|
| 1 | +#Requires -Modules @{ ModuleName='Pester'; ModuleVersion='5.7.0' } |
| 2 | +<# |
| 3 | +.SYNOPSIS |
| 4 | + Windows PowerShell 5.1 compatibility tests for delphi-msbuild.ps1. |
| 5 | +
|
| 6 | +.DESCRIPTION |
| 7 | + Verifies that delphi-msbuild.ps1 can be launched under powershell.exe |
| 8 | + (Windows PowerShell 5.1) and produces correct exit codes. |
| 9 | + All tests in this file skip automatically on platforms where |
| 10 | + powershell.exe is absent (e.g. Linux CI runners). |
| 11 | +
|
| 12 | + The test suite itself continues to require pwsh 7+ (see run-tests.ps1); |
| 13 | + these tests only invoke the script-under-test via powershell.exe. |
| 14 | +
|
| 15 | + Scenarios tested: |
| 16 | + Exits 3 when no -RootDir and no pipeline input. |
| 17 | + Exits 3 when -RootDir directory does not exist on disk. |
| 18 | + Exits 3 when -RootDir exists but rsvars.bat is absent. |
| 19 | + Exits 4 when rsvars.bat exists but -ProjectFile does not. |
| 20 | +
|
| 21 | +.NOTES |
| 22 | + Get-Command is NOT used to locate powershell.exe. The Invoke-RsvarsEnvironment |
| 23 | + unit test applies fake environment variables (including a truncated PATH) to the |
| 24 | + live process, which removes C:\Windows\System32\WindowsPowerShell\v1.0 from PATH |
| 25 | + and breaks Get-Command resolution for external commands. Instead, powershell.exe |
| 26 | + is located via its well-known fixed path under $env:SystemRoot. On Linux/macOS |
| 27 | + $env:SystemRoot is absent so Test-Path returns $false and all tests skip cleanly. |
| 28 | +
|
| 29 | + $skipTests is a discovery-time local variable captured by -Skip:. |
| 30 | + $script:winPS51Exe is set in BeforeAll (run time) so it is visible in |
| 31 | + It and Context BeforeAll blocks. |
| 32 | +
|
| 33 | + -ExecutionPolicy Bypass is passed to powershell.exe because the machine's |
| 34 | + default execution policy may not permit running unsigned scripts. |
| 35 | +#> |
| 36 | + |
| 37 | +Describe 'Windows PowerShell 5.1 compatibility' { |
| 38 | + |
| 39 | + # Evaluated at Pester discovery time -- captured by -Skip: on each It. |
| 40 | + # Uses Test-Path (filesystem) rather than Get-Command (PATH-dependent) to |
| 41 | + # locate powershell.exe safely regardless of prior process PATH changes. |
| 42 | + $ps51Path = if ($env:SystemRoot) { |
| 43 | + [System.IO.Path]::Combine($env:SystemRoot, 'System32', 'WindowsPowerShell', 'v1.0', 'powershell.exe') |
| 44 | + } else { $null } |
| 45 | + $skipTests = -not ($ps51Path -and (Test-Path -LiteralPath $ps51Path)) |
| 46 | + |
| 47 | + BeforeAll { |
| 48 | + . "$PSScriptRoot/TestHelpers.ps1" |
| 49 | + $script:scriptPath = Get-ScriptUnderTestPath |
| 50 | + |
| 51 | + $script:winPS51Exe = $null |
| 52 | + $sysRoot = $env:SystemRoot |
| 53 | + if ($sysRoot) { |
| 54 | + $candidate = [System.IO.Path]::Combine($sysRoot, 'System32', 'WindowsPowerShell', 'v1.0', 'powershell.exe') |
| 55 | + if (Test-Path -LiteralPath $candidate) { $script:winPS51Exe = $candidate } |
| 56 | + } |
| 57 | + } |
| 58 | + |
| 59 | + It 'powershell.exe (Windows PowerShell 5.1) is present on this machine' -Skip:$skipTests { |
| 60 | + $script:winPS51Exe | Should -Not -BeNullOrEmpty |
| 61 | + } |
| 62 | + |
| 63 | + Context 'exits 3 when no rootDir is provided and no pipeline input' { |
| 64 | + |
| 65 | + BeforeAll { |
| 66 | + if (-not $script:winPS51Exe) { return } |
| 67 | + $script:result = Invoke-ToolProcess ` |
| 68 | + -Shell $script:winPS51Exe ` |
| 69 | + -ExecutionPolicy 'Bypass' ` |
| 70 | + -ScriptPath $script:scriptPath ` |
| 71 | + -Arguments @('-ProjectFile', 'C:\Fake\MyApp.dproj') |
| 72 | + } |
| 73 | + |
| 74 | + It 'exit code is 3' -Skip:$skipTests { |
| 75 | + $script:result.ExitCode | Should -Be 3 |
| 76 | + } |
| 77 | + |
| 78 | + It 'stderr contains helpful message' -Skip:$skipTests { |
| 79 | + $script:result.StdErr -join ' ' | Should -Match 'root dir' |
| 80 | + } |
| 81 | + |
| 82 | + } |
| 83 | + |
| 84 | + Context 'exits 3 when rootDir directory does not exist on disk' { |
| 85 | + |
| 86 | + BeforeAll { |
| 87 | + if (-not $script:winPS51Exe) { return } |
| 88 | + $script:result = Invoke-ToolProcess ` |
| 89 | + -Shell $script:winPS51Exe ` |
| 90 | + -ExecutionPolicy 'Bypass' ` |
| 91 | + -ScriptPath $script:scriptPath ` |
| 92 | + -Arguments @('-ProjectFile', 'C:\Fake\MyApp.dproj', '-RootDir', 'C:\DoesNotExist\AtAll\9999') |
| 93 | + } |
| 94 | + |
| 95 | + It 'exit code is 3' -Skip:$skipTests { |
| 96 | + $script:result.ExitCode | Should -Be 3 |
| 97 | + } |
| 98 | + |
| 99 | + It 'stderr mentions the missing directory' -Skip:$skipTests { |
| 100 | + $script:result.StdErr -join ' ' | Should -Match 'not found' |
| 101 | + } |
| 102 | + |
| 103 | + } |
| 104 | + |
| 105 | + Context 'exits 3 when rootDir exists but rsvars.bat is absent' { |
| 106 | + |
| 107 | + BeforeAll { |
| 108 | + if (-not $script:winPS51Exe) { return } |
| 109 | + $script:result = Invoke-ToolProcess ` |
| 110 | + -Shell $script:winPS51Exe ` |
| 111 | + -ExecutionPolicy 'Bypass' ` |
| 112 | + -ScriptPath $script:scriptPath ` |
| 113 | + -Arguments @('-ProjectFile', 'C:\Fake\MyApp.dproj', '-RootDir', ([System.IO.Path]::GetTempPath())) |
| 114 | + } |
| 115 | + |
| 116 | + It 'exit code is 3' -Skip:$skipTests { |
| 117 | + $script:result.ExitCode | Should -Be 3 |
| 118 | + } |
| 119 | + |
| 120 | + It 'stderr mentions rsvars.bat' -Skip:$skipTests { |
| 121 | + $script:result.StdErr -join ' ' | Should -Match 'rsvars\.bat' |
| 122 | + } |
| 123 | + |
| 124 | + } |
| 125 | + |
| 126 | + Context 'exits 4 when rsvars.bat exists but project file does not' { |
| 127 | + |
| 128 | + BeforeAll { |
| 129 | + if (-not $script:winPS51Exe) { return } |
| 130 | + $script:tempRoot = Join-Path ([System.IO.Path]::GetTempPath()) 'delphi-msbuild-winps51-test' |
| 131 | + $script:tempBin = Join-Path $script:tempRoot 'bin' |
| 132 | + $null = New-Item -ItemType Directory -Path $script:tempBin -Force |
| 133 | + $null = New-Item -ItemType File -Path (Join-Path $script:tempBin 'rsvars.bat') -Force |
| 134 | + |
| 135 | + $script:result = Invoke-ToolProcess ` |
| 136 | + -Shell $script:winPS51Exe ` |
| 137 | + -ExecutionPolicy 'Bypass' ` |
| 138 | + -ScriptPath $script:scriptPath ` |
| 139 | + -Arguments @('-ProjectFile', 'C:\Fake\DoesNotExist.dproj', '-RootDir', $script:tempRoot) |
| 140 | + } |
| 141 | + |
| 142 | + AfterAll { |
| 143 | + if ($script:tempRoot) { |
| 144 | + Remove-Item -LiteralPath $script:tempRoot -Recurse -Force -ErrorAction SilentlyContinue |
| 145 | + } |
| 146 | + } |
| 147 | + |
| 148 | + It 'exit code is 4' -Skip:$skipTests { |
| 149 | + $script:result.ExitCode | Should -Be 4 |
| 150 | + } |
| 151 | + |
| 152 | + It 'stderr mentions the missing project file' -Skip:$skipTests { |
| 153 | + $script:result.StdErr -join ' ' | Should -Match 'not found' |
| 154 | + } |
| 155 | + |
| 156 | + } |
| 157 | + |
| 158 | +} |
0 commit comments