Merge remote-tracking branch 'upstream/master'

Signed-off-by: Pierre-Nicolas Clauss <pinicarus@protonmail.com>
This commit is contained in:
Pierre-Nicolas Clauss
2021-01-23 19:06:59 +01:00
188 changed files with 5099 additions and 424 deletions

View File

View File

View File

@@ -0,0 +1,17 @@
Before:
call ale#assert#SetUpLinterTest('ada', 'adals')
After:
call ale#assert#TearDownLinterTest()
Execute(Sets adals executable):
let g:ale_ada_adals_executable = '/path/to /Ada'
AssertLinter '/path/to /Ada', ale#Escape('/path/to /Ada')
Execute(Sets adals encoding):
let b:ale_ada_adals_encoding = 'iso-8859-1'
AssertLSPConfig {'ada.defaultCharset': 'iso-8859-1', 'ada.projectFile': 'default.gpr'}
Execute(Sets adals project):
let g:ale_ada_adals_project = 'myproject.gpr'
AssertLSPConfig {'ada.defaultCharset': 'utf-8', 'ada.projectFile': 'myproject.gpr'}

View File

@@ -68,7 +68,6 @@ Execute(The build directory should be used for header files):
\ ale#Escape('clang-tidy')
\ . ' -checks=' . ale#Escape('*') . ' %s'
\ . ' -p ' . ale#Escape('/foo/bar')
\ . ' -- -x c++'
call ale#test#SetFilename('test.hpp')

View File

@@ -0,0 +1,15 @@
Before:
call ale#assert#SetUpLinterTest('dart', 'analysis_server')
After:
call ale#assert#TearDownLinterTest()
Execute(The default command should be correct):
AssertLinter 'dart', ale#Escape('dart')
\ . ' ./snapshots/analysis_server.dart.snapshot --lsp'
Execute(The executable should be configurable):
let g:ale_dart_analysis_server_executable = 'foobar'
AssertLinter 'foobar', ale#Escape('foobar')
\ . ' ./snapshots/analysis_server.dart.snapshot --lsp'

View File

@@ -38,3 +38,10 @@ Execute(Builds credo command with suggest mode when set to 0):
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 a custom config file):
let g:ale_elixir_credo_config_file = '/home/user/custom_credo.exs'
AssertLinter 'mix',
\ ale#path#CdString(ale#path#Simplify(g:dir . '/elixir_paths/mix_project'))
\ . 'mix help credo && mix credo suggest --config-file /home/user/custom_credo.exs --format=flycheck --read-from-stdin %s'

View File

@@ -0,0 +1,16 @@
Before:
let b:file = fnamemodify(bufname(''), ':.')
call ale#assert#SetUpLinterTest('erlang', 'elvis')
After:
call ale#assert#TearDownLinterTest()
Execute(Default command should be correct):
AssertLinter 'elvis',
\ ale#Escape('elvis') . ' rock --output-format=parsable ' . ale#Escape(b:file)
Execute(Executable should be configurable):
let b:ale_erlang_elvis_executable = '/path/to/elvis'
AssertLinter '/path/to/elvis',
\ ale#Escape('/path/to/elvis') . ' rock --output-format=parsable ' . ale#Escape(b:file)

View File

@@ -1,5 +1,6 @@
Before:
call ale#assert#SetUpLinterTest('javascript', 'fecs')
runtime autoload/ale/handlers/fecs.vim
After:
call ale#assert#TearDownLinterTest()

View File

@@ -0,0 +1,15 @@
Before:
call ale#assert#SetUpLinterTest('openapi', 'ibm_validator')
After:
call ale#assert#TearDownLinterTest()
Execute(The yaml ibm-openapi-validator command callback should return the correct default string):
AssertLinter 'lint-openapi', ale#Escape('lint-openapi') . ' %t'
Execute(The yaml ibm-openapi-validator command callback should be configurable):
let g:ale_openapi_ibm_validator_executable = '~/.local/bin/lint-openapi'
let g:ale_openapi_ibm_validator_options = '-c ~/.config'
AssertLinter '~/.local/bin/lint-openapi', ale#Escape('~/.local/bin/lint-openapi')
\ . ' -c ~/.config %t'

View File

@@ -0,0 +1,20 @@
Before:
call ale#assert#SetUpLinterTest('inko', 'inko')
call ale#test#SetFilename('inko_paths/test.inko')
After:
call ale#assert#TearDownLinterTest()
Execute(The default executable path should be correct):
AssertLinter 'inko', ale#Escape('inko') . ' build --check --format=json %s'
Execute(The inko callback should include tests/ for test paths):
call ale#engine#Cleanup(bufnr(''))
noautocmd e! inko_paths/tests/test/test_foo.inko
call ale#engine#InitBufferInfo(bufnr(''))
AssertLinter 'inko',
\ ale#Escape('inko')
\ . ' build --check --format=json --include '
\ . ale#Escape(ale#path#Simplify(g:dir . '/inko_paths/tests/'))
\ . ' %s'

View File

@@ -11,16 +11,16 @@ After:
Execute(The default executable path should be correct):
AssertLinter 'julia',
\ ale#Escape('julia') .
\' --startup-file=no --history-file=no -e ' .
\ ale#Escape('using LanguageServer; server = LanguageServer.LanguageServerInstance(isdefined(Base, :stdin) ? stdin : STDIN, isdefined(Base, :stdout) ? stdout : STDOUT, false); server.runlinter = true; run(server);')
\' --project=@. --startup-file=no --history-file=no -e ' .
\ ale#Escape('using LanguageServer; using Pkg; import StaticLint; import SymbolServer; server = LanguageServer.LanguageServerInstance(isdefined(Base, :stdin) ? stdin : STDIN, isdefined(Base, :stdout) ? stdout : STDOUT, dirname(Pkg.Types.Context().env.project_file)); server.runlinter = true; run(server);')
Execute(The executable should be configurable):
let g:ale_julia_executable = 'julia-new'
AssertLinter 'julia-new',
\ ale#Escape('julia-new') .
\' --startup-file=no --history-file=no -e ' .
\ ale#Escape('using LanguageServer; server = LanguageServer.LanguageServerInstance(isdefined(Base, :stdin) ? stdin : STDIN, isdefined(Base, :stdout) ? stdout : STDOUT, false); server.runlinter = true; run(server);')
\' --project=@. --startup-file=no --history-file=no -e ' .
\ ale#Escape('using LanguageServer; using Pkg; import StaticLint; import SymbolServer; server = LanguageServer.LanguageServerInstance(isdefined(Base, :stdin) ? stdin : STDIN, isdefined(Base, :stdout) ? stdout : STDOUT, dirname(Pkg.Types.Context().env.project_file)); server.runlinter = true; run(server);')
Execute(The project root should be detected correctly):
AssertLSPProject ''

View File

@@ -0,0 +1,26 @@
Before:
call ale#assert#SetUpLinterTest('php', 'intelephense')
After:
call ale#assert#TearDownLinterTest()
Execute(The default executable path should be correct):
AssertLinter 'intelephense',
\ ale#Escape('intelephense') . ' --stdio'
Execute(The project path should be correct for .git directories):
call ale#test#SetFilename('php-intelephense-project/with-git/test.php')
silent! call mkdir('php-intelephense-project/with-git/.git', 'p')
AssertLSPProject ale#path#Simplify(g:dir . '/php-intelephense-project/with-git')
Execute(The project path should be correct for composer.json file):
call ale#test#SetFilename('php-intelephense-project/with-composer/test.php')
AssertLSPProject ale#path#Simplify(g:dir . '/php-intelephense-project/with-composer')
Execute(The project cache should be saved in a temp dir):
call ale#test#SetFilename('php-intelephense-project/with-composer/test.php')
let g:ale_php_intelephense_config = { 'storagePath': '/tmp/intelephense' }
AssertLSPProject ale#path#Simplify(g:dir . '/php-intelephense-project/with-composer')

View File

@@ -0,0 +1,22 @@
Before:
call ale#assert#SetUpLinterTest('r', 'languageserver')
After:
call ale#assert#TearDownLinterTest()
Execute(The default executable path should be correct):
AssertLinter 'Rscript', 'Rscript --vanilla -e ' . ale#Escape('languageserver::run()')
Execute(The project root should be detected correctly):
AssertLSPProject '.'
call ale#test#SetFilename('r_paths/dummy/test.R')
AssertLSPProject ale#path#Simplify(g:dir . '/r_paths')
Execute(Should accept configuration settings):
AssertLSPConfig {}
let b:ale_r_languageserver_config = {'r': {'lsp': {'debug': 'true', 'diagnostics': 'true'}}}
AssertLSPConfig {'r': {'lsp': {'debug': 'true', 'diagnostics': 'true'}}}

View File

@@ -16,5 +16,5 @@ Execute(The project root should be detected correctly):
Execute(Should accept configuration settings):
AssertLSPConfig {}
let b:ale_rust_analyzer_config = {'rust': {'clippy_preference': 'on'}}
AssertLSPConfig {'rust': {'clippy_preference': 'on'}}
let b:ale_rust_analyzer_config = {'diagnostics': {'disabled': ['unresolved-import']}}
AssertLSPOptions {'diagnostics': {'disabled': ['unresolved-import']}}

View File

@@ -5,6 +5,7 @@ Before:
let g:ale_ruby_sorbet_executable = 'srb'
let g:ale_ruby_sorbet_options = ''
let g:ale_ruby_sorbet_enable_watchman = 0
After:
call ale#assert#TearDownLinterTest()
@@ -13,6 +14,12 @@ Execute(Executable should default to srb):
AssertLinter 'srb', ale#Escape('srb')
\ . ' tc --lsp --disable-watchman'
Execute(Able to enable watchman):
let g:ale_ruby_sorbet_enable_watchman = 1
AssertLinter 'srb', ale#Escape('srb')
\ . ' tc --lsp'
Execute(Should be able to set a custom executable):
let g:ale_ruby_sorbet_executable = 'bin/srb'

View File

@@ -0,0 +1,31 @@
Before:
call ale#assert#SetUpLinterTest('yaml', 'spectral')
After:
call ale#assert#TearDownLinterTest()
Execute(The yaml spectral command callback should return the correct default string):
AssertLinter 'spectral', ale#Escape('spectral') . ' lint --ignore-unknown-format -q -f text %t'
Execute(The yaml spectral command callback should be configurable):
let g:ale_yaml_spectral_executable = '~/.local/bin/spectral'
AssertLinter '~/.local/bin/spectral',
\ ale#Escape('~/.local/bin/spectral')
\ . ' lint --ignore-unknown-format -q -f text %t'
Execute(The yaml spectral command callback should allow a global installation to be used):
let g:ale_yaml_spectral_executable = '/usr/local/bin/spectral'
let g:ale_yaml_spectral_use_global = 1
AssertLinter '/usr/local/bin/spectral',
\ ale#Escape('/usr/local/bin/spectral')
\ . ' lint --ignore-unknown-format -q -f text %t'
Execute(The yaml spectral command callback should allow a local installation to be used):
call ale#test#SetFilename('spectral_paths/openapi.yaml')
AssertLinter
\ ale#path#Simplify(g:dir . '/spectral_paths/node_modules/.bin/spectral'),
\ ale#Escape(ale#path#Simplify(g:dir . '/spectral_paths/node_modules/.bin/spectral'))
\ . ' lint --ignore-unknown-format -q -f text %t'

View File

@@ -0,0 +1,60 @@
Before:
let g:ale_deno_unstable = 0
let g:ale_deno_executable = 'deno'
let g:ale_deno_project_root = ''
runtime autoload/ale/handlers/deno.vim
call ale#assert#SetUpLinterTest('typescript', 'deno')
After:
call ale#assert#TearDownLinterTest()
Execute(Should set deno lsp for TypeScript projects using stable Deno API):
AssertLSPLanguage 'typescript'
AssertLSPConfig {}
AssertLSPProject ale#path#Simplify(g:dir . '/../..')
AssertLSPOptions {
\ 'enable': v:true,
\ 'lint': v:true,
\ 'unstable': v:false
\}
Execute(Should set deno lsp using unstable Deno API if enabled by user):
let g:ale_deno_unstable = 1
AssertLSPLanguage 'typescript'
AssertLSPConfig {}
AssertLSPProject ale#path#Simplify(g:dir . '/../..')
AssertLSPOptions {
\ 'enable': v:true,
\ 'lint': v:true,
\ 'unstable': v:true
\}
Execute(Should find project root containing tsconfig.json):
call ale#test#SetFilename('../typescript/test.ts')
AssertLSPLanguage 'typescript'
AssertLSPConfig {}
AssertLSPProject ale#path#Simplify(g:dir . '/../typescript')
AssertLSPOptions {
\ 'enable': v:true,
\ 'lint': v:true,
\ 'unstable': v:false
\}
Execute(Should use user-specified project root):
let g:ale_deno_lsp_project_root = '/'
call ale#test#SetFilename('../typescript/test.ts')
AssertLSPLanguage 'typescript'
AssertLSPConfig {}
AssertLSPProject '/'
AssertLSPOptions {
\ 'enable': v:true,
\ 'lint': v:true,
\ 'unstable': v:false
\}
Execute(Check Deno LSP command):
AssertLinter 'deno', [
\ ale#Escape('deno') . ' lsp',
\]

