merge master -- apparently someone else added dhall?

This commit is contained in:
toastal
2020-09-08 10:08:00 +07:00
182 changed files with 4228 additions and 2146 deletions

View File

@@ -18,11 +18,10 @@ After:
call ale#assert#TearDownLinterTest()
Execute(The executable should be configurable):
AssertLinter 'gcc',
\ ale#Escape('gcc') . ' -x ada -c -gnatc'
\ . ' -o ' . b:out_file
\ . ' -I ' . ale#Escape(getcwd())
\ . ' -I %s:h'
\ . ' -gnatwa -gnatq %t'
let b:ale_ada_gcc_executable = 'foo'
@@ -30,15 +29,14 @@ Execute(The executable should be configurable):
AssertLinter 'foo',
\ ale#Escape('foo') . ' -x ada -c -gnatc'
\ . ' -o ' . b:out_file
\ . ' -I ' . ale#Escape(getcwd())
\ . ' -I %s:h'
\ . ' -gnatwa -gnatq %t'
Execute(The options should be configurable):
let g:ale_ada_gcc_options = '--foo --bar'
AssertLinter 'gcc',
\ ale#Escape('gcc') . ' -x ada -c -gnatc'
\ . ' -o ' . b:out_file
\ . ' -I ' . ale#Escape(getcwd())
\ . ' -I %s:h'
\ . ' --foo --bar %t'

View File

@@ -3,7 +3,7 @@ Before:
call ale#test#SetFilename('test.cpp')
let b:command_tail = ' -x assembler'
\ . ' -o ' . (has('win32') ? 'nul': '/dev/null')
\ . '-iquote ' . ale#Escape(g:dir)
\ . '-iquote %s:h'
\ . ' -Wall -'
After:

View File

