using UnitTestSharp; using Azimuth; using Annulus; using System; namespace Glass.UnitTests { public class ScreenTests : TestFixture { public class CtorTests : TestFixture { public void RoutesInputIntoTheScreensOwnControlTree() { var screen = new Screen(); CheckEqual(screen.Controls, screen.MouseManager.Controls); } public void StartsWithNoControls() { CheckEqual(0, new Screen().Controls.Count); } public void StartsWithZeroBounds() { CheckEqual(Rect.Zero, new Screen().Bounds); } } public class UpdateTests : TestFixture { private Screen screen; private TimeSpan? notifiedElapsed; private int notificationCount; public override void TestSetup() { notifiedElapsed = null; notificationCount = 0; screen = new Screen(); screen.OnUpdate = (TimeSpan elapsed) => { notifiedElapsed = elapsed; ++notificationCount; }; } public void Always_NotifiesWithTheElapsedTime() { screen.Update(TimeSpan.FromMilliseconds(16)); CheckEqual(TimeSpan.FromMilliseconds(16), notifiedElapsed); } public void Always_NotifiesOncePerCall() { screen.Update(TimeSpan.FromMilliseconds(16)); screen.Update(TimeSpan.FromMilliseconds(16)); CheckEqual(2, notificationCount); } public void ZeroElapsed_StillNotifies() { screen.Update(TimeSpan.Zero); CheckEqual(TimeSpan.Zero, notifiedElapsed); } public void WithNoSubscriber_DoesNotThrow() { screen.OnUpdate = null; screen.Update(TimeSpan.FromMilliseconds(16)); CheckEqual(0, notificationCount); } public void Always_AgesEveryControlInTheTree() { var parent = screen.Controls.NewChild(); var child = parent.ChildControls.NewChild(); screen.Update(TimeSpan.FromMilliseconds(16)); CheckEqual(TimeSpan.FromMilliseconds(16), parent.Age); CheckEqual(TimeSpan.FromMilliseconds(16), child.Age); } public void Always_TellsEveryControlTheScreenRect() { screen.Bounds = Rect.FromPositionAndSize(Vector.Zero, new Vector(800, 600)); var recorder = new ControlTests.StateRecordingControl(); screen.Controls.Add(recorder); screen.Update(TimeSpan.FromMilliseconds(16)); CheckEqual(screen.Bounds, recorder.LastState.ScreenRect); } public void Always_StartsTheParentClientRectAtTheWholeScreen() { screen.Bounds = Rect.FromPositionAndSize(Vector.Zero, new Vector(800, 600)); var recorder = new ControlTests.StateRecordingControl(); screen.Controls.Add(recorder); screen.Update(TimeSpan.FromMilliseconds(16)); CheckEqual(screen.Bounds, recorder.LastState.ParentClientRect); } public void Always_StartsTheParentBoundsAtTheWholeScreen() { screen.Bounds = Rect.FromPositionAndSize(Vector.Zero, new Vector(800, 600)); var recorder = new ControlTests.StateRecordingControl(); screen.Controls.Add(recorder); screen.Update(TimeSpan.FromMilliseconds(16)); CheckEqual(screen.Bounds, recorder.LastState.ParentBounds); } public void WithNoMouseState_TellsEveryControlItIsUnknown() { var recorder = new ControlTests.StateRecordingControl(); screen.Controls.Add(recorder); screen.Update(TimeSpan.FromMilliseconds(16)); CheckNull(recorder.LastState.MouseState); } public void WithAMouseState_HandsItToEveryControl() { var recorder = new ControlTests.StateRecordingControl(); screen.Controls.Add(recorder); var mouse = new MouseState { Position = new Vector(37, 41), Buttons = MouseButtonFlags.Left, }; screen.Update(TimeSpan.FromMilliseconds(16), mouse); CheckEqual(new Vector(37, 41), recorder.LastState.MouseState.Value.Position); CheckEqual(MouseButtonFlags.Left, recorder.LastState.MouseState.Value.Buttons); } public void ControlAddedLater_StartsFromZeroRatherThanTheScreensClock() { screen.Update(TimeSpan.FromMilliseconds(16)); var latecomer = screen.Controls.NewChild(); screen.Update(TimeSpan.FromMilliseconds(4)); CheckEqual(TimeSpan.FromMilliseconds(4), latecomer.Age); } public void ControlOutOfTheTree_HasItsAgePausedRatherThanReset() { var control = screen.Controls.NewChild(); screen.Update(TimeSpan.FromMilliseconds(16)); screen.Controls.Remove(control); screen.Update(TimeSpan.FromMilliseconds(100)); screen.Controls.Add(control); screen.Update(TimeSpan.FromMilliseconds(4)); CheckEqual(TimeSpan.FromMilliseconds(20), control.Age); } public void NotifiesOnlyOnceEveryAgeHasAdvanced() { var control = screen.Controls.NewChild(); TimeSpan? ageWhenNotified = null; screen.OnUpdate = (TimeSpan _) => ageWhenNotified = control.Age; screen.Update(TimeSpan.FromMilliseconds(16)); CheckEqual(TimeSpan.FromMilliseconds(16), ageWhenNotified); } } public class BoundsTests : TestFixture { private Screen screen; private Rect? notifiedBounds; private readonly Rect bounds = Rect.FromPositionAndSize(new Vector(3, 4), new Vector(800, 600)); public override void TestSetup() { notifiedBounds = null; screen = new Screen(); screen.OnBoundsChanged = (Rect newBounds) => notifiedBounds = newBounds; } public void Set_IsReadBack() { screen.Bounds = bounds; CheckEqual(bounds, screen.Bounds); } public void Set_NotifiesWithTheNewBounds() { screen.Bounds = bounds; CheckEqual(bounds, notifiedBounds); } public void Set_NotifiesOnlyOnceTheNewBoundsIsReadable() { Rect? boundsWhenNotified = null; screen.OnBoundsChanged = (Rect _) => boundsWhenNotified = screen.Bounds; screen.Bounds = bounds; CheckEqual(bounds, boundsWhenNotified); } public void SetToTheSameBounds_NotifiesStill() { screen.Bounds = bounds; Rect? boundsWhenNotified = null; screen.OnBoundsChanged = (Rect _) => boundsWhenNotified = screen.Bounds; screen.Bounds = bounds; CheckEqual(bounds, boundsWhenNotified); } public void SetToTheSamePositionButADifferentSize_Notifies() { screen.Bounds = bounds; notifiedBounds = null; screen.Bounds = Rect.FromPositionAndSize(bounds.Position, new Vector(1024, 600)); CheckNotNull(notifiedBounds); } public void SetToTheSameSizeButADifferentPosition_Notifies() { screen.Bounds = bounds; notifiedBounds = null; screen.Bounds = Rect.FromPositionAndSize(new Vector(0, 4), bounds.Size); CheckNotNull(notifiedBounds); } public void SetWithNoSubscriber_DoesNotThrow() { screen.OnBoundsChanged = null; screen.Bounds = bounds; CheckEqual(bounds, screen.Bounds); } } } }