View File

@@ -1,8 +1,11 @@
Before:
call ale#assert#SetUpLinterTest('typescript', 'xo')
call ale#test#SetFilename('testfile.ts')
call ale#assert#SetUpLinterTest('javascript', 'xo')
call ale#test#SetFilename('testfile.jsx')
unlet! b:executable
set filetype=javascriptreact
runtime autoload/ale/handlers/xo.vim
After:
call ale#assert#TearDownLinterTest()
@@ -10,11 +13,11 @@ Execute(The XO executable should be called):
AssertLinter 'xo', ale#Escape('xo') . ' --reporter json --stdin --stdin-filename %s'
Execute(The XO executable should be configurable):
let b:ale_typescript_xo_executable = 'foobar'
let b:ale_javascript_xo_executable = 'foobar'
AssertLinter 'foobar', ale#Escape('foobar') . ' --reporter json --stdin --stdin-filename %s'
Execute(The XO options should be configurable):
let b:ale_typescript_xo_options = '--wat'
let b:ale_javascript_xo_options = '--wat'
AssertLinter 'xo', ale#Escape('xo') . ' --wat --reporter json --stdin --stdin-filename %s'

View File

@@ -0,0 +1,23 @@
Before:
call ale#assert#SetUpLinterTest('typescript', 'xo')
call ale#test#SetFilename('testfile.tsx')
unlet! b:executable
set filetype=typescriptreact
runtime autoload/ale/handlers/xo.vim
After:
call ale#assert#TearDownLinterTest()
Execute(The XO executable should be called):
AssertLinter 'xo', ale#Escape('xo') . ' --reporter json --stdin --stdin-filename %s'
Execute(The XO executable should be configurable):
let b:ale_typescript_xo_executable = 'foobar'
AssertLinter 'foobar', ale#Escape('foobar') . ' --reporter json --stdin --stdin-filename %s'
Execute(The XO options should be configurable):
let b:ale_typescript_xo_options = '--wat'
AssertLinter 'xo', ale#Escape('xo') . ' --wat --reporter json --stdin --stdin-filename %s'

View File

@@ -40,6 +40,7 @@ Execute(Should handle Rust completion results correctly):
\ {'word': 'from', 'menu': 'fn from(s: &''a str) -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
\ {'word': 'from', 'menu': 'fn from(s: Box<str>) -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
\ {'word': 'from', 'menu': 'fn from(s: Cow<''a, str>) -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
\ {'word': 'to_vec', 'menu': 'pub fn to_vec(&self) -> Vec<T> where T: Clone,', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
\],
\ ale#completion#ParseLSPCompletions({
\ "jsonrpc":"2.0",
@@ -184,6 +185,11 @@ Execute(Should handle Rust completion results correctly):
\ "label":"from",
\ "kind":3,
\ "detail":"fn from(s: Cow<'a, str>) -> String"
\ },
\ {
\ "label":"to_vec",
\ "kind":3,
\ "detail":"pub fn to_vec(&self) -> Vec<T>\nwhere\n T: Clone,"
\ }
\ ]
\ })

View File

View File

@@ -0,0 +1,50 @@
Before:
Save g:ale_python_autoimport_executable
Save g:ale_python_autoimport_options
" Use an invalid global executable, so we don't match it.
let g:ale_python_autoimport_executable = 'xxxinvalid'
let g:ale_python_autoimport_options = ''
call ale#test#SetDirectory('/testplugin/test/fixers')
silent cd ..
silent cd command_callback
let g:dir = getcwd()
let b:bin_dir = has('win32') ? 'Scripts' : 'bin'
After:
Restore
unlet! b:bin_dir
call ale#test#RestoreDirectory()
Execute(The autoimport callback should return the correct default values):
AssertEqual
\ 0,
\ ale#fixers#autoimport#Fix(bufnr(''))
silent execute 'file ' . fnameescape(g:dir . '/python_paths/with_virtualenv/subdir/foo/bar.py')
AssertEqual
\ {
\ 'command': ale#path#BufferCdString(bufnr(''))
\ . ale#Escape(ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/env/' . b:bin_dir . '/autoimport')) . ' -',
\ },
\ ale#fixers#autoimport#Fix(bufnr(''))
Execute(The autoimport callback should respect custom options):
let g:ale_python_autoimport_options = '--multi-line=3 --trailing-comma'
AssertEqual
\ 0,
\ ale#fixers#autoimport#Fix(bufnr(''))
silent execute 'file ' . fnameescape(g:dir . '/python_paths/with_virtualenv/subdir/foo/bar.py')
AssertEqual
\ {
\ 'command': ale#path#BufferCdString(bufnr(''))
\ . ale#Escape(ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/env/' . b:bin_dir . '/autoimport'))
\ . ' --multi-line=3 --trailing-comma -',
\ },
\ ale#fixers#autoimport#Fix(bufnr(''))

View File

@@ -1,11 +0,0 @@
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

@@ -0,0 +1,24 @@
Before:
Save g:ale_dhall_executable
Save g:ale_dhall_options
" Use an invalid global executable, so we dont match it.
let g:ale_dhall_executable = 'odd-dhall'
let g:ale_dhall_options = '--ascii'
call ale#assert#SetUpFixerTest('dhall-format', 'dhall-format')
After:
call ale#assert#TearDownFixerTest()
Execute(The dhall-format callback should return the correct options):
call ale#test#SetFilename('../dhall_files/testfile.dhall')
AssertFixer
\ {
\ 'command': ale#Escape('odd-dhall')
\ . ' --ascii'
\ . ' format'
\ . ' --inplace %t',
\ 'read_temporary_file': 1,
\ }

View File

@@ -0,0 +1,24 @@
Before:
Save g:ale_dhall_executable
Save g:ale_dhall_options
" Use an invalid global executable, so we dont match it.
let g:ale_dhall_executable = 'odd-dhall'
let g:ale_dhall_options = '--ascii'
let g:ale_dhall_freeze_options = '--all'
call ale#assert#SetUpFixerTest('dhall-freeze', 'dhall-freeze')
After:
call ale#assert#TearDownFixerTest()
Execute(The dhall-freeze callback should return the correct options):
AssertFixer
\ {
\ 'command': ale#Escape('odd-dhall')
\ . ' --ascii'
\ . ' freeze'
\ . ' --all'
\ . ' --inplace %t',
\ 'read_temporary_file': 1,
\ }

View File

@@ -0,0 +1,22 @@
Before:
Save g:ale_dhall_executable
Save g:ale_dhall_options
" Use an invalid global executable, so we dont match it.
let g:ale_dhall_executable = 'odd-dhall'
let g:ale_dhall_options = '--ascii'
call ale#assert#SetUpFixerTest('dhall-lint', 'dhall-lint')
After:
call ale#assert#TearDownFixerTest()
Execute(The dhall-lint callback should return the correct options):
AssertFixer
\ {
\ 'command': ale#Escape('odd-dhall')
\ . ' --ascii'
\ . ' lint'
\ . ' --inplace %t',
\ 'read_temporary_file': 1,
\ }

View File

@@ -21,10 +21,7 @@ Execute(The gofmt callback should return the correct default values):
AssertEqual
\ {
\ 'read_temporary_file': 1,
\ 'command': ale#Escape('xxxinvalid')
\ . ' -l -w'
\ . ' %t',
\ 'command': ale#Escape('xxxinvalid'),
\ },
\ ale#fixers#gofmt#Fix(bufnr(''))
@@ -35,11 +32,8 @@ Execute(The gofmt callback should include custom gofmt options):
AssertEqual
\ {
\ 'read_temporary_file': 1,
\ 'command': ale#Escape('xxxinvalid')
\ . ' -l -w'
\ . ' ' . g:ale_go_gofmt_options
\ . ' %t',
\ . ' ' . g:ale_go_gofmt_options,
\ },
\ ale#fixers#gofmt#Fix(bufnr(''))
@@ -50,9 +44,7 @@ Execute(The gofmt callback should support Go environment variables):
AssertEqual
\ {
\ 'read_temporary_file': 1,
\ 'command': ale#Env('GO111MODULE', 'off')
\ . ale#Escape('xxxinvalid') . ' -l -w'
\ . ' %t',
\ . ale#Escape('xxxinvalid')
\ },
\ ale#fixers#gofmt#Fix(bufnr(''))

View File

