From e9245710ddf1efa3cd909911c408536a66e9e70f Mon Sep 17 00:00:00 2001 From: Danny Ben Shitrit Date: Tue, 29 Nov 2022 17:28:45 +0000 Subject: [PATCH] - Improve test command output and allow multiple complines in one run --- .rspec | 1 + .rubocop.yml | 6 -- lib/completely/commands/base.rb | 15 +++- lib/completely/commands/generate.rb | 11 ++- lib/completely/commands/test.rb | 49 +++++++++---- spec/approvals/cli/generate/help | 23 +++--- spec/approvals/cli/init/help | 6 +- spec/approvals/cli/preview/help | 12 +-- .../approvals/cli/test/completely-tester-1.sh | 73 +++++++++++++++++++ .../approvals/cli/test/completely-tester-2.sh | 73 +++++++++++++++++++ spec/approvals/cli/test/comps-custom-config | 2 + spec/approvals/cli/test/comps-default | 2 + spec/approvals/cli/test/comps-default-keep | 4 +- spec/approvals/cli/test/comps-multi | 7 ++ spec/approvals/cli/test/comps-multi-keep | 9 +++ spec/approvals/cli/test/help | 23 +++--- spec/approvals/cli/test/usage | 2 +- spec/completely/commands/generate_spec.rb | 3 +- spec/completely/commands/test_spec.rb | 24 +++++- spec/completely/pattern_spec.rb | 2 +- 20 files changed, 283 insertions(+), 64 deletions(-) create mode 100644 spec/approvals/cli/test/completely-tester-1.sh create mode 100644 spec/approvals/cli/test/completely-tester-2.sh create mode 100644 spec/approvals/cli/test/comps-multi create mode 100644 spec/approvals/cli/test/comps-multi-keep diff --git a/.rspec b/.rspec index 75a19da..0692e82 100644 --- a/.rspec +++ b/.rspec @@ -1,3 +1,4 @@ +--require spec_helper --color --format documentation --fail-fast \ No newline at end of file diff --git a/.rubocop.yml b/.rubocop.yml index 94ae94d..99e19a4 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -18,9 +18,3 @@ AllCops: Naming/AccessorMethodName: Exclude: - 'lib/completely/tester.rb' - -# Allow long lines in specs and commands -Layout/LineLength: - Exclude: - - 'spec/**/*' - - 'lib/completely/commands/**/*' diff --git a/lib/completely/commands/base.rb b/lib/completely/commands/base.rb index 49d60ad..e51a22e 100644 --- a/lib/completely/commands/base.rb +++ b/lib/completely/commands/base.rb @@ -5,19 +5,26 @@ module Commands class Base < MisterBin::Command class << self def param_config_path - param 'CONFIG_PATH', "Path to the YAML configuration file [default: completely.yaml]\nCan also be set by an environment variable" + param 'CONFIG_PATH', <<~USAGE + Path to the YAML configuration file [default: completely.yaml]. + Can also be set by an environment variable. + USAGE end def option_function - option '-f --function NAME', 'Modify the name of the function in the generated script' + option '-f --function NAME', + 'Modify the name of the function in the generated script.' end def environment_config_path - environment 'COMPLETELY_CONFIG_PATH', 'Path to a completely configuration file [default: completely.yaml]' + environment 'COMPLETELY_CONFIG_PATH', + 'Path to a completely configuration file [default: completely.yaml].' end def environment_debug - environment 'COMPLETELY_DEBUG', 'It not empty, the generated script will include an additional debugging snippet that outputs the compline and current word to a text file when a completion is requested' + environment 'COMPLETELY_DEBUG', 'If not empty, the generated script will include ' \ + 'an additional debugging snippet that outputs the compline and current word to ' \ + 'a text file when a completion is requested.' end end diff --git a/lib/completely/commands/generate.rb b/lib/completely/commands/generate.rb index 42425de..fecba04 100644 --- a/lib/completely/commands/generate.rb +++ b/lib/completely/commands/generate.rb @@ -9,13 +9,18 @@ class Generate < Base usage 'completely generate (-h|--help)' option_function - option '-w --wrap NAME', 'Wrap the completion script inside a function that echos the script. This is useful if you wish to embed it directly in your script' + option '-w --wrap NAME', 'Wrap the completion script inside a function that echos the ' \ + 'script. This is useful if you wish to embed it directly in your script.' param_config_path - param 'OUTPUT_PATH', "Path to the output bash script. When not provided, the name of the input file will be used with a .bash extension\nCan also be set by an environment variable" + param 'OUTPUT_PATH', <<~USAGE + Path to the output bash script. + When not provided, the name of the input file will be used with a .bash extension. + Can also be set by an environment variable. + USAGE environment_config_path - environment 'COMPLETELY_OUTPUT_PATH', 'Path to the output bash script' + environment 'COMPLETELY_OUTPUT_PATH', 'Path to the output bash script.' environment_debug def run diff --git a/lib/completely/commands/test.rb b/lib/completely/commands/test.rb index ebdd006..3ebe92d 100644 --- a/lib/completely/commands/test.rb +++ b/lib/completely/commands/test.rb @@ -5,27 +5,30 @@ module Commands class Test < Base summary 'Test completions' - help 'This command can be used to test that your completions script responds with the right completions. It works by reading your completely.yaml file, generating a completions script, and generating a temporary testing script.' + help 'This command can be used to test that your completions script responds with ' \ + 'the right completions. It works by reading your completely.yaml file, generating ' \ + 'a completions script, and generating a temporary testing script.' - usage 'completely test [--keep] COMPLINE' + usage 'completely test [--keep] COMPLINE...' usage 'completely test (-h|--help)' - option '-k --keep', 'Keep the temporary testing script in the current directory' + option '-k --keep', 'Keep the temporary testing script in the current directory.' - param 'COMPLINE', 'The command to test completions for. This will be handled as if a TAB was pressed immediately at the end of it, so the last word is considered the active cursor. If you wish to complete for the next word instead, end your command with a space.' + param 'COMPLINE', 'One or more commands to test completions for. ' \ + 'This will be handled as if a TAB was pressed immediately at the end of it, ' \ + 'so the last word is considered the active cursor. ' \ + 'If you wish to complete for the next word instead, end your command with a space.' environment_config_path environment_debug - example 'completely test "mygit pu"' - example 'completely test "mygit pull "' + example 'completely test "mygit "' + example 'completely test --keep "mygit status "' + example 'completely test "mygit status --" "mygit init "' def run - puts tester.test(compline).join "\n" - - if args['--keep'] - File.write 'completely-tester.sh', tester_script - puts 'saved completely-tester.sh' + complines.each_with_index do |compline, i| + show_compline compline, filename: "completely-tester-#{i + 1}.sh" end syntax_warning unless completions.valid? @@ -33,8 +36,24 @@ def run private - def compline - args['COMPLINE'] + def show_compline(compline, filename: nil) + filename ||= 'completely-tester.sh' + say "!txtblu!$ !txtgrn!#{compline}!txtrst!" + puts tester.test(compline).join "\n" + puts + + return unless keep + + File.write filename, tester_script(compline) + say "Saved !txtpur!#{filename}" + end + + def complines + @complines ||= args['COMPLINE'] + end + + def keep + @keep ||= args['--keep'] end def completions @@ -45,8 +64,8 @@ def tester @tester ||= completions.tester end - def tester_script - @tester_script ||= tester.tester_script compline + def tester_script(compline) + tester.tester_script compline end end end diff --git a/spec/approvals/cli/generate/help b/spec/approvals/cli/generate/help index 9a3555d..e262f90 100644 --- a/spec/approvals/cli/generate/help +++ b/spec/approvals/cli/generate/help @@ -6,33 +6,34 @@ Usage: Options: -f --function NAME - Modify the name of the function in the generated script + Modify the name of the function in the generated script. -w --wrap NAME Wrap the completion script inside a function that echos the script. This is - useful if you wish to embed it directly in your script + useful if you wish to embed it directly in your script. -h --help Show this help Parameters: CONFIG_PATH - Path to the YAML configuration file [default: completely.yaml] - Can also be set by an environment variable + Path to the YAML configuration file [default: completely.yaml]. + Can also be set by an environment variable. OUTPUT_PATH - Path to the output bash script. When not provided, the name of the input - file will be used with a .bash extension - Can also be set by an environment variable + Path to the output bash script. + When not provided, the name of the input file will be used with a .bash + extension. + Can also be set by an environment variable. Environment Variables: COMPLETELY_CONFIG_PATH - Path to a completely configuration file [default: completely.yaml] + Path to a completely configuration file [default: completely.yaml]. COMPLETELY_OUTPUT_PATH - Path to the output bash script + Path to the output bash script. COMPLETELY_DEBUG - It not empty, the generated script will include an additional debugging + If not empty, the generated script will include an additional debugging snippet that outputs the compline and current word to a text file when a - completion is requested + completion is requested. diff --git a/spec/approvals/cli/init/help b/spec/approvals/cli/init/help index 5665f0a..208809f 100644 --- a/spec/approvals/cli/init/help +++ b/spec/approvals/cli/init/help @@ -10,9 +10,9 @@ Options: Parameters: CONFIG_PATH - Path to the YAML configuration file [default: completely.yaml] - Can also be set by an environment variable + Path to the YAML configuration file [default: completely.yaml]. + Can also be set by an environment variable. Environment Variables: COMPLETELY_CONFIG_PATH - Path to a completely configuration file [default: completely.yaml] + Path to a completely configuration file [default: completely.yaml]. diff --git a/spec/approvals/cli/preview/help b/spec/approvals/cli/preview/help index b7f3024..6546285 100644 --- a/spec/approvals/cli/preview/help +++ b/spec/approvals/cli/preview/help @@ -6,21 +6,21 @@ Usage: Options: -f --function NAME - Modify the name of the function in the generated script + Modify the name of the function in the generated script. -h --help Show this help Parameters: CONFIG_PATH - Path to the YAML configuration file [default: completely.yaml] - Can also be set by an environment variable + Path to the YAML configuration file [default: completely.yaml]. + Can also be set by an environment variable. Environment Variables: COMPLETELY_CONFIG_PATH - Path to a completely configuration file [default: completely.yaml] + Path to a completely configuration file [default: completely.yaml]. COMPLETELY_DEBUG - It not empty, the generated script will include an additional debugging + If not empty, the generated script will include an additional debugging snippet that outputs the compline and current word to a text file when a - completion is requested + completion is requested. diff --git a/spec/approvals/cli/test/completely-tester-1.sh b/spec/approvals/cli/test/completely-tester-1.sh new file mode 100644 index 0000000..d3f517b --- /dev/null +++ b/spec/approvals/cli/test/completely-tester-1.sh @@ -0,0 +1,73 @@ +#!/usr/bin/env bash +if [[ -n $ZSH_VERSION ]]; then + autoload -U +X bashcompinit && bashcompinit + autoload -U +X compinit && compinit +fi + +# === COMPLETION SCRIPT START === + +# mygit completion -*- shell-script -*- + +# This bash completions script was generated by +# completely (https://github.com/dannyben/completely) +# Modifying it manually is not recommended + +_mygit_completions_filter() { + local words="$1" + local cur=${COMP_WORDS[COMP_CWORD]} + local result=() + + if [[ "${cur:0:1}" == "-" ]]; then + echo "$words" + + else + for word in $words; do + [[ "${word:0:1}" != "-" ]] && result+=("$word") + done + + echo "${result[*]}" + + fi +} + +_mygit_completions() { + local cur=${COMP_WORDS[COMP_CWORD]} + local compwords=("${COMP_WORDS[@]:1:$COMP_CWORD-1}") + local compline="${compwords[*]}" + + case "$compline" in + 'status'*) + while read -r; do COMPREPLY+=( "$REPLY" ); done < <( compgen -W "$(_mygit_completions_filter "--help --verbose --branch $(git branch 2> /dev/null)")" -- "$cur" ) + ;; + + 'commit'*) + while read -r; do COMPREPLY+=( "$REPLY" ); done < <( compgen -A file -W "$(_mygit_completions_filter "--help --message --all -a --quiet -q")" -- "$cur" ) + ;; + + 'init'*) + while read -r; do COMPREPLY+=( "$REPLY" ); done < <( compgen -A directory -W "$(_mygit_completions_filter "--bare")" -- "$cur" ) + ;; + + *) + while read -r; do COMPREPLY+=( "$REPLY" ); done < <( compgen -W "$(_mygit_completions_filter "--help --version status init commit")" -- "$cur" ) + ;; + + esac +} && +complete -F _mygit_completions mygit + +# ex: filetype=sh + + +# === COMPLETION SCRIPT END === + +COMP_WORDS=( mygit -- ) +COMP_LINE="mygit --" +COMP_POINT=${#COMP_LINE} +COMP_CWORD=1 + +_mygit_completions +for suggestion in "${COMPREPLY[@]}"; do + echo "$suggestion" +done + diff --git a/spec/approvals/cli/test/completely-tester-2.sh b/spec/approvals/cli/test/completely-tester-2.sh new file mode 100644 index 0000000..9af1f4c --- /dev/null +++ b/spec/approvals/cli/test/completely-tester-2.sh @@ -0,0 +1,73 @@ +#!/usr/bin/env bash +if [[ -n $ZSH_VERSION ]]; then + autoload -U +X bashcompinit && bashcompinit + autoload -U +X compinit && compinit +fi + +# === COMPLETION SCRIPT START === + +# mygit completion -*- shell-script -*- + +# This bash completions script was generated by +# completely (https://github.com/dannyben/completely) +# Modifying it manually is not recommended + +_mygit_completions_filter() { + local words="$1" + local cur=${COMP_WORDS[COMP_CWORD]} + local result=() + + if [[ "${cur:0:1}" == "-" ]]; then + echo "$words" + + else + for word in $words; do + [[ "${word:0:1}" != "-" ]] && result+=("$word") + done + + echo "${result[*]}" + + fi +} + +_mygit_completions() { + local cur=${COMP_WORDS[COMP_CWORD]} + local compwords=("${COMP_WORDS[@]:1:$COMP_CWORD-1}") + local compline="${compwords[*]}" + + case "$compline" in + 'status'*) + while read -r; do COMPREPLY+=( "$REPLY" ); done < <( compgen -W "$(_mygit_completions_filter "--help --verbose --branch $(git branch 2> /dev/null)")" -- "$cur" ) + ;; + + 'commit'*) + while read -r; do COMPREPLY+=( "$REPLY" ); done < <( compgen -A file -W "$(_mygit_completions_filter "--help --message --all -a --quiet -q")" -- "$cur" ) + ;; + + 'init'*) + while read -r; do COMPREPLY+=( "$REPLY" ); done < <( compgen -A directory -W "$(_mygit_completions_filter "--bare")" -- "$cur" ) + ;; + + *) + while read -r; do COMPREPLY+=( "$REPLY" ); done < <( compgen -W "$(_mygit_completions_filter "--help --version status init commit")" -- "$cur" ) + ;; + + esac +} && +complete -F _mygit_completions mygit + +# ex: filetype=sh + + +# === COMPLETION SCRIPT END === + +COMP_WORDS=( mygit st ) +COMP_LINE="mygit st" +COMP_POINT=${#COMP_LINE} +COMP_CWORD=1 + +_mygit_completions +for suggestion in "${COMPREPLY[@]}"; do + echo "$suggestion" +done + diff --git a/spec/approvals/cli/test/comps-custom-config b/spec/approvals/cli/test/comps-custom-config index f22b05f..c0b15c8 100644 --- a/spec/approvals/cli/test/comps-custom-config +++ b/spec/approvals/cli/test/comps-custom-config @@ -1,2 +1,4 @@ +$ play co command conquer + diff --git a/spec/approvals/cli/test/comps-default b/spec/approvals/cli/test/comps-default index c5738cd..7e64e33 100644 --- a/spec/approvals/cli/test/comps-default +++ b/spec/approvals/cli/test/comps-default @@ -1,2 +1,4 @@ +$ mygit -- --help --version + diff --git a/spec/approvals/cli/test/comps-default-keep b/spec/approvals/cli/test/comps-default-keep index c7233b8..ab9e915 100644 --- a/spec/approvals/cli/test/comps-default-keep +++ b/spec/approvals/cli/test/comps-default-keep @@ -1,4 +1,6 @@ +$ mygit status -- --help --verbose --branch -saved completely-tester.sh + +Saved completely-tester-1.sh diff --git a/spec/approvals/cli/test/comps-multi b/spec/approvals/cli/test/comps-multi new file mode 100644 index 0000000..fd6da49 --- /dev/null +++ b/spec/approvals/cli/test/comps-multi @@ -0,0 +1,7 @@ +$ mygit -- +--help +--version + +$ mygit s +status + diff --git a/spec/approvals/cli/test/comps-multi-keep b/spec/approvals/cli/test/comps-multi-keep new file mode 100644 index 0000000..47d6a2b --- /dev/null +++ b/spec/approvals/cli/test/comps-multi-keep @@ -0,0 +1,9 @@ +$ mygit -- +--help +--version + +Saved completely-tester-1.sh +$ mygit st +status + +Saved completely-tester-2.sh diff --git a/spec/approvals/cli/test/help b/spec/approvals/cli/test/help index c2eb408..8918a91 100644 --- a/spec/approvals/cli/test/help +++ b/spec/approvals/cli/test/help @@ -5,32 +5,33 @@ right completions. It works by reading your completely.yaml file, generating a completions script, and generating a temporary testing script. Usage: - completely test [--keep] COMPLINE + completely test [--keep] COMPLINE... completely test (-h|--help) Options: -k --keep - Keep the temporary testing script in the current directory + Keep the temporary testing script in the current directory. -h --help Show this help Parameters: COMPLINE - The command to test completions for. This will be handled as if a TAB was - pressed immediately at the end of it, so the last word is considered the - active cursor. If you wish to complete for the next word instead, end your - command with a space. + One or more commands to test completions for. This will be handled as if a + TAB was pressed immediately at the end of it, so the last word is considered + the active cursor. If you wish to complete for the next word instead, end + your command with a space. Environment Variables: COMPLETELY_CONFIG_PATH - Path to a completely configuration file [default: completely.yaml] + Path to a completely configuration file [default: completely.yaml]. COMPLETELY_DEBUG - It not empty, the generated script will include an additional debugging + If not empty, the generated script will include an additional debugging snippet that outputs the compline and current word to a text file when a - completion is requested + completion is requested. Examples: - completely test "mygit pu" - completely test "mygit pull " + completely test "mygit " + completely test --keep "mygit status " + completely test "mygit status --" "mygit init " diff --git a/spec/approvals/cli/test/usage b/spec/approvals/cli/test/usage index f6ae669..1ff5071 100644 --- a/spec/approvals/cli/test/usage +++ b/spec/approvals/cli/test/usage @@ -1,3 +1,3 @@ Usage: - completely test [--keep] COMPLINE + completely test [--keep] COMPLINE... completely test (-h|--help) diff --git a/spec/completely/commands/generate_spec.rb b/spec/completely/commands/generate_spec.rb index 09f04e8..de67ea9 100644 --- a/spec/completely/commands/generate_spec.rb +++ b/spec/completely/commands/generate_spec.rb @@ -72,7 +72,8 @@ before { reset_tmp_dir } it 'generates the bash script to the specified path' do - expect { subject.execute %w[generate completely.yaml spec/tmp/out.bash] }.to output_approval('cli/generate/custom-out-path') + expect { subject.execute %w[generate completely.yaml spec/tmp/out.bash] } + .to output_approval('cli/generate/custom-out-path') expect(File.read 'spec/tmp/out.bash').to match_approval('cli/generated-script') end end diff --git a/spec/completely/commands/test_spec.rb b/spec/completely/commands/test_spec.rb index 87f82a0..6a96509 100644 --- a/spec/completely/commands/test_spec.rb +++ b/spec/completely/commands/test_spec.rb @@ -34,7 +34,7 @@ before { system "rm -f #{filename}" } after { system "rm -f #{filename}" } - let(:filename) { 'completely-tester.sh' } + let(:filename) { 'completely-tester-1.sh' } it 'copies the test script to the current directory' do expect { subject.execute ['test', '--keep', 'mygit status --'] } @@ -44,6 +44,28 @@ end end + context 'with COMPLINE COMPLINE' do + it 'prints multiple completions' do + expect { subject.execute ['test', 'mygit --', 'mygit s'] } + .to output_approval('cli/test/comps-multi') + end + end + + context 'with --keep COMPLINE COMPLINE' do + before { filenames.each { |filename| system "rm -f #{filename}" } } + after { filenames.each { |filename| system "rm -f #{filename}" } } + + let(:filenames) { ['completely-tester-1.sh', 'completely-tester-2.sh'] } + + it 'copies the test scripts to the current directory' do + expect { subject.execute ['test', '--keep', 'mygit --', 'mygit st'] } + .to output_approval('cli/test/comps-multi-keep') + + expect(File.read filenames[0]).to match_approval('cli/test/completely-tester-1.sh') + expect(File.read filenames[1]).to match_approval('cli/test/completely-tester-2.sh') + end + end + context 'when COMPLETELY_CONFIG_PATH is set' do before do reset_tmp_dir diff --git a/spec/completely/pattern_spec.rb b/spec/completely/pattern_spec.rb index 5bc3a6c..7cf0c32 100644 --- a/spec/completely/pattern_spec.rb +++ b/spec/completely/pattern_spec.rb @@ -77,7 +77,7 @@ context 'when the pattern includes a wildcard' do let(:text) { 'git checkout*--branch' } - it 'returns the quoted pattern (excluding command name) with an unquoted wildcard and without a wildcard suffix' do + it 'returns the quoted pattern (excluding command name) with an unquoted wildcard, without a wildcard suffix' do expect(subject.case_string).to eq "'checkout'*'--branch'" end end