diff options
Diffstat (limited to 'autoload')
-rw-r--r-- | autoload/ale.vim | 19 | ||||
-rw-r--r-- | autoload/ale/assert.vim | 125 | ||||
-rw-r--r-- | autoload/ale/engine.vim | 17 | ||||
-rw-r--r-- | autoload/ale/fixers/tslint.vim | 2 | ||||
-rw-r--r-- | autoload/ale/handlers/rails_best_practices.vim | 6 | ||||
-rw-r--r-- | autoload/ale/handlers/tslint.vim | 13 | ||||
-rw-r--r-- | autoload/ale/lsp_linter.vim | 20 |
7 files changed, 180 insertions, 22 deletions
diff --git a/autoload/ale.vim b/autoload/ale.vim index f61418f6..26c73547 100644 --- a/autoload/ale.vim +++ b/autoload/ale.vim @@ -213,6 +213,25 @@ function! ale#Set(variable_name, default) abort endif endfunction +" Given a string for adding to a command, return the string padded with a +" space on the left if it is not empty. Otherwise return an empty string. +" +" This can be used for making command strings cleaner and easier to test. +function! ale#Pad(string) abort + return !empty(a:string) ? ' ' . a:string : '' +endfunction + +" Given a environment variable name and a value, produce part of a command for +" setting an environment variable before running a command. The syntax will be +" valid for cmd on Windows, or most shells on Unix. +function! ale#Env(variable_name, value) abort + if has('win32') + return 'set ' . a:variable_name . '=' . ale#Escape(a:value) . ' && ' + endif + + return a:variable_name . '=' . ale#Escape(a:value) . ' ' +endfunction + " Escape a string suitably for each platform. " shellescape does not work on Windows. function! ale#Escape(str) abort diff --git a/autoload/ale/assert.vim b/autoload/ale/assert.vim index eae41596..55c39ee3 100644 --- a/autoload/ale/assert.vim +++ b/autoload/ale/assert.vim @@ -1,3 +1,9 @@ +let s:chain_results = [] + +function! ale#assert#WithChainResults(...) abort + let s:chain_results = a:000 +endfunction + function! s:GetLinter() abort let l:linters = ale#linter#GetLintersLoaded() let l:filetype_linters = get(values(l:linters), 0, []) @@ -21,15 +27,31 @@ function! ale#assert#Linter(expected_executable, expected_command) abort let l:executable = ale#linter#GetExecutable(l:buffer, l:linter) if has_key(l:linter, 'command_chain') - let l:command = [] + let l:callbacks = map(copy(l:linter.command_chain), 'v:val.callback') - for l:chain_item in l:linter.command_chain - if empty(l:command) - call add(l:command, call(l:chain_item.callback, [l:buffer])) + " If the expected command is a string, just check the last one. + if type(a:expected_command) is type('') + if len(l:callbacks) is 1 + let l:command = call(l:callbacks[0], [l:buffer]) else - call add(l:command, call(l:chain_item.callback, [l:buffer, []])) + let l:input = get(s:chain_results, len(l:callbacks) - 2, []) + let l:command = call(l:callbacks[-1], [l:buffer, l:input]) endif - endfor + else + let l:command = [] + let l:chain_index = 0 + + for l:Callback in l:callbacks + if l:chain_index is 0 + call add(l:command, call(l:Callback, [l:buffer])) + else + let l:input = get(s:chain_results, l:chain_index - 1, []) + call add(l:command, call(l:Callback, [l:buffer, l:input])) + endif + + let l:chain_index += 1 + endfor + endif else let l:command = ale#linter#GetCommand(l:buffer, l:linter) " Replace %e with the escaped executable, so tests keep passing after @@ -42,9 +64,96 @@ function! ale#assert#Linter(expected_executable, expected_command) abort \ [l:executable, l:command] endfunction -command! -nargs=+ AssertLinter :call ale#assert#Linter(<args>) +function! ale#assert#LinterNotExecuted() abort + let l:buffer = bufnr('') + let l:linter = s:GetLinter() + let l:executable = ale#linter#GetExecutable(l:buffer, l:linter) + + Assert empty(l:executable), "The linter will be executed when it shouldn't be" +endfunction + +function! ale#assert#LSPOptions(expected_options) abort + let l:buffer = bufnr('') + let l:linter = s:GetLinter() + let l:initialization_options = ale#lsp_linter#GetOptions(l:buffer, l:linter) + + AssertEqual a:expected_options, l:initialization_options +endfunction + +function! ale#assert#LSPLanguage(expected_language) abort + let l:buffer = bufnr('') + let l:linter = s:GetLinter() + let l:language = ale#util#GetFunction(l:linter.language_callback)(l:buffer) + + AssertEqual a:expected_language, l:language +endfunction + +function! ale#assert#LSPProject(expected_root) abort + let l:buffer = bufnr('') + let l:linter = s:GetLinter() + let l:root = ale#util#GetFunction(l:linter.project_root_callback)(l:buffer) + + AssertEqual a:expected_root, l:root +endfunction " A dummy function for making sure this module is loaded. -function! ale#assert#Init() abort +function! ale#assert#SetUpLinterTest(filetype, name) abort + " Set up a marker so ALE doesn't create real random temporary filenames. + let g:ale_create_dummy_temporary_file = 1 + + " Remove current linters. call ale#linter#Reset() + call ale#linter#PreventLoading(a:filetype) + + let l:prefix = 'ale_' . a:filetype . '_' . a:name + let b:filter_expr = 'v:val[: len(l:prefix) - 1] is# l:prefix' + + Save g:ale_c_build_dir + unlet! g:ale_c_build_dir + + " Save and clear linter variables. + " We'll load the runtime file to reset them to defaults. + for l:key in filter(keys(g:), b:filter_expr) + execute 'Save g:' . l:key + unlet g:[l:key] + endfor + + unlet! b:ale_c_build_dir + + for l:key in filter(keys(b:), b:filter_expr) + unlet b:[l:key] + endfor + + execute 'runtime ale_linters/' . a:filetype . '/' . a:name . '.vim' + + call ale#test#SetDirectory('/testplugin/test/command_callback') + + command! -nargs=+ WithChainResults :call ale#assert#WithChainResults(<args>) + command! -nargs=+ AssertLinter :call ale#assert#Linter(<args>) + command! -nargs=0 AssertLinterNotExecuted :call ale#assert#LinterNotExecuted() + command! -nargs=+ AssertLSPOptions :call ale#assert#LSPOptions(<args>) + command! -nargs=+ AssertLSPLanguage :call ale#assert#LSPLanguage(<args>) + command! -nargs=+ AssertLSPProject :call ale#assert#LSPProject(<args>) +endfunction + +function! ale#assert#TearDownLinterTest() abort + unlet! g:ale_create_dummy_temporary_file + let s:chain_results = [] + + delcommand WithChainResults + delcommand AssertLinter + delcommand AssertLinterNotExecuted + delcommand AssertLSPOptions + delcommand AssertLSPLanguage + delcommand AssertLSPProject + + call ale#test#RestoreDirectory() + + Restore + + call ale#linter#Reset() + + if exists('*ale#semver#ResetVersionCache') + call ale#semver#ResetVersionCache() + endif endfunction diff --git a/autoload/ale/engine.vim b/autoload/ale/engine.vim index cb4ba534..ec5ccb6d 100644 --- a/autoload/ale/engine.vim +++ b/autoload/ale/engine.vim @@ -96,8 +96,25 @@ function! ale#engine#ManageDirectory(buffer, directory) abort call add(g:ale_buffer_info[a:buffer].temporary_directory_list, a:directory) endfunction +function! ale#engine#CreateFile(buffer) abort + " This variable can be set to 1 in tests to stub this out. + if get(g:, 'ale_create_dummy_temporary_file') + return 'TEMP' + endif + + let l:temporary_file = ale#util#Tempname() + call ale#engine#ManageFile(a:buffer, l:temporary_file) + + return l:temporary_file +endfunction + " Create a new temporary directory and manage it in one go. function! ale#engine#CreateDirectory(buffer) abort + " This variable can be set to 1 in tests to stub this out. + if get(g:, 'ale_create_dummy_temporary_file') + return 'TEMP_DIR' + endif + let l:temporary_directory = ale#util#Tempname() " Create the temporary directory for the file, unreadable by 'other' " users. diff --git a/autoload/ale/fixers/tslint.vim b/autoload/ale/fixers/tslint.vim index 4d905a08..b352af3a 100644 --- a/autoload/ale/fixers/tslint.vim +++ b/autoload/ale/fixers/tslint.vim @@ -2,7 +2,7 @@ " Description: Fixing files with tslint. function! ale#fixers#tslint#Fix(buffer) abort - let l:executable = ale_linters#typescript#tslint#GetExecutable(a:buffer) + let l:executable = ale#handlers#tslint#GetExecutable(a:buffer) let l:tslint_config_path = ale#path#ResolveLocalPath( \ a:buffer, diff --git a/autoload/ale/handlers/rails_best_practices.vim b/autoload/ale/handlers/rails_best_practices.vim deleted file mode 100644 index 51bafbb0..00000000 --- a/autoload/ale/handlers/rails_best_practices.vim +++ /dev/null @@ -1,6 +0,0 @@ -call ale#Set('ruby_rails_best_practices_options', '') -call ale#Set('ruby_rails_best_practices_executable', 'rails_best_practices') - -function! ale#handlers#rails_best_practices#GetExecutable(buffer) abort - return ale#Var(a:buffer, 'ruby_rails_best_practices_executable') -endfunction diff --git a/autoload/ale/handlers/tslint.vim b/autoload/ale/handlers/tslint.vim new file mode 100644 index 00000000..90579344 --- /dev/null +++ b/autoload/ale/handlers/tslint.vim @@ -0,0 +1,13 @@ +function! ale#handlers#tslint#InitVariables() abort + call ale#Set('typescript_tslint_executable', 'tslint') + call ale#Set('typescript_tslint_config_path', '') + call ale#Set('typescript_tslint_rules_dir', '') + call ale#Set('typescript_tslint_use_global', get(g:, 'ale_use_global_executables', 0)) + call ale#Set('typescript_tslint_ignore_empty_files', 0) +endfunction + +function! ale#handlers#tslint#GetExecutable(buffer) abort + return ale#node#FindExecutable(a:buffer, 'typescript_tslint', [ + \ 'node_modules/.bin/tslint', + \]) +endfunction diff --git a/autoload/ale/lsp_linter.vim b/autoload/ale/lsp_linter.vim index 31299fc5..6dc78e4c 100644 --- a/autoload/ale/lsp_linter.vim +++ b/autoload/ale/lsp_linter.vim @@ -114,6 +114,18 @@ function! ale#lsp_linter#HandleLSPResponse(conn_id, response) abort endif endfunction +function! ale#lsp_linter#GetOptions(buffer, linter) abort + let l:initialization_options = {} + + if has_key(a:linter, 'initialization_options_callback') + let l:initialization_options = ale#util#GetFunction(a:linter.initialization_options_callback)(a:buffer) + elseif has_key(a:linter, 'initialization_options') + let l:initialization_options = a:linter.initialization_options + endif + + return l:initialization_options +endfunction + " Given a buffer, an LSP linter, and a callback to register for handling " messages, start up an LSP linter and get ready to receive errors or " completions. @@ -128,13 +140,7 @@ function! ale#lsp_linter#StartLSP(buffer, linter, callback) abort return {} endif - let l:initialization_options = {} - - if has_key(a:linter, 'initialization_options_callback') - let l:initialization_options = ale#util#GetFunction(a:linter.initialization_options_callback)(a:buffer) - elseif has_key(a:linter, 'initialization_options') - let l:initialization_options = a:linter.initialization_options - endif + let l:initialization_options = ale#lsp_linter#GetOptions(a:buffer, a:linter) if a:linter.lsp is# 'socket' let l:address = ale#linter#GetAddress(a:buffer, a:linter) |