WindowTests.cs 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Threading.Tasks;
  4. using Avalonia.Media;
  5. using Avalonia.Platform;
  6. using Avalonia.Rendering;
  7. using Avalonia.Rendering.Composition;
  8. using Avalonia.UnitTests;
  9. using Moq;
  10. using Xunit;
  11. namespace Avalonia.Controls.UnitTests
  12. {
  13. public class WindowTests
  14. {
  15. [Fact]
  16. public void Setting_Title_Should_Set_Impl_Title()
  17. {
  18. var windowImpl = new Mock<IWindowImpl>();
  19. windowImpl.Setup(r => r.Compositor).Returns(RendererMocks.CreateDummyCompositor());
  20. var windowingPlatform = new MockWindowingPlatform(() => windowImpl.Object);
  21. using (UnitTestApplication.Start(new TestServices(windowingPlatform: windowingPlatform)))
  22. {
  23. var target = new Window();
  24. target.Title = "Hello World";
  25. windowImpl.Verify(x => x.SetTitle("Hello World"));
  26. }
  27. }
  28. [Fact]
  29. public void IsVisible_Should_Initially_Be_False()
  30. {
  31. using (UnitTestApplication.Start(TestServices.MockWindowingPlatform))
  32. {
  33. var window = new Window();
  34. Assert.False(window.IsVisible);
  35. }
  36. }
  37. [Fact]
  38. public void IsVisible_Should_Be_True_After_Show()
  39. {
  40. using (UnitTestApplication.Start(TestServices.StyledWindow))
  41. {
  42. var window = new Window();
  43. window.Show();
  44. Assert.True(window.IsVisible);
  45. }
  46. }
  47. [Fact]
  48. public void IsVisible_Should_Be_True_After_ShowDialog()
  49. {
  50. using (UnitTestApplication.Start(TestServices.StyledWindow))
  51. {
  52. var parent = new Window();
  53. parent.Show();
  54. var window = new Window();
  55. var task = window.ShowDialog(parent);
  56. Assert.True(window.IsVisible);
  57. }
  58. }
  59. [Fact]
  60. public void IsVisible_Should_Be_False_After_Hide()
  61. {
  62. using (UnitTestApplication.Start(TestServices.StyledWindow))
  63. {
  64. var window = new Window();
  65. window.Show();
  66. window.Hide();
  67. Assert.False(window.IsVisible);
  68. }
  69. }
  70. [Fact]
  71. public void IsVisible_Should_Be_False_After_Close()
  72. {
  73. using (UnitTestApplication.Start(TestServices.StyledWindow))
  74. {
  75. var window = new Window();
  76. window.Show();
  77. window.Close();
  78. Assert.False(window.IsVisible);
  79. }
  80. }
  81. [Fact]
  82. public void IsVisible_Should_Be_False_After_Impl_Signals_Close()
  83. {
  84. var windowImpl = new Mock<IWindowImpl>();
  85. windowImpl.Setup(r => r.Compositor).Returns(RendererMocks.CreateDummyCompositor());
  86. windowImpl.SetupProperty(x => x.Closed);
  87. windowImpl.Setup(x => x.DesktopScaling).Returns(1);
  88. windowImpl.Setup(x => x.RenderScaling).Returns(1);
  89. var services = TestServices.StyledWindow.With(
  90. windowingPlatform: new MockWindowingPlatform(() => windowImpl.Object));
  91. using (UnitTestApplication.Start(services))
  92. {
  93. var window = new Window();
  94. window.Show();
  95. windowImpl.Object.Closed();
  96. Assert.False(window.IsVisible);
  97. }
  98. }
  99. [Fact]
  100. public void Closing_Should_Only_Be_Invoked_Once()
  101. {
  102. using (UnitTestApplication.Start(TestServices.StyledWindow))
  103. {
  104. var window = new Window();
  105. var count = 0;
  106. window.Closing +=
  107. (sender, e) =>
  108. {
  109. count++;
  110. };
  111. window.Show();
  112. window.Close();
  113. Assert.Equal(1, count);
  114. }
  115. }
  116. [Theory]
  117. [InlineData(true)]
  118. [InlineData(false)]
  119. public void Child_windows_should_be_closed_before_parent(bool programmaticClose)
  120. {
  121. using (UnitTestApplication.Start(TestServices.StyledWindow))
  122. {
  123. var window = new Window();
  124. var child = new Window();
  125. int count = 0;
  126. int windowClosing = 0;
  127. int childClosing = 0;
  128. int windowClosed = 0;
  129. int childClosed = 0;
  130. window.Closing += (sender, e) =>
  131. {
  132. Assert.Equal(WindowCloseReason.WindowClosing, e.CloseReason);
  133. Assert.Equal(programmaticClose, e.IsProgrammatic);
  134. count++;
  135. windowClosing = count;
  136. };
  137. child.Closing += (sender, e) =>
  138. {
  139. Assert.Equal(WindowCloseReason.OwnerWindowClosing, e.CloseReason);
  140. Assert.Equal(programmaticClose, e.IsProgrammatic);
  141. count++;
  142. childClosing = count;
  143. };
  144. window.Closed += (sender, e) =>
  145. {
  146. count++;
  147. windowClosed = count;
  148. };
  149. child.Closed += (sender, e) =>
  150. {
  151. count++;
  152. childClosed = count;
  153. };
  154. window.Show();
  155. child.Show(window);
  156. if (programmaticClose)
  157. {
  158. window.Close();
  159. }
  160. else
  161. {
  162. var cancel = window.PlatformImpl.Closing(WindowCloseReason.WindowClosing);
  163. Assert.Equal(false, cancel);
  164. }
  165. Assert.Equal(2, windowClosing);
  166. Assert.Equal(1, childClosing);
  167. Assert.Equal(4, windowClosed);
  168. Assert.Equal(3, childClosed);
  169. }
  170. }
  171. [Theory]
  172. [InlineData(true)]
  173. [InlineData(false)]
  174. public void Child_windows_must_not_close_before_parent_has_chance_to_Cancel_OSCloseButton(bool programmaticClose)
  175. {
  176. using (UnitTestApplication.Start(TestServices.StyledWindow))
  177. {
  178. var window = new Window();
  179. var child = new Window();
  180. int count = 0;
  181. int windowClosing = 0;
  182. int childClosing = 0;
  183. int windowClosed = 0;
  184. int childClosed = 0;
  185. window.Closing += (sender, e) =>
  186. {
  187. count++;
  188. windowClosing = count;
  189. e.Cancel = true;
  190. };
  191. child.Closing += (sender, e) =>
  192. {
  193. count++;
  194. childClosing = count;
  195. };
  196. window.Closed += (sender, e) =>
  197. {
  198. count++;
  199. windowClosed = count;
  200. };
  201. child.Closed += (sender, e) =>
  202. {
  203. count++;
  204. childClosed = count;
  205. };
  206. window.Show();
  207. child.Show(window);
  208. if (programmaticClose)
  209. {
  210. window.Close();
  211. }
  212. else
  213. {
  214. var cancel = window.PlatformImpl.Closing(WindowCloseReason.WindowClosing);
  215. Assert.Equal(true, cancel);
  216. }
  217. Assert.Equal(2, windowClosing);
  218. Assert.Equal(1, childClosing);
  219. Assert.Equal(0, windowClosed);
  220. Assert.Equal(0, childClosed);
  221. }
  222. }
  223. [Fact]
  224. public void Showing_Should_Start_Renderer()
  225. {
  226. using (UnitTestApplication.Start(TestServices.StyledWindow))
  227. {
  228. var target = new Window(CreateImpl());
  229. target.Show();
  230. Assert.True(MediaContext.Instance.IsTopLevelActive(target));
  231. }
  232. }
  233. [Fact]
  234. public void ShowDialog_Should_Start_Renderer()
  235. {
  236. using (UnitTestApplication.Start(TestServices.StyledWindow))
  237. {
  238. var parent = new Window();
  239. var target = new Window(CreateImpl());
  240. parent.Show();
  241. target.ShowDialog<object>(parent);
  242. Assert.True(MediaContext.Instance.IsTopLevelActive(target));
  243. }
  244. }
  245. [Fact]
  246. public void ShowDialog_Should_Raise_Opened()
  247. {
  248. using (UnitTestApplication.Start(TestServices.StyledWindow))
  249. {
  250. var parent = new Window();
  251. var target = new Window();
  252. var raised = false;
  253. parent.Show();
  254. target.Opened += (s, e) => raised = true;
  255. target.ShowDialog<object>(parent);
  256. Assert.True(raised);
  257. }
  258. }
  259. [Fact]
  260. public void Hiding_Should_Stop_Renderer()
  261. {
  262. using (UnitTestApplication.Start(TestServices.StyledWindow))
  263. {
  264. var target = new Window(CreateImpl());
  265. target.Show();
  266. target.Hide();
  267. Assert.False(MediaContext.Instance.IsTopLevelActive(target));
  268. }
  269. }
  270. [Fact]
  271. public async Task ShowDialog_With_ValueType_Returns_Default_When_Closed()
  272. {
  273. using (UnitTestApplication.Start(TestServices.StyledWindow))
  274. {
  275. var parent = new Window();
  276. var windowImpl = new Mock<IWindowImpl>();
  277. windowImpl.Setup(x => x.Compositor).Returns(RendererMocks.CreateDummyCompositor());
  278. windowImpl.SetupProperty(x => x.Closed);
  279. windowImpl.Setup(x => x.DesktopScaling).Returns(1);
  280. windowImpl.Setup(x => x.RenderScaling).Returns(1);
  281. parent.Show();
  282. var target = new Window(windowImpl.Object);
  283. var task = target.ShowDialog<bool>(parent);
  284. windowImpl.Object.Closed();
  285. var result = await task;
  286. Assert.False(result);
  287. }
  288. }
  289. [Fact]
  290. public void Calling_Show_On_Closed_Window_Should_Throw()
  291. {
  292. using (UnitTestApplication.Start(TestServices.StyledWindow))
  293. {
  294. var target = new Window();
  295. target.Show();
  296. target.Close();
  297. var openedRaised = false;
  298. target.Opened += (s, e) => openedRaised = true;
  299. var ex = Assert.Throws<InvalidOperationException>(() => target.Show());
  300. Assert.Equal("Cannot re-show a closed window.", ex.Message);
  301. Assert.False(openedRaised);
  302. }
  303. }
  304. [Fact]
  305. public async Task Calling_ShowDialog_On_Closed_Window_Should_Throw()
  306. {
  307. using (UnitTestApplication.Start(TestServices.StyledWindow))
  308. {
  309. var parent = new Window();
  310. var windowImpl = new Mock<IWindowImpl>();
  311. windowImpl.Setup(x => x.Compositor).Returns(RendererMocks.CreateDummyCompositor());
  312. windowImpl.SetupProperty(x => x.Closed);
  313. windowImpl.Setup(x => x.DesktopScaling).Returns(1);
  314. windowImpl.Setup(x => x.RenderScaling).Returns(1);
  315. parent.Show();
  316. var target = new Window(windowImpl.Object);
  317. var task = target.ShowDialog<bool>(parent);
  318. windowImpl.Object.Closed();
  319. await task;
  320. var openedRaised = false;
  321. target.Opened += (s, e) => openedRaised = true;
  322. var ex = await Assert.ThrowsAsync<InvalidOperationException>(() => target.ShowDialog<bool>(parent));
  323. Assert.Equal("Cannot re-show a closed window.", ex.Message);
  324. Assert.False(openedRaised);
  325. }
  326. }
  327. [Fact]
  328. public void Calling_Show_With_Closed_Parent_Window_Should_Throw()
  329. {
  330. using (UnitTestApplication.Start(TestServices.StyledWindow))
  331. {
  332. var parent = new Window();
  333. var target = new Window();
  334. parent.Close();
  335. var ex = Assert.Throws<InvalidOperationException>(() => target.Show(parent));
  336. Assert.Equal("Cannot show a window with a closed owner.", ex.Message);
  337. }
  338. }
  339. [Fact]
  340. public async Task Calling_ShowDialog_With_Closed_Parent_Window_Should_Throw()
  341. {
  342. using (UnitTestApplication.Start(TestServices.StyledWindow))
  343. {
  344. var parent = new Window();
  345. var target = new Window();
  346. parent.Close();
  347. var ex = await Assert.ThrowsAsync<InvalidOperationException>(() => target.ShowDialog(parent));
  348. Assert.Equal("Cannot show a window with a closed owner.", ex.Message);
  349. }
  350. }
  351. [Fact]
  352. public void Calling_Show_With_Invisible_Parent_Window_Should_Throw()
  353. {
  354. using (UnitTestApplication.Start(TestServices.StyledWindow))
  355. {
  356. var parent = new Window();
  357. var target = new Window();
  358. var ex = Assert.Throws<InvalidOperationException>(() => target.Show(parent));
  359. Assert.Equal("Cannot show window with non-visible owner.", ex.Message);
  360. }
  361. }
  362. [Fact]
  363. public async Task Calling_ShowDialog_With_Invisible_Parent_Window_Should_Throw()
  364. {
  365. using (UnitTestApplication.Start(TestServices.StyledWindow))
  366. {
  367. var parent = new Window();
  368. var target = new Window();
  369. var ex = await Assert.ThrowsAsync<InvalidOperationException>(() => target.ShowDialog(parent));
  370. Assert.Equal("Cannot show window with non-visible owner.", ex.Message);
  371. }
  372. }
  373. [Fact]
  374. public void Calling_Show_With_Self_As_Parent_Window_Should_Throw()
  375. {
  376. using (UnitTestApplication.Start(TestServices.StyledWindow))
  377. {
  378. var target = new Window();
  379. var ex = Assert.Throws<InvalidOperationException>(() => target.Show(target));
  380. Assert.Equal("A Window cannot be its own owner.", ex.Message);
  381. }
  382. }
  383. [Fact]
  384. public async Task Calling_ShowDialog_With_Self_As_Parent_Window_Should_Throw()
  385. {
  386. using (UnitTestApplication.Start(TestServices.StyledWindow))
  387. {
  388. var target = new Window();
  389. var ex = await Assert.ThrowsAsync<InvalidOperationException>(() => target.ShowDialog(target));
  390. Assert.Equal("A Window cannot be its own owner.", ex.Message);
  391. }
  392. }
  393. [Fact]
  394. public void Hiding_Parent_Window_Should_Close_Children()
  395. {
  396. using (UnitTestApplication.Start(TestServices.MockWindowingPlatform))
  397. {
  398. var parent = new Window();
  399. var child = new Window();
  400. parent.Show();
  401. child.Show(parent);
  402. parent.Hide();
  403. Assert.False(parent.IsVisible);
  404. Assert.False(child.IsVisible);
  405. }
  406. }
  407. [Fact]
  408. public void Hiding_Parent_Window_Should_Close_Dialog_Children()
  409. {
  410. using (UnitTestApplication.Start(TestServices.MockWindowingPlatform))
  411. {
  412. var parent = new Window();
  413. var child = new Window();
  414. parent.Show();
  415. child.ShowDialog(parent);
  416. parent.Hide();
  417. Assert.False(parent.IsVisible);
  418. Assert.False(child.IsVisible);
  419. }
  420. }
  421. [Fact]
  422. public void Window_Should_Not_Be_Centered_When_WindowStartupLocation_Is_CenterScreen_And_Window_Is_Hidden_And_Shown()
  423. {
  424. var screen1 = new Mock<Screen>(1.0, new PixelRect(new PixelSize(1920, 1080)), new PixelRect(new PixelSize(1920, 1040)), true);
  425. var screens = new Mock<IScreenImpl>();
  426. screens.Setup(x => x.AllScreens).Returns(new Screen[] { screen1.Object });
  427. screens.Setup(x => x.ScreenFromPoint(It.IsAny<PixelPoint>())).Returns(screen1.Object);
  428. var windowImpl = MockWindowingPlatform.CreateWindowMock();
  429. windowImpl.Setup(x => x.ClientSize).Returns(new Size(800, 480));
  430. windowImpl.Setup(x => x.DesktopScaling).Returns(1);
  431. windowImpl.Setup(x => x.RenderScaling).Returns(1);
  432. windowImpl.Setup(x => x.TryGetFeature(It.Is<Type>(t => t == typeof(IScreenImpl)))).Returns(screens.Object);
  433. using (UnitTestApplication.Start(TestServices.StyledWindow))
  434. {
  435. var window = new Window(windowImpl.Object)
  436. {
  437. WindowStartupLocation = WindowStartupLocation.CenterScreen
  438. };
  439. window.Show();
  440. var expected = new PixelPoint(150, 400);
  441. window.Position = expected;
  442. window.IsVisible = false;
  443. window.IsVisible = true;
  444. Assert.Equal(expected, window.Position);
  445. }
  446. }
  447. [Fact]
  448. public void Window_Should_Be_Centered_When_WindowStartupLocation_Is_CenterScreen()
  449. {
  450. var screen1 = new Mock<Screen>(1.0, new PixelRect(new PixelSize(1920, 1080)), new PixelRect(new PixelSize(1920, 1040)), true);
  451. var screen2 = new Mock<Screen>(1.0, new PixelRect(new PixelSize(1366, 768)), new PixelRect(new PixelSize(1366, 728)), false);
  452. var screens = new Mock<IScreenImpl>();
  453. screens.Setup(x => x.AllScreens).Returns(new Screen[] { screen1.Object, screen2.Object });
  454. screens.Setup(x => x.ScreenFromPoint(It.IsAny<PixelPoint>())).Returns(screen1.Object);
  455. var windowImpl = MockWindowingPlatform.CreateWindowMock();
  456. windowImpl.Setup(x => x.ClientSize).Returns(new Size(800, 480));
  457. windowImpl.Setup(x => x.DesktopScaling).Returns(1);
  458. windowImpl.Setup(x => x.RenderScaling).Returns(1);
  459. windowImpl.Setup(x => x.TryGetFeature(It.Is<Type>(t => t == typeof(IScreenImpl)))).Returns(screens.Object);
  460. using (UnitTestApplication.Start(TestServices.StyledWindow))
  461. {
  462. var window = new Window(windowImpl.Object);
  463. window.WindowStartupLocation = WindowStartupLocation.CenterScreen;
  464. window.Position = new PixelPoint(60, 40);
  465. window.Show();
  466. var expectedPosition = new PixelPoint(
  467. (int)(screen1.Object.WorkingArea.Size.Width / 2 - window.ClientSize.Width / 2),
  468. (int)(screen1.Object.WorkingArea.Size.Height / 2 - window.ClientSize.Height / 2));
  469. Assert.Equal(window.Position, expectedPosition);
  470. }
  471. }
  472. [Fact]
  473. public void Window_Should_Be_Sized_To_MinSize_If_InitialSize_Less_Than_MinSize()
  474. {
  475. var screen1 = new Mock<Screen>(1.75, new PixelRect(new PixelSize(1920, 1080)), new PixelRect(new PixelSize(1920, 966)), true);
  476. var screens = new Mock<IScreenImpl>();
  477. screens.Setup(x => x.AllScreens).Returns(new Screen[] { screen1.Object });
  478. screens.Setup(x => x.ScreenFromPoint(It.IsAny<PixelPoint>())).Returns(screen1.Object);
  479. var windowImpl = MockWindowingPlatform.CreateWindowMock(400, 300);
  480. windowImpl.Setup(x => x.DesktopScaling).Returns(1.75);
  481. windowImpl.Setup(x => x.RenderScaling).Returns(1.75);
  482. windowImpl.Setup(x => x.TryGetFeature(It.Is<Type>(t => t == typeof(IScreenImpl)))).Returns(screens.Object);
  483. using (UnitTestApplication.Start(TestServices.StyledWindow))
  484. {
  485. var window = new Window(windowImpl.Object);
  486. window.WindowStartupLocation = WindowStartupLocation.CenterScreen;
  487. window.MinWidth = 720;
  488. window.MinHeight = 480;
  489. window.Show();
  490. Assert.Equal(new PixelPoint(330, 63), window.Position);
  491. Assert.Equal(new Size(720, 480), window.Bounds.Size);
  492. }
  493. }
  494. [Fact]
  495. public void Window_Should_Be_Centered_Relative_To_Owner_When_WindowStartupLocation_Is_CenterOwner()
  496. {
  497. var parentWindowImpl = MockWindowingPlatform.CreateWindowMock();
  498. parentWindowImpl.Setup(x => x.ClientSize).Returns(new Size(800, 480));
  499. parentWindowImpl.Setup(x => x.MaxAutoSizeHint).Returns(new Size(1920, 1080));
  500. parentWindowImpl.Setup(x => x.DesktopScaling).Returns(1);
  501. parentWindowImpl.Setup(x => x.RenderScaling).Returns(1);
  502. var windowImpl = MockWindowingPlatform.CreateWindowMock();
  503. windowImpl.Setup(x => x.ClientSize).Returns(new Size(320, 200));
  504. windowImpl.Setup(x => x.MaxAutoSizeHint).Returns(new Size(1920, 1080));
  505. windowImpl.Setup(x => x.DesktopScaling).Returns(1);
  506. windowImpl.Setup(x => x.RenderScaling).Returns(1);
  507. var parentWindowServices = TestServices.StyledWindow.With(
  508. windowingPlatform: new MockWindowingPlatform(() => parentWindowImpl.Object));
  509. var windowServices = TestServices.StyledWindow.With(
  510. windowingPlatform: new MockWindowingPlatform(() => windowImpl.Object));
  511. using (UnitTestApplication.Start(parentWindowServices))
  512. {
  513. var parentWindow = new Window();
  514. parentWindow.Position = new PixelPoint(60, 40);
  515. parentWindow.Show();
  516. using (UnitTestApplication.Start(windowServices))
  517. {
  518. var window = new Window();
  519. window.WindowStartupLocation = WindowStartupLocation.CenterOwner;
  520. window.Position = new PixelPoint(60, 40);
  521. window.ShowDialog(parentWindow);
  522. var expectedPosition = new PixelPoint(
  523. (int)(parentWindow.Position.X + parentWindow.ClientSize.Width / 2 - window.ClientSize.Width / 2),
  524. (int)(parentWindow.Position.Y + parentWindow.ClientSize.Height / 2 - window.ClientSize.Height / 2));
  525. Assert.Equal(window.Position, expectedPosition);
  526. }
  527. }
  528. }
  529. [Fact]
  530. public void Window_Topmost_By_Default_Should_Configure_PlatformImpl_When_Constructed()
  531. {
  532. var windowImpl = MockWindowingPlatform.CreateWindowMock();
  533. var windowServices = TestServices.StyledWindow.With(
  534. windowingPlatform: new MockWindowingPlatform(() => windowImpl.Object));
  535. using (UnitTestApplication.Start(windowServices))
  536. {
  537. var window = new TopmostWindow();
  538. Assert.True(window.Topmost);
  539. windowImpl.Verify(i => i.SetTopmost(true));
  540. }
  541. }
  542. public class SizingTests
  543. {
  544. [Fact]
  545. public void Child_Should_Be_Measured_With_Width_And_Height_If_SizeToContent_Is_Manual()
  546. {
  547. using (UnitTestApplication.Start(TestServices.StyledWindow))
  548. {
  549. var child = new ChildControl();
  550. var target = new Window
  551. {
  552. Width = 100,
  553. Height = 50,
  554. SizeToContent = SizeToContent.Manual,
  555. Content = child
  556. };
  557. Show(target);
  558. Assert.Equal(1, child.MeasureSizes.Count);
  559. Assert.Equal(new Size(100, 50), child.MeasureSizes[0]);
  560. }
  561. }
  562. [Fact]
  563. public void Child_Should_Be_Measured_With_ClientSize_If_SizeToContent_Is_Manual_And_No_Width_Height_Specified()
  564. {
  565. using (UnitTestApplication.Start(TestServices.StyledWindow))
  566. {
  567. var windowImpl = MockWindowingPlatform.CreateWindowMock();
  568. windowImpl.Setup(x => x.ClientSize).Returns(new Size(550, 450));
  569. var child = new ChildControl();
  570. var target = new Window(windowImpl.Object)
  571. {
  572. SizeToContent = SizeToContent.Manual,
  573. Content = child
  574. };
  575. Show(target);
  576. Assert.Equal(1, child.MeasureSizes.Count);
  577. Assert.Equal(new Size(550, 450), child.MeasureSizes[0]);
  578. }
  579. }
  580. [Fact]
  581. public void Child_Should_Be_Measured_With_MaxAutoSizeHint_If_SizeToContent_Is_WidthAndHeight()
  582. {
  583. using (UnitTestApplication.Start(TestServices.StyledWindow))
  584. {
  585. var windowImpl = MockWindowingPlatform.CreateWindowMock();
  586. windowImpl.Setup(x => x.MaxAutoSizeHint).Returns(new Size(1200, 1000));
  587. var child = new ChildControl();
  588. var target = new Window(windowImpl.Object)
  589. {
  590. Width = 100,
  591. Height = 50,
  592. SizeToContent = SizeToContent.WidthAndHeight,
  593. Content = child
  594. };
  595. target.Show();
  596. Assert.Equal(1, child.MeasureSizes.Count);
  597. Assert.Equal(new Size(1200, 1000), child.MeasureSizes[0]);
  598. }
  599. }
  600. [Fact]
  601. public void Should_Not_Have_Offset_On_Bounds_When_Content_Larger_Than_Max_Window_Size()
  602. {
  603. // Issue #3784.
  604. using (UnitTestApplication.Start(TestServices.StyledWindow))
  605. {
  606. var windowImpl = MockWindowingPlatform.CreateWindowMock();
  607. var clientSize = new Size(200, 200);
  608. var maxClientSize = new Size(480, 480);
  609. windowImpl.Setup(x => x.Resize(It.IsAny<Size>(), It.IsAny<WindowResizeReason>()))
  610. .Callback<Size, WindowResizeReason>((size, reason) =>
  611. {
  612. clientSize = size.Constrain(maxClientSize);
  613. windowImpl.Object.Resized?.Invoke(clientSize, reason);
  614. });
  615. windowImpl.Setup(x => x.ClientSize).Returns(() => clientSize);
  616. var child = new Canvas
  617. {
  618. Width = 400,
  619. Height = 800,
  620. };
  621. var target = new Window(windowImpl.Object)
  622. {
  623. SizeToContent = SizeToContent.WidthAndHeight,
  624. Content = child
  625. };
  626. Show(target);
  627. Assert.Equal(new Size(400, 480), target.Bounds.Size);
  628. // Issue #3784 causes this to be (0, 160) which makes no sense as Window has no
  629. // parent control to be offset against.
  630. Assert.Equal(new Point(0, 0), target.Bounds.Position);
  631. }
  632. }
  633. [Fact]
  634. public void Width_Height_Should_Not_Be_NaN_After_Show_With_SizeToContent_Manual()
  635. {
  636. using (UnitTestApplication.Start(TestServices.StyledWindow))
  637. {
  638. var child = new Canvas
  639. {
  640. Width = 400,
  641. Height = 800,
  642. };
  643. var target = new Window()
  644. {
  645. SizeToContent = SizeToContent.Manual,
  646. Content = child
  647. };
  648. Show(target);
  649. // Values come from MockWindowingPlatform defaults.
  650. Assert.Equal(800, target.Width);
  651. Assert.Equal(600, target.Height);
  652. }
  653. }
  654. [Fact]
  655. public void Width_Height_Should_Not_Be_NaN_After_Show_With_SizeToContent_WidthAndHeight()
  656. {
  657. using (UnitTestApplication.Start(TestServices.StyledWindow))
  658. {
  659. var child = new Canvas
  660. {
  661. Width = 400,
  662. Height = 800,
  663. };
  664. var target = new Window()
  665. {
  666. SizeToContent = SizeToContent.WidthAndHeight,
  667. Content = child
  668. };
  669. target.GetObservable(Window.WidthProperty).Subscribe(x => { });
  670. Show(target);
  671. Assert.Equal(400, target.Width);
  672. Assert.Equal(800, target.Height);
  673. }
  674. }
  675. [Fact]
  676. public void MaxWidth_And_MaxHeight_Should_Be_Respected_With_SizeToContent_WidthAndHeight()
  677. {
  678. using (UnitTestApplication.Start(TestServices.StyledWindow))
  679. {
  680. var child = new ChildControl();
  681. var target = new Window()
  682. {
  683. SizeToContent = SizeToContent.WidthAndHeight,
  684. MaxWidth = 300,
  685. MaxHeight = 700,
  686. Content = child,
  687. };
  688. Show(target);
  689. Assert.Equal(new[] { new Size(300, 700) }, child.MeasureSizes);
  690. }
  691. }
  692. [Fact]
  693. public void SizeToContent_Should_Not_Be_Lost_On_Show()
  694. {
  695. using (UnitTestApplication.Start(TestServices.StyledWindow))
  696. {
  697. var child = new Canvas
  698. {
  699. Width = 400,
  700. Height = 800,
  701. };
  702. var target = new Window()
  703. {
  704. SizeToContent = SizeToContent.WidthAndHeight,
  705. Content = child
  706. };
  707. Show(target);
  708. Assert.Equal(SizeToContent.WidthAndHeight, target.SizeToContent);
  709. }
  710. }
  711. [Fact]
  712. public void SizeToContent_Should_Not_Be_Lost_On_Scaling_Change()
  713. {
  714. using (UnitTestApplication.Start(TestServices.StyledWindow))
  715. {
  716. var child = new Canvas
  717. {
  718. Width = 209,
  719. Height = 117,
  720. };
  721. var target = new Window()
  722. {
  723. SizeToContent = SizeToContent.WidthAndHeight,
  724. Content = child
  725. };
  726. Show(target);
  727. // Size before and after DPI change is a real-world example, with size after DPI
  728. // change coming from Win32 WM_DPICHANGED.
  729. target.PlatformImpl.ScalingChanged(1.5);
  730. target.PlatformImpl.Resized(
  731. new Size(210.66666666666666, 118.66666666666667),
  732. WindowResizeReason.DpiChange);
  733. Assert.Equal(SizeToContent.WidthAndHeight, target.SizeToContent);
  734. }
  735. }
  736. [Fact]
  737. public void Width_Height_Should_Be_Updated_When_SizeToContent_Is_WidthAndHeight()
  738. {
  739. using (UnitTestApplication.Start(TestServices.StyledWindow))
  740. {
  741. var child = new Canvas
  742. {
  743. Width = 400,
  744. Height = 800,
  745. };
  746. var target = new Window()
  747. {
  748. SizeToContent = SizeToContent.WidthAndHeight,
  749. Content = child
  750. };
  751. Show(target);
  752. Assert.Equal(400, target.Width);
  753. Assert.Equal(800, target.Height);
  754. child.Width = 410;
  755. target.LayoutManager.ExecuteLayoutPass();
  756. Assert.Equal(410, target.Width);
  757. Assert.Equal(800, target.Height);
  758. Assert.Equal(SizeToContent.WidthAndHeight, target.SizeToContent);
  759. }
  760. }
  761. [Fact]
  762. public void Setting_Width_Should_Resize_WindowImpl()
  763. {
  764. // Issue #3796
  765. using (UnitTestApplication.Start(TestServices.StyledWindow))
  766. {
  767. var target = new Window()
  768. {
  769. Width = 400,
  770. Height = 800,
  771. };
  772. Show(target);
  773. Assert.Equal(400, target.Width);
  774. Assert.Equal(800, target.Height);
  775. target.Width = 410;
  776. target.LayoutManager.ExecuteLayoutPass();
  777. var windowImpl = Mock.Get(target.PlatformImpl);
  778. windowImpl.Verify(x => x.Resize(new Size(410, 800), WindowResizeReason.Application));
  779. Assert.Equal(410, target.Width);
  780. }
  781. }
  782. [Fact]
  783. public void User_Resize_Of_Window_Width_Should_Reset_SizeToContent()
  784. {
  785. using (UnitTestApplication.Start(TestServices.StyledWindow))
  786. {
  787. var target = new Window()
  788. {
  789. SizeToContent = SizeToContent.WidthAndHeight,
  790. Content = new Canvas
  791. {
  792. Width = 400,
  793. Height = 800,
  794. },
  795. };
  796. Show(target);
  797. Assert.Equal(400, target.Width);
  798. Assert.Equal(800, target.Height);
  799. target.PlatformImpl.Resized(new Size(410, 800), WindowResizeReason.User);
  800. Assert.Equal(410, target.Width);
  801. Assert.Equal(800, target.Height);
  802. Assert.Equal(SizeToContent.Height, target.SizeToContent);
  803. }
  804. }
  805. [Fact]
  806. public void User_Resize_Of_Window_Height_Should_Reset_SizeToContent()
  807. {
  808. using (UnitTestApplication.Start(TestServices.StyledWindow))
  809. {
  810. var target = new Window()
  811. {
  812. SizeToContent = SizeToContent.WidthAndHeight,
  813. Content = new Canvas
  814. {
  815. Width = 400,
  816. Height = 800,
  817. },
  818. };
  819. Show(target);
  820. Assert.Equal(400, target.Width);
  821. Assert.Equal(800, target.Height);
  822. target.PlatformImpl.Resized(new Size(400, 810), WindowResizeReason.User);
  823. Assert.Equal(400, target.Width);
  824. Assert.Equal(810, target.Height);
  825. Assert.Equal(SizeToContent.Width, target.SizeToContent);
  826. }
  827. }
  828. [Fact]
  829. public void Window_Resize_Should_Not_Reset_SizeToContent_If_CanResize_False()
  830. {
  831. using (UnitTestApplication.Start(TestServices.StyledWindow))
  832. {
  833. var target = new Window()
  834. {
  835. SizeToContent = SizeToContent.WidthAndHeight,
  836. CanResize = false,
  837. Content = new Canvas
  838. {
  839. Width = 400,
  840. Height = 800,
  841. },
  842. };
  843. Show(target);
  844. Assert.Equal(400, target.Width);
  845. Assert.Equal(800, target.Height);
  846. target.PlatformImpl.Resized(new Size(410, 810), WindowResizeReason.Unspecified);
  847. Assert.Equal(400, target.Width);
  848. Assert.Equal(800, target.Height);
  849. Assert.Equal(SizeToContent.WidthAndHeight, target.SizeToContent);
  850. }
  851. }
  852. [Fact]
  853. public void IsVisible_Should_Open_Window()
  854. {
  855. using (UnitTestApplication.Start(TestServices.StyledWindow))
  856. {
  857. var target = new Window();
  858. var raised = false;
  859. target.Opened += (s, e) => raised = true;
  860. target.IsVisible = true;
  861. Assert.True(raised);
  862. }
  863. }
  864. [Fact]
  865. public void IsVisible_Should_Close_DialogWindow()
  866. {
  867. using (UnitTestApplication.Start(TestServices.StyledWindow))
  868. {
  869. var parent = new Window();
  870. parent.Show();
  871. var target = new Window();
  872. var raised = false;
  873. var task = target.ShowDialog<bool>(parent);
  874. target.Closed += (sender, args) => raised = true;
  875. target.IsVisible = false;
  876. Assert.True(raised);
  877. Assert.False(task.Result);
  878. }
  879. }
  880. protected virtual void Show(Window window)
  881. {
  882. window.Show();
  883. }
  884. }
  885. public class DialogSizingTests : SizingTests
  886. {
  887. protected override void Show(Window window)
  888. {
  889. var owner = new Window();
  890. owner.Show();
  891. window.ShowDialog(owner);
  892. }
  893. }
  894. private static IWindowImpl CreateImpl()
  895. {
  896. var compositor = RendererMocks.CreateDummyCompositor();
  897. return Mock.Of<IWindowImpl>(x => x.RenderScaling == 1 &&
  898. x.Compositor == compositor);
  899. }
  900. private class ChildControl : Control
  901. {
  902. public List<Size> MeasureSizes { get; } = new List<Size>();
  903. protected override Size MeasureOverride(Size availableSize)
  904. {
  905. MeasureSizes.Add(availableSize);
  906. return base.MeasureOverride(availableSize);
  907. }
  908. }
  909. private class TopmostWindow : Window
  910. {
  911. static TopmostWindow()
  912. {
  913. TopmostProperty.OverrideDefaultValue<TopmostWindow>(true);
  914. }
  915. }
  916. }
  917. }