From 98f0126a9feed008f0ac930164585552b10064d4 Mon Sep 17 00:00:00 2001 From: BDisp Date: Tue, 3 Mar 2026 22:53:22 +0000 Subject: [PATCH 01/29] Upgrade nuget packages, rename TestContext to FluentTestContext and remove using Xunit.Abstractions --- Directory.Packages.props | 62 +- Examples/ReactiveExample/LoginView.cs | 3 +- Examples/ReactiveExample/Program.cs | 13 +- Examples/ScenarioRunner/Program.cs | 270 ++++--- Examples/UICatalog/UICatalog.cs | 111 +-- Tests/IntegrationTests/DialogTests.cs | 3 - .../FluentTests/FileDialogTests.cs | 25 +- .../FluentTests/LinearRangeFluentTests.cs | 149 ++-- .../FluentTests/MenuBarTests.cs | 745 +++++++++--------- .../FluentTests/NavigationTests.cs | 97 ++- .../FluentTests/PopverMenuTests.cs | 471 ++++++----- .../FluentTests/TestContextKeyEventTests.cs | 199 +++-- .../FluentTests/TestContextMouseEventTests.cs | 109 ++- .../FluentTests/TestContextTests.cs | 65 +- .../FluentTests/TextFieldTests.cs | 33 +- .../FluentTests/TreeViewTests.cs | 5 +- .../IntegrationTests/IntegrationTests.csproj | 12 +- Tests/IntegrationTests/TestOutputWriter.cs | 1 - Tests/StressTests/ApplicationStressTests.cs | 3 +- Tests/StressTests/ScenariosStressTests.cs | 1 - Tests/StressTests/StressTests.csproj | 12 +- .../TestContext.ContextMenu.cs | 4 +- .../TestContext.Input.cs | 16 +- .../TestContext.Navigation.cs | 6 +- .../TestContext.ViewBase.cs | 4 +- Tests/TerminalGuiFluentTesting/TestContext.cs | 24 +- Tests/TerminalGuiFluentTesting/With.cs | 4 +- .../TheGenerator.cs | 10 +- .../TerminalGuiFluentTestingXunit.csproj | 7 +- .../XunitContextExtensions.cs | 2 +- .../Application/ApplicationScreenTests.cs | 4 +- .../Mouse/ApplicationMouseTests.cs | 1 - Tests/UnitTests/AutoInitShutdownAttribute.cs | 6 +- .../Configuration/ConfigurationMangerTests.cs | 1 - .../Configuration/ThemeManagerTests.cs | 4 - Tests/UnitTests/DriverAssert.cs | 1 - .../UnitTests/FileServices/FileDialogTests.cs | 2 - Tests/UnitTests/OutputAssert.cs | 4 +- .../SetupFakeApplicationAttribute.cs | 10 +- Tests/UnitTests/TestDriverBase.cs | 1 - .../TestRespondersDisposedAttribute.cs | 12 +- Tests/UnitTests/Text/AutocompleteTests.cs | 1 - Tests/UnitTests/UICatalog/RunnerTests.cs | 1 - .../UICatalog/ScenarioLogCaptureTests.cs | 1 - Tests/UnitTests/UICatalog/ScenarioTests.cs | 1 - Tests/UnitTests/UnitTests.csproj | 2 +- .../View/Adornment/AdornmentTests.cs | 5 +- Tests/UnitTests/View/Adornment/BorderTests.cs | 4 +- .../UnitTests/View/Adornment/PaddingTests.cs | 5 +- .../View/Adornment/ShadowStyleTests.cs | 4 +- Tests/UnitTests/View/ArrangementTests.cs | 4 +- Tests/UnitTests/View/DiagnosticsTests.cs | 2 - Tests/UnitTests/View/Draw/ClipTests.cs | 2 - Tests/UnitTests/View/Draw/DrawTests.cs | 2 - Tests/UnitTests/View/Draw/TransparentTests.cs | 2 - Tests/UnitTests/View/Layout/Dim.Tests.cs | 2 - Tests/UnitTests/View/Layout/Pos.ViewTests.cs | 2 - Tests/UnitTests/View/SubviewTests.cs | 4 +- Tests/UnitTests/View/TextTests.cs | 2 - Tests/UnitTests/View/ViewTests.cs | 8 +- .../Views/AppendAutocompleteTests.cs | 3 - Tests/UnitTests/Views/ButtonTests.cs | 4 - Tests/UnitTests/Views/CheckBoxTests.cs | 4 - Tests/UnitTests/Views/ComboBoxTests.cs | 1 - Tests/UnitTests/Views/FrameViewTests.cs | 5 +- Tests/UnitTests/Views/GraphViewTests.cs | 2 - Tests/UnitTests/Views/LabelTests.cs | 1 - Tests/UnitTests/Views/MessageBoxTests.cs | 1 - Tests/UnitTests/Views/ScrollBarTests.cs | 5 +- Tests/UnitTests/Views/SpinnerViewTests.cs | 5 +- Tests/UnitTests/Views/TabViewTests.cs | 2 - Tests/UnitTests/Views/TableViewTests.cs | 1 - Tests/UnitTests/Views/TextFieldTests.cs | 12 +- .../UnitTests/Views/TextViewTests.History.cs | 1 - Tests/UnitTests/Views/TextViewTests.cs | 12 +- Tests/UnitTests/Views/TreeTableSourceTests.cs | 2 - Tests/UnitTests/Views/TreeViewTests.cs | 1 - Tests/UnitTests/Views/ViewDisposalTest.cs | 2 - Tests/UnitTests/Views/WindowTests.cs | 3 - .../Application.NavigationTests.cs | 4 +- .../Application/BeginEndTests.cs | 2 - .../Application/CursorTests.cs | 2 - .../Application/InitTests.cs | 1 - .../Application/LoggingTests.cs | 1 - .../Application/Mouse/MouseInterfaceTests.cs | 2 - .../Popover/PopoverBaseImplTests.cs | 1 - .../Application/RunTests.cs | 1 - .../Runnable/RunnableEdgeCasesTests.cs | 2 - .../Runnable/RunnableIntegrationTests.cs | 1 - .../Runnable/RunnableLifecycleTests.cs | 1 - .../Runnable/RunnableSessionTokenTests.cs | 3 - .../Application/Runnable/RunnableTests.cs | 3 - .../Application/ScreeenTests.cs | 2 - .../Timeouts/NestedRunTimeoutTests.cs | 3 - .../Application/Timeouts/TimeoutTests.cs | 1 - .../Drawing/AlignerTests.cs | 1 - .../Color/StandardColorNameResolverTests.cs | 4 +- .../Drawing/Lines/LineCanvasTests.cs | 2 - .../Lines/StraightLineExtensionsTests.cs | 2 - .../Drawing/Lines/StraightLineTests.cs | 4 +- .../Drawing/Region/DrawOuterBoundaryTests.cs | 2 - .../Drawing/RulerTests.cs | 2 - .../SchemeTests.ColorNoneDerivationTests.cs | 1 - .../Drawing/ThicknessTests.cs | 2 - .../Drivers/AllDriverTests.cs | 1 - .../Drivers/Ansi/AnsiInputOutputTests.cs | 1 - .../Drivers/AnsiDriver/AnsiDriverTests.cs | 1 - .../AnsiHandling/AnsiKeyboardEncoderTests.cs | 4 +- .../AnsiHandling/AnsiMouseParserDebugTests.cs | 2 - .../AnsiHandling/AnsiResponseParserTests.cs | 1 - .../AnsiHandling/UrlHyperlinkerTests.cs | 1 - .../Drivers/Dotnet/NetInputOutputTests.cs | 1 - .../Drivers/Keyboard/KeyCodeTests.cs | 4 +- .../MouseButtonClickTrackerTests.cs | 4 +- .../MouseInterpreterExtendedTests.cs | 4 +- .../Drivers/Output/AddRuneTests.cs | 1 - .../Drivers/Output/ClipRegionTests.cs | 1 - .../Drivers/Output/ContentsTests.cs | 1 - .../Drivers/PlatformDetectionTests.cs | 1 - .../Drivers/Unix/UnixInputOutputTests.cs | 1 - .../Windows/WindowsInputOutputTests.cs | 1 - .../Input/InjectMouseEventTests.cs | 1 - .../Input/InputInjectorTests.cs | 1 - .../Input/InputProcessorImplTests.cs | 1 - .../Input/Keyboard/KeyTests.cs | 1 - .../TestDateAttribute.cs | 10 +- .../Testing/TestLogging.cs | 1 - .../Text/AutocompleteTests.cs | 1 - .../Text/CollectionNavigatorTests.cs | 1 - .../Text/TextFormatterDrawTests.cs | 1 - .../Text/TextFormatterJustificationTests.cs | 1 - .../Text/TextFormatterTests.cs | 1 - .../Tracing/ThreadSafeTraceTests.cs | 1 - .../Tracing/TraceTests.cs | 1 - .../UnitTests.Parallelizable.csproj | 2 +- .../Adornment/AdornmentSubViewTests.cs | 1 - .../Adornment/BorderArrangementTests.cs | 1 - .../ViewBase/Adornment/MarginTests.cs | 1 - .../ViewBase/Adornment/ShadowTests.cs | 1 - .../ViewBase/Adornment/ToScreenTests.cs | 4 +- .../ViewBase/ArrangementTests.cs | 4 +- .../ViewBase/Draw/ClearViewportTests.cs | 1 - .../Draw/ViewDrawTextAndLineCanvasTests.cs | 4 +- .../ViewBase/Draw/ViewDrawingClippingTests.cs | 1 - .../ViewBase/Draw/ViewDrawingFlowTests.cs | 1 - .../ViewBase/InitTests.cs | 4 +- .../ViewBase/Keyboard/KeyboardEventTests.cs | 1 - .../ViewBase/Layout/ContentSizeTests.cs | 2 - .../ViewBase/Layout/Dim.AutoTests.cs | 1 - .../ViewBase/Layout/Dim.CombineTests.cs | 1 - .../ViewBase/Layout/Dim.FillTests.cs | 1 - .../ViewBase/Layout/Dim.FuncTests.cs | 1 - .../ViewBase/Layout/Pos.AbsoluteTests.cs | 1 - .../ViewBase/Layout/Pos.CenterTests.cs | 1 - .../ViewBase/Layout/Pos.CombineTests.cs | 1 - .../ViewBase/Layout/Pos.FuncTests.cs | 1 - .../ViewBase/Layout/Pos.PercentTests.cs | 3 +- .../ViewBase/Layout/TopologicalSortTests.cs | 4 +- .../ViewBase/Layout/ViewportTests.cs | 4 +- .../ViewBase/Mouse/DefaultActivationTests.cs | 2 - .../ViewBase/Mouse/HighlightStatesTests.cs | 1 - .../ViewBase/Mouse/MouseEventRoutingTests.cs | 1 - .../ViewBase/Mouse/MouseHoldRepeatTests.cs | 3 +- .../Mouse/MouseReleasedBindingTests.cs | 2 - .../ViewBase/Mouse/MouseTests.cs | 1 - .../Navigation/AllViewsNavigationTests.cs | 1 - .../ViewBase/Navigation/RestoreFocusTests.cs | 1 - .../ViewBase/Navigation/VisibleTests.cs | 1 - .../ViewBase/TextTests.cs | 1 - .../ViewBase/ViewCommandTests.cs | 1 - .../Views/AllViewsDrawTests.cs | 1 - .../Views/AllViewsTests.cs | 1 - .../Views/DialogTests.cs | 1 - .../Views/IListDataSourceTests.cs | 1 - .../Views/LabelTests.cs | 1 - .../Views/ListViewTests.cs | 3 +- .../Views/MenuBarShowItemTests.cs | 2 - .../Views/MenuBarTests.cs | 1 - .../Views/MenuItemTests.cs | 1 - .../Views/MenuTests.cs | 1 - .../Views/PopoverMenuTests.cs | 1 - .../Views/ScrollSliderTests.cs | 1 - .../Views/ShortcutTests.cs | 2 - .../Views/TextFieldTests.cs | 1 - .../Views/TextModelTests.cs | 1 - .../Views/TextView.AutocompleteTests.cs | 1 - .../Views/TextView.EventsTests.cs | 1 - 187 files changed, 1308 insertions(+), 1510 deletions(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 34805646a7..9abbbd54a7 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -9,40 +9,40 @@ - - - - + + + + - - - - - - - - + + + + + + + + - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + diff --git a/Examples/ReactiveExample/LoginView.cs b/Examples/ReactiveExample/LoginView.cs index 0eb5e7a345..4090d2694d 100644 --- a/Examples/ReactiveExample/LoginView.cs +++ b/Examples/ReactiveExample/LoginView.cs @@ -1,4 +1,5 @@ using System.Reactive.Disposables; +using System.Reactive.Disposables.Fluent; using System.Reactive.Linq; using ReactiveMarbles.ObservableEvents; using ReactiveUI; @@ -138,7 +139,7 @@ public LoginView (LoginViewModel viewModel) ViewModel .WhenAnyObservable (x => x.Login.IsExecuting) .Select (executing => executing ? ProgressMessage : IdleMessage) - .ObserveOn (RxApp.MainThreadScheduler) + .ObserveOn (Program._rxApp.MainThreadScheduler!) .BindTo (progress, x => x.Text) .DisposeWith (_disposable); }); diff --git a/Examples/ReactiveExample/Program.cs b/Examples/ReactiveExample/Program.cs index e70611afc5..fd7572b69d 100644 --- a/Examples/ReactiveExample/Program.cs +++ b/Examples/ReactiveExample/Program.cs @@ -1,5 +1,5 @@ using System.Reactive.Concurrency; -using ReactiveUI; +using ReactiveUI.Builder; using Terminal.Gui.App; using Terminal.Gui.Configuration; @@ -7,14 +7,17 @@ namespace ReactiveExample; public static class Program { - private static void Main (string [] args) + internal static ReactiveUIBuilder _rxApp; + + private static void Main (string [] _) { ConfigurationManager.Enable (ConfigLocations.All); using IApplication app = Application.Create (); app.Init (); - RxApp.MainThreadScheduler = new TerminalScheduler (app); - RxApp.TaskpoolScheduler = TaskPoolScheduler.Default; - var loginView = new LoginView (new ()); + _rxApp = RxAppBuilder.CreateReactiveUIBuilder (); + _rxApp.WithMainThreadScheduler (new TerminalScheduler (app)); + _rxApp.WithTaskPoolScheduler (TaskPoolScheduler.Default); + var loginView = new LoginView (new LoginViewModel ()); app.Run (loginView); loginView.Dispose (); } diff --git a/Examples/ScenarioRunner/Program.cs b/Examples/ScenarioRunner/Program.cs index 4925d55128..b2d353c46d 100644 --- a/Examples/ScenarioRunner/Program.cs +++ b/Examples/ScenarioRunner/Program.cs @@ -1,8 +1,6 @@ #nullable enable using System.Collections.ObjectModel; using System.CommandLine; -using System.CommandLine.Builder; -using System.CommandLine.Parsing; using System.Reflection; using System.Text; using Microsoft.Extensions.Logging; @@ -34,168 +32,178 @@ public static int Main (string [] args) // Get allowed driver names string? [] allowedDrivers = DriverRegistry.GetDriverNames ().ToArray (); - Option driverOption = new Option ("--driver", "The IDriver to use.").FromAmong (allowedDrivers!); - driverOption.SetDefaultValue (string.Empty); - driverOption.AddAlias ("-d"); + Option driverOption = new Option ("--driver") { Description = "The IDriver to use.", DefaultValueFactory = _ => string.Empty }; + driverOption.AcceptOnlyFromAmong (allowedDrivers!); + driverOption.Aliases.Add ("-d"); - Option disableConfigManagement = new ("--disable-cm", "Indicates Configuration Management should not be enabled."); - disableConfigManagement.AddAlias ("-dcm"); + Option disableConfigManagement = new ("--disable-cm") { Description = "Indicates Configuration Management should not be enabled." }; + disableConfigManagement.Aliases.Add ("-dcm"); - Option force16Colors = new ("--force-16-colors", "Forces the driver to use 16-color mode instead of TrueColor."); - force16Colors.AddAlias ("-16"); + Option force16Colors = new ("--force-16-colors") { Description = "Forces the driver to use 16-color mode instead of TrueColor." }; + force16Colors.Aliases.Add ("-16"); - Option benchmarkTimeout = new ("--timeout", - () => Scenario.BenchmarkTimeout, - $"The maximum time in milliseconds to run a benchmark. Default is {Scenario.BenchmarkTimeout}ms."); - benchmarkTimeout.AddAlias ("-t"); + Option benchmarkTimeout = new ("--timeout") + { + Description = $"The maximum time in milliseconds to run a benchmark. Default is {Scenario.BenchmarkTimeout}ms.", + DefaultValueFactory = _ => Scenario.BenchmarkTimeout + }; + benchmarkTimeout.Aliases.Add ("-t"); - Option resultsFile = new ("--file", "The file to save benchmark results to."); - resultsFile.AddAlias ("-f"); + Option resultsFile = new ("--file") { Description = "The file to save benchmark results to." }; + resultsFile.Aliases.Add ("-f"); LogFilePath = $"{LOGFILE_LOCATION}/{Assembly.GetExecutingAssembly ().GetName ().Name}"; - Option debugLogLevel = new Option ("--debug-log-level", "The level to use for logging.").FromAmong (Enum.GetNames ()); - debugLogLevel.SetDefaultValue ("Warning"); - debugLogLevel.AddAlias ("-dl"); + Option debugLogLevel = new Option ("--debug-log-level") + { + Description = "The level to use for logging.", DefaultValueFactory = _ => "Warning" + }; + debugLogLevel.AcceptOnlyFromAmong (Enum.GetNames ()); + debugLogLevel.Aliases.Add ("-dl"); // List command Command listCommand = new ("list", "List all available scenarios"); - listCommand.SetHandler (() => - { - ObservableCollection scenarios = Scenario.GetScenarios (); + listCommand.SetAction (_ => + { + ObservableCollection scenarios = Scenario.GetScenarios (); - Console.WriteLine (@$"Available scenarios ({scenarios.Count})"); - Console.WriteLine (); + Console.WriteLine (@$"Available scenarios ({scenarios.Count})"); + Console.WriteLine (); - foreach (Scenario s in scenarios) - { - Console.WriteLine (@$" {s.GetName (),-30} {s.GetDescription ()}"); - } - }); + foreach (Scenario s in scenarios) + { + Console.WriteLine (@$" {s.GetName (),-30} {s.GetDescription ()}"); + } + }); // Run command - Argument scenarioArgument = new ("scenario", "The name of the Scenario to run."); + Argument scenarioArgument = new ("scenario") { Description = "The name of the Scenario to run." }; Command runCommand = new ("run", "Run a specific scenario") { scenarioArgument }; - runCommand.AddOption (driverOption); - runCommand.AddOption (disableConfigManagement); - runCommand.AddOption (force16Colors); - runCommand.AddOption (debugLogLevel); + runCommand.Options.Add (driverOption); + runCommand.Options.Add (disableConfigManagement); + runCommand.Options.Add (force16Colors); + runCommand.Options.Add (debugLogLevel); - runCommand.SetHandler ((scenarioName, driver, disableCm, force16, logLevel) => - { - SetupLogging (logLevel); + runCommand.SetAction (parseResult => + { + // Extract the values ​​using parseResult. + string scenarioName = parseResult.GetRequiredValue (scenarioArgument); + string driver = parseResult.GetRequiredValue (driverOption); + bool disableCm = parseResult.GetRequiredValue (disableConfigManagement); + bool force16 = parseResult.GetRequiredValue (force16Colors); + string logLevel = parseResult.GetRequiredValue (debugLogLevel); - Runner runner = new (); + // Executing the original logic + SetupLogging (logLevel); - if (!disableCm) - { - runner.SetRuntimeConfig(driver, force16 ? true : null); - ConfigurationManager.Enable (ConfigLocations.All); - } + Runner runner = new (); - Scenario? scenario = FindScenario (scenarioName); + if (!disableCm) + { + runner.SetRuntimeConfig (driver, force16 ? true : null); + ConfigurationManager.Enable (ConfigLocations.All); + } - if (scenario is null) - { - Console.Error.WriteLine ($"Scenario '{scenarioName}' not found."); + Scenario? scenario = FindScenario (scenarioName); - return; - } + if (scenario is null) + { + Console.Error.WriteLine ($"Scenario '{scenarioName}' not found."); - // Pass force16 only if explicitly set (default false means not set) - runner.RunScenario (scenarioName, false); - }, - scenarioArgument, - driverOption, - disableConfigManagement, - force16Colors, - debugLogLevel); + return; // SetAction returns void, so the empty return value works. + } + + // Pass force16 only if explicitly set (default false means not set) + runner.RunScenario (scenarioName, false); + }); // Benchmark command - Argument benchmarkScenarioArgument = - new ("scenario", () => null, "The name of the Scenario to benchmark. If not specified, all scenarios are benchmarked."); + Argument benchmarkScenarioArgument = new ("scenario") + { + Description = "The name of the Scenario to benchmark. If not specified, all scenarios are benchmarked.", DefaultValueFactory = _ => null + }; Command benchmarkCommand = new ("benchmark", "Benchmark scenarios") { benchmarkScenarioArgument }; - benchmarkCommand.AddOption (driverOption); - benchmarkCommand.AddOption (disableConfigManagement); - benchmarkCommand.AddOption (force16Colors); - benchmarkCommand.AddOption (benchmarkTimeout); - benchmarkCommand.AddOption (resultsFile); - benchmarkCommand.AddOption (debugLogLevel); - - benchmarkCommand.SetHandler ((scenarioName, driver, disableCm, force16, timeout, file, logLevel) => - { - SetupLogging (logLevel); - Scenario.BenchmarkTimeout = timeout; - - Runner runner = new (); - - if (!disableCm) - { - // Pass force16 only if explicitly set - runner.SetRuntimeConfig (driver, force16 ? true : null); - ConfigurationManager.Enable (ConfigLocations.All); - } - - List results; - - if (string.IsNullOrEmpty (scenarioName)) - { - // Benchmark all scenarios - ObservableCollection scenarios = Scenario.GetScenarios (); - results = runner.BenchmarkAllScenarios (scenarios); - } - else - { - // Benchmark single scenario - Scenario? scenario = FindScenario (scenarioName); - - if (scenario is null) - { - Console.Error.WriteLine ($"Scenario '{scenarioName}' not found."); - - return; - } - - BenchmarkResults? result = runner.RunScenario (scenarioName, true); - results = result is { } ? [result] : []; - } - - if (results.Count == 0) - { - Console.WriteLine (@"No benchmark results collected."); - - return; - } - - if (!string.IsNullOrEmpty (file)) - { - Runner.SaveResultsToFile (results, file); - Console.WriteLine (@$"Results saved to {file}"); - } - else - { - // Display in UI - Runner.DisplayResultsUI (results); - } - }, - benchmarkScenarioArgument, - driverOption, - disableConfigManagement, - force16Colors, - benchmarkTimeout, - resultsFile, - debugLogLevel); + benchmarkCommand.Options.Add (driverOption); + benchmarkCommand.Options.Add (disableConfigManagement); + benchmarkCommand.Options.Add (force16Colors); + benchmarkCommand.Options.Add (benchmarkTimeout); + benchmarkCommand.Options.Add (resultsFile); + benchmarkCommand.Options.Add (debugLogLevel); - RootCommand rootCommand = new ("Terminal.Gui Scenario Runner - Run and benchmark Terminal.Gui scenarios") { listCommand, runCommand, benchmarkCommand }; + benchmarkCommand.SetAction (parseResult => + { + // Extract the values ​​using parseResult. + string scenarioName = parseResult.GetRequiredValue (scenarioArgument); + string driver = parseResult.GetRequiredValue (driverOption); + bool disableCm = parseResult.GetRequiredValue (disableConfigManagement); + bool force16 = parseResult.GetRequiredValue (force16Colors); + uint timeout = parseResult.GetRequiredValue (benchmarkTimeout); + string file = parseResult.GetRequiredValue (resultsFile); + string logLevel = parseResult.GetRequiredValue (debugLogLevel); + + SetupLogging (logLevel); + Scenario.BenchmarkTimeout = timeout; + + Runner runner = new (); + + if (!disableCm) + { + // Pass force16 only if explicitly set + runner.SetRuntimeConfig (driver, force16 ? true : null); + ConfigurationManager.Enable (ConfigLocations.All); + } + + List results; + + if (string.IsNullOrEmpty (scenarioName)) + { + // Benchmark all scenarios + ObservableCollection scenarios = Scenario.GetScenarios (); + results = runner.BenchmarkAllScenarios (scenarios); + } + else + { + // Benchmark single scenario + Scenario? scenario = FindScenario (scenarioName); + + if (scenario is null) + { + Console.Error.WriteLine ($"Scenario '{scenarioName}' not found."); + + return; + } + + BenchmarkResults? result = runner.RunScenario (scenarioName, true); + results = result is { } ? [result] : []; + } + + if (results.Count == 0) + { + Console.WriteLine (@"No benchmark results collected."); + + return; + } + + if (!string.IsNullOrEmpty (file)) + { + Runner.SaveResultsToFile (results, file); + Console.WriteLine (@$"Results saved to {file}"); + } + else + { + // Display in UI + Runner.DisplayResultsUI (results); + } + }); - Parser parser = new CommandLineBuilder (rootCommand).UseDefaults ().Build (); + RootCommand rootCommand = new ("Terminal.Gui Scenario Runner - Run and benchmark Terminal.Gui scenarios") { listCommand, runCommand, benchmarkCommand }; - return parser.Invoke (args); + return rootCommand.Parse (args).Invoke (); } private static Scenario? FindScenario (string name) diff --git a/Examples/UICatalog/UICatalog.cs b/Examples/UICatalog/UICatalog.cs index c6f32830eb..c97ca59c18 100644 --- a/Examples/UICatalog/UICatalog.cs +++ b/Examples/UICatalog/UICatalog.cs @@ -10,9 +10,7 @@ global using Terminal.Gui.Text; global using Terminal.Gui.FileServices; global using Terminal.Gui.Resources; -global using Terminal.Gui.Tracing; using System.CommandLine; -using System.CommandLine.Builder; using System.CommandLine.Parsing; using System.Diagnostics; using System.Globalization; @@ -81,60 +79,77 @@ private static int Main (string [] args) // Get allowed driver names string? [] allowedDrivers = DriverRegistry.GetDriverNames ().ToArray (); - Option driverOption = new Option ("--driver", "The IDriver to use.").FromAmong (allowedDrivers!); - driverOption.SetDefaultValue (string.Empty); - driverOption.AddAlias ("-d"); - driverOption.AddAlias ("--d"); + Option driverOption = new ("--driver") + { + Description = "The IDriver to use." + }; + driverOption.AcceptOnlyFromAmong (allowedDrivers!); + driverOption.DefaultValueFactory = _ => string.Empty; + driverOption.Aliases.Add ("-d"); + driverOption.Aliases.Add ("--d"); // Add validator separately (not chained) - driverOption.AddValidator (result => + driverOption.Validators.Add (result => { var value = result.GetValueOrDefault (); if (result.Tokens.Count > 0 && !allowedDrivers.Contains (value)) { - result.ErrorMessage = $"Invalid driver name '{value}'. Allowed values: {string.Join (", ", allowedDrivers)}"; + result.AddError ($"Invalid driver name '{value}'. Allowed values: {string.Join (", ", allowedDrivers)}"); } }); // Configuration Management - Option disableConfigManagement = new ("--disable-cm", - "Indicates Configuration Management should not be enabled. Only `ConfigLocations.HardCoded` settings will be loaded."); - disableConfigManagement.AddAlias ("-dcm"); - disableConfigManagement.AddAlias ("--dcm"); + Option disableConfigManagement = new ("--disable-cm") + { + Description = "Indicates Configuration Management should not be enabled. Only `ConfigLocations.HardCoded` settings will be loaded." + }; + disableConfigManagement.Aliases.Add ("-dcm"); + disableConfigManagement.Aliases.Add ("--dcm"); - Option benchmarkFlag = new ("--benchmark", "Enables benchmarking. If a Scenario is specified, just that Scenario will be benchmarked."); - benchmarkFlag.AddAlias ("-b"); - benchmarkFlag.AddAlias ("--b"); + Option benchmarkFlag = new ("--benchmark") + { + Description = "Enables benchmarking. If a Scenario is specified, just that Scenario will be benchmarked." + }; + benchmarkFlag.Aliases.Add ("-b"); + benchmarkFlag.Aliases.Add ("--b"); - Option force16ColorsOption = new ("--force-16-colors", "Forces the driver to use 16-color mode instead of TrueColor."); - force16ColorsOption.AddAlias ("-16"); + Option force16ColorsOption = new ("--force-16-colors") { Description = "Forces the driver to use 16-color mode instead of TrueColor." }; + force16ColorsOption.Aliases.Add ("-16"); - Option benchmarkTimeout = new ("--timeout", - () => Scenario.BenchmarkTimeout, - $"The maximum time in milliseconds to run a benchmark for. Default is {Scenario.BenchmarkTimeout}ms."); - benchmarkTimeout.AddAlias ("-t"); - benchmarkTimeout.AddAlias ("--t"); + Option benchmarkTimeout = new ("--timeout") + { + Description = $"The maximum time in milliseconds to run a benchmark for. Default is {Scenario.BenchmarkTimeout}ms.", + DefaultValueFactory = _ => Scenario.BenchmarkTimeout + }; + benchmarkTimeout.Aliases.Add ("-t"); + benchmarkTimeout.Aliases.Add ("--t"); - Option resultsFile = new ("--file", "The file to save benchmark results to. If not specified, the results will be displayed in a TableView."); - resultsFile.AddAlias ("-f"); - resultsFile.AddAlias ("--f"); + Option resultsFile = new ("--file") + { + Description = "The file to save benchmark results to. If not specified, the results will be displayed in a TableView.", + DefaultValueFactory = _ => string.Empty + }; + resultsFile.Aliases.Add ("-f"); + resultsFile.Aliases.Add ("--f"); // what's the app name? LogFilePath = $"{LOGFILE_LOCATION}/{Assembly.GetExecutingAssembly ().GetName ().Name}.log"; - Option debugLogLevel = - new Option ("--debug-log-level", $"The level to use for logging (debug console and {LogFilePath})").FromAmong (Enum.GetNames ()); - debugLogLevel.SetDefaultValue ("Warning"); - debugLogLevel.AddAlias ("-dl"); - debugLogLevel.AddAlias ("--dl"); + Option debugLogLevel = new ("--debug-log-level") + { + Description = $"The level to use for logging (debug console and {LogFilePath})" + }; + debugLogLevel.AcceptOnlyFromAmong (Enum.GetNames ()); + debugLogLevel.DefaultValueFactory = _ => "Warning"; + debugLogLevel.Aliases.Add ("-dl"); + debugLogLevel.Aliases.Add ("--dl"); - Argument scenarioArgument = - new Argument ("scenario", - description: "The name of the Scenario to run. If not provided, the UI Catalog UI will be shown.", - getDefaultValue: () => "none").FromAmong (UICatalogRunnable.CachedScenarios.Select (s => s.GetName ()) - .Append ("none") - .ToArray ()); + Argument scenarioArgument = new ("scenario") + { + Description = "The name of the Scenario to run. If not provided, the UI Catalog UI will be shown.", DefaultValueFactory = _ => "none" + }; + scenarioArgument.AcceptOnlyFromAmong (UICatalogRunnable.CachedScenarios.Select (s => s.GetName ()).Append ("none").ToArray ()); var rootCommand = new RootCommand ("A comprehensive sample library and test app for Terminal.Gui") { @@ -148,19 +163,19 @@ private static int Main (string [] args) force16ColorsOption }; - rootCommand.SetHandler (context => + rootCommand.SetAction (context => { - bool force16 = context.ParseResult.GetValueForOption (force16ColorsOption); + bool force16 = context.GetRequiredValue (force16ColorsOption); UICatalogCommandLineOptions options = new () { - Scenario = context.ParseResult.GetValueForArgument (scenarioArgument), - Driver = context.ParseResult.GetValueForOption (driverOption) ?? string.Empty, - DontEnableConfigurationManagement = context.ParseResult.GetValueForOption (disableConfigManagement), - Benchmark = context.ParseResult.GetValueForOption (benchmarkFlag), - BenchmarkTimeout = context.ParseResult.GetValueForOption (benchmarkTimeout), - ResultsFile = context.ParseResult.GetValueForOption (resultsFile) ?? string.Empty, - DebugLogLevel = context.ParseResult.GetValueForOption (debugLogLevel) ?? "Warning", + Scenario = context.GetRequiredValue (scenarioArgument), + Driver = context.GetRequiredValue (driverOption) ?? string.Empty, + DontEnableConfigurationManagement = context.GetRequiredValue (disableConfigManagement), + Benchmark = context.GetRequiredValue (benchmarkFlag), + BenchmarkTimeout = context.GetRequiredValue (benchmarkTimeout), + ResultsFile = context.GetRequiredValue (resultsFile) ?? string.Empty, + DebugLogLevel = context.GetRequiredValue (debugLogLevel) ?? "Warning", // Only set Force16Colors if explicitly specified on command line Force16Colors = force16 ? true : null @@ -172,16 +187,14 @@ private static int Main (string [] args) var helpShown = false; - Parser parser = new CommandLineBuilder (rootCommand).UseHelp (_ => helpShown = true).Build (); - - parser.Invoke (args); + rootCommand.Parse (args).Invoke (); if (helpShown) { return 0; } - ParseResult parseResult = parser.Parse (args); + ParseResult parseResult = rootCommand.Parse (args); if (parseResult.Errors.Count > 0) { diff --git a/Tests/IntegrationTests/DialogTests.cs b/Tests/IntegrationTests/DialogTests.cs index e8767f58bc..67ebf4b2bb 100644 --- a/Tests/IntegrationTests/DialogTests.cs +++ b/Tests/IntegrationTests/DialogTests.cs @@ -1,7 +1,4 @@ #nullable enable -using UnitTests; -using Xunit.Abstractions; - namespace IntegrationTests; public class DialogTests diff --git a/Tests/IntegrationTests/FluentTests/FileDialogTests.cs b/Tests/IntegrationTests/FluentTests/FileDialogTests.cs index e456d90bed..a8531124e1 100644 --- a/Tests/IntegrationTests/FluentTests/FileDialogTests.cs +++ b/Tests/IntegrationTests/FluentTests/FileDialogTests.cs @@ -5,7 +5,6 @@ using System.Runtime.InteropServices; using TerminalGuiFluentTesting; using TerminalGuiFluentTestingXunit; -using Xunit.Abstractions; namespace IntegrationTests; @@ -58,7 +57,7 @@ public void CancelFileDialog_QuitKey_Quits (string d) { SaveDialog? sd = null; - using TestContext c = With.A (() => NewSaveDialog (out sd), 100, 20, d, _out) + using FluentTestContext c = With.A (() => NewSaveDialog (out sd), 100, 20, d, _out) .ScreenShot ("Save dialog", _out) .KeyDown (Application.QuitKey) .AssertTrue (sd!.Canceled); @@ -70,7 +69,7 @@ public void CancelFileDialog_UsingCancelButton_TabThenEnter (string d) { SaveDialog? sd = null; - using TestContext c = With.A (() => NewSaveDialog (out sd), 100, 20, d) + using FluentTestContext c = With.A (() => NewSaveDialog (out sd), 100, 20, d) .ScreenShot ("Save dialog", _out) .Focus