TopLevelTests.cs 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. // Copyright (c) The Avalonia 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 Avalonia.Controls.Presenters;
  5. using Avalonia.Controls.Templates;
  6. using Avalonia.Input;
  7. using Avalonia.Input.Raw;
  8. using Avalonia.Layout;
  9. using Avalonia.LogicalTree;
  10. using Avalonia.Platform;
  11. using Avalonia.UnitTests;
  12. using Moq;
  13. using Xunit;
  14. namespace Avalonia.Controls.UnitTests
  15. {
  16. public class TopLevelTests
  17. {
  18. [Fact]
  19. public void IsAttachedToLogicalTree_Is_True()
  20. {
  21. using (UnitTestApplication.Start(TestServices.StyledWindow))
  22. {
  23. var impl = new Mock<ITopLevelImpl>();
  24. var target = new TestTopLevel(impl.Object);
  25. Assert.True(((ILogical)target).IsAttachedToLogicalTree);
  26. }
  27. }
  28. [Fact]
  29. public void ClientSize_Should_Be_Set_On_Construction()
  30. {
  31. using (UnitTestApplication.Start(TestServices.StyledWindow))
  32. {
  33. var impl = new Mock<ITopLevelImpl>();
  34. impl.Setup(x => x.ClientSize).Returns(new Size(123, 456));
  35. var target = new TestTopLevel(impl.Object);
  36. Assert.Equal(new Size(123, 456), target.ClientSize);
  37. }
  38. }
  39. [Fact]
  40. public void Width_Should_Not_Be_Set_On_Construction()
  41. {
  42. using (UnitTestApplication.Start(TestServices.StyledWindow))
  43. {
  44. var impl = new Mock<ITopLevelImpl>();
  45. impl.Setup(x => x.ClientSize).Returns(new Size(123, 456));
  46. var target = new TestTopLevel(impl.Object);
  47. Assert.Equal(double.NaN, target.Width);
  48. }
  49. }
  50. [Fact]
  51. public void Height_Should_Not_Be_Set_On_Construction()
  52. {
  53. using (UnitTestApplication.Start(TestServices.StyledWindow))
  54. {
  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. var services = TestServices.StyledWindow.With(layoutManager: Mock.Of<ILayoutManager>());
  65. using (UnitTestApplication.Start(services))
  66. {
  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(LayoutManager.Instance);
  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 (UnitTestApplication.Start(TestServices.StyledWindow))
  78. {
  79. var impl = new Mock<ITopLevelImpl>();
  80. impl.SetupProperty(x => x.Resized);
  81. impl.SetupGet(x => x.Scaling).Returns(1);
  82. var target = new TestTopLevel(impl.Object)
  83. {
  84. IsVisible = true,
  85. Template = CreateTemplate(),
  86. Content = new TextBlock
  87. {
  88. Width = 321,
  89. Height = 432,
  90. }
  91. };
  92. LayoutManager.Instance.ExecuteInitialLayoutPass(target);
  93. Assert.Equal(new Rect(0, 0, 321, 432), target.Bounds);
  94. }
  95. }
  96. [Fact]
  97. public void Width_And_Height_Should_Not_Be_Set_After_Layout_Pass()
  98. {
  99. using (UnitTestApplication.Start(TestServices.StyledWindow))
  100. {
  101. var impl = new Mock<ITopLevelImpl>();
  102. impl.Setup(x => x.ClientSize).Returns(new Size(123, 456));
  103. var target = new TestTopLevel(impl.Object);
  104. LayoutManager.Instance.ExecuteLayoutPass();
  105. Assert.Equal(double.NaN, target.Width);
  106. Assert.Equal(double.NaN, target.Height);
  107. }
  108. }
  109. [Fact]
  110. public void Width_And_Height_Should_Be_Set_After_Window_Resize_Notification()
  111. {
  112. using (UnitTestApplication.Start(TestServices.StyledWindow))
  113. {
  114. var impl = new Mock<ITopLevelImpl>();
  115. impl.SetupAllProperties();
  116. impl.Setup(x => x.ClientSize).Returns(new Size(123, 456));
  117. // The user has resized the window, so we can no longer auto-size.
  118. var target = new TestTopLevel(impl.Object);
  119. impl.Object.Resized(new Size(100, 200));
  120. Assert.Equal(100, target.Width);
  121. Assert.Equal(200, target.Height);
  122. }
  123. }
  124. [Fact]
  125. public void Impl_Close_Should_Call_Raise_Closed_Event()
  126. {
  127. using (UnitTestApplication.Start(TestServices.StyledWindow))
  128. {
  129. var impl = new Mock<ITopLevelImpl>();
  130. impl.SetupAllProperties();
  131. bool raised = false;
  132. var target = new TestTopLevel(impl.Object);
  133. target.Closed += (s, e) => raised = true;
  134. impl.Object.Closed();
  135. Assert.True(raised);
  136. }
  137. }
  138. [Fact]
  139. public void Impl_Input_Should_Pass_Input_To_InputManager()
  140. {
  141. var inputManagerMock = new Mock<IInputManager>();
  142. var services = TestServices.StyledWindow.With(inputManager: inputManagerMock.Object);
  143. using (UnitTestApplication.Start(services))
  144. {
  145. var impl = new Mock<ITopLevelImpl>();
  146. impl.SetupAllProperties();
  147. var target = new TestTopLevel(impl.Object);
  148. var input = new RawKeyEventArgs(
  149. new Mock<IKeyboardDevice>().Object,
  150. 0,
  151. RawKeyEventType.KeyDown,
  152. Key.A, InputModifiers.None);
  153. impl.Object.Input(input);
  154. inputManagerMock.Verify(x => x.ProcessInput(input));
  155. }
  156. }
  157. [Fact]
  158. public void Adding_Top_Level_As_Child_Should_Throw_Exception()
  159. {
  160. using (UnitTestApplication.Start(TestServices.StyledWindow))
  161. {
  162. var impl = new Mock<ITopLevelImpl>();
  163. impl.SetupAllProperties();
  164. var target = new TestTopLevel(impl.Object);
  165. var child = new TestTopLevel(impl.Object);
  166. target.Template = CreateTemplate();
  167. target.Content = child;
  168. Assert.Throws<InvalidOperationException>(() => target.ApplyTemplate());
  169. }
  170. }
  171. [Fact]
  172. public void Exiting_Application_Notifies_Top_Level()
  173. {
  174. using (UnitTestApplication.Start(TestServices.StyledWindow))
  175. {
  176. var impl = new Mock<ITopLevelImpl>();
  177. impl.SetupAllProperties();
  178. var target = new TestTopLevel(impl.Object);
  179. UnitTestApplication.Current.Exit();
  180. Assert.True(target.IsClosed);
  181. }
  182. }
  183. private FuncControlTemplate<TestTopLevel> CreateTemplate()
  184. {
  185. return new FuncControlTemplate<TestTopLevel>(x =>
  186. new ContentPresenter
  187. {
  188. Name = "PART_ContentPresenter",
  189. [!ContentPresenter.ContentProperty] = x[!ContentControl.ContentProperty],
  190. });
  191. }
  192. private class TestTopLevel : TopLevel
  193. {
  194. public bool IsClosed { get; private set; }
  195. public TestTopLevel(ITopLevelImpl impl)
  196. : base(impl)
  197. {
  198. }
  199. protected override void HandleApplicationExiting()
  200. {
  201. base.HandleApplicationExiting();
  202. IsClosed = true;
  203. }
  204. }
  205. }
  206. }