mirror of
https://github.com/gui-cs/Terminal.Gui.git
synced 2025-12-26 15:57:56 +01:00
Fix fence logic to work with parallel tests
Co-authored-by: tig <585482+tig@users.noreply.github.com>
This commit is contained in:
@@ -75,10 +75,7 @@ public static partial class Application // Lifecycle (Init/Shutdown)
|
||||
[Obsolete ("The legacy static Application object is going away.")]
|
||||
internal static void ResetState (bool ignoreDisposed = false)
|
||||
{
|
||||
// Reset the model usage tracking first to allow access to Instance if needed
|
||||
ApplicationImpl.ResetModelUsageTracking ();
|
||||
|
||||
// Now safe to access Instance for cleanup
|
||||
ApplicationImpl.Instance?.ResetState (ignoreDisposed);
|
||||
// Use the static reset method to bypass the fence check
|
||||
ApplicationImpl.ResetStateStatic (ignoreDisposed);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,23 @@ public partial class ApplicationImpl
|
||||
throw new InvalidOperationException ("Init called multiple times without Shutdown");
|
||||
}
|
||||
|
||||
// Check the fence: ensure we're not mixing application models
|
||||
// If this is a legacy static instance and instance-based model was used, throw
|
||||
if (this == _instance && _modelUsage == ApplicationModelUsage.InstanceBased)
|
||||
{
|
||||
throw new InvalidOperationException (
|
||||
"Cannot use legacy static Application model (Application.Init/ApplicationImpl.Instance) after using modern instance-based model (Application.Create). " +
|
||||
"Use only one model per process.");
|
||||
}
|
||||
|
||||
// If this is an instance-based instance and legacy static model was used, throw
|
||||
if (this != _instance && _modelUsage == ApplicationModelUsage.LegacyStatic)
|
||||
{
|
||||
throw new InvalidOperationException (
|
||||
"Cannot use modern instance-based model (Application.Create) after using legacy static Application model (Application.Init/ApplicationImpl.Instance). " +
|
||||
"Use only one model per process.");
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace (driverName))
|
||||
{
|
||||
_driverName = driverName;
|
||||
@@ -273,10 +290,6 @@ public partial class ApplicationImpl
|
||||
// gui.cs does no longer process any callbacks. See #1084 for more details:
|
||||
// (https://github.com/gui-cs/Terminal.Gui/issues/1084).
|
||||
SynchronizationContext.SetSynchronizationContext (null);
|
||||
|
||||
// === 12. Reset application model usage tracking ===
|
||||
// Reset the model usage tracking to allow the process to use either model after shutdown
|
||||
ResetModelUsageTracking ();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -49,7 +49,7 @@ public partial class ApplicationImpl : IApplication
|
||||
return _instance;
|
||||
}
|
||||
|
||||
// Only check the fence when creating a new instance
|
||||
// Check if the instance-based model has already been used
|
||||
if (_modelUsage == ApplicationModelUsage.InstanceBased)
|
||||
{
|
||||
throw new InvalidOperationException (
|
||||
@@ -57,6 +57,7 @@ public partial class ApplicationImpl : IApplication
|
||||
"Use only one model per process.");
|
||||
}
|
||||
|
||||
// Mark the usage and create the instance
|
||||
_modelUsage = ApplicationModelUsage.LegacyStatic;
|
||||
|
||||
return _instance = new ApplicationImpl ();
|
||||
@@ -68,7 +69,8 @@ public partial class ApplicationImpl : IApplication
|
||||
/// </summary>
|
||||
internal static void MarkInstanceBasedModelUsed ()
|
||||
{
|
||||
if (_modelUsage == ApplicationModelUsage.LegacyStatic)
|
||||
// Check if the legacy static model has already been initialized
|
||||
if (_modelUsage == ApplicationModelUsage.LegacyStatic && _instance?.Initialized == true)
|
||||
{
|
||||
throw new InvalidOperationException (
|
||||
"Cannot use modern instance-based model (Application.Create) after using legacy static Application model (Application.Init/ApplicationImpl.Instance). " +
|
||||
@@ -87,6 +89,19 @@ public partial class ApplicationImpl : IApplication
|
||||
_instance = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// INTERNAL: Resets state without going through the fence-checked Instance property.
|
||||
/// Used by Application.ResetState() to allow cleanup regardless of which model was used.
|
||||
/// </summary>
|
||||
internal static void ResetStateStatic (bool ignoreDisposed = false)
|
||||
{
|
||||
// If an instance exists, reset it
|
||||
_instance?.ResetState (ignoreDisposed);
|
||||
|
||||
// Always reset the model tracking to allow tests to use either model after reset
|
||||
ResetModelUsageTracking ();
|
||||
}
|
||||
|
||||
#endregion Singleton
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -18,11 +18,12 @@ public class ApplicationModelFencingTests
|
||||
{
|
||||
// Create a modern instance-based application
|
||||
IApplication app = Application.Create ();
|
||||
app.Init ("fake");
|
||||
|
||||
// Attempting to access the legacy static instance should throw
|
||||
// Attempting to initialize using the legacy static model should throw
|
||||
InvalidOperationException ex = Assert.Throws<InvalidOperationException> (() =>
|
||||
{
|
||||
IApplication _ = ApplicationImpl.Instance;
|
||||
ApplicationImpl.Instance.Init ("fake");
|
||||
});
|
||||
|
||||
Assert.Contains ("Cannot use legacy static Application model", ex.Message);
|
||||
@@ -35,13 +36,15 @@ public class ApplicationModelFencingTests
|
||||
[Fact]
|
||||
public void InstanceAccess_ThenCreate_ThrowsInvalidOperationException ()
|
||||
{
|
||||
// Access the legacy static instance
|
||||
// Initialize using the legacy static model
|
||||
IApplication staticInstance = ApplicationImpl.Instance;
|
||||
staticInstance.Init ("fake");
|
||||
|
||||
// Attempting to create a modern instance-based application should throw
|
||||
// Attempting to create and initialize with modern instance-based model should throw
|
||||
InvalidOperationException ex = Assert.Throws<InvalidOperationException> (() =>
|
||||
{
|
||||
IApplication _ = Application.Create ();
|
||||
IApplication app = Application.Create ();
|
||||
app.Init ("fake");
|
||||
});
|
||||
|
||||
Assert.Contains ("Cannot use modern instance-based model", ex.Message);
|
||||
@@ -78,11 +81,10 @@ public class ApplicationModelFencingTests
|
||||
IApplication app = Application.Create ();
|
||||
app.Init ("fake");
|
||||
|
||||
// Attempting to access the legacy static instance should throw
|
||||
// (Init calls ApplicationImpl.Instance internally)
|
||||
// Attempting to initialize using the legacy static model should throw
|
||||
InvalidOperationException ex = Assert.Throws<InvalidOperationException> (() =>
|
||||
{
|
||||
IApplication _ = ApplicationImpl.Instance;
|
||||
ApplicationImpl.Instance.Init ("fake");
|
||||
});
|
||||
|
||||
Assert.Contains ("Cannot use legacy static Application model", ex.Message);
|
||||
|
||||
Reference in New Issue
Block a user