diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index 6fb66961c9..a562562954 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -54,6 +54,10 @@ jobs: # mv -v Tests/UnitTests/TestResults/*/*.* TestResults/UnitTests/ + - name: Run UnitTests.AOT + run: | + dotnet test Tests/UnitTests.AOT --no-build --verbosity normal --collect:"XPlat Code Coverage" --settings Tests/UnitTests.AOT/coverlet.runsettings --diag:logs/UnitTests.AOT/${{ runner.os }}/logs.txt --blame --blame-crash --blame-hang --blame-hang-timeout 60s --blame-crash-collect-always -- xunit.stopOnFail=true + - name: Upload Test Logs if: always() uses: actions/upload-artifact@v4 diff --git a/Examples/CommunityToolkitExample/CommunityToolkitExample.csproj b/Examples/CommunityToolkitExample/CommunityToolkitExample.csproj index f01c030b97..94b5cfd3ca 100644 --- a/Examples/CommunityToolkitExample/CommunityToolkitExample.csproj +++ b/Examples/CommunityToolkitExample/CommunityToolkitExample.csproj @@ -9,6 +9,6 @@ + - diff --git a/Examples/CommunityToolkitExample/LoginView.cs b/Examples/CommunityToolkitExample/LoginView.cs index 70ec87f071..3c2c1a13d1 100644 --- a/Examples/CommunityToolkitExample/LoginView.cs +++ b/Examples/CommunityToolkitExample/LoginView.cs @@ -1,6 +1,6 @@ using CommunityToolkit.Mvvm.Messaging; using Terminal.Gui.App; -using Terminal.Gui.ViewBase; +using RuntimeEnvironment = Microsoft.DotNet.PlatformAbstractions.RuntimeEnvironment; namespace CommunityToolkitExample; diff --git a/Examples/CommunityToolkitExample/Program.cs b/Examples/CommunityToolkitExample/Program.cs index 265c979aac..6d45222e61 100644 --- a/Examples/CommunityToolkitExample/Program.cs +++ b/Examples/CommunityToolkitExample/Program.cs @@ -1,7 +1,6 @@ using Microsoft.Extensions.DependencyInjection; using Terminal.Gui.Configuration; using Terminal.Gui.App; -using Terminal.Gui.ViewBase; namespace CommunityToolkitExample; diff --git a/Examples/Example/Example.cs b/Examples/Example/Example.cs deleted file mode 100644 index d3e02a342c..0000000000 --- a/Examples/Example/Example.cs +++ /dev/null @@ -1,93 +0,0 @@ -// A simple Terminal.Gui example in C# - using C# 9.0 Top-level statements - -// This is a simple example application. For the full range of functionality -// see the UICatalog project - -using Terminal.Gui.Configuration; -using Terminal.Gui.App; -using Terminal.Gui.Drawing; -using Terminal.Gui.ViewBase; -using Terminal.Gui.Views; -using Attribute = Terminal.Gui.Drawing.Attribute; - -// Override the default configuration for the application to use the Light theme -ConfigurationManager.RuntimeConfig = """{ "Theme": "Light" }"""; -ConfigurationManager.Enable(ConfigLocations.All); - -Application.Run ().Dispose (); - -// Before the application exits, reset Terminal.Gui for clean shutdown -Application.Shutdown (); - -// To see this output on the screen it must be done after shutdown, -// which restores the previous screen. -Console.WriteLine ($@"Username: {ExampleWindow.UserName}"); - -// Defines a top-level window with border and title -public class ExampleWindow : Window -{ - public static string UserName { get; set; } - - public ExampleWindow () - { - Title = $"Example App ({Application.QuitKey} to quit)"; - - // Create input components and labels - var usernameLabel = new Label { Text = "Username:" }; - - var userNameText = new TextField - { - // Position text field adjacent to the label - X = Pos.Right (usernameLabel) + 1, - - // Fill remaining horizontal space - Width = Dim.Fill () - }; - - var passwordLabel = new Label - { - Text = "Password:", X = Pos.Left (usernameLabel), Y = Pos.Bottom (usernameLabel) + 1 - }; - - var passwordText = new TextField - { - Secret = true, - - // align with the text box above - X = Pos.Left (userNameText), - Y = Pos.Top (passwordLabel), - Width = Dim.Fill () - }; - - // Create login button - var btnLogin = new Button - { - Text = "Login", - Y = Pos.Bottom (passwordLabel) + 1, - - // center the login button horizontally - X = Pos.Center (), - IsDefault = true - }; - - // When login button is clicked display a message popup - btnLogin.Accepting += (s, e) => - { - if (userNameText.Text == "admin" && passwordText.Text == "password") - { - MessageBox.Query ("Logging In", "Login Successful", "Ok"); - UserName = userNameText.Text; - Application.RequestStop (); - } - else - { - MessageBox.ErrorQuery ("Logging In", "Incorrect username or password", "Ok"); - } - // When Accepting is handled, set e.Handled to true to prevent further processing. - e.Handled = true; - }; - - // Add the views to the Window - Add (usernameLabel, userNameText, passwordLabel, passwordText, btnLogin); - } -} diff --git a/Examples/Example/Example.csproj b/Examples/Example/Example.csproj index 6d7e8c1b5a..5374a731cd 100644 --- a/Examples/Example/Example.csproj +++ b/Examples/Example/Example.csproj @@ -9,6 +9,11 @@ 2.0 2.0 + + + + + diff --git a/Examples/Example/ExampleWindow.cs b/Examples/Example/ExampleWindow.cs new file mode 100644 index 0000000000..6f34f5429e --- /dev/null +++ b/Examples/Example/ExampleWindow.cs @@ -0,0 +1,76 @@ +using Terminal.Gui.App; +using Terminal.Gui.ViewBase; +using Terminal.Gui.Views; +using RuntimeEnvironment = Microsoft.DotNet.PlatformAbstractions.RuntimeEnvironment; + +// Defines a top-level window with border and title +public class ExampleWindow : Window +{ + public static string? UserName { get; set; } + + public ExampleWindow () + { + Title = $"Example App ({Application.QuitKey} to quit)"; + + // Create input components and labels + var usernameLabel = new Label { Text = "Username:" }; + + var userNameText = new TextField + { + // Position text field adjacent to the label + X = Pos.Right (usernameLabel) + 1, + + // Fill remaining horizontal space + Width = Dim.Fill () + }; + + var passwordLabel = new Label + { + Text = "Password:", X = Pos.Left (usernameLabel), Y = Pos.Bottom (usernameLabel) + 1 + }; + + var passwordText = new TextField + { + Secret = true, + + // align with the text box above + X = Pos.Left (userNameText), + Y = Pos.Top (passwordLabel), + Width = Dim.Fill () + }; + + // Create login button + var btnLogin = new Button + { + Text = "Login", + Y = Pos.Bottom (passwordLabel) + 1, + + // center the login button horizontally + X = Pos.Center (), + IsDefault = true + }; + + // When login button is clicked display a message popup + btnLogin.Accepting += (s, e) => + { + if (userNameText.Text == "admin" && passwordText.Text == "password") + { + MessageBox.Query ("Logging In", "Login Successful", "Ok"); + UserName = userNameText.Text; + Application.RequestStop (); + } + else + { + MessageBox.ErrorQuery ("Logging In", "Incorrect username or password", "Ok"); + } + // When Accepting is handled, set e.Handled to true to prevent further processing. + e.Handled = true; + }; + + Height = Dim.Fill (); + Width = Dim.Fill (); + + // Add the views to the Window + Add (usernameLabel, userNameText, passwordLabel, passwordText, btnLogin); + } +} diff --git a/Examples/Example/Program.cs b/Examples/Example/Program.cs new file mode 100644 index 0000000000..6f74801e2e --- /dev/null +++ b/Examples/Example/Program.cs @@ -0,0 +1,21 @@ +// A simple Terminal.Gui example in C# - using C# 9.0 Top-level statements + +// This is a simple example application. For the full range of functionality +// see the UICatalog project + +using Terminal.Gui.Configuration; +using Terminal.Gui.App; + +// Override the default configuration for the application to use the Light theme +ConfigurationManager.RuntimeConfig = """{ "Theme": "Light" }"""; +ConfigurationManager.Enable(ConfigLocations.All); + +// As Run is used to start the application, it will create an instance of ExampleWindow and run it without needing to explicitly call `Application.Init()`. +Application.Run ().Dispose (); + +// Before the application exits, reset Terminal.Gui for clean shutdown +Application.Shutdown (); + +// To see this output on the screen it must be done after shutdown, +// which restores the previous screen. +Console.WriteLine ($@"Username: {ExampleWindow.UserName}"); diff --git a/Examples/NativeAot/NativeAot.csproj b/Examples/NativeAot/NativeAot.csproj index 928c003f39..701f8407c2 100644 --- a/Examples/NativeAot/NativeAot.csproj +++ b/Examples/NativeAot/NativeAot.csproj @@ -7,6 +7,10 @@ false + + + + @@ -17,4 +21,7 @@ + + + diff --git a/Examples/NativeAot/Program.cs b/Examples/NativeAot/Program.cs index bfc566c6d3..baf676941b 100644 --- a/Examples/NativeAot/Program.cs +++ b/Examples/NativeAot/Program.cs @@ -4,9 +4,7 @@ using System.Diagnostics.CodeAnalysis; using System.Globalization; using Terminal.Gui.Configuration; -using Terminal.Gui.Views; using Terminal.Gui.App; -using Terminal.Gui.ViewBase; namespace NativeAot; @@ -48,72 +46,3 @@ private static void Main (string [] args) Console.WriteLine ($@"Username: {ExampleWindow.UserName}"); } } - -// Defines a top-level window with border and title -public class ExampleWindow : Window -{ - public static string? UserName; - - public ExampleWindow () - { - Title = $"Example App ({Application.QuitKey} to quit)"; - - // Create input components and labels - var usernameLabel = new Label { Text = "Username:" }; - - var userNameText = new TextField - { - // Position text field adjacent to the label - X = Pos.Right (usernameLabel) + 1, - - // Fill remaining horizontal space - Width = Dim.Fill () - }; - - var passwordLabel = new Label - { - Text = "Password:", X = Pos.Left (usernameLabel), Y = Pos.Bottom (usernameLabel) + 1 - }; - - var passwordText = new TextField - { - Secret = true, - - // align with the text box above - X = Pos.Left (userNameText), - Y = Pos.Top (passwordLabel), - Width = Dim.Fill () - }; - - // Create login button - var btnLogin = new Button - { - Text = "Login", - Y = Pos.Bottom (passwordLabel) + 1, - - // center the login button horizontally - X = Pos.Center (), - IsDefault = true - }; - - // When login button is clicked display a message popup - btnLogin.Accepting += (s, e) => - { - if (userNameText.Text == "admin" && passwordText.Text == "password") - { - MessageBox.Query ("Logging In", "Login Successful", "Ok"); - UserName = userNameText.Text; - Application.RequestStop (); - } - else - { - MessageBox.ErrorQuery ("Logging In", "Incorrect username or password", "Ok"); - } - // Anytime Accepting is handled, make sure to set e.Handled to true. - e.Handled = true; - }; - - // Add the views to the Window - Add (usernameLabel, userNameText, passwordLabel, passwordText, btnLogin); - } -} diff --git a/Examples/NativeAot/Properties/launchSettings.json b/Examples/NativeAot/Properties/launchSettings.json deleted file mode 100644 index a7872f0012..0000000000 --- a/Examples/NativeAot/Properties/launchSettings.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "profiles": { - "NativeAot": { - "commandName": "Project" - }, - "WSL : NativeAot": { - "commandName": "Executable", - "executablePath": "wsl", - "commandLineArgs": "dotnet NativeAot.dll", - "distributionName": "" - } - } -} \ No newline at end of file diff --git a/Examples/NativeAot/README.md b/Examples/NativeAot/README.md index 7a55ccfc7c..6969fbc77c 100644 --- a/Examples/NativeAot/README.md +++ b/Examples/NativeAot/README.md @@ -1,4 +1,4 @@ -# Terminal.Gui C# SelfContained +# Terminal.Gui C# NativeAot This project aims to test the `Terminal.Gui` library to create a simple `native AOT` `self-container` GUI application in C#, ensuring that all its features are available. diff --git a/Examples/ReactiveExample/LoginView.cs b/Examples/ReactiveExample/LoginView.cs index 0eb5e7a345..e72f95f769 100644 --- a/Examples/ReactiveExample/LoginView.cs +++ b/Examples/ReactiveExample/LoginView.cs @@ -6,6 +6,7 @@ using Terminal.Gui.Views; using Terminal.Gui.App; using Terminal.Gui.ViewBase; +using RuntimeEnvironment = Microsoft.DotNet.PlatformAbstractions.RuntimeEnvironment; namespace ReactiveExample; diff --git a/Examples/ReactiveExample/ReactiveExample.csproj b/Examples/ReactiveExample/ReactiveExample.csproj index f639a03d79..d5da8345c1 100644 --- a/Examples/ReactiveExample/ReactiveExample.csproj +++ b/Examples/ReactiveExample/ReactiveExample.csproj @@ -13,6 +13,7 @@ + diff --git a/Examples/SelfContained/Program.cs b/Examples/SelfContained/Program.cs index 2cfdb8cc94..4e9e71642d 100644 --- a/Examples/SelfContained/Program.cs +++ b/Examples/SelfContained/Program.cs @@ -5,8 +5,6 @@ using System.Globalization; using Terminal.Gui.Configuration; using Terminal.Gui.App; -using Terminal.Gui.ViewBase; -using Terminal.Gui.Views; namespace SelfContained; @@ -47,72 +45,3 @@ private static void Main (string [] args) Console.WriteLine ($@"Username: {ExampleWindow.UserName}"); } } - -// Defines a top-level window with border and title -public class ExampleWindow : Window -{ - public static string? UserName; - - public ExampleWindow () - { - Title = $"Example App ({Application.QuitKey} to quit)"; - - // Create input components and labels - var usernameLabel = new Label { Text = "Username:" }; - - var userNameText = new TextField - { - // Position text field adjacent to the label - X = Pos.Right (usernameLabel) + 1, - - // Fill remaining horizontal space - Width = Dim.Fill () - }; - - var passwordLabel = new Label - { - Text = "Password:", X = Pos.Left (usernameLabel), Y = Pos.Bottom (usernameLabel) + 1 - }; - - var passwordText = new TextField - { - Secret = true, - - // align with the text box above - X = Pos.Left (userNameText), - Y = Pos.Top (passwordLabel), - Width = Dim.Fill () - }; - - // Create login button - var btnLogin = new Button - { - Text = "Login", - Y = Pos.Bottom (passwordLabel) + 1, - - // center the login button horizontally - X = Pos.Center (), - IsDefault = true - }; - - // When login button is clicked display a message popup - btnLogin.Accepting += (s, e) => - { - if (userNameText.Text == "admin" && passwordText.Text == "password") - { - MessageBox.Query ("Logging In", "Login Successful", "Ok"); - UserName = userNameText.Text; - Application.RequestStop (); - } - else - { - MessageBox.ErrorQuery ("Logging In", "Incorrect username or password", "Ok"); - } - // When Accepting is handled, set e.Handled to true to prevent further processing. - e.Handled = true; - }; - - // Add the views to the Window - Add (usernameLabel, userNameText, passwordLabel, passwordText, btnLogin); - } -} diff --git a/Examples/SelfContained/SelfContained.csproj b/Examples/SelfContained/SelfContained.csproj index c7f907753b..572e27e009 100644 --- a/Examples/SelfContained/SelfContained.csproj +++ b/Examples/SelfContained/SelfContained.csproj @@ -10,6 +10,10 @@ embedded + + + + @@ -20,4 +24,7 @@ + + + diff --git a/Terminal.Gui/Terminal.Gui.csproj b/Terminal.Gui/Terminal.Gui.csproj index 0646dce055..0e1856adee 100644 --- a/Terminal.Gui/Terminal.Gui.csproj +++ b/Terminal.Gui/Terminal.Gui.csproj @@ -82,6 +82,7 @@ + @@ -162,9 +163,9 @@ --> - - - + + + diff --git a/Terminal.sln b/Terminal.sln index 4c84370978..6a2b839ce1 100644 --- a/Terminal.sln +++ b/Terminal.sln @@ -75,6 +75,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TerminalGuiFluentTestingXun EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TerminalGuiFluentTestingXunit.Generator", "Tests\TerminalGuiFluentTestingXunit.Generator\TerminalGuiFluentTestingXunit.Generator.csproj", "{199F27D8-A905-4DDC-82CA-1FE1A90B1788}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTests.AOT", "Tests\UnitTests.AOT\UnitTests.AOT.csproj", "{F9E1362D-29EC-4C77-9E83-BCEA54553CCD}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -141,6 +143,10 @@ Global {199F27D8-A905-4DDC-82CA-1FE1A90B1788}.Debug|Any CPU.Build.0 = Debug|Any CPU {199F27D8-A905-4DDC-82CA-1FE1A90B1788}.Release|Any CPU.ActiveCfg = Release|Any CPU {199F27D8-A905-4DDC-82CA-1FE1A90B1788}.Release|Any CPU.Build.0 = Release|Any CPU + {F9E1362D-29EC-4C77-9E83-BCEA54553CCD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F9E1362D-29EC-4C77-9E83-BCEA54553CCD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F9E1362D-29EC-4C77-9E83-BCEA54553CCD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F9E1362D-29EC-4C77-9E83-BCEA54553CCD}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Terminal.sln.DotSettings b/Terminal.sln.DotSettings index fd588071f4..007e4c6a38 100644 --- a/Terminal.sln.DotSettings +++ b/Terminal.sln.DotSettings @@ -381,6 +381,7 @@ False True True + AOT CWP LL LR diff --git a/Tests/UnitTests.AOT/UnitTests.AOT.csproj b/Tests/UnitTests.AOT/UnitTests.AOT.csproj new file mode 100644 index 0000000000..91aaac6506 --- /dev/null +++ b/Tests/UnitTests.AOT/UnitTests.AOT.csproj @@ -0,0 +1,96 @@ + + + + + + 2.0 + 2.0 + 2.0 + 2.0 + + + false + + true + true + AOT + + true + true + portable + $(DefineConstants);JETBRAINS_ANNOTATIONS;CONTRACTS_FULL + enable + true + true + + + true + $(DefineConstants);DEBUG_IDISPOSABLE + + + true + + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + PreserveNewest + + + + + + + + + + False + + + [UICatalog]* + + + + + + + + + + False + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Tests/UnitTests.AOT/coverlet.runsettings b/Tests/UnitTests.AOT/coverlet.runsettings new file mode 100644 index 0000000000..fd3b5ceca9 --- /dev/null +++ b/Tests/UnitTests.AOT/coverlet.runsettings @@ -0,0 +1,23 @@ + + + + + + + opencover + [UnitTests]*,[UnitTests.AOT]*,[UICatalog]*,[coverlet.*.tests?]*,[*]Coverlet.Core* + + + + + false + true + true + true + false + TestResults/ + + + + + \ No newline at end of file diff --git a/Tests/UnitTests/ConsoleDrivers/AnsiRequestSchedulerTests.cs b/Tests/UnitTests/ConsoleDrivers/AnsiRequestSchedulerTests.cs index 3dcfaeedd7..265644c27d 100644 --- a/Tests/UnitTests/ConsoleDrivers/AnsiRequestSchedulerTests.cs +++ b/Tests/UnitTests/ConsoleDrivers/AnsiRequestSchedulerTests.cs @@ -17,7 +17,7 @@ public AnsiRequestSchedulerTests () _scheduler = new AnsiRequestScheduler (_parserMock.Object, () => _staticNow); } - [Fact] + [FactSkipIfAOT] public void SendOrSchedule_SendsDeviceAttributeRequest_WhenNoOutstandingRequests () { // Arrange @@ -43,7 +43,7 @@ public void SendOrSchedule_SendsDeviceAttributeRequest_WhenNoOutstandingRequests Assert.True (result); // Should send immediately _parserMock.Verify (); } - [Fact] + [FactSkipIfAOT] public void SendOrSchedule_QueuesRequest_WhenOutstandingRequestExists () { // Arrange @@ -67,7 +67,7 @@ public void SendOrSchedule_QueuesRequest_WhenOutstandingRequestExists () } - [Fact] + [FactSkipIfAOT] public void RunSchedule_ThrottleNotExceeded_AllowSend () { // Arrange @@ -99,7 +99,7 @@ public void RunSchedule_ThrottleNotExceeded_AllowSend () _parserMock.Verify (); } - [Fact] + [FactSkipIfAOT] public void RunSchedule_ThrottleExceeded_QueueRequest () { // Arrange @@ -145,7 +145,7 @@ public void RunSchedule_ThrottleExceeded_QueueRequest () _parserMock.Verify (); } - [Fact] + [FactSkipIfAOT] public void EvictStaleRequests_RemovesStaleRequest_AfterTimeout () { // Arrange @@ -190,7 +190,7 @@ public void EvictStaleRequests_RemovesStaleRequest_AfterTimeout () _parserMock.Verify (); } - [Fact] + [FactSkipIfAOT] public void RunSchedule_DoesNothing_WhenQueueIsEmpty () { // Act @@ -201,7 +201,7 @@ public void RunSchedule_DoesNothing_WhenQueueIsEmpty () Assert.Empty (_scheduler.QueuedRequests); } - [Fact] + [FactSkipIfAOT] public void SendOrSchedule_ManagesIndependentTerminatorsCorrectly () { // Arrange diff --git a/Tests/UnitTests/ConsoleDrivers/V2/ApplicationV2Tests.cs b/Tests/UnitTests/ConsoleDrivers/V2/ApplicationV2Tests.cs index 0a34417fac..5d93e6e497 100644 --- a/Tests/UnitTests/ConsoleDrivers/V2/ApplicationV2Tests.cs +++ b/Tests/UnitTests/ConsoleDrivers/V2/ApplicationV2Tests.cs @@ -26,7 +26,7 @@ private ApplicationV2 NewApplicationV2 () Mock.Of); } - [Fact] + [FactSkipIfAOT] public void Init_CreatesKeybindings () { var orig = ApplicationImpl.Instance; @@ -47,7 +47,7 @@ public void Init_CreatesKeybindings () ApplicationImpl.ChangeInstance (orig); } - [Fact] + [FactSkipIfAOT] public void Init_DriverIsFacade () { var orig = ApplicationImpl.Instance; @@ -69,7 +69,7 @@ public void Init_DriverIsFacade () ApplicationImpl.ChangeInstance (orig); } - [Fact] + [FactSkipIfAOT] public void Init_ExplicitlyRequestWin () { var orig = ApplicationImpl.Instance; @@ -111,7 +111,7 @@ public void Init_ExplicitlyRequestWin () ApplicationImpl.ChangeInstance (orig); } - [Fact] + [FactSkipIfAOT] public void Init_ExplicitlyRequestNet () { var orig = ApplicationImpl.Instance; @@ -165,6 +165,7 @@ private void SetupRunInputMockMethodToBlock (Mock winInput) }) .Verifiable (Times.Once); } + private void SetupRunInputMockMethodToBlock (Mock netInput) { netInput.Setup (r => r.Run (It.IsAny ())) @@ -196,7 +197,7 @@ public void NoInitThrowOnRun () ApplicationImpl.ChangeInstance (orig); } - [Fact] + [FactSkipIfAOT] public void InitRunShutdown_Top_Set_To_Null_After_Shutdown () { var orig = ApplicationImpl.Instance; @@ -235,7 +236,7 @@ public void InitRunShutdown_Top_Set_To_Null_After_Shutdown () ApplicationImpl.ChangeInstance (orig); } - [Fact] + [FactSkipIfAOT] public void InitRunShutdown_Running_Set_To_False () { var orig = ApplicationImpl.Instance; @@ -280,7 +281,7 @@ public void InitRunShutdown_Running_Set_To_False () ApplicationImpl.ChangeInstance (orig); } - [Fact] + [FactSkipIfAOT] public void InitRunShutdown_End_Is_Called () { var orig = ApplicationImpl.Instance; @@ -344,8 +345,7 @@ public void InitRunShutdown_End_Is_Called () ApplicationImpl.ChangeInstance (orig); } - - [Fact] + [FactSkipIfAOT] public void InitRunShutdown_QuitKey_Quits () { var orig = ApplicationImpl.Instance; @@ -390,8 +390,7 @@ public void InitRunShutdown_QuitKey_Quits () ApplicationImpl.ChangeInstance (orig); } - - [Fact] + [FactSkipIfAOT] public void InitRunShutdown_Generic_IdleForExit () { var orig = ApplicationImpl.Instance; @@ -416,7 +415,7 @@ public void InitRunShutdown_Generic_IdleForExit () ApplicationImpl.ChangeInstance (orig); } - [Fact] + [FactSkipIfAOT] public void Shutdown_Closing_Closed_Raised () { var orig = ApplicationImpl.Instance; @@ -474,7 +473,7 @@ private bool IdleExit () return true; } - [Fact] + [FactSkipIfAOT] public void Shutdown_Called_Repeatedly_DoNotDuplicateDisposeOutput () { var orig = ApplicationImpl.Instance; @@ -501,7 +500,7 @@ public void Shutdown_Called_Repeatedly_DoNotDuplicateDisposeOutput () ApplicationImpl.ChangeInstance (orig); } - [Fact] + [FactSkipIfAOT] public void Init_Called_Repeatedly_WarnsAndIgnores () { var orig = ApplicationImpl.Instance; @@ -537,7 +536,7 @@ public void Init_Called_Repeatedly_WarnsAndIgnores () ApplicationImpl.ChangeInstance (orig); } - [Fact] + [FactSkipIfAOT] public void Open_Calls_ContinueWith_On_UIThread () { var orig = ApplicationImpl.Instance; diff --git a/Tests/UnitTests/ConsoleDrivers/V2/MainLoopCoordinatorTests.cs b/Tests/UnitTests/ConsoleDrivers/V2/MainLoopCoordinatorTests.cs index 4c2a32e6fc..982be02d91 100644 --- a/Tests/UnitTests/ConsoleDrivers/V2/MainLoopCoordinatorTests.cs +++ b/Tests/UnitTests/ConsoleDrivers/V2/MainLoopCoordinatorTests.cs @@ -5,7 +5,7 @@ namespace UnitTests.ConsoleDrivers.V2; public class MainLoopCoordinatorTests { - [Fact] + [FactSkipIfAOT] public async Task TestMainLoopCoordinator_InputCrashes_ExceptionSurfacesMainThread () { diff --git a/Tests/UnitTests/ConsoleDrivers/V2/MainLoopTTests.cs b/Tests/UnitTests/ConsoleDrivers/V2/MainLoopTTests.cs index 727c105536..7f6eb59d56 100644 --- a/Tests/UnitTests/ConsoleDrivers/V2/MainLoopTTests.cs +++ b/Tests/UnitTests/ConsoleDrivers/V2/MainLoopTTests.cs @@ -6,7 +6,7 @@ namespace UnitTests.ConsoleDrivers.V2; public class MainLoopTTests { - [Fact] + [FactSkipIfAOT] public void MainLoopT_NotInitialized_Throws() { var m = new MainLoop (); diff --git a/Tests/UnitTests/ConsoleDrivers/V2/WindowSizeMonitorTests.cs b/Tests/UnitTests/ConsoleDrivers/V2/WindowSizeMonitorTests.cs index 89dde8af1b..e2cf1feb90 100644 --- a/Tests/UnitTests/ConsoleDrivers/V2/WindowSizeMonitorTests.cs +++ b/Tests/UnitTests/ConsoleDrivers/V2/WindowSizeMonitorTests.cs @@ -8,7 +8,7 @@ public WindowSizeMonitorTests () ConsoleDriver.RunningUnitTests = false; } - [Fact] + [FactSkipIfAOT] public void TestWindowSizeMonitor_RaisesEventWhenChanges () { var consoleOutput = new Mock (); @@ -42,7 +42,7 @@ public void TestWindowSizeMonitor_RaisesEventWhenChanges () Assert.Equal (new Size (20, 20), result [1].Size); } - [Fact] + [FactSkipIfAOT] public void TestWindowSizeMonitor_DoesNotRaiseEventWhen_NoChanges () { var consoleOutput = new Mock (); diff --git a/Tests/UnitTests/FactSkipIfAOTAttribute.cs b/Tests/UnitTests/FactSkipIfAOTAttribute.cs new file mode 100644 index 0000000000..df7d6ad995 --- /dev/null +++ b/Tests/UnitTests/FactSkipIfAOTAttribute.cs @@ -0,0 +1,17 @@ +namespace UnitTests; + +public class FactSkipIfAOTAttribute : FactAttribute +{ + public FactSkipIfAOTAttribute () + { + if (IsAOTEnvironment ()) + { + base.Skip = "Test skipped in AOT project due to Moq incompatibility."; + } + } + + private static bool IsAOTEnvironment () + { + return Type.GetType ("System.Runtime.CompilerServices.RuntimeFeature")?.GetProperty ("IsDynamicCodeSupported")?.GetValue (null) is bool and false; + } +} diff --git a/Tests/UnitTests/UnitTests.csproj b/Tests/UnitTests/UnitTests.csproj index f1558775d2..50eb52466f 100644 --- a/Tests/UnitTests/UnitTests.csproj +++ b/Tests/UnitTests/UnitTests.csproj @@ -57,9 +57,6 @@ - - - False diff --git a/Tests/UnitTests/View/Draw/ClearViewportTests.cs b/Tests/UnitTests/View/Draw/ClearViewportTests.cs index 5aa69954fe..3180b55ccf 100644 --- a/Tests/UnitTests/View/Draw/ClearViewportTests.cs +++ b/Tests/UnitTests/View/Draw/ClearViewportTests.cs @@ -26,7 +26,7 @@ protected override bool OnClearingViewport () protected override void OnClearedViewport () { OnClearedViewportCalled++; } } - [Fact] + [FactSkipIfAOT] public void DoClearViewport_ViewportIsTransparent_DoesNotClear () { // Arrange @@ -41,7 +41,7 @@ public void DoClearViewport_ViewportIsTransparent_DoesNotClear () Assert.Equal (0, view.Object.OnClearedViewportCalled); } - [Fact] + [FactSkipIfAOT] public void DoClearViewport_OnClearingViewportReturnsTrue_DoesNotClear () { // Arrange @@ -55,7 +55,7 @@ public void DoClearViewport_OnClearingViewportReturnsTrue_DoesNotClear () Assert.Equal (0, view.Object.OnClearedViewportCalled); } - [Fact] + [FactSkipIfAOT] public void DoClearViewport_ClearingViewportEventCancelled_DoesNotClear () { // Arrange @@ -69,7 +69,7 @@ public void DoClearViewport_ClearingViewportEventCancelled_DoesNotClear () Assert.Equal (0, view.Object.OnClearedViewportCalled); } - [Fact] + [FactSkipIfAOT] public void DoClearViewport_ClearsViewport () { // Arrange @@ -82,7 +82,7 @@ public void DoClearViewport_ClearsViewport () Assert.Equal (1, view.Object.OnClearedViewportCalled); } - [Fact] + [FactSkipIfAOT] public void DoClearViewport_RaisesClearingViewportEvent () { // Arrange