瀏覽代碼

Fixed all modelusage bugs?

Replaced static `Application` references with instance-based `App`
context across the codebase. Updated calls to `Application.RequestStop()`
and `Application.Screen` to use `App?.RequestStop()` and `App?.Screen`
for better encapsulation and flexibility.

Refactored test infrastructure to align with the new context, including
reintroducing `FakeApplicationFactory` and `FakeApplicationLifecycle`
for testing purposes. Improved logging, error handling, and test
clarity by adding `logWriter` support and simplifying test setup.

Removed redundant or obsolete code, such as `NetSequences` and the old
`FakeApplicationFactory` implementation. Updated documentation to
reflect the new `IApplication.RequestStop()` usage.
Tig 3 周之前
父節點
當前提交
bc0634cf44

+ 1 - 1
Examples/UICatalog/Scenarios/Dialogs.cs

@@ -266,7 +266,7 @@ public class Dialogs : Scenario
             {
                 Title = titleEdit.Text,
                 Text = "Dialog Text",
-                ButtonAlignment = (Alignment)Enum.Parse (typeof (Alignment), alignmentGroup.Labels! [(int)alignmentGroup.Value!.Value] [1..]),
+                ButtonAlignment = (Alignment)Enum.Parse (typeof (Alignment), alignmentGroup.Labels! [(int)alignmentGroup.Value!.Value] [0..]),
 
                 Buttons = buttons.ToArray ()
             };

+ 1 - 1
Examples/UICatalog/Scenarios/DynamicStatusBar.cs

@@ -200,7 +200,7 @@ public class DynamicStatusBar : Scenario
                                       TextTitle.Text = string.Empty;
                                       Application.RequestStop ();
                                   };
-            var dialog = new Dialog { Title = "Enter the menu details.", Buttons = [btnOk, btnCancel], Height = Dim.Auto (DimAutoStyle.Content, 17, Application.Screen.Height) };
+            var dialog = new Dialog { Title = "Enter the menu details.", Buttons = [btnOk, btnCancel], Height = Dim.Auto (DimAutoStyle.Content, 17, App?.Screen.Height) };
 
             Width = Dim.Fill ();
             Height = Dim.Fill () - 2;

+ 2 - 2
Terminal.Gui/Views/Color/ColorPicker.Prompt.cs

@@ -37,7 +37,7 @@ public partial class ColorPicker
                         {
                             accept = true;
                             e.Handled = true;
-                            Application.RequestStop ();
+                            (s as View)?.App?.RequestStop ();
                         };
 
         var btnCancel = new Button
@@ -51,7 +51,7 @@ public partial class ColorPicker
         btnCancel.Accepting += (s, e) =>
                             {
                                 e.Handled = true;
-                                Application.RequestStop ();
+                                (s as View)?.App ?.RequestStop ();
                             };
 
         d.Add (btnOk);

+ 1 - 1
Terminal.Gui/Views/Dialog.cs

@@ -11,7 +11,7 @@ namespace Terminal.Gui.Views;
 ///     <see cref="IApplication.Run(Toplevel, Func{Exception, bool})"/>. This will execute the dialog until
 ///     it terminates via the <see cref="Application.QuitKey"/> (`Esc` by default),
 ///     or when one of the views or buttons added to the dialog calls
-///     <see cref="Application.RequestStop"/>.
+///     <see cref="IApplication.RequestStop()"/>.
 /// </remarks>
 public class Dialog : Window
 {

+ 2 - 2
Terminal.Gui/Views/FileDialogs/DefaultFileOperations.cs

@@ -138,7 +138,7 @@ public class DefaultFileOperations : IFileOperations
         btnOk.Accepting += (s, e) =>
                          {
                              confirm = true;
-                             Application.RequestStop ();
+                             (s as View)?.App?.RequestStop ();
                              // When Accepting is handled, set e.Handled to true to prevent further processing.
                              e.Handled = true;
                          };
@@ -147,7 +147,7 @@ public class DefaultFileOperations : IFileOperations
         btnCancel.Accepting += (s, e) =>
                              {
                                  confirm = false;
-                                 Application.RequestStop ();
+                                 (s as View)?.App?.RequestStop ();
                                  // When Accepting is handled, set e.Handled to true to prevent further processing.
                                  e.Handled = true;
                              };

+ 4 - 4
Terminal.Gui/Views/FileDialogs/FileDialog.cs

@@ -108,7 +108,7 @@ public class FileDialog : Dialog, IDesignable
 
                                     if (Modal)
                                     {
-                                        Application.RequestStop ();
+                                        (s as View)?.App?.RequestStop ();
                                     }
                                 };
 
