Browse Source

Phase 1: Add SetScreenSize API to IConsoleDriver and implementations

Co-authored-by: tig <[email protected]>
copilot-swe-agent[bot] 1 month ago
parent
commit
21c0335018

+ 14 - 0
Terminal.Gui/Drivers/ConsoleDriver.cs

@@ -531,6 +531,20 @@ public abstract class ConsoleDriver : IConsoleDriver
     /// <returns><see langword="true"/> upon success</returns>
     public abstract bool SetCursorVisibility (CursorVisibility visibility);
 
+    /// <summary>
+    ///     Sets the screen (terminal) size. This method is primarily used for testing with <see cref="FakeDriver"/>.
+    /// </summary>
+    /// <remarks>
+    ///     Only <see cref="FakeDriver"/> implements this method. Other drivers throw <see cref="NotImplementedException"/>.
+    /// </remarks>
+    /// <param name="width">The new width (columns).</param>
+    /// <param name="height">The new height (rows).</param>
+    /// <exception cref="NotImplementedException">Thrown by all drivers except <see cref="FakeDriver"/>.</exception>
+    public virtual void SetScreenSize (int width, int height)
+    {
+        throw new NotImplementedException ("SetScreenSize is only supported by FakeDriver for testing purposes.");
+    }
+
     /// <summary>The event fired when the terminal is resized.</summary>
     public event EventHandler<SizeChangedEventArgs>? SizeChanged;
 

+ 14 - 0
Terminal.Gui/Drivers/ConsoleDriverFacade.cs

@@ -317,6 +317,20 @@ internal class ConsoleDriverFacade<T> : IConsoleDriver, IConsoleDriverFacade
         return true;
     }
 
+    /// <summary>
+    ///     Sets the screen (terminal) size. This method is only supported by FakeDriver.
+    /// </summary>
+    /// <remarks>
+    ///     This is a pass-through to the underlying driver. Only FakeDriver implements this; other drivers throw <see cref="NotImplementedException"/>.
+    /// </remarks>
+    /// <param name="width">The new width (columns).</param>
+    /// <param name="height">The new height (rows).</param>
+    /// <exception cref="NotImplementedException">Thrown by all drivers except FakeDriver.</exception>
+    public virtual void SetScreenSize (int width, int height)
+    {
+        throw new NotImplementedException ("SetScreenSize is only supported by FakeDriver for testing purposes.");
+    }
+
     /// <inheritdoc/>
     public bool GetCursorVisibility (out CursorVisibility current)
     {

+ 14 - 0
Terminal.Gui/Drivers/FakeDriver/FakeDriver.cs

@@ -401,6 +401,20 @@ public class FakeDriver : ConsoleDriver
         ProcessResize ();
     }
 
+    /// <summary>
+    ///     Sets the screen (terminal) size for testing purposes.
+    /// </summary>
+    /// <remarks>
+    ///     This method updates <see cref="ConsoleDriver.Cols"/> and <see cref="ConsoleDriver.Rows"/>,
+    ///     resizes the internal buffers, clears contents, and fires the <see cref="ConsoleDriver.SizeChanged"/> event.
+    /// </remarks>
+    /// <param name="width">The new width (columns).</param>
+    /// <param name="height">The new height (rows).</param>
+    public override void SetScreenSize (int width, int height)
+    {
+        SetWindowSize (width, height);
+    }
+
     public void SetWindowPosition (int left, int top)
     {
         if (Left > 0 || Top > 0)

+ 16 - 0
Terminal.Gui/Drivers/IConsoleDriver.cs

@@ -200,6 +200,22 @@ public interface IConsoleDriver
     /// <returns><see langword="true"/> upon success</returns>
     bool SetCursorVisibility (CursorVisibility visibility);
 
+    /// <summary>
+    ///     Sets the screen (terminal) size. This method is primarily used for testing with <see cref="FakeDriver"/>.
+    /// </summary>
+    /// <remarks>
+    ///     <para>
+    ///         Only <see cref="FakeDriver"/> implements this method. Other drivers throw <see cref="NotImplementedException"/>.
+    ///     </para>
+    ///     <para>
+    ///         When implemented, this method updates <see cref="Cols"/> and <see cref="Rows"/>, clears the contents buffer,
+    ///         and fires the <see cref="SizeChanged"/> event.
+    ///     </para>
+    /// </remarks>
+    /// <param name="width">The new width (columns).</param>
+    /// <param name="height">The new height (rows).</param>
+    void SetScreenSize (int width, int height);
+
     /// <summary>The event fired when the terminal is resized.</summary>
     event EventHandler<SizeChangedEventArgs>? SizeChanged;
 

+ 10 - 0
Tests/TerminalGuiFluentTesting/FakeDriver/FakeConsoleDriver.cs

@@ -51,6 +51,16 @@ internal class FakeConsoleDriver : ConsoleDriverFacade<ConsoleKeyInfo>, IFakeCon
         OutputBuffer.SetWindowSize (width, height);
     }
 
