浏览代码

Add comprehensive XML documentation for FakeDriver resize APIs and driver screen properties

Co-authored-by: tig <[email protected]>
copilot-swe-agent[bot] 1 月之前
父节点
当前提交
7f38a5b0a7

+ 103 - 6
Terminal.Gui/Drivers/ConsoleDriver.cs

@@ -57,7 +57,24 @@ public abstract class ConsoleDriver : IConsoleDriver
     internal bool []? _dirtyLines;
 
     // QUESTION: When non-full screen apps are supported, will this represent the app size, or will that be in Application?
-    /// <summary>Gets the location and size of the terminal screen.</summary>
+    /// <summary>
+    ///     Gets the location and size of the terminal screen. This is the single source of truth for
+    ///     the available drawing area.
+    /// </summary>
+    /// <remarks>
+    ///     <para>
+    ///         The screen rectangle always has origin (0,0) and size determined by <see cref="Cols"/> and <see cref="Rows"/>.
+    ///         When the terminal is resized, <see cref="Cols"/> and <see cref="Rows"/> are updated, and the
+    ///         <see cref="SizeChanged"/> event is fired.
+    ///     </para>
+    ///     <para>
+    ///         In production drivers (WindowsDriver, UnixDriver, DotNetDriver), this reflects the actual terminal size.
+    ///         In <see cref="FakeDriver"/>, this can be controlled programmatically via <c>SetBufferSize</c> for testing.
+    ///     </para>
+    /// </remarks>
+    /// <seealso cref="Cols"/>
+    /// <seealso cref="Rows"/>
+    /// <seealso cref="SizeChanged"/>
     public Rectangle Screen => new (0, 0, Cols, Rows);
 
     private Region? _clip;
@@ -93,7 +110,25 @@ public abstract class ConsoleDriver : IConsoleDriver
     /// </summary>
     public int Col { get; private set; }
 
-    /// <summary>The number of columns visible in the terminal.</summary>
+    /// <summary>
+    ///     Gets or sets the number of columns visible in the terminal. This property, along with <see cref="Rows"/>,
+    ///     defines the dimensions of the <see cref="Screen"/> rectangle.
+    /// </summary>
+    /// <remarks>
+    ///     <para>
+    ///         In production drivers, this value reflects the actual terminal width and is updated when
+    ///         the terminal is resized. In <see cref="FakeDriver"/>, this can be set programmatically
+    ///         via <c>SetBufferSize</c> or <c>SetWindowSize</c> for testing.
+    ///     </para>
+    ///     <para>
+    ///         <strong>Warning:</strong> Setting this property directly clears the contents buffer.
+    ///         Prefer using resize methods (<c>SetBufferSize</c> in FakeDriver) that properly handle
+    ///         the resize sequence including firing <see cref="SizeChanged"/> events.
+    ///     </para>
+    /// </remarks>
+    /// <seealso cref="Rows"/>
+    /// <seealso cref="Screen"/>
+    /// <seealso cref="SizeChanged"/>
     public virtual int Cols
     {
         get => _cols;
@@ -157,7 +192,25 @@ public abstract class ConsoleDriver : IConsoleDriver
     /// </summary>
     public int Row { get; private set; }
 
-    /// <summary>The number of rows visible in the terminal.</summary>
+    /// <summary>
+    ///     Gets or sets the number of rows visible in the terminal. This property, along with <see cref="Cols"/>,
+    ///     defines the dimensions of the <see cref="Screen"/> rectangle.
+    /// </summary>
+    /// <remarks>
+    ///     <para>
+    ///         In production drivers, this value reflects the actual terminal height and is updated when
+    ///         the terminal is resized. In <see cref="FakeDriver"/>, this can be set programmatically
+    ///         via <c>SetBufferSize</c> or <c>SetWindowSize</c> for testing.
+    ///     </para>
+    ///     <para>
+    ///         <strong>Warning:</strong> Setting this property directly clears the contents buffer.
+    ///         Prefer using resize methods (<c>SetBufferSize</c> in FakeDriver) that properly handle
+    ///         the resize sequence including firing <see cref="SizeChanged"/> events.
+    ///     </para>
+    /// </remarks>
+    /// <seealso cref="Cols"/>
+    /// <seealso cref="Screen"/>
+    /// <seealso cref="SizeChanged"/>
     public virtual int Rows
     {
         get => _rows;
@@ -508,8 +561,27 @@ public abstract class ConsoleDriver : IConsoleDriver
         }
     }
 