@@ -0,0 +1,55 @@
Before:
Save g:ale_c_parse_makefile
Save g:ale_history_enabled
let g:ale_c_parse_makefile = 0
let g:ale_history_enabled = 0
let g:get_cflags_return_value = ''
let g:executable_map = {}
runtime autoload/ale/c.vim
runtime autoload/ale/engine.vim
function! ale#engine#IsExecutable(buffer, executable) abort
return has_key(g:executable_map, a:executable)
endfunction
function! ale#c#GetCFlags(buffer, output) abort
return g:get_cflags_return_value
endfunction
call ale#assert#SetUpLinterTest('c', 'cc')
let b:command_tail = ' -S -x c'
\ . ' -o ' . (has('win32') ? 'nul': '/dev/null')
\ . ' -iquote %s:h'
\ . ' -std=c11 -Wall -'
After:
unlet! g:get_cflags_return_value
unlet! g:executable_map
unlet! b:command_tail
runtime autoload/ale/c.vim
runtime autoload/ale/engine.vim
call ale#assert#TearDownLinterTest()
Execute(clang should be used instead of gcc, if available):
let g:executable_map = {'clang': 1}
AssertLinter 'clang', [ale#Escape('clang') . b:command_tail]
Execute(The executable should be configurable):
AssertLinter 'gcc', [ale#Escape('gcc') . b:command_tail]
let b:ale_c_cc_executable = 'foobar'
AssertLinter 'foobar', [ale#Escape('foobar') . b:command_tail]
Execute(The -std flag should be replaced by parsed C flags):
let b:command_tail = substitute(b:command_tail, 'c11', 'c99 ', '')
let g:get_cflags_return_value = '-std=c99'
AssertLinter 'gcc', ale#Escape('gcc') . b:command_tail

View File

@@ -1,20 +0,0 @@
Before:
Save g:ale_c_parse_makefile
let g:ale_c_parse_makefile = 0
call ale#assert#SetUpLinterTest('c', 'clang')
let b:command_tail = ' -S -x c -fsyntax-only -iquote'
\ . ' ' . ale#Escape(getcwd())
\ . ' -std=c11 -Wall -'
After:
unlet! b:command_tail
call ale#assert#TearDownLinterTest()
Execute(The executable should be configurable):
AssertLinter 'clang', [ale#Escape('clang') . b:command_tail]
let b:ale_c_clang_executable = 'foobar'
AssertLinter 'foobar', [ale#Escape('foobar') . b:command_tail]

View File

@@ -1,22 +0,0 @@
Before:
Save g:ale_c_parse_makefile
let g:ale_c_parse_makefile = 0
call ale#assert#SetUpLinterTest('c', 'gcc')
let b:command_tail = ' -S -x c'
\ . ' -o ' . (has('win32') ? 'nul': '/dev/null')
\ . ' -iquote ' . ale#Escape(getcwd())
\ . ' -std=c11 -Wall -'
After:
call ale#assert#TearDownLinterTest()
unlet! b:command_tail
Execute(The executable should be configurable):
AssertLinter 'gcc', [ale#Escape('gcc') . b:command_tail]
let b:ale_c_gcc_executable = 'foobar'
AssertLinter 'foobar', [ale#Escape('foobar') . b:command_tail]

View File

@@ -7,6 +7,7 @@ Before:
Save g:__ale_c_project_filenames
let g:original_project_filenames = g:__ale_c_project_filenames
let g:executable_map = {}
" Remove the .git/HEAD dir for C import paths for these tests.
" The tests run inside of a git repo.
@@ -18,106 +19,67 @@ Before:
let g:ale_c_parse_compile_commands = 0
let g:ale_c_parse_makefile = 0
runtime autoload/ale/engine.vim
function! ale#engine#IsExecutable(buffer, executable) abort
return has_key(g:executable_map, a:executable)
endfunction
After:
Restore
unlet! g:original_project_filenames
unlet! g:executable_map
runtime autoload/ale/engine.vim
call ale#assert#TearDownLinterTest()
Execute(The C GCC handler should include 'include' directories for projects with a Makefile):
call ale#assert#SetUpLinterTest('c', 'gcc')
Execute(The C cc linter should include 'include' directories for projects with a Makefile):
call ale#assert#SetUpLinterTest('c', 'cc')
call ale#test#SetFilename('../test_c_projects/makefile_project/subdir/file.c')
let g:ale_c_gcc_options = ''
let g:ale_c_cc_options = ''
AssertLinter 'gcc',
\ ale#Escape('gcc')
\ . ' -S -x c -o ' . (has('win32') ? 'nul': '/dev/null')
\ . ' -iquote ' . ale#Escape(ale#path#Simplify(g:dir . '/../test_c_projects/makefile_project/subdir'))
\ . ' -iquote %s:h'
\ . ' -I' . ale#Escape(ale#path#Simplify(g:dir . '/../test_c_projects/makefile_project/include'))
\ . ' -'
Execute(The C GCC handler should include 'include' directories for projects with a configure file):
call ale#assert#SetUpLinterTest('c', 'gcc')
Execute(The C cc linter should include 'include' directories for projects with a configure file):
call ale#assert#SetUpLinterTest('c', 'cc')
call ale#test#SetFilename('../test_c_projects/configure_project/subdir/file.c')
let g:ale_c_gcc_options = ''
let g:ale_c_cc_options = ''
AssertLinter 'gcc',
\ ale#Escape('gcc')
\ . ' -S -x c -o ' . (has('win32') ? 'nul': '/dev/null')
\ . ' -iquote ' . ale#Escape(ale#path#Simplify(g:dir . '/../test_c_projects/configure_project/subdir'))
\ . ' -iquote %s:h'
\ . ' -I' . ale#Escape(ale#path#Simplify(g:dir . '/../test_c_projects/configure_project/include'))
\ . ' -'
Execute(The C GCC handler should include root directories for projects with .h files in them):
call ale#assert#SetUpLinterTest('c', 'gcc')
Execute(The C cc linter should include root directories for projects with .h files in them):
call ale#assert#SetUpLinterTest('c', 'cc')
call ale#test#SetFilename('../test_c_projects/h_file_project/subdir/file.c')
let g:ale_c_gcc_options = ''
let g:ale_c_cc_options = ''
AssertLinter 'gcc',
\ ale#Escape('gcc')
\ . ' -S -x c -o ' . (has('win32') ? 'nul': '/dev/null')
\ . ' -iquote ' . ale#Escape(ale#path#Simplify(g:dir . '/../test_c_projects/h_file_project/subdir'))
\ . ' -iquote %s:h'
\ . ' -I' . ale#Escape(ale#path#Simplify(g:dir . '/../test_c_projects/h_file_project'))
\ . ' -'
Execute(The C GCC handler should include root directories for projects with .hpp files in them):
call ale#assert#SetUpLinterTest('c', 'gcc')
Execute(The C cc linter should include root directories for projects with .hpp files in them):
call ale#assert#SetUpLinterTest('c', 'cc')
call ale#test#SetFilename('../test_c_projects/hpp_file_project/subdir/file.c')
let g:ale_c_gcc_options = ''
let g:ale_c_cc_options = ''
AssertLinter 'gcc',
\ ale#Escape('gcc')
\ . ' -S -x c -o ' . (has('win32') ? 'nul': '/dev/null')
\ . ' -iquote ' . ale#Escape(ale#path#Simplify(g:dir . '/../test_c_projects/hpp_file_project/subdir'))
\ . ' -I' . ale#Escape(ale#path#Simplify(g:dir . '/../test_c_projects/hpp_file_project'))
\ . ' -'
Execute(The C Clang handler should include 'include' directories for projects with a Makefile):
call ale#assert#SetUpLinterTest('c', 'clang')
call ale#test#SetFilename('../test_c_projects/makefile_project/subdir/file.c')
let g:ale_c_clang_options = ''
AssertLinter 'clang',
\ ale#Escape('clang')
\ . ' -S -x c -fsyntax-only'
\ . ' -iquote ' . ale#Escape(ale#path#Simplify(g:dir . '/../test_c_projects/makefile_project/subdir'))
\ . ' -I' . ale#Escape(ale#path#Simplify(g:dir . '/../test_c_projects/makefile_project/include'))
\ . ' -'
Execute(The C Clang handler should include 'include' directories for projects with a configure file):
call ale#assert#SetUpLinterTest('c', 'clang')
call ale#test#SetFilename('../test_c_projects/h_file_project/subdir/file.c')
let g:ale_c_clang_options = ''
AssertLinter 'clang',
\ ale#Escape('clang')
\ . ' -S -x c -fsyntax-only'
\ . ' -iquote ' . ale#Escape(ale#path#Simplify(g:dir . '/../test_c_projects/h_file_project/subdir'))
\ . ' -I' . ale#Escape(ale#path#Simplify(g:dir . '/../test_c_projects/h_file_project'))
\ . ' -'
Execute(The C Clang handler should include root directories for projects with .h files in them):
call ale#assert#SetUpLinterTest('c', 'clang')
call ale#test#SetFilename('../test_c_projects/h_file_project/subdir/file.c')
let g:ale_c_clang_options = ''
AssertLinter 'clang',
\ ale#Escape('clang')
\ . ' -S -x c -fsyntax-only'
\ . ' -iquote ' . ale#Escape(ale#path#Simplify(g:dir . '/../test_c_projects/h_file_project/subdir'))
\ . ' -I' . ale#Escape(ale#path#Simplify(g:dir . '/../test_c_projects/h_file_project'))
\ . ' -'
Execute(The C Clang handler should include root directories for projects with .hpp files in them):
call ale#assert#SetUpLinterTest('c', 'clang')
call ale#test#SetFilename('../test_c_projects/hpp_file_project/subdir/file.c')
let g:ale_c_clang_options = ''
AssertLinter 'clang',
\ ale#Escape('clang')
\ . ' -S -x c -fsyntax-only'
\ . ' -iquote ' . ale#Escape(ale#path#Simplify(g:dir . '/../test_c_projects/hpp_file_project/subdir'))
\ . ' -iquote %s:h'
\ . ' -I' . ale#Escape(ale#path#Simplify(g:dir . '/../test_c_projects/hpp_file_project'))
\ . ' -'
@@ -131,99 +93,51 @@ Execute(The C ClangTidy handler should include 'include' directories for project
\ . ' %s '
\ . '-- -I' . ale#Escape(ale#path#Simplify(g:dir . '/../test_c_projects/makefile_project/include'))
Execute(The C++ GCC handler should include 'include' directories for projects with a Makefile):
call ale#assert#SetUpLinterTest('cpp', 'gcc')
Execute(The C++ cc linter should include 'include' directories for projects with a Makefile):
call ale#assert#SetUpLinterTest('cpp', 'cc')
call ale#test#SetFilename('../test_c_projects/makefile_project/subdir/file.cpp')
let g:ale_cpp_gcc_options = ''
let g:ale_cpp_cc_options = ''
AssertLinter 'gcc',
\ ale#Escape('gcc')
\ . ' -S -x c++ -o ' . (has('win32') ? 'nul': '/dev/null')
\ . ' -iquote ' . ale#Escape(ale#path#Simplify(g:dir . '/../test_c_projects/makefile_project/subdir'))
\ . ' -iquote %s:h'
\ . ' -I' . ale#Escape(ale#path#Simplify(g:dir . '/../test_c_projects/makefile_project/include'))
\ . ' -'
Execute(The C++ GCC handler should include 'include' directories for projects with a configure file):
call ale#assert#SetUpLinterTest('cpp', 'gcc')
Execute(The C++ cc linter should include 'include' directories for projects with a configure file):
call ale#assert#SetUpLinterTest('cpp', 'cc')
call ale#test#SetFilename('../test_c_projects/configure_project/subdir/file.cpp')
let g:ale_cpp_gcc_options = ''
let g:ale_cpp_cc_options = ''
AssertLinter 'gcc',
\ ale#Escape('gcc')
\ . ' -S -x c++ -o ' . (has('win32') ? 'nul': '/dev/null')
\ . ' -iquote ' . ale#Escape(ale#path#Simplify(g:dir . '/../test_c_projects/configure_project/subdir'))
\ . ' -iquote %s:h'
\ . ' -I' . ale#Escape(ale#path#Simplify(g:dir . '/../test_c_projects/configure_project/include'))
\ . ' -'
Execute(The C++ GCC handler should include root directories for projects with .h files in them):
call ale#assert#SetUpLinterTest('cpp', 'gcc')
Execute(The C++ cc linter should include root directories for projects with .h files in them):
call ale#assert#SetUpLinterTest('cpp', 'cc')
call ale#test#SetFilename('../test_c_projects/h_file_project/subdir/file.cpp')
let g:ale_cpp_gcc_options = ''
let g:ale_cpp_cc_options = ''
AssertLinter 'gcc',
\ ale#Escape('gcc')
\ . ' -S -x c++ -o ' . (has('win32') ? 'nul': '/dev/null')
\ . ' -iquote ' . ale#Escape(ale#path#Simplify(g:dir . '/../test_c_projects/h_file_project/subdir'))
\ . ' -iquote %s:h'
\ . ' -I' . ale#Escape(ale#path#Simplify(g:dir . '/../test_c_projects/h_file_project'))
\ . ' -'
Execute(The C++ GCC handler should include root directories for projects with .hpp files in them):
call ale#assert#SetUpLinterTest('cpp', 'gcc')
Execute(The C++ cc linter should include root directories for projects with .hpp files in them):
call ale#assert#SetUpLinterTest('cpp', 'cc')
call ale#test#SetFilename('../test_c_projects/hpp_file_project/subdir/file.cpp')
let g:ale_cpp_gcc_options = ''
let g:ale_cpp_cc_options = ''
AssertLinter 'gcc',
\ ale#Escape('gcc')
\ . ' -S -x c++ -o ' . (has('win32') ? 'nul': '/dev/null')
\ . ' -iquote ' . ale#Escape(ale#path#Simplify(g:dir . '/../test_c_projects/hpp_file_project/subdir'))
\ . ' -I' . ale#Escape(ale#path#Simplify(g:dir . '/../test_c_projects/hpp_file_project'))
\ . ' -'
Execute(The C++ Clang handler should include 'include' directories for projects with a Makefile):
call ale#assert#SetUpLinterTest('cpp', 'clang')
call ale#test#SetFilename('../test_c_projects/makefile_project/subdir/file.cpp')
let g:ale_cpp_clang_options = ''
AssertLinter 'clang++',
\ ale#Escape('clang++')
\ . ' -S -x c++ -fsyntax-only'
\ . ' -iquote ' . ale#Escape(ale#path#Simplify(g:dir . '/../test_c_projects/makefile_project/subdir'))
\ . ' -I' . ale#Escape(ale#path#Simplify(g:dir . '/../test_c_projects/makefile_project/include'))
\ . ' -'
Execute(The C++ Clang handler should include 'include' directories for projects with a configure file):
call ale#assert#SetUpLinterTest('cpp', 'clang')
call ale#test#SetFilename('../test_c_projects/configure_project/subdir/file.cpp')
let g:ale_cpp_clang_options = ''
AssertLinter 'clang++',
\ ale#Escape('clang++')
\ . ' -S -x c++ -fsyntax-only'
\ . ' -iquote ' . ale#Escape(ale#path#Simplify(g:dir . '/../test_c_projects/configure_project/subdir'))
\ . ' -I' . ale#Escape(ale#path#Simplify(g:dir . '/../test_c_projects/configure_project/include'))
\ . ' -'
Execute(The C++ Clang handler should include root directories for projects with .h files in them):
call ale#assert#SetUpLinterTest('cpp', 'clang')
call ale#test#SetFilename('../test_c_projects/h_file_project/subdir/file.cpp')
let g:ale_cpp_clang_options = ''
AssertLinter 'clang++',
\ ale#Escape('clang++')
\ . ' -S -x c++ -fsyntax-only'
\ . ' -iquote ' . ale#Escape(ale#path#Simplify(g:dir . '/../test_c_projects/h_file_project/subdir'))
\ . ' -I' . ale#Escape(ale#path#Simplify(g:dir . '/../test_c_projects/h_file_project'))
\ . ' -'
Execute(The C++ Clang handler should include root directories for projects with .hpp files in them):
call ale#assert#SetUpLinterTest('cpp', 'clang')
call ale#test#SetFilename('../test_c_projects/hpp_file_project/subdir/file.cpp')
let g:ale_cpp_clang_options = ''
AssertLinter 'clang++',
\ ale#Escape('clang++')
\ . ' -S -x c++ -fsyntax-only'
\ . ' -iquote ' . ale#Escape(ale#path#Simplify(g:dir . '/../test_c_projects/hpp_file_project/subdir'))
\ . ' -iquote %s:h'
\ . ' -I' . ale#Escape(ale#path#Simplify(g:dir . '/../test_c_projects/hpp_file_project'))
\ . ' -'

View File

@@ -0,0 +1,55 @@
Before:
Save g:ale_c_parse_makefile
Save g:ale_history_enabled
let g:ale_c_parse_makefile = 0
let g:ale_history_enabled = 0
let g:get_cflags_return_value = ''
let g:executable_map = {}
runtime autoload/ale/c.vim
runtime autoload/ale/engine.vim
function! ale#engine#IsExecutable(buffer, executable) abort
return has_key(g:executable_map, a:executable)
endfunction
function! ale#c#GetCFlags(buffer, output) abort
return g:get_cflags_return_value
endfunction
call ale#assert#SetUpLinterTest('cpp', 'cc')
let b:command_tail = ' -S -x c++'
\ . ' -o ' . (has('win32') ? 'nul': '/dev/null')
\ . ' -iquote %s:h'
\ . ' -std=c++14 -Wall -'
After:
unlet! g:get_cflags_return_value
unlet! g:executable_map
unlet! b:command_tail
runtime autoload/ale/c.vim
runtime autoload/ale/engine.vim
call ale#assert#TearDownLinterTest()
Execute(clang++ should be used instead of gcc, if available):
let g:executable_map = {'clang++': 1}
AssertLinter 'clang++', [ale#Escape('clang++') . b:command_tail]
Execute(The executable should be configurable):
AssertLinter 'gcc', [ale#Escape('gcc') . b:command_tail]
let b:ale_cpp_cc_executable = 'foobar'
AssertLinter 'foobar', [ale#Escape('foobar') . b:command_tail]
Execute(The -std flag should be replaced by parsed C flags):
let b:command_tail = substitute(b:command_tail, 'c++14', 'c++11 ', '')
let g:get_cflags_return_value = '-std=c++11'
AssertLinter 'gcc', ale#Escape('gcc') . b:command_tail

View File

@@ -1,19 +0,0 @@
Before:
Save g:ale_c_parse_makefile
let g:ale_c_parse_makefile = 0
call ale#assert#SetUpLinterTest('cpp', 'clang')
let b:command_tail = ' -S -x c++ -fsyntax-only -iquote'
\ . ' ' . ale#Escape(getcwd())
\ . ' -std=c++14 -Wall -'
After:
unlet! b:command_tail
call ale#assert#TearDownLinterTest()
Execute(The executable should be configurable):
AssertLinter 'clang++', ale#Escape('clang++') . b:command_tail
let b:ale_cpp_clang_executable = 'foobar'
AssertLinter 'foobar', ale#Escape('foobar') . b:command_tail

View File

@@ -1,20 +0,0 @@
Before:
Save g:ale_c_parse_makefile
let g:ale_c_parse_makefile = 0
call ale#assert#SetUpLinterTest('cpp', 'gcc')
let b:command_tail = ' -S -x c++'
\ . ' -o ' . (has('win32') ? 'nul': '/dev/null')
\ . ' -iquote ' . ale#Escape(getcwd())
\ . ' -std=c++14 -Wall -'
After:
unlet! b:command_tail
call ale#assert#TearDownLinterTest()
Execute(The executable should be configurable):
AssertLinter 'gcc', ale#Escape('gcc') . b:command_tail
let b:ale_cpp_gcc_executable = 'foobar'
AssertLinter 'foobar', ale#Escape('foobar') . b:command_tail

View File

@@ -8,6 +8,18 @@ After:
call ale#assert#TearDownLinterTest()
Execute(Builds credo command with normal project):
AssertLinter 'mix',
\ ale#path#CdString(ale#path#Simplify(g:dir . '/elixir_paths/mix_project'))
\ . 'mix help credo && mix credo suggest --format=flycheck --read-from-stdin %s'
Execute(Builds credo command with umbrella project):
call ale#test#SetFilename('elixir_paths/umbrella_project/apps/mix_project/lib/app.ex')
AssertLinter 'mix',
\ ale#path#CdString(ale#path#Simplify(g:dir . '/elixir_paths/umbrella_project'))
\ . 'mix help credo && mix credo suggest --format=flycheck --read-from-stdin %s'
Execute(Builds credo command with --strict mode when set to 1):
let g:ale_elixir_credo_strict = 1

View File

@@ -0,0 +1,17 @@
Before:
call ale#assert#SetUpLinterTest('handlebars', 'embertemplatelint')
GivenCommandOutput ['1.6.0']
After:
call ale#assert#TearDownLinterTest()
Execute(ember-template-lint executables runs the right command):
AssertLinter 'ember-template-lint',
\ ale#Escape('ember-template-lint') . ' --json --filename %s'
Execute(old ember-template-lint executables runs the right command):
GivenCommandOutput []
AssertLinter 'ember-template-lint',
\ ale#Escape('ember-template-lint') . ' --json %t'

View File

@@ -34,13 +34,52 @@ Execute(The flake8 callbacks should return the correct default values):
\]
Execute(The option for disabling changing directories should work):
let g:ale_python_flake8_change_directory = 0
let g:ale_python_flake8_change_directory = 'off'
AssertLinter 'flake8', [
\ ale#Escape('flake8') . ' --version',
\ ale#Escape('flake8') . ' --format=default --stdin-display-name %s -',
\]
let g:ale_python_flake8_change_directory = 0
AssertLinter 'flake8', [
\ ale#Escape('flake8') . ' --format=default --stdin-display-name %s -',
\]
" Invalid options should be considered the same as turning the setting off.
let g:ale_python_flake8_change_directory = 'xxx'
AssertLinter 'flake8', [
\ ale#Escape('flake8') . ' --format=default --stdin-display-name %s -',
\]
Execute(The option for changing directory to project root should work):
silent execute 'file ' . fnameescape(g:dir . '/python_paths/namespace_package_tox/namespace/foo/bar.py')
AssertLinter 'flake8', [
\ ale#Escape('flake8') . ' --version',
\ ale#path#CdString(ale#python#FindProjectRootIni(bufnr('')))
\ . ale#Escape('flake8') . ' --format=default --stdin-display-name %s -',
\]
Execute(The option for changing directory to file dir should work):
let g:ale_python_flake8_change_directory = 'file'
silent execute 'file ' . fnameescape(g:dir . '/python_paths/namespace_package_tox/namespace/foo/bar.py')
AssertLinter 'flake8', [
\ ale#Escape('flake8') . ' --version',
\ ale#path#BufferCdString(bufnr(''))
\ . ale#Escape('flake8') . ' --format=default --stdin-display-name %s -',
\]
let g:ale_python_flake8_change_directory = 1
AssertLinter 'flake8', [
\ ale#path#BufferCdString(bufnr(''))
\ . ale#Escape('flake8') . ' --format=default --stdin-display-name %s -',
\]
Execute(The flake8 command callback should let you set options):
let g:ale_python_flake8_options = '--some-option'
@@ -163,5 +202,5 @@ Execute(Pipenv is detected when python_flake8_auto_pipenv is set):
call ale#test#SetFilename('../python_fixtures/pipenv/whatever.py')
AssertLinter 'pipenv',
\ ale#path#BufferCdString(bufnr(''))
\ ale#path#CdString(ale#python#FindProjectRootIni(bufnr('')))
\ . ale#Escape('pipenv') . ' run flake8 --format=default --stdin-display-name %s -'

View File

@@ -11,14 +11,14 @@ After:
Execute(The default commands should be correct):
AssertLinter 'go',
\ ale#path#CdString(expand('%:p:h'))
\ ale#path#BufferCdString(bufnr(''))
\ . 'go test -c -o /dev/null ./'
Execute(Go environment variables should be supported):
let b:ale_go_go111module = 'on'
AssertLinter 'go',
\ ale#path#CdString(expand('%:p:h'))
\ ale#path#BufferCdString(bufnr(''))
\ . ale#Env('GO111MODULE', 'on')
\ . 'go test -c -o /dev/null ./'
@@ -28,7 +28,7 @@ Execute(Extra options should be supported):
let g:ale_go_gobuild_options = '--foo-bar'
AssertLinter 'go',
\ ale#path#CdString(expand('%:p:h'))
\ ale#path#BufferCdString(bufnr(''))
\ . 'go test --foo-bar -c -o /dev/null ./'
let g:ale_go_gobuild_options = ''
@@ -37,5 +37,5 @@ Execute(The executable should be configurable):
let g:ale_go_go_executable = 'foobar'
AssertLinter 'foobar',
\ ale#path#CdString(expand('%:p:h'))
\ ale#path#BufferCdString(bufnr(''))
\ . 'foobar test -c -o /dev/null ./'

View File

@@ -1,5 +1,8 @@
Before:
Save g:ale_go_go111module
Save b:ale_go_go111module
let b:ale_go_go111module = ''
call ale#assert#SetUpLinterTest('go', 'gofmt')
call ale#test#SetFilename('../go_files/testfile2.go')

View File

@@ -13,7 +13,7 @@ After:
Execute(The golangci-lint defaults should be correct):
AssertLinter 'golangci-lint',
\ ale#path#CdString(expand('%:p:h'))
\ ale#path#BufferCdString(bufnr(''))
\ . ale#Escape('golangci-lint')
\ . ' run ' . ale#Escape(expand('%' . ':t'))
\ . ' --enable-all'
@@ -22,7 +22,7 @@ Execute(The golangci-lint callback should use a configured executable):
let b:ale_go_golangci_lint_executable = 'something else'
AssertLinter 'something else',
\ ale#path#CdString(expand('%:p:h'))
\ ale#path#BufferCdString(bufnr(''))
\ . ale#Escape('something else')
\ . ' run ' . ale#Escape(expand('%' . ':t'))
\ . ' --enable-all'
@@ -31,7 +31,7 @@ Execute(The golangci-lint callback should use configured options):
let b:ale_go_golangci_lint_options = '--foobar'
AssertLinter 'golangci-lint',
\ ale#path#CdString(expand('%:p:h'))
\ ale#path#BufferCdString(bufnr(''))
\ . ale#Escape('golangci-lint')
\ . ' run ' . ale#Escape(expand('%' . ':t'))
\ . ' --foobar'
@@ -40,7 +40,7 @@ Execute(The golangci-lint callback should support environment variables):
let b:ale_go_go111module = 'on'
AssertLinter 'golangci-lint',
\ ale#path#CdString(expand('%:p:h'))
\ ale#path#BufferCdString(bufnr(''))
\ . ale#Env('GO111MODULE', 'on')
\ . ale#Escape('golangci-lint')
\ . ' run ' . ale#Escape(expand('%' . ':t'))
@@ -50,5 +50,5 @@ Execute(The golangci-lint `lint_package` option should use the correct command):
let b:ale_go_golangci_lint_package = 1
AssertLinter 'golangci-lint',
\ ale#path#CdString(expand('%:p:h'))
\ ale#path#BufferCdString(bufnr(''))
\ . ale#Escape('golangci-lint') . ' run --enable-all'

View File

@@ -13,7 +13,7 @@ After:
Execute(The gometalinter defaults should be correct):
AssertLinter 'gometalinter',
\ ale#path#CdString(expand('%:p:h'))
\ ale#path#BufferCdString(bufnr(''))
\ . ale#Escape('gometalinter')
\ . ' --include=' . ale#Escape(ale#util#EscapePCRE(expand('%' . ':t')))
\ . ' .'
@@ -22,7 +22,7 @@ Execute(The gometalinter callback should use a configured executable):
let b:ale_go_gometalinter_executable = 'something else'
AssertLinter 'something else',
\ ale#path#CdString(expand('%:p:h'))
\ ale#path#BufferCdString(bufnr(''))
\ . ale#Escape('something else')
\ . ' --include=' . ale#Escape(ale#util#EscapePCRE(expand('%' . ':t')))
\ . ' .'
@@ -31,7 +31,7 @@ Execute(The gometalinter callback should use configured options):
let b:ale_go_gometalinter_options = '--foobar'
AssertLinter 'gometalinter',
\ ale#path#CdString(expand('%:p:h'))
\ ale#path#BufferCdString(bufnr(''))
\ . ale#Escape('gometalinter')
\ . ' --include=' . ale#Escape(ale#util#EscapePCRE(expand('%' . ':t')))
\ . ' --foobar' . ' .'
@@ -40,7 +40,7 @@ Execute(The gometalinter should use configured environment variables):
let b:ale_go_go111module = 'off'
AssertLinter 'gometalinter',
\ ale#path#CdString(expand('%:p:h'))
\ ale#path#BufferCdString(bufnr(''))
\ . ale#Env('GO111MODULE', 'off')
\ . ale#Escape('gometalinter')
\ . ' --include=' . ale#Escape(ale#util#EscapePCRE(expand('%' . ':t')))
@@ -50,5 +50,5 @@ Execute(The gometalinter `lint_package` option should use the correct command):
let b:ale_go_gometalinter_lint_package = 1
AssertLinter 'gometalinter',
\ ale#path#CdString(expand('%:p:h'))
\ ale#path#BufferCdString(bufnr(''))
\ . ale#Escape('gometalinter') . ' .'

View File

@@ -11,11 +11,12 @@ After:
Execute(The default gosimple command should be correct):
AssertLinter 'gosimple',
\ ale#path#CdString(expand('%:p:h')) . ' gosimple .'
\ ale#path#BufferCdString(bufnr(''))
\ . ' gosimple .'
Execute(The gosimple command should support Go environment variables):
let b:ale_go_go111module = 'on'
AssertLinter 'gosimple',
\ ale#path#CdString(expand('%:p:h')) . ' '
\ . ale#Env('GO111MODULE', 'on') . 'gosimple .'
\ ale#path#BufferCdString(bufnr(''))
\ . ' ' . ale#Env('GO111MODULE', 'on') . 'gosimple .'

View File

@@ -11,7 +11,8 @@ After:
Execute(The default gotype command should be correct):
AssertLinter 'gotype',
\ ale#path#CdString(expand('%:p:h')) . ' gotype -e .'
\ ale#path#BufferCdString(bufnr(''))
\ . ' gotype -e .'
Execute(The gotype callback should ignore test files):
call ale#test#SetFilename('bla_test.go')
@@ -22,6 +23,6 @@ Execute(The gotype callback should support Go environment variables):
let b:ale_go_go111module = 'on'
AssertLinter 'gotype',
\ ale#path#CdString(expand('%:p:h')) . ' '
\ . ale#Env('GO111MODULE', 'on')
\ ale#path#BufferCdString(bufnr(''))
\ . ' ' . ale#Env('GO111MODULE', 'on')
\ . 'gotype -e .'

View File

@@ -13,22 +13,22 @@ After:
call ale#assert#TearDownLinterTest()
Execute(The default command should be correct):
AssertLinter 'go', ale#path#CdString(expand('%:p:h')) . ' go vet .'
AssertLinter 'go', ale#path#BufferCdString(bufnr('')) . ' go vet .'
Execute(Extra options should be supported):
let g:ale_go_govet_options = '--foo-bar'
AssertLinter 'go', ale#path#CdString(expand('%:p:h')) . ' go vet --foo-bar .'
AssertLinter 'go', ale#path#BufferCdString(bufnr('')) . ' go vet --foo-bar .'
Execute(The executable should be configurable):
let g:ale_go_go_executable = 'foobar'
AssertLinter 'foobar', ale#path#CdString(expand('%:p:h')) . ' foobar vet .'
AssertLinter 'foobar', ale#path#BufferCdString(bufnr('')) . ' foobar vet .'
Execute(Go environment variables should be supported):
let b:ale_go_go111module = 'on'
AssertLinter 'go',
\ ale#path#CdString(expand('%:p:h')) . ' '
\ ale#path#BufferCdString(bufnr('')) . ' '
\ . ale#Env('GO111MODULE', 'on')
\ . 'go vet .'

View File

@@ -6,6 +6,6 @@ After:
Execute(The linter should run from the directory of the file in the buffer):
AssertLinter 'gqlint',
\ ale#path#CdString(expand('%:p:h'))
\ ale#path#BufferCdString(bufnr(''))
\ . 'gqlint --reporter=simple'
\ . ' %t'

View File

@@ -3,7 +3,7 @@ Before:
call ale#test#SetFilename('dummy.java')
let g:cp_sep = has('unix') ? ':' : ';'
let g:prefix = ale#path#CdString(expand('%:p:h'))
let g:prefix = ale#path#BufferCdString(bufnr(''))
\ . ale#Escape('javac') . ' -Xlint'
function! GetCommand(previous_output) abort
@@ -51,7 +51,7 @@ Execute(The executable should be configurable):
let g:ale_java_javac_executable = 'foobar'
AssertLinter 'foobar',
\ ale#path#CdString(expand('%:p:h'))
\ ale#path#BufferCdString(bufnr(''))
\ . ale#Escape('foobar') . ' -Xlint'
\ . ' -d ' . ale#Escape('TEMP_DIR') . ' %t'
@@ -197,7 +197,8 @@ Execute(The javac callback should combine discovered sourcepath and manual ones)
let b:command = ale_linters#java#javac#GetCommand(bufnr(''), [], {})
AssertEqual
\ ale#path#CdString(expand('%:p:h')) . ale#Escape('javac') . ' -Xlint'
\ ale#path#BufferCdString(bufnr(''))
\ . 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/'),
@@ -210,7 +211,8 @@ Execute(The javac callback should combine discovered sourcepath and manual ones)
let b:command = ale_linters#java#javac#GetCommand(bufnr(''), [], {})
AssertEqual
\ ale#path#CdString(expand('%:p:h')) . ale#Escape('javac') . ' -Xlint'
\ ale#path#BufferCdString(bufnr(''))
\ . 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/'),
@@ -223,7 +225,8 @@ Execute(The javac callback should combine discovered sourcepath and manual ones)
let b:command = ale_linters#java#javac#GetCommand(bufnr(''), [], {})
AssertEqual
\ ale#path#CdString(expand('%:p:h')) . ale#Escape('javac') . ' -Xlint'
\ ale#path#BufferCdString(bufnr(''))
\ . 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/')
@@ -238,7 +241,8 @@ Execute(The javac callback should combine discovered sourcepath and manual ones)
let b:command = ale_linters#java#javac#GetCommand(bufnr(''), [], {})
AssertEqual
\ ale#path#CdString(expand('%:p:h')) . ale#Escape('javac') . ' -Xlint'
\ ale#path#BufferCdString(bufnr(''))
\ . 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/'),
@@ -253,7 +257,8 @@ Execute(The javac callback should detect source directories):
call ale#engine#InitBufferInfo(bufnr(''))
AssertLinter 'javac',
\ ale#path#CdString(expand('%:p:h')) . ale#Escape('javac') . ' -Xlint'
\ ale#path#BufferCdString(bufnr(''))
\ . ale#Escape('javac') . ' -Xlint'
\ . ' -sourcepath ' . ale#Escape(
\ ale#path#Simplify(g:dir . '/java_paths/src/main/java/')
\ )
@@ -272,7 +277,8 @@ Execute(The javac callback should combine detected source directories and classp
\], {})
AssertEqual
\ ale#path#CdString(expand('%:p:h')) . ale#Escape('javac') . ' -Xlint'
\ ale#path#BufferCdString(bufnr(''))
\ . ale#Escape('javac') . ' -Xlint'
\ . ' -cp ' . ale#Escape(join(['/foo/bar.jar', '/xyz/abc.jar'], g:cp_sep))
\ . ' -sourcepath ' . ale#Escape(
\ ale#path#Simplify(g:dir . '/java_paths/src/main/java/')
@@ -294,7 +300,8 @@ Execute(The javac callback should include src/test/java for test paths):
call ale#engine#InitBufferInfo(bufnr(''))
AssertLinter 'javac',
\ ale#path#CdString(expand('%:p:h')) . ale#Escape('javac') . ' -Xlint'
\ ale#path#BufferCdString(bufnr(''))
\ . 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/src/test/java/'),
@@ -307,7 +314,8 @@ Execute(The javac callback should include src/main/jaxb when available):
call ale#engine#InitBufferInfo(bufnr(''))
AssertLinter 'javac',
\ ale#path#CdString(expand('%:p:h')) . ale#Escape('javac') . ' -Xlint'
\ ale#path#BufferCdString(bufnr(''))
\ . ale#Escape('javac') . ' -Xlint'
\ . ' -sourcepath ' . ale#Escape(join([
\ ale#path#Simplify(g:dir . '/java_paths_with_jaxb/src/main/java/'),
\ ale#path#Simplify(g:dir . '/java_paths_with_jaxb/src/main/jaxb/'),
@@ -320,7 +328,8 @@ Execute(The javac callback should add -sourcepath even if src/java/main doesn't
call ale#engine#InitBufferInfo(bufnr(''))
AssertLinter 'javac',
\ ale#path#CdString(expand('%:p:h')) . ale#Escape('javac') . ' -Xlint'
\ ale#path#BufferCdString(bufnr(''))
\ . ale#Escape('javac') . ' -Xlint'
\ . ' -sourcepath ' . ale#Escape(join([
\ ale#path#Simplify(g:dir . '/java_paths_no_main/src/test/java/'),
\ ], g:cp_sep))

View File

@@ -6,7 +6,7 @@ After:
Execute(The default lintr command should be correct):
AssertLinter 'Rscript',
\ ale#path#CdString(getcwd())
\ ale#path#BufferCdString(bufnr(''))
\ . 'Rscript --vanilla -e '
\ . ale#Escape('suppressPackageStartupMessages(library(lintr));'
\ . 'lint(cache = FALSE, commandArgs(TRUE), '
@@ -17,7 +17,7 @@ Execute(The lintr options should be configurable):
let b:ale_r_lintr_options = 'with_defaults(object_usage_linter = NULL)'
AssertLinter 'Rscript',
\ ale#path#CdString(getcwd())
\ ale#path#BufferCdString(bufnr(''))
\ . 'Rscript --vanilla -e '
\ . ale#Escape('suppressPackageStartupMessages(library(lintr));'
\ . 'lint(cache = FALSE, commandArgs(TRUE), '
@@ -28,7 +28,7 @@ Execute(If the lint_package flag is set, lintr::lint_package should be called):
let b:ale_r_lintr_lint_package = 1
AssertLinter 'Rscript',
\ ale#path#CdString(getcwd())
\ ale#path#BufferCdString(bufnr(''))
\ . 'Rscript --vanilla -e '
\ . ale#Escape('suppressPackageStartupMessages(library(lintr));'
\ . 'lint_package(cache = FALSE, '

View File

@@ -0,0 +1,13 @@
Before:
call ale#assert#SetUpLinterTest('markdown', 'markdownlint')
After:
call ale#assert#TearDownLinterTest()
Execute(The default command should be correct):
AssertLinter 'markdownlint', ale#Escape('markdownlint') . ' %s'
Execute(The options should be configurable):
let g:ale_markdown_markdownlint_options = '--config ~/custom/.markdownlintrc'
AssertLinter 'markdownlint', ale#Escape('markdownlint') . ' --config ~/custom/.markdownlintrc %s'

View File

@@ -75,14 +75,14 @@ Execute(Setting executable to 'pipenv' appends 'run mypy'):
let g:ale_python_mypy_executable = 'path/to/pipenv'
AssertLinter 'path/to/pipenv',
\ ale#path#BufferCdString(bufnr(''))
\ ale#path#CdString(expand('#' . bufnr('') . ':p:h'))
\ . ale#Escape('path/to/pipenv') . ' run mypy'
\ . ' --show-column-numbers --shadow-file %s %t %s'
Execute(Pipenv is detected when python_mypy_auto_pipenv is set):
let g:ale_python_mypy_auto_pipenv = 1
call ale#test#SetFilename('/testplugin/test/python_fixtures/pipenv/whatever.py')
call ale#test#SetFilename('../python_fixtures/pipenv/whatever.py')
AssertLinter 'pipenv',
\ ale#path#BufferCdString(bufnr(''))
\ ale#path#CdString(expand('#' . bufnr('') . ':p:h'))
\ . ale#Escape('pipenv') . ' run mypy --show-column-numbers --shadow-file %s %t %s'

View File

@@ -2,9 +2,9 @@ Before:
call ale#assert#SetUpLinterTest('nasm', 'nasm')
let b:command_tail =
\ ' -X gnu -I ' . ale#Escape(getcwd() . (has('win32') ? '\' : '/')) . ' %s -o ' . (has('win32') ? 'NUL' : '/dev/null')
\ ' -X gnu -I %s:h' . (has('win32') ? '\' : '/') . ' %s -o ' . (has('win32') ? 'NUL' : '/dev/null')
let b:command_tail_opt =
\ ' -X gnu -I ' . ale#Escape(getcwd() . (has('win32') ? '\' : '/')) . ' -w+orphan-labels %s -o ' . (has('win32') ? 'NUL' : '/dev/null')
\ ' -X gnu -I %s:h' . (has('win32') ? '\' : '/') . ' -w+orphan-labels %s -o ' . (has('win32') ? 'NUL' : '/dev/null')
After:
unlet! b:command_tail
@@ -23,7 +23,8 @@ Execute(The options should be configurable):
let b:ale_nasm_nasm_options = '-w-macro-params'
AssertLinter 'nasm', ale#Escape('nasm')
\ . ' -X gnu -I ' . ale#Escape(getcwd() . (has('win32') ? '\' : '/')) . ' -w-macro-params %s -o ' . (has('win32') ? 'NUL' : '/dev/null')
\ . ' -X gnu -I %s:h' . (has('win32') ? '\' : '/')
\ . ' -w-macro-params %s -o ' . (has('win32') ? 'NUL' : '/dev/null')
Execute(The options should be used in command):
let b:ale_nasm_nasm_options = '-w+orphan-labels'

View File

@@ -2,6 +2,9 @@ Before:
call ale#assert#SetUpLinterTest('php', 'psalm')
After:
unlet! g:i
unlet! g:matched
if isdirectory(g:dir . '/.git')
call delete(g:dir . '/.git', 'd')
endif
@@ -22,19 +25,36 @@ Execute(Vendor executables should be detected):
\ . '/psalm-project/vendor/bin/psalm'
\ )) . ' --language-server'
let g:ale_php_psalm_use_global = 1
AssertLinter 'psalm',
\ ale#Escape('psalm') . ' --language-server'
Execute(User provided options should be used):
let g:ale_psalm_langserver_options = '--my-user-provided-option my-value'
let g:ale_php_psalm_options = '--my-user-provided-option my-value'
AssertLinter 'psalm',
\ ale#Escape('psalm')
\ . ' --language-server --my-user-provided-option my-value'
Execute(The project path should be correct for .git directories):
call ale#test#SetFilename('psalm-project/test.php')
let g:matched = 0
if !isdirectory(g:dir . '/.git')
call mkdir(g:dir . '/.git')
for g:i in range(4)
if !isdirectory(g:dir . '/.git')
call mkdir(g:dir . '/.git')
endif
try
AssertLSPProject g:dir
catch /.+/
endtry
let g:matched = 1
break
endfor
if !g:matched
AssertLSPProject g:dir
endif
AssertLSPProject g:dir

View File

@@ -1,5 +1,6 @@
Before:
call ale#assert#SetUpLinterTest('python', 'pydocstyle')
call ale#test#SetFilename('test.py')
After:
call ale#assert#TearDownLinterTest()
@@ -7,33 +8,33 @@ After:
Execute(The pydocstyle command callback should return default string):
AssertLinter 'pydocstyle',
\ ale#path#BufferCdString(bufnr(''))
\ . ale#Escape('pydocstyle') . ' ' . ale#Escape('dummy.txt')
\ . ale#Escape('pydocstyle') . ' %s:t'
Execute(The pydocstyle command callback should allow options):
let g:ale_python_pydocstyle_options = '--verbose'
AssertLinter 'pydocstyle',
\ ale#path#BufferCdString(bufnr(''))
\ . ale#Escape('pydocstyle') . ' --verbose ' . ale#Escape('dummy.txt')
\ . ale#Escape('pydocstyle') . ' --verbose %s:t'
Execute(The pydocstyle executable should be configurable):
let g:ale_python_pydocstyle_executable = '~/.local/bin/pydocstyle'
AssertLinter '~/.local/bin/pydocstyle',
\ ale#path#BufferCdString(bufnr(''))
\ . ale#Escape('~/.local/bin/pydocstyle') . ' ' . ale#Escape('dummy.txt')
\ . ale#Escape('~/.local/bin/pydocstyle') . ' %s:t'
Execute(Setting executable to 'pipenv' appends 'run pydocstyle'):
let g:ale_python_pydocstyle_executable = 'path/to/pipenv'
AssertLinter 'path/to/pipenv',
\ ale#path#BufferCdString(bufnr(''))
\ . ale#Escape('path/to/pipenv') . ' run pydocstyle ' . ale#Escape('dummy.txt')
\ . ale#Escape('path/to/pipenv') . ' run pydocstyle %s:t'
Execute(Pipenv is detected when python_pydocstyle_auto_pipenv is set):
let g:ale_python_pydocstyle_auto_pipenv = 1
call ale#test#SetFilename('/testplugin/test/python_fixtures/pipenv/whatever.py')
call ale#test#SetFilename('../python_fixtures/pipenv/whatever.py')
AssertLinter 'pipenv',
\ ale#path#BufferCdString(bufnr(''))
\ . ale#Escape('pipenv') . ' run pydocstyle ' . ale#Escape('whatever.py')
\ . ale#Escape('pipenv') . ' run pydocstyle %s:t'

View File

@@ -14,7 +14,7 @@ After:
Execute(The pylama command callback should return a default):
AssertLinter 'pylama',
\ ale#path#BufferCdString(bufnr(''))
\ ale#path#CdString(expand('#' . bufnr('') . ':p:h'))
\ . ale#Escape('pylama') . b:command_tail
Execute(The option for disabling changing directories should work):
@@ -26,14 +26,14 @@ Execute(The pylama executable should be configurable, and escaped properly):
let g:ale_python_pylama_executable = 'executable with spaces'
AssertLinter 'executable with spaces',
\ ale#path#BufferCdString(bufnr(''))
\ ale#path#CdString(expand('#' . bufnr('') . ':p:h'))
\ . ale#Escape('executable with spaces') . b:command_tail
Execute(The pylama command callback should let you set options):
let g:ale_python_pylama_options = '--some-option'
AssertLinter 'pylama',
\ ale#path#BufferCdString(bufnr(''))
\ ale#path#CdString(expand('#' . bufnr('') . ':p:h'))
\ . ale#Escape('pylama') . ' --some-option' . b:command_tail
Execute(The pylama command callback should switch directories to the detected project root):
@@ -73,13 +73,13 @@ Execute(Setting executable to 'pipenv' appends 'run pylama'):
let g:ale_python_pylama_executable = 'path/to/pipenv'
AssertLinter 'path/to/pipenv',
\ ale#path#BufferCdString(bufnr(''))
\ ale#path#CdString(expand('#' . bufnr('') . ':p:h'))
\ . ale#Escape('path/to/pipenv') . ' run pylama' . b:command_tail
Execute(Pipenv is detected when python_pylama_auto_pipenv is set):
let g:ale_python_pylama_auto_pipenv = 1
call ale#test#SetFilename('/testplugin/test/python_fixtures/pipenv/whatever.py')
call ale#test#SetFilename('../python_fixtures/pipenv/whatever.py')
AssertLinter 'pipenv',
\ ale#path#BufferCdString(bufnr(''))
\ ale#path#CdString(expand('#' . bufnr('') . ':p:h'))
\ . ale#Escape('pipenv') . ' run pylama' . b:command_tail

View File

@@ -1,4 +1,8 @@
Before:
Save g:ale_python_auto_pipenv
let g:ale_python_auto_pipenv = 0
call ale#assert#SetUpLinterTest('python', 'pylint')
let b:bin_dir = has('win32') ? 'Scripts' : 'bin'
@@ -13,7 +17,7 @@ After:
Execute(The pylint callbacks should return the correct default values):
AssertLinter 'pylint',
\ ale#path#BufferCdString(bufnr(''))
\ ale#path#CdString(expand('#' . bufnr('') . ':p:h'))
\ . ale#Escape('pylint') . ' ' . b:command_tail
Execute(The option for disabling changing directories should work):
@@ -25,14 +29,14 @@ Execute(The pylint executable should be configurable, and escaped properly):
let g:ale_python_pylint_executable = 'executable with spaces'
AssertLinter 'executable with spaces',
\ ale#path#BufferCdString(bufnr(''))
\ ale#path#CdString(expand('#' . bufnr('') . ':p:h'))
\ . ale#Escape('executable with spaces') . ' ' . b:command_tail
Execute(The pylint command callback should let you set options):
let g:ale_python_pylint_options = '--some-option'
AssertLinter 'pylint',
\ ale#path#BufferCdString(bufnr(''))
\ ale#path#CdString(expand('#' . bufnr('') . ':p:h'))
\ . ale#Escape('pylint') . ' --some-option' . b:command_tail
Execute(The pylint callbacks shouldn't detect virtualenv directories where they don't exist):
@@ -65,15 +69,15 @@ Execute(Setting executable to 'pipenv' appends 'run pylint'):
let g:ale_python_pylint_executable = 'path/to/pipenv'
AssertLinter 'path/to/pipenv',
\ ale#path#BufferCdString(bufnr(''))
\ ale#path#CdString(expand('#' . bufnr('') . ':p:h'))
\ . ale#Escape('path/to/pipenv') . ' run pylint'
\ . ' --output-format text --msg-template="{path}:{line}:{column}: {msg_id} ({symbol}) {msg}" --reports n %s'
Execute(Pipenv is detected when python_pylint_auto_pipenv is set):
let g:ale_python_pylint_auto_pipenv = 1
call ale#test#SetFilename('/testplugin/test/python_fixtures/pipenv/whatever.py')
call ale#test#SetFilename('../python_fixtures/pipenv/whatever.py')
AssertLinter 'pipenv',
\ ale#path#BufferCdString(bufnr(''))
\ ale#path#CdString(expand('#' . bufnr('') . ':p:h'))
\ . ale#Escape('pipenv') . ' run pylint'
\ . ' --output-format text --msg-template="{path}:{line}:{column}: {msg_id} ({symbol}) {msg}" --reports n %s'

View File

@@ -6,8 +6,8 @@ After:
Execute(The default cython command should be correct):
AssertLinter 'cython', ale#Escape('cython')
\ . ' --working ' . ale#Escape(g:dir)
\ . ' --include-dir ' . ale#Escape(g:dir)
\ . ' --working %s:h'
\ . ' --include-dir %s:h'
\ . ' --warning-extra'
\ . ' --output-file ' . g:ale#util#nul_file . ' %t'
@@ -15,8 +15,8 @@ Execute(The cython executable should be configurable):
let b:ale_pyrex_cython_executable = 'cython_foobar'
AssertLinter 'cython_foobar', ale#Escape('cython_foobar')
\ . ' --working ' . ale#Escape(g:dir)
\ . ' --include-dir ' . ale#Escape(g:dir)
\ . ' --working %s:h'
\ . ' --include-dir %s:h'
\ . ' --warning-extra'
\ . ' --output-file ' . g:ale#util#nul_file . ' %t'
@@ -24,7 +24,7 @@ Execute(Additional cython options should be configurable):
let b:ale_pyrex_cython_options = '--foobar'
AssertLinter 'cython', ale#Escape('cython')
\ . ' --working ' . ale#Escape(g:dir)
\ . ' --include-dir ' . ale#Escape(g:dir)
\ . ' --working %s:h'
\ . ' --include-dir %s:h'
\ . ' --foobar'
\ . ' --output-file ' . g:ale#util#nul_file . ' %t'

View File

@@ -10,20 +10,17 @@ After:
Execute(Executable should default to rubocop):
AssertLinter 'rubocop', ale#Escape('rubocop')
\ . ' --format json --force-exclusion --stdin '
\ . ale#Escape(ale#path#Simplify(g:dir . '/dummy.rb'))
\ . ' --format json --force-exclusion --stdin %s'
Execute(Should be able to set a custom executable):
let g:ale_ruby_rubocop_executable = 'bin/rubocop'
AssertLinter 'bin/rubocop' , ale#Escape('bin/rubocop')
\ . ' --format json --force-exclusion --stdin '
\ . ale#Escape(ale#path#Simplify(g:dir . '/dummy.rb'))
\ . ' --format json --force-exclusion --stdin %s'
Execute(Setting bundle appends 'exec rubocop'):
let g:ale_ruby_rubocop_executable = 'path to/bundle'
AssertLinter 'path to/bundle', ale#Escape('path to/bundle')
\ . ' exec rubocop'
\ . ' --format json --force-exclusion --stdin '
\ . ale#Escape(ale#path#Simplify(g:dir . '/dummy.rb'))
\ . ' --format json --force-exclusion --stdin %s'

View File

@@ -10,20 +10,17 @@ After:
Execute(Executable should default to ruumba):
AssertLinter 'ruumba', ale#Escape('ruumba')
\ . ' --format json --force-exclusion --stdin '
\ . ale#Escape(ale#path#Simplify(g:dir . '/dummy.html.erb'))
\ . ' --format json --force-exclusion --stdin %s'
Execute(Should be able to set a custom executable):
let g:ale_eruby_ruumba_executable = 'bin/ruumba'
AssertLinter 'bin/ruumba' , ale#Escape('bin/ruumba')
\ . ' --format json --force-exclusion --stdin '
\ . ale#Escape(ale#path#Simplify(g:dir . '/dummy.html.erb'))
\ . ' --format json --force-exclusion --stdin %s'
Execute(Setting bundle appends 'exec ruumba'):
let g:ale_eruby_ruumba_executable = 'path to/bundle'
AssertLinter 'path to/bundle', ale#Escape('path to/bundle')
\ . ' exec ruumba'
\ . ' --format json --force-exclusion --stdin '
\ . ale#Escape(ale#path#Simplify(g:dir . '/dummy.html.erb'))
\ . ' --format json --force-exclusion --stdin %s'

View File

@@ -2,7 +2,7 @@ Before:
call ale#assert#SetUpLinterTest('sh', 'shellcheck')
call ale#test#SetFilename('test.sh')
let b:prefix = ale#path#CdString(ale#path#Simplify(g:dir))
let b:prefix = ale#path#BufferCdString(bufnr(''))
let b:suffix = ' -f gcc -'
After:

View File

@@ -0,0 +1,12 @@
Before:
" Load the linter and set up a series of commands, reset linter variables,
" clear caches, etc.
"
" Vader's 'Save' command will be called here for linter variables.
call ale#assert#SetUpLinterTest('sql', 'sqllint')
After:
call ale#assert#TearDownLinterTest()
Execute(The default command should be correct):
AssertLinter 'sql-lint', ['sql-lint']

View File

@@ -10,20 +10,17 @@ After:
Execute(Executable should default to standardrb):
AssertLinter 'standardrb', ale#Escape('standardrb')
\ . ' --format json --force-exclusion --stdin '
\ . ale#Escape(ale#path#Simplify(g:dir . '/dummy.rb'))
\ . ' --format json --force-exclusion --stdin %s'
Execute(Should be able to set a custom executable):
let g:ale_ruby_standardrb_executable = 'bin/standardrb'
AssertLinter 'bin/standardrb' , ale#Escape('bin/standardrb')
\ . ' --format json --force-exclusion --stdin '
\ . ale#Escape(ale#path#Simplify(g:dir . '/dummy.rb'))
\ . ' --format json --force-exclusion --stdin %s'
Execute(Setting bundle appends 'exec standardrb'):
let g:ale_ruby_standardrb_executable = 'path to/bundle'
AssertLinter 'path to/bundle', ale#Escape('path to/bundle')
\ . ' exec standardrb'
\ . ' --format json --force-exclusion --stdin '
\ . ale#Escape(ale#path#Simplify(g:dir . '/dummy.rb'))
\ . ' --format json --force-exclusion --stdin %s'

View File

@@ -11,7 +11,7 @@ After:
Execute(The staticcheck callback should return the right defaults):
AssertLinter 'staticcheck',
\ ale#path#CdString(expand('%:p:h'))
\ ale#path#BufferCdString(bufnr(''))
\ . 'staticcheck '
\ . ale#Escape(expand('%' . ':t'))
@@ -19,7 +19,7 @@ Execute(The staticcheck callback should use configured options):
let b:ale_go_staticcheck_options = '-test'
AssertLinter 'staticcheck',
\ ale#path#CdString(expand('%:p:h'))
\ ale#path#BufferCdString(bufnr(''))
\ . 'staticcheck '
\ . '-test ' . ale#Escape(expand('%' . ':t'))
@@ -27,13 +27,14 @@ Execute(The staticcheck `lint_package` option should use the correct command):
let b:ale_go_staticcheck_lint_package = 1
AssertLinter 'staticcheck',
\ ale#path#CdString(expand('%:p:h')) . 'staticcheck .',
\ ale#path#BufferCdString(bufnr(''))
\ . 'staticcheck .',
Execute(The staticcheck callback should use the `GO111MODULE` option if set):
let b:ale_go_go111module = 'off'
AssertLinter 'staticcheck',
\ ale#path#CdString(expand('%:p:h'))
\ ale#path#BufferCdString(bufnr(''))
\ . ale#Env('GO111MODULE', 'off')
\ . 'staticcheck '
\ . ale#Escape(expand('%' . ':t'))
@@ -42,6 +43,6 @@ Execute(The staticcheck callback should use the `GO111MODULE` option if set):
let b:ale_go_staticcheck_lint_package = 1
AssertLinter 'staticcheck',
\ ale#path#CdString(expand('%:p:h'))
\ ale#path#BufferCdString(bufnr(''))
\ . ale#Env('GO111MODULE', 'off')
\ . 'staticcheck .'

View File

@@ -0,0 +1,25 @@
Before:
call ale#assert#SetUpLinterTest('swift', 'swiftformat')
After:
call ale#assert#TearDownLinterTest()
Execute(Should use default command when not in a swift package):
call ale#test#SetFilename('../swift-test-files/non-swift-package-project/src/folder/dummy.swift')
AssertLinter 'swift-format',
\ ale#Escape('swift-format') . ' --mode lint %t'
Execute(Should use swift run when in a swift package):
call ale#test#SetFilename('../swift-test-files/swift-package-project/src/folder/dummy.swift')
AssertLinter 'swift',
\ ale#Escape('swift') . ' run swift-format --mode lint %t'
Execute(Should let users configure a global executable and override local paths):
call ale#test#SetFilename('../swift-test-files/swift-package-project/src/folder/dummy.swift')
let g:ale_swift_swiftformat_executable = '/path/to/custom/swift-format'
AssertLinter '/path/to/custom/swift-format',
\ ale#Escape('/path/to/custom/swift-format') . ' --mode lint %t'

View File

@@ -7,14 +7,14 @@ After:
Execute(The default tslint command should be correct):
AssertLinter 'tslint',
\ ale#path#CdString(expand('%:p:h'))
\ ale#path#BufferCdString(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'
AssertLinter 'tslint',
\ ale#path#CdString(expand('%:p:h'))
\ ale#path#BufferCdString(bufnr(''))
\ . ale#Escape('tslint') . ' --format json'
\ . ' -r ' . ale#Escape('/foo/bar')
\ . ' %t'
@@ -23,5 +23,5 @@ Execute(The executable should be configurable and escaped):
let b:ale_typescript_tslint_executable = 'foo bar'
AssertLinter 'foo bar',
\ ale#path#CdString(expand('%:p:h'))
\ ale#path#BufferCdString(bufnr(''))
\ . ale#Escape('foo bar') . ' --format json %t'

View File

@@ -1,7 +1,7 @@
Before:
call ale#assert#SetUpLinterTest('vim', 'vint')
let b:command_tail = (has('nvim') ? ' --enable-neovim' : '')
\ . ' -f "{file_path}:{line_number}:{column_number}: {severity}: {description} (see {reference})" %t'
\ . ' -f "{file_path}:{line_number}:{column_number}: {severity}: {policy_name} - {description} (see {reference})" %t'
After:
unlet! b:bin_dir

View File

@@ -12,7 +12,7 @@ After:
Execute(The vulture command callback should lint file directory by default):
AssertLinter 'vulture',
\ ale#path#BufferCdString(bufnr(''))
\ ale#path#CdString(expand('#' . bufnr('') . ':p:h'))
\ . ale#Escape('vulture') . ' .'
Execute(The vulture command callback should lint project root, when present):
@@ -31,14 +31,14 @@ Execute(The vulture executable should be configurable, and escaped properly):
let g:ale_python_vulture_executable = 'executable with spaces'
AssertLinter 'executable with spaces',
\ ale#path#BufferCdString(bufnr(''))
\ ale#path#CdString(expand('#' . bufnr('') . ':p:h'))
\ . ale#Escape('executable with spaces') . ' .'
Execute(The vulture command callback should let you set options):
let g:ale_python_vulture_options = '--some-option'
AssertLinter 'vulture',
\ ale#path#BufferCdString(bufnr(''))
\ ale#path#CdString(expand('#' . bufnr('') . ':p:h'))
\ . ale#Escape('vulture') . ' --some-option .'
Execute(The vulture command callback should detect virtualenv directories and switch to the project root):
@@ -64,5 +64,5 @@ Execute(Setting executable to 'pipenv' appends 'run vulture'):
let g:ale_python_vulture_executable = 'path/to/pipenv'
AssertLinter 'path/to/pipenv',
\ ale#path#BufferCdString(bufnr(''))
\ ale#path#CdString(expand('#' . bufnr('') . ':p:h'))
\ . ale#Escape('path/to/pipenv') . ' run vulture' . ' .'

View File

@@ -0,0 +1,562 @@
Before:
Save g:ale_enabled
Save b:ale_enabled
Save g:ale_lint_on_text_changed
Save g:ale_completion_enabled
Save g:ale_completion_autoimport
Save g:ale_completion_max_suggestions
Save g:ale_linters
Save b:ale_linters
let g:ale_enabled = 0
let b:ale_enabled = 0
let g:ale_lint_on_text_changed = 'always'
let g:ale_completion_enabled = 0
let g:ale_completion_autoimport = 0
let g:ale_completion_max_suggestions = 50
let g:ale_linters = {'typescript': ['tsserver'], 'python': ['pyre']}
unlet! b:ale_linters
let g:server_started_value = 1
let g:request_id = 0
let g:LastCallback = v:null
let g:LastHandleCallback = v:null
let g:sent_message_list = []
let g:code_action_list = []
let g:execute_list = []
let g:ale_queue_call_list = []
runtime autoload/ale.vim
runtime autoload/ale/util.vim
runtime autoload/ale/code_action.vim
runtime autoload/ale/lsp.vim
runtime autoload/ale/lsp_linter.vim
function! ale#util#Execute(expr) abort
call add(g:execute_list, a:expr)
endfunction
function! ale#Queue(...) abort
call add(g:ale_queue_call_list, a:000)
endfunction
function! ale#lsp#RegisterCallback(id, Callback) abort
let g:LastHandleCallback = a:Callback
endfunction
function! ale#lsp#NotifyForChanges(id, buffer) abort
endfunction
function! ale#lsp#HasCapability(id, capability) abort
return 1
endfunction
function! ale#lsp#Send(id, message) abort
let g:request_id += 1
call add(g:sent_message_list, a:message)
return g:request_id
endfunction
function! ale#lsp_linter#StartLSP(buffer, linter, Callback) abort
let g:LastCallback = a:Callback
return g:server_started_value
endfunction
function! ale#code_action#HandleCodeAction(code_action, should_save) abort
Assert !a:should_save
call add(g:code_action_list, a:code_action)
endfunction
function GetLastMessage()
return get(g:execute_list, -1, '')
endfunction
function CheckLintStates(conn_id, message)
" Check that we request more linter results after adding completions.
AssertEqual [[0, '']], g:ale_queue_call_list
let g:ale_enabled = 0
let g:ale_queue_call_list = []
call g:LastHandleCallback(a:conn_id, a:message)
AssertEqual [], g:ale_queue_call_list
let g:ale_enabled = 1
let g:ale_lint_on_text_changed = 1
let g:ale_queue_call_list = []
call g:LastHandleCallback(a:conn_id, a:message)
AssertEqual [[0, '']], g:ale_queue_call_list
let g:ale_lint_on_text_changed = 'normal'
let g:ale_queue_call_list = []
call g:LastHandleCallback(a:conn_id, a:message)
AssertEqual [[0, '']], g:ale_queue_call_list
let g:ale_lint_on_text_changed = 'insert'
let g:ale_queue_call_list = []
call g:LastHandleCallback(a:conn_id, a:message)
AssertEqual [[0, '']], g:ale_queue_call_list
let g:ale_queue_call_list = []
let g:ale_lint_on_text_changed = 'never'
call g:LastHandleCallback(a:conn_id, a:message)
AssertEqual [], g:ale_queue_call_list
let g:ale_lint_on_text_changed = '0'
call g:LastHandleCallback(a:conn_id, a:message)
AssertEqual [], g:ale_queue_call_list
let g:ale_lint_on_text_changed = 0
call g:LastHandleCallback(a:conn_id, a:message)
AssertEqual [], g:ale_queue_call_list
let g:ale_lint_on_text_changed = 'xxx'
call g:LastHandleCallback(a:conn_id, a:message)
AssertEqual [], g:ale_queue_call_list
endfunction
After:
call ale#linter#Reset()
Restore
delfunction GetLastMessage
delfunction CheckLintStates
unlet! g:LastCallback
unlet! g:LastHandleCallback
unlet! g:request_id
unlet! g:server_started_value
unlet! g:sent_message_list
unlet! g:code_action_list
unlet! g:ale_queue_call_list
unlet! g:execute_list
unlet! g:received_message
unlet! b:ale_old_omnifunc
unlet! b:ale_old_completeopt
unlet! b:ale_completion_info
unlet! b:ale_completion_result
unlet! b:ale_complete_done_time
runtime autoload/ale.vim
runtime autoload/ale/util.vim
runtime autoload/ale/code_action.vim
runtime autoload/ale/lsp.vim
runtime autoload/ale/lsp_linter.vim
Given typescript(Some example TypeScript code):
let xyz = 123
let foo = missingword
let abc = 456
Execute(ALEImport should complain when there's no word at the cursor):
call setpos('.', [bufnr(''), 3, 1, 0])
ALEImport
AssertEqual 'echom ''Nothing to complete at cursor!''', GetLastMessage()
Execute(ALEImport should tell the user if no LSP is available):
let g:server_started_value = 0
call setpos('.', [bufnr(''), 2, 16, 0])
ALEImport
AssertEqual
\ 'echom ''No completion providers are available.''',
\ GetLastMessage()
Execute(ALEImport should request imports correctly for tsserver):
call setpos('.', [bufnr(''), 2, 16, 0])
ALEImport
AssertEqual
\ {
\ 'conn_id': 0,
\ 'request_id': 0,
\ 'source': 'ale-import',
\ 'column': 11,
\ 'line': 2,
\ 'line_length': 21,
\ 'prefix': 'missingword',
\ 'additional_edits_only': 1,
\ },
\ b:ale_completion_info
Assert g:LastCallback isnot v:null
call g:LastCallback(ale#linter#Get(&filetype)[0], {
\ 'connection_id': 347,
\ 'buffer': bufnr(''),
\})
AssertEqual
\ {
\ 'conn_id': 347,
\ 'request_id': 1,
\ 'source': 'ale-import',
\ 'column': 11,
\ 'line': 2,
\ 'line_length': 21,
\ 'prefix': 'missingword',
\ 'additional_edits_only': 1,
\ },
\ b:ale_completion_info
Assert g:LastHandleCallback isnot v:null
call g:LastHandleCallback(347, {
\ 'request_seq': 1,
\ 'command': 'completions',
\ 'body': [
\ {'name': 'missingwordIgnoreMe'},
\ {'name': 'missingword'},
\ ],
\})
AssertEqual
\ [
\ [0, 'ts@completions', {
\ 'file': expand('%:p'),
\ 'includeExternalModuleExports': 1,
\ 'offset': 11,
\ 'line': 2,
\ 'prefix': 'missingword',
\ }],
\ [0, 'ts@completionEntryDetails', {
\ 'file': expand('%:p'),
\ 'entryNames': [{'name': 'missingword'}],
\ 'offset': 11,
\ 'line': 2,
\ }]
\ ],
\ g:sent_message_list
AssertEqual 2, b:ale_completion_info.request_id
let g:ale_enabled = 1
let g:received_message = {
\ 'request_seq': 2,
\ 'command': 'completionEntryDetails',
\ 'body': [
\ {
\ 'name': 'missingword',
\ 'kind': 'className',
\ 'displayParts': [],
\ 'codeActions': [{
\ 'description': 'import { missingword } from "./Something";',
\ 'changes': [],
\ }],
\ },
\ ],
\}
call g:LastHandleCallback(347, g:received_message)
AssertEqual
\ [
\ {
\ 'description': 'import { missingword } from "./Something";',
\ 'changes': [],
\ },
\ ],
\ g:code_action_list
call CheckLintStates(347, g:received_message)
Execute(ALEImport should tell the user when no completions were found from tsserver):
call setpos('.', [bufnr(''), 2, 16, 0])
ALEImport
AssertEqual
\ {
\ 'conn_id': 0,
\ 'request_id': 0,
\ 'source': 'ale-import',
\ 'column': 11,
\ 'line': 2,
\ 'line_length': 21,
\ 'prefix': 'missingword',
\ 'additional_edits_only': 1,
\ },
\ b:ale_completion_info
Assert g:LastCallback isnot v:null
call g:LastCallback(ale#linter#Get(&filetype)[0], {
\ 'connection_id': 347,
\ 'buffer': bufnr(''),
\})
AssertEqual
\ {
\ 'conn_id': 347,
\ 'request_id': 1,
\ 'source': 'ale-import',
\ 'column': 11,
\ 'line': 2,
\ 'line_length': 21,
\ 'prefix': 'missingword',
\ 'additional_edits_only': 1,
\ },
\ b:ale_completion_info
Assert g:LastHandleCallback isnot v:null
call g:LastHandleCallback(347, {
\ 'request_seq': 1,
\ 'command': 'completions',
\ 'body': [
\ {'name': 'missingwordIgnoreMe'},
\ ],
\})
AssertEqual 'echom ''No possible imports found.''', GetLastMessage()
Given python(Some example Python code):
xyz = 123
foo = missingword
abc = 456
Execute(ALEImport should request imports correctly for language servers):
call setpos('.', [bufnr(''), 2, 12, 0])
ALEImport
AssertEqual
\ {
\ 'conn_id': 0,
\ 'request_id': 0,
\ 'source': 'ale-import',
\ 'column': 7,
\ 'line': 2,
\ 'line_length': 17,
\ 'prefix': 'missingword',
\ 'additional_edits_only': 1,
\ },
\ b:ale_completion_info
Assert g:LastCallback isnot v:null
call g:LastCallback(ale#linter#Get(&filetype)[0], {
\ 'connection_id': 347,
\ 'buffer': bufnr(''),
\})
AssertEqual
\ {
\ 'conn_id': 347,
\ 'request_id': 1,
\ 'source': 'ale-import',
\ 'column': 7,
\ 'line': 2,
\ 'line_length': 17,
\ 'prefix': 'missingword',
\ 'additional_edits_only': 1,
\ 'completion_filter': 'ale#completion#python#CompletionItemFilter',
\ },
\ b:ale_completion_info
Assert g:LastHandleCallback isnot v:null
AssertEqual
\ [
\ [0, 'textDocument/completion', {
\ 'textDocument': {'uri': ale#path#ToURI(expand('%:p'))},
\ 'position': {'character': 6, 'line': 1}
\ }],
\ ],
\ g:sent_message_list
AssertEqual 1, b:ale_completion_info.request_id
let g:ale_enabled = 1
let g:received_message = {
\ 'id': 1,
\ 'jsonrpc': '2.0',
\ 'result': {
\ 'isIncomplete': v:false,
\ 'items': [
\ {
\ 'detail': 'Some other word we should ignore',
\ 'filterText': 'missingwordIgnoreMe',
\ 'insertText': 'missingwordIgnoreMe',
\ 'insertTextFormat': 1,
\ 'kind': 6,
\ 'label': ' missingwordIgnoreMe',
\ 'sortText': '3ee19999missingword',
\ 'additionalTextEdits': [
\ {
\ 'range': {
\ 'start': {'line': 1, 'character': 1},
\ 'end': {'line': 2, 'character': 1},
\ },
\ 'newText': 'from something import missingwordIgnoreMe',
\ },
\ ],
\ },
\ {
\ 'detail': 'Some word without text edits',
\ 'filterText': 'missingword',
\ 'insertText': 'missingword',
\ 'insertTextFormat': 1,
\ 'kind': 6,
\ 'label': ' missingword',
\ 'sortText': '3ee19999missingword',
\ },
\ {
\ 'detail': 'The word we should use',
\ 'filterText': 'missingword',
\ 'insertText': 'missingword',
\ 'insertTextFormat': 1,
\ 'kind': 6,
\ 'label': ' missingword',
\ 'sortText': '3ee19999missingword',
\ 'additionalTextEdits': [
\ {
\ 'range': {
\ 'start': {'line': 1, 'character': 1},
\ 'end': {'line': 2, 'character': 1},
\ },
\ 'newText': 'from something import missingword',
\ },
\ ],
\ },
\ {
\ 'detail': 'The other word we should not use',
\ 'filterText': 'missingword',
\ 'insertText': 'missingword',
\ 'insertTextFormat': 1,
\ 'kind': 6,
\ 'label': ' missingword',
\ 'sortText': '3ee19999missingword',
\ 'additionalTextEdits': [
\ {
\ 'range': {
\ 'start': {'line': 1, 'character': 1},
\ 'end': {'line': 2, 'character': 1},
\ },
\ 'newText': 'from something_else import missingword',
\ },
\ ],
\ },
\ ],
\ },
\}
call g:LastHandleCallback(347, g:received_message)
AssertEqual
\ [
\ {
\ 'description': 'completion',
\ 'changes': [
\ {
\ 'fileName': expand('%:p'),
\ 'textChanges': [
\ {
\ 'start': {'line': 2, 'offset': 2},
\ 'end': {'line': 3, 'offset': 2},
\ 'newText': 'from something import missingword',
\ },
\ ],
\ },
\ ],
\ },
\ ],
\ g:code_action_list
call CheckLintStates(347, g:received_message)
Execute(ALEImport should tell the user when no completions were found from a language server):
call setpos('.', [bufnr(''), 2, 12, 0])
ALEImport
AssertEqual
\ {
\ 'conn_id': 0,
\ 'request_id': 0,
\ 'source': 'ale-import',
\ 'column': 7,
\ 'line': 2,
\ 'line_length': 17,
\ 'prefix': 'missingword',
\ 'additional_edits_only': 1,
\ },
\ b:ale_completion_info
Assert g:LastCallback isnot v:null
call g:LastCallback(ale#linter#Get(&filetype)[0], {
\ 'connection_id': 347,
\ 'buffer': bufnr(''),
\})
AssertEqual
\ {
\ 'conn_id': 347,
\ 'request_id': 1,
\ 'source': 'ale-import',
\ 'column': 7,
\ 'line': 2,
\ 'line_length': 17,
\ 'prefix': 'missingword',
\ 'additional_edits_only': 1,
\ 'completion_filter': 'ale#completion#python#CompletionItemFilter',
\ },
\ b:ale_completion_info
Assert g:LastHandleCallback isnot v:null
AssertEqual
\ [
\ [0, 'textDocument/completion', {
\ 'textDocument': {'uri': ale#path#ToURI(expand('%:p'))},
\ 'position': {'character': 6, 'line': 1}
\ }],
\ ],
\ g:sent_message_list
AssertEqual 1, b:ale_completion_info.request_id
let g:received_message = {
\ 'id': 1,
\ 'jsonrpc': '2.0',
\ 'result': {
\ 'isIncomplete': v:false,
\ 'items': [
\ {
\ 'detail': 'Some other word we should ignore',
\ 'filterText': 'missingwordIgnoreMe',
\ 'insertText': 'missingwordIgnoreMe',
\ 'insertTextFormat': 1,
\ 'kind': 6,
\ 'label': ' missingwordIgnoreMe',
\ 'sortText': '3ee19999missingword',
\ 'additionalTextEdits': [
\ {
\ 'range': {
\ 'start': {'line': 1, 'character': 1},
\ 'end': {'line': 2, 'character': 1},
\ },
\ 'newText': 'from something import missingwordIgnoreMe',
\ },
\ ],
\ },
\ {
\ 'detail': 'Some word without text edits',
\ 'filterText': 'missingword',
\ 'insertText': 'missingword',
\ 'insertTextFormat': 1,
\ 'kind': 6,
\ 'label': ' missingword',
\ 'sortText': '3ee19999missingword',
\ },
\ ],
\ },
\}
call g:LastHandleCallback(347, g:received_message)
AssertEqual 'echom ''No possible imports found.''', GetLastMessage()

View File

@@ -35,7 +35,7 @@ Before:
let g:ale_completion_delay = 0
" Run this check a few times, as it can fail randomly.
for g:i in range(has('nvim-0.3') || has('win32') ? 5 : 1)
for l:i in range(has('nvim-0.3') || has('win32') ? 5 : 1)
call ale#completion#Queue()
sleep 1m

View File

@@ -12,13 +12,24 @@ After:
Execute(Prefix filtering should work for Lists of strings):
AssertEqual
\ ['FooBar', 'foo'],
\ ale#completion#Filter(bufnr(''), '', ['FooBar', 'FongBar', 'baz', 'foo'], 'foo')
\ ale#completion#Filter(bufnr(''), '', ['FooBar', 'FongBar', 'baz', 'foo'], 'foo', 0)
AssertEqual
\ ['FooBar', 'FongBar', 'baz', 'foo'],
\ ale#completion#Filter(bufnr(''), '', ['FooBar', 'FongBar', 'baz', 'foo'], '.')
\ ale#completion#Filter(bufnr(''), '', ['FooBar', 'FongBar', 'baz', 'foo'], '.', 0)
AssertEqual
\ ['FooBar', 'FongBar', 'baz', 'foo'],
\ ale#completion#Filter(bufnr(''), '', ['FooBar', 'FongBar', 'baz', 'foo'], '')
\ ale#completion#Filter(bufnr(''), '', ['FooBar', 'FongBar', 'baz', 'foo'], '', 0)
Execute(Exact filtering should work):
AssertEqual
\ ['foo'],
\ ale#completion#Filter(bufnr(''), '', ['FooBar', 'FongBar', 'baz', 'foo'], 'foo', 1)
AssertEqual
\ ['FooBar', 'FongBar', 'baz', 'foo'],
\ ale#completion#Filter(bufnr(''), '', ['FooBar', 'FongBar', 'baz', 'foo'], '.', 1)
AssertEqual
\ ['Foo'],
\ ale#completion#Filter(bufnr(''), '', ['FooBar', 'FongBar', 'Foo', 'foo'], 'Foo', 1)
Execute(Prefix filtering should work for completion items):
AssertEqual
@@ -32,7 +43,8 @@ Execute(Prefix filtering should work for completion items):
\ {'word': 'baz'},
\ {'word': 'foo'},
\ ],
\ 'foo'
\ 'foo',
\ 0,
\ )
AssertEqual
@@ -51,7 +63,8 @@ Execute(Prefix filtering should work for completion items):
\ {'word': 'baz'},
\ {'word': 'foo'},
\ ],
\ '.'
\ '.',
\ 0,
\ )
Execute(Excluding words from completion results should work):
@@ -66,7 +79,8 @@ Execute(Excluding words from completion results should work):
\ {'word': 'Italian'},
\ {'word': 'it'},
\ ],
\ 'it'
\ 'it',
\ 0,
\ )
AssertEqual
@@ -78,7 +92,8 @@ Execute(Excluding words from completion results should work):
\ {'word': 'describe'},
\ {'word': 'Deutsch'},
\ ],
\ 'de'
\ 'de',
\ 0,
\ )
AssertEqual
@@ -90,7 +105,8 @@ Execute(Excluding words from completion results should work):
\ {'word': 'describe'},
\ {'word': 'Deutsch'},
\ ],
\ '.'
\ '.',
\ 0,
\ )
Execute(Excluding words from completion results should work with lists of Strings):
@@ -98,29 +114,29 @@ Execute(Excluding words from completion results should work with lists of String
AssertEqual
\ ['Italian'],
\ ale#completion#Filter(bufnr(''), '', ['Italian', 'it'], 'it')
\ ale#completion#Filter(bufnr(''), '', ['Italian', 'it'], 'it', 0)
AssertEqual
\ ['Deutsch'],
\ ale#completion#Filter(bufnr(''), '', ['describe', 'Deutsch'], 'de')
\ ale#completion#Filter(bufnr(''), '', ['describe', 'Deutsch'], 'de', 0)
AssertEqual
\ ['Deutsch'],
\ ale#completion#Filter(bufnr(''), '', ['describe', 'Deutsch'], '.')
\ ale#completion#Filter(bufnr(''), '', ['describe', 'Deutsch'], '.', 0)
AssertEqual
\ ['Deutsch'],
\ ale#completion#Filter(bufnr(''), '', ['Deutsch'], '')
\ ale#completion#Filter(bufnr(''), '', ['Deutsch'], '', 0)
Execute(Filtering shouldn't modify the original list):
let b:ale_completion_excluded_words = ['it', 'describe']
let b:suggestions = [{'word': 'describe'}]
AssertEqual [], ale#completion#Filter(bufnr(''), '', b:suggestions, '.')
AssertEqual [], ale#completion#Filter(bufnr(''), '', b:suggestions, '.', 0)
AssertEqual b:suggestions, [{'word': 'describe'}]
AssertEqual [], ale#completion#Filter(bufnr(''), '', b:suggestions, 'de')
AssertEqual [], ale#completion#Filter(bufnr(''), '', b:suggestions, 'de', 0)
AssertEqual b:suggestions, [{'word': 'describe'}]
Execute(Filtering should respect filetype triggers):
let b:suggestions = [{'word': 'describe'}]
AssertEqual b:suggestions, ale#completion#Filter(bufnr(''), '', b:suggestions, '.')
AssertEqual b:suggestions, ale#completion#Filter(bufnr(''), 'rust', b:suggestions, '.')
AssertEqual b:suggestions, ale#completion#Filter(bufnr(''), 'rust', b:suggestions, '::')
AssertEqual b:suggestions, ale#completion#Filter(bufnr(''), '', b:suggestions, '.', 0)
AssertEqual b:suggestions, ale#completion#Filter(bufnr(''), 'rust', b:suggestions, '.', 0)
AssertEqual b:suggestions, ale#completion#Filter(bufnr(''), 'rust', b:suggestions, '::', 0)

View File

@@ -609,6 +609,7 @@ Execute(Should handle completion messages with additionalTextEdits when ale_comp
Execute(Should not handle completion messages with additionalTextEdits when ale_completion_autoimport is turned off):
let g:ale_completion_autoimport = 0
let b:ale_completion_info = {'line': 30}
AssertEqual
\ [],
@@ -645,3 +646,36 @@ Execute(Should not handle completion messages with additionalTextEdits when ale_
\ ],
\ },
\ })
Execute(Should still handle completion messages with empty additionalTextEdits with ale_completion_autoimport turned off):
let g:ale_completion_autoimport = 0
AssertEqual
\ [
\ {
\ 'word': 'next_callback',
\ 'menu': 'PlayTimeCallback',
\ 'info': '',
\ 'kind': 'v',
\ 'icase': 1,
\ }
\ ],
\ ale#completion#ParseLSPCompletions({
\ 'id': 226,
\ 'jsonrpc': '2.0',
\ 'result': {
\ 'isIncomplete': v:false,
\ 'items': [
\ {
\ 'detail': 'PlayTimeCallback',
\ 'filterText': 'next_callback',
\ 'insertText': 'next_callback',
\ 'insertTextFormat': 1,
\ 'kind': 6,
\ 'label': ' next_callback',
\ 'sortText': '3ee19999next_callback',
\ 'additionalTextEdits': [],
\ },
\ ],
\ },
\ })

