using Annulus; using Azimuth; using Glass; using System; using UnitTestSharp; namespace Glass.UnitTests { public class TooltipTests : TestFixture { public static readonly Rect Screen = Rect.FromPositionAndSize(Vector.Zero, new Vector(800, 600)); public static readonly Vector ContentSize = new Vector(60, 20); public static Tooltip NewTooltip() { var content = new Panel { Bounds = Rect.FromPositionAndSize(Vector.Zero, ContentSize) }; return new Tooltip(Material.Invisible, content); } /// /// Ticks the tooltip the way its owner's subtree walk would, with the owner sitting at /// on screen. /// public static void Tick(Tooltip tooltip, TimeSpan elapsed, Rect? ownerRect = null) { tooltip.Update(elapsed, new UpdateState { ScreenRect = Screen, ParentClientRect = ownerRect ?? Rect.FromPositionAndSize(new Vector(100, 100), new Vector(40, 30)), }); } /// /// Ticks with a pointer position, the way a host that can report one does. /// public static void TickWithPointer(Tooltip tooltip, TimeSpan elapsed, Vector pointer, Rect ownerRect) { tooltip.Update(elapsed, new UpdateState { ScreenRect = Screen, ParentClientRect = ownerRect, MouseState = new MouseState { Position = pointer }, }); } public class CtorTests : TestFixture { public void Always_StartsHidden() { CheckFalse(NewTooltip().Visible); } public void Always_EscapesTheOwnersClipAndPaintsLast() { Tooltip tooltip = NewTooltip(); CheckTrue(tooltip.AlwaysOnTop); CheckFalse(tooltip.ClipToAncestors); } public void Always_StaysInParentSpaceSoItRidesWithItsOwner() { CheckFalse(NewTooltip().Hoisted); } public void Always_SizesItselfToItsContent() { CheckEqual(ContentSize, NewTooltip().Bounds.Size); } } public class UpdateTests : TestFixture { public void BeforeTheDwellElapses_StaysHidden() { Tooltip tooltip = NewTooltip(); tooltip.HoverStarted(); Tick(tooltip, tooltip.DwellDelay - TimeSpan.FromMilliseconds(1)); CheckFalse(tooltip.Visible); } public void OnceTheDwellElapses_Shows() { Tooltip tooltip = NewTooltip(); tooltip.HoverStarted(); Tick(tooltip, tooltip.DwellDelay); CheckTrue(tooltip.Visible); } public void WithoutAHover_NeverShows() { Tooltip tooltip = NewTooltip(); Tick(tooltip, TimeSpan.FromSeconds(10)); CheckFalse(tooltip.Visible); } public void DwellAccumulatesAcrossTicks() { Tooltip tooltip = NewTooltip(); tooltip.DwellDelay = TimeSpan.FromMilliseconds(600); tooltip.HoverStarted(); Tick(tooltip, TimeSpan.FromMilliseconds(300)); CheckFalse(tooltip.Visible); Tick(tooltip, TimeSpan.FromMilliseconds(300)); CheckTrue(tooltip.Visible); } public void AZeroDwell_ShowsOnTheFirstTick() { Tooltip tooltip = NewTooltip(); tooltip.DwellDelay = TimeSpan.Zero; tooltip.HoverStarted(); Tick(tooltip, TimeSpan.Zero); CheckTrue(tooltip.Visible); } public void PastTheTimeout_HidesAgain() { Tooltip tooltip = NewTooltip(); tooltip.Timeout = TimeSpan.FromSeconds(2); tooltip.HoverStarted(); Tick(tooltip, tooltip.DwellDelay); CheckTrue(tooltip.Visible); Tick(tooltip, TimeSpan.FromSeconds(2)); CheckFalse(tooltip.Visible); } public void PastTheTimeout_StaysHiddenWhileStillHovered() { Tooltip tooltip = NewTooltip(); tooltip.Timeout = TimeSpan.FromSeconds(2); tooltip.HoverStarted(); Tick(tooltip, tooltip.DwellDelay + TimeSpan.FromSeconds(2)); Tick(tooltip, TimeSpan.FromSeconds(1)); CheckFalse(tooltip.Visible); } public void WithNoTimeout_StaysUpIndefinitely() { Tooltip tooltip = NewTooltip(); tooltip.HoverStarted(); Tick(tooltip, tooltip.DwellDelay); Tick(tooltip, TimeSpan.FromHours(1)); CheckTrue(tooltip.Visible); } public void WithAPointer_SpawnsBesideIt() { Tooltip tooltip = NewTooltip(); var owner = Rect.FromPositionAndSize(new Vector(100, 100), new Vector(40, 30)); tooltip.HoverStarted(); TickWithPointer(tooltip, tooltip.DwellDelay, new Vector(210, 220), owner); Vector positionOnScreen = owner.TopLeft + tooltip.Bounds.Position; CheckEqual(new Vector(210, 220) + tooltip.Offset, positionOnScreen); } public void OnceShown_HoldsStillWhileThePointerMoves() { Tooltip tooltip = NewTooltip(); var owner = Rect.FromPositionAndSize(new Vector(100, 100), new Vector(40, 30)); tooltip.HoverStarted(); TickWithPointer(tooltip, tooltip.DwellDelay, new Vector(210, 220), owner); Vector whereItSpawned = tooltip.Bounds.Position; TickWithPointer(tooltip, TimeSpan.FromMilliseconds(16), new Vector(260, 240), owner); CheckEqual(whereItSpawned, tooltip.Bounds.Position); } public void ANewHoverAfterTheLast_SpawnsAtTheNewPointerPosition() { Tooltip tooltip = NewTooltip(); var owner = Rect.FromPositionAndSize(new Vector(100, 100), new Vector(40, 30)); tooltip.HoverStarted(); TickWithPointer(tooltip, tooltip.DwellDelay, new Vector(210, 220), owner); tooltip.HoverEnded(); tooltip.HoverStarted(); TickWithPointer(tooltip, tooltip.DwellDelay, new Vector(300, 400), owner); Vector positionOnScreen = owner.TopLeft + tooltip.Bounds.Position; CheckEqual(new Vector(300, 400) + tooltip.Offset, positionOnScreen); } public void WithoutAPointer_FallsBackToTheOwnersCenter() { Tooltip tooltip = NewTooltip(); var owner = Rect.FromPositionAndSize(new Vector(100, 100), new Vector(40, 30)); tooltip.HoverStarted(); Tick(tooltip, tooltip.DwellDelay, owner); CheckEqual(new Vector(20, 15) + tooltip.Offset, tooltip.Bounds.Position); } public void NearTheBottomEdge_IsPushedBackOnScreen() { Tooltip tooltip = NewTooltip(); var owner = Rect.FromPositionAndSize(new Vector(100, 570), new Vector(40, 30)); tooltip.HoverStarted(); Tick(tooltip, tooltip.DwellDelay, owner); Scalar bottomOnScreen = owner.TopLeft.Y + tooltip.Bounds.Position.Y + tooltip.Bounds.Height; CheckEqual(Screen.Bottom, bottomOnScreen); } public void NearTheRightEdge_IsPushedBackOnScreen() { Tooltip tooltip = NewTooltip(); var owner = Rect.FromPositionAndSize(new Vector(770, 100), new Vector(40, 30)); tooltip.HoverStarted(); Tick(tooltip, tooltip.DwellDelay, owner); Scalar rightOnScreen = owner.TopLeft.X + tooltip.Bounds.Position.X + tooltip.Bounds.Width; CheckEqual(Screen.Right, rightOnScreen); } } public class HoverEndedTests : TestFixture { public void WhileShown_HidesIt() { Tooltip tooltip = NewTooltip(); tooltip.HoverStarted(); Tick(tooltip, tooltip.DwellDelay); tooltip.HoverEnded(); CheckFalse(tooltip.Visible); } public void Always_RestartsTheDwellForTheNextHover() { Tooltip tooltip = NewTooltip(); tooltip.HoverStarted(); Tick(tooltip, tooltip.DwellDelay - TimeSpan.FromMilliseconds(1)); tooltip.HoverEnded(); tooltip.HoverStarted(); Tick(tooltip, TimeSpan.FromMilliseconds(1)); CheckFalse(tooltip.Visible); } public void AfterATimeout_ANewHoverShowsItAgain() { Tooltip tooltip = NewTooltip(); tooltip.Timeout = TimeSpan.FromSeconds(2); tooltip.HoverStarted(); Tick(tooltip, tooltip.DwellDelay + TimeSpan.FromSeconds(2)); tooltip.HoverEnded(); tooltip.HoverStarted(); Tick(tooltip, tooltip.DwellDelay); CheckTrue(tooltip.Visible); } } public class HoverStartedTests : TestFixture { public void Always_LeavesItHiddenUntilTheDwellElapses() { Tooltip tooltip = NewTooltip(); tooltip.HoverStarted(); CheckFalse(tooltip.Visible); } } } }