using Amphora; using Annulus; using Azimuth; using System; using System.Reflection; using UnitTestSharp; namespace Glass.UnitTests { public class PopupTests : TestFixture { public static readonly Rect ScreenRect = Rect.FromPositionAndSize(Vector.Zero, new Vector(800, 600)); public static readonly Vector PopupSize = new Vector(100, 60); public static readonly Rect ParentRect = Box(100, 200, 150, 30); public static readonly Vector InsideThePopup = new Vector(150, 200); 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 Popup NewPopup() { return new Popup { Bounds = Rect.FromPositionAndSize(Vector.Zero, PopupSize) }; } public static void Tick(Popup popup, Rect parent, Vector? screenSize = null) { popup.Update(Duration.Zero, new UpdateState { ScreenSize = screenSize ?? ScreenRect.Size, ParentBounds = parent, }); } public static Popup OpenOver(Rect parent) { Popup popup = NewPopup(); popup.Open(); Tick(popup, parent); return popup; } public class CtorTests : TestFixture { public void Always_EscapesTheParentsSpaceZOrderAndClip() { var popup = new Popup(); CheckTrue(popup.Hoisted); CheckTrue(popup.AlwaysOnTop); CheckFalse(popup.ClipToAncestors); } public void Always_TakesFirstRefusalOnInput() { CheckTrue(new Popup().Modal); } public void Always_StartsClosedAndHidden() { var popup = new Popup(); CheckFalse(popup.IsOpen); CheckFalse(popup.Visible); } public void Always_StartsDismissingOnAnOutsidePress() { CheckTrue(new Popup().DismissOnOutsidePress); } } public class MaterialTests : TestFixture { public void Setting_IsReadBack() { var popup = new Popup(); Material material = DropdownTests.Bordered3; popup.Material = material; CheckEqual(material, popup.Material); } } public class PlaceCenteredTests : TestFixture { public static Rect Place(Rect parent, Vector size) { return Popup.PlaceCentered(parent, size, ScreenRect); } public void ParentWellInsideTheScreen_CentersOnTheParent() { CheckEqual(Box(125, 185, 100, 60), Place(ParentRect, PopupSize)); } public void LargerThanTheParent_StillCentersOnIt() { CheckEqual(Box(260, 280, 100, 60), Place(Box(300, 300, 20, 20), PopupSize)); } public void OverhangingTheLeftEdge_SlidesRightToStayOnScreen() { CheckEqual(Box(0, 180, 100, 60), Place(Box(0, 200, 20, 20), PopupSize)); } public void OverhangingTheRightEdge_SlidesLeftToStayOnScreen() { CheckEqual(Box(700, 180, 100, 60), Place(Box(780, 200, 20, 20), PopupSize)); } public void OverhangingTheTopEdge_SlidesDownToStayOnScreen() { CheckEqual(Box(260, 0, 100, 60), Place(Box(300, 0, 20, 20), PopupSize)); } public void OverhangingTheBottomEdge_SlidesUpToStayOnScreen() { CheckEqual(Box(260, 540, 100, 60), Place(Box(300, 590, 20, 20), PopupSize)); } public void LargerThanTheScreen_AlignsTopLeftAndOverhangs() { CheckEqual(Box(0, 0, 1000, 700), Place(ParentRect, new Vector(1000, 700))); } } public class OpenTests : TestFixture { public void Always_IsOpenAtOnce() { Popup popup = NewPopup(); popup.Open(); CheckTrue(popup.IsOpen); } public void Always_WaitsForAnUpdateBeforeShowing() { Popup popup = NewPopup(); popup.Open(); CheckFalse(popup.Visible); } } public class CloseTests : TestFixture { public void WhileShowing_HidesAtOnce() { Popup popup = OpenOver(ParentRect); popup.Close(); CheckFalse(popup.IsOpen); CheckFalse(popup.Visible); } public void BeforeItEverShowed_KeepsItHiddenThroughTheNextUpdate() { Popup popup = NewPopup(); popup.Open(); popup.Close(); Tick(popup, ParentRect); CheckFalse(popup.Visible); } public void WhileOpen_RaisesOnClosedWithThePopup() { Popup popup = OpenOver(ParentRect); Popup closed = null; popup.OnClosed += whichPopup => closed = whichPopup; popup.Close(); CheckEqual(popup, closed); } public void WhenNotOpen_RaisesNothing() { Popup popup = NewPopup(); int raised = 0; popup.OnClosed += _ => ++raised; popup.Close(); CheckEqual(0, raised); } public void CalledTwice_RaisesOnceOnly() { Popup popup = OpenOver(ParentRect); int raised = 0; popup.OnClosed += _ => ++raised; popup.Close(); popup.Close(); CheckEqual(1, raised); } } public class UpdateTests : TestFixture { public void Closed_LeavesItHiddenAndUnplaced() { Popup popup = NewPopup(); Tick(popup, ParentRect); CheckFalse(popup.Visible); CheckEqual(Box(0, 0, 100, 60), popup.Bounds); } public void Open_ShowsIt() { CheckTrue(OpenOver(ParentRect).Visible); } public void Open_CentersOverTheParentKeepingItsSize() { CheckEqual(Box(125, 185, 100, 60), OpenOver(ParentRect).Bounds); } public void TheParentMoving_FollowsIt() { Popup popup = OpenOver(ParentRect); Tick(popup, Box(300, 100, 150, 30)); CheckEqual(Box(325, 85, 100, 60), popup.Bounds); } public void TheParentStayingPut_LeavesItWhereItIs() { Popup popup = OpenOver(ParentRect); Tick(popup, ParentRect); CheckEqual(Box(125, 185, 100, 60), popup.Bounds); } public void TheScreenShrinking_SlidesItBackOnScreen() { Popup popup = OpenOver(Box(300, 500, 20, 20)); Tick(popup, Box(300, 500, 20, 20), new Vector(800, 300)); CheckEqual(Box(260, 240, 100, 60), popup.Bounds); } public void Always_CentersOnTheParentsBoundsRatherThanItsCanvasRect() { Popup popup = NewPopup(); popup.Open(); popup.Update(Duration.Zero, new UpdateState { ScreenSize = ScreenRect.Size, ParentBounds = ParentRect, ParentCanvasRect = Box(0, 0, 10, 10), }); CheckEqual(Box(125, 185, 100, 60), popup.Bounds); } } public class MouseDownTests : TestFixture { public void Outside_ClosesItAndClaimsTheEvent() { Popup popup = OpenOver(ParentRect); CheckTrue(popup.MouseDown(At(OutsideThePopup), MouseButtonFlags.Left)); CheckFalse(popup.IsOpen); CheckFalse(popup.Visible); } public void Inside_ClaimsTheEventAndStaysOpen() { Popup popup = OpenOver(ParentRect); CheckTrue(popup.MouseDown(At(InsideThePopup), MouseButtonFlags.Left)); CheckTrue(popup.IsOpen); } public void OutsideWithDismissingOff_ClaimsTheEventAndStaysOpen() { Popup popup = OpenOver(ParentRect); popup.DismissOnOutsidePress = false; CheckTrue(popup.MouseDown(At(OutsideThePopup), MouseButtonFlags.Left)); CheckTrue(popup.IsOpen); } public void Disabled_LetsTheEventThroughAndStaysOpen() { Popup popup = OpenOver(ParentRect); popup.Enabled = false; CheckFalse(popup.MouseDown(At(OutsideThePopup), MouseButtonFlags.Left)); CheckTrue(popup.IsOpen); } public void Closed_LetsTheEventThrough() { CheckFalse(NewPopup().MouseDown(At(InsideThePopup), MouseButtonFlags.Left)); } public void Always_StillFiresTheHandler() { Popup popup = OpenOver(ParentRect); 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() { Popup popup = OpenOver(ParentRect); CheckTrue(popup.MouseUp(At(InsideThePopup), MouseButtonFlags.Left)); CheckTrue(popup.MouseUp(At(OutsideThePopup), MouseButtonFlags.Left)); } public void Outside_LeavesItOpen() { Popup popup = OpenOver(ParentRect); popup.MouseUp(At(OutsideThePopup), MouseButtonFlags.Left); CheckTrue(popup.IsOpen); } public void Disabled_LetsTheEventThrough() { Popup popup = OpenOver(ParentRect); popup.Enabled = false; CheckFalse(popup.MouseUp(At(InsideThePopup), MouseButtonFlags.Left)); } public void Closed_LetsTheEventThrough() { CheckFalse(NewPopup().MouseUp(At(InsideThePopup), MouseButtonFlags.Left)); } public void Always_StillFiresTheHandler() { Popup popup = OpenOver(ParentRect); 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() { Popup popup = OpenOver(ParentRect); CheckTrue(popup.MouseMoveStart(At(InsideThePopup))); CheckTrue(popup.MouseMoveStart(At(OutsideThePopup))); } public void Disabled_LetsTheEventThrough() { Popup popup = OpenOver(ParentRect); popup.Enabled = false; CheckFalse(popup.MouseMoveStart(At(InsideThePopup))); } public void Closed_LetsTheEventThrough() { CheckFalse(NewPopup().MouseMoveStart(At(InsideThePopup))); } public void Always_StillFiresTheHandler() { Popup popup = OpenOver(ParentRect); int fired = 0; popup.OnMouseMoveStart += (in MouseState _) => ++fired; popup.MouseMoveStart(At(InsideThePopup)); CheckEqual(1, fired); } } public class MouseMoveTests : TestFixture { public void Anywhere_ClaimsTheEvent() { Popup popup = OpenOver(ParentRect); CheckTrue(popup.MouseMove(At(InsideThePopup))); CheckTrue(popup.MouseMove(At(OutsideThePopup))); } public void Disabled_LetsTheEventThrough() { Popup popup = OpenOver(ParentRect); popup.Enabled = false; CheckFalse(popup.MouseMove(At(InsideThePopup))); } public void Closed_LetsTheEventThrough() { CheckFalse(NewPopup().MouseMove(At(InsideThePopup))); } public void Always_StillFiresTheHandler() { Popup popup = OpenOver(ParentRect); int fired = 0; popup.OnMouseMove += (in MouseState _) => ++fired; popup.MouseMove(At(InsideThePopup)); CheckEqual(1, fired); } } public class MouseMoveEndTests : TestFixture { public void Anywhere_ClaimsTheEvent() { Popup popup = OpenOver(ParentRect); CheckTrue(popup.MouseMoveEnd(At(InsideThePopup))); CheckTrue(popup.MouseMoveEnd(At(OutsideThePopup))); } public void Disabled_LetsTheEventThrough() { Popup popup = OpenOver(ParentRect); popup.Enabled = false; CheckFalse(popup.MouseMoveEnd(At(InsideThePopup))); } public void Closed_LetsTheEventThrough() { CheckFalse(NewPopup().MouseMoveEnd(At(InsideThePopup))); } public void Always_StillFiresTheHandler() { Popup popup = OpenOver(ParentRect); int fired = 0; popup.OnMouseMoveEnd += (in MouseState _) => ++fired; popup.MouseMoveEnd(At(InsideThePopup)); CheckEqual(1, fired); } } public class ClickTests : TestFixture { public void Anywhere_ClaimsTheEvent() { Popup popup = OpenOver(ParentRect); CheckTrue(popup.Click(At(InsideThePopup), MouseButtonFlags.Left, clickCount: 1)); CheckTrue(popup.Click(At(OutsideThePopup), MouseButtonFlags.Left, clickCount: 1)); } public void Disabled_LetsTheEventThrough() { Popup popup = OpenOver(ParentRect); popup.Enabled = false; CheckFalse(popup.Click(At(InsideThePopup), MouseButtonFlags.Left, clickCount: 1)); } public void Closed_LetsTheEventThrough() { CheckFalse(NewPopup().Click(At(InsideThePopup), MouseButtonFlags.Left, clickCount: 1)); } public void Always_StillFiresTheHandler() { Popup popup = OpenOver(ParentRect); int fired = 0; popup.OnClick += (in MouseState _, MouseButtonFlags __, int ___) => ++fired; popup.Click(At(InsideThePopup), MouseButtonFlags.Left, clickCount: 1); CheckEqual(1, fired); } } public class MouseWheelTests : TestFixture { public void Anywhere_ClaimsTheEvent() { Popup popup = OpenOver(ParentRect); CheckTrue(popup.MouseWheel(At(InsideThePopup), -1)); CheckTrue(popup.MouseWheel(At(OutsideThePopup), -1)); } public void Disabled_LetsTheEventThrough() { Popup popup = OpenOver(ParentRect); popup.Enabled = false; CheckFalse(popup.MouseWheel(At(InsideThePopup), -1)); } public void Closed_LetsTheEventThrough() { CheckFalse(NewPopup().MouseWheel(At(InsideThePopup), -1)); } } public class MouseHandlerCoverageTests : TestFixture { public void OverridesEveryHandlerControlDeclares() { CheckEqual( SpotlightTests.MouseHandlerCoverageTests.OnControl(), SpotlightTests.MouseHandlerCoverageTests.MouseHandlerNamesOn( typeof(Popup), BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)); } } } }