TopLevelTests.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  1. // -----------------------------------------------------------------------
  2. // <copyright file="TopLevelTests.cs" company="Steven Kirk">
  3. // Copyright 2015 MIT Licence. See licence.md for more information.
  4. // </copyright>
  5. // -----------------------------------------------------------------------
  6. namespace Perspex.Controls.UnitTests
  7. {
  8. using System.Reactive;
  9. using System.Reactive.Subjects;
  10. using Moq;
  11. using Perspex.Controls.Presenters;
  12. using Perspex.Controls.Templates;
  13. using Perspex.Input;
  14. using Perspex.Input.Raw;
  15. using Perspex.Layout;
  16. using Perspex.Platform;
  17. using Perspex.Rendering;
  18. using Perspex.Styling;
  19. using Ploeh.AutoFixture;
  20. using Ploeh.AutoFixture.AutoMoq;
  21. using Splat;
  22. using Xunit;
  23. public class TopLevelTests
  24. {
  25. [Fact]
  26. public void ClientSize_Should_Be_Set_On_Construction()
  27. {
  28. using (Locator.CurrentMutable.WithResolver())
  29. {
  30. this.RegisterServices();
  31. var impl = new Mock<ITopLevelImpl>();
  32. impl.Setup(x => x.ClientSize).Returns(new Size(123, 456));
  33. var target = new TestTopLevel(impl.Object);
  34. Assert.Equal(new Size(123, 456), target.ClientSize);
  35. }
  36. }
  37. [Fact]
  38. public void Width_Should_Not_Be_Set_On_Construction()
  39. {
  40. using (Locator.CurrentMutable.WithResolver())
  41. {
  42. this.RegisterServices();
  43. var impl = new Mock<ITopLevelImpl>();
  44. impl.Setup(x => x.ClientSize).Returns(new Size(123, 456));
  45. var target = new TestTopLevel(impl.Object);
  46. Assert.Equal(double.NaN, target.Width);
  47. }
  48. }
  49. [Fact]
  50. public void Height_Should_Not_Be_Set_On_Construction()
  51. {
  52. using (Locator.CurrentMutable.WithResolver())
  53. {
  54. this.RegisterServices();
  55. var impl = new Mock<ITopLevelImpl>();
  56. impl.Setup(x => x.ClientSize).Returns(new Size(123, 456));
  57. var target = new TestTopLevel(impl.Object);
  58. Assert.Equal(double.NaN, target.Height);
  59. }
  60. }
  61. [Fact]
  62. public void Layout_Pass_Should_Not_Be_Automatically_Scheduled()
  63. {
  64. using (Locator.CurrentMutable.WithResolver())
  65. {
  66. this.RegisterServices();
  67. var impl = new Mock<ITopLevelImpl>();
  68. var target = new TestTopLevel(impl.Object);
  69. // The layout pass should be scheduled by the derived class.
  70. var layoutManagerMock = Mock.Get(target.LayoutManager);
  71. layoutManagerMock.Verify(x => x.ExecuteLayoutPass(), Times.Never);
  72. }
  73. }
  74. [Fact]
  75. public void Bounds_Should_Be_Set_After_Layout_Pass()
  76. {
  77. using (Locator.CurrentMutable.WithResolver())
  78. {
  79. this.RegisterServices();
  80. Locator.CurrentMutable.RegisterConstant(new LayoutManager(), typeof(ILayoutManager));
  81. var impl = new Mock<ITopLevelImpl>();
  82. impl.SetupProperty(x => x.ClientSize);
  83. impl.SetupProperty(x => x.Resized);
  84. var target = new TestTopLevel(impl.Object)
  85. {
  86. Template = new ControlTemplate<TestTopLevel>(x =>
  87. new ContentPresenter
  88. {
  89. [~ContentPresenter.ContentProperty] = x[~TestTopLevel.ContentProperty],
  90. }),
  91. Content = new TextBlock
  92. {
  93. Width = 321,
  94. Height = 432,
  95. }
  96. };
  97. target.LayoutManager.ExecuteLayoutPass();
  98. Assert.Equal(new Rect(0, 0, 321, 432), target.Bounds);
  99. }
  100. }
  101. [Fact]
  102. public void Impl_ClientSize_Should_Be_Set_After_Layout_Pass()
  103. {
  104. using (Locator.CurrentMutable.WithResolver())
  105. {
  106. this.RegisterServices();
  107. Locator.CurrentMutable.RegisterConstant(new LayoutManager(), typeof(ILayoutManager));
  108. var impl = new Mock<ITopLevelImpl>();
  109. var target = new TestTopLevel(impl.Object)
  110. {
  111. Template = new ControlTemplate<TestTopLevel>(x =>
  112. new ContentPresenter
  113. {
  114. [~ContentPresenter.ContentProperty] = x[~TestTopLevel.ContentProperty],
  115. }),
  116. Content = new TextBlock
  117. {
  118. Width = 321,
  119. Height = 432,
  120. }
  121. };
  122. target.LayoutManager.ExecuteLayoutPass();
  123. impl.VerifySet(x => x.ClientSize = new Size(321, 432));
  124. }
  125. }
  126. [Fact]
  127. public void Width_And_Height_Should_Not_Be_Set_After_Layout_Pass()
  128. {
  129. using (Locator.CurrentMutable.WithResolver())
  130. {
  131. this.RegisterServices();
  132. var impl = new Mock<ITopLevelImpl>();
  133. impl.Setup(x => x.ClientSize).Returns(new Size(123, 456));
  134. var target = new TestTopLevel(impl.Object);
  135. target.LayoutManager.ExecuteLayoutPass();
  136. Assert.Equal(double.NaN, target.Width);
  137. Assert.Equal(double.NaN, target.Height);
  138. }
  139. }
  140. [Fact]
  141. public void Render_Should_Be_Scheduled_After_Layout_Pass()
  142. {
  143. using (Locator.CurrentMutable.WithResolver())
  144. {
  145. this.RegisterServices();
  146. var completed = new Subject<Unit>();
  147. var layoutManagerMock = Mock.Get(Locator.Current.GetService<ILayoutManager>());
  148. layoutManagerMock.Setup(x => x.LayoutCompleted).Returns(completed);
  149. var impl = new Mock<ITopLevelImpl>();
  150. impl.Setup(x => x.ClientSize).Returns(new Size(123, 456));
  151. var target = new TestTopLevel(impl.Object);
  152. completed.OnNext(Unit.Default);
  153. var renderManagerMock = Mock.Get(Locator.Current.GetService<IRenderManager>());
  154. renderManagerMock.Verify(x => x.InvalidateRender(target));
  155. }
  156. }
  157. [Fact]
  158. public void Width_And_Height_Should_Be_Set_After_Window_Resize_Notification()
  159. {
  160. using (Locator.CurrentMutable.WithResolver())
  161. {
  162. this.RegisterServices();
  163. var impl = new Mock<ITopLevelImpl>();
  164. impl.SetupAllProperties();
  165. impl.Setup(x => x.ClientSize).Returns(new Size(123, 456));
  166. // The user has resized the window, so we can no longer auto-size.
  167. var target = new TestTopLevel(impl.Object);
  168. impl.Object.Resized(new Size(100, 200));
  169. Assert.Equal(100, target.Width);
  170. Assert.Equal(200, target.Height);
  171. }
  172. }
  173. [Fact]
  174. public void Activate_Should_Call_Impl_Activate()
  175. {
  176. using (Locator.CurrentMutable.WithResolver())
  177. {
  178. this.RegisterServices();
  179. var impl = new Mock<ITopLevelImpl>();
  180. var target = new TestTopLevel(impl.Object);
  181. target.Activate();
  182. impl.Verify(x => x.Activate());
  183. }
  184. }
  185. [Fact]
  186. public void Impl_Activate_Should_Call_Raise_Activated_Event()
  187. {
  188. using (Locator.CurrentMutable.WithResolver())
  189. {
  190. this.RegisterServices();
  191. var impl = new Mock<ITopLevelImpl>();
  192. impl.SetupAllProperties();
  193. bool raised = false;
  194. var target = new TestTopLevel(impl.Object);
  195. target.Activated += (s, e) => raised = true;
  196. impl.Object.Activated();
  197. Assert.True(raised);
  198. }
  199. }
  200. [Fact]
  201. public void Impl_Close_Should_Call_Raise_Closed_Event()
  202. {
  203. using (Locator.CurrentMutable.WithResolver())
  204. {
  205. this.RegisterServices();
  206. var impl = new Mock<ITopLevelImpl>();
  207. impl.SetupAllProperties();
  208. bool raised = false;
  209. var target = new TestTopLevel(impl.Object);
  210. target.Closed += (s, e) => raised = true;
  211. impl.Object.Closed();
  212. Assert.True(raised);
  213. }
  214. }
  215. [Fact]
  216. public void Impl_Deactivate_Should_Call_Raise_Activated_Event()
  217. {
  218. using (Locator.CurrentMutable.WithResolver())
  219. {
  220. this.RegisterServices();
  221. var impl = new Mock<ITopLevelImpl>();
  222. impl.SetupAllProperties();
  223. bool raised = false;
  224. var target = new TestTopLevel(impl.Object);
  225. target.Deactivated += (s, e) => raised = true;
  226. impl.Object.Deactivated();
  227. Assert.True(raised);
  228. }
  229. }
  230. [Fact]
  231. public void Impl_Input_Should_Pass_Input_To_InputManager()
  232. {
  233. using (Locator.CurrentMutable.WithResolver())
  234. {
  235. this.RegisterServices();
  236. var impl = new Mock<ITopLevelImpl>();
  237. impl.SetupAllProperties();
  238. var target = new TestTopLevel(impl.Object);
  239. var input = new RawKeyEventArgs(
  240. new Mock<IKeyboardDevice>().Object,
  241. 0,
  242. RawKeyEventType.KeyDown,
  243. Key.A);
  244. impl.Object.Input(input);
  245. var inputManagerMock = Mock.Get(InputManager.Instance);
  246. inputManagerMock.Verify(x => x.Process(input));
  247. }
  248. }
  249. private void RegisterServices()
  250. {
  251. var fixture = new Fixture().Customize(new AutoMoqCustomization());
  252. var l = Locator.CurrentMutable;
  253. var formattedText = fixture.Create<IFormattedTextImpl>();
  254. var globalStyles = new Mock<IGlobalStyles>();
  255. var layoutManager = fixture.Create<ILayoutManager>();
  256. var renderInterface = fixture.Create<IPlatformRenderInterface>();
  257. var renderManager = fixture.Create<IRenderManager>();
  258. var windowImpl = new Mock<IWindowImpl>();
  259. var theme = new Styles();
  260. globalStyles.Setup(x => x.Styles).Returns(theme);
  261. l.RegisterConstant(new Mock<IInputManager>().Object, typeof(IInputManager));
  262. l.RegisterConstant(new Mock<IFocusManager>().Object, typeof(IFocusManager));
  263. l.RegisterConstant(globalStyles.Object, typeof(IGlobalStyles));
  264. l.RegisterConstant(layoutManager, typeof(ILayoutManager));
  265. l.RegisterConstant(new Mock<IPlatformThreadingInterface>().Object, typeof(IPlatformThreadingInterface));
  266. l.RegisterConstant(renderInterface, typeof(IPlatformRenderInterface));
  267. l.RegisterConstant(renderManager, typeof(IRenderManager));
  268. l.RegisterConstant(new Styler(), typeof(IStyler));
  269. }
  270. private class TestTopLevel : TopLevel
  271. {
  272. public TestTopLevel(ITopLevelImpl impl)
  273. : base(impl)
  274. {
  275. }
  276. }
  277. }
  278. }