From eaf540df8af32ae5ed4b33f7200c5a95e93c5780 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 22 Mar 2026 13:43:39 +0000 Subject: [PATCH 01/26] Initial plan From 7b7d49be7eae0c1a6de9982d29e58bd8f7f695d0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 22 Mar 2026 14:00:00 +0000 Subject: [PATCH 02/26] Refactor tests: rename UnitTests to UnitTests.Legacy, add UnitTests.NonParallelizable Co-authored-by: tig <585482+tig@users.noreply.github.com> Agent-Logs-Url: https://github.com/gui-cs/Terminal.Gui/sessions/ef0c73fd-ea61-4cf7-a133-0722922a198b --- .github/workflows/unit-tests.yml | 21 +++-- Terminal.Gui/Terminal.Gui.csproj | 2 + Terminal.sln | 11 ++- Tests/README.md | 86 ++++++++++++++++--- .../ApplicationForceDriverTests.cs | 0 .../Application/ApplicationPopoverTests.cs | 0 .../Application/ApplicationScreenTests.cs | 0 .../Application/MainLoopTTests.cs | 0 .../Mouse/ApplicationMouseTests.cs | 0 .../Application/SynchronizatonContextTests.cs | 0 .../Application/TimedEventsTests.cs | 0 .../AssemblyInfo.cs | 0 .../AutoInitShutdownAttribute.cs | 0 .../Clipboard/ClipboardTests.cs | 0 .../Configuration/AppScopeTests.cs | 0 .../Configuration/ConfigPropertyTests.cs | 0 .../Configuration/ConfigurationMangerTests.cs | 0 .../Configuration/GlyphTests.cs | 0 .../Configuration/KeyJsonConverterTests.cs | 0 .../Configuration/MemorySizeEstimator.cs | 0 .../Configuration/SchemeManagerTests.cs | 0 .../Configuration/SettingsScopeTests.cs | 0 .../Configuration/SourcesManagerTests.cs | 0 .../Configuration/ThemeManagerTests.cs | 0 .../Configuration/ThemeScopeTests.cs | 0 .../Configuration/ThemeTests.cs | 0 .../Dialogs/WizardTests.cs | 0 .../DriverAssert.cs | 0 .../FakeDriver/FakeApplicationFactory.cs | 0 .../FakeDriver/FakeApplicationLifecycle.cs | 0 .../FileServices/FileDialogTests.cs | 0 .../TreeViewFileSystemNavigationTests.cs | 0 .../OutputAssert.cs | 0 Tests/UnitTests.Legacy/README.md | 13 +++ .../SetupFakeApplicationAttribute.cs | 0 .../TestDriverBase.cs | 0 .../TestLogging.cs | 0 .../TestRespondersDisposedAttribute.cs | 0 .../TestsAllViews.cs | 0 .../Text/AutocompleteTests.cs | 0 .../Tracing/ThreadSafeTraceTests.cs | 0 .../UICatalog/RunnerTests.cs | 0 .../UICatalog/ScenarioLogCaptureTests.cs | 0 .../UICatalog/ScenarioTests.cs | 0 .../UnitTests.Legacy.csproj} | 1 + .../UnitTests.Legacy.csproj.DotSettings} | 0 .../UnitTests.Legacy.sln} | 2 +- .../View/Adornment/AdornmentTests.cs | 0 .../View/Adornment/BorderTests.cs | 0 .../View/Adornment/PaddingTests.cs | 0 .../View/Adornment/ShadowStyleTests.cs | 0 .../View/ArrangementTests.cs | 0 .../View/DiagnosticsTests.cs | 0 .../View/Draw/ClipTests.cs | 0 .../View/Draw/DrawEventTests.cs | 0 .../View/Draw/DrawTests.cs | 0 .../View/Draw/NeedsDrawTests.cs | 0 .../View/Draw/TransparentTests.cs | 0 .../View/Layout/Dim.Tests.cs | 0 .../View/Layout/Pos.Tests.cs | 0 .../View/Layout/Pos.ViewTests.cs | 0 .../View/Mouse/MouseTests.cs | 0 .../View/Navigation/EnabledTests.cs | 0 .../View/SchemeTests.cs | 0 .../View/SubviewTests.cs | 0 .../View/TextTests.cs | 0 .../View/ViewTests.cs | 0 .../Views/AppendAutocompleteTests.cs | 0 .../Views/ButtonTests.cs | 0 .../Views/CheckBoxTests.cs | 0 .../Views/ColorPickerTests.cs | 0 .../Views/DatePickerTests.cs | 0 .../Views/DialogTests.cs | 0 .../Views/FrameViewTests.cs | 0 .../Views/GraphViewTests.cs | 0 .../Views/LabelTests.cs | 0 .../Views/MessageBoxTests.cs | 0 .../Views/ProgressBarTests.cs | 0 .../Views/ScrollBarTests.cs | 0 .../Views/SpinnerViewTests.cs | 0 .../Views/StatusBarTests.cs | 0 .../Views/TabTests.cs | 0 .../Views/TabViewTests.cs | 0 .../Views/TableViewTests.cs | 0 .../Views/TextFieldTests.cs | 0 .../Views/TextViewTests.History.cs | 0 .../Views/TextViewTests.cs | 0 .../Views/TreeTableSourceTests.cs | 0 ...TreeViewCollectionNavigatorMatcherTests.cs | 0 .../Views/TreeViewTests.cs | 0 .../Views/ViewDisposalTest.cs | 0 .../Views/WindowTests.cs | 0 .../runsettings.coverage.xml | 0 .../runsettings.xml | 0 .../xunit.runner.json | 0 .../ApplicationModelFencingTests.cs | 2 +- .../ApplicationKeyboardThreadSafetyTests.cs | 2 +- .../Keyboard/KeyboardSetterTests.cs | 2 +- .../AssemblyInfo.cs | 15 ++++ Tests/UnitTests.NonParallelizable/README.md | 24 ++++++ .../UnitTests.NonParallelizable.csproj | 61 +++++++++++++ .../xunit.runner.json | 6 ++ Tests/UnitTests/README.md | 5 -- .../UnitTests.Parallelizable.csproj | 4 +- 104 files changed, 227 insertions(+), 30 deletions(-) rename Tests/{UnitTests => UnitTests.Legacy}/Application/ApplicationForceDriverTests.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/Application/ApplicationPopoverTests.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/Application/ApplicationScreenTests.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/Application/MainLoopTTests.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/Application/Mouse/ApplicationMouseTests.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/Application/SynchronizatonContextTests.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/Application/TimedEventsTests.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/AssemblyInfo.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/AutoInitShutdownAttribute.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/Clipboard/ClipboardTests.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/Configuration/AppScopeTests.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/Configuration/ConfigPropertyTests.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/Configuration/ConfigurationMangerTests.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/Configuration/GlyphTests.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/Configuration/KeyJsonConverterTests.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/Configuration/MemorySizeEstimator.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/Configuration/SchemeManagerTests.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/Configuration/SettingsScopeTests.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/Configuration/SourcesManagerTests.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/Configuration/ThemeManagerTests.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/Configuration/ThemeScopeTests.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/Configuration/ThemeTests.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/Dialogs/WizardTests.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/DriverAssert.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/FakeDriver/FakeApplicationFactory.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/FakeDriver/FakeApplicationLifecycle.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/FileServices/FileDialogTests.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/FileServices/TreeViewFileSystemNavigationTests.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/OutputAssert.cs (100%) create mode 100644 Tests/UnitTests.Legacy/README.md rename Tests/{UnitTests => UnitTests.Legacy}/SetupFakeApplicationAttribute.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/TestDriverBase.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/TestLogging.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/TestRespondersDisposedAttribute.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/TestsAllViews.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/Text/AutocompleteTests.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/Tracing/ThreadSafeTraceTests.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/UICatalog/RunnerTests.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/UICatalog/ScenarioLogCaptureTests.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/UICatalog/ScenarioTests.cs (100%) rename Tests/{UnitTests/UnitTests.csproj => UnitTests.Legacy/UnitTests.Legacy.csproj} (98%) rename Tests/{UnitTests/UnitTests.csproj.DotSettings => UnitTests.Legacy/UnitTests.Legacy.csproj.DotSettings} (100%) rename Tests/{UnitTests/UnitTests.sln => UnitTests.Legacy/UnitTests.Legacy.sln} (87%) rename Tests/{UnitTests => UnitTests.Legacy}/View/Adornment/AdornmentTests.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/View/Adornment/BorderTests.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/View/Adornment/PaddingTests.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/View/Adornment/ShadowStyleTests.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/View/ArrangementTests.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/View/DiagnosticsTests.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/View/Draw/ClipTests.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/View/Draw/DrawEventTests.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/View/Draw/DrawTests.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/View/Draw/NeedsDrawTests.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/View/Draw/TransparentTests.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/View/Layout/Dim.Tests.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/View/Layout/Pos.Tests.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/View/Layout/Pos.ViewTests.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/View/Mouse/MouseTests.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/View/Navigation/EnabledTests.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/View/SchemeTests.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/View/SubviewTests.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/View/TextTests.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/View/ViewTests.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/Views/AppendAutocompleteTests.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/Views/ButtonTests.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/Views/CheckBoxTests.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/Views/ColorPickerTests.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/Views/DatePickerTests.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/Views/DialogTests.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/Views/FrameViewTests.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/Views/GraphViewTests.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/Views/LabelTests.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/Views/MessageBoxTests.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/Views/ProgressBarTests.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/Views/ScrollBarTests.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/Views/SpinnerViewTests.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/Views/StatusBarTests.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/Views/TabTests.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/Views/TabViewTests.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/Views/TableViewTests.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/Views/TextFieldTests.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/Views/TextViewTests.History.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/Views/TextViewTests.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/Views/TreeTableSourceTests.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/Views/TreeViewCollectionNavigatorMatcherTests.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/Views/TreeViewTests.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/Views/ViewDisposalTest.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/Views/WindowTests.cs (100%) rename Tests/{UnitTests => UnitTests.Legacy}/runsettings.coverage.xml (100%) rename Tests/{UnitTests => UnitTests.Legacy}/runsettings.xml (100%) rename Tests/{UnitTests => UnitTests.Legacy}/xunit.runner.json (100%) rename Tests/{UnitTests => UnitTests.NonParallelizable}/Application/ApplicationModelFencingTests.cs (99%) rename Tests/{UnitTests => UnitTests.NonParallelizable}/Application/Keyboard/ApplicationKeyboardThreadSafetyTests.cs (99%) rename Tests/{UnitTests => UnitTests.NonParallelizable}/Application/Keyboard/KeyboardSetterTests.cs (98%) create mode 100644 Tests/UnitTests.NonParallelizable/AssemblyInfo.cs create mode 100644 Tests/UnitTests.NonParallelizable/README.md create mode 100644 Tests/UnitTests.NonParallelizable/UnitTests.NonParallelizable.csproj create mode 100644 Tests/UnitTests.NonParallelizable/xunit.runner.json delete mode 100644 Tests/UnitTests/README.md diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index 9cd63dfb0c..2c2f7453e0 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -47,14 +47,23 @@ jobs: Add-MpPreference -ExclusionPath "${{ github.workspace }}" Add-MpPreference -ExclusionProcess "dotnet.exe" - - name: Run UnitTests + - name: Run UnitTests.Legacy shell: bash run: | dotnet test \ - --project Tests/UnitTests \ + --project Tests/UnitTests.Legacy \ --no-build \ --verbosity normal \ - --diagnostic --diagnostic-output-directory logs/UnitTests/${{ runner.os }} + --diagnostic --diagnostic-output-directory logs/UnitTests.Legacy/${{ runner.os }} + + - name: Run UnitTests.NonParallelizable + shell: bash + run: | + dotnet test \ + --project Tests/UnitTests.NonParallelizable \ + --no-build \ + --verbosity normal \ + --diagnostic --diagnostic-output-directory logs/UnitTests.NonParallelizable/${{ runner.os }} - name: Upload Test Logs if: always() @@ -62,8 +71,10 @@ jobs: with: name: non_parallel_unittests-logs-${{ runner.os }} path: | - logs/UnitTests/ - Tests/UnitTests/logs/ + logs/UnitTests.Legacy/ + Tests/UnitTests.Legacy/logs/ + logs/UnitTests.NonParallelizable/ + Tests/UnitTests.NonParallelizable/logs/ TestResults/ **/*.dmp if-no-files-found: ignore diff --git a/Terminal.Gui/Terminal.Gui.csproj b/Terminal.Gui/Terminal.Gui.csproj index 544579f229..1ae0543353 100644 --- a/Terminal.Gui/Terminal.Gui.csproj +++ b/Terminal.Gui/Terminal.Gui.csproj @@ -83,6 +83,8 @@ + + diff --git a/Terminal.sln b/Terminal.sln index e2663bcd20..30911810be 100644 --- a/Terminal.sln +++ b/Terminal.sln @@ -105,7 +105,9 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NativeAot", "Examples\Nativ EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Benchmarks", "Tests\Benchmarks\Benchmarks.csproj", "{242FBD3E-2EC6-4274-BD40-8E62AF9327B2}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTests", "Tests\UnitTests\UnitTests.csproj", "{038B09F5-EF3A-F21E-7C10-A6551866ECE2}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTests.Legacy", "Tests\UnitTests.Legacy\UnitTests.Legacy.csproj", "{038B09F5-EF3A-F21E-7C10-A6551866ECE2}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTests.NonParallelizable", "Tests\UnitTests.NonParallelizable\UnitTests.NonParallelizable.csproj", "{B7C94F2A-3E8D-4A1B-9F5C-2D1E6A3B7C90}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IntegrationTests", "Tests\IntegrationTests\IntegrationTests.csproj", "{F74EC349-B988-FCFA-A1E5-967F70FB75B5}" EndProject @@ -123,7 +125,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Testing", "Testing", "{1A3C ProjectSection(SolutionItems) = preProject codecov.yml = codecov.yml Scripts\Run-LocalCoverage.ps1 = Scripts\Run-LocalCoverage.ps1 - Tests\UnitTests\runsettings.xml = Tests\UnitTests\runsettings.xml + Tests\UnitTests.Legacy\runsettings.xml = Tests\UnitTests.Legacy\runsettings.xml EndProjectSection EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FluentExample", "Examples\FluentExample\FluentExample.csproj", "{8C05292F-86C9-C29A-635B-A4DFC5955D1C}" @@ -189,6 +191,10 @@ Global {038B09F5-EF3A-F21E-7C10-A6551866ECE2}.Debug|Any CPU.Build.0 = Debug|Any CPU {038B09F5-EF3A-F21E-7C10-A6551866ECE2}.Release|Any CPU.ActiveCfg = Release|Any CPU {038B09F5-EF3A-F21E-7C10-A6551866ECE2}.Release|Any CPU.Build.0 = Release|Any CPU + {B7C94F2A-3E8D-4A1B-9F5C-2D1E6A3B7C90}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B7C94F2A-3E8D-4A1B-9F5C-2D1E6A3B7C90}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B7C94F2A-3E8D-4A1B-9F5C-2D1E6A3B7C90}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B7C94F2A-3E8D-4A1B-9F5C-2D1E6A3B7C90}.Release|Any CPU.Build.0 = Release|Any CPU {F74EC349-B988-FCFA-A1E5-967F70FB75B5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {F74EC349-B988-FCFA-A1E5-967F70FB75B5}.Debug|Any CPU.Build.0 = Debug|Any CPU {F74EC349-B988-FCFA-A1E5-967F70FB75B5}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -248,6 +254,7 @@ Global {E6D716C6-AC94-4150-B10A-44AE13F79344} = {3DD033C0-E023-47BF-A808-9CCE30873C3E} {242FBD3E-2EC6-4274-BD40-8E62AF9327B2} = {A589126F-C71A-4FEE-B7EA-2DCA1ADF6A46} {038B09F5-EF3A-F21E-7C10-A6551866ECE2} = {A589126F-C71A-4FEE-B7EA-2DCA1ADF6A46} + {B7C94F2A-3E8D-4A1B-9F5C-2D1E6A3B7C90} = {A589126F-C71A-4FEE-B7EA-2DCA1ADF6A46} {F74EC349-B988-FCFA-A1E5-967F70FB75B5} = {A589126F-C71A-4FEE-B7EA-2DCA1ADF6A46} {96ACE8BA-2E07-7537-FBF2-E8176CCB8080} = {A589126F-C71A-4FEE-B7EA-2DCA1ADF6A46} {DE780834-190A-8277-51FD-750CC666E82D} = {A589126F-C71A-4FEE-B7EA-2DCA1ADF6A46} diff --git a/Tests/README.md b/Tests/README.md index 805a8b54a9..78efbc3b35 100644 --- a/Tests/README.md +++ b/Tests/README.md @@ -2,28 +2,90 @@ This folder contains the tests for Terminal.Gui. -## ./UnitTests +## Test Projects -This folder contains the unit tests for Terminal.Gui that can not be run in parallel. This is because they -depend on `Application` or other class that use static state or `ConfigurationManager`. +### ./UnitTestsParallelizable -We should be striving to move as many tests as possible to the `./UnitTestsParallelizable` folder. +The primary home for new tests. Tests here run in parallel (`parallelizeAssembly: true`, `maxParallelThreads: 12`) +and **must not** touch any process-wide static state. -## ./UnitTestsParallelizable +### ./UnitTests.NonParallelizable -This folder contains the unit tests for Terminal.Gui that can be run in parallel. +Tests that either explicitly test process-wide static state, or must set process-wide statics, or otherwise +cannot be run concurrently with other tests. These tests run with `parallelizeAssembly: false`. -## ./IntegrationTests +### ./UnitTests.Legacy -This folder contains the integration tests for Terminal.Gui. +Tests that have not yet been ported to `UnitTestsParallelizable` or `UnitTests.NonParallelizable`. +These tests are candidates for rewrite (if the case is not covered elsewhere) or deletion (if already covered). +Do not add new tests here. -## ./StressTests +### ./IntegrationTests -This folder contains the stress tests for Terminal.Gui. +Integration tests for Terminal.Gui. -## ./PerformanceTests +### ./StressTests -This folder WILL contain the performance tests for Terminal.Gui. +Stress tests for Terminal.Gui. +--- + +## Static State in Terminal.Gui + +The following classes and properties use process-wide static state. Tests that read or write these **must not** +go in `UnitTestsParallelizable` — they belong in `UnitTests.NonParallelizable`. + +### `Application` (legacy static façade — `Terminal.Gui.App/Legacy/`) + +| Member | Notes | +|--------|-------| +| `Application.Instance` | Returns `ApplicationImpl.Instance` (singleton) | +| `Application.Init(driverName)` | Initializes the singleton; sets `Initialized`, `Driver`, `MainThreadId`, `SynchronizationContext` | +| `Application.Shutdown()` | Disposes the singleton; resets all static fields | +| `Application.Initialized` | Global bool; true between `Init` and `Shutdown` | +| `Application.MainThreadId` | Process-wide main thread ID set by `Init` | +| `Application.Driver` | The active `IDriver` singleton | +| `Application.DefaultKeyBindings` | Process-wide default key-binding dictionary (mutable `IDictionary`) | +| `Application.ForceDriver` | Persists across tests unless reset | +| `Application.Keyboard` | Delegates to `ApplicationImpl.Instance.Keyboard` | +| `Application.Navigation` | Delegates to `ApplicationImpl.Instance.Navigation` | +| `Application.Popovers` | Delegates to `ApplicationImpl.Instance.Popovers` | +| `Application.Screen` | Delegates to `ApplicationImpl.Instance.Screen` | +| `Application.ResetState()` | Resets all static backing fields to defaults | +| `SynchronizationContext.Current` | Set by `Application.Init`; process-wide | + +### `ApplicationImpl` (singleton — `Terminal.Gui.App/ApplicationImpl.cs`) + +| Member | Notes | +|--------|-------| +| `ApplicationImpl.Instance` | Process-wide singleton; set by `SetInstance()` | +| `ApplicationImpl.SetInstance(impl)` | Replaces the singleton (used in tests) | +| `ApplicationImpl.ResetModelUsageTracking()` | Resets the static "which model was used" flag | + +### `ConfigurationManager` (singleton — `Terminal.Gui.Configuration/`) + +| Member | Notes | +|--------|-------| +| `CM.IsEnabled` | Global flag; affects all code reading configuration | +| `CM.Disable(reset)` | Disables and optionally resets to hard-coded defaults | + +### `View.Diagnostics` (static field — `Terminal.Gui.ViewBase/View.cs`) + +| Member | Notes | +|--------|-------| +| `View.Diagnostics` | `ViewDiagnosticFlags`; process-wide debug flags | + +--- + +## Which Project Does My Test Belong In? + +| Test characteristic | Project | +|---------------------|---------| +| No static state; no `Application.Init`/`Shutdown`; no `ConfigurationManager` mutations | `UnitTestsParallelizable` | +| Calls `Application.Init`/`Shutdown` directly, or mutates `Application.DefaultKeyBindings`, `Application.ForceDriver`, or `ApplicationImpl.ResetModelUsageTracking()` | `UnitTests.NonParallelizable` | +| Uses `[AutoInitShutdown]` or `[SetupFakeApplication]` (fake driver, does not call real `Application.Init`) | Currently in `UnitTests.Legacy`; migrate to `UnitTestsParallelizable` or `UnitTests.NonParallelizable` after review | +| Not yet reviewed / ported | `UnitTests.Legacy` | + +--- See the [Testing wiki](https://github.com/gui-cs/Terminal.Gui/wiki/Testing) for details on how to add more tests. diff --git a/Tests/UnitTests/Application/ApplicationForceDriverTests.cs b/Tests/UnitTests.Legacy/Application/ApplicationForceDriverTests.cs similarity index 100% rename from Tests/UnitTests/Application/ApplicationForceDriverTests.cs rename to Tests/UnitTests.Legacy/Application/ApplicationForceDriverTests.cs diff --git a/Tests/UnitTests/Application/ApplicationPopoverTests.cs b/Tests/UnitTests.Legacy/Application/ApplicationPopoverTests.cs similarity index 100% rename from Tests/UnitTests/Application/ApplicationPopoverTests.cs rename to Tests/UnitTests.Legacy/Application/ApplicationPopoverTests.cs diff --git a/Tests/UnitTests/Application/ApplicationScreenTests.cs b/Tests/UnitTests.Legacy/Application/ApplicationScreenTests.cs similarity index 100% rename from Tests/UnitTests/Application/ApplicationScreenTests.cs rename to Tests/UnitTests.Legacy/Application/ApplicationScreenTests.cs diff --git a/Tests/UnitTests/Application/MainLoopTTests.cs b/Tests/UnitTests.Legacy/Application/MainLoopTTests.cs similarity index 100% rename from Tests/UnitTests/Application/MainLoopTTests.cs rename to Tests/UnitTests.Legacy/Application/MainLoopTTests.cs diff --git a/Tests/UnitTests/Application/Mouse/ApplicationMouseTests.cs b/Tests/UnitTests.Legacy/Application/Mouse/ApplicationMouseTests.cs similarity index 100% rename from Tests/UnitTests/Application/Mouse/ApplicationMouseTests.cs rename to Tests/UnitTests.Legacy/Application/Mouse/ApplicationMouseTests.cs diff --git a/Tests/UnitTests/Application/SynchronizatonContextTests.cs b/Tests/UnitTests.Legacy/Application/SynchronizatonContextTests.cs similarity index 100% rename from Tests/UnitTests/Application/SynchronizatonContextTests.cs rename to Tests/UnitTests.Legacy/Application/SynchronizatonContextTests.cs diff --git a/Tests/UnitTests/Application/TimedEventsTests.cs b/Tests/UnitTests.Legacy/Application/TimedEventsTests.cs similarity index 100% rename from Tests/UnitTests/Application/TimedEventsTests.cs rename to Tests/UnitTests.Legacy/Application/TimedEventsTests.cs diff --git a/Tests/UnitTests/AssemblyInfo.cs b/Tests/UnitTests.Legacy/AssemblyInfo.cs similarity index 100% rename from Tests/UnitTests/AssemblyInfo.cs rename to Tests/UnitTests.Legacy/AssemblyInfo.cs diff --git a/Tests/UnitTests/AutoInitShutdownAttribute.cs b/Tests/UnitTests.Legacy/AutoInitShutdownAttribute.cs similarity index 100% rename from Tests/UnitTests/AutoInitShutdownAttribute.cs rename to Tests/UnitTests.Legacy/AutoInitShutdownAttribute.cs diff --git a/Tests/UnitTests/Clipboard/ClipboardTests.cs b/Tests/UnitTests.Legacy/Clipboard/ClipboardTests.cs similarity index 100% rename from Tests/UnitTests/Clipboard/ClipboardTests.cs rename to Tests/UnitTests.Legacy/Clipboard/ClipboardTests.cs diff --git a/Tests/UnitTests/Configuration/AppScopeTests.cs b/Tests/UnitTests.Legacy/Configuration/AppScopeTests.cs similarity index 100% rename from Tests/UnitTests/Configuration/AppScopeTests.cs rename to Tests/UnitTests.Legacy/Configuration/AppScopeTests.cs diff --git a/Tests/UnitTests/Configuration/ConfigPropertyTests.cs b/Tests/UnitTests.Legacy/Configuration/ConfigPropertyTests.cs similarity index 100% rename from Tests/UnitTests/Configuration/ConfigPropertyTests.cs rename to Tests/UnitTests.Legacy/Configuration/ConfigPropertyTests.cs diff --git a/Tests/UnitTests/Configuration/ConfigurationMangerTests.cs b/Tests/UnitTests.Legacy/Configuration/ConfigurationMangerTests.cs similarity index 100% rename from Tests/UnitTests/Configuration/ConfigurationMangerTests.cs rename to Tests/UnitTests.Legacy/Configuration/ConfigurationMangerTests.cs diff --git a/Tests/UnitTests/Configuration/GlyphTests.cs b/Tests/UnitTests.Legacy/Configuration/GlyphTests.cs similarity index 100% rename from Tests/UnitTests/Configuration/GlyphTests.cs rename to Tests/UnitTests.Legacy/Configuration/GlyphTests.cs diff --git a/Tests/UnitTests/Configuration/KeyJsonConverterTests.cs b/Tests/UnitTests.Legacy/Configuration/KeyJsonConverterTests.cs similarity index 100% rename from Tests/UnitTests/Configuration/KeyJsonConverterTests.cs rename to Tests/UnitTests.Legacy/Configuration/KeyJsonConverterTests.cs diff --git a/Tests/UnitTests/Configuration/MemorySizeEstimator.cs b/Tests/UnitTests.Legacy/Configuration/MemorySizeEstimator.cs similarity index 100% rename from Tests/UnitTests/Configuration/MemorySizeEstimator.cs rename to Tests/UnitTests.Legacy/Configuration/MemorySizeEstimator.cs diff --git a/Tests/UnitTests/Configuration/SchemeManagerTests.cs b/Tests/UnitTests.Legacy/Configuration/SchemeManagerTests.cs similarity index 100% rename from Tests/UnitTests/Configuration/SchemeManagerTests.cs rename to Tests/UnitTests.Legacy/Configuration/SchemeManagerTests.cs diff --git a/Tests/UnitTests/Configuration/SettingsScopeTests.cs b/Tests/UnitTests.Legacy/Configuration/SettingsScopeTests.cs similarity index 100% rename from Tests/UnitTests/Configuration/SettingsScopeTests.cs rename to Tests/UnitTests.Legacy/Configuration/SettingsScopeTests.cs diff --git a/Tests/UnitTests/Configuration/SourcesManagerTests.cs b/Tests/UnitTests.Legacy/Configuration/SourcesManagerTests.cs similarity index 100% rename from Tests/UnitTests/Configuration/SourcesManagerTests.cs rename to Tests/UnitTests.Legacy/Configuration/SourcesManagerTests.cs diff --git a/Tests/UnitTests/Configuration/ThemeManagerTests.cs b/Tests/UnitTests.Legacy/Configuration/ThemeManagerTests.cs similarity index 100% rename from Tests/UnitTests/Configuration/ThemeManagerTests.cs rename to Tests/UnitTests.Legacy/Configuration/ThemeManagerTests.cs diff --git a/Tests/UnitTests/Configuration/ThemeScopeTests.cs b/Tests/UnitTests.Legacy/Configuration/ThemeScopeTests.cs similarity index 100% rename from Tests/UnitTests/Configuration/ThemeScopeTests.cs rename to Tests/UnitTests.Legacy/Configuration/ThemeScopeTests.cs diff --git a/Tests/UnitTests/Configuration/ThemeTests.cs b/Tests/UnitTests.Legacy/Configuration/ThemeTests.cs similarity index 100% rename from Tests/UnitTests/Configuration/ThemeTests.cs rename to Tests/UnitTests.Legacy/Configuration/ThemeTests.cs diff --git a/Tests/UnitTests/Dialogs/WizardTests.cs b/Tests/UnitTests.Legacy/Dialogs/WizardTests.cs similarity index 100% rename from Tests/UnitTests/Dialogs/WizardTests.cs rename to Tests/UnitTests.Legacy/Dialogs/WizardTests.cs diff --git a/Tests/UnitTests/DriverAssert.cs b/Tests/UnitTests.Legacy/DriverAssert.cs similarity index 100% rename from Tests/UnitTests/DriverAssert.cs rename to Tests/UnitTests.Legacy/DriverAssert.cs diff --git a/Tests/UnitTests/FakeDriver/FakeApplicationFactory.cs b/Tests/UnitTests.Legacy/FakeDriver/FakeApplicationFactory.cs similarity index 100% rename from Tests/UnitTests/FakeDriver/FakeApplicationFactory.cs rename to Tests/UnitTests.Legacy/FakeDriver/FakeApplicationFactory.cs diff --git a/Tests/UnitTests/FakeDriver/FakeApplicationLifecycle.cs b/Tests/UnitTests.Legacy/FakeDriver/FakeApplicationLifecycle.cs similarity index 100% rename from Tests/UnitTests/FakeDriver/FakeApplicationLifecycle.cs rename to Tests/UnitTests.Legacy/FakeDriver/FakeApplicationLifecycle.cs diff --git a/Tests/UnitTests/FileServices/FileDialogTests.cs b/Tests/UnitTests.Legacy/FileServices/FileDialogTests.cs similarity index 100% rename from Tests/UnitTests/FileServices/FileDialogTests.cs rename to Tests/UnitTests.Legacy/FileServices/FileDialogTests.cs diff --git a/Tests/UnitTests/FileServices/TreeViewFileSystemNavigationTests.cs b/Tests/UnitTests.Legacy/FileServices/TreeViewFileSystemNavigationTests.cs similarity index 100% rename from Tests/UnitTests/FileServices/TreeViewFileSystemNavigationTests.cs rename to Tests/UnitTests.Legacy/FileServices/TreeViewFileSystemNavigationTests.cs diff --git a/Tests/UnitTests/OutputAssert.cs b/Tests/UnitTests.Legacy/OutputAssert.cs similarity index 100% rename from Tests/UnitTests/OutputAssert.cs rename to Tests/UnitTests.Legacy/OutputAssert.cs diff --git a/Tests/UnitTests.Legacy/README.md b/Tests/UnitTests.Legacy/README.md new file mode 100644 index 0000000000..ad8be9df31 --- /dev/null +++ b/Tests/UnitTests.Legacy/README.md @@ -0,0 +1,13 @@ +# UnitTests.Legacy + +This project contains tests that have not yet been ported to `UnitTestsParallelizable` or `UnitTests.NonParallelizable`. + +**Do not add new tests here.** New tests should go in: +- [`../UnitTestsParallelizable`](../UnitTestsParallelizable/README.md) for tests with no static state dependency. +- [`../UnitTests.NonParallelizable`](../UnitTests.NonParallelizable/README.md) for tests that explicitly depend on process-wide static state. + +Each test class in this project is a candidate for one of: +1. **Rewrite** in the appropriate project if the case is not already covered. +2. **Deletion** if the case is already covered in `UnitTestsParallelizable`. + +See the [Testing wiki](https://github.com/gui-cs/Terminal.Gui/wiki/Testing) for details. diff --git a/Tests/UnitTests/SetupFakeApplicationAttribute.cs b/Tests/UnitTests.Legacy/SetupFakeApplicationAttribute.cs similarity index 100% rename from Tests/UnitTests/SetupFakeApplicationAttribute.cs rename to Tests/UnitTests.Legacy/SetupFakeApplicationAttribute.cs diff --git a/Tests/UnitTests/TestDriverBase.cs b/Tests/UnitTests.Legacy/TestDriverBase.cs similarity index 100% rename from Tests/UnitTests/TestDriverBase.cs rename to Tests/UnitTests.Legacy/TestDriverBase.cs diff --git a/Tests/UnitTests/TestLogging.cs b/Tests/UnitTests.Legacy/TestLogging.cs similarity index 100% rename from Tests/UnitTests/TestLogging.cs rename to Tests/UnitTests.Legacy/TestLogging.cs diff --git a/Tests/UnitTests/TestRespondersDisposedAttribute.cs b/Tests/UnitTests.Legacy/TestRespondersDisposedAttribute.cs similarity index 100% rename from Tests/UnitTests/TestRespondersDisposedAttribute.cs rename to Tests/UnitTests.Legacy/TestRespondersDisposedAttribute.cs diff --git a/Tests/UnitTests/TestsAllViews.cs b/Tests/UnitTests.Legacy/TestsAllViews.cs similarity index 100% rename from Tests/UnitTests/TestsAllViews.cs rename to Tests/UnitTests.Legacy/TestsAllViews.cs diff --git a/Tests/UnitTests/Text/AutocompleteTests.cs b/Tests/UnitTests.Legacy/Text/AutocompleteTests.cs similarity index 100% rename from Tests/UnitTests/Text/AutocompleteTests.cs rename to Tests/UnitTests.Legacy/Text/AutocompleteTests.cs diff --git a/Tests/UnitTests/Tracing/ThreadSafeTraceTests.cs b/Tests/UnitTests.Legacy/Tracing/ThreadSafeTraceTests.cs similarity index 100% rename from Tests/UnitTests/Tracing/ThreadSafeTraceTests.cs rename to Tests/UnitTests.Legacy/Tracing/ThreadSafeTraceTests.cs diff --git a/Tests/UnitTests/UICatalog/RunnerTests.cs b/Tests/UnitTests.Legacy/UICatalog/RunnerTests.cs similarity index 100% rename from Tests/UnitTests/UICatalog/RunnerTests.cs rename to Tests/UnitTests.Legacy/UICatalog/RunnerTests.cs diff --git a/Tests/UnitTests/UICatalog/ScenarioLogCaptureTests.cs b/Tests/UnitTests.Legacy/UICatalog/ScenarioLogCaptureTests.cs similarity index 100% rename from Tests/UnitTests/UICatalog/ScenarioLogCaptureTests.cs rename to Tests/UnitTests.Legacy/UICatalog/ScenarioLogCaptureTests.cs diff --git a/Tests/UnitTests/UICatalog/ScenarioTests.cs b/Tests/UnitTests.Legacy/UICatalog/ScenarioTests.cs similarity index 100% rename from Tests/UnitTests/UICatalog/ScenarioTests.cs rename to Tests/UnitTests.Legacy/UICatalog/ScenarioTests.cs diff --git a/Tests/UnitTests/UnitTests.csproj b/Tests/UnitTests.Legacy/UnitTests.Legacy.csproj similarity index 98% rename from Tests/UnitTests/UnitTests.csproj rename to Tests/UnitTests.Legacy/UnitTests.Legacy.csproj index 1771097314..98cce1be6b 100644 --- a/Tests/UnitTests/UnitTests.csproj +++ b/Tests/UnitTests.Legacy/UnitTests.Legacy.csproj @@ -9,6 +9,7 @@ 2.0 + UnitTests.Legacy Exe true true diff --git a/Tests/UnitTests/UnitTests.csproj.DotSettings b/Tests/UnitTests.Legacy/UnitTests.Legacy.csproj.DotSettings similarity index 100% rename from Tests/UnitTests/UnitTests.csproj.DotSettings rename to Tests/UnitTests.Legacy/UnitTests.Legacy.csproj.DotSettings diff --git a/Tests/UnitTests/UnitTests.sln b/Tests/UnitTests.Legacy/UnitTests.Legacy.sln similarity index 87% rename from Tests/UnitTests/UnitTests.sln rename to Tests/UnitTests.Legacy/UnitTests.Legacy.sln index 0d950924ca..b7af8b233c 100644 --- a/Tests/UnitTests/UnitTests.sln +++ b/Tests/UnitTests.Legacy/UnitTests.Legacy.sln @@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.5.002.0 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTests", "UnitTests.csproj", "{A29633F2-B26E-48B2-997A-1733286E3C13}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTests.Legacy", "UnitTests.Legacy.csproj", "{A29633F2-B26E-48B2-997A-1733286E3C13}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/Tests/UnitTests/View/Adornment/AdornmentTests.cs b/Tests/UnitTests.Legacy/View/Adornment/AdornmentTests.cs similarity index 100% rename from Tests/UnitTests/View/Adornment/AdornmentTests.cs rename to Tests/UnitTests.Legacy/View/Adornment/AdornmentTests.cs diff --git a/Tests/UnitTests/View/Adornment/BorderTests.cs b/Tests/UnitTests.Legacy/View/Adornment/BorderTests.cs similarity index 100% rename from Tests/UnitTests/View/Adornment/BorderTests.cs rename to Tests/UnitTests.Legacy/View/Adornment/BorderTests.cs diff --git a/Tests/UnitTests/View/Adornment/PaddingTests.cs b/Tests/UnitTests.Legacy/View/Adornment/PaddingTests.cs similarity index 100% rename from Tests/UnitTests/View/Adornment/PaddingTests.cs rename to Tests/UnitTests.Legacy/View/Adornment/PaddingTests.cs diff --git a/Tests/UnitTests/View/Adornment/ShadowStyleTests.cs b/Tests/UnitTests.Legacy/View/Adornment/ShadowStyleTests.cs similarity index 100% rename from Tests/UnitTests/View/Adornment/ShadowStyleTests.cs rename to Tests/UnitTests.Legacy/View/Adornment/ShadowStyleTests.cs diff --git a/Tests/UnitTests/View/ArrangementTests.cs b/Tests/UnitTests.Legacy/View/ArrangementTests.cs similarity index 100% rename from Tests/UnitTests/View/ArrangementTests.cs rename to Tests/UnitTests.Legacy/View/ArrangementTests.cs diff --git a/Tests/UnitTests/View/DiagnosticsTests.cs b/Tests/UnitTests.Legacy/View/DiagnosticsTests.cs similarity index 100% rename from Tests/UnitTests/View/DiagnosticsTests.cs rename to Tests/UnitTests.Legacy/View/DiagnosticsTests.cs diff --git a/Tests/UnitTests/View/Draw/ClipTests.cs b/Tests/UnitTests.Legacy/View/Draw/ClipTests.cs similarity index 100% rename from Tests/UnitTests/View/Draw/ClipTests.cs rename to Tests/UnitTests.Legacy/View/Draw/ClipTests.cs diff --git a/Tests/UnitTests/View/Draw/DrawEventTests.cs b/Tests/UnitTests.Legacy/View/Draw/DrawEventTests.cs similarity index 100% rename from Tests/UnitTests/View/Draw/DrawEventTests.cs rename to Tests/UnitTests.Legacy/View/Draw/DrawEventTests.cs diff --git a/Tests/UnitTests/View/Draw/DrawTests.cs b/Tests/UnitTests.Legacy/View/Draw/DrawTests.cs similarity index 100% rename from Tests/UnitTests/View/Draw/DrawTests.cs rename to Tests/UnitTests.Legacy/View/Draw/DrawTests.cs diff --git a/Tests/UnitTests/View/Draw/NeedsDrawTests.cs b/Tests/UnitTests.Legacy/View/Draw/NeedsDrawTests.cs similarity index 100% rename from Tests/UnitTests/View/Draw/NeedsDrawTests.cs rename to Tests/UnitTests.Legacy/View/Draw/NeedsDrawTests.cs diff --git a/Tests/UnitTests/View/Draw/TransparentTests.cs b/Tests/UnitTests.Legacy/View/Draw/TransparentTests.cs similarity index 100% rename from Tests/UnitTests/View/Draw/TransparentTests.cs rename to Tests/UnitTests.Legacy/View/Draw/TransparentTests.cs diff --git a/Tests/UnitTests/View/Layout/Dim.Tests.cs b/Tests/UnitTests.Legacy/View/Layout/Dim.Tests.cs similarity index 100% rename from Tests/UnitTests/View/Layout/Dim.Tests.cs rename to Tests/UnitTests.Legacy/View/Layout/Dim.Tests.cs diff --git a/Tests/UnitTests/View/Layout/Pos.Tests.cs b/Tests/UnitTests.Legacy/View/Layout/Pos.Tests.cs similarity index 100% rename from Tests/UnitTests/View/Layout/Pos.Tests.cs rename to Tests/UnitTests.Legacy/View/Layout/Pos.Tests.cs diff --git a/Tests/UnitTests/View/Layout/Pos.ViewTests.cs b/Tests/UnitTests.Legacy/View/Layout/Pos.ViewTests.cs similarity index 100% rename from Tests/UnitTests/View/Layout/Pos.ViewTests.cs rename to Tests/UnitTests.Legacy/View/Layout/Pos.ViewTests.cs diff --git a/Tests/UnitTests/View/Mouse/MouseTests.cs b/Tests/UnitTests.Legacy/View/Mouse/MouseTests.cs similarity index 100% rename from Tests/UnitTests/View/Mouse/MouseTests.cs rename to Tests/UnitTests.Legacy/View/Mouse/MouseTests.cs diff --git a/Tests/UnitTests/View/Navigation/EnabledTests.cs b/Tests/UnitTests.Legacy/View/Navigation/EnabledTests.cs similarity index 100% rename from Tests/UnitTests/View/Navigation/EnabledTests.cs rename to Tests/UnitTests.Legacy/View/Navigation/EnabledTests.cs diff --git a/Tests/UnitTests/View/SchemeTests.cs b/Tests/UnitTests.Legacy/View/SchemeTests.cs similarity index 100% rename from Tests/UnitTests/View/SchemeTests.cs rename to Tests/UnitTests.Legacy/View/SchemeTests.cs diff --git a/Tests/UnitTests/View/SubviewTests.cs b/Tests/UnitTests.Legacy/View/SubviewTests.cs similarity index 100% rename from Tests/UnitTests/View/SubviewTests.cs rename to Tests/UnitTests.Legacy/View/SubviewTests.cs diff --git a/Tests/UnitTests/View/TextTests.cs b/Tests/UnitTests.Legacy/View/TextTests.cs similarity index 100% rename from Tests/UnitTests/View/TextTests.cs rename to Tests/UnitTests.Legacy/View/TextTests.cs diff --git a/Tests/UnitTests/View/ViewTests.cs b/Tests/UnitTests.Legacy/View/ViewTests.cs similarity index 100% rename from Tests/UnitTests/View/ViewTests.cs rename to Tests/UnitTests.Legacy/View/ViewTests.cs diff --git a/Tests/UnitTests/Views/AppendAutocompleteTests.cs b/Tests/UnitTests.Legacy/Views/AppendAutocompleteTests.cs similarity index 100% rename from Tests/UnitTests/Views/AppendAutocompleteTests.cs rename to Tests/UnitTests.Legacy/Views/AppendAutocompleteTests.cs diff --git a/Tests/UnitTests/Views/ButtonTests.cs b/Tests/UnitTests.Legacy/Views/ButtonTests.cs similarity index 100% rename from Tests/UnitTests/Views/ButtonTests.cs rename to Tests/UnitTests.Legacy/Views/ButtonTests.cs diff --git a/Tests/UnitTests/Views/CheckBoxTests.cs b/Tests/UnitTests.Legacy/Views/CheckBoxTests.cs similarity index 100% rename from Tests/UnitTests/Views/CheckBoxTests.cs rename to Tests/UnitTests.Legacy/Views/CheckBoxTests.cs diff --git a/Tests/UnitTests/Views/ColorPickerTests.cs b/Tests/UnitTests.Legacy/Views/ColorPickerTests.cs similarity index 100% rename from Tests/UnitTests/Views/ColorPickerTests.cs rename to Tests/UnitTests.Legacy/Views/ColorPickerTests.cs diff --git a/Tests/UnitTests/Views/DatePickerTests.cs b/Tests/UnitTests.Legacy/Views/DatePickerTests.cs similarity index 100% rename from Tests/UnitTests/Views/DatePickerTests.cs rename to Tests/UnitTests.Legacy/Views/DatePickerTests.cs diff --git a/Tests/UnitTests/Views/DialogTests.cs b/Tests/UnitTests.Legacy/Views/DialogTests.cs similarity index 100% rename from Tests/UnitTests/Views/DialogTests.cs rename to Tests/UnitTests.Legacy/Views/DialogTests.cs diff --git a/Tests/UnitTests/Views/FrameViewTests.cs b/Tests/UnitTests.Legacy/Views/FrameViewTests.cs similarity index 100% rename from Tests/UnitTests/Views/FrameViewTests.cs rename to Tests/UnitTests.Legacy/Views/FrameViewTests.cs diff --git a/Tests/UnitTests/Views/GraphViewTests.cs b/Tests/UnitTests.Legacy/Views/GraphViewTests.cs similarity index 100% rename from Tests/UnitTests/Views/GraphViewTests.cs rename to Tests/UnitTests.Legacy/Views/GraphViewTests.cs diff --git a/Tests/UnitTests/Views/LabelTests.cs b/Tests/UnitTests.Legacy/Views/LabelTests.cs similarity index 100% rename from Tests/UnitTests/Views/LabelTests.cs rename to Tests/UnitTests.Legacy/Views/LabelTests.cs diff --git a/Tests/UnitTests/Views/MessageBoxTests.cs b/Tests/UnitTests.Legacy/Views/MessageBoxTests.cs similarity index 100% rename from Tests/UnitTests/Views/MessageBoxTests.cs rename to Tests/UnitTests.Legacy/Views/MessageBoxTests.cs diff --git a/Tests/UnitTests/Views/ProgressBarTests.cs b/Tests/UnitTests.Legacy/Views/ProgressBarTests.cs similarity index 100% rename from Tests/UnitTests/Views/ProgressBarTests.cs rename to Tests/UnitTests.Legacy/Views/ProgressBarTests.cs diff --git a/Tests/UnitTests/Views/ScrollBarTests.cs b/Tests/UnitTests.Legacy/Views/ScrollBarTests.cs similarity index 100% rename from Tests/UnitTests/Views/ScrollBarTests.cs rename to Tests/UnitTests.Legacy/Views/ScrollBarTests.cs diff --git a/Tests/UnitTests/Views/SpinnerViewTests.cs b/Tests/UnitTests.Legacy/Views/SpinnerViewTests.cs similarity index 100% rename from Tests/UnitTests/Views/SpinnerViewTests.cs rename to Tests/UnitTests.Legacy/Views/SpinnerViewTests.cs diff --git a/Tests/UnitTests/Views/StatusBarTests.cs b/Tests/UnitTests.Legacy/Views/StatusBarTests.cs similarity index 100% rename from Tests/UnitTests/Views/StatusBarTests.cs rename to Tests/UnitTests.Legacy/Views/StatusBarTests.cs diff --git a/Tests/UnitTests/Views/TabTests.cs b/Tests/UnitTests.Legacy/Views/TabTests.cs similarity index 100% rename from Tests/UnitTests/Views/TabTests.cs rename to Tests/UnitTests.Legacy/Views/TabTests.cs diff --git a/Tests/UnitTests/Views/TabViewTests.cs b/Tests/UnitTests.Legacy/Views/TabViewTests.cs similarity index 100% rename from Tests/UnitTests/Views/TabViewTests.cs rename to Tests/UnitTests.Legacy/Views/TabViewTests.cs diff --git a/Tests/UnitTests/Views/TableViewTests.cs b/Tests/UnitTests.Legacy/Views/TableViewTests.cs similarity index 100% rename from Tests/UnitTests/Views/TableViewTests.cs rename to Tests/UnitTests.Legacy/Views/TableViewTests.cs diff --git a/Tests/UnitTests/Views/TextFieldTests.cs b/Tests/UnitTests.Legacy/Views/TextFieldTests.cs similarity index 100% rename from Tests/UnitTests/Views/TextFieldTests.cs rename to Tests/UnitTests.Legacy/Views/TextFieldTests.cs diff --git a/Tests/UnitTests/Views/TextViewTests.History.cs b/Tests/UnitTests.Legacy/Views/TextViewTests.History.cs similarity index 100% rename from Tests/UnitTests/Views/TextViewTests.History.cs rename to Tests/UnitTests.Legacy/Views/TextViewTests.History.cs diff --git a/Tests/UnitTests/Views/TextViewTests.cs b/Tests/UnitTests.Legacy/Views/TextViewTests.cs similarity index 100% rename from Tests/UnitTests/Views/TextViewTests.cs rename to Tests/UnitTests.Legacy/Views/TextViewTests.cs diff --git a/Tests/UnitTests/Views/TreeTableSourceTests.cs b/Tests/UnitTests.Legacy/Views/TreeTableSourceTests.cs similarity index 100% rename from Tests/UnitTests/Views/TreeTableSourceTests.cs rename to Tests/UnitTests.Legacy/Views/TreeTableSourceTests.cs diff --git a/Tests/UnitTests/Views/TreeViewCollectionNavigatorMatcherTests.cs b/Tests/UnitTests.Legacy/Views/TreeViewCollectionNavigatorMatcherTests.cs similarity index 100% rename from Tests/UnitTests/Views/TreeViewCollectionNavigatorMatcherTests.cs rename to Tests/UnitTests.Legacy/Views/TreeViewCollectionNavigatorMatcherTests.cs diff --git a/Tests/UnitTests/Views/TreeViewTests.cs b/Tests/UnitTests.Legacy/Views/TreeViewTests.cs similarity index 100% rename from Tests/UnitTests/Views/TreeViewTests.cs rename to Tests/UnitTests.Legacy/Views/TreeViewTests.cs diff --git a/Tests/UnitTests/Views/ViewDisposalTest.cs b/Tests/UnitTests.Legacy/Views/ViewDisposalTest.cs similarity index 100% rename from Tests/UnitTests/Views/ViewDisposalTest.cs rename to Tests/UnitTests.Legacy/Views/ViewDisposalTest.cs diff --git a/Tests/UnitTests/Views/WindowTests.cs b/Tests/UnitTests.Legacy/Views/WindowTests.cs similarity index 100% rename from Tests/UnitTests/Views/WindowTests.cs rename to Tests/UnitTests.Legacy/Views/WindowTests.cs diff --git a/Tests/UnitTests/runsettings.coverage.xml b/Tests/UnitTests.Legacy/runsettings.coverage.xml similarity index 100% rename from Tests/UnitTests/runsettings.coverage.xml rename to Tests/UnitTests.Legacy/runsettings.coverage.xml diff --git a/Tests/UnitTests/runsettings.xml b/Tests/UnitTests.Legacy/runsettings.xml similarity index 100% rename from Tests/UnitTests/runsettings.xml rename to Tests/UnitTests.Legacy/runsettings.xml diff --git a/Tests/UnitTests/xunit.runner.json b/Tests/UnitTests.Legacy/xunit.runner.json similarity index 100% rename from Tests/UnitTests/xunit.runner.json rename to Tests/UnitTests.Legacy/xunit.runner.json diff --git a/Tests/UnitTests/Application/ApplicationModelFencingTests.cs b/Tests/UnitTests.NonParallelizable/Application/ApplicationModelFencingTests.cs similarity index 99% rename from Tests/UnitTests/Application/ApplicationModelFencingTests.cs rename to Tests/UnitTests.NonParallelizable/Application/ApplicationModelFencingTests.cs index eaaf6d3728..a0b6cb1a9f 100644 --- a/Tests/UnitTests/Application/ApplicationModelFencingTests.cs +++ b/Tests/UnitTests.NonParallelizable/Application/ApplicationModelFencingTests.cs @@ -1,4 +1,4 @@ -namespace UnitTests.ApplicationTests; +namespace UnitTests.NonParallelizable.ApplicationTests; /// /// Tests to ensure that mixing legacy static Application and modern instance-based models diff --git a/Tests/UnitTests/Application/Keyboard/ApplicationKeyboardThreadSafetyTests.cs b/Tests/UnitTests.NonParallelizable/Application/Keyboard/ApplicationKeyboardThreadSafetyTests.cs similarity index 99% rename from Tests/UnitTests/Application/Keyboard/ApplicationKeyboardThreadSafetyTests.cs rename to Tests/UnitTests.NonParallelizable/Application/Keyboard/ApplicationKeyboardThreadSafetyTests.cs index c03ebae47a..7fa69249fe 100644 --- a/Tests/UnitTests/Application/Keyboard/ApplicationKeyboardThreadSafetyTests.cs +++ b/Tests/UnitTests.NonParallelizable/Application/Keyboard/ApplicationKeyboardThreadSafetyTests.cs @@ -1,6 +1,6 @@ // ReSharper disable AccessToDisposedClosure -namespace UnitTests.ApplicationTests.Keyboard; +namespace UnitTests.NonParallelizable.ApplicationTests.Keyboard; /// /// Tests to verify that ApplicationKeyboard is thread-safe for concurrent access scenarios. diff --git a/Tests/UnitTests/Application/Keyboard/KeyboardSetterTests.cs b/Tests/UnitTests.NonParallelizable/Application/Keyboard/KeyboardSetterTests.cs similarity index 98% rename from Tests/UnitTests/Application/Keyboard/KeyboardSetterTests.cs rename to Tests/UnitTests.NonParallelizable/Application/Keyboard/KeyboardSetterTests.cs index 6388369021..ca3f4fa1d7 100644 --- a/Tests/UnitTests/Application/Keyboard/KeyboardSetterTests.cs +++ b/Tests/UnitTests.NonParallelizable/Application/Keyboard/KeyboardSetterTests.cs @@ -1,7 +1,7 @@ // Tests that mutate Application.DefaultKeyBindings (static state). // These MUST NOT be in UnitTestsParallelizable. -namespace UnitTests.ApplicationTests.Keyboard; +namespace UnitTests.NonParallelizable.ApplicationTests.Keyboard; public class KeyboardSetterTests { diff --git a/Tests/UnitTests.NonParallelizable/AssemblyInfo.cs b/Tests/UnitTests.NonParallelizable/AssemblyInfo.cs new file mode 100644 index 0000000000..e6cc8f6e5c --- /dev/null +++ b/Tests/UnitTests.NonParallelizable/AssemblyInfo.cs @@ -0,0 +1,15 @@ +global using Attribute = Terminal.Gui.Drawing.Attribute; +global using Color = Terminal.Gui.Drawing.Color; +global using CM = Terminal.Gui.Configuration.ConfigurationManager; +global using Terminal.Gui.App; +global using Terminal.Gui.Time; +global using Terminal.Gui.Testing; +global using Terminal.Gui.Drivers; +global using Terminal.Gui.Input; +global using Terminal.Gui.Configuration; +global using Terminal.Gui.ViewBase; +global using Terminal.Gui.Views; +global using Terminal.Gui.Drawing; +global using Terminal.Gui.Text; +global using Terminal.Gui.Resources; +global using Terminal.Gui.FileServices; diff --git a/Tests/UnitTests.NonParallelizable/README.md b/Tests/UnitTests.NonParallelizable/README.md new file mode 100644 index 0000000000..034e109360 --- /dev/null +++ b/Tests/UnitTests.NonParallelizable/README.md @@ -0,0 +1,24 @@ +# UnitTests.NonParallelizable + +This project contains tests that must not run concurrently with other tests because they read or write +process-wide static state. + +## When to add tests here + +Add a test here if it does **any** of the following: + +- Calls `Application.Init()` or `Application.Shutdown()` directly (not through `SetupFakeApplication`). +- Mutates `Application.DefaultKeyBindings` (a process-wide static dictionary). +- Calls `ApplicationImpl.ResetModelUsageTracking()`. +- Calls `Application.Create()` and tests the static-vs-instance model fencing. +- Sets `SynchronizationContext.Current` or depends on it being in a particular state. +- Otherwise cannot be run concurrently with other tests due to shared mutable static state. + +## What does NOT belong here + +- Tests that use `[SetupFakeApplication]` or `ApplicationImpl.SetInstance()` — those use a fake driver + instance and do not touch global static state in a way that prevents parallelism. They may belong in + `UnitTestsParallelizable` after review. +- New feature tests — those belong in `UnitTestsParallelizable`. + +See the [Testing wiki](https://github.com/gui-cs/Terminal.Gui/wiki/Testing) for details. diff --git a/Tests/UnitTests.NonParallelizable/UnitTests.NonParallelizable.csproj b/Tests/UnitTests.NonParallelizable/UnitTests.NonParallelizable.csproj new file mode 100644 index 0000000000..5deff5e754 --- /dev/null +++ b/Tests/UnitTests.NonParallelizable/UnitTests.NonParallelizable.csproj @@ -0,0 +1,61 @@ + + + + + + 2.0 + 2.0 + 2.0 + 2.0 + + + UnitTests.NonParallelizable + Exe + true + true + false + + true + true + portable + $(DefineConstants);JETBRAINS_ANNOTATIONS;CONTRACTS_FULL + enable + true + $(NoWarn);AD0001 + true + + + true + $(DefineConstants);DEBUG_IDISPOSABLE + + + true + + + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + PreserveNewest + + + + + + + + diff --git a/Tests/UnitTests.NonParallelizable/xunit.runner.json b/Tests/UnitTests.NonParallelizable/xunit.runner.json new file mode 100644 index 0000000000..d47a70ea08 --- /dev/null +++ b/Tests/UnitTests.NonParallelizable/xunit.runner.json @@ -0,0 +1,6 @@ +{ + "$schema": "https://xunit.net/schema/current/xunit.runner.schema.json", + "parallelizeTestCollections": false, + "parallelizeAssembly": false, + "stopOnFail": false +} diff --git a/Tests/UnitTests/README.md b/Tests/UnitTests/README.md deleted file mode 100644 index db8d0451c6..0000000000 --- a/Tests/UnitTests/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# Automated Unit Tests (non-Parallelizable) - -**IMPORTANT:** New tests belong in [UnitTests.Parallelizable](../UnitTestsParallelizable/README.md). Please use the [UnitTests.Parallelizable](../UnitTestsParallelizable/README.md) project for all new tests. - -See the [Testing wiki](https://github.com/gui-cs/Terminal.Gui/wiki/Testing) for details on how to add more tests. diff --git a/Tests/UnitTestsParallelizable/UnitTests.Parallelizable.csproj b/Tests/UnitTestsParallelizable/UnitTests.Parallelizable.csproj index 37ac79b9c8..f590d74bd6 100644 --- a/Tests/UnitTestsParallelizable/UnitTests.Parallelizable.csproj +++ b/Tests/UnitTestsParallelizable/UnitTests.Parallelizable.csproj @@ -34,7 +34,7 @@ - + @@ -57,7 +57,7 @@ - + From b940474509ac3d64ce930eb7750f03bab4bc5640 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 22 Mar 2026 14:23:30 +0000 Subject: [PATCH 03/26] Fix IntegrationTests.csproj: update project reference from UnitTests to UnitTests.Legacy Co-authored-by: tig <585482+tig@users.noreply.github.com> Agent-Logs-Url: https://github.com/gui-cs/Terminal.Gui/sessions/afc0cfa3-f67a-4db4-8d95-0ca2c16b0d11 --- .github/workflows/README.md | 8 +++++--- Tests/IntegrationTests/IntegrationTests.csproj | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/.github/workflows/README.md b/.github/workflows/README.md index 0fe1570677..86483386e5 100644 --- a/.github/workflows/README.md +++ b/.github/workflows/README.md @@ -29,8 +29,9 @@ The repository uses multiple GitHub Actions workflows. What runs and when: 1. Each OS checks out code, restores, and builds locally 2. **Performance optimizations**: - Disables Windows Defender on Windows runners (significant speedup) -3. Runs two test jobs: - - **Non-parallel UnitTests**: `Tests/UnitTests` with diagnostic output +3. Runs three test jobs: + - **Non-parallel UnitTests.Legacy**: `Tests/UnitTests.Legacy` with diagnostic output + - **Non-parallel UnitTests.NonParallelizable**: `Tests/UnitTests.NonParallelizable` with diagnostic output - **Parallel UnitTestsParallelizable**: `Tests/UnitTestsParallelizable` with diagnostic output 4. Uploads test logs and diagnostic data from all runners @@ -87,7 +88,8 @@ The repository uses multiple GitHub Actions workflows. What runs and when: # Full CI sequence: dotnet restore dotnet build --configuration Debug --no-restore -dotnet test --project Tests/UnitTests --no-build --verbosity normal +dotnet test --project Tests/UnitTests.Legacy --no-build --verbosity normal +dotnet test --project Tests/UnitTests.NonParallelizable --no-build --verbosity normal dotnet test --project Tests/UnitTestsParallelizable --no-build --verbosity normal dotnet build --configuration Release --no-restore ``` diff --git a/Tests/IntegrationTests/IntegrationTests.csproj b/Tests/IntegrationTests/IntegrationTests.csproj index 8b1545686a..1faeffd3ec 100644 --- a/Tests/IntegrationTests/IntegrationTests.csproj +++ b/Tests/IntegrationTests/IntegrationTests.csproj @@ -34,7 +34,7 @@ - + From b6d58d61746de9e1d6de48c36dc058dd67a0fbef Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 22 Mar 2026 17:21:14 +0000 Subject: [PATCH 04/26] Step 4 iteration 1: delete 37 Legacy test files already covered in UnitTestsParallelizable Co-authored-by: tig <585482+tig@users.noreply.github.com> Agent-Logs-Url: https://github.com/gui-cs/Terminal.Gui/sessions/f62dad05-cd4b-4fd9-8b7e-9b1d88aeaaa6 --- .../Configuration/KeyJsonConverterTests.cs | 58 - .../Configuration/MemorySizeEstimator.cs | 253 -- .../Configuration/SourcesManagerTests.cs | 75 - .../Configuration/ThemeManagerTests.cs | 287 -- .../Text/AutocompleteTests.cs | 283 -- .../Tracing/ThreadSafeTraceTests.cs | 354 -- .../View/Adornment/AdornmentTests.cs | 74 - .../View/Adornment/BorderTests.cs | 955 ----- .../View/Adornment/PaddingTests.cs | 39 - .../View/Adornment/ShadowStyleTests.cs | 127 - .../UnitTests.Legacy/View/ArrangementTests.cs | 215 - .../UnitTests.Legacy/View/DiagnosticsTests.cs | 28 - Tests/UnitTests.Legacy/View/Draw/ClipTests.cs | 313 -- .../View/Draw/DrawEventTests.cs | 30 - Tests/UnitTests.Legacy/View/Draw/DrawTests.cs | 953 ----- .../View/Draw/NeedsDrawTests.cs | 68 - .../View/Draw/TransparentTests.cs | 107 - .../UnitTests.Legacy/View/Layout/Dim.Tests.cs | 223 -- .../UnitTests.Legacy/View/Layout/Pos.Tests.cs | 250 -- .../View/Layout/Pos.ViewTests.cs | 80 - .../UnitTests.Legacy/View/Mouse/MouseTests.cs | 629 --- .../View/Navigation/EnabledTests.cs | 75 - Tests/UnitTests.Legacy/View/SchemeTests.cs | 22 - Tests/UnitTests.Legacy/View/SubviewTests.cs | 105 - Tests/UnitTests.Legacy/View/TextTests.cs | 1142 ------ Tests/UnitTests.Legacy/View/ViewTests.cs | 526 --- Tests/UnitTests.Legacy/Views/ButtonTests.cs | 207 - Tests/UnitTests.Legacy/Views/CheckBoxTests.cs | 316 -- .../Views/ColorPickerTests.cs | 9 - .../UnitTests.Legacy/Views/DatePickerTests.cs | 67 - Tests/UnitTests.Legacy/Views/DialogTests.cs | 115 - Tests/UnitTests.Legacy/Views/LabelTests.cs | 1178 ------ .../UnitTests.Legacy/Views/MessageBoxTests.cs | 91 - .../UnitTests.Legacy/Views/ScrollBarTests.cs | 627 --- .../UnitTests.Legacy/Views/TextFieldTests.cs | 1712 -------- Tests/UnitTests.Legacy/Views/TextViewTests.cs | 3482 ----------------- Tests/UnitTests.Legacy/Views/TreeViewTests.cs | 936 ----- 37 files changed, 16011 deletions(-) delete mode 100644 Tests/UnitTests.Legacy/Configuration/KeyJsonConverterTests.cs delete mode 100644 Tests/UnitTests.Legacy/Configuration/MemorySizeEstimator.cs delete mode 100644 Tests/UnitTests.Legacy/Configuration/SourcesManagerTests.cs delete mode 100644 Tests/UnitTests.Legacy/Configuration/ThemeManagerTests.cs delete mode 100644 Tests/UnitTests.Legacy/Text/AutocompleteTests.cs delete mode 100644 Tests/UnitTests.Legacy/Tracing/ThreadSafeTraceTests.cs delete mode 100644 Tests/UnitTests.Legacy/View/Adornment/AdornmentTests.cs delete mode 100644 Tests/UnitTests.Legacy/View/Adornment/BorderTests.cs delete mode 100644 Tests/UnitTests.Legacy/View/Adornment/PaddingTests.cs delete mode 100644 Tests/UnitTests.Legacy/View/Adornment/ShadowStyleTests.cs delete mode 100644 Tests/UnitTests.Legacy/View/ArrangementTests.cs delete mode 100644 Tests/UnitTests.Legacy/View/DiagnosticsTests.cs delete mode 100644 Tests/UnitTests.Legacy/View/Draw/ClipTests.cs delete mode 100644 Tests/UnitTests.Legacy/View/Draw/DrawEventTests.cs delete mode 100644 Tests/UnitTests.Legacy/View/Draw/DrawTests.cs delete mode 100644 Tests/UnitTests.Legacy/View/Draw/NeedsDrawTests.cs delete mode 100644 Tests/UnitTests.Legacy/View/Draw/TransparentTests.cs delete mode 100644 Tests/UnitTests.Legacy/View/Layout/Dim.Tests.cs delete mode 100644 Tests/UnitTests.Legacy/View/Layout/Pos.Tests.cs delete mode 100644 Tests/UnitTests.Legacy/View/Layout/Pos.ViewTests.cs delete mode 100644 Tests/UnitTests.Legacy/View/Mouse/MouseTests.cs delete mode 100644 Tests/UnitTests.Legacy/View/Navigation/EnabledTests.cs delete mode 100644 Tests/UnitTests.Legacy/View/SchemeTests.cs delete mode 100644 Tests/UnitTests.Legacy/View/SubviewTests.cs delete mode 100644 Tests/UnitTests.Legacy/View/TextTests.cs delete mode 100644 Tests/UnitTests.Legacy/View/ViewTests.cs delete mode 100644 Tests/UnitTests.Legacy/Views/ButtonTests.cs delete mode 100644 Tests/UnitTests.Legacy/Views/CheckBoxTests.cs delete mode 100644 Tests/UnitTests.Legacy/Views/ColorPickerTests.cs delete mode 100644 Tests/UnitTests.Legacy/Views/DatePickerTests.cs delete mode 100644 Tests/UnitTests.Legacy/Views/DialogTests.cs delete mode 100644 Tests/UnitTests.Legacy/Views/LabelTests.cs delete mode 100644 Tests/UnitTests.Legacy/Views/MessageBoxTests.cs delete mode 100644 Tests/UnitTests.Legacy/Views/ScrollBarTests.cs delete mode 100644 Tests/UnitTests.Legacy/Views/TextFieldTests.cs delete mode 100644 Tests/UnitTests.Legacy/Views/TextViewTests.cs delete mode 100644 Tests/UnitTests.Legacy/Views/TreeViewTests.cs diff --git a/Tests/UnitTests.Legacy/Configuration/KeyJsonConverterTests.cs b/Tests/UnitTests.Legacy/Configuration/KeyJsonConverterTests.cs deleted file mode 100644 index 8f3e6f973a..0000000000 --- a/Tests/UnitTests.Legacy/Configuration/KeyJsonConverterTests.cs +++ /dev/null @@ -1,58 +0,0 @@ -using System.Text; -using System.Text.Encodings.Web; -using System.Text.Json; -using System.Text.Unicode; - -namespace UnitTests.ConfigurationTests; - -public class KeyJsonConverterTests -{ - - [Fact] - public void Separator_Property_Set_Changes_Serialization_Format () - { - Rune savedSeparator = Key.Separator; - - // Act - // NOTE: This means this test can't be parallelized - Key.Separator = (Rune)'*'; - string json = JsonSerializer.Serialize (Key.Separator, ConfigurationManager.SerializerContext.Options); - - // Assert - Assert.Equal ("\"*\"", json); - Key.Separator = savedSeparator; - } - - [Theory] - [InlineData ('A', '+', "\"Ctrl+Alt+A\"")] - [InlineData ('A', '-', "\"Ctrl+Alt+A\"")] - [InlineData ('A', '*', "\"Ctrl+Alt+A\"")] - [InlineData ('A', '@', "\"Ctrl+Alt+A\"")] - [InlineData ('A', '+', "\"Ctrl@Alt@A\"")] - [InlineData ('A', '-', "\"Ctrl@Alt@A\"")] - [InlineData ('A', '*', "\"Ctrl@Alt@A\"")] - [InlineData ('A', '@', "\"Ctrl@Alt@A\"")] - [InlineData ('+', '+', "\"Ctrl+Alt++\"")] - [InlineData ('+', '-', "\"Ctrl+Alt++\"")] - [InlineData ('+', '*', "\"Ctrl+Alt++\"")] - [InlineData ('+', '@', "\"Ctrl+Alt++\"")] - [InlineData ('+', '+', "\"Ctrl@Alt@+\"")] - [InlineData ('+', '-', "\"Ctrl@Alt@+\"")] - [InlineData ('+', '*', "\"Ctrl@Alt@+\"")] - [InlineData ('+', '@', "\"Ctrl@Alt@+\"")] - public void Separator_Property_Set_Deserialization_Works_With_Any (char keyChar, char separator, string json) - { - Rune savedSeparator = Key.Separator; - - // Act - // NOTE: This means this test can't be parallelized - Key.Separator = (Rune)separator; - - Key deserializedKey = JsonSerializer.Deserialize (json, ConfigurationManager.SerializerContext.Options); - - Key expectedKey = new Key ((KeyCode)keyChar).WithCtrl.WithAlt; - // Assert - Assert.Equal (expectedKey, deserializedKey); - Key.Separator = savedSeparator; - } -} \ No newline at end of file diff --git a/Tests/UnitTests.Legacy/Configuration/MemorySizeEstimator.cs b/Tests/UnitTests.Legacy/Configuration/MemorySizeEstimator.cs deleted file mode 100644 index 7562650d2b..0000000000 --- a/Tests/UnitTests.Legacy/Configuration/MemorySizeEstimator.cs +++ /dev/null @@ -1,253 +0,0 @@ -#nullable enable - -namespace UnitTests.ConfigurationTests; - -using System; -using System.Collections; -using System.Collections.Concurrent; -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using System.Text; - -public static class MemorySizeEstimator -{ - public static long EstimateSize (T? source) - { - if (source is null) - { - return 0; - } - - ConcurrentDictionary visited = new (ReferenceEqualityComparer.Instance); - return EstimateSizeInternal (source, visited); - } - - private const int POINTER_SIZE = 8; // 64-bit system - private const int OBJECT_HEADER_SIZE = 16; // 2 pointers for GC - - private static long EstimateSizeInternal (object? source, ConcurrentDictionary visited) - { - if (source is null) - { - return 0; - } - - // Handle already visited objects to avoid circular references - if (visited.TryGetValue (source, out long existingSize)) - { - // // Log revisited object (enable for debugging) - // Console.WriteLine($"Revisited {source.GetType().FullName}: {existingSize} bytes"); - return existingSize; - } - - Type type = source.GetType (); - long size = 0; - - // Handle simple types - if (IsSimpleType (type)) - { - size = EstimateSimpleTypeSize (source, type); - visited.TryAdd (source, size); - // // Log simple type (enable for debugging) - // Console.WriteLine($"{type.FullName}: {size} bytes"); - return size; - } - - // Handle arrays - if (type.IsArray) - { - size = EstimateArraySize (source, visited); - } - // Handle dictionaries - else if (source is IDictionary) - { - size = EstimateDictionarySize (source, visited); - } - // Handle collections - else if (typeof (ICollection).IsAssignableFrom (type)) - { - size = EstimateCollectionSize (source, visited); - } - // Handle structs and classes - else - { - size = EstimateObjectSize (source, type, visited); - } - - visited.TryAdd (source, size); - // // Log object size (enable for debugging) - // if (size == 0) - // { - // Console.WriteLine($"Zero size for {type.FullName}"); - // } - // else - // { - // Console.WriteLine($"{type.FullName}: {size} bytes"); - // } - - return size; - } - - private static bool IsSimpleType (Type type) - { - if (type.IsPrimitive - || type.IsEnum - || type == typeof (decimal) - || type == typeof (DateTime) - || type == typeof (DateTimeOffset) - || type == typeof (TimeSpan) - || type == typeof (Guid) - || type == typeof (Rune) - || type == typeof (string)) - { - return true; - } - - // Treat structs with no writable public properties as simple types - if (type.IsValueType) - { - PropertyInfo [] writableProperties = type.GetProperties (BindingFlags.Instance | BindingFlags.Public) - .Where (p => p is { CanRead: true, CanWrite: true } && p.GetIndexParameters ().Length == 0) - .ToArray (); - return writableProperties.Length == 0; - } - - // Treat Property翰Info as simple (metadata, not cloned) - if (typeof (PropertyInfo).IsAssignableFrom (type)) - { - return true; - } - - return false; - } - - private static long EstimateSimpleTypeSize (object source, Type type) - { - if (type == typeof (string)) - { - string str = (string)source; - // Header + length (4) + char array ref + chars (2 bytes each) - return OBJECT_HEADER_SIZE + 4 + POINTER_SIZE + (str.Length * 2); - } - - try - { - return Marshal.SizeOf (type); - } - catch (ArgumentException) - { - // Fallback for enums or other simple types - return 4; // Conservative estimate - } - } - - private static long EstimateArraySize (object source, ConcurrentDictionary visited) - { - Array array = (Array)source; - long size = OBJECT_HEADER_SIZE + 4 + POINTER_SIZE; // Header + length + padding - - foreach (object? element in array) - { - size += EstimateSizeInternal (element, visited); - } - - return size; - } - - private static long EstimateDictionarySize (object source, ConcurrentDictionary visited) - { - IDictionary dict = (IDictionary)source; - long size = OBJECT_HEADER_SIZE + (POINTER_SIZE * 5); // Header + buckets, entries, comparer, fields - size += dict.Count * 4; // Bucket array (~4 bytes per entry) - size += dict.Count * (4 + 4 + POINTER_SIZE * 2); // Entry array: hashcode, next, key, value - - foreach (object? key in dict.Keys) - { - size += EstimateSizeInternal (key, visited); - size += EstimateSizeInternal (dict [key], visited); - } - - return size; - } - - private static long EstimateCollectionSize (object source, ConcurrentDictionary visited) - { - Type type = source.GetType (); - long size = OBJECT_HEADER_SIZE + (POINTER_SIZE * 3); // Header + internal array + fields - - if (type.IsGenericType && type.GetGenericTypeDefinition () == typeof (Dictionary<,>)) - { - return EstimateDictionarySize (source, visited); - } - - if (source is IEnumerable enumerable) - { - foreach (object? item in enumerable) - { - size += EstimateSizeInternal (item, visited); - } - } - - return size; - } - - private static long EstimateObjectSize (object source, Type type, ConcurrentDictionary visited) - { - long size = OBJECT_HEADER_SIZE; - - // Size public writable properties - foreach (PropertyInfo prop in type.GetProperties (BindingFlags.Instance | BindingFlags.Public) - .Where (p => p is { CanRead: true, CanWrite: true } && p.GetIndexParameters ().Length == 0)) - { - try - { - object? value = prop.GetValue (source); - size += EstimateSizeInternal (value, visited); - } - catch (Exception) - { - // // Log exception (enable for debugging) - // Console.WriteLine($"Error processing property {prop.Name} of {type.FullName}: {ex.Message}"); - // Continue to avoid crashing - } - } - - // For structs, also size fields (to handle generic structs) - if (type.IsValueType) - { - FieldInfo [] fields = type.GetFields (BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); - foreach (FieldInfo field in fields) - { - try - { - object? fieldValue = field.GetValue (source); - size += EstimateSizeInternal (fieldValue, visited); - } - catch (Exception) - { - // // Log exception (enable for debugging) - // Console.WriteLine($"Error processing field {field.Name} of {type.FullName}: {ex.Message}"); - // Continue to avoid crashing - } - } - } - - return size; - } - - private sealed class ReferenceEqualityComparer : IEqualityComparer - { - public static ReferenceEqualityComparer Instance { get; } = new (); - - public new bool Equals (object? x, object? y) - { - return ReferenceEquals (x, y); - } - - public int GetHashCode (object obj) - { - return RuntimeHelpers.GetHashCode (obj); - } - } -} \ No newline at end of file diff --git a/Tests/UnitTests.Legacy/Configuration/SourcesManagerTests.cs b/Tests/UnitTests.Legacy/Configuration/SourcesManagerTests.cs deleted file mode 100644 index 8ff31f0050..0000000000 --- a/Tests/UnitTests.Legacy/Configuration/SourcesManagerTests.cs +++ /dev/null @@ -1,75 +0,0 @@ -using System.Reflection; -using System.Text.Json; - -namespace UnitTests.ConfigurationTests; - -public class SourcesManagerTests -{ - [Fact] - public void Sources_StaysConsistentWhenUpdateFails () - { - // Arrange - var sourcesManager = new SourcesManager (); - var settingsScope = new SettingsScope (); - - // Add one successful source - var validSource = "valid.json"; - var validLocation = ConfigLocations.Runtime; - sourcesManager.Load (settingsScope, """{"Driver.Force16Colors": true}""", validSource, validLocation); - - try - { - // Configure to throw on errors - ConfigurationManager.ThrowOnJsonErrors = true; - - // Act & Assert - attempt to update with invalid JSON - var invalidSource = "invalid.json"; - var invalidLocation = ConfigLocations.AppCurrent; - var invalidJson = "{ invalid json }"; - - Assert.Throws ( - () => - sourcesManager.Load (settingsScope, invalidJson, invalidSource, invalidLocation)); - - // The valid source should still be there - Assert.Single (sourcesManager.Sources); - Assert.Equal (validSource, sourcesManager.Sources [validLocation]); - - // The invalid source should not have been added - Assert.DoesNotContain (invalidLocation, sourcesManager.Sources.Keys); - } - finally - { - // Reset for other tests - ConfigurationManager.ThrowOnJsonErrors = false; - } - } - - - // NOTE: This test causes the static CM._jsonErrors to be modified; can't use in a parallel test - [Fact] - public void Load_WithInvalidJson_AddsJsonError () - { - // Arrange - var sourcesManager = new SourcesManager (); - - var settingsScope = new SettingsScope (); - var invalidJson = "{ invalid json }"; - var stream = new MemoryStream (); - var writer = new StreamWriter (stream); - writer.Write (invalidJson); - writer.Flush (); - stream.Position = 0; - - var source = "Load_WithInvalidJson_AddsJsonError"; - var location = ConfigLocations.AppCurrent; - - // Act - bool result = sourcesManager.Load (settingsScope, stream, source, location); - - // Assert - Assert.False (result); - - // Assuming AddJsonError logs errors, verify the error was logged (mock or inspect logs if possible). - } -} diff --git a/Tests/UnitTests.Legacy/Configuration/ThemeManagerTests.cs b/Tests/UnitTests.Legacy/Configuration/ThemeManagerTests.cs deleted file mode 100644 index 54f8999eff..0000000000 --- a/Tests/UnitTests.Legacy/Configuration/ThemeManagerTests.cs +++ /dev/null @@ -1,287 +0,0 @@ -#nullable enable -using System.Collections.Concurrent; -using static Terminal.Gui.Configuration.ConfigurationManager; - -namespace UnitTests.ConfigurationTests; - -public class ThemeManagerTests (ITestOutputHelper output) -{ - [Fact] - public void ResetToCurrentValues_Adds_Default_Theme () - { - try - { - Enable (ConfigLocations.HardCoded); - Assert.NotEmpty (ThemeManager.Themes!); - - ThemeManager.UpdateToCurrentValues (); - - Assert.NotEmpty (ThemeManager.Themes!); - - // Default theme exists - Assert.NotNull (ThemeManager.Themes? [ThemeManager.DEFAULT_THEME_NAME]); - } - finally - { - Disable (resetToHardCodedDefaults: true); - } - } - - // ResetToCurrentValues - - // OnThemeChanged - - #region Tests Settings["Theme"] and ThemeManager.Theme - - [Fact] - public void Theme_Settings_Theme_Equals_ThemeManager_Theme () - { - Assert.False (IsEnabled); - - Assert.Equal (Settings! ["Theme"].PropertyValue, ThemeManager.Theme); - Assert.Equal (ThemeManager.DEFAULT_THEME_NAME, ThemeManager.Theme); - } - - [Fact] - public void Theme_Enabled_Settings_Theme_Equals_ThemeManager_Theme () - { - Assert.False (IsEnabled); - - Enable (ConfigLocations.HardCoded); - - Assert.Equal (Settings! ["Theme"].PropertyValue, ThemeManager.Theme); - Assert.Equal (ThemeManager.DEFAULT_THEME_NAME, ThemeManager.Theme); - - Disable (resetToHardCodedDefaults: true); - } - - [Fact] - public void Theme_Set_Sets () - { - Assert.False (IsEnabled); - - Enable (ConfigLocations.HardCoded); - - Assert.Equal (ThemeManager.DEFAULT_THEME_NAME, ThemeManager.Theme); - - ThemeManager.Theme = "Test"; - Assert.Equal ("Test", ThemeManager.Theme); - Assert.Equal (Settings! ["Theme"].PropertyValue, ThemeManager.Theme); - Assert.Equal ("Test", Settings! ["Theme"].PropertyValue); - - Disable (resetToHardCodedDefaults: true); - } - - [Fact] - public void Theme_ResetToHardCodedDefaults_Sets_To_Default () - { - try - { - Assert.False (IsEnabled); - Assert.Equal (ThemeManager.DEFAULT_THEME_NAME, ThemeManager.Theme); - - Enable (ConfigLocations.HardCoded); - Assert.Equal ("Default", ThemeManager.Theme); - - ThemeManager.Theme = "Test"; - Assert.Equal ("Test", ThemeManager.Theme); - Assert.Equal (Settings! ["Theme"].PropertyValue, ThemeManager.Theme); - Assert.Equal ("Test", Settings! ["Theme"].PropertyValue); - - ResetToHardCodedDefaults (); - Assert.Equal ("Default", ThemeManager.Theme); - } - finally - { - Disable(true); - } - } - - #endregion Tests Settings["Theme"] and ThemeManager.Theme - - #region Tests Settings["Themes"] and ThemeManager.Themes - - [Fact] - public void Themes_Set_Throws_If_Not_Enabled () - { - Assert.False (IsEnabled); - - Assert.Single (ThemeManager.Themes!); - Assert.Throws (() => ThemeManager.Themes = new ()); - Assert.Single (ThemeManager.Themes!); - } - - [Fact] - public void Themes_Set_Sets_If_Enabled () - { - Assert.False (IsEnabled); - - Enable (ConfigLocations.HardCoded); - - Assert.Single (ThemeManager.Themes!); - - // Use ConcurrentDictionary instead of a regular dictionary - ThemeManager.Themes = new ConcurrentDictionary ( - new Dictionary - { - { "Default", new ThemeScope() }, - { "test", new ThemeScope() } - }, - StringComparer.InvariantCultureIgnoreCase - ); - - Assert.Contains ("test", ThemeManager.Themes!); - - Disable (resetToHardCodedDefaults: true); - } - - - [Fact] - public void Themes_Set_Throws_If_No_Default_Theme_In_Dictionary () - { - Assert.False (IsEnabled); - - Enable (ConfigLocations.HardCoded); - - Assert.Single (ThemeManager.Themes!); - - Assert.Throws ( - () => ThemeManager.Themes = new ConcurrentDictionary ( - new Dictionary - { - { "test", new ThemeScope() } - }, - StringComparer.InvariantCultureIgnoreCase - )); - Assert.Single (ThemeManager.Themes!); - - Disable (resetToHardCodedDefaults: true); - } - - [Fact] - public void Themes_Get () { } - - #endregion Tests Settings["Themes"] and ThemeManager.Themes - - [Fact] - public void Themes_TryAdd_Adds () - { - Enable (ConfigLocations.HardCoded); - - // Verify that the Themes dictionary contains only the Default theme - Assert.Single (ThemeManager.Themes!); - Assert.Contains (ThemeManager.DEFAULT_THEME_NAME, ThemeManager.Themes!); - - var theme = new ThemeScope (); - theme.LoadHardCodedDefaults (); - Assert.NotEmpty (theme); - - Assert.True (ThemeManager.Themes!.TryAdd ("testTheme", theme)); - Assert.Equal (2, ThemeManager.Themes.Count); - - Disable (resetToHardCodedDefaults: true); - } - - [Fact] - public void Apply_Applies () - { - Assert.False (IsEnabled); - Enable (ConfigLocations.HardCoded); - - var theme = new ThemeScope (); - theme.LoadHardCodedDefaults (); - Assert.NotEmpty (theme); - - Assert.True (ThemeManager.Themes!.TryAdd ("testTheme", theme)); - Assert.Equal (2, ThemeManager.Themes.Count); - - Assert.Equal (LineStyle.Rounded, FrameView.DefaultBorderStyle); - theme ["FrameView.DefaultBorderStyle"].PropertyValue = LineStyle.Double; // default is Single - - ThemeManager.Theme = "testTheme"; - ThemeManager.Themes! [ThemeManager.Theme]!.Apply (); - - Assert.Equal (LineStyle.Double, FrameView.DefaultBorderStyle); - - Disable (resetToHardCodedDefaults: true); - } - - [Fact] - public void Theme_Reload_Consistency () - { - try - { - Enable (ConfigLocations.HardCoded); - - // BUGBUG: Setting Schemes to empty array is not valid! - // Create a test theme - RuntimeConfig = """ - { - "Theme": "TestTheme", - "Themes": [ - { - "TestTheme": { - "Schemes": [] - } - } - ] - } - """; - - // Load the test theme - ThrowOnJsonErrors = true; - Load (ConfigLocations.Runtime); - Assert.Equal ("TestTheme", ThemeManager.Theme); - - // Now reset everything and reload - ResetToHardCodedDefaults (); - - // Verify we're back to default - Assert.Equal ("Default", ThemeManager.Theme); - } - finally - { - Disable (resetToHardCodedDefaults: true); - } - } - - [Fact] - public void In_Memory_Themes_Size_Is_Reasonable () - { - output.WriteLine ($"Start: Color size: {(MemorySizeEstimator.EstimateSize (Color.Red))} b"); - - output.WriteLine ($"Start: Attribute size: {(MemorySizeEstimator.EstimateSize (Attribute.Default))} b"); - - output.WriteLine ($"Start: Base Scheme size: {(MemorySizeEstimator.EstimateSize (Scheme.GetHardCodedSchemes ()))} b"); - - output.WriteLine ($"Start: PropertyInfo size: {(MemorySizeEstimator.EstimateSize (ConfigurationManager.Settings! ["Application.DefaultKeyBindings"]))} b"); - - ThemeScope themeScope = new ThemeScope (); - output.WriteLine ($"Start: ThemeScope ({themeScope.Count}) size: {(MemorySizeEstimator.EstimateSize (themeScope))} b"); - - themeScope.AddValue ("Schemes", Scheme.GetHardCodedSchemes ()); - output.WriteLine ($"Start: ThemeScope ({themeScope.Count}) size: {(MemorySizeEstimator.EstimateSize (themeScope))} b"); - - output.WriteLine ($"Start: HardCoded Schemes ({SchemeManager.Schemes!.Count}) size: {(MemorySizeEstimator.EstimateSize (SchemeManager.Schemes!))} b"); - - output.WriteLine ($"Start: Themes dictionary ({ThemeManager.Themes!.Count}) size: {(MemorySizeEstimator.EstimateSize (ThemeManager.Themes!)) / 1024} Kb"); - - Enable (ConfigLocations.HardCoded); - - output.WriteLine ($"Enabled: Themes dictionary ({ThemeManager.Themes.Count}) size: {(MemorySizeEstimator.EstimateSize (ThemeManager.Themes!)) / 1024} Kb"); - - Load (ConfigLocations.LibraryResources); - output.WriteLine ($"After Load: Themes dictionary ({ThemeManager.Themes!.Count}) size: {(MemorySizeEstimator.EstimateSize (ThemeManager.Themes!)) / 1024} Kb"); - - output.WriteLine ($"Total Settings Size: {(MemorySizeEstimator.EstimateSize (Settings!)) / 1024} Kb"); - - string json = ConfigurationManager.SourcesManager?.ToJson (Settings)!; - - // In memory size should be less than the size of the json - output.WriteLine ($"JSON size: {json.Length / 1024} Kb"); - - Assert.True (70000 > MemorySizeEstimator.EstimateSize (ThemeManager.Themes!), $"In memory size ({(MemorySizeEstimator.EstimateSize (Settings!)) / 1024} Kb) is > json size ({json.Length / 1024} Kb)"); - - Disable (resetToHardCodedDefaults: true); - } -} \ No newline at end of file diff --git a/Tests/UnitTests.Legacy/Text/AutocompleteTests.cs b/Tests/UnitTests.Legacy/Text/AutocompleteTests.cs deleted file mode 100644 index 34272f33cb..0000000000 --- a/Tests/UnitTests.Legacy/Text/AutocompleteTests.cs +++ /dev/null @@ -1,283 +0,0 @@ -using System.Text.RegularExpressions; - -namespace UnitTests.TextTests; - -public class AutocompleteTests (ITestOutputHelper output) -{ - [Fact] - [AutoInitShutdown] - public void CursorLeft_CursorRight_Mouse_Button_Pressed_Does_Not_Show_Popup () - { - Application.Driver?.SetScreenSize (50, 5); - - var tv = new TextView { Width = 50, Height = 5, Text = "This a long line and against TextView." }; - - var g = (SingleWordSuggestionGenerator)tv.Autocomplete.SuggestionGenerator; - - g.AllSuggestions = Regex.Matches (tv.Text, "\\w+") - .Select (s => s.Value) - .Distinct () - .ToList (); - Runnable top = new (); - top.Add (tv); - SessionToken rs = Application.Begin (top); - - for (var i = 0; i < 7; i++) - { - Assert.True (tv.NewKeyDownEvent (Key.CursorRight)); - top.SetNeedsDraw (); - AutoInitShutdownAttribute.RunIteration (); - Assert.Equal (i + 1, tv.InsertionPoint.X); - Assert.Equal (i + 1, tv.Cursor.Position!.Value.X); - - if (i < 4 || i > 5) - { - DriverAssert.AssertDriverContentsWithFrameAre ( - @" -This a long line and against TextView.", - output - ); - } - else - { - DriverAssert.AssertDriverContentsWithFrameAre ( - @" -This a long line and against TextView. - and - against ", - output - ); - } - } - - Assert.True ( - tv.NewMouseEvent ( - new () { Position = new (6, 0), Flags = MouseFlags.LeftButtonPressed } - ) - ); - top.SetNeedsDraw (); - AutoInitShutdownAttribute.RunIteration (); - - DriverAssert.AssertDriverContentsWithFrameAre ( - @" -This a long line and against TextView. - and - against ", - output - ); - - Assert.True (tv.NewKeyDownEvent (Key.G)); - top.SetNeedsDraw (); - AutoInitShutdownAttribute.RunIteration (); - - DriverAssert.AssertDriverContentsWithFrameAre ( - @" -This ag long line and against TextView. - against ", - output - ); - - Assert.True (tv.NewKeyDownEvent (Key.CursorLeft)); - top.SetNeedsDraw (); - AutoInitShutdownAttribute.RunIteration (); - - DriverAssert.AssertDriverContentsWithFrameAre ( - @" -This ag long line and against TextView. - against ", - output - ); - - Assert.True (tv.NewKeyDownEvent (Key.CursorLeft)); - top.SetNeedsDraw (); - AutoInitShutdownAttribute.RunIteration (); - - DriverAssert.AssertDriverContentsWithFrameAre ( - @" -This ag long line and against TextView. - against ", - output - ); - - Assert.True (tv.NewKeyDownEvent (Key.CursorLeft)); - top.SetNeedsDraw (); - AutoInitShutdownAttribute.RunIteration (); - - DriverAssert.AssertDriverContentsWithFrameAre ( - @" -This ag long line and against TextView.", - output - ); - - for (var i = 0; i < 3; i++) - { - Assert.True (tv.NewKeyDownEvent (Key.CursorRight)); - top.SetNeedsDraw (); - AutoInitShutdownAttribute.RunIteration (); - - DriverAssert.AssertDriverContentsWithFrameAre ( - @" -This ag long line and against TextView. - against ", - output - ); - } - - Assert.True (tv.NewKeyDownEvent (Key.Backspace)); - top.SetNeedsDraw (); - AutoInitShutdownAttribute.RunIteration (); - - DriverAssert.AssertDriverContentsWithFrameAre ( - @" -This a long line and against TextView. - and - against ", - output - ); - - Assert.True (tv.NewKeyDownEvent (Key.N)); - top.SetNeedsDraw (); - AutoInitShutdownAttribute.RunIteration (); - - DriverAssert.AssertDriverContentsWithFrameAre ( - @" -This an long line and against TextView. - and ", - output - ); - - Assert.True (tv.NewKeyDownEvent (Key.CursorRight)); - top.SetNeedsDraw (); - AutoInitShutdownAttribute.RunIteration (); - - DriverAssert.AssertDriverContentsWithFrameAre ( - @" -This an long line and against TextView.", - output - ); - Assert.Empty (tv.Autocomplete.Suggestions); - Assert.False (((PopupAutocomplete)tv.Autocomplete)._popup.Visible); - - top.Dispose (); - } - - [Fact] - [AutoInitShutdown] - public void KeyBindings_Command () - { - var tv = new TextView { Width = 10, Height = 2, Text = " Fortunately super feature." }; - Runnable top = new (); - top.Add (tv); - Application.Begin (top); - - Assert.Equal (Point.Empty, tv.InsertionPoint); - Assert.NotNull (tv.Autocomplete); - var g = (SingleWordSuggestionGenerator)tv.Autocomplete.SuggestionGenerator; - - Assert.Empty (g.AllSuggestions); - - g.AllSuggestions = Regex.Matches (tv.Text, "\\w+") - .Select (s => s.Value) - .Distinct () - .ToList (); - Assert.Equal (3, g.AllSuggestions.Count); - Assert.Equal ("Fortunately", g.AllSuggestions [0]); - Assert.Equal ("super", g.AllSuggestions [1]); - Assert.Equal ("feature", g.AllSuggestions [^1]); - Assert.Equal (0, tv.Autocomplete.SelectedIdx); - Assert.Empty (tv.Autocomplete.Suggestions); - Assert.True (tv.NewKeyDownEvent (Key.F.WithShift)); - top.Draw (); - Assert.Equal ("F Fortunately super feature.", tv.Text); - Assert.Equal (new (1, 0), tv.InsertionPoint); - Assert.Equal (2, tv.Autocomplete.Suggestions.Count); - Assert.Equal ("Fortunately", tv.Autocomplete.Suggestions [0].Replacement); - Assert.Equal ("feature", tv.Autocomplete.Suggestions [^1].Replacement); - Assert.Equal (0, tv.Autocomplete.SelectedIdx); - Assert.Equal ("Fortunately", tv.Autocomplete.Suggestions [tv.Autocomplete.SelectedIdx].Replacement); - Assert.True (tv.NewKeyDownEvent (Key.CursorDown)); - top.Draw (); - Assert.Equal ("F Fortunately super feature.", tv.Text); - Assert.Equal (new (1, 0), tv.InsertionPoint); - Assert.Equal (2, tv.Autocomplete.Suggestions.Count); - Assert.Equal ("Fortunately", tv.Autocomplete.Suggestions [0].Replacement); - Assert.Equal ("feature", tv.Autocomplete.Suggestions [^1].Replacement); - Assert.Equal (1, tv.Autocomplete.SelectedIdx); - Assert.Equal ("feature", tv.Autocomplete.Suggestions [tv.Autocomplete.SelectedIdx].Replacement); - Assert.True (tv.NewKeyDownEvent (Key.CursorDown)); - top.Draw (); - Assert.Equal ("F Fortunately super feature.", tv.Text); - Assert.Equal (new (1, 0), tv.InsertionPoint); - Assert.Equal (2, tv.Autocomplete.Suggestions.Count); - Assert.Equal ("Fortunately", tv.Autocomplete.Suggestions [0].Replacement); - Assert.Equal ("feature", tv.Autocomplete.Suggestions [^1].Replacement); - Assert.Equal (0, tv.Autocomplete.SelectedIdx); - Assert.Equal ("Fortunately", tv.Autocomplete.Suggestions [tv.Autocomplete.SelectedIdx].Replacement); - Assert.True (tv.NewKeyDownEvent (Key.CursorUp)); - top.Draw (); - Assert.Equal ("F Fortunately super feature.", tv.Text); - Assert.Equal (new (1, 0), tv.InsertionPoint); - Assert.Equal (2, tv.Autocomplete.Suggestions.Count); - Assert.Equal ("Fortunately", tv.Autocomplete.Suggestions [0].Replacement); - Assert.Equal ("feature", tv.Autocomplete.Suggestions [^1].Replacement); - Assert.Equal (1, tv.Autocomplete.SelectedIdx); - Assert.Equal ("feature", tv.Autocomplete.Suggestions [tv.Autocomplete.SelectedIdx].Replacement); - Assert.True (tv.NewKeyDownEvent (Key.CursorUp)); - top.Draw (); - Assert.Equal ("F Fortunately super feature.", tv.Text); - Assert.Equal (new (1, 0), tv.InsertionPoint); - Assert.Equal (2, tv.Autocomplete.Suggestions.Count); - Assert.Equal ("Fortunately", tv.Autocomplete.Suggestions [0].Replacement); - Assert.Equal ("feature", tv.Autocomplete.Suggestions [^1].Replacement); - Assert.Equal (0, tv.Autocomplete.SelectedIdx); - Assert.Equal ("Fortunately", tv.Autocomplete.Suggestions [tv.Autocomplete.SelectedIdx].Replacement); - Assert.True (tv.Autocomplete.Visible); - top.Draw (); - Assert.True (tv.NewKeyDownEvent (new (tv.Autocomplete.CloseKey))); - Assert.Equal ("F Fortunately super feature.", tv.Text); - Assert.Equal (new (1, 0), tv.InsertionPoint); - Assert.Empty (tv.Autocomplete.Suggestions); - Assert.Equal (3, g.AllSuggestions.Count); - Assert.False (tv.Autocomplete.Visible); - - Assert.True (tv.NewKeyDownEvent (new (tv.Autocomplete.Reopen))); - Assert.Equal ("F Fortunately super feature.", tv.Text); - Assert.Equal (new (1, 0), tv.InsertionPoint); - Assert.Equal (2, tv.Autocomplete.Suggestions.Count); - Assert.Equal (3, g.AllSuggestions.Count); - - Assert.True (tv.NewKeyDownEvent (new (tv.Autocomplete.SelectionKey))); - Assert.Equal ("Fortunately Fortunately super feature.", tv.Text); - Assert.Equal (new (11, 0), tv.InsertionPoint); - Assert.Empty (tv.Autocomplete.Suggestions); - Assert.Equal (3, g.AllSuggestions.Count); - Assert.False (tv.Autocomplete.Visible); - top.Dispose (); - } - - [Fact] - [AutoInitShutdown] - public void TestSettingSchemeOnAutocomplete () - { - var tv = new TextView (); - - // to begin with we should be using the default menu scheme - Assert.Same (SchemeManager.GetSchemes () ["Menu"], tv.Autocomplete.Scheme); - - // allocate a new custom scheme - tv.Autocomplete.Scheme = new () - { - Normal = new (Color.Black, Color.Blue), Focus = new (Color.Black, Color.Cyan) - }; - - // should be separate instance - Assert.NotSame (SchemeManager.GetSchemes () ["Menu"], tv.Autocomplete.Scheme); - - // with the values we set on it - Assert.Equal (new (Color.Black), tv.Autocomplete.Scheme.Normal.Foreground); - Assert.Equal (new (Color.Blue), tv.Autocomplete.Scheme.Normal.Background); - - Assert.Equal (new (Color.Black), tv.Autocomplete.Scheme.Focus.Foreground); - Assert.Equal (new (Color.Cyan), tv.Autocomplete.Scheme.Focus.Background); - } -} diff --git a/Tests/UnitTests.Legacy/Tracing/ThreadSafeTraceTests.cs b/Tests/UnitTests.Legacy/Tracing/ThreadSafeTraceTests.cs deleted file mode 100644 index 51f2e03346..0000000000 --- a/Tests/UnitTests.Legacy/Tracing/ThreadSafeTraceTests.cs +++ /dev/null @@ -1,354 +0,0 @@ -// Claude - Opus 4.5 - -using Terminal.Gui.Tracing; -using UnitTests.Parallelizable; - -#pragma warning disable xUnit1031 - -namespace UnitTests.TracingTests; - -/// -/// Tests for thread-safe tracing behavior. -/// These tests verify that tracing is properly isolated per-thread and per-async-context. -/// All tests work correctly in both Debug and Release builds. -/// IMPORTANT: These tests set static state on the Trace class, so they must be run in isolation (not parallelized) to avoid interference between tests. -/// -public class ThreadSafeTraceTests (ITestOutputHelper output) -{ - [Fact] - public void EnabledCategories_Default_IsNone () - { - // Reset to clean state - Trace.EnabledCategories = TraceCategory.None; - - Assert.Equal (TraceCategory.None, Trace.EnabledCategories); - } - - [Fact] - public void EnabledCategories_CanBeSetAndRead () - { - try - { - Trace.EnabledCategories = TraceCategory.Command | TraceCategory.Mouse; - - Assert.True (Trace.EnabledCategories.HasFlag (TraceCategory.Command)); - Assert.True (Trace.EnabledCategories.HasFlag (TraceCategory.Mouse)); - Assert.False (Trace.EnabledCategories.HasFlag (TraceCategory.Keyboard)); - } - finally - { - Trace.EnabledCategories = TraceCategory.None; - } - } - - [Fact] - public void EnabledCategories_HasFlagWorks () - { - try - { - Trace.EnabledCategories = TraceCategory.Command | TraceCategory.Keyboard; - - Assert.True (Trace.EnabledCategories.HasFlag (TraceCategory.Command)); - Assert.True (Trace.EnabledCategories.HasFlag (TraceCategory.Keyboard)); - Assert.False (Trace.EnabledCategories.HasFlag (TraceCategory.Mouse)); - Assert.False (Trace.EnabledCategories.HasFlag (TraceCategory.Navigation)); - Assert.False (Trace.EnabledCategories.HasFlag (TraceCategory.Lifecycle)); - } - finally - { - Trace.EnabledCategories = TraceCategory.None; - } - } - - [Fact] - public void PushScope_RestoresPreviousState () - { - try - { - Trace.EnabledCategories = TraceCategory.None; - - using (Trace.PushScope (TraceCategory.Command)) - { - Assert.True (Trace.EnabledCategories.HasFlag (TraceCategory.Command)); - } - - Assert.False (Trace.EnabledCategories.HasFlag (TraceCategory.Command)); - Assert.Equal (TraceCategory.None, Trace.EnabledCategories); - } - finally - { - Trace.EnabledCategories = TraceCategory.None; - } - } - - [Fact] - public void PushScope_NestedScopes_RestoreCorrectly () - { - try - { - Trace.EnabledCategories = TraceCategory.Mouse; - - using (Trace.PushScope (TraceCategory.Command)) - { - Assert.True (Trace.EnabledCategories.HasFlag (TraceCategory.Command)); - Assert.False (Trace.EnabledCategories.HasFlag (TraceCategory.Mouse)); - - using (Trace.PushScope (TraceCategory.Keyboard)) - { - Assert.False (Trace.EnabledCategories.HasFlag (TraceCategory.Command)); - Assert.True (Trace.EnabledCategories.HasFlag (TraceCategory.Keyboard)); - } - - Assert.True (Trace.EnabledCategories.HasFlag (TraceCategory.Command)); - Assert.False (Trace.EnabledCategories.HasFlag (TraceCategory.Keyboard)); - } - - Assert.True (Trace.EnabledCategories.HasFlag (TraceCategory.Mouse)); - Assert.False (Trace.EnabledCategories.HasFlag (TraceCategory.Command)); - } - finally - { - Trace.EnabledCategories = TraceCategory.None; - } - } - - [Fact] - public void PushScope_WithBackend_RestoresBackend () - { - ListBackend customBackend = new (); - - try - { - Trace.Backend = new NullBackend (); - - using (Trace.PushScope (TraceCategory.Command, customBackend)) - { - Assert.Same (customBackend, Trace.Backend); - Assert.True (Trace.EnabledCategories.HasFlag (TraceCategory.Command)); - } - - Assert.IsType (Trace.Backend); - Assert.False (Trace.EnabledCategories.HasFlag (TraceCategory.Command)); - } - finally - { - Trace.EnabledCategories = TraceCategory.None; - Trace.Backend = new NullBackend (); - } - } - - [Fact] - public void PushScope_CapturesTraces () - { - ListBackend backend = new (); - - try - { - using (Trace.PushScope (TraceCategory.Command, backend)) - { - View view = new () { Id = "test" }; - Trace.Command (view, Command.Accept, CommandRouting.Direct, "TestPhase", "TestMessage"); - -#if DEBUG - Assert.Single (backend.Entries); - Assert.Equal (TraceCategory.Command, backend.Entries [0].Category); - Assert.Contains ("test", backend.Entries [0].Id); -#else - // In Release, [Conditional("DEBUG")] removes Trace.Command calls - Assert.Empty (backend.Entries); -#endif - } - } - finally - { - Trace.EnabledCategories = TraceCategory.None; - Trace.Backend = new NullBackend (); - } - } - - [Fact] - public void TestLogging_Verbose_WithTraceCategories () - { - try - { - using (TestLogging.Verbose (output, TraceCategory.Command)) - { - Assert.True (Trace.EnabledCategories.HasFlag (TraceCategory.Command)); - Assert.False (Trace.EnabledCategories.HasFlag (TraceCategory.Mouse)); - - CheckBox checkbox = new () { Id = "checkbox" }; - checkbox.InvokeCommand (Command.Activate); - } - - // After scope, tracing should be disabled - Assert.False (Trace.EnabledCategories.HasFlag (TraceCategory.Command)); - } - finally - { - Trace.EnabledCategories = TraceCategory.None; - } - } - - [Fact] - public async Task ParallelTests_IsolatedTracing_Test1 () - { - ListBackend backend = new (); - - try - { - using (Trace.PushScope (TraceCategory.Command, backend)) - { - // Simulate some async work - await Task.Delay (10, TestContext.Current.CancellationToken); - - View view = new () { Id = "parallel-test-1" }; - Trace.Command (view, Command.Accept, CommandRouting.Direct, "Test1"); - - await Task.Delay (10, TestContext.Current.CancellationToken); - -#if DEBUG - // This test should only see its own traces - Assert.All (backend.Entries, entry => Assert.Contains ("parallel-test-1", entry.Id)); -#else - Assert.Empty (backend.Entries); -#endif - - Assert.True (Trace.EnabledCategories.HasFlag (TraceCategory.Command)); - } - } - finally - { - Trace.EnabledCategories = TraceCategory.None; - } - } - - [Fact] - public async Task ParallelTests_IsolatedTracing_Test2 () - { - ListBackend backend = new (); - - try - { - using (Trace.PushScope (TraceCategory.Mouse, backend)) - { - // Simulate some async work - await Task.Delay (10, TestContext.Current.CancellationToken); - - View view = new () { Id = "parallel-test-2" }; - Trace.Mouse (view, MouseFlags.LeftButtonClicked, Point.Empty, "Test2"); - - await Task.Delay (10, TestContext.Current.CancellationToken); - -#if DEBUG - // This test should only see its own traces - Assert.All (backend.Entries, entry => Assert.Contains ("parallel-test-2", entry.Id)); -#else - Assert.Empty (backend.Entries); -#endif - - Assert.True (Trace.EnabledCategories.HasFlag (TraceCategory.Mouse)); - Assert.False (Trace.EnabledCategories.HasFlag (TraceCategory.Command)); - } - } - finally - { - Trace.EnabledCategories = TraceCategory.None; - } - } - - [Fact] - public void EnabledCategories_IsAsyncLocal_IsolatesAcrossExecutionContexts () - { - try - { - Trace.EnabledCategories = TraceCategory.Command; - - TraceCategory capturedCategories = TraceCategory.None; - - // Task.Run flows ExecutionContext by default, so the async-local value is visible in the task. - // The key isolation behavior is that changes in the task don't affect the parent context. - Task.Run (() => - { - // Task sees parent's value due to ExecutionContext flow - capturedCategories = Trace.EnabledCategories; - - // Set different categories in task context - Trace.EnabledCategories = TraceCategory.Mouse; - }, - TestContext.Current.CancellationToken) - .Wait (TestContext.Current.CancellationToken); - - // Parent context is unchanged despite modifications in the task - Assert.True (Trace.EnabledCategories.HasFlag (TraceCategory.Command)); - Assert.Equal (TraceCategory.Command, Trace.EnabledCategories); - } - finally - { - Trace.EnabledCategories = TraceCategory.None; - } - } - - [Fact] - public void Backend_IsAsyncLocal_IsolatedPerExecutionContext () - { - ListBackend mainBackend = new (); - - try - { - Trace.Backend = mainBackend; - - ITraceBackend? capturedBackend = null; - - // Use Task.Run which may or may not flow ExecutionContext - Task.Run (() => - { - capturedBackend = Trace.Backend; - - // Set different backend in this context - Trace.Backend = new ListBackend (); - }, - TestContext.Current.CancellationToken) - .Wait (TestContext.Current.CancellationToken); - - // Main thread backend should be unchanged - Assert.Same (mainBackend, Trace.Backend); - } - finally - { - Trace.Backend = new NullBackend (); - } - } - - [Fact] - public async Task AsyncLocal_FlowsAcrossAwait () - { - ListBackend backend = new (); - - try - { - using (Trace.PushScope (TraceCategory.Command, backend)) - { - Assert.True (Trace.EnabledCategories.HasFlag (TraceCategory.Command)); - - // EnabledCategories should flow across await - await Task.Delay (1, TestContext.Current.CancellationToken); - - Assert.True (Trace.EnabledCategories.HasFlag (TraceCategory.Command)); - Assert.Same (backend, Trace.Backend); - - View view = new () { Id = "async-test" }; - Trace.Command (view, Command.Accept, CommandRouting.Direct, "AfterAwait"); - -#if DEBUG - Assert.Single (backend.Entries); -#else - Assert.Empty (backend.Entries); -#endif - } - } - finally - { - Trace.EnabledCategories = TraceCategory.None; - } - } -} diff --git a/Tests/UnitTests.Legacy/View/Adornment/AdornmentTests.cs b/Tests/UnitTests.Legacy/View/Adornment/AdornmentTests.cs deleted file mode 100644 index 442e187f05..0000000000 --- a/Tests/UnitTests.Legacy/View/Adornment/AdornmentTests.cs +++ /dev/null @@ -1,74 +0,0 @@ -namespace UnitTests.ViewBaseTests; - -public class AdornmentTests (ITestOutputHelper output) -{ - [Fact] - [SetupFakeApplication] - public void Border_Is_Cleared_After_Margin_Thickness_Change () - { - View view = new () - { - App = ApplicationImpl.Instance, - Text = "View", Width = 6, Height = 3, BorderStyle = LineStyle.Rounded - }; - - // Remove border bottom thickness - view.Border!.Thickness = new (1, 1, 1, 0); - - // Add margin bottom thickness - view.Margin!.Thickness = new (0, 0, 0, 1); - - Assert.Equal (6, view.Width); - Assert.Equal (3, view.Height); - - view.Draw (); - - DriverAssert.AssertDriverContentsWithFrameAre ( - @" -╭────╮ -│View│ -", - output - ); - - // Add border bottom thickness - view.Border!.Thickness = new (1, 1, 1, 1); - - // Remove margin bottom thickness - view.Margin!.Thickness = new (0, 0, 0, 0); - - view.Draw (); - - Assert.Equal (6, view.Width); - Assert.Equal (3, view.Height); - - DriverAssert.AssertDriverContentsWithFrameAre ( - @" -╭────╮ -│View│ -╰────╯ -", - output - ); - - // Remove border bottom thickness - view.Border!.Thickness = new (1, 1, 1, 0); - - // Add margin bottom thickness - view.Margin!.Thickness = new (0, 0, 0, 1); - - Assert.Equal (6, view.Width); - Assert.Equal (3, view.Height); - - view.App.LayoutAndDraw (true); - view.Draw (); - - DriverAssert.AssertDriverContentsWithFrameAre ( - @" -╭────╮ -│View│ -", - output - ); - } -} diff --git a/Tests/UnitTests.Legacy/View/Adornment/BorderTests.cs b/Tests/UnitTests.Legacy/View/Adornment/BorderTests.cs deleted file mode 100644 index b02464ed26..0000000000 --- a/Tests/UnitTests.Legacy/View/Adornment/BorderTests.cs +++ /dev/null @@ -1,955 +0,0 @@ -namespace UnitTests.ViewBaseTests; - -public class BorderTests (ITestOutputHelper output) -{ - [Fact] - [SetupFakeApplication] - public void Border_Parent_HasFocus_Title_Uses_FocusAttribute () - { - var superView = new View - { - Driver = ApplicationImpl.Instance.Driver, - Width = 10, Height = 10, CanFocus = true - }; - var otherView = new View { Width = 0, Height = 0, CanFocus = true }; - superView.Add (otherView); - - var view = new View { Title = "A", Height = 2, Width = 5 }; - superView.Add (view); - - view.Border!.Thickness = new (0, 1, 0, 0); - view.Border!.LineStyle = LineStyle.Single; - - view.SetScheme ( - new () - { - Normal = new (Color.Red, Color.Green), - Focus = new (Color.Green, Color.Red) - }); - Assert.NotEqual (view.GetScheme ().Normal.Foreground, view.GetScheme ().Focus.Foreground); - Assert.Equal (ColorName16.Red, view.Border!.GetAttributeForRole (VisualRole.Normal).Foreground.GetClosestNamedColor16 ()); - Assert.Equal (ColorName16.Green, view.Border!.GetAttributeForRole (VisualRole.Focus).Foreground.GetClosestNamedColor16 ()); - Assert.Equal (view.GetAttributeForRole (VisualRole.Focus), view.Border!.GetAttributeForRole (VisualRole.Focus)); - - superView.BeginInit (); - superView.EndInit (); - superView.Draw (); - - var expected = @"─┤A├─"; - DriverAssert.AssertDriverContentsAre (expected, output); - DriverAssert.AssertDriverAttributesAre ("00000", output, null, view.GetScheme ().Normal); - - view.CanFocus = true; - view.SetFocus (); - view.SetClipToScreen (); - view.Draw (); - Assert.Equal (view.GetAttributeForRole (VisualRole.Focus), view.Border!.GetAttributeForRole (VisualRole.Focus)); - Assert.Equal (view.GetScheme ().Focus.Foreground, view.Border!.GetAttributeForRole (VisualRole.Focus).Foreground); - Assert.Equal (view.GetScheme ().Normal.Foreground, view.Border!.GetAttributeForRole (VisualRole.Normal).Foreground); - DriverAssert.AssertDriverAttributesAre ("00100", output, null, view.GetScheme ().Normal, view.GetAttributeForRole (VisualRole.Focus)); - } - - [Fact] - [SetupFakeApplication] - public void Border_Uses_Parent_Scheme () - { - var view = new View - { - Driver = ApplicationImpl.Instance.Driver, - Title = "A", Height = 2, Width = 5 - }; - view.Border!.Thickness = new (0, 1, 0, 0); - view.Border!.LineStyle = LineStyle.Single; - - view.SetScheme ( - new () - { - Normal = new (Color.Red, Color.Green), Focus = new (Color.Green, Color.Red) - }); - Assert.Equal (ColorName16.Red, view.Border!.GetAttributeForRole (VisualRole.Normal).Foreground.GetClosestNamedColor16 ()); - Assert.Equal (ColorName16.Green, view.Border!.GetAttributeForRole (VisualRole.Focus).Foreground.GetClosestNamedColor16 ()); - Assert.Equal (view.GetAttributeForRole (VisualRole.Normal), view.Border!.GetAttributeForRole (VisualRole.Normal)); - Assert.Equal (view.GetAttributeForRole (VisualRole.Focus), view.Border!.GetAttributeForRole (VisualRole.Focus)); - - view.BeginInit (); - view.EndInit (); - view.Draw (); - - var expected = @"─┤A├─"; - DriverAssert.AssertDriverContentsAre (expected, output); - DriverAssert.AssertDriverAttributesAre ("00000", output, null, view.GetScheme ().Normal); - } - - [Theory] - [AutoInitShutdown] - [InlineData (0)] - [InlineData (1)] - [InlineData (2)] - [InlineData (3)] - [InlineData (4)] - [InlineData (5)] - [InlineData (6)] - [InlineData (7)] - [InlineData (8)] - [InlineData (9)] - [InlineData (10)] - public void Border_With_Title_Border_Double_Thickness_Top_Four_Size_Width (int width) - { - var win = new Window - { - Title = "1234", Width = Dim.Fill (), Height = Dim.Fill (), BorderStyle = LineStyle.Double - }; - win.Border!.Thickness = win.Border!.Thickness with { Top = 4 }; - - SessionToken rs = Application.Begin (win); - - Application.Driver!.SetScreenSize (width, 5); - AutoInitShutdownAttribute.RunIteration (); - var expected = string.Empty; - - switch (width) - { - case 1: - Assert.Equal (new (0, 0, 1, 5), win.Frame); - - expected = @" -║ -║ -║"; - - break; - case 2: - Assert.Equal (new (0, 0, 2, 5), win.Frame); - - expected = @" -╔╗ -║║ -╚╝"; - - break; - case 3: - Assert.Equal (new (0, 0, 3, 5), win.Frame); - - expected = @" -╔═╗ -║ ║ -╚═╝"; - - break; - case 4: - Assert.Equal (new (0, 0, 4, 5), win.Frame); - - expected = @" - ╒╕ -╔╡╞╗ -║╘╛║ -╚══╝"; - - break; - case 5: - Assert.Equal (new (0, 0, 5, 5), win.Frame); - - expected = @" - ╒═╕ -╔╡1╞╗ -║╘═╛║ -╚═══╝"; - - break; - case 6: - Assert.Equal (new (0, 0, 6, 5), win.Frame); - - expected = @" - ╒══╕ -╔╡12╞╗ -║╘══╛║ -╚════╝"; - - break; - case 7: - Assert.Equal (new (0, 0, 7, 5), win.Frame); - - expected = @" - ╒═══╕ -╔╡123╞╗ -║╘═══╛║ -╚═════╝"; - - break; - case 8: - Assert.Equal (new (0, 0, 8, 5), win.Frame); - - expected = @" - ╒════╕ -╔╡1234╞╗ -║╘════╛║ -╚══════╝"; - - break; - case 9: - Assert.Equal (new (0, 0, 9, 5), win.Frame); - - expected = @" - ╒════╕ -╔╡1234╞═╗ -║╘════╛ ║ -╚═══════╝"; - - break; - case 10: - Assert.Equal (new (0, 0, 10, 5), win.Frame); - - expected = @" - ╒════╕ -╔╡1234╞══╗ -║╘════╛ ║ -╚════════╝"; - - break; - } - - _ = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); - Application.End (rs); - win.Dispose (); - } - - [Theory] - [AutoInitShutdown] - [InlineData (0)] - [InlineData (1)] - [InlineData (2)] - [InlineData (3)] - [InlineData (4)] - [InlineData (5)] - [InlineData (6)] - [InlineData (7)] - [InlineData (8)] - [InlineData (9)] - [InlineData (10)] - public void Border_With_Title_Border_Double_Thickness_Top_Three_Size_Width (int width) - { - Window win = new () - { - Title = "1234", Width = Dim.Fill (), Height = Dim.Fill (), BorderStyle = LineStyle.Double - }; - win.Border!.Thickness = win.Border!.Thickness with { Top = 3 }; - - SessionToken rs = Application.Begin (win); - - Application.Driver!.SetScreenSize (width, 4); - AutoInitShutdownAttribute.RunIteration (); - var expected = string.Empty; - - switch (width) - { - case 1: - Assert.Equal (new (0, 0, 1, 4), win.Frame); - - expected = @" -║ -║ -║"; - - break; - case 2: - Assert.Equal (new (0, 0, 2, 4), win.Frame); - - expected = @" -╔╗ -║║ -╚╝"; - - break; - case 3: - Assert.Equal (new (0, 0, 3, 4), win.Frame); - - expected = @" -╔═╗ -║ ║ -╚═╝"; - - break; - case 4: - Assert.Equal (new (0, 0, 4, 4), win.Frame); - - expected = @" - ╒╕ -╔╡╞╗ -║╘╛║ -╚══╝"; - - break; - case 5: - Assert.Equal (new (0, 0, 5, 4), win.Frame); - - expected = @" - ╒═╕ -╔╡1╞╗ -║╘═╛║ -╚═══╝"; - - break; - case 6: - Assert.Equal (new (0, 0, 6, 4), win.Frame); - - expected = @" - ╒══╕ -╔╡12╞╗ -║╘══╛║ -╚════╝"; - - break; - case 7: - Assert.Equal (new (0, 0, 7, 4), win.Frame); - - expected = @" - ╒═══╕ -╔╡123╞╗ -║╘═══╛║ -╚═════╝"; - - break; - case 8: - Assert.Equal (new (0, 0, 8, 4), win.Frame); - - expected = @" - ╒════╕ -╔╡1234╞╗ -║╘════╛║ -╚══════╝"; - - break; - case 9: - Assert.Equal (new (0, 0, 9, 4), win.Frame); - - expected = @" - ╒════╕ -╔╡1234╞═╗ -║╘════╛ ║ -╚═══════╝"; - - break; - case 10: - Assert.Equal (new (0, 0, 10, 4), win.Frame); - - expected = @" - ╒════╕ -╔╡1234╞══╗ -║╘════╛ ║ -╚════════╝"; - - break; - } - - _ = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); - Application.End (rs); - win.Dispose (); - } - - [Theory] - [AutoInitShutdown] - [InlineData (0)] - [InlineData (1)] - [InlineData (2)] - [InlineData (3)] - [InlineData (4)] - [InlineData (5)] - [InlineData (6)] - [InlineData (7)] - [InlineData (8)] - [InlineData (9)] - [InlineData (10)] - public void Border_With_Title_Border_Double_Thickness_Top_Two_Size_Width (int width) - { - var win = new Window - { - Title = "1234", Width = Dim.Fill (), Height = Dim.Fill (), BorderStyle = LineStyle.Double - }; - win.Border!.Thickness = win.Border!.Thickness with { Top = 2 }; - - SessionToken rs = Application.Begin (win); - - Application.Driver!.SetScreenSize (width, 4); - AutoInitShutdownAttribute.RunIteration (); - var expected = string.Empty; - - switch (width) - { - case 1: - Assert.Equal (new (0, 0, 1, 4), win.Frame); - - expected = @" -║ -║ -║"; - - break; - case 2: - Assert.Equal (new (0, 0, 2, 4), win.Frame); - - expected = @" -╔╗ -║║ -╚╝"; - - break; - case 3: - Assert.Equal (new (0, 0, 3, 4), win.Frame); - - expected = @" -╔═╗ -║ ║ -╚═╝"; - - break; - case 4: - Assert.Equal (new (0, 0, 4, 4), win.Frame); - - expected = @" - ╒╕ -╔╛╘╗ -║ ║ -╚══╝"; - - break; - case 5: - Assert.Equal (new (0, 0, 5, 4), win.Frame); - - expected = @" - ╒═╕ -╔╛1╘╗ -║ ║ -╚═══╝"; - - break; - case 6: - Assert.Equal (new (0, 0, 6, 4), win.Frame); - - expected = @" - ╒══╕ -╔╛12╘╗ -║ ║ -╚════╝"; - - break; - case 7: - Assert.Equal (new (0, 0, 7, 4), win.Frame); - - expected = @" - ╒═══╕ -╔╛123╘╗ -║ ║ -╚═════╝"; - - break; - case 8: - Assert.Equal (new (0, 0, 8, 4), win.Frame); - - expected = @" - ╒════╕ -╔╛1234╘╗ -║ ║ -╚══════╝"; - - break; - case 9: - Assert.Equal (new (0, 0, 9, 4), win.Frame); - - expected = @" - ╒════╕ -╔╛1234╘═╗ -║ ║ -╚═══════╝"; - - break; - case 10: - Assert.Equal (new (0, 0, 10, 4), win.Frame); - - expected = @" - ╒════╕ -╔╛1234╘══╗ -║ ║ -╚════════╝"; - - break; - } - - _ = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); - Application.End (rs); - win.Dispose (); - } - - [Theory] - [AutoInitShutdown] - [InlineData (0)] - [InlineData (1)] - [InlineData (2)] - [InlineData (3)] - public void Border_With_Title_Size_Height (int height) - { - var win = new Window { Title = "1234", Width = Dim.Fill (), Height = Dim.Fill () }; - - SessionToken rs = Application.Begin (win); - - Application.Driver!.SetScreenSize (20, height); - AutoInitShutdownAttribute.RunIteration (); - var expected = string.Empty; - - switch (height) - { - case 0: - //Assert.Equal (new (0, 0, 17, 0), subview.Frame); - expected = @" -"; - - break; - case 1: - //Assert.Equal (new (0, 0, 17, 0), subview.Frame); - expected = @" -─┤1234├─────────────"; - - break; - case 2: - //Assert.Equal (new (0, 0, 17, 1), subview.Frame); - expected = @" -┌┤1234├────────────┐ -└──────────────────┘ -"; - - break; - case 3: - //Assert.Equal (new (0, 0, 17, 2), subview.Frame); - expected = @" -┌┤1234├────────────┐ -│ │ -└──────────────────┘ -"; - - break; - } - - _ = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); - Application.End (rs); - win.Dispose (); - } - - [Theory] - [AutoInitShutdown] - [InlineData (0)] - [InlineData (1)] - [InlineData (2)] - [InlineData (3)] - [InlineData (4)] - [InlineData (5)] - [InlineData (6)] - [InlineData (7)] - [InlineData (8)] - [InlineData (9)] - [InlineData (10)] - public void Border_With_Title_Size_Width (int width) - { - var win = new Window { Title = "1234", Width = Dim.Fill (), Height = Dim.Fill () }; - - SessionToken rs = Application.Begin (win); - - Application.Driver!.SetScreenSize (width, 3); - AutoInitShutdownAttribute.RunIteration (); - var expected = string.Empty; - - switch (width) - { - case 1: - //Assert.Equal (new (0, 0, 17, 0), subview.Frame); - expected = @" -│ -│ -│"; - - break; - case 2: - //Assert.Equal (new (0, 0, 17, 1), subview.Frame); - expected = @" -┌┐ -││ -└┘"; - - break; - case 3: - //Assert.Equal (new (0, 0, 17, 2), subview.Frame); - expected = @" -┌─┐ -│ │ -└─┘ -"; - - break; - case 4: - //Assert.Equal (new (0, 0, 17, 3), subview.Frame); - expected = @" -┌┤├┐ -│ │ -└──┘"; - - break; - case 5: - //Assert.Equal (new (0, 0, 17, 3), subview.Frame); - expected = @" -┌┤1├┐ -│ │ -└───┘"; - - break; - case 6: - //Assert.Equal (new (0, 0, 17, 3), subview.Frame); - expected = @" -┌┤12├┐ -│ │ -└────┘"; - - break; - case 7: - //Assert.Equal (new (0, 0, 17, 3), subview.Frame); - expected = @" -┌┤123├┐ -│ │ -└─────┘"; - - break; - case 8: - //Assert.Equal (new (0, 0, 17, 3), subview.Frame); - expected = @" -┌┤1234├┐ -│ │ -└──────┘"; - - break; - case 9: - //Assert.Equal (new (0, 0, 17, 3), subview.Frame); - expected = @" -┌┤1234├─┐ -│ │ -└───────┘"; - - break; - case 10: - //Assert.Equal (new (0, 0, 17, 3), subview.Frame); - expected = @" -┌┤1234├──┐ -│ │ -└────────┘"; - - break; - } - - _ = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); - win.Dispose (); - } - - [Theory] - [InlineData (0, 0, 0, 2, 2)] - [InlineData (1, 0, 0, 4, 4)] - [InlineData (2, 0, 0, 6, 6)] - [InlineData (1, 1, 0, 5, 4)] - [InlineData (1, 0, 1, 4, 5)] - [InlineData (1, 1, 1, 5, 5)] - [InlineData (1, 10, 10, 14, 14)] - public void FrameToScreen_NestedSuperView_WithBorder ( - int superOffset, - int frameX, - int frameY, - int expectedScreenX, - int expectedScreenY - ) - { - var superSuper = new View - { - X = superOffset, - Y = superOffset, - Width = 30, - Height = 30, - BorderStyle = LineStyle.Single - }; - - var super = new View - { - X = superOffset, - Y = superOffset, - Width = 20, - Height = 20, - BorderStyle = LineStyle.Single - }; - superSuper.Add (super); - - var view = new View { X = frameX, Y = frameY, Width = 10, Height = 10 }; - super.Add (view); - superSuper.Layout (); - - var expected = new Rectangle (expectedScreenX, expectedScreenY, 10, 10); - Rectangle actual = view.FrameToScreen (); - Assert.Equal (expected, actual); - } - - [Theory] - [InlineData (0, 0, 0, 1, 1)] - [InlineData (1, 0, 0, 2, 2)] - [InlineData (2, 0, 0, 3, 3)] - [InlineData (1, 1, 0, 3, 2)] - [InlineData (1, 0, 1, 2, 3)] - [InlineData (1, 1, 1, 3, 3)] - [InlineData (1, 10, 10, 12, 12)] - public void FrameToScreen_SuperView_WithBorder ( - int superOffset, - int frameX, - int frameY, - int expectedScreenX, - int expectedScreenY - ) - { - var super = new View - { - X = superOffset, - Y = superOffset, - Width = 20, - Height = 20, - BorderStyle = LineStyle.Single - }; - - var view = new View { X = frameX, Y = frameY, Width = 10, Height = 10 }; - super.Add (view); - super.Layout (); - - var expected = new Rectangle (expectedScreenX, expectedScreenY, 10, 10); - Rectangle actual = view.FrameToScreen (); - Assert.Equal (expected, actual); - } - - [Fact] - [AutoInitShutdown] - public void HasSuperView () - { - var top = new Runnable (); - top.BorderStyle = LineStyle.Double; - - var frame = new FrameView { Width = Dim.Fill (), Height = Dim.Fill (), BorderStyle = LineStyle.Single }; - - top.Add (frame); - SessionToken rs = Application.Begin (top); - - Application.Driver!.SetScreenSize (5, 5); - AutoInitShutdownAttribute.RunIteration (); - - var expected = @" -╔═══╗ -║┌─┐║ -║│ │║ -║└─┘║ -╚═══╝"; - - _ = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); - Application.End (rs); - top.Dispose (); - } - - [Fact] - [AutoInitShutdown] - public void HasSuperView_Title () - { - var top = new Runnable (); - top.BorderStyle = LineStyle.Double; - - var frame = new FrameView { Title = "1234", Width = Dim.Fill (), Height = Dim.Fill (), BorderStyle = LineStyle.Single }; - - top.Add (frame); - SessionToken rs = Application.Begin (top); - - Application.Driver!.SetScreenSize (10, 4); - AutoInitShutdownAttribute.RunIteration (); - - var expected = @" -╔════════╗ -║┌┤1234├┐║ -║└──────┘║ -╚════════╝"; - - _ = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); - Application.End (rs); - top.Dispose (); - } - - [Fact] - [AutoInitShutdown] - public void NoSuperView () - { - var win = new Window { Width = Dim.Fill (), Height = Dim.Fill () }; - - SessionToken rs = Application.Begin (win); - - Application.Driver!.SetScreenSize (3, 3); - AutoInitShutdownAttribute.RunIteration (); - - var expected = @" -┌─┐ -│ │ -└─┘"; - - _ = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); - win.Dispose (); - } - - [Fact] - public void View_BorderStyle_Defaults () - { - var view = new View (); - Assert.Equal (LineStyle.None, view.BorderStyle); - Assert.Equal (Thickness.Empty, view.Border!.Thickness); - view.Dispose (); - } - - [Fact] - public void View_SetBorderStyle () - { - var view = new View (); - view.BorderStyle = LineStyle.Single; - Assert.Equal (LineStyle.Single, view.BorderStyle); - Assert.Equal (new (1), view.Border!.Thickness); - - view.BorderStyle = LineStyle.Double; - Assert.Equal (LineStyle.Double, view.BorderStyle); - Assert.Equal (new (1), view.Border!.Thickness); - - view.BorderStyle = LineStyle.None; - Assert.Equal (LineStyle.None, view.BorderStyle); - Assert.Equal (Thickness.Empty, view.Border!.Thickness); - view.Dispose (); - } - - [Theory] - [InlineData ( - false, - @" -┌───┐ -│ ║ │ -│═┌┄│ -│ ┊ │ -└───┘")] - [InlineData ( - true, - @" -╔═╦─┐ -║ ║ │ -╠═╬┄┤ -│ ┊ ┊ -└─┴┄┘")] - [SetupFakeApplication] - public void SuperViewRendersLineCanvas_No_SubViews_AutoJoinsLines (bool superViewRendersLineCanvas, string expected) - { - var superView = new View - { - Driver = ApplicationImpl.Instance.Driver, - Id = "superView", - Width = 5, - Height = 5, - BorderStyle = LineStyle.Single - }; - - var view1 = new View - { - Id = "view1", - Width = 3, - Height = 3, - X = -1, - Y = -1, - BorderStyle = LineStyle.Double, - SuperViewRendersLineCanvas = superViewRendersLineCanvas - }; - - var view2 = new View - { - Id = "view2", - Width = 3, - Height = 3, - X = 1, - Y = 1, - BorderStyle = LineStyle.Dotted, - SuperViewRendersLineCanvas = superViewRendersLineCanvas - }; - - superView.Add (view1, view2); - - superView.BeginInit (); - superView.EndInit (); - superView.Draw (); - - DriverAssert.AssertDriverContentsAre (expected, output); - } - - [Theory] - [InlineData ( - false, - @" -┌┤A├──────┐ -│ ║ │ -│ ║ │ -│════┌┤C├┄│ -│ ┊ │ -│ ┊ │ -└─────────┘")] - [InlineData ( - true, - @" -╔╡A╞═╦────┐ -║ ║ │ -║ ║ │ -╠════╬┤C├┄┤ -│ ┊ ┊ -│ ┊ ┊ -└────┴┄┄┄┄┘")] - [SetupFakeApplication] - public void SuperViewRendersLineCanvas_Title_AutoJoinsLines (bool superViewRendersLineCanvas, string expected) - { - var superView = new View - { - Driver = ApplicationImpl.Instance.Driver, - Id = "superView", - Title = "A", - Width = 11, - Height = 7, - CanFocus = true, - BorderStyle = LineStyle.Single - }; - - var view1 = new View - { - Id = "view1", - Title = "B", - Width = 6, - Height = 4, - X = -1, - Y = -1, - CanFocus = true, - BorderStyle = LineStyle.Double, - SuperViewRendersLineCanvas = superViewRendersLineCanvas - }; - - var view2 = new View - { - Id = "view2", - Title = "C", - Width = 6, - Height = 4, - X = 4, - Y = 2, - CanFocus = true, - BorderStyle = LineStyle.Dotted, - SuperViewRendersLineCanvas = superViewRendersLineCanvas - }; - - superView.Add (view1, view2); - - superView.BeginInit (); - superView.EndInit (); - superView.Draw (); - - DriverAssert.AssertDriverContentsAre (expected, output); - } -} diff --git a/Tests/UnitTests.Legacy/View/Adornment/PaddingTests.cs b/Tests/UnitTests.Legacy/View/Adornment/PaddingTests.cs deleted file mode 100644 index 80f5846785..0000000000 --- a/Tests/UnitTests.Legacy/View/Adornment/PaddingTests.cs +++ /dev/null @@ -1,39 +0,0 @@ -namespace UnitTests.ViewBaseTests; - -public class PaddingTests (ITestOutputHelper output) -{ - [Fact] - [SetupFakeApplication] - public void Padding_Uses_Parent_Scheme () - { - ApplicationImpl.Instance.Driver!.SetScreenSize (5, 5); - var view = new View - { - App = ApplicationImpl.Instance, - Height = 3, Width = 3 - }; - view.Padding!.Thickness = new (1); - view.Padding.Diagnostics = ViewDiagnosticFlags.Thickness; - - view.SetScheme (new() - { - Normal = new (Color.Red, Color.Green), Focus = new (Color.Green, Color.Red) - }); - - Assert.Equal (ColorName16.Red, view.Padding.GetAttributeForRole (VisualRole.Normal).Foreground.GetClosestNamedColor16 ()); - Assert.Equal (view.GetAttributeForRole (VisualRole.Normal), view.Padding.GetAttributeForRole (VisualRole.Normal)); - - view.BeginInit (); - view.EndInit (); - view.Draw (); - - DriverAssert.AssertDriverContentsAre ( - @" -PPP -P P -PPP", - output - ); - DriverAssert.AssertDriverAttributesAre ("0", output, null, view.GetAttributeForRole (VisualRole.Normal)); - } -} diff --git a/Tests/UnitTests.Legacy/View/Adornment/ShadowStyleTests.cs b/Tests/UnitTests.Legacy/View/Adornment/ShadowStyleTests.cs deleted file mode 100644 index a2fb54a962..0000000000 --- a/Tests/UnitTests.Legacy/View/Adornment/ShadowStyleTests.cs +++ /dev/null @@ -1,127 +0,0 @@ -namespace UnitTests.ViewBaseTests; - -public class ShadowStyleTests (ITestOutputHelper output) -{ - [Theory] - [InlineData (ShadowStyle.None, - """ - 011 - 111 - 111 - """)] - [InlineData (ShadowStyle.Transparent, - """ - 031 - 131 - 111 - """)] - [InlineData (ShadowStyle.Opaque, - """ - 021 - 221 - 111 - """)] - [SetupFakeApplication] - public void ShadowView_Colors (ShadowStyle style, string expectedAttrs) - { - Application.Driver!.SetScreenSize (5, 5); - Color fg = Color.Red; - Color bg = Color.Green; - - // 0 - View - // 1 - SuperView - // 2 - Opaque - fg is Black, bg is SuperView.Bg - // 3 - Transparent - fg is darker fg, bg is darker bg - Attribute [] attributes = { Attribute.Default, new (fg, bg), new (Color.Black, bg), new (fg.GetDimmerColor (), bg.GetDimmerColor ()) }; - - var superView = new Runnable { Driver = ApplicationImpl.Instance.Driver, Height = 3, Width = 3, Text = "012ABC!@#" }; - superView.SetScheme (new Scheme (new Attribute (fg, bg))); - superView.TextFormatter.WordWrap = true; - - View view = new () { Width = Dim.Auto (), Height = Dim.Auto (), Text = "*", ShadowStyle = style }; - view.SetScheme (new Scheme (Attribute.Default)); - - superView.Add (view); - Application.Begin (superView); - Application.LayoutAndDraw (true); - DriverAssert.AssertDriverAttributesAre (expectedAttrs, output, Application.Driver, attributes); - superView.Dispose (); - Application.ResetState (true); - } - - // Visual tests - [Theory] - [InlineData (ShadowStyle.None, - """ - 01#$ - AB#$ - !@#$ - !@#$ - """)] - [InlineData (ShadowStyle.Opaque, - """ - 01▖$ - AB▌$ - ▝▀▘$ - !@#$ - """)] - [InlineData (ShadowStyle.Transparent, - """ - 01#$ - AB#$ - !@#$ - !@#$ - """)] - [SetupFakeApplication] - public void Visual_Test (ShadowStyle style, string expected) - { - Application.Driver!.SetScreenSize (5, 5); - - var superView = new Runnable { Driver = ApplicationImpl.Instance.Driver, Width = 4, Height = 4, Text = "!@#$".Repeat (4)! }; - superView.TextFormatter.WordWrap = true; - - var view = new View { Text = "01\nAB", Width = Dim.Auto (), Height = Dim.Auto () }; - view.ShadowStyle = style; - superView.Add (view); - Application.Begin (superView); - Application.LayoutAndDraw (true); - - DriverAssert.AssertDriverContentsWithFrameAre (expected, output); - superView.Dispose (); - Application.ResetState (true); - } - - [Theory] - [InlineData (ShadowStyle.None, 0, 0, 0, 0)] - [InlineData (ShadowStyle.Opaque, 1, 0, 0, 1)] - [InlineData (ShadowStyle.Transparent, 1, 0, 0, 1)] - [AutoInitShutdown] - public void ShadowStyle_LeftButtonPressed_Causes_Movement (ShadowStyle style, int expectedLeft, int expectedTop, int expectedRight, int expectedBottom) - { - var superView = new View { Height = 10, Width = 10, App = ApplicationImpl.Instance }; - - View view = new () - { - Width = Dim.Auto (), - Height = Dim.Auto (), - Text = "0123", - MouseHighlightStates = MouseState.Pressed, - ShadowStyle = style, - CanFocus = true - }; - - superView.Add (view); - superView.BeginInit (); - superView.EndInit (); - - Thickness origThickness = view.Margin!.Thickness; - view.NewMouseEvent (new Mouse { Flags = MouseFlags.LeftButtonPressed, Position = new Point (0, 0) }); - Assert.Equal (new Thickness (expectedLeft, expectedTop, expectedRight, expectedBottom), view.Margin.Thickness); - - view.NewMouseEvent (new Mouse { Flags = MouseFlags.LeftButtonReleased, Position = new Point (0, 0) }); - Assert.Equal (origThickness, view.Margin.Thickness); - - // LeftButtonPressed, LeftButtonReleased cause Application.Mouse.IsGrabbed to be set - Application.ResetState (true); - } -} diff --git a/Tests/UnitTests.Legacy/View/ArrangementTests.cs b/Tests/UnitTests.Legacy/View/ArrangementTests.cs deleted file mode 100644 index 7f28b9c561..0000000000 --- a/Tests/UnitTests.Legacy/View/ArrangementTests.cs +++ /dev/null @@ -1,215 +0,0 @@ -namespace UnitTests.ViewBaseTests; - -public class ArrangementTests (ITestOutputHelper output) -{ - private readonly ITestOutputHelper _output = output; - - [Fact] - public void MouseGrabHandler_WorksWithMovableView_UsingNewMouseEvent () - { - // This test proves that MouseGrabHandler works correctly with concurrent unit tests - // using NewMouseEvent directly on views, without requiring Application.Init - - var superView = new View - { - Width = 80, - Height = 25 - }; - superView.App = ApplicationImpl.Instance; - - var movableView = new View - { - Arrangement = ViewArrangement.Movable, - BorderStyle = LineStyle.Single, - X = 10, - Y = 10, - Width = 20, - Height = 10 - }; - - superView.Add (movableView); - - // Verify initial state - Assert.NotNull (movableView.Border); - Assert.False (Application.Mouse.IsGrabbed (movableView.Border)); - - // Simulate mouse press on the border to start dragging - var pressEvent = new Mouse - { - Position = new (1, 0), // Top border area - Flags = MouseFlags.LeftButtonPressed - }; - - bool? result = movableView.Border.NewMouseEvent (pressEvent); - - // The border should have grabbed the mouse - Assert.True (result); - Assert.True (superView.App.Mouse.IsGrabbed (movableView.Border)); - - // Simulate mouse drag - var dragEvent = new Mouse - { - Position = new (5, 2), - Flags = MouseFlags.LeftButtonPressed | MouseFlags.PositionReport - }; - - result = movableView.Border.NewMouseEvent (dragEvent); - Assert.True (result); - - // Mouse should still be grabbed - Assert.True (superView.App.Mouse.IsGrabbed (movableView.Border)); - - // Simulate mouse release to end dragging - var releaseEvent = new Mouse - { - Position = new (5, 2), - Flags = MouseFlags.LeftButtonReleased - }; - - result = movableView.Border.NewMouseEvent (releaseEvent); - Assert.True (result); - - // Mouse should be released - Assert.False (superView.App.Mouse.IsGrabbed (movableView.Border)); - } - - [Fact] - public void MouseGrabHandler_WorksWithResizableView_UsingNewMouseEvent () - { - // This test proves MouseGrabHandler works for resizing operations - - var superView = new View - { - App = ApplicationImpl.Instance, - Width = 80, - Height = 25 - }; - - var resizableView = new View - { - Arrangement = ViewArrangement.RightResizable, - BorderStyle = LineStyle.Single, - X = 10, - Y = 10, - Width = 20, - Height = 10 - }; - - superView.Add (resizableView); - - // Verify initial state - Assert.NotNull (resizableView.Border); - Assert.False (Application.Mouse.IsGrabbed (resizableView.Border)); - - // Calculate position on right border (border is at right edge) - // Border.Frame.X is relative to parent, so we use coordinates relative to the border - var pressEvent = new Mouse - { - Position = new (resizableView.Border.Frame.Width - 1, 5), // Right border area - Flags = MouseFlags.LeftButtonPressed - }; - - bool? result = resizableView.Border.NewMouseEvent (pressEvent); - - // The border should have grabbed the mouse for resizing - Assert.True (result); - Assert.True (superView.App.Mouse.IsGrabbed (resizableView.Border)); - - // Simulate dragging to resize - var dragEvent = new Mouse - { - Position = new (resizableView.Border.Frame.Width + 3, 5), - Flags = MouseFlags.LeftButtonPressed | MouseFlags.PositionReport - }; - - result = resizableView.Border.NewMouseEvent (dragEvent); - Assert.True (result); - Assert.True (superView.App.Mouse.IsGrabbed (resizableView.Border)); - - // Simulate mouse release - var releaseEvent = new Mouse - { - Position = new (resizableView.Border.Frame.Width + 3, 5), - Flags = MouseFlags.LeftButtonReleased - }; - - result = resizableView.Border.NewMouseEvent (releaseEvent); - Assert.True (result); - - // Mouse should be released - Assert.False (superView.App.Mouse.IsGrabbed (resizableView.Border)); - } - - [Fact] - public void MouseGrabHandler_ReleasesOnMultipleViews () - { - // This test verifies MouseGrabHandler properly releases when switching between views - - var superView = new View { Width = 80, Height = 25 }; - superView.App = ApplicationImpl.Instance; - - var view1 = new View - { - Arrangement = ViewArrangement.Movable, - BorderStyle = LineStyle.Single, - X = 10, - Y = 10, - Width = 15, - Height = 8 - }; - - var view2 = new View - { - Arrangement = ViewArrangement.Movable, - BorderStyle = LineStyle.Single, - X = 30, - Y = 10, - Width = 15, - Height = 8 - }; - - superView.Add (view1, view2); - superView.BeginInit (); - superView.EndInit (); - - // Grab mouse on first view - var pressEvent1 = new Mouse - { - Position = new (1, 0), - Flags = MouseFlags.LeftButtonPressed - }; - - view1.Border!.NewMouseEvent (pressEvent1); - Assert.True (superView.App.Mouse.IsGrabbed (view1.Border)); - - // Release on first view - var releaseEvent1 = new Mouse - { - Position = new (1, 0), - Flags = MouseFlags.LeftButtonReleased - }; - - view1.Border.NewMouseEvent (releaseEvent1); - Assert.False (Application.Mouse.IsGrabbed (view1.Border)); - - // Grab mouse on second view - var pressEvent2 = new Mouse - { - Position = new (1, 0), - Flags = MouseFlags.LeftButtonPressed - }; - - view2.Border!.NewMouseEvent (pressEvent2); - Assert.True (superView.App.Mouse.IsGrabbed (view2.Border)); - - // Release on second view - var releaseEvent2 = new Mouse - { - Position = new (1, 0), - Flags = MouseFlags.LeftButtonReleased - }; - - view2.Border.NewMouseEvent (releaseEvent2); - Assert.False (superView.App.Mouse.IsGrabbed (view2.Border)); - } -} diff --git a/Tests/UnitTests.Legacy/View/DiagnosticsTests.cs b/Tests/UnitTests.Legacy/View/DiagnosticsTests.cs deleted file mode 100644 index e56a09fec1..0000000000 --- a/Tests/UnitTests.Legacy/View/DiagnosticsTests.cs +++ /dev/null @@ -1,28 +0,0 @@ -#nullable enable -namespace UnitTests.ViewBaseTests; - -/// -/// Tests static property and enum. -/// -/// -[Trait ("Category", "Output")] -public class DiagnosticTests () -{ - /// - /// /// Tests static property and enum. - /// /// - /// - [Fact] - public void Diagnostics_Sets () - { - // View.Diagnostics is a static property that returns the current diagnostic flags. - Assert.Equal (ViewDiagnosticFlags.Off, View.Diagnostics); - - // View.Diagnostics can be set to a new value. - View.Diagnostics = ViewDiagnosticFlags.Thickness; - Assert.Equal (ViewDiagnosticFlags.Thickness, View.Diagnostics); - - // Ensure we turn off at the end of the test - View.Diagnostics = ViewDiagnosticFlags.Off; - } -} diff --git a/Tests/UnitTests.Legacy/View/Draw/ClipTests.cs b/Tests/UnitTests.Legacy/View/Draw/ClipTests.cs deleted file mode 100644 index 2e033ea7a9..0000000000 --- a/Tests/UnitTests.Legacy/View/Draw/ClipTests.cs +++ /dev/null @@ -1,313 +0,0 @@ -#nullable enable -using System.Text; - -namespace UnitTests.ViewBaseTests; - -[Trait ("Category", "Output")] -public class ClipTests (ITestOutputHelper _output) -{ - [Fact] - [SetupFakeApplication] - public void Move_Is_Not_Constrained_To_Viewport () - { - var view = new View - { - App = ApplicationImpl.Instance, - X = 1, - Y = 1, - Width = 3, Height = 3 - }; - view.Margin!.Thickness = new (1); - - view.Move (0, 0); - Assert.Equal (new (2, 2), new Point (Application.Driver!.Col, Application.Driver!.Row)); - - view.Move (-1, -1); - Assert.Equal (new (1, 1), new Point (Application.Driver!.Col, Application.Driver!.Row)); - - view.Move (1, 1); - Assert.Equal (new (3, 3), new Point (Application.Driver!.Col, Application.Driver!.Row)); - } - - [Fact] - [SetupFakeApplication] - public void AddRune_Is_Constrained_To_Viewport () - { - var view = new View - { - App = ApplicationImpl.Instance, - X = 1, - Y = 1, - Width = 3, Height = 3 - }; - view.Padding!.Thickness = new (1); - view.Padding.Diagnostics = ViewDiagnosticFlags.Thickness; - view.BeginInit (); - view.EndInit (); - view.Draw (); - - // Only valid location w/in Viewport is 0, 0 (view) - 2, 2 (screen) - Assert.Equal (" ", Application.Driver?.Contents! [2, 2].Grapheme); - - // When we exit Draw, the view is excluded from the clip. So drawing at 0,0, is not valid and is clipped. - view.AddRune (0, 0, Glyphs.WideGlyphReplacement); - Assert.Equal (" ", Application.Driver?.Contents! [2, 2].Grapheme); - - view.AddRune (-1, -1, Glyphs.WideGlyphReplacement); - Assert.Equal ("P", Application.Driver?.Contents! [1, 1].Grapheme); - - view.AddRune (1, 1, Glyphs.WideGlyphReplacement); - Assert.Equal ("P", Application.Driver?.Contents! [3, 3].Grapheme); - } - - [Theory] - [InlineData (0, 0, 1, 1)] - [InlineData (0, 0, 2, 2)] - [InlineData (-1, -1, 2, 2)] - [SetupFakeApplication] - public void FillRect_Fills_HonorsClip (int x, int y, int width, int height) - { - var superView = new View - { - App = ApplicationImpl.Instance, - Width = Dim.Fill (), Height = Dim.Fill () - }; - - var view = new View - { - Text = "X", - X = 1, Y = 1, - Width = 3, Height = 3, - BorderStyle = LineStyle.Single - }; - superView.Add (view); - superView.BeginInit (); - superView.EndInit (); - superView.LayoutSubViews (); - - superView.Draw (); - - DriverAssert.AssertDriverContentsWithFrameAre ( - @" - ┌─┐ - │X│ - └─┘", - _output); - - Rectangle toFill = new (x, y, width, height); - superView.SetClipToScreen (); - view.FillRect (toFill); - - DriverAssert.AssertDriverContentsWithFrameAre ( - @" - ┌─┐ - │ │ - └─┘", - _output); - - // Now try to clear beyond Viewport (invalid; clipping should prevent) - superView.SetNeedsDraw (); - superView.Draw (); - - DriverAssert.AssertDriverContentsWithFrameAre ( - @" - ┌─┐ - │X│ - └─┘", - _output); - toFill = new (-width, -height, width, height); - view.FillRect (toFill); - - DriverAssert.AssertDriverContentsWithFrameAre ( - @" - ┌─┐ - │X│ - └─┘", - _output); - - // Now try to clear beyond Viewport (valid) - superView.SetNeedsDraw (); - superView.Draw (); - - DriverAssert.AssertDriverContentsWithFrameAre ( - @" - ┌─┐ - │X│ - └─┘", - _output); - toFill = new (-1, -1, width + 1, height + 1); - - superView.SetClipToScreen (); - view.FillRect (toFill); - - DriverAssert.AssertDriverContentsWithFrameAre ( - @" - ┌─┐ - │ │ - └─┘", - _output); - - // Now clear too much size - superView.SetNeedsDraw (); - superView.Draw (); - - DriverAssert.AssertDriverContentsWithFrameAre ( - @" - ┌─┐ - │X│ - └─┘", - _output); - toFill = new (0, 0, width * 2, height * 2); - superView.SetClipToScreen (); - view.FillRect (toFill); - - DriverAssert.AssertDriverContentsWithFrameAre ( - @" - ┌─┐ - │ │ - └─┘", - _output); - } - - // TODO: Simplify this test to just use AddRune directly - [Fact] - [SetupFakeApplication] - [Trait ("Category", "Unicode")] - public void Clipping_Wide_Runes () - { - Application.Driver!.SetScreenSize (30, 1); - Application.Driver!.GetOutputBuffer ().SetWideGlyphReplacement ((Rune)'①'); - - var top = new View - { - App = ApplicationImpl.Instance, - Id = "top", - Width = Dim.Fill (), - Height = Dim.Fill () - }; - - var frameView = new View - { - Id = "frameView", - Width = Dim.Fill (), - Height = Dim.Fill (), - Text = """ - これは広いルーンラインです。 - """ - }; - frameView.Border!.LineStyle = LineStyle.Single; - frameView.Border!.Thickness = new (1, 0, 0, 0); - - top.Add (frameView); - top.SetClipToScreen (); - top.Layout (); - top.Draw (); - - var expectedOutput = """ - │これは広いルーンラインです。 - """; - - DriverAssert.AssertDriverContentsWithFrameAre (expectedOutput, _output); - - var view = new View - { - Text = "0123456789", - - //Text = "ワイドルー。", - X = 2, - Height = Dim.Auto (), - Width = Dim.Auto (), - BorderStyle = LineStyle.Single - }; - view.Border!.Thickness = new (1, 0, 1, 0); - - top.Add (view); - top.Layout (); - top.SetClipToScreen (); - top.Draw (); - - // 012345678901234567890123456789012345678 - // 012 34 56 78 90 12 34 56 78 90 12 34 56 78 - // │こ れ は 広 い ル ー ン ラ イ ン で す 。 - // 01 2345678901234 56 78 90 12 34 56 - // │① |0123456989│① ン ラ イ ン で す 。 - expectedOutput = """ - │①│0123456789│ ンラインです。 - """; - - DriverAssert.AssertDriverContentsWithFrameAre (expectedOutput, _output); - } - - // TODO: Add more AddRune tests to cover all the cases where wide runes are clipped - - [Fact] - [SetupFakeApplication] - public void SetClip_ClipVisibleContentOnly_VisibleContentIsClipped () - { - // Screen is 25x25 - // View is 25x25 - // Viewport is (0, 0, 23, 23) - // ContentSize is (10, 10) - // ViewportToScreen is (1, 1, 23, 23) - // Visible content is (1, 1, 10, 10) - // Expected clip is (1, 1, 10, 10) - same as visible content - Rectangle expectedClip = new (1, 1, 10, 10); - - // Arrange - var view = new View - { - Width = Dim.Fill (), - Height = Dim.Fill (), - ViewportSettings = ViewportSettingsFlags.ClipContentOnly, - App = ApplicationImpl.Instance - }; - view.SetContentSize (new Size (10, 10)); - view.Border!.Thickness = new (1); - view.BeginInit (); - view.EndInit (); - Assert.Equal (view.Frame, view.GetClip ()!.GetBounds ()); - - // Act - view.AddViewportToClip (); - - // Assert - Assert.Equal (expectedClip, view.GetClip ()!.GetBounds ()); - view.Dispose (); - } - - [Fact] - [SetupFakeApplication] - public void SetClip_Default_ClipsToViewport () - { - // Screen is 25x25 - Application.Driver!.SetScreenSize (25, 25); - // View is 25x25 - // Viewport is (0, 0, 23, 23) - // ContentSize is (10, 10) - // ViewportToScreen is (1, 1, 23, 23) - // Visible content is (1, 1, 10, 10) - // Expected clip is (1, 1, 23, 23) - same as Viewport - Rectangle expectedClip = new (1, 1, 23, 23); - - // Arrange - var view = new View - { - Width = Dim.Fill (), - Height = Dim.Fill (), - App = ApplicationImpl.Instance - }; - view.SetContentSize (new Size (10, 10)); - view.Border!.Thickness = new (1); - view.BeginInit (); - view.EndInit (); - Assert.Equal (view.Frame, view.GetClip ()!.GetBounds ()); - view.Viewport = view.Viewport with { X = 1, Y = 1 }; - - // Act - view.AddViewportToClip (); - - // Assert - Assert.Equal (expectedClip, view.GetClip ()!.GetBounds ()); - view.Dispose (); - } -} diff --git a/Tests/UnitTests.Legacy/View/Draw/DrawEventTests.cs b/Tests/UnitTests.Legacy/View/Draw/DrawEventTests.cs deleted file mode 100644 index c037af3d57..0000000000 --- a/Tests/UnitTests.Legacy/View/Draw/DrawEventTests.cs +++ /dev/null @@ -1,30 +0,0 @@ -#nullable enable -using UnitTests; - -namespace UnitTests.ViewBaseTests; - -[Trait ("Category", "Output")] -public class DrawEventTests -{ - [Fact] - [AutoInitShutdown] - public void DrawContentComplete_Event_Is_Always_Called () - { - var viewCalled = false; - var tvCalled = false; - - var view = new View { Width = 10, Height = 10, Text = "View" }; - view.DrawComplete += (s, e) => viewCalled = true; - var tv = new TextView { Y = 11, Width = 10, Height = 10 }; - tv.DrawComplete += (s, e) => tvCalled = true; - - var top = new Runnable (); - top.Add (view, tv); - Application.Begin (top); - AutoInitShutdownAttribute.RunIteration (); - - Assert.True (viewCalled); - Assert.True (tvCalled); - top.Dispose (); - } -} diff --git a/Tests/UnitTests.Legacy/View/Draw/DrawTests.cs b/Tests/UnitTests.Legacy/View/Draw/DrawTests.cs deleted file mode 100644 index b6be67128e..0000000000 --- a/Tests/UnitTests.Legacy/View/Draw/DrawTests.cs +++ /dev/null @@ -1,953 +0,0 @@ -#nullable enable -using System.Text; - -namespace UnitTests.ViewBaseTests; - -[Trait ("Category", "Output")] -public class DrawTests (ITestOutputHelper output) -{ - - [Fact] - [AutoInitShutdown] - [Trait ("Category", "Unicode")] - public void CJK_Compatibility_Ideographs_ConsoleWidth_ColumnWidth_Equal_Two () - { - const string s = "\U0000f900"; - var r = (Rune)0xf900; - - Assert.Equal ("豈", s); - Assert.Equal ("豈", r.ToString ()); - Assert.Equal (s, r.ToString ()); - - Assert.Equal (2, s.GetColumns ()); - Assert.Equal (2, r.GetColumns ()); - - var win = new Window { Title = s }; - var view = new View { Text = r.ToString (), Height = Dim.Fill (), Width = Dim.Fill () }; - var tf = new TextField { Text = s, Y = 1, Width = 3 }; - win.Add (view, tf); - Runnable top = new (); - top.Add (win); - - Application.Begin (top); - Application.Driver!.SetScreenSize (10, 4); - Application.LayoutAndDraw (); - - const string expectedOutput = """ - - ┌┤豈├────┐ - │豈 │ - │豈 │ - └────────┘ - """; - DriverAssert.AssertDriverContentsWithFrameAre (expectedOutput, output); - - DriverAssert.AssertDriverContentsAre (expectedOutput, output); - - // This test has nothing to do with color - removing as it is not relevant and fragile - top.Dispose (); - } - - [Fact] - [AutoInitShutdown] - [Trait ("Category", "Output")] - public void Colors_On_TextAlignment_Right_And_Bottom () - { - var viewRight = new View - { - Text = "Test", - Width = 6, - Height = 1, - TextAlignment = Alignment.End, - }; - - var viewBottom = new View - { - Text = "Test", - TextDirection = TextDirection.TopBottom_LeftRight, - Y = 1, - Width = 1, - Height = 6, - VerticalTextAlignment = Alignment.End, - }; - Runnable top = new (); - top.Add (viewRight, viewBottom); - - var rs = Application.Begin (top); - Application.Driver!.SetScreenSize (7, 7); - AutoInitShutdownAttribute.RunIteration (); - - DriverAssert.AssertDriverContentsWithFrameAre ( - """ - - Test - - - T - e - s - t - """, - output - ); - - DriverAssert.AssertDriverAttributesAre ( - """ - - 000000 - 0 - 0 - 0 - 0 - 0 - 0 - """, - output, - Application.Driver, - SchemeManager.GetSchemes () ["Base"]!.Normal - ); - top.Dispose (); - } - - [Fact] - [SetupFakeApplication] - public void Draw_Minimum_Full_Border_With_Empty_Viewport () - { - var view = new View - { - App = ApplicationImpl.Instance, - Width = 2, Height = 2, BorderStyle = LineStyle.Single - }; - Assert.True (view.NeedsLayout); - Assert.True (view.NeedsDraw); - view.Layout (); - - Assert.Equal (new (0, 0, 2, 2), view.Frame); - Assert.Equal (Rectangle.Empty, view.Viewport); - - Assert.True (view.NeedsDraw); - view.Draw (); - - DriverAssert.AssertDriverContentsWithFrameAre ( - """ - - ┌┐ - └┘ - """, - output - ); - } - - [Fact] - [SetupFakeApplication] - public void Draw_Minimum_Full_Border_With_Empty_Viewport_Without_Bottom () - { - var view = new View - { - App = ApplicationImpl.Instance, - Width = 2, Height = 1, BorderStyle = LineStyle.Single - }; - view.Border!.Thickness = new (1, 1, 1, 0); - view.BeginInit (); - view.EndInit (); - view.SetRelativeLayout (Application.Screen.Size); - - Assert.Equal (new (0, 0, 2, 1), view.Frame); - Assert.Equal (Rectangle.Empty, view.Viewport); - - view.Draw (); - - DriverAssert.AssertDriverContentsWithFrameAre ("──", output); - } - - [Fact] - [SetupFakeApplication] - public void Draw_Minimum_Full_Border_With_Empty_Viewport_Without_Left () - { - var view = new View - { - App = ApplicationImpl.Instance, - Width = 1, Height = 2, BorderStyle = LineStyle.Single - }; - view.Border!.Thickness = new (0, 1, 1, 1); - view.BeginInit (); - view.EndInit (); - view.SetRelativeLayout (Application.Screen.Size); - - Assert.Equal (new (0, 0, 1, 2), view.Frame); - Assert.Equal (Rectangle.Empty, view.Viewport); - - view.Draw (); - - DriverAssert.AssertDriverContentsWithFrameAre ( - """ - - │ - │ - """, - output - ); - } - - [Fact] - [SetupFakeApplication] - public void Draw_Minimum_Full_Border_With_Empty_Viewport_Without_Right () - { - var view = new View - { - App = ApplicationImpl.Instance, - Width = 1, Height = 2, BorderStyle = LineStyle.Single - }; - view.Border!.Thickness = new (1, 1, 0, 1); - view.BeginInit (); - view.EndInit (); - view.SetRelativeLayout (Application.Screen.Size); - - Assert.Equal (new (0, 0, 1, 2), view.Frame); - Assert.Equal (Rectangle.Empty, view.Viewport); - - view.Draw (); - - DriverAssert.AssertDriverContentsWithFrameAre ( - """ - - │ - │ - """, - output - ); - } - - [Fact] - [SetupFakeApplication] - public void Draw_Minimum_Full_Border_With_Empty_Viewport_Without_Top () - { - var view = new View - { - App = ApplicationImpl.Instance, - Width = 2, Height = 1, BorderStyle = LineStyle.Single - }; - view.Border!.Thickness = new (1, 0, 1, 1); - - view.BeginInit (); - view.EndInit (); - view.SetRelativeLayout (Application.Screen.Size); - - Assert.Equal (new (0, 0, 2, 1), view.Frame); - Assert.Equal (Rectangle.Empty, view.Viewport); - - view.Draw (); - - DriverAssert.AssertDriverContentsWithFrameAre ( - "││", - output - ); - } - - [Fact] - [AutoInitShutdown] - public void Draw_Negative_Viewport_Horizontal_With_New_Lines () - { - var subView = new View - { - Id = "subView", - X = 1, - Width = 1, - Height = 7, - Text = """ - s - u - b - V - i - e - w - """ - }; - - var view = new View - { - Id = "view", Width = 2, Height = 20, Text = """ - 0 - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 0 - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - """ - }; - view.Add (subView); - var content = new View { Id = "content", Width = 20, Height = 20 }; - content.Add (view); - - var container = new View - { - Id = "container", - X = 1, - Y = 1, - Width = 5, - Height = 5 - }; - container.Add (content); - Runnable top = new (); - top.Add (container); - var rs = Application.Begin (top); - - top.Draw (); - DriverAssert.AssertDriverContentsWithFrameAre ( - """ - - 0s - 1u - 2b - 3V - 4i - """, - output - ); - - content.X = -1; - - AutoInitShutdownAttribute.RunIteration (); - - DriverAssert.AssertDriverContentsWithFrameAre ( - """ - - s - u - b - V - i - """, - output - ); - - content.X = -2; - AutoInitShutdownAttribute.RunIteration (); - DriverAssert.AssertDriverContentsWithFrameAre (@"", output); - - content.X = 0; - content.Y = -1; - AutoInitShutdownAttribute.RunIteration (); - - DriverAssert.AssertDriverContentsWithFrameAre ( - """ - - 1u - 2b - 3V - 4i - 5e - """, - output - ); - - content.Y = -6; - AutoInitShutdownAttribute.RunIteration (); - - DriverAssert.AssertDriverContentsWithFrameAre ( - """ - - 6w - 7 - 8 - 9 - 0 - """, - output - ); - - content.Y = -19; - AutoInitShutdownAttribute.RunIteration (); - - DriverAssert.AssertDriverContentsWithFrameAre ( - """ - - 9 - """, - output - ); - - content.Y = -20; - AutoInitShutdownAttribute.RunIteration (); - DriverAssert.AssertDriverContentsWithFrameAre ("", output); - - content.X = -2; - content.Y = 0; - AutoInitShutdownAttribute.RunIteration (); - DriverAssert.AssertDriverContentsWithFrameAre ("", output); - top.Dispose (); - } - - [Fact] - [AutoInitShutdown] - public void Draw_Negative_Viewport_Horizontal_Without_New_Lines () - { - // BUGBUG: This previously assumed the default height of a View was 1. - var subView = new View - { - Id = "subView", - Y = 1, - Width = 7, - Height = 1, - Text = "subView" - }; - var view = new View { Id = "view", Width = 20, Height = 2, Text = "01234567890123456789" }; - view.Add (subView); - var content = new View { Id = "content", Width = 20, Height = 20 }; - content.Add (view); - - var container = new View - { - Id = "container", - X = 1, - Y = 1, - Width = 5, - Height = 5 - }; - container.Add (content); - Runnable top = new (); - top.Add (container); - - // BUGBUG: v2 - it's bogus to reference .Frame before BeginInit. And why is the clip being set anyway??? - - top.SubViewsLaidOut += Top_LayoutComplete; - Application.Begin (top); - - AutoInitShutdownAttribute.RunIteration (); - DriverAssert.AssertDriverContentsWithFrameAre ( - """ - - 01234 - subVi - """, - output - ); - - content.X = -1; - AutoInitShutdownAttribute.RunIteration (); - - DriverAssert.AssertDriverContentsWithFrameAre ( - """ - - 12345 - ubVie - """, - output - ); - - content.Y = -1; - AutoInitShutdownAttribute.RunIteration (); - - DriverAssert.AssertDriverContentsWithFrameAre ( - """ - - ubVie - """, - output - ); - - content.Y = -2; - AutoInitShutdownAttribute.RunIteration (); - DriverAssert.AssertDriverContentsWithFrameAre ("", output); - - content.X = -20; - content.Y = 0; - AutoInitShutdownAttribute.RunIteration (); - DriverAssert.AssertDriverContentsWithFrameAre ("", output); - top.Dispose (); - - return; - - void Top_LayoutComplete (object? sender, LayoutEventArgs e) { Application.Driver!.Clip = new (container.Frame); } - } - - [Fact] - [AutoInitShutdown] - public void Draw_Negative_Viewport_Vertical () - { - var subView = new View - { - Id = "subView", - X = 1, - Width = 1, - Height = 7, - Text = "subView", - TextDirection = TextDirection.TopBottom_LeftRight - }; - - var view = new View - { - Id = "view", - Width = 2, - Height = 20, - Text = "01234567890123456789", - TextDirection = TextDirection.TopBottom_LeftRight - }; - view.Add (subView); - var content = new View { Id = "content", Width = 20, Height = 20 }; - content.Add (view); - - var container = new View - { - Id = "container", - X = 1, - Y = 1, - Width = 5, - Height = 5 - }; - container.Add (content); - Runnable top = new (); - top.Add (container); - Application.Begin (top); - - AutoInitShutdownAttribute.RunIteration (); - DriverAssert.AssertDriverContentsWithFrameAre ( - """ - - 0s - 1u - 2b - 3V - 4i - """, - output - ); - - content.X = -1; - AutoInitShutdownAttribute.RunIteration (); - - DriverAssert.AssertDriverContentsWithFrameAre ( - """ - - s - u - b - V - i - """, - output - ); - - content.X = -2; - AutoInitShutdownAttribute.RunIteration (); - DriverAssert.AssertDriverContentsWithFrameAre (@"", output); - - content.X = 0; - content.Y = -1; - AutoInitShutdownAttribute.RunIteration (); - - DriverAssert.AssertDriverContentsWithFrameAre ( - """ - - 1u - 2b - 3V - 4i - 5e - """, - output - ); - - content.Y = -6; - AutoInitShutdownAttribute.RunIteration (); - - DriverAssert.AssertDriverContentsWithFrameAre ( - """ - - 6w - 7 - 8 - 9 - 0 - """, - output - ); - - content.Y = -19; - AutoInitShutdownAttribute.RunIteration (); - - DriverAssert.AssertDriverContentsWithFrameAre ( - """ - - 9 - """, - output - ); - - content.Y = -20; - AutoInitShutdownAttribute.RunIteration (); - DriverAssert.AssertDriverContentsWithFrameAre ("", output); - - content.X = -2; - content.Y = 0; - AutoInitShutdownAttribute.RunIteration (); - DriverAssert.AssertDriverContentsWithFrameAre ("", output); - top.Dispose (); - } - - [Theory] - [SetupFakeApplication] - [InlineData ("𝔽𝕆𝕆𝔹𝔸R")] - [InlineData ("a𐐀b")] - public void DrawHotString_NonBmp (string expected) - { - var view = new View - { - App = ApplicationImpl.Instance, - Width = 10, Height = 1 - }; - view.DrawHotString (expected, Attribute.Default, Attribute.Default); - - DriverAssert.AssertDriverContentsWithFrameAre (expected, output); - } - - // TODO: The tests below that use Label should use View instead. - [Fact] - [AutoInitShutdown] - public void Non_Bmp_ConsoleWidth_ColumnWidth_Equal_Two () - { - var us = "\U0001d539"; - var r = (Rune)0x1d539; - - Assert.Equal ("𝔹", us); - Assert.Equal ("𝔹", r.ToString ()); - Assert.Equal (us, r.ToString ()); - - Assert.Equal (1, us.GetColumns ()); - Assert.Equal (1, r.GetColumns ()); - - var win = new Window { Title = us }; - var view = new Label { Text = r.ToString () }; - var tf = new TextField { Text = us, Y = 1, Width = 3 }; - win.Add (view, tf); - Runnable top = new (); - top.Add (win); - - Application.Begin (top); - Application.Driver!.SetScreenSize (10, 4); - Application.LayoutAndDraw (); - - var expected = """ - - ┌┤𝔹├─────┐ - │𝔹 │ - │𝔹 │ - └────────┘ - """; - DriverAssert.AssertDriverContentsWithFrameAre (expected, output); - - DriverAssert.AssertDriverContentsAre (expected, output); - top.Dispose (); - - // This test has nothing to do with color - removing as it is not relevant and fragile - } - - [Fact] - [AutoInitShutdown] - public void Draw_Throws_IndexOutOfRangeException_With_Negative_Bounds () - { - Runnable top = new (); - - var view = new View { X = -2, Text = "view" }; - top.Add (view); - - Application.Iteration += OnApplicationOnIteration; - - try - { - Application.Run (top); - } - catch (IndexOutOfRangeException ex) - { - // After the fix this exception will not be caught. - Assert.IsType (ex); - } - finally - { - Application.Iteration -= OnApplicationOnIteration; - } - - top.Dispose (); - - // Shutdown must be called to safely clean up Application if Init has been called - Application.Shutdown (); - - return; - - void OnApplicationOnIteration (object? s, EventArgs a) - { - Assert.Equal (-2, view.X); - - Application.RequestStop (); - } - } - - - [Fact] - [AutoInitShutdown] - public void Correct_Redraw_Viewport_NeedDisplay_On_Shrink_And_Move_Down_Right_Using_Frame () - { - var label = new Label { Text = "At 0,0" }; - - var view = new DerivedView - { - X = 2, - Y = 2, - Width = 30, - Height = 2, - Text = "A text with some long width\n and also with two lines." - }; - Runnable top = new (); - top.Add (label, view); - SessionToken sessionToken = Application.Begin (top); - AutoInitShutdownAttribute.RunIteration (); - - DriverAssert.AssertDriverContentsWithFrameAre ( - @" -At 0,0 - - A text with some long width - and also with two lines. " - , - output - ); - - view.Frame = new (3, 3, 10, 1); - Assert.Equal (new (3, 3, 10, 1), view.Frame); - Assert.Equal (new (0, 0, 10, 1), view.Viewport); - Assert.Equal (new (0, 0, 10, 1), view.NeedsDrawRect); - //Application.Refresh(); - top.Draw (); - - DriverAssert.AssertDriverContentsWithFrameAre ( - @" -At 0,0 - - - A text wit", - output - ); - Application.End (sessionToken); - top.Dispose (); - } - - [Fact] - [AutoInitShutdown] - public void Correct_Redraw_Viewport_NeedDisplay_On_Shrink_And_Move_Down_Right_Using_Pos_Dim () - { - var label = new Label { Text = "At 0,0" }; - - var view = new DerivedView - { - X = 2, - Y = 2, - Width = 30, - Height = 2, - Text = "A text with some long width\n and also with two lines." - }; - Runnable top = new (); - top.Add (label, view); - SessionToken sessionToken = Application.Begin (top); - - top.Draw (); - - DriverAssert.AssertDriverContentsWithFrameAre ( - @" -At 0,0 - - A text with some long width - and also with two lines. " - , - output - ); - - view.X = 3; - view.Y = 3; - view.Width = 10; - view.Height = 1; - Assert.Equal (new (3, 3, 10, 1), view.Frame); - Assert.Equal (new (0, 0, 10, 1), view.Viewport); - Assert.Equal (new (0, 0, 10, 1), view.NeedsDrawRect); - view.SetClipToScreen (); - top.Draw (); - - DriverAssert.AssertDriverContentsWithFrameAre ( - @" -At 0,0 - - - A text wit" - , - output - ); - Application.End (sessionToken); - top.Dispose (); - } - - [Fact] - [AutoInitShutdown] - public void Correct_Redraw_Viewport_NeedDisplay_On_Shrink_And_Move_Up_Left_Using_Frame () - { - var label = new Label { Text = "At 0,0" }; - - var view = new DerivedView - { - X = 2, - Y = 2, - Width = 30, - Height = 2, - Text = "A text with some long width\n and also with two lines." - }; - Runnable top = new (); - top.Add (label, view); - SessionToken sessionToken = Application.Begin (top); - AutoInitShutdownAttribute.RunIteration (); - - DriverAssert.AssertDriverContentsWithFrameAre ( - @" -At 0,0 - - A text with some long width - and also with two lines. " - , - output - ); - - view.Frame = new (1, 1, 10, 1); - Assert.Equal (new (1, 1, 10, 1), view.Frame); - Assert.Equal (new (0, 0, 10, 1), view.Viewport); - Assert.Equal (new (0, 0, 10, 1), view.NeedsDrawRect); - top.Draw (); - - DriverAssert.AssertDriverContentsWithFrameAre ( - @" -At 0,0 - A text wit" - , - output - ); - Application.End (sessionToken); - top.Dispose (); - } - - [Fact] - [AutoInitShutdown] - public void Correct_Redraw_Viewport_NeedDisplay_On_Shrink_And_Move_Up_Left_Using_Pos_Dim () - { - var label = new Label { Text = "At 0,0" }; - - var view = new DerivedView - { - X = 2, - Y = 2, - Width = 30, - Height = 2, - Text = "A text with some long width\n and also with two lines." - }; - Runnable top = new (); - top.Add (label, view); - SessionToken sessionToken = Application.Begin (top); - - top.Draw (); - - DriverAssert.AssertDriverContentsWithFrameAre ( - @" -At 0,0 - - A text with some long width - and also with two lines. " - , - output - ); - - view.X = 1; - view.Y = 1; - view.Width = 10; - view.Height = 1; - Assert.Equal (new (1, 1, 10, 1), view.Frame); - Assert.Equal (new (0, 0, 10, 1), view.Viewport); - Assert.Equal (new (0, 0, 10, 1), view.NeedsDrawRect); - view.SetClipToScreen (); - - top.Draw (); - - DriverAssert.AssertDriverContentsWithFrameAre ( - @" -At 0,0 - A text wit" - , - output - ); - Application.End (sessionToken); - top.Dispose (); - } - public class DerivedView : View - { - public DerivedView () { CanFocus = true; } - public bool IsKeyDown { get; set; } - public bool IsKeyPress { get; set; } - public override string Text { get; set; } = null!; - - protected override bool OnDrawingContent (DrawContext? context) - { - var idx = 0; - - // BUGBUG: v2 - this should use Viewport, not Frame - for (var r = 0; r < Frame.Height; r++) - { - for (var c = 0; c < Frame.Width; c++) - { - if (idx < Text.Length) - { - char rune = Text [idx]; - - if (rune != '\n') - { - AddRune (c, r, (Rune)Text [idx]); - } - - idx++; - - if (rune == '\n') - { - break; - } - } - } - } - - ClearNeedsDraw (); - - return true; - } - - protected override bool OnKeyDown (Key keyEvent) - { - IsKeyDown = true; - - return true; - } - - protected override bool OnKeyDownNotHandled (Key keyEvent) - { - IsKeyPress = true; - - return true; - } - } -} diff --git a/Tests/UnitTests.Legacy/View/Draw/NeedsDrawTests.cs b/Tests/UnitTests.Legacy/View/Draw/NeedsDrawTests.cs deleted file mode 100644 index 231590f725..0000000000 --- a/Tests/UnitTests.Legacy/View/Draw/NeedsDrawTests.cs +++ /dev/null @@ -1,68 +0,0 @@ -#nullable enable -using UnitTests; - -namespace UnitTests.ViewBaseTests; - -[Trait ("Category", "Output")] -public class NeedsDrawTests () -{ - [Fact] - [AutoInitShutdown] - public void Frame_Set_After_Initialize_Update_NeededDisplay () - { - var frame = new FrameView (); - - var label = new Label - { - SchemeName = "Menu", X = 0, Y = 0, Text = "This should be the first line." - }; - - var view = new View - { - X = 0, // don't overcomplicate unit tests - Y = 1, - Height = Dim.Auto (DimAutoStyle.Text), - Width = Dim.Auto (DimAutoStyle.Text), - Text = "Press me!" - }; - - frame.Add (label, view); - - frame.X = Pos.Center (); - frame.Y = Pos.Center (); - frame.Width = 40; - frame.Height = 8; - - Runnable top = new (); - - top.Add (frame); - - SessionToken sessionToken = Application.Begin (top); - - Application.Driver!.SetScreenSize (80,25); - - top.SubViewsLaidOut += (s, e) => { Assert.Equal (new (0, 0, 80, 25), top.NeedsDrawRect); }; - - frame.SubViewsLaidOut += (s, e) => { Assert.Equal (new (0, 0, 40, 8), frame.NeedsDrawRect); }; - - label.SubViewsLaidOut += (s, e) => { Assert.Equal (new (0, 0, 38, 1), label.NeedsDrawRect); }; - - view.SubViewsLaidOut += (s, e) => { Assert.Equal (new (0, 0, 13, 1), view.NeedsDrawRect); }; - Assert.Equal (new (0, 0, 80, 25), top.Frame); - Assert.Equal (new (20, 8, 40, 8), frame.Frame); - - Assert.Equal ( - new (20, 8, 60, 16), - new Rectangle ( - frame.Frame.Left, - frame.Frame.Top, - frame.Frame.Right, - frame.Frame.Bottom - ) - ); - Assert.Equal (new (0, 0, 30, 1), label.Frame); - Assert.Equal (new (0, 1, 9, 1), view.Frame); // this proves frame was set - Application.End (sessionToken); - top.Dispose (); - } -} diff --git a/Tests/UnitTests.Legacy/View/Draw/TransparentTests.cs b/Tests/UnitTests.Legacy/View/Draw/TransparentTests.cs deleted file mode 100644 index a4929c1cf9..0000000000 --- a/Tests/UnitTests.Legacy/View/Draw/TransparentTests.cs +++ /dev/null @@ -1,107 +0,0 @@ -#nullable enable - -namespace UnitTests.ViewBaseTests; - -[Trait ("Category", "Output")] -public class TransparentTests (ITestOutputHelper output) -{ - [Fact] - [SetupFakeApplication] - - public void Transparent_Text_Occludes () - { - var super = new View - { - App = ApplicationImpl.Instance, - Id = "super", - Width = 20, - Height = 5, - }; - super.DrawingContent += (sender, args) => - { - var s = sender as View; - s!.FillRect(s!.Viewport, Glyphs.Stipple); - args.Cancel = true; - }; - - var sub = new View - { - X = 1, - Y = 1, - Width = 15, - Height = 3, - Id = "sub", - Text = "Sub", - ViewportSettings = ViewportSettingsFlags.Transparent, - BorderStyle = LineStyle.Single - }; - - super.Add (sub); - - super.Layout (); - super.Draw (); - - _ = DriverAssert.AssertDriverContentsWithFrameAre ( - @" -░░░░░░░░░░░░░░░░░░░░ -░┌─────────────┐░░░░ -░│Sub░░░░░░░░░░│░░░░ -░└─────────────┘░░░░ -░░░░░░░░░░░░░░░░░░░░", output); - } - - [Fact] - [SetupFakeApplication] - - public void Transparent_SubView_Occludes () - { - var super = new View - { - App = ApplicationImpl.Instance, - Id = "super", - Width = 20, - Height = 5, - }; - super.DrawingContent += (sender, args) => - { - var s = sender as View; - s!.FillRect (s!.Viewport, Glyphs.Stipple); - args.Cancel = true; - }; - - var sub = new View - { - X = 1, - Y = 1, - Width = 15, - Height = 3, - Id = "sub", - ViewportSettings = ViewportSettingsFlags.Transparent, - BorderStyle = LineStyle.Single - }; - - var subSub = new View - { - X = Pos.Center(), - Y = Pos.Center(), - Width = Dim.Auto(), - Height = Dim.Auto(), - Id = "subSub", - Text = "subSub", - }; - sub.Add (subSub); - - super.Add (sub); - - super.Layout (); - super.Draw (); - - _ = DriverAssert.AssertDriverContentsWithFrameAre ( - @" -░░░░░░░░░░░░░░░░░░░░ -░┌─────────────┐░░░░ -░│░░░subSub░░░░│░░░░ -░└─────────────┘░░░░ -░░░░░░░░░░░░░░░░░░░░", output); - } -} diff --git a/Tests/UnitTests.Legacy/View/Layout/Dim.Tests.cs b/Tests/UnitTests.Legacy/View/Layout/Dim.Tests.cs deleted file mode 100644 index d25e37e247..0000000000 --- a/Tests/UnitTests.Legacy/View/Layout/Dim.Tests.cs +++ /dev/null @@ -1,223 +0,0 @@ -using System.Globalization; -using System.Text; -using static Terminal.Gui.ViewBase.Dim; - -namespace UnitTests.LayoutTests; - -public class DimTests -{ - private readonly ITestOutputHelper _output; - - public DimTests (ITestOutputHelper output) - { - _output = output; - Console.OutputEncoding = Encoding.Default; - - // Change current culture - var culture = CultureInfo.CreateSpecificCulture ("en-US"); - Thread.CurrentThread.CurrentCulture = culture; - Thread.CurrentThread.CurrentUICulture = culture; - } - - - // TODO: This actually a SetRelativeLayout/LayoutSubViews test and should be moved - // TODO: A new test that calls SetRelativeLayout directly is needed. - [Fact (Skip = "Convoluted test; rewrite")] - [AutoInitShutdown] - public void Only_DimAbsolute_And_DimFactor_As_A_Different_Procedure_For_Assigning_Value_To_Width_Or_Height () - { - // Override CM - Button.DefaultShadow = ShadowStyle.None; - - // Testing with the Button because it properly handles the Dim class. - Runnable t = new (); - - var w = new Window { Width = 100, Height = 100 }; - - var f1 = new FrameView - { - X = 0, - Y = 0, - Width = Percent (50), - Height = 5, - Title = "f1" - }; - - var f2 = new FrameView - { - X = Pos.Right (f1), - Y = 0, - Width = Fill (), - Height = 5, - Title = "f2" - }; - - var v1 = new Button - { - X = Pos.X (f1) + 2, - Y = Pos.Bottom (f1) + 2, - Width = Width (f1) - 2, - Height = Fill () - 2, - ValidatePosDim = true, - Text = "v1" - }; - - var v2 = new Button - { - X = Pos.X (f2) + 2, - Y = Pos.Bottom (f2) + 2, - Width = Width (f2) - 2, - Height = Fill () - 2, - ValidatePosDim = true, - Text = "v2" - }; - - var v3 = new Button - { - Width = Percent (10), - Height = Percent (10), - ValidatePosDim = true, - Text = "v3" - }; - - var v4 = new Button - { - Width = Absolute (50), - Height = Absolute (50), - ValidatePosDim = true, - Text = "v4" - }; - - var v5 = new Button - { - Width = Width (v1) - Width (v3), - Height = Height (v1) - Height (v3), - ValidatePosDim = true, - Text = "v5" - }; - - var v6 = new Button - { - X = Pos.X (f2), - Y = Pos.Bottom (f2) + 2, - Width = Percent (20, DimPercentMode.Position), - Height = Percent (20, DimPercentMode.Position), - ValidatePosDim = true, - Text = "v6" - }; - - w.Add (f1, f2, v1, v2, v3, v4, v5, v6); - t.Add (w); - - t.IsModalChanged += (s, e) => - { - Assert.Equal ("Absolute(100)", w.Width.ToString ()); - Assert.Equal ("Absolute(100)", w.Height.ToString ()); - Assert.Equal (100, w.Frame.Width); - Assert.Equal (100, w.Frame.Height); - - Assert.Equal ("Absolute(5)", f1.Height.ToString ()); - Assert.Equal (49, f1.Frame.Width); // 50-1=49 - Assert.Equal (5, f1.Frame.Height); - - Assert.Equal ("Fill(Absolute(0))", f2.Width.ToString ()); - Assert.Equal ("Absolute(5)", f2.Height.ToString ()); - Assert.Equal (49, f2.Frame.Width); // 50-1=49 - Assert.Equal (5, f2.Frame.Height); - - Assert.Equal ($"Combine(View(Width,FrameView(){f1.Border!.Frame})-Absolute(2))", v1.Width.ToString ()); - Assert.Equal ("Combine(Fill(Absolute(0))-Absolute(2))", v1.Height.ToString ()); - Assert.Equal (47, v1.Frame.Width); // 49-2=47 - Assert.Equal (89, v1.Frame.Height); // 98-5-2-2=89 - - Assert.Equal ( - $"Combine(View(Width,FrameView(){f2.Frame})-Absolute(2))", - v2.Width.ToString () - ); - Assert.Equal ("Combine(Fill(Absolute(0))-Absolute(2))", v2.Height.ToString ()); - Assert.Equal (47, v2.Frame.Width); // 49-2=47 - Assert.Equal (89, v2.Frame.Height); // 98-5-2-2=89 - - Assert.Equal (9, v3.Frame.Width); // 98*10%=9 - Assert.Equal (9, v3.Frame.Height); // 98*10%=9 - - Assert.Equal ("Absolute(50)", v4.Width.ToString ()); - Assert.Equal ("Absolute(50)", v4.Height.ToString ()); - Assert.Equal (50, v4.Frame.Width); - Assert.Equal (50, v4.Frame.Height); - Assert.Equal ($"Combine(View(Height,Button(){v1.Frame})-View(Height,Button(){v3.Viewport}))", v5.Height.ToString ( )); - Assert.Equal (38, v5.Frame.Width); // 47-9=38 - Assert.Equal (80, v5.Frame.Height); // 89-9=80 - - Assert.Equal (9, v6.Frame.Width); // 47*20%=9 - Assert.Equal (18, v6.Frame.Height); // 89*20%=18 - - w.Width = 200; - Assert.True (t.NeedsLayout); - w.Height = 200; - t.LayoutSubViews (); - - Assert.Equal ("Absolute(200)", w.Width.ToString ()); - Assert.Equal ("Absolute(200)", w.Height.ToString ()); - Assert.Equal (200, w.Frame.Width); - Assert.Equal (200, w.Frame.Height); - - f1.Text = "Frame1"; - Assert.Equal (99, f1.Frame.Width); // 100-1=99 - Assert.Equal (5, f1.Frame.Height); - - f2.Text = "Frame2"; - Assert.Equal ("Fill(Absolute(0))", f2.Width.ToString ()); - Assert.Equal ("Absolute(5)", f2.Height.ToString ()); - Assert.Equal (99, f2.Frame.Width); // 100-1=99 - Assert.Equal (5, f2.Frame.Height); - - v1.Text = "LeftButton"; - Assert.Equal ($"Combine(View(Width,FrameView(){f1.Frame})-Absolute(2))", v1.Width.ToString ()); - Assert.Equal ("Combine(Fill(Absolute(0))-Absolute(2))", v1.Height.ToString ()); - Assert.Equal (97, v1.Frame.Width); // 99-2=97 - Assert.Equal (189, v1.Frame.Height); // 198-2-7=189 - - v2.Text = "MiddleButton"; - - Assert.Equal ($"Combine(View(Width,FrameView(){f2.Frame})-Absolute(2))", v2.Width.ToString ()); - Assert.Equal ("Combine(Fill(Absolute(0))-Absolute(2))", v2.Height.ToString ()); - Assert.Equal (97, v2.Frame.Width); // 99-2=97 - Assert.Equal (189, v2.Frame.Height); // 198-2-7=189 - - v3.Text = "RightButton"; - - // 198*10%=19 * Percent is related to the super-view if it isn't null otherwise the view width - Assert.Equal (19, v3.Frame.Width); - - // 199*10%=19 - Assert.Equal (19, v3.Frame.Height); - - v4.Text = "Button4"; - v4.Width = Auto (DimAutoStyle.Text); - v4.Height = Auto (DimAutoStyle.Text); - v4.Layout (); - Assert.Equal (Auto (DimAutoStyle.Text), v4.Width); - Assert.Equal (Auto (DimAutoStyle.Text), v4.Height); - Assert.Equal (11, v4.Frame.Width); // 11 is the text length and because is DimAbsolute - Assert.Equal (1, v4.Frame.Height); // 1 because is DimAbsolute - - v5.Text = "Button5"; - - Assert.Equal ($"Combine(View(Width,Button(){v1.Frame})-View(Width,Button(){v3.Frame}))", v5.Width.ToString ()); - Assert.Equal ($"Combine(View(Height,Button(){v1.Frame})-View(Height,Button(){v3.Frame}))", v5.Height.ToString ()); - - Assert.Equal (78, v5.Frame.Width); // 97-9=78 - Assert.Equal (170, v5.Frame.Height); // 189-19=170 - - v6.Text = "Button6"; - Assert.Equal (19, v6.Frame.Width); // 99*20%=19 - Assert.Equal (38, v6.Frame.Height); // 198-7*20=18 - }; - - Application.StopAfterFirstIteration = true; - - Application.Run (t); - t.Dispose (); - } -} diff --git a/Tests/UnitTests.Legacy/View/Layout/Pos.Tests.cs b/Tests/UnitTests.Legacy/View/Layout/Pos.Tests.cs deleted file mode 100644 index 76d8bb00a6..0000000000 --- a/Tests/UnitTests.Legacy/View/Layout/Pos.Tests.cs +++ /dev/null @@ -1,250 +0,0 @@ -#nullable enable - -namespace UnitTests.LayoutTests; - -public class PosTests () -{ - [Fact] - public void - Pos_Validation_Do_Not_Throws_If_NewValue_Is_PosAbsolute_And_OldValue_Is_Another_Type_After_Sets_To_LayoutStyle_Absolute () - { - Application.Init (DriverRegistry.Names.ANSI); - - Runnable t = new (); - - var w = new Window { X = Pos.Left (t) + 2, Y = Pos.Absolute (2) }; - - var v = new View { X = Pos.Center (), Y = Pos.Percent (10) }; - - w.Add (v); - t.Add (w); - - t.IsModalChanged += (s, e) => - { - v.Frame = new Rectangle (2, 2, 10, 10); - Assert.Equal (2, v.X = 2); - Assert.Equal (2, v.Y = 2); - }; - - Application.StopAfterFirstIteration = true; - - Application.Run (t); - t.Dispose (); - Application.Shutdown (); - } - - - // TODO: This actually a SetRelativeLayout/LayoutSubViews test and should be moved - // TODO: A new test that calls SetRelativeLayout directly is needed. - [Fact] - public void PosCombine_WHY_Throws () - { - Application.Init (DriverRegistry.Names.ANSI); - - Runnable t = new Runnable (); - - var w = new Window { X = Pos.Left (t) + 2, Y = Pos.Top (t) + 2 }; - var f = new FrameView (); - var v1 = new View { X = Pos.Left (w) + 2, Y = Pos.Top (w) + 2 }; - var v2 = new View { X = Pos.Left (v1) + 2, Y = Pos.Top (v1) + 2 }; - - f.Add (v1); // v2 not added - w.Add (f); - t.Add (w); - - f.X = Pos.X (v2) - Pos.X (v1); - f.Y = Pos.Y (v2) - Pos.Y (v1); - - Assert.Throws (() => Application.Run (t)); - t.Dispose (); - Application.Shutdown (); - - v2.Dispose (); - } - - - // TODO: This actually a SetRelativeLayout/LayoutSubViews test and should be moved - // TODO: A new test that calls SetRelativeLayout directly is needed. - [Fact] - [SetupFakeApplication] - public void Pos_Add_Operator () - { - Runnable top = new (); - - var view = new View { X = 0, Y = 0, Width = 20, Height = 20 }; - var field = new TextField { X = 0, Y = 0, Width = 20 }; - var count = 0; - - field.KeyDown += (s, k) => - { - if (k.KeyCode == KeyCode.Enter) - { - field.Text = $"View {count}"; - var view2 = new View { X = 0, Y = field.Y, Width = 20, Text = field.Text }; - view.Add (view2); - Assert.Equal ($"View {count}", view2.Text); - Assert.Equal ($"Absolute({count})", view2.Y.ToString ()); - - Assert.Equal ($"Absolute({count})", field.Y.ToString ()); - field.Y += 1; - count++; - Assert.Equal ($"Absolute({count})", field.Y.ToString ()); - } - }; - - Application.Iteration += OnInstanceOnIteration; - - var win = new Window (); - win.Add (view); - win.Add (field); - - top.Add (win); - - Application.Run (top); - Application.Iteration -= OnInstanceOnIteration; - - Assert.Equal (20, count); - - top.Dispose (); - - // Shutdown must be called to safely clean up Application if Init has been called - Application.Shutdown (); - - return; - - void OnInstanceOnIteration (object? s, EventArgs a) - { - while (count < 20) - { - field.NewKeyDownEvent (Key.Enter); - } - - Application.RequestStop (); - } - } - - // TODO: This actually a SetRelativeLayout/LayoutSubViews test and should be moved - // TODO: A new test that calls SetRelativeLayout directly is needed. - [Fact] - public void Pos_Subtract_Operator () - { - Application.Init (DriverRegistry.Names.ANSI); - - Runnable top = new (); - - var view = new View { X = 0, Y = 0, Width = 20, Height = 20 }; - var field = new TextField { X = 0, Y = 0, Width = 20 }; - var count = 20; - List listViews = new (); - - for (var i = 0; i < count; i++) - { - field.Text = $"View {i}"; - var view2 = new View { X = 0, Y = field.Y, Width = 20, Text = field.Text }; - view.Add (view2); - Assert.Equal ($"View {i}", view2.Text); - Assert.Equal ($"Absolute({i})", field.Y.ToString ()); - listViews.Add (view2); - - Assert.Equal ($"Absolute({i})", field.Y.ToString ()); - field.Y += 1; - Assert.Equal ($"Absolute({i + 1})", field.Y.ToString ()); - } - - field.KeyDown += (s, k) => - { - if (k.KeyCode == KeyCode.Enter) - { - Assert.Equal ($"View {count - 1}", listViews [count - 1].Text); - view.Remove (listViews [count - 1]); - listViews [count - 1].Dispose (); - - Assert.Equal ($"Absolute({count})", field.Y.ToString ()); - field.Y -= 1; - count--; - Assert.Equal ($"Absolute({count})", field.Y.ToString ()); - } - }; - - Application.Iteration += OnApplicationOnIteration; - - var win = new Window (); - win.Add (view); - win.Add (field); - - top.Add (win); - - Application.Run (top); - Application.Iteration -= OnApplicationOnIteration; - - Assert.Equal (0, count); - - top.Dispose (); - - // Shutdown must be called to safely clean up Application if Init has been called - Application.Shutdown (); - - return; - - void OnApplicationOnIteration (object? s, EventArgs a) - { - while (count > 0) - { - field.NewKeyDownEvent (Key.Enter); - } - - Application.RequestStop (); - } - } - - // TODO: This actually a SetRelativeLayout/LayoutSubViews test and should be moved - // TODO: A new test that calls SetRelativeLayout directly is needed. - [Fact] - public void Pos_Validation_Do_Not_Throws_If_NewValue_Is_PosAbsolute_And_OldValue_Is_Null () - { - Application.Init (DriverRegistry.Names.ANSI); - - Runnable t = new (); - - var w = new Window { X = 1, Y = 2, Width = 3, Height = 5 }; - t.Add (w); - - t.IsModalChanged += (s, e) => - { - Assert.Equal (2, w.X = 2); - Assert.Equal (2, w.Y = 2); - }; - - Application.StopAfterFirstIteration = true; - - Application.Run (t); - t.Dispose (); - Application.Shutdown (); - } - - - // TODO: This actually a SetRelativeLayout/LayoutSubViews test and should be moved - // TODO: A new test that calls SetRelativeLayout directly is needed. - [Fact] - public void Validation_Does_Not_Throw_If_NewValue_Is_PosAbsolute_And_OldValue_Is_Null () - { - Application.Init (DriverRegistry.Names.ANSI); - - Runnable t = new Runnable (); - - var w = new Window { X = 1, Y = 2, Width = 3, Height = 5 }; - t.Add (w); - - t.IsModalChanged += (s, e) => - { - Assert.Equal (2, w.X = 2); - Assert.Equal (2, w.Y = 2); - }; - - Application.StopAfterFirstIteration = true; - - Application.Run (t); - t.Dispose (); - Application.Shutdown (); - } -} diff --git a/Tests/UnitTests.Legacy/View/Layout/Pos.ViewTests.cs b/Tests/UnitTests.Legacy/View/Layout/Pos.ViewTests.cs deleted file mode 100644 index 43b66d7542..0000000000 --- a/Tests/UnitTests.Legacy/View/Layout/Pos.ViewTests.cs +++ /dev/null @@ -1,80 +0,0 @@ -#nullable enable - -namespace UnitTests.LayoutTests; - -public class PosViewTests (ITestOutputHelper output) -{ - private readonly ITestOutputHelper _output = output; - - // TODO: This actually a SetRelativeLayout/LayoutSubViews test and should be moved - // TODO: A new test that calls SetRelativeLayout directly is needed. - [Fact] - [SetupFakeApplication] - public void Subtract_Operator () - { - var top = new Runnable (); - - var view = new View { X = 0, Y = 0, Width = 20, Height = 20 }; - var field = new TextField { X = 0, Y = 0, Width = 20 }; - var count = 20; - List listViews = new (); - - for (var i = 0; i < count; i++) - { - field.Text = $"View {i}"; - var view2 = new View { X = 0, Y = field.Y, Width = 20, Text = field.Text }; - view.Add (view2); - Assert.Equal ($"View {i}", view2.Text); - Assert.Equal ($"Absolute({i})", field.Y.ToString ()); - listViews.Add (view2); - - Assert.Equal ($"Absolute({i})", field.Y.ToString ()); - field.Y += 1; - Assert.Equal ($"Absolute({i + 1})", field.Y.ToString ()); - } - - field.KeyDown += (s, k) => - { - if (k.KeyCode == KeyCode.Enter) - { - Assert.Equal ($"View {count - 1}", listViews [count - 1].Text); - view.Remove (listViews [count - 1]); - listViews [count - 1].Dispose (); - - Assert.Equal ($"Absolute({count})", field.Y.ToString ()); - field.Y -= 1; - count--; - Assert.Equal ($"Absolute({count})", field.Y.ToString ()); - } - }; - - Application.Iteration += OnApplicationOnIteration; - - var win = new Window (); - win.Add (view); - win.Add (field); - - top.Add (win); - - Application.Run (top); - Application.Iteration -= OnApplicationOnIteration; - - top.Dispose (); - Assert.Equal (0, count); - - // Shutdown must be called to safely clean up Application if Init has been called - Application.Shutdown (); - - return; - - void OnApplicationOnIteration (object? s, EventArgs a) - { - while (count > 0) - { - field.NewKeyDownEvent (new (KeyCode.Enter)); - } - - Application.RequestStop (); - } - } -} diff --git a/Tests/UnitTests.Legacy/View/Mouse/MouseTests.cs b/Tests/UnitTests.Legacy/View/Mouse/MouseTests.cs deleted file mode 100644 index 0acea9a0e3..0000000000 --- a/Tests/UnitTests.Legacy/View/Mouse/MouseTests.cs +++ /dev/null @@ -1,629 +0,0 @@ -using Timeout = Terminal.Gui.App.Timeout; - -namespace UnitTests.ViewBaseTests.MouseTests; - -[Trait ("Category", "Input")] -public class MouseTests : TestsAllViews -{ - // TODO: Add more tests that ensure the above test works with positive adornments - - // Test drag to move - [Theory] - [InlineData (0, 0, 0, 0, false)] - [InlineData (0, 0, 0, 4, false)] - [InlineData (1, 0, 0, 4, false)] - [InlineData (0, 1, 0, 4, true)] - [InlineData (0, 0, 1, 4, false)] - [InlineData (1, 1, 0, 3, false)] - [InlineData (1, 1, 0, 4, false)] - [InlineData (1, 1, 0, 5, true)] - [InlineData (1, 1, 0, 6, false)] - [InlineData (1, 1, 0, 11, false)] - [InlineData (1, 1, 0, 12, true)] - [InlineData (1, 1, 0, 13, false)] - [InlineData (1, 1, 0, 14, false)] - [AutoInitShutdown] - public void ButtonPressed_In_Border_Starts_Drag (int marginThickness, int borderThickness, int paddingThickness, int xy, bool expectedMoved) - { - View testView = new () - { - CanFocus = true, - X = 4, - Y = 4, - Width = 10, - Height = 10, - Arrangement = ViewArrangement.Movable - }; - testView.Margin!.Thickness = new (marginThickness); - testView.Border!.Thickness = new (borderThickness); - testView.Padding!.Thickness = new (paddingThickness); - - Runnable top = new (); - top.Add (testView); - - SessionToken rs = Application.Begin (top); - Assert.Equal (4, testView.Frame.X); - - Assert.Equal (new (4, 4), testView.Frame.Location); - Application.RaiseMouseEvent (new () { ScreenPosition = new (xy, xy), Flags = MouseFlags.LeftButtonPressed }); - - Application.RaiseMouseEvent (new () { ScreenPosition = new (xy + 1, xy + 1), Flags = MouseFlags.LeftButtonPressed | MouseFlags.PositionReport }); - AutoInitShutdownAttribute.RunIteration (); - Assert.Equal (expectedMoved, new Point (5, 5) == testView.Frame.Location); - // The above grabbed the mouse. Need to ungrab. - Application.Mouse.UngrabMouse (); - - top.Dispose (); - } - - [Theory] - [InlineData (MouseFlags.LeftButtonPressed, MouseFlags.LeftButtonReleased, MouseFlags.LeftButtonClicked)] - [InlineData (MouseFlags.MiddleButtonPressed, MouseFlags.MiddleButtonReleased, MouseFlags.MiddleButtonClicked)] - [InlineData (MouseFlags.RightButtonPressed, MouseFlags.RightButtonReleased, MouseFlags.RightButtonClicked)] - [InlineData (MouseFlags.Button4Pressed, MouseFlags.Button4Released, MouseFlags.Button4Clicked)] - public void MouseHoldRepeat_False_Button_Press_Release_DoesNotClick (MouseFlags pressed, MouseFlags released, MouseFlags clicked) - { - Mouse me = new (); - - View view = new () - { - Width = 1, - Height = 1, - MouseHoldRepeat = null - }; - - var clickedCount = 0; - - view.MouseEvent += (s, e) => clickedCount += e.IsSingleDoubleOrTripleClicked ? 1 : 0; - - me.Flags = pressed; - view.NewMouseEvent (me); - Assert.Equal (0, clickedCount); - me.Handled = false; - - me.Flags = pressed; - view.NewMouseEvent (me); - Assert.Equal (0, clickedCount); - me.Handled = false; - - me.Flags = released; - view.NewMouseEvent (me); - Assert.Equal (0, clickedCount); - me.Handled = false; - - me.Flags = clicked; - view.NewMouseEvent (me); - Assert.Equal (1, clickedCount); - - view.Dispose (); - - // LeftButtonPressed, LeftButtonReleased cause Application.Mouse.IsGrabbed to be set - Application.ResetState (true); - } - - [Theory] - [InlineData (MouseFlags.LeftButtonPressed, MouseFlags.LeftButtonReleased)] - [InlineData (MouseFlags.MiddleButtonPressed, MouseFlags.MiddleButtonReleased)] - [InlineData (MouseFlags.RightButtonPressed, MouseFlags.RightButtonReleased)] - [InlineData (MouseFlags.Button4Pressed, MouseFlags.Button4Released)] - public void MouseHoldRepeat_True_And_MousePositionTracking_True_Button_Press_Release_Clicks (MouseFlags pressed, MouseFlags released) - { - Mouse me = new (); - - View view = new () - { - Width = 1, - Height = 1, - MouseHoldRepeat = MouseFlags.LeftButtonReleased, - MousePositionTracking = true - }; - - // Setup components for mouse held down - TimedEvents timed = new (); - ApplicationMouse grab = new (); - view.MouseHoldRepeater = new MouseHoldRepeaterImpl (view, timed, grab); - - // Register callback for what to do when the mouse is held down - var clickedCount = 0; - view.MouseHoldRepeater.MouseIsHeldDownTick += (_, _) => clickedCount++; - - // Mouse is currently not held down so should be no timers running - Assert.Empty (timed.Timeouts); - - // When mouse is held down - me.Flags = pressed; - view.NewMouseEvent (me); - Assert.Equal (0, clickedCount); - me.Handled = false; - - // A timer should begin - KeyValuePair t = Assert.Single (timed.Timeouts); - - // Invoke the timer - t.Value.Callback.Invoke (); - - // Event should have been raised - Assert.Equal (1, clickedCount); - Assert.NotEmpty (timed.Timeouts); - - // When mouse is released - me.Flags = released; - view.NewMouseEvent (me); - - // timer should stop - Assert.Empty (timed.Timeouts); - Assert.Equal (1, clickedCount); - - view.Dispose (); - } - - [Theory] - [InlineData (MouseFlags.LeftButtonPressed, MouseFlags.LeftButtonReleased, MouseFlags.LeftButtonClicked)] - [InlineData (MouseFlags.MiddleButtonPressed, MouseFlags.MiddleButtonReleased, MouseFlags.MiddleButtonClicked)] - [InlineData (MouseFlags.RightButtonPressed, MouseFlags.RightButtonReleased, MouseFlags.RightButtonClicked)] - [InlineData (MouseFlags.Button4Pressed, MouseFlags.Button4Released, MouseFlags.Button4Clicked)] - public void MouseHoldRepeat_True_And_MousePositionTracking_True_Button_Press_Release_Clicks_Repeatedly ( - MouseFlags pressed, - MouseFlags released, - MouseFlags clicked - ) - { - Mouse me = new (); - - View view = new () - { - Width = 1, - Height = 1, - MouseHoldRepeat = MouseFlags.LeftButtonReleased, - MousePositionTracking = true - }; - - // Setup components for mouse held down - TimedEvents timed = new (); - ApplicationMouse grab = new (); - view.MouseHoldRepeater = new MouseHoldRepeaterImpl (view, timed, grab); - - // Register callback for what to do when the mouse is held down - var clickedCount = 0; - view.MouseHoldRepeater.MouseIsHeldDownTick += (_, _) => clickedCount++; - - Assert.Empty (timed.Timeouts); - - me.Flags = pressed; - view.NewMouseEvent (me); - Assert.Equal (0, clickedCount); - me.Handled = false; - - Assert.NotEmpty (timed.Timeouts); - Assert.Single (timed.Timeouts).Value.Callback.Invoke (); - - me.Flags = pressed; - view.NewMouseEvent (me); - Assert.Equal (1, clickedCount); - me.Handled = false; - - Assert.NotEmpty (timed.Timeouts); - - me.Flags = released; - view.NewMouseEvent (me); - Assert.Equal (1, clickedCount); - me.Handled = false; - - Assert.Empty (timed.Timeouts); - - me.Flags = clicked; - view.NewMouseEvent (me); - Assert.Equal (1, clickedCount); - - view.Dispose (); - } - - [Fact] - public void MouseHoldRepeat_True_And_MousePositionTracking_True_Move_InViewport_OutOfViewport_Keeps_Counting () - { - Mouse mouse = new () - { - Position = Point.Empty - }; - - View view = new () - { - Width = 1, - Height = 1, - MouseHoldRepeat = MouseFlags.LeftButtonReleased, - MousePositionTracking = true - }; - - // Setup components for mouse held down - TimedEvents timed = new (); - ApplicationMouse grab = new (); - view.MouseHoldRepeater = new MouseHoldRepeaterImpl (view, timed, grab); - - // Register callback for what to do when the mouse is held down - var clickedCount = 0; - view.MouseHoldRepeater.MouseIsHeldDownTick += (_, _) => clickedCount++; - - // Start in Viewport - mouse.Flags = MouseFlags.LeftButtonPressed; - mouse.Position = mouse.Position!.Value with { X = 0 }; - view.NewMouseEvent (mouse); - Assert.Equal (0, clickedCount); - mouse.Handled = false; - - // Mouse is held down so timer should be ticking - Assert.NotEmpty (timed.Timeouts); - Assert.Equal (0, clickedCount); - - // Don't wait, just force it to expire - Assert.Single (timed.Timeouts).Value.Callback.Invoke (); - Assert.Equal (1, clickedCount); - - // Move out of Viewport - mouse.Flags = MouseFlags.LeftButtonPressed; - mouse.Position = mouse.Position!.Value with { X = 1 }; - view.NewMouseEvent (mouse); - - Assert.Single (timed.Timeouts).Value.Callback.Invoke (); - Assert.Equal (2, clickedCount); - - mouse.Handled = false; - - // Move into Viewport - mouse.Flags = MouseFlags.LeftButtonPressed; - mouse.Position = mouse.Position!.Value with { X = 0 }; - view.NewMouseEvent (mouse); - - Assert.NotEmpty (timed.Timeouts); - Assert.Equal (2, clickedCount); - mouse.Handled = false; - - // Stay in Viewport - mouse.Flags = MouseFlags.LeftButtonPressed; - mouse.Position = mouse.Position!.Value with { X = 0 }; - view.NewMouseEvent (mouse); - - Assert.Single (timed.Timeouts).Value.Callback.Invoke (); - - Assert.Equal (3, clickedCount); - mouse.Handled = false; - - view.Dispose (); - } - - //[Theory] - //[InlineData (true, MouseState.None, 0, 0, 0, 0)] - //[InlineData (true, MouseState.In, 0, 0, 0, 0)] - //[InlineData (true, MouseState.Pressed, 0, 0, 1, 0)] - //[InlineData (true, MouseState.PressedOutside, 0, 0, 0, 1)] - //public void MouseState_LeftButton_Pressed_Then_Released_Outside (bool inViewport, MouseState highlightFlags, int noneCount, int expectedInCount, int expectedPressedCount, int expectedPressedOutsideCount) - //{ - // MouseEventTestView testView = new () - // { - // MouseHighlightStates = highlightFlags - // }; - - // Assert.Equal (0, testView.MouseStateInCount); - // Assert.Equal (0, testView.MouseStatePressedCount); - // Assert.Equal (0, testView.MouseStatePressedOutsideCount); - // Assert.Equal (0, testView.MouseStateNoneCount); - - // testView.NewMouseEvent (new () { Flags = MouseFlags.LeftButtonPressed, Position = new (inViewport ? 0 : 1, 0) }); - // Assert.Equal (expectedInCount, testView.MouseStateInCount); - // Assert.Equal (expectedPressedCount, testView.MouseStatePressedCount); - // Assert.Equal (expectedPressedOutsideCount, testView.MouseStatePressedOutsideCount); - // Assert.Equal (noneCount, testView.MouseStateNoneCount); - - // testView.NewMouseEvent (new () { Flags = MouseFlags.LeftButtonReleased, Position = new (inViewport ? 0 : 1, 0) }); - // Assert.Equal (expectedInCount, testView.MouseStateInCount); - // Assert.Equal (expectedPressedCount, testView.MouseStatePressedCount); - // Assert.Equal (expectedPressedOutsideCount, testView.MouseStatePressedOutsideCount); - // Assert.Equal (noneCount, testView.MouseStateNoneCount); - - // testView.Dispose (); - - // // LeftButtonPressed, LeftButtonReleased cause Application.Mouse.IsGrabbed to be set - // Application.ResetState (true); - - //} - - // TODO: Add tests for each combination of HighlightFlags - - [Theory] - [InlineData (0)] - [InlineData (1)] - [InlineData (10)] - public void MouseState_None_LeftButton_Pressed_Move_No_Changes (int x) - { - MouseEventTestView testView = new () - { - MouseHighlightStates = MouseState.None - }; - - bool inViewport = testView.Viewport.Contains (x, 0); - - // Start at 0,0 ; in viewport - testView.NewMouseEvent (new () { Flags = MouseFlags.LeftButtonPressed }); - Assert.Equal (0, testView.MouseStateInCount); - Assert.Equal (0, testView.MouseStatePressedCount); - Assert.Equal (0, testView.MouseStatePressedOutsideCount); - Assert.Equal (0, testView.MouseStateNoneCount); - - // Move to x,0 - testView.NewMouseEvent (new () { Flags = MouseFlags.LeftButtonPressed, Position = new (x, 0) }); - - if (inViewport) - { - Assert.Equal (0, testView.MouseStateInCount); - Assert.Equal (0, testView.MouseStatePressedCount); - Assert.Equal (0, testView.MouseStatePressedOutsideCount); - Assert.Equal (0, testView.MouseStateNoneCount); - } - else - { - Assert.Equal (0, testView.MouseStateInCount); - Assert.Equal (0, testView.MouseStatePressedCount); - Assert.Equal (0, testView.MouseStatePressedOutsideCount); - Assert.Equal (0, testView.MouseStateNoneCount); - } - - // Move back to 0,0 ; in viewport - testView.NewMouseEvent (new () { Flags = MouseFlags.LeftButtonPressed }); - - if (inViewport) - { - Assert.Equal (0, testView.MouseStateInCount); - Assert.Equal (0, testView.MouseStatePressedCount); - Assert.Equal (0, testView.MouseStatePressedOutsideCount); - Assert.Equal (0, testView.MouseStateNoneCount); - } - else - { - Assert.Equal (0, testView.MouseStateInCount); - Assert.Equal (0, testView.MouseStatePressedCount); - Assert.Equal (0, testView.MouseStatePressedOutsideCount); - Assert.Equal (0, testView.MouseStateNoneCount); - } - - testView.Dispose (); - - // LeftButtonPressed, LeftButtonReleased cause Application.Mouse.IsGrabbed to be set - Application.ResetState (true); - } - - [Theory] - [InlineData (0)] - [InlineData (1)] - [InlineData (10)] - public void MouseState_Pressed_LeftButton_Pressed_Move_Keeps_Pressed (int x) - { - MouseEventTestView testView = new () - { - MouseHighlightStates = MouseState.Pressed - }; - - bool inViewport = testView.Viewport.Contains (x, 0); - - // Start at 0,0 ; in viewport - testView.NewMouseEvent (new () { Flags = MouseFlags.LeftButtonPressed }); - Assert.Equal (0, testView.MouseStateInCount); - Assert.Equal (1, testView.MouseStatePressedCount); - Assert.Equal (0, testView.MouseStatePressedOutsideCount); - Assert.Equal (0, testView.MouseStateNoneCount); - - // Move to x,0 - testView.NewMouseEvent (new () { Flags = MouseFlags.LeftButtonPressed, Position = new (x, 0) }); - - if (inViewport) - { - Assert.Equal (0, testView.MouseStateInCount); - Assert.Equal (1, testView.MouseStatePressedCount); - Assert.Equal (0, testView.MouseStatePressedOutsideCount); - Assert.Equal (0, testView.MouseStateNoneCount); - } - else - { - Assert.Equal (0, testView.MouseStateInCount); - Assert.Equal (1, testView.MouseStatePressedCount); - Assert.Equal (0, testView.MouseStatePressedOutsideCount); - Assert.Equal (0, testView.MouseStateNoneCount); - } - - // Move backto 0,0 ; in viewport - testView.NewMouseEvent (new () { Flags = MouseFlags.LeftButtonPressed }); - - if (inViewport) - { - Assert.Equal (0, testView.MouseStateInCount); - Assert.Equal (1, testView.MouseStatePressedCount); - Assert.Equal (0, testView.MouseStatePressedOutsideCount); - Assert.Equal (0, testView.MouseStateNoneCount); - } - else - { - Assert.Equal (0, testView.MouseStateInCount); - Assert.Equal (1, testView.MouseStatePressedCount); - Assert.Equal (0, testView.MouseStatePressedOutsideCount); - Assert.Equal (0, testView.MouseStateNoneCount); - } - - testView.Dispose (); - - // LeftButtonPressed, LeftButtonReleased cause Application.Mouse.IsGrabbed to be set - Application.ResetState (true); - } - - [Theory] - [InlineData (0)] - [InlineData (1)] - [InlineData (10)] - public void MouseState_PressedOutside_LeftButton_Pressed_Move_Raises_PressedOutside (int x) - { - MouseEventTestView testView = new () - { - MouseHighlightStates = MouseState.PressedOutside, - MouseHoldRepeat = null - }; - - bool inViewport = testView.Viewport.Contains (x, 0); - - // Start at 0,0 ; in viewport - testView.NewMouseEvent (new () { Flags = MouseFlags.LeftButtonPressed }); - Assert.Equal (0, testView.MouseStateInCount); - Assert.Equal (0, testView.MouseStatePressedCount); - Assert.Equal (0, testView.MouseStatePressedOutsideCount); - Assert.Equal (0, testView.MouseStateNoneCount); - - // Move to x,0 - testView.NewMouseEvent (new () { Flags = MouseFlags.LeftButtonPressed, Position = new (x, 0) }); - - if (inViewport) - { - Assert.Equal (0, testView.MouseStateInCount); - Assert.Equal (0, testView.MouseStatePressedCount); - Assert.Equal (0, testView.MouseStatePressedOutsideCount); - Assert.Equal (0, testView.MouseStateNoneCount); - } - else - { - Assert.Equal (0, testView.MouseStateInCount); - Assert.Equal (0, testView.MouseStatePressedCount); - Assert.Equal (1, testView.MouseStatePressedOutsideCount); - Assert.Equal (0, testView.MouseStateNoneCount); - } - - // Move backto 0,0 ; in viewport - testView.NewMouseEvent (new () { Flags = MouseFlags.LeftButtonPressed }); - - if (inViewport) - { - Assert.Equal (0, testView.MouseStateInCount); - Assert.Equal (0, testView.MouseStatePressedCount); - Assert.Equal (0, testView.MouseStatePressedOutsideCount); - Assert.Equal (0, testView.MouseStateNoneCount); - } - else - { - Assert.Equal (0, testView.MouseStateInCount); - Assert.Equal (0, testView.MouseStatePressedCount); - Assert.Equal (1, testView.MouseStatePressedOutsideCount); - Assert.Equal (1, testView.MouseStateNoneCount); - } - - testView.Dispose (); - - // LeftButtonPressed, LeftButtonReleased cause Application.Mouse.IsGrabbed to be set - Application.ResetState (true); - } - - [Theory] - [InlineData (0)] - [InlineData (1)] - [InlineData (10)] - public void MouseState_PressedOutside_LeftButton_Pressed_Move_Raises_PressedOutside_MouseHoldRepeat (int x) - { - MouseEventTestView testView = new () - { - MouseHighlightStates = MouseState.PressedOutside, - MouseHoldRepeat = MouseFlags.LeftButtonReleased - }; - - bool inViewport = testView.Viewport.Contains (x, 0); - - // Start at 0,0 ; in viewport - testView.NewMouseEvent (new () { Flags = MouseFlags.LeftButtonPressed }); - Assert.Equal (0, testView.MouseStateInCount); - Assert.Equal (0, testView.MouseStatePressedCount); - Assert.Equal (0, testView.MouseStatePressedOutsideCount); - Assert.Equal (0, testView.MouseStateNoneCount); - - // Move to x,0 - testView.NewMouseEvent (new () { Flags = MouseFlags.LeftButtonPressed, Position = new (x, 0) }); - - if (inViewport) - { - Assert.Equal (0, testView.MouseStateInCount); - Assert.Equal (0, testView.MouseStatePressedCount); - Assert.Equal (0, testView.MouseStatePressedOutsideCount); - Assert.Equal (0, testView.MouseStateNoneCount); - } - else - { - Assert.Equal (0, testView.MouseStateInCount); - Assert.Equal (0, testView.MouseStatePressedCount); - Assert.Equal (0, testView.MouseStatePressedOutsideCount); - Assert.Equal (0, testView.MouseStateNoneCount); - } - - // Move backto 0,0 ; in viewport - testView.NewMouseEvent (new () { Flags = MouseFlags.LeftButtonPressed }); - - if (inViewport) - { - Assert.Equal (0, testView.MouseStateInCount); - Assert.Equal (0, testView.MouseStatePressedCount); - Assert.Equal (0, testView.MouseStatePressedOutsideCount); - Assert.Equal (0, testView.MouseStateNoneCount); - } - else - { - Assert.Equal (0, testView.MouseStateInCount); - Assert.Equal (0, testView.MouseStatePressedCount); - Assert.Equal (0, testView.MouseStatePressedOutsideCount); - Assert.Equal (0, testView.MouseStateNoneCount); - } - - testView.Dispose (); - - // LeftButtonPressed, LeftButtonReleased cause Application.Mouse.IsGrabbed to be set - Application.ResetState (true); - } - - private class MouseEventTestView : View - { - public int MouseEnterCount { get; private set; } - public int MouseLeaveCount { get; private set; } - public int MouseStatePressedOutsideCount { get; private set; } - public int MouseStateInCount { get; private set; } - public int MouseStatePressedCount { get; private set; } - public int MouseStateNoneCount { get; private set; } - - public MouseEventTestView () - { - Height = 1; - Width = 1; - CanFocus = true; - Id = "mouseEventTestView"; - - MouseLeave += (s, e) => { MouseEnterCount++; }; - MouseEnter += (s, e) => { MouseLeaveCount++; }; - } - - /// - protected override void OnMouseStateChanged (EventArgs args) - { - switch (args.Value) - { - case MouseState.None: - MouseStateNoneCount++; - - break; - case MouseState.In: - MouseStateInCount++; - - break; - - case MouseState.Pressed: - MouseStatePressedCount++; - - break; - - case MouseState.PressedOutside: - MouseStatePressedOutsideCount++; - - break; - } - - base.OnMouseStateChanged (args); - } - } -} diff --git a/Tests/UnitTests.Legacy/View/Navigation/EnabledTests.cs b/Tests/UnitTests.Legacy/View/Navigation/EnabledTests.cs deleted file mode 100644 index 6524b196cd..0000000000 --- a/Tests/UnitTests.Legacy/View/Navigation/EnabledTests.cs +++ /dev/null @@ -1,75 +0,0 @@ -#nullable enable -namespace UnitTests.ViewBaseTests; - -public class EnabledTests -{ - - [Fact] - [AutoInitShutdown] - public void _Enabled_Sets_Also_Sets_SubViews () - { - var wasClicked = false; - var button = new Button { Text = "Click Me" }; - button.IsDefault = true; - button.Accepting += (s, e) => wasClicked = !wasClicked; - var win = new Window { Width = Dim.Fill (), Height = Dim.Fill () }; - win.Add (button); - var top = new Runnable (); - top.Add (win); - - var iterations = 0; - - Application.Iteration += OnApplicationOnIteration; - - Application.Run (top); - Application.Iteration -= OnApplicationOnIteration; - - Assert.Equal (1, iterations); - top.Dispose (); - - return; - - void OnApplicationOnIteration (object? s, EventArgs a) - { - iterations++; - - win.NewKeyDownEvent (Key.Enter); - Assert.True (wasClicked); - button.NewMouseEvent (new () { Flags = MouseFlags.LeftButtonClicked }); - Assert.False (wasClicked); - Assert.True (button.Enabled); - Assert.True (button.CanFocus); - Assert.True (button.HasFocus); - Assert.True (win.Enabled); - Assert.True (win.CanFocus); - Assert.True (win.HasFocus); - - Assert.True (button.HasFocus); - win.Enabled = false; - Assert.False (button.HasFocus); - button.NewKeyDownEvent (Key.Enter); - Assert.False (wasClicked); - button.NewMouseEvent (new () { Flags = MouseFlags.LeftButtonClicked }); - Assert.False (wasClicked); - Assert.False (button.Enabled); - Assert.True (button.CanFocus); - Assert.False (button.HasFocus); - Assert.False (win.Enabled); - Assert.True (win.CanFocus); - Assert.False (win.HasFocus); - button.SetFocus (); - Assert.False (button.HasFocus); - Assert.False (win.HasFocus); - win.SetFocus (); - Assert.False (button.HasFocus); - Assert.False (win.HasFocus); - - win.Enabled = true; - win.FocusDeepest (NavigationDirection.Forward, null); - Assert.True (button.HasFocus); - Assert.True (win.HasFocus); - - Application.RequestStop (); - } - } -} diff --git a/Tests/UnitTests.Legacy/View/SchemeTests.cs b/Tests/UnitTests.Legacy/View/SchemeTests.cs deleted file mode 100644 index 9660a853b6..0000000000 --- a/Tests/UnitTests.Legacy/View/SchemeTests.cs +++ /dev/null @@ -1,22 +0,0 @@ -using Xunit; - -namespace UnitTests.ViewBaseTests; - -[Trait ("Category", "View.Scheme")] -public class SchemeTests -{ - [Fact] - [UnitTests.AutoInitShutdown] - public void View_Resolves_Attributes_From_Scheme () - { - View view = new Label { SchemeName = "Base" }; - - foreach (VisualRole role in Enum.GetValues ()) - { - Attribute attr = view.GetAttributeForRole (role); - Assert.NotEqual (default, attr.Foreground); // Defensive: avoid all-defaults - } - - view.Dispose (); - } -} diff --git a/Tests/UnitTests.Legacy/View/SubviewTests.cs b/Tests/UnitTests.Legacy/View/SubviewTests.cs deleted file mode 100644 index 42f31baacb..0000000000 --- a/Tests/UnitTests.Legacy/View/SubviewTests.cs +++ /dev/null @@ -1,105 +0,0 @@ -namespace UnitTests.ViewBaseTests; - -public class SubViewTests -{ - //private readonly ITestOutputHelper _output; - //public SubViewTests (ITestOutputHelper output) { _output = output; } - - //// TODO: This is a poor unit tests. Not clear what it's testing. Refactor. - //[Fact] - //[AutoInitShutdown] - //public void Initialized_Event_Will_Be_Invoked_When_Added_Dynamically () - //{ - // var t = new Runnable { Id = "0" }; - - // var w = new Window { Id = "t", Width = Dim.Fill (), Height = Dim.Fill () }; - // var v1 = new View { Id = "v1", Width = Dim.Fill (), Height = Dim.Fill () }; - // var v2 = new View { Id = "v2", Width = Dim.Fill (), Height = Dim.Fill () }; - - // int tc = 0, wc = 0, v1c = 0, v2c = 0, sv1c = 0; - - // t.Initialized += (s, e) => - // { - // tc++; - // Assert.Equal (1, tc); - // Assert.Equal (1, wc); - // Assert.Equal (1, v1c); - // Assert.Equal (1, v2c); - // Assert.Equal (0, sv1c); // Added after t in the Application.Iteration. - - // Assert.True (t.CanFocus); - // Assert.True (w.CanFocus); - // Assert.False (v1.CanFocus); - // Assert.False (v2.CanFocus); - - // Application.LayoutAndDraw (); - // }; - - // w.Initialized += (s, e) => - // { - // wc++; - // Assert.Equal (t.Viewport.Width, w.Frame.Width); - // Assert.Equal (t.Viewport.Height, w.Frame.Height); - // }; - - // v1.Initialized += (s, e) => - // { - // v1c++; - - // //Assert.Equal (t.Viewport.Width, v1.Frame.Width); - // //Assert.Equal (t.Viewport.Height, v1.Frame.Height); - // }; - - // v2.Initialized += (s, e) => - // { - // v2c++; - - // //Assert.Equal (t.Viewport.Width, v2.Frame.Width); - // //Assert.Equal (t.Viewport.Height, v2.Frame.Height); - // }; - // w.Add (v1, v2); - // t.Add (w); - - // Application.Iteration += OnApplicationOnIteration; - - // Application.Run (t); - // Application.Iteration -= OnApplicationOnIteration; - - // t.Dispose (); - // Application.Shutdown (); - - // Assert.Equal (1, tc); - // Assert.Equal (1, wc); - // Assert.Equal (1, v1c); - // Assert.Equal (1, v2c); - // Assert.Equal (1, sv1c); - - // Assert.True (t.CanFocus); - // Assert.True (w.CanFocus); - // Assert.False (v1.CanFocus); - // Assert.False (v2.CanFocus); - - // return; - - // void OnApplicationOnIteration (object s, EventArgs a) - // { - // var sv1 = new View { Id = "sv1", Width = Dim.Fill (), Height = Dim.Fill () }; - - // sv1.Initialized += (s, e) => - // { - // sv1c++; - // Assert.NotEqual (t.Frame.Width, sv1.Frame.Width); - // Assert.NotEqual (t.Frame.Height, sv1.Frame.Height); - // Assert.False (sv1.CanFocus); - - // //Assert.Throws (() => sv1.CanFocus = true); - // Assert.False (sv1.CanFocus); - // }; - - // v1.Add (sv1); - - // Application.LayoutAndDraw (); - // t.Running = false; - // } - //} -} diff --git a/Tests/UnitTests.Legacy/View/TextTests.cs b/Tests/UnitTests.Legacy/View/TextTests.cs deleted file mode 100644 index 696cde8e3a..0000000000 --- a/Tests/UnitTests.Legacy/View/TextTests.cs +++ /dev/null @@ -1,1142 +0,0 @@ -using System.Text; - -namespace UnitTests.ViewBaseTests; - -/// -/// Tests of the and properties. -/// -public class TextTests (ITestOutputHelper output) -{ - [Fact] - [SetupFakeApplication] - public void Setting_With_Height_Horizontal () - { - var top = new View { Width = 25, Height = 25 }; - top.App = ApplicationImpl.Instance; - - var label = new Label { Text = "Hello", /* Width = 10, Height = 2, */ ValidatePosDim = true }; - var viewX = new View { Text = "X", X = Pos.Right (label), Width = 1, Height = 1 }; - var viewY = new View { Text = "Y", Y = Pos.Bottom (label), Width = 1, Height = 1 }; - - top.Add (label, viewX, viewY); - top.Layout (); - - Assert.Equal (new (0, 0, 5, 1), label.Frame); - - top.LayoutSubViews (); - top.Draw (); - - var expected = @" -HelloX -Y -"; - - Rectangle pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); - - label.Width = 10; - label.Height = 2; - - Assert.Equal (new (0, 0, 10, 2), label.Frame); - - top.LayoutSubViews (); - top.SetClipToScreen (); - top.Draw (); - - expected = @" -Hello X - -Y -"; - - pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); - } - - [Fact] - [AutoInitShutdown] - public void Setting_With_Height_Vertical () - { - // BUGBUG: Label is Width = Dim.Auto (), Height = Dim.Auto (), so Width & Height are ignored - var label = new Label - { /*Width = 2, Height = 10, */ - TextDirection = TextDirection.TopBottom_LeftRight, ValidatePosDim = true - }; - var viewX = new View { Text = "X", X = Pos.Right (label), Width = 1, Height = 1 }; - var viewY = new View { Text = "Y", Y = Pos.Bottom (label), Width = 1, Height = 1 }; - - var top = new Runnable (); - top.Add (label, viewX, viewY); - SessionToken rs = Application.Begin (top); - - label.Text = "Hello"; - AutoInitShutdownAttribute.RunIteration (); - - Assert.Equal (new (0, 0, 1, 5), label.Frame); - - var expected = @" -HX -e -l -l -o -Y -"; - - Rectangle pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); - - label.Width = 2; - label.Height = 10; - AutoInitShutdownAttribute.RunIteration (); - - Assert.Equal (new (0, 0, 2, 10), label.Frame); - - expected = @" -H X -e -l -l -o - - - - - -Y -" - ; - - pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); - Application.End (rs); - top.Dispose (); - } - - [Fact] - [AutoInitShutdown] - public void TextDirection_Toggle () - { - var win = new Window { Width = Dim.Fill (), Height = Dim.Fill () }; - - var view = new View (); - win.Add (view); - var top = new Runnable (); - top.Add (win); - - SessionToken rs = Application.Begin (top); - Application.Driver!.SetScreenSize (15, 15); - Application.LayoutAndDraw (); - - Assert.Equal (new (0, 0, 15, 15), win.Frame); - Assert.Equal (new (0, 0, 15, 15), win.Margin!.Frame); - Assert.Equal (new (0, 0, 15, 15), win.Border!.Frame); - Assert.Equal (new (1, 1, 13, 13), win.Padding.Frame); - - Assert.Equal (TextDirection.LeftRight_TopBottom, view.TextDirection); - Assert.Equal (Rectangle.Empty, view.Frame); - Assert.Equal ("Absolute(0)", view.X.ToString ()); - Assert.Equal ("Absolute(0)", view.Y.ToString ()); - Assert.Equal ("Absolute(0)", view.Width.ToString ()); - Assert.Equal ("Absolute(0)", view.Height.ToString ()); - - var expected = @" -┌─────────────┐ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -└─────────────┘ -"; - - Rectangle pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); - - view.Text = "Hello World"; - view.Width = 11; - view.Height = 1; - AutoInitShutdownAttribute.RunIteration (); - Assert.Equal (new (0, 0, 11, 1), view.Frame); - Assert.Equal ("Absolute(0)", view.X.ToString ()); - Assert.Equal ("Absolute(0)", view.Y.ToString ()); - Assert.Equal ("Absolute(11)", view.Width.ToString ()); - Assert.Equal ("Absolute(1)", view.Height.ToString ()); - - expected = @" -┌─────────────┐ -│Hello World │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -└─────────────┘ -"; - - pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); - - view.Width = Dim.Auto (); - view.Height = Dim.Auto (); - view.Text = "Hello Worlds"; - AutoInitShutdownAttribute.RunIteration (); - int len = "Hello Worlds".Length; - Assert.Equal (12, len); - Assert.Equal (new (0, 0, len, 1), view.Frame); - - expected = @" -┌─────────────┐ -│Hello Worlds │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -└─────────────┘ -"; - - pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); - - view.TextDirection = TextDirection.TopBottom_LeftRight; - AutoInitShutdownAttribute.RunIteration (); - Assert.Equal (new (0, 0, 1, 12), view.Frame); - Assert.Equal (new (0, 0, 1, 12), view.Frame); - - expected = @" -┌─────────────┐ -│H │ -│e │ -│l │ -│l │ -│o │ -│ │ -│W │ -│o │ -│r │ -│l │ -│d │ -│s │ -│ │ -└─────────────┘ -"; - - pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); - - // Setting to false causes Width and Height to be set to the current ContentSize - view.Width = 1; - view.Height = 12; - AutoInitShutdownAttribute.RunIteration (); - Assert.Equal (new (0, 0, 1, 12), view.Frame); - - view.Width = 12; - view.Height = 1; - view.TextFormatter.ConstrainToSize = new (12, 1); - AutoInitShutdownAttribute.RunIteration (); - Assert.Equal (new (12, 1), view.TextFormatter.ConstrainToSize); - Assert.Equal (new (0, 0, 12, 1), view.Frame); - - top.ClearViewport (); - view.SetNeedsDraw (); - view.Draw (); - expected = @" HelloWorlds"; - DriverAssert.AssertDriverContentsWithFrameAre (expected, output); - - AutoInitShutdownAttribute.RunIteration (); - - // TextDirection.TopBottom_LeftRight - Height of 1 and Width of 12 means - // that the text will be spread "vertically" across 1 line. - // Hence no space. - expected = @" -┌─────────────┐ -│HelloWorlds │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -└─────────────┘ -"; - - pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); - - view.PreserveTrailingSpaces = true; - AutoInitShutdownAttribute.RunIteration (); - - Assert.Equal (new (0, 0, 12, 1), view.Frame); - - expected = @" -┌─────────────┐ -│Hello Worlds │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -└─────────────┘ -"; - - pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); - - view.PreserveTrailingSpaces = false; - Rectangle f = view.Frame; - view.Width = f.Height; - view.Height = f.Width; - view.TextDirection = TextDirection.TopBottom_LeftRight; - AutoInitShutdownAttribute.RunIteration (); - - Assert.Equal (new (0, 0, 1, 12), view.Frame); - - expected = @" -┌─────────────┐ -│H │ -│e │ -│l │ -│l │ -│o │ -│ │ -│W │ -│o │ -│r │ -│l │ -│d │ -│s │ -│ │ -└─────────────┘ -"; - - pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); - - view.Width = Dim.Auto (); - view.Height = Dim.Auto (); - - AutoInitShutdownAttribute.RunIteration (); - - Assert.Equal (new (0, 0, 1, 12), view.Frame); - - expected = @" -┌─────────────┐ -│H │ -│e │ -│l │ -│l │ -│o │ -│ │ -│W │ -│o │ -│r │ -│l │ -│d │ -│s │ -│ │ -└─────────────┘ -"; - - pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); - Application.End (rs); - top.Dispose (); - } - - [Fact] - [AutoInitShutdown] - public void View_IsEmpty_False_Minimum_Width () - { - var text = "Views"; - - var view = new View - { - TextDirection = TextDirection.TopBottom_LeftRight, - Height = Dim.Fill () - text.Length, - Text = text - }; - view.Width = Dim.Auto (); - view.Height = Dim.Auto (); - - var win = new Window { Width = Dim.Fill (), Height = Dim.Fill () }; - win.Add (view); - var top = new Runnable (); - top.Add (win); - SessionToken rs = Application.Begin (top); - Application.Driver!.SetScreenSize (4, 10); - Application.LayoutAndDraw (); - - Assert.Equal (5, text.Length); - - Assert.Equal (new (0, 0, 1, 5), view.Frame); - Assert.Equal (new (1, 5), view.TextFormatter.ConstrainToSize); - Assert.Equal (new () { "Views" }, view.TextFormatter.GetLines ()); - Assert.Equal (new (0, 0, 4, 10), win.Frame); - Assert.Equal (new (0, 0, 4, 10), Application.TopRunnableView.Frame); - - var expected = @" -┌──┐ -│V │ -│i │ -│e │ -│w │ -│s │ -│ │ -│ │ -│ │ -└──┘ -"; - - Rectangle pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); - Assert.Equal (new (0, 0, 4, 10), pos); - - text = "0123456789"; - Assert.Equal (10, text.Length); - - //view.Height = Dim.Fill () - text.Length; - AutoInitShutdownAttribute.RunIteration (); - - Assert.Equal (new (0, 0, 1, 5), view.Frame); - Assert.Equal (new (1, 5), view.TextFormatter.ConstrainToSize); - Exception exception = Record.Exception (() => Assert.Single (view.TextFormatter.GetLines ())); - Assert.Null (exception); - - expected = @" -┌──┐ -│V │ -│i │ -│e │ -│w │ -│s │ -│ │ -│ │ -│ │ -└──┘ -"; - - pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); - Assert.Equal (new (0, 0, 4, 10), pos); - top.Dispose (); - } - - [Fact] - [SetupFakeApplication] - public void DimAuto_Vertical_TextDirection_Wide_Rune () - { - var text = "界View"; - - var view = new View - { - App = ApplicationImpl.Instance, - TextDirection = TextDirection.TopBottom_LeftRight, - Text = text, - Width = Dim.Auto (), - Height = Dim.Auto () - }; - - view.SetRelativeLayout (new (4, 10)); - - Assert.Equal (5, text.Length); - - // Vertical text - 2 wide, 5 down - Assert.Equal (new (0, 0, 2, 5), view.Frame); - Assert.Equal (new (2, 5), view.TextFormatter.ConstrainToSize); - Assert.Equal (new () { "界View" }, view.TextFormatter.GetLines ()); - - view.Draw (); - - var expected = @" -界 -V -i -e -w "; - - Rectangle pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); - } - - [Fact] - [AutoInitShutdown] - public void Width_Height_SetMinWidthHeight_Narrow_Wide_Runes () - { - var text = $"0123456789{Environment.NewLine}01234567891"; - - var horizontalView = new View - { - Width = Dim.Auto (), - Height = Dim.Auto (), - Text = text - }; - - var verticalView = new View - { - Width = Dim.Auto (), - Height = Dim.Auto (), - Y = 3, - - //Height = 11, - //Width = 2, - Text = text, - TextDirection = TextDirection.TopBottom_LeftRight - }; - - var win = new Window - { - Width = Dim.Fill (), - Height = Dim.Fill (), - Text = "Window" - }; - win.Add (horizontalView, verticalView); - var top = new Runnable (); - top.Add (win); - SessionToken rs = Application.Begin (top); - Application.Driver!.SetScreenSize (20, 20); - Application.LayoutAndDraw (); - - Assert.Equal (new (0, 0, 11, 2), horizontalView.Frame); - Assert.Equal (new (0, 3, 2, 11), verticalView.Frame); - - var expected = @" -┌──────────────────┐ -│0123456789 │ -│01234567891 │ -│ │ -│00 │ -│11 │ -│22 │ -│33 │ -│44 │ -│55 │ -│66 │ -│77 │ -│88 │ -│99 │ -│ 1 │ -│ │ -│ │ -│ │ -│ │ -└──────────────────┘ -"; - - Rectangle pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); - - verticalView.Text = $"最初の行{Environment.NewLine}二行目"; - AutoInitShutdownAttribute.RunIteration (); - Assert.Equal (new (0, 3, 4, 4), verticalView.Frame); - - expected = @" -┌──────────────────┐ -│0123456789 │ -│01234567891 │ -│ │ -│最二 │ -│初行 │ -│の目 │ -│行 │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -└──────────────────┘ -"; - - pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); - Application.End (rs); - top.Dispose (); - } - - [Fact] - [AutoInitShutdown] - public void Width_Height_Stay_True_If_TextFormatter_Size_Fit () - { - var text = "Finish 終"; - - var horizontalView = new View - { - Id = "horizontalView", - Width = Dim.Auto (), Height = Dim.Auto (), Text = text - }; - - var verticalView = new View - { - Id = "verticalView", - Y = 3, - Width = Dim.Auto (), - Height = Dim.Auto (), - Text = text, - TextDirection = TextDirection.TopBottom_LeftRight - }; - var win = new Window { Id = "win", Width = Dim.Fill (), Height = Dim.Fill (), Text = "Window" }; - win.Add (horizontalView, verticalView); - var top = new Runnable (); - top.Add (win); - SessionToken rs = Application.Begin (top); - Application.Driver!.SetScreenSize (22, 22); - Application.LayoutAndDraw (); - - Assert.Equal (new (text.GetColumns (), 1), horizontalView.TextFormatter.ConstrainToSize); - Assert.Equal (new (2, 8), verticalView.TextFormatter.ConstrainToSize); - - //Assert.Equal (new (0, 0, 10, 1), horizontalView.Frame); - //Assert.Equal (new (0, 3, 10, 9), verticalView.Frame); - - var expected = @" -┌────────────────────┐ -│Finish 終 │ -│ │ -│ │ -│F │ -│i │ -│n │ -│i │ -│s │ -│h │ -│ │ -│終 │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -└────────────────────┘ -"; - - Rectangle pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); - - verticalView.Text = "最初の行二行目"; - AutoInitShutdownAttribute.RunIteration (); - - // height was initialized with 8 and can only grow or keep initial value - Assert.Equal (new (0, 3, 2, 7), verticalView.Frame); - - expected = @" -┌────────────────────┐ -│Finish 終 │ -│ │ -│ │ -│最 │ -│初 │ -│の │ -│行 │ -│二 │ -│行 │ -│目 │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -└────────────────────┘ -"; - - pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); - Application.End (rs); - top.Dispose (); - } - - [Fact] - [AutoInitShutdown] - public void Excess_Text_Is_Erased_When_The_Width_Is_Reduced () - { - var lbl = new Label { Text = "123" }; - var top = new Runnable (); - top.Add (lbl); - SessionToken rs = Application.Begin (top); - AutoInitShutdownAttribute.RunIteration (); - - Assert.Equal (new (0, 0, 3, 1), lbl.Frame); - - Assert.Equal ("123 ", GetContents ()); - - lbl.Text = "12"; - lbl.Layout (); - - Assert.Equal (new (0, 0, 2, 1), lbl.Frame); - Assert.Equal (new (0, 0, 2, 1), lbl.NeedsDrawRect); - Assert.Equal (new (0, 0, 80, 25), lbl.SuperView.NeedsDrawRect); - Assert.True (lbl.SuperView.NeedsLayout); - AutoInitShutdownAttribute.RunIteration (); - - Assert.Equal ("12 ", GetContents ()); - - string GetContents () - { - var sb = new StringBuilder (); - - for (var i = 0; i < 4; i++) - { - sb.Append (Application.Driver?.Contents! [0, i].Grapheme); - } - - return sb.ToString (); - } - - Application.End (rs); - top.Dispose (); - } - - [Theory] - [AutoInitShutdown] - [InlineData (true)] - [InlineData (false)] - public void View_Draw_Horizontal_Simple_TextAlignments (bool autoSize) - { - var text = "Hello World"; - var width = 20; - - var lblLeft = new View - { - Text = text, - Width = width, - Height = 1 - }; - - if (autoSize) - { - lblLeft.Width = Dim.Auto (); - lblLeft.Height = Dim.Auto (); - } - - var lblCenter = new View - { - Text = text, - Y = 1, - Width = width, - Height = 1, - TextAlignment = Alignment.Center - }; - - if (autoSize) - { - lblCenter.Width = Dim.Auto (); - lblCenter.Height = Dim.Auto (); - } - - var lblRight = new View - { - Text = text, - Y = 2, - Width = width, - Height = 1, - TextAlignment = Alignment.End - }; - - if (autoSize) - { - lblRight.Width = Dim.Auto (); - lblRight.Height = Dim.Auto (); - } - - var lblJust = new View - { - Text = text, - Y = 3, - Width = width, - Height = 1, - TextAlignment = Alignment.Fill - }; - - if (autoSize) - { - lblJust.Width = Dim.Auto (); - lblJust.Height = Dim.Auto (); - } - - var frame = new FrameView { Width = Dim.Fill (), Height = Dim.Fill (), BorderStyle = LineStyle.Single }; - frame.Add (lblLeft, lblCenter, lblRight, lblJust); - var top = new Runnable (); - top.Add (frame); - Application.Begin (top); - Application.Driver!.SetScreenSize (width + 2, 6); - Application.LayoutAndDraw (); - - // frame.Width is width + border wide (20 + 2) and 6 high - - if (autoSize) - { - Size expectedSize = new (11, 1); - Assert.Equal (expectedSize, lblLeft.TextFormatter.ConstrainToSize); - Assert.Equal (expectedSize, lblCenter.TextFormatter.ConstrainToSize); - Assert.Equal (expectedSize, lblRight.TextFormatter.ConstrainToSize); - Assert.Equal (expectedSize, lblJust.TextFormatter.ConstrainToSize); - } - else - { - Size expectedSize = new (width, 1); - Assert.Equal (expectedSize, lblLeft.TextFormatter.ConstrainToSize); - Assert.Equal (expectedSize, lblCenter.TextFormatter.ConstrainToSize); - Assert.Equal (expectedSize, lblRight.TextFormatter.ConstrainToSize); - Assert.Equal (expectedSize, lblJust.TextFormatter.ConstrainToSize); - } - - Assert.Equal (new (0, 0, width + 2, 6), frame.Frame); - - string expected; - - if (autoSize) - { - expected = @" -┌────────────────────┐ -│Hello World │ -│Hello World │ -│Hello World │ -│Hello World │ -└────────────────────┘ -"; - } - else - { - expected = @" -┌────────────────────┐ -│Hello World │ -│ Hello World │ -│ Hello World│ -│Hello World│ -└────────────────────┘ -"; - } - - Rectangle pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); - Assert.Equal (new (0, 0, width + 2, 6), pos); - top.Dispose (); - } - - [Theory] - [AutoInitShutdown] - [InlineData (true)] - [InlineData (false)] - public void View_Draw_Vertical_Simple_TextAlignments (bool autoSize) - { - var text = "Hello World"; - var height = 20; - - var lblLeft = new View - { - Text = text, - Width = 1, - Height = height, - TextDirection = TextDirection.TopBottom_LeftRight - }; - - if (autoSize) - { - lblLeft.Width = Dim.Auto (); - lblLeft.Height = Dim.Auto (); - } - - var lblCenter = new View - { - Text = text, - X = 2, - Width = 1, - Height = height, - TextDirection = TextDirection.TopBottom_LeftRight, - VerticalTextAlignment = Alignment.Center - }; - - if (autoSize) - { - lblCenter.Width = Dim.Auto (); - lblCenter.Height = Dim.Auto (); - } - - var lblRight = new View - { - Text = text, - X = 4, - Width = 1, - Height = height, - TextDirection = TextDirection.TopBottom_LeftRight, - VerticalTextAlignment = Alignment.End - }; - - if (autoSize) - { - lblRight.Width = Dim.Auto (); - lblRight.Height = Dim.Auto (); - } - - var lblJust = new View - { - Text = text, - X = 6, - Width = 1, - Height = height, - TextDirection = TextDirection.TopBottom_LeftRight, - VerticalTextAlignment = Alignment.Fill - }; - - if (autoSize) - { - lblJust.Width = Dim.Auto (); - lblJust.Height = Dim.Auto (); - } - - var frame = new FrameView { Width = Dim.Fill (), Height = Dim.Fill (), BorderStyle = LineStyle.Single }; - - frame.Add (lblLeft, lblCenter, lblRight, lblJust); - var top = new Runnable (); - top.Add (frame); - Application.Begin (top); - Application.Driver!.SetScreenSize (9, height + 2); - Application.LayoutAndDraw (); - - if (autoSize) - { - Assert.Equal (new (1, 11), lblLeft.TextFormatter.ConstrainToSize); - Assert.Equal (new (1, 11), lblCenter.TextFormatter.ConstrainToSize); - Assert.Equal (new (1, 11), lblRight.TextFormatter.ConstrainToSize); - Assert.Equal (new (1, 11), lblJust.TextFormatter.ConstrainToSize); - Assert.Equal (new (0, 0, 9, height + 2), frame.Frame); - } - else - { - Assert.Equal (new (1, height), lblLeft.TextFormatter.ConstrainToSize); - Assert.Equal (new (1, height), lblCenter.TextFormatter.ConstrainToSize); - Assert.Equal (new (1, height), lblRight.TextFormatter.ConstrainToSize); - Assert.Equal (new (1, height), lblJust.TextFormatter.ConstrainToSize); - Assert.Equal (new (0, 0, 9, height + 2), frame.Frame); - } - - string expected; - - if (autoSize) - { - expected = @" -┌───────┐ -│H H H H│ -│e e e e│ -│l l l l│ -│l l l l│ -│o o o o│ -│ │ -│W W W W│ -│o o o o│ -│r r r r│ -│l l l l│ -│d d d d│ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -└───────┘ -"; - } - else - { - expected = @" -┌───────┐ -│H H│ -│e e│ -│l l│ -│l l│ -│o H o│ -│ e │ -│W l │ -│o l │ -│r o │ -│l H │ -│d W e │ -│ o l │ -│ r l │ -│ l o │ -│ d │ -│ W W│ -│ o o│ -│ r r│ -│ l l│ -│ d d│ -└───────┘ -"; - } - - Rectangle pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); - Assert.Equal (new (0, 0, 9, height + 2), pos); - top.Dispose (); - } - - [Fact] - [SetupFakeApplication] - public void Narrow_Wide_Runes () - { - Application.Driver!.SetScreenSize (32, 32); - var top = new View { Width = 32, Height = 32 }; - top.App = ApplicationImpl.Instance; - - var text = $"First line{Environment.NewLine}Second line"; - var horizontalView = new View { Width = 20, Height = 1, Text = text }; - - // Autosize is off, so we have to explicitly set TextFormatter.Size - horizontalView.TextFormatter.ConstrainToSize = new (20, 1); - - var verticalView = new View - { - Y = 3, - Height = 20, - Width = 1, - Text = text, - TextDirection = TextDirection.TopBottom_LeftRight - }; - - // Autosize is off, so we have to explicitly set TextFormatter.Size - verticalView.TextFormatter.ConstrainToSize = new (1, 20); - - var frame = new FrameView { Width = Dim.Fill (), Height = Dim.Fill (), Text = "Window", BorderStyle = LineStyle.Single }; - frame.Add (horizontalView, verticalView); - top.Add (frame); - top.BeginInit (); - top.EndInit (); - - Assert.Equal (new (0, 0, 20, 1), horizontalView.Frame); - Assert.Equal (new (0, 3, 1, 20), verticalView.Frame); - - top.Draw (); - - var expected = @" -┌──────────────────────────────┐ -│First line Second li │ -│ │ -│ │ -│F │ -│i │ -│r │ -│s │ -│t │ -│ │ -│l │ -│i │ -│n │ -│e │ -│ │ -│S │ -│e │ -│c │ -│o │ -│n │ -│d │ -│ │ -│l │ -│i │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -└──────────────────────────────┘ -"; - - Rectangle pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); - - verticalView.Text = $"最初の行{Environment.NewLine}二行目"; - Assert.True (verticalView.TextFormatter.NeedsFormat); - - // Autosize is off, so we have to explicitly set TextFormatter.Size - // We know these glpyhs are 2 cols wide, so we need to widen the view - verticalView.Width = 2; - verticalView.TextFormatter.ConstrainToSize = new (2, 20); - Assert.True (verticalView.TextFormatter.NeedsFormat); - top.SetClipToScreen (); - top.Draw (); - Assert.Equal (new (0, 3, 2, 20), verticalView.Frame); - - expected = @" -┌──────────────────────────────┐ -│First line Second li │ -│ │ -│ │ -│最 │ -│初 │ -│の │ -│行 │ -│ │ -│二 │ -│行 │ -│目 │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -└──────────────────────────────┘ -"; - - pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); - } - - [Fact] - [SetupFakeApplication] - public void SetText_RendersCorrectly () - { - View view; - var text = "test"; - - view = new Label { App = ApplicationImpl.Instance, Text = text }; - view.BeginInit (); - view.EndInit (); - view.Draw (); - - DriverAssert.AssertDriverContentsWithFrameAre (text, output); - } -} diff --git a/Tests/UnitTests.Legacy/View/ViewTests.cs b/Tests/UnitTests.Legacy/View/ViewTests.cs deleted file mode 100644 index 3836d11311..0000000000 --- a/Tests/UnitTests.Legacy/View/ViewTests.cs +++ /dev/null @@ -1,526 +0,0 @@ -namespace UnitTests.ViewBaseTests; - -public class ViewTests -{ - private readonly ITestOutputHelper _output; - - public ViewTests (ITestOutputHelper output) => _output = output; - - // Generic lifetime (IDisposable) tests - [Fact] - [TestRespondersDisposed] - public void Dispose_Works () - { - var r = new View (); -#if DEBUG_IDISPOSABLE - Assert.Equal (4, View.Instances.Count); -#endif - - r.Dispose (); -#if DEBUG_IDISPOSABLE - Assert.Empty (View.Instances); -#endif - } - - [Fact] - public void Disposing_Event_Notify_All_Subscribers_On_The_First_Container () - { -#if DEBUG_IDISPOSABLE - - // Only clear before because need to test after assert - View.Instances.Clear (); -#endif - - var container1 = new View { Id = "Container1" }; - var count = 0; - - var view = new View { Id = "View" }; - view.Disposing += ViewDisposing; - container1.Add (view); - Assert.Equal (container1, view.SuperView); - - Assert.Single (container1.SubViews); - - var container2 = new View { Id = "Container2" }; - - // BUGBUG: It's not legit to add a View to two SuperViews - container2.Add (view); - Assert.Equal (container2, view.SuperView); - Assert.Equal (container1.SubViews.Count, container2.SubViews.Count); - container2.Dispose (); - - Assert.Empty (container1.SubViews); - Assert.Empty (container2.SubViews); - Assert.Equal (1, count); - Assert.Null (view.SuperView); - - container1.Dispose (); - -#if DEBUG_IDISPOSABLE - Assert.Empty (View.Instances); -#endif - - return; - - void ViewDisposing (object sender, EventArgs e) - { - count++; - Assert.Equal (view, sender); - container1.Remove ((View)sender); - } - } - - [Fact] - public void Disposing_Event_Notify_All_Subscribers_On_The_Second_Container () - { -#if DEBUG_IDISPOSABLE - - // Only clear before because need to test after assert - View.Instances.Clear (); -#endif - - var container1 = new View { Id = "Container1" }; - - var view = new View { Id = "View" }; - container1.Add (view); - Assert.Equal (container1, view.SuperView); - Assert.Single (container1.SubViews); - - var container2 = new View { Id = "Container2" }; - var count = 0; - - view.Disposing += View_Disposing; - - // BUGBUG: It's not legit to add a View to two SuperViews - container2.Add (view); - Assert.Equal (container2, view.SuperView); - - void View_Disposing (object sender, EventArgs e) - { - count++; - Assert.Equal (view, sender); - container2.Remove ((View)sender); - } - - Assert.Equal (container1.SubViews.Count, container2.SubViews.Count); - container1.Dispose (); - - Assert.Empty (container1.SubViews); - Assert.Empty (container2.SubViews); - Assert.Equal (1, count); - Assert.Null (view.SuperView); - - container2.Dispose (); - -#if DEBUG_IDISPOSABLE - Assert.Empty (View.Instances); -#endif - } - - [Fact] - public void Not_Notifying_Dispose () - { - // Only clear before because need to test after assert -#if DEBUG_IDISPOSABLE - View.Instances.Clear (); -#endif - var container1 = new View { Id = "Container1" }; - - var view = new View { Id = "View" }; - container1.Add (view); - Assert.Equal (container1, view.SuperView); - - Assert.Single (container1.SubViews); - - var container2 = new View { Id = "Container2" }; - - // BUGBUG: It's not legit to add a View to two SuperViews - container2.Add (view); - Assert.Equal (container2, view.SuperView); - Assert.Equal (container1.SubViews.Count, container2.SubViews.Count); - container1.Dispose (); - - Assert.Empty (container1.SubViews); - Assert.NotEmpty (container2.SubViews); - Assert.Single (container2.SubViews); - Assert.Null (view.SuperView); - - // Trying access disposed properties -#if DEBUG_IDISPOSABLE - Assert.True (container2.SubViews.ElementAt (0).WasDisposed); -#endif - Assert.False (container2.SubViews.ElementAt (0).CanFocus); - Assert.Null (container2.SubViews.ElementAt (0).Margin); - Assert.Null (container2.SubViews.ElementAt (0).Border); - Assert.Null (container2.SubViews.ElementAt (0).Padding); - Assert.Null (view.SuperView); - - container2.Dispose (); - -#if DEBUG_IDISPOSABLE - Assert.Empty (View.Instances); -#endif - } - - [Fact] - [TestRespondersDisposed] - public void Dispose_View () - { - var view = new View (); - Assert.NotNull (view.Margin); - Assert.NotNull (view.Border); - Assert.NotNull (view.Padding); - -#if DEBUG_IDISPOSABLE - Assert.Equal (4, View.Instances.Count); -#endif - - view.Dispose (); - Assert.Null (view.Margin); - Assert.Null (view.Border); - Assert.Null (view.Padding); - } - - [Fact] - public void Internal_Tests () - { - var rect = new Rectangle (1, 1, 10, 1); - var view = new View { Frame = rect }; - } - - [Fact] - [TestRespondersDisposed] - public void New_Initializes () - { - // Parameterless - var r = new View (); - Assert.NotNull (r); - Assert.True (r.Enabled); - Assert.True (r.Visible); - - Assert.False (r.CanFocus); - Assert.False (r.HasFocus); - Assert.Equal (new (0, 0, 0, 0), r.Viewport); - Assert.Equal (new (0, 0, 0, 0), r.Frame); - Assert.Null (r.Focused); - Assert.False (r.HasScheme); - Assert.NotNull (r.GetScheme ()); - Assert.Equal (r.GetScheme (), SchemeManager.GetSchemesForCurrentTheme () ["Base"]); - Assert.Equal (0, r.Width); - Assert.Equal (0, r.Height); - Assert.Equal (0, r.X); - Assert.Equal (0, r.Y); - Assert.False (r.IsCurrentTop); - Assert.Empty (r.Id); - Assert.Empty (r.SubViews); - Assert.Null (r.MouseHoldRepeat); - Assert.False (r.MousePositionTracking); - Assert.Null (r.SuperView); - Assert.Null (r.MostFocused); - Assert.Equal (TextDirection.LeftRight_TopBottom, r.TextDirection); - r.Dispose (); - - // Empty Rect - r = new () { Frame = Rectangle.Empty }; - Assert.NotNull (r); - Assert.False (r.CanFocus); - Assert.False (r.HasFocus); - Assert.Equal (new (0, 0, 0, 0), r.Viewport); - Assert.Equal (new (0, 0, 0, 0), r.Frame); - Assert.Null (r.Focused); - Assert.False (r.HasScheme); - Assert.NotNull (r.GetScheme ()); - Assert.Equal (r.GetScheme (), SchemeManager.GetSchemesForCurrentTheme () ["Base"]); - Assert.Equal (0, r.Width); - Assert.Equal (0, r.Height); - Assert.Equal (0, r.X); - Assert.Equal (0, r.Y); - Assert.False (r.IsCurrentTop); - Assert.Empty (r.Id); - Assert.Empty (r.SubViews); - Assert.Null (r.MouseHoldRepeat); - Assert.False (r.MousePositionTracking); - Assert.Null (r.SuperView); - Assert.Null (r.MostFocused); - Assert.Equal (TextDirection.LeftRight_TopBottom, r.TextDirection); - r.Dispose (); - - // Rect with values - r = new () { Frame = new (1, 2, 3, 4) }; - Assert.NotNull (r); - Assert.False (r.CanFocus); - Assert.False (r.HasFocus); - Assert.Equal (new (0, 0, 3, 4), r.Viewport); - Assert.Equal (new (1, 2, 3, 4), r.Frame); - Assert.Null (r.Focused); - Assert.False (r.HasScheme); - Assert.NotNull (r.GetScheme ()); - Assert.Equal (r.GetScheme (), SchemeManager.GetSchemesForCurrentTheme () ["Base"]); - Assert.Equal (3, r.Width); - Assert.Equal (4, r.Height); - Assert.Equal (1, r.X); - Assert.Equal (2, r.Y); - Assert.False (r.IsCurrentTop); - Assert.Empty (r.Id); - Assert.Empty (r.SubViews); - Assert.Null (r.MouseHoldRepeat); - Assert.False (r.MousePositionTracking); - Assert.Null (r.SuperView); - Assert.Null (r.MostFocused); - Assert.Equal (TextDirection.LeftRight_TopBottom, r.TextDirection); - r.Dispose (); - - // Initializes a view with a vertical direction - r = new () { Text = "Vertical View", TextDirection = TextDirection.TopBottom_LeftRight, Width = Dim.Auto (), Height = Dim.Auto () }; - r.TextFormatter.WordWrap = false; - Assert.NotNull (r); - - r.BeginInit (); - r.EndInit (); - Assert.False (r.CanFocus); - Assert.False (r.HasFocus); - Assert.Equal (new (0, 0, 1, 13), r.Viewport); - Assert.Equal (new (0, 0, 1, 13), r.Frame); - Assert.Null (r.Focused); - Assert.False (r.HasScheme); - Assert.NotNull (r.GetScheme ()); - Assert.Equal (r.GetScheme (), SchemeManager.GetSchemesForCurrentTheme () ["Base"]); - Assert.False (r.IsCurrentTop); - Assert.Equal (string.Empty, r.Id); - Assert.Empty (r.SubViews); - Assert.Null (r.MouseHoldRepeat); - Assert.False (r.MousePositionTracking); - Assert.Null (r.SuperView); - Assert.Null (r.MostFocused); - Assert.Equal (TextDirection.TopBottom_LeftRight, r.TextDirection); - r.Dispose (); - } - - [Fact] - [TestRespondersDisposed] - public void New_Methods_Return_False () - { - var r = new View (); - - Assert.False (r.NewKeyDownEvent (Key.Empty)); - - Assert.False (r.NewMouseEvent (new () { Flags = MouseFlags.AllEvents })); - - r.Dispose (); - - // TODO: Add more - } - - [Fact] - [AutoInitShutdown] - public void Test_Nested_Views_With_Height_Equal_To_One () - { - var v = new View { Width = 11, Height = 3 }; - v.App = ApplicationImpl.Instance; - - var top = new View { Width = Dim.Fill (), Height = 1 }; - var bottom = new View { Width = Dim.Fill (), Height = 1, Y = 2 }; - - top.Add (new Label { Text = "111" }); - v.Add (top); - v.Add (new Line { Orientation = Orientation.Horizontal, Y = 1 }); - bottom.Add (new Label { Text = "222" }); - v.Add (bottom); - - v.BeginInit (); - v.EndInit (); - v.LayoutSubViews (); - v.Draw (); - - var looksLike = @" -111 -─────────── -222"; - DriverAssert.AssertDriverContentsAre (looksLike, _output); - v.Dispose (); - top.Dispose (); - bottom.Dispose (); - } - - [Fact] - [TestRespondersDisposed] - public void View_With_No_Difference_Between_An_Object_Initializer_Compute_And_A_Absolute () - { - // Object Initializer Computed - var view = new View { X = 1, Y = 2, Width = 3, Height = 4 }; - - // Object Initializer Absolute - var super = new View { Frame = new (0, 0, 10, 10) }; - super.Add (view); - super.BeginInit (); - super.EndInit (); - super.LayoutSubViews (); - - Assert.Equal (1, view.X); - Assert.Equal (2, view.Y); - Assert.Equal (3, view.Width); - Assert.Equal (4, view.Height); - Assert.False (view.Frame.IsEmpty); - Assert.Equal (new (1, 2, 3, 4), view.Frame); - Assert.False (view.Viewport.IsEmpty); - Assert.Equal (new (0, 0, 3, 4), view.Viewport); - - view.LayoutSubViews (); - - Assert.Equal (1, view.X); - Assert.Equal (2, view.Y); - Assert.Equal (3, view.Width); - Assert.Equal (4, view.Height); - Assert.False (view.Frame.IsEmpty); - Assert.False (view.Viewport.IsEmpty); - super.Dispose (); - -#if DEBUG_IDISPOSABLE - Assert.Empty (View.Instances); -#endif - - // Default Constructor - view = new (); - Assert.Equal (0, view.X); - Assert.Equal (0, view.Y); - Assert.Equal (0, view.Width); - Assert.Equal (0, view.Height); - Assert.True (view.Frame.IsEmpty); - Assert.True (view.Viewport.IsEmpty); - view.Dispose (); - - // Object Initializer - view = new () { X = 1, Y = 2, Text = "" }; - Assert.Equal (1, view.X); - Assert.Equal (2, view.Y); - Assert.Equal (0, view.Width); - Assert.Equal (0, view.Height); - Assert.False (view.Frame.IsEmpty); - Assert.True (view.Viewport.IsEmpty); - view.Dispose (); - - // Default Constructor and post assignment equivalent to Object Initializer - view = new (); - view.X = 1; - view.Y = 2; - view.Width = 3; - view.Height = 4; - super = new () { Frame = new (0, 0, 10, 10) }; - super.Add (view); - super.BeginInit (); - super.EndInit (); - super.LayoutSubViews (); - Assert.Equal (1, view.X); - Assert.Equal (2, view.Y); - Assert.Equal (3, view.Width); - Assert.Equal (4, view.Height); - Assert.False (view.Frame.IsEmpty); - Assert.Equal (new (1, 2, 3, 4), view.Frame); - Assert.False (view.Viewport.IsEmpty); - Assert.Equal (new (0, 0, 3, 4), view.Viewport); - super.Dispose (); - } - - [Fact] - [AutoInitShutdown] - public void Visible_Clear_The_View_Output () - { - var view = new View { Text = "Testing visibility." }; // use View, not Label to avoid AutoSize == true - - Assert.Equal (0, view.Frame.Width); - Assert.Equal (0, view.Height); - var win = new Window (); - win.Add (view); - Runnable top = new (); - top.Add (win); - SessionToken rs = Application.Begin (top); - - view.Width = Dim.Auto (); - view.Height = Dim.Auto (); - AutoInitShutdownAttribute.RunIteration (); - Assert.Equal ("Testing visibility.".Length, view.Frame.Width); - Assert.True (view.Visible); - Application.Driver!.SetScreenSize (30, 5); - Application.LayoutAndDraw (); - - DriverAssert.AssertDriverContentsWithFrameAre (@" -┌────────────────────────────┐ -│Testing visibility. │ -│ │ -│ │ -└────────────────────────────┘ -", - _output); - - view.Visible = false; - - AutoInitShutdownAttribute.RunIteration (); - - DriverAssert.AssertDriverContentsWithFrameAre (@" -┌────────────────────────────┐ -│ │ -│ │ -│ │ -└────────────────────────────┘ -", - _output); - Application.End (rs); - top.Dispose (); - } - - [Fact] - [AutoInitShutdown] - public void Visible_Sets_Also_Sets_SubViews () - { - var button = new Button { Text = "Click Me" }; - var win = new Window { Width = Dim.Fill (), Height = Dim.Fill () }; - win.Add (button); - Runnable top = new (); - top.Add (win); - - var iterations = 0; - - Application.Iteration += OnApplicationOnIteration; - - Application.Run (top); - Application.Iteration -= OnApplicationOnIteration; - top.Dispose (); - Assert.Equal (1, iterations); - - return; - - void OnApplicationOnIteration (object s, EventArgs a) - { - iterations++; - - Assert.True (button.Visible); - Assert.True (button.CanFocus); - Assert.True (button.HasFocus); - Assert.True (win.Visible); - Assert.True (win.CanFocus); - Assert.True (win.HasFocus); - - win.Visible = false; - Assert.True (button.Visible); - Assert.True (button.CanFocus); - Assert.False (button.HasFocus); - Assert.False (win.Visible); - Assert.True (win.CanFocus); - Assert.False (win.HasFocus); - - button.SetFocus (); - Assert.False (button.HasFocus); - Assert.False (win.HasFocus); - - win.SetFocus (); - Assert.False (button.HasFocus); - Assert.False (win.HasFocus); - - win.Visible = true; - Assert.True (button.HasFocus); - Assert.True (win.HasFocus); - - Application.RequestStop (); - } - } -} diff --git a/Tests/UnitTests.Legacy/Views/ButtonTests.cs b/Tests/UnitTests.Legacy/Views/ButtonTests.cs deleted file mode 100644 index cd6e5febcb..0000000000 --- a/Tests/UnitTests.Legacy/Views/ButtonTests.cs +++ /dev/null @@ -1,207 +0,0 @@ -namespace UnitTests.ViewsTests; - -public class ButtonTests (ITestOutputHelper output) -{ - [Fact] - [SetupFakeApplication] - public void Constructors_Defaults () - { - // Override CM - Button.DefaultShadow = ShadowStyle.None; - - var btn = new Button () - { - App = ApplicationImpl.Instance - }; - Assert.Equal (string.Empty, btn.Text); - btn.BeginInit (); - btn.EndInit (); - btn.SetRelativeLayout (new (100, 100)); - - Assert.Equal ($"{Glyphs.LeftBracket} {Glyphs.RightBracket}", btn.TextFormatter.Text); - Assert.False (btn.IsDefault); - Assert.Equal (Alignment.Center, btn.TextAlignment); - Assert.Equal ('_', btn.HotKeySpecifier.Value); - Assert.True (btn.CanFocus); - Assert.Equal (new (0, 0, 4, 1), btn.Viewport); - Assert.Equal (new (0, 0, 4, 1), btn.Frame); - Assert.Equal ($"{Glyphs.LeftBracket} {Glyphs.RightBracket}", btn.TextFormatter.Text); - Assert.False (btn.IsDefault); - Assert.Equal (Alignment.Center, btn.TextAlignment); - Assert.Equal ('_', btn.HotKeySpecifier.Value); - Assert.True (btn.CanFocus); - Assert.Equal (new (0, 0, 4, 1), btn.Viewport); - Assert.Equal (new (0, 0, 4, 1), btn.Frame); - - Assert.Equal (string.Empty, btn.Title); - Assert.Equal (KeyCode.Null, btn.HotKey); - - btn.Draw (); - - var expected = @$" -{Glyphs.LeftBracket} {Glyphs.RightBracket} -"; - DriverAssert.AssertDriverContentsWithFrameAre (expected, output); - btn.Dispose (); - - btn = new () - { - App = ApplicationImpl.Instance, - Text = "_Test", IsDefault = true - }; - btn.Layout (); - Assert.Equal (new (10, 1), btn.TextFormatter.ConstrainToSize); - - btn.BeginInit (); - btn.EndInit (); - Assert.Equal ('_', btn.HotKeySpecifier.Value); - Assert.Equal (Key.T, btn.HotKey); - Assert.Equal ("_Test", btn.Text); - - Assert.Equal ( - $"{Glyphs.LeftBracket}{Glyphs.LeftDefaultIndicator} Test {Glyphs.RightDefaultIndicator}{Glyphs.RightBracket}", - btn.TextFormatter.Format () - ); - Assert.True (btn.IsDefault); - Assert.Equal (Alignment.Center, btn.TextAlignment); - Assert.True (btn.CanFocus); - - btn.SetRelativeLayout (new (100, 100)); - - // 0123456789012345678901234567890123456789 - // [* Test *] - Assert.Equal ('_', btn.HotKeySpecifier.Value); - Assert.Equal (10, btn.TextFormatter.Format ().Length); - Assert.Equal (new (10, 1), btn.TextFormatter.ConstrainToSize); - Assert.Equal (new (10, 1), btn.GetContentSize ()); - Assert.Equal (new (0, 0, 10, 1), btn.Viewport); - Assert.Equal (new (0, 0, 10, 1), btn.Frame); - Assert.Equal (KeyCode.T, btn.HotKey); - - btn.Dispose (); - - btn = new () - { - App = ApplicationImpl.Instance, - X = 1, Y = 2, Text = "_abc", IsDefault = true - }; - btn.BeginInit (); - btn.EndInit (); - Assert.Equal ("_abc", btn.Text); - Assert.Equal (Key.A, btn.HotKey); - - Assert.Equal ( - $"{Glyphs.LeftBracket}{Glyphs.LeftDefaultIndicator} abc {Glyphs.RightDefaultIndicator}{Glyphs.RightBracket}", - btn.TextFormatter.Format () - ); - Assert.True (btn.IsDefault); - Assert.Equal (Alignment.Center, btn.TextAlignment); - Assert.Equal ('_', btn.HotKeySpecifier.Value); - Assert.True (btn.CanFocus); - - ApplicationImpl.Instance.Driver?.ClearContents (); - btn.Draw (); - - expected = @$" - {Glyphs.LeftBracket}{Glyphs.LeftDefaultIndicator} abc {Glyphs.RightDefaultIndicator}{Glyphs.RightBracket} -"; - DriverAssert.AssertDriverContentsWithFrameAre (expected, output, ApplicationImpl.Instance.Driver); - - Assert.Equal (new (0, 0, 9, 1), btn.Viewport); - Assert.Equal (new (1, 2, 9, 1), btn.Frame); - btn.Dispose (); - } - - /// - /// This test demonstrates how to change the activation key for Button as described in the README.md keyboard - /// handling section - /// - [Fact] - [AutoInitShutdown] - public void KeyBindingExample () - { - var pressed = 0; - var btn = new Button { Text = "Press Me" }; - - btn.Accepting += (s, e) => pressed++; - - // The Button class supports the Default and Accept command - Assert.Contains (Command.HotKey, btn.GetSupportedCommands ()); - Assert.Contains (Command.Accept, btn.GetSupportedCommands ()); - - var top = new Runnable (); - top.Add (btn); - Application.Begin (top); - - Assert.True (btn.HasFocus); - - // default keybinding is Space which results in Command.Accept (when focused) - Application.RaiseKeyDownEvent (new ((KeyCode)' ')); - Assert.Equal (1, pressed); - - // remove the default keybinding (Space) - btn.KeyBindings.Clear (Command.HotKey); - btn.KeyBindings.Clear (Command.Accept); - - // After clearing the default keystroke the Space button no longer does anything for the Button - Application.RaiseKeyDownEvent (new ((KeyCode)' ')); - Assert.Equal (1, pressed); - - // Set a new binding of b for the click (Accept) event - btn.KeyBindings.Add (Key.B, Command.HotKey); // b will now trigger the Accept command (when focused or not) - - // now pressing B should call the button click event - Application.RaiseKeyDownEvent (Key.B); - Assert.Equal (2, pressed); - - // now pressing Shift-B should NOT call the button click event - Application.RaiseKeyDownEvent (Key.B.WithShift); - Assert.Equal (2, pressed); - - // now pressing Alt-B should NOT call the button click event - Application.RaiseKeyDownEvent (Key.B.WithAlt); - Assert.Equal (2, pressed); - - // now pressing Shift-Alt-B should NOT call the button click event - Application.RaiseKeyDownEvent (Key.B.WithAlt.WithShift); - Assert.Equal (2, pressed); - top.Dispose (); - } - - - [Fact] - [AutoInitShutdown] - public void Update_Parameterless_Only_On_Or_After_Initialize () - { - Button.DefaultShadow = ShadowStyle.None; - var btn = new Button { X = Pos.Center (), Y = Pos.Center (), Text = "Say Hello 你" }; - var win = new Window { Width = Dim.Fill (), Height = Dim.Fill () }; - win.Add (btn); - var top = new Runnable (); - top.Add (win); - - Assert.False (btn.IsInitialized); - - Application.Begin (top); - Application.Driver?.SetScreenSize (30, 5); - Application.LayoutAndDraw (); - Assert.True (btn.IsInitialized); - Assert.Equal ("Say Hello 你", btn.Text); - Assert.Equal ($"{Glyphs.LeftBracket} {btn.Text} {Glyphs.RightBracket}", btn.TextFormatter.Text); - Assert.Equal (new (0, 0, 16, 1), btn.Viewport); - var btnTxt = $"{Glyphs.LeftBracket} {btn.Text} {Glyphs.RightBracket}"; - - var expected = @$" -┌────────────────────────────┐ -│ │ -│ {btnTxt} │ -│ │ -└────────────────────────────┘ -"; - - Rectangle pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); - Assert.Equal (new (0, 0, 30, 5), pos); - top.Dispose (); - } - -} diff --git a/Tests/UnitTests.Legacy/Views/CheckBoxTests.cs b/Tests/UnitTests.Legacy/Views/CheckBoxTests.cs deleted file mode 100644 index 9e23efe706..0000000000 --- a/Tests/UnitTests.Legacy/Views/CheckBoxTests.cs +++ /dev/null @@ -1,316 +0,0 @@ -// ReSharper disable AccessToModifiedClosure - -namespace UnitTests.ViewsTests; - -public class CheckBoxTests (ITestOutputHelper output) -{ - private static readonly Size _size25x1 = new (25, 1); - - - - #region Mouse Tests - - - - - - #endregion Mouse Tests - - [Fact] - [AutoInitShutdown] - public void TextAlignment_Centered () - { - var checkBox = new CheckBox - { - X = 1, - Y = Pos.Center (), - Text = "Check this out 你", - TextAlignment = Alignment.Center, - Width = 25 - }; - var win = new Window { Width = Dim.Fill (), Height = Dim.Fill (), Title = "Test Demo 你" }; - win.Add (checkBox); - var top = new Runnable (); - top.Add (win); - - Application.Begin (top); - Application.Driver?.SetScreenSize (30, 5); - Application.LayoutAndDraw (); - - Assert.Equal (Alignment.Center, checkBox.TextAlignment); - Assert.Equal (new (1, 1, 25, 1), checkBox.Frame); - Assert.Equal (_size25x1, checkBox.TextFormatter.ConstrainToSize); - - var expected = @$" -┌┤Test Demo 你├──────────────┐ -│ │ -│ {Glyphs.CheckStateUnChecked} Check this out 你 │ -│ │ -└────────────────────────────┘ -"; - - Rectangle pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); - Assert.Equal (new (0, 0, 30, 5), pos); - - checkBox.Value = CheckState.Checked; - Application.LayoutAndDraw (); - - expected = @$" -┌┤Test Demo 你├──────────────┐ -│ │ -│ {Glyphs.CheckStateChecked} Check this out 你 │ -│ │ -└────────────────────────────┘ -"; - - pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); - Assert.Equal (new (0, 0, 30, 5), pos); - top.Dispose (); - } - - [Fact] - [AutoInitShutdown] - public void TextAlignment_Justified () - { - var checkBox1 = new CheckBox - { - X = 1, - Y = Pos.Center (), - Text = "Check first out 你", - TextAlignment = Alignment.Fill, - Width = 25 - }; - - var checkBox2 = new CheckBox - { - X = 1, - Y = Pos.Bottom (checkBox1), - Text = "Check second out 你", - TextAlignment = Alignment.Fill, - Width = 25 - }; - var win = new Window { Width = Dim.Fill (), Height = Dim.Fill (), Title = "Test Demo 你" }; - win.Add (checkBox1, checkBox2); - var top = new Runnable (); - top.Add (win); - - SessionToken rs = Application.Begin (top); - Application.Driver!.SetScreenSize (30, 6); - Application.LayoutAndDraw (); - Assert.Equal (Alignment.Fill, checkBox1.TextAlignment); - Assert.Equal (new (1, 1, 25, 1), checkBox1.Frame); - Assert.Equal (Alignment.Fill, checkBox2.TextAlignment); - Assert.Equal (new (1, 2, 25, 1), checkBox2.Frame); - - var expected = @$" -┌┤Test Demo 你├──────────────┐ -│ │ -│ {Glyphs.CheckStateUnChecked} Check first out 你 │ -│ {Glyphs.CheckStateUnChecked} Check second out 你 │ -│ │ -└────────────────────────────┘ -"; - - Rectangle pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); - Assert.Equal (new (0, 0, 30, 6), pos); - - checkBox1.Value = CheckState.Checked; - AutoInitShutdownAttribute.RunIteration (); - Assert.Equal (new (1, 1, 25, 1), checkBox1.Frame); - Assert.Equal (_size25x1, checkBox1.TextFormatter.ConstrainToSize); - - checkBox2.Value = CheckState.Checked; - AutoInitShutdownAttribute.RunIteration (); - Assert.Equal (new (1, 2, 25, 1), checkBox2.Frame); - Assert.Equal (_size25x1, checkBox2.TextFormatter.ConstrainToSize); - AutoInitShutdownAttribute.RunIteration (); - - expected = @$" -┌┤Test Demo 你├──────────────┐ -│ │ -│ {Glyphs.CheckStateChecked} Check first out 你 │ -│ {Glyphs.CheckStateChecked} Check second out 你 │ -│ │ -└────────────────────────────┘ -"; - - pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); - Assert.Equal (new (0, 0, 30, 6), pos); - top.Dispose (); - } - - [Fact] - [AutoInitShutdown] - public void TextAlignment_Left () - { - var checkBox = new CheckBox - { - X = 1, - Y = Pos.Center (), - Text = "Check this out 你", - Width = 25 - }; - var win = new Window { Width = Dim.Fill (), Height = Dim.Fill (), Title = "Test Demo 你" }; - win.Add (checkBox); - var top = new Runnable (); - top.Add (win); - - Application.Begin (top); - Application.Driver!.SetScreenSize (30, 5); - Application.LayoutAndDraw (); - Assert.Equal (Alignment.Start, checkBox.TextAlignment); - Assert.Equal (new (1, 1, 25, 1), checkBox.Frame); - Assert.Equal (_size25x1, checkBox.TextFormatter.ConstrainToSize); - - var expected = @$" -┌┤Test Demo 你├──────────────┐ -│ │ -│ {Glyphs.CheckStateUnChecked} Check this out 你 │ -│ │ -└────────────────────────────┘ -"; - - Rectangle pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); - Assert.Equal (new (0, 0, 30, 5), pos); - - checkBox.Value = CheckState.Checked; - AutoInitShutdownAttribute.RunIteration (); - - expected = @$" -┌┤Test Demo 你├──────────────┐ -│ │ -│ {Glyphs.CheckStateChecked} Check this out 你 │ -│ │ -└────────────────────────────┘ -"; - - pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); - Assert.Equal (new (0, 0, 30, 5), pos); - top.Dispose (); - } - - [Fact] - [AutoInitShutdown] - public void TextAlignment_Right () - { - var checkBox = new CheckBox - { - X = 1, - Y = Pos.Center (), - Text = "Check this out 你", - TextAlignment = Alignment.End, - Width = 25 - }; - var win = new Window { Width = Dim.Fill (), Height = Dim.Fill (), Title = "Test Demo 你" }; - win.Add (checkBox); - var top = new Runnable (); - top.Add (win); - - Application.Begin (top); - Application.Driver!.SetScreenSize (30, 5); - Application.LayoutAndDraw (); - Assert.Equal (Alignment.End, checkBox.TextAlignment); - Assert.Equal (new (1, 1, 25, 1), checkBox.Frame); - Assert.Equal (_size25x1, checkBox.TextFormatter.ConstrainToSize); - - var expected = @$" -┌┤Test Demo 你├──────────────┐ -│ │ -│ Check this out 你 {Glyphs.CheckStateUnChecked} │ -│ │ -└────────────────────────────┘ -"; - - Rectangle pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); - Assert.Equal (new (0, 0, 30, 5), pos); - - checkBox.Value = CheckState.Checked; - AutoInitShutdownAttribute.RunIteration (); - - expected = @$" -┌┤Test Demo 你├──────────────┐ -│ │ -│ Check this out 你 {Glyphs.CheckStateChecked} │ -│ │ -└────────────────────────────┘ -"; - - pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); - Assert.Equal (new (0, 0, 30, 5), pos); - top.Dispose (); - } - - [Fact] - public void HotKey_Command_Does_Not_Fire_Accept () - { - var cb = new CheckBox (); - var accepted = false; - - cb.Accepting += CheckBoxOnAccept; - cb.InvokeCommand (Command.HotKey); - - Assert.False (accepted); - - return; - - void CheckBoxOnAccept (object sender, CommandEventArgs e) { accepted = true; } - } - - [Theory] - [InlineData (CheckState.Checked)] - [InlineData (CheckState.UnChecked)] - [InlineData (CheckState.None)] - public void Activated_Handle_Event_Prevents_Change (CheckState initialState) - { - var ckb = new CheckBox { AllowCheckStateNone = true }; - var checkedInvoked = false; - - ckb.Value = initialState; - - ckb.Activating += OnActivating; - - Assert.Equal (initialState, ckb.Value); - bool? ret = ckb.InvokeCommand (Command.Activate); - Assert.True (ret); - Assert.True (checkedInvoked); - Assert.Equal (initialState, ckb.Value); - - return; - - void OnActivating (object sender, CommandEventArgs e) - { - checkedInvoked = true; - e.Handled = true; - } - } - - [Theory] - [InlineData (CheckState.Checked)] - [InlineData (CheckState.UnChecked)] - [InlineData (CheckState.None)] - public void ValueChanging_Cancel_Event_Prevents_Change (CheckState initialState) - { - var ckb = new CheckBox { AllowCheckStateNone = true }; - var checkedInvoked = false; - - ckb.Value = initialState; - - ckb.ValueChanging += OnValueChanging; - - Assert.Equal (initialState, ckb.Value); - - // AdvanceCheckState returns false if the state was changed, true if it was cancelled, null if it was not changed - bool? ret = ckb.AdvanceCheckState (); - Assert.True (ret); - Assert.True (checkedInvoked); - Assert.Equal (initialState, ckb.Value); - - return; - - void OnValueChanging (object sender, ValueChangingEventArgs e) - { - checkedInvoked = true; - e.Handled = true; - } - } -} diff --git a/Tests/UnitTests.Legacy/Views/ColorPickerTests.cs b/Tests/UnitTests.Legacy/Views/ColorPickerTests.cs deleted file mode 100644 index 3ed1358ef2..0000000000 --- a/Tests/UnitTests.Legacy/Views/ColorPickerTests.cs +++ /dev/null @@ -1,9 +0,0 @@ -#nullable enable -using UnitTests; - -namespace UnitTests_Parallelizable.ViewsTests; - -public class ColorPickerTests -{ - -} diff --git a/Tests/UnitTests.Legacy/Views/DatePickerTests.cs b/Tests/UnitTests.Legacy/Views/DatePickerTests.cs deleted file mode 100644 index 7be8544f7d..0000000000 --- a/Tests/UnitTests.Legacy/Views/DatePickerTests.cs +++ /dev/null @@ -1,67 +0,0 @@ -using System.Globalization; -using UnitTests; - -namespace UnitTests.ViewsTests; - -public class DatePickerTests -{ - [Fact] - [AutoInitShutdown] - public void DatePicker_ShouldNot_SetDateOutOfRange_UsingNextMonthButton () - { - var date = new DateTime (9999, 11, 15); - var datePicker = new DatePicker (date); - - var top = new Runnable (); - top.Add (datePicker); - Application.Begin (top); - - Assert.Equal (datePicker.SubViews.First (v => v.Id == "_dateEditor"), datePicker.Focused); - - // Set focus to next month button - datePicker.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabStop); - Assert.Equal (datePicker.SubViews.First (v => v.Id == "_calendar"), datePicker.Focused); - datePicker.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabStop); - Assert.Equal (datePicker.SubViews.First (v => v.Id == "_previousMonthButton"), datePicker.Focused); - datePicker.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabStop); - Assert.Equal (datePicker.SubViews.First (v => v.Id == "_nextMonthButton"), datePicker.Focused); - - // Change month to December - Application.RaiseKeyDownEvent (Key.Enter); - Assert.Equal (12, datePicker.Value.Month); - - // Next month button is disabled, so focus advanced to edit field - Assert.Equal (datePicker.SubViews.First (v => v.Id == "_previousMonthButton"), datePicker.Focused); - - top.Dispose (); - } - - [Fact] - [AutoInitShutdown] - public void DatePicker_ShouldNot_SetDateOutOfRange_UsingPreviousMonthButton () - { - var date = new DateTime (1, 2, 15); - var datePicker = new DatePicker (date); - var top = new Runnable (); - - // Move focus to previous month button - top.Add (datePicker); - Application.Begin (top); - - Assert.Equal (datePicker.SubViews.First (v => v.Id == "_dateEditor"), datePicker.Focused); - - datePicker.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabStop); - Assert.Equal (datePicker.SubViews.First (v => v.Id == "_calendar"), datePicker.Focused); - datePicker.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabStop); - Assert.Equal (datePicker.SubViews.First (v => v.Id == "_previousMonthButton"), datePicker.Focused); - - // Change month to January - datePicker.NewKeyDownEvent (Key.Enter); - Assert.Equal (1, datePicker.Value.Month); - - // Next prev button is disabled, so focus advanced to edit button - Assert.Equal (datePicker.SubViews.First (v => v.Id == "_calendar"), datePicker.Focused); - - top.Dispose (); - } -} diff --git a/Tests/UnitTests.Legacy/Views/DialogTests.cs b/Tests/UnitTests.Legacy/Views/DialogTests.cs deleted file mode 100644 index 3f96a5cc3a..0000000000 --- a/Tests/UnitTests.Legacy/Views/DialogTests.cs +++ /dev/null @@ -1,115 +0,0 @@ -namespace ViewsTests; - -/// -/// Unit tests for that modify static properties and cannot run in parallel. -/// -public class DialogTests -{ - [Fact] - public void DefaultBorderStyle_Get_Set () - { - LineStyle original = Dialog.DefaultBorderStyle; - - try - { - Dialog.DefaultBorderStyle = LineStyle.Single; - Assert.Equal (LineStyle.Single, Dialog.DefaultBorderStyle); - - Dialog dialog = new (); - Assert.Equal (LineStyle.Single, dialog.BorderStyle); - dialog.Dispose (); - - Dialog.DefaultBorderStyle = LineStyle.Double; - Assert.Equal (LineStyle.Double, Dialog.DefaultBorderStyle); - - dialog = new (); - Assert.Equal (LineStyle.Double, dialog.BorderStyle); - dialog.Dispose (); - } - finally - { - Dialog.DefaultBorderStyle = original; - } - } - - [Fact] - public void DefaultButtonAlignment_Get_Set () - { - Alignment original = Dialog.DefaultButtonAlignment; - - try - { - Dialog.DefaultButtonAlignment = Alignment.Start; - Assert.Equal (Alignment.Start, Dialog.DefaultButtonAlignment); - - Dialog dialog = new (); - Assert.Equal (Alignment.Start, dialog.ButtonAlignment); - dialog.Dispose (); - - Dialog.DefaultButtonAlignment = Alignment.Center; - Assert.Equal (Alignment.Center, Dialog.DefaultButtonAlignment); - - dialog = new (); - Assert.Equal (Alignment.Center, dialog.ButtonAlignment); - dialog.Dispose (); - } - finally - { - Dialog.DefaultButtonAlignment = original; - } - } - - [Fact] - public void DefaultButtonAlignmentModes_Get_Set () - { - AlignmentModes original = Dialog.DefaultButtonAlignmentModes; - - try - { - Dialog.DefaultButtonAlignmentModes = AlignmentModes.StartToEnd; - Assert.Equal (AlignmentModes.StartToEnd, Dialog.DefaultButtonAlignmentModes); - - Dialog dialog = new (); - Assert.Equal (AlignmentModes.StartToEnd, dialog.ButtonAlignmentModes); - dialog.Dispose (); - - Dialog.DefaultButtonAlignmentModes = AlignmentModes.IgnoreFirstOrLast; - Assert.Equal (AlignmentModes.IgnoreFirstOrLast, Dialog.DefaultButtonAlignmentModes); - - dialog = new (); - Assert.Equal (AlignmentModes.IgnoreFirstOrLast, dialog.ButtonAlignmentModes); - dialog.Dispose (); - } - finally - { - Dialog.DefaultButtonAlignmentModes = original; - } - } - - [Fact] - public void DefaultShadow_Get_Set () - { - ShadowStyle original = Dialog.DefaultShadow; - - try - { - Dialog.DefaultShadow = ShadowStyle.None; - Assert.Equal (ShadowStyle.None, Dialog.DefaultShadow); - - Dialog dialog = new (); - Assert.Equal (ShadowStyle.None, dialog.ShadowStyle); - dialog.Dispose (); - - Dialog.DefaultShadow = ShadowStyle.Opaque; - Assert.Equal (ShadowStyle.Opaque, Dialog.DefaultShadow); - - dialog = new (); - Assert.Equal (ShadowStyle.Opaque, dialog.ShadowStyle); - dialog.Dispose (); - } - finally - { - Dialog.DefaultShadow = original; - } - } -} diff --git a/Tests/UnitTests.Legacy/Views/LabelTests.cs b/Tests/UnitTests.Legacy/Views/LabelTests.cs deleted file mode 100644 index 25bed7467d..0000000000 --- a/Tests/UnitTests.Legacy/Views/LabelTests.cs +++ /dev/null @@ -1,1178 +0,0 @@ -#nullable enable - -namespace UnitTests.ViewsTests; - -public class LabelTests (ITestOutputHelper output) -{ - [Fact] - [AutoInitShutdown] - public void Text_Set_With_AnchorEnd_Works () - { - var label = new Label { Y = Pos.Center (), Text = "Say Hello 你" }; - label.X = Pos.AnchorEnd (0) - Pos.Func (_ => label.TextFormatter.Text.GetColumns ()); - - var win = new Window { Width = Dim.Fill (), Height = Dim.Fill () }; - win.Add (label); - var top = new Runnable (); - top.Add (win); - - Application.Begin (top); - Application.Driver!.SetScreenSize (30, 5); - AutoInitShutdownAttribute.RunIteration (); - - var expected = @" -┌────────────────────────────┐ -│ │ -│ Say Hello 你│ -│ │ -└────────────────────────────┘ -"; - - DriverAssert.AssertDriverContentsWithFrameAre (expected, output); - - label.Text = "Say Hello 你 changed"; - - AutoInitShutdownAttribute.RunIteration (); - - expected = @" -┌────────────────────────────┐ -│ │ -│ Say Hello 你 changed│ -│ │ -└────────────────────────────┘ -"; - - DriverAssert.AssertDriverContentsWithFrameAre (expected, output); - top.Dispose (); - } - - [Fact] - [AutoInitShutdown] - public void Set_Text_With_Center () - { - var label = new Label { X = Pos.Center (), Y = Pos.Center (), Text = "Say Hello 你" }; - - var win = new Window { Width = Dim.Fill (), Height = Dim.Fill () }; - win.Add (label); - var top = new Runnable (); - top.Add (win); - - Application.Begin (top); - Application.Driver!.SetScreenSize (30, 5); - Application.LayoutAndDraw (); - var expected = @" -┌────────────────────────────┐ -│ │ -│ Say Hello 你 │ -│ │ -└────────────────────────────┘ -"; - - DriverAssert.AssertDriverContentsWithFrameAre (expected, output); - - label.Text = "Say Hello 你 changed"; - - AutoInitShutdownAttribute.RunIteration (); - - expected = @" -┌────────────────────────────┐ -│ │ -│ Say Hello 你 changed │ -│ │ -└────────────────────────────┘ -"; - - DriverAssert.AssertDriverContentsWithFrameAre (expected, output); - top.Dispose (); - } - - [Fact] - [AutoInitShutdown] - public void Label_Draw_Fill_Remaining () - { - Size tfSize = new (80, 1); - - Label label = new () { Text = "This label needs to be cleared before rewritten.", Width = tfSize.Width, Height = tfSize.Height }; - - TextFormatter tf1 = new () { Direction = TextDirection.LeftRight_TopBottom, ConstrainToSize = tfSize }; - tf1.Text = "This TextFormatter (tf1) without fill will not be cleared on rewritten."; - - TextFormatter tf2 = new () { Direction = TextDirection.LeftRight_TopBottom, ConstrainToSize = tfSize, FillRemaining = true }; - tf2.Text = "This TextFormatter (tf2) with fill will be cleared on rewritten."; - - Runnable top = new (); - top.Add (label); - SessionToken sessionToken = Application.Begin (top); - AutoInitShutdownAttribute.RunIteration (); - - Assert.False (label.TextFormatter.FillRemaining); - Assert.False (tf1.FillRemaining); - Assert.True (tf2.FillRemaining); - - AutoInitShutdownAttribute.RunIteration (); - - tf1.Draw ( - Application.Driver, - new (new (0, 1), tfSize), - label.GetAttributeForRole (VisualRole.Normal), - label.GetAttributeForRole (VisualRole.HotNormal)); - - tf2.Draw ( - Application.Driver, - new (new (0, 2), tfSize), - label.GetAttributeForRole (VisualRole.Normal), - label.GetAttributeForRole (VisualRole.HotNormal)); - - DriverAssert.AssertDriverContentsWithFrameAre ( - @" -This label needs to be cleared before rewritten. -This TextFormatter (tf1) without fill will not be cleared on rewritten. -This TextFormatter (tf2) with fill will be cleared on rewritten. ", - output - ); - - Assert.False (label.NeedsDraw); - Assert.False (label.NeedsLayout); - Assert.False (label.SubViewNeedsDraw); - label.Text = "This label is rewritten."; - Assert.True (label.NeedsDraw); - Assert.True (label.NeedsLayout); - - //Assert.False (label.SubViewNeedsDraw); - label.Draw (); - - tf1.Text = "This TextFormatter (tf1) is rewritten."; - - tf1.Draw ( - Application.Driver, - new (new (0, 1), tfSize), - label.GetAttributeForRole (VisualRole.Normal), - label.GetAttributeForRole (VisualRole.HotNormal)); - - tf2.Text = "This TextFormatter (tf2) is rewritten."; - - tf2.Draw ( - Application.Driver, - new (new (0, 2), tfSize), - label.GetAttributeForRole (VisualRole.Normal), - label.GetAttributeForRole (VisualRole.HotNormal)); - - DriverAssert.AssertDriverContentsWithFrameAre ( - @" -This label is rewritten. -This TextFormatter (tf1) is rewritten.will not be cleared on rewritten. -This TextFormatter (tf2) is rewritten. ", - output - ); - top.Dispose (); - } - - [Fact] - [AutoInitShutdown] - public void Label_Draw_Horizontal_Simple_Runes () - { - var label = new Label { Text = "Demo Simple Text" }; - var top = new Runnable (); - top.Add (label); - Application.Begin (top); - AutoInitShutdownAttribute.RunIteration (); - - Assert.Equal (new (0, 0, 16, 1), label.Frame); - - var expected = @" -Demo Simple Text -"; - - Rectangle pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); - Assert.Equal (new (0, 0, 16, 1), pos); - top.Dispose (); - } - - [Fact] - [AutoInitShutdown] - public void Label_Draw_Vertical_Simple_Text () - { - var label = new Label { TextDirection = TextDirection.TopBottom_LeftRight, Text = "Demo Simple Text" }; - var top = new Runnable (); - top.Add (label); - Application.Begin (top); - AutoInitShutdownAttribute.RunIteration (); - Assert.NotNull (label.Width); - Assert.NotNull (label.Height); - - var expected = @" -D -e -m -o - -S -i -m -p -l -e - -T -e -x -t -"; - - Rectangle pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); - Assert.Equal (new (0, 0, 1, 16), pos); - top.Dispose (); - } - - [Fact] - [AutoInitShutdown] - public void Label_Draw_Vertical_Wide_Runes () - { - var label = new Label { TextDirection = TextDirection.TopBottom_LeftRight, Text = "デモエムポンズ" }; - var top = new Runnable (); - top.Add (label); - Application.Begin (top); - AutoInitShutdownAttribute.RunIteration (); - - var expected = @" -デ -モ -エ -ム -ポ -ン -ズ -"; - - Rectangle pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); - Assert.Equal (new (0, 0, 2, 7), pos); - top.Dispose (); - } - - [Fact] - [AutoInitShutdown] - public void Update_Only_On_Or_After_Initialize () - { - var label = new Label { X = Pos.Center (), Y = Pos.Center (), Text = "Say Hello 你" }; - var win = new Window { Width = Dim.Fill (), Height = Dim.Fill () }; - win.Add (label); - var top = new Runnable (); - top.Add (win); - - Assert.False (label.IsInitialized); - - Application.Begin (top); - Application.Driver!.SetScreenSize (30, 5); - Application.LayoutAndDraw (); - Assert.True (label.IsInitialized); - Assert.Equal ("Say Hello 你", label.Text); - Assert.Equal ("Say Hello 你", label.TextFormatter.Text); - Assert.Equal (new (0, 0, 12, 1), label.Viewport); - - var expected = @" -┌────────────────────────────┐ -│ │ -│ Say Hello 你 │ -│ │ -└────────────────────────────┘ -"; - Rectangle pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); - Assert.Equal (new (0, 0, 30, 5), pos); - top.Dispose (); - } - - [Fact] - [AutoInitShutdown] - public void Update_Parameterless_Only_On_Or_After_Initialize () - { - var label = new Label { X = Pos.Center (), Y = Pos.Center (), Text = "Say Hello 你" }; - var win = new Window { Width = Dim.Fill (), Height = Dim.Fill () }; - win.Add (label); - var top = new Runnable (); - top.Add (win); - - Assert.False (label.IsInitialized); - - Application.Begin (top); - Application.Driver!.SetScreenSize (30, 5); - Application.LayoutAndDraw (); - Assert.True (label.IsInitialized); - Assert.Equal ("Say Hello 你", label.Text); - Assert.Equal ("Say Hello 你", label.TextFormatter.Text); - Assert.Equal (new (0, 0, 12, 1), label.Viewport); - - var expected = @" -┌────────────────────────────┐ -│ │ -│ Say Hello 你 │ -│ │ -└────────────────────────────┘ -"; - - Rectangle pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); - Assert.Equal (new (0, 0, 30, 5), pos); - top.Dispose (); - } - - [Fact] - [SetupFakeApplication] - public void Full_Border () - { - var label = new Label - { - Driver = Application.Driver, - BorderStyle = LineStyle.Single, Text = "Test" - }; - label.BeginInit (); - label.EndInit (); - label.SetRelativeLayout (Application.Screen.Size); - - Assert.Equal (new (0, 0, 4, 1), label.Viewport); - Assert.Equal (new (0, 0, 6, 3), label.Frame); - - label.Draw (); - - DriverAssert.AssertDriverContentsWithFrameAre ( - @" -┌┤Te├┐ -│Test│ -└────┘", - output - ); - label.Dispose (); - } - - // These tests were formally in AutoSizetrue.cs. They are (poor) Label tests. - private readonly string [] _expecteds = new string [21] - { - @" -┌────────────────────┐ -│View with long text │ -│ │ -└────────────────────┘", - @" -┌────────────────────┐ -│View with long text │ -│Label 0 │ -│Label 0 │ -└────────────────────┘", - @" -┌────────────────────┐ -│View with long text │ -│Label 0 │ -│Label 1 │ -│Label 1 │ -└────────────────────┘", - @" -┌────────────────────┐ -│View with long text │ -│Label 0 │ -│Label 1 │ -│Label 2 │ -│Label 2 │ -└────────────────────┘", - @" -┌────────────────────┐ -│View with long text │ -│Label 0 │ -│Label 1 │ -│Label 2 │ -│Label 3 │ -│Label 3 │ -└────────────────────┘", - @" -┌────────────────────┐ -│View with long text │ -│Label 0 │ -│Label 1 │ -│Label 2 │ -│Label 3 │ -│Label 4 │ -│Label 4 │ -└────────────────────┘", - @" -┌────────────────────┐ -│View with long text │ -│Label 0 │ -│Label 1 │ -│Label 2 │ -│Label 3 │ -│Label 4 │ -│Label 5 │ -│Label 5 │ -└────────────────────┘", - @" -┌────────────────────┐ -│View with long text │ -│Label 0 │ -│Label 1 │ -│Label 2 │ -│Label 3 │ -│Label 4 │ -│Label 5 │ -│Label 6 │ -│Label 6 │ -└────────────────────┘", - @" -┌────────────────────┐ -│View with long text │ -│Label 0 │ -│Label 1 │ -│Label 2 │ -│Label 3 │ -│Label 4 │ -│Label 5 │ -│Label 6 │ -│Label 7 │ -│Label 7 │ -└────────────────────┘", - @" -┌────────────────────┐ -│View with long text │ -│Label 0 │ -│Label 1 │ -│Label 2 │ -│Label 3 │ -│Label 4 │ -│Label 5 │ -│Label 6 │ -│Label 7 │ -│Label 8 │ -│Label 8 │ -└────────────────────┘", - @" -┌────────────────────┐ -│View with long text │ -│Label 0 │ -│Label 1 │ -│Label 2 │ -│Label 3 │ -│Label 4 │ -│Label 5 │ -│Label 6 │ -│Label 7 │ -│Label 8 │ -│Label 9 │ -│Label 9 │ -└────────────────────┘", - @" -┌────────────────────┐ -│View with long text │ -│Label 0 │ -│Label 1 │ -│Label 2 │ -│Label 3 │ -│Label 4 │ -│Label 5 │ -│Label 6 │ -│Label 7 │ -│Label 8 │ -│Label 9 │ -│Label 10 │ -│Label 10 │ -└────────────────────┘", - @" -┌────────────────────┐ -│View with long text │ -│Label 0 │ -│Label 1 │ -│Label 2 │ -│Label 3 │ -│Label 4 │ -│Label 5 │ -│Label 6 │ -│Label 7 │ -│Label 8 │ -│Label 9 │ -│Label 10 │ -│Label 11 │ -│Label 11 │ -└────────────────────┘", - @" -┌────────────────────┐ -│View with long text │ -│Label 0 │ -│Label 1 │ -│Label 2 │ -│Label 3 │ -│Label 4 │ -│Label 5 │ -│Label 6 │ -│Label 7 │ -│Label 8 │ -│Label 9 │ -│Label 10 │ -│Label 11 │ -│Label 12 │ -│Label 12 │ -└────────────────────┘", - @" -┌────────────────────┐ -│View with long text │ -│Label 0 │ -│Label 1 │ -│Label 2 │ -│Label 3 │ -│Label 4 │ -│Label 5 │ -│Label 6 │ -│Label 7 │ -│Label 8 │ -│Label 9 │ -│Label 10 │ -│Label 11 │ -│Label 12 │ -│Label 13 │ -│Label 13 │ -└────────────────────┘", - @" -┌────────────────────┐ -│View with long text │ -│Label 0 │ -│Label 1 │ -│Label 2 │ -│Label 3 │ -│Label 4 │ -│Label 5 │ -│Label 6 │ -│Label 7 │ -│Label 8 │ -│Label 9 │ -│Label 10 │ -│Label 11 │ -│Label 12 │ -│Label 13 │ -│Label 14 │ -│Label 14 │ -└────────────────────┘", - @" -┌────────────────────┐ -│View with long text │ -│Label 0 │ -│Label 1 │ -│Label 2 │ -│Label 3 │ -│Label 4 │ -│Label 5 │ -│Label 6 │ -│Label 7 │ -│Label 8 │ -│Label 9 │ -│Label 10 │ -│Label 11 │ -│Label 12 │ -│Label 13 │ -│Label 14 │ -│Label 15 │ -│Label 15 │ -└────────────────────┘", - @" -┌────────────────────┐ -│View with long text │ -│Label 0 │ -│Label 1 │ -│Label 2 │ -│Label 3 │ -│Label 4 │ -│Label 5 │ -│Label 6 │ -│Label 7 │ -│Label 8 │ -│Label 9 │ -│Label 10 │ -│Label 11 │ -│Label 12 │ -│Label 13 │ -│Label 14 │ -│Label 15 │ -│Label 16 │ -│Label 16 │ -└────────────────────┘", - @" -┌────────────────────┐ -│View with long text │ -│Label 0 │ -│Label 1 │ -│Label 2 │ -│Label 3 │ -│Label 4 │ -│Label 5 │ -│Label 6 │ -│Label 7 │ -│Label 8 │ -│Label 9 │ -│Label 10 │ -│Label 11 │ -│Label 12 │ -│Label 13 │ -│Label 14 │ -│Label 15 │ -│Label 16 │ -│Label 17 │ -│Label 17 │ -└────────────────────┘", - @" -┌────────────────────┐ -│View with long text │ -│Label 0 │ -│Label 1 │ -│Label 2 │ -│Label 3 │ -│Label 4 │ -│Label 5 │ -│Label 6 │ -│Label 7 │ -│Label 8 │ -│Label 9 │ -│Label 10 │ -│Label 11 │ -│Label 12 │ -│Label 13 │ -│Label 14 │ -│Label 15 │ -│Label 16 │ -│Label 17 │ -│Label 18 │ -│Label 18 │ -└────────────────────┘", - @" -┌────────────────────┐ -│View with long text │ -│Label 0 │ -│Label 1 │ -│Label 2 │ -│Label 3 │ -│Label 4 │ -│Label 5 │ -│Label 6 │ -│Label 7 │ -│Label 8 │ -│Label 9 │ -│Label 10 │ -│Label 11 │ -│Label 12 │ -│Label 13 │ -│Label 14 │ -│Label 15 │ -│Label 16 │ -│Label 17 │ -│Label 18 │ -│Label 19 │ -│Label 19 │ -└────────────────────┘" - }; - - // TODO: This is a Label test. Move to label tests if there's not already a test for this. - [Fact] - [AutoInitShutdown] - public void AnchorEnd_Better_Than_Bottom_Equal_Inside_Window () - { - var win = new Window (); - - var label = new Label - { - Text = "This should be the last line.", - - //Width = Dim.Fill (), - X = 0, // keep unit test focused; don't use Center here - Y = Pos.AnchorEnd (1) - }; - - win.Add (label); - - Runnable top = new (); - top.Add (win); - SessionToken rs = Application.Begin (top); - Application.Driver!.SetScreenSize (40, 10); - Application.LayoutAndDraw (); - Assert.Equal (29, label.Text.Length); - Assert.Equal (new (0, 0, 40, 10), top.Frame); - Assert.Equal (new (0, 0, 40, 10), win.Frame); - Assert.Equal (new (0, 7, 29, 1), label.Frame); - - var expected = @" -┌──────────────────────────────────────┐ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│This should be the last line. │ -└──────────────────────────────────────┘ -" - ; - - DriverAssert.AssertDriverContentsWithFrameAre (expected, output); - Application.End (rs); - top.Dispose (); - } - - // TODO: This is a Label test. Move to label tests if there's not already a test for this. - [Fact] - [AutoInitShutdown] - public void Bottom_Equal_Inside_Window () - { - var win = new Window (); - - var label = new Label - { - Text = "This should be the last line.", - - //Width = Dim.Fill (), - X = 0, - Y = Pos.Bottom (win) - - 3 // two lines top and bottom borders more one line above the bottom border - }; - - win.Add (label); - - Runnable top = new (); - top.Add (win); - SessionToken rs = Application.Begin (top); - Application.Driver!.SetScreenSize (40, 10); - Application.LayoutAndDraw (); - Assert.Equal (new (0, 0, 40, 10), top.Frame); - Assert.Equal (new (0, 0, 40, 10), win.Frame); - Assert.Equal (new (0, 7, 29, 1), label.Frame); - - var expected = @" -┌──────────────────────────────────────┐ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│This should be the last line. │ -└──────────────────────────────────────┘ -"; - - DriverAssert.AssertDriverContentsWithFrameAre (expected, output); - Application.End (rs); - top.Dispose (); - } - - // TODO: This is a Dim test. Move to Dim tests. - - [Fact] - [AutoInitShutdown] - public void Dim_Subtract_Operator_With_Text () - { - Runnable top = new (); - - var view = new View - { - Text = "View with long text", - X = 0, - Y = 0, - Width = 20, - Height = 1 - }; - var field = new TextField { X = 0, Y = Pos.Bottom (view), Width = 20 }; - var count = 20; - - List