From 4999ad7e7860459f4ebea2d36d63317e88dd3870 Mon Sep 17 00:00:00 2001 From: w0rp Date: Fri, 6 Jul 2018 22:46:36 +0100 Subject: [PATCH] Add an AssertLinter command for tests --- autoload/ale/assert.vim | 50 +++++++++++++++++++ autoload/ale/linter.vim | 7 +++ .../test_tslint_command_callback.vader | 21 ++++---- .../test_write_good_command_callback.vader | 29 +++++------ 4 files changed, 80 insertions(+), 27 deletions(-) create mode 100644 autoload/ale/assert.vim diff --git a/autoload/ale/assert.vim b/autoload/ale/assert.vim new file mode 100644 index 00000000..eae41596 --- /dev/null +++ b/autoload/ale/assert.vim @@ -0,0 +1,50 @@ +function! s:GetLinter() abort + let l:linters = ale#linter#GetLintersLoaded() + let l:filetype_linters = get(values(l:linters), 0, []) + + if len(l:linters) is 0 || len(l:filetype_linters) is 0 + throw 'No linters were loaded' + endif + + if len(l:linters) > 1 || len(l:filetype_linters) > 1 + throw 'More than one linter was loaded' + endif + + return l:filetype_linters[0] +endfunction + +" Load the currently loaded linter for a test case, and check that the command +" matches the given string. +function! ale#assert#Linter(expected_executable, expected_command) abort + let l:buffer = bufnr('') + let l:linter = s:GetLinter() + let l:executable = ale#linter#GetExecutable(l:buffer, l:linter) + + if has_key(l:linter, 'command_chain') + let l:command = [] + + for l:chain_item in l:linter.command_chain + if empty(l:command) + call add(l:command, call(l:chain_item.callback, [l:buffer])) + else + call add(l:command, call(l:chain_item.callback, [l:buffer, []])) + endif + endfor + else + let l:command = ale#linter#GetCommand(l:buffer, l:linter) + " Replace %e with the escaped executable, so tests keep passing after + " linters are changed to use %e. + let l:command = substitute(l:command, '%e', '\=ale#Escape(l:executable)', 'g') + endif + + AssertEqual + \ [a:expected_executable, a:expected_command], + \ [l:executable, l:command] +endfunction + +command! -nargs=+ AssertLinter :call ale#assert#Linter() + +" A dummy function for making sure this module is loaded. +function! ale#assert#Init() abort + call ale#linter#Reset() +endfunction diff --git a/autoload/ale/linter.vim b/autoload/ale/linter.vim index b0237bcb..9e518551 100644 --- a/autoload/ale/linter.vim +++ b/autoload/ale/linter.vim @@ -47,6 +47,13 @@ function! ale#linter#Reset() abort let s:linters = {} endfunction +" Return a reference to the linters loaded. +" This is only for tests. +" Do not call this function. +function! ale#linter#GetLintersLoaded() abort + return s:linters +endfunction + function! s:IsCallback(value) abort return type(a:value) == type('') || type(a:value) == type(function('type')) endfunction diff --git a/test/command_callback/test_tslint_command_callback.vader b/test/command_callback/test_tslint_command_callback.vader index edab72c8..0c2f3abf 100644 --- a/test/command_callback/test_tslint_command_callback.vader +++ b/test/command_callback/test_tslint_command_callback.vader @@ -1,4 +1,6 @@ Before: + call ale#assert#Init() + Save g:ale_typescript_tslint_executable Save g:ale_typescript_tslint_config_path Save g:ale_typescript_tslint_rules_dir @@ -26,26 +28,25 @@ After: call ale#linter#Reset() Execute(The default tslint command should be correct): - AssertEqual + AssertLinter + \ 'tslint', \ 'cd ' . ale#Escape(expand('%:p:h')) . ' && ' - \ . ale#Escape('tslint') . ' --format json %t', - \ ale_linters#typescript#tslint#GetCommand(bufnr('')) + \ . ale#Escape('tslint') . ' --format json %t' Execute(The rules directory option should be included if set): let b:ale_typescript_tslint_rules_dir = '/foo/bar' - AssertEqual + AssertLinter + \ 'tslint', \ 'cd ' . ale#Escape(expand('%:p:h')) . ' && ' \ . ale#Escape('tslint') . ' --format json' \ . ' -r ' . ale#Escape('/foo/bar') - \ . ' %t', - \ ale_linters#typescript#tslint#GetCommand(bufnr('')) + \ . ' %t' Execute(The executable should be configurable and escaped): let b:ale_typescript_tslint_executable = 'foo bar' - AssertEqual 'foo bar', ale_linters#typescript#tslint#GetExecutable(bufnr('')) - AssertEqual + AssertLinter + \ 'foo bar', \ 'cd ' . ale#Escape(expand('%:p:h')) . ' && ' - \ . ale#Escape('foo bar') . ' --format json %t', - \ ale_linters#typescript#tslint#GetCommand(bufnr('')) + \ . ale#Escape('foo bar') . ' --format json %t' diff --git a/test/command_callback/test_write_good_command_callback.vader b/test/command_callback/test_write_good_command_callback.vader index 8d9e9a00..4b5ed7b7 100644 --- a/test/command_callback/test_write_good_command_callback.vader +++ b/test/command_callback/test_write_good_command_callback.vader @@ -1,4 +1,6 @@ Before: + call ale#assert#Init() + Save g:ale_writegood_options Save g:ale_writegood_executable Save g:ale_writegood_use_global @@ -7,6 +9,8 @@ Before: unlet! g:ale_writegood_executable unlet! g:ale_writegood_use_global + runtime ale_linters/markdown/write-good.vim + call ale#test#SetDirectory('/testplugin/test/command_callback') call ale#test#SetFilename('testfile.txt') @@ -16,42 +20,36 @@ After: Restore call ale#test#RestoreDirectory() + call ale#linter#Reset() Execute(The global executable should be used when the local one cannot be found): - AssertEqual 'write-good', ale#handlers#writegood#GetExecutable(bufnr('')) - AssertEqual + AssertLinter + \ 'write-good', \ ale#Escape('write-good') . ' %t', - \ ale#handlers#writegood#GetCommand(bufnr('')) Execute(The options should be used in the command): let g:ale_writegood_options = '--foo --bar' - AssertEqual + AssertLinter + \ 'write-good', \ ale#Escape('write-good') . ' --foo --bar %t', - \ ale#handlers#writegood#GetCommand(bufnr('')) Execute(Should use the node_modules/.bin executable, if available): call ale#test#SetFilename('write-good-node-modules/test.txt') - AssertEqual + AssertLinter \ ale#path#Simplify(g:dir . '/write-good-node-modules/node_modules/.bin/write-good'), - \ ale#handlers#writegood#GetExecutable(bufnr('')) - AssertEqual \ ale#Escape(ale#path#Simplify(g:dir . '/write-good-node-modules/node_modules/.bin/write-good')) \ . ' %t', - \ ale#handlers#writegood#GetCommand(bufnr('')) Execute(Should use the node_modules/write-good executable, if available): call ale#test#SetFilename('write-good-node-modules-2/test.txt') - AssertEqual + AssertLinter \ ale#path#Simplify(g:dir . '/write-good-node-modules-2/node_modules/write-good/bin/write-good.js'), - \ ale#handlers#writegood#GetExecutable(bufnr('')) - AssertEqual \ (has('win32') ? 'node.exe ' : '') \ . ale#Escape(ale#path#Simplify(g:dir . '/write-good-node-modules-2/node_modules/write-good/bin/write-good.js')) \ . ' %t', - \ ale#handlers#writegood#GetCommand(bufnr('')) Execute(Should let users configure a global executable and override local paths): call ale#test#SetFilename('write-good-node-modules-2/test.txt') @@ -59,7 +57,4 @@ Execute(Should let users configure a global executable and override local paths) let g:ale_writegood_executable = 'foo-bar' let g:ale_writegood_use_global = 1 - AssertEqual 'foo-bar', ale#handlers#writegood#GetExecutable(bufnr('')) - AssertEqual - \ ale#Escape('foo-bar') . ' %t', - \ ale#handlers#writegood#GetCommand(bufnr('')) + AssertLinter 'foo-bar', ale#Escape('foo-bar') . ' %t'