diff --git a/src/GitParamTabExpansion.ps1 b/src/GitParamTabExpansion.ps1 index 0082ea40d..cdae9a65a 100644 --- a/src/GitParamTabExpansion.ps1 +++ b/src/GitParamTabExpansion.ps1 @@ -93,18 +93,150 @@ $shortVstsParams = @{ update = "d i $shortVstsGlobal" } +$shortAzGlobal = 'h o' +$shortAzParams = @{ + checkout = " $shortAzGlobal" + create = "d p r s t $shortAzGlobal" + list = "p r s t $shortAzGlobal" + 'set-vote' = " $shortAzGlobal" + show = " $shortAzGlobal" + update = "d $shortAzGlobal" +} + $longVstsGlobal = 'debug help output query verbose' $longVstsParams = @{ abandon = "id detect instance $longVstsGlobal" create = "auto-complete delete-source-branch work-items bypass-policy bypass-policy-reason description detect instance merge-commit-message open project repository reviewers source-branch squash target-branch title $longVstsGlobal" complete = "id detect instance $longVstsGlobal" - list = " $longVstsGlobal" - reactivate = " $longVstsGlobal" - 'set-vote' = " $longVstsGlobal" - show = " $longVstsGlobal" - update = " $longVstsGlobal" + list = "creator detect include-links instance project repository reviewer skip source-branch status= target-branch top $longVstsGlobal" + reactivate = "id detect instance $longVstsGlobal" + 'set-vote' = "id vote detect instance $longVstsGlobal" + show = "id detect instance open $longVstsGlobal" + update = "id auto-complete delete-source-branch bypass-policy bypass-policy-reason description detect instance merge-commit-message squash title transition-work-items $longVstsGlobal" +} + +$longAzGlobal = 'debug help output query verbose' +$longAzParams = @{ + checkout = "id remote-name $longAzGlobal" + create = "auto-complete delete-source-branch work-items bypass-policy bypass-policy-reason description detect draft merge-commit-message open organization project repository reviewers source-branch squash target-branch title transition-work-items work-items $longAzGlobal" + list = "creator include-links detect organization repository reviewer skip source-branch status= target-branch top $longAzGlobal" + 'set-vote' = "id vote= $longAzGlobal" + show = "id detect open organization $longAzGlobal" + update = "id auto-complete bypass-policy bypass-policy-reason delete-source-branch description detect draft merge-commit-message organization squash status= title transition-work-items $longAzGlobal" +} + +$vstsCommandsWithSubCommands = @{ + policies = "list queue" + reviewers = "add list remove" + 'work-items' = "add list remove" } +$azCommandsWithSubCommands = @{ + policy = "list queue" + reviewer = "add list remove" + 'work-item' = "add list remove" +} + +$shortVstsSubCommandParams = @{ + policies = @{ + list = "i $shortVstsGlobal" + queue = "e i $shortVstsGlobal" + } + reviewers = @{ + add = "i $shortVstsGlobal" + list = "i $shortVstsGlobal" + remove = "i $shortVstsGlobal" + } + 'work-items' = @{ + add = "i $shortVstsGlobal" + list = "i $shortVstsGlobal" + remove = "i $shortVstsGlobal" + } +} + +$shortAzSubCommandParams = @{ + policy = @{ + list = " $shortAzGlobal" + queue = "e $shortAzGlobal" + } + reviewer = @{ + add = " $shortAzGlobal" + list = " $shortAzGlobal" + remove = " $shortAzGlobal" + } + 'work-item' = @{ + add = " $shortAzGlobal" + list = " $shortAzGlobal" + remove = " $shortAzGlobal" + } +} + +# these aren't "global" commands, but *are* common to each of the below +$longAzSubCommandCommon = "id detect organization" + +$longAzSubCommandParams = @{ + policy = @{ + list = "$longAzSubCommandCommon skip top $longAzGlobal" + queue = "$longAzSubCommandCommon evaluation-id $longAzGlobal" + } + reviewer = @{ + add = "$longAzSubCommandCommon reviewers $longAzGlobal" + list = "$longAzSubCommandCommon $longAzGlobal" + remove = "$longAzSubCommandCommon reviewers $longAzGlobal" + } + 'work-item' = @{ + add = "$longAzSubCommandCommon work-items $longAzGlobal" + list = "$longAzSubCommandCommon $longAzGlobal" + remove = "$longAzSubCommandCommon work-items $longAzGlobal" + } +} + +$longVstsSubCommandCommon = "id detect instance" +$longVstsSubCommandParams = @{ + policies = @{ + list = "$longVstsSubCommandCommon skip top $longVstsGlobal" + queue = "$longVstsSubCommandCommon evaluation-id $longVstsGlobal" + } + reviewers = @{ + add = "$longVstsSubCommandCommon reviewers $longVstsGlobal" + list = "$longVstsSubCommandCommon $longVstsGlobal" + remove = "$longVstsSubCommandCommon reviewers $longVstsGlobal" + } + 'work-items' = @{ + add = "$longVstsSubCommandCommon work-items $longVstsGlobal" + list = "$longVstsSubCommandCommon $longVstsGlobal" + remove = "$longVstsSubCommandCommon work-items $longVstsGlobal" + } +} + +$vstsParamValues = @{ + 'set-vote' = @{ + vote = 'approve approve-with-suggestions reject reset wait-for-author' + } + list = @{ + status = 'abandoned active all completed' + } + '**' = @{ + output = 'json jsonc table tsv' + } +} + +$azParamValues = @{ + update = @{ + status = 'abandoned active completed' + } + 'set-vote' = @{ + vote = 'approve approve-with-suggestions reject reset wait-for-author' + } + list = @{ + status = 'abandoned active all completed' + } + '**' = @{ + output = 'json jsonc table tsv' + } +} + + # Variable is used in GitTabExpansion.ps1 $gitParamValues = @{ blame = @{ diff --git a/src/GitTabExpansion.ps1 b/src/GitTabExpansion.ps1 index 0cd1dfd28..8eecc1a18 100644 --- a/src/GitTabExpansion.ps1 +++ b/src/GitTabExpansion.ps1 @@ -5,6 +5,8 @@ $Global:GitTabSettings = New-Object PSObject -Property @{ AllCommands = $false KnownAliases = @{ '!f() { exec vsts code pr "$@"; }; f' = 'vsts.pr' + '!f() { exec az.cmd repos pr "$@"; }; f' = 'az.pr' + '!f() { exec az.cmd repos "$@"; }; f' = 'az.repo' } } @@ -12,6 +14,8 @@ $subcommands = @{ bisect = "start bad good skip reset visualize replay log run" notes = 'add append copy edit get-ref list merge prune remove show' 'vsts.pr' = 'create update show list complete abandon reactivate reviewers work-items set-vote policies' + 'az.pr' = 'create update show list checkout reviewer work-item set-vote policy' + 'az.repo' = 'list show' reflog = "show delete expire" remote = " add rename remove set-head set-branches @@ -64,8 +68,29 @@ if ((($PSVersionTable.PSVersion.Major -eq 5) -or $IsWindows) -and ($script:GitVe $script:gitCommandsWithLongParams = $longGitParams.Keys -join '|' $script:gitCommandsWithShortParams = $shortGitParams.Keys -join '|' $script:gitCommandsWithParamValues = $gitParamValues.Keys -join '|' +$script:vstsAllCommands = $subCommands['vsts.pr'].Split(' ', [StringSplitOptions]::RemoveEmptyEntries) -join '|' $script:vstsCommandsWithShortParams = $shortVstsParams.Keys -join '|' $script:vstsCommandsWithLongParams = $longVstsParams.Keys -join '|' +$script:vstsCommandsWithParamValues = ( $vstsParamValues.Keys | Where-Object { $_ -ne '**' } ) -join '|' +$script:vstsSubCommandCommands = $vstsCommandsWithSubCommands.Keys -join '|' +$script:azAllCommands = $subCommands['az.pr'].Split(' ', [StringSplitOptions]::RemoveEmptyEntries) -join '|' +$script:azCommandsWithShortParams = $shortAzParams.Keys -join '|' +$script:azCommandsWithLongParams = $longAzParams.Keys -join '|' +$script:azCommandsWithParamValues = ( $azParamValues.Keys | Where-Object { $_ -ne '**' } ) -join '|' +$script:azSubCommandCommands = $azCommandsWithSubCommands.Keys -join '|' + +# constructs (?:(?Name) (?a|b|c))|(?:(?Name2) (?d|e|f)) +# only one group will match, so repeat of capture name is perfectly legal for our use-case +$script:azSubCommandsWithLongParams = ` + ($longAzSubCommandParams.Keys | ForEach-Object { "(?:(?$_) (?$( $longAzSubCommandParams[$_].Keys -join '|' )))" }) -join '|' +$script:azSubCommandsWithShortParams = ` + ($shortAzSubCommandParams.Keys | ForEach-Object { "(?:(?$_) (?$( $shortAzSubCommandParams[$_].Keys -join '|' )))" }) -join '|' + +$script:vstsSubCommandsWithLongParams = ` + ($longVstsSubCommandParams.Keys | ForEach-Object { "(?:(?$_) (?$( $longVstsSubCommandParams[$_].Keys -join '|' )))" }) -join '|' +$script:vstsSubCommandsWithShortParams = ` + ($shortVstsSubCommandParams.Keys | ForEach-Object { "(?:(?$_) (?$( $shortVstsSubCommandParams[$_].Keys -join '|' )))" }) -join '|' + try { if ($null -ne (git help -a 2>&1 | Select-String flow)) { @@ -190,6 +215,7 @@ function script:gitCheckoutFiles($GitStatus, $filter) { gitFiles $filter (@($GitStatus.Working.Unmerged) + @($GitStatus.Working.Modified) + @($GitStatus.Working.Deleted)) } + function script:gitDiffFiles($GitStatus, $filter, $staged) { if ($staged) { gitFiles $filter $GitStatus.Index.Modified @@ -248,11 +274,17 @@ function script:expandShortParams($hash, $cmd, $filter) { ForEach-Object { -join ("-", $_) } } -function script:expandParamValues($cmd, $param, $filter) { - $gitParamValues[$cmd][$param].Trim() -split ' ' | +function script:expandParamValues($hash, $cmd, $param, $filter, $full = $TRUE) { + $hash[$cmd][$param].Trim() -split ' ' | Where-Object { $_ -like "$filter*" } | Sort-Object | - ForEach-Object { -join ("--", $param, "=", $_) } + ForEach-Object { + if ($full) { + -join ("--", $param, "=", $_) + } else { + $_ + } + } } function Expand-GitCommand($Command) { @@ -394,6 +426,7 @@ function GitTabExpansionInternal($lastBlock, $GitStatus = $null) { gitMergeFiles $GitStatus $matches['files'] } + # Handles git checkout "^(?:checkout).* (?\S*)$" { & { @@ -417,7 +450,7 @@ function GitTabExpansionInternal($lastBlock, $GitStatus = $null) { # Handles git --= "^(?$gitCommandsWithParamValues).* --(?[^=]+)=(?\S*)$" { - expandParamValues $matches['cmd'] $matches['param'] $matches['value'] + expandParamValues $gitParamValues $matches['cmd'] $matches['param'] $matches['value'] } # Handles git -- @@ -430,21 +463,75 @@ function GitTabExpansionInternal($lastBlock, $GitStatus = $null) { expandShortParams $shortGitParams $matches['cmd'] $matches['shortparam'] } + # Handles the vsts/azure CLI commands + # Assumption is that the majority of commands will NOT invoke these CLI's. In order to reduce + # amount of matching we will do in general, first detect the az.pr / vsts.pr aliases + # and THEN perform secondary matches + "(?(?:az|vsts)\.pr)\s+(?.*)$" { + expandVstsAndAzureCli $matches['alias'] $matches['rest'] + } + + } +} + +function script:expandVstsAndAzureCli($alias, $rest) { + + # will be "az" or "vsts" + $cliType = $alias.Split('.')[0] + + switch -regex ($rest) { + # Handles git pr alias - "vsts\.pr\s+(?\S*)$" { - gitCmdOperations $subcommands 'vsts.pr' $matches['op'] + "^(?\S*)$" { + gitCmdOperations $subcommands $alias $matches['op'] + } + + # Handles all git pr aliases with expansion for --output/-o formats + # matches vstsAllCommands or azAllCommands + "^(?:$(Get-Variable ('{0}AllCommands' -f $cliType) -ValueOnly)).* (?:(--out(put)?(?=|\s+))|(-o\s+))(?\S*)$" { + expandParamValues (Get-Variable "$($cliType)ParamValues" -ValueOnly) '**' 'output' $matches['value'] -Full ($matches['eq'] -and $matches['eq'].Trim()) + } + + # Handles git pr --= + # matches vstsCommandsWithParamValues or azCommandsWithParamValues + "^(?$(Get-Variable ('{0}CommandsWithParamValues' -f $cliType) -ValueOnly)).* --(?!\*+)(?[^=]+)=(?\S*)$" { + expandParamValues (Get-Variable "$($cliType)ParamValues" -ValueOnly) $matches['cmd'] $matches['param'] $matches['value'] + } + + # add branch expansion for git PR target/source branch + "^(?:create|list)\s+.*?(?:--(?:target|source)-branch|-(?:t|s))\s+(?\S*)$" { + # should only return non-remote-qualified name of remote branches + gitRemoteUniqueBranches $matches['ref'] + } + + # handles git pr => git pr policy list + # matches vstsSubCommandCommands or azSubCommandCommands + "^(?$(Get-Variable ('{0}SubCommandCommands' -f $cliType) -ValueOnly))\s+(?\S*)$" { + gitCmdOperations (Get-Variable "$($cliType)CommandsWithSubCommands" -ValueOnly) $matches['subcmd'] $matches['op'] } # Handles git pr -- - "vsts\.pr\s+(?$vstsCommandsWithLongParams).*--(?\S*)$" - { - expandLongParams $longVstsParams $matches['cmd'] $matches['param'] + # matches vstsCommandsWithLongParams or azCommandsWithLongParams + "^(?$(Get-Variable ('{0}CommandsWithLongParams' -f $cliType) -ValueOnly)).* --(?!\*+)(?\S*)$" { + expandLongParams (Get-Variable "long$($cliType)Params" -ValueOnly) $matches['cmd'] $matches['param'] + } + + # Handles git pr -- => git pr policy list --debug + # matches vstsSubCommandsWithLongParams or azSubCommandsWithLongParams + "^(?:$(Get-Variable ('{0}SubCommandsWithLongParams' -f $cliType) -ValueOnly)).* --(?!\*+)(?\S*)$" { + expandLongParams (Get-Variable "long$($cliType)SubCommandParams" -ValueOnly)[$Matches['cmd']] $Matches['subcmd'] $matches['param'] } # Handles git pr - - "vsts\.pr\s+(?$vstsCommandsWithShortParams).*-(?\S*)$" - { - expandShortParams $shortVstsParams $matches['cmd'] $matches['shortparam'] + # matches vstsCommandsWithShortParams or azCommandsWithShortParams + "^(?$(Get-Variable ('{0}CommandsWithShortParams' -f $cliType) -ValueOnly)).* -(?!-)(?\S*)$" { + expandShortParams (Get-Variable "short$($cliType)Params" -ValueOnly) $matches['cmd'] $matches['shortparam'] + } + + # Handles git pr - => git pr policy list -d + # matches vstsSubCommandsWithShortParams or azSubCommandsWithShortParams + "^(?:$(Get-Variable ('{0}SubCommandsWithShortParams' -f $cliType) -ValueOnly)).* -(?!-)(?\S*)$" { + expandShortParams (Get-Variable "short$($cliType)SubCommandParams" -ValueOnly)[$Matches['cmd']] $Matches['subcmd'] $matches['shortparam'] } } } diff --git a/test/GitParamTabExpansionAz.Tests.ps1 b/test/GitParamTabExpansionAz.Tests.ps1 new file mode 100644 index 000000000..6d98e8bb1 --- /dev/null +++ b/test/GitParamTabExpansionAz.Tests.ps1 @@ -0,0 +1,151 @@ +. $PSScriptRoot\Shared.ps1 + +Describe 'ParamsTabExpansion Azure CLI Tests' { + + Context 'Push Parameters TabExpansion Tests' { + # Create a git alias for 'pr', as if we'd installed az-cli + BeforeEach { + [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssigments', '')] + $repoPath = NewGitTempRepo + + # Test with non-standard vsts pr alias name + &$gitbin config alias.test-az-pr "!f() { exec az.cmd repos pr \`"`$`@\`"; }; f" + } + AfterEach { + RemoveGitTempRepo $repoPath + } + + It 'Tab completes empty for git pr oops parameters values' { + $result = & $module GitTabExpansionInternal 'git test-az-pr oops --' + $result | Should BeNullOrEmpty + } + + It 'Tab completes empty for git pr oops short parameter values' { + $result = & $module GitTabExpansionInternal 'git test-az-pr oops -' + $result | Should BeNullOrEmpty + } + + It 'Tab completes empty for git pr update --**= ' { + $result = & $module GitTabExpansionInternal 'git test-az-pr update --**=' + $result | Should BeNullOrEmpty + } + + It 'Tab completes git pr create parameters values' { + $result = & $module GitTabExpansionInternal 'git test-az-pr create --' + $result -contains '--auto-complete' | Should Be $true + } + + It 'Tab completes git pr create auto-complete parameters values' { + $result = & $module GitTabExpansionInternal 'git test-az-pr create --auto-complete --' + $result -contains '--delete-source-branch' | Should Be $true + } + + It 'Tab completes git pr show all parameters values' { + $result = & $module GitTabExpansionInternal 'git test-az-pr show --' + $result -contains '--' | Should Be $false + $result -contains '--debug' | Should Be $true + $result -contains '--help' | Should Be $true + $result -contains '--output' | Should Be $true + $result -contains '--query' | Should Be $true + $result -contains '--verbose' | Should Be $true + $result -contains '--id' | Should Be $true + $result -contains '--detect' | Should Be $true + $result -contains '--open' | Should Be $true + $result -contains '--organization' | Should Be $true + $result -contains '--instance' | Should Be $false + } + + It 'Tab completes git pr create all short parameters' { + $result = & $module GitTabExpansionInternal 'git test-az-pr create -' + $result -contains '-d' | Should Be $true + $result -contains '-i' | Should Be $false + $result -contains '-p' | Should Be $true + $result -contains '-r' | Should Be $true + $result -contains '-s' | Should Be $true + $result -contains '-t' | Should Be $true + $result -contains '-h' | Should Be $true + $result -contains '-o' | Should Be $true + } + + It 'Tab completes git pr reviewer add all parameter values' { + $result = & $module GitTabExpansionInternal 'git test-az-pr reviewer add --' + $result -contains '--' | Should Be $false + $result -contains '--id' | Should Be $true + $result -contains '--detect' | Should Be $true + $result -contains '--instance' | Should Be $false + $result -contains '--reviewers' | Should Be $true + } + + It 'Tab completes git pr work-item list all short parameters' { + $result = & $module GitTabExpansionInternal 'git test-az-pr work-item list -' + $result -contains '-i' | Should Be $false + $result -contains '-h' | Should Be $true + $result -contains '-o' | Should Be $true + } + + It 'Tab completes git pr list --output types' { + $result = & $module GitTabExpansionInternal 'git test-az-pr list --output ' + $result -contains 'json' | Should Be $true + $result -contains 'jsonc' | Should Be $true + $result -contains 'table' | Should Be $true + $result -contains 'tsv' | Should Be $true + } + + It 'Tab completes git pr policy list -o types' { + $result = & $module GitTabExpansionInternal 'git test-az-pr policy list -o ' + $result -contains 'json' | Should Be $true + $result -contains 'jsonc' | Should Be $true + $result -contains 'table' | Should Be $true + $result -contains 'tsv' | Should Be $true + } + + It 'Tab completes git pr reviewers list --output= types' { + $result = & $module GitTabExpansionInternal 'git test-az-pr reviewer list --output=' + $result -contains '--output=' | Should Be $false + $result -contains '--output=json' | Should Be $true + $result -contains '--output=jsonc' | Should Be $true + $result -contains '--output=table' | Should Be $true + $result -contains '--output=tsv' | Should Be $true + } + + It 'Tab completes git pr update --status= types' { + $result = & $module GitTabExpansionInternal 'git test-az-pr update --status=' + $result -contains '--status=abandoned' | Should Be $true + $result -contains '--status=active' | Should Be $true + $result -contains '--status=completed' | Should Be $true + } + + # need to mock gitRemoteUniqueBranches + InModuleScope 'posh-git' { + + Mock gitRemoteUniqueBranches { return 'master' } -ParameterFilter { $filter -eq 'm' } + Mock gitRemoteUniqueBranches { return 'develop','master' } -ParameterFilter { $filter -eq '' } + + It 'Tab completes git pr create --target-branch partial branch names' { + $result = GitTabExpansionInternal 'git test-az-pr create --target-branch m' + $result -contains 'develop' | Should Be $false + $result -contains 'master' | Should Be $true + } + + It 'Tab completes git pr create -t branch names' { + $result = GitTabExpansionInternal 'git test-az-pr create -t ' + + $result -contains 'develop' | Should Be $true + $result -contains 'master' | Should Be $true + } + + It 'Tab completes git pr create -s branch names' { + $result = GitTabExpansionInternal 'git test-az-pr create -s m' + + $result -contains 'develop' | Should Be $false + $result -contains 'master' | Should Be $true + } + + It 'Tab completes git pr create --source-branch branch names' { + $result = GitTabExpansionInternal 'git test-az-pr create --source-branch ' + $result -contains 'develop' | Should Be $true + $result -contains 'master' | Should Be $true + } + } + } +} diff --git a/test/GitParamTabExpansionVsts.Tests.ps1 b/test/GitParamTabExpansionVsts.Tests.ps1 index d2e708723..68d3c265b 100644 --- a/test/GitParamTabExpansionVsts.Tests.ps1 +++ b/test/GitParamTabExpansionVsts.Tests.ps1 @@ -1,6 +1,7 @@ . $PSScriptRoot\Shared.ps1 Describe 'ParamsTabExpansion VSTS Tests' { + Context 'Push Parameters TabExpansion Tests' { # Create a git alias for 'pr', as if we'd installed vsts-cli BeforeEach { @@ -16,18 +17,24 @@ Describe 'ParamsTabExpansion VSTS Tests' { It 'Tab completes empty for git pr oops parameters values' { $result = & $module GitTabExpansionInternal 'git test-vsts-pr oops --' - $result | Should Be @() + $result | Should BeNullOrEmpty } It 'Tab completes empty for git pr oops short parameter values' { $result = & $module GitTabExpansionInternal 'git test-vsts-pr oops -' - $result | Should Be @() + $result | Should BeNullOrEmpty + } + + It 'Tab completes empty for git pr set-vote --**= ' { + $result = & $module GitTabExpansionInternal 'git test-vsts-pr set-vote --**=' + $result | Should BeNullOrEmpty } It 'Tab completes git pr create parameters values' { $result = & $module GitTabExpansionInternal 'git test-vsts-pr create --' $result -contains '--auto-complete' | Should Be $true } + It 'Tab completes git pr create auto-complete parameters values' { $result = & $module GitTabExpansionInternal 'git test-vsts-pr create --auto-complete --' $result -contains '--delete-source-branch' | Should Be $true @@ -41,17 +48,105 @@ Describe 'ParamsTabExpansion VSTS Tests' { $result -contains '--output' | Should Be $true $result -contains '--query' | Should Be $true $result -contains '--verbose' | Should Be $true + $result -contains '--id' | Should Be $true + $result -contains '--detect' | Should Be $true + $result -contains '--open' | Should Be $true + $result -contains '--organization' | Should Be $false + $result -contains '--instance' | Should Be $true } - It 'Tab completes git pr create all short push parameters' { + It 'Tab completes git pr create all short parameters' { $result = & $module GitTabExpansionInternal 'git test-vsts-pr create -' $result -contains '-d' | Should Be $true $result -contains '-i' | Should Be $true $result -contains '-p' | Should Be $true $result -contains '-r' | Should Be $true $result -contains '-s' | Should Be $true + $result -contains '-t' | Should Be $true + $result -contains '-h' | Should Be $true + $result -contains '-o' | Should Be $true + } + + It 'Tab completes git pr reviewers add all parameter values' { + $result = & $module GitTabExpansionInternal 'git test-vsts-pr reviewers add --' + $result -contains '--' | Should Be $false + $result -contains '--id' | Should Be $true + $result -contains '--detect' | Should Be $true + $result -contains '--instance' | Should Be $true + $result -contains '--reviewers' | Should Be $true + } + + It 'Tab completes git pr work-items list all short parameters' { + $result = & $module GitTabExpansionInternal 'git test-vsts-pr work-items list -' + $result -contains '-i' | Should Be $true $result -contains '-h' | Should Be $true $result -contains '-o' | Should Be $true } + + It 'Tab completes git pr list --output types' { + $result = & $module GitTabExpansionInternal 'git test-vsts-pr list --output ' + $result -contains 'json' | Should Be $true + $result -contains 'jsonc' | Should Be $true + $result -contains 'table' | Should Be $true + $result -contains 'tsv' | Should Be $true + } + + It 'Tab completes git pr policies list -o types' { + $result = & $module GitTabExpansionInternal 'git test-vsts-pr policies list -o ' + $result -contains 'json' | Should Be $true + $result -contains 'jsonc' | Should Be $true + $result -contains 'table' | Should Be $true + $result -contains 'tsv' | Should Be $true + } + + It 'Tab completes git pr reviewers list --output= types' { + $result = & $module GitTabExpansionInternal 'git test-vsts-pr reviewers list --output=' + $result -contains '--output=' | Should Be $false + $result -contains '--output=json' | Should Be $true + $result -contains '--output=jsonc' | Should Be $true + $result -contains '--output=table' | Should Be $true + $result -contains '--output=tsv' | Should Be $true + } + + It 'Tab completes git pr set-vote --vote= types' { + $result = & $module GitTabExpansionInternal 'git test-vsts-pr set-vote --vote=' + $result -contains '--vote=approve' | Should Be $true + $result -contains '--vote=approve-with-suggestions' | Should Be $true + $result -contains '--vote=reject' | Should Be $true + $result -contains '--vote=reset' | Should Be $true + $result -contains '--vote=wait-for-author' | Should Be $true + } + + # need to mock gitRemoteUniqueBranches + InModuleScope 'posh-git' { + + Mock gitRemoteUniqueBranches { return 'master' } -ParameterFilter { $filter -eq 'm' } + Mock gitRemoteUniqueBranches { return 'develop','master' } -ParameterFilter { $filter -eq '' } + + It 'Tab completes git pr create --target-branch partial branch names' { + $result = GitTabExpansionInternal 'git test-vsts-pr create --target-branch m' + + $result -contains 'develop' | Should Be $false + $result -contains 'master' | Should Be $true + } + + It 'Tab completes git pr create -t branch names' { + $result = GitTabExpansionInternal 'git test-vsts-pr create -t ' + $result -contains 'develop' | Should Be $true + $result -contains 'master' | Should Be $true + } + + It 'Tab completes git pr create -s branch names' { + $result = GitTabExpansionInternal 'git test-vsts-pr create -s m' + $result -contains 'develop' | Should Be $false + $result -contains 'master' | Should Be $true + } + + It 'Tab completes git pr create --source-branch branch names' { + $result = GitTabExpansionInternal 'git test-vsts-pr create --source-branch ' + $result -contains 'develop' | Should Be $true + $result -contains 'master' | Should Be $true + } + } } } diff --git a/test/TabExpansion.Tests.ps1 b/test/TabExpansion.Tests.ps1 index 32d387931..2379045f0 100644 --- a/test/TabExpansion.Tests.ps1 +++ b/test/TabExpansion.Tests.ps1 @@ -8,7 +8,7 @@ Describe 'TabExpansion Tests' { It 'Tab completes without subcommands' { $result = & $module GitTabExpansionInternal 'git whatever ' - $result | Should Be @() + $result | Should BeNullOrEmpty } It 'Tab completes bisect subcommands' { $result = & $module GitTabExpansionInternal 'git bisect ' @@ -203,6 +203,61 @@ Describe 'TabExpansion Tests' { It 'Tab completes pr options' { $result = & $module GitTabExpansionInternal 'git test-vsts-pr ' $result -contains 'abandon' | Should Be $true + $result -contains 'reactivate' | Should Be $true + $result -contains 'create' | Should Be $true + $result -contains 'list' | Should Be $true + $result -contains 'update' | Should Be $true + $result -contains 'show' | Should Be $true + $result -contains 'policies' | Should Be $true + $result -contains 'work-items' | Should Be $true + $result -contains 'reviewers' | Should Be $true + # Azure CLI variants + $result -contains 'checkout' | Should Be $false + $result -contains 'policy' | Should Be $false + $result -contains 'reviewer' | Should Be $false + $result -contains 'work-item' | Should Be $false + } + + It 'Tab completes pr policies all subcommands' { + $result = & $module GitTabExpansionInternal 'git test-vsts-pr policies ' + $result -contains 'list' | Should Be $true + $result -contains 'queue' | Should Be $true + } + } + + Context 'Azure CLI' { + BeforeEach { + [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssigments', '')] + $repoPath = NewGitTempRepo + + # Test with non-standard vsts pr alias name + &$gitbin config alias.test-az-pr "!f() { exec az.cmd repos pr \`"`$`@\`"; }; f" + } + AfterEach { + RemoveGitTempRepo $repoPath + } + It 'Tab completes pr options' { + $result = & $module GitTabExpansionInternal 'git test-az-pr ' + $result -contains 'create' | Should Be $true + $result -contains 'list' | Should Be $true + $result -contains 'checkout' | Should Be $true + $result -contains 'update' | Should Be $true + $result -contains 'show' | Should Be $true + $result -contains 'policy' | Should Be $true + $result -contains 'work-item' | Should Be $true + $result -contains 'reviewer' | Should Be $true + # VSTS CLI Variants + $result -contains 'abandon' | Should Be $false + $result -contains 'reactivate' | Should Be $false + $result -contains 'policies' | Should Be $false + $result -contains 'reviewers' | Should Be $false + $result -contains 'work-items' | Should Be $false + } + + It 'Tab completes pr policy all subcommands' { + $result = & $module GitTabExpansionInternal 'git test-az-pr policy ' + $result -contains 'list' | Should Be $true + $result -contains 'queue' | Should Be $true } }