2020-03-24 19:08:37 +01:00
# Copyright (c) Microsoft Corporation.
2018-02-13 18:23:53 +01:00
# Licensed under the MIT License.
2017-04-25 01:45:05 +02:00
Describe " TabCompletion " -Tags CI {
2017-08-15 18:49:48 +02:00
BeforeAll {
$separator = [ System.IO.Path ] :: DirectorySeparatorChar
}
2017-04-25 01:45:05 +02:00
It 'Should complete Command' {
2017-05-06 03:05:21 +02:00
$res = TabExpansion2 -inputScript 'Get-Com' -cursorColumn 'Get-Com' . Length
2018-07-30 07:32:52 +02:00
$res . CompletionMatches [ 0 ] . CompletionText | Should -BeExactly 'Get-Command'
2017-04-25 01:45:05 +02:00
}
2019-06-13 22:05:37 +02:00
It 'Should complete abbreviated cmdlet' {
$res = ( TabExpansion2 -inputScript 'i-psdf' -cursorColumn 'pschr' . Length ) . CompletionMatches . CompletionText
$res | Should -HaveCount 1
$res | Should -BeExactly 'Import-PowerShellDataFile'
}
2019-01-11 01:11:43 +01:00
2019-06-13 22:05:37 +02:00
It 'Should complete abbreviated function' {
2019-11-16 02:29:04 +01:00
function Test-AbbreviatedFunctionExpansion { }
$res = ( TabExpansion2 -inputScript 't-afe' -cursorColumn 't-afe' . Length ) . CompletionMatches . CompletionText
2019-06-13 22:05:37 +02:00
$res . Count | Should -BeGreaterOrEqual 1
2019-11-16 02:29:04 +01:00
$res | Should -BeExactly 'Test-AbbreviatedFunctionExpansion'
2019-01-11 01:11:43 +01:00
}
2017-04-25 01:45:05 +02:00
It 'Should complete native exe' -Skip: ( ! $IsWindows ) {
2017-05-06 03:05:21 +02:00
$res = TabExpansion2 -inputScript 'notep' -cursorColumn 'notep' . Length
2018-07-30 07:32:52 +02:00
$res . CompletionMatches [ 0 ] . CompletionText | Should -BeExactly 'notepad.exe'
2017-04-25 01:45:05 +02:00
}
2017-05-06 03:05:21 +02:00
2017-04-25 01:45:05 +02:00
It 'Should complete dotnet method' {
2017-05-06 03:05:21 +02:00
$res = TabExpansion2 -inputScript '(1).ToSt' -cursorColumn '(1).ToSt' . Length
2018-07-30 07:32:52 +02:00
$res . CompletionMatches [ 0 ] . CompletionText | Should -BeExactly 'ToString('
2017-05-06 03:05:21 +02:00
}
2020-08-27 19:11:01 +02:00
It 'Should complete dotnet method with null conditional operator' {
2019-11-16 01:39:53 +01:00
$res = TabExpansion2 -inputScript '(1)?.ToSt' -cursorColumn '(1)?.ToSt' . Length
$res . CompletionMatches [ 0 ] . CompletionText | Should -BeExactly 'ToString('
}
2020-08-27 19:11:01 +02:00
It 'Should complete dotnet method with null conditional operator without first letter' {
2019-11-16 01:39:53 +01:00
$res = TabExpansion2 -inputScript '(1)?.' -cursorColumn '(1)?.' . Length
$res . CompletionMatches [ 0 ] . CompletionText | Should -BeExactly 'CompareTo('
}
2017-04-25 01:45:05 +02:00
It 'Should complete Magic foreach' {
2017-05-06 03:05:21 +02:00
$res = TabExpansion2 -inputScript '(1..10).Fo' -cursorColumn '(1..10).Fo' . Length
2018-07-30 07:32:52 +02:00
$res . CompletionMatches [ 0 ] . CompletionText | Should -BeExactly 'ForEach('
2017-05-06 03:05:21 +02:00
}
2017-08-04 00:26:20 +02:00
It " Should complete Magic where " {
$res = TabExpansion2 -inputScript '(1..10).wh' -cursorColumn '(1..10).wh' . Length
2018-07-30 07:32:52 +02:00
$res . CompletionMatches [ 0 ] . CompletionText | Should -BeExactly 'Where('
2017-08-04 00:26:20 +02:00
}
2017-04-25 01:45:05 +02:00
It 'Should complete types' {
2017-05-06 03:05:21 +02:00
$res = TabExpansion2 -inputScript '[pscu' -cursorColumn '[pscu' . Length
2018-07-30 07:32:52 +02:00
$res . CompletionMatches [ 0 ] . CompletionText | Should -BeExactly 'pscustomobject'
2017-05-06 03:05:21 +02:00
}
2017-04-25 01:45:05 +02:00
It 'Should complete namespaces' {
2017-05-06 03:05:21 +02:00
$res = TabExpansion2 -inputScript 'using namespace Sys' -cursorColumn 'using namespace Sys' . Length
2018-07-30 07:32:52 +02:00
$res . CompletionMatches [ 0 ] . CompletionText | Should -BeExactly 'System'
2017-05-06 03:05:21 +02:00
}
2017-04-25 01:45:05 +02:00
It 'Should complete format-table hashtable' {
2017-05-06 03:05:21 +02:00
$res = TabExpansion2 -inputScript 'Get-ChildItem | Format-Table @{ ' -cursorColumn 'Get-ChildItem | Format-Table @{ ' . Length
2018-07-30 07:32:52 +02:00
$res . CompletionMatches | Should -HaveCount 5
2017-06-25 21:13:57 +02:00
$completionText = $res . CompletionMatches . CompletionText | Sort-Object
2018-07-30 07:32:52 +02:00
$completionText -join ' ' | Should -BeExactly 'Alignment Expression FormatString Label Width'
2017-05-06 03:05:21 +02:00
}
2017-04-25 01:45:05 +02:00
2017-07-07 18:25:46 +02:00
It 'Should complete format-* hashtable on GroupBy: <cmd>' -TestCases (
2017-04-25 01:45:05 +02:00
@ { cmd = 'Format-Table' } ,
@ { cmd = 'Format-List' } ,
@ { cmd = 'Format-Wide' } ,
@ { cmd = 'Format-Custom' }
) {
param ( $cmd )
2017-05-06 03:05:21 +02:00
$res = TabExpansion2 -inputScript " Get-ChildItem | $cmd -GroupBy @{ " -cursorColumn " Get-ChildItem | $cmd -GroupBy @{ " . Length
2018-07-30 07:32:52 +02:00
$res . CompletionMatches | Should -HaveCount 3
2017-06-25 21:13:57 +02:00
$completionText = $res . CompletionMatches . CompletionText | Sort-Object
2018-07-30 07:32:52 +02:00
$completionText -join ' ' | Should -BeExactly 'Expression FormatString Label'
2017-05-06 03:05:21 +02:00
}
2017-04-25 01:45:05 +02:00
It 'Should complete format-list hashtable' {
2017-05-06 03:05:21 +02:00
$res = TabExpansion2 -inputScript 'Get-ChildItem | Format-List @{ ' -cursorColumn 'Get-ChildItem | Format-List @{ ' . Length
2018-07-30 07:32:52 +02:00
$res . CompletionMatches | Should -HaveCount 3
2017-06-25 21:13:57 +02:00
$completionText = $res . CompletionMatches . CompletionText | Sort-Object
2018-07-30 07:32:52 +02:00
$completionText -join ' ' | Should -BeExactly 'Expression FormatString Label'
2017-05-06 03:05:21 +02:00
}
2017-04-25 01:45:05 +02:00
It 'Should complete format-wide hashtable' {
2017-05-06 03:05:21 +02:00
$res = TabExpansion2 -inputScript 'Get-ChildItem | Format-Wide @{ ' -cursorColumn 'Get-ChildItem | Format-Wide @{ ' . Length
2018-07-30 07:32:52 +02:00
$res . CompletionMatches | Should -HaveCount 2
2017-06-25 21:13:57 +02:00
$completionText = $res . CompletionMatches . CompletionText | Sort-Object
2018-07-30 07:32:52 +02:00
$completionText -join ' ' | Should -BeExactly 'Expression FormatString'
2017-05-06 03:05:21 +02:00
}
2017-04-25 01:45:05 +02:00
2017-09-05 04:45:51 +02:00
It 'Should complete format-custom hashtable' {
2017-05-06 03:05:21 +02:00
$res = TabExpansion2 -inputScript 'Get-ChildItem | Format-Custom @{ ' -cursorColumn 'Get-ChildItem | Format-Custom @{ ' . Length
2018-07-30 07:32:52 +02:00
$res . CompletionMatches | Should -HaveCount 2
2017-06-25 21:13:57 +02:00
$completionText = $res . CompletionMatches . CompletionText | Sort-Object
2018-07-30 07:32:52 +02:00
$completionText -join ' ' | Should -BeExactly 'Depth Expression'
2017-05-06 03:05:21 +02:00
}
2017-09-05 04:45:51 +02:00
It 'Should complete Select-Object hashtable' {
2017-05-06 03:05:21 +02:00
$res = TabExpansion2 -inputScript 'Get-ChildItem | Select-Object @{ ' -cursorColumn 'Get-ChildItem | Select-Object @{ ' . Length
2018-07-30 07:32:52 +02:00
$res . CompletionMatches | Should -HaveCount 2
2017-06-25 21:13:57 +02:00
$completionText = $res . CompletionMatches . CompletionText | Sort-Object
Update pester syntax to v4 (#11544)
* Capitalize 'Should' command and fix whitespace
```powershell
$_ -ireplace '\s?\|\s?should\b',' | Should'
```
* Capitalise and apply hyphen to 'Not' parameter
```powershell
$_ -ireplace '(\| Should) not\b','$1 -Not'
```
* Capitalise and apply hyphen to 'Be' parameter
```powershell
$_ -ireplace '(\| Should(?: -Not)?) -?be\b','$1 -Be'
```
* Capitalise and apply hyphen to 'BeExactly' parameter
$_ -ireplace '(\| Should(?: -Not)?) -?beexactly\b','$1 -BeExactly'
* Capitalise and apply hyphen to 'BeGreaterThan' parameter
```powershell
$_ -ireplace '(\| Should(?: -Not)?) -?begreaterthan\b','$1 -BeGreaterThan'
```
* Use 'BeTrue' parameter
```powershell
$_ -ireplace '(\| Should(?: -Not)?) -Be\s\$?true\b','$1 -BeTrue'
```
* Use 'BeFalse' parameter
```powershell
$_ -ireplace '(\| Should(?: -Not)?) -Be\s\$?false\b','$1 -BeFalse'
```
* Capitalise and apply hyphen to 'Match' parameter
```powershell
$_ -ireplace '(\| Should(?: -Not)?)\s-?match\b','$1 -Match'
```
* Capitalise and apply hyphen to 'Throw' parameter
```powershell
$_ -ireplace '(\| Should(?: -Not)?)\s-?throw\b','$1 -Throw'
```
* Capitalise and apply hyphen to 'BeNullOrEmpty' parameter
```powershell
$_ -ireplace '(\| Should(?: -Not)?)\s-?benullorempty\b','$1 -BeNullOrEmpty'
```
* Capitalise 'Because' parameter
```powershell
$_ -ireplace '\s-because\b',' -Because'
```
* Fix 'BeNullOrEmpty'
2020-01-11 16:41:59 +01:00
$completionText -join ' ' | Should -BeExactly 'Expression Name'
2017-05-06 03:05:21 +02:00
}
2017-04-25 01:45:05 +02:00
2017-09-05 04:45:51 +02:00
It 'Should complete Sort-Object hashtable' {
2017-05-06 03:05:21 +02:00
$res = TabExpansion2 -inputScript 'Get-ChildItem | Sort-Object @{ ' -cursorColumn 'Get-ChildItem | Sort-Object @{ ' . Length
2018-07-30 07:32:52 +02:00
$res . CompletionMatches | Should -HaveCount 3
2017-06-25 21:13:57 +02:00
$completionText = $res . CompletionMatches . CompletionText | Sort-Object
Update pester syntax to v4 (#11544)
* Capitalize 'Should' command and fix whitespace
```powershell
$_ -ireplace '\s?\|\s?should\b',' | Should'
```
* Capitalise and apply hyphen to 'Not' parameter
```powershell
$_ -ireplace '(\| Should) not\b','$1 -Not'
```
* Capitalise and apply hyphen to 'Be' parameter
```powershell
$_ -ireplace '(\| Should(?: -Not)?) -?be\b','$1 -Be'
```
* Capitalise and apply hyphen to 'BeExactly' parameter
$_ -ireplace '(\| Should(?: -Not)?) -?beexactly\b','$1 -BeExactly'
* Capitalise and apply hyphen to 'BeGreaterThan' parameter
```powershell
$_ -ireplace '(\| Should(?: -Not)?) -?begreaterthan\b','$1 -BeGreaterThan'
```
* Use 'BeTrue' parameter
```powershell
$_ -ireplace '(\| Should(?: -Not)?) -Be\s\$?true\b','$1 -BeTrue'
```
* Use 'BeFalse' parameter
```powershell
$_ -ireplace '(\| Should(?: -Not)?) -Be\s\$?false\b','$1 -BeFalse'
```
* Capitalise and apply hyphen to 'Match' parameter
```powershell
$_ -ireplace '(\| Should(?: -Not)?)\s-?match\b','$1 -Match'
```
* Capitalise and apply hyphen to 'Throw' parameter
```powershell
$_ -ireplace '(\| Should(?: -Not)?)\s-?throw\b','$1 -Throw'
```
* Capitalise and apply hyphen to 'BeNullOrEmpty' parameter
```powershell
$_ -ireplace '(\| Should(?: -Not)?)\s-?benullorempty\b','$1 -BeNullOrEmpty'
```
* Capitalise 'Because' parameter
```powershell
$_ -ireplace '\s-because\b',' -Because'
```
* Fix 'BeNullOrEmpty'
2020-01-11 16:41:59 +01:00
$completionText -join ' ' | Should -BeExactly 'Ascending Descending Expression'
2017-05-06 03:05:21 +02:00
}
2017-04-25 01:45:05 +02:00
2017-09-05 04:45:51 +02:00
It 'Should complete New-Object hashtable' {
2017-04-25 01:45:05 +02:00
class X {
$A
$B
$C
}
2017-05-06 03:05:21 +02:00
$res = TabExpansion2 -inputScript 'New-Object -TypeName X -Property @{ ' -cursorColumn 'New-Object -TypeName X -Property @{ ' . Length
2018-07-30 07:32:52 +02:00
$res . CompletionMatches | Should -HaveCount 3
$res . CompletionMatches . CompletionText -join ' ' | Should -BeExactly 'A B C'
2017-05-06 03:05:21 +02:00
}
It 'Should complete "Get-Process -Id " with Id and name in tooltip' {
2020-02-03 18:44:10 +01:00
Set-StrictMode -Version 3.0
2017-05-06 03:05:21 +02:00
$cmd = 'Get-Process -Id '
[ System.Management.Automation.CommandCompletion ] $res = TabExpansion2 -inputScript $cmd -cursorColumn $cmd . Length
2018-03-23 18:48:26 +01:00
$res . CompletionMatches [ 0 ] . CompletionText -match '^\d+$' | Should -BeTrue
$res . CompletionMatches [ 0 ] . ListItemText -match '^\d+ -' | Should -BeTrue
$res . CompletionMatches [ 0 ] . ToolTip -match '^\d+ -' | Should -BeTrue
2017-05-06 03:05:21 +02:00
}
2018-06-27 21:48:42 +02:00
It 'Should complete "Get-Process" with process names' {
$cmd = " Get-Process "
$res = TabExpansion2 -inputScript $cmd -cursorColumn $cmd . Length
# Can't compare to number of processes since macOS has a large number of processes
# that have empty Name which should be skipped
$res . CompletionMatches . Count | Should -BeGreaterThan 0
}
2017-04-25 01:45:05 +02:00
2020-05-07 14:00:30 +02:00
It 'Should complete keyword' -Skip {
2017-05-06 03:05:21 +02:00
$res = TabExpansion2 -inputScript 'using nam' -cursorColumn 'using nam' . Length
2018-07-30 07:32:52 +02:00
$res . CompletionMatches [ 0 ] . CompletionText | Should -BeExactly 'namespace'
2017-06-08 01:34:44 +02:00
}
2020-05-07 14:00:30 +02:00
It 'Should first suggest -Full and then -Functionality when using Get-Help -Fu<tab>' -Skip {
2018-07-31 08:13:18 +02:00
$res = TabExpansion2 -inputScript 'Get-Help -Fu' -cursorColumn 'Get-Help -Fu' . Length
$res . CompletionMatches [ 0 ] . CompletionText | Should -BeExactly '-Full'
$res . CompletionMatches [ 1 ] . CompletionText | Should -BeExactly '-Functionality'
}
2020-05-07 14:00:30 +02:00
It 'Should first suggest -Full and then -Functionality when using help -Fu<tab>' -Skip {
2018-07-31 08:13:18 +02:00
$res = TabExpansion2 -inputScript 'help -Fu' -cursorColumn 'help -Fu' . Length
$res . CompletionMatches [ 0 ] . CompletionText | Should -BeExactly '-Full'
$res . CompletionMatches [ 1 ] . CompletionText | Should -BeExactly '-Functionality'
}
2019-10-14 18:53:11 +02:00
It 'Should work for variable assignment of enum type: <inputStr>' -TestCases @ (
@ { inputStr = '$ErrorActionPreference = ' ; filter = '' ; doubleQuotes = $false }
@ { inputStr = '$ErrorActionPreference=' ; filter = '' ; doubleQuotes = $false }
@ { inputStr = '$ErrorActionPreference="' ; filter = '' ; doubleQuotes = $true }
@ { inputStr = '$ErrorActionPreference = ''s' ; filter = '| Where-Object { $_ -like "''s*" }' ; doubleQuotes = $false }
@ { inputStr = '$ErrorActionPreference = "siL' ; filter = '| Where-Object { $_ -like ''"sil*'' }' ; doubleQuotes = $true }
@ { inputStr = '[System.Management.Automation.ActionPreference]$e=' ; filter = '' ; doubleQuotes = $false }
@ { inputStr = '[System.Management.Automation.ActionPreference]$e = ' ; filter = '' ; doubleQuotes = $false }
@ { inputStr = '[System.Management.Automation.ActionPreference]$e = "' ; filter = '' ; doubleQuotes = $true }
@ { inputStr = '[System.Management.Automation.ActionPreference]$e = "s' ; filter = '| Where-Object { $_ -like """s*" }' ; doubleQuotes = $true }
@ { inputStr = '[System.Management.Automation.ActionPreference]$e = "x' ; filter = '| Where-Object { $_ -like """x*" }' ; doubleQuotes = $true }
) {
param ( $inputStr , $filter , $doubleQuotes )
$quote = ''''
if ( $doubleQuotes ) {
$quote = '"'
}
$sb = [ scriptblock ] :: Create ( @"
[ cmdletbinding ( ) ] param ( [ Parameter ( ValueFromPipeline = `$ true ) ] `$ obj ) process { `$ obj $filter }
" @)
$expectedValues = [ enum ] :: GetValues ( " System.Management.Automation.ActionPreference " ) | ForEach-Object { $quote + $_ . ToString ( ) + $quote } | & $sb | Sort-Object
if ( $expectedValues . Count -gt 0 ) {
$expected = [ string ] :: Join ( " , " , $expectedValues )
}
else {
$expected = ''
}
$res = TabExpansion2 -inputScript $inputStr -cursorColumn $inputStr . Length
if ( $res . CompletionMatches . Count -gt 0 ) {
$actual = [ string ] :: Join ( " , " , $res . CompletionMatches . completiontext )
}
else {
$actual = ''
}
$actual | Should -BeExactly $expected
}
It 'Should work for variable assignment of custom enum: <inputStr>' -TestCases @ (
@ { inputStr = '[Animal]$c="g' ; expected = '"Giraffe"' , '"Goose"' }
@ { inputStr = '[Animal]$c=' ; expected = " 'Duck' " , " 'Giraffe' " , " 'Goose' " , " 'Horse' " }
@ { inputStr = '$script:test = "g' ; expected = '"Giraffe"' , '"Goose"' }
@ { inputStr = '$script:test=' ; expected = " 'Duck' " , " 'Giraffe' " , " 'Goose' " , " 'Horse' " }
@ { inputStr = '$script:test = "x' ; expected = @ ( ) }
) {
param ( $inputStr , $expected )
enum Animal { Duck ; Goose ; Horse ; Giraffe }
[ Animal ] $script:test = 'Duck'
$res = TabExpansion2 -inputScript $inputStr -cursorColumn $inputStr . Length
if ( $res . CompletionMatches . Count -gt 0 ) {
$actual = [ string ] :: Join ( " , " , $res . CompletionMatches . completiontext )
}
else {
$actual = ''
}
$actual | Should -BeExactly ( [ string ] :: Join ( " , " , $expected ) )
}
It 'Should work for assignment of variable with validateset of strings: <inputStr>' -TestCases @ (
@ { inputStr = '$test=' ; expected = " 'a' " , " 'aa' " , " 'aab' " , " 'b' " ; doubleQuotes = $false }
@ { inputStr = '$test="a' ; expected = " 'a' " , " 'aa' " , " 'aab' " ; doubleQuotes = $true }
@ { inputStr = '$test = "aa' ; expected = " 'aa' " , " 'aab' " ; doubleQuotes = $true }
@ { inputStr = '$test=''aab' ; expected = " 'aab' " ; doubleQuotes = $false }
@ { inputStr = '$test="c' ; expected = '' ; doubleQuotes = $true }
) {
param ( $inputStr , $expected , $doubleQuotes )
[ ValidateSet ( 'a' , 'aa' , 'aab' , 'b' ) ] [ string ] $test = 'b'
$expected = [ string ] :: Join ( " , " , $expected )
if ( $doubleQuotes ) {
$expected = $expected . Replace ( " ' " , " "" " )
}
$res = TabExpansion2 -inputScript $inputStr -cursorColumn $inputStr . Length
if ( $res . CompletionMatches . Count -gt 0 ) {
$actual = [ string ] :: Join ( " , " , $res . CompletionMatches . completiontext )
}
else {
$actual = ''
}
$actual | Should -BeExactly $expected
}
It 'Should work for assignment of variable with validateset of int: <inputStr>' -TestCases @ (
@ { inputStr = '$test=' ; expected = 2 , 3 , 11 , 112 }
@ { inputStr = '$test = 1' ; expected = 11 , 112 }
@ { inputStr = '$test =11' ; expected = 11 , 112 }
@ { inputStr = '$test =4' ; expected = @ ( ) }
) {
param ( $inputStr , $expected )
[ ValidateSet ( 2 , 3 , 11 , 112 ) ] [ int ] $test = 2
$res = TabExpansion2 -inputScript $inputStr -cursorColumn $inputStr . Length
if ( $res . CompletionMatches . Count -gt 0 ) {
$actual = [ string ] :: Join ( " , " , $res . CompletionMatches . completiontext )
}
else {
$actual = ''
}
$actual | Should -BeExactly ( [ string ] :: Join ( " , " , $expected ) )
}
It 'Should work for assignment of variable with validateset of strings: <inputStr>' -TestCases @ (
@ { inputStr = '[validateset("a","aa","aab","b")][string]$test=' ; expected = " 'a' " , " 'aa' " , " 'aab' " , " 'b' " ; doubleQuotes = $false }
@ { inputStr = '[validateset("a","aa","aab","b")][string]$test="a' ; expected = " 'a' " , " 'aa' " , " 'aab' " ; doubleQuotes = $true }
@ { inputStr = '[validateset("a","aa","aab","b")][string]$test = "aa' ; expected = " 'aa' " , " 'aab' " ; doubleQuotes = $true }
@ { inputStr = '[validateset("a","aa","aab","b")][string]$test=''aab' ; expected = " 'aab' " ; doubleQuotes = $false }
@ { inputStr = '[validateset("a","aa","aab","b")][string]$test=''c' ; expected = '' ; doubleQuotes = $false }
) {
param ( $inputStr , $expected , $doubleQuotes )
$expected = [ string ] :: Join ( " , " , $expected )
if ( $doubleQuotes ) {
$expected = $expected . Replace ( " ' " , " "" " )
}
$res = TabExpansion2 -inputScript $inputStr -cursorColumn $inputStr . Length
if ( $res . CompletionMatches . Count -gt 0 ) {
$actual = [ string ] :: Join ( " , " , $res . CompletionMatches . completiontext )
}
else {
$actual = ''
}
$actual | Should -BeExactly $expected
}
2021-07-13 19:32:48 +02:00
Context " Format cmdlet's View paramter completion " {
BeforeAll {
$viewDefinition = @ '
< ? xml version = " 1.0 " encoding = " utf-8 " ? >
< Configuration >
< ViewDefinitions >
< View >
< Name > R A M < / Name >
< ViewSelectedBy >
< TypeName > System . Diagnostics . Process < / TypeName >
< / ViewSelectedBy >
< TableControl >
< TableHeaders >
< TableColumnHeader >
< Label > ProcName < / Label >
< Width > 40 < / Width >
< Alignment > Center < / Alignment >
< / TableColumnHeader >
< TableColumnHeader >
< Label > PagedMem < / Label >
< Width > 40 < / Width >
< Alignment > Center < / Alignment >
< / TableColumnHeader >
< TableColumnHeader >
< Label > PeakWS < / Label >
< Width > 40 < / Width >
< Alignment > Center < / Alignment >
< / TableColumnHeader >
< / TableHeaders >
< TableRowEntries >
< TableRowEntry >
< TableColumnItems >
< TableColumnItem >
< Alignment > Center < / Alignment >
< PropertyName > Name < / PropertyName >
< / TableColumnItem >
< TableColumnItem >
< Alignment > Center < / Alignment >
< PropertyName > PagedMemorySize < / PropertyName >
< / TableColumnItem >
< TableColumnItem >
< Alignment > Center < / Alignment >
< PropertyName > PeakWorkingSet < / PropertyName >
< / TableColumnItem >
< / TableColumnItems >
< / TableRowEntry >
< / TableRowEntries >
< / TableControl >
< / View >
< / ViewDefinitions >
< / Configuration >
' @
$tempViewFile = Join-Path -Path $TestDrive -ChildPath 'processViewDefinition.ps1xml'
Set-Content -LiteralPath $tempViewFile -Value $viewDefinition -Force
$ps = [ PowerShell ] :: Create ( )
$null = $ps . AddScript ( " Update-FormatData -AppendPath $tempViewFile " )
$ps . Invoke ( )
$ps . HadErrors | Should -BeFalse
$ps . Commands . Clear ( )
Remove-Item -LiteralPath $tempViewFile -Force -ErrorAction SilentlyContinue
}
It 'Should complete Get-ChildItem | <cmd> -View' -TestCases (
2021-08-09 23:01:57 +02:00
@ { cmd = 'Format-Table' ; expected = " children childrenWithHardlink $( if ( ! $IsWindows ) { ' childrenWithUnixStat' } ) " } ,
2021-07-13 19:32:48 +02:00
@ { cmd = 'Format-List' ; expected = 'children' } ,
@ { cmd = 'Format-Wide' ; expected = 'children' } ,
@ { cmd = 'Format-Custom' ; expected = '' }
) {
param ( $cmd , $expected )
# The completion is based on OutputTypeAttribute() of the cmdlet.
$res = TabExpansion2 -inputScript " Get-ChildItem | $cmd -View " -cursorColumn " Get-ChildItem | $cmd -View " . Length
$completionText = $res . CompletionMatches . CompletionText | Sort-Object
$completionText -join ' ' | Should -BeExactly $expected
}
It 'Should complete $processList = Get-Process; $processList | <cmd>' -TestCases (
@ { cmd = 'Format-Table -View ' ; expected = " 'R A M' " , " Priority " , " process " , " ProcessModule " , " ProcessWithUserName " , " StartTime " } ,
@ { cmd = 'Format-List -View ' ; expected = '' } ,
@ { cmd = 'Format-Wide -View ' ; expected = 'process' } ,
@ { cmd = 'Format-Custom -View ' ; expected = '' } ,
@ { cmd = 'Format-Table -View S' ; expected = " StartTime " } ,
@ { cmd = " Format-Table -View 'S " ; expected = " 'StartTime' " } ,
@ { cmd = " Format-Table -View R " ; expected = " 'R A M' " }
) {
param ( $cmd , $expected )
$null = $ps . AddScript ( {
param ( $cmd )
$processList = Get-Process
$res = TabExpansion2 -inputScript " `$ processList | $cmd " -cursorColumn " `$ processList | $cmd " . Length
$completionText = $res . CompletionMatches . CompletionText | Sort-Object
$completionText
} ) . AddArgument ( $cmd )
$result = $ps . Invoke ( )
$ps . Commands . Clear ( )
$expected = ( $expected | Sort-Object ) -join ' '
$result -join ' ' | Should -BeExactly $expected
}
}
2017-06-08 01:34:44 +02:00
Context NativeCommand {
BeforeAll {
$nativeCommand = ( Get-Command -CommandType Application -TotalCount 1 ) . Name
}
It 'Completes native commands with -' {
Register-ArgumentCompleter -Native -CommandName $nativeCommand -ScriptBlock {
param ( $wordToComplete , $ast , $cursorColumn )
if ( $wordToComplete -eq '-' ) {
return " -flag "
}
else {
return " unexpected wordtocomplete "
}
}
$line = " $nativeCommand - "
$res = TabExpansion2 -inputScript $line -cursorColumn $line . Length
2018-07-30 07:32:52 +02:00
$res . CompletionMatches | Should -HaveCount 1
$res . CompletionMatches . CompletionText | Should -BeExactly " -flag "
2017-06-08 01:34:44 +02:00
}
It 'Completes native commands with --' {
Register-ArgumentCompleter -Native -CommandName $nativeCommand -ScriptBlock {
param ( $wordToComplete , $ast , $cursorColumn )
if ( $wordToComplete -eq '--' ) {
return " --flag "
}
else {
return " unexpected wordtocomplete "
}
}
$line = " $nativeCommand -- "
$res = TabExpansion2 -inputScript $line -cursorColumn $line . Length
2018-07-30 07:32:52 +02:00
$res . CompletionMatches | Should -HaveCount 1
$res . CompletionMatches . CompletionText | Should -BeExactly " --flag "
2017-06-08 01:34:44 +02:00
}
It 'Completes native commands with --f' {
Register-ArgumentCompleter -Native -CommandName $nativeCommand -ScriptBlock {
param ( $wordToComplete , $ast , $cursorColumn )
if ( $wordToComplete -eq '--f' ) {
return " --flag "
}
else {
return " unexpected wordtocomplete "
}
}
$line = " $nativeCommand --f "
2020-05-07 14:00:30 +02:00
$res = TabExpansion2 -inputScript $line -cursorColumn $line . Length
2018-07-30 07:32:52 +02:00
$res . CompletionMatches | Should -HaveCount 1
$res . CompletionMatches . CompletionText | Should -BeExactly " --flag "
2017-06-08 01:34:44 +02:00
}
It 'Completes native commands with -o' {
Register-ArgumentCompleter -Native -CommandName $nativeCommand -ScriptBlock {
param ( $wordToComplete , $ast , $cursorColumn )
if ( $wordToComplete -eq '-o' ) {
return " -option "
}
else {
return " unexpected wordtocomplete "
}
}
$line = " $nativeCommand -o "
2020-05-07 14:00:30 +02:00
$res = TabExpansion2 -inputScript $line -cursorColumn $line . Length
2018-07-30 07:32:52 +02:00
$res . CompletionMatches | Should -HaveCount 1
$res . CompletionMatches . CompletionText | Should -BeExactly " -option "
2017-06-08 01:34:44 +02:00
}
2017-05-06 03:05:21 +02:00
}
2017-06-25 21:13:57 +02:00
2017-07-20 02:20:01 +02:00
It 'Should complete "Export-Counter -FileFormat" with available output formats' -Pending {
2017-06-25 21:13:57 +02:00
$res = TabExpansion2 -inputScript 'Export-Counter -FileFormat ' -cursorColumn 'Export-Counter -FileFormat ' . Length
2018-07-30 07:32:52 +02:00
$res . CompletionMatches | Should -HaveCount 3
2017-06-25 21:13:57 +02:00
$completionText = $res . CompletionMatches . CompletionText | Sort-Object
Update pester syntax to v4 (#11544)
* Capitalize 'Should' command and fix whitespace
```powershell
$_ -ireplace '\s?\|\s?should\b',' | Should'
```
* Capitalise and apply hyphen to 'Not' parameter
```powershell
$_ -ireplace '(\| Should) not\b','$1 -Not'
```
* Capitalise and apply hyphen to 'Be' parameter
```powershell
$_ -ireplace '(\| Should(?: -Not)?) -?be\b','$1 -Be'
```
* Capitalise and apply hyphen to 'BeExactly' parameter
$_ -ireplace '(\| Should(?: -Not)?) -?beexactly\b','$1 -BeExactly'
* Capitalise and apply hyphen to 'BeGreaterThan' parameter
```powershell
$_ -ireplace '(\| Should(?: -Not)?) -?begreaterthan\b','$1 -BeGreaterThan'
```
* Use 'BeTrue' parameter
```powershell
$_ -ireplace '(\| Should(?: -Not)?) -Be\s\$?true\b','$1 -BeTrue'
```
* Use 'BeFalse' parameter
```powershell
$_ -ireplace '(\| Should(?: -Not)?) -Be\s\$?false\b','$1 -BeFalse'
```
* Capitalise and apply hyphen to 'Match' parameter
```powershell
$_ -ireplace '(\| Should(?: -Not)?)\s-?match\b','$1 -Match'
```
* Capitalise and apply hyphen to 'Throw' parameter
```powershell
$_ -ireplace '(\| Should(?: -Not)?)\s-?throw\b','$1 -Throw'
```
* Capitalise and apply hyphen to 'BeNullOrEmpty' parameter
```powershell
$_ -ireplace '(\| Should(?: -Not)?)\s-?benullorempty\b','$1 -BeNullOrEmpty'
```
* Capitalise 'Because' parameter
```powershell
$_ -ireplace '\s-because\b',' -Because'
```
* Fix 'BeNullOrEmpty'
2020-01-11 16:41:59 +01:00
$completionText -join ' ' | Should -BeExactly 'blg csv tsv'
2017-06-25 21:13:57 +02:00
}
2017-08-04 00:26:20 +02:00
2019-03-21 21:49:57 +01:00
Context " Script name completion " {
BeforeAll {
2020-05-07 14:00:30 +02:00
Setup -f 'install-powershell.ps1' -Content " "
Setup -f 'remove-powershell.ps1' -Content " "
2019-03-21 21:49:57 +01:00
$scriptWithWildcardCases = @ (
@ {
command = '.\install-*.ps1'
expectedCommand = Join-Path -Path '.' -ChildPath 'install-powershell.ps1'
name = " ' $( Join-Path -Path '.' -ChildPath 'install-powershell.ps1' ) ' "
}
@ {
command = ( Join-Path $ { TestDrive } -ChildPath 'install-*.ps1' )
expectedCommand = ( Join-Path $ { TestDrive } -ChildPath 'install-powershell.ps1' )
name = " ' $( Join-Path -Path '.' -ChildPath 'install-powershell.ps1' ) ' by fully qualified path "
}
@ {
command = '.\?emove-powershell.ps1'
expectedCommand = Join-Path -Path '.' -ChildPath 'remove-powershell.ps1'
name = " ' $( Join-Path -Path '.' -ChildPath '?emove-powershell.ps1' ) ' "
}
@ {
# [] cause the parser to create a new token.
# So, the command must be quoted to tab complete.
command = " '.\[ra]emove-powershell.ps1' "
expectedCommand = " ' $( Join-Path -Path '.' -ChildPath 'remove-powershell.ps1' ) ' "
name = " ' $( Join-Path -Path '.' -ChildPath '[ra]emove-powershell.ps1' ) ' "
}
)
Push-Location $ { TestDrive } \
}
AfterAll {
Pop-Location
}
2020-05-07 14:00:30 +02:00
It " Input <name> should successfully complete " -TestCases $scriptWithWildcardCases {
2019-03-21 21:49:57 +01:00
param ( $command , $expectedCommand )
$res = TabExpansion2 -inputScript $command -cursorColumn $command . Length
$res . CompletionMatches . Count | Should -BeGreaterThan 0
$res . CompletionMatches [ 0 ] . CompletionText | Should -BeExactly $expectedCommand
}
}
2017-08-04 00:26:20 +02:00
Context " File name completion " {
BeforeAll {
$tempDir = Join-Path -Path $TestDrive -ChildPath " baseDir "
$oneSubDir = Join-Path -Path $tempDir -ChildPath " oneSubDir "
$oneSubDirPrime = Join-Path -Path $tempDir -ChildPath " prime "
$twoSubDir = Join-Path -Path $oneSubDir -ChildPath " twoSubDir "
2018-10-28 05:48:49 +01:00
$caseTestPath = Join-Path $testdrive " CaseTest "
2017-08-04 00:26:20 +02:00
New-Item -Path $tempDir -ItemType Directory -Force > $null
New-Item -Path $oneSubDir -ItemType Directory -Force > $null
New-Item -Path $oneSubDirPrime -ItemType Directory -Force > $null
New-Item -Path $twoSubDir -ItemType Directory -Force > $null
$testCases = @ (
@ { inputStr = " ab " ; name = " abc " ; localExpected = " . ${separator} abc " ; oneSubExpected = " .. ${separator} abc " ; twoSubExpected = " .. ${separator} .. ${separator} abc " }
@ { inputStr = " asaasas " ; name = " asaasas!popee " ; localExpected = " . ${separator} asaasas!popee " ; oneSubExpected = " .. ${separator} asaasas!popee " ; twoSubExpected = " .. ${separator} .. ${separator} asaasas!popee " }
@ { inputStr = " asaasa " ; name = " asaasas!popee " ; localExpected = " . ${separator} asaasas!popee " ; oneSubExpected = " .. ${separator} asaasas!popee " ; twoSubExpected = " .. ${separator} .. ${separator} asaasas!popee " }
@ { inputStr = " bbbbbbbbbb " ; name = 'bbbbbbbbbb`' ; localExpected = " & '. ${separator} bbbbbbbbbb `` ' " ; oneSubExpected = " & '.. ${separator} bbbbbbbbbb `` ' " ; twoSubExpected = " & '.. ${separator} .. ${separator} bbbbbbbbbb `` ' " }
@ { inputStr = " bbbbbbbbb " ; name = " bbbbbbbbb# " ; localExpected = " . ${separator} bbbbbbbbb# " ; oneSubExpected = " .. ${separator} bbbbbbbbb# " ; twoSubExpected = " .. ${separator} .. ${separator} bbbbbbbbb# " }
@ { inputStr = " bbbbbbbb " ; name = " bbbbbbbb{ " ; localExpected = " & '. ${separator} bbbbbbbb{' " ; oneSubExpected = " & '.. ${separator} bbbbbbbb{' " ; twoSubExpected = " & '.. ${separator} .. ${separator} bbbbbbbb{' " }
@ { inputStr = " bbbbbbb " ; name = " bbbbbbb} " ; localExpected = " & '. ${separator} bbbbbbb}' " ; oneSubExpected = " & '.. ${separator} bbbbbbb}' " ; twoSubExpected = " & '.. ${separator} .. ${separator} bbbbbbb}' " }
@ { inputStr = " bbbbbb " ; name = " bbbbbb( " ; localExpected = " & '. ${separator} bbbbbb(' " ; oneSubExpected = " & '.. ${separator} bbbbbb(' " ; twoSubExpected = " & '.. ${separator} .. ${separator} bbbbbb(' " }
@ { inputStr = " bbbbb " ; name = " bbbbb) " ; localExpected = " & '. ${separator} bbbbb)' " ; oneSubExpected = " & '.. ${separator} bbbbb)' " ; twoSubExpected = " & '.. ${separator} .. ${separator} bbbbb)' " }
@ { inputStr = " bbbb " ; name = " bbbb $ " ; localExpected = " & '. ${separator} bbbb $ ' " ; oneSubExpected = " & '.. ${separator} bbbb $ ' " ; twoSubExpected = " & '.. ${separator} .. ${separator} bbbb $ ' " }
@ { inputStr = " bbb " ; name = " bbb' " ; localExpected = " & '. ${separator} bbb''' " ; oneSubExpected = " & '.. ${separator} bbb''' " ; twoSubExpected = " & '.. ${separator} .. ${separator} bbb''' " }
@ { inputStr = " bb " ; name = " bb, " ; localExpected = " & '. ${separator} bb,' " ; oneSubExpected = " & '.. ${separator} bb,' " ; twoSubExpected = " & '.. ${separator} .. ${separator} bb,' " }
@ { inputStr = " b " ; name = " b; " ; localExpected = " & '. ${separator} b;' " ; oneSubExpected = " & '.. ${separator} b;' " ; twoSubExpected = " & '.. ${separator} .. ${separator} b;' " }
)
try {
Push-Location -Path $tempDir
foreach ( $entry in $testCases ) {
New-Item -Path $tempDir -Name $entry . name -ItemType File -ErrorAction SilentlyContinue > $null
}
} finally {
Pop-Location
}
}
2018-10-28 05:48:49 +01:00
BeforeEach {
New-Item -ItemType Directory -Path $caseTestPath > $null
}
2017-08-04 00:26:20 +02:00
AfterAll {
2017-08-15 18:49:48 +02:00
Remove-Item -Path $tempDir -Recurse -Force -ErrorAction SilentlyContinue
2017-08-04 00:26:20 +02:00
}
AfterEach {
Pop-Location
2018-10-28 05:48:49 +01:00
Remove-Item -Path $caseTestPath -Recurse -Force -ErrorAction SilentlyContinue
2017-08-04 00:26:20 +02:00
}
It " Input '<inputStr>' should successfully complete " -TestCases $testCases {
param ( $inputStr , $localExpected )
Push-Location -Path $tempDir
$res = TabExpansion2 -inputScript $inputStr -cursorColumn $inputStr . Length
2018-03-23 18:48:26 +01:00
$res . CompletionMatches . Count | Should -BeGreaterThan 0
2018-07-30 07:32:52 +02:00
$res . CompletionMatches [ 0 ] . CompletionText | Should -BeExactly $localExpected
2017-08-04 00:26:20 +02:00
}
It " Input '<inputStr>' should successfully complete with relative path '..\' " -TestCases $testCases {
param ( $inputStr , $oneSubExpected )
Push-Location -Path $oneSubDir
$inputStr = " ..\ ${inputStr} "
$res = TabExpansion2 -inputScript $inputStr -cursorColumn $inputStr . Length
2018-03-23 18:48:26 +01:00
$res . CompletionMatches . Count | Should -BeGreaterThan 0
2018-07-30 07:32:52 +02:00
$res . CompletionMatches [ 0 ] . CompletionText | Should -BeExactly $oneSubExpected
2017-08-04 00:26:20 +02:00
}
It " Input '<inputStr>' should successfully complete with relative path '..\..\' " -TestCases $testCases {
param ( $inputStr , $twoSubExpected )
Push-Location -Path $twoSubDir
$inputStr = " ../../ ${inputStr} "
$res = TabExpansion2 -inputScript $inputStr -cursorColumn $inputStr . Length
2018-03-23 18:48:26 +01:00
$res . CompletionMatches . Count | Should -BeGreaterThan 0
2018-07-30 07:32:52 +02:00
$res . CompletionMatches [ 0 ] . CompletionText | Should -BeExactly $twoSubExpected
2017-08-04 00:26:20 +02:00
}
It " Input '<inputStr>' should successfully complete with relative path '..\..\..\ba*\' " -TestCases $testCases {
param ( $inputStr , $twoSubExpected )
Push-Location -Path $twoSubDir
$inputStr = " ..\..\..\ba*\ ${inputStr} "
$res = TabExpansion2 -inputScript $inputStr -cursorColumn $inputStr . Length
2018-03-23 18:48:26 +01:00
$res . CompletionMatches . Count | Should -BeGreaterThan 0
2018-07-30 07:32:52 +02:00
$res . CompletionMatches [ 0 ] . CompletionText | Should -BeExactly $twoSubExpected
2017-08-04 00:26:20 +02:00
}
It " Test relative path " {
Push-Location -Path $oneSubDir
$beforeTab = " twoSubDir/../../pri "
$afterTab = " .. ${separator} prime "
$res = TabExpansion2 -inputScript $beforeTab -cursorColumn $beforeTab . Length
2018-07-30 07:32:52 +02:00
$res . CompletionMatches | Should -HaveCount 1
$res . CompletionMatches [ 0 ] . CompletionText | Should -BeExactly $afterTab
2017-08-04 00:26:20 +02:00
}
It " Test path with both '\' and '/' " {
Push-Location -Path $twoSubDir
$beforeTab = " ..\../..\ba*/ab "
$afterTab = " .. ${separator} .. ${separator} abc "
$res = TabExpansion2 -inputScript $beforeTab -cursorColumn $beforeTab . Length
2018-07-30 07:32:52 +02:00
$res . CompletionMatches | Should -HaveCount 1
$res . CompletionMatches [ 0 ] . CompletionText | Should -BeExactly $afterTab
2017-08-04 00:26:20 +02:00
}
2018-10-28 05:48:49 +01:00
It " Test case insensitive <type> path " -Skip: ( ! $IsLinux ) -TestCases @ (
@ { type = " File " ; beforeTab = " Get-Content f " } ,
@ { type = " Directory " ; beforeTab = " cd f " }
) {
param ( $type , $beforeTab )
$testItems = " foo " , " Foo " , " fOO "
$testItems | ForEach-Object {
$itemPath = Join-Path $caseTestPath $_
New-Item -ItemType $type -Path $itemPath
}
Push-Location $caseTestPath
$res = TabExpansion2 -inputScript $beforeTab -cursorColumn $beforeTab . Length
$res . CompletionMatches | Should -HaveCount $testItems . Count
# order isn't guaranteed so we'll sort them first
$completions = ( $res . CompletionMatches | Sort-Object CompletionText -CaseSensitive ) . CompletionText -join " : "
$expected = ( $testItems | Sort-Object -CaseSensitive | ForEach-Object { " ./ $_ " } ) -join " : "
$completions | Should -BeExactly $expected
}
It " Test case insensitive file and folder path completing for <type> " -Skip: ( ! $IsLinux ) -TestCases @ (
@ { type = " File " ; beforeTab = " Get-Content f " ; expected = " foo " , " Foo " } , # Get-Content passes thru to provider
@ { type = " Directory " ; beforeTab = " cd f " ; expected = " Foo " } # Set-Location is aware of Files vs Folders
) {
param ( $beforeTab , $expected )
$filePath = Join-Path $caseTestPath " foo "
$folderPath = Join-Path $caseTestPath " Foo "
New-Item -ItemType File -Path $filePath
New-Item -ItemType Directory -Path $folderPath
Push-Location $caseTestPath
$res = TabExpansion2 -inputScript $beforeTab -cursorColumn $beforeTab . Length
$res . CompletionMatches | Should -HaveCount $expected . Count
# order isn't guaranteed so we'll sort them first
$completions = ( $res . CompletionMatches | Sort-Object CompletionText -CaseSensitive ) . CompletionText -join " : "
$expected = ( $expected | Sort-Object -CaseSensitive | ForEach-Object { " ./ $_ " } ) -join " : "
}
2017-08-04 00:26:20 +02:00
}
Context " Cmdlet name completion " {
BeforeAll {
$testCases = @ (
2018-07-30 07:32:52 +02:00
@ { inputStr = " get-c*item " ; expected = " Get-ChildItem " }
@ { inputStr = " set-alia? " ; expected = " Set-Alias " }
@ { inputStr = " s*-alias " ; expected = " Set-Alias " }
@ { inputStr = " se*-alias " ; expected = " Set-Alias " }
@ { inputStr = " set-al " ; expected = " Set-Alias " }
@ { inputStr = " set-a?i " ; expected = " Set-Alias " }
@ { inputStr = " set-?lias " ; expected = " Set-Alias " }
2018-11-01 20:03:03 +01:00
@ { inputStr = " get-c*ditem " ; expected = " Get-ChildItem " }
2018-07-30 07:32:52 +02:00
@ { inputStr = " Microsoft.PowerShell.Management\get-c*item " ; expected = " Microsoft.PowerShell.Management\Get-ChildItem " }
@ { inputStr = " Microsoft.PowerShell.Utility\set-alia? " ; expected = " Microsoft.PowerShell.Utility\Set-Alias " }
@ { inputStr = " Microsoft.PowerShell.Utility\s*-alias " ; expected = " Microsoft.PowerShell.Utility\Set-Alias " }
@ { inputStr = " Microsoft.PowerShell.Utility\se*-alias " ; expected = " Microsoft.PowerShell.Utility\Set-Alias " }
@ { inputStr = " Microsoft.PowerShell.Utility\set-al " ; expected = " Microsoft.PowerShell.Utility\Set-Alias " }
@ { inputStr = " Microsoft.PowerShell.Utility\set-a?i " ; expected = " Microsoft.PowerShell.Utility\Set-Alias " }
@ { inputStr = " Microsoft.PowerShell.Utility\set-?lias " ; expected = " Microsoft.PowerShell.Utility\Set-Alias " }
@ { inputStr = " Microsoft.PowerShell.Management\get-*ditem " ; expected = " Microsoft.PowerShell.Management\Get-ChildItem " }
2017-08-04 00:26:20 +02:00
)
}
It " Input '<inputStr>' should successfully complete " -TestCases $testCases {
param ( $inputStr , $expected )
$res = TabExpansion2 -inputScript $inputStr -cursorColumn $inputStr . Length
2018-07-30 07:32:52 +02:00
$res . CompletionMatches [ 0 ] . CompletionText | Should -BeExactly $expected
2017-08-04 00:26:20 +02:00
}
}
Context " Miscellaneous completion tests " {
BeforeAll {
$testCases = @ (
@ { inputStr = " get-childitem - " ; expected = " -Path " ; setup = $null }
@ { inputStr = " get-childitem -Fil " ; expected = " -Filter " ; setup = $null }
@ { inputStr = '$arg' ; expected = '$args' ; setup = $null }
@ { inputStr = '$args.' ; expected = 'Count' ; setup = $null }
2020-01-13 20:34:10 +01:00
@ { inputStr = '$Host.UI.Ra' ; expected = 'RawUI' ; setup = $null }
@ { inputStr = '$Host.UI.WriteD' ; expected = 'WriteDebugLine(' ; setup = $null }
2017-08-04 00:26:20 +02:00
@ { inputStr = '$MaximumHistoryCount.' ; expected = 'CompareTo(' ; setup = $null }
@ { inputStr = '$A=[datetime]::now;$A.' ; expected = 'Date' ; setup = $null }
2019-06-13 22:05:37 +02:00
@ { inputStr = '$e=$null;try { 1/0 } catch {$e=$_};$e.' ; expected = 'CategoryInfo' ; setup = $null }
2017-10-18 02:25:11 +02:00
@ { inputStr = '$x= gps pwsh;$x.*pm' ; expected = 'NPM' ; setup = $null }
2019-04-18 20:42:49 +02:00
@ { inputStr = 'function Get-ScrumData {}; Get-Scrum' ; expected = 'Get-ScrumData' ; setup = $null }
2017-08-04 00:26:20 +02:00
@ { inputStr = 'function write-output {param($abcd) $abcd};Write-Output -a' ; expected = '-abcd' ; setup = $null }
@ { inputStr = 'function write-output {param($abcd) $abcd};Microsoft.PowerShell.Utility\Write-Output -' ; expected = '-InputObject' ; setup = $null }
2019-05-21 07:43:51 +02:00
@ { inputStr = '[math]::Co' ; expected = 'CopySign(' ; setup = $null }
2017-08-04 00:26:20 +02:00
@ { inputStr = '[math]::PI.GetT' ; expected = 'GetType(' ; setup = $null }
@ { inputStr = '[math]' ; expected = '::E' ; setup = $null }
@ { inputStr = '[math].' ; expected = 'Assembly' ; setup = $null }
@ { inputStr = '[math].G' ; expected = 'GenericParameterAttributes' ; setup = $null }
@ { inputStr = '[Environment+specialfolder]::App' ; expected = 'ApplicationData' ; setup = $null }
@ { inputStr = 'icm {get-pro' ; expected = 'Get-Process' ; setup = $null }
@ { inputStr = 'write-ouput (get-pro' ; expected = 'Get-Process' ; setup = $null }
@ { inputStr = 'iex "get-pro' ; expected = '"Get-Process"' ; setup = $null }
@ { inputStr = '$variab' ; expected = '$variableA' ; setup = { $variableB = 2 ; $variableA = 1 } }
@ { inputStr = 'a -' ; expected = '-keys' ; setup = { function a { param ( $keys ) $a } } }
@ { inputStr = 'Get-Content -Li' ; expected = '-LiteralPath' ; setup = $null }
@ { inputStr = 'New-Item -W' ; expected = '-WhatIf' ; setup = $null }
@ { inputStr = 'Get-Alias gs' ; expected = 'gsn' ; setup = $null }
@ { inputStr = 'Get-Alias -Definition cd' ; expected = 'cd..' ; setup = $null }
@ { inputStr = 'remove-psdrive fun' ; expected = 'Function' ; setup = $null }
@ { inputStr = 'new-psdrive -PSProvider fi' ; expected = 'FileSystem' ; setup = $null }
@ { inputStr = 'Get-PSDrive -PSProvider En' ; expected = 'Environment' ; setup = $null }
@ { inputStr = 'remove-psdrive fun' ; expected = 'Function' ; setup = $null }
@ { inputStr = 'get-psprovider ali' ; expected = 'Alias' ; setup = $null }
@ { inputStr = 'Get-PSDrive -PSProvider Variable ' ; expected = 'Variable' ; setup = $null }
@ { inputStr = 'Get-Command Get-Chil' ; expected = 'Get-ChildItem' ; setup = $null }
@ { inputStr = 'Get-Variable psver' ; expected = 'PSVersionTable' ; setup = $null }
2018-11-01 20:03:03 +01:00
@ { inputStr = 'Get-Help get-c*ditem' ; expected = 'Get-ChildItem' ; setup = $null }
2017-08-04 00:26:20 +02:00
@ { inputStr = 'Trace-Command e' ; expected = 'ETS' ; setup = $null }
@ { inputStr = 'Get-TraceSource e' ; expected = 'ETS' ; setup = $null }
@ { inputStr = '[int]:: max' ; expected = 'MaxValue' ; setup = $null }
@ { inputStr = '"string". l*' ; expected = 'Length' ; setup = $null }
@ { inputStr = '("a" * 5).e' ; expected = 'EndsWith(' ; setup = $null }
@ { inputStr = '([string][int]1).e' ; expected = 'EndsWith(' ; setup = $null }
@ { inputStr = '(++$i).c' ; expected = 'CompareTo(' ; setup = $null }
@ { inputStr = '"a".Length.c' ; expected = 'CompareTo(' ; setup = $null }
@ { inputStr = '@(1, "a").c' ; expected = 'Count' ; setup = $null }
@ { inputStr = '{1}.is' ; expected = 'IsConfiguration' ; setup = $null }
@ { inputStr = '@{ }.' ; expected = 'Count' ; setup = $null }
@ { inputStr = '@{abc=1}.a' ; expected = 'Add(' ; setup = $null }
@ { inputStr = '$a.f' ; expected = " 'fo-o' " ; setup = { $a = @ { 'fo-o' = 'bar' } } }
@ { inputStr = 'dir | % { $_.Full' ; expected = 'FullName' ; setup = $null }
@ { inputStr = '@{a=$(exit)}.Ke' ; expected = 'Keys' ; setup = $null }
@ { inputStr = '@{$(exit)=1}.Va' ; expected = 'Values' ; setup = $null }
@ { inputStr = 'switch -' ; expected = '-CaseSensitive' ; setup = $null }
@ { inputStr = 'gm -t' ; expected = '-Type' ; setup = $null }
@ { inputStr = 'foo -aa -aa' ; expected = '-aaa' ; setup = { function foo { param ( $a , $aa , $aaa ) } } }
@ { inputStr = 'switch ( gps -' ; expected = '-Name' ; setup = $null }
@ { inputStr = 'set-executionpolicy ' ; expected = 'AllSigned' ; setup = $null }
@ { inputStr = 'Set-ExecutionPolicy -exe: b' ; expected = 'Bypass' ; setup = $null }
@ { inputStr = 'Set-ExecutionPolicy -exe:b' ; expected = 'Bypass' ; setup = $null }
@ { inputStr = 'Set-ExecutionPolicy -ExecutionPolicy:' ; expected = 'AllSigned' ; setup = $null }
@ { inputStr = 'Set-ExecutionPolicy by -for:' ; expected = '$true' ; setup = $null }
2018-07-30 07:32:52 +02:00
@ { inputStr = 'Import-Csv -Encoding ' ; expected = 'ascii' ; setup = $null }
2017-08-04 00:26:20 +02:00
@ { inputStr = 'Get-Process | % ModuleM' ; expected = 'ModuleMemorySize' ; setup = $null }
@ { inputStr = 'Get-Process | % {$_.MainModule} | % Com' ; expected = 'Company' ; setup = $null }
@ { inputStr = 'Get-Process | % MainModule | % Com' ; expected = 'Company' ; setup = $null }
@ { inputStr = '$p = Get-Process; $p | % ModuleM' ; expected = 'ModuleMemorySize' ; setup = $null }
@ { inputStr = 'gmo Microsoft.PowerShell.U' ; expected = 'Microsoft.PowerShell.Utility' ; setup = $null }
@ { inputStr = 'rmo Microsoft.PowerShell.U' ; expected = 'Microsoft.PowerShell.Utility' ; setup = $null }
@ { inputStr = 'gcm -Module Microsoft.PowerShell.U' ; expected = 'Microsoft.PowerShell.Utility' ; setup = $null }
@ { inputStr = 'gmo -list PackageM' ; expected = 'PackageManagement' ; setup = $null }
@ { inputStr = 'gcm -Module PackageManagement Find-Pac' ; expected = 'Find-Package' ; setup = $null }
@ { inputStr = 'ipmo PackageM' ; expected = 'PackageManagement' ; setup = $null }
2017-10-18 02:25:11 +02:00
@ { inputStr = 'Get-Process pws' ; expected = 'pwsh' ; setup = $null }
2017-08-04 00:26:20 +02:00
@ { inputStr = " function bar { [OutputType('System.IO.FileInfo')][OutputType('System.Diagnostics.Process')]param() }; bar | ? { `$ _.ProcessN " ; expected = 'ProcessName' ; setup = $null }
@ { inputStr = " function bar { [OutputType('System.IO.FileInfo')][OutputType('System.Diagnostics.Process')]param() }; bar | ? { `$ _.LastAc " ; expected = 'LastAccessTime' ; setup = $null }
@ { inputStr = " & 'get-comm " ; expected = " 'Get-Command' " ; setup = $null }
@ { inputStr = 'alias:dir' ; expected = Join-Path 'Alias:' 'dir' ; setup = $null }
2018-07-30 07:32:52 +02:00
@ { inputStr = 'gc alias::ipm' ; expected = 'alias::ipmo' ; setup = $null }
2017-08-04 00:26:20 +02:00
@ { inputStr = 'gc enVironment::psmod' ; expected = 'enVironment::PSModulePath' ; setup = $null }
## tab completion safe expression evaluator tests
@ { inputStr = '@{a=$(exit)}.Ke' ; expected = 'Keys' ; setup = $null }
@ { inputStr = '@{$(exit)=1}.Ke' ; expected = 'Keys' ; setup = $null }
## tab completion variable names
@ { inputStr = '@PSVer' ; expected = '@PSVersionTable' ; setup = $null }
@ { inputStr = '$global:max' ; expected = '$global:MaximumHistoryCount' ; setup = $null }
@ { inputStr = '$PSMod' ; expected = '$PSModuleAutoLoadingPreference' ; setup = $null }
## tab completion for variable in path
2017-10-13 22:54:43 +02:00
## if $PSHOME contains a space tabcompletion adds ' around the path
2020-01-13 20:35:33 +01:00
@ { inputStr = 'cd $PSHOME\Modu' ; expected = if ( $PSHOME . Contains ( ' ' ) ) { " ' $( Join-Path $PSHOME 'Modules' ) ' " } else { Join-Path $PSHOME 'Modules' } ; setup = $null }
@ { inputStr = 'cd "$PSHOME\Modu"' ; expected = " `" $( Join-Path $PSHOME 'Modules' ) `" " ; setup = $null }
2020-05-07 14:00:30 +02:00
@ { inputStr = '$PSHOME\System.Management.Au' ; expected = if ( $PSHOME . Contains ( ' ' ) ) { " ` & ' $( Join-Path $PSHOME 'System.Management.Automation.dll' ) ' " } else { Join-Path $PSHOME 'System.Management.Automation.dll' ; Setup = $null } }
2017-08-15 18:49:48 +02:00
@ { inputStr = '"$PSHOME\System.Management.Au"' ; expected = " `" $( Join-Path $PSHOME 'System.Management.Automation.dll' ) `" " ; setup = $null }
2018-03-16 17:10:06 +01:00
@ { inputStr = '& "$PSHOME\System.Management.Au"' ; expected = " `" $( Join-Path $PSHOME 'System.Management.Automation.dll' ) `" " ; setup = $null }
2017-08-04 00:26:20 +02:00
## tab completion AST-based tests
@ { inputStr = 'get-date | ForEach-Object { $PSItem.h' ; expected = 'Hour' ; setup = $null }
@ { inputStr = '$a=gps;$a[0].h' ; expected = 'Handle' ; setup = $null }
@ { inputStr = " `$ (1,'a',@{})[-1].k " ; expected = 'Keys' ; setup = $null }
@ { inputStr = " `$ (1,'a',@{})[1].tri " ; expected = 'Trim(' ; setup = $null }
## tab completion for type names
@ { inputStr = '[ScriptBlockAst' ; expected = 'System.Management.Automation.Language.ScriptBlockAst' ; setup = $null }
@ { inputStr = 'New-Object dict' ; expected = 'System.Collections.Generic.Dictionary' ; setup = $null }
@ { inputStr = 'New-Object System.Collections.Generic.List[datet' ; expected = " 'System.Collections.Generic.List[datetime]' " ; setup = $null }
@ { inputStr = '[System.Management.Automation.Runspaces.runspacef' ; expected = 'System.Management.Automation.Runspaces.RunspaceFactory' ; setup = $null }
@ { inputStr = '[specialfol' ; expected = 'System.Environment+SpecialFolder' ; setup = $null }
2017-08-15 18:49:48 +02:00
## tab completion for variable names in '{}'
@ { inputStr = '${PSDefault' ; expected = '$PSDefaultParameterValues' ; setup = $null }
2017-08-04 00:26:20 +02:00
)
}
It " Input '<inputStr>' should successfully complete " -TestCases $testCases {
param ( $inputStr , $expected , $setup )
if ( $null -ne $setup ) { . $setup }
$res = TabExpansion2 -inputScript $inputStr -cursorColumn $inputStr . Length
2018-03-23 18:48:26 +01:00
$res . CompletionMatches . Count | Should -BeGreaterThan 0
2019-03-11 22:51:22 +01:00
$res . CompletionMatches . CompletionText | Should -Contain $expected
2017-08-04 00:26:20 +02:00
}
It " Tab completion UNC path " -Skip: ( ! $IsWindows ) {
$homeDrive = $env:HOMEDRIVE . Replace ( " : " , " $ " )
$beforeTab = " \\localhost\ $homeDrive \wind "
$afterTab = " & '\\localhost\ $homeDrive \Windows' "
$res = TabExpansion2 -inputScript $beforeTab -cursorColumn $beforeTab . Length
2018-03-23 18:48:26 +01:00
$res . CompletionMatches . Count | Should -BeGreaterThan 0
2018-07-30 07:32:52 +02:00
$res . CompletionMatches [ 0 ] . CompletionText | Should -BeExactly $afterTab
2017-08-04 00:26:20 +02:00
}
It " Tab completion for registry " -Skip: ( ! $IsWindows ) {
$beforeTab = 'registry::HKEY_l'
$afterTab = 'registry::HKEY_LOCAL_MACHINE'
$res = TabExpansion2 -inputScript $beforeTab -cursorColumn $beforeTab . Length
2018-07-30 07:32:52 +02:00
$res . CompletionMatches | Should -HaveCount 1
$res . CompletionMatches [ 0 ] . CompletionText | Should -BeExactly $afterTab
2017-08-04 00:26:20 +02:00
}
It " Tab completion for wsman provider " -Skip: ( ! $IsWindows ) {
$beforeTab = 'wsman::localh'
$afterTab = 'wsman::localhost'
$res = TabExpansion2 -inputScript $beforeTab -cursorColumn $beforeTab . Length
2018-07-30 07:32:52 +02:00
$res . CompletionMatches | Should -HaveCount 1
$res . CompletionMatches [ 0 ] . CompletionText | Should -BeExactly $afterTab
2017-08-04 00:26:20 +02:00
}
It " Tab completion for filesystem provider qualified path " {
2018-05-03 01:58:39 +02:00
$tempFolder = [ System.IO.Path ] :: GetTempPath ( )
try
{
New-Item -ItemType Directory -Path " $tempFolder /helloworld " > $null
$tempFolder | Should -Exist
$beforeTab = 'filesystem::{0}hello' -f $tempFolder
$afterTab = 'filesystem::{0}helloworld' -f $tempFolder
$res = TabExpansion2 -inputScript $beforeTab -cursorColumn $beforeTab . Length
$res . CompletionMatches . Count | Should -BeGreaterThan 0
2018-07-30 07:32:52 +02:00
$res . CompletionMatches [ 0 ] . CompletionText | Should -BeExactly $afterTab
2018-05-03 01:58:39 +02:00
}
finally
{
Remove-Item -Path " $tempFolder /helloworld " -Force -ErrorAction SilentlyContinue
2017-08-04 00:26:20 +02:00
}
}
It " Tab completion dynamic parameter of a custom function " {
function Test-DynamicParam {
[ CmdletBinding ( ) ]
PARAM ( $DeFirst )
DYNAMICPARAM {
$paramDictionary = [ System.Management.Automation.RuntimeDefinedParameterDictionary ] :: new ( )
$attributeCollection = [ System.Collections.ObjectModel.Collection[Attribute] ] :: new ( )
$attributeCollection . Add ( [ Parameter ] :: new ( ) )
$deSecond = [ System.Management.Automation.RuntimeDefinedParameter ] :: new ( 'DeSecond' , [ System.Array ] , $attributeCollection )
$deThird = [ System.Management.Automation.RuntimeDefinedParameter ] :: new ( 'DeThird' , [ System.Array ] , $attributeCollection )
$null = $paramDictionary . Add ( 'DeSecond' , $deSecond )
$null = $paramDictionary . Add ( 'DeThird' , $deThird )
return $paramDictionary
}
PROCESS {
Write-Host 'Hello'
Write-Host $PSBoundParameters
}
}
$inputStr = " Test-DynamicParam -D "
$res = TabExpansion2 -inputScript $inputStr -cursorColumn $inputStr . Length
2018-03-23 18:48:26 +01:00
$res . CompletionMatches . Count | Should -BeGreaterThan 3
2018-07-30 07:32:52 +02:00
$res . CompletionMatches [ 0 ] . CompletionText | Should -BeExactly '-DeFirst'
$res . CompletionMatches [ 1 ] . CompletionText | Should -BeExactly '-DeSecond'
$res . CompletionMatches [ 2 ] . CompletionText | Should -BeExactly '-DeThird'
2017-08-04 00:26:20 +02:00
}
It " Tab completion dynamic parameter '-CodeSigningCert' " -Skip: ( ! $IsWindows ) {
try {
Push-Location cert : \
$inputStr = " gci -co "
$res = TabExpansion2 -inputScript $inputStr -cursorColumn $inputStr . Length
2018-07-30 07:32:52 +02:00
$res . CompletionMatches [ 0 ] . CompletionText | Should -BeExactly '-CodeSigningCert'
2017-08-04 00:26:20 +02:00
} finally {
Pop-Location
}
}
It " Tab completion for file system takes precedence over functions " {
try {
Push-Location $TestDrive
New-Item -Name myf -ItemType File -Force
function MyFunction { " Hi there " }
$inputStr = " myf "
$res = TabExpansion2 -inputScript $inputStr -cursorColumn $inputStr . Length
2018-07-30 07:32:52 +02:00
$res . CompletionMatches | Should -HaveCount 2
$res . CompletionMatches [ 0 ] . CompletionText | Should -BeExactly ( Resolve-Path myf -Relative )
$res . CompletionMatches [ 1 ] . CompletionText | Should -BeExactly " MyFunction "
2017-08-04 00:26:20 +02:00
} finally {
Remove-Item -Path myf -Force
Pop-Location
}
}
It " Tab completion for validateSet attribute " {
function foo { param ( [ ValidateSet ( 'cat' , 'dog' ) ] $p ) }
$inputStr = " foo "
$res = TabExpansion2 -inputScript $inputStr -cursorColumn $inputStr . Length
2018-07-30 07:32:52 +02:00
$res . CompletionMatches | Should -HaveCount 2
$res . CompletionMatches [ 0 ] . CompletionText | Should -BeExactly 'cat'
$res . CompletionMatches [ 1 ] . CompletionText | Should -BeExactly 'dog'
2017-08-04 00:26:20 +02:00
}
2019-12-02 19:51:13 +01:00
It " Tab completion for ArgumentCompleter when AST is passed to CompleteInput " {
$scriptBl = {
function Test-Completion {
param (
[ String ] $TestVal
)
}
[ scriptblock ] $completer = {
param ( $commandName , $parameterName , $wordToComplete , $commandAst , $fakeBoundParameters )
@ ( 'Val1' , 'Val2' )
}
Register-ArgumentCompleter -CommandName Test-Completion -ParameterName TestVal -ScriptBlock $completer
}
$pwsh = [ PowerShell ] :: Create ( )
$pwsh . AddScript ( $scriptBl )
$pwsh . Invoke ( )
$completeInput_Input = $scriptBl . ToString ( )
$completeInput_Input + = " `n Test-Completion -TestVal "
$res = [ System.Management.Automation.CommandCompletion ] :: CompleteInput ( $completeInput_Input , $completeInput_Input . Length , $null , $pwsh )
$res . CompletionMatches | Should -HaveCount 2
$res . CompletionMatches [ 0 ] . CompletionText | Should -BeExactly 'Val1'
$res . CompletionMatches [ 1 ] . CompletionText | Should -BeExactly 'Val2'
}
2017-08-04 00:26:20 +02:00
It " Tab completion for enum type parameter of a custom function " {
function baz ( [ consolecolor ] $name , [ ValidateSet ( 'cat' , 'dog' ) ] $p ) { }
$inputStr = " baz -name "
$res = TabExpansion2 -inputScript $inputStr -cursorColumn $inputStr . Length
2018-07-30 07:32:52 +02:00
$res . CompletionMatches | Should -HaveCount 16
$res . CompletionMatches [ 0 ] . CompletionText | Should -BeExactly 'Black'
2017-08-04 00:26:20 +02:00
$inputStr = " baz Black "
$res = TabExpansion2 -inputScript $inputStr -cursorColumn $inputStr . Length
2018-07-30 07:32:52 +02:00
$res . CompletionMatches | Should -HaveCount 2
$res . CompletionMatches [ 0 ] . CompletionText | Should -BeExactly 'cat'
$res . CompletionMatches [ 1 ] . CompletionText | Should -BeExactly 'dog'
2017-08-04 00:26:20 +02:00
}
It " Tab completion for enum members after comma " {
$inputStr = " Get-Command -Type Alias,c "
$res = TabExpansion2 -inputScript $inputStr -cursorColumn $inputStr . Length
2018-07-30 07:32:52 +02:00
$res . CompletionMatches | Should -HaveCount 2
$res . CompletionMatches [ 0 ] . CompletionText | Should -BeExactly 'Cmdlet'
$res . CompletionMatches [ 1 ] . CompletionText | Should -BeExactly 'Configuration'
2017-08-04 00:26:20 +02:00
}
It " Test [CommandCompletion]::GetNextResult " {
$inputStr = " Get-Command -Type Alias,c "
$res = TabExpansion2 -inputScript $inputStr -cursorColumn $inputStr . Length
2018-07-30 07:32:52 +02:00
$res . CompletionMatches | Should -HaveCount 2
$res . GetNextResult ( $false ) . CompletionText | Should -BeExactly 'Configuration'
$res . GetNextResult ( $true ) . CompletionText | Should -BeExactly 'Cmdlet'
$res . GetNextResult ( $true ) . CompletionText | Should -BeExactly 'Configuration'
2017-08-04 00:26:20 +02:00
}
2017-08-15 18:49:48 +02:00
It " Test history completion " {
$startDate = Get-Date
$endDate = $startDate . AddSeconds ( 1 )
$history = [ pscustomobject ] @ {
CommandLine = " Test history completion "
ExecutionStatus = " Stopped "
StartExecutionTime = $startDate
EndExecutionTime = $endDate
}
Add-History -InputObject $history
$res = TabExpansion2 -inputScript " # " -cursorColumn 1
2018-03-23 18:48:26 +01:00
$res . CompletionMatches . Count | Should -BeGreaterThan 0
2018-07-30 07:32:52 +02:00
$res . CompletionMatches [ 0 ] . CompletionText | Should -BeExactly " Test history completion "
2017-08-15 18:49:48 +02:00
}
2021-04-14 19:26:48 +02:00
It " Test #requires parameter completion " {
$res = TabExpansion2 -inputScript " #requires - " -cursorColumn 11
$res . CompletionMatches . Count | Should -BeGreaterThan 0
$res . CompletionMatches [ 0 ] . CompletionText | Should -BeExactly " Modules "
}
It " Test #requires parameter value completion " {
$res = TabExpansion2 -inputScript " #requires -PSEdition " -cursorColumn 21
$res . CompletionMatches . Count | Should -BeGreaterThan 0
$res . CompletionMatches [ 0 ] . CompletionText | Should -BeExactly " Core "
}
It " Test no completion after #requires -RunAsAdministrator " {
$res = TabExpansion2 -inputScript " #requires -RunAsAdministrator - " -cursorColumn 31
$res . CompletionMatches | Should -HaveCount 0
}
It " Test no suggestions for already existing parameters in #requires " {
$res = TabExpansion2 -inputScript " #requires -Modules - " -cursorColumn 20
$res . CompletionMatches . CompletionText | Should -Not -Contain " Modules "
}
It " Test module completion in #requires without quotes " {
$res = TabExpansion2 -inputScript " #requires -Modules P " -cursorColumn 20
$res . CompletionMatches . Count | Should -BeGreaterThan 0
$res . CompletionMatches . CompletionText | Should -Contain " Pester "
}
It " Test module completion in #requires with quotes " {
$res = TabExpansion2 -inputScript '#requires -Modules "' -cursorColumn 20
$res . CompletionMatches . Count | Should -BeGreaterThan 0
$res . CompletionMatches . CompletionText | Should -Contain " Pester "
}
It " Test module completion in #requires with multiple modules " {
$res = TabExpansion2 -inputScript " #requires -Modules Pester, " -cursorColumn 26
$res . CompletionMatches . Count | Should -BeGreaterThan 0
$res . CompletionMatches . CompletionText | Should -Contain " Pester "
}
It " Test hashtable key completion in #requires statement for modules " {
$res = TabExpansion2 -inputScript " #requires -Modules @{ " -cursorColumn 21
$res . CompletionMatches . Count | Should -BeGreaterThan 0
$res . CompletionMatches [ 0 ] . CompletionText | Should -BeExactly " GUID "
}
It " Test no suggestions for already existing hashtable keys in #requires statement for modules " {
$res = TabExpansion2 -inputScript '#requires -Modules @{ModuleName="Pester";' -cursorColumn 41
$res . CompletionMatches . Count | Should -BeGreaterThan 0
$res . CompletionMatches . CompletionText | Should -Not -Contain " ModuleName "
}
It " Test no suggestions for mutually exclusive hashtable keys in #requires statement for modules " {
$res = TabExpansion2 -inputScript '#requires -Modules @{ModuleName="Pester";RequiredVersion="1.0";' -cursorColumn 63
$res . CompletionMatches . CompletionText | Should -BeExactly " GUID "
}
It " Test no suggestions for RequiredVersion key in #requires statement when ModuleVersion is specified " {
$res = TabExpansion2 -inputScript '#requires -Modules @{ModuleName="Pester";ModuleVersion="1.0";' -cursorColumn 61
$res . CompletionMatches . Count | Should -BeGreaterThan 0
$res . CompletionMatches . CompletionText | Should -Not -Contain " RequiredVersion "
}
It " Test module completion in #requires statement for hashtables " {
$res = TabExpansion2 -inputScript '#requires -Modules @{ModuleName="p' -cursorColumn 34
$res . CompletionMatches . Count | Should -BeGreaterThan 0
$res . CompletionMatches . CompletionText | Should -Contain " Pester "
}
2017-08-15 18:49:48 +02:00
It " Test Attribute member completion " {
$inputStr = " function bar { [parameter(]param() } "
$res = TabExpansion2 -inputScript $inputStr -cursorColumn ( $inputStr . IndexOf ( '(' ) + 1 )
2018-07-30 07:32:52 +02:00
$res . CompletionMatches | Should -HaveCount 10
2017-08-15 18:49:48 +02:00
$entry = $res . CompletionMatches | Where-Object CompletionText -EQ " Position "
2018-07-30 07:32:52 +02:00
$entry . CompletionText | Should -BeExactly " Position "
2017-08-15 18:49:48 +02:00
}
2021-01-14 05:30:15 +01:00
It " Test Attribute member completion multiple members " {
$inputStr = " function bar { [parameter(Position,]param() } "
$res = TabExpansion2 -inputScript $inputStr -cursorColumn ( $inputStr . IndexOf ( ',' ) + 1 )
$res . CompletionMatches | Should -HaveCount 10
$entry = $res . CompletionMatches | Where-Object CompletionText -EQ " Mandatory "
$entry . CompletionText | Should -BeExactly " Mandatory "
}
2017-08-15 18:49:48 +02:00
2021-11-10 03:26:14 +01:00
It " Test Attribute scriptblock completion " {
$inputStr = '[ValidateScript({Get-Child})]$Test=ls'
$res = TabExpansion2 -inputScript $inputStr -cursorColumn ( $inputStr . IndexOf ( '}' ) )
$res . CompletionMatches | Should -HaveCount 1
$entry = $res . CompletionMatches | Where-Object CompletionText -EQ " Get-ChildItem "
$entry . CompletionText | Should -BeExactly " Get-ChildItem "
}
2017-08-15 18:49:48 +02:00
It " Test completion with line continuation " {
$inputStr = @ '
dir -Recurse `
-Lite
' @
$res = TabExpansion2 -inputScript $inputStr -cursorColumn $inputStr . Length
2018-07-30 07:32:52 +02:00
$res . CompletionMatches | Should -HaveCount 1
$res . CompletionMatches [ 0 ] . CompletionText | Should -BeExactly " -LiteralPath "
2017-08-15 18:49:48 +02:00
}
2018-10-23 13:58:31 +02:00
It " Test member completion of a static method invocation " {
$inputStr = '[powershell]::Create().'
$res = TabExpansion2 -inputScript $inputStr -cursorColumn $inputStr . Length
2019-07-12 04:56:27 +02:00
$res . CompletionMatches | Should -HaveCount 33
2018-10-23 13:58:31 +02:00
$res . CompletionMatches [ 0 ] . CompletionText | Should -BeExactly " Commands "
}
2019-10-31 21:09:37 +01:00
It " Test completion with common parameters " {
$inputStr = 'invoke-webrequest -out'
$res = TabExpansion2 -inputScript $inputStr -cursorColumn $inputStr . Length
$res . CompletionMatches | Should -HaveCount 3
[ string ] :: Join ( ',' , ( $res . CompletionMatches . completiontext | Sort-Object ) ) | Should -BeExactly " -OutBuffer,-OutFile,-OutVariable "
}
It " Test completion with exact match " {
$inputStr = 'get-content -wa'
$res = TabExpansion2 -inputScript $inputStr -cursorColumn $inputStr . Length
$res . CompletionMatches | Should -HaveCount 4
[ string ] :: Join ( ',' , ( $res . CompletionMatches . completiontext | Sort-Object ) ) | Should -BeExactly " -wa,-Wait,-WarningAction,-WarningVariable "
}
2021-06-16 01:56:14 +02:00
It " Test completion with splatted variable " {
$inputStr = 'Get-Content @Splat -P'
$res = TabExpansion2 -inputScript $inputStr -cursorColumn $inputStr . Length
$res . CompletionMatches | Should -HaveCount 4
[ string ] :: Join ( ',' , ( $res . CompletionMatches . completiontext | Sort-Object ) ) | Should -BeExactly " -Path,-PipelineVariable,-PSPath,-pv "
}
2021-11-03 00:53:36 +01:00
It " Test completion for HttpVersion parameter name " {
$inputStr = 'Invoke-WebRequest -HttpV'
$res = TabExpansion2 -inputScript $inputStr -cursorColumn $inputStr . Length
$res . CompletionMatches | Should -HaveCount 1
$res . CompletionMatches [ 0 ] . CompletionText | Should -BeExactly " -HttpVersion "
}
It " Test completion for HttpVersion parameter " {
$inputStr = 'Invoke-WebRequest -HttpVersion '
$res = TabExpansion2 -inputScript $inputStr -cursorColumn $inputStr . Length
$res . CompletionMatches | Should -HaveCount 4
[ string ] :: Join ( ',' , ( $res . CompletionMatches . completiontext | Sort-Object ) ) | Should -BeExactly " 1.0,1.1,2.0,3.0 "
}
It " Test completion for HttpVersion parameter with input " {
$inputStr = 'Invoke-WebRequest -HttpVersion 1'
$res = TabExpansion2 -inputScript $inputStr -cursorColumn $inputStr . Length
$res . CompletionMatches | Should -HaveCount 2
[ string ] :: Join ( ',' , ( $res . CompletionMatches . completiontext | Sort-Object ) ) | Should -BeExactly " 1.0,1.1 "
}
2017-08-15 18:49:48 +02:00
}
Context " Module completion for 'using module' " {
BeforeAll {
$tempDir = Join-Path -Path $TestDrive -ChildPath " UsingModule "
New-Item -Path $tempDir -ItemType Directory -Force > $null
New-Item -Path " $tempDir \testModule.psm1 " -ItemType File -Force > $null
Push-Location -Path $tempDir
}
AfterAll {
Pop-Location
Remove-Item -Path $tempDir -Recurse -Force -ErrorAction SilentlyContinue
}
It " Test complete module file name " {
$inputStr = " using module test "
$res = TabExpansion2 -inputScript $inputStr -cursorColumn $inputStr . Length
2018-07-30 07:32:52 +02:00
$res . CompletionMatches | Should -HaveCount 1
$res . CompletionMatches [ 0 ] . CompletionText | Should -BeExactly " . ${separator} testModule.psm1 "
2017-08-15 18:49:48 +02:00
}
It " Test complete module name " {
$inputStr = " using module PSRead "
$res = TabExpansion2 -inputScript $inputStr -cursorColumn $inputStr . Length
2018-03-23 18:48:26 +01:00
$res . CompletionMatches . Count | Should -BeGreaterThan 0
2018-07-30 07:32:52 +02:00
$res . CompletionMatches [ 0 ] . CompletionText | Should -BeExactly " PSReadLine "
2017-08-15 18:49:48 +02:00
}
It " Test complete module name with wildcard " {
$inputStr = " using module *ReadLi "
$res = TabExpansion2 -inputScript $inputStr -cursorColumn $inputStr . Length
2018-03-23 18:48:26 +01:00
$res . CompletionMatches . Count | Should -BeGreaterThan 0
2018-07-30 07:32:52 +02:00
$res . CompletionMatches [ 0 ] . CompletionText | Should -BeExactly " PSReadLine "
2017-08-15 18:49:48 +02:00
}
}
Context " Completion on 'comma', 'redirection' and 'minus' tokens " {
BeforeAll {
$tempDir = Join-Path -Path $TestDrive -ChildPath " CommaTest "
New-Item -Path $tempDir -ItemType Directory -Force > $null
New-Item -Path " $tempDir \commaA.txt " -ItemType File -Force > $null
$redirectionTestCases = @ (
@ { inputStr = " gps > " ; expected = " . ${separator} commaA.txt " }
@ { inputStr = " gps >> " ; expected = " . ${separator} commaA.txt " }
@ { inputStr = " dir con 2> " ; expected = " . ${separator} commaA.txt " }
@ { inputStr = " dir con 2>> " ; expected = " . ${separator} commaA.txt " }
@ { inputStr = " gps 2>&1> " ; expected = " . ${separator} commaA.txt " }
@ { inputStr = " gps 2>&1>> " ; expected = " . ${separator} commaA.txt " }
)
Push-Location -Path $tempDir
}
AfterAll {
Pop-Location
Remove-Item -Path $tempDir -Recurse -Force -ErrorAction SilentlyContinue
}
It " Test comma with file array element " {
$inputStr = " dir .\commaA.txt, "
$expected = " . ${separator} commaA.txt "
$res = TabExpansion2 -inputScript $inputStr -cursorColumn $inputStr . Length
2018-07-30 07:32:52 +02:00
$res . CompletionMatches | Should -HaveCount 1
$res . CompletionMatches [ 0 ] . CompletionText | Should -BeExactly $expected
2017-08-15 18:49:48 +02:00
}
It " Test comma with Enum array element " {
$inputStr = " gcm -CommandType Cmdlet, "
$res = TabExpansion2 -inputScript $inputStr -cursorColumn $inputStr . Length
2018-07-30 07:32:52 +02:00
$res . CompletionMatches | Should -HaveCount ( [ System.Enum ] :: GetNames ( [ System.Management.Automation.CommandTypes ] ) . Count )
$res . CompletionMatches [ 0 ] . CompletionText | Should -BeExactly " Alias "
2017-08-15 18:49:48 +02:00
}
It " Test redirection operator '<inputStr>' " -TestCases $redirectionTestCases {
param ( $inputStr , $expected )
$res = TabExpansion2 -inputScript $inputStr -cursorColumn $inputStr . Length
2018-07-30 07:32:52 +02:00
$res . CompletionMatches | Should -HaveCount 1
$res . CompletionMatches [ 0 ] . CompletionText | Should -BeExactly $expected
2017-08-15 18:49:48 +02:00
}
It " Test complete the minus token to operators " {
$inputStr = " 55 - "
$res = TabExpansion2 -inputScript $inputStr -cursorColumn $inputStr . Length
2018-07-30 07:32:52 +02:00
$res . CompletionMatches | Should -HaveCount ( [ System.Management.Automation.CompletionCompleters ] :: CompleteOperator ( " " ) . Count )
$res . CompletionMatches [ 0 ] . CompletionText | Should -BeExactly '-and'
2017-08-15 18:49:48 +02:00
}
2017-08-04 00:26:20 +02:00
}
Context " Folder/File path tab completion with special characters " {
BeforeAll {
2017-08-15 18:49:48 +02:00
$tempDir = Join-Path -Path $TestDrive -ChildPath " SpecialChar "
New-Item -Path $tempDir -ItemType Directory -Force > $null
New-Item -Path " $tempDir \My [Path] " -ItemType Directory -Force > $null
New-Item -Path " $tempDir \My [Path]\test.ps1 " -ItemType File -Force > $null
New-Item -Path " $tempDir \)file.txt " -ItemType File -Force > $null
2017-08-04 00:26:20 +02:00
$testCases = @ (
@ { inputStr = " cd My " ; expected = " '. ${separator} My `` [Path `` ]' " }
@ { inputStr = " Get-Help '.\My `` [Path `` ]'\ " ; expected = " '. ${separator} My `` [Path `` ] ${separator} test.ps1' " }
@ { inputStr = " Get-Process >My " ; expected = " '. ${separator} My `` [Path `` ]' " }
@ { inputStr = " Get-Process >'.\My `` [Path `` ]\' " ; expected = " '. ${separator} My `` [Path `` ] ${separator} test.ps1' " }
2017-08-15 18:49:48 +02:00
@ { inputStr = " Get-Process > ${tempDir} \My " ; expected = " ' ${tempDir} ${separator} My `` [Path `` ]' " }
@ { inputStr = " Get-Process > ' ${tempDir} \My `` [Path `` ]\' " ; expected = " ' ${tempDir} ${separator} My `` [Path `` ] ${separator} test.ps1' " }
2017-08-04 00:26:20 +02:00
)
2017-08-15 18:49:48 +02:00
Push-Location -Path $tempDir
2017-08-04 00:26:20 +02:00
}
AfterAll {
Pop-Location
2017-08-15 18:49:48 +02:00
Remove-Item -Path $tempDir -Recurse -Force -ErrorAction SilentlyContinue
2017-08-04 00:26:20 +02:00
}
It " Complete special relative path '<inputStr>' " -TestCases $testCases {
param ( $inputStr , $expected )
$res = TabExpansion2 -inputScript $inputStr -cursorColumn $inputStr . Length
2018-03-23 18:48:26 +01:00
$res . CompletionMatches . Count | Should -BeGreaterThan 0
2018-07-30 07:32:52 +02:00
$res . CompletionMatches [ 0 ] . CompletionText | Should -BeExactly $expected
2017-08-04 00:26:20 +02:00
}
2017-08-15 18:49:48 +02:00
It " Complete file name starting with special char " {
$inputStr = " ) "
$res = TabExpansion2 -inputScript $inputStr -cursorColumn $inputStr . Length
2018-07-30 07:32:52 +02:00
$res . CompletionMatches | Should -HaveCount 1
$res . CompletionMatches [ 0 ] . CompletionText | Should -BeExactly " & '. ${separator} )file.txt' "
2017-08-15 18:49:48 +02:00
}
2017-08-04 00:26:20 +02:00
}
Context " Local tab completion with AST " {
BeforeAll {
$testCases = @ (
@ { inputStr = '$p = Get-Process; $p | % ProcessN ' ; bareWord = 'ProcessN' ; expected = 'ProcessName' }
@ { inputStr = 'function bar { Get-Ali* }' ; bareWord = 'Get-Ali*' ; expected = 'Get-Alias' }
@ { inputStr = 'function baz ([string]$version, [consolecolor]$name){} baz version bl' ; bareWord = 'bl' ; expected = 'Black' }
)
}
It " Input '<inputStr>' should successfully complete via AST " -TestCases $testCases {
param ( $inputStr , $bareWord , $expected )
$tokens = $null
$ast = [ System.Management.Automation.Language.Parser ] :: ParseInput ( $inputStr , [ ref ] $tokens , [ ref ] $null )
$elementAst = $ast . Find (
{ $args [ 0 ] -is [ System.Management.Automation.Language.StringConstantExpressionAst ] -and $args [ 0 ] . Value -eq $bareWord } ,
$true
)
$res = TabExpansion2 -ast $ast -tokens $tokens -positionOfCursor $elementAst . Extent . EndScriptPosition
2018-03-23 18:48:26 +01:00
$res . CompletionMatches . Count | Should -BeGreaterThan 0
2018-07-30 07:32:52 +02:00
$res . CompletionMatches [ 0 ] . CompletionText | Should -BeExactly $expected
2017-08-04 00:26:20 +02:00
}
}
Context " User-overridden TabExpansion implementations " {
It " Override TabExpansion with function " {
function TabExpansion ( $line , $lastword ) {
" Overridden-TabExpansion-Function "
}
2020-01-13 20:34:38 +01:00
$inputStr = '$PID.'
2017-08-04 00:26:20 +02:00
$res = [ System.Management.Automation.CommandCompletion ] :: CompleteInput ( $inputStr , $inputst . Length , $null )
2018-07-30 07:32:52 +02:00
$res . CompletionMatches | Should -HaveCount 1
$res . CompletionMatches [ 0 ] . CompletionText | Should -BeExactly 'Overridden-TabExpansion-Function'
2017-08-04 00:26:20 +02:00
}
It " Override TabExpansion with alias " {
function OverrideTabExpansion ( $line , $lastword ) {
" Overridden-TabExpansion-Alias "
}
Set-Alias -Name TabExpansion -Value OverrideTabExpansion
2020-01-13 20:34:38 +01:00
$inputStr = '$PID.'
2017-08-04 00:26:20 +02:00
$res = [ System.Management.Automation.CommandCompletion ] :: CompleteInput ( $inputStr , $inputst . Length , $null )
2018-07-30 07:32:52 +02:00
$res . CompletionMatches | Should -HaveCount 1
$res . CompletionMatches [ 0 ] . CompletionText | Should -BeExactly " Overridden-TabExpansion-Alias "
2017-08-04 00:26:20 +02:00
}
}
Context " No tab completion tests " {
BeforeAll {
$testCases = @ (
@ { inputStr = 'function new-' }
@ { inputStr = 'filter new-' }
@ { inputStr = '@pid.' }
)
}
It " Input '<inputStr>' should not complete to anything " -TestCases $testCases {
param ( $inputStr )
$res = TabExpansion2 -inputScript $inputStr -cursorColumn $inputStr . Length
2018-07-30 07:32:52 +02:00
$res . CompletionMatches | Should -BeNullOrEmpty
2017-08-04 00:26:20 +02:00
}
}
2018-07-30 07:32:52 +02:00
Context " Tab completion error tests " {
2017-08-04 00:26:20 +02:00
BeforeAll {
$ast = { } . Ast ;
$tokens = [ System.Management.Automation.Language.Token[] ] @ ( )
$testCases = @ (
2020-01-13 20:34:38 +01:00
@ { inputStr = { [ System.Management.Automation.CommandCompletion ] :: MapStringInputToParsedInput ( '$PID.' , 7 ) } ; expected = " PSArgumentException " }
2017-08-04 00:26:20 +02:00
@ { inputStr = { [ System.Management.Automation.CommandCompletion ] :: CompleteInput ( $null , $null , $null , $null ) } ; expected = " PSArgumentNullException " }
@ { inputStr = { [ System.Management.Automation.CommandCompletion ] :: CompleteInput ( $ast , $null , $null , $null ) } ; expected = " PSArgumentNullException " }
@ { inputStr = { [ System.Management.Automation.CommandCompletion ] :: CompleteInput ( $ast , $tokens , $null , $null ) } ; expected = " PSArgumentNullException " }
2020-01-13 20:34:38 +01:00
@ { inputStr = { [ System.Management.Automation.CommandCompletion ] :: CompleteInput ( '$PID.' , 7 , $null , $null ) } ; expected = " PSArgumentException " }
@ { inputStr = { [ System.Management.Automation.CommandCompletion ] :: CompleteInput ( '$PID.' , 5 , $null , $null ) } ; expected = " PSArgumentNullException " }
2017-08-04 00:26:20 +02:00
@ { inputStr = { [ System.Management.Automation.CommandCompletion ] :: CompleteInput ( $null , $null , $null , $null , $null ) } ; expected = " PSArgumentNullException " }
@ { inputStr = { [ System.Management.Automation.CommandCompletion ] :: CompleteInput ( $ast , $null , $null , $null , $null ) } ; expected = " PSArgumentNullException " }
@ { inputStr = { [ System.Management.Automation.CommandCompletion ] :: CompleteInput ( $ast , $tokens , $null , $null , $null ) } ; expected = " PSArgumentNullException " }
@ { inputStr = { [ System.Management.Automation.CommandCompletion ] :: CompleteInput ( $ast , $tokens , $ast . Extent . EndScriptPosition , $null , $null ) } ; expected = " PSArgumentNullException " }
)
}
It " Input '<inputStr>' should throw in tab completion " -TestCases $testCases {
param ( $inputStr , $expected )
2018-05-17 23:42:04 +02:00
$inputStr | Should -Throw -ErrorId $expected
2017-08-04 00:26:20 +02:00
}
}
Context " DSC tab completion tests " {
BeforeAll {
$testCases = @ (
@ { inputStr = 'Configura' ; expected = 'Configuration' }
@ { inputStr = '$extension = New-Object [System.Collections.Generic.List[string]]; $extension.wh' ; expected = " Where( " }
@ { inputStr = '$extension = New-Object [System.Collections.Generic.List[string]]; $extension.fo' ; expected = 'ForEach(' }
@ { inputStr = 'Configuration foo { node $SelectedNodes.' ; expected = 'Where(' }
@ { inputStr = 'Configuration foo { node $SelectedNodes.fo' ; expected = 'ForEach(' }
@ { inputStr = 'Configuration foo { node $AllNodes.' ; expected = 'Where(' }
@ { inputStr = 'Configuration foo { node $ConfigurationData.AllNodes.' ; expected = 'Where(' }
@ { inputStr = 'Configuration foo { node $ConfigurationData.AllNodes.fo' ; expected = 'ForEach(' }
@ { inputStr = 'Configuration bar { File foo { Destinat' ; expected = 'DestinationPath = ' }
@ { inputStr = 'Configuration bar { File foo { Content' ; expected = 'Contents = ' }
@ { inputStr = 'Configuration bar { Fil' ; expected = 'File' }
@ { inputStr = 'Configuration bar { Import-Dsc' ; expected = 'Import-DscResource' }
@ { inputStr = 'Configuration bar { Import-DscResource -Modu' ; expected = '-ModuleName' }
@ { inputStr = 'Configuration bar { Import-DscResource -ModuleName blah -Modu' ; expected = '-ModuleVersion' }
@ { inputStr = 'Configuration bar { Scri' ; expected = 'Script' }
@ { inputStr = 'configuration foo { Script ab {Get' ; expected = 'GetScript = ' }
@ { inputStr = 'configuration foo { Script ab { ' ; expected = 'DependsOn = ' }
2017-08-15 18:49:48 +02:00
@ { inputStr = 'configuration foo { File ab { Attributes =' ; expected = " 'Archive' " }
@ { inputStr = " configuration foo { File ab { Attributes = " ; expected = " 'Archive' " }
@ { inputStr = " configuration foo { File ab { Attributes = ar " ; expected = " Archive " }
@ { inputStr = " configuration foo { File ab { Attributes = 'ar " ; expected = " Archive " }
@ { inputStr = 'configuration foo { File ab { Attributes =(' ; expected = " 'Archive' " }
@ { inputStr = 'configuration foo { File ab { Attributes =( ' ; expected = " 'Archive' " }
@ { inputStr = " configuration foo { File ab { Attributes =('Archive', " ; expected = " 'Hidden' " }
@ { inputStr = " configuration foo { File ab { Attributes =('Archive', " ; expected = " 'Hidden' " }
@ { inputStr = " configuration foo { File ab { Attributes =('Archive', 'Hi " ; expected = " Hidden " }
2017-08-04 00:26:20 +02:00
)
}
It " Input '<inputStr>' should successfully complete " -TestCases $testCases -Skip: ( ! $IsWindows ) {
param ( $inputStr , $expected )
$res = TabExpansion2 -inputScript $inputStr -cursorColumn $inputStr . Length
2018-03-23 18:48:26 +01:00
$res . CompletionMatches . Count | Should -BeGreaterThan 0
2018-07-30 07:32:52 +02:00
$res . CompletionMatches [ 0 ] . CompletionText | Should -BeExactly $expected
2017-08-04 00:26:20 +02:00
}
}
Context " CIM cmdlet completion tests " {
BeforeAll {
$testCases = @ (
@ { inputStr = " Invoke-CimMethod -ClassName Win32_Process -MethodName Crea " ; expected = " Create " }
@ { inputStr = " Get-CimInstance -ClassName Win32_Process | Invoke-CimMethod -MethodName AttachDeb " ; expected = " AttachDebugger " }
2020-01-13 20:34:38 +01:00
@ { inputStr = 'Get-CimInstance Win32_Process | ?{ $_.ProcessId -eq $PID } | Get-CimAssociatedInstance -ResultClassName Win32_Co*uterSyst' ; expected = " Win32_ComputerSystem " }
2017-08-04 00:26:20 +02:00
@ { inputStr = " Get-CimInstance -ClassName Win32_Environm " ; expected = " Win32_Environment " }
@ { inputStr = " New-CimInstance -ClassName Win32_Environm " ; expected = " Win32_Environment " }
@ { inputStr = 'New-CimInstance -ClassName Win32_Process | %{ $_.Captio' ; expected = " Caption " }
@ { inputStr = " Invoke-CimMethod -ClassName Win32_Environm " ; expected = 'Win32_Environment' }
@ { inputStr = " Get-CimClass -ClassName Win32_Environm " ; expected = 'Win32_Environment' }
@ { inputStr = 'Get-CimInstance -ClassName Win32_Process | Invoke-CimMethod -MethodName SetPriorit' ; expected = 'SetPriority' }
@ { inputStr = 'Invoke-CimMethod -Namespace root/StandardCimv2 -ClassName MSFT_NetIPAddress -MethodName Crea' ; expected = 'Create' }
@ { inputStr = '$win32_process = Get-CimInstance -ClassName Win32_Process; $win32_process | Invoke-CimMethod -MethodName AttachDe' ; expected = 'AttachDebugger' }
@ { inputStr = '$win32_process = Get-CimInstance -ClassName Win32_Process; Invoke-CimMethod -InputObject $win32_process -MethodName AttachDe' ; expected = 'AttachDebugger' }
2020-01-13 20:34:38 +01:00
@ { inputStr = 'Get-CimInstance Win32_Process | ?{ $_.ProcessId -eq $PID } | Get-CimAssociatedInstance -ResultClassName Win32_ComputerS' ; expected = 'Win32_ComputerSystem' }
2017-08-04 00:26:20 +02:00
@ { inputStr = 'Get-CimInstance -Namespace root/Interop -ClassName Win32_PowerSupplyP' ; expected = 'Win32_PowerSupplyProfile' }
@ { inputStr = 'Get-CimInstance __NAMESP' ; expected = '__NAMESPACE' }
2017-10-13 22:54:43 +02:00
@ { inputStr = 'Get-CimInstance -Namespace root/Inter' ; expected = 'root/Interop' }
2017-08-04 00:26:20 +02:00
@ { inputStr = 'Get-CimInstance -Namespace root/Int*ro' ; expected = 'root/Interop' }
@ { inputStr = 'Get-CimInstance -Namespace root/Interop/' ; expected = 'root/Interop/ms_409' }
2017-10-13 22:54:43 +02:00
@ { inputStr = 'New-CimInstance -Namespace root/Inter' ; expected = 'root/Interop' }
@ { inputStr = 'Invoke-CimMethod -Namespace root/Inter' ; expected = 'root/Interop' }
@ { inputStr = 'Get-CimClass -Namespace root/Inter' ; expected = 'root/Interop' }
@ { inputStr = 'Register-CimIndicationEvent -Namespace root/Inter' ; expected = 'root/Interop' }
2017-08-04 00:26:20 +02:00
@ { inputStr = '[Microsoft.Management.Infrastructure.CimClass]$c = $null; $c.CimClassNam' ; expected = 'CimClassName' }
@ { inputStr = '[Microsoft.Management.Infrastructure.CimClass]$c = $null; $c.CimClassName.Substrin' ; expected = 'Substring(' }
@ { inputStr = 'Get-CimInstance -ClassName Win32_Process | %{ $_.ExecutableP' ; expected = 'ExecutablePath' }
)
}
It " CIM cmdlet input '<inputStr>' should successfully complete " -TestCases $testCases -Skip: ( ! $IsWindows ) {
param ( $inputStr , $expected )
$res = TabExpansion2 -inputScript $inputStr -cursorColumn $inputStr . Length
2018-03-23 18:48:26 +01:00
$res . CompletionMatches . Count | Should -BeGreaterThan 0
2020-05-12 23:26:22 +02:00
$res . CompletionMatches [ 0 ] . CompletionText | Should -Be $expected
2017-08-04 00:26:20 +02:00
}
}
2017-09-13 02:12:52 +02:00
Context " Module cmdlet completion tests " {
It " ArugmentCompleter for PSEdition should work for '<cmd>' " -TestCases @ (
@ { cmd = " Get-Module -PSEdition " ; expected = " Desktop " , " Core " }
) {
param ( $cmd , $expected )
$res = TabExpansion2 -inputScript $cmd -cursorColumn $cmd . Length
2018-07-30 07:32:52 +02:00
$res . CompletionMatches | Should -HaveCount $expected . Count
2017-09-13 02:12:52 +02:00
$completionOptions = " "
foreach ( $completion in $res . CompletionMatches ) {
$completionOptions + = $completion . ListItemText
}
2018-07-30 07:32:52 +02:00
$completionOptions | Should -BeExactly ( [ string ] :: Join ( " " , $expected ) )
2017-09-13 02:12:52 +02:00
}
}
2017-08-04 00:26:20 +02:00
2018-04-03 00:32:55 +02:00
Context " Tab completion help test " {
BeforeAll {
if ( [ System.Management.Automation.Platform ] :: IsWindows ) {
$userHelpRoot = Join-Path $HOME " Documents/PowerShell/Help/ "
} else {
$userModulesRoot = [ System.Management.Automation.Platform ] :: SelectProductNameForDirectory ( [ System . Management . Automation . Platform + XDG_Type ] :: USER_MODULES )
$userHelpRoot = Join-Path $userModulesRoot -ChildPath " .. " -AdditionalChildPath " Help "
}
}
2017-11-16 01:29:04 +01:00
2018-04-03 00:32:55 +02:00
It 'Should complete about help topic' {
2018-11-30 01:16:36 +01:00
$aboutHelpPathUserScope = Join-Path $userHelpRoot ( Get-Culture ) . Name
$aboutHelpPathAllUsersScope = Join-Path $PSHOME ( Get-Culture ) . Name
2017-11-16 01:29:04 +01:00
2018-04-03 00:32:55 +02:00
## If help content does not exist, tab completion will not work. So update it first.
2018-11-30 01:16:36 +01:00
$userScopeHelp = Test-Path ( Join-Path $aboutHelpPathUserScope " about_Splatting.help.txt " )
$allUserScopeHelp = Test-Path ( Join-Path $aboutHelpPathAllUsersScope " about_Splatting.help.txt " )
if ( ( -not $userScopeHelp ) -and ( -not $aboutHelpPathAllUsersScope ) ) {
2018-04-03 00:32:55 +02:00
Update-Help -Force -ErrorAction SilentlyContinue -Scope 'CurrentUser'
}
2017-11-16 01:29:04 +01:00
2018-11-30 01:16:36 +01:00
# If help content is present on both scopes, expect 2 or else expect 1 completion.
$expectedCompletions = if ( $userScopeHelp -and $allUserScopeHelp ) { 2 } else { 1 }
2018-04-03 00:32:55 +02:00
$res = TabExpansion2 -inputScript 'get-help about_spla' -cursorColumn 'get-help about_spla' . Length
2018-11-30 01:16:36 +01:00
$res . CompletionMatches | Should -HaveCount $expectedCompletions
2018-04-03 00:32:55 +02:00
$res . CompletionMatches [ 0 ] . CompletionText | Should -BeExactly 'about_Splatting'
}
2021-05-05 20:24:40 +02:00
It 'Should complete about help topic regardless of culture' {
try
{
## Save original culture and temporarily set it to da-DK because there's no localized help for da-DK.
$OriginalCulture = [ cultureinfo ] :: CurrentCulture
[ cultureinfo ] :: CurrentCulture = " da-DK "
2021-07-13 19:32:48 +02:00
2021-05-05 20:24:40 +02:00
$res = TabExpansion2 -inputScript 'get-help about_spla' -cursorColumn 'get-help about_spla' . Length
$res . CompletionMatches | Should -HaveCount 1
$res . CompletionMatches [ 0 ] . CompletionText | Should -BeExactly 'about_Splatting'
}
finally
{
[ cultureinfo ] :: CurrentCulture = $OriginalCulture
}
}
2021-05-25 22:36:53 +02:00
It '<Intent>' -TestCases @ (
@ {
Intent = 'Complete help keywords with minimum input'
Expected = @ (
'COMPONENT'
'DESCRIPTION'
'EXAMPLE'
'EXTERNALHELP'
'FORWARDHELPCATEGORY'
'FORWARDHELPTARGETNAME'
'FUNCTIONALITY'
'INPUTS'
'LINK'
'NOTES'
'OUTPUTS'
'PARAMETER'
'REMOTEHELPRUNSPACE'
'ROLE'
'SYNOPSIS'
)
TestString = @ '
<#
. ^
#>
' @
}
@ {
Intent = 'Complete help keywords without duplicates'
Expected = $null
TestString = @ '
<#
. SYNOPSIS
. S ^
#>
' @
}
@ {
Intent = 'Complete help keywords with allowed duplicates'
Expected = 'PARAMETER'
TestString = @ '
<#
. PARAMETER
. Paramet ^
#>
' @
}
@ {
Intent = 'Complete help keyword FORWARDHELPTARGETNAME argument'
Expected = 'Get-ChildItem'
TestString = @ '
<#
. FORWARDHELPTARGETNAME Get-Child ^
#>
' @
}
@ {
Intent = 'Complete help keyword FORWARDHELPCATEGORY argument'
Expected = 'Cmdlet'
TestString = @ '
<#
. FORWARDHELPCATEGORY C ^
#>
' @
}
@ {
Intent = 'Complete help keyword REMOTEHELPRUNSPACE argument'
Expected = 'PSEdition'
TestString = @ '
<#
. REMOTEHELPRUNSPACE PSEditi ^
#>
' @
}
@ {
Intent = 'Complete help keyword EXTERNALHELP argument'
Expected = Join-Path $PSHOME " pwsh.xml "
TestString = @"
<#
. EXTERNALHELP $PSHOME \ pwsh . ^
#>
" @
}
@ {
Intent = 'Complete help keyword PARAMETER argument for script'
Expected = 'Param1'
TestString = @ '
<#
. PARAMETER ^
#>
param ( $Param1 )
' @
}
@ {
Intent = 'Complete help keyword PARAMETER argument for function with help inside'
Expected = 'param2'
TestString = @ '
function MyFunction ( $param1 , $param2 )
{
<#
. PARAMETER param1
. PARAMETER ^
#>
}
' @
}
@ {
Intent = 'Complete help keyword PARAMETER argument for function with help before it'
Expected = 'param1' , 'param2'
TestString = @ '
<#
. PARAMETER ^
#>
function MyFunction ( $param1 , $param2 )
{
}
' @
}
@ {
Intent = 'Complete help keyword PARAMETER argument for advanced function with help inside'
Expected = 'Param1'
TestString = @ '
function Verb-Noun
{
<#
. PARAMETER ^
#>
[ CmdletBinding ( ) ]
Param
(
$Param1
)
Begin
{
}
Process
{
}
End
{
}
}
' @
}
@ {
Intent = 'Complete help keyword PARAMETER argument for nested function with help before it'
Expected = 'param3' , 'param4'
TestString = @ '
function MyFunction ( $param1 , $param2 )
{
<#
. PARAMETER ^
#>
function MyFunction2 ( $param3 , $param4 )
{
}
}
' @
}
@ {
Intent = 'Not complete help keyword PARAMETER argument if following function is too far away'
Expected = $null
TestString = @ '
<#
. PARAMETER ^
#>
function MyFunction ( $param1 , $param2 )
{
}
' @
}
) {
param ( $Expected , $TestString )
$CursorIndex = $TestString . IndexOf ( '^' )
$res = TabExpansion2 -cursorColumn $CursorIndex -inputScript $TestString . Remove ( $CursorIndex , 1 )
$res . CompletionMatches . CompletionText | Should -BeExactly $Expected
}
2017-11-16 01:29:04 +01:00
}
}
2018-11-10 00:11:02 +01:00
Describe " Tab completion tests with remote Runspace " -Tags Feature , RequireAdminOnWindows {
2017-08-04 00:26:20 +02:00
BeforeAll {
if ( $IsWindows ) {
$session = New-RemoteSession
$powershell = [ powershell ] :: Create ( )
$powershell . Runspace = $session . Runspace
$testCases = @ (
@ { inputStr = 'Get-Proc' ; expected = 'Get-Process' }
@ { inputStr = 'Get-Process | % ProcessN' ; expected = 'ProcessName' }
@ { inputStr = 'Get-ChildItem alias: | % { $_.Defini' ; expected = 'Definition' }
)
$testCasesWithAst = @ (
@ { inputStr = '$p = Get-Process; $p | % ProcessN ' ; bareWord = 'ProcessN' ; expected = 'ProcessName' }
@ { inputStr = 'function bar { Get-Ali* }' ; bareWord = 'Get-Ali*' ; expected = 'Get-Alias' }
@ { inputStr = 'function baz ([string]$version, [consolecolor]$name){} baz version bl' ; bareWord = 'bl' ; expected = 'Black' }
)
} else {
$defaultParameterValues = $PSDefaultParameterValues . Clone ( )
$PSDefaultParameterValues [ " It:Skip " ] = $true
}
}
AfterAll {
if ( $IsWindows ) {
Remove-PSSession $session
$powershell . Dispose ( )
} else {
$Global:PSDefaultParameterValues = $defaultParameterValues
}
}
It " Input '<inputStr>' should successfully complete in remote runspace " -TestCases $testCases {
param ( $inputStr , $expected )
$res = [ System.Management.Automation.CommandCompletion ] :: CompleteInput ( $inputStr , $inputStr . Length , $null , $powershell )
2018-03-23 18:48:26 +01:00
$res . CompletionMatches . Count | Should -BeGreaterThan 0
2018-07-30 07:32:52 +02:00
$res . CompletionMatches [ 0 ] . CompletionText | Should -BeExactly $expected
2017-08-04 00:26:20 +02:00
}
It " Input '<inputStr>' should successfully complete via AST in remote runspace " -TestCases $testCasesWithAst {
param ( $inputStr , $bareWord , $expected )
$tokens = $null
$ast = [ System.Management.Automation.Language.Parser ] :: ParseInput ( $inputStr , [ ref ] $tokens , [ ref ] $null )
$elementAst = $ast . Find (
{ $args [ 0 ] -is [ System.Management.Automation.Language.StringConstantExpressionAst ] -and $args [ 0 ] . Value -eq $bareWord } ,
$true
)
$res = [ System.Management.Automation.CommandCompletion ] :: CompleteInput ( $ast , $tokens , $elementAst . Extent . EndScriptPosition , $null , $powershell )
2018-03-23 18:48:26 +01:00
$res . CompletionMatches . Count | Should -BeGreaterThan 0
2018-07-30 07:32:52 +02:00
$res . CompletionMatches [ 0 ] . CompletionText | Should -BeExactly $expected
2017-08-04 00:26:20 +02:00
}
2017-04-25 01:45:05 +02:00
}
2017-09-19 00:44:09 +02:00
Describe " WSMan Config Provider tab complete tests " -Tags Feature , RequireAdminOnWindows {
BeforeAll {
$originalDefaultParameterValues = $PSDefaultParameterValues . Clone ( )
$PSDefaultParameterValues [ " it:skip " ] = ! $IsWindows
}
AfterAll {
$Global:PSDefaultParameterValues = $originalDefaultParameterValues
}
It " Tab completion works correctly for Listeners " {
$path = " wsman:\localhost\listener\listener "
$res = TabExpansion2 -inputScript $path -cursorColumn $path . Length
$listener = Get-ChildItem WSMan : \ localhost \ Listener
2018-03-23 18:48:26 +01:00
$res . CompletionMatches . Count | Should -Be $listener . Count
2018-11-10 00:11:02 +01:00
$res . CompletionMatches . ListItemText | Should -BeIn $listener . Name
2017-09-19 00:44:09 +02:00
}
It " Tab completion gets dynamic parameters for '<path>' using '<parameter>' " -TestCases @ (
2019-10-31 21:09:37 +01:00
@ { path = " " ; parameter = " -conn " ; expected = " ConnectionURI " } ,
2017-09-19 00:44:09 +02:00
@ { path = " " ; parameter = " -op " ; expected = " OptionSet " } ,
@ { path = " " ; parameter = " -au " ; expected = " Authentication " } ,
@ { path = " " ; parameter = " -ce " ; expected = " CertificateThumbprint " } ,
@ { path = " " ; parameter = " -se " ; expected = " SessionOption " } ,
@ { path = " " ; parameter = " -ap " ; expected = " ApplicationName " } ,
@ { path = " " ; parameter = " -po " ; expected = " Port " } ,
@ { path = " " ; parameter = " -u " ; expected = " UseSSL " } ,
@ { path = " localhost\plugin " ; parameter = " -pl " ; expected = " Plugin " } ,
@ { path = " localhost\plugin " ; parameter = " -sd " ; expected = " SDKVersion " } ,
@ { path = " localhost\plugin " ; parameter = " -re " ; expected = " Resource " } ,
@ { path = " localhost\plugin " ; parameter = " -ca " ; expected = " Capability " } ,
@ { path = " localhost\plugin " ; parameter = " -xm " ; expected = " XMLRenderingType " } ,
@ { path = " localhost\plugin " ; parameter = " -fi " ; expected = @ ( " FileName " , " File " ) } ,
@ { path = " localhost\plugin " ; parameter = " -ru " ; expected = " RunAsCredential " } ,
@ { path = " localhost\plugin " ; parameter = " -us " ; expected = " UseSharedProcess " } ,
@ { path = " localhost\plugin " ; parameter = " -au " ; expected = " AutoRestart " } ,
@ { path = " localhost\plugin " ; parameter = " -pr " ; expected = " ProcessIdleTimeoutSec " } ,
@ { path = " localhost\Plugin\microsoft.powershell\Resources\ " ; parameter = " -re " ; expected = " ResourceUri " } ,
@ { path = " localhost\Plugin\microsoft.powershell\Resources\ " ; parameter = " -ca " ; expected = " Capability " }
) {
param ( $path , $parameter , $expected )
$script = " new-item wsman:\ $path $parameter "
2019-10-30 21:45:28 +01:00
$res = TabExpansion2 -inputScript $script
2018-07-30 07:32:52 +02:00
$res . CompletionMatches | Should -HaveCount $expected . Count
2017-09-19 00:44:09 +02:00
$completionOptions = " "
foreach ( $completion in $res . CompletionMatches ) {
$completionOptions + = $completion . ListItemText
}
2018-07-30 07:32:52 +02:00
$completionOptions | Should -BeExactly ( [ string ] :: Join ( " " , $expected ) )
2017-09-19 00:44:09 +02:00
}
It " Tab completion get dynamic parameters for initialization parameters " -Pending -TestCases @ (
@ { path = " localhost\Plugin\microsoft.powershell\InitializationParameters\ " ; parameter = " -pa " ; expected = @ ( " ParamName " , " ParamValue " ) }
) {
# https://github.com/PowerShell/PowerShell/issues/4744
# TODO: move to test cases above once working
}
}