View File

@@ -1,4 +1,11 @@
Before:
Save g:ale_completion_tsserver_remove_warnings
let g:ale_completion_tsserver_remove_warnings = 0
After:
Restore
unlet! b:ale_tsserver_completion_names
Execute(TypeScript completions responses should be parsed correctly):
@@ -242,3 +249,54 @@ Execute(Entries without details should be included in the responses):
\ },
\ ],
\})
Execute(Default imports should be handled correctly):
AssertEqual
\ [
\ {
\ 'word': 'abcd',
\ 'menu': 'Import default ''abcd'' from module "./foo" (alias) const abcd: 3',
\ 'info': '',
\ 'kind': 't',
\ 'icase': 1,
\ 'user_data': json_encode({
\ 'codeActions': [{
\ 'description': 'Import default ''abcd'' from module "./foo"',
\ 'changes': [],
\ }],
\ }),
\ 'dup': g:ale_completion_autoimport,
\ },
\ ],
\ ale#completion#ParseTSServerCompletionEntryDetails({
\ 'body': [
\ {
\ 'name': 'default',
\ 'kind': 'alias',
\ 'displayParts': [
\ {'kind': 'punctuation', 'text': '('},
\ {'kind': 'text', 'text': 'alias'},
\ {'kind': 'punctuation', 'text': ')'},
\ {'kind': 'space', 'text': ' '},
\ {'kind': 'keyword', 'text': 'const'},
\ {'kind': 'space', 'text': ' '},
\ {'kind': 'localName', 'text': 'abcd'},
\ {'kind': 'punctuation', 'text': ':'},
\ {'kind': 'space', 'text': ' '},
\ {'kind': 'stringLiteral', 'text': '3'},
\ {'kind': 'lineBreak', 'text': '^@'},
\ {'kind': 'keyword', 'text': 'export'},
\ {'kind': 'space', 'text': ' '},
\ {'kind': 'keyword', 'text': 'default'},
\ {'kind': 'space', 'text': ' '},
\ {'kind': 'aliasName', 'text': 'abcd'}
\ ],
\ 'codeActions': [
\ {
\ 'description': 'Import default ''abcd'' from module "./foo"',
\ 'changes': [],
\ },
\ ],
\ },
\ ],
\ })