@@ -5,6 +5,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 = ''
let g:ale_python_isort_auto_pipenv = 0
call ale#test#SetDirectory('/testplugin/test/fixers')
silent cd ..
@@ -48,3 +49,12 @@ Execute(The isort callback should respect custom options):
\ . ' --multi-line=3 --trailing-comma -',
\ },
\ ale#fixers#isort#Fix(bufnr(''))
Execute(Pipenv is detected when python_isort_auto_pipenv is set):
let g:ale_python_isort_auto_pipenv = 1
call ale#test#SetFilename('/testplugin/test/python_fixtures/pipenv/whatever.py')
AssertEqual
\ {'command': ale#path#BufferCdString(bufnr('')) . ale#Escape('pipenv') . ' run isort -'},
\ ale#fixers#isort#Fix(bufnr(''))

View File

@@ -0,0 +1,35 @@
Before:
Save g:ale_lua_luafmt_executable
Save g:ale_lua_luafmt_options
" Use an invalid global executable, so we don't match it.
let g:ale_lua_luafmt_executable = 'xxxinvalid'
let g:ale_lua_luafmt_options = ''
call ale#test#SetDirectory('/testplugin/test/fixers')
After:
Restore
call ale#test#RestoreDirectory()
Execute(The luafmt callback should return the correct default values):
call ale#test#SetFilename('../lua_files/testfile.lua')
AssertEqual
\ {
\ 'command': ale#Escape('xxxinvalid') . ' --stdin',
\ },
\ ale#fixers#luafmt#Fix(bufnr(''))
Execute(The luafmt callback should include custom luafmt options):
let g:ale_lua_luafmt_options = "--skip-children"
call ale#test#SetFilename('../lua_files/testfile.lua')
AssertEqual
\ {
\ 'command': ale#Escape('xxxinvalid')
\ . ' ' . g:ale_lua_luafmt_options
\ . ' --stdin',
\ },
\ ale#fixers#luafmt#Fix(bufnr(''))

View File

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

View File

@@ -5,6 +5,7 @@ Before:
let g:ale_php_phpcbf_executable = 'phpcbf_test'
let g:ale_php_phpcbf_standard = ''
let g:ale_php_phpcbf_options = ''
let g:ale_php_phpcbf_use_global = 0
call ale#test#SetDirectory('/testplugin/test/fixers')
@@ -54,6 +55,15 @@ Execute(The phpcbf callback should include the phpcbf_standard option):
\ {'command': ale#Escape(ale#path#Simplify(g:dir . '/php_paths/project-with-phpcbf/vendor/bin/phpcbf')) . ' --stdin-path=%s ' . '--standard=phpcbf_ruleset.xml' . ' -'},
\ ale#fixers#phpcbf#Fix(bufnr(''))
Execute(User provided options should be used):
let g:ale_php_phpcbf_options = '--my-user-provided-option my-value'
call ale#test#SetFilename('php_paths/project-with-phpcbf/foo/test.php')
AssertEqual
\ {'command': ale#Escape(ale#path#Simplify(g:dir . '/php_paths/project-with-phpcbf/vendor/bin/phpcbf')) . ' --stdin-path=%s ' . ale#Pad('--my-user-provided-option my-value') . ' -'},
\ ale#fixers#phpcbf#Fix(bufnr(''))
Before:
Save g:ale_php_phpcbf_executable
Save g:ale_php_phpcbf_standard
@@ -61,6 +71,7 @@ Before:
let g:ale_php_phpcbf_executable = 'phpcbf_test'
let g:ale_php_phpcbf_standard = ''
let g:ale_php_phpcbf_options = ''
let g:ale_php_phpcbf_use_global = 0
call ale#test#SetDirectory('/testplugin/test/fixers')

View File

@@ -21,9 +21,9 @@ Execute(The standardrb callback should return the correct default values):
AssertEqual
\ {
\ 'read_temporary_file': 1,
\ 'process_with': 'ale#fixers#rubocop#PostProcess',
\ 'command': ale#Escape(g:ale_ruby_standardrb_executable)
\ . ' --fix --force-exclusion %t',
\ . ' --fix --force-exclusion --stdin %s',
\ },
\ ale#fixers#standardrb#Fix(bufnr(''))
@@ -32,10 +32,10 @@ Execute(The standardrb callback should include configuration files):
AssertEqual
\ {
\ 'read_temporary_file': 1,
\ 'process_with': 'ale#fixers#rubocop#PostProcess',
\ 'command': ale#Escape(g:ale_ruby_standardrb_executable)
\ . ' --config ' . ale#Escape(ale#path#Simplify(g:dir . '/ruby_paths/with_config/.standard.yml'))
\ . ' --fix --force-exclusion %t',
\ . ' --fix --force-exclusion --stdin %s',
\ },
\ ale#fixers#standardrb#Fix(bufnr(''))
@@ -45,10 +45,10 @@ Execute(The standardrb callback should include custom rubocop options):
AssertEqual
\ {
\ 'read_temporary_file': 1,
\ 'process_with': 'ale#fixers#rubocop#PostProcess',
\ 'command': ale#Escape(g:ale_ruby_standardrb_executable)
\ . ' --config ' . ale#Escape(ale#path#Simplify(g:dir . '/ruby_paths/with_config/.standard.yml'))
\ . ' --except Lint/Debugger'
\ . ' --fix --force-exclusion %t',
\ . ' --fix --force-exclusion --stdin %s',
\ },
\ ale#fixers#standardrb#Fix(bufnr(''))

View File

@@ -0,0 +1,45 @@
Before:
call ale#assert#SetUpFixerTest('javascript', 'xo')
runtime autoload/ale/handlers/xo.vim
set filetype=javascript
After:
call ale#assert#TearDownFixerTest()
Execute(The xo callback should return the correct default values):
call ale#test#SetFilename('../xo-test-files/monorepo/packages/a/index.js')
AssertFixer
\ {
\ 'read_temporary_file': 1,
\ 'command': (has('win32') ? 'node.exe ' : '')
\ . ale#Escape(ale#path#Simplify(g:dir . '/../xo-test-files/monorepo/node_modules/xo/cli.js'))
\ . ' --fix %t',
\ }
Execute(The xo callback should include custom xo options):
let g:ale_javascript_xo_options = '--space'
call ale#test#SetFilename('../xo-test-files/monorepo/packages/a/index.js')
AssertFixer
\ {
\ 'read_temporary_file': 1,
\ 'command': (has('win32') ? 'node.exe ' : '')
\ . ale#Escape(ale#path#Simplify(g:dir . '/../xo-test-files/monorepo/node_modules/xo/cli.js'))
\ . ' --fix %t'
\ . ' --space',
\ }
Execute(--stdin should be used when xo is new enough):
let g:ale_javascript_xo_options = '--space'
call ale#test#SetFilename('../xo-test-files/monorepo/packages/a/index.js')
GivenCommandOutput ['0.30.0']
AssertFixer
\ {
\ 'command': (has('win32') ? 'node.exe ' : '')
\ . ale#Escape(ale#path#Simplify(g:dir . '/../xo-test-files/monorepo/node_modules/xo/cli.js'))
\ . ' --stdin --stdin-filename %s'
\ . ' --fix'
\ . ' --space',
\ }

View File

@@ -0,0 +1,45 @@
Before:
call ale#assert#SetUpFixerTest('typescript', 'xo')
runtime autoload/ale/handlers/xo.vim
set filetype=typescript
After:
call ale#assert#TearDownFixerTest()
Execute(The xo callback should return the correct default values):
call ale#test#SetFilename('../xo-test-files/monorepo/packages/a/index.ts')
AssertFixer
\ {
\ 'read_temporary_file': 1,
\ 'command': (has('win32') ? 'node.exe ' : '')
\ . ale#Escape(ale#path#Simplify(g:dir . '/../xo-test-files/monorepo/node_modules/xo/cli.js'))
\ . ' --fix %t',
\ }
Execute(The xo callback should include custom xo options):
let g:ale_typescript_xo_options = '--space'
call ale#test#SetFilename('../xo-test-files/monorepo/packages/a/index.ts')
AssertFixer
\ {
\ 'read_temporary_file': 1,
\ 'command': (has('win32') ? 'node.exe ' : '')
\ . ale#Escape(ale#path#Simplify(g:dir . '/../xo-test-files/monorepo/node_modules/xo/cli.js'))
\ . ' --fix %t'
\ . ' --space',
\ }
Execute(--stdin should be used when xo is new enough):
let g:ale_typescript_xo_options = '--space'
call ale#test#SetFilename('../xo-test-files/monorepo/packages/a/index.ts')
GivenCommandOutput ['0.30.0']
AssertFixer
\ {
\ 'command': (has('win32') ? 'node.exe ' : '')
\ . ale#Escape(ale#path#Simplify(g:dir . '/../xo-test-files/monorepo/node_modules/xo/cli.js'))
\ . ' --stdin --stdin-filename %s'
\ . ' --fix'
\ . ' --space',
\ }

View File

@@ -0,0 +1,50 @@
Before:
Save g:ale_python_yamlfix_executable
Save g:ale_python_yamlfix_options
" Use an invalid global executable, so we don't match it.
let g:ale_python_yamlfix_executable = 'xxxinvalid'
let g:ale_python_yamlfix_options = ''
call ale#test#SetDirectory('/testplugin/test/fixers')
silent cd ..
silent cd command_callback
let g:dir = getcwd()
let b:bin_dir = has('win32') ? 'Scripts' : 'bin'
After:
Restore
unlet! b:bin_dir
call ale#test#RestoreDirectory()
Execute(The yamlfix callback should return the correct default values):
AssertEqual
\ 0,
\ ale#fixers#yamlfix#Fix(bufnr(''))
silent execute 'file ' . fnameescape(g:dir . '/python_paths/with_virtualenv/subdir/foo/bar.yaml')
AssertEqual
\ {
\ 'command': ale#path#BufferCdString(bufnr(''))
\ . ale#Escape(ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/env/' . b:bin_dir . '/yamlfix')) . ' -',
\ },
\ ale#fixers#yamlfix#Fix(bufnr(''))
Execute(The yamlfix callback should respect custom options):
let g:ale_yaml_yamlfix_options = '--multi-line=3 --trailing-comma'
AssertEqual
\ 0,
\ ale#fixers#yamlfix#Fix(bufnr(''))
silent execute 'file ' . fnameescape(g:dir . '/python_paths/with_virtualenv/subdir/foo/bar.yaml')
AssertEqual
\ {
\ 'command': ale#path#BufferCdString(bufnr(''))
\ . ale#Escape(ale#path#Simplify(g:dir . '/python_paths/with_virtualenv/env/' . b:bin_dir . '/yamlfix'))
\ . ' --multi-line=3 --trailing-comma -',
\ },
\ ale#fixers#yamlfix#Fix(bufnr(''))

View File

@@ -0,0 +1,85 @@
Before:
runtime autoload/ale/handlers/atools.vim
After:
call ale#linter#Reset()
Execute(The atools handler should handle basic errors or warings):
AssertEqual
\ [
\ {
\ 'lnum': 2,
\ 'text': 'trailing whitespace',
\ 'type': 'E',
\ 'code': 'AL8',
\ },
\ {
\ 'lnum': 15,
\ 'text': '$pkgname should not be used in the source url',
\ 'type': 'W',
\ 'code': 'AL29',
\ },
\ ],
\ ale#handlers#atools#Handle(bufnr(''), [
\ 'IC:[AL8]:APKBUILD:2:trailing whitespace',
\ 'MC:[AL29]:APKBUILD:15:$pkgname should not be used in the source url',
\ ])
" Regardless of the severity, if the certainty is [P]ossible and not [C]ertain
" or if regardless of the Certainity the Severity is not [I]mportant or [S]erious
" then it must be a [W]arning
Execute(If we are not Certain or Importantly Serious, be a Warning):
AssertEqual
\ [
\ {
\ 'lnum': 3,
\ 'text': 'This violation is Serious but Possible false positive, I am a Warning!',
\ 'type': 'W',
\ 'code': 'AL',
\ },
\ {
\ 'lnum': 4,
\ 'text': 'This violation is Important but Possible false positive, I am a Warning!',
\ 'type': 'W',
\ 'code': 'AL',
\ },
\ {
\ 'lnum': 5,
\ 'text': 'This violation is Minor, I am a Warning!',
\ 'type': 'W',
\ 'code': 'AL',
\ },
\ {
\ 'lnum': 6,
\ 'text': 'This violation is Style, I am a Warning!',
\ 'type': 'W',
\ 'code': 'AL',
\ },
\ ],
\ ale#handlers#atools#Handle(bufnr(''), [
\ 'SP:[AL]:APKBUILD:3:This violation is Serious but Possible false positive, I am a Warning!',
\ 'IP:[AL]:APKBUILD:4:This violation is Important but Possible false positive, I am a Warning!',
\ 'MC:[AL]:APKBUILD:5:This violation is Minor, I am a Warning!',
\ 'TC:[AL]:APKBUILD:6:This violation is Style, I am a Warning!',
\ ])
Execute(We should be error if we are Certain it is Serious or Important):
AssertEqual
\ [
\ {
\ 'lnum': 7,
\ 'text': 'This is Certainly Serious, I am an Error!',
\ 'type': 'E',
\ 'code': 'AL',
\ },
\ {
\ 'lnum': 8,
\ 'text': 'This is Certainly Important, I am an Error!',
\ 'type': 'E',
\ 'code': 'AL',
\ },
\ ],
\ ale#handlers#atools#Handle(bufnr(''), [
\ 'SC:[AL]:APKBUILD:7:This is Certainly Serious, I am an Error!',
\ 'IC:[AL]:APKBUILD:8:This is Certainly Important, I am an Error!',
\ ])

View File

@@ -8,21 +8,29 @@ Execute(The Dafny handler should parse output correctly):
AssertEqual
\ [
\ {
\ 'bufnr': 0,
\ 'filename': 'File.dfy',
\ 'col': 45,
\ 'lnum': 123,
\ 'text': 'A precondition for this call might not hold.',
\ 'type': 'E'
\ },
\ {
\ 'bufnr': 0,
\ 'filename': 'File.dfy',
\ 'col': 90,
\ 'lnum': 678,
\ 'text': 'This is the precondition that might not hold.',
\ 'type': 'W'
\ }
\ },
\ {
\ 'bufnr': 0,
\ 'col': 45,
\ 'lnum': 123,
\ 'text': "Verification of 'Impl$$_22_Proof.__default.PutKeepsMapsFull' timed out after 2 seconds",
\ 'type': 'E'
\ },
\ ],
\ ale_linters#dafny#dafny#Handle(0, [
\ 'File.dfy(123,45): Error BP5002: A precondition for this call might not hold.',
\ 'File.dfy(678,90): Related location: This is the precondition that might not hold.'
\ 'File.dfy(678,90): Related location: This is the precondition that might not hold.',
\ "File.dfy(123,45): Verification of 'Impl$$_22_Proof.__default.PutKeepsMapsFull' timed out after 2 seconds",
\ ])

View File

@@ -0,0 +1,37 @@
Before:
runtime ale_linters/erlang/elvis.vim
After:
call ale#linter#Reset()
Execute(Warning messages should be handled):
AssertEqual
\ [
\ {
\ 'lnum': 11,
\ 'text': "Replace the 'if' expression on line 11 with a 'case' expression or function clauses.",
\ 'type': 'W',
\ },
\ {
\ 'lnum': 20,
\ 'text': 'Remove the debug call to io:format/1 on line 20.',
\ 'type': 'W',
\ },
\ ],
\ ale_linters#erlang#elvis#Handle(bufnr(''), [
\ "src/foo.erl:11:no_if_expression:Replace the 'if' expression on line 11 with a 'case' expression or function clauses.",
\ 'src/foo.erl:20:no_debug_call:Remove the debug call to io:format/1 on line 20.',
\ ])
Execute(Line length message shouldn't contain the line itself):
AssertEqual
\ [
\ {
\ 'lnum': 24,
\ 'text': 'Line 24 is too long.',
\ 'type': 'W',
\ },
\ ],
\ ale_linters#erlang#elvis#Handle(bufnr(''), [
\ 'src/foo.erl:24:line_length:Line 24 is too long: io:format("Look ma, too long!"),.',
\ ])

