Fixes #4391. Weird situation where ForceDriver with args doesn't persists on open scenario

This commit is contained in:
BDisp
2025-11-17 00:53:08 +00:00
parent 09951485fe
commit c8e2d5ce69
5 changed files with 111 additions and 5 deletions

View File

@@ -55,13 +55,31 @@ namespace UICatalog;
/// </remarks>
public class UICatalog
{
private static string? _forceDriver = null;
private static string? _forceDriver;
private static bool _forTesting;
private static bool _iterationHandlerRemoved;
private static string? _uiCatalogDriver;
private static string? _scenarioDriver;
public static string LogFilePath { get; set; } = string.Empty;
public static LoggingLevelSwitch LogLevelSwitch { get; } = new ();
public const string LOGFILE_LOCATION = "logs";
public static UICatalogCommandLineOptions Options { get; set; }
public static (string? UiCatalogDriver, string? ScenarioDriver) Run (string [] args)
{
// Flag for testing
_forTesting = true;
// Start app
Main (args);
// Unset testing flag
_forTesting = false;
return new (_uiCatalogDriver, _scenarioDriver);
}
private static int Main (string [] args)
{
Console.OutputEncoding = Encoding.Default;
@@ -194,6 +212,8 @@ public class UICatalog
UICatalogMain (Options);
Debug.Assert (Application.ForceDriver == string.Empty);
return 0;
}
@@ -247,6 +267,11 @@ public class UICatalog
/// <returns></returns>
private static Scenario RunUICatalogTopLevel ()
{
if (_iterationHandlerRemoved)
{
return null!;
}
// Run UI Catalog UI. When it exits, if _selectedScenario is != null then
// a Scenario was selected. Otherwise, the user wants to quit UI Catalog.
@@ -255,7 +280,22 @@ public class UICatalog
Application.Init (driverName: _forceDriver);
var top = Application.Run<UICatalogTop> ();
Toplevel top;
if (_forTesting)
{
top = new UICatalogTop ();
SessionToken sessionToken = Application.Begin (top);
UICatalogTop.CachedSelectedScenario = Scenario.GetScenarios () [0];
Application.End (sessionToken);
_uiCatalogDriver = Application.Driver!.GetName ();
}
else
{
top = Application.Run<UICatalogTop> ();
}
top.Dispose ();
Application.Shutdown ();
VerifyObjectsWereDisposed ();
@@ -412,6 +452,8 @@ public class UICatalog
Application.InitializedChanged += ApplicationOnInitializedChanged;
#endif
Application.ForceDriver = _forceDriver;
scenario.Main ();
scenario.Dispose ();
@@ -430,6 +472,43 @@ public class UICatalog
if (e.Value)
{
sw.Start ();
if (_forTesting)
{
int iterationCount = 0;
Key quitKey;
Application.Iteration += OnApplicationOnIteration;
void OnApplicationOnIteration (object? s, IterationEventArgs a)
{
iterationCount++;
if (Application.Initialized)
{
// Press QuitKey
quitKey = Application.QuitKey;
Logging.Trace (
$"Attempting to quit with {quitKey} after {iterationCount} iterations.");
try
{
Application.RaiseKeyDownEvent (quitKey);
}
catch (Exception ex)
{
Logging.Trace (
$"Exception raising quit key: {ex.Message}");
}
Application.Iteration -= OnApplicationOnIteration;
_iterationHandlerRemoved = true;
_scenarioDriver = Application.Driver?.GetName ();
}
}
}
}
else
{

View File

@@ -26,7 +26,16 @@ public static partial class Application // Driver abstractions
public static string ForceDriver
{
get => ApplicationImpl.Instance.ForceDriver;
set => ApplicationImpl.Instance.ForceDriver = value;
set
{
if (!string.IsNullOrEmpty (ApplicationImpl.Instance.ForceDriver))
{
// ForceDriver cannot be changed if it has a valid value
return;
}
ApplicationImpl.Instance.ForceDriver = value;
}
}
/// <inheritdoc cref="IApplication.Sixel"/>

View File

@@ -35,7 +35,7 @@ public partial class ApplicationImpl
bool factoryIsFake = _componentFactory is IComponentFactory<ConsoleKeyInfo>;
// Then check driverName
bool nameIsWindows = driverName?.Contains ("win", StringComparison.OrdinalIgnoreCase) ?? false;
bool nameIsWindows = driverName?.Contains ("windows", StringComparison.OrdinalIgnoreCase) ?? false;
bool nameIsDotNet = driverName?.Contains ("dotnet", StringComparison.OrdinalIgnoreCase) ?? false;
bool nameIsUnix = driverName?.Contains ("unix", StringComparison.OrdinalIgnoreCase) ?? false;
bool nameIsFake = driverName?.Contains ("fake", StringComparison.OrdinalIgnoreCase) ?? false;

View File

@@ -231,7 +231,10 @@ public partial class ApplicationImpl
// === 9. Clear graphics ===
Sixel.Clear ();
// === 10. Reset synchronization context ===
// === 10. Reset ForceDriver ===
ForceDriver = string.Empty;
// === 11. Reset synchronization context ===
// IMPORTANT: Always reset sync context, even if not initialized
// This ensures cleanup works correctly even if Shutdown is called without Init
// Reset synchronization context to allow the user to run async/await,

View File

@@ -665,4 +665,19 @@ public class ScenarioTests : TestsAllViews
void LayoutCompleteHandler (object? sender, LayoutEventArgs args) { UpdateTitle (curView); }
}
[Fact]
public void ForceDriver_persists_On_Open_Scenario_With_Args ()
{
string driverName = "fake";
string [] args = ["-d", driverName];
(string? UiCatalogDriver, string? ScenarioDriver) driverNames = global::UICatalog.UICatalog.Run (args);
Assert.Equal (string.Empty, Application.ForceDriver);
Assert.Equal (driverName, driverNames.UiCatalogDriver);
Assert.Equal (driverName, driverNames.ScenarioDriver);
Assert.Equal (driverNames.UiCatalogDriver, driverNames.ScenarioDriver);
}
}