InitTests.cs 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. using Xunit.Abstractions;
  2. namespace ApplicationTests.Init;
  3. /// <summary>
  4. /// Comprehensive tests for ApplicationImpl.Begin/End logic that manages Current and SessionStack.
  5. /// These tests ensure the fragile state management logic is robust and catches regressions.
  6. /// Tests work directly with ApplicationImpl instances to avoid global Application state issues.
  7. /// </summary>
  8. public class InitTests (ITestOutputHelper output)
  9. {
  10. private readonly ITestOutputHelper _output = output;
  11. [Fact]
  12. public void Init_Unbalanced_Throws ()
  13. {
  14. IApplication? app = Application.Create ();
  15. app.Init ("fake");
  16. Assert.Throws<InvalidOperationException> (() =>
  17. app.Init ("fake")
  18. );
  19. }
  20. [Fact]
  21. public void Init_Null_Driver_Should_Pick_A_Driver ()
  22. {
  23. IApplication app = Application.Create ();
  24. app.Init ();
  25. Assert.NotNull (app.Driver);
  26. app.Dispose ();
  27. }
  28. [Fact]
  29. public void Init_Dispose_Cleans_Up ()
  30. {
  31. IApplication app = Application.Create ();
  32. app.Init ("fake");
  33. app.Dispose ();
  34. #if DEBUG_IDISPOSABLE
  35. // Validate there are no outstanding Responder-based instances
  36. // after cleanup
  37. // Note: We can't check View.Instances in parallel tests as it's a static field
  38. // that would be shared across parallel test runs
  39. #endif
  40. }
  41. [Fact]
  42. public void Init_Dispose_Fire_InitializedChanged ()
  43. {
  44. var initialized = false;
  45. var Dispose = false;
  46. IApplication app = Application.Create ();
  47. app.InitializedChanged += OnApplicationOnInitializedChanged;
  48. app.Init (driverName: "fake");
  49. Assert.True (initialized);
  50. Assert.False (Dispose);
  51. app.Dispose ();
  52. Assert.True (initialized);
  53. Assert.True (Dispose);
  54. app.InitializedChanged -= OnApplicationOnInitializedChanged;
  55. return;
  56. void OnApplicationOnInitializedChanged (object? s, EventArgs<bool> a)
  57. {
  58. if (a.Value)
  59. {
  60. initialized = true;
  61. }
  62. else
  63. {
  64. Dispose = true;
  65. }
  66. }
  67. }
  68. [Fact]
  69. public void Init_KeyBindings_Are_Not_Reset ()
  70. {
  71. IApplication app = Application.Create ();
  72. // Set via Keyboard property (modern API)
  73. app.Keyboard.QuitKey = Key.Q;
  74. Assert.Equal (Key.Q, app.Keyboard.QuitKey);
  75. app.Init ("fake");
  76. Assert.Equal (Key.Q, app.Keyboard.QuitKey);
  77. app.Dispose ();
  78. }
  79. [Fact]
  80. public void Init_NoParam_ForceDriver_Works ()
  81. {
  82. using IApplication app = Application.Create ();
  83. app.ForceDriver = "fake";
  84. // Note: Init() without params picks up driver configuration
  85. app.Init ();
  86. Assert.Equal ("fake", app.Driver!.GetName ());
  87. }
  88. [Fact]
  89. public void Init_Dispose_Resets_Instance_Properties ()
  90. {
  91. IApplication app = Application.Create ();
  92. // Init the app
  93. app.Init (driverName: "fake");
  94. // Verify initialized
  95. Assert.True (app.Initialized);
  96. Assert.NotNull (app.Driver);
  97. // Dispose cleans up
  98. app.Dispose ();
  99. // Check reset state on the instance
  100. CheckReset (app);
  101. // Create a new instance and set values
  102. app = Application.Create ();
  103. app.Init ("fake");
  104. app.StopAfterFirstIteration = true;
  105. app.Keyboard.PrevTabGroupKey = Key.A;
  106. app.Keyboard.NextTabGroupKey = Key.B;
  107. app.Keyboard.QuitKey = Key.C;
  108. app.Keyboard.KeyBindings.Add (Key.D, Command.Cancel);
  109. app.Mouse.CachedViewsUnderMouse.Clear ();
  110. app.Mouse.LastMousePosition = new Point (1, 1);
  111. // Dispose and check reset
  112. app.Dispose ();
  113. CheckReset (app);
  114. return;
  115. void CheckReset (IApplication application)
  116. {
  117. // Check that all fields and properties are reset on the instance
  118. // Public Properties
  119. Assert.Null (application.TopRunnableView);
  120. Assert.Null (application.Mouse.MouseGrabView);
  121. Assert.Null (application.Driver);
  122. Assert.False (application.StopAfterFirstIteration);
  123. // Internal properties
  124. Assert.False (application.Initialized);
  125. Assert.Null (application.MainThreadId);
  126. Assert.Empty (application.Mouse.CachedViewsUnderMouse);
  127. }
  128. }
  129. }