View File

@@ -5,18 +5,22 @@ Before:
Save g:ale_fix_on_save
Save g:ale_lint_on_save
Save g:ale_echo_cursor
Save g:ale_command_wrapper
Save g:ale_filename_mappings
silent! cd /testplugin/test/fix
unlet! b:ale_lint_on_save
let g:ale_enabled = 0
let g:ale_echo_cursor = 0
let g:ale_command_wrapper = ''
let g:ale_run_synchronously = 1
let g:ale_set_lists_synchronously = 1
let g:ale_fix_buffer_data = {}
let g:ale_fixers = {
\ 'testft': [],
\}
let g:ale_filename_mappings = {}
let g:pre_success = 0
let g:post_success = 0
@@ -70,6 +74,10 @@ Before:
return {'command': 'cat %t <(echo d)'}
endfunction
function EchoFilename(buffer, lines) abort
return {'command': 'echo %s'}
endfunction
function RemoveLastLine(buffer, lines) abort
return ['a', 'b']
endfunction
@@ -82,56 +90,6 @@ Before:
return [{'lnum': 1, 'col': 1, 'text': 'xxx'}]
endfunction
function! FirstChainCallback(buffer)
return {'command': 'echo echoline', 'chain_with': 'SecondChainCallback'}
endfunction
function! FirstChainCallbackSkipped(buffer)
let l:ChainWith = 'SecondChainCallback'
" Test with lambdas where support is available.
if has('lambda')
let l:ChainWith = {buffer, output -> SecondChainCallback(buffer, output)}
endif
return {'command': '', 'chain_with': l:ChainWith}
endfunction
function! FirstChainCallbackSecondSkipped(buffer)
return {'command': 'echo skipit', 'chain_with': 'SecondChainCallback'}
endfunction
function! SecondChainCallback(buffer, output)
let l:previous_line = empty(a:output)
\ ? 'emptydefault'
\ : join(split(a:output[0]))
if l:previous_line is# 'skipit'
return {'command': '', 'chain_with': 'ThirdChainCallback'}
endif
return {
\ 'command': 'echo ' . l:previous_line,
\ 'chain_with': 'ThirdChainCallback',
\}
endfunction
function! ThirdChainCallback(buffer, output, input)
let l:previous_line = empty(a:output)
\ ? 'thirddefault'
\ : join(split(a:output[0]))
return a:input + [l:previous_line]
endfunction
function! ChainWhereLastIsSkipped(buffer)
return {'command': 'echo echoline', 'chain_with': 'ChainEndSkipped'}
endfunction
function! ChainEndSkipped(buffer, output)
return {'command': ''}
endfunction
" echo will output a single blank line, and we should ingore it.
function! IgnoredEmptyOutput(buffer, output)
return {'command': has('win32') ? 'echo(' : 'echo'}
@@ -203,16 +161,10 @@ After:
delfunction CatLineDeferred
delfunction ReplaceWithTempFile
delfunction CatWithTempFile
delfunction EchoFilename
delfunction RemoveLastLine
delfunction RemoveLastLineOneArg
delfunction TestCallback
delfunction FirstChainCallback
delfunction FirstChainCallbackSkipped
delfunction FirstChainCallbackSecondSkipped
delfunction SecondChainCallback
delfunction ThirdChainCallback
delfunction ChainWhereLastIsSkipped
delfunction ChainEndSkipped
delfunction SetUpLinters
delfunction GetLastMessage
delfunction IgnoredEmptyOutput
@@ -264,6 +216,25 @@ Expect(The first function should be used):
^b
^c
Execute(Should apply filename mpapings):
" The command echos %s, and we'll map the current path so we can check
" that ALEFix applies filename mappings, end-to-end.
let g:ale_filename_mappings = {
\ 'echo_filename': [
\ [expand('%:p:h') . '/', '/some/fake/path/'],
\ ],
\}
call ale#fix#registry#Add('echo_filename', 'EchoFilename', [], 'echo filename')
let g:ale_fixers.testft = ['echo_filename']
ALEFix
call ale#test#FlushJobs()
" Remote trailing whitespace from the line.
call setline(1, substitute(getline(1), '[ \r]\+$', '', ''))
Expect(The mapped filename should be printed):
/some/fake/path/test.txt
Execute(ALEFix should apply simple functions in a chain):
let g:ale_fixers.testft = ['AddCarets', 'Capitalize']
ALEFix
@@ -756,6 +727,19 @@ Expect(There should be only two lines):
a
b
Execute(ALEFix should modify a buffer that is not modifiable, if it becomes modifiable later):
let g:ale_fixers.testft = ['RemoveLastLineOneArg']
set nomodifiable
ALEFix
call ale#test#FlushJobs()
set modifiable
call ale#fix#ApplyQueuedFixes(bufnr(''))
Expect(There should be only two lines):
a
b
Execute(b:ale_fix_on_save = 1 should override g:ale_fix_on_save = 0):
let g:ale_fix_on_save = 0
let b:ale_fix_on_save = 1
@@ -814,57 +798,6 @@ Execute(ALE should tolerate valid fixers with minuses in the name):
ALEFix
call ale#test#FlushJobs()
Execute(Test fixing with chained callbacks):
let g:ale_fixers.testft = ['FirstChainCallback']
ALEFix
call ale#test#FlushJobs()
" The buffer shouldn't be piped in for earlier commands in the chain.
AssertEqual
\ [
\ string(ale#job#PrepareCommand(bufnr(''), 'echo echoline')),
\ string(ale#job#PrepareCommand(bufnr(''), 'echo echoline')),
\ ],
\ map(ale#history#Get(bufnr(''))[-2:-1], 'string(v:val.command)')
Expect(The echoed line should be added):
a
b
c
echoline
Execute(Test fixing with chained callback where the first command is skipped):
let g:ale_fixers.testft = ['FirstChainCallbackSkipped']
ALEFix
call ale#test#FlushJobs()
Expect(The default line should be added):
a
b
c
emptydefault
Execute(Test fixing with chained callback where the second command is skipped):
let g:ale_fixers.testft = ['FirstChainCallbackSecondSkipped']
ALEFix
call ale#test#FlushJobs()
Expect(The default line should be added):
a
b
c
thirddefault
Execute(Test fixing with chained callback where the final callback is skipped):
let g:ale_fixers.testft = ['ChainWhereLastIsSkipped']
ALEFix
call ale#test#FlushJobs()
Expect(The lines should be the same):
a
b
c
Execute(Empty output should be ignored):
let g:ale_fixers.testft = ['IgnoredEmptyOutput']
ALEFix

View File

@@ -1,8 +1,19 @@
Before:
Save g:ale_c_build_dir
Save g:ale_c_clangtidy_executable
Save g:ale_c_clangtidy_checks
Save g:ale_c_clangtidy_extra_options
Save g:ale_cpp_clangtidy_executable
Save g:ale_cpp_clangtidy_checks
Save g:ale_cpp_clangtidy_extra_options
" Use an invalid global executable, so we don't match it.
let g:ale_c_clangtidy_executable = 'xxxinvalid'
let g:ale_c_clangtidy_checks = []
let g:ale_c_clangtidy_extra_options = ''
let g:ale_cpp_clangtidy_executable = 'xxxinvalidpp'
let g:ale_cpp_clangtidy_checks = []
let g:ale_cpp_clangtidy_extra_options = ''
let g:ale_c_build_dir = ''
call ale#test#SetDirectory('/testplugin/test/fixers')
@@ -36,16 +47,3 @@ Execute(The clangtidy callback should include any additional options):
\ . ' -fix -fix-errors --some-option %t',
\ },
\ ale#fixers#clangtidy#Fix(bufnr(''))
Execute(The clangtidy callback should support cpp files):
call ale#test#SetFilename('c_paths/dummy.cpp')
let g:ale_cpp_clangtidy_executable = 'invalidpp'
set filetype=cpp " The test fails without this
AssertEqual
\ {
\ 'read_temporary_file': 1,
\ 'command': ale#Escape(g:ale_cpp_clangtidy_executable)
\ . ' -fix -fix-errors %t',
\ },
\ ale#fixers#clangtidy#Fix(bufnr(''))

View File

@@ -0,0 +1,11 @@
Before:
call ale#assert#SetUpFixerTest('dhall', 'dhall')
After:
call ale#assert#TearDownFixerTest()
Execute(The default command should be correct):
AssertFixer
\ { 'read_temporary_file': 1,
\ 'command': ale#Escape('dhall') . ' format --inplace %t'
\ }

View File

@@ -1,7 +1,11 @@
Before:
call ale#assert#SetUpFixerTest('javascript', 'eslint')
Save g:ale_command_wrapper
runtime autoload/ale/handlers/eslint.vim
let g:ale_command_wrapper = ''
After:
call ale#assert#TearDownFixerTest()

View File

@@ -4,6 +4,7 @@ Before:
" Use an invalid global executable, so we don't match it.
let g:ale_python_isort_executable = 'xxxinvalid'
let g:ale_python_isort_options = ''
call ale#test#SetDirectory('/testplugin/test/fixers')
silent cd ..
@@ -27,7 +28,7 @@ Execute(The isort callback should return the correct default values):
silent execute 'file ' . fnameescape(g:dir . '/python_paths/with_virtualenv/subdir/foo/bar.py')
AssertEqual
\ {
\ 'command': ale#path#CdString(ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/subdir/foo'))
\ 'command': ale#path#BufferCdString(bufnr(''))
\ . ale#Escape(ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/env/' . b:bin_dir . '/isort')) . ' -',
\ },
\ ale#fixers#isort#Fix(bufnr(''))
@@ -42,7 +43,7 @@ Execute(The isort callback should respect custom options):
silent execute 'file ' . fnameescape(g:dir . '/python_paths/with_virtualenv/subdir/foo/bar.py')
AssertEqual
\ {
\ 'command': ale#path#CdString(ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/subdir/foo'))
\ 'command': ale#path#BufferCdString(bufnr(''))
\ . ale#Escape(ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/env/' . b:bin_dir . '/isort'))
\ . ' --multi-line=3 --trailing-comma -',
\ },

View File

@@ -18,10 +18,8 @@ Execute(The latexindent callback should return the correct default values):
AssertEqual
\ {
\ 'read_temporary_file': 1,
\ 'command': ale#Escape('xxxinvalid')
\ . ' -l -w'
\ . ' %t',
\ . ' -l'
\ },
\ ale#fixers#latexindent#Fix(bufnr(''))
@@ -31,10 +29,8 @@ Execute(The latexindent callback should include custom gofmt options):
AssertEqual
\ {
\ 'read_temporary_file': 1,
\ 'command': ale#Escape('xxxinvalid')
\ . ' -l -w'
\ . ' -l'
\ . ' ' . g:ale_tex_latexindent_options
\ . ' %t',
\ },
\ ale#fixers#latexindent#Fix(bufnr(''))

View File

@@ -19,8 +19,7 @@ Execute(The ocamlformat callback should return the correct default values):
AssertEqual
\ {
\ 'command': ale#Escape('xxxinvalid')
\ . ' --name=' . ale#Escape(bufname(bufnr('')))
\ . ' -',
\ . ' --name=%s -',
\ },
\ ale#fixers#ocamlformat#Fix(bufnr(''))
@@ -32,7 +31,6 @@ Execute(The ocamlformat callback should include custom ocamlformat options):
\ {
\ 'command': ale#Escape('xxxinvalid')
\ . ' ' . g:ale_ocaml_ocamlformat_options
\ . ' --name=' . ale#Escape(bufname(bufnr('')))
\ . ' -',
\ . ' --name=%s -',
\ },
\ ale#fixers#ocamlformat#Fix(bufnr(''))

View File

@@ -1,5 +1,8 @@
Before:
call ale#assert#SetUpFixerTest('javascript', 'prettier_eslint')
Save g:ale_command_wrapper
let g:ale_command_wrapper = ''
After:
call ale#assert#TearDownFixerTest()
@@ -70,7 +73,7 @@ Execute(The new --stdin-filepath option should be used when the version is new e
GivenCommandOutput ['4.4.0']
AssertFixer
\ {
\ 'command': ale#path#CdString(expand('%:p:h'))
\ 'command': ale#path#BufferCdString(bufnr(''))
\ . ale#Escape('prettier-eslint')
\ . ' --eslint-config-path ' . ale#Escape(ale#path#Simplify(g:dir . '/eslint-test-files/react-app/.eslintrc.js'))
\ . ' --stdin-filepath %s --stdin',
@@ -80,7 +83,7 @@ Execute(The version number should be cached):
GivenCommandOutput ['4.4.0']
AssertFixer
\ {
\ 'command': ale#path#CdString(expand('%:p:h'))
\ 'command': ale#path#BufferCdString(bufnr(''))
\ . ale#Escape('prettier-eslint')
\ . ' --stdin-filepath %s --stdin',
\ }
@@ -88,7 +91,7 @@ Execute(The version number should be cached):
GivenCommandOutput []
AssertFixer
\ {
\ 'command': ale#path#CdString(expand('%:p:h'))
\ 'command': ale#path#BufferCdString(bufnr(''))
\ . ale#Escape('prettier-eslint')
\ . ' --stdin-filepath %s --stdin',
\ }

View File

@@ -1,5 +1,8 @@
Before:
call ale#assert#SetUpFixerTest('javascript', 'prettier')
Save g:ale_command_wrapper
let g:ale_command_wrapper = ''
silent cd ..
silent cd command_callback
@@ -294,6 +297,17 @@ Execute(Should set --parser for experimental language, Handlebars):
\ . ' --stdin-filepath %s --stdin',
\ }
Execute(Changes to directory where .prettierignore is found):
call ale#test#SetFilename('../prettier-test-files/with_prettierignore/src/testfile.js')
GivenCommandOutput ['1.6.0']
AssertFixer
\ {
\ 'command': ale#path#CdString(expand('%:p:h:h'))
\ . ale#Escape(g:ale_javascript_prettier_executable)
\ . ' --stdin-filepath %s --stdin',
\ }
Execute(The prettier_d post-processor should permit regular JavaScript content):
AssertEqual
\ [

View File

@@ -0,0 +1,19 @@
Before:
call ale#assert#SetUpFixerTest('javascript', 'prettier_standard')
silent cd ..
silent cd command_callback
let g:dir = getcwd()
After:
call ale#assert#TearDownFixerTest()
Execute(The prettier callback should return the correct default values):
call ale#test#SetFilename('../prettier-test-files/testfile.js')
AssertFixer
\ {
\ 'command': ale#Escape(g:ale_javascript_prettier_standard_executable)
\ . ' --stdin'
\ . ' --stdin-filepath=%s ',
\ }

View File

@@ -0,0 +1,24 @@
Before:
Save g:ale_markdown_remark_lint_executable
Save g:ale_markdown_remark_lint_options
After:
Restore
Execute(The remark callback should return the correct default values):
AssertEqual
\ {
\ 'command': ale#Escape('remark')
\ },
\ ale#fixers#remark_lint#Fix(bufnr(''))
Execute(The remark executable and options should be configurable):
let g:ale_markdown_remark_lint_executable = '/path/to/remark'
let g:ale_markdown_remark_lint_options = '-h'
AssertEqual
\ {
\ 'command': ale#Escape('/path/to/remark')
\ . ' -h',
\ },
\ ale#fixers#remark_lint#Fix(bufnr(''))

View File

@@ -23,8 +23,7 @@ Execute(The rubocop callback should return the correct default values):
\ {
\ 'process_with': 'ale#fixers#rubocop#PostProcess',
\ 'command': ale#Escape(g:ale_ruby_rubocop_executable)
\ . ' --auto-correct --force-exclusion --stdin '
\ . ale#Escape(expand('#' . bufnr('') . ':p')),
\ . ' --auto-correct --force-exclusion --stdin %s',
\ },
\ ale#fixers#rubocop#Fix(bufnr(''))
@@ -36,8 +35,7 @@ Execute(The rubocop callback should include configuration files):
\ 'process_with': 'ale#fixers#rubocop#PostProcess',
\ 'command': ale#Escape(g:ale_ruby_rubocop_executable)
\ . ' --config ' . ale#Escape(ale#path#Simplify(g:dir . '/ruby_paths/with_config/.rubocop.yml'))
\ . ' --auto-correct --force-exclusion --stdin '
\ . ale#Escape(expand('#' . bufnr('') . ':p')),
\ . ' --auto-correct --force-exclusion --stdin %s',
\ },
\ ale#fixers#rubocop#Fix(bufnr(''))
@@ -51,8 +49,7 @@ Execute(The rubocop callback should include custom rubocop options):
\ 'command': ale#Escape(g:ale_ruby_rubocop_executable)
\ . ' --config ' . ale#Escape(ale#path#Simplify(g:dir . '/ruby_paths/with_config/.rubocop.yml'))
\ . ' --except Lint/Debugger'
\ . ' --auto-correct --force-exclusion --stdin '
\ . ale#Escape(expand('#' . bufnr('') . ':p')),
\ . ' --auto-correct --force-exclusion --stdin %s',
\ },
\ ale#fixers#rubocop#Fix(bufnr(''))
@@ -65,8 +62,7 @@ Execute(The rubocop callback should use auto-correct-all option when set):
\ 'process_with': 'ale#fixers#rubocop#PostProcess',
\ 'command': ale#Escape(g:ale_ruby_rubocop_executable)
\ . ' --config ' . ale#Escape(ale#path#Simplify(g:dir . '/ruby_paths/with_config/.rubocop.yml'))
\ . ' --auto-correct-all --force-exclusion --stdin '
\ . ale#Escape(expand('#' . bufnr('') . ':p')),
\ . ' --auto-correct-all --force-exclusion --stdin %s'
\ },
\ ale#fixers#rubocop#Fix(bufnr(''))

View File

@@ -15,7 +15,7 @@ Execute(The executable path should be correct):
\ 'read_temporary_file': 1,
\ 'command': (has('win32') ? 'node.exe ' : '')
\ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/standard/bin/cmd.js'))
\ . ' --fix %t',
\ . ' --fix --stdin < %s > %t',
\ },
\ ale#fixers#standard#Fix(bufnr(''))
@@ -26,6 +26,6 @@ Execute(Custom options should be supported):
AssertEqual
\ {
\ 'read_temporary_file': 1,
\ 'command': ale#Escape('standard') . ' --foo-bar --fix %t',
\ 'command': ale#Escape('standard') . ' --foo-bar --fix --stdin < %s > %t',
\ },
\ ale#fixers#standard#Fix(bufnr(''))