View File

@@ -0,0 +1,49 @@
Before:
runtime! ale_linters/openapi/ibm_validator.vim
After:
call ale#linter#Reset()
Execute(Problems should be parsed correctly for openapi-ibm-validator):
AssertEqual
\ [
\ {
\ 'lnum': 54,
\ 'col': 0,
\ 'type': 'E',
\ 'text': 'Items with a description must have content in it.',
\ },
\ {
\ 'lnum': 24,
\ 'col': 0,
\ 'type': 'W',
\ 'text': 'Operations must have a non-empty `operationId`.',
\ },
\ {
\ 'lnum': 40,
\ 'col': 0,
\ 'type': 'W',
\ 'text': 'operationIds must follow case convention: lower_snake_case',
\ },
\ ],
\ ale_linters#openapi#ibm_validator#Handle(bufnr(''), [
\ '',
\ '[Warning] No .validaterc file found. The validator will run in default mode.',
\ 'To configure the validator, create a .validaterc file.',
\ '',
\ 'errors',
\ '',
\ ' Message : Items with a description must have content in it.',
\ ' Path : paths./settings.patch.description',
\ ' Line : 54',
\ '',
\ 'warnings',
\ '',
\ ' Message : Operations must have a non-empty `operationId`.',
\ ' Path : paths./stats.get.operationId',
\ ' Line : 24',
\ '',
\ ' Message : operationIds must follow case convention: lower_snake_case',
\ ' Path : paths./settings.get.operationId',
\ ' Line : 40'
\ ])

View File

@@ -0,0 +1,54 @@
Before:
runtime ale_linters/inko/inko.vim
After:
call ale#linter#Reset()
Execute(The inko handler should parse errors correctly):
AssertEqual
\ [
\ {
\ 'filename': ale#path#Simplify('/tmp/foo.inko'),
\ 'lnum': 4,
\ 'col': 5,
\ 'text': 'this is an error',
\ 'type': 'E',
\ }
\ ],
\ ale#handlers#inko#Handle(bufnr(''), [
\ '[',
\ ' {',
\ ' "file": "/tmp/foo.inko",',
\ ' "line": 4,',
\ ' "column": 5,',
\ ' "message": "this is an error",',
\ ' "level": "error"',
\ ' }',
\ ']'
\ ])
Execute(The inko handler should parse warnings correctly):
AssertEqual
\ [
\ {
\ 'filename': ale#path#Simplify('/tmp/foo.inko'),
\ 'lnum': 4,
\ 'col': 5,
\ 'text': 'this is a warning',
\ 'type': 'W',
\ }
\ ],
\ ale#handlers#inko#Handle(bufnr(''), [
\ '[',
\ ' {',
\ ' "file": "/tmp/foo.inko",',
\ ' "line": 4,',
\ ' "column": 5,',
\ ' "message": "this is a warning",',
\ ' "level": "warning"',
\ ' }',
\ ']'
\ ])
Execute(The inko handler should handle empty output):
AssertEqual [], ale#handlers#inko#Handle(bufnr(''), [])

View File

@@ -13,7 +13,16 @@ Execute(phpcs errors should be handled):
\ 'type': 'E',
\ 'sub_type': 'style',
\ 'text': 'Line indented incorrectly; expected 4 spaces, found 2 (Generic.WhiteSpace.ScopeIndent.IncorrectExact)',
\ }],
\ },
\ {
\ 'lnum': 22,
\ 'col': 3,
\ 'type': 'E',
\ 'sub_type': 'style',
\ 'text': 'All output should be run through an escaping function (see the Security sections in the WordPress Developer Handbooks)',
\ },
\ ],
\ ale_linters#php#phpcs#Handle(bufnr(''), [
\ '/path/to/some-filename.php:18:3: error - Line indented incorrectly; expected 4 spaces, found 2 (Generic.WhiteSpace.ScopeIndent.IncorrectExact)',
\ "/path/to/some-filename.php:22:3: error - All output should be run through an escaping function (see the Security sections in the WordPress Developer Handbooks), found '\"\n'.",
\ ])

View File

@@ -0,0 +1,34 @@
Before:
runtime ale_linters/salt/salt_lint.vim
After:
call ale#linter#Reset()
Execute(The salt handler should parse lines correctly and show error in severity HIGH):
AssertEqual
\ [
\ {
\ 'lnum': 5,
\ 'code': 207,
\ 'text': 'File modes should always be encapsulated in quotation marks',
\ 'type': 'E'
\ }
\ ],
\ ale_linters#salt#salt_lint#Handle(255, [
\ '[{"id": "207", "message": "File modes should always be encapsulated in quotation marks", "filename": "test.sls", "linenumber": 5, "line": " - mode: 0755", "severity": "HIGH"}]'
\ ])
Execute(The salt handler should parse lines correctly and show error in severity not HIGH):
AssertEqual
\ [
\ {
\ 'lnum': 27,
\ 'code': 204,
\ 'text': 'Lines should be no longer that 160 chars',
\ 'type': 'W'
\ }
\ ],
\ ale_linters#salt#salt_lint#Handle(255, [
\ '[{"id": "204", "message": "Lines should be no longer that 160 chars", "filename": "test2.sls", "linenumber": 27, "line": "this line is definitely longer than 160 chars, this line is definitely longer than 160 chars, this line is definitely longer than 160 chars", "severity": "VERY_LOW"}]'
\ ])

View File

@@ -0,0 +1,52 @@
Before:
runtime ale_linters/yaml/spectral.vim
After:
call ale#linter#Reset()
Execute(spectral handler should parse lines correctly):
AssertEqual
\ [
\ {
\ 'lnum': 1,
\ 'col': 1,
\ 'code': 'oas3-api-servers',
\ 'text': 'OpenAPI `servers` must be present and non-empty array.',
\ 'type': 'W'
\ },
\ {
\ 'lnum': 1,
\ 'col': 1,
\ 'code': 'oas3-schema',
\ 'text': 'Object should have required property `paths`.',
\ 'type': 'E'
\ },
\ {
\ 'lnum': 1,
\ 'col': 1,
\ 'code': 'openapi-tags',
\ 'text': 'OpenAPI object should have non-empty `tags` array.',
\ 'type': 'W'
\ },
\ {
\ 'lnum': 3,
\ 'col': 6,
\ 'code': 'info-contact',
\ 'text': 'Info object should contain `contact` object.',
\ 'type': 'W'
\ },
\ {
\ 'lnum': 3,
\ 'col': 6,
\ 'code': 'oas3-schema',
\ 'text': '`info` property should have required property `version`.',
\ 'type': 'E'
\ },
\ ],
\ ale#handlers#spectral#HandleSpectralOutput(bufnr(''), [
\ 'openapi.yml:1:1 warning oas3-api-servers "OpenAPI `servers` must be present and non-empty array."',
\ 'openapi.yml:1:1 error oas3-schema "Object should have required property `paths`."',
\ 'openapi.yml:1:1 warning openapi-tags "OpenAPI object should have non-empty `tags` array."',
\ 'openapi.yml:3:6 warning info-contact "Info object should contain `contact` object."',
\ 'openapi.yml:3:6 error oas3-schema "`info` property should have required property `version`."',
\ ])

View File

@@ -0,0 +1,34 @@
Before:
runtime ale_linters/php/tlint.vim
After:
call ale#linter#Reset()
Execute(The tlint handler should calculate line numbers):
AssertEqual
\ [
\ {
\ 'lnum': '5',
\ 'col': 0,
\ 'sub_type':
\ 'style',
\ 'type': 'W',
\ 'text': ['! There should be no unused imports.', 'There should be no unused imports.', '', '', '', '', '', '', '', '']
\ },
\ {
\ 'lnum': '15',
\ 'col': 0,
\ 'sub_type':
\ 'style',
\ 'type': 'W',
\ 'text': ['! There should be no method visibility in test methods.', 'There should be no method visibility in test methods.', '', '', '', '', '', '', '', '']
\ },
\ ],
\ ale_linters#php#tlint#Handle(347, [
\ "Lints for /Users/jose/Code/Tighten/tester/tests/Unit/ExampleTest.php",
\ "============",
\ "! There should be no unused imports.",
\ "5 : `use Illuminate\Foundation\Testing\RefreshDatabase;`",
\ "! There should be no method visibility in test methods.",
\ "15 : ` public function testBasicTest()`",
\ ])

View File

@@ -0,0 +1,54 @@
Before:
runtime ale_linters/vala/vala_lint.vim
After:
call ale#linter#Reset()
Execute(The Vala-Lint handler should parse lines correctly):
AssertEqual
\ [
\ {
\ 'lnum': 18,
\ 'col': 18,
\ 'text': 'Expected space before paren',
\ 'code': 'space-before-paren',
\ 'type': 'E',
\ },
\ {
\ 'lnum': 64,
\ 'col': 37,
\ 'text': 'Expected space before paren',
\ 'code': 'space-before-paren',
\ 'type': 'W',
\ },
\ {
\ 'lnum': 73,
\ 'col': 37,
\ 'text': 'Expected space before paren',
\ 'code': 'space-before-paren',
\ 'type': 'E',
\ },
\ ],
\ ale_linters#vala#vala_lint#Handle(bufnr(''), [
\ 'Application.vala',
\ ' 18.18 error Expected space before paren space-before-paren',
\ ' 64.37 warn Expected space before paren space-before-paren',
\ ' 73.37 error Expected space before paren space-before-paren',
\ ])
Execute(The Vala-Lint handler should ignore unknown error types):
AssertEqual
\ [
\ {
\ 'lnum': 73,
\ 'col': 37,
\ 'text': 'Expected space before paren',
\ 'code': 'space-before-paren',
\ 'type': 'E',
\ },
\ ],
\ ale_linters#vala#vala_lint#Handle(bufnr(''), [
\ 'Application.vala',
\ ' 18.18 test Expected space before paren space-before-paren',
\ ' 73.37 error Expected space before paren space-before-paren',
\ ])

View File

@@ -3,7 +3,7 @@ Before:
let g:ale_warn_about_trailing_whitespace = 1
runtime! ale_linters/yaml/yamllint.vim
runtime! ale/handlers/yamllint.vim
After:
Restore
@@ -29,7 +29,7 @@ Execute(Problems should be parsed correctly for yamllint):
\ 'text': 'syntax error: expected the node content, but found ''<stream end>''',
\ },
\ ],
\ ale_linters#yaml#yamllint#Handle(bufnr(''), [
\ ale#handlers#yamllint#Handle(bufnr(''), [
\ 'something.yaml:1:1: [warning] missing document start "---" (document-start)',
\ 'something.yml:2:1: [error] syntax error: expected the node content, but found ''<stream end>''',
\ ])
@@ -45,7 +45,7 @@ Execute(The yamllint handler should respect ale_warn_about_trailing_whitespace):
\ 'code': 'trailing-spaces',
\ },
\ ],
\ ale_linters#yaml#yamllint#Handle(bufnr(''), [
\ ale#handlers#yamllint#Handle(bufnr(''), [
\ 'something.yml:5:18: [error] trailing spaces (trailing-spaces)',
\ ])
@@ -54,6 +54,6 @@ Execute(The yamllint handler should respect ale_warn_about_trailing_whitespace):
AssertEqual
\ [
\ ],
\ ale_linters#yaml#yamllint#Handle(bufnr(''), [
\ ale#handlers#yamllint#Handle(bufnr(''), [
\ 'something.yml:5:18: [error] trailing spaces (trailing-spaces)',
\ ])

View File

@@ -23,6 +23,7 @@ Before:
\ 'completion_trigger_characters': [],
\ 'definition': 0,
\ 'symbol_search': 0,
\ 'code_actions': 0,
\ },
\}
@@ -102,6 +103,7 @@ Execute(Capabilities should bet set up correctly):
\ 'definition': 1,
\ 'symbol_search': 1,
\ 'rename': 1,
\ 'code_actions': 1,
\ },
\ b:conn.capabilities
AssertEqual [[1, 'initialized', {}]], g:message_list
@@ -125,7 +127,7 @@ Execute(Disabled capabilities should be recognised correctly):
\ 'referencesProvider': v:false,
\ 'textDocumentSync': 2,
\ 'documentFormattingProvider': v:true,
\ 'codeActionProvider': v:true,
\ 'codeActionProvider': v:false,
\ 'signatureHelpProvider': {
\ 'triggerCharacters': ['(', ','],
\ },
@@ -146,6 +148,7 @@ Execute(Disabled capabilities should be recognised correctly):
\ 'definition': 0,
\ 'symbol_search': 0,
\ 'rename': 0,
\ 'code_actions': 0,
\ },
\ b:conn.capabilities
AssertEqual [[1, 'initialized', {}]], g:message_list
@@ -197,6 +200,7 @@ Execute(Capabilities should be enabled when send as Dictionaries):
\ 'typeDefinition': 1,
\ 'symbol_search': 1,
\ 'rename': 1,
\ 'code_actions': 1,
\ },
\ b:conn.capabilities
AssertEqual [[1, 'initialized', {}]], g:message_list

