Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Bartek thindil Jasicki
2020-06-07 09:26:06 +02:00
98 changed files with 1937 additions and 492 deletions

View File

@@ -54,6 +54,7 @@ Execute(VersionCheck should return correct version):
Execute(The eclipselsp callback should return the correct default value):
let cmd = [ ale#Escape('java'),
\ '',
\ '-Declipse.application=org.eclipse.jdt.ls.core.id1',
\ '-Dosgi.bundles.defaultStartLevel=4',
\ '-Declipse.product=org.eclipse.jdt.ls.core.product',
@@ -72,6 +73,7 @@ Execute(The eclipselsp callback should return the correct default value):
Execute(The eclipselsp callback should allow custom executable):
let b:ale_java_eclipselsp_executable='/bin/foobar'
let cmd = [ ale#Escape('/bin/foobar'),
\ '',
\ '-Declipse.application=org.eclipse.jdt.ls.core.id1',
\ '-Dosgi.bundles.defaultStartLevel=4',
\ '-Declipse.product=org.eclipse.jdt.ls.core.product',
@@ -87,9 +89,12 @@ Execute(The eclipselsp callback should allow custom executable):
\]
AssertLinter '/bin/foobar', join(cmd, ' ')
Execute(The eclipselsp callback should allow custom configuration path):
Execute(The eclipselsp callback should allow custom configuration path and javaagent):
let b:ale_java_eclipselsp_config_path = '/home/config'
let b:ale_java_eclipselsp_javaagent = '/home/lombok.jar /home/lombok2.jar'
let cmd = [ ale#Escape('java'),
\ ale#Escape('-javaagent:/home/lombok.jar'),
\ ale#Escape('-javaagent:/home/lombok2.jar'),
\ '-Declipse.application=org.eclipse.jdt.ls.core.id1',
\ '-Dosgi.bundles.defaultStartLevel=4',
\ '-Declipse.product=org.eclipse.jdt.ls.core.product',

View File

@@ -31,7 +31,7 @@ After:
Execute(The javac callback should return the correct default value):
AssertLinter 'javac', g:prefix . ' -d ' . ale#Escape('TEMP_DIR') . ' %t'
Execute(The javac callback should use g:ale_java_javac_classpath correctly):
Execute(The javac callback should use string type g:ale_java_javac_classpath correctly):
let g:ale_java_javac_classpath = 'foo.jar'
AssertLinter 'javac',
@@ -39,6 +39,14 @@ Execute(The javac callback should use g:ale_java_javac_classpath correctly):
\ . ' -cp ' . ale#Escape('foo.jar')
\ . ' -d ' . ale#Escape('TEMP_DIR') . ' %t'
Execute(The javac callback should use list type g:ale_java_javac_classpath correctly):
let g:ale_java_javac_classpath = ['foo.jar']
AssertLinter 'javac',
\ g:prefix
\ . ' -cp ' . ale#Escape('foo.jar')
\ . ' -d ' . ale#Escape('TEMP_DIR') . ' %t'
Execute(The executable should be configurable):
let g:ale_java_javac_executable = 'foobar'
@@ -108,6 +116,137 @@ Execute(The javac callback should combine discovered classpaths and manual ones)
\ . ' -d ' . ale#Escape('TEMP_DIR') . ' %t',
\ substitute(b:command, '%e', '\=ale#Escape(''javac'')', 'g')
let g:ale_java_javac_classpath = ['configured.jar']
let b:command = ale_linters#java#javac#GetCommand(bufnr(''), [
\ '[DEBUG] Ignore this.',
\ '[INFO] Something we should ignore.',
\ '/foo/bar.jar',
\ '/xyz/abc.jar',
\], {})
AssertEqual
\ g:prefix
\ . ' -cp '
\ . ale#Escape(join(
\ [
\ '/foo/bar.jar',
\ '/xyz/abc.jar',
\ 'configured.jar',
\ ],
\ g:cp_sep
\ ))
\ . ' -d ' . ale#Escape('TEMP_DIR') . ' %t',
\ substitute(b:command, '%e', '\=ale#Escape(''javac'')', 'g')
let g:ale_java_javac_classpath = ['configured.jar', 'configured2.jar']
let b:command = ale_linters#java#javac#GetCommand(bufnr(''), [
\ '[DEBUG] Ignore this.',
\ '[INFO] Something we should ignore.',
\ '/foo/bar.jar',
\ '/xyz/abc.jar',
\], {})
AssertEqual
\ g:prefix
\ . ' -cp '
\ . ale#Escape(join(
\ [
\ '/foo/bar.jar',
\ '/xyz/abc.jar',
\ 'configured.jar',
\ 'configured2.jar',
\ ],
\ g:cp_sep
\ ))
\ . ' -d ' . ale#Escape('TEMP_DIR') . ' %t',
\ substitute(b:command, '%e', '\=ale#Escape(''javac'')', 'g')
Execute(The javac callback should use string type g:ale_java_javac_sourcepath correctly):
let g:ale_java_javac_sourcepath = 'java_paths/build/gen/main'
AssertLinter 'javac',
\ g:prefix
\ . ' -sourcepath ' . ale#Escape(
\ ale#path#Simplify(g:dir . '/java_paths/build/gen/main/')
\ )
\ . ' -d ' . ale#Escape('TEMP_DIR') . ' %t'
Execute(The javac callback should use list type g:ale_java_javac_sourcepath correctly):
let g:ale_java_javac_sourcepath = ['java_paths/build/gen/main']
AssertLinter 'javac',
\ g:prefix
\ . ' -sourcepath ' . ale#Escape(
\ ale#path#Simplify(g:dir . '/java_paths/build/gen/main/')
\ )
\ . ' -d ' . ale#Escape('TEMP_DIR') . ' %t'
Execute(The javac callback shouldn't add -sourcepath when g:ale_java_javac_sourcepath variable path doesn't exist):
let g:ale_java_javac_sourcepath = 'java_paths/build/gen3/main'
AssertLinter 'javac',
\ g:prefix
\ . ' -d ' . ale#Escape('TEMP_DIR') . ' %t'
Execute(The javac callback should combine discovered sourcepath and manual ones):
call ale#engine#Cleanup(bufnr(''))
call ale#test#SetFilename('java_paths/src/main/java/com/something/dummy.java')
call ale#engine#InitBufferInfo(bufnr(''))
let g:ale_java_javac_sourcepath = 'java_paths/build/gen/main'
let b:command = ale_linters#java#javac#GetCommand(bufnr(''), [], {})
AssertEqual
\ ale#path#CdString(expand('%:p:h')) . ale#Escape('javac') . ' -Xlint'
\ . ' -sourcepath ' . ale#Escape(join([
\ ale#path#Simplify(g:dir . '/java_paths/src/main/java/'),
\ ale#path#Simplify(g:dir . '/java_paths/build/gen/main/'),
\ ], g:cp_sep))
\ . ' -d ' . ale#Escape('TEMP_DIR') . ' %t',
\ substitute(b:command, '%e', '\=ale#Escape(''javac'')', 'g')
let g:ale_java_javac_sourcepath = 'java_paths/build/gen/main'
\ . g:cp_sep . 'java_paths/build/gen2/main'
let b:command = ale_linters#java#javac#GetCommand(bufnr(''), [], {})
AssertEqual
\ ale#path#CdString(expand('%:p:h')) . ale#Escape('javac') . ' -Xlint'
\ . ' -sourcepath ' . ale#Escape(join([
\ ale#path#Simplify(g:dir . '/java_paths/src/main/java/'),
\ ale#path#Simplify(g:dir . '/java_paths/build/gen/main/'),
\ ale#path#Simplify(g:dir . '/java_paths/build/gen2/main/')
\ ], g:cp_sep))
\ . ' -d ' . ale#Escape('TEMP_DIR') . ' %t',
\ substitute(b:command, '%e', '\=ale#Escape(''javac'')', 'g')
let g:ale_java_javac_sourcepath = ['java_paths/build/gen/main']
let b:command = ale_linters#java#javac#GetCommand(bufnr(''), [], {})
AssertEqual
\ ale#path#CdString(expand('%:p:h')) . ale#Escape('javac') . ' -Xlint'
\ . ' -sourcepath ' . ale#Escape(join([
\ ale#path#Simplify(g:dir . '/java_paths/src/main/java/'),
\ ale#path#Simplify(g:dir . '/java_paths/build/gen/main/')
\ ], g:cp_sep))
\ . ' -d ' . ale#Escape('TEMP_DIR') . ' %t',
\ substitute(b:command, '%e', '\=ale#Escape(''javac'')', 'g')
let g:ale_java_javac_sourcepath = [
\ 'java_paths/build/gen/main',
\ 'java_paths/build/gen2/main'
\ ]
let b:command = ale_linters#java#javac#GetCommand(bufnr(''), [], {})
AssertEqual
\ ale#path#CdString(expand('%:p:h')) . ale#Escape('javac') . ' -Xlint'
\ . ' -sourcepath ' . ale#Escape(join([
\ ale#path#Simplify(g:dir . '/java_paths/src/main/java/'),
\ ale#path#Simplify(g:dir . '/java_paths/build/gen/main/'),
\ ale#path#Simplify(g:dir . '/java_paths/build/gen2/main/')
\ ], g:cp_sep))
\ . ' -d ' . ale#Escape('TEMP_DIR') . ' %t',
\ substitute(b:command, '%e', '\=ale#Escape(''javac'')', 'g')
Execute(The javac callback should detect source directories):
call ale#engine#Cleanup(bufnr(''))
noautocmd e! java_paths/src/main/java/com/something/dummy

