diff --git a/azure-pipelines/e2e-specs/autocomplete-posh-vcpkg.Tests.ps1 b/azure-pipelines/e2e-specs/autocomplete-posh-vcpkg.Tests.ps1 new file mode 100644 index 0000000000..abd2b2fbed --- /dev/null +++ b/azure-pipelines/e2e-specs/autocomplete-posh-vcpkg.Tests.ps1 @@ -0,0 +1,307 @@ +param ( + [Parameter(Mandatory)][string]$poshVcpkgModulePath, + [Parameter(Mandatory)][string]$vcpkgExeDir +) + +BeforeAll { + Import-Module $poshVcpkgModulePath + + $env:PATH = $vcpkgExeDir + [System.IO.Path]::PathSeparator + $env:PATH + + function Complete-InputCaret { + [OutputType([string[]])] + param ( + [Parameter(Mandatory, Position = 0, ValueFromPipeline)] + [string]$InputCaretScript + ) + $positionMatches = [regex]::Matches($InputCaretScript, '\^') + if ($positionMatches.Count -ne 1) { + throw 'Invalid caret cursor command, please indicate by only one ^ character' + } + $command = [string]$InputCaretScript.Replace('^', '') + $cursorPosition = [int]$positionMatches[0].Index + $result = [System.Management.Automation.CommandCompletion]::CompleteInput($command, $cursorPosition, $null) + return $result.CompletionMatches | Select-Object -ExpandProperty CompletionText + } +} + +Describe 'Prerequisites tests' { + Context 'Internal function Complete-InputCaret tests' { + It 'Complete-InputCaret 1 caret string should success' { + { 'aaaa^' | Complete-InputCaret } | Should -Not -Throw + } + + It 'Complete-InputCaret 0 caret string should throw' { + { 'aaaa' | Complete-InputCaret } | Should -Throw + } + + It 'Complete-InputCaret 2 caret string should throw' { + { 'aaaa^^' | Complete-InputCaret } | Should -Throw + } + + It 'Complete-InputCaret self should success' { + 'Complete-InputCaret^' | Complete-InputCaret | Should -Contain 'Complete-InputCaret' + } + } + + Context 'Exist module and command tests' { + It 'Should imported module posh-vcpkg' { + (Get-Module -Name posh-vcpkg).Name | Should -Be 'posh-vcpkg' + } + + It 'Should have command vcpkg' { + Get-Command -Name vcpkg | Should -Not -BeNullOrEmpty + } + } +} + +Describe 'Module posh-vcpkg tests' { +} + +Describe 'Complete position tests' { +} + +Describe 'Complete append tests' { + Context 'Complete command tests' { + It 'Should exact match command completions [vcpkg ver^] be [version]' { + 'vcpkg ver^' | Complete-InputCaret | Should -Be 'version' + } + + It 'Should complete command [vcpkg in^] contain [install]' { + 'vcpkg in^' | Complete-InputCaret | Should -Contain 'install' + } + + It 'Should complete command [vcpkg in^] contain [integrate]' { + 'vcpkg in^' | Complete-InputCaret | Should -Contain 'integrate' + } + } + + Context 'Complete command list tests' { + It 'Should complete command for blank space [vcpkg ^] contain [<_>]' -ForEach @( + 'help' + 'install' + 'list' + 'remove' + 'version' + ) { + 'vcpkg ^' | Complete-InputCaret | Should -Contain $_ + } + + It 'Should exact match command completions for blank space [vcpkg ^]' { + $completions = 'vcpkg ^' | Complete-InputCaret + $expected = @( + 'acquire', 'create', 'env', 'format-manifest', 'integrate', 'portsdiff', 'upgrade', 'x-check-support' + 'x-set-installed', 'acquire_project', 'deactivate', 'export', 'hash', 'list', 'remove', 'use' + 'x-init-registry', 'x-update-baseline', 'activate', 'depend-info', 'fetch', 'help', 'new', 'search' + 'version', 'x-package-info', 'x-update-registry', 'add', 'edit', 'find', 'install', 'owns', 'update' + 'x-add-version', 'x-regenerate', 'x-vsinstances' + ) + Compare-Object $completions $expected | Should -BeNullOrEmpty + } + } + + Context 'Complete common option tests' { + It 'Should not complete common option for blank space [vcpkg ^] not yet contain [<_>]' -ForEach @( + '--host-triplet', '--host-triplet=' + '--triplet', '--triplet=' + '--vcpkg-root', '--vcpkg-root=' + ) { + 'vcpkg ^' | Complete-InputCaret | Should -Not -Contain $_ + } + } + + Context 'Complete common option argument tests' { + It 'Should not complete common option arguments for [vcpkg ^] not yet contain []' -ForEach @( + @{ argument = '--triplet=' ; expected = '--triplet=x64-windows' } + @{ argument = '--triplet=x64' ; expected = '--triplet=x64-windows' } + ) { + 'vcpkg {0}^' -f $argument | Complete-InputCaret | Should -Not -Contain $expected + } + } + + # Skip due to https://github.com/PowerShell/PowerShell/issues/2912 + Context 'Complete command option list tests conditionally - CoreOnly' -Tag CoreOnly { + + It 'Should complete option flags with single minus [vcpkg -^] contain []' -ForEach @( + @{ command = 'install' ; expected = '--editable' } + @{ command = 'remove' ; expected = '--dry-run' } + ) { + 'vcpkg {0} -^' -f $command | Complete-InputCaret | Should -Contain $expected + } + + It 'Should complete option flags with double minus [vcpkg --^] contain []' -ForEach @( + @{ command = 'install' ; expected = '--editable' } + @{ command = 'remove' ; expected = '--dry-run' } + ) { + 'vcpkg {0} --^' -f $command | Complete-InputCaret | Should -Contain $expected + } + + It 'Should exact match command options for double minus [vcpkg --^]' -ForEach @( + @{ + command = 'install' + expected = @( + '--allow-unsupported', '--clean-after-build', '--clean-buildtrees-after-build' + '--clean-downloads-after-build', '--clean-packages-after-build', '--dry-run', '--editable' + '--enforce-port-checks', '--head', '--keep-going', '--no-downloads', '--no-print-usage' + '--only-binarycaching', '--only-downloads', '--recurse', '--x-feature', '--x-no-default-features' + '--x-prohibit-backcompat-features', '--x-use-aria2', '--x-write-nuget-packages-config', '--x-xunit' + ) + } + @{ + command = 'remove' + expected = @('--dry-run', '--outdated', '--purge', '--recurse') + } + ) { + $completions = ('vcpkg {0} --^' -f $command) | Complete-InputCaret + Compare-Object $completions $expected | Should -BeNullOrEmpty + } + } + + Context 'Complete command argument tests conditionally' { + It 'Should complete install with port name [] contain []' -ForEach @( + @{ caretCmd = 'vcpkg install vcpkg-^' ; expected = 'vcpkg-cmake' } + ) { + $caretCmd | Complete-InputCaret | Should -Contain $expected + } + + It 'Should complete install port with triplet [] contain []' -ForEach @( + @{ caretCmd = 'vcpkg install vcpkg-cmake:^' ; expected = 'vcpkg-cmake:x64-windows' } + ) { + $caretCmd | Complete-InputCaret | Should -Contain $expected + } + + It 'Should complete integrate with subcommand [vcpkg integrate ^] contain [powershell] - WindowsOnly' -Tag WindowsOnly { + 'vcpkg integrate ^' | Complete-InputCaret | Should -Contain 'powershell' + } + + It 'Should complete integrate with subcommand [vcpkg integrate ^] contain [bash] - NonWindowsOnly' -Tag NonWindowsOnly { + 'vcpkg integrate ^' | Complete-InputCaret | Should -Contain 'bash' + } + + It 'Should exact match command subcommands [vcpkg integrate ^] - WindowsOnly' -Tag WindowsOnly { + $expected = @('install', 'remove', 'powershell', 'project') + $completions = 'vcpkg integrate ^' | Complete-InputCaret + Compare-Object $completions $expected | Should -BeNullOrEmpty + } + + It 'Should exact match command subcommands [vcpkg integrate ^] - NonWindowsOnly' -Tag NonWindowsOnly { + $expected = @('install', 'remove', 'bash', 'x-fish', 'zsh') + $completions = 'vcpkg integrate ^' | Complete-InputCaret + Compare-Object $completions $expected | Should -BeNullOrEmpty + } + } +} + +# Context 'Complete command name tests' { + +# It -Skip 'Should complete command list with blank space []' -TestCases ( +# @{ caretCmd = 'vcpkg ^' ; expected = 'version'; comment = 'without word' }, +# @{ caretCmd = 'vcpkg ver^' ; expected = 'version'; comment = 'with word' }, +# @{ caretCmd = 'vcpkg.exe ver^' ; expected = 'version'; comment = 'with native exe' }, +# @{ caretCmd = './vcpkg ver^' ; expected = 'version'; comment = 'with dot slash' }, +# @{ caretCmd = '.\vcpkg ver^' ; expected = 'version'; comment = 'with dot backslash' } +# ) { +# param($caretCmd, $expected, $comment) +# $caretCmd | Complete-InputCaret | Should -Contain $expected +# } + +# It -Skip 'Should complete command word [] with [] with ' -TestCases ( +# @{ caretCmd = 'vcpkg ^' ; expected = 'version'; comment = 'without word' }, +# @{ caretCmd = 'vcpkg ver^' ; expected = 'version'; comment = 'with word' }, +# @{ caretCmd = 'vcpkg.exe ver^' ; expected = 'version'; comment = 'with native exe' }, +# @{ caretCmd = './vcpkg ver^' ; expected = 'version'; comment = 'with dot slash' }, +# @{ caretCmd = '.\vcpkg ver^' ; expected = 'version'; comment = 'with dot backslash' } +# ) { +# param($caretCmd, $expected, $comment) +# $caretCmd | Complete-InputCaret | Should -Contain $expected +# } + +# } + +# Context -Skip 'Complete command spaces tests' { + +# It 'Should complete command []' -TestCases ( +# @{ comment = 'spaces without argument'; caretCmd = 'vcpkg ^'; expected = 'version' }, +# @{ comment = 'before remaining'; caretCmd = 'vcpkg ver^'; expected = 'version' }, +# # @{ comment = 'with trailing spaces'; caretCmd = 'vcpkg ver ^'; expected = 'version' }, +# @{ comment = 'with leading spaces'; caretCmd = ' vcpkg ver^'; expected = 'version' } +# ) { +# param($caretCmd, $expected, $comment) +# $caretCmd | Complete-InputCaret | Should -Contain $expected +# } + +# It 'Should complete command with trailing spaces [vcpkg ver ^]' -Skip { +# 'vcpkg ver ^' | Complete-InputCaret | Should -Contain 'version' +# } + +# } + +# Context -Skip 'Complete command quotation tests' { + +# It "Should complete command with quoted word [vcpkg 'ver'^]" { +# "vcpkg 'ver'^" | Complete-InputCaret | Should -Contain 'version' +# } + +# It "Should complete command with quoted space [vcpkg ' '^]" { +# "vcpkg 'ver'^" | Complete-InputCaret | Should -Contain 'version' +# } + +# It "Should complete command with quoted word [vcpkg 'version'^]" { +# "vcpkg 'ver'^" | Complete-InputCaret | Should -Contain 'version' +# } + +# } + +# Context -Skip 'Complete command intermediate tests' { + +# It 'Should complete command []' -TestCases ( +# @{ comment = 'end of word'; caretCmd = 'vcpkg version^'; expected = 'version' }, +# @{ comment = 'middle of word'; caretCmd = 'vcpkg ver^sion'; expected = 'version' }, +# @{ comment = 'front of word'; caretCmd = 'vcpkg ^version'; expected = 'version' } +# ) { +# param($caretCmd, $expected, $comment) +# $caretCmd | Complete-InputCaret | Should -Contain $expected +# } + +# } + +# Context -Skip 'Complete subcommand tests' { + +# It 'Should complete subcommand [] from []' -TestCases ( +# @{ caretCmd = 'vcpkg depend^'; expected = 'depend-info' }, +# @{ caretCmd = 'vcpkg inst^'; expected = 'install' }, +# @{ caretCmd = 'vcpkg int^'; expected = 'integrate' }, +# @{ caretCmd = 'vcpkg rem^'; expected = 'remove' } +# ) { +# param($caretCmd, $expected) +# @($caretCmd | Complete-InputCaret)[0] | Should -BeExactly $expected +# } + +# It 'Should complete subcommand two-level [powershell] from [vcpkg integrate power^]' -Skip { +# 'vcpkg integrate power^' | Complete-InputCaret | Should -Contain 'powershell' +# } + +# } + +# Context -Skip 'Complete subcommand argument and options tests' { + +# It 'Should complete argument [] from []' -TestCases ( +# @{ caretCmd = 'vcpkg install vcpkg-cmake^'; expected = 'vcpkg-cmake-get-vars' }, +# @{ caretCmd = 'vcpkg install vcpkg-cmake --^'; expected = '--dry-run' } +# ) { +# param($caretCmd, $expected) +# $caretCmd | Complete-InputCaret | Should -Contain $expected +# } + +# } + +# Context -Skip 'Complete complex tests' { + +# It 'Should complete complex line [] from []' -TestCases ( +# @{ caretCmd = 'echo powershell | % { vcpkg ver^ $_ }; echo $?'; expected = 'version' } +# ) { +# param($caretCmd, $expected) +# $caretCmd | Complete-InputCaret | Should -Contain $expected +# } + +# } diff --git a/azure-pipelines/end-to-end-tests-dir/autocomplete-posh-vcpkg.ps1 b/azure-pipelines/end-to-end-tests-dir/autocomplete-posh-vcpkg.ps1 new file mode 100644 index 0000000000..6cd3d94ec1 --- /dev/null +++ b/azure-pipelines/end-to-end-tests-dir/autocomplete-posh-vcpkg.ps1 @@ -0,0 +1,36 @@ + +[string]$poshVcpkgModulePath = "$PSScriptRoot/../../scripts/posh-vcpkg.psd1" +[string]$vcpkgExeDir = $VcpkgItem.Directory.FullName + +[string]$TestSpecsDir = "$PSScriptRoot/../e2e-specs" + +$containerPosh = New-PesterContainer -Path @( + "$TestSpecsDir/autocomplete-posh-vcpkg.Tests.ps1" +) -Data @( + @{ + poshVcpkgModulePath = $poshVcpkgModulePath + vcpkgExeDir = $vcpkgExeDir + } +) + +if ($null -eq $IsWindows) { Set-Variable IsWindows $true } + +$configuration = [PesterConfiguration]@{ + Run = @{ + Container = @( + $containerPosh + ) + } + Output = @{ + Verbosity = 'Detailed' + } + Filter = @{ + ExcludeTag = @{ + NonWindowsOnly = -not $IsWindows + WindowsOnly = $IsWindows + CoreOnly = 'Core' -eq $PSEdition + }.GetEnumerator().Where{ -not $_.Value }.ForEach{ $_.Name } + } +} + +Invoke-Pester -Configuration $configuration