TopLevelTests.cs 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. // Copyright (c) The Perspex Project. All rights reserved.
  2. // Licensed under the MIT license. See licence.md file in the project root for full license information.
  3. using System;
  4. using System.Reactive;
  5. using System.Reactive.Subjects;
  6. using Moq;
  7. using Perspex.Controls.Presenters;
  8. using Perspex.Controls.Templates;
  9. using Perspex.Input;
  10. using Perspex.Input.Raw;
  11. using Perspex.Layout;
  12. using Perspex.Platform;
  13. using Perspex.Rendering;
  14. using Perspex.Styling;
  15. using Perspex.UnitTests;
  16. using Ploeh.AutoFixture;
  17. using Ploeh.AutoFixture.AutoMoq;
  18. using Xunit;
  19. namespace Perspex.Controls.UnitTests
  20. {
  21. public class TopLevelTests
  22. {
  23. [Fact]
  24. public void ClientSize_Should_Be_Set_On_Construction()
  25. {
  26. using (UnitTestApplication.Start(TestServices.StyledWindow))
  27. {
  28. var impl = new Mock<ITopLevelImpl>();
  29. impl.Setup(x => x.ClientSize).Returns(new Size(123, 456));
  30. var target = new TestTopLevel(impl.Object);
  31. Assert.Equal(new Size(123, 456), target.ClientSize);
  32. }
  33. }
  34. [Fact]
  35. public void Width_Should_Not_Be_Set_On_Construction()
  36. {
  37. using (UnitTestApplication.Start(TestServices.StyledWindow))
  38. {
  39. var impl = new Mock<ITopLevelImpl>();
  40. impl.Setup(x => x.ClientSize).Returns(new Size(123, 456));
  41. var target = new TestTopLevel(impl.Object);
  42. Assert.Equal(double.NaN, target.Width);
  43. }
  44. }
  45. [Fact]
  46. public void Height_Should_Not_Be_Set_On_Construction()
  47. {
  48. using (UnitTestApplication.Start(TestServices.StyledWindow))
  49. {
  50. var impl = new Mock<ITopLevelImpl>();
  51. impl.Setup(x => x.ClientSize).Returns(new Size(123, 456));
  52. var target = new TestTopLevel(impl.Object);
  53. Assert.Equal(double.NaN, target.Height);
  54. }
  55. }
  56. [Fact]
  57. public void Layout_Pass_Should_Not_Be_Automatically_Scheduled()
  58. {
  59. var services = TestServices.StyledWindow.With(layoutManager: Mock.Of<ILayoutManager>());
  60. using (UnitTestApplication.Start(services))
  61. {
  62. var impl = new Mock<ITopLevelImpl>();
  63. var target = new TestTopLevel(impl.Object);
  64. // The layout pass should be scheduled by the derived class.
  65. var layoutManagerMock = Mock.Get(LayoutManager.Instance);
  66. layoutManagerMock.Verify(x => x.ExecuteLayoutPass(), Times.Never);
  67. }
  68. }
  69. [Fact]
  70. public void Bounds_Should_Be_Set_After_Layout_Pass()
  71. {
  72. using (UnitTestApplication.Start(TestServices.StyledWindow))
  73. {
  74. var impl = new Mock<ITopLevelImpl>();
  75. impl.SetupProperty(x => x.ClientSize);
  76. impl.SetupProperty(x => x.Resized);
  77. var target = new TestTopLevel(impl.Object)
  78. {
  79. Template = CreateTemplate(),
  80. Content = new TextBlock
  81. {
  82. Width = 321,
  83. Height = 432,
  84. }
  85. };
  86. LayoutManager.Instance.ExecuteInitialLayoutPass(target);
  87. Assert.Equal(new Rect(0, 0, 321, 432), target.Bounds);
  88. }
  89. }
  90. [Fact]
  91. public void Impl_ClientSize_Should_Be_Set_After_Layout_Pass()
  92. {
  93. using (UnitTestApplication.Start(TestServices.StyledWindow))
  94. {
  95. var impl = new Mock<ITopLevelImpl>();
  96. var target = new TestTopLevel(impl.Object)
  97. {
  98. Template = CreateTemplate(),
  99. Content = new TextBlock
  100. {
  101. Width = 321,
  102. Height = 432,
  103. }
  104. };
  105. LayoutManager.Instance.ExecuteInitialLayoutPass(target);
  106. impl.VerifySet(x => x.ClientSize = new Size(321, 432));
  107. }
  108. }
  109. [Fact]
  110. public void Width_And_Height_Should_Not_Be_Set_After_Layout_Pass()
  111. {
  112. using (UnitTestApplication.Start(TestServices.StyledWindow))
  113. {
  114. var impl = new Mock<ITopLevelImpl>();
  115. impl.Setup(x => x.ClientSize).Returns(new Size(123, 456));
  116. var target = new TestTopLevel(impl.Object);
  117. LayoutManager.Instance.ExecuteLayoutPass();
  118. Assert.Equal(double.NaN, target.Width);
  119. Assert.Equal(double.NaN, target.Height);
  120. }
  121. }
  122. [Fact]
  123. public void Width_And_Height_Should_Be_Set_After_Window_Resize_Notification()
  124. {
  125. using (UnitTestApplication.Start(TestServices.StyledWindow))
  126. {
  127. var impl = new Mock<ITopLevelImpl>();
  128. impl.SetupAllProperties();
  129. impl.Setup(x => x.ClientSize).Returns(new Size(123, 456));
  130. // The user has resized the window, so we can no longer auto-size.
  131. var target = new TestTopLevel(impl.Object);
  132. impl.Object.Resized(new Size(100, 200));
  133. Assert.Equal(100, target.Width);
  134. Assert.Equal(200, target.Height);
  135. }
  136. }
  137. [Fact]
  138. public void Activate_Should_Call_Impl_Activate()
  139. {
  140. using (UnitTestApplication.Start(TestServices.StyledWindow))
  141. {
  142. var impl = new Mock<ITopLevelImpl>();
  143. var target = new TestTopLevel(impl.Object);
  144. target.Activate();
  145. impl.Verify(x => x.Activate());
  146. }
  147. }
  148. [Fact]
  149. public void Impl_Activate_Should_Call_Raise_Activated_Event()
  150. {
  151. using (UnitTestApplication.Start(TestServices.StyledWindow))
  152. {
  153. var impl = new Mock<ITopLevelImpl>();
  154. impl.SetupAllProperties();
  155. bool raised = false;
  156. var target = new TestTopLevel(impl.Object);
  157. target.Activated += (s, e) => raised = true;
  158. impl.Object.Activated();
  159. Assert.True(raised);
  160. }
  161. }
  162. [Fact]
  163. public void Impl_Close_Should_Call_Raise_Closed_Event()
  164. {
  165. using (UnitTestApplication.Start(TestServices.StyledWindow))
  166. {
  167. var impl = new Mock<ITopLevelImpl>();
  168. impl.SetupAllProperties();
  169. bool raised = false;
  170. var target = new TestTopLevel(impl.Object);
  171. target.Closed += (s, e) => raised = true;
  172. impl.Object.Closed();
  173. Assert.True(raised);
  174. }
  175. }
  176. [Fact]
  177. public void Impl_Deactivate_Should_Call_Raise_Activated_Event()
  178. {
  179. using (UnitTestApplication.Start(TestServices.StyledWindow))
  180. {
  181. var impl = new Mock<ITopLevelImpl>();
  182. impl.SetupAllProperties();
  183. bool raised = false;
  184. var target = new TestTopLevel(impl.Object);
  185. target.Deactivated += (s, e) => raised = true;
  186. impl.Object.Deactivated();
  187. Assert.True(raised);
  188. }
  189. }
  190. [Fact]
  191. public void Impl_Input_Should_Pass_Input_To_InputManager()
  192. {
  193. var inputManagerMock = new Mock<IInputManager>();
  194. var services = TestServices.StyledWindow.With(inputManager: inputManagerMock.Object);
  195. using (UnitTestApplication.Start(services))
  196. {
  197. var impl = new Mock<ITopLevelImpl>();
  198. impl.SetupAllProperties();
  199. var target = new TestTopLevel(impl.Object);
  200. var input = new RawKeyEventArgs(
  201. new Mock<IKeyboardDevice>().Object,
  202. 0,
  203. RawKeyEventType.KeyDown,
  204. Key.A, InputModifiers.None);
  205. impl.Object.Input(input);
  206. inputManagerMock.Verify(x => x.Process(input));
  207. }
  208. }
  209. [Fact]
  210. public void Adding_Top_Level_As_Child_Should_Throw_Exception()
  211. {
  212. using (UnitTestApplication.Start(TestServices.StyledWindow))
  213. {
  214. var impl = new Mock<ITopLevelImpl>();
  215. impl.SetupAllProperties();
  216. var target = new TestTopLevel(impl.Object);
  217. var child = new TestTopLevel(impl.Object);
  218. target.Template = CreateTemplate();
  219. target.Content = child;
  220. Assert.Throws<InvalidOperationException>(() => target.ApplyTemplate());
  221. }
  222. }
  223. private FuncControlTemplate<TestTopLevel> CreateTemplate()
  224. {
  225. return new FuncControlTemplate<TestTopLevel>(x =>
  226. new ContentPresenter
  227. {
  228. Name = "PART_ContentPresenter",
  229. [!ContentPresenter.ContentProperty] = x[!ContentControl.ContentProperty],
  230. });
  231. }
  232. private class TestTopLevel : TopLevel
  233. {
  234. public TestTopLevel(ITopLevelImpl impl)
  235. : base(impl)
  236. {
  237. }
  238. }
  239. }
  240. }