using System.Collections.Concurrent; using System.Drawing; using Terminal.Gui; namespace TerminalGuiFluentAssertions; class FakeInput : IConsoleInput { /// public void Dispose () { } /// public void Initialize (ConcurrentQueue inputBuffer) { } /// public void Run (CancellationToken token) { // Simulate an infinite loop that checks for cancellation token.WaitHandle.WaitOne (); // Blocks until the token is cancelled } } class FakeNetInput : FakeInput, INetInput { } class FakeWindowsInput : FakeInput, IWindowsInput { } class FakeOutput : IConsoleOutput { public Size Size { get; set; } /// public void Dispose () { } /// public void Write (ReadOnlySpan text) { } /// public void Write (IOutputBuffer buffer) { } /// public Size GetWindowSize () { return Size; } /// public void SetCursorVisibility (CursorVisibility visibility) { } /// public void SetCursorPosition (int col, int row) { } } /// /// Entry point to fluent assertions. /// public static class With { /// /// Entrypoint to fluent assertions /// /// /// /// public static GuiTestContext A (int width, int height) where T : Toplevel, new () { return new GuiTestContext (width,height); } } public class GuiTestContext where T : Toplevel, new() { private readonly CancellationTokenSource _cts; private readonly Task _runTask; internal GuiTestContext (int width, int height) { IApplication origApp = ApplicationImpl.Instance; var netInput = new FakeNetInput (); var winInput = new FakeWindowsInput (); var output = new FakeOutput (); output.Size = new (width, height); var v2 = new ApplicationV2( () => netInput, ()=>output, () => winInput, () => output); // Create a cancellation token _cts = new (); // Start the application in a background thread _runTask = Task.Run (() => { try { ApplicationImpl.ChangeInstance (v2); v2.Init (); Application.Run (); // This will block, but it's on a background thread now Application.Shutdown (); } catch (OperationCanceledException) { } finally { ApplicationImpl.ChangeInstance (origApp); } }, _cts.Token); Application.Shutdown (); } /// /// Stops the application and waits for the background thread to exit. /// public void Stop () { _cts.Cancel (); Application.Invoke (()=>Application.RequestStop()); _runTask.Wait (); // Ensure the background thread exits } // Cleanup to avoid state bleed between tests public void Dispose () { } }