using System.Text.Json; using FrameProcessor.Domain; using SixLabors.ImageSharp; using SixLabors.ImageSharp.PixelFormats; namespace FrameProcessor.Tests; public class PaletteEntryTests { [Fact] public void JsonDeserialize_ParsesHexIntoColor() { const string json = """{ "name": "black", "color": "#1F2226", "deviceColor": "#000000" }"""; var entry = JsonSerializer.Deserialize(json); Assert.NotNull(entry); Assert.Equal("black", entry!.Name); Assert.Equal(new Rgba32(0x1F, 0x22, 0x26, 0xFF), entry.DisplayColor.ToPixel()); Assert.Equal(new Rgba32(0x00, 0x00, 0x00, 0xFF), entry.DeviceColor.ToPixel()); } [Fact] public void JsonDeserialize_HexWithoutHashIsAccepted() { const string json = """{ "name": "red", "color": "62201E", "deviceColor": "FF0000" }"""; var entry = JsonSerializer.Deserialize(json); Assert.NotNull(entry); Assert.Equal(new Rgba32(0x62, 0x20, 0x1E, 0xFF), entry!.DisplayColor.ToPixel()); Assert.Equal(new Rgba32(0xFF, 0x00, 0x00, 0xFF), entry.DeviceColor.ToPixel()); } [Fact] public void JsonSerialize_EmitsHashPrefixedSixDigitHex() { var entry = new PaletteEntry( "yellow", Color.FromPixel(new Rgba32(0xC1, 0xBB, 0x1E, 0xFF)), Color.FromPixel(new Rgba32(0xFF, 0xFF, 0x00, 0xFF))); var json = JsonSerializer.Serialize(entry); Assert.Contains("\"name\":\"yellow\"", json); Assert.Contains("\"color\":\"#C1BB1E\"", json); Assert.Contains("\"deviceColor\":\"#FFFF00\"", json); } [Fact] public void JsonRoundTrip_PreservesValues() { var original = new PaletteEntry( "blue", Color.FromPixel(new Rgba32(0x23, 0x3F, 0x8E, 0xFF)), Color.FromPixel(new Rgba32(0x00, 0x00, 0xFF, 0xFF))); var json = JsonSerializer.Serialize(original); var roundTripped = JsonSerializer.Deserialize(json); Assert.Equal(original, roundTripped); } [Theory] [InlineData("""{ "color": "#000000", "deviceColor": "#000000" }""")] [InlineData("""{ "name": "x", "deviceColor": "#000000" }""")] [InlineData("""{ "name": "x", "color": "#000000" }""")] public void JsonDeserialize_MissingField_Throws(string json) { Assert.Throws(() => JsonSerializer.Deserialize(json)); } [Theory] [InlineData("""{ "name": "x", "color": "not-a-color", "deviceColor": "#000000" }""")] [InlineData("""{ "name": "x", "color": "#000000", "deviceColor": "zzz" }""")] [InlineData("""{ "name": "x", "color": "", "deviceColor": "#000000" }""")] public void JsonDeserialize_InvalidHex_Throws(string json) { Assert.Throws(() => JsonSerializer.Deserialize(json)); } [Fact] public void JsonDeserialize_EmptyName_Throws() { const string json = """{ "name": "", "color": "#000000", "deviceColor": "#000000" }"""; Assert.Throws(() => JsonSerializer.Deserialize(json)); } [Fact] public void JsonDeserialize_UnknownFields_AreIgnored() { const string json = """{ "name": "black", "color": "#000000", "deviceColor": "#000000", "extra": 42 }"""; var entry = JsonSerializer.Deserialize(json); Assert.NotNull(entry); Assert.Equal("black", entry!.Name); } [Fact] public void Equality_BasedOnNameAndColors() { var a = new PaletteEntry("black", Color.Black, Color.Black); var b = new PaletteEntry("black", Color.Black, Color.Black); var c = new PaletteEntry("white", Color.Black, Color.Black); Assert.Equal(a, b); Assert.NotEqual(a, c); } }