Fixes #4332 - Refactor test infrastructure to use modern ApplicationImpl.Coordinator instead of legacy MainLoop (#4335)

* Initial plan

* Refactor tests to use modern ApplicationImpl.Coordinator architecture instead of legacy Application.RunIteration

Co-authored-by: tig <585482+tig@users.noreply.github.com>

* Changes before error encountered

Co-authored-by: tig <585482+tig@users.noreply.github.com>

* Replace Application.RunIteration implementation to use modern ApplicationImpl.Coordinator architecture

Co-authored-by: tig <585482+tig@users.noreply.github.com>

* Simplify Application.RunIteration to directly delegate to ApplicationImpl.Coordinator without legacy infrastructure

Co-authored-by: tig <585482+tig@users.noreply.github.com>

* Update multitasking.md documentation to use Application.AddTimeout/RemoveTimeout instead of deprecated Application.MainLoop methods

Co-authored-by: tig <585482+tig@users.noreply.github.com>

* Refactor contribution guidelines and documentation

- Consolidated all contribution-related instructions into `CONTRIBUTING.md` as the single source of truth.
- Updated `copilot-instructions.md` and `AGENTS.md` to reference `CONTRIBUTING.md`.
- Enhanced build, test, and CI/CD workflow documentation.
- Updated repository structure documentation in `README.md` and `CONTRIBUTING.md`.
- Reinforced coding conventions and streamlined testing requirements.
- Documented GitHub Actions workflows and provided local CI replication steps.
- Refined API documentation requirements and PR guidelines.
- Simplified `.sln` file and removed redundant content.
- Updated links to point to the latest documentation resources.

* Revamp bug report template for clarity and detail

Updated the bug report template to improve structure, readability, and comprehensiveness:
- Specified "Terminal.Gui" in the `about` section.
- Replaced bold headings with Markdown heading syntax.
- Enhanced "To Reproduce" with placeholders for code and behavior details.
- Added an "Environment" section to collect OS, terminal, PowerShell, .NET, and `Terminal.Gui` version details.
- Expanded "Screenshots" to include GIFs and terminal output instructions.
- Removed outdated "Desktop" and "Smartphone" sections, consolidating relevant details.
- Improved "Additional Context" with prompts for consistency, prior behavior, and error messages.
- Streamlined "For Maintainers" instructions for setting project and milestone.

These changes aim to make bug reports more actionable and easier to reproduce.

* Remove [Obsolete] attribute and pragma warnings from Application.RunIteration - method now uses modern architecture internally

Co-authored-by: tig <585482+tig@users.noreply.github.com>

* Refactor Application.Run.cs for clarity and cleanup

Removed debug assertions and unused/commented-out code to simplify logic and improve maintainability. Renamed `forceDraw` to `forceRedraw` in `LayoutAndDraw` for better clarity. Removed the internal `OnNotifyStopRunState` method and its associated logic, indicating a refactor of the stop notification mechanism.

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Tig <tig@users.noreply.github.com>
Co-authored-by: tig <585482+tig@users.noreply.github.com>
This commit is contained in:
Copilot
2025-10-26 09:15:46 -06:00
committed by GitHub
parent 1046b47be7
commit aef88ad4bb
17 changed files with 570 additions and 912 deletions

View File

