using Annulus; using Azimuth; using UnitTestSharp; namespace Glass.UnitTests { public class FramedMaterialTests : TestFixture { /// /// Prefers one fixed size and can shrink to another. /// public record SizedMaterial : Material { private readonly Vector preferred; private readonly Vector minimum; public SizedMaterial(Vector preferred, Vector minimum = default) { this.preferred = preferred; this.minimum = minimum; } protected override Vector PreferredSizeInModelSpace(Constraints constraints) => constraints.Constrain(preferred); protected override Vector MinimumSizeInModelSpace(Constraints constraints) => constraints.Constrain(minimum); } public static readonly Rect ControlBounds = Rect.FromPositionAndSize(new Vector(10, 20), new Vector(100, 50)); public static Rect.BorderSize Border(Scalar left, Scalar top, Scalar right, Scalar bottom) { return new Rect.BorderSize { Left = left, Top = top, Right = right, Bottom = bottom }; } public static readonly Rect.BorderSize OneAllRound = Border(1, 1, 1, 1); public static Material Bordered(Scalar left, Scalar top, Scalar right, Scalar bottom) { return new Material { BorderSize = Border(left, top, right, bottom) }; } public static Rect Box(Scalar x, Scalar y, Scalar width, Scalar height) { return Rect.FromPositionAndSize(new Vector(x, y), new Vector(width, height)); } public class CtorTests : TestFixture { public void Always_PutsChromeThenBodyInChildMaterials() { Material chrome = new SolidColorMaterial(); Material body = new SolidColorMaterial(); var framed = new FramedMaterial(chrome, body); CheckEqual(2, framed.ChildMaterials.Count); CheckEqual(chrome, framed.ChildMaterials[0]); CheckEqual(body, framed.ChildMaterials[1]); } } public class ChromeTests : TestFixture { public void Always_IsTheFirstChildMaterial() { Material chrome = new SolidColorMaterial(); CheckEqual(chrome, new FramedMaterial(chrome, new SolidColorMaterial()).Chrome); } } public class BodyTests : TestFixture { public void Always_IsTheSecondChildMaterial() { Material body = new SolidColorMaterial(); CheckEqual(body, new FramedMaterial(new SolidColorMaterial(), body).Body); } } public class IsBodyInsetTests : TestFixture { public void Default_IsTrue() { CheckTrue(new FramedMaterial(null, null).IsBodyInset); } } public class IsBodyOnTopTests : TestFixture { public void Default_IsTrue() { CheckTrue(new FramedMaterial(null, null).IsBodyOnTop); } } public class BodyBoundsTests : TestFixture { public void Inset_IsTheChromesViewport() { var framed = new FramedMaterial(Bordered(1, 2, 3, 4), new SolidColorMaterial()); CheckEqual(Box(11, 22, 96, 44), framed.BodyBounds(ControlBounds)); } public void NotInset_IsTheWholeRect() { var framed = new FramedMaterial(Bordered(1, 2, 3, 4), new SolidColorMaterial()) { IsBodyInset = false, }; CheckEqual(ControlBounds, framed.BodyBounds(ControlBounds)); } public void NullChrome_IsTheWholeRect() { var framed = new FramedMaterial(null, new SolidColorMaterial()); CheckEqual(ControlBounds, framed.BodyBounds(ControlBounds)); } } public class PreferredSizeTests : TestFixture { public void Inset_AddsTheChromesBorderAroundTheBody() { var framed = new FramedMaterial(Bordered(1, 2, 3, 4), new SizedMaterial(new Vector(40, 16))); CheckEqual(new Vector(44, 22), framed.PreferredSize(Constraints.Unbounded)); } public void Inset_TheChromesOwnSizeIsAFloor() { var chrome = new SizedMaterial(new Vector(100, 60)) { BorderSize = OneAllRound }; var framed = new FramedMaterial(chrome, new SizedMaterial(new Vector(40, 16))); CheckEqual(new Vector(100, 60), framed.PreferredSize(Constraints.Unbounded)); } public void NotInset_TakesTheLargerOfTheTwoOnEachAxis() { var chrome = new SizedMaterial(new Vector(40, 10)) { BorderSize = Border(5, 5, 5, 5) }; var framed = new FramedMaterial(chrome, new SizedMaterial(new Vector(20, 30))) { IsBodyInset = false }; CheckEqual(new Vector(40, 30), framed.PreferredSize(Constraints.Unbounded)); } public void NullChrome_IsTheBodySize() { var framed = new FramedMaterial(null, new SizedMaterial(new Vector(40, 16))); CheckEqual(new Vector(40, 16), framed.PreferredSize(Constraints.Unbounded)); } public void NullBody_IsTheChromesSize() { var framed = new FramedMaterial(new SizedMaterial(new Vector(40, 16)), null); CheckEqual(new Vector(40, 16), framed.PreferredSize(Constraints.Unbounded)); } public void Scaled_ScalesTheFramedSize() { var framed = new FramedMaterial(Bordered(1, 2, 3, 4), new SizedMaterial(new Vector(40, 16))) { Scale = 2, }; CheckEqual(new Vector(88, 44), framed.PreferredSize(Constraints.Unbounded)); } } public class MinimumSizeTests : TestFixture { public void Inset_AddsTheChromesBorderAroundTheBodyMinimum() { var framed = new FramedMaterial( Bordered(1, 2, 3, 4), new SizedMaterial(new Vector(40, 40), minimum: new Vector(5, 8))); CheckEqual(new Vector(9, 14), framed.MinimumSize(Constraints.Unbounded)); } public void NotInset_TakesTheLargerOfTheTwoOnEachAxis() { var chrome = new SizedMaterial(new Vector(40, 40), minimum: new Vector(5, 8)) { BorderSize = Border(5, 5, 5, 5), }; var body = new SizedMaterial(new Vector(40, 40), minimum: new Vector(7, 3)); var framed = new FramedMaterial(chrome, body) { IsBodyInset = false }; CheckEqual(new Vector(7, 8), framed.MinimumSize(Constraints.Unbounded)); } } public class ViewportRectTests : TestFixture { public void Inset_ChainsTheBodyViewportInsideTheChromes() { var framed = new FramedMaterial(Bordered(1, 2, 3, 4), Bordered(1, 1, 1, 1)); CheckEqual(Box(12, 23, 94, 42), framed.ViewportRect(ControlBounds)); } public void NotInset_IsTheChromesAlone() { var framed = new FramedMaterial(Bordered(1, 2, 3, 4), Bordered(1, 1, 1, 1)) { IsBodyInset = false }; CheckEqual(Box(11, 22, 96, 44), framed.ViewportRect(ControlBounds)); } public void NullChrome_IsTheBodyViewport() { var framed = new FramedMaterial(null, Bordered(1, 1, 1, 1)); CheckEqual(Box(11, 21, 98, 48), framed.ViewportRect(ControlBounds)); } public void BothNull_IsTheWholeBounds() { CheckEqual(ControlBounds, new FramedMaterial(null, null).ViewportRect(ControlBounds)); } public void Scaled_ScalesBothBorders() { var framed = new FramedMaterial(Bordered(1, 1, 1, 1), Bordered(1, 1, 1, 1)) { Scale = 2 }; CheckEqual(Box(14, 24, 92, 42), framed.ViewportRect(ControlBounds)); } } public class ViewportSizeForTests : TestFixture { public static readonly Constraints TightBounds = Constraints.Tight(ControlBounds.Size); public void Inset_ChainsTheBodyViewportInsideTheChromes() { var framed = new FramedMaterial(Bordered(1, 2, 3, 4), Bordered(1, 1, 1, 1)); CheckEqual(new Vector(94, 42), framed.ViewportSizeFor(TightBounds)); } public void NotInset_IsTheChromesAlone() { var framed = new FramedMaterial(Bordered(1, 2, 3, 4), Bordered(1, 1, 1, 1)) { IsBodyInset = false }; CheckEqual(new Vector(96, 44), framed.ViewportSizeFor(TightBounds)); } public void BothNull_IsTheWholeBoundsSize() { CheckEqual(ControlBounds.Size, new FramedMaterial(null, null).ViewportSizeFor(TightBounds)); } public void Scaled_ScalesBothBorders() { var framed = new FramedMaterial(Bordered(1, 1, 1, 1), Bordered(1, 1, 1, 1)) { Scale = 2 }; CheckEqual(new Vector(92, 42), framed.ViewportSizeFor(TightBounds)); } } public class BoundsSizeForTests : TestFixture { public void Inset_ChainsTheChromesBorderAroundTheBody() { var framed = new FramedMaterial(Bordered(1, 2, 3, 4), Bordered(1, 1, 1, 1)); CheckEqual(new Vector(106, 58), framed.BoundsSizeFor(ControlBounds.Size)); } public void NotInset_IsTheChromesAlone() { var framed = new FramedMaterial(Bordered(1, 2, 3, 4), Bordered(1, 1, 1, 1)) { IsBodyInset = false }; CheckEqual(new Vector(104, 56), framed.BoundsSizeFor(ControlBounds.Size)); } public void BothNull_IsTheViewportSize() { CheckEqual(ControlBounds.Size, new FramedMaterial(null, null).BoundsSizeFor(ControlBounds.Size)); } public void Scaled_ScalesBothBorders() { var framed = new FramedMaterial(Bordered(1, 1, 1, 1), Bordered(1, 1, 1, 1)) { Scale = 2 }; CheckEqual(new Vector(108, 58), framed.BoundsSizeFor(ControlBounds.Size)); } public void Inset_InvertsViewportSizeFor() { var framed = new FramedMaterial(Bordered(1, 2, 3, 4), Bordered(1, 1, 1, 1)) { Scale = 2 }; Vector bounds = framed.BoundsSizeFor(ControlBounds.Size); CheckEqual(ControlBounds.Size, framed.ViewportSizeFor(Constraints.Tight(bounds))); } public void NotInset_InvertsViewportSizeFor() { var framed = new FramedMaterial(Bordered(1, 2, 3, 4), Bordered(1, 1, 1, 1)) { IsBodyInset = false, Scale = 2, }; Vector bounds = framed.BoundsSizeFor(ControlBounds.Size); CheckEqual(ControlBounds.Size, framed.ViewportSizeFor(Constraints.Tight(bounds))); } } } }