diff --git a/.github/workflows/build-release.yml b/.github/workflows/build-release.yml new file mode 100644 index 000000000..586c7cb15 --- /dev/null +++ b/.github/workflows/build-release.yml @@ -0,0 +1,34 @@ +name: Ensure that Release builds are not broken + +on: + push: + branches: [ v2_release, v2_develop ] + paths-ignore: + - '**.md' + pull_request: + branches: [ v2_release, v2_develop ] + paths-ignore: + - '**.md' + +jobs: + build_release: + # Ensure that RELEASE builds are not broken + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup .NET Core + uses: actions/setup-dotnet@v4 + with: + dotnet-version: 8.x + dotnet-quality: 'ga' + + - name: Build Release Terminal.Gui + run: dotnet build Terminal.Gui/Terminal.Gui.csproj --configuration Release + + - name: Pack Release Terminal.Gui + run: dotnet pack Terminal.Gui/Terminal.Gui.csproj --configuration Release --output ./local_packages + + - name: Build Release Solution + run: dotnet build --configuration Release diff --git a/.github/workflows/check-duplicates.yml b/.github/workflows/check-duplicates.yml new file mode 100644 index 000000000..f325d3f95 --- /dev/null +++ b/.github/workflows/check-duplicates.yml @@ -0,0 +1,14 @@ +name: Check for Duplicate UnitTests +on: + push: + branches: [ v2_release, v2_develop ] + pull_request: + branches: [ v2_release, v2_develop ] + workflow_dispatch: +jobs: + check-duplicates: + runs-on: windows-latest + steps: + - uses: actions/checkout@v4 + - name: Run Duplicate Test Check + run: pwsh -File ./Scripts/FindDuplicateTestMethodsInSameFileName.ps1 -solutionPath "$PWD" \ No newline at end of file diff --git a/.github/workflows/dotnet-core.yml b/.github/workflows/dotnet-core.yml deleted file mode 100644 index d22eefcfb..000000000 --- a/.github/workflows/dotnet-core.yml +++ /dev/null @@ -1,119 +0,0 @@ -name: Build & Test Terminal.Gui with .NET Core - -on: - push: - branches: [ v2_release, v2_develop ] - paths-ignore: - - '**.md' - pull_request: - branches: [ v2_release, v2_develop ] - paths-ignore: - - '**.md' - -jobs: - build_and_test_debug: - - runs-on: ${{ matrix.os }} - strategy: - # Turn off fail-fast to let all runners run even if there are errors - fail-fast: true - matrix: - os: [ ubuntu-latest, windows-latest, macos-latest ] - - timeout-minutes: 10 - steps: - -# Build (Debug) - - - name: Checkout code - uses: actions/checkout@v4 - - - name: Setup .NET Core - uses: actions/setup-dotnet@v4 - with: - dotnet-version: 8.x - dotnet-quality: 'ga' - - - name: Install dependencies - run: | - dotnet restore - - - name: Build Debug - run: dotnet build --configuration Debug --no-restore - -# Test - # Note: The --blame and VSTEST_DUMP_PATH stuff is needed to diagnose the test runner crashing on ubuntu/mac - # See https://github.com/microsoft/vstest/issues/2952 for why the --blame stuff below is needed. - # Without it, the test runner crashes on ubuntu (but not Windows or mac) - - - name: MacOS - Patch test runner settings to stop on fail - if: runner.os == 'macOS' - run: | - brew install gnu-sed - gsed -i 's/"stopOnFail": false/"stopOnFail": true/g' UnitTests/xunit.runner.json - - - name: Windows/Linux - Patch test runner settings to stop on fail - if: runner.os != 'macOS' - run: | - sed -i 's/"stopOnFail": false/"stopOnFail": true/g' UnitTests/xunit.runner.json - - - name: Set VSTEST_DUMP_PATH - shell: bash - run: echo "{VSTEST_DUMP_PATH}={logs/${{ runner.os }}/}" >> $GITHUB_ENV - - - name: Test - run: | - dotnet test --verbosity normal --collect:"XPlat Code Coverage" --settings UnitTests/coverlet.runsettings --diag:logs/${{ runner.os }}/logs.txt --blame --blame-crash --blame-hang --blame-hang-timeout 60s --blame-crash-collect-always - - # mv -v UnitTests/TestResults/*/*.* UnitTests/TestResults/ - - - name: Upload Test Logs - if: always() - uses: actions/upload-artifact@v4 - with: - name: test-logs-${{ runner.os }} - path: | - logs/ - UnitTests/TestResults/ - - - build_release: - # Ensure that RELEASE builds are not broken - runs-on: ubuntu-latest - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Setup .NET Core - uses: actions/setup-dotnet@v4 - with: - dotnet-version: 8.x - dotnet-quality: 'ga' - - - name: Build Release Terminal.Gui - run: dotnet build Terminal.Gui/Terminal.Gui.csproj --configuration Release - - - name: Pack Release Terminal.Gui - run: dotnet pack Terminal.Gui/Terminal.Gui.csproj --configuration Release --output ./local_packages - - - name: Build Release Solution - run: dotnet build --configuration Release - - - # Note: this step is currently not writing to the gist for some reason - # - name: Create Test Coverage Badge - # uses: simon-k/dotnet-code-coverage-badge@v1.0.0 - # id: create_coverage_badge - # with: - # label: Unit Test Coverage - # color: brightgreen - # path: UnitTests/TestResults/coverage.opencover.xml - # gist-filename: code-coverage.json - # # https://gist.github.com/migueldeicaza/90ef67a684cb71db1817921a970f8d27 - # gist-id: 90ef67a684cb71db1817921a970f8d27 - # gist-auth-token: ${{ secrets.GIST_AUTH_TOKEN }} - - # - name: Print Code Coverage - # run: | - # echo "Code coverage percentage: ${{steps.create_coverage_badge.outputs.percentage}}%" - # echo "Badge data: ${{steps.create_coverage_badge.outputs.badge}}" diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml new file mode 100644 index 000000000..e0cb43025 --- /dev/null +++ b/.github/workflows/integration-tests.yml @@ -0,0 +1,60 @@ +name: Build & Run Integration Tests + +on: + push: + branches: [ v2_release, v2_develop ] + paths-ignore: + - '**.md' + pull_request: + branches: [ v2_release, v2_develop ] + paths-ignore: + - '**.md' + +jobs: + build_and_test_debug: + + runs-on: ${{ matrix.os }} + strategy: + # Turn off fail-fast to let all runners run even if there are errors + fail-fast: true + matrix: + os: [ ubuntu-latest, windows-latest, macos-latest ] + + timeout-minutes: 10 + steps: + + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup .NET Core + uses: actions/setup-dotnet@v4 + with: + dotnet-version: 8.x + dotnet-quality: 'ga' + + - name: Install dependencies + run: | + dotnet restore + + - name: Build IntegrationTests + run: dotnet build Tests/IntegrationTests --configuration Debug --no-restore + + - name: Set VSTEST_DUMP_PATH + shell: bash + run: echo "{VSTEST_DUMP_PATH}={logs/${{ runner.os }}/}" >> $GITHUB_ENV + + - name: Run IntegrationTests + run: | + dotnet test Tests/IntegrationTests --no-build --verbosity normal --diag:logs/${{ runner.os }}/logs.txt --blame --blame-crash --blame-hang --blame-hang-timeout 60s --blame-crash-collect-always -- xunit.stopOnFail=true + + # mv -v Tests/IntegrationTests/TestResults/*/*.* TestResults/IntegrationTests/ + + - name: Upload Test Logs + if: always() + uses: actions/upload-artifact@v4 + with: + name: integration-test-logs-${{ runner.os }} + path: | + logs/ + TestResults/IntegrationTests/ + diff --git a/.github/workflows/stress-tests.yml b/.github/workflows/stress-tests.yml new file mode 100644 index 000000000..6592f2510 --- /dev/null +++ b/.github/workflows/stress-tests.yml @@ -0,0 +1,51 @@ +name: Run StressTests (for 15 minutes) + +on: + schedule: + - cron: '0 0 * * *' # Runs every day at midnight UTC + push: + branches: [ v2_release, v2_develop ] + paths-ignore: + - '**.md' + +jobs: + run_stress_tests: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ ubuntu-latest ] + + timeout-minutes: 70 # Allow some buffer time beyond the 1-hour test duration + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup .NET Core + uses: actions/setup-dotnet@v4 + with: + dotnet-version: 8.x + dotnet-quality: 'ga' + + - name: Install dependencies + run: dotnet restore + + - name: Build StressTests + run: dotnet build Tests/StressTests --configuration Debug --no-restore + + - name: Run StressTests for 15 minutes + run: | + end=$((SECONDS+900)) + while [ $SECONDS -lt $end ]; do + dotnet test Tests/StressTests --no-build --verbosity normal --diag:logs/${{ runner.os }}/logs.txt --blame --blame-crash --blame-hang --blame-hang-timeout 60s --blame-crash-collect-always -- xunit.stopOnFail=true + done + + - name: Upload Test Logs + if: always() + uses: actions/upload-artifact@v4 + with: + name: stress-test-logs-${{ runner.os }} + path: | + logs/ + TestResults/StressTests + diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml new file mode 100644 index 000000000..6fb66961c --- /dev/null +++ b/.github/workflows/unit-tests.yml @@ -0,0 +1,116 @@ +name: Build & Run Unit Tests + +on: + push: + branches: [ v2_release, v2_develop ] + paths-ignore: + - '**.md' + pull_request: + branches: [ v2_release, v2_develop ] + paths-ignore: + - '**.md' + +jobs: + non_parallel_unittests: + name: Non-Parallel Unit Tests + runs-on: ${{ matrix.os }} + strategy: + # Turn off fail-fast to let all runners run even if there are errors + fail-fast: true + matrix: + os: [ ubuntu-latest, windows-latest, macos-latest ] + + timeout-minutes: 10 + steps: + + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup .NET Core + uses: actions/setup-dotnet@v4 + with: + dotnet-version: 8.x + dotnet-quality: 'ga' + + - name: Install dependencies + run: | + dotnet restore + + - name: Build Solution Debug + run: dotnet build --configuration Debug --no-restore + +# Test + # Note: The --blame and VSTEST_DUMP_PATH stuff is needed to diagnose the test runner crashing on ubuntu/mac + # See https://github.com/microsoft/vstest/issues/2952 for why the --blame stuff below is needed. + # Without it, the test runner crashes on ubuntu (but not Windows or mac) + + - name: Set VSTEST_DUMP_PATH + shell: bash + run: echo "{VSTEST_DUMP_PATH}={logs/UnitTests/${{ runner.os }}/}" >> $GITHUB_ENV + + - name: Run UnitTests + run: | + dotnet test Tests/UnitTests --no-build --verbosity normal --collect:"XPlat Code Coverage" --settings Tests/UnitTests/coverlet.runsettings --diag:logs/UnitTests/${{ runner.os }}/logs.txt --blame --blame-crash --blame-hang --blame-hang-timeout 60s --blame-crash-collect-always -- xunit.stopOnFail=true + + # mv -v Tests/UnitTests/TestResults/*/*.* TestResults/UnitTests/ + + - name: Upload Test Logs + if: always() + uses: actions/upload-artifact@v4 + with: + name: non_parallel_unittests-logs-${{ runner.os }} + path: | + logs/UnitTests + TestResults/UnitTests/ + + parallel_unittests: + name: Parallel Unit Tests + runs-on: ${{ matrix.os }} + strategy: + # Turn off fail-fast to let all runners run even if there are errors + fail-fast: true + matrix: + os: [ ubuntu-latest, windows-latest, macos-latest ] + + timeout-minutes: 10 + steps: + + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup .NET Core + uses: actions/setup-dotnet@v4 + with: + dotnet-version: 8.x + dotnet-quality: 'ga' + + - name: Install dependencies + run: | + dotnet restore + + - name: Build Solution Debug + run: dotnet build --configuration Debug --no-restore + +# Test + # Note: The --blame and VSTEST_DUMP_PATH stuff is needed to diagnose the test runner crashing on ubuntu/mac + # See https://github.com/microsoft/vstest/issues/2952 for why the --blame stuff below is needed. + # Without it, the test runner crashes on ubuntu (but not Windows or mac) + + - name: Set VSTEST_DUMP_PATH + shell: bash + run: echo "{VSTEST_DUMP_PATH}={logs/UnitTestsParallelizable/${{ runner.os }}/}" >> $GITHUB_ENV + + - name: Run UnitTestsParallelizable + run: | + dotnet test Tests/UnitTestsParallelizable --no-build --verbosity normal --collect:"XPlat Code Coverage" --settings Tests/UnitTestsParallelizable/coverlet.runsettings --diag:logs/UnitTestsParallelizable/${{ runner.os }}/logs.txt --blame --blame-crash --blame-hang --blame-hang-timeout 60s --blame-crash-collect-always -- xunit.stopOnFail=true + + # mv -v Tests/UnitTestsParallelizable/TestResults/*/*.* TestResults/UnitTestsParallelizable/ + + - name: Upload UnitTestsParallelizable Logs + if: always() + uses: actions/upload-artifact@v4 + with: + name: parallel_unittests-logs-${{ runner.os }} + path: | + logs/UnitTestsParallelizable/ + TestResults/UnitTestsParallelizable/ diff --git a/.gitignore b/.gitignore index 14e25a86c..99f085cf5 100644 --- a/.gitignore +++ b/.gitignore @@ -60,3 +60,5 @@ demo.* *.dotCover logs/ + +log.* \ No newline at end of file diff --git a/Benchmarks/Benchmarks.csproj b/Benchmarks/Benchmarks.csproj index 62f1be76c..369ee89ec 100644 --- a/Benchmarks/Benchmarks.csproj +++ b/Benchmarks/Benchmarks.csproj @@ -2,15 +2,13 @@ Exe - net8.0 false - enable enable Terminal.Gui.$(MSBuildProjectName.Replace(" ", "_")) - + diff --git a/CommunityToolkitExample/CommunityToolkitExample.csproj b/CommunityToolkitExample/CommunityToolkitExample.csproj index 8a25e7c31..13ed59966 100644 --- a/CommunityToolkitExample/CommunityToolkitExample.csproj +++ b/CommunityToolkitExample/CommunityToolkitExample.csproj @@ -2,14 +2,12 @@ Exe - net8.0 - enable enable - - + + diff --git a/example_config.json b/DemoFiles/example_config.json similarity index 100% rename from example_config.json rename to DemoFiles/example_config.json diff --git a/Directory.Build.props b/Directory.Build.props new file mode 100644 index 000000000..dfd0c8b78 --- /dev/null +++ b/Directory.Build.props @@ -0,0 +1,11 @@ + + + net8.0 + enable + + 12 + + + false + + \ No newline at end of file diff --git a/Directory.Packages.props b/Directory.Packages.props new file mode 100644 index 000000000..8ad412965 --- /dev/null +++ b/Directory.Packages.props @@ -0,0 +1,52 @@ + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Example/Example.csproj b/Example/Example.csproj index 4bb8cc0bc..be1d5c035 100644 --- a/Example/Example.csproj +++ b/Example/Example.csproj @@ -1,7 +1,6 @@  Exe - net8.0 diff --git a/GitVersion.yml b/GitVersion.yml index 78d807140..9b976f1c5 100644 --- a/GitVersion.yml +++ b/GitVersion.yml @@ -1,10 +1,9 @@ -mode: ContinuousDeployment +workflow: GitFlow/v1 tag-prefix: '[vV]' -continuous-delivery-fallback-tag: dev branches: develop: mode: ContinuousDeployment - tag: develop + label: develop regex: v2_develop tracks-release-branches: true is-source-branch-for: ['main'] @@ -12,14 +11,14 @@ branches: main: mode: ContinuousDeployment - tag: prealpha + label: prealpha regex: v2_release is-release-branch: true source-branches: ['develop'] v1_develop: mode: ContinuousDeployment - tag: v1_develop + label: v1_develop regex: v1_develop source-branches: - v1_release @@ -33,9 +32,9 @@ branches: pull-request: mode: ContinuousDeployment - tag: PullRequest.{BranchName} + label: PullRequest.{BranchName} increment: Inherit - tag-number-pattern: '[/-](?\d+)' + label-number-pattern: '[/-](?\d+)' regex: ^(pull|pull\-requests|pr)[/-] source-branches: - develop @@ -56,13 +55,13 @@ ignore: # branches: # # v1_develop: # # mode: ContinuousDeployment -# # tag: pre +# # label: pre # # regex: ^v1_develop?[/-] # # is-release-branch: false # # source-branches: # # - v1 # # v1: -# # tag: rc +# # label: rc # # increment: Patch # # regex: ^v2?[/-] # # is-release-branch: false @@ -71,7 +70,7 @@ ignore: # v2_develop: # mode: ContinuousDeployment -# tag: pre +# label: pre # regex: ^v2_develop?[/-] # is-release-branch: true # tracks-release-branches: true @@ -80,13 +79,13 @@ ignore: # v2: # mode: ContinuousDeployment # is-release-branch: false -# tag: alpha +# label: alpha # increment: Patch # regex: ^v2?[/-] # source-branches: ['v2_develop'] # # feature: -# # tag: useBranchName +# # label: useBranchName # # regex: ^features?[/-] # # source-branches: # # - v1 @@ -95,7 +94,7 @@ ignore: # # - v2_develop # pull-request: -# tag: PullRequest.{BranchName} +# label: PullRequest.{BranchName} # increment: Inherit # ignore: # sha: [] diff --git a/NativeAot/NativeAot.csproj b/NativeAot/NativeAot.csproj index 4f5238a9d..2dffeb5af 100644 --- a/NativeAot/NativeAot.csproj +++ b/NativeAot/NativeAot.csproj @@ -2,8 +2,6 @@ Exe - net8.0 - enable enable true false @@ -15,7 +13,7 @@ - + diff --git a/NoSamples.slnf b/NoSamples.slnf index 8d2a38dad..60dfeeede 100644 --- a/NoSamples.slnf +++ b/NoSamples.slnf @@ -4,7 +4,10 @@ "projects": [ "Terminal.Gui\\Terminal.Gui.csproj", "UICatalog\\UICatalog.csproj", - "UnitTests\\UnitTests.csproj" - ] + "Tests\\UnitTests\\UnitTests.csproj", + "Tests\\UnitTestsParallelizable\\UnitTests.Parallelizable.csproj", + "Tests\\IntegrationTests\\IntegrationTests.csproj", + "Tests\\StressTests\\StressTests.csproj" + ] } } \ No newline at end of file diff --git a/ReactiveExample/ReactiveExample.csproj b/ReactiveExample/ReactiveExample.csproj index 178b14b66..0e61fcdbb 100644 --- a/ReactiveExample/ReactiveExample.csproj +++ b/ReactiveExample/ReactiveExample.csproj @@ -1,7 +1,6 @@  Exe - net8.0 @@ -11,9 +10,9 @@ 2.0 - - - + + + diff --git a/Release.slnf b/Release.slnf index 8d2a38dad..c87196ae5 100644 --- a/Release.slnf +++ b/Release.slnf @@ -4,7 +4,10 @@ "projects": [ "Terminal.Gui\\Terminal.Gui.csproj", "UICatalog\\UICatalog.csproj", - "UnitTests\\UnitTests.csproj" + "Tests\\UnitTests\\UnitTests.csproj", + "Tests\\UnitTestsParallelizable\\UnitTests.Parallelizable.csproj", + "Tests\\IntegrationTests\\IntegrationTests.csproj", + "Tests\\StressTests\\StressTests.csproj" ] } } \ No newline at end of file diff --git a/Scripts/.testloop.sh.swp b/Scripts/.testloop.sh.swp new file mode 100644 index 000000000..d219228cc Binary files /dev/null and b/Scripts/.testloop.sh.swp differ diff --git a/Scripts/FindDuplicateTestMethodsInSameFileName.ps1 b/Scripts/FindDuplicateTestMethodsInSameFileName.ps1 new file mode 100644 index 000000000..b5807b760 --- /dev/null +++ b/Scripts/FindDuplicateTestMethodsInSameFileName.ps1 @@ -0,0 +1,92 @@ +# FindDuplicateTestMethodsInSameFileName.ps1 +param ( + [string]$solutionPath = ".\Tests" +) + +# Set the base path for relative paths (current directory when script is run) +$basePath = Get-Location + +# Define projects to ignore (add your project names or path patterns here) +$ignoreProjects = @( + "StressTests" + # Add more as needed, e.g., "Tests/SubFolder/OldProject" +) + +# Function to extract method names from a C# file +function Get-TestMethodNames { + param ($filePath) + $content = Get-Content -Path $filePath -Raw + $testMethods = @() + + # Match test attributes and capture method names with flexible spacing/comments + $methodPattern = '(?s)(\[TestMethod\]|\[Test\]|\[Fact\]|\[Theory\])\s*[\s\S]*?public\s+(?:void|Task)\s+(\w+)\s*\(' + $methods = [regex]::Matches($content, $methodPattern) + + foreach ($match in $methods) { + $methodName = $match.Groups[2].Value # Group 2 is the method name + if ($methodName) { # Ensure we only add non-empty method names + $testMethods += $methodName + } + } + return $testMethods +} + +# Collect all test files +$testFiles = Get-ChildItem -Path $solutionPath -Recurse -Include *.cs | + Where-Object { $_.FullName -match "Tests" -or $_.FullName -match "Test" } + +# Group files by filename +$fileGroups = $testFiles | Group-Object -Property Name + +# Dictionary to track method names and their locations, scoped to same filenames +$duplicates = @{} + +foreach ($group in $fileGroups) { + if ($group.Count -gt 1) { # Only process files that exist in multiple locations + $fileName = $group.Name + $methodMap = @{} # Track methods for this specific filename + + foreach ($file in $group.Group) { + # Skip files in ignored projects + $skipFile = $false + foreach ($ignore in $ignoreProjects) { + if ($file.FullName -like "*$ignore*") { + $skipFile = $true + break + } + } + if ($skipFile) { continue } + + $methods = Get-TestMethodNames -filePath $file.FullName + foreach ($method in $methods) { + if ($methodMap.ContainsKey($method)) { + # Duplicate found for this method in the same filename + if (-not $duplicates.ContainsKey($method)) { + $duplicates[$method] = @($methodMap[$method]) + } + $duplicates[$method] += $file.FullName + } else { + $methodMap[$method] = $file.FullName + } + } + } + } +} + +# Output results with relative paths +if ($duplicates.Count -eq 0) { + Write-Host "No duplicate test method names found in files with the same name across projects." -ForegroundColor Green +} else { + Write-Host "Duplicate test method names found in files with the same name across projects:" -ForegroundColor Yellow + foreach ($dup in $duplicates.Keys) { + Write-Host "Method: $dup" -ForegroundColor Cyan + foreach ($fullPath in $duplicates[$dup]) { + $relativePath = Resolve-Path -Path $fullPath -Relative -RelativeBasePath $basePath + Write-Host " - $relativePath" -ForegroundColor White + } + } + # Display total number of duplicate methods + Write-Host "Total number of duplicate methods: $($duplicates.Count)" -ForegroundColor Magenta + # Fail the pipeline by setting a non-zero exit code + exit 1 +} \ No newline at end of file diff --git a/Scripts/FindDuplicateTests.ps1 b/Scripts/FindDuplicateTests.ps1 new file mode 100644 index 000000000..2e7335a5f --- /dev/null +++ b/Scripts/FindDuplicateTests.ps1 @@ -0,0 +1,50 @@ +# Define the root directory containing test projects +$testsDir = "./Tests" + +# Get all subfolders in the ./Tests directory +$subfolders = Get-ChildItem -Directory $testsDir + +# Initialize a hashtable to track method names and their associated subfolders +$methodMap = @{} + +# Iterate through each subfolder +foreach ($subfolder in $subfolders) { + $subfolderName = $subfolder.Name + + # Run dotnet test --list-tests to get the list of tests in the subfolder + $output = dotnet test $subfolder.FullName --list-tests | Out-String + + # Split the output into lines and filter for lines containing a dot (indicative of test names) + $testLines = $output -split "`n" | Where-Object { $_ -match "\." } + + # Process each test line to extract the method name + foreach ($testLine in $testLines) { + $trimmed = $testLine.Trim() + $parts = $trimmed -split "\." + $lastPart = $parts[-1] + + # Handle parameterized tests by extracting the method name before any parentheses + if ($lastPart -match "\(") { + $methodName = $lastPart.Substring(0, $lastPart.IndexOf("(")) + } else { + $methodName = $lastPart + } + + # Update the hashtable with the method name and subfolder + if ($methodMap.ContainsKey($methodName)) { + # Add the subfolder only if it’s not already listed for this method name + if (-not ($methodMap[$methodName] -contains $subfolderName)) { + $methodMap[$methodName] += $subfolderName + } + } else { + $methodMap[$methodName] = @($subfolderName) + } + } +} + +# Identify and display duplicated test method names +foreach ($entry in $methodMap.GetEnumerator()) { + if ($entry.Value.Count -gt 1) { + Write-Output "Duplicated test: $($entry.Key) in folders: $($entry.Value -join ', ')" + } +} diff --git a/Scripts/testloop.sh b/Scripts/testloop.sh new file mode 100755 index 000000000..936764ab3 --- /dev/null +++ b/Scripts/testloop.sh @@ -0,0 +1,30 @@ +#!/bin/bash + +# This script runs the tests in a loop until they all pass. +# It will exit if any test run fails. + +dotnet build -c Debug + +iterationCount=1 + +while true; do + echo "Starting iteration $iterationCount..." + + dotnet test Tests/UnitTests --no-build --diag:TestResults/UnitTests.log -- xunit.stopOnFail=true + if [ $? -ne 0 ]; then + echo "UnitTests run failed on iteration $iterationCount. Exiting." + exit 1 + fi + + dotnet test Tests/UnitTestsParallelizable --no-build --diag:TestResults/UnitTestsParallelizable.log -- xunit.stopOnFail=true + if [ $? -ne 0 ]; then + echo "UnitTestsParallelizable run failed on iteration $iterationCount. Exiting." + exit 1 + fi + + # Clean up the log files + rm log* + + # Increment the iteration counter + ((iterationCount++)) +done \ No newline at end of file diff --git a/SelfContained/SelfContained.csproj b/SelfContained/SelfContained.csproj index 46800e09c..3aec661bc 100644 --- a/SelfContained/SelfContained.csproj +++ b/SelfContained/SelfContained.csproj @@ -2,8 +2,6 @@ Exe - net8.0 - enable enable true Link @@ -18,7 +16,7 @@ - + diff --git a/Terminal.Gui/Application/Application.Mouse.cs b/Terminal.Gui/Application/Application.Mouse.cs index 176e85d35..01bdcc1a3 100644 --- a/Terminal.Gui/Application/Application.Mouse.cs +++ b/Terminal.Gui/Application/Application.Mouse.cs @@ -62,7 +62,10 @@ public static partial class Application // Mouse handling } #if DEBUG_IDISPOSABLE - ObjectDisposedException.ThrowIf (MouseGrabView.WasDisposed, MouseGrabView); + if (View.DebugIDisposable) + { + ObjectDisposedException.ThrowIf (MouseGrabView.WasDisposed, MouseGrabView); + } #endif if (!RaiseUnGrabbingMouseEvent (MouseGrabView)) @@ -150,7 +153,7 @@ public static partial class Application // Mouse handling if (deepestViewUnderMouse is { }) { #if DEBUG_IDISPOSABLE - if (deepestViewUnderMouse.WasDisposed) + if (View.DebugIDisposable && deepestViewUnderMouse.WasDisposed) { throw new ObjectDisposedException (deepestViewUnderMouse.GetType ().FullName); } @@ -278,7 +281,7 @@ public static partial class Application // Mouse handling if (MouseGrabView is { }) { #if DEBUG_IDISPOSABLE - if (MouseGrabView.WasDisposed) + if (View.DebugIDisposable && MouseGrabView.WasDisposed) { throw new ObjectDisposedException (MouseGrabView.GetType ().FullName); } diff --git a/Terminal.Gui/Application/Application.Run.cs b/Terminal.Gui/Application/Application.Run.cs index 6906efd90..5bfa5f2cc 100644 --- a/Terminal.Gui/Application/Application.Run.cs +++ b/Terminal.Gui/Application/Application.Run.cs @@ -1,8 +1,6 @@ #nullable enable using System.Diagnostics; using System.Diagnostics.CodeAnalysis; -using System.Text.Json.Serialization; -using Microsoft.CodeAnalysis.Diagnostics; namespace Terminal.Gui; @@ -27,7 +25,6 @@ public static partial class Application // Run (Begin, Run, End, Stop) private static Key _arrangeKey = Key.F5.WithCtrl; // Resources/config.json overrides - /// Gets or sets the key to activate arranging views using the keyboard. [SerializableConfigurationProperty (Scope = typeof (SettingsScope))] public static Key ArrangeKey @@ -97,7 +94,7 @@ public static partial class Application // Run (Begin, Run, End, Stop) var rs = new RunState (toplevel); #if DEBUG_IDISPOSABLE - if (Top is { } && toplevel != Top && !TopLevels.Contains (Top)) + if (View.DebugIDisposable && Top is { } && toplevel != Top && !TopLevels.Contains (Top)) { // This assertion confirm if the Top was already disposed Debug.Assert (Top.WasDisposed); @@ -174,7 +171,7 @@ public static partial class Application // Run (Begin, Run, End, Stop) // Force leave events for any entered views in the old Top if (GetLastMousePosition () is { }) { - RaiseMouseEnterLeaveEvents (GetLastMousePosition ()!.Value, new List ()); + RaiseMouseEnterLeaveEvents (GetLastMousePosition ()!.Value, new ()); } Top?.OnDeactivate (toplevel); @@ -208,7 +205,7 @@ public static partial class Application // Run (Begin, Run, End, Stop) NotifyNewRunState?.Invoke (toplevel, new (rs)); // Force an Idle event so that an Iteration (and Refresh) happen. - Application.Invoke (() => { }); + Invoke (() => { }); return rs; } @@ -231,7 +228,7 @@ public static partial class Application // Run (Begin, Run, End, Stop) // If the view is not visible or enabled, don't position the cursor if (mostFocused is null || !mostFocused.Visible || !mostFocused.Enabled) { - CursorVisibility current = CursorVisibility.Invisible; + var current = CursorVisibility.Invisible; Driver?.GetCursorVisibility (out current); if (current != CursorVisibility.Invisible) @@ -244,7 +241,9 @@ public static partial class Application // Run (Begin, Run, End, Stop) // If the view is not visible within it's superview, don't position the cursor Rectangle mostFocusedViewport = mostFocused.ViewportToScreen (mostFocused.Viewport with { Location = Point.Empty }); - Rectangle superViewViewport = mostFocused.SuperView?.ViewportToScreen (mostFocused.SuperView.Viewport with { Location = Point.Empty }) ?? Driver!.Screen; + + Rectangle superViewViewport = + mostFocused.SuperView?.ViewportToScreen (mostFocused.SuperView.Viewport with { Location = Point.Empty }) ?? Driver!.Screen; if (!superViewViewport.IntersectsWith (mostFocusedViewport)) { @@ -305,8 +304,10 @@ public static partial class Application // Run (Begin, Run, End, Stop) /// The created object. The caller is responsible for disposing this object. [RequiresUnreferencedCode ("AOT")] [RequiresDynamicCode ("AOT")] - public static Toplevel Run (Func? errorHandler = null, IConsoleDriver? driver = null) => - ApplicationImpl.Instance.Run (errorHandler, driver); + public static Toplevel Run (Func? errorHandler = null, IConsoleDriver? driver = null) + { + return ApplicationImpl.Instance.Run (errorHandler, driver); + } /// /// Runs the application by creating a -derived object of type T and calling @@ -332,7 +333,10 @@ public static partial class Application // Run (Begin, Run, End, Stop) [RequiresUnreferencedCode ("AOT")] [RequiresDynamicCode ("AOT")] public static T Run (Func? errorHandler = null, IConsoleDriver? driver = null) - where T : Toplevel, new() => ApplicationImpl.Instance.Run (errorHandler, driver); + where T : Toplevel, new () + { + return ApplicationImpl.Instance.Run (errorHandler, driver); + } /// Runs the Application using the provided view. /// @@ -356,7 +360,8 @@ public static partial class Application // Run (Begin, Run, End, Stop) /// method will only process any pending events, timers, idle handlers and then /// return control immediately. /// - /// When using or + /// + /// When using or /// /// will be called automatically. /// @@ -372,8 +377,7 @@ public static partial class Application // Run (Begin, Run, End, Stop) /// RELEASE builds only: Handler for any unhandled exceptions (resumes when returns true, /// rethrows when null). /// - public static void Run (Toplevel view, Func? errorHandler = null) - => ApplicationImpl.Instance.Run (view, errorHandler); + public static void Run (Toplevel view, Func? errorHandler = null) { ApplicationImpl.Instance.Run (view, errorHandler); } /// Adds a timeout to the application. /// @@ -381,7 +385,7 @@ public static partial class Application // Run (Begin, Run, End, Stop) /// reset, repeating the invocation. If it returns false, the timeout will stop and be removed. The returned value is a /// token that can be used to stop the timeout by calling . /// - public static object? AddTimeout (TimeSpan time, Func callback) => ApplicationImpl.Instance.AddTimeout (time, callback); + public static object? AddTimeout (TimeSpan time, Func callback) { return ApplicationImpl.Instance.AddTimeout (time, callback); } /// Removes a previously scheduled timeout /// The token parameter is the value returned by . @@ -393,11 +397,11 @@ public static partial class Application // Run (Begin, Run, End, Stop) /// This method also returns /// /// if the timeout is not found. - public static bool RemoveTimeout (object token) => ApplicationImpl.Instance.RemoveTimeout (token); + public static bool RemoveTimeout (object token) { return ApplicationImpl.Instance.RemoveTimeout (token); } /// Runs on the thread that is processing events /// the action to be invoked on the main processing thread. - public static void Invoke (Action action) => ApplicationImpl.Instance.Invoke (action); + public static void Invoke (Action action) { ApplicationImpl.Instance.Invoke (action); } // TODO: Determine if this is really needed. The only code that calls WakeUp I can find // is ProgressBarStyles, and it's not clear it needs to. @@ -406,14 +410,15 @@ public static partial class Application // Run (Begin, Run, End, Stop) public static void Wakeup () { MainLoop?.Wakeup (); } /// - /// Causes any Toplevels that need layout to be laid out. Then draws any Toplevels that need display. Only Views that need to be laid out (see ) will be laid out. - /// Only Views that need to be drawn (see ) will be drawn. + /// Causes any Toplevels that need layout to be laid out. Then draws any Toplevels that need display. Only Views that + /// need to be laid out (see ) will be laid out. + /// Only Views that need to be drawn (see ) will be drawn. /// - /// If the entire View hierarchy will be redrawn. The default is and should only be overriden for testing. - public static void LayoutAndDraw (bool forceDraw = false) - { - ApplicationImpl.Instance.LayoutAndDraw (forceDraw); - } + /// + /// If the entire View hierarchy will be redrawn. The default is and + /// should only be overriden for testing. + /// + public static void LayoutAndDraw (bool forceDraw = false) { ApplicationImpl.Instance.LayoutAndDraw (forceDraw); } internal static void LayoutAndDrawImpl (bool forceDraw = false) { @@ -424,6 +429,7 @@ public static partial class Application // Run (Begin, Run, End, Stop) forceDraw = true; ClearScreenNextIteration = false; } + if (forceDraw) { Driver?.ClearContents (); @@ -431,7 +437,7 @@ public static partial class Application // Run (Begin, Run, End, Stop) View.SetClipToScreen (); View.Draw (TopLevels, neededLayout || forceDraw); - View.SetClipToScreen (); + View.SetClipToScreen (); Driver?.Refresh (); } @@ -521,11 +527,13 @@ public static partial class Application // Run (Begin, Run, End, Stop) /// /// This will cause to return. /// - /// Calling is equivalent to setting the + /// Calling is equivalent to setting the + /// /// property on the currently running to false. /// /// - public static void RequestStop (Toplevel? top = null) => ApplicationImpl.Instance.RequestStop (top); + public static void RequestStop (Toplevel? top = null) { ApplicationImpl.Instance.RequestStop (top); } + internal static void OnNotifyStopRunState (Toplevel top) { if (EndAfterFirstIteration) diff --git a/Terminal.Gui/Application/Application.cs b/Terminal.Gui/Application/Application.cs index a493f3056..9ea1b4504 100644 --- a/Terminal.Gui/Application/Application.cs +++ b/Terminal.Gui/Application/Application.cs @@ -63,7 +63,7 @@ public static partial class Application { Rune rune = contents [r, c].Rune; - if (rune.DecodeSurrogatePair (out char [] sp)) + if (rune.DecodeSurrogatePair (out char []? sp)) { sb.Append (sp); } @@ -152,7 +152,7 @@ public static partial class Application #if DEBUG_IDISPOSABLE // Don't dispose the Top. It's up to caller dispose it - if (!ignoreDisposed && Top is { }) + if (View.DebugIDisposable && !ignoreDisposed && Top is { }) { Debug.Assert (Top.WasDisposed); @@ -173,6 +173,7 @@ public static partial class Application MainThreadId = -1; Iteration = null; EndAfterFirstIteration = false; + ClearScreenNextIteration = false; // Driver stuff if (Driver is { }) @@ -212,7 +213,6 @@ public static partial class Application Navigation = null; - ClearScreenNextIteration = false; KeyBindings.Clear (); AddKeyBindings (); diff --git a/Terminal.Gui/Application/ApplicationImpl.cs b/Terminal.Gui/Application/ApplicationImpl.cs index 49e1d4b52..8bbc17ccb 100644 --- a/Terminal.Gui/Application/ApplicationImpl.cs +++ b/Terminal.Gui/Application/ApplicationImpl.cs @@ -176,7 +176,10 @@ public class ApplicationImpl : IApplication if (runState.Toplevel is null) { #if DEBUG_IDISPOSABLE - Debug.Assert (Application.TopLevels.Count == 0); + if (View.DebugIDisposable) + { + Debug.Assert (Application.TopLevels.Count == 0); + } #endif runState.Dispose (); diff --git a/Terminal.Gui/Application/RunState.cs b/Terminal.Gui/Application/RunState.cs index 0c1387ff8..e0b6fdc30 100644 --- a/Terminal.Gui/Application/RunState.cs +++ b/Terminal.Gui/Application/RunState.cs @@ -22,7 +22,10 @@ public class RunState : IDisposable Dispose (true); GC.SuppressFinalize (this); #if DEBUG_IDISPOSABLE - WasDisposed = true; + if (View.DebugIDisposable) + { + WasDisposed = true; + } #endif } @@ -52,6 +55,12 @@ public class RunState : IDisposable public static List Instances = new (); /// Creates a new RunState object. - public RunState () { Instances.Add (this); } + public RunState () + { + if (View.DebugIDisposable) + { + Instances.Add (this); + } + } #endif } diff --git a/Terminal.Gui/Configuration/ConfigurationManager.cs b/Terminal.Gui/Configuration/ConfigurationManager.cs index 676f68251..2326c028e 100644 --- a/Terminal.Gui/Configuration/ConfigurationManager.cs +++ b/Terminal.Gui/Configuration/ConfigurationManager.cs @@ -326,6 +326,9 @@ public static class ConfigurationManager } + /// + /// Logs any Json deserialization errors that occurred during deserialization to the logging system. + /// public static void LogJsonErrors () { if (_jsonErrors.Length > 0) diff --git a/Terminal.Gui/Configuration/ScopeJsonConverter.cs b/Terminal.Gui/Configuration/ScopeJsonConverter.cs index 11e83c6f7..d1d6e475e 100644 --- a/Terminal.Gui/Configuration/ScopeJsonConverter.cs +++ b/Terminal.Gui/Configuration/ScopeJsonConverter.cs @@ -91,7 +91,7 @@ internal class ScopeJsonConverter<[DynamicallyAccessedMembers (DynamicallyAccess scope! [propertyName].PropertyValue = JsonSerializer.Deserialize (ref reader, propertyType!, SerializerContext); } - catch (Exception ex) + catch (Exception) { // Logging.Trace ($"scopeT Read: {ex}"); } diff --git a/Terminal.Gui/ConsoleDrivers/AnsiResponseParser/Keyboard/CsiKeyPattern.cs b/Terminal.Gui/ConsoleDrivers/AnsiResponseParser/Keyboard/CsiKeyPattern.cs index 9c442e5e2..cdcd10a59 100644 --- a/Terminal.Gui/ConsoleDrivers/AnsiResponseParser/Keyboard/CsiKeyPattern.cs +++ b/Terminal.Gui/ConsoleDrivers/AnsiResponseParser/Keyboard/CsiKeyPattern.cs @@ -52,6 +52,11 @@ public class CsiKeyPattern : AnsiKeyboardParserPattern _pattern = new (@$"^\u001b\[(1;(\d+))?([{terms}]|\d+~)$"); } + /// + /// + /// + /// + /// protected override Key? GetKeyImpl (string input) { Match match = _pattern.Match (input); @@ -66,7 +71,7 @@ public class CsiKeyPattern : AnsiKeyboardParserPattern Key? key = _terminators.GetValueOrDefault (terminator); - if (key != null && int.TryParse (modifierGroup, out int modifier)) + if (key is {} && int.TryParse (modifierGroup, out int modifier)) { key = modifier switch { diff --git a/Terminal.Gui/Terminal.Gui.csproj b/Terminal.Gui/Terminal.Gui.csproj index aaadfee75..e19e3521f 100644 --- a/Terminal.Gui/Terminal.Gui.csproj +++ b/Terminal.Gui/Terminal.Gui.csproj @@ -1,175 +1,184 @@  - - - - - - - - 2.0.0 - - - - - - - Terminal.Gui - + + + + + + + + 2.0.0 + + + + + + + Terminal.Gui + - - - - - net8.0 - 12 - $(AssemblyName) - true - true - portable - $(DefineConstants);CONTRACTS_FULL;CODE_ANALYSIS - enable - true - true - false - true - true - - - true - $(DefineConstants);DEBUG_IDISPOSABLE - - - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - true - \ - - - true - \ - - - - - - - - true - true - Strings.resx - - - - - ResXFileCodeGenerator - Strings.Designer.cs - - - - - - - $(AssemblyName) - MIT - https://github.com/gui-cs/$(AssemblyName) - logo.png - README.md - csharp, terminal, c#, f#, gui, toolkit, console, tui - Cross platform Terminal UI toolkit for .NET - Miguel de Icaza, Tig Kindel - A toolkit for building rich console apps for .NET that works on Windows, Mac, and Linux/Unix. - $(AssemblyName) - Cross-platform Terminal User Interface (TUI) toolkit for .NET - - See: $(PackageProjectUrl)/releases - - bin\$(Configuration)\$(AssemblyName).xml - true - true - https://github.com/gui-cs/$(AssemblyName).git - git - true - snupkg - - true - upstream - - true - true - Miguel de Icaza, Tig Kindel (@tig), @BDisp - - + + + + + + net8.0 + 12 + enable + + $(AssemblyName) + true + true + portable + $(DefineConstants);CONTRACTS_FULL;CODE_ANALYSIS + true + true + false + true + true + + + true + $(DefineConstants);DEBUG_IDISPOSABLE + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + \ + + + true + \ + + + + + + + + true + true + Strings.resx + + + + + ResXFileCodeGenerator + Strings.Designer.cs + + + + + + + $(AssemblyName) + MIT + https://github.com/gui-cs/$(AssemblyName) + logo.png + README.md + csharp, terminal, c#, f#, gui, toolkit, console, tui + Cross platform Terminal UI toolkit for .NET + Miguel de Icaza, Tig Kindel + A toolkit for building rich console apps for .NET that works on Windows, Mac, and Linux/Unix. + $(AssemblyName) - Cross-platform Terminal User Interface (TUI) toolkit for .NET + + See: $(PackageProjectUrl)/releases + + bin\$(Configuration)\$(AssemblyName).xml + true + true + https://github.com/gui-cs/$(AssemblyName).git + git + true + snupkg + + true + upstream + + true + true + Miguel de Icaza, Tig Kindel (@tig), @BDisp + + + + + + - - - - $(MSBuildThisFileDirectory)..\local_packages\ - - $(MSBuildThisFileDirectory)bin\$(Configuration)\ - + + + + $(MSBuildThisFileDirectory)..\local_packages\ + + $(MSBuildThisFileDirectory)bin\$(Configuration)\ + - - - + + + - - - - + + + + - - + + - - + + - - - + + + diff --git a/Terminal.Gui/View/DrawContext.cs b/Terminal.Gui/View/DrawContext.cs index 36b60c4c4..2648caefe 100644 --- a/Terminal.Gui/View/DrawContext.cs +++ b/Terminal.Gui/View/DrawContext.cs @@ -2,7 +2,7 @@ namespace Terminal.Gui; /// -/// Tracks the region that has been drawn during . This is primarily +/// Tracks the region that has been drawn during . This is primarily /// in support of . /// public class DrawContext diff --git a/Terminal.Gui/View/DrawEventArgs.cs b/Terminal.Gui/View/DrawEventArgs.cs index 5aabd2e66..b172d85ab 100644 --- a/Terminal.Gui/View/DrawEventArgs.cs +++ b/Terminal.Gui/View/DrawEventArgs.cs @@ -16,7 +16,7 @@ public class DrawEventArgs : CancelEventArgs /// . /// /// - /// Add any regions that have been drawn to during operations to this context. This is + /// Add any regions that have been drawn to during operations to this context. This is /// primarily /// in support of . /// @@ -34,7 +34,7 @@ public class DrawEventArgs : CancelEventArgs public Rectangle NewViewport { get; } /// - /// Add any regions that have been drawn to during operations to this context. This is + /// Add any regions that have been drawn to during operations to this context. This is /// primarily /// in support of . /// diff --git a/Terminal.Gui/View/View.Mouse.cs b/Terminal.Gui/View/View.Mouse.cs index 691c10d8a..3c5b0d01a 100644 --- a/Terminal.Gui/View/View.Mouse.cs +++ b/Terminal.Gui/View/View.Mouse.cs @@ -762,6 +762,7 @@ public partial class View // Mouse APIs /// INTERNAL: Gets the Views that are under the mouse at , including Adornments. /// /// + /// /// internal static List GetViewsUnderMouse (in Point location, bool ignoreTransparent = false) { diff --git a/Terminal.Gui/View/View.cs b/Terminal.Gui/View/View.cs index 8ffff38c8..bf4fc0d8c 100644 --- a/Terminal.Gui/View/View.cs +++ b/Terminal.Gui/View/View.cs @@ -24,6 +24,83 @@ namespace Terminal.Gui; public partial class View : IDisposable, ISupportInitializeNotification { + private bool _disposedValue; + + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resource. + public void Dispose () + { + // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method + Disposing?.Invoke (this, EventArgs.Empty); + Dispose (true); + GC.SuppressFinalize (this); +#if DEBUG_IDISPOSABLE + if (DebugIDisposable) + { + WasDisposed = true; + + foreach (View? instance in Instances.Where ( + x => + { + if (x is { }) + { + return x.WasDisposed; + } + + return false; + }) + .ToList ()) + { + Instances.Remove (instance); + } + } +#endif + } + + /// + /// Riased when the is being disposed. + /// + public event EventHandler? Disposing; + + /// Pretty prints the View + /// + public override string ToString () { return $"{GetType ().Name}({Id}){Frame}"; } + + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// + /// If disposing equals true, the method has been called directly or indirectly by a user's code. Managed and + /// unmanaged resources can be disposed. If disposing equals false, the method has been called by the runtime from + /// inside the finalizer and you should not reference other objects. Only unmanaged resources can be disposed. + /// + /// + protected virtual void Dispose (bool disposing) + { + LineCanvas.Dispose (); + + DisposeMouse (); + DisposeKeyboard (); + DisposeAdornments (); + DisposeScrollBars (); + + for (int i = InternalSubviews.Count - 1; i >= 0; i--) + { + View subview = InternalSubviews [i]; + Remove (subview); + subview.Dispose (); + } + + if (!_disposedValue) + { + if (disposing) + { + // TODO: dispose managed state (managed objects) + } + + _disposedValue = true; + } + + Debug.Assert (InternalSubviews.Count == 0); + } + #region Constructors and Initialization /// Gets or sets arbitrary data for the view. @@ -51,7 +128,10 @@ public partial class View : IDisposable, ISupportInitializeNotification public View () { #if DEBUG_IDISPOSABLE - Instances.Add (this); + if (DebugIDisposable) + { + Instances.Add (this); + } #endif SetupAdornments (); @@ -168,6 +248,7 @@ public partial class View : IDisposable, ISupportInitializeNotification // TODO: Figure out how to move this out of here and just depend on LayoutNeeded in Mainloop Layout (); // the EventLog in AllViewsTester fails to layout correctly if this is not here (convoluted Dim.Fill(Func)). } + SetNeedsLayout (); Initialized?.Invoke (this, EventArgs.Empty); @@ -371,7 +452,7 @@ public partial class View : IDisposable, ISupportInitializeNotification get { #if DEBUG_IDISPOSABLE - if (WasDisposed) + if (DebugIDisposable && WasDisposed) { throw new ObjectDisposedException (GetType ().FullName); } @@ -381,7 +462,7 @@ public partial class View : IDisposable, ISupportInitializeNotification set { #if DEBUG_IDISPOSABLE - if (WasDisposed) + if (DebugIDisposable && WasDisposed) { throw new ObjectDisposedException (GetType ().FullName); } @@ -450,71 +531,12 @@ public partial class View : IDisposable, ISupportInitializeNotification #endregion - /// Pretty prints the View - /// - public override string ToString () { return $"{GetType ().Name}({Id}){Frame}"; } - - private bool _disposedValue; - - /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. - /// - /// If disposing equals true, the method has been called directly or indirectly by a user's code. Managed and - /// unmanaged resources can be disposed. If disposing equals false, the method has been called by the runtime from - /// inside the finalizer and you should not reference other objects. Only unmanaged resources can be disposed. - /// - /// - protected virtual void Dispose (bool disposing) - { - LineCanvas.Dispose (); - - DisposeMouse (); - DisposeKeyboard (); - DisposeAdornments (); - DisposeScrollBars (); - - for (int i = InternalSubviews.Count - 1; i >= 0; i--) - { - View subview = InternalSubviews [i]; - Remove (subview); - subview.Dispose (); - } - - if (!_disposedValue) - { - if (disposing) - { - // TODO: dispose managed state (managed objects) - } - - _disposedValue = true; - } - - Debug.Assert (InternalSubviews.Count == 0); - } - +#if DEBUG_IDISPOSABLE /// - /// Riased when the is being disposed. + /// Set to false to disable the debug IDisposable feature. /// - public event EventHandler? Disposing; + public static bool DebugIDisposable { get; set; } = false; - /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resource. - public void Dispose () - { - // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method - Disposing?.Invoke (this, EventArgs.Empty); - Dispose (true); - GC.SuppressFinalize (this); -#if DEBUG_IDISPOSABLE - WasDisposed = true; - - foreach (View instance in Instances.Where (x => x.WasDisposed).ToList ()) - { - Instances.Remove (instance); - } -#endif - } - -#if DEBUG_IDISPOSABLE /// For debug purposes to verify objects are being disposed properly public bool WasDisposed { get; set; } diff --git a/Terminal.Gui/Views/Bar.cs b/Terminal.Gui/Views/Bar.cs index 05bcc1101..d5b72c185 100644 --- a/Terminal.Gui/Views/Bar.cs +++ b/Terminal.Gui/Views/Bar.cs @@ -109,11 +109,13 @@ public class Bar : View, IOrientation, IDesignable set => _orientationHelper.Orientation = value; } +#pragma warning disable CS0067 // The event is never used /// public event EventHandler>? OrientationChanging; /// public event EventHandler>? OrientationChanged; +#pragma warning restore CS0067 // The event is never used /// Called when has changed. /// diff --git a/Terminal.Gui/Views/Dialog.cs b/Terminal.Gui/Views/Dialog.cs index 259638baf..a70b597fd 100644 --- a/Terminal.Gui/Views/Dialog.cs +++ b/Terminal.Gui/Views/Dialog.cs @@ -107,7 +107,7 @@ public class Dialog : Window get { #if DEBUG_IDISPOSABLE - if (WasDisposed) + if (View.DebugIDisposable && WasDisposed) { throw new ObjectDisposedException (GetType ().FullName); } @@ -117,7 +117,7 @@ public class Dialog : Window set { #if DEBUG_IDISPOSABLE - if (WasDisposed) + if (View.DebugIDisposable && WasDisposed) { throw new ObjectDisposedException (GetType ().FullName); } diff --git a/Terminal.Gui/Views/Line.cs b/Terminal.Gui/Views/Line.cs index 9d2889373..45d2fa3cf 100644 --- a/Terminal.Gui/Views/Line.cs +++ b/Terminal.Gui/Views/Line.cs @@ -33,11 +33,13 @@ public class Line : View, IOrientation set => _orientationHelper.Orientation = value; } +#pragma warning disable CS0067 // The event is never used /// public event EventHandler> OrientationChanging; /// public event EventHandler> OrientationChanged; +#pragma warning restore CS0067 // The event is never used /// Called when has changed. /// diff --git a/Terminal.Gui/Views/RadioGroup.cs b/Terminal.Gui/Views/RadioGroup.cs index d72bebad7..3b9d9aeac 100644 --- a/Terminal.Gui/Views/RadioGroup.cs +++ b/Terminal.Gui/Views/RadioGroup.cs @@ -403,11 +403,13 @@ public class RadioGroup : View, IDesignable, IOrientation private readonly OrientationHelper _orientationHelper; +#pragma warning disable CS0067 // The event is never used /// public event EventHandler>? OrientationChanging; /// public event EventHandler>? OrientationChanged; +#pragma warning restore CS0067 // The event is never used /// Called when has changed. /// diff --git a/Terminal.Gui/Views/ScrollBar/ScrollBar.cs b/Terminal.Gui/Views/ScrollBar/ScrollBar.cs index 10df243a1..62d60320d 100644 --- a/Terminal.Gui/Views/ScrollBar/ScrollBar.cs +++ b/Terminal.Gui/Views/ScrollBar/ScrollBar.cs @@ -164,11 +164,13 @@ public class ScrollBar : View, IOrientation, IDesignable set => _orientationHelper.Orientation = value; } +#pragma warning disable CS0067 // The event is never used /// public event EventHandler>? OrientationChanging; /// public event EventHandler>? OrientationChanged; +#pragma warning restore CS0067 // The event is never used /// public void OnOrientationChanged (Orientation newOrientation) diff --git a/Terminal.Gui/Views/Wizard/WizardStep.cs b/Terminal.Gui/Views/Wizard/WizardStep.cs index 8d9be18b0..afb750ffb 100644 --- a/Terminal.Gui/Views/Wizard/WizardStep.cs +++ b/Terminal.Gui/Views/Wizard/WizardStep.cs @@ -125,7 +125,7 @@ public class WizardStep : View { _contentView.Add (view); - if (view.CanFocus) + if (view!.CanFocus) { CanFocus = true; } diff --git a/Terminal.sln b/Terminal.sln index 7cb9d0367..0399a634d 100644 --- a/Terminal.sln +++ b/Terminal.sln @@ -6,8 +6,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Terminal.Gui", "Terminal.Gu EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UICatalog", "UICatalog\UICatalog.csproj", "{88979F89-9A42-448F-AE3E-3060145F6375}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTests", "UnitTests\UnitTests.csproj", "{8B901EDE-8974-4820-B100-5226917E2990}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ReactiveExample", "ReactiveExample\ReactiveExample.csproj", "{44E15B48-0DB2-4560-82BD-D3B7989811C3}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Example", "Example\Example.csproj", "{B0A602CD-E176-449D-8663-64238D54F857}" @@ -21,6 +19,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Settings", "Settings", "{B8 .editorconfig = .editorconfig .filenesting.json = .filenesting.json .gitignore = .gitignore + Directory.Build.props = Directory.Build.props + Directory.Packages.props = Directory.Packages.props GitVersion.yml = GitVersion.yml global.json = global.json nuget.config = nuget.config @@ -31,9 +31,13 @@ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "GitHub", "GitHub", "{13BB2C46-B324-4B9C-92EB-CE6184D4736E}" ProjectSection(SolutionItems) = preProject .github\workflows\api-docs.yml = .github\workflows\api-docs.yml - .github\workflows\dotnet-core.yml = .github\workflows\dotnet-core.yml + .github\workflows\build-release.yml = .github\workflows\build-release.yml + .github\workflows\check-duplicates.yml = .github\workflows\check-duplicates.yml GitVersion.yml = GitVersion.yml + .github\workflows\integration-tests.yml = .github\workflows\integration-tests.yml .github\workflows\publish.yml = .github\workflows\publish.yml + .github\workflows\stress-tests.yml = .github\workflows\stress-tests.yml + .github\workflows\unit-tests.yml = .github\workflows\unit-tests.yml EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Docs", "Docs", "{C7A51224-5E0F-4986-AB37-A6BF89966C12}" @@ -50,6 +54,14 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NativeAot", "NativeAot\Nati EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Benchmarks", "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}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IntegrationTests", "Tests\IntegrationTests\IntegrationTests.csproj", "{F74EC349-B988-FCFA-A1E5-967F70FB75B5}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StressTests", "Tests\StressTests\StressTests.csproj", "{96ACE8BA-2E07-7537-FBF2-E8176CCB8080}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTests.Parallelizable", "Tests\UnitTestsParallelizable\UnitTests.Parallelizable.csproj", "{DE780834-190A-8277-51FD-750CC666E82D}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -64,10 +76,6 @@ Global {88979F89-9A42-448F-AE3E-3060145F6375}.Debug|Any CPU.Build.0 = Debug|Any CPU {88979F89-9A42-448F-AE3E-3060145F6375}.Release|Any CPU.ActiveCfg = Release|Any CPU {88979F89-9A42-448F-AE3E-3060145F6375}.Release|Any CPU.Build.0 = Release|Any CPU - {8B901EDE-8974-4820-B100-5226917E2990}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {8B901EDE-8974-4820-B100-5226917E2990}.Debug|Any CPU.Build.0 = Debug|Any CPU - {8B901EDE-8974-4820-B100-5226917E2990}.Release|Any CPU.ActiveCfg = Release|Any CPU - {8B901EDE-8974-4820-B100-5226917E2990}.Release|Any CPU.Build.0 = Release|Any CPU {44E15B48-0DB2-4560-82BD-D3B7989811C3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {44E15B48-0DB2-4560-82BD-D3B7989811C3}.Debug|Any CPU.Build.0 = Debug|Any CPU {44E15B48-0DB2-4560-82BD-D3B7989811C3}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -92,6 +100,22 @@ Global {242FBD3E-2EC6-4274-BD40-8E62AF9327B2}.Debug|Any CPU.Build.0 = Debug|Any CPU {242FBD3E-2EC6-4274-BD40-8E62AF9327B2}.Release|Any CPU.ActiveCfg = Release|Any CPU {242FBD3E-2EC6-4274-BD40-8E62AF9327B2}.Release|Any CPU.Build.0 = Release|Any CPU + {038B09F5-EF3A-F21E-7C10-A6551866ECE2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {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 + {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 + {F74EC349-B988-FCFA-A1E5-967F70FB75B5}.Release|Any CPU.Build.0 = Release|Any CPU + {96ACE8BA-2E07-7537-FBF2-E8176CCB8080}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {96ACE8BA-2E07-7537-FBF2-E8176CCB8080}.Debug|Any CPU.Build.0 = Debug|Any CPU + {96ACE8BA-2E07-7537-FBF2-E8176CCB8080}.Release|Any CPU.ActiveCfg = Release|Any CPU + {96ACE8BA-2E07-7537-FBF2-E8176CCB8080}.Release|Any CPU.Build.0 = Release|Any CPU + {DE780834-190A-8277-51FD-750CC666E82D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DE780834-190A-8277-51FD-750CC666E82D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DE780834-190A-8277-51FD-750CC666E82D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DE780834-190A-8277-51FD-750CC666E82D}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Terminal.sln.DotSettings b/Terminal.sln.DotSettings index 07d849e84..7b9a335a8 100644 --- a/Terminal.sln.DotSettings +++ b/Terminal.sln.DotSettings @@ -409,10 +409,12 @@ True True True + 5 True True True True + True True True True diff --git a/Tests/IntegrationTests/IntegrationTests.csproj b/Tests/IntegrationTests/IntegrationTests.csproj new file mode 100644 index 000000000..94b97b6a0 --- /dev/null +++ b/Tests/IntegrationTests/IntegrationTests.csproj @@ -0,0 +1,40 @@ + + + + enable + false + true + $(DefineConstants);JETBRAINS_ANNOTATIONS;CONTRACTS_FULL + portable + enable + true + true + + + true + $(DefineConstants);DEBUG_IDISPOSABLE + + + true + + + + + + + + + + + + + + + + + + + PreserveNewest + + + diff --git a/UnitTests/UICatalog/ScenarioTests.cs b/Tests/IntegrationTests/UICatalog/ScenarioTests.cs similarity index 78% rename from UnitTests/UICatalog/ScenarioTests.cs rename to Tests/IntegrationTests/UICatalog/ScenarioTests.cs index 09ba8b754..3de2735f4 100644 --- a/UnitTests/UICatalog/ScenarioTests.cs +++ b/Tests/IntegrationTests/UICatalog/ScenarioTests.cs @@ -1,15 +1,19 @@ using System.Collections.ObjectModel; using System.Diagnostics; using System.Reflection; +using Terminal.Gui; +using UnitTests; +using UICatalog; using Xunit.Abstractions; -namespace UICatalog.Tests; +namespace IntegrationTests.UICatalog; public class ScenarioTests : TestsAllViews { public ScenarioTests (ITestOutputHelper output) { #if DEBUG_IDISPOSABLE + View.DebugIDisposable = true; View.Instances.Clear (); #endif _output = output; @@ -137,169 +141,7 @@ public class ScenarioTests : TestsAllViews } } - /// - /// This runs through all Scenarios defined in UI Catalog, calling Init, Setup, and Run and measuring the perf of each. - /// - [Theory] - [MemberData (nameof (AllScenarioTypes))] - public void All_Scenarios_Benchmark (Type scenarioType) - { - Assert.Null (_timeoutLock); - _timeoutLock = new (); - - // Disable any UIConfig settings - ConfigLocations savedConfigLocations = ConfigurationManager.Locations; - ConfigurationManager.Locations = ConfigLocations.Default; - - // If a previous test failed, this will ensure that the Application is in a clean state - Application.ResetState (true); - - uint maxIterations = 1000; - uint abortTime = 2000; - object timeout = null; - var initialized = false; - var shutdown = false; - - int iterationCount = 0; - int clearedContentCount = 0; - int refreshedCount = 0; - int updatedCount = 0; - int drawCompleteCount = 0; - - int addedCount = 0; - int laidOutCount = 0; - - _output.WriteLine ($"Running Scenario '{scenarioType}'"); - var scenario = (Scenario)Activator.CreateInstance (scenarioType); - - Stopwatch stopwatch = null; - - Application.InitializedChanged += OnApplicationOnInitializedChanged; - Application.ForceDriver = "FakeDriver"; - scenario!.Main (); - scenario.Dispose (); - scenario = null; - Application.ForceDriver = string.Empty; - Application.InitializedChanged -= OnApplicationOnInitializedChanged; - - lock (_timeoutLock) - { - if (timeout is { }) - { - timeout = null; - } - } - - lock (_timeoutLock) - { - _timeoutLock = null; - } - - _output.WriteLine ($"Scenario {scenarioType}"); - _output.WriteLine ($" took {stopwatch.ElapsedMilliseconds} ms to run."); - _output.WriteLine ($" called Driver.ClearContents {clearedContentCount} times."); - _output.WriteLine ($" called Driver.Refresh {refreshedCount} times."); - _output.WriteLine ($" which updated the screen {updatedCount} times."); - _output.WriteLine ($" called View.Draw {drawCompleteCount} times."); - _output.WriteLine ($" added {addedCount} views."); - _output.WriteLine ($" called View.LayoutComplete {laidOutCount} times."); - - // Restore the configuration locations - ConfigurationManager.Locations = savedConfigLocations; - ConfigurationManager.Reset (); - - return; - - void OnApplicationOnInitializedChanged (object s, EventArgs a) - { - if (a.CurrentValue) - { - lock (_timeoutLock) - { - timeout = Application.AddTimeout (TimeSpan.FromMilliseconds (abortTime), ForceCloseCallback); - } - - initialized = true; - Application.Iteration += OnApplicationOnIteration; - Application.Driver!.ClearedContents += (sender, args) => clearedContentCount++; - - if (Application.Driver is ConsoleDriver cd) - { - cd!.Refreshed += (sender, args) => - { - refreshedCount++; - - if (args.CurrentValue) - { - updatedCount++; - } - }; - } - - Application.NotifyNewRunState += OnApplicationNotifyNewRunState; - - stopwatch = Stopwatch.StartNew (); - } - else - { - shutdown = true; - Application.NotifyNewRunState -= OnApplicationNotifyNewRunState; - Application.Iteration -= OnApplicationOnIteration; - stopwatch!.Stop (); - } - _output.WriteLine ($"Initialized == {a.CurrentValue}"); - } - - void OnApplicationOnIteration (object s, IterationEventArgs a) - { - iterationCount++; - if (iterationCount > maxIterations) - { - // Press QuitKey - _output.WriteLine ($"Attempting to quit scenario with RequestStop"); - Application.RequestStop (); - } - } - - - void OnApplicationNotifyNewRunState (object sender, RunStateEventArgs e) - { - // Get a list of all subviews under Application.Top (and their subviews, etc.) - // and subscribe to their DrawComplete event - void SubscribeAllSubviews (View view) - { - view.DrawComplete += (s, a) => drawCompleteCount++; - view.SubviewsLaidOut += (s, a) => laidOutCount++; - view.Added += (s, a) => addedCount++; - foreach (View subview in view.Subviews) - { - SubscribeAllSubviews (subview); - } - } - - SubscribeAllSubviews (Application.Top); - } - - // If the scenario doesn't close within the abort time, this will force it to quit - bool ForceCloseCallback () - { - lock (_timeoutLock) - { - if (timeout is { }) - { - timeout = null; - } - } - - _output.WriteLine( - $"'{scenario.GetName ()}' failed to Quit with {Application.QuitKey} after {abortTime}ms and {iterationCount} iterations. Force quit."); - - Application.RequestStop (); - - return false; - } - } - + public static IEnumerable AllScenarioTypes => typeof (Scenario).Assembly .GetTypes () @@ -344,7 +186,7 @@ public class ScenarioTests : TestsAllViews var top = new Toplevel (); - _viewClasses = TestHelpers.GetAllViewClasses ().ToDictionary (t => t.Name); + _viewClasses = ViewTestHelpers.GetAllViewClasses ().ToDictionary (t => t.Name); _leftPane = new () { diff --git a/UnitTests/xunit.runner.json b/Tests/IntegrationTests/xunit.runner.json similarity index 100% rename from UnitTests/xunit.runner.json rename to Tests/IntegrationTests/xunit.runner.json diff --git a/Tests/README.md b/Tests/README.md new file mode 100644 index 000000000..805a8b54a --- /dev/null +++ b/Tests/README.md @@ -0,0 +1,29 @@ +# Terminal.Gui Tests + +This folder contains the tests for Terminal.Gui. + +## ./UnitTests + +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`. + +We should be striving to move as many tests as possible to the `./UnitTestsParallelizable` folder. + +## ./UnitTestsParallelizable + +This folder contains the unit tests for Terminal.Gui that can be run in parallel. + +## ./IntegrationTests + +This folder contains the integration tests for Terminal.Gui. + +## ./StressTests + +This folder contains the stress tests for Terminal.Gui. + +## ./PerformanceTests + +This folder WILL contain the performance tests for Terminal.Gui. + + +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/StressTests/ApplicationStressTests.cs b/Tests/StressTests/ApplicationStressTests.cs new file mode 100644 index 000000000..b326a054c --- /dev/null +++ b/Tests/StressTests/ApplicationStressTests.cs @@ -0,0 +1,111 @@ +using Terminal.Gui; +using UnitTests; +using Xunit.Abstractions; + +namespace StressTests; + +public class ApplicationStressTests : TestsAllViews +{ + public ApplicationStressTests (ITestOutputHelper output) + { + ConsoleDriver.RunningUnitTests = true; + ConfigurationManager.Locations = ConfigLocations.Default; + } + + private static volatile int _tbCounter; + private static readonly ManualResetEventSlim _wakeUp = new (false); + + [Theory] + [InlineData (typeof (FakeDriver))] + [InlineData (typeof (NetDriver), Skip = "System.IO.IOException: The handle is invalid")] + //[InlineData (typeof (ANSIDriver))] + [InlineData (typeof (WindowsDriver))] + [InlineData (typeof (CursesDriver), Skip = "Unable to load DLL 'libc' or one of its dependencies: The specified module could not be found. (0x8007007E)")] + public async Task InvokeLeakTest (Type driverType) + { + + Application.Init (driverName: driverType.Name); + Random r = new (); + TextField tf = new (); + var top = new Toplevel (); + top.Add (tf); + + const int NUM_PASSES = 50; + const int NUM_INCREMENTS = 500; + const int POLL_MS = 100; + _tbCounter = 0; + + Task task = Task.Run (() => RunTest (r, tf, NUM_PASSES, NUM_INCREMENTS, POLL_MS)); + + // blocks here until the RequestStop is processed at the end of the test + Application.Run (top); + + await task; // Propagate exception if any occurred + + Assert.Equal (NUM_INCREMENTS * NUM_PASSES, _tbCounter); + top.Dispose (); + Application.Shutdown (); + + return; + + static void RunTest (Random r, TextField tf, int numPasses, int numIncrements, int pollMs) + { + for (var j = 0; j < numPasses; j++) + { + _wakeUp.Reset (); + + for (var i = 0; i < numIncrements; i++) + { + Launch (r, tf, (j + 1) * numIncrements); + } + + while (_tbCounter != (j + 1) * numIncrements) // Wait for tbCounter to reach expected value + { + int tbNow = _tbCounter; + _wakeUp.Wait (pollMs); + + if (_tbCounter != tbNow) + { + continue; + } + + // No change after wait: Idle handlers added via Application.Invoke have gone missing + Application.Invoke (() => Application.RequestStop ()); + + throw new TimeoutException ( + $"Timeout: Increment lost. _tbCounter ({_tbCounter}) didn't " + + $"change after waiting {pollMs} ms. Failed to reach {(j + 1) * numIncrements} on pass {j + 1}" + ); + } + + ; + } + + Application.Invoke (() => Application.RequestStop ()); + } + + static void Launch (Random r, TextField tf, int target) + { + Task.Run ( + () => + { + Thread.Sleep (r.Next (2, 4)); + + Application.Invoke ( + () => + { + tf.Text = $"index{r.Next ()}"; + Interlocked.Increment (ref _tbCounter); + + if (target == _tbCounter) + { + // On last increment wake up the check + _wakeUp.Set (); + } + } + ); + } + ); + } + } +} diff --git a/Tests/StressTests/ScenariosStressTests.cs b/Tests/StressTests/ScenariosStressTests.cs new file mode 100644 index 000000000..007cd58b3 --- /dev/null +++ b/Tests/StressTests/ScenariosStressTests.cs @@ -0,0 +1,193 @@ +using System.Diagnostics; +using Terminal.Gui; +using UICatalog; +using UnitTests; +using Xunit.Abstractions; + +namespace StressTests; + +public class ScenariosStressTests : TestsAllViews +{ + public ScenariosStressTests (ITestOutputHelper output) + { +#if DEBUG_IDISPOSABLE + View.DebugIDisposable = true; + View.Instances.Clear (); +#endif + _output = output; + } + + private readonly ITestOutputHelper _output; + + private object? _timeoutLock; + + /// + /// + /// This runs through all Scenarios defined in UI Catalog, calling Init, Setup, and Run and measuring the perf of + /// each. + /// + /// + [Theory] + [MemberData (nameof (AllScenarioTypes))] + public void All_Scenarios_Benchmark (Type scenarioType) + { + Assert.Null (_timeoutLock); + _timeoutLock = new (); + + // Disable any UIConfig settings + ConfigLocations savedConfigLocations = ConfigurationManager.Locations; + ConfigurationManager.Locations = ConfigLocations.Default; + + // If a previous test failed, this will ensure that the Application is in a clean state + Application.ResetState (true); + + uint maxIterations = 1000; + uint abortTime = 2000; + object? timeout = null; + + var iterationCount = 0; + var clearedContentCount = 0; + var refreshedCount = 0; + var updatedCount = 0; + var drawCompleteCount = 0; + + var addedCount = 0; + var laidOutCount = 0; + + _output.WriteLine ($"Running Scenario '{scenarioType}'"); + var scenario = (Scenario)Activator.CreateInstance (scenarioType)!; + + Stopwatch? stopwatch = null; + + Application.InitializedChanged += OnApplicationOnInitializedChanged; + Application.ForceDriver = "FakeDriver"; + scenario!.Main (); + scenario.Dispose (); + scenario = null; + Application.ForceDriver = string.Empty; + Application.InitializedChanged -= OnApplicationOnInitializedChanged; + + lock (_timeoutLock) + { + if (timeout is { }) + { + timeout = null; + } + } + + lock (_timeoutLock) + { + _timeoutLock = null; + } + + _output.WriteLine ($"Scenario {scenarioType}"); + _output.WriteLine ($" took {stopwatch!.ElapsedMilliseconds} ms to run."); + _output.WriteLine ($" called Driver.ClearContents {clearedContentCount} times."); + _output.WriteLine ($" called Driver.Refresh {refreshedCount} times."); + _output.WriteLine ($" which updated the screen {updatedCount} times."); + _output.WriteLine ($" called View.Draw {drawCompleteCount} times."); + _output.WriteLine ($" added {addedCount} views."); + _output.WriteLine ($" called View.LayoutComplete {laidOutCount} times."); + + // Restore the configuration locations + ConfigurationManager.Locations = savedConfigLocations; + ConfigurationManager.Reset (); + + return; + + void OnApplicationOnInitializedChanged (object? s, EventArgs a) + { + if (a.CurrentValue) + { + lock (_timeoutLock) + { + timeout = Application.AddTimeout (TimeSpan.FromMilliseconds (abortTime), ForceCloseCallback); + } + + Application.Iteration += OnApplicationOnIteration; + Application.Driver!.ClearedContents += (sender, args) => clearedContentCount++; + + if (Application.Driver is ConsoleDriver cd) + { + cd!.Refreshed += (sender, args) => + { + refreshedCount++; + + if (args.CurrentValue) + { + updatedCount++; + } + }; + } + + Application.NotifyNewRunState += OnApplicationNotifyNewRunState; + + stopwatch = Stopwatch.StartNew (); + } + else + { + Application.NotifyNewRunState -= OnApplicationNotifyNewRunState; + Application.Iteration -= OnApplicationOnIteration; + stopwatch!.Stop (); + } + + _output.WriteLine ($"Initialized == {a.CurrentValue}"); + } + + void OnApplicationOnIteration (object? s, IterationEventArgs a) + { + iterationCount++; + + if (iterationCount > maxIterations) + { + // Press QuitKey + _output.WriteLine ("Attempting to quit scenario with RequestStop"); + Application.RequestStop (); + } + } + + void OnApplicationNotifyNewRunState (object? sender, RunStateEventArgs e) + { + // Get a list of all subviews under Application.Top (and their subviews, etc.) + // and subscribe to their DrawComplete event + void SubscribeAllSubviews (View view) + { + view.DrawComplete += (s, a) => drawCompleteCount++; + view.SubviewsLaidOut += (s, a) => laidOutCount++; + view.Added += (s, a) => addedCount++; + + foreach (View subview in view.Subviews) + { + SubscribeAllSubviews (subview); + } + } + + SubscribeAllSubviews (Application.Top!); + } + + // If the scenario doesn't close within the abort time, this will force it to quit + bool ForceCloseCallback () + { + lock (_timeoutLock) + { + if (timeout is { }) + { + timeout = null; + } + } + + _output.WriteLine ( + $"'{scenario!.GetName ()}' failed to Quit with {Application.QuitKey} after {abortTime}ms and {iterationCount} iterations. Force quit."); + + Application.RequestStop (); + + return false; + } + } + + public static IEnumerable AllScenarioTypes => + typeof (Scenario).Assembly + .GetTypes () + .Where (type => type.IsClass && !type.IsAbstract && type.IsSubclassOf (typeof (Scenario))) + .Select (type => new object [] { type }); +} diff --git a/Tests/StressTests/StressTests.csproj b/Tests/StressTests/StressTests.csproj new file mode 100644 index 000000000..62efd367f --- /dev/null +++ b/Tests/StressTests/StressTests.csproj @@ -0,0 +1,44 @@ + + + + enable + + false + true + $(DefineConstants);JETBRAINS_ANNOTATIONS;CONTRACTS_FULL + portable + enable + true + true + + + + true + $(DefineConstants);DEBUG_IDISPOSABLE + + + true + + + + + + + + + + + + + + + + + + + + PreserveNewest + + + + diff --git a/Tests/StressTests/xunit.runner.json b/Tests/StressTests/xunit.runner.json new file mode 100644 index 000000000..c096d4186 --- /dev/null +++ b/Tests/StressTests/xunit.runner.json @@ -0,0 +1,6 @@ +{ + "$schema": "https://xunit.net/schema/current/xunit.runner.schema.json", + "parallelizeTestCollections": false, + "parallelizeAssembly": false, + "stopOnFail": false +} \ No newline at end of file diff --git a/UnitTests/Application/Application.NavigationTests.cs b/Tests/UnitTests/Application/Application.NavigationTests.cs similarity index 100% rename from UnitTests/Application/Application.NavigationTests.cs rename to Tests/UnitTests/Application/Application.NavigationTests.cs diff --git a/UnitTests/Application/ApplicationScreenTests.cs b/Tests/UnitTests/Application/ApplicationScreenTests.cs similarity index 79% rename from UnitTests/Application/ApplicationScreenTests.cs rename to Tests/UnitTests/Application/ApplicationScreenTests.cs index 0abdeacbc..c13165ff8 100644 --- a/UnitTests/Application/ApplicationScreenTests.cs +++ b/Tests/UnitTests/Application/ApplicationScreenTests.cs @@ -2,8 +2,14 @@ namespace Terminal.Gui.ApplicationTests; -public class ApplicationScreenTests (ITestOutputHelper output) +public class ApplicationScreenTests { + public ApplicationScreenTests (ITestOutputHelper output) + { + ConsoleDriver.RunningUnitTests = true; + } + + [Fact] public void ClearScreenNextIteration_Resets_To_False_After_LayoutAndDraw () { @@ -27,12 +33,13 @@ public class ApplicationScreenTests (ITestOutputHelper output) { // Arrange Application.Init (new FakeDriver ()); - Application.Top = new Toplevel (); + Application.Top = new (); Application.TopLevels.Push (Application.Top); - int clearedContentsRaised = 0; + var clearedContentsRaised = 0; - Application.Driver!.ClearedContents += (e, a) => clearedContentsRaised++; + + Application.Driver!.ClearedContents += OnClearedContents; // Act Application.LayoutAndDraw (); @@ -64,9 +71,13 @@ public class ApplicationScreenTests (ITestOutputHelper output) // Cleanup Application.Top.Dispose (); Application.Top = null; + Application.Driver!.ClearedContents -= OnClearedContents; Application.Shutdown (); Application.ResetState (true); + return; + + void OnClearedContents (object e, EventArgs a) { clearedContentsRaised++; } } [Fact] @@ -80,7 +91,7 @@ public class ApplicationScreenTests (ITestOutputHelper output) Assert.Equal (new (0, 0, 25, 25), Application.Screen); // Act - (((FakeDriver)Application.Driver)!).SetBufferSize (120, 30); + ((FakeDriver)Application.Driver)!.SetBufferSize (120, 30); // Assert Assert.Equal (new (0, 0, 120, 30), Application.Screen); diff --git a/UnitTests/Application/ApplicationTests.cs b/Tests/UnitTests/Application/ApplicationTests.cs similarity index 93% rename from UnitTests/Application/ApplicationTests.cs rename to Tests/UnitTests/Application/ApplicationTests.cs index 53838d09a..c98bbe394 100644 --- a/UnitTests/Application/ApplicationTests.cs +++ b/Tests/UnitTests/Application/ApplicationTests.cs @@ -1,4 +1,5 @@ using System.Diagnostics; +using UnitTests; using Xunit.Abstractions; using static Terminal.Gui.ConfigurationManager; @@ -15,6 +16,7 @@ public class ApplicationTests Locations = ConfigLocations.Default; #if DEBUG_IDISPOSABLE + View.DebugIDisposable = true; View.Instances.Clear (); RunState.Instances.Clear (); #endif @@ -906,53 +908,6 @@ public class ApplicationTests Assert.Equal (3, count); } - // TODO: All Toplevel layout tests should be moved to ToplevelTests.cs - [Fact (Skip = "#2491 - Changing focus should cause NeedsDraw = true, so bogus test?")] - public void Run_Toplevel_With_Modal_View_Does_Not_Refresh_If_Not_Dirty () - { - Init (); - var count = 0; - - // Don't use Dialog here as it has more layout logic. Use Window instead. - Dialog d = null; - Toplevel top = new (); - top.DrawingContent += (s, a) => count++; - int iteration = -1; - - Application.Iteration += (s, a) => - { - iteration++; - - if (iteration == 0) - { - // TODO: Don't use Dialog here as it has more layout logic. Use Window instead. - d = new (); - d.DrawingContent += (s, a) => count++; - Application.Run (d); - } - else if (iteration < 3) - { - Application.RaiseMouseEvent (new () { Flags = MouseFlags.ReportMousePosition }); - Assert.False (top.NeedsDraw); - Assert.False (top.SubViewNeedsDraw); - Assert.False (top.NeedsLayout); - Assert.False (d.NeedsDraw); - Assert.False (d.SubViewNeedsDraw); - Assert.False (d.NeedsLayout); - } - else - { - Application.RequestStop (); - } - }; - Application.Run (top); - top.Dispose (); - Application.Shutdown (); - - // 1 - First top load, 1 - Dialog load, 1 - Dialog unload, Total - 3. - Assert.Equal (3, count); - } - // TODO: All Toplevel layout tests should be moved to ToplevelTests.cs [Fact] public void Run_A_Modal_Toplevel_Refresh_Background_On_Moving () diff --git a/UnitTests/Application/CursorTests.cs b/Tests/UnitTests/Application/CursorTests.cs similarity index 98% rename from UnitTests/Application/CursorTests.cs rename to Tests/UnitTests/Application/CursorTests.cs index 7454e1501..74bf21396 100644 --- a/UnitTests/Application/CursorTests.cs +++ b/Tests/UnitTests/Application/CursorTests.cs @@ -1,4 +1,5 @@ -using Xunit.Abstractions; +using UnitTests; +using Xunit.Abstractions; namespace Terminal.Gui.ApplicationTests; diff --git a/UnitTests/Application/KeyboardTests.cs b/Tests/UnitTests/Application/KeyboardTests.cs similarity index 84% rename from UnitTests/Application/KeyboardTests.cs rename to Tests/UnitTests/Application/KeyboardTests.cs index 970d6a5b8..c1e1c9f65 100644 --- a/UnitTests/Application/KeyboardTests.cs +++ b/Tests/UnitTests/Application/KeyboardTests.cs @@ -1,4 +1,5 @@ -using Xunit.Abstractions; +using UnitTests; +using Xunit.Abstractions; namespace Terminal.Gui.ApplicationTests; @@ -20,119 +21,6 @@ public class KeyboardTests private object _timeoutLock; - [Fact (Skip = "No longer valid test.")] - [AutoInitShutdown] - public void EnsuresTopOnFront_CanFocus_False_By_Keyboard () - { - Toplevel top = new (); - - var win = new Window - { - Title = "win", - X = 0, - Y = 0, - Width = 20, - Height = 10 - }; - var tf = new TextField { Width = 10 }; - win.Add (tf); - - var win2 = new Window - { - Title = "win2", - X = 22, - Y = 0, - Width = 20, - Height = 10 - }; - var tf2 = new TextField { Width = 10 }; - win2.Add (tf2); - top.Add (win, win2); - - Application.Begin (top); - - Assert.True (win.CanFocus); - Assert.True (win.HasFocus); - Assert.True (win2.CanFocus); - Assert.False (win2.HasFocus); - Assert.Equal ("win", ((Window)top.Subviews [^1]).Title); - - win.CanFocus = false; - Assert.False (win.CanFocus); - Assert.False (win.HasFocus); - Assert.True (win2.CanFocus); - Assert.True (win2.HasFocus); - Assert.Equal ("win2", ((Window)top.Subviews [^1]).Title); - - Application.RaiseKeyDownEvent (Key.F6); - Assert.True (win2.CanFocus); - Assert.False (win.HasFocus); - Assert.True (win2.CanFocus); - Assert.True (win2.HasFocus); - Assert.Equal ("win2", ((Window)top.Subviews [^1]).Title); - - Application.RaiseKeyDownEvent (Key.F6); - Assert.False (win.CanFocus); - Assert.False (win.HasFocus); - Assert.True (win2.CanFocus); - Assert.True (win2.HasFocus); - Assert.Equal ("win2", ((Window)top.Subviews [^1]).Title); - top.Dispose (); - } - - [Fact (Skip = "No longer valid test.")] - [AutoInitShutdown] - public void EnsuresTopOnFront_CanFocus_True_By_Keyboard () - { - Toplevel top = new (); - - var win = new Window - { - Title = "win", - X = 0, - Y = 0, - Width = 20, - Height = 10 - }; - var tf = new TextField { Width = 10 }; - win.Add (tf); - - var win2 = new Window - { - Title = "win2", - X = 22, - Y = 0, - Width = 20, - Height = 10 - }; - var tf2 = new TextField { Width = 10 }; - win2.Add (tf2); - top.Add (win, win2); - - Application.Begin (top); - - Assert.True (win.CanFocus); - Assert.True (win.HasFocus); - Assert.True (win2.CanFocus); - Assert.False (win2.HasFocus); - Assert.Equal ("win", ((Window)top.Subviews [^1]).Title); - - Application.RaiseKeyDownEvent (Key.F6); - Assert.True (win.CanFocus); - Assert.False (win.HasFocus); - Assert.True (win2.CanFocus); - Assert.True (win2.HasFocus); - Assert.Equal ("win2", ((Window)top.Subviews [^1]).Title); - - Application.RaiseKeyDownEvent (Key.F6); - Assert.True (win.CanFocus); - Assert.True (win.HasFocus); - Assert.True (win2.CanFocus); - Assert.False (win2.HasFocus); - Assert.Equal ("win", ((Window)top.Subviews [^1]).Title); - top.Dispose (); - } - [Fact] [AutoInitShutdown] public void KeyBindings_Add_Adds () @@ -145,7 +33,7 @@ public class KeyboardTests Assert.True (Application.KeyBindings.TryGet (Key.B, out binding)); Assert.Null (binding.Target); } - + [Fact] [AutoInitShutdown] public void KeyBindings_Remove_Removes () @@ -161,7 +49,7 @@ public class KeyboardTests [Fact] public void KeyBindings_OnKeyDown () { - Application.Top = new Toplevel (); + Application.Top = new (); var view = new ScopedKeyBindingView (); var keyWasHandled = false; view.KeyDownNotHandled += (s, e) => keyWasHandled = true; diff --git a/UnitTests/Application/MainLoopTests.cs b/Tests/UnitTests/Application/MainLoopTests.cs similarity index 86% rename from UnitTests/Application/MainLoopTests.cs rename to Tests/UnitTests/Application/MainLoopTests.cs index 820414274..49bd831ab 100644 --- a/UnitTests/Application/MainLoopTests.cs +++ b/Tests/UnitTests/Application/MainLoopTests.cs @@ -1,5 +1,4 @@ using System.Diagnostics; -using System.IO; // Alias Console to MockConsole so we don't accidentally use Console @@ -8,7 +7,6 @@ namespace Terminal.Gui.ApplicationTests; /// Tests MainLoop using the FakeMainLoop. public class MainLoopTests { - private static readonly ManualResetEventSlim _wakeUp = new (false); private static Button btn; private static string cancel; private static string clickMe; @@ -22,28 +20,11 @@ public class MainLoopTests // - wait = false // TODO: Add IMainLoop tests - private static volatile int tbCounter; private static int three; private static int total; private static int two; private static int zero; - public static IEnumerable TestAddIdle - { - get - { - // Goes fine - Action a1 = StartWindow; - - yield return new object [] { a1, "Click Me", "Cancel", "Pew Pew", 0, 1, 2, 3, 4 }; - - // Also goes fine - Action a2 = () => Application.Invoke (StartWindow); - - yield return new object [] { a2, "Click Me", "Cancel", "Pew Pew", 0, 1, 2, 3, 4 }; - } - } - // See Also ConsoleDRivers/MainLoopDriverTests.cs for tests of the MainLoopDriver // Idle Handler tests @@ -60,7 +41,7 @@ public class MainLoopTests Assert.Equal (2, ml.TimedEvents.IdleHandlers.Count); Assert.Equal (fnTrue, ml.TimedEvents.IdleHandlers [0]); - Assert.NotEqual (fnFalse, ml.TimedEvents.IdleHandlers[0]); + Assert.NotEqual (fnFalse, ml.TimedEvents.IdleHandlers [0]); Assert.True (ml.TimedEvents.RemoveIdle (fnTrue)); Assert.Single (ml.TimedEvents.IdleHandlers); @@ -82,15 +63,15 @@ public class MainLoopTests ml.AddIdle (fnTrue); Assert.Equal (2, ml.TimedEvents.IdleHandlers.Count); - Assert.Equal (fnTrue, ml.TimedEvents.IdleHandlers[0]); - Assert.True (ml.TimedEvents.IdleHandlers[0] ()); - Assert.Equal (fnTrue, ml.TimedEvents.IdleHandlers[1]); - Assert.True (ml.TimedEvents.IdleHandlers[1] ()); + Assert.Equal (fnTrue, ml.TimedEvents.IdleHandlers [0]); + Assert.True (ml.TimedEvents.IdleHandlers [0] ()); + Assert.Equal (fnTrue, ml.TimedEvents.IdleHandlers [1]); + Assert.True (ml.TimedEvents.IdleHandlers [1] ()); Assert.True (ml.TimedEvents.RemoveIdle (fnTrue)); Assert.Single (ml.TimedEvents.IdleHandlers); - Assert.Equal (fnTrue, ml.TimedEvents.IdleHandlers[0]); - Assert.NotEqual (fnFalse, ml.TimedEvents.IdleHandlers[0]); + Assert.Equal (fnTrue, ml.TimedEvents.IdleHandlers [0]); + Assert.NotEqual (fnFalse, ml.TimedEvents.IdleHandlers [0]); Assert.True (ml.TimedEvents.RemoveIdle (fnTrue)); Assert.Empty (ml.TimedEvents.IdleHandlers); @@ -298,10 +279,10 @@ public class MainLoopTests TimeoutEventArgs args = null; ml.TimedEvents.TimeoutAdded += (s, e) => - { - sender = s; - args = e; - }; + { + sender = s; + args = e; + }; object token = ml.TimedEvents.AddTimeout (TimeSpan.FromMilliseconds (ms), callback); @@ -616,41 +597,10 @@ public class MainLoopTests Assert.Empty (mainloop.TimedEvents.IdleHandlers); Assert.NotNull ( - new Timeout { Span = new TimeSpan (), Callback = () => true } + new Timeout { Span = new (), Callback = () => true } ); } - [Theory] - [InlineData (typeof (FakeDriver))] - //[InlineData (typeof (NetDriver))] // BUGBUG: NetDriver never exits in this test - - //[InlineData (typeof (ANSIDriver))] - //[InlineData (typeof (WindowsDriver))] // BUGBUG: NetDriver never exits in this test - //[InlineData (typeof (CursesDriver))] // BUGBUG: CursesDriver never exits in this test - public async Task InvokeLeakTest (Type driverType) - { - Application.Init (driverName: driverType.Name); - Random r = new (); - TextField tf = new (); - var top = new Toplevel (); - top.Add (tf); - - const int numPasses = 2; - const int numIncrements = 500; - const int pollMs = 2500; - - Task task = Task.Run (() => RunTest (r, tf, numPasses, numIncrements, pollMs)); - - // blocks here until the RequestStop is processed at the end of the test - Application.Run (top); - - await task; // Propagate exception if any occurred - - Assert.Equal (numIncrements * numPasses, tbCounter); - top.Dispose (); - Application.Shutdown (); - } - [Theory] [MemberData (nameof (TestAddIdle))] public void Mainloop_Invoke_Or_AddIdle_Can_Be_Used_For_Events_Or_Actions ( @@ -666,7 +616,7 @@ public class MainLoopTests ) { // TODO: Expand this test to test all drivers - Application.Init (new FakeDriver()); + Application.Init (new FakeDriver ()); total = 0; btn = null; @@ -779,28 +729,20 @@ public class MainLoopTests Assert.Equal (10, functionCalled); } - private static void Launch (Random r, TextField tf, int target) + public static IEnumerable TestAddIdle { - Task.Run ( - () => - { - Thread.Sleep (r.Next (2, 4)); + get + { + // Goes fine + Action a1 = StartWindow; - Application.Invoke ( - () => - { - tf.Text = $"index{r.Next ()}"; - Interlocked.Increment (ref tbCounter); + yield return new object [] { a1, "Click Me", "Cancel", "Pew Pew", 0, 1, 2, 3, 4 }; - if (target == tbCounter) - { - // On last increment wake up the check - _wakeUp.Set (); - } - } - ); - } - ); + // Also goes fine + Action a2 = () => Application.Invoke (StartWindow); + + yield return new object [] { a2, "Click Me", "Cancel", "Pew Pew", 0, 1, 2, 3, 4 }; + } } private static async void RunAsyncTest (object sender, EventArgs e) @@ -862,40 +804,6 @@ public class MainLoopTests ); } - private static void RunTest (Random r, TextField tf, int numPasses, int numIncrements, int pollMs) - { - for (var j = 0; j < numPasses; j++) - { - _wakeUp.Reset (); - - for (var i = 0; i < numIncrements; i++) - { - Launch (r, tf, (j + 1) * numIncrements); - } - - while (tbCounter != (j + 1) * numIncrements) // Wait for tbCounter to reach expected value - { - int tbNow = tbCounter; - _wakeUp.Wait (pollMs); - - if (tbCounter == tbNow) - { - // No change after wait: Idle handlers added via Application.Invoke have gone missing - Application.Invoke (() => Application.RequestStop ()); - - throw new TimeoutException ( - $"Timeout: Increment lost. tbCounter ({tbCounter}) didn't " - + $"change after waiting {pollMs} ms. Failed to reach {(j + 1) * numIncrements} on pass {j + 1}" - ); - } - } - - ; - } - - Application.Invoke (() => Application.RequestStop ()); - } - private static void SetReadyToRun () { Thread.Sleep (100); @@ -916,7 +824,7 @@ public class MainLoopTests { var startWindow = new Window { Modal = true }; - btn = new Button { Text = "Click Me" }; + btn = new() { Text = "Click Me" }; btn.Accepting += RunAsyncTest; @@ -937,8 +845,8 @@ public class MainLoopTests private class MillisecondTolerance : IEqualityComparer { - private readonly int _tolerance; public MillisecondTolerance (int tolerance) { _tolerance = tolerance; } + private readonly int _tolerance; public bool Equals (TimeSpan x, TimeSpan y) { return Math.Abs (x.Milliseconds - y.Milliseconds) <= _tolerance; } public int GetHashCode (TimeSpan obj) { return obj.GetHashCode (); } } diff --git a/UnitTests/Application/Mouse/ApplicationMouseEnterLeaveTests.cs b/Tests/UnitTests/Application/Mouse/ApplicationMouseEnterLeaveTests.cs similarity index 100% rename from UnitTests/Application/Mouse/ApplicationMouseEnterLeaveTests.cs rename to Tests/UnitTests/Application/Mouse/ApplicationMouseEnterLeaveTests.cs diff --git a/UnitTests/Application/Mouse/ApplicationMouseTests.cs b/Tests/UnitTests/Application/Mouse/ApplicationMouseTests.cs similarity index 99% rename from UnitTests/Application/Mouse/ApplicationMouseTests.cs rename to Tests/UnitTests/Application/Mouse/ApplicationMouseTests.cs index b180a768c..3ae825d94 100644 --- a/UnitTests/Application/Mouse/ApplicationMouseTests.cs +++ b/Tests/UnitTests/Application/Mouse/ApplicationMouseTests.cs @@ -1,4 +1,5 @@ -using Xunit.Abstractions; +using UnitTests; +using Xunit.Abstractions; // Alias Console to MockConsole so we don't accidentally use Console diff --git a/UnitTests/Application/RunStateTests.cs b/Tests/UnitTests/Application/RunStateTests.cs similarity index 98% rename from UnitTests/Application/RunStateTests.cs rename to Tests/UnitTests/Application/RunStateTests.cs index 5b8a53c58..35e318788 100644 --- a/UnitTests/Application/RunStateTests.cs +++ b/Tests/UnitTests/Application/RunStateTests.cs @@ -8,6 +8,8 @@ public class RunStateTests public RunStateTests () { #if DEBUG_IDISPOSABLE + View.DebugIDisposable = true; + View.Instances.Clear (); RunState.Instances.Clear (); #endif diff --git a/UnitTests/Application/StackExtensionsTests.cs b/Tests/UnitTests/Application/StackExtensionsTests.cs similarity index 100% rename from UnitTests/Application/StackExtensionsTests.cs rename to Tests/UnitTests/Application/StackExtensionsTests.cs diff --git a/UnitTests/Application/SynchronizatonContextTests.cs b/Tests/UnitTests/Application/SynchronizatonContextTests.cs similarity index 99% rename from UnitTests/Application/SynchronizatonContextTests.cs rename to Tests/UnitTests/Application/SynchronizatonContextTests.cs index 8aeb36ceb..0e878983b 100644 --- a/UnitTests/Application/SynchronizatonContextTests.cs +++ b/Tests/UnitTests/Application/SynchronizatonContextTests.cs @@ -1,5 +1,7 @@ // Alias Console to MockConsole so we don't accidentally use Console +using UnitTests; + namespace Terminal.Gui.ApplicationTests; public class SyncrhonizationContextTests diff --git a/UnitTests/AssemblyInfo.cs b/Tests/UnitTests/AssemblyInfo.cs similarity index 100% rename from UnitTests/AssemblyInfo.cs rename to Tests/UnitTests/AssemblyInfo.cs diff --git a/Tests/UnitTests/AutoInitShutdownAttribute.cs b/Tests/UnitTests/AutoInitShutdownAttribute.cs new file mode 100644 index 000000000..c3b35a120 --- /dev/null +++ b/Tests/UnitTests/AutoInitShutdownAttribute.cs @@ -0,0 +1,140 @@ +using System.Diagnostics; +using System.Globalization; +using System.Reflection; +using Xunit.Sdk; + +namespace UnitTests; + +/// +/// Enables test functions annotated with the [AutoInitShutdown] attribute to +/// automatically call Application.Init at start of the test and Application.Shutdown after the +/// test exits. +/// This is necessary because a) Application is a singleton and Init/Shutdown must be called +/// as a pair, and b) all unit test functions should be atomic.. +/// +[AttributeUsage (AttributeTargets.Class | AttributeTargets.Method)] +public class AutoInitShutdownAttribute : BeforeAfterTestAttribute +{ + /// + /// Initializes a [AutoInitShutdown] attribute, which determines if/how Application.Init and Application.Shutdown + /// are automatically called Before/After a test runs. + /// + /// If true, Application.Init will be called Before the test runs. + /// + /// Determines which IConsoleDriver (FakeDriver, WindowsDriver, CursesDriver, NetDriver) + /// will be used when Application.Init is called. If null FakeDriver will be used. Only valid if + /// is true. + /// + /// + /// If true, will force the use of . Only valid if + /// == and is true. + /// + /// + /// Only valid if is true. Only + /// valid if == and is true. + /// + /// + /// Only valid if is true. Only valid if + /// == and is true. + /// + /// Determines what config file locations will load from. + /// If true and is true, the test will fail. + public AutoInitShutdownAttribute ( + bool autoInit = true, + Type consoleDriverType = null, + bool useFakeClipboard = true, + bool fakeClipboardAlwaysThrowsNotSupportedException = false, + bool fakeClipboardIsSupportedAlwaysTrue = false, + ConfigLocations configLocation = ConfigLocations.Default, // DefaultOnly is the default for tests + bool verifyShutdown = false + ) + { + AutoInit = autoInit; + CultureInfo.DefaultThreadCurrentUICulture = CultureInfo.GetCultureInfo ("en-US"); + _driverType = consoleDriverType ?? typeof (FakeDriver); + FakeDriver.FakeBehaviors.UseFakeClipboard = useFakeClipboard; + + FakeDriver.FakeBehaviors.FakeClipboardAlwaysThrowsNotSupportedException = + fakeClipboardAlwaysThrowsNotSupportedException; + FakeDriver.FakeBehaviors.FakeClipboardIsSupportedAlwaysFalse = fakeClipboardIsSupportedAlwaysTrue; + ConfigurationManager.Locations = configLocation; + _verifyShutdown = verifyShutdown; + } + + private readonly bool _verifyShutdown; + private readonly Type _driverType; + + public override void After (MethodInfo methodUnderTest) + { + Debug.WriteLine ($"After: {methodUnderTest.Name}"); + + // Turn off diagnostic flags in case some test left them on + View.Diagnostics = ViewDiagnosticFlags.Off; + + if (AutoInit) + { + // try + { + if (!_verifyShutdown) + { + Application.ResetState (ignoreDisposed: true); + } + + Application.Shutdown (); +#if DEBUG_IDISPOSABLE + if (View.Instances.Count == 0) + { + Assert.Empty (View.Instances); + } + else + { + View.Instances.Clear (); + } +#endif + } + //catch (Exception e) + //{ + // Assert.Fail ($"Application.Shutdown threw an exception after the test exited: {e}"); + //} + //finally + { +#if DEBUG_IDISPOSABLE + View.Instances.Clear (); + Application.ResetState (true); +#endif + } + } + + // Reset to defaults + ConfigurationManager.Locations = ConfigLocations.Default; + ConfigurationManager.Reset (); + + // Enable subsequent tests that call Init to get all config files (the default). + //Locations = ConfigLocations.All; + } + + public override void Before (MethodInfo methodUnderTest) + { + Debug.WriteLine ($"Before: {methodUnderTest.Name}"); + + if (AutoInit) + { +#if DEBUG_IDISPOSABLE + View.DebugIDisposable = true; + + // Clear out any lingering Responder instances from previous tests + if (View.Instances.Count == 0) + { + Assert.Empty (View.Instances); + } + else + { + View.Instances.Clear (); + } +#endif + Application.Init ((IConsoleDriver)Activator.CreateInstance (_driverType)); + } + } + + private bool AutoInit { get; } +} \ No newline at end of file diff --git a/UnitTests/Clipboard/ClipboardTests.cs b/Tests/UnitTests/Clipboard/ClipboardTests.cs similarity index 100% rename from UnitTests/Clipboard/ClipboardTests.cs rename to Tests/UnitTests/Clipboard/ClipboardTests.cs diff --git a/UnitTests/Configuration/AppScopeTests.cs b/Tests/UnitTests/Configuration/AppScopeTests.cs similarity index 99% rename from UnitTests/Configuration/AppScopeTests.cs rename to Tests/UnitTests/Configuration/AppScopeTests.cs index d09e74f1d..4460681da 100644 --- a/UnitTests/Configuration/AppScopeTests.cs +++ b/Tests/UnitTests/Configuration/AppScopeTests.cs @@ -1,4 +1,5 @@ using System.Text.Json; +using UnitTests; using static Terminal.Gui.ConfigurationManager; namespace Terminal.Gui.ConfigurationTests; diff --git a/UnitTests/Configuration/AttributeJsonConverterTests.cs b/Tests/UnitTests/Configuration/AttributeJsonConverterTests.cs similarity index 98% rename from UnitTests/Configuration/AttributeJsonConverterTests.cs rename to Tests/UnitTests/Configuration/AttributeJsonConverterTests.cs index 8487e0271..81e5b6fe2 100644 --- a/UnitTests/Configuration/AttributeJsonConverterTests.cs +++ b/Tests/UnitTests/Configuration/AttributeJsonConverterTests.cs @@ -1,4 +1,5 @@ using System.Text.Json; +using UnitTests; namespace Terminal.Gui.ConfigurationTests; diff --git a/UnitTests/Configuration/ColorJsonConverterTests.cs b/Tests/UnitTests/Configuration/ColorJsonConverterTests.cs similarity index 100% rename from UnitTests/Configuration/ColorJsonConverterTests.cs rename to Tests/UnitTests/Configuration/ColorJsonConverterTests.cs diff --git a/UnitTests/Configuration/ColorSchemeJsonConverterTests.cs b/Tests/UnitTests/Configuration/ColorSchemeJsonConverterTests.cs similarity index 99% rename from UnitTests/Configuration/ColorSchemeJsonConverterTests.cs rename to Tests/UnitTests/Configuration/ColorSchemeJsonConverterTests.cs index 2fd50838b..9ab3b06f9 100644 --- a/UnitTests/Configuration/ColorSchemeJsonConverterTests.cs +++ b/Tests/UnitTests/Configuration/ColorSchemeJsonConverterTests.cs @@ -1,4 +1,5 @@ using System.Text.Json; +using UnitTests; namespace Terminal.Gui.ConfigurationTests; diff --git a/UnitTests/Configuration/ConfigPropertyTests.cs b/Tests/UnitTests/Configuration/ConfigPropertyTests.cs similarity index 100% rename from UnitTests/Configuration/ConfigPropertyTests.cs rename to Tests/UnitTests/Configuration/ConfigPropertyTests.cs diff --git a/UnitTests/Configuration/ConfigurationMangerTests.cs b/Tests/UnitTests/Configuration/ConfigurationMangerTests.cs similarity index 99% rename from UnitTests/Configuration/ConfigurationMangerTests.cs rename to Tests/UnitTests/Configuration/ConfigurationMangerTests.cs index 0ab76e4c2..96239c1f6 100644 --- a/UnitTests/Configuration/ConfigurationMangerTests.cs +++ b/Tests/UnitTests/Configuration/ConfigurationMangerTests.cs @@ -1,6 +1,7 @@ using System.Diagnostics; using System.Reflection; using System.Text.Json; +using UnitTests; using Xunit.Abstractions; using static Terminal.Gui.ConfigurationManager; #pragma warning disable IDE1006 diff --git a/UnitTests/Configuration/GlyphTests.cs b/Tests/UnitTests/Configuration/GlyphTests.cs similarity index 100% rename from UnitTests/Configuration/GlyphTests.cs rename to Tests/UnitTests/Configuration/GlyphTests.cs diff --git a/UnitTests/Configuration/KeyCodeJsonConverterTests.cs b/Tests/UnitTests/Configuration/KeyCodeJsonConverterTests.cs similarity index 100% rename from UnitTests/Configuration/KeyCodeJsonConverterTests.cs rename to Tests/UnitTests/Configuration/KeyCodeJsonConverterTests.cs diff --git a/UnitTests/Configuration/KeyJsonConverterTests.cs b/Tests/UnitTests/Configuration/KeyJsonConverterTests.cs similarity index 100% rename from UnitTests/Configuration/KeyJsonConverterTests.cs rename to Tests/UnitTests/Configuration/KeyJsonConverterTests.cs diff --git a/UnitTests/Configuration/RuneJsonConverterTests.cs b/Tests/UnitTests/Configuration/RuneJsonConverterTests.cs similarity index 100% rename from UnitTests/Configuration/RuneJsonConverterTests.cs rename to Tests/UnitTests/Configuration/RuneJsonConverterTests.cs diff --git a/UnitTests/Configuration/SerializableConfigurationPropertyTests.cs b/Tests/UnitTests/Configuration/SerializableConfigurationPropertyTests.cs similarity index 100% rename from UnitTests/Configuration/SerializableConfigurationPropertyTests.cs rename to Tests/UnitTests/Configuration/SerializableConfigurationPropertyTests.cs diff --git a/UnitTests/Configuration/SettingsScopeTests.cs b/Tests/UnitTests/Configuration/SettingsScopeTests.cs similarity index 98% rename from UnitTests/Configuration/SettingsScopeTests.cs rename to Tests/UnitTests/Configuration/SettingsScopeTests.cs index 805a01fbd..349b6f31a 100644 --- a/UnitTests/Configuration/SettingsScopeTests.cs +++ b/Tests/UnitTests/Configuration/SettingsScopeTests.cs @@ -1,4 +1,5 @@ -using static Terminal.Gui.ConfigurationManager; +using UnitTests; +using static Terminal.Gui.ConfigurationManager; namespace Terminal.Gui.ConfigurationTests; diff --git a/UnitTests/Configuration/ThemeScopeTests.cs b/Tests/UnitTests/Configuration/ThemeScopeTests.cs similarity index 99% rename from UnitTests/Configuration/ThemeScopeTests.cs rename to Tests/UnitTests/Configuration/ThemeScopeTests.cs index 28477f423..497b2ddea 100644 --- a/UnitTests/Configuration/ThemeScopeTests.cs +++ b/Tests/UnitTests/Configuration/ThemeScopeTests.cs @@ -1,4 +1,5 @@ using System.Text.Json; +using UnitTests; using static Terminal.Gui.ConfigurationManager; namespace Terminal.Gui.ConfigurationTests; diff --git a/UnitTests/Configuration/ThemeTests.cs b/Tests/UnitTests/Configuration/ThemeTests.cs similarity index 99% rename from UnitTests/Configuration/ThemeTests.cs rename to Tests/UnitTests/Configuration/ThemeTests.cs index 70a1b393b..8482b7a0d 100644 --- a/UnitTests/Configuration/ThemeTests.cs +++ b/Tests/UnitTests/Configuration/ThemeTests.cs @@ -1,4 +1,5 @@ using System.Text.Json; +using UnitTests; using static Terminal.Gui.ConfigurationManager; namespace Terminal.Gui.ConfigurationTests; diff --git a/UnitTests/ConsoleDrivers/AddRuneTests.cs b/Tests/UnitTests/ConsoleDrivers/AddRuneTests.cs similarity index 95% rename from UnitTests/ConsoleDrivers/AddRuneTests.cs rename to Tests/UnitTests/ConsoleDrivers/AddRuneTests.cs index 5c753386e..77d4cf758 100644 --- a/UnitTests/ConsoleDrivers/AddRuneTests.cs +++ b/Tests/UnitTests/ConsoleDrivers/AddRuneTests.cs @@ -68,22 +68,22 @@ public class AddRuneTests // var s = "a\u0301\u0300\u0306"; - // TestHelpers.AssertDriverContentsWithFrameAre (@" + // DriverAsserts.AssertDriverContentsWithFrameAre (@" //ắ", output); // tf.Text = "\u1eaf"; // Application.Refresh (); - // TestHelpers.AssertDriverContentsWithFrameAre (@" + // DriverAsserts.AssertDriverContentsWithFrameAre (@" //ắ", output); // tf.Text = "\u0103\u0301"; // Application.Refresh (); - // TestHelpers.AssertDriverContentsWithFrameAre (@" + // DriverAsserts.AssertDriverContentsWithFrameAre (@" //ắ", output); // tf.Text = "\u0061\u0306\u0301"; // Application.Refresh (); - // TestHelpers.AssertDriverContentsWithFrameAre (@" + // DriverAsserts.AssertDriverContentsWithFrameAre (@" //ắ", output); driver.End (); } diff --git a/UnitTests/ConsoleDrivers/AnsiKeyboardParserTests.cs b/Tests/UnitTests/ConsoleDrivers/AnsiKeyboardParserTests.cs similarity index 100% rename from UnitTests/ConsoleDrivers/AnsiKeyboardParserTests.cs rename to Tests/UnitTests/ConsoleDrivers/AnsiKeyboardParserTests.cs diff --git a/UnitTests/ConsoleDrivers/AnsiMouseParserTests.cs b/Tests/UnitTests/ConsoleDrivers/AnsiMouseParserTests.cs similarity index 100% rename from UnitTests/ConsoleDrivers/AnsiMouseParserTests.cs rename to Tests/UnitTests/ConsoleDrivers/AnsiMouseParserTests.cs diff --git a/UnitTests/ConsoleDrivers/AnsiRequestSchedulerTests.cs b/Tests/UnitTests/ConsoleDrivers/AnsiRequestSchedulerTests.cs similarity index 100% rename from UnitTests/ConsoleDrivers/AnsiRequestSchedulerTests.cs rename to Tests/UnitTests/ConsoleDrivers/AnsiRequestSchedulerTests.cs diff --git a/UnitTests/ConsoleDrivers/AnsiResponseParserTests.cs b/Tests/UnitTests/ConsoleDrivers/AnsiResponseParserTests.cs similarity index 100% rename from UnitTests/ConsoleDrivers/AnsiResponseParserTests.cs rename to Tests/UnitTests/ConsoleDrivers/AnsiResponseParserTests.cs diff --git a/UnitTests/ConsoleDrivers/ClipRegionTests.cs b/Tests/UnitTests/ConsoleDrivers/ClipRegionTests.cs similarity index 100% rename from UnitTests/ConsoleDrivers/ClipRegionTests.cs rename to Tests/UnitTests/ConsoleDrivers/ClipRegionTests.cs diff --git a/UnitTests/ConsoleDrivers/ConsoleDriverTests.cs b/Tests/UnitTests/ConsoleDrivers/ConsoleDriverTests.cs similarity index 98% rename from UnitTests/ConsoleDrivers/ConsoleDriverTests.cs rename to Tests/UnitTests/ConsoleDrivers/ConsoleDriverTests.cs index cd957af48..fbede01b0 100644 --- a/UnitTests/ConsoleDrivers/ConsoleDriverTests.cs +++ b/Tests/UnitTests/ConsoleDrivers/ConsoleDriverTests.cs @@ -256,7 +256,7 @@ public class ConsoleDriverTests //└──────────────────┘ //"; - // var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + // var pos = DriverAsserts.AssertDriverContentsWithFrameAre (expected, output); // Assert.Equal (new (0, 0, 20, 8), pos); // Assert.True (dlg.ProcessKey (new (Key.Tab))); @@ -273,7 +273,7 @@ public class ConsoleDriverTests //└──────────────────┘ //"; - // pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + // pos = DriverAsserts.AssertDriverContentsWithFrameAre (expected, output); // Assert.Equal (new (0, 0, 20, 8), pos); // win.RequestStop (); diff --git a/UnitTests/ConsoleDrivers/ConsoleKeyMappingTests.cs b/Tests/UnitTests/ConsoleDrivers/ConsoleKeyMappingTests.cs similarity index 100% rename from UnitTests/ConsoleDrivers/ConsoleKeyMappingTests.cs rename to Tests/UnitTests/ConsoleDrivers/ConsoleKeyMappingTests.cs diff --git a/UnitTests/ConsoleDrivers/ConsoleScrolllingTests.cs b/Tests/UnitTests/ConsoleDrivers/ConsoleScrolllingTests.cs similarity index 100% rename from UnitTests/ConsoleDrivers/ConsoleScrolllingTests.cs rename to Tests/UnitTests/ConsoleDrivers/ConsoleScrolllingTests.cs diff --git a/UnitTests/ConsoleDrivers/ContentsTests.cs b/Tests/UnitTests/ConsoleDrivers/ContentsTests.cs similarity index 91% rename from UnitTests/ConsoleDrivers/ContentsTests.cs rename to Tests/UnitTests/ConsoleDrivers/ContentsTests.cs index d0f2d83ff..577ac2062 100644 --- a/UnitTests/ConsoleDrivers/ContentsTests.cs +++ b/Tests/UnitTests/ConsoleDrivers/ContentsTests.cs @@ -1,4 +1,6 @@ using System.Text; +using UnitTests; +using UnitTests; using Xunit.Abstractions; // Alias Console to MockConsole so we don't accidentally use Console @@ -28,7 +30,7 @@ public class ContentsTests driver.Init (); var expected = "\u0301!"; driver.AddStr ("\u0301!"); // acute accent + exclamation mark - TestHelpers.AssertDriverContentsAre (expected, output, driver); + DriverAssert.AssertDriverContentsAre (expected, output, driver); driver.End (); } @@ -50,7 +52,7 @@ public class ContentsTests var expected = "é"; driver.AddStr (combined); - TestHelpers.AssertDriverContentsAre (expected, output, driver); + DriverAssert.AssertDriverContentsAre (expected, output, driver); // 3 char combine // a + ogonek + acute = ( ą́ ) @@ -60,7 +62,7 @@ public class ContentsTests driver.Move (0, 0); driver.AddStr (combined); - TestHelpers.AssertDriverContentsAre (expected, output, driver); + DriverAssert.AssertDriverContentsAre (expected, output, driver); // e + ogonek + acute = ( ę́́ ) combined = "e" + ogonek + acuteaccent; @@ -68,7 +70,7 @@ public class ContentsTests driver.Move (0, 0); driver.AddStr (combined); - TestHelpers.AssertDriverContentsAre (expected, output, driver); + DriverAssert.AssertDriverContentsAre (expected, output, driver); // i + ogonek + acute = ( į́́́ ) combined = "i" + ogonek + acuteaccent; @@ -76,7 +78,7 @@ public class ContentsTests driver.Move (0, 0); driver.AddStr (combined); - TestHelpers.AssertDriverContentsAre (expected, output, driver); + DriverAssert.AssertDriverContentsAre (expected, output, driver); // u + ogonek + acute = ( ų́́́́ ) combined = "u" + ogonek + acuteaccent; @@ -84,7 +86,7 @@ public class ContentsTests driver.Move (0, 0); driver.AddStr (combined); - TestHelpers.AssertDriverContentsAre (expected, output, driver); + DriverAssert.AssertDriverContentsAre (expected, output, driver); driver.End (); } diff --git a/UnitTests/ConsoleDrivers/DriverColorTests.cs b/Tests/UnitTests/ConsoleDrivers/DriverColorTests.cs similarity index 100% rename from UnitTests/ConsoleDrivers/DriverColorTests.cs rename to Tests/UnitTests/ConsoleDrivers/DriverColorTests.cs diff --git a/UnitTests/ConsoleDrivers/KeyCodeTests.cs b/Tests/UnitTests/ConsoleDrivers/KeyCodeTests.cs similarity index 100% rename from UnitTests/ConsoleDrivers/KeyCodeTests.cs rename to Tests/UnitTests/ConsoleDrivers/KeyCodeTests.cs diff --git a/UnitTests/ConsoleDrivers/MainLoopDriverTests.cs b/Tests/UnitTests/ConsoleDrivers/MainLoopDriverTests.cs similarity index 100% rename from UnitTests/ConsoleDrivers/MainLoopDriverTests.cs rename to Tests/UnitTests/ConsoleDrivers/MainLoopDriverTests.cs diff --git a/UnitTests/ConsoleDrivers/V2/ApplicationV2Tests.cs b/Tests/UnitTests/ConsoleDrivers/V2/ApplicationV2Tests.cs similarity index 100% rename from UnitTests/ConsoleDrivers/V2/ApplicationV2Tests.cs rename to Tests/UnitTests/ConsoleDrivers/V2/ApplicationV2Tests.cs diff --git a/UnitTests/ConsoleDrivers/V2/ConsoleInputTests.cs b/Tests/UnitTests/ConsoleDrivers/V2/ConsoleInputTests.cs similarity index 100% rename from UnitTests/ConsoleDrivers/V2/ConsoleInputTests.cs rename to Tests/UnitTests/ConsoleDrivers/V2/ConsoleInputTests.cs diff --git a/UnitTests/ConsoleDrivers/V2/MainLoopCoordinatorTests.cs b/Tests/UnitTests/ConsoleDrivers/V2/MainLoopCoordinatorTests.cs similarity index 100% rename from UnitTests/ConsoleDrivers/V2/MainLoopCoordinatorTests.cs rename to Tests/UnitTests/ConsoleDrivers/V2/MainLoopCoordinatorTests.cs diff --git a/UnitTests/ConsoleDrivers/V2/MainLoopTTests.cs b/Tests/UnitTests/ConsoleDrivers/V2/MainLoopTTests.cs similarity index 100% rename from UnitTests/ConsoleDrivers/V2/MainLoopTTests.cs rename to Tests/UnitTests/ConsoleDrivers/V2/MainLoopTTests.cs diff --git a/UnitTests/ConsoleDrivers/V2/MouseInterpreterTests.cs b/Tests/UnitTests/ConsoleDrivers/V2/MouseInterpreterTests.cs similarity index 100% rename from UnitTests/ConsoleDrivers/V2/MouseInterpreterTests.cs rename to Tests/UnitTests/ConsoleDrivers/V2/MouseInterpreterTests.cs diff --git a/UnitTests/ConsoleDrivers/V2/NetInputProcessorTests.cs b/Tests/UnitTests/ConsoleDrivers/V2/NetInputProcessorTests.cs similarity index 100% rename from UnitTests/ConsoleDrivers/V2/NetInputProcessorTests.cs rename to Tests/UnitTests/ConsoleDrivers/V2/NetInputProcessorTests.cs diff --git a/UnitTests/ConsoleDrivers/V2/WindowSizeMonitorTests.cs b/Tests/UnitTests/ConsoleDrivers/V2/WindowSizeMonitorTests.cs similarity index 100% rename from UnitTests/ConsoleDrivers/V2/WindowSizeMonitorTests.cs rename to Tests/UnitTests/ConsoleDrivers/V2/WindowSizeMonitorTests.cs diff --git a/UnitTests/ConsoleDrivers/V2/WindowsInputProcessorTests.cs b/Tests/UnitTests/ConsoleDrivers/V2/WindowsInputProcessorTests.cs similarity index 100% rename from UnitTests/ConsoleDrivers/V2/WindowsInputProcessorTests.cs rename to Tests/UnitTests/ConsoleDrivers/V2/WindowsInputProcessorTests.cs diff --git a/UnitTests/Dialogs/DialogTests.cs b/Tests/UnitTests/Dialogs/DialogTests.cs similarity index 92% rename from UnitTests/Dialogs/DialogTests.cs rename to Tests/UnitTests/Dialogs/DialogTests.cs index 9009b41d3..b05859816 100644 --- a/UnitTests/Dialogs/DialogTests.cs +++ b/Tests/UnitTests/Dialogs/DialogTests.cs @@ -1,3 +1,5 @@ +using UnitTests; +using UnitTests; using Xunit.Abstractions; using static Terminal.Gui.Application; @@ -6,7 +8,14 @@ namespace Terminal.Gui.DialogTests; public class DialogTests { private readonly ITestOutputHelper _output; - public DialogTests (ITestOutputHelper output) { _output = output; } + + public DialogTests (ITestOutputHelper output) + { +#if DEBUG_IDISPOSABLE + View.DebugIDisposable = true; +#endif + _output = output; + } [Fact] [AutoInitShutdown] @@ -49,14 +58,14 @@ public class DialogTests RunIteration (ref runstate); - TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); + DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); // Now add a second button buttonRow = $"{Glyphs.VLine} {btn1} {btn2} {Glyphs.VLine}"; dlg.AddButton (new () { Text = btn2Text }); RunIteration (ref runstate); - TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); + DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); End (runstate); dlg.Dispose (); @@ -77,13 +86,13 @@ public class DialogTests RunIteration (ref runstate); buttonRow = $"{Glyphs.VLine}{btn1} {Glyphs.VLine}"; - TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); + DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); // Now add a second button buttonRow = $"{Glyphs.VLine}{btn1} {btn2}{Glyphs.VLine}"; dlg.AddButton (new () { Text = btn2Text }); RunIteration (ref runstate); - TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); + DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); End (runstate); dlg.Dispose (); @@ -104,14 +113,14 @@ public class DialogTests RunIteration (ref runstate); buttonRow = $"{Glyphs.VLine}{new (' ', width - btn1.Length - 2)}{btn1}{Glyphs.VLine}"; - TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); + DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); // Now add a second button buttonRow = $"{Glyphs.VLine} {btn1} {btn2}{Glyphs.VLine}"; dlg.AddButton (new () { Text = btn2Text }); RunIteration (ref runstate); - TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); + DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); End (runstate); dlg.Dispose (); @@ -131,14 +140,14 @@ public class DialogTests RunIteration (ref runstate); buttonRow = $"{Glyphs.VLine}{btn1}{new (' ', width - btn1.Length - 2)}{Glyphs.VLine}"; - TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); + DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); // Now add a second button buttonRow = $"{Glyphs.VLine}{btn1} {btn2} {Glyphs.VLine}"; dlg.AddButton (new () { Text = btn2Text }); RunIteration (ref runstate); - TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); + DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); End (runstate); dlg.Dispose (); } @@ -179,7 +188,7 @@ public class DialogTests new Button { Text = btn3Text }, new Button { Text = btn4Text } ); - TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); + DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); End (runstate); dlg.Dispose (); @@ -196,7 +205,7 @@ public class DialogTests new Button { Text = btn3Text }, new Button { Text = btn4Text } ); - TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); + DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); End (runstate); dlg.Dispose (); @@ -213,7 +222,7 @@ public class DialogTests new Button { Text = btn3Text }, new Button { Text = btn4Text } ); - TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); + DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); End (runstate); dlg.Dispose (); @@ -230,7 +239,7 @@ public class DialogTests new Button { Text = btn3Text }, new Button { Text = btn4Text } ); - TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); + DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); End (runstate); dlg.Dispose (); } @@ -275,7 +284,7 @@ public class DialogTests new Button { Text = btn4Text } ); Assert.Equal (new (width, 1), dlg.Frame.Size); - TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); + DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); End (runstate); dlg.Dispose (); @@ -292,7 +301,7 @@ public class DialogTests new Button { Text = btn3Text }, new Button { Text = btn4Text } ); - TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); + DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); End (runstate); dlg.Dispose (); @@ -309,7 +318,7 @@ public class DialogTests new Button { Text = btn3Text }, new Button { Text = btn4Text } ); - TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); + DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); End (runstate); dlg.Dispose (); @@ -325,7 +334,7 @@ public class DialogTests new Button { Text = btn3Text }, new Button { Text = btn4Text } ); - TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); + DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); End (runstate); dlg.Dispose (); } @@ -368,7 +377,7 @@ public class DialogTests new Button { Text = btn3Text }, new Button { Text = btn4Text } ); - TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); + DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); End (runstate); dlg.Dispose (); @@ -385,7 +394,7 @@ public class DialogTests new Button { Text = btn3Text }, new Button { Text = btn4Text } ); - TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); + DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); End (runstate); dlg.Dispose (); @@ -402,7 +411,7 @@ public class DialogTests new Button { Text = btn3Text }, new Button { Text = btn4Text } ); - TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); + DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); End (runstate); dlg.Dispose (); @@ -419,7 +428,7 @@ public class DialogTests new Button { Text = btn3Text }, new Button { Text = btn4Text } ); - TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); + DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); End (runstate); dlg.Dispose (); } @@ -464,7 +473,7 @@ public class DialogTests new Button { Text = btn3Text }, new Button { Text = btn4Text } ); - TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); + DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); End (runstate); dlg.Dispose (); @@ -481,7 +490,7 @@ public class DialogTests new Button { Text = btn3Text }, new Button { Text = btn4Text } ); - TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); + DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); End (runstate); dlg.Dispose (); @@ -498,7 +507,7 @@ public class DialogTests new Button { Text = btn3Text }, new Button { Text = btn4Text } ); - TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); + DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); End (runstate); dlg.Dispose (); @@ -515,7 +524,7 @@ public class DialogTests new Button { Text = btn3Text }, new Button { Text = btn4Text } ); - TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); + DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); End (runstate); dlg.Dispose (); } @@ -548,7 +557,7 @@ public class DialogTests ); // Center - TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); + DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); End (runstate); dlg.Dispose (); @@ -563,7 +572,7 @@ public class DialogTests Alignment.Fill, new Button { Text = btnText } ); - TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); + DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); End (runstate); dlg.Dispose (); @@ -578,7 +587,7 @@ public class DialogTests Alignment.End, new Button { Text = btnText } ); - TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); + DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); End (runstate); dlg.Dispose (); @@ -593,7 +602,7 @@ public class DialogTests Alignment.Start, new Button { Text = btnText } ); - TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); + DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); End (runstate); dlg.Dispose (); @@ -610,7 +619,7 @@ public class DialogTests Alignment.Center, new Button { Text = btnText } ); - TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); + DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); End (runstate); dlg.Dispose (); @@ -625,7 +634,7 @@ public class DialogTests Alignment.Fill, new Button { Text = btnText } ); - TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); + DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); End (runstate); dlg.Dispose (); @@ -640,7 +649,7 @@ public class DialogTests Alignment.End, new Button { Text = btnText } ); - TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); + DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); End (runstate); dlg.Dispose (); @@ -655,7 +664,7 @@ public class DialogTests Alignment.Start, new Button { Text = btnText } ); - TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); + DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); End (runstate); dlg.Dispose (); } @@ -693,7 +702,7 @@ public class DialogTests new Button { Text = btn2Text }, new Button { Text = btn3Text } ); - TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); + DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); End (runstate); dlg.Dispose (); @@ -709,7 +718,7 @@ public class DialogTests new Button { Text = btn2Text }, new Button { Text = btn3Text } ); - TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); + DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); End (runstate); dlg.Dispose (); @@ -725,7 +734,7 @@ public class DialogTests new Button { Text = btn2Text }, new Button { Text = btn3Text } ); - TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); + DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); End (runstate); dlg.Dispose (); @@ -741,7 +750,7 @@ public class DialogTests new Button { Text = btn2Text }, new Button { Text = btn3Text } ); - TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); + DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); End (runstate); dlg.Dispose (); } @@ -776,7 +785,7 @@ public class DialogTests new Button { Text = btn1Text }, new Button { Text = btn2Text } ); - TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); + DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); End (runstate); dlg.Dispose (); @@ -791,7 +800,7 @@ public class DialogTests new Button { Text = btn1Text }, new Button { Text = btn2Text } ); - TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); + DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); End (runstate); dlg.Dispose (); @@ -806,7 +815,7 @@ public class DialogTests new Button { Text = btn1Text }, new Button { Text = btn2Text } ); - TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); + DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); End (runstate); dlg.Dispose (); @@ -821,7 +830,7 @@ public class DialogTests new Button { Text = btn1Text }, new Button { Text = btn2Text } ); - TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); + DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); End (runstate); dlg.Dispose (); } @@ -860,7 +869,7 @@ public class DialogTests button1.Visible = false; RunIteration (ref runstate, firstIteration); buttonRow = $@"{Glyphs.VLine} {btn2} {Glyphs.VLine}"; - TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); + DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); End (runstate); dlg.Dispose (); @@ -872,7 +881,7 @@ public class DialogTests button1.Visible = false; RunIteration (ref runstate, firstIteration); buttonRow = $@"{Glyphs.VLine} {btn2}{Glyphs.VLine}"; - TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); + DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); End (runstate); dlg.Dispose (); @@ -883,7 +892,7 @@ public class DialogTests (runstate, dlg) = BeginButtonTestDialog (title, width, Alignment.End, button1, button2); button1.Visible = false; RunIteration (ref runstate, firstIteration); - TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); + DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); End (runstate); dlg.Dispose (); @@ -895,7 +904,7 @@ public class DialogTests button1.Visible = false; RunIteration (ref runstate, firstIteration); buttonRow = $@"{Glyphs.VLine} {btn2} {Glyphs.VLine}"; - TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); + DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); End (runstate); dlg.Dispose (); } @@ -940,7 +949,7 @@ public class DialogTests ││ {btn} ││ │└────────────────┘│ └──────────────────┘"; - _ = TestHelpers.AssertDriverContentsWithFrameAre (expected, _output); + _ = DriverAssert.AssertDriverContentsWithFrameAre (expected, _output); }; Run (dlg); @@ -1040,7 +1049,7 @@ public class DialogTests LayoutAndDraw (); // BUGBUG: This seems wrong; is it a bug in Dim.Percent(85)?? No - _ = TestHelpers.AssertDriverContentsWithFrameAre (expected, _output); + _ = DriverAssert.AssertDriverContentsWithFrameAre (expected, _output); } else { @@ -1129,7 +1138,7 @@ public class DialogTests │ │ │{Glyphs.LeftBracket} Show Sub {Glyphs.RightBracket} {Glyphs.LeftBracket} Close {Glyphs.RightBracket} │ └───────────────────────┘"; - TestHelpers.AssertDriverContentsWithFrameAre (expected, _output); + DriverAssert.AssertDriverContentsWithFrameAre (expected, _output); Assert.False (btn2.NewKeyDownEvent (Key.Space)); @@ -1137,7 +1146,7 @@ public class DialogTests case 3: LayoutAndDraw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @$" ┌───────────────────────┐ │ ┌──────────────────┐ │ @@ -1156,13 +1165,13 @@ public class DialogTests case 4: LayoutAndDraw (); - TestHelpers.AssertDriverContentsWithFrameAre (expected, _output); + DriverAssert.AssertDriverContentsWithFrameAre (expected, _output); Assert.False (btn3.NewKeyDownEvent (Key.Space)); break; case 5: - TestHelpers.AssertDriverContentsWithFrameAre ("", _output); + DriverAssert.AssertDriverContentsWithFrameAre ("", _output); RequestStop (); @@ -1240,7 +1249,7 @@ public class DialogTests // Default location is centered, so 100 / 2 - 85 / 2 = 7 Assert.Equal (new (expected, expected), d.Frame.Location); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌───┐ │ │ @@ -1277,7 +1286,7 @@ public class DialogTests Alignment.Center, new Button { Text = btnText } ); - TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); + DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); End (runstate); dlg.Dispose (); } @@ -1332,7 +1341,7 @@ public class DialogTests (runstate, Dialog dlg) = BeginButtonTestDialog (title, width, Alignment.Center, null); - TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); + DriverAssert.AssertDriverContentsWithFrameAre ($"{buttonRow}", _output); End (runstate); dlg.Dispose (); diff --git a/UnitTests/Dialogs/MessageBoxTests.cs b/Tests/UnitTests/Dialogs/MessageBoxTests.cs similarity index 97% rename from UnitTests/Dialogs/MessageBoxTests.cs rename to Tests/UnitTests/Dialogs/MessageBoxTests.cs index b163d154f..50765272f 100644 --- a/UnitTests/Dialogs/MessageBoxTests.cs +++ b/Tests/UnitTests/Dialogs/MessageBoxTests.cs @@ -1,5 +1,7 @@ using System.Text; using Microsoft.VisualStudio.TestPlatform.CommunicationUtilities; +using UnitTests; +using UnitTests; using Xunit.Abstractions; namespace Terminal.Gui.DialogTests; @@ -221,7 +223,7 @@ public class MessageBoxTests { Application.LayoutAndDraw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ╔════════════════╗ ║ ff ff ff ff ff ║ @@ -238,7 +240,7 @@ public class MessageBoxTests { Application.LayoutAndDraw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ╔════════════════╗ ║ffffffffffffffff║ @@ -293,7 +295,7 @@ public class MessageBoxTests { Application.LayoutAndDraw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ╔══════════════╗ ║ff ff ff ff ff║ @@ -313,7 +315,7 @@ public class MessageBoxTests { Application.LayoutAndDraw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @$" ╔════════════════╗ ║ffffffffffffffff║ @@ -491,7 +493,7 @@ public class MessageBoxTests └────────────────────────────────────────────────────────────────────┘ """; - TestHelpers.AssertDriverContentsAre (expectedText, _output); + DriverAssert.AssertDriverContentsAre (expectedText, _output); Application.RequestStop (); } diff --git a/UnitTests/Dialogs/WizardTests.cs b/Tests/UnitTests/Dialogs/WizardTests.cs similarity index 99% rename from UnitTests/Dialogs/WizardTests.cs rename to Tests/UnitTests/Dialogs/WizardTests.cs index 66fbfc8f9..a73d0e15f 100644 --- a/UnitTests/Dialogs/WizardTests.cs +++ b/Tests/UnitTests/Dialogs/WizardTests.cs @@ -1,4 +1,5 @@ -using Xunit.Abstractions; +using UnitTests; +using Xunit.Abstractions; namespace Terminal.Gui.DialogTests; @@ -467,7 +468,7 @@ public class WizardTests () Application.RunIteration (ref runstate, firstIteration); // TODO: Disabled until Dim.Auto is used in Dialog - //TestHelpers.AssertDriverContentsWithFrameAre ( + //DriverAsserts.AssertDriverContentsWithFrameAre ( // $"{topRow}\n{row2}\n{row3}\n{row4}\n{separatorRow}\n{buttonRow}\n{bottomRow}", // _output // ); @@ -715,7 +716,7 @@ public class WizardTests () RunState runstate = Application.Begin (wizard); // TODO: Disabled until Dim.Auto is used in Dialog - //TestHelpers.AssertDriverContentsWithFrameAre ( + //DriverAsserts.AssertDriverContentsWithFrameAre ( // $"{topRow}\n{row2}\n{row3}\n{separatorRow}\n{buttonRow}\n{bottomRow}", // _output // ); diff --git a/UnitTests/Drawing/LineCanvasTests.cs b/Tests/UnitTests/Drawing/LineCanvasTests.cs similarity index 95% rename from UnitTests/Drawing/LineCanvasTests.cs rename to Tests/UnitTests/Drawing/LineCanvasTests.cs index a9b6f4743..7ef1a449c 100644 --- a/UnitTests/Drawing/LineCanvasTests.cs +++ b/Tests/UnitTests/Drawing/LineCanvasTests.cs @@ -1,4 +1,6 @@ using System.Text; +using UnitTests; +using UnitTests; using Xunit.Abstractions; namespace Terminal.Gui.DrawingTests; @@ -294,7 +296,7 @@ public class LineCanvasTests (ITestOutputHelper _output) lc.AddLine (new (x1, y1), len1, o1, s1); lc.AddLine (new (x2, y2), len2, o2, s2); - TestHelpers.AssertEqual (_output, expected, lc.ToString ()); + OutputAssert.AssertEqual (_output, expected, lc.ToString ()); v.Dispose (); } @@ -502,7 +504,7 @@ public class LineCanvasTests (ITestOutputHelper _output) lc.AddLine (new (x + width, y), height, Orientation.Vertical, LineStyle.Double); Assert.Equal (new (x, y, 4, 2), lc.Bounds); - TestHelpers.AssertEqual ( + OutputAssert.AssertEqual ( _output, @" ╔╡╞╗ @@ -552,7 +554,7 @@ public class LineCanvasTests (ITestOutputHelper _output) lc.AddLine (new (x + width, y), height, Orientation.Vertical, LineStyle.Double); Assert.Equal (new (x, y, 4, 2), lc.Bounds); - TestHelpers.AssertEqual ( + OutputAssert.AssertEqual ( _output, @" ╔╡╞╗ @@ -596,7 +598,7 @@ public class LineCanvasTests (ITestOutputHelper _output) // Add a line at 5, 5 that's has length of 1 canvas.AddLine (new (x, y), 1, orientation, LineStyle.Single); - TestHelpers.AssertEqual (_output, $"{expected}", $"{canvas}"); + OutputAssert.AssertEqual (_output, $"{expected}", $"{canvas}"); } // X is offset by 2 @@ -653,7 +655,7 @@ public class LineCanvasTests (ITestOutputHelper _output) canvas.AddLine (new (x, y), length, orientation, LineStyle.Single); var result = canvas.ToString (); - TestHelpers.AssertEqual (_output, expected, result); + OutputAssert.AssertEqual (_output, expected, result); } [Fact] @@ -680,7 +682,7 @@ public class LineCanvasTests (ITestOutputHelper _output) // Add a line at 0, 0 that's has length of 0 lc.AddLine (Point.Empty, 0, orientation, LineStyle.Single); - TestHelpers.AssertEqual (_output, expected, $"{lc}"); + OutputAssert.AssertEqual (_output, expected, $"{lc}"); } [InlineData (Orientation.Horizontal, "┼")] @@ -701,7 +703,7 @@ public class LineCanvasTests (ITestOutputHelper _output) // Add a line at 0, 0 that's has length of 0 lc.AddLine (Point.Empty, 0, orientation, LineStyle.Single); - TestHelpers.AssertEqual (_output, expected, $"{lc}"); + OutputAssert.AssertEqual (_output, expected, $"{lc}"); } [InlineData (Orientation.Horizontal, "╥")] @@ -724,7 +726,7 @@ public class LineCanvasTests (ITestOutputHelper _output) // Add a line at 0, 0 that's has length of 0 lc.AddLine (Point.Empty, 0, orientation, LineStyle.Single); - TestHelpers.AssertEqual (_output, expected, $"{lc}"); + OutputAssert.AssertEqual (_output, expected, $"{lc}"); } [Fact] @@ -740,7 +742,7 @@ public class LineCanvasTests (ITestOutputHelper _output) @" ┌─ │ "; - TestHelpers.AssertEqual (_output, looksLike, $"{Environment.NewLine}{canvas}"); + OutputAssert.AssertEqual (_output, looksLike, $"{Environment.NewLine}{canvas}"); } [Fact] @@ -767,7 +769,7 @@ public class LineCanvasTests (ITestOutputHelper _output) ┣━━━━╋━━━┫ ┃ ┃ ┃ ┗━━━━┻━━━┛"; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); v.Dispose (); } @@ -798,7 +800,7 @@ public class LineCanvasTests (ITestOutputHelper _output) │ │ │ ┕━━━━┷━━━┙ "; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); v.Dispose (); } @@ -830,7 +832,7 @@ public class LineCanvasTests (ITestOutputHelper _output) ┖────┸───┚ "; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); v.Dispose (); } @@ -848,7 +850,7 @@ public class LineCanvasTests (ITestOutputHelper _output) @" ┌─ │ "; - TestHelpers.AssertEqual (_output, looksLike, $"{Environment.NewLine}{canvas}"); + OutputAssert.AssertEqual (_output, looksLike, $"{Environment.NewLine}{canvas}"); } [Fact] @@ -877,7 +879,7 @@ public class LineCanvasTests (ITestOutputHelper _output) Dictionary map = canvas.GetMap (); Assert.Equal (2, map.Count); - TestHelpers.AssertEqual ( + OutputAssert.AssertEqual ( _output, @" ─ @@ -891,7 +893,7 @@ public class LineCanvasTests (ITestOutputHelper _output) public void ToString_Empty () { var lc = new LineCanvas (); - TestHelpers.AssertEqual (_output, string.Empty, lc.ToString ()); + OutputAssert.AssertEqual (_output, string.Empty, lc.ToString ()); } // 012 @@ -910,7 +912,7 @@ public class LineCanvasTests (ITestOutputHelper _output) { var lc = new LineCanvas (); lc.AddLine (new (x, y), 3, Orientation.Horizontal, LineStyle.Double); - TestHelpers.AssertEqual (_output, expected, $"{lc}"); + OutputAssert.AssertEqual (_output, expected, $"{lc}"); } [InlineData (0, 0, 0, 0, "═══")] @@ -935,7 +937,7 @@ public class LineCanvasTests (ITestOutputHelper _output) lc.AddLine (new (x1, y1), 3, Orientation.Horizontal, LineStyle.Double); lc.AddLine (new (x2, y2), 3, Orientation.Horizontal, LineStyle.Double); - TestHelpers.AssertEqual (_output, expected, $"{lc}"); + OutputAssert.AssertEqual (_output, expected, $"{lc}"); } // [Fact, SetupFakeDriver] @@ -995,7 +997,7 @@ public class LineCanvasTests (ITestOutputHelper _output) v.Draw (); - TestHelpers.AssertDriverContentsAre (expected, _output); + DriverAssert.AssertDriverContentsAre (expected, _output); v.Dispose (); } @@ -1014,7 +1016,7 @@ public class LineCanvasTests (ITestOutputHelper _output) @" ┌─ │"; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); v.Dispose (); } @@ -1037,7 +1039,7 @@ public class LineCanvasTests (ITestOutputHelper _output) ── │ │"; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); v.Dispose (); } @@ -1055,7 +1057,7 @@ public class LineCanvasTests (ITestOutputHelper _output) var looksLike = @" ──"; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); v.Dispose (); } @@ -1071,7 +1073,7 @@ public class LineCanvasTests (ITestOutputHelper _output) var looksLike = @" ══"; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); v.Dispose (); } @@ -1090,7 +1092,7 @@ public class LineCanvasTests (ITestOutputHelper _output) @" │ │"; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); v.Dispose (); } @@ -1107,7 +1109,7 @@ public class LineCanvasTests (ITestOutputHelper _output) @" ║ ║"; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); v.Dispose (); } @@ -1135,7 +1137,7 @@ public class LineCanvasTests (ITestOutputHelper _output) ╠════╬═══╣ ║ ║ ║ ╚════╩═══╝"; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); v.Dispose (); } @@ -1166,7 +1168,7 @@ public class LineCanvasTests (ITestOutputHelper _output) │ │ │ ╘════╧═══╛ "; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); v.Dispose (); } @@ -1203,7 +1205,7 @@ public class LineCanvasTests (ITestOutputHelper _output) ├────┼───┤ │ │ │ ╰────┴───╯"; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); v.Dispose (); } @@ -1235,7 +1237,7 @@ public class LineCanvasTests (ITestOutputHelper _output) ╙────╨───╜ "; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); v.Dispose (); } @@ -1262,7 +1264,7 @@ public class LineCanvasTests (ITestOutputHelper _output) ├────┼───┤ │ │ │ └────┴───┘"; - TestHelpers.AssertEqual (_output, looksLike, $"{Environment.NewLine}{canvas}"); + OutputAssert.AssertEqual (_output, looksLike, $"{Environment.NewLine}{canvas}"); } [Fact] @@ -1300,7 +1302,7 @@ public class LineCanvasTests (ITestOutputHelper _output) var looksLike = @" ╔╡╞══╗ ║ ║"; - TestHelpers.AssertEqual (_output, looksLike, $"{Environment.NewLine}{lc}"); + OutputAssert.AssertEqual (_output, looksLike, $"{Environment.NewLine}{lc}"); } [Fact] diff --git a/UnitTests/Drawing/RulerTests.cs b/Tests/UnitTests/Drawing/RulerTests.cs similarity index 87% rename from UnitTests/Drawing/RulerTests.cs rename to Tests/UnitTests/Drawing/RulerTests.cs index b58b64c98..f259a601e 100644 --- a/UnitTests/Drawing/RulerTests.cs +++ b/Tests/UnitTests/Drawing/RulerTests.cs @@ -1,4 +1,6 @@ -using Xunit.Abstractions; +using UnitTests; +using UnitTests; +using Xunit.Abstractions; namespace Terminal.Gui.DrawingTests; @@ -33,7 +35,7 @@ public class RulerTests var r = new Ruler (); r.Draw (Point.Empty); - TestHelpers.AssertDriverContentsWithFrameAre (@"", _output); + DriverAssert.AssertDriverContentsWithFrameAre (@"", _output); } [Fact] @@ -48,7 +50,7 @@ public class RulerTests r.Length = len; r.Draw (Point.Empty); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" |123456789|1234", _output @@ -57,7 +59,7 @@ public class RulerTests // Postive offset r.Draw (new (1, 1)); - TestHelpers.AssertDriverContentsAre ( + DriverAssert.AssertDriverContentsAre ( @" |123456789|1234 |123456789|1234 @@ -68,7 +70,7 @@ public class RulerTests // Negative offset r.Draw (new (-1, 3)); - TestHelpers.AssertDriverContentsAre ( + DriverAssert.AssertDriverContentsAre ( @" |123456789|1234 |123456789|1234 @@ -89,7 +91,7 @@ public class RulerTests r.Length = len; r.Draw (Point.Empty); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" - 1 @@ -111,7 +113,7 @@ public class RulerTests r.Draw (new (1, 1)); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" - 1- @@ -135,7 +137,7 @@ public class RulerTests // Negative offset r.Draw (new (2, -1)); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" - 1 1-2 diff --git a/UnitTests/Drawing/StraightLineExtensionsTests.cs b/Tests/UnitTests/Drawing/StraightLineExtensionsTests.cs similarity index 97% rename from UnitTests/Drawing/StraightLineExtensionsTests.cs rename to Tests/UnitTests/Drawing/StraightLineExtensionsTests.cs index 865ae805a..5de27b964 100644 --- a/UnitTests/Drawing/StraightLineExtensionsTests.cs +++ b/Tests/UnitTests/Drawing/StraightLineExtensionsTests.cs @@ -1,4 +1,6 @@ -using Xunit.Abstractions; +using UnitTests; +using UnitTests; +using Xunit.Abstractions; namespace Terminal.Gui.DrawingTests; @@ -14,7 +16,7 @@ public class StraightLineExtensionsTests (ITestOutputHelper output) lc.AddLine (new Point (9, 4), -10, Orientation.Horizontal, LineStyle.Single); lc.AddLine (new Point (0, 4), -5, Orientation.Vertical, LineStyle.Single); - TestHelpers.AssertEqual ( + OutputAssert.AssertEqual ( output, @" ┌────────┐ @@ -28,7 +30,7 @@ public class StraightLineExtensionsTests (ITestOutputHelper output) lc = new LineCanvas (origLines.Exclude (Point.Empty, 10, Orientation.Horizontal)); - TestHelpers.AssertEqual ( + OutputAssert.AssertEqual ( output, @" │ │ @@ -40,7 +42,7 @@ public class StraightLineExtensionsTests (ITestOutputHelper output) lc = new LineCanvas (origLines.Exclude (new Point (0, 1), 10, Orientation.Horizontal)); - TestHelpers.AssertEqual ( + OutputAssert.AssertEqual ( output, @" ┌────────┐ @@ -53,7 +55,7 @@ public class StraightLineExtensionsTests (ITestOutputHelper output) lc = new LineCanvas (origLines.Exclude (new Point (0, 2), 10, Orientation.Horizontal)); - TestHelpers.AssertEqual ( + OutputAssert.AssertEqual ( output, @" ┌────────┐ @@ -66,7 +68,7 @@ public class StraightLineExtensionsTests (ITestOutputHelper output) lc = new LineCanvas (origLines.Exclude (new Point (0, 3), 10, Orientation.Horizontal)); - TestHelpers.AssertEqual ( + OutputAssert.AssertEqual ( output, @" ┌────────┐ @@ -79,7 +81,7 @@ public class StraightLineExtensionsTests (ITestOutputHelper output) lc = new LineCanvas (origLines.Exclude (new Point (0, 4), 10, Orientation.Horizontal)); - TestHelpers.AssertEqual ( + OutputAssert.AssertEqual ( output, @" ┌────────┐ @@ -91,7 +93,7 @@ public class StraightLineExtensionsTests (ITestOutputHelper output) lc = new LineCanvas (origLines.Exclude (Point.Empty, 10, Orientation.Vertical)); - TestHelpers.AssertEqual ( + OutputAssert.AssertEqual ( output, @" ────────┐ @@ -104,7 +106,7 @@ public class StraightLineExtensionsTests (ITestOutputHelper output) lc = new LineCanvas (origLines.Exclude (new Point (1, 0), 10, Orientation.Vertical)); - TestHelpers.AssertEqual ( + OutputAssert.AssertEqual ( output, @" ┌ ───────┐ @@ -117,7 +119,7 @@ public class StraightLineExtensionsTests (ITestOutputHelper output) lc = new LineCanvas (origLines.Exclude (new Point (8, 0), 10, Orientation.Vertical)); - TestHelpers.AssertEqual ( + OutputAssert.AssertEqual ( output, @" ┌─────── ┐ @@ -130,7 +132,7 @@ public class StraightLineExtensionsTests (ITestOutputHelper output) lc = new LineCanvas (origLines.Exclude (new Point (9, 0), 10, Orientation.Vertical)); - TestHelpers.AssertEqual ( + OutputAssert.AssertEqual ( output, @" ┌──────── diff --git a/Tests/UnitTests/Drawing/ThicknessTests.cs b/Tests/UnitTests/Drawing/ThicknessTests.cs new file mode 100644 index 000000000..fb75aacff --- /dev/null +++ b/Tests/UnitTests/Drawing/ThicknessTests.cs @@ -0,0 +1,255 @@ +using System.Text; +using UnitTests; +using UnitTests; +using Xunit.Abstractions; + +namespace Terminal.Gui.DrawingTests; +public class ThicknessTests (ITestOutputHelper output) +{ + [Fact] + [AutoInitShutdown] + public void DrawTests () + { + ((FakeDriver)Application.Driver!).SetBufferSize (60, 60); + var t = new Thickness (0, 0, 0, 0); + var r = new Rectangle (5, 5, 40, 15); + + Application.Driver?.FillRect ( + new Rectangle (0, 0, Application.Driver!.Cols, Application.Driver!.Rows), + (Rune)' ' + ); + t.Draw (r, ViewDiagnosticFlags.Thickness, "Test"); + + DriverAssert.AssertDriverContentsWithFrameAre ( + @" + Test (Left=0,Top=0,Right=0,Bottom=0)", + output + ); + + t = new Thickness (1, 1, 1, 1); + r = new Rectangle (5, 5, 40, 15); + + Application.Driver?.FillRect ( + new Rectangle (0, 0, Application.Driver!.Cols, Application.Driver!.Rows), + (Rune)' ' + ); + t.Draw (r, ViewDiagnosticFlags.Thickness, "Test"); + + DriverAssert.AssertDriverContentsWithFrameAre ( + @" + TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT + T T + T T + T T + T T + T T + T T + T T + T T + T T + T T + T T + T T + T T + TTTest (Left=1,Top=1,Right=1,Bottom=1)TT", + output + ); + + t = new Thickness (1, 2, 3, 4); + r = new Rectangle (5, 5, 40, 15); + + Application.Driver?.FillRect ( + new Rectangle (0, 0, Application.Driver!.Cols, Application.Driver!.Rows), + (Rune)' ' + ); + t.Draw (r, ViewDiagnosticFlags.Thickness, "Test"); + + DriverAssert.AssertDriverContentsWithFrameAre ( + @" + TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT + TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT + T TTT + T TTT + T TTT + T TTT + T TTT + T TTT + T TTT + T TTT + T TTT + TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT + TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT + TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT + TTTest (Left=1,Top=2,Right=3,Bottom=4)TT", + output + ); + + t = new Thickness (-1, 1, 1, 1); + r = new Rectangle (5, 5, 40, 15); + + Application.Driver?.FillRect ( + new Rectangle (0, 0, Application.Driver!.Cols, Application.Driver!.Rows), + (Rune)' ' + ); + t.Draw (r, ViewDiagnosticFlags.Thickness, "Test"); + + DriverAssert.AssertDriverContentsWithFrameAre ( + @" + TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT + T + T + T + T + T + T + T + T + T + T + T + T + T + TTest (Left=-1,Top=1,Right=1,Bottom=1)TT", + output + ); + } + + [Fact] + [AutoInitShutdown] + public void DrawTests_Ruler () + { + // Add a frame so we can see the ruler + var f = new FrameView { X = 0, Y = 0, Width = Dim.Fill (), Height = Dim.Fill () }; + + var top = new Toplevel (); + top.Add (f); + RunState rs = Application.Begin (top); + + ((FakeDriver)Application.Driver!).SetBufferSize (45, 20); + var t = new Thickness (0, 0, 0, 0); + var r = new Rectangle (2, 2, 40, 15); + Application.RunIteration (ref rs); + + t.Draw (r, ViewDiagnosticFlags.Ruler, "Test"); + + DriverAssert.AssertDriverContentsAre ( + @" +┌───────────────────────────────────────────┐ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +└───────────────────────────────────────────┘", + output + ); + + t = new Thickness (1, 1, 1, 1); + r = new Rectangle (1, 1, 40, 15); + top.SetNeedsDraw (); + Application.RunIteration (ref rs); + t.Draw (r, ViewDiagnosticFlags.Ruler, "Test"); + + DriverAssert.AssertDriverContentsAre ( + @" +┌───────────────────────────────────────────┐ +│|123456789|123456789|123456789|123456789 │ +│1 1 │ +│2 2 │ +│3 3 │ +│4 4 │ +│5 5 │ +│6 6 │ +│7 7 │ +│8 8 │ +│9 9 │ +│- - │ +│1 1 │ +│2 2 │ +│3 3 │ +│|123456789|123456789|123456789|123456789 │ +│ │ +│ │ +│ │ +└───────────────────────────────────────────┘", + output + ); + + t = new Thickness (1, 2, 3, 4); + r = new Rectangle (2, 2, 40, 15); + top.SetNeedsDraw (); + Application.RunIteration (ref rs); + t.Draw (r, ViewDiagnosticFlags.Ruler, "Test"); + + DriverAssert.AssertDriverContentsWithFrameAre ( + @" +┌───────────────────────────────────────────┐ +│ │ +│ |123456789|123456789|123456789|123456789 │ +│ 1 1 │ +│ 2 2 │ +│ 3 3 │ +│ 4 4 │ +│ 5 5 │ +│ 6 6 │ +│ 7 7 │ +│ 8 8 │ +│ 9 9 │ +│ - - │ +│ 1 1 │ +│ 2 2 │ +│ 3 3 │ +│ |123456789|123456789|123456789|123456789 │ +│ │ +│ │ +└───────────────────────────────────────────┘", + output + ); + + t = new Thickness (-1, 1, 1, 1); + r = new Rectangle (5, 5, 40, 15); + top.SetNeedsDraw (); + Application.RunIteration (ref rs); + t.Draw (r, ViewDiagnosticFlags.Ruler, "Test"); + + DriverAssert.AssertDriverContentsWithFrameAre ( + @" +┌───────────────────────────────────────────┐ +│ │ +│ │ +│ │ +│ │ +│ |123456789|123456789|123456789|123456789 +│ 1 +│ 2 +│ 3 +│ 4 +│ 5 +│ 6 +│ 7 +│ 8 +│ 9 +│ - +│ 1 +│ 2 +│ 3 +└────|123456789|123456789|123456789|123456789", + output + ); + top.Dispose (); + } + +} diff --git a/Tests/UnitTests/DriverAssert.cs b/Tests/UnitTests/DriverAssert.cs new file mode 100644 index 000000000..a9ec89a8d --- /dev/null +++ b/Tests/UnitTests/DriverAssert.cs @@ -0,0 +1,346 @@ +using System.Text; +using System.Text.RegularExpressions; +using Xunit.Abstractions; +using Attribute = Terminal.Gui.Attribute; + +namespace UnitTests; + +/// +/// Provides xUnit-style assertions for contents. +/// +internal partial class DriverAssert +{ + private const char SpaceChar = ' '; + private static readonly Rune SpaceRune = (Rune)SpaceChar; +#pragma warning disable xUnit1013 // Public method should be marked as test + /// + /// Verifies are found at the locations specified by + /// . is a bitmap of indexes into + /// (e.g. "00110" means the attribute at expectedAttributes[1] is expected + /// at the 3rd and 4th columns of the 1st row of driver.Contents). + /// + /// + /// Numbers between 0 and 9 for each row/col of the console. Must be valid indexes into + /// . + /// + /// + /// The IConsoleDriver to use. If null will be used. + /// + public static void AssertDriverAttributesAre ( + string expectedLook, + ITestOutputHelper output, + IConsoleDriver driver = null, + params Attribute [] expectedAttributes + ) + { +#pragma warning restore xUnit1013 // Public method should be marked as test + + if (expectedAttributes.Length > 10) + { + throw new ArgumentException ("This method only works for UIs that use at most 10 colors"); + } + + expectedLook = expectedLook.Trim (); + driver ??= Application.Driver; + + Cell [,] contents = driver.Contents; + + var line = 0; + + foreach (string lineString in expectedLook.Split ('\n').Select (l => l.Trim ())) + { + for (var c = 0; c < lineString.Length; c++) + { + Attribute? val = contents [line, c].Attribute; + + List match = expectedAttributes.Where (e => e == val).ToList (); + + switch (match.Count) + { + case 0: + output.WriteLine ( + $"{Application.ToString (driver)}\n" + + $"Expected Attribute {val} (PlatformColor = {val.Value.PlatformColor}) at Contents[{line},{c}] {contents [line, c]} ((PlatformColor = {contents [line, c].Attribute.Value.PlatformColor}) was not found.\n" + + $" Expected: {string.Join (",", expectedAttributes.Select (c => c))}\n" + + $" But Was: " + ); + Assert.Empty (match); + + return; + case > 1: + throw new ArgumentException ( + $"Bad value for expectedColors, {match.Count} Attributes had the same Value" + ); + } + + char colorUsed = Array.IndexOf (expectedAttributes, match [0]).ToString () [0]; + char userExpected = lineString [c]; + + if (colorUsed != userExpected) + { + output.WriteLine ($"{Application.ToString (driver)}"); + output.WriteLine ($"Unexpected Attribute at Contents[{line},{c}] {contents [line, c]}."); + output.WriteLine ($" Expected: {userExpected} ({expectedAttributes [int.Parse (userExpected.ToString ())]})"); + output.WriteLine ($" But Was: {colorUsed} ({val})"); + Assert.Equal (userExpected, colorUsed); + + return; + } + } + + line++; + } + } + +#pragma warning disable xUnit1013 // Public method should be marked as test + /// Asserts that the driver contents match the expected contents, optionally ignoring any trailing whitespace. + /// + /// + /// The IConsoleDriver to use. If null will be used. + /// + public static void AssertDriverContentsAre ( + string expectedLook, + ITestOutputHelper output, + IConsoleDriver driver = null, + bool ignoreLeadingWhitespace = false + ) + { +#pragma warning restore xUnit1013 // Public method should be marked as test + var actualLook = Application.ToString (driver ?? Application.Driver); + + if (string.Equals (expectedLook, actualLook)) + { + return; + } + + // get rid of trailing whitespace on each line (and leading/trailing whitespace of start/end of full string) + expectedLook = TrailingWhiteSpaceRegEx ().Replace (expectedLook, "").Trim (); + actualLook = TrailingWhiteSpaceRegEx ().Replace (actualLook, "").Trim (); + + if (ignoreLeadingWhitespace) + { + expectedLook = LeadingWhitespaceRegEx ().Replace (expectedLook, "").Trim (); + actualLook = LeadingWhitespaceRegEx ().Replace (actualLook, "").Trim (); + } + + // standardize line endings for the comparison + expectedLook = expectedLook.Replace ("\r\n", "\n"); + actualLook = actualLook.Replace ("\r\n", "\n"); + + // If test is about to fail show user what things looked like + if (!string.Equals (expectedLook, actualLook)) + { + output?.WriteLine ("Expected:" + Environment.NewLine + expectedLook); + output?.WriteLine (" But Was:" + Environment.NewLine + actualLook); + } + + Assert.Equal (expectedLook, actualLook); + } + + /// + /// Asserts that the driver contents are equal to the provided string. + /// + /// + /// + /// The IConsoleDriver to use. If null will be used. + /// + public static Rectangle AssertDriverContentsWithFrameAre ( + string expectedLook, + ITestOutputHelper output, + IConsoleDriver driver = null + ) + { + List> lines = new (); + var sb = new StringBuilder (); + driver ??= Application.Driver; + int x = -1; + int y = -1; + int w = -1; + int h = -1; + + Cell [,] contents = driver.Contents; + + for (var rowIndex = 0; rowIndex < driver.Rows; rowIndex++) + { + List runes = []; + + for (var colIndex = 0; colIndex < driver.Cols; colIndex++) + { + Rune runeAtCurrentLocation = contents [rowIndex, colIndex].Rune; + + if (runeAtCurrentLocation != SpaceRune) + { + if (x == -1) + { + x = colIndex; + y = rowIndex; + + for (var i = 0; i < colIndex; i++) + { + runes.InsertRange (i, [SpaceRune]); + } + } + + if (runeAtCurrentLocation.GetColumns () > 1) + { + colIndex++; + } + + if (colIndex + 1 > w) + { + w = colIndex + 1; + } + + h = rowIndex - y + 1; + } + + if (x > -1) + { + runes.Add (runeAtCurrentLocation); + } + + // See Issue #2616 + //foreach (var combMark in contents [r, c].CombiningMarks) { + // runes.Add (combMark); + //} + } + + if (runes.Count > 0) + { + lines.Add (runes); + } + } + + // Remove unnecessary empty lines + if (lines.Count > 0) + { + for (int r = lines.Count - 1; r > h - 1; r--) + { + lines.RemoveAt (r); + } + } + + // Remove trailing whitespace on each line + foreach (List row in lines) + { + for (int c = row.Count - 1; c >= 0; c--) + { + Rune rune = row [c]; + + if (rune != (Rune)' ' || row.Sum (x => x.GetColumns ()) == w) + { + break; + } + + row.RemoveAt (c); + } + } + + // Convert Rune list to string + for (var r = 0; r < lines.Count; r++) + { + var line = StringExtensions.ToString (lines [r]); + + if (r == lines.Count - 1) + { + sb.Append (line); + } + else + { + sb.AppendLine (line); + } + } + + var actualLook = sb.ToString (); + + if (string.Equals (expectedLook, actualLook)) + { + return new (x > -1 ? x : 0, y > -1 ? y : 0, w > -1 ? w : 0, h > -1 ? h : 0); + } + + // standardize line endings for the comparison + expectedLook = expectedLook.ReplaceLineEndings (); + actualLook = actualLook.ReplaceLineEndings (); + + // Remove the first and the last line ending from the expectedLook + if (expectedLook.StartsWith (Environment.NewLine)) + { + expectedLook = expectedLook [Environment.NewLine.Length..]; + } + + if (expectedLook.EndsWith (Environment.NewLine)) + { + expectedLook = expectedLook [..^Environment.NewLine.Length]; + } + + // If test is about to fail show user what things looked like + if (!string.Equals (expectedLook, actualLook)) + { + output?.WriteLine ("Expected:" + Environment.NewLine + expectedLook); + output?.WriteLine (" But Was:" + Environment.NewLine + actualLook); + } + + Assert.Equal (expectedLook, actualLook); + + return new (x > -1 ? x : 0, y > -1 ? y : 0, w > -1 ? w : 0, h > -1 ? h : 0); + } + + + /// + /// Verifies the console used all the when rendering. If one or more of the + /// expected colors are not used then the failure will output both the colors that were found to be used and which of + /// your expectations was not met. + /// + /// if null uses + /// + internal static void AssertDriverUsedColors (IConsoleDriver driver = null, params Attribute [] expectedColors) + { + driver ??= Application.Driver; + Cell [,] contents = driver.Contents; + + List toFind = expectedColors.ToList (); + + // Contents 3rd column is an Attribute + HashSet colorsUsed = new (); + + for (var r = 0; r < driver.Rows; r++) + { + for (var c = 0; c < driver.Cols; c++) + { + Attribute? val = contents [r, c].Attribute; + + if (val.HasValue) + { + colorsUsed.Add (val.Value); + + Attribute match = toFind.FirstOrDefault (e => e == val); + + // need to check twice because Attribute is a struct and therefore cannot be null + if (toFind.Any (e => e == val)) + { + toFind.Remove (match); + } + } + } + } + + if (!toFind.Any ()) + { + return; + } + + var sb = new StringBuilder (); + sb.AppendLine ("The following colors were not used:" + string.Join ("; ", toFind.Select (a => a.ToString ()))); + sb.AppendLine ("Colors used were:" + string.Join ("; ", colorsUsed.Select (a => a.ToString ()))); + + throw new (sb.ToString ()); + } + + + [GeneratedRegex ("^\\s+", RegexOptions.Multiline)] + private static partial Regex LeadingWhitespaceRegEx (); + + + [GeneratedRegex ("\\s+$", RegexOptions.Multiline)] + private static partial Regex TrailingWhiteSpaceRegEx (); +} diff --git a/UnitTests/FileServices/FileDialogTests.cs b/Tests/UnitTests/FileServices/FileDialogTests.cs similarity index 99% rename from UnitTests/FileServices/FileDialogTests.cs rename to Tests/UnitTests/FileServices/FileDialogTests.cs index cb31b7462..269670509 100644 --- a/UnitTests/FileServices/FileDialogTests.cs +++ b/Tests/UnitTests/FileServices/FileDialogTests.cs @@ -1,5 +1,6 @@ using System.IO.Abstractions.TestingHelpers; using System.Runtime.InteropServices; +using UnitTests; using Xunit.Abstractions; namespace Terminal.Gui.FileServicesTests; diff --git a/UnitTests/Input/EscSeqRequestsTests.cs b/Tests/UnitTests/Input/EscSeqRequestsTests.cs similarity index 100% rename from UnitTests/Input/EscSeqRequestsTests.cs rename to Tests/UnitTests/Input/EscSeqRequestsTests.cs diff --git a/UnitTests/Input/EscSeqUtilsTests.cs b/Tests/UnitTests/Input/EscSeqUtilsTests.cs similarity index 99% rename from UnitTests/Input/EscSeqUtilsTests.cs rename to Tests/UnitTests/Input/EscSeqUtilsTests.cs index 4f783115f..10dd82323 100644 --- a/UnitTests/Input/EscSeqUtilsTests.cs +++ b/Tests/UnitTests/Input/EscSeqUtilsTests.cs @@ -1,4 +1,6 @@ using JetBrains.Annotations; +using UnitTests; + // ReSharper disable HeuristicUnreachableCode namespace Terminal.Gui.InputTests; diff --git a/Tests/UnitTests/OutputAssert.cs b/Tests/UnitTests/OutputAssert.cs new file mode 100644 index 000000000..29f5d8c2c --- /dev/null +++ b/Tests/UnitTests/OutputAssert.cs @@ -0,0 +1,51 @@ +using Xunit.Abstractions; + +namespace UnitTests; + +/// +/// Provides xunit-style assertions for . +/// +/// +internal class OutputAssert +{ +#pragma warning disable xUnit1013 // Public method should be marked as test + /// + /// Verifies two strings are equivalent. If the assert fails, output will be generated to standard output showing + /// the expected and actual look. + /// + /// + /// + /// A string containing the expected look. Newlines should be specified as "\r\n" as they will + /// be converted to to make tests platform independent. + /// + /// + public static void AssertEqual (ITestOutputHelper output, string expectedLook, string actualLook) + { + // Convert newlines to platform-specific newlines + expectedLook = ReplaceNewLinesToPlatformSpecific (expectedLook); + + // If test is about to fail show user what things looked like + if (!string.Equals (expectedLook, actualLook)) + { + output?.WriteLine ("Expected:" + Environment.NewLine + expectedLook); + output?.WriteLine (" But Was:" + Environment.NewLine + actualLook); + } + + Assert.Equal (expectedLook, actualLook); + } +#pragma warning restore xUnit1013 // Public method should be marked as test + + private static string ReplaceNewLinesToPlatformSpecific (string toReplace) + { + string replaced = toReplace; + + replaced = Environment.NewLine.Length switch + { + 2 when !replaced.Contains ("\r\n") => replaced.Replace ("\n", Environment.NewLine), + 1 => replaced.Replace ("\r\n", Environment.NewLine), + _ => replaced + }; + + return replaced; + } +} diff --git a/Tests/UnitTests/README.md b/Tests/UnitTests/README.md new file mode 100644 index 000000000..217607fd3 --- /dev/null +++ b/Tests/UnitTests/README.md @@ -0,0 +1,3 @@ +# Automated Unit Tests (non-Parallelizable) + +See the [Testing wiki](https://github.com/gui-cs/Terminal.Gui/wiki/Testing) for details on how to add more tests. diff --git a/UnitTests/Resources/ResourceManagerTests.cs b/Tests/UnitTests/Resources/ResourceManagerTests.cs similarity index 100% rename from UnitTests/Resources/ResourceManagerTests.cs rename to Tests/UnitTests/Resources/ResourceManagerTests.cs diff --git a/Tests/UnitTests/SetupFakeDriverAttribute.cs b/Tests/UnitTests/SetupFakeDriverAttribute.cs new file mode 100644 index 000000000..48c07c10c --- /dev/null +++ b/Tests/UnitTests/SetupFakeDriverAttribute.cs @@ -0,0 +1,44 @@ +using System.Diagnostics; +using System.Reflection; +using Xunit.Sdk; + +namespace UnitTests; + +/// +/// Enables test functions annotated with the [SetupFakeDriver] attribute to set Application.Driver to new +/// FakeDriver(). The driver is set up with 25 rows and columns. +/// +/// +/// On Before, sets Configuration.Locations to ConfigLocations.DefaultOnly. +/// On After, sets Configuration.Locations to ConfigLocations.All. +/// +[AttributeUsage (AttributeTargets.Class | AttributeTargets.Method)] +public class SetupFakeDriverAttribute : BeforeAfterTestAttribute +{ + public override void After (MethodInfo methodUnderTest) + { + Debug.WriteLine ($"After: {methodUnderTest.Name}"); + + // Turn off diagnostic flags in case some test left them on + View.Diagnostics = ViewDiagnosticFlags.Off; + + Application.ResetState (true); + Assert.Null (Application.Driver); + Assert.Equal (new (0, 0, 2048, 2048), Application.Screen); + base.After (methodUnderTest); + } + + public override void Before (MethodInfo methodUnderTest) + { + Debug.WriteLine ($"Before: {methodUnderTest.Name}"); + + Application.ResetState (true); + Assert.Null (Application.Driver); + Application.Driver = new FakeDriver { Rows = 25, Cols = 25 }; + Assert.Equal (new (0, 0, 25, 25), Application.Screen); + // Ensures subscribing events, at least for the SizeChanged event + Application.SubscribeDriverEvents (); + + base.Before (methodUnderTest); + } +} \ No newline at end of file diff --git a/Tests/UnitTests/TestDateAttribute.cs b/Tests/UnitTests/TestDateAttribute.cs new file mode 100644 index 000000000..5ad857a2f --- /dev/null +++ b/Tests/UnitTests/TestDateAttribute.cs @@ -0,0 +1,20 @@ +using System.Globalization; +using System.Reflection; +using Xunit.Sdk; + +namespace UnitTests; + +[AttributeUsage (AttributeTargets.Class | AttributeTargets.Method)] +public class TestDateAttribute : BeforeAfterTestAttribute +{ + public TestDateAttribute () { CultureInfo.CurrentCulture = CultureInfo.InvariantCulture; } + private readonly CultureInfo _currentCulture = CultureInfo.CurrentCulture; + + public override void After (MethodInfo methodUnderTest) + { + CultureInfo.CurrentCulture = _currentCulture; + Assert.Equal (CultureInfo.CurrentCulture, _currentCulture); + } + + public override void Before (MethodInfo methodUnderTest) { Assert.Equal (CultureInfo.CurrentCulture, CultureInfo.InvariantCulture); } +} \ No newline at end of file diff --git a/Tests/UnitTests/TestRespondersDisposedAttribute.cs b/Tests/UnitTests/TestRespondersDisposedAttribute.cs new file mode 100644 index 000000000..a1f29319a --- /dev/null +++ b/Tests/UnitTests/TestRespondersDisposedAttribute.cs @@ -0,0 +1,44 @@ +using System.Diagnostics; +using System.Globalization; +using System.Reflection; +using Xunit.Sdk; + +namespace UnitTests; + +/// +/// Enables test functions annotated with the [TestRespondersDisposed] attribute to ensure all Views are disposed. +/// +/// +/// On Before, sets Configuration.Locations to ConfigLocations.DefaultOnly. +/// On After, sets Configuration.Locations to ConfigLocations.All. +/// +[AttributeUsage (AttributeTargets.Class | AttributeTargets.Method)] +public class TestRespondersDisposedAttribute : BeforeAfterTestAttribute +{ + public TestRespondersDisposedAttribute () { CultureInfo.DefaultThreadCurrentUICulture = CultureInfo.GetCultureInfo ("en-US"); } + + public override void After (MethodInfo methodUnderTest) + { + Debug.WriteLine ($"After: {methodUnderTest.Name}"); + base.After (methodUnderTest); + +#if DEBUG_IDISPOSABLE + View.DebugIDisposable = true; + + Assert.Empty (View.Instances); +#endif + } + + public override void Before (MethodInfo methodUnderTest) + { + Debug.WriteLine ($"Before: {methodUnderTest.Name}"); + + base.Before (methodUnderTest); +#if DEBUG_IDISPOSABLE + View.DebugIDisposable = true; + // Clear out any lingering Responder instances from previous tests + View.Instances.Clear (); + Assert.Empty (View.Instances); +#endif + } +} \ No newline at end of file diff --git a/Tests/UnitTests/TestsAllViews.cs b/Tests/UnitTests/TestsAllViews.cs new file mode 100644 index 000000000..a3ab97b45 --- /dev/null +++ b/Tests/UnitTests/TestsAllViews.cs @@ -0,0 +1,28 @@ +#nullable enable + +using Terminal.Gui; + +namespace UnitTests; + +/// +/// Base class for tests that need to test all views. +/// +public class TestsAllViews +{ + public static IEnumerable AllViewTypes => + typeof (View).Assembly + .GetTypes () + .Where (type => type.IsClass && !type.IsAbstract && type.IsPublic && (type.IsSubclassOf (typeof (View)) || type == typeof (View))) + .Select (type => new object [] { type }); + + public static View CreateInstanceIfNotGeneric (Type type) + { + if (type.IsGenericType) + { + // Return null for generic types + return null; + } + + return Activator.CreateInstance (type) as View; + } +} diff --git a/UnitTests/Text/AutocompleteTests.cs b/Tests/UnitTests/Text/AutocompleteTests.cs similarity index 94% rename from UnitTests/Text/AutocompleteTests.cs rename to Tests/UnitTests/Text/AutocompleteTests.cs index 7be3f35e0..7e8c0e175 100644 --- a/UnitTests/Text/AutocompleteTests.cs +++ b/Tests/UnitTests/Text/AutocompleteTests.cs @@ -1,4 +1,6 @@ using System.Text.RegularExpressions; +using UnitTests; +using UnitTests; using Xunit.Abstractions; namespace Terminal.Gui.TextTests; @@ -29,7 +31,7 @@ public class AutocompleteTests (ITestOutputHelper output) if (i < 4 || i > 5) { - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" This a long line and against TextView.", output @@ -37,7 +39,7 @@ This a long line and against TextView.", } else { - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" This a long line and against TextView. and @@ -55,7 +57,7 @@ This a long line and against TextView. top.SetNeedsDraw (); Application.RunIteration (ref rs); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" This a long line and against TextView. and @@ -67,7 +69,7 @@ This a long line and against TextView. top.SetNeedsDraw (); Application.RunIteration (ref rs); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" This ag long line and against TextView. against ", @@ -78,7 +80,7 @@ This ag long line and against TextView. top.SetNeedsDraw (); Application.RunIteration (ref rs); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" This ag long line and against TextView. against ", @@ -89,7 +91,7 @@ This ag long line and against TextView. top.SetNeedsDraw (); Application.RunIteration (ref rs); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" This ag long line and against TextView. against ", @@ -100,7 +102,7 @@ This ag long line and against TextView. top.SetNeedsDraw (); Application.RunIteration (ref rs); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" This ag long line and against TextView.", output @@ -112,7 +114,7 @@ This ag long line and against TextView.", top.SetNeedsDraw (); Application.RunIteration (ref rs); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" This ag long line and against TextView. against ", @@ -124,7 +126,7 @@ This ag long line and against TextView. top.SetNeedsDraw (); Application.RunIteration (ref rs); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" This a long line and against TextView. and @@ -136,7 +138,7 @@ This a long line and against TextView. top.SetNeedsDraw (); Application.RunIteration (ref rs); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" This an long line and against TextView. and ", @@ -147,7 +149,7 @@ This an long line and against TextView. top.SetNeedsDraw (); Application.RunIteration (ref rs); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" This an long line and against TextView.", output diff --git a/Tests/UnitTests/Text/TextFormatterTests.cs b/Tests/UnitTests/Text/TextFormatterTests.cs new file mode 100644 index 000000000..407bd4a79 --- /dev/null +++ b/Tests/UnitTests/Text/TextFormatterTests.cs @@ -0,0 +1,4381 @@ +using System.Text; +using UnitTests; +using UICatalog; +using UnitTests; +using Xunit.Abstractions; + +// Alias Console to MockConsole so we don't accidentally use Console + +namespace Terminal.Gui.TextTests; + +public class TextFormatterTests +{ + public TextFormatterTests (ITestOutputHelper output) { _output = output; } + private readonly ITestOutputHelper _output; + + + public static IEnumerable CMGlyphs => + new List { new object [] { $"{Glyphs.LeftBracket} Say Hello 你 {Glyphs.RightBracket}", 16, 15 } }; + + [SetupFakeDriver] + [Theory] + [InlineData ("A", 0, "")] + [InlineData ("A", 1, "A")] + [InlineData ("A", 2, "A")] + [InlineData ("A", 3, " A")] + [InlineData ("AB", 1, "A")] + [InlineData ("AB", 2, "AB")] + [InlineData ("ABC", 3, "ABC")] + [InlineData ("ABC", 4, "ABC")] + [InlineData ("ABC", 5, " ABC")] + [InlineData ("ABC", 6, " ABC")] + [InlineData ("ABC", 9, " ABC")] + public void Draw_Horizontal_Centered (string text, int width, string expectedText) + { + TextFormatter tf = new () + { + Text = text, + Alignment = Alignment.Center + }; + + tf.ConstrainToWidth = width; + tf.ConstrainToHeight = 1; + tf.Draw (new (0, 0, width, 1), Attribute.Default, Attribute.Default); + + DriverAssert.AssertDriverContentsWithFrameAre (expectedText, _output); + } + + [SetupFakeDriver] + [Theory] + [InlineData ("A", 0, "")] + [InlineData ("A", 1, "A")] + [InlineData ("A", 2, "A")] + [InlineData ("A B", 3, "A B")] + [InlineData ("A B", 1, "A")] + [InlineData ("A B", 2, "A")] + [InlineData ("A B", 4, "A B")] + [InlineData ("A B", 5, "A B")] + [InlineData ("A B", 6, "A B")] + [InlineData ("A B", 10, "A B")] + [InlineData ("ABC ABC", 10, "ABC ABC")] + public void Draw_Horizontal_Justified (string text, int width, string expectedText) + { + TextFormatter tf = new () + { + Text = text, + Alignment = Alignment.Fill + }; + + tf.ConstrainToWidth = width; + tf.ConstrainToHeight = 1; + tf.Draw (new (0, 0, width, 1), Attribute.Default, Attribute.Default); + + DriverAssert.AssertDriverContentsWithFrameAre (expectedText, _output); + } + + [SetupFakeDriver] + [Theory] + [InlineData ("A", 0, "")] + [InlineData ("A", 1, "A")] + [InlineData ("A", 2, "A")] + [InlineData ("AB", 1, "A")] + [InlineData ("AB", 2, "AB")] + [InlineData ("ABC", 3, "ABC")] + [InlineData ("ABC", 4, "ABC")] + [InlineData ("ABC", 6, "ABC")] + public void Draw_Horizontal_Left (string text, int width, string expectedText) + + { + TextFormatter tf = new () + { + Text = text, + Alignment = Alignment.Start + }; + + tf.ConstrainToWidth = width; + tf.ConstrainToHeight = 1; + tf.Draw (new (0, 0, width, 1), Attribute.Default, Attribute.Default); + + DriverAssert.AssertDriverContentsWithFrameAre (expectedText, _output); + } + + [SetupFakeDriver] + [Theory] + [InlineData ("A", 0, "")] + [InlineData ("A", 1, "A")] + [InlineData ("A", 2, " A")] + [InlineData ("AB", 1, "B")] + [InlineData ("AB", 2, "AB")] + [InlineData ("ABC", 3, "ABC")] + [InlineData ("ABC", 4, " ABC")] + [InlineData ("ABC", 6, " ABC")] + public void Draw_Horizontal_Right (string text, int width, string expectedText) + { + TextFormatter tf = new () + { + Text = text, + Alignment = Alignment.End + }; + + tf.ConstrainToWidth = width; + tf.ConstrainToHeight = 1; + + tf.Draw (new (Point.Empty, new (width, 1)), Attribute.Default, Attribute.Default); + DriverAssert.AssertDriverContentsWithFrameAre (expectedText, _output); + } + + [SetupFakeDriver] + [Theory] + [InlineData ("A", 1, 0, "")] + [InlineData ("A", 0, 1, "")] + [InlineData ("AB1 2", 2, 1, "2")] + [InlineData ("AB12", 5, 1, "21BA")] + [InlineData ("AB\n12", 5, 2, "21\nBA")] + [InlineData ("ABC 123 456", 7, 2, "CBA \n654 321")] + [InlineData ("こんにちは", 1, 1, "")] + [InlineData ("こんにちは", 2, 1, "は")] + [InlineData ("こんにちは", 5, 1, "はち")] + [InlineData ("こんにちは", 10, 1, "はちにんこ")] + [InlineData ("こんにちは\nAB\n12", 10, 3, "21 \nBA \nはちにんこ")] + public void Draw_Horizontal_RightLeft_BottomTop (string text, int width, int height, string expectedText) + { + TextFormatter tf = new () + { + Text = text, + Direction = TextDirection.RightLeft_BottomTop + }; + + tf.ConstrainToWidth = width; + tf.ConstrainToHeight = height; + tf.Draw (new (0, 0, width, height), Attribute.Default, Attribute.Default); + + DriverAssert.AssertDriverContentsWithFrameAre (expectedText, _output); + } + + [SetupFakeDriver] + [Theory] + [InlineData ("A", 1, 0, "")] + [InlineData ("A", 0, 1, "")] + [InlineData ("AB1 2", 2, 1, "2")] + [InlineData ("AB12", 5, 1, "21BA")] + [InlineData ("AB\n12", 5, 2, "BA\n21")] + [InlineData ("ABC 123 456", 7, 2, "654 321\nCBA ")] + [InlineData ("こんにちは", 1, 1, "")] + [InlineData ("こんにちは", 2, 1, "は")] + [InlineData ("こんにちは", 5, 1, "はち")] + [InlineData ("こんにちは", 10, 1, "はちにんこ")] + [InlineData ("こんにちは\nAB\n12", 10, 3, "はちにんこ\nBA \n21 ")] + public void Draw_Horizontal_RightLeft_TopBottom (string text, int width, int height, string expectedText) + { + TextFormatter tf = new () + { + Text = text, + Direction = TextDirection.RightLeft_TopBottom + }; + + tf.ConstrainToWidth = width; + tf.ConstrainToHeight = height; + tf.Draw (new (0, 0, width, height), Attribute.Default, Attribute.Default); + + DriverAssert.AssertDriverContentsWithFrameAre (expectedText, _output); + } + + [SetupFakeDriver] + [Theory] + + // Horizontal with Alignment.Start + // LeftRight_TopBottom + [InlineData ( + "0 2 4", + Alignment.Start, + Alignment.Start, + TextDirection.LeftRight_TopBottom, + @" +0 2 4** +******* +******* +******* +******* +******* +*******")] + [InlineData ( + "0 2 4", + Alignment.End, + Alignment.Start, + TextDirection.LeftRight_TopBottom, + @" +**0 2 4 +******* +******* +******* +******* +******* +*******")] + [InlineData ( + "0 2 4", + Alignment.Center, + Alignment.Start, + TextDirection.LeftRight_TopBottom, + @" +*0 2 4* +******* +******* +******* +******* +******* +*******")] + [InlineData ( + "0 2 4", + Alignment.Fill, + Alignment.Start, + TextDirection.LeftRight_TopBottom, + @" +0 2 4 +******* +******* +******* +******* +******* +*******")] + [InlineData ( + "0 你 4", + Alignment.Start, + Alignment.Start, + TextDirection.LeftRight_TopBottom, + @" +0 你 4* +******* +******* +******* +******* +******* +*******")] + [InlineData ( + "0 你 4", + Alignment.End, + Alignment.Start, + TextDirection.LeftRight_TopBottom, + @" +*0 你 4 +******* +******* +******* +******* +******* +*******")] + [InlineData ( + "0 你 4", + Alignment.Center, + Alignment.Start, + TextDirection.LeftRight_TopBottom, + @" +0 你 4* +******* +******* +******* +******* +******* +*******")] + [InlineData ( + "0 你 4", + Alignment.Fill, + Alignment.Start, + TextDirection.LeftRight_TopBottom, + @" +0 你 4 +******* +******* +******* +******* +******* +*******")] + + // LeftRight_BottomTop + [InlineData ( + "0 2 4", + Alignment.Start, + Alignment.Start, + TextDirection.LeftRight_BottomTop, + @" +0 2 4** +******* +******* +******* +******* +******* +*******")] + [InlineData ( + "0 2 4", + Alignment.End, + Alignment.Start, + TextDirection.LeftRight_BottomTop, + @" +**0 2 4 +******* +******* +******* +******* +******* +*******")] + [InlineData ( + "0 2 4", + Alignment.Center, + Alignment.Start, + TextDirection.LeftRight_BottomTop, + @" +*0 2 4* +******* +******* +******* +******* +******* +*******")] + [InlineData ( + "0 2 4", + Alignment.Fill, + Alignment.Start, + TextDirection.LeftRight_BottomTop, + @" +0 2 4 +******* +******* +******* +******* +******* +*******")] + [InlineData ( + "0 你 4", + Alignment.Start, + Alignment.Start, + TextDirection.LeftRight_BottomTop, + @" +0 你 4* +******* +******* +******* +******* +******* +*******")] + [InlineData ( + "0 你 4", + Alignment.End, + Alignment.Start, + TextDirection.LeftRight_BottomTop, + @" +*0 你 4 +******* +******* +******* +******* +******* +*******")] + [InlineData ( + "0 你 4", + Alignment.Center, + Alignment.Start, + TextDirection.LeftRight_BottomTop, + @" +0 你 4* +******* +******* +******* +******* +******* +*******")] + [InlineData ( + "0 你 4", + Alignment.Fill, + Alignment.Start, + TextDirection.LeftRight_BottomTop, + @" +0 你 4 +******* +******* +******* +******* +******* +*******")] + + // RightLeft_TopBottom + [InlineData ( + "0 2 4", + Alignment.Start, + Alignment.Start, + TextDirection.RightLeft_TopBottom, + @" +4 2 0** +******* +******* +******* +******* +******* +*******")] + [InlineData ( + "0 2 4", + Alignment.End, + Alignment.Start, + TextDirection.RightLeft_TopBottom, + @" +**4 2 0 +******* +******* +******* +******* +******* +*******")] + [InlineData ( + "0 2 4", + Alignment.Center, + Alignment.Start, + TextDirection.RightLeft_TopBottom, + @" +*4 2 0* +******* +******* +******* +******* +******* +*******")] + [InlineData ( + "0 2 4", + Alignment.Fill, + Alignment.Start, + TextDirection.RightLeft_TopBottom, + @" +4 2 0 +******* +******* +******* +******* +******* +*******")] + [InlineData ( + "0 你 4", + Alignment.Start, + Alignment.Start, + TextDirection.RightLeft_TopBottom, + @" +4 你 0* +******* +******* +******* +******* +******* +*******")] + [InlineData ( + "0 你 4", + Alignment.End, + Alignment.Start, + TextDirection.RightLeft_TopBottom, + @" +*4 你 0 +******* +******* +******* +******* +******* +*******")] + [InlineData ( + "0 你 4", + Alignment.Center, + Alignment.Start, + TextDirection.RightLeft_TopBottom, + @" +4 你 0* +******* +******* +******* +******* +******* +*******")] + [InlineData ( + "0 你 4", + Alignment.Fill, + Alignment.Start, + TextDirection.RightLeft_TopBottom, + @" +4 你 0 +******* +******* +******* +******* +******* +*******")] + + // RightLeft_BottomTop + [InlineData ( + "0 2 4", + Alignment.Start, + Alignment.Start, + TextDirection.RightLeft_BottomTop, + @" +4 2 0** +******* +******* +******* +******* +******* +*******")] + [InlineData ( + "0 2 4", + Alignment.End, + Alignment.Start, + TextDirection.RightLeft_BottomTop, + @" +**4 2 0 +******* +******* +******* +******* +******* +*******")] + [InlineData ( + "0 2 4", + Alignment.Center, + Alignment.Start, + TextDirection.RightLeft_BottomTop, + @" +*4 2 0* +******* +******* +******* +******* +******* +*******")] + [InlineData ( + "0 2 4", + Alignment.Fill, + Alignment.Start, + TextDirection.RightLeft_BottomTop, + @" +4 2 0 +******* +******* +******* +******* +******* +*******")] + [InlineData ( + "0 你 4", + Alignment.Start, + Alignment.Start, + TextDirection.RightLeft_BottomTop, + @" +4 你 0* +******* +******* +******* +******* +******* +*******")] + [InlineData ( + "0 你 4", + Alignment.End, + Alignment.Start, + TextDirection.RightLeft_BottomTop, + @" +*4 你 0 +******* +******* +******* +******* +******* +*******")] + [InlineData ( + "0 你 4", + Alignment.Center, + Alignment.Start, + TextDirection.RightLeft_BottomTop, + @" +4 你 0* +******* +******* +******* +******* +******* +*******")] + [InlineData ( + "0 你 4", + Alignment.Fill, + Alignment.Start, + TextDirection.RightLeft_BottomTop, + @" +4 你 0 +******* +******* +******* +******* +******* +*******")] + + // Horizontal with Alignment.End + // LeftRight_TopBottom + [InlineData ( + "0 2 4", + Alignment.Start, + Alignment.End, + TextDirection.LeftRight_TopBottom, + @" +******* +******* +******* +******* +******* +******* +0 2 4**")] + [InlineData ( + "0 2 4", + Alignment.End, + Alignment.End, + TextDirection.LeftRight_TopBottom, + @" +******* +******* +******* +******* +******* +******* +**0 2 4")] + [InlineData ( + "0 2 4", + Alignment.Center, + Alignment.End, + TextDirection.LeftRight_TopBottom, + @" +******* +******* +******* +******* +******* +******* +*0 2 4*")] + [InlineData ( + "0 2 4", + Alignment.Fill, + Alignment.End, + TextDirection.LeftRight_TopBottom, + @" +******* +******* +******* +******* +******* +******* +0 2 4")] + [InlineData ( + "0 你 4", + Alignment.Start, + Alignment.End, + TextDirection.LeftRight_TopBottom, + @" +******* +******* +******* +******* +******* +******* +0 你 4*")] + [InlineData ( + "0 你 4", + Alignment.End, + Alignment.End, + TextDirection.LeftRight_TopBottom, + @" +******* +******* +******* +******* +******* +******* +*0 你 4")] + [InlineData ( + "0 你 4", + Alignment.Center, + Alignment.End, + TextDirection.LeftRight_TopBottom, + @" +******* +******* +******* +******* +******* +******* +0 你 4*")] + [InlineData ( + "0 你 4", + Alignment.Fill, + Alignment.End, + TextDirection.LeftRight_TopBottom, + @" +******* +******* +******* +******* +******* +******* +0 你 4")] + + // LeftRight_BottomTop + [InlineData ( + "0 2 4", + Alignment.Start, + Alignment.End, + TextDirection.LeftRight_BottomTop, + @" +******* +******* +******* +******* +******* +******* +0 2 4**")] + [InlineData ( + "0 2 4", + Alignment.End, + Alignment.End, + TextDirection.LeftRight_BottomTop, + @" +******* +******* +******* +******* +******* +******* +**0 2 4")] + [InlineData ( + "0 2 4", + Alignment.Center, + Alignment.End, + TextDirection.LeftRight_BottomTop, + @" +******* +******* +******* +******* +******* +******* +*0 2 4*")] + [InlineData ( + "0 2 4", + Alignment.Fill, + Alignment.End, + TextDirection.LeftRight_BottomTop, + @" +******* +******* +******* +******* +******* +******* +0 2 4")] + [InlineData ( + "0 你 4", + Alignment.Start, + Alignment.End, + TextDirection.LeftRight_BottomTop, + @" +******* +******* +******* +******* +******* +******* +0 你 4*")] + [InlineData ( + "0 你 4", + Alignment.End, + Alignment.End, + TextDirection.LeftRight_BottomTop, + @" +******* +******* +******* +******* +******* +******* +*0 你 4")] + [InlineData ( + "0 你 4", + Alignment.Center, + Alignment.End, + TextDirection.LeftRight_BottomTop, + @" +******* +******* +******* +******* +******* +******* +0 你 4*")] + [InlineData ( + "0 你 4", + Alignment.Fill, + Alignment.End, + TextDirection.LeftRight_BottomTop, + @" +******* +******* +******* +******* +******* +******* +0 你 4")] + + // RightLeft_TopBottom + [InlineData ( + "0 2 4", + Alignment.Start, + Alignment.End, + TextDirection.RightLeft_TopBottom, + @" +******* +******* +******* +******* +******* +******* +4 2 0**")] + [InlineData ( + "0 2 4", + Alignment.End, + Alignment.End, + TextDirection.RightLeft_TopBottom, + @" +******* +******* +******* +******* +******* +******* +**4 2 0")] + [InlineData ( + "0 2 4", + Alignment.Center, + Alignment.End, + TextDirection.RightLeft_TopBottom, + @" +******* +******* +******* +******* +******* +******* +*4 2 0*")] + [InlineData ( + "0 2 4", + Alignment.Fill, + Alignment.End, + TextDirection.RightLeft_TopBottom, + @" +******* +******* +******* +******* +******* +******* +4 2 0")] + [InlineData ( + "0 你 4", + Alignment.Start, + Alignment.End, + TextDirection.RightLeft_TopBottom, + @" +******* +******* +******* +******* +******* +******* +4 你 0*")] + [InlineData ( + "0 你 4", + Alignment.End, + Alignment.End, + TextDirection.RightLeft_TopBottom, + @" +******* +******* +******* +******* +******* +******* +*4 你 0")] + [InlineData ( + "0 你 4", + Alignment.Center, + Alignment.End, + TextDirection.RightLeft_TopBottom, + @" +******* +******* +******* +******* +******* +******* +4 你 0*")] + [InlineData ( + "0 你 4", + Alignment.Fill, + Alignment.End, + TextDirection.RightLeft_TopBottom, + @" +******* +******* +******* +******* +******* +******* +4 你 0")] + + // RightLeft_BottomTop + [InlineData ( + "0 2 4", + Alignment.Start, + Alignment.End, + TextDirection.RightLeft_BottomTop, + @" +******* +******* +******* +******* +******* +******* +4 2 0**")] + [InlineData ( + "0 2 4", + Alignment.End, + Alignment.End, + TextDirection.RightLeft_BottomTop, + @" +******* +******* +******* +******* +******* +******* +**4 2 0")] + [InlineData ( + "0 2 4", + Alignment.Center, + Alignment.End, + TextDirection.RightLeft_BottomTop, + @" +******* +******* +******* +******* +******* +******* +*4 2 0*")] + [InlineData ( + "0 2 4", + Alignment.Fill, + Alignment.End, + TextDirection.RightLeft_BottomTop, + @" +******* +******* +******* +******* +******* +******* +4 2 0")] + [InlineData ( + "0 你 4", + Alignment.Start, + Alignment.End, + TextDirection.RightLeft_BottomTop, + @" +******* +******* +******* +******* +******* +******* +4 你 0*")] + [InlineData ( + "0 你 4", + Alignment.End, + Alignment.End, + TextDirection.RightLeft_BottomTop, + @" +******* +******* +******* +******* +******* +******* +*4 你 0")] + [InlineData ( + "0 你 4", + Alignment.Center, + Alignment.End, + TextDirection.RightLeft_BottomTop, + @" +******* +******* +******* +******* +******* +******* +4 你 0*")] + [InlineData ( + "0 你 4", + Alignment.Fill, + Alignment.End, + TextDirection.RightLeft_BottomTop, + @" +******* +******* +******* +******* +******* +******* +4 你 0")] + + // Horizontal with alignment.Centered + // LeftRight_TopBottom + [InlineData ( + "0 2 4", + Alignment.Start, + Alignment.Center, + TextDirection.LeftRight_TopBottom, + @" +******* +******* +******* +0 2 4** +******* +******* +*******")] + [InlineData ( + "0 2 4", + Alignment.End, + Alignment.Center, + TextDirection.LeftRight_TopBottom, + @" +******* +******* +******* +**0 2 4 +******* +******* +*******")] + [InlineData ( + "0 2 4", + Alignment.Center, + Alignment.Center, + TextDirection.LeftRight_TopBottom, + @" +******* +******* +******* +*0 2 4* +******* +******* +*******")] + [InlineData ( + "0 2 4", + Alignment.Fill, + Alignment.Center, + TextDirection.LeftRight_TopBottom, + @" +******* +******* +******* +0 2 4 +******* +******* +*******")] + [InlineData ( + "0 你 4", + Alignment.Start, + Alignment.Center, + TextDirection.LeftRight_TopBottom, + @" +******* +******* +******* +0 你 4* +******* +******* +*******")] + [InlineData ( + "0 你 4", + Alignment.End, + Alignment.Center, + TextDirection.LeftRight_TopBottom, + @" +******* +******* +******* +*0 你 4 +******* +******* +*******")] + [InlineData ( + "0 你 4", + Alignment.Center, + Alignment.Center, + TextDirection.LeftRight_TopBottom, + @" +******* +******* +******* +0 你 4* +******* +******* +*******")] + [InlineData ( + "0 你 4", + Alignment.Fill, + Alignment.Center, + TextDirection.LeftRight_TopBottom, + @" +******* +******* +******* +0 你 4 +******* +******* +*******")] + + // LeftRight_BottomTop + [InlineData ( + "0 2 4", + Alignment.Start, + Alignment.Center, + TextDirection.LeftRight_BottomTop, + @" +******* +******* +******* +0 2 4** +******* +******* +*******")] + [InlineData ( + "0 2 4", + Alignment.End, + Alignment.Center, + TextDirection.LeftRight_BottomTop, + @" +******* +******* +******* +**0 2 4 +******* +******* +*******")] + [InlineData ( + "0 2 4", + Alignment.Center, + Alignment.Center, + TextDirection.LeftRight_BottomTop, + @" +******* +******* +******* +*0 2 4* +******* +******* +*******")] + [InlineData ( + "0 2 4", + Alignment.Fill, + Alignment.Center, + TextDirection.LeftRight_BottomTop, + @" +******* +******* +******* +0 2 4 +******* +******* +*******")] + [InlineData ( + "0 你 4", + Alignment.Start, + Alignment.Center, + TextDirection.LeftRight_BottomTop, + @" +******* +******* +******* +0 你 4* +******* +******* +*******")] + [InlineData ( + "0 你 4", + Alignment.End, + Alignment.Center, + TextDirection.LeftRight_BottomTop, + @" +******* +******* +******* +*0 你 4 +******* +******* +*******")] + [InlineData ( + "0 你 4", + Alignment.Center, + Alignment.Center, + TextDirection.LeftRight_BottomTop, + @" +******* +******* +******* +0 你 4* +******* +******* +*******")] + [InlineData ( + "0 你 4", + Alignment.Fill, + Alignment.Center, + TextDirection.LeftRight_BottomTop, + @" +******* +******* +******* +0 你 4 +******* +******* +*******")] + + // RightLeft_TopBottom + [InlineData ( + "0 2 4", + Alignment.Start, + Alignment.Center, + TextDirection.RightLeft_TopBottom, + @" +******* +******* +******* +4 2 0** +******* +******* +*******")] + [InlineData ( + "0 2 4", + Alignment.End, + Alignment.Center, + TextDirection.RightLeft_TopBottom, + @" +******* +******* +******* +**4 2 0 +******* +******* +*******")] + [InlineData ( + "0 2 4", + Alignment.Center, + Alignment.Center, + TextDirection.RightLeft_TopBottom, + @" +******* +******* +******* +*4 2 0* +******* +******* +*******")] + [InlineData ( + "0 2 4", + Alignment.Fill, + Alignment.Center, + TextDirection.RightLeft_TopBottom, + @" +******* +******* +******* +4 2 0 +******* +******* +*******")] + [InlineData ( + "0 你 4", + Alignment.Start, + Alignment.Center, + TextDirection.RightLeft_TopBottom, + @" +******* +******* +******* +4 你 0* +******* +******* +*******")] + [InlineData ( + "0 你 4", + Alignment.End, + Alignment.Center, + TextDirection.RightLeft_TopBottom, + @" +******* +******* +******* +*4 你 0 +******* +******* +*******")] + [InlineData ( + "0 你 4", + Alignment.Center, + Alignment.Center, + TextDirection.RightLeft_TopBottom, + @" +******* +******* +******* +4 你 0* +******* +******* +*******")] + [InlineData ( + "0 你 4", + Alignment.Fill, + Alignment.Center, + TextDirection.RightLeft_TopBottom, + @" +******* +******* +******* +4 你 0 +******* +******* +*******")] + + // RightLeft_BottomTop + [InlineData ( + "0 2 4", + Alignment.Start, + Alignment.Center, + TextDirection.RightLeft_BottomTop, + @" +******* +******* +******* +4 2 0** +******* +******* +*******")] + [InlineData ( + "0 2 4", + Alignment.End, + Alignment.Center, + TextDirection.RightLeft_BottomTop, + @" +******* +******* +******* +**4 2 0 +******* +******* +*******")] + [InlineData ( + "0 2 4", + Alignment.Center, + Alignment.Center, + TextDirection.RightLeft_BottomTop, + @" +******* +******* +******* +*4 2 0* +******* +******* +*******")] + [InlineData ( + "0 2 4", + Alignment.Fill, + Alignment.Center, + TextDirection.RightLeft_BottomTop, + @" +******* +******* +******* +4 2 0 +******* +******* +*******")] + [InlineData ( + "0 你 4", + Alignment.Start, + Alignment.Center, + TextDirection.RightLeft_BottomTop, + @" +******* +******* +******* +4 你 0* +******* +******* +*******")] + [InlineData ( + "0 你 4", + Alignment.End, + Alignment.Center, + TextDirection.RightLeft_BottomTop, + @" +******* +******* +******* +*4 你 0 +******* +******* +*******")] + [InlineData ( + "0 你 4", + Alignment.Center, + Alignment.Center, + TextDirection.RightLeft_BottomTop, + @" +******* +******* +******* +4 你 0* +******* +******* +*******")] + [InlineData ( + "0 你 4", + Alignment.Fill, + Alignment.Center, + TextDirection.RightLeft_BottomTop, + @" +******* +******* +******* +4 你 0 +******* +******* +*******")] + + // Horizontal with alignment.Justified + // LeftRight_TopBottom + [InlineData ( + "0 2 4", + Alignment.Start, + Alignment.Fill, + TextDirection.LeftRight_TopBottom, + @" +0 2 4** +******* +******* +******* +******* +******* +*******")] + [InlineData ( + "0 2 4", + Alignment.End, + Alignment.Fill, + TextDirection.LeftRight_TopBottom, + @" +**0 2 4 +******* +******* +******* +******* +******* +*******")] + [InlineData ( + "0 2 4", + Alignment.Center, + Alignment.Fill, + TextDirection.LeftRight_TopBottom, + @" +*0 2 4* +******* +******* +******* +******* +******* +*******")] + [InlineData ( + "0 2 4", + Alignment.Fill, + Alignment.Fill, + TextDirection.LeftRight_TopBottom, + @" +0 2 4 +******* +******* +******* +******* +******* +*******")] + [InlineData ( + "0 你 4", + Alignment.Start, + Alignment.Fill, + TextDirection.LeftRight_TopBottom, + @" +0 你 4* +******* +******* +******* +******* +******* +*******")] + [InlineData ( + "0 你 4", + Alignment.End, + Alignment.Fill, + TextDirection.LeftRight_TopBottom, + @" +*0 你 4 +******* +******* +******* +******* +******* +*******")] + [InlineData ( + "0 你 4", + Alignment.Center, + Alignment.Fill, + TextDirection.LeftRight_TopBottom, + @" +0 你 4* +******* +******* +******* +******* +******* +*******")] + [InlineData ( + "0 你 4", + Alignment.Fill, + Alignment.Fill, + TextDirection.LeftRight_TopBottom, + @" +0 你 4 +******* +******* +******* +******* +******* +*******")] + + // LeftRight_BottomTop + [InlineData ( + "0 2 4", + Alignment.Start, + Alignment.Fill, + TextDirection.LeftRight_BottomTop, + @" +0 2 4** +******* +******* +******* +******* +******* +*******")] + [InlineData ( + "0 2 4", + Alignment.End, + Alignment.Fill, + TextDirection.LeftRight_BottomTop, + @" +**0 2 4 +******* +******* +******* +******* +******* +*******")] + [InlineData ( + "0 2 4", + Alignment.Center, + Alignment.Fill, + TextDirection.LeftRight_BottomTop, + @" +*0 2 4* +******* +******* +******* +******* +******* +*******")] + [InlineData ( + "0 2 4", + Alignment.Fill, + Alignment.Fill, + TextDirection.LeftRight_BottomTop, + @" +0 2 4 +******* +******* +******* +******* +******* +*******")] + [InlineData ( + "0 你 4", + Alignment.Start, + Alignment.Fill, + TextDirection.LeftRight_BottomTop, + @" +0 你 4* +******* +******* +******* +******* +******* +*******")] + [InlineData ( + "0 你 4", + Alignment.End, + Alignment.Fill, + TextDirection.LeftRight_BottomTop, + @" +*0 你 4 +******* +******* +******* +******* +******* +*******")] + [InlineData ( + "0 你 4", + Alignment.Center, + Alignment.Fill, + TextDirection.LeftRight_BottomTop, + @" +0 你 4* +******* +******* +******* +******* +******* +*******")] + [InlineData ( + "0 你 4", + Alignment.Fill, + Alignment.Fill, + TextDirection.LeftRight_BottomTop, + @" +0 你 4 +******* +******* +******* +******* +******* +*******")] + + // RightLeft_TopBottom + [InlineData ( + "0 2 4", + Alignment.Start, + Alignment.Fill, + TextDirection.RightLeft_TopBottom, + @" +4 2 0** +******* +******* +******* +******* +******* +*******")] + [InlineData ( + "0 2 4", + Alignment.End, + Alignment.Fill, + TextDirection.RightLeft_TopBottom, + @" +**4 2 0 +******* +******* +******* +******* +******* +*******")] + [InlineData ( + "0 2 4", + Alignment.Center, + Alignment.Fill, + TextDirection.RightLeft_TopBottom, + @" +*4 2 0* +******* +******* +******* +******* +******* +*******")] + [InlineData ( + "0 2 4", + Alignment.Fill, + Alignment.Fill, + TextDirection.RightLeft_TopBottom, + @" +4 2 0 +******* +******* +******* +******* +******* +*******")] + [InlineData ( + "0 你 4", + Alignment.Start, + Alignment.Fill, + TextDirection.RightLeft_TopBottom, + @" +4 你 0* +******* +******* +******* +******* +******* +*******")] + [InlineData ( + "0 你 4", + Alignment.End, + Alignment.Fill, + TextDirection.RightLeft_TopBottom, + @" +*4 你 0 +******* +******* +******* +******* +******* +*******")] + [InlineData ( + "0 你 4", + Alignment.Center, + Alignment.Fill, + TextDirection.RightLeft_TopBottom, + @" +4 你 0* +******* +******* +******* +******* +******* +*******")] + [InlineData ( + "0 你 4", + Alignment.Fill, + Alignment.Fill, + TextDirection.RightLeft_TopBottom, + @" +4 你 0 +******* +******* +******* +******* +******* +*******")] + + // RightLeft_BottomTop + [InlineData ( + "0 2 4", + Alignment.Start, + Alignment.Fill, + TextDirection.RightLeft_BottomTop, + @" +4 2 0** +******* +******* +******* +******* +******* +*******")] + [InlineData ( + "0 2 4", + Alignment.End, + Alignment.Fill, + TextDirection.RightLeft_BottomTop, + @" +**4 2 0 +******* +******* +******* +******* +******* +*******")] + [InlineData ( + "0 2 4", + Alignment.Center, + Alignment.Fill, + TextDirection.RightLeft_BottomTop, + @" +*4 2 0* +******* +******* +******* +******* +******* +*******")] + [InlineData ( + "0 2 4", + Alignment.Fill, + Alignment.Fill, + TextDirection.RightLeft_BottomTop, + @" +4 2 0 +******* +******* +******* +******* +******* +*******")] + [InlineData ( + "0 你 4", + Alignment.Start, + Alignment.Fill, + TextDirection.RightLeft_BottomTop, + @" +4 你 0* +******* +******* +******* +******* +******* +*******")] + [InlineData ( + "0 你 4", + Alignment.End, + Alignment.Fill, + TextDirection.RightLeft_BottomTop, + @" +*4 你 0 +******* +******* +******* +******* +******* +*******")] + [InlineData ( + "0 你 4", + Alignment.Center, + Alignment.Fill, + TextDirection.RightLeft_BottomTop, + @" +4 你 0* +******* +******* +******* +******* +******* +*******")] + [InlineData ( + "0 你 4", + Alignment.Fill, + Alignment.Fill, + TextDirection.RightLeft_BottomTop, + @" +4 你 0 +******* +******* +******* +******* +******* +*******")] + + // Vertical with alignment.Left + // TopBottom_LeftRight + [InlineData ( + "0 2 4", + Alignment.Start, + Alignment.Start, + TextDirection.TopBottom_LeftRight, + @" +0****** + ****** +2****** + ****** +4****** +******* +*******")] + [InlineData ( + "0 2 4", + Alignment.Start, + Alignment.End, + TextDirection.TopBottom_LeftRight, + @" +******* +******* +0****** + ****** +2****** + ****** +4******")] + [InlineData ( + "0 2 4", + Alignment.Start, + Alignment.Center, + TextDirection.TopBottom_LeftRight, + @" +******* +0****** + ****** +2****** + ****** +4****** +*******")] + [InlineData ( + "0 2 4", + Alignment.Start, + Alignment.Fill, + TextDirection.TopBottom_LeftRight, + @" +0****** + ****** + ****** +2****** + ****** + ****** +4******")] + [InlineData ( + "0 你 4", + Alignment.Start, + Alignment.Start, + TextDirection.TopBottom_LeftRight, + @" +0****** + ****** +你***** + ****** +4****** +******* +*******")] + [InlineData ( + "0 你 4", + Alignment.Start, + Alignment.End, + TextDirection.TopBottom_LeftRight, + @" +******* +******* +0****** + ****** +你***** + ****** +4******")] + [InlineData ( + "0 你 4", + Alignment.Start, + Alignment.Center, + TextDirection.TopBottom_LeftRight, + @" +******* +0****** + ****** +你***** + ****** +4****** +*******")] + [InlineData ( + "0 你 4", + Alignment.Start, + Alignment.Fill, + TextDirection.TopBottom_LeftRight, + @" +0****** + ****** + ****** +你***** + ****** + ****** +4******")] + + // TopBottom_RightLeft + [InlineData ( + "0 2 4", + Alignment.Start, + Alignment.Start, + TextDirection.TopBottom_RightLeft, + @" +0****** + ****** +2****** + ****** +4****** +******* +*******")] + [InlineData ( + "0 2 4", + Alignment.Start, + Alignment.End, + TextDirection.TopBottom_RightLeft, + @" +******* +******* +0****** + ****** +2****** + ****** +4******")] + [InlineData ( + "0 2 4", + Alignment.Start, + Alignment.Center, + TextDirection.TopBottom_RightLeft, + @" +******* +0****** + ****** +2****** + ****** +4****** +*******")] + [InlineData ( + "0 2 4", + Alignment.Start, + Alignment.Fill, + TextDirection.TopBottom_RightLeft, + @" +0****** + ****** + ****** +2****** + ****** + ****** +4******")] + [InlineData ( + "0 你 4", + Alignment.Start, + Alignment.Start, + TextDirection.TopBottom_RightLeft, + @" +0****** + ****** +你***** + ****** +4****** +******* +*******")] + [InlineData ( + "0 你 4", + Alignment.Start, + Alignment.End, + TextDirection.TopBottom_RightLeft, + @" +******* +******* +0****** + ****** +你***** + ****** +4******")] + [InlineData ( + "0 你 4", + Alignment.Start, + Alignment.Center, + TextDirection.TopBottom_RightLeft, + @" +******* +0****** + ****** +你***** + ****** +4****** +*******")] + [InlineData ( + "0 你 4", + Alignment.Start, + Alignment.Fill, + TextDirection.TopBottom_RightLeft, + @" +0****** + ****** + ****** +你***** + ****** + ****** +4******")] + + // BottomTop_LeftRight + [InlineData ( + "0 2 4", + Alignment.Start, + Alignment.Start, + TextDirection.BottomTop_LeftRight, + @" +4****** + ****** +2****** + ****** +0****** +******* +*******")] + [InlineData ( + "0 2 4", + Alignment.Start, + Alignment.End, + TextDirection.BottomTop_LeftRight, + @" +******* +******* +4****** + ****** +2****** + ****** +0******")] + [InlineData ( + "0 2 4", + Alignment.Start, + Alignment.Center, + TextDirection.BottomTop_LeftRight, + @" +******* +4****** + ****** +2****** + ****** +0****** +*******")] + [InlineData ( + "0 2 4", + Alignment.Start, + Alignment.Fill, + TextDirection.BottomTop_LeftRight, + @" +4****** + ****** + ****** +2****** + ****** + ****** +0******")] + [InlineData ( + "0 你 4", + Alignment.Start, + Alignment.Start, + TextDirection.BottomTop_LeftRight, + @" +4****** + ****** +你***** + ****** +0****** +******* +*******")] + [InlineData ( + "0 你 4", + Alignment.Start, + Alignment.End, + TextDirection.BottomTop_LeftRight, + @" +******* +******* +4****** + ****** +你***** + ****** +0******")] + [InlineData ( + "0 你 4", + Alignment.Start, + Alignment.Center, + TextDirection.BottomTop_LeftRight, + @" +******* +4****** + ****** +你***** + ****** +0****** +*******")] + [InlineData ( + "0 你 4", + Alignment.Start, + Alignment.Fill, + TextDirection.BottomTop_LeftRight, + @" +4****** + ****** + ****** +你***** + ****** + ****** +0******")] + + // BottomTop_RightLeft + [InlineData ( + "0 2 4", + Alignment.Start, + Alignment.Start, + TextDirection.BottomTop_RightLeft, + @" +4****** + ****** +2****** + ****** +0****** +******* +*******")] + [InlineData ( + "0 2 4", + Alignment.Start, + Alignment.End, + TextDirection.BottomTop_RightLeft, + @" +******* +******* +4****** + ****** +2****** + ****** +0******")] + [InlineData ( + "0 2 4", + Alignment.Start, + Alignment.Center, + TextDirection.BottomTop_RightLeft, + @" +******* +4****** + ****** +2****** + ****** +0****** +*******")] + [InlineData ( + "0 2 4", + Alignment.Start, + Alignment.Fill, + TextDirection.BottomTop_RightLeft, + @" +4****** + ****** + ****** +2****** + ****** + ****** +0******")] + [InlineData ( + "0 你 4", + Alignment.Start, + Alignment.Start, + TextDirection.BottomTop_RightLeft, + @" +4****** + ****** +你***** + ****** +0****** +******* +*******")] + [InlineData ( + "0 你 4", + Alignment.Start, + Alignment.End, + TextDirection.BottomTop_RightLeft, + @" +******* +******* +4****** + ****** +你***** + ****** +0******")] + [InlineData ( + "0 你 4", + Alignment.Start, + Alignment.Center, + TextDirection.BottomTop_RightLeft, + @" +******* +4****** + ****** +你***** + ****** +0****** +*******")] + [InlineData ( + "0 你 4", + Alignment.Start, + Alignment.Fill, + TextDirection.BottomTop_RightLeft, + @" +4****** + ****** + ****** +你***** + ****** + ****** +0******")] + + // Vertical with alignment.Right + // TopBottom_LeftRight + [InlineData ( + "0 2 4", + Alignment.End, + Alignment.Start, + TextDirection.TopBottom_LeftRight, + @" +******0 +****** +******2 +****** +******4 +******* +*******")] + [InlineData ( + "0 2 4", + Alignment.End, + Alignment.End, + TextDirection.TopBottom_LeftRight, + @" +******* +******* +******0 +****** +******2 +****** +******4")] + [InlineData ( + "0 2 4", + Alignment.End, + Alignment.Center, + TextDirection.TopBottom_LeftRight, + @" +******* +******0 +****** +******2 +****** +******4 +*******")] + [InlineData ( + "0 2 4", + Alignment.End, + Alignment.Fill, + TextDirection.TopBottom_LeftRight, + @" +******0 +****** +****** +******2 +****** +****** +******4")] + [InlineData ( + "0 你 4", + Alignment.End, + Alignment.Start, + TextDirection.TopBottom_LeftRight, + @" +*****0* +***** * +*****你 +***** * +*****4* +******* +*******")] + [InlineData ( + "0 你 4", + Alignment.End, + Alignment.End, + TextDirection.TopBottom_LeftRight, + @" +******* +******* +*****0* +***** * +*****你 +***** * +*****4*")] + [InlineData ( + "0 你 4", + Alignment.End, + Alignment.Center, + TextDirection.TopBottom_LeftRight, + @" +******* +*****0* +***** * +*****你 +***** * +*****4* +*******")] + [InlineData ( + "0 你 4", + Alignment.End, + Alignment.Fill, + TextDirection.TopBottom_LeftRight, + @" +*****0* +***** * +***** * +*****你 +***** * +***** * +*****4*")] + + // TopBottom_RightLeft + [InlineData ( + "0 2 4", + Alignment.End, + Alignment.Start, + TextDirection.TopBottom_RightLeft, + @" +******0 +****** +******2 +****** +******4 +******* +*******")] + [InlineData ( + "0 2 4", + Alignment.End, + Alignment.End, + TextDirection.TopBottom_RightLeft, + @" +******* +******* +******0 +****** +******2 +****** +******4")] + [InlineData ( + "0 2 4", + Alignment.End, + Alignment.Center, + TextDirection.TopBottom_RightLeft, + @" +******* +******0 +****** +******2 +****** +******4 +*******")] + [InlineData ( + "0 2 4", + Alignment.End, + Alignment.Fill, + TextDirection.TopBottom_RightLeft, + @" +******0 +****** +****** +******2 +****** +****** +******4")] + [InlineData ( + "0 你 4", + Alignment.End, + Alignment.Start, + TextDirection.TopBottom_RightLeft, + @" +*****0* +***** * +*****你 +***** * +*****4* +******* +*******")] + [InlineData ( + "0 你 4", + Alignment.End, + Alignment.End, + TextDirection.TopBottom_RightLeft, + @" +******* +******* +*****0* +***** * +*****你 +***** * +*****4*")] + [InlineData ( + "0 你 4", + Alignment.End, + Alignment.Center, + TextDirection.TopBottom_RightLeft, + @" +******* +*****0* +***** * +*****你 +***** * +*****4* +*******")] + [InlineData ( + "0 你 4", + Alignment.End, + Alignment.Fill, + TextDirection.TopBottom_RightLeft, + @" +*****0* +***** * +***** * +*****你 +***** * +***** * +*****4*")] + + // BottomTop_LeftRight + [InlineData ( + "0 2 4", + Alignment.End, + Alignment.Start, + TextDirection.BottomTop_LeftRight, + @" +******4 +****** +******2 +****** +******0 +******* +*******")] + [InlineData ( + "0 2 4", + Alignment.End, + Alignment.End, + TextDirection.BottomTop_LeftRight, + @" +******* +******* +******4 +****** +******2 +****** +******0")] + [InlineData ( + "0 2 4", + Alignment.End, + Alignment.Center, + TextDirection.BottomTop_LeftRight, + @" +******* +******4 +****** +******2 +****** +******0 +*******")] + [InlineData ( + "0 2 4", + Alignment.End, + Alignment.Fill, + TextDirection.BottomTop_LeftRight, + @" +******4 +****** +****** +******2 +****** +****** +******0")] + [InlineData ( + "0 你 4", + Alignment.End, + Alignment.Start, + TextDirection.BottomTop_LeftRight, + @" +*****4* +***** * +*****你 +***** * +*****0* +******* +*******")] + [InlineData ( + "0 你 4", + Alignment.End, + Alignment.End, + TextDirection.BottomTop_LeftRight, + @" +******* +******* +*****4* +***** * +*****你 +***** * +*****0*")] + [InlineData ( + "0 你 4", + Alignment.End, + Alignment.Center, + TextDirection.BottomTop_LeftRight, + @" +******* +*****4* +***** * +*****你 +***** * +*****0* +*******")] + [InlineData ( + "0 你 4", + Alignment.End, + Alignment.Fill, + TextDirection.BottomTop_LeftRight, + @" +*****4* +***** * +***** * +*****你 +***** * +***** * +*****0*")] + + // BottomTop_RightLeft + [InlineData ( + "0 2 4", + Alignment.End, + Alignment.Start, + TextDirection.BottomTop_RightLeft, + @" +******4 +****** +******2 +****** +******0 +******* +*******")] + [InlineData ( + "0 2 4", + Alignment.End, + Alignment.End, + TextDirection.BottomTop_RightLeft, + @" +******* +******* +******4 +****** +******2 +****** +******0")] + [InlineData ( + "0 2 4", + Alignment.End, + Alignment.Center, + TextDirection.BottomTop_RightLeft, + @" +******* +******4 +****** +******2 +****** +******0 +*******")] + [InlineData ( + "0 2 4", + Alignment.End, + Alignment.Fill, + TextDirection.BottomTop_RightLeft, + @" +******4 +****** +****** +******2 +****** +****** +******0")] + [InlineData ( + "0 你 4", + Alignment.End, + Alignment.Start, + TextDirection.BottomTop_RightLeft, + @" +*****4* +***** * +*****你 +***** * +*****0* +******* +*******")] + [InlineData ( + "0 你 4", + Alignment.End, + Alignment.End, + TextDirection.BottomTop_RightLeft, + @" +******* +******* +*****4* +***** * +*****你 +***** * +*****0*")] + [InlineData ( + "0 你 4", + Alignment.End, + Alignment.Center, + TextDirection.BottomTop_RightLeft, + @" +******* +*****4* +***** * +*****你 +***** * +*****0* +*******")] + [InlineData ( + "0 你 4", + Alignment.End, + Alignment.Fill, + TextDirection.BottomTop_RightLeft, + @" +*****4* +***** * +***** * +*****你 +***** * +***** * +*****0*")] + + // Vertical with alignment.Centered + // TopBottom_LeftRight + [InlineData ( + "0 2 4", + Alignment.Center, + Alignment.Start, + TextDirection.TopBottom_LeftRight, + @" +***0*** +*** *** +***2*** +*** *** +***4*** +******* +*******")] + [InlineData ( + "0 2 4", + Alignment.Center, + Alignment.End, + TextDirection.TopBottom_LeftRight, + @" +******* +******* +***0*** +*** *** +***2*** +*** *** +***4***")] + [InlineData ( + "0 2 4", + Alignment.Center, + Alignment.Center, + TextDirection.TopBottom_LeftRight, + @" +******* +***0*** +*** *** +***2*** +*** *** +***4*** +*******")] + [InlineData ( + "0 2 4", + Alignment.Center, + Alignment.Fill, + TextDirection.TopBottom_LeftRight, + @" +***0*** +*** *** +*** *** +***2*** +*** *** +*** *** +***4***")] + [InlineData ( + "0 你 4", + Alignment.Center, + Alignment.Start, + TextDirection.TopBottom_LeftRight, + @" +**0**** +** **** +**你*** +** **** +**4**** +******* +*******")] + [InlineData ( + "0 你 4", + Alignment.Center, + Alignment.End, + TextDirection.TopBottom_LeftRight, + @" +******* +******* +**0**** +** **** +**你*** +** **** +**4****")] + [InlineData ( + "0 你 4", + Alignment.Center, + Alignment.Center, + TextDirection.TopBottom_LeftRight, + @" +******* +**0**** +** **** +**你*** +** **** +**4**** +*******")] + [InlineData ( + "0 你 4", + Alignment.Center, + Alignment.Fill, + TextDirection.TopBottom_LeftRight, + @" +**0**** +** **** +** **** +**你*** +** **** +** **** +**4****")] + + // TopBottom_RightLeft + [InlineData ( + "0 2 4", + Alignment.Center, + Alignment.Start, + TextDirection.TopBottom_RightLeft, + @" +***0*** +*** *** +***2*** +*** *** +***4*** +******* +*******")] + [InlineData ( + "0 2 4", + Alignment.Center, + Alignment.End, + TextDirection.TopBottom_RightLeft, + @" +******* +******* +***0*** +*** *** +***2*** +*** *** +***4***")] + [InlineData ( + "0 2 4", + Alignment.Center, + Alignment.Center, + TextDirection.TopBottom_RightLeft, + @" +******* +***0*** +*** *** +***2*** +*** *** +***4*** +*******")] + [InlineData ( + "0 2 4", + Alignment.Center, + Alignment.Fill, + TextDirection.TopBottom_RightLeft, + @" +***0*** +*** *** +*** *** +***2*** +*** *** +*** *** +***4***")] + [InlineData ( + "0 你 4", + Alignment.Center, + Alignment.Start, + TextDirection.TopBottom_RightLeft, + @" +**0**** +** **** +**你*** +** **** +**4**** +******* +*******")] + [InlineData ( + "0 你 4", + Alignment.Center, + Alignment.End, + TextDirection.TopBottom_RightLeft, + @" +******* +******* +**0**** +** **** +**你*** +** **** +**4****")] + [InlineData ( + "0 你 4", + Alignment.Center, + Alignment.Center, + TextDirection.TopBottom_RightLeft, + @" +******* +**0**** +** **** +**你*** +** **** +**4**** +*******")] + [InlineData ( + "0 你 4", + Alignment.Center, + Alignment.Fill, + TextDirection.TopBottom_RightLeft, + @" +**0**** +** **** +** **** +**你*** +** **** +** **** +**4****")] + + // BottomTop_LeftRight + [InlineData ( + "0 2 4", + Alignment.Center, + Alignment.Start, + TextDirection.BottomTop_LeftRight, + @" +***4*** +*** *** +***2*** +*** *** +***0*** +******* +*******")] + [InlineData ( + "0 2 4", + Alignment.Center, + Alignment.End, + TextDirection.BottomTop_LeftRight, + @" +******* +******* +***4*** +*** *** +***2*** +*** *** +***0***")] + [InlineData ( + "0 2 4", + Alignment.Center, + Alignment.Center, + TextDirection.BottomTop_LeftRight, + @" +******* +***4*** +*** *** +***2*** +*** *** +***0*** +*******")] + [InlineData ( + "0 2 4", + Alignment.Center, + Alignment.Fill, + TextDirection.BottomTop_LeftRight, + @" +***4*** +*** *** +*** *** +***2*** +*** *** +*** *** +***0***")] + [InlineData ( + "0 你 4", + Alignment.Center, + Alignment.Start, + TextDirection.BottomTop_LeftRight, + @" +**4**** +** **** +**你*** +** **** +**0**** +******* +*******")] + [InlineData ( + "0 你 4", + Alignment.Center, + Alignment.End, + TextDirection.BottomTop_LeftRight, + @" +******* +******* +**4**** +** **** +**你*** +** **** +**0****")] + [InlineData ( + "0 你 4", + Alignment.Center, + Alignment.Center, + TextDirection.BottomTop_LeftRight, + @" +******* +**4**** +** **** +**你*** +** **** +**0**** +*******")] + [InlineData ( + "0 你 4", + Alignment.Center, + Alignment.Fill, + TextDirection.BottomTop_LeftRight, + @" +**4**** +** **** +** **** +**你*** +** **** +** **** +**0****")] + + // BottomTop_RightLeft + [InlineData ( + "0 2 4", + Alignment.Center, + Alignment.Start, + TextDirection.BottomTop_RightLeft, + @" +***4*** +*** *** +***2*** +*** *** +***0*** +******* +*******")] + [InlineData ( + "0 2 4", + Alignment.Center, + Alignment.End, + TextDirection.BottomTop_RightLeft, + @" +******* +******* +***4*** +*** *** +***2*** +*** *** +***0***")] + [InlineData ( + "0 2 4", + Alignment.Center, + Alignment.Center, + TextDirection.BottomTop_RightLeft, + @" +******* +***4*** +*** *** +***2*** +*** *** +***0*** +*******")] + [InlineData ( + "0 2 4", + Alignment.Center, + Alignment.Fill, + TextDirection.BottomTop_RightLeft, + @" +***4*** +*** *** +*** *** +***2*** +*** *** +*** *** +***0***")] + [InlineData ( + "0 你 4", + Alignment.Center, + Alignment.Start, + TextDirection.BottomTop_RightLeft, + @" +**4**** +** **** +**你*** +** **** +**0**** +******* +*******")] + [InlineData ( + "0 你 4", + Alignment.Center, + Alignment.End, + TextDirection.BottomTop_RightLeft, + @" +******* +******* +**4**** +** **** +**你*** +** **** +**0****")] + [InlineData ( + "0 你 4", + Alignment.Center, + Alignment.Center, + TextDirection.BottomTop_RightLeft, + @" +******* +**4**** +** **** +**你*** +** **** +**0**** +*******")] + [InlineData ( + "0 你 4", + Alignment.Center, + Alignment.Fill, + TextDirection.BottomTop_RightLeft, + @" +**4**** +** **** +** **** +**你*** +** **** +** **** +**0****")] + + // Vertical with alignment.Justified + // TopBottom_LeftRight + [InlineData ( + "0 2 4", + Alignment.Fill, + Alignment.Start, + TextDirection.TopBottom_LeftRight, + @" +0****** + ****** +2****** + ****** +4****** +******* +*******")] + [InlineData ( + "0 2 4", + Alignment.Fill, + Alignment.End, + TextDirection.TopBottom_LeftRight, + @" +******* +******* +0****** + ****** +2****** + ****** +4******")] + [InlineData ( + "0 2 4", + Alignment.Fill, + Alignment.Center, + TextDirection.TopBottom_LeftRight, + @" +******* +0****** + ****** +2****** + ****** +4****** +*******")] + [InlineData ( + "0 2 4", + Alignment.Fill, + Alignment.Fill, + TextDirection.TopBottom_LeftRight, + @" +0****** + ****** + ****** +2****** + ****** + ****** +4******")] + [InlineData ( + "0 你 4", + Alignment.Fill, + Alignment.Start, + TextDirection.TopBottom_LeftRight, + @" +0****** + ****** +你***** + ****** +4****** +******* +*******")] + [InlineData ( + "0 你 4", + Alignment.Fill, + Alignment.End, + TextDirection.TopBottom_LeftRight, + @" +******* +******* +0****** + ****** +你***** + ****** +4******")] + [InlineData ( + "0 你 4", + Alignment.Fill, + Alignment.Center, + TextDirection.TopBottom_LeftRight, + @" +******* +0****** + ****** +你***** + ****** +4****** +*******")] + [InlineData ( + "0 你 4", + Alignment.Fill, + Alignment.Fill, + TextDirection.TopBottom_LeftRight, + @" +0****** + ****** + ****** +你***** + ****** + ****** +4******")] + + // TopBottom_RightLeft + [InlineData ( + "0 2 4", + Alignment.Fill, + Alignment.Start, + TextDirection.TopBottom_RightLeft, + @" +0****** + ****** +2****** + ****** +4****** +******* +*******")] + [InlineData ( + "0 2 4", + Alignment.Fill, + Alignment.End, + TextDirection.TopBottom_RightLeft, + @" +******* +******* +0****** + ****** +2****** + ****** +4******")] + [InlineData ( + "0 2 4", + Alignment.Fill, + Alignment.Center, + TextDirection.TopBottom_RightLeft, + @" +******* +0****** + ****** +2****** + ****** +4****** +*******")] + [InlineData ( + "0 2 4", + Alignment.Fill, + Alignment.Fill, + TextDirection.TopBottom_RightLeft, + @" +0****** + ****** + ****** +2****** + ****** + ****** +4******")] + [InlineData ( + "0 你 4", + Alignment.Fill, + Alignment.Start, + TextDirection.TopBottom_RightLeft, + @" +0****** + ****** +你***** + ****** +4****** +******* +*******")] + [InlineData ( + "0 你 4", + Alignment.Fill, + Alignment.End, + TextDirection.TopBottom_RightLeft, + @" +******* +******* +0****** + ****** +你***** + ****** +4******")] + [InlineData ( + "0 你 4", + Alignment.Fill, + Alignment.Center, + TextDirection.TopBottom_RightLeft, + @" +******* +0****** + ****** +你***** + ****** +4****** +*******")] + [InlineData ( + "0 你 4", + Alignment.Fill, + Alignment.Fill, + TextDirection.TopBottom_RightLeft, + @" +0****** + ****** + ****** +你***** + ****** + ****** +4******")] + + // BottomTop_LeftRight + [InlineData ( + "0 2 4", + Alignment.Fill, + Alignment.Start, + TextDirection.BottomTop_LeftRight, + @" +4****** + ****** +2****** + ****** +0****** +******* +*******")] + [InlineData ( + "0 2 4", + Alignment.Fill, + Alignment.End, + TextDirection.BottomTop_LeftRight, + @" +******* +******* +4****** + ****** +2****** + ****** +0******")] + [InlineData ( + "0 2 4", + Alignment.Fill, + Alignment.Center, + TextDirection.BottomTop_LeftRight, + @" +******* +4****** + ****** +2****** + ****** +0****** +*******")] + [InlineData ( + "0 2 4", + Alignment.Fill, + Alignment.Fill, + TextDirection.BottomTop_LeftRight, + @" +4****** + ****** + ****** +2****** + ****** + ****** +0******")] + [InlineData ( + "0 你 4", + Alignment.Fill, + Alignment.Start, + TextDirection.BottomTop_LeftRight, + @" +4****** + ****** +你***** + ****** +0****** +******* +*******")] + [InlineData ( + "0 你 4", + Alignment.Fill, + Alignment.End, + TextDirection.BottomTop_LeftRight, + @" +******* +******* +4****** + ****** +你***** + ****** +0******")] + [InlineData ( + "0 你 4", + Alignment.Fill, + Alignment.Center, + TextDirection.BottomTop_LeftRight, + @" +******* +4****** + ****** +你***** + ****** +0****** +*******")] + [InlineData ( + "0 你 4", + Alignment.Fill, + Alignment.Fill, + TextDirection.BottomTop_LeftRight, + @" +4****** + ****** + ****** +你***** + ****** + ****** +0******")] + + // BottomTop_RightLeft + [InlineData ( + "0 2 4", + Alignment.Fill, + Alignment.Start, + TextDirection.BottomTop_RightLeft, + @" +4****** + ****** +2****** + ****** +0****** +******* +*******")] + [InlineData ( + "0 2 4", + Alignment.Fill, + Alignment.End, + TextDirection.BottomTop_RightLeft, + @" +******* +******* +4****** + ****** +2****** + ****** +0******")] + [InlineData ( + "0 2 4", + Alignment.Fill, + Alignment.Center, + TextDirection.BottomTop_RightLeft, + @" +******* +4****** + ****** +2****** + ****** +0****** +*******")] + [InlineData ( + "0 2 4", + Alignment.Fill, + Alignment.Fill, + TextDirection.BottomTop_RightLeft, + @" +4****** + ****** + ****** +2****** + ****** + ****** +0******")] + [InlineData ( + "0 你 4", + Alignment.Fill, + Alignment.Start, + TextDirection.BottomTop_RightLeft, + @" +4****** + ****** +你***** + ****** +0****** +******* +*******")] + [InlineData ( + "0 你 4", + Alignment.Fill, + Alignment.End, + TextDirection.BottomTop_RightLeft, + @" +******* +******* +4****** + ****** +你***** + ****** +0******")] + [InlineData ( + "0 你 4", + Alignment.Fill, + Alignment.Center, + TextDirection.BottomTop_RightLeft, + @" +******* +4****** + ****** +你***** + ****** +0****** +*******")] + [InlineData ( + "0 你 4", + Alignment.Fill, + Alignment.Fill, + TextDirection.BottomTop_RightLeft, + @" +4****** + ****** + ****** +你***** + ****** + ****** +0******")] + public void Draw_Text_Justification (string text, Alignment horizontalTextAlignment, Alignment alignment, TextDirection textDirection, string expectedText) + { + TextFormatter tf = new () + { + Alignment = horizontalTextAlignment, + VerticalAlignment = alignment, + Direction = textDirection, + ConstrainToSize = new (7, 7), + Text = text + }; + + Application.Driver?.FillRect (new (0, 0, 7, 7), (Rune)'*'); + tf.Draw (new (0, 0, 7, 7), Attribute.Default, Attribute.Default); + DriverAssert.AssertDriverContentsWithFrameAre (expectedText, _output); + } + + [SetupFakeDriver] + [Theory] + [InlineData ("A", 0, 1, "", 0)] + [InlineData ("A", 1, 1, "A", 0)] + [InlineData ("A", 2, 2, " A", 1)] + [InlineData ("AB", 1, 1, "B", 0)] + [InlineData ("AB", 2, 2, " A\n B", 0)] + [InlineData ("ABC", 3, 2, " B\n C", 0)] + [InlineData ("ABC", 4, 2, " B\n C", 0)] + [InlineData ("ABC", 6, 2, " B\n C", 0)] + [InlineData ("こんにちは", 0, 1, "", 0)] + [InlineData ("こんにちは", 1, 0, "", 0)] + [InlineData ("こんにちは", 1, 1, "", 0)] + [InlineData ("こんにちは", 2, 1, "は", 0)] + [InlineData ("こんにちは", 2, 2, "ち\nは", 0)] + [InlineData ("こんにちは", 2, 3, "に\nち\nは", 0)] + [InlineData ("こんにちは", 2, 4, "ん\nに\nち\nは", 0)] + [InlineData ("こんにちは", 2, 5, "こ\nん\nに\nち\nは", 0)] + [InlineData ("こんにちは", 2, 6, "こ\nん\nに\nち\nは", 1)] + [InlineData ("ABCD\nこんにちは", 4, 7, " こ\n Aん\n Bに\n Cち\n Dは", 2)] + [InlineData ("こんにちは\nABCD", 3, 7, "こ \nんA\nにB\nちC\nはD", 2)] + public void Draw_Vertical_Bottom_Horizontal_Right (string text, int width, int height, string expectedText, int expectedY) + { + TextFormatter tf = new () + { + Text = text, + Alignment = Alignment.End, + Direction = TextDirection.TopBottom_LeftRight, + VerticalAlignment = Alignment.End + }; + + tf.ConstrainToWidth = width; + tf.ConstrainToHeight = height; + + tf.Draw (new (Point.Empty, new (width, height)), Attribute.Default, Attribute.Default); + Rectangle rect = DriverAssert.AssertDriverContentsWithFrameAre (expectedText, _output); + Assert.Equal (expectedY, rect.Y); + } + + [SetupFakeDriver] + [Theory] + [InlineData ("A", 1, 0, "")] + [InlineData ("A", 0, 1, "")] + [InlineData ("AB1 2", 1, 2, "2")] + [InlineData ("AB12", 1, 5, "2\n1\nB\nA")] + [InlineData ("AB\n12", 2, 5, "B2\nA1")] + [InlineData ("ABC 123 456", 2, 7, "6C\n5B\n4A\n \n3 \n2 \n1 ")] + [InlineData ("こんにちは", 1, 1, "")] + [InlineData ("こんにちは", 2, 1, "は")] + [InlineData ("こんにちは", 2, 5, "は\nち\nに\nん\nこ")] + [InlineData ("こんにちは", 2, 10, "は\nち\nに\nん\nこ")] + [InlineData ("こんにちは\nAB\n12", 4, 10, "はB2\nちA1\nに \nん \nこ ")] + public void Draw_Vertical_BottomTop_LeftRight (string text, int width, int height, string expectedText) + { + TextFormatter tf = new () + { + Text = text, + Direction = TextDirection.BottomTop_LeftRight + }; + + tf.ConstrainToWidth = width; + tf.ConstrainToHeight = height; + tf.Draw (new (0, 0, width, height), Attribute.Default, Attribute.Default); + + DriverAssert.AssertDriverContentsWithFrameAre (expectedText, _output); + } + + [SetupFakeDriver] + [Theory] + [InlineData ("A", 1, 0, "")] + [InlineData ("A", 0, 1, "")] + [InlineData ("AB1 2", 1, 2, "2")] + [InlineData ("AB12", 1, 5, "2\n1\nB\nA")] + [InlineData ("AB\n12", 2, 5, "2B\n1A")] + [InlineData ("ABC 123 456", 2, 7, "C6\nB5\nA4\n \n 3\n 2\n 1")] + [InlineData ("こんにちは", 1, 1, "")] + [InlineData ("こんにちは", 2, 1, "は")] + [InlineData ("こんにちは", 2, 5, "は\nち\nに\nん\nこ")] + [InlineData ("こんにちは", 2, 10, "は\nち\nに\nん\nこ")] + [InlineData ("こんにちは\nAB\n12", 4, 10, "2Bは\n1Aち\n に\n ん\n こ")] + public void Draw_Vertical_BottomTop_RightLeft (string text, int width, int height, string expectedText) + { + TextFormatter tf = new () + { + Text = text, + Direction = TextDirection.BottomTop_RightLeft + }; + + tf.ConstrainToWidth = width; + tf.ConstrainToHeight = height; + tf.Draw (new (0, 0, width, height), Attribute.Default, Attribute.Default); + + DriverAssert.AssertDriverContentsWithFrameAre (expectedText, _output); + } + + // Draw tests - Note that these depend on View + + [Fact] + [TestRespondersDisposed] + public void Draw_Vertical_Throws_IndexOutOfRangeException_With_Negative_Bounds () + { + Application.Init (new FakeDriver ()); + Dialog.DefaultShadow = ShadowStyle.None; + Button.DefaultShadow = ShadowStyle.None; + + Toplevel top = new (); + + var view = new View { Y = -2, Height = 10, TextDirection = TextDirection.TopBottom_LeftRight, Text = "view" }; + top.Add (view); + + Application.Iteration += (s, a) => + { + Assert.Equal (-2, view.Y); + + Application.RequestStop (); + }; + + try + { + Application.Run (top); + } + catch (IndexOutOfRangeException ex) + { + // After the fix this exception will not be caught. + Assert.IsType (ex); + } + + top.Dispose (); + + // Shutdown must be called to safely clean up Application if Init has been called + Application.Shutdown (); + } + + [SetupFakeDriver] + [Theory] + [InlineData ("A", 5, 5, "A")] + [InlineData ( + "AB12", + 5, + 5, + @" +A +B +1 +2")] + [InlineData ( + "AB\n12", + 5, + 5, + @" +A1 +B2")] + [InlineData ("", 5, 1, "")] + [InlineData ( + "Hello Worlds", + 1, + 12, + @" +H +e +l +l +o + +W +o +r +l +d +s")] + [InlineData ("Hello Worlds", 12, 1, @"HelloWorlds")] + public void Draw_Vertical_TopBottom_LeftRight (string text, int width, int height, string expectedText) + { + TextFormatter tf = new () + { + Text = text, + Direction = TextDirection.TopBottom_LeftRight + }; + + tf.ConstrainToWidth = width; + tf.ConstrainToHeight = height; + tf.Draw (new (0, 0, 20, 20), Attribute.Default, Attribute.Default); + + DriverAssert.AssertDriverContentsWithFrameAre (expectedText, _output); + } + + [SetupFakeDriver] + [Theory] + + // The expectedY param is to probe that the expectedText param start at that Y coordinate + [InlineData ("A", 0, "", 0)] + [InlineData ("A", 1, "A", 0)] + [InlineData ("A", 2, "A", 0)] + [InlineData ("A", 3, "A", 1)] + [InlineData ("AB", 1, "A", 0)] + [InlineData ("AB", 2, "A\nB", 0)] + [InlineData ("ABC", 2, "A\nB", 0)] + [InlineData ("ABC", 3, "A\nB\nC", 0)] + [InlineData ("ABC", 4, "A\nB\nC", 0)] + [InlineData ("ABC", 5, "A\nB\nC", 1)] + [InlineData ("ABC", 6, "A\nB\nC", 1)] + [InlineData ("ABC", 9, "A\nB\nC", 3)] + [InlineData ("ABCD", 2, "B\nC", 0)] + [InlineData ("こんにちは", 0, "", 0)] + [InlineData ("こんにちは", 1, "に", 0)] + [InlineData ("こんにちは", 2, "ん\nに", 0)] + [InlineData ("こんにちは", 3, "ん\nに\nち", 0)] + [InlineData ("こんにちは", 4, "こ\nん\nに\nち", 0)] + [InlineData ("こんにちは", 5, "こ\nん\nに\nち\nは", 0)] + [InlineData ("こんにちは", 6, "こ\nん\nに\nち\nは", 0)] + [InlineData ("ABCD\nこんにちは", 7, "Aこ\nBん\nCに\nDち\n は", 1)] + [InlineData ("こんにちは\nABCD", 7, "こA\nんB\nにC\nちD\nは ", 1)] + public void Draw_Vertical_TopBottom_LeftRight_Middle (string text, int height, string expectedText, int expectedY) + { + TextFormatter tf = new () + { + Text = text, + Direction = TextDirection.TopBottom_LeftRight, + VerticalAlignment = Alignment.Center + }; + + int width = text.ToRunes ().Max (r => r.GetColumns ()); + + if (text.Contains ("\n")) + { + width++; + } + + tf.ConstrainToWidth = width; + tf.ConstrainToHeight = height; + tf.Draw (new (0, 0, 5, height), Attribute.Default, Attribute.Default); + + Rectangle rect = DriverAssert.AssertDriverContentsWithFrameAre (expectedText, _output); + Assert.Equal (expectedY, rect.Y); + } + + [SetupFakeDriver] + [Theory] + [InlineData ("A", 5, "A")] + [InlineData ( + "AB12", + 5, + @" +A +B +1 +2")] + [InlineData ( + "AB\n12", + 5, + @" +A1 +B2")] + [InlineData ("", 1, "")] + [InlineData ( + "AB1 2", + 2, + @" +A12 +B ")] + [InlineData ( + "こんにちは", + 1, + @" +こん")] + [InlineData ( + "こんにちは", + 2, + @" +こに +んち")] + [InlineData ( + "こんにちは", + 5, + @" +こ +ん +に +ち +は")] + public void Draw_Vertical_TopBottom_LeftRight_Top (string text, int height, string expectedText) + { + TextFormatter tf = new () + { + Text = text, + Direction = TextDirection.TopBottom_LeftRight + }; + + tf.ConstrainToWidth = 5; + tf.ConstrainToHeight = height; + tf.Draw (new (0, 0, 5, height), Attribute.Default, Attribute.Default); + + DriverAssert.AssertDriverContentsWithFrameAre (expectedText, _output); + } + + [Theory] + [InlineData (14, 1, TextDirection.LeftRight_TopBottom, "Les Misęrables")] + [InlineData (1, 14, TextDirection.TopBottom_LeftRight, "L\ne\ns\n \nM\ni\ns\nę\nr\na\nb\nl\ne\ns")] + [InlineData ( + 4, + 4, + TextDirection.TopBottom_LeftRight, + @" +LMre +eias +ssb + ęl " + )] + public void Draw_With_Combining_Runes (int width, int height, TextDirection textDirection, string expected) + { + var driver = new FakeDriver (); + driver.Init (); + + var text = "Les Mise\u0328\u0301rables"; + + var tf = new TextFormatter (); + tf.Direction = textDirection; + tf.Text = text; + + Assert.True (tf.WordWrap); + + tf.ConstrainToSize = new (width, height); + + tf.Draw ( + new (0, 0, width, height), + new (ColorName16.White, ColorName16.Black), + new (ColorName16.Blue, ColorName16.Black), + default (Rectangle), + driver + ); + DriverAssert.AssertDriverContentsWithFrameAre (expected, _output, driver); + + driver.End (); + } + + [Fact] + [SetupFakeDriver] + public void FillRemaining_True_False () + { + ((FakeDriver)Application.Driver!).SetBufferSize (22, 5); + + Attribute [] attrs = + { + Attribute.Default, new (ColorName16.Green, ColorName16.BrightMagenta), + new (ColorName16.Blue, ColorName16.Cyan) + }; + var tf = new TextFormatter { ConstrainToSize = new (14, 3), Text = "Test\nTest long\nTest long long\n", MultiLine = true }; + + tf.Draw ( + new (1, 1, 19, 3), + attrs [1], + attrs [2]); + + Assert.False (tf.FillRemaining); + + DriverAssert.AssertDriverContentsWithFrameAre ( + @" + Test + Test long + Test long long", + _output); + + DriverAssert.AssertDriverAttributesAre ( + @" +000000000000000000000 +011110000000000000000 +011111111100000000000 +011111111111111000000 +000000000000000000000", + _output, + null, + attrs); + + tf.FillRemaining = true; + + tf.Draw ( + new (1, 1, 19, 3), + attrs [1], + attrs [2]); + + DriverAssert.AssertDriverAttributesAre ( + @" +000000000000000000000 +011111111111111111110 +011111111111111111110 +011111111111111111110 +000000000000000000000", + _output, + null, + attrs); + } + + [SetupFakeDriver] + [Theory] + [InlineData ("Hello World", 15, 1, "Hello World")] + [InlineData ( + "Well Done\nNice Work", + 15, + 2, + @" +Well Done +Nice Work")] + [InlineData ("你好 世界", 15, 1, "你好 世界")] + [InlineData ( + "做 得好\n幹 得好", + 15, + 2, + @" +做 得好 +幹 得好")] + public void Justify_Horizontal (string text, int width, int height, string expectedText) + { + TextFormatter tf = new () + { + Text = text, + Alignment = Alignment.Fill, + ConstrainToSize = new Size (width, height), + MultiLine = true + }; + + tf.Draw (new (0, 0, width, height), Attribute.Default, Attribute.Default); + + DriverAssert.AssertDriverContentsWithFrameAre (expectedText, _output); + } + + [Theory] + [InlineData (17, 1, TextDirection.LeftRight_TopBottom, 4, "This is a Tab")] + [InlineData (1, 17, TextDirection.TopBottom_LeftRight, 4, "T\nh\ni\ns\n \ni\ns\n \na\n \n \n \n \n \nT\na\nb")] + [InlineData (13, 1, TextDirection.LeftRight_TopBottom, 0, "This is a Tab")] + [InlineData (1, 13, TextDirection.TopBottom_LeftRight, 0, "T\nh\ni\ns\n \ni\ns\n \na\n \nT\na\nb")] + public void TabWith_PreserveTrailingSpaces_False ( + int width, + int height, + TextDirection textDirection, + int tabWidth, + string expected + ) + { + var driver = new FakeDriver (); + driver.Init (); + + var text = "This is a \tTab"; + var tf = new TextFormatter (); + tf.Direction = textDirection; + tf.TabWidth = tabWidth; + tf.Text = text; + tf.ConstrainToWidth = 20; + tf.ConstrainToHeight = 20; + + Assert.True (tf.WordWrap); + Assert.False (tf.PreserveTrailingSpaces); + + tf.Draw ( + new (0, 0, width, height), + new (ColorName16.White, ColorName16.Black), + new (ColorName16.Blue, ColorName16.Black), + default (Rectangle), + driver + ); + DriverAssert.AssertDriverContentsWithFrameAre (expected, _output, driver); + + driver.End (); + } + + [Theory] + [InlineData (17, 1, TextDirection.LeftRight_TopBottom, 4, "This is a Tab")] + [InlineData (1, 17, TextDirection.TopBottom_LeftRight, 4, "T\nh\ni\ns\n \ni\ns\n \na\n \n \n \n \n \nT\na\nb")] + [InlineData (13, 1, TextDirection.LeftRight_TopBottom, 0, "This is a Tab")] + [InlineData (1, 13, TextDirection.TopBottom_LeftRight, 0, "T\nh\ni\ns\n \ni\ns\n \na\n \nT\na\nb")] + public void TabWith_PreserveTrailingSpaces_True ( + int width, + int height, + TextDirection textDirection, + int tabWidth, + string expected + ) + { + var driver = new FakeDriver (); + driver.Init (); + + var text = "This is a \tTab"; + var tf = new TextFormatter (); + + tf.Direction = textDirection; + tf.TabWidth = tabWidth; + tf.PreserveTrailingSpaces = true; + tf.Text = text; + tf.ConstrainToWidth = 20; + tf.ConstrainToHeight = 20; + + Assert.True (tf.WordWrap); + + tf.Draw ( + new (0, 0, width, height), + new (ColorName16.White, ColorName16.Black), + new (ColorName16.Blue, ColorName16.Black), + default (Rectangle), + driver + ); + DriverAssert.AssertDriverContentsWithFrameAre (expected, _output, driver); + + driver.End (); + } + + [Theory] + [InlineData (17, 1, TextDirection.LeftRight_TopBottom, 4, "This is a Tab")] + [InlineData (1, 17, TextDirection.TopBottom_LeftRight, 4, "T\nh\ni\ns\n \ni\ns\n \na\n \n \n \n \n \nT\na\nb")] + [InlineData (13, 1, TextDirection.LeftRight_TopBottom, 0, "This is a Tab")] + [InlineData (1, 13, TextDirection.TopBottom_LeftRight, 0, "T\nh\ni\ns\n \ni\ns\n \na\n \nT\na\nb")] + public void TabWith_WordWrap_True ( + int width, + int height, + TextDirection textDirection, + int tabWidth, + string expected + ) + { + var driver = new FakeDriver (); + driver.Init (); + + var text = "This is a \tTab"; + var tf = new TextFormatter (); + + tf.Direction = textDirection; + tf.TabWidth = tabWidth; + tf.WordWrap = true; + tf.Text = text; + tf.ConstrainToWidth = 20; + tf.ConstrainToHeight = 20; + + Assert.False (tf.PreserveTrailingSpaces); + + tf.Draw ( + new (0, 0, width, height), + new (ColorName16.White, ColorName16.Black), + new (ColorName16.Blue, ColorName16.Black), + default (Rectangle), + driver + ); + DriverAssert.AssertDriverContentsWithFrameAre (expected, _output, driver); + + driver.End (); + } + + [Fact] + [SetupFakeDriver] + public void UICatalog_AboutBox_Text () + { + TextFormatter tf = new () + { + Text = UICatalogApp.GetAboutBoxMessage (), + Alignment = Alignment.Center, + VerticalAlignment = Alignment.Start, + WordWrap = false, + MultiLine = true, + HotKeySpecifier = (Rune)0xFFFF + }; + + Size tfSize = tf.FormatAndGetSize (); + Assert.Equal (new (59, 13), tfSize); + + ((FakeDriver)Application.Driver).SetBufferSize (tfSize.Width, tfSize.Height); + + Application.Driver.FillRect (Application.Screen, (Rune)'*'); + tf.Draw (Application.Screen, Attribute.Default, Attribute.Default); + + var expectedText = """ + UI Catalog: A comprehensive sample library and test app for + *********************************************************** + _______ _ _ _____ _ * + |__ __| (_) | | / ____| (_)* + | | ___ _ __ _ __ ___ _ _ __ __ _| || | __ _ _ _ * + | |/ _ \ '__| '_ ` _ \| | '_ \ / _` | || | |_ | | | | |* + | | __/ | | | | | | | | | | | (_| | || |__| | |_| | |* + |_|\___|_| |_| |_| |_|_|_| |_|\__,_|_(_)_____|\__,_|_|* + *********************************************************** + **********************v2 - Pre-Alpha*********************** + *********************************************************** + **********https://github.com/gui-cs/Terminal.Gui*********** + *********************************************************** + """; + + DriverAssert.AssertDriverContentsAre (expectedText.ReplaceLineEndings (), _output); + } + + #region FormatAndGetSizeTests + + // TODO: Add multi-line examples + // TODO: Add other TextDirection examples + + [Theory] + [SetupFakeDriver] + [InlineData ("界1234", 10, 10, TextDirection.LeftRight_TopBottom, 6, 1, @"界1234")] + [InlineData ("01234", 10, 10, TextDirection.LeftRight_TopBottom, 5, 1, @"01234")] + [InlineData ( + "界1234", + 10, + 10, + TextDirection.TopBottom_LeftRight, + 2, + 5, + """ + 界 + 1 + 2 + 3 + 4 + """)] + [InlineData ( + "01234", + 10, + 10, + TextDirection.TopBottom_LeftRight, + 1, + 5, + """ + 0 + 1 + 2 + 3 + 4 + """)] + [InlineData ( + "界1234", + 3, + 3, + TextDirection.LeftRight_TopBottom, + 3, + 2, + """ + 界1 + 234 + """)] + [InlineData ( + "01234", + 3, + 3, + TextDirection.LeftRight_TopBottom, + 3, + 2, + """ + 012 + 34 + """)] + [InlineData ( + "界1234", + 3, + 3, + TextDirection.TopBottom_LeftRight, + 3, + 3, + """ + 界3 + 1 4 + 2 + """)] + [InlineData ( + "01234", + 3, + 3, + TextDirection.TopBottom_LeftRight, + 2, + 3, + """ + 03 + 14 + 2 + """)] + [InlineData ("01234", 2, 1, TextDirection.LeftRight_TopBottom, 2, 1, @"01")] + public void FormatAndGetSize_Returns_Correct_Size ( + string text, + int width, + int height, + TextDirection direction, + int expectedWidth, + int expectedHeight, + string expectedDraw + ) + { + TextFormatter tf = new () + { + Direction = direction, + ConstrainToWidth = width, + ConstrainToHeight = height, + Text = text + }; + Assert.True (tf.WordWrap); + Size size = tf.FormatAndGetSize (); + Assert.Equal (new (expectedWidth, expectedHeight), size); + + tf.Draw (new (0, 0, width, height), Attribute.Default, Attribute.Default); + + DriverAssert.AssertDriverContentsWithFrameAre (expectedDraw, _output); + } + + [Theory] + [SetupFakeDriver] + [InlineData ("界1234", 10, 10, TextDirection.LeftRight_TopBottom, 6, 1, @"界1234")] + [InlineData ("01234", 10, 10, TextDirection.LeftRight_TopBottom, 5, 1, @"01234")] + [InlineData ( + "界1234", + 10, + 10, + TextDirection.TopBottom_LeftRight, + 2, + 5, + """ + 界 + 1 + 2 + 3 + 4 + """)] + [InlineData ( + "01234", + 10, + 10, + TextDirection.TopBottom_LeftRight, + 1, + 5, + """ + 0 + 1 + 2 + 3 + 4 + """)] + [InlineData ("界1234", 3, 3, TextDirection.LeftRight_TopBottom, 3, 1, @"界1")] + [InlineData ("01234", 3, 3, TextDirection.LeftRight_TopBottom, 3, 1, @"012")] + [InlineData ( + "界1234", + 3, + 3, + TextDirection.TopBottom_LeftRight, + 2, + 3, + """ + 界 + 1 + 2 + """)] + [InlineData ( + "01234", + 3, + 3, + TextDirection.TopBottom_LeftRight, + 1, + 3, + """ + 0 + 1 + 2 + """)] + public void FormatAndGetSize_WordWrap_False_Returns_Correct_Size ( + string text, + int width, + int height, + TextDirection direction, + int expectedWidth, + int expectedHeight, + string expectedDraw + ) + { + TextFormatter tf = new () + { + Direction = direction, + ConstrainToSize = new (width, height), + Text = text, + WordWrap = false + }; + Assert.False (tf.WordWrap); + Size size = tf.FormatAndGetSize (); + Assert.Equal (new (expectedWidth, expectedHeight), size); + + tf.Draw (new (0, 0, width, height), Attribute.Default, Attribute.Default); + + DriverAssert.AssertDriverContentsWithFrameAre (expectedDraw, _output); + } + + #endregion +} diff --git a/Tests/UnitTests/UnitTests.csproj b/Tests/UnitTests/UnitTests.csproj new file mode 100644 index 000000000..c37dc7cc9 --- /dev/null +++ b/Tests/UnitTests/UnitTests.csproj @@ -0,0 +1,84 @@ + + + + + + 2.0 + 2.0 + 2.0 + 2.0 + + + false + + true + true + portable + $(DefineConstants);JETBRAINS_ANNOTATIONS;CONTRACTS_FULL + enable + true + true + + + true + $(DefineConstants);DEBUG_IDISPOSABLE + + + true + + + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + PreserveNewest + + + + + + + + + + + + + + + False + + + [UICatalog]* + + + + + + + + + + False + + + \ No newline at end of file diff --git a/UnitTests/UnitTests.csproj.DotSettings b/Tests/UnitTests/UnitTests.csproj.DotSettings similarity index 100% rename from UnitTests/UnitTests.csproj.DotSettings rename to Tests/UnitTests/UnitTests.csproj.DotSettings diff --git a/UnitTests/UnitTests.sln b/Tests/UnitTests/UnitTests.sln similarity index 100% rename from UnitTests/UnitTests.sln rename to Tests/UnitTests/UnitTests.sln diff --git a/UnitTests/View/Adornment/AdornmentSubViewTests.cs b/Tests/UnitTests/View/Adornment/AdornmentSubViewTests.cs similarity index 78% rename from UnitTests/View/Adornment/AdornmentSubViewTests.cs rename to Tests/UnitTests/View/Adornment/AdornmentSubViewTests.cs index 9e1ef4be7..b7de7d31c 100644 --- a/UnitTests/View/Adornment/AdornmentSubViewTests.cs +++ b/Tests/UnitTests/View/Adornment/AdornmentSubViewTests.cs @@ -65,26 +65,4 @@ public class AdornmentSubViewTests (ITestOutputHelper output) Application.Top?.Dispose (); Application.ResetState (ignoreDisposed: true); } - - [Fact] - public void Setting_Thickness_Causes_Adornment_SubView_Layout () - { - var view = new View (); - var subView = new View (); - view.Margin.Add (subView); - view.BeginInit (); - view.EndInit (); - var raised = false; - - subView.SubviewLayout += LayoutStarted; - view.Margin.Thickness = new Thickness (1, 2, 3, 4); - view.Layout (); - Assert.True (raised); - - return; - void LayoutStarted (object sender, LayoutEventArgs e) - { - raised = true; - } - } } diff --git a/Tests/UnitTests/View/Adornment/AdornmentTests.cs b/Tests/UnitTests/View/Adornment/AdornmentTests.cs new file mode 100644 index 000000000..e74d6df39 --- /dev/null +++ b/Tests/UnitTests/View/Adornment/AdornmentTests.cs @@ -0,0 +1,73 @@ +using UnitTests; +using Xunit.Abstractions; + +namespace Terminal.Gui.ViewTests; + +public class AdornmentTests (ITestOutputHelper output) +{ + [Fact] + [SetupFakeDriver] + public void Border_Is_Cleared_After_Margin_Thickness_Change () + { + View view = new () { 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.SetClipToScreen (); + view.Draw (); + + DriverAssert.AssertDriverContentsWithFrameAre ( + @" +╭────╮ +│View│ +", + output + ); + } +} diff --git a/UnitTests/View/Adornment/BorderTests.cs b/Tests/UnitTests/View/Adornment/BorderTests.cs similarity index 94% rename from UnitTests/View/Adornment/BorderTests.cs rename to Tests/UnitTests/View/Adornment/BorderTests.cs index 18a4b8ef6..42cb210b3 100644 --- a/UnitTests/View/Adornment/BorderTests.cs +++ b/Tests/UnitTests/View/Adornment/BorderTests.cs @@ -1,4 +1,6 @@ -using Xunit.Abstractions; +using UnitTests; +using UnitTests; +using Xunit.Abstractions; namespace Terminal.Gui.ViewTests; @@ -33,8 +35,8 @@ public class BorderTests (ITestOutputHelper output) superView.Draw (); var expected = @"─┤A├─"; - TestHelpers.AssertDriverContentsAre (expected, output); - TestHelpers.AssertDriverAttributesAre ("00000", output, null, view.ColorScheme.Normal); + DriverAssert.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverAttributesAre ("00000", output, null, view.ColorScheme.Normal); view.CanFocus = true; view.SetFocus (); @@ -43,7 +45,7 @@ public class BorderTests (ITestOutputHelper output) Assert.Equal (view.GetFocusColor (), view.Border.GetFocusColor ()); Assert.Equal (view.ColorScheme.Focus.Foreground, view.Border.GetFocusColor ().Foreground); Assert.Equal (view.ColorScheme.Normal.Foreground, view.Border.GetNormalColor ().Foreground); - TestHelpers.AssertDriverAttributesAre ("00100", output, null, view.ColorScheme.Normal, view.GetFocusColor ()); + DriverAssert.AssertDriverAttributesAre ("00100", output, null, view.ColorScheme.Normal, view.GetFocusColor ()); } [Fact] @@ -68,8 +70,8 @@ public class BorderTests (ITestOutputHelper output) view.Draw (); var expected = @"─┤A├─"; - TestHelpers.AssertDriverContentsAre (expected, output); - TestHelpers.AssertDriverAttributesAre ("00000", output, null, view.ColorScheme.Normal); + DriverAssert.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverAttributesAre ("00000", output, null, view.ColorScheme.Normal); } [Theory] @@ -201,7 +203,7 @@ public class BorderTests (ITestOutputHelper output) break; } - _ = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + _ = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Application.End (rs); win.Dispose (); } @@ -334,7 +336,7 @@ public class BorderTests (ITestOutputHelper output) break; } - _ = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + _ = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Application.End (rs); win.Dispose (); } @@ -468,7 +470,7 @@ public class BorderTests (ITestOutputHelper output) break; } - _ = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + _ = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Application.End (rs); win.Dispose (); } @@ -523,7 +525,7 @@ public class BorderTests (ITestOutputHelper output) break; } - _ = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + _ = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Application.End (rs); win.Dispose (); } @@ -637,7 +639,7 @@ public class BorderTests (ITestOutputHelper output) break; } - _ = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + _ = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); win.Dispose (); } @@ -742,7 +744,7 @@ public class BorderTests (ITestOutputHelper output) ║└─┘║ ╚═══╝"; - _ = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + _ = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Application.End (rs); top.Dispose (); } @@ -769,7 +771,7 @@ public class BorderTests (ITestOutputHelper output) ║└──────┘║ ╚════════╝"; - _ = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + _ = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Application.End (rs); top.Dispose (); } @@ -791,7 +793,7 @@ public class BorderTests (ITestOutputHelper output) │ │ └─┘"; - _ = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + _ = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); win.Dispose (); } @@ -874,7 +876,7 @@ public class BorderTests (ITestOutputHelper output) superView.EndInit (); superView.Draw (); - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); } @@ -940,6 +942,6 @@ public class BorderTests (ITestOutputHelper output) superView.EndInit (); superView.Draw (); - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); } } diff --git a/UnitTests/View/Adornment/MarginTests.cs b/Tests/UnitTests/View/Adornment/MarginTests.cs similarity index 85% rename from UnitTests/View/Adornment/MarginTests.cs rename to Tests/UnitTests/View/Adornment/MarginTests.cs index 0025d7725..92495c019 100644 --- a/UnitTests/View/Adornment/MarginTests.cs +++ b/Tests/UnitTests/View/Adornment/MarginTests.cs @@ -1,4 +1,6 @@ -using Xunit.Abstractions; +using UnitTests; +using UnitTests; +using Xunit.Abstractions; namespace Terminal.Gui.ViewTests; @@ -30,14 +32,14 @@ public class MarginTests (ITestOutputHelper output) Application.Top.EndInit (); Application.LayoutAndDraw(); - TestHelpers.AssertDriverContentsAre ( + DriverAssert.AssertDriverContentsAre ( @" MMM M M MMM", output ); - TestHelpers.AssertDriverAttributesAre ("0", output, null, Application.Top.GetNormalColor ()); + DriverAssert.AssertDriverAttributesAre ("0", output, null, Application.Top.GetNormalColor ()); Application.ResetState (true); } diff --git a/UnitTests/View/Adornment/PaddingTests.cs b/Tests/UnitTests/View/Adornment/PaddingTests.cs similarity index 82% rename from UnitTests/View/Adornment/PaddingTests.cs rename to Tests/UnitTests/View/Adornment/PaddingTests.cs index 0242bcc1d..f0bbd32af 100644 --- a/UnitTests/View/Adornment/PaddingTests.cs +++ b/Tests/UnitTests/View/Adornment/PaddingTests.cs @@ -1,4 +1,6 @@ -using Xunit.Abstractions; +using UnitTests; +using UnitTests; +using Xunit.Abstractions; namespace Terminal.Gui.ViewTests; @@ -25,13 +27,13 @@ public class PaddingTests (ITestOutputHelper output) view.EndInit (); view.Draw (); - TestHelpers.AssertDriverContentsAre ( + DriverAssert.AssertDriverContentsAre ( @" PPP P P PPP", output ); - TestHelpers.AssertDriverAttributesAre ("0", output, null, view.GetNormalColor ()); + DriverAssert.AssertDriverAttributesAre ("0", output, null, view.GetNormalColor ()); } } diff --git a/Tests/UnitTests/View/Adornment/ShadowStyletests.cs b/Tests/UnitTests/View/Adornment/ShadowStyletests.cs new file mode 100644 index 000000000..76574dfec --- /dev/null +++ b/Tests/UnitTests/View/Adornment/ShadowStyletests.cs @@ -0,0 +1,127 @@ +using UnitTests; +using Xunit.Abstractions; + +namespace Terminal.Gui.ViewTests; + +public class ShadowStyleTests (ITestOutputHelper output) +{ + [Theory] + [InlineData ( + ShadowStyle.None, + """ + 011 + 111 + 111 + """)] + [InlineData ( + ShadowStyle.Transparent, + """ + 031 + 131 + 111 + """)] + [InlineData ( + ShadowStyle.Opaque, + """ + 021 + 221 + 111 + """)] + [SetupFakeDriver] + public void ShadowView_Colors (ShadowStyle style, string expectedAttrs) + { + ((FakeDriver)Application.Driver!).SetBufferSize (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.GetDarkerColor (), bg.GetDarkerColor ()) + }; + + var superView = new Toplevel + { + Height = 3, + Width = 3, + Text = "012ABC!@#", + ColorScheme = new (new Attribute (fg, bg)) + }; + superView.TextFormatter.WordWrap = true; + + View view = new () + { + Width = Dim.Auto (), + Height = Dim.Auto (), + Text = "*", + ShadowStyle = style, + ColorScheme = new (Attribute.Default) + }; + superView.Add (view); + Application.TopLevels.Push (superView); + Application.LayoutAndDraw (true); + DriverAssert.AssertDriverAttributesAre (expectedAttrs, output, Application.Driver, attributes); + Application.ResetState (true); + } + + // Visual tests + [Theory] + [InlineData ( + ShadowStyle.None, + """ + 01#$ + AB#$ + !@#$ + !@#$ + """)] + [InlineData ( + ShadowStyle.Opaque, + """ + 01▖$ + AB▌$ + ▝▀▘$ + !@#$ + """)] + [InlineData ( + ShadowStyle.Transparent, + """ + 01#$ + AB#$ + !@#$ + !@#$ + """)] + [SetupFakeDriver] + public void Visual_Test (ShadowStyle style, string expected) + { + ((FakeDriver)Application.Driver!).SetBufferSize (5, 5); + + var superView = new Toplevel + { + 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.TopLevels.Push (superView); + Application.LayoutAndDraw (true); + + DriverAssert.AssertDriverContentsWithFrameAre (expected, output); + view.Dispose (); + Application.ResetState (true); + } +} diff --git a/UnitTests/View/ArrangementTests.cs b/Tests/UnitTests/View/ArrangementTests.cs similarity index 100% rename from UnitTests/View/ArrangementTests.cs rename to Tests/UnitTests/View/ArrangementTests.cs diff --git a/UnitTests/View/ColorSchemeTests.cs b/Tests/UnitTests/View/ColorSchemeTests.cs similarity index 100% rename from UnitTests/View/ColorSchemeTests.cs rename to Tests/UnitTests/View/ColorSchemeTests.cs diff --git a/UnitTests/View/DiagnosticsTests.cs b/Tests/UnitTests/View/DiagnosticsTests.cs similarity index 100% rename from UnitTests/View/DiagnosticsTests.cs rename to Tests/UnitTests/View/DiagnosticsTests.cs diff --git a/UnitTests/View/Draw/AllViewsDrawTests.cs b/Tests/UnitTests/View/Draw/AllViewsDrawTests.cs similarity index 96% rename from UnitTests/View/Draw/AllViewsDrawTests.cs rename to Tests/UnitTests/View/Draw/AllViewsDrawTests.cs index 64d6c543e..9cbac00b3 100644 --- a/UnitTests/View/Draw/AllViewsDrawTests.cs +++ b/Tests/UnitTests/View/Draw/AllViewsDrawTests.cs @@ -1,4 +1,6 @@ -using Xunit.Abstractions; +using UnitTests; +using UnitTests; +using Xunit.Abstractions; namespace Terminal.Gui.LayoutTests; diff --git a/UnitTests/View/Draw/ClearViewportTests.cs b/Tests/UnitTests/View/Draw/ClearViewportTests.cs similarity index 93% rename from UnitTests/View/Draw/ClearViewportTests.cs rename to Tests/UnitTests/View/Draw/ClearViewportTests.cs index b95f85fec..236e66506 100644 --- a/UnitTests/View/Draw/ClearViewportTests.cs +++ b/Tests/UnitTests/View/Draw/ClearViewportTests.cs @@ -1,5 +1,7 @@ #nullable enable using Moq; +using UnitTests; +using UnitTests; using Xunit.Abstractions; namespace Terminal.Gui.ViewTests; @@ -117,7 +119,7 @@ public class ClearViewportTests (ITestOutputHelper _output) superView.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌─┐ │X│ @@ -127,7 +129,7 @@ public class ClearViewportTests (ITestOutputHelper _output) // On Draw exit the view is excluded from the clip, so this will do nothing. view.ClearViewport (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌─┐ │X│ @@ -138,7 +140,7 @@ public class ClearViewportTests (ITestOutputHelper _output) view.ClearViewport (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌─┐ │ │ @@ -167,7 +169,7 @@ public class ClearViewportTests (ITestOutputHelper _output) superView.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌─┐ │X│ @@ -176,7 +178,7 @@ public class ClearViewportTests (ITestOutputHelper _output) View.SetClipToScreen (); view.ClearViewport (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌─┐ │ │ @@ -226,7 +228,7 @@ public class ClearViewportTests (ITestOutputHelper _output) " ; - Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, _output); + Rectangle pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, _output); Assert.Equal (new (0, 0, 20, 10), pos); view.FillRect (view.Viewport); @@ -245,7 +247,7 @@ public class ClearViewportTests (ITestOutputHelper _output) " ; - pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, _output); + pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, _output); top.Dispose (); } @@ -291,7 +293,7 @@ public class ClearViewportTests (ITestOutputHelper _output) " ; - Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, _output); + Rectangle pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, _output); Assert.Equal (new (0, 0, 20, 10), pos); view.FillRect (view.Viewport); @@ -309,7 +311,7 @@ public class ClearViewportTests (ITestOutputHelper _output) └──────────────────┘ "; - pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, _output); + pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, _output); top.Dispose (); } @@ -350,7 +352,7 @@ public class ClearViewportTests (ITestOutputHelper _output) Assert.Equal (new (0, 0, 20, 1), v.Frame); } - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" cccccccccccccccccccc", _output @@ -365,7 +367,7 @@ cccccccccccccccccccc", if (label) { - TestHelpers.AssertDriverAttributesAre ( + DriverAssert.AssertDriverAttributesAre ( @" 111111111111111111110 111111111111111111110", @@ -376,7 +378,7 @@ cccccccccccccccccccc", } else { - TestHelpers.AssertDriverAttributesAre ( + DriverAssert.AssertDriverAttributesAre ( @" 222222222222222222220 111111111111111111110", @@ -395,7 +397,7 @@ cccccccccccccccccccc", Assert.True (v.HasFocus); Application.LayoutAndDraw (); - TestHelpers.AssertDriverAttributesAre ( + DriverAssert.AssertDriverAttributesAre ( @" 222222222222222222220 111111111111111111110", diff --git a/UnitTests/View/Draw/ClipTests.cs b/Tests/UnitTests/View/Draw/ClipTests.cs similarity index 82% rename from UnitTests/View/Draw/ClipTests.cs rename to Tests/UnitTests/View/Draw/ClipTests.cs index f09eb492b..7eccc918d 100644 --- a/UnitTests/View/Draw/ClipTests.cs +++ b/Tests/UnitTests/View/Draw/ClipTests.cs @@ -1,5 +1,6 @@ #nullable enable using System.Text; +using UnitTests; using Xunit.Abstractions; namespace Terminal.Gui.ViewTests; @@ -82,86 +83,86 @@ public class ClipTests (ITestOutputHelper _output) superView.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ( - @" + DriverAssert.AssertDriverContentsWithFrameAre ( + @" ┌─┐ │X│ └─┘", - _output); + _output); Rectangle toFill = new (x, y, width, height); View.SetClipToScreen (); view.FillRect (toFill); - TestHelpers.AssertDriverContentsWithFrameAre ( - @" + DriverAssert.AssertDriverContentsWithFrameAre ( + @" ┌─┐ │ │ └─┘", - _output); + _output); // Now try to clear beyond Viewport (invalid; clipping should prevent) superView.SetNeedsDraw (); superView.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ( - @" + DriverAssert.AssertDriverContentsWithFrameAre ( + @" ┌─┐ │X│ └─┘", - _output); + _output); toFill = new (-width, -height, width, height); view.FillRect (toFill); - TestHelpers.AssertDriverContentsWithFrameAre ( - @" + DriverAssert.AssertDriverContentsWithFrameAre ( + @" ┌─┐ │X│ └─┘", - _output); + _output); // Now try to clear beyond Viewport (valid) superView.SetNeedsDraw (); superView.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ( - @" + DriverAssert.AssertDriverContentsWithFrameAre ( + @" ┌─┐ │X│ └─┘", - _output); + _output); toFill = new (-1, -1, width + 1, height + 1); View.SetClipToScreen (); view.FillRect (toFill); - TestHelpers.AssertDriverContentsWithFrameAre ( - @" + DriverAssert.AssertDriverContentsWithFrameAre ( + @" ┌─┐ │ │ └─┘", - _output); + _output); // Now clear too much size superView.SetNeedsDraw (); superView.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ( - @" + DriverAssert.AssertDriverContentsWithFrameAre ( + @" ┌─┐ │X│ └─┘", - _output); + _output); toFill = new (0, 0, width * 2, height * 2); View.SetClipToScreen (); view.FillRect (toFill); - TestHelpers.AssertDriverContentsWithFrameAre ( - @" + DriverAssert.AssertDriverContentsWithFrameAre ( + @" ┌─┐ │ │ └─┘", - _output); + _output); } // TODO: Simplify this test to just use AddRune directly @@ -200,7 +201,7 @@ public class ClipTests (ITestOutputHelper _output) │これは広いルーンラインです。 """; - TestHelpers.AssertDriverContentsWithFrameAre (expectedOutput, _output); + DriverAssert.AssertDriverContentsWithFrameAre (expectedOutput, _output); var view = new View { @@ -228,7 +229,7 @@ public class ClipTests (ITestOutputHelper _output) │�│0123456789│�ンラインです。 """; - TestHelpers.AssertDriverContentsWithFrameAre (expectedOutput, _output); + DriverAssert.AssertDriverContentsWithFrameAre (expectedOutput, _output); } // TODO: Add more AddRune tests to cover all the cases where wide runes are clipped diff --git a/UnitTests/View/Draw/DrawEventTests.cs b/Tests/UnitTests/View/Draw/DrawEventTests.cs similarity index 88% rename from UnitTests/View/Draw/DrawEventTests.cs rename to Tests/UnitTests/View/Draw/DrawEventTests.cs index 7b1bf2c0e..dc6bfc160 100644 --- a/UnitTests/View/Draw/DrawEventTests.cs +++ b/Tests/UnitTests/View/Draw/DrawEventTests.cs @@ -1,13 +1,11 @@ #nullable enable -using System.Text; -using Xunit.Abstractions; +using UnitTests; namespace Terminal.Gui.ViewTests; [Trait ("Category", "Output")] -public class DrawEventTests (ITestOutputHelper _output) +public class DrawEventTests { - [Fact] [AutoInitShutdown] public void DrawContentComplete_Event_Is_Always_Called () diff --git a/UnitTests/View/Draw/DrawTests.cs b/Tests/UnitTests/View/Draw/DrawTests.cs similarity index 92% rename from UnitTests/View/Draw/DrawTests.cs rename to Tests/UnitTests/View/Draw/DrawTests.cs index 7cb246168..eed5c3532 100644 --- a/UnitTests/View/Draw/DrawTests.cs +++ b/Tests/UnitTests/View/Draw/DrawTests.cs @@ -1,6 +1,6 @@ #nullable enable using System.Text; -using Microsoft.VisualStudio.TestPlatform.Utilities; +using UnitTests; using Xunit.Abstractions; namespace Terminal.Gui.ViewTests; @@ -41,9 +41,9 @@ public class DrawTests (ITestOutputHelper _output) │豈 │ └────────┘ """; - TestHelpers.AssertDriverContentsWithFrameAre (expectedOutput, _output); + DriverAssert.AssertDriverContentsWithFrameAre (expectedOutput, _output); - TestHelpers.AssertDriverContentsAre (expectedOutput, _output); + DriverAssert.AssertDriverContentsAre (expectedOutput, _output); // This test has nothing to do with color - removing as it is not relevant and fragile top.Dispose (); @@ -80,7 +80,7 @@ public class DrawTests (ITestOutputHelper _output) ((FakeDriver)Application.Driver!).SetBufferSize (7, 7); Application.RunIteration (ref rs); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( """ Test @@ -94,7 +94,7 @@ public class DrawTests (ITestOutputHelper _output) _output ); - TestHelpers.AssertDriverAttributesAre ( + DriverAssert.AssertDriverAttributesAre ( """ 000000 @@ -127,7 +127,7 @@ public class DrawTests (ITestOutputHelper _output) Assert.True (view.NeedsDraw); view.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( """ ┌┐ @@ -152,7 +152,7 @@ public class DrawTests (ITestOutputHelper _output) view.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ("──", _output); + DriverAssert.AssertDriverContentsWithFrameAre ("──", _output); } [Fact] @@ -170,7 +170,7 @@ public class DrawTests (ITestOutputHelper _output) view.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( """ │ @@ -195,7 +195,7 @@ public class DrawTests (ITestOutputHelper _output) view.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( """ │ @@ -221,7 +221,7 @@ public class DrawTests (ITestOutputHelper _output) view.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( "││", _output ); @@ -291,7 +291,7 @@ public class DrawTests (ITestOutputHelper _output) var rs = Application.Begin (top); top.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( """ 0s @@ -306,7 +306,7 @@ public class DrawTests (ITestOutputHelper _output) content.X = -1; Application.LayoutAndDraw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( """ s @@ -320,13 +320,13 @@ public class DrawTests (ITestOutputHelper _output) content.X = -2; Application.LayoutAndDraw (); - TestHelpers.AssertDriverContentsWithFrameAre (@"", _output); + DriverAssert.AssertDriverContentsWithFrameAre (@"", _output); content.X = 0; content.Y = -1; Application.LayoutAndDraw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( """ 1u @@ -341,7 +341,7 @@ public class DrawTests (ITestOutputHelper _output) content.Y = -6; Application.LayoutAndDraw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( """ 6w @@ -356,7 +356,7 @@ public class DrawTests (ITestOutputHelper _output) content.Y = -19; Application.LayoutAndDraw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( """ 9 @@ -366,12 +366,12 @@ public class DrawTests (ITestOutputHelper _output) content.Y = -20; Application.LayoutAndDraw (); - TestHelpers.AssertDriverContentsWithFrameAre ("", _output); + DriverAssert.AssertDriverContentsWithFrameAre ("", _output); content.X = -2; content.Y = 0; Application.LayoutAndDraw (); - TestHelpers.AssertDriverContentsWithFrameAre ("", _output); + DriverAssert.AssertDriverContentsWithFrameAre ("", _output); top.Dispose (); } @@ -411,7 +411,7 @@ public class DrawTests (ITestOutputHelper _output) Application.Begin (top); Application.LayoutAndDraw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( """ 01234 @@ -423,7 +423,7 @@ public class DrawTests (ITestOutputHelper _output) content.X = -1; Application.LayoutAndDraw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( """ 12345 @@ -435,7 +435,7 @@ public class DrawTests (ITestOutputHelper _output) content.Y = -1; Application.LayoutAndDraw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( """ ubVie @@ -445,12 +445,12 @@ public class DrawTests (ITestOutputHelper _output) content.Y = -2; Application.LayoutAndDraw (); - TestHelpers.AssertDriverContentsWithFrameAre ("", _output); + DriverAssert.AssertDriverContentsWithFrameAre ("", _output); content.X = -20; content.Y = 0; Application.LayoutAndDraw (); - TestHelpers.AssertDriverContentsWithFrameAre ("", _output); + DriverAssert.AssertDriverContentsWithFrameAre ("", _output); top.Dispose (); return; @@ -498,7 +498,7 @@ public class DrawTests (ITestOutputHelper _output) Application.Begin (top); Application.LayoutAndDraw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( """ 0s @@ -513,7 +513,7 @@ public class DrawTests (ITestOutputHelper _output) content.X = -1; Application.LayoutAndDraw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( """ s @@ -527,13 +527,13 @@ public class DrawTests (ITestOutputHelper _output) content.X = -2; Application.LayoutAndDraw (); - TestHelpers.AssertDriverContentsWithFrameAre (@"", _output); + DriverAssert.AssertDriverContentsWithFrameAre (@"", _output); content.X = 0; content.Y = -1; Application.LayoutAndDraw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( """ 1u @@ -548,7 +548,7 @@ public class DrawTests (ITestOutputHelper _output) content.Y = -6; Application.LayoutAndDraw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( """ 6w @@ -563,7 +563,7 @@ public class DrawTests (ITestOutputHelper _output) content.Y = -19; Application.LayoutAndDraw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( """ 9 @@ -573,12 +573,12 @@ public class DrawTests (ITestOutputHelper _output) content.Y = -20; Application.LayoutAndDraw (); - TestHelpers.AssertDriverContentsWithFrameAre ("", _output); + DriverAssert.AssertDriverContentsWithFrameAre ("", _output); content.X = -2; content.Y = 0; Application.LayoutAndDraw (); - TestHelpers.AssertDriverContentsWithFrameAre ("", _output); + DriverAssert.AssertDriverContentsWithFrameAre ("", _output); top.Dispose (); } @@ -591,7 +591,7 @@ public class DrawTests (ITestOutputHelper _output) var view = new View { Width = 10, Height = 1 }; view.DrawHotString (expected, Attribute.Default, Attribute.Default); - TestHelpers.AssertDriverContentsWithFrameAre (expected, _output); + DriverAssert.AssertDriverContentsWithFrameAre (expected, _output); } // TODO: The tests below that use Label should use View instead. @@ -626,9 +626,9 @@ public class DrawTests (ITestOutputHelper _output) │𝔹 │ └────────┘ """; - TestHelpers.AssertDriverContentsWithFrameAre (expected, _output); + DriverAssert.AssertDriverContentsWithFrameAre (expected, _output); - TestHelpers.AssertDriverContentsAre (expected, _output); + DriverAssert.AssertDriverContentsAre (expected, _output); top.Dispose (); // This test has nothing to do with color - removing as it is not relevant and fragile @@ -688,7 +688,7 @@ public class DrawTests (ITestOutputHelper _output) RunState runState = Application.Begin (top); Application.RunIteration (ref runState); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" At 0,0 @@ -705,7 +705,7 @@ At 0,0 //Application.Refresh(); top.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" At 0,0 @@ -737,7 +737,7 @@ At 0,0 top.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" At 0,0 @@ -757,7 +757,7 @@ At 0,0 View.SetClipToScreen (); top.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" At 0,0 @@ -789,7 +789,7 @@ At 0,0 RunState runState = Application.Begin (top); Application.RunIteration (ref runState); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" At 0,0 @@ -805,7 +805,7 @@ At 0,0 Assert.Equal (new (0, 0, 10, 1), view._needsDrawRect); top.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" At 0,0 A text wit" @@ -836,7 +836,7 @@ At 0,0 top.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" At 0,0 @@ -857,7 +857,7 @@ At 0,0 top.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" At 0,0 A text wit" diff --git a/Tests/UnitTests/View/Draw/NeedsDrawTests.cs b/Tests/UnitTests/View/Draw/NeedsDrawTests.cs new file mode 100644 index 000000000..21a09589f --- /dev/null +++ b/Tests/UnitTests/View/Draw/NeedsDrawTests.cs @@ -0,0 +1,67 @@ +#nullable enable +using UnitTests; + +namespace Terminal.Gui.ViewTests; + +[Trait ("Category", "Output")] +public class NeedsDrawTests () +{ + [Fact] + [AutoInitShutdown] + public void Frame_Set_After_Initialize_Update_NeededDisplay () + { + var frame = new FrameView (); + + var label = new Label + { + ColorScheme = Colors.ColorSchemes ["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; + + Toplevel top = new (); + + top.Add (frame); + + RunState runState = Application.Begin (top); + + 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 (runState); + top.Dispose (); + } +} diff --git a/UnitTests/View/Draw/TransparentTests.cs b/Tests/UnitTests/View/Draw/TransparentTests.cs similarity index 95% rename from UnitTests/View/Draw/TransparentTests.cs rename to Tests/UnitTests/View/Draw/TransparentTests.cs index ce8a70c64..81747914a 100644 --- a/UnitTests/View/Draw/TransparentTests.cs +++ b/Tests/UnitTests/View/Draw/TransparentTests.cs @@ -1,5 +1,7 @@ #nullable enable using System.Text; +using UnitTests; +using UnitTests; using Xunit.Abstractions; namespace Terminal.Gui.ViewTests; @@ -42,7 +44,7 @@ public class TransparentTests (ITestOutputHelper _output) super.Layout (); super.Draw (); - _ = TestHelpers.AssertDriverContentsWithFrameAre ( + _ = DriverAssert.AssertDriverContentsWithFrameAre ( @" ░░░░░░░░░░░░░░░░░░░░ ░┌─────────────┐░░░░ @@ -96,7 +98,7 @@ public class TransparentTests (ITestOutputHelper _output) super.Layout (); super.Draw (); - _ = TestHelpers.AssertDriverContentsWithFrameAre ( + _ = DriverAssert.AssertDriverContentsWithFrameAre ( @" ░░░░░░░░░░░░░░░░░░░░ ░┌─────────────┐░░░░ diff --git a/UnitTests/View/InitTests.cs b/Tests/UnitTests/View/InitTests.cs similarity index 100% rename from UnitTests/View/InitTests.cs rename to Tests/UnitTests/View/InitTests.cs diff --git a/UnitTests/View/Keyboard/HotKeyTests.cs b/Tests/UnitTests/View/Keyboard/HotKeyTests.cs similarity index 100% rename from UnitTests/View/Keyboard/HotKeyTests.cs rename to Tests/UnitTests/View/Keyboard/HotKeyTests.cs diff --git a/UnitTests/View/Keyboard/KeyBindingsTests.cs b/Tests/UnitTests/View/Keyboard/KeyBindingsTests.cs similarity index 98% rename from UnitTests/View/Keyboard/KeyBindingsTests.cs rename to Tests/UnitTests/View/Keyboard/KeyBindingsTests.cs index a07730b7a..64685a9d6 100644 --- a/UnitTests/View/Keyboard/KeyBindingsTests.cs +++ b/Tests/UnitTests/View/Keyboard/KeyBindingsTests.cs @@ -1,4 +1,5 @@ -using Xunit.Abstractions; +using UnitTests; +using Xunit.Abstractions; namespace Terminal.Gui.ViewTests; diff --git a/UnitTests/View/Keyboard/KeyboardEventTests.cs b/Tests/UnitTests/View/Keyboard/KeyboardEventTests.cs similarity index 99% rename from UnitTests/View/Keyboard/KeyboardEventTests.cs rename to Tests/UnitTests/View/Keyboard/KeyboardEventTests.cs index 7cbbcaa8f..1451a1321 100644 --- a/UnitTests/View/Keyboard/KeyboardEventTests.cs +++ b/Tests/UnitTests/View/Keyboard/KeyboardEventTests.cs @@ -1,4 +1,6 @@ -using Xunit.Abstractions; +using UnitTests; +using UnitTests; +using Xunit.Abstractions; // Alias Console to MockConsole so we don't accidentally use Console diff --git a/Tests/UnitTests/View/Layout/Dim.FillTests.cs b/Tests/UnitTests/View/Layout/Dim.FillTests.cs new file mode 100644 index 000000000..e09033e8c --- /dev/null +++ b/Tests/UnitTests/View/Layout/Dim.FillTests.cs @@ -0,0 +1,28 @@ +using UnitTests; +using Xunit.Abstractions; + +namespace Terminal.Gui.LayoutTests; + +public class DimFillTests (ITestOutputHelper output) +{ + private readonly ITestOutputHelper _output = output; + + [Fact] + [AutoInitShutdown] + public void DimFill_SizedCorrectly () + { + var view = new View { Width = Dim.Fill (), Height = Dim.Fill (), BorderStyle = LineStyle.Single }; + var top = new Toplevel (); + top.Add (view); + RunState rs = Application.Begin (top); + ((FakeDriver)Application.Driver!).SetBufferSize (32, 5); + + top.Layout (); + + //view.SetRelativeLayout (new (0, 0, 32, 5)); + Assert.Equal (32, view.Frame.Width); + Assert.Equal (5, view.Frame.Height); + top.Dispose (); + } + +} diff --git a/UnitTests/View/Layout/Dim.Tests.cs b/Tests/UnitTests/View/Layout/Dim.Tests.cs similarity index 57% rename from UnitTests/View/Layout/Dim.Tests.cs rename to Tests/UnitTests/View/Layout/Dim.Tests.cs index 9734de3c8..5b1698371 100644 --- a/UnitTests/View/Layout/Dim.Tests.cs +++ b/Tests/UnitTests/View/Layout/Dim.Tests.cs @@ -1,5 +1,6 @@ using System.Globalization; using System.Text; +using UnitTests; using Xunit.Abstractions; using static Terminal.Gui.Dim; @@ -20,88 +21,6 @@ public class DimTests Thread.CurrentThread.CurrentUICulture = culture; } - [Fact] - public void DimAbsolute_Calculate_ReturnsCorrectValue () - { - var dim = new DimAbsolute (10); - int result = dim.Calculate (0, 100, null, Dimension.None); - Assert.Equal (10, result); - } - - // TODO: This actually a SetRelativeLayout/LayoutSubViews test and should be moved - // TODO: A new test that calls SetRelativeLayout directly is needed. - [Fact] - [TestRespondersDisposed] - public void Dim_Validation_Do_Not_Throws_If_NewValue_Is_DimAbsolute_And_OldValue_Is_Null () - { - var t = new View { Width = 80, Height = 25, Text = "top" }; - - var w = new Window - { - X = 1, - Y = 2, - Width = 4, - Height = 5, - Title = "w" - }; - t.Add (w); - t.LayoutSubviews (); - - Assert.Equal (3, w.Width = 3); - Assert.Equal (4, w.Height = 4); - t.Dispose (); - } - - [Fact] - public void DimHeight_Set_To_Null_Throws () - { - Dim dim = Height (null); - Assert.Throws (() => dim.ToString ()); - } - - [Fact] - [TestRespondersDisposed] - public void DimHeight_SetsValue () - { - var testVal = Rectangle.Empty; - var testValview = new View { Frame = testVal }; - Dim dim = Height (testValview); - Assert.Equal ($"View(Height,View(){testVal})", dim.ToString ()); - testValview.Dispose (); - - testVal = new (1, 2, 3, 4); - testValview = new () { Frame = testVal }; - dim = Height (testValview); - Assert.Equal ($"View(Height,View(){testVal})", dim.ToString ()); - testValview.Dispose (); - } - - [Fact] - [TestRespondersDisposed] - public void Internal_Tests () - { - var dimFactor = new DimPercent (10); - Assert.Equal (10, dimFactor.GetAnchor (100)); - - var dimAbsolute = new DimAbsolute (10); - Assert.Equal (10, dimAbsolute.GetAnchor (0)); - - var dimFill = new DimFill (1); - Assert.Equal (99, dimFill.GetAnchor (100)); - - var dimCombine = new DimCombine (AddOrSubtract.Add, dimFactor, dimAbsolute); - Assert.Equal (dimCombine.Left, dimFactor); - Assert.Equal (dimCombine.Right, dimAbsolute); - Assert.Equal (20, dimCombine.GetAnchor (100)); - - var view = new View { Frame = new (20, 10, 20, 1) }; - var dimViewHeight = new DimView (view, Dimension.Height); - Assert.Equal (1, dimViewHeight.GetAnchor (0)); - var dimViewWidth = new DimView (view, Dimension.Width); - Assert.Equal (20, dimViewWidth.GetAnchor (0)); - - view.Dispose (); - } // TODO: This actually a SetRelativeLayout/LayoutSubViews test and should be moved // TODO: A new test that calls SetRelativeLayout directly is needed. @@ -334,168 +253,4 @@ public class DimTests Application.Run (t); t.Dispose (); } - - // TODO: This actually a SetRelativeLayout/LayoutSubViews test and should be moved - // TODO: A new test that calls SetRelativeLayout directly is needed. - [Fact] - [TestRespondersDisposed] - public void Referencing_SuperView_Does_Not_Throw () - { - var super = new View { Width = 10, Height = 10, Text = "super" }; - - var view = new View - { - Width = Width (super), // this is allowed - Height = Height (super), // this is allowed - Text = "view" - }; - - super.Add (view); - super.BeginInit (); - super.EndInit (); - - Exception exception = Record.Exception (super.LayoutSubviews); - Assert.Null (exception); - super.Dispose (); - } - - [Fact] - public void DimSized_Equals () - { - var n1 = 0; - var n2 = 0; - Dim dim1 = Absolute (n1); - Dim dim2 = Absolute (n2); - Assert.Equal (dim1, dim2); - - n1 = n2 = 1; - dim1 = Absolute (n1); - dim2 = Absolute (n2); - Assert.Equal (dim1, dim2); - - n1 = n2 = -1; - dim1 = Absolute (n1); - dim2 = Absolute (n2); - Assert.Equal (dim1, dim2); - - n1 = 0; - n2 = 1; - dim1 = Absolute (n1); - dim2 = Absolute (n2); - Assert.NotEqual (dim1, dim2); - } - - [Fact] - public void DimSized_SetsValue () - { - Dim dim = Absolute (0); - Assert.Equal ("Absolute(0)", dim.ToString ()); - - var testVal = 5; - dim = Absolute (testVal); - Assert.Equal ($"Absolute({testVal})", dim.ToString ()); - - testVal = -1; - dim = Absolute (testVal); - Assert.Equal ($"Absolute({testVal})", dim.ToString ()); - } - - // TODO: This actually a SetRelativeLayout/LayoutSubViews test and should be moved - // TODO: A new test that calls SetRelativeLayout directly is needed. - [Fact] - [TestRespondersDisposed] - public void Validation_Does_Not_Throw_If_NewValue_Is_DimAbsolute_And_OldValue_Is_Null () - { - var t = new View { Width = 80, Height = 25, Text = "top" }; - - var w = new Window - { - X = 1, - Y = 2, - Width = 4, - Height = 5, - Title = "w" - }; - t.Add (w); - t.LayoutSubviews (); - - Assert.Equal (3, w.Width = 3); - Assert.Equal (4, w.Height = 4); - t.Dispose (); - } - - [Fact] - [TestRespondersDisposed] - public void DimWidth_Equals () - { - var testRect1 = Rectangle.Empty; - var view1 = new View { Frame = testRect1 }; - var testRect2 = Rectangle.Empty; - var view2 = new View { Frame = testRect2 }; - - Dim dim1 = Width (view1); - Dim dim2 = Width (view1); - - // FIXED: Dim.Width should support Equals() and this should change to Equal. - Assert.Equal (dim1, dim2); - - dim2 = Width (view2); - Assert.NotEqual (dim1, dim2); - - testRect1 = new (0, 1, 2, 3); - view1 = new () { Frame = testRect1 }; - testRect2 = new (0, 1, 2, 3); - dim1 = Width (view1); - dim2 = Width (view1); - - // FIXED: Dim.Width should support Equals() and this should change to Equal. - Assert.Equal (dim1, dim2); - - testRect1 = new (0, -1, 2, 3); - view1 = new () { Frame = testRect1 }; - testRect2 = new (0, -1, 2, 3); - dim1 = Width (view1); - dim2 = Width (view1); - - // FIXED: Dim.Width should support Equals() and this should change to Equal. - Assert.Equal (dim1, dim2); - - testRect1 = new (0, -1, 2, 3); - view1 = new () { Frame = testRect1 }; - testRect2 = Rectangle.Empty; - view2 = new () { Frame = testRect2 }; - dim1 = Width (view1); - dim2 = Width (view2); - Assert.NotEqual (dim1, dim2); -#if DEBUG_IDISPOSABLE - - // HACK: Force clean up of Responders to avoid having to Dispose all the Views created above. - View.Instances.Clear (); - Assert.Empty (View.Instances); -#endif - } - - [Fact] - public void DimWidth_Set_To_Null_Throws () - { - Dim dim = Width (null); - Assert.Throws (() => dim.ToString ()); - } - - [Fact] - [TestRespondersDisposed] - public void DimWidth_SetsValue () - { - var testVal = Rectangle.Empty; - var testValView = new View { Frame = testVal }; - Dim dim = Width (testValView); - Assert.Equal ($"View(Width,View(){testVal})", dim.ToString ()); - testValView.Dispose (); - - testVal = new (1, 2, 3, 4); - testValView = new () { Frame = testVal }; - dim = Width (testValView); - Assert.Equal ($"View(Width,View(){testVal})", dim.ToString ()); - testValView.Dispose (); - } } diff --git a/UnitTests/View/Layout/LayoutTests.cs b/Tests/UnitTests/View/Layout/LayoutTests.cs similarity index 95% rename from UnitTests/View/Layout/LayoutTests.cs rename to Tests/UnitTests/View/Layout/LayoutTests.cs index 1b4110553..46b088394 100644 --- a/UnitTests/View/Layout/LayoutTests.cs +++ b/Tests/UnitTests/View/Layout/LayoutTests.cs @@ -1,4 +1,6 @@ -using Xunit.Abstractions; +using UnitTests; +using UnitTests; +using Xunit.Abstractions; namespace Terminal.Gui.LayoutTests; diff --git a/Tests/UnitTests/View/Layout/Pos.AnchorEndTests.cs b/Tests/UnitTests/View/Layout/Pos.AnchorEndTests.cs new file mode 100644 index 000000000..75f79af9c --- /dev/null +++ b/Tests/UnitTests/View/Layout/Pos.AnchorEndTests.cs @@ -0,0 +1,76 @@ +using UnitTests; +using UnitTests; +using Xunit.Abstractions; +using static Terminal.Gui.Dim; +using static Terminal.Gui.Pos; + +namespace Terminal.Gui.LayoutTests; + +public class PosAnchorEndTests (ITestOutputHelper output) +{ + + + // TODO: This actually a SetRelativeLayout/LayoutSubViews test and should be moved + // TODO: A new test that calls SetRelativeLayout directly is needed. + [Fact] + [AutoInitShutdown] + public void PosAnchorEnd_Equal_Inside_Window () + { + var viewWidth = 10; + var viewHeight = 1; + + var tv = new TextView + { + X = Pos.AnchorEnd (viewWidth), Y = Pos.AnchorEnd (viewHeight), Width = viewWidth, Height = viewHeight + }; + + var win = new Window (); + + win.Add (tv); + + Toplevel top = new (); + top.Add (win); + RunState rs = Application.Begin (top); + + Assert.Equal (new (0, 0, 80, 25), top.Frame); + Assert.Equal (new (0, 0, 80, 25), win.Frame); + Assert.Equal (new (68, 22, 10, 1), tv.Frame); + Application.End (rs); + top.Dispose (); + } + + //// TODO: This actually a SetRelativeLayout/LayoutSubViews test and should be moved + //// TODO: A new test that calls SetRelativeLayout directly is needed. + //[Fact] + //[AutoInitShutdown] + //public void PosAnchorEnd_Equal_Inside_Window_With_MenuBar_And_StatusBar_On_Toplevel () + //{ + // var viewWidth = 10; + // var viewHeight = 1; + + // var tv = new TextView + // { + // X = Pos.AnchorEnd (viewWidth), Y = Pos.AnchorEnd (viewHeight), Width = viewWidth, Height = viewHeight + // }; + + // var win = new Window (); + + // win.Add (tv); + + // var menu = new MenuBar (); + // var status = new StatusBar (); + // Toplevel top = new (); + // top.Add (win, menu, status); + // RunState rs = Application.Begin (top); + + // Assert.Equal (new (0, 0, 80, 25), top.Frame); + // Assert.Equal (new (0, 0, 80, 1), menu.Frame); + // Assert.Equal (new (0, 24, 80, 1), status.Frame); + // Assert.Equal (new (0, 1, 80, 23), win.Frame); + // Assert.Equal (new (68, 20, 10, 1), tv.Frame); + + // Application.End (rs); + // top.Dispose (); + //} + +} diff --git a/UnitTests/View/Layout/Pos.CenterTests.cs b/Tests/UnitTests/View/Layout/Pos.CenterTests.cs similarity index 82% rename from UnitTests/View/Layout/Pos.CenterTests.cs rename to Tests/UnitTests/View/Layout/Pos.CenterTests.cs index a27dc5e22..26b834a22 100644 --- a/UnitTests/View/Layout/Pos.CenterTests.cs +++ b/Tests/UnitTests/View/Layout/Pos.CenterTests.cs @@ -1,4 +1,6 @@ -using Xunit.Abstractions; +using UnitTests; +using UnitTests; +using Xunit.Abstractions; using static Terminal.Gui.Dim; using static Terminal.Gui.Pos; @@ -8,65 +10,6 @@ public class PosCenterTests (ITestOutputHelper output) { private readonly ITestOutputHelper _output = output; - [Fact] - public void PosCenter_Constructor () - { - var posCenter = new PosCenter (); - Assert.NotNull (posCenter); - } - - [Fact] - public void PosCenter_ToString () - { - var posCenter = new PosCenter (); - var expectedString = "Center"; - - Assert.Equal (expectedString, posCenter.ToString ()); - } - - [Fact] - public void PosCenter_GetAnchor () - { - var posCenter = new PosCenter (); - var width = 50; - int expectedAnchor = width / 2; - - Assert.Equal (expectedAnchor, posCenter.GetAnchor (width)); - } - - [Fact] - public void PosCenter_CreatesCorrectInstance () - { - Pos pos = Center (); - Assert.IsType (pos); - } - - [Theory] - [InlineData (10, 2, 4)] - [InlineData (10, 10, 0)] - [InlineData (10, 11, 0)] - [InlineData (10, 12, -1)] - [InlineData (19, 20, 0)] - public void PosCenter_Calculate_ReturnsExpectedValue (int superviewDimension, int width, int expectedX) - { - var posCenter = new PosCenter (); - int result = posCenter.Calculate (superviewDimension, new DimAbsolute (width), null!, Dimension.Width); - Assert.Equal (expectedX, result); - } - - - [Fact] - public void PosCenter_Bigger_Than_SuperView () - { - var superView = new View { Width = 10, Height = 10 }; - var view = new View { X = Center (), Y = Center (), Width = 20, Height = 20 }; - superView.Add (view); - superView.LayoutSubviews (); - - Assert.Equal (-5, view.Frame.Left); - Assert.Equal (-5, view.Frame.Top); - } - [Theory] [AutoInitShutdown] [InlineData (1)] @@ -209,7 +152,7 @@ public class PosCenterTests (ITestOutputHelper output) break; } - _ = TestHelpers.AssertDriverContentsWithFrameAre (expected, _output); + _ = DriverAssert.AssertDriverContentsWithFrameAre (expected, _output); Application.End (rs); win.Dispose (); } @@ -379,7 +322,7 @@ public class PosCenterTests (ITestOutputHelper output) break; } - _ = TestHelpers.AssertDriverContentsWithFrameAre (expected, _output); + _ = DriverAssert.AssertDriverContentsWithFrameAre (expected, _output); Application.End (rs); win.Dispose (); } diff --git a/UnitTests/View/Layout/Pos.CombineTests.cs b/Tests/UnitTests/View/Layout/Pos.CombineTests.cs similarity index 81% rename from UnitTests/View/Layout/Pos.CombineTests.cs rename to Tests/UnitTests/View/Layout/Pos.CombineTests.cs index 8a71ef422..a3b8b5045 100644 --- a/UnitTests/View/Layout/Pos.CombineTests.cs +++ b/Tests/UnitTests/View/Layout/Pos.CombineTests.cs @@ -1,4 +1,5 @@ using Microsoft.VisualStudio.TestPlatform.Utilities; +using UnitTests; using Xunit.Abstractions; using static Terminal.Gui.Dim; using static Terminal.Gui.Pos; @@ -9,29 +10,6 @@ public class PosCombineTests (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] - public void PosCombine_Referencing_Same_View () - { - var super = new View { Width = 10, Height = 10, Text = "super" }; - var view1 = new View { Width = 2, Height = 2, Text = "view1" }; - var view2 = new View { Width = 2, Height = 2, Text = "view2" }; - view2.X = Pos.AnchorEnd (0) - (Pos.Right (view2) - Pos.Left (view2)); - - super.Add (view1, view2); - super.BeginInit (); - super.EndInit (); - - Exception exception = Record.Exception (super.LayoutSubviews); - Assert.Null (exception); - Assert.Equal (new (0, 0, 10, 10), super.Frame); - Assert.Equal (new (0, 0, 2, 2), view1.Frame); - Assert.Equal (new (8, 0, 2, 2), view2.Frame); - - super.Dispose (); - } - // TODO: This actually a SetRelativeLayout/LayoutSubViews test and should be moved // TODO: A new test that calls SetRelativeLayout directly is needed. [Fact] diff --git a/UnitTests/View/Layout/Pos.Tests.cs b/Tests/UnitTests/View/Layout/Pos.Tests.cs similarity index 68% rename from UnitTests/View/Layout/Pos.Tests.cs rename to Tests/UnitTests/View/Layout/Pos.Tests.cs index abc217a32..d0683086a 100644 --- a/UnitTests/View/Layout/Pos.Tests.cs +++ b/Tests/UnitTests/View/Layout/Pos.Tests.cs @@ -1,4 +1,5 @@ -using Xunit.Abstractions; +using UnitTests; +using Xunit.Abstractions; using static Terminal.Gui.Dim; using static Terminal.Gui.Pos; @@ -35,38 +36,6 @@ public class PosTests () Application.Shutdown (); } - [Fact] - public void PosCombine_Calculate_ReturnsExpectedValue () - { - var posCombine = new PosCombine (AddOrSubtract.Add, new PosAbsolute (5), new PosAbsolute (3)); - var result = posCombine.Calculate (10, new DimAbsolute (2), null, Dimension.None); - Assert.Equal (8, result); - } - - [Fact] - public void PosFactor_Calculate_ReturnsExpectedValue () - { - var posFactor = new PosPercent (50); - var result = posFactor.Calculate (10, new DimAbsolute (2), null, Dimension.None); - Assert.Equal (5, result); - } - - [Fact] - public void PosFunc_Calculate_ReturnsExpectedValue () - { - var posFunc = new PosFunc (() => 5); - var result = posFunc.Calculate (10, new DimAbsolute (2), null, Dimension.None); - Assert.Equal (5, result); - } - - [Fact] - public void PosView_Calculate_ReturnsExpectedValue () - { - var posView = new PosView (new View { Frame = new Rectangle (5, 5, 10, 10) }, 0); - var result = posView.Calculate (10, new DimAbsolute (2), null, Dimension.None); - Assert.Equal (5, result); - } - // TODO: This actually a SetRelativeLayout/LayoutSubViews test and should be moved // TODO: A new test that calls SetRelativeLayout directly is needed. @@ -97,107 +66,6 @@ public class PosTests () v2.Dispose (); } - [Fact] - public void PosCombine_DoesNotReturn () - { - var v = new View { Id = "V" }; - - Pos pos = Pos.Left (v); - - Assert.Equal ( - $"View(Side=Left,Target=View(V){v.Frame})", - pos.ToString () - ); - - pos = Pos.X (v); - - Assert.Equal ( - $"View(Side=Left,Target=View(V){v.Frame})", - pos.ToString () - ); - - pos = Pos.Top (v); - - Assert.Equal ( - $"View(Side=Top,Target=View(V){v.Frame})", - pos.ToString () - ); - - pos = Pos.Y (v); - - Assert.Equal ( - $"View(Side=Top,Target=View(V){v.Frame})", - pos.ToString () - ); - - pos = Pos.Right (v); - - Assert.Equal ( - $"View(Side=Right,Target=View(V){v.Frame})", - pos.ToString () - ); - - pos = Pos.Bottom (v); - - Assert.Equal ( - $"View(Side=Bottom,Target=View(V){v.Frame})", - pos.ToString () - ); - } - - [Fact] - public void PosFunction_SetsValue () - { - var text = "Test"; - Pos pos = Pos.Func (() => text.Length); - Assert.Equal ("PosFunc(4)", pos.ToString ()); - - text = "New Test"; - Assert.Equal ("PosFunc(8)", pos.ToString ()); - - text = ""; - Assert.Equal ("PosFunc(0)", pos.ToString ()); - } - - [Fact] - [TestRespondersDisposed] - public void Internal_Tests () - { - var posFactor = new PosPercent (10); - Assert.Equal (10, posFactor.GetAnchor (100)); - - var posAnchorEnd = new PosAnchorEnd (1); - Assert.Equal (99, posAnchorEnd.GetAnchor (100)); - - var posCenter = new PosCenter (); - Assert.Equal (50, posCenter.GetAnchor (100)); - - var posAbsolute = new PosAbsolute (10); - Assert.Equal (10, posAbsolute.GetAnchor (0)); - - var posCombine = new PosCombine (AddOrSubtract.Add, posFactor, posAbsolute); - Assert.Equal (posCombine.Left, posFactor); - Assert.Equal (posCombine.Right, posAbsolute); - Assert.Equal (20, posCombine.GetAnchor (100)); - - posCombine = new (AddOrSubtract.Add, posAbsolute, posFactor); - Assert.Equal (posCombine.Left, posAbsolute); - Assert.Equal (posCombine.Right, posFactor); - Assert.Equal (20, posCombine.GetAnchor (100)); - - var view = new View { Frame = new (20, 10, 20, 1) }; - var posViewX = new PosView (view, Side.Left); - Assert.Equal (20, posViewX.GetAnchor (0)); - var posViewY = new PosView (view, Side.Top); - Assert.Equal (10, posViewY.GetAnchor (0)); - var posRight = new PosView (view, Side.Right); - Assert.Equal (40, posRight.GetAnchor (0)); - var posViewBottom = new PosView (view, Side.Bottom); - Assert.Equal (11, posViewBottom.GetAnchor (0)); - - view.Dispose (); - } - // TODO: This actually a SetRelativeLayout/LayoutSubViews test and should be moved // TODO: A new test that calls SetRelativeLayout directly is needed. // See: https://github.com/gui-cs/Terminal.Gui/issues/504 @@ -283,42 +151,6 @@ public class PosTests () } } - [Fact] - public void PosPercent_Equal () - { - int n1 = 0; - int n2 = 0; - Pos pos1 = Pos.Percent (n1); - Pos pos2 = Pos.Percent (n2); - Assert.Equal (pos1, pos2); - - n1 = n2 = 1; - pos1 = Pos.Percent (n1); - pos2 = Pos.Percent (n2); - Assert.Equal (pos1, pos2); - - n1 = n2 = 50; - pos1 = Pos.Percent (n1); - pos2 = Pos.Percent (n2); - Assert.Equal (pos1, pos2); - - n1 = n2 = 100; - pos1 = Pos.Percent (n1); - pos2 = Pos.Percent (n2); - Assert.Equal (pos1, pos2); - - n1 = 0; - n2 = 1; - pos1 = Pos.Percent (n1); - pos2 = Pos.Percent (n2); - Assert.NotEqual (pos1, pos2); - - n1 = 50; - n2 = 150; - pos1 = Pos.Percent (n1); - pos2 = Pos.Percent (n2); - Assert.NotEqual (pos1, pos2); - } // TODO: This actually a SetRelativeLayout/LayoutSubViews test and should be moved // TODO: A new test that calls SetRelativeLayout directly is needed. diff --git a/Tests/UnitTests/View/Layout/Pos.ViewTests.cs b/Tests/UnitTests/View/Layout/Pos.ViewTests.cs new file mode 100644 index 000000000..398dae7f8 --- /dev/null +++ b/Tests/UnitTests/View/Layout/Pos.ViewTests.cs @@ -0,0 +1,78 @@ +using UnitTests; +using Xunit.Abstractions; +using static Terminal.Gui.Pos; + +namespace Terminal.Gui.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] + [TestRespondersDisposed] + public void Subtract_Operator () + { + Application.Init (new FakeDriver ()); + + var top = new Toplevel (); + + 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 += (s, a) => + { + while (count > 0) + { + field.NewKeyDownEvent (new (KeyCode.Enter)); + } + + Application.RequestStop (); + }; + + var win = new Window (); + win.Add (view); + win.Add (field); + + top.Add (win); + + Application.Run (top); + top.Dispose (); + Assert.Equal (0, count); + + // Shutdown must be called to safely clean up Application if Init has been called + Application.Shutdown (); + } +} diff --git a/Tests/UnitTests/View/Layout/SetLayoutTests.cs b/Tests/UnitTests/View/Layout/SetLayoutTests.cs new file mode 100644 index 000000000..27605d541 --- /dev/null +++ b/Tests/UnitTests/View/Layout/SetLayoutTests.cs @@ -0,0 +1,41 @@ +using UnitTests; +using Xunit.Abstractions; + +namespace Terminal.Gui.LayoutTests; + +public class SetLayoutTests (ITestOutputHelper output) +{ + private readonly ITestOutputHelper _output = output; + + + [Fact] + [AutoInitShutdown] + public void Screen_Size_Change_Causes_Layout () + { + Application.Top = new (); + + var view = new View + { + X = 3, + Y = 2, + Width = 10, + Height = 1, + Text = "0123456789" + }; + Application.Top.Add (view); + + var rs = Application.Begin (Application.Top); + + Assert.Equal (new (0, 0, 80, 25), new Rectangle (0, 0, View.Driver.Cols, View.Driver.Rows)); + Assert.Equal (new (0, 0, View.Driver.Cols, View.Driver.Rows), Application.Top.Frame); + Assert.Equal (new (0, 0, 80, 25), Application.Top.Frame); + + ((FakeDriver)Application.Driver!).SetBufferSize (20, 10); + Assert.Equal (new (0, 0, View.Driver.Cols, View.Driver.Rows), Application.Top.Frame); + + Assert.Equal (new (0, 0, 20, 10), Application.Top.Frame); + + Application.End (rs); + + } +} diff --git a/UnitTests/View/Mouse/GetViewsUnderMouseTests.cs b/Tests/UnitTests/View/Mouse/GetViewsUnderMouseTests.cs similarity index 100% rename from UnitTests/View/Mouse/GetViewsUnderMouseTests.cs rename to Tests/UnitTests/View/Mouse/GetViewsUnderMouseTests.cs diff --git a/UnitTests/View/Mouse/MouseEnterLeaveTests.cs b/Tests/UnitTests/View/Mouse/MouseEnterLeaveTests.cs similarity index 100% rename from UnitTests/View/Mouse/MouseEnterLeaveTests.cs rename to Tests/UnitTests/View/Mouse/MouseEnterLeaveTests.cs diff --git a/UnitTests/View/Mouse/MouseTests.cs b/Tests/UnitTests/View/Mouse/MouseTests.cs similarity index 99% rename from UnitTests/View/Mouse/MouseTests.cs rename to Tests/UnitTests/View/Mouse/MouseTests.cs index 9c91735ac..1c94ecd45 100644 --- a/UnitTests/View/Mouse/MouseTests.cs +++ b/Tests/UnitTests/View/Mouse/MouseTests.cs @@ -1,4 +1,6 @@ -using Xunit.Abstractions; +using UnitTests; +using UnitTests; +using Xunit.Abstractions; namespace Terminal.Gui.ViewMouseTests; diff --git a/UnitTests/View/Navigation/AddRemoveTests.cs b/Tests/UnitTests/View/Navigation/AddRemoveTests.cs similarity index 99% rename from UnitTests/View/Navigation/AddRemoveTests.cs rename to Tests/UnitTests/View/Navigation/AddRemoveTests.cs index ae84ba64f..253dd6dbd 100644 --- a/UnitTests/View/Navigation/AddRemoveTests.cs +++ b/Tests/UnitTests/View/Navigation/AddRemoveTests.cs @@ -1,4 +1,5 @@ -using Xunit.Abstractions; +using UnitTests; +using Xunit.Abstractions; namespace Terminal.Gui.ViewTests; diff --git a/UnitTests/View/Navigation/AdvanceFocusTests.cs b/Tests/UnitTests/View/Navigation/AdvanceFocusTests.cs similarity index 100% rename from UnitTests/View/Navigation/AdvanceFocusTests.cs rename to Tests/UnitTests/View/Navigation/AdvanceFocusTests.cs diff --git a/UnitTests/View/Navigation/CanFocusTests.cs b/Tests/UnitTests/View/Navigation/CanFocusTests.cs similarity index 93% rename from UnitTests/View/Navigation/CanFocusTests.cs rename to Tests/UnitTests/View/Navigation/CanFocusTests.cs index 39fa34ad8..88bd8300a 100644 --- a/UnitTests/View/Navigation/CanFocusTests.cs +++ b/Tests/UnitTests/View/Navigation/CanFocusTests.cs @@ -1,4 +1,5 @@ -using Xunit.Abstractions; +using UnitTests; +using Xunit.Abstractions; namespace Terminal.Gui.ViewTests; @@ -361,25 +362,4 @@ public class CanFocusTests () : TestsAllViews Application.Top.Dispose (); Application.ResetState (); } - - [Fact (Skip = "Causes crash on Ubuntu in Github Action. Bogus test anyway.")] - public void WindowDispose_CanFocusProblem () - { - // Arrange - Application.Init (); - using var top = new Toplevel (); - using var view = new View { X = 0, Y = 1, Text = nameof (WindowDispose_CanFocusProblem) }; - using var window = new Window (); - top.Add (window); - window.Add (view); - - // Act - RunState rs = Application.Begin (top); - Application.End (rs); - top.Dispose (); - Application.Shutdown (); - - // Assert does Not throw NullReferenceException - top.SetFocus (); - } } diff --git a/UnitTests/View/Navigation/EnabledTests.cs b/Tests/UnitTests/View/Navigation/EnabledTests.cs similarity index 99% rename from UnitTests/View/Navigation/EnabledTests.cs rename to Tests/UnitTests/View/Navigation/EnabledTests.cs index 708977904..46f8a782b 100644 --- a/UnitTests/View/Navigation/EnabledTests.cs +++ b/Tests/UnitTests/View/Navigation/EnabledTests.cs @@ -1,4 +1,6 @@ -using Xunit.Abstractions; +using UnitTests; +using UnitTests; +using Xunit.Abstractions; namespace Terminal.Gui.ViewTests; diff --git a/UnitTests/View/Navigation/HasFocusChangeEventTests.cs b/Tests/UnitTests/View/Navigation/HasFocusChangeEventTests.cs similarity index 99% rename from UnitTests/View/Navigation/HasFocusChangeEventTests.cs rename to Tests/UnitTests/View/Navigation/HasFocusChangeEventTests.cs index 24e4d4478..bba863af6 100644 --- a/UnitTests/View/Navigation/HasFocusChangeEventTests.cs +++ b/Tests/UnitTests/View/Navigation/HasFocusChangeEventTests.cs @@ -1,4 +1,5 @@ -using Xunit.Abstractions; +using UnitTests; +using Xunit.Abstractions; namespace Terminal.Gui.ViewTests; diff --git a/UnitTests/View/Navigation/HasFocusTests.cs b/Tests/UnitTests/View/Navigation/HasFocusTests.cs similarity index 99% rename from UnitTests/View/Navigation/HasFocusTests.cs rename to Tests/UnitTests/View/Navigation/HasFocusTests.cs index 072d23c71..59d22ef73 100644 --- a/UnitTests/View/Navigation/HasFocusTests.cs +++ b/Tests/UnitTests/View/Navigation/HasFocusTests.cs @@ -1,4 +1,5 @@ -using Xunit.Abstractions; +using UnitTests; +using Xunit.Abstractions; namespace Terminal.Gui.ViewTests; diff --git a/UnitTests/View/Navigation/NavigationTests.cs b/Tests/UnitTests/View/Navigation/NavigationTests.cs similarity index 99% rename from UnitTests/View/Navigation/NavigationTests.cs rename to Tests/UnitTests/View/Navigation/NavigationTests.cs index 97aef5df5..d72067663 100644 --- a/UnitTests/View/Navigation/NavigationTests.cs +++ b/Tests/UnitTests/View/Navigation/NavigationTests.cs @@ -1,4 +1,6 @@ using JetBrains.Annotations; +using UnitTests; +using UnitTests; using Xunit.Abstractions; namespace Terminal.Gui.ViewTests; diff --git a/UnitTests/View/Navigation/RestoreFocusTests.cs b/Tests/UnitTests/View/Navigation/RestoreFocusTests.cs similarity index 99% rename from UnitTests/View/Navigation/RestoreFocusTests.cs rename to Tests/UnitTests/View/Navigation/RestoreFocusTests.cs index e03c25fc8..8767f9c1b 100644 --- a/UnitTests/View/Navigation/RestoreFocusTests.cs +++ b/Tests/UnitTests/View/Navigation/RestoreFocusTests.cs @@ -1,4 +1,5 @@ -using Xunit.Abstractions; +using UnitTests; +using Xunit.Abstractions; namespace Terminal.Gui.ViewTests; diff --git a/UnitTests/View/Navigation/SetFocusTests.cs b/Tests/UnitTests/View/Navigation/SetFocusTests.cs similarity index 99% rename from UnitTests/View/Navigation/SetFocusTests.cs rename to Tests/UnitTests/View/Navigation/SetFocusTests.cs index 832c88ac3..9cb6c311b 100644 --- a/UnitTests/View/Navigation/SetFocusTests.cs +++ b/Tests/UnitTests/View/Navigation/SetFocusTests.cs @@ -1,4 +1,5 @@ -using Xunit.Abstractions; +using UnitTests; +using Xunit.Abstractions; namespace Terminal.Gui.ViewTests; diff --git a/UnitTests/View/Navigation/VisibleTests.cs b/Tests/UnitTests/View/Navigation/VisibleTests.cs similarity index 99% rename from UnitTests/View/Navigation/VisibleTests.cs rename to Tests/UnitTests/View/Navigation/VisibleTests.cs index e4a1e102b..aa037c16e 100644 --- a/UnitTests/View/Navigation/VisibleTests.cs +++ b/Tests/UnitTests/View/Navigation/VisibleTests.cs @@ -1,4 +1,5 @@ -using Xunit.Abstractions; +using UnitTests; +using Xunit.Abstractions; namespace Terminal.Gui.ViewTests; diff --git a/UnitTests/View/Orientation/OrientationHelperTests.cs b/Tests/UnitTests/View/Orientation/OrientationHelperTests.cs similarity index 100% rename from UnitTests/View/Orientation/OrientationHelperTests.cs rename to Tests/UnitTests/View/Orientation/OrientationHelperTests.cs diff --git a/UnitTests/View/Orientation/OrientationTests.cs b/Tests/UnitTests/View/Orientation/OrientationTests.cs similarity index 100% rename from UnitTests/View/Orientation/OrientationTests.cs rename to Tests/UnitTests/View/Orientation/OrientationTests.cs diff --git a/UnitTests/View/SubviewTests.cs b/Tests/UnitTests/View/SubviewTests.cs similarity index 61% rename from UnitTests/View/SubviewTests.cs rename to Tests/UnitTests/View/SubviewTests.cs index 8dc057457..666a282e0 100644 --- a/UnitTests/View/SubviewTests.cs +++ b/Tests/UnitTests/View/SubviewTests.cs @@ -1,4 +1,5 @@ using System.Text; +using UnitTests; using Xunit.Abstractions; namespace Terminal.Gui.ViewTests; @@ -8,37 +9,6 @@ public class SubviewTests private readonly ITestOutputHelper _output; public SubviewTests (ITestOutputHelper output) { _output = output; } - [Fact] - [TestRespondersDisposed] - public void Added_Removed () - { - var v = new View { Frame = new Rectangle (0, 0, 10, 24) }; - var t = new View (); - - v.Added += (s, e) => - { - Assert.Same (v.SuperView, e.SuperView); - Assert.Same (t, e.SuperView); - Assert.Same (v, e.SubView); - }; - - v.Removed += (s, e) => - { - Assert.Same (t, e.SuperView); - Assert.Same (v, e.SubView); - Assert.True (v.SuperView == null); - }; - - t.Add (v); - Assert.True (t.Subviews.Count == 1); - - t.Remove (v); - Assert.True (t.Subviews.Count == 0); - - t.Dispose (); - v.Dispose (); - } - [Fact] [AutoInitShutdown] public void GetTopSuperView_Test () @@ -315,296 +285,4 @@ public class SubviewTests Assert.True (w.CanFocus); Assert.False (v1.CanFocus); Assert.False (v2.CanFocus); - } - - [Fact] - [TestRespondersDisposed] - public void IsAdded_Added_Removed () - { - var top = new Toplevel (); - var view = new View (); - Assert.False (view.IsAdded); - top.Add (view); - Assert.True (view.IsAdded); - top.Remove (view); - Assert.False (view.IsAdded); - - top.Dispose (); - view.Dispose (); - } - - // TODO: Consider a feature that will change the ContentSize to fit the subviews. - [Fact] - public void Add_Does_Not_Impact_ContentSize () - { - var view = new View (); - view.SetContentSize (new Size (1, 1)); - - var subview = new View () - { - X = 10, - Y = 10 - }; - - Assert.Equal (new Size (1, 1), view.GetContentSize ()); - view.Add (subview); - Assert.Equal (new Size (1, 1), view.GetContentSize ()); - } - - [Fact] - public void Remove_Does_Not_Impact_ContentSize () - { - var view = new View (); - view.SetContentSize (new Size (1, 1)); - - var subview = new View () - { - X = 10, - Y = 10 - }; - - Assert.Equal (new Size (1, 1), view.GetContentSize ()); - view.Add (subview); - Assert.Equal (new Size (1, 1), view.GetContentSize ()); - - view.SetContentSize (new Size (5, 5)); - Assert.Equal (new Size (5, 5), view.GetContentSize ()); - - view.Remove (subview); - Assert.Equal (new Size (5, 5), view.GetContentSize ()); - } - - [Fact] - public void MoveSubviewToStart () - { - View superView = new (); - - View subview1 = new View () - { - Id = "subview1" - }; - - View subview2 = new View () - { - Id = "subview2" - }; - - View subview3 = new View () - { - Id = "subview3" - }; - - superView.Add (subview1, subview2, subview3); - - superView.MoveSubviewToStart (subview2); - Assert.Equal(subview2, superView.Subviews [0]); - - superView.MoveSubviewToStart (subview3); - Assert.Equal (subview3, superView.Subviews [0]); - } - - - [Fact] - public void MoveSubviewTowardsFront () - { - View superView = new (); - - View subview1 = new View () - { - Id = "subview1" - }; - - View subview2 = new View () - { - Id = "subview2" - }; - - View subview3 = new View () - { - Id = "subview3" - }; - - superView.Add (subview1, subview2, subview3); - - superView.MoveSubviewTowardsStart (subview2); - Assert.Equal (subview2, superView.Subviews [0]); - - superView.MoveSubviewTowardsStart (subview3); - Assert.Equal (subview3, superView.Subviews [1]); - - // Already at front, what happens? - superView.MoveSubviewTowardsStart (subview2); - Assert.Equal (subview2, superView.Subviews [0]); - } - - [Fact] - public void MoveSubviewToEnd () - { - View superView = new (); - - View subview1 = new View () - { - Id = "subview1" - }; - - View subview2 = new View () - { - Id = "subview2" - }; - - View subview3 = new View () - { - Id = "subview3" - }; - - superView.Add (subview1, subview2, subview3); - - superView.MoveSubviewToEnd (subview1); - Assert.Equal (subview1, superView.Subviews [^1]); - - superView.MoveSubviewToEnd (subview2); - Assert.Equal (subview2, superView.Subviews [^1]); - } - - - [Fact] - public void MoveSubviewTowardsEnd () - { - View superView = new (); - - View subview1 = new View () - { - Id = "subview1" - }; - - View subview2 = new View () - { - Id = "subview2" - }; - - View subview3 = new View () - { - Id = "subview3" - }; - - superView.Add (subview1, subview2, subview3); - - superView.MoveSubviewTowardsEnd (subview2); - Assert.Equal (subview2, superView.Subviews [^1]); - - superView.MoveSubviewTowardsEnd (subview1); - Assert.Equal (subview1, superView.Subviews [1]); - - // Already at end, what happens? - superView.MoveSubviewTowardsEnd (subview2); - Assert.Equal (subview2, superView.Subviews [^1]); - } - - [Fact] - public void IsInHierarchy_ViewIsNull_ReturnsFalse () - { - // Arrange - var start = new View (); - - // Act - var result = View.IsInHierarchy (start, null); - - // Assert - Assert.False (result); - } - - [Fact] - public void IsInHierarchy_StartIsNull_ReturnsFalse () - { - // Arrange - var view = new View (); - - // Act - var result = View.IsInHierarchy (null, view); - - // Assert - Assert.False (result); - } - - [Fact] - public void IsInHierarchy_ViewIsStart_ReturnsTrue () - { - // Arrange - var start = new View (); - - // Act - var result = View.IsInHierarchy (start, start); - - // Assert - Assert.True (result); - } - - [Fact] - public void IsInHierarchy_ViewIsDirectSubview_ReturnsTrue () - { - // Arrange - var start = new View (); - var subview = new View (); - start.Add (subview); - - // Act - var result = View.IsInHierarchy (start, subview); - - // Assert - Assert.True (result); - } - - [Fact] - public void IsInHierarchy_ViewIsNestedSubview_ReturnsTrue () - { - // Arrange - var start = new View (); - var subview = new View (); - var nestedSubview = new View (); - start.Add (subview); - subview.Add (nestedSubview); - - // Act - var result = View.IsInHierarchy (start, nestedSubview); - - // Assert - Assert.True (result); - } - - [Fact] - public void IsInHierarchy_ViewIsNotInHierarchy_ReturnsFalse () - { - // Arrange - var start = new View (); - var subview = new View (); - - // Act - var result = View.IsInHierarchy (start, subview); - - // Assert - Assert.False (result); - } - - [Theory] - [CombinatorialData] - public void IsInHierarchy_ViewIsInAdornments_ReturnsTrue (bool includeAdornments) - { - // Arrange - var start = new View () - { - Id = "start" - }; - var inPadding = new View () - { - Id = "inPadding" - }; - - start.Padding.Add (inPadding); - - // Act - var result = View.IsInHierarchy (start, inPadding, includeAdornments: includeAdornments); - - // Assert - Assert.Equal(includeAdornments, result); - } -} + }} diff --git a/UnitTests/View/TextTests.cs b/Tests/UnitTests/View/TextTests.cs similarity index 78% rename from UnitTests/View/TextTests.cs rename to Tests/UnitTests/View/TextTests.cs index d1a96a45d..6370521ec 100644 --- a/UnitTests/View/TextTests.cs +++ b/Tests/UnitTests/View/TextTests.cs @@ -1,5 +1,7 @@ using System.Runtime.CompilerServices; using System.Text; +using UnitTests; +using UnitTests; using Xunit.Abstractions; namespace Terminal.Gui.ViewTests; @@ -9,32 +11,6 @@ namespace Terminal.Gui.ViewTests; /// public class TextTests (ITestOutputHelper output) { - // TextFormatter.Size should be empty unless DimAuto is set or ContentSize is set - [Theory] - [InlineData ("", 0, 0)] - [InlineData (" ", 0, 0)] - [InlineData ("01234", 0, 0)] - public void TextFormatter_Size_Default (string text, int expectedW, int expectedH) - { - var view = new View (); - view.Text = text; - view.Layout (); - Assert.Equal (new (expectedW, expectedH), view.TextFormatter.ConstrainToSize); - } - - // TextFormatter.Size should track ContentSize (without DimAuto) - [Theory] - [InlineData ("", 1, 1)] - [InlineData (" ", 1, 1)] - [InlineData ("01234", 1, 1)] - public void TextFormatter_Size_Tracks_ContentSize (string text, int expectedW, int expectedH) - { - var view = new View (); - view.SetContentSize (new (1, 1)); - view.Text = text; - view.Layout (); - Assert.Equal (new (expectedW, expectedH), view.TextFormatter.ConstrainToSize); - } [Fact] [SetupFakeDriver] @@ -59,7 +35,7 @@ HelloX Y "; - Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Rectangle pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); label.Width = 10; label.Height = 2; @@ -76,7 +52,7 @@ Hello X Y "; - pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); } [Fact] @@ -109,7 +85,7 @@ o Y "; - Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Rectangle pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); label.Width = 2; label.Height = 10; @@ -132,7 +108,7 @@ Y " ; - pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Application.End (rs); top.Dispose (); } @@ -181,7 +157,7 @@ Y └─────────────┘ "; - Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Rectangle pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); view.Text = "Hello World"; view.Width = 11; @@ -211,7 +187,7 @@ Y └─────────────┘ "; - pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); view.Width = Dim.Auto (); view.Height = Dim.Auto (); @@ -239,7 +215,7 @@ Y └─────────────┘ "; - pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); view.TextDirection = TextDirection.TopBottom_LeftRight; Application.RunIteration (ref rs); @@ -264,7 +240,7 @@ Y └─────────────┘ "; - pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); // Setting to false causes Width and Height to be set to the current ContentSize view.Width = 1; @@ -283,7 +259,7 @@ Y view.SetNeedsDraw (); view.Draw (); expected = @" HelloWorlds"; - TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Application.RunIteration (ref rs); @@ -308,7 +284,7 @@ Y └─────────────┘ "; - pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); view.PreserveTrailingSpaces = true; Application.RunIteration (ref rs); @@ -333,7 +309,7 @@ Y └─────────────┘ "; - pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); view.PreserveTrailingSpaces = false; Rectangle f = view.Frame; @@ -362,7 +338,7 @@ Y └─────────────┘ "; - pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); view.Width = Dim.Auto (); view.Height = Dim.Auto (); @@ -389,7 +365,7 @@ Y └─────────────┘ "; - pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Application.End (rs); top.Dispose (); } @@ -437,7 +413,7 @@ Y └──┘ "; - Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Rectangle pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (0, 0, 4, 10), pos); text = "0123456789"; @@ -464,7 +440,7 @@ Y └──┘ "; - pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (0, 0, 4, 10), pos); top.Dispose (); } @@ -501,7 +477,7 @@ i e w "; - Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Rectangle pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); } [Fact] @@ -567,7 +543,7 @@ w "; └──────────────────┘ "; - Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Rectangle pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); verticalView.Text = $"最初の行{Environment.NewLine}二行目"; Application.RunIteration (ref rs); @@ -596,7 +572,7 @@ w "; └──────────────────┘ "; - pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Application.End (rs); top.Dispose (); } @@ -660,7 +636,7 @@ w "; └────────────────────┘ "; - Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Rectangle pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); verticalView.Text = "最初の行二行目"; Application.RunIteration (ref rs); @@ -693,7 +669,7 @@ w "; └────────────────────┘ "; - pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Application.End (rs); top.Dispose (); } @@ -858,7 +834,7 @@ w "; "; } - Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Rectangle pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (0, 0, width + 2, 6), pos); top.Dispose (); } @@ -1016,166 +992,11 @@ w "; "; } - Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Rectangle pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (0, 0, 9, height + 2), pos); top.Dispose (); } - // Test that View.PreserveTrailingSpaces removes trailing spaces - [Fact] - public void PreserveTrailingSpaces_Removes_Trailing_Spaces () - { - var view = new View { Text = "Hello World " }; - Assert.Equal ("Hello World ", view.TextFormatter.Text); - - view.TextFormatter.WordWrap = true; - view.TextFormatter.ConstrainToSize = new (5, 3); - - view.PreserveTrailingSpaces = false; - Assert.Equal ($"Hello{Environment.NewLine}World", view.TextFormatter.Format ()); - - view.PreserveTrailingSpaces = true; - Assert.Equal ($"Hello{Environment.NewLine} {Environment.NewLine}World", view.TextFormatter.Format ()); - } - - // View.PreserveTrailingSpaces Gets or sets whether trailing spaces at the end of word-wrapped lines are preserved - // or not when is enabled. - // If trailing spaces at the end of wrapped lines will be removed when - // is formatted for display.The default is . - [Fact] - public void PreserveTrailingSpaces_Set_Get () - { - var view = new View { Text = "Hello World" }; - - Assert.False (view.PreserveTrailingSpaces); - - view.PreserveTrailingSpaces = true; - Assert.True (view.PreserveTrailingSpaces); - } - - // Setting TextFormatter DOES NOT update Text - [Fact] - public void SettingTextFormatterDoesNotUpdateText () - { - var view = new View (); - view.TextFormatter.Text = "Hello World"; - - Assert.True (string.IsNullOrEmpty (view.Text)); - } - - // Setting Text updates TextFormatter - [Fact] - public void SettingTextUpdatesTextFormatter () - { - var view = new View { Text = "Hello World" }; - - Assert.Equal ("Hello World", view.Text); - Assert.Equal ("Hello World", view.TextFormatter.Text); - } - - // Setting Text does NOT set the HotKey - [Fact] - public void Text_Does_Not_Set_HotKey () - { - var view = new View { HotKeySpecifier = (Rune)'_', Text = "_Hello World" }; - - Assert.NotEqual (Key.H, view.HotKey); - } - - // Test that TextFormatter is init only - [Fact] - public void TextFormatterIsInitOnly () - { - var view = new View (); - - // Use reflection to ensure the TextFormatter property is `init` only - Assert.Contains ( - typeof (IsExternalInit), - typeof (View).GetMethod ("set_TextFormatter") - .ReturnParameter.GetRequiredCustomModifiers ()); - } - - // Test that the Text property is set correctly. - [Fact] - public void TextProperty () - { - var view = new View { Text = "Hello World" }; - - Assert.Equal ("Hello World", view.Text); - } - - // Test view.UpdateTextFormatterText overridden in a subclass updates TextFormatter.Text - [Fact] - public void UpdateTextFormatterText_Overridden () - { - var view = new TestView { Text = "Hello World" }; - - Assert.Equal ("Hello World", view.Text); - Assert.Equal (">Hello World<", view.TextFormatter.Text); - } - - private class TestView : View - { - protected override void UpdateTextFormatterText () { TextFormatter.Text = $">{Text}<"; } - } - - [Fact] - public void TextDirection_Horizontal_Dims_Correct () - { - // Initializes a view with a vertical direction - var view = new View - { - Text = "01234", - TextDirection = TextDirection.LeftRight_TopBottom, - Width = Dim.Auto (DimAutoStyle.Text), - Height = Dim.Auto (DimAutoStyle.Text) - }; - Assert.True (view.NeedsLayout); - view.Layout (); - Assert.Equal (new (0, 0, 5, 1), view.Frame); - Assert.Equal (new (0, 0, 5, 1), view.Viewport); - - view.BeginInit (); - view.EndInit (); - Assert.Equal (new (0, 0, 5, 1), view.Frame); - Assert.Equal (new (0, 0, 5, 1), view.Viewport); - } - - // BUGBUG: this is a temporary test that helped identify #3469 - It needs to be expanded upon (and renamed) - [Fact] - public void TextDirection_Horizontal_Dims_Correct_WidthAbsolute () - { - var view = new View - { - Text = "01234", - TextDirection = TextDirection.LeftRight_TopBottom, - TextAlignment = Alignment.Center, - Width = 10, - Height = Dim.Auto (DimAutoStyle.Text) - }; - view.BeginInit (); - view.EndInit (); - Assert.Equal (new (0, 0, 10, 1), view.Frame); - Assert.Equal (new (0, 0, 10, 1), view.Viewport); - - Assert.Equal (new (10, 1), view.TextFormatter.ConstrainToSize); - } - - [Fact] - public void TextDirection_Vertical_Dims_Correct () - { - // Initializes a view with a vertical direction - var view = new View - { - TextDirection = TextDirection.TopBottom_LeftRight, - Text = "01234", - Width = Dim.Auto (DimAutoStyle.Text), - Height = Dim.Auto (DimAutoStyle.Text) - }; - view.Layout (); - Assert.Equal (new (0, 0, 1, 5), view.Frame); - Assert.Equal (new (0, 0, 1, 5), view.Viewport); - } [Fact] [SetupFakeDriver] @@ -1248,7 +1069,7 @@ w "; └──────────────────────────────┘ "; - Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Rectangle pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); verticalView.Text = $"最初の行{Environment.NewLine}二行目"; Assert.True (verticalView.TextFormatter.NeedsFormat); @@ -1297,7 +1118,7 @@ w "; └──────────────────────────────┘ "; - pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); } [Fact] @@ -1312,6 +1133,6 @@ w "; view.EndInit (); view.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre (text, output); + DriverAssert.AssertDriverContentsWithFrameAre (text, output); } } diff --git a/UnitTests/View/ViewCommandTests.cs b/Tests/UnitTests/View/ViewCommandTests.cs similarity index 97% rename from UnitTests/View/ViewCommandTests.cs rename to Tests/UnitTests/View/ViewCommandTests.cs index a13243fae..728cc3bff 100644 --- a/UnitTests/View/ViewCommandTests.cs +++ b/Tests/UnitTests/View/ViewCommandTests.cs @@ -167,7 +167,8 @@ public class ViewCommandTests w.LayoutSubviews (); - Application.Begin (w); + Application.Top = w; + Application.TopLevels.Push(w); Assert.Same (Application.Top, w); // Click button 2 @@ -195,6 +196,8 @@ public class ViewCommandTests // Button A (IsDefault) should NOT have been accepted because B canceled Assert.Equal (1, A_AcceptedCount); Assert.Equal (2, B_AcceptedCount); + + Application.ResetState (true); } // See: https://github.com/gui-cs/Terminal.Gui/issues/3905 @@ -235,9 +238,12 @@ public class ViewCommandTests w.Add (btn); - w.LayoutSubviews (); - Application.Begin (w); + Application.Top = w; + Application.TopLevels.Push (w); + Assert.Same (Application.Top, w); + + w.LayoutSubviews (); // Click button just like a driver would var btnFrame = btn.FrameToScreen (); @@ -264,6 +270,8 @@ public class ViewCommandTests Assert.Equal (1, btnAcceptedCount); Assert.Equal (2, wAcceptedCount); + + Application.ResetState (true); } #endregion OnAccept/Accept tests diff --git a/UnitTests/View/ViewTests.cs b/Tests/UnitTests/View/ViewTests.cs similarity index 96% rename from UnitTests/View/ViewTests.cs rename to Tests/UnitTests/View/ViewTests.cs index 055c78244..f42cc4abd 100644 --- a/UnitTests/View/ViewTests.cs +++ b/Tests/UnitTests/View/ViewTests.cs @@ -1,19 +1,31 @@ using System.ComponentModel; using System.Text; +using UnitTests; +using UnitTests; using Xunit.Abstractions; namespace Terminal.Gui.ViewTests; -public class ViewTests (ITestOutputHelper output) +public class ViewTests { + private ITestOutputHelper _output; + + public ViewTests (ITestOutputHelper output) + { + output = output; +#if DEBUG_IDISPOSABLE + View.DebugIDisposable = true; +#endif + } + // Generic lifetime (IDisposable) tests [Fact] [TestRespondersDisposed] public void Dispose_Works () { var r = new View (); -#if DEBUG_IDISPOSABL - Assert.Equals (3, View.Instances.Count); +#if DEBUG_IDISPOSABLE + Assert.Equal (4, View.Instances.Count); #endif r.Dispose (); @@ -338,7 +350,7 @@ public class ViewTests (ITestOutputHelper output) 111 ─────────── 222"; - TestHelpers.AssertDriverContentsAre (looksLike, output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); v.Dispose (); top.Dispose (); bottom.Dispose (); @@ -444,7 +456,7 @@ public class ViewTests (ITestOutputHelper output) Assert.True (view.Visible); ((FakeDriver)Application.Driver!).SetBufferSize (30, 5); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌────────────────────────────┐ │Testing visibility. │ @@ -452,7 +464,7 @@ public class ViewTests (ITestOutputHelper output) │ │ └────────────────────────────┘ ", - output + _output ); view.Visible = false; @@ -460,7 +472,7 @@ public class ViewTests (ITestOutputHelper output) var firstIteration = false; Application.RunIteration (ref rs, firstIteration); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌────────────────────────────┐ │ │ @@ -468,7 +480,7 @@ public class ViewTests (ITestOutputHelper output) │ │ └────────────────────────────┘ ", - output + _output ); Application.End (rs); top.Dispose (); diff --git a/Tests/UnitTests/ViewTestHelpers.cs b/Tests/UnitTests/ViewTestHelpers.cs new file mode 100644 index 000000000..63085ef24 --- /dev/null +++ b/Tests/UnitTests/ViewTestHelpers.cs @@ -0,0 +1,141 @@ +using System.Reflection; + +namespace UnitTests; + +/// +/// Helpers for View tests. +/// +public class ViewTestHelpers +{ + public static View CreateViewFromType (Type type, ConstructorInfo ctor) + { + View viewType = null; + + if (type.IsGenericType && type.IsTypeDefinition) + { + List gTypes = new (); + + foreach (Type args in type.GetGenericArguments ()) + { + gTypes.Add (typeof (object)); + } + + type = type.MakeGenericType (gTypes.ToArray ()); + + Assert.IsType (type, (View)Activator.CreateInstance (type)); + } + else + { + ParameterInfo [] paramsInfo = ctor.GetParameters (); + Type paramType; + List pTypes = new (); + + if (type.IsGenericType) + { + foreach (Type args in type.GetGenericArguments ()) + { + paramType = args.GetType (); + + if (args.Name == "T") + { + pTypes.Add (typeof (object)); + } + else + { + AddArguments (paramType, pTypes); + } + } + } + + foreach (ParameterInfo p in paramsInfo) + { + paramType = p.ParameterType; + + if (p.HasDefaultValue) + { + pTypes.Add (p.DefaultValue); + } + else + { + AddArguments (paramType, pTypes); + } + } + + if (type.IsGenericType && !type.IsTypeDefinition) + { + viewType = (View)Activator.CreateInstance (type); + Assert.IsType (type, viewType); + } + else + { + viewType = (View)ctor.Invoke (pTypes.ToArray ()); + Assert.IsType (type, viewType); + } + } + + return viewType; + } + + public static List GetAllViewClasses () + { + return typeof (View).Assembly.GetTypes () + .Where ( + myType => myType.IsClass + && !myType.IsAbstract + && myType.IsPublic + && myType.IsSubclassOf (typeof (View)) + ) + .ToList (); + } + + private static void AddArguments (Type paramType, List pTypes) + { + if (paramType == typeof (Rectangle)) + { + pTypes.Add (Rectangle.Empty); + } + else if (paramType == typeof (string)) + { + pTypes.Add (string.Empty); + } + else if (paramType == typeof (int)) + { + pTypes.Add (0); + } + else if (paramType == typeof (bool)) + { + pTypes.Add (true); + } + else if (paramType.Name == "IList") + { + pTypes.Add (new List ()); + } + else if (paramType.Name == "View") + { + var top = new Toplevel (); + var view = new View (); + top.Add (view); + pTypes.Add (view); + } + else if (paramType.Name == "View[]") + { + pTypes.Add (new View [] { }); + } + else if (paramType.Name == "Stream") + { + pTypes.Add (new MemoryStream ()); + } + else if (paramType.Name == "String") + { + pTypes.Add (string.Empty); + } + else if (paramType.Name == "TreeView`1[T]") + { + pTypes.Add (string.Empty); + } + else + { + pTypes.Add (null); + } + } +} diff --git a/UnitTests/Views/AllViewsTests.cs b/Tests/UnitTests/Views/AllViewsTests.cs similarity index 98% rename from UnitTests/Views/AllViewsTests.cs rename to Tests/UnitTests/Views/AllViewsTests.cs index 456c2be0b..9d8f30a35 100644 --- a/UnitTests/Views/AllViewsTests.cs +++ b/Tests/UnitTests/Views/AllViewsTests.cs @@ -1,6 +1,8 @@ using System.Collections; using System.Reflection; using System.Text; +using UnitTests; +using UnitTests; using Xunit.Abstractions; namespace Terminal.Gui.ViewsTests; @@ -77,7 +79,7 @@ public class AllViewsTests (ITestOutputHelper output) : TestsAllViews { foreach (ConstructorInfo ctor in type.GetConstructors ()) { - View view = TestHelpers.CreateViewFromType (type, ctor); + View view = ViewTestHelpers.CreateViewFromType (type, ctor); if (view != null) { diff --git a/UnitTests/Views/AppendAutocompleteTests.cs b/Tests/UnitTests/Views/AppendAutocompleteTests.cs similarity index 86% rename from UnitTests/Views/AppendAutocompleteTests.cs rename to Tests/UnitTests/Views/AppendAutocompleteTests.cs index 6bdc1f067..53d63261d 100644 --- a/UnitTests/Views/AppendAutocompleteTests.cs +++ b/Tests/UnitTests/Views/AppendAutocompleteTests.cs @@ -1,3 +1,5 @@ +using UnitTests; +using UnitTests; using Xunit.Abstractions; namespace Terminal.Gui.TextTests; @@ -14,7 +16,7 @@ public class AppendAutocompleteTests (ITestOutputHelper output) Application.Driver?.SendKeys ('f', ConsoleKey.F, false, false, false); tf.Draw (); tf.PositionCursor (); - TestHelpers.AssertDriverContentsAre ("fish", output); + DriverAssert.AssertDriverContentsAre ("fish", output); Assert.Equal ("f", tf.Text); // When cancelling autocomplete @@ -23,7 +25,7 @@ public class AppendAutocompleteTests (ITestOutputHelper output) // Suggestion should disappear View.SetClipToScreen (); tf.Draw (); - TestHelpers.AssertDriverContentsAre ("f", output); + DriverAssert.AssertDriverContentsAre ("f", output); Assert.Equal ("f", tf.Text); // Still has focus though @@ -46,7 +48,7 @@ public class AppendAutocompleteTests (ITestOutputHelper output) View.SetClipToScreen (); tf.Draw (); tf.PositionCursor (); - TestHelpers.AssertDriverContentsAre ("fish", output); + DriverAssert.AssertDriverContentsAre ("fish", output); Assert.Equal ("f", tf.Text); // When cancelling autocomplete @@ -55,7 +57,7 @@ public class AppendAutocompleteTests (ITestOutputHelper output) // Suggestion should disappear View.SetClipToScreen (); tf.Draw (); - TestHelpers.AssertDriverContentsAre ("f", output); + DriverAssert.AssertDriverContentsAre ("f", output); Assert.Equal ("f", tf.Text); // Should reappear when you press next letter @@ -63,7 +65,7 @@ public class AppendAutocompleteTests (ITestOutputHelper output) tf.PositionCursor (); View.SetClipToScreen (); tf.Draw (); - TestHelpers.AssertDriverContentsAre ("fish", output); + DriverAssert.AssertDriverContentsAre ("fish", output); Assert.Equal ("fi", tf.Text); Application.Top.Dispose (); } @@ -81,7 +83,7 @@ public class AppendAutocompleteTests (ITestOutputHelper output) View.SetClipToScreen (); tf.Draw (); tf.PositionCursor (); - TestHelpers.AssertDriverContentsAre ("fish", output); + DriverAssert.AssertDriverContentsAre ("fish", output); Assert.Equal ("f", tf.Text); // When cycling autocomplete @@ -90,7 +92,7 @@ public class AppendAutocompleteTests (ITestOutputHelper output) View.SetClipToScreen (); tf.Draw (); tf.PositionCursor (); - TestHelpers.AssertDriverContentsAre ("friend", output); + DriverAssert.AssertDriverContentsAre ("friend", output); Assert.Equal ("f", tf.Text); // Should be able to cycle in circles endlessly @@ -98,7 +100,7 @@ public class AppendAutocompleteTests (ITestOutputHelper output) View.SetClipToScreen (); tf.Draw (); tf.PositionCursor (); - TestHelpers.AssertDriverContentsAre ("fish", output); + DriverAssert.AssertDriverContentsAre ("fish", output); Assert.Equal ("f", tf.Text); Application.Top.Dispose (); } @@ -114,7 +116,7 @@ public class AppendAutocompleteTests (ITestOutputHelper output) View.SetClipToScreen (); tf.Draw (); tf.PositionCursor (); - TestHelpers.AssertDriverContentsAre ("fish", output); + DriverAssert.AssertDriverContentsAre ("fish", output); Assert.Equal ("f", tf.Text); // add a space then go back 1 @@ -123,7 +125,7 @@ public class AppendAutocompleteTests (ITestOutputHelper output) View.SetClipToScreen (); tf.Draw (); - TestHelpers.AssertDriverContentsAre ("f", output); + DriverAssert.AssertDriverContentsAre ("f", output); Assert.Equal ("f ", tf.Text); Application.Top.Dispose (); } @@ -139,14 +141,14 @@ public class AppendAutocompleteTests (ITestOutputHelper output) View.SetClipToScreen (); tf.Draw (); tf.PositionCursor (); - TestHelpers.AssertDriverContentsAre ("fish", output); + DriverAssert.AssertDriverContentsAre ("fish", output); Assert.Equal ("f", tf.Text); // x is typed and suggestion should disappear Application.Driver?.SendKeys ('x', ConsoleKey.X, false, false, false); View.SetClipToScreen (); tf.Draw (); - TestHelpers.AssertDriverContentsAre ("fx", output); + DriverAssert.AssertDriverContentsAre ("fx", output); Assert.Equal ("fx", tf.Text); Application.Top.Dispose (); } @@ -164,7 +166,7 @@ public class AppendAutocompleteTests (ITestOutputHelper output) View.SetClipToScreen (); tf.Draw (); tf.PositionCursor (); - TestHelpers.AssertDriverContentsAre ("", output); + DriverAssert.AssertDriverContentsAre ("", output); tf.NewKeyDownEvent (Key.M); tf.NewKeyDownEvent (Key.Y); tf.NewKeyDownEvent (Key.Space); @@ -175,14 +177,14 @@ public class AppendAutocompleteTests (ITestOutputHelper output) View.SetClipToScreen (); tf.Draw (); tf.PositionCursor (); - TestHelpers.AssertDriverContentsAre ("my fISH", output); + DriverAssert.AssertDriverContentsAre ("my fISH", output); Assert.Equal ("my f", tf.Text); // When tab completing the case of the whole suggestion should be applied Application.Driver?.SendKeys ('\t', ConsoleKey.Tab, false, false, false); View.SetClipToScreen (); tf.Draw (); - TestHelpers.AssertDriverContentsAre ("my FISH", output); + DriverAssert.AssertDriverContentsAre ("my FISH", output); Assert.Equal ("my FISH", tf.Text); Application.Top.Dispose (); } @@ -200,21 +202,21 @@ public class AppendAutocompleteTests (ITestOutputHelper output) View.SetClipToScreen (); tf.Draw (); tf.PositionCursor (); - TestHelpers.AssertDriverContentsAre ("", output); + DriverAssert.AssertDriverContentsAre ("", output); tf.NewKeyDownEvent (new Key ('f')); View.SetClipToScreen (); tf.Draw (); tf.PositionCursor (); - TestHelpers.AssertDriverContentsAre ("fish", output); + DriverAssert.AssertDriverContentsAre ("fish", output); Assert.Equal ("f", tf.Text); Application.Driver?.SendKeys ('\t', ConsoleKey.Tab, false, false, false); View.SetClipToScreen (); tf.Draw (); - TestHelpers.AssertDriverContentsAre ("fish", output); + DriverAssert.AssertDriverContentsAre ("fish", output); Assert.Equal ("fish", tf.Text); // Tab should autcomplete but not move focus @@ -240,7 +242,7 @@ public class AppendAutocompleteTests (ITestOutputHelper output) View.SetClipToScreen (); tf.Draw (); tf.PositionCursor (); - TestHelpers.AssertDriverContentsAre (expectRender, output); + DriverAssert.AssertDriverContentsAre (expectRender, output); Assert.Equal ("f", tf.Text); Application.Top.Dispose (); } @@ -271,7 +273,7 @@ public class AppendAutocompleteTests (ITestOutputHelper output) tf.Draw (); tf.PositionCursor (); - TestHelpers.AssertDriverContentsAre ("", output); + DriverAssert.AssertDriverContentsAre ("", output); return tf; } diff --git a/UnitTests/Views/BarTests.cs b/Tests/UnitTests/Views/BarTests.cs similarity index 100% rename from UnitTests/Views/BarTests.cs rename to Tests/UnitTests/Views/BarTests.cs diff --git a/UnitTests/Views/ButtonTests.cs b/Tests/UnitTests/Views/ButtonTests.cs similarity index 98% rename from UnitTests/Views/ButtonTests.cs rename to Tests/UnitTests/Views/ButtonTests.cs index dc7dcb5ce..1e2fad255 100644 --- a/UnitTests/Views/ButtonTests.cs +++ b/Tests/UnitTests/Views/ButtonTests.cs @@ -1,4 +1,6 @@ using System.ComponentModel; +using UnitTests; +using UnitTests; using Xunit.Abstractions; namespace Terminal.Gui.ViewsTests; @@ -181,7 +183,7 @@ public class ButtonTests (ITestOutputHelper output) var expected = @$" {Glyphs.LeftBracket} {Glyphs.RightBracket} "; - TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + DriverAssert.AssertDriverContentsWithFrameAre (expected, output); btn.Dispose (); btn = new () { Text = "_Test", IsDefault = true }; @@ -238,7 +240,7 @@ public class ButtonTests (ITestOutputHelper output) expected = @$" {Glyphs.LeftBracket}{Glyphs.LeftDefaultIndicator} abc {Glyphs.RightDefaultIndicator}{Glyphs.RightBracket} "; - TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (0, 0, 9, 1), btn.Viewport); Assert.Equal (new (1, 2, 9, 1), btn.Frame); @@ -588,7 +590,7 @@ public class ButtonTests (ITestOutputHelper output) └────────────────────────────┘ "; - Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Rectangle pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (0, 0, 30, 5), pos); top.Dispose (); } diff --git a/UnitTests/Views/CheckBoxTests.cs b/Tests/UnitTests/Views/CheckBoxTests.cs similarity index 94% rename from UnitTests/Views/CheckBoxTests.cs rename to Tests/UnitTests/Views/CheckBoxTests.cs index 511cf3be4..2f2de821f 100644 --- a/UnitTests/Views/CheckBoxTests.cs +++ b/Tests/UnitTests/Views/CheckBoxTests.cs @@ -1,5 +1,7 @@ using System.ComponentModel; +using UnitTests; using Xunit.Abstractions; + // ReSharper disable AccessToModifiedClosure namespace Terminal.Gui.ViewsTests; @@ -142,8 +144,6 @@ public class CheckBoxTests (ITestOutputHelper output) Assert.Equal (new (3, 4, 6, 1), ckb.Frame); } - - [Fact] [SetupFakeDriver] public void AllowCheckStateNone_Get_Set () @@ -174,21 +174,21 @@ public class CheckBoxTests (ITestOutputHelper output) [Fact] public void Commands_Select () { - Application.Navigation = new ApplicationNavigation (); - Application.Top = new Toplevel (); + Application.Navigation = new (); + Application.Top = new (); View otherView = new () { CanFocus = true }; var ckb = new CheckBox (); Application.Top.Add (ckb, otherView); Application.Top.SetFocus (); Assert.True (ckb.HasFocus); - int checkedStateChangingCount = 0; + var checkedStateChangingCount = 0; ckb.CheckedStateChanging += (s, e) => checkedStateChangingCount++; - int selectCount = 0; + var selectCount = 0; ckb.Selecting += (s, e) => selectCount++; - int acceptCount = 0; + var acceptCount = 0; ckb.Accepting += (s, e) => acceptCount++; Assert.Equal (CheckState.UnChecked, ckb.CheckedState); @@ -224,7 +224,7 @@ public class CheckBoxTests (ITestOutputHelper output) Assert.Equal (1, acceptCount); Application.Top.Dispose (); - Application.ResetState (false); + Application.ResetState (); } [Fact] @@ -257,13 +257,13 @@ public class CheckBoxTests (ITestOutputHelper output) var checkBox = new CheckBox { Text = "_Checkbox" }; Assert.True (checkBox.CanFocus); - int checkedStateChangingCount = 0; + var checkedStateChangingCount = 0; checkBox.CheckedStateChanging += (s, e) => checkedStateChangingCount++; - int selectCount = 0; + var selectCount = 0; checkBox.Selecting += (s, e) => selectCount++; - int acceptCount = 0; + var acceptCount = 0; checkBox.Accepting += (s, e) => acceptCount++; checkBox.HasFocus = true; @@ -293,7 +293,6 @@ public class CheckBoxTests (ITestOutputHelper output) Assert.Equal (0, acceptCount); } - [Fact] [SetupFakeDriver] public void Mouse_DoubleClick_Accepts () @@ -301,13 +300,14 @@ public class CheckBoxTests (ITestOutputHelper output) var checkBox = new CheckBox { Text = "_Checkbox" }; Assert.True (checkBox.CanFocus); - int checkedStateChangingCount = 0; + var checkedStateChangingCount = 0; checkBox.CheckedStateChanging += (s, e) => checkedStateChangingCount++; - int selectCount = 0; + var selectCount = 0; checkBox.Selecting += (s, e) => selectCount++; - int acceptCount = 0; + var acceptCount = 0; + checkBox.Accepting += (s, e) => { acceptCount++; @@ -327,7 +327,6 @@ public class CheckBoxTests (ITestOutputHelper output) Assert.Equal (0, checkedStateChangingCount); Assert.Equal (0, selectCount); Assert.Equal (1, acceptCount); - } #endregion Mouse Tests @@ -364,7 +363,7 @@ public class CheckBoxTests (ITestOutputHelper output) └────────────────────────────┘ "; - Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Rectangle pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (0, 0, 30, 5), pos); checkBox.CheckedState = CheckState.Checked; @@ -378,7 +377,7 @@ public class CheckBoxTests (ITestOutputHelper output) └────────────────────────────┘ "; - pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (0, 0, 30, 5), pos); top.Dispose (); } @@ -426,7 +425,7 @@ public class CheckBoxTests (ITestOutputHelper output) └────────────────────────────┘ "; - Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Rectangle pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (0, 0, 30, 6), pos); checkBox1.CheckedState = CheckState.Checked; @@ -449,7 +448,7 @@ public class CheckBoxTests (ITestOutputHelper output) └────────────────────────────┘ "; - pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (0, 0, 30, 6), pos); top.Dispose (); } @@ -485,7 +484,7 @@ public class CheckBoxTests (ITestOutputHelper output) └────────────────────────────┘ "; - Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Rectangle pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (0, 0, 30, 5), pos); checkBox.CheckedState = CheckState.Checked; @@ -499,7 +498,7 @@ public class CheckBoxTests (ITestOutputHelper output) └────────────────────────────┘ "; - pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (0, 0, 30, 5), pos); top.Dispose (); } @@ -536,7 +535,7 @@ public class CheckBoxTests (ITestOutputHelper output) └────────────────────────────┘ "; - Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Rectangle pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (0, 0, 30, 5), pos); checkBox.CheckedState = CheckState.Checked; @@ -550,7 +549,7 @@ public class CheckBoxTests (ITestOutputHelper output) └────────────────────────────┘ "; - pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (0, 0, 30, 5), pos); top.Dispose (); } @@ -571,7 +570,6 @@ public class CheckBoxTests (ITestOutputHelper output) void CheckBoxOnAccept (object sender, CommandEventArgs e) { accepted = true; } } - [Theory] [InlineData (CheckState.Checked)] [InlineData (CheckState.UnChecked)] @@ -614,6 +612,7 @@ public class CheckBoxTests (ITestOutputHelper output) ckb.CheckedStateChanging += OnCheckedStateChanging; Assert.Equal (initialState, ckb.CheckedState); + // 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); diff --git a/UnitTests/Views/ColorPicker16Tests.cs b/Tests/UnitTests/Views/ColorPicker16Tests.cs similarity index 97% rename from UnitTests/Views/ColorPicker16Tests.cs rename to Tests/UnitTests/Views/ColorPicker16Tests.cs index 162301e2b..38d46947f 100644 --- a/UnitTests/Views/ColorPicker16Tests.cs +++ b/Tests/UnitTests/Views/ColorPicker16Tests.cs @@ -1,4 +1,6 @@ -namespace Terminal.Gui.ViewsTests; +using UnitTests; + +namespace Terminal.Gui.ViewsTests; public class ColorPicker16Tests { diff --git a/UnitTests/Views/ColorPickerTests.cs b/Tests/UnitTests/Views/ColorPickerTests.cs similarity index 66% rename from UnitTests/Views/ColorPickerTests.cs rename to Tests/UnitTests/Views/ColorPickerTests.cs index 754e9e206..076e2a8fa 100644 --- a/UnitTests/Views/ColorPickerTests.cs +++ b/Tests/UnitTests/Views/ColorPickerTests.cs @@ -1,16 +1,235 @@ -using System.Reflection.Emit; -using Xunit.Abstractions; -using Color = Terminal.Gui.Color; +using UnitTests; namespace Terminal.Gui.ViewsTests; public class ColorPickerTests { + public ColorPickerTests () + { +#if DEBUG_IDISPOSABLE + View.DebugIDisposable = true; +#endif + } + + [Fact] + [SetupFakeDriver] + public void ColorPicker_ChangedEvent_Fires () + { + Color newColor = default; + var count = 0; + + var cp = new ColorPicker (); + + cp.ColorChanged += (s, e) => + { + count++; + newColor = e.CurrentValue; + + Assert.Equal (cp.SelectedColor, e.CurrentValue); + }; + + cp.SelectedColor = new (1, 2, 3); + Assert.Equal (1, count); + Assert.Equal (new (1, 2, 3), newColor); + + cp.SelectedColor = new (2, 3, 4); + + Assert.Equal (2, count); + Assert.Equal (new (2, 3, 4), newColor); + + // Set to same value + cp.SelectedColor = new (2, 3, 4); + + // Should have no effect + Assert.Equal (2, count); + } + + [Fact] + [SetupFakeDriver] + public void ColorPicker_ChangeValueOnUI_UpdatesAllUIElements () + { + ColorPicker cp = GetColorPicker (ColorModel.RGB, true); + + var otherView = new View { CanFocus = true }; + + Application.Top?.Add (otherView); // thi sets focus to otherView + Assert.True (otherView.HasFocus); + + cp.SetFocus (); + Assert.False (otherView.HasFocus); + + cp.Draw (); + + ColorBar r = GetColorBar (cp, ColorPickerPart.Bar1); + ColorBar g = GetColorBar (cp, ColorPickerPart.Bar2); + ColorBar b = GetColorBar (cp, ColorPickerPart.Bar3); + TextField hex = GetTextField (cp, ColorPickerPart.Hex); + TextField rTextField = GetTextField (cp, ColorPickerPart.Bar1); + TextField gTextField = GetTextField (cp, ColorPickerPart.Bar2); + TextField bTextField = GetTextField (cp, ColorPickerPart.Bar3); + + Assert.Equal ("R:", r.Text); + Assert.Equal (2, r.TrianglePosition); + Assert.Equal ("0", rTextField.Text); + Assert.Equal ("G:", g.Text); + Assert.Equal (2, g.TrianglePosition); + Assert.Equal ("0", gTextField.Text); + Assert.Equal ("B:", b.Text); + Assert.Equal (2, b.TrianglePosition); + Assert.Equal ("0", bTextField.Text); + Assert.Equal ("#000000", hex.Text); + + // Change value using text field + TextField rBarTextField = cp.Subviews.OfType ().First (tf => tf.Text == "0"); + + rBarTextField.SetFocus (); + rBarTextField.Text = "128"; + + otherView.SetFocus (); + Assert.True (otherView.HasFocus); + + cp.Draw (); + + Assert.Equal ("R:", r.Text); + Assert.Equal (9, r.TrianglePosition); + Assert.Equal ("128", rTextField.Text); + Assert.Equal ("G:", g.Text); + Assert.Equal (2, g.TrianglePosition); + Assert.Equal ("0", gTextField.Text); + Assert.Equal ("B:", b.Text); + Assert.Equal (2, b.TrianglePosition); + Assert.Equal ("0", bTextField.Text); + Assert.Equal ("#800000", hex.Text); + + Application.Top?.Dispose (); + } + + [Fact] + [SetupFakeDriver] + public void ColorPicker_ClickingAtEndOfBar_SetsMaxValue () + { + ColorPicker cp = GetColorPicker (ColorModel.RGB, false); + + cp.Draw (); + + // Click at the end of the Red bar + cp.Focused.RaiseMouseEvent ( + new () + { + Flags = MouseFlags.Button1Pressed, + Position = new (19, 0) // Assuming 0-based indexing + }); + + cp.Draw (); + + ColorBar r = GetColorBar (cp, ColorPickerPart.Bar1); + ColorBar g = GetColorBar (cp, ColorPickerPart.Bar2); + ColorBar b = GetColorBar (cp, ColorPickerPart.Bar3); + TextField hex = GetTextField (cp, ColorPickerPart.Hex); + + Assert.Equal ("R:", r.Text); + Assert.Equal (19, r.TrianglePosition); + Assert.Equal ("G:", g.Text); + Assert.Equal (2, g.TrianglePosition); + Assert.Equal ("B:", b.Text); + Assert.Equal (2, b.TrianglePosition); + Assert.Equal ("#FF0000", hex.Text); + + Application.Top?.Dispose (); + } + + [Fact] + [SetupFakeDriver] + public void ColorPicker_ClickingBeyondBar_ChangesToMaxValue () + { + ColorPicker cp = GetColorPicker (ColorModel.RGB, false); + + cp.Draw (); + + // Click beyond the bar + cp.Focused.RaiseMouseEvent ( + new () + { + Flags = MouseFlags.Button1Pressed, + Position = new (21, 0) // Beyond the bar + }); + + cp.Draw (); + + ColorBar r = GetColorBar (cp, ColorPickerPart.Bar1); + ColorBar g = GetColorBar (cp, ColorPickerPart.Bar2); + ColorBar b = GetColorBar (cp, ColorPickerPart.Bar3); + TextField hex = GetTextField (cp, ColorPickerPart.Hex); + + Assert.Equal ("R:", r.Text); + Assert.Equal (19, r.TrianglePosition); + Assert.Equal ("G:", g.Text); + Assert.Equal (2, g.TrianglePosition); + Assert.Equal ("B:", b.Text); + Assert.Equal (2, b.TrianglePosition); + Assert.Equal ("#FF0000", hex.Text); + + Application.Top?.Dispose (); + } + + [Fact] + [SetupFakeDriver] + public void ColorPicker_ClickingDifferentBars_ChangesFocus () + { + ColorPicker cp = GetColorPicker (ColorModel.RGB, false); + + cp.Draw (); + + // Click on Green bar + Application.RaiseMouseEvent ( + new () + { + Flags = MouseFlags.Button1Pressed, + ScreenPosition = new (0, 1) + }); + + //cp.Subviews.OfType () + // .Single () + // .OnMouseEvent ( + // new () + // { + // Flags = MouseFlags.Button1Pressed, + // Position = new (0, 1) + // }); + + cp.Draw (); + + Assert.IsAssignableFrom (cp.Focused); + + // Click on Blue bar + Application.RaiseMouseEvent ( + new () + { + Flags = MouseFlags.Button1Pressed, + ScreenPosition = new (0, 2) + }); + + //cp.Subviews.OfType () + // .Single () + // .OnMouseEvent ( + // new () + // { + // Flags = MouseFlags.Button1Pressed, + // Position = new (0, 2) + // }); + + cp.Draw (); + + Assert.IsAssignableFrom (cp.Focused); + + Application.Top?.Dispose (); + } + [Fact] [SetupFakeDriver] public void ColorPicker_Construct_DefaultValue () { - var cp = GetColorPicker (ColorModel.HSV, false); + ColorPicker cp = GetColorPicker (ColorModel.HSV, false); // Should be only a single text field (Hex) because ShowTextFields is false Assert.Single (cp.Subviews.OfType ()); @@ -18,36 +237,235 @@ public class ColorPickerTests cp.Draw (); // All bars should be at 0 with the triangle at 0 (+2 because of "H:", "S:" etc) - var h = GetColorBar (cp, ColorPickerPart.Bar1); + ColorBar h = GetColorBar (cp, ColorPickerPart.Bar1); Assert.Equal ("H:", h.Text); Assert.Equal (2, h.TrianglePosition); Assert.IsType (h); - var s = GetColorBar (cp, ColorPickerPart.Bar2); + ColorBar s = GetColorBar (cp, ColorPickerPart.Bar2); Assert.Equal ("S:", s.Text); Assert.Equal (2, s.TrianglePosition); Assert.IsType (s); - var v = GetColorBar (cp, ColorPickerPart.Bar3); + ColorBar v = GetColorBar (cp, ColorPickerPart.Bar3); Assert.Equal ("V:", v.Text); Assert.Equal (2, v.TrianglePosition); Assert.IsType (v); - var hex = GetTextField (cp, ColorPickerPart.Hex); + TextField hex = GetTextField (cp, ColorPickerPart.Hex); Assert.Equal ("#000000", hex.Text); } + [Fact] + [SetupFakeDriver] + public void ColorPicker_DisposesOldViews_OnModelChange () + { + ColorPicker cp = GetColorPicker (ColorModel.HSL, true); + + ColorBar b1 = GetColorBar (cp, ColorPickerPart.Bar1); + ColorBar b2 = GetColorBar (cp, ColorPickerPart.Bar2); + ColorBar b3 = GetColorBar (cp, ColorPickerPart.Bar3); + + TextField tf1 = GetTextField (cp, ColorPickerPart.Bar1); + TextField tf2 = GetTextField (cp, ColorPickerPart.Bar2); + TextField tf3 = GetTextField (cp, ColorPickerPart.Bar3); + + TextField hex = GetTextField (cp, ColorPickerPart.Hex); + +#if DEBUG_IDISPOSABLE + Assert.All (new View [] { b1, b2, b3, tf1, tf2, tf3, hex }, b => Assert.False (b.WasDisposed)); +#endif + cp.Style.ColorModel = ColorModel.RGB; + cp.ApplyStyleChanges (); + + ColorBar b1After = GetColorBar (cp, ColorPickerPart.Bar1); + ColorBar b2After = GetColorBar (cp, ColorPickerPart.Bar2); + ColorBar b3After = GetColorBar (cp, ColorPickerPart.Bar3); + + TextField tf1After = GetTextField (cp, ColorPickerPart.Bar1); + TextField tf2After = GetTextField (cp, ColorPickerPart.Bar2); + TextField tf3After = GetTextField (cp, ColorPickerPart.Bar3); + + TextField hexAfter = GetTextField (cp, ColorPickerPart.Hex); + + // Old bars should be disposed +#if DEBUG_IDISPOSABLE + Assert.All (new View [] { b1, b2, b3, tf1, tf2, tf3, hex }, b => Assert.True (b.WasDisposed)); +#endif + Assert.NotSame (hex, hexAfter); + + Assert.NotSame (b1, b1After); + Assert.NotSame (b2, b2After); + Assert.NotSame (b3, b3After); + + Assert.NotSame (tf1, tf1After); + Assert.NotSame (tf2, tf2After); + Assert.NotSame (tf3, tf3After); + } + + [Fact] + [SetupFakeDriver] + public void ColorPicker_EnterHexFor_ColorName () + { + ColorPicker cp = GetColorPicker (ColorModel.RGB, true, true); + Application.Navigation = new (); + Application.Top = new (); + Application.Top.Add (cp); + + cp.Draw (); + + TextField name = GetTextField (cp, ColorPickerPart.ColorName); + TextField hex = GetTextField (cp, ColorPickerPart.Hex); + + hex.SetFocus (); + + Assert.True (hex.HasFocus); + Assert.Same (hex, cp.Focused); + + hex.Text = ""; + name.Text = ""; + + Assert.Empty (hex.Text); + Assert.Empty (name.Text); + + Application.RaiseKeyDownEvent ('#'); + Assert.Empty (name.Text); + + //7FFFD4 + + Assert.Equal ("#", hex.Text); + Application.RaiseKeyDownEvent ('7'); + Application.RaiseKeyDownEvent ('F'); + Application.RaiseKeyDownEvent ('F'); + Application.RaiseKeyDownEvent ('F'); + Application.RaiseKeyDownEvent ('D'); + Assert.Empty (name.Text); + + Application.RaiseKeyDownEvent ('4'); + + Assert.True (hex.HasFocus); + + // Tab out of the hex field - should wrap to first focusable subview + Application.RaiseKeyDownEvent (Key.Tab); + Assert.False (hex.HasFocus); + Assert.NotSame (hex, cp.Focused); + + // Color name should be recognised as a known string and populated + Assert.Equal ("#7FFFD4", hex.Text); + Assert.Equal ("Aquamarine", name.Text); + + Application.Top?.Dispose (); + Application.ResetState (true); + } + + /// + /// In this version we use the Enter button to accept the typed text instead + /// of tabbing to the next view. + /// + [Fact] + [SetupFakeDriver] + public void ColorPicker_EnterHexFor_ColorName_AcceptVariation () + { + ColorPicker cp = GetColorPicker (ColorModel.RGB, true, true); + Application.Navigation = new (); + Application.Top = new (); + Application.Top.Add (cp); + + cp.Draw (); + + TextField name = GetTextField (cp, ColorPickerPart.ColorName); + TextField hex = GetTextField (cp, ColorPickerPart.Hex); + + hex.SetFocus (); + + Assert.True (hex.HasFocus); + Assert.Same (hex, cp.Focused); + + hex.Text = ""; + name.Text = ""; + + Assert.Empty (hex.Text); + Assert.Empty (name.Text); + + Application.RaiseKeyDownEvent ('#'); + Assert.Empty (name.Text); + + //7FFFD4 + + Assert.Equal ("#", hex.Text); + Application.RaiseKeyDownEvent ('7'); + Application.RaiseKeyDownEvent ('F'); + Application.RaiseKeyDownEvent ('F'); + Application.RaiseKeyDownEvent ('F'); + Application.RaiseKeyDownEvent ('D'); + Assert.Empty (name.Text); + + Application.RaiseKeyDownEvent ('4'); + + Assert.True (hex.HasFocus); + + // Should stay in the hex field (because accept not tab) + Application.RaiseKeyDownEvent (Key.Enter); + Assert.True (hex.HasFocus); + Assert.Same (hex, cp.Focused); + + // But still, Color name should be recognised as a known string and populated + Assert.Equal ("#7FFFD4", hex.Text); + Assert.Equal ("Aquamarine", name.Text); + + Application.Top?.Dispose (); + Application.ResetState (true); + } + + [Fact] + [SetupFakeDriver] + public void ColorPicker_InvalidHexInput_DoesNotChangeColor () + { + ColorPicker cp = GetColorPicker (ColorModel.RGB, true); + + cp.Draw (); + + // Enter invalid hex value + TextField hexField = cp.Subviews.OfType ().First (tf => tf.Text == "#000000"); + hexField.SetFocus (); + hexField.Text = "#ZZZZZZ"; + Assert.True (hexField.HasFocus); + Assert.Equal ("#ZZZZZZ", hexField.Text); + + ColorBar r = GetColorBar (cp, ColorPickerPart.Bar1); + ColorBar g = GetColorBar (cp, ColorPickerPart.Bar2); + ColorBar b = GetColorBar (cp, ColorPickerPart.Bar3); + TextField hex = GetTextField (cp, ColorPickerPart.Hex); + + Assert.Equal ("#ZZZZZZ", hex.Text); + + // Advance away from hexField to cause validation + cp.AdvanceFocus (NavigationDirection.Forward, null); + + cp.Draw (); + + Assert.Equal ("R:", r.Text); + Assert.Equal (2, r.TrianglePosition); + Assert.Equal ("G:", g.Text); + Assert.Equal (2, g.TrianglePosition); + Assert.Equal ("B:", b.Text); + Assert.Equal (2, b.TrianglePosition); + Assert.Equal ("#000000", hex.Text); + + Application.Top?.Dispose (); + } + [Fact] [SetupFakeDriver] public void ColorPicker_RGB_KeyboardNavigation () { - var cp = GetColorPicker (ColorModel.RGB, false); + ColorPicker cp = GetColorPicker (ColorModel.RGB, false); cp.Draw (); - var r = GetColorBar (cp, ColorPickerPart.Bar1); - var g = GetColorBar (cp, ColorPickerPart.Bar2); - var b = GetColorBar (cp, ColorPickerPart.Bar3); - var hex = GetTextField (cp, ColorPickerPart.Hex); + ColorBar r = GetColorBar (cp, ColorPickerPart.Bar1); + ColorBar g = GetColorBar (cp, ColorPickerPart.Bar2); + ColorBar b = GetColorBar (cp, ColorPickerPart.Bar3); + TextField hex = GetTextField (cp, ColorPickerPart.Hex); Assert.Equal ("R:", r.Text); Assert.Equal (2, r.TrianglePosition); @@ -79,7 +497,7 @@ public class ColorPickerTests Assert.Equal ("#1E0000", hex.Text); // Use cursor to move the triangle all the way to the right - for (int i = 0; i < 1000; i++) + for (var i = 0; i < 1000; i++) { Application.RaiseKeyDownEvent (Key.CursorRight); } @@ -98,14 +516,14 @@ public class ColorPickerTests [SetupFakeDriver] public void ColorPicker_RGB_MouseNavigation () { - var cp = GetColorPicker (ColorModel.RGB, false); + ColorPicker cp = GetColorPicker (ColorModel.RGB, false); cp.Draw (); - var r = GetColorBar (cp, ColorPickerPart.Bar1); - var g = GetColorBar (cp, ColorPickerPart.Bar2); - var b = GetColorBar (cp, ColorPickerPart.Bar3); - var hex = GetTextField (cp, ColorPickerPart.Hex); + ColorBar r = GetColorBar (cp, ColorPickerPart.Bar1); + ColorBar g = GetColorBar (cp, ColorPickerPart.Bar2); + ColorBar b = GetColorBar (cp, ColorPickerPart.Bar3); + TextField hex = GetTextField (cp, ColorPickerPart.Hex); Assert.Equal ("R:", r.Text); Assert.Equal (2, r.TrianglePosition); @@ -121,11 +539,11 @@ public class ColorPickerTests Assert.IsAssignableFrom (cp.Focused); cp.Focused.RaiseMouseEvent ( - new () - { - Flags = MouseFlags.Button1Pressed, - Position = new (3, 0) - }); + new () + { + Flags = MouseFlags.Button1Pressed, + Position = new (3, 0) + }); cp.Draw (); @@ -133,11 +551,11 @@ public class ColorPickerTests Assert.Equal ("#0F0000", hex.Text); cp.Focused.RaiseMouseEvent ( - new () - { - Flags = MouseFlags.Button1Pressed, - Position = new (4, 0) - }); + new () + { + Flags = MouseFlags.Button1Pressed, + Position = new (4, 0) + }); cp.Draw (); @@ -147,48 +565,29 @@ public class ColorPickerTests Application.Top?.Dispose (); } - - public static IEnumerable ColorPickerTestData () - { - yield return new object [] - { - new Color(255, 0), - "R:", 19, "G:", 2, "B:", 2, "#FF0000" - }; - - yield return new object [] - { - new Color(0, 255), - "R:", 2, "G:", 19, "B:", 2, "#00FF00" - }; - - yield return new object [] - { - new Color(0, 0, 255), - "R:", 2, "G:", 2, "B:", 19, "#0000FF" - }; - - yield return new object [] - { - new Color(125, 125, 125), - "R:", 11, "G:", 11, "B:", 11, "#7D7D7D" - }; - } - [Theory] [SetupFakeDriver] [MemberData (nameof (ColorPickerTestData))] - public void ColorPicker_RGB_NoText (Color c, string expectedR, int expectedRTriangle, string expectedG, int expectedGTriangle, string expectedB, int expectedBTriangle, string expectedHex) + public void ColorPicker_RGB_NoText ( + Color c, + string expectedR, + int expectedRTriangle, + string expectedG, + int expectedGTriangle, + string expectedB, + int expectedBTriangle, + string expectedHex + ) { - var cp = GetColorPicker (ColorModel.RGB, false); + ColorPicker cp = GetColorPicker (ColorModel.RGB, false); cp.SelectedColor = c; cp.Draw (); - var r = GetColorBar (cp, ColorPickerPart.Bar1); - var g = GetColorBar (cp, ColorPickerPart.Bar2); - var b = GetColorBar (cp, ColorPickerPart.Bar3); - var hex = GetTextField (cp, ColorPickerPart.Hex); + ColorBar r = GetColorBar (cp, ColorPickerPart.Bar1); + ColorBar g = GetColorBar (cp, ColorPickerPart.Bar2); + ColorBar b = GetColorBar (cp, ColorPickerPart.Bar3); + TextField hex = GetTextField (cp, ColorPickerPart.Hex); Assert.Equal (expectedR, r.Text); Assert.Equal (expectedRTriangle, r.TrianglePosition); @@ -201,50 +600,35 @@ public class ColorPickerTests Application.Top.Dispose (); } - public static IEnumerable ColorPickerTestData_WithTextFields () - { - yield return new object [] - { - new Color(255, 0), - "R:", 15, 255, "G:", 2, 0, "B:", 2, 0, "#FF0000" - }; - - yield return new object [] - { - new Color(0, 255), - "R:", 2, 0, "G:", 15, 255, "B:", 2, 0, "#00FF00" - }; - - yield return new object [] - { - new Color(0, 0, 255), - "R:", 2, 0, "G:", 2, 0, "B:", 15, 255, "#0000FF" - }; - - yield return new object [] - { - new Color(125, 125, 125), - "R:", 9, 125, "G:", 9, 125, "B:", 9, 125, "#7D7D7D" - }; - } - [Theory] [SetupFakeDriver] [MemberData (nameof (ColorPickerTestData_WithTextFields))] - public void ColorPicker_RGB_NoText_WithTextFields (Color c, string expectedR, int expectedRTriangle, int expectedRValue, string expectedG, int expectedGTriangle, int expectedGValue, string expectedB, int expectedBTriangle, int expectedBValue, string expectedHex) + public void ColorPicker_RGB_NoText_WithTextFields ( + Color c, + string expectedR, + int expectedRTriangle, + int expectedRValue, + string expectedG, + int expectedGTriangle, + int expectedGValue, + string expectedB, + int expectedBTriangle, + int expectedBValue, + string expectedHex + ) { - var cp = GetColorPicker (ColorModel.RGB, true); + ColorPicker cp = GetColorPicker (ColorModel.RGB, true); cp.SelectedColor = c; cp.Draw (); - var r = GetColorBar (cp, ColorPickerPart.Bar1); - var g = GetColorBar (cp, ColorPickerPart.Bar2); - var b = GetColorBar (cp, ColorPickerPart.Bar3); - var hex = GetTextField (cp, ColorPickerPart.Hex); - var rTextField = GetTextField (cp, ColorPickerPart.Bar1); - var gTextField = GetTextField (cp, ColorPickerPart.Bar2); - var bTextField = GetTextField (cp, ColorPickerPart.Bar3); + ColorBar r = GetColorBar (cp, ColorPickerPart.Bar1); + ColorBar g = GetColorBar (cp, ColorPickerPart.Bar2); + ColorBar b = GetColorBar (cp, ColorPickerPart.Bar3); + TextField hex = GetTextField (cp, ColorPickerPart.Hex); + TextField rTextField = GetTextField (cp, ColorPickerPart.Bar1); + TextField gTextField = GetTextField (cp, ColorPickerPart.Bar2); + TextField bTextField = GetTextField (cp, ColorPickerPart.Bar3); Assert.Equal (expectedR, r.Text); Assert.Equal (expectedRTriangle, r.TrianglePosition); @@ -260,235 +644,21 @@ public class ColorPickerTests Application.Top?.Dispose (); } - [Fact] - [SetupFakeDriver] - public void ColorPicker_ClickingAtEndOfBar_SetsMaxValue () - { - var cp = GetColorPicker (ColorModel.RGB, false); - - cp.Draw (); - - // Click at the end of the Red bar - cp.Focused.RaiseMouseEvent ( - new () - { - Flags = MouseFlags.Button1Pressed, - Position = new (19, 0) // Assuming 0-based indexing - }); - - cp.Draw (); - - var r = GetColorBar (cp, ColorPickerPart.Bar1); - var g = GetColorBar (cp, ColorPickerPart.Bar2); - var b = GetColorBar (cp, ColorPickerPart.Bar3); - var hex = GetTextField (cp, ColorPickerPart.Hex); - - Assert.Equal ("R:", r.Text); - Assert.Equal (19, r.TrianglePosition); - Assert.Equal ("G:", g.Text); - Assert.Equal (2, g.TrianglePosition); - Assert.Equal ("B:", b.Text); - Assert.Equal (2, b.TrianglePosition); - Assert.Equal ("#FF0000", hex.Text); - - Application.Top?.Dispose (); - } - - [Fact] - [SetupFakeDriver] - public void ColorPicker_ClickingBeyondBar_ChangesToMaxValue () - { - var cp = GetColorPicker (ColorModel.RGB, false); - - cp.Draw (); - - // Click beyond the bar - cp.Focused.RaiseMouseEvent ( - new () - { - Flags = MouseFlags.Button1Pressed, - Position = new (21, 0) // Beyond the bar - }); - - cp.Draw (); - - var r = GetColorBar (cp, ColorPickerPart.Bar1); - var g = GetColorBar (cp, ColorPickerPart.Bar2); - var b = GetColorBar (cp, ColorPickerPart.Bar3); - var hex = GetTextField (cp, ColorPickerPart.Hex); - - Assert.Equal ("R:", r.Text); - Assert.Equal (19, r.TrianglePosition); - Assert.Equal ("G:", g.Text); - Assert.Equal (2, g.TrianglePosition); - Assert.Equal ("B:", b.Text); - Assert.Equal (2, b.TrianglePosition); - Assert.Equal ("#FF0000", hex.Text); - - Application.Top?.Dispose (); - } - - [Fact] - [SetupFakeDriver] - public void ColorPicker_ChangeValueOnUI_UpdatesAllUIElements () - { - var cp = GetColorPicker (ColorModel.RGB, true); - - View otherView = new View () { CanFocus = true }; - - Application.Top?.Add (otherView); // thi sets focus to otherView - Assert.True (otherView.HasFocus); - - cp.SetFocus (); - Assert.False (otherView.HasFocus); - - cp.Draw (); - - var r = GetColorBar (cp, ColorPickerPart.Bar1); - var g = GetColorBar (cp, ColorPickerPart.Bar2); - var b = GetColorBar (cp, ColorPickerPart.Bar3); - var hex = GetTextField (cp, ColorPickerPart.Hex); - var rTextField = GetTextField (cp, ColorPickerPart.Bar1); - var gTextField = GetTextField (cp, ColorPickerPart.Bar2); - var bTextField = GetTextField (cp, ColorPickerPart.Bar3); - - Assert.Equal ("R:", r.Text); - Assert.Equal (2, r.TrianglePosition); - Assert.Equal ("0", rTextField.Text); - Assert.Equal ("G:", g.Text); - Assert.Equal (2, g.TrianglePosition); - Assert.Equal ("0", gTextField.Text); - Assert.Equal ("B:", b.Text); - Assert.Equal (2, b.TrianglePosition); - Assert.Equal ("0", bTextField.Text); - Assert.Equal ("#000000", hex.Text); - // Change value using text field - TextField rBarTextField = cp.Subviews.OfType ().First (tf => tf.Text == "0"); - - rBarTextField.SetFocus (); - rBarTextField.Text = "128"; - - otherView.SetFocus (); - Assert.True (otherView.HasFocus); - - cp.Draw (); - - Assert.Equal ("R:", r.Text); - Assert.Equal (9, r.TrianglePosition); - Assert.Equal ("128", rTextField.Text); - Assert.Equal ("G:", g.Text); - Assert.Equal (2, g.TrianglePosition); - Assert.Equal ("0", gTextField.Text); - Assert.Equal ("B:", b.Text); - Assert.Equal (2, b.TrianglePosition); - Assert.Equal ("0", bTextField.Text); - Assert.Equal ("#800000", hex.Text); - - Application.Top?.Dispose (); - } - - [Fact] - [SetupFakeDriver] - public void ColorPicker_InvalidHexInput_DoesNotChangeColor () - { - var cp = GetColorPicker (ColorModel.RGB, true); - - cp.Draw (); - - // Enter invalid hex value - TextField hexField = cp.Subviews.OfType ().First (tf => tf.Text == "#000000"); - hexField.SetFocus (); - hexField.Text = "#ZZZZZZ"; - Assert.True (hexField.HasFocus); - Assert.Equal ("#ZZZZZZ", hexField.Text); - - var r = GetColorBar (cp, ColorPickerPart.Bar1); - var g = GetColorBar (cp, ColorPickerPart.Bar2); - var b = GetColorBar (cp, ColorPickerPart.Bar3); - var hex = GetTextField (cp, ColorPickerPart.Hex); - - Assert.Equal ("#ZZZZZZ", hex.Text); - - // Advance away from hexField to cause validation - cp.AdvanceFocus (NavigationDirection.Forward, null); - - cp.Draw (); - - Assert.Equal ("R:", r.Text); - Assert.Equal (2, r.TrianglePosition); - Assert.Equal ("G:", g.Text); - Assert.Equal (2, g.TrianglePosition); - Assert.Equal ("B:", b.Text); - Assert.Equal (2, b.TrianglePosition); - Assert.Equal ("#000000", hex.Text); - - Application.Top?.Dispose (); - } - - [Fact] - [SetupFakeDriver] - public void ColorPicker_ClickingDifferentBars_ChangesFocus () - { - var cp = GetColorPicker (ColorModel.RGB, false); - - cp.Draw (); - - // Click on Green bar - Application.RaiseMouseEvent (new () - { - Flags = MouseFlags.Button1Pressed, - ScreenPosition = new (0, 1) - }); - //cp.Subviews.OfType () - // .Single () - // .OnMouseEvent ( - // new () - // { - // Flags = MouseFlags.Button1Pressed, - // Position = new (0, 1) - // }); - - cp.Draw (); - - Assert.IsAssignableFrom (cp.Focused); - - // Click on Blue bar - Application.RaiseMouseEvent (new () - { - Flags = MouseFlags.Button1Pressed, - ScreenPosition = new (0, 2) - }); - //cp.Subviews.OfType () - // .Single () - // .OnMouseEvent ( - // new () - // { - // Flags = MouseFlags.Button1Pressed, - // Position = new (0, 2) - // }); - - cp.Draw (); - - Assert.IsAssignableFrom (cp.Focused); - - Application.Top?.Dispose (); - } - [Fact] [SetupFakeDriver] public void ColorPicker_SwitchingColorModels_ResetsBars () { - var cp = GetColorPicker (ColorModel.RGB, false); + ColorPicker cp = GetColorPicker (ColorModel.RGB, false); cp.BeginInit (); cp.EndInit (); cp.SelectedColor = new (255, 0); cp.Draw (); - var r = GetColorBar (cp, ColorPickerPart.Bar1); - var g = GetColorBar (cp, ColorPickerPart.Bar2); - var b = GetColorBar (cp, ColorPickerPart.Bar3); - var hex = GetTextField (cp, ColorPickerPart.Hex); + ColorBar r = GetColorBar (cp, ColorPickerPart.Bar1); + ColorBar g = GetColorBar (cp, ColorPickerPart.Bar2); + ColorBar b = GetColorBar (cp, ColorPickerPart.Bar3); + TextField hex = GetTextField (cp, ColorPickerPart.Hex); Assert.Equal ("R:", r.Text); Assert.Equal (19, r.TrianglePosition); @@ -504,9 +674,9 @@ public class ColorPickerTests cp.Draw (); - var h = GetColorBar (cp, ColorPickerPart.Bar1); - var s = GetColorBar (cp, ColorPickerPart.Bar2); - var v = GetColorBar (cp, ColorPickerPart.Bar3); + ColorBar h = GetColorBar (cp, ColorPickerPart.Bar1); + ColorBar s = GetColorBar (cp, ColorPickerPart.Bar2); + ColorBar v = GetColorBar (cp, ColorPickerPart.Bar3); Assert.Equal ("H:", h.Text); Assert.Equal (2, h.TrianglePosition); @@ -523,7 +693,7 @@ public class ColorPickerTests [SetupFakeDriver] public void ColorPicker_SyncBetweenTextFieldAndBars () { - var cp = GetColorPicker (ColorModel.RGB, true); + ColorPicker cp = GetColorPicker (ColorModel.RGB, true); cp.Draw (); @@ -533,13 +703,13 @@ public class ColorPickerTests cp.Draw (); - var r = GetColorBar (cp, ColorPickerPart.Bar1); - var g = GetColorBar (cp, ColorPickerPart.Bar2); - var b = GetColorBar (cp, ColorPickerPart.Bar3); - var hex = GetTextField (cp, ColorPickerPart.Hex); - var rTextField = GetTextField (cp, ColorPickerPart.Bar1); - var gTextField = GetTextField (cp, ColorPickerPart.Bar2); - var bTextField = GetTextField (cp, ColorPickerPart.Bar3); + ColorBar r = GetColorBar (cp, ColorPickerPart.Bar1); + ColorBar g = GetColorBar (cp, ColorPickerPart.Bar2); + ColorBar b = GetColorBar (cp, ColorPickerPart.Bar3); + TextField hex = GetTextField (cp, ColorPickerPart.Hex); + TextField rTextField = GetTextField (cp, ColorPickerPart.Bar1); + TextField gTextField = GetTextField (cp, ColorPickerPart.Bar2); + TextField bTextField = GetTextField (cp, ColorPickerPart.Bar3); Assert.Equal ("R:", r.Text); Assert.Equal (9, r.TrianglePosition); @@ -555,19 +725,146 @@ public class ColorPickerTests Application.Top?.Dispose (); } - enum ColorPickerPart + [Fact] + [SetupFakeDriver] + public void ColorPicker_TabCompleteColorName () { - Bar1 = 0, - Bar2 = 1, - Bar3 = 2, - ColorName = 3, - Hex = 4, + ColorPicker cp = GetColorPicker (ColorModel.RGB, true, true); + Application.Navigation = new (); + Application.Top = new (); + Application.Top.Add (cp); + + cp.Draw (); + + ColorBar r = GetColorBar (cp, ColorPickerPart.Bar1); + ColorBar g = GetColorBar (cp, ColorPickerPart.Bar2); + ColorBar b = GetColorBar (cp, ColorPickerPart.Bar3); + TextField name = GetTextField (cp, ColorPickerPart.ColorName); + TextField hex = GetTextField (cp, ColorPickerPart.Hex); + + name.SetFocus (); + + Assert.True (name.HasFocus); + Assert.Same (name, cp.Focused); + + name.Text = ""; + Assert.Empty (name.Text); + + Application.RaiseKeyDownEvent (Key.A); + Application.RaiseKeyDownEvent (Key.Q); + + Assert.Equal ("aq", name.Text); + + // Auto complete the color name + Application.RaiseKeyDownEvent (Key.Tab); + + Assert.Equal ("Aquamarine", name.Text); + + // Tab out of the text field + Application.RaiseKeyDownEvent (Key.Tab); + + Assert.False (name.HasFocus); + Assert.NotSame (name, cp.Focused); + + Assert.Equal ("#7FFFD4", hex.Text); + + Application.Top?.Dispose (); + Application.ResetState (true); + } + + public static IEnumerable ColorPickerTestData () + { + yield return new object [] + { + new Color (255, 0), + "R:", 19, "G:", 2, "B:", 2, "#FF0000" + }; + + yield return new object [] + { + new Color (0, 255), + "R:", 2, "G:", 19, "B:", 2, "#00FF00" + }; + + yield return new object [] + { + new Color (0, 0, 255), + "R:", 2, "G:", 2, "B:", 19, "#0000FF" + }; + + yield return new object [] + { + new Color (125, 125, 125), + "R:", 11, "G:", 11, "B:", 11, "#7D7D7D" + }; + } + + public static IEnumerable ColorPickerTestData_WithTextFields () + { + yield return new object [] + { + new Color (255, 0), + "R:", 15, 255, "G:", 2, 0, "B:", 2, 0, "#FF0000" + }; + + yield return new object [] + { + new Color (0, 255), + "R:", 2, 0, "G:", 15, 255, "B:", 2, 0, "#00FF00" + }; + + yield return new object [] + { + new Color (0, 0, 255), + "R:", 2, 0, "G:", 2, 0, "B:", 15, 255, "#0000FF" + }; + + yield return new object [] + { + new Color (125, 125, 125), + "R:", 9, 125, "G:", 9, 125, "B:", 9, 125, "#7D7D7D" + }; + } + + [Fact] + public void TestColorNames () + { + var colors = new W3CColors (); + Assert.Contains ("Aquamarine", colors.GetColorNames ()); + Assert.DoesNotContain ("Save as", colors.GetColorNames ()); + } + + private ColorBar GetColorBar (ColorPicker cp, ColorPickerPart toGet) + { + if (toGet <= ColorPickerPart.Bar3) + { + return cp.Subviews.OfType ().ElementAt ((int)toGet); + } + + throw new NotSupportedException ("ColorPickerPart must be a bar"); + } + + private ColorPicker GetColorPicker (ColorModel colorModel, bool showTextFields, bool showName = false) + { + var cp = new ColorPicker { Width = 20, SelectedColor = new (0, 0) }; + cp.Style.ColorModel = colorModel; + cp.Style.ShowTextFields = showTextFields; + cp.Style.ShowColorName = showName; + cp.ApplyStyleChanges (); + + Application.Top = new() { Width = 20, Height = 5 }; + Application.Top.Add (cp); + + Application.Top.LayoutSubviews (); + Application.Top.SetFocus (); + + return cp; } private TextField GetTextField (ColorPicker cp, ColorPickerPart toGet) { - var hasBarValueTextFields = cp.Style.ShowTextFields; - var hasColorNameTextField = cp.Style.ShowColorName; + bool hasBarValueTextFields = cp.Style.ShowTextFields; + bool hasColorNameTextField = cp.Style.ShowColorName; switch (toGet) { @@ -598,277 +895,12 @@ public class ColorPickerTests } } - private ColorBar GetColorBar (ColorPicker cp, ColorPickerPart toGet) + private enum ColorPickerPart { - if (toGet <= ColorPickerPart.Bar3) - { - return cp.Subviews.OfType ().ElementAt ((int)toGet); - } - throw new NotSupportedException ("ColorPickerPart must be a bar"); - } - - [Fact] - [SetupFakeDriver] - public void ColorPicker_ChangedEvent_Fires () - { - Color newColor = default; - var count = 0; - - var cp = new ColorPicker (); - - cp.ColorChanged += (s, e) => - { - count++; - newColor = e.CurrentValue; - - Assert.Equal (cp.SelectedColor, e.CurrentValue); - }; - - cp.SelectedColor = new (1, 2, 3); - Assert.Equal (1, count); - Assert.Equal (new (1, 2, 3), newColor); - - cp.SelectedColor = new (2, 3, 4); - - Assert.Equal (2, count); - Assert.Equal (new (2, 3, 4), newColor); - - // Set to same value - cp.SelectedColor = new (2, 3, 4); - - // Should have no effect - Assert.Equal (2, count); - } - - [Fact] - [SetupFakeDriver] - public void ColorPicker_DisposesOldViews_OnModelChange () - { - var cp = GetColorPicker (ColorModel.HSL, true); - - var b1 = GetColorBar (cp, ColorPickerPart.Bar1); - var b2 = GetColorBar (cp, ColorPickerPart.Bar2); - var b3 = GetColorBar (cp, ColorPickerPart.Bar3); - - var tf1 = GetTextField (cp, ColorPickerPart.Bar1); - var tf2 = GetTextField (cp, ColorPickerPart.Bar2); - var tf3 = GetTextField (cp, ColorPickerPart.Bar3); - - var hex = GetTextField (cp, ColorPickerPart.Hex); - -#if DEBUG_IDISPOSABLE - Assert.All (new View [] { b1, b2, b3, tf1, tf2, tf3, hex }, b => Assert.False (b.WasDisposed)); -#endif - cp.Style.ColorModel = ColorModel.RGB; - cp.ApplyStyleChanges (); - - var b1After = GetColorBar (cp, ColorPickerPart.Bar1); - var b2After = GetColorBar (cp, ColorPickerPart.Bar2); - var b3After = GetColorBar (cp, ColorPickerPart.Bar3); - - var tf1After = GetTextField (cp, ColorPickerPart.Bar1); - var tf2After = GetTextField (cp, ColorPickerPart.Bar2); - var tf3After = GetTextField (cp, ColorPickerPart.Bar3); - - var hexAfter = GetTextField (cp, ColorPickerPart.Hex); - - // Old bars should be disposed -#if DEBUG_IDISPOSABLE - Assert.All (new View [] { b1, b2, b3, tf1, tf2, tf3, hex }, b => Assert.True (b.WasDisposed)); -#endif - Assert.NotSame (hex, hexAfter); - - Assert.NotSame (b1, b1After); - Assert.NotSame (b2, b2After); - Assert.NotSame (b3, b3After); - - Assert.NotSame (tf1, tf1After); - Assert.NotSame (tf2, tf2After); - Assert.NotSame (tf3, tf3After); - - } - - [Fact] - [SetupFakeDriver] - public void ColorPicker_TabCompleteColorName () - { - var cp = GetColorPicker (ColorModel.RGB, true, true); - Application.Navigation = new (); - Application.Top = new (); - Application.Top.Add (cp); - - cp.Draw (); - - var r = GetColorBar (cp, ColorPickerPart.Bar1); - var g = GetColorBar (cp, ColorPickerPart.Bar2); - var b = GetColorBar (cp, ColorPickerPart.Bar3); - var name = GetTextField (cp, ColorPickerPart.ColorName); - var hex = GetTextField (cp, ColorPickerPart.Hex); - - name.SetFocus (); - - Assert.True (name.HasFocus); - Assert.Same (name, cp.Focused); - - name.Text = ""; - Assert.Empty (name.Text); - - Application.RaiseKeyDownEvent (Key.A); - Application.RaiseKeyDownEvent (Key.Q); - - Assert.Equal ("aq", name.Text); - - - // Auto complete the color name - Application.RaiseKeyDownEvent (Key.Tab); - - Assert.Equal ("Aquamarine", name.Text); - - // Tab out of the text field - Application.RaiseKeyDownEvent (Key.Tab); - - Assert.False (name.HasFocus); - Assert.NotSame (name, cp.Focused); - - Assert.Equal ("#7FFFD4", hex.Text); - - Application.Top?.Dispose (); - Application.ResetState (ignoreDisposed: true); - } - - [Fact] - [SetupFakeDriver] - public void ColorPicker_EnterHexFor_ColorName () - { - var cp = GetColorPicker (ColorModel.RGB, true, true); - Application.Navigation = new (); - Application.Top = new (); - Application.Top.Add (cp); - - cp.Draw (); - - var name = GetTextField (cp, ColorPickerPart.ColorName); - var hex = GetTextField (cp, ColorPickerPart.Hex); - - hex.SetFocus (); - - Assert.True (hex.HasFocus); - Assert.Same (hex, cp.Focused); - - hex.Text = ""; - name.Text = ""; - - Assert.Empty (hex.Text); - Assert.Empty (name.Text); - - Application.RaiseKeyDownEvent ('#'); - Assert.Empty (name.Text); - //7FFFD4 - - Assert.Equal ("#", hex.Text); - Application.RaiseKeyDownEvent ('7'); - Application.RaiseKeyDownEvent ('F'); - Application.RaiseKeyDownEvent ('F'); - Application.RaiseKeyDownEvent ('F'); - Application.RaiseKeyDownEvent ('D'); - Assert.Empty (name.Text); - - Application.RaiseKeyDownEvent ('4'); - - Assert.True (hex.HasFocus); - - // Tab out of the hex field - should wrap to first focusable subview - Application.RaiseKeyDownEvent (Key.Tab); - Assert.False (hex.HasFocus); - Assert.NotSame (hex, cp.Focused); - - // Color name should be recognised as a known string and populated - Assert.Equal ("#7FFFD4", hex.Text); - Assert.Equal ("Aquamarine", name.Text); - - Application.Top?.Dispose (); - Application.ResetState (ignoreDisposed: true); - } - - /// - /// In this version we use the Enter button to accept the typed text instead - /// of tabbing to the next view. - /// - [Fact] - [SetupFakeDriver] - public void ColorPicker_EnterHexFor_ColorName_AcceptVariation () - { - var cp = GetColorPicker (ColorModel.RGB, true, true); - Application.Navigation = new (); - Application.Top = new (); - Application.Top.Add (cp); - - cp.Draw (); - - var name = GetTextField (cp, ColorPickerPart.ColorName); - var hex = GetTextField (cp, ColorPickerPart.Hex); - - hex.SetFocus (); - - Assert.True (hex.HasFocus); - Assert.Same (hex, cp.Focused); - - hex.Text = ""; - name.Text = ""; - - Assert.Empty (hex.Text); - Assert.Empty (name.Text); - - Application.RaiseKeyDownEvent ('#'); - Assert.Empty (name.Text); - //7FFFD4 - - Assert.Equal ("#", hex.Text); - Application.RaiseKeyDownEvent ('7'); - Application.RaiseKeyDownEvent ('F'); - Application.RaiseKeyDownEvent ('F'); - Application.RaiseKeyDownEvent ('F'); - Application.RaiseKeyDownEvent ('D'); - Assert.Empty (name.Text); - - Application.RaiseKeyDownEvent ('4'); - - Assert.True (hex.HasFocus); - - // Should stay in the hex field (because accept not tab) - Application.RaiseKeyDownEvent (Key.Enter); - Assert.True (hex.HasFocus); - Assert.Same (hex, cp.Focused); - - // But still, Color name should be recognised as a known string and populated - Assert.Equal ("#7FFFD4", hex.Text); - Assert.Equal ("Aquamarine", name.Text); - - Application.Top?.Dispose (); - Application.ResetState (ignoreDisposed: true); - } - - [Fact] - public void TestColorNames () - { - var colors = new W3CColors (); - Assert.Contains ("Aquamarine", colors.GetColorNames ()); - Assert.DoesNotContain ("Save as", colors.GetColorNames ()); - } - private ColorPicker GetColorPicker (ColorModel colorModel, bool showTextFields, bool showName = false) - { - var cp = new ColorPicker { Width = 20, SelectedColor = new (0, 0) }; - cp.Style.ColorModel = colorModel; - cp.Style.ShowTextFields = showTextFields; - cp.Style.ShowColorName = showName; - cp.ApplyStyleChanges (); - - Application.Top = new Toplevel () { Width = 20, Height = 5 }; - Application.Top.Add (cp); - - Application.Top.LayoutSubviews (); - Application.Top.SetFocus (); - - return cp; + Bar1 = 0, + Bar2 = 1, + Bar3 = 2, + ColorName = 3, + Hex = 4 } } diff --git a/UnitTests/Views/ComboBoxTests.cs b/Tests/UnitTests/Views/ComboBoxTests.cs similarity index 98% rename from UnitTests/Views/ComboBoxTests.cs rename to Tests/UnitTests/Views/ComboBoxTests.cs index 839b3ece7..bec3a7578 100644 --- a/UnitTests/Views/ComboBoxTests.cs +++ b/Tests/UnitTests/Views/ComboBoxTests.cs @@ -1,4 +1,6 @@ using System.Collections.ObjectModel; +using UnitTests; +using UnitTests; using Xunit.Abstractions; namespace Terminal.Gui.ViewsTests; @@ -529,7 +531,7 @@ public class ComboBoxTests (ITestOutputHelper output) cb.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ▼ One @@ -550,7 +552,7 @@ Three ", cb.Subviews [1].GetNormalColor () }; - TestHelpers.AssertDriverAttributesAre ( + DriverAssert.AssertDriverAttributesAre ( @" 000000 222222 @@ -569,7 +571,7 @@ Three ", View.SetClipToScreen (); cb.Draw (); - TestHelpers.AssertDriverAttributesAre ( + DriverAssert.AssertDriverAttributesAre ( @" 000000 222222 @@ -588,7 +590,7 @@ Three ", View.SetClipToScreen (); cb.Draw (); - TestHelpers.AssertDriverAttributesAre ( + DriverAssert.AssertDriverAttributesAre ( @" 000000 222222 @@ -613,7 +615,7 @@ Three ", View.SetClipToScreen (); cb.Draw (); - TestHelpers.AssertDriverAttributesAre ( + DriverAssert.AssertDriverAttributesAre ( @" 000000 222222 @@ -632,7 +634,7 @@ Three ", View.SetClipToScreen (); cb.Draw (); - TestHelpers.AssertDriverAttributesAre ( + DriverAssert.AssertDriverAttributesAre ( @" 000000 222222 @@ -651,7 +653,7 @@ Three ", View.SetClipToScreen (); cb.Draw (); - TestHelpers.AssertDriverAttributesAre ( + DriverAssert.AssertDriverAttributesAre ( @" 000000 000002 @@ -915,7 +917,7 @@ Three ", Assert.Equal ("One", cb.Text); cb.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" One ▼ One @@ -930,7 +932,7 @@ One View.SetClipToScreen (); cb.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" Two ▼ Two @@ -945,7 +947,7 @@ Two View.SetClipToScreen (); cb.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" Three ▼ Three diff --git a/UnitTests/Views/ContextMenuTests.cs b/Tests/UnitTests/Views/ContextMenuTests.cs similarity index 96% rename from UnitTests/Views/ContextMenuTests.cs rename to Tests/UnitTests/Views/ContextMenuTests.cs index 8fa24b729..ec555edac 100644 --- a/UnitTests/Views/ContextMenuTests.cs +++ b/Tests/UnitTests/Views/ContextMenuTests.cs @@ -1,4 +1,6 @@ using System.Globalization; +using UnitTests; +using UnitTests; using Xunit.Abstractions; namespace Terminal.Gui.ViewsTests; @@ -133,7 +135,7 @@ public class ContextMenuTests (ITestOutputHelper output) ((FakeDriver)Application.Driver!).SetBufferSize (20, 15); Assert.Equal (new Rectangle (0, 0, 20, 15), View.GetClip ()!.GetBounds ()); - TestHelpers.AssertDriverContentsWithFrameAre ("", output); + DriverAssert.AssertDriverContentsWithFrameAre ("", output); var top = new Toplevel { X = 2, Y = 2, Width = 15, Height = 4 }; top.Add (new TextField { X = Pos.Center (), Width = 10, Text = "Test" }); @@ -143,7 +145,7 @@ public class ContextMenuTests (ITestOutputHelper output) Assert.Equal (new Rectangle (2, 2, 15, 4), top.Frame); Assert.Equal (top, Application.Top); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" Test", output @@ -153,7 +155,7 @@ public class ContextMenuTests (ITestOutputHelper output) Application.RunIteration (ref rs); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" Test ┌─────────────────── @@ -184,7 +186,7 @@ public class ContextMenuTests (ITestOutputHelper output) Assert.Equal (new Rectangle (0, 0, 20, 15), win.Frame); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌──────────────────┐ │ │ @@ -212,7 +214,7 @@ public class ContextMenuTests (ITestOutputHelper output) Assert.Equal (new Rectangle (2, 2, 15, 4), testWindow.Frame); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌──────────────────┐ │ │ @@ -236,7 +238,7 @@ public class ContextMenuTests (ITestOutputHelper output) Application.RunIteration (ref rsDialog); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌──────────────────┐ │ │ @@ -268,7 +270,7 @@ public class ContextMenuTests (ITestOutputHelper output) ((FakeDriver)Application.Driver!).SetBufferSize (20, 15); Assert.Equal (new Rectangle (0, 0, 20, 15), View.GetClip ()!.GetBounds ()); - TestHelpers.AssertDriverContentsWithFrameAre ("", output); + DriverAssert.AssertDriverContentsWithFrameAre ("", output); // Don't use Dialog here as it has more layout logic. Use Window instead. var dialog = new Window { X = 2, Y = 2, Width = 15, Height = 4 }; @@ -279,7 +281,7 @@ public class ContextMenuTests (ITestOutputHelper output) Assert.Equal (new Rectangle (2, 2, 15, 4), dialog.Frame); Assert.Equal (dialog, Application.Top); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌─────────────┐ │ Test │ @@ -293,7 +295,7 @@ public class ContextMenuTests (ITestOutputHelper output) var firstIteration = false; Application.RunIteration (ref rs, firstIteration); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌─────────────┐ │ Test │ @@ -344,7 +346,7 @@ public class ContextMenuTests (ITestOutputHelper output) └──────┘ "; - Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Rectangle pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new Rectangle (0, 1, 8, 4), pos); cm.ForceMinimumPosToZero = false; @@ -358,7 +360,7 @@ public class ContextMenuTests (ITestOutputHelper output) ──────┘ "; - pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new Rectangle (1, 0, 7, 3), pos); top.Dispose (); } @@ -451,7 +453,7 @@ public class ContextMenuTests (ITestOutputHelper output) └──────┘ "; - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); menuItems = new MenuBarItem ( [ @@ -472,7 +474,7 @@ public class ContextMenuTests (ITestOutputHelper output) └─────────┘ "; - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); top.Dispose (); } @@ -516,7 +518,7 @@ public class ContextMenuTests (ITestOutputHelper output) Assert.Equal (new Point (-1, -2), cm.Position); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌────────┐ │ One │ @@ -539,7 +541,7 @@ public class ContextMenuTests (ITestOutputHelper output) Application.RunIteration (ref rs); Assert.Equal (new Point (-1, -2), cm.Position); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌────────┐ │ One │ @@ -564,7 +566,7 @@ public class ContextMenuTests (ITestOutputHelper output) Application.RunIteration (ref rs); Assert.Equal (new Point (41, -2), cm.Position); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌────────┐ │ One │ @@ -587,7 +589,7 @@ public class ContextMenuTests (ITestOutputHelper output) Application.RunIteration (ref rs); Assert.Equal (new Point (41, -2), cm.Position); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌────────┐ │ One │ @@ -611,7 +613,7 @@ public class ContextMenuTests (ITestOutputHelper output) Application.RunIteration (ref rs); Assert.Equal (new Point (41, 9), cm.Position); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌────────┐ │ One │ @@ -634,7 +636,7 @@ public class ContextMenuTests (ITestOutputHelper output) Application.RunIteration (ref rs); Assert.Equal (new Point (41, 9), cm.Position); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌────────┐ ┌───────────┐│ One │ @@ -655,7 +657,7 @@ public class ContextMenuTests (ITestOutputHelper output) Application.RunIteration (ref rs); Assert.Equal (new Point (41, 22), cm.Position); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌────────┐ │ One │ @@ -678,7 +680,7 @@ public class ContextMenuTests (ITestOutputHelper output) Application.RunIteration (ref rs); Assert.Equal (new Point (41, 22), cm.Position); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌───────────┐ │ SubMenu1 │┌────────┐ @@ -699,7 +701,7 @@ public class ContextMenuTests (ITestOutputHelper output) Application.RunIteration (ref rs); Assert.Equal (new Point (19, 10), cm.Position); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌────────┐ │ One │ @@ -722,7 +724,7 @@ public class ContextMenuTests (ITestOutputHelper output) Application.RunIteration (ref rs); Assert.Equal (new Point (19, 10), cm.Position); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌───────────┐────┐ │ SubMenu1 │ │ @@ -809,7 +811,7 @@ public class ContextMenuTests (ITestOutputHelper output) └──────┘ "; - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); cm.Position = new Point (5, 10); @@ -823,7 +825,7 @@ public class ContextMenuTests (ITestOutputHelper output) └──────┘ "; - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); top.Dispose (); } @@ -942,7 +944,7 @@ public class ContextMenuTests (ITestOutputHelper output) │ One │ │ Two │"; - Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Rectangle pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new Rectangle (0, 0, 8, 3), pos); cm.Hide (); @@ -981,7 +983,7 @@ public class ContextMenuTests (ITestOutputHelper output) │ Two └────"; - Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Rectangle pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new Rectangle (0, 1, 5, 4), pos); cm.Hide (); @@ -1032,7 +1034,7 @@ public class ContextMenuTests (ITestOutputHelper output) └──────┘ "; - Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Rectangle pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new Rectangle (10, 5, 18, 5), pos); cm.Hide (); @@ -1056,7 +1058,7 @@ public class ContextMenuTests (ITestOutputHelper output) └──────┘ "; - pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new Rectangle (5, 10, 13, 7), pos); cm.Hide (); @@ -1094,7 +1096,7 @@ public class ContextMenuTests (ITestOutputHelper output) └──────┘ "; - Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Rectangle pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new Rectangle (72, 21, 80, 4), pos); cm.Hide (); @@ -1145,7 +1147,7 @@ public class ContextMenuTests (ITestOutputHelper output) View "; - Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Rectangle pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new Rectangle (70, 20, 78, 5), pos); cm.Hide (); @@ -1179,7 +1181,7 @@ public class ContextMenuTests (ITestOutputHelper output) └──────┘ "; - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); cm.Hide (); Assert.False (ContextMenu.IsShow); @@ -1188,7 +1190,7 @@ public class ContextMenuTests (ITestOutputHelper output) expected = ""; - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); top.Dispose (); } @@ -1226,7 +1228,7 @@ public class ContextMenuTests (ITestOutputHelper output) Assert.Equal (new Rectangle (5, 11, 10, 5), Application.Top!.Subviews [0].Frame); Application.LayoutAndDraw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌────────┐ │ One │ @@ -1244,7 +1246,7 @@ public class ContextMenuTests (ITestOutputHelper output) Assert.Equal (new Rectangle (5, 11, 10, 5), Application.Top.Subviews [0].Frame); Assert.Equal (new Rectangle (5, 11, 15, 6), Application.Top.Subviews [1].Frame); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌─────────────┐ │◄ Two │ @@ -1261,7 +1263,7 @@ public class ContextMenuTests (ITestOutputHelper output) Application.RunIteration (ref rs, firstIteration); Assert.Equal (new Rectangle (5, 11, 10, 5), Application.Top.Subviews [0].Frame); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌────────┐ │ One │ @@ -1319,7 +1321,7 @@ public class ContextMenuTests (ITestOutputHelper output) Assert.Equal (new Rectangle (5, 11, 10, 5), Application.Top.Subviews [0].Frame); Application.LayoutAndDraw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌────────┐ │ One │ @@ -1335,7 +1337,7 @@ public class ContextMenuTests (ITestOutputHelper output) Application.RunIteration (ref rs, firstIteration); Assert.Equal (new Rectangle (5, 11, 10, 5), Application.Top.Subviews [0].Frame); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌────────┐ │ One │ @@ -1352,7 +1354,7 @@ public class ContextMenuTests (ITestOutputHelper output) Application.RunIteration (ref rs, firstIteration); Assert.Equal (new Rectangle (5, 11, 10, 5), Application.Top.Subviews [0].Frame); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌────────┐ │ One │ @@ -1370,7 +1372,7 @@ public class ContextMenuTests (ITestOutputHelper output) Application.RunIteration (ref rs, firstIteration); Assert.Equal (new Rectangle (5, 11, 10, 5), Application.Top.Subviews [0].Frame); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌────────┐ │ One │ diff --git a/UnitTests/Views/DateFieldTests.cs b/Tests/UnitTests/Views/DateFieldTests.cs similarity index 99% rename from UnitTests/Views/DateFieldTests.cs rename to Tests/UnitTests/Views/DateFieldTests.cs index 574eb246a..851ed6c1b 100644 --- a/UnitTests/Views/DateFieldTests.cs +++ b/Tests/UnitTests/Views/DateFieldTests.cs @@ -1,5 +1,6 @@ using System.Globalization; using System.Runtime.InteropServices; +using UnitTests; namespace Terminal.Gui.ViewsTests; diff --git a/UnitTests/Views/DatePickerTests.cs b/Tests/UnitTests/Views/DatePickerTests.cs similarity index 99% rename from UnitTests/Views/DatePickerTests.cs rename to Tests/UnitTests/Views/DatePickerTests.cs index 75761d94f..85096ec4d 100644 --- a/UnitTests/Views/DatePickerTests.cs +++ b/Tests/UnitTests/Views/DatePickerTests.cs @@ -1,4 +1,5 @@ using System.Globalization; +using UnitTests; namespace Terminal.Gui.ViewsTests; diff --git a/UnitTests/Views/FrameViewTests.cs b/Tests/UnitTests/Views/FrameViewTests.cs similarity index 88% rename from UnitTests/Views/FrameViewTests.cs rename to Tests/UnitTests/Views/FrameViewTests.cs index ee43d04e8..0d559919e 100644 --- a/UnitTests/Views/FrameViewTests.cs +++ b/Tests/UnitTests/Views/FrameViewTests.cs @@ -1,4 +1,6 @@ -using Xunit.Abstractions; +using UnitTests; +using UnitTests; +using Xunit.Abstractions; namespace Terminal.Gui.ViewsTests; @@ -45,14 +47,14 @@ public class FrameViewTests (ITestOutputHelper output) top.Add (fv); Application.Begin (top); Assert.Equal (new (0, 0, 0, 0), fv.Frame); - TestHelpers.AssertDriverContentsWithFrameAre (@"", output); + DriverAssert.AssertDriverContentsWithFrameAre (@"", output); fv.Height = 5; fv.Width = 5; Assert.Equal (new (0, 0, 5, 5), fv.Frame); Application.LayoutAndDraw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌───┐ │ │ @@ -67,7 +69,7 @@ public class FrameViewTests (ITestOutputHelper output) Assert.Equal (new (1, 2, 5, 5), fv.Frame); Application.LayoutAndDraw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌───┐ │ │ @@ -82,7 +84,7 @@ public class FrameViewTests (ITestOutputHelper output) Assert.Equal (new (-1, -2, 5, 5), fv.Frame); Application.LayoutAndDraw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" │ │ @@ -95,7 +97,7 @@ public class FrameViewTests (ITestOutputHelper output) Assert.Equal (new (7, 8, 5, 5), fv.Frame); Application.LayoutAndDraw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌── │ ", diff --git a/UnitTests/Views/GraphViewTests.cs b/Tests/UnitTests/Views/GraphViewTests.cs similarity index 97% rename from UnitTests/Views/GraphViewTests.cs rename to Tests/UnitTests/Views/GraphViewTests.cs index 4a7fe4a06..ef5230f66 100644 --- a/UnitTests/Views/GraphViewTests.cs +++ b/Tests/UnitTests/Views/GraphViewTests.cs @@ -1,5 +1,7 @@ using System.Text; +using UnitTests; using Terminal.Gui.ViewMouseTests; +using UnitTests; using Xunit.Abstractions; namespace Terminal.Gui.ViewsTests; @@ -705,7 +707,7 @@ public class MultiBarSeriesTests │ MM MM MM ┼──┬M──┬M──┬M────── heytherebob "; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); // Shutdown must be called to safely clean up Application if Init has been called Application.Shutdown (); @@ -1123,7 +1125,7 @@ public class TextAnnotationTests 0┼┬┬┬┬┬┬┬┬ 0 5"; - TestHelpers.AssertDriverContentsAre (expected, _output); + DriverAssert.AssertDriverContentsAre (expected, _output); // Shutdown must be called to safely clean up Application if Init has been called Application.Shutdown (); @@ -1149,7 +1151,7 @@ public class TextAnnotationTests 0┼┬┬┬┬┬┬┬┬ 0 5"; - TestHelpers.AssertDriverContentsAre (expected, _output); + DriverAssert.AssertDriverContentsAre (expected, _output); // user scrolls up one unit of graph space gv.ScrollOffset = new PointF (0, 1f); @@ -1169,7 +1171,7 @@ public class TextAnnotationTests 1┼┬┬┬┬┬┬┬┬ 0 5"; - TestHelpers.AssertDriverContentsAre (expected, _output); + DriverAssert.AssertDriverContentsAre (expected, _output); // Shutdown must be called to safely clean up Application if Init has been called Application.Shutdown (); @@ -1203,7 +1205,7 @@ public class TextAnnotationTests 0┼┬┬┬┬┬┬┬┬ 0 5"; - TestHelpers.AssertDriverContentsAre (expected, _output); + DriverAssert.AssertDriverContentsAre (expected, _output); // Shutdown must be called to safely clean up Application if Init has been called Application.Shutdown (); @@ -1233,7 +1235,7 @@ public class TextAnnotationTests 0┼┬┬┬┬┬┬┬┬ 0 5"; - TestHelpers.AssertDriverContentsAre (expected, _output); + DriverAssert.AssertDriverContentsAre (expected, _output); // Shutdown must be called to safely clean up Application if Init has been called Application.Shutdown (); @@ -1259,7 +1261,7 @@ public class TextAnnotationTests 0┼┬┬┬┬┬┬┬┬ 0 5"; - TestHelpers.AssertDriverContentsAre (expected, _output); + DriverAssert.AssertDriverContentsAre (expected, _output); // user scrolls up one unit of graph space gv.ScrollOffset = new PointF (0, 1f); @@ -1278,7 +1280,7 @@ public class TextAnnotationTests 1┼┬┬┬┬┬┬┬┬ 0 5"; - TestHelpers.AssertDriverContentsAre (expected, _output); + DriverAssert.AssertDriverContentsAre (expected, _output); // user scrolls up one unit of graph space gv.ScrollOffset = new PointF (0, 1f); @@ -1297,7 +1299,7 @@ public class TextAnnotationTests 1┼┬┬┬┬┬┬┬┬ 0 5"; - TestHelpers.AssertDriverContentsAre (expected, _output); + DriverAssert.AssertDriverContentsAre (expected, _output); // Shutdown must be called to safely clean up Application if Init has been called Application.Shutdown (); @@ -1349,7 +1351,7 @@ public class LegendTests 0┼┬┬┬┬┬┬┬┬ 0 5"; - TestHelpers.AssertDriverContentsAre (expected, _output); + DriverAssert.AssertDriverContentsAre (expected, _output); // Shutdown must be called to safely clean up Application if Init has been called Application.Shutdown (); @@ -1378,7 +1380,7 @@ public class LegendTests 0┼┬┬┬┬┬┬┬┬ 0 5"; - TestHelpers.AssertDriverContentsAre (expected, _output); + DriverAssert.AssertDriverContentsAre (expected, _output); // Shutdown must be called to safely clean up Application if Init has been called Application.Shutdown (); @@ -1409,7 +1411,7 @@ public class PathAnnotationTests "; - TestHelpers.AssertDriverContentsAre (expected, _output); + DriverAssert.AssertDriverContentsAre (expected, _output); // Shutdown must be called to safely clean up Application if Init has been called Application.Shutdown (); @@ -1434,7 +1436,7 @@ public class PathAnnotationTests "; - TestHelpers.AssertDriverContentsAre (expected, _output); + DriverAssert.AssertDriverContentsAre (expected, _output); // Shutdown must be called to safely clean up Application if Init has been called Application.Shutdown (); @@ -1467,7 +1469,7 @@ public class PathAnnotationTests 0┼┬┬┬┬┬┬┬┬ 0 5"; - TestHelpers.AssertDriverContentsAre (expected, _output); + DriverAssert.AssertDriverContentsAre (expected, _output); // Shutdown must be called to safely clean up Application if Init has been called Application.Shutdown (); @@ -1500,7 +1502,7 @@ public class PathAnnotationTests 0┼┬┬┬┬┬┬┬┬ 0 5"; - TestHelpers.AssertDriverContentsAre (expected, _output); + DriverAssert.AssertDriverContentsAre (expected, _output); // Shutdown must be called to safely clean up Application if Init has been called Application.Shutdown (); @@ -1548,7 +1550,7 @@ public class PathAnnotationTests mount.Draw (); // should have the initial text - TestHelpers.AssertDriverContentsAre ("ff", null); + DriverAssert.AssertDriverContentsAre ("ff", null); // change the text and redraw view.Text = "ff1234"; @@ -1557,7 +1559,7 @@ public class PathAnnotationTests mount.Draw (); // should have the new text rendered - TestHelpers.AssertDriverContentsAre ("ff1234", null); + DriverAssert.AssertDriverContentsAre ("ff1234", null); } finally { @@ -1599,7 +1601,7 @@ public class PathAnnotationTests 0 5 "; - TestHelpers.AssertDriverContentsAre (expected, _output); + DriverAssert.AssertDriverContentsAre (expected, _output); // Shutdown must be called to safely clean up Application if Init has been called Application.Shutdown (); @@ -1636,7 +1638,7 @@ public class PathAnnotationTests 0 5 "; - TestHelpers.AssertDriverContentsAre (expected, _output); + DriverAssert.AssertDriverContentsAre (expected, _output); // Shutdown must be called to safely clean up Application if Init has been called Application.Shutdown (); diff --git a/UnitTests/Views/HexViewTests.cs b/Tests/UnitTests/Views/HexViewTests.cs similarity index 100% rename from UnitTests/Views/HexViewTests.cs rename to Tests/UnitTests/Views/HexViewTests.cs diff --git a/UnitTests/Views/LabelTests.cs b/Tests/UnitTests/Views/LabelTests.cs similarity index 95% rename from UnitTests/Views/LabelTests.cs rename to Tests/UnitTests/Views/LabelTests.cs index 061e4b7bd..03d8369ea 100644 --- a/UnitTests/Views/LabelTests.cs +++ b/Tests/UnitTests/Views/LabelTests.cs @@ -1,5 +1,7 @@ using System.ComponentModel; using Microsoft.VisualStudio.TestPlatform.ObjectModel; +using UnitTests; +using UnitTests; using Xunit.Abstractions; namespace Terminal.Gui.ViewsTests; @@ -113,7 +115,7 @@ public class LabelTests (ITestOutputHelper output) └────────────────────────────┘ "; - TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + DriverAssert.AssertDriverContentsWithFrameAre (expected, output); label.Text = "Say Hello 你 changed"; @@ -127,7 +129,7 @@ public class LabelTests (ITestOutputHelper output) └────────────────────────────┘ "; - TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + DriverAssert.AssertDriverContentsWithFrameAre (expected, output); top.Dispose (); } @@ -153,7 +155,7 @@ public class LabelTests (ITestOutputHelper output) └────────────────────────────┘ "; - TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + DriverAssert.AssertDriverContentsWithFrameAre (expected, output); label.Text = "Say Hello 你 changed"; @@ -167,7 +169,7 @@ public class LabelTests (ITestOutputHelper output) └────────────────────────────┘ "; - TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + DriverAssert.AssertDriverContentsWithFrameAre (expected, output); top.Dispose (); } @@ -209,7 +211,7 @@ public class LabelTests (ITestOutputHelper output) tf2.Draw (new (new (0, 2), tfSize), label.GetNormalColor (), label.ColorScheme.HotNormal); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" This label needs to be cleared before rewritten. This TextFormatter (tf1) without fill will not be cleared on rewritten. @@ -232,7 +234,7 @@ This TextFormatter (tf2) with fill will be cleared on rewritten. ", tf2.Text = "This TextFormatter (tf2) is rewritten."; tf2.Draw (new (new (0, 2), tfSize), label.GetNormalColor (), label.ColorScheme.HotNormal); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" This label is rewritten. This TextFormatter (tf1) is rewritten.will not be cleared on rewritten. @@ -258,7 +260,7 @@ This TextFormatter (tf2) is rewritten. ", Demo Simple Rune "; - Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Rectangle pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (0, 0, 16, 1), pos); top.Dispose (); } @@ -294,7 +296,7 @@ n e "; - Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Rectangle pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (0, 0, 1, 16), pos); top.Dispose (); } @@ -319,7 +321,7 @@ e ズ "; - Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Rectangle pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (0, 0, 2, 7), pos); top.Dispose (); } @@ -406,7 +408,7 @@ e │ │ └────────────────────────────┘ "; - Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Rectangle pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (0, 0, 30, 5), pos); top.Dispose (); } @@ -439,7 +441,7 @@ e └────────────────────────────┘ "; - Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Rectangle pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (0, 0, 30, 5), pos); top.Dispose (); } @@ -458,7 +460,7 @@ e label.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌┤Te├┐ │Test│ @@ -484,7 +486,7 @@ e Assert.Equal (new (0, 0, 4, 1), label.Viewport); Application.Begin (top); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" │Test│ └────┘", @@ -507,7 +509,7 @@ e Assert.Equal (new (0, 0, 4, 1), label.Viewport); Application.Begin (top); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" │Test│ └────┘", @@ -881,7 +883,7 @@ e " ; - TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Application.End (rs); top.Dispose (); } @@ -928,7 +930,7 @@ e └──────────────────────────────────────┘ "; - TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Application.End (rs); top.Dispose (); } @@ -982,7 +984,7 @@ e if (k.KeyCode == KeyCode.Enter) { ((FakeDriver)Application.Driver!).SetBufferSize (22, count + 4); - Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expecteds [count], output); + Rectangle pos = DriverAssert.AssertDriverContentsWithFrameAre (expecteds [count], output); Assert.Equal (new (0, 0, 22, count + 4), pos); if (count > 0) @@ -1076,7 +1078,7 @@ e └────────┘ "; - Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Rectangle pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (0, 0, 10, 4), pos); text = "0123456789"; @@ -1105,7 +1107,7 @@ e └────────┘ "; - pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (0, 0, 10, 4), pos); } @@ -1133,7 +1135,7 @@ e if (k.KeyCode == KeyCode.Enter) { ((FakeDriver)Application.Driver!).SetBufferSize (22, count + 4); - Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expecteds [count], output); + Rectangle pos = DriverAssert.AssertDriverContentsWithFrameAre (expecteds [count], output); Assert.Equal (new (0, 0, 22, count + 4), pos); if (count < 20) @@ -1223,7 +1225,7 @@ e └────────┘ "; - Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Rectangle pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (0, 0, 10, 4), pos); text = "0123456789"; @@ -1244,7 +1246,7 @@ e └────────┘ "; - pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (0, 0, 10, 4), pos); top.Dispose (); } @@ -1282,7 +1284,7 @@ e └────────┘ "; - Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Rectangle pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (0, 0, 10, 4), pos); text = "0123456789"; @@ -1302,7 +1304,7 @@ e └────────┘ "; - pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (0, 0, 10, 4), pos); top.Dispose (); } diff --git a/UnitTests/Views/LineViewTests.cs b/Tests/UnitTests/Views/LineViewTests.cs similarity index 94% rename from UnitTests/Views/LineViewTests.cs rename to Tests/UnitTests/Views/LineViewTests.cs index 7be90c829..c0360365c 100644 --- a/UnitTests/Views/LineViewTests.cs +++ b/Tests/UnitTests/Views/LineViewTests.cs @@ -1,4 +1,6 @@ -namespace Terminal.Gui.ViewsTests; +using UnitTests; + +namespace Terminal.Gui.ViewsTests; public class LineViewTests { diff --git a/UnitTests/Views/ListViewTests.cs b/Tests/UnitTests/Views/ListViewTests.cs similarity index 97% rename from UnitTests/Views/ListViewTests.cs rename to Tests/UnitTests/Views/ListViewTests.cs index add91a9a0..2c9eef208 100644 --- a/UnitTests/Views/ListViewTests.cs +++ b/Tests/UnitTests/Views/ListViewTests.cs @@ -2,6 +2,8 @@ using System.Collections.ObjectModel; using System.Collections.Specialized; using System.ComponentModel; +using UnitTests; +using UnitTests; using Xunit.Abstractions; namespace Terminal.Gui.ViewsTests; @@ -60,7 +62,7 @@ public class ListViewTests (ITestOutputHelper output) Assert.Equal (-1, lv.SelectedItem); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌──────────┐ │Line0 │ @@ -81,7 +83,7 @@ public class ListViewTests (ITestOutputHelper output) Application.RunIteration (ref rs); Assert.Equal (-1, lv.SelectedItem); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌──────────┐ │Line10 │ @@ -102,7 +104,7 @@ public class ListViewTests (ITestOutputHelper output) Application.RunIteration (ref rs); Assert.Equal (0, lv.SelectedItem); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌──────────┐ │Line0 │ @@ -123,7 +125,7 @@ public class ListViewTests (ITestOutputHelper output) Application.RunIteration (ref rs); Assert.Equal (19, lv.SelectedItem); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌──────────┐ │Line10 │ @@ -144,7 +146,7 @@ public class ListViewTests (ITestOutputHelper output) Application.RunIteration (ref rs); Assert.Equal (19, lv.SelectedItem); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌──────────┐ │Line0 │ @@ -165,7 +167,7 @@ public class ListViewTests (ITestOutputHelper output) Application.RunIteration (ref rs); Assert.Equal (19, lv.SelectedItem); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌──────────┐ │Line10 │ @@ -186,7 +188,7 @@ public class ListViewTests (ITestOutputHelper output) Application.RunIteration (ref rs); Assert.Equal (19, lv.SelectedItem); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌──────────┐ │Line0 │ @@ -207,7 +209,7 @@ public class ListViewTests (ITestOutputHelper output) Application.RunIteration (ref rs); Assert.Equal (19, lv.SelectedItem); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌──────────┐ │Line10 │ @@ -228,7 +230,7 @@ public class ListViewTests (ITestOutputHelper output) Application.RunIteration (ref rs); Assert.Equal (0, lv.SelectedItem); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌──────────┐ │Line0 │ @@ -249,7 +251,7 @@ public class ListViewTests (ITestOutputHelper output) Application.RunIteration (ref rs); Assert.Equal (0, lv.SelectedItem); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌──────────┐ │Line19 │ @@ -270,7 +272,7 @@ public class ListViewTests (ITestOutputHelper output) Application.RunIteration (ref rs); Assert.Equal (0, lv.SelectedItem); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌──────────┐ │Line0 │ @@ -306,7 +308,7 @@ public class ListViewTests (ITestOutputHelper output) Application.Begin (top); Application.LayoutAndDraw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" Item 0 Item 1 @@ -320,7 +322,7 @@ Item 4", lv.SelectedItem = 6; Application.LayoutAndDraw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" Item 2 Item 3 @@ -729,7 +731,7 @@ Item 6", Assert.Equal (-1, lv.SelectedItem); Assert.Equal ("", lv.Text); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌─────┐ │One │ @@ -799,7 +801,7 @@ Item 6", Application.Begin (top); Application.LayoutAndDraw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" Item 0 Item 1 @@ -812,7 +814,7 @@ Item 6", lv.TopItem = 1; Application.LayoutAndDraw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" tem 1 tem 2 diff --git a/UnitTests/Views/MenuBarTests.cs b/Tests/UnitTests/Views/MenuBarTests.cs similarity index 94% rename from UnitTests/Views/MenuBarTests.cs rename to Tests/UnitTests/Views/MenuBarTests.cs index 133f0175f..6deae87d4 100644 --- a/UnitTests/Views/MenuBarTests.cs +++ b/Tests/UnitTests/Views/MenuBarTests.cs @@ -1,4 +1,6 @@ -using Xunit.Abstractions; +using UnitTests; +using UnitTests; +using Xunit.Abstractions; namespace Terminal.Gui.ViewsTests; @@ -103,7 +105,7 @@ public class MenuBarTests (ITestOutputHelper output) ); Application.LayoutAndDraw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @$" Nullable Checked ┌──────────────────────┐ @@ -378,7 +380,7 @@ public class MenuBarTests (ITestOutputHelper output) menu.ColorScheme.Disabled }; - TestHelpers.AssertDriverAttributesAre ( + DriverAssert.AssertDriverAttributesAre ( @" 00000000000000", output, @@ -393,7 +395,7 @@ public class MenuBarTests (ITestOutputHelper output) ); top.Draw (); - TestHelpers.AssertDriverAttributesAre ( + DriverAssert.AssertDriverAttributesAre ( @" 11111100000000 00000000000000 @@ -416,7 +418,7 @@ public class MenuBarTests (ITestOutputHelper output) top.Subviews [1].Layout(); top.Subviews [1].Draw (); - TestHelpers.AssertDriverAttributesAre ( + DriverAssert.AssertDriverAttributesAre ( @" 11111100000000 00000000000000 @@ -438,7 +440,7 @@ public class MenuBarTests (ITestOutputHelper output) ); top.Subviews [1].Draw (); - TestHelpers.AssertDriverAttributesAre ( + DriverAssert.AssertDriverAttributesAre ( @" 11111100000000 00000000000000 @@ -473,7 +475,7 @@ public class MenuBarTests (ITestOutputHelper output) Assert.Equal (new (0, 0, 40, 15), win.Frame); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌──────────────────────────────────────┐ │ │ @@ -575,7 +577,7 @@ public class MenuBarTests (ITestOutputHelper output) Assert.Equal (new (2, 2, 15, 4), dialog.Frame); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌──────────────────────────────────────┐ │ │ @@ -599,7 +601,7 @@ public class MenuBarTests (ITestOutputHelper output) menu.OpenMenu (); Application.RunIteration (ref rsDialog); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌──────────────────────────────────────┐ │ │ @@ -627,7 +629,7 @@ public class MenuBarTests (ITestOutputHelper output) Application.RunIteration (ref rsDialog, firstIteration); Assert.Equal (items [0], menu.Menus [0].Title); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌──────────────────────────────────────┐ │ │ @@ -661,7 +663,7 @@ public class MenuBarTests (ITestOutputHelper output) menu.OpenMenu (); Application.RunIteration (ref rsDialog); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌──────────────────┐ │ │ @@ -700,7 +702,7 @@ public class MenuBarTests (ITestOutputHelper output) Button.DefaultShadow = ShadowStyle.None; Assert.Equal (new (0, 0, 40, 15), View.GetClip ()!.GetBounds()); - TestHelpers.AssertDriverContentsWithFrameAre (@"", output); + DriverAssert.AssertDriverContentsWithFrameAre (@"", output); List items = new () { @@ -784,7 +786,7 @@ public class MenuBarTests (ITestOutputHelper output) Assert.Equal (new (2, 2, 15, 4), dialog.Frame); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌─────────────┐ │ File │ @@ -797,7 +799,7 @@ public class MenuBarTests (ITestOutputHelper output) menu.OpenMenu (); Application.RunIteration (ref rs); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌─────────────┐ │ File │ @@ -819,7 +821,7 @@ public class MenuBarTests (ITestOutputHelper output) Application.RunIteration (ref rs); Assert.Equal (items [0], menu.Menus [0].Title); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌─────────────┐ │ New │ @@ -842,7 +844,7 @@ public class MenuBarTests (ITestOutputHelper output) menu.OpenMenu (); Application.RunIteration (ref rs); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌─────────────┐ │ Delete │ @@ -890,7 +892,7 @@ public class MenuBarTests (ITestOutputHelper output) ──────┘ "; - Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Rectangle pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (0, 0, 7, 4), pos); menu.CloseAllMenus (); @@ -904,7 +906,7 @@ public class MenuBarTests (ITestOutputHelper output) ──────┘ "; - pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (1, 0, 7, 3), pos); menu.CloseAllMenus (); @@ -920,7 +922,7 @@ public class MenuBarTests (ITestOutputHelper output) └────── "; - pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (0, 1, 7, 4), pos); menu.CloseAllMenus (); @@ -935,7 +937,7 @@ public class MenuBarTests (ITestOutputHelper output) │ Two "; - pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (0, 0, 7, 3), pos); top.Dispose (); } @@ -968,7 +970,7 @@ ne wo "; - _ = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + _ = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); menu.CloseAllMenus (); menu.Frame = new (-2, -2, menu.Frame.Width, menu.Frame.Height); @@ -979,7 +981,7 @@ wo wo "; - _ = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + _ = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); menu.CloseAllMenus (); menu.Frame = new (0, 0, menu.Frame.Width, menu.Frame.Height); @@ -992,7 +994,7 @@ wo Tw "; - _ = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + _ = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); menu.CloseAllMenus (); menu.Frame = new (0, 0, menu.Frame.Width, menu.Frame.Height); @@ -1004,7 +1006,7 @@ wo On "; - _ = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + _ = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); top.Dispose (); } @@ -1034,7 +1036,7 @@ wo └──────┘ "; - Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Rectangle pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (0, 1, 8, 4), pos); top.Dispose (); } @@ -1064,7 +1066,7 @@ wo Two "; - _ = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + _ = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); top.Dispose (); } @@ -1112,7 +1114,7 @@ wo File Edit "; - var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + var pos = DriverAsserts.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (1, 0, 11, 1), pos); Assert.True (Application.Top.ProcessKeyDown (new KeyEventArgs (Key.N))); @@ -1140,7 +1142,7 @@ wo File Edit "; - pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + pos = DriverAsserts.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (1, 0, 11, 1), pos); Assert.True (Application.Top.ProcessKeyDown (new KeyEventArgs (Key.CursorRight))); @@ -1214,7 +1216,7 @@ wo Assert.True (menu.NewKeyDownEvent (Key.F.WithAlt)); Assert.True (menu.IsMenuOpen); Application.Top.Draw (); - TestHelpers.AssertDriverContentsAre (expectedMenu.ExpectedSubMenuOpen (0), output); + DriverAssert.AssertDriverContentsAre (expectedMenu.ExpectedSubMenuOpen (0), output); Assert.True (Application.Top.Subviews [1].NewKeyDownEvent (Key.N)); Application.MainLoop.RunIteration (); @@ -1223,7 +1225,7 @@ wo Assert.True (menu.NewKeyDownEvent (Key.E.WithAlt)); Assert.True (menu.IsMenuOpen); Application.Top.Draw (); - TestHelpers.AssertDriverContentsAre (expectedMenu.ExpectedSubMenuOpen (1), output); + DriverAssert.AssertDriverContentsAre (expectedMenu.ExpectedSubMenuOpen (1), output); Assert.True (Application.Top.Subviews [1].NewKeyDownEvent (Key.C)); Application.MainLoop.RunIteration (); @@ -1482,7 +1484,7 @@ wo menu.OpenMenu (); Application.LayoutAndDraw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" File ┌────────────────────────────┐ @@ -1530,7 +1532,7 @@ wo menu.OpenMenu (); Application.LayoutAndDraw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" File Open Open a file Ctrl+O @@ -1592,13 +1594,13 @@ wo Assert.True (menu.IsMenuOpen); top.Draw (); - TestHelpers.AssertDriverContentsAre (expectedMenu.ExpectedSubMenuOpen (0), output); + DriverAssert.AssertDriverContentsAre (expectedMenu.ExpectedSubMenuOpen (0), output); Assert.True (menu.NewMouseEvent (new () { Position = new (1, 0), Flags = MouseFlags.Button1Pressed, View = menu })); Assert.False (menu.IsMenuOpen); View.SetClipToScreen (); top.Draw (); - TestHelpers.AssertDriverContentsAre (expectedMenu.ClosedMenuText, output); + DriverAssert.AssertDriverContentsAre (expectedMenu.ClosedMenuText, output); top.Dispose (); } @@ -1632,7 +1634,7 @@ wo Application.Begin (top); ((FakeDriver)Application.Driver!).SetBufferSize (40, 8); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌──────────────────────────────────────┐ │ File Edit │ @@ -1648,7 +1650,7 @@ wo Assert.True (win.NewKeyDownEvent (menu.Key)); top.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌──────────────────────────────────────┐ │ File Edit │ @@ -1664,7 +1666,7 @@ wo Assert.True (menu.NewKeyDownEvent (Key.CursorRight)); Application.LayoutAndDraw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌──────────────────────────────────────┐ │ File Edit │ @@ -1680,7 +1682,7 @@ wo Assert.True (menu._openMenu.NewKeyDownEvent (Key.CursorRight)); top.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌──────────────────────────────────────┐ │ File Edit │ @@ -1697,7 +1699,7 @@ wo View.SetClipToScreen (); top.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌──────────────────────────────────────┐ │ File Edit │ @@ -1744,7 +1746,7 @@ wo { ((FakeDriver)Application.Driver!).SetBufferSize (40, 8); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌──────────────────────────────────────┐ │ File Edit │ @@ -1760,7 +1762,7 @@ wo Assert.True (win.NewKeyDownEvent (menu.Key)); top.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌──────────────────────────────────────┐ │ File Edit │ @@ -1776,7 +1778,7 @@ wo Assert.True (menu.NewKeyDownEvent (Key.CursorRight)); Application.LayoutAndDraw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌──────────────────────────────────────┐ │ File Edit │ @@ -1792,7 +1794,7 @@ wo Assert.True (menu._openMenu.NewKeyDownEvent (Key.CursorRight)); top.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌──────────────────────────────────────┐ │ File Edit │ @@ -1809,7 +1811,7 @@ wo View.SetClipToScreen (); top.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌──────────────────────────────────────┐ │ File Edit │ @@ -1858,7 +1860,7 @@ wo RunState rs = Application.Begin (win); Application.RunIteration (ref rs); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌──────────────────────────────────────┐ │ File Edit │ @@ -1874,7 +1876,7 @@ wo Assert.True (win.NewKeyDownEvent (menu.Key)); Application.RunIteration (ref rs); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌──────────────────────────────────────┐ │ File Edit │ @@ -1890,7 +1892,7 @@ wo Assert.True (menu.NewKeyDownEvent (Key.CursorRight)); Application.RunIteration (ref rs); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌──────────────────────────────────────┐ │ File Edit │ @@ -1906,7 +1908,7 @@ wo Assert.True (menu._openMenu.NewKeyDownEvent (Key.CursorRight)); Application.RunIteration (ref rs); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌──────────────────────────────────────┐ │ File Edit │ @@ -1922,7 +1924,7 @@ wo Assert.True (menu._openMenu.NewKeyDownEvent (Key.CursorRight)); Application.RunIteration (ref rs); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌──────────────────────────────────────┐ │ File Edit │ @@ -1948,7 +1950,7 @@ wo Toplevel top = Application.Top; Application.LayoutAndDraw(); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌──────────────────────────────────────┐ │ File Edit │ @@ -1964,7 +1966,7 @@ wo Assert.True (top.NewKeyDownEvent (Key.F9)); top.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌──────────────────────────────────────┐ │ File Edit │ @@ -1980,7 +1982,7 @@ wo Assert.True (top.Subviews [0].NewKeyDownEvent (Key.CursorRight)); Application.LayoutAndDraw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌──────────────────────────────────────┐ │ File Edit │ @@ -1998,7 +2000,7 @@ wo ); top.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌──────────────────────────────────────┐ │ File Edit │ @@ -2017,7 +2019,7 @@ wo View.SetClipToScreen (); top.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌──────────────────────────────────────┐ │ File Edit │ @@ -2084,21 +2086,21 @@ wo Assert.True (menu.NewKeyDownEvent (menu.Key)); Assert.True (menu.IsMenuOpen); top.Draw (); - TestHelpers.AssertDriverContentsAre (expectedMenu.ExpectedSubMenuOpen (0), output); + DriverAssert.AssertDriverContentsAre (expectedMenu.ExpectedSubMenuOpen (0), output); // Open second Assert.True (Application.Top.Subviews [1].NewKeyDownEvent (Key.CursorRight)); Assert.True (menu.IsMenuOpen); View.SetClipToScreen (); top.Draw (); - TestHelpers.AssertDriverContentsAre (expectedMenu.ExpectedSubMenuOpen (1), output); + DriverAssert.AssertDriverContentsAre (expectedMenu.ExpectedSubMenuOpen (1), output); // Close menu Assert.True (menu.NewKeyDownEvent (menu.Key)); Assert.False (menu.IsMenuOpen); View.SetClipToScreen (); top.Draw (); - TestHelpers.AssertDriverContentsAre (expectedMenu.ClosedMenuText, output); + DriverAssert.AssertDriverContentsAre (expectedMenu.ClosedMenuText, output); top.Remove (menu); @@ -2132,21 +2134,21 @@ wo Assert.True (menu.IsMenuOpen); View.SetClipToScreen (); top.Draw (); - TestHelpers.AssertDriverContentsAre (expectedMenu.ExpectedSubMenuOpen (0), output); + DriverAssert.AssertDriverContentsAre (expectedMenu.ExpectedSubMenuOpen (0), output); // Open second Assert.True (top.Subviews [1].NewKeyDownEvent (Key.CursorRight)); Assert.True (menu.IsMenuOpen); View.SetClipToScreen (); Application.Top.Draw (); - TestHelpers.AssertDriverContentsAre (expectedMenu.ExpectedSubMenuOpen (1), output); + DriverAssert.AssertDriverContentsAre (expectedMenu.ExpectedSubMenuOpen (1), output); // Close menu Assert.True (menu.NewKeyDownEvent (menu.Key)); Assert.False (menu.IsMenuOpen); View.SetClipToScreen (); top.Draw (); - TestHelpers.AssertDriverContentsAre (expectedMenu.ClosedMenuText, output); + DriverAssert.AssertDriverContentsAre (expectedMenu.ClosedMenuText, output); top.Dispose (); } @@ -2215,7 +2217,7 @@ wo View.SetClipToScreen (); top.Draw (); - TestHelpers.AssertDriverContentsAre (expectedMenu.ClosedMenuText, output); + DriverAssert.AssertDriverContentsAre (expectedMenu.ClosedMenuText, output); for (var i = 0; i < expectedMenu.Menus.Length; i++) { @@ -2223,7 +2225,7 @@ wo Assert.True (menu.IsMenuOpen); View.SetClipToScreen (); top.Draw (); - TestHelpers.AssertDriverContentsAre (expectedMenu.ExpectedSubMenuOpen (i), output); + DriverAssert.AssertDriverContentsAre (expectedMenu.ExpectedSubMenuOpen (i), output); } top.Dispose (); @@ -2474,7 +2476,7 @@ Edit │ Copy Copies the selection. │ └──────────────────────────────┘ "; - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); cancelClosing = true; Assert.True (menu.NewKeyDownEvent (menu.Key)); @@ -2489,7 +2491,7 @@ Edit │ Copy Copies the selection. │ └──────────────────────────────┘ "; - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); cancelClosing = false; Assert.True (menu.NewKeyDownEvent (menu.Key)); @@ -2501,7 +2503,7 @@ Edit expected = @" Edit "; - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); void New () { miAction = "New"; } @@ -2650,7 +2652,7 @@ Edit Assert.True (menu.IsMenuOpen); Assert.False (tf.HasFocus); top.Draw (); - TestHelpers.AssertDriverContentsAre (expectedMenu.ExpectedSubMenuOpen (0), output); + DriverAssert.AssertDriverContentsAre (expectedMenu.ExpectedSubMenuOpen (0), output); // Right - Edit has no sub menu; this tests that no sub menu shows Assert.True (menu._openMenu.NewKeyDownEvent (Key.CursorRight)); @@ -2661,7 +2663,7 @@ Edit Assert.Null (menu._openSubMenu); View.SetClipToScreen (); top.Draw (); - TestHelpers.AssertDriverContentsAre (expectedMenu.ExpectedSubMenuOpen (1), output); + DriverAssert.AssertDriverContentsAre (expectedMenu.ExpectedSubMenuOpen (1), output); // Right - Format Assert.True (menu._openMenu.NewKeyDownEvent (Key.CursorRight)); @@ -2669,7 +2671,7 @@ Edit Assert.False (tf.HasFocus); View.SetClipToScreen (); top.Draw (); - TestHelpers.AssertDriverContentsAre (expectedMenu.ExpectedSubMenuOpen (2), output); + DriverAssert.AssertDriverContentsAre (expectedMenu.ExpectedSubMenuOpen (2), output); // Left - Edit Assert.True (menu._openMenu.NewKeyDownEvent (Key.CursorLeft)); @@ -2677,21 +2679,21 @@ Edit Assert.False (tf.HasFocus); View.SetClipToScreen (); top.Draw (); - TestHelpers.AssertDriverContentsAre (expectedMenu.ExpectedSubMenuOpen (1), output); + DriverAssert.AssertDriverContentsAre (expectedMenu.ExpectedSubMenuOpen (1), output); Assert.True (menu._openMenu.NewKeyDownEvent (Key.CursorLeft)); Assert.True (menu.IsMenuOpen); Assert.False (tf.HasFocus); View.SetClipToScreen (); top.Draw (); - TestHelpers.AssertDriverContentsAre (expectedMenu.ExpectedSubMenuOpen (0), output); + DriverAssert.AssertDriverContentsAre (expectedMenu.ExpectedSubMenuOpen (0), output); Assert.True (Application.RaiseKeyDownEvent (menu.Key)); Assert.False (menu.IsMenuOpen); Assert.True (tf.HasFocus); View.SetClipToScreen (); top.Draw (); - TestHelpers.AssertDriverContentsAre (expectedMenu.ClosedMenuText, output); + DriverAssert.AssertDriverContentsAre (expectedMenu.ClosedMenuText, output); top.Dispose (); } @@ -2751,7 +2753,7 @@ Edit Assert.True (menu.IsMenuOpen); Assert.False (tf.HasFocus); top.Draw (); - TestHelpers.AssertDriverContentsAre (expectedMenu.ExpectedSubMenuOpen (0), output); + DriverAssert.AssertDriverContentsAre (expectedMenu.ExpectedSubMenuOpen (0), output); Assert.True ( menu.NewMouseEvent ( @@ -2762,7 +2764,7 @@ Edit Assert.False (tf.HasFocus); View.SetClipToScreen (); top.Draw (); - TestHelpers.AssertDriverContentsAre (expectedMenu.ExpectedSubMenuOpen (1), output); + DriverAssert.AssertDriverContentsAre (expectedMenu.ExpectedSubMenuOpen (1), output); Assert.True ( menu.NewMouseEvent ( @@ -2773,7 +2775,7 @@ Edit Assert.False (tf.HasFocus); View.SetClipToScreen (); top.Draw (); - TestHelpers.AssertDriverContentsAre (expectedMenu.ExpectedSubMenuOpen (2), output); + DriverAssert.AssertDriverContentsAre (expectedMenu.ExpectedSubMenuOpen (2), output); Assert.True ( menu.NewMouseEvent ( @@ -2784,7 +2786,7 @@ Edit Assert.False (tf.HasFocus); View.SetClipToScreen (); top.Draw (); - TestHelpers.AssertDriverContentsAre (expectedMenu.ClosedMenuText, output); + DriverAssert.AssertDriverContentsAre (expectedMenu.ClosedMenuText, output); Assert.True ( menu.NewMouseEvent ( @@ -2795,14 +2797,14 @@ Edit Assert.False (tf.HasFocus); View.SetClipToScreen (); top.Draw (); - TestHelpers.AssertDriverContentsAre (expectedMenu.ExpectedSubMenuOpen (0), output); + DriverAssert.AssertDriverContentsAre (expectedMenu.ExpectedSubMenuOpen (0), output); Assert.True (menu.NewMouseEvent (new () { Position = new (8, 0), Flags = MouseFlags.Button1Pressed, View = menu })); Assert.False (menu.IsMenuOpen); Assert.True (tf.HasFocus); View.SetClipToScreen (); top.Draw (); - TestHelpers.AssertDriverContentsAre (expectedMenu.ClosedMenuText, output); + DriverAssert.AssertDriverContentsAre (expectedMenu.ClosedMenuText, output); top.Dispose (); } @@ -2892,7 +2894,7 @@ Edit var firstIteration = false; Application.RunIteration (ref rs, firstIteration); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" File ┌────────────────────────────┐ @@ -2905,7 +2907,7 @@ Edit firstIteration = false; Application.RunIteration (ref rs, firstIteration); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" File", output @@ -3063,7 +3065,7 @@ Edit Numbers "; - Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Rectangle pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Assert.True (menu.NewKeyDownEvent (menu.Key)); top.Draw (); @@ -3077,7 +3079,7 @@ Edit └────────┘ "; - pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Assert.True (Application.Top.Subviews [1].NewKeyDownEvent (Key.CursorDown)); top.Draw (); @@ -3092,7 +3094,7 @@ Edit └─────────────┘ "; - pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Assert.True (Application.Top.Subviews [2].NewKeyDownEvent (Key.CursorLeft)); top.Draw (); @@ -3106,7 +3108,7 @@ Edit └────────┘ "; - pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Assert.True (Application.Top.Subviews [1].NewKeyDownEvent (Key.Esc)); top.Draw (); @@ -3115,7 +3117,7 @@ Edit Numbers "; - pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); top.Dispose (); } @@ -3167,7 +3169,7 @@ Edit Numbers "; - Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Rectangle pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (1, 0, 8, 1), pos); menu.NewMouseEvent ( @@ -3184,7 +3186,7 @@ Edit └────────┘ "; - pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (1, 0, 10, 6), pos); menu.NewMouseEvent ( @@ -3205,7 +3207,7 @@ Edit └─────────────┘ "; - pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (1, 0, 25, 7), pos); Assert.False ( @@ -3227,7 +3229,7 @@ Edit └────────┘ "; - pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (1, 0, 10, 6), pos); menu.NewMouseEvent ( @@ -3239,7 +3241,7 @@ Edit Numbers "; - pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (1, 0, 8, 1), pos); top.Dispose (); } @@ -3297,7 +3299,7 @@ Edit Two ► Three "; - _ = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + _ = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Assert.True (menu._openMenu.NewKeyDownEvent (Key.CursorDown)); menu.Draw (); @@ -3310,7 +3312,7 @@ Edit Two ► Sub-Menu 1 Three Sub-Menu 2"; - _ = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + _ = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); } [Fact (Skip = "#3798 Broke. Will fix in #2975")] @@ -3363,7 +3365,7 @@ Edit Numbers "; - Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Rectangle pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (1, 0, 8, 1), pos); Assert.True (menu.NewKeyDownEvent (menu.Key)); @@ -3378,7 +3380,7 @@ Edit └────────┘ "; - pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (1, 0, 10, 6), pos); Assert.True (Application.Top.Subviews [1].NewKeyDownEvent (Key.CursorDown)); @@ -3395,7 +3397,7 @@ Edit └─────────────┘ "; - pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (1, 0, 15, 7), pos); Assert.True (Application.Top.Subviews [2].NewKeyDownEvent (Key.Enter)); @@ -3410,7 +3412,7 @@ Edit └────────┘ "; - pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (1, 0, 10, 6), pos); Assert.True (Application.Top.Subviews [1].NewKeyDownEvent (Key.Esc)); @@ -3420,7 +3422,7 @@ Edit Numbers "; - pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (1, 0, 8, 1), pos); top.Dispose (); } @@ -3475,7 +3477,7 @@ Edit Numbers "; - Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Rectangle pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (1, 0, 8, 1), pos); Assert.True (menu.NewMouseEvent (new () { Position = new (1, 0), Flags = MouseFlags.Button1Pressed, View = menu })); @@ -3490,7 +3492,7 @@ Edit └────────┘ "; - pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (1, 0, 10, 6), pos); Assert.False (menu.NewMouseEvent (new () { Position = new (1, 2), Flags = MouseFlags.Button1Clicked, View = Application.Top.Subviews [1] })); @@ -3506,7 +3508,7 @@ Edit └─────────────┘ "; - pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (1, 0, 15, 7), pos); menu.NewMouseEvent (new () { Position = new (1, 1), Flags = MouseFlags.Button1Clicked, View = Application.Top.Subviews [2] }); @@ -3521,7 +3523,7 @@ Edit └────────┘ "; - pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (1, 0, 10, 6), pos); Assert.False (menu.NewMouseEvent (new () { Position = new (70, 2), Flags = MouseFlags.Button1Clicked, View = Application.Top })); @@ -3531,7 +3533,7 @@ Edit Numbers "; - pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (1, 0, 8, 1), pos); top.Dispose (); } @@ -3589,7 +3591,7 @@ Edit Two ► Three "; - _ = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + _ = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Assert.True (menu._openMenu.NewKeyDownEvent (Key.CursorDown)); Assert.True (menu._openMenu.NewKeyDownEvent (Key.Enter)); @@ -3604,7 +3606,7 @@ Edit Sub-Menu 1 Sub-Menu 2 "; - _ = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + _ = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); } [Fact (Skip = "#3798 Broke. Will fix in #2975")] @@ -3658,7 +3660,7 @@ Edit Numbers "; - Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Rectangle pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (1, 0, 8, 1), pos); Assert.True ( @@ -3675,7 +3677,7 @@ Edit Three "; - pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (1, 0, 8, 4), pos); menu.NewMouseEvent ( @@ -3691,7 +3693,7 @@ Edit Sub-Menu 2 "; - pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (1, 0, 13, 5), pos); menu.NewMouseEvent ( @@ -3706,7 +3708,7 @@ Edit Three "; - pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (1, 0, 8, 4), pos); menu.NewMouseEvent ( @@ -3718,7 +3720,7 @@ Edit Numbers "; - pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (1, 0, 8, 1), pos); top.Dispose (); } diff --git a/UnitTests/Views/MenuTests.cs b/Tests/UnitTests/Views/MenuTests.cs similarity index 100% rename from UnitTests/Views/MenuTests.cs rename to Tests/UnitTests/Views/MenuTests.cs diff --git a/UnitTests/Views/NumericUpDownTests.cs b/Tests/UnitTests/Views/NumericUpDownTests.cs similarity index 100% rename from UnitTests/Views/NumericUpDownTests.cs rename to Tests/UnitTests/Views/NumericUpDownTests.cs diff --git a/UnitTests/Views/ProgressBarTests.cs b/Tests/UnitTests/Views/ProgressBarTests.cs similarity index 99% rename from UnitTests/Views/ProgressBarTests.cs rename to Tests/UnitTests/Views/ProgressBarTests.cs index d5c163a76..2b56360a1 100644 --- a/UnitTests/Views/ProgressBarTests.cs +++ b/Tests/UnitTests/Views/ProgressBarTests.cs @@ -1,4 +1,5 @@ using System.Text; +using UnitTests; namespace Terminal.Gui.ViewsTests; diff --git a/UnitTests/Views/RadioGroupTests.cs b/Tests/UnitTests/Views/RadioGroupTests.cs similarity index 98% rename from UnitTests/Views/RadioGroupTests.cs rename to Tests/UnitTests/Views/RadioGroupTests.cs index 8eb95cb71..c5a9ea92e 100644 --- a/UnitTests/Views/RadioGroupTests.cs +++ b/Tests/UnitTests/Views/RadioGroupTests.cs @@ -1,4 +1,6 @@ using System.ComponentModel; +using UnitTests; +using UnitTests; using Xunit.Abstractions; // ReSharper disable AccessToModifiedClosure @@ -549,7 +551,7 @@ public class RadioGroupTests (ITestOutputHelper output) └────────────────────────────┘ "; - Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + Rectangle pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (0, 0, 30, 5), pos); rg.Orientation = Orientation.Horizontal; @@ -570,7 +572,7 @@ public class RadioGroupTests (ITestOutputHelper output) └────────────────────────────┘ "; - pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (0, 0, 30, 5), pos); rg.HorizontalSpace = 4; @@ -591,7 +593,7 @@ public class RadioGroupTests (ITestOutputHelper output) └────────────────────────────┘ "; - pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + pos = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (0, 0, 30, 5), pos); top.Dispose (); } diff --git a/UnitTests/Views/ScrollBarTests.cs b/Tests/UnitTests/Views/ScrollBarTests.cs similarity index 93% rename from UnitTests/Views/ScrollBarTests.cs rename to Tests/UnitTests/Views/ScrollBarTests.cs index 616a112a0..4cc48f385 100644 --- a/UnitTests/Views/ScrollBarTests.cs +++ b/Tests/UnitTests/Views/ScrollBarTests.cs @@ -1,4 +1,6 @@ -using Xunit.Abstractions; +using UnitTests; +using UnitTests; +using Xunit.Abstractions; using static Unix.Terminal.Delegates; namespace Terminal.Gui.ViewsTests; @@ -230,7 +232,7 @@ public class ScrollBarTests (ITestOutputHelper output) #region Position [Fact] - public void Position_Event_Cancelables () + public void Position_Event_Cancels () { var changingCount = 0; var changedCount = 0; @@ -802,7 +804,7 @@ public class ScrollBarTests (ITestOutputHelper output) super.Layout (); super.Draw (); - _ = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + _ = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); } #endregion Draw @@ -905,39 +907,4 @@ public class ScrollBarTests (ITestOutputHelper output) Application.ResetState (true); } #endregion Mouse - - - - [Fact (Skip = "Disabled - Will put this feature in View")] - [AutoInitShutdown] - public void KeepContentInAllViewport_True_False () - { - var view = new View { Width = Dim.Fill (), Height = Dim.Fill () }; - view.Padding.Thickness = new (0, 0, 2, 0); - view.SetContentSize (new (view.Viewport.Width, 30)); - var scrollBar = new ScrollBar { Width = 2, Height = Dim.Fill (), ScrollableContentSize = view.GetContentSize ().Height }; - scrollBar.SliderPositionChanged += (_, e) => view.Viewport = view.Viewport with { Y = e.CurrentValue }; - view.Padding.Add (scrollBar); - var top = new Toplevel (); - top.Add (view); - Application.Begin (top); - - //Assert.False (scrollBar.KeepContentInAllViewport); - //scrollBar.KeepContentInAllViewport = true; - Assert.Equal (80, view.Padding.Viewport.Width); - Assert.Equal (25, view.Padding.Viewport.Height); - Assert.Equal (2, scrollBar.Viewport.Width); - Assert.Equal (25, scrollBar.Viewport.Height); - Assert.Equal (30, scrollBar.ScrollableContentSize); - - //scrollBar.KeepContentInAllViewport = false; - scrollBar.Position = 50; - Assert.Equal (scrollBar.GetSliderPosition (), scrollBar.ScrollableContentSize - 1); - Assert.Equal (scrollBar.GetSliderPosition (), view.Viewport.Y); - Assert.Equal (29, scrollBar.GetSliderPosition ()); - Assert.Equal (29, view.Viewport.Y); - - top.Dispose (); - } - } diff --git a/UnitTests/Views/ScrollSliderTests.cs b/Tests/UnitTests/Views/ScrollSliderTests.cs similarity index 99% rename from UnitTests/Views/ScrollSliderTests.cs rename to Tests/UnitTests/Views/ScrollSliderTests.cs index 6f5d1cd26..2e94d4b3e 100644 --- a/UnitTests/Views/ScrollSliderTests.cs +++ b/Tests/UnitTests/Views/ScrollSliderTests.cs @@ -1,6 +1,8 @@ using System.Diagnostics; using System.Runtime.InteropServices; using Microsoft.VisualStudio.TestPlatform.Utilities; +using UnitTests; +using UnitTests; using Xunit.Abstractions; using static Unix.Terminal.Delegates; @@ -1005,6 +1007,6 @@ public class ScrollSliderTests (ITestOutputHelper output) super.Layout (); super.Draw (); - _ = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + _ = DriverAssert.AssertDriverContentsWithFrameAre (expected, output); } } diff --git a/UnitTests/Views/ShortcutTests.cs b/Tests/UnitTests/Views/ShortcutTests.cs similarity index 99% rename from UnitTests/Views/ShortcutTests.cs rename to Tests/UnitTests/Views/ShortcutTests.cs index bc2ba9645..e9c0edfeb 100644 --- a/UnitTests/Views/ShortcutTests.cs +++ b/Tests/UnitTests/Views/ShortcutTests.cs @@ -1,4 +1,5 @@ using JetBrains.Annotations; +using UnitTests; namespace Terminal.Gui.ViewsTests; diff --git a/UnitTests/Views/SliderTests.cs b/Tests/UnitTests/Views/SliderTests.cs similarity index 100% rename from UnitTests/Views/SliderTests.cs rename to Tests/UnitTests/Views/SliderTests.cs diff --git a/UnitTests/Views/SpinnerViewTests.cs b/Tests/UnitTests/Views/SpinnerViewTests.cs similarity index 83% rename from UnitTests/Views/SpinnerViewTests.cs rename to Tests/UnitTests/Views/SpinnerViewTests.cs index 0af6f0b50..bd2a116cd 100644 --- a/UnitTests/Views/SpinnerViewTests.cs +++ b/Tests/UnitTests/Views/SpinnerViewTests.cs @@ -1,4 +1,6 @@ -using Xunit.Abstractions; +using UnitTests; +using UnitTests; +using Xunit.Abstractions; namespace Terminal.Gui.ViewsTests; @@ -56,14 +58,14 @@ public class SpinnerViewTests view.Draw (); var expected = "|"; - TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + DriverAssert.AssertDriverContentsWithFrameAre (expected, output); view.AdvanceAnimation (); View.SetClipToScreen (); view.Draw (); expected = "/"; - TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + DriverAssert.AssertDriverContentsWithFrameAre (expected, output); Application.Top.Dispose (); } @@ -75,19 +77,19 @@ public class SpinnerViewTests view.Draw (); var expected = @"\"; - TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + DriverAssert.AssertDriverContentsWithFrameAre (expected, output); view.AdvanceAnimation (); view.Draw (); expected = @"\"; - TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + DriverAssert.AssertDriverContentsWithFrameAre (expected, output); view.AdvanceAnimation (); view.Draw (); expected = @"\"; - TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + DriverAssert.AssertDriverContentsWithFrameAre (expected, output); // BUGBUG: Disabled due to xunit error //Task.Delay (400).Wait (); @@ -96,7 +98,7 @@ public class SpinnerViewTests //view.Draw (); //expected = "|"; - //TestHelpers.AssertDriverContentsWithFrameAre (expected, output); + //DriverAsserts.AssertDriverContentsWithFrameAre (expected, output); Application.Top.Dispose (); } diff --git a/UnitTests/Views/StatusBarTests.cs b/Tests/UnitTests/Views/StatusBarTests.cs similarity index 99% rename from UnitTests/Views/StatusBarTests.cs rename to Tests/UnitTests/Views/StatusBarTests.cs index 062a1e396..15ad8309b 100644 --- a/UnitTests/Views/StatusBarTests.cs +++ b/Tests/UnitTests/Views/StatusBarTests.cs @@ -1,4 +1,5 @@ -using Xunit.Abstractions; +using UnitTests; +using Xunit.Abstractions; namespace Terminal.Gui.ViewsTests; public class StatusBarTests diff --git a/UnitTests/Views/TabTests.cs b/Tests/UnitTests/Views/TabTests.cs similarity index 100% rename from UnitTests/Views/TabTests.cs rename to Tests/UnitTests/Views/TabTests.cs diff --git a/UnitTests/Views/TabViewTests.cs b/Tests/UnitTests/Views/TabViewTests.cs similarity index 94% rename from UnitTests/Views/TabViewTests.cs rename to Tests/UnitTests/Views/TabViewTests.cs index ac12a5556..0ec61e4ff 100644 --- a/UnitTests/Views/TabViewTests.cs +++ b/Tests/UnitTests/Views/TabViewTests.cs @@ -1,4 +1,6 @@ using System.Globalization; +using UnitTests; +using UnitTests; using Xunit.Abstractions; namespace Terminal.Gui.ViewsTests; @@ -103,7 +105,7 @@ public class TabViewTests (ITestOutputHelper output) View tabRow = tv.Subviews [0]; Assert.Equal ("TabRow", tabRow.GetType ().Name); - TestHelpers.AssertDriverContentsAre ( + DriverAssert.AssertDriverContentsAre ( @" ╭────┬────╮ │Tab1│Tab2│ @@ -186,7 +188,7 @@ public class TabViewTests (ITestOutputHelper output) View tabRow = tv.Subviews [0]; Assert.Equal ("TabRow", tabRow.GetType ().Name); - TestHelpers.AssertDriverContentsAre ( + DriverAssert.AssertDriverContentsAre ( @" ╭────╮ │Tab1│ @@ -223,7 +225,7 @@ public class TabViewTests (ITestOutputHelper output) Assert.Equal (tab2, newChanged); Assert.Equal (tab2, tv.SelectedTab); - TestHelpers.AssertDriverContentsAre ( + DriverAssert.AssertDriverContentsAre ( @" ╭────╮ │Tab2│ @@ -243,7 +245,7 @@ public class TabViewTests (ITestOutputHelper output) Assert.Equal (tab1, newChanged); Assert.Equal (tab1, tv.SelectedTab); - TestHelpers.AssertDriverContentsAre ( + DriverAssert.AssertDriverContentsAre ( @" ╭────╮ │Tab1│ @@ -274,7 +276,7 @@ public class TabViewTests (ITestOutputHelper output) View tabRow = tv.Subviews [0]; Assert.Equal ("TabRow", tabRow.GetType ().Name); - TestHelpers.AssertDriverContentsAre ( + DriverAssert.AssertDriverContentsAre ( @" ┌───────┐ │╭────╮ │ @@ -313,7 +315,7 @@ public class TabViewTests (ITestOutputHelper output) Assert.Equal (tab2, newChanged); Assert.Equal (tab2, tv.SelectedTab); - TestHelpers.AssertDriverContentsAre ( + DriverAssert.AssertDriverContentsAre ( @" ┌───────┐ │╭────╮ │ @@ -335,7 +337,7 @@ public class TabViewTests (ITestOutputHelper output) Assert.Equal (tab1, newChanged); Assert.Equal (tab1, tv.SelectedTab); - TestHelpers.AssertDriverContentsAre ( + DriverAssert.AssertDriverContentsAre ( @" ┌───────┐ │╭────╮ │ @@ -595,7 +597,7 @@ public class TabViewTests (ITestOutputHelper output) tv.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ││ │╰► @@ -619,7 +621,7 @@ public class TabViewTests (ITestOutputHelper output) tv.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" │T│ │ ╰► @@ -649,7 +651,7 @@ public class TabViewTests (ITestOutputHelper output) tv.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" │12│13│ │ ╰──┴──╮ @@ -666,7 +668,7 @@ public class TabViewTests (ITestOutputHelper output) View.SetClipToScreen (); tv.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" │12│13│ ├──╯ ╰──╮ @@ -685,7 +687,7 @@ public class TabViewTests (ITestOutputHelper output) View.SetClipToScreen (); tv.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" │1234567│ │ ╰► @@ -701,7 +703,7 @@ public class TabViewTests (ITestOutputHelper output) tv.Layout (); View.SetClipToScreen (); tv.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" │13│ ◄ ╰─────╮ @@ -718,7 +720,7 @@ public class TabViewTests (ITestOutputHelper output) tv.Layout (); View.SetClipToScreen (); tv.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" │abcdefg│ ◄ ╰╮ @@ -742,7 +744,7 @@ public class TabViewTests (ITestOutputHelper output) tv.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌─┐ │h│ @@ -766,7 +768,7 @@ public class TabViewTests (ITestOutputHelper output) tv.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌──┐ │hi│ @@ -795,7 +797,7 @@ public class TabViewTests (ITestOutputHelper output) tv.Layout (); tv.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌────────┐ │hi │ @@ -812,7 +814,7 @@ public class TabViewTests (ITestOutputHelper output) View.SetClipToScreen (); tv.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌────────┐ │hi2 │ @@ -832,7 +834,7 @@ public class TabViewTests (ITestOutputHelper output) View.SetClipToScreen (); tv.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌────────┐ │hi │ @@ -849,7 +851,7 @@ public class TabViewTests (ITestOutputHelper output) View.SetClipToScreen (); tv.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌────────┐ │hi2 │ @@ -867,7 +869,7 @@ public class TabViewTests (ITestOutputHelper output) View.SetClipToScreen (); tv.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌────────┐ │hi2 │ @@ -889,7 +891,7 @@ public class TabViewTests (ITestOutputHelper output) tv.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ╭╮ ││ @@ -912,7 +914,7 @@ public class TabViewTests (ITestOutputHelper output) View.SetClipToScreen (); tv.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ╭─╮ │T│ @@ -938,7 +940,7 @@ public class TabViewTests (ITestOutputHelper output) tv.Layout (); tv.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ╭──┬──╮ │12│13│ @@ -954,7 +956,7 @@ public class TabViewTests (ITestOutputHelper output) View.SetClipToScreen (); tv.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ╭──┬──╮ │12│13│ @@ -974,7 +976,7 @@ public class TabViewTests (ITestOutputHelper output) View.SetClipToScreen (); tv.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ╭───────╮ │1234567│ @@ -991,7 +993,7 @@ public class TabViewTests (ITestOutputHelper output) View.SetClipToScreen (); tv.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ╭──╮ │13│ @@ -1009,7 +1011,7 @@ public class TabViewTests (ITestOutputHelper output) View.SetClipToScreen (); tv.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ╭───────╮ │abcdefg│ @@ -1035,7 +1037,7 @@ public class TabViewTests (ITestOutputHelper output) tv.Layout (); tv.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ╭────╮ │Tab0│ @@ -1051,7 +1053,7 @@ public class TabViewTests (ITestOutputHelper output) View.SetClipToScreen (); tv.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ╭──────────────╮ │Les Misérables│ @@ -1075,7 +1077,7 @@ public class TabViewTests (ITestOutputHelper output) tv.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌─┐ │h│ @@ -1099,7 +1101,7 @@ public class TabViewTests (ITestOutputHelper output) tv.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌──┐ │hi│ @@ -1128,7 +1130,7 @@ public class TabViewTests (ITestOutputHelper output) tv.Layout (); tv.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌────────┐ │hi │ @@ -1146,7 +1148,7 @@ public class TabViewTests (ITestOutputHelper output) View.SetClipToScreen (); tv.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌────────┐ │hi │ @@ -1163,7 +1165,7 @@ public class TabViewTests (ITestOutputHelper output) View.SetClipToScreen (); tv.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌────────┐ │hi2 │ @@ -1181,7 +1183,7 @@ public class TabViewTests (ITestOutputHelper output) View.SetClipToScreen (); tv.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌────────┐ │hi2 │ @@ -1209,7 +1211,7 @@ public class TabViewTests (ITestOutputHelper output) tv.Layout (); tv.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌──────────────────┐ │hi │ @@ -1225,7 +1227,7 @@ public class TabViewTests (ITestOutputHelper output) View.SetClipToScreen (); tv.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌──────────────────┐ │hi2 │ @@ -1322,7 +1324,7 @@ public class TabViewTests (ITestOutputHelper output) Assert.Equal (tab1, tv.SelectedTab); - TestHelpers.AssertDriverContentsAre ( + DriverAssert.AssertDriverContentsAre ( @" ╭────┬────┬────╮ │Tab1│Tab2│Tab3│ @@ -1339,7 +1341,7 @@ public class TabViewTests (ITestOutputHelper output) View.SetClipToScreen (); tv.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ╭────┬────┬────╮ │Tab1│Tab2│Tab3│ @@ -1356,7 +1358,7 @@ public class TabViewTests (ITestOutputHelper output) View.SetClipToScreen (); tv.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ╭────┬────┬────╮ │Tab1│Tab2│Tab3│ @@ -1389,7 +1391,7 @@ public class TabViewTests (ITestOutputHelper output) Assert.Equal (tab1, tv.SelectedTab); - TestHelpers.AssertDriverContentsAre ( + DriverAssert.AssertDriverContentsAre ( @" ┌──────────────────┐ │hi │ @@ -1406,7 +1408,7 @@ public class TabViewTests (ITestOutputHelper output) View.SetClipToScreen (); tv.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌──────────────────┐ │hi2 │ @@ -1423,7 +1425,7 @@ public class TabViewTests (ITestOutputHelper output) View.SetClipToScreen (); tv.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌──────────────────┐ │hi3 │ diff --git a/UnitTests/Views/TableViewTests.cs b/Tests/UnitTests/Views/TableViewTests.cs similarity index 95% rename from UnitTests/Views/TableViewTests.cs rename to Tests/UnitTests/Views/TableViewTests.cs index 54793cf15..63dc829db 100644 --- a/UnitTests/Views/TableViewTests.cs +++ b/Tests/UnitTests/Views/TableViewTests.cs @@ -2,6 +2,8 @@ using System.Collections; using System.Data; using System.Globalization; using System.Reflection; +using UnitTests; +using UnitTests; using Xunit.Abstractions; namespace Terminal.Gui.ViewsTests; @@ -83,7 +85,7 @@ public class TableViewTests (ITestOutputHelper output) │Hello│ │f │ "; - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); var color = new Attribute (Color.Magenta, Color.BrightBlue); @@ -115,7 +117,7 @@ public class TableViewTests (ITestOutputHelper output) 00000000000000000000 01111101101111111110 "; - TestHelpers.AssertDriverAttributesAre (expected, output, Application.Driver, tv.ColorScheme.Normal, color); + DriverAssert.AssertDriverAttributesAre (expected, output, Application.Driver, tv.ColorScheme.Normal, color); top.Dispose (); } @@ -452,7 +454,7 @@ public class TableViewTests (ITestOutputHelper output) │1│2 │ "; - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); // get a style for the long column ColumnStyle style = tableView.Style.GetOrCreateColumnStyle (2); @@ -470,7 +472,7 @@ public class TableViewTests (ITestOutputHelper output) │1│2│aaaaaaaaaaaaaaaaaaa│ │1│2│aaa │ "; - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); // revert the style change style.MaxWidth = TableView.DefaultMaxCellWidth; @@ -489,7 +491,7 @@ public class TableViewTests (ITestOutputHelper output) │1│2│aaaaaaaaaaaaa... │ │1│2│aaa │ "; - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); // revert style change style.RepresentationGetter = null; @@ -516,7 +518,7 @@ public class TableViewTests (ITestOutputHelper output) │1│2│aaaaaaaaaaaaaaaaaaa│ │1│2│aaa │ "; - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); // Now test making the width too small for the MinAcceptableWidth // the Column won't fit so should not be rendered @@ -534,7 +536,7 @@ public class TableViewTests (ITestOutputHelper output) │1│2 │ "; - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); // setting width to 10 leaves just enough space for the column to // meet MinAcceptableWidth of 5. Column width includes terminator line @@ -549,7 +551,7 @@ public class TableViewTests (ITestOutputHelper output) │1│2│aaaa│ │1│2│aaa │ "; - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); tableView.Viewport = new (0, 0, 25, 5); @@ -570,7 +572,7 @@ public class TableViewTests (ITestOutputHelper output) │1 │2 │aaaaaaaaaa│ │ │1 │2 │aaa │ │ "; - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); // MaxCellWidth limits MinCellWidth tableView.MaxCellWidth = 5; @@ -586,7 +588,7 @@ public class TableViewTests (ITestOutputHelper output) │1 │2 │aaaaa│ │ │1 │2 │aaa │ │ "; - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); top.Dispose (); Application.Shutdown (); @@ -716,7 +718,7 @@ public class TableViewTests (ITestOutputHelper output) ├─┼─┼─► │1│2│3│"; - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); // Scroll right tableView.NewKeyDownEvent (new () { KeyCode = KeyCode.CursorRight }); @@ -732,7 +734,7 @@ public class TableViewTests (ITestOutputHelper output) ◄─┼─┼─► │2│3│4│"; - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); // Scroll right twice more (to end of columns) tableView.NewKeyDownEvent (new () { KeyCode = KeyCode.CursorRight }); @@ -747,7 +749,7 @@ public class TableViewTests (ITestOutputHelper output) ◄─┼─┼─┤ │4│5│6│"; - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); // Shutdown must be called to safely clean up Application if Init has been called Application.Shutdown (); @@ -793,7 +795,7 @@ public class TableViewTests (ITestOutputHelper output) │A│B│C│ │1│2│3│"; - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); // Scroll right tableView.NewKeyDownEvent (new () { KeyCode = KeyCode.CursorRight }); @@ -812,7 +814,7 @@ public class TableViewTests (ITestOutputHelper output) │B│C│D│ │2│3│4│"; - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); } [Fact] @@ -853,7 +855,7 @@ public class TableViewTests (ITestOutputHelper output) │A│B│C│ │1│2│3│"; - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); // Scroll right tableView.NewKeyDownEvent (new () { KeyCode = KeyCode.CursorRight }); @@ -871,7 +873,7 @@ public class TableViewTests (ITestOutputHelper output) │D│E│F│ │4│5│6│"; - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); } @@ -959,7 +961,7 @@ public class TableViewTests (ITestOutputHelper output) 1 2 3 ───────"; - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); } [Fact] @@ -989,7 +991,7 @@ public class TableViewTests (ITestOutputHelper output) │1│2│3│ └─┴─┴─┘"; - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); } [Fact] @@ -1076,7 +1078,7 @@ public class TableViewTests (ITestOutputHelper output) ├─┼─┤ │1│2│ "; - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); var expectedColors = @" 00000 @@ -1085,7 +1087,7 @@ public class TableViewTests (ITestOutputHelper output) 01020 "; - TestHelpers.AssertDriverAttributesAre ( + DriverAssert.AssertDriverAttributesAre ( expectedColors, output, Application.Driver, @@ -1110,7 +1112,7 @@ public class TableViewTests (ITestOutputHelper output) ├─┼─┤ │1│5│ "; - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); expectedColors = @" 00000 @@ -1122,7 +1124,7 @@ public class TableViewTests (ITestOutputHelper output) // now we only see 2 colors used (the selected cell color and Normal // cellHighlight should no longer be used because the delegate returned null // (now that the cell value is 5 - which does not match the conditional) - TestHelpers.AssertDriverAttributesAre ( + DriverAssert.AssertDriverAttributesAre ( expectedColors, output, Application.Driver, @@ -1172,7 +1174,7 @@ public class TableViewTests (ITestOutputHelper output) ├─┼─┤ │1│2│ "; - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); var expectedColors = @" 00000 @@ -1181,7 +1183,7 @@ public class TableViewTests (ITestOutputHelper output) 21222 "; - TestHelpers.AssertDriverAttributesAre ( + DriverAssert.AssertDriverAttributesAre ( expectedColors, output, Application.Driver, @@ -1205,7 +1207,7 @@ public class TableViewTests (ITestOutputHelper output) ├─┼─┤ │1│5│ "; - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); expectedColors = @" 00000 @@ -1217,7 +1219,7 @@ public class TableViewTests (ITestOutputHelper output) // now we only see 2 colors used (the selected cell color and Normal // rowHighlight should no longer be used because the delegate returned null // (now that the cell value is 5 - which does not match the conditional) - TestHelpers.AssertDriverAttributesAre ( + DriverAssert.AssertDriverAttributesAre ( expectedColors, output, Application.Driver, @@ -1254,7 +1256,7 @@ public class TableViewTests (ITestOutputHelper output) ├─┼─┤ │1│2│ "; - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); var expectedColors = @" 00000 @@ -1263,7 +1265,7 @@ public class TableViewTests (ITestOutputHelper output) 01000 "; - TestHelpers.AssertDriverAttributesAre ( + DriverAssert.AssertDriverAttributesAre ( expectedColors, output, Application.Driver, @@ -1297,7 +1299,7 @@ public class TableViewTests (ITestOutputHelper output) ├─┼─┤ │1│2│ "; - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); var expectedColors = @" 00000 @@ -1309,7 +1311,7 @@ public class TableViewTests (ITestOutputHelper output) var invertFocus = new Attribute (tv.ColorScheme.Focus.Background, tv.ColorScheme.Focus.Foreground); var invertHotNormal = new Attribute (tv.ColorScheme.HotNormal.Background, tv.ColorScheme.HotNormal.Foreground); - TestHelpers.AssertDriverAttributesAre ( + DriverAssert.AssertDriverAttributesAre ( expectedColors, output, Application.Driver, @@ -1336,7 +1338,7 @@ public class TableViewTests (ITestOutputHelper output) ├─┼─┼────┤ │1│2│ │ "; - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); } @@ -1360,7 +1362,7 @@ public class TableViewTests (ITestOutputHelper output) ├─┼─┤ │1│2│ "; - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); } [Fact] @@ -1380,7 +1382,7 @@ public class TableViewTests (ITestOutputHelper output) ├─┼──────┤ │1│2 │ "; - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); } [Fact] @@ -1404,7 +1406,7 @@ public class TableViewTests (ITestOutputHelper output) ├─┼─► │1│2│ "; - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); } [Fact] @@ -1423,7 +1425,7 @@ public class TableViewTests (ITestOutputHelper output) var expected = @" │1│2│ "; - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); } [Fact] @@ -1443,7 +1445,7 @@ public class TableViewTests (ITestOutputHelper output) ┌─┬─┐ │1│2│ "; - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); } [Fact] @@ -1466,7 +1468,7 @@ public class TableViewTests (ITestOutputHelper output) ├─┼─► │1│2│ "; - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); } [Fact] @@ -1592,7 +1594,7 @@ public class TableViewTests (ITestOutputHelper output) │trap │p │ │zoo │o │"; - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); Assert.Equal (0, tv.SelectedRow); @@ -1672,7 +1674,7 @@ public class TableViewTests (ITestOutputHelper output) │1│2│3│ │1│2│3│"; - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); // ---------------- X=0 ----------------------- // click is before first cell @@ -1750,7 +1752,7 @@ public class TableViewTests (ITestOutputHelper output) │1│2│3│ │1│2│3│"; - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); int? col; // ---------------- X=0 ----------------------- @@ -1862,13 +1864,13 @@ public class TableViewTests (ITestOutputHelper output) "; tableView.Draw (); - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); // expect behavior to match when Table is null tableView.Table = null; tableView.Draw (); - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); } [InlineData (true)] @@ -1916,7 +1918,7 @@ public class TableViewTests (ITestOutputHelper output) ├─┼─┼─► │2│3│4│"; - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); } [InlineData (true)] @@ -1968,7 +1970,7 @@ public class TableViewTests (ITestOutputHelper output) ◄─┼─┼─► │2│3│4│"; - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); // but if E and F are invisible so we shouldn't show right tableView.Style.GetOrCreateColumnStyle (4).Visible = false; @@ -1983,7 +1985,7 @@ public class TableViewTests (ITestOutputHelper output) View.SetClipToScreen (); tableView.Draw (); - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); // now also A is invisible so we cannot scroll in either direction tableView.Style.GetOrCreateColumnStyle (0).Visible = false; @@ -1997,7 +1999,7 @@ public class TableViewTests (ITestOutputHelper output) View.SetClipToScreen (); tableView.Draw (); - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); } [Fact] @@ -2020,7 +2022,7 @@ public class TableViewTests (ITestOutputHelper output) ├─┼─┼─► │1│2│3│"; - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); // but if DEF are invisible we shouldn't be showing the indicator tableView.Style.GetOrCreateColumnStyle (3).Visible = false; @@ -2035,7 +2037,7 @@ public class TableViewTests (ITestOutputHelper output) tableView.SetNeedsDraw (); View.SetClipToScreen (); tableView.Draw (); - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); } [Fact] @@ -2115,7 +2117,7 @@ public class TableViewTests (ITestOutputHelper output) │A│C│D│ │1│3│4│"; - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); } [Fact] @@ -2239,7 +2241,7 @@ public class TableViewTests (ITestOutputHelper output) │Int32 │System │System.ValueType │ │Single│System │System.ValueType │"; - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); } [Fact] @@ -2276,7 +2278,7 @@ public class TableViewTests (ITestOutputHelper output) │1│2│3│ └─┴─┴─┘"; - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); Attribute normal = tv.ColorScheme.Normal; tv.ColorScheme = new (tv.ColorScheme) { Focus = new (Color.Magenta, Color.White) }; @@ -2295,7 +2297,7 @@ public class TableViewTests (ITestOutputHelper output) 0101010 0000000"; - TestHelpers.AssertDriverAttributesAre (expected, output, Application.Driver, normal, focus); + DriverAssert.AssertDriverAttributesAre (expected, output, Application.Driver, normal, focus); } [Fact] @@ -2330,7 +2332,7 @@ A B C 1 2 3 1 2 3"; - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); Attribute normal = tv.ColorScheme.Normal; tv.ColorScheme = new (tv.ColorScheme) { Focus = new (Color.Magenta, Color.White) }; @@ -2348,7 +2350,7 @@ A B C 000000 111111"; - TestHelpers.AssertDriverAttributesAre (expected, output, Application.Driver, normal, focus); + DriverAssert.AssertDriverAttributesAre (expected, output, Application.Driver, normal, focus); } [Fact] @@ -2384,7 +2386,7 @@ A B C │1│2│3│ └─┴─┴─┘"; - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); Attribute normal = tv.ColorScheme.Normal; tv.ColorScheme = new (tv.ColorScheme) { Focus = new (Color.Magenta, Color.White) }; @@ -2404,7 +2406,7 @@ A B C 0111110 0000000"; - TestHelpers.AssertDriverAttributesAre (expected, output, Application.Driver, normal, focus); + DriverAssert.AssertDriverAttributesAre (expected, output, Application.Driver, normal, focus); } [Theory] @@ -2488,7 +2490,7 @@ A B C } } - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); } [InlineData (true)] @@ -2599,7 +2601,7 @@ A B C │☐│Tibbles│Cat │ │☐│Ripper │Dog │"; - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); #pragma warning disable xUnit2029 Assert.Empty (pets.Where (p => p.IsPicked)); @@ -2621,7 +2623,7 @@ A B C │☐│Tibbles│Cat │ │☐│Ripper │Dog │"; - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); tv.NewKeyDownEvent (Key.CursorDown); tv.NewKeyDownEvent (Key.Space); @@ -2641,7 +2643,7 @@ A B C │☑│Tibbles│Cat │ │☐│Ripper │Dog │"; - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); tv.NewKeyDownEvent (Key.CursorUp); tv.NewKeyDownEvent (Key.Space); @@ -2661,7 +2663,7 @@ A B C │☑│Tibbles│Cat │ │☐│Ripper │Dog │"; - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); } [Fact] @@ -2695,7 +2697,7 @@ A B C tv.NewKeyDownEvent (Key.Space); // Because at least 1 of the rows is not yet ticked we toggle them all to ticked - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); Assert.Contains (0, wrapper.CheckedRows); Assert.Contains (1, wrapper.CheckedRows); Assert.Contains (2, wrapper.CheckedRows); @@ -2712,7 +2714,7 @@ A B C │☑│1│2│ │☑│1│2│"; - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); // Untoggle the top 2 tv.NewKeyDownEvent (Key.Space); @@ -2727,7 +2729,7 @@ A B C │☐│1│2│ │☐│1│2│ │☑│1│2│"; - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); Assert.Single (wrapper.CheckedRows, 2); } @@ -2757,7 +2759,7 @@ A B C │☑│1│2│ │☑│1│2│"; - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); Assert.Contains (0, wrapper.CheckedRows); Assert.Contains (1, wrapper.CheckedRows); Assert.Contains (2, wrapper.CheckedRows); @@ -2777,7 +2779,7 @@ A B C │☐│1│2│ │☐│1│2│"; - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); Assert.Empty (wrapper.CheckedRows); } @@ -2819,7 +2821,7 @@ A B C │☑│Tibbles│Cat │ │☑│Ripper │Dog │"; - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); tv.NewKeyDownEvent (Key.Space); @@ -2840,7 +2842,7 @@ A B C │☐│Ripper │Dog │ "; - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); } [Fact] @@ -2865,7 +2867,7 @@ A B C │☐│1│2│ │☐│1│2│"; - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); Assert.Empty (wrapper.CheckedRows); @@ -2885,7 +2887,7 @@ A B C │☐│1│2│ │☐│1│2│"; - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); tv.NewKeyDownEvent (Key.CursorDown); tv.NewKeyDownEvent (Key.Space); @@ -2905,7 +2907,7 @@ A B C │☑│1│2│ │☐│1│2│"; - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); // untoggle top one tv.NewKeyDownEvent (Key.CursorUp); @@ -2924,7 +2926,7 @@ A B C │☑│1│2│ │☐│1│2│"; - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); } [Fact] @@ -2958,7 +2960,7 @@ A B C │○│Ripper │Dog │ "; - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); #pragma warning disable xUnit2029 Assert.Empty (pets.Where (p => p.IsPicked)); @@ -2980,7 +2982,7 @@ A B C │○│Tibbles│Cat │ │○│Ripper │Dog │"; - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); tv.NewKeyDownEvent (Key.CursorDown); tv.NewKeyDownEvent (Key.Space); @@ -3001,7 +3003,7 @@ A B C │◉│Tibbles│Cat │ │○│Ripper │Dog │"; - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); tv.NewKeyDownEvent (Key.CursorUp); tv.NewKeyDownEvent (Key.Space); @@ -3022,7 +3024,7 @@ A B C │○│Tibbles│Cat │ │○│Ripper │Dog │"; - TestHelpers.AssertDriverContentsAre (expected, output); + DriverAssert.AssertDriverContentsAre (expected, output); } [Fact] diff --git a/UnitTests/Views/TextFieldTests.cs b/Tests/UnitTests/Views/TextFieldTests.cs similarity index 98% rename from UnitTests/Views/TextFieldTests.cs rename to Tests/UnitTests/Views/TextFieldTests.cs index 03e9c1d39..a80e67961 100644 --- a/UnitTests/Views/TextFieldTests.cs +++ b/Tests/UnitTests/Views/TextFieldTests.cs @@ -1,6 +1,8 @@ using System.Globalization; using System.Reflection; using System.Text; +using UnitTests; +using UnitTests; using Xunit.Abstractions; namespace Terminal.Gui.ViewsTests; @@ -17,7 +19,7 @@ public class TextFieldTests (ITestOutputHelper output) tf.Layout (); tf.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ắ", output @@ -27,7 +29,7 @@ public class TextFieldTests (ITestOutputHelper output) tf.Layout (); tf.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ắ", output @@ -37,7 +39,7 @@ public class TextFieldTests (ITestOutputHelper output) tf.Layout (); tf.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ắ", output @@ -47,7 +49,7 @@ public class TextFieldTests (ITestOutputHelper output) tf.Layout (); tf.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ắ", output @@ -170,7 +172,7 @@ public class TextFieldTests (ITestOutputHelper output) Assert.False (tf.HasFocus); tf.Draw (); - TestHelpers.AssertDriverContentsAre (expectedRender, output); + DriverAssert.AssertDriverContentsAre (expectedRender, output); Application.Top.Dispose (); } @@ -190,7 +192,7 @@ public class TextFieldTests (ITestOutputHelper output) Assert.False (tf.HasFocus); tf.Draw (); - TestHelpers.AssertDriverContentsAre ("Misérables", output); + DriverAssert.AssertDriverContentsAre ("Misérables", output); Application.Top.Dispose (); } @@ -203,7 +205,7 @@ public class TextFieldTests (ITestOutputHelper output) TextField tf = GetTextFieldsInView (); tf.Draw (); - TestHelpers.AssertDriverContentsAre ("", output); + DriverAssert.AssertDriverContentsAre ("", output); tf.Caption = "Enter txt"; Application.Driver?.SendKeys ('\t', ConsoleKey.Tab, false, false, false); @@ -212,13 +214,13 @@ public class TextFieldTests (ITestOutputHelper output) Assert.False (tf.HasFocus); View.SetClipToScreen (); tf.Draw (); - TestHelpers.AssertDriverContentsAre ("Enter txt", output); + DriverAssert.AssertDriverContentsAre ("Enter txt", output); // but disapear when text is added tf.Text = content; View.SetClipToScreen (); tf.Draw (); - TestHelpers.AssertDriverContentsAre (content, output); + DriverAssert.AssertDriverContentsAre (content, output); Application.Top.Dispose (); } @@ -229,21 +231,21 @@ public class TextFieldTests (ITestOutputHelper output) TextField tf = GetTextFieldsInView (); tf.Draw (); - TestHelpers.AssertDriverContentsAre ("", output); + DriverAssert.AssertDriverContentsAre ("", output); // Caption has no effect when focused tf.Caption = "Enter txt"; Assert.True (tf.HasFocus); View.SetClipToScreen (); tf.Draw (); - TestHelpers.AssertDriverContentsAre ("", output); + DriverAssert.AssertDriverContentsAre ("", output); Application.Driver?.SendKeys ('\t', ConsoleKey.Tab, false, false, false); Assert.False (tf.HasFocus); View.SetClipToScreen (); tf.Draw (); - TestHelpers.AssertDriverContentsAre ("Enter txt", output); + DriverAssert.AssertDriverContentsAre ("Enter txt", output); Application.Top.Dispose (); } @@ -1082,7 +1084,7 @@ public class TextFieldTests (ITestOutputHelper output) }; // TAB to jump between text fields. - TestHelpers.AssertDriverAttributesAre ("0000000", output, Application.Driver, attributes); + DriverAssert.AssertDriverAttributesAre ("0000000", output, Application.Driver, attributes); // Cursor is at the end Assert.Equal (32, _textField.CursorPosition); @@ -1093,7 +1095,7 @@ public class TextFieldTests (ITestOutputHelper output) Assert.Equal (4, _textField.CursorPosition); // TAB to jump between text fields. - TestHelpers.AssertDriverAttributesAre ("1111000", output, Application.Driver, attributes); + DriverAssert.AssertDriverAttributesAre ("1111000", output, Application.Driver, attributes); top.Dispose (); } @@ -1980,7 +1982,7 @@ public class TextFieldTests (ITestOutputHelper output) tf.SetRelativeLayout (new (100, 100)); tf.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" Les Misérables", output @@ -1989,7 +1991,7 @@ Les Misérables", tf.Text = "Les Mise" + char.ConvertFromUtf32 (int.Parse ("0301", NumberStyles.HexNumber)) + "rables"; tf.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" Les Misérables", output @@ -2000,7 +2002,7 @@ Les Misérables", View.SetClipToScreen (); tf.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" Les Miśerables", output @@ -2173,7 +2175,7 @@ Les Miśerables", tf.EndInit (); tf.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ("\u241b", output); + DriverAssert.AssertDriverContentsWithFrameAre ("\u241b", output); tf.Dispose (); } diff --git a/UnitTests/Views/TextValidateFieldTests.cs b/Tests/UnitTests/Views/TextValidateFieldTests.cs similarity index 100% rename from UnitTests/Views/TextValidateFieldTests.cs rename to Tests/UnitTests/Views/TextValidateFieldTests.cs diff --git a/UnitTests/Views/TextViewTests.cs b/Tests/UnitTests/Views/TextViewTests.cs similarity index 99% rename from UnitTests/Views/TextViewTests.cs rename to Tests/UnitTests/Views/TextViewTests.cs index ab04015ec..aed7bd09e 100644 --- a/UnitTests/Views/TextViewTests.cs +++ b/Tests/UnitTests/Views/TextViewTests.cs @@ -2,6 +2,8 @@ using System.Reflection; using System.Text; using System.Text.RegularExpressions; using Xunit.Abstractions; +using UnitTests; +using UnitTests; namespace Terminal.Gui.ViewsTests; @@ -727,7 +729,7 @@ public class TextViewTests Assert.False (tv.WordWrap); Assert.Equal (Point.Empty, tv.CursorPosition); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" This is the first line. This is the second line. @@ -741,7 +743,7 @@ This is the second line. Application.RunIteration (ref rs); Assert.Equal (new Point (2, 0), tv.CursorPosition); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" Ths is the first line. This is the second line. @@ -755,7 +757,7 @@ This is the second line. Application.RunIteration (ref rs); Assert.Equal (new Point (22, 0), tv.CursorPosition); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" Ths is the first line.This is the second line. ", @@ -766,7 +768,7 @@ Ths is the first line.This is the second line. Application.RunIteration (ref rs); Assert.Equal (new Point (0, 1), tv.CursorPosition); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" Ths is the first line. This is the second line. @@ -801,7 +803,7 @@ This is the second line. Assert.True (tv.WordWrap); Assert.Equal (Point.Empty, tv.CursorPosition); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" This is the first line. This is the second line. @@ -815,7 +817,7 @@ This is the second line. Application.RunIteration (ref rs); Assert.Equal (new Point (2, 0), tv.CursorPosition); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" Ths is the first line. This is the second line. @@ -829,7 +831,7 @@ This is the second line. Application.RunIteration (ref rs); Assert.Equal (new Point (22, 0), tv.CursorPosition); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" Ths is the first line.This is the second line. ", @@ -840,7 +842,7 @@ Ths is the first line.This is the second line. Application.RunIteration (ref rs); Assert.Equal (new Point (0, 1), tv.CursorPosition); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" Ths is the first line. This is the second line. @@ -875,7 +877,7 @@ This is the second line. Assert.False (tv.WordWrap); Assert.Equal (Point.Empty, tv.CursorPosition); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" This is the first line. This is the second line. @@ -889,7 +891,7 @@ This is the second line. Application.RunIteration (ref rs); Assert.Equal (new Point (2, 0), tv.CursorPosition); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" Ths is the first line. This is the second line. @@ -903,7 +905,7 @@ This is the second line. Application.RunIteration (ref rs); Assert.Equal (new Point (22, 0), tv.CursorPosition); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" Ths is the first line.This is the second line. ", @@ -914,7 +916,7 @@ Ths is the first line.This is the second line. Application.RunIteration (ref rs); Assert.Equal (new Point (0, 1), tv.CursorPosition); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" Ths is the first line. This is the second line. @@ -948,7 +950,7 @@ This is the second line. Assert.True (tv.WordWrap); Assert.Equal (Point.Empty, tv.CursorPosition); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" This is the first line. This is the second line. @@ -962,7 +964,7 @@ This is the second line. Application.RunIteration (ref rs); Assert.Equal (new Point (2, 0), tv.CursorPosition); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" Ths is the first line. This is the second line. @@ -976,7 +978,7 @@ This is the second line. Application.RunIteration (ref rs); Assert.Equal (new Point (22, 0), tv.CursorPosition); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" Ths is the first line.This is the second line. ", @@ -987,7 +989,7 @@ Ths is the first line.This is the second line. Application.RunIteration (ref rs); Assert.Equal (new Point (0, 1), tv.CursorPosition); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" Ths is the first line. This is the second line. @@ -6366,7 +6368,7 @@ This is the second line. }; // TAB to jump between text fields. - TestHelpers.AssertDriverAttributesAre ("0000000", _output, Application.Driver, attributes); + DriverAssert.AssertDriverAttributesAre ("0000000", _output, Application.Driver, attributes); Assert.Empty (_textView.SelectedCellsList); _textView.NewKeyDownEvent (Key.CursorRight.WithCtrl.WithShift); @@ -6375,7 +6377,7 @@ This is the second line. Assert.Equal (new Point (4, 0), _textView.CursorPosition); // TAB to jump between text fields. - TestHelpers.AssertDriverAttributesAre ("1111000", _output, Application.Driver, attributes); + DriverAssert.AssertDriverAttributesAre ("1111000", _output, Application.Driver, attributes); Assert.Equal ("TAB ", Cell.ToString (_textView.SelectedCellsList [^1])); top.Dispose (); } @@ -6743,7 +6745,7 @@ This is the second line. Assert.Equal ("\tTAB to jump between text fields.", _textView.Text); Application.LayoutAndDraw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" TAB to jump between text field", _output @@ -6752,7 +6754,7 @@ TAB to jump between text field", _textView.TabWidth = 4; Application.LayoutAndDraw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" TAB to jump between text f", _output @@ -6763,7 +6765,7 @@ TAB to jump between text field", Assert.True (_textView.NeedsDraw); Application.LayoutAndDraw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" TAB to jump between text field", _output @@ -6830,7 +6832,7 @@ TAB to jump between text field", Application.LayoutAndDraw (); //this passes - Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre ( + Rectangle pos = DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌─────────────┐ │ │ @@ -6858,7 +6860,7 @@ TAB to jump between text field", tv.InsertText ("\r\naaa\r\nbbb"); Application.LayoutAndDraw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌─────────────┐ │ │ @@ -6908,7 +6910,7 @@ TAB to jump between text field", Application.LayoutAndDraw (); //this passes - Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre ( + Rectangle pos = DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌─────────────┐ │ │ @@ -6936,7 +6938,7 @@ TAB to jump between text field", tv.InsertText ("\naaa\nbbb"); Application.LayoutAndDraw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌─────────────┐ │ │ @@ -7009,7 +7011,7 @@ TAB to jump between text field", Assert.Equal (Point.Empty, tv.CursorPosition); Assert.Equal (Point.Empty, cp); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" This is the first line. This is the second line. @@ -7023,7 +7025,7 @@ This is the second line. Assert.Equal (new Point (12, 0), tv.CursorPosition); Assert.Equal (new Point (12, 0), cp); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" This is the first line. This is the second line. @@ -7037,7 +7039,7 @@ This is the second line. Assert.Equal (new Point (4, 2), tv.CursorPosition); Assert.Equal (new Point (12, 0), cp); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" This is @@ -7060,7 +7062,7 @@ line. Assert.Equal (new Point (0, 3), tv.CursorPosition); Assert.Equal (new Point (12, 0), cp); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" This is @@ -7083,7 +7085,7 @@ line. Assert.Equal (new Point (1, 3), tv.CursorPosition); Assert.Equal (new Point (13, 0), cp); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" This is @@ -7106,7 +7108,7 @@ line. Assert.Equal (new Point (0, 3), tv.CursorPosition); Assert.Equal (new Point (13, 0), cp); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" This is @@ -8181,7 +8183,7 @@ line. Assert.Equal (Point.Empty, tv.CursorPosition); Assert.Equal (0, tv.LeftColumn); - TestHelpers.AssertDriverContentsAre ( + DriverAssert.AssertDriverContentsAre ( @" aaaa ", @@ -8193,7 +8195,7 @@ aaaa Application.LayoutAndDraw (); Assert.Equal (0, tv.LeftColumn); - TestHelpers.AssertDriverContentsAre ( + DriverAssert.AssertDriverContentsAre ( @" aaa ", @@ -8204,7 +8206,7 @@ aaa Application.LayoutAndDraw (); Assert.Equal (0, tv.LeftColumn); - TestHelpers.AssertDriverContentsAre ( + DriverAssert.AssertDriverContentsAre ( @" aa ", @@ -8215,7 +8217,7 @@ aa Application.LayoutAndDraw (); Assert.Equal (0, tv.LeftColumn); - TestHelpers.AssertDriverContentsAre ( + DriverAssert.AssertDriverContentsAre ( @" a ", @@ -8226,7 +8228,7 @@ a Application.LayoutAndDraw (); Assert.Equal (0, tv.LeftColumn); - TestHelpers.AssertDriverContentsAre ( + DriverAssert.AssertDriverContentsAre ( @" ", @@ -8237,7 +8239,7 @@ a Application.LayoutAndDraw (); Assert.Equal (0, tv.LeftColumn); - TestHelpers.AssertDriverContentsAre ( + DriverAssert.AssertDriverContentsAre ( @" ", @@ -8260,7 +8262,7 @@ a Assert.True (_textView.WordWrap); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" Line 1. Line 2.", @@ -8272,13 +8274,13 @@ Line 2.", Assert.True (_textView.NewKeyDownEvent (new Key (del))); Application.LayoutAndDraw (); - TestHelpers.AssertDriverContentsWithFrameAre ("Line 2.", _output); + DriverAssert.AssertDriverContentsWithFrameAre ("Line 2.", _output); Assert.True (_textView.NewKeyDownEvent (Key.H.WithShift)); Assert.NotEqual (Rectangle.Empty, _textView._needsDrawRect); Application.LayoutAndDraw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" H Line 2.", @@ -8335,7 +8337,7 @@ Line 2.", top.Layout (); tv.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" This is the first @@ -8355,7 +8357,7 @@ line. View.SetClipToScreen (); tv.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" This is the first @@ -8441,7 +8443,7 @@ line. top.Layout (); tv.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" This is the @@ -8860,7 +8862,7 @@ line. tv.EndInit (); tv.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre ("\u241b", _output); + DriverAssert.AssertDriverContentsWithFrameAre ("\u241b", _output); tv.Dispose (); } @@ -8916,7 +8918,7 @@ line. Application.Begin (top); Application.LayoutAndDraw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" This is the first line. This is the second line.", @@ -8928,7 +8930,7 @@ This is the second line.", tv.WordWrap = true; Application.LayoutAndDraw (); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" This is the @@ -8978,7 +8980,7 @@ Base Dialog Menu Error "; - TestHelpers.AssertDriverContentsWithFrameAre (expectedText, _output); + DriverAssert.AssertDriverContentsWithFrameAre (expectedText, _output); Attribute [] attributes = { @@ -9007,12 +9009,12 @@ Error "; 2222225555 3333555555 4444455555"; - TestHelpers.AssertDriverAttributesAre (expectedColor, _output, Application.Driver, attributes); + DriverAssert.AssertDriverAttributesAre (expectedColor, _output, Application.Driver, attributes); tv.WordWrap = true; Application.LayoutAndDraw (); - TestHelpers.AssertDriverContentsWithFrameAre (expectedText, _output); - TestHelpers.AssertDriverAttributesAre (expectedColor, _output, Application.Driver, attributes); + DriverAssert.AssertDriverContentsWithFrameAre (expectedText, _output); + DriverAssert.AssertDriverAttributesAre (expectedColor, _output, Application.Driver, attributes); tv.CursorPosition = new (6, 2); tv.SelectionStartColumn = 0; @@ -9032,7 +9034,7 @@ Menu ErTopLevel Base Dialogror "; - TestHelpers.AssertDriverContentsWithFrameAre (expectedText, _output); + DriverAssert.AssertDriverContentsWithFrameAre (expectedText, _output); expectedColor = @" 0000000055 @@ -9042,7 +9044,7 @@ Dialogror "; 4400000000 1111555555 2222224445"; - TestHelpers.AssertDriverAttributesAre (expectedColor, _output, Application.Driver, attributes); + DriverAssert.AssertDriverAttributesAre (expectedColor, _output, Application.Driver, attributes); tv.Undo (); tv.CursorPosition = new (0, 3); @@ -9068,7 +9070,7 @@ ErTopLevel Base Dialog ror "; - TestHelpers.AssertDriverContentsWithFrameAre (expectedText, _output); + DriverAssert.AssertDriverContentsWithFrameAre (expectedText, _output); expectedColor = @" 0000000055 @@ -9079,7 +9081,7 @@ ror "; 1111555555 2222225555 4445555555"; - TestHelpers.AssertDriverAttributesAre (expectedColor, _output, Application.Driver, attributes); + DriverAssert.AssertDriverAttributesAre (expectedColor, _output, Application.Driver, attributes); Application.End (rs); top.Dispose (); diff --git a/UnitTests/Views/TileViewTests.cs b/Tests/UnitTests/Views/TileViewTests.cs similarity index 90% rename from UnitTests/Views/TileViewTests.cs rename to Tests/UnitTests/Views/TileViewTests.cs index 5a0f18238..a8301280e 100644 --- a/UnitTests/Views/TileViewTests.cs +++ b/Tests/UnitTests/Views/TileViewTests.cs @@ -1,4 +1,6 @@ -using Xunit.Abstractions; +using UnitTests; +using UnitTests; +using Xunit.Abstractions; namespace Terminal.Gui.ViewsTests; @@ -43,7 +45,7 @@ public class TileViewTests │ │ └──────────────────┘"; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); } [Fact] @@ -64,7 +66,7 @@ public class TileViewTests │ │ │ │ │ │ └────┴────┴────┴────┴───┘ "; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); for (var x = 0; x <= 5; x++) { @@ -95,7 +97,7 @@ public class TileViewTests │ ││ │ │ │ └────────┴┴────┴────┴───┘ "; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); } [Fact] @@ -116,7 +118,7 @@ public class TileViewTests │ │ │ │ │ │ │ │ "; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); for (var x = 0; x <= 5; x++) { @@ -149,7 +151,7 @@ public class TileViewTests ││ │ │ "; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); } [Fact] @@ -171,7 +173,7 @@ public class TileViewTests │ │ │ │ │ │ └────┴────┴────┴────┴───┘ "; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); for (var x = 10; x > 7; x--) { @@ -193,7 +195,7 @@ public class TileViewTests │ │ │ │ │ │ └────┴──┴──────┴────┴───┘ "; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); for (var x = 10; x < 12; x++) { @@ -215,7 +217,7 @@ public class TileViewTests │ │ │ │ │ │ └────┴─────┴───┴────┴───┘ "; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); } [Fact] @@ -236,7 +238,7 @@ public class TileViewTests │ │ │ │ │ │ │ │ "; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); for (var x = 10; x > 7; x--) { @@ -260,7 +262,7 @@ public class TileViewTests │ │ │ │ "; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); for (var x = 10; x < 12; x++) { @@ -283,7 +285,7 @@ public class TileViewTests │ │ │ │ "; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); } [Fact] @@ -305,7 +307,7 @@ public class TileViewTests │ │ │ │ │ │ └────┴────┴────┴────┴───┘ "; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); for (var x = 20; x > 17; x--) { @@ -328,7 +330,7 @@ public class TileViewTests └────┴────┴────┴──┴─────┘ "; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); for (var x = 20; x < 23; x++) { @@ -350,7 +352,7 @@ public class TileViewTests │ │ │ │ │ │ └────┴────┴────┴──────┴─┘ "; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); } [Fact] @@ -372,7 +374,7 @@ public class TileViewTests │ │ │ │ │ │ │ │ "; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); for (var x = 20; x > 17; x--) { @@ -394,7 +396,7 @@ public class TileViewTests │ │ │ │ │ │ │ │ "; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); for (var x = 20; x < 24; x++) { @@ -416,7 +418,7 @@ public class TileViewTests │ │ │ │ │ │ │ │ "; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); } [Fact] @@ -435,7 +437,7 @@ public class TileViewTests │ │ │ │ │ │ └────┴────┴────┴────┴───┘ "; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); for (var x = 5; x > 0; x--) { @@ -454,7 +456,7 @@ public class TileViewTests ││ │ │ │ │ └┴────────┴────┴────┴───┘ "; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); for (var x = 6; x < 10; x++) { @@ -478,7 +480,7 @@ public class TileViewTests │ ││ │ │ │ └────────┴┴────┴────┴───┘ "; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); } [Fact] @@ -497,7 +499,7 @@ public class TileViewTests │ │ │ │ │ │ │ │ "; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); for (var x = 5; x >= 0; x--) { @@ -514,7 +516,7 @@ public class TileViewTests │ │ │ │ │ │ │ │ "; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); for (var x = 6; x < 10; x++) { @@ -538,7 +540,7 @@ public class TileViewTests ││ │ │ "; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); } [Fact] @@ -556,7 +558,7 @@ public class TileViewTests │ │ │ │ │ │ └────┴────┴────┴────┴───┘ "; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); for (var x = 10; x > 5; x--) { @@ -577,7 +579,7 @@ public class TileViewTests │ ││ │ │ │ └────┴┴────────┴────┴───┘ "; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); for (var x = 10; x < 15; x++) { @@ -599,7 +601,7 @@ public class TileViewTests │ │ ││ │ │ └────┴────────┴┴────┴───┘ "; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); } [Fact] @@ -618,7 +620,7 @@ public class TileViewTests │ │ │ │ │ │ │ │ "; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); for (var x = 10; x > 5; x--) { @@ -640,7 +642,7 @@ public class TileViewTests ││ │ │ "; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); for (var x = 10; x < 15; x++) { @@ -662,7 +664,7 @@ public class TileViewTests │ ││ │ │ ││ │ "; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); } [Fact] @@ -681,7 +683,7 @@ public class TileViewTests │ │ │ │ │ │ └────┴────┴────┴────┴───┘ "; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); for (var x = 20; x > 15; x--) { @@ -703,7 +705,7 @@ public class TileViewTests │ │ │ ││ │ └────┴────┴────┴┴───────┘ "; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); for (var x = 20; x < 24; x++) { @@ -725,7 +727,7 @@ public class TileViewTests │ │ │ │ ││ └────┴────┴────┴───────┴┘ "; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); } [Fact] @@ -744,7 +746,7 @@ public class TileViewTests │ │ │ │ │ │ │ │ "; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); for (var x = 20; x > 15; x--) { @@ -767,7 +769,7 @@ public class TileViewTests │ │ ││ "; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); for (var x = 20; x < 25; x++) { @@ -789,7 +791,7 @@ public class TileViewTests │ │ │ │ │ │ │ │ "; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); } [Fact] @@ -915,7 +917,7 @@ public class TileViewTests │ │ │"; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); } [Fact] @@ -939,7 +941,7 @@ public class TileViewTests 111111│222222│444444 111111│222222│444444 "; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); // It looks good but lets double check the measurements incase // anything is sticking out but drawn over @@ -1004,7 +1006,7 @@ public class TileViewTests │11111│222222│44444│ └─────┴──────┴─────┘"; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); tileView.Tiles.ElementAt (0).ContentView.Visible = false; tileView.Tiles.ElementAt (1).ContentView.Visible = true; @@ -1025,7 +1027,7 @@ public class TileViewTests │222222222222│44444│ └────────────┴─────┘"; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); tileView.Tiles.ElementAt (0).ContentView.Visible = true; tileView.Tiles.ElementAt (1).ContentView.Visible = false; @@ -1044,7 +1046,7 @@ public class TileViewTests │111111111111│44444│ └────────────┴─────┘"; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); tileView.Tiles.ElementAt (0).ContentView.Visible = true; tileView.Tiles.ElementAt (1).ContentView.Visible = true; @@ -1064,7 +1066,7 @@ public class TileViewTests │11111│222222222222│ └─────┴────────────┘"; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); tileView.Tiles.ElementAt (0).ContentView.Visible = true; tileView.Tiles.ElementAt (1).ContentView.Visible = false; @@ -1085,7 +1087,7 @@ public class TileViewTests │111111111111111111│ └──────────────────┘"; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); tileView.Tiles.ElementAt (0).ContentView.Visible = false; tileView.Tiles.ElementAt (1).ContentView.Visible = true; @@ -1106,7 +1108,7 @@ public class TileViewTests │222222222222222222│ └──────────────────┘"; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); tileView.Tiles.ElementAt (0).ContentView.Visible = false; tileView.Tiles.ElementAt (1).ContentView.Visible = false; @@ -1127,9 +1129,9 @@ public class TileViewTests │444444444444444444│ └──────────────────┘"; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); tileView.Tiles.ElementAt (0).ContentView.Visible = false; tileView.Tiles.ElementAt (1).ContentView.Visible = false; @@ -1150,7 +1152,7 @@ public class TileViewTests │ │ └──────────────────┘"; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); } [Fact] @@ -1174,7 +1176,7 @@ public class TileViewTests 111111│222222│444444 111111│222222│444444"; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); tileView.Tiles.ElementAt (0).ContentView.Visible = false; tileView.Tiles.ElementAt (1).ContentView.Visible = true; @@ -1195,7 +1197,7 @@ public class TileViewTests 2222222222222│444444 2222222222222│444444"; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); tileView.Tiles.ElementAt (0).ContentView.Visible = true; tileView.Tiles.ElementAt (1).ContentView.Visible = false; @@ -1216,7 +1218,7 @@ public class TileViewTests 1111111111111│444444 1111111111111│444444"; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); tileView.Tiles.ElementAt (0).ContentView.Visible = true; tileView.Tiles.ElementAt (1).ContentView.Visible = true; @@ -1237,7 +1239,7 @@ public class TileViewTests 111111│2222222222222 111111│2222222222222"; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); tileView.Tiles.ElementAt (0).ContentView.Visible = true; tileView.Tiles.ElementAt (1).ContentView.Visible = false; @@ -1258,7 +1260,7 @@ public class TileViewTests 11111111111111111111 11111111111111111111"; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); tileView.Tiles.ElementAt (0).ContentView.Visible = false; tileView.Tiles.ElementAt (1).ContentView.Visible = true; @@ -1279,7 +1281,7 @@ public class TileViewTests 22222222222222222222 22222222222222222222"; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); tileView.Tiles.ElementAt (0).ContentView.Visible = false; tileView.Tiles.ElementAt (1).ContentView.Visible = false; @@ -1300,9 +1302,9 @@ public class TileViewTests 44444444444444444444 44444444444444444444"; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); tileView.Tiles.ElementAt (0).ContentView.Visible = false; tileView.Tiles.ElementAt (1).ContentView.Visible = false; @@ -1314,7 +1316,7 @@ public class TileViewTests @" "; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); } [Fact] @@ -1338,7 +1340,7 @@ public class TileViewTests │11111│444444│22222│ └─────┴──────┴─────┘"; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); } [Fact] @@ -1369,7 +1371,7 @@ public class TileViewTests │11111│444444│22222│ └─────┴──────┴─────┘"; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); } [Fact] @@ -1393,7 +1395,7 @@ public class TileViewTests │11111│222222│44444│ │11111│222222│44444│ └─────┴──────┴─────┘"; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); Tile toRemove = tileView.Tiles.ElementAt (1); Tile removed = tileView.RemoveTile (1); @@ -1414,7 +1416,7 @@ public class TileViewTests │111111111│44444444│ │111111111│44444444│ └─────────┴────────┘"; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); // cannot remove at this index because there is only one horizontal tile left Assert.Null (tileView.RemoveTile (2)); @@ -1434,7 +1436,7 @@ public class TileViewTests │444444444444444444│ │444444444444444444│ └──────────────────┘"; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); Assert.NotNull (tileView.RemoveTile (0)); Application.LayoutAndDraw (); @@ -1452,7 +1454,7 @@ public class TileViewTests │ │ │ │ └──────────────────┘"; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); // cannot remove Assert.Null (tileView.RemoveTile (0)); @@ -1478,7 +1480,7 @@ public class TileViewTests │11111│222222│44444│ │11111│222222│44444│ └─────┴──────┴─────┘"; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); // It looks good but lets double check the measurements incase // anything is sticking out but drawn over @@ -1541,7 +1543,7 @@ public class TileViewTests │11111│222222│44444│ │11111│222222│44444│ └─────┴──────┴─────┘"; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); } [Fact] @@ -1586,7 +1588,7 @@ public class TileViewTests │ │ │ └────┴───┘ "; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); } [Fact] @@ -1636,7 +1638,7 @@ public class TileViewTests │ │└─┘│ └────┴───┘ "; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); } [Fact] @@ -1674,14 +1676,14 @@ public class TileViewTests 11111111111 ─────────── 22222222222"; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); // Keyboard movement on splitter should have no effect if it is not focused bool handled = tileView.NewKeyDownEvent (Key.CursorDown); Assert.False (handled); tileView.SetNeedsDraw (); tileView.Draw (); - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); } [Fact] @@ -1702,7 +1704,7 @@ public class TileViewTests 11111111111 ─────◊───── 22222222222"; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); // Now move splitter line down tileView.NewKeyDownEvent (Key.CursorDown); @@ -1715,7 +1717,7 @@ public class TileViewTests 11111111111 11111111111 ─────◊─────"; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); // And 2 up line.NewKeyDownEvent (Key.CursorUp); @@ -1731,7 +1733,7 @@ public class TileViewTests ─────◊───── 22222222222 22222222222"; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); } [Fact] @@ -1757,7 +1759,7 @@ public class TileViewTests 11111111111 ─────◊───── 22222222222"; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); // Now move splitter line down (allowed line.NewKeyDownEvent (Key.CursorDown); @@ -1769,7 +1771,7 @@ public class TileViewTests 11111111111 11111111111 ─────◊─────"; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); // And up 2 (only 1 is allowed because of minimum size of 1 on view1) line.NewKeyDownEvent (Key.CursorUp); @@ -1784,7 +1786,7 @@ public class TileViewTests 11111111111 ─────◊───── 22222222222"; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); } [Theory] @@ -1845,7 +1847,7 @@ public class TileViewTests ┌──┬───┬──┐ │11│222│ │ └──┴───┴──┘"; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); } [Fact] @@ -1864,7 +1866,7 @@ public class TileViewTests ┌──┬───┬──┐ │ │111│22│ └──┴───┴──┘"; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); } [Fact] @@ -1883,7 +1885,7 @@ public class TileViewTests ┌──┬───┬──┐ │11│ │22│ └──┴───┴──┘"; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); } [Fact] @@ -1900,13 +1902,13 @@ public class TileViewTests 11111│22222 11111│22222 │ "; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); // Keyboard movement on splitter should have no effect if it is not focused tileView.NewKeyDownEvent (Key.CursorRight); tileView.SetNeedsDraw (); tileView.Draw (); - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); } [Fact] @@ -1924,7 +1926,7 @@ public class TileViewTests 11111│22222 11111◊22222 │ "; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); // Now while focused move the splitter 1 unit right line.NewKeyDownEvent (Key.CursorRight); @@ -1936,7 +1938,7 @@ public class TileViewTests 111111│2222 111111◊2222 │ "; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); // and 2 to the left line.NewKeyDownEvent (Key.CursorLeft); @@ -1950,7 +1952,7 @@ public class TileViewTests 1111│222222 1111◊222222 │ "; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); } [Fact] @@ -1969,7 +1971,7 @@ public class TileViewTests 11111│22222 11111◊22222 │ "; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); // Now while focused move the splitter 1 unit right line.NewKeyDownEvent (Key.CursorRight); @@ -1981,7 +1983,7 @@ public class TileViewTests 111111│2222 111111◊2222 │ "; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); // Even when moving the splitter location it should stay a Percentage based one Assert.IsType (tileView.SplitterDistances.ElementAt (0)); @@ -1998,7 +2000,7 @@ public class TileViewTests 1111│222222 1111◊222222 │ "; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); // Even when moving the splitter location it should stay a Percentage based one Assert.IsType (tileView.SplitterDistances.ElementAt (0)); @@ -2018,7 +2020,7 @@ public class TileViewTests ┌────┬────┐ │1111◊2222│ └────┴────┘"; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); // Now while focused move the splitter 1 unit right line.NewKeyDownEvent (Key.CursorRight); @@ -2030,7 +2032,7 @@ public class TileViewTests ┌─────┬───┐ │11111◊222│ └─────┴───┘"; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); // and 2 to the left line.NewKeyDownEvent (Key.CursorLeft); @@ -2044,7 +2046,7 @@ public class TileViewTests ┌───┬─────┐ │111◊22222│ └───┴─────┘"; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); } [Fact] @@ -2069,14 +2071,14 @@ public class TileViewTests 11111│22222 11111◊22222 │ "; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); // Keyboard movement on splitter should have no effect because it // would take us below the minimum splitter size line.NewKeyDownEvent (Key.CursorLeft); Application.LayoutAndDraw (); - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); // but we can continue to move the splitter right if we want line.NewKeyDownEvent (Key.CursorRight); @@ -2088,7 +2090,7 @@ public class TileViewTests 111111◊2222 │ "; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); } [Fact] @@ -2113,14 +2115,14 @@ public class TileViewTests ┌────┬────┐ │1111◊2222│ └────┴────┘"; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); // Keyboard movement on splitter should have no effect because it // would take us below the minimum splitter size line.NewKeyDownEvent (Key.CursorLeft); Application.LayoutAndDraw (); - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); // but we can continue to move the splitter right if we want line.NewKeyDownEvent (Key.CursorRight); @@ -2133,7 +2135,7 @@ public class TileViewTests │11111◊222│ └─────┴───┘"; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); } [Fact] @@ -2160,14 +2162,14 @@ public class TileViewTests 11111│22222 11111◊22222 │ "; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); // Keyboard movement on splitter should have no effect because it // would take us below the minimum splitter size line.NewKeyDownEvent (Key.CursorRight); Application.LayoutAndDraw (); - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); // but we can continue to move the splitter left if we want line.NewKeyDownEvent (Key.CursorLeft); @@ -2180,7 +2182,7 @@ public class TileViewTests 1111◊222222 │ "; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); } [Fact] @@ -2208,14 +2210,14 @@ public class TileViewTests ┌────┬────┐ │1111◊2222│ └────┴────┘"; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); // Keyboard movement on splitter should have no effect because it // would take us below the minimum splitter size line.NewKeyDownEvent (Key.CursorRight); Application.LayoutAndDraw (); - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); // but we can continue to move the splitter left if we want line.NewKeyDownEvent (Key.CursorLeft); @@ -2228,7 +2230,7 @@ public class TileViewTests │111◊22222│ └───┴─────┘"; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); } [Fact] @@ -2245,13 +2247,13 @@ public class TileViewTests ┌────┬────┐ │1111│2222│ └────┴────┘"; - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); // Keyboard movement on splitter should have no effect if it is not focused tileView.NewKeyDownEvent (Key.CursorRight); Application.LayoutAndDraw (); - TestHelpers.AssertDriverContentsAre (looksLike, _output); + DriverAssert.AssertDriverContentsAre (looksLike, _output); } [Fact] diff --git a/UnitTests/Views/TimeFieldTests.cs b/Tests/UnitTests/Views/TimeFieldTests.cs similarity index 99% rename from UnitTests/Views/TimeFieldTests.cs rename to Tests/UnitTests/Views/TimeFieldTests.cs index 1d901fcdc..81337e092 100644 --- a/UnitTests/Views/TimeFieldTests.cs +++ b/Tests/UnitTests/Views/TimeFieldTests.cs @@ -1,3 +1,5 @@ +using UnitTests; + namespace Terminal.Gui.ViewsTests; public class TimeFieldTests diff --git a/UnitTests/Views/ToplevelTests.cs b/Tests/UnitTests/Views/ToplevelTests.cs similarity index 84% rename from UnitTests/Views/ToplevelTests.cs rename to Tests/UnitTests/Views/ToplevelTests.cs index 8c45ad6f0..b7a776e9d 100644 --- a/UnitTests/Views/ToplevelTests.cs +++ b/Tests/UnitTests/Views/ToplevelTests.cs @@ -1,7 +1,16 @@ -namespace Terminal.Gui.ViewsTests; +using UnitTests; -public partial class ToplevelTests () +namespace Terminal.Gui.ViewsTests; + +public partial class ToplevelTests { + public ToplevelTests () + { +#if DEBUG_IDISPOSABLE + View.DebugIDisposable = true; +#endif + } + [Fact] public void Constructor_Default () { @@ -90,7 +99,7 @@ public partial class ToplevelTests () // The available height is lower than the Application.Top height minus // the menu bar and status bar, then the top can go beyond the bottom -// Assert.Equal (2, ny); + // Assert.Equal (2, ny); //Assert.NotNull (sb); menuBar = top.MenuBar; @@ -104,7 +113,7 @@ public partial class ToplevelTests () // The available height is lower than the Application.Top height minus // the status bar, then the top can go beyond the bottom -// Assert.Equal (2, ny); + // Assert.Equal (2, ny); //Assert.NotNull (sb); //statusBar = top.StatusBar; @@ -217,162 +226,6 @@ public partial class ToplevelTests () #endif } - [Fact (Skip = "#2491 - Test is broken until #2491 is more mature.")] - [AutoInitShutdown] - public void KeyBindings_Command () - { - var isRunning = false; - - var win1 = new Window { Id = "win1", Width = Dim.Percent (50), Height = Dim.Fill () }; - var lblTf1W1 = new Label { Id = "lblTf1W1", Text = "Enter text in TextField on Win1:" }; - - var tf1W1 = new TextField - { - Id = "tf1W1", X = Pos.Right (lblTf1W1) + 1, Width = Dim.Fill (), Text = "Text1 on Win1" - }; - - var lblTvW1 = new Label - { - Id = "lblTvW1", Y = Pos.Bottom (lblTf1W1) + 1, Text = "Enter text in TextView on Win1:" - }; - - var tvW1 = new TextView - { - Id = "tvW1", - X = Pos.Left (tf1W1), - Width = Dim.Fill (), - Height = 2, - Text = "First line Win1\nSecond line Win1" - }; - - var lblTf2W1 = new Label - { - Id = "lblTf2W1", Y = Pos.Bottom (lblTvW1) + 1, Text = "Enter text in TextField on Win1:" - }; - var tf2W1 = new TextField { Id = "tf2W1", X = Pos.Left (tf1W1), Width = Dim.Fill (), Text = "Text2 on Win1" }; - win1.Add (lblTf1W1, tf1W1, lblTvW1, tvW1, lblTf2W1, tf2W1); - - var win2 = new Window - { - Id = "win2", X = Pos.Right (win1) + 1, Width = Dim.Percent (50), Height = Dim.Fill () - }; - var lblTf1W2 = new Label { Id = "lblTf1W2", Text = "Enter text in TextField on Win2:" }; - - var tf1W2 = new TextField - { - Id = "tf1W2", X = Pos.Right (lblTf1W2) + 1, Width = Dim.Fill (), Text = "Text1 on Win2" - }; - - var lblTvW2 = new Label - { - Id = "lblTvW2", Y = Pos.Bottom (lblTf1W2) + 1, Text = "Enter text in TextView on Win2:" - }; - - var tvW2 = new TextView - { - Id = "tvW2", - X = Pos.Left (tf1W2), - Width = Dim.Fill (), - Height = 2, - Text = "First line Win1\nSecond line Win2" - }; - - var lblTf2W2 = new Label - { - Id = "lblTf2W2", Y = Pos.Bottom (lblTvW2) + 1, Text = "Enter text in TextField on Win2:" - }; - var tf2W2 = new TextField { Id = "tf2W2", X = Pos.Left (tf1W2), Width = Dim.Fill (), Text = "Text2 on Win2" }; - win2.Add (lblTf1W2, tf1W2, lblTvW2, tvW2, lblTf2W2, tf2W2); - - Toplevel top = new (); - top.Add (win1, win2); - top.Loaded += (s, e) => isRunning = true; - top.Closing += (s, e) => isRunning = false; - Application.Begin (top); - top.Running = true; - - Assert.Equal (new (0, 0, 40, 25), win1.Frame); - Assert.Equal (new (41, 0, 40, 25), win2.Frame); - Assert.Equal (win1, top.Focused); - Assert.Equal (tf1W1, top.MostFocused); - - Assert.True (isRunning); - Assert.True (Application.RaiseKeyDownEvent (Application.QuitKey)); - Assert.False (isRunning); - Assert.True (Application.RaiseKeyDownEvent (Key.Z.WithCtrl)); - - Assert.True (Application.RaiseKeyDownEvent (Key.F5)); // refresh - - Assert.True (Application.RaiseKeyDownEvent (Key.Tab)); - Assert.Equal (win1, top.Focused); - Assert.Equal (tvW1, top.MostFocused); - Assert.True (Application.RaiseKeyDownEvent (Key.Tab)); - Assert.Equal ($"\tFirst line Win1{Environment.NewLine}Second line Win1", tvW1.Text); - Assert.True (Application.RaiseKeyDownEvent (Key.Tab.WithShift)); - Assert.Equal ($"First line Win1{Environment.NewLine}Second line Win1", tvW1.Text); - - var prevMostFocusedSubview = top.MostFocused; - - Assert.True (Application.RaiseKeyDownEvent (Key.F6)); // move to next TabGroup (win2) - Assert.Equal (win2, top.Focused); - - Assert.True (Application.RaiseKeyDownEvent (Key.F6.WithShift)); // move to prev TabGroup (win1) - Assert.Equal (win1, top.Focused); - Assert.Equal (tf2W1, top.MostFocused); // BUGBUG: Should be prevMostFocusedSubview - We need to cache the last focused view in the TabGroup somehow - - prevMostFocusedSubview.SetFocus (); - - Assert.Equal (tvW1, top.MostFocused); - - tf2W1.SetFocus (); - Assert.True (Application.RaiseKeyDownEvent (Key.Tab)); // tf2W1 is last subview in win1 - tabbing should take us to first subview of win1 - Assert.Equal (win1, top.Focused); - Assert.Equal (tf1W1, top.MostFocused); - Assert.True (Application.RaiseKeyDownEvent (Key.CursorRight)); // move char to right in tf1W1. We're at last char so nav to next view - Assert.Equal (win1, top.Focused); - Assert.Equal (tvW1, top.MostFocused); - Assert.True (Application.RaiseKeyDownEvent (Key.CursorDown)); // move down to next view (tvW1) - Assert.Equal (win1, top.Focused); - Assert.Equal (tvW1, top.MostFocused); -#if UNIX_KEY_BINDINGS - Assert.True (Application.OnKeyDown (new (Key.I.WithCtrl))); - Assert.Equal (win1, top.GetFocused ()); - Assert.Equal (tf2W1, top.MostFocused); -#endif - Assert.True (Application.RaiseKeyDownEvent (Key.Tab.WithShift)); // Ignored. TextView eats shift-tab by default - Assert.Equal (win1, top.Focused); - Assert.Equal (tvW1, top.MostFocused); - tvW1.AllowsTab = false; - Assert.True (Application.RaiseKeyDownEvent (Key.Tab.WithShift)); - Assert.Equal (win1, top.Focused); - Assert.Equal (tf1W1, top.MostFocused); - Assert.True (Application.RaiseKeyDownEvent (Key.CursorLeft)); - Assert.Equal (win1, top.Focused); - Assert.Equal (tf2W1, top.MostFocused); - Assert.True (Application.RaiseKeyDownEvent (Key.CursorUp)); - Assert.Equal (win1, top.Focused); - Assert.Equal (tvW1, top.MostFocused); - - // nav to win2 - Assert.True (Application.RaiseKeyDownEvent (Key.F6)); - Assert.Equal (win2, top.Focused); - Assert.Equal (tf1W2, top.MostFocused); - Assert.True (Application.RaiseKeyDownEvent (Key.F6.WithShift)); - Assert.Equal (win1, top.Focused); - Assert.Equal (tf2W1, top.MostFocused); - Assert.True (Application.RaiseKeyDownEvent (Application.NextTabGroupKey)); - Assert.Equal (win2, top.Focused); - Assert.Equal (tf1W2, top.MostFocused); - Assert.True (Application.RaiseKeyDownEvent (Application.PrevTabGroupKey)); - Assert.Equal (win1, top.Focused); - Assert.Equal (tf2W1, top.MostFocused); - Assert.True (Application.RaiseKeyDownEvent (Key.CursorUp)); - Assert.Equal (win1, top.Focused); - Assert.Equal (tvW1, top.MostFocused); - - top.Dispose (); - } - [Fact] public void Added_Event_Should_Not_Be_Used_To_Initialize_Toplevel_Events () { @@ -793,7 +646,7 @@ public partial class ToplevelTests () Application.LayoutAndDraw (); Assert.Equal (new (0, 0, 19, 2), top.Frame); Assert.Equal (new (19, 2, 20, 3), window.Frame); - //TestHelpers.AssertDriverContentsWithFrameAre (@"", output); + //DriverAsserts.AssertDriverContentsWithFrameAre (@"", output); Application.End (rsWindow); Application.End (rsTop); diff --git a/UnitTests/Views/TreeTableSourceTests.cs b/Tests/UnitTests/Views/TreeTableSourceTests.cs similarity index 93% rename from UnitTests/Views/TreeTableSourceTests.cs rename to Tests/UnitTests/Views/TreeTableSourceTests.cs index d23569028..856a6809c 100644 --- a/UnitTests/Views/TreeTableSourceTests.cs +++ b/Tests/UnitTests/Views/TreeTableSourceTests.cs @@ -1,4 +1,6 @@ using System.Text; +using UnitTests; +using UnitTests; using Xunit.Abstractions; namespace Terminal.Gui.ViewsTests; @@ -43,7 +45,7 @@ public class TreeTableSourceTests : IDisposable │├+Lost Highway│Exciting night road │ │└+Route 66 │Great race course │"; - TestHelpers.AssertDriverContentsAre (expected, _output); + DriverAssert.AssertDriverContentsAre (expected, _output); Assert.Equal (2, tv.Table.Rows); @@ -67,7 +69,7 @@ public class TreeTableSourceTests : IDisposable │└+Route 66 │Great race course │ "; - TestHelpers.AssertDriverContentsAre (expected, _output); + DriverAssert.AssertDriverContentsAre (expected, _output); // when pressing left we should collapse the top route again tv.NewKeyDownEvent (Key.CursorLeft); @@ -83,7 +85,7 @@ public class TreeTableSourceTests : IDisposable │└+Route 66 │Great race course │ "; - TestHelpers.AssertDriverContentsAre (expected, _output); + DriverAssert.AssertDriverContentsAre (expected, _output); } [Fact] @@ -106,7 +108,7 @@ public class TreeTableSourceTests : IDisposable │├+Lost Highway│Exciting night road │ │└+Route 66 │Great race course │"; - TestHelpers.AssertDriverContentsAre (expected, _output); + DriverAssert.AssertDriverContentsAre (expected, _output); Assert.Equal (2, tv.Table.Rows); @@ -129,15 +131,15 @@ public class TreeTableSourceTests : IDisposable │└+Route 66 │Great race course │ "; - TestHelpers.AssertDriverContentsAre (expected, _output); + DriverAssert.AssertDriverContentsAre (expected, _output); // Clicking to the right/left of the expand/collapse does nothing tv.NewMouseEvent (new MouseEventArgs { Position = new (3, 2), Flags = MouseFlags.Button1Clicked }); tv.Draw (); - TestHelpers.AssertDriverContentsAre (expected, _output); + DriverAssert.AssertDriverContentsAre (expected, _output); tv.NewMouseEvent (new MouseEventArgs { Position = new (1, 2), Flags = MouseFlags.Button1Clicked }); tv.Draw (); - TestHelpers.AssertDriverContentsAre (expected, _output); + DriverAssert.AssertDriverContentsAre (expected, _output); // Clicking on the + again should collapse tv.NewMouseEvent (new MouseEventArgs { Position = new (2, 2), Flags = MouseFlags.Button1Clicked }); @@ -151,7 +153,7 @@ public class TreeTableSourceTests : IDisposable │├+Lost Highway│Exciting night road │ │└+Route 66 │Great race course │"; - TestHelpers.AssertDriverContentsAre (expected, _output); + DriverAssert.AssertDriverContentsAre (expected, _output); } [Fact] @@ -177,7 +179,7 @@ public class TreeTableSourceTests : IDisposable │☐│└+Route 66 │Great race course │ "; - TestHelpers.AssertDriverContentsAre (expected, _output); + DriverAssert.AssertDriverContentsAre (expected, _output); Assert.Equal (2, tv.Table.Rows); @@ -208,7 +210,7 @@ public class TreeTableSourceTests : IDisposable │☐│└+Route 66 │Great race course │ "; - TestHelpers.AssertDriverContentsAre (expected, _output); + DriverAssert.AssertDriverContentsAre (expected, _output); tv.NewKeyDownEvent (Key.CursorDown); tv.NewKeyDownEvent (Key.Space); @@ -226,7 +228,7 @@ public class TreeTableSourceTests : IDisposable │☐│└+Route 66 │Great race course │ "; - TestHelpers.AssertDriverContentsAre (expected, _output); + DriverAssert.AssertDriverContentsAre (expected, _output); IDescribedThing [] selectedObjects = checkSource.CheckedRows.Select (treeSource.GetObjectOnRow).ToArray (); IDescribedThing selected = Assert.Single (selectedObjects); diff --git a/UnitTests/Views/TreeViewTests.cs b/Tests/UnitTests/Views/TreeViewTests.cs similarity index 97% rename from UnitTests/Views/TreeViewTests.cs rename to Tests/UnitTests/Views/TreeViewTests.cs index 21ba9a5f3..602a205bd 100644 --- a/UnitTests/Views/TreeViewTests.cs +++ b/Tests/UnitTests/Views/TreeViewTests.cs @@ -1,5 +1,7 @@ using System.ComponentModel; using System.Text; +using UnitTests; +using UnitTests; using Xunit.Abstractions; namespace Terminal.Gui.ViewsTests; @@ -714,7 +716,7 @@ public class TreeViewTests tv.Draw (); // Nothing expanded - TestHelpers.AssertDriverContentsAre ( + DriverAssert.AssertDriverContentsAre ( @"└+1 ", _output @@ -725,7 +727,7 @@ public class TreeViewTests tv.Draw (); // Normal drawing of the tree view - TestHelpers.AssertDriverContentsAre ( + DriverAssert.AssertDriverContentsAre ( @" └-1 └-2 @@ -753,7 +755,7 @@ public class TreeViewTests tv.Draw (); // Nothing expanded - TestHelpers.AssertDriverContentsAre ( + DriverAssert.AssertDriverContentsAre ( @"└+1 ", _output @@ -765,7 +767,7 @@ public class TreeViewTests tv.Draw (); // Normal drawing of the tree view - TestHelpers.AssertDriverContentsAre ( + DriverAssert.AssertDriverContentsAre ( @" └-1 └-2 @@ -793,7 +795,7 @@ public class TreeViewTests tv.Draw (); // Normal drawing of the tree view - TestHelpers.AssertDriverContentsAre ( + DriverAssert.AssertDriverContentsAre ( @" └-1 └-2 @@ -827,7 +829,7 @@ public class TreeViewTests tv.LayoutSubviews (); tv.Draw (); - TestHelpers.AssertDriverContentsAre ( + DriverAssert.AssertDriverContentsAre ( @"├-normal │ ├─pink │ └─normal @@ -847,7 +849,7 @@ public class TreeViewTests tv.Draw (); - TestHelpers.AssertDriverContentsAre ( + DriverAssert.AssertDriverContentsAre ( @"├+normal └─pink ", @@ -883,7 +885,7 @@ public class TreeViewTests View.SetClipToScreen (); tv.Draw (); - TestHelpers.AssertDriverContentsAre ( + DriverAssert.AssertDriverContentsAre ( @"├-normal │ ├─pink │ └─normal @@ -903,7 +905,7 @@ public class TreeViewTests View.SetClipToScreen (); tv.Draw (); - TestHelpers.AssertDriverContentsAre ( + DriverAssert.AssertDriverContentsAre ( @"├+normal └─pink ", @@ -921,7 +923,7 @@ public class TreeViewTests View.SetClipToScreen (); tv.Draw (); - TestHelpers.AssertDriverContentsAre ( + DriverAssert.AssertDriverContentsAre ( @"└─pink ", _output @@ -959,7 +961,7 @@ public class TreeViewTests tv.Draw (); // Normal drawing of the tree view - TestHelpers.AssertDriverContentsAre ( + DriverAssert.AssertDriverContentsAre ( @" ├-root one │ ├─leaf 1 @@ -1034,7 +1036,7 @@ public class TreeViewTests tv.Draw (); // Normal drawing of the tree view - TestHelpers.AssertDriverContentsAre ( + DriverAssert.AssertDriverContentsAre ( @" ├-root one FFFFFFFFFF @@ -1074,7 +1076,7 @@ FFFFFFFFFF tv.Draw (); // Normal drawing of the tree view - TestHelpers.AssertDriverContentsAre ( + DriverAssert.AssertDriverContentsAre ( @" ─leaf 1 ─leaf 2 @@ -1130,7 +1132,7 @@ oot two tv.Draw (); // Normal drawing of the tree view - TestHelpers.AssertDriverContentsAre ( + DriverAssert.AssertDriverContentsAre ( @" ├-root one │ ├─leaf 1 @@ -1148,7 +1150,7 @@ oot two tv.Draw (); // Normal drawing of the tree view - TestHelpers.AssertDriverContentsAre ( + DriverAssert.AssertDriverContentsAre ( @"", _output ); @@ -1158,7 +1160,7 @@ oot two View.SetClipToScreen (); tv.Draw (); - TestHelpers.AssertDriverContentsAre ( + DriverAssert.AssertDriverContentsAre ( @" ├-root one │ ├─leaf 1 @@ -1173,7 +1175,7 @@ oot two View.SetClipToScreen (); tv.Draw (); - TestHelpers.AssertDriverContentsAre ( + DriverAssert.AssertDriverContentsAre ( @" ├-root one │ ├─leaf 1 @@ -1187,7 +1189,7 @@ oot two View.SetClipToScreen (); tv.Draw (); - TestHelpers.AssertDriverContentsAre ( + DriverAssert.AssertDriverContentsAre ( @" ├-root one │ ├─leaf 1 @@ -1223,7 +1225,7 @@ oot two var hotpink = new Attribute (Color.BrightMagenta, Color.Black); // Normal drawing of the tree view - TestHelpers.AssertDriverContentsAre ( + DriverAssert.AssertDriverContentsAre ( @" ├-normal │ ├─pink @@ -1234,7 +1236,7 @@ oot two ); // Should all be the same color - TestHelpers.AssertDriverAttributesAre ( + DriverAssert.AssertDriverAttributesAre ( @" 0000000000 0000000000 @@ -1260,7 +1262,7 @@ oot two tv.Draw (); // Same text - TestHelpers.AssertDriverContentsAre ( + DriverAssert.AssertDriverContentsAre ( @" ├-normal │ ├─pink @@ -1272,7 +1274,7 @@ oot two // but now the item (only not lines) appear // in pink when they are the word "pink" - TestHelpers.AssertDriverAttributesAre ( + DriverAssert.AssertDriverAttributesAre ( @" 00000000 00001111 diff --git a/UnitTests/Views/ViewDisposalTest.cs b/Tests/UnitTests/Views/ViewDisposalTest.cs similarity index 99% rename from UnitTests/Views/ViewDisposalTest.cs rename to Tests/UnitTests/Views/ViewDisposalTest.cs index f171ff708..d7c0397e6 100644 --- a/UnitTests/Views/ViewDisposalTest.cs +++ b/Tests/UnitTests/Views/ViewDisposalTest.cs @@ -1,4 +1,5 @@ using System.Reflection; +using UnitTests; using Xunit.Abstractions; namespace Terminal.Gui.ViewsTests; diff --git a/UnitTests/Views/WindowTests.cs b/Tests/UnitTests/Views/WindowTests.cs similarity index 97% rename from UnitTests/Views/WindowTests.cs rename to Tests/UnitTests/Views/WindowTests.cs index 1bcce1a97..73a53064f 100644 --- a/UnitTests/Views/WindowTests.cs +++ b/Tests/UnitTests/Views/WindowTests.cs @@ -1,3 +1,5 @@ +using UnitTests; +using UnitTests; using Xunit.Abstractions; namespace Terminal.Gui.ViewsTests; @@ -55,7 +57,7 @@ public class WindowTests Application.Begin (top); ((FakeDriver)Application.Driver!).SetBufferSize (20, 10); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌──────────────────┐ │ File Edit │ @@ -72,7 +74,7 @@ public class WindowTests ((FakeDriver)Application.Driver!).SetBufferSize (40, 20); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌──────────────────────────────────────┐ │ File Edit │ @@ -99,7 +101,7 @@ public class WindowTests ((FakeDriver)Application.Driver!).SetBufferSize (20, 10); - TestHelpers.AssertDriverContentsWithFrameAre ( + DriverAssert.AssertDriverContentsWithFrameAre ( @" ┌──────────────────┐ │ File Edit │ diff --git a/UnitTests/coverlet.runsettings b/Tests/UnitTests/coverlet.runsettings similarity index 100% rename from UnitTests/coverlet.runsettings rename to Tests/UnitTests/coverlet.runsettings diff --git a/Tests/UnitTests/xunit.runner.json b/Tests/UnitTests/xunit.runner.json new file mode 100644 index 000000000..c096d4186 --- /dev/null +++ b/Tests/UnitTests/xunit.runner.json @@ -0,0 +1,6 @@ +{ + "$schema": "https://xunit.net/schema/current/xunit.runner.schema.json", + "parallelizeTestCollections": false, + "parallelizeAssembly": false, + "stopOnFail": false +} \ No newline at end of file diff --git a/Tests/UnitTestsParallelizable/AssemblyInfo.cs b/Tests/UnitTestsParallelizable/AssemblyInfo.cs new file mode 100644 index 000000000..97d54f7cf --- /dev/null +++ b/Tests/UnitTestsParallelizable/AssemblyInfo.cs @@ -0,0 +1 @@ +global using CM = Terminal.Gui.ConfigurationManager; diff --git a/UnitTests/Drawing/AlignerTests.cs b/Tests/UnitTestsParallelizable/Drawing/AlignerTests.cs similarity index 100% rename from UnitTests/Drawing/AlignerTests.cs rename to Tests/UnitTestsParallelizable/Drawing/AlignerTests.cs diff --git a/UnitTests/Drawing/AttributeTests.cs b/Tests/UnitTestsParallelizable/Drawing/AttributeTests.cs similarity index 100% rename from UnitTests/Drawing/AttributeTests.cs rename to Tests/UnitTestsParallelizable/Drawing/AttributeTests.cs diff --git a/UnitTests/Drawing/CellTests.cs b/Tests/UnitTestsParallelizable/Drawing/CellTests.cs similarity index 95% rename from UnitTests/Drawing/CellTests.cs rename to Tests/UnitTestsParallelizable/Drawing/CellTests.cs index a7fc88073..4cef97335 100644 --- a/UnitTests/Drawing/CellTests.cs +++ b/Tests/UnitTestsParallelizable/Drawing/CellTests.cs @@ -3,7 +3,7 @@ using Xunit.Abstractions; namespace Terminal.Gui.DrawingTests; -public class CellTests (ITestOutputHelper output) +public class CellTests () { [Fact] public void Constructor_Defaults () diff --git a/UnitTests/Drawing/ColorSchemeTests.cs b/Tests/UnitTestsParallelizable/Drawing/ColorSchemeTests.cs similarity index 100% rename from UnitTests/Drawing/ColorSchemeTests.cs rename to Tests/UnitTestsParallelizable/Drawing/ColorSchemeTests.cs diff --git a/UnitTests/Drawing/ColorTests.Constructors.cs b/Tests/UnitTestsParallelizable/Drawing/ColorTests.Constructors.cs similarity index 90% rename from UnitTests/Drawing/ColorTests.Constructors.cs rename to Tests/UnitTestsParallelizable/Drawing/ColorTests.Constructors.cs index 98efa98df..7206467eb 100644 --- a/UnitTests/Drawing/ColorTests.Constructors.cs +++ b/Tests/UnitTestsParallelizable/Drawing/ColorTests.Constructors.cs @@ -66,28 +66,6 @@ public partial class ColorTests ); } - [Theory (Skip = "Relies on old ColorName mapping")] - [MemberData ( - nameof (ColorTestsTheoryDataGenerators.Constructor_WithColorName_AllChannelsCorrect), - MemberType = typeof (ColorTestsTheoryDataGenerators) - )] - public void Constructor_WithColorName_AllChannelsCorrect ( - ColorName16 cname, - ValueTuple expectedColorValues - ) - { - var color = new Color (cname); - - (byte r, byte g, byte b) = expectedColorValues; - - Assert.Multiple ( - () => Assert.Equal (r, color.R), - () => Assert.Equal (g, color.G), - () => Assert.Equal (b, color.B), - () => Assert.Equal (byte.MaxValue, color.A) - ); - } - [Theory] [CombinatorialData] public void Constructor_WithInt32_AllValuesCorrect ( diff --git a/UnitTests/Drawing/ColorTests.Operators.cs b/Tests/UnitTestsParallelizable/Drawing/ColorTests.Operators.cs similarity index 93% rename from UnitTests/Drawing/ColorTests.Operators.cs rename to Tests/UnitTestsParallelizable/Drawing/ColorTests.Operators.cs index e3f25a1ba..092f6707c 100644 --- a/UnitTests/Drawing/ColorTests.Operators.cs +++ b/Tests/UnitTestsParallelizable/Drawing/ColorTests.Operators.cs @@ -57,20 +57,7 @@ public partial class ColorTests Assert.Equal (rgba.GetHashCode (), color.GetHashCode ()); } - - [Theory (Skip = "Relies on old ColorName mapping")] - [Trait ("Category", "Operators")] - [MemberData ( - nameof (ColorTestsTheoryDataGenerators.ExplicitOperator_FromColorName_RoundTripsCorrectly), - MemberType = typeof (ColorTestsTheoryDataGenerators) - )] - public void ImplicitOperator_FromColorName_ReturnsCorrectColorValue (ColorName16 cname, Color expectedColor) - { - Color color = cname; - - Assert.Equal (expectedColor, color); - } - + [Theory] [CombinatorialData] [Trait ("Category", "Operators")] diff --git a/UnitTests/Drawing/ColorTests.ParsingAndFormatting.cs b/Tests/UnitTestsParallelizable/Drawing/ColorTests.ParsingAndFormatting.cs similarity index 88% rename from UnitTests/Drawing/ColorTests.ParsingAndFormatting.cs rename to Tests/UnitTestsParallelizable/Drawing/ColorTests.ParsingAndFormatting.cs index 82b6cc503..8b8ebed62 100644 --- a/UnitTests/Drawing/ColorTests.ParsingAndFormatting.cs +++ b/Tests/UnitTestsParallelizable/Drawing/ColorTests.ParsingAndFormatting.cs @@ -59,24 +59,6 @@ public partial class ColorTests Assert.Equal (constructedColor.Argb, parsedColor.Argb); } - [Theory (Skip = "Doesn't utilize W3ColorNames")] - [CombinatorialData] - public void ToString_WithInvariantCultureAndNullString_IsSameAsParameterless ( - [CombinatorialValues (0, 64, 128, 255)] byte r, - [CombinatorialValues (0, 64, 128, 255)] byte g, - [CombinatorialValues (0, 64, 128, 255)] byte b - ) - { - var expected = $"#{r:X2}{g:X2}{b:X2}"; - Color testColor = new (r, g, b); - - var testStringWithExplicitInvariantCulture = testColor.ToString (null, CultureInfo.InvariantCulture); - Assert.Equal (expected, testStringWithExplicitInvariantCulture); - - var parameterlessToStringValue = testColor.ToString (); - Assert.Equal (parameterlessToStringValue, testStringWithExplicitInvariantCulture); - } - [Theory] [MemberData ( nameof (ColorTestsTheoryDataGenerators.TryParse_string_Returns_False_For_Invalid_Inputs), @@ -146,7 +128,6 @@ public static partial class ColorTestsTheoryDataGenerators int expectedRgba = BinaryPrimitives.ReadInt32LittleEndian ([(byte)(i + 16), i, (byte)(i - 16), i]); values.Add ($"rgb({i - 16:D},{i:D},{i + 16:D})", expectedRgb); values.Add ($"rgb({i - 16:D},{i:D},{i + 16:D},{i:D})", expectedRgba); - values.Add ($"rgb({i - 16:D},{i:D},{i + 16:D})", expectedRgb); values.Add ($"rgba({i - 16:D},{i:D},{i + 16:D},{i:D})", expectedRgba); values.Add ($"#{i - 16:X2}{i:X2}{i + 16:X2}", expectedRgb); values.Add ($"#{i:X2}{i - 16:X2}{i:X2}{i + 16:X2}", expectedRgba); @@ -182,5 +163,6 @@ public static partial class ColorTestsTheoryDataGenerators } return values; + } } diff --git a/UnitTests/Drawing/ColorTests.TypeChecks.cs b/Tests/UnitTestsParallelizable/Drawing/ColorTests.TypeChecks.cs similarity index 100% rename from UnitTests/Drawing/ColorTests.TypeChecks.cs rename to Tests/UnitTestsParallelizable/Drawing/ColorTests.TypeChecks.cs diff --git a/UnitTests/Drawing/ColorTests.cs b/Tests/UnitTestsParallelizable/Drawing/ColorTests.cs similarity index 57% rename from UnitTests/Drawing/ColorTests.cs rename to Tests/UnitTestsParallelizable/Drawing/ColorTests.cs index 7fcf7ab93..28c37b11c 100644 --- a/UnitTests/Drawing/ColorTests.cs +++ b/Tests/UnitTestsParallelizable/Drawing/ColorTests.cs @@ -21,20 +21,6 @@ public partial class ColorTests Assert.Equal (expectedArgb, color.Argb); } - [Fact (Skip = "Relies on old ColorName mapping")] - public void Color_ColorName_Get_ReturnsClosestColorName () - { - // Arrange - var color = new Color (128, 64, 40); // Custom RGB color, closest to Yellow - var expectedColorName = ColorName16.Yellow; - - // Act - ColorName16 colorName = color.GetClosestNamedColor16 (); - - // Assert - Assert.Equal (expectedColorName, colorName); - } - [Fact] public void Color_IsClosestToNamedColor_ReturnsExpectedValue () { @@ -47,18 +33,6 @@ public partial class ColorTests Assert.True (color2.IsClosestToNamedColor16 (ColorName16.Red)); } - [Theory (Skip = "Test data is now bogus")] - [MemberData ( - nameof (ColorTestsTheoryDataGenerators.FindClosestColor_ReturnsClosestColor), - MemberType = typeof (ColorTestsTheoryDataGenerators) - )] - public void FindClosestColor_ReturnsClosestColor (Color inputColor, ColorName16 expectedColorName) - { - ColorName16 actualColorName = Color.GetClosestNamedColor16 (inputColor); - - Assert.Equal (expectedColorName, actualColorName); - } - [Theory] [CombinatorialData] public void Rgba_Returns_Expected_Value ( @@ -82,13 +56,13 @@ public static partial class ColorTestsTheoryDataGenerators public static TheoryData FindClosestColor_ReturnsClosestColor () { TheoryData data = []; - data.Add (new Color (0, 0), ColorName16.Black); - data.Add (new Color (255, 255, 255), ColorName16.White); - data.Add (new Color (5, 100, 255), ColorName16.BrightBlue); - data.Add (new Color (0, 255), ColorName16.BrightGreen); - data.Add (new Color (255, 70, 8), ColorName16.BrightRed); - data.Add (new Color (0, 128, 128), ColorName16.Cyan); - data.Add (new Color (128, 64, 32), ColorName16.Yellow); + data.Add (new (0, 0), ColorName16.Black); + data.Add (new (255, 255, 255), ColorName16.White); + data.Add (new (5, 100, 255), ColorName16.BrightBlue); + data.Add (new (0, 255), ColorName16.BrightGreen); + data.Add (new (255, 70, 8), ColorName16.BrightRed); + data.Add (new (0, 128, 128), ColorName16.Cyan); + data.Add (new (128, 64, 32), ColorName16.Yellow); return data; } diff --git a/UnitTests/Drawing/FillPairTests.cs b/Tests/UnitTestsParallelizable/Drawing/FillPairTests.cs similarity index 100% rename from UnitTests/Drawing/FillPairTests.cs rename to Tests/UnitTestsParallelizable/Drawing/FillPairTests.cs diff --git a/UnitTests/Drawing/GradientFillTests.cs b/Tests/UnitTestsParallelizable/Drawing/GradientFillTests.cs similarity index 100% rename from UnitTests/Drawing/GradientFillTests.cs rename to Tests/UnitTestsParallelizable/Drawing/GradientFillTests.cs diff --git a/UnitTests/Drawing/GradientTests.cs b/Tests/UnitTestsParallelizable/Drawing/GradientTests.cs similarity index 100% rename from UnitTests/Drawing/GradientTests.cs rename to Tests/UnitTestsParallelizable/Drawing/GradientTests.cs diff --git a/UnitTests/Drawing/PopularityPaletteWithThresholdTests.cs b/Tests/UnitTestsParallelizable/Drawing/PopularityPaletteWithThresholdTests.cs similarity index 100% rename from UnitTests/Drawing/PopularityPaletteWithThresholdTests.cs rename to Tests/UnitTestsParallelizable/Drawing/PopularityPaletteWithThresholdTests.cs diff --git a/UnitTests/Drawing/Region/DifferenceTests.cs b/Tests/UnitTestsParallelizable/Drawing/Region/DifferenceTests.cs similarity index 100% rename from UnitTests/Drawing/Region/DifferenceTests.cs rename to Tests/UnitTestsParallelizable/Drawing/Region/DifferenceTests.cs diff --git a/UnitTests/Drawing/Region/MergeRectanglesTests.cs b/Tests/UnitTestsParallelizable/Drawing/Region/MergeRectanglesTests.cs similarity index 100% rename from UnitTests/Drawing/Region/MergeRectanglesTests.cs rename to Tests/UnitTestsParallelizable/Drawing/Region/MergeRectanglesTests.cs diff --git a/UnitTests/Drawing/Region/RegionTests.cs b/Tests/UnitTestsParallelizable/Drawing/Region/RegionTests.cs similarity index 100% rename from UnitTests/Drawing/Region/RegionTests.cs rename to Tests/UnitTestsParallelizable/Drawing/Region/RegionTests.cs diff --git a/UnitTests/Drawing/Region/SubtractRectangleTests.cs b/Tests/UnitTestsParallelizable/Drawing/Region/SubtractRectangleTests.cs similarity index 100% rename from UnitTests/Drawing/Region/SubtractRectangleTests.cs rename to Tests/UnitTestsParallelizable/Drawing/Region/SubtractRectangleTests.cs diff --git a/UnitTests/Drawing/SixelEncoderTests.cs b/Tests/UnitTestsParallelizable/Drawing/SixelEncoderTests.cs similarity index 100% rename from UnitTests/Drawing/SixelEncoderTests.cs rename to Tests/UnitTestsParallelizable/Drawing/SixelEncoderTests.cs diff --git a/UnitTests/Drawing/SolidFillTests.cs b/Tests/UnitTestsParallelizable/Drawing/SolidFillTests.cs similarity index 100% rename from UnitTests/Drawing/SolidFillTests.cs rename to Tests/UnitTestsParallelizable/Drawing/SolidFillTests.cs diff --git a/UnitTests/Drawing/StraightLineTests.cs b/Tests/UnitTestsParallelizable/Drawing/StraightLineTests.cs similarity index 99% rename from UnitTests/Drawing/StraightLineTests.cs rename to Tests/UnitTestsParallelizable/Drawing/StraightLineTests.cs index 39c67d81e..cb284f9f7 100644 --- a/UnitTests/Drawing/StraightLineTests.cs +++ b/Tests/UnitTestsParallelizable/Drawing/StraightLineTests.cs @@ -307,7 +307,6 @@ public class StraightLineTests (ITestOutputHelper output) 3 )] [Theory] - [SetupFakeDriver] public void Viewport ( Orientation orientation, int x, diff --git a/UnitTests/Drawing/ThicknessTests.cs b/Tests/UnitTestsParallelizable/Drawing/ThicknessTests.cs similarity index 58% rename from UnitTests/Drawing/ThicknessTests.cs rename to Tests/UnitTestsParallelizable/Drawing/ThicknessTests.cs index c1a5cbae5..ca584d4af 100644 --- a/UnitTests/Drawing/ThicknessTests.cs +++ b/Tests/UnitTestsParallelizable/Drawing/ThicknessTests.cs @@ -1,9 +1,6 @@ -using System.Text; -using Xunit.Abstractions; +namespace Terminal.Gui.DrawingTests; -namespace Terminal.Gui.DrawingTests; - -public class ThicknessTests (ITestOutputHelper output) +public class ThicknessTests { [Fact] public void Constructor_Defaults () @@ -24,13 +21,13 @@ public class ThicknessTests (ITestOutputHelper output) Assert.Equal (3, t.Right); Assert.Equal (4, t.Bottom); - t = new Thickness (0, 0, 0, 0); + t = new (0, 0, 0, 0); Assert.Equal (0, t.Left); Assert.Equal (0, t.Top); Assert.Equal (0, t.Right); Assert.Equal (0, t.Bottom); - t = new Thickness (-1, 0, 0, 0); + t = new (-1, 0, 0, 0); Assert.Equal (-1, t.Left); Assert.Equal (0, t.Top); Assert.Equal (0, t.Right); @@ -47,252 +44,6 @@ public class ThicknessTests (ITestOutputHelper output) Assert.Equal (1, t.Bottom); } - [Fact] - [AutoInitShutdown] - public void DrawTests () - { - ((FakeDriver)Application.Driver!).SetBufferSize (60, 60); - var t = new Thickness (0, 0, 0, 0); - var r = new Rectangle (5, 5, 40, 15); - - Application.Driver?.FillRect ( - new Rectangle (0, 0, Application.Driver!.Cols, Application.Driver!.Rows), - (Rune)' ' - ); - t.Draw (r, ViewDiagnosticFlags.Thickness, "Test"); - - TestHelpers.AssertDriverContentsWithFrameAre ( - @" - Test (Left=0,Top=0,Right=0,Bottom=0)", - output - ); - - t = new Thickness (1, 1, 1, 1); - r = new Rectangle (5, 5, 40, 15); - - Application.Driver?.FillRect ( - new Rectangle (0, 0, Application.Driver!.Cols, Application.Driver!.Rows), - (Rune)' ' - ); - t.Draw (r, ViewDiagnosticFlags.Thickness, "Test"); - - TestHelpers.AssertDriverContentsWithFrameAre ( - @" - TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT - T T - T T - T T - T T - T T - T T - T T - T T - T T - T T - T T - T T - T T - TTTest (Left=1,Top=1,Right=1,Bottom=1)TT", - output - ); - - t = new Thickness (1, 2, 3, 4); - r = new Rectangle (5, 5, 40, 15); - - Application.Driver?.FillRect ( - new Rectangle (0, 0, Application.Driver!.Cols, Application.Driver!.Rows), - (Rune)' ' - ); - t.Draw (r, ViewDiagnosticFlags.Thickness, "Test"); - - TestHelpers.AssertDriverContentsWithFrameAre ( - @" - TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT - TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT - T TTT - T TTT - T TTT - T TTT - T TTT - T TTT - T TTT - T TTT - T TTT - TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT - TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT - TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT - TTTest (Left=1,Top=2,Right=3,Bottom=4)TT", - output - ); - - t = new Thickness (-1, 1, 1, 1); - r = new Rectangle (5, 5, 40, 15); - - Application.Driver?.FillRect ( - new Rectangle (0, 0, Application.Driver!.Cols, Application.Driver!.Rows), - (Rune)' ' - ); - t.Draw (r, ViewDiagnosticFlags.Thickness, "Test"); - - TestHelpers.AssertDriverContentsWithFrameAre ( - @" - TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT - T - T - T - T - T - T - T - T - T - T - T - T - T - TTest (Left=-1,Top=1,Right=1,Bottom=1)TT", - output - ); - } - - [Fact] - [AutoInitShutdown] - public void DrawTests_Ruler () - { - // Add a frame so we can see the ruler - var f = new FrameView { X = 0, Y = 0, Width = Dim.Fill (), Height = Dim.Fill () }; - - var top = new Toplevel (); - top.Add (f); - RunState rs = Application.Begin (top); - - ((FakeDriver)Application.Driver!).SetBufferSize (45, 20); - var t = new Thickness (0, 0, 0, 0); - var r = new Rectangle (2, 2, 40, 15); - Application.RunIteration (ref rs); - - t.Draw (r, ViewDiagnosticFlags.Ruler, "Test"); - - TestHelpers.AssertDriverContentsAre ( - @" -┌───────────────────────────────────────────┐ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -└───────────────────────────────────────────┘", - output - ); - - t = new Thickness (1, 1, 1, 1); - r = new Rectangle (1, 1, 40, 15); - top.SetNeedsDraw (); - Application.RunIteration (ref rs); - t.Draw (r, ViewDiagnosticFlags.Ruler, "Test"); - - TestHelpers.AssertDriverContentsAre ( - @" -┌───────────────────────────────────────────┐ -│|123456789|123456789|123456789|123456789 │ -│1 1 │ -│2 2 │ -│3 3 │ -│4 4 │ -│5 5 │ -│6 6 │ -│7 7 │ -│8 8 │ -│9 9 │ -│- - │ -│1 1 │ -│2 2 │ -│3 3 │ -│|123456789|123456789|123456789|123456789 │ -│ │ -│ │ -│ │ -└───────────────────────────────────────────┘", - output - ); - - t = new Thickness (1, 2, 3, 4); - r = new Rectangle (2, 2, 40, 15); - top.SetNeedsDraw (); - Application.RunIteration (ref rs); - t.Draw (r, ViewDiagnosticFlags.Ruler, "Test"); - - TestHelpers.AssertDriverContentsWithFrameAre ( - @" -┌───────────────────────────────────────────┐ -│ │ -│ |123456789|123456789|123456789|123456789 │ -│ 1 1 │ -│ 2 2 │ -│ 3 3 │ -│ 4 4 │ -│ 5 5 │ -│ 6 6 │ -│ 7 7 │ -│ 8 8 │ -│ 9 9 │ -│ - - │ -│ 1 1 │ -│ 2 2 │ -│ 3 3 │ -│ |123456789|123456789|123456789|123456789 │ -│ │ -│ │ -└───────────────────────────────────────────┘", - output - ); - - t = new Thickness (-1, 1, 1, 1); - r = new Rectangle (5, 5, 40, 15); - top.SetNeedsDraw (); - Application.RunIteration (ref rs); - t.Draw (r, ViewDiagnosticFlags.Ruler, "Test"); - - TestHelpers.AssertDriverContentsWithFrameAre ( - @" -┌───────────────────────────────────────────┐ -│ │ -│ │ -│ │ -│ │ -│ |123456789|123456789|123456789|123456789 -│ 1 -│ 2 -│ 3 -│ 4 -│ 5 -│ 6 -│ 7 -│ 8 -│ 9 -│ - -│ 1 -│ 2 -│ 3 -└────|123456789|123456789|123456789|123456789", - output - ); - top.Dispose (); - } - [Fact] public void Empty_Is_empty () { @@ -350,24 +101,24 @@ public class ThicknessTests (ITestOutputHelper output) Assert.Equal (5, inside.Width); Assert.Equal (1, inside.Height); - t = new Thickness (-1, 1, -1, 1); - r = new Rectangle (-1, -1, 3, 3); + t = new (-1, 1, -1, 1); + r = new (-1, -1, 3, 3); inside = t.GetInside (r); Assert.Equal (-2, inside.X); Assert.Equal (0, inside.Y); Assert.Equal (5, inside.Width); Assert.Equal (1, inside.Height); - t = new Thickness (-1, 1, -1, 1); - r = new Rectangle (1, 1, 3, 3); + t = new (-1, 1, -1, 1); + r = new (1, 1, 3, 3); inside = t.GetInside (r); Assert.Equal (0, inside.X); Assert.Equal (2, inside.Y); Assert.Equal (5, inside.Width); Assert.Equal (1, inside.Height); - t = new Thickness (-2, -1, 0, 1); - r = new Rectangle (-1, 0, 50, 60); + t = new (-2, -1, 0, 1); + r = new (-1, 0, 50, 60); inside = t.GetInside (r); Assert.Equal (-3, inside.X); Assert.Equal (-1, inside.Y); @@ -386,24 +137,24 @@ public class ThicknessTests (ITestOutputHelper output) Assert.Equal (5, inside.Width); Assert.Equal (5, inside.Height); - t = new Thickness (-1, -1, -1, -1); - r = new Rectangle (-1, -1, 3, 3); + t = new (-1, -1, -1, -1); + r = new (-1, -1, 3, 3); inside = t.GetInside (r); Assert.Equal (-2, inside.X); Assert.Equal (-2, inside.Y); Assert.Equal (5, inside.Width); Assert.Equal (5, inside.Height); - t = new Thickness (-1, -1, -1, -1); - r = new Rectangle (1, 1, 3, 3); + t = new (-1, -1, -1, -1); + r = new (1, 1, 3, 3); inside = t.GetInside (r); Assert.Equal (0, inside.X); Assert.Equal (0, inside.Y); Assert.Equal (5, inside.Width); Assert.Equal (5, inside.Height); - t = new Thickness (-1, -2, -3, -4); - r = new Rectangle (-1, 0, 50, 60); + t = new (-1, -2, -3, -4); + r = new (-1, 0, 50, 60); inside = t.GetInside (r); Assert.Equal (-2, inside.X); Assert.Equal (-2, inside.Y); @@ -422,24 +173,24 @@ public class ThicknessTests (ITestOutputHelper output) Assert.Equal (1, inside.Width); Assert.Equal (1, inside.Height); - t = new Thickness (1, 1, 1, 1); - r = new Rectangle (-1, -1, 3, 3); + t = new (1, 1, 1, 1); + r = new (-1, -1, 3, 3); inside = t.GetInside (r); Assert.Equal (0, inside.X); Assert.Equal (0, inside.Y); Assert.Equal (1, inside.Width); Assert.Equal (1, inside.Height); - t = new Thickness (1, 1, 1, 1); - r = new Rectangle (1, 1, 3, 3); + t = new (1, 1, 1, 1); + r = new (1, 1, 3, 3); inside = t.GetInside (r); Assert.Equal (2, inside.X); Assert.Equal (2, inside.Y); Assert.Equal (1, inside.Width); Assert.Equal (1, inside.Height); - t = new Thickness (1, 2, 3, 4); - r = new Rectangle (-1, 0, 50, 60); + t = new (1, 2, 3, 4); + r = new (-1, 0, 50, 60); inside = t.GetInside (r); Assert.Equal (0, inside.X); Assert.Equal (2, inside.Y); @@ -458,72 +209,72 @@ public class ThicknessTests (ITestOutputHelper output) Assert.Equal (0, inside.Width); Assert.Equal (0, inside.Height); - t = new Thickness (1, 1, 1, 1); - r = new Rectangle (0, 0, 1, 1); + t = new (1, 1, 1, 1); + r = new (0, 0, 1, 1); inside = t.GetInside (r); Assert.Equal (1, inside.X); Assert.Equal (1, inside.Y); Assert.Equal (0, inside.Width); Assert.Equal (0, inside.Height); - t = new Thickness (1, 1, 1, 1); - r = new Rectangle (1, 1, 1, 1); + t = new (1, 1, 1, 1); + r = new (1, 1, 1, 1); inside = t.GetInside (r); Assert.Equal (2, inside.X); Assert.Equal (2, inside.Y); Assert.Equal (0, inside.Width); Assert.Equal (0, inside.Height); - t = new Thickness (1, 1, 1, 1); - r = new Rectangle (0, 0, 1, 0); + t = new (1, 1, 1, 1); + r = new (0, 0, 1, 0); inside = t.GetInside (r); Assert.Equal (1, inside.X); Assert.Equal (1, inside.Y); Assert.Equal (0, inside.Width); Assert.Equal (0, inside.Height); - t = new Thickness (1, 1, 1, 1); - r = new Rectangle (0, 0, 0, 1); + t = new (1, 1, 1, 1); + r = new (0, 0, 0, 1); inside = t.GetInside (r); Assert.Equal (1, inside.X); Assert.Equal (1, inside.Y); Assert.Equal (0, inside.Width); Assert.Equal (0, inside.Height); - t = new Thickness (1, 1, 1, 1); - r = new Rectangle (-1, -1, 0, 1); + t = new (1, 1, 1, 1); + r = new (-1, -1, 0, 1); inside = t.GetInside (r); Assert.Equal (0, inside.X); Assert.Equal (0, inside.Y); Assert.Equal (0, inside.Width); Assert.Equal (0, inside.Height); - t = new Thickness (1, 1, 1, 1); - r = new Rectangle (0, 0, 2, 2); + t = new (1, 1, 1, 1); + r = new (0, 0, 2, 2); inside = t.GetInside (r); Assert.Equal (1, inside.X); Assert.Equal (1, inside.Y); Assert.Equal (0, inside.Width); Assert.Equal (0, inside.Height); - t = new Thickness (1, 1, 1, 1); - r = new Rectangle (-1, -1, 2, 2); + t = new (1, 1, 1, 1); + r = new (-1, -1, 2, 2); inside = t.GetInside (r); Assert.Equal (0, inside.X); Assert.Equal (0, inside.Y); Assert.Equal (0, inside.Width); Assert.Equal (0, inside.Height); - t = new Thickness (1, 1, 1, 1); - r = new Rectangle (1, 1, 2, 2); + t = new (1, 1, 1, 1); + r = new (1, 1, 2, 2); inside = t.GetInside (r); Assert.Equal (2, inside.X); Assert.Equal (2, inside.Y); Assert.Equal (0, inside.Width); Assert.Equal (0, inside.Height); - t = new Thickness (1, 2, 3, 4); - r = new Rectangle (-1, 0, 4, 6); + t = new (1, 2, 3, 4); + r = new (-1, 0, 4, 6); inside = t.GetInside (r); Assert.Equal (0, inside.X); Assert.Equal (2, inside.Y); @@ -542,40 +293,40 @@ public class ThicknessTests (ITestOutputHelper output) Assert.Equal (0, inside.Width); Assert.Equal (0, inside.Height); - t = new Thickness (0, 0, 0, 0); - r = new Rectangle (0, 0, 1, 1); + t = new (0, 0, 0, 0); + r = new (0, 0, 1, 1); inside = t.GetInside (r); Assert.Equal (0, inside.X); Assert.Equal (0, inside.Y); Assert.Equal (1, inside.Width); Assert.Equal (1, inside.Height); - t = new Thickness (0, 0, 0, 0); - r = new Rectangle (1, 1, 1, 1); + t = new (0, 0, 0, 0); + r = new (1, 1, 1, 1); inside = t.GetInside (r); Assert.Equal (1, inside.X); Assert.Equal (1, inside.Y); Assert.Equal (1, inside.Width); Assert.Equal (1, inside.Height); - t = new Thickness (0, 0, 0, 0); - r = new Rectangle (0, 0, 1, 0); + t = new (0, 0, 0, 0); + r = new (0, 0, 1, 0); inside = t.GetInside (r); Assert.Equal (0, inside.X); Assert.Equal (0, inside.Y); Assert.Equal (1, inside.Width); Assert.Equal (0, inside.Height); - t = new Thickness (0, 0, 0, 0); - r = new Rectangle (0, 0, 0, 1); + t = new (0, 0, 0, 0); + r = new (0, 0, 0, 1); inside = t.GetInside (r); Assert.Equal (0, inside.X); Assert.Equal (0, inside.Y); Assert.Equal (0, inside.Width); Assert.Equal (1, inside.Height); - t = new Thickness (0, 0, 0, 0); - r = new Rectangle (-1, -1, 0, 1); + t = new (0, 0, 0, 0); + r = new (-1, -1, 0, 1); inside = t.GetInside (r); Assert.Equal (-1, inside.X); Assert.Equal (-1, inside.Y); @@ -589,7 +340,7 @@ public class ThicknessTests (ITestOutputHelper output) var t = new Thickness (1, 2, 3, 4); Assert.Equal (4, t.Horizontal); - t = new Thickness (0); + t = new (0); Assert.Equal (0, t.Horizontal); } @@ -723,13 +474,11 @@ public class ThicknessTests (ITestOutputHelper output) Assert.Equal (expected, result); } - [Theory] [InlineData (0, 0, 0, 0, 0, 0, false)] [InlineData (0, 0, 0, 1, 0, 0, false)] [InlineData (0, 0, 1, 0, 0, 0, false)] [InlineData (0, 0, 1, 1, 0, 0, true)] - [InlineData (1, 1, 0, 0, 0, 0, false)] [InlineData (1, 1, 0, 1, 0, 0, false)] [InlineData (1, 1, 1, 0, 0, 0, false)] @@ -757,7 +506,7 @@ public class ThicknessTests (ITestOutputHelper output) var t = new Thickness (1, 2, 3, 4); Assert.Equal (6, t.Vertical); - t = new Thickness (0); + t = new (0); Assert.Equal (0, t.Vertical); } @@ -844,7 +593,6 @@ public class ThicknessTests (ITestOutputHelper output) 3, 4, 5)] - public void AddTest ( int left, int top, @@ -862,7 +610,7 @@ public class ThicknessTests (ITestOutputHelper output) { var t = new Thickness (left, top, right, bottom); var t2 = new Thickness (left2, top2, right2, bottom2); - var result = t.Add (t2); + Thickness result = t.Add (t2); Assert.Equal (expectedLeft, result.Left); Assert.Equal (expectedTop, result.Top); Assert.Equal (expectedRight, result.Right); diff --git a/UnitTests/FileServices/FileSystemColorProviderTests.cs b/Tests/UnitTestsParallelizable/FileServices/FileSystemColorProviderTests.cs similarity index 100% rename from UnitTests/FileServices/FileSystemColorProviderTests.cs rename to Tests/UnitTestsParallelizable/FileServices/FileSystemColorProviderTests.cs diff --git a/UnitTests/FileServices/FileSystemIconProviderTests.cs b/Tests/UnitTestsParallelizable/FileServices/FileSystemIconProviderTests.cs similarity index 100% rename from UnitTests/FileServices/FileSystemIconProviderTests.cs rename to Tests/UnitTestsParallelizable/FileServices/FileSystemIconProviderTests.cs diff --git a/UnitTests/FileServices/NerdFontsTests.cs b/Tests/UnitTestsParallelizable/FileServices/NerdFontsTests.cs similarity index 100% rename from UnitTests/FileServices/NerdFontsTests.cs rename to Tests/UnitTestsParallelizable/FileServices/NerdFontsTests.cs diff --git a/UnitTests/Input/Keyboard/KeyBindingTests.cs b/Tests/UnitTestsParallelizable/Input/Keyboard/KeyBindingTests.cs similarity index 100% rename from UnitTests/Input/Keyboard/KeyBindingTests.cs rename to Tests/UnitTestsParallelizable/Input/Keyboard/KeyBindingTests.cs diff --git a/UnitTests/Input/Keyboard/KeyBindingsTests.cs b/Tests/UnitTestsParallelizable/Input/Keyboard/KeyBindingsTests.cs similarity index 100% rename from UnitTests/Input/Keyboard/KeyBindingsTests.cs rename to Tests/UnitTestsParallelizable/Input/Keyboard/KeyBindingsTests.cs diff --git a/UnitTests/Input/Keyboard/KeyTests.cs b/Tests/UnitTestsParallelizable/Input/Keyboard/KeyTests.cs similarity index 95% rename from UnitTests/Input/Keyboard/KeyTests.cs rename to Tests/UnitTestsParallelizable/Input/Keyboard/KeyTests.cs index ecc08624b..0fcb4bead 100644 --- a/UnitTests/Input/Keyboard/KeyTests.cs +++ b/Tests/UnitTestsParallelizable/Input/Keyboard/KeyTests.cs @@ -180,9 +180,6 @@ public class KeyTests [InlineData ('!', (KeyCode)'!')] [InlineData ('\r', KeyCode.Enter)] [InlineData ('\t', KeyCode.Tab)] -#pragma warning disable xUnit1025 // InlineData should be unique within the Theory it belongs to - [InlineData ('\r', (KeyCode)13)] -#pragma warning restore xUnit1025 // InlineData should be unique within the Theory it belongs to [InlineData ('\n', (KeyCode)10)] [InlineData ('ó', (KeyCode)'ó')] [InlineData ('Ó', (KeyCode)'Ó')] @@ -292,10 +289,10 @@ public class KeyTests [Fact] public void NoShift_ShouldReturnCorrectValue () { - Key CAD = Key.Delete.WithCtrl.WithAlt; - Assert.Equal (KeyCode.Delete | KeyCode.CtrlMask | KeyCode.AltMask, CAD); + Key cad = Key.Delete.WithCtrl.WithAlt; + Assert.Equal (KeyCode.Delete | KeyCode.CtrlMask | KeyCode.AltMask, cad); - Assert.Equal (KeyCode.Delete | KeyCode.AltMask, CAD.NoCtrl); + Assert.Equal (KeyCode.Delete | KeyCode.AltMask, cad.NoCtrl); Key a = Key.A.WithCtrl.WithAlt.WithShift; Assert.Equal (KeyCode.A, a.NoCtrl.NoShift.NoAlt); @@ -412,15 +409,6 @@ public class KeyTests [InlineData (KeyCode.ShiftMask | KeyCode.AltMask | KeyCode.Null, "Alt+Shift")] [InlineData (KeyCode.AltMask | KeyCode.CtrlMask | KeyCode.Null, "Ctrl+Alt")] [InlineData (KeyCode.ShiftMask | KeyCode.CtrlMask | KeyCode.AltMask | KeyCode.Null, "Ctrl+Alt+Shift")] -#pragma warning disable xUnit1025 // InlineData should be unique within the Theory it belongs to - [InlineData (KeyCode.ShiftMask, "Shift")] - [InlineData (KeyCode.CtrlMask, "Ctrl")] - [InlineData (KeyCode.AltMask, "Alt")] - [InlineData (KeyCode.ShiftMask | KeyCode.CtrlMask, "Ctrl+Shift")] - [InlineData (KeyCode.ShiftMask | KeyCode.AltMask, "Alt+Shift")] - [InlineData (KeyCode.AltMask | KeyCode.CtrlMask, "Ctrl+Alt")] - [InlineData (KeyCode.ShiftMask | KeyCode.CtrlMask | KeyCode.AltMask, "Ctrl+Alt+Shift")] -#pragma warning restore xUnit1025 // InlineData should be unique within the Theory it belongs to [InlineData (KeyCode.CharMask, "CharMask")] [InlineData (KeyCode.SpecialMask, "Ctrl+Alt+Shift")] [InlineData ((KeyCode)'+', "+")] @@ -519,8 +507,8 @@ public class KeyTests Key a = Key.A; Assert.Equal (KeyCode.A | KeyCode.ShiftMask, a.WithShift); - Key CAD = Key.Delete.WithCtrl.WithAlt; - Assert.Equal (KeyCode.Delete | KeyCode.CtrlMask | KeyCode.AltMask, CAD); + Key cad = Key.Delete.WithCtrl.WithAlt; + Assert.Equal (KeyCode.Delete | KeyCode.CtrlMask | KeyCode.AltMask, cad); } // Test Equals diff --git a/UnitTests/Input/Mouse/MouseBindingTests.cs b/Tests/UnitTestsParallelizable/Input/Mouse/MouseBindingTests.cs similarity index 100% rename from UnitTests/Input/Mouse/MouseBindingTests.cs rename to Tests/UnitTestsParallelizable/Input/Mouse/MouseBindingTests.cs diff --git a/UnitTests/Input/Mouse/MouseBindingsTests.cs b/Tests/UnitTestsParallelizable/Input/Mouse/MouseBindingsTests.cs similarity index 100% rename from UnitTests/Input/Mouse/MouseBindingsTests.cs rename to Tests/UnitTestsParallelizable/Input/Mouse/MouseBindingsTests.cs diff --git a/UnitTests/Input/Mouse/MouseEventArgsTest.cs b/Tests/UnitTestsParallelizable/Input/Mouse/MouseEventArgsTest.cs similarity index 100% rename from UnitTests/Input/Mouse/MouseEventArgsTest.cs rename to Tests/UnitTestsParallelizable/Input/Mouse/MouseEventArgsTest.cs diff --git a/UnitTests/Input/ResponderTests.cs b/Tests/UnitTestsParallelizable/Input/ResponderTests.cs similarity index 99% rename from UnitTests/Input/ResponderTests.cs rename to Tests/UnitTestsParallelizable/Input/ResponderTests.cs index ed899aede..c45d37e2d 100644 --- a/UnitTests/Input/ResponderTests.cs +++ b/Tests/UnitTestsParallelizable/Input/ResponderTests.cs @@ -4,8 +4,6 @@ namespace Terminal.Gui.InputTests; public class ResponderTests { - - [Fact] public void KeyPressed_Handled_True_Cancels_KeyPress () { diff --git a/UnitTests/LocalPackagesTests.cs b/Tests/UnitTestsParallelizable/LocalPackagesTests.cs similarity index 93% rename from UnitTests/LocalPackagesTests.cs rename to Tests/UnitTestsParallelizable/LocalPackagesTests.cs index 04e5c7802..38c268cff 100644 --- a/UnitTests/LocalPackagesTests.cs +++ b/Tests/UnitTestsParallelizable/LocalPackagesTests.cs @@ -8,7 +8,7 @@ public class LocalPackagesTests public LocalPackagesTests () { // Define the local_packages path relative to the solution directory - _localPackagesPath = Path.Combine (Directory.GetCurrentDirectory (), "..", "..", "..", "..", "local_packages"); + _localPackagesPath = Path.Combine (Directory.GetCurrentDirectory (), "..", "..", "..", "..", "..", "local_packages"); } [Fact] diff --git a/Tests/UnitTestsParallelizable/README.md b/Tests/UnitTestsParallelizable/README.md new file mode 100644 index 000000000..5d1ebb4d3 --- /dev/null +++ b/Tests/UnitTestsParallelizable/README.md @@ -0,0 +1,2 @@ +# Automated Unit Tests for parallelizable code + diff --git a/UnitTests/Text/CollectionNavigatorTests.cs b/Tests/UnitTestsParallelizable/Text/CollectionNavigatorTests.cs similarity index 100% rename from UnitTests/Text/CollectionNavigatorTests.cs rename to Tests/UnitTestsParallelizable/Text/CollectionNavigatorTests.cs diff --git a/UnitTests/Text/RuneTests.cs b/Tests/UnitTestsParallelizable/Text/RuneTests.cs similarity index 100% rename from UnitTests/Text/RuneTests.cs rename to Tests/UnitTestsParallelizable/Text/RuneTests.cs diff --git a/UnitTests/Text/StringTests.cs b/Tests/UnitTestsParallelizable/Text/StringTests.cs similarity index 100% rename from UnitTests/Text/StringTests.cs rename to Tests/UnitTestsParallelizable/Text/StringTests.cs diff --git a/UnitTests/Text/TextFormatterTests.cs b/Tests/UnitTestsParallelizable/Text/TextFormatterTests.cs similarity index 53% rename from UnitTests/Text/TextFormatterTests.cs rename to Tests/UnitTestsParallelizable/Text/TextFormatterTests.cs index 786f566fd..18b7e5041 100644 --- a/UnitTests/Text/TextFormatterTests.cs +++ b/Tests/UnitTestsParallelizable/Text/TextFormatterTests.cs @@ -1,16 +1,14 @@ using System.Text; -using UICatalog; using Xunit.Abstractions; +using UnitTests; + // Alias Console to MockConsole so we don't accidentally use Console namespace Terminal.Gui.TextTests; public class TextFormatterTests { - public TextFormatterTests (ITestOutputHelper output) { _output = output; } - private readonly ITestOutputHelper _output; - [Theory] [InlineData ("")] [InlineData (null)] @@ -237,3978 +235,7 @@ public class TextFormatterTests public static IEnumerable CMGlyphs => new List { new object [] { $"{Glyphs.LeftBracket} Say Hello 你 {Glyphs.RightBracket}", 16, 15 } }; - [SetupFakeDriver] - [Theory] - [InlineData ("A", 0, "")] - [InlineData ("A", 1, "A")] - [InlineData ("A", 2, "A")] - [InlineData ("A", 3, " A")] - [InlineData ("AB", 1, "A")] - [InlineData ("AB", 2, "AB")] - [InlineData ("ABC", 3, "ABC")] - [InlineData ("ABC", 4, "ABC")] - [InlineData ("ABC", 5, " ABC")] - [InlineData ("ABC", 6, " ABC")] - [InlineData ("ABC", 9, " ABC")] - public void Draw_Horizontal_Centered (string text, int width, string expectedText) - { - TextFormatter tf = new () - { - Text = text, - Alignment = Alignment.Center - }; - tf.ConstrainToWidth = width; - tf.ConstrainToHeight = 1; - tf.Draw (new (0, 0, width, 1), Attribute.Default, Attribute.Default); - - TestHelpers.AssertDriverContentsWithFrameAre (expectedText, _output); - } - - [SetupFakeDriver] - [Theory] - [InlineData ("A", 0, "")] - [InlineData ("A", 1, "A")] - [InlineData ("A", 2, "A")] - [InlineData ("A B", 3, "A B")] - [InlineData ("A B", 1, "A")] - [InlineData ("A B", 2, "A")] - [InlineData ("A B", 4, "A B")] - [InlineData ("A B", 5, "A B")] - [InlineData ("A B", 6, "A B")] - [InlineData ("A B", 10, "A B")] - [InlineData ("ABC ABC", 10, "ABC ABC")] - public void Draw_Horizontal_Justified (string text, int width, string expectedText) - { - TextFormatter tf = new () - { - Text = text, - Alignment = Alignment.Fill - }; - - tf.ConstrainToWidth = width; - tf.ConstrainToHeight = 1; - tf.Draw (new (0, 0, width, 1), Attribute.Default, Attribute.Default); - - TestHelpers.AssertDriverContentsWithFrameAre (expectedText, _output); - } - - [SetupFakeDriver] - [Theory] - [InlineData ("A", 0, "")] - [InlineData ("A", 1, "A")] - [InlineData ("A", 2, "A")] - [InlineData ("AB", 1, "A")] - [InlineData ("AB", 2, "AB")] - [InlineData ("ABC", 3, "ABC")] - [InlineData ("ABC", 4, "ABC")] - [InlineData ("ABC", 6, "ABC")] - public void Draw_Horizontal_Left (string text, int width, string expectedText) - - { - TextFormatter tf = new () - { - Text = text, - Alignment = Alignment.Start - }; - - tf.ConstrainToWidth = width; - tf.ConstrainToHeight = 1; - tf.Draw (new (0, 0, width, 1), Attribute.Default, Attribute.Default); - - TestHelpers.AssertDriverContentsWithFrameAre (expectedText, _output); - } - - [SetupFakeDriver] - [Theory] - [InlineData ("A", 0, "")] - [InlineData ("A", 1, "A")] - [InlineData ("A", 2, " A")] - [InlineData ("AB", 1, "B")] - [InlineData ("AB", 2, "AB")] - [InlineData ("ABC", 3, "ABC")] - [InlineData ("ABC", 4, " ABC")] - [InlineData ("ABC", 6, " ABC")] - public void Draw_Horizontal_Right (string text, int width, string expectedText) - { - TextFormatter tf = new () - { - Text = text, - Alignment = Alignment.End - }; - - tf.ConstrainToWidth = width; - tf.ConstrainToHeight = 1; - - tf.Draw (new (Point.Empty, new (width, 1)), Attribute.Default, Attribute.Default); - TestHelpers.AssertDriverContentsWithFrameAre (expectedText, _output); - } - - [SetupFakeDriver] - [Theory] - [InlineData ("A", 1, 0, "")] - [InlineData ("A", 0, 1, "")] - [InlineData ("AB1 2", 2, 1, "2")] - [InlineData ("AB12", 5, 1, "21BA")] - [InlineData ("AB\n12", 5, 2, "21\nBA")] - [InlineData ("ABC 123 456", 7, 2, "CBA \n654 321")] - [InlineData ("こんにちは", 1, 1, "")] - [InlineData ("こんにちは", 2, 1, "は")] - [InlineData ("こんにちは", 5, 1, "はち")] - [InlineData ("こんにちは", 10, 1, "はちにんこ")] - [InlineData ("こんにちは\nAB\n12", 10, 3, "21 \nBA \nはちにんこ")] - public void Draw_Horizontal_RightLeft_BottomTop (string text, int width, int height, string expectedText) - { - TextFormatter tf = new () - { - Text = text, - Direction = TextDirection.RightLeft_BottomTop - }; - - tf.ConstrainToWidth = width; - tf.ConstrainToHeight = height; - tf.Draw (new (0, 0, width, height), Attribute.Default, Attribute.Default); - - TestHelpers.AssertDriverContentsWithFrameAre (expectedText, _output); - } - - [SetupFakeDriver] - [Theory] - [InlineData ("A", 1, 0, "")] - [InlineData ("A", 0, 1, "")] - [InlineData ("AB1 2", 2, 1, "2")] - [InlineData ("AB12", 5, 1, "21BA")] - [InlineData ("AB\n12", 5, 2, "BA\n21")] - [InlineData ("ABC 123 456", 7, 2, "654 321\nCBA ")] - [InlineData ("こんにちは", 1, 1, "")] - [InlineData ("こんにちは", 2, 1, "は")] - [InlineData ("こんにちは", 5, 1, "はち")] - [InlineData ("こんにちは", 10, 1, "はちにんこ")] - [InlineData ("こんにちは\nAB\n12", 10, 3, "はちにんこ\nBA \n21 ")] - public void Draw_Horizontal_RightLeft_TopBottom (string text, int width, int height, string expectedText) - { - TextFormatter tf = new () - { - Text = text, - Direction = TextDirection.RightLeft_TopBottom - }; - - tf.ConstrainToWidth = width; - tf.ConstrainToHeight = height; - tf.Draw (new (0, 0, width, height), Attribute.Default, Attribute.Default); - - TestHelpers.AssertDriverContentsWithFrameAre (expectedText, _output); - } - - [SetupFakeDriver] - [Theory] - - // Horizontal with Alignment.Start - // LeftRight_TopBottom - [InlineData ( - "0 2 4", - Alignment.Start, - Alignment.Start, - TextDirection.LeftRight_TopBottom, - @" -0 2 4** -******* -******* -******* -******* -******* -*******")] - [InlineData ( - "0 2 4", - Alignment.End, - Alignment.Start, - TextDirection.LeftRight_TopBottom, - @" -**0 2 4 -******* -******* -******* -******* -******* -*******")] - [InlineData ( - "0 2 4", - Alignment.Center, - Alignment.Start, - TextDirection.LeftRight_TopBottom, - @" -*0 2 4* -******* -******* -******* -******* -******* -*******")] - [InlineData ( - "0 2 4", - Alignment.Fill, - Alignment.Start, - TextDirection.LeftRight_TopBottom, - @" -0 2 4 -******* -******* -******* -******* -******* -*******")] - [InlineData ( - "0 你 4", - Alignment.Start, - Alignment.Start, - TextDirection.LeftRight_TopBottom, - @" -0 你 4* -******* -******* -******* -******* -******* -*******")] - [InlineData ( - "0 你 4", - Alignment.End, - Alignment.Start, - TextDirection.LeftRight_TopBottom, - @" -*0 你 4 -******* -******* -******* -******* -******* -*******")] - [InlineData ( - "0 你 4", - Alignment.Center, - Alignment.Start, - TextDirection.LeftRight_TopBottom, - @" -0 你 4* -******* -******* -******* -******* -******* -*******")] - [InlineData ( - "0 你 4", - Alignment.Fill, - Alignment.Start, - TextDirection.LeftRight_TopBottom, - @" -0 你 4 -******* -******* -******* -******* -******* -*******")] - - // LeftRight_BottomTop - [InlineData ( - "0 2 4", - Alignment.Start, - Alignment.Start, - TextDirection.LeftRight_BottomTop, - @" -0 2 4** -******* -******* -******* -******* -******* -*******")] - [InlineData ( - "0 2 4", - Alignment.End, - Alignment.Start, - TextDirection.LeftRight_BottomTop, - @" -**0 2 4 -******* -******* -******* -******* -******* -*******")] - [InlineData ( - "0 2 4", - Alignment.Center, - Alignment.Start, - TextDirection.LeftRight_BottomTop, - @" -*0 2 4* -******* -******* -******* -******* -******* -*******")] - [InlineData ( - "0 2 4", - Alignment.Fill, - Alignment.Start, - TextDirection.LeftRight_BottomTop, - @" -0 2 4 -******* -******* -******* -******* -******* -*******")] - [InlineData ( - "0 你 4", - Alignment.Start, - Alignment.Start, - TextDirection.LeftRight_BottomTop, - @" -0 你 4* -******* -******* -******* -******* -******* -*******")] - [InlineData ( - "0 你 4", - Alignment.End, - Alignment.Start, - TextDirection.LeftRight_BottomTop, - @" -*0 你 4 -******* -******* -******* -******* -******* -*******")] - [InlineData ( - "0 你 4", - Alignment.Center, - Alignment.Start, - TextDirection.LeftRight_BottomTop, - @" -0 你 4* -******* -******* -******* -******* -******* -*******")] - [InlineData ( - "0 你 4", - Alignment.Fill, - Alignment.Start, - TextDirection.LeftRight_BottomTop, - @" -0 你 4 -******* -******* -******* -******* -******* -*******")] - - // RightLeft_TopBottom - [InlineData ( - "0 2 4", - Alignment.Start, - Alignment.Start, - TextDirection.RightLeft_TopBottom, - @" -4 2 0** -******* -******* -******* -******* -******* -*******")] - [InlineData ( - "0 2 4", - Alignment.End, - Alignment.Start, - TextDirection.RightLeft_TopBottom, - @" -**4 2 0 -******* -******* -******* -******* -******* -*******")] - [InlineData ( - "0 2 4", - Alignment.Center, - Alignment.Start, - TextDirection.RightLeft_TopBottom, - @" -*4 2 0* -******* -******* -******* -******* -******* -*******")] - [InlineData ( - "0 2 4", - Alignment.Fill, - Alignment.Start, - TextDirection.RightLeft_TopBottom, - @" -4 2 0 -******* -******* -******* -******* -******* -*******")] - [InlineData ( - "0 你 4", - Alignment.Start, - Alignment.Start, - TextDirection.RightLeft_TopBottom, - @" -4 你 0* -******* -******* -******* -******* -******* -*******")] - [InlineData ( - "0 你 4", - Alignment.End, - Alignment.Start, - TextDirection.RightLeft_TopBottom, - @" -*4 你 0 -******* -******* -******* -******* -******* -*******")] - [InlineData ( - "0 你 4", - Alignment.Center, - Alignment.Start, - TextDirection.RightLeft_TopBottom, - @" -4 你 0* -******* -******* -******* -******* -******* -*******")] - [InlineData ( - "0 你 4", - Alignment.Fill, - Alignment.Start, - TextDirection.RightLeft_TopBottom, - @" -4 你 0 -******* -******* -******* -******* -******* -*******")] - - // RightLeft_BottomTop - [InlineData ( - "0 2 4", - Alignment.Start, - Alignment.Start, - TextDirection.RightLeft_BottomTop, - @" -4 2 0** -******* -******* -******* -******* -******* -*******")] - [InlineData ( - "0 2 4", - Alignment.End, - Alignment.Start, - TextDirection.RightLeft_BottomTop, - @" -**4 2 0 -******* -******* -******* -******* -******* -*******")] - [InlineData ( - "0 2 4", - Alignment.Center, - Alignment.Start, - TextDirection.RightLeft_BottomTop, - @" -*4 2 0* -******* -******* -******* -******* -******* -*******")] - [InlineData ( - "0 2 4", - Alignment.Fill, - Alignment.Start, - TextDirection.RightLeft_BottomTop, - @" -4 2 0 -******* -******* -******* -******* -******* -*******")] - [InlineData ( - "0 你 4", - Alignment.Start, - Alignment.Start, - TextDirection.RightLeft_BottomTop, - @" -4 你 0* -******* -******* -******* -******* -******* -*******")] - [InlineData ( - "0 你 4", - Alignment.End, - Alignment.Start, - TextDirection.RightLeft_BottomTop, - @" -*4 你 0 -******* -******* -******* -******* -******* -*******")] - [InlineData ( - "0 你 4", - Alignment.Center, - Alignment.Start, - TextDirection.RightLeft_BottomTop, - @" -4 你 0* -******* -******* -******* -******* -******* -*******")] - [InlineData ( - "0 你 4", - Alignment.Fill, - Alignment.Start, - TextDirection.RightLeft_BottomTop, - @" -4 你 0 -******* -******* -******* -******* -******* -*******")] - - // Horizontal with Alignment.End - // LeftRight_TopBottom - [InlineData ( - "0 2 4", - Alignment.Start, - Alignment.End, - TextDirection.LeftRight_TopBottom, - @" -******* -******* -******* -******* -******* -******* -0 2 4**")] - [InlineData ( - "0 2 4", - Alignment.End, - Alignment.End, - TextDirection.LeftRight_TopBottom, - @" -******* -******* -******* -******* -******* -******* -**0 2 4")] - [InlineData ( - "0 2 4", - Alignment.Center, - Alignment.End, - TextDirection.LeftRight_TopBottom, - @" -******* -******* -******* -******* -******* -******* -*0 2 4*")] - [InlineData ( - "0 2 4", - Alignment.Fill, - Alignment.End, - TextDirection.LeftRight_TopBottom, - @" -******* -******* -******* -******* -******* -******* -0 2 4")] - [InlineData ( - "0 你 4", - Alignment.Start, - Alignment.End, - TextDirection.LeftRight_TopBottom, - @" -******* -******* -******* -******* -******* -******* -0 你 4*")] - [InlineData ( - "0 你 4", - Alignment.End, - Alignment.End, - TextDirection.LeftRight_TopBottom, - @" -******* -******* -******* -******* -******* -******* -*0 你 4")] - [InlineData ( - "0 你 4", - Alignment.Center, - Alignment.End, - TextDirection.LeftRight_TopBottom, - @" -******* -******* -******* -******* -******* -******* -0 你 4*")] - [InlineData ( - "0 你 4", - Alignment.Fill, - Alignment.End, - TextDirection.LeftRight_TopBottom, - @" -******* -******* -******* -******* -******* -******* -0 你 4")] - - // LeftRight_BottomTop - [InlineData ( - "0 2 4", - Alignment.Start, - Alignment.End, - TextDirection.LeftRight_BottomTop, - @" -******* -******* -******* -******* -******* -******* -0 2 4**")] - [InlineData ( - "0 2 4", - Alignment.End, - Alignment.End, - TextDirection.LeftRight_BottomTop, - @" -******* -******* -******* -******* -******* -******* -**0 2 4")] - [InlineData ( - "0 2 4", - Alignment.Center, - Alignment.End, - TextDirection.LeftRight_BottomTop, - @" -******* -******* -******* -******* -******* -******* -*0 2 4*")] - [InlineData ( - "0 2 4", - Alignment.Fill, - Alignment.End, - TextDirection.LeftRight_BottomTop, - @" -******* -******* -******* -******* -******* -******* -0 2 4")] - [InlineData ( - "0 你 4", - Alignment.Start, - Alignment.End, - TextDirection.LeftRight_BottomTop, - @" -******* -******* -******* -******* -******* -******* -0 你 4*")] - [InlineData ( - "0 你 4", - Alignment.End, - Alignment.End, - TextDirection.LeftRight_BottomTop, - @" -******* -******* -******* -******* -******* -******* -*0 你 4")] - [InlineData ( - "0 你 4", - Alignment.Center, - Alignment.End, - TextDirection.LeftRight_BottomTop, - @" -******* -******* -******* -******* -******* -******* -0 你 4*")] - [InlineData ( - "0 你 4", - Alignment.Fill, - Alignment.End, - TextDirection.LeftRight_BottomTop, - @" -******* -******* -******* -******* -******* -******* -0 你 4")] - - // RightLeft_TopBottom - [InlineData ( - "0 2 4", - Alignment.Start, - Alignment.End, - TextDirection.RightLeft_TopBottom, - @" -******* -******* -******* -******* -******* -******* -4 2 0**")] - [InlineData ( - "0 2 4", - Alignment.End, - Alignment.End, - TextDirection.RightLeft_TopBottom, - @" -******* -******* -******* -******* -******* -******* -**4 2 0")] - [InlineData ( - "0 2 4", - Alignment.Center, - Alignment.End, - TextDirection.RightLeft_TopBottom, - @" -******* -******* -******* -******* -******* -******* -*4 2 0*")] - [InlineData ( - "0 2 4", - Alignment.Fill, - Alignment.End, - TextDirection.RightLeft_TopBottom, - @" -******* -******* -******* -******* -******* -******* -4 2 0")] - [InlineData ( - "0 你 4", - Alignment.Start, - Alignment.End, - TextDirection.RightLeft_TopBottom, - @" -******* -******* -******* -******* -******* -******* -4 你 0*")] - [InlineData ( - "0 你 4", - Alignment.End, - Alignment.End, - TextDirection.RightLeft_TopBottom, - @" -******* -******* -******* -******* -******* -******* -*4 你 0")] - [InlineData ( - "0 你 4", - Alignment.Center, - Alignment.End, - TextDirection.RightLeft_TopBottom, - @" -******* -******* -******* -******* -******* -******* -4 你 0*")] - [InlineData ( - "0 你 4", - Alignment.Fill, - Alignment.End, - TextDirection.RightLeft_TopBottom, - @" -******* -******* -******* -******* -******* -******* -4 你 0")] - - // RightLeft_BottomTop - [InlineData ( - "0 2 4", - Alignment.Start, - Alignment.End, - TextDirection.RightLeft_BottomTop, - @" -******* -******* -******* -******* -******* -******* -4 2 0**")] - [InlineData ( - "0 2 4", - Alignment.End, - Alignment.End, - TextDirection.RightLeft_BottomTop, - @" -******* -******* -******* -******* -******* -******* -**4 2 0")] - [InlineData ( - "0 2 4", - Alignment.Center, - Alignment.End, - TextDirection.RightLeft_BottomTop, - @" -******* -******* -******* -******* -******* -******* -*4 2 0*")] - [InlineData ( - "0 2 4", - Alignment.Fill, - Alignment.End, - TextDirection.RightLeft_BottomTop, - @" -******* -******* -******* -******* -******* -******* -4 2 0")] - [InlineData ( - "0 你 4", - Alignment.Start, - Alignment.End, - TextDirection.RightLeft_BottomTop, - @" -******* -******* -******* -******* -******* -******* -4 你 0*")] - [InlineData ( - "0 你 4", - Alignment.End, - Alignment.End, - TextDirection.RightLeft_BottomTop, - @" -******* -******* -******* -******* -******* -******* -*4 你 0")] - [InlineData ( - "0 你 4", - Alignment.Center, - Alignment.End, - TextDirection.RightLeft_BottomTop, - @" -******* -******* -******* -******* -******* -******* -4 你 0*")] - [InlineData ( - "0 你 4", - Alignment.Fill, - Alignment.End, - TextDirection.RightLeft_BottomTop, - @" -******* -******* -******* -******* -******* -******* -4 你 0")] - - // Horizontal with alignment.Centered - // LeftRight_TopBottom - [InlineData ( - "0 2 4", - Alignment.Start, - Alignment.Center, - TextDirection.LeftRight_TopBottom, - @" -******* -******* -******* -0 2 4** -******* -******* -*******")] - [InlineData ( - "0 2 4", - Alignment.End, - Alignment.Center, - TextDirection.LeftRight_TopBottom, - @" -******* -******* -******* -**0 2 4 -******* -******* -*******")] - [InlineData ( - "0 2 4", - Alignment.Center, - Alignment.Center, - TextDirection.LeftRight_TopBottom, - @" -******* -******* -******* -*0 2 4* -******* -******* -*******")] - [InlineData ( - "0 2 4", - Alignment.Fill, - Alignment.Center, - TextDirection.LeftRight_TopBottom, - @" -******* -******* -******* -0 2 4 -******* -******* -*******")] - [InlineData ( - "0 你 4", - Alignment.Start, - Alignment.Center, - TextDirection.LeftRight_TopBottom, - @" -******* -******* -******* -0 你 4* -******* -******* -*******")] - [InlineData ( - "0 你 4", - Alignment.End, - Alignment.Center, - TextDirection.LeftRight_TopBottom, - @" -******* -******* -******* -*0 你 4 -******* -******* -*******")] - [InlineData ( - "0 你 4", - Alignment.Center, - Alignment.Center, - TextDirection.LeftRight_TopBottom, - @" -******* -******* -******* -0 你 4* -******* -******* -*******")] - [InlineData ( - "0 你 4", - Alignment.Fill, - Alignment.Center, - TextDirection.LeftRight_TopBottom, - @" -******* -******* -******* -0 你 4 -******* -******* -*******")] - - // LeftRight_BottomTop - [InlineData ( - "0 2 4", - Alignment.Start, - Alignment.Center, - TextDirection.LeftRight_BottomTop, - @" -******* -******* -******* -0 2 4** -******* -******* -*******")] - [InlineData ( - "0 2 4", - Alignment.End, - Alignment.Center, - TextDirection.LeftRight_BottomTop, - @" -******* -******* -******* -**0 2 4 -******* -******* -*******")] - [InlineData ( - "0 2 4", - Alignment.Center, - Alignment.Center, - TextDirection.LeftRight_BottomTop, - @" -******* -******* -******* -*0 2 4* -******* -******* -*******")] - [InlineData ( - "0 2 4", - Alignment.Fill, - Alignment.Center, - TextDirection.LeftRight_BottomTop, - @" -******* -******* -******* -0 2 4 -******* -******* -*******")] - [InlineData ( - "0 你 4", - Alignment.Start, - Alignment.Center, - TextDirection.LeftRight_BottomTop, - @" -******* -******* -******* -0 你 4* -******* -******* -*******")] - [InlineData ( - "0 你 4", - Alignment.End, - Alignment.Center, - TextDirection.LeftRight_BottomTop, - @" -******* -******* -******* -*0 你 4 -******* -******* -*******")] - [InlineData ( - "0 你 4", - Alignment.Center, - Alignment.Center, - TextDirection.LeftRight_BottomTop, - @" -******* -******* -******* -0 你 4* -******* -******* -*******")] - [InlineData ( - "0 你 4", - Alignment.Fill, - Alignment.Center, - TextDirection.LeftRight_BottomTop, - @" -******* -******* -******* -0 你 4 -******* -******* -*******")] - - // RightLeft_TopBottom - [InlineData ( - "0 2 4", - Alignment.Start, - Alignment.Center, - TextDirection.RightLeft_TopBottom, - @" -******* -******* -******* -4 2 0** -******* -******* -*******")] - [InlineData ( - "0 2 4", - Alignment.End, - Alignment.Center, - TextDirection.RightLeft_TopBottom, - @" -******* -******* -******* -**4 2 0 -******* -******* -*******")] - [InlineData ( - "0 2 4", - Alignment.Center, - Alignment.Center, - TextDirection.RightLeft_TopBottom, - @" -******* -******* -******* -*4 2 0* -******* -******* -*******")] - [InlineData ( - "0 2 4", - Alignment.Fill, - Alignment.Center, - TextDirection.RightLeft_TopBottom, - @" -******* -******* -******* -4 2 0 -******* -******* -*******")] - [InlineData ( - "0 你 4", - Alignment.Start, - Alignment.Center, - TextDirection.RightLeft_TopBottom, - @" -******* -******* -******* -4 你 0* -******* -******* -*******")] - [InlineData ( - "0 你 4", - Alignment.End, - Alignment.Center, - TextDirection.RightLeft_TopBottom, - @" -******* -******* -******* -*4 你 0 -******* -******* -*******")] - [InlineData ( - "0 你 4", - Alignment.Center, - Alignment.Center, - TextDirection.RightLeft_TopBottom, - @" -******* -******* -******* -4 你 0* -******* -******* -*******")] - [InlineData ( - "0 你 4", - Alignment.Fill, - Alignment.Center, - TextDirection.RightLeft_TopBottom, - @" -******* -******* -******* -4 你 0 -******* -******* -*******")] - - // RightLeft_BottomTop - [InlineData ( - "0 2 4", - Alignment.Start, - Alignment.Center, - TextDirection.RightLeft_BottomTop, - @" -******* -******* -******* -4 2 0** -******* -******* -*******")] - [InlineData ( - "0 2 4", - Alignment.End, - Alignment.Center, - TextDirection.RightLeft_BottomTop, - @" -******* -******* -******* -**4 2 0 -******* -******* -*******")] - [InlineData ( - "0 2 4", - Alignment.Center, - Alignment.Center, - TextDirection.RightLeft_BottomTop, - @" -******* -******* -******* -*4 2 0* -******* -******* -*******")] - [InlineData ( - "0 2 4", - Alignment.Fill, - Alignment.Center, - TextDirection.RightLeft_BottomTop, - @" -******* -******* -******* -4 2 0 -******* -******* -*******")] - [InlineData ( - "0 你 4", - Alignment.Start, - Alignment.Center, - TextDirection.RightLeft_BottomTop, - @" -******* -******* -******* -4 你 0* -******* -******* -*******")] - [InlineData ( - "0 你 4", - Alignment.End, - Alignment.Center, - TextDirection.RightLeft_BottomTop, - @" -******* -******* -******* -*4 你 0 -******* -******* -*******")] - [InlineData ( - "0 你 4", - Alignment.Center, - Alignment.Center, - TextDirection.RightLeft_BottomTop, - @" -******* -******* -******* -4 你 0* -******* -******* -*******")] - [InlineData ( - "0 你 4", - Alignment.Fill, - Alignment.Center, - TextDirection.RightLeft_BottomTop, - @" -******* -******* -******* -4 你 0 -******* -******* -*******")] - - // Horizontal with alignment.Justified - // LeftRight_TopBottom - [InlineData ( - "0 2 4", - Alignment.Start, - Alignment.Fill, - TextDirection.LeftRight_TopBottom, - @" -0 2 4** -******* -******* -******* -******* -******* -*******")] - [InlineData ( - "0 2 4", - Alignment.End, - Alignment.Fill, - TextDirection.LeftRight_TopBottom, - @" -**0 2 4 -******* -******* -******* -******* -******* -*******")] - [InlineData ( - "0 2 4", - Alignment.Center, - Alignment.Fill, - TextDirection.LeftRight_TopBottom, - @" -*0 2 4* -******* -******* -******* -******* -******* -*******")] - [InlineData ( - "0 2 4", - Alignment.Fill, - Alignment.Fill, - TextDirection.LeftRight_TopBottom, - @" -0 2 4 -******* -******* -******* -******* -******* -*******")] - [InlineData ( - "0 你 4", - Alignment.Start, - Alignment.Fill, - TextDirection.LeftRight_TopBottom, - @" -0 你 4* -******* -******* -******* -******* -******* -*******")] - [InlineData ( - "0 你 4", - Alignment.End, - Alignment.Fill, - TextDirection.LeftRight_TopBottom, - @" -*0 你 4 -******* -******* -******* -******* -******* -*******")] - [InlineData ( - "0 你 4", - Alignment.Center, - Alignment.Fill, - TextDirection.LeftRight_TopBottom, - @" -0 你 4* -******* -******* -******* -******* -******* -*******")] - [InlineData ( - "0 你 4", - Alignment.Fill, - Alignment.Fill, - TextDirection.LeftRight_TopBottom, - @" -0 你 4 -******* -******* -******* -******* -******* -*******")] - - // LeftRight_BottomTop - [InlineData ( - "0 2 4", - Alignment.Start, - Alignment.Fill, - TextDirection.LeftRight_BottomTop, - @" -0 2 4** -******* -******* -******* -******* -******* -*******")] - [InlineData ( - "0 2 4", - Alignment.End, - Alignment.Fill, - TextDirection.LeftRight_BottomTop, - @" -**0 2 4 -******* -******* -******* -******* -******* -*******")] - [InlineData ( - "0 2 4", - Alignment.Center, - Alignment.Fill, - TextDirection.LeftRight_BottomTop, - @" -*0 2 4* -******* -******* -******* -******* -******* -*******")] - [InlineData ( - "0 2 4", - Alignment.Fill, - Alignment.Fill, - TextDirection.LeftRight_BottomTop, - @" -0 2 4 -******* -******* -******* -******* -******* -*******")] - [InlineData ( - "0 你 4", - Alignment.Start, - Alignment.Fill, - TextDirection.LeftRight_BottomTop, - @" -0 你 4* -******* -******* -******* -******* -******* -*******")] - [InlineData ( - "0 你 4", - Alignment.End, - Alignment.Fill, - TextDirection.LeftRight_BottomTop, - @" -*0 你 4 -******* -******* -******* -******* -******* -*******")] - [InlineData ( - "0 你 4", - Alignment.Center, - Alignment.Fill, - TextDirection.LeftRight_BottomTop, - @" -0 你 4* -******* -******* -******* -******* -******* -*******")] - [InlineData ( - "0 你 4", - Alignment.Fill, - Alignment.Fill, - TextDirection.LeftRight_BottomTop, - @" -0 你 4 -******* -******* -******* -******* -******* -*******")] - - // RightLeft_TopBottom - [InlineData ( - "0 2 4", - Alignment.Start, - Alignment.Fill, - TextDirection.RightLeft_TopBottom, - @" -4 2 0** -******* -******* -******* -******* -******* -*******")] - [InlineData ( - "0 2 4", - Alignment.End, - Alignment.Fill, - TextDirection.RightLeft_TopBottom, - @" -**4 2 0 -******* -******* -******* -******* -******* -*******")] - [InlineData ( - "0 2 4", - Alignment.Center, - Alignment.Fill, - TextDirection.RightLeft_TopBottom, - @" -*4 2 0* -******* -******* -******* -******* -******* -*******")] - [InlineData ( - "0 2 4", - Alignment.Fill, - Alignment.Fill, - TextDirection.RightLeft_TopBottom, - @" -4 2 0 -******* -******* -******* -******* -******* -*******")] - [InlineData ( - "0 你 4", - Alignment.Start, - Alignment.Fill, - TextDirection.RightLeft_TopBottom, - @" -4 你 0* -******* -******* -******* -******* -******* -*******")] - [InlineData ( - "0 你 4", - Alignment.End, - Alignment.Fill, - TextDirection.RightLeft_TopBottom, - @" -*4 你 0 -******* -******* -******* -******* -******* -*******")] - [InlineData ( - "0 你 4", - Alignment.Center, - Alignment.Fill, - TextDirection.RightLeft_TopBottom, - @" -4 你 0* -******* -******* -******* -******* -******* -*******")] - [InlineData ( - "0 你 4", - Alignment.Fill, - Alignment.Fill, - TextDirection.RightLeft_TopBottom, - @" -4 你 0 -******* -******* -******* -******* -******* -*******")] - - // RightLeft_BottomTop - [InlineData ( - "0 2 4", - Alignment.Start, - Alignment.Fill, - TextDirection.RightLeft_BottomTop, - @" -4 2 0** -******* -******* -******* -******* -******* -*******")] - [InlineData ( - "0 2 4", - Alignment.End, - Alignment.Fill, - TextDirection.RightLeft_BottomTop, - @" -**4 2 0 -******* -******* -******* -******* -******* -*******")] - [InlineData ( - "0 2 4", - Alignment.Center, - Alignment.Fill, - TextDirection.RightLeft_BottomTop, - @" -*4 2 0* -******* -******* -******* -******* -******* -*******")] - [InlineData ( - "0 2 4", - Alignment.Fill, - Alignment.Fill, - TextDirection.RightLeft_BottomTop, - @" -4 2 0 -******* -******* -******* -******* -******* -*******")] - [InlineData ( - "0 你 4", - Alignment.Start, - Alignment.Fill, - TextDirection.RightLeft_BottomTop, - @" -4 你 0* -******* -******* -******* -******* -******* -*******")] - [InlineData ( - "0 你 4", - Alignment.End, - Alignment.Fill, - TextDirection.RightLeft_BottomTop, - @" -*4 你 0 -******* -******* -******* -******* -******* -*******")] - [InlineData ( - "0 你 4", - Alignment.Center, - Alignment.Fill, - TextDirection.RightLeft_BottomTop, - @" -4 你 0* -******* -******* -******* -******* -******* -*******")] - [InlineData ( - "0 你 4", - Alignment.Fill, - Alignment.Fill, - TextDirection.RightLeft_BottomTop, - @" -4 你 0 -******* -******* -******* -******* -******* -*******")] - - // Vertical with alignment.Left - // TopBottom_LeftRight - [InlineData ( - "0 2 4", - Alignment.Start, - Alignment.Start, - TextDirection.TopBottom_LeftRight, - @" -0****** - ****** -2****** - ****** -4****** -******* -*******")] - [InlineData ( - "0 2 4", - Alignment.Start, - Alignment.End, - TextDirection.TopBottom_LeftRight, - @" -******* -******* -0****** - ****** -2****** - ****** -4******")] - [InlineData ( - "0 2 4", - Alignment.Start, - Alignment.Center, - TextDirection.TopBottom_LeftRight, - @" -******* -0****** - ****** -2****** - ****** -4****** -*******")] - [InlineData ( - "0 2 4", - Alignment.Start, - Alignment.Fill, - TextDirection.TopBottom_LeftRight, - @" -0****** - ****** - ****** -2****** - ****** - ****** -4******")] - [InlineData ( - "0 你 4", - Alignment.Start, - Alignment.Start, - TextDirection.TopBottom_LeftRight, - @" -0****** - ****** -你***** - ****** -4****** -******* -*******")] - [InlineData ( - "0 你 4", - Alignment.Start, - Alignment.End, - TextDirection.TopBottom_LeftRight, - @" -******* -******* -0****** - ****** -你***** - ****** -4******")] - [InlineData ( - "0 你 4", - Alignment.Start, - Alignment.Center, - TextDirection.TopBottom_LeftRight, - @" -******* -0****** - ****** -你***** - ****** -4****** -*******")] - [InlineData ( - "0 你 4", - Alignment.Start, - Alignment.Fill, - TextDirection.TopBottom_LeftRight, - @" -0****** - ****** - ****** -你***** - ****** - ****** -4******")] - - // TopBottom_RightLeft - [InlineData ( - "0 2 4", - Alignment.Start, - Alignment.Start, - TextDirection.TopBottom_RightLeft, - @" -0****** - ****** -2****** - ****** -4****** -******* -*******")] - [InlineData ( - "0 2 4", - Alignment.Start, - Alignment.End, - TextDirection.TopBottom_RightLeft, - @" -******* -******* -0****** - ****** -2****** - ****** -4******")] - [InlineData ( - "0 2 4", - Alignment.Start, - Alignment.Center, - TextDirection.TopBottom_RightLeft, - @" -******* -0****** - ****** -2****** - ****** -4****** -*******")] - [InlineData ( - "0 2 4", - Alignment.Start, - Alignment.Fill, - TextDirection.TopBottom_RightLeft, - @" -0****** - ****** - ****** -2****** - ****** - ****** -4******")] - [InlineData ( - "0 你 4", - Alignment.Start, - Alignment.Start, - TextDirection.TopBottom_RightLeft, - @" -0****** - ****** -你***** - ****** -4****** -******* -*******")] - [InlineData ( - "0 你 4", - Alignment.Start, - Alignment.End, - TextDirection.TopBottom_RightLeft, - @" -******* -******* -0****** - ****** -你***** - ****** -4******")] - [InlineData ( - "0 你 4", - Alignment.Start, - Alignment.Center, - TextDirection.TopBottom_RightLeft, - @" -******* -0****** - ****** -你***** - ****** -4****** -*******")] - [InlineData ( - "0 你 4", - Alignment.Start, - Alignment.Fill, - TextDirection.TopBottom_RightLeft, - @" -0****** - ****** - ****** -你***** - ****** - ****** -4******")] - - // BottomTop_LeftRight - [InlineData ( - "0 2 4", - Alignment.Start, - Alignment.Start, - TextDirection.BottomTop_LeftRight, - @" -4****** - ****** -2****** - ****** -0****** -******* -*******")] - [InlineData ( - "0 2 4", - Alignment.Start, - Alignment.End, - TextDirection.BottomTop_LeftRight, - @" -******* -******* -4****** - ****** -2****** - ****** -0******")] - [InlineData ( - "0 2 4", - Alignment.Start, - Alignment.Center, - TextDirection.BottomTop_LeftRight, - @" -******* -4****** - ****** -2****** - ****** -0****** -*******")] - [InlineData ( - "0 2 4", - Alignment.Start, - Alignment.Fill, - TextDirection.BottomTop_LeftRight, - @" -4****** - ****** - ****** -2****** - ****** - ****** -0******")] - [InlineData ( - "0 你 4", - Alignment.Start, - Alignment.Start, - TextDirection.BottomTop_LeftRight, - @" -4****** - ****** -你***** - ****** -0****** -******* -*******")] - [InlineData ( - "0 你 4", - Alignment.Start, - Alignment.End, - TextDirection.BottomTop_LeftRight, - @" -******* -******* -4****** - ****** -你***** - ****** -0******")] - [InlineData ( - "0 你 4", - Alignment.Start, - Alignment.Center, - TextDirection.BottomTop_LeftRight, - @" -******* -4****** - ****** -你***** - ****** -0****** -*******")] - [InlineData ( - "0 你 4", - Alignment.Start, - Alignment.Fill, - TextDirection.BottomTop_LeftRight, - @" -4****** - ****** - ****** -你***** - ****** - ****** -0******")] - - // BottomTop_RightLeft - [InlineData ( - "0 2 4", - Alignment.Start, - Alignment.Start, - TextDirection.BottomTop_RightLeft, - @" -4****** - ****** -2****** - ****** -0****** -******* -*******")] - [InlineData ( - "0 2 4", - Alignment.Start, - Alignment.End, - TextDirection.BottomTop_RightLeft, - @" -******* -******* -4****** - ****** -2****** - ****** -0******")] - [InlineData ( - "0 2 4", - Alignment.Start, - Alignment.Center, - TextDirection.BottomTop_RightLeft, - @" -******* -4****** - ****** -2****** - ****** -0****** -*******")] - [InlineData ( - "0 2 4", - Alignment.Start, - Alignment.Fill, - TextDirection.BottomTop_RightLeft, - @" -4****** - ****** - ****** -2****** - ****** - ****** -0******")] - [InlineData ( - "0 你 4", - Alignment.Start, - Alignment.Start, - TextDirection.BottomTop_RightLeft, - @" -4****** - ****** -你***** - ****** -0****** -******* -*******")] - [InlineData ( - "0 你 4", - Alignment.Start, - Alignment.End, - TextDirection.BottomTop_RightLeft, - @" -******* -******* -4****** - ****** -你***** - ****** -0******")] - [InlineData ( - "0 你 4", - Alignment.Start, - Alignment.Center, - TextDirection.BottomTop_RightLeft, - @" -******* -4****** - ****** -你***** - ****** -0****** -*******")] - [InlineData ( - "0 你 4", - Alignment.Start, - Alignment.Fill, - TextDirection.BottomTop_RightLeft, - @" -4****** - ****** - ****** -你***** - ****** - ****** -0******")] - - // Vertical with alignment.Right - // TopBottom_LeftRight - [InlineData ( - "0 2 4", - Alignment.End, - Alignment.Start, - TextDirection.TopBottom_LeftRight, - @" -******0 -****** -******2 -****** -******4 -******* -*******")] - [InlineData ( - "0 2 4", - Alignment.End, - Alignment.End, - TextDirection.TopBottom_LeftRight, - @" -******* -******* -******0 -****** -******2 -****** -******4")] - [InlineData ( - "0 2 4", - Alignment.End, - Alignment.Center, - TextDirection.TopBottom_LeftRight, - @" -******* -******0 -****** -******2 -****** -******4 -*******")] - [InlineData ( - "0 2 4", - Alignment.End, - Alignment.Fill, - TextDirection.TopBottom_LeftRight, - @" -******0 -****** -****** -******2 -****** -****** -******4")] - [InlineData ( - "0 你 4", - Alignment.End, - Alignment.Start, - TextDirection.TopBottom_LeftRight, - @" -*****0* -***** * -*****你 -***** * -*****4* -******* -*******")] - [InlineData ( - "0 你 4", - Alignment.End, - Alignment.End, - TextDirection.TopBottom_LeftRight, - @" -******* -******* -*****0* -***** * -*****你 -***** * -*****4*")] - [InlineData ( - "0 你 4", - Alignment.End, - Alignment.Center, - TextDirection.TopBottom_LeftRight, - @" -******* -*****0* -***** * -*****你 -***** * -*****4* -*******")] - [InlineData ( - "0 你 4", - Alignment.End, - Alignment.Fill, - TextDirection.TopBottom_LeftRight, - @" -*****0* -***** * -***** * -*****你 -***** * -***** * -*****4*")] - - // TopBottom_RightLeft - [InlineData ( - "0 2 4", - Alignment.End, - Alignment.Start, - TextDirection.TopBottom_RightLeft, - @" -******0 -****** -******2 -****** -******4 -******* -*******")] - [InlineData ( - "0 2 4", - Alignment.End, - Alignment.End, - TextDirection.TopBottom_RightLeft, - @" -******* -******* -******0 -****** -******2 -****** -******4")] - [InlineData ( - "0 2 4", - Alignment.End, - Alignment.Center, - TextDirection.TopBottom_RightLeft, - @" -******* -******0 -****** -******2 -****** -******4 -*******")] - [InlineData ( - "0 2 4", - Alignment.End, - Alignment.Fill, - TextDirection.TopBottom_RightLeft, - @" -******0 -****** -****** -******2 -****** -****** -******4")] - [InlineData ( - "0 你 4", - Alignment.End, - Alignment.Start, - TextDirection.TopBottom_RightLeft, - @" -*****0* -***** * -*****你 -***** * -*****4* -******* -*******")] - [InlineData ( - "0 你 4", - Alignment.End, - Alignment.End, - TextDirection.TopBottom_RightLeft, - @" -******* -******* -*****0* -***** * -*****你 -***** * -*****4*")] - [InlineData ( - "0 你 4", - Alignment.End, - Alignment.Center, - TextDirection.TopBottom_RightLeft, - @" -******* -*****0* -***** * -*****你 -***** * -*****4* -*******")] - [InlineData ( - "0 你 4", - Alignment.End, - Alignment.Fill, - TextDirection.TopBottom_RightLeft, - @" -*****0* -***** * -***** * -*****你 -***** * -***** * -*****4*")] - - // BottomTop_LeftRight - [InlineData ( - "0 2 4", - Alignment.End, - Alignment.Start, - TextDirection.BottomTop_LeftRight, - @" -******4 -****** -******2 -****** -******0 -******* -*******")] - [InlineData ( - "0 2 4", - Alignment.End, - Alignment.End, - TextDirection.BottomTop_LeftRight, - @" -******* -******* -******4 -****** -******2 -****** -******0")] - [InlineData ( - "0 2 4", - Alignment.End, - Alignment.Center, - TextDirection.BottomTop_LeftRight, - @" -******* -******4 -****** -******2 -****** -******0 -*******")] - [InlineData ( - "0 2 4", - Alignment.End, - Alignment.Fill, - TextDirection.BottomTop_LeftRight, - @" -******4 -****** -****** -******2 -****** -****** -******0")] - [InlineData ( - "0 你 4", - Alignment.End, - Alignment.Start, - TextDirection.BottomTop_LeftRight, - @" -*****4* -***** * -*****你 -***** * -*****0* -******* -*******")] - [InlineData ( - "0 你 4", - Alignment.End, - Alignment.End, - TextDirection.BottomTop_LeftRight, - @" -******* -******* -*****4* -***** * -*****你 -***** * -*****0*")] - [InlineData ( - "0 你 4", - Alignment.End, - Alignment.Center, - TextDirection.BottomTop_LeftRight, - @" -******* -*****4* -***** * -*****你 -***** * -*****0* -*******")] - [InlineData ( - "0 你 4", - Alignment.End, - Alignment.Fill, - TextDirection.BottomTop_LeftRight, - @" -*****4* -***** * -***** * -*****你 -***** * -***** * -*****0*")] - - // BottomTop_RightLeft - [InlineData ( - "0 2 4", - Alignment.End, - Alignment.Start, - TextDirection.BottomTop_RightLeft, - @" -******4 -****** -******2 -****** -******0 -******* -*******")] - [InlineData ( - "0 2 4", - Alignment.End, - Alignment.End, - TextDirection.BottomTop_RightLeft, - @" -******* -******* -******4 -****** -******2 -****** -******0")] - [InlineData ( - "0 2 4", - Alignment.End, - Alignment.Center, - TextDirection.BottomTop_RightLeft, - @" -******* -******4 -****** -******2 -****** -******0 -*******")] - [InlineData ( - "0 2 4", - Alignment.End, - Alignment.Fill, - TextDirection.BottomTop_RightLeft, - @" -******4 -****** -****** -******2 -****** -****** -******0")] - [InlineData ( - "0 你 4", - Alignment.End, - Alignment.Start, - TextDirection.BottomTop_RightLeft, - @" -*****4* -***** * -*****你 -***** * -*****0* -******* -*******")] - [InlineData ( - "0 你 4", - Alignment.End, - Alignment.End, - TextDirection.BottomTop_RightLeft, - @" -******* -******* -*****4* -***** * -*****你 -***** * -*****0*")] - [InlineData ( - "0 你 4", - Alignment.End, - Alignment.Center, - TextDirection.BottomTop_RightLeft, - @" -******* -*****4* -***** * -*****你 -***** * -*****0* -*******")] - [InlineData ( - "0 你 4", - Alignment.End, - Alignment.Fill, - TextDirection.BottomTop_RightLeft, - @" -*****4* -***** * -***** * -*****你 -***** * -***** * -*****0*")] - - // Vertical with alignment.Centered - // TopBottom_LeftRight - [InlineData ( - "0 2 4", - Alignment.Center, - Alignment.Start, - TextDirection.TopBottom_LeftRight, - @" -***0*** -*** *** -***2*** -*** *** -***4*** -******* -*******")] - [InlineData ( - "0 2 4", - Alignment.Center, - Alignment.End, - TextDirection.TopBottom_LeftRight, - @" -******* -******* -***0*** -*** *** -***2*** -*** *** -***4***")] - [InlineData ( - "0 2 4", - Alignment.Center, - Alignment.Center, - TextDirection.TopBottom_LeftRight, - @" -******* -***0*** -*** *** -***2*** -*** *** -***4*** -*******")] - [InlineData ( - "0 2 4", - Alignment.Center, - Alignment.Fill, - TextDirection.TopBottom_LeftRight, - @" -***0*** -*** *** -*** *** -***2*** -*** *** -*** *** -***4***")] - [InlineData ( - "0 你 4", - Alignment.Center, - Alignment.Start, - TextDirection.TopBottom_LeftRight, - @" -**0**** -** **** -**你*** -** **** -**4**** -******* -*******")] - [InlineData ( - "0 你 4", - Alignment.Center, - Alignment.End, - TextDirection.TopBottom_LeftRight, - @" -******* -******* -**0**** -** **** -**你*** -** **** -**4****")] - [InlineData ( - "0 你 4", - Alignment.Center, - Alignment.Center, - TextDirection.TopBottom_LeftRight, - @" -******* -**0**** -** **** -**你*** -** **** -**4**** -*******")] - [InlineData ( - "0 你 4", - Alignment.Center, - Alignment.Fill, - TextDirection.TopBottom_LeftRight, - @" -**0**** -** **** -** **** -**你*** -** **** -** **** -**4****")] - - // TopBottom_RightLeft - [InlineData ( - "0 2 4", - Alignment.Center, - Alignment.Start, - TextDirection.TopBottom_RightLeft, - @" -***0*** -*** *** -***2*** -*** *** -***4*** -******* -*******")] - [InlineData ( - "0 2 4", - Alignment.Center, - Alignment.End, - TextDirection.TopBottom_RightLeft, - @" -******* -******* -***0*** -*** *** -***2*** -*** *** -***4***")] - [InlineData ( - "0 2 4", - Alignment.Center, - Alignment.Center, - TextDirection.TopBottom_RightLeft, - @" -******* -***0*** -*** *** -***2*** -*** *** -***4*** -*******")] - [InlineData ( - "0 2 4", - Alignment.Center, - Alignment.Fill, - TextDirection.TopBottom_RightLeft, - @" -***0*** -*** *** -*** *** -***2*** -*** *** -*** *** -***4***")] - [InlineData ( - "0 你 4", - Alignment.Center, - Alignment.Start, - TextDirection.TopBottom_RightLeft, - @" -**0**** -** **** -**你*** -** **** -**4**** -******* -*******")] - [InlineData ( - "0 你 4", - Alignment.Center, - Alignment.End, - TextDirection.TopBottom_RightLeft, - @" -******* -******* -**0**** -** **** -**你*** -** **** -**4****")] - [InlineData ( - "0 你 4", - Alignment.Center, - Alignment.Center, - TextDirection.TopBottom_RightLeft, - @" -******* -**0**** -** **** -**你*** -** **** -**4**** -*******")] - [InlineData ( - "0 你 4", - Alignment.Center, - Alignment.Fill, - TextDirection.TopBottom_RightLeft, - @" -**0**** -** **** -** **** -**你*** -** **** -** **** -**4****")] - - // BottomTop_LeftRight - [InlineData ( - "0 2 4", - Alignment.Center, - Alignment.Start, - TextDirection.BottomTop_LeftRight, - @" -***4*** -*** *** -***2*** -*** *** -***0*** -******* -*******")] - [InlineData ( - "0 2 4", - Alignment.Center, - Alignment.End, - TextDirection.BottomTop_LeftRight, - @" -******* -******* -***4*** -*** *** -***2*** -*** *** -***0***")] - [InlineData ( - "0 2 4", - Alignment.Center, - Alignment.Center, - TextDirection.BottomTop_LeftRight, - @" -******* -***4*** -*** *** -***2*** -*** *** -***0*** -*******")] - [InlineData ( - "0 2 4", - Alignment.Center, - Alignment.Fill, - TextDirection.BottomTop_LeftRight, - @" -***4*** -*** *** -*** *** -***2*** -*** *** -*** *** -***0***")] - [InlineData ( - "0 你 4", - Alignment.Center, - Alignment.Start, - TextDirection.BottomTop_LeftRight, - @" -**4**** -** **** -**你*** -** **** -**0**** -******* -*******")] - [InlineData ( - "0 你 4", - Alignment.Center, - Alignment.End, - TextDirection.BottomTop_LeftRight, - @" -******* -******* -**4**** -** **** -**你*** -** **** -**0****")] - [InlineData ( - "0 你 4", - Alignment.Center, - Alignment.Center, - TextDirection.BottomTop_LeftRight, - @" -******* -**4**** -** **** -**你*** -** **** -**0**** -*******")] - [InlineData ( - "0 你 4", - Alignment.Center, - Alignment.Fill, - TextDirection.BottomTop_LeftRight, - @" -**4**** -** **** -** **** -**你*** -** **** -** **** -**0****")] - - // BottomTop_RightLeft - [InlineData ( - "0 2 4", - Alignment.Center, - Alignment.Start, - TextDirection.BottomTop_RightLeft, - @" -***4*** -*** *** -***2*** -*** *** -***0*** -******* -*******")] - [InlineData ( - "0 2 4", - Alignment.Center, - Alignment.End, - TextDirection.BottomTop_RightLeft, - @" -******* -******* -***4*** -*** *** -***2*** -*** *** -***0***")] - [InlineData ( - "0 2 4", - Alignment.Center, - Alignment.Center, - TextDirection.BottomTop_RightLeft, - @" -******* -***4*** -*** *** -***2*** -*** *** -***0*** -*******")] - [InlineData ( - "0 2 4", - Alignment.Center, - Alignment.Fill, - TextDirection.BottomTop_RightLeft, - @" -***4*** -*** *** -*** *** -***2*** -*** *** -*** *** -***0***")] - [InlineData ( - "0 你 4", - Alignment.Center, - Alignment.Start, - TextDirection.BottomTop_RightLeft, - @" -**4**** -** **** -**你*** -** **** -**0**** -******* -*******")] - [InlineData ( - "0 你 4", - Alignment.Center, - Alignment.End, - TextDirection.BottomTop_RightLeft, - @" -******* -******* -**4**** -** **** -**你*** -** **** -**0****")] - [InlineData ( - "0 你 4", - Alignment.Center, - Alignment.Center, - TextDirection.BottomTop_RightLeft, - @" -******* -**4**** -** **** -**你*** -** **** -**0**** -*******")] - [InlineData ( - "0 你 4", - Alignment.Center, - Alignment.Fill, - TextDirection.BottomTop_RightLeft, - @" -**4**** -** **** -** **** -**你*** -** **** -** **** -**0****")] - - // Vertical with alignment.Justified - // TopBottom_LeftRight - [InlineData ( - "0 2 4", - Alignment.Fill, - Alignment.Start, - TextDirection.TopBottom_LeftRight, - @" -0****** - ****** -2****** - ****** -4****** -******* -*******")] - [InlineData ( - "0 2 4", - Alignment.Fill, - Alignment.End, - TextDirection.TopBottom_LeftRight, - @" -******* -******* -0****** - ****** -2****** - ****** -4******")] - [InlineData ( - "0 2 4", - Alignment.Fill, - Alignment.Center, - TextDirection.TopBottom_LeftRight, - @" -******* -0****** - ****** -2****** - ****** -4****** -*******")] - [InlineData ( - "0 2 4", - Alignment.Fill, - Alignment.Fill, - TextDirection.TopBottom_LeftRight, - @" -0****** - ****** - ****** -2****** - ****** - ****** -4******")] - [InlineData ( - "0 你 4", - Alignment.Fill, - Alignment.Start, - TextDirection.TopBottom_LeftRight, - @" -0****** - ****** -你***** - ****** -4****** -******* -*******")] - [InlineData ( - "0 你 4", - Alignment.Fill, - Alignment.End, - TextDirection.TopBottom_LeftRight, - @" -******* -******* -0****** - ****** -你***** - ****** -4******")] - [InlineData ( - "0 你 4", - Alignment.Fill, - Alignment.Center, - TextDirection.TopBottom_LeftRight, - @" -******* -0****** - ****** -你***** - ****** -4****** -*******")] - [InlineData ( - "0 你 4", - Alignment.Fill, - Alignment.Fill, - TextDirection.TopBottom_LeftRight, - @" -0****** - ****** - ****** -你***** - ****** - ****** -4******")] - - // TopBottom_RightLeft - [InlineData ( - "0 2 4", - Alignment.Fill, - Alignment.Start, - TextDirection.TopBottom_RightLeft, - @" -0****** - ****** -2****** - ****** -4****** -******* -*******")] - [InlineData ( - "0 2 4", - Alignment.Fill, - Alignment.End, - TextDirection.TopBottom_RightLeft, - @" -******* -******* -0****** - ****** -2****** - ****** -4******")] - [InlineData ( - "0 2 4", - Alignment.Fill, - Alignment.Center, - TextDirection.TopBottom_RightLeft, - @" -******* -0****** - ****** -2****** - ****** -4****** -*******")] - [InlineData ( - "0 2 4", - Alignment.Fill, - Alignment.Fill, - TextDirection.TopBottom_RightLeft, - @" -0****** - ****** - ****** -2****** - ****** - ****** -4******")] - [InlineData ( - "0 你 4", - Alignment.Fill, - Alignment.Start, - TextDirection.TopBottom_RightLeft, - @" -0****** - ****** -你***** - ****** -4****** -******* -*******")] - [InlineData ( - "0 你 4", - Alignment.Fill, - Alignment.End, - TextDirection.TopBottom_RightLeft, - @" -******* -******* -0****** - ****** -你***** - ****** -4******")] - [InlineData ( - "0 你 4", - Alignment.Fill, - Alignment.Center, - TextDirection.TopBottom_RightLeft, - @" -******* -0****** - ****** -你***** - ****** -4****** -*******")] - [InlineData ( - "0 你 4", - Alignment.Fill, - Alignment.Fill, - TextDirection.TopBottom_RightLeft, - @" -0****** - ****** - ****** -你***** - ****** - ****** -4******")] - - // BottomTop_LeftRight - [InlineData ( - "0 2 4", - Alignment.Fill, - Alignment.Start, - TextDirection.BottomTop_LeftRight, - @" -4****** - ****** -2****** - ****** -0****** -******* -*******")] - [InlineData ( - "0 2 4", - Alignment.Fill, - Alignment.End, - TextDirection.BottomTop_LeftRight, - @" -******* -******* -4****** - ****** -2****** - ****** -0******")] - [InlineData ( - "0 2 4", - Alignment.Fill, - Alignment.Center, - TextDirection.BottomTop_LeftRight, - @" -******* -4****** - ****** -2****** - ****** -0****** -*******")] - [InlineData ( - "0 2 4", - Alignment.Fill, - Alignment.Fill, - TextDirection.BottomTop_LeftRight, - @" -4****** - ****** - ****** -2****** - ****** - ****** -0******")] - [InlineData ( - "0 你 4", - Alignment.Fill, - Alignment.Start, - TextDirection.BottomTop_LeftRight, - @" -4****** - ****** -你***** - ****** -0****** -******* -*******")] - [InlineData ( - "0 你 4", - Alignment.Fill, - Alignment.End, - TextDirection.BottomTop_LeftRight, - @" -******* -******* -4****** - ****** -你***** - ****** -0******")] - [InlineData ( - "0 你 4", - Alignment.Fill, - Alignment.Center, - TextDirection.BottomTop_LeftRight, - @" -******* -4****** - ****** -你***** - ****** -0****** -*******")] - [InlineData ( - "0 你 4", - Alignment.Fill, - Alignment.Fill, - TextDirection.BottomTop_LeftRight, - @" -4****** - ****** - ****** -你***** - ****** - ****** -0******")] - - // BottomTop_RightLeft - [InlineData ( - "0 2 4", - Alignment.Fill, - Alignment.Start, - TextDirection.BottomTop_RightLeft, - @" -4****** - ****** -2****** - ****** -0****** -******* -*******")] - [InlineData ( - "0 2 4", - Alignment.Fill, - Alignment.End, - TextDirection.BottomTop_RightLeft, - @" -******* -******* -4****** - ****** -2****** - ****** -0******")] - [InlineData ( - "0 2 4", - Alignment.Fill, - Alignment.Center, - TextDirection.BottomTop_RightLeft, - @" -******* -4****** - ****** -2****** - ****** -0****** -*******")] - [InlineData ( - "0 2 4", - Alignment.Fill, - Alignment.Fill, - TextDirection.BottomTop_RightLeft, - @" -4****** - ****** - ****** -2****** - ****** - ****** -0******")] - [InlineData ( - "0 你 4", - Alignment.Fill, - Alignment.Start, - TextDirection.BottomTop_RightLeft, - @" -4****** - ****** -你***** - ****** -0****** -******* -*******")] - [InlineData ( - "0 你 4", - Alignment.Fill, - Alignment.End, - TextDirection.BottomTop_RightLeft, - @" -******* -******* -4****** - ****** -你***** - ****** -0******")] - [InlineData ( - "0 你 4", - Alignment.Fill, - Alignment.Center, - TextDirection.BottomTop_RightLeft, - @" -******* -4****** - ****** -你***** - ****** -0****** -*******")] - [InlineData ( - "0 你 4", - Alignment.Fill, - Alignment.Fill, - TextDirection.BottomTop_RightLeft, - @" -4****** - ****** - ****** -你***** - ****** - ****** -0******")] - public void Draw_Text_Justification (string text, Alignment horizontalTextAlignment, Alignment alignment, TextDirection textDirection, string expectedText) - { - TextFormatter tf = new () - { - Alignment = horizontalTextAlignment, - VerticalAlignment = alignment, - Direction = textDirection, - ConstrainToSize = new (7, 7), - Text = text - }; - - Application.Driver?.FillRect (new (0, 0, 7, 7), (Rune)'*'); - tf.Draw (new (0, 0, 7, 7), Attribute.Default, Attribute.Default); - TestHelpers.AssertDriverContentsWithFrameAre (expectedText, _output); - } - - [SetupFakeDriver] - [Theory] - [InlineData ("A", 0, 1, "", 0)] - [InlineData ("A", 1, 1, "A", 0)] - [InlineData ("A", 2, 2, " A", 1)] - [InlineData ("AB", 1, 1, "B", 0)] - [InlineData ("AB", 2, 2, " A\n B", 0)] - [InlineData ("ABC", 3, 2, " B\n C", 0)] - [InlineData ("ABC", 4, 2, " B\n C", 0)] - [InlineData ("ABC", 6, 2, " B\n C", 0)] - [InlineData ("こんにちは", 0, 1, "", 0)] - [InlineData ("こんにちは", 1, 0, "", 0)] - [InlineData ("こんにちは", 1, 1, "", 0)] - [InlineData ("こんにちは", 2, 1, "は", 0)] - [InlineData ("こんにちは", 2, 2, "ち\nは", 0)] - [InlineData ("こんにちは", 2, 3, "に\nち\nは", 0)] - [InlineData ("こんにちは", 2, 4, "ん\nに\nち\nは", 0)] - [InlineData ("こんにちは", 2, 5, "こ\nん\nに\nち\nは", 0)] - [InlineData ("こんにちは", 2, 6, "こ\nん\nに\nち\nは", 1)] - [InlineData ("ABCD\nこんにちは", 4, 7, " こ\n Aん\n Bに\n Cち\n Dは", 2)] - [InlineData ("こんにちは\nABCD", 3, 7, "こ \nんA\nにB\nちC\nはD", 2)] - public void Draw_Vertical_Bottom_Horizontal_Right (string text, int width, int height, string expectedText, int expectedY) - { - TextFormatter tf = new () - { - Text = text, - Alignment = Alignment.End, - Direction = TextDirection.TopBottom_LeftRight, - VerticalAlignment = Alignment.End - }; - - tf.ConstrainToWidth = width; - tf.ConstrainToHeight = height; - - tf.Draw (new (Point.Empty, new (width, height)), Attribute.Default, Attribute.Default); - Rectangle rect = TestHelpers.AssertDriverContentsWithFrameAre (expectedText, _output); - Assert.Equal (expectedY, rect.Y); - } - - [SetupFakeDriver] - [Theory] - [InlineData ("A", 1, 0, "")] - [InlineData ("A", 0, 1, "")] - [InlineData ("AB1 2", 1, 2, "2")] - [InlineData ("AB12", 1, 5, "2\n1\nB\nA")] - [InlineData ("AB\n12", 2, 5, "B2\nA1")] - [InlineData ("ABC 123 456", 2, 7, "6C\n5B\n4A\n \n3 \n2 \n1 ")] - [InlineData ("こんにちは", 1, 1, "")] - [InlineData ("こんにちは", 2, 1, "は")] - [InlineData ("こんにちは", 2, 5, "は\nち\nに\nん\nこ")] - [InlineData ("こんにちは", 2, 10, "は\nち\nに\nん\nこ")] - [InlineData ("こんにちは\nAB\n12", 4, 10, "はB2\nちA1\nに \nん \nこ ")] - public void Draw_Vertical_BottomTop_LeftRight (string text, int width, int height, string expectedText) - { - TextFormatter tf = new () - { - Text = text, - Direction = TextDirection.BottomTop_LeftRight - }; - - tf.ConstrainToWidth = width; - tf.ConstrainToHeight = height; - tf.Draw (new (0, 0, width, height), Attribute.Default, Attribute.Default); - - TestHelpers.AssertDriverContentsWithFrameAre (expectedText, _output); - } - - [SetupFakeDriver] - [Theory] - [InlineData ("A", 1, 0, "")] - [InlineData ("A", 0, 1, "")] - [InlineData ("AB1 2", 1, 2, "2")] - [InlineData ("AB12", 1, 5, "2\n1\nB\nA")] - [InlineData ("AB\n12", 2, 5, "2B\n1A")] - [InlineData ("ABC 123 456", 2, 7, "C6\nB5\nA4\n \n 3\n 2\n 1")] - [InlineData ("こんにちは", 1, 1, "")] - [InlineData ("こんにちは", 2, 1, "は")] - [InlineData ("こんにちは", 2, 5, "は\nち\nに\nん\nこ")] - [InlineData ("こんにちは", 2, 10, "は\nち\nに\nん\nこ")] - [InlineData ("こんにちは\nAB\n12", 4, 10, "2Bは\n1Aち\n に\n ん\n こ")] - public void Draw_Vertical_BottomTop_RightLeft (string text, int width, int height, string expectedText) - { - TextFormatter tf = new () - { - Text = text, - Direction = TextDirection.BottomTop_RightLeft - }; - - tf.ConstrainToWidth = width; - tf.ConstrainToHeight = height; - tf.Draw (new (0, 0, width, height), Attribute.Default, Attribute.Default); - - TestHelpers.AssertDriverContentsWithFrameAre (expectedText, _output); - } - - // Draw tests - Note that these depend on View - - [Fact] - [TestRespondersDisposed] - public void Draw_Vertical_Throws_IndexOutOfRangeException_With_Negative_Bounds () - { - Application.Init (new FakeDriver ()); - Dialog.DefaultShadow = ShadowStyle.None; - Button.DefaultShadow = ShadowStyle.None; - - Toplevel top = new (); - - var view = new View { Y = -2, Height = 10, TextDirection = TextDirection.TopBottom_LeftRight, Text = "view" }; - top.Add (view); - - Application.Iteration += (s, a) => - { - Assert.Equal (-2, view.Y); - - Application.RequestStop (); - }; - - try - { - Application.Run (top); - } - catch (IndexOutOfRangeException ex) - { - // After the fix this exception will not be caught. - Assert.IsType (ex); - } - - top.Dispose (); - - // Shutdown must be called to safely clean up Application if Init has been called - Application.Shutdown (); - } - - [SetupFakeDriver] - [Theory] - [InlineData ("A", 5, 5, "A")] - [InlineData ( - "AB12", - 5, - 5, - @" -A -B -1 -2")] - [InlineData ( - "AB\n12", - 5, - 5, - @" -A1 -B2")] - [InlineData ("", 5, 1, "")] - [InlineData ( - "Hello Worlds", - 1, - 12, - @" -H -e -l -l -o - -W -o -r -l -d -s")] - [InlineData ("Hello Worlds", 12, 1, @"HelloWorlds")] - public void Draw_Vertical_TopBottom_LeftRight (string text, int width, int height, string expectedText) - { - TextFormatter tf = new () - { - Text = text, - Direction = TextDirection.TopBottom_LeftRight - }; - - tf.ConstrainToWidth = width; - tf.ConstrainToHeight = height; - tf.Draw (new (0, 0, 20, 20), Attribute.Default, Attribute.Default); - - TestHelpers.AssertDriverContentsWithFrameAre (expectedText, _output); - } - - [SetupFakeDriver] - [Theory] - - // The expectedY param is to probe that the expectedText param start at that Y coordinate - [InlineData ("A", 0, "", 0)] - [InlineData ("A", 1, "A", 0)] - [InlineData ("A", 2, "A", 0)] - [InlineData ("A", 3, "A", 1)] - [InlineData ("AB", 1, "A", 0)] - [InlineData ("AB", 2, "A\nB", 0)] - [InlineData ("ABC", 2, "A\nB", 0)] - [InlineData ("ABC", 3, "A\nB\nC", 0)] - [InlineData ("ABC", 4, "A\nB\nC", 0)] - [InlineData ("ABC", 5, "A\nB\nC", 1)] - [InlineData ("ABC", 6, "A\nB\nC", 1)] - [InlineData ("ABC", 9, "A\nB\nC", 3)] - [InlineData ("ABCD", 2, "B\nC", 0)] - [InlineData ("こんにちは", 0, "", 0)] - [InlineData ("こんにちは", 1, "に", 0)] - [InlineData ("こんにちは", 2, "ん\nに", 0)] - [InlineData ("こんにちは", 3, "ん\nに\nち", 0)] - [InlineData ("こんにちは", 4, "こ\nん\nに\nち", 0)] - [InlineData ("こんにちは", 5, "こ\nん\nに\nち\nは", 0)] - [InlineData ("こんにちは", 6, "こ\nん\nに\nち\nは", 0)] - [InlineData ("ABCD\nこんにちは", 7, "Aこ\nBん\nCに\nDち\n は", 1)] - [InlineData ("こんにちは\nABCD", 7, "こA\nんB\nにC\nちD\nは ", 1)] - public void Draw_Vertical_TopBottom_LeftRight_Middle (string text, int height, string expectedText, int expectedY) - { - TextFormatter tf = new () - { - Text = text, - Direction = TextDirection.TopBottom_LeftRight, - VerticalAlignment = Alignment.Center - }; - - int width = text.ToRunes ().Max (r => r.GetColumns ()); - - if (text.Contains ("\n")) - { - width++; - } - - tf.ConstrainToWidth = width; - tf.ConstrainToHeight = height; - tf.Draw (new (0, 0, 5, height), Attribute.Default, Attribute.Default); - - Rectangle rect = TestHelpers.AssertDriverContentsWithFrameAre (expectedText, _output); - Assert.Equal (expectedY, rect.Y); - } - - [SetupFakeDriver] - [Theory] - [InlineData ("A", 5, "A")] - [InlineData ( - "AB12", - 5, - @" -A -B -1 -2")] - [InlineData ( - "AB\n12", - 5, - @" -A1 -B2")] - [InlineData ("", 1, "")] - [InlineData ( - "AB1 2", - 2, - @" -A12 -B ")] - [InlineData ( - "こんにちは", - 1, - @" -こん")] - [InlineData ( - "こんにちは", - 2, - @" -こに -んち")] - [InlineData ( - "こんにちは", - 5, - @" -こ -ん -に -ち -は")] - public void Draw_Vertical_TopBottom_LeftRight_Top (string text, int height, string expectedText) - { - TextFormatter tf = new () - { - Text = text, - Direction = TextDirection.TopBottom_LeftRight - }; - - tf.ConstrainToWidth = 5; - tf.ConstrainToHeight = height; - tf.Draw (new (0, 0, 5, height), Attribute.Default, Attribute.Default); - - TestHelpers.AssertDriverContentsWithFrameAre (expectedText, _output); - } - - [Theory] - [InlineData (14, 1, TextDirection.LeftRight_TopBottom, "Les Misęrables")] - [InlineData (1, 14, TextDirection.TopBottom_LeftRight, "L\ne\ns\n \nM\ni\ns\nę\nr\na\nb\nl\ne\ns")] - [InlineData ( - 4, - 4, - TextDirection.TopBottom_LeftRight, - @" -LMre -eias -ssb - ęl " - )] - public void Draw_With_Combining_Runes (int width, int height, TextDirection textDirection, string expected) - { - var driver = new FakeDriver (); - driver.Init (); - - var text = "Les Mise\u0328\u0301rables"; - - var tf = new TextFormatter (); - tf.Direction = textDirection; - tf.Text = text; - - Assert.True (tf.WordWrap); - - tf.ConstrainToSize = new (width, height); - - tf.Draw ( - new (0, 0, width, height), - new (ColorName16.White, ColorName16.Black), - new (ColorName16.Blue, ColorName16.Black), - default (Rectangle), - driver - ); - TestHelpers.AssertDriverContentsWithFrameAre (expected, _output, driver); - - driver.End (); - } - - [Fact] - [SetupFakeDriver] - public void FillRemaining_True_False () - { - ((FakeDriver)Application.Driver!).SetBufferSize (22, 5); - - Attribute [] attrs = - { - Attribute.Default, new (ColorName16.Green, ColorName16.BrightMagenta), - new (ColorName16.Blue, ColorName16.Cyan) - }; - var tf = new TextFormatter { ConstrainToSize = new (14, 3), Text = "Test\nTest long\nTest long long\n", MultiLine = true }; - - tf.Draw ( - new (1, 1, 19, 3), - attrs [1], - attrs [2]); - - Assert.False (tf.FillRemaining); - - TestHelpers.AssertDriverContentsWithFrameAre ( - @" - Test - Test long - Test long long", - _output); - - TestHelpers.AssertDriverAttributesAre ( - @" -000000000000000000000 -011110000000000000000 -011111111100000000000 -011111111111111000000 -000000000000000000000", - _output, - null, - attrs); - - tf.FillRemaining = true; - - tf.Draw ( - new (1, 1, 19, 3), - attrs [1], - attrs [2]); - - TestHelpers.AssertDriverAttributesAre ( - @" -000000000000000000000 -011111111111111111110 -011111111111111111110 -011111111111111111110 -000000000000000000000", - _output, - null, - attrs); - } [Theory] [InlineData ("_k Before", true, 0, (KeyCode)'K')] // lower case should return uppercase Hotkey @@ -4835,39 +862,6 @@ ssb Assert.Equal (KeyCode.CtrlMask | KeyCode.Q, tf.HotKey); } - [SetupFakeDriver] - [Theory] - [InlineData ("Hello World", 15, 1, "Hello World")] - [InlineData ( - "Well Done\nNice Work", - 15, - 2, - @" -Well Done -Nice Work")] - [InlineData ("你好 世界", 15, 1, "你好 世界")] - [InlineData ( - "做 得好\n幹 得好", - 15, - 2, - @" -做 得好 -幹 得好")] - public void Justify_Horizontal (string text, int width, int height, string expectedText) - { - TextFormatter tf = new () - { - Text = text, - Alignment = Alignment.Fill, - ConstrainToSize = new Size (width, height), - MultiLine = true - }; - - tf.Draw (new (0, 0, width, height), Attribute.Default, Attribute.Default); - - TestHelpers.AssertDriverContentsWithFrameAre (expectedText, _output); - } - [Theory] [InlineData ("")] [InlineData (null)] @@ -4975,66 +969,6 @@ Nice Work")] Assert.Equal (justifiedText, TextFormatter.Justify (text, width, fillChar)); } - [SetupFakeDriver] - [Theory] - [InlineData ("Hello World", 1, 15, "H\ne\nl\nl\no\n \n \n \n \n \nW\no\nr\nl\nd")] - [InlineData ( - "Well Done\nNice Work", - 2, - 15, - @" -WN -ei -lc -le - - - - - - - -DW -oo -nr -ek")] - [InlineData ("你好 世界", 2, 15, "你\n好\n \n \n \n \n \n \n \n \n \n \n \n世\n界")] - [InlineData ( - "做 得好\n幹 得好", - 4, - 15, - @" -做幹 - - - - - - - - - - - - -得得 -好好")] - public void Justify_Vertical (string text, int width, int height, string expectedText) - { - TextFormatter tf = new () - { - Text = text, - Direction = TextDirection.TopBottom_LeftRight, - VerticalAlignment = Alignment.Fill, - ConstrainToSize = new Size (width, height), - MultiLine = true - }; - - tf.Draw (new (0, 0, width, height), Attribute.Default, Attribute.Default); - - TestHelpers.AssertDriverContentsWithFrameAre (expectedText, _output); - } - [Theory] [InlineData ("Single Line 界", 14)] [InlineData ("First Line 界\nSecond Line 界\nThird Line 界\n", 14)] @@ -6022,124 +1956,6 @@ ek")] } } - [Theory] - [InlineData (17, 1, TextDirection.LeftRight_TopBottom, 4, "This is a Tab")] - [InlineData (1, 17, TextDirection.TopBottom_LeftRight, 4, "T\nh\ni\ns\n \ni\ns\n \na\n \n \n \n \n \nT\na\nb")] - [InlineData (13, 1, TextDirection.LeftRight_TopBottom, 0, "This is a Tab")] - [InlineData (1, 13, TextDirection.TopBottom_LeftRight, 0, "T\nh\ni\ns\n \ni\ns\n \na\n \nT\na\nb")] - public void TabWith_PreserveTrailingSpaces_False ( - int width, - int height, - TextDirection textDirection, - int tabWidth, - string expected - ) - { - var driver = new FakeDriver (); - driver.Init (); - - var text = "This is a \tTab"; - var tf = new TextFormatter (); - tf.Direction = textDirection; - tf.TabWidth = tabWidth; - tf.Text = text; - tf.ConstrainToWidth = 20; - tf.ConstrainToHeight = 20; - - Assert.True (tf.WordWrap); - Assert.False (tf.PreserveTrailingSpaces); - - tf.Draw ( - new (0, 0, width, height), - new (ColorName16.White, ColorName16.Black), - new (ColorName16.Blue, ColorName16.Black), - default (Rectangle), - driver - ); - TestHelpers.AssertDriverContentsWithFrameAre (expected, _output, driver); - - driver.End (); - } - - [Theory] - [InlineData (17, 1, TextDirection.LeftRight_TopBottom, 4, "This is a Tab")] - [InlineData (1, 17, TextDirection.TopBottom_LeftRight, 4, "T\nh\ni\ns\n \ni\ns\n \na\n \n \n \n \n \nT\na\nb")] - [InlineData (13, 1, TextDirection.LeftRight_TopBottom, 0, "This is a Tab")] - [InlineData (1, 13, TextDirection.TopBottom_LeftRight, 0, "T\nh\ni\ns\n \ni\ns\n \na\n \nT\na\nb")] - public void TabWith_PreserveTrailingSpaces_True ( - int width, - int height, - TextDirection textDirection, - int tabWidth, - string expected - ) - { - var driver = new FakeDriver (); - driver.Init (); - - var text = "This is a \tTab"; - var tf = new TextFormatter (); - - tf.Direction = textDirection; - tf.TabWidth = tabWidth; - tf.PreserveTrailingSpaces = true; - tf.Text = text; - tf.ConstrainToWidth = 20; - tf.ConstrainToHeight = 20; - - Assert.True (tf.WordWrap); - - tf.Draw ( - new (0, 0, width, height), - new (ColorName16.White, ColorName16.Black), - new (ColorName16.Blue, ColorName16.Black), - default (Rectangle), - driver - ); - TestHelpers.AssertDriverContentsWithFrameAre (expected, _output, driver); - - driver.End (); - } - - [Theory] - [InlineData (17, 1, TextDirection.LeftRight_TopBottom, 4, "This is a Tab")] - [InlineData (1, 17, TextDirection.TopBottom_LeftRight, 4, "T\nh\ni\ns\n \ni\ns\n \na\n \n \n \n \n \nT\na\nb")] - [InlineData (13, 1, TextDirection.LeftRight_TopBottom, 0, "This is a Tab")] - [InlineData (1, 13, TextDirection.TopBottom_LeftRight, 0, "T\nh\ni\ns\n \ni\ns\n \na\n \nT\na\nb")] - public void TabWith_WordWrap_True ( - int width, - int height, - TextDirection textDirection, - int tabWidth, - string expected - ) - { - var driver = new FakeDriver (); - driver.Init (); - - var text = "This is a \tTab"; - var tf = new TextFormatter (); - - tf.Direction = textDirection; - tf.TabWidth = tabWidth; - tf.WordWrap = true; - tf.Text = text; - tf.ConstrainToWidth = 20; - tf.ConstrainToHeight = 20; - - Assert.False (tf.PreserveTrailingSpaces); - - tf.Draw ( - new (0, 0, width, height), - new (ColorName16.White, ColorName16.Black), - new (ColorName16.Blue, ColorName16.Black), - default (Rectangle), - driver - ); - TestHelpers.AssertDriverContentsWithFrameAre (expected, _output, driver); - - driver.End (); - } [Theory] [InlineData ("123456789", 3, "123")] @@ -6173,47 +1989,6 @@ ek")] Assert.Equal (new (expectedWidth, expectedHeight), tf.FormatAndGetSize ()); } - [Fact] - [SetupFakeDriver] - public void UICatalog_AboutBox_Text () - { - TextFormatter tf = new () - { - Text = UICatalogApp.GetAboutBoxMessage (), - Alignment = Alignment.Center, - VerticalAlignment = Alignment.Start, - WordWrap = false, - MultiLine = true, - HotKeySpecifier = (Rune)0xFFFF - }; - - Size tfSize = tf.FormatAndGetSize (); - Assert.Equal (new (59, 13), tfSize); - - ((FakeDriver)Application.Driver).SetBufferSize (tfSize.Width, tfSize.Height); - - Application.Driver.FillRect (Application.Screen, (Rune)'*'); - tf.Draw (Application.Screen, Attribute.Default, Attribute.Default); - - var expectedText = """ - UI Catalog: A comprehensive sample library and test app for - *********************************************************** - _______ _ _ _____ _ * - |__ __| (_) | | / ____| (_)* - | | ___ _ __ _ __ ___ _ _ __ __ _| || | __ _ _ _ * - | |/ _ \ '__| '_ ` _ \| | '_ \ / _` | || | |_ | | | | |* - | | __/ | | | | | | | | | | | (_| | || |__| | |_| | |* - |_|\___|_| |_| |_| |_|_|_| |_|\__,_|_(_)_____|\__,_|_|* - *********************************************************** - **********************v2 - Pre-Alpha*********************** - *********************************************************** - **********https://github.com/gui-cs/Terminal.Gui*********** - *********************************************************** - """; - - TestHelpers.AssertDriverContentsAre (expectedText.ReplaceLineEndings (), _output); - } - [Fact] public void WordWrap_BigWidth () { @@ -7111,199 +2886,4 @@ ek")] Assert.Equal (resultLines, wrappedLines); } - #region FormatAndGetSizeTests - - // TODO: Add multi-line examples - // TODO: Add other TextDirection examples - - [Theory] - [SetupFakeDriver] - [InlineData ("界1234", 10, 10, TextDirection.LeftRight_TopBottom, 6, 1, @"界1234")] - [InlineData ("01234", 10, 10, TextDirection.LeftRight_TopBottom, 5, 1, @"01234")] - [InlineData ( - "界1234", - 10, - 10, - TextDirection.TopBottom_LeftRight, - 2, - 5, - """ - 界 - 1 - 2 - 3 - 4 - """)] - [InlineData ( - "01234", - 10, - 10, - TextDirection.TopBottom_LeftRight, - 1, - 5, - """ - 0 - 1 - 2 - 3 - 4 - """)] - [InlineData ( - "界1234", - 3, - 3, - TextDirection.LeftRight_TopBottom, - 3, - 2, - """ - 界1 - 234 - """)] - [InlineData ( - "01234", - 3, - 3, - TextDirection.LeftRight_TopBottom, - 3, - 2, - """ - 012 - 34 - """)] - [InlineData ( - "界1234", - 3, - 3, - TextDirection.TopBottom_LeftRight, - 3, - 3, - """ - 界3 - 1 4 - 2 - """)] - [InlineData ( - "01234", - 3, - 3, - TextDirection.TopBottom_LeftRight, - 2, - 3, - """ - 03 - 14 - 2 - """)] - [InlineData ("01234", 2, 1, TextDirection.LeftRight_TopBottom, 2, 1, @"01")] - public void FormatAndGetSize_Returns_Correct_Size ( - string text, - int width, - int height, - TextDirection direction, - int expectedWidth, - int expectedHeight, - string expectedDraw - ) - { - TextFormatter tf = new () - { - Direction = direction, - ConstrainToWidth = width, - ConstrainToHeight = height, - Text = text - }; - Assert.True (tf.WordWrap); - Size size = tf.FormatAndGetSize (); - Assert.Equal (new (expectedWidth, expectedHeight), size); - - tf.Draw (new (0, 0, width, height), Attribute.Default, Attribute.Default); - - TestHelpers.AssertDriverContentsWithFrameAre (expectedDraw, _output); - } - - [Theory] - [SetupFakeDriver] - [InlineData ("界1234", 10, 10, TextDirection.LeftRight_TopBottom, 6, 1, @"界1234")] - [InlineData ("01234", 10, 10, TextDirection.LeftRight_TopBottom, 5, 1, @"01234")] - [InlineData ( - "界1234", - 10, - 10, - TextDirection.TopBottom_LeftRight, - 2, - 5, - """ - 界 - 1 - 2 - 3 - 4 - """)] - [InlineData ( - "01234", - 10, - 10, - TextDirection.TopBottom_LeftRight, - 1, - 5, - """ - 0 - 1 - 2 - 3 - 4 - """)] - [InlineData ("界1234", 3, 3, TextDirection.LeftRight_TopBottom, 3, 1, @"界1")] - [InlineData ("01234", 3, 3, TextDirection.LeftRight_TopBottom, 3, 1, @"012")] - [InlineData ( - "界1234", - 3, - 3, - TextDirection.TopBottom_LeftRight, - 2, - 3, - """ - 界 - 1 - 2 - """)] - [InlineData ( - "01234", - 3, - 3, - TextDirection.TopBottom_LeftRight, - 1, - 3, - """ - 0 - 1 - 2 - """)] - public void FormatAndGetSize_WordWrap_False_Returns_Correct_Size ( - string text, - int width, - int height, - TextDirection direction, - int expectedWidth, - int expectedHeight, - string expectedDraw - ) - { - TextFormatter tf = new () - { - Direction = direction, - ConstrainToSize = new (width, height), - Text = text, - WordWrap = false - }; - Assert.False (tf.WordWrap); - Size size = tf.FormatAndGetSize (); - Assert.Equal (new (expectedWidth, expectedHeight), size); - - tf.Draw (new (0, 0, width, height), Attribute.Default, Attribute.Default); - - TestHelpers.AssertDriverContentsWithFrameAre (expectedDraw, _output); - } - - #endregion } diff --git a/Tests/UnitTestsParallelizable/UnitTests.Parallelizable.csproj b/Tests/UnitTestsParallelizable/UnitTests.Parallelizable.csproj new file mode 100644 index 000000000..d450dad11 --- /dev/null +++ b/Tests/UnitTestsParallelizable/UnitTests.Parallelizable.csproj @@ -0,0 +1,87 @@ + + + + + + 2.0 + 2.0 + 2.0 + 2.0 + + + false + + true + true + portable + $(DefineConstants);JETBRAINS_ANNOTATIONS;CONTRACTS_FULL + enable + true + true + + + + true + $(DefineConstants) + + + true + + + + + + + + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + + PreserveNewest + + + + + + + + + + False + + + [UICatalog]* + + + + + + + + + + False + + + \ No newline at end of file diff --git a/Tests/UnitTestsParallelizable/UnitTests.Parallelizable.csproj.DotSettings b/Tests/UnitTestsParallelizable/UnitTests.Parallelizable.csproj.DotSettings new file mode 100644 index 000000000..632c26816 --- /dev/null +++ b/Tests/UnitTestsParallelizable/UnitTests.Parallelizable.csproj.DotSettings @@ -0,0 +1,2 @@ + + CSharp120 \ No newline at end of file diff --git a/Tests/UnitTestsParallelizable/View/Adornment/AdornmentSubViewTests.cs b/Tests/UnitTestsParallelizable/View/Adornment/AdornmentSubViewTests.cs new file mode 100644 index 000000000..c44be1410 --- /dev/null +++ b/Tests/UnitTestsParallelizable/View/Adornment/AdornmentSubViewTests.cs @@ -0,0 +1,28 @@ +using Xunit.Abstractions; + +namespace Terminal.Gui.ViewTests; + +public class AdornmentSubViewTests () +{ + [Fact] + public void Setting_Thickness_Causes_Adornment_SubView_Layout () + { + var view = new View (); + var subView = new View (); + view.Margin.Add (subView); + view.BeginInit (); + view.EndInit (); + var raised = false; + + subView.SubviewLayout += LayoutStarted; + view.Margin.Thickness = new Thickness (1, 2, 3, 4); + view.Layout (); + Assert.True (raised); + + return; + void LayoutStarted (object sender, LayoutEventArgs e) + { + raised = true; + } + } +} diff --git a/UnitTests/View/Adornment/AdornmentTests.cs b/Tests/UnitTestsParallelizable/View/Adornment/AdornmentTests.cs similarity index 63% rename from UnitTests/View/Adornment/AdornmentTests.cs rename to Tests/UnitTestsParallelizable/View/Adornment/AdornmentTests.cs index baa51833a..e251157e2 100644 --- a/UnitTests/View/Adornment/AdornmentTests.cs +++ b/Tests/UnitTestsParallelizable/View/Adornment/AdornmentTests.cs @@ -1,11 +1,7 @@ -using Xunit.Abstractions; +namespace Terminal.Gui.ViewTests; -namespace Terminal.Gui.ViewTests; - -public class AdornmentTests (ITestOutputHelper output) +public class AdornmentTests { - private readonly ITestOutputHelper _output = output; - [Fact] public void Viewport_Location_Always_Empty_Size_Correct () { @@ -32,7 +28,7 @@ public class AdornmentTests (ITestOutputHelper output) Assert.Equal (new (0, 0, 14, 14), view.Viewport); var paddingThickness = 3; - view.Padding.Thickness = new Thickness (paddingThickness); + view.Padding.Thickness = new (paddingThickness); Assert.Equal (new (0, 0, 8, 8), view.Viewport); Assert.Equal (new (0, 0, view.Margin.Frame.Width, view.Margin.Frame.Height), view.Margin.Viewport); @@ -55,7 +51,6 @@ public class AdornmentTests (ITestOutputHelper output) [InlineData (1, 0, 0, 4, 4)] [InlineData (1, 0, 0, 4, 0)] [InlineData (1, 0, 0, 0, 4)] - [InlineData (0, 1, 0, 0, 0)] [InlineData (0, 1, 0, 1, 1)] [InlineData (0, 1, 0, 1, 0)] @@ -67,7 +62,6 @@ public class AdornmentTests (ITestOutputHelper output) [InlineData (1, 1, 0, 4, 4)] [InlineData (1, 1, 0, 4, 0)] [InlineData (1, 1, 0, 0, 4)] - [InlineData (0, 1, 1, 0, 0)] [InlineData (0, 1, 1, 1, 1)] [InlineData (0, 1, 1, 1, 0)] @@ -82,9 +76,9 @@ public class AdornmentTests (ITestOutputHelper output) public void Viewport_Width_Is_Frame_Width (int thickness, int x, int y, int w, int h) { var adornment = new Adornment (null); - adornment.Thickness = new Thickness (thickness); - adornment.Frame = new Rectangle (x, y, w, h); - Assert.Equal (new Rectangle (x, y, w, h), adornment.Frame); + adornment.Thickness = new (thickness); + adornment.Frame = new (x, y, w, h); + Assert.Equal (new (x, y, w, h), adornment.Frame); var expectedBounds = new Rectangle (0, 0, w, h); Assert.Equal (expectedBounds, adornment.Viewport); @@ -99,26 +93,26 @@ public class AdornmentTests (ITestOutputHelper output) parent.BeginInit (); parent.EndInit (); - Assert.Equal (new Rectangle (1, 2, 10, 10), parent.Frame); - Assert.Equal (new Rectangle (0, 0, 10, 10), parent.Viewport); - Assert.Equal (new Rectangle (0, 0, 10, 10), parent.Margin.Frame); - Assert.Equal (new Rectangle (0, 0, 10, 10), parent.Margin.Viewport); + Assert.Equal (new (1, 2, 10, 10), parent.Frame); + Assert.Equal (new (0, 0, 10, 10), parent.Viewport); + Assert.Equal (new (0, 0, 10, 10), parent.Margin.Frame); + Assert.Equal (new (0, 0, 10, 10), parent.Margin.Viewport); Assert.Null (parent.Margin.SuperView); Rectangle boundsAsScreen = parent.Margin.ViewportToScreen (new Rectangle (1, 2, 5, 5)); - Assert.Equal (new Rectangle (2, 4, 5, 5), boundsAsScreen); + Assert.Equal (new (2, 4, 5, 5), boundsAsScreen); } [Fact] public void SetAdornmentFrames_Sets_Frames_Correctly () { var parent = new View { X = 1, Y = 2, Width = 10, Height = 20 }; - parent.SetAdornmentFrames(); + parent.SetAdornmentFrames (); - Assert.Equal (new Rectangle (1, 2, 10, 20), parent.Frame); - Assert.Equal (new Rectangle (0, 0, 10, 20), parent.Viewport); - Assert.Equal (new Rectangle (0, 0, 10, 20), parent.Margin.Frame); - Assert.Equal (new Rectangle (0, 0, 10, 20), parent.Margin.Viewport); + Assert.Equal (new (1, 2, 10, 20), parent.Frame); + Assert.Equal (new (0, 0, 10, 20), parent.Viewport); + Assert.Equal (new (0, 0, 10, 20), parent.Margin.Frame); + Assert.Equal (new (0, 0, 10, 20), parent.Margin.Viewport); } [Fact] @@ -133,35 +127,35 @@ public class AdornmentTests (ITestOutputHelper output) }; var marginThickness = 1; - view.Margin.Thickness = new Thickness (marginThickness); + view.Margin.Thickness = new (marginThickness); var borderThickness = 2; - view.Border.Thickness = new Thickness (borderThickness); + view.Border.Thickness = new (borderThickness); var paddingThickness = 3; - view.Padding.Thickness = new Thickness (paddingThickness); + view.Padding.Thickness = new (paddingThickness); view.BeginInit (); view.EndInit (); - Assert.Equal (new Rectangle (1, 2, 20, 31), view.Frame); - Assert.Equal (new Rectangle (0, 0, 8, 19), view.Viewport); + Assert.Equal (new (1, 2, 20, 31), view.Frame); + Assert.Equal (new (0, 0, 8, 19), view.Viewport); // Margin.Frame is always the same as the view frame - Assert.Equal (new Rectangle (0, 0, 20, 31), view.Margin.Frame); + Assert.Equal (new (0, 0, 20, 31), view.Margin.Frame); // Border.Frame is View.Frame minus the Margin thickness Assert.Equal ( - new Rectangle (marginThickness, marginThickness, view.Frame.Width - marginThickness * 2, view.Frame.Height - marginThickness * 2), + new (marginThickness, marginThickness, view.Frame.Width - marginThickness * 2, view.Frame.Height - marginThickness * 2), view.Border.Frame); // Padding.Frame is View.Frame minus the Border thickness plus Margin thickness Assert.Equal ( - new Rectangle ( - marginThickness + borderThickness, - marginThickness + borderThickness, - view.Frame.Width - (marginThickness + borderThickness) * 2, - view.Frame.Height - (marginThickness + borderThickness) * 2), + new ( + marginThickness + borderThickness, + marginThickness + borderThickness, + view.Frame.Width - (marginThickness + borderThickness) * 2, + view.Frame.Height - (marginThickness + borderThickness) * 2), view.Padding.Frame); } @@ -176,13 +170,13 @@ public class AdornmentTests (ITestOutputHelper output) public void FrameToScreen_Retains_Frame_Size (int marginThickness, int w, int h) { var parent = new View { X = 1, Y = 2, Width = w, Height = h }; - parent.Margin.Thickness = new Thickness (marginThickness); + parent.Margin.Thickness = new (marginThickness); parent.BeginInit (); parent.EndInit (); - Assert.Equal (new Rectangle (1, 2, w, h), parent.Frame); - Assert.Equal (new Rectangle (0, 0, w, h), parent.Margin.Frame); + Assert.Equal (new (1, 2, w, h), parent.Frame); + Assert.Equal (new (0, 0, w, h), parent.Margin.Frame); Assert.Equal (parent.Frame, parent.Margin.FrameToScreen ()); } @@ -226,24 +220,24 @@ public class AdornmentTests (ITestOutputHelper output) Width = 20, Height = 20 }; - superView.Margin.Thickness = new Thickness (marginThickness); - superView.Border.Thickness = new Thickness (borderThickness); + superView.Margin.Thickness = new (marginThickness); + superView.Border.Thickness = new (borderThickness); var view = new View { X = x, Y = y, Width = 1, Height = 1 }; superView.Add (view); superView.BeginInit (); superView.EndInit (); - Assert.Equal (new Rectangle (x, y, 1, 1), view.Frame); - Assert.Equal (new Rectangle (0, 0, 20, 20), superView.Margin.Frame); + Assert.Equal (new (x, y, 1, 1), view.Frame); + Assert.Equal (new (0, 0, 20, 20), superView.Margin.Frame); Assert.Equal ( - new Rectangle (marginThickness, marginThickness, 20 - marginThickness * 2, 20 - marginThickness * 2), + new (marginThickness, marginThickness, 20 - marginThickness * 2, 20 - marginThickness * 2), superView.Border.Frame ); Assert.Equal ( - new Rectangle (superView.Frame.X + marginThickness, superView.Frame.Y + marginThickness, 20 - marginThickness * 2, 20 - marginThickness * 2), + new (superView.Frame.X + marginThickness, superView.Frame.Y + marginThickness, 20 - marginThickness * 2, 20 - marginThickness * 2), superView.Border.FrameToScreen () ); } @@ -257,13 +251,13 @@ public class AdornmentTests (ITestOutputHelper output) parent.BeginInit (); parent.EndInit (); - Assert.Equal (new Rectangle (1, 2, 10, 10), parent.Frame); - Assert.Equal (new Rectangle (0, 0, 10, 10), parent.Viewport); - Assert.Equal (new Rectangle (0, 0, 10, 10), parent.Margin.Frame); - Assert.Equal (new Rectangle (0, 0, 10, 10), parent.Margin.Viewport); + Assert.Equal (new (1, 2, 10, 10), parent.Frame); + Assert.Equal (new (0, 0, 10, 10), parent.Viewport); + Assert.Equal (new (0, 0, 10, 10), parent.Margin.Frame); + Assert.Equal (new (0, 0, 10, 10), parent.Margin.Viewport); Assert.Null (parent.Margin.SuperView); - Assert.Equal (new Rectangle (1, 2, 10, 10), parent.Margin.FrameToScreen ()); + Assert.Equal (new (1, 2, 10, 10), parent.Margin.FrameToScreen ()); } [Fact] @@ -272,23 +266,23 @@ public class AdornmentTests (ITestOutputHelper output) var view = new View (); Assert.Equal (Thickness.Empty, view.GetAdornmentsThickness ()); - view.Margin.Thickness = new Thickness (1); - Assert.Equal (new Thickness (1), view.GetAdornmentsThickness ()); + view.Margin.Thickness = new (1); + Assert.Equal (new (1), view.GetAdornmentsThickness ()); - view.Border.Thickness = new Thickness (1); - Assert.Equal (new Thickness (2), view.GetAdornmentsThickness ()); + view.Border.Thickness = new (1); + Assert.Equal (new (2), view.GetAdornmentsThickness ()); - view.Padding.Thickness = new Thickness (1); - Assert.Equal (new Thickness (3), view.GetAdornmentsThickness ()); + view.Padding.Thickness = new (1); + Assert.Equal (new (3), view.GetAdornmentsThickness ()); - view.Padding.Thickness = new Thickness (2); - Assert.Equal (new Thickness (4), view.GetAdornmentsThickness ()); + view.Padding.Thickness = new (2); + Assert.Equal (new (4), view.GetAdornmentsThickness ()); - view.Padding.Thickness = new Thickness (1, 2, 3, 4); - Assert.Equal (new Thickness (3, 4, 5, 6), view.GetAdornmentsThickness ()); + view.Padding.Thickness = new (1, 2, 3, 4); + Assert.Equal (new (3, 4, 5, 6), view.GetAdornmentsThickness ()); - view.Margin.Thickness = new Thickness (1, 2, 3, 4); - Assert.Equal (new Thickness (3, 5, 7, 9), view.GetAdornmentsThickness ()); + view.Margin.Thickness = new (1, 2, 3, 4); + Assert.Equal (new (3, 5, 7, 9), view.GetAdornmentsThickness ()); view.Dispose (); } @@ -296,14 +290,14 @@ public class AdornmentTests (ITestOutputHelper output) public void Setting_Viewport_Throws () { var adornment = new Adornment (null); - Assert.Throws (() => adornment.Viewport = new Rectangle (1, 2, 3, 4)); + Assert.Throws (() => adornment.Viewport = new (1, 2, 3, 4)); } [Fact] public void Setting_SuperView_Throws () { var adornment = new Adornment (null); - Assert.Throws (() => adornment.SuperView = new View ()); + Assert.Throws (() => adornment.SuperView = new ()); } [Fact] @@ -320,12 +314,12 @@ public class AdornmentTests (ITestOutputHelper output) parent.BeginInit (); parent.EndInit (); - Assert.Equal (new Rectangle (0, 0, 10, 10), parent.Frame); - Assert.Equal (new Rectangle (0, 0, 10, 10), parent.Viewport); + Assert.Equal (new (0, 0, 10, 10), parent.Frame); + Assert.Equal (new (0, 0, 10, 10), parent.Viewport); - parent.Margin.Thickness = new Thickness (1); - Assert.Equal (new Rectangle (0, 0, 10, 10), parent.Frame); - Assert.Equal (new Rectangle (0, 0, 8, 8), parent.Viewport); + parent.Margin.Thickness = new (1); + Assert.Equal (new (0, 0, 10, 10), parent.Frame); + Assert.Equal (new (0, 0, 8, 8), parent.Viewport); } [Fact] @@ -334,16 +328,16 @@ public class AdornmentTests (ITestOutputHelper output) var adornment = new Adornment (null); var super = new View (); var raised = false; + adornment.ThicknessChanged += (s, e) => { raised = true; - Assert.Equal (new Thickness (1, 2, 3, 4), adornment.Thickness); + Assert.Equal (new (1, 2, 3, 4), adornment.Thickness); }; - adornment.Thickness = new Thickness (1, 2, 3, 4); + adornment.Thickness = new (1, 2, 3, 4); Assert.True (raised); } - [Fact] public void Setting_Thickness_Causes_Parent_Layout () { @@ -353,18 +347,15 @@ public class AdornmentTests (ITestOutputHelper output) parent.EndInit (); parent.SubviewLayout += LayoutStarted; - parent.Margin.Thickness = new Thickness (1, 2, 3, 4); + parent.Margin.Thickness = new (1, 2, 3, 4); Assert.True (parent.NeedsLayout); Assert.True (parent.Margin.NeedsLayout); parent.Layout (); Assert.True (raised); return; - void LayoutStarted (object sender, LayoutEventArgs e) - { - raised = true; - } + void LayoutStarted (object sender, LayoutEventArgs e) { raised = true; } } [Fact] @@ -376,17 +367,15 @@ public class AdornmentTests (ITestOutputHelper output) parent.EndInit (); parent.Margin.SubviewLayout += LayoutStarted; - parent.Margin.Thickness = new Thickness (1, 2, 3, 4); + parent.Margin.Thickness = new (1, 2, 3, 4); Assert.True (parent.NeedsLayout); Assert.True (parent.Margin.NeedsLayout); parent.Layout (); Assert.True (raised); return; - void LayoutStarted (object sender, LayoutEventArgs e) - { - raised = true; - } + + void LayoutStarted (object sender, LayoutEventArgs e) { raised = true; } } [Fact] @@ -408,7 +397,6 @@ public class AdornmentTests (ITestOutputHelper output) [InlineData (0, 0, 1, 0, 0, 0, false)] [InlineData (0, 0, 1, 1, 0, 0, true)] [InlineData (0, 0, 1, 2, 0, 0, true)] - [InlineData (1, 1, 0, 0, 0, 0, false)] [InlineData (1, 1, 0, 1, 0, 0, false)] [InlineData (1, 1, 1, 0, 0, 0, false)] @@ -420,8 +408,8 @@ public class AdornmentTests (ITestOutputHelper output) public void Contains_Left_Only (int x, int y, int width, int height, int pointX, int pointY, bool expected) { Adornment adornment = new () { Id = "adornment" }; - adornment.Parent = new View () { Id = "parent" }; - adornment.Parent.Frame = new Rectangle (x, y, width, height); + adornment.Parent = new() { Id = "parent" }; + adornment.Parent.Frame = new (x, y, width, height); adornment.Thickness = new (1, 0, 0, 0); adornment.Frame = adornment.Parent.Frame with { Location = Point.Empty }; @@ -435,7 +423,6 @@ public class AdornmentTests (ITestOutputHelper output) [InlineData (0, 0, 1, 0, 0, 0, false)] [InlineData (0, 0, 1, 1, 0, 0, true)] [InlineData (0, 0, 1, 2, 0, 0, true)] - [InlineData (1, 1, 0, 0, 0, 0, false)] [InlineData (1, 1, 0, 1, 0, 0, false)] [InlineData (1, 1, 1, 0, 0, 0, false)] @@ -447,8 +434,8 @@ public class AdornmentTests (ITestOutputHelper output) public void Contains_Right_Only (int x, int y, int width, int height, int pointX, int pointY, bool expected) { Adornment adornment = new () { Id = "adornment" }; - adornment.Parent = new View () { Id = "parent" }; - adornment.Parent.Frame = new Rectangle (x, y, width, height); + adornment.Parent = new() { Id = "parent" }; + adornment.Parent.Frame = new (x, y, width, height); adornment.Thickness = new (0, 0, 1, 0); adornment.Frame = adornment.Parent.Frame with { Location = Point.Empty }; @@ -456,14 +443,12 @@ public class AdornmentTests (ITestOutputHelper output) Assert.Equal (expected, result); } - [Theory] [InlineData (0, 0, 0, 0, 0, 0, false)] [InlineData (0, 0, 0, 1, 0, 0, false)] [InlineData (0, 0, 1, 0, 0, 0, false)] [InlineData (0, 0, 1, 1, 0, 0, true)] [InlineData (0, 0, 1, 2, 0, 0, true)] - [InlineData (1, 1, 0, 0, 0, 0, false)] [InlineData (1, 1, 0, 1, 0, 0, false)] [InlineData (1, 1, 1, 0, 0, 0, false)] @@ -475,8 +460,8 @@ public class AdornmentTests (ITestOutputHelper output) public void Contains_Top_Only (int x, int y, int width, int height, int pointX, int pointY, bool expected) { Adornment adornment = new () { Id = "adornment" }; - adornment.Parent = new View () { Id = "parent" }; - adornment.Parent.Frame = new Rectangle (x, y, width, height); + adornment.Parent = new() { Id = "parent" }; + adornment.Parent.Frame = new (x, y, width, height); adornment.Thickness = new (0, 1, 0, 0); adornment.Frame = adornment.Parent.Frame with { Location = Point.Empty }; @@ -484,14 +469,12 @@ public class AdornmentTests (ITestOutputHelper output) Assert.Equal (expected, result); } - [Theory] [InlineData (0, 0, 0, 0, 0, 0, false)] [InlineData (0, 0, 0, 1, 0, 0, false)] [InlineData (0, 0, 1, 0, 0, 0, false)] [InlineData (0, 0, 1, 1, 0, 0, true)] [InlineData (0, 0, 1, 2, 0, 0, true)] - [InlineData (1, 1, 0, 0, 0, 0, false)] [InlineData (1, 1, 0, 1, 0, 0, false)] [InlineData (1, 1, 1, 0, 0, 0, false)] @@ -503,74 +486,12 @@ public class AdornmentTests (ITestOutputHelper output) public void Contains_TopLeft_Only (int x, int y, int width, int height, int pointX, int pointY, bool expected) { Adornment adornment = new () { Id = "adornment" }; - adornment.Parent = new View () { Id = "parent" }; - adornment.Parent.Frame = new Rectangle (x, y, width, height); + adornment.Parent = new() { Id = "parent" }; + adornment.Parent.Frame = new (x, y, width, height); adornment.Thickness = new (1, 1, 0, 0); adornment.Frame = adornment.Parent.Frame with { Location = Point.Empty }; bool result = adornment.Contains (new (pointX, pointY)); Assert.Equal (expected, result); } - - [Fact] - [SetupFakeDriver] - public void Border_Is_Cleared_After_Margin_Thickness_Change () - { - View view = new () { 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 (); - - TestHelpers.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); - - TestHelpers.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.SetClipToScreen (); - view.Draw (); - - TestHelpers.AssertDriverContentsWithFrameAre ( - @" -╭────╮ -│View│ -", - output - ); - } } diff --git a/Tests/UnitTestsParallelizable/View/Adornment/ShadowStyletests.cs b/Tests/UnitTestsParallelizable/View/Adornment/ShadowStyletests.cs new file mode 100644 index 000000000..7885f314b --- /dev/null +++ b/Tests/UnitTestsParallelizable/View/Adornment/ShadowStyletests.cs @@ -0,0 +1,106 @@ +namespace Terminal.Gui.ViewTests; + +public class ShadowStyleTests +{ + [Fact] + public void Default_None () + { + var view = new View (); + Assert.Equal (ShadowStyle.None, view.ShadowStyle); + Assert.Equal (ShadowStyle.None, view.Margin!.ShadowStyle); + view.Dispose (); + } + + [Theory] + [InlineData (ShadowStyle.None)] + [InlineData (ShadowStyle.Opaque)] + [InlineData (ShadowStyle.Transparent)] + public void Set_View_Sets_Margin (ShadowStyle style) + { + var view = new View (); + + view.ShadowStyle = style; + Assert.Equal (style, view.ShadowStyle); + Assert.Equal (style, view.Margin!.ShadowStyle); + view.Dispose (); + } + + [Theory] + [InlineData (ShadowStyle.None, 0, 0, 0, 0)] + [InlineData (ShadowStyle.Opaque, 1, 0, 0, 1)] + [InlineData (ShadowStyle.Transparent, 1, 0, 0, 1)] + public void ShadowStyle_Button1Pressed_Causes_Movement (ShadowStyle style, int expectedLeft, int expectedTop, int expectedRight, int expectedBottom) + { + var superView = new View + { + Height = 10, Width = 10 + }; + + View view = new () + { + Width = Dim.Auto (), + Height = Dim.Auto (), + Text = "0123", + HighlightStyle = HighlightStyle.Pressed, + ShadowStyle = style, + CanFocus = true + }; + + superView.Add (view); + superView.BeginInit (); + superView.EndInit (); + + Thickness origThickness = view.Margin!.Thickness; + view.NewMouseEvent (new () { Flags = MouseFlags.Button1Pressed, Position = new (0, 0) }); + Assert.Equal (new (expectedLeft, expectedTop, expectedRight, expectedBottom), view.Margin.Thickness); + + view.NewMouseEvent (new () { Flags = MouseFlags.Button1Released, Position = new (0, 0) }); + Assert.Equal (origThickness, view.Margin.Thickness); + } + + [Theory] + [InlineData (ShadowStyle.None, 0, 0, 0, 0)] + [InlineData (ShadowStyle.Opaque, 0, 0, 1, 1)] + [InlineData (ShadowStyle.Transparent, 0, 0, 1, 1)] + public void ShadowStyle_Margin_Thickness (ShadowStyle style, int expectedLeft, int expectedTop, int expectedRight, int expectedBottom) + { + var superView = new View + { + Height = 10, Width = 10 + }; + + View view = new () + { + Width = Dim.Auto (), + Height = Dim.Auto (), + Text = "0123", + HighlightStyle = HighlightStyle.Pressed, + ShadowStyle = style, + CanFocus = true + }; + + superView.Add (view); + superView.BeginInit (); + superView.EndInit (); + + Assert.Equal (new (expectedLeft, expectedTop, expectedRight, expectedBottom), view.Margin.Thickness); + } + + + [Theory] + [InlineData (ShadowStyle.None, 3)] + [InlineData (ShadowStyle.Opaque, 4)] + [InlineData (ShadowStyle.Transparent, 4)] + public void Style_Changes_Margin_Thickness (ShadowStyle style, int expected) + { + var view = new View (); + view.Margin!.Thickness = new (3); + view.ShadowStyle = style; + Assert.Equal (new (3, 3, expected, expected), view.Margin.Thickness); + + view.ShadowStyle = ShadowStyle.None; + Assert.Equal (new (3), view.Margin.Thickness); + view.Dispose (); + } + +} diff --git a/Tests/UnitTestsParallelizable/View/Adornment/ToScreenTests.cs b/Tests/UnitTestsParallelizable/View/Adornment/ToScreenTests.cs new file mode 100644 index 000000000..2d8f03de1 --- /dev/null +++ b/Tests/UnitTestsParallelizable/View/Adornment/ToScreenTests.cs @@ -0,0 +1,14 @@ +using Xunit.Abstractions; + +namespace Terminal.Gui.ViewTests; + +/// +/// Test the and methods. +/// DOES NOT TEST View.xxxToScreen methods. Those are in ./View/Layout/ToScreenTests.cs +/// +/// +public class AdornmentToScreenTests (ITestOutputHelper output) +{ + private readonly ITestOutputHelper _output = output; + +} diff --git a/UnitTests/View/Draw/NeedsDrawTests.cs b/Tests/UnitTestsParallelizable/View/Draw/NeedsDrawTests.cs similarity index 79% rename from UnitTests/View/Draw/NeedsDrawTests.cs rename to Tests/UnitTestsParallelizable/View/Draw/NeedsDrawTests.cs index 6637bc768..58bf23cdf 100644 --- a/UnitTests/View/Draw/NeedsDrawTests.cs +++ b/Tests/UnitTestsParallelizable/View/Draw/NeedsDrawTests.cs @@ -2,7 +2,7 @@ namespace Terminal.Gui.ViewTests; [Trait ("Category", "Output")] -public class NeedsDrawTests () +public class NeedsDrawTests { [Fact] public void NeedsDraw_False_If_Width_Height_Zero () @@ -11,10 +11,10 @@ public class NeedsDrawTests () view.BeginInit (); view.EndInit (); Assert.True (view.NeedsDraw); + //Assert.False (view.SubViewNeedsDraw); } - [Fact] public void NeedsDraw_True_Initially_If_Width_Height_Not_Zero () { @@ -31,7 +31,7 @@ public class NeedsDrawTests () Assert.True (view1.NeedsDraw); Assert.True (view2.NeedsDraw); - superView.Layout (); // NeedsDraw is always false if Layout is needed + superView.Layout (); // NeedsDraw is always false if Layout is needed superView.Draw (); @@ -48,14 +48,13 @@ public class NeedsDrawTests () Assert.True (view2.NeedsDraw); } - [Fact] public void NeedsDraw_True_After_Constructor () { var view = new View { Width = 2, Height = 2 }; Assert.True (view.NeedsDraw); - view = new View { Width = 2, Height = 2, BorderStyle = LineStyle.Single }; + view = new() { Width = 2, Height = 2, BorderStyle = LineStyle.Single }; Assert.True (view.NeedsDraw); } @@ -89,14 +88,13 @@ public class NeedsDrawTests () view.EndInit (); Assert.True (view.NeedsDraw); - view = new View { Width = 2, Height = 2, BorderStyle = LineStyle.Single }; + view = new() { Width = 2, Height = 2, BorderStyle = LineStyle.Single }; view.BeginInit (); view.NeedsDraw = false; view.EndInit (); Assert.True (view.NeedsDraw); } - [Fact] public void NeedsDraw_After_SetLayoutNeeded () { @@ -144,6 +142,7 @@ public class NeedsDrawTests () public void NeedsDraw_False_After_SetRelativeLayout_Relative_Dims () { var view = new View { Width = Dim.Percent (50), Height = Dim.Percent (50) }; + View superView = new () { Id = "superView", @@ -169,7 +168,6 @@ public class NeedsDrawTests () Assert.True (superView.NeedsDraw); } - [Fact] public void NeedsDraw_False_After_SetRelativeLayout_10x10 () { @@ -244,7 +242,7 @@ public class NeedsDrawTests () var view = new View { - Id = "view", + Id = "view" }; view.Frame = new (0, 1, 2, 3); @@ -294,66 +292,5 @@ public class NeedsDrawTests () Assert.Equal (new (3, 3, 5, 5), view.Frame); Assert.Equal (new (1, 1, 5, 5), view.Viewport); Assert.Equal (new (1, 1, 5, 5), view._needsDrawRect); - - } - - - [Fact] - [AutoInitShutdown] - public void Frame_Set_After_Initialize_Update_NeededDisplay () - { - var frame = new FrameView (); - - var label = new Label - { - ColorScheme = Colors.ColorSchemes ["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; - - Toplevel top = new (); - - top.Add (frame); - - RunState runState = Application.Begin (top); - - 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 (runState); - top.Dispose (); } } diff --git a/UnitTests/View/Layout/Dim.AutoTests.DimTypes.cs b/Tests/UnitTestsParallelizable/View/Layout/Dim.AutoTests.DimTypes.cs similarity index 100% rename from UnitTests/View/Layout/Dim.AutoTests.DimTypes.cs rename to Tests/UnitTestsParallelizable/View/Layout/Dim.AutoTests.DimTypes.cs diff --git a/UnitTests/View/Layout/Dim.AutoTests.MinMax.cs b/Tests/UnitTestsParallelizable/View/Layout/Dim.AutoTests.MinMax.cs similarity index 100% rename from UnitTests/View/Layout/Dim.AutoTests.MinMax.cs rename to Tests/UnitTestsParallelizable/View/Layout/Dim.AutoTests.MinMax.cs diff --git a/UnitTests/View/Layout/Dim.AutoTests.PosTypes.cs b/Tests/UnitTestsParallelizable/View/Layout/Dim.AutoTests.PosTypes.cs similarity index 100% rename from UnitTests/View/Layout/Dim.AutoTests.PosTypes.cs rename to Tests/UnitTestsParallelizable/View/Layout/Dim.AutoTests.PosTypes.cs diff --git a/UnitTests/View/Layout/Dim.AutoTests.cs b/Tests/UnitTestsParallelizable/View/Layout/Dim.AutoTests.cs similarity index 96% rename from UnitTests/View/Layout/Dim.AutoTests.cs rename to Tests/UnitTestsParallelizable/View/Layout/Dim.AutoTests.cs index 0d569e675..e9a141c0a 100644 --- a/UnitTests/View/Layout/Dim.AutoTests.cs +++ b/Tests/UnitTestsParallelizable/View/Layout/Dim.AutoTests.cs @@ -1,4 +1,5 @@ using System.Text; +using UnitTests; using Xunit.Abstractions; using static Terminal.Gui.Dim; @@ -993,41 +994,6 @@ public partial class DimAutoTests (ITestOutputHelper output) Assert.Equal (new (5, 5), view.Frame.Size); } - [Fact] - [SetupFakeDriver] - public void DimAutoStyle_Content_Pos_AnchorEnd_Locates_Correctly () - { - (((FakeDriver)Application.Driver)!).SetBufferSize(10,10); - - DimAutoTestView view = new (Auto (DimAutoStyle.Content), Auto (DimAutoStyle.Content)); - - View subView = new () - { - Width = 5, - Height = 1 - }; - view.Add (subView); - - view.Layout (); - Assert.Equal (new (5, 1), view.Frame.Size); - Assert.Equal (new (0, 0), view.Frame.Location); - - view.X = 0; - view.Y = Pos.AnchorEnd (1); - view.Layout (); - Assert.Equal (new (5, 1), view.Frame.Size); - Assert.Equal (new (0, 9), view.Frame.Location); - - view.Y = Pos.AnchorEnd (); - view.Layout (); - Assert.Equal (new (5, 1), view.Frame.Size); - Assert.Equal (new (0, 9), view.Frame.Location); - - view.Y = Pos.AnchorEnd () - 1; - view.Layout (); - Assert.Equal (new (5, 1), view.Frame.Size); - Assert.Equal (new (0, 8), view.Frame.Location); - } #endregion DimAutoStyle.Content tests diff --git a/UnitTests/View/Layout/Dim.CombineTests.cs b/Tests/UnitTestsParallelizable/View/Layout/Dim.CombineTests.cs similarity index 100% rename from UnitTests/View/Layout/Dim.CombineTests.cs rename to Tests/UnitTestsParallelizable/View/Layout/Dim.CombineTests.cs diff --git a/UnitTests/View/Layout/Dim.FillTests.cs b/Tests/UnitTestsParallelizable/View/Layout/Dim.FillTests.cs similarity index 88% rename from UnitTests/View/Layout/Dim.FillTests.cs rename to Tests/UnitTestsParallelizable/View/Layout/Dim.FillTests.cs index 5e1ba315a..ec43c9538 100644 --- a/UnitTests/View/Layout/Dim.FillTests.cs +++ b/Tests/UnitTestsParallelizable/View/Layout/Dim.FillTests.cs @@ -1,4 +1,5 @@ -using Xunit.Abstractions; +using UnitTests; +using Xunit.Abstractions; namespace Terminal.Gui.LayoutTests; @@ -6,24 +7,6 @@ public class DimFillTests (ITestOutputHelper output) { private readonly ITestOutputHelper _output = output; - [Fact] - [AutoInitShutdown] - public void DimFill_SizedCorrectly () - { - var view = new View { Width = Dim.Fill (), Height = Dim.Fill (), BorderStyle = LineStyle.Single }; - var top = new Toplevel (); - top.Add (view); - RunState rs = Application.Begin (top); - ((FakeDriver)Application.Driver!).SetBufferSize (32, 5); - - top.Layout (); - - //view.SetRelativeLayout (new (0, 0, 32, 5)); - Assert.Equal (32, view.Frame.Width); - Assert.Equal (5, view.Frame.Height); - top.Dispose (); - } - [Fact] public void DimFill_Equal () diff --git a/UnitTests/View/Layout/Dim.FuncTests.cs b/Tests/UnitTestsParallelizable/View/Layout/Dim.FuncTests.cs similarity index 100% rename from UnitTests/View/Layout/Dim.FuncTests.cs rename to Tests/UnitTestsParallelizable/View/Layout/Dim.FuncTests.cs diff --git a/UnitTests/View/Layout/Dim.PercentTests.cs b/Tests/UnitTestsParallelizable/View/Layout/Dim.PercentTests.cs similarity index 100% rename from UnitTests/View/Layout/Dim.PercentTests.cs rename to Tests/UnitTestsParallelizable/View/Layout/Dim.PercentTests.cs diff --git a/Tests/UnitTestsParallelizable/View/Layout/Dim.Tests.cs b/Tests/UnitTestsParallelizable/View/Layout/Dim.Tests.cs new file mode 100644 index 000000000..d844841c0 --- /dev/null +++ b/Tests/UnitTestsParallelizable/View/Layout/Dim.Tests.cs @@ -0,0 +1,245 @@ +using System.Globalization; +using System.Text; +using UnitTests; +using Xunit.Abstractions; +using static Terminal.Gui.Dim; + +namespace Terminal.Gui.LayoutTests; + +public class DimTests +{ + [Fact] + public void DimAbsolute_Calculate_ReturnsCorrectValue () + { + var dim = new DimAbsolute (10); + int result = dim.Calculate (0, 100, null, Dimension.None); + Assert.Equal (10, result); + } + + // TODO: This actually a SetRelativeLayout/LayoutSubViews test and should be moved + // TODO: A new test that calls SetRelativeLayout directly is needed. + [Fact] + public void Dim_Validation_Do_Not_Throws_If_NewValue_Is_DimAbsolute_And_OldValue_Is_Null () + { + var t = new View { Width = 80, Height = 25, Text = "top" }; + + var w = new View + { + BorderStyle = LineStyle.Single, + X = 1, + Y = 2, + Width = 4, + Height = 5, + Title = "w" + }; + t.Add (w); + t.LayoutSubviews (); + + Assert.Equal (3, w.Width = 3); + Assert.Equal (4, w.Height = 4); + t.Dispose (); + } + + [Fact] + public void DimHeight_Set_To_Null_Throws () + { + Dim dim = Height (null); + Assert.Throws (() => dim.ToString ()); + } + + [Fact] + public void DimHeight_SetsValue () + { + var testVal = Rectangle.Empty; + var testValview = new View { Frame = testVal }; + Dim dim = Height (testValview); + Assert.Equal ($"View(Height,View(){testVal})", dim.ToString ()); + testValview.Dispose (); + + testVal = new (1, 2, 3, 4); + testValview = new () { Frame = testVal }; + dim = Height (testValview); + Assert.Equal ($"View(Height,View(){testVal})", dim.ToString ()); + testValview.Dispose (); + } + + [Fact] + public void Internal_Tests () + { + var dimFactor = new DimPercent (10); + Assert.Equal (10, dimFactor.GetAnchor (100)); + + var dimAbsolute = new DimAbsolute (10); + Assert.Equal (10, dimAbsolute.GetAnchor (0)); + + var dimFill = new DimFill (1); + Assert.Equal (99, dimFill.GetAnchor (100)); + + var dimCombine = new DimCombine (AddOrSubtract.Add, dimFactor, dimAbsolute); + Assert.Equal (dimCombine.Left, dimFactor); + Assert.Equal (dimCombine.Right, dimAbsolute); + Assert.Equal (20, dimCombine.GetAnchor (100)); + + var view = new View { Frame = new (20, 10, 20, 1) }; + var dimViewHeight = new DimView (view, Dimension.Height); + Assert.Equal (1, dimViewHeight.GetAnchor (0)); + var dimViewWidth = new DimView (view, Dimension.Width); + Assert.Equal (20, dimViewWidth.GetAnchor (0)); + + view.Dispose (); + } + + // TODO: This actually a SetRelativeLayout/LayoutSubViews test and should be moved + // TODO: A new test that calls SetRelativeLayout directly is needed. + [Fact] + public void Referencing_SuperView_Does_Not_Throw () + { + var super = new View { Width = 10, Height = 10, Text = "super" }; + + var view = new View + { + Width = Width (super), // this is allowed + Height = Height (super), // this is allowed + Text = "view" + }; + + super.Add (view); + super.BeginInit (); + super.EndInit (); + + Exception exception = Record.Exception (super.LayoutSubviews); + Assert.Null (exception); + super.Dispose (); + } + + [Fact] + public void DimSized_Equals () + { + var n1 = 0; + var n2 = 0; + Dim dim1 = Absolute (n1); + Dim dim2 = Absolute (n2); + Assert.Equal (dim1, dim2); + + n1 = n2 = 1; + dim1 = Absolute (n1); + dim2 = Absolute (n2); + Assert.Equal (dim1, dim2); + + n1 = n2 = -1; + dim1 = Absolute (n1); + dim2 = Absolute (n2); + Assert.Equal (dim1, dim2); + + n1 = 0; + n2 = 1; + dim1 = Absolute (n1); + dim2 = Absolute (n2); + Assert.NotEqual (dim1, dim2); + } + + [Fact] + public void DimSized_SetsValue () + { + Dim dim = Absolute (0); + Assert.Equal ("Absolute(0)", dim.ToString ()); + + var testVal = 5; + dim = Absolute (testVal); + Assert.Equal ($"Absolute({testVal})", dim.ToString ()); + + testVal = -1; + dim = Absolute (testVal); + Assert.Equal ($"Absolute({testVal})", dim.ToString ()); + } + + // 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_DimAbsolute_And_OldValue_Is_Null () + { + var t = new View { Width = 80, Height = 25, Text = "top" }; + + var w = new Window + { + X = 1, + Y = 2, + Width = 4, + Height = 5, + Title = "w" + }; + t.Add (w); + t.LayoutSubviews (); + + Assert.Equal (3, w.Width = 3); + Assert.Equal (4, w.Height = 4); + t.Dispose (); + } + + [Fact] + public void DimWidth_Equals () + { + var testRect1 = Rectangle.Empty; + var view1 = new View { Frame = testRect1 }; + var testRect2 = Rectangle.Empty; + var view2 = new View { Frame = testRect2 }; + + Dim dim1 = Width (view1); + Dim dim2 = Width (view1); + + // FIXED: Dim.Width should support Equals() and this should change to Equal. + Assert.Equal (dim1, dim2); + + dim2 = Width (view2); + Assert.NotEqual (dim1, dim2); + + testRect1 = new (0, 1, 2, 3); + view1 = new () { Frame = testRect1 }; + testRect2 = new (0, 1, 2, 3); + dim1 = Width (view1); + dim2 = Width (view1); + + // FIXED: Dim.Width should support Equals() and this should change to Equal. + Assert.Equal (dim1, dim2); + + testRect1 = new (0, -1, 2, 3); + view1 = new () { Frame = testRect1 }; + testRect2 = new (0, -1, 2, 3); + dim1 = Width (view1); + dim2 = Width (view1); + + // FIXED: Dim.Width should support Equals() and this should change to Equal. + Assert.Equal (dim1, dim2); + + testRect1 = new (0, -1, 2, 3); + view1 = new () { Frame = testRect1 }; + testRect2 = Rectangle.Empty; + view2 = new () { Frame = testRect2 }; + dim1 = Width (view1); + dim2 = Width (view2); + Assert.NotEqual (dim1, dim2); + } + + [Fact] + public void DimWidth_Set_To_Null_Throws () + { + Dim dim = Width (null); + Assert.Throws (() => dim.ToString ()); + } + + [Fact] + public void DimWidth_SetsValue () + { + var testVal = Rectangle.Empty; + var testValView = new View { Frame = testVal }; + Dim dim = Width (testValView); + Assert.Equal ($"View(Width,View(){testVal})", dim.ToString ()); + testValView.Dispose (); + + testVal = new (1, 2, 3, 4); + testValView = new () { Frame = testVal }; + dim = Width (testValView); + Assert.Equal ($"View(Width,View(){testVal})", dim.ToString ()); + testValView.Dispose (); + } +} diff --git a/UnitTests/View/Layout/Dim.ViewTests.cs b/Tests/UnitTestsParallelizable/View/Layout/Dim.ViewTests.cs similarity index 76% rename from UnitTests/View/Layout/Dim.ViewTests.cs rename to Tests/UnitTestsParallelizable/View/Layout/Dim.ViewTests.cs index 2df83b531..6c8d3247a 100644 --- a/UnitTests/View/Layout/Dim.ViewTests.cs +++ b/Tests/UnitTestsParallelizable/View/Layout/Dim.ViewTests.cs @@ -1,12 +1,9 @@ -using Xunit.Abstractions; -using static Terminal.Gui.Dim; +using static Terminal.Gui.Dim; namespace Terminal.Gui.LayoutTests; -public class DimViewTests (ITestOutputHelper output) +public class DimViewTests { - private readonly ITestOutputHelper _output = output; - [Fact] public void DimView_Equal () { @@ -24,29 +21,27 @@ public class DimViewTests (ITestOutputHelper output) Assert.NotEqual (dim1, dim2); } - [Fact] public void DimView_Calculate_ReturnsCorrectValue () { var view = new View { Width = 10 }; view.Layout (); var dim = new DimView (view, Dimension.Width); - var result = dim.Calculate (0, 100, null, Dimension.None); + int result = dim.Calculate (0, 100, null, Dimension.None); Assert.Equal (10, result); } // TODO: This actually a SetRelativeLayout/LayoutSubViews test and should be moved // TODO: A new test that calls SetRelativeLayout directly is needed. [Fact] - [TestRespondersDisposed] public void Dim_Referencing_SuperView_Does_Not_Throw () { var super = new View { Width = 10, Height = 10, Text = "super" }; var view = new View { - Width = Dim.Width (super), // this is allowed - Height = Dim.Height (super), // this is allowed + Width = Width (super), // this is allowed + Height = Height (super), // this is allowed Text = "view" }; diff --git a/UnitTests/View/Layout/FrameTests.cs b/Tests/UnitTestsParallelizable/View/Layout/FrameTests.cs similarity index 83% rename from UnitTests/View/Layout/FrameTests.cs rename to Tests/UnitTestsParallelizable/View/Layout/FrameTests.cs index cc9ba8608..a58475158 100644 --- a/UnitTests/View/Layout/FrameTests.cs +++ b/Tests/UnitTestsParallelizable/View/Layout/FrameTests.cs @@ -1,53 +1,84 @@ -using Xunit.Abstractions; +namespace Terminal.Gui.LayoutTests; -namespace Terminal.Gui.LayoutTests; - -public class FrameTests (ITestOutputHelper output) +public class FrameTests { - private readonly ITestOutputHelper _output = output; - [Fact] public void Frame_Empty_Default () { View view = new (); - Assert.Equal(Rectangle.Empty, view.Frame); + Assert.Equal (Rectangle.Empty, view.Frame); - view.BeginInit(); - view.EndInit(); + view.BeginInit (); + view.EndInit (); Assert.Equal (Rectangle.Empty, view.Frame); } [Fact] - public void Frame_Set_Sets () + public void Frame_Empty_Initializer_Overrides_Base () { - Rectangle frame = new (1, 2, 3, 4); - View view = new (); + // Prove TestView is correct + FrameTestView view = new (); Assert.True (view.NeedsLayout); - Assert.Equal (Rectangle.Empty, view.Frame); - view.Frame = frame; - Assert.Equal (frame, view.Frame); - Assert.False (view.NeedsLayout); + view.Layout (); + Assert.Equal (new (10, 20, 30, 40), view.Frame); + Assert.Equal (10, view.X.GetAnchor (0)); + Assert.Equal (20, view.Y.GetAnchor (0)); + Assert.Equal (30, view.Width!.GetAnchor (0)); + Assert.Equal (40, view.Height!.GetAnchor (0)); + Assert.Equal (new (0, 0, 30, 40), view.Viewport); - Assert.Equal(view.X, frame.X); - Assert.Equal (view.Y, frame.Y); - Assert.Equal (view.Width, frame.Width); - Assert.Equal (view.Height, frame.Height); - } - - [Fact] - public void Frame_Initializer_Sets () - { + // Set Frame via init Rectangle frame = new (1, 2, 3, 4); - View view = new () - { - Frame = frame, - }; + view = new () + { + Frame = frame + }; Assert.Equal (frame, view.Frame); Assert.False (view.NeedsLayout); Assert.Equal (frame.Size, view.Viewport.Size); + Assert.Equal (view.X, frame.X); + Assert.Equal (view.Y, frame.Y); + Assert.Equal (view.Width, frame.Width); + Assert.Equal (view.Height, frame.Height); + + // Set Frame via init to empty + frame = Rectangle.Empty; + + view = new () + { + Frame = frame + }; + Assert.Equal (frame, view.Frame); + Assert.False (view.NeedsLayout); + Assert.Equal (frame.Size, view.Viewport.Size); + + Assert.Equal (view.X, frame.X); + Assert.Equal (view.Y, frame.Y); + Assert.Equal (view.Width, frame.Width); + Assert.Equal (view.Height, frame.Height); + + // Set back to original state + view.X = Pos.Func (() => 10); + view.Y = Pos.Func (() => 20); + view.Width = Dim.Func (() => 30); + view.Height = Dim.Func (() => 40); + Assert.True (view.NeedsLayout); + + view.Layout (); + Assert.Equal (new (10, 20, 30, 40), view.Frame); + Assert.Equal (10, view.X.GetAnchor (0)); + Assert.Equal (20, view.Y.GetAnchor (0)); + Assert.Equal (30, view.Width!.GetAnchor (0)); + Assert.Equal (40, view.Height!.GetAnchor (0)); + Assert.Equal (new (0, 0, 30, 40), view.Viewport); + + view.Frame = frame; + Assert.Equal (frame, view.Frame); + Assert.False (view.NeedsLayout); + Assert.Equal (frame.Size, view.Viewport.Size); Assert.Equal (view.X, frame.X); Assert.Equal (view.Y, frame.Y); @@ -55,14 +86,14 @@ public class FrameTests (ITestOutputHelper output) Assert.Equal (view.Height, frame.Height); } - [Fact] public void Frame_Empty_Initializer_Sets () { Rectangle frame = new (1, 2, 3, 4); + View view = new () { - Frame = frame, + Frame = frame }; Assert.Equal (frame, view.Frame); @@ -100,71 +131,18 @@ public class FrameTests (ITestOutputHelper output) Assert.Equal (view.Y, Rectangle.Empty.Y); Assert.Equal (view.Width, Rectangle.Empty.Width); Assert.Equal (view.Height, Rectangle.Empty.Height); - } - [Fact] - public void Frame_Empty_Initializer_Overrides_Base () + public void Frame_Initializer_Sets () { - // Prove TestView is correct - FrameTestView view = new (); - Assert.True (view.NeedsLayout); - - view.Layout (); - Assert.Equal (new Rectangle(10, 20, 30, 40), view.Frame); - Assert.Equal (10, view.X.GetAnchor(0)); - Assert.Equal (20, view.Y.GetAnchor(0)); - Assert.Equal (30, view.Width!.GetAnchor(0)); - Assert.Equal (40, view.Height!.GetAnchor(0)); - Assert.Equal (new Rectangle (0, 0, 30, 40), view.Viewport); - - // Set Frame via init Rectangle frame = new (1, 2, 3, 4); - view = new () + + View view = new () { - Frame = frame, + Frame = frame }; - Assert.Equal (frame, view.Frame); - Assert.False (view.NeedsLayout); - Assert.Equal (frame.Size, view.Viewport.Size); - Assert.Equal (view.X, frame.X); - Assert.Equal (view.Y, frame.Y); - Assert.Equal (view.Width, frame.Width); - Assert.Equal (view.Height, frame.Height); - - // Set Frame via init to empty - frame = Rectangle.Empty; - view = new () - { - Frame = frame, - }; - Assert.Equal (frame, view.Frame); - Assert.False (view.NeedsLayout); - Assert.Equal (frame.Size, view.Viewport.Size); - - Assert.Equal (view.X, frame.X); - Assert.Equal (view.Y, frame.Y); - Assert.Equal (view.Width, frame.Width); - Assert.Equal (view.Height, frame.Height); - - // Set back to original state - view.X = Pos.Func (() => 10); - view.Y = Pos.Func (() => 20); - view.Width = Dim.Func (() => 30); - view.Height = Dim.Func (() => 40); - Assert.True (view.NeedsLayout); - - view.Layout (); - Assert.Equal (new Rectangle (10, 20, 30, 40), view.Frame); - Assert.Equal (10, view.X.GetAnchor (0)); - Assert.Equal (20, view.Y.GetAnchor (0)); - Assert.Equal (30, view.Width!.GetAnchor (0)); - Assert.Equal (40, view.Height!.GetAnchor (0)); - Assert.Equal (new Rectangle (0, 0, 30, 40), view.Viewport); - - view.Frame = frame; Assert.Equal (frame, view.Frame); Assert.False (view.NeedsLayout); Assert.Equal (frame.Size, view.Viewport.Size); @@ -175,22 +153,9 @@ public class FrameTests (ITestOutputHelper output) Assert.Equal (view.Height, frame.Height); } - private class FrameTestView : View - { - public FrameTestView () - { - X = Pos.Func (() => 10); - Y = Pos.Func (() => 20); - Width = Dim.Func (() => 30); - Height = Dim.Func (() => 40); - } - } - - // Moved this test from AbsoluteLayoutTests // TODO: Refactor as Theory [Fact] - [TestRespondersDisposed] public void Frame_Set () { var frame = new Rectangle (1, 2, 3, 4); @@ -200,14 +165,14 @@ public class FrameTests (ITestOutputHelper output) Assert.Equal (Rectangle.Empty, v.Frame); v.Dispose (); - v = new View { Frame = frame }; + v = new() { Frame = frame }; Assert.Equal (frame, v.Frame); v.Frame = newFrame; Assert.Equal (newFrame, v.Frame); Assert.Equal ( - new Rectangle (0, 0, newFrame.Width, newFrame.Height), + new (0, 0, newFrame.Width, newFrame.Height), v.Viewport ); // With Absolute Viewport *is* deterministic before Layout Assert.Equal (Pos.Absolute (1), v.X); @@ -216,12 +181,12 @@ public class FrameTests (ITestOutputHelper output) Assert.Equal (Dim.Absolute (40), v.Height); v.Dispose (); - v = new View { X = frame.X, Y = frame.Y, Text = "v" }; + v = new() { X = frame.X, Y = frame.Y, Text = "v" }; v.Frame = newFrame; Assert.Equal (newFrame, v.Frame); Assert.Equal ( - new Rectangle (0, 0, newFrame.Width, newFrame.Height), + new (0, 0, newFrame.Width, newFrame.Height), v.Viewport ); // With Absolute Viewport *is* deterministic before Layout Assert.Equal (Pos.Absolute (1), v.X); @@ -230,13 +195,13 @@ public class FrameTests (ITestOutputHelper output) Assert.Equal (Dim.Absolute (40), v.Height); v.Dispose (); - newFrame = new Rectangle (10, 20, 30, 40); - v = new View { Frame = frame }; + newFrame = new (10, 20, 30, 40); + v = new() { Frame = frame }; v.Frame = newFrame; Assert.Equal (newFrame, v.Frame); Assert.Equal ( - new Rectangle (0, 0, newFrame.Width, newFrame.Height), + new (0, 0, newFrame.Width, newFrame.Height), v.Viewport ); // With Absolute Viewport *is* deterministic before Layout Assert.Equal (Pos.Absolute (10), v.X); @@ -245,12 +210,12 @@ public class FrameTests (ITestOutputHelper output) Assert.Equal (Dim.Absolute (40), v.Height); v.Dispose (); - v = new View { X = frame.X, Y = frame.Y, Text = "v" }; + v = new() { X = frame.X, Y = frame.Y, Text = "v" }; v.Frame = newFrame; Assert.Equal (newFrame, v.Frame); Assert.Equal ( - new Rectangle (0, 0, newFrame.Width, newFrame.Height), + new (0, 0, newFrame.Width, newFrame.Height), v.Viewport ); // With Absolute Viewport *is* deterministic before Layout Assert.Equal (Pos.Absolute (10), v.X); @@ -260,21 +225,39 @@ public class FrameTests (ITestOutputHelper output) v.Dispose (); } - private class TestFrameEventsView : View + [Fact] + public void Frame_Set_Sets () { - public int OnFrameChangedCallCount { get; private set; } - public int FrameChangedEventCallCount { get; private set; } + Rectangle frame = new (1, 2, 3, 4); + View view = new (); + Assert.True (view.NeedsLayout); + Assert.Equal (Rectangle.Empty, view.Frame); - public TestFrameEventsView () - { - FrameChanged += (sender, args) => FrameChangedEventCallCount++; - } + view.Frame = frame; + Assert.Equal (frame, view.Frame); + Assert.False (view.NeedsLayout); - protected override void OnFrameChanged (in Rectangle frame) - { - OnFrameChangedCallCount++; - base.OnFrameChanged (frame); - } + Assert.Equal (view.X, frame.X); + Assert.Equal (view.Y, frame.Y); + Assert.Equal (view.Width, frame.Width); + Assert.Equal (view.Height, frame.Height); + } + + [Fact] + public void FrameChanged_Event_Raised_When_Frame_Changes () + { + // Arrange + var view = new TestFrameEventsView (); + var initialFrame = new Rectangle (0, 0, 10, 10); + var newFrame = new Rectangle (0, 0, 20, 20); + view.Frame = initialFrame; + Assert.Equal (1, view.FrameChangedEventCallCount); + + // Act + view.Frame = newFrame; + + // Assert + Assert.Equal (2, view.FrameChangedEventCallCount); } [Fact] @@ -294,20 +277,28 @@ public class FrameTests (ITestOutputHelper output) Assert.Equal (2, view.OnFrameChangedCallCount); } - [Fact] - public void FrameChanged_Event_Raised_When_Frame_Changes () + private class FrameTestView : View { - // Arrange - var view = new TestFrameEventsView (); - var initialFrame = new Rectangle (0, 0, 10, 10); - var newFrame = new Rectangle (0, 0, 20, 20); - view.Frame = initialFrame; - Assert.Equal (1, view.FrameChangedEventCallCount); + public FrameTestView () + { + X = Pos.Func (() => 10); + Y = Pos.Func (() => 20); + Width = Dim.Func (() => 30); + Height = Dim.Func (() => 40); + } + } - // Act - view.Frame = newFrame; + private class TestFrameEventsView : View + { + public TestFrameEventsView () { FrameChanged += (sender, args) => FrameChangedEventCallCount++; } - // Assert - Assert.Equal (2, view.FrameChangedEventCallCount); + public int FrameChangedEventCallCount { get; private set; } + public int OnFrameChangedCallCount { get; private set; } + + protected override void OnFrameChanged (in Rectangle frame) + { + OnFrameChangedCallCount++; + base.OnFrameChanged (frame); + } } } diff --git a/UnitTests/View/Layout/Pos.AbsoluteTests.cs b/Tests/UnitTestsParallelizable/View/Layout/Pos.AbsoluteTests.cs similarity index 100% rename from UnitTests/View/Layout/Pos.AbsoluteTests.cs rename to Tests/UnitTestsParallelizable/View/Layout/Pos.AbsoluteTests.cs diff --git a/UnitTests/View/Layout/Pos.AlignTests.cs b/Tests/UnitTestsParallelizable/View/Layout/Pos.AlignTests.cs similarity index 100% rename from UnitTests/View/Layout/Pos.AlignTests.cs rename to Tests/UnitTestsParallelizable/View/Layout/Pos.AlignTests.cs diff --git a/UnitTests/View/Layout/Pos.AnchorEndTests.cs b/Tests/UnitTestsParallelizable/View/Layout/Pos.AnchorEndTests.cs similarity index 55% rename from UnitTests/View/Layout/Pos.AnchorEndTests.cs rename to Tests/UnitTestsParallelizable/View/Layout/Pos.AnchorEndTests.cs index f69faca9f..73cd8a354 100644 --- a/UnitTests/View/Layout/Pos.AnchorEndTests.cs +++ b/Tests/UnitTestsParallelizable/View/Layout/Pos.AnchorEndTests.cs @@ -1,10 +1,9 @@ using Xunit.Abstractions; -using static Terminal.Gui.Dim; using static Terminal.Gui.Pos; namespace Terminal.Gui.LayoutTests; -public class PosAnchorEndTests (ITestOutputHelper output) +public class PosAnchorEndTests () { [Fact] public void PosAnchorEnd_Constructor () @@ -170,128 +169,6 @@ public class PosAnchorEndTests (ITestOutputHelper output) Assert.Equal (expectedXPosition, view.Frame.X); } - // This test used to be Dialog_In_Window_With_TextField_And_Button_AnchorEnd in DialogTests. - [Fact] - [SetupFakeDriver] - public void PosAnchorEnd_View_And_Button () - { - ((FakeDriver)Application.Driver!).SetBufferSize (20, 5); - - // Override CM - Button.DefaultShadow = ShadowStyle.None; - - var b = $"{Glyphs.LeftBracket} Ok {Glyphs.RightBracket}"; - - var frame = new FrameView { Width = 18, Height = 3 }; - Assert.Equal (16, frame.Viewport.Width); - - Button btn = null; - - int Btn_Width () { return btn?.Viewport.Width ?? 0; } - - btn = new () { Text = "Ok", X = Pos.AnchorEnd (0) - Pos.Func (Btn_Width) }; - - var view = new View - { - Text = "0123456789abcdefghij", - - // Dim.Fill (1) fills remaining space minus 1 (16 - 1 = 15) - // Dim.Function (Btn_Width) is 6 - // Width should be 15 - 6 = 9 - Width = Dim.Fill (1) - Dim.Func (Btn_Width), - Height = 1 - }; - - frame.Add (btn, view); - frame.BeginInit(); // Needed to enable Border - frame.EndInit(); - frame.Layout (); - - Assert.Equal (6, btn.Viewport.Width); - Assert.Equal (10, btn.Frame.X); // frame.Viewport.Width (16) - btn.Frame.Width (6) = 10 - Assert.Equal (0, btn.Frame.Y); - Assert.Equal (6, btn.Frame.Width); - Assert.Equal (1, btn.Frame.Height); - - Assert.Equal (9, view.Viewport.Width); // frame.Viewport.Width (16) - Dim.Fill (1) - Dim.Function (6) = 9 - Assert.Equal (0, view.Frame.X); - Assert.Equal (0, view.Frame.Y); - Assert.Equal (9, view.Frame.Width); - Assert.Equal (1, view.Frame.Height); - - frame.Draw (); - var expected = $@" -┌────────────────┐ -│012345678 {b}│ -└────────────────┘ -"; - _ = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); - } - - - // TODO: This actually a SetRelativeLayout/LayoutSubViews test and should be moved - // TODO: A new test that calls SetRelativeLayout directly is needed. - [Fact] - [AutoInitShutdown] - public void PosAnchorEnd_Equal_Inside_Window () - { - var viewWidth = 10; - var viewHeight = 1; - - var tv = new TextView - { - X = Pos.AnchorEnd (viewWidth), Y = Pos.AnchorEnd (viewHeight), Width = viewWidth, Height = viewHeight - }; - - var win = new Window (); - - win.Add (tv); - - Toplevel top = new (); - top.Add (win); - RunState rs = Application.Begin (top); - - Assert.Equal (new (0, 0, 80, 25), top.Frame); - Assert.Equal (new (0, 0, 80, 25), win.Frame); - Assert.Equal (new (68, 22, 10, 1), tv.Frame); - Application.End (rs); - top.Dispose (); - } - - //// TODO: This actually a SetRelativeLayout/LayoutSubViews test and should be moved - //// TODO: A new test that calls SetRelativeLayout directly is needed. - //[Fact] - //[AutoInitShutdown] - //public void PosAnchorEnd_Equal_Inside_Window_With_MenuBar_And_StatusBar_On_Toplevel () - //{ - // var viewWidth = 10; - // var viewHeight = 1; - - // var tv = new TextView - // { - // X = Pos.AnchorEnd (viewWidth), Y = Pos.AnchorEnd (viewHeight), Width = viewWidth, Height = viewHeight - // }; - - // var win = new Window (); - - // win.Add (tv); - - // var menu = new MenuBar (); - // var status = new StatusBar (); - // Toplevel top = new (); - // top.Add (win, menu, status); - // RunState rs = Application.Begin (top); - - // Assert.Equal (new (0, 0, 80, 25), top.Frame); - // Assert.Equal (new (0, 0, 80, 1), menu.Frame); - // Assert.Equal (new (0, 24, 80, 1), status.Frame); - // Assert.Equal (new (0, 1, 80, 23), win.Frame); - // Assert.Equal (new (68, 20, 10, 1), tv.Frame); - - // Application.End (rs); - // top.Dispose (); - //} - [Fact] public void PosAnchorEnd_Calculate_ReturnsExpectedValue () { diff --git a/Tests/UnitTestsParallelizable/View/Layout/Pos.CenterTests.cs b/Tests/UnitTestsParallelizable/View/Layout/Pos.CenterTests.cs new file mode 100644 index 000000000..69e0ac81c --- /dev/null +++ b/Tests/UnitTestsParallelizable/View/Layout/Pos.CenterTests.cs @@ -0,0 +1,67 @@ +using Xunit.Abstractions; +using static Terminal.Gui.Pos; + +namespace Terminal.Gui.LayoutTests; + +public class PosCenterTests (ITestOutputHelper output) +{ + private readonly ITestOutputHelper _output = output; + + [Fact] + public void PosCenter_Constructor () + { + var posCenter = new PosCenter (); + Assert.NotNull (posCenter); + } + + [Fact] + public void PosCenter_ToString () + { + var posCenter = new PosCenter (); + var expectedString = "Center"; + + Assert.Equal (expectedString, posCenter.ToString ()); + } + + [Fact] + public void PosCenter_GetAnchor () + { + var posCenter = new PosCenter (); + var width = 50; + int expectedAnchor = width / 2; + + Assert.Equal (expectedAnchor, posCenter.GetAnchor (width)); + } + + [Fact] + public void PosCenter_CreatesCorrectInstance () + { + Pos pos = Center (); + Assert.IsType (pos); + } + + [Theory] + [InlineData (10, 2, 4)] + [InlineData (10, 10, 0)] + [InlineData (10, 11, 0)] + [InlineData (10, 12, -1)] + [InlineData (19, 20, 0)] + public void PosCenter_Calculate_ReturnsExpectedValue (int superviewDimension, int width, int expectedX) + { + var posCenter = new PosCenter (); + int result = posCenter.Calculate (superviewDimension, new DimAbsolute (width), null!, Dimension.Width); + Assert.Equal (expectedX, result); + } + + [Fact] + public void PosCenter_Bigger_Than_SuperView () + { + var superView = new View { Width = 10, Height = 10 }; + var view = new View { X = Center (), Y = Center (), Width = 20, Height = 20 }; + superView.Add (view); + superView.LayoutSubviews (); + + Assert.Equal (-5, view.Frame.Left); + Assert.Equal (-5, view.Frame.Top); + } +} diff --git a/Tests/UnitTestsParallelizable/View/Layout/Pos.CombineTests.cs b/Tests/UnitTestsParallelizable/View/Layout/Pos.CombineTests.cs new file mode 100644 index 000000000..402c95932 --- /dev/null +++ b/Tests/UnitTestsParallelizable/View/Layout/Pos.CombineTests.cs @@ -0,0 +1,36 @@ +using Microsoft.VisualStudio.TestPlatform.Utilities; +using UnitTests; +using Xunit.Abstractions; +using static Terminal.Gui.Dim; +using static Terminal.Gui.Pos; + +namespace Terminal.Gui.LayoutTests; + +public class PosCombineTests (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] + public void PosCombine_Referencing_Same_View () + { + var super = new View { Width = 10, Height = 10, Text = "super" }; + var view1 = new View { Width = 2, Height = 2, Text = "view1" }; + var view2 = new View { Width = 2, Height = 2, Text = "view2" }; + view2.X = Pos.AnchorEnd (0) - (Pos.Right (view2) - Pos.Left (view2)); + + super.Add (view1, view2); + super.BeginInit (); + super.EndInit (); + + Exception exception = Record.Exception (super.LayoutSubviews); + Assert.Null (exception); + Assert.Equal (new (0, 0, 10, 10), super.Frame); + Assert.Equal (new (0, 0, 2, 2), view1.Frame); + Assert.Equal (new (8, 0, 2, 2), view2.Frame); + + super.Dispose (); + } + +} diff --git a/UnitTests/View/Layout/Pos.FuncTests.cs b/Tests/UnitTestsParallelizable/View/Layout/Pos.FuncTests.cs similarity index 100% rename from UnitTests/View/Layout/Pos.FuncTests.cs rename to Tests/UnitTestsParallelizable/View/Layout/Pos.FuncTests.cs diff --git a/UnitTests/View/Layout/Pos.PercentTests.cs b/Tests/UnitTestsParallelizable/View/Layout/Pos.PercentTests.cs similarity index 100% rename from UnitTests/View/Layout/Pos.PercentTests.cs rename to Tests/UnitTestsParallelizable/View/Layout/Pos.PercentTests.cs diff --git a/Tests/UnitTestsParallelizable/View/Layout/Pos.Tests.cs b/Tests/UnitTestsParallelizable/View/Layout/Pos.Tests.cs new file mode 100644 index 000000000..fcfc40456 --- /dev/null +++ b/Tests/UnitTestsParallelizable/View/Layout/Pos.Tests.cs @@ -0,0 +1,135 @@ +namespace Terminal.Gui.LayoutTests; + +public class PosTests +{ + [Fact] + public void PosCombine_Calculate_ReturnsExpectedValue () + { + var posCombine = new PosCombine (AddOrSubtract.Add, new PosAbsolute (5), new PosAbsolute (3)); + int result = posCombine.Calculate (10, new DimAbsolute (2), null, Dimension.None); + Assert.Equal (8, result); + } + + [Fact] + public void PosFactor_Calculate_ReturnsExpectedValue () + { + var posFactor = new PosPercent (50); + int result = posFactor.Calculate (10, new DimAbsolute (2), null, Dimension.None); + Assert.Equal (5, result); + } + + [Fact] + public void PosFunc_Calculate_ReturnsExpectedValue () + { + var posFunc = new PosFunc (() => 5); + int result = posFunc.Calculate (10, new DimAbsolute (2), null, Dimension.None); + Assert.Equal (5, result); + } + + [Fact] + public void PosView_Calculate_ReturnsExpectedValue () + { + var posView = new PosView (new() { Frame = new (5, 5, 10, 10) }, 0); + int result = posView.Calculate (10, new DimAbsolute (2), null, Dimension.None); + Assert.Equal (5, result); + } + + [Fact] + public void PosCombine_DoesNotReturn () + { + var v = new View { Id = "V" }; + + Pos pos = Pos.Left (v); + + Assert.Equal ( + $"View(Side=Left,Target=View(V){v.Frame})", + pos.ToString () + ); + + pos = Pos.X (v); + + Assert.Equal ( + $"View(Side=Left,Target=View(V){v.Frame})", + pos.ToString () + ); + + pos = Pos.Top (v); + + Assert.Equal ( + $"View(Side=Top,Target=View(V){v.Frame})", + pos.ToString () + ); + + pos = Pos.Y (v); + + Assert.Equal ( + $"View(Side=Top,Target=View(V){v.Frame})", + pos.ToString () + ); + + pos = Pos.Right (v); + + Assert.Equal ( + $"View(Side=Right,Target=View(V){v.Frame})", + pos.ToString () + ); + + pos = Pos.Bottom (v); + + Assert.Equal ( + $"View(Side=Bottom,Target=View(V){v.Frame})", + pos.ToString () + ); + } + + [Fact] + public void PosFunction_SetsValue () + { + var text = "Test"; + Pos pos = Pos.Func (() => text.Length); + Assert.Equal ("PosFunc(4)", pos.ToString ()); + + text = "New Test"; + Assert.Equal ("PosFunc(8)", pos.ToString ()); + + text = ""; + Assert.Equal ("PosFunc(0)", pos.ToString ()); + } + + [Fact] + public void PosPercent_Equal () + { + var n1 = 0; + var n2 = 0; + Pos pos1 = Pos.Percent (n1); + Pos pos2 = Pos.Percent (n2); + Assert.Equal (pos1, pos2); + + n1 = n2 = 1; + pos1 = Pos.Percent (n1); + pos2 = Pos.Percent (n2); + Assert.Equal (pos1, pos2); + + n1 = n2 = 50; + pos1 = Pos.Percent (n1); + pos2 = Pos.Percent (n2); + Assert.Equal (pos1, pos2); + + n1 = n2 = 100; + pos1 = Pos.Percent (n1); + pos2 = Pos.Percent (n2); + Assert.Equal (pos1, pos2); + + n1 = 0; + n2 = 1; + pos1 = Pos.Percent (n1); + pos2 = Pos.Percent (n2); + Assert.NotEqual (pos1, pos2); + + n1 = 50; + n2 = 150; + pos1 = Pos.Percent (n1); + pos2 = Pos.Percent (n2); + Assert.NotEqual (pos1, pos2); + } +} diff --git a/UnitTests/View/Layout/Pos.ViewTests.cs b/Tests/UnitTestsParallelizable/View/Layout/Pos.ViewTests.cs similarity index 70% rename from UnitTests/View/Layout/Pos.ViewTests.cs rename to Tests/UnitTestsParallelizable/View/Layout/Pos.ViewTests.cs index b97ae2111..c1531140c 100644 --- a/UnitTests/View/Layout/Pos.ViewTests.cs +++ b/Tests/UnitTestsParallelizable/View/Layout/Pos.ViewTests.cs @@ -1,12 +1,9 @@ -using Xunit.Abstractions; -using static Terminal.Gui.Pos; +using static Terminal.Gui.Pos; namespace Terminal.Gui.LayoutTests; -public class PosViewTests (ITestOutputHelper output) +public class PosViewTests { - private readonly ITestOutputHelper _output = output; - [Fact] public void PosView_Equal () { @@ -28,7 +25,6 @@ public class PosViewTests (ITestOutputHelper output) /// Tests Pos.Left, Pos.X, Pos.Top, Pos.Y, Pos.Right, and Pos.Bottom set operations [Fact] - [TestRespondersDisposed] public void PosView_Side_SetsValue () { string side; // used in format string @@ -245,90 +241,5 @@ public class PosViewTests (ITestOutputHelper output) $"Combine(View(Side={side},Target=View(){testRect}){(testInt < 0 ? '-' : '+')}Absolute({testInt}))", pos.ToString () ); - -#if DEBUG_IDISPOSABLE - - // HACK: Force clean up of Responders to avoid having to Dispose all the Views created above. - View.Instances.Clear (); -#endif - } - - [Fact] - public void PosView_Side_SetToNull_Throws () - { - Assert.Throws (() => X (null)); - Assert.Throws (() => Y (null)); - Assert.Throws (() => Left (null)); - Assert.Throws (() => Right (null)); - Assert.Throws (() => Bottom (null)); - Assert.Throws (() => Top (null)); - } - - // TODO: This actually a SetRelativeLayout/LayoutSubViews test and should be moved - // TODO: A new test that calls SetRelativeLayout directly is needed. - [Fact] - [TestRespondersDisposed] - public void Subtract_Operator () - { - Application.Init (new FakeDriver ()); - - var top = new Toplevel (); - - 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 += (s, a) => - { - while (count > 0) - { - field.NewKeyDownEvent (new (KeyCode.Enter)); - } - - Application.RequestStop (); - }; - - var win = new Window (); - win.Add (view); - win.Add (field); - - top.Add (win); - - Application.Run (top); - top.Dispose (); - Assert.Equal (0, count); - - // Shutdown must be called to safely clean up Application if Init has been called - Application.Shutdown (); } } diff --git a/UnitTests/View/Layout/ScreenToTests.cs b/Tests/UnitTestsParallelizable/View/Layout/ScreenToTests.cs similarity index 97% rename from UnitTests/View/Layout/ScreenToTests.cs rename to Tests/UnitTestsParallelizable/View/Layout/ScreenToTests.cs index c2de37443..174fb2f02 100644 --- a/UnitTests/View/Layout/ScreenToTests.cs +++ b/Tests/UnitTestsParallelizable/View/Layout/ScreenToTests.cs @@ -1,185 +1,8 @@ -using Xunit.Abstractions; - -namespace Terminal.Gui.LayoutTests; +namespace Terminal.Gui.LayoutTests; /// Tests for view coordinate mapping (e.g. etc...). public class ScreenToTests { - private readonly ITestOutputHelper _output; - public ScreenToTests (ITestOutputHelper output) { _output = output; } - - /// - /// Tests that screen to bounds mapping works correctly when the view has no superview and there ARE Adornments on the - /// view. - /// - [Theory] - [InlineData (0, 0, 0, 0, -1, -1)] - [InlineData (0, 0, 1, 1, 0, 0)] - [InlineData (0, 0, 9, 9, 8, 8)] - [InlineData (0, 0, 11, 11, 10, 10)] - [InlineData (1, 1, 0, 0, -2, -2)] - [InlineData (1, 1, 1, 1, -1, -1)] - [InlineData (1, 1, 9, 9, 7, 7)] - [InlineData (1, 1, 11, 11, 9, 9)] - public void ScreenToViewport_NoSuper_HasAdornments (int viewX, int viewY, int x, int y, int expectedX, int expectedY) - { - var view = new View - { - X = viewX, - Y = viewY, - Width = 10, - Height = 10, - BorderStyle = LineStyle.Single - }; - view.Layout (); - - Point actual = view.ScreenToViewport (new (x, y)); - Assert.Equal (expectedX, actual.X); - Assert.Equal (expectedY, actual.Y); - } - - /// - /// Tests that screen to bounds mapping works correctly when the view has no superview and there are no Adornments on - /// the view. - /// - [Theory] - [InlineData (0, 0, 0, 0, 0, 0)] - [InlineData (0, 0, 1, 1, 1, 1)] - [InlineData (0, 0, 9, 9, 9, 9)] - [InlineData (0, 0, 11, 11, 11, 11)] // it's ok for the view to return coordinates outside of its bounds - [InlineData (1, 1, 0, 0, -1, -1)] - [InlineData (1, 1, 1, 1, 0, 0)] - [InlineData (1, 1, 9, 9, 8, 8)] - [InlineData (1, 1, 11, 11, 10, 10)] // it's ok for the view to return coordinates outside of its bounds - public void ScreenToViewport_NoSuper_NoAdornments (int viewX, int viewY, int x, int y, int expectedX, int expectedY) - { - var view = new View { X = viewX, Y = viewY, Width = 10, Height = 10 }; - view.Layout (); - - Point actual = view.ScreenToViewport (new (x, y)); - Assert.Equal (expectedX, actual.X); - Assert.Equal (expectedY, actual.Y); - } - - /// Tests that screen to bounds mapping works correctly when the view has as superview it DOES have Adornments - [Theory] - [InlineData (0, 0, 0, 0, -1, -1)] // it's ok for the view to return coordinates outside of its bounds - [InlineData (0, 0, 1, 1, 0, 0)] - [InlineData (0, 0, 9, 9, 8, 8)] - [InlineData (0, 0, 11, 11, 10, 10)] // it's ok for the view to return coordinates outside of its bounds - [InlineData (1, 1, 0, 0, -2, -2)] - [InlineData (1, 1, 1, 1, -1, -1)] - [InlineData (1, 1, 9, 9, 7, 7)] - [InlineData (1, 1, 11, 11, 9, 9)] // it's ok for the view to return coordinates outside of its bounds - public void ScreenToViewport_SuperHasAdornments (int viewX, int viewY, int x, int y, int expectedX, int expectedY) - { - var super = new View - { - X = 0, - Y = 0, - Width = 10, - Height = 10, - BorderStyle = LineStyle.Single - }; - var view = new View { X = viewX, Y = viewY, Width = 5, Height = 5 }; - super.Add (view); - super.Layout (); - - Point actual = view.ScreenToViewport (new (x, y)); - Assert.Equal (expectedX, actual.X); - Assert.Equal (expectedY, actual.Y); - } - - /// Tests that screen to bounds mapping works correctly when the view has as superview it DOES have Adornments - [Theory] - [InlineData (0, 0, 0, 0, -1, -1)] // it's ok for the view to return coordinates outside of its bounds - [InlineData (0, 0, 1, 1, 0, 0)] - [InlineData (0, 0, 9, 9, 8, 8)] - [InlineData (0, 0, 11, 11, 10, 10)] // it's ok for the view to return coordinates outside of its bounds - [InlineData (1, 1, 0, 0, -2, -2)] - [InlineData (1, 1, 1, 1, -1, -1)] - [InlineData (1, 1, 9, 9, 7, 7)] - [InlineData (1, 1, 11, 11, 9, 9)] // it's ok for the view to return coordinates outside of its bounds - public void ScreenToViewport_SuperHasAdornments_Positive_Viewport (int viewX, int viewY, int x, int y, int expectedX, int expectedY) - { - var super = new View - { - X = 0, - Y = 0, - Width = 10, - Height = 10, - BorderStyle = LineStyle.Single, - }; - var view = new View { X = viewX, Y = viewY, Width = 5, Height = 5 }; - view.SetContentSize (new (6, 6)); - super.Add (view); - super.Layout (); - - view.Viewport = new (1, 1, 5, 5); - - Point actual = view.ScreenToViewport (new (x, y)); - Assert.Equal (expectedX, actual.X); - Assert.Equal (expectedY, actual.Y); - } - - /// Tests that screen to bounds mapping works correctly when the view has as superview it does not have Adornments - [Theory] - [InlineData (0, 0, 0, 0, 0, 0)] - [InlineData (0, 0, 1, 1, 1, 1)] - [InlineData (0, 0, 9, 9, 9, 9)] - [InlineData (0, 0, 11, 11, 11, 11)] // it's ok for the view to return coordinates outside of its bounds - [InlineData (1, 1, 0, 0, -1, -1)] - [InlineData (1, 1, 1, 1, 0, 0)] - [InlineData (1, 1, 9, 9, 8, 8)] - [InlineData (1, 1, 11, 11, 10, 10)] // it's ok for the view to return coordinates outside of its bounds - public void ScreenToViewport_SuperHasNoAdornments (int viewX, int viewY, int x, int y, int expectedX, int expectedY) - { - var super = new View { X = 0, Y = 0, Width = 10, Height = 10 }; - var view = new View { X = viewX, Y = viewY, Width = 5, Height = 5 }; - super.Add (view); - super.Layout (); - - Point actual = view.ScreenToViewport (new (x, y)); - Assert.Equal (expectedX, actual.X); - Assert.Equal (expectedY, actual.Y); - } - - /// Tests that screen to bounds mapping works correctly when the view has as superview it DOES have Adornments - [Theory] - [InlineData (0, 0, 0, 0, -2, -2)] // it's ok for the view to return coordinates outside of its bounds - [InlineData (0, 0, 1, 1, -1, -1)] - [InlineData (0, 0, 9, 9, 7, 7)] - //[InlineData (0, 0, 11, 11, 10, 10)] // it's ok for the view to return coordinates outside of its bounds - //[InlineData (1, 1, 0, 0, -2, -2)] - //[InlineData (1, 1, 1, 1, -1, -1)] - //[InlineData (1, 1, 9, 9, 7, 7)] - //[InlineData (1, 1, 11, 11, 9, 9)] // it's ok for the view to return coordinates outside of its bounds - public void ScreenToViewport_HasAdornments_Positive_Viewport (int viewX, int viewY, int x, int y, int expectedX, int expectedY) - { - var super = new View - { - X = 0, - Y = 0, - Width = 10, - Height = 10, - BorderStyle = LineStyle.Single, - }; - var view = new View - { - X = viewX, Y = viewY, Width = 5, Height = 5, - BorderStyle = LineStyle.Single, - }; - view.SetContentSize (new (10, 10)); - super.Add (view); - super.Layout (); - - view.Viewport = view.Viewport with { Location = new (1, 1) }; - - Point actual = view.ScreenToViewport (new (x, y)); - Assert.Equal (expectedX, actual.X); - Assert.Equal (expectedY, actual.Y); - } - /// /// Tests that screen to view mapping works correctly when the view has no superview and there ARE Adornments on the /// view. @@ -283,4 +106,178 @@ public class ScreenToTests Assert.Equal (expectedX, actual.X); Assert.Equal (expectedY, actual.Y); } + + /// Tests that screen to bounds mapping works correctly when the view has as superview it DOES have Adornments + [Theory] + [InlineData (0, 0, 0, 0, -2, -2)] // it's ok for the view to return coordinates outside of its bounds + [InlineData (0, 0, 1, 1, -1, -1)] + [InlineData (0, 0, 9, 9, 7, 7)] + + //[InlineData (0, 0, 11, 11, 10, 10)] // it's ok for the view to return coordinates outside of its bounds + //[InlineData (1, 1, 0, 0, -2, -2)] + //[InlineData (1, 1, 1, 1, -1, -1)] + //[InlineData (1, 1, 9, 9, 7, 7)] + //[InlineData (1, 1, 11, 11, 9, 9)] // it's ok for the view to return coordinates outside of its bounds + public void ScreenToViewport_HasAdornments_Positive_Viewport (int viewX, int viewY, int x, int y, int expectedX, int expectedY) + { + var super = new View + { + X = 0, + Y = 0, + Width = 10, + Height = 10, + BorderStyle = LineStyle.Single + }; + + var view = new View + { + X = viewX, Y = viewY, Width = 5, Height = 5, + BorderStyle = LineStyle.Single + }; + view.SetContentSize (new (10, 10)); + super.Add (view); + super.Layout (); + + view.Viewport = view.Viewport with { Location = new (1, 1) }; + + Point actual = view.ScreenToViewport (new (x, y)); + Assert.Equal (expectedX, actual.X); + Assert.Equal (expectedY, actual.Y); + } + + /// + /// Tests that screen to bounds mapping works correctly when the view has no superview and there ARE Adornments on the + /// view. + /// + [Theory] + [InlineData (0, 0, 0, 0, -1, -1)] + [InlineData (0, 0, 1, 1, 0, 0)] + [InlineData (0, 0, 9, 9, 8, 8)] + [InlineData (0, 0, 11, 11, 10, 10)] + [InlineData (1, 1, 0, 0, -2, -2)] + [InlineData (1, 1, 1, 1, -1, -1)] + [InlineData (1, 1, 9, 9, 7, 7)] + [InlineData (1, 1, 11, 11, 9, 9)] + public void ScreenToViewport_NoSuper_HasAdornments (int viewX, int viewY, int x, int y, int expectedX, int expectedY) + { + var view = new View + { + X = viewX, + Y = viewY, + Width = 10, + Height = 10, + BorderStyle = LineStyle.Single + }; + view.Layout (); + + Point actual = view.ScreenToViewport (new (x, y)); + Assert.Equal (expectedX, actual.X); + Assert.Equal (expectedY, actual.Y); + } + + /// + /// Tests that screen to bounds mapping works correctly when the view has no superview and there are no Adornments on + /// the view. + /// + [Theory] + [InlineData (0, 0, 0, 0, 0, 0)] + [InlineData (0, 0, 1, 1, 1, 1)] + [InlineData (0, 0, 9, 9, 9, 9)] + [InlineData (0, 0, 11, 11, 11, 11)] // it's ok for the view to return coordinates outside of its bounds + [InlineData (1, 1, 0, 0, -1, -1)] + [InlineData (1, 1, 1, 1, 0, 0)] + [InlineData (1, 1, 9, 9, 8, 8)] + [InlineData (1, 1, 11, 11, 10, 10)] // it's ok for the view to return coordinates outside of its bounds + public void ScreenToViewport_NoSuper_NoAdornments (int viewX, int viewY, int x, int y, int expectedX, int expectedY) + { + var view = new View { X = viewX, Y = viewY, Width = 10, Height = 10 }; + view.Layout (); + + Point actual = view.ScreenToViewport (new (x, y)); + Assert.Equal (expectedX, actual.X); + Assert.Equal (expectedY, actual.Y); + } + + /// Tests that screen to bounds mapping works correctly when the view has as superview it DOES have Adornments + [Theory] + [InlineData (0, 0, 0, 0, -1, -1)] // it's ok for the view to return coordinates outside of its bounds + [InlineData (0, 0, 1, 1, 0, 0)] + [InlineData (0, 0, 9, 9, 8, 8)] + [InlineData (0, 0, 11, 11, 10, 10)] // it's ok for the view to return coordinates outside of its bounds + [InlineData (1, 1, 0, 0, -2, -2)] + [InlineData (1, 1, 1, 1, -1, -1)] + [InlineData (1, 1, 9, 9, 7, 7)] + [InlineData (1, 1, 11, 11, 9, 9)] // it's ok for the view to return coordinates outside of its bounds + public void ScreenToViewport_SuperHasAdornments (int viewX, int viewY, int x, int y, int expectedX, int expectedY) + { + var super = new View + { + X = 0, + Y = 0, + Width = 10, + Height = 10, + BorderStyle = LineStyle.Single + }; + var view = new View { X = viewX, Y = viewY, Width = 5, Height = 5 }; + super.Add (view); + super.Layout (); + + Point actual = view.ScreenToViewport (new (x, y)); + Assert.Equal (expectedX, actual.X); + Assert.Equal (expectedY, actual.Y); + } + + /// Tests that screen to bounds mapping works correctly when the view has as superview it DOES have Adornments + [Theory] + [InlineData (0, 0, 0, 0, -1, -1)] // it's ok for the view to return coordinates outside of its bounds + [InlineData (0, 0, 1, 1, 0, 0)] + [InlineData (0, 0, 9, 9, 8, 8)] + [InlineData (0, 0, 11, 11, 10, 10)] // it's ok for the view to return coordinates outside of its bounds + [InlineData (1, 1, 0, 0, -2, -2)] + [InlineData (1, 1, 1, 1, -1, -1)] + [InlineData (1, 1, 9, 9, 7, 7)] + [InlineData (1, 1, 11, 11, 9, 9)] // it's ok for the view to return coordinates outside of its bounds + public void ScreenToViewport_SuperHasAdornments_Positive_Viewport (int viewX, int viewY, int x, int y, int expectedX, int expectedY) + { + var super = new View + { + X = 0, + Y = 0, + Width = 10, + Height = 10, + BorderStyle = LineStyle.Single + }; + var view = new View { X = viewX, Y = viewY, Width = 5, Height = 5 }; + view.SetContentSize (new (6, 6)); + super.Add (view); + super.Layout (); + + view.Viewport = new (1, 1, 5, 5); + + Point actual = view.ScreenToViewport (new (x, y)); + Assert.Equal (expectedX, actual.X); + Assert.Equal (expectedY, actual.Y); + } + + /// Tests that screen to bounds mapping works correctly when the view has as superview it does not have Adornments + [Theory] + [InlineData (0, 0, 0, 0, 0, 0)] + [InlineData (0, 0, 1, 1, 1, 1)] + [InlineData (0, 0, 9, 9, 9, 9)] + [InlineData (0, 0, 11, 11, 11, 11)] // it's ok for the view to return coordinates outside of its bounds + [InlineData (1, 1, 0, 0, -1, -1)] + [InlineData (1, 1, 1, 1, 0, 0)] + [InlineData (1, 1, 9, 9, 8, 8)] + [InlineData (1, 1, 11, 11, 10, 10)] // it's ok for the view to return coordinates outside of its bounds + public void ScreenToViewport_SuperHasNoAdornments (int viewX, int viewY, int x, int y, int expectedX, int expectedY) + { + var super = new View { X = 0, Y = 0, Width = 10, Height = 10 }; + var view = new View { X = viewX, Y = viewY, Width = 5, Height = 5 }; + super.Add (view); + super.Layout (); + + Point actual = view.ScreenToViewport (new (x, y)); + Assert.Equal (expectedX, actual.X); + Assert.Equal (expectedY, actual.Y); + } } diff --git a/UnitTests/View/Layout/SetLayoutTests.cs b/Tests/UnitTestsParallelizable/View/Layout/SetLayoutTests.cs similarity index 92% rename from UnitTests/View/Layout/SetLayoutTests.cs rename to Tests/UnitTestsParallelizable/View/Layout/SetLayoutTests.cs index d348fe2b1..b521b39fd 100644 --- a/UnitTests/View/Layout/SetLayoutTests.cs +++ b/Tests/UnitTestsParallelizable/View/Layout/SetLayoutTests.cs @@ -1,96 +1,14 @@ -using Xunit.Abstractions; +namespace Terminal.Gui.LayoutTests; -namespace Terminal.Gui.LayoutTests; - -public class SetLayoutTests (ITestOutputHelper output) +public class SetLayoutTests { - private readonly ITestOutputHelper _output = output; - - - [Fact] - [AutoInitShutdown] - public void Screen_Size_Change_Causes_Layout () - { - Application.Top = new (); - - var view = new View - { - X = 3, - Y = 2, - Width = 10, - Height = 1, - Text = "0123456789" - }; - Application.Top.Add (view); - - var rs = Application.Begin (Application.Top); - - Assert.Equal (new (0, 0, 80, 25), new Rectangle (0, 0, View.Driver.Cols, View.Driver.Rows)); - Assert.Equal (new (0, 0, View.Driver.Cols, View.Driver.Rows), Application.Top.Frame); - Assert.Equal (new (0, 0, 80, 25), Application.Top.Frame); - - ((FakeDriver)Application.Driver!).SetBufferSize (20, 10); - Assert.Equal (new (0, 0, View.Driver.Cols, View.Driver.Rows), Application.Top.Frame); - - Assert.Equal (new (0, 0, 20, 10), Application.Top.Frame); - - Application.End (rs); - - } - - [Fact] - [TestRespondersDisposed] - public void LayoutSubviews () - { - var superRect = new Rectangle (0, 0, 100, 100); - var super = new View { Frame = superRect, Text = "super" }; - var v1 = new View { X = 0, Y = 0, Width = 10, Height = 10 }; - - var v2 = new View { X = 10, Y = 10, Width = 10, Height = 10 }; - - super.Add (v1, v2); - - super.LayoutSubviews (); - Assert.Equal (new (0, 0, 10, 10), v1.Frame); - Assert.Equal (new (10, 10, 10, 10), v2.Frame); - super.Dispose (); - } - - [Fact] - public void LayoutSubviews_No_SuperView () - { - var root = new View (); - - var first = new View - { - Id = "first", - X = 1, - Y = 2, - Height = 3, - Width = 4 - }; - root.Add (first); - - var second = new View { Id = "second" }; - root.Add (second); - - second.X = Pos.Right (first) + 1; - - root.LayoutSubviews (); - - Assert.Equal (6, second.Frame.X); - root.Dispose (); - first.Dispose (); - second.Dispose (); - } - [Fact] public void Add_Does_Not_Call_Layout () { var superView = new View { Id = "superView" }; var view = new View { Id = "view" }; - bool layoutStartedRaised = false; - bool layoutCompleteRaised = false; + var layoutStartedRaised = false; + var layoutCompleteRaised = false; superView.SubviewLayout += (sender, e) => layoutStartedRaised = true; superView.SubviewsLaidOut += (sender, e) => layoutCompleteRaised = true; @@ -105,438 +23,9 @@ public class SetLayoutTests (ITestOutputHelper output) Assert.False (layoutStartedRaised); Assert.False (layoutCompleteRaised); - } [Fact] - public void LayoutSubViews_Raises_LayoutStarted_LayoutComplete () - { - var superView = new View { Id = "superView" }; - int layoutStartedRaised = 0; - int layoutCompleteRaised = 0; - superView.SubviewLayout += (sender, e) => layoutStartedRaised++; - superView.SubviewsLaidOut += (sender, e) => layoutCompleteRaised++; - - superView.SetNeedsLayout (); - superView.LayoutSubviews (); - Assert.Equal (1, layoutStartedRaised); - Assert.Equal (1, layoutCompleteRaised); - - superView.BeginInit (); - superView.EndInit (); - superView.LayoutSubviews (); - Assert.Equal (3, layoutStartedRaised); - Assert.Equal (3, layoutCompleteRaised); - } - - [Fact] - public void LayoutSubviews_RootHas_SuperView () - { - var top = new View (); - var root = new View (); - top.Add (root); - - var first = new View - { - Id = "first", - X = 1, - Y = 2, - Height = 3, - Width = 4 - }; - root.Add (first); - - var second = new View { Id = "second" }; - root.Add (second); - - second.X = Pos.Right (first) + 1; - - root.LayoutSubviews (); - - Assert.Equal (6, second.Frame.X); - root.Dispose (); - top.Dispose (); - first.Dispose (); - second.Dispose (); - } - - [Fact] - public void LayoutSubviews_ViewThatRefsSubView_Throws () - { - var root = new View (); - var super = new View (); - root.Add (super); - var sub = new View (); - super.Add (sub); - super.Width = Dim.Width (sub); - Assert.Throws (() => root.Layout ()); - root.Dispose (); - super.Dispose (); - } - - [Fact] - public void LayoutSubviews_Uses_ContentSize () - { - var superView = new View () - { - Width = 5, - Height = 5, - }; - superView.SetContentSize (new (10, 10)); - var view = new View () - { - X = Pos.Center () - }; - superView.Add (view); - - superView.LayoutSubviews (); - - Assert.Equal (5, view.Frame.X); - superView.Dispose (); - } - - // Test OnLayoutStarted/OnLayoutComplete - ensure that they are called at right times - [Fact] - public void LayoutSubviews_LayoutStarted_Complete () - { - var superView = new View (); - var view = new View (); - - var layoutStartedCount = 0; - var layoutCompleteCount = 0; - - var borderLayoutStartedCount = 0; - var borderLayoutCompleteCount = 0; - - view.SubviewLayout += (sender, e) => layoutStartedCount++; - view.SubviewsLaidOut += (sender, e) => layoutCompleteCount++; - - view.Border.SubviewLayout += (sender, e) => borderLayoutStartedCount++; - view.Border.SubviewsLaidOut += (sender, e) => borderLayoutCompleteCount++; - - - superView.Add (view); - Assert.Equal (0, borderLayoutStartedCount); - Assert.Equal (0, borderLayoutCompleteCount); - Assert.Equal (0, layoutStartedCount); - Assert.Equal (0, layoutCompleteCount); - - superView.BeginInit (); - Assert.Equal (0, borderLayoutStartedCount); - Assert.Equal (0, borderLayoutCompleteCount); - Assert.Equal (0, layoutStartedCount); - Assert.Equal (0, layoutCompleteCount); - - superView.EndInit (); - Assert.Equal (1, borderLayoutStartedCount); - Assert.Equal (1, borderLayoutCompleteCount); - Assert.Equal (2, layoutStartedCount); - Assert.Equal (2, layoutCompleteCount); - - superView.LayoutSubviews (); - Assert.Equal (1, borderLayoutStartedCount); - Assert.Equal (1, borderLayoutCompleteCount); - Assert.Equal (3, layoutStartedCount); - Assert.Equal (3, layoutCompleteCount); - - superView.SetNeedsLayout (); - superView.LayoutSubviews (); - Assert.Equal (1, borderLayoutStartedCount); - Assert.Equal (1, borderLayoutCompleteCount); - Assert.Equal (4, layoutStartedCount); - Assert.Equal (4, layoutCompleteCount); - - superView.Dispose (); - } - - [Fact] - public void LayoutSubviews_Honors_IsLayoutNeeded () - { - // No adornment subviews - var superView = new View (); - var view = new View (); - - var layoutStartedCount = 0; - var layoutCompleteCount = 0; - - var borderLayoutStartedCount = 0; - var borderLayoutCompleteCount = 0; - - view.SubviewLayout += (sender, e) => layoutStartedCount++; - view.SubviewsLaidOut += (sender, e) => layoutCompleteCount++; - - view.Border.SubviewLayout += (sender, e) => borderLayoutStartedCount++; - view.Border.SubviewsLaidOut += (sender, e) => borderLayoutCompleteCount++; - - - superView.Add (view); - - superView.LayoutSubviews (); - Assert.Equal (0, borderLayoutStartedCount); - Assert.Equal (0, borderLayoutCompleteCount); - Assert.Equal (1, layoutStartedCount); - Assert.Equal (1, layoutCompleteCount); - - superView.LayoutSubviews (); - Assert.Equal (0, borderLayoutStartedCount); - Assert.Equal (0, borderLayoutCompleteCount); - Assert.Equal (1, layoutStartedCount); - Assert.Equal (1, layoutCompleteCount); - - superView.SetNeedsLayout (); - superView.LayoutSubviews (); - Assert.Equal (0, borderLayoutStartedCount); - Assert.Equal (0, borderLayoutCompleteCount); - Assert.Equal (2, layoutStartedCount); - Assert.Equal (2, layoutCompleteCount); - - // With Border subview - view.Border.Add (new View ()); - superView.LayoutSubviews (); - Assert.Equal (1, borderLayoutStartedCount); - Assert.Equal (1, borderLayoutCompleteCount); - Assert.Equal (3, layoutStartedCount); - Assert.Equal (3, layoutCompleteCount); - - superView.LayoutSubviews (); - Assert.Equal (1, borderLayoutStartedCount); - Assert.Equal (1, borderLayoutCompleteCount); - Assert.Equal (3, layoutStartedCount); - Assert.Equal (3, layoutCompleteCount); - - superView.SetNeedsLayout (); - superView.LayoutSubviews (); - Assert.Equal (2, borderLayoutStartedCount); - Assert.Equal (2, borderLayoutCompleteCount); - Assert.Equal (4, layoutStartedCount); - - superView.Dispose (); - } - - [Fact] - public void Set_X_PosAbsolute_Layout_Is_Implicit () - { - var v = new View (); - - v.X = 1; - Assert.False (v.NeedsLayout); - Assert.Equal (1, v.Frame.X); - - v.X = 2; - Assert.False (v.NeedsLayout); - Assert.Equal (2, v.Frame.X); - - v.X = Pos.Absolute (3); - Assert.False (v.NeedsLayout); - Assert.Equal (3, v.Frame.X); - - v.X = Pos.Absolute (3) + 1; - Assert.False (v.NeedsLayout); - Assert.Equal (4, v.Frame.X); - - v.X = 1 + Pos.Absolute (1) + 1; - Assert.False (v.NeedsLayout); - Assert.Equal (3, v.Frame.X); - - } - - [Fact] - public void Set_X_Non_PosAbsolute_Explicit_Layout_Required () - { - var v = new View (); - - v.X = Pos.Center (); - Assert.True (v.NeedsLayout); - Assert.Equal (0, v.Frame.X); - - v.X = Pos.Percent (50); - Assert.True (v.NeedsLayout); - Assert.Equal (0, v.Frame.X); - - v.X = Pos.Align (Alignment.Center); - Assert.True (v.NeedsLayout); - Assert.Equal (0, v.Frame.X); - - v.X = Pos.Func (() => 10); - Assert.True (v.NeedsLayout); - Assert.Equal (0, v.Frame.X); - - v.X = Pos.AnchorEnd (); - Assert.True (v.NeedsLayout); - Assert.Equal (0, v.Frame.X); - - v.X = Pos.Top (new View ()); - Assert.True (v.NeedsLayout); - Assert.Equal (0, v.Frame.X); - } - - - [Fact] - public void Set_Y_PosAbsolute_Layout_Is_Implicit () - { - var v = new View (); - - v.Y = 1; - Assert.False (v.NeedsLayout); - Assert.Equal (1, v.Frame.Y); - - v.Y = 2; - Assert.False (v.NeedsLayout); - Assert.Equal (2, v.Frame.Y); - - v.Y = Pos.Absolute (3); - Assert.False (v.NeedsLayout); - Assert.Equal (3, v.Frame.Y); - - v.Y = Pos.Absolute (3) + 1; - Assert.False (v.NeedsLayout); - Assert.Equal (4, v.Frame.Y); - - v.Y = 1 + Pos.Absolute (1) + 1; - Assert.False (v.NeedsLayout); - Assert.Equal (3, v.Frame.Y); - - } - - [Fact] - public void Set_Y_Non_PosAbsolute_Explicit_Layout_Required () - { - var v = new View (); - - v.Y = Pos.Center (); - Assert.True (v.NeedsLayout); - Assert.Equal (0, v.Frame.Y); - - v.Y = Pos.Percent (50); - Assert.True (v.NeedsLayout); - Assert.Equal (0, v.Frame.Y); - - v.Y = Pos.Align (Alignment.Center); - Assert.True (v.NeedsLayout); - Assert.Equal (0, v.Frame.Y); - - v.Y = Pos.Func (() => 10); - Assert.True (v.NeedsLayout); - Assert.Equal (0, v.Frame.Y); - - v.Y = Pos.AnchorEnd (); - Assert.True (v.NeedsLayout); - Assert.Equal (0, v.Frame.Y); - - v.Y = Pos.Top (new View ()); - Assert.True (v.NeedsLayout); - Assert.Equal (0, v.Frame.Y); - } - - - [Fact] - public void Set_Width_DimAbsolute_Layout_Is_Implicit () - { - var v = new View (); - - v.Width = 1; - Assert.False (v.NeedsLayout); - Assert.Equal (1, v.Frame.Width); - - v.Width = 2; - Assert.False (v.NeedsLayout); - Assert.Equal (2, v.Frame.Width); - - v.Width = Dim.Absolute (3); - Assert.False (v.NeedsLayout); - Assert.Equal (3, v.Frame.Width); - - v.Width = Dim.Absolute (3) + 1; - Assert.False (v.NeedsLayout); - Assert.Equal (4, v.Frame.Width); - - v.Width = 1 + Dim.Absolute (1) + 1; - Assert.False (v.NeedsLayout); - Assert.Equal (3, v.Frame.Width); - - } - - [Fact] - public void Set_Width_Non_DimAbsolute_Explicit_Layout_Required () - { - var v = new View (); - - v.Width = Dim.Auto(); - Assert.True (v.NeedsLayout); - Assert.Equal (0, v.Frame.Width); - - v.Width = Dim.Percent (50); - Assert.True (v.NeedsLayout); - Assert.Equal (0, v.Frame.Width); - - v.Width = Dim.Fill (); - Assert.True (v.NeedsLayout); - Assert.Equal (0, v.Frame.Width); - - v.Width = Dim.Func (() => 10); - Assert.True (v.NeedsLayout); - Assert.Equal (0, v.Frame.Width); - - v.Width = Dim.Width(new View ()); - Assert.True (v.NeedsLayout); - Assert.Equal (0, v.Frame.Width); - } - - [Fact] - public void Set_Height_DimAbsolute_Layout_Is_Implicit () - { - var v = new View (); - - v.Height = 1; - Assert.False (v.NeedsLayout); - Assert.Equal (1, v.Frame.Height); - - v.Height = 2; - Assert.False (v.NeedsLayout); - Assert.Equal (2, v.Frame.Height); - - v.Height = Dim.Absolute (3); - Assert.False (v.NeedsLayout); - Assert.Equal (3, v.Frame.Height); - - v.Height = Dim.Absolute (3) + 1; - Assert.False (v.NeedsLayout); - Assert.Equal (4, v.Frame.Height); - - v.Height = 1 + Dim.Absolute (1) + 1; - Assert.False (v.NeedsLayout); - Assert.Equal (3, v.Frame.Height); - - } - - [Fact] - public void Set_Height_Non_DimAbsolute_Explicit_Layout_Required () - { - var v = new View (); - - v.Height = Dim.Auto (); - Assert.True (v.NeedsLayout); - Assert.Equal (0, v.Frame.Height); - - v.Height = Dim.Percent (50); - Assert.True (v.NeedsLayout); - Assert.Equal (0, v.Frame.Height); - - v.Height = Dim.Fill (); - Assert.True (v.NeedsLayout); - Assert.Equal (0, v.Frame.Height); - - v.Height = Dim.Func (() => 10); - Assert.True (v.NeedsLayout); - Assert.Equal (0, v.Frame.Height); - - v.Height = Dim.Height (new View ()); - Assert.True (v.NeedsLayout); - Assert.Equal (0, v.Frame.Height); - } - - [Fact] - [TestRespondersDisposed] public void Change_Height_or_Width_MakesComputed () { var v = new View { Frame = Rectangle.Empty }; @@ -546,7 +35,6 @@ public class SetLayoutTests (ITestOutputHelper output) } [Fact] - [TestRespondersDisposed] public void Change_X_or_Y_Absolute () { var frame = new Rectangle (1, 2, 3, 4); @@ -570,7 +58,6 @@ public class SetLayoutTests (ITestOutputHelper output) } [Fact] - [TestRespondersDisposed] public void Change_X_or_Y_MakesComputed () { var v = new View { Frame = Rectangle.Empty }; @@ -580,7 +67,6 @@ public class SetLayoutTests (ITestOutputHelper output) } [Fact] - [TestRespondersDisposed] public void Change_X_Y_Height_Width_Absolute () { var v = new View { Frame = Rectangle.Empty }; @@ -671,6 +157,7 @@ public class SetLayoutTests (ITestOutputHelper output) v = new () { Frame = frame }; v.Layout (); Assert.Equal (frame, v.Frame); + Assert.Equal ( new (0, 0, frame.Width, frame.Height), v.Viewport @@ -684,6 +171,7 @@ public class SetLayoutTests (ITestOutputHelper output) v = new () { Frame = frame, Text = "v" }; v.Layout (); Assert.Equal (frame, v.Frame); + Assert.Equal ( new (0, 0, frame.Width, frame.Height), v.Viewport @@ -725,44 +213,6 @@ public class SetLayoutTests (ITestOutputHelper output) v.Dispose (); } - /// - /// This tests the special case in LayoutSubviews. See https://github.com/gui-cs/Terminal.Gui/issues/2461 - [Fact] - public void Nested_SubViews_Ref_Topmost_SuperView () - { - var superView = new View { Width = 80, Height = 25, Text = "superView" }; - - var subView1 = new View - { - Id = "subView1 - refs superView", - Width = Dim.Width (superView) - 2, // 78 - Height = Dim.Height (superView) - 2 // 23 - }; - superView.Add (subView1); - - var subView1OfSubView1 = new View () - { - Id = "subView1OfSubView1 - refs superView", - Width = Dim.Width (superView) - 4, // 76 - Height = Dim.Height (superView) - 4 // 21 - }; - subView1.Add (subView1OfSubView1); - - superView.Layout (); - - Assert.Equal (80, superView.Frame.Width); - Assert.Equal (25, superView.Frame.Height); - Assert.Equal (78, subView1.Frame.Width); - Assert.Equal (23, subView1.Frame.Height); - //Assert.Equal (76, subView2.Frame.Width); - //Assert.Equal (21, subView2.Frame.Height); - - Assert.Equal (76, subView1OfSubView1.Frame.Width); - Assert.Equal (21, subView1OfSubView1.Frame.Height); - - superView.Dispose (); - } - /// This is an intentionally obtuse test. See https://github.com/gui-cs/Terminal.Gui/issues/2461 [Fact] public void Does_Not_Throw_If_Nested_SubViews_Ref_Topmost_SuperView () @@ -812,4 +262,509 @@ public class SetLayoutTests (ITestOutputHelper output) Assert.Equal (19, v2.Frame.Height); t.Dispose (); } + + [Fact] + public void LayoutSubviews () + { + var superRect = new Rectangle (0, 0, 100, 100); + var super = new View { Frame = superRect, Text = "super" }; + var v1 = new View { X = 0, Y = 0, Width = 10, Height = 10 }; + + var v2 = new View { X = 10, Y = 10, Width = 10, Height = 10 }; + + super.Add (v1, v2); + + super.LayoutSubviews (); + Assert.Equal (new (0, 0, 10, 10), v1.Frame); + Assert.Equal (new (10, 10, 10, 10), v2.Frame); + super.Dispose (); + } + + [Fact] + public void LayoutSubviews_Honors_IsLayoutNeeded () + { + // No adornment subviews + var superView = new View (); + var view = new View (); + + var layoutStartedCount = 0; + var layoutCompleteCount = 0; + + var borderLayoutStartedCount = 0; + var borderLayoutCompleteCount = 0; + + view.SubviewLayout += (sender, e) => layoutStartedCount++; + view.SubviewsLaidOut += (sender, e) => layoutCompleteCount++; + + view.Border.SubviewLayout += (sender, e) => borderLayoutStartedCount++; + view.Border.SubviewsLaidOut += (sender, e) => borderLayoutCompleteCount++; + + superView.Add (view); + + superView.LayoutSubviews (); + Assert.Equal (0, borderLayoutStartedCount); + Assert.Equal (0, borderLayoutCompleteCount); + Assert.Equal (1, layoutStartedCount); + Assert.Equal (1, layoutCompleteCount); + + superView.LayoutSubviews (); + Assert.Equal (0, borderLayoutStartedCount); + Assert.Equal (0, borderLayoutCompleteCount); + Assert.Equal (1, layoutStartedCount); + Assert.Equal (1, layoutCompleteCount); + + superView.SetNeedsLayout (); + superView.LayoutSubviews (); + Assert.Equal (0, borderLayoutStartedCount); + Assert.Equal (0, borderLayoutCompleteCount); + Assert.Equal (2, layoutStartedCount); + Assert.Equal (2, layoutCompleteCount); + + // With Border subview + view.Border.Add (new View ()); + superView.LayoutSubviews (); + Assert.Equal (1, borderLayoutStartedCount); + Assert.Equal (1, borderLayoutCompleteCount); + Assert.Equal (3, layoutStartedCount); + Assert.Equal (3, layoutCompleteCount); + + superView.LayoutSubviews (); + Assert.Equal (1, borderLayoutStartedCount); + Assert.Equal (1, borderLayoutCompleteCount); + Assert.Equal (3, layoutStartedCount); + Assert.Equal (3, layoutCompleteCount); + + superView.SetNeedsLayout (); + superView.LayoutSubviews (); + Assert.Equal (2, borderLayoutStartedCount); + Assert.Equal (2, borderLayoutCompleteCount); + Assert.Equal (4, layoutStartedCount); + + superView.Dispose (); + } + + // Test OnLayoutStarted/OnLayoutComplete - ensure that they are called at right times + [Fact] + public void LayoutSubviews_LayoutStarted_Complete () + { + var superView = new View (); + var view = new View (); + + var layoutStartedCount = 0; + var layoutCompleteCount = 0; + + var borderLayoutStartedCount = 0; + var borderLayoutCompleteCount = 0; + + view.SubviewLayout += (sender, e) => layoutStartedCount++; + view.SubviewsLaidOut += (sender, e) => layoutCompleteCount++; + + view.Border.SubviewLayout += (sender, e) => borderLayoutStartedCount++; + view.Border.SubviewsLaidOut += (sender, e) => borderLayoutCompleteCount++; + + superView.Add (view); + Assert.Equal (0, borderLayoutStartedCount); + Assert.Equal (0, borderLayoutCompleteCount); + Assert.Equal (0, layoutStartedCount); + Assert.Equal (0, layoutCompleteCount); + + superView.BeginInit (); + Assert.Equal (0, borderLayoutStartedCount); + Assert.Equal (0, borderLayoutCompleteCount); + Assert.Equal (0, layoutStartedCount); + Assert.Equal (0, layoutCompleteCount); + + superView.EndInit (); + Assert.Equal (1, borderLayoutStartedCount); + Assert.Equal (1, borderLayoutCompleteCount); + Assert.Equal (2, layoutStartedCount); + Assert.Equal (2, layoutCompleteCount); + + superView.LayoutSubviews (); + Assert.Equal (1, borderLayoutStartedCount); + Assert.Equal (1, borderLayoutCompleteCount); + Assert.Equal (3, layoutStartedCount); + Assert.Equal (3, layoutCompleteCount); + + superView.SetNeedsLayout (); + superView.LayoutSubviews (); + Assert.Equal (1, borderLayoutStartedCount); + Assert.Equal (1, borderLayoutCompleteCount); + Assert.Equal (4, layoutStartedCount); + Assert.Equal (4, layoutCompleteCount); + + superView.Dispose (); + } + + [Fact] + public void LayoutSubviews_No_SuperView () + { + var root = new View (); + + var first = new View + { + Id = "first", + X = 1, + Y = 2, + Height = 3, + Width = 4 + }; + root.Add (first); + + var second = new View { Id = "second" }; + root.Add (second); + + second.X = Pos.Right (first) + 1; + + root.LayoutSubviews (); + + Assert.Equal (6, second.Frame.X); + root.Dispose (); + first.Dispose (); + second.Dispose (); + } + + [Fact] + public void LayoutSubViews_Raises_LayoutStarted_LayoutComplete () + { + var superView = new View { Id = "superView" }; + var layoutStartedRaised = 0; + var layoutCompleteRaised = 0; + superView.SubviewLayout += (sender, e) => layoutStartedRaised++; + superView.SubviewsLaidOut += (sender, e) => layoutCompleteRaised++; + + superView.SetNeedsLayout (); + superView.LayoutSubviews (); + Assert.Equal (1, layoutStartedRaised); + Assert.Equal (1, layoutCompleteRaised); + + superView.BeginInit (); + superView.EndInit (); + superView.LayoutSubviews (); + Assert.Equal (3, layoutStartedRaised); + Assert.Equal (3, layoutCompleteRaised); + } + + [Fact] + public void LayoutSubviews_RootHas_SuperView () + { + var top = new View (); + var root = new View (); + top.Add (root); + + var first = new View + { + Id = "first", + X = 1, + Y = 2, + Height = 3, + Width = 4 + }; + root.Add (first); + + var second = new View { Id = "second" }; + root.Add (second); + + second.X = Pos.Right (first) + 1; + + root.LayoutSubviews (); + + Assert.Equal (6, second.Frame.X); + root.Dispose (); + top.Dispose (); + first.Dispose (); + second.Dispose (); + } + + [Fact] + public void LayoutSubviews_Uses_ContentSize () + { + var superView = new View + { + Width = 5, + Height = 5 + }; + superView.SetContentSize (new (10, 10)); + + var view = new View + { + X = Pos.Center () + }; + superView.Add (view); + + superView.LayoutSubviews (); + + Assert.Equal (5, view.Frame.X); + superView.Dispose (); + } + + [Fact] + public void LayoutSubviews_ViewThatRefsSubView_Throws () + { + var root = new View (); + var super = new View (); + root.Add (super); + var sub = new View (); + super.Add (sub); + super.Width = Dim.Width (sub); + Assert.Throws (() => root.Layout ()); + root.Dispose (); + super.Dispose (); + } + + /// + /// This tests the special case in LayoutSubviews. See https://github.com/gui-cs/Terminal.Gui/issues/2461 + /// + [Fact] + public void Nested_SubViews_Ref_Topmost_SuperView () + { + var superView = new View { Width = 80, Height = 25, Text = "superView" }; + + var subView1 = new View + { + Id = "subView1 - refs superView", + Width = Dim.Width (superView) - 2, // 78 + Height = Dim.Height (superView) - 2 // 23 + }; + superView.Add (subView1); + + var subView1OfSubView1 = new View + { + Id = "subView1OfSubView1 - refs superView", + Width = Dim.Width (superView) - 4, // 76 + Height = Dim.Height (superView) - 4 // 21 + }; + subView1.Add (subView1OfSubView1); + + superView.Layout (); + + Assert.Equal (80, superView.Frame.Width); + Assert.Equal (25, superView.Frame.Height); + Assert.Equal (78, subView1.Frame.Width); + Assert.Equal (23, subView1.Frame.Height); + + //Assert.Equal (76, subView2.Frame.Width); + //Assert.Equal (21, subView2.Frame.Height); + + Assert.Equal (76, subView1OfSubView1.Frame.Width); + Assert.Equal (21, subView1OfSubView1.Frame.Height); + + superView.Dispose (); + } + + [Fact] + public void Set_Height_DimAbsolute_Layout_Is_Implicit () + { + var v = new View (); + + v.Height = 1; + Assert.False (v.NeedsLayout); + Assert.Equal (1, v.Frame.Height); + + v.Height = 2; + Assert.False (v.NeedsLayout); + Assert.Equal (2, v.Frame.Height); + + v.Height = Dim.Absolute (3); + Assert.False (v.NeedsLayout); + Assert.Equal (3, v.Frame.Height); + + v.Height = Dim.Absolute (3) + 1; + Assert.False (v.NeedsLayout); + Assert.Equal (4, v.Frame.Height); + + v.Height = 1 + Dim.Absolute (1) + 1; + Assert.False (v.NeedsLayout); + Assert.Equal (3, v.Frame.Height); + } + + [Fact] + public void Set_Height_Non_DimAbsolute_Explicit_Layout_Required () + { + var v = new View (); + + v.Height = Dim.Auto (); + Assert.True (v.NeedsLayout); + Assert.Equal (0, v.Frame.Height); + + v.Height = Dim.Percent (50); + Assert.True (v.NeedsLayout); + Assert.Equal (0, v.Frame.Height); + + v.Height = Dim.Fill (); + Assert.True (v.NeedsLayout); + Assert.Equal (0, v.Frame.Height); + + v.Height = Dim.Func (() => 10); + Assert.True (v.NeedsLayout); + Assert.Equal (0, v.Frame.Height); + + v.Height = Dim.Height (new ()); + Assert.True (v.NeedsLayout); + Assert.Equal (0, v.Frame.Height); + } + + [Fact] + public void Set_Width_DimAbsolute_Layout_Is_Implicit () + { + var v = new View (); + + v.Width = 1; + Assert.False (v.NeedsLayout); + Assert.Equal (1, v.Frame.Width); + + v.Width = 2; + Assert.False (v.NeedsLayout); + Assert.Equal (2, v.Frame.Width); + + v.Width = Dim.Absolute (3); + Assert.False (v.NeedsLayout); + Assert.Equal (3, v.Frame.Width); + + v.Width = Dim.Absolute (3) + 1; + Assert.False (v.NeedsLayout); + Assert.Equal (4, v.Frame.Width); + + v.Width = 1 + Dim.Absolute (1) + 1; + Assert.False (v.NeedsLayout); + Assert.Equal (3, v.Frame.Width); + } + + [Fact] + public void Set_Width_Non_DimAbsolute_Explicit_Layout_Required () + { + var v = new View (); + + v.Width = Dim.Auto (); + Assert.True (v.NeedsLayout); + Assert.Equal (0, v.Frame.Width); + + v.Width = Dim.Percent (50); + Assert.True (v.NeedsLayout); + Assert.Equal (0, v.Frame.Width); + + v.Width = Dim.Fill (); + Assert.True (v.NeedsLayout); + Assert.Equal (0, v.Frame.Width); + + v.Width = Dim.Func (() => 10); + Assert.True (v.NeedsLayout); + Assert.Equal (0, v.Frame.Width); + + v.Width = Dim.Width (new ()); + Assert.True (v.NeedsLayout); + Assert.Equal (0, v.Frame.Width); + } + + [Fact] + public void Set_X_Non_PosAbsolute_Explicit_Layout_Required () + { + var v = new View (); + + v.X = Pos.Center (); + Assert.True (v.NeedsLayout); + Assert.Equal (0, v.Frame.X); + + v.X = Pos.Percent (50); + Assert.True (v.NeedsLayout); + Assert.Equal (0, v.Frame.X); + + v.X = Pos.Align (Alignment.Center); + Assert.True (v.NeedsLayout); + Assert.Equal (0, v.Frame.X); + + v.X = Pos.Func (() => 10); + Assert.True (v.NeedsLayout); + Assert.Equal (0, v.Frame.X); + + v.X = Pos.AnchorEnd (); + Assert.True (v.NeedsLayout); + Assert.Equal (0, v.Frame.X); + + v.X = Pos.Top (new ()); + Assert.True (v.NeedsLayout); + Assert.Equal (0, v.Frame.X); + } + + [Fact] + public void Set_X_PosAbsolute_Layout_Is_Implicit () + { + var v = new View (); + + v.X = 1; + Assert.False (v.NeedsLayout); + Assert.Equal (1, v.Frame.X); + + v.X = 2; + Assert.False (v.NeedsLayout); + Assert.Equal (2, v.Frame.X); + + v.X = Pos.Absolute (3); + Assert.False (v.NeedsLayout); + Assert.Equal (3, v.Frame.X); + + v.X = Pos.Absolute (3) + 1; + Assert.False (v.NeedsLayout); + Assert.Equal (4, v.Frame.X); + + v.X = 1 + Pos.Absolute (1) + 1; + Assert.False (v.NeedsLayout); + Assert.Equal (3, v.Frame.X); + } + + [Fact] + public void Set_Y_Non_PosAbsolute_Explicit_Layout_Required () + { + var v = new View (); + + v.Y = Pos.Center (); + Assert.True (v.NeedsLayout); + Assert.Equal (0, v.Frame.Y); + + v.Y = Pos.Percent (50); + Assert.True (v.NeedsLayout); + Assert.Equal (0, v.Frame.Y); + + v.Y = Pos.Align (Alignment.Center); + Assert.True (v.NeedsLayout); + Assert.Equal (0, v.Frame.Y); + + v.Y = Pos.Func (() => 10); + Assert.True (v.NeedsLayout); + Assert.Equal (0, v.Frame.Y); + + v.Y = Pos.AnchorEnd (); + Assert.True (v.NeedsLayout); + Assert.Equal (0, v.Frame.Y); + + v.Y = Pos.Top (new ()); + Assert.True (v.NeedsLayout); + Assert.Equal (0, v.Frame.Y); + } + + [Fact] + public void Set_Y_PosAbsolute_Layout_Is_Implicit () + { + var v = new View (); + + v.Y = 1; + Assert.False (v.NeedsLayout); + Assert.Equal (1, v.Frame.Y); + + v.Y = 2; + Assert.False (v.NeedsLayout); + Assert.Equal (2, v.Frame.Y); + + v.Y = Pos.Absolute (3); + Assert.False (v.NeedsLayout); + Assert.Equal (3, v.Frame.Y); + + v.Y = Pos.Absolute (3) + 1; + Assert.False (v.NeedsLayout); + Assert.Equal (4, v.Frame.Y); + + v.Y = 1 + Pos.Absolute (1) + 1; + Assert.False (v.NeedsLayout); + Assert.Equal (3, v.Frame.Y); + } } diff --git a/UnitTests/View/Layout/SetRelativeLayoutTests.cs b/Tests/UnitTestsParallelizable/View/Layout/SetRelativeLayoutTests.cs similarity index 98% rename from UnitTests/View/Layout/SetRelativeLayoutTests.cs rename to Tests/UnitTestsParallelizable/View/Layout/SetRelativeLayoutTests.cs index 547700de2..3ac89f638 100644 --- a/UnitTests/View/Layout/SetRelativeLayoutTests.cs +++ b/Tests/UnitTestsParallelizable/View/Layout/SetRelativeLayoutTests.cs @@ -1,13 +1,11 @@ -using Xunit.Abstractions; +using UnitTests; +using Xunit.Abstractions; using static Terminal.Gui.Dim; namespace Terminal.Gui.LayoutTests; public class SetRelativeLayoutTests { - private readonly ITestOutputHelper _output; - public SetRelativeLayoutTests (ITestOutputHelper output) { _output = output; } - [Fact] public void AbsolutePosDim_DontChange () { @@ -233,7 +231,6 @@ public class SetRelativeLayoutTests } [Fact] - [TestRespondersDisposed] public void PosCombine_Plus_Absolute () { var superView = new View { Width = 10, Height = 10 }; diff --git a/UnitTests/View/Layout/ToScreenTests.cs b/Tests/UnitTestsParallelizable/View/Layout/ToScreenTests.cs similarity index 59% rename from UnitTests/View/Layout/ToScreenTests.cs rename to Tests/UnitTestsParallelizable/View/Layout/ToScreenTests.cs index eed7b12f1..714cd715c 100644 --- a/UnitTests/View/Layout/ToScreenTests.cs +++ b/Tests/UnitTestsParallelizable/View/Layout/ToScreenTests.cs @@ -1,18 +1,14 @@ using Xunit.Abstractions; -using static System.Net.Mime.MediaTypeNames; namespace Terminal.Gui.LayoutTests; /// -/// Test the and methods. -/// DOES NOT TEST Adornment.xxxToScreen methods. Those are in ./Adornment/ToScreenTests.cs +/// Test the and methods. +/// DOES NOT TEST Adornment.xxxToScreen methods. Those are in ./Adornment/ToScreenTests.cs /// /// -public class ToScreenTests (ITestOutputHelper output) +public class ToScreenTests () { - private readonly ITestOutputHelper _output = output; - - // Test FrameToScreen [Theory] [InlineData (0, 0, 0, 0)] @@ -56,6 +52,7 @@ public class ToScreenTests (ITestOutputHelper output) Rectangle actual = view.FrameToScreen (); Assert.Equal (expected, actual); } + [Theory] [InlineData (0, 0)] [InlineData (1, 1)] @@ -71,7 +68,7 @@ public class ToScreenTests (ITestOutputHelper output) view.Frame = frame; // Act - var screen = view.FrameToScreen (); + Rectangle screen = view.FrameToScreen (); // Assert Assert.Equal (expectedX, screen.X); @@ -93,7 +90,7 @@ public class ToScreenTests (ITestOutputHelper output) view.Frame = frame; // Act - var screen = view.FrameToScreen (); + Rectangle screen = view.FrameToScreen (); // Assert Assert.Equal (expectedX, screen.X); @@ -114,7 +111,7 @@ public class ToScreenTests (ITestOutputHelper output) view.BorderStyle = LineStyle.Single; view.Frame = frame; - var subviewOfBorder = new View () + var subviewOfBorder = new View { X = 1, // screen should be 1 Y = 0, @@ -127,7 +124,7 @@ public class ToScreenTests (ITestOutputHelper output) view.EndInit (); // Act - var screen = subviewOfBorder.FrameToScreen (); + Rectangle screen = subviewOfBorder.FrameToScreen (); // Assert Assert.Equal (expectedX, screen.X); @@ -148,16 +145,16 @@ public class ToScreenTests (ITestOutputHelper output) adornment.Frame = adornmentFrame; adornment.Thickness = new (1); - var subviewOfAdornment = new View () + var subviewOfAdornment = new View { Id = "subviewOfAdornment", X = 1, // screen should be 1 Y = 0, Width = 1, - Height = 1, + Height = 1 }; - var subviewOfSubview = new View () + var subviewOfSubview = new View { Id = "subviewOfSubview", X = 2, // screen should be 3 (the subviewOfAdornment location is 1) @@ -172,7 +169,7 @@ public class ToScreenTests (ITestOutputHelper output) adornment.EndInit (); // Act - var screen = subviewOfSubview.FrameToScreen (); + Rectangle screen = subviewOfSubview.FrameToScreen (); // Assert Assert.Equal (expectedX, screen.X); @@ -189,7 +186,7 @@ public class ToScreenTests (ITestOutputHelper output) // Arrange var frame = new Rectangle (x, 0, 10, 10); - var superView = new View () + var superView = new View { X = 0, Y = 0, @@ -204,7 +201,7 @@ public class ToScreenTests (ITestOutputHelper output) superView.LayoutSubviews (); // Act - var screen = view.FrameToScreen (); + Rectangle screen = view.FrameToScreen (); // Assert Assert.Equal (expectedX, screen.X); @@ -221,7 +218,7 @@ public class ToScreenTests (ITestOutputHelper output) // Arrange var frame = new Rectangle (x, 0, 10, 10); - var superView = new View () + var superView = new View { X = 0, Y = 0, @@ -237,7 +234,7 @@ public class ToScreenTests (ITestOutputHelper output) superView.LayoutSubviews (); // Act - var screen = view.FrameToScreen (); + Rectangle screen = view.FrameToScreen (); // Assert Assert.Equal (expectedX, screen.X); @@ -254,7 +251,7 @@ public class ToScreenTests (ITestOutputHelper output) // Arrange var frame = new Rectangle (x, 0, 10, 10); - var superSuperView = new View () + var superSuperView = new View { X = 0, Y = 0, @@ -262,7 +259,7 @@ public class ToScreenTests (ITestOutputHelper output) Width = Dim.Fill () }; - var superView = new View () + var superView = new View { X = 0, Y = 0, @@ -279,7 +276,7 @@ public class ToScreenTests (ITestOutputHelper output) superView.LayoutSubviews (); // Act - var screen = view.FrameToScreen (); + Rectangle screen = view.FrameToScreen (); // Assert Assert.Equal (expectedX, screen.X); @@ -296,7 +293,7 @@ public class ToScreenTests (ITestOutputHelper output) // Arrange var frame = new Rectangle (x, 0, 10, 10); - var superSuperView = new View () + var superSuperView = new View { X = 0, Y = 0, @@ -305,7 +302,7 @@ public class ToScreenTests (ITestOutputHelper output) }; superSuperView.BorderStyle = LineStyle.Single; - var superView = new View () + var superView = new View { X = 0, Y = 0, @@ -323,7 +320,7 @@ public class ToScreenTests (ITestOutputHelper output) superSuperView.Layout (); // Act - var screen = view.FrameToScreen (); + Rectangle screen = view.FrameToScreen (); // Assert Assert.Equal (expectedX, screen.X); @@ -345,18 +342,16 @@ public class ToScreenTests (ITestOutputHelper output) view.SetContentSize (new (20, 20)); Point testPoint = new (0, 0); - Assert.Equal (new Point (1, 1), view.ContentToScreen (testPoint)); + Assert.Equal (new (1, 1), view.ContentToScreen (testPoint)); } [Theory] [InlineData (0, 0, 1)] [InlineData (1, 0, 2)] [InlineData (-1, 0, 0)] - [InlineData (0, 1, 2)] [InlineData (1, 1, 3)] [InlineData (-1, 1, 1)] - [InlineData (0, -1, 0)] [InlineData (1, -1, 1)] [InlineData (-1, -1, -1)] @@ -372,7 +367,7 @@ public class ToScreenTests (ITestOutputHelper output) view.BorderStyle = LineStyle.Single; // Act - var screen = view.ContentToScreen (new (contentX, 0)); + Point screen = view.ContentToScreen (new (contentX, 0)); // Assert Assert.Equal (expectedX, screen.X); @@ -383,12 +378,10 @@ public class ToScreenTests (ITestOutputHelper output) [InlineData (1, 0, 1)] [InlineData (-1, 0, -1)] [InlineData (11, 0, 11)] - [InlineData (0, 1, 1)] [InlineData (1, 1, 2)] [InlineData (-1, 1, 0)] [InlineData (11, 1, 12)] - [InlineData (0, -1, -1)] [InlineData (1, -1, 0)] [InlineData (-1, -1, -2)] @@ -399,7 +392,7 @@ public class ToScreenTests (ITestOutputHelper output) // Arrange var frame = new Rectangle (frameX, 0, 10, 10); - var superView = new View () + var superView = new View { X = 0, Y = 0, @@ -415,7 +408,7 @@ public class ToScreenTests (ITestOutputHelper output) superView.LayoutSubviews (); // Act - var screen = view.ContentToScreen (new (contentX, 0)); + Point screen = view.ContentToScreen (new (contentX, 0)); // Assert Assert.Equal (expectedX, screen.X); @@ -570,7 +563,6 @@ public class ToScreenTests (ITestOutputHelper output) // Assert.Equal (expectedX, screen.X); //} - //[Theory] //[InlineData (0, 0, 3)] //[InlineData (1, 0, 4)] @@ -640,12 +632,12 @@ public class ToScreenTests (ITestOutputHelper output) }; view.Layout (); - Rectangle testRect = new Rectangle (0, 0, 1, 1); - Assert.Equal (new Point (0, 0), view.ViewportToScreen (testRect).Location); - view.Viewport = view.Viewport with { Location = new Point (1, 1) }; + var testRect = new Rectangle (0, 0, 1, 1); + Assert.Equal (new (0, 0), view.ViewportToScreen (testRect).Location); + view.Viewport = view.Viewport with { Location = new (1, 1) }; - Assert.Equal (new Rectangle (1, 1, 10, 10), view.Viewport); - Assert.Equal (new Point (0, 0), view.ViewportToScreen (testRect).Location); + Assert.Equal (new (1, 1, 10, 10), view.Viewport); + Assert.Equal (new (0, 0), view.ViewportToScreen (testRect).Location); } [Theory] @@ -664,7 +656,7 @@ public class ToScreenTests (ITestOutputHelper output) view.Layout (); // Act - var screen = view.ViewportToScreen (new Point (viewportX, 0)); + Point screen = view.ViewportToScreen (new Point (viewportX, 0)); // Assert Assert.Equal (expectedX, screen.X); @@ -675,12 +667,10 @@ public class ToScreenTests (ITestOutputHelper output) [InlineData (1, 0, 2)] [InlineData (-1, 0, 0)] [InlineData (11, 0, 12)] - [InlineData (0, 1, 2)] [InlineData (1, 1, 3)] [InlineData (-1, 1, 1)] [InlineData (11, 1, 13)] - [InlineData (0, -1, 0)] [InlineData (1, -1, 1)] [InlineData (-1, -1, -1)] @@ -696,7 +686,7 @@ public class ToScreenTests (ITestOutputHelper output) view.Frame = frame; // Act - var screen = view.ViewportToScreen (new Point (viewportX, 0)); + Point screen = view.ViewportToScreen (new Point (viewportX, 0)); // Assert Assert.Equal (expectedX, screen.X); @@ -707,12 +697,10 @@ public class ToScreenTests (ITestOutputHelper output) [InlineData (1, 0, 1)] [InlineData (-1, 0, -1)] [InlineData (11, 0, 11)] - [InlineData (0, 1, 1)] [InlineData (1, 1, 2)] [InlineData (-1, 1, 0)] [InlineData (11, 1, 12)] - [InlineData (0, -1, -1)] [InlineData (1, -1, 0)] [InlineData (-1, -1, -2)] @@ -723,7 +711,7 @@ public class ToScreenTests (ITestOutputHelper output) // Arrange var frame = new Rectangle (frameX, 0, 10, 10); - var superView = new View () + var superView = new View { X = 0, Y = 0, @@ -738,7 +726,7 @@ public class ToScreenTests (ITestOutputHelper output) superView.LayoutSubviews (); // Act - var screen = view.ViewportToScreen (new Point (viewportX, 0)); + Point screen = view.ViewportToScreen (new Point (viewportX, 0)); // Assert Assert.Equal (expectedX, screen.X); @@ -749,12 +737,10 @@ public class ToScreenTests (ITestOutputHelper output) [InlineData (1, 0, 2)] [InlineData (-1, 0, 0)] [InlineData (11, 0, 12)] - [InlineData (0, 1, 2)] [InlineData (1, 1, 3)] [InlineData (-1, 1, 1)] [InlineData (11, 1, 13)] - [InlineData (0, -1, 0)] [InlineData (1, -1, 1)] [InlineData (-1, -1, -1)] @@ -765,7 +751,7 @@ public class ToScreenTests (ITestOutputHelper output) // Arrange var frame = new Rectangle (frameX, 0, 10, 10); - var superView = new View () + var superView = new View { X = 0, Y = 0, @@ -781,7 +767,7 @@ public class ToScreenTests (ITestOutputHelper output) superView.LayoutSubviews (); // Act - var screen = view.ViewportToScreen (new Point (viewportX, 0)); + Point screen = view.ViewportToScreen (new Point (viewportX, 0)); // Assert Assert.Equal (expectedX, screen.X); @@ -792,12 +778,10 @@ public class ToScreenTests (ITestOutputHelper output) [InlineData (1, 0, 1)] [InlineData (-1, 0, -1)] [InlineData (11, 0, 11)] - [InlineData (0, 1, 1)] [InlineData (1, 1, 2)] [InlineData (-1, 1, 0)] [InlineData (11, 1, 12)] - [InlineData (0, -1, -1)] [InlineData (1, -1, 0)] [InlineData (-1, -1, -2)] @@ -808,7 +792,7 @@ public class ToScreenTests (ITestOutputHelper output) // Arrange var frame = new Rectangle (frameX, 0, 10, 10); - var superSuperView = new View () + var superSuperView = new View { X = 0, Y = 0, @@ -816,7 +800,7 @@ public class ToScreenTests (ITestOutputHelper output) Width = Dim.Fill () }; - var superView = new View () + var superView = new View { X = 0, Y = 0, @@ -833,7 +817,7 @@ public class ToScreenTests (ITestOutputHelper output) superView.LayoutSubviews (); // Act - var screen = view.ViewportToScreen (new Point (viewportX, 0)); + Point screen = view.ViewportToScreen (new Point (viewportX, 0)); // Assert Assert.Equal (expectedX, screen.X); @@ -844,12 +828,10 @@ public class ToScreenTests (ITestOutputHelper output) [InlineData (1, 0, 3)] [InlineData (-1, 0, 1)] [InlineData (11, 0, 13)] - [InlineData (0, 1, 3)] [InlineData (1, 1, 4)] [InlineData (-1, 1, 2)] [InlineData (11, 1, 14)] - [InlineData (0, -1, 1)] [InlineData (1, -1, 2)] [InlineData (-1, -1, 0)] @@ -860,7 +842,7 @@ public class ToScreenTests (ITestOutputHelper output) // Arrange var frame = new Rectangle (frameX, 0, 10, 10); - var superSuperView = new View () + var superSuperView = new View { X = 0, Y = 0, @@ -869,7 +851,7 @@ public class ToScreenTests (ITestOutputHelper output) }; superSuperView.BorderStyle = LineStyle.Single; - var superView = new View () + var superView = new View { X = 0, Y = 0, @@ -887,24 +869,21 @@ public class ToScreenTests (ITestOutputHelper output) superView.Layout (); // Act - var screen = view.ViewportToScreen (new Point (viewportX, 0)); + Point screen = view.ViewportToScreen (new Point (viewportX, 0)); // Assert Assert.Equal (expectedX, screen.X); } - [Theory] [InlineData (0, 0, 2)] [InlineData (1, 0, 3)] [InlineData (-1, 0, 1)] [InlineData (11, 0, 13)] - [InlineData (0, 1, 3)] [InlineData (1, 1, 4)] [InlineData (-1, 1, 2)] [InlineData (11, 1, 14)] - [InlineData (0, -1, 1)] [InlineData (1, -1, 2)] [InlineData (-1, -1, 0)] @@ -915,7 +894,7 @@ public class ToScreenTests (ITestOutputHelper output) // Arrange var frame = new Rectangle (frameX, 0, 10, 10); - var superSuperView = new View () + var superSuperView = new View { X = 0, Y = 0, @@ -924,7 +903,7 @@ public class ToScreenTests (ITestOutputHelper output) }; superSuperView.BorderStyle = LineStyle.Single; - var superView = new View () + var superView = new View { X = 0, Y = 0, @@ -944,300 +923,9 @@ public class ToScreenTests (ITestOutputHelper output) superView.LayoutSubviews (); // Act - var screen = view.ViewportToScreen (new Point (testX, 0)); + Point screen = view.ViewportToScreen (new Point (testX, 0)); // Assert Assert.Equal (expectedX, screen.X); } - - - [Fact] - [AutoInitShutdown] - public void ScreenToView_ViewToScreen_GetViewsUnderMouse_Full_Top () - { - Application.Top = new (); - Application.Top.BorderStyle = LineStyle.Single; - - var view = new View - { - X = 3, - Y = 2, - Width = 10, - Height = 1, - Text = "0123456789" - }; - Application.Top.Add (view); - - var rs = Application.Begin (Application.Top); - - Assert.Equal (new (0, 0, 80, 25), new Rectangle (0, 0, View.Driver.Cols, View.Driver.Rows)); - Assert.Equal (new (0, 0, View.Driver.Cols, View.Driver.Rows), Application.Top.Frame); - Assert.Equal (new (0, 0, 80, 25), Application.Top.Frame); - - ((FakeDriver)Application.Driver!).SetBufferSize (20, 10); - Assert.Equal (new (0, 0, View.Driver.Cols, View.Driver.Rows), Application.Top.Frame); - Assert.Equal (new (0, 0, 20, 10), Application.Top.Frame); - - - _ = TestHelpers.AssertDriverContentsWithFrameAre ( - @" -┌──────────────────┐ -│ │ -│ │ -│ 0123456789 │ -│ │ -│ │ -│ │ -│ │ -│ │ -└──────────────────┘" - , - _output - ); - - // top - Assert.Equal (Point.Empty, Application.Top.ScreenToFrame (new (0, 0))); - Point screen = Application.Top.Margin.ViewportToScreen (new Point (0, 0)); - Assert.Equal (0, screen.X); - Assert.Equal (0, screen.Y); - screen = Application.Top.Border.ViewportToScreen (new Point (0, 0)); - Assert.Equal (0, screen.X); - Assert.Equal (0, screen.Y); - screen = Application.Top.Padding.ViewportToScreen (new Point (0, 0)); - Assert.Equal (1, screen.X); - Assert.Equal (1, screen.Y); - screen = Application.Top.ViewportToScreen (new Point (0, 0)); - Assert.Equal (1, screen.X); - Assert.Equal (1, screen.Y); - screen = Application.Top.ViewportToScreen (new Point (-1, -1)); - Assert.Equal (0, screen.X); - Assert.Equal (0, screen.Y); - var found = View.GetViewsUnderMouse (new Point(0, 0)).LastOrDefault (); - Assert.Equal (Application.Top.Border, found); - - Assert.Equal (0, found.Frame.X); - Assert.Equal (0, found.Frame.Y); - Assert.Equal (new (3, 2), Application.Top.ScreenToFrame (new (3, 2))); - screen = Application.Top.ViewportToScreen (new Point (3, 2)); - Assert.Equal (4, screen.X); - Assert.Equal (3, screen.Y); - found = View.GetViewsUnderMouse (new Point(screen.X, screen.Y)).LastOrDefault (); - Assert.Equal (view, found); - - //Assert.Equal (0, found.FrameToScreen ().X); - //Assert.Equal (0, found.FrameToScreen ().Y); - found = View.GetViewsUnderMouse (new Point(3, 2)).LastOrDefault (); - Assert.Equal (Application.Top, found); - - //Assert.Equal (3, found.FrameToScreen ().X); - //Assert.Equal (2, found.FrameToScreen ().Y); - Assert.Equal (new (13, 2), Application.Top.ScreenToFrame (new (13, 2))); - screen = Application.Top.ViewportToScreen (new Point (12, 2)); - Assert.Equal (13, screen.X); - Assert.Equal (3, screen.Y); - found = View.GetViewsUnderMouse (new Point(screen.X, screen.Y)).LastOrDefault (); - Assert.Equal (view, found); - - //Assert.Equal (9, found.FrameToScreen ().X); - //Assert.Equal (0, found.FrameToScreen ().Y); - screen = Application.Top.ViewportToScreen (new Point (13, 2)); - Assert.Equal (14, screen.X); - Assert.Equal (3, screen.Y); - found = View.GetViewsUnderMouse (new Point(13, 2)).LastOrDefault (); - Assert.Equal (Application.Top, found); - - //Assert.Equal (13, found.FrameToScreen ().X); - //Assert.Equal (2, found.FrameToScreen ().Y); - Assert.Equal (new (14, 3), Application.Top.ScreenToFrame (new (14, 3))); - screen = Application.Top.ViewportToScreen (new Point (14, 3)); - Assert.Equal (15, screen.X); - Assert.Equal (4, screen.Y); - found = View.GetViewsUnderMouse (new Point(14, 3)).LastOrDefault (); - Assert.Equal (Application.Top, found); - - //Assert.Equal (14, found.FrameToScreen ().X); - //Assert.Equal (3, found.FrameToScreen ().Y); - - // view - Assert.Equal (new (-4, -3), view.ScreenToFrame (new (0, 0))); - screen = view.Margin.ViewportToScreen (new Point (-3, -2)); - Assert.Equal (1, screen.X); - Assert.Equal (1, screen.Y); - screen = view.Border.ViewportToScreen (new Point (-3, -2)); - Assert.Equal (1, screen.X); - Assert.Equal (1, screen.Y); - screen = view.Padding.ViewportToScreen (new Point (-3, -2)); - Assert.Equal (1, screen.X); - Assert.Equal (1, screen.Y); - screen = view.ViewportToScreen (new Point (-3, -2)); - Assert.Equal (1, screen.X); - Assert.Equal (1, screen.Y); - screen = view.ViewportToScreen (new Point (-4, -3)); - Assert.Equal (0, screen.X); - Assert.Equal (0, screen.Y); - found = View.GetViewsUnderMouse (new Point(0, 0)).LastOrDefault (); - Assert.Equal (Application.Top.Border, found); - - Assert.Equal (new (-1, -1), view.ScreenToFrame (new (3, 2))); - screen = view.ViewportToScreen (new Point (0, 0)); - Assert.Equal (4, screen.X); - Assert.Equal (3, screen.Y); - found = View.GetViewsUnderMouse (new Point(4, 3)).LastOrDefault (); - Assert.Equal (view, found); - - Assert.Equal (new (9, -1), view.ScreenToFrame (new (13, 2))); - screen = view.ViewportToScreen (new Point (10, 0)); - Assert.Equal (14, screen.X); - Assert.Equal (3, screen.Y); - found = View.GetViewsUnderMouse (new Point(14, 3)).LastOrDefault (); - Assert.Equal (Application.Top, found); - - Assert.Equal (new (10, 0), view.ScreenToFrame (new (14, 3))); - screen = view.ViewportToScreen (new Point (11, 1)); - Assert.Equal (15, screen.X); - Assert.Equal (4, screen.Y); - found = View.GetViewsUnderMouse (new Point(15, 4)).LastOrDefault (); - Assert.Equal (Application.Top, found); - - Application.Top.Dispose (); - Application.ResetState (ignoreDisposed: true); - } - - [Fact] - [AutoInitShutdown] - public void ScreenToView_ViewToScreen_GetViewsUnderMouse_Smaller_Top () - { - Application.Top = new () - { - X = 3, - Y = 2, - Width = 20, - Height = 10, - BorderStyle = LineStyle.Single - }; - - var view = new View - { - X = 3, - Y = 2, - Width = 10, - Height = 1, - Text = "0123456789" - }; - Application.Top.Add (view); - - Application.Begin (Application.Top); - - Assert.Equal (new (0, 0, 80, 25), new Rectangle (0, 0, View.Driver.Cols, View.Driver.Rows)); - Assert.NotEqual (new (0, 0, View.Driver.Cols, View.Driver.Rows), Application.Top.Frame); - Assert.Equal (new (3, 2, 20, 10), Application.Top.Frame); - - ((FakeDriver)Application.Driver!).SetBufferSize (30, 20); - Assert.Equal (new (0, 0, 30, 20), new Rectangle (0, 0, View.Driver.Cols, View.Driver.Rows)); - Assert.NotEqual (new (0, 0, View.Driver.Cols, View.Driver.Rows), Application.Top.Frame); - Assert.Equal (new (3, 2, 20, 10), Application.Top.Frame); - - Rectangle frame = TestHelpers.AssertDriverContentsWithFrameAre ( - @" - ┌──────────────────┐ - │ │ - │ │ - │ 0123456789 │ - │ │ - │ │ - │ │ - │ │ - │ │ - └──────────────────┘" - , - _output - ); - - // mean the output started at col 3 and line 2 - // which result with a width of 23 and a height of 10 on the output - Assert.Equal (new (3, 2, 23, 10), frame); - - // top - Assert.Equal (new (-3, -2), Application.Top.ScreenToFrame (new (0, 0))); - Point screen = Application.Top.Margin.ViewportToScreen (new Point (-3, -2)); - Assert.Equal (0, screen.X); - Assert.Equal (0, screen.Y); - screen = Application.Top.Border.ViewportToScreen (new Point (-3, -2)); - Assert.Equal (0, screen.X); - Assert.Equal (0, screen.Y); - screen = Application.Top.Padding.ViewportToScreen (new Point (-3, -2)); - Assert.Equal (1, screen.X); - Assert.Equal (1, screen.Y); - screen = Application.Top.ViewportToScreen (new Point (-3, -2)); - Assert.Equal (1, screen.X); - Assert.Equal (1, screen.Y); - screen = Application.Top.ViewportToScreen (new Point (-4, -3)); - Assert.Equal (0, screen.X); - Assert.Equal (0, screen.Y); - var found = View.GetViewsUnderMouse (new Point(-4, -3)).LastOrDefault (); - Assert.Null (found); - Assert.Equal (Point.Empty, Application.Top.ScreenToFrame (new (3, 2))); - screen = Application.Top.ViewportToScreen (new Point (0, 0)); - Assert.Equal (4, screen.X); - Assert.Equal (3, screen.Y); - Assert.Equal (Application.Top.Border, View.GetViewsUnderMouse (new Point(3, 2)).LastOrDefault ()); - - //Assert.Equal (0, found.FrameToScreen ().X); - //Assert.Equal (0, found.FrameToScreen ().Y); - Assert.Equal (new (10, 0), Application.Top.ScreenToFrame (new (13, 2))); - screen = Application.Top.ViewportToScreen (new Point (10, 0)); - Assert.Equal (14, screen.X); - Assert.Equal (3, screen.Y); - Assert.Equal (Application.Top.Border, View.GetViewsUnderMouse (new Point(13, 2)).LastOrDefault ()); - - //Assert.Equal (10, found.FrameToScreen ().X); - //Assert.Equal (0, found.FrameToScreen ().Y); - Assert.Equal (new (11, 1), Application.Top.ScreenToFrame (new (14, 3))); - screen = Application.Top.ViewportToScreen (new Point (11, 1)); - Assert.Equal (15, screen.X); - Assert.Equal (4, screen.Y); - Assert.Equal (Application.Top, View.GetViewsUnderMouse (new Point(14, 3)).LastOrDefault ()); - - // view - Assert.Equal (new (-7, -5), view.ScreenToFrame (new (0, 0))); - screen = view.Margin.ViewportToScreen (new Point (-6, -4)); - Assert.Equal (1, screen.X); - Assert.Equal (1, screen.Y); - screen = view.Border.ViewportToScreen (new Point (-6, -4)); - Assert.Equal (1, screen.X); - Assert.Equal (1, screen.Y); - screen = view.Padding.ViewportToScreen (new Point (-6, -4)); - Assert.Equal (1, screen.X); - Assert.Equal (1, screen.Y); - screen = view.ViewportToScreen (new Point (-6, -4)); - Assert.Equal (1, screen.X); - Assert.Equal (1, screen.Y); - Assert.Null (View.GetViewsUnderMouse (new Point(1, 1)).LastOrDefault ()); - Assert.Equal (new (-4, -3), view.ScreenToFrame (new (3, 2))); - screen = view.ViewportToScreen (new Point (-3, -2)); - Assert.Equal (4, screen.X); - Assert.Equal (3, screen.Y); - Assert.Equal (Application.Top, View.GetViewsUnderMouse (new Point(4, 3)).LastOrDefault ()); - Assert.Equal (new (-1, -1), view.ScreenToFrame (new (6, 4))); - screen = view.ViewportToScreen (new Point (0, 0)); - Assert.Equal (7, screen.X); - Assert.Equal (5, screen.Y); - Assert.Equal (view, View.GetViewsUnderMouse (new Point(7, 5)).LastOrDefault ()); - Assert.Equal (new (6, -1), view.ScreenToFrame (new (13, 4))); - screen = view.ViewportToScreen (new Point (7, 0)); - Assert.Equal (14, screen.X); - Assert.Equal (5, screen.Y); - Assert.Equal (view, View.GetViewsUnderMouse (new Point(14, 5)).LastOrDefault ()); - Assert.Equal (new (7, -2), view.ScreenToFrame (new (14, 3))); - screen = view.ViewportToScreen (new Point (8, -1)); - Assert.Equal (15, screen.X); - Assert.Equal (4, screen.Y); - Assert.Equal (Application.Top, View.GetViewsUnderMouse (new Point(15, 4)).LastOrDefault ()); - Assert.Equal (new (16, -2), view.ScreenToFrame (new (23, 3))); - screen = view.ViewportToScreen (new Point (17, -1)); - Assert.Equal (24, screen.X); - Assert.Equal (4, screen.Y); - Assert.Null (View.GetViewsUnderMouse (new Point(24, 4)).LastOrDefault ()); - Application.Top.Dispose (); - } } diff --git a/UnitTests/View/Layout/TopologicalSortTests.cs b/Tests/UnitTestsParallelizable/View/Layout/TopologicalSortTests.cs similarity index 100% rename from UnitTests/View/Layout/TopologicalSortTests.cs rename to Tests/UnitTestsParallelizable/View/Layout/TopologicalSortTests.cs diff --git a/UnitTests/View/Layout/ViewportTests.cs b/Tests/UnitTestsParallelizable/View/Layout/ViewportTests.cs similarity index 100% rename from UnitTests/View/Layout/ViewportTests.cs rename to Tests/UnitTestsParallelizable/View/Layout/ViewportTests.cs diff --git a/Tests/UnitTestsParallelizable/View/SubviewTests.cs b/Tests/UnitTestsParallelizable/View/SubviewTests.cs new file mode 100644 index 000000000..7362ea625 --- /dev/null +++ b/Tests/UnitTestsParallelizable/View/SubviewTests.cs @@ -0,0 +1,330 @@ +using Xunit.Abstractions; + +namespace Terminal.Gui.ViewTests; + +public class SubviewTests +{ + private readonly ITestOutputHelper _output; + public SubviewTests (ITestOutputHelper output) { _output = output; } + + [Fact] + public void Added_Removed () + { + var v = new View { Frame = new Rectangle (0, 0, 10, 24) }; + var t = new View (); + + v.Added += (s, e) => + { + Assert.Same (v.SuperView, e.SuperView); + Assert.Same (t, e.SuperView); + Assert.Same (v, e.SubView); + }; + + v.Removed += (s, e) => + { + Assert.Same (t, e.SuperView); + Assert.Same (v, e.SubView); + Assert.True (v.SuperView == null); + }; + + t.Add (v); + Assert.True (t.Subviews.Count == 1); + + t.Remove (v); + Assert.True (t.Subviews.Count == 0); + + t.Dispose (); + v.Dispose (); + } + + + [Fact] + public void IsAdded_Added_Removed () + { + var top = new Toplevel (); + var view = new View (); + Assert.False (view.IsAdded); + top.Add (view); + Assert.True (view.IsAdded); + top.Remove (view); + Assert.False (view.IsAdded); + + top.Dispose (); + view.Dispose (); + } + + // TODO: Consider a feature that will change the ContentSize to fit the subviews. + [Fact] + public void Add_Does_Not_Impact_ContentSize () + { + var view = new View (); + view.SetContentSize (new Size (1, 1)); + + var subview = new View () + { + X = 10, + Y = 10 + }; + + Assert.Equal (new Size (1, 1), view.GetContentSize ()); + view.Add (subview); + Assert.Equal (new Size (1, 1), view.GetContentSize ()); + } + + [Fact] + public void Remove_Does_Not_Impact_ContentSize () + { + var view = new View (); + view.SetContentSize (new Size (1, 1)); + + var subview = new View () + { + X = 10, + Y = 10 + }; + + Assert.Equal (new Size (1, 1), view.GetContentSize ()); + view.Add (subview); + Assert.Equal (new Size (1, 1), view.GetContentSize ()); + + view.SetContentSize (new Size (5, 5)); + Assert.Equal (new Size (5, 5), view.GetContentSize ()); + + view.Remove (subview); + Assert.Equal (new Size (5, 5), view.GetContentSize ()); + } + + [Fact] + public void MoveSubviewToStart () + { + View superView = new (); + + View subview1 = new View () + { + Id = "subview1" + }; + + View subview2 = new View () + { + Id = "subview2" + }; + + View subview3 = new View () + { + Id = "subview3" + }; + + superView.Add (subview1, subview2, subview3); + + superView.MoveSubviewToStart (subview2); + Assert.Equal(subview2, superView.Subviews [0]); + + superView.MoveSubviewToStart (subview3); + Assert.Equal (subview3, superView.Subviews [0]); + } + + + [Fact] + public void MoveSubviewTowardsFront () + { + View superView = new (); + + View subview1 = new View () + { + Id = "subview1" + }; + + View subview2 = new View () + { + Id = "subview2" + }; + + View subview3 = new View () + { + Id = "subview3" + }; + + superView.Add (subview1, subview2, subview3); + + superView.MoveSubviewTowardsStart (subview2); + Assert.Equal (subview2, superView.Subviews [0]); + + superView.MoveSubviewTowardsStart (subview3); + Assert.Equal (subview3, superView.Subviews [1]); + + // Already at front, what happens? + superView.MoveSubviewTowardsStart (subview2); + Assert.Equal (subview2, superView.Subviews [0]); + } + + [Fact] + public void MoveSubviewToEnd () + { + View superView = new (); + + View subview1 = new View () + { + Id = "subview1" + }; + + View subview2 = new View () + { + Id = "subview2" + }; + + View subview3 = new View () + { + Id = "subview3" + }; + + superView.Add (subview1, subview2, subview3); + + superView.MoveSubviewToEnd (subview1); + Assert.Equal (subview1, superView.Subviews [^1]); + + superView.MoveSubviewToEnd (subview2); + Assert.Equal (subview2, superView.Subviews [^1]); + } + + + [Fact] + public void MoveSubviewTowardsEnd () + { + View superView = new (); + + View subview1 = new View () + { + Id = "subview1" + }; + + View subview2 = new View () + { + Id = "subview2" + }; + + View subview3 = new View () + { + Id = "subview3" + }; + + superView.Add (subview1, subview2, subview3); + + superView.MoveSubviewTowardsEnd (subview2); + Assert.Equal (subview2, superView.Subviews [^1]); + + superView.MoveSubviewTowardsEnd (subview1); + Assert.Equal (subview1, superView.Subviews [1]); + + // Already at end, what happens? + superView.MoveSubviewTowardsEnd (subview2); + Assert.Equal (subview2, superView.Subviews [^1]); + } + + [Fact] + public void IsInHierarchy_ViewIsNull_ReturnsFalse () + { + // Arrange + var start = new View (); + + // Act + var result = View.IsInHierarchy (start, null); + + // Assert + Assert.False (result); + } + + [Fact] + public void IsInHierarchy_StartIsNull_ReturnsFalse () + { + // Arrange + var view = new View (); + + // Act + var result = View.IsInHierarchy (null, view); + + // Assert + Assert.False (result); + } + + [Fact] + public void IsInHierarchy_ViewIsStart_ReturnsTrue () + { + // Arrange + var start = new View (); + + // Act + var result = View.IsInHierarchy (start, start); + + // Assert + Assert.True (result); + } + + [Fact] + public void IsInHierarchy_ViewIsDirectSubview_ReturnsTrue () + { + // Arrange + var start = new View (); + var subview = new View (); + start.Add (subview); + + // Act + var result = View.IsInHierarchy (start, subview); + + // Assert + Assert.True (result); + } + + [Fact] + public void IsInHierarchy_ViewIsNestedSubview_ReturnsTrue () + { + // Arrange + var start = new View (); + var subview = new View (); + var nestedSubview = new View (); + start.Add (subview); + subview.Add (nestedSubview); + + // Act + var result = View.IsInHierarchy (start, nestedSubview); + + // Assert + Assert.True (result); + } + + [Fact] + public void IsInHierarchy_ViewIsNotInHierarchy_ReturnsFalse () + { + // Arrange + var start = new View (); + var subview = new View (); + + // Act + var result = View.IsInHierarchy (start, subview); + + // Assert + Assert.False (result); + } + + [Theory] + [CombinatorialData] + public void IsInHierarchy_ViewIsInAdornments_ReturnsTrue (bool includeAdornments) + { + // Arrange + var start = new View () + { + Id = "start" + }; + var inPadding = new View () + { + Id = "inPadding" + }; + + start.Padding.Add (inPadding); + + // Act + var result = View.IsInHierarchy (start, inPadding, includeAdornments: includeAdornments); + + // Assert + Assert.Equal(includeAdornments, result); + } +} diff --git a/Tests/UnitTestsParallelizable/View/TextTests.cs b/Tests/UnitTestsParallelizable/View/TextTests.cs new file mode 100644 index 000000000..31ca7eea8 --- /dev/null +++ b/Tests/UnitTestsParallelizable/View/TextTests.cs @@ -0,0 +1,194 @@ +using System.Runtime.CompilerServices; +using System.Text; +using Xunit.Abstractions; + +namespace Terminal.Gui.ViewTests; + +/// +/// Tests of the and properties. +/// +public class TextTests () +{ + // TextFormatter.Size should be empty unless DimAuto is set or ContentSize is set + [Theory] + [InlineData ("", 0, 0)] + [InlineData (" ", 0, 0)] + [InlineData ("01234", 0, 0)] + public void TextFormatter_Size_Default (string text, int expectedW, int expectedH) + { + var view = new View (); + view.Text = text; + view.Layout (); + Assert.Equal (new (expectedW, expectedH), view.TextFormatter.ConstrainToSize); + } + + // TextFormatter.Size should track ContentSize (without DimAuto) + [Theory] + [InlineData ("", 1, 1)] + [InlineData (" ", 1, 1)] + [InlineData ("01234", 1, 1)] + public void TextFormatter_Size_Tracks_ContentSize (string text, int expectedW, int expectedH) + { + var view = new View (); + view.SetContentSize (new (1, 1)); + view.Text = text; + view.Layout (); + Assert.Equal (new (expectedW, expectedH), view.TextFormatter.ConstrainToSize); + } + + // Test that View.PreserveTrailingSpaces removes trailing spaces + [Fact] + public void PreserveTrailingSpaces_Removes_Trailing_Spaces () + { + var view = new View { Text = "Hello World " }; + Assert.Equal ("Hello World ", view.TextFormatter.Text); + + view.TextFormatter.WordWrap = true; + view.TextFormatter.ConstrainToSize = new (5, 3); + + view.PreserveTrailingSpaces = false; + Assert.Equal ($"Hello{Environment.NewLine}World", view.TextFormatter.Format ()); + + view.PreserveTrailingSpaces = true; + Assert.Equal ($"Hello{Environment.NewLine} {Environment.NewLine}World", view.TextFormatter.Format ()); + } + + // View.PreserveTrailingSpaces Gets or sets whether trailing spaces at the end of word-wrapped lines are preserved + // or not when is enabled. + // If trailing spaces at the end of wrapped lines will be removed when + // is formatted for display.The default is . + [Fact] + public void PreserveTrailingSpaces_Set_Get () + { + var view = new View { Text = "Hello World" }; + + Assert.False (view.PreserveTrailingSpaces); + + view.PreserveTrailingSpaces = true; + Assert.True (view.PreserveTrailingSpaces); + } + + // Setting TextFormatter DOES NOT update Text + [Fact] + public void SettingTextFormatterDoesNotUpdateText () + { + var view = new View (); + view.TextFormatter.Text = "Hello World"; + + Assert.True (string.IsNullOrEmpty (view.Text)); + } + + // Setting Text updates TextFormatter + [Fact] + public void SettingTextUpdatesTextFormatter () + { + var view = new View { Text = "Hello World" }; + + Assert.Equal ("Hello World", view.Text); + Assert.Equal ("Hello World", view.TextFormatter.Text); + } + + // Setting Text does NOT set the HotKey + [Fact] + public void Text_Does_Not_Set_HotKey () + { + var view = new View { HotKeySpecifier = (Rune)'_', Text = "_Hello World" }; + + Assert.NotEqual (Key.H, view.HotKey); + } + + // Test that TextFormatter is init only + [Fact] + public void TextFormatterIsInitOnly () + { + var view = new View (); + + // Use reflection to ensure the TextFormatter property is `init` only + Assert.Contains ( + typeof (IsExternalInit), + typeof (View).GetMethod ("set_TextFormatter") + .ReturnParameter.GetRequiredCustomModifiers ()); + } + + // Test that the Text property is set correctly. + [Fact] + public void TextProperty () + { + var view = new View { Text = "Hello World" }; + + Assert.Equal ("Hello World", view.Text); + } + + // Test view.UpdateTextFormatterText overridden in a subclass updates TextFormatter.Text + [Fact] + public void UpdateTextFormatterText_Overridden () + { + var view = new TestView { Text = "Hello World" }; + + Assert.Equal ("Hello World", view.Text); + Assert.Equal (">Hello World<", view.TextFormatter.Text); + } + + private class TestView : View + { + protected override void UpdateTextFormatterText () { TextFormatter.Text = $">{Text}<"; } + } + + [Fact] + public void TextDirection_Horizontal_Dims_Correct () + { + // Initializes a view with a vertical direction + var view = new View + { + Text = "01234", + TextDirection = TextDirection.LeftRight_TopBottom, + Width = Dim.Auto (DimAutoStyle.Text), + Height = Dim.Auto (DimAutoStyle.Text) + }; + Assert.True (view.NeedsLayout); + view.Layout (); + Assert.Equal (new (0, 0, 5, 1), view.Frame); + Assert.Equal (new (0, 0, 5, 1), view.Viewport); + + view.BeginInit (); + view.EndInit (); + Assert.Equal (new (0, 0, 5, 1), view.Frame); + Assert.Equal (new (0, 0, 5, 1), view.Viewport); + } + + // BUGBUG: this is a temporary test that helped identify #3469 - It needs to be expanded upon (and renamed) + [Fact] + public void TextDirection_Horizontal_Dims_Correct_WidthAbsolute () + { + var view = new View + { + Text = "01234", + TextDirection = TextDirection.LeftRight_TopBottom, + TextAlignment = Alignment.Center, + Width = 10, + Height = Dim.Auto (DimAutoStyle.Text) + }; + view.BeginInit (); + view.EndInit (); + Assert.Equal (new (0, 0, 10, 1), view.Frame); + Assert.Equal (new (0, 0, 10, 1), view.Viewport); + + Assert.Equal (new (10, 1), view.TextFormatter.ConstrainToSize); + } + + [Fact] + public void TextDirection_Vertical_Dims_Correct () + { + // Initializes a view with a vertical direction + var view = new View + { + TextDirection = TextDirection.TopBottom_LeftRight, + Text = "01234", + Width = Dim.Auto (DimAutoStyle.Text), + Height = Dim.Auto (DimAutoStyle.Text) + }; + view.Layout (); + Assert.Equal (new (0, 0, 1, 5), view.Frame); + Assert.Equal (new (0, 0, 1, 5), view.Viewport); + } +} diff --git a/UnitTests/View/TitleTests.cs b/Tests/UnitTestsParallelizable/View/TitleTests.cs similarity index 100% rename from UnitTests/View/TitleTests.cs rename to Tests/UnitTestsParallelizable/View/TitleTests.cs diff --git a/Tests/UnitTestsParallelizable/coverlet.runsettings b/Tests/UnitTestsParallelizable/coverlet.runsettings new file mode 100644 index 000000000..760e3718a --- /dev/null +++ b/Tests/UnitTestsParallelizable/coverlet.runsettings @@ -0,0 +1,23 @@ + + + + + + + opencover + [UnitTests]*,[UICatalog]*,[coverlet.*.tests?]*,[*]Coverlet.Core* + + + + + false + true + true + true + false + TestResults/ + + + + + \ No newline at end of file diff --git a/Tests/UnitTestsParallelizable/xunit.runner.json b/Tests/UnitTestsParallelizable/xunit.runner.json new file mode 100644 index 000000000..66c35c65f --- /dev/null +++ b/Tests/UnitTestsParallelizable/xunit.runner.json @@ -0,0 +1,6 @@ +{ + "$schema": "https://xunit.net/schema/current/xunit.runner.schema.json", + "parallelizeTestCollections": true, + "parallelizeAssembly": true, + "stopOnFail": false +} \ No newline at end of file diff --git a/UICatalog/Scenarios/Clipping.cs b/UICatalog/Scenarios/Clipping.cs index 4d8a701d6..fddcb8ddb 100644 --- a/UICatalog/Scenarios/Clipping.cs +++ b/UICatalog/Scenarios/Clipping.cs @@ -1,6 +1,5 @@ -using System.Text; -using System.Timers; -using Terminal.Gui; +using Terminal.Gui; +using Timer = System.Timers.Timer; namespace UICatalog.Scenarios; @@ -20,21 +19,22 @@ public class Clipping : Scenario Window app = new () { - Title = GetQuitKeyAndName (), + Title = GetQuitKeyAndName () + //BorderStyle = LineStyle.None }; app.DrawingContent += (s, e) => - { - app!.FillRect (app!.Viewport, Glyphs.Dot); - e.Cancel = true; - }; + { + app!.FillRect (app!.Viewport, Glyphs.Dot); + e.Cancel = true; + }; - var arrangementEditor = new ArrangementEditor () + var arrangementEditor = new ArrangementEditor { X = Pos.AnchorEnd (), Y = 0, - AutoSelectViewToEdit = true, + AutoSelectViewToEdit = true }; app.Add (arrangementEditor); @@ -48,7 +48,7 @@ public class Clipping : Scenario Y = Pos.AnchorEnd (), Width = Dim.Fill (), Id = "tiledProgressBar", - BidirectionalMarquee = true, + BidirectionalMarquee = true }; tiledView1.Add (tiledProgressBar1); @@ -62,6 +62,7 @@ public class Clipping : Scenario Id = "tiledProgressBar", BidirectionalMarquee = true, ProgressBarStyle = ProgressBarStyle.MarqueeBlocks + // BorderStyle = LineStyle.Rounded }; tiledView2.Add (tiledProgressBar2); @@ -84,7 +85,6 @@ public class Clipping : Scenario //}; //overlappedView1.Add (progressBar); - //View overlappedView2 = CreateOverlappedView (2, 32, 4); //View overlappedView3 = CreateOverlappedView (3, 34, 6); @@ -92,7 +92,7 @@ public class Clipping : Scenario //app.Add (overlappedView2); //app.Add (overlappedView3); - Timer progressTimer = new Timer (150) + var progressTimer = new Timer (150) { AutoReset = true }; @@ -109,8 +109,6 @@ public class Clipping : Scenario progressTimer.Stop (); app.Dispose (); Application.Shutdown (); - - return; } private View CreateOverlappedView (int id, Pos x, Pos y) @@ -130,6 +128,7 @@ public class Clipping : Scenario TabStop = TabBehavior.TabGroup, Arrangement = ViewArrangement.Movable | ViewArrangement.Overlapped | ViewArrangement.Resizable }; + return overlapped; } @@ -148,8 +147,9 @@ public class Clipping : Scenario CanFocus = true, // Can't drag without this? BUGBUG TabStop = TabBehavior.TabStop, Arrangement = ViewArrangement.Movable | ViewArrangement.Resizable, - ShadowStyle = ShadowStyle.Transparent, + ShadowStyle = ShadowStyle.Transparent }; + //tiled.Padding.Thickness = new (1); //tiled.Padding.Diagnostics = ViewDiagnosticFlags.Thickness; @@ -159,7 +159,7 @@ public class Clipping : Scenario { Title = "FrameView", Width = 15, - Height = 3, + Height = 3 }; tiled.Add (fv); diff --git a/UICatalog/Scenarios/Shortcuts.cs b/UICatalog/Scenarios/Shortcuts.cs index 32d82491b..2a7724358 100644 --- a/UICatalog/Scenarios/Shortcuts.cs +++ b/UICatalog/Scenarios/Shortcuts.cs @@ -6,6 +6,7 @@ using System.Collections.ObjectModel; using System.Linq; using System.Timers; using Terminal.Gui; +using Timer = System.Timers.Timer; namespace UICatalog.Scenarios; diff --git a/UICatalog/UICatalog.cs b/UICatalog/UICatalog.cs index 3ff3035dd..e661097d6 100644 --- a/UICatalog/UICatalog.cs +++ b/UICatalog/UICatalog.cs @@ -455,7 +455,7 @@ public class UICatalogApp scenario.TopLevelColorScheme = _topLevelColorScheme; #if DEBUG_IDISPOSABLE - + View.DebugIDisposable = true; // Measure how long it takes for the app to shut down var sw = new Stopwatch (); string scenarioName = scenario.GetName (); @@ -685,6 +685,10 @@ public class UICatalogApp private static void VerifyObjectsWereDisposed () { #if DEBUG_IDISPOSABLE + if (!View.DebugIDisposable) + { + return; + } // Validate there are no outstanding Responder-based instances // after a scenario was selected to run. This proves the main UI Catalog @@ -1356,7 +1360,7 @@ public class UICatalogApp //CanExecute = () => false }); - return menuItems.ToArray (); + return menuItems.ToArray ()!; } // TODO: This should be an ConfigurationManager setting diff --git a/UICatalog/UICatalog.csproj b/UICatalog/UICatalog.csproj index aba324a4c..f0b5a8760 100644 --- a/UICatalog/UICatalog.csproj +++ b/UICatalog/UICatalog.csproj @@ -1,55 +1,53 @@  - - Exe - net8.0 - UICatalog.UICatalogApp - 12 - - - - 2.0 - 2.0 - 2.0 - 2.0 - Linux - - - TRACE - - - TRACE;DEBUG_IDISPOSABLE - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + UICatalog.UICatalogApp + Exe + + + + 2.0 + 2.0 + 2.0 + 2.0 + Linux + + + TRACE + + + TRACE;DEBUG_IDISPOSABLE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/UnitTests/README.md b/UnitTests/README.md deleted file mode 100644 index 3f3731b09..000000000 --- a/UnitTests/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# Automated Unit Tests - -`Terminal.Gui` uses [xunit](https://xunit.net/) for automated unit tests run automatically with Github Actions. - -See the [Testing wiki](https://github.com/gui-cs/Terminal.Gui/wiki/Testing) for details on how to add more tests. diff --git a/UnitTests/TestHelpers.cs b/UnitTests/TestHelpers.cs deleted file mode 100644 index ed687e61b..000000000 --- a/UnitTests/TestHelpers.cs +++ /dev/null @@ -1,759 +0,0 @@ -using System.Diagnostics; -using System.Globalization; -using System.Reflection; -using System.Text; -using System.Text.RegularExpressions; -using Xunit.Abstractions; -using Xunit.Sdk; -using static Terminal.Gui.ConfigurationManager; - -namespace Terminal.Gui; - -/// -/// This class enables test functions annotated with the [AutoInitShutdown] attribute to -/// automatically call Application.Init at start of the test and Application.Shutdown after the -/// test exits. -/// This is necessary because a) Application is a singleton and Init/Shutdown must be called -/// as a pair, and b) all unit test functions should be atomic.. -/// -[AttributeUsage (AttributeTargets.Class | AttributeTargets.Method)] -public class AutoInitShutdownAttribute : BeforeAfterTestAttribute -{ - /// - /// Initializes a [AutoInitShutdown] attribute, which determines if/how Application.Init and Application.Shutdown - /// are automatically called Before/After a test runs. - /// - /// If true, Application.Init will be called Before the test runs. - /// - /// Determines which IConsoleDriver (FakeDriver, WindowsDriver, CursesDriver, NetDriver) - /// will be used when Application.Init is called. If null FakeDriver will be used. Only valid if - /// is true. - /// - /// - /// If true, will force the use of . Only valid if - /// == and is true. - /// - /// - /// Only valid if is true. Only - /// valid if == and is true. - /// - /// - /// Only valid if is true. Only valid if - /// == and is true. - /// - /// Determines what config file locations will load from. - /// If true and is true, the test will fail. - public AutoInitShutdownAttribute ( - bool autoInit = true, - Type consoleDriverType = null, - bool useFakeClipboard = true, - bool fakeClipboardAlwaysThrowsNotSupportedException = false, - bool fakeClipboardIsSupportedAlwaysTrue = false, - ConfigLocations configLocation = ConfigLocations.Default, // DefaultOnly is the default for tests - bool verifyShutdown = false - ) - { - AutoInit = autoInit; - CultureInfo.DefaultThreadCurrentUICulture = CultureInfo.GetCultureInfo ("en-US"); - _driverType = consoleDriverType ?? typeof (FakeDriver); - FakeDriver.FakeBehaviors.UseFakeClipboard = useFakeClipboard; - - FakeDriver.FakeBehaviors.FakeClipboardAlwaysThrowsNotSupportedException = - fakeClipboardAlwaysThrowsNotSupportedException; - FakeDriver.FakeBehaviors.FakeClipboardIsSupportedAlwaysFalse = fakeClipboardIsSupportedAlwaysTrue; - Locations = configLocation; - _verifyShutdown = verifyShutdown; - } - - private readonly bool _verifyShutdown; - private readonly Type _driverType; - - public override void After (MethodInfo methodUnderTest) - { - Debug.WriteLine ($"After: {methodUnderTest.Name}"); - - // Turn off diagnostic flags in case some test left them on - View.Diagnostics = ViewDiagnosticFlags.Off; - - if (AutoInit) - { - // try - { - if (!_verifyShutdown) - { - Application.ResetState (ignoreDisposed: true); - } - - Application.Shutdown (); -#if DEBUG_IDISPOSABLE - if (View.Instances.Count == 0) - { - Assert.Empty (View.Instances); - } - else - { - View.Instances.Clear (); - } -#endif - } - //catch (Exception e) - //{ - // Assert.Fail ($"Application.Shutdown threw an exception after the test exited: {e}"); - //} - //finally - { -#if DEBUG_IDISPOSABLE - View.Instances.Clear (); - Application.ResetState (true); -#endif - } - } - - // Reset to defaults - Locations = ConfigLocations.Default; - Reset (); - - // Enable subsequent tests that call Init to get all config files (the default). - //Locations = ConfigLocations.All; - } - - public override void Before (MethodInfo methodUnderTest) - { - Debug.WriteLine ($"Before: {methodUnderTest.Name}"); - - if (AutoInit) - { -#if DEBUG_IDISPOSABLE - - // Clear out any lingering Responder instances from previous tests - if (View.Instances.Count == 0) - { - Assert.Empty (View.Instances); - } - else - { - View.Instances.Clear (); - } -#endif - Application.Init ((IConsoleDriver)Activator.CreateInstance (_driverType)); - } - } - - private bool AutoInit { get; } -} - -/// -/// Enables test functions annotated with the [TestRespondersDisposed] attribute to ensure all Views are disposed. -/// -/// -/// On Before, sets Configuration.Locations to ConfigLocations.DefaultOnly. -/// On After, sets Configuration.Locations to ConfigLocations.All. -/// -[AttributeUsage (AttributeTargets.Class | AttributeTargets.Method)] -public class TestRespondersDisposed : BeforeAfterTestAttribute -{ - public TestRespondersDisposed () { CultureInfo.DefaultThreadCurrentUICulture = CultureInfo.GetCultureInfo ("en-US"); } - - public override void After (MethodInfo methodUnderTest) - { - Debug.WriteLine ($"After: {methodUnderTest.Name}"); - base.After (methodUnderTest); - -#if DEBUG_IDISPOSABLE - Assert.Empty (View.Instances); -#endif - } - - public override void Before (MethodInfo methodUnderTest) - { - Debug.WriteLine ($"Before: {methodUnderTest.Name}"); - - base.Before (methodUnderTest); -#if DEBUG_IDISPOSABLE - - // Clear out any lingering Responder instances from previous tests - View.Instances.Clear (); - Assert.Empty (View.Instances); -#endif - } -} - -// TODO: Make this inherit from TestRespondersDisposed so that all tests that don't dispose Views correctly can be identified and fixed -/// -/// Enables test functions annotated with the [SetupFakeDriver] attribute to set Application.Driver to new -/// FakeDriver(). The driver is set up with 25 rows and columns. -/// -/// -/// On Before, sets Configuration.Locations to ConfigLocations.DefaultOnly. -/// On After, sets Configuration.Locations to ConfigLocations.All. -/// -[AttributeUsage (AttributeTargets.Class | AttributeTargets.Method)] -public class SetupFakeDriverAttribute : BeforeAfterTestAttribute -{ - public override void After (MethodInfo methodUnderTest) - { - Debug.WriteLine ($"After: {methodUnderTest.Name}"); - - // Turn off diagnostic flags in case some test left them on - View.Diagnostics = ViewDiagnosticFlags.Off; - - Application.ResetState (true); - Assert.Null (Application.Driver); - Assert.Equal (new (0, 0, 2048, 2048), Application.Screen); - base.After (methodUnderTest); - } - - public override void Before (MethodInfo methodUnderTest) - { - Debug.WriteLine ($"Before: {methodUnderTest.Name}"); - - Application.ResetState (true); - Assert.Null (Application.Driver); - Application.Driver = new FakeDriver { Rows = 25, Cols = 25 }; - Assert.Equal (new (0, 0, 25, 25), Application.Screen); - // Ensures subscribing events, at least for the SizeChanged event - Application.SubscribeDriverEvents (); - - base.Before (methodUnderTest); - } -} - -[AttributeUsage (AttributeTargets.Class | AttributeTargets.Method)] -public class TestDateAttribute : BeforeAfterTestAttribute -{ - public TestDateAttribute () { CultureInfo.CurrentCulture = CultureInfo.InvariantCulture; } - private readonly CultureInfo _currentCulture = CultureInfo.CurrentCulture; - - public override void After (MethodInfo methodUnderTest) - { - CultureInfo.CurrentCulture = _currentCulture; - Assert.Equal (CultureInfo.CurrentCulture, _currentCulture); - } - - public override void Before (MethodInfo methodUnderTest) { Assert.Equal (CultureInfo.CurrentCulture, CultureInfo.InvariantCulture); } -} - -internal partial class TestHelpers -{ - private const char SpaceChar = ' '; - private static readonly Rune SpaceRune = (Rune)SpaceChar; -#pragma warning disable xUnit1013 // Public method should be marked as test - /// - /// Verifies are found at the locations specified by - /// . is a bitmap of indexes into - /// (e.g. "00110" means the attribute at expectedAttributes[1] is expected - /// at the 3rd and 4th columns of the 1st row of driver.Contents). - /// - /// - /// Numbers between 0 and 9 for each row/col of the console. Must be valid indexes into - /// . - /// - /// - /// The IConsoleDriver to use. If null will be used. - /// - public static void AssertDriverAttributesAre ( - string expectedLook, - ITestOutputHelper output, - IConsoleDriver driver = null, - params Attribute [] expectedAttributes - ) - { -#pragma warning restore xUnit1013 // Public method should be marked as test - - if (expectedAttributes.Length > 10) - { - throw new ArgumentException ("This method only works for UIs that use at most 10 colors"); - } - - expectedLook = expectedLook.Trim (); - driver ??= Application.Driver; - - Cell [,] contents = driver.Contents; - - var line = 0; - - foreach (string lineString in expectedLook.Split ('\n').Select (l => l.Trim ())) - { - for (var c = 0; c < lineString.Length; c++) - { - Attribute? val = contents [line, c].Attribute; - - List match = expectedAttributes.Where (e => e == val).ToList (); - - switch (match.Count) - { - case 0: - output.WriteLine ( - $"{Application.ToString (driver)}\n" - + $"Expected Attribute {val} (PlatformColor = {val.Value.PlatformColor}) at Contents[{line},{c}] {contents [line, c]} ((PlatformColor = {contents [line, c].Attribute.Value.PlatformColor}) was not found.\n" - + $" Expected: {string.Join (",", expectedAttributes.Select (c => c))}\n" - + $" But Was: " - ); - Assert.Empty (match); - return; - case > 1: - throw new ArgumentException ( - $"Bad value for expectedColors, {match.Count} Attributes had the same Value" - ); - } - - char colorUsed = Array.IndexOf (expectedAttributes, match [0]).ToString () [0]; - char userExpected = lineString [c]; - - if (colorUsed != userExpected) - { - output.WriteLine ($"{Application.ToString (driver)}"); - output.WriteLine ($"Unexpected Attribute at Contents[{line},{c}] {contents [line, c]}."); - output.WriteLine ($" Expected: {userExpected} ({expectedAttributes [int.Parse (userExpected.ToString ())]})"); - output.WriteLine ($" But Was: {colorUsed} ({val})"); - Assert.Equal (userExpected, colorUsed); - return; - } - } - - line++; - } - } - -#pragma warning disable xUnit1013 // Public method should be marked as test - /// Asserts that the driver contents match the expected contents, optionally ignoring any trailing whitespace. - /// - /// - /// The IConsoleDriver to use. If null will be used. - /// - public static void AssertDriverContentsAre ( - string expectedLook, - ITestOutputHelper output, - IConsoleDriver driver = null, - bool ignoreLeadingWhitespace = false - ) - { -#pragma warning restore xUnit1013 // Public method should be marked as test - var actualLook = Application.ToString (driver ?? Application.Driver); - - if (string.Equals (expectedLook, actualLook)) - { - return; - } - - // get rid of trailing whitespace on each line (and leading/trailing whitespace of start/end of full string) - expectedLook = TrailingWhiteSpaceRegEx ().Replace (expectedLook, "").Trim (); - actualLook = TrailingWhiteSpaceRegEx ().Replace (actualLook, "").Trim (); - - if (ignoreLeadingWhitespace) - { - expectedLook = LeadingWhitespaceRegEx ().Replace (expectedLook, "").Trim (); - actualLook = LeadingWhitespaceRegEx ().Replace (actualLook, "").Trim (); - } - - // standardize line endings for the comparison - expectedLook = expectedLook.Replace ("\r\n", "\n"); - actualLook = actualLook.Replace ("\r\n", "\n"); - - // If test is about to fail show user what things looked like - if (!string.Equals (expectedLook, actualLook)) - { - output?.WriteLine ("Expected:" + Environment.NewLine + expectedLook); - output?.WriteLine (" But Was:" + Environment.NewLine + actualLook); - } - - Assert.Equal (expectedLook, actualLook); - } - - /// - /// Asserts that the driver contents are equal to the provided string. - /// - /// - /// - /// The IConsoleDriver to use. If null will be used. - /// - public static Rectangle AssertDriverContentsWithFrameAre ( - string expectedLook, - ITestOutputHelper output, - IConsoleDriver driver = null - ) - { - List> lines = new (); - var sb = new StringBuilder (); - driver ??= Application.Driver; - int x = -1; - int y = -1; - int w = -1; - int h = -1; - - Cell [,] contents = driver.Contents; - - for (var rowIndex = 0; rowIndex < driver.Rows; rowIndex++) - { - List runes = []; - - for (var colIndex = 0; colIndex < driver.Cols; colIndex++) - { - Rune runeAtCurrentLocation = contents [rowIndex, colIndex].Rune; - - if (runeAtCurrentLocation != SpaceRune) - { - if (x == -1) - { - x = colIndex; - y = rowIndex; - - for (var i = 0; i < colIndex; i++) - { - runes.InsertRange (i, [SpaceRune]); - } - } - - if (runeAtCurrentLocation.GetColumns () > 1) - { - colIndex++; - } - - if (colIndex + 1 > w) - { - w = colIndex + 1; - } - - h = rowIndex - y + 1; - } - - if (x > -1) - { - runes.Add (runeAtCurrentLocation); - } - - // See Issue #2616 - //foreach (var combMark in contents [r, c].CombiningMarks) { - // runes.Add (combMark); - //} - } - - if (runes.Count > 0) - { - lines.Add (runes); - } - } - - // Remove unnecessary empty lines - if (lines.Count > 0) - { - for (int r = lines.Count - 1; r > h - 1; r--) - { - lines.RemoveAt (r); - } - } - - // Remove trailing whitespace on each line - foreach (List row in lines) - { - for (int c = row.Count - 1; c >= 0; c--) - { - Rune rune = row [c]; - - if (rune != (Rune)' ' || row.Sum (x => x.GetColumns ()) == w) - { - break; - } - - row.RemoveAt (c); - } - } - - // Convert Rune list to string - for (var r = 0; r < lines.Count; r++) - { - var line = StringExtensions.ToString (lines [r]); - - if (r == lines.Count - 1) - { - sb.Append (line); - } - else - { - sb.AppendLine (line); - } - } - - var actualLook = sb.ToString (); - - if (string.Equals (expectedLook, actualLook)) - { - return new (x > -1 ? x : 0, y > -1 ? y : 0, w > -1 ? w : 0, h > -1 ? h : 0); - } - - // standardize line endings for the comparison - expectedLook = expectedLook.ReplaceLineEndings (); - actualLook = actualLook.ReplaceLineEndings (); - - // Remove the first and the last line ending from the expectedLook - if (expectedLook.StartsWith (Environment.NewLine)) - { - expectedLook = expectedLook [Environment.NewLine.Length..]; - } - - if (expectedLook.EndsWith (Environment.NewLine)) - { - expectedLook = expectedLook [..^Environment.NewLine.Length]; - } - - // If test is about to fail show user what things looked like - if (!string.Equals (expectedLook, actualLook)) - { - output?.WriteLine ("Expected:" + Environment.NewLine + expectedLook); - output?.WriteLine (" But Was:" + Environment.NewLine + actualLook); - } - - Assert.Equal (expectedLook, actualLook); - - return new (x > -1 ? x : 0, y > -1 ? y : 0, w > -1 ? w : 0, h > -1 ? h : 0); - } - -#pragma warning disable xUnit1013 // Public method should be marked as test - /// - /// Verifies two strings are equivalent. If the assert fails, output will be generated to standard output showing - /// the expected and actual look. - /// - /// - /// - /// A string containing the expected look. Newlines should be specified as "\r\n" as they will - /// be converted to to make tests platform independent. - /// - /// - public static void AssertEqual (ITestOutputHelper output, string expectedLook, string actualLook) - { - // Convert newlines to platform-specific newlines - expectedLook = ReplaceNewLinesToPlatformSpecific (expectedLook); - - // If test is about to fail show user what things looked like - if (!string.Equals (expectedLook, actualLook)) - { - output?.WriteLine ("Expected:" + Environment.NewLine + expectedLook); - output?.WriteLine (" But Was:" + Environment.NewLine + actualLook); - } - - Assert.Equal (expectedLook, actualLook); - } -#pragma warning restore xUnit1013 // Public method should be marked as test - - public static View CreateViewFromType (Type type, ConstructorInfo ctor) - { - View viewType = null; - - if (type.IsGenericType && type.IsTypeDefinition) - { - List gTypes = new (); - - foreach (Type args in type.GetGenericArguments ()) - { - gTypes.Add (typeof (object)); - } - - type = type.MakeGenericType (gTypes.ToArray ()); - - Assert.IsType (type, (View)Activator.CreateInstance (type)); - } - else - { - ParameterInfo [] paramsInfo = ctor.GetParameters (); - Type paramType; - List pTypes = new (); - - if (type.IsGenericType) - { - foreach (Type args in type.GetGenericArguments ()) - { - paramType = args.GetType (); - - if (args.Name == "T") - { - pTypes.Add (typeof (object)); - } - else - { - AddArguments (paramType, pTypes); - } - } - } - - foreach (ParameterInfo p in paramsInfo) - { - paramType = p.ParameterType; - - if (p.HasDefaultValue) - { - pTypes.Add (p.DefaultValue); - } - else - { - AddArguments (paramType, pTypes); - } - } - - if (type.IsGenericType && !type.IsTypeDefinition) - { - viewType = (View)Activator.CreateInstance (type); - Assert.IsType (type, viewType); - } - else - { - viewType = (View)ctor.Invoke (pTypes.ToArray ()); - Assert.IsType (type, viewType); - } - } - - return viewType; - } - - public static List GetAllViewClasses () - { - return typeof (View).Assembly.GetTypes () - .Where ( - myType => myType.IsClass - && !myType.IsAbstract - && myType.IsPublic - && myType.IsSubclassOf (typeof (View)) - ) - .ToList (); - } - - /// - /// Verifies the console used all the when rendering. If one or more of the - /// expected colors are not used then the failure will output both the colors that were found to be used and which of - /// your expectations was not met. - /// - /// if null uses - /// - internal static void AssertDriverUsedColors (IConsoleDriver driver = null, params Attribute [] expectedColors) - { - driver ??= Application.Driver; - Cell [,] contents = driver.Contents; - - List toFind = expectedColors.ToList (); - - // Contents 3rd column is an Attribute - HashSet colorsUsed = new (); - - for (var r = 0; r < driver.Rows; r++) - { - for (var c = 0; c < driver.Cols; c++) - { - Attribute? val = contents [r, c].Attribute; - - if (val.HasValue) - { - colorsUsed.Add (val.Value); - - Attribute match = toFind.FirstOrDefault (e => e == val); - - // need to check twice because Attribute is a struct and therefore cannot be null - if (toFind.Any (e => e == val)) - { - toFind.Remove (match); - } - } - } - } - - if (!toFind.Any ()) - { - return; - } - - var sb = new StringBuilder (); - sb.AppendLine ("The following colors were not used:" + string.Join ("; ", toFind.Select (a => a.ToString ()))); - sb.AppendLine ("Colors used were:" + string.Join ("; ", colorsUsed.Select (a => a.ToString ()))); - - throw new (sb.ToString ()); - } - - private static void AddArguments (Type paramType, List pTypes) - { - if (paramType == typeof (Rectangle)) - { - pTypes.Add (Rectangle.Empty); - } - else if (paramType == typeof (string)) - { - pTypes.Add (string.Empty); - } - else if (paramType == typeof (int)) - { - pTypes.Add (0); - } - else if (paramType == typeof (bool)) - { - pTypes.Add (true); - } - else if (paramType.Name == "IList") - { - pTypes.Add (new List ()); - } - else if (paramType.Name == "View") - { - var top = new Toplevel (); - var view = new View (); - top.Add (view); - pTypes.Add (view); - } - else if (paramType.Name == "View[]") - { - pTypes.Add (new View [] { }); - } - else if (paramType.Name == "Stream") - { - pTypes.Add (new MemoryStream ()); - } - else if (paramType.Name == "String") - { - pTypes.Add (string.Empty); - } - else if (paramType.Name == "TreeView`1[T]") - { - pTypes.Add (string.Empty); - } - else - { - pTypes.Add (null); - } - } - - [GeneratedRegex ("^\\s+", RegexOptions.Multiline)] - private static partial Regex LeadingWhitespaceRegEx (); - - private static string ReplaceNewLinesToPlatformSpecific (string toReplace) - { - string replaced = toReplace; - - replaced = Environment.NewLine.Length switch - { - 2 when !replaced.Contains ("\r\n") => replaced.Replace ("\n", Environment.NewLine), - 1 => replaced.Replace ("\r\n", Environment.NewLine), - var _ => replaced - }; - - return replaced; - } - - [GeneratedRegex ("\\s+$", RegexOptions.Multiline)] - private static partial Regex TrailingWhiteSpaceRegEx (); -} - -public class TestsAllViews -{ - public static IEnumerable AllViewTypes => - typeof (View).Assembly - .GetTypes () - .Where (type => type.IsClass && !type.IsAbstract && type.IsPublic && (type.IsSubclassOf (typeof (View)) || type == typeof (View))) - .Select (type => new object [] { type }); - - public static View CreateInstanceIfNotGeneric (Type type) - { - if (type.IsGenericType) - { - // Return null for generic types - return null; - } - - return Activator.CreateInstance (type) as View; - } -} diff --git a/UnitTests/UnitTests.csproj b/UnitTests/UnitTests.csproj deleted file mode 100644 index c574ea37c..000000000 --- a/UnitTests/UnitTests.csproj +++ /dev/null @@ -1,84 +0,0 @@ - - - - - - 2.0 - 2.0 - 2.0 - 2.0 - - - net8.0 - 12 - false - - true - true - portable - $(DefineConstants);JETBRAINS_ANNOTATIONS;CONTRACTS_FULL - enable - true - true - - - true - $(DefineConstants);DEBUG_IDISPOSABLE - - - true - - - - - - - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - - - PreserveNewest - - - - - - - - - - - - - False - - - [UICatalog]* - - - - - - - - - - False - - - diff --git a/UnitTests/View/Adornment/ShadowStyletests.cs b/UnitTests/View/Adornment/ShadowStyletests.cs deleted file mode 100644 index bc1088789..000000000 --- a/UnitTests/View/Adornment/ShadowStyletests.cs +++ /dev/null @@ -1,222 +0,0 @@ -using Xunit.Abstractions; - -namespace Terminal.Gui.ViewTests; - -public class ShadowStyleTests (ITestOutputHelper output) -{ - [Fact] - public void Default_None () - { - var view = new View (); - Assert.Equal (ShadowStyle.None, view.ShadowStyle); - Assert.Equal (ShadowStyle.None, view.Margin.ShadowStyle); - view.Dispose (); - } - - [Theory] - [InlineData (ShadowStyle.None)] - [InlineData (ShadowStyle.Opaque)] - [InlineData (ShadowStyle.Transparent)] - public void Set_View_Sets_Margin (ShadowStyle style) - { - var view = new View (); - - view.ShadowStyle = style; - Assert.Equal (style, view.ShadowStyle); - Assert.Equal (style, view.Margin.ShadowStyle); - view.Dispose (); - } - - [Theory] - [InlineData (ShadowStyle.None, 0, 0, 0, 0)] - [InlineData (ShadowStyle.Opaque, 1, 0, 0, 1)] - [InlineData (ShadowStyle.Transparent, 1, 0, 0, 1)] - public void ShadowStyle_Button1Pressed_Causes_Movement (ShadowStyle style, int expectedLeft, int expectedTop, int expectedRight, int expectedBottom) - { - var superView = new View - { - Height = 10, Width = 10 - }; - - View view = new () - { - Width = Dim.Auto (), - Height = Dim.Auto (), - Text = "0123", - HighlightStyle = HighlightStyle.Pressed, - ShadowStyle = style, - CanFocus = true - }; - - superView.Add (view); - superView.BeginInit (); - superView.EndInit (); - - Thickness origThickness = view.Margin.Thickness; - view.NewMouseEvent (new () { Flags = MouseFlags.Button1Pressed, Position = new (0, 0) }); - Assert.Equal (new (expectedLeft, expectedTop, expectedRight, expectedBottom), view.Margin.Thickness); - - view.NewMouseEvent (new () { Flags = MouseFlags.Button1Released, Position = new (0, 0) }); - Assert.Equal (origThickness, view.Margin.Thickness); - } - - [Theory] - [InlineData (ShadowStyle.None, 0, 0, 0, 0)] - [InlineData (ShadowStyle.Opaque, 0, 0, 1, 1)] - [InlineData (ShadowStyle.Transparent, 0, 0, 1, 1)] - public void ShadowStyle_Margin_Thickness (ShadowStyle style, int expectedLeft, int expectedTop, int expectedRight, int expectedBottom) - { - var superView = new View - { - Height = 10, Width = 10 - }; - - View view = new () - { - Width = Dim.Auto (), - Height = Dim.Auto (), - Text = "0123", - HighlightStyle = HighlightStyle.Pressed, - ShadowStyle = style, - CanFocus = true - }; - - superView.Add (view); - superView.BeginInit (); - superView.EndInit (); - - Assert.Equal (new (expectedLeft, expectedTop, expectedRight, expectedBottom), view.Margin.Thickness); - } - - [Theory (Skip = "#3761 Broke - Need to figure out transparent margin.")] - [InlineData ( - ShadowStyle.None, - """ - 011 - 111 - 111 - """)] - [InlineData ( - ShadowStyle.Transparent, - """ - 031 - 131 - 111 - """)] - [InlineData ( - ShadowStyle.Opaque, - """ - 021 - 221 - 111 - """)] - [SetupFakeDriver] - public void ShadowView_Colors (ShadowStyle style, string expectedAttrs) - { - 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.GetDarkerColor (), bg.GetDarkerColor ()) - }; - - var superView = new View - { - Height = 3, - Width = 3, - Text = "012ABC!@#", - ColorScheme = new (new Attribute (fg, bg)) - }; - superView.TextFormatter.WordWrap = true; - - View view = new () - { - Width = Dim.Auto (), - Height = Dim.Auto (), - Text = " ", - ShadowStyle = style, - ColorScheme = new (Attribute.Default) - }; - superView.Add (view); - superView.Layout (); - superView.Draw (); - TestHelpers.AssertDriverAttributesAre (expectedAttrs, output, Application.Driver, attributes); - } - - [Theory (Skip = "#3761 Broke - Need to figure out transparent margin.")] - [InlineData (ShadowStyle.None, 3)] - [InlineData (ShadowStyle.Opaque, 4)] - [InlineData (ShadowStyle.Transparent, 4)] - public void Style_Changes_Magin_Thickness (ShadowStyle style, int expected) - { - var view = new View (); - view.Margin.Thickness = new (3); - view.ShadowStyle = style; - Assert.Equal (new (3, 3, expected, expected), view.Margin.Thickness); - - view.ShadowStyle = ShadowStyle.None; - Assert.Equal (new (3), view.Margin.Thickness); - view.Dispose (); - } - - // Visual tests - [Theory (Skip = "#3761 Broke - Need to figure out transparent margin.")] - [InlineData ( - ShadowStyle.None, - """ - 01#$ - AB#$ - !@#$ - !@#$ - """)] - [InlineData ( - ShadowStyle.Opaque, - """ - 01▖$ - AB▌$ - ▝▀▘$ - !@#$ - """)] - [InlineData ( - ShadowStyle.Transparent, - """ - 01#$ - AB#$ - !@#$ - !@#$ - """)] - [SetupFakeDriver] - public void Visual_Test (ShadowStyle style, string expected) - { - var superView = new View - { - 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); - superView.BeginInit (); - superView.EndInit (); - superView.Draw (); - - TestHelpers.AssertDriverContentsWithFrameAre (expected, output); - view.Dispose (); - } -} diff --git a/UnitTests/View/Adornment/ToScreenTests.cs b/UnitTests/View/Adornment/ToScreenTests.cs deleted file mode 100644 index 621f52b2f..000000000 --- a/UnitTests/View/Adornment/ToScreenTests.cs +++ /dev/null @@ -1,514 +0,0 @@ -using Xunit.Abstractions; - -namespace Terminal.Gui.ViewTests; - -/// -/// Test the and methods. -/// DOES NOT TEST View.xxxToScreen methods. Those are in ./View/Layout/ToScreenTests.cs -/// -/// -public class AdornmentToScreenTests (ITestOutputHelper output) -{ - private readonly ITestOutputHelper _output = output; - - [Theory] - [InlineData (0, 0)] - [InlineData (1, 1)] - [InlineData (-1, -1)] - [InlineData (11, 11)] - public void FrameToScreen_NoSuperView_WithoutAdornments (int x, int expectedX) - { - // We test with only X because Y is equivalent. Height/Width are irrelevant. - // Arrange - var frame = new Rectangle (x, 0, 10, 10); - - var view = new View (); - view.Frame = frame; - - // Act - var marginScreen = view.Margin.FrameToScreen(); - var borderScreen = view.Border.FrameToScreen (); - var paddingScreen = view.Padding.FrameToScreen (); - - // Assert - Assert.Equal(expectedX, marginScreen.X); - Assert.Equal (expectedX + view.Margin.Thickness.Left, borderScreen.X); - Assert.Equal (expectedX + view.Margin.Thickness.Left + view.Border.Thickness.Left, paddingScreen.X); - } - - [Theory] - [InlineData (0, 0)] - [InlineData (1, 1)] - [InlineData (-1, -1)] - [InlineData (11, 11)] - public void FrameToScreen_NoSuperView_WithAdornments (int x, int expectedX) - { - // We test with only X because Y is equivalent. Height/Width are irrelevant. - // Arrange - var frame = new Rectangle (x, 0, 10, 10); - - var view = new View (); - view.Border.Thickness = new (1); - view.Frame = frame; - - // Act - var marginScreen = view.Margin.FrameToScreen (); - var borderScreen = view.Border.FrameToScreen (); - var paddingScreen = view.Padding.FrameToScreen (); - - // Assert - Assert.Equal (expectedX, marginScreen.X); - Assert.Equal (expectedX + view.Margin.Thickness.Left, borderScreen.X); - Assert.Equal (expectedX + view.Margin.Thickness.Left + view.Border.Thickness.Left, paddingScreen.X); - } - - [Theory] - [InlineData (0, 0)] - [InlineData (1, 1)] - [InlineData (-1, -1)] - [InlineData (11, 11)] - public void FrameToScreen_SuperView_WithoutAdornments (int x, int expectedX) - { - // We test with only X because Y is equivalent. Height/Width are irrelevant. - // Arrange - var frame = new Rectangle (x, 0, 10, 10); - - var superView = new View () - { - X = 0, - Y = 0, - Height = Dim.Fill (), - Width = Dim.Fill () - }; - - var view = new View (); - view.Frame = frame; - - superView.Add (view); - superView.LayoutSubviews (); - - // Act - var marginScreen = view.Margin.FrameToScreen (); - var borderScreen = view.Border.FrameToScreen (); - var paddingScreen = view.Padding.FrameToScreen (); - - // Assert - Assert.Equal (expectedX, marginScreen.X); - Assert.Equal (expectedX + view.Margin.Thickness.Left, borderScreen.X); - Assert.Equal (expectedX + view.Margin.Thickness.Left + view.Border.Thickness.Left, paddingScreen.X); - } - - [Theory] - [InlineData (0, 3)] - [InlineData (1, 4)] - [InlineData (-1, 2)] - [InlineData (11, 14)] - public void FrameToScreen_SuperView_WithAdornments (int x, int expectedX) - { - // We test with only X because Y is equivalent. Height/Width are irrelevant. - // Arrange - var frame = new Rectangle (x, 0, 10, 10); - - var superView = new View () - { - X = 0, - Y = 0, - Height = Dim.Fill (), - Width = Dim.Fill () - }; - superView.Margin.Thickness = new (1); - superView.Border.Thickness = new (1); - superView.Padding.Thickness = new (1); - - var view = new View (); - view.Frame = frame; - - superView.Add (view); - superView.LayoutSubviews (); - - // Act - var marginScreen = view.Margin.FrameToScreen (); - var borderScreen = view.Border.FrameToScreen (); - var paddingScreen = view.Padding.FrameToScreen (); - - // Assert - Assert.Equal (expectedX, marginScreen.X); - Assert.Equal (expectedX + view.Margin.Thickness.Left, borderScreen.X); - Assert.Equal (expectedX + view.Margin.Thickness.Left + view.Border.Thickness.Left, paddingScreen.X); - } - - [Theory] - [InlineData (0, 0)] - [InlineData (1, 1)] - [InlineData (-1, -1)] - [InlineData (11, 11)] - public void FrameToScreen_NestedSuperView_WithoutAdornments (int x, int expectedX) - { - // We test with only X because Y is equivalent. Height/Width are irrelevant. - // Arrange - var frame = new Rectangle (x, 0, 10, 10); - - var superSuperView = new View () - { - X = 0, - Y = 0, - Height = Dim.Fill (), - Width = Dim.Fill () - }; - - var superView = new View () - { - X = 0, - Y = 0, - Height = Dim.Fill (), - Width = Dim.Fill () - }; - - superSuperView.Add (superView); - - var view = new View (); - view.Frame = frame; - - superView.Add (view); - superView.LayoutSubviews (); - - // Act - var marginScreen = view.Margin.FrameToScreen (); - var borderScreen = view.Border.FrameToScreen (); - var paddingScreen = view.Padding.FrameToScreen (); - - // Assert - Assert.Equal (expectedX, marginScreen.X); - Assert.Equal (expectedX + view.Margin.Thickness.Left, borderScreen.X); - Assert.Equal (expectedX + view.Margin.Thickness.Left + view.Border.Thickness.Left, paddingScreen.X); - } - - [Theory] - [InlineData (0, 6)] - [InlineData (1, 7)] - [InlineData (-1, 5)] - [InlineData (11, 17)] - public void FrameToScreen_NestedSuperView_WithAdornments (int x, int expectedX) - { - // We test with only X because Y is equivalent. Height/Width are irrelevant. - // Arrange - var frame = new Rectangle (x, 0, 10, 10); - - var superSuperView = new View () - { - X = 0, - Y = 0, - Height = Dim.Fill (), - Width = Dim.Fill () - }; - superSuperView.Margin.Thickness = new (1); - superSuperView.Border.Thickness = new (1); - superSuperView.Padding.Thickness = new (1); - - var superView = new View () - { - X = 0, - Y = 0, - Height = Dim.Fill (), - Width = Dim.Fill () - }; - superView.Margin.Thickness = new (1); - superView.Border.Thickness = new (1); - superView.Padding.Thickness = new (1); - superSuperView.Add (superView); - - var view = new View (); - view.Frame = frame; - - superView.Add (view); - superView.LayoutSubviews (); - - // Act - var marginScreen = view.Margin.FrameToScreen (); - var borderScreen = view.Border.FrameToScreen (); - var paddingScreen = view.Padding.FrameToScreen (); - - // Assert - Assert.Equal (expectedX, marginScreen.X); - Assert.Equal (expectedX + view.Margin.Thickness.Left, borderScreen.X); - Assert.Equal (expectedX + view.Margin.Thickness.Left + view.Border.Thickness.Left, paddingScreen.X); - } - - // Adornment.ViewportToScreen tests ============================ - - [Theory] - [InlineData (0, 0, 0)] - [InlineData (1, 0, 1)] - [InlineData (-1, 0, -1)] - [InlineData (11, 0, 11)] - public void ViewportToScreen_NoSuperView_WithoutAdornments (int frameX, int testX, int expectedX) - { - // We test with only X because Y is equivalent. Height/Width are irrelevant. - // Arrange - var frame = new Rectangle (frameX, 0, 10, 10); - - var view = new View (); - view.Frame = frame; - - // Act - var marginScreen = view.Margin.ViewportToScreen (new Point (testX, 0)); - var borderScreen = view.Border.ViewportToScreen (new Point (testX, 0)); - var paddingScreen = view.Padding.ViewportToScreen (new Point (testX, 0)); - - // Assert - Assert.Equal (expectedX, marginScreen.X); - Assert.Equal (expectedX + view.Margin.Thickness.Left, borderScreen.X); - Assert.Equal (expectedX + view.Margin.Thickness.Left + view.Border.Thickness.Left, paddingScreen.X); - } - - [Theory] - [InlineData (0, 0, 0)] - [InlineData (1, 0, 1)] - [InlineData (-1, 0, -1)] - [InlineData (11, 0, 11)] - - [InlineData (0, 1, 1)] - [InlineData (1, 1, 2)] - [InlineData (-1, 1, 0)] - [InlineData (11, 1, 12)] - - [InlineData (0, -1, -1)] - [InlineData (1, -1, 0)] - [InlineData (-1, -1, -2)] - [InlineData (11, -1, 10)] - public void ViewportToScreen_NoSuperView_WithAdornments (int frameX, int testX, int expectedX) - { - // We test with only X because Y is equivalent. Height/Width are irrelevant. - // Arrange - var frame = new Rectangle (frameX, 0, 10, 10); - - var view = new View (); - view.Margin.Thickness = new (1); - view.Border.Thickness = new (1); - view.Padding.Thickness = new (1); - // Total thickness is 3 (view.Viewport will be Frame.Width - 6) - view.Frame = frame; - - Assert.Equal(4, view.Viewport.Width); - - // Act - var marginScreen = view.Margin.ViewportToScreen (new Point (testX, 0)); - var borderScreen = view.Border.ViewportToScreen (new Point (testX, 0)); - var paddingScreen = view.Padding.ViewportToScreen (new Point (testX, 0)); - - // Assert - Assert.Equal (expectedX, marginScreen.X); - Assert.Equal (expectedX + view.Margin.Thickness.Left, borderScreen.X); - Assert.Equal (expectedX + view.Margin.Thickness.Left + view.Border.Thickness.Left, paddingScreen.X); - } - - [Theory] - [InlineData (0, 0, 0)] - [InlineData (1, 0, 1)] - [InlineData (-1, 0, -1)] - [InlineData (11, 0, 11)] - - [InlineData (0, 1, 1)] - [InlineData (1, 1, 2)] - [InlineData (-1, 1, 0)] - [InlineData (11, 1, 12)] - - [InlineData (0, -1, -1)] - [InlineData (1, -1, 0)] - [InlineData (-1, -1, -2)] - [InlineData (11, -1, 10)] - public void ViewportToScreen_SuperView_WithoutAdornments (int frameX, int testX, int expectedX) - { - // We test with only X because Y is equivalent. Height/Width are irrelevant. - // Arrange - var frame = new Rectangle (frameX, 0, 10, 10); - - var superView = new View () - { - X = 0, - Y = 0, - Height = Dim.Fill (), - Width = Dim.Fill () - }; - - var view = new View (); - view.Frame = frame; - - superView.Add (view); - superView.LayoutSubviews (); - - // Act - var marginScreen = view.Margin.ViewportToScreen (new Point (testX, 0)); - var borderScreen = view.Border.ViewportToScreen (new Point (testX, 0)); - var paddingScreen = view.Padding.ViewportToScreen (new Point (testX, 0)); - - // Assert - Assert.Equal (expectedX, marginScreen.X); - Assert.Equal (expectedX + view.Margin.Thickness.Left, borderScreen.X); - Assert.Equal (expectedX + view.Border.Thickness.Left, paddingScreen.X); - } - - [Theory] - [InlineData (0, 0, 1)] - [InlineData (1, 0, 2)] - [InlineData (-1, 0, 0)] - [InlineData (11, 0, 12)] - - [InlineData (0, 1, 2)] - [InlineData (1, 1, 3)] - [InlineData (-1, 1, 1)] - [InlineData (11, 1, 13)] - - [InlineData (0, -1, 0)] - [InlineData (1, -1, 1)] - [InlineData (-1, -1, -1)] - [InlineData (11, -1, 11)] - public void ViewportToScreen_SuperView_WithAdornments (int frameX, int testX, int expectedX) - { - // We test with only X because Y is equivalent. Height/Width are irrelevant. - // Arrange - var frame = new Rectangle (frameX, 0, 10, 10); - - var superView = new View () - { - X = 0, - Y = 0, - Height = Dim.Fill (), - Width = Dim.Fill () - }; - superView.Border.Thickness = new (1); - - var view = new View (); - view.Frame = frame; - - superView.Add (view); - superView.LayoutSubviews (); - - // Act - var marginScreen = view.Margin.ViewportToScreen (new Point (testX, 0)); - var borderScreen = view.Border.ViewportToScreen (new Point (testX, 0)); - var paddingScreen = view.Padding.ViewportToScreen (new Point (testX, 0)); - - // Assert - Assert.Equal (expectedX, marginScreen.X); - Assert.Equal (expectedX + view.Margin.Thickness.Left, borderScreen.X); - Assert.Equal (expectedX + view.Border.Thickness.Left, paddingScreen.X); - } - - [Theory] - [InlineData (0, 0, 0)] - [InlineData (1, 0, 1)] - [InlineData (-1, 0, -1)] - [InlineData (11, 0, 11)] - - [InlineData (0, 1, 1)] - [InlineData (1, 1, 2)] - [InlineData (-1, 1, 0)] - [InlineData (11, 1, 12)] - - [InlineData (0, -1, -1)] - [InlineData (1, -1, 0)] - [InlineData (-1, -1, -2)] - [InlineData (11, -1, 10)] - public void ViewportToScreen_NestedSuperView_WithoutAdornments (int frameX, int testX, int expectedX) - { - // We test with only X because Y is equivalent. Height/Width are irrelevant. - // Arrange - var frame = new Rectangle (frameX, 0, 10, 10); - - var superSuperView = new View () - { - X = 0, - Y = 0, - Height = Dim.Fill (), - Width = Dim.Fill () - }; - - var superView = new View () - { - X = 0, - Y = 0, - Height = Dim.Fill (), - Width = Dim.Fill () - }; - - superSuperView.Add (superView); - - var view = new View (); - view.Frame = frame; - - superView.Add (view); - superView.LayoutSubviews (); - - // Act - var marginScreen = view.Margin.ViewportToScreen (new Point (testX, 0)); - var borderScreen = view.Border.ViewportToScreen (new Point (testX, 0)); - var paddingScreen = view.Padding.ViewportToScreen (new Point (testX, 0)); - - // Assert - Assert.Equal (expectedX, marginScreen.X); - Assert.Equal (expectedX + view.Margin.Thickness.Left, borderScreen.X); - Assert.Equal (expectedX + view.Border.Thickness.Left, paddingScreen.X); - } - - [Theory] - [InlineData (0, 0, 6)] - [InlineData (1, 0, 7)] - [InlineData (-1, 0, 5)] - [InlineData (11, 0, 17)] - - [InlineData (0, 1, 7)] - [InlineData (1, 1, 8)] - [InlineData (-1, 1, 6)] - [InlineData (11, 1, 18)] - - [InlineData (0, -1, 5)] - [InlineData (1, -1, 6)] - [InlineData (-1, -1, 4)] - [InlineData (11, -1, 16)] - public void ViewportToScreen_NestedSuperView_WithAdornments (int frameX, int testX, int expectedX) - { - // We test with only X because Y is equivalent. Height/Width are irrelevant. - // Arrange - var frame = new Rectangle (frameX, 0, 10, 10); - - var superSuperView = new View () - { - X = 0, - Y = 0, - Height = Dim.Fill (), - Width = Dim.Fill () - }; - superSuperView.Margin.Thickness = new (1); - superSuperView.Border.Thickness = new (1); - superSuperView.Padding.Thickness = new (1); - - var superView = new View () - { - X = 0, - Y = 0, - Height = Dim.Fill (), - Width = Dim.Fill () - }; - superView.Margin.Thickness = new (1); - superView.Border.Thickness = new (1); - superView.Padding.Thickness = new (1); - superSuperView.Add (superView); - - var view = new View (); - view.Frame = frame; - - superView.Add (view); - superView.LayoutSubviews (); - - // Act - var marginScreen = view.Margin.ViewportToScreen (new Point (testX, 0)); - var borderScreen = view.Border.ViewportToScreen (new Point (testX, 0)); - var paddingScreen = view.Padding.ViewportToScreen (new Point (testX, 0)); - - // Assert - Assert.Equal (expectedX, marginScreen.X); - Assert.Equal (expectedX + view.Margin.Thickness.Left, borderScreen.X); - Assert.Equal (expectedX + view.Margin.Thickness.Left + view.Border.Thickness.Left, paddingScreen.X); - } -} diff --git a/local_packages/Terminal.Gui.2.0.0.nupkg b/local_packages/Terminal.Gui.2.0.0.nupkg index ce9920892..9e06cdd99 100644 Binary files a/local_packages/Terminal.Gui.2.0.0.nupkg and b/local_packages/Terminal.Gui.2.0.0.nupkg differ diff --git a/local_packages/Terminal.Gui.2.0.0.snupkg b/local_packages/Terminal.Gui.2.0.0.snupkg index 6d8120947..057069fa8 100644 Binary files a/local_packages/Terminal.Gui.2.0.0.snupkg and b/local_packages/Terminal.Gui.2.0.0.snupkg differ