View File

@@ -1,4 +1,8 @@
Before:
Save g:ale_stylelint_options
let g:ale_stylelint_options = ''
call ale#assert#SetUpFixerTest('css', 'stylelint')
After:
@@ -10,7 +14,7 @@ Execute(The stylelint callback should return the correct default values):
AssertFixer
\ {
\ 'read_temporary_file': 1,
\ 'command': ale#path#CdString(expand('%:p:h'))
\ 'command': ale#path#BufferCdString(bufnr(''))
\ . (has('win32') ? 'node.exe ' : '')
\ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/stylelint/bin/stylelint.js'))
\ . ' %t'
@@ -24,7 +28,7 @@ Execute(The stylelint callback should include custom stylelint options):
AssertFixer
\ {
\ 'read_temporary_file': 1,
\ 'command': ale#path#CdString(expand('%:p:h'))
\ 'command': ale#path#BufferCdString(bufnr(''))
\ . (has('win32') ? 'node.exe ' : '')
\ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/stylelint/bin/stylelint.js'))
\ . ' %t'

View File

@@ -279,3 +279,38 @@ Execute(The GCC handler should handle errors for inlined header functions):
\ ' __open_too_many_args ();',
\ ' ^~~~~~~~~~~~~~~~~~~~~~~',
\ ])
Execute(The GCC handler should handle macro expansion errors in current file):
AssertEqual
\ [
\ {
\ 'lnum': 1,
\ 'col': 19,
\ 'type': 'E',
\ 'text': 'error message',
\ 'detail': "error message\n<stdin>:1:19: note: in expansion of macro 'TEST'",
\ },
\ ],
\ ale#handlers#gcc#HandleGCCFormatWithIncludes(347, [
\ '<command-line>: error: error message',
\ '<stdin>:1:19: note: in expansion of macro TEST',
\ ' 1 | std::string str = TEST;',
\ ' | ^~~~',
\ ])
Execute(The GCC handler should handle macro expansion errors in other files):
AssertEqual
\ [
\ {
\ 'lnum': 0,
\ 'type': 'E',
\ 'text': 'Error found in macro expansion. See :ALEDetail',
\ 'detail': "error message\ninc.h:1:19: note: in expansion of macro 'TEST'",
\ },
\ ],
\ ale#handlers#gcc#HandleGCCFormatWithIncludes(347, [
\ '<command-line>: error: error message',
\ 'inc.h:1:19: note: in expansion of macro TEST',
\ ' 1 | std::string str = TEST;',
\ ' | ^~~~',
\ ])

View File

@@ -1,3 +1,6 @@
Before:
runtime ale_linters/glsl/glslang.vim
Execute(The glsl glslang handler should parse lines correctly):
AssertEqual
\ [

View File

@@ -0,0 +1,23 @@
Before:
" Load the file which defines the linter.
runtime ale_linters/sql/sqllint.vim
After:
" Unload all linters again.
call ale#linter#Reset()
Execute (The output should be correct):
" Test that the right loclist items are parsed from the handler.
AssertEqual
\ [
\ {
\ 'lnum': 1,
\ 'col': 0,
\ 'type': '',
\ 'text': 'stdin:1 [ER_NO_DB_ERROR] No database selected'
\ },
\ ],
\ ale_linters#sql#sqllint#Handle(bufnr(''), [
\ 'stdin:1 [ER_NO_DB_ERROR] No database selected'
\ ])

View File

@@ -1,3 +1,11 @@
Before:
Save g:ale_javascript_eslint_suppress_eslintignore
let g:ale_javascript_eslint_suppress_eslintignore = 0
After:
Restore
Execute(The standard handler should parse lines correctly):
AssertEqual
\ [

View File

@@ -0,0 +1,28 @@
Before:
runtime ale_linters/swift/swiftformat.vim
After:
call ale#linter#Reset()
Execute(The swiftformat handler should parse lines correctly):
AssertEqual
\ [
\ {
\ 'lnum': 4,
\ 'col': 21,
\ 'type': 'W',
\ 'code': 'DoNotUseSemicolons',
\ 'text': 'remove '';'' and move the next statement to the new line',
\ },
\ {
\ 'lnum': 3,
\ 'col': 12,
\ 'type': 'W',
\ 'code': 'Spacing',
\ 'text': 'remove 1 space'
\ },
\ ],
\ ale_linters#swift#swiftformat#Handle(bufnr(''), [
\ 'Sources/main.swift:4:21: warning: [DoNotUseSemicolons]: remove '';'' and move the next statement to the new line',
\ 'Sources/main.swift:3:12: warning: [Spacing]: remove 1 space',
\ ])

View File

@@ -10,12 +10,14 @@ Execute(The vlog handler should parse old-style lines correctly):
\ {
\ 'lnum': 7,
\ 'type': 'W',
\ 'text': '(vlog-2623) Undefined variable: C.'
\ 'text': '(vlog-2623) Undefined variable: C.',
\ 'filename': 'add.v'
\ },
\ {
\ 'lnum': 1,
\ 'type': 'E',
\ 'text': '(vlog-13294) Identifier must be declared with a port mode: C.'
\ 'text': '(vlog-13294) Identifier must be declared with a port mode: C.',
\ 'filename': 'file.v'
\ },
\ ],
\ ale_linters#verilog#vlog#Handle(bufnr(''), [
@@ -29,12 +31,14 @@ Execute(The vlog handler should parse new-style lines correctly):
\ {
\ 'lnum': 7,
\ 'type': 'W',
\ 'text': '(vlog-2623) Undefined variable: C.'
\ 'text': '(vlog-2623) Undefined variable: C.',
\ 'filename': 'add.v'
\ },
\ {
\ 'lnum': 1,
\ 'type': 'E',
\ 'text': '(vlog-13294) Identifier must be declared with a port mode: C.'
\ 'text': '(vlog-13294) Identifier must be declared with a port mode: C.',
\ 'filename': 'file.v'
\ },
\ ],
\ ale_linters#verilog#vlog#Handle(bufnr(''), [

View File

@@ -33,8 +33,8 @@ Before:
\ 'lsp': 'stdio',
\ 'command': 'cat - > /dev/null',
\ 'executable': has('win32') ? 'cmd' : 'echo',
\ 'language_callback': 'LanguageCallback',
\ 'project_root_callback': 'ProjectRootCallback',
\ 'language': function('LanguageCallback'),
\ 'project_root': function('ProjectRootCallback'),
\ })
let g:ale_linters = {'foobar': ['dummy_linter']}

View File

@@ -44,9 +44,21 @@ After:
Given foobar(An empty file):
Execute(tsserver syntax error responses should be handled correctly):
runtime ale_linters/typescript/tsserver.vim
call ale#test#SetFilename('filename.ts')
if has('win32')
call ale#test#SetFilename('filename,[]^$.ts')
else
call ale#test#SetFilename('filename*?,{}[]^$.ts')
endif
call ale#engine#InitBufferInfo(bufnr(''))
if has('win32')
AssertEqual 'filename,[]^$.ts', expand('%:p:t')
else
AssertEqual 'filename*?,{}[]^$.ts', expand('%:p:t')
endif
" When we get syntax errors and no semantic errors, we should keep the
" syntax errors.
call ale#lsp_linter#HandleLSPResponse(1, {
@@ -54,7 +66,7 @@ Execute(tsserver syntax error responses should be handled correctly):
\ 'type': 'event',
\ 'event': 'syntaxDiag',
\ 'body': {
\ 'file': g:dir . '/filename.ts',
\ 'file': expand('%:p'),
\ 'diagnostics':[
\ {
\ 'start': {
@@ -76,7 +88,7 @@ Execute(tsserver syntax error responses should be handled correctly):
\ 'type': 'event',
\ 'event': 'semanticDiag',
\ 'body': {
\ 'file': g:dir . '/filename.ts',
\ 'file': expand('%:p'),
\ 'diagnostics':[
\ ],
\ },
@@ -104,7 +116,7 @@ Execute(tsserver syntax error responses should be handled correctly):
\ 'type': 'event',
\ 'event': 'syntaxDiag',
\ 'body': {
\ 'file': g:dir . '/filename.ts',
\ 'file': expand('%:p'),
\ 'diagnostics':[
\ ],
\ },
@@ -146,9 +158,21 @@ Execute(tsserver syntax error responses should be handled correctly):
Execute(tsserver semantic error responses should be handled correctly):
runtime ale_linters/typescript/tsserver.vim
call ale#test#SetFilename('filename.ts')
if has('win32')
call ale#test#SetFilename('filename,[]^$.ts')
else
call ale#test#SetFilename('filename*?,{}[]^$.ts')
endif
call ale#engine#InitBufferInfo(bufnr(''))
if has('win32')
AssertEqual 'filename,[]^$.ts', expand('%:p:t')
else
AssertEqual 'filename*?,{}[]^$.ts', expand('%:p:t')
endif
" When we get syntax errors and no semantic errors, we should keep the
" syntax errors.
call ale#lsp_linter#HandleLSPResponse(1, {
@@ -156,7 +180,7 @@ Execute(tsserver semantic error responses should be handled correctly):
\ 'type': 'event',
\ 'event': 'syntaxDiag',
\ 'body': {
\ 'file': g:dir . '/filename.ts',
\ 'file': expand('%:p'),
\ 'diagnostics':[
\ ],
\ },
@@ -166,7 +190,7 @@ Execute(tsserver semantic error responses should be handled correctly):
\ 'type': 'event',
\ 'event': 'semanticDiag',
\ 'body': {
\ 'file': g:dir . '/filename.ts',
\ 'file': expand('%:p'),
\ 'diagnostics':[
\ {
\ 'start': {
@@ -206,7 +230,7 @@ Execute(tsserver semantic error responses should be handled correctly):
\ 'type': 'event',
\ 'event': 'semanticDiag',
\ 'body': {
\ 'file': g:dir . '/filename.ts',
\ 'file': expand('%:p'),
\ 'diagnostics':[
\ ],
\ },
@@ -270,15 +294,27 @@ Execute(tsserver errors should mark tsserver no longer active):
Execute(LSP diagnostics responses should be handled correctly):
let b:ale_linters = ['eclipselsp']
runtime ale_linters/java/eclipselsp.vim
call ale#test#SetFilename('filename.java')
if has('win32')
call ale#test#SetFilename('filename,[]^$.ts')
else
call ale#test#SetFilename('filename*?,{}[]^$.java')
endif
call ale#engine#InitBufferInfo(bufnr(''))
call ale#lsp_linter#SetLSPLinterMap({'1': 'eclipselsp'})
if has('win32')
AssertEqual 'filename,[]^$.ts', expand('%:p:t')
else
AssertEqual 'filename*?,{}[]^$.java', expand('%:p:t')
endif
call ale#lsp_linter#HandleLSPResponse(1, {
\ 'jsonrpc':'2.0',
\ 'method':'textDocument/publishDiagnostics',
\ 'params': {
\ 'uri':'file://' . g:dir . '/filename.java',
\ 'uri': ale#path#ToURI(expand('%:p')),
\ 'diagnostics': [
\ {
\ 'range': {

View File

@@ -1,6 +1,10 @@
Before:
Save g:ale_command_wrapper
runtime autoload/ale/lsp.vim
let g:ale_command_wrapper = ''
let g:args = []
" Mock the StartProgram function so we can just capture the arguments.
@@ -9,6 +13,8 @@ Before:
endfunction
After:
Restore
unlet! g:args
runtime autoload/ale/lsp.vim
@@ -18,8 +24,8 @@ Execute(Command formatting should be applied correctly for LSP linters):
\ bufnr(''),
\ {
\ 'name': 'linter',
\ 'language_callback': {-> 'x'},
\ 'project_root_callback': {-> '/foo/bar'},
\ 'language': {-> 'x'},
\ 'project_root': {-> '/foo/bar'},
\ 'lsp': 'stdio',
\ 'executable': has('win32') ? 'cmd': 'true',
\ 'command': '%e --foo',

View File

@@ -25,7 +25,6 @@ Before:
\ 'name': g:linter_name,
\ 'project_root': {b -> g:project_root},
\ 'aliases': [],
\ 'language_callback': {b -> 'cpp'},
\ 'read_buffer': 1,
\ 'command': '%e'
\ }]

View File

@@ -422,3 +422,13 @@ Execute(Deferred addresses should be handled correctly):
Assert Start()
call ale#test#FlushJobs()
call AssertInitSuccess('foo', 'localhost:1234', 'foobar', '/foo/bar', '')
Execute(Servers that have crashed should be restarted):
call ale#lsp#Register('foo', '/foo/bar', {})
call extend(ale#lsp#GetConnections()['foo:/foo/bar'], {'initialized': 1})
" Starting the program again should reset initialized to `0`.
call ale#lsp#StartProgram('foo:/foo/bar', 'foobar', 'foobar --start')
AssertEqual 0, ale#lsp#GetConnections()['foo:/foo/bar']['initialized']
AssertEqual ['initialize'], map(PopMessages(), 'v:val[''method'']')

View File

@@ -10,7 +10,9 @@ Before:
Save g:ale_set_loclist
Save g:ale_set_quickfix
Save g:ale_set_signs
Save g:ale_command_wrapper
let g:ale_command_wrapper = ''
let g:ale_buffer_info = {}
let g:ale_run_synchronously = 1
unlet! g:ale_run_synchronously_callbacks

View File

@@ -6,7 +6,9 @@ Before:
Save g:ale_set_loclist
Save g:ale_set_quickfix
Save g:ale_set_signs
Save g:ale_command_wrapper
let g:ale_command_wrapper = ''
let g:ale_buffer_info = {}
let g:ale_run_synchronously = 1
let g:ale_set_signs = 1

View File

@@ -1,8 +1,10 @@
Before:
Save g:ale_enabled
Save g:ale_set_lists_synchronously
Save g:ale_buffer_info
Save &shell
let g:ale_enabled = 1
let g:ale_buffer_info = {}
let g:ale_set_lists_synchronously = 1

View File

@@ -92,8 +92,8 @@ Execute (All events should be set up when everything is on):
\ 'FileType * call ale#events#FileTypeEvent( str2nr(expand(''<abuf>'')), expand(''<amatch>''))',
\ 'InsertLeave * if ale#Var(str2nr(expand(''<abuf>'')), ''lint_on_insert_leave'') | call ale#Queue(0) | endif',
\ 'InsertLeave if exists(''*ale#engine#Cleanup'') | call ale#cursor#EchoCursorWarning() | endif',
\ 'TextChanged * call ale#Queue(g:ale_lint_delay)',
\ 'TextChangedI * call ale#Queue(g:ale_lint_delay)',
\ 'TextChanged * call ale#Queue(ale#Var(str2nr(expand(''<abuf>'')), ''lint_delay''))',
\ 'TextChangedI * call ale#Queue(ale#Var(str2nr(expand(''<abuf>'')), ''lint_delay''))',
\ ],
\ CheckAutocmd('ALEEvents')
@@ -145,8 +145,8 @@ Execute (g:ale_lint_on_text_changed = 1 bind both events):
AssertEqual
\ [
\ 'TextChanged * call ale#Queue(g:ale_lint_delay)',
\ 'TextChangedI * call ale#Queue(g:ale_lint_delay)',
\ 'TextChanged * call ale#Queue(ale#Var(str2nr(expand(''<abuf>'')), ''lint_delay''))',
\ 'TextChangedI * call ale#Queue(ale#Var(str2nr(expand(''<abuf>'')), ''lint_delay''))',
\ ],
\ filter(CheckAutocmd('ALEEvents'), 'v:val =~ ''^TextChanged''')
@@ -155,8 +155,8 @@ Execute (g:ale_lint_on_text_changed = 'always' should bind both events):
AssertEqual
\ [
\ 'TextChanged * call ale#Queue(g:ale_lint_delay)',
\ 'TextChangedI * call ale#Queue(g:ale_lint_delay)',
\ 'TextChanged * call ale#Queue(ale#Var(str2nr(expand(''<abuf>'')), ''lint_delay''))',
\ 'TextChangedI * call ale#Queue(ale#Var(str2nr(expand(''<abuf>'')), ''lint_delay''))',
\ ],
\ filter(CheckAutocmd('ALEEvents'), 'v:val =~ ''^TextChanged''')
@@ -165,7 +165,7 @@ Execute (g:ale_lint_on_text_changed = 'normal' should bind only TextChanged):
AssertEqual
\ [
\ 'TextChanged * call ale#Queue(g:ale_lint_delay)',
\ 'TextChanged * call ale#Queue(ale#Var(str2nr(expand(''<abuf>'')), ''lint_delay''))',
\ ],
\ filter(CheckAutocmd('ALEEvents'), 'v:val =~ ''^TextChanged''')
@@ -174,7 +174,7 @@ Execute (g:ale_lint_on_text_changed = 'insert' should bind only TextChangedI):
AssertEqual
\ [
\ 'TextChangedI * call ale#Queue(g:ale_lint_delay)',
\ 'TextChangedI * call ale#Queue(ale#Var(str2nr(expand(''<abuf>'')), ''lint_delay''))',
\ ],
\ filter(CheckAutocmd('ALEEvents'), 'v:val =~ ''^TextChanged''')

View File

@@ -1,15 +1,43 @@
Before:
Save g:ale_c_parse_makefile
Save g:ale_c_always_make
Save b:ale_c_always_make
call ale#test#SetDirectory('/testplugin/test')
let g:ale_c_parse_makefile = 1
let g:ale_c_always_make = 1
let b:ale_c_always_make = 1
function SplitAndParse(path_prefix, command) abort
let l:args = ale#c#ShellSplit(a:command)
return ale#c#ParseCFlags(a:path_prefix, 0, l:args)
endfunction
After:
delfunction SplitAndParse
Restore
call ale#test#RestoreDirectory()
Execute(The make command should be correct):
call ale#test#SetFilename('test_c_projects/makefile_project/subdir/file.c')
AssertEqual
\ ale#path#CdString(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project'))
\ . 'make -n --always-make',
\ ale#c#GetMakeCommand(bufnr(''))
" You should be able to disable --always-make for a buffer.
let b:ale_c_always_make = 0
AssertEqual
\ ale#path#CdString(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project'))
\ . 'make -n',
\ ale#c#GetMakeCommand(bufnr(''))
Execute(The CFlags parser should be able to parse include directives):
call ale#test#SetFilename('test_c_projects/makefile_project/subdir/file.c')
@@ -18,7 +46,7 @@ Execute(The CFlags parser should be able to parse include directives):
\ ale#c#ParseCFlagsFromMakeOutput(bufnr(''), ['gcc -Isubdir -c file.c'])
AssertEqual
\ '-isystem ' . '/usr/include/dir',
\ '-isystem ' . ale#Escape('/usr/include/dir'),
\ ale#c#ParseCFlagsFromMakeOutput(bufnr(''), ['gcc -isystem /usr/include/dir -c file.c'])
Execute(ParseCFlags should ignore -c and -o):
@@ -57,48 +85,21 @@ Execute(ParseCFlags should be able to parse flags with relative paths):
\ '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/subdir'))
\ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/kernel/include'))
\ . ' -DTEST=`date +%s`',
\ ale#c#ParseCFlags(
\ SplitAndParse(
\ ale#path#Simplify(g:dir. '/test_c_projects/makefile_project'),
\ 'gcc -Isubdir '
\ . '-I'. ale#path#Simplify('kernel/include')
\ . ' -DTEST=`date +%s` -c file.c'
\ )
Execute(ParseCFlags should be able to parse -Dgoal):
AssertEqual
\ '-Dgoal=9'
\ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/subdir'))
\ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/kernel/include'))
\ . ' -DTEST=`date +%s`',
\ ale#c#ParseCFlags(
\ ale#path#Simplify(g:dir. '/test_c_projects/makefile_project'),
\ 'gcc -Dgoal=9 -Isubdir '
\ . '-I'. ale#path#Simplify('kernel/include')
\ . ' -DTEST=`date +%s` -c file.c'
\ )
Execute(ParseCFlags should ignore -T and other arguments):
AssertEqual
\ '-Dgoal=9'
\ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/subdir'))
\ . ' ' . '--sysroot=subdir'
\ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/kernel/include'))
\ . ' -DTEST=`date +%s`',
\ ale#c#ParseCFlags(
\ ale#path#Simplify(g:dir. '/test_c_projects/makefile_project'),
\ 'gcc -Dgoal=9 -Tlinkerfile.ld blabla -Isubdir --sysroot=subdir '
\ . '-I'. ale#path#Simplify('kernel/include')
\ . ' -DTEST=`date +%s` -c file.c'
\ )
Execute(ParseCFlags should handle paths with spaces in double quotes):
Execute(We should handle paths with spaces in double quotes):
AssertEqual
\ '-Dgoal=9'
\ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/subdir'))
\ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/dir with spaces'))
\ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/kernel/include'))
\ . ' -DTEST=`date +%s`',
\ ale#c#ParseCFlags(
\ SplitAndParse(
\ ale#path#Simplify(g:dir. '/test_c_projects/makefile_project'),
\ 'gcc -Dgoal=9 -Tlinkerfile.ld blabla -Isubdir '
\ . '-I"dir with spaces"' . ' -I'. ale#path#Simplify('kernel/include')
@@ -112,7 +113,7 @@ Execute(ParseCFlags should handle paths with spaces in single quotes):
\ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/dir with spaces'))
\ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/kernel/include'))
\ . ' -DTEST=`date +%s`',
\ ale#c#ParseCFlags(
\ SplitAndParse(
\ ale#path#Simplify(g:dir. '/test_c_projects/makefile_project'),
\ 'gcc -Dgoal=9 -Tlinkerfile.ld blabla -Isubdir '
\ . '-I''dir with spaces''' . ' -I'. ale#path#Simplify('kernel/include')
@@ -127,7 +128,7 @@ Execute(ParseCFlags should handle paths with minuses):
\ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/dir-with-dash'))
\ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/kernel/include'))
\ . ' -DTEST=`date +%s`',
\ ale#c#ParseCFlags(
\ SplitAndParse(
\ ale#path#Simplify(g:dir. '/test_c_projects/makefile_project'),
\ 'gcc -Dgoal=9 -Tlinkerfile.ld blabla -Isubdir '
\ . '-I''dir with spaces''' . ' -Idir-with-dash'
@@ -135,7 +136,7 @@ Execute(ParseCFlags should handle paths with minuses):
\ . ' -DTEST=`date +%s` -c file.c'
\ )
Execute(ParseCFlags should handle -D with minuses):
Execute(We should handle -D with minuses):
AssertEqual
\ '-Dgoal=9'
\ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/subdir'))
@@ -144,7 +145,7 @@ Execute(ParseCFlags should handle -D with minuses):
\ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/dir-with-dash'))
\ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/kernel/include'))
\ . ' -DTEST=`date +%s`',
\ ale#c#ParseCFlags(
\ SplitAndParse(
\ ale#path#Simplify(g:dir. '/test_c_projects/makefile_project'),
\ 'gcc -Dgoal=9 -Tlinkerfile.ld blabla -Isubdir '
\ . '-Dmacro-with-dash '
@@ -153,7 +154,7 @@ Execute(ParseCFlags should handle -D with minuses):
\ . ' -DTEST=`date +%s` -c file.c'
\ )
Execute(ParseCFlags should handle flags at the end of the line):
Execute(We should handle flags at the end of the line):
AssertEqual
\ '-Dgoal=9'
\ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/subdir'))
@@ -161,7 +162,7 @@ Execute(ParseCFlags should handle flags at the end of the line):
\ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/dir with spaces'))
\ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/dir-with-dash'))
\ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/kernel/include')),
\ ale#c#ParseCFlags(
\ SplitAndParse(
\ ale#path#Simplify(g:dir. '/test_c_projects/makefile_project'),
\ 'gcc -Dgoal=9 -Tlinkerfile.ld blabla -Isubdir '
\ . '-Dmacro-with-dash '
@@ -178,50 +179,170 @@ Execute(ParseCompileCommandsFlags should tolerate empty values):
Execute(ParseCompileCommandsFlags should parse some basic flags):
silent noautocmd execute 'file! ' . fnameescape(ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.c'))
" We should read the absolute path filename entry, not the other ones.
AssertEqual
\ '-I ' . ale#path#Simplify('/usr/include/xmms2'),
\ ale#c#ParseCompileCommandsFlags(bufnr(''), { "xmms2-mpris.c": [
\ '-I ' . ale#Escape(ale#path#Simplify('/usr/include/xmms2')),
\ ale#c#ParseCompileCommandsFlags(
\ bufnr(''),
\ {
\ 'directory': ale#path#Simplify('/foo/bar/xmms2-mpris'),
\ 'command': '/usr/bin/cc -I' . ale#path#Simplify('/usr/include/xmms2')
\ . ' -o CMakeFiles/xmms2-mpris.dir/src/xmms2-mpris.c.o'
\ . ' -c ' . ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.c'),
\ 'file': ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.c'),
\ ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.c'): [
\ {
\ 'directory': ale#path#Simplify('/foo/bar/xmms2-mpris'),
\ 'command': '/usr/bin/cc -I' . ale#path#Simplify('/usr/include/xmms2')
\ . ' -o CMakeFiles/xmms2-mpris.dir/src/xmms2-mpris.c.o'
\ . ' -c ' . ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.c'),
\ 'file': ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.c'),
\ },
\ ],
\ "xmms2-mpris.c": [
\ {
\ 'directory': ale#path#Simplify('/foo/bar/xmms2-mpris'),
\ 'command': '/usr/bin/cc -I' . ale#path#Simplify('/usr/include/ignoreme')
\ . ' -o CMakeFiles/xmms2-mpris.dir/src/xmms2-mpris.c.o'
\ . ' -c ' . ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.c'),
\ 'file': ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.c'),
\ },
\ ],
\ },
\ ] }, {})
\ {
\ ale#path#Simplify('/foo/bar/xmms2-mpris/src'): [
\ {
\ 'directory': ale#path#Simplify('/foo/bar/xmms2-mpris/src'),
\ 'command': '/usr/bin/cc -I' . ale#path#Simplify('/usr/include/ignoreme')
\ . ' -o CMakeFiles/xmms2-mpris.dir/src/xmms2-mpris.c.o'
\ . ' -c ' . ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.c'),
\ 'file': 'other.c',
\ },
\ ],
\ "src": [
\ {
\ 'directory': ale#path#Simplify('/foo/bar/xmms2-mpris'),
\ 'command': '/usr/bin/cc -I' . ale#path#Simplify('/usr/include/ignoreme')
\ . ' -o CMakeFiles/xmms2-mpris.dir/src/xmms2-mpris.c.o'
\ . ' -c ' . ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.c'),
\ 'file': ale#path#Simplify((has('win32') ? 'C:' : '') . '/foo/bar/xmms2-mpris/src/xmms2-other.c'),
\ },
\ ],
\ },
\ )
Execute(ParseCompileCommandsFlags should fall back to files with the same name):
silent noautocmd execute 'file! ' . fnameescape(ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.c'))
" We should prefer the basename file flags, not the base dirname flags.
AssertEqual
\ '-I ' . ale#Escape(ale#path#Simplify('/usr/include/xmms2')),
\ ale#c#ParseCompileCommandsFlags(
\ bufnr(''),
\ {
\ "xmms2-mpris.c": [
\ {
\ 'directory': ale#path#Simplify('/foo/bar/xmms2-mpris'),
\ 'command': '/usr/bin/cc -I' . ale#path#Simplify('/usr/include/xmms2')
\ . ' -o CMakeFiles/xmms2-mpris.dir/src/xmms2-mpris.c.o'
\ . ' -c ' . ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.c'),
\ 'file': ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.c'),
\ },
\ ],
\ },
\ {
\ "src": [
\ {
\ 'directory': ale#path#Simplify('/foo/bar/xmms2-mpris'),
\ 'command': '/usr/bin/cc -I' . ale#path#Simplify('/usr/include/ignoreme')
\ . ' -o CMakeFiles/xmms2-mpris.dir/src/xmms2-mpris.c.o'
\ . ' -c ' . ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.c'),
\ 'file': ale#path#Simplify((has('win32') ? 'C:' : '') . '/foo/bar/xmms2-mpris/src/xmms2-other.c'),
\ },
\ ],
\ },
\ )
Execute(ParseCompileCommandsFlags should parse flags for exact directory matches):
silent noautocmd execute 'file! ' . fnameescape(ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.c'))
" We should ues the exact directory flags, not the file basename flags.
AssertEqual
\ '-I ' . ale#Escape(ale#path#Simplify('/usr/include/xmms2')),
\ ale#c#ParseCompileCommandsFlags(
\ bufnr(''),
\ {
\ "xmms2-mpris.c": [
\ {
\ 'directory': ale#path#Simplify('/foo/bar/xmms2-mpris'),
\ 'command': '/usr/bin/cc -I' . ale#path#Simplify('/usr/include/ignoreme')
\ . ' -o CMakeFiles/xmms2-mpris.dir/src/xmms2-mpris.c.o'
\ . ' -c ' . ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.c'),
\ 'file': ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.c'),
\ },
\ ],
\ },
\ {
\ ale#path#Simplify('/foo/bar/xmms2-mpris/src'): [
\ {
\ 'directory': ale#path#Simplify('/foo/bar/xmms2-mpris/src'),
\ 'command': '/usr/bin/cc -I' . ale#path#Simplify('/usr/include/xmms2')
\ . ' -o CMakeFiles/xmms2-mpris.dir/src/xmms2-mpris.c.o'
\ . ' -c ' . ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.c'),
\ 'file': 'other.c',
\ },
\ ],
\ "src": [
\ {
\ 'directory': ale#path#Simplify('/foo/bar/xmms2-mpris'),
\ 'command': '/usr/bin/cc -I' . ale#path#Simplify('/usr/include/ignoreme')
\ . ' -o CMakeFiles/xmms2-mpris.dir/src/xmms2-mpris.c.o'
\ . ' -c ' . ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.c'),
\ 'file': ale#path#Simplify((has('win32') ? 'C:' : '') . '/foo/bar/xmms2-mpris/src/xmms2-other.c'),
\ },
\ ],
\ },
\ )
Execute(ParseCompileCommandsFlags should fall back to files in the same directory):
silent noautocmd execute 'file! ' . fnameescape(ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.c'))
AssertEqual
\ '-I ' . ale#Escape(ale#path#Simplify('/usr/include/xmms2')),
\ ale#c#ParseCompileCommandsFlags(
\ bufnr(''),
\ {},
\ {
\ "src": [
\ {
\ 'directory': ale#path#Simplify('/foo/bar/xmms2-mpris'),
\ 'command': '/usr/bin/cc -I' . ale#path#Simplify('/usr/include/xmms2')
\ . ' -o CMakeFiles/xmms2-mpris.dir/src/xmms2-mpris.c.o'
\ . ' -c ' . ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.c'),
\ 'file': ale#path#Simplify((has('win32') ? 'C:' : '') . '/foo/bar/xmms2-mpris/src/xmms2-other.c'),
\ },
\ ],
\ },
\ )
Execute(ParseCompileCommandsFlags should tolerate items without commands):
silent noautocmd execute 'file! ' . fnameescape(ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.c'))
AssertEqual
\ '',
\ ale#c#ParseCompileCommandsFlags(bufnr(''), { "xmms2-mpris.c": [
\ ale#c#ParseCompileCommandsFlags(
\ bufnr(''),
\ {
\ 'directory': '/foo/bar/xmms2-mpris',
\ 'file': '/foo/bar/xmms2-mpris/src/xmms2-mpris.c',
\ "xmms2-mpris.c": [
\ {
\ 'directory': '/foo/bar/xmms2-mpris',
\ 'file': '/foo/bar/xmms2-mpris/src/xmms2-mpris.c',
\ },
\ ],
\ },
\ ] }, {})
Execute(ParseCompileCommandsFlags should fall back to files in the same directory):
silent noautocmd execute 'file! ' . fnameescape(ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.c'))
AssertEqual
\ '-I ' . ale#path#Simplify('/usr/include/xmms2'),
\ ale#c#ParseCompileCommandsFlags(bufnr(''), {}, { "src": [
\ {
\ 'directory': ale#path#Simplify('/foo/bar/xmms2-mpris'),
\ 'command': '/usr/bin/cc -I' . ale#path#Simplify('/usr/include/xmms2')
\ . ' -o CMakeFiles/xmms2-mpris.dir/src/xmms2-mpris.c.o'
\ . ' -c ' . ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.c'),
\ 'file': ale#path#Simplify((has('win32') ? 'C:' : '') . '/foo/bar/xmms2-mpris/src/xmms2-other.c'),
\ },
\ ] })
\ {},
\ )
Execute(ParseCompileCommandsFlags should take commands from matching .c files for .h files):
silent noautocmd execute 'file! ' . fnameescape(ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.h'))
AssertEqual
\ '-I /usr/include/xmms2',
\ '-I ' . ale#Escape('/usr/include/xmms2'),
\ ale#c#ParseCompileCommandsFlags(
\ bufnr(''),
\ {
@@ -235,15 +356,14 @@ Execute(ParseCompileCommandsFlags should take commands from matching .c files fo
\ },
\ ],
\ },
\ {
\ },
\ {},
\ )
Execute(ParseCompileCommandsFlags should take commands from matching .cpp files for .hpp files):
silent noautocmd execute 'file! ' . fnameescape(ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.hpp'))
AssertEqual
\ '-I /usr/include/xmms2',
\ '-I ' . ale#Escape('/usr/include/xmms2'),
\ ale#c#ParseCompileCommandsFlags(
\ bufnr(''),
\ {
@@ -265,7 +385,7 @@ Execute(ParseCompileCommandsFlags should take commands from matching .cpp files
silent noautocmd execute 'file! ' . fnameescape(ale#path#Simplify('/foo/bar/xmms2-mpris/src/xmms2-mpris.h'))
AssertEqual
\ '-I /usr/include/xmms2',
\ '-I ' . ale#Escape('/usr/include/xmms2'),
\ ale#c#ParseCompileCommandsFlags(
\ bufnr(''),
\ {
@@ -305,42 +425,69 @@ Execute(ParseCompileCommandsFlags should not take commands from .c files for .h
\ },
\ )
Execute(ParseCFlags should not merge flags):
Execute(ShellSplit should not merge flags):
AssertEqual
\ '-Dgoal=9'
\ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/subdir'))
\ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/dir with spaces'))
\ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/dir-with-dash'))
\ . ' ' . '-I' . ' ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/kernel/include')),
\ ale#c#ParseCFlags(
\ ale#path#Simplify(g:dir. '/test_c_projects/makefile_project'),
\ [
\ 'gcc',
\ '-Dgoal=9',
\ '-Tlinkerfile.ld',
\ 'blabla',
\ '-Isubdir',
\ 'subdir/somedep1.o',
\ 'subdir/somedep2.o',
\ '-I''dir with spaces''',
\ '-Idir-with-dash',
\ 'subdir/somedep3.o',
\ 'subdir/somedep4.o',
\ '-I' . ale#path#Simplify('kernel/include'),
\ 'subdir/somedep5.o',
\ 'subdir/somedep6.o',
\ ],
\ ale#c#ShellSplit(
\ 'gcc -Dgoal=9 -Tlinkerfile.ld blabla -Isubdir '
\ . 'subdir/somedep1.o ' . 'subdir/somedep2.o '
\ . '-I''dir with spaces''' . ' -Idir-with-dash '
\ . 'subdir/somedep3.o ' . 'subdir/somedep4.o '
\ . ' -I'. ale#path#Simplify('kernel/include') . ' '
\ . 'subdir/somedep5.o ' . 'subdir/somedep6.o '
\ . 'subdir/somedep5.o ' . 'subdir/somedep6.o'
\ )
Execute(ParseCFlags should handle parenthesis and quotes):
Execute(ShellSplit should handle parenthesis and quotes):
AssertEqual
\ '-Dgoal=9 -Dtest1="('' '')" -Dtest2=''(` `)'' -Dtest3=`(" ")`',
\ ale#c#ParseCFlags(
\ ale#path#Simplify(g:dir. '/test_c_projects/makefile_project'),
\ [
\ 'gcc',
\ '-Dgoal=9',
\ '-Tlinkerfile.ld',
\ 'blabla',
\ '-Dtest1="('' '')"',
\ 'file1.o',
\ '-Dtest2=''(` `)''',
\ 'file2.o',
\ '-Dtest3=`(" ")`',
\ 'file3.o',
\ ] ,
\ ale#c#ShellSplit(
\ 'gcc -Dgoal=9 -Tlinkerfile.ld blabla '
\ . '-Dtest1="('' '')" file1.o '
\ . '-Dtest2=''(` `)'' file2.o '
\ . '-Dtest3=`(" ")` file3.o '
\ . '-Dtest3=`(" ")` file3.o'
\ )
Execute(CFlags we want to pass):
Execute(We should include several important flags):
AssertEqual
\ '-I ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/inc'))
\ . ' -I ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/include'))
\ . ' -iquote ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/incquote'))
\ . ' -isystem ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/incsystem'))
\ '-I ' . ale#Escape(ale#path#Simplify(g:dir . '/test_c_projects/makefile_project/inc'))
\ . ' -I ' . ale#Escape(ale#path#Simplify(g:dir . '/test_c_projects/makefile_project/include'))
\ . ' -iquote ' . ale#Escape(ale#path#Simplify(g:dir . '/test_c_projects/makefile_project/incquote'))
\ . ' -isystem ' . ale#Escape(ale#path#Simplify(g:dir . '/test_c_projects/makefile_project/incsystem'))
\ . ' -idirafter ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/incafter'))
\ . ' -Dmacro=value -D macro2 -Bbdir -B bdir2'
\ . ' -iframework ' . ale#Escape(ale#path#Simplify(g:dir . '/test_c_projects/makefile_project/incframework'))
\ . ' -include ' . ale#Escape(ale#path#Simplify(g:dir . '/test_c_projects/makefile_project/foo bar'))
\ . ' -Dmacro="value"'
\ . ' -DGoal=9'
\ . ' -D macro2'
\ . ' -D macro3="value"'
\ . ' -Bbdir'
\ . ' -B bdir2'
\ . ' -iprefix prefix -iwithprefix prefix2 -iwithprefixbefore prefix3'
\ . ' -isysroot sysroot --sysroot=test --no-sysroot-suffix -imultilib multidir'
\ . ' -Wsome-warning -std=c89 -pedantic -pedantic-errors -ansi'
@@ -348,21 +495,175 @@ Execute(CFlags we want to pass):
\ . ' -iplugindir=dir -march=native -w',
\ ale#c#ParseCFlags(
\ ale#path#Simplify(g:dir. '/test_c_projects/makefile_project'),
\ 'gcc'
\ . ' -Iinc -I include -iquote incquote -isystem incsystem -idirafter incafter'
\ . ' -Dmacro=value -D macro2 -Bbdir -B bdir2'
\ . ' -iprefix prefix -iwithprefix prefix2 -iwithprefixbefore prefix3'
\ . ' -isysroot sysroot --sysroot=test --no-sysroot-suffix -imultilib multidir'
\ . ' -Wsome-warning -std=c89 -pedantic -pedantic-errors -ansi'
\ . ' -foption -O2 -C -CC -trigraphs -nostdinc -nostdinc++'
\ . ' -iplugindir=dir -march=native -w'
\ 0,
\ [
\ 'gcc',
\ '-Iinc',
\ '-I',
\ 'include',
\ '-iquote',
\ 'incquote',
\ '-isystem',
\ 'incsystem',
\ '-idirafter',
\ 'incafter',
\ '-iframework',
\ 'incframework',
\ '-include',
\ '''foo bar''',
\ '-Dmacro="value"',
\ '-DGoal=9',
\ '-D',
\ 'macro2',
\ '-D',
\ 'macro3="value"',
\ '-Bbdir',
\ '-B',
\ 'bdir2',
\ '-iprefix',
\ 'prefix',
\ '-iwithprefix',
\ 'prefix2',
\ '-iwithprefixbefore',
\ 'prefix3',
\ '-isysroot',
\ 'sysroot',
\ '--sysroot=test',
\ '--no-sysroot-suffix',
\ '-imultilib',
\ 'multidir',
\ '-Wsome-warning',
\ '-std=c89',
\ '-pedantic',
\ '-pedantic-errors',
\ '-ansi',
\ '-foption',
\ '-O2',
\ '-C',
\ '-CC',
\ '-trigraphs',
\ '-nostdinc',
\ '-nostdinc++',
\ '-iplugindir=dir',
\ '-march=native',
\ '-w',
\ ],
\ )
Execute(CFlags we dont want to pass):
Execute(We should quote the flags we need to quote):
AssertEqual
\ '-I ' . ale#Escape(ale#path#Simplify(g:dir . '/test_c_projects/makefile_project/inc'))
\ . ' -I ' . ale#Escape(ale#path#Simplify(g:dir . '/test_c_projects/makefile_project/include'))
\ . ' -iquote ' . ale#Escape(ale#path#Simplify(g:dir . '/test_c_projects/makefile_project/incquote'))
\ . ' -isystem ' . ale#Escape(ale#path#Simplify(g:dir . '/test_c_projects/makefile_project/incsystem'))
\ . ' -idirafter ' . ale#Escape(ale#path#Simplify(g:dir. '/test_c_projects/makefile_project/incafter'))
\ . ' -iframework ' . ale#Escape(ale#path#Simplify(g:dir . '/test_c_projects/makefile_project/incframework'))
\ . ' -include ' . ale#Escape(ale#path#Simplify(g:dir . '/test_c_projects/makefile_project/foo bar'))
\ . ' ' . ale#Escape('-Dmacro="value"')
\ . ' -DGoal=9'
\ . ' -D macro2'
\ . ' -D ' . ale#Escape('macro3="value"')
\ . ' -Bbdir'
\ . ' -B bdir2'
\ . ' -iprefix prefix -iwithprefix prefix2 -iwithprefixbefore prefix3'
\ . ' -isysroot sysroot --sysroot=test'
\ . ' ' . ale#Escape('--sysroot="quoted"')
\ . ' ' . ale#Escape('--sysroot=foo bar')
\ . ' --no-sysroot-suffix -imultilib multidir'
\ . ' -Wsome-warning -std=c89 -pedantic -pedantic-errors -ansi'
\ . ' -foption -O2 -C -CC -trigraphs -nostdinc -nostdinc++'
\ . ' -iplugindir=dir -march=native -w',
\ ale#c#ParseCFlags(
\ ale#path#Simplify(g:dir. '/test_c_projects/makefile_project'),
\ 1,
\ [
\ 'gcc',
\ '-Iinc',
\ '-I',
\ 'include',
\ '-iquote',
\ 'incquote',
\ '-isystem',
\ 'incsystem',
\ '-idirafter',
\ 'incafter',
\ '-iframework',
\ 'incframework',
\ '-include',
\ '''foo bar''',
\ '-Dmacro="value"',
\ '-DGoal=9',
\ '-D',
\ 'macro2',
\ '-D',
\ 'macro3="value"',
\ '-Bbdir',
\ '-B',
\ 'bdir2',
\ '-iprefix',
\ 'prefix',
\ '-iwithprefix',
\ 'prefix2',
\ '-iwithprefixbefore',
\ 'prefix3',
\ '-isysroot',
\ 'sysroot',
\ '--sysroot=test',
\ '--sysroot="quoted"',
\ '--sysroot=foo bar',
\ '--no-sysroot-suffix',
\ '-imultilib',
\ 'multidir',
\ '-Wsome-warning',
\ '-std=c89',
\ '-pedantic',
\ '-pedantic-errors',
\ '-ansi',
\ '-foption',
\ '-O2',
\ '-C',
\ '-CC',
\ '-trigraphs',
\ '-nostdinc',
\ '-nostdinc++',
\ '-iplugindir=dir',
\ '-march=native',
\ '-w',
\ ],
\ )
Execute(We should exclude other flags that cause problems):
AssertEqual
\ '',
\ ale#c#ParseCFlags(
\ ale#path#Simplify(g:dir. '/test_c_projects/makefile_project'),
\ 'gcc -Wl,option -Wa,option -Wp,option filename.c somelib.a '
\ . '-fdump-file=name -fdiagnostics-arg -fno-show-column'
\ 0,
\ [
\ 'gcc',
\ '-Wl,option',
\ '-Wa,option',
\ '-Wp,option',
\ '-c',
\ 'filename.c',
\ 'somelib.a',
\ '-fdump-file=name',
\ '-fdiagnostics-arg',
\ '-fno-show-column',
\ '-fstack-usage',
\ '-Tlinkerfile.ld',
\ ],
\ )
Execute(We should expand @file in CFlags):
AssertEqual
\ '-DARGS1 -DARGS2 -O2',
\ ale#c#ParseCFlags(
\ ale#path#Simplify(g:dir. '/test_c_projects/makefile_project'),
\ 0,
\ [
\ 'gcc',
\ '-g',
\ '@./args',
\ '-O2',
\ ],
\ )

