Phase 1: Add SetScreenSize API to IConsoleDriver and implementations

Co-authored-by: tig <585482+tig@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2025-10-27 03:29:15 +00:00
parent 3d701152a3
commit 21c0335018
7 changed files with 109 additions and 13 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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);
}
else if (d.WindowSizeMonitor is FakeWindowSizeMonitor fakeWindowSizeMonitor)
{
// For FakeWindowSizeMonitor, use the RaiseSizeChanging method
fakeWindowSizeMonitor.RaiseSizeChanging (size);
return;
}
// Try the library FakeDriver first - it has SetScreenSize implemented
if (Application.Driver is FakeDriver fakeDriver)
{
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);
}

View File

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