+    /// <summary>
+    ///     Sets the screen size for testing purposes.
+    /// </summary>
+    /// <param name="width">The new width (columns).</param>
+    /// <param name="height">The new height (rows).</param>
+    public override void SetScreenSize (int width, int height)
+    {
+        SetBufferSize (width, height);
+    }
+
     public IConsoleOutput ConsoleOutput { get; }
     public ConcurrentQueue<ConsoleKeyInfo> InputBuffer { get; }
     public new OutputBuffer OutputBuffer { get; }

+ 36 - 11
Tests/UnitTests/AutoInitShutdownAttribute.cs

@@ -155,25 +155,50 @@ public class AutoInitShutdownAttribute : BeforeAfterTestAttribute
     private bool AutoInit { get; }
 
     /// <summary>
-    /// 'Resizes' the application and forces layout. Only works if your test uses <see cref="AutoInitShutdownAttribute"/>
+    /// 'Resizes' the application screen and forces layout. Only works if your test uses <see cref="AutoInitShutdownAttribute"/>
+    /// with FakeDriver (the default).
     /// </summary>
-    /// <param name="size"></param>
+    /// <param name="size">The new screen size.</param>
+    /// <remarks>
+    ///     This method works with both the library FakeDriver and the fluent testing FakeConsoleDriver.
+    ///     It uses <see cref="IConsoleDriver.SetScreenSize"/> when available, or manipulates the buffer/monitor directly.
+    /// </remarks>
     public static void FakeResize (Size size)
     {
-        var d = (IConsoleDriverFacade)Application.Driver!;
-        d.OutputBuffer.SetWindowSize (size.Width, size.Height);
-        
-        // Handle both FakeSizeMonitor (from test project) and FakeWindowSizeMonitor (from main library)
-        if (d.WindowSizeMonitor is FakeSizeMonitor fakeSizeMonitor)
+        if (Application.Driver is null)
         {
-            fakeSizeMonitor.RaiseSizeChanging (size);
+            return;
         }
-        else if (d.WindowSizeMonitor is FakeWindowSizeMonitor fakeWindowSizeMonitor)
+
+        // Try the library FakeDriver first - it has SetScreenSize implemented
+        if (Application.Driver is FakeDriver fakeDriver)
         {
-            // For FakeWindowSizeMonitor, use the RaiseSizeChanging method
-            fakeWindowSizeMonitor.RaiseSizeChanging (size);
+            fakeDriver.SetScreenSize (size.Width, size.Height);
+            Application.LayoutAndDraw (true);
+            return;
+        }
+
+        // For fluent testing FakeConsoleDriver (through facade), manipulate buffer and monitor directly
+        if (Application.Driver is IConsoleDriverFacade facade)
+        {
+            facade.OutputBuffer.SetWindowSize (size.Width, size.Height);
+            
+            // Raise the size changing event through the monitor
+            if (facade.WindowSizeMonitor is FakeSizeMonitor fakeSizeMonitor)
+            {
+                fakeSizeMonitor.RaiseSizeChanging (size);
+            }
+            else if (facade.WindowSizeMonitor is FakeWindowSizeMonitor fakeWindowSizeMonitor)
+            {
+                fakeWindowSizeMonitor.RaiseSizeChanging (size);
+            }
+
+            Application.LayoutAndDraw (true);
+            return;
         }
 
+        // Fallback: try SetScreenSize through interface (will throw if not supported)
+        Application.Driver.SetScreenSize (size.Width, size.Height);
         Application.LayoutAndDraw (true);
     }
 

+ 3 - 0
Tests/UnitTestsParallelizable/MockConsoleDriver.cs

@@ -145,6 +145,9 @@ internal class MockConsoleDriver : IConsoleDriver
     /// <inheritdoc />
     public bool SetCursorVisibility (CursorVisibility visibility) { throw new NotImplementedException (); }
 
+    /// <inheritdoc />
+    public void SetScreenSize (int width, int height) { throw new NotImplementedException ("SetScreenSize is only supported by FakeDriver for testing purposes."); }
+
     /// <inheritdoc />
     public event EventHandler<SizeChangedEventArgs>? SizeChanged;