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

Co-authored-by: tig <585482+tig@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2025-10-27 02:21:41 +00:00
parent 120cf15637
commit 7f38a5b0a7
3 changed files with 209 additions and 8 deletions

View File

@@ -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

View File

@@ -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);

View File

@@ -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!;