WindowTests.cs 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561
  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_ClientSize_If_SizeToContent_Is_Manual_And_No_Width_Height_Specified()
  287. {
  288. using (UnitTestApplication.Start(TestServices.StyledWindow))
  289. {
  290. var windowImpl = MockWindowingPlatform.CreateWindowMock();
  291. windowImpl.Setup(x => x.ClientSize).Returns(new Size(550, 450));
  292. var child = new ChildControl();
  293. var target = new Window(windowImpl.Object)
  294. {
  295. SizeToContent = SizeToContent.Manual,
  296. Content = child
  297. };
  298. target.Show();
  299. Assert.Equal(new Size(550, 450), child.MeasureSize);
  300. }
  301. }
  302. [Fact]
  303. public void Child_Should_Be_Measured_With_Infinity_If_SizeToContent_Is_WidthAndHeight()
  304. {
  305. using (UnitTestApplication.Start(TestServices.StyledWindow))
  306. {
  307. var child = new ChildControl();
  308. var target = new Window
  309. {
  310. Width = 100,
  311. Height = 50,
  312. SizeToContent = SizeToContent.WidthAndHeight,
  313. Content = child
  314. };
  315. target.Show();
  316. Assert.Equal(Size.Infinity, child.MeasureSize);
  317. }
  318. }
  319. [Fact]
  320. public void Should_Not_Have_Offset_On_Bounds_When_Content_Larger_Than_Max_Window_Size()
  321. {
  322. // Issue #3784.
  323. using (UnitTestApplication.Start(TestServices.StyledWindow))
  324. {
  325. var windowImpl = MockWindowingPlatform.CreateWindowMock();
  326. var clientSize = new Size(200, 200);
  327. var maxClientSize = new Size(480, 480);
  328. windowImpl.Setup(x => x.Resize(It.IsAny<Size>())).Callback<Size>(size =>
  329. {
  330. clientSize = size.Constrain(maxClientSize);
  331. windowImpl.Object.Resized?.Invoke(clientSize);
  332. });
  333. windowImpl.Setup(x => x.ClientSize).Returns(() => clientSize);
  334. var child = new Canvas
  335. {
  336. Width = 400,
  337. Height = 800,
  338. };
  339. var target = new Window(windowImpl.Object)
  340. {
  341. SizeToContent = SizeToContent.WidthAndHeight,
  342. Content = child
  343. };
  344. target.Show();
  345. Assert.Equal(new Size(400, 480), target.Bounds.Size);
  346. // Issue #3784 causes this to be (0, 160) which makes no sense as Window has no
  347. // parent control to be offset against.
  348. Assert.Equal(new Point(0, 0), target.Bounds.Position);
  349. }
  350. }
  351. [Fact]
  352. public void Width_Height_Should_Not_Be_NaN_After_Show_With_SizeToContent_WidthAndHeight()
  353. {
  354. using (UnitTestApplication.Start(TestServices.StyledWindow))
  355. {
  356. var child = new Canvas
  357. {
  358. Width = 400,
  359. Height = 800,
  360. };
  361. var target = new Window()
  362. {
  363. SizeToContent = SizeToContent.WidthAndHeight,
  364. Content = child
  365. };
  366. target.Show();
  367. Assert.Equal(400, target.Width);
  368. Assert.Equal(800, target.Height);
  369. }
  370. }
  371. [Fact]
  372. public void SizeToContent_Should_Not_Be_Lost_On_Show()
  373. {
  374. using (UnitTestApplication.Start(TestServices.StyledWindow))
  375. {
  376. var child = new Canvas
  377. {
  378. Width = 400,
  379. Height = 800,
  380. };
  381. var target = new Window()
  382. {
  383. SizeToContent = SizeToContent.WidthAndHeight,
  384. Content = child
  385. };
  386. target.Show();
  387. Assert.Equal(SizeToContent.WidthAndHeight, target.SizeToContent);
  388. }
  389. }
  390. [Fact]
  391. public void Width_Height_Should_Be_Updated_When_SizeToContent_Is_WidthAndHeight()
  392. {
  393. using (UnitTestApplication.Start(TestServices.StyledWindow))
  394. {
  395. var child = new Canvas
  396. {
  397. Width = 400,
  398. Height = 800,
  399. };
  400. var target = new Window()
  401. {
  402. SizeToContent = SizeToContent.WidthAndHeight,
  403. Content = child
  404. };
  405. target.Show();
  406. Assert.Equal(400, target.Width);
  407. Assert.Equal(800, target.Height);
  408. child.Width = 410;
  409. target.LayoutManager.ExecuteLayoutPass();
  410. Assert.Equal(410, target.Width);
  411. Assert.Equal(800, target.Height);
  412. Assert.Equal(SizeToContent.WidthAndHeight, target.SizeToContent);
  413. }
  414. }
  415. [Fact]
  416. public void Setting_Width_Should_Resize_WindowImpl()
  417. {
  418. // Issue #3796
  419. using (UnitTestApplication.Start(TestServices.StyledWindow))
  420. {
  421. var target = new Window()
  422. {
  423. Width = 400,
  424. Height = 800,
  425. };
  426. target.Show();
  427. Assert.Equal(400, target.Width);
  428. Assert.Equal(800, target.Height);
  429. target.Width = 410;
  430. target.LayoutManager.ExecuteLayoutPass();
  431. var windowImpl = Mock.Get(target.PlatformImpl);
  432. windowImpl.Verify(x => x.Resize(new Size(410, 800)));
  433. Assert.Equal(410, target.Width);
  434. }
  435. }
  436. private IWindowImpl CreateImpl(Mock<IRenderer> renderer)
  437. {
  438. return Mock.Of<IWindowImpl>(x =>
  439. x.Scaling == 1 &&
  440. x.CreateRenderer(It.IsAny<IRenderRoot>()) == renderer.Object);
  441. }
  442. private class ChildControl : Control
  443. {
  444. public Size MeasureSize { get; private set; }
  445. protected override Size MeasureOverride(Size availableSize)
  446. {
  447. MeasureSize = availableSize;
  448. return base.MeasureOverride(availableSize);
  449. }
  450. }
  451. }
  452. }