@@ -468,7 +468,6 @@ public class FileDialog : Dialog, IDesignable
         Style.IconProvider.IsOpenGetter = _treeView.IsExpanded;
 
         _treeView.AddObjects (_treeRoots.Keys);
-#if MENU_V1
 
         // if filtering on file type is configured then create the ComboBox and establish
         // initial filtering by extension(s)
@@ -479,6 +478,7 @@ public class FileDialog : Dialog, IDesignable
             // Fiddle factor
             int width = AllowedTypes.Max (a => a.ToString ()!.Length) + 6;
 
+#if MENU_V1
             _allowedTypeMenu = new (
                                     "<placeholder>",
                                     _allowedTypeMenuItems = AllowedTypes.Select (
@@ -512,8 +512,8 @@ public class FileDialog : Dialog, IDesignable
                                                   };
 
             Add (_allowedTypeMenuBar);
-        }
 #endif
+        }
 
         // if no path has been provided
         if (_tbPath.Text.Length <= 0)
@@ -879,7 +879,7 @@ public class FileDialog : Dialog, IDesignable
 
         if (Modal)
         {
-            Application.RequestStop ();
+            App?.RequestStop ();
         }
     }
 

+ 2 - 2
Terminal.Gui/Views/MessageBox.cs

@@ -360,7 +360,7 @@ public static class MessageBox
                 if (count == defaultButton)
                 {
                     b.IsDefault = true;
-                    b.Accepting += (_, e) =>
+                    b.Accepting += (s, e) =>
                                    {
                                        if (e?.Context?.Source is Button button)
                                        {
@@ -376,7 +376,7 @@ public static class MessageBox
                                            e.Handled = true;
                                        }
 
-                                       Application.RequestStop ();
+                                       (s as View)?.App?.RequestStop ();
                                    };
                 }
 

+ 2 - 2
Terminal.Gui/Views/TableView/TableView.cs

@@ -1534,7 +1534,7 @@ public class TableView : View, IDesignable
     /// <param name="width"></param>
     private void ClearLine (int row, int width)
     {
-        if (Application.Screen.Height == 0)
+        if (App?.Screen.Height == 0)
         {
             return;
         }
@@ -1810,7 +1810,7 @@ public class TableView : View, IDesignable
                 }
             }
 
-            if (Application.Screen.Height > 0)
+            if (App?.Screen.Height > 0)
             {
                 AddRuneAt (c, row, rune);
             }

+ 1 - 1
Terminal.Gui/Views/Wizard/Wizard.cs

@@ -458,7 +458,7 @@ public class Wizard : Dialog
 
                 if (IsCurrentTop)
                 {
-                    Application.RequestStop (this);
+                    (sender as View)?.App?.RequestStop (this);
                     e.Handled = true;
                 }
 

+ 12 - 11
Tests/IntegrationTests/FluentTests/FileDialogFluentTests.cs

@@ -60,10 +60,10 @@ public class FileDialogFluentTests
     public void CancelFileDialog_QuitKey_Quits (TestDriver d)
     {
         SaveDialog? sd = null;
-        using var c = With.A (() => NewSaveDialog (out sd), 100, 20, d)
-            .ScreenShot ("Save dialog", _out)
-            .EnqueueKeyEvent (Application.QuitKey)
-            .AssertTrue (sd!.Canceled);
+        using GuiTestContext c = With.A (() => NewSaveDialog (out sd), 100, 20, d, logWriter: _out)
+                                     .ScreenShot ("Save dialog", _out)
+                                     .EnqueueKeyEvent (Application.QuitKey)
+                                     .AssertTrue (sd!.Canceled);
     }
 
     [Theory]