-    /// <summary>Called when the terminal size changes. Fires the <see cref="SizeChanged"/> event.</summary>
-    /// <param name="args"></param>
+    /// <summary>
+    ///     Called when the terminal screen size changes. This method fires the <see cref="SizeChanged"/> event,
+    ///     notifying subscribers that <see cref="Screen"/>, <see cref="Cols"/>, and <see cref="Rows"/> have changed.
+    /// </summary>
+    /// <remarks>
+    ///     <para>
+    ///         This method is typically called internally by the driver when it detects a terminal resize.
+    ///         For <see cref="FakeDriver"/>, it is called by <c>SetBufferSize</c> and <c>SetWindowSize</c> methods.
+    ///     </para>
+    ///     <para>
+    ///         <strong>For driver implementations:</strong> Call this method after updating <see cref="Cols"/> and
+    ///         <see cref="Rows"/> to notify the application that the screen dimensions have changed.
+    ///     </para>
+    ///     <para>
+    ///         <strong>For application code:</strong> Subscribe to the <see cref="SizeChanged"/> event to respond
+    ///         to screen size changes rather than calling this method directly.
+    ///     </para>
+    /// </remarks>
+    /// <param name="args">Event arguments containing the new screen size.</param>
+    /// <seealso cref="SizeChanged"/>
+    /// <seealso cref="Screen"/>
     public void OnSizeChanged (SizeChangedEventArgs args) { SizeChanged?.Invoke (this, args); }
 
     /// <summary>Updates the screen to reflect all the changes that have been done to the display buffer</summary>
@@ -531,7 +603,32 @@ public abstract class ConsoleDriver : IConsoleDriver
     /// <returns><see langword="true"/> upon success</returns>
     public abstract bool SetCursorVisibility (CursorVisibility visibility);
 
-    /// <summary>The event fired when the terminal is resized.</summary>
+    /// <summary>
+    ///     Event fired when the terminal screen is resized. Provides the new screen dimensions via
+    ///     <see cref="SizeChangedEventArgs"/>.
+    /// </summary>
+    /// <remarks>
+    ///     <para>
+    ///         This event is raised by <see cref="OnSizeChanged"/> when the driver detects or is notified
+    ///         of a terminal size change. At the time this event fires, <see cref="Cols"/>, <see cref="Rows"/>,
+    ///         and <see cref="Screen"/> have already been updated to reflect the new dimensions.
+    ///     </para>
+    ///     <para>
+    ///         <strong>In production drivers:</strong> This event fires when the OS notifies the driver of a
+    ///         terminal window resize (e.g., SIGWINCH on Unix, WINDOW_BUFFER_SIZE_EVENT on Windows).
+    ///     </para>
+    ///     <para>
+    ///         <strong>In FakeDriver:</strong> This event fires when test code calls <c>SetBufferSize</c> or
+    ///         <c>SetWindowSize</c>, allowing tests to simulate and verify resize behavior.
+    ///     </para>
+    ///     <para>
+    ///         <strong>Usage in Application:</strong> <see cref="Application"/> subscribes to this event
+    ///         during initialization and propagates resize notifications to top-level views, triggering layout
+    ///         and redraw operations.
+    ///     </para>
+    /// </remarks>
+    /// <seealso cref="OnSizeChanged"/>
+    /// <seealso cref="Screen"/>
     public event EventHandler<SizeChangedEventArgs>? SizeChanged;
 
     #endregion Cursor Handling

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

@@ -378,6 +378,46 @@ public class FakeDriver : ConsoleDriver
     /// <inheritdoc />
     internal override IAnsiResponseParser GetParser () => _parser;
 
+    /// <summary>
+    ///     Sets the size of the fake console screen/buffer for testing purposes. This method updates
+    ///     the driver's dimensions (<see cref="ConsoleDriver.Cols"/> and <see cref="ConsoleDriver.Rows"/>),
+    ///     clears the contents, and fires the <see cref="ConsoleDriver.SizeChanged"/> event.
+    /// </summary>
+    /// <remarks>
+    ///     <para>
+    ///         This method is intended for use in unit tests to simulate terminal resize events.
+    ///         For FakeDriver, the buffer size and window size are always the same (there is no scrollback).
+    ///     </para>
+    ///     <para>
+    ///         When called, this method:
+    ///         <list type="number">
+    ///             <item>Updates the <see cref="FakeConsole"/> buffer size</item>
+    ///             <item>Sets <see cref="ConsoleDriver.Cols"/> and <see cref="ConsoleDriver.Rows"/> to the new dimensions</item>
+    ///             <item>Updates the window size to match</item>
+    ///             <item>Clears the screen contents</item>
+    ///             <item>Fires the <see cref="ConsoleDriver.SizeChanged"/> event</item>
+    ///         </list>
+    ///     </para>
+    ///     <para>
+    ///         <strong>Thread Safety:</strong> This method is not thread-safe. Tests using this method
+    ///         should ensure they are not accessing the driver concurrently.
+    ///     </para>
+    ///     <para>
+    ///         <strong>Relationship to Screen property:</strong> After calling this method, 
+    ///         <see cref="ConsoleDriver.Screen"/> will return a rectangle with origin (0,0) and size (width, height).
+    ///     </para>
+    /// </remarks>
+    /// <param name="width">The new width in columns.</param>
+    /// <param name="height">The new height in rows.</param>
+    /// <example>
+    ///     <code>
+    ///     // Simulate a terminal resize to 120x30
+    ///     var driver = new FakeDriver();
+    ///     driver.SetBufferSize(120, 30);
+    ///     Assert.Equal(120, driver.Cols);
+    ///     Assert.Equal(30, driver.Rows);
+    ///     </code>
+    /// </example>
     public void SetBufferSize (int width, int height)
     {
         FakeConsole.SetBufferSize (width, height);
@@ -387,6 +427,24 @@ public class FakeDriver : ConsoleDriver
         ProcessResize ();
     }
 
