ApplicationTests.cs 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. using System;
  2. using System.Linq;
  3. using System.Threading;
  4. using System.Threading.Tasks;
  5. using Xunit;
  6. // Alais Console to MockConsole so we don't accidentally use Console
  7. using Console = Terminal.Gui.FakeConsole;
  8. namespace Terminal.Gui.Core {
  9. public class ApplicationTests {
  10. public ApplicationTests ()
  11. {
  12. #if DEBUG_IDISPOSABLE
  13. Responder.Instances.Clear ();
  14. #endif
  15. }
  16. [Fact]
  17. public void Init_Shutdown_Cleans_Up ()
  18. {
  19. // Verify inital state is per spec
  20. Pre_Init_State ();
  21. Application.Init (new FakeDriver (), new FakeMainLoop (() => FakeConsole.ReadKey (true)));
  22. // Verify post-Init state is correct
  23. Post_Init_State ();
  24. // MockDriver is always 80x25
  25. Assert.Equal (80, Application.Driver.Cols);
  26. Assert.Equal (25, Application.Driver.Rows);
  27. Application.Shutdown ();
  28. // Verify state is back to initial
  29. Pre_Init_State ();
  30. }
  31. void Pre_Init_State ()
  32. {
  33. Assert.Null (Application.Driver);
  34. Assert.Null (Application.Top);
  35. Assert.Null (Application.Current);
  36. Assert.Throws<ArgumentNullException> (() => Application.HeightAsBuffer == true);
  37. Assert.False (Application.AlwaysSetPosition);
  38. Assert.Null (Application.MainLoop);
  39. Assert.Null (Application.Iteration);
  40. Assert.False (Application.UseSystemConsole);
  41. Assert.Null (Application.RootMouseEvent);
  42. Assert.Null (Application.Resized);
  43. }
  44. void Post_Init_State ()
  45. {
  46. Assert.NotNull (Application.Driver);
  47. Assert.NotNull (Application.Top);
  48. Assert.NotNull (Application.Current);
  49. Assert.False (Application.HeightAsBuffer);
  50. Assert.False (Application.AlwaysSetPosition);
  51. Assert.NotNull (Application.MainLoop);
  52. Assert.Null (Application.Iteration);
  53. Assert.False (Application.UseSystemConsole);
  54. Assert.Null (Application.RootMouseEvent);
  55. Assert.Null (Application.Resized);
  56. }
  57. [Fact]
  58. public void RunState_Dispose_Cleans_Up ()
  59. {
  60. var rs = new Application.RunState (null);
  61. Assert.NotNull (rs);
  62. // Should not throw because Toplevel was null
  63. rs.Dispose ();
  64. var top = new Toplevel ();
  65. rs = new Application.RunState (top);
  66. Assert.NotNull (rs);
  67. // Should throw because there's no stack
  68. Assert.Throws<InvalidOperationException> (() => rs.Dispose ());
  69. }
  70. void Init ()
  71. {
  72. Application.Init (new FakeDriver (), new FakeMainLoop (() => FakeConsole.ReadKey (true)));
  73. Assert.NotNull (Application.Driver);
  74. Assert.NotNull (Application.MainLoop);
  75. }
  76. void Shutdown ()
  77. {
  78. Application.Shutdown ();
  79. }
  80. [Fact]
  81. public void Begin_End_Cleana_Up ()
  82. {
  83. // Setup Mock driver
  84. Init ();
  85. // Test null Toplevel
  86. Assert.Throws<ArgumentNullException> (() => Application.Begin (null));
  87. var top = new Toplevel ();
  88. var rs = Application.Begin (top);
  89. Assert.NotNull (rs);
  90. Assert.Equal (top, Application.Current);
  91. Application.End (rs);
  92. Assert.Null (Application.Current);
  93. Assert.NotNull (Application.Top);
  94. Assert.NotNull (Application.MainLoop);
  95. Assert.NotNull (Application.Driver);
  96. Shutdown ();
  97. Assert.Null (Application.Top);
  98. Assert.Null (Application.MainLoop);
  99. Assert.Null (Application.Driver);
  100. }
  101. [Fact]
  102. public void RequestStop_Stops ()
  103. {
  104. // Setup Mock driver
  105. Init ();
  106. var top = new Toplevel ();
  107. var rs = Application.Begin (top);
  108. Assert.NotNull (rs);
  109. Assert.Equal (top, Application.Current);
  110. Application.Iteration = () => {
  111. Application.RequestStop ();
  112. };
  113. Application.Run (top);
  114. Application.Shutdown ();
  115. Assert.Null (Application.Current);
  116. Assert.Null (Application.Top);
  117. Assert.Null (Application.MainLoop);
  118. Assert.Null (Application.Driver);
  119. }
  120. [Fact]
  121. public void RunningFalse_Stops ()
  122. {
  123. // Setup Mock driver
  124. Init ();
  125. var top = new Toplevel ();
  126. var rs = Application.Begin (top);
  127. Assert.NotNull (rs);
  128. Assert.Equal (top, Application.Current);
  129. Application.Iteration = () => {
  130. top.Running = false;
  131. };
  132. Application.Run (top);
  133. Application.Shutdown ();
  134. Assert.Null (Application.Current);
  135. Assert.Null (Application.Top);
  136. Assert.Null (Application.MainLoop);
  137. Assert.Null (Application.Driver);
  138. }
  139. [Fact]
  140. public void KeyUp_Event ()
  141. {
  142. // Setup Mock driver
  143. Init ();
  144. // Setup some fake kepresses (This)
  145. var input = "Tests";
  146. // Put a control-q in at the end
  147. Console.MockKeyPresses.Push (new ConsoleKeyInfo ('q', ConsoleKey.Q, shift: false, alt: false, control: true));
  148. foreach (var c in input.Reverse ()) {
  149. if (char.IsLetter (c)) {
  150. Console.MockKeyPresses.Push (new ConsoleKeyInfo (c, (ConsoleKey)char.ToUpper (c), shift: char.IsUpper (c), alt: false, control: false));
  151. } else {
  152. Console.MockKeyPresses.Push (new ConsoleKeyInfo (c, (ConsoleKey)c, shift: false, alt: false, control: false));
  153. }
  154. }
  155. int stackSize = Console.MockKeyPresses.Count;
  156. int iterations = 0;
  157. Application.Iteration = () => {
  158. iterations++;
  159. // Stop if we run out of control...
  160. if (iterations > 10) {
  161. Application.RequestStop ();
  162. }
  163. };
  164. int keyUps = 0;
  165. var output = string.Empty;
  166. Application.Top.KeyUp += (View.KeyEventEventArgs args) => {
  167. if (args.KeyEvent.Key != (Key.CtrlMask | Key.Q)) {
  168. output += (char)args.KeyEvent.KeyValue;
  169. }
  170. keyUps++;
  171. };
  172. Application.Run (Application.Top);
  173. // Input string should match output
  174. Assert.Equal (input, output);
  175. // # of key up events should match stack size
  176. //Assert.Equal (stackSize, keyUps);
  177. // We can't use numbers variables on the left side of an Assert.Equal/NotEqual,
  178. // it must be literal (Linux only).
  179. Assert.Equal (6, keyUps);
  180. // # of key up events should match # of iterations
  181. Assert.Equal (stackSize, iterations);
  182. Application.Shutdown ();
  183. Assert.Null (Application.Current);
  184. Assert.Null (Application.Top);
  185. Assert.Null (Application.MainLoop);
  186. Assert.Null (Application.Driver);
  187. }
  188. [Fact]
  189. public void Loaded_Ready_Unlodaded_Events ()
  190. {
  191. Init ();
  192. var top = Application.Top;
  193. var count = 0;
  194. top.Loaded += () => count++;
  195. top.Ready += () => count++;
  196. top.Unloaded += () => count++;
  197. Application.Iteration = () => Application.RequestStop ();
  198. Application.Run ();
  199. Application.Shutdown ();
  200. Assert.Equal (3, count);
  201. }
  202. [Fact]
  203. public void Shutdown_Allows_Async ()
  204. {
  205. static async Task TaskWithAsyncContinuation ()
  206. {
  207. await Task.Yield ();
  208. await Task.Yield ();
  209. }
  210. Init ();
  211. Application.Shutdown ();
  212. var task = TaskWithAsyncContinuation ();
  213. Thread.Sleep (20);
  214. Assert.True (task.IsCompletedSuccessfully);
  215. }
  216. [Fact]
  217. public void Shutdown_Resets_SyncContext ()
  218. {
  219. Init ();
  220. Application.Shutdown ();
  221. Assert.Null (SynchronizationContext.Current);
  222. }
  223. }
  224. }