View File

@@ -52,6 +52,15 @@ Execute(The mypy callbacks should detect virtualenv directories and switch to th
\ . ' --show-column-numbers '
\ . '--shadow-file %s %t %s'
Execute(The mypy callbacks should cd to directory containing mypy.ini if found):
silent execute 'file ' . fnameescape(g:dir . '/python_paths/with_mypy_ini_and_pytest_ini/tests/testsubfolder/my_tests.py')
AssertLinter 'mypy',
\ ale#path#CdString(ale#path#Simplify(g:dir . '/python_paths/with_mypy_ini_and_pytest_ini'))
\ . ale#Escape('mypy')
\ . ' --show-column-numbers '
\ . '--shadow-file %s %t %s'
Execute(You should able able to use the global mypy instead):
silent execute 'file ' . fnameescape(g:dir . '/python_paths/with_virtualenv/subdir/foo/bar.py')
let g:ale_python_mypy_use_global = 1

View File

@@ -0,0 +1,30 @@
Before:
Save g:ale_go_go111module
call ale#assert#SetUpLinterTest('go', 'revive')
After:
Restore
unlet! b:ale_go_go111module
call ale#assert#TearDownLinterTest()
Execute(The default revive command should be correct):
AssertLinter 'revive', ale#Escape('revive') . ' %t'
Execute(The revive executable should be configurable):
let b:ale_go_revive_executable = 'foobar'
AssertLinter 'foobar', ale#Escape('foobar') . ' %t'
Execute(The revive options should be configurable):
let b:ale_go_revive_options = '--foo'
AssertLinter 'revive', ale#Escape('revive') . ' --foo %t'
Execute(The revive command should support Go environment variables):
let b:ale_go_go111module = 'on'
AssertLinter 'revive',
\ ale#Env('GO111MODULE', 'on') . ale#Escape('revive') . ' %t'

View File

@@ -0,0 +1,20 @@
Before:
call ale#assert#SetUpLinterTest('rust', 'analyzer')
After:
call ale#assert#TearDownLinterTest()
Execute(The default executable path should be correct):
AssertLinter 'rust-analyzer', ale#Escape('rust-analyzer')
Execute(The project root should be detected correctly):
AssertLSPProject ''
call ale#test#SetFilename('rust-rls-project/test.rs')
AssertLSPProject ale#path#Simplify(g:dir . '/rust-rls-project')
Execute(Should accept configuration settings):
AssertLSPConfig {}
let b:ale_rust_analyzer_config = {'rust': {'clippy_preference': 'on'}}
AssertLSPConfig {'rust': {'clippy_preference': 'on'}}

View File

@@ -0,0 +1,43 @@
Before:
call ale#assert#SetUpLinterTest('typescript', 'standard')
call ale#test#SetFilename('testfile.js')
unlet! b:executable
After:
call ale#assert#TearDownLinterTest()
Execute(bin/cmd.js paths should be preferred):
call ale#test#SetFilename('standard-test-files/with-cmd/testfile.js')
let b:executable = ale#path#Simplify(
\ g:dir
\ . '/standard-test-files/with-cmd/node_modules/standard/bin/cmd.js'
\)
AssertLinter b:executable,
\ (has('win32') ? 'node.exe ' : '')
\ . ale#Escape(b:executable)
\ . ' --stdin %s'
Execute(.bin directories should be used too):
call ale#test#SetFilename('standard-test-files/with-bin/testfile.js')
let b:executable = ale#path#Simplify(
\ g:dir
\ . '/standard-test-files/with-bin/node_modules/.bin/standard'
\)
AssertLinter b:executable, ale#Escape(b:executable) . ' --stdin %s'
Execute(The global executable should be used otherwise):
AssertLinter 'standard', ale#Escape('standard') . ' --stdin %s'
Execute(The global executable should be configurable):
let b:ale_typescript_standard_executable = 'foobar'
AssertLinter 'foobar', ale#Escape('foobar') . ' --stdin %s'
Execute(The options should be configurable):
let b:ale_typescript_standard_options = '--wat'
AssertLinter 'standard', ale#Escape('standard') . ' --wat --stdin %s'

View File

@@ -0,0 +1,48 @@
Before:
call ale#assert#SetUpLinterTest('terraform', 'terraform_lsp')
After:
if isdirectory(g:dir . '/.terraform')
call delete(g:dir . '/.terraform', 'd')
endif
unlet! b:ale_terraform_langserver_executable
unlet! b:ale_terraform_langserver_options
call ale#assert#TearDownLinterTest()
Execute(Should send correct LSP language):
AssertLSPLanguage 'terraform'
Execute(Should load default executable):
AssertLinter 'terraform-lsp', ale#Escape('terraform-lsp')
Execute(Should configure custom executable):
let b:ale_terraform_langserver_executable = 'foo'
AssertLinter 'foo', ale#Escape('foo')
Execute(Should set custom options):
let b:ale_terraform_langserver_options = '--bar'
AssertLinter 'terraform-lsp',
\ ale#Escape('terraform-lsp') . ' --bar'
Execute(Should return current directory if it contains .terraform directory):
call mkdir(g:dir . '/.terraform')
AssertLSPProject g:dir
Execute(Should return nearest directory with .terraform if found in parent directory):
call ale#test#SetFilename('../terraform_files/main.tf')
let b:parent_dir = ale#path#Simplify(g:dir . '/..')
let b:tf_dir = b:parent_dir . '/.terraform'
if !isdirectory(b:tf_dir)
call mkdir(b:tf_dir)
endif
AssertLSPProject b:parent_dir
call delete(b:tf_dir, 'd')
unlet!b:parent_dir
unlet!b:tf_dir

View File

@@ -0,0 +1,76 @@
" Author: Jeffrey Lau https://github.com/zoonfafer
" Description: Tests for the Vim vimls linter
Before:
call ale#assert#SetUpLinterTest('vim', 'vimls')
After:
if isdirectory(g:dir . '/.git')
call delete(g:dir . '/.git', 'd')
endif
call ale#assert#TearDownLinterTest()
Execute(should set correct defaults):
AssertLinter 'vim-language-server', ale#Escape('vim-language-server') . ' --stdio'
Execute(should set correct LSP values):
call ale#test#SetFilename('vim_fixtures/path_with_autoload/test.vim')
AssertLSPLanguage 'vim'
AssertLSPOptions {}
AssertLSPConfig {}
AssertLSPProject ale#path#Simplify(g:dir . '/vim_fixtures/path_with_autoload')
Execute(should set correct project for .git/):
let b:parent_dir = ale#path#Simplify(g:dir . '/..')
let b:git_dir = b:parent_dir . '/.git'
call ale#test#SetFilename('vim_fixtures/test.vim')
if !isdirectory(b:git_dir)
call mkdir(b:git_dir)
endif
AssertLSPProject ale#path#Simplify(b:parent_dir)
call delete(b:git_dir, 'd')
unlet! b:git_dir
Execute(should set correct project for plugin/):
call ale#test#SetFilename('vim_fixtures/path_with_plugin/test.vim')
AssertLSPProject ale#path#Simplify(g:dir . '/vim_fixtures/path_with_plugin')
Execute(should accept configuration settings):
AssertLSPConfig {}
let b:ale_vim_vimls_config = {'vim': {'foobar': v:true}}
AssertLSPConfig {'vim': {'foobar': v:true}}
Execute(should set correct project for .vimrc):
call ale#test#SetFilename('vim_fixtures/path_with_vimrc/.vimrc')
AssertLSPProject ale#path#Simplify(g:dir . '/vim_fixtures/path_with_vimrc')
Execute(should set correct project for init.vim):
call ale#test#SetFilename('vim_fixtures/path_with_initvim/init.vim')
AssertLSPProject ale#path#Simplify(g:dir . '/vim_fixtures/path_with_initvim')
Execute(should use the local executable when available):
call ale#test#SetFilename('vim_fixtures/file.vim')
AssertLinter ale#path#Simplify(g:dir . '/vim_fixtures/node_modules/.bin/vim-language-server'),
\ ale#Escape(ale#path#Simplify(g:dir . '/vim_fixtures/node_modules/.bin/vim-language-server')) . ' --stdio'
Execute(should let the global executable to be used):
let g:ale_vim_vimls_use_global = 1
call ale#test#SetFilename('vim_fixtures/file.vim')
AssertLinter 'vim-language-server',
\ ale#Escape('vim-language-server') . ' --stdio'
Execute(should let the executable to be configured):
let g:ale_vim_vimls_executable = 'foobar'
AssertLinter 'foobar', ale#Escape('foobar') . ' --stdio'

