|
| 1 | +param ( |
| 2 | + [Parameter(Mandatory)][string]$poshVcpkgModulePath, |
| 3 | + [Parameter(Mandatory)][System.IO.FileInfo]$vcpkgExe |
| 4 | +) |
| 5 | + |
| 6 | +BeforeAll { |
| 7 | + Import-Module $poshVcpkgModulePath |
| 8 | + |
| 9 | + $env:PATH = $vcpkgExe.Directory.FullName + [System.IO.Path]::PathSeparator + $env:PATH |
| 10 | + |
| 11 | + function Complete-InputCaret { |
| 12 | + [OutputType([string[]])] |
| 13 | + param ( |
| 14 | + [Parameter(Mandatory, Position = 0, ValueFromPipeline)] |
| 15 | + [string]$InputCaretScript |
| 16 | + ) |
| 17 | + $positionMatches = [regex]::Matches($InputCaretScript, '\^') |
| 18 | + if ($positionMatches.Count -ne 1) { |
| 19 | + throw 'Invalid caret cursor command, please indicate by only one ^ character' |
| 20 | + } |
| 21 | + $command = [string]$InputCaretScript.Replace('^', '') |
| 22 | + $cursorPosition = [int]$positionMatches[0].Index |
| 23 | + $result = [System.Management.Automation.CommandCompletion]::CompleteInput($command, $cursorPosition, $null) |
| 24 | + return $result.CompletionMatches | Select-Object -ExpandProperty CompletionText |
| 25 | + } |
| 26 | + |
| 27 | + $VcpkgPredefined = @{ |
| 28 | + CommandList = @( |
| 29 | + 'acquire_project', 'acquire', 'activate', 'add', 'create', 'deactivate', 'depend-info', 'edit', 'env' |
| 30 | + 'export', 'fetch', 'find', 'format-manifest', 'hash', 'help', 'install', 'integrate', 'list', 'new', 'owns' |
| 31 | + 'portsdiff', 'remove', 'search', 'update', 'upgrade', 'use', 'version', 'x-add-version', 'x-check-support' |
| 32 | + 'x-init-registry', 'x-package-info', 'x-regenerate', 'x-set-installed', 'x-update-baseline' |
| 33 | + 'x-update-registry', 'x-vsinstances' |
| 34 | + ) |
| 35 | + CommonParameterList = @() |
| 36 | + CommandOptionList = @{ |
| 37 | + install = @( |
| 38 | + '--allow-unsupported', '--clean-after-build', '--clean-buildtrees-after-build' |
| 39 | + '--clean-downloads-after-build', '--clean-packages-after-build', '--dry-run', '--editable' |
| 40 | + '--enforce-port-checks', '--head', '--keep-going', '--no-downloads', '--no-print-usage' |
| 41 | + '--only-binarycaching', '--only-downloads', '--recurse', '--x-feature', '--x-no-default-features' |
| 42 | + '--x-prohibit-backcompat-features', '--x-use-aria2', '--x-write-nuget-packages-config', '--x-xunit' |
| 43 | + ) |
| 44 | + remove = @( |
| 45 | + '--dry-run', '--outdated', '--purge', '--recurse' |
| 46 | + ) |
| 47 | + } |
| 48 | + } |
| 49 | + $VcpkgPredefined | Out-Null |
| 50 | +} |
| 51 | + |
| 52 | +Describe 'Prerequisites tests' { |
| 53 | + Context 'Internal function Complete-InputCaret tests' { |
| 54 | + It 'Complete-InputCaret 1 caret string should success' { |
| 55 | + { 'aaaa^' | Complete-InputCaret } | Should -Not -Throw |
| 56 | + } |
| 57 | + |
| 58 | + It 'Complete-InputCaret 0 caret string should throw' { |
| 59 | + { 'aaaa' | Complete-InputCaret } | Should -Throw |
| 60 | + } |
| 61 | + |
| 62 | + It 'Complete-InputCaret 2 caret string should throw' { |
| 63 | + { 'aaaa^^' | Complete-InputCaret } | Should -Throw |
| 64 | + } |
| 65 | + |
| 66 | + It 'Complete-InputCaret self should success' { |
| 67 | + 'Complete-InputCaret^' | Complete-InputCaret | Should -Contain 'Complete-InputCaret' |
| 68 | + } |
| 69 | + } |
| 70 | + |
| 71 | + Context 'Exist module and command tests' { |
| 72 | + It 'Should imported module posh-vcpkg' { |
| 73 | + (Get-Module -Name posh-vcpkg).Name | Should -Be 'posh-vcpkg' |
| 74 | + } |
| 75 | + |
| 76 | + It 'Should version greater than or equal 0.0.2' { |
| 77 | + (Get-Module posh-vcpkg).Version | Should -BeGreaterOrEqual '0.0.2' |
| 78 | + } |
| 79 | + |
| 80 | + It 'Should have executable vcpkg' { |
| 81 | + $vcpkgExe | Should -Exist |
| 82 | + } |
| 83 | + |
| 84 | + It 'Should have command vcpkg' { |
| 85 | + Get-Command -Name vcpkg | Should -Not -BeNullOrEmpty |
| 86 | + } |
| 87 | + |
| 88 | + It 'Should command vcpkg is the executable' { |
| 89 | + (Get-Command -Name vcpkg).Path | Should -Be $vcpkgExe.FullName |
| 90 | + } |
| 91 | + } |
| 92 | +} |
| 93 | + |
| 94 | +Describe 'Complete basic tests' { |
| 95 | + Context 'Complete full command contain tests' { |
| 96 | + It 'Should complete command [vcpkg <_>^] contain [<_>]' -ForEach @( |
| 97 | + 'help' |
| 98 | + 'install' |
| 99 | + 'version' |
| 100 | + 'integrate' |
| 101 | + ) { |
| 102 | + 'vcpkg {0}^' -f $_ | Complete-InputCaret | Should -Contain $_ |
| 103 | + } |
| 104 | + } |
| 105 | + |
| 106 | + Context 'Complete full command exact match tests' { |
| 107 | + It 'Should exact match command completions [vcpkg <_>^] be [<_>]' -ForEach @( |
| 108 | + 'help' |
| 109 | + 'install' |
| 110 | + 'version' |
| 111 | + 'integrate' |
| 112 | + ) { |
| 113 | + 'vcpkg {0}^' -f $_ | Complete-InputCaret | Should -Be $_ |
| 114 | + } |
| 115 | + } |
| 116 | + |
| 117 | + Context 'Complete part command contain tests' { |
| 118 | + It 'Should complete command [vcpkg <command>^] contain [<expected>]' -ForEach @( |
| 119 | + @{command = 'he'; expected = 'help' } |
| 120 | + @{command = 'in'; expected = 'install' } |
| 121 | + @{command = 've'; expected = 'version' } |
| 122 | + @{command = 'in'; expected = 'integrate' } |
| 123 | + ) { |
| 124 | + 'vcpkg {0}^' -f $command | Complete-InputCaret | Should -Contain $expected |
| 125 | + } |
| 126 | + } |
| 127 | + |
| 128 | + Context 'Complete space tests' { |
| 129 | + It 'Should complete command for blank space [vcpkg ^] contain [<_>]' -ForEach @( |
| 130 | + 'help' |
| 131 | + 'install' |
| 132 | + 'version' |
| 133 | + 'integrate' |
| 134 | + ) { |
| 135 | + 'vcpkg ^' | Complete-InputCaret | Should -Contain $_ |
| 136 | + } |
| 137 | + |
| 138 | + It 'Should exact match command completions for blank space [vcpkg ^]' { |
| 139 | + $completions = 'vcpkg ^' | Complete-InputCaret |
| 140 | + $expected = $VcpkgPredefined.CommandList |
| 141 | + Compare-Object $completions $expected | Should -BeNullOrEmpty |
| 142 | + } |
| 143 | + } |
| 144 | +} |
| 145 | + |
| 146 | +Describe 'Complete command tests' { |
| 147 | + Context 'Complete common option tests' -Skip { |
| 148 | + It 'Should complete common option for blank space [vcpkg ^] contain [--host-triplet]' { |
| 149 | + 'vcpkg ^' | Complete-InputCaret | Should -Contain '--host-triplet' |
| 150 | + } |
| 151 | + |
| 152 | + It 'Should complete common option for blank space [vcpkg ^] contain [--host-triplet=]' { |
| 153 | + 'vcpkg ^' | Complete-InputCaret | Should -Contain '--host-triplet=' |
| 154 | + } |
| 155 | + |
| 156 | + It 'Should complete common option for blank space [vcpkg ^] contain [--vcpkg-root]' { |
| 157 | + 'vcpkg ^' | Complete-InputCaret | Should -Contain '--vcpkg-root' |
| 158 | + } |
| 159 | + |
| 160 | + It 'Should complete common option for blank space [vcpkg ^] contain [--vcpkg-root=]' { |
| 161 | + 'vcpkg ^' | Complete-InputCaret | Should -Contain '--vcpkg-root=' |
| 162 | + } |
| 163 | + } |
| 164 | + |
| 165 | + Context 'Complete common option argument tests' -Skip { |
| 166 | + It 'Should complete common option arguments for [vcpkg --triplet^] contain [--triplet=]' { |
| 167 | + 'vcpkg --triplet^' -f $argument | Complete-InputCaret | Should -Contain '--triplet=x64-windows' |
| 168 | + } |
| 169 | + |
| 170 | + It 'Should complete common option arguments for [vcpkg --triplet=^] contain [--triplet=x64-windows]' { |
| 171 | + 'vcpkg --triplet=^' -f $argument | Complete-InputCaret | Should -Contain '--triplet=x64-windows' |
| 172 | + } |
| 173 | + |
| 174 | + It 'Should complete common option arguments for [vcpkg --triplet=x64^] contain [--triplet=x64-windows]' { |
| 175 | + 'vcpkg --triplet=x64^' -f $argument | Complete-InputCaret | Should -Contain '--triplet=x64-windows' |
| 176 | + } |
| 177 | + } |
| 178 | + |
| 179 | + # Skip due to https://github.com/PowerShell/PowerShell/issues/2912 |
| 180 | + Context 'Complete command option list tests conditionally - CoreOnly' -Tag CoreOnly { |
| 181 | + It 'Should complete option flags with single minus [vcpkg <command> -^] contain [<expected>]' -ForEach @( |
| 182 | + @{ command = 'install' ; expected = '--editable' } |
| 183 | + @{ command = 'remove' ; expected = '--dry-run' } |
| 184 | + ) { |
| 185 | + 'vcpkg {0} -^' -f $command | Complete-InputCaret | Should -Contain $expected |
| 186 | + } |
| 187 | + |
| 188 | + It 'Should complete option flags with double minus [vcpkg <command> --^] contain [<expected>]' -ForEach @( |
| 189 | + @{ command = 'install' ; expected = '--editable' } |
| 190 | + @{ command = 'remove' ; expected = '--dry-run' } |
| 191 | + ) { |
| 192 | + 'vcpkg {0} --^' -f $command | Complete-InputCaret | Should -Contain $expected |
| 193 | + } |
| 194 | + |
| 195 | + It 'Should exact match command options for double minus [vcpkg <_> --^]' -ForEach @( |
| 196 | + 'install' |
| 197 | + 'remove' |
| 198 | + ) { |
| 199 | + $completions = 'vcpkg {0} --^' -f $_ | Complete-InputCaret |
| 200 | + $expected = $VcpkgPredefined.CommandOptionList[$_] |
| 201 | + Compare-Object $completions $expected | Should -BeNullOrEmpty |
| 202 | + } |
| 203 | + } |
| 204 | + |
| 205 | + Context 'Complete command argument tests conditionally' { |
| 206 | + It 'Should complete install with port name [<caretCmd>] contain [<expected>]' -ForEach @( |
| 207 | + @{ caretCmd = 'vcpkg install vcpkg-^' ; expected = 'vcpkg-cmake' } |
| 208 | + ) { |
| 209 | + $caretCmd | Complete-InputCaret | Should -Contain $expected |
| 210 | + } |
| 211 | + |
| 212 | + It 'Should complete install port with triplet [<caretCmd>] contain [<expected>]' -ForEach @( |
| 213 | + @{ caretCmd = 'vcpkg install vcpkg-cmake:^' ; expected = 'vcpkg-cmake:x64-windows' } |
| 214 | + ) { |
| 215 | + $caretCmd | Complete-InputCaret | Should -Contain $expected |
| 216 | + } |
| 217 | + |
| 218 | + It 'Should complete integrate with subcommand [vcpkg integrate inst^] be [install]' { |
| 219 | + 'vcpkg integrate inst^' | Complete-InputCaret | Should -Be 'install' |
| 220 | + } |
| 221 | + |
| 222 | + It 'Should complete integrate with subcommand [vcpkg integrate ^] contain [powershell] - WindowsOnly' -Tag WindowsOnly { |
| 223 | + 'vcpkg integrate ^' | Complete-InputCaret | Should -Contain 'powershell' |
| 224 | + } |
| 225 | + |
| 226 | + It 'Should complete integrate with subcommand [vcpkg integrate ^] contain [bash] - NonWindowsOnly' -Tag NonWindowsOnly { |
| 227 | + 'vcpkg integrate ^' | Complete-InputCaret | Should -Contain 'bash' |
| 228 | + } |
| 229 | + |
| 230 | + It 'Should exact match command subcommands [vcpkg integrate ^] - WindowsOnly' -Tag WindowsOnly { |
| 231 | + $expected = @('install', 'remove', 'powershell', 'project') |
| 232 | + $completions = 'vcpkg integrate ^' | Complete-InputCaret |
| 233 | + Compare-Object $completions $expected | Should -BeNullOrEmpty |
| 234 | + } |
| 235 | + |
| 236 | + It 'Should exact match command subcommands [vcpkg integrate ^] - NonWindowsOnly' -Tag NonWindowsOnly { |
| 237 | + $expected = @('install', 'remove', 'bash', 'x-fish', 'zsh') |
| 238 | + $completions = 'vcpkg integrate ^' | Complete-InputCaret |
| 239 | + Compare-Object $completions $expected | Should -BeNullOrEmpty |
| 240 | + } |
| 241 | + } |
| 242 | +} |
| 243 | + |
| 244 | +Describe 'Complete variants tests' { |
| 245 | + BeforeAll { |
| 246 | + Set-Variable vcpkgWithExt ($vcpkgExe.FullName) |
| 247 | + Set-Variable vcpkgNoExt ([System.IO.Path]::GetFileNameWithoutExtension($vcpkgExe.FullName)) |
| 248 | + } |
| 249 | + |
| 250 | + Context 'Complete basic variant command tests' { |
| 251 | + It 'Should exact match command completions with call operator absolute exe word be [version]' { |
| 252 | + "& $vcpkgWithExt ver^" | Complete-InputCaret | Should -Be 'version' |
| 253 | + } |
| 254 | + |
| 255 | + It 'Should exact match command completions [<caretCmd>] <comment> be [version]' -ForEach @( |
| 256 | + @{ caretCmd = 'vcpkg ver^' ; comment = 'with word' } |
| 257 | + @{ caretCmd = '& vcpkg ver^' ; comment = 'with & word' } |
| 258 | + ) { |
| 259 | + $caretCmd | Complete-InputCaret | Should -Be 'version' |
| 260 | + } |
| 261 | + |
| 262 | + It 'Should exact match command completions for exe path [<caretCmd>] <comment> be [version]' -ForEach @( |
| 263 | + @{ caretCmd = './vcpkg ver^' ; comment = 'with dot slash word' } |
| 264 | + @{ caretCmd = '& ./vcpkg ver^' ; comment = 'with & dot slash word' } |
| 265 | + ) { |
| 266 | + Set-Location $vcpkgExe.Directory |
| 267 | + $caretCmd | Complete-InputCaret | Should -Be 'version' |
| 268 | + } |
| 269 | + } |
| 270 | + |
| 271 | + Context 'Complete variant command tests conditionally - WindowsOnly' -Tag WindowsOnly { |
| 272 | + It 'Should exact match command completions with call operator no-ext absolute exe word be [version]' { |
| 273 | + "& $vcpkgNoExt ver^" | Complete-InputCaret | Should -Be 'version' |
| 274 | + } |
| 275 | + |
| 276 | + It 'Should exact match command completions [<caretCmd>] <comment> be [version]' -ForEach @( |
| 277 | + @{ caretCmd = '& vcpkg.exe ver^' ; comment = 'with & extension word' } |
| 278 | + @{ caretCmd = 'vcpkg.exe ver^' ; comment = 'with extension word' } |
| 279 | + ) { |
| 280 | + $caretCmd | Complete-InputCaret | Should -Be 'version' |
| 281 | + } |
| 282 | + |
| 283 | + It 'Should exact match command completions for exe path [<caretCmd>] <comment> be [version]' -ForEach @( |
| 284 | + @{ caretCmd = '.\vcpkg ver^' ; comment = 'with dot backslash word' } |
| 285 | + @{ caretCmd = '& .\vcpkg ver^' ; comment = 'with & dot backslash word' } |
| 286 | + @{ caretCmd = './vcpkg.exe ver^' ; comment = 'with dot slash extension word' } |
| 287 | + @{ caretCmd = '.\vcpkg.exe ver^' ; comment = 'with dot backslash extension word' } |
| 288 | + @{ caretCmd = '& ./vcpkg.exe ver^' ; comment = 'with & dot slash extension word' } |
| 289 | + @{ caretCmd = '& .\vcpkg.exe ver^' ; comment = 'with & dot backslash extension word' } |
| 290 | + ) { |
| 291 | + Set-Location $vcpkgExe.Directory |
| 292 | + $caretCmd | Complete-InputCaret | Should -Be 'version' |
| 293 | + } |
| 294 | + } |
| 295 | + |
| 296 | + Context 'Complete command with spaces tests' { |
| 297 | + It 'Should complete command [<caretCmd>] <comment> contain [version]' -ForEach @( |
| 298 | + @{ caretCmd = 'vcpkg ^' ; comment = 'many spaces' } |
| 299 | + @{ caretCmd = 'vcpkg ver^' ; comment = 'middle many spaces' } |
| 300 | + @{ caretCmd = ' vcpkg ver^' ; comment = 'with leading spaces' } |
| 301 | + @{ caretCmd = ' & vcpkg ver^' ; comment = 'with leading spaces and call operator' } |
| 302 | + ) { |
| 303 | + $caretCmd | Complete-InputCaret | Should -Contain 'version' |
| 304 | + } |
| 305 | + } |
| 306 | + |
| 307 | + Context 'Complete command quotation tests' { |
| 308 | + It "Should fallback to default completion with quoted full word [vcpkg 'install'^]" { |
| 309 | + "vcpkg 'install'^" | Complete-InputCaret | Should -Be $null |
| 310 | + } |
| 311 | + |
| 312 | + It "Should prevent completion for quoted space [vcpkg ' '^]" { |
| 313 | + "vcpkg ' '^" | Complete-InputCaret | Should -Be $null |
| 314 | + } |
| 315 | + } |
| 316 | +} |
| 317 | + |
| 318 | +Describe 'Complete position tests' { |
| 319 | + Context 'Complete command intermediate tests' { |
| 320 | + It 'Should exact match command completions [<caretCmd>] <comment> be [version]' -ForEach @( |
| 321 | + @{ caretCmd = 'vcpkg version^'; comment = 'end of word' } |
| 322 | + @{ caretCmd = 'vcpkg ver^sion'; comment = 'middle of word' } |
| 323 | + ) { |
| 324 | + $caretCmd | Complete-InputCaret | Should -Be 'version' |
| 325 | + } |
| 326 | + |
| 327 | + It 'Should exact match command completions [<_>]' -ForEach @( |
| 328 | + 'vcpkg ^version' |
| 329 | + 'vcpkg ^ ' |
| 330 | + 'vcpkg ^ ' |
| 331 | + ' vcpkg ^ ' |
| 332 | + ' & vcpkg ^ ' |
| 333 | + 'vcpkg ^ version ' |
| 334 | + ) { |
| 335 | + $completions = $_ | Complete-InputCaret |
| 336 | + $expected = $VcpkgPredefined.CommandList |
| 337 | + Compare-Object $completions $expected | Should -BeNullOrEmpty |
| 338 | + } |
| 339 | + } |
| 340 | + |
| 341 | + Context 'Complete complex tests' { |
| 342 | + It 'Should complete complex command line [<caretCmd>] be [<expected>]' -ForEach ( |
| 343 | + @{ caretCmd = 'echo powershell | % { vcpkg int^egr $_ }; echo $?'; expected = 'integrate' } |
| 344 | + ) { |
| 345 | + $caretCmd | Complete-InputCaret | Should -Be $expected |
| 346 | + } |
| 347 | + } |
| 348 | +} |
| 349 | + |
| 350 | +Describe 'Impossible command tests' { |
| 351 | + Context 'Complete non-exist command tests conditionally' { |
| 352 | + It 'Should prevent completion for non-exist command [vcpkg zzzzzzzz^]' { |
| 353 | + 'vcpkg zzzzzzzz^' | Complete-InputCaret | Should -Be $null |
| 354 | + } |
| 355 | + |
| 356 | + It 'Should prevent completion for non-exist command [vcpkg ---^]' { |
| 357 | + 'vcpkg ---^' | Complete-InputCaret | Should -Be $null |
| 358 | + } |
| 359 | + |
| 360 | + It 'Should fallback to default for non-exist command with trailing spaces [vcpkg zzzzzzzz ^] - WindowsOnly' -Tag WindowsOnly { |
| 361 | + 'vcpkg zzzzzzzz ^' | Complete-InputCaret | Should -BeLike '.\*' |
| 362 | + } |
| 363 | + |
| 364 | + It 'Should fallback to default for non-exist command with trailing spaces [vcpkg zzzzzzzz ^] - NonWindowsOnly' -Tag NonWindowsOnly { |
| 365 | + 'vcpkg zzzzzzzz ^' | Complete-InputCaret | Should -BeLike './*' |
| 366 | + } |
| 367 | + } |
| 368 | + |
| 369 | + Context 'Complete error command tests' { |
| 370 | + It 'Should prevent error from error command [vcpkg --triplet^]' { |
| 371 | + { $ErrorActionPreference = 'Stop'; 'vcpkg --triplet^' | Complete-InputCaret } | Should -Not -Throw |
| 372 | + } |
| 373 | + |
| 374 | + It 'Should prevent completion for error command [vcpkg --triplet^]' { |
| 375 | + 'vcpkg --triplet^' | Complete-InputCaret | Should -Be $null |
| 376 | + } |
| 377 | + } |
| 378 | +} |
0 commit comments