From ce17fddd9c5bdb4c6dceaa502b758bdea8bc3900 Mon Sep 17 00:00:00 2001 From: BDisp Date: Tue, 3 Dec 2024 22:35:25 +0000 Subject: [PATCH 1/4] Fixes #3836. SetupFakeDriver sometimes causes failure in the unit test. --- UnitTests/TestHelpers.cs | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/UnitTests/TestHelpers.cs b/UnitTests/TestHelpers.cs index 3f32e35b5..1f7763984 100644 --- a/UnitTests/TestHelpers.cs +++ b/UnitTests/TestHelpers.cs @@ -197,14 +197,8 @@ public class SetupFakeDriverAttribute : BeforeAfterTestAttribute // Turn off diagnostic flags in case some test left them on View.Diagnostics = ViewDiagnosticFlags.Off; - if (Application.Driver is { }) - { - ((FakeDriver)Application.Driver).Rows = 25; - ((FakeDriver)Application.Driver).Cols = 25; - ((FakeDriver)Application.Driver).End (); - } - - Application.Driver = null; + Application.ResetState (true); + Assert.Equal (new (0, 0, 2048, 2048), Application.Screen); base.After (methodUnderTest); } From 99866c80b5066e97b59dc14abf1af2a3ecdc896a Mon Sep 17 00:00:00 2001 From: BDisp Date: Wed, 4 Dec 2024 14:08:22 +0000 Subject: [PATCH 2/4] Add internal static InitState method to subscribe events. --- .../Application/Application.Initialization.cs | 15 ++++++++++---- .../Application/ApplicationScreenTests.cs | 20 +++++++++++++++++++ UnitTests/Application/ApplicationTests.cs | 6 ++++++ UnitTests/TestHelpers.cs | 4 ++++ 4 files changed, 41 insertions(+), 4 deletions(-) diff --git a/Terminal.Gui/Application/Application.Initialization.cs b/Terminal.Gui/Application/Application.Initialization.cs index c58e1bf92..a6840db2a 100644 --- a/Terminal.Gui/Application/Application.Initialization.cs +++ b/Terminal.Gui/Application/Application.Initialization.cs @@ -163,10 +163,7 @@ public static partial class Application // Initialization (Init/Shutdown) ); } - Driver.SizeChanged += Driver_SizeChanged; - Driver.KeyDown += Driver_KeyDown; - Driver.KeyUp += Driver_KeyUp; - Driver.MouseEvent += Driver_MouseEvent; + InitState (); SynchronizationContext.SetSynchronizationContext (new MainLoopSyncContext ()); @@ -176,6 +173,16 @@ public static partial class Application // Initialization (Init/Shutdown) InitializedChanged?.Invoke (null, new (init)); } + internal static void InitState () + { + ArgumentNullException.ThrowIfNull (Driver); + + Driver.SizeChanged += Driver_SizeChanged; + Driver.KeyDown += Driver_KeyDown; + Driver.KeyUp += Driver_KeyUp; + Driver.MouseEvent += Driver_MouseEvent; + } + private static void Driver_SizeChanged (object? sender, SizeChangedEventArgs e) { OnSizeChanging (e); } private static void Driver_KeyDown (object? sender, Key e) { RaiseKeyDownEvent (e); } private static void Driver_KeyUp (object? sender, Key e) { RaiseKeyUpEvent (e); } diff --git a/UnitTests/Application/ApplicationScreenTests.cs b/UnitTests/Application/ApplicationScreenTests.cs index c6a220e52..d3866859e 100644 --- a/UnitTests/Application/ApplicationScreenTests.cs +++ b/UnitTests/Application/ApplicationScreenTests.cs @@ -65,4 +65,24 @@ public class ApplicationScreenTests (ITestOutputHelper output) Application.Top = null; Application.Shutdown (); } + + [Fact] + public void Screen_Changes_OnSizeChanged_Without_Call_Application_Init () + { + // Arrange + Application.ResetState (true); + Assert.Null (Application.Driver); + Application.Driver = new FakeDriver { Rows = 25, Cols = 25 }; + Application.InitState (); + Assert.Equal (new (0, 0, 25, 25), Application.Screen); + + // Act + (((FakeDriver)Application.Driver)!).SetBufferSize (120, 30); + + // Assert + Assert.Equal (new (0, 0, 120, 30), Application.Screen); + + // Cleanup + Application.ResetState (true); + } } diff --git a/UnitTests/Application/ApplicationTests.cs b/UnitTests/Application/ApplicationTests.cs index ab44e66ef..b5d2edee1 100644 --- a/UnitTests/Application/ApplicationTests.cs +++ b/UnitTests/Application/ApplicationTests.cs @@ -641,6 +641,12 @@ public class ApplicationTests Application.Shutdown (); } + [Fact] + public void InitState_Throws_If_Driver_Is_Null () + { + Assert.Throws (static () => Application.InitState ()); + } + private void Init () { Application.Init (new FakeDriver ()); diff --git a/UnitTests/TestHelpers.cs b/UnitTests/TestHelpers.cs index 1f7763984..e29825135 100644 --- a/UnitTests/TestHelpers.cs +++ b/UnitTests/TestHelpers.cs @@ -198,6 +198,7 @@ public class SetupFakeDriverAttribute : BeforeAfterTestAttribute View.Diagnostics = ViewDiagnosticFlags.Off; Application.ResetState (true); + Assert.Null (Application.Driver); Assert.Equal (new (0, 0, 2048, 2048), Application.Screen); base.After (methodUnderTest); } @@ -209,6 +210,9 @@ public class SetupFakeDriverAttribute : BeforeAfterTestAttribute Application.ResetState (true); Assert.Null (Application.Driver); Application.Driver = new FakeDriver { Rows = 25, Cols = 25 }; + Assert.Equal (new (0, 0, 25, 25), Application.Screen); + // Ensures subscribing events, at least for the SizeChanged event + Application.InitState (); base.Before (methodUnderTest); } From be07f5a2764d9f4e264c520328eb6696bcaf167d Mon Sep 17 00:00:00 2001 From: BDisp Date: Thu, 5 Dec 2024 16:12:40 +0000 Subject: [PATCH 3/4] Rename to SubscribeDriverEvents and add UnsubscribeDriverEvents method. --- .../Application/Application.Initialization.cs | 13 ++++++++++--- Terminal.Gui/Application/Application.cs | 5 +---- UnitTests/Application/ApplicationScreenTests.cs | 2 +- UnitTests/Application/ApplicationTests.cs | 2 +- UnitTests/TestHelpers.cs | 2 +- 5 files changed, 14 insertions(+), 10 deletions(-) diff --git a/Terminal.Gui/Application/Application.Initialization.cs b/Terminal.Gui/Application/Application.Initialization.cs index a6840db2a..f3901b8c9 100644 --- a/Terminal.Gui/Application/Application.Initialization.cs +++ b/Terminal.Gui/Application/Application.Initialization.cs @@ -150,6 +150,7 @@ public static partial class Application // Initialization (Init/Shutdown) try { MainLoop = Driver!.Init (); + SubscribeDriverEvents (); } catch (InvalidOperationException ex) { @@ -163,8 +164,6 @@ public static partial class Application // Initialization (Init/Shutdown) ); } - InitState (); - SynchronizationContext.SetSynchronizationContext (new MainLoopSyncContext ()); SupportedCultures = GetSupportedCultures (); @@ -173,7 +172,7 @@ public static partial class Application // Initialization (Init/Shutdown) InitializedChanged?.Invoke (null, new (init)); } - internal static void InitState () + internal static void SubscribeDriverEvents () { ArgumentNullException.ThrowIfNull (Driver); @@ -183,6 +182,14 @@ public static partial class Application // Initialization (Init/Shutdown) Driver.MouseEvent += Driver_MouseEvent; } + internal static void UnsubscribeDriverEvents () + { + Driver.SizeChanged -= Driver_SizeChanged; + Driver.KeyDown -= Driver_KeyDown; + Driver.KeyUp -= Driver_KeyUp; + Driver.MouseEvent -= Driver_MouseEvent; + } + private static void Driver_SizeChanged (object? sender, SizeChangedEventArgs e) { OnSizeChanging (e); } private static void Driver_KeyDown (object? sender, Key e) { RaiseKeyDownEvent (e); } private static void Driver_KeyUp (object? sender, Key e) { RaiseKeyUpEvent (e); } diff --git a/Terminal.Gui/Application/Application.cs b/Terminal.Gui/Application/Application.cs index 77a53de2a..7c0ff5529 100644 --- a/Terminal.Gui/Application/Application.cs +++ b/Terminal.Gui/Application/Application.cs @@ -177,10 +177,7 @@ public static partial class Application // Driver stuff if (Driver is { }) { - Driver.SizeChanged -= Driver_SizeChanged; - Driver.KeyDown -= Driver_KeyDown; - Driver.KeyUp -= Driver_KeyUp; - Driver.MouseEvent -= Driver_MouseEvent; + UnsubscribeDriverEvents (); Driver?.End (); Driver = null; } diff --git a/UnitTests/Application/ApplicationScreenTests.cs b/UnitTests/Application/ApplicationScreenTests.cs index d3866859e..f53bf8531 100644 --- a/UnitTests/Application/ApplicationScreenTests.cs +++ b/UnitTests/Application/ApplicationScreenTests.cs @@ -73,7 +73,7 @@ public class ApplicationScreenTests (ITestOutputHelper output) Application.ResetState (true); Assert.Null (Application.Driver); Application.Driver = new FakeDriver { Rows = 25, Cols = 25 }; - Application.InitState (); + Application.SubscribeDriverEvents (); Assert.Equal (new (0, 0, 25, 25), Application.Screen); // Act diff --git a/UnitTests/Application/ApplicationTests.cs b/UnitTests/Application/ApplicationTests.cs index b5d2edee1..333e4f942 100644 --- a/UnitTests/Application/ApplicationTests.cs +++ b/UnitTests/Application/ApplicationTests.cs @@ -644,7 +644,7 @@ public class ApplicationTests [Fact] public void InitState_Throws_If_Driver_Is_Null () { - Assert.Throws (static () => Application.InitState ()); + Assert.Throws (static () => Application.SubscribeDriverEvents ()); } private void Init () diff --git a/UnitTests/TestHelpers.cs b/UnitTests/TestHelpers.cs index e29825135..ed687e61b 100644 --- a/UnitTests/TestHelpers.cs +++ b/UnitTests/TestHelpers.cs @@ -212,7 +212,7 @@ public class SetupFakeDriverAttribute : BeforeAfterTestAttribute Application.Driver = new FakeDriver { Rows = 25, Cols = 25 }; Assert.Equal (new (0, 0, 25, 25), Application.Screen); // Ensures subscribing events, at least for the SizeChanged event - Application.InitState (); + Application.SubscribeDriverEvents (); base.Before (methodUnderTest); } From 58a63c2334aeb917eeb2e7b1997ef4c238c8aa66 Mon Sep 17 00:00:00 2001 From: BDisp Date: Thu, 5 Dec 2024 19:33:08 +0000 Subject: [PATCH 4/4] Add ArgumentNullException.ThrowIfNull. --- Terminal.Gui/Application/Application.Initialization.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Terminal.Gui/Application/Application.Initialization.cs b/Terminal.Gui/Application/Application.Initialization.cs index f3901b8c9..d7ce7874b 100644 --- a/Terminal.Gui/Application/Application.Initialization.cs +++ b/Terminal.Gui/Application/Application.Initialization.cs @@ -184,6 +184,8 @@ public static partial class Application // Initialization (Init/Shutdown) internal static void UnsubscribeDriverEvents () { + ArgumentNullException.ThrowIfNull (Driver); + Driver.SizeChanged -= Driver_SizeChanged; Driver.KeyDown -= Driver_KeyDown; Driver.KeyUp -= Driver_KeyUp;