mirror of
https://github.com/PowerShell/PowerShell
synced 2026-06-08 12:12:50 +00:00
Handle empty-string and null-value results returned from custom argument completer more properly (#27398)
This commit is contained in:
@@ -149,4 +149,150 @@ Describe "Tab completion bug fix" -Tags "CI" {
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user