View File

@@ -50,7 +50,8 @@ Before:
let g:handle_code_action_called = 0
function! MockHandleCodeAction() abort
" delfunction! ale#code_action#HandleCodeAction
function! ale#code_action#HandleCodeAction(action) abort
function! ale#code_action#HandleCodeAction(action, should_save) abort
AssertEqual v:false, a:should_save
let g:handle_code_action_called += 1
endfunction
endfunction
@@ -233,7 +234,7 @@ Execute(ale#completion#Show() should make the correct feedkeys() call for manual
AssertEqual [["\<Plug>(ale_show_completion_menu)"]], g:feedkeys_calls
Execute(ale#completion#Show() should not call feedkeys() for other sources):
let b:ale_completion_info = {'source': 'deoplete'}
let b:ale_completion_info = {'source': 'other-source'}
call ale#completion#Show([{'word': 'x', 'kind': 'v', 'icase': 1}])
sleep 1ms
@@ -334,7 +335,7 @@ Execute(b:ale_completion_info should be set up correctly when requesting complet
Execute(b:ale_completion_info should be set up correctly for other sources):
let b:ale_completion_result = []
call setpos('.', [bufnr(''), 3, 14, 0])
call ale#completion#GetCompletions('deoplete')
call ale#completion#GetCompletions('ale-callback')
AssertEqual
\ {
@@ -344,7 +345,7 @@ Execute(b:ale_completion_info should be set up correctly for other sources):
\ 'line_length': 14,
\ 'line': 3,
\ 'prefix': 'ab',
\ 'source': 'deoplete',
\ 'source': 'ale-callback',
\ },
\ b:ale_completion_info
Assert !exists('b:ale_completion_result')

View File

@@ -17,17 +17,17 @@ Execute(Should handle Rust completion results correctly):
\ {'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': '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': 'f', 'icase': 1},
\ {'word': 'Output', 'menu': 'type Output = str;', 'info': '', 'kind': 'f', 'icase': 1},
\ {'word': 'Output', 'menu': 'type Output = str;', 'info': '', 'kind': 'f', 'icase': 1},
\ {'word': 'Output', 'menu': 'type Output = str;', 'info': '', 'kind': 'f', 'icase': 1},
\ {'word': 'Output', 'menu': 'type Output = str;', 'info': '', 'kind': 'f', 'icase': 1},
\ {'word': 'Output', 'menu': 'type Output = str;', 'info': '', 'kind': 'f', 'icase': 1},
\ {'word': 'Output', 'menu': 'type Output = str;', 'info': '', 'kind': 'f', 'icase': 1},
\ {'word': 'Target', 'menu': 'type Target = str;', 'info': '', 'kind': 'f', 'icase': 1},
\ {'word': 'Err', 'menu': 'type Err = ParseError;', '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},

View File

@@ -36,7 +36,7 @@ Execute(TypeScript completion details responses should be parsed correctly):
\ 'word': 'abc',
\ 'menu': '(property) Foo.abc: number',
\ 'info': '',
\ 'kind': 'f',
\ 'kind': 'v',
\ 'icase': 1,
\ 'dup': g:ale_completion_tsserver_autoimport,
\ },
@@ -44,7 +44,7 @@ Execute(TypeScript completion details responses should be parsed correctly):
\ 'word': 'def',
\ 'menu': '(property) Foo.def: number',
\ 'info': 'foo bar baz',
\ 'kind': 'f',
\ 'kind': 'v',
\ 'icase': 1,
\ 'dup': g:ale_completion_tsserver_autoimport,
\ },
@@ -52,7 +52,7 @@ Execute(TypeScript completion details responses should be parsed correctly):
\ 'word': 'ghi',
\ 'menu': '(class) Foo',
\ 'info': '',
\ 'kind': 'f',
\ 'kind': 'v',
\ 'icase': 1,
\ 'dup': g:ale_completion_tsserver_autoimport,
\ },
@@ -124,7 +124,7 @@ Execute(Entries without details should be included in the responses):
\ 'word': 'abc',
\ 'menu': 'import { def } from "./Foo"; (property) Foo.abc: number',
\ 'info': '',
\ 'kind': 'f',
\ 'kind': 'v',
\ 'icase': 1,
\ 'user_data': json_encode({
\ 'codeActions': [{
@@ -138,7 +138,7 @@ Execute(Entries without details should be included in the responses):
\ 'word': 'def',
\ 'menu': '(property) Foo.def: number',
\ 'info': 'foo bar baz',
\ 'kind': 'f',
\ 'kind': 'v',
\ 'icase': 1,
\ 'dup': g:ale_completion_tsserver_autoimport,
\ },

View File

@@ -0,0 +1,23 @@
Before:
call ale#assert#SetUpFixerTest('nim', 'nimpretty')
After:
call ale#assert#TearDownFixerTest()
Execute(The nimpretty callback should return the correct default values):
AssertEqual
\ {
\ 'read_temporary_file': 1,
\ 'command': ale#Escape('nimpretty') . ' %t --maxLineLen:80'
\ },
\ ale#fixers#nimpretty#Fix(bufnr(''))
Execute(The nimpretty callback should include any additional options):
let g:ale_nim_nimpretty_options = '--some-option'
AssertEqual
\ {
\ 'read_temporary_file': 1,
\ 'command': ale#Escape('nimpretty') . ' %t --some-option'
\ },
\ ale#fixers#nimpretty#Fix(bufnr(''))

View File

@@ -21,6 +21,7 @@ After:
unlet! g:config_error_lines
Execute(The eslint handler should parse json correctly):
call ale#test#SetFilename('foo.js')
AssertEqual
\ [
\ {
@@ -53,6 +54,21 @@ Execute(The eslint handler should parse json correctly):
\ '[{"filePath":"foo.js","messages":[{"ruleId":"no-unused-vars","severity":1,"message":"''variable'' is assigned a value but never used.","line":1,"column":7,"nodeType":"Identifier","endLine":1,"endColumn":15},{"ruleId":"semi","severity":1,"message":"Missing semicolon.","line":5,"column":15,"nodeType":"ExpressionStatement","fix":{"range":[46,46],"text":";"}},{"ruleId":"no-redeclare","severity":2,"message":"''variable'' is already defined.","line":7,"column":7,"nodeType":"Identifier","endLine":7,"endColumn":15}],"errorCount":1,"warningCount":3,"fixableErrorCount":0,"fixableWarningCount":1,"source":"const variable = {\n a: 3\n};\n\nconsole.log(1)\n\nclass variable {\n}\n"}]'
\ ])
Execute(The eslint handler should suppress deprecation warnings):
call ale#test#SetFilename('foo.js')
AssertEqual
\ [
\ {
\ 'lnum': 1,
\ 'col': 9,
\ 'text': 'Parsing error: Unexpected token Controller',
\ 'type': 'E',
\ }
\ ],
\ ale#handlers#eslint#HandleJSON(bufnr(''), [
\ '[{"filePath":"foo.js","messages":[{"ruleId":null,"fatal":true,"severity":2 ,"message":"Parsing error: Unexpected token Controller","line":1,"column":9}],"errorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount": 0,"source":"i:mport Controller from \"@ember/controller\";\nimport listViewControllerMixin from \"elearning/mixins/list-view-controller\";\nimport { inject as service } from \"@ember/service\";\n\nexport default Controller.extend(listViewControllerMixin(), {\n modelName: \"notification\",\n intl: service(),\n\n flatpickrLocale: computed(\"intl.locale\", function() {\n return this.intl.locale.firstObject.split(\"-\")[0];\n })\n});\n"}]', '(node:616989) [ESLINT_LEGACY_OBJECT_REST_SPREAD] DeprecationWarning: The ''parserOptions.ecmaFeatures.experimentalObjectRestSpread'' option is deprecated. Use ''parser Options.ecmaVersion'' instead. (found in "node_modules/eslint-plugin-ember/lib/config/base.js")]'
\ ])
Execute(The eslint handler should print a message about a missing configuration file):
let g:config_error_lines = [
\ '',
@@ -262,7 +278,7 @@ Execute(Suppressing missing configs shouldn't suppress module import errors):
\ ale#handlers#eslint#HandleJSON(bufnr(''), g:config_error_lines[:])
Execute(The eslint handler should hint about using typescript-eslint-parser):
silent! noautocmd file foo.ts
call ale#test#SetFilename('foo.ts')
AssertEqual
\ [
@@ -326,7 +342,7 @@ Execute(Failing to connect to eslint_d should be handled correctly):
\ ])
Execute(Disabling warnings about trailing spaces should work):
silent! noautocmd file foo.ts
call ale#test#SetFilename('foo.js')
AssertEqual
\ [

View File

@@ -1,6 +1,8 @@
Before:
Save g:ale_python_mypy_ignore_invalid_syntax
Save g:ale_python_mypy_show_notes
unlet! g:ale_python_mypy_show_notes
unlet! g:ale_python_mypy_ignore_invalid_syntax
runtime ale_linters/python/mypy.vim
@@ -16,6 +18,8 @@ After:
Execute(The mypy handler should parse lines correctly):
call ale#test#SetFilename('__init__.py')
let g:ale_python_mypy_show_notes = 0
AssertEqual
\ [
\ {
@@ -69,6 +73,31 @@ Execute(The mypy handler should parse lines correctly):
\ '__init__.py:72:1: warning: Some warning',
\ ])
Execute(The mypy handler should show notes if enabled):
call ale#test#SetFilename('__init__.py')
AssertEqual
\ [
\ {
\ 'lnum': 72,
\ 'col': 1,
\ 'filename': ale#path#Simplify(g:dir . '/__init__.py'),
\ 'type': 'I',
\ 'text': 'A note',
\ },
\ ],
\ ale_linters#python#mypy#Handle(bufnr(''), [
\ '__init__.py:72:1: note: A note',
\ ])
let g:ale_python_mypy_show_notes = 0
AssertEqual
\ [],
\ ale_linters#python#mypy#Handle(bufnr(''), [
\ '__init__.py:72:1: note: A note',
\ ])
Execute(The mypy handler should handle Windows names with spaces):
" This test works on Unix, where this is seen as a single filename
silent file C:\\something\\with\ spaces.py