View File

@@ -0,0 +1,3 @@
foolib.a
-DARGS1
@subdir/args

View File

@@ -0,0 +1 @@
-DARGS2

View File

@@ -1,4 +1,8 @@
Before:
Save g:ale_enabled
let g:ale_enabled = 0
runtime autoload/ale/code_action.vim
runtime autoload/ale/util.vim
@@ -35,6 +39,8 @@ Before:
endfunction!
After:
Restore
" Close the extra buffers if we opened it.
if bufnr(g:file1) != -1
execute ':bp! | :bd! ' . bufnr(g:file1)
@@ -50,9 +56,10 @@ After:
call delete(g:file2)
endif
unlet g:file1
unlet g:file2
unlet g:test
unlet! g:file1
unlet! g:file2
unlet! g:test
unlet! g:changes
delfunction WriteFileAndEdit
runtime autoload/ale/code_action.vim
@@ -350,3 +357,36 @@ Execute(It should just modify file when should_save is set to v:false):
\ ' value: string',
\ '}',
\], getline(1, '$')
Given typescript(An example TypeScript file):
type Foo = {}
export interface ISomething {
fooLongName: Foo | null
}
export class SomethingElse implements ISomething {
// Bindings
fooLongName!: ISomething['fooLongName']
}
Execute():
let g:changes = [
\ {'end': {'offset': 14, 'line': 4}, 'newText': 'foo', 'start': {'offset': 3, 'line': 4}},
\ {'end': {'offset': 40, 'line': 9}, 'newText': 'foo', 'start': {'offset': 29, 'line': 9}},
\ {'end': {'offset': 14, 'line': 9}, 'newText': 'foo', 'start': {'offset': 3, 'line': 9}},
\]
call ale#code_action#ApplyChanges(expand('%:p'), g:changes, 0)
Expect(The changes should be applied correctly):
type Foo = {}
export interface ISomething {
foo: Foo | null
}
export class SomethingElse implements ISomething {
// Bindings
foo!: ISomething['foo']
}

View File

@@ -1,73 +0,0 @@
Before:
Save &shell, g:ale_run_synchronously
let g:ale_run_synchronously = 1
unlet! g:ale_run_synchronously_callbacks
if !has('win32')
set shell=/bin/sh
endif
let g:linter_output = []
let g:first_echo_called = 0
let g:second_echo_called = 0
let g:final_callback_called = 0
function! CollectResults(buffer, output)
let g:final_callback_called = 1
let g:linter_output = map(copy(a:output), 'join(split(v:val))')
return []
endfunction
function! RunFirstEcho(buffer)
let g:first_echo_called = 1
return 'echo foo'
endfunction
function! RunSecondEcho(buffer, output)
let g:second_echo_called = 1
return 'echo bar'
endfunction
call ale#linter#Define('foobar', {
\ 'name': 'testlinter',
\ 'callback': 'CollectResults',
\ 'executable': has('win32') ? 'cmd' : 'echo',
\ 'command_chain': [
\ {
\ 'callback': 'RunFirstEcho',
\ 'output_stream': 'stdout',
\ 'read_buffer': 0,
\ },
\ {
\ 'callback': 'RunSecondEcho',
\ 'output_stream': 'stdout',
\ 'read_buffer': 0,
\ },
\ ],
\})
After:
Restore
unlet! g:ale_run_synchronously_callbacks
unlet! g:first_echo_called
unlet! g:second_echo_called
unlet! g:final_callback_called
unlet! g:linter_output
let g:ale_buffer_info = {}
call ale#linter#Reset()
delfunction CollectResults
delfunction RunFirstEcho
delfunction RunSecondEcho
Given foobar (Some imaginary filetype):
anything
Execute(Check the results of running the chain):
AssertEqual 'foobar', &filetype
call ale#Queue(0)
call ale#test#FlushJobs()
Assert g:first_echo_called, 'The first chain item was not called'
Assert g:second_echo_called, 'The second chain item was not called'
Assert g:final_callback_called, 'The final callback was not called'
AssertEqual ['bar'], g:linter_output

View File

@@ -0,0 +1,134 @@
Before:
Save g:ale_enabled
Save g:ale_run_synchronously
Save g:ale_set_lists_synchronously
Save g:ale_buffer_info
let g:ale_enabled = 1
let g:ale_buffer_info = {}
let g:ale_run_synchronously = 1
let g:ale_set_lists_synchronously = 1
function! TestCallback(buffer, output)
" Windows adds extra spaces to the text from echo.
return [{
\ 'lnum': 2,
\ 'col': 3,
\ 'text': 'testlinter1',
\}]
endfunction
function! TestCallback2(buffer, output)
" Windows adds extra spaces to the text from echo.
return [{
\ 'lnum': 1,
\ 'col': 3,
\ 'text': 'testlinter2',
\}]
endfunction
function! TestCallback3(buffer, output)
" Windows adds extra spaces to the text from echo.
return [{
\ 'lnum': 3,
\ 'col': 3,
\ 'text': 'testlinter3',
\}]
endfunction
" These two linters computer their lint_file values after running commands.
call ale#linter#Define('foobar', {
\ 'name': 'testlinter1',
\ 'callback': 'TestCallback',
\ 'executable': has('win32') ? 'cmd' : 'echo',
\ 'command': has('win32') ? 'echo foo bar' : '/bin/sh -c ''echo foo bar''',
\ 'lint_file': {b -> ale#command#Run(b, 'echo', {-> 1})},
\})
call ale#linter#Define('foobar', {
\ 'name': 'testlinter2',
\ 'callback': 'TestCallback2',
\ 'executable': has('win32') ? 'cmd' : 'echo',
\ 'command': has('win32') ? 'echo foo bar' : '/bin/sh -c ''echo foo bar''',
\ 'lint_file': {b -> ale#command#Run(b, 'echo', {-> ale#command#Run(b, 'echo', {-> 1})})},
\})
" This one directly computes the result.
call ale#linter#Define('foobar', {
\ 'name': 'testlinter3',
\ 'callback': 'TestCallback3',
\ 'executable': has('win32') ? 'cmd' : 'echo',
\ 'command': has('win32') ? 'echo foo bar' : '/bin/sh -c ''echo foo bar''',
\ 'lint_file': {b -> 1},
\})
let g:filename = tempname()
call writefile([], g:filename)
call ale#test#SetFilename(g:filename)
After:
delfunction TestCallback
call ale#engine#Cleanup(bufnr(''))
Restore
call ale#linter#Reset()
" Items and markers, etc.
call setloclist(0, [])
call clearmatches()
call ale#sign#Clear()
if filereadable(g:filename)
call delete(g:filename)
endif
unlet g:filename
Given foobar(A file with some lines):
foo
bar
baz
Execute(lint_file results where the result is eventually computed should be run):
call ale#Queue(0, 'lint_file')
call ale#test#FlushJobs()
AssertEqual
\ [
\ {
\ 'bufnr': bufnr('%'),
\ 'lnum': 1,
\ 'vcol': 0,
\ 'col': 3,
\ 'text': 'testlinter2',
\ 'type': 'E',
\ 'nr': -1,
\ 'pattern': '',
\ 'valid': 1,
\ },
\ {
\ 'bufnr': bufnr('%'),
\ 'lnum': 2,
\ 'vcol': 0,
\ 'col': 3,
\ 'text': 'testlinter1',
\ 'type': 'E',
\ 'nr': -1,
\ 'pattern': '',
\ 'valid': 1,
\ },
\ {
\ 'bufnr': bufnr('%'),
\ 'lnum': 3,
\ 'vcol': 0,
\ 'col': 3,
\ 'text': 'testlinter3',
\ 'type': 'E',
\ 'nr': -1,
\ 'pattern': '',
\ 'valid': 1,
\ },
\ ],
\ ale#test#GetLoclistWithoutModule()
Execute(Linters where lint_file eventually evaluates to 1 shouldn't be run if we don't want to run them):
call ale#Queue(0, '')
call ale#test#FlushJobs()
AssertEqual [], ale#test#GetLoclistWithoutModule()