@@ -584,7 +584,7 @@ public class ApplicationTests
[AutoInitShutdown]
public void Invoke_Adds_Idle ()
{
var top = new Toplevel ();
Toplevel top = new ();
RunState rs = Application.Begin (top);
var actionCalled = 0;

View File

@@ -20,8 +20,8 @@ public class WizardTests ()
public void Finish_Button_Closes ()
{
// https://github.com/gui-cs/Terminal.Gui/issues/1833
var wizard = new Wizard ();
var step1 = new WizardStep { Title = "step1" };
Wizard wizard = new ();
WizardStep step1 = new () { Title = "step1" };
wizard.AddStep (step1);
var finishedFired = false;
@@ -31,11 +31,10 @@ public class WizardTests ()
wizard.Closed += (s, e) => { closedFired = true; };
RunState runstate = Application.Begin (wizard);
var firstIteration = true;
Application.RunIteration (ref runstate, firstIteration);
AutoInitShutdownAttribute.RunIteration ();
wizard.NextFinishButton.InvokeCommand (Command.Accept);
Application.RunIteration (ref runstate, firstIteration);
AutoInitShutdownAttribute.RunIteration ();
Application.End (runstate);
Assert.True (finishedFired);
Assert.True (closedFired);
@@ -44,10 +43,9 @@ public class WizardTests ()
// Same test, but with two steps
wizard = new ();
firstIteration = false;
step1 = new() { Title = "step1" };
wizard.AddStep (step1);
var step2 = new WizardStep { Title = "step2" };
WizardStep step2 = new () { Title = "step2" };
wizard.AddStep (step2);
finishedFired = false;
@@ -57,7 +55,7 @@ public class WizardTests ()
wizard.Closed += (s, e) => { closedFired = true; };
runstate = Application.Begin (wizard);
Application.RunIteration (ref runstate, firstIteration);
AutoInitShutdownAttribute.RunIteration ();
Assert.Equal (step1.Title, wizard.CurrentStep.Title);
wizard.NextFinishButton.InvokeCommand (Command.Accept);
@@ -77,7 +75,6 @@ public class WizardTests ()
// Same test, but with two steps but the 1st one disabled
wizard = new ();
firstIteration = false;
step1 = new() { Title = "step1" };
wizard.AddStep (step1);
step2 = new() { Title = "step2" };
@@ -91,7 +88,7 @@ public class WizardTests ()
wizard.Closed += (s, e) => { closedFired = true; };
runstate = Application.Begin (wizard);
Application.RunIteration (ref runstate, firstIteration);
AutoInitShutdownAttribute.RunIteration ();
Assert.Equal (step2.Title, wizard.CurrentStep.Title);
Assert.Equal (wizard.GetLastStep ().Title, wizard.CurrentStep.Title);
@@ -458,13 +455,12 @@ public class WizardTests ()
Glyphs.LRCornerDbl
}";
var wizard = new Wizard { Title = title, Width = width, Height = height };
Wizard wizard = new () { Title = title, Width = width, Height = height };
wizard.AddStep (new() { Title = stepTitle });
//wizard.LayoutSubViews ();
var firstIteration = false;
RunState runstate = Application.Begin (wizard);
Application.RunIteration (ref runstate, firstIteration);
AutoInitShutdownAttribute.RunIteration ();
// TODO: Disabled until Dim.Auto is used in Dialog
//DriverAsserts.AssertDriverContentsWithFrameAre (

View File

@@ -222,7 +222,7 @@ public class BorderTests (ITestOutputHelper output)
[InlineData (10)]
public void Border_With_Title_Border_Double_Thickness_Top_Three_Size_Width (int width)
{
var win = new Window
Window win = new ()
{
Title = "1234", Width = Dim.Fill (), Height = Dim.Fill (), BorderStyle = LineStyle.Double
};
@@ -231,7 +231,7 @@ public class BorderTests (ITestOutputHelper output)
RunState rs = Application.Begin (win);
AutoInitShutdownAttribute.FakeResize(new Size(width, 4));
Application.RunIteration (ref rs, false);
AutoInitShutdownAttribute.RunIteration ();
var expected = string.Empty;
switch (width)

View File

@@ -321,7 +321,7 @@ public class ClearViewportTests (ITestOutputHelper output)
{
ConfigurationManager.Enable (ConfigLocations.LibraryResources);
var root = new View { Width = 20, Height = 10 };
View root = new () { Width = 20, Height = 10 };
string text = new ('c', 100);
@@ -335,10 +335,10 @@ public class ClearViewportTests (ITestOutputHelper output)
root.Add (v);
var top = new Toplevel ();
Toplevel top = new ();
top.Add (root);
RunState runState = Application.Begin (top);
Application.RunIteration (ref runState);
AutoInitShutdownAttribute.RunIteration ();
if (label)
{

View File

@@ -91,20 +91,20 @@ public class LabelTests (ITestOutputHelper output)
[AutoInitShutdown]
public void Label_Draw_Fill_Remaining ()
{
var tfSize = new Size (80, 1);
Size tfSize = new (80, 1);
var label = new Label { Text = "This label needs to be cleared before rewritten.", Width = tfSize.Width, Height = tfSize.Height };
Label label = new () { Text = "This label needs to be cleared before rewritten.", Width = tfSize.Width, Height = tfSize.Height };
var tf1 = new TextFormatter { Direction = TextDirection.LeftRight_TopBottom, ConstrainToSize = tfSize };
TextFormatter tf1 = new () { Direction = TextDirection.LeftRight_TopBottom, ConstrainToSize = tfSize };
tf1.Text = "This TextFormatter (tf1) without fill will not be cleared on rewritten.";
var tf2 = new TextFormatter { Direction = TextDirection.LeftRight_TopBottom, ConstrainToSize = tfSize, FillRemaining = true };
TextFormatter tf2 = new () { Direction = TextDirection.LeftRight_TopBottom, ConstrainToSize = tfSize, FillRemaining = true };
tf2.Text = "This TextFormatter (tf2) with fill will be cleared on rewritten.";
var top = new Toplevel ();
Toplevel top = new ();
top.Add (label);
RunState runState = Application.Begin (top);
Application.RunIteration (ref runState);
AutoInitShutdownAttribute.RunIteration ();
Assert.False (label.TextFormatter.FillRemaining);
Assert.False (tf1.FillRemaining);

View File

@@ -467,7 +467,7 @@ public class MenuBarv1Tests (ITestOutputHelper output)
Button.DefaultShadow = ShadowStyle.None;
Toplevel top = new ();
var win = new Window ();
Window win = new ();
top.Add (win);
RunState rsTop = Application.Begin (top);
AutoInitShutdownAttribute.FakeResize(new Size(40, 15)) ;
@@ -503,8 +503,8 @@ public class MenuBarv1Tests (ITestOutputHelper output)
"Save As",
"Delete"
};
var dialog = new Dialog { X = 2, Y = 2, Width = 15, Height = 4 };
var menu = new MenuBar { X = Pos.Center (), Width = 10 };
Dialog dialog = new () { X = 2, Y = 2, Width = 15, Height = 4 };
MenuBar menu = new () { X = Pos.Center (), Width = 10 };
menu.Menus = new MenuBarItem []
{
@@ -572,7 +572,7 @@ public class MenuBarv1Tests (ITestOutputHelper output)
}
RunState rsDialog = Application.Begin (dialog);
Application.RunIteration (ref rsDialog);
AutoInitShutdownAttribute.RunIteration ();
Assert.Equal (new (2, 2, 15, 4), dialog.Frame);
@@ -598,7 +598,7 @@ public class MenuBarv1Tests (ITestOutputHelper output)
Assert.Equal ("File", menu.Menus [0].Title);
menu.OpenMenu ();
Application.RunIteration (ref rsDialog);
AutoInitShutdownAttribute.RunIteration ();
DriverAssert.AssertDriverContentsWithFrameAre (
@"
@@ -624,8 +624,7 @@ public class MenuBarv1Tests (ITestOutputHelper output)
// Need to fool MainLoop into thinking it's running
Application.MainLoop.Running = true;
bool firstIteration = true;
Application.RunIteration (ref rsDialog, firstIteration);
AutoInitShutdownAttribute.RunIteration ();
Assert.Equal (items [0], menu.Menus [0].Title);
DriverAssert.AssertDriverContentsWithFrameAre (
@@ -654,13 +653,13 @@ public class MenuBarv1Tests (ITestOutputHelper output)
Application.RaiseMouseEvent (new () { ScreenPosition = new (20, 5 + i), Flags = MouseFlags.Button1Clicked });
Application.RunIteration (ref rsDialog);
AutoInitShutdownAttribute.RunIteration ();
Assert.Equal (items [i], menu.Menus [0].Title);
}
AutoInitShutdownAttribute.FakeResize(new Size(20, 15));
menu.OpenMenu ();
Application.RunIteration (ref rsDialog);
AutoInitShutdownAttribute.RunIteration ();
DriverAssert.AssertDriverContentsWithFrameAre (
@"

View File

@@ -4813,7 +4813,7 @@ This is the second line.
public void Selected_Text_Shows ()
{
// Proves #3022 is fixed (TextField selected text does not show in v2)
var top = new Toplevel ();
Toplevel top = new ();
top.Add (_textView);
RunState rs = Application.Begin (top);
@@ -4833,7 +4833,7 @@ This is the second line.
_textView.NewKeyDownEvent (Key.CursorRight.WithCtrl.WithShift);
Application.RunIteration (ref rs, true);
AutoInitShutdownAttribute.RunIteration ();
Assert.Equal (new (4, 0), _textView.CursorPosition);
// TAB to jump between text fields.