WindowTests.cs 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Threading.Tasks;
  4. using Avalonia.Layout;
  5. using Avalonia.Platform;
  6. using Avalonia.Rendering;
  7. using Avalonia.UnitTests;
  8. using Moq;
  9. using Xunit;
  10. namespace Avalonia.Controls.UnitTests
  11. {
  12. public class WindowTests
  13. {
  14. [Fact]
  15. public void Setting_Title_Should_Set_Impl_Title()
  16. {
  17. var windowImpl = new Mock<IWindowImpl>();
  18. var windowingPlatform = new MockWindowingPlatform(() => windowImpl.Object);
  19. using (UnitTestApplication.Start(new TestServices(windowingPlatform: windowingPlatform)))
  20. {
  21. var target = new Window();
  22. target.Title = "Hello World";
  23. windowImpl.Verify(x => x.SetTitle("Hello World"));
  24. }
  25. }
  26. [Fact]
  27. public void IsVisible_Should_Initially_Be_False()
  28. {
  29. using (UnitTestApplication.Start(TestServices.MockWindowingPlatform))
  30. {
  31. var window = new Window();
  32. Assert.False(window.IsVisible);
  33. }
  34. }
  35. [Fact]
  36. public void IsVisible_Should_Be_True_After_Show()
  37. {
  38. using (UnitTestApplication.Start(TestServices.StyledWindow))
  39. {
  40. var window = new Window();
  41. window.Show();
  42. Assert.True(window.IsVisible);
  43. }
  44. }
  45. [Fact]
  46. public void IsVisible_Should_Be_True_After_ShowDialog()
  47. {
  48. using (UnitTestApplication.Start(TestServices.StyledWindow))
  49. {
  50. var parent = new Window();
  51. parent.Show();
  52. var window = new Window();
  53. var task = window.ShowDialog(parent);
  54. Assert.True(window.IsVisible);
  55. }
  56. }
  57. [Fact]
  58. public void IsVisible_Should_Be_False_After_Hide()
  59. {
  60. using (UnitTestApplication.Start(TestServices.StyledWindow))
  61. {
  62. var window = new Window();
  63. window.Show();
  64. window.Hide();
  65. Assert.False(window.IsVisible);
  66. }
  67. }
  68. [Fact]
  69. public void IsVisible_Should_Be_False_After_Close()
  70. {
  71. using (UnitTestApplication.Start(TestServices.StyledWindow))
  72. {
  73. var window = new Window();
  74. window.Show();
  75. window.Close();
  76. Assert.False(window.IsVisible);
  77. }
  78. }
  79. [Fact]
  80. public void IsVisible_Should_Be_False_After_Impl_Signals_Close()
  81. {
  82. var windowImpl = new Mock<IWindowImpl>();
  83. windowImpl.SetupProperty(x => x.Closed);
  84. windowImpl.Setup(x => x.Scaling).Returns(1);
  85. var services = TestServices.StyledWindow.With(
  86. windowingPlatform: new MockWindowingPlatform(() => windowImpl.Object));
  87. using (UnitTestApplication.Start(services))
  88. {
  89. var window = new Window();
  90. window.Show();
  91. windowImpl.Object.Closed();
  92. Assert.False(window.IsVisible);
  93. }
  94. }
  95. [Fact]
  96. public void Closing_Should_Only_Be_Invoked_Once()
  97. {
  98. using (UnitTestApplication.Start(TestServices.StyledWindow))
  99. {
  100. var window = new Window();
  101. var count = 0;
  102. window.Closing +=
  103. (sender, e) =>
  104. {
  105. count++;
  106. };
  107. window.Show();
  108. window.Close();
  109. Assert.Equal(1, count);
  110. }
  111. }
  112. [Fact]
  113. public void Showing_Should_Start_Renderer()
  114. {
  115. using (UnitTestApplication.Start(TestServices.StyledWindow))
  116. {
  117. var renderer = new Mock<IRenderer>();
  118. var target = new Window(CreateImpl(renderer));
  119. target.Show();
  120. renderer.Verify(x => x.Start(), Times.Once);
  121. }
  122. }
  123. [Fact]
  124. public void ShowDialog_Should_Start_Renderer()
  125. {
  126. using (UnitTestApplication.Start(TestServices.StyledWindow))
  127. {
  128. var parent = Mock.Of<IWindowImpl>();
  129. var renderer = new Mock<IRenderer>();
  130. var target = new Window(CreateImpl(renderer));
  131. target.ShowDialog<object>(parent);
  132. renderer.Verify(x => x.Start(), Times.Once);
  133. }
  134. }
  135. [Fact]
  136. public void ShowDialog_Should_Raise_Opened()
  137. {
  138. using (UnitTestApplication.Start(TestServices.StyledWindow))
  139. {
  140. var parent = Mock.Of<IWindowImpl>();
  141. var target = new Window();
  142. var raised = false;
  143. target.Opened += (s, e) => raised = true;
  144. target.ShowDialog<object>(parent);
  145. Assert.True(raised);
  146. }
  147. }
  148. [Fact]
  149. public void Hiding_Should_Stop_Renderer()
  150. {
  151. using (UnitTestApplication.Start(TestServices.StyledWindow))
  152. {
  153. var renderer = new Mock<IRenderer>();
  154. var target = new Window(CreateImpl(renderer));
  155. target.Show();
  156. target.Hide();
  157. renderer.Verify(x => x.Stop(), Times.Once);
  158. }
  159. }
  160. [Fact]
  161. public async Task ShowDialog_With_ValueType_Returns_Default_When_Closed()
  162. {
  163. using (UnitTestApplication.Start(TestServices.StyledWindow))
  164. {
  165. var parent = new Mock<IWindowImpl>();
  166. var windowImpl = new Mock<IWindowImpl>();
  167. windowImpl.SetupProperty(x => x.Closed);
  168. windowImpl.Setup(x => x.Scaling).Returns(1);
  169. var target = new Window(windowImpl.Object);
  170. var task = target.ShowDialog<bool>(parent.Object);
  171. windowImpl.Object.Closed();
  172. var result = await task;
  173. Assert.False(result);
  174. }
  175. }
  176. [Fact]
  177. public void Calling_Show_On_Closed_Window_Should_Throw()
  178. {
  179. using (UnitTestApplication.Start(TestServices.StyledWindow))
  180. {
  181. var target = new Window();
  182. target.Show();
  183. target.Close();
  184. var openedRaised = false;
  185. target.Opened += (s, e) => openedRaised = true;
  186. var ex = Assert.Throws<InvalidOperationException>(() => target.Show());
  187. Assert.Equal("Cannot re-show a closed window.", ex.Message);
  188. Assert.False(openedRaised);
  189. }
  190. }
  191. [Fact]
  192. public async Task Calling_ShowDialog_On_Closed_Window_Should_Throw()
  193. {
  194. using (UnitTestApplication.Start(TestServices.StyledWindow))
  195. {
  196. var parent = new Mock<IWindowImpl>();
  197. var windowImpl = new Mock<IWindowImpl>();
  198. windowImpl.SetupProperty(x => x.Closed);
  199. windowImpl.Setup(x => x.Scaling).Returns(1);
  200. var target = new Window(windowImpl.Object);
  201. var task = target.ShowDialog<bool>(parent.Object);
  202. windowImpl.Object.Closed();
  203. await task;
  204. var openedRaised = false;
  205. target.Opened += (s, e) => openedRaised = true;
  206. var ex = await Assert.ThrowsAsync<InvalidOperationException>(() => target.ShowDialog<bool>(parent.Object));
  207. Assert.Equal("Cannot re-show a closed window.", ex.Message);
  208. Assert.False(openedRaised);
  209. }
  210. }
  211. [Fact]
  212. public void Window_Should_Be_Centered_When_WindowStartupLocation_Is_CenterScreen()
  213. {
  214. var screen1 = new Mock<Screen>(1.0, new PixelRect(new PixelSize(1920, 1080)), new PixelRect(new PixelSize(1920, 1040)), true);
  215. var screen2 = new Mock<Screen>(1.0, new PixelRect(new PixelSize(1366, 768)), new PixelRect(new PixelSize(1366, 728)), false);
  216. var screens = new Mock<IScreenImpl>();
  217. screens.Setup(x => x.AllScreens).Returns(new Screen[] { screen1.Object, screen2.Object });
  218. var windowImpl = MockWindowingPlatform.CreateWindowMock();
  219. windowImpl.Setup(x => x.ClientSize).Returns(new Size(800, 480));
  220. windowImpl.Setup(x => x.Scaling).Returns(1);
  221. windowImpl.Setup(x => x.Screen).Returns(screens.Object);
  222. using (UnitTestApplication.Start(TestServices.StyledWindow))
  223. {
  224. var window = new Window(windowImpl.Object);
  225. window.WindowStartupLocation = WindowStartupLocation.CenterScreen;
  226. window.Position = new PixelPoint(60, 40);
  227. window.Show();
  228. var expectedPosition = new PixelPoint(
  229. (int)(screen1.Object.WorkingArea.Size.Width / 2 - window.ClientSize.Width / 2),
  230. (int)(screen1.Object.WorkingArea.Size.Height / 2 - window.ClientSize.Height / 2));
  231. Assert.Equal(window.Position, expectedPosition);
  232. }
  233. }
  234. [Fact]
  235. public void Window_Should_Be_Centered_Relative_To_Owner_When_WindowStartupLocation_Is_CenterOwner()
  236. {
  237. var parentWindowImpl = MockWindowingPlatform.CreateWindowMock();
  238. parentWindowImpl.Setup(x => x.ClientSize).Returns(new Size(800, 480));
  239. parentWindowImpl.Setup(x => x.MaxClientSize).Returns(new Size(1920, 1080));
  240. parentWindowImpl.Setup(x => x.Scaling).Returns(1);
  241. var windowImpl = MockWindowingPlatform.CreateWindowMock();
  242. windowImpl.Setup(x => x.ClientSize).Returns(new Size(320, 200));
  243. windowImpl.Setup(x => x.MaxClientSize).Returns(new Size(1920, 1080));
  244. windowImpl.Setup(x => x.Scaling).Returns(1);
  245. var parentWindowServices = TestServices.StyledWindow.With(
  246. windowingPlatform: new MockWindowingPlatform(() => parentWindowImpl.Object));
  247. var windowServices = TestServices.StyledWindow.With(
  248. windowingPlatform: new MockWindowingPlatform(() => windowImpl.Object));
  249. using (UnitTestApplication.Start(parentWindowServices))
  250. {
  251. var parentWindow = new Window();
  252. parentWindow.Position = new PixelPoint(60, 40);
  253. parentWindow.Show();
  254. using (UnitTestApplication.Start(windowServices))
  255. {
  256. var window = new Window();
  257. window.WindowStartupLocation = WindowStartupLocation.CenterOwner;
  258. window.Position = new PixelPoint(60, 40);
  259. window.Owner = parentWindow;
  260. window.Show();
  261. var expectedPosition = new PixelPoint(
  262. (int)(parentWindow.Position.X + parentWindow.ClientSize.Width / 2 - window.ClientSize.Width / 2),
  263. (int)(parentWindow.Position.Y + parentWindow.ClientSize.Height / 2 - window.ClientSize.Height / 2));
  264. Assert.Equal(window.Position, expectedPosition);
  265. }
  266. }
  267. }
  268. [Fact]
  269. public void Child_Should_Be_Measured_With_Width_And_Height_If_SizeToContent_Is_Manual()
  270. {
  271. using (UnitTestApplication.Start(TestServices.StyledWindow))
  272. {
  273. var child = new ChildControl();
  274. var target = new Window
  275. {
  276. Width = 100,
  277. Height = 50,
  278. SizeToContent = SizeToContent.Manual,
  279. Content = child
  280. };
  281. target.Show();
  282. Assert.Equal(new Size(100, 50), child.MeasureSize);
  283. }
  284. }
  285. [Fact]
  286. public void Child_Should_Be_Measured_With_Infinity_If_SizeToContent_Is_WidthAndHeight()
  287. {
  288. using (UnitTestApplication.Start(TestServices.StyledWindow))
  289. {
  290. var child = new ChildControl();
  291. var target = new Window
  292. {
  293. Width = 100,
  294. Height = 50,
  295. SizeToContent = SizeToContent.WidthAndHeight,
  296. Content = child
  297. };
  298. target.Show();
  299. Assert.Equal(Size.Infinity, child.MeasureSize);
  300. }
  301. }
  302. [Fact]
  303. public void Should_Not_Have_Offset_On_Bounds_When_Content_Larger_Than_Max_Window_Size()
  304. {
  305. // Issue #3784.
  306. using (UnitTestApplication.Start(TestServices.StyledWindow))
  307. {
  308. var windowImpl = MockWindowingPlatform.CreateWindowMock();
  309. var clientSize = new Size(200, 200);
  310. var maxClientSize = new Size(480, 480);
  311. windowImpl.Setup(x => x.Resize(It.IsAny<Size>())).Callback<Size>(size =>
  312. {
  313. clientSize = size.Constrain(maxClientSize);
  314. windowImpl.Object.Resized?.Invoke(clientSize);
  315. });
  316. windowImpl.Setup(x => x.ClientSize).Returns(() => clientSize);
  317. var child = new Canvas
  318. {
  319. Width = 400,
  320. Height = 800,
  321. };
  322. var target = new Window(windowImpl.Object)
  323. {
  324. SizeToContent = SizeToContent.WidthAndHeight,
  325. Content = child
  326. };
  327. target.Show();
  328. Assert.Equal(new Size(400, 480), target.Bounds.Size);
  329. // Issue #3784 causes this to be (0, 160) which makes no sense as Window has no
  330. // parent control to be offset against.
  331. Assert.Equal(new Point(0, 0), target.Bounds.Position);
  332. }
  333. }
  334. [Fact]
  335. public void Width_Height_Should_Not_Be_NaN_After_Show_With_SizeToContent_WidthAndHeight()
  336. {
  337. using (UnitTestApplication.Start(TestServices.StyledWindow))
  338. {
  339. var child = new Canvas
  340. {
  341. Width = 400,
  342. Height = 800,
  343. };
  344. var target = new Window()
  345. {
  346. SizeToContent = SizeToContent.WidthAndHeight,
  347. Content = child
  348. };
  349. target.Show();
  350. Assert.Equal(400, target.Width);
  351. Assert.Equal(800, target.Height);
  352. }
  353. }
  354. [Fact]
  355. public void SizeToContent_Should_Not_Be_Lost_On_Show()
  356. {
  357. using (UnitTestApplication.Start(TestServices.StyledWindow))
  358. {
  359. var child = new Canvas
  360. {
  361. Width = 400,
  362. Height = 800,
  363. };
  364. var target = new Window()
  365. {
  366. SizeToContent = SizeToContent.WidthAndHeight,
  367. Content = child
  368. };
  369. target.Show();
  370. Assert.Equal(SizeToContent.WidthAndHeight, target.SizeToContent);
  371. }
  372. }
  373. [Fact]
  374. public void Width_Height_Should_Be_Updated_When_SizeToContent_Is_WidthAndHeight()
  375. {
  376. using (UnitTestApplication.Start(TestServices.StyledWindow))
  377. {
  378. var child = new Canvas
  379. {
  380. Width = 400,
  381. Height = 800,
  382. };
  383. var target = new Window()
  384. {
  385. SizeToContent = SizeToContent.WidthAndHeight,
  386. Content = child
  387. };
  388. target.Show();
  389. Assert.Equal(400, target.Width);
  390. Assert.Equal(800, target.Height);
  391. child.Width = 410;
  392. target.LayoutManager.ExecuteLayoutPass();
  393. Assert.Equal(410, target.Width);
  394. Assert.Equal(800, target.Height);
  395. Assert.Equal(SizeToContent.WidthAndHeight, target.SizeToContent);
  396. }
  397. }
  398. private IWindowImpl CreateImpl(Mock<IRenderer> renderer)
  399. {
  400. return Mock.Of<IWindowImpl>(x =>
  401. x.Scaling == 1 &&
  402. x.CreateRenderer(It.IsAny<IRenderRoot>()) == renderer.Object);
  403. }
  404. private class ChildControl : Control
  405. {
  406. public Size MeasureSize { get; private set; }
  407. protected override Size MeasureOverride(Size availableSize)
  408. {
  409. MeasureSize = availableSize;
  410. return base.MeasureOverride(availableSize);
  411. }
  412. }
  413. }
  414. }