View File

0
test/nix/test.nix Normal file
View File

View File

@@ -0,0 +1,14 @@
" Author: jD91mZM2 <me@krake.one>
" Description: Tests for rnix-lsp language client
Before:
call ale#assert#SetUpLinterTest('nix', 'rnix_lsp')
After:
call ale#assert#TearDownLinterTest()
Execute(should start rnix-lsp):
call ale#test#SetFilename('./test.nix')
AssertLSPLanguage 'nix'
AssertLSPOptions {}
AssertLSPProject ale#path#Simplify('.')

View File

@@ -0,0 +1,5 @@
#!/usr/bin/env bash
set -e
grep --exclude=tags -roh '\*.*\*$' doc | sort | uniq -d

View File

@@ -15,14 +15,13 @@ while read -r; do
if [[ "$REPLY" =~ ^! ]]; then
language="${REPLY/!/}"
else
# shellcheck disable=SC2001
echo "$language - $REPLY"
fi
done < <(
grep '^\*\|^ *\*' doc/ale-supported-languages-and-tools.txt \
| sed -e '1,2d' \
| sed 's/^\* */!/' \
| sed 's/^ *\* *\|!!\|\^\|(.*)\|`//g' \
| sed -E 's/^ *\* *|!!|\^|\(.*\)|`//g' \
| sed 's/ *$//'
) > "$doc_file"
@@ -30,13 +29,12 @@ while read -r; do
if [[ "$REPLY" =~ ^! ]]; then
language="${REPLY/!/}"
else
# shellcheck disable=SC2001
echo "$language - $REPLY"
fi
done < <(
grep '^\*\|^ *\*' supported-tools.md \
| sed 's/^\* */!/' \
| sed 's/^ *\* *\|:floppy_disk:\|:warning:\|(.*)\|\[\|\].*\|-n flag//g' \
| sed -E 's/^ *\* *|:floppy_disk:|:warning:|\(.*\)|\[|\].*|-n flag//g' \
| sed 's/ *$//'
) > "$readme_file"

11
test/script/check-tag-alignment Executable file
View File

@@ -0,0 +1,11 @@
#!/usr/bin/env bash
exit_code=0
# Documentation tags need to be aligned to the right margin, so look for
# tags which aren't at the right margin.
grep ' \*[^*]\+\*$' doc/ -r \
| awk '{ sep = index($0, ":"); if (length(substr($0, sep + 1 )) < 79) { print } }' \
| grep . && exit_code=1
exit $exit_code

View File

@@ -0,0 +1,22 @@
#!/usr/bin/env bash
set -e
exit_code=0
tag_regex='[gb]\?:\?\(ale\|ALE\)[a-zA-Z_\-]\+'
tags="$(mktemp -t tags.XXXXXXXX)"
refs="$(mktemp -t refs.XXXXXXXX)"
# Grep for tags and references, and complain if we find a reference without
# a tag for the reference. Only our tags will be included.
grep --exclude=tags -roh "\\*$tag_regex\\*" doc | sed 's/*//g' | sort -u > "$tags"
grep --exclude=tags -roh "|$tag_regex|" doc | sed 's/|//g' | sort -u > "$refs"
exit_code=0
if ! [[ $(comm -23 $refs $tags | wc -l) -eq 0 ]]; then
exit_code=1
fi
rm "$tags"
rm "$refs"

View File

@@ -35,7 +35,7 @@ sed -n "$toc_start_line,$toc_end_line"p doc/ale.txt \
> "$toc_file"
# Get all of the doc files in a natural sorted order.
doc_files="$(/usr/bin/env ls -1v doc | grep ^ale- | sed 's/^/doc\//' | paste -sd ' ' -)"
doc_files="$(/usr/bin/env ls -1v doc | grep '^ale-' | sed 's/^/doc\//' | paste -sd ' ' -)"
# shellcheck disable=SC2086
grep -h '\*ale-.*-options\|^[a-z].*\*ale-.*\*$' $doc_files \

View File

@@ -13,7 +13,7 @@ echo 'Custom warnings/errors follow:'
echo
set -o pipefail
docker run -a stdout "${docker_flags[@]}" test/script/custom-linting-rules . || exit_code=$?
docker run "${docker_flags[@]}" test/script/custom-linting-rules . || exit_code=$?
set +o pipefail
echo
@@ -23,7 +23,10 @@ echo '========================================'
echo 'Duplicate tags follow:'
echo
grep --exclude=tags -roh '\*.*\*$' doc | sort | uniq -d || exit_code=$?
set -o pipefail
docker run "${docker_flags[@]}" test/script/check-duplicate-tags . || exit_code=$?
set +o pipefail
echo
echo '========================================'
echo 'Checking for invalid tag references'
@@ -31,14 +34,9 @@ echo '========================================'
echo 'Invalid tag references tags follow:'
echo
tag_regex='[gb]\?:\?\(ale\|ALE\)[a-zA-Z_\-]\+'
# Grep for tags and references, and complain if we find a reference without
# a tag for the reference. Only our tags will be included.
diff -u \
<(grep --exclude=tags -roh "\\*$tag_regex\\*" doc | sort -u | sed 's/*//g') \
<(grep --exclude=tags -roh "|$tag_regex|" doc | sort -u | sed 's/|//g') \
| grep '^+[^+]' && exit_code=1
set -o pipefail
docker run "${docker_flags[@]}" test/script/check-tag-references || exit_code=$?
set +o pipefail
echo '========================================'
echo 'diff supported-tools.md and doc/ale-supported-languages-and-tools.txt tables'
@@ -46,7 +44,9 @@ echo '========================================'
echo 'Differences follow:'
echo
test/script/check-supported-tools-tables || exit_code=$?
set -o pipefail
docker run "${docker_flags[@]}" test/script/check-supported-tools-tables || exit_code=$?
set +o pipefail
echo '========================================'
echo 'Look for badly aligned doc tags'
@@ -54,18 +54,18 @@ echo '========================================'
echo 'Badly aligned tags follow:'
echo
# Documentation tags need to be aligned to the right margin, so look for
# tags which aren't at the right margin.
grep ' \*[^*]\+\*$' doc/ -r \
| awk '{ sep = index($0, ":"); if (length(substr($0, sep + 1 )) < 79) { print } }' \
| grep . && exit_code=1
set -o pipefail
docker run "${docker_flags[@]}" test/script/check-tag-alignment || exit_code=$?
set +o pipefail
echo '========================================'
echo 'Look for table of contents issues'
echo '========================================'
echo
test/script/check-toc || exit_code=$?
set -o pipefail
docker run "${docker_flags[@]}" test/script/check-toc || exit_code=$?
set +o pipefail
echo '========================================'
echo 'Check Python code'

View File

@@ -53,17 +53,29 @@ check_errors() {
regex="$1"
message="$2"
include_arg=''
exclude_arg=''
if [ $# -gt 2 ]; then
include_arg="--include $3"
fi
if [ $# -gt 3 ]; then
shift
shift
shift
while (( "$#" )); do
exclude_arg="$exclude_arg --exclude $1"
shift
done
fi
for directory in "${directories[@]}"; do
# shellcheck disable=SC2086
while read -r; do
RETURN_CODE=1
echo "$REPLY $message"
done < <(grep -H -n "$regex" $include_arg "$directory"/**/*.vim \
done < <(grep -H -n "$regex" $include_arg $exclude_arg "$directory"/**/*.vim \
| grep -v 'no-custom-checks' \
| grep -o '^[^:]\+:[0-9]\+' \
| sed 's:^\./::')
@@ -92,7 +104,7 @@ if (( FIX_ERRORS )); then
done
fi
# The arguments are: regex, explanation, [filename_filter]
# The arguments are: regex, explanation, [filename_filter], [list, of, exclusions]
check_errors \
'^function.*) *$' \
'Function without abort keyword (See :help except-compat)'
@@ -114,7 +126,10 @@ check_errors '==?' "Use 'is?' instead of '==?'. 0 ==? 'foobar' is true"
check_errors '!=#' "Use 'isnot#' instead of '!=#'. 0 !=# 'foobar' is false"
check_errors '!=?' "Use 'isnot?' instead of '!=?'. 0 !=? 'foobar' is false"
check_errors '^ *:\?echo' "Stray echo line. Use \`execute echo\` if you want to echo something"
check_errors $'name.:.*\'[a-z_]*[^a-z_0-9][a-z_0-9]*\',$' 'Use snake_case names for linters' '*/ale_linters/*'
# Exclusions for grandfathered-in exceptions
exclusions="clojure/clj_kondo.vim elixir/elixir_ls.vim go/golangci_lint.vim swift/swiftformat.vim"
# shellcheck disable=SC2086
check_errors $'name.:.*\'[a-z_]*[^a-z_0-9][a-z_0-9]*\',$' 'Use snake_case names for linters' '*/ale_linters/*' $exclusions
# Checks for improving type checks.
check_errors $'\\(==.\\?\\|is\\) type([\'"]\+)' "Use 'is v:t_string' instead"
check_errors '\(==.\?\|is\) type([0-9]\+)' "Use 'is v:t_number' instead"

View File

@@ -482,6 +482,7 @@ Execute(We should include several important flags):
\ . ' -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'))
\ . ' -imacros ' . ale#Escape(ale#path#Simplify(g:dir . '/test_c_projects/makefile_project/incmacros'))
\ . ' -Dmacro="value"'
\ . ' -DGoal=9'
\ . ' -D macro2'
@@ -511,6 +512,8 @@ Execute(We should include several important flags):
\ 'incframework',
\ '-include',
\ '''foo bar''',
\ '-imacros',
\ 'incmacros',
\ '-Dmacro="value"',
\ '-DGoal=9',
\ '-D',
@@ -559,6 +562,7 @@ Execute(We should quote the flags we need to quote):
\ . ' -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'))
\ . ' -imacros ' . ale#Escape(ale#path#Simplify(g:dir . '/test_c_projects/makefile_project/incmacros'))
\ . ' ' . ale#Escape('-Dmacro="value"')
\ . ' -DGoal=9'
\ . ' -D macro2'
@@ -591,6 +595,8 @@ Execute(We should quote the flags we need to quote):
\ 'incframework',
\ '-include',
\ '''foo bar''',
\ '-imacros',
\ 'incmacros',
\ '-Dmacro="value"',
\ '-DGoal=9',
\ '-D',

View File

