using System; namespace Prism.UnitTests { public class GradientTests : UnitTestSharp.TestFixture { private static GradientStop Stop(double offset, Color color) { return new GradientStop(offset, color); } public static bool HueBetween(double lowest, double highest, Color color) { double hue = Oklch.FromColor(color).Hue; return hue >= lowest && hue <= highest; } public class CtorTests : UnitTestSharp.TestFixture { public void KeepsTheSpaceAndCountsTheStops() { var gradient = new Gradient(GradientSpace.Oklab, Stop(0, Colors.Red), Stop(1, Colors.Blue)); CheckEqual(GradientSpace.Oklab, gradient.Space); CheckEqual(2, gradient.StopCount); } public void WithoutADirection_GoesTheShortWay() { CheckEqual(HueDirection.Shortest, new Gradient(GradientSpace.Hsv, Stop(0, Colors.Red)).Direction); } public void KeepsAGivenDirection() { var gradient = new Gradient(GradientSpace.Hsv, HueDirection.Longest, Stop(0, Colors.Red)); CheckEqual(HueDirection.Longest, gradient.Direction); } public void StopsSharingAnOffset_AreAllowed() { CheckEqual( 2, new Gradient(GradientSpace.LinearLight, Stop(0.5, Colors.Red), Stop(0.5, Colors.Blue)).StopCount); } public void NullStops_Throws() { CheckThrow(typeof(ArgumentNullException)); new Gradient(GradientSpace.LinearLight, (GradientStop[])null); } public void NoStops_Throws() { CheckThrow(typeof(ArgumentException)); new Gradient(GradientSpace.LinearLight, new GradientStop[0]); } public void StopsOutOfOrder_Throws() { CheckThrow(typeof(ArgumentException)); new Gradient(GradientSpace.LinearLight, Stop(0.75, Colors.Red), Stop(0.25, Colors.Blue)); } public void AnUnknownSpace_Throws() { CheckThrow(typeof(ArgumentOutOfRangeException)); new Gradient((GradientSpace)99, Stop(0, Colors.Red)); } public void AnUnknownDirection_Throws() { CheckThrow(typeof(ArgumentOutOfRangeException)); new Gradient(GradientSpace.Oklch, (HueDirection)99, Stop(0, Colors.Red)); } } public class GetStopTests : UnitTestSharp.TestFixture { private static readonly Gradient TwoStops = new Gradient( GradientSpace.LinearLight, Stop(0.25, Colors.Red), Stop(0.75, Colors.Blue)); public void ReturnsTheStopsInOrder() { CheckEqual(Stop(0.25, Colors.Red), TwoStops.GetStop(0)); CheckEqual(Stop(0.75, Colors.Blue), TwoStops.GetStop(1)); } public void AnIndexBelowZero_Throws() { CheckThrow(typeof(ArgumentOutOfRangeException)); TwoStops.GetStop(-1); } public void AnIndexPastTheLastStop_Throws() { CheckThrow(typeof(ArgumentOutOfRangeException)); TwoStops.GetStop(2); } } public class ClampToUnitTests : UnitTestSharp.TestFixture { public void APositionInRange_IsUnchanged() { CheckEqual(0.25, Gradient.ClampToUnit(0.25)); } public void BelowZero_GivesZero() { CheckEqual(0.0, Gradient.ClampToUnit(-3)); } public void AboveOne_GivesOne() { CheckEqual(1.0, Gradient.ClampToUnit(3)); } public void NaN_GivesZero() { CheckEqual(0.0, Gradient.ClampToUnit(double.NaN)); } public void TheEnds_AreUnchanged() { CheckEqual(0.0, Gradient.ClampToUnit(0)); CheckEqual(1.0, Gradient.ClampToUnit(1)); } } public class ConstantTests : UnitTestSharp.TestFixture { public void IsTheColorEverywhere() { Gradient gradient = Gradient.Constant(Color.FromArgb(10, 20, 30)); CheckEqual(Color.FromArgb(10, 20, 30), gradient.Evaluate(0)); CheckEqual(Color.FromArgb(10, 20, 30), gradient.Evaluate(0.6)); CheckEqual(Color.FromArgb(10, 20, 30), gradient.Evaluate(1)); } } public class BetweenTests : UnitTestSharp.TestFixture { public void BlendsInLinearLightByDefault() { CheckEqual(Color.FromArgb(188, 188, 188), Gradient.Between(Colors.Black, Colors.White).Evaluate(0.5)); } public void BlendsInTheGivenSpace() { Gradient gradient = Gradient.Between(Colors.Black, Colors.White, GradientSpace.Oklab); CheckEqual(Color.FromArgb(99, 99, 99), gradient.Evaluate(0.5)); } } public class EvaluateExactTests : UnitTestSharp.TestFixture { private static readonly Gradient BlackToWhiteInHsv = Gradient.Between( Colors.Black, Colors.White, GradientSpace.Hsv); public void BetweenStops_IsNotRoundedToBytes() { CheckEqual(new SrgbColor(0.5, 0.5, 0.5), BlackToWhiteInHsv.EvaluateExact(0.5)); } public void AtAStop_IsThatStopsColor() { CheckEqual(SrgbColor.FromColor(Colors.White), BlackToWhiteInHsv.EvaluateExact(1)); } public void BeforeTheFirstStop_IsTheFirstColor() { var gradient = new Gradient( GradientSpace.LinearLight, Stop(0.5, Color.FromArgb(40, 50, 60)), Stop(1, Colors.White)); CheckEqual(SrgbColor.FromColor(Color.FromArgb(40, 50, 60)), gradient.EvaluateExact(0.25)); } public void NaN_IsTheFirstColor() { CheckEqual(SrgbColor.FromColor(Colors.Black), BlackToWhiteInHsv.EvaluateExact(double.NaN)); } public void RoundedToBytes_IsTheEvaluatedColor() { Gradient gradient = Gradient.Between(Colors.Red, Colors.Blue, GradientSpace.Oklab); CheckEqual(gradient.Evaluate(0.3), gradient.EvaluateExact(0.3).ToColor()); } } public class EvaluateTests : UnitTestSharp.TestFixture { private static readonly Gradient ThreeStops = new Gradient( GradientSpace.LinearLight, Stop(0.25, Color.FromArgb(10, 20, 30)), Stop(0.5, Color.FromArgb(100, 110, 120)), Stop(1, Color.FromArgb(200, 210, 220))); public void AtAStop_IsThatStopsColor() { CheckEqual(Color.FromArgb(10, 20, 30), ThreeStops.Evaluate(0.25)); CheckEqual(Color.FromArgb(100, 110, 120), ThreeStops.Evaluate(0.5)); CheckEqual(Color.FromArgb(200, 210, 220), ThreeStops.Evaluate(1)); } public void BeforeTheFirstStop_IsTheFirstColor() { CheckEqual(Color.FromArgb(10, 20, 30), ThreeStops.Evaluate(0)); CheckEqual(Color.FromArgb(10, 20, 30), ThreeStops.Evaluate(0.2)); } public void AfterTheLastStop_IsTheLastColor() { var gradient = new Gradient( GradientSpace.LinearLight, Stop(0, Colors.Black), Stop(0.5, Color.FromArgb(40, 50, 60))); CheckEqual(Color.FromArgb(40, 50, 60), gradient.Evaluate(0.75)); CheckEqual(Color.FromArgb(40, 50, 60), gradient.Evaluate(1)); } public void BetweenTwoStops_BlendsOnlyThoseTwo() { Color atMiddleOfSecondSegment = ThreeStops.Evaluate(0.75); CheckEqual( Gradient.Between(Color.FromArgb(100, 110, 120), Color.FromArgb(200, 210, 220)).Evaluate(0.5), atMiddleOfSecondSegment); } public void PositionsOutsideZeroToOne_AreClamped() { CheckEqual(ThreeStops.Evaluate(0), ThreeStops.Evaluate(-5)); CheckEqual(ThreeStops.Evaluate(1), ThreeStops.Evaluate(5)); } public void NaN_IsTheStart() { CheckEqual(ThreeStops.Evaluate(0), ThreeStops.Evaluate(double.NaN)); } public void AHardEdge_IsTheLaterColorFromTheEdgeOn() { var gradient = new Gradient( GradientSpace.LinearLight, Stop(0, Colors.Red), Stop(0.5, Colors.Red), Stop(0.5, Colors.Blue), Stop(1, Colors.Blue)); CheckEqual(Colors.Red, gradient.Evaluate(0.4999)); CheckEqual(Colors.Blue, gradient.Evaluate(0.5)); } public void LinearLight_BlendsBlackToWhiteToALightGray() { var gradient = new Gradient(GradientSpace.LinearLight, Stop(0, Colors.Black), Stop(1, Colors.White)); CheckEqual(Color.FromArgb(188, 188, 188), gradient.Evaluate(0.5)); } public void Oklab_BlendsBlackToWhiteToADarkerGray() { CheckEqual( Color.FromArgb(99, 99, 99), new Gradient(GradientSpace.Oklab, Stop(0, Colors.Black), Stop(1, Colors.White)).Evaluate(0.5)); } public void Hsv_BlendsRedToGreenThroughYellow() { var gradient = new Gradient(GradientSpace.Hsv, Stop(0, Colors.Red), Stop(1, Color.FromArgb(0, 255, 0))); CheckEqual(Color.FromArgb(255, 255, 0), gradient.Evaluate(0.5)); } public void Hsl_BlendsRedToGreenThroughYellow() { var gradient = new Gradient(GradientSpace.Hsl, Stop(0, Colors.Red), Stop(1, Color.FromArgb(0, 255, 0))); CheckEqual(Color.FromArgb(255, 255, 0), gradient.Evaluate(0.5)); } public void Oklch_GoesTheShortWayRoundTheHuesByDefault() { var gradient = new Gradient( GradientSpace.Oklch, Stop(0, Colors.Red), Stop(1, Color.FromArgb(0, 0, 255))); CheckTrue(HueBetween(0.85, 0.95, gradient.Evaluate(0.5))); } public void Oklch_GoesTheLongWayWhenAskedTo() { var gradient = new Gradient( GradientSpace.Oklch, HueDirection.Longest, Stop(0, Colors.Red), Stop(1, Color.FromArgb(0, 0, 255))); CheckTrue(HueBetween(0.3, 0.55, gradient.Evaluate(0.5))); } public void ATransparentEnd_AddsNoColor() { var gradient = new Gradient( GradientSpace.LinearLight, Stop(0, Colors.Red), Stop(1, Color.FromArgb(0, 0, 0, 255))); CheckEqual(Color.FromArgb(128, 255, 0, 0), gradient.Evaluate(0.5)); } } } }