ScreenManagerTests.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Reflection;
  4. using Microsoft.Xna.Framework;
  5. using MonoGame.Extended.Screens;
  6. namespace MonoGame.Extended.Tests.Screens;
  7. [Collection("GraphicsTest")]
  8. public sealed class ScreenManagerTests
  9. {
  10. #region ShowScreen Tests
  11. [Fact]
  12. public void ShowScreen_FirstScreen_BecomesActive()
  13. {
  14. ScreenManager manager = new ScreenManager();
  15. TestScreen screen = new TestScreen("Screen1");
  16. manager.ShowScreen(screen);
  17. Assert.Equal(screen, manager.ActiveScreen);
  18. Assert.True(screen.IsActive);
  19. Assert.Single(manager.Screens);
  20. }
  21. [Fact]
  22. public void ShowScreen_SecondScreen_DeactivatesFirstAndBecomesActive()
  23. {
  24. ScreenManager manager = new ScreenManager();
  25. TestScreen screen1 = new TestScreen("Screen1");
  26. TestScreen screen2 = new TestScreen("Screen2");
  27. manager.ShowScreen(screen1);
  28. manager.ShowScreen(screen2);
  29. Assert.Equal(screen2, manager.ActiveScreen);
  30. Assert.True(screen2.IsActive);
  31. Assert.False(screen1.IsActive);
  32. Assert.Equal(2, manager.Screens.Count);
  33. }
  34. [Fact]
  35. public void ShowScreen_SetsScreenManagerProperty()
  36. {
  37. ScreenManager manager = new ScreenManager();
  38. TestScreen screen = new TestScreen("Screen1");
  39. manager.ShowScreen(screen);
  40. Assert.Equal(manager, screen.ScreenManager);
  41. }
  42. [Fact]
  43. public void ShowScreen_WithNull_ThrowsArgumentNullException()
  44. {
  45. ScreenManager manager = new ScreenManager();
  46. Assert.Throws<ArgumentNullException>(() => manager.ShowScreen(null));
  47. }
  48. #endregion
  49. #region CloseScreen Tests
  50. [Fact]
  51. public void CloseScreen_RemovesActiveAndActivatesPrevious()
  52. {
  53. ScreenManager manager = new ScreenManager();
  54. TestScreen screen1 = new TestScreen("Screen1");
  55. TestScreen screen2 = new TestScreen("Screen2");
  56. manager.ShowScreen(screen1);
  57. manager.ShowScreen(screen2);
  58. manager.CloseScreen();
  59. Assert.Equal(screen1, manager.ActiveScreen);
  60. Assert.True(screen1.IsActive);
  61. Assert.True(screen2.DisposeCalled);
  62. Assert.Single(manager.Screens);
  63. }
  64. [Fact]
  65. public void CloseScreen_OnLastScreen_LeavesEmptyStack()
  66. {
  67. ScreenManager manager = new ScreenManager();
  68. TestScreen screen = new TestScreen("Screen1");
  69. manager.ShowScreen(screen);
  70. manager.CloseScreen();
  71. Assert.Null(manager.ActiveScreen);
  72. Assert.Empty(manager.Screens);
  73. Assert.True(screen.DisposeCalled);
  74. }
  75. [Fact]
  76. public void CloseScreen_OnEmptyStack_DoesNotThrow()
  77. {
  78. ScreenManager manager = new ScreenManager();
  79. manager.CloseScreen();
  80. Assert.Null(manager.ActiveScreen);
  81. Assert.Empty(manager.Screens);
  82. }
  83. #endregion
  84. #region ReplaceScreen Tests
  85. [Fact]
  86. public void ReplaceScreen_ClosesActiveAndShowsNew()
  87. {
  88. ScreenManager manager = new ScreenManager();
  89. TestScreen screen1 = new TestScreen("Screen1");
  90. TestScreen screen2 = new TestScreen("Screen2");
  91. manager.ShowScreen(screen1);
  92. manager.ReplaceScreen(screen2);
  93. Assert.Equal(screen2, manager.ActiveScreen);
  94. Assert.True(screen2.IsActive);
  95. Assert.True(screen1.DisposeCalled);
  96. Assert.Single(manager.Screens);
  97. }
  98. [Fact]
  99. public void ReplaceScreen_OnEmptyStack_JustShowsScreen()
  100. {
  101. ScreenManager manager = new ScreenManager();
  102. TestScreen screen = new TestScreen("Screen1");
  103. manager.ReplaceScreen(screen);
  104. Assert.Equal(screen, manager.ActiveScreen);
  105. Assert.Single(manager.Screens);
  106. }
  107. [Fact]
  108. public void ReplaceScreen_WithNull_ThrowsArgumentNullException()
  109. {
  110. ScreenManager manager = new ScreenManager();
  111. Assert.Throws<ArgumentNullException>(() => manager.ReplaceScreen(null));
  112. }
  113. #endregion
  114. #region ClearScreens Tests
  115. [Fact]
  116. public void ClearScreens_DisposesAllScreensAndClearsStack()
  117. {
  118. ScreenManager manager = new ScreenManager();
  119. TestScreen screen1 = new TestScreen("Screen1");
  120. TestScreen screen2 = new TestScreen("Screen2");
  121. TestScreen screen3 = new TestScreen("Screen3");
  122. manager.ShowScreen(screen1);
  123. manager.ShowScreen(screen2);
  124. manager.ShowScreen(screen3);
  125. manager.ClearScreens();
  126. Assert.Null(manager.ActiveScreen);
  127. Assert.Empty(manager.Screens);
  128. Assert.True(screen1.DisposeCalled);
  129. Assert.True(screen2.DisposeCalled);
  130. Assert.True(screen3.DisposeCalled);
  131. }
  132. [Fact]
  133. public void ClearScreens_OnEmptyStack_DoesNotThrow()
  134. {
  135. ScreenManager manager = new ScreenManager();
  136. manager.ClearScreens();
  137. Assert.Null(manager.ActiveScreen);
  138. }
  139. #endregion
  140. #region Update Tests
  141. [Fact]
  142. public void Update_OnlyUpdatesActiveScreen_ByDefault()
  143. {
  144. ScreenManager manager = new ScreenManager();
  145. TestScreen screen1 = new TestScreen("Screen1");
  146. TestScreen screen2 = new TestScreen("Screen2");
  147. GameTime gameTime = new GameTime();
  148. manager.ShowScreen(screen1);
  149. manager.ShowScreen(screen2);
  150. manager.Update(gameTime);
  151. Assert.Equal(0, screen1.UpdateCallCount);
  152. Assert.Equal(1, screen2.UpdateCallCount);
  153. }
  154. [Fact]
  155. public void Update_UpdatesInactiveScreens_WhenUpdateWhenInactiveIsTrue()
  156. {
  157. ScreenManager manager = new ScreenManager();
  158. TestScreen screen1 = new TestScreen("Screen1") { UpdateWhenInactive = true };
  159. TestScreen screen2 = new TestScreen("Screen2");
  160. GameTime gameTime = new GameTime();
  161. manager.ShowScreen(screen1);
  162. manager.ShowScreen(screen2);
  163. manager.Update(gameTime);
  164. Assert.Equal(1, screen1.UpdateCallCount);
  165. Assert.Equal(1, screen2.UpdateCallCount);
  166. }
  167. [Fact]
  168. public void Update_UpdatesScreensInBottomToTopOrder()
  169. {
  170. ScreenManager manager = new ScreenManager();
  171. List<string> updateOrder = new List<string>();
  172. TestScreen screen1 = new TestScreen("Screen1") { UpdateWhenInactive = true };
  173. TestScreen screen2 = new TestScreen("Screen2") { UpdateWhenInactive = true };
  174. TestScreen screen3 = new TestScreen("Screen3");
  175. screen1.OnUpdate += name => updateOrder.Add(name);
  176. screen2.OnUpdate += name => updateOrder.Add(name);
  177. screen3.OnUpdate += name => updateOrder.Add(name);
  178. manager.ShowScreen(screen1);
  179. manager.ShowScreen(screen2);
  180. manager.ShowScreen(screen3);
  181. manager.Update(new GameTime());
  182. Assert.Equal(["Screen1", "Screen2", "Screen3"], updateOrder);
  183. }
  184. [Fact]
  185. public void Update_OnEmptyStack_DoesNotThrow()
  186. {
  187. ScreenManager manager = new ScreenManager();
  188. manager.Update(new GameTime());
  189. }
  190. #endregion
  191. #region Draw Tests
  192. [Fact]
  193. public void Draw_OnlyDrawsActiveScreen_ByDefault()
  194. {
  195. ScreenManager manager = new ScreenManager();
  196. TestScreen screen1 = new TestScreen("Screen1");
  197. TestScreen screen2 = new TestScreen("Screen2");
  198. GameTime gameTime = new GameTime();
  199. manager.ShowScreen(screen1);
  200. manager.ShowScreen(screen2);
  201. manager.Draw(gameTime);
  202. Assert.Equal(0, screen1.DrawCallCount);
  203. Assert.Equal(1, screen2.DrawCallCount);
  204. }
  205. [Fact]
  206. public void Draw_DrawsInactiveScreens_WhenDrawWhenInactiveIsTrue()
  207. {
  208. ScreenManager manager = new ScreenManager();
  209. TestScreen screen1 = new TestScreen("Screen1") { DrawWhenInactive = true };
  210. TestScreen screen2 = new TestScreen("Screen2");
  211. GameTime gameTime = new GameTime();
  212. manager.ShowScreen(screen1);
  213. manager.ShowScreen(screen2);
  214. manager.Draw(gameTime);
  215. Assert.Equal(1, screen1.DrawCallCount);
  216. Assert.Equal(1, screen2.DrawCallCount);
  217. }
  218. [Fact]
  219. public void Draw_DrawsScreensInBottomToTopOrder()
  220. {
  221. ScreenManager manager = new ScreenManager();
  222. List<string> drawOrder = new List<string>();
  223. TestScreen screen1 = new TestScreen("Screen1") { DrawWhenInactive = true };
  224. TestScreen screen2 = new TestScreen("Screen2") { DrawWhenInactive = true };
  225. TestScreen screen3 = new TestScreen("Screen3");
  226. screen1.OnDraw += name => drawOrder.Add(name);
  227. screen2.OnDraw += name => drawOrder.Add(name);
  228. screen3.OnDraw += name => drawOrder.Add(name);
  229. manager.ShowScreen(screen1);
  230. manager.ShowScreen(screen2);
  231. manager.ShowScreen(screen3);
  232. manager.Draw(new GameTime());
  233. Assert.Equal(["Screen1", "Screen2", "Screen3"], drawOrder);
  234. }
  235. [Fact]
  236. public void Draw_OnEmptyStack_DoesNotThrow()
  237. {
  238. ScreenManager manager = new ScreenManager();
  239. manager.Draw(new GameTime());
  240. }
  241. #endregion
  242. #region Stack Ordering Tests
  243. [Fact]
  244. public void Screens_ReturnsScreensInBottomToTopOrder()
  245. {
  246. ScreenManager manager = new ScreenManager();
  247. TestScreen screen1 = new TestScreen("Screen1");
  248. TestScreen screen2 = new TestScreen("Screen2");
  249. TestScreen screen3 = new TestScreen("Screen3");
  250. manager.ShowScreen(screen1);
  251. manager.ShowScreen(screen2);
  252. manager.ShowScreen(screen3);
  253. IReadOnlyList<Screen> screens = manager.Screens;
  254. Assert.Equal(3, screens.Count);
  255. Assert.Equal(screen1, screens[0]);
  256. Assert.Equal(screen2, screens[1]);
  257. Assert.Equal(screen3, screens[2]);
  258. }
  259. #endregion
  260. #region Cache Invalidation Tests
  261. [Fact]
  262. public void Screens_CachesResultsBetweenCalls()
  263. {
  264. ScreenManager manager = new ScreenManager();
  265. manager.ShowScreen(new TestScreen("Screen1"));
  266. IReadOnlyList<Screen> screens1 = manager.Screens;
  267. IReadOnlyList<Screen> screens2 = manager.Screens;
  268. Assert.Same(screens1, screens2);
  269. }
  270. [Fact]
  271. public void Screens_InvalidatesCacheOnShowScreen()
  272. {
  273. ScreenManager manager = new ScreenManager();
  274. manager.ShowScreen(new TestScreen("Screen1"));
  275. IReadOnlyList<Screen> screensBefore = manager.Screens;
  276. manager.ShowScreen(new TestScreen("Screen2"));
  277. IReadOnlyList<Screen> screensAfter = manager.Screens;
  278. Assert.NotSame(screensBefore, screensAfter);
  279. Assert.Equal(2, screensAfter.Count);
  280. }
  281. [Fact]
  282. public void Screens_InvalidatesCacheOnCloseScreen()
  283. {
  284. ScreenManager manager = new ScreenManager();
  285. manager.ShowScreen(new TestScreen("Screen1"));
  286. manager.ShowScreen(new TestScreen("Screen2"));
  287. IReadOnlyList<Screen> screensBefore = manager.Screens;
  288. manager.CloseScreen();
  289. IReadOnlyList<Screen> screensAfter = manager.Screens;
  290. Assert.NotSame(screensBefore, screensAfter);
  291. Assert.Single(screensAfter);
  292. }
  293. [Fact]
  294. public void Screens_InvalidatesCacheOnClearScreens()
  295. {
  296. ScreenManager manager = new ScreenManager();
  297. manager.ShowScreen(new TestScreen("Screen1"));
  298. IReadOnlyList<Screen> screensBefore = manager.Screens;
  299. manager.ClearScreens();
  300. IReadOnlyList<Screen> screensAfter = manager.Screens;
  301. Assert.NotSame(screensBefore, screensAfter);
  302. Assert.Empty(screensAfter);
  303. }
  304. #endregion
  305. }