View File

@@ -22,7 +22,7 @@ Execute(The shellcheck handler should handle basic errors or warnings):
\ 'code': 'SC1068',
\ },
\ ],
\ ale_linters#sh#shellcheck#Handle(bufnr(''), [
\ ale#handlers#shellcheck#Handle(bufnr(''), [
\ '-:2:1: warning: In POSIX sh, ''let'' is not supported. [SC2039]',
\ '-:2:3: error: Don''t put spaces around the = in assignments. [SC1068]',
\ ])
@@ -38,6 +38,6 @@ Execute(The shellcheck handler should handle notes):
\ 'code': 'SC2086',
\ },
\ ],
\ ale_linters#sh#shellcheck#Handle(bufnr(''), [
\ ale#handlers#shellcheck#Handle(bufnr(''), [
\ '-:3:3: note: Double quote to prevent globbing and word splitting. [SC2086]',
\ ])

View File

@@ -0,0 +1,48 @@
Before:
runtime ale_linters/verilog/verilator.vim
After:
call ale#linter#Reset()
Execute (The verilator handler should parse legacy messages with only line numbers):
AssertEqual
\ [
\ {
\ 'lnum': 3,
\ 'type': 'E',
\ 'text': 'syntax error, unexpected IDENTIFIER'
\ },
\ {
\ 'lnum': 10,
\ 'type': 'W',
\ 'text': 'Blocking assignments (=) in sequential (flop or latch) block; suggest delayed assignments (<=).'
\ },
\ ],
\ ale_linters#verilog#verilator#Handle(bufnr(''), [
\ '%Error: foo_verilator_linted.v:3: syntax error, unexpected IDENTIFIER',
\ '%Warning-BLKSEQ: bar_verilator_linted.v:10: Blocking assignments (=) in sequential (flop or latch) block; suggest delayed assignments (<=).',
\ ])
Execute (The verilator handler should parse new format messages with line and column numbers):
AssertEqual
\ [
\ {
\ 'lnum': 3,
\ 'col' : 1,
\ 'type': 'E',
\ 'text': 'syntax error, unexpected endmodule, expecting ;'
\ },
\ {
\ 'lnum': 4,
\ 'col' : 6,
\ 'type': 'W',
\ 'text': 'Signal is not used: r'
\ },
\ ],
\ ale_linters#verilog#verilator#Handle(bufnr(''), [
\ '%Error: bar_verilator_linted.v:3:1: syntax error, unexpected endmodule, expecting ;',
\ '%Warning-UNUSED: foo_verilator_linted.v:4:6: Signal is not used: r',
\ ])

View File

