ScenarioTests.cs 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using Terminal.Gui;
  5. using UICatalog;
  6. using Xunit;
  7. // Alias Console to MockConsole so we don't accidentally use Console
  8. using Console = Terminal.Gui.FakeConsole;
  9. namespace Terminal.Gui {
  10. public class ScenarioTests {
  11. public ScenarioTests ()
  12. {
  13. #if DEBUG_IDISPOSABLE
  14. Responder.Instances.Clear ();
  15. #endif
  16. }
  17. int CreateInput (string input)
  18. {
  19. // Put a control-q in at the end
  20. Console.MockKeyPresses.Push (new ConsoleKeyInfo ('q', ConsoleKey.Q, shift: false, alt: false, control: true));
  21. foreach (var c in input.Reverse ()) {
  22. if (char.IsLetter (c)) {
  23. Console.MockKeyPresses.Push (new ConsoleKeyInfo (char.ToLower (c), (ConsoleKey)char.ToUpper (c), shift: char.IsUpper (c), alt: false, control: false));
  24. } else {
  25. Console.MockKeyPresses.Push (new ConsoleKeyInfo (c, (ConsoleKey)c, shift: false, alt: false, control: false));
  26. }
  27. }
  28. return Console.MockKeyPresses.Count;
  29. }
  30. /// <summary>
  31. /// This runs through all Scenarios defined in UI Catalog, calling Init, Setup, and Run.
  32. /// It puts a Ctrl-Q in the input queue so the Scenario immediately exits.
  33. /// Should find any egregious regressions.
  34. /// </summary>
  35. [Fact]
  36. public void Run_All_Scenarios ()
  37. {
  38. List<Type> scenarioClasses = Scenario.GetDerivedClasses<Scenario> ();
  39. Assert.NotEmpty (scenarioClasses);
  40. foreach (var scenarioClass in scenarioClasses) {
  41. // Setup some fake keypresses
  42. // Passing empty string will cause just a ctrl-q to be fired
  43. Console.MockKeyPresses.Clear ();
  44. int stackSize = CreateInput ("");
  45. Application.Init (new FakeDriver (), new FakeMainLoop (() => FakeConsole.ReadKey (true)));
  46. int iterations = 0;
  47. Application.Iteration = () => {
  48. iterations++;
  49. // Stop if we run out of control...
  50. if (iterations > 10) {
  51. Application.RequestStop ();
  52. }
  53. };
  54. var ms = 1000;
  55. var abortCount = 0;
  56. Func<MainLoop, bool> abortCallback = (MainLoop loop) => {
  57. abortCount++;
  58. Application.RequestStop ();
  59. return false;
  60. };
  61. var token = Application.MainLoop.AddTimeout (TimeSpan.FromMilliseconds (ms), abortCallback);
  62. var scenario = (Scenario)Activator.CreateInstance (scenarioClass);
  63. scenario.Init (Application.Top, Colors.Base);
  64. scenario.Setup ();
  65. // There is no need to call Application.Begin because Init already creates the Application.Top
  66. // If Application.RunState is used then the Application.RunLoop must also be used instead Application.Run.
  67. //var rs = Application.Begin (Application.Top);
  68. scenario.Run ();
  69. //Application.End (rs);
  70. // Shutdown must be called to safely clean up Application if Init has been called
  71. Application.Shutdown ();
  72. Assert.Equal (0, abortCount);
  73. // # of key up events should match # of iterations
  74. Assert.Equal (1, iterations);
  75. Assert.Equal (stackSize, iterations);
  76. }
  77. #if DEBUG_IDISPOSABLE
  78. foreach (var inst in Responder.Instances) {
  79. Assert.True (inst.WasDisposed);
  80. }
  81. Responder.Instances.Clear ();
  82. #endif
  83. }
  84. [Fact]
  85. public void Run_Generic ()
  86. {
  87. List<Type> scenarioClasses = Scenario.GetDerivedClasses<Scenario> ();
  88. Assert.NotEmpty (scenarioClasses);
  89. var item = scenarioClasses.FindIndex (t => Scenario.ScenarioMetadata.GetName (t).Equals ("Generic", StringComparison.OrdinalIgnoreCase));
  90. var scenarioClass = scenarioClasses [item];
  91. // Setup some fake keypresses
  92. // Passing empty string will cause just a ctrl-q to be fired
  93. int stackSize = CreateInput ("");
  94. Application.Init (new FakeDriver (), new FakeMainLoop (() => FakeConsole.ReadKey (true)));
  95. int iterations = 0;
  96. Application.Iteration = () => {
  97. iterations++;
  98. // Stop if we run out of control...
  99. if (iterations == 10) {
  100. Application.RequestStop ();
  101. }
  102. };
  103. var ms = 1000;
  104. var abortCount = 0;
  105. Func<MainLoop, bool> abortCallback = (MainLoop loop) => {
  106. abortCount++;
  107. Application.RequestStop ();
  108. return false;
  109. };
  110. var token = Application.MainLoop.AddTimeout (TimeSpan.FromMilliseconds (ms), abortCallback);
  111. Application.Top.KeyPress += (View.KeyEventEventArgs args) => {
  112. Assert.Equal (Key.CtrlMask | Key.Q, args.KeyEvent.Key);
  113. };
  114. var scenario = (Scenario)Activator.CreateInstance (scenarioClass);
  115. scenario.Init (Application.Top, Colors.Base);
  116. scenario.Setup ();
  117. // There is no need to call Application.Begin because Init already creates the Application.Top
  118. // If Application.RunState is used then the Application.RunLoop must also be used instead Application.Run.
  119. //var rs = Application.Begin (Application.Top);
  120. scenario.Run ();
  121. //Application.End (rs);
  122. Assert.Equal (0, abortCount);
  123. // # of key up events should match # of iterations
  124. Assert.Equal (1, iterations);
  125. // Using variable in the left side of Assert.Equal/NotEqual give error. Must be used literals values.
  126. //Assert.Equal (stackSize, iterations);
  127. // Shutdown must be called to safely clean up Application if Init has been called
  128. Application.Shutdown ();
  129. #if DEBUG_IDISPOSABLE
  130. foreach (var inst in Responder.Instances) {
  131. Assert.True (inst.WasDisposed);
  132. }
  133. Responder.Instances.Clear ();
  134. #endif
  135. }
  136. }
  137. }