@@ -3,6 +3,9 @@ Before:
let g:ale_enabled = 0
" Enable fix end-of-line as tests below expect that
set fixeol
runtime autoload/ale/code_action.vim
runtime autoload/ale/util.vim
@@ -211,6 +214,7 @@ Execute(End of file can be modified):
\)
AssertEqual g:test.text + [
\ '',
\ 'type A: string',
\ 'type B: number',
\ '',

View File

@@ -0,0 +1,59 @@
Given python(An example Python file):
def main():
a = 1
c = a + 1
Execute():
let g:changes = [
\ {'end': {'offset': 7, 'line': 1}, 'newText': 'func_qtffgsv', 'start': {'offset': 5, 'line': 1}},
\ {'end': {'offset': 9, 'line': 1}, 'newText': '', 'start': {'offset': 8, 'line': 1}},
\ {'end': {'offset': 15, 'line': 3}, 'newText': " return c\n\n\ndef main():\n c = func_qtffgsvi()\n", 'start': {'offset': 15, 'line': 3}}
\]
call ale#code_action#ApplyChanges(expand('%:p'), g:changes, 0)
Expect(The changes should be applied correctly):
def func_qtffgsvi():
a = 1
c = a + 1
return c
def main():
c = func_qtffgsvi()
Given python(Second python example):
import sys
import exifread
def main():
with open(sys.argv[1], 'rb') as f:
exif = exifread.process_file(f)
dt = str(exif['Image DateTime'])
date = dt[:10].replace(':', '-')
Execute():
let g:changes = [
\ {'end': {'offset': 16, 'line': 2}, 'newText': "\n\ndef func_ivlpdpao(f):\n exif = exifread.process_file(f)\n dt = str(exif['Image DateTime'])\n date = dt[:10].replace(':', '-')\n return date\n", 'start': {'offset': 16, 'line': 2}},
\ {'end': {'offset': 32, 'line': 6}, 'newText': 'date = func', 'start': {'offset': 9, 'line': 6}},
\ {'end': {'offset': 42, 'line': 8}, 'newText': "ivlpdpao(f)\n", 'start': {'offset': 33, 'line': 6}}
\]
call ale#code_action#ApplyChanges(expand('%:p'), g:changes, 0)
Expect(The changes should be applied correctly):
import sys
import exifread
def func_ivlpdpao(f):
exif = exifread.process_file(f)
dt = str(exif['Image DateTime'])
date = dt[:10].replace(':', '-')
return date
def main():
with open(sys.argv[1], 'rb') as f:
date = func_ivlpdpao(f)

549
test/test_codefix.vader Normal file
View File

@@ -0,0 +1,549 @@
Before:
call ale#test#SetDirectory('/testplugin/test')
call ale#test#SetFilename('dummy.txt')
Save g:ale_buffer_info
let g:ale_buffer_info = {}
let g:old_filename = expand('%:p')
let g:Callback = ''
let g:expr_list = []
let g:message_list = []
let g:handle_code_action_called = 0
let g:code_actions = []
let g:options = {}
let g:capability_checked = ''
let g:conn_id = v:null
let g:InitCallback = v:null
runtime autoload/ale/lsp_linter.vim
runtime autoload/ale/lsp.vim
runtime autoload/ale/util.vim
runtime autoload/ale/codefix.vim
runtime autoload/ale/code_action.vim
function! ale#lsp_linter#StartLSP(buffer, linter, Callback) abort
let g:conn_id = ale#lsp#Register('executable', '/foo/bar', {})
call ale#lsp#MarkDocumentAsOpen(g:conn_id, a:buffer)
if a:linter.lsp is# 'tsserver'
call ale#lsp#MarkConnectionAsTsserver(g:conn_id)
endif
let l:details = {
\ 'command': 'foobar',
\ 'buffer': a:buffer,
\ 'connection_id': g:conn_id,
\ 'project_root': '/foo/bar',
\}
let g:InitCallback = {-> ale#lsp_linter#OnInit(a:linter, l:details, a:Callback)}
endfunction
function! ale#lsp#HasCapability(conn_id, capability) abort
let g:capability_checked = a:capability
return 1
endfunction
function! ale#lsp#RegisterCallback(conn_id, callback) abort
let g:Callback = a:callback
endfunction
function! ale#lsp#Send(conn_id, message) abort
call add(g:message_list, a:message)
return 42
endfunction
function! ale#util#Execute(expr) abort
call add(g:expr_list, a:expr)
endfunction
function! ale#code_action#HandleCodeAction(code_action, options) abort
let g:handle_code_action_called = 1
Assert !get(a:options, 'should_save')
call add(g:code_actions, a:code_action)
endfunction
function! ale#util#Input(message, value) abort
return '2'
endfunction
After:
Restore
if g:conn_id isnot v:null
call ale#lsp#RemoveConnectionWithID(g:conn_id)
endif
call ale#test#RestoreDirectory()
call ale#linter#Reset()
unlet! g:capability_checked
unlet! g:InitCallback
unlet! g:old_filename
unlet! g:conn_id
unlet! g:Callback
unlet! g:message_list
unlet! g:expr_list
unlet! b:ale_linters
unlet! g:options
unlet! g:code_actions
unlet! g:handle_code_action_called
runtime autoload/ale/lsp_linter.vim
runtime autoload/ale/lsp.vim
runtime autoload/ale/util.vim
runtime autoload/ale/codefix.vim
runtime autoload/ale/code_action.vim
Execute(Failed codefix responses should be handled correctly):
call ale#codefix#HandleTSServerResponse(
\ 1,
\ {'command': 'getCodeFixes', 'request_seq': 3}
\)
AssertEqual g:handle_code_action_called, 0
Given typescript(Some typescript file):
foo
somelongerline ()
bazxyzxyzxyz
Execute(getCodeFixes from tsserver should be handled):
call ale#codefix#SetMap({3: {}})
call ale#codefix#HandleTSServerResponse(1, {
\ 'command': 'getCodeFixes',
\ 'request_seq': 3,
\ 'success': v:true,
\ 'type': 'response',
\ 'body': [
\ {
\ 'description': 'Import default "x" from module "./z"',
\ 'fixName': 'import',
\ 'changes': [
\ {
\ 'fileName': "/foo/bar/file1.ts",
\ 'textChanges': [
\ {
\ 'end': {
\ 'line': 2,
\ 'offset': 1,
\ },
\ 'newText': 'import x from "./z";^@',
\ 'start': {
\ 'line': 2,
\ 'offset': 1,
\ }
\ }
\ ]
\ }
\ ]
\ }
\ ]
\})
AssertEqual g:handle_code_action_called, 1
AssertEqual
\ [
\ {
\ 'description': 'codefix',
\ 'changes': [
\ {
\ 'fileName': "/foo/bar/file1.ts",
\ 'textChanges': [
\ {
\ 'end': {
\ 'line': 2,
\ 'offset': 1
\ },
\ 'newText': 'import x from "./z";^@',
\ 'start': {
\ 'line': 2,
\ 'offset': 1
\ }
\ }
\ ]
\ }
\ ]
\ }
\ ],
\ g:code_actions
Execute(getCodeFixes from tsserver should be handled with user input if there are more than one action):
call ale#codefix#SetMap({3: {}})
call ale#codefix#HandleTSServerResponse(1, {
\ 'command': 'getCodeFixes',
\ 'request_seq': 3,
\ 'success': v:true,
\ 'type': 'response',
\ 'body': [
\ {
\ 'description': 'Import default "x" from module "./z"',
\ 'fixName': 'import',
\ 'changes': [
\ {
\ 'fileName': "/foo/bar/file1.ts",
\ 'textChanges': [
\ {
\ 'end': {
\ 'line': 2,
\ 'offset': 1,
\ },
\ 'newText': 'import x from "./z";^@',
\ 'start': {
\ 'line': 2,
\ 'offset': 1,
\ }
\ }
\ ]
\ }
\ ]
\ },
\ {
\ 'description': 'Import default "x" from module "./y"',
\ 'fixName': 'import',
\ 'changes': [
\ {
\ 'fileName': "/foo/bar/file1.ts",
\ 'textChanges': [
\ {
\ 'end': {
\ 'line': 2,
\ 'offset': 1,
\ },
\ 'newText': 'import x from "./y";^@',
\ 'start': {
\ 'line': 2,
\ 'offset': 1,
\ }
\ }
\ ]
\ }
\ ]
\ }
\ ]
\})
AssertEqual g:handle_code_action_called, 1
AssertEqual
\ [
\ {
\ 'description': 'codefix',
\ 'changes': [
\ {
\ 'fileName': "/foo/bar/file1.ts",
\ 'textChanges': [
\ {
\ 'end': {
\ 'line': 2,
\ 'offset': 1
\ },
\ 'newText': 'import x from "./y";^@',
\ 'start': {
\ 'line': 2,
\ 'offset': 1
\ }
\ }
\ ]
\ }
\ ]
\ }
\ ],
\ g:code_actions
Execute(Prints a tsserver error message when getCodeFixes unsuccessful):
call ale#codefix#SetMap({3: {}})
call ale#codefix#HandleTSServerResponse(1, {
\ 'command': 'getCodeFixes',
\ 'request_seq': 3,
\ 'success': v:false,
\ 'message': 'something is wrong',
\})
AssertEqual g:handle_code_action_called, 0
AssertEqual ['echom ''Error while getting code fixes. Reason: something is wrong'''], g:expr_list
Execute(Does nothing when where are no code fixes):
call ale#codefix#SetMap({3: {}})
call ale#codefix#HandleTSServerResponse(1, {
\ 'command': 'getCodeFixes',
\ 'request_seq': 3,
\ 'success': v:true,
\ 'body': []
\})
AssertEqual g:handle_code_action_called, 0
AssertEqual ['echom ''No code fixes available.'''], g:expr_list
Execute(tsserver codefix requests should be sent):
call ale#linter#Reset()
runtime ale_linters/typescript/tsserver.vim
let g:ale_buffer_info = {bufnr(''): {'loclist': [{'lnum': 2, 'col': 5, 'code': 2304}]}}
call setpos('.', [bufnr(''), 2, 16, 0])
" ALECodeAction
call ale#codefix#Execute(0)
" We shouldn't register the callback yet.
AssertEqual '''''', string(g:Callback)
AssertEqual type(function('type')), type(g:InitCallback)
call g:InitCallback()
AssertEqual 'code_actions', g:capability_checked
AssertEqual
\ 'function(''ale#codefix#HandleTSServerResponse'')',
\ string(g:Callback)
AssertEqual
\ [
\ ale#lsp#tsserver_message#Change(bufnr('')),
\ [0, 'ts@getCodeFixes', {
\ 'startLine': 2,
\ 'startOffset': 16,
\ 'endLine': 2,
\ 'endOffset': 17,
\ 'file': expand('%:p'),
\ 'errorCodes': [2304],
\ }]
\ ],
\ g:message_list
Execute(tsserver codefix requests should be sent only for error with code):
call ale#linter#Reset()
runtime ale_linters/typescript/tsserver.vim
let g:ale_buffer_info = {bufnr(''): {'loclist': [{'lnum': 2, 'col': 16}, {'lnum': 2, 'col': 16, 'code': 2304}]}}
call setpos('.', [bufnr(''), 2, 16, 0])
" ALECodeAction
call ale#codefix#Execute(0)
" We shouldn't register the callback yet.
AssertEqual '''''', string(g:Callback)
AssertEqual type(function('type')), type(g:InitCallback)
call g:InitCallback()
AssertEqual 'code_actions', g:capability_checked
AssertEqual
\ 'function(''ale#codefix#HandleTSServerResponse'')',
\ string(g:Callback)
AssertEqual
\ [
\ ale#lsp#tsserver_message#Change(bufnr('')),
\ [0, 'ts@getCodeFixes', {
\ 'startLine': 2,
\ 'startOffset': 16,
\ 'endLine': 2,
\ 'endOffset': 17,
\ 'file': expand('%:p'),
\ 'errorCodes': [2304],
\ }]
\ ],
\ g:message_list
Execute(getApplicableRefactors from tsserver should be handled):
call ale#codefix#SetMap({3: {
\ 'buffer': expand('%:p'),
\ 'line': 1,
\ 'column': 2,
\ 'end_line': 3,
\ 'end_column': 4,
\ 'connection_id': 0,
\}})
call ale#codefix#HandleTSServerResponse(1,
\ {'seq': 0, 'request_seq': 3, 'type': 'response', 'success': v:true, 'body': [{'actions': [{'description': 'Extract to constant in enclosing scope', 'name': 'constant_scope_0'}], 'description': 'Extract constant', 'name': 'Extract Symbol'}, {'actions': [{'description': 'Extract to function in module scope', 'name': 'function_scope_1'}], 'description': 'Extract function', 'name': 'Extract Symbol'}], 'command': 'getApplicableRefactors'})
AssertEqual
\ [
\ [0, 'ts@getEditsForRefactor', {
\ 'startLine': 1,
\ 'startOffset': 2,
\ 'endLine': 3,
\ 'endOffset': 5,
\ 'file': expand('%:p'),
\ 'refactor': 'Extract Symbol',
\ 'action': 'function_scope_1',
\ }]
\ ],
\ g:message_list
Execute(getApplicableRefactors should print error on failure):
call ale#codefix#SetMap({3: {
\ 'buffer': expand('%:p'),
\ 'line': 1,
\ 'column': 2,
\ 'end_line': 3,
\ 'end_column': 4,
\ 'connection_id': 0,
\}})
call ale#codefix#HandleTSServerResponse(1,
\ {'seq': 0, 'request_seq': 3, 'type': 'response', 'success': v:false, 'message': 'oops', 'command': 'getApplicableRefactors'})
AssertEqual ['echom ''Error while getting applicable refactors. Reason: oops'''], g:expr_list
Execute(getApplicableRefactors should do nothing if there are no refactors):
call ale#codefix#SetMap({3: {
\ 'buffer': expand('%:p'),
\ 'line': 1,
\ 'column': 2,
\ 'end_line': 3,
\ 'end_column': 4,
\ 'connection_id': 0,
\}})
call ale#codefix#HandleTSServerResponse(1,
\ {'seq': 0, 'request_seq': 3, 'type': 'response', 'success': v:true, 'body': [], 'command': 'getApplicableRefactors'})
AssertEqual ['echom ''No applicable refactors available.'''], g:expr_list
Execute(getEditsForRefactor from tsserver should be handled):
call ale#codefix#SetMap({3: {}})
call ale#codefix#HandleTSServerResponse(1,
\{'seq': 0, 'request_seq': 3, 'type': 'response', 'success': v:true, 'body': {'edits': [{'fileName': '/foo/bar/file.ts', 'textChanges': [{'end': {'offset': 35, 'line': 9}, 'newText': 'newFunction(app);', 'start': {'offset': 3, 'line': 8}}, {'end': {'offset': 4, 'line': 19}, 'newText': '^@function newFunction(app: Router) {^@ app.use(booExpressCsrf());^@ app.use(booExpressRequireHttps);^@}^@', 'start': {'offset': 4, 'line': 19}}]}], 'renameLocation': {'offset': 3, 'line': 8}, 'renameFilename': '/foo/bar/file.ts'}, 'command': 'getEditsForRefactor' }
\)
AssertEqual g:handle_code_action_called, 1
AssertEqual
\ [
\ {
\ 'description': 'editsForRefactor',
\ 'changes': [{'fileName': '/foo/bar/file.ts', 'textChanges': [{'end': {'offset': 35, 'line': 9}, 'newText': 'newFunction(app);', 'start': {'offset': 3, 'line': 8}}, {'end': {'offset': 4, 'line': 19}, 'newText': '^@function newFunction(app: Router) {^@ app.use(booExpressCsrf());^@ app.use(booExpressRequireHttps);^@}^@', 'start': {'offset': 4, 'line': 19}}]}],
\ }
\ ],
\ g:code_actions
Execute(getEditsForRefactor should print error on failure):
call ale#codefix#SetMap({3: {}})
call ale#codefix#HandleTSServerResponse(1,
\{'seq': 0, 'request_seq': 3, 'type': 'response', 'success': v:false, 'message': 'oops', 'command': 'getEditsForRefactor' }
\)
AssertEqual ['echom ''Error while getting edits for refactor. Reason: oops'''], g:expr_list
Execute(Failed LSP responses should be handled correctly):
call ale#codefix#HandleLSPResponse(
\ 1,
\ {'method': 'workspace/applyEdit', 'request_seq': 3}
\)
AssertEqual g:handle_code_action_called, 0
Given python(Some python file):
def main():
a = 1
b = a + 2
Execute("workspace/applyEdit" from LSP should be handled):
call ale#codefix#SetMap({3: {}})
call ale#codefix#HandleLSPResponse(1,
\ {'id': 0, 'jsonrpc': '2.0', 'method': 'workspace/applyEdit', 'params': {'edit': {'changes': {'file:///foo/bar/file.ts': [{'range': {'end': {'character': 27, 'line': 7}, 'start': {'character': 27, 'line': 7}}, 'newText': ', Config'}, {'range': {'end': {'character': 12, 'line': 96}, 'start': {'character': 2, 'line': 94}}, 'newText': 'await newFunction(redis, imageKey, cover, config);'}, {'range': {'end': {'character': 2, 'line': 99}, 'start': {'character': 2, 'line': 99}}, 'newText': '^@async function newFunction(redis: IRedis, imageKey: string, cover: Buffer, config: Config) {^@ try {^@ await redis.set(imageKey, cover, ''ex'', parseInt(config.coverKeyTTL, 10));^@ }^@ catch { }^@}^@'}]}}}})
AssertEqual g:handle_code_action_called, 1
AssertEqual
\ [{'description': 'applyEdit', 'changes': [{'fileName': '/foo/bar/file.ts', 'textChanges': [{'end': {'offset': 28, 'line': 8}, 'newText': ', Config', 'start': {'offset': 28, 'line': 8}}, {'end': {'offset': 13, 'line': 97}, 'newText': 'await newFunction(redis, imageKey, cover, config);', 'start': {'offset': 3, 'line': 95}}, {'end': {'offset': 3, 'line': 100}, 'newText': '^@async function newFunction(redis: IRedis, imageKey: string, cover: Buffer, config: Config) {^@ try {^@ await redis.set(imageKey, cover, ''ex'', parseInt(config.coverKeyTTL, 10));^@ }^@ catch { }^@}^@', 'start': {'offset': 3, 'line': 100}}]}]}],
\ g:code_actions
Execute(Code Actions from LSP should be handled with user input if there are more than one action):
call ale#codefix#SetMap({2: {}})
call ale#codefix#HandleLSPResponse(1,
\ {'id': 2, 'jsonrpc': '2.0', 'result': [{'title': 'fake for testing'}, {'arguments': [{'documentChanges': [{'edits': [{'range': {'end': {'character': 31, 'line': 2}, 'start': {'character': 31, 'line': 2}}, 'newText': ', createVideo'}], 'textDocument': {'uri': 'file:///foo/bar/file.ts', 'version': 1}}]}], 'title': 'Add ''createVideo'' to existing import declaration from "./video"', 'command': '_typescript.applyWorkspaceEdit'}]})
AssertEqual g:handle_code_action_called, 1
AssertEqual
\ [{'description': 'codeaction', 'changes': [{'fileName': '/foo/bar/file.ts', 'textChanges': [{'end': {'offset': 32, 'line': 3}, 'newText': ', createVideo', 'start': {'offset': 32, 'line': 3}}]}]}],
\ g:code_actions
Execute(Code Actions from LSP should be handled when returned with documentChanges):
call ale#codefix#SetMap({2: {}})
call ale#codefix#HandleLSPResponse(1,
\ {'id': 2, 'jsonrpc': '2.0', 'result': [{'diagnostics': v:null, 'edit': {'changes': v:null, 'documentChanges': [{'edits': [{'range': {'end': {'character': 4, 'line': 2}, 'start': {'character': 4, 'line': 1}}, 'newText': ''}, {'range': {'end': {'character': 9, 'line': 2}, 'start': {'character': 8, 'line': 2}}, 'newText': '(1)'}], 'textDocument': {'uri': 'file:///foo/bar/test.py', 'version': v:null}}]}, 'kind': 'refactor.inline', 'title': 'Inline variable', 'command': v:null}, {'diagnostics': v:null, 'edit': {'changes': v:null, 'documentChanges': [{'edits': [{'range': {'end': {'character': 0, 'line': 0}, 'start': {'character': 0, 'line': 0}}, 'newText': 'def func_bomdjnxh():^@ a = 1return a^@^@^@'}, {'range': {'end': {'character': 9, 'line': 1}, 'start': {'character': 8, 'line': 1}}, 'newText': 'func_bomdjnxh()^@'}], 'textDocument': {'uri': 'file:///foo/bar/test.py', 'version': v:null}}]}, 'kind': 'refactor.extract', 'title': 'Extract expression into function ''func_bomdjnxh''', 'command': v:null}]})
AssertEqual g:handle_code_action_called, 1
AssertEqual
\ [{'description': 'codeaction', 'changes': [{'fileName': '/foo/bar/test.py', 'textChanges': [{'end': {'offset': 1, 'line': 1}, 'newText': 'def func_bomdjnxh():^@ a = 1return a^@^@^@', 'start': {'offset': 1, 'line': 1}}, {'end': {'offset': 10, 'line': 2}, 'newText': 'func_bomdjnxh()^@', 'start': {'offset': 9, 'line': 2}}]}]}],
\ g:code_actions
Execute(LSP Code Actions handles command responses):
call ale#codefix#SetMap({3: {
\ 'connection_id': 0,
\}})
call ale#codefix#HandleLSPResponse(1,
\ {'id': 3, 'jsonrpc': '2.0', 'result': [{'kind': 'refactor', 'title': 'Extract to inner function in function ''getVideo''', 'command': {'arguments': [{'file': '/foo/bar/file.ts', 'endOffset': 0, 'action': 'function_scope_0', 'startOffset': 1, 'startLine': 65, 'refactor': 'Extract Symbol', 'endLine': 68}], 'title': 'Extract to inner function in function ''getVideo''', 'command': '_typescript.applyRefactoring'}}, {'kind': 'refactor', 'title': 'Extract to function in module scope', 'command': {'arguments': [{'file': '/foo/bar/file.ts', 'endOffset': 0, 'action': 'function_scope_1', 'startOffset': 1, 'startLine': 65, 'refactor': 'Extract Symbol', 'endLine': 68}], 'title': 'Extract to function in module scope', 'command': '_typescript.applyRefactoring'}}]})
AssertEqual
\ [[0, 'workspace/executeCommand', {'arguments': [{'file': '/foo/bar/file.ts', 'action': 'function_scope_1', 'endOffset': 0, 'refactor': 'Extract Symbol', 'endLine': 68, 'startLine': 65, 'startOffset': 1}], 'command': '_typescript.applyRefactoring'}]],
\ g:message_list
Execute(Prints message when LSP code action returns no results):
call ale#codefix#SetMap({3: {}})
call ale#codefix#HandleLSPResponse(1,
\ {'id': 3, 'jsonrpc': '2.0', 'result': []})
AssertEqual g:handle_code_action_called, 0
AssertEqual ['echom ''No code actions received from server'''], g:expr_list
Execute(LSP code action requests should be sent):
call ale#linter#Reset()
runtime ale_linters/python/jedils.vim
let g:ale_buffer_info = {bufnr(''): {'loclist': [{'lnum': 2, 'col': 5, 'end_lnum': 2, 'end_col': 6, 'code': 2304, 'text': 'oops'}]}}
call setpos('.', [bufnr(''), 2, 5, 0])
" ALECodeAction
call ale#codefix#Execute(0)
" We shouldn't register the callback yet.
AssertEqual '''''', string(g:Callback)
AssertEqual type(function('type')), type(g:InitCallback)
call g:InitCallback()
AssertEqual 'code_actions', g:capability_checked
AssertEqual
\ 'function(''ale#codefix#HandleLSPResponse'')',
\ string(g:Callback)
AssertEqual
\ [
\ [0, 'textDocument/codeAction', {
\ 'context': {
\ 'diagnostics': [{'range': {'end': {'character': 6, 'line': 1}, 'start': {'character': 4, 'line': 1}}, 'code': 2304, 'message': 'oops'}]
\ },
\ 'range': {'end': {'character': 5, 'line': 1}, 'start': {'character': 4, 'line': 1}},
\ 'textDocument': {'uri': ale#path#ToURI(expand('%:p'))}
\ }]
\ ],
\ g:message_list[-1:]
Execute(LSP code action requests should be sent only for error with code):
call ale#linter#Reset()
runtime ale_linters/python/jedils.vim
let g:ale_buffer_info = {bufnr(''): {'loclist': [{'lnum': 2, 'col': 5, 'end_lnum': 2, 'end_col': 6, 'code': 2304, 'text': 'oops'}]}}
call setpos('.', [bufnr(''), 2, 5, 0])
" ALECodeAction
call ale#codefix#Execute(0)
" We shouldn't register the callback yet.
AssertEqual '''''', string(g:Callback)
AssertEqual type(function('type')), type(g:InitCallback)
call g:InitCallback()
AssertEqual 'code_actions', g:capability_checked
AssertEqual
\ 'function(''ale#codefix#HandleLSPResponse'')',
\ string(g:Callback)
AssertEqual
\ [
\ [0, 'textDocument/codeAction', {
\ 'context': {
\ 'diagnostics': [{'range': {'end': {'character': 6, 'line': 1}, 'start': {'character': 4, 'line': 1}}, 'code': 2304, 'message': 'oops'}]
\ },
\ 'range': {'end': {'character': 5, 'line': 1}, 'start': {'character': 4, 'line': 1}},
\ 'textDocument': {'uri': ale#path#ToURI(expand('%:p'))}
\ }]
\ ],
\ g:message_list[-1:]

View File

@@ -0,0 +1,19 @@
Before:
runtime autoload/ale/handlers/deno.vim
After:
unlet! g:ale_deno_executable
call ale#linter#Reset()
Execute(Default executable should be detected correctly):
AssertEqual
\ 'deno',
\ ale#handlers#deno#GetExecutable(bufnr(''))
Execute(User specified executable should override default):
let g:ale_deno_executable = '/path/to/deno-bin'
AssertEqual
\ '/path/to/deno-bin',
\ ale#handlers#deno#GetExecutable(bufnr(''))

View File

@@ -70,3 +70,10 @@ Execute(The defaults for the verilog filetype should be correct):
Execute(Default aliases for React should be defined):
AssertEqual ['javascript', 'jsx'], ale#linter#ResolveFiletype('javascriptreact')
AssertEqual ['typescript', 'tsx'], ale#linter#ResolveFiletype('typescriptreact')
Execute(The defaults for the apkbuild filetype should be correct):
AssertEqual ['apkbuild_lint', 'secfixes_check'], GetLinterNames('apkbuild')
let g:ale_linters_explicit = 1
AssertEqual [], GetLinterNames('apkbuild')

View File

@@ -0,0 +1,92 @@
Before:
let g:ale_floating_preview = 0
let g:ale_hover_to_floating_preview = 0
let g:ale_detail_to_floating_preview = 0
runtime autoload/ale/floating_preview.vim
let g:floated_lines = []
let g:floating_preview_show_called = 0
" Stub out so we can track the call
function! ale#floating_preview#Show(lines, ...) abort
let g:floating_preview_show_called = 1
let g:floated_lines = a:lines
endfunction
let g:ale_buffer_info = {
\ bufnr('%'): {
\ 'loclist': [
\ {
\ 'lnum': 1,
\ 'col': 10,
\ 'bufnr': bufnr('%'),
\ 'vcol': 0,
\ 'linter_name': 'notalinter',
\ 'nr': -1,
\ 'type': 'E',
\ 'code': 'semi',
\ 'text': "Missing semicolon.\r",
\ 'detail': "Every statement should end with a semicolon\nsecond line",
\ },
\ ],
\ }
\}
call ale#linter#Reset()
call ale#linter#PreventLoading('javascript')
After:
Restore
let g:ale_floating_preview = 0
let g:ale_hover_to_floating_preview = 0
let g:ale_detail_to_floating_preview = 0
call cursor(1, 1)
let g:ale_buffer_info = {}
" Close the preview window if it's open.
if &filetype is# 'ale-preview'
noautocmd :q!
endif
call ale#linter#Reset()
Given javascript(A file with warnings/errors):
var x = 3 + 12345678
var x = 5*2 + parseInt("10");
// comment
Execute(Floating preview is used with ALEDetail when g:ale_floating_preview set):
let g:ale_floating_preview = 1
call cursor(1, 10)
ALEDetail
let expected = ["Every statement should end with a semicolon", "second line"]
AssertEqual 1, g:floating_preview_show_called
AssertEqual expected, g:floated_lines
Execute(Floating preview is used with ALEDetail when g:ale_detail_to_floating_preview set):
let g:ale_detail_to_floating_preview = 1
call cursor(1, 10)
ALEDetail
let expected = ["Every statement should end with a semicolon", "second line"]
AssertEqual 1, g:floating_preview_show_called
AssertEqual expected, g:floated_lines
Execute(Floating preview is not used with ALEDetail by default):
call cursor(1, 10)
ALEDetail
AssertEqual 0, g:floating_preview_show_called

View File

@@ -7,9 +7,25 @@ Before:
let g:item_list = []
let g:show_message_arg_list = []
let g:ale_floating_preview = 0
let g:ale_hover_to_floating_preview = 0
let g:ale_detail_to_floating_preview = 0
runtime autoload/ale/linter.vim
runtime autoload/ale/lsp.vim
runtime autoload/ale/lsp_linter.vim
runtime autoload/ale/util.vim
runtime autoload/ale/floating_preview.vim
runtime autoload/ale/hover.vim
let g:floated_lines = []
let g:floating_preview_show_called = 0
" Stub out so we can track the call
function! ale#floating_preview#Show(lines, ...) abort
let g:floating_preview_show_called = 1
let g:floated_lines = a:lines
endfunction
function! ale#lsp_linter#StartLSP(buffer, linter, callback) abort
let g:Callback = a:callback
@@ -50,6 +66,7 @@ Before:
\)
endfunction
After:
call ale#hover#SetMap({})
call ale#test#RestoreDirectory()
@@ -65,6 +82,7 @@ After:
runtime autoload/ale/lsp_linter.vim
runtime autoload/ale/lsp.vim
runtime autoload/ale/util.vim
runtime autoload/ale/floating_preview.vim
Given python(Some Python file):
foo
@@ -101,7 +119,7 @@ Execute(tsserver quickinfo responses will null missing bodies should be handled)
AssertEqual {}, ale#hover#GetMap()
Execute(tsserver quickinfo displayString values should be displayed):
call ale#hover#SetMap({3: {}})
call ale#hover#SetMap({3: {'buffer': bufnr('')}})
call ale#hover#HandleTSServerResponse(
\ 1,
\ {
@@ -168,8 +186,30 @@ Execute(LSP hover response with lists of strings and marked strings should be ha
\], g:show_message_arg_list
AssertEqual {}, ale#hover#GetMap()
Execute(LSP hover with ale_floating_preview should float):
let g:ale_floating_preview = 1
call HandleValidLSPResult({'contents': "the message\ncontinuing"})
AssertEqual 1, g:floating_preview_show_called
AssertEqual ["the message", "continuing"], g:floated_lines
Execute(LSP hover ale_hover_to_floating_preview should float):
let g:ale_hover_to_floating_preview = 1
call HandleValidLSPResult({'contents': "the message\ncontinuing"})
AssertEqual 1, g:floating_preview_show_called
AssertEqual ["the message", "continuing"], g:floated_lines
Execute(LSP hover by default should not float):
call HandleValidLSPResult({'contents': "the message\ncontinuing"})
AssertEqual 0, g:floating_preview_show_called
Execute(tsserver responses for documentation requests should be handled):
call ale#hover#SetMap({3: {'show_documentation': 1}})
call ale#hover#SetMap({3: {'show_documentation': 1, 'buffer': bufnr('')}})
call ale#hover#HandleTSServerResponse(
\ 1,
@@ -187,3 +227,46 @@ Execute(tsserver responses for documentation requests should be handled):
" The preview window should show the text.
AssertEqual ['foo is a very good method'], ale#test#GetPreviewWindowText()
silent! pclose
Execute(hover with show_documentation should be in the preview window, not floating):
let g:ale_hover_to_floating_preview = 1
let g:ale_floating_preview = 1
call ale#hover#SetMap({3: {'show_documentation': 1, 'buffer': bufnr('')}})
call ale#hover#HandleTSServerResponse(
\ 1,
\ {
\ 'command': 'quickinfo',
\ 'request_seq': 3,
\ 'success': v:true,
\ 'body': {
\ 'documentation': 'foo is a very good method',
\ 'displayString': 'foo bar ',
\ },
\ }
\)
let expected = ["Every statement should end with a semicolon", "second line"]
AssertEqual 0, g:floating_preview_show_called
Execute(TSServer hover without show_documentation and ale_floating_preview should float):
let g:ale_floating_preview = 1
call ale#hover#SetMap({3: {'buffer': bufnr('')}})
call ale#hover#HandleTSServerResponse(
\ 1,
\ {
\ 'command': 'quickinfo',
\ 'request_seq': 3,
\ 'success': v:true,
\ 'body': {
\ 'displayString': "the message\ncontinuing",
\ },
\ }
\)
AssertEqual 1, g:floating_preview_show_called
AssertEqual ["the message", "continuing"], g:floated_lines