@@ -8,15 +8,20 @@ ale_module = imp.load_source(
class VimMock(object):
def __init__(self, call_list, call_results):
def __init__(self, call_list, call_results, commands):
self.__call_list = call_list
self.__call_results = call_results
self.__commands = commands
def call(self, function, *args):
self.__call_list.append((function, args))
return self.__call_results.get(function, 0)
def command(self, command):
self.__commands.append(command)
class DeopleteSourceTest(unittest.TestCase):
def setUp(self):
@@ -24,8 +29,10 @@ class DeopleteSourceTest(unittest.TestCase):
self.call_list = []
self.call_results = {'ale#completion#CanProvideCompletions': 1}
self.commands = []
self.source = ale_module.Source('vim')
self.source.vim = VimMock(self.call_list, self.call_results)
self.source.vim = VimMock(
self.call_list, self.call_results, self.commands)
def test_attributes(self):
"""
@@ -48,6 +55,7 @@ class DeopleteSourceTest(unittest.TestCase):
'cpp': r'(\.|::|->)\w*$',
},
'is_bytepos': True,
'is_volatile': True,
'mark': '[L]',
'min_pattern_length': 1,
'name': 'ale',
@@ -64,70 +72,28 @@ class DeopleteSourceTest(unittest.TestCase):
])
def test_request_completion_results(self):
context = {'is_async': False}
context = {'event': 'TextChangedI', 'is_refresh': True}
self.assertEqual(self.source.gather_candidates(context), [])
self.assertEqual(context, {'is_async': True})
self.assertEqual(self.call_list, [
('ale#completion#CanProvideCompletions', ()),
('ale#completion#GetCompletions', ('deoplete',)),
])
self.assertEqual(self.commands, [
"call ale#completion#GetCompletions('ale-callback', " + \
"{'callback': {completions -> deoplete#auto_complete() }})"
])
def test_request_completion_results_from_buffer_without_providers(self):
self.call_results['ale#completion#CanProvideCompletions'] = 0
context = {'is_async': False}
context = {'event': 'TextChangedI', 'is_refresh': True}
self.assertIsNone(self.source.gather_candidates(context), [])
self.assertEqual(context, {'is_async': False})
self.assertEqual(self.call_list, [
('ale#completion#CanProvideCompletions', ()),
])
def test_refresh_completion_results(self):
context = {'is_async': False}
self.assertEqual(self.source.gather_candidates(context), [])
self.assertEqual(context, {'is_async': True})
self.assertEqual(self.call_list, [
('ale#completion#CanProvideCompletions', ()),
('ale#completion#GetCompletions', ('deoplete',)),
])
context = {'is_async': True, 'is_refresh': True}
self.assertEqual(self.source.gather_candidates(context), [])
self.assertEqual(context, {'is_async': True, 'is_refresh': True})
self.assertEqual(self.call_list, [
('ale#completion#CanProvideCompletions', ()),
('ale#completion#GetCompletions', ('deoplete',)),
('ale#completion#CanProvideCompletions', ()),
('ale#completion#GetCompletions', ('deoplete',)),
])
def test_poll_no_result(self):
context = {'is_async': True}
self.call_results['ale#completion#GetCompletionResult'] = None
self.assertEqual(self.source.gather_candidates(context), [])
self.assertEqual(context, {'is_async': True})
self.assertEqual(self.call_list, [
('ale#completion#CanProvideCompletions', ()),
('ale#completion#GetCompletionResult', ()),
])
def test_poll_empty_result_ready(self):
context = {'is_async': True}
self.call_results['ale#completion#GetCompletionResult'] = []
self.assertEqual(self.source.gather_candidates(context), [])
self.assertEqual(context, {'is_async': False})
self.assertEqual(self.call_list, [
('ale#completion#CanProvideCompletions', ()),
('ale#completion#GetCompletionResult', ()),
])
def test_poll_non_empty_result_ready(self):
context = {'is_async': True}
def test_async_event(self):
context = {'event': 'Async', 'is_refresh': True}
self.call_results['ale#completion#GetCompletionResult'] = [
{
'word': 'foobar',
@@ -147,7 +113,7 @@ class DeopleteSourceTest(unittest.TestCase):
'info': '',
},
])
self.assertEqual(context, {'is_async': False})
self.assertEqual(self.call_list, [
('ale#completion#CanProvideCompletions', ()),
('ale#completion#GetCompletionResult', ()),

View File

@@ -32,7 +32,7 @@ Before:
function! CollectSigns()
redir => l:output
if has('nvim-0.4.2') || (v:version >= 801 && has('patch614'))
if has('nvim-0.4.2') || has('patch-8.1.614')
silent exec 'sign place group=ale'
else
silent exec 'sign place'

View File

@@ -1,5 +1,5 @@
Execute (Parsing English signs should work):
if has('nvim-0.4.2') || (v:version >= 801 && has('patch614'))
if has('nvim-0.4.2') || has('patch-8.1.614')
AssertEqual
\ [0, [[9, 1000001, 'ALEWarningSign']]],
\ ale#sign#ParseSigns([
@@ -16,7 +16,7 @@ Execute (Parsing English signs should work):
endif
Execute (Parsing Russian signs should work):
if has('nvim-0.4.2') || (v:version >= 801 && has('patch614'))
if has('nvim-0.4.2') || has('patch-8.1.614')
AssertEqual
\ [0, [[1, 1000001, 'ALEErrorSign']]],
\ ale#sign#ParseSigns([' строка=1 id=1000001 группа=ale имя=ALEErrorSign'])
@@ -27,7 +27,7 @@ Execute (Parsing Russian signs should work):
endif
Execute (Parsing Japanese signs should work):
if has('nvim-0.4.2') || (v:version >= 801 && has('patch614'))
if has('nvim-0.4.2') || has('patch-8.1.614')
AssertEqual
\ [0, [[1, 1000001, 'ALEWarningSign']]],
\ ale#sign#ParseSigns([' 行=1 識別子=1000001 グループ=ale 名前=ALEWarningSign'])
@@ -38,7 +38,7 @@ Execute (Parsing Japanese signs should work):
endif
Execute (Parsing Spanish signs should work):
if has('nvim-0.4.2') || (v:version >= 801 && has('patch614'))
if has('nvim-0.4.2') || has('patch-8.1.614')
AssertEqual
\ [0, [[12, 1000001, 'ALEWarningSign']]],
\ ale#sign#ParseSigns([' línea=12 id=1000001 grupo=ale nombre=ALEWarningSign'])
@@ -49,7 +49,7 @@ Execute (Parsing Spanish signs should work):
endif
Execute (Parsing Italian signs should work):
if has('nvim-0.4.2') || (v:version >= 801 && has('patch614'))
if has('nvim-0.4.2') || has('patch-8.1.614')
AssertEqual
\ [0, [[1, 1000001, 'ALEWarningSign']]],
\ ale#sign#ParseSigns([' riga=1 id=1000001, gruppo=ale nome=ALEWarningSign'])
@@ -60,7 +60,7 @@ Execute (Parsing Italian signs should work):
endif
Execute (Parsing German signs should work):
if has('nvim-0.4.2') || (v:version >= 801 && has('patch614'))
if has('nvim-0.4.2') || has('patch-8.1.614')
AssertEqual
\ [0, [[235, 1000001, 'ALEErrorSign']]],
\ ale#sign#ParseSigns([' Zeile=235 id=1000001 Gruppe=ale Name=ALEErrorSign'])
@@ -71,7 +71,7 @@ Execute (Parsing German signs should work):
endif
Execute (The sign parser should indicate if the dummy sign is set):
if has('nvim-0.4.2') || (v:version >= 801 && has('patch614'))
if has('nvim-0.4.2') || has('patch-8.1.614')
AssertEqual
\ [1, [[1, 1000001, 'ALEErrorSign']]],
\ ale#sign#ParseSigns([

View File

@@ -68,7 +68,7 @@ Before:
function! ParseSigns()
redir => l:output
if has('nvim-0.4.2') || (v:version >= 801 && has('patch614'))
if has('nvim-0.4.2') || has('patch-8.1.614')
silent sign place group=ale
else
silent sign place
@@ -152,7 +152,7 @@ Execute(The current signs should be set for running a job):
\ ParseSigns()
Execute(Loclist items with sign_id values should be kept):
if has('nvim-0.4.2') || (v:version >= 801 && has('patch614'))
if has('nvim-0.4.2') || has('patch-8.1.614')
exec 'sign place 1000347 group=ale line=3 name=ALEErrorSign buffer=' . bufnr('')
exec 'sign place 1000348 group=ale line=15 name=ALEErrorSign buffer=' . bufnr('')
exec 'sign place 1000349 group=ale line=16 name=ALEWarningSign buffer=' . bufnr('')
@@ -297,7 +297,7 @@ Execute(No exceptions should be thrown when setting signs for invalid buffers):
Execute(Signs should be removed when lines have multiple sign IDs on them):
" We can fail to remove signs if there are multiple signs on one line,
" say after deleting lines in Vim, etc.
if has('nvim-0.4.2') || (v:version >= 801 && has('patch614'))
if has('nvim-0.4.2') || has('patch-8.1.614')
exec 'sign place 1000347 group=ale line=3 name=ALEErrorSign buffer=' . bufnr('')
exec 'sign place 1000348 group=ale line=3 name=ALEWarningSign buffer=' . bufnr('')
exec 'sign place 1000349 group=ale line=10 name=ALEErrorSign buffer=' . bufnr('')

View File

View File

@@ -37,10 +37,10 @@ Before:
After:
" Close the extra buffers if we opened it.
if bufnr(g:file1) != -1
execute ':bp | :bd ' . bufnr(g:file1)
execute ':bp! | :bd! ' . bufnr(g:file1)
endif
if bufnr(g:file2) != -1
execute ':bp | :bd ' . bufnr(g:file2)
execute ':bp! | :bd! ' . bufnr(g:file2)
endif
if filereadable(g:file1)
@@ -116,7 +116,7 @@ Execute(It should modify and save multiple files):
\ 'newText': "import {A, B} from 'module'\n\n",
\ }]
\ }],
\})
\}, v:true)
AssertEqual [
\ 'class Value {',
@@ -161,7 +161,7 @@ Execute(Beginning of file can be modified):
\ 'newText': "type A: string\ntype B: number\n",
\ }],
\ }]
\})
\}, v:true)
AssertEqual [
\ 'type A: string',
@@ -192,7 +192,7 @@ Execute(End of file can be modified):
\ 'newText': "type A: string\ntype B: number\n",
\ }],
\ }]
\})
\}, v:true)
AssertEqual g:test.text + [
\ 'type A: string',
@@ -227,7 +227,7 @@ Execute(Current buffer contents will be reloaded):
\ 'newText': "type A: string\ntype B: number\n",
\ }],
\ }]
\})
\}, v:true)
AssertEqual [
\ 'type A: string',
@@ -249,11 +249,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)
call ale#code_action#HandleCodeAction(g:test.changes, v:true)
AssertEqual [1, 1], getpos('.')[1:2]
call setpos('.', [0, 2, 2, 0])
call ale#code_action#HandleCodeAction(g:test.changes)
call ale#code_action#HandleCodeAction(g:test.changes, v:true)
AssertEqual [2, 2], getpos('.')[1:2]
# ====C====
@@ -264,7 +264,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)
call ale#code_action#HandleCodeAction(g:test.changes, v:true)
AssertEqual ' value2: string', getline('.')
AssertEqual [2, 9], getpos('.')[1:2]
endfor
@@ -275,7 +275,8 @@ Execute(Cursor column will move back when new text is shorter):
call WriteFileAndEdit()
call setpos('.', [0, 2, 8, 0])
AssertEqual ' value: string', getline('.')
call ale#code_action#HandleCodeAction(g:test.create_change(2, 3, 2, 8, 'val'))
call ale#code_action#HandleCodeAction(
\ g:test.create_change(2, 3, 2, 8, 'val'), v:true)
AssertEqual ' val: string', getline('.')
AssertEqual [2, 6], getpos('.')[1:2]
@@ -286,7 +287,8 @@ 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'))
call ale#code_action#HandleCodeAction(
\ g:test.create_change(2, 3, 2, 8, 'longValue'), v:true)
AssertEqual ' longValue: string', getline('.')
AssertEqual [2, 12], getpos('.')[1:2]
@@ -297,7 +299,8 @@ Execute(Cursor line will move when updates are happening on lines above):
call WriteFileAndEdit()
call setpos('.', [0, 3, 1, 0])
AssertEqual '}', getline('.')
call ale#code_action#HandleCodeAction(g:test.create_change(1, 1, 2, 1, "test\ntest\n"))
call ale#code_action#HandleCodeAction(
\ g:test.create_change(1, 1, 2, 1, "test\ntest\n"), v:true)
AssertEqual '}', getline('.')
AssertEqual [4, 1], getpos('.')[1:2]
@@ -308,7 +311,8 @@ Execute(Cursor line and column will move when change on lines above and just bef
call WriteFileAndEdit()
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"))
call ale#code_action#HandleCodeAction(
\ g:test.create_change(1, 1, 2, 1, "test\ntest\n123"), v:true)
AssertEqual '123 value: string', getline('.')
AssertEqual [3, 5], getpos('.')[1:2]
@@ -319,7 +323,8 @@ Execute(Cursor line and column will move at the end of changes):
call WriteFileAndEdit()
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"))
call ale#code_action#HandleCodeAction(
\ g:test.create_change(1, 1, 3, 1, "test\n"), v:true)
AssertEqual '}', getline('.')
AssertEqual [2, 1], getpos('.')[1:2]
@@ -329,6 +334,19 @@ Execute(Cursor will not move when changes happening on lines >= cursor, but afte
call WriteFileAndEdit()
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"))
call ale#code_action#HandleCodeAction(
\ g:test.create_change(2, 10, 3, 1, "number\n"), v:true)
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)
AssertEqual 1, getbufvar(bufnr(''), '&modified')
AssertEqual [
\ 'import { writeFile } from ''fs'';',
\ 'class Name {',
\ ' value: string',
\ '}',
\], getline(1, '$')

View File

@@ -15,7 +15,7 @@ Before:
\ 'col': 10,
\ 'bufnr': bufnr('%'),
\ 'vcol': 0,
\ 'linter_name': 'eslint',
\ 'linter_name': 'bettercode',
\ 'nr': -1,
\ 'type': 'W',
\ 'code': 'semi',
@@ -26,7 +26,7 @@ Before:
\ 'col': 10,
\ 'bufnr': bufnr('%'),
\ 'vcol': 0,
\ 'linter_name': 'eslint',
\ 'linter_name': 'bettercode',
\ 'nr': -1,
\ 'type': 'E',
\ 'code': 'semi',
@@ -38,7 +38,7 @@ Before:
\ 'col': 14,
\ 'bufnr': bufnr('%'),
\ 'vcol': 0,
\ 'linter_name': 'eslint',
\ 'linter_name': 'bettercode',
\ 'nr': -1,
\ 'type': 'I',
\ 'text': 'Some information',
@@ -48,7 +48,7 @@ Before:
\ 'col': 10,
\ 'bufnr': bufnr('%'),
\ 'vcol': 0,
\ 'linter_name': 'eslint',
\ 'linter_name': 'bettercode',
\ 'nr': -1,
\ 'type': 'W',
\ 'code': 'space-infix-ops',
@@ -59,7 +59,7 @@ Before:
\ 'col': 15,
\ 'bufnr': bufnr('%'),
\ 'vcol': 0,
\ 'linter_name': 'eslint',
\ 'linter_name': 'bettercode',
\ 'nr': -1,
\ 'type': 'E',
\ 'code': 'radix',
@@ -70,7 +70,7 @@ Before:
\ 'col': 1,
\ 'bufnr': bufnr('%'),
\ 'vcol': 0,
\ 'linter_name': 'eslint',
\ 'linter_name': 'bettercode',
\ 'nr': -1,
\ 'type': 'E',
\ 'text': 'lowercase error',
@@ -196,7 +196,7 @@ Execute(The linter name should be formatted into the message correctly):
call ale#cursor#EchoCursorWarning()
AssertEqual
\ 'eslint: Infix operators must be spaced.',
\ 'bettercode: Infix operators must be spaced.',
\ GetLastMessage()
Execute(The severity should be formatted into the message correctly):

View File

@@ -57,13 +57,25 @@ Execute(eslint.js executables should be run with node on Windows):
" We have to execute the file with node.
if has('win32')
AssertEqual
\ ale#Escape('node.exe') . ' '
\ ale#path#CdString(ale#path#Simplify(g:dir . '/eslint-test-files/react-app'))
\ . ale#Escape('node.exe') . ' '
\ . ale#Escape(ale#path#Simplify(g:dir . '/eslint-test-files/react-app/node_modules/eslint/bin/eslint.js'))
\ . ' -f json --stdin --stdin-filename %s',
\ ale#handlers#eslint#GetCommand(bufnr(''))
else
AssertEqual
\ ale#Escape(ale#path#Simplify(g:dir . '/eslint-test-files/react-app/node_modules/eslint/bin/eslint.js'))
\ ale#path#CdString(ale#path#Simplify(g:dir . '/eslint-test-files/react-app'))
\ . ale#Escape(ale#path#Simplify(g:dir . '/eslint-test-files/react-app/node_modules/eslint/bin/eslint.js'))
\ . ' -f json --stdin --stdin-filename %s',
\ ale#handlers#eslint#GetCommand(bufnr(''))
endif
Execute(eslint.js executables can be run outside project dir):
" Set filename above eslint-test-files (which contains node_modules)
call ale#test#SetFilename('testfile.js')
" cd "..." not present, since project root not found (from node_modules)
AssertEqual
\ ale#Escape(ale#handlers#eslint#GetExecutable(bufnr('')))
\ . ' -f json --stdin --stdin-filename %s',
\ ale#handlers#eslint#GetCommand(bufnr(''))

View File

@@ -2,6 +2,8 @@ Before:
call ale#test#SetDirectory('/testplugin/test')
call ale#test#SetFilename('dummy.txt')
Save g:ale_default_navigation
let g:old_filename = expand('%:p')
let g:Callback = ''
let g:expr_list = []
@@ -12,6 +14,7 @@ Before:
let g:capability_checked = ''
let g:conn_id = v:null
let g:InitCallback = v:null
let g:ale_default_navigation = 'buffer'
runtime autoload/ale/lsp_linter.vim
runtime autoload/ale/lsp.vim
@@ -63,6 +66,8 @@ Before:
endfunction
After:
Restore
if g:conn_id isnot v:null
call ale#lsp#RemoveConnectionWithID(g:conn_id)
endif
@@ -152,6 +157,20 @@ Execute(Results should be shown for tsserver responses):
\ g:item_list
AssertEqual {}, ale#references#GetMap()
" We should be able to repeat selections with ALERepeatSelection
let g:ale_item_list = []
ALERepeatSelection
AssertEqual
\ [
\ {'filename': '/foo/bar/app.ts', 'column': 9, 'line': 9, 'match': 'import {doSomething} from ''./whatever'''},
\ {'filename': '/foo/bar/app.ts', 'column': 3, 'line': 804, 'match': 'doSomething()'},
\ {'filename': '/foo/bar/other/app.ts', 'column': 3, 'line': 51, 'match': 'doSomething()'},
\ ],
\ g:item_list
AssertEqual {}, ale#references#GetMap()
Execute(The preview window should not be opened for empty tsserver responses):
call ale#references#SetMap({3: {}})
call ale#references#HandleTSServerResponse(1, {
@@ -195,7 +214,7 @@ Execute(tsserver reference requests should be sent):
\ [0, 'ts@references', {'file': expand('%:p'), 'line': 2, 'offset': 5}]
\ ],
\ g:message_list
AssertEqual {'42': {'use_relative_paths': 0}}, ale#references#GetMap()
AssertEqual {'42': {'open_in': 'current-buffer', 'use_relative_paths': 0}}, ale#references#GetMap()
Execute('-relative' argument should enable 'use_relative_paths' in HandleTSServerResponse):
runtime ale_linters/typescript/tsserver.vim
@@ -205,7 +224,48 @@ Execute('-relative' argument should enable 'use_relative_paths' in HandleTSServe
call g:InitCallback()
AssertEqual {'42': {'use_relative_paths': 1}}, ale#references#GetMap()
AssertEqual {'42': {'open_in': 'current-buffer', 'use_relative_paths': 1}}, ale#references#GetMap()
Execute(`-tab` should display results in tabs):
runtime ale_linters/typescript/tsserver.vim
call setpos('.', [bufnr(''), 2, 5, 0])
ALEFindReferences -tab
call g:InitCallback()
AssertEqual {'42': {'open_in': 'tab', 'use_relative_paths': 0}}, ale#references#GetMap()
Execute(The default navigation type should be used):
runtime ale_linters/typescript/tsserver.vim
call setpos('.', [bufnr(''), 2, 5, 0])
let g:ale_default_navigation = 'tab'
ALEFindReferences
call g:InitCallback()
AssertEqual {'42': {'open_in': 'tab', 'use_relative_paths': 0}}, ale#references#GetMap()
Execute(`-split` should display results in splits):
runtime ale_linters/typescript/tsserver.vim
call setpos('.', [bufnr(''), 2, 5, 0])
ALEFindReferences -split
call g:InitCallback()
AssertEqual {'42': {'open_in': 'split', 'use_relative_paths': 0}}, ale#references#GetMap()
Execute(`-vsplit` should display results in vsplits):
runtime ale_linters/typescript/tsserver.vim
call setpos('.', [bufnr(''), 2, 5, 0])
ALEFindReferences -vsplit
call g:InitCallback()
AssertEqual {'42': {'open_in': 'vsplit', 'use_relative_paths': 0}}, ale#references#GetMap()
Given python(Some Python file):
foo
@@ -302,7 +362,7 @@ Execute(LSP reference requests should be sent):
\ ],
\ g:message_list
AssertEqual {'42': {'use_relative_paths': 0}}, ale#references#GetMap()
AssertEqual {'42': {'open_in': 'current-buffer', 'use_relative_paths': 0}}, ale#references#GetMap()
Execute('-relative' argument should enable 'use_relative_paths' in HandleLSPResponse):
runtime ale_linters/python/pyls.vim
@@ -313,4 +373,4 @@ Execute('-relative' argument should enable 'use_relative_paths' in HandleLSPResp
call g:InitCallback()
AssertEqual {'42': {'use_relative_paths': 1}}, ale#references#GetMap()
AssertEqual {'42': {'open_in': 'current-buffer', 'use_relative_paths': 1}}, ale#references#GetMap()

View File

@@ -2,6 +2,8 @@ Before:
call ale#test#SetDirectory('/testplugin/test')
call ale#test#SetFilename('dummy.txt')
Save g:ale_default_navigation
let g:old_filename = expand('%:p')
let g:Callback = ''
let g:message_list = []
@@ -9,6 +11,7 @@ Before:
let g:capability_checked = ''
let g:conn_id = v:null
let g:InitCallback = v:null
let g:ale_default_navigation = 'buffer'
runtime autoload/ale/linter.vim
runtime autoload/ale/lsp_linter.vim
@@ -54,6 +57,8 @@ Before:
endfunction
After:
Restore
if g:conn_id isnot v:null
call ale#lsp#RemoveConnectionWithID(g:conn_id)
endif
@@ -164,7 +169,7 @@ Execute(Other files should be jumped to for definition responses in tabs too):
AssertEqual {}, ale#definition#GetMap()
Execute(Other files should be jumped to for definition responses in splits too):
call ale#definition#SetMap({3: {'open_in': 'horizontal-split'}})
call ale#definition#SetMap({3: {'open_in': 'split'}})
call ale#definition#HandleTSServerResponse(
\ 1,
\ {
@@ -189,7 +194,7 @@ Execute(Other files should be jumped to for definition responses in splits too):
AssertEqual {}, ale#definition#GetMap()
Execute(Other files should be jumped to for definition responses in vsplits too):
call ale#definition#SetMap({3: {'open_in': 'vertical-split'}})
call ale#definition#SetMap({3: {'open_in': 'vsplit'}})
call ale#definition#HandleTSServerResponse(
\ 1,
\ {
@@ -241,7 +246,32 @@ Execute(tsserver tab definition requests should be sent):
runtime ale_linters/typescript/tsserver.vim
call setpos('.', [bufnr(''), 2, 5, 0])
ALEGoToDefinitionInTab
ALEGoToDefinition -tab
" We shouldn't register the callback yet.
AssertEqual '''''', string(g:Callback)
AssertEqual type(function('type')), type(g:InitCallback)
call g:InitCallback()
AssertEqual 'definition', g:capability_checked
AssertEqual
\ 'function(''ale#definition#HandleTSServerResponse'')',
\ string(g:Callback)
AssertEqual
\ [
\ ale#lsp#tsserver_message#Change(bufnr('')),
\ [0, 'ts@definition', {'file': expand('%:p'), 'line': 2, 'offset': 5}]
\ ],
\ g:message_list
AssertEqual {'42': {'open_in': 'tab'}}, ale#definition#GetMap()
Execute(The default navigation type should be used):
runtime ale_linters/typescript/tsserver.vim
call setpos('.', [bufnr(''), 2, 5, 0])
let g:ale_default_navigation = 'tab'
ALEGoToDefinition
" We shouldn't register the callback yet.
AssertEqual '''''', string(g:Callback)
@@ -448,7 +478,7 @@ Execute(LSP tab definition requests should be sent):
let b:ale_linters = ['pyls']
call setpos('.', [bufnr(''), 1, 5, 0])
ALEGoToDefinitionInTab
ALEGoToDefinition -tab
" We shouldn't register the callback yet.
AssertEqual '''''', string(g:Callback)

View File

@@ -7,6 +7,8 @@ Before:
Save g:ale_set_loclist
Save g:ale_set_quickfix
Save g:ale_set_signs
Save g:ale_exclude_highlights
Save b:ale_exclude_highlights
runtime autoload/ale/highlight.vim
@@ -20,6 +22,8 @@ Before:
let g:ale_set_quickfix = 0
let g:ale_set_loclist = 0
let g:ale_echo_cursor = 0
let g:ale_exclude_highlights = []
let b:ale_exclude_highlights = []
function! GenerateResults(buffer, output)
return [
@@ -363,6 +367,23 @@ Execute(Highlights should always be cleared when the buffer highlight list is em
\ GetMatchesWithoutIDs()
endif
Execute(Highlights should be hidden when excluded):
let b:ale_exclude_highlights = ['ig.*ore', 'nope']
call ale#highlight#SetHighlights(bufnr('%'), [
\ {'bufnr': bufnr('%'), 'type': 'E', 'lnum': 1, 'col': 1, 'text': 'hello'},
\ {'bufnr': bufnr('%'), 'type': 'E', 'lnum': 2, 'col': 1, 'text': 'ignore'},
\ {'bufnr': bufnr('%'), 'type': 'E', 'lnum': 3, 'col': 1, 'text': 'nope'},
\ {'bufnr': bufnr('%'), 'type': 'E', 'lnum': 4, 'col': 1, 'text': 'world'},
\])
AssertEqual
\ [
\ {'group': 'ALEError', 'priority': 10, 'pos1': [1, 1, 1]},
\ {'group': 'ALEError', 'priority': 10, 'pos1': [4, 1, 1]},
\ ],
\ GetMatchesWithoutIDs()
Execute(Highlights should be cleared when ALE is disabled):
let g:ale_enabled = 1
call ale#highlight#SetHighlights(bufnr(''), [

View File

@@ -57,8 +57,9 @@ Before:
call add(g:expr_list, a:expr)
endfunction
function! ale#code_action#HandleCodeAction(code_action) abort
function! ale#code_action#HandleCodeAction(code_action, should_save) abort
let g:handle_code_action_called = 1
AssertEqual v:false, a:should_save
call add(g:code_actions, a:code_action)
endfunction

View File

@@ -57,8 +57,9 @@ Before:
call add(g:expr_list, a:expr)
endfunction
function! ale#code_action#HandleCodeAction(code_action) abort
function! ale#code_action#HandleCodeAction(code_action, should_save) abort
let g:handle_code_action_called = 1
AssertEqual v:true, a:should_save
call add(g:code_actions, a:code_action)
endfunction

View File

@@ -15,7 +15,7 @@ Given(A file with a Bash hashbang):
Execute(/bin/bash should be detected appropriately):
AssertEqual 'bash', ale#handlers#sh#GetShellType(bufnr(''))
AssertEqual 'bash', ale_linters#sh#shell#GetExecutable(bufnr(''))
AssertEqual 'bash', ale_linters#sh#shellcheck#GetDialectArgument(bufnr(''))
AssertEqual 'bash', ale#handlers#shellcheck#GetDialectArgument(bufnr(''))
Given(A file with /bin/sh):
#!/usr/bin/env sh -eu --foobar
@@ -23,7 +23,7 @@ Given(A file with /bin/sh):
Execute(/bin/sh should be detected appropriately):
AssertEqual 'sh', ale#handlers#sh#GetShellType(bufnr(''))
AssertEqual 'sh', ale_linters#sh#shell#GetExecutable(bufnr(''))
AssertEqual 'sh', ale_linters#sh#shellcheck#GetDialectArgument(bufnr(''))
AssertEqual 'sh', ale#handlers#shellcheck#GetDialectArgument(bufnr(''))
Given(A file with bash as an argument to env):
#!/usr/bin/env bash
@@ -31,7 +31,7 @@ Given(A file with bash as an argument to env):
Execute(/usr/bin/env bash should be detected appropriately):
AssertEqual 'bash', ale#handlers#sh#GetShellType(bufnr(''))
AssertEqual 'bash', ale_linters#sh#shell#GetExecutable(bufnr(''))
AssertEqual 'bash', ale_linters#sh#shellcheck#GetDialectArgument(bufnr(''))
AssertEqual 'bash', ale#handlers#shellcheck#GetDialectArgument(bufnr(''))
Given(A file with a tcsh hash bang and arguments):
#!/usr/bin/env tcsh -eu --foobar
@@ -39,7 +39,7 @@ Given(A file with a tcsh hash bang and arguments):
Execute(tcsh should be detected appropriately):
AssertEqual 'tcsh', ale#handlers#sh#GetShellType(bufnr(''))
AssertEqual 'tcsh', ale_linters#sh#shell#GetExecutable(bufnr(''))
AssertEqual 'tcsh', ale_linters#sh#shellcheck#GetDialectArgument(bufnr(''))
AssertEqual 'tcsh', ale#handlers#shellcheck#GetDialectArgument(bufnr(''))
Given(A file with a zsh hash bang and arguments):
#!/usr/bin/env zsh -eu --foobar
@@ -47,7 +47,7 @@ Given(A file with a zsh hash bang and arguments):
Execute(zsh should be detected appropriately):
AssertEqual 'zsh', ale#handlers#sh#GetShellType(bufnr(''))
AssertEqual 'zsh', ale_linters#sh#shell#GetExecutable(bufnr(''))
AssertEqual 'zsh', ale_linters#sh#shellcheck#GetDialectArgument(bufnr(''))
AssertEqual 'zsh', ale#handlers#shellcheck#GetDialectArgument(bufnr(''))
Given(A file with a csh hash bang and arguments):
#!/usr/bin/env csh -eu --foobar
@@ -55,7 +55,7 @@ Given(A file with a csh hash bang and arguments):
Execute(csh should be detected appropriately):
AssertEqual 'csh', ale#handlers#sh#GetShellType(bufnr(''))
AssertEqual 'csh', ale_linters#sh#shell#GetExecutable(bufnr(''))
AssertEqual 'csh', ale_linters#sh#shellcheck#GetDialectArgument(bufnr(''))
AssertEqual 'csh', ale#handlers#shellcheck#GetDialectArgument(bufnr(''))
Given(A file with a ksh hashbang):
#!/bin/ksh
@@ -63,7 +63,7 @@ Given(A file with a ksh hashbang):
Execute(/bin/ksh should be detected appropriately):
AssertEqual 'ksh', ale#handlers#sh#GetShellType(bufnr(''))
AssertEqual 'ksh', ale_linters#sh#shell#GetExecutable(bufnr(''))
AssertEqual 'ksh', ale_linters#sh#shellcheck#GetDialectArgument(bufnr(''))
AssertEqual 'ksh', ale#handlers#shellcheck#GetDialectArgument(bufnr(''))
Given(A file with a ksh as an argument to env):
#!/usr/bin/env ksh
@@ -71,7 +71,7 @@ Given(A file with a ksh as an argument to env):
Execute(ksh should be detected appropriately):
AssertEqual 'ksh', ale#handlers#sh#GetShellType(bufnr(''))
AssertEqual 'ksh', ale_linters#sh#shell#GetExecutable(bufnr(''))
AssertEqual 'ksh', ale_linters#sh#shellcheck#GetDialectArgument(bufnr(''))
AssertEqual 'ksh', ale#handlers#shellcheck#GetDialectArgument(bufnr(''))
Given(A file with a sh hash bang and arguments):
#!/usr/bin/env sh -eu --foobar
@@ -79,24 +79,24 @@ Given(A file with a sh hash bang and arguments):
Execute(sh should be detected appropriately):
AssertEqual 'sh', ale#handlers#sh#GetShellType(bufnr(''))
AssertEqual 'sh', ale_linters#sh#shell#GetExecutable(bufnr(''))
AssertEqual 'sh', ale_linters#sh#shellcheck#GetDialectArgument(bufnr(''))
AssertEqual 'sh', ale#handlers#shellcheck#GetDialectArgument(bufnr(''))
Given(A file without a hashbang):
Execute(The bash dialect should be used for shellcheck if b:is_bash is 1):
let b:is_bash = 1
AssertEqual 'bash', ale_linters#sh#shellcheck#GetDialectArgument(bufnr(''))
AssertEqual 'bash', ale#handlers#shellcheck#GetDialectArgument(bufnr(''))
Execute(The sh dialect should be used for shellcheck if b:is_sh is 1):
let b:is_sh = 1
AssertEqual 'sh', ale_linters#sh#shellcheck#GetDialectArgument(bufnr(''))
AssertEqual 'sh', ale#handlers#shellcheck#GetDialectArgument(bufnr(''))
Execute(The ksh dialect should be used for shellcheck if b:is_kornshell is 1):
let b:is_kornshell = 1
AssertEqual 'ksh', ale_linters#sh#shellcheck#GetDialectArgument(bufnr(''))
AssertEqual 'ksh', ale#handlers#shellcheck#GetDialectArgument(bufnr(''))
Given(A file with /bin/ash):
#!/bin/ash
@@ -106,7 +106,7 @@ Execute(The ash dialect should be used for the shell and the base function):
AssertEqual 'ash', ale_linters#sh#shell#GetExecutable(bufnr(''))
Execute(dash should be used for shellcheck, which has no ash dialect):
AssertEqual 'dash', ale_linters#sh#shellcheck#GetDialectArgument(bufnr(''))
AssertEqual 'dash', ale#handlers#shellcheck#GetDialectArgument(bufnr(''))
Given(A file with /bin/dash):
#!/bin/dash
@@ -116,4 +116,4 @@ Execute(The dash dialect should be used for the shell and the base function):
AssertEqual 'dash', ale_linters#sh#shell#GetExecutable(bufnr(''))
Execute(dash should be used for shellcheck):
AssertEqual 'dash', ale_linters#sh#shellcheck#GetDialectArgument(bufnr(''))
AssertEqual 'dash', ale#handlers#shellcheck#GetDialectArgument(bufnr(''))