using System; using Annulus; using Azimuth; using UnitTestSharp; namespace Glass.UnitTests { public class CheckboxTests : TestFixture { public class CheckedTests : TestFixture { public void SettingToNewValueRaisesOnCheckedChangedWithThatValue() { var checkBox = new Checkbox(); bool? raisedWith = null; checkBox.OnCheckedChanged +=value => raisedWith = value; checkBox.Checked = true; CheckEqual(true, raisedWith); } public void SettingToTheSameValueDoesNotRaise() { var checkBox = new Checkbox(); checkBox.Checked = true; bool raised = false; checkBox.OnCheckedChanged +=_ => raised = true; checkBox.Checked = true; CheckFalse(raised); } public void DefaultsToUnchecked() { CheckFalse(new Checkbox().Checked); } } public class ToggleTests : TestFixture { public void FlipsUncheckedToChecked() { var checkBox = new Checkbox(); checkBox.Toggle(); Check(checkBox.Checked); } public void FlipsCheckedToUnchecked() { var checkBox = new Checkbox { Checked = true }; checkBox.Toggle(); CheckFalse(checkBox.Checked); } public void RaisesOnCheckedChangedOnEachFlip() { var checkBox = new Checkbox(); int raiseCount = 0; checkBox.OnCheckedChanged +=_ => ++raiseCount; checkBox.Toggle(); checkBox.Toggle(); CheckEqual(2, raiseCount); } } public class ClickTests : TestFixture { public void TogglesChecked() { var checkBox = new Checkbox(); checkBox.Click(new MouseState(), MouseButtonFlags.Left); Check(checkBox.Checked); } public void OnClickSeesTheUpdatedCheckedValue() { var checkBox = new Checkbox(); bool? checkedDuringCallback = null; checkBox.OnClick += (in MouseState _, MouseButtonFlags __) => checkedDuringCallback = checkBox.Checked; checkBox.Click(new MouseState(), MouseButtonFlags.Left); CheckEqual(true, checkedDuringCallback); } public void ReturnsTrueWithNoOnClickHandler() { var checkBox = new Checkbox(); Check(checkBox.Click(new MouseState(), MouseButtonFlags.Left)); } public void ReturnsTrueWithAnOnClickHandler() { var checkBox = new Checkbox(); checkBox.OnClick += (in MouseState _, MouseButtonFlags __) => { }; Check(checkBox.Click(new MouseState(), MouseButtonFlags.Left)); } public void DisabledDoesNotToggle() { var checkBox = new Checkbox { Enabled = false }; checkBox.Click(new MouseState(), MouseButtonFlags.Left); CheckFalse(checkBox.Checked); } public void DisabledDoesNotRaiseOnCheckedChanged() { var checkBox = new Checkbox { Enabled = false }; bool raised = false; checkBox.OnCheckedChanged +=_ => raised = true; checkBox.Click(new MouseState(), MouseButtonFlags.Left); CheckFalse(raised); } public void DisabledReturnsFalse() { var checkBox = new Checkbox { Enabled = false }; CheckFalse(checkBox.Click(new MouseState(), MouseButtonFlags.Left)); } } public class MaterialTests : TestFixture { static ButtonMaterial UncheckedSet = new ButtonMaterial { NominalMaterial = new Material { DebugName = "uncheckedNominal" }, HoverMaterial = new Material { DebugName = "uncheckedHover" }, PressedMaterial = new Material { DebugName = "uncheckedPressed" }, HoverPressedMaterial = new Material { DebugName = "uncheckedHoverPressed" }, DisabledMaterial = new Material { DebugName = "uncheckedDisabled" }, }; static ButtonMaterial CheckedSet = new ButtonMaterial { NominalMaterial = new Material { DebugName = "checkedNominal" }, HoverMaterial = new Material { DebugName = "checkedHover" }, PressedMaterial = new Material { DebugName = "checkedPressed" }, HoverPressedMaterial = new Material { DebugName = "checkedHoverPressed" }, DisabledMaterial = new Material { DebugName = "checkedDisabled" }, }; Checkbox checkBox; public override void TestSetup() { checkBox = new Checkbox { UncheckedMaterial = UncheckedSet, CheckedMaterial = CheckedSet, }; } public void UncheckedDrawsFromUncheckedMaterial() { CheckEqual(UncheckedSet.NominalMaterial, checkBox.Material); } public void CheckedDrawsFromCheckedMaterial() { checkBox.Checked = true; CheckEqual(CheckedSet.NominalMaterial, checkBox.Material); } public void HoverIsReflectedWithinTheActiveSet() { checkBox.Checked = true; checkBox.HoveredOver = true; CheckEqual(CheckedSet.HoverMaterial, checkBox.Material); } public void PressIsReflectedWithinTheActiveSet() { checkBox.ButtonsDown = MouseButtonFlags.Left; CheckEqual(UncheckedSet.PressedMaterial, checkBox.Material); } public void DisabledDrawsTheActiveSetsDisabledSlot() { checkBox.Checked = true; checkBox.Enabled = false; CheckEqual(CheckedSet.DisabledMaterial, checkBox.Material); } public void TogglingSwapsWhichSetMaterialDrawsFrom() { CheckEqual(UncheckedSet.NominalMaterial, checkBox.Material); checkBox.Toggle(); CheckEqual(CheckedSet.NominalMaterial, checkBox.Material); } } public class MaterialRectTests : TestFixture { // A 16px sheet at Scale 2 gives a 32px indicator box. static ButtonMaterial Indicator => new ButtonMaterial(SpriteMaterialTests.WithSheet(16, 16, lockAspectRatio: false) with { Scale = 2 }); static Checkbox NewCheckbox(Rect bounds, Anchor anchor = Anchor.Left, Alignment.Linear alignment = Alignment.Linear.Center) { return new Checkbox { UncheckedMaterial = Indicator, CheckedMaterial = Indicator, IndicatorAnchor = anchor, IndicatorAlignment = alignment, Bounds = bounds, }; } public void AnchorLeft_BoxHugsTheLeftEdgeCenteredVertically() { Checkbox checkBox = NewCheckbox(Rect.FromPositionAndSize(Vector.Zero, new Vector(200, 40))); Rect box = checkBox.MaterialRect; CheckEqual(new Vector(0, 4), box.TopLeft); CheckEqual(new Vector(32, 32), box.Size); } public void AnchorRight_BoxHugsTheRightEdge() { Checkbox checkBox = NewCheckbox(Rect.FromPositionAndSize(Vector.Zero, new Vector(200, 40)), Anchor.Right); CheckEqual(new Vector(168, 4), checkBox.MaterialRect.TopLeft); } public void AnchorTop_BoxHugsTheTopEdgeCenteredHorizontally() { Checkbox checkBox = NewCheckbox(Rect.FromPositionAndSize(Vector.Zero, new Vector(200, 100)), Anchor.Top); CheckEqual(new Vector(84, 0), checkBox.MaterialRect.TopLeft); } public void AnchorBottom_BoxHugsTheBottomEdge() { Checkbox checkBox = NewCheckbox( Rect.FromPositionAndSize(Vector.Zero, new Vector(200, 100)), Anchor.Bottom); CheckEqual(new Vector(84, 68), checkBox.MaterialRect.TopLeft); } public void AlignmentStart_PushesToTheStartOfTheFreeAxis() { Checkbox checkBox = NewCheckbox( Rect.FromPositionAndSize(Vector.Zero, new Vector(200, 40)), Anchor.Left, Alignment.Linear.Start); CheckEqual(new Vector(0, 0), checkBox.MaterialRect.TopLeft); } public void AlignmentEnd_PushesToTheEndOfTheFreeAxis() { Checkbox checkBox = NewCheckbox( Rect.FromPositionAndSize(Vector.Zero, new Vector(200, 40)), Anchor.Left, Alignment.Linear.End); CheckEqual(new Vector(0, 8), checkBox.MaterialRect.TopLeft); } public void FollowsBoundsPosition() { Checkbox checkBox = NewCheckbox(Rect.FromPositionAndSize(new Vector(10, 20), new Vector(200, 40))); CheckEqual(new Vector(10, 24), checkBox.MaterialRect.TopLeft); } public void IndicatorLargerThanBounds_ClampsAndStaysInside() { Rect bounds = Rect.FromPositionAndSize(new Vector(5, 5), new Vector(20, 10)); Checkbox checkBox = NewCheckbox(bounds); Rect box = checkBox.MaterialRect; CheckEqual(new Vector(20, 10), box.Size); CheckEqual(box, bounds.Intersection(box).Value); } public void NoMaterial_BoxIsEmpty() { var checkBox = new Checkbox { Bounds = Rect.FromPositionAndSize(Vector.Zero, new Vector(200, 40)) }; CheckEqual(Vector.Zero, checkBox.MaterialRect.Size); } } public class ViewportRectTests : TestFixture { // A 16px sheet at Scale 2 gives a 32px indicator strip. static ButtonMaterial Indicator => new ButtonMaterial(SpriteMaterialTests.WithSheet(16, 16, lockAspectRatio: false) with { Scale = 2 }); static Checkbox NewCheckbox(Rect bounds, Anchor anchor = Anchor.Left) { return new Checkbox { UncheckedMaterial = Indicator, CheckedMaterial = Indicator, IndicatorAnchor = anchor, Bounds = bounds, }; } public void AnchorLeft_IsTheRightRemainder() { Checkbox checkBox = NewCheckbox(Rect.FromPositionAndSize(Vector.Zero, new Vector(200, 40))); Rect viewport = checkBox.ViewportRect; CheckEqual(new Vector(32, 0), viewport.TopLeft); CheckEqual(new Vector(168, 40), viewport.Size); } public void AnchorRight_IsTheLeftRemainder() { Checkbox checkBox = NewCheckbox(Rect.FromPositionAndSize(Vector.Zero, new Vector(200, 40)), Anchor.Right); Rect viewport = checkBox.ViewportRect; CheckEqual(new Vector(0, 0), viewport.TopLeft); CheckEqual(new Vector(168, 40), viewport.Size); } public void AnchorTop_IsTheBottomRemainder() { Checkbox checkBox = NewCheckbox(Rect.FromPositionAndSize(Vector.Zero, new Vector(200, 100)), Anchor.Top); Rect viewport = checkBox.ViewportRect; CheckEqual(new Vector(0, 32), viewport.TopLeft); CheckEqual(new Vector(200, 68), viewport.Size); } public void AnchorBottom_IsTheTopRemainder() { Checkbox checkBox = NewCheckbox( Rect.FromPositionAndSize(Vector.Zero, new Vector(200, 100)), Anchor.Bottom); Rect viewport = checkBox.ViewportRect; CheckEqual(new Vector(0, 0), viewport.TopLeft); CheckEqual(new Vector(200, 68), viewport.Size); } public void FollowsBoundsPosition() { Checkbox checkBox = NewCheckbox(Rect.FromPositionAndSize(new Vector(10, 20), new Vector(200, 40))); Rect viewport = checkBox.ViewportRect; CheckEqual(new Vector(42, 20), viewport.TopLeft); CheckEqual(new Vector(168, 40), viewport.Size); } public void FollowsBoundsResize() { Checkbox checkBox = NewCheckbox(Rect.FromPositionAndSize(Vector.Zero, new Vector(200, 40))); checkBox.Bounds = Rect.FromPositionAndSize(Vector.Zero, new Vector(120, 40)); CheckEqual(new Vector(88, 40), checkBox.ViewportRect.Size); } public void NoMaterial_IsTheWholeBounds() { var checkBox = new Checkbox { Bounds = Rect.FromPositionAndSize(Vector.Zero, new Vector(200, 40)) }; CheckEqual(new Vector(200, 40), checkBox.ViewportRect.Size); } public void IndicatorWiderThanBounds_Collapses() { Checkbox checkBox = NewCheckbox(Rect.FromPositionAndSize(Vector.Zero, new Vector(20, 40))); CheckEqual(new Vector(0, 40), checkBox.ViewportRect.Size); } public void IndicatorAlignmentDoesNotMoveIt() { Checkbox checkBox = NewCheckbox(Rect.FromPositionAndSize(Vector.Zero, new Vector(200, 40))); checkBox.IndicatorAlignment = Alignment.Linear.End; Rect viewport = checkBox.ViewportRect; CheckEqual(new Vector(32, 0), viewport.TopLeft); CheckEqual(new Vector(168, 40), viewport.Size); } } public class CancelMouseInputTests : TestFixture { public void ClearsHoverAndPress() { var checkBox = new Checkbox { HoveredOver = true, ButtonsDown = MouseButtonFlags.Left, }; checkBox.CancelMouseInput(); CheckFalse(checkBox.HoveredOver); CheckEqual(MouseButtonFlags.None, checkBox.ButtonsDown); } public void LeavesCheckedUntouched() { var checkBox = new Checkbox { Checked = true }; checkBox.CancelMouseInput(); Check(checkBox.Checked); } } } }