diff options
23 files changed, 283 insertions, 62 deletions
@@ -169,7 +169,7 @@ formatting. | reStructuredText | [alex](https://github.com/wooorm/alex) !!, [proselint](http://proselint.com/), [redpen](http://redpen.cc/), [rstcheck](https://github.com/myint/rstcheck), [vale](https://github.com/ValeLint/vale), [write-good](https://github.com/btford/write-good) | | Re:VIEW | [redpen](http://redpen.cc/) | | RPM spec | [rpmlint](https://github.com/rpm-software-management/rpmlint) (disabled by default; see `:help ale-integration-spec`) | -| Ruby | [brakeman](http://brakemanscanner.org/) !!, [rails_best_practices](https://github.com/flyerhzm/rails_best_practices) !!, [reek](https://github.com/troessner/reek), [rubocop](https://github.com/bbatsov/rubocop), [ruby](https://www.ruby-lang.org), [rufo](https://github.com/ruby-formatter/rufo), [solargraph]([solargraph](https://solargraph.org) | +| Ruby | [brakeman](http://brakemanscanner.org/) !!, [rails_best_practices](https://github.com/flyerhzm/rails_best_practices) !!, [reek](https://github.com/troessner/reek), [rubocop](https://github.com/bbatsov/rubocop), [ruby](https://www.ruby-lang.org), [rufo](https://github.com/ruby-formatter/rufo), [solargraph](https://solargraph.org) | | Rust | cargo !! (see `:help ale-integration-rust` for configuration instructions), [rls](https://github.com/rust-lang-nursery/rls), [rustc](https://www.rust-lang.org/), [rustfmt](https://github.com/rust-lang-nursery/rustfmt) | | SASS | [sass-lint](https://www.npmjs.com/package/sass-lint), [stylelint](https://github.com/stylelint/stylelint) | | SCSS | [prettier](https://github.com/prettier/prettier), [sass-lint](https://www.npmjs.com/package/sass-lint), [scss-lint](https://github.com/brigade/scss-lint), [stylelint](https://github.com/stylelint/stylelint) | diff --git a/ale_linters/julia/languageserver.vim b/ale_linters/julia/languageserver.vim index b6bf8e73..b5d90bff 100644 --- a/ale_linters/julia/languageserver.vim +++ b/ale_linters/julia/languageserver.vim @@ -6,7 +6,7 @@ call ale#Set('julia_executable', 'julia') function! ale_linters#julia#languageserver#GetCommand(buffer) abort let l:julia_executable = ale#Var(a:buffer, 'julia_executable') - let l:cmd_string = 'using LanguageServer; server = LanguageServer.LanguageServerInstance(STDIN, STDOUT, false); server.runlinter = true; run(server);' + let l:cmd_string = 'using LanguageServer; server = LanguageServer.LanguageServerInstance(stdin, stdout, false); server.runlinter = true; run(server);' return ale#Escape(l:julia_executable) . ' --startup-file=no --history-file=no -e ' . ale#Escape(l:cmd_string) endfunction diff --git a/ale_linters/ruby/solargraph.vim b/ale_linters/ruby/solargraph.vim index 2aad3af6..7ca0399f 100644 --- a/ale_linters/ruby/solargraph.vim +++ b/ale_linters/ruby/solargraph.vim @@ -1,20 +1,20 @@ " Author: Horacio Sanson - https://github.com/hsanson " Description: Solargraph Language Server https://solargraph.org/ +" +" Author: Devon Meunier <devon.meunier@gmail.com> +" Description: updated to use stdio -call ale#Set('ruby_solargraph_host', '127.0.0.1') -call ale#Set('ruby_solargraph_port', '7658') +call ale#Set('ruby_solargraph_executable', 'solargraph') -function! ale_linters#ruby#solargraph#GetAddress(buffer) abort - let l:host = ale#Var(a:buffer, 'ruby_solargraph_host') - let l:port = ale#Var(a:buffer, 'ruby_solargraph_port') - - return l:host . ':' . l:port +function! ale_linters#ruby#solargraph#GetCommand(buffer) abort + return '%e' . ale#Pad('stdio') endfunction call ale#linter#Define('ruby', { \ 'name': 'solargraph', -\ 'lsp': 'socket', -\ 'address_callback': 'ale_linters#ruby#solargraph#GetAddress', +\ 'lsp': 'stdio', \ 'language': 'ruby', -\ 'project_root_callback': 'ale#ruby#FindProjectRoot' +\ 'executable_callback': ale#VarFunc('ruby_solargraph_executable'), +\ 'command_callback': 'ale_linters#ruby#solargraph#GetCommand', +\ 'project_root_callback': 'ale#ruby#FindProjectRoot', \}) diff --git a/ale_linters/thrift/thrift.vim b/ale_linters/thrift/thrift.vim index 396a2355..36a8656e 100644 --- a/ale_linters/thrift/thrift.vim +++ b/ale_linters/thrift/thrift.vim @@ -2,7 +2,7 @@ call ale#Set('thrift_thrift_executable', 'thrift') call ale#Set('thrift_thrift_generators', ['cpp']) -call ale#Set('thrift_thrift_includes', []) +call ale#Set('thrift_thrift_includes', ['.']) call ale#Set('thrift_thrift_options', '-strict') function! ale_linters#thrift#thrift#GetCommand(buffer) abort diff --git a/autoload/ale/c.vim b/autoload/ale/c.vim index e7b43d88..ce59ae31 100644 --- a/autoload/ale/c.vim +++ b/autoload/ale/c.vim @@ -55,7 +55,7 @@ function! ale#c#ParseCFlags(path_prefix, cflag_line) abort " Check if cflag contained a '-' and should not have been splitted let l:option_list = split(l:option, '\zs') - if l:option_list[-1] isnot# ' ' + if len(l:option_list) > 0 && l:option_list[-1] isnot# ' ' continue endif diff --git a/autoload/ale/completion.vim b/autoload/ale/completion.vim index 2556d50c..9dd913f5 100644 --- a/autoload/ale/completion.vim +++ b/autoload/ale/completion.vim @@ -360,12 +360,18 @@ function! ale#completion#ParseLSPCompletions(response) abort let l:kind = 'v' endif + let l:doc = get(l:item, 'documentation', '') + + if type(l:doc) is v:t_dict && has_key(l:doc, 'value') + let l:doc = l:doc.value + endif + call add(l:results, { \ 'word': l:word, \ 'kind': l:kind, \ 'icase': 1, \ 'menu': get(l:item, 'detail', ''), - \ 'info': get(l:item, 'documentation', ''), + \ 'info': (type(l:doc) is v:t_string ? l:doc : ''), \}) endfor diff --git a/autoload/ale/engine.vim b/autoload/ale/engine.vim index b6c2d3c9..05db0e49 100644 --- a/autoload/ale/engine.vim +++ b/autoload/ale/engine.vim @@ -18,6 +18,22 @@ if !has_key(s:, 'executable_cache_map') let s:executable_cache_map = {} endif + +function! ale#engine#CleanupEveryBuffer() abort + for l:key in keys(g:ale_buffer_info) + " The key could be a filename or a buffer number, so try and + " convert it to a number. We need a number for the other + " functions. + let l:buffer = str2nr(l:key) + + if l:buffer > 0 + " Stop all jobs and clear the results for everything, and delete + " all of the data we stored for the buffer. + call ale#engine#Cleanup(l:buffer) + endif + endfor +endfunction + function! ale#engine#ResetExecutableCache() abort let s:executable_cache_map = {} endfunction diff --git a/autoload/ale/fixers/eslint.vim b/autoload/ale/fixers/eslint.vim index 36f47510..ea5b2a63 100644 --- a/autoload/ale/fixers/eslint.vim +++ b/autoload/ale/fixers/eslint.vim @@ -25,7 +25,7 @@ endfunction function! ale#fixers#eslint#ProcessEslintDOutput(buffer, output) abort " If the output is an error message, don't use it. for l:line in a:output[:10] - if l:line =~# '^Error:' + if l:line =~# '\v^Error:|^Could not connect' return [] endif endfor diff --git a/autoload/ale/handlers/eslint.vim b/autoload/ale/handlers/eslint.vim index bc10ec21..eda033e4 100644 --- a/autoload/ale/handlers/eslint.vim +++ b/autoload/ale/handlers/eslint.vim @@ -99,6 +99,13 @@ function! ale#handlers#eslint#Handle(buffer, lines) abort \}] endif + if a:lines == ['Could not connect'] + return [{ + \ 'lnum': 1, + \ 'text': 'Could not connect to eslint_d. Try updating eslint_d or killing it.', + \}] + endif + " Matches patterns line the following: " " /path/to/some-filename.js:47:14: Missing trailing comma. [Warning/comma-dangle] diff --git a/autoload/ale/lsp_linter.vim b/autoload/ale/lsp_linter.vim index 8fbad12f..a11c76bc 100644 --- a/autoload/ale/lsp_linter.vim +++ b/autoload/ale/lsp_linter.vim @@ -55,16 +55,29 @@ function! s:HandleTSServerDiagnostics(response, error_type) abort endif let l:thislist = ale#lsp#response#ReadTSServerDiagnostics(a:response) + let l:no_changes = 0 " tsserver sends syntax and semantic errors in separate messages, so we " have to collect the messages separately for each buffer and join them " back together again. if a:error_type is# 'syntax' + if len(l:thislist) is 0 && len(get(l:info, 'syntax_loclist', [])) is 0 + let l:no_changes = 1 + endif + let l:info.syntax_loclist = l:thislist else + if len(l:thislist) is 0 && len(get(l:info, 'semantic_loclist', [])) is 0 + let l:no_changes = 1 + endif + let l:info.semantic_loclist = l:thislist endif + if l:no_changes + return + endif + let l:loclist = get(l:info, 'semantic_loclist', []) \ + get(l:info, 'syntax_loclist', []) @@ -99,9 +112,10 @@ endfunction function! ale#lsp_linter#HandleLSPResponse(conn_id, response) abort let l:method = get(a:response, 'method', '') - let l:linter_name = get(s:lsp_linter_map, a:conn_id, '') if get(a:response, 'jsonrpc', '') is# '2.0' && has_key(a:response, 'error') + let l:linter_name = get(s:lsp_linter_map, a:conn_id, '') + call s:HandleLSPErrorMessage(l:linter_name, a:response) elseif l:method is# 'textDocument/publishDiagnostics' call s:HandleLSPDiagnostics(a:conn_id, a:response) diff --git a/autoload/ale/toggle.vim b/autoload/ale/toggle.vim index 1d052b4f..8e642b3f 100644 --- a/autoload/ale/toggle.vim +++ b/autoload/ale/toggle.vim @@ -15,21 +15,6 @@ function! s:DisablePostamble() abort endif endfunction -function! s:CleanupEveryBuffer() abort - for l:key in keys(g:ale_buffer_info) - " The key could be a filename or a buffer number, so try and - " convert it to a number. We need a number for the other - " functions. - let l:buffer = str2nr(l:key) - - if l:buffer > 0 - " Stop all jobs and clear the results for everything, and delete - " all of the data we stored for the buffer. - call ale#engine#Cleanup(l:buffer) - endif - endfor -endfunction - function! ale#toggle#Toggle() abort let g:ale_enabled = !get(g:, 'ale_enabled') @@ -40,7 +25,7 @@ function! ale#toggle#Toggle() abort call ale#balloon#Enable() endif else - call s:CleanupEveryBuffer() + call ale#engine#CleanupEveryBuffer() call s:DisablePostamble() if exists('*ale#balloon#Disable') @@ -64,7 +49,7 @@ function! ale#toggle#Disable() abort endfunction function! ale#toggle#Reset() abort - call s:CleanupEveryBuffer() + call ale#engine#CleanupEveryBuffer() call ale#highlight#UpdateHighlights() endfunction diff --git a/doc/ale-ruby.txt b/doc/ale-ruby.txt index 810a1d45..c0e521c3 100644 --- a/doc/ale-ruby.txt +++ b/doc/ale-ruby.txt @@ -120,19 +120,13 @@ g:ale_ruby_rufo_executable *g:ale_ruby_rufo_executable* =============================================================================== solargraph *ale-ruby-solargraph* -g:ale_ruby_solargraph_host *g:ale_ruby_solargraph_host* - *b:ale_ruby_solargraph_host* +g:ale_ruby_solargraph_executable *g:ale_ruby_solargraph_executable* + *b:ale_ruby_solargraph_executable* Type: String - Default: `'127.0.0.1'` + Default: `'solargraph'` - The host/ip where the solargraph language server is running. - -g:ale_ruby_solargraph_port *g:ale_ruby_solargraph_port* - *b:ale_ruby_solargraph_port* - Type: String - Default: `'7658'` - - The listening port where the solargraph language server is running. + Override the invoked solargraph binary. This is useful for running rufo from + binstubs or a bundle. =============================================================================== diff --git a/doc/ale-thrift.txt b/doc/ale-thrift.txt index ed858db8..bb2ec058 100644 --- a/doc/ale-thrift.txt +++ b/doc/ale-thrift.txt @@ -28,7 +28,7 @@ g:ale_thrift_thrift_generators *g:ale_thrift_thrift_generators* g:ale_thrift_thrift_includes *g:ale_thrift_thrift_includes* *b:ale_thrift_thrift_includes* Type: |List| of |String|s - Default: `[]` + Default: `['.']` This list contains paths that will be searched for thrift `include` directives. diff --git a/plugin/ale.vim b/plugin/ale.vim index 36edb48c..888120fe 100644 --- a/plugin/ale.vim +++ b/plugin/ale.vim @@ -224,4 +224,8 @@ augroup ALECleanupGroup " Clean up buffers automatically when they are unloaded. autocmd BufDelete * if exists('*ale#engine#Cleanup') | call ale#engine#Cleanup(str2nr(expand('<abuf>'))) | endif autocmd QuitPre * call ale#events#QuitEvent(str2nr(expand('<abuf>'))) + + if exists('##VimSuspend') + autocmd VimSuspend * if exists('*ale#engine#CleanupEveryBuffer') | call ale#engine#CleanupEveryBuffer() | endif + endif augroup END diff --git a/test/command_callback/test_julia_languageserver_callbacks.vader b/test/command_callback/test_julia_languageserver_callbacks.vader index a1f3a1ae..22c6cefe 100644 --- a/test/command_callback/test_julia_languageserver_callbacks.vader +++ b/test/command_callback/test_julia_languageserver_callbacks.vader @@ -1,14 +1,18 @@ Before: + Save g:ale_julia_executable + call ale#assert#SetUpLinterTest('julia', 'languageserver') After: + Restore + call ale#assert#TearDownLinterTest() Execute(The default executable path should be correct): AssertLinter 'julia', \ ale#Escape('julia') . \' --startup-file=no --history-file=no -e ' . - \ ale#Escape('using LanguageServer; server = LanguageServer.LanguageServerInstance(STDIN, STDOUT, false); server.runlinter = true; run(server);') + \ ale#Escape('using LanguageServer; server = LanguageServer.LanguageServerInstance(stdin, stdout, false); server.runlinter = true; run(server);') Execute(The executable should be configurable): let g:ale_julia_executable = 'julia-new' @@ -16,7 +20,7 @@ Execute(The executable should be configurable): AssertLinter 'julia-new', \ ale#Escape('julia-new') . \' --startup-file=no --history-file=no -e ' . - \ ale#Escape('using LanguageServer; server = LanguageServer.LanguageServerInstance(STDIN, STDOUT, false); server.runlinter = true; run(server);') + \ ale#Escape('using LanguageServer; server = LanguageServer.LanguageServerInstance(stdin, stdout, false); server.runlinter = true; run(server);') Execute(The project root should be detected correctly): AssertLSPProject '' diff --git a/test/command_callback/test_ruby_solargraph.vader b/test/command_callback/test_ruby_solargraph.vader index b9dd46d8..b39f686e 100644 --- a/test/command_callback/test_ruby_solargraph.vader +++ b/test/command_callback/test_ruby_solargraph.vader @@ -7,30 +7,33 @@ Before: After: call ale#assert#TearDownLinterTest() +Execute(command callback should return default string): + AssertLinter 'solargraph', ale#Escape('solargraph') . ' stdio' + +Execute(command callback executable can be overridden): + let g:ale_ruby_solargraph_executable = 'foobar' + AssertLinter 'foobar', ale#Escape('foobar') . ' stdio' + Execute(should set solargraph for rails app): call ale#test#SetFilename('../ruby_fixtures/valid_rails_app/app/models/thing.rb') AssertLSPLanguage 'ruby' AssertLSPOptions {} AssertLSPProject ale#path#Simplify(g:dir . 'command_callback/../ruby_fixtures/valid_rails_app') - AssertLSPAddress '127.0.0.1:7658' Execute(should set solargraph for ruby app1): call ale#test#SetFilename('../ruby_fixtures/valid_ruby_app1/lib/file.rb') AssertLSPLanguage 'ruby' AssertLSPOptions {} AssertLSPProject ale#path#Simplify(g:dir . 'command_callback/../ruby_fixtures/valid_ruby_app1') - AssertLSPAddress '127.0.0.1:7658' Execute(should set solargraph for ruby app2): call ale#test#SetFilename('../ruby_fixtures/valid_ruby_app2/lib/file.rb') AssertLSPLanguage 'ruby' AssertLSPOptions {} AssertLSPProject ale#path#Simplify(g:dir . 'command_callback/../ruby_fixtures/valid_ruby_app2') - AssertLSPAddress '127.0.0.1:7658' Execute(should set solargraph for ruby app3): call ale#test#SetFilename('../ruby_fixtures/valid_ruby_app3/lib/file.rb') AssertLSPLanguage 'ruby' AssertLSPOptions {} AssertLSPProject ale#path#Simplify(g:dir . 'command_callback/../ruby_fixtures/valid_ruby_app3') - AssertLSPAddress '127.0.0.1:7658' diff --git a/test/command_callback/test_thrift_command_callback.vader b/test/command_callback/test_thrift_command_callback.vader index ea217259..cbada818 100644 --- a/test/command_callback/test_thrift_command_callback.vader +++ b/test/command_callback/test_thrift_command_callback.vader @@ -23,22 +23,22 @@ After: call ale#assert#TearDownLinterTest() Execute(The default command should be correct): - AssertLinter 'thrift', ale#Escape('thrift') . ' --gen cpp -strict' . b:suffix + AssertLinter 'thrift', ale#Escape('thrift') . ' --gen cpp -I . -strict' . b:suffix Execute(The executable should be configurable): let b:ale_thrift_thrift_executable = 'foobar' - AssertLinter 'foobar', ale#Escape('foobar') . ' --gen cpp -strict' . b:suffix + AssertLinter 'foobar', ale#Escape('foobar') . ' --gen cpp -I . -strict' . b:suffix Execute(The list of generators should be configurable): let b:ale_thrift_thrift_generators = ['java', 'py:dynamic'] AssertLinter 'thrift', ale#Escape('thrift') - \ . ' --gen java --gen py:dynamic -strict' . b:suffix + \ . ' --gen java --gen py:dynamic -I . -strict' . b:suffix let b:ale_thrift_thrift_generators = [] - AssertLinter 'thrift', ale#Escape('thrift') . ' --gen cpp -strict' . b:suffix + AssertLinter 'thrift', ale#Escape('thrift') . ' --gen cpp -I . -strict' . b:suffix Execute(The list of include paths should be configurable): let b:ale_thrift_thrift_includes = ['included/path'] @@ -50,4 +50,4 @@ Execute(The string of compiler options should be configurable): let b:ale_thrift_thrift_options = '-strict --allow-64bit-consts' AssertLinter 'thrift', ale#Escape('thrift') - \ . ' --gen cpp -strict --allow-64bit-consts' . b:suffix + \ . ' --gen cpp -I . -strict --allow-64bit-consts' . b:suffix diff --git a/test/completion/test_lsp_completion_parsing.vader b/test/completion/test_lsp_completion_parsing.vader index d5a45b54..71e53ab6 100644 --- a/test/completion/test_lsp_completion_parsing.vader +++ b/test/completion/test_lsp_completion_parsing.vader @@ -447,3 +447,27 @@ 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}, + \ ], + \ ale#completion#ParseLSPCompletions({ + \ 'jsonrpc': '2.0', + \ 'id': 6, + \ 'result': { + \ 'isIncomplete': v:false, + \ 'items': [ + \ { + \ 'label': 'migrations', + \ 'kind': 3, + \ 'detail': 'xxx', + \ 'documentation': { + \ 'kind': 'markdown', + \ 'value': 'Markdown documentation', + \ }, + \ }, + \ ], + \ }, + \ }) diff --git a/test/fixers/test_eslint_fixer_callback.vader b/test/fixers/test_eslint_fixer_callback.vader index be33825c..774595e3 100644 --- a/test/fixers/test_eslint_fixer_callback.vader +++ b/test/fixers/test_eslint_fixer_callback.vader @@ -170,3 +170,10 @@ Execute(The eslint_d post-processor should handle error messages correctly): \ ale#fixers#eslint#ProcessEslintDOutput(bufnr(''), [ \ 'Error: No ESLint configuration found.', \ ]) + +Execute(The eslint_d post-processor should handle failing to connect properly): + AssertEqual + \ [], + \ ale#fixers#eslint#ProcessEslintDOutput(bufnr(''), [ + \ 'Could not connect', + \ ]) diff --git a/test/handler/test_eslint_handler.vader b/test/handler/test_eslint_handler.vader index 2e8bfd2a..4a57927b 100644 --- a/test/handler/test_eslint_handler.vader +++ b/test/handler/test_eslint_handler.vader @@ -365,3 +365,15 @@ Execute(eslint should handle react errors correctly): \ ale#handlers#eslint#Handle(bufnr(''), [ \ '/path/editor-help.jsx:59:9: Property should be placed on the same line as the component declaration [Error/react/jsx-first-prop-new-line]', \ ]) + +Execute(Failing to connect to eslint_d should be handled correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 1, + \ 'text': 'Could not connect to eslint_d. Try updating eslint_d or killing it.', + \ }, + \ ], + \ ale#handlers#eslint#Handle(bufnr(''), [ + \ 'Could not connect', + \ ]) diff --git a/test/test_autocmd_commands.vader b/test/test_autocmd_commands.vader index 8d5048f0..4bb894ba 100644 --- a/test/test_autocmd_commands.vader +++ b/test/test_autocmd_commands.vader @@ -175,10 +175,19 @@ Execute (g:ale_lint_on_filetype_changed = 1 should bind the FileType event): \ filter(CheckAutocmd('ALEEvents'), 'v:val =~ ''\v^FileType''') Execute (ALECleanupGroup should include the right commands): - AssertEqual [ - \ 'BufDelete * if exists(''*ale#engine#Cleanup'') | call ale#engine#Cleanup(str2nr(expand(''<abuf>''))) | endif', - \ 'QuitPre * call ale#events#QuitEvent(str2nr(expand(''<abuf>'')))', - \], CheckAutocmd('ALECleanupGroup') + if exists('##VimSuspend') + AssertEqual [ + \ 'BufDelete * if exists(''*ale#engine#Cleanup'') | call ale#engine#Cleanup(str2nr(expand(''<abuf>''))) | endif', + \ 'QuitPre * call ale#events#QuitEvent(str2nr(expand(''<abuf>'')))', + \ 'VimSuspend * if exists(''*ale#engine#CleanupEveryBuffer'') | call ale#engine#CleanupEveryBuffer() | endif', + \], CheckAutocmd('ALECleanupGroup') + else + AssertEqual [ + \ 'BufDelete * if exists(''*ale#engine#Cleanup'') | call ale#engine#Cleanup(str2nr(expand(''<abuf>''))) | endif', + \ 'QuitPre * call ale#events#QuitEvent(str2nr(expand(''<abuf>'')))', + \], CheckAutocmd('ALECleanupGroup') + endif + Execute(Enabling completion should set up autocmd events correctly): let g:ale_completion_enabled = 0 diff --git a/test/test_c_flag_parsing.vader b/test/test_c_flag_parsing.vader index a4e00452..f7bfaa04 100644 --- a/test/test_c_flag_parsing.vader +++ b/test/test_c_flag_parsing.vader @@ -74,7 +74,7 @@ Execute(ParseCFlags should ignore -T and other arguments): \ . ' -DTEST=`date +%s`', \ ale#c#ParseCFlags( \ ale#path#Simplify(g:dir. '/test_c_projects/makefile_project'), - \ 'gcc -Dgoal=9 -Tlinkerfile.ld blabla -Isubdir ' + \ 'gcc -Dgoal=9 -Tlinkerfile.ld blabla -Isubdir --sysroot=subdir ' \ . '-I'. ale#path#Simplify('kernel/include') \ . ' -DTEST=`date +%s` -c file.c' \ ) diff --git a/test/test_redundant_tsserver_rendering_avoided.vader b/test/test_redundant_tsserver_rendering_avoided.vader new file mode 100644 index 00000000..41cbe5e0 --- /dev/null +++ b/test/test_redundant_tsserver_rendering_avoided.vader @@ -0,0 +1,136 @@ +Before: + Save g:ale_buffer_info + + function! CreateError(type, message) abort + let l:diagnostics = [] + + if !empty(a:message) + let l:diagnostics = [{ + \ 'start': {'line': 1, 'offset': 1}, + \ 'end': {'line': 1, 'offset':1}, + \ 'text': a:message, + \ 'code': 1005, + \}] + endif + + return { + \ 'seq': 0, + \ 'type': 'event', + \ 'event': a:type, + \ 'body': {'file': expand('%:p'), 'diagnostics': l:diagnostics}, + \} + endfunction + + function! CreateLoclist(message) abort + let l:list = [] + + if !empty(a:message) + let l:list = [{ + \ 'lnum': 1, + \ 'col': 1, + \ 'end_lnum': 1, + \ 'end_col': 1, + \ 'text': a:message, + \}] + endif + + return l:list + endfunction + + call ale#test#SetDirectory('/testplugin/test') + call ale#test#SetFilename('filename.ts') + + runtime autoload/ale/engine.vim + + let g:ale_buffer_info = {bufnr(''): {'loclist': []}} + let g:ale_handle_loclist_called = 0 + + function! ale#engine#HandleLoclist(linter_name, buffer, loclist) abort + let g:ale_handle_loclist_called = 1 + endfunction + +After: + Restore + + delfunction CreateError + delfunction CreateLoclist + + call ale#test#RestoreDirectory() + + runtime autoload/ale/engine.vim + +Execute(An initial empty list of syntax errors should be ignored): + call ale#lsp_linter#HandleLSPResponse(1, CreateError('syntaxDiag', '')) + + Assert !g:ale_handle_loclist_called + +Execute(An initial list of syntax errors should be handled): + call ale#lsp_linter#HandleLSPResponse(1, CreateError('syntaxDiag', 'x')) + + Assert g:ale_handle_loclist_called + +Execute(Subsequent empty lists should be ignored): + let g:ale_buffer_info[bufnr('')].syntax_loclist = [] + + call ale#lsp_linter#HandleLSPResponse(1, CreateError('syntaxDiag', '')) + + Assert !g:ale_handle_loclist_called + +Execute(Empty then non-empty syntax errors should be handled): + let g:ale_buffer_info[bufnr('')].syntax_loclist = [] + + call ale#lsp_linter#HandleLSPResponse(1, CreateError('syntaxDiag', 'x')) + + Assert g:ale_handle_loclist_called + +Execute(Non-empty then empty syntax errors should be handled): + let g:ale_buffer_info[bufnr('')].syntax_loclist = CreateLoclist('x') + + call ale#lsp_linter#HandleLSPResponse(1, CreateError('syntaxDiag', '')) + + Assert g:ale_handle_loclist_called + +Execute(Non-empty then non-empty syntax errors should be handled): + let g:ale_buffer_info[bufnr('')].syntax_loclist = CreateLoclist('x') + + call ale#lsp_linter#HandleLSPResponse(1, CreateError('syntaxDiag', 'x')) + + Assert g:ale_handle_loclist_called + +Execute(An initial empty list of semantic errors should be ignored): + call ale#lsp_linter#HandleLSPResponse(1, CreateError('semanticDiag', '')) + + Assert !g:ale_handle_loclist_called + +Execute(An initial list of semantic errors should be handled): + call ale#lsp_linter#HandleLSPResponse(1, CreateError('semanticDiag', 'x')) + + Assert g:ale_handle_loclist_called + +Execute(Subsequent empty lists should be ignored): + let g:ale_buffer_info[bufnr('')].semantic_loclist = [] + + call ale#lsp_linter#HandleLSPResponse(1, CreateError('semanticDiag', '')) + + Assert !g:ale_handle_loclist_called + +Execute(Empty then non-empty semantic errors should be handled): + let g:ale_buffer_info[bufnr('')].semantic_loclist = [] + + call ale#lsp_linter#HandleLSPResponse(1, CreateError('semanticDiag', 'x')) + + Assert g:ale_handle_loclist_called + +Execute(Non-empty then empty semantic errors should be handled): + let g:ale_buffer_info[bufnr('')].semantic_loclist = CreateLoclist('x') + + call ale#lsp_linter#HandleLSPResponse(1, CreateError('semanticDiag', '')) + + Assert g:ale_handle_loclist_called + +Execute(Non-empty then non-empty semantic errors should be handled): + let g:ale_buffer_info[bufnr('')].semantic_loclist = CreateLoclist('x') + + call ale#lsp_linter#HandleLSPResponse(1, CreateError('semanticDiag', 'x')) + + Assert g:ale_handle_loclist_called |