View File

@@ -30,7 +30,7 @@ Before:
\ 'nr': -1,
\ 'type': 'E',
\ 'code': 'semi',
\ 'text': 'Missing semicolon.',
\ 'text': "Missing semicolon.\r",
\ 'detail': "Every statement should end with a semicolon\nsecond line",
\ },
\ {

View File

@@ -12,7 +12,7 @@ Before:
call ale#linter#Define('foobar', {
\ 'name': 'lint_file_linter',
\ 'callback': 'LintFileCallback',
\ 'executable': 'echo',
\ 'executable': has('win32') ? 'cmd' : 'echo',
\ 'command': {b -> ale#command#Run(b, 'echo', {-> ale#command#Run(b, 'echo', {-> 'foo'})})},
\ 'read_buffer': 0,
\})
@@ -28,7 +28,7 @@ After:
Given foobar (Some imaginary filetype):
Execute(It should be possible to compute an executable to check based on the result of commands):
AssertLinter 'echo', 'foo'
AssertLinter has('win32') ? 'cmd' : 'echo', 'foo'
ALELint
call ale#test#FlushJobs()
@@ -40,7 +40,7 @@ Execute(It should be possible to compute an executable to check based on the res
Execute(It handle the deferred command failing):
let g:ale_emulate_job_failure = 1
AssertLinter 'echo', 0
AssertLinter has('win32') ? 'cmd' : 'echo', 0
ALELint
call ale#test#FlushJobs()

View File

@@ -1,108 +0,0 @@
Before:
function! CollectResults(buffer, output)
return []
endfunction
function! FirstChainFunction(buffer)
return 'first'
endfunction
function! SecondChainFunction(buffer, output)
" We'll skip this command
return ''
endfunction
function! ThirdChainFunction(buffer, output)
return 'third'
endfunction
function! FourthChainFunction(buffer, output)
return 'fourth'
endfunction
let g:linter = {
\ 'name': 'testlinter',
\ 'callback': 'CollectResults',
\ 'executable': 'echo',
\ 'command_chain': [
\ {'callback': 'FirstChainFunction'},
\ {'callback': 'SecondChainFunction'},
\ {'callback': 'ThirdChainFunction'},
\ {'callback': 'FourthChainFunction'},
\ ],
\ 'read_buffer': 1,
\}
function! ProcessIndex(chain_index)
let [l:command, l:options] = ale#engine#ProcessChain(347, '', g:linter, a:chain_index, [])
let l:options.command = l:command
return l:options
endfunction
After:
delfunction CollectResults
delfunction FirstChainFunction
delfunction SecondChainFunction
delfunction ThirdChainFunction
delfunction ProcessIndex
unlet! g:linter
unlet! g:result
Execute(Engine invocation should return the command for the first item correctly):
let g:result = ProcessIndex(0)
AssertEqual 'first', g:result.command
AssertEqual 1, g:result.next_chain_index
Execute(Engine invocation should return the command for the second item correctly):
let g:result = ProcessIndex(1)
AssertEqual 'third', g:result.command
AssertEqual 3, g:result.next_chain_index
Execute(Engine invocation should return the command for the fourth item correctly):
let g:result = ProcessIndex(3)
AssertEqual 'fourth', g:result.command
AssertEqual 4, g:result.next_chain_index
Execute(Engine invocation should allow read_buffer to be enabled for a command in the middle of a chain):
let g:linter.command_chain[2].read_buffer = 1
let g:result = ProcessIndex(2)
AssertEqual g:result.command, 'third'
AssertEqual g:result.read_buffer, 1
Execute(Engine invocation should allow read_buffer to be disabled for the end of a chain):
let g:linter.command_chain[3].read_buffer = 0
let g:result = ProcessIndex(3)
AssertEqual g:result.command, 'fourth'
AssertEqual g:result.read_buffer, 0
Execute(Engine invocation should not use read_buffer from earlier items in a chain):
let g:linter.command_chain[1].read_buffer = 1
let g:result = ProcessIndex(1)
AssertEqual g:result.command, 'third'
AssertEqual g:result.read_buffer, 0
Execute(Engine invocation should allow the output_stream setting to be changed in the middle of a chain):
let g:linter.command_chain[2].output_stream = 'both'
let g:result = ProcessIndex(2)
AssertEqual g:result.command, 'third'
AssertEqual g:result.output_stream, 'both'
Execute(Engine invocation should not use output_stream from earlier items in a chain):
let g:linter.command_chain[1].output_stream = 'both'
let g:result = ProcessIndex(1)
AssertEqual g:result.command, 'third'
AssertEqual g:result.output_stream, 'stdout'

View File

@@ -0,0 +1,62 @@
Before:
Save g:ale_filename_mappings
Save b:ale_filename_mappings
let g:ale_filename_mappings = {}
unlet! b:ale_filename_mappings
After:
Restore
Execute(ale#GetFilenameMappings should return the correct mappings for given linters/fixers):
let g:ale_filename_mappings = {'a': [['foo', 'bar']], 'b': [['baz', 'foo']]}
AssertEqual [['foo', 'bar']], ale#GetFilenameMappings(bufnr(''), 'a')
AssertEqual [['baz', 'foo']], ale#GetFilenameMappings(bufnr(''), 'b')
AssertEqual [], ale#GetFilenameMappings(bufnr(''), 'c')
let b:ale_filename_mappings = {'b': [['abc', 'xyz']]}
AssertEqual [], ale#GetFilenameMappings(bufnr(''), 'a')
AssertEqual [['abc', 'xyz']], ale#GetFilenameMappings(bufnr(''), 'b')
AssertEqual [], ale#GetFilenameMappings(bufnr(''), 'c')
Execute(ale#GetFilenameMappings should return Lists set for use with all tools):
let g:ale_filename_mappings = [['foo', 'bar']]
AssertEqual [['foo', 'bar']], ale#GetFilenameMappings(bufnr(''), 'a')
AssertEqual [['foo', 'bar']], ale#GetFilenameMappings(bufnr(''), '')
AssertEqual [['foo', 'bar']], ale#GetFilenameMappings(bufnr(''), v:null)
let b:ale_filename_mappings = [['abc', 'xyz']]
AssertEqual [['abc', 'xyz']], ale#GetFilenameMappings(bufnr(''), 'a')
AssertEqual [['abc', 'xyz']], ale#GetFilenameMappings(bufnr(''), '')
AssertEqual [['abc', 'xyz']], ale#GetFilenameMappings(bufnr(''), v:null)
Execute(ale#GetFilenameMappings should let you use * as a fallback):
let g:ale_filename_mappings = {'a': [['foo', 'bar']], '*': [['abc', 'xyz']]}
AssertEqual [['foo', 'bar']], ale#GetFilenameMappings(bufnr(''), 'a')
AssertEqual [['abc', 'xyz']], ale#GetFilenameMappings(bufnr(''), 'b')
AssertEqual [['abc', 'xyz']], ale#GetFilenameMappings(bufnr(''), '')
AssertEqual [['abc', 'xyz']], ale#GetFilenameMappings(bufnr(''), v:null)
Execute(ale#filename_mapping#Invert should invert filename mappings):
AssertEqual
\ [['b', 'a'], ['y', 'x']],
\ ale#filename_mapping#Invert([['a', 'b'], ['x', 'y']])
\
Execute(ale#filename_mapping#Map return the filename as-is if there are no mappings):
AssertEqual
\ '/foo//bar',
\ ale#filename_mapping#Map('/foo//bar', [['/bar', '/data/']])
Execute(ale#filename_mapping#Map should map filenames):
AssertEqual
\ '/data/bar',
\ ale#filename_mapping#Map('/foo//bar', [
\ ['/data/', '/baz/'],
\ ['/foo/', '/data/'],
\ ['/foo/', '/xyz/'],
\ ])

View File

@@ -39,7 +39,7 @@ Execute(The defaults for the python filetype should be correct):
AssertEqual [], GetLinterNames('python')
Execute(The defaults for the rust filetype should be correct):
AssertEqual ['cargo'], GetLinterNames('rust')
AssertEqual ['cargo', 'rls'], GetLinterNames('rust')
let g:ale_linters_explicit = 1

View File

@@ -63,6 +63,8 @@ Before:
let g:preview_called = 1
let g:item_list = a:item_list
let g:options = a:options
call ale#preview#SetLastSelection(a:item_list, a:options)
endfunction
After:
@@ -110,7 +112,16 @@ Given typescript(Some typescript file):
bazxyzxyzxyz
Execute(Results should be shown for tsserver responses):
call ale#references#SetMap({3: {}})
" We should remember these options when we repeat the selection.
call ale#references#SetMap(
\ {
\ 3: {
\ 'ignorethis': 'x',
\ 'open_in': 'tab',
\ 'use_relative_paths': 1,
\ }
\ }
\)
call ale#references#HandleTSServerResponse(1, {
\ 'command': 'references',
\ 'request_seq': 3,
@@ -158,8 +169,7 @@ Execute(Results should be shown for tsserver responses):
AssertEqual {}, ale#references#GetMap()
" We should be able to repeat selections with ALERepeatSelection
let g:ale_item_list = []
let g:item_list = []
ALERepeatSelection
AssertEqual
@@ -170,6 +180,12 @@ Execute(Results should be shown for tsserver responses):
\ ],
\ g:item_list
AssertEqual {}, ale#references#GetMap()
AssertEqual
\ {
\ 'open_in': 'tab',
\ 'use_relative_paths': 1,
\ },
\ g:options
Execute(The preview window should not be opened for empty tsserver responses):
call ale#references#SetMap({3: {}})

View File

@@ -25,12 +25,12 @@ After:
Execute(FormatCommand should do nothing to basic command strings):
AssertEqual
\ ['', 'awesome-linter do something', 0],
\ ale#command#FormatCommand(bufnr('%'), '', 'awesome-linter do something', 0, v:null)
\ ale#command#FormatCommand(bufnr('%'), '', 'awesome-linter do something', 0, v:null, [])
Execute(FormatCommand should handle %%, and ignore other percents):
AssertEqual
\ ['', '% %%d %%f %x %', 0],
\ ale#command#FormatCommand(bufnr('%'), '', '%% %%%d %%%f %x %', 0, v:null)
\ ale#command#FormatCommand(bufnr('%'), '', '%% %%%d %%%f %x %', 0, v:null, [])
Execute(FormatCommand should convert %s to the current filename):
AssertEqual
@@ -39,10 +39,10 @@ Execute(FormatCommand should convert %s to the current filename):
\ 'foo ' . ale#Escape(expand('%:p')) . ' bar ' . ale#Escape(expand('%:p')),
\ 0,
\ ],
\ ale#command#FormatCommand(bufnr('%'), '', 'foo %s bar %s', 0, v:null)
\ ale#command#FormatCommand(bufnr('%'), '', 'foo %s bar %s', 0, v:null, [])
Execute(FormatCommand should convert %t to a new temporary filename):
let g:result = ale#command#FormatCommand(bufnr('%'), '', 'foo %t bar %t', 0, v:null)
let g:result = ale#command#FormatCommand(bufnr('%'), '', 'foo %t bar %t', 0, v:null, [])
call CheckTempFile(g:result[0])
@@ -56,21 +56,21 @@ Execute(FormatCommand should convert %t to a new temporary filename):
AssertEqual g:match[1], g:match[2]
Execute(FormatCommand should not convert %t to a new temporary filename when the input is given as v:false):
let g:result = ale#command#FormatCommand(bufnr('%'), '', 'foo %t bar %t', 0, v:false)
let g:result = ale#command#FormatCommand(bufnr('%'), '', 'foo %t bar %t', 0, v:false, [])
AssertEqual ['', 'foo %t bar %t', 0], g:result
Execute(FormatCommand should signal that files are created when temporary files are needed):
AssertEqual
\ 1,
\ ale#command#FormatCommand(bufnr('%'), '', 'foo %t', 0, v:null)[2]
\ ale#command#FormatCommand(bufnr('%'), '', 'foo %t', 0, v:null, [])[2]
AssertEqual
\ 0,
\ ale#command#FormatCommand(bufnr('%'), '', 'foo %s', 0, v:null)[2]
\ ale#command#FormatCommand(bufnr('%'), '', 'foo %s', 0, v:null, [])[2]
Execute(FormatCommand should let you combine %s and %t):
let g:result = ale#command#FormatCommand(bufnr('%'), '', 'foo %t bar %s', 0, v:null)
let g:result = ale#command#FormatCommand(bufnr('%'), '', 'foo %t bar %s', 0, v:null, [])
call CheckTempFile(g:result[0])
@@ -87,30 +87,30 @@ Execute(FormatCommand should replace %e with the escaped executable):
if has('win32')
AssertEqual
\ ['', 'foo foo', 0],
\ ale#command#FormatCommand(bufnr('%'), 'foo', '%e %e', 0, v:null)
\ ale#command#FormatCommand(bufnr('%'), 'foo', '%e %e', 0, v:null, [])
AssertEqual
\ ['', '"foo bar"', 0],
\ ale#command#FormatCommand(bufnr('%'), 'foo bar', '%e', 0, v:null)
\ ale#command#FormatCommand(bufnr('%'), 'foo bar', '%e', 0, v:null, [])
AssertEqual
\ ['', '%e %e', 0],
\ ale#command#FormatCommand(bufnr('%'), '', '%e %e', 0, v:null)
\ ale#command#FormatCommand(bufnr('%'), '', '%e %e', 0, v:null, [])
else
AssertEqual
\ ['', '''foo'' ''foo''', 0],
\ ale#command#FormatCommand(bufnr('%'), 'foo', '%e %e', 0, v:null)
\ ale#command#FormatCommand(bufnr('%'), 'foo', '%e %e', 0, v:null, [])
AssertEqual
\ ['', '''foo bar''', 0],
\ ale#command#FormatCommand(bufnr('%'), 'foo bar', '%e', 0, v:null)
\ ale#command#FormatCommand(bufnr('%'), 'foo bar', '%e', 0, v:null, [])
AssertEqual
\ ['', '%e %e', 0],
\ ale#command#FormatCommand(bufnr('%'), '', '%e %e', 0, v:null)
\ ale#command#FormatCommand(bufnr('%'), '', '%e %e', 0, v:null, [])
endif
Execute(EscapeCommandPart should escape all percent signs):
AssertEqual '%%s %%t %%%% %%s %%t %%%%', ale#engine#EscapeCommandPart('%s %t %% %s %t %%')
Execute(EscapeCommandPart should pipe in temporary files appropriately):
let g:result = ale#command#FormatCommand(bufnr('%'), '', 'foo bar', 1, v:null)
let g:result = ale#command#FormatCommand(bufnr('%'), '', 'foo bar', 1, v:null, [])
call CheckTempFile(g:result[0])
@@ -118,10 +118,57 @@ Execute(EscapeCommandPart should pipe in temporary files appropriately):
Assert !empty(g:match), 'No match found! Result was: ' . g:result[1]
AssertEqual ale#Escape(g:result[0]), g:match[1]
let g:result = ale#command#FormatCommand(bufnr('%'), '', 'foo bar %t', 1, v:null)
let g:result = ale#command#FormatCommand(bufnr('%'), '', 'foo bar %t', 1, v:null, [])
call CheckTempFile(g:result[0])
let g:match = matchlist(g:result[1], '\v^foo bar (.*)$')
Assert !empty(g:match), 'No match found! Result was: ' . g:result[1]
AssertEqual ale#Escape(g:result[0]), g:match[1]
Execute(FormatCommand should apply filename modifiers to the current file):
AssertEqual
\ ale#Escape(expand('%:p:h'))
\ . ' ' . ale#Escape('dummy.txt')
\ . ' ' . ale#Escape(expand('%:p:h:t'))
\ . ' ' . ale#Escape('txt')
\ . ' ' . ale#Escape(expand('%:p:r')),
\ ale#command#FormatCommand(bufnr(''), '', '%s:h %s:t %s:h:t %s:e %s:r', 0, v:null, [])[1]
Execute(FormatCommand should apply filename modifiers to the temporary file):
let g:result = ale#command#FormatCommand(bufnr(''), '', '%t:h %t:t %t:h:t %t:e %t:r', 0, v:null, [])
AssertEqual
\ ale#Escape(fnamemodify(g:result[0], ':h'))
\ . ' ' . ale#Escape('dummy.txt')
\ . ' ' . ale#Escape(fnamemodify(g:result[0], ':h:t'))
\ . ' ' . ale#Escape('txt')
\ . ' ' . ale#Escape(fnamemodify(g:result[0], ':r')),
\ g:result[1]
Execute(FormatCommand should apply filename mappings the current file):
let g:result = ale#command#FormatCommand(bufnr('%'), '', '%s', 0, v:null, [
\ [expand('%:p:h'), '/foo/bar'],
\])
Assert g:result[1] =~# '/foo/bar'
Execute(FormatCommand should apply filename mappings to temporary files):
let g:result = ale#command#FormatCommand(bufnr('%'), '', '%t', 0, v:null, [
\ [fnamemodify(tempname(), ':h:h'), '/foo/bar']
\])
Assert g:result[1] =~# '/foo/bar'
Execute(FormatCommand should apply filename modifiers to mapped filenames):
let g:result = ale#command#FormatCommand(bufnr('%'), '', '%s:h', 0, v:null, [
\ [expand('%:p:h'), '/foo/bar'],
\])
AssertEqual ale#Escape('/foo/bar'), g:result[1]
let g:result = ale#command#FormatCommand(bufnr('%'), '', '%t:h:h:h', 0, v:null, [
\ [fnamemodify(tempname(), ':h:h'), '/foo/bar']
\])
AssertEqual ale#Escape('/foo/bar'), g:result[1]

View File

@@ -514,7 +514,7 @@ Execute(LSP tab type definition requests should be sent):
let b:ale_linters = ['pyls']
call setpos('.', [bufnr(''), 1, 5, 0])
ALEGoToTypeDefinitionInTab
ALEGoToTypeDefinition -tab
" We shouldn't register the callback yet.
AssertEqual '''''', string(g:Callback)

View File