View File

@@ -35,7 +35,7 @@ After:
Execute(The file changed event function should set b:ale_file_changed):
let g:ale_lint_on_enter = 0
if has('gui')
if has('gui_running')
new
else
e test

View File

@@ -111,7 +111,7 @@ Execute(An initial list of semantic errors should be handled):
Assert g:ale_handle_loclist_called
Execute(Subsequent empty lists should be ignored):
Execute(Subsequent empty lists should be ignored - semantic):
let g:ale_buffer_info[bufnr('')].semantic_loclist = []
call ale#lsp_linter#HandleLSPResponse(1, CreateError('semanticDiag', ''))
@@ -138,3 +138,31 @@ Execute(Non-empty then non-empty semantic errors should be handled):
call ale#lsp_linter#HandleLSPResponse(1, CreateError('semanticDiag', 'x'))
Assert g:ale_handle_loclist_called
Execute(Subsequent empty lists should be ignored - suggestion):
let g:ale_buffer_info[bufnr('')].suggestion_loclist = []
call ale#lsp_linter#HandleLSPResponse(1, CreateError('suggestionDiag', ''))
Assert !g:ale_handle_loclist_called
Execute(Empty then non-empty suggestion messages should be handled):
let g:ale_buffer_info[bufnr('')].suggestion_loclist = []
call ale#lsp_linter#HandleLSPResponse(1, CreateError('suggestionDiag', 'x'))
Assert g:ale_handle_loclist_called
Execute(Non-empty then empt suggestion messages should be handled):
let g:ale_buffer_info[bufnr('')].suggestion_loclist = CreateLoclist('x')
call ale#lsp_linter#HandleLSPResponse(1, CreateError('suggestionDiag', ''))
Assert g:ale_handle_loclist_called
Execute(Non-empty then non-empty suggestion messages should be handled):
let g:ale_buffer_info[bufnr('')].suggestion_loclist = CreateLoclist('x')
call ale#lsp_linter#HandleLSPResponse(1, CreateError('suggestionDiag', 'x'))
Assert g:ale_handle_loclist_called

