| @ -1,6 +0,0 @@ | |||
| [submodule "vendor/shunit2"] | |||
| path = vendor/shunit2 | |||
| url = https://github.com/kward/shunit2 | |||
| [submodule "vendor/stub.sh"] | |||
| path = vendor/stub.sh | |||
| url = https://github.com/ericfreese/stub.sh | |||
| @ -1,2 +1,3 @@ | |||
| --color | |||
| --require spec_helper | |||
| --format documentation | |||
| @ -0,0 +1,30 @@ | |||
| # Rails: | |||
| # Enabled: true | |||
| AllCops: | |||
| TargetRubyVersion: 2.3 | |||
| Include: | |||
| - '**/Rakefile' | |||
| - '**/config.ru' | |||
| - '**/Gemfile' | |||
| Metrics/LineLength: | |||
| Max: 120 | |||
| Style/Documentation: | |||
| Enabled: false | |||
| Style/DotPosition: | |||
| EnforcedStyle: trailing | |||
| Style/FrozenStringLiteralComment: | |||
| Enabled: false | |||
| Style/Lambda: | |||
| Enabled: false | |||
| Style/MultilineMethodCallIndentation: | |||
| EnforcedStyle: indented | |||
| Style/TrailingUnderscoreVariable: | |||
| Enabled: false | |||
| @ -1,54 +0,0 @@ | |||
| #!/usr/bin/env zsh | |||
| DIR="${0:a:h}" | |||
| ROOT_DIR="$DIR/.." | |||
| TEST_DIR="$ROOT_DIR/test" | |||
| header() { | |||
| local message="$1" | |||
| cat <<-EOF | |||
| #====================================================================# | |||
| # $message | |||
| #====================================================================# | |||
| EOF | |||
| } | |||
| # ZSH binary to use | |||
| local zsh_bin="zsh" | |||
| while getopts ":z:" opt; do | |||
| case $opt in | |||
| z) | |||
| zsh_bin="$OPTARG" | |||
| ;; | |||
| \?) | |||
| echo "Invalid option: -$OPTARG" >&2 | |||
| exit 1 | |||
| ;; | |||
| :) | |||
| echo "Option -$OPTARG requires an argument" >&2 | |||
| exit 1 | |||
| ;; | |||
| esac | |||
| done | |||
| shift $((OPTIND -1)) | |||
| # Test suites to run | |||
| local -a tests | |||
| if [ $#@ -gt 0 ]; then | |||
| tests=($@) | |||
| else | |||
| tests=($TEST_DIR/**/*_test.zsh) | |||
| fi | |||
| local -i retval=0 | |||
| for suite in $tests; do | |||
| header "${suite#"$ROOT_DIR/"}" | |||
| "$zsh_bin" -f "$suite" || retval=$? | |||
| done | |||
| exit $retval | |||
| @ -0,0 +1,11 @@ | |||
| describe 'a running zpty command' do | |||
| it 'is not affected by running zsh-autosuggestions' do | |||
| session.run_command('zmodload zsh/zpty') | |||
| session.run_command('zpty -b kitty cat') | |||
| session.run_command('zpty -w kitty cat') | |||
| sleep 1 | |||
| session.run_command('zpty -r kitty') | |||
| wait_for(session.content).to end_with("\ncat") | |||
| end | |||
| end | |||
| @ -0,0 +1,13 @@ | |||
| describe 'a multi-line suggestion' do | |||
| it 'should be displayed on multiple lines' do | |||
| with_history(-> { | |||
| session.send_string('echo "') | |||
| session.send_keys('enter') | |||
| session.send_string('"') | |||
| session.send_keys('enter') | |||
| }) do | |||
| session.send_keys('e') | |||
| wait_for { session.content }.to eq("echo \"\n\"") | |||
| end | |||
| end | |||
| end | |||
| @ -0,0 +1,15 @@ | |||
| describe 'the zpty for async suggestions' do | |||
| it 'is created with the default name' do | |||
| session.run_command('zpty -t zsh_autosuggest_pty &>/dev/null; echo $?') | |||
| wait_for { session.content }.to end_with("\n0") | |||
| end | |||
| context 'when ZSH_AUTOSUGGEST_ASYNC_PTY_NAME is set' do | |||
| let(:options) { ['ZSH_AUTOSUGGEST_ASYNC_PTY_NAME=foo_pty'] } | |||
| it 'is created with the specified name' do | |||
| session.run_command('zpty -t foo_pty &>/dev/null; echo $?') | |||
| wait_for { session.content }.to end_with("\n0") | |||
| end | |||
| end | |||
| end | |||
| @ -0,0 +1,30 @@ | |||
| describe 'a suggestion' do | |||
| let(:term_opts) { { width: 200 } } | |||
| let(:long_command) { "echo #{'a' * 100}" } | |||
| around do |example| | |||
| with_history(long_command) { example.run } | |||
| end | |||
| it 'is provided for any buffer length' do | |||
| session.send_string(long_command[0...-1]) | |||
| wait_for { session.content }.to eq(long_command) | |||
| end | |||
| context 'when ZSH_AUTOSUGGEST_BUFFER_MAX_SIZE is specified' do | |||
| let(:buffer_max_size) { 10 } | |||
| let(:options) { ["ZSH_AUTOSUGGEST_BUFFER_MAX_SIZE=#{buffer_max_size}"] } | |||
| it 'is provided when the buffer is shorter than the specified length' do | |||
| session.send_string(long_command[0...(buffer_max_size - 1)]) | |||
| wait_for { session.content }.to eq(long_command) | |||
| end | |||
| it 'is provided when the buffer is equal to the specified length' do | |||
| session.send_string(long_command[0...(buffer_max_size)]) | |||
| wait_for { session.content }.to eq(long_command) | |||
| end | |||
| it 'is not provided when the buffer is longer than the specified length' | |||
| end | |||
| end | |||
| @ -0,0 +1,7 @@ | |||
| describe 'a displayed suggestion' do | |||
| it 'is shown in the default style' | |||
| describe 'when ZSH_AUTOSUGGEST_HIGHLIGHT_STYLE is set to a zle_highlight string' do | |||
| it 'is shown in the specified style' | |||
| end | |||
| end | |||
| @ -0,0 +1,7 @@ | |||
| describe 'an original zle widget' do | |||
| context 'is accessible with the default prefix' | |||
| context 'when ZSH_AUTOSUGGEST_ORIGINAL_WIDGET_PREFIX is set' do | |||
| it 'is accessible with the specified prefix' | |||
| end | |||
| end | |||
| @ -0,0 +1,20 @@ | |||
| describe 'a suggestion for a given prefix' do | |||
| let(:options) { ['_zsh_autosuggest_strategy_default() { suggestion="echo foo" }'] } | |||
| it 'is determined by calling the default strategy function' do | |||
| session.send_string('e') | |||
| wait_for { session.content }.to eq('echo foo') | |||
| end | |||
| context 'when ZSH_AUTOSUGGEST_STRATEGY is set' do | |||
| let(:options) { [ | |||
| '_zsh_autosuggest_strategy_custom() { suggestion="echo foo" }', | |||
| 'ZSH_AUTOSUGGEST_STRATEGY=custom' | |||
| ] } | |||
| it 'is determined by calling the specified strategy function' do | |||
| session.send_string('e') | |||
| wait_for { session.content }.to eq('echo foo') | |||
| end | |||
| end | |||
| end | |||
| @ -0,0 +1,7 @@ | |||
| describe 'suggestion fetching' do | |||
| it 'is performed asynchronously' | |||
| context 'when ZSH_AUTOSUGGEST_USE_ASYNC is unset' do | |||
| it 'is performed synchronously' | |||
| end | |||
| end | |||
| @ -0,0 +1,72 @@ | |||
| describe 'a zle widget' do | |||
| let(:before_sourcing) { -> { session.run_command('my-widget() {}; zle -N my-widget; bindkey ^B my-widget') } } | |||
| context 'when added to ZSH_AUTOSUGGEST_ACCEPT_WIDGETS' do | |||
| let(:options) { ['ZSH_AUTOSUGGEST_ACCEPT_WIDGETS=(my-widget)'] } | |||
| it 'accepts the suggestion when invoked' do | |||
| with_history('echo hello') do | |||
| session.send_string('e') | |||
| wait_for { session.content }.to eq('echo hello') | |||
| session.send_keys('C-b') | |||
| wait_for { session.content(esc_seqs: true) }.to eq('echo hello') | |||
| end | |||
| end | |||
| end | |||
| context 'when added to ZSH_AUTOSUGGEST_CLEAR_WIDGETS' do | |||
| let(:options) { ['ZSH_AUTOSUGGEST_CLEAR_WIDGETS=(my-widget)'] } | |||
| it 'clears the suggestion when invoked' do | |||
| with_history('echo hello') do | |||
| session.send_string('e') | |||
| wait_for { session.content }.to eq('echo hello') | |||
| session.send_keys('C-b') | |||
| wait_for { session.content }.to eq('e') | |||
| end | |||
| end | |||
| end | |||
| context 'when added to ZSH_AUTOSUGGEST_EXECUTE_WIDGETS' do | |||
| let(:options) { ['ZSH_AUTOSUGGEST_EXECUTE_WIDGETS=(my-widget)'] } | |||
| it 'executes the suggestion when invoked' do | |||
| with_history('echo hello') do | |||
| session.send_string('e') | |||
| wait_for { session.content }.to eq('echo hello') | |||
| session.send_keys('C-b') | |||
| wait_for { session.content }.to end_with("\nhello") | |||
| end | |||
| end | |||
| end | |||
| end | |||
| describe 'a zle widget that moves the cursor forward' do | |||
| let(:before_sourcing) { -> { session.run_command('my-widget() { zle forward-char }; zle -N my-widget; bindkey ^B my-widget') } } | |||
| context 'when added to ZSH_AUTOSUGGEST_PARTIAL_ACCEPT_WIDGETS' do | |||
| let(:options) { ['ZSH_AUTOSUGGEST_PARTIAL_ACCEPT_WIDGETS=(my-widget)'] } | |||
| it 'accepts the suggestion as far as the cursor is moved when invoked' do | |||
| with_history('echo hello') do | |||
| session.send_string('e') | |||
| wait_for { session.content }.to start_with('echo hello') | |||
| session.send_keys('C-b') | |||
| wait_for { session.content(esc_seqs: true) }.to match(/\Aec\e\[[0-9]+mho hello/) | |||
| end | |||
| end | |||
| end | |||
| end | |||
| describe 'a builtin zle widget' do | |||
| let(:widget) { 'beep' } | |||
| context 'when added to ZSH_AUTOSUGGEST_IGNORE_WIDGETS' do | |||
| let(:options) { ["ZSH_AUTOSUGGEST_IGNORE_WIDGETS=(#{widget})"] } | |||
| it 'should not be wrapped with an autosuggest widget' do | |||
| session.run_command("echo $widgets[#{widget}]") | |||
| wait_for { session.content }.to end_with("\nbuiltin") | |||
| end | |||
| end | |||
| end | |||
| @ -0,0 +1,55 @@ | |||
| describe 'a special character in the buffer' do | |||
| it 'should be treated like any other character' do | |||
| with_history('echo "hello*"', 'echo "hello."') do | |||
| session.send_string('echo "hello*') | |||
| wait_for { session.content }.to eq('echo "hello*"') | |||
| end | |||
| with_history('echo "hello?"', 'echo "hello."') do | |||
| session.send_string('echo "hello?') | |||
| wait_for { session.content }.to eq('echo "hello?"') | |||
| end | |||
| with_history('echo "hello\nworld"') do | |||
| session.send_string('echo "hello\\') | |||
| wait_for { session.content }.to eq('echo "hello\nworld"') | |||
| end | |||
| with_history('echo "\\\\"') do | |||
| session.send_string('echo "\\\\') | |||
| wait_for { session.content }.to eq('echo "\\\\"') | |||
| end | |||
| with_history('echo ~/foo') do | |||
| session.send_string('echo ~') | |||
| wait_for { session.content }.to eq('echo ~/foo') | |||
| end | |||
| with_history('echo "$(ls foo)"') do | |||
| session.send_string('echo "$(') | |||
| wait_for { session.content }.to eq('echo "$(ls foo)"') | |||
| end | |||
| with_history('echo "$history[123]"') do | |||
| session.send_string('echo "$history[') | |||
| wait_for { session.content }.to eq('echo "$history[123]"') | |||
| session.send_string('123]') | |||
| wait_for { session.content }.to eq('echo "$history[123]"') | |||
| end | |||
| with_history('echo "#yolo"') do | |||
| session.send_string('echo "#') | |||
| wait_for { session.content }.to eq('echo "#yolo"') | |||
| end | |||
| with_history('echo "#foo"', 'echo $#abc') do | |||
| session.send_string('echo "#') | |||
| wait_for { session.content }.to eq('echo "#foo"') | |||
| end | |||
| with_history('echo "^A"', 'echo "^B"') do | |||
| session.send_string('echo "^A') | |||
| wait_for { session.content }.to eq('echo "^A"') | |||
| end | |||
| end | |||
| end | |||
| @ -1,148 +1,8 @@ | |||
| describe 'default strategy' do | |||
| let(:session) { TerminalSession.new } | |||
| before do | |||
| session.run_command('source zsh-autosuggestions.zsh') | |||
| session.run_command('fc -p') | |||
| session.clear | |||
| wait_for { session.content }.to eq('') | |||
| end | |||
| after do | |||
| session.destroy | |||
| end | |||
| context 'with some simple history entries' do | |||
| before do | |||
| session.run_command('ls foo') | |||
| session.run_command('ls bar') | |||
| session.clear | |||
| end | |||
| it 'suggests nothing if there is no match' do | |||
| session.send_string('ls q') | |||
| wait_for { session.content }.to eq('ls q') | |||
| end | |||
| it 'suggests the most recent matching history item' do | |||
| describe 'the default suggestion strategy' do | |||
| it 'suggests the last matching history entry' do | |||
| with_history('ls foo', 'ls bar', 'echo baz') do | |||
| session.send_string('ls') | |||
| wait_for { session.content }.to eq('ls bar') | |||
| end | |||
| end | |||
| context 'with a multiline hist entry' do | |||
| before do | |||
| session.send_string('echo "') | |||
| session.send_keys('enter') | |||
| session.send_string('"') | |||
| session.send_keys('enter') | |||
| session.clear | |||
| end | |||
| it do | |||
| session.send_keys('e') | |||
| wait_for { session.content }.to eq "echo \"\n\"" | |||
| end | |||
| end | |||
| context 'with a newline hist entry' do | |||
| before do | |||
| session.send_string('echo "\n"') | |||
| session.send_keys('enter') | |||
| session.clear | |||
| end | |||
| it do | |||
| session.send_keys('e') | |||
| wait_for { session.content }.to eq 'echo "\n"' | |||
| end | |||
| end | |||
| context 'with a hist entry with a backslash' do | |||
| before do | |||
| session.run_command('echo "hello\nworld"') | |||
| session.clear | |||
| end | |||
| it do | |||
| session.send_string('echo "hello\\') | |||
| wait_for { session.content }.to eq('echo "hello\nworld"') | |||
| end | |||
| end | |||
| context 'with a hist entry with double backslashes' do | |||
| before do | |||
| session.run_command('echo "\\\\"') | |||
| session.clear | |||
| end | |||
| it do | |||
| session.send_string('echo "\\\\') | |||
| wait_for { session.content }.to eq('echo "\\\\"') | |||
| end | |||
| end | |||
| context 'with a hist entry with a tilde' do | |||
| before do | |||
| session.run_command('ls ~/foo') | |||
| session.clear | |||
| end | |||
| it do | |||
| session.send_string('ls ~') | |||
| wait_for { session.content }.to eq('ls ~/foo') | |||
| end | |||
| context 'with extended_glob set' do | |||
| before do | |||
| session.run_command('setopt local_options extended_glob') | |||
| session.clear | |||
| end | |||
| it do | |||
| session.send_string('ls ~') | |||
| wait_for { session.content }.to eq('ls ~/foo') | |||
| end | |||
| end | |||
| end | |||
| context 'with a hist entry with parentheses' do | |||
| before do | |||
| session.run_command('echo "$(ls foo)"') | |||
| session.clear | |||
| end | |||
| it do | |||
| session.send_string('echo "$(') | |||
| wait_for { session.content }.to eq('echo "$(ls foo)"') | |||
| end | |||
| end | |||
| context 'with a hist entry with square brackets' do | |||
| before do | |||
| session.run_command('echo "$history[123]"') | |||
| session.clear | |||
| end | |||
| it do | |||
| session.send_string('echo "$history[') | |||
| wait_for { session.content }.to eq('echo "$history[123]"') | |||
| end | |||
| end | |||
| context 'with a hist entry with pound sign' do | |||
| before do | |||
| session.run_command('echo "#yolo"') | |||
| session.clear | |||
| end | |||
| it do | |||
| session.send_string('echo "#') | |||
| wait_for { session.content }.to eq('echo "#yolo"') | |||
| end | |||
| end | |||
| end | |||
| @ -1,60 +1,17 @@ | |||
| describe 'match_prev_cmd strategy' do | |||
| let(:session) { TerminalSession.new } | |||
| before do | |||
| session.run_command('source zsh-autosuggestions.zsh') | |||
| session.run_command('ZSH_AUTOSUGGEST_STRATEGY=match_prev_cmd') | |||
| session.run_command('fc -p') | |||
| session.clear | |||
| end | |||
| after do | |||
| session.destroy | |||
| end | |||
| context 'with some history entries' do | |||
| before do | |||
| session.run_command('echo what') | |||
| session.run_command('ls foo') | |||
| session.run_command('echo what') | |||
| session.run_command('ls bar') | |||
| session.run_command('ls baz') | |||
| session.clear | |||
| end | |||
| it 'suggests nothing if prefix does not match' do | |||
| session.send_string('ls q') | |||
| wait_for { session.content }.to eq('ls q') | |||
| end | |||
| it 'suggests the most recent matching history item' do | |||
| session.send_string('ls') | |||
| wait_for { session.content }.to eq('ls baz') | |||
| end | |||
| it 'suggests the most recent after the previous command' do | |||
| session.run_command('echo what') | |||
| session.clear | |||
| describe 'the match_prev_cmd strategy' do | |||
| let(:options) { ['ZSH_AUTOSUGGEST_STRATEGY=match_prev_cmd'] } | |||
| it 'suggests the last matching history entry after the previous command' do | |||
| with_history( | |||
| 'echo what', | |||
| 'ls foo', | |||
| 'echo what', | |||
| 'ls bar', | |||
| 'ls baz', | |||
| 'echo what' | |||
| ) do | |||
| session.send_string('ls') | |||
| wait_for { session.content }.to eq('ls bar') | |||
| end | |||
| end | |||
| context 'with a multiline hist entry' do | |||
| before do | |||
| session.send_string('echo "') | |||
| session.send_keys('enter') | |||
| session.send_string('"') | |||
| session.send_keys('enter') | |||
| session.clear | |||
| end | |||
| it do | |||
| session.send_keys('e') | |||
| wait_for { session.content }.to eq "echo \"\n\"" | |||
| end | |||
| end | |||
| end | |||
| @ -1,162 +0,0 @@ | |||
| describe 'accept widget' do | |||
| let(:session) { TerminalSession.new } | |||
| before do | |||
| session.run_command('source zsh-autosuggestions.zsh') | |||
| session.run_command(select_keymap) | |||
| session.run_command('fc -p') | |||
| session.run_command('echo hello world') | |||
| session.clear | |||
| session.send_string('echo') | |||
| wait_for { session.content }.to start_with('echo') | |||
| end | |||
| after do | |||
| session.destroy | |||
| end | |||
| describe 'emacs keymap' do | |||
| let(:select_keymap) { 'bindkey -e' } | |||
| context 'forward-char' do | |||
| subject { session.send_keys('right') } | |||
| context 'when the cursor is at the end of the buffer' do | |||
| it 'accepts the suggestion' do | |||
| expect { subject }.to change { session.content(esc_seqs: true) }.to('echo hello world') | |||
| end | |||
| it 'moves the cursor to the end of the buffer' do | |||
| expect { subject }.to change { session.cursor }.from([4, 0]).to([16, 0]) | |||
| end | |||
| end | |||
| context 'when the cursor is not at the end of the buffer' do | |||
| before { 2.times { session.send_keys('left') } } | |||
| it 'does not accept the suggestion' do | |||
| expect { subject }.not_to change { session.content(esc_seqs: true) } | |||
| end | |||
| it 'moves the cursor forward one character' do | |||
| expect { subject }.to change { session.cursor }.from([2, 0]).to([3, 0]) | |||
| end | |||
| end | |||
| end | |||
| context 'end-of-line' do | |||
| subject { session.send_keys('C-e') } | |||
| context 'when the cursor is at the end of the buffer' do | |||
| it 'accepts the suggestion' do | |||
| expect { subject }.to change { session.content(esc_seqs: true) }.to('echo hello world') | |||
| end | |||
| it 'moves the cursor to the end of the buffer' do | |||
| expect { subject }.to change { session.cursor }.from([4, 0]).to([16, 0]) | |||
| end | |||
| end | |||
| context 'when the cursor is not at the end of the buffer' do | |||
| before { 2.times { session.send_keys('left') } } | |||
| it 'does not accept the suggestion' do | |||
| expect { subject }.not_to change { session.content(esc_seqs: true) } | |||
| end | |||
| it 'moves the cursor to the end of the line' do | |||
| expect { subject }.to change { session.cursor }.from([2, 0]).to([4, 0]) | |||
| end | |||
| end | |||
| end | |||
| end | |||
| describe 'vi keymap' do | |||
| let(:select_keymap) { 'bindkey -v' } | |||
| before { session.send_keys('escape') } | |||
| context 'vi-forward-char' do | |||
| subject { session.send_keys('l') } | |||
| context 'when the cursor is at the end of the buffer' do | |||
| it 'accepts the suggestion' do | |||
| expect { subject }.to change { session.content(esc_seqs: true) }.to('echo hello world') | |||
| end | |||
| it 'moves the cursor to the end of the buffer' do | |||
| wait_for { session.cursor }.to eq([3, 0]) | |||
| expect { subject }.to change { session.cursor }.from([3, 0]).to([15, 0]) | |||
| end | |||
| end | |||
| context 'when the cursor is not at the end of the buffer' do | |||
| before { 2.times { session.send_keys('h') } } | |||
| it 'does not accept the suggestion' do | |||
| expect { subject }.not_to change { session.content(esc_seqs: true) } | |||
| end | |||
| it 'moves the cursor forward one character' do | |||
| expect { subject }.to change { session.cursor }.from([1, 0]).to([2, 0]) | |||
| end | |||
| end | |||
| end | |||
| context 'vi-end-of-line' do | |||
| subject { session.send_keys('$') } | |||
| context 'when the cursor is at the end of the buffer' do | |||
| it 'accepts the suggestion' do | |||
| expect { subject }.to change { session.content(esc_seqs: true) }.to('echo hello world') | |||
| end | |||
| it 'moves the cursor to the end of the buffer' do | |||
| wait_for { session.cursor }.to eq([3, 0]) | |||
| expect { subject }.to change { session.cursor }.from([3, 0]).to([15, 0]) | |||
| end | |||
| end | |||
| context 'when the cursor is not at the end of the buffer' do | |||
| before { 2.times { session.send_keys('h') } } | |||
| it 'does not accept the suggestion' do | |||
| expect { subject }.not_to change { session.content(esc_seqs: true) } | |||
| end | |||
| it 'moves the cursor to the end of the line' do | |||
| expect { subject }.to change { session.cursor }.from([1, 0]).to([3, 0]) | |||
| end | |||
| end | |||
| end | |||
| context 'vi-add-eol' do | |||
| subject { session.send_keys('A') } | |||
| context 'when the cursor is at the end of the buffer' do | |||
| it 'accepts the suggestion' do | |||
| expect { subject }.to change { session.content(esc_seqs: true) }.to('echo hello world') | |||
| end | |||
| it 'moves the cursor to the end of the buffer' do | |||
| wait_for { session.cursor }.to eq([3, 0]) | |||
| expect { subject }.to change { session.cursor }.from([3, 0]).to([16, 0]) | |||
| end | |||
| end | |||
| context 'when the cursor is not at the end of the buffer' do | |||
| before { 2.times { session.send_keys('h') } } | |||
| it 'does not accept the suggestion' do | |||
| expect { subject }.not_to change { session.content(esc_seqs: true) } | |||
| end | |||
| it 'moves the cursor to the end of the line' do | |||
| expect { subject }.to change { session.cursor }.from([1, 0]).to([4, 0]) | |||
| end | |||
| end | |||
| end | |||
| end | |||
| end | |||
| @ -1,45 +0,0 @@ | |||
| #!/usr/bin/env zsh | |||
| source "${0:a:h}/test_helper.zsh" | |||
| oneTimeSetUp() { | |||
| source_autosuggestions | |||
| } | |||
| testInvokeOriginalWidgetDefined() { | |||
| stub_and_eval \ | |||
| zle \ | |||
| 'return 1' | |||
| _zsh_autosuggest_invoke_original_widget 'self-insert' | |||
| assertEquals \ | |||
| '1' \ | |||
| "$?" | |||
| assertTrue \ | |||
| 'zle was not invoked' \ | |||
| 'stub_called zle' | |||
| restore zle | |||
| } | |||
| testInvokeOriginalWidgetUndefined() { | |||
| stub_and_eval \ | |||
| zle \ | |||
| 'return 1' | |||
| _zsh_autosuggest_invoke_original_widget 'some-undefined-widget' | |||
| assertEquals \ | |||
| '0' \ | |||
| "$?" | |||
| assertFalse \ | |||
| 'zle was invoked' \ | |||
| 'stub_called zle' | |||
| restore zle | |||
| } | |||
| run_tests "$0" | |||
| @ -1,73 +0,0 @@ | |||
| #!/usr/bin/env zsh | |||
| source "${0:a:h}/test_helper.zsh" | |||
| oneTimeSetUp() { | |||
| source_autosuggestions | |||
| } | |||
| testHighlightDefaultStyle() { | |||
| assertEquals \ | |||
| 'fg=8' \ | |||
| "$ZSH_AUTOSUGGEST_HIGHLIGHT_STYLE" | |||
| } | |||
| testHighlightApplyWithSuggestion() { | |||
| local orig_style=ZSH_AUTOSUGGEST_HIGHLIGHT_STYLE | |||
| ZSH_AUTOSUGGEST_HIGHLIGHT_STYLE='fg=4' | |||
| BUFFER='ec' | |||
| POSTDISPLAY='ho hello' | |||
| region_highlight=('0 2 fg=1') | |||
| _zsh_autosuggest_highlight_apply | |||
| assertEquals \ | |||
| 'highlight did not use correct style' \ | |||
| "0 2 fg=1 2 10 $ZSH_AUTOSUGGEST_HIGHLIGHT_STYLE" \ | |||
| "$region_highlight" | |||
| assertEquals \ | |||
| 'higlight was not saved to be removed later' \ | |||
| "2 10 $ZSH_AUTOSUGGEST_HIGHLIGHT_STYLE" \ | |||
| "$_ZSH_AUTOSUGGEST_LAST_HIGHLIGHT" | |||
| ZSH_AUTOSUGGEST_HIGHLIGHT_STYLE=orig_style | |||
| } | |||
| testHighlightApplyWithoutSuggestion() { | |||
| BUFFER='echo hello' | |||
| POSTDISPLAY='' | |||
| region_highlight=('0 4 fg=1') | |||
| _zsh_autosuggest_highlight_apply | |||
| assertEquals \ | |||
| 'region_highlight was modified' \ | |||
| '0 4 fg=1' \ | |||
| "$region_highlight" | |||
| assertNull \ | |||
| 'last highlight region was not cleared' \ | |||
| "$_ZSH_AUTOSUGGEST_LAST_HIGHLIGHT" | |||
| } | |||
| testHighlightReset() { | |||
| BUFFER='ec' | |||
| POSTDISPLAY='ho hello' | |||
| region_highlight=('0 1 fg=1' '2 10 fg=8' '1 2 fg=1') | |||
| _ZSH_AUTOSUGGEST_LAST_HIGHLIGHT='2 10 fg=8' | |||
| _zsh_autosuggest_highlight_reset | |||
| assertEquals \ | |||
| 'last highlight region was not removed' \ | |||
| '0 1 fg=1 1 2 fg=1' \ | |||
| "$region_highlight" | |||
| assertNull \ | |||
| 'last highlight variable was not cleared' \ | |||
| "$_ZSH_AUTOSUGGEST_LAST_HIGHLIGHT" | |||
| } | |||
| run_tests "$0" | |||
| @ -1,46 +0,0 @@ | |||
| #!/usr/bin/env zsh | |||
| source "${0:a:h}/test_helper.zsh" | |||
| oneTimeSetUp() { | |||
| source_autosuggestions | |||
| } | |||
| testEscapeCommand() { | |||
| assertEquals \ | |||
| 'Did not escape single backslash' \ | |||
| '\\' \ | |||
| "$(_zsh_autosuggest_escape_command '\')" | |||
| assertEquals \ | |||
| 'Did not escape two backslashes' \ | |||
| '\\\\' \ | |||
| "$(_zsh_autosuggest_escape_command '\\')" | |||
| assertEquals \ | |||
| 'Did not escape parentheses' \ | |||
| '\(\)' \ | |||
| "$(_zsh_autosuggest_escape_command '()')" | |||
| assertEquals \ | |||
| 'Did not escape square brackets' \ | |||
| '\[\]' \ | |||
| "$(_zsh_autosuggest_escape_command '[]')" | |||
| assertEquals \ | |||
| 'Did not escape pipe' \ | |||
| '\|' \ | |||
| "$(_zsh_autosuggest_escape_command '|')" | |||
| assertEquals \ | |||
| 'Did not escape star' \ | |||
| '\*' \ | |||
| "$(_zsh_autosuggest_escape_command '*')" | |||
| assertEquals \ | |||
| 'Did not escape question mark' \ | |||
| '\?' \ | |||
| "$(_zsh_autosuggest_escape_command '?')" | |||
| } | |||
| run_tests "$0" | |||
| @ -1,60 +0,0 @@ | |||
| DIR="${0:a:h}" | |||
| ROOT_DIR="$DIR/.." | |||
| VENDOR_DIR="$ROOT_DIR/vendor" | |||
| # Use stub.sh for stubbing/mocking | |||
| source "$VENDOR_DIR/stub.sh/stub.sh" | |||
| #--------------------------------------------------------------------# | |||
| # Helper Functions # | |||
| #--------------------------------------------------------------------# | |||
| # Source the autosuggestions plugin file | |||
| source_autosuggestions() { | |||
| source "$ROOT_DIR/zsh-autosuggestions.zsh" | |||
| } | |||
| # Set history list from stdin | |||
| set_history() { | |||
| # Make a tmp file in shunit's tmp dir | |||
| local tmp=$(mktemp "$SHUNIT_TMPDIR/hist.XXX") | |||
| # Write from stdin to the tmp file | |||
| > "$tmp" | |||
| # Write an extra line to simulate history active mode | |||
| # See https://github.com/zsh-users/zsh/blob/ca3bc0d95d7deab4f5381f12b15047de748c0814/Src/hist.c#L69-L82 | |||
| echo >> "$tmp" | |||
| # Clear history and re-read from the tmp file | |||
| fc -P; fc -p; fc -R "$tmp" | |||
| rm "$tmp" | |||
| } | |||
| # Should be called at the bottom of every test suite file | |||
| # Pass in the name of the test script ($0) for shunit | |||
| run_tests() { | |||
| local test_script="$1" | |||
| shift | |||
| # Required for shunit to work with zsh | |||
| setopt localoptions shwordsplit | |||
| SHUNIT_PARENT="$test_script" | |||
| source "$VENDOR_DIR/shunit2/2.1.6/src/shunit2" | |||
| } | |||
| #--------------------------------------------------------------------# | |||
| # Custom Assertions # | |||
| #--------------------------------------------------------------------# | |||
| assertSuggestion() { | |||
| local prefix="$1" | |||
| local expected_suggestion="$2" | |||
| assertEquals \ | |||
| "Did not get correct suggestion for prefix:<$prefix> using strategy <$ZSH_AUTOSUGGEST_STRATEGY>" \ | |||
| "$expected_suggestion" \ | |||
| "$(_zsh_autosuggest_suggestion "$prefix")" | |||
| } | |||
| @ -1,161 +0,0 @@ | |||
| #!/usr/bin/env zsh | |||
| source "${0:a:h}/../test_helper.zsh" | |||
| oneTimeSetUp() { | |||
| source_autosuggestions | |||
| } | |||
| setUp() { | |||
| BUFFER='' | |||
| POSTDISPLAY='' | |||
| CURSOR=0 | |||
| KEYMAP='main' | |||
| } | |||
| tearDown() { | |||
| restore _zsh_autosuggest_invoke_original_widget | |||
| } | |||
| testCursorAtEnd() { | |||
| BUFFER='echo' | |||
| POSTDISPLAY=' hello' | |||
| CURSOR=4 | |||
| stub _zsh_autosuggest_invoke_original_widget | |||
| _zsh_autosuggest_accept 'original-widget' | |||
| assertTrue \ | |||
| 'original widget not invoked' \ | |||
| 'stub_called _zsh_autosuggest_invoke_original_widget' | |||
| assertEquals \ | |||
| 'BUFFER was not modified' \ | |||
| 'echo hello' \ | |||
| "$BUFFER" | |||
| assertEquals \ | |||
| 'POSTDISPLAY was not cleared' \ | |||
| '' \ | |||
| "$POSTDISPLAY" | |||
| } | |||
| testCursorNotAtEnd() { | |||
| BUFFER='echo' | |||
| POSTDISPLAY=' hello' | |||
| CURSOR=2 | |||
| stub _zsh_autosuggest_invoke_original_widget | |||
| _zsh_autosuggest_accept 'original-widget' | |||
| assertTrue \ | |||
| 'original widget not invoked' \ | |||
| 'stub_called _zsh_autosuggest_invoke_original_widget' | |||
| assertEquals \ | |||
| 'BUFFER was modified' \ | |||
| 'echo' \ | |||
| "$BUFFER" | |||
| assertEquals \ | |||
| 'POSTDISPLAY was modified' \ | |||
| ' hello' \ | |||
| "$POSTDISPLAY" | |||
| } | |||
| testViCursorAtEnd() { | |||
| BUFFER='echo' | |||
| POSTDISPLAY=' hello' | |||
| CURSOR=3 | |||
| KEYMAP='vicmd' | |||
| stub _zsh_autosuggest_invoke_original_widget | |||
| _zsh_autosuggest_accept 'original-widget' | |||
| assertTrue \ | |||
| 'original widget not invoked' \ | |||
| 'stub_called _zsh_autosuggest_invoke_original_widget' | |||
| assertEquals \ | |||
| 'BUFFER was not modified' \ | |||
| 'echo hello' \ | |||
| "$BUFFER" | |||
| assertEquals \ | |||
| 'POSTDISPLAY was not cleared' \ | |||
| '' \ | |||
| "$POSTDISPLAY" | |||
| } | |||
| testViCursorNotAtEnd() { | |||
| BUFFER='echo' | |||
| POSTDISPLAY=' hello' | |||
| CURSOR=2 | |||
| KEYMAP='vicmd' | |||
| stub _zsh_autosuggest_invoke_original_widget | |||
| _zsh_autosuggest_accept 'original-widget' | |||
| assertTrue \ | |||
| 'original widget not invoked' \ | |||
| 'stub_called _zsh_autosuggest_invoke_original_widget' | |||
| assertEquals \ | |||
| 'BUFFER was modified' \ | |||
| 'echo' \ | |||
| "$BUFFER" | |||
| assertEquals \ | |||
| 'POSTDISPLAY was modified' \ | |||
| ' hello' \ | |||
| "$POSTDISPLAY" | |||
| } | |||
| testRetval() { | |||
| stub_and_eval \ | |||
| _zsh_autosuggest_invoke_original_widget \ | |||
| 'return 1' | |||
| _zsh_autosuggest_widget_accept 'original-widget' | |||
| assertEquals \ | |||
| 'Did not return correct value from original widget' \ | |||
| '1' \ | |||
| "$?" | |||
| } | |||
| testWidget() { | |||
| stub _zsh_autosuggest_highlight_reset | |||
| stub _zsh_autosuggest_accept | |||
| stub _zsh_autosuggest_highlight_apply | |||
| # Call the function pointed to by the widget since we can't call | |||
| # the widget itself when zle is not active | |||
| ${widgets[autosuggest-accept]#*:} 'original-widget' | |||
| assertTrue \ | |||
| 'autosuggest-accept widget does not exist' \ | |||
| 'zle -l autosuggest-accept' | |||
| assertTrue \ | |||
| 'highlight_reset was not called' \ | |||
| 'stub_called _zsh_autosuggest_highlight_reset' | |||
| assertTrue \ | |||
| 'widget function was not called' \ | |||
| 'stub_called _zsh_autosuggest_accept' | |||
| assertTrue \ | |||
| 'highlight_apply was not called' \ | |||
| 'stub_called _zsh_autosuggest_highlight_apply' | |||
| restore _zsh_autosuggest_highlight_reset | |||
| restore _zsh_autosuggest_accept | |||
| restore _zsh_autosuggest_highlight_apply | |||
| } | |||
| run_tests "$0" | |||
| @ -1,77 +0,0 @@ | |||
| #!/usr/bin/env zsh | |||
| source "${0:a:h}/../test_helper.zsh" | |||
| oneTimeSetUp() { | |||
| source_autosuggestions | |||
| } | |||
| setUp() { | |||
| BUFFER='' | |||
| POSTDISPLAY='' | |||
| } | |||
| tearDown() { | |||
| restore _zsh_autosuggest_invoke_original_widget | |||
| } | |||
| testClear() { | |||
| BUFFER='ec' | |||
| POSTDISPLAY='ho hello' | |||
| _zsh_autosuggest_clear 'original-widget' | |||
| assertEquals \ | |||
| 'BUFFER was modified' \ | |||
| 'ec' \ | |||
| "$BUFFER" | |||
| assertNull \ | |||
| 'POSTDISPLAY was not cleared' \ | |||
| "$POSTDISPLAY" | |||
| } | |||
| testRetval() { | |||
| stub_and_eval \ | |||
| _zsh_autosuggest_invoke_original_widget \ | |||
| 'return 1' | |||
| _zsh_autosuggest_widget_clear 'original-widget' | |||
| assertEquals \ | |||
| 'Did not return correct value from original widget' \ | |||
| '1' \ | |||
| "$?" | |||
| } | |||
| testWidget() { | |||
| stub _zsh_autosuggest_highlight_reset | |||
| stub _zsh_autosuggest_clear | |||
| stub _zsh_autosuggest_highlight_apply | |||
| # Call the function pointed to by the widget since we can't call | |||
| # the widget itself when zle is not active | |||
| ${widgets[autosuggest-clear]#*:} 'original-widget' | |||
| assertTrue \ | |||
| 'autosuggest-clear widget does not exist' \ | |||
| 'zle -l autosuggest-clear' | |||
| assertTrue \ | |||
| 'highlight_reset was not called' \ | |||
| 'stub_called _zsh_autosuggest_highlight_reset' | |||
| assertTrue \ | |||
| 'widget function was not called' \ | |||
| 'stub_called _zsh_autosuggest_clear' | |||
| assertTrue \ | |||
| 'highlight_apply was not called' \ | |||
| 'stub_called _zsh_autosuggest_highlight_apply' | |||
| restore _zsh_autosuggest_highlight_reset | |||
| restore _zsh_autosuggest_clear | |||
| restore _zsh_autosuggest_highlight_apply | |||
| } | |||
| run_tests "$0" | |||
| @ -1,26 +0,0 @@ | |||
| #!/usr/bin/env zsh | |||
| source "${0:a:h}/../test_helper.zsh" | |||
| oneTimeSetUp() { | |||
| source_autosuggestions | |||
| } | |||
| tearDown() { | |||
| restore _zsh_autosuggest_invoke_original_widget | |||
| } | |||
| testRetval() { | |||
| stub_and_eval \ | |||
| _zsh_autosuggest_invoke_original_widget \ | |||
| 'return 1' | |||
| _zsh_autosuggest_widget_execute 'original-widget' | |||
| assertEquals \ | |||
| 'Did not return correct value from original widget' \ | |||
| '1' \ | |||
| "$?" | |||
| } | |||
| run_tests "$0" | |||
| @ -1,88 +0,0 @@ | |||
| #!/usr/bin/env zsh | |||
| source "${0:a:h}/../test_helper.zsh" | |||
| oneTimeSetUp() { | |||
| source_autosuggestions | |||
| } | |||
| setUp() { | |||
| BUFFER='' | |||
| POSTDISPLAY='' | |||
| ZSH_AUTOSUGGEST_BUFFER_MAX_SIZE='' | |||
| } | |||
| tearDown() { | |||
| restore _zsh_autosuggest_invoke_original_widget | |||
| restore _zsh_autosuggest_suggestion | |||
| } | |||
| testModify() { | |||
| stub_and_eval \ | |||
| _zsh_autosuggest_invoke_original_widget \ | |||
| 'BUFFER+="e"' | |||
| stub_and_echo \ | |||
| _zsh_autosuggest_suggestion \ | |||
| 'echo hello' | |||
| _zsh_autosuggest_modify 'original-widget' | |||
| assertTrue \ | |||
| 'original widget not invoked' \ | |||
| 'stub_called _zsh_autosuggest_invoke_original_widget' | |||
| assertEquals \ | |||
| 'BUFFER was not modified' \ | |||
| 'e' \ | |||
| "$BUFFER" | |||
| assertEquals \ | |||
| 'POSTDISPLAY does not contain suggestion' \ | |||
| 'cho hello' \ | |||
| "$POSTDISPLAY" | |||
| } | |||
| testModifyBufferTooLarge() { | |||
| ZSH_AUTOSUGGEST_BUFFER_MAX_SIZE='20' | |||
| stub_and_eval \ | |||
| _zsh_autosuggest_invoke_original_widget \ | |||
| 'BUFFER+="012345678901234567890"' | |||
| stub_and_echo \ | |||
| _zsh_autosuggest_suggestion \ | |||
| '012345678901234567890123456789' | |||
| _zsh_autosuggest_modify 'original-widget' | |||
| assertTrue \ | |||
| 'original widget not invoked' \ | |||
| 'stub_called _zsh_autosuggest_invoke_original_widget' | |||
| assertEquals \ | |||
| 'BUFFER was not modified' \ | |||
| '012345678901234567890' \ | |||
| "$BUFFER" | |||
| assertEquals \ | |||
| 'POSTDISPLAY does not contain suggestion' \ | |||
| '' \ | |||
| "$POSTDISPLAY" | |||
| } | |||
| testRetval() { | |||
| stub_and_eval \ | |||
| _zsh_autosuggest_invoke_original_widget \ | |||
| 'return 1' | |||
| _zsh_autosuggest_widget_modify 'original-widget' | |||
| assertEquals \ | |||
| 'Did not return correct value from original widget' \ | |||
| '1' \ | |||
| "$?" | |||
| } | |||
| run_tests "$0" | |||
| @ -1,84 +0,0 @@ | |||
| #!/usr/bin/env zsh | |||
| source "${0:a:h}/../test_helper.zsh" | |||
| oneTimeSetUp() { | |||
| source_autosuggestions | |||
| } | |||
| setUp() { | |||
| BUFFER='' | |||
| POSTDISPLAY='' | |||
| CURSOR=0 | |||
| } | |||
| tearDown() { | |||
| restore _zsh_autosuggest_invoke_original_widget | |||
| } | |||
| testCursorMovesOutOfBuffer() { | |||
| BUFFER='ec' | |||
| POSTDISPLAY='ho hello' | |||
| CURSOR=1 | |||
| stub_and_eval \ | |||
| _zsh_autosuggest_invoke_original_widget \ | |||
| 'CURSOR=5; LBUFFER="echo "; RBUFFER="hello"' | |||
| _zsh_autosuggest_partial_accept 'original-widget' | |||
| assertTrue \ | |||
| 'original widget not invoked' \ | |||
| 'stub_called _zsh_autosuggest_invoke_original_widget' | |||
| assertEquals \ | |||
| 'BUFFER was not modified correctly' \ | |||
| 'echo ' \ | |||
| "$BUFFER" | |||
| assertEquals \ | |||
| 'POSTDISPLAY was not modified correctly' \ | |||
| 'hello' \ | |||
| "$POSTDISPLAY" | |||
| } | |||
| testCursorStaysInBuffer() { | |||
| BUFFER='echo hello' | |||
| POSTDISPLAY=' world' | |||
| CURSOR=1 | |||
| stub_and_eval \ | |||
| _zsh_autosuggest_invoke_original_widget \ | |||
| 'CURSOR=5; LBUFFER="echo "; RBUFFER="hello"' | |||
| _zsh_autosuggest_partial_accept 'original-widget' | |||
| assertTrue \ | |||
| 'original widget not invoked' \ | |||
| 'stub_called _zsh_autosuggest_invoke_original_widget' | |||
| assertEquals \ | |||
| 'BUFFER was modified' \ | |||
| 'echo hello' \ | |||
| "$BUFFER" | |||
| assertEquals \ | |||
| 'POSTDISPLAY was modified' \ | |||
| ' world' \ | |||
| "$POSTDISPLAY" | |||
| } | |||
| testRetval() { | |||
| stub_and_eval \ | |||
| _zsh_autosuggest_invoke_original_widget \ | |||
| 'return 1' | |||
| _zsh_autosuggest_widget_partial_accept 'original-widget' | |||
| assertEquals \ | |||
| 'Did not return correct value from original widget' \ | |||
| '1' \ | |||
| "$?" | |||
| } | |||
| run_tests "$0" | |||