@@ -93,7 +93,7 @@ public class FileDialogFluentTests
     public void CancelFileDialog_UsingCancelButton_AltC (TestDriver d)
     {
         SaveDialog? sd = null;
-        using var c = With.A (() => NewSaveDialog (out sd), 100, 20, d)
+        using var c = With.A (() => NewSaveDialog (out sd), 100, 20, d, _out)
                           .ScreenShot ("Save dialog", _out)
                           .EnqueueKeyEvent (Key.C.WithAlt)
                           .AssertTrue (sd!.Canceled);
@@ -132,12 +132,13 @@ public class FileDialogFluentTests
     {
         SaveDialog? sd = null;
         MockFileSystem? fs = null;
-        using var c = With.A (() => NewSaveDialog (out sd, out fs, modal: false), 100, 20, d)
-                          .ScreenShot ("Save dialog", _out)
-                          .Focus<Button> (b => b.Text == "_Save")
-                          .EnqueueKeyEvent (Key.Enter)
-                          .AssertFalse (sd!.Canceled)
-                          .AssertEqual (GetFileSystemRoot (fs!), sd!.FileName);
+        using GuiTestContext c = With.A (() => NewSaveDialog (out sd, out fs, modal: false), 100, 20, d)
+                                     .ScreenShot ("Save dialog", _out)
+                                     .Focus<Button> (b => b.Text == "_Save")
+                                     .EnqueueKeyEvent (Key.Enter)
+                                     .AssertFalse (sd!.Canceled)
+                                     .AssertEqual (GetFileSystemRoot (fs!), sd!.FileName)
+                                     ;
     }
 
     private string GetFileSystemRoot (IFileSystem fs)

+ 1 - 1
Tests/IntegrationTests/FluentTests/GuiTestContextTests.cs

@@ -18,7 +18,7 @@ public class GuiTestContextTests (ITestOutputHelper outputHelper)
     {
         using var context = new GuiTestContext (d, _out, TimeSpan.FromSeconds (10));
 
-        Assert.NotEqual (Rectangle.Empty, Application.Screen);
+        Assert.NotEqual (Rectangle.Empty, context.App?.Screen);
     }
 
     [Theory]

+ 0 - 5
Tests/TerminalGuiFluentTesting/GuiTestContext.Input.cs

@@ -205,11 +205,6 @@ public partial class GuiTestContext
             App.Driver.EnqueueKeyEvent (key);
             WaitUntil (() => keyReceived);
         }
-        else
-        {
-            Fail ("Expected Application.Driver to be non-null.");
-        }
-
 
         return this;
 

+ 33 - 21
Tests/TerminalGuiFluentTesting/GuiTestContext.cs