View File

@@ -269,7 +269,7 @@ Execute(tsserver rename requests should be sent):
\ }]
\ ],
\ g:message_list
AssertEqual {'42': {'old_name': 'somelongerline', 'new_name': 'a-new-name', 'force_save': 0}},
AssertEqual {'42': {'old_name': 'somelongerline', 'new_name': 'a-new-name'}},
\ ale#rename#GetMap()
Given python(Some Python file):
@@ -470,7 +470,7 @@ Execute(LSP rename requests should be sent):
let b:ale_linters = ['pyls']
call setpos('.', [bufnr(''), 1, 5, 0])
ALERename!
ALERename
" We shouldn't register the callback yet.
AssertEqual '''''', string(g:Callback)
@@ -500,5 +500,5 @@ Execute(LSP rename requests should be sent):
\ ],
\ g:message_list
AssertEqual {'42': {'old_name': 'foo', 'new_name': 'a-new-name', 'force_save': 1}},
AssertEqual {'42': {'old_name': 'foo', 'new_name': 'a-new-name'}},
\ ale#rename#GetMap()

View File

@@ -127,3 +127,51 @@ Execute(The dash dialect should be used for the shell and the base function):
Execute(dash should be used for shellcheck):
AssertEqual 'dash', ale#handlers#shellcheck#GetDialectArgument(bufnr(''))
Given(A file with a Bash shellcheck shell directive):
# shellcheck shell=bash
Execute(bash dialect should be detected appropriately):
AssertEqual 'bash', ale#handlers#shellcheck#GetDialectArgument(bufnr(''))
Given(A file with a sh shellcheck shell directive):
#shellcheck shell=sh
Execute(sh dialect should be detected appropriately):
AssertEqual 'sh', ale#handlers#shellcheck#GetDialectArgument(bufnr(''))
Given(A file with a tcsh shellcheck shell directive):
# shellcheck shell=tcsh
Execute(tcsh dialect should be detected appropriately):
AssertEqual 'tcsh', ale#handlers#shellcheck#GetDialectArgument(bufnr(''))
Given(A file with a zsh shellcheck shell directive):
# shellcheck shell=zsh
Execute(zsh dialect should be detected appropriately):
AssertEqual 'zsh', ale#handlers#shellcheck#GetDialectArgument(bufnr(''))
Given(A file with a csh shellcheck shell directive):
# shellcheck shell=csh
Execute(zsh dialect should be detected appropriately):
AssertEqual 'csh', ale#handlers#shellcheck#GetDialectArgument(bufnr(''))
Given(A file with a ksh shellcheck shell directive):
# shellcheck shell=ksh
Execute(ksh dialect should be detected appropriately):
AssertEqual 'ksh', ale#handlers#shellcheck#GetDialectArgument(bufnr(''))
Given(A file with a dash shellcheck shell directive):
# shellcheck shell=dash
Execute(dash dialect should be detected appropriately):
AssertEqual 'dash', ale#handlers#shellcheck#GetDialectArgument(bufnr(''))
Given(A file with a ash shellcheck shell directive):
# shellcheck shell=ash
Execute(dash dialect should be detected for ash that shellcheck does not support):
AssertEqual 'dash', ale#handlers#shellcheck#GetDialectArgument(bufnr(''))

0
test/typescript/test.ts Normal file
View File

View File

0
test/xo-test-files/monorepo/node_modules/xo/cli.js generated vendored Normal file
View File

View File