DesktopStyleApplicationLifetimeTests.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413
  1. using System;
  2. using System.Collections.Generic;
  3. using Avalonia.Controls.ApplicationLifetimes;
  4. using Avalonia.Platform;
  5. using Avalonia.Rendering;
  6. using Avalonia.Threading;
  7. using Avalonia.UnitTests;
  8. using Moq;
  9. using Xunit;
  10. namespace Avalonia.Controls.UnitTests
  11. {
  12. public class DesktopStyleApplicationLifetimeTests
  13. {
  14. IDispatcherImpl CreateDispatcherWithInstantMainLoop() => Mock.Of<IControlledDispatcherImpl>(x => x.CurrentThreadIsLoopThread == true);
  15. [Fact]
  16. public void Should_Set_ExitCode_After_Shutdown()
  17. {
  18. using (UnitTestApplication.Start(new TestServices(dispatcherImpl: CreateDispatcherWithInstantMainLoop())))
  19. using(var lifetime = new ClassicDesktopStyleApplicationLifetime())
  20. {
  21. lifetime.Shutdown(1337);
  22. var exitCode = lifetime.Start(Array.Empty<string>());
  23. Assert.Equal(1337, exitCode);
  24. }
  25. }
  26. [Fact]
  27. public void Should_Close_All_Remaining_Open_Windows_After_Explicit_Exit_Call()
  28. {
  29. using (UnitTestApplication.Start(TestServices.StyledWindow))
  30. using(var lifetime = new ClassicDesktopStyleApplicationLifetime())
  31. {
  32. var windows = new List<Window> { new Window(), new Window(), new Window(), new Window() };
  33. foreach (var window in windows)
  34. {
  35. window.Show();
  36. }
  37. Assert.Equal(4, lifetime.Windows.Count);
  38. lifetime.Shutdown();
  39. Assert.Empty(lifetime.Windows);
  40. }
  41. }
  42. [Fact]
  43. public void Should_Only_Exit_On_Explicit_Exit()
  44. {
  45. using (UnitTestApplication.Start(TestServices.StyledWindow))
  46. using(var lifetime = new ClassicDesktopStyleApplicationLifetime())
  47. {
  48. lifetime.ShutdownMode = ShutdownMode.OnExplicitShutdown;
  49. var hasExit = false;
  50. lifetime.Exit += (_, _) => hasExit = true;
  51. var windowA = new Window();
  52. windowA.Show();
  53. var windowB = new Window();
  54. windowB.Show();
  55. windowA.Close();
  56. Assert.False(hasExit);
  57. windowB.Close();
  58. Assert.False(hasExit);
  59. lifetime.Shutdown();
  60. Assert.True(hasExit);
  61. }
  62. }
  63. [Fact]
  64. public void Should_Exit_After_MainWindow_Closed()
  65. {
  66. using (UnitTestApplication.Start(TestServices.StyledWindow))
  67. using(var lifetime = new ClassicDesktopStyleApplicationLifetime())
  68. {
  69. lifetime.ShutdownMode = ShutdownMode.OnMainWindowClose;
  70. var hasExit = false;
  71. lifetime.Exit += (_, _) => hasExit = true;
  72. var mainWindow = new Window();
  73. mainWindow.Show();
  74. lifetime.MainWindow = mainWindow;
  75. var window = new Window();
  76. window.Show();
  77. mainWindow.Close();
  78. Assert.True(hasExit);
  79. }
  80. }
  81. [Fact]
  82. public void Should_Exit_After_Last_Window_Closed()
  83. {
  84. using (UnitTestApplication.Start(TestServices.StyledWindow))
  85. using(var lifetime = new ClassicDesktopStyleApplicationLifetime())
  86. {
  87. lifetime.ShutdownMode = ShutdownMode.OnLastWindowClose;
  88. var hasExit = false;
  89. lifetime.Exit += (_, _) => hasExit = true;
  90. var windowA = new Window();
  91. windowA.Show();
  92. var windowB = new Window();
  93. windowB.Show();
  94. windowA.Close();
  95. Assert.False(hasExit);
  96. windowB.Close();
  97. Assert.True(hasExit);
  98. }
  99. }
  100. [Fact]
  101. public void Show_Should_Add_Window_To_OpenWindows()
  102. {
  103. using (UnitTestApplication.Start(TestServices.StyledWindow))
  104. using(var lifetime = new ClassicDesktopStyleApplicationLifetime())
  105. {
  106. var window = new Window();
  107. window.Show();
  108. Assert.Equal(new[] { window }, lifetime.Windows);
  109. }
  110. }
  111. [Fact]
  112. public void Window_Should_Be_Added_To_OpenWindows_Only_Once()
  113. {
  114. using (UnitTestApplication.Start(TestServices.StyledWindow))
  115. using(var lifetime = new ClassicDesktopStyleApplicationLifetime())
  116. {
  117. var window = new Window();
  118. window.Show();
  119. window.Show();
  120. window.IsVisible = true;
  121. Assert.Equal(new[] { window }, lifetime.Windows);
  122. window.Close();
  123. }
  124. }
  125. [Fact]
  126. public void Close_Should_Remove_Window_From_OpenWindows()
  127. {
  128. using (UnitTestApplication.Start(TestServices.StyledWindow))
  129. using(var lifetime = new ClassicDesktopStyleApplicationLifetime())
  130. {
  131. var window = new Window();
  132. window.Show();
  133. Assert.Equal(1, lifetime.Windows.Count);
  134. window.Close();
  135. Assert.Empty(lifetime.Windows);
  136. }
  137. }
  138. [Fact]
  139. public void Impl_Closing_Should_Remove_Window_From_OpenWindows()
  140. {
  141. var windowImpl = new Mock<IWindowImpl>();
  142. windowImpl.Setup(x => x.CreateRenderer(It.IsAny<IRenderRoot>()))
  143. .Returns(() => RendererMocks.CreateRenderer().Object);
  144. windowImpl.SetupProperty(x => x.Closed);
  145. windowImpl.Setup(x => x.DesktopScaling).Returns(1);
  146. windowImpl.Setup(x => x.RenderScaling).Returns(1);
  147. var services = TestServices.StyledWindow.With(
  148. windowingPlatform: new MockWindowingPlatform(() => windowImpl.Object));
  149. using (UnitTestApplication.Start(services))
  150. using(var lifetime = new ClassicDesktopStyleApplicationLifetime())
  151. {
  152. var window = new Window();
  153. window.Show();
  154. Assert.Equal(1, lifetime.Windows.Count);
  155. windowImpl.Object.Closed();
  156. Assert.Empty(lifetime.Windows);
  157. }
  158. }
  159. [Fact]
  160. public void Should_Allow_Canceling_Shutdown_Via_ShutdownRequested_Event()
  161. {
  162. using (UnitTestApplication.Start(TestServices.StyledWindow.With(dispatcherImpl: CreateDispatcherWithInstantMainLoop())))
  163. using (var lifetime = new ClassicDesktopStyleApplicationLifetime())
  164. {
  165. var lifetimeEvents = new Mock<IPlatformLifetimeEventsImpl>();
  166. AvaloniaLocator.CurrentMutable.Bind<IPlatformLifetimeEventsImpl>().ToConstant(lifetimeEvents.Object);
  167. lifetime.Start(Array.Empty<string>());
  168. var window = new Window();
  169. var raised = 0;
  170. window.Show();
  171. lifetime.ShutdownRequested += (_, e) =>
  172. {
  173. e.Cancel = true;
  174. ++raised;
  175. };
  176. lifetimeEvents.Raise(x => x.ShutdownRequested += null, new ShutdownRequestedEventArgs());
  177. Assert.Equal(1, raised);
  178. Assert.Equal(new[] { window }, lifetime.Windows);
  179. }
  180. }
  181. [Fact]
  182. public void MainWindow_Closed_Shutdown_Should_Be_Cancellable()
  183. {
  184. using (UnitTestApplication.Start(TestServices.StyledWindow))
  185. using(var lifetime = new ClassicDesktopStyleApplicationLifetime())
  186. {
  187. lifetime.ShutdownMode = ShutdownMode.OnMainWindowClose;
  188. var hasExit = false;
  189. lifetime.Exit += (_, _) => hasExit = true;
  190. var mainWindow = new Window();
  191. mainWindow.Show();
  192. lifetime.MainWindow = mainWindow;
  193. var window = new Window();
  194. window.Show();
  195. var raised = 0;
  196. lifetime.ShutdownRequested += (_, e) =>
  197. {
  198. e.Cancel = true;
  199. ++raised;
  200. };
  201. mainWindow.Close();
  202. Assert.Equal(1, raised);
  203. Assert.False(hasExit);
  204. }
  205. }
  206. [Fact]
  207. public void LastWindow_Closed_Shutdown_Should_Be_Cancellable()
  208. {
  209. using (UnitTestApplication.Start(TestServices.StyledWindow))
  210. using(var lifetime = new ClassicDesktopStyleApplicationLifetime())
  211. {
  212. lifetime.ShutdownMode = ShutdownMode.OnLastWindowClose;
  213. var hasExit = false;
  214. lifetime.Exit += (_, _) => hasExit = true;
  215. var windowA = new Window();
  216. windowA.Show();
  217. var windowB = new Window();
  218. windowB.Show();
  219. var raised = 0;
  220. lifetime.ShutdownRequested += (_, e) =>
  221. {
  222. e.Cancel = true;
  223. ++raised;
  224. };
  225. windowA.Close();
  226. Assert.False(hasExit);
  227. windowB.Close();
  228. Assert.Equal(1, raised);
  229. Assert.False(hasExit);
  230. }
  231. }
  232. [Fact]
  233. public void TryShutdown_Cancellable_By_Preventing_Window_Close()
  234. {
  235. using (UnitTestApplication.Start(TestServices.StyledWindow))
  236. using(var lifetime = new ClassicDesktopStyleApplicationLifetime())
  237. {
  238. var hasExit = false;
  239. lifetime.Exit += (_, _) => hasExit = true;
  240. var windowA = new Window();
  241. windowA.Show();
  242. var windowB = new Window();
  243. windowB.Show();
  244. var raised = 0;
  245. windowA.Closing += (_, e) =>
  246. {
  247. e.Cancel = true;
  248. ++raised;
  249. };
  250. lifetime.TryShutdown();
  251. Assert.Equal(1, raised);
  252. Assert.False(hasExit);
  253. }
  254. }
  255. [Fact]
  256. public void Shutdown_NotCancellable_By_Preventing_Window_Close()
  257. {
  258. using (UnitTestApplication.Start(TestServices.StyledWindow))
  259. using(var lifetime = new ClassicDesktopStyleApplicationLifetime())
  260. {
  261. var hasExit = false;
  262. lifetime.Exit += (_, _) => hasExit = true;
  263. var windowA = new Window();
  264. windowA.Show();
  265. var windowB = new Window();
  266. windowB.Show();
  267. var raised = 0;
  268. windowA.Closing += (_, e) =>
  269. {
  270. e.Cancel = true;
  271. ++raised;
  272. };
  273. lifetime.Shutdown();
  274. Assert.Equal(1, raised);
  275. Assert.True(hasExit);
  276. }
  277. }
  278. [Fact]
  279. public void Shutdown_Doesnt_Raise_Shutdown_Requested()
  280. {
  281. using (UnitTestApplication.Start(TestServices.StyledWindow))
  282. using(var lifetime = new ClassicDesktopStyleApplicationLifetime())
  283. {
  284. var hasExit = false;
  285. lifetime.Exit += (_, _) => hasExit = true;
  286. var raised = 0;
  287. lifetime.ShutdownRequested += (_, _) =>
  288. {
  289. ++raised;
  290. };
  291. lifetime.Shutdown();
  292. Assert.Equal(0, raised);
  293. Assert.True(hasExit);
  294. }
  295. }
  296. }
  297. }