@@ -39,13 +39,13 @@ Execute (PreProcess should throw when then callback is not a function):
\})
AssertEqual '`callback` must be defined with a callback to accept output', g:vader_exception
Execute (PreProcess should throw when there is no executable or executable_callback):
Execute (PreProcess should throw when there is no executable):
AssertThrows call ale#linter#PreProcess('testft', {
\ 'name': 'foo',
\ 'callback': 'SomeFunction',
\ 'command': 'echo',
\})
AssertEqual 'Either `executable` or `executable_callback` must be defined', g:vader_exception
AssertEqual '`executable` must be defined', g:vader_exception
Execute (PreProcess should throw when executable is not a string):
AssertThrows call ale#linter#PreProcess('testft', {
@@ -56,15 +56,6 @@ Execute (PreProcess should throw when executable is not a string):
\})
AssertEqual '`executable` must be a String or Function if defined', g:vader_exception
Execute (PreProcess should throw when executable_callback is not a callback):
AssertThrows call ale#linter#PreProcess('testft', {
\ 'name': 'foo',
\ 'callback': 'SomeFunction',
\ 'executable_callback': 123,
\ 'command': 'echo',
\})
AssertEqual '`executable_callback` must be a callback if defined', g:vader_exception
Execute (PreProcess should allow executable to be a callback):
call ale#linter#PreProcess('testft', {
\ 'name': 'foo',
@@ -79,7 +70,7 @@ Execute (PreProcess should throw when there is no command):
\ 'callback': 'SomeFunction',
\ 'executable': 'echo',
\})
AssertEqual 'Either `command`, `executable_callback`, `command_chain` must be defined', g:vader_exception
AssertEqual '`command` must be defined', g:vader_exception
Execute (PreProcess should throw when command is not a string):
AssertThrows call ale#linter#PreProcess('testft', {
@@ -98,15 +89,6 @@ Execute (PreProcess should allow command to be a callback):
\ 'command': function('type'),
\})
Execute (PreProcess should throw when command_callback is not a callback):
AssertThrows call ale#linter#PreProcess('testft', {
\ 'name': 'foo',
\ 'callback': 'SomeFunction',
\ 'executable': 'echo',
\ 'command_callback': 123,
\})
AssertEqual '`command_callback` must be a callback if defined', g:vader_exception
Execute (PreProcess should when the output stream isn't a valid string):
AssertThrows call ale#linter#PreProcess('testft', {
\ 'name': 'foo',
@@ -152,117 +134,12 @@ Execute (PreProcess should accept a 'both' output_stream):
\ 'output_stream': 'both',
\})
Execute(PreProcess should complain if the command_chain is not a List):
let g:linter = {
\ 'name': 'x',
\ 'callback': 'x',
\ 'executable': 'x',
\ 'command_chain': 'x',
\}
AssertThrows call ale#linter#PreProcess('testft', g:linter)
AssertEqual '`command_chain` must be a List', g:vader_exception
Execute(PreProcess should complain if the command_chain is empty):
let g:linter = {
\ 'name': 'x',
\ 'callback': 'x',
\ 'executable': 'x',
\ 'command_chain': [],
\}
AssertThrows call ale#linter#PreProcess('testft', g:linter)
AssertEqual '`command_chain` must contain at least one item', g:vader_exception
Execute(PreProcess should complain if the command_chain has no callback):
let g:linter = {
\ 'name': 'x',
\ 'callback': 'x',
\ 'executable': 'x',
\ 'command_chain': [{}],
\}
AssertThrows call ale#linter#PreProcess('testft', g:linter)
AssertEqual 'The `command_chain` item 0 must define a `callback` function', g:vader_exception
Execute(PreProcess should complain if the command_chain callback is not a function):
let g:linter = {
\ 'name': 'x',
\ 'callback': 'x',
\ 'executable': 'x',
\ 'command_chain': [{'callback': 2}],
\}
AssertThrows call ale#linter#PreProcess('testft', g:linter)
AssertEqual 'The `command_chain` item 0 must define a `callback` function', g:vader_exception
Execute(PreProcess should accept a chain with one callback):
let g:linter = {
\ 'name': 'x',
\ 'callback': 'x',
\ 'executable': 'x',
\ 'command_chain': [{'callback': 'foo'}],
\}
call ale#linter#PreProcess('testft', g:linter)
Execute(PreProcess should complain about invalid output_stream values in the chain):
let g:linter = {
\ 'name': 'x',
\ 'callback': 'x',
\ 'executable': 'x',
\ 'command_chain': [{'callback': 'foo', 'output_stream': ''}],
\}
AssertThrows call ale#linter#PreProcess('testft', g:linter)
AssertEqual "The `command_chain` item 0 `output_stream` flag must be 'stdout', 'stderr', or 'both'", g:vader_exception
Execute(PreProcess should complain about valid output_stream values in the chain):
let g:linter = {
\ 'name': 'x',
\ 'callback': 'x',
\ 'executable': 'x',
\ 'command_chain': [{'callback': 'foo', 'output_stream': 'stdout'}],
\}
call ale#linter#PreProcess('testft', g:linter)
let g:linter.command_chain[0].output_stream = 'stderr'
call ale#linter#PreProcess('testft', g:linter)
let g:linter.command_chain[0].output_stream = 'both'
call ale#linter#PreProcess('testft', g:linter)
Execute(PreProcess should complain about invalid chain items at higher indices):
let g:linter = {
\ 'name': 'x',
\ 'callback': 'x',
\ 'executable': 'x',
\ 'command_chain': [{'callback': 'foo'}, {'callback': 123}],
\}
AssertThrows call ale#linter#PreProcess('testft', g:linter)
AssertEqual 'The `command_chain` item 1 must define a `callback` function', g:vader_exception
Execute(PreProcess should complain when conflicting command options are used):
let g:linter = {
\ 'name': 'x',
\ 'callback': 'x',
\ 'executable': 'x',
\ 'command': 'foo',
\ 'command_chain': [{'callback': 'foo'}],
\}
AssertThrows call ale#linter#PreProcess('testft', g:linter)
AssertEqual 'Only one of `command`, `command_callback`, or `command_chain` should be set', g:vader_exception
unlet g:linter.command
let g:linter.command_callback = 'foo'
AssertThrows call ale#linter#PreProcess('testft', g:linter)
AssertEqual 'Only one of `command`, `command_callback`, or `command_chain` should be set', g:vader_exception
let g:linter.command = 'foo'
unlet g:linter.command_chain
AssertThrows call ale#linter#PreProcess('testft', g:linter)
AssertEqual 'Only one of `command`, `command_callback`, or `command_chain` should be set', g:vader_exception
Execute(PreProcess should process the read_buffer option correctly):
let g:linter = {
\ 'name': 'x',
\ 'callback': 'x',
\ 'executable': 'x',
\ 'command_chain': [{'callback': 'foo'}, {'callback': 'bar'}],
\ 'command': 'x',
\ 'read_buffer': '0',
\}
@@ -277,25 +154,6 @@ Execute(PreProcess should process the read_buffer option correctly):
call ale#linter#PreProcess('testft', g:linter)
unlet g:linter.read_buffer
let g:linter.command_chain[0].read_buffer = '0'
AssertThrows call ale#linter#PreProcess('testft', g:linter)
AssertEqual 'The `command_chain` item 0 value for `read_buffer` must be `0` or `1`', g:vader_exception
let g:linter.command_chain[0].read_buffer = 0
call ale#linter#PreProcess('testft', g:linter)
let g:linter.command_chain[1].read_buffer = '0'
AssertThrows call ale#linter#PreProcess('testft', g:linter)
AssertEqual 'The `command_chain` item 1 value for `read_buffer` must be `0` or `1`', g:vader_exception
let g:linter.command_chain[1].read_buffer = 1
call ale#linter#PreProcess('testft', g:linter)
Execute(PreProcess should set a default value for read_buffer):
let g:linter = {
\ 'name': 'x',
@@ -316,7 +174,7 @@ Execute(PreProcess should process the lint_file option correctly):
\}
AssertThrows call ale#linter#PreProcess('testft', g:linter)
AssertEqual '`lint_file` must be `0` or `1`', g:vader_exception
AssertEqual '`lint_file` must be `0`, `1`, or a Function', g:vader_exception
let g:linter.lint_file = 0
@@ -327,14 +185,17 @@ Execute(PreProcess should process the lint_file option correctly):
let g:linter.lint_file = 1
AssertEqual 1, ale#linter#PreProcess('testft', g:linter).lint_file
" The default for read_buffer should change to 0 when lint_file is 1.
AssertEqual 0, ale#linter#PreProcess('testft', g:linter).read_buffer
" The default for read_buffer should still be 1
AssertEqual 1, ale#linter#PreProcess('testft', g:linter).read_buffer
let g:linter.read_buffer = 1
" We shouldn't be able to set both options to 1 at the same time.
AssertThrows call ale#linter#PreProcess('testft', g:linter)
AssertEqual 'Only one of `lint_file` or `read_buffer` can be `1`', g:vader_exception
" We should be able to set `read_buffer` and `lint_file` at the same time.
AssertEqual 1, ale#linter#PreProcess('testft', g:linter).read_buffer
let g:linter.lint_file = function('type')
Assert type(ale#linter#PreProcess('testft', g:linter).lint_file) is v:t_func
Execute(PreProcess should set a default value for lint_file):
let g:linter = {
@@ -394,151 +255,96 @@ Execute(PreProcess should accept tsserver LSP configuration):
\ 'executable': 'x',
\ 'command': 'x',
\ 'lsp': 'tsserver',
\ 'language_callback': 'x',
\ 'project_root_callback': 'x',
\ 'language': 'x',
\ 'project_root': 'x',
\}
AssertEqual 'tsserver', ale#linter#PreProcess('testft', g:linter).lsp
call remove(g:linter, 'executable')
let g:linter.executable_callback = 'X'
call ale#linter#PreProcess('testft', g:linter)
call remove(g:linter, 'command')
let g:linter.command_callback = 'X'
call ale#linter#PreProcess('testft', g:linter)
Execute(PreProcess should accept stdio LSP configuration):
let g:linter = {
\ 'name': 'x',
\ 'executable': 'x',
\ 'command': 'x',
\ 'lsp': 'stdio',
\ 'language_callback': 'x',
\ 'project_root_callback': 'x',
\ 'language': 'x',
\ 'project_root': 'x',
\}
AssertEqual 'stdio', ale#linter#PreProcess('testft', g:linter).lsp
call remove(g:linter, 'executable')
let g:linter.executable_callback = 'X'
call ale#linter#PreProcess('testft', g:linter)
call remove(g:linter, 'command')
let g:linter.command_callback = 'X'
call ale#linter#PreProcess('testft', g:linter)
Execute(PreProcess should accept LSP server configurations):
let g:linter = {
\ 'name': 'x',
\ 'lsp': 'socket',
\ 'address_callback': 'X',
\ 'language_callback': 'x',
\ 'project_root_callback': 'x',
\ 'address': 'X',
\ 'language': 'foobar',
\ 'project_root': 'x',
\}
AssertEqual 'socket', ale#linter#PreProcess('testft', g:linter).lsp
Execute(PreProcess should accept let you specify the language as just a string):
Execute(PreProcess should accept let you specify the `language` as a Function):
let g:linter = {
\ 'name': 'x',
\ 'lsp': 'socket',
\ 'address_callback': 'X',
\ 'language': 'foobar',
\ 'project_root_callback': 'x',
\ 'address': 'X',
\ 'language': {-> 'foobar'},
\ 'project_root': 'x',
\}
AssertEqual 'foobar', ale#linter#PreProcess('testft', g:linter).language_callback(0)
Execute(PreProcess should complain about using language and language_callback together):
let g:linter = {
\ 'name': 'x',
\ 'lsp': 'socket',
\ 'address_callback': 'X',
\ 'language': 'x',
\ 'language_callback': 'x',
\ 'project_root_callback': 'x',
\}
AssertThrows call ale#linter#PreProcess('testft', g:linter)
AssertEqual 'Only one of `language` or `language_callback` should be set', g:vader_exception
AssertEqual 'foobar', ale#linter#PreProcess('testft', g:linter).language(bufnr(''))
Execute(PreProcess should complain about invalid language values):
let g:linter = {
\ 'name': 'x',
\ 'lsp': 'socket',
\ 'address_callback': 'X',
\ 'address': 'X',
\ 'language': 0,
\ 'project_root_callback': 'x',
\ 'project_root': 'x',
\}
AssertThrows call ale#linter#PreProcess('testft', g:linter)
AssertEqual '`language` must be a String or Funcref', g:vader_exception
AssertEqual '`language` must be a String or Funcref if defined', g:vader_exception
Execute(PreProcess should use the filetype as the language string by default):
let g:linter = {
\ 'name': 'x',
\ 'lsp': 'socket',
\ 'address_callback': 'X',
\ 'project_root_callback': 'x',
\ 'address': 'X',
\ 'project_root': 'x',
\}
AssertEqual 'testft', ale#linter#PreProcess('testft', g:linter).language_callback(0)
AssertEqual 'testft', ale#linter#PreProcess('testft', g:linter).language
Execute(PreProcess should allow language to be set to a callback):
let g:linter = {
\ 'name': 'x',
\ 'lsp': 'socket',
\ 'address_callback': 'X',
\ 'language': {-> 'foo'},
\ 'project_root_callback': 'x',
\}
AssertEqual 'foo', ale#linter#PreProcess('testft', g:linter).language_callback(0)
Execute(PreProcess should require an address_callback for LSP socket configurations):
Execute(PreProcess should require an `address` for LSP socket configurations):
let g:linter = {
\ 'name': 'x',
\ 'lsp': 'socket',
\}
AssertThrows call ale#linter#PreProcess('testft', g:linter)
AssertEqual '`address` or `address_callback` must be defined for getting the LSP address', g:vader_exception
AssertEqual '`address` must be defined for getting the LSP address', g:vader_exception
Execute(PreProcess should complain about address_callback for non-LSP linters):
Execute(PreProcess should complain about `address` for non-LSP linters):
let g:linter = {
\ 'name': 'x',
\ 'callback': 'SomeFunction',
\ 'executable': 'echo',
\ 'command': 'echo',
\ 'address_callback': 'X',
\ 'address': 'X',
\}
AssertThrows call ale#linter#PreProcess('testft', g:linter)
AssertEqual '`address` or `address_callback` cannot be used when lsp != ''socket''', g:vader_exception
AssertEqual '`address` cannot be used when lsp != ''socket''', g:vader_exception
Execute(PreProcess accept valid address_callback values):
let g:linter = ale#linter#PreProcess('testft', {
\ 'name': 'x',
\ 'lsp': 'socket',
\ 'address_callback': {-> 'foo:123'},
\ 'language': 'x',
\ 'project_root_callback': 'x',
\})
AssertEqual 'foo:123', ale#linter#GetAddress(0, g:linter)
Execute(PreProcess accept address as a String):
Execute(PreProcess accept `address` as a String):
let g:linter = ale#linter#PreProcess('testft', {
\ 'name': 'x',
\ 'lsp': 'socket',
\ 'address': 'foo:123',
\ 'language': 'x',
\ 'project_root_callback': 'x',
\ 'project_root': 'x',
\})
AssertEqual 'foo:123', ale#linter#GetAddress(0, g:linter)
@@ -549,7 +355,7 @@ Execute(PreProcess accept address as a Function):
\ 'lsp': 'socket',
\ 'address': {-> 'foo:123'},
\ 'language': 'x',
\ 'project_root_callback': 'x',
\ 'project_root': 'x',
\})
AssertEqual 'foo:123', ale#linter#GetAddress(0, g:linter)
@@ -560,11 +366,11 @@ Execute(PreProcess should complain about invalid address values):
\ 'lsp': 'socket',
\ 'address': 0,
\ 'language': 'x',
\ 'project_root_callback': 'x',
\ 'project_root': 'x',
\})
AssertEqual '`address` must be a String or Function if defined', g:vader_exception
Execute(PreProcess should accept allow the project root be set as a String):
Execute(PreProcess should allow the `project_root` to be set as a String):
let g:linter = ale#linter#PreProcess('testft', {
\ 'name': 'x',
\ 'lsp': 'socket',
@@ -575,7 +381,7 @@ Execute(PreProcess should accept allow the project root be set as a String):
AssertEqual '/foo/bar', ale#lsp_linter#FindProjectRoot(0, g:linter)
Execute(PreProcess should accept allow the project root be set as a Function):
Execute(PreProcess should `project_root` be set as a Function):
let g:linter = ale#linter#PreProcess('testft', {
\ 'name': 'x',
\ 'lsp': 'socket',
@@ -586,7 +392,7 @@ Execute(PreProcess should accept allow the project root be set as a Function):
AssertEqual '/foo/bar', ale#lsp_linter#FindProjectRoot(0, g:linter)
Execute(PreProcess should complain when the project_root valid is invalid):
Execute(PreProcess should complain when `project_root` is invalid):
AssertThrows call ale#linter#PreProcess('testft', {
\ 'name': 'x',
\ 'lsp': 'socket',
@@ -594,154 +400,74 @@ Execute(PreProcess should complain when the project_root valid is invalid):
\ 'language': 'x',
\ 'project_root': 0,
\})
AssertEqual '`project_root` must be a String or Function if defined', g:vader_exception
AssertEqual '`project_root` must be a String or Function', g:vader_exception
Execute(PreProcess should accept project_root_callback as a String):
call ale#linter#PreProcess('testft', {
\ 'name': 'x',
\ 'lsp': 'socket',
\ 'address': 'foo:123',
\ 'language': 'x',
\ 'project_root_callback': 'Foobar',
\})
Execute(PreProcess should accept project_root_callback as a Function):
let g:linter = ale#linter#PreProcess('testft', {
\ 'name': 'x',
\ 'lsp': 'socket',
\ 'address': 'foo:123',
\ 'language': 'x',
\ 'project_root_callback': {-> '/foo/bar'},
\})
AssertEqual '/foo/bar', ale#lsp_linter#FindProjectRoot(0, g:linter)
Execute(PreProcess should complain when the project_root_callback valid is invalid):
AssertThrows call ale#linter#PreProcess('testft', {
\ 'name': 'x',
\ 'lsp': 'socket',
\ 'address': 'foo:123',
\ 'language': 'x',
\ 'project_root_callback': 0,
\})
AssertEqual '`project_root_callback` must be a callback if defined', g:vader_exception
Execute(PreProcess should complain about using initialization_options and initialization_options_callback together):
let g:linter = {
\ 'name': 'x',
\ 'lsp': 'socket',
\ 'address_callback': 'X',
\ 'language': 'x',
\ 'project_root_callback': 'x',
\ 'initialization_options': 'x',
\ 'initialization_options_callback': 'x',
\}
AssertThrows call ale#linter#PreProcess('testft', g:linter)
AssertEqual 'Only one of `initialization_options` or `initialization_options_callback` should be set', g:vader_exception
Execute(PreProcess should throw when initialization_options_callback is not a callback):
Execute(PreProcess should throw when `initialization_options` is not a Dictionary or callback):
AssertThrows call ale#linter#PreProcess('testft', {
\ 'name': 'foo',
\ 'lsp': 'socket',
\ 'address_callback': 'X',
\ 'address': 'X',
\ 'language': 'x',
\ 'project_root_callback': 'x',
\ 'initialization_options_callback': {},
\})
AssertEqual '`initialization_options_callback` must be a callback if defined', g:vader_exception
Execute(PreProcess should throw when initialization_options is not a Dictionary or callback):
AssertThrows call ale#linter#PreProcess('testft', {
\ 'name': 'foo',
\ 'lsp': 'socket',
\ 'address_callback': 'X',
\ 'language': 'x',
\ 'project_root_callback': 'x',
\ 'project_root': 'x',
\ 'initialization_options': 0,
\})
AssertEqual '`initialization_options` must be a String or Function if defined', g:vader_exception
AssertEqual '`initialization_options` must be a Dictionary or Function if defined', g:vader_exception
Execute(PreProcess should accept initialization_options as a Dictionary):
Execute(PreProcess should accept `initialization_options` as a Dictionary):
let g:linter = ale#linter#PreProcess('testft', {
\ 'name': 'foo',
\ 'lsp': 'socket',
\ 'address_callback': 'X',
\ 'address': 'X',
\ 'language': 'x',
\ 'project_root_callback': 'x',
\ 'project_root': 'x',
\ 'initialization_options': {'foo': v:true},
\})
AssertEqual {'foo': v:true}, ale#lsp_linter#GetOptions(0, g:linter)
Execute(PreProcess should accept initialization_options as a Funcref):
Execute(PreProcess should accept `initialization_options` as a Function):
let g:linter = ale#linter#PreProcess('testft', {
\ 'name': 'foo',
\ 'lsp': 'socket',
\ 'address_callback': 'X',
\ 'address': 'X',
\ 'language': 'x',
\ 'project_root_callback': 'x',
\ 'project_root': 'x',
\ 'initialization_options': {-> {'foo': v:true}},
\})
AssertEqual {'foo': v:true}, ale#lsp_linter#GetOptions(0, g:linter)
Execute(PreProcess should complain about using lsp_config and lsp_config_callback together):
Execute(PreProcess should accept `lsp_config` as a Dictionary):
let g:linter = {
\ 'name': 'x',
\ 'lsp': 'socket',
\ 'address_callback': 'X',
\ 'address': 'X',
\ 'language': 'x',
\ 'project_root_callback': 'x',
\ 'lsp_config': 'x',
\ 'lsp_config_callback': 'x',
\}
AssertThrows call ale#linter#PreProcess('testft', g:linter)
AssertEqual 'Only one of `lsp_config` or `lsp_config_callback` should be set', g:vader_exception
Execute(PreProcess should throw when lsp_config_callback is not a callback):
AssertThrows call ale#linter#PreProcess('testft', {
\ 'name': 'foo',
\ 'lsp': 'socket',
\ 'address_callback': 'X',
\ 'language': 'x',
\ 'project_root_callback': 'x',
\ 'lsp_config_callback': {},
\})
AssertEqual '`lsp_config_callback` must be a callback if defined', g:vader_exception
Execute(PreProcess should accept LSP configuration options via lsp_config):
let g:linter = {
\ 'name': 'x',
\ 'lsp': 'socket',
\ 'address_callback': 'X',
\ 'language_callback': 'x',
\ 'project_root_callback': 'x',
\ 'project_root': 'x',
\ 'lsp_config': {'foo': 'bar'},
\}
AssertEqual {'foo': 'bar'}, ale#lsp_linter#GetConfig(0, g:linter)
Execute(PreProcess should accept LSP configuration options via lsp_config as a function):
Execute(PreProcess should accept `lsp_config` as a Function):
let g:linter = {
\ 'name': 'x',
\ 'lsp': 'socket',
\ 'address_callback': 'X',
\ 'language_callback': 'x',
\ 'project_root_callback': 'x',
\ 'address': 'X',
\ 'language': 'x',
\ 'project_root': 'x',
\ 'lsp_config': {-> {'foo': 'bar'}},
\}
AssertEqual {'foo': 'bar'}, ale#lsp_linter#GetConfig(0, g:linter)
Execute(PreProcess should throw when lsp_config is not a Dictionary or Function):
Execute(PreProcess should throw when `lsp_config` is not a Dictionary or Function):
AssertThrows call ale#linter#PreProcess('testft', {
\ 'name': 'foo',
\ 'lsp': 'socket',
\ 'address_callback': 'X',
\ 'address': 'X',
\ 'language': 'x',
\ 'project_root_callback': 'x',
\ 'project_root': 'x',
\ 'lsp_config': 'x',
\})
AssertEqual '`lsp_config` must be a Dictionary or Function if defined', g:vader_exception

View File

@@ -36,7 +36,7 @@ After:
call setqflist([])
Execute(Formatting with codes should work for the loclist):
call AddItem({'text': 'nocode'})
call AddItem({'text': "nocode\r"})
call ale#list#SetLists(bufnr(''), g:loclist)
AssertEqual
@@ -79,7 +79,7 @@ Execute(Formatting with codes should work for the quickfix list):
let g:ale_set_loclist = 0
let g:ale_set_quickfix = 1
call AddItem({'text': 'nocode'})
call AddItem({'text': "nocode\r"})
call ale#list#SetLists(bufnr(''), g:loclist)
AssertEqual

View File

@@ -1,7 +1,50 @@
Before:
Save g:ale_filename_mappings
let g:ale_filename_mappings = {}
After:
unlet! b:temp_name
unlet! b:other_bufnr
Restore
Execute(FixLocList should map filenames):
" Paths converted back into temporary filenames shouldn't be included.
let g:ale_filename_mappings = {
\ 'linter2': [['/xxx/', '/data/']],
\ 'linter1': [
\ ['/bar/', '/data/special/'],
\ ['/foo/', '/data/'],
\ [
\ ale#path#Simplify(fnamemodify(ale#util#Tempname(), ':h:h')) . '/',
\ '/x-tmp/',
\ ],
\ ],
\}
AssertEqual
\ [
\ '/foo/file.txt',
\ v:null,
\ '/bar/file.txt',
\ ],
\ map(
\ ale#engine#FixLocList(
\ bufnr('%'),
\ 'linter1',
\ 0,
\ [
\ {'text': 'x', 'lnum': 1, 'filename': '/data/file.txt'},
\ {'text': 'x', 'lnum': 1, 'filename': '/x-tmp/file.txt'},
\ {'text': 'x', 'lnum': 1, 'filename': '/data/special/file.txt'},
\ ],
\ ),
\ 'get(v:val, ''filename'', v:null)',
\ )
Given foo (Some file with lines to count):
foo12345678
bar12345678
@@ -37,7 +80,7 @@ Execute(FixLocList should set all the default values correctly):
\ 'nr': -1,
\ 'linter_name': 'foobar',
\ },
\],
\ ],
\ ale#engine#FixLocList(
\ bufnr('%'),
\ 'foobar',
@@ -58,7 +101,7 @@ Execute(FixLocList should use the values we supply):
\ 'nr': 42,
\ 'linter_name': 'foobar',
\ },
\],
\ ],
\ ale#engine#FixLocList(
\ bufnr('%'),
\ 'foobar',
@@ -87,7 +130,7 @@ Execute(FixLocList should set items with lines beyond the end to the last line):
\ 'nr': -1,
\ 'linter_name': 'foobar',
\ },
\],
\ ],
\ ale#engine#FixLocList(
\ bufnr('%'),
\ 'foobar',
@@ -108,7 +151,7 @@ Execute(FixLocList should move line 0 to line 1):
\ 'nr': -1,
\ 'linter_name': 'foobar',
\ },
\],
\ ],
\ ale#engine#FixLocList(
\ bufnr('%'),
\ 'foobar',
@@ -130,7 +173,7 @@ Execute(FixLocList should convert line and column numbers correctly):
\ 'nr': -1,
\ 'linter_name': 'foobar',
\ },
\],
\ ],
\ ale#engine#FixLocList(
\ bufnr('%'),
\ 'foobar',
@@ -164,7 +207,7 @@ Execute(FixLocList should pass on end_col values):
\ 'nr': -1,
\ 'linter_name': 'foobar',
\ },
\],
\ ],
\ ale#engine#FixLocList(
\ bufnr('%'),
\ 'foobar',
@@ -202,7 +245,7 @@ Execute(FixLocList should pass on end_lnum values):
\ 'nr': -1,
\ 'linter_name': 'foobar',
\ },
\],
\ ],
\ ale#engine#FixLocList(
\ bufnr('%'),
\ 'foobar',
@@ -227,7 +270,7 @@ Execute(FixLocList should allow subtypes to be set):
\ 'nr': -1,
\ 'linter_name': 'foobar',
\ },
\],
\ ],
\ ale#engine#FixLocList(
\ bufnr('%'),
\ 'foobar',
@@ -289,7 +332,7 @@ Execute(FixLocList should accept filenames):
\ 'nr': -1,
\ 'linter_name': 'foobar',
\ },
\],
\ ],
\ ale#engine#FixLocList(
\ bufnr('%'),
\ 'foobar',
@@ -327,7 +370,7 @@ Execute(FixLocList should interpret temporary filenames as being the current buf
\ 'nr': -1,
\ 'linter_name': 'foobar',
\ },
\],
\ ],
\ ale#engine#FixLocList(
\ bufnr(''),
\ 'foobar',
@@ -352,7 +395,7 @@ Execute(The error code should be passed on):
\ 'linter_name': 'foobar',
\ 'code': 'some-code'
\ },
\],
\ ],
\ ale#engine#FixLocList(
\ bufnr('%'),
\ 'foobar',
@@ -385,7 +428,7 @@ Execute(FixLocList should mark problems as coming from other sources if requeste
\ 'linter_name': 'foobar',
\ 'from_other_source': 1,
\ },
\],
\ ],
\ ale#engine#FixLocList(
\ bufnr('%'),
\ 'foobar',
@@ -407,7 +450,7 @@ Execute(character positions should be converted to byte positions):
\ {'lnum': 1, 'bufnr': bufnr(''), 'col': 7, 'end_col': 13, 'end_lnum': 1, 'linter_name': 'foobar', 'nr': -1, 'type': 'E', 'vcol': 0, 'text': 'a'},
\ {'lnum': 1, 'bufnr': bufnr(''), 'col': 7, 'end_col': 17, 'end_lnum': 2, 'linter_name': 'foobar', 'nr': -1, 'type': 'E', 'vcol': 0, 'text': 'a'},
\ {'lnum': 2, 'bufnr': bufnr(''), 'col': 17, 'linter_name': 'foobar', 'nr': -1, 'type': 'E', 'vcol': 0, 'text': 'a'},
\],
\ ],
\ ale#engine#FixLocList(
\ bufnr('%'),
\ 'foobar',

View File

@@ -98,6 +98,16 @@ Execute(The ksh dialect should be used for shellcheck if b:is_kornshell is 1):
AssertEqual 'ksh', ale#handlers#shellcheck#GetDialectArgument(bufnr(''))
Execute(The filetype should be used as the default shell type when there is no hashbang line):
set filetype=zsh
AssertEqual 'zsh', ale#handlers#sh#GetShellType(bufnr(''))
set filetype=tcsh
AssertEqual 'tcsh', ale#handlers#sh#GetShellType(bufnr(''))
set filetype=python
AssertEqual '', ale#handlers#sh#GetShellType(bufnr(''))
Given(A file with /bin/ash):
#!/bin/ash

View File

@@ -23,22 +23,22 @@ Execute(React Native apps using CocoaPods should take precedence over the defaul
call ale#test#SetFilename('swiftlint-test-files/react-native/testfile.swift')
AssertEqual
\ ale#path#Simplify(g:dir . '/swiftlint-test-files/react-native/ios/Pods/SwiftLint/swiftlint'),
\ ale_linters#swift#swiftlint#GetExecutable(bufnr(''))
\ tolower(ale#path#Simplify(g:dir . '/swiftlint-test-files/react-native/ios/Pods/SwiftLint/swiftlint')),
\ tolower(ale_linters#swift#swiftlint#GetExecutable(bufnr('')))
Execute(CocoaPods installation should take precedence over the default executable):
call ale#test#SetFilename('swiftlint-test-files/cocoapods/testfile.swift')
AssertEqual
\ ale#path#Simplify(g:dir . '/swiftlint-test-files/cocoapods/Pods/SwiftLint/swiftlint'),
\ ale_linters#swift#swiftlint#GetExecutable(bufnr(''))
\ tolower(ale#path#Simplify(g:dir . '/swiftlint-test-files/cocoapods/Pods/SwiftLint/swiftlint')),
\ tolower(ale_linters#swift#swiftlint#GetExecutable(bufnr('')))
Execute(Top level CocoaPods installation should take precedence over React Native installation):
call ale#test#SetFilename('swiftlint-test-files/cocoapods-and-react-native/testfile.swift')
AssertEqual
\ ale#path#Simplify(g:dir . '/swiftlint-test-files/cocoapods-and-react-native/Pods/SwiftLint/swiftlint'),
\ ale_linters#swift#swiftlint#GetExecutable(bufnr(''))
\ tolower(ale#path#Simplify(g:dir . '/swiftlint-test-files/cocoapods-and-react-native/Pods/SwiftLint/swiftlint')),
\ tolower(ale_linters#swift#swiftlint#GetExecutable(bufnr('')))
Execute(use-global should override other versions):
let g:ale_swift_swiftlint_use_global = 1

View File

@@ -40,7 +40,7 @@ Before:
\ 'name': 'testlinter',
\ 'executable': has('win32') ? 'cmd' : 'echo',
\ 'callback': 'TestCallback',
\ 'command_callback': 'TestCommandCallback',
\ 'command': function('TestCommandCallback'),
\})
call ale#command#ClearData()

View File

@@ -69,3 +69,49 @@ Execute(Unix file lines should be written as normal):
call ale#util#Writefile(bufnr(''), getline(1, '$'), g:new_line_test_file)
AssertEqual
\ ['first', 'second', 'third', ''],
\ readfile(g:new_line_test_file, 'b')
Execute(Newline at end of file should be preserved even when nofixeol):
call ale#test#SetFilename(g:new_line_test_file)
setlocal buftype=
noautocmd :w
noautocmd :e! ++ff=unix
set eol
set nofixeol
call ale#util#Writefile(bufnr(''), getline(1, '$'), g:new_line_test_file)
AssertEqual
\ ['first', 'second', 'third', ''],
\ readfile(g:new_line_test_file, 'b')
Execute(Newline should not be appended on write when noeol and nofixeol):
call ale#test#SetFilename(g:new_line_test_file)
setlocal buftype=
noautocmd :w
noautocmd :e! ++ff=unix
set noeol
set nofixeol
call ale#util#Writefile(bufnr(''), getline(1, '$'), g:new_line_test_file)
AssertEqual
\ ['first', 'second', 'third'],
\ readfile(g:new_line_test_file, 'b')
Execute(Newline should be appended on write when noeol and fixeol):
call ale#test#SetFilename(g:new_line_test_file)
setlocal buftype=
noautocmd :w
noautocmd :e! ++ff=unix
set noeol
set fixeol
call ale#util#Writefile(bufnr(''), getline(1, '$'), g:new_line_test_file)
AssertEqual

View File

@@ -16,5 +16,5 @@ Execute(BufferCdString should output the correct command string):
call ale#test#SetFilename('foo.txt')
AssertEqual
\ has('unix') ? 'cd ' . ale#Escape(g:dir) . ' && ' : 'cd /d ' . ale#Escape(g:dir) . ' && ',
\ has('unix') ? 'cd %s:h && ' : 'cd /d %s:h && ',
\ ale#path#BufferCdString(bufnr(''))