mirror of
https://github.com/ethauvin/sdkman-for-fish.git
synced 2025-04-25 05:17:11 -07:00
Account for fuzzy completions.
Introduced in Fish 3.1 cf. https://github.com/fish-shell/fish-shell/issues/5467 Needed to make tests less strict. Instead of checking the exact list of matches, we require the expected ones and exclude some others.
This commit is contained in:
parent
0c15f199cd
commit
479fa1e541
4 changed files with 154 additions and 115 deletions
|
@ -88,14 +88,14 @@ complete -c sdk -f -n '__fish_sdkman_no_command' \
|
|||
-d 'Install new version'
|
||||
complete -c sdk -f -n '__fish_sdkman_using_command i install' \
|
||||
-a "(__fish_sdkman_candidates)"
|
||||
# TODO complete available versions --> issue #4
|
||||
complete -c sdk -f -n '__fish_sdkman_specifying_candidate i install' \
|
||||
# TODO complete available versions --> #4
|
||||
-a 'a.b.c' \
|
||||
-d "version list unavailable"
|
||||
complete -c sdk -f -n '__fish_sdkman_specifying_candidate i install' \
|
||||
-a 'x.y.z' \
|
||||
-d "Add your own; specify path!"
|
||||
# Implicit: complete files as fourth parameter
|
||||
-d "Specify path to install custom version."
|
||||
# Implicit: complete files as fourth parameter
|
||||
complete -c sdk -f -n '__fish_sdkman_command_has_enough_parameters 3 i install'
|
||||
# block
|
||||
|
||||
|
|
|
@ -14,166 +14,179 @@ Feature: Shell Completion
|
|||
Scenario Outline: Commands complete
|
||||
When the user enters "<cmd>" into the prompt
|
||||
Then completion should propose "<completions>"
|
||||
But completion should not propose <exclusions>
|
||||
Examples:
|
||||
| cmd | completions |
|
||||
| b | b, broadcast |
|
||||
| c | c, current |
|
||||
| d | d, default |
|
||||
| f | flush |
|
||||
| h | h, help |
|
||||
| i | i, install |
|
||||
| in | install |
|
||||
| l | list, ls |
|
||||
| o | offline |
|
||||
| r | rm |
|
||||
| s | selfupdate |
|
||||
| u | u, ug, uninstall, update, upgrade, use |
|
||||
| un | uninstall |
|
||||
| up | update, upgrade |
|
||||
| us | use |
|
||||
| v | v, version |
|
||||
# Currently uncovered; include to catch new upstream commands:
|
||||
| a | |
|
||||
| e | |
|
||||
| g | |
|
||||
| j | |
|
||||
| k | |
|
||||
| m | |
|
||||
| n | |
|
||||
| p | |
|
||||
| q | |
|
||||
| t | |
|
||||
| w | |
|
||||
| x | |
|
||||
| y | |
|
||||
| z | |
|
||||
| cmd | completions | exclusions |
|
||||
| b | b, broadcast | /^[^b]+$/ |
|
||||
| c | c, current | /^[^c]+$/ |
|
||||
| d | d, default | /^[^d]+$/ |
|
||||
| f | flush | /^[^f]+$/ |
|
||||
| h | h, help | /^[^h]+$/ |
|
||||
| i | i, install | /^[^i]+$/ |
|
||||
| in | install | |
|
||||
| l | list, ls | /^[^l]+$/ |
|
||||
| o | offline | /^[^o]+$/ |
|
||||
| r | rm | /^[^r]+$/ |
|
||||
| s | selfupdate | /^[^s]+$/ |
|
||||
| u | u, ug, uninstall, update, upgrade, use | /^[^u]+$/ |
|
||||
| un | uninstall | |
|
||||
| up | update, upgrade | |
|
||||
| us | use | |
|
||||
| v | v, version | /^[^v]+$/ |
|
||||
# Currently uncovered (except by fuzzy matches);
|
||||
# include negatives to prevent accidents:
|
||||
| a | | /^a/ |
|
||||
| e | | /^e/ |
|
||||
| g | | /^g/ |
|
||||
| j | | /^j/ |
|
||||
| k | | /^k/ |
|
||||
| m | | /^m/ |
|
||||
| n | | /^n/ |
|
||||
| p | | /^p/ |
|
||||
| q | | /^q/ |
|
||||
| t | | /^t/ |
|
||||
| w | | /^w/ |
|
||||
| x | | /^x/ |
|
||||
| y | | /^y/ |
|
||||
| z | | /^z/ |
|
||||
|
||||
Scenario Outline: Completion for 'install'
|
||||
When the user enters "install <cmd>" into the prompt
|
||||
Then completion should propose "<completions>"
|
||||
But completion should not propose <exclusions>
|
||||
Examples:
|
||||
| cmd | completions |
|
||||
| an | ant |
|
||||
| xyz | |
|
||||
| 1. | |
|
||||
| gra | gradle, grails |
|
||||
| grad | gradle |
|
||||
| gradk | |
|
||||
# | ant 1.10. | 1.10.0, 1.10.1 | # TODO: list installable versions --> issue #4
|
||||
| ant 1.10.2-mine /tm | /tmp/ |
|
||||
| 'ant 1.10.2-mine /tmp ' | |
|
||||
| cmd | completions | exclusions |
|
||||
| an | ant | gradle |
|
||||
| xyz | | /.*/ |
|
||||
| 1. | | /.*/ |
|
||||
| gra | gradle, grails | ant |
|
||||
| grad | gradle | ant, grails |
|
||||
| gradk | | /.*/ |
|
||||
# | ant 1.10. | 1.10.0, 1.10.1 | | # TODO: list installable versions --> issue #4
|
||||
| ant 1.10.2-mine /tm | /tmp/ | /bin |
|
||||
| 'ant 1.10.2-mine /tmp ' | | /.*/ |
|
||||
# NB: Excluding wildcard pattern /.*/ expresses "do not offer any completions"
|
||||
|
||||
Scenario Outline: Completion for 'uninstall'
|
||||
When the user enters "uninstall <cmd>" into the prompt
|
||||
Then completion should propose "<completions>"
|
||||
But completion should not propose <exclusions>
|
||||
Examples:
|
||||
| cmd | completions |
|
||||
| | ant, crash |
|
||||
| a | ant |
|
||||
| j | |
|
||||
| 1. | |
|
||||
| an | ant | # installed
|
||||
| gr | | # none installed
|
||||
| xyz | | # no such candidate
|
||||
| 'an ' | | # no such candidate installed
|
||||
| 'ant 1' | 1.10.1, 1.9.9 |
|
||||
| 'ant 1.10.' | 1.10.1 |
|
||||
| 'ant 2' | |
|
||||
| 'ant 1.10.1 ' | |
|
||||
| cmd | completions | exclusions |
|
||||
| | ant, crash | gradle |
|
||||
| a | ant | gradle |
|
||||
| j | | /.*/ |
|
||||
| 1. | | /.*/ |
|
||||
| an | ant | gradle, crash | # some installed
|
||||
| gr | | /.*/ | # none installed
|
||||
| xyz | | /.*/ | # no such candidate
|
||||
| 'an ' | | /.*/ | # no such candidate installed
|
||||
| 'ant 1' | 1.10.1, 1.9.9 | /^\w+$/ |
|
||||
| 'ant 1.10.' | 1.10.1 | 1.9.9 |
|
||||
| 'ant 2' | | /.*/ |
|
||||
| 'ant 1.10.1 ' | | /.*/ | # only one version at a time
|
||||
|
||||
Scenario Outline: Completion for 'list'
|
||||
When the user enters "list <cmd>" into the prompt
|
||||
Then completion should propose "<completions>"
|
||||
But completion should not propose <exclusions>
|
||||
Examples:
|
||||
| cmd | completions |
|
||||
| an | ant |
|
||||
| xyz | |
|
||||
| 1. | |
|
||||
| 'ant ' | |
|
||||
| cmd | completions | exclusions |
|
||||
| an | ant | crash |
|
||||
| xyz | | /.*/ |
|
||||
| 1. | | /.*/ |
|
||||
| 'ant ' | | /.*/ |
|
||||
|
||||
Scenario Outline: Completion for 'use'
|
||||
When the user enters "use <cmd>" into the prompt
|
||||
Then completion should propose "<completions>"
|
||||
But completion should not propose <exclusions>
|
||||
Examples:
|
||||
| cmd | completions |
|
||||
| | ant, crash |
|
||||
| an | ant |
|
||||
| j | |
|
||||
| 1. | |
|
||||
| 'ant ' | 1.10.1, 1.9.9 |
|
||||
| 'ant 1.10.1 ' | |
|
||||
| cmd | completions | exclusions |
|
||||
| | ant, crash | gradle |
|
||||
| an | ant | crash, gradle |
|
||||
| j | | /.*/ |
|
||||
| 1. | | /.*/ |
|
||||
| 'ant ' | 1.10.1, 1.9.9 | /^\w+$/ |
|
||||
| 'ant 1.10.1 ' | | /.*/ |
|
||||
|
||||
Scenario Outline: Completion for 'default'
|
||||
When the user enters "default <cmd>" into the prompt
|
||||
Then completion should propose "<completions>"
|
||||
But completion should not propose <exclusions>
|
||||
Examples:
|
||||
| cmd | completions |
|
||||
| | ant, crash |
|
||||
| an | ant |
|
||||
| j | |
|
||||
| 1. | |
|
||||
| 'ant ' | 1.10.1, 1.9.9 |
|
||||
| 'ant 1.10.1 ' | |
|
||||
| cmd | completions | exclusions |
|
||||
| | ant, crash | gradle |
|
||||
| an | ant | crash, gradle |
|
||||
| j | | /.*/ |
|
||||
| 1. | | /.*/ |
|
||||
| 'ant ' | 1.10.1, 1.9.9 | /^\w+$/ |
|
||||
| 'ant 1.10.1 ' | | /.*/ |
|
||||
|
||||
Scenario Outline: Completion for 'current'
|
||||
When the user enters "current <cmd>" into the prompt
|
||||
Then completion should propose "<completions>"
|
||||
But completion should not propose <exclusions>
|
||||
Examples:
|
||||
| cmd | completions |
|
||||
| an | ant | # --> installed version
|
||||
| ja | java | # --> not installed
|
||||
| xyz | |
|
||||
| 1. | |
|
||||
| 'ant ' | |
|
||||
| cmd | completions | exclusions |
|
||||
| an | ant | gradle | # --> installed version
|
||||
| gr | gradle | ant | # --> not installed
|
||||
| xyz | | /.*/ |
|
||||
| 1. | | /.*/ |
|
||||
| 'ant ' | | /.*/ |
|
||||
|
||||
Scenario Outline: Completion for 'upgrade'
|
||||
When the user enters "upgrade <cmd>" into the prompt
|
||||
Then completion should propose "<completions>"
|
||||
But completion should not propose <exclusions>
|
||||
Examples:
|
||||
| cmd | completions |
|
||||
| | ant, crash |
|
||||
| an | ant |
|
||||
| j | |
|
||||
| 1. | |
|
||||
| 'ant ' | |
|
||||
| cmd | completions | exclusions |
|
||||
| | ant, crash | gradle |
|
||||
| an | ant | crash, gradle |
|
||||
| j | | /.*/ |
|
||||
| 1. | | /.*/ |
|
||||
| 'ant ' | | /^\w+$/ |
|
||||
|
||||
Scenario Outline: Completion for 'offline'
|
||||
When the user enters "offline <cmd>" into the prompt
|
||||
Then completion should propose "<completions>"
|
||||
But completion should not propose <exclusions>
|
||||
Examples:
|
||||
| cmd | completions |
|
||||
| | disable, enable |
|
||||
| e | enable |
|
||||
| d | disable |
|
||||
| a | |
|
||||
| 'enable ' | |
|
||||
| cmd | completions | exclusions |
|
||||
| | disable, enable | /^(?!disable\|enable).*$/ | # NB: \| escaped to get it past Gherkin's parser
|
||||
| en | enable | /^(?!enable).*$/ |
|
||||
| di | disable | /^(?!disable).*$/ |
|
||||
| an | | /.*/ |
|
||||
| 'enable ' | | /.*/ |
|
||||
|
||||
Scenario Outline: Completion for 'selfupdate'
|
||||
When the user enters "selfupdate <cmd>" into the prompt
|
||||
Then completion should propose "<completions>"
|
||||
But completion should not propose <exclusions>
|
||||
Examples:
|
||||
| cmd | completions |
|
||||
| | force |
|
||||
| f | force |
|
||||
| a | |
|
||||
| 'force ' | |
|
||||
| cmd | completions | exclusions |
|
||||
| | force | /^(?!force).*$/ |
|
||||
| f | force | /^(?!force).*$/ |
|
||||
| a | | /.*/ |
|
||||
| 'force ' | | /.*/ |
|
||||
|
||||
Scenario Outline: Completion for 'flush'
|
||||
When the user enters "flush <cmd>" into the prompt
|
||||
Then completion should propose "<completions>"
|
||||
But completion should not propose <exclusions>
|
||||
Examples:
|
||||
| cmd | completions |
|
||||
| | archives, broadcast, temp |
|
||||
| b | broadcast |
|
||||
| a | archives |
|
||||
| t | temp |
|
||||
| x | |
|
||||
| 'temp ' | |
|
||||
| cmd | completions | exclusions |
|
||||
| | archives, broadcast, temp | /^(?!archives\|broadcast\|temp).*$/ |
|
||||
| b | broadcast | /^(?!broadcast).*$/ |
|
||||
| a | archives | /^(?!archives\|broadcast).*$/ |
|
||||
| t | temp | /^(?!temp\|broadcast).*$/ |
|
||||
| x | | /.*/ |
|
||||
| 'temp ' | | /.*/ |
|
||||
|
||||
|
||||
Scenario Outline: Completion for commands without parameters
|
||||
When the user enters "<cmd>" into the prompt
|
||||
Then completion should propose ""
|
||||
Then completion should not propose /.*/
|
||||
Examples:
|
||||
| cmd |
|
||||
| 'version ' |
|
||||
|
|
|
@ -7,12 +7,8 @@ module CompletionHelper
|
|||
completions = run_fish_command("complete -C\"sdk #{cmd}\"")
|
||||
|
||||
completions.split("\n") \
|
||||
.map { |line| line.split(/\s+/)[0].strip } \
|
||||
.sort \
|
||||
.uniq \
|
||||
.join(', ')
|
||||
.map { |line| line.split(/\s+/)[0].strip }
|
||||
# TODO: Why do we get duplicates in the Docker container?
|
||||
# --> remove uniq
|
||||
end
|
||||
end
|
||||
World CompletionHelper
|
||||
|
@ -21,6 +17,15 @@ When('the user enters {string} into the prompt') do |cmd|
|
|||
@response = complete(cmd.gsub(/["']/, ''))
|
||||
end
|
||||
|
||||
Then(/^completion should propose "(.*)"$/) do |completions|
|
||||
expect(@response).to eq(completions)
|
||||
Then('completion should propose {string}') do |completions|
|
||||
completions = completions.split(',').map(&:strip)
|
||||
expect(@response).to include(*completions)
|
||||
end
|
||||
|
||||
Then('completion should not propose {patterns}') do |exclusions_patterns|
|
||||
exclusions_patterns.each do |p|
|
||||
@response.each do |r|
|
||||
expect(r).not_to match(p)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
21
test/features/support/parameter_types.rb
Normal file
21
test/features/support/parameter_types.rb
Normal file
|
@ -0,0 +1,21 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
ParameterType(
|
||||
name: 'patterns',
|
||||
regexp: %r{([^\s]*|'[^']*'|/[^/]*/)(,\s*([^\s]*|'[^']*'|/[^/]*/))*},
|
||||
type: Array,
|
||||
transformer: lambda do |*patterns|
|
||||
patterns \
|
||||
.map(&:strip) \
|
||||
.map do |s|
|
||||
s = if %r{^/(.*)/$} =~ s
|
||||
Regexp.last_match(1)
|
||||
elsif %r{^'(.*)'$} =~ s
|
||||
"^#{Regexp.escape(Regexp.last_match(1))}$"
|
||||
else
|
||||
"^#{Regexp.escape(s)}$"
|
||||
end
|
||||
Regexp.compile(s)
|
||||
end
|
||||
end
|
||||
)
|
Loading…
Add table
Add a link
Reference in a new issue