@@ -68,7 +68,7 @@ public partial class GuiTestContext : IDisposable
 
         try
         {
-            InitializeApplication ();
+            App?.Init (GetDriverName ());
             _booting.Release ();
 
             // After Init, Application.Screen should be set by the driver
@@ -119,21 +119,36 @@ public partial class GuiTestContext : IDisposable
                              {
                                  try
                                  {
-                                     InitializeApplication ();
-
-                                     _booting.Release ();
-
-                                     Toplevel t = topLevelBuilder ();
-                                     t.Closed += (s, e) => { Finished = true; };
-                                     App?.Run (t); // This will block, but it's on a background thread now
+                                     try
+                                     {
+                                         App?.Init (GetDriverName ());
+                                     }
+                                     catch (Exception e)
+                                     {
+                                         Logging.Error(e.Message);
+                                         _runCancellationTokenSource.Cancel ();
+                                     }
+                                     finally
+                                     {
+                                         _booting.Release ();
+                                     }
 
-                                     t.Dispose ();
-                                     Logging.Trace ("Application.Run completed");
-                                     App?.Shutdown ();
-                                     _runCancellationTokenSource.Cancel ();
+                                     if (App is { Initialized: true })
+                                     {
+                                         Toplevel t = topLevelBuilder ();
+                                         t.Closed += (s, e) => { Finished = true; };
+                                         App?.Run (t); // This will block, but it's on a background thread now
+
+                                         t.Dispose ();
+                                         Logging.Trace ("Application.Run completed");
+                                         App?.Shutdown ();
+                                         _runCancellationTokenSource.Cancel ();
+                                     }
                                  }
                                  catch (OperationCanceledException)
-                                 { }
+                                 {
+                                     Logging.Trace ("OperationCanceledException");
+                                 }
                                  catch (Exception ex)
                                  {
                                      _backgroundException = ex;
@@ -142,7 +157,6 @@ public partial class GuiTestContext : IDisposable
                                  finally
                                  {
                                      CleanupApplication ();
-
                                      if (_logWriter != null)
                                      {
                                          WriteOutLogs (_logWriter);
@@ -165,11 +179,6 @@ public partial class GuiTestContext : IDisposable
         }
     }
 
-    private void InitializeApplication ()
-    {
-        App?.Init (GetDriverName ());
-    }
-
 
     /// <summary>
     ///     Common initialization for both constructors.
@@ -316,7 +325,7 @@ public partial class GuiTestContext : IDisposable
             throw new NotSupportedException ("Cannot WaitIteration during Invoke");
         }
 
-        Logging.Trace ($"WaitIteration started");
+        //Logging.Trace ($"WaitIteration started");
         if (action is null)
         {
             action = (app) => { };
@@ -358,8 +367,9 @@ public partial class GuiTestContext : IDisposable
         GuiTestContext? c = null;
         var sw = Stopwatch.StartNew ();
 
-        //Logging.Trace ($"WaitUntil started with timeout {_timeout}");
+        Logging.Trace ($"WaitUntil started with timeout {_timeout}");
 
+        int count = 0;
         while (!condition ())
         {
             if (sw.Elapsed > _timeout)
@@ -368,8 +378,10 @@ public partial class GuiTestContext : IDisposable
             }
 
             c = WaitIteration ();
+            count++;
         }
 
+        Logging.Trace ($"WaitUntil completed after {sw.ElapsedMilliseconds}ms and {count} iterations");
         return c ?? this;
     }
 

+ 0 - 53
Tests/TerminalGuiFluentTesting/NetSequences.cs

@@ -1,53 +0,0 @@
-namespace TerminalGuiFluentTesting;
-class NetSequences
-{
-    public static ConsoleKeyInfo [] Down = new []
-    {
-        new ConsoleKeyInfo('\x1B', ConsoleKey.Enter, false, false, false),
-        new ConsoleKeyInfo('[', ConsoleKey.None, false, false, false),
-        new ConsoleKeyInfo('B', ConsoleKey.None, false, false, false),
-    };
-
-    public static ConsoleKeyInfo [] Up = new []
-    {
-        new ConsoleKeyInfo('\x1B', ConsoleKey.Enter, false, false, false),
-        new ConsoleKeyInfo('[', ConsoleKey.None, false, false, false),
-        new ConsoleKeyInfo('A', ConsoleKey.None, false, false, false),
-    };
-
-    public static ConsoleKeyInfo [] Left = new []
-    {
-        new ConsoleKeyInfo('\x1B', ConsoleKey.Enter, false, false, false),
-        new ConsoleKeyInfo('[', ConsoleKey.None, false, false, false),
-        new ConsoleKeyInfo('D', ConsoleKey.None, false, false, false),
-    };
-
-    public static ConsoleKeyInfo [] Right = new []
-    {
-        new ConsoleKeyInfo('\x1B', ConsoleKey.Enter, false, false, false),
-        new ConsoleKeyInfo('[', ConsoleKey.None, false, false, false),
-        new ConsoleKeyInfo('C', ConsoleKey.None, false, false, false),
-    };
-
-    public static IEnumerable<ConsoleKeyInfo> Click (int button, int screenX, int screenY)
-    {
-        // Adjust for 1-based coordinates
-        int adjustedX = screenX + 1;
-        int adjustedY = screenY + 1;
-
-        // Mouse press sequence
-        var sequence = $"\x1B[<{button};{adjustedX};{adjustedY}M";
-        foreach (char c in sequence)
-        {
-            yield return new ConsoleKeyInfo (c, ConsoleKey.None, false, false, false);
-        }
-
-        // Mouse release sequence
-        sequence = $"\x1B[<{button};{adjustedX};{adjustedY}m";
-        foreach (char c in sequence)
-        {
-            yield return new ConsoleKeyInfo (c, ConsoleKey.None, false, false, false);
-        }
-    }
-
-}

+ 3 - 2
Tests/TerminalGuiFluentTesting/With.cs

@@ -29,10 +29,11 @@ public static class With
     /// <param name="width"></param>
     /// <param name="height"></param>
     /// <param name="testDriver"></param>
+    /// <param name="logWriter"></param>
     /// <returns></returns>
-    public static GuiTestContext A (Func<Toplevel> toplevelFactory, int width, int height, TestDriver testDriver)
+    public static GuiTestContext A (Func<Toplevel> toplevelFactory, int width, int height, TestDriver testDriver, TextWriter? logWriter = null)
     {
-        return new (toplevelFactory, width, height, testDriver, null, Timeout);
+        return new (toplevelFactory, width, height, testDriver, logWriter, Timeout);
     }
     /// <summary>
     ///     The global timeout to allow for any given application to run for before shutting down.

+ 0 - 0
Tests/TerminalGuiFluentTesting/FakeDriver/FakeApplicationFactory.cs → Tests/UnitTests/FakeDriver/FakeApplicationFactory.cs


+ 0 - 0
Tests/TerminalGuiFluentTesting/FakeDriver/FakeApplicationLifecycle.cs → Tests/UnitTests/FakeDriver/FakeApplicationLifecycle.cs


+ 11 - 11
Tests/UnitTests/Views/TableViewTests.cs

@@ -59,7 +59,7 @@ public class TableViewTests (ITestOutputHelper output)
     {
         var tv = new TableView
         {
-            Driver = ApplicationImpl.Instance.Driver,
+            App = ApplicationImpl.Instance,
             Width = 20, Height = 4
         };
 
@@ -683,7 +683,7 @@ public class TableViewTests (ITestOutputHelper output)
     {
         var tableView = new TableView ()
         {
-            Driver = ApplicationImpl.Instance.Driver
+            App = ApplicationImpl.Instance
         };
         tableView.BeginInit ();
         tableView.EndInit ();
@@ -765,7 +765,7 @@ public class TableViewTests (ITestOutputHelper output)
     {
         var tableView = new TableView ()
         {
-            Driver = ApplicationImpl.Instance.Driver
+            App = ApplicationImpl.Instance
         };
         tableView.BeginInit ();
         tableView.EndInit ();
@@ -830,7 +830,7 @@ public class TableViewTests (ITestOutputHelper output)
     {
         var tableView = new TableView ()
         {
-            Driver = ApplicationImpl.Instance.Driver
+            App = ApplicationImpl.Instance
         };
 
         tableView.BeginInit ();
@@ -1579,7 +1579,7 @@ public class TableViewTests (ITestOutputHelper output)
     {
         var tv = new TableView ()
         {
-            Driver = ApplicationImpl.Instance.Driver
+            App = ApplicationImpl.Instance
         };
         tv.SchemeName = "TopLevel";
         tv.Viewport = new (0, 0, 50, 7);
@@ -2226,7 +2226,7 @@ public class TableViewTests (ITestOutputHelper output)
         ApplicationImpl.Instance.Driver!.SetScreenSize (100, 100);
         var tv = new TableView ()
         {
-            Driver = ApplicationImpl.Instance.Driver
+            App = ApplicationImpl.Instance
         };
         tv.SchemeName = "TopLevel";
         tv.Viewport = new (0, 0, 50, 6);
@@ -2433,7 +2433,7 @@ A B C
 
         var tv = new TableView ()
         {
-            Driver = ApplicationImpl.Instance.Driver
+            App = ApplicationImpl.Instance
         };
 
         //tv.BeginInit (); tv.EndInit ();
@@ -3441,7 +3441,7 @@ A B C
     {
         var tableView = new TableView ()
         {
-            Driver = ApplicationImpl.Instance.Driver
+            App = ApplicationImpl.Instance
         };
         tableView.BeginInit ();
         tableView.EndInit ();
@@ -3473,7 +3473,7 @@ A B C
     {
         var tv = new TableView ()
         {
-            Driver = ApplicationImpl.Instance.Driver,
+            App = ApplicationImpl.Instance,
             SchemeName = "TopLevel",
             Viewport = new (0, 0, 25, 6)
         };
@@ -3504,7 +3504,7 @@ A B C
     {
         var tableView = new TableView ()
         {
-            Driver = ApplicationImpl.Instance.Driver
+            App = ApplicationImpl.Instance
         };
         tableView.SchemeName = "TopLevel";
 
@@ -3537,7 +3537,7 @@ A B C
     {
         var tv = new TableView ()
         {
-            Driver = ApplicationImpl.Instance.Driver
+            App = ApplicationImpl.Instance
         };
         tv.BeginInit ();
         tv.EndInit ();