From c7a11ef353586b9fa66d902fc42b8a69510c0a29 Mon Sep 17 00:00:00 2001 From: zhaowenkai <799480165@qq.com> Date: Mon, 25 Dec 2023 14:32:13 +0800 Subject: [PATCH] add more tests for TinyColor --- src/Colors/Format.cs | 2 +- src/Colors/TinyColor.cs | 17 +- src/Colors/Util.cs | 52 +- test/CssInCSharp.Tests/MockData.cs | 740 +++++++++++++++++++++++ test/CssInCSharp.Tests/TinyColorTests.cs | 163 +++++ 5 files changed, 965 insertions(+), 9 deletions(-) create mode 100644 test/CssInCSharp.Tests/MockData.cs diff --git a/src/Colors/Format.cs b/src/Colors/Format.cs index 1daae31..8b6d728 100644 --- a/src/Colors/Format.cs +++ b/src/Colors/Format.cs @@ -254,7 +254,7 @@ public static ColorInput StringInputToObject(string color) R = ParseIntFromHex(match.Groups[1].Value), G = ParseIntFromHex(match.Groups[2].Value), B = ParseIntFromHex(match.Groups[3].Value), - A = ParseIntFromHex(match.Groups[4].Value), + A = ConvertHexToDecimal(match.Groups[4].Value), Format = named ? "name" : "hex8", }; } diff --git a/src/Colors/TinyColor.cs b/src/Colors/TinyColor.cs index 476c82f..194b01f 100644 --- a/src/Colors/TinyColor.cs +++ b/src/Colors/TinyColor.cs @@ -61,6 +61,17 @@ public static TinyColor FromRatio(RatioInput ratio, TinyColorOptions opts = null return new TinyColor(newColor, opts); } + public static TinyColor LegacyRandom() + { + var random = new Random(); + return new TinyColor(new RGB + { + R = random.Next(), + G = random.Next(), + B = random.Next(), + }); + } + public bool IsDark() { return GetBrightness() < 128; @@ -145,7 +156,7 @@ public string ToHsvString() public HSLA ToHsl() { var hsl = RgbToHsl(_r, _g, _b); - return new HSLA(hsl.H, hsl.S, hsl.L, _a); + return new HSLA(hsl.H * 360, hsl.S, hsl.L, _a); } public string ToHslString() @@ -394,7 +405,7 @@ public TinyColor[] Analogous(double results = 6, double slices = 30) var hsl = ToHsl(); var part = 360 / slices; var ret = new List() { this }; - for (hsl.H = (hsl.H - ((int)(part * results) >> 1) + 720) % 360; results > 0; --results) + for (hsl.H = (hsl.H - ((int)(part * results) >> 1) + 720) % 360; results > 1; --results) { hsl.H = (hsl.H + part) % 360; ret.Add(new TinyColor(hsl)); @@ -465,7 +476,7 @@ public TinyColor[] Triad() public TinyColor[] Tetrad() { - return Polyad(3); + return Polyad(4); } public TinyColor[] Polyad(double n) diff --git a/src/Colors/Util.cs b/src/Colors/Util.cs index 917a9df..c27770f 100644 --- a/src/Colors/Util.cs +++ b/src/Colors/Util.cs @@ -4,7 +4,7 @@ namespace CssInCSharp.Colors { - internal static class Util + public static class Util { public static string CharAt(this string str, int index) { @@ -28,7 +28,7 @@ public static StringNumber Bound01(StringNumber n, double max) if (isPercent) { - n = n * max / 100; + n = (int)(n * max) / (double)100; } if (Math.Abs(n - max) < 0.000001) @@ -78,7 +78,7 @@ public static double BoundAlpha(StringNumber a) public static double ConvertHexToDecimal(string h) { - return ParseIntFromHex(h) / 255; + return ParseIntFromHex(h) / (double)255; } public static int ParseIntFromHex(string h) @@ -114,7 +114,30 @@ public static bool IsPercentage(StringNumber n) public static double MathRound(double value) { - return Math.Round(value, MidpointRounding.AwayFromZero); + if (value >= 0) + { + return Math.Round(value, MidpointRounding.AwayFromZero); + } + else + { + /* + * js math round method: + * Math.round(25.5) -> 26 + * Math.round(-25.5) -> -25 + */ + if (IsMidpoint(GetDecimalPlaces(value))) + { +#if NETSTANDARD2_1 + return Math.Round(value, MidpointRounding.ToEven); +#else + return Math.Round(value, MidpointRounding.ToZero); +#endif + } + else + { + return Math.Round(value, MidpointRounding.AwayFromZero); + } + } } public static double MathMax(params double[] values) @@ -131,5 +154,24 @@ public static double Clamp01(double val) { return Math.Min(1, Math.Max(0, val)); } -} + public static bool IsMidpoint(double val) + { + var i = 0; + while (i < 16) + { + i++; + var mid = -(5 / Math.Pow(10, i)); + if (val == mid) + { + return true; + } + } + return false; + } + + public static double GetDecimalPlaces(double val) + { + return val - Math.Truncate(val); + } + } } diff --git a/test/CssInCSharp.Tests/MockData.cs b/test/CssInCSharp.Tests/MockData.cs new file mode 100644 index 0000000..c4f48eb --- /dev/null +++ b/test/CssInCSharp.Tests/MockData.cs @@ -0,0 +1,740 @@ +namespace CssInCSharp.Tests +{ + public class MockData + { + public static readonly string[] DESATURATIONS = new[] + { + "ff0000", + "fe0101", + "fc0303", + "fb0404", + "fa0505", + "f90606", + "f70808", + "f60909", + "f50a0a", + "f40b0b", + "f20d0d", + "f10e0e", + "f00f0f", + "ee1111", + "ed1212", + "ec1313", + "eb1414", + "e91616", + "e81717", + "e71818", + "e61919", + "e41b1b", + "e31c1c", + "e21d1d", + "e01f1f", + "df2020", + "de2121", + "dd2222", + "db2424", + "da2525", + "d92626", + "d72828", + "d62929", + "d52a2a", + "d42b2b", + "d22d2d", + "d12e2e", + "d02f2f", + "cf3030", + "cd3232", + "cc3333", + "cb3434", + "c93636", + "c83737", + "c73838", + "c63939", + "c43b3b", + "c33c3c", + "c23d3d", + "c13e3e", + "bf4040", + "be4141", + "bd4242", + "bb4444", + "ba4545", + "b94646", + "b84747", + "b64949", + "b54a4a", + "b44b4b", + "b34d4d", + "b14e4e", + "b04f4f", + "af5050", + "ad5252", + "ac5353", + "ab5454", + "aa5555", + "a85757", + "a75858", + "a65959", + "a45b5b", + "a35c5c", + "a25d5d", + "a15e5e", + "9f6060", + "9e6161", + "9d6262", + "9c6363", + "9a6565", + "996666", + "986767", + "966969", + "956a6a", + "946b6b", + "936c6c", + "916e6e", + "906f6f", + "8f7070", + "8e7171", + "8c7373", + "8b7474", + "8a7575", + "887777", + "877878", + "867979", + "857a7a", + "837c7c", + "827d7d", + "817e7e", + "808080", + }; + + public static readonly string[] SATURATIONS = new [] + { + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + "ff0000", + }; + + public static readonly string[] LIGHTENS = new [] + { + "ff0000", + "ff0505", + "ff0a0a", + "ff0f0f", + "ff1414", + "ff1a1a", + "ff1f1f", + "ff2424", + "ff2929", + "ff2e2e", + "ff3333", + "ff3838", + "ff3d3d", + "ff4242", + "ff4747", + "ff4d4d", + "ff5252", + "ff5757", + "ff5c5c", + "ff6161", + "ff6666", + "ff6b6b", + "ff7070", + "ff7575", + "ff7a7a", + "ff8080", + "ff8585", + "ff8a8a", + "ff8f8f", + "ff9494", + "ff9999", + "ff9e9e", + "ffa3a3", + "ffa8a8", + "ffadad", + "ffb3b3", + "ffb8b8", + "ffbdbd", + "ffc2c2", + "ffc7c7", + "ffcccc", + "ffd1d1", + "ffd6d6", + "ffdbdb", + "ffe0e0", + "ffe5e5", + "ffebeb", + "fff0f0", + "fff5f5", + "fffafa", + "ffffff", + "ffffff", + "ffffff", + "ffffff", + "ffffff", + "ffffff", + "ffffff", + "ffffff", + "ffffff", + "ffffff", + "ffffff", + "ffffff", + "ffffff", + "ffffff", + "ffffff", + "ffffff", + "ffffff", + "ffffff", + "ffffff", + "ffffff", + "ffffff", + "ffffff", + "ffffff", + "ffffff", + "ffffff", + "ffffff", + "ffffff", + "ffffff", + "ffffff", + "ffffff", + "ffffff", + "ffffff", + "ffffff", + "ffffff", + "ffffff", + "ffffff", + "ffffff", + "ffffff", + "ffffff", + "ffffff", + "ffffff", + "ffffff", + "ffffff", + "ffffff", + "ffffff", + "ffffff", + "ffffff", + "ffffff", + "ffffff", + "ffffff", + "ffffff", + }; + + public static readonly string[] BRIGHTENS = new [] + { + "ff0000", + "ff0303", + "ff0505", + "ff0808", + "ff0a0a", + "ff0d0d", + "ff0f0f", + "ff1212", + "ff1414", + "ff1717", + "ff1919", + "ff1c1c", + "ff1f1f", + "ff2121", + "ff2424", + "ff2626", + "ff2929", + "ff2b2b", + "ff2e2e", + "ff3030", + "ff3333", + "ff3636", + "ff3838", + "ff3b3b", + "ff3d3d", + "ff4040", + "ff4242", + "ff4545", + "ff4747", + "ff4a4a", + "ff4c4c", + "ff4f4f", + "ff5252", + "ff5454", + "ff5757", + "ff5959", + "ff5c5c", + "ff5e5e", + "ff6161", + "ff6363", + "ff6666", + "ff6969", + "ff6b6b", + "ff6e6e", + "ff7070", + "ff7373", + "ff7575", + "ff7878", + "ff7a7a", + "ff7d7d", + "ff7f7f", + "ff8282", + "ff8585", + "ff8787", + "ff8a8a", + "ff8c8c", + "ff8f8f", + "ff9191", + "ff9494", + "ff9696", + "ff9999", + "ff9c9c", + "ff9e9e", + "ffa1a1", + "ffa3a3", + "ffa6a6", + "ffa8a8", + "ffabab", + "ffadad", + "ffb0b0", + "ffb2b2", + "ffb5b5", + "ffb8b8", + "ffbaba", + "ffbdbd", + "ffbfbf", + "ffc2c2", + "ffc4c4", + "ffc7c7", + "ffc9c9", + "ffcccc", + "ffcfcf", + "ffd1d1", + "ffd4d4", + "ffd6d6", + "ffd9d9", + "ffdbdb", + "ffdede", + "ffe0e0", + "ffe3e3", + "ffe5e5", + "ffe8e8", + "ffebeb", + "ffeded", + "fff0f0", + "fff2f2", + "fff5f5", + "fff7f7", + "fffafa", + "fffcfc", + "ffffff", + }; + + public static readonly string[] DARKENS = new [] + { + "ff0000", + "fa0000", + "f50000", + "f00000", + "eb0000", + "e60000", + "e00000", + "db0000", + "d60000", + "d10000", + "cc0000", + "c70000", + "c20000", + "bd0000", + "b80000", + "b30000", + "ad0000", + "a80000", + "a30000", + "9e0000", + "990000", + "940000", + "8f0000", + "8a0000", + "850000", + "800000", + "7a0000", + "750000", + "700000", + "6b0000", + "660000", + "610000", + "5c0000", + "570000", + "520000", + "4d0000", + "470000", + "420000", + "3d0000", + "380000", + "330000", + "2e0000", + "290000", + "240000", + "1f0000", + "190000", + "140000", + "0f0000", + "0a0000", + "050000", + "000000", + "000000", + "000000", + "000000", + "000000", + "000000", + "000000", + "000000", + "000000", + "000000", + "000000", + "000000", + "000000", + "000000", + "000000", + "000000", + "000000", + "000000", + "000000", + "000000", + "000000", + "000000", + "000000", + "000000", + "000000", + "000000", + "000000", + "000000", + "000000", + "000000", + "000000", + "000000", + "000000", + "000000", + "000000", + "000000", + "000000", + "000000", + "000000", + "000000", + "000000", + "000000", + "000000", + "000000", + "000000", + "000000", + "000000", + "000000", + "000000", + "000000", + "000000", + }; + + public static readonly string[] TINTS = new [] + { + "ff0000", + "ff0303", + "ff0505", + "ff0808", + "ff0a0a", + "ff0d0d", + "ff0f0f", + "ff1212", + "ff1414", + "ff1717", + "ff1a1a", + "ff1c1c", + "ff1f1f", + "ff2121", + "ff2424", + "ff2626", + "ff2929", + "ff2b2b", + "ff2e2e", + "ff3030", + "ff3333", + "ff3636", + "ff3838", + "ff3b3b", + "ff3d3d", + "ff4040", + "ff4242", + "ff4545", + "ff4747", + "ff4a4a", + "ff4d4d", + "ff4f4f", + "ff5252", + "ff5454", + "ff5757", + "ff5959", + "ff5c5c", + "ff5e5e", + "ff6161", + "ff6363", + "ff6666", + "ff6969", + "ff6b6b", + "ff6e6e", + "ff7070", + "ff7373", + "ff7575", + "ff7878", + "ff7a7a", + "ff7d7d", + "ff8080", + "ff8282", + "ff8585", + "ff8787", + "ff8a8a", + "ff8c8c", + "ff8f8f", + "ff9191", + "ff9494", + "ff9696", + "ff9999", + "ff9c9c", + "ff9e9e", + "ffa1a1", + "ffa3a3", + "ffa6a6", + "ffa8a8", + "ffabab", + "ffadad", + "ffb0b0", + "ffb3b3", + "ffb5b5", + "ffb8b8", + "ffbaba", + "ffbdbd", + "ffbfbf", + "ffc2c2", + "ffc4c4", + "ffc7c7", + "ffc9c9", + "ffcccc", + "ffcfcf", + "ffd1d1", + "ffd4d4", + "ffd6d6", + "ffd9d9", + "ffdbdb", + "ffdede", + "ffe0e0", + "ffe3e3", + "ffe6e6", + "ffe8e8", + "ffebeb", + "ffeded", + "fff0f0", + "fff2f2", + "fff5f5", + "fff7f7", + "fffafa", + "fffcfc", + "ffffff", + }; + + public static readonly string[] SHADES = new [] + { + "ff0000", + "fc0000", + "fa0000", + "f70000", + "f50000", + "f20000", + "f00000", + "ed0000", + "eb0000", + "e80000", + "e60000", + "e30000", + "e00000", + "de0000", + "db0000", + "d90000", + "d60000", + "d40000", + "d10000", + "cf0000", + "cc0000", + "c90000", + "c70000", + "c40000", + "c20000", + "bf0000", + "bd0000", + "ba0000", + "b80000", + "b50000", + "b30000", + "b00000", + "ad0000", + "ab0000", + "a80000", + "a60000", + "a30000", + "a10000", + "9e0000", + "9c0000", + "990000", + "960000", + "940000", + "910000", + "8f0000", + "8c0000", + "8a0000", + "870000", + "850000", + "820000", + "800000", + "7d0000", + "7a0000", + "780000", + "750000", + "730000", + "700000", + "6e0000", + "6b0000", + "690000", + "660000", + "630000", + "610000", + "5e0000", + "5c0000", + "590000", + "570000", + "540000", + "520000", + "4f0000", + "4d0000", + "4a0000", + "470000", + "450000", + "420000", + "400000", + "3d0000", + "3b0000", + "380000", + "360000", + "330000", + "300000", + "2e0000", + "2b0000", + "290000", + "260000", + "240000", + "210000", + "1f0000", + "1c0000", + "1a0000", + "170000", + "140000", + "120000", + "0f0000", + "0d0000", + "0a0000", + "080000", + "050000", + "030000", + "000000", + }; + } +} diff --git a/test/CssInCSharp.Tests/TinyColorTests.cs b/test/CssInCSharp.Tests/TinyColorTests.cs index 65540a9..4f7c62d 100644 --- a/test/CssInCSharp.Tests/TinyColorTests.cs +++ b/test/CssInCSharp.Tests/TinyColorTests.cs @@ -1,6 +1,8 @@ using CssInCSharp.Colors; using Shouldly; using Xunit; +using static CssInCSharp.Tests.MockData; +using static CssInCSharp.Colors.Util; namespace CssInCSharp.Tests { @@ -462,5 +464,166 @@ public void Is_Dark_Or_Light_Colors() new TinyColor("#eee").IsLight().ShouldBe(true); new TinyColor("#fff").IsLight().ShouldBe(true); } + + [Fact] + public void Color_Equality() + { + new TinyColor("#ff0000").Equals("#ff0000").ShouldBe(true); + new TinyColor("#ff0000").Equals("rgb(255, 0, 0)").ShouldBe(true); + new TinyColor("#ff0000").Equals("rgba(255, 0, 0, .1)").ShouldBe(false); + new TinyColor("#ff000066").Equals("rgba(255, 0, 0, .4)").ShouldBe(true); + new TinyColor("#f009").Equals("rgba(255, 0, 0, .6)").ShouldBe(true); + new TinyColor("#336699CC").Equals("369C").ShouldBe(true); + new TinyColor("ff0000").Equals("#ff0000").ShouldBe(true); + new TinyColor("#f00").Equals("#ff0000").ShouldBe(true); + new TinyColor("#f00").Equals("#ff0000").ShouldBe(true); + new TinyColor("f00").Equals("#ff0000").ShouldBe(true); + new TinyColor("010101").ToHexString().ShouldBe("#010101"); + new TinyColor("#ff0000").Equals("#00ff00").ShouldBe(false); + new TinyColor("#ff8000").Equals("rgb(100%, 50%, 0%)").ShouldBe(true); + } + + [Fact] + public void Modifications() + { + for (var i = 0; i <= 100; i++) + { + new TinyColor("red").Desaturate(i).ToHex().ShouldBe(DESATURATIONS[i]); + } + + for (var i = 0; i <= 100; i++) + { + new TinyColor("red").Saturate(i).ToHex().ShouldBe(SATURATIONS[i]); + } + + for (var i = 0; i <= 100; i++) + { + new TinyColor("red").Lighten(i).ToHex().ShouldBe(LIGHTENS[i]); + } + + for (var i = 0; i <= 100; i++) + { + new TinyColor("red").Brighten(i).ToHex().ShouldBe(BRIGHTENS[i]); + } + + for (var i = 0; i <= 100; i++) + { + new TinyColor("red").Darken(i).ToHex().ShouldBe(DARKENS[i]); + } + + for (var i = 0; i <= 100; i++) + { + new TinyColor("red").Tint(i).ToHex().ShouldBe(TINTS[i]); + } + + for (var i = 0; i <= 100; i++) + { + new TinyColor("red").Shade(i).ToHex().ShouldBe(SHADES[i]); + } + + new TinyColor("red").Greyscale().ToHex().ShouldBe("808080"); + } + + [Fact] + public void Spin() + { + MathRound(new TinyColor("#f00").Spin(-1234).ToHsl().H.AsNumber).ShouldBe(206); + MathRound(new TinyColor("#f00").Spin(-360).ToHsl().H.AsNumber).ShouldBe(0); + MathRound(new TinyColor("#f00").Spin(-120).ToHsl().H.AsNumber).ShouldBe(240); + MathRound(new TinyColor("#f00").Spin(0).ToHsl().H.AsNumber).ShouldBe(0); + MathRound(new TinyColor("#f00").Spin(10).ToHsl().H.AsNumber).ShouldBe(10); + MathRound(new TinyColor("#f00").Spin(360).ToHsl().H.AsNumber).ShouldBe(0); + MathRound(new TinyColor("#f00").Spin(2345).ToHsl().H.AsNumber).ShouldBe(185); + } + + [Fact] + public void Mix() + { + new TinyColor("#000").Mix("#fff").ToHsl().L.AsNumber.ShouldBe(0.5); + new TinyColor("#f00").Mix("#000", 0).ToHex().ShouldBe("ff0000"); + new TinyColor("#fff").Mix("#000", 90).ToHex().ShouldBe("1a1a1a"); + for (var i = 0; i < 100; i++) + { + var newHex = ((int)MathRound(((double)255 * (100 - i)) / 100)).ToString("x2"); + + if (newHex.Length == 1) + { + newHex = "0" + newHex; + } + + new TinyColor("#f00").Mix("#000", i).ToHex().ShouldBe(newHex + "0000"); + new TinyColor("#0f0").Mix("#000", i).ToHex().ShouldBe($"00{newHex}00"); + new TinyColor("#00f").Mix("#000", i).ToHex().ShouldBe("0000" + newHex); + new TinyColor("transparent").Mix("#000", i).ToRgb().A.Value.AsNumber.ShouldBe(i / (double)100); + } + } + + [Fact] + public void OnBackground() + { + new TinyColor("#ffffff").OnBackground("#000").ToHex().ShouldBe("ffffff"); + new TinyColor("#ffffff00").OnBackground("#000").ToHex().ShouldBe("000000"); + new TinyColor("#ffffff77").OnBackground("#000").ToHex().ShouldBe("777777"); + new TinyColor("#262a6d82").OnBackground("#644242").ToHex().ShouldBe("443658"); + new TinyColor("rgba(255,0,0,0.5)").OnBackground("rgba(0,255,0,0.5)").ToRgbString().ShouldBe("rgba(170, 85, 0, 0.75)"); + new TinyColor("rgba(255,0,0,0.5)").OnBackground("rgba(0,0,255,1)").ToRgbString().ShouldBe("rgb(128, 0, 128)"); + new TinyColor("rgba(0,0,255,1)").OnBackground("rgba(0,0,0,0.5)").ToRgbString().ShouldBe("rgb(0, 0, 255)"); + } + + [Fact] + public void Complement() + { + var complementDoesntModifyInstance = new TinyColor("red"); + complementDoesntModifyInstance.Complement().ToHex().ShouldBe("00ffff"); + complementDoesntModifyInstance.ToHex().ShouldBe("ff0000"); + } + + [Fact] + public void Analogous() + { + var combination = new TinyColor("red").Analogous(); + ColorsToHexString(combination).ShouldBe("ff0000,ff0066,ff0033,ff0000,ff3300,ff6600"); + } + + [Fact] + public void Monochromatic() + { + var combination = new TinyColor("red").Monochromatic(); + ColorsToHexString(combination).ShouldBe("ff0000,2a0000,550000,800000,aa0000,d40000"); + } + + [Fact] + public void Splitcomplement() + { + var combination = new TinyColor("red").Splitcomplement(); + ColorsToHexString(combination).ShouldBe("ff0000,ccff00,0066ff"); + } + + [Fact] + public void Triad() + { + var combination = new TinyColor("red").Triad(); + ColorsToHexString(combination).ShouldBe("ff0000,00ff00,0000ff"); + } + + [Fact] + public void Tetrad() + { + var combination = new TinyColor("red").Tetrad(); + ColorsToHexString(combination).ShouldBe("ff0000,80ff00,00ffff,7f00ff"); + } + + [Fact] + public void Legacy_Random() + { + TinyColor.LegacyRandom().IsValid.ShouldBeTrue(); + } + + private string ColorsToHexString(TinyColor[] colors) + { + return colors + .Select(c => c.ToHex()) + .Join(","); + } } }