summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/command_callback/test_pylint_command_callback.vader31
-rw-r--r--test/command_callback/test_vint_command_callback.vader23
-rw-r--r--test/completion/test_ale_import_command.vader562
-rw-r--r--test/completion/test_complete_events.vader35
-rw-r--r--test/completion/test_completion_events.vader52
-rw-r--r--test/completion/test_completion_filtering.vader50
-rw-r--r--test/completion/test_lsp_completion_parsing.vader76
-rw-r--r--test/completion/test_tsserver_completion_parsing.vader11
-rw-r--r--test/fix/test_ale_fix.vader24
-rw-r--r--test/handler/test_bibclean_handler.vader57
-rw-r--r--test/handler/test_phpcs_handler.vader11
-rw-r--r--test/lsp/test_other_initialize_message_handling.vader6
-rwxr-xr-xtest/maven-test-files/maven-java-project/module1/mvnw0
-rwxr-xr-xtest/maven-test-files/maven-java-project/module1/mvnw.cmd0
-rw-r--r--test/maven-test-files/maven-java-project/module1/pom.xml1
-rw-r--r--test/maven-test-files/maven-java-project/module1/src/main/java/dummy1.java0
-rw-r--r--test/maven-test-files/maven-java-project/module2/pom.xml1
-rw-r--r--test/maven-test-files/maven-java-project/module2/src/main/java/dummy2.java0
-rwxr-xr-xtest/maven-test-files/mvn0
-rw-r--r--test/maven-test-files/non-maven-project/src/main/java/dummy.java0
-rw-r--r--test/test_ale_has.vader1
-rw-r--r--test/test_ale_info.vader27
-rw-r--r--test/test_ale_lint_stop_command.vader27
-rw-r--r--test/test_code_action.vader80
-rw-r--r--test/test_code_action_python.vader59
-rw-r--r--test/test_codefix.vader549
-rw-r--r--test/test_computed_lint_file_values.vader16
-rw-r--r--test/test_maven_build_classpath_command.vader48
-rw-r--r--test/test_maven_find_executable.vader46
-rw-r--r--test/test_maven_find_project_root.vader28
-rw-r--r--test/test_organize_imports.vader4
-rw-r--r--test/test_rename.vader10
32 files changed, 1711 insertions, 124 deletions
diff --git a/test/command_callback/test_pylint_command_callback.vader b/test/command_callback/test_pylint_command_callback.vader
index 755dd292..15f004b6 100644
--- a/test/command_callback/test_pylint_command_callback.vader
+++ b/test/command_callback/test_pylint_command_callback.vader
@@ -8,6 +8,8 @@ Before:
let b:bin_dir = has('win32') ? 'Scripts' : 'bin'
let b:command_tail = ' --output-format text --msg-template="{path}:{line}:{column}: {msg_id} ({symbol}) {msg}" --reports n %s'
+ GivenCommandOutput ['pylint 2.3.0']
+
After:
unlet! b:bin_dir
unlet! b:executable
@@ -17,26 +19,33 @@ After:
Execute(The pylint callbacks should return the correct default values):
AssertLinter 'pylint',
- \ ale#path#CdString(expand('#' . bufnr('') . ':p:h'))
- \ . ale#Escape('pylint') . ' ' . b:command_tail
+ \ ale#path#CdString(expand('%:p:h'))
+ \ . ale#Escape('pylint') . b:command_tail
+
+Execute(Pylint should run with the --from-stdin in new enough versions):
+ GivenCommandOutput ['pylint 2.4.0']
+
+ AssertLinter 'pylint',
+ \ ale#path#CdString(expand('%:p:h'))
+ \ . ale#Escape('pylint') . b:command_tail[:-3] . '--from-stdin %s'
Execute(The option for disabling changing directories should work):
let g:ale_python_pylint_change_directory = 0
- AssertLinter 'pylint', ale#Escape('pylint') . ' ' . b:command_tail
+ AssertLinter 'pylint', ale#Escape('pylint') . b:command_tail
Execute(The pylint executable should be configurable, and escaped properly):
let g:ale_python_pylint_executable = 'executable with spaces'
AssertLinter 'executable with spaces',
- \ ale#path#CdString(expand('#' . bufnr('') . ':p:h'))
- \ . ale#Escape('executable with spaces') . ' ' . b:command_tail
+ \ ale#path#CdString(expand('%:p:h'))
+ \ . ale#Escape('executable with spaces') . b:command_tail
Execute(The pylint command callback should let you set options):
let g:ale_python_pylint_options = '--some-option'
AssertLinter 'pylint',
- \ ale#path#CdString(expand('#' . bufnr('') . ':p:h'))
+ \ ale#path#CdString(expand('%:p:h'))
\ . ale#Escape('pylint') . ' --some-option' . b:command_tail
Execute(The pylint callbacks shouldn't detect virtualenv directories where they don't exist):
@@ -44,7 +53,7 @@ Execute(The pylint callbacks shouldn't detect virtualenv directories where they
AssertLinter 'pylint',
\ ale#path#CdString(ale#path#Simplify(g:dir . '/python_paths/no_virtualenv/subdir'))
- \ . ale#Escape('pylint') . ' ' . b:command_tail
+ \ . ale#Escape('pylint') . b:command_tail
Execute(The pylint callbacks should detect virtualenv directories):
silent execute 'file ' . fnameescape(g:dir . '/python_paths/with_virtualenv/subdir/foo/bar.py')
@@ -55,7 +64,7 @@ Execute(The pylint callbacks should detect virtualenv directories):
AssertLinter b:executable,
\ ale#path#CdString(ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/subdir'))
- \ . ale#Escape(b:executable) . ' ' . b:command_tail
+ \ . ale#Escape(b:executable) . b:command_tail
Execute(You should able able to use the global pylint instead):
silent execute 'file ' . fnameescape(g:dir . '/python_paths/with_virtualenv/subdir/foo/bar.py')
@@ -63,7 +72,7 @@ Execute(You should able able to use the global pylint instead):
AssertLinter 'pylint',
\ ale#path#CdString(ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/subdir'))
- \ . ale#Escape('pylint') . ' ' . b:command_tail
+ \ . ale#Escape('pylint') . b:command_tail
Execute(Setting executable to 'pipenv' appends 'run pylint'):
let g:ale_python_pylint_executable = 'path/to/pipenv'
@@ -71,7 +80,7 @@ Execute(Setting executable to 'pipenv' appends 'run pylint'):
AssertLinter 'path/to/pipenv',
\ ale#path#CdString(expand('#' . bufnr('') . ':p:h'))
\ . ale#Escape('path/to/pipenv') . ' run pylint'
- \ . ' --output-format text --msg-template="{path}:{line}:{column}: {msg_id} ({symbol}) {msg}" --reports n %s'
+ \ . ' --output-format text --msg-template="{path}:{line}:{column}: {msg_id} ({symbol}) {msg}" --reports n %s'
Execute(Pipenv is detected when python_pylint_auto_pipenv is set):
let g:ale_python_pylint_auto_pipenv = 1
@@ -80,4 +89,4 @@ Execute(Pipenv is detected when python_pylint_auto_pipenv is set):
AssertLinter 'pipenv',
\ ale#path#CdString(expand('#' . bufnr('') . ':p:h'))
\ . ale#Escape('pipenv') . ' run pylint'
- \ . ' --output-format text --msg-template="{path}:{line}:{column}: {msg_id} ({symbol}) {msg}" --reports n %s'
+ \ . ' --output-format text --msg-template="{path}:{line}:{column}: {msg_id} ({symbol}) {msg}" --reports n %s'
diff --git a/test/command_callback/test_vint_command_callback.vader b/test/command_callback/test_vint_command_callback.vader
index 4ce277e8..4a224d01 100644
--- a/test/command_callback/test_vint_command_callback.vader
+++ b/test/command_callback/test_vint_command_callback.vader
@@ -1,17 +1,17 @@
Before:
call ale#assert#SetUpLinterTest('vim', 'vint')
- let b:command_tail = (has('nvim') ? ' --enable-neovim' : '')
- \ . ' -f "{file_path}:{line_number}:{column_number}: {severity}: {policy_name} - {description} (see {reference})" %t'
+ let b:common_flags = (has('nvim') ? ' --enable-neovim' : '')
+ \ . ' -f "{file_path}:{line_number}:{column_number}: {severity}: {policy_name} - {description} (see {reference})"'
After:
- unlet! b:bin_dir
- unlet! b:executable
+ unlet! b:common_flags
+
call ale#assert#TearDownLinterTest()
Execute(The default command should be correct):
AssertLinter 'vint', [
\ ale#Escape('vint') .' --version',
- \ ale#Escape('vint') .' -s --no-color' . b:command_tail,
+ \ ale#Escape('vint') .' -s --no-color' . b:common_flags . ' %t',
\]
Execute(The executable should be configurable):
@@ -19,5 +19,16 @@ Execute(The executable should be configurable):
AssertLinter 'foobar', [
\ ale#Escape('foobar') .' --version',
- \ ale#Escape('foobar') .' -s --no-color' . b:command_tail,
+ \ ale#Escape('foobar') .' -s --no-color' . b:common_flags . ' %t',
\]
+
+Execute(The --no-color flag should not be used for older Vint versions):
+ GivenCommandOutput ['v0.3.5']
+
+ AssertLinter 'vint', ale#Escape('vint') .' -s' . b:common_flags . ' %t'
+
+Execute(--stdin-display-name should be used in newer versions):
+ GivenCommandOutput ['v0.4.0']
+
+ AssertLinter 'vint', ale#Escape('vint') .' -s --no-color' . b:common_flags
+ \ . ' --stdin-display-name %s -'
diff --git a/test/completion/test_ale_import_command.vader b/test/completion/test_ale_import_command.vader
new file mode 100644
index 00000000..d36caae2
--- /dev/null
+++ b/test/completion/test_ale_import_command.vader
@@ -0,0 +1,562 @@
+Before:
+ Save g:ale_enabled
+ Save b:ale_enabled
+ Save g:ale_lint_on_text_changed
+ Save g:ale_completion_enabled
+ Save g:ale_completion_autoimport
+ Save g:ale_completion_max_suggestions
+ Save g:ale_linters
+ Save b:ale_linters
+
+ let g:ale_enabled = 0
+ let b:ale_enabled = 0
+ let g:ale_lint_on_text_changed = 'always'
+ let g:ale_completion_enabled = 0
+ let g:ale_completion_autoimport = 0
+ let g:ale_completion_max_suggestions = 50
+ let g:ale_linters = {'typescript': ['tsserver'], 'python': ['pyre']}
+ unlet! b:ale_linters
+
+ let g:server_started_value = 1
+ let g:request_id = 0
+ let g:LastCallback = v:null
+ let g:LastHandleCallback = v:null
+ let g:sent_message_list = []
+ let g:code_action_list = []
+ let g:execute_list = []
+ let g:ale_queue_call_list = []
+
+ runtime autoload/ale.vim
+ runtime autoload/ale/util.vim
+ runtime autoload/ale/code_action.vim
+ runtime autoload/ale/lsp.vim
+ runtime autoload/ale/lsp_linter.vim
+
+ function! ale#util#Execute(expr) abort
+ call add(g:execute_list, a:expr)
+ endfunction
+
+ function! ale#Queue(...) abort
+ call add(g:ale_queue_call_list, a:000)
+ endfunction
+
+ function! ale#lsp#RegisterCallback(id, Callback) abort
+ let g:LastHandleCallback = a:Callback
+ endfunction
+
+ function! ale#lsp#NotifyForChanges(id, buffer) abort
+ endfunction
+
+ function! ale#lsp#HasCapability(id, capability) abort
+ return 1
+ endfunction
+
+ function! ale#lsp#Send(id, message) abort
+ let g:request_id += 1
+
+ call add(g:sent_message_list, a:message)
+
+ return g:request_id
+ endfunction
+
+ function! ale#lsp_linter#StartLSP(buffer, linter, Callback) abort
+ let g:LastCallback = a:Callback
+
+ return g:server_started_value
+ endfunction
+
+ function! ale#code_action#HandleCodeAction(code_action, options) abort
+ Assert !get(a:options, 'should_save')
+
+ call add(g:code_action_list, a:code_action)
+ endfunction
+
+ function GetLastMessage()
+ return get(g:execute_list, -1, '')
+ endfunction
+
+ function CheckLintStates(conn_id, message)
+ " Check that we request more linter results after adding completions.
+ AssertEqual [[0, '']], g:ale_queue_call_list
+
+ let g:ale_enabled = 0
+
+ let g:ale_queue_call_list = []
+ call g:LastHandleCallback(a:conn_id, a:message)
+ AssertEqual [], g:ale_queue_call_list
+
+ let g:ale_enabled = 1
+ let g:ale_lint_on_text_changed = 1
+
+ let g:ale_queue_call_list = []
+ call g:LastHandleCallback(a:conn_id, a:message)
+ AssertEqual [[0, '']], g:ale_queue_call_list
+
+ let g:ale_lint_on_text_changed = 'normal'
+
+ let g:ale_queue_call_list = []
+ call g:LastHandleCallback(a:conn_id, a:message)
+ AssertEqual [[0, '']], g:ale_queue_call_list
+
+ let g:ale_lint_on_text_changed = 'insert'
+
+ let g:ale_queue_call_list = []
+ call g:LastHandleCallback(a:conn_id, a:message)
+ AssertEqual [[0, '']], g:ale_queue_call_list
+
+ let g:ale_queue_call_list = []
+ let g:ale_lint_on_text_changed = 'never'
+
+ call g:LastHandleCallback(a:conn_id, a:message)
+ AssertEqual [], g:ale_queue_call_list
+
+ let g:ale_lint_on_text_changed = '0'
+
+ call g:LastHandleCallback(a:conn_id, a:message)
+ AssertEqual [], g:ale_queue_call_list
+
+ let g:ale_lint_on_text_changed = 0
+
+ call g:LastHandleCallback(a:conn_id, a:message)
+ AssertEqual [], g:ale_queue_call_list
+
+ let g:ale_lint_on_text_changed = 'xxx'
+
+ call g:LastHandleCallback(a:conn_id, a:message)
+ AssertEqual [], g:ale_queue_call_list
+ endfunction
+
+After:
+ call ale#linter#Reset()
+
+ Restore
+
+ delfunction GetLastMessage
+ delfunction CheckLintStates
+
+ unlet! g:LastCallback
+ unlet! g:LastHandleCallback
+ unlet! g:request_id
+ unlet! g:server_started_value
+ unlet! g:sent_message_list
+ unlet! g:code_action_list
+ unlet! g:ale_queue_call_list
+ unlet! g:execute_list
+ unlet! g:received_message
+ unlet! b:ale_old_omnifunc
+ unlet! b:ale_old_completeopt
+ unlet! b:ale_completion_info
+ unlet! b:ale_completion_result
+ unlet! b:ale_complete_done_time
+
+ runtime autoload/ale.vim
+ runtime autoload/ale/util.vim
+ runtime autoload/ale/code_action.vim
+ runtime autoload/ale/lsp.vim
+ runtime autoload/ale/lsp_linter.vim
+
+Given typescript(Some example TypeScript code):
+ let xyz = 123
+ let foo = missingword
+
+ let abc = 456
+
+Execute(ALEImport should complain when there's no word at the cursor):
+ call setpos('.', [bufnr(''), 3, 1, 0])
+ ALEImport
+
+ AssertEqual 'echom ''Nothing to complete at cursor!''', GetLastMessage()
+
+Execute(ALEImport should tell the user if no LSP is available):
+ let g:server_started_value = 0
+
+ call setpos('.', [bufnr(''), 2, 16, 0])
+ ALEImport
+
+ AssertEqual
+ \ 'echom ''No completion providers are available.''',
+ \ GetLastMessage()
+
+Execute(ALEImport should request imports correctly for tsserver):
+ call setpos('.', [bufnr(''), 2, 16, 0])
+
+ ALEImport
+
+ AssertEqual
+ \ {
+ \ 'conn_id': 0,
+ \ 'request_id': 0,
+ \ 'source': 'ale-import',
+ \ 'column': 11,
+ \ 'line': 2,
+ \ 'line_length': 21,
+ \ 'prefix': 'missingword',
+ \ 'additional_edits_only': 1,
+ \ },
+ \ b:ale_completion_info
+ Assert g:LastCallback isnot v:null
+
+ call g:LastCallback(ale#linter#Get(&filetype)[0], {
+ \ 'connection_id': 347,
+ \ 'buffer': bufnr(''),
+ \})
+
+ AssertEqual
+ \ {
+ \ 'conn_id': 347,
+ \ 'request_id': 1,
+ \ 'source': 'ale-import',
+ \ 'column': 11,
+ \ 'line': 2,
+ \ 'line_length': 21,
+ \ 'prefix': 'missingword',
+ \ 'additional_edits_only': 1,
+ \ },
+ \ b:ale_completion_info
+ Assert g:LastHandleCallback isnot v:null
+
+ call g:LastHandleCallback(347, {
+ \ 'request_seq': 1,
+ \ 'command': 'completions',
+ \ 'body': [
+ \ {'name': 'missingwordIgnoreMe'},
+ \ {'name': 'missingword'},
+ \ ],
+ \})
+
+ AssertEqual
+ \ [
+ \ [0, 'ts@completions', {
+ \ 'file': expand('%:p'),
+ \ 'includeExternalModuleExports': 1,
+ \ 'offset': 11,
+ \ 'line': 2,
+ \ 'prefix': 'missingword',
+ \ }],
+ \ [0, 'ts@completionEntryDetails', {
+ \ 'file': expand('%:p'),
+ \ 'entryNames': [{'name': 'missingword'}],
+ \ 'offset': 11,
+ \ 'line': 2,
+ \ }]
+ \ ],
+ \ g:sent_message_list
+ AssertEqual 2, b:ale_completion_info.request_id
+
+ let g:ale_enabled = 1
+ let g:received_message = {
+ \ 'request_seq': 2,
+ \ 'command': 'completionEntryDetails',
+ \ 'body': [
+ \ {
+ \ 'name': 'missingword',
+ \ 'kind': 'className',
+ \ 'displayParts': [],
+ \ 'codeActions': [{
+ \ 'description': 'import { missingword } from "./Something";',
+ \ 'changes': [],
+ \ }],
+ \ },
+ \ ],
+ \}
+ call g:LastHandleCallback(347, g:received_message)
+
+ AssertEqual
+ \ [
+ \ {
+ \ 'description': 'import { missingword } from "./Something";',
+ \ 'changes': [],
+ \ },
+ \ ],
+ \ g:code_action_list
+
+ call CheckLintStates(347, g:received_message)
+
+Execute(ALEImport should tell the user when no completions were found from tsserver):
+ call setpos('.', [bufnr(''), 2, 16, 0])
+
+ ALEImport
+
+ AssertEqual
+ \ {
+ \ 'conn_id': 0,
+ \ 'request_id': 0,
+ \ 'source': 'ale-import',
+ \ 'column': 11,
+ \ 'line': 2,
+ \ 'line_length': 21,
+ \ 'prefix': 'missingword',
+ \ 'additional_edits_only': 1,
+ \ },
+ \ b:ale_completion_info
+ Assert g:LastCallback isnot v:null
+
+ call g:LastCallback(ale#linter#Get(&filetype)[0], {
+ \ 'connection_id': 347,
+ \ 'buffer': bufnr(''),
+ \})
+
+ AssertEqual
+ \ {
+ \ 'conn_id': 347,
+ \ 'request_id': 1,
+ \ 'source': 'ale-import',
+ \ 'column': 11,
+ \ 'line': 2,
+ \ 'line_length': 21,
+ \ 'prefix': 'missingword',
+ \ 'additional_edits_only': 1,
+ \ },
+ \ b:ale_completion_info
+ Assert g:LastHandleCallback isnot v:null
+
+ call g:LastHandleCallback(347, {
+ \ 'request_seq': 1,
+ \ 'command': 'completions',
+ \ 'body': [
+ \ {'name': 'missingwordIgnoreMe'},
+ \ ],
+ \})
+
+ AssertEqual 'echom ''No possible imports found.''', GetLastMessage()
+
+Given python(Some example Python code):
+ xyz = 123
+ foo = missingword
+
+ abc = 456
+
+Execute(ALEImport should request imports correctly for language servers):
+ call setpos('.', [bufnr(''), 2, 12, 0])
+
+ ALEImport
+
+ AssertEqual
+ \ {
+ \ 'conn_id': 0,
+ \ 'request_id': 0,
+ \ 'source': 'ale-import',
+ \ 'column': 7,
+ \ 'line': 2,
+ \ 'line_length': 17,
+ \ 'prefix': 'missingword',
+ \ 'additional_edits_only': 1,
+ \ },
+ \ b:ale_completion_info
+ Assert g:LastCallback isnot v:null
+
+ call g:LastCallback(ale#linter#Get(&filetype)[0], {
+ \ 'connection_id': 347,
+ \ 'buffer': bufnr(''),
+ \})
+
+ AssertEqual
+ \ {
+ \ 'conn_id': 347,
+ \ 'request_id': 1,
+ \ 'source': 'ale-import',
+ \ 'column': 7,
+ \ 'line': 2,
+ \ 'line_length': 17,
+ \ 'prefix': 'missingword',
+ \ 'additional_edits_only': 1,
+ \ 'completion_filter': 'ale#completion#python#CompletionItemFilter',
+ \ },
+ \ b:ale_completion_info
+ Assert g:LastHandleCallback isnot v:null
+
+ AssertEqual
+ \ [
+ \ [0, 'textDocument/completion', {
+ \ 'textDocument': {'uri': ale#path#ToURI(expand('%:p'))},
+ \ 'position': {'character': 6, 'line': 1}
+ \ }],
+ \ ],
+ \ g:sent_message_list
+ AssertEqual 1, b:ale_completion_info.request_id
+
+ let g:ale_enabled = 1
+ let g:received_message = {
+ \ 'id': 1,
+ \ 'jsonrpc': '2.0',
+ \ 'result': {
+ \ 'isIncomplete': v:false,
+ \ 'items': [
+ \ {
+ \ 'detail': 'Some other word we should ignore',
+ \ 'filterText': 'missingwordIgnoreMe',
+ \ 'insertText': 'missingwordIgnoreMe',
+ \ 'insertTextFormat': 1,
+ \ 'kind': 6,
+ \ 'label': ' missingwordIgnoreMe',
+ \ 'sortText': '3ee19999missingword',
+ \ 'additionalTextEdits': [
+ \ {
+ \ 'range': {
+ \ 'start': {'line': 1, 'character': 1},
+ \ 'end': {'line': 2, 'character': 1},
+ \ },
+ \ 'newText': 'from something import missingwordIgnoreMe',
+ \ },
+ \ ],
+ \ },
+ \ {
+ \ 'detail': 'Some word without text edits',
+ \ 'filterText': 'missingword',
+ \ 'insertText': 'missingword',
+ \ 'insertTextFormat': 1,
+ \ 'kind': 6,
+ \ 'label': ' missingword',
+ \ 'sortText': '3ee19999missingword',
+ \ },
+ \ {
+ \ 'detail': 'The word we should use',
+ \ 'filterText': 'missingword',
+ \ 'insertText': 'missingword',
+ \ 'insertTextFormat': 1,
+ \ 'kind': 6,
+ \ 'label': ' missingword',
+ \ 'sortText': '3ee19999missingword',
+ \ 'additionalTextEdits': [
+ \ {
+ \ 'range': {
+ \ 'start': {'line': 1, 'character': 1},
+ \ 'end': {'line': 2, 'character': 1},
+ \ },
+ \ 'newText': 'from something import missingword',
+ \ },
+ \ ],
+ \ },
+ \ {
+ \ 'detail': 'The other word we should not use',
+ \ 'filterText': 'missingword',
+ \ 'insertText': 'missingword',
+ \ 'insertTextFormat': 1,
+ \ 'kind': 6,
+ \ 'label': ' missingword',
+ \ 'sortText': '3ee19999missingword',
+ \ 'additionalTextEdits': [
+ \ {
+ \ 'range': {
+ \ 'start': {'line': 1, 'character': 1},
+ \ 'end': {'line': 2, 'character': 1},
+ \ },
+ \ 'newText': 'from something_else import missingword',
+ \ },
+ \ ],
+ \ },
+ \ ],
+ \ },
+ \}
+ call g:LastHandleCallback(347, g:received_message)
+
+ AssertEqual
+ \ [
+ \ {
+ \ 'description': 'completion',
+ \ 'changes': [
+ \ {
+ \ 'fileName': expand('%:p'),
+ \ 'textChanges': [
+ \ {
+ \ 'start': {'line': 2, 'offset': 2},
+ \ 'end': {'line': 3, 'offset': 2},
+ \ 'newText': 'from something import missingword',
+ \ },
+ \ ],
+ \ },
+ \ ],
+ \ },
+ \ ],
+ \ g:code_action_list
+
+ call CheckLintStates(347, g:received_message)
+
+Execute(ALEImport should tell the user when no completions were found from a language server):
+ call setpos('.', [bufnr(''), 2, 12, 0])
+
+ ALEImport
+
+ AssertEqual
+ \ {
+ \ 'conn_id': 0,
+ \ 'request_id': 0,
+ \ 'source': 'ale-import',
+ \ 'column': 7,
+ \ 'line': 2,
+ \ 'line_length': 17,
+ \ 'prefix': 'missingword',
+ \ 'additional_edits_only': 1,
+ \ },
+ \ b:ale_completion_info
+ Assert g:LastCallback isnot v:null
+
+ call g:LastCallback(ale#linter#Get(&filetype)[0], {
+ \ 'connection_id': 347,
+ \ 'buffer': bufnr(''),
+ \})
+
+ AssertEqual
+ \ {
+ \ 'conn_id': 347,
+ \ 'request_id': 1,
+ \ 'source': 'ale-import',
+ \ 'column': 7,
+ \ 'line': 2,
+ \ 'line_length': 17,
+ \ 'prefix': 'missingword',
+ \ 'additional_edits_only': 1,
+ \ 'completion_filter': 'ale#completion#python#CompletionItemFilter',
+ \ },
+ \ b:ale_completion_info
+ Assert g:LastHandleCallback isnot v:null
+
+ AssertEqual
+ \ [
+ \ [0, 'textDocument/completion', {
+ \ 'textDocument': {'uri': ale#path#ToURI(expand('%:p'))},
+ \ 'position': {'character': 6, 'line': 1}
+ \ }],
+ \ ],
+ \ g:sent_message_list
+ AssertEqual 1, b:ale_completion_info.request_id
+
+ let g:received_message = {
+ \ 'id': 1,
+ \ 'jsonrpc': '2.0',
+ \ 'result': {
+ \ 'isIncomplete': v:false,
+ \ 'items': [
+ \ {
+ \ 'detail': 'Some other word we should ignore',
+ \ 'filterText': 'missingwordIgnoreMe',
+ \ 'insertText': 'missingwordIgnoreMe',
+ \ 'insertTextFormat': 1,
+ \ 'kind': 6,
+ \ 'label': ' missingwordIgnoreMe',
+ \ 'sortText': '3ee19999missingword',
+ \ 'additionalTextEdits': [
+ \ {
+ \ 'range': {
+ \ 'start': {'line': 1, 'character': 1},
+ \ 'end': {'line': 2, 'character': 1},
+ \ },
+ \ 'newText': 'from something import missingwordIgnoreMe',
+ \ },
+ \ ],
+ \ },
+ \ {
+ \ 'detail': 'Some word without text edits',
+ \ 'filterText': 'missingword',
+ \ 'insertText': 'missingword',
+ \ 'insertTextFormat': 1,
+ \ 'kind': 6,
+ \ 'label': ' missingword',
+ \ 'sortText': '3ee19999missingword',
+ \ },
+ \ ],
+ \ },
+ \}
+ call g:LastHandleCallback(347, g:received_message)
+
+ AssertEqual 'echom ''No possible imports found.''', GetLastMessage()
diff --git a/test/completion/test_complete_events.vader b/test/completion/test_complete_events.vader
new file mode 100644
index 00000000..cee15985
--- /dev/null
+++ b/test/completion/test_complete_events.vader
@@ -0,0 +1,35 @@
+Before:
+ let g:complete_post_triggered = 0
+
+ augroup VaderTest
+ autocmd!
+ autocmd User ALECompletePost let g:complete_post_triggered = 1
+ augroup END
+
+After:
+ unlet! b:ale_completion_info
+ unlet! g:complete_post_triggered
+
+ augroup VaderTest
+ autocmd!
+ augroup END
+
+ augroup! VaderTest
+
+Execute(ALECompletePost should not be triggered when completion is cancelled):
+ call ale#completion#HandleUserData({})
+
+ Assert !g:complete_post_triggered
+
+Execute(ALECompletePost should not be triggered when tools other than ALE insert completions):
+ call ale#completion#HandleUserData({'user_data': ''})
+ call ale#completion#HandleUserData({'user_data': '{}'})
+
+ Assert !g:complete_post_triggered
+
+Execute(ALECompletePost should be triggered when ALE inserts completions):
+ call ale#completion#HandleUserData({
+ \ 'user_data': json_encode({'_ale_completion_item': 1}),
+ \})
+
+ Assert g:complete_post_triggered
diff --git a/test/completion/test_completion_events.vader b/test/completion/test_completion_events.vader
index 87bd10ad..30bf603c 100644
--- a/test/completion/test_completion_events.vader
+++ b/test/completion/test_completion_events.vader
@@ -50,8 +50,8 @@ Before:
let g:handle_code_action_called = 0
function! MockHandleCodeAction() abort
" delfunction! ale#code_action#HandleCodeAction
- function! ale#code_action#HandleCodeAction(action, should_save) abort
- AssertEqual v:false, a:should_save
+ function! ale#code_action#HandleCodeAction(action, options) abort
+ Assert !get(a:options, 'should_save')
let g:handle_code_action_called += 1
endfunction
endfunction
@@ -407,41 +407,75 @@ Execute(HandleUserData should call ale#code_action#HandleCodeAction):
AssertEqual g:handle_code_action_called, 0
call ale#completion#HandleUserData({
- \ 'user_data': ''
+ \ 'user_data': ''
\})
AssertEqual g:handle_code_action_called, 0
call ale#completion#HandleUserData({
- \ 'user_data': '{}'
+ \ 'user_data': json_encode({}),
\})
AssertEqual g:handle_code_action_called, 0
call ale#completion#HandleUserData({
- \ 'user_data': '{"codeActions": []}'
+ \ 'user_data': json_encode({
+ \ '_ale_completion_item': 1,
+ \ 'code_actions': [],
+ \ }),
\})
AssertEqual g:handle_code_action_called, 0
call ale#completion#HandleUserData({
- \ 'user_data': '{"codeActions": [{"description":"", "changes": []}]}'
+ \ 'user_data': json_encode({
+ \ '_ale_completion_item': 1,
+ \ 'code_actions': [
+ \ {'description': '', 'changes': []},
+ \ ],
+ \ }),
\})
AssertEqual g:handle_code_action_called, 1
let b:ale_completion_info = {'source': 'ale-automatic'}
call ale#completion#HandleUserData({
- \ 'user_data': '{"codeActions": [{"description":"", "changes": []}]}'
+ \ 'user_data': json_encode({
+ \ '_ale_completion_item': 1,
+ \ 'code_actions': [
+ \ {'description': '', 'changes': []},
+ \ ],
+ \ }),
\})
AssertEqual g:handle_code_action_called, 2
let b:ale_completion_info = {'source': 'ale-callback'}
call ale#completion#HandleUserData({
- \ 'user_data': '{"codeActions": [{"description":"", "changes": []}]}'
+ \ 'user_data': json_encode({
+ \ '_ale_completion_item': 1,
+ \ 'code_actions': [
+ \ {'description': '', 'changes': []},
+ \ ],
+ \ }),
\})
AssertEqual g:handle_code_action_called, 3
+ let b:ale_completion_info = {'source': 'ale-omnifunc'}
+ call ale#completion#HandleUserData({
+ \ 'user_data': json_encode({
+ \ '_ale_completion_item': 1,
+ \ 'code_actions': [
+ \ {'description': '', 'changes': []},
+ \ ],
+ \ }),
+ \})
+ AssertEqual g:handle_code_action_called, 4
+
Execute(ale#code_action#HandleCodeAction should not be called when when source is not ALE):
call MockHandleCodeAction()
let b:ale_completion_info = {'source': 'syntastic'}
call ale#completion#HandleUserData({
- \ 'user_data': '{"codeActions": [{"description":"", "changes": []}]}'
+ \ 'user_data': json_encode({
+ \ '_ale_completion_item': 1,
+ \ 'code_actions': [
+ \ {'description': '', 'changes': []},
+ \ ],
+ \ }),
\})
AssertEqual g:handle_code_action_called, 0
diff --git a/test/completion/test_completion_filtering.vader b/test/completion/test_completion_filtering.vader
index c5f14266..172203a4 100644
--- a/test/completion/test_completion_filtering.vader
+++ b/test/completion/test_completion_filtering.vader
@@ -12,13 +12,24 @@ After:
Execute(Prefix filtering should work for Lists of strings):
AssertEqual
\ ['FooBar', 'foo'],
- \ ale#completion#Filter(bufnr(''), '', ['FooBar', 'FongBar', 'baz', 'foo'], 'foo')
+ \ ale#completion#Filter(bufnr(''), '', ['FooBar', 'FongBar', 'baz', 'foo'], 'foo', 0)
AssertEqual
\ ['FooBar', 'FongBar', 'baz', 'foo'],
- \ ale#completion#Filter(bufnr(''), '', ['FooBar', 'FongBar', 'baz', 'foo'], '.')
+ \ ale#completion#Filter(bufnr(''), '', ['FooBar', 'FongBar', 'baz', 'foo'], '.', 0)
AssertEqual
\ ['FooBar', 'FongBar', 'baz', 'foo'],
- \ ale#completion#Filter(bufnr(''), '', ['FooBar', 'FongBar', 'baz', 'foo'], '')
+ \ ale#completion#Filter(bufnr(''), '', ['FooBar', 'FongBar', 'baz', 'foo'], '', 0)
+
+Execute(Exact filtering should work):
+ AssertEqual
+ \ ['foo'],
+ \ ale#completion#Filter(bufnr(''), '', ['FooBar', 'FongBar', 'baz', 'foo'], 'foo', 1)
+ AssertEqual
+ \ ['FooBar', 'FongBar', 'baz', 'foo'],
+ \ ale#completion#Filter(bufnr(''), '', ['FooBar', 'FongBar', 'baz', 'foo'], '.', 1)
+ AssertEqual
+ \ ['Foo'],
+ \ ale#completion#Filter(bufnr(''), '', ['FooBar', 'FongBar', 'Foo', 'foo'], 'Foo', 1)
Execute(Prefix filtering should work for completion items):
AssertEqual
@@ -32,7 +43,8 @@ Execute(Prefix filtering should work for completion items):
\ {'word': 'baz'},
\ {'word': 'foo'},
\ ],
- \ 'foo'
+ \ 'foo',
+ \ 0,
\ )
AssertEqual
@@ -51,7 +63,8 @@ Execute(Prefix filtering should work for completion items):
\ {'word': 'baz'},
\ {'word': 'foo'},
\ ],
- \ '.'
+ \ '.',
+ \ 0,
\ )
Execute(Excluding words from completion results should work):
@@ -66,7 +79,8 @@ Execute(Excluding words from completion results should work):
\ {'word': 'Italian'},
\ {'word': 'it'},
\ ],
- \ 'it'
+ \ 'it',
+ \ 0,
\ )
AssertEqual
@@ -78,7 +92,8 @@ Execute(Excluding words from completion results should work):
\ {'word': 'describe'},
\ {'word': 'Deutsch'},
\ ],
- \ 'de'
+ \ 'de',
+ \ 0,
\ )
AssertEqual
@@ -90,7 +105,8 @@ Execute(Excluding words from completion results should work):
\ {'word': 'describe'},
\ {'word': 'Deutsch'},
\ ],
- \ '.'
+ \ '.',
+ \ 0,
\ )
Execute(Excluding words from completion results should work with lists of Strings):
@@ -98,29 +114,29 @@ Execute(Excluding words from completion results should work with lists of String
AssertEqual
\ ['Italian'],
- \ ale#completion#Filter(bufnr(''), '', ['Italian', 'it'], 'it')
+ \ ale#completion#Filter(bufnr(''), '', ['Italian', 'it'], 'it', 0)
AssertEqual
\ ['Deutsch'],
- \ ale#completion#Filter(bufnr(''), '', ['describe', 'Deutsch'], 'de')
+ \ ale#completion#Filter(bufnr(''), '', ['describe', 'Deutsch'], 'de', 0)
AssertEqual
\ ['Deutsch'],
- \ ale#completion#Filter(bufnr(''), '', ['describe', 'Deutsch'], '.')
+ \ ale#completion#Filter(bufnr(''), '', ['describe', 'Deutsch'], '.', 0)
AssertEqual
\ ['Deutsch'],
- \ ale#completion#Filter(bufnr(''), '', ['Deutsch'], '')
+ \ ale#completion#Filter(bufnr(''), '', ['Deutsch'], '', 0)
Execute(Filtering shouldn't modify the original list):
let b:ale_completion_excluded_words = ['it', 'describe']
let b:suggestions = [{'word': 'describe'}]
- AssertEqual [], ale#completion#Filter(bufnr(''), '', b:suggestions, '.')
+ AssertEqual [], ale#completion#Filter(bufnr(''), '', b:suggestions, '.', 0)
AssertEqual b:suggestions, [{'word': 'describe'}]
- AssertEqual [], ale#completion#Filter(bufnr(''), '', b:suggestions, 'de')
+ AssertEqual [], ale#completion#Filter(bufnr(''), '', b:suggestions, 'de', 0)
AssertEqual b:suggestions, [{'word': 'describe'}]
Execute(Filtering should respect filetype triggers):
let b:suggestions = [{'word': 'describe'}]
- AssertEqual b:suggestions, ale#completion#Filter(bufnr(''), '', b:suggestions, '.')
- AssertEqual b:suggestions, ale#completion#Filter(bufnr(''), 'rust', b:suggestions, '.')
- AssertEqual b:suggestions, ale#completion#Filter(bufnr(''), 'rust', b:suggestions, '::')
+ AssertEqual b:suggestions, ale#completion#Filter(bufnr(''), '', b:suggestions, '.', 0)
+ AssertEqual b:suggestions, ale#completion#Filter(bufnr(''), 'rust', b:suggestions, '.', 0)
+ AssertEqual b:suggestions, ale#completion#Filter(bufnr(''), 'rust', b:suggestions, '::', 0)
diff --git a/test/completion/test_lsp_completion_parsing.vader b/test/completion/test_lsp_completion_parsing.vader
index b8e71320..d989aefe 100644
--- a/test/completion/test_lsp_completion_parsing.vader
+++ b/test/completion/test_lsp_completion_parsing.vader
@@ -12,34 +12,34 @@ After:
Execute(Should handle Rust completion results correctly):
AssertEqual
\ [
- \ {'word': 'new', 'menu': 'pub fn new() -> String', 'info': '', 'kind': 'f', 'icase': 1},
- \ {'word': 'with_capacity', 'menu': 'pub fn with_capacity(capacity: usize) -> String', 'info': '', 'kind': 'f', 'icase': 1},
- \ {'word': 'from_utf8', 'menu': 'pub fn from_utf8(vec: Vec<u8>) -> Result<String, FromUtf8Error>', 'info': '', 'kind': 'f', 'icase': 1},
- \ {'word': 'from_utf8_lossy', 'menu': 'pub fn from_utf8_lossy<''a>(v: &''a [u8]) -> Cow<''a, str>', 'info': '', 'kind': 'f', 'icase': 1},
- \ {'word': 'from_utf16', 'menu': 'pub fn from_utf16(v: &[u16]) -> Result<String, FromUtf16Error>', 'info': '', 'kind': 'f', 'icase': 1},
- \ {'word': 'from_utf16_lossy', 'menu': 'pub fn from_utf16_lossy(v: &[u16]) -> String', 'info': '', 'kind': 'f', 'icase': 1},
- \ {'word': 'from_raw_parts', 'menu': 'pub unsafe fn from_raw_parts(buf: *mut u8, length: usize, capacity: usize) -> String', 'info': '', 'kind': 'f', 'icase': 1},
- \ {'word': 'from_utf8_unchecked', 'menu': 'pub unsafe fn from_utf8_unchecked(bytes: Vec<u8>) -> String', 'info': '', 'kind': 'f', 'icase': 1},
- \ {'word': 'from_iter', 'menu': 'fn from_iter<I: IntoIterator<Item = char>>(iter: I) -> String', 'info': '', 'kind': 'f', 'icase': 1},
- \ {'word': 'from_iter', 'menu': 'fn from_iter<I: IntoIterator<Item = &''a char>>(iter: I) -> String', 'info': '', 'kind': 'f', 'icase': 1},
- \ {'word': 'from_iter', 'menu': 'fn from_iter<I: IntoIterator<Item = &''a str>>(iter: I) -> String', 'info': '', 'kind': 'f', 'icase': 1},
- \ {'word': 'from_iter', 'menu': 'fn from_iter<I: IntoIterator<Item = String>>(iter: I) -> String', 'info': '', 'kind': 'f', 'icase': 1},
- \ {'word': 'from_iter', 'menu': 'fn from_iter<I: IntoIterator<Item = Cow<''a, str>>>(iter: I) -> String', 'info': '', 'kind': 'f', 'icase': 1},
- \ {'word': 'Searcher', 'menu': 'type Searcher = <&''b str as Pattern<''a>>::Searcher;', 'info': '', 'kind': 't', 'icase': 1},
- \ {'word': 'default', 'menu': 'fn default() -> String', 'info': '', 'kind': 'f', 'icase': 1},
- \ {'word': 'Output', 'menu': 'type Output = String;', 'info': '', 'kind': 't', 'icase': 1},
- \ {'word': 'Output', 'menu': 'type Output = str;', 'info': '', 'kind': 't', 'icase': 1},
- \ {'word': 'Output', 'menu': 'type Output = str;', 'info': '', 'kind': 't', 'icase': 1},
- \ {'word': 'Output', 'menu': 'type Output = str;', 'info': '', 'kind': 't', 'icase': 1},
- \ {'word': 'Output', 'menu': 'type Output = str;', 'info': '', 'kind': 't', 'icase': 1},
- \ {'word': 'Output', 'menu': 'type Output = str;', 'info': '', 'kind': 't', 'icase': 1},
- \ {'word': 'Output', 'menu': 'type Output = str;', 'info': '', 'kind': 't', 'icase': 1},
- \ {'word': 'Target', 'menu': 'type Target = str;', 'info': '', 'kind': 't', 'icase': 1},
- \ {'word': 'Err', 'menu': 'type Err = ParseError;', 'info': '', 'kind': 't', 'icase': 1},
- \ {'word': 'from_str', 'menu': 'fn from_str(s: &str) -> Result<String, ParseError>', 'info': '', 'kind': 'f', 'icase': 1},
- \ {'word': 'from', 'menu': 'fn from(s: &''a str) -> String', 'info': '', 'kind': 'f', 'icase': 1},
- \ {'word': 'from', 'menu': 'fn from(s: Box<str>) -> String', 'info': '', 'kind': 'f', 'icase': 1},
- \ {'word': 'from', 'menu': 'fn from(s: Cow<''a, str>) -> String', 'info': '', 'kind': 'f', 'icase': 1},
+ \ {'word': 'new', 'menu': 'pub fn new() -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
+ \ {'word': 'with_capacity', 'menu': 'pub fn with_capacity(capacity: usize) -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
+ \ {'word': 'from_utf8', 'menu': 'pub fn from_utf8(vec: Vec<u8>) -> Result<String, FromUtf8Error>', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
+ \ {'word': 'from_utf8_lossy', 'menu': 'pub fn from_utf8_lossy<''a>(v: &''a [u8]) -> Cow<''a, str>', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
+ \ {'word': 'from_utf16', 'menu': 'pub fn from_utf16(v: &[u16]) -> Result<String, FromUtf16Error>', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
+ \ {'word': 'from_utf16_lossy', 'menu': 'pub fn from_utf16_lossy(v: &[u16]) -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
+ \ {'word': 'from_raw_parts', 'menu': 'pub unsafe fn from_raw_parts(buf: *mut u8, length: usize, capacity: usize) -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
+ \ {'word': 'from_utf8_unchecked', 'menu': 'pub unsafe fn from_utf8_unchecked(bytes: Vec<u8>) -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
+ \ {'word': 'from_iter', 'menu': 'fn from_iter<I: IntoIterator<Item = char>>(iter: I) -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
+ \ {'word': 'from_iter', 'menu': 'fn from_iter<I: IntoIterator<Item = &''a char>>(iter: I) -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
+ \ {'word': 'from_iter', 'menu': 'fn from_iter<I: IntoIterator<Item = &''a str>>(iter: I) -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
+ \ {'word': 'from_iter', 'menu': 'fn from_iter<I: IntoIterator<Item = String>>(iter: I) -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
+ \ {'word': 'from_iter', 'menu': 'fn from_iter<I: IntoIterator<Item = Cow<''a, str>>>(iter: I) -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
+ \ {'word': 'Searcher', 'menu': 'type Searcher = <&''b str as Pattern<''a>>::Searcher;', 'info': '', 'kind': 't', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
+ \ {'word': 'default', 'menu': 'fn default() -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
+ \ {'word': 'Output', 'menu': 'type Output = String;', 'info': '', 'kind': 't', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
+ \ {'word': 'Output', 'menu': 'type Output = str;', 'info': '', 'kind': 't', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
+ \ {'word': 'Output', 'menu': 'type Output = str;', 'info': '', 'kind': 't', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
+ \ {'word': 'Output', 'menu': 'type Output = str;', 'info': '', 'kind': 't', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
+ \ {'word': 'Output', 'menu': 'type Output = str;', 'info': '', 'kind': 't', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
+ \ {'word': 'Output', 'menu': 'type Output = str;', 'info': '', 'kind': 't', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
+ \ {'word': 'Output', 'menu': 'type Output = str;', 'info': '', 'kind': 't', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
+ \ {'word': 'Target', 'menu': 'type Target = str;', 'info': '', 'kind': 't', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
+ \ {'word': 'Err', 'menu': 'type Err = ParseError;', 'info': '', 'kind': 't', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
+ \ {'word': 'from_str', 'menu': 'fn from_str(s: &str) -> Result<String, ParseError>', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
+ \ {'word': 'from', 'menu': 'fn from(s: &''a str) -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
+ \ {'word': 'from', 'menu': 'fn from(s: Box<str>) -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
+ \ {'word': 'from', 'menu': 'fn from(s: Cow<''a, str>) -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
\],
\ ale#completion#ParseLSPCompletions({
\ "jsonrpc":"2.0",
@@ -195,7 +195,7 @@ Execute(Should handle Python completion results correctly):
AssertEqual
\ [
- \ {'word': 'what', 'menu': 'example-python-project.bar.Bar', 'info': "what()\n\n", 'kind': 'f', 'icase': 1},
+ \ {'word': 'what', 'menu': 'example-python-project.bar.Bar', 'info': "what()\n\n", 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
\ ],
\ ale#completion#ParseLSPCompletions({
\ "jsonrpc":"2.0",
@@ -399,7 +399,7 @@ Execute(Should handle Python completion results correctly):
\ }
\ })
-Execute(Should handle Python completion results correctly):
+Execute(Should handle extra Python completion results correctly):
let b:ale_completion_info = {
\ 'completion_filter': 'ale#completion#python#CompletionItemFilter',
\ 'prefix': 'mig',
@@ -407,8 +407,8 @@ Execute(Should handle Python completion results correctly):
AssertEqual
\ [
- \ {'word': 'migrations', 'menu': 'xxx', 'info': 'migrations', 'kind': 'f', 'icase': 1},
- \ {'word': 'MigEngine', 'menu': 'xxx', 'info': 'mig engine', 'kind': 'f', 'icase': 1},
+ \ {'word': 'migrations', 'menu': 'xxx', 'info': 'migrations', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
+ \ {'word': 'MigEngine', 'menu': 'xxx', 'info': 'mig engine', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
\ ],
\ ale#completion#ParseLSPCompletions({
\ 'jsonrpc': '2.0',
@@ -441,7 +441,7 @@ Execute(Should handle Python completion results correctly):
Execute(Should handle missing keys):
AssertEqual
\ [
- \ {'word': 'x', 'menu': '', 'info': '', 'kind': 'v', 'icase': 1},
+ \ {'word': 'x', 'menu': '', 'info': '', 'kind': 'v', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
\ ],
\ ale#completion#ParseLSPCompletions({
\ 'jsonrpc': '2.0',
@@ -459,7 +459,7 @@ Execute(Should handle missing keys):
Execute(Should handle documentation in the markdown format):
AssertEqual
\ [
- \ {'word': 'migrations', 'menu': 'xxx', 'info': 'Markdown documentation', 'kind': 'f', 'icase': 1},
+ \ {'word': 'migrations', 'menu': 'xxx', 'info': 'Markdown documentation', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
\ ],
\ ale#completion#ParseLSPCompletions({
\ 'jsonrpc': '2.0',
@@ -483,7 +483,7 @@ Execute(Should handle documentation in the markdown format):
Execute(Should handle completion messages with textEdit objects):
AssertEqual
\ [
- \ {'word': 'next_callback', 'menu': 'PlayTimeCallback', 'info': '', 'kind': 'v', 'icase': 1},
+ \ {'word': 'next_callback', 'menu': 'PlayTimeCallback', 'info': '', 'kind': 'v', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
\ ],
\ ale#completion#ParseLSPCompletions({
\ 'id': 226,
@@ -514,7 +514,7 @@ Execute(Should handle completion messages with textEdit objects):
Execute(Should handle completion messages with the deprecated insertText attribute):
AssertEqual
\ [
- \ {'word': 'next_callback', 'menu': 'PlayTimeCallback', 'info': '', 'kind': 'v', 'icase': 1},
+ \ {'word': 'next_callback', 'menu': 'PlayTimeCallback', 'info': '', 'kind': 'v', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
\ ],
\ ale#completion#ParseLSPCompletions({
\ 'id': 226,
@@ -547,7 +547,8 @@ Execute(Should handle completion messages with additionalTextEdits when ale_comp
\ 'kind': 'v',
\ 'icase': 1,
\ 'user_data': json_encode({
- \ 'codeActions': [
+ \ '_ale_completion_item': 1,
+ \ 'code_actions': [
\ {
\ 'description': 'completion',
\ 'changes': [
@@ -658,6 +659,7 @@ Execute(Should still handle completion messages with empty additionalTextEdits w
\ 'info': '',
\ 'kind': 'v',
\ 'icase': 1,
+ \ 'user_data': json_encode({'_ale_completion_item': 1}),
\ }
\ ],
\ ale#completion#ParseLSPCompletions({
diff --git a/test/completion/test_tsserver_completion_parsing.vader b/test/completion/test_tsserver_completion_parsing.vader
index aaaaae95..231c0f95 100644
--- a/test/completion/test_tsserver_completion_parsing.vader
+++ b/test/completion/test_tsserver_completion_parsing.vader
@@ -90,6 +90,7 @@ Execute(TypeScript completion details responses should be parsed correctly):
\ 'info': '',
\ 'kind': 'v',
\ 'icase': 1,
+ \ 'user_data': json_encode({'_ale_completion_item': 1}),
\ 'dup': g:ale_completion_autoimport,
\ },
\ {
@@ -98,6 +99,7 @@ Execute(TypeScript completion details responses should be parsed correctly):
\ 'info': 'foo bar baz',
\ 'kind': 'v',
\ 'icase': 1,
+ \ 'user_data': json_encode({'_ale_completion_item': 1}),
\ 'dup': g:ale_completion_autoimport,
\ },
\ {
@@ -106,6 +108,7 @@ Execute(TypeScript completion details responses should be parsed correctly):
\ 'info': '',
\ 'kind': 'v',
\ 'icase': 1,
+ \ 'user_data': json_encode({'_ale_completion_item': 1}),
\ 'dup': g:ale_completion_autoimport,
\ },
\ ],
@@ -179,7 +182,8 @@ Execute(Entries without details should be included in the responses):
\ 'kind': 'v',
\ 'icase': 1,
\ 'user_data': json_encode({
- \ 'codeActions': [{
+ \ '_ale_completion_item': 1,
+ \ 'code_actions': [{
\ 'description': 'import { def } from "./Foo";',
\ 'changes': [],
\ }],
@@ -192,6 +196,7 @@ Execute(Entries without details should be included in the responses):
\ 'info': 'foo bar baz',
\ 'kind': 'v',
\ 'icase': 1,
+ \ 'user_data': json_encode({'_ale_completion_item': 1}),
\ 'dup': g:ale_completion_autoimport,
\ },
\ {
@@ -199,6 +204,7 @@ Execute(Entries without details should be included in the responses):
\ 'menu': '',
\ 'info': '',
\ 'kind': 'v',
+ \ 'user_data': json_encode({'_ale_completion_item': 1}),
\ 'icase': 1,
\ },
\ ],
@@ -260,7 +266,8 @@ Execute(Default imports should be handled correctly):
\ 'kind': 't',
\ 'icase': 1,
\ 'user_data': json_encode({
- \ 'codeActions': [{
+ \ '_ale_completion_item': 1,
+ \ 'code_actions': [{
\ 'description': 'Import default ''abcd'' from module "./foo"',
\ 'changes': [],
\ }],
diff --git a/test/fix/test_ale_fix.vader b/test/fix/test_ale_fix.vader
index a51a5a53..128e3a14 100644
--- a/test/fix/test_ale_fix.vader
+++ b/test/fix/test_ale_fix.vader
@@ -196,6 +196,10 @@ After:
" Clear the messages between tests.
echomsg ''
+ if !exists('g:ale_command_wrapper')
+ let g:ale_command_wrapper = ''
+ endif
+
Given testft (A file with three lines):
a
b
@@ -206,6 +210,13 @@ Execute(ALEFix should complain when there are no functions to call):
call ale#test#FlushJobs()
AssertEqual 'No fixers have been defined. Try :ALEFixSuggest', GetLastMessage()
+Execute(ALEFix should not complain when the command is run with a bang):
+ echom 'none'
+
+ ALEFix!
+ call ale#test#FlushJobs()
+ AssertEqual 'none', GetLastMessage()
+
Execute(ALEFix should apply simple functions):
let g:ale_fixers.testft = ['AddCarets']
ALEFix
@@ -715,6 +726,19 @@ Execute(ale#fix#InitBufferData() should set up the correct data):
\ 'done': 0,
\ 'lines_before': ['a', 'b', 'c'],
\ 'should_save': 1,
+ \ 'ignore_file_changed_errors': 0,
+ \ },
+ \}, g:ale_fix_buffer_data
+
+ call ale#fix#InitBufferData(bufnr(''), '!')
+
+ AssertEqual {
+ \ bufnr(''): {
+ \ 'temporary_directory_list': [],
+ \ 'done': 0,
+ \ 'lines_before': ['a', 'b', 'c'],
+ \ 'should_save': 0,
+ \ 'ignore_file_changed_errors': 1,
\ },
\}, g:ale_fix_buffer_data
diff --git a/test/handler/test_bibclean_handler.vader b/test/handler/test_bibclean_handler.vader
index 6179d7f5..9da52a92 100644
--- a/test/handler/test_bibclean_handler.vader
+++ b/test/handler/test_bibclean_handler.vader
@@ -4,7 +4,7 @@ Before:
After:
call ale#linter#Reset()
-Execute(The bibclean handler should parse lines correctly):
+Execute(The bibclean handler should parse lines from bibclean <= v2.11.4 correctly):
AssertEqual
\ [
@@ -19,6 +19,12 @@ Execute(The bibclean handler should parse lines correctly):
\ 'type': 'E',
\ 'text': 'Expected comma after last field ``keywords''''.',
\ 'col': ' 1'
+ \ },
+ \ {
+ \ 'lnum': '176',
+ \ 'type': 'W',
+ \ 'text': 'Unexpected DOI in URL value ``"https://doi.org/DOI"'''': move to separate DOI = "..." key/value in this entry.',
+ \ 'col': '14'
\ }
\ ],
\ ale_linters#bib#bibclean#Handle(255, [
@@ -31,5 +37,52 @@ Execute(The bibclean handler should parse lines correctly):
\ "?? File positions: input [main.bib] output [stdout]",
\ "?? Entry input byte=2145 line=63 column= 1 output byte=2146 line=63 column= 0",
\ "?? Value input byte=2528 line=71 column= 2 output byte=2527 line=70 column=49",
- \ "?? Current input byte=2529 line=71 column= 3 output byte=2528 line=70 column=50"
+ \ "?? Current input byte=2529 line=71 column= 3 output byte=2528 line=70 column=50",
+ \ "%% \"stdin\", line 176: Unexpected DOI in URL value ``\"https://doi.org/DOI\"'': move to separate DOI = \"...\" key/value in this entry.",
+ \ "%% File positions: input [stdin] output [stdout]",
+ \ "%% Entry input byte=6813 line=174 column= 1 output byte=8543 line=227 column= 0",
+ \ "%% Value input byte=6890 line=176 column=14 output byte=8641 line=229 column=17",
+ \ "%% Current input byte=6938 line=176 column=62 output byte=8641 line=229 column=17"
+ \ ])
+
+Execute(The bibclean handler should parse lines of bibclean > v2.11.4 correctly):
+
+ AssertEqual
+ \ [
+ \ {
+ \ 'lnum': '60',
+ \ 'type': 'W',
+ \ 'text': 'Unexpected value in ``month = "09"''''.',
+ \ 'col': '17'
+ \ },
+ \ {
+ \ 'lnum': '63',
+ \ 'type': 'E',
+ \ 'text': 'Expected comma after last field ``keywords''''.',
+ \ 'col': ' 1'
+ \ },
+ \ {
+ \ 'lnum': '176',
+ \ 'type': 'W',
+ \ 'text': 'Unexpected DOI in URL value ``"https://doi.org/DOI"'''': move to separate DOI = "..." key/value in this entry.',
+ \ 'col': '14'
+ \ }
+ \ ],
+ \ ale_linters#bib#bibclean#Handle(255, [
+ \ "%% stdin:60:Unexpected value in ``month = \"09\"''.",
+ \ "%% File positions: input [main.bib] output [stdout]",
+ \ "%% Entry input byte=1681 line=50 column= 1 output byte=1680 line=50 column= 0",
+ \ "%% Value input byte=2137 line=60 column=17 output byte=2137 line=60 column=17",
+ \ "%% Current input byte=2139 line=60 column=19 output byte=2137 line=60 column=17",
+ \ "?? stdin:71:Expected comma after last field ``keywords''.",
+ \ "?? File positions: input [main.bib] output [stdout]",
+ \ "?? Entry input byte=2145 line=63 column= 1 output byte=2146 line=63 column= 0",
+ \ "?? Value input byte=2528 line=71 column= 2 output byte=2527 line=70 column=49",
+ \ "?? Current input byte=2529 line=71 column= 3 output byte=2528 line=70 column=50",
+ \ "%% stdin:176:Unexpected DOI in URL value ``\"https://doi.org/DOI\"'': move to separate DOI = \"...\" key/value in this entry.",
+ \ "%% File positions: input [stdin] output [stdout]",
+ \ "%% Entry input byte=6813 line=174 column= 1 output byte=8543 line=227 column= 0",
+ \ "%% Value input byte=6890 line=176 column=14 output byte=8641 line=229 column=17",
+ \ "%% Current input byte=6938 line=176 column=62 output byte=8641 line=229 column=17"
\ ])
+
diff --git a/test/handler/test_phpcs_handler.vader b/test/handler/test_phpcs_handler.vader
index 18accece..26d35cb8 100644
--- a/test/handler/test_phpcs_handler.vader
+++ b/test/handler/test_phpcs_handler.vader
@@ -13,7 +13,16 @@ Execute(phpcs errors should be handled):
\ 'type': 'E',
\ 'sub_type': 'style',
\ 'text': 'Line indented incorrectly; expected 4 spaces, found 2 (Generic.WhiteSpace.ScopeIndent.IncorrectExact)',
- \ }],
+ \ },
+ \ {
+ \ 'lnum': 22,
+ \ 'col': 3,
+ \ 'type': 'E',
+ \ 'sub_type': 'style',
+ \ 'text': 'All output should be run through an escaping function (see the Security sections in the WordPress Developer Handbooks)',
+ \ },
+ \ ],
\ ale_linters#php#phpcs#Handle(bufnr(''), [
\ '/path/to/some-filename.php:18:3: error - Line indented incorrectly; expected 4 spaces, found 2 (Generic.WhiteSpace.ScopeIndent.IncorrectExact)',
+ \ "/path/to/some-filename.php:22:3: error - All output should be run through an escaping function (see the Security sections in the WordPress Developer Handbooks), found '\"\n'.",
\ ])
diff --git a/test/lsp/test_other_initialize_message_handling.vader b/test/lsp/test_other_initialize_message_handling.vader
index b6ef852a..f3b53843 100644
--- a/test/lsp/test_other_initialize_message_handling.vader
+++ b/test/lsp/test_other_initialize_message_handling.vader
@@ -23,6 +23,7 @@ Before:
\ 'completion_trigger_characters': [],
\ 'definition': 0,
\ 'symbol_search': 0,
+ \ 'code_actions': 0,
\ },
\}
@@ -102,6 +103,7 @@ Execute(Capabilities should bet set up correctly):
\ 'definition': 1,
\ 'symbol_search': 1,
\ 'rename': 1,
+ \ 'code_actions': 1,
\ },
\ b:conn.capabilities
AssertEqual [[1, 'initialized', {}]], g:message_list
@@ -125,7 +127,7 @@ Execute(Disabled capabilities should be recognised correctly):
\ 'referencesProvider': v:false,
\ 'textDocumentSync': 2,
\ 'documentFormattingProvider': v:true,
- \ 'codeActionProvider': v:true,
+ \ 'codeActionProvider': v:false,
\ 'signatureHelpProvider': {
\ 'triggerCharacters': ['(', ','],
\ },
@@ -146,6 +148,7 @@ Execute(Disabled capabilities should be recognised correctly):
\ 'definition': 0,
\ 'symbol_search': 0,
\ 'rename': 0,
+ \ 'code_actions': 0,
\ },
\ b:conn.capabilities
AssertEqual [[1, 'initialized', {}]], g:message_list
@@ -197,6 +200,7 @@ Execute(Capabilities should be enabled when send as Dictionaries):
\ 'typeDefinition': 1,
\ 'symbol_search': 1,
\ 'rename': 1,
+ \ 'code_actions': 1,
\ },
\ b:conn.capabilities
AssertEqual [[1, 'initialized', {}]], g:message_list
diff --git a/test/maven-test-files/maven-java-project/module1/mvnw b/test/maven-test-files/maven-java-project/module1/mvnw
new file mode 100755
index 00000000..e69de29b
--- /dev/null
+++ b/test/maven-test-files/maven-java-project/module1/mvnw
diff --git a/test/maven-test-files/maven-java-project/module1/mvnw.cmd b/test/maven-test-files/maven-java-project/module1/mvnw.cmd
new file mode 100755
index 00000000..e69de29b
--- /dev/null
+++ b/test/maven-test-files/maven-java-project/module1/mvnw.cmd
diff --git a/test/maven-test-files/maven-java-project/module1/pom.xml b/test/maven-test-files/maven-java-project/module1/pom.xml
new file mode 100644
index 00000000..8b137891
--- /dev/null
+++ b/test/maven-test-files/maven-java-project/module1/pom.xml
@@ -0,0 +1 @@
+
diff --git a/test/maven-test-files/maven-java-project/module1/src/main/java/dummy1.java b/test/maven-test-files/maven-java-project/module1/src/main/java/dummy1.java
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/test/maven-test-files/maven-java-project/module1/src/main/java/dummy1.java
diff --git a/test/maven-test-files/maven-java-project/module2/pom.xml b/test/maven-test-files/maven-java-project/module2/pom.xml
new file mode 100644
index 00000000..8b137891
--- /dev/null
+++ b/test/maven-test-files/maven-java-project/module2/pom.xml
@@ -0,0 +1 @@
+
diff --git a/test/maven-test-files/maven-java-project/module2/src/main/java/dummy2.java b/test/maven-test-files/maven-java-project/module2/src/main/java/dummy2.java
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/test/maven-test-files/maven-java-project/module2/src/main/java/dummy2.java
diff --git a/test/maven-test-files/mvn b/test/maven-test-files/mvn
new file mode 100755
index 00000000..e69de29b
--- /dev/null
+++ b/test/maven-test-files/mvn
diff --git a/test/maven-test-files/non-maven-project/src/main/java/dummy.java b/test/maven-test-files/non-maven-project/src/main/java/dummy.java
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/test/maven-test-files/non-maven-project/src/main/java/dummy.java
diff --git a/test/test_ale_has.vader b/test/test_ale_has.vader
index 633c7186..6e73641d 100644
--- a/test/test_ale_has.vader
+++ b/test/test_ale_has.vader
@@ -1,4 +1,5 @@
Execute(Checks for versions below the current version should succeed):
+ AssertEqual 1, ale#Has('ale-3.0.0')
AssertEqual 1, ale#Has('ale-2.7.0')
AssertEqual 1, ale#Has('ale-2.6.0')
AssertEqual 1, ale#Has('ale-2.5.0')
diff --git a/test/test_ale_info.vader b/test/test_ale_info.vader
index 2bc8c635..895ed2a7 100644
--- a/test/test_ale_info.vader
+++ b/test/test_ale_info.vader
@@ -6,6 +6,7 @@ Before:
Save g:ale_completion_delay
Save g:ale_completion_enabled
Save g:ale_completion_max_suggestions
+ Save g:ale_disable_lsp
Save g:ale_echo_cursor
Save g:ale_echo_msg_error_str
Save g:ale_echo_msg_format
@@ -24,6 +25,7 @@ Before:
Save g:ale_lint_on_text_changed
Save g:ale_linters
Save g:ale_linters_explicit
+ Save g:ale_linters_ignore
Save g:ale_list_vertical
Save g:ale_list_window_size
Save g:ale_loclist_msg_format
@@ -64,6 +66,7 @@ Before:
let g:ale_completion_delay = 100
let g:ale_completion_enabled = 0
let g:ale_completion_max_suggestions = 50
+ let g:ale_disable_lsp = 0
let g:ale_echo_cursor = 1
let g:ale_echo_msg_error_str = 'Error'
let g:ale_echo_msg_format = '%code: %%s'
@@ -80,6 +83,7 @@ Before:
let g:ale_lint_on_save = 1
let g:ale_lint_on_text_changed = 'normal'
let g:ale_linters_explicit = 0
+ let g:ale_linters_ignore = {'python': ['pyright']}
let g:ale_list_vertical = 0
let g:ale_list_window_size = 10
let g:ale_loclist_msg_format = '%code: %%s'
@@ -138,6 +142,7 @@ Before:
\ 'let g:ale_completion_delay = 100',
\ 'let g:ale_completion_enabled = 0',
\ 'let g:ale_completion_max_suggestions = 50',
+ \ 'let g:ale_disable_lsp = 0',
\ 'let g:ale_echo_cursor = 1',
\ 'let g:ale_echo_msg_error_str = ''Error''',
\ 'let g:ale_echo_msg_format = ''%code: %%s''',
@@ -158,6 +163,7 @@ Before:
\ 'let g:ale_linter_aliases = {}',
\ 'let g:ale_linters = {}',
\ 'let g:ale_linters_explicit = 0',
+ \ 'let g:ale_linters_ignore = {''python'': [''pyright'']}',
\ 'let g:ale_list_vertical = 0',
\ 'let g:ale_list_window_size = 10',
\ 'let g:ale_loclist_msg_format = ''%code: %%s''',
@@ -243,6 +249,7 @@ Execute (ALEInfo with no linters should return the right output):
\ ' Current Filetype: nolintersft',
\ 'Available Linters: []',
\ ' Enabled Linters: []',
+ \ ' Ignored Linters: []',
\ ]
\ + g:fixer_lines
\ + g:variables_lines
@@ -265,6 +272,7 @@ Execute (ALEInfo should return buffer-local global ALE settings):
\ ' Current Filetype: ',
\ 'Available Linters: []',
\ ' Enabled Linters: []',
+ \ ' Ignored Linters: []',
\ ]
\ + g:fixer_lines
\ + g:variables_lines
@@ -279,6 +287,7 @@ Execute (ALEInfo with no filetype should return the right output):
\ ' Current Filetype: ',
\ 'Available Linters: []',
\ ' Enabled Linters: []',
+ \ ' Ignored Linters: []',
\ ]
\ + g:fixer_lines
\ + g:variables_lines
@@ -295,6 +304,7 @@ Execute (ALEInfo with a single linter should return the right output):
\ ' Current Filetype: testft',
\ 'Available Linters: [''testlinter1'']',
\ ' Enabled Linters: [''testlinter1'']',
+ \ ' Ignored Linters: []',
\ ]
\ + g:fixer_lines
\ + g:variables_lines
@@ -312,6 +322,7 @@ Execute (ALEInfo with two linters should return the right output):
\ ' Current Filetype: testft',
\ 'Available Linters: [''testlinter1'', ''testlinter2'']',
\ ' Enabled Linters: [''testlinter1'', ''testlinter2'']',
+ \ ' Ignored Linters: []',
\ ]
\ + g:fixer_lines
\ + g:variables_lines
@@ -333,6 +344,7 @@ Execute (ALEInfo should calculate enabled linters correctly):
\ ' Current Filetype: testft',
\ 'Available Linters: [''testlinter1'', ''testlinter2'']',
\ ' Enabled Linters: [''testlinter2'']',
+ \ ' Ignored Linters: []',
\ ]
\ + g:fixer_lines
\ + g:variables_lines
@@ -350,6 +362,7 @@ Execute (ALEInfo should only return linters for current filetype):
\ ' Current Filetype: testft',
\ 'Available Linters: [''testlinter1'']',
\ ' Enabled Linters: [''testlinter1'']',
+ \ ' Ignored Linters: []',
\ ]
\ + g:fixer_lines
\ + g:variables_lines
@@ -367,6 +380,7 @@ Execute (ALEInfo with compound filetypes should return linters for both of them)
\ ' Current Filetype: testft.testft2',
\ 'Available Linters: [''testlinter1'', ''testlinter2'']',
\ ' Enabled Linters: [''testlinter1'', ''testlinter2'']',
+ \ ' Ignored Linters: []',
\ ]
\ + g:fixer_lines
\ + g:variables_lines
@@ -389,6 +403,7 @@ Execute (ALEInfo should return appropriately named global variables):
\ ' Current Filetype: testft.testft2',
\ 'Available Linters: [''testlinter1'', ''testlinter2'']',
\ ' Enabled Linters: [''testlinter1'', ''testlinter2'']',
+ \ ' Ignored Linters: []',
\ ]
\ + g:fixer_lines
\ + [
@@ -420,6 +435,7 @@ Execute (ALEInfoToFile should write to a file correctly):
\ ' Current Filetype: testft.testft2',
\ 'Available Linters: [''testlinter1'', ''testlinter2'']',
\ ' Enabled Linters: [''testlinter1'', ''testlinter2'']',
+ \ ' Ignored Linters: []',
\ ]
\ + g:fixer_lines
\ + [
@@ -447,6 +463,7 @@ Execute (ALEInfo should buffer-local linter variables):
\ ' Current Filetype: testft.testft2',
\ 'Available Linters: [''testlinter1'', ''testlinter2'']',
\ ' Enabled Linters: [''testlinter1'', ''testlinter2'']',
+ \ ' Ignored Linters: []',
\ ]
\ + g:fixer_lines
\ + [
@@ -478,6 +495,7 @@ Execute (ALEInfo should output linter aliases):
\ '''testlinter1'' -> [''testftalias1'', ''testftalias2'']',
\ '''testlinter2'' -> [''testftalias3'', ''testftalias4'']',
\ ' Enabled Linters: [''testlinter1'', ''testlinter2'']',
+ \ ' Ignored Linters: []',
\ ]
\ + g:fixer_lines
\ + [
@@ -505,6 +523,7 @@ Execute (ALEInfo should return command history):
\ ' Current Filetype: testft.testft2',
\ 'Available Linters: [''testlinter1'', ''testlinter2'']',
\ ' Enabled Linters: [''testlinter1'', ''testlinter2'']',
+ \ ' Ignored Linters: []',
\ ]
\ + g:fixer_lines
\ + g:variables_lines
@@ -532,6 +551,7 @@ Execute (ALEInfo command history should print exit codes correctly):
\ ' Current Filetype: testft.testft2',
\ 'Available Linters: [''testlinter1'', ''testlinter2'']',
\ ' Enabled Linters: [''testlinter1'', ''testlinter2'']',
+ \ ' Ignored Linters: []',
\ ]
\ + g:fixer_lines
\ + g:variables_lines
@@ -580,6 +600,7 @@ Execute (ALEInfo command history should print command output if logging is on):
\ ' Current Filetype: testft.testft2',
\ 'Available Linters: [''testlinter1'', ''testlinter2'']',
\ ' Enabled Linters: [''testlinter1'', ''testlinter2'']',
+ \ ' Ignored Linters: []',
\ ]
\ + g:fixer_lines
\ + g:variables_lines
@@ -618,6 +639,7 @@ Execute (ALEInfo should include executable checks in the history):
\ ' Current Filetype: testft.testft2',
\ 'Available Linters: [''testlinter1'']',
\ ' Enabled Linters: [''testlinter1'']',
+ \ ' Ignored Linters: []',
\ ]
\ + g:fixer_lines
\ + g:variables_lines
@@ -647,6 +669,7 @@ Execute (The option for caching failing executable checks should work):
\ ' Current Filetype: testft.testft2',
\ 'Available Linters: [''testlinter1'']',
\ ' Enabled Linters: [''testlinter1'']',
+ \ ' Ignored Linters: []',
\ ]
\ + g:fixer_lines
\ + g:variables_lines
@@ -669,6 +692,7 @@ Execute (LSP errors for a linter should be outputted):
\ ' Current Filetype: testft',
\ 'Available Linters: [''testlinter1'']',
\ ' Enabled Linters: [''testlinter1'']',
+ \ ' Ignored Linters: []',
\ ]
\ + g:fixer_lines
\ + g:variables_lines
@@ -693,6 +717,7 @@ Execute (LSP errors for other linters shouldn't appear):
\ ' Current Filetype: testft',
\ 'Available Linters: [''testlinter1'']',
\ ' Enabled Linters: [''testlinter1'']',
+ \ ' Ignored Linters: []',
\ ]
\ + g:fixer_lines
\ + g:variables_lines
@@ -715,6 +740,7 @@ Execute (ALEInfo should include linter global options):
\ ' Current Filetype: testft.testft2',
\ 'Available Linters: [''testlinter1'', ''testlinter2'']',
\ ' Enabled Linters: [''testlinter1'', ''testlinter2'']',
+ \ ' Ignored Linters: []',
\ ]
\ + g:fixer_lines
\ + g:variables_lines
@@ -740,6 +766,7 @@ Execute (ALEInfo should include linter global options for enabled linters):
\ ' Current Filetype: testft',
\ 'Available Linters: [''testlinter1'', ''testlinter2'']',
\ ' Enabled Linters: [''testlinter1'']',
+ \ ' Ignored Linters: []',
\ ]
\ + g:fixer_lines
\ + g:variables_lines
diff --git a/test/test_ale_lint_stop_command.vader b/test/test_ale_lint_stop_command.vader
new file mode 100644
index 00000000..c50db5a8
--- /dev/null
+++ b/test/test_ale_lint_stop_command.vader
@@ -0,0 +1,27 @@
+Before:
+ Save g:ale_buffer_info
+
+ let g:ale_buffer_info = {}
+
+ call ale#linter#PreventLoading('testft')
+ call ale#linter#Define('testft', {
+ \ 'name': 'testlinter',
+ \ 'callback': {-> []},
+ \ 'executable': has('win32') ? 'cmd' : 'true',
+ \ 'command': 'sleep 9001',
+ \})
+
+After:
+ Restore
+
+ call ale#linter#Reset()
+
+Given testft (An empty file):
+Execute(ALELintStop should stop ALE from linting):
+ ALELint
+
+ Assert ale#engine#IsCheckingBuffer(bufnr('')), 'ALE did not start checking the buffer'
+
+ ALELintStop
+
+ Assert !ale#engine#IsCheckingBuffer(bufnr('')), 'ALELintStop didn''t work'
diff --git a/test/test_code_action.vader b/test/test_code_action.vader
index 19de7268..7eabb759 100644
--- a/test/test_code_action.vader
+++ b/test/test_code_action.vader
@@ -3,6 +3,9 @@ Before:
let g:ale_enabled = 0
+ " Enable fix end-of-line as tests below expect that
+ set fixeol
+
runtime autoload/ale/code_action.vim
runtime autoload/ale/util.vim
@@ -85,7 +88,8 @@ Execute(It should modify and save multiple files):
\ 'import D from "D"',
\], g:file2, 'S')
- call ale#code_action#HandleCodeAction({
+ call ale#code_action#HandleCodeAction(
+ \ {
\ 'changes': [{
\ 'fileName': g:file1,
\ 'textChanges': [{
@@ -122,8 +126,10 @@ Execute(It should modify and save multiple files):
\ },
\ 'newText': "import {A, B} from 'module'\n\n",
\ }]
- \ }],
- \}, v:true)
+ \ }],
+ \ },
+ \ {'should_save': 1},
+ \)
AssertEqual [
\ 'class Value {',
@@ -153,7 +159,8 @@ Execute(Beginning of file can be modified):
\]
call writefile(g:test.text, g:file1, 'S')
- call ale#code_action#HandleCodeAction({
+ call ale#code_action#HandleCodeAction(
+ \ {
\ 'changes': [{
\ 'fileName': g:file1,
\ 'textChanges': [{
@@ -168,7 +175,9 @@ Execute(Beginning of file can be modified):
\ 'newText': "type A: string\ntype B: number\n",
\ }],
\ }]
- \}, v:true)
+ \ },
+ \ {'should_save': 1},
+ \)
AssertEqual [
\ 'type A: string',
@@ -184,24 +193,28 @@ Execute(End of file can be modified):
\]
call writefile(g:test.text, g:file1, 'S')
- call ale#code_action#HandleCodeAction({
+ call ale#code_action#HandleCodeAction(
+ \ {
\ 'changes': [{
- \ 'fileName': g:file1,
- \ 'textChanges': [{
- \ 'start': {
- \ 'line': 4,
- \ 'offset': 1,
- \ },
- \ 'end': {
- \ 'line': 4,
- \ 'offset': 1,
- \ },
- \ 'newText': "type A: string\ntype B: number\n",
- \ }],
+ \ 'fileName': g:file1,
+ \ 'textChanges': [{
+ \ 'start': {
+ \ 'line': 4,
+ \ 'offset': 1,
+ \ },
+ \ 'end': {
+ \ 'line': 4,
+ \ 'offset': 1,
+ \ },
+ \ 'newText': "type A: string\ntype B: number\n",
+ \ }],
\ }]
- \}, v:true)
+ \ },
+ \ {'should_save': 1},
+ \)
AssertEqual g:test.text + [
+ \ '',
\ 'type A: string',
\ 'type B: number',
\ '',
@@ -219,7 +232,8 @@ Execute(Current buffer contents will be reloaded):
execute 'edit ' . g:file1
let g:test.buffer = bufnr(g:file1)
- call ale#code_action#HandleCodeAction({
+ call ale#code_action#HandleCodeAction(
+ \ {
\ 'changes': [{
\ 'fileName': g:file1,
\ 'textChanges': [{
@@ -234,7 +248,9 @@ Execute(Current buffer contents will be reloaded):
\ 'newText': "type A: string\ntype B: number\n",
\ }],
\ }]
- \}, v:true)
+ \ },
+ \ {'should_save': 1},
+ \)
AssertEqual [
\ 'type A: string',
@@ -256,11 +272,11 @@ Execute(Cursor will not move when it is before text change):
let g:test.changes = g:test.create_change(2, 3, 2, 8, 'value2')
call setpos('.', [0, 1, 1, 0])
- call ale#code_action#HandleCodeAction(g:test.changes, v:true)
+ call ale#code_action#HandleCodeAction(g:test.changes, {'should_save': 1})
AssertEqual [1, 1], getpos('.')[1:2]
call setpos('.', [0, 2, 2, 0])
- call ale#code_action#HandleCodeAction(g:test.changes, v:true)
+ call ale#code_action#HandleCodeAction(g:test.changes, {'should_save': 1})
AssertEqual [2, 2], getpos('.')[1:2]
# ====C====
@@ -271,7 +287,7 @@ Execute(Cursor column will move to the change end when cursor between start/end)
call WriteFileAndEdit()
call setpos('.', [0, 2, r, 0])
AssertEqual ' value: string', getline('.')
- call ale#code_action#HandleCodeAction(g:test.changes, v:true)
+ call ale#code_action#HandleCodeAction(g:test.changes, {'should_save': 1})
AssertEqual ' value2: string', getline('.')
AssertEqual [2, 9], getpos('.')[1:2]
endfor
@@ -283,7 +299,9 @@ Execute(Cursor column will move back when new text is shorter):
call setpos('.', [0, 2, 8, 0])
AssertEqual ' value: string', getline('.')
call ale#code_action#HandleCodeAction(
- \ g:test.create_change(2, 3, 2, 8, 'val'), v:true)
+ \ g:test.create_change(2, 3, 2, 8, 'val'),
+ \ {'should_save': 1},
+ \)
AssertEqual ' val: string', getline('.')
AssertEqual [2, 6], getpos('.')[1:2]
@@ -295,7 +313,7 @@ Execute(Cursor column will move forward when new text is longer):
call setpos('.', [0, 2, 8, 0])
AssertEqual ' value: string', getline('.')
call ale#code_action#HandleCodeAction(
- \ g:test.create_change(2, 3, 2, 8, 'longValue'), v:true)
+ \ g:test.create_change(2, 3, 2, 8, 'longValue'), {'should_save': 1})
AssertEqual ' longValue: string', getline('.')
AssertEqual [2, 12], getpos('.')[1:2]
@@ -307,7 +325,7 @@ Execute(Cursor line will move when updates are happening on lines above):
call setpos('.', [0, 3, 1, 0])
AssertEqual '}', getline('.')
call ale#code_action#HandleCodeAction(
- \ g:test.create_change(1, 1, 2, 1, "test\ntest\n"), v:true)
+ \ g:test.create_change(1, 1, 2, 1, "test\ntest\n"), {'should_save': 1})
AssertEqual '}', getline('.')
AssertEqual [4, 1], getpos('.')[1:2]
@@ -319,7 +337,7 @@ Execute(Cursor line and column will move when change on lines above and just bef
call setpos('.', [0, 2, 2, 0])
AssertEqual ' value: string', getline('.')
call ale#code_action#HandleCodeAction(
- \ g:test.create_change(1, 1, 2, 1, "test\ntest\n123"), v:true)
+ \ g:test.create_change(1, 1, 2, 1, "test\ntest\n123"), {'should_save': 1})
AssertEqual '123 value: string', getline('.')
AssertEqual [3, 5], getpos('.')[1:2]
@@ -331,7 +349,7 @@ Execute(Cursor line and column will move at the end of changes):
call setpos('.', [0, 2, 10, 0])
AssertEqual ' value: string', getline('.')
call ale#code_action#HandleCodeAction(
- \ g:test.create_change(1, 1, 3, 1, "test\n"), v:true)
+ \ g:test.create_change(1, 1, 3, 1, "test\n"), {'should_save': 1})
AssertEqual '}', getline('.')
AssertEqual [2, 1], getpos('.')[1:2]
@@ -342,14 +360,14 @@ Execute(Cursor will not move when changes happening on lines >= cursor, but afte
call setpos('.', [0, 2, 3, 0])
AssertEqual ' value: string', getline('.')
call ale#code_action#HandleCodeAction(
- \ g:test.create_change(2, 10, 3, 1, "number\n"), v:true)
+ \ g:test.create_change(2, 10, 3, 1, "number\n"), {'should_save': 1})
AssertEqual ' value: number', getline('.')
AssertEqual [2, 3], getpos('.')[1:2]
Execute(It should just modify file when should_save is set to v:false):
call WriteFileAndEdit()
let g:test.change = g:test.create_change(1, 1, 1, 1, "import { writeFile } from 'fs';\n")
- call ale#code_action#HandleCodeAction(g:test.change, v:false)
+ call ale#code_action#HandleCodeAction(g:test.change, {})
AssertEqual 1, getbufvar(bufnr(''), '&modified')
AssertEqual [
\ 'import { writeFile } from ''fs'';',
diff --git a/test/test_code_action_python.vader b/test/test_code_action_python.vader
new file mode 100644
index 00000000..fd30633d
--- /dev/null
+++ b/test/test_code_action_python.vader
@@ -0,0 +1,59 @@
+Given python(An example Python file):
+ def main():
+ a = 1
+ c = a + 1
+
+Execute():
+ let g:changes = [
+ \ {'end': {'offset': 7, 'line': 1}, 'newText': 'func_qtffgsv', 'start': {'offset': 5, 'line': 1}},
+ \ {'end': {'offset': 9, 'line': 1}, 'newText': '', 'start': {'offset': 8, 'line': 1}},
+ \ {'end': {'offset': 15, 'line': 3}, 'newText': " return c\n\n\ndef main():\n c = func_qtffgsvi()\n", 'start': {'offset': 15, 'line': 3}}
+ \]
+
+ call ale#code_action#ApplyChanges(expand('%:p'), g:changes, 0)
+
+Expect(The changes should be applied correctly):
+ def func_qtffgsvi():
+ a = 1
+ c = a + 1
+ return c
+
+
+ def main():
+ c = func_qtffgsvi()
+
+
+Given python(Second python example):
+ import sys
+ import exifread
+
+ def main():
+ with open(sys.argv[1], 'rb') as f:
+ exif = exifread.process_file(f)
+ dt = str(exif['Image DateTime'])
+ date = dt[:10].replace(':', '-')
+
+Execute():
+ let g:changes = [
+ \ {'end': {'offset': 16, 'line': 2}, 'newText': "\n\ndef func_ivlpdpao(f):\n exif = exifread.process_file(f)\n dt = str(exif['Image DateTime'])\n date = dt[:10].replace(':', '-')\n return date\n", 'start': {'offset': 16, 'line': 2}},
+ \ {'end': {'offset': 32, 'line': 6}, 'newText': 'date = func', 'start': {'offset': 9, 'line': 6}},
+ \ {'end': {'offset': 42, 'line': 8}, 'newText': "ivlpdpao(f)\n", 'start': {'offset': 33, 'line': 6}}
+ \]
+
+ call ale#code_action#ApplyChanges(expand('%:p'), g:changes, 0)
+
+Expect(The changes should be applied correctly):
+ import sys
+ import exifread
+
+
+ def func_ivlpdpao(f):
+ exif = exifread.process_file(f)
+ dt = str(exif['Image DateTime'])
+ date = dt[:10].replace(':', '-')
+ return date
+
+
+ def main():
+ with open(sys.argv[1], 'rb') as f:
+ date = func_ivlpdpao(f)
diff --git a/test/test_codefix.vader b/test/test_codefix.vader
new file mode 100644
index 00000000..fc5470aa
--- /dev/null
+++ b/test/test_codefix.vader
@@ -0,0 +1,549 @@
+Before:
+ call ale#test#SetDirectory('/testplugin/test')
+ call ale#test#SetFilename('dummy.txt')
+ Save g:ale_buffer_info
+
+ let g:ale_buffer_info = {}
+
+ let g:old_filename = expand('%:p')
+ let g:Callback = ''
+ let g:expr_list = []
+ let g:message_list = []
+ let g:handle_code_action_called = 0
+ let g:code_actions = []
+ let g:options = {}
+ let g:capability_checked = ''
+ let g:conn_id = v:null
+ let g:InitCallback = v:null
+
+ runtime autoload/ale/lsp_linter.vim
+ runtime autoload/ale/lsp.vim
+ runtime autoload/ale/util.vim
+ runtime autoload/ale/codefix.vim
+ runtime autoload/ale/code_action.vim
+
+ function! ale#lsp_linter#StartLSP(buffer, linter, Callback) abort
+ let g:conn_id = ale#lsp#Register('executable', '/foo/bar', {})
+ call ale#lsp#MarkDocumentAsOpen(g:conn_id, a:buffer)
+
+ if a:linter.lsp is# 'tsserver'
+ call ale#lsp#MarkConnectionAsTsserver(g:conn_id)
+ endif
+
+ let l:details = {
+ \ 'command': 'foobar',
+ \ 'buffer': a:buffer,
+ \ 'connection_id': g:conn_id,
+ \ 'project_root': '/foo/bar',
+ \}
+
+ let g:InitCallback = {-> ale#lsp_linter#OnInit(a:linter, l:details, a:Callback)}
+ endfunction
+
+ function! ale#lsp#HasCapability(conn_id, capability) abort
+ let g:capability_checked = a:capability
+
+ return 1
+ endfunction
+
+ function! ale#lsp#RegisterCallback(conn_id, callback) abort
+ let g:Callback = a:callback
+ endfunction
+
+ function! ale#lsp#Send(conn_id, message) abort
+ call add(g:message_list, a:message)
+
+ return 42
+ endfunction
+
+ function! ale#util#Execute(expr) abort
+ call add(g:expr_list, a:expr)
+ endfunction
+
+ function! ale#code_action#HandleCodeAction(code_action, options) abort
+ let g:handle_code_action_called = 1
+ Assert !get(a:options, 'should_save')
+ call add(g:code_actions, a:code_action)
+ endfunction
+
+ function! ale#util#Input(message, value) abort
+ return '2'
+ endfunction
+
+After:
+ Restore
+
+ if g:conn_id isnot v:null
+ call ale#lsp#RemoveConnectionWithID(g:conn_id)
+ endif
+
+ call ale#test#RestoreDirectory()
+ call ale#linter#Reset()
+
+ unlet! g:capability_checked
+ unlet! g:InitCallback
+ unlet! g:old_filename
+ unlet! g:conn_id
+ unlet! g:Callback
+ unlet! g:message_list
+ unlet! g:expr_list
+ unlet! b:ale_linters
+ unlet! g:options
+ unlet! g:code_actions
+ unlet! g:handle_code_action_called
+
+ runtime autoload/ale/lsp_linter.vim
+ runtime autoload/ale/lsp.vim
+ runtime autoload/ale/util.vim
+ runtime autoload/ale/codefix.vim
+ runtime autoload/ale/code_action.vim
+
+Execute(Failed codefix responses should be handled correctly):
+ call ale#codefix#HandleTSServerResponse(
+ \ 1,
+ \ {'command': 'getCodeFixes', 'request_seq': 3}
+ \)
+ AssertEqual g:handle_code_action_called, 0
+
+Given typescript(Some typescript file):
+ foo
+ somelongerline ()
+ bazxyzxyzxyz
+
+Execute(getCodeFixes from tsserver should be handled):
+ call ale#codefix#SetMap({3: {}})
+ call ale#codefix#HandleTSServerResponse(1, {
+ \ 'command': 'getCodeFixes',
+ \ 'request_seq': 3,
+ \ 'success': v:true,
+ \ 'type': 'response',
+ \ 'body': [
+ \ {
+ \ 'description': 'Import default "x" from module "./z"',
+ \ 'fixName': 'import',
+ \ 'changes': [
+ \ {
+ \ 'fileName': "/foo/bar/file1.ts",
+ \ 'textChanges': [
+ \ {
+ \ 'end': {
+ \ 'line': 2,
+ \ 'offset': 1,
+ \ },
+ \ 'newText': 'import x from "./z";^@',
+ \ 'start': {
+ \ 'line': 2,
+ \ 'offset': 1,
+ \ }
+ \ }
+ \ ]
+ \ }
+ \ ]
+ \ }
+ \ ]
+ \})
+
+ AssertEqual g:handle_code_action_called, 1
+ AssertEqual
+ \ [
+ \ {
+ \ 'description': 'codefix',
+ \ 'changes': [
+ \ {
+ \ 'fileName': "/foo/bar/file1.ts",
+ \ 'textChanges': [
+ \ {
+ \ 'end': {
+ \ 'line': 2,
+ \ 'offset': 1
+ \ },
+ \ 'newText': 'import x from "./z";^@',
+ \ 'start': {
+ \ 'line': 2,
+ \ 'offset': 1
+ \ }
+ \ }
+ \ ]
+ \ }
+ \ ]
+ \ }
+ \ ],
+ \ g:code_actions
+
+Execute(getCodeFixes from tsserver should be handled with user input if there are more than one action):
+ call ale#codefix#SetMap({3: {}})
+ call ale#codefix#HandleTSServerResponse(1, {
+ \ 'command': 'getCodeFixes',
+ \ 'request_seq': 3,
+ \ 'success': v:true,
+ \ 'type': 'response',
+ \ 'body': [
+ \ {
+ \ 'description': 'Import default "x" from module "./z"',
+ \ 'fixName': 'import',
+ \ 'changes': [
+ \ {
+ \ 'fileName': "/foo/bar/file1.ts",
+ \ 'textChanges': [
+ \ {
+ \ 'end': {
+ \ 'line': 2,
+ \ 'offset': 1,
+ \ },
+ \ 'newText': 'import x from "./z";^@',
+ \ 'start': {
+ \ 'line': 2,
+ \ 'offset': 1,
+ \ }
+ \ }
+ \ ]
+ \ }
+ \ ]
+ \ },
+ \ {
+ \ 'description': 'Import default "x" from module "./y"',
+ \ 'fixName': 'import',
+ \ 'changes': [
+ \ {
+ \ 'fileName': "/foo/bar/file1.ts",
+ \ 'textChanges': [
+ \ {
+ \ 'end': {
+ \ 'line': 2,
+ \ 'offset': 1,
+ \ },
+ \ 'newText': 'import x from "./y";^@',
+ \ 'start': {
+ \ 'line': 2,
+ \ 'offset': 1,
+ \ }
+ \ }
+ \ ]
+ \ }
+ \ ]
+ \ }
+ \ ]
+ \})
+
+ AssertEqual g:handle_code_action_called, 1
+ AssertEqual
+ \ [
+ \ {
+ \ 'description': 'codefix',
+ \ 'changes': [
+ \ {
+ \ 'fileName': "/foo/bar/file1.ts",
+ \ 'textChanges': [
+ \ {
+ \ 'end': {
+ \ 'line': 2,
+ \ 'offset': 1
+ \ },
+ \ 'newText': 'import x from "./y";^@',
+ \ 'start': {
+ \ 'line': 2,
+ \ 'offset': 1
+ \ }
+ \ }
+ \ ]
+ \ }
+ \ ]
+ \ }
+ \ ],
+ \ g:code_actions
+
+Execute(Prints a tsserver error message when getCodeFixes unsuccessful):
+ call ale#codefix#SetMap({3: {}})
+ call ale#codefix#HandleTSServerResponse(1, {
+ \ 'command': 'getCodeFixes',
+ \ 'request_seq': 3,
+ \ 'success': v:false,
+ \ 'message': 'something is wrong',
+ \})
+
+ AssertEqual g:handle_code_action_called, 0
+ AssertEqual ['echom ''Error while getting code fixes. Reason: something is wrong'''], g:expr_list
+
+Execute(Does nothing when where are no code fixes):
+ call ale#codefix#SetMap({3: {}})
+ call ale#codefix#HandleTSServerResponse(1, {
+ \ 'command': 'getCodeFixes',
+ \ 'request_seq': 3,
+ \ 'success': v:true,
+ \ 'body': []
+ \})
+
+ AssertEqual g:handle_code_action_called, 0
+ AssertEqual ['echom ''No code fixes available.'''], g:expr_list
+
+Execute(tsserver codefix requests should be sent):
+ call ale#linter#Reset()
+
+ runtime ale_linters/typescript/tsserver.vim
+ let g:ale_buffer_info = {bufnr(''): {'loclist': [{'lnum': 2, 'col': 5, 'code': 2304}]}}
+ call setpos('.', [bufnr(''), 2, 16, 0])
+
+ " ALECodeAction
+ call ale#codefix#Execute(0)
+
+ " We shouldn't register the callback yet.
+ AssertEqual '''''', string(g:Callback)
+
+ AssertEqual type(function('type')), type(g:InitCallback)
+ call g:InitCallback()
+
+ AssertEqual 'code_actions', g:capability_checked
+ AssertEqual
+ \ 'function(''ale#codefix#HandleTSServerResponse'')',
+ \ string(g:Callback)
+ AssertEqual
+ \ [
+ \ ale#lsp#tsserver_message#Change(bufnr('')),
+ \ [0, 'ts@getCodeFixes', {
+ \ 'startLine': 2,
+ \ 'startOffset': 16,
+ \ 'endLine': 2,
+ \ 'endOffset': 17,
+ \ 'file': expand('%:p'),
+ \ 'errorCodes': [2304],
+ \ }]
+ \ ],
+ \ g:message_list
+
+Execute(tsserver codefix requests should be sent only for error with code):
+ call ale#linter#Reset()
+
+ runtime ale_linters/typescript/tsserver.vim
+ let g:ale_buffer_info = {bufnr(''): {'loclist': [{'lnum': 2, 'col': 16}, {'lnum': 2, 'col': 16, 'code': 2304}]}}
+ call setpos('.', [bufnr(''), 2, 16, 0])
+
+ " ALECodeAction
+ call ale#codefix#Execute(0)
+
+ " We shouldn't register the callback yet.
+ AssertEqual '''''', string(g:Callback)
+
+ AssertEqual type(function('type')), type(g:InitCallback)
+ call g:InitCallback()
+
+ AssertEqual 'code_actions', g:capability_checked
+ AssertEqual
+ \ 'function(''ale#codefix#HandleTSServerResponse'')',
+ \ string(g:Callback)
+ AssertEqual
+ \ [
+ \ ale#lsp#tsserver_message#Change(bufnr('')),
+ \ [0, 'ts@getCodeFixes', {
+ \ 'startLine': 2,
+ \ 'startOffset': 16,
+ \ 'endLine': 2,
+ \ 'endOffset': 17,
+ \ 'file': expand('%:p'),
+ \ 'errorCodes': [2304],
+ \ }]
+ \ ],
+ \ g:message_list
+
+Execute(getApplicableRefactors from tsserver should be handled):
+ call ale#codefix#SetMap({3: {
+ \ 'buffer': expand('%:p'),
+ \ 'line': 1,
+ \ 'column': 2,
+ \ 'end_line': 3,
+ \ 'end_column': 4,
+ \ 'connection_id': 0,
+ \}})
+ call ale#codefix#HandleTSServerResponse(1,
+ \ {'seq': 0, 'request_seq': 3, 'type': 'response', 'success': v:true, 'body': [{'actions': [{'description': 'Extract to constant in enclosing scope', 'name': 'constant_scope_0'}], 'description': 'Extract constant', 'name': 'Extract Symbol'}, {'actions': [{'description': 'Extract to function in module scope', 'name': 'function_scope_1'}], 'description': 'Extract function', 'name': 'Extract Symbol'}], 'command': 'getApplicableRefactors'})
+
+ AssertEqual
+ \ [
+ \ [0, 'ts@getEditsForRefactor', {
+ \ 'startLine': 1,
+ \ 'startOffset': 2,
+ \ 'endLine': 3,
+ \ 'endOffset': 5,
+ \ 'file': expand('%:p'),
+ \ 'refactor': 'Extract Symbol',
+ \ 'action': 'function_scope_1',
+ \ }]
+ \ ],
+ \ g:message_list
+
+Execute(getApplicableRefactors should print error on failure):
+ call ale#codefix#SetMap({3: {
+ \ 'buffer': expand('%:p'),
+ \ 'line': 1,
+ \ 'column': 2,
+ \ 'end_line': 3,
+ \ 'end_column': 4,
+ \ 'connection_id': 0,
+ \}})
+ call ale#codefix#HandleTSServerResponse(1,
+ \ {'seq': 0, 'request_seq': 3, 'type': 'response', 'success': v:false, 'message': 'oops', 'command': 'getApplicableRefactors'})
+
+ AssertEqual ['echom ''Error while getting applicable refactors. Reason: oops'''], g:expr_list
+
+Execute(getApplicableRefactors should do nothing if there are no refactors):
+ call ale#codefix#SetMap({3: {
+ \ 'buffer': expand('%:p'),
+ \ 'line': 1,
+ \ 'column': 2,
+ \ 'end_line': 3,
+ \ 'end_column': 4,
+ \ 'connection_id': 0,
+ \}})
+ call ale#codefix#HandleTSServerResponse(1,
+ \ {'seq': 0, 'request_seq': 3, 'type': 'response', 'success': v:true, 'body': [], 'command': 'getApplicableRefactors'})
+
+ AssertEqual ['echom ''No applicable refactors available.'''], g:expr_list
+
+Execute(getEditsForRefactor from tsserver should be handled):
+ call ale#codefix#SetMap({3: {}})
+ call ale#codefix#HandleTSServerResponse(1,
+ \{'seq': 0, 'request_seq': 3, 'type': 'response', 'success': v:true, 'body': {'edits': [{'fileName': '/foo/bar/file.ts', 'textChanges': [{'end': {'offset': 35, 'line': 9}, 'newText': 'newFunction(app);', 'start': {'offset': 3, 'line': 8}}, {'end': {'offset': 4, 'line': 19}, 'newText': '^@function newFunction(app: Router) {^@ app.use(booExpressCsrf());^@ app.use(booExpressRequireHttps);^@}^@', 'start': {'offset': 4, 'line': 19}}]}], 'renameLocation': {'offset': 3, 'line': 8}, 'renameFilename': '/foo/bar/file.ts'}, 'command': 'getEditsForRefactor' }
+ \)
+
+ AssertEqual g:handle_code_action_called, 1
+ AssertEqual
+ \ [
+ \ {
+ \ 'description': 'editsForRefactor',
+ \ 'changes': [{'fileName': '/foo/bar/file.ts', 'textChanges': [{'end': {'offset': 35, 'line': 9}, 'newText': 'newFunction(app);', 'start': {'offset': 3, 'line': 8}}, {'end': {'offset': 4, 'line': 19}, 'newText': '^@function newFunction(app: Router) {^@ app.use(booExpressCsrf());^@ app.use(booExpressRequireHttps);^@}^@', 'start': {'offset': 4, 'line': 19}}]}],
+ \ }
+ \ ],
+ \ g:code_actions
+
+Execute(getEditsForRefactor should print error on failure):
+ call ale#codefix#SetMap({3: {}})
+ call ale#codefix#HandleTSServerResponse(1,
+ \{'seq': 0, 'request_seq': 3, 'type': 'response', 'success': v:false, 'message': 'oops', 'command': 'getEditsForRefactor' }
+ \)
+
+ AssertEqual ['echom ''Error while getting edits for refactor. Reason: oops'''], g:expr_list
+
+Execute(Failed LSP responses should be handled correctly):
+ call ale#codefix#HandleLSPResponse(
+ \ 1,
+ \ {'method': 'workspace/applyEdit', 'request_seq': 3}
+ \)
+ AssertEqual g:handle_code_action_called, 0
+
+Given python(Some python file):
+ def main():
+ a = 1
+ b = a + 2
+
+Execute("workspace/applyEdit" from LSP should be handled):
+ call ale#codefix#SetMap({3: {}})
+ call ale#codefix#HandleLSPResponse(1,
+ \ {'id': 0, 'jsonrpc': '2.0', 'method': 'workspace/applyEdit', 'params': {'edit': {'changes': {'file:///foo/bar/file.ts': [{'range': {'end': {'character': 27, 'line': 7}, 'start': {'character': 27, 'line': 7}}, 'newText': ', Config'}, {'range': {'end': {'character': 12, 'line': 96}, 'start': {'character': 2, 'line': 94}}, 'newText': 'await newFunction(redis, imageKey, cover, config);'}, {'range': {'end': {'character': 2, 'line': 99}, 'start': {'character': 2, 'line': 99}}, 'newText': '^@async function newFunction(redis: IRedis, imageKey: string, cover: Buffer, config: Config) {^@ try {^@ await redis.set(imageKey, cover, ''ex'', parseInt(config.coverKeyTTL, 10));^@ }^@ catch { }^@}^@'}]}}}})
+
+ AssertEqual g:handle_code_action_called, 1
+ AssertEqual
+ \ [{'description': 'applyEdit', 'changes': [{'fileName': '/foo/bar/file.ts', 'textChanges': [{'end': {'offset': 28, 'line': 8}, 'newText': ', Config', 'start': {'offset': 28, 'line': 8}}, {'end': {'offset': 13, 'line': 97}, 'newText': 'await newFunction(redis, imageKey, cover, config);', 'start': {'offset': 3, 'line': 95}}, {'end': {'offset': 3, 'line': 100}, 'newText': '^@async function newFunction(redis: IRedis, imageKey: string, cover: Buffer, config: Config) {^@ try {^@ await redis.set(imageKey, cover, ''ex'', parseInt(config.coverKeyTTL, 10));^@ }^@ catch { }^@}^@', 'start': {'offset': 3, 'line': 100}}]}]}],
+ \ g:code_actions
+
+Execute(Code Actions from LSP should be handled with user input if there are more than one action):
+ call ale#codefix#SetMap({2: {}})
+ call ale#codefix#HandleLSPResponse(1,
+ \ {'id': 2, 'jsonrpc': '2.0', 'result': [{'title': 'fake for testing'}, {'arguments': [{'documentChanges': [{'edits': [{'range': {'end': {'character': 31, 'line': 2}, 'start': {'character': 31, 'line': 2}}, 'newText': ', createVideo'}], 'textDocument': {'uri': 'file:///foo/bar/file.ts', 'version': 1}}]}], 'title': 'Add ''createVideo'' to existing import declaration from "./video"', 'command': '_typescript.applyWorkspaceEdit'}]})
+
+ AssertEqual g:handle_code_action_called, 1
+ AssertEqual
+ \ [{'description': 'codeaction', 'changes': [{'fileName': '/foo/bar/file.ts', 'textChanges': [{'end': {'offset': 32, 'line': 3}, 'newText': ', createVideo', 'start': {'offset': 32, 'line': 3}}]}]}],
+ \ g:code_actions
+
+Execute(Code Actions from LSP should be handled when returned with documentChanges):
+ call ale#codefix#SetMap({2: {}})
+ call ale#codefix#HandleLSPResponse(1,
+ \ {'id': 2, 'jsonrpc': '2.0', 'result': [{'diagnostics': v:null, 'edit': {'changes': v:null, 'documentChanges': [{'edits': [{'range': {'end': {'character': 4, 'line': 2}, 'start': {'character': 4, 'line': 1}}, 'newText': ''}, {'range': {'end': {'character': 9, 'line': 2}, 'start': {'character': 8, 'line': 2}}, 'newText': '(1)'}], 'textDocument': {'uri': 'file:///foo/bar/test.py', 'version': v:null}}]}, 'kind': 'refactor.inline', 'title': 'Inline variable', 'command': v:null}, {'diagnostics': v:null, 'edit': {'changes': v:null, 'documentChanges': [{'edits': [{'range': {'end': {'character': 0, 'line': 0}, 'start': {'character': 0, 'line': 0}}, 'newText': 'def func_bomdjnxh():^@ a = 1return a^@^@^@'}, {'range': {'end': {'character': 9, 'line': 1}, 'start': {'character': 8, 'line': 1}}, 'newText': 'func_bomdjnxh()^@'}], 'textDocument': {'uri': 'file:///foo/bar/test.py', 'version': v:null}}]}, 'kind': 'refactor.extract', 'title': 'Extract expression into function ''func_bomdjnxh''', 'command': v:null}]})
+
+ AssertEqual g:handle_code_action_called, 1
+ AssertEqual
+ \ [{'description': 'codeaction', 'changes': [{'fileName': '/foo/bar/test.py', 'textChanges': [{'end': {'offset': 1, 'line': 1}, 'newText': 'def func_bomdjnxh():^@ a = 1return a^@^@^@', 'start': {'offset': 1, 'line': 1}}, {'end': {'offset': 10, 'line': 2}, 'newText': 'func_bomdjnxh()^@', 'start': {'offset': 9, 'line': 2}}]}]}],
+ \ g:code_actions
+
+Execute(LSP Code Actions handles command responses):
+ call ale#codefix#SetMap({3: {
+ \ 'connection_id': 0,
+ \}})
+ call ale#codefix#HandleLSPResponse(1,
+ \ {'id': 3, 'jsonrpc': '2.0', 'result': [{'kind': 'refactor', 'title': 'Extract to inner function in function ''getVideo''', 'command': {'arguments': [{'file': '/foo/bar/file.ts', 'endOffset': 0, 'action': 'function_scope_0', 'startOffset': 1, 'startLine': 65, 'refactor': 'Extract Symbol', 'endLine': 68}], 'title': 'Extract to inner function in function ''getVideo''', 'command': '_typescript.applyRefactoring'}}, {'kind': 'refactor', 'title': 'Extract to function in module scope', 'command': {'arguments': [{'file': '/foo/bar/file.ts', 'endOffset': 0, 'action': 'function_scope_1', 'startOffset': 1, 'startLine': 65, 'refactor': 'Extract Symbol', 'endLine': 68}], 'title': 'Extract to function in module scope', 'command': '_typescript.applyRefactoring'}}]})
+
+ AssertEqual
+ \ [[0, 'workspace/executeCommand', {'arguments': [{'file': '/foo/bar/file.ts', 'action': 'function_scope_1', 'endOffset': 0, 'refactor': 'Extract Symbol', 'endLine': 68, 'startLine': 65, 'startOffset': 1}], 'command': '_typescript.applyRefactoring'}]],
+ \ g:message_list
+
+
+Execute(Prints message when LSP code action returns no results):
+ call ale#codefix#SetMap({3: {}})
+ call ale#codefix#HandleLSPResponse(1,
+ \ {'id': 3, 'jsonrpc': '2.0', 'result': []})
+
+ AssertEqual g:handle_code_action_called, 0
+ AssertEqual ['echom ''No code actions received from server'''], g:expr_list
+
+Execute(LSP code action requests should be sent):
+ call ale#linter#Reset()
+
+ runtime ale_linters/python/jedils.vim
+ let g:ale_buffer_info = {bufnr(''): {'loclist': [{'lnum': 2, 'col': 5, 'end_lnum': 2, 'end_col': 6, 'code': 2304, 'text': 'oops'}]}}
+ call setpos('.', [bufnr(''), 2, 5, 0])
+
+ " ALECodeAction
+ call ale#codefix#Execute(0)
+
+ " We shouldn't register the callback yet.
+ AssertEqual '''''', string(g:Callback)
+
+ AssertEqual type(function('type')), type(g:InitCallback)
+ call g:InitCallback()
+
+ AssertEqual 'code_actions', g:capability_checked
+ AssertEqual
+ \ 'function(''ale#codefix#HandleLSPResponse'')',
+ \ string(g:Callback)
+ AssertEqual
+ \ [
+ \ [0, 'textDocument/codeAction', {
+ \ 'context': {
+ \ 'diagnostics': [{'range': {'end': {'character': 6, 'line': 1}, 'start': {'character': 4, 'line': 1}}, 'code': 2304, 'message': 'oops'}]
+ \ },
+ \ 'range': {'end': {'character': 5, 'line': 1}, 'start': {'character': 4, 'line': 1}},
+ \ 'textDocument': {'uri': ale#path#ToURI(expand('%:p'))}
+ \ }]
+ \ ],
+ \ g:message_list[-1:]
+
+Execute(LSP code action requests should be sent only for error with code):
+ call ale#linter#Reset()
+
+ runtime ale_linters/python/jedils.vim
+ let g:ale_buffer_info = {bufnr(''): {'loclist': [{'lnum': 2, 'col': 5, 'end_lnum': 2, 'end_col': 6, 'code': 2304, 'text': 'oops'}]}}
+ call setpos('.', [bufnr(''), 2, 5, 0])
+
+ " ALECodeAction
+ call ale#codefix#Execute(0)
+
+ " We shouldn't register the callback yet.
+ AssertEqual '''''', string(g:Callback)
+
+ AssertEqual type(function('type')), type(g:InitCallback)
+ call g:InitCallback()
+
+ AssertEqual 'code_actions', g:capability_checked
+ AssertEqual
+ \ 'function(''ale#codefix#HandleLSPResponse'')',
+ \ string(g:Callback)
+ AssertEqual
+ \ [
+ \ [0, 'textDocument/codeAction', {
+ \ 'context': {
+ \ 'diagnostics': [{'range': {'end': {'character': 6, 'line': 1}, 'start': {'character': 4, 'line': 1}}, 'code': 2304, 'message': 'oops'}]
+ \ },
+ \ 'range': {'end': {'character': 5, 'line': 1}, 'start': {'character': 4, 'line': 1}},
+ \ 'textDocument': {'uri': ale#path#ToURI(expand('%:p'))}
+ \ }]
+ \ ],
+ \ g:message_list[-1:]
diff --git a/test/test_computed_lint_file_values.vader b/test/test_computed_lint_file_values.vader
index 399e96fe..ed0d4c0c 100644
--- a/test/test_computed_lint_file_values.vader
+++ b/test/test_computed_lint_file_values.vader
@@ -132,3 +132,19 @@ Execute(Linters where lint_file eventually evaluates to 1 shouldn't be run if we
call ale#test#FlushJobs()
AssertEqual [], ale#test#GetLoclistWithoutModule()
+
+Execute(Keeping computed lint_file jobs running should work):
+ AssertEqual 'testlinter2', ale#linter#Get('foobar')[1].name
+
+ call ale#engine#InitBufferInfo(bufnr(''))
+
+ call ale#engine#MarkLinterActive(
+ \ g:ale_buffer_info[bufnr('')],
+ \ ale#linter#Get('foobar')[1]
+ \)
+ call ale#engine#RunLinters(bufnr(''), ale#linter#Get('foobar'), 0)
+
+ Assert !empty(g:ale_buffer_info[bufnr('')].active_linter_list),
+ \ 'The active linter list was empty'
+ Assert ale#engine#IsCheckingBuffer(bufnr('')),
+ \ 'The IsCheckingBuffer function returned 0'
diff --git a/test/test_maven_build_classpath_command.vader b/test/test_maven_build_classpath_command.vader
new file mode 100644
index 00000000..2d8b38a5
--- /dev/null
+++ b/test/test_maven_build_classpath_command.vader
@@ -0,0 +1,48 @@
+Before:
+ Save $PATH
+ Save $PATHEXT
+
+ let $PATHEXT = '.'
+
+ call ale#test#SetDirectory('/testplugin/test')
+ runtime ale_linters/java/javac.vim
+ let g:expected_wrapper = ''
+ if has('unix')
+ let g:expected_wrapper = 'mvnw'
+ else
+ let g:expected_wrapper = 'mvnw.cmd'
+ endif
+
+After:
+ Restore
+
+ unlet! g:expected_wrapper
+
+ call ale#test#RestoreDirectory()
+ call ale#linter#Reset()
+
+Execute(Should use 'mvnw' in classpath command if available):
+ call ale#test#SetFilename('maven-test-files/maven-java-project/module1/src/main/java/dummy1.java')
+
+ AssertEqual
+ \ ale#path#CdString(ale#path#Simplify(g:dir . '/maven-test-files/maven-java-project/module1'))
+ \ . ale#path#Simplify(g:dir . '/maven-test-files/maven-java-project/module1/' . g:expected_wrapper)
+ \ . ' dependency:build-classpath',
+ \ ale#maven#BuildClasspathCommand(bufnr(''))
+
+Execute(Should use 'mvn' in classpath command if it is executable and 'mvnw' is unavailable):
+ call ale#test#SetFilename('maven-test-files/maven-java-project/module2/src/main/java/dummy2.java')
+ let $PATH .= (has('win32') ? ';' : ':')
+ \ . ale#path#Simplify(g:dir . '/maven-test-files')
+
+ AssertEqual
+ \ ale#path#CdString(ale#path#Simplify(g:dir . '/maven-test-files/maven-java-project/module2'))
+ \ . 'mvn dependency:build-classpath',
+ \ ale#maven#BuildClasspathCommand(bufnr(''))
+
+Execute(Should return empty string if maven cannot be executed):
+ call ale#test#SetFilename('maven-test-files/non-maven-project/src/main/java/dummy.java')
+
+ AssertEqual
+ \ '',
+ \ ale#maven#BuildClasspathCommand(bufnr(''))
diff --git a/test/test_maven_find_executable.vader b/test/test_maven_find_executable.vader
new file mode 100644
index 00000000..1d2f6da2
--- /dev/null
+++ b/test/test_maven_find_executable.vader
@@ -0,0 +1,46 @@
+Before:
+ Save $PATH
+ Save $PATHEXT
+
+ " Count the maven executable without .exe as executable on Windows
+ let $PATHEXT = '.'
+
+ call ale#test#SetDirectory('/testplugin/test')
+ runtime ale_linters/java/javac.vim
+ let g:expected_wrapper = ''
+ if has('unix')
+ let g:expected_wrapper = 'mvnw'
+ else
+ let g:expected_wrapper = 'mvnw.cmd'
+ endif
+
+After:
+ Restore
+
+ unlet! g:expected_wrapper
+
+ call ale#test#RestoreDirectory()
+ call ale#linter#Reset()
+
+Execute(Should return 'mvnw' if found in parent directory):
+ call ale#test#SetFilename('maven-test-files/maven-java-project/module1/src/main/java/dummy1.java')
+
+ AssertEqual
+ \ ale#path#Simplify(g:dir . '/maven-test-files/maven-java-project/module1/' . g:expected_wrapper),
+ \ ale#maven#FindExecutable(bufnr(''))
+
+Execute(Should return 'mvn' if 'mvnw' not found in parent directory):
+ call ale#test#SetFilename('maven-test-files/maven-java-project/module2/src/main/java/dummy2.java')
+ let $PATH .= (has('win32') ? ';' : ':')
+ \ . ale#path#Simplify(g:dir . '/maven-test-files')
+
+ AssertEqual
+ \ 'mvn',
+ \ ale#maven#FindExecutable(bufnr(''))
+
+Execute(Should return empty string if 'mvnw' not in parent directory and mvn not in path):
+ call ale#test#SetFilename('mvn-test-files/java-maven-project/module2/src/main/java/dummy2.java')
+
+ AssertEqual
+ \ '',
+ \ ale#gradle#FindExecutable(bufnr(''))
diff --git a/test/test_maven_find_project_root.vader b/test/test_maven_find_project_root.vader
new file mode 100644
index 00000000..3a2138d1
--- /dev/null
+++ b/test/test_maven_find_project_root.vader
@@ -0,0 +1,28 @@
+Before:
+ call ale#test#SetDirectory('/testplugin/test')
+ runtime ale_linters/kotlin/javac.vim
+
+After:
+ call ale#test#RestoreDirectory()
+ call ale#linter#Reset()
+
+Execute(Should return directory for 'mvnw' if found in parent directory):
+ call ale#test#SetFilename('maven-test-files/maven-java-project/module1/src/main/java/dummy1.java')
+
+ AssertEqual
+ \ ale#path#Simplify(g:dir . '/maven-test-files/maven-java-project/module1'),
+ \ ale#maven#FindProjectRoot(bufnr(''))
+
+Execute(Should return directory for 'pom.xml' if found in parent directory):
+ call ale#test#SetFilename('maven-test-files/maven-java-project/module2/src/main/java/dummy2.java')
+
+ AssertEqual
+ \ ale#path#Simplify(g:dir . '/maven-test-files/maven-java-project/module2'),
+ \ ale#maven#FindProjectRoot(bufnr(''))
+
+Execute(Should return empty string if maven files are not found in parent directory):
+ call ale#test#SetFilename('maven-test-files/non-maven-project/src/main/java/dummy.java')
+
+ AssertEqual
+ \ '',
+ \ ale#maven#FindProjectRoot(bufnr(''))
diff --git a/test/test_organize_imports.vader b/test/test_organize_imports.vader
index c51ff1c0..35cd99ff 100644
--- a/test/test_organize_imports.vader
+++ b/test/test_organize_imports.vader
@@ -57,9 +57,9 @@ Before:
call add(g:expr_list, a:expr)
endfunction
- function! ale#code_action#HandleCodeAction(code_action, should_save) abort
+ function! ale#code_action#HandleCodeAction(code_action, options) abort
let g:handle_code_action_called = 1
- AssertEqual v:false, a:should_save
+ Assert !get(a:options, 'should_save')
call add(g:code_actions, a:code_action)
endfunction
diff --git a/test/test_rename.vader b/test/test_rename.vader
index 34d9e32e..2e8b746e 100644
--- a/test/test_rename.vader
+++ b/test/test_rename.vader
@@ -57,9 +57,9 @@ Before:
call add(g:expr_list, a:expr)
endfunction
- function! ale#code_action#HandleCodeAction(code_action, should_save) abort
+ function! ale#code_action#HandleCodeAction(code_action, options) abort
let g:handle_code_action_called = 1
- AssertEqual v:true, a:should_save
+ Assert get(a:options, 'should_save')
call add(g:code_actions, a:code_action)
endfunction
@@ -269,7 +269,7 @@ Execute(tsserver rename requests should be sent):
\ }]
\ ],
\ g:message_list
- AssertEqual {'42': {'old_name': 'somelongerline', 'new_name': 'a-new-name'}},
+ AssertEqual {'42': {'old_name': 'somelongerline', 'new_name': 'a-new-name', 'force_save': 0}},
\ ale#rename#GetMap()
Given python(Some Python file):
@@ -470,7 +470,7 @@ Execute(LSP rename requests should be sent):
let b:ale_linters = ['pyls']
call setpos('.', [bufnr(''), 1, 5, 0])
- ALERename
+ ALERename!
" We shouldn't register the callback yet.
AssertEqual '''''', string(g:Callback)
@@ -500,5 +500,5 @@ Execute(LSP rename requests should be sent):
\ ],
\ g:message_list
- AssertEqual {'42': {'old_name': 'foo', 'new_name': 'a-new-name'}},
+ AssertEqual {'42': {'old_name': 'foo', 'new_name': 'a-new-name', 'force_save': 1}},
\ ale#rename#GetMap()