mirror of
https://github.com/aphrody-labs/PowerShell.git
synced 2026-10-14 13:49:09 +00:00
299 lines
13 KiB
PowerShell
299 lines
13 KiB
PowerShell
# Copyright (c) Microsoft Corporation.
|
|
# Licensed under the MIT License.
|
|
Describe "Tab completion bug fix" -Tags "CI" {
|
|
|
|
It "Issue#682 - '[system.manage<tab>' should work" {
|
|
$result = TabExpansion2 -inputScript "[system.manage" -cursorColumn "[system.manage".Length
|
|
$result.CompletionMatches | Should -HaveCount 1
|
|
$result.CompletionMatches[0].CompletionText | Should -BeExactly "System.Management"
|
|
}
|
|
|
|
It "Issue#1350 - '1 -sp<tab>' should work" {
|
|
$result = TabExpansion2 -inputScript "1 -sp" -cursorColumn "1 -sp".Length
|
|
$result.CompletionMatches | Should -HaveCount 1
|
|
$result.CompletionMatches[0].CompletionText | Should -BeExactly "-split"
|
|
}
|
|
|
|
It "Issue#1350 - '1 -a<tab>' should work" {
|
|
$result = TabExpansion2 -inputScript "1 -a" -cursorColumn "1 -a".Length
|
|
$result.CompletionMatches | Should -HaveCount 2
|
|
$result.CompletionMatches[0].CompletionText | Should -BeExactly "-and"
|
|
$result.CompletionMatches[1].CompletionText | Should -BeExactly "-as"
|
|
}
|
|
It "Issue#2295 - '[pscu<tab>' should expand to [pscustomobject]" {
|
|
$result = TabExpansion2 -inputScript "[pscu" -cursorColumn "[pscu".Length
|
|
$result.CompletionMatches | Should -HaveCount 1
|
|
$result.CompletionMatches[0].CompletionText | Should -BeExactly "pscustomobject"
|
|
}
|
|
It "Issue#1345 - 'Import-Module -n<tab>' should work" {
|
|
$cmd = "Import-Module -n"
|
|
$result = TabExpansion2 -inputScript $cmd -cursorColumn $cmd.Length
|
|
$result.CompletionMatches | Should -HaveCount 2
|
|
$result.CompletionMatches[0].CompletionText | Should -BeExactly "-Name"
|
|
$result.CompletionMatches[1].CompletionText | Should -BeExactly "-NoClobber"
|
|
}
|
|
|
|
It "Issue#11227 - [CompletionCompleters]::CompleteVariable and [CompletionCompleters]::CompleteType should work" {
|
|
$result = [System.Management.Automation.CompletionCompleters]::CompleteType("CompletionComple")
|
|
$result.Count | Should -BeExactly 1
|
|
$result[0].CompletionText | Should -BeExactly 'System.Management.Automation.CompletionCompleters'
|
|
|
|
$result = [System.Management.Automation.CompletionCompleters]::CompleteVariable("errorAction")
|
|
$result.Count | Should -BeExactly 1
|
|
$result[0].CompletionText | Should -BeExactly '$ErrorActionPreference'
|
|
}
|
|
|
|
It "Issue#24756 - Wildcard completions should not return early due to missing results in one container" -Skip:(!$IsWindows) {
|
|
try
|
|
{
|
|
$keys = New-Item -Path @(
|
|
'HKCU:\AB1'
|
|
'HKCU:\AB2'
|
|
'HKCU:\AB2\Test'
|
|
)
|
|
|
|
$res = TabExpansion2 -inputScript 'Get-ChildItem -Path HKCU:\AB?\'
|
|
$res.CompletionMatches.Count | Should -Be 1
|
|
$res.CompletionMatches[0].CompletionText | Should -BeExactly "HKCU:\AB2\Test"
|
|
}
|
|
finally
|
|
{
|
|
if ($keys)
|
|
{
|
|
Remove-Item -Path HKCU:\AB? -Recurse -ErrorAction SilentlyContinue
|
|
}
|
|
}
|
|
}
|
|
|
|
Context "Issue#3416 - 'Select-Object'" {
|
|
BeforeAll {
|
|
$DatetimeProperties = @((Get-Date).psobject.baseobject.psobject.properties) | Sort-Object -Property Name
|
|
}
|
|
It "Issue#3416 - 'Select-Object -ExcludeProperty <tab>' should work" {
|
|
$cmd = "Get-Date | Select-Object -ExcludeProperty "
|
|
$result = TabExpansion2 -inputScript $cmd -cursorColumn $cmd.Length
|
|
$result.CompletionMatches | Should -HaveCount $DatetimeProperties.Count
|
|
$result.CompletionMatches[0].CompletionText | Should -BeExactly $DatetimeProperties[0].Name # Date
|
|
$result.CompletionMatches[1].CompletionText | Should -BeExactly $DatetimeProperties[1].Name # DateTime
|
|
}
|
|
It "Issue#3416 - 'Select-Object -ExpandProperty <tab>' should work" {
|
|
$cmd = "Get-Date | Select-Object -ExpandProperty "
|
|
$result = TabExpansion2 -inputScript $cmd -cursorColumn $cmd.Length
|
|
$result.CompletionMatches | Should -HaveCount $DatetimeProperties.Count
|
|
$result.CompletionMatches[0].CompletionText | Should -BeExactly $DatetimeProperties[0].Name # Date
|
|
$result.CompletionMatches[1].CompletionText | Should -BeExactly $DatetimeProperties[1].Name # DateTime
|
|
}
|
|
}
|
|
|
|
It "Issue#3628 - 'Sort-Object @{<tab>' should work" {
|
|
$cmd = "Get-Date | Sort-Object @{"
|
|
$result = TabExpansion2 -inputScript $cmd -cursorColumn $cmd.Length
|
|
$result.CompletionMatches | Should -HaveCount 3
|
|
$result.CompletionMatches[0].CompletionText | Should -BeExactly 'Expression'
|
|
$result.CompletionMatches[1].CompletionText | Should -BeExactly 'Ascending'
|
|
$result.CompletionMatches[2].CompletionText | Should -BeExactly 'Descending'
|
|
}
|
|
|
|
It "'Get-Date | Sort-Object @{Expression=<tab>' should work without completion" {
|
|
$cmd = "Get-Date | Sort-Object @{Expression="
|
|
$result = TabExpansion2 -inputScript $cmd -cursorColumn $cmd.Length
|
|
$result.CompletionMatches | Should -HaveCount 0
|
|
}
|
|
|
|
It "Issue#5322 - 'Get-Date | Sort-Object @{Expression=...;' should work" {
|
|
$cmd = "Get-Date | Sort-Object @{Expression=...;"
|
|
$result = TabExpansion2 -inputScript $cmd -cursorColumn $cmd.Length
|
|
$result.CurrentMatchIndex | Should -Be -1
|
|
$result.ReplacementIndex | Should -Be 40
|
|
$result.ReplacementLength | Should -Be 0
|
|
$result.CompletionMatches[0].CompletionText | Should -BeExactly 'Ascending'
|
|
$result.CompletionMatches[1].CompletionText | Should -BeExactly 'Descending'
|
|
}
|
|
|
|
It "Issue#19912 - Tab completion should not crash" {
|
|
$ISS = [initialsessionstate]::CreateDefault()
|
|
$Runspace = [runspacefactory]::CreateRunspace($ISS)
|
|
$Runspace.Open()
|
|
$OldRunspace = [runspace]::DefaultRunspace
|
|
try
|
|
{
|
|
[runspace]::DefaultRunspace = $Runspace
|
|
{[System.Management.Automation.CommandCompletion]::CompleteInput('Get-', 3, $null)} | Should -Not -Throw
|
|
}
|
|
finally
|
|
{
|
|
[runspace]::DefaultRunspace = $OldRunspace
|
|
$Runspace.Dispose()
|
|
}
|
|
}
|
|
|
|
It "Issue#26277 - [CompletionCompleters]::CompleteFilename('') should work" {
|
|
$testDir = Join-Path $TestDrive "TempTestDir"
|
|
$file1 = Join-Path $testDir "abc.ps1"
|
|
$file2 = Join-Path $testDir "def.py"
|
|
|
|
New-Item -ItemType Directory -Path $testDir > $null
|
|
New-Item -ItemType File -Path $file1 > $null
|
|
New-Item -ItemType File -Path $file2 > $null
|
|
|
|
try {
|
|
Push-Location -Path $testDir
|
|
$result = [System.Management.Automation.CompletionCompleters]::CompleteFilename("")
|
|
$result | Should -Not -Be $null
|
|
$result | Measure-Object | ForEach-Object -MemberName Count | Should -Be 2
|
|
|
|
$item1, $item2 = @($result)
|
|
$item1.ListItemText | Should -BeExactly 'abc.ps1'
|
|
$item2.ListItemText | Should -BeExactly 'def.py'
|
|
} finally {
|
|
Pop-Location
|
|
}
|
|
}
|
|
|
|
Context 'Native CLI argument completion' {
|
|
BeforeAll {
|
|
$testDir = Join-Path $TestDrive "TempTestDir"
|
|
$file1 = Join-Path $testDir "abc.ps1"
|
|
$file2 = Join-Path $testDir "def.py"
|
|
|
|
New-Item -ItemType Directory -Path $testDir > $null
|
|
New-Item -ItemType File -Path $file1 > $null
|
|
New-Item -ItemType File -Path $file2 > $null
|
|
|
|
$dirSep = [System.IO.Path]::DirectorySeparatorChar
|
|
$relative_name_abc = ".${dirSep}abc.ps1"
|
|
$relative_name_def = ".${dirSep}def.py"
|
|
}
|
|
|
|
AfterAll {
|
|
## Unregister the completer for 'ping' to avoid affecting other tests.
|
|
register-ArgumentCompleter -Native -CommandName ping -ScriptBlock $null
|
|
}
|
|
|
|
It 'Completer script block returning nothing should fall back to file name completion' {
|
|
register-ArgumentCompleter -Native -CommandName ping -ScriptBlock {
|
|
param($WordToComplete, $CommandAst, $CursorPosition)
|
|
}
|
|
|
|
try {
|
|
Push-Location -Path $testDir
|
|
$cmd = "ping "
|
|
$result = TabExpansion2 -inputScript $cmd -cursorColumn $cmd.Length
|
|
$result.CompletionMatches | Should -Not -BeNullOrEmpty
|
|
$result.CompletionMatches.Count | Should -Be 2
|
|
$result.CompletionMatches[0].CompletionText | Should -BeExactly $relative_name_abc
|
|
$result.CompletionMatches[1].CompletionText | Should -BeExactly $relative_name_def
|
|
} finally {
|
|
Pop-Location
|
|
}
|
|
}
|
|
|
|
It 'Completer script block returning $null should suppress default completion fallback' {
|
|
register-ArgumentCompleter -Native -CommandName ping -ScriptBlock {
|
|
param($WordToComplete, $CommandAst, $CursorPosition)
|
|
return $null
|
|
}
|
|
|
|
try {
|
|
Push-Location -Path $testDir
|
|
$cmd = "ping "
|
|
## This call should not throw, and should suppress the default file name completion fallback, returning no results.
|
|
$result = TabExpansion2 -inputScript $cmd -cursorColumn $cmd.Length
|
|
$result.CompletionMatches.Count | Should -Be 0
|
|
} finally {
|
|
Pop-Location
|
|
}
|
|
}
|
|
|
|
It 'Completer script block returning empty string should suppress default completion fallback' {
|
|
register-ArgumentCompleter -Native -CommandName ping -ScriptBlock {
|
|
param($WordToComplete, $CommandAst, $CursorPosition)
|
|
return ''
|
|
}
|
|
|
|
try {
|
|
Push-Location -Path $testDir
|
|
$cmd = "ping "
|
|
## This call should not throw, and should suppress the default file name completion fallback, returning no results.
|
|
$result = TabExpansion2 -inputScript $cmd -cursorColumn $cmd.Length
|
|
$result.CompletionMatches.Count | Should -Be 0
|
|
} finally {
|
|
Pop-Location
|
|
}
|
|
}
|
|
|
|
It 'Completer script block returning empty-string-only array should fall back to default completion' {
|
|
register-ArgumentCompleter -Native -CommandName ping -ScriptBlock {
|
|
param($WordToComplete, $CommandAst, $CursorPosition)
|
|
return '', ''
|
|
}
|
|
|
|
try {
|
|
Push-Location -Path $testDir
|
|
$cmd = "ping "
|
|
## This call should not throw, and should fall back to the default completion.
|
|
$result = TabExpansion2 -inputScript $cmd -cursorColumn $cmd.Length
|
|
$result.CompletionMatches.Count | Should -Be 2
|
|
$result.CompletionMatches[0].CompletionText | Should -BeExactly $relative_name_abc
|
|
$result.CompletionMatches[1].CompletionText | Should -BeExactly $relative_name_def
|
|
} finally {
|
|
Pop-Location
|
|
}
|
|
}
|
|
|
|
It 'Completer script block returning null-value-only array should fall back to default completion' {
|
|
register-ArgumentCompleter -Native -CommandName ping -ScriptBlock {
|
|
param($WordToComplete, $CommandAst, $CursorPosition)
|
|
return $null, $null
|
|
}
|
|
|
|
try {
|
|
Push-Location -Path $testDir
|
|
$cmd = "ping "
|
|
## This call should not throw, and should fall back to the default completion.
|
|
$result = TabExpansion2 -inputScript $cmd -cursorColumn $cmd.Length
|
|
$result.CompletionMatches.Count | Should -Be 2
|
|
$result.CompletionMatches[0].CompletionText | Should -BeExactly $relative_name_abc
|
|
$result.CompletionMatches[1].CompletionText | Should -BeExactly $relative_name_def
|
|
} finally {
|
|
Pop-Location
|
|
}
|
|
}
|
|
|
|
It 'Completer script block returning a single string works as expected' {
|
|
register-ArgumentCompleter -Native -CommandName ping -ScriptBlock {
|
|
param($WordToComplete, $CommandAst, $CursorPosition)
|
|
return 'hello'
|
|
}
|
|
|
|
try {
|
|
Push-Location -Path $testDir
|
|
$cmd = "ping "
|
|
$result = TabExpansion2 -inputScript $cmd -cursorColumn $cmd.Length
|
|
$result.CompletionMatches.Count | Should -Be 1
|
|
$result.CompletionMatches[0].CompletionText | Should -BeExactly "hello"
|
|
} finally {
|
|
Pop-Location
|
|
}
|
|
}
|
|
|
|
It 'Completer script block returning an array that contains non-empty-or-null strings works as expected' {
|
|
register-ArgumentCompleter -Native -CommandName ping -ScriptBlock {
|
|
param($WordToComplete, $CommandAst, $CursorPosition)
|
|
return '', 'hello', $null, 'world'
|
|
}
|
|
|
|
try {
|
|
Push-Location -Path $testDir
|
|
$cmd = "ping "
|
|
$result = TabExpansion2 -inputScript $cmd -cursorColumn $cmd.Length
|
|
$result.CompletionMatches.Count | Should -Be 2
|
|
$result.CompletionMatches[0].CompletionText | Should -BeExactly "hello"
|
|
$result.CompletionMatches[1].CompletionText | Should -BeExactly "world"
|
|
} finally {
|
|
Pop-Location
|
|
}
|
|
}
|
|
}
|
|
}
|