+    /// <summary>
+    ///     Sets the window size of the fake console. For FakeDriver, this is functionally equivalent to
+    ///     <see cref="SetBufferSize"/> as the fake console does not support scrollback (window size == buffer size).
+    /// </summary>
+    /// <remarks>
+    ///     <para>
+    ///         This method exists for API compatibility with real console drivers, but in FakeDriver,
+    ///         the window size and buffer size are always kept in sync. Calling this method will update
+    ///         both the window and buffer to the specified size.
+    ///     </para>
+    ///     <para>
+    ///         Prefer using <see cref="SetBufferSize"/> for clarity in test code, as it more accurately
+    ///         describes what's happening (setting the entire screen size for the fake driver).
+    ///     </para>
+    /// </remarks>
+    /// <param name="width">The new width in columns.</param>
+    /// <param name="height">The new height in rows.</param>
+    /// <seealso cref="SetBufferSize"/>
     public void SetWindowSize (int width, int height)
     {
         FakeConsole.SetWindowSize (width, height);

+ 48 - 2
Tests/UnitTests/AutoInitShutdownAttribute.cs

@@ -155,9 +155,55 @@ public class AutoInitShutdownAttribute : BeforeAfterTestAttribute
     private bool AutoInit { get; }
 
     /// <summary>
-    /// 'Resizes' the application and forces layout. Only works if your test uses <see cref="AutoInitShutdownAttribute"/>
+    ///     Simulates a terminal resize in tests that use <see cref="AutoInitShutdownAttribute"/>.
+    ///     This method updates the driver's output buffer size, triggers size change events,
+    ///     and forces a layout/draw cycle.
     /// </summary>
-    /// <param name="size"></param>
+    /// <remarks>
+    ///     <para>
+    ///         This method is designed for use in unit tests to simulate terminal resize events.
+    ///         It works with both the fluent testing infrastructure (<see cref="FakeSizeMonitor"/>) and
+    ///         the library's built-in <see cref="FakeWindowSizeMonitor"/>.
+    ///     </para>
+    ///     <para>
+    ///         The method performs the following operations:
+    ///         <list type="number">
+    ///             <item>Updates the output buffer size via <see cref="IOutputBuffer.SetWindowSize"/></item>
+    ///             <item>Raises the size changing event through the appropriate size monitor</item>
+    ///             <item>Forces a layout and draw cycle via <see cref="Application.LayoutAndDraw"/></item>
+    ///         </list>
+    ///     </para>
+    ///     <para>
+    ///         <strong>Thread Safety:</strong> This method is not thread-safe. Tests using FakeResize
+    ///         should not run in parallel if they share driver state.
+    ///     </para>
+    ///     <para>
+    ///         <strong>Requirements:</strong> Your test must use <see cref="AutoInitShutdownAttribute"/>
+    ///         with autoInit=true for this method to work correctly.
+    ///     </para>
+    /// </remarks>
+    /// <param name="size">The new terminal size (width, height).</param>
+    /// <exception cref="InvalidOperationException">
+    ///     Thrown if <see cref="Application.Driver"/> is null or not initialized.
+    /// </exception>
+    /// <example>
+    ///     <code>
+    ///     [Fact]
+    ///     [AutoInitShutdown]
+    ///     public void TestResize()
+    ///     {
+    ///         // Initial size is 80x25
+    ///         Assert.Equal(80, Application.Driver.Cols);
+    ///         
+    ///         // Simulate resize to 120x30
+    ///         AutoInitShutdownAttribute.FakeResize(new Size(120, 30));
+    ///         
+    ///         // Verify new size
+    ///         Assert.Equal(120, Application.Driver.Cols);
+    ///         Assert.Equal(30, Application.Driver.Rows);
+    ///     }
+    ///     </code>
+    /// </example>
     public static void FakeResize (Size size)
     {
         var d = (IConsoleDriverFacade)Application.Driver!;