using Annulus; using Azimuth; using System; using UnitTestSharp; namespace Glass.UnitTests { public class GroupBoxMaterialTests : TestFixture { public record FixedCell : SolidColorMaterial { public FixedCell() { LayoutSizingX = LayoutSizing.Intrinsic; LayoutSizingY = LayoutSizing.Intrinsic; } protected override Vector PreferredSizeInModelSpace(Constraints constraints) { return new Vector(4, 4); } protected override Vector MinimumSizeInModelSpace(Constraints constraints) { return new Vector(4, 4); } } public static readonly Rect.BorderSize FrameBorder = new Rect.BorderSize { Top = 2, Bottom = 2, Left = 3, Right = 3 }; public static NineSliceMaterial Plain(int edge = 2) { return new NineSliceMaterial { BorderSize = FrameBorder with { Top = edge } }; } // A nine slice whose corners are 4 wide. public static NineSliceMaterial Cornered() { var returnMe = new NineSliceMaterial { BorderSize = FrameBorder }; for (int i = 0; i < 9; ++i) { ((Material[])returnMe.ChildMaterials)[i] = new FixedCell(); } ((Material[])returnMe.ChildMaterials)[4] = Material.Invisible; return returnMe; } // The caption is 14 tall with its baseline 10 down, and starts 4 in. public static GroupBoxMaterial Captioned(NineSliceMaterial frame = null) { return new GroupBoxMaterial { Background = null, Frame = frame ?? Plain(), CaptionStyle = GroupBoxTests.CaptionStyle(), CaptionOffset = 4, CaptionPlacement = CaptionPlacement.Baseline, }; } public class CaptionOffsetTests : TestFixture { public void Negative_Throws() { CheckThrow(typeof(ArgumentOutOfRangeException)); var material = new GroupBoxMaterial { Background = null, Frame = null, CaptionOffset = -1 }; } public void NotANumber_Throws() { CheckThrow(typeof(ArgumentOutOfRangeException)); var material = new GroupBoxMaterial { Background = null, Frame = null, CaptionOffset = Scalar.NaN }; } public void Set_IsKept() { CheckEqual(6, new GroupBoxMaterial { Background = null, Frame = null, CaptionOffset = 6, }.CaptionOffset); } public void Zero_IsKeptRatherThanDerived() { var material = new GroupBoxMaterial { Background = null, Frame = null, CaptionStyle = GroupBoxTests.CaptionStyle(), CaptionOffset = 0, }; CheckEqual(0, material.CaptionOffset); } public void Unset_IsHalfALineOfTheFont() { var material = new GroupBoxMaterial { Background = null, Frame = null, CaptionStyle = GroupBoxTests.CaptionStyle(), }; CheckEqual(5, material.CaptionOffset); } public void Unset_GrowsWithTheStyleScale() { var material = new GroupBoxMaterial { Background = null, Frame = null, CaptionStyle = GroupBoxTests.CaptionStyle() with { Scale = 2 }, }; CheckEqual(10, material.CaptionOffset); } public void Unset_WithoutAFontIsZero() { CheckEqual(0, new GroupBoxMaterial { Background = null, Frame = null }.CaptionOffset); } } public class FrameInsetTests : TestFixture { public void Negative_Throws() { CheckThrow(typeof(ArgumentOutOfRangeException)); var material = new GroupBoxMaterial { Background = null, Frame = null, FrameInset = -1 }; } public void NotANumber_Throws() { CheckThrow(typeof(ArgumentOutOfRangeException)); var material = new GroupBoxMaterial { Background = null, Frame = null, FrameInset = Scalar.NaN }; } public void Positive_IsKept() { CheckEqual(6, new GroupBoxMaterial { Background = null, Frame = null, FrameInset = 6 }.FrameInset); } } public class ChildMaterialsTests : TestFixture { public void AreTheBackgroundThenTheFrame() { var background = new SolidColorMaterial(); var frame = new NineSliceMaterial(); var material = new GroupBoxMaterial { Background = background, Frame = frame }; CheckEqual(2, material.ChildMaterials.Count); CheckTrue(ReferenceEquals(background, material.ChildMaterials[0])); CheckTrue(ReferenceEquals(frame, material.ChildMaterials[1])); } public void Unset_AreNull() { var material = new GroupBoxMaterial { Background = null, Frame = null }; CheckNull(material.Background); CheckNull(material.Frame); } public void SettingOneKeepsTheOther() { var background = new SolidColorMaterial(); var material = new GroupBoxMaterial { Frame = null, Background = background }; GroupBoxMaterial copy = material with { Frame = new NineSliceMaterial() }; CheckTrue(ReferenceEquals(background, copy.Background)); CheckNull(material.Frame); } } public class WithTests : TestFixture { public void CopiesEveryCaptionSetting() { GroupBoxMaterial original = new GroupBoxMaterial { Background = null, Frame = null, CaptionStyle = GroupBoxTests.CaptionStyle(), CaptionPlacement = CaptionPlacement.Middle, CaptionOffset = 1, FrameInset = 4, }; GroupBoxMaterial copy = original with { FrameInset = 9 }; CheckEqual(original.CaptionStyle, copy.CaptionStyle); CheckEqual(CaptionPlacement.Middle, copy.CaptionPlacement); CheckEqual(1, copy.CaptionOffset); CheckEqual(9, copy.FrameInset); } public void CopyOfAnUnsetOffset_StillDerivesIt() { var original = new GroupBoxMaterial { Background = null, Frame = null, CaptionStyle = GroupBoxTests.CaptionStyle(), }; GroupBoxMaterial copy = original with { FrameInset = 9 }; CheckEqual(5, copy.CaptionOffset); } } public class CaptionPlacementTests : TestFixture { public void DefaultsToMiddle() { CheckEqual(CaptionPlacement.Middle, new GroupBoxMaterial { Background = null, Frame = null, }.CaptionPlacement); } } public class ScaleTests : TestFixture { public void FrameMetrics_CompoundTheMaterialsScaleWithTheFramesOwn() { GroupBoxMaterial material = Captioned(Cornered() with { Scale = 2 }) with { Scale = 3 }; CheckEqual(4, Captioned(Cornered()).LeftCornerWidth); CheckEqual(24, material.LeftCornerWidth); CheckEqual(24, material.RightCornerWidth); CheckEqual(12, material.EdgeThickness); } public void FrameInset_ScalesWithTheMaterial() { GroupBoxMaterial material = Captioned(Cornered()) with { FrameInset = 6, Scale = 2 }; CheckEqual(12 + 8 + 8, material.GapStart); CheckEqual(12, material.FrameRect(Rect.FromPositionAndSize(Vector.Zero, new Vector(100, 100))).Left); } public void CaptionHeight_ScalesWithTheMaterial() { CheckEqual(28, (Captioned() with { Scale = 2 }).CaptionHeight); } public void CaptionHeight_CompoundsTheStyleScaleWithTheMaterials() { GroupBoxMaterial material = Captioned() with { CaptionStyle = GroupBoxTests.CaptionStyle() with { Scale = 3 }, Scale = 2, }; CheckEqual(84, material.CaptionHeight); } public void CaptionOffset_IsKeptBeforeTheMaterialsScale() { CheckEqual(4, (Captioned() with { Scale = 2 }).CaptionOffset); } public void GapStart_ScalesTheCaptionOffset() { GroupBoxMaterial material = Captioned(Cornered()) with { Scale = 2 }; CheckEqual(8 + 8, material.GapStart); } public void WidthForCaption_ScalesTheOffsetOnBothSidesOfTheCaption() { GroupBoxMaterial material = Captioned(Cornered()) with { Scale = 2 }; CheckEqual(16 + 30 + 8 + 8, material.WidthForCaption(30)); } public void FrameTopOffset_BaselineScalesTheCaptionNotTheEdgeTwice() { GroupBoxMaterial material = Captioned() with { Scale = 2 }; CheckEqual(20 - 2, material.FrameTopOffset); } public void FrameTopOffset_MiddleScalesTheCaptionHeight() { GroupBoxMaterial material = Captioned() with { CaptionPlacement = CaptionPlacement.Middle, Scale = 2 }; CheckEqual(14 - 2, material.FrameTopOffset); } public void FrameTopOffset_AboveIsTheScaledCaptionHeight() { GroupBoxMaterial material = Captioned() with { CaptionPlacement = CaptionPlacement.Above, Scale = 2 }; CheckEqual(28, material.FrameTopOffset); } } public class EdgeThicknessTests : TestFixture { public void IsTheFramesTopBorder() { CheckEqual(3, Captioned(Plain(edge: 3)).EdgeThickness); } public void ScalesWithTheFrame() { CheckEqual(6, Captioned(Plain(edge: 3) with { Scale = 2 }).EdgeThickness); } public void NoFrame_IsZero() { CheckEqual(0, new GroupBoxMaterial { Background = null, Frame = null }.EdgeThickness); } } public class CornerWidthTests : TestFixture { public void NineSlice_IsItsCornerColumns() { GroupBoxMaterial material = Captioned(Cornered()); CheckEqual(4, material.LeftCornerWidth); CheckEqual(4, material.RightCornerWidth); } public void ScaledNineSlice_IsInControlUnits() { GroupBoxMaterial material = Captioned(Cornered() with { Scale = 2 }); CheckEqual(8, material.LeftCornerWidth); CheckEqual(8, material.RightCornerWidth); } public void OtherMaterials_HaveNoCorners() { GroupBoxMaterial material = Captioned(Plain()); CheckEqual(0, material.LeftCornerWidth); CheckEqual(0, material.RightCornerWidth); } public void NoFrame_HasNoCorners() { CheckEqual(0, new GroupBoxMaterial { Background = null, Frame = null }.LeftCornerWidth); CheckEqual(0, new GroupBoxMaterial { Background = null, Frame = null }.RightCornerWidth); } } public class CaptionHeightTests : TestFixture { public void IsOneLineOfTheStyle() { CheckEqual(14, Captioned().CaptionHeight); } public void NoFont_IsZero() { CheckEqual(0, new GroupBoxMaterial { Background = null, Frame = Plain() }.CaptionHeight); } public void GrowsWithTheStyleScale() { GroupBoxMaterial material = Captioned() with { CaptionStyle = GroupBoxTests.CaptionStyle() with { Scale = 2 }, }; CheckEqual(28, material.CaptionHeight); } } public class FrameTopOffsetTests : TestFixture { public void NoFont_IsZero() { CheckEqual(0, new GroupBoxMaterial { Background = null, Frame = Plain() }.FrameTopOffset); } public void Baseline_RunsTheEdgeThroughTheBaseline() { CheckEqual(9, Captioned().FrameTopOffset); } public void Middle_RunsTheEdgeThroughTheMiddleOfTheCaption() { CheckEqual(6, (Captioned() with { CaptionPlacement = CaptionPlacement.Middle }).FrameTopOffset); } public void Above_HangsTheFrameBelowTheCaption() { CheckEqual(14, (Captioned() with { CaptionPlacement = CaptionPlacement.Above }).FrameTopOffset); } public void HalfUnitEdge_RoundsTheOffsetUp() { CheckEqual(9, Captioned(Plain(edge: 3)).FrameTopOffset); } public void ScaledFrame_StraddlesItsThickerEdge() { CheckEqual(8, Captioned(Plain() with { Scale = 2 }).FrameTopOffset); } public void EdgeThickerThanTheBaseline_ClampsAtZero() { CheckEqual(0, Captioned(Plain(edge: 40)).FrameTopOffset); } public void UnknownPlacement_Throws() { CheckThrow(typeof(InvalidOperationException)); Scalar offset = (Captioned() with { CaptionPlacement = (CaptionPlacement)99 }).FrameTopOffset; } } public class GapStartTests : TestFixture { public void IsTheCaptionOffset() { CheckEqual(4, Captioned().GapStart); } public void IsPastTheInsetAndTheCorner() { GroupBoxMaterial material = Captioned(Cornered()) with { FrameInset = 6 }; CheckEqual(14, material.GapStart); } } public class ContentTopInsetTests : TestFixture { public void Captioned_IsTheCaptionHeight() { CheckEqual(14, Captioned().ContentTopInset); } public void LowFrameEdge_IsTheEdgesBottom() { CheckEqual(16, (Captioned() with { CaptionPlacement = CaptionPlacement.Above }).ContentTopInset); } public void NoCaptionFont_IsTheFramesEdge() { CheckEqual(2, new GroupBoxMaterial { Background = null, Frame = Plain() }.ContentTopInset); } } public class ViewportRectTests : TestFixture { private static readonly Rect Bounds = Rect.FromPositionAndSize(Vector.Zero, new Vector(100, 80)); public void Captioned_ErodesTheFramesBorderAndTheCaptionStrip() { CheckEqual( Rect.FromPositionAndSize(new Vector(3, 14), new Vector(94, 64)), Captioned().ViewportRect(Bounds)); } public void FrameInset_ErodesLeftRightAndBottomToo() { GroupBoxMaterial material = Captioned() with { FrameInset = 6 }; CheckEqual( Rect.FromPositionAndSize(new Vector(9, 14), new Vector(82, 58)), material.ViewportRect(Bounds)); } public void ScaledFrame_ScalesItsBorder() { GroupBoxMaterial material = Captioned(Plain() with { Scale = 2 }); CheckEqual( Rect.FromPositionAndSize(new Vector(6, 14), new Vector(88, 62)), material.ViewportRect(Bounds)); } public void NoFrame_ErodesJustTheCaptionStrip() { var material = new GroupBoxMaterial { Background = null, Frame = null, CaptionStyle = GroupBoxTests.CaptionStyle(), }; CheckEqual( Rect.FromPositionAndSize(new Vector(0, 14), new Vector(100, 66)), material.ViewportRect(Bounds)); } } public class BoundsSizeForTests : TestFixture { public void AddsTheFrameAndTheCaptionStrip() { CheckEqual(new Vector(56, 56), Captioned().BoundsSizeFor(new Vector(50, 40))); } public void FrameInset_AddsToBothSidesAndTheBottom() { CheckEqual(new Vector(68, 62), (Captioned() with { FrameInset = 6 }).BoundsSizeFor(new Vector(50, 40))); } public void FramesMinimum_IsRespected() { Vector bounds = Captioned(Cornered()).BoundsSizeFor(new Vector(1, 1)); CheckEqual(new Vector(8, 20), bounds); } public void NoFrame_AddsJustTheCaptionStrip() { var material = new GroupBoxMaterial { Background = null, Frame = null, CaptionStyle = GroupBoxTests.CaptionStyle(), }; CheckEqual(new Vector(50, 54), material.BoundsSizeFor(new Vector(50, 40))); } public void IsTheInverseOfViewportRect() { GroupBoxMaterial material = Captioned(Plain() with { Scale = 2 }) with { FrameInset = 6 }; Vector viewport = new Vector(50, 40); Vector bounds = material.BoundsSizeFor(viewport); CheckEqual(viewport, material.ViewportRect(Rect.FromPositionAndSize(Vector.Zero, bounds)).Size); } } public class WidthForCaptionTests : TestFixture { public void HoldsTheCaptionAndTheSameEdgeOnEachSide() { CheckEqual(34, Captioned().WidthForCaption(26)); } public void IncludesTheCornersAndTheInset() { GroupBoxMaterial material = Captioned(Cornered()) with { FrameInset = 6 }; CheckEqual(54, material.WidthForCaption(26)); } } public class FrameRectTests : TestFixture { private static readonly Rect Whole = Rect.FromPositionAndSize(new Vector(10, 20), new Vector(100, 80)); public void NoCaption_IsTheWholeRect() { CheckEqual(Whole, new GroupBoxMaterial { Background = null, Frame = Plain() }.FrameRect(Whole)); } public void Captioned_TakesTheStripOffTheTop() { CheckEqual( Rect.FromPositionAndSize(new Vector(10, 29), new Vector(100, 71)), Captioned().FrameRect(Whole)); } public void FrameInset_LeavesTheMarginOnThreeSides() { GroupBoxMaterial material = Captioned() with { FrameInset = 6 }; CheckEqual( Rect.FromPositionAndSize(new Vector(16, 29), new Vector(88, 65)), material.FrameRect(Whole)); } public void FrameInsetBiggerThanTheRect_LeavesAnEmptyFrame() { GroupBoxMaterial material = Captioned() with { FrameInset = 60 }; Rect tiny = Rect.FromPositionAndSize(Vector.Zero, new Vector(20, 15)); Rect frame = material.FrameRect(tiny); CheckEqual(0, frame.Width); CheckEqual(0, frame.Height); } public void OffsetPastTheBottom_LeavesAnEmptyFrameAtTheBottom() { GroupBoxMaterial material = Captioned() with { CaptionStyle = GroupBoxTests.CaptionStyle() with { VerticalMargin = 492 }, }; CheckEqual( Rect.FromPositionAndSize(new Vector(10, 100), new Vector(100, 0)), material.FrameRect(Whole)); } } } }