ApplicationPopoverTests.cs 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364
  1. #nullable enable
  2. namespace UnitTests.ApplicationTests;
  3. public class ApplicationPopoverTests
  4. {
  5. [Fact]
  6. public void Application_Init_Initializes_PopoverManager ()
  7. {
  8. try
  9. {
  10. // Arrange
  11. Assert.Null (Application.Popover);
  12. Application.Init (null, "fake");
  13. // Act
  14. Assert.NotNull (Application.Popover);
  15. }
  16. finally
  17. {
  18. Application.ResetState (true);
  19. }
  20. }
  21. [Fact]
  22. public void Application_Shutdown_Resets_PopoverManager ()
  23. {
  24. try
  25. {
  26. // Arrange
  27. Assert.Null (Application.Popover);
  28. Application.Init (null, "fake");
  29. // Act
  30. Assert.NotNull (Application.Popover);
  31. Application.Shutdown ();
  32. // Test
  33. Assert.Null (Application.Popover);
  34. }
  35. finally
  36. {
  37. Application.ResetState (true);
  38. }
  39. }
  40. [Fact]
  41. public void Application_End_Does_Not_Reset_PopoverManager ()
  42. {
  43. Toplevel? top = null;
  44. try
  45. {
  46. // Arrange
  47. Assert.Null (Application.Popover);
  48. Application.Init (null, "fake");
  49. Assert.NotNull (Application.Popover);
  50. Application.StopAfterFirstIteration = true;
  51. top = new Toplevel ();
  52. SessionToken rs = Application.Begin (top);
  53. // Act
  54. Application.End (rs);
  55. // Test
  56. Assert.NotNull (Application.Popover);
  57. }
  58. finally
  59. {
  60. top?.Dispose ();
  61. Application.ResetState (true);
  62. }
  63. }
  64. [Fact]
  65. public void Application_End_Hides_Active ()
  66. {
  67. Toplevel? top = null;
  68. try
  69. {
  70. // Arrange
  71. Assert.Null (Application.Popover);
  72. Application.Init (null, "fake");
  73. Application.StopAfterFirstIteration = true;
  74. top = new Toplevel ();
  75. SessionToken rs = Application.Begin (top);
  76. PopoverTestClass? popover = new ();
  77. Application.Popover?.Show (popover);
  78. Assert.True (popover.Visible);
  79. // Act
  80. Application.End (rs);
  81. // Test
  82. Assert.False (popover.Visible);
  83. Assert.NotNull (Application.Popover);
  84. popover.Dispose ();
  85. Assert.Equal (1, popover.DisposedCount);
  86. }
  87. finally
  88. {
  89. top?.Dispose ();
  90. Application.ResetState (true);
  91. }
  92. }
  93. [Fact]
  94. public void Application_Shutdown_Disposes_Registered_Popovers ()
  95. {
  96. try
  97. {
  98. // Arrange
  99. Assert.Null (Application.Popover);
  100. Application.Init (null, "fake");
  101. PopoverTestClass? popover = new ();
  102. // Act
  103. Application.Popover?.Register (popover);
  104. Application.Shutdown ();
  105. // Test
  106. Assert.Equal (1, popover.DisposedCount);
  107. }
  108. finally
  109. {
  110. Application.ResetState (true);
  111. }
  112. }
  113. [Fact]
  114. public void Application_Shutdown_Does_Not_Dispose_DeRegistered_Popovers ()
  115. {
  116. try
  117. {
  118. // Arrange
  119. Assert.Null (Application.Popover);
  120. Application.Init (null, "fake");
  121. PopoverTestClass? popover = new ();
  122. Application.Popover?.Register (popover);
  123. // Act
  124. Application.Popover?.DeRegister (popover);
  125. Application.Shutdown ();
  126. // Test
  127. Assert.Equal (0, popover.DisposedCount);
  128. popover.Dispose ();
  129. Assert.Equal (1, popover.DisposedCount);
  130. }
  131. finally
  132. {
  133. Application.ResetState (true);
  134. }
  135. }
  136. [Fact]
  137. public void Application_Shutdown_Does_Not_Dispose_ActiveNotRegistered_Popover ()
  138. {
  139. try
  140. {
  141. // Arrange
  142. Assert.Null (Application.Popover);
  143. Application.Init (null, "fake");
  144. PopoverTestClass? popover = new ();
  145. Application.Popover?.Show (popover);
  146. Application.Popover?.DeRegister (popover);
  147. // Act
  148. Application.Shutdown ();
  149. // Test
  150. Assert.Equal (0, popover.DisposedCount);
  151. popover.Dispose ();
  152. Assert.Equal (1, popover.DisposedCount);
  153. }
  154. finally
  155. {
  156. Application.ResetState (true);
  157. }
  158. }
  159. [Fact]
  160. public void Register_SetsTopLevel ()
  161. {
  162. try
  163. {
  164. // Arrange
  165. Assert.Null (Application.Popover);
  166. Application.Init (null, "fake");
  167. Application.Top = new Toplevel ();
  168. PopoverTestClass? popover = new ();
  169. // Act
  170. Application.Popover?.Register (popover);
  171. // Assert
  172. Assert.Equal (Application.Top, popover.Toplevel);
  173. }
  174. finally
  175. {
  176. Application.ResetState (true);
  177. }
  178. }
  179. [Fact]
  180. public void Keyboard_Events_Go_Only_To_Popover_Associated_With_Toplevel ()
  181. {
  182. try
  183. {
  184. // Arrange
  185. Assert.Null (Application.Popover);
  186. Application.Init (null, "fake");
  187. Application.Top = new Toplevel () { Id = "initialTop" };
  188. PopoverTestClass? popover = new ();
  189. int keyDownEvents = 0;
  190. popover.KeyDown += (s, e) =>
  191. {
  192. keyDownEvents++;
  193. e.Handled = true;
  194. }; // Ensure it handles the key
  195. Application.Popover?.Register (popover);
  196. // Act
  197. Application.RaiseKeyDownEvent (Key.A); // Goes to initialTop
  198. Application.Top = new Toplevel () { Id = "secondaryTop" };
  199. Application.RaiseKeyDownEvent (Key.A); // Goes to secondaryTop
  200. // Test
  201. Assert.Equal (1, keyDownEvents);
  202. popover.Dispose ();
  203. Assert.Equal (1, popover.DisposedCount);
  204. }
  205. finally
  206. {
  207. Application.ResetState (true);
  208. }
  209. }
  210. // See: https://github.com/gui-cs/Terminal.Gui/issues/4122
  211. [Theory]
  212. [InlineData (0, 0, new [] { "top" })]
  213. [InlineData (10, 10, new string [] { })]
  214. [InlineData (1, 1, new [] { "top", "view" })]
  215. [InlineData (5, 5, new [] { "top" })]
  216. [InlineData (6, 6, new [] { "popoverSubView" })]
  217. [InlineData (7, 7, new [] { "top" })]
  218. [InlineData (3, 3, new [] { "top" })]
  219. public void GetViewsUnderMouse_Supports_ActivePopover (int mouseX, int mouseY, string [] viewIdStrings)
  220. {
  221. PopoverTestClass? popover = null;
  222. try
  223. {
  224. // Arrange
  225. Assert.Null (Application.Popover);
  226. Application.Init (null, "fake");
  227. Application.Top = new ()
  228. {
  229. Frame = new (0, 0, 10, 10),
  230. Id = "top"
  231. };
  232. View? view = new ()
  233. {
  234. Id = "view",
  235. X = 1,
  236. Y = 1,
  237. Width = 2,
  238. Height = 2,
  239. };
  240. Application.Top.Add (view);
  241. popover = new ()
  242. {
  243. Id = "popover",
  244. X = 5,
  245. Y = 5,
  246. Width = 3,
  247. Height = 3,
  248. }; // at 5,5 to 8,8 (screen)
  249. View? popoverSubView = new ()
  250. {
  251. Id = "popoverSubView",
  252. X = 1,
  253. Y = 1,
  254. Width = 1,
  255. Height = 1,
  256. };
  257. popover.Add (popoverSubView);
  258. Application.Popover?.Show (popover);
  259. List<View?> found = View.GetViewsUnderLocation (new (mouseX, mouseY), ViewportSettingsFlags.TransparentMouse);
  260. string [] foundIds = found.Select (v => v!.Id).ToArray ();
  261. Assert.Equal (viewIdStrings, foundIds);
  262. }
  263. finally
  264. {
  265. popover?.Dispose ();
  266. Application.Top?.Dispose ();
  267. Application.ResetState (true);
  268. }
  269. }
  270. public class PopoverTestClass : PopoverBaseImpl
  271. {
  272. public List<Key> HandledKeys { get; } = [];
  273. public int NewCommandInvokeCount { get; private set; }
  274. // NOTE: Hides the base DisposedCount property
  275. public new int DisposedCount { get; private set; }
  276. public PopoverTestClass ()
  277. {
  278. CanFocus = true;
  279. AddCommand (Command.New, NewCommandHandler!);
  280. HotKeyBindings.Add (Key.N.WithCtrl, Command.New);
  281. return;
  282. bool? NewCommandHandler (ICommandContext ctx)
  283. {
  284. NewCommandInvokeCount++;
  285. return false;
  286. }
  287. }
  288. protected override bool OnKeyDown (Key key)
  289. {
  290. HandledKeys.Add (key);
  291. return false;
  292. }
  293. /// <inheritdoc/>
  294. protected override void Dispose (bool disposing)
  295. {
  296. base.Dispose (disposing);
  297. DisposedCount++;
  298. }
  299. }
  300. }