using Annulus; using Azimuth; using System; using System.Collections.Generic; using System.Reflection; using UnitTestSharp; namespace Glass.UnitTests { public class DropdownPopupTests : TestFixture { public const int Thickness = 20; public static readonly Rect ScreenRect = Rect.FromPositionAndSize(Vector.Zero, new Vector(800, 600)); public static readonly Rect AnchorRect = Box(100, 200, 150, 30); public static readonly Vector ContentSize = new Vector(120, 100); public static readonly Vector InsideThePopup = new Vector(200, 280); public static readonly Vector OutsideThePopup = new Vector(700, 500); public static Rect Box(Scalar x, Scalar y, Scalar width, Scalar height) { return Rect.FromPositionAndSize(new Vector(x, y), new Vector(width, height)); } public static MouseState At(Vector position) { return new MouseState { Position = position, Buttons = MouseButtonFlags.Left }; } public static DropdownPopup NewPopup(Vector? contentSize = null) { return new DropdownPopup { ScrollViewMaterial = ScrollViewTests.WithBars(Thickness), ContentSize = contentSize ?? ContentSize, }; } public static void Tick(DropdownPopup popup, Rect anchor, Vector? screenSize = null) { popup.Update(TimeSpan.Zero, new UpdateState { ScreenSize = screenSize ?? ScreenRect.Size, ParentBounds = anchor, }); } public static DropdownPopup OpenAt(Rect anchor, Vector? contentSize = null) { DropdownPopup popup = NewPopup(contentSize); popup.Open(); Tick(popup, anchor); return popup; } [IgnoreTest] public static Control[] Rows(DropdownPopup popup) { var rows = new List(); foreach (Control row in popup.CanvasChildren.BackToFront()) { rows.Add(row); } return rows.ToArray(); } public class CtorTests : TestFixture { public void Always_EscapesTheOwnersSpaceZOrderAndClip() { var popup = new DropdownPopup(); CheckTrue(popup.Hoisted); CheckTrue(popup.AlwaysOnTop); CheckFalse(popup.ClipToAncestors); } public void Always_TakesFirstRefusalOnInput() { CheckTrue(new DropdownPopup().Modal); } public void Always_StartsClosedAndHidden() { var popup = new DropdownPopup(); CheckFalse(popup.IsOpen); CheckFalse(popup.Visible); } public void Always_ScrollsVerticallyOnly() { var popup = new DropdownPopup(); CheckFalse(popup.ScrollsHorizontally); CheckTrue(popup.ScrollsVertically); } public void Always_StartsWithNoHeightCap() { CheckTrue(Scalar.IsInfinity(new DropdownPopup().MaxHeight)); } public void Always_StartsWithNoItemButtonMaterial() { CheckEqual(default(ButtonMaterial), new DropdownPopup().ItemButtonMaterial); } public void Always_StartsAtZeroDropdownWidth() { CheckEqual(0, new DropdownPopup().DropdownWidth); } public void Always_StartsWithNothingSelected() { CheckNull(new DropdownPopup().SelectedIndex); } public void Always_StartsWithNoSelectedItemButtonMaterial() { CheckNull(new DropdownPopup().SelectedItemButtonMaterial); } } public class ItemButtonMaterialTests : TestFixture { public void Always_ChromesEachRow() { var popup = new DropdownPopup { DropdownWidth = 10 }; popup.ItemButtonMaterial = new ButtonMaterial(DropdownTests.Bordered3); popup.Rebuild(new[] { DropdownTests.NarrowLabel }); CheckEqual(new Vector(46, 22), Rows(popup)[0].Bounds.Size); } public void ChangingItAfterRebuild_RelaysOutTheExistingRows() { var popup = new DropdownPopup { DropdownWidth = 10 }; popup.Rebuild(new[] { DropdownTests.NarrowLabel }); popup.ItemButtonMaterial = new ButtonMaterial(DropdownTests.Bordered3); CheckEqual(new Vector(46, 22), Rows(popup)[0].Bounds.Size); } } public static readonly ButtonMaterial Item = DropdownTests.Arrow(1, 1); public static readonly ButtonMaterial Selected = DropdownTests.Arrow(2, 2); /// /// A popup of two narrow rows, with distinct item and selected materials that add no chrome. /// public static DropdownPopup TwoRowPopup() { var popup = new DropdownPopup { DropdownWidth = 10, ItemButtonMaterial = Item, SelectedItemButtonMaterial = Selected, }; popup.Rebuild(new[] { DropdownTests.NarrowLabel, DropdownTests.NarrowLabel }); return popup; } /// /// The ButtonMaterial a row frames its label in. /// [IgnoreTest] public static ButtonMaterial ChromeOfRow(DropdownPopup popup, int index) { ButtonMaterial framed = ((Button)Rows(popup)[index]).ButtonMaterial; Material ChromeOf(Material state) => ((FramedMaterial)state).Chrome; return new ButtonMaterial { NominalMaterial = ChromeOf(framed.NominalMaterial), HoverMaterial = ChromeOf(framed.HoverMaterial), PressedMaterial = ChromeOf(framed.PressedMaterial), HoverPressedMaterial = ChromeOf(framed.HoverPressedMaterial), DisabledMaterial = ChromeOf(framed.DisabledMaterial), }; } [IgnoreTest] public static Vector LabelSizeOfRow(DropdownPopup popup, int index) { var row = (Button)Rows(popup)[index]; var framed = (FramedMaterial)row.ButtonMaterial.NominalMaterial; return framed.BodyBounds(row.Bounds).Size; } public class SelectedItemButtonMaterialTests : TestFixture { public void ChangingItAfterSelecting_RewrapsTheSelectedRow() { DropdownPopup popup = TwoRowPopup(); popup.SelectedIndex = 1; ButtonMaterial replacement = DropdownTests.Arrow(3, 3); popup.SelectedItemButtonMaterial = replacement; CheckEqual(replacement, ChromeOfRow(popup, 1)); } public void Null_LeavesTheSelectedRowInTheItemMaterial() { DropdownPopup popup = TwoRowPopup(); popup.SelectedItemButtonMaterial = null; popup.SelectedIndex = 1; CheckEqual(Item, ChromeOfRow(popup, 1)); } public void ChromierThanTheItemMaterial_GrowsEveryRowToMatch() { DropdownPopup popup = TwoRowPopup(); popup.SelectedItemButtonMaterial = new ButtonMaterial(DropdownTests.Bordered3); CheckEqual(new Vector(46, 22), Rows(popup)[0].Bounds.Size); CheckEqual(new Vector(46, 22), Rows(popup)[1].Bounds.Size); } public void ChromierThanTheItemMaterial_InsetsOnlyTheSelectedRowsLabel() { DropdownPopup popup = TwoRowPopup(); popup.SelectedItemButtonMaterial = new ButtonMaterial(DropdownTests.Bordered3); popup.SelectedIndex = 1; CheckEqual(new Vector(46, 22), LabelSizeOfRow(popup, 0)); CheckEqual(new Vector(40, 16), LabelSizeOfRow(popup, 1)); } } public class SelectedIndexTests : TestFixture { public void ValidIndex_WrapsThatRowInTheSelectedMaterial() { DropdownPopup popup = TwoRowPopup(); popup.SelectedIndex = 1; CheckEqual(Selected, ChromeOfRow(popup, 1)); } public void ValidIndex_LeavesTheOtherRowsInTheItemMaterial() { DropdownPopup popup = TwoRowPopup(); popup.SelectedIndex = 1; CheckEqual(Item, ChromeOfRow(popup, 0)); } public void Moving_PutsThePreviousRowBackInTheItemMaterial() { DropdownPopup popup = TwoRowPopup(); popup.SelectedIndex = 1; popup.SelectedIndex = 0; CheckEqual(Selected, ChromeOfRow(popup, 0)); CheckEqual(Item, ChromeOfRow(popup, 1)); } public void Null_PutsEveryRowInTheItemMaterial() { DropdownPopup popup = TwoRowPopup(); popup.SelectedIndex = 1; popup.SelectedIndex = null; CheckEqual(Item, ChromeOfRow(popup, 0)); CheckEqual(Item, ChromeOfRow(popup, 1)); } public void NullWithNoItems_DoesNotThrow() { new DropdownPopup().SelectedIndex = null; } public void IndexEqualToCount_Throws() { DropdownPopup popup = TwoRowPopup(); CheckThrow(typeof(ArgumentOutOfRangeException)); popup.SelectedIndex = 2; } public void NegativeIndex_Throws() { DropdownPopup popup = TwoRowPopup(); CheckThrow(typeof(ArgumentOutOfRangeException)); popup.SelectedIndex = -1; } public void ClickingTheSelectedRow_FiresWithItsIndex() { DropdownPopup popup = TwoRowPopup(); popup.SelectedIndex = 1; int firedWith = -1; popup.OnItemClicked += index => firedWith = index; Rows(popup)[1].Click(default, MouseButtonFlags.Left); CheckEqual(1, firedWith); } } public class DropdownWidthTests : TestFixture { public void RowNarrowerThanIt_StretchesToFillIt() { var popup = new DropdownPopup { DropdownWidth = 200 }; popup.Rebuild(new[] { DropdownTests.NarrowLabel }); CheckEqual(200, Rows(popup)[0].Bounds.Width); } public void RowWiderThanIt_KeepsTheRowsOwnWidth() { var popup = new DropdownPopup { DropdownWidth = 10 }; popup.Rebuild(new[] { DropdownTests.WideLabel }); CheckEqual(90, Rows(popup)[0].Bounds.Width); } public void ChangingItAfterRebuild_RelaysOutTheExistingRows() { var popup = new DropdownPopup { DropdownWidth = 200 }; popup.Rebuild(new[] { DropdownTests.NarrowLabel }); popup.DropdownWidth = 300; CheckEqual(300, Rows(popup)[0].Bounds.Width); } public void BeforeAnyRebuild_HasNoEffect() { var popup = new DropdownPopup(); popup.ContentSize = new Vector(50, 50); popup.DropdownWidth = 200; CheckEqual(new Vector(50, 50), popup.ContentSize); } } public class ScrollViewMaterialTests : TestFixture { public void Getting_ReturnsWhatWasSet() { var popup = new DropdownPopup(); ScrollViewMaterial material = ScrollViewTests.WithBars(Thickness); popup.ScrollViewMaterial = material; CheckEqual(material, popup.ScrollViewMaterial); } public void Background_NarrowsARowByItsBorder() { var popup = new DropdownPopup { DropdownWidth = 200 }; popup.ScrollViewMaterial = new ScrollViewMaterial { Background = DropdownTests.Bordered3 }; popup.Rebuild(new[] { DropdownTests.NarrowLabel }); CheckEqual(194, Rows(popup)[0].Bounds.Width); } public void VerticalScrollBar_NeverNarrowsARowSinceThePopupWidensBesideItInstead() { var popup = new DropdownPopup { DropdownWidth = 200 }; popup.ScrollViewMaterial = new ScrollViewMaterial { VerticalScrollBar = ScrollViewTests.WithBars(20).VerticalScrollBar, }; popup.Rebuild(new[] { DropdownTests.NarrowLabel }); CheckEqual(200, Rows(popup)[0].Bounds.Width); } public void HorizontalScrollBar_IsIgnoredSinceThePopupNeverScrollsThatWay() { var popup = new DropdownPopup { DropdownWidth = 200 }; popup.ScrollViewMaterial = new ScrollViewMaterial { HorizontalScrollBar = ScrollViewTests.WithBars(20).HorizontalScrollBar, }; popup.Rebuild(new[] { DropdownTests.NarrowLabel }); CheckEqual(200, Rows(popup)[0].Bounds.Width); } public void ChangingItAfterRebuild_RelaysOutTheExistingRows() { var popup = new DropdownPopup { DropdownWidth = 200 }; popup.Rebuild(new[] { DropdownTests.NarrowLabel }); popup.ScrollViewMaterial = new ScrollViewMaterial { Background = DropdownTests.Bordered3 }; CheckEqual(194, Rows(popup)[0].Bounds.Width); } } public class DropdownPopupMaterialTests : TestFixture { public void Getting_GathersEachPart() { ButtonMaterial item = DropdownTests.Arrow(3, 3); ButtonMaterial selected = DropdownTests.Arrow(4, 4); ScrollViewMaterial scrollView = ScrollViewTests.WithBars(Thickness); var popup = new DropdownPopup { ItemButtonMaterial = item, SelectedItemButtonMaterial = selected, ScrollViewMaterial = scrollView, }; DropdownPopupMaterial gathered = popup.DropdownPopupMaterial; CheckEqual(item, gathered.ItemButton); CheckEqual(selected, gathered.SelectedItemButton); CheckEqual(scrollView, gathered.ScrollView); } public void Setting_SpreadsEachPart() { ButtonMaterial item = DropdownTests.Arrow(3, 3); ButtonMaterial selected = DropdownTests.Arrow(4, 4); ScrollViewMaterial scrollView = ScrollViewTests.WithBars(Thickness); var popup = new DropdownPopup(); popup.DropdownPopupMaterial = new DropdownPopupMaterial { ItemButton = item, SelectedItemButton = selected, ScrollView = scrollView, }; CheckEqual(item, popup.ItemButtonMaterial); CheckEqual(selected, popup.SelectedItemButtonMaterial); CheckEqual(scrollView, popup.ScrollViewMaterial); } public void Setting_RelaysOutTheExistingRows() { var popup = new DropdownPopup { DropdownWidth = 10 }; popup.Rebuild(new[] { DropdownTests.NarrowLabel }); popup.DropdownPopupMaterial = new DropdownPopupMaterial { ItemButton = new ButtonMaterial(DropdownTests.Bordered3), }; CheckEqual(new Vector(46, 22), Rows(popup)[0].Bounds.Size); } } public class OnItemClickedTests : TestFixture { public void ClickingARow_FiresWithThatRowsIndex() { var popup = new DropdownPopup { DropdownWidth = 200 }; popup.Rebuild(new[] { DropdownTests.NarrowLabel, DropdownTests.WideLabel }); int firedWith = -1; popup.OnItemClicked += index => firedWith = index; Rows(popup)[1].Click(default, MouseButtonFlags.Left); CheckEqual(1, firedWith); } public void AfterRebuild_NewRowsFireWithFreshIndices() { var popup = new DropdownPopup { DropdownWidth = 200 }; popup.Rebuild(new[] { DropdownTests.NarrowLabel, DropdownTests.WideLabel }); popup.Rebuild(new[] { DropdownTests.WideLabel }); int firedWith = -1; popup.OnItemClicked += index => firedWith = index; Rows(popup)[0].Click(default, MouseButtonFlags.Left); CheckEqual(0, firedWith); } } public class RebuildTests : TestFixture { public void Always_BuildsOneRowPerLabel() { var popup = new DropdownPopup { DropdownWidth = 200 }; popup.Rebuild(new[] { DropdownTests.NarrowLabel, DropdownTests.WideLabel }); CheckEqual(2, popup.CanvasChildren.Count); } public void Always_SizesEveryRowToTheSameWidth() { var popup = new DropdownPopup { DropdownWidth = 200 }; popup.Rebuild(new[] { DropdownTests.NarrowLabel, DropdownTests.WideLabel }); Control[] rows = Rows(popup); CheckEqual(rows[0].Bounds.Width, rows[1].Bounds.Width); } public void Always_StacksRowsTopToBottomWithNoGap() { var popup = new DropdownPopup { DropdownWidth = 200 }; popup.Rebuild(new[] { DropdownTests.NarrowLabel, DropdownTests.WideLabel }); Control[] rows = Rows(popup); CheckEqual(rows[0].Bounds.Bottom, rows[1].Bounds.Top); } public void Always_SetsContentSizeToTheStackedRows() { var popup = new DropdownPopup { DropdownWidth = 200 }; popup.Rebuild(new[] { DropdownTests.NarrowLabel, DropdownTests.WideLabel }); Control[] rows = Rows(popup); Vector expected = new Vector(rows[0].Bounds.Width, rows[0].Bounds.Height + rows[1].Bounds.Height); CheckEqual(expected, popup.ContentSize); } public void EmptyList_ClearsAnyExistingRowsAndContentSize() { var popup = new DropdownPopup { DropdownWidth = 200 }; popup.Rebuild(new[] { DropdownTests.NarrowLabel }); popup.Rebuild(Array.Empty()); CheckEqual(0, popup.CanvasChildren.Count); CheckEqual(Vector.Zero, popup.ContentSize); } public void CalledAgain_ReplacesThePreviousRows() { var popup = new DropdownPopup { DropdownWidth = 200 }; popup.Rebuild(new[] { DropdownTests.NarrowLabel, DropdownTests.WideLabel }); popup.Rebuild(new[] { DropdownTests.NarrowLabel }); CheckEqual(1, popup.CanvasChildren.Count); } public void Always_ClearsTheSelection() { DropdownPopup popup = TwoRowPopup(); popup.SelectedIndex = 1; popup.Rebuild(new[] { DropdownTests.NarrowLabel, DropdownTests.NarrowLabel }); CheckNull(popup.SelectedIndex); CheckEqual(Item, ChromeOfRow(popup, 1)); } public void Null_Throws() { var popup = new DropdownPopup(); CheckThrow(typeof(ArgumentNullException)); popup.Rebuild(null); } } public class EnabledTests : TestFixture { public void Disabling_DisablesEachExistingRow() { var popup = new DropdownPopup { DropdownWidth = 200 }; popup.Rebuild(new[] { DropdownTests.NarrowLabel, DropdownTests.WideLabel }); popup.Enabled = false; foreach (Control row in Rows(popup)) { CheckFalse(row.Enabled); } } public void Enabling_EnablesEachExistingRowAgain() { var popup = new DropdownPopup { DropdownWidth = 200 }; popup.Rebuild(new[] { DropdownTests.NarrowLabel, DropdownTests.WideLabel }); popup.Enabled = false; popup.Enabled = true; foreach (Control row in Rows(popup)) { CheckTrue(row.Enabled); } } public void Disabling_AlsoDisablesItsOwnScrollBars() { var popup = new DropdownPopup(); popup.Enabled = false; CheckFalse(popup.VerticalScrollBar.Enabled); CheckFalse(popup.HorizontalScrollBar.Enabled); } public void RowBuiltWhileDisabled_StartsDisabled() { var popup = new DropdownPopup { DropdownWidth = 200, Enabled = false }; popup.Rebuild(new[] { DropdownTests.NarrowLabel }); CheckFalse(Rows(popup)[0].Enabled); } } public class PlaceBesideTests : TestFixture { public static Rect Place(Rect anchor, Vector size) { return DropdownPopup.PlaceBeside(anchor, size, ScreenRect); } public void FitsBelow_SitsFlushBelowTheAnchor() { CheckEqual(Box(100, 230, 140, 100), Place(AnchorRect, new Vector(140, 100))); } public void FitsBelowAndAbove_PrefersBelow() { CheckEqual(Box(100, 330, 140, 100), Place(Box(100, 300, 150, 30), new Vector(140, 100))); } public void FillsTheRoomBelowExactly_StaysBelow() { CheckEqual(Box(100, 230, 140, 370), Place(AnchorRect, new Vector(140, 370))); } public void FitsOnlyAbove_SitsFlushAboveTheAnchor() { CheckEqual(Box(100, 400, 140, 100), Place(Box(100, 500, 150, 30), new Vector(140, 100))); } public void FillsTheRoomAboveExactly_GoesAbove() { CheckEqual(Box(100, 0, 140, 400), Place(Box(100, 400, 150, 30), new Vector(140, 400))); } public void FitsNeitherAndBelowHasMoreRoom_ShrinksToBelow() { CheckEqual(Box(100, 230, 140, 370), Place(AnchorRect, new Vector(140, 500))); } public void FitsNeitherAndAboveHasMoreRoom_ShrinksToAbove() { CheckEqual(Box(100, 0, 140, 400), Place(Box(100, 400, 150, 30), new Vector(140, 500))); } public void FitsNeitherWithEqualRoom_ShrinksToBelow() { CheckEqual(Box(100, 315, 140, 285), Place(Box(100, 285, 150, 30), new Vector(140, 500))); } public void OverhangingTheRightEdge_SlidesLeftToStayOnScreen() { CheckEqual(Box(660, 230, 140, 100), Place(Box(750, 200, 40, 30), new Vector(140, 100))); } public void OverhangingTheLeftEdge_SlidesRightToStayOnScreen() { CheckEqual(Box(0, 230, 140, 100), Place(Box(-30, 200, 100, 30), new Vector(140, 100))); } public void AnchorBelowTheScreen_StillLandsOnScreen() { CheckEqual(Box(100, 500, 140, 100), Place(Box(100, 700, 150, 30), new Vector(140, 100))); } public void AnchorSpanningTheWholeScreen_CollapsesToNoHeight() { CheckEqual(Box(100, 600, 140, 0), Place(Box(100, -50, 150, 700), new Vector(140, 100))); } } public class OpenTests : TestFixture { public void Always_IsOpenAtOnce() { DropdownPopup popup = NewPopup(); popup.Open(); CheckTrue(popup.IsOpen); } public void Always_WaitsForAnUpdateBeforeShowing() { DropdownPopup popup = NewPopup(); popup.Open(); CheckFalse(popup.Visible); } } public class CloseTests : TestFixture { public void WhileShowing_HidesAtOnce() { DropdownPopup popup = OpenAt(AnchorRect); popup.Close(); CheckFalse(popup.IsOpen); CheckFalse(popup.Visible); } public void BeforeItEverShowed_KeepsItHiddenThroughTheNextUpdate() { DropdownPopup popup = NewPopup(); popup.Open(); popup.Close(); Tick(popup, AnchorRect); CheckFalse(popup.Visible); } } public class MaxHeightTests : TestFixture { public void BelowTheContentsHeight_CapsThePopupAndScrolls() { DropdownPopup popup = NewPopup(); popup.MaxHeight = 60; popup.Open(); Tick(popup, AnchorRect); CheckEqual(Box(100, 230, 150, 60), popup.Bounds); CheckTrue(popup.VerticalScrollBar.Visible); CheckTrue(popup.ScrollsVertically); } public void AboveTheContentsHeight_HasNoEffect() { DropdownPopup popup = NewPopup(); popup.MaxHeight = 500; popup.Open(); Tick(popup, AnchorRect); CheckEqual(Box(100, 230, 150, 100), popup.Bounds); CheckFalse(popup.ScrollsVertically); } } public class UpdateTests : TestFixture { public void Closed_LeavesItHiddenAndUnplaced() { DropdownPopup popup = NewPopup(); Tick(popup, AnchorRect); CheckFalse(popup.Visible); CheckEqual(default(Rect), popup.Bounds); } public void Open_ShowsIt() { CheckTrue(OpenAt(AnchorRect).Visible); } public void Open_SitsBelowTheAnchorAtTheAnchorsWidth() { CheckEqual(Box(100, 230, 150, 100), OpenAt(AnchorRect).Bounds); } public void ContentWiderThanTheAnchor_KeepsTheWidthItsContentNeedsWithNoScrollbarReserved() { DropdownPopup popup = OpenAt(AnchorRect, new Vector(300, 100)); CheckEqual(Box(100, 230, 300, 100), popup.Bounds); CheckFalse(popup.ScrollsVertically); } public void ScreenTooShortEvenWithNoHeightCap_StillReservesScrollbarWidth() { DropdownPopup popup = OpenAt(AnchorRect, new Vector(200, 500)); CheckEqual(Box(100, 230, 220, 370), popup.Bounds); CheckTrue(popup.ScrollsVertically); } public void NotEnoughRoomBelow_SitsAboveTheAnchor() { CheckEqual(Box(100, 400, 150, 100), OpenAt(Box(100, 500, 150, 30)).Bounds); } public void NotEnoughRoomAnywhere_ShrinksToTheRoomierSideAndScrolls() { DropdownPopup popup = OpenAt(AnchorRect, new Vector(120, 1000)); CheckEqual(Box(100, 230, 150, 370), popup.Bounds); CheckTrue(popup.VerticalScrollBar.Visible); CheckTrue(popup.ScrollsVertically); } public void ContentThatFits_HidesItsScrollBar() { CheckFalse(OpenAt(AnchorRect).VerticalScrollBar.Visible); } public void NearTheRightEdge_SlidesLeftToStayOnScreen() { CheckEqual(Box(680, 230, 120, 100), OpenAt(Box(750, 200, 40, 30)).Bounds); } public void TheAnchorMoving_FollowsIt() { DropdownPopup popup = OpenAt(AnchorRect); Tick(popup, Box(300, 100, 150, 30)); CheckEqual(Box(300, 130, 150, 100), popup.Bounds); } public void TheContentGrowing_ResizesItOnTheNextUpdate() { DropdownPopup popup = OpenAt(AnchorRect); popup.ContentSize = new Vector(120, 150); Tick(popup, AnchorRect); CheckEqual(Box(100, 230, 150, 150), popup.Bounds); } public void TheScreenShrinking_MovesItToWhicheverSideStillFits() { DropdownPopup popup = OpenAt(AnchorRect); Tick(popup, AnchorRect, new Vector(800, 300)); CheckEqual(Box(100, 100, 150, 100), popup.Bounds); } public void Always_AnchorsToTheParentsBoundsRatherThanItsCanvasRect() { DropdownPopup popup = NewPopup(); popup.Open(); popup.Update(TimeSpan.Zero, new UpdateState { ScreenSize = ScreenRect.Size, ParentBounds = AnchorRect, ParentCanvasRect = Box(0, 0, 10, 10), }); CheckEqual(Box(100, 230, 150, 100), popup.Bounds); } } public class MouseDownTests : TestFixture { public void Outside_ClosesItAndClaimsTheEvent() { DropdownPopup popup = OpenAt(AnchorRect); CheckTrue(popup.MouseDown(At(OutsideThePopup), MouseButtonFlags.Left)); CheckFalse(popup.IsOpen); CheckFalse(popup.Visible); } public void Inside_ClaimsTheEventAndStaysOpen() { DropdownPopup popup = OpenAt(AnchorRect); CheckTrue(popup.MouseDown(At(InsideThePopup), MouseButtonFlags.Left)); CheckTrue(popup.IsOpen); } public void Disabled_LetsTheEventThroughAndStaysOpen() { DropdownPopup popup = OpenAt(AnchorRect); popup.Enabled = false; CheckFalse(popup.MouseDown(At(OutsideThePopup), MouseButtonFlags.Left)); CheckTrue(popup.IsOpen); } public void Always_StillFiresTheHandler() { DropdownPopup popup = OpenAt(AnchorRect); int fired = 0; popup.OnMouseDown += (in MouseState _, MouseButtonFlags __) => ++fired; popup.MouseDown(At(InsideThePopup), MouseButtonFlags.Left); CheckEqual(1, fired); } } public class MouseUpTests : TestFixture { public void Anywhere_ClaimsTheEvent() { DropdownPopup popup = OpenAt(AnchorRect); CheckTrue(popup.MouseUp(At(InsideThePopup), MouseButtonFlags.Left)); CheckTrue(popup.MouseUp(At(OutsideThePopup), MouseButtonFlags.Left)); } public void Outside_LeavesItOpen() { DropdownPopup popup = OpenAt(AnchorRect); popup.MouseUp(At(OutsideThePopup), MouseButtonFlags.Left); CheckTrue(popup.IsOpen); } public void Disabled_LetsTheEventThrough() { DropdownPopup popup = OpenAt(AnchorRect); popup.Enabled = false; CheckFalse(popup.MouseUp(At(InsideThePopup), MouseButtonFlags.Left)); } public void Always_StillFiresTheHandler() { DropdownPopup popup = OpenAt(AnchorRect); int fired = 0; popup.OnMouseUp += (in MouseState _, MouseButtonFlags __) => ++fired; popup.MouseUp(At(InsideThePopup), MouseButtonFlags.Left); CheckEqual(1, fired); } } public class MouseMoveStartTests : TestFixture { public void Anywhere_ClaimsTheEvent() { DropdownPopup popup = OpenAt(AnchorRect); CheckTrue(popup.MouseMoveStart(At(InsideThePopup))); CheckTrue(popup.MouseMoveStart(At(OutsideThePopup))); } public void Disabled_LetsTheEventThrough() { DropdownPopup popup = OpenAt(AnchorRect); popup.Enabled = false; CheckFalse(popup.MouseMoveStart(At(InsideThePopup))); } public void Always_StillFiresTheHandler() { DropdownPopup popup = OpenAt(AnchorRect); int fired = 0; popup.OnMouseMoveStart += (in MouseState _) => ++fired; popup.MouseMoveStart(At(InsideThePopup)); CheckEqual(1, fired); } } public class MouseMoveTests : TestFixture { public void Anywhere_ClaimsTheEvent() { DropdownPopup popup = OpenAt(AnchorRect); CheckTrue(popup.MouseMove(At(InsideThePopup))); CheckTrue(popup.MouseMove(At(OutsideThePopup))); } public void Disabled_LetsTheEventThrough() { DropdownPopup popup = OpenAt(AnchorRect); popup.Enabled = false; CheckFalse(popup.MouseMove(At(InsideThePopup))); } public void Always_StillFiresTheHandler() { DropdownPopup popup = OpenAt(AnchorRect); int fired = 0; popup.OnMouseMove += (in MouseState _) => ++fired; popup.MouseMove(At(InsideThePopup)); CheckEqual(1, fired); } } public class MouseMoveEndTests : TestFixture { public void Anywhere_ClaimsTheEvent() { DropdownPopup popup = OpenAt(AnchorRect); CheckTrue(popup.MouseMoveEnd(At(InsideThePopup))); CheckTrue(popup.MouseMoveEnd(At(OutsideThePopup))); } public void Disabled_LetsTheEventThrough() { DropdownPopup popup = OpenAt(AnchorRect); popup.Enabled = false; CheckFalse(popup.MouseMoveEnd(At(InsideThePopup))); } public void Always_StillFiresTheHandler() { DropdownPopup popup = OpenAt(AnchorRect); int fired = 0; popup.OnMouseMoveEnd += (in MouseState _) => ++fired; popup.MouseMoveEnd(At(InsideThePopup)); CheckEqual(1, fired); } } public class ClickTests : TestFixture { public void Anywhere_ClaimsTheEvent() { DropdownPopup popup = OpenAt(AnchorRect); CheckTrue(popup.Click(At(InsideThePopup), MouseButtonFlags.Left)); CheckTrue(popup.Click(At(OutsideThePopup), MouseButtonFlags.Left)); } public void Disabled_LetsTheEventThrough() { DropdownPopup popup = OpenAt(AnchorRect); popup.Enabled = false; CheckFalse(popup.Click(At(InsideThePopup), MouseButtonFlags.Left)); } public void Always_StillFiresTheHandler() { DropdownPopup popup = OpenAt(AnchorRect); int fired = 0; popup.OnClick += (in MouseState _, MouseButtonFlags __) => ++fired; popup.Click(At(InsideThePopup), MouseButtonFlags.Left); CheckEqual(1, fired); } } public class MouseWheelTests : TestFixture { public void Inside_ScrollsTheListAndClaimsTheEvent() { DropdownPopup popup = OpenAt(AnchorRect, new Vector(120, 1000)); CheckTrue(popup.MouseWheel(At(InsideThePopup), -1)); CheckTrue(popup.ScrollOffset.Y > 0); } public void Inside_ClaimsTheEventWhenTheContentFits() { DropdownPopup popup = OpenAt(AnchorRect); CheckTrue(popup.MouseWheel(At(InsideThePopup), -1)); } public void Outside_ClaimsTheEventWithoutScrolling() { DropdownPopup popup = OpenAt(AnchorRect, new Vector(120, 1000)); CheckTrue(popup.MouseWheel(At(OutsideThePopup), -1)); CheckEqual(Vector.Zero, popup.ScrollOffset); } public void Disabled_LetsTheEventThrough() { DropdownPopup popup = OpenAt(AnchorRect); popup.Enabled = false; CheckFalse(popup.MouseWheel(At(InsideThePopup), -1)); } } public class MouseHandlerCoverageTests : TestFixture { public void OverridesEveryHandlerControlDeclares() { CheckEqual( SpotlightTests.MouseHandlerCoverageTests.OnControl(), SpotlightTests.MouseHandlerCoverageTests.MouseHandlerNamesOn( typeof(DropdownPopup), BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)); } } } }