summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/command_callback/inko_paths/test.inko0
-rw-r--r--test/command_callback/inko_paths/tests/test/test_foo.inko0
-rw-r--r--test/command_callback/spectral_paths/node_modules/.bin/spectral0
-rw-r--r--test/command_callback/spectral_paths/openapi.yaml0
-rw-r--r--test/command_callback/test_adals_command_callbacks.vader17
-rw-r--r--test/command_callback/test_clang_tidy_command_callback.vader1
-rw-r--r--test/command_callback/test_dart_analysis_server_command_callback.vader15
-rw-r--r--test/command_callback/test_elixir_credo.vader7
-rw-r--r--test/command_callback/test_erlang_dialyzer_command_callback.vader8
-rw-r--r--test/command_callback/test_erlang_erlc_command_callback.vader40
-rw-r--r--test/command_callback/test_fecs_command_callback.vader1
-rw-r--r--test/command_callback/test_haskell_hls_callbacks.vader27
-rw-r--r--test/command_callback/test_ibm_openapi_validator_command_callback.vader15
-rw-r--r--test/command_callback/test_inko_inko_callbacks.vader20
-rw-r--r--test/command_callback/test_julia_languageserver_callbacks.vader8
-rw-r--r--test/command_callback/test_rust_analyzer_callbacks.vader4
-rw-r--r--test/command_callback/test_sorbet_command_callback.vader7
-rw-r--r--test/command_callback/test_spectral_command_callback.vader31
-rw-r--r--test/command_callback/test_terraform_ls_command_callback.vader61
-rw-r--r--test/command_callback/test_terraform_terraform_command_callback.vader8
-rw-r--r--test/command_callback/test_typescript_deno_lsp.vader60
-rw-r--r--test/command_callback/test_xo_command_callback.vader11
-rw-r--r--test/command_callback/test_xots_command_callback.vader23
-rw-r--r--test/completion/test_lsp_completion_parsing.vader87
-rw-r--r--test/completion/test_omnifunc_completion.vader6
-rw-r--r--test/dumb_named_pipe_server.py42
-rw-r--r--test/eslint-test-files/react-app/node_modules/xo/cli.js0
-rw-r--r--test/eslint-test-files/react-app/subdir/testfile.ts0
-rw-r--r--test/fixers/test_dhall_fixer_callback.vader11
-rw-r--r--test/fixers/test_dhall_format_fixer_callback.vader24
-rw-r--r--test/fixers/test_dhall_freeze_fixer_callback.vader24
-rw-r--r--test/fixers/test_dhall_lint_fixer_callback.vader22
-rw-r--r--test/fixers/test_isort_fixer_callback.vader10
-rw-r--r--test/fixers/test_standardrb_fixer_callback.vader12
-rw-r--r--test/fixers/test_xo_fixer_callback.vader45
-rw-r--r--test/fixers/test_xots_fixer_callback.vader45
-rw-r--r--test/handler/test_atools_handler.vader85
-rw-r--r--test/handler/test_dafny_handler.vader16
-rw-r--r--test/handler/test_ibm_openapi_validator_handler.vader49
-rw-r--r--test/handler/test_inko_handler.vader54
-rw-r--r--test/handler/test_nix_handler.vader23
-rw-r--r--test/handler/test_salt_salt_lint.vader34
-rw-r--r--test/handler/test_spectral_handler.vader52
-rw-r--r--test/handler/test_swipl_handler.vader60
-rw-r--r--test/handler/test_terraform_handler.vader59
-rw-r--r--test/handler/test_vala_lint_handler.vader54
-rw-r--r--test/handler/test_yamllint_handler.vader8
-rw-r--r--test/nix/test.nix0
-rw-r--r--test/nix/test_rnix_lsp.vader14
-rwxr-xr-xtest/script/check-duplicate-tags5
-rwxr-xr-xtest/script/check-supported-tools-tables6
-rwxr-xr-xtest/script/check-tag-alignment11
-rwxr-xr-xtest/script/check-tag-references22
-rwxr-xr-xtest/script/check-toc2
-rwxr-xr-xtest/script/custom-checks34
-rwxr-xr-xtest/script/custom-linting-rules25
-rw-r--r--test/smoke_test.vader8
-rw-r--r--test/test_c_flag_parsing.vader6
-rw-r--r--test/test_deno_executable_detection.vader19
-rw-r--r--test/test_filetype_linter_defaults.vader7
-rw-r--r--test/test_floating_preview.vader92
-rw-r--r--test/test_hover.vader83
-rw-r--r--test/test_linting_updates_loclist.vader6
-rw-r--r--test/test_redundant_tsserver_rendering_avoided.vader30
-rw-r--r--test/test_socket_connections.vader57
-rw-r--r--test/typescript/test.ts0
-rw-r--r--test/typescript/tsconfig.json0
-rw-r--r--test/xo-test-files/monorepo/node_modules/xo/cli.js0
-rw-r--r--test/xo-test-files/monorepo/package.json0
-rw-r--r--test/xo-test-files/monorepo/packages/a/index.js0
-rw-r--r--test/xo-test-files/monorepo/packages/a/index.ts0
-rw-r--r--test/xo-test-files/monorepo/packages/a/package.json0
72 files changed, 1482 insertions, 131 deletions
diff --git a/test/command_callback/inko_paths/test.inko b/test/command_callback/inko_paths/test.inko
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/test/command_callback/inko_paths/test.inko
diff --git a/test/command_callback/inko_paths/tests/test/test_foo.inko b/test/command_callback/inko_paths/tests/test/test_foo.inko
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/test/command_callback/inko_paths/tests/test/test_foo.inko
diff --git a/test/command_callback/spectral_paths/node_modules/.bin/spectral b/test/command_callback/spectral_paths/node_modules/.bin/spectral
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/test/command_callback/spectral_paths/node_modules/.bin/spectral
diff --git a/test/command_callback/spectral_paths/openapi.yaml b/test/command_callback/spectral_paths/openapi.yaml
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/test/command_callback/spectral_paths/openapi.yaml
diff --git a/test/command_callback/test_adals_command_callbacks.vader b/test/command_callback/test_adals_command_callbacks.vader
new file mode 100644
index 00000000..5a04594e
--- /dev/null
+++ b/test/command_callback/test_adals_command_callbacks.vader
@@ -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'}
diff --git a/test/command_callback/test_clang_tidy_command_callback.vader b/test/command_callback/test_clang_tidy_command_callback.vader
index f0a07e8c..eb1220be 100644
--- a/test/command_callback/test_clang_tidy_command_callback.vader
+++ b/test/command_callback/test_clang_tidy_command_callback.vader
@@ -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')
diff --git a/test/command_callback/test_dart_analysis_server_command_callback.vader b/test/command_callback/test_dart_analysis_server_command_callback.vader
new file mode 100644
index 00000000..1754109a
--- /dev/null
+++ b/test/command_callback/test_dart_analysis_server_command_callback.vader
@@ -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'
diff --git a/test/command_callback/test_elixir_credo.vader b/test/command_callback/test_elixir_credo.vader
index 3eb88846..b14444c6 100644
--- a/test/command_callback/test_elixir_credo.vader
+++ b/test/command_callback/test_elixir_credo.vader
@@ -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'
diff --git a/test/command_callback/test_erlang_dialyzer_command_callback.vader b/test/command_callback/test_erlang_dialyzer_command_callback.vader
index 5e21c053..5e818d7f 100644
--- a/test/command_callback/test_erlang_dialyzer_command_callback.vader
+++ b/test/command_callback/test_erlang_dialyzer_command_callback.vader
@@ -25,6 +25,14 @@ Execute(The command should accept configured executable.):
\ . ' -Wunderspecs'
\ . ' %s'
+Execute(The command should accept configured options.):
+ let b:ale_erlang_dialyzer_options = '-r ' . expand('$HOME')
+ AssertLinter 'dialyzer',
+ \ ale#Escape('dialyzer')
+ \ . ' -n --plt ' . ale#Escape(expand('$HOME/.dialyzer_plt'))
+ \ . ' -r ' . expand('$HOME')
+ \ . ' %s'
+
Execute(The command should accept configured PLT file.):
let b:ale_erlang_dialyzer_plt_file = 'custom-plt'
AssertLinter 'dialyzer',
diff --git a/test/command_callback/test_erlang_erlc_command_callback.vader b/test/command_callback/test_erlang_erlc_command_callback.vader
new file mode 100644
index 00000000..7d659a07
--- /dev/null
+++ b/test/command_callback/test_erlang_erlc_command_callback.vader
@@ -0,0 +1,40 @@
+Before:
+ call ale#assert#SetUpLinterTest('erlang', 'erlc')
+
+After:
+ call ale#assert#TearDownLinterTest()
+
+Execute(The default command should be correct.):
+ let g:cmd = ale_linters#erlang#erlc#GetCommand(bufnr(''))
+ let g:regex = 'erlc.\+-o.\+%t'
+ let g:matched = match(g:cmd, g:regex)
+
+ " match returns -1 if not found
+ AssertNotEqual
+ \ g:matched,
+ \ -1,
+ \ 'Command error: expected [' . g:cmd . '] to match [' . g:regex . ']'
+
+Execute(The command should accept configured executable.):
+ let b:ale_erlang_erlc_executable = '/usr/bin/erlc'
+ let g:cmd = ale_linters#erlang#erlc#GetCommand(bufnr(''))
+ let g:regex = '/usr/bin/erlc.\+-o.\+%t'
+ let g:matched = match(g:cmd, g:regex)
+
+ " match returns -1 if not found
+ AssertNotEqual
+ \ g:matched,
+ \ -1,
+ \ 'Command error: expected [' . g:cmd . '] to match [' . g:regex . ']'
+
+Execute(The command should accept configured options.):
+ let b:ale_erlang_erlc_options = '-I include'
+ let g:cmd = ale_linters#erlang#erlc#GetCommand(bufnr(''))
+ let g:regex = 'erlc.\+-o.\+-I include.\+%t'
+ let g:matched = match(g:cmd, g:regex)
+
+ " match returns -1 if not found
+ AssertNotEqual
+ \ g:matched,
+ \ -1,
+ \ 'Command error: expected [' . g:cmd . '] to match [' . g:regex . ']'
diff --git a/test/command_callback/test_fecs_command_callback.vader b/test/command_callback/test_fecs_command_callback.vader
index f70ad084..4287d324 100644
--- a/test/command_callback/test_fecs_command_callback.vader
+++ b/test/command_callback/test_fecs_command_callback.vader
@@ -1,5 +1,6 @@
Before:
call ale#assert#SetUpLinterTest('javascript', 'fecs')
+ runtime autoload/ale/handlers/fecs.vim
After:
call ale#assert#TearDownLinterTest()
diff --git a/test/command_callback/test_haskell_hls_callbacks.vader b/test/command_callback/test_haskell_hls_callbacks.vader
new file mode 100644
index 00000000..e64aab6f
--- /dev/null
+++ b/test/command_callback/test_haskell_hls_callbacks.vader
@@ -0,0 +1,27 @@
+Before:
+ call ale#assert#SetUpLinterTest('haskell', 'hls')
+
+ Save &filetype
+ let &filetype = 'haskell'
+
+After:
+ call ale#assert#TearDownLinterTest()
+
+Execute(The language string should be correct):
+ AssertLSPLanguage 'haskell'
+
+Execute(The default executable should be correct):
+ AssertLinter 'haskell-language-server-wrapper',
+ \ ale#Escape('haskell-language-server-wrapper') . ' --lsp'
+
+Execute(The project root should be detected correctly):
+ AssertLSPProject g:dir
+
+ call ale#test#SetFilename('hls_paths/file.hs')
+
+ AssertLSPProject ale#path#Simplify(g:dir . '/hls_paths')
+
+Execute(The executable should be configurable):
+ let g:ale_haskell_hls_executable = 'foobar'
+
+ AssertLinter 'foobar', ale#Escape('foobar') . ' --lsp'
diff --git a/test/command_callback/test_ibm_openapi_validator_command_callback.vader b/test/command_callback/test_ibm_openapi_validator_command_callback.vader
new file mode 100644
index 00000000..3484cc09
--- /dev/null
+++ b/test/command_callback/test_ibm_openapi_validator_command_callback.vader
@@ -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'
diff --git a/test/command_callback/test_inko_inko_callbacks.vader b/test/command_callback/test_inko_inko_callbacks.vader
new file mode 100644
index 00000000..93295c91
--- /dev/null
+++ b/test/command_callback/test_inko_inko_callbacks.vader
@@ -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'
diff --git a/test/command_callback/test_julia_languageserver_callbacks.vader b/test/command_callback/test_julia_languageserver_callbacks.vader
index 3bc46e3d..96df81f1 100644
--- a/test/command_callback/test_julia_languageserver_callbacks.vader
+++ b/test/command_callback/test_julia_languageserver_callbacks.vader
@@ -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 ''
diff --git a/test/command_callback/test_rust_analyzer_callbacks.vader b/test/command_callback/test_rust_analyzer_callbacks.vader
index 95866076..efab1378 100644
--- a/test/command_callback/test_rust_analyzer_callbacks.vader
+++ b/test/command_callback/test_rust_analyzer_callbacks.vader
@@ -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']}}
diff --git a/test/command_callback/test_sorbet_command_callback.vader b/test/command_callback/test_sorbet_command_callback.vader
index b46e90a4..fe758635 100644
--- a/test/command_callback/test_sorbet_command_callback.vader
+++ b/test/command_callback/test_sorbet_command_callback.vader
@@ -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'
diff --git a/test/command_callback/test_spectral_command_callback.vader b/test/command_callback/test_spectral_command_callback.vader
new file mode 100644
index 00000000..ed3795b9
--- /dev/null
+++ b/test/command_callback/test_spectral_command_callback.vader
@@ -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'
diff --git a/test/command_callback/test_terraform_ls_command_callback.vader b/test/command_callback/test_terraform_ls_command_callback.vader
new file mode 100644
index 00000000..d559ba8c
--- /dev/null
+++ b/test/command_callback/test_terraform_ls_command_callback.vader
@@ -0,0 +1,61 @@
+Before:
+ call ale#assert#SetUpLinterTest('terraform', 'terraform_ls')
+
+After:
+ if isdirectory(g:dir . '/.terraform')
+ call delete(g:dir . '/.terraform', 'd')
+ endif
+
+ unlet! b:ale_terraform_terraform_executable
+ unlet! b:ale_terraform_ls_executable
+ unlet! b:ale_terraform_ls_options
+
+ call ale#assert#TearDownLinterTest()
+
+Execute(Should send correct LSP language):
+ AssertLSPLanguage 'terraform'
+
+Execute(Should load default executable):
+ AssertLinter 'terraform-ls',
+ \ ale#Escape('terraform-ls') . ' serve'
+
+Execute(Should configure custom executable):
+ let b:ale_terraform_ls_executable = 'foo'
+ AssertLinter 'foo',
+ \ ale#Escape('foo') . ' serve'
+
+Execute(Should ignore non-absolute custom terraform executable):
+ let b:ale_terraform_terraform_executable = 'terraform'
+ AssertLinter 'terraform-ls',
+ \ ale#Escape('terraform-ls') . ' serve'
+
+Execute(Should set absolute custom terraform executable):
+ let b:ale_terraform_terraform_executable = '/bin/terraform'
+ AssertLinter 'terraform-ls',
+ \ ale#Escape('terraform-ls') . ' serve -tf-exec /bin/terraform'
+
+Execute(Should set custom options):
+ let b:ale_terraform_ls_options = '--bar'
+
+ AssertLinter 'terraform-ls',
+ \ ale#Escape('terraform-ls') . ' serve --bar'
+
+Execute(Should return current directory if it contains .terraform directory):
+ call mkdir(g:dir . '/.terraform')
+ AssertLSPProject g:dir
+
+Execute(Should return nearest directory with .terraform if found in parent directory):
+ call ale#test#SetFilename('../terraform_files/main.tf')
+
+ let b:parent_dir = ale#path#Simplify(g:dir . '/..')
+ let b:tf_dir = b:parent_dir . '/.terraform'
+
+ if !isdirectory(b:tf_dir)
+ call mkdir(b:tf_dir)
+ endif
+
+ AssertLSPProject b:parent_dir
+
+ call delete(b:tf_dir, 'd')
+ unlet!b:parent_dir
+ unlet!b:tf_dir
diff --git a/test/command_callback/test_terraform_terraform_command_callback.vader b/test/command_callback/test_terraform_terraform_command_callback.vader
index fabd902d..25ca652a 100644
--- a/test/command_callback/test_terraform_terraform_command_callback.vader
+++ b/test/command_callback/test_terraform_terraform_command_callback.vader
@@ -6,4 +6,10 @@ After:
call ale#assert#TearDownLinterTest()
Execute(The default command should be correct):
- AssertLinter 'terraform', ale#Escape('terraform') . ' fmt -no-color --check=true -'
+ AssertLinter 'terraform',
+ \ ale#Escape('terraform') . ' validate -no-color -json '
+
+Execute(The default command should be overriden):
+ let b:ale_terraform_terraform_executable = '/bin/other/terraform'
+ AssertLinter '/bin/other/terraform',
+ \ ale#Escape('/bin/other/terraform') . ' validate -no-color -json '
diff --git a/test/command_callback/test_typescript_deno_lsp.vader b/test/command_callback/test_typescript_deno_lsp.vader
new file mode 100644
index 00000000..01cbc851
--- /dev/null
+++ b/test/command_callback/test_typescript_deno_lsp.vader
@@ -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',
+ \]
diff --git a/test/command_callback/test_xo_command_callback.vader b/test/command_callback/test_xo_command_callback.vader
index 65cb4f8a..1aa4c3f1 100644
--- a/test/command_callback/test_xo_command_callback.vader
+++ b/test/command_callback/test_xo_command_callback.vader
@@ -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'
diff --git a/test/command_callback/test_xots_command_callback.vader b/test/command_callback/test_xots_command_callback.vader
new file mode 100644
index 00000000..cc38ff02
--- /dev/null
+++ b/test/command_callback/test_xots_command_callback.vader
@@ -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'
diff --git a/test/completion/test_lsp_completion_parsing.vader b/test/completion/test_lsp_completion_parsing.vader
index 36228c10..a334d945 100644
--- a/test/completion/test_lsp_completion_parsing.vader
+++ b/test/completion/test_lsp_completion_parsing.vader
@@ -10,37 +10,39 @@ After:
unlet! b:ale_completion_info
Execute(Should handle Rust completion results correctly):
+ let g:ale_completion_autoimport = 0
+
AssertEqual
\ [
- \ {'word': 'new', 'menu': 'pub fn new() -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
- \ {'word': 'with_capacity', 'menu': 'pub fn with_capacity(capacity: usize) -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
- \ {'word': 'from_utf8', 'menu': 'pub fn from_utf8(vec: Vec<u8>) -> Result<String, FromUtf8Error>', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
- \ {'word': 'from_utf8_lossy', 'menu': 'pub fn from_utf8_lossy<''a>(v: &''a [u8]) -> Cow<''a, str>', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
- \ {'word': 'from_utf16', 'menu': 'pub fn from_utf16(v: &[u16]) -> Result<String, FromUtf16Error>', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
- \ {'word': 'from_utf16_lossy', 'menu': 'pub fn from_utf16_lossy(v: &[u16]) -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
- \ {'word': 'from_raw_parts', 'menu': 'pub unsafe fn from_raw_parts(buf: *mut u8, length: usize, capacity: usize) -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
- \ {'word': 'from_utf8_unchecked', 'menu': 'pub unsafe fn from_utf8_unchecked(bytes: Vec<u8>) -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
- \ {'word': 'from_iter', 'menu': 'fn from_iter<I: IntoIterator<Item = char>>(iter: I) -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
- \ {'word': 'from_iter', 'menu': 'fn from_iter<I: IntoIterator<Item = &''a char>>(iter: I) -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
- \ {'word': 'from_iter', 'menu': 'fn from_iter<I: IntoIterator<Item = &''a str>>(iter: I) -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
- \ {'word': 'from_iter', 'menu': 'fn from_iter<I: IntoIterator<Item = String>>(iter: I) -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
- \ {'word': 'from_iter', 'menu': 'fn from_iter<I: IntoIterator<Item = Cow<''a, str>>>(iter: I) -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
- \ {'word': 'Searcher', 'menu': 'type Searcher = <&''b str as Pattern<''a>>::Searcher;', 'info': '', 'kind': 't', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
- \ {'word': 'default', 'menu': 'fn default() -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
- \ {'word': 'Output', 'menu': 'type Output = String;', 'info': '', 'kind': 't', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
- \ {'word': 'Output', 'menu': 'type Output = str;', 'info': '', 'kind': 't', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
- \ {'word': 'Output', 'menu': 'type Output = str;', 'info': '', 'kind': 't', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
- \ {'word': 'Output', 'menu': 'type Output = str;', 'info': '', 'kind': 't', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
- \ {'word': 'Output', 'menu': 'type Output = str;', 'info': '', 'kind': 't', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
- \ {'word': 'Output', 'menu': 'type Output = str;', 'info': '', 'kind': 't', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
- \ {'word': 'Output', 'menu': 'type Output = str;', 'info': '', 'kind': 't', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
- \ {'word': 'Target', 'menu': 'type Target = str;', 'info': '', 'kind': 't', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
- \ {'word': 'Err', 'menu': 'type Err = ParseError;', 'info': '', 'kind': 't', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
- \ {'word': 'from_str', 'menu': 'fn from_str(s: &str) -> Result<String, ParseError>', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
- \ {'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})},
+ \ {'word': 'new', 'dup': 0, 'menu': 'pub fn new() -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
+ \ {'word': 'with_capacity', 'dup': 0, 'menu': 'pub fn with_capacity(capacity: usize) -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
+ \ {'word': 'from_utf8', 'dup': 0, 'menu': 'pub fn from_utf8(vec: Vec<u8>) -> Result<String, FromUtf8Error>', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
+ \ {'word': 'from_utf8_lossy', 'dup': 0, 'menu': 'pub fn from_utf8_lossy<''a>(v: &''a [u8]) -> Cow<''a, str>', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
+ \ {'word': 'from_utf16', 'dup': 0, 'menu': 'pub fn from_utf16(v: &[u16]) -> Result<String, FromUtf16Error>', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
+ \ {'word': 'from_utf16_lossy', 'dup': 0, 'menu': 'pub fn from_utf16_lossy(v: &[u16]) -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
+ \ {'word': 'from_raw_parts', 'dup': 0, 'menu': 'pub unsafe fn from_raw_parts(buf: *mut u8, length: usize, capacity: usize) -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
+ \ {'word': 'from_utf8_unchecked', 'dup': 0, 'menu': 'pub unsafe fn from_utf8_unchecked(bytes: Vec<u8>) -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
+ \ {'word': 'from_iter', 'dup': 0, 'menu': 'fn from_iter<I: IntoIterator<Item = char>>(iter: I) -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
+ \ {'word': 'from_iter', 'dup': 0, 'menu': 'fn from_iter<I: IntoIterator<Item = &''a char>>(iter: I) -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
+ \ {'word': 'from_iter', 'dup': 0, 'menu': 'fn from_iter<I: IntoIterator<Item = &''a str>>(iter: I) -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
+ \ {'word': 'from_iter', 'dup': 0, 'menu': 'fn from_iter<I: IntoIterator<Item = String>>(iter: I) -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
+ \ {'word': 'from_iter', 'dup': 0, 'menu': 'fn from_iter<I: IntoIterator<Item = Cow<''a, str>>>(iter: I) -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
+ \ {'word': 'Searcher', 'dup': 0, 'menu': 'type Searcher = <&''b str as Pattern<''a>>::Searcher;', 'info': '', 'kind': 't', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
+ \ {'word': 'default', 'dup': 0, 'menu': 'fn default() -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
+ \ {'word': 'Output', 'dup': 0, 'menu': 'type Output = String;', 'info': '', 'kind': 't', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
+ \ {'word': 'Output', 'dup': 0, 'menu': 'type Output = str;', 'info': '', 'kind': 't', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
+ \ {'word': 'Output', 'dup': 0, 'menu': 'type Output = str;', 'info': '', 'kind': 't', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
+ \ {'word': 'Output', 'dup': 0, 'menu': 'type Output = str;', 'info': '', 'kind': 't', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
+ \ {'word': 'Output', 'dup': 0, 'menu': 'type Output = str;', 'info': '', 'kind': 't', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
+ \ {'word': 'Output', 'dup': 0, 'menu': 'type Output = str;', 'info': '', 'kind': 't', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
+ \ {'word': 'Output', 'dup': 0, 'menu': 'type Output = str;', 'info': '', 'kind': 't', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
+ \ {'word': 'Target', 'dup': 0, 'menu': 'type Target = str;', 'info': '', 'kind': 't', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
+ \ {'word': 'Err', 'dup': 0, 'menu': 'type Err = ParseError;', 'info': '', 'kind': 't', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
+ \ {'word': 'from_str', 'dup': 0, 'menu': 'fn from_str(s: &str) -> Result<String, ParseError>', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
+ \ {'word': 'from', 'dup': 0, 'menu': 'fn from(s: &''a str) -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
+ \ {'word': 'from', 'dup': 0, 'menu': 'fn from(s: Box<str>) -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
+ \ {'word': 'from', 'dup': 0, 'menu': 'fn from(s: Cow<''a, str>) -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
+ \ {'word': 'to_vec', 'dup': 0, '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",
@@ -195,13 +197,14 @@ Execute(Should handle Rust completion results correctly):
\ })
Execute(Should handle Python completion results correctly):
+ let g:ale_completion_autoimport = 0
let b:ale_completion_info = {
\ 'completion_filter': 'ale#completion#python#CompletionItemFilter',
\}
AssertEqual
\ [
- \ {'word': 'what', 'menu': 'example-python-project.bar.Bar', 'info': "what()\n\n", 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
+ \ {'word': 'what', 'dup': 0, 'menu': 'example-python-project.bar.Bar', 'info': "what()\n\n", 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
\ ],
\ ale#completion#ParseLSPCompletions({
\ "jsonrpc":"2.0",
@@ -406,6 +409,8 @@ Execute(Should handle Python completion results correctly):
\ })
Execute(Should handle extra Python completion results correctly):
+ let g:ale_completion_autoimport = 0
+
let b:ale_completion_info = {
\ 'completion_filter': 'ale#completion#python#CompletionItemFilter',
\ 'prefix': 'mig',
@@ -413,8 +418,8 @@ Execute(Should handle extra Python completion results correctly):
AssertEqual
\ [
- \ {'word': 'migrations', 'menu': 'xxx', 'info': 'migrations', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
- \ {'word': 'MigEngine', 'menu': 'xxx', 'info': 'mig engine', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
+ \ {'word': 'migrations', 'dup': 0, 'menu': 'xxx', 'info': 'migrations', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
+ \ {'word': 'MigEngine', 'dup': 0, 'menu': 'xxx', 'info': 'mig engine', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
\ ],
\ ale#completion#ParseLSPCompletions({
\ 'jsonrpc': '2.0',
@@ -445,9 +450,11 @@ Execute(Should handle extra Python completion results correctly):
\ })
Execute(Should handle missing keys):
+ let g:ale_completion_autoimport = 0
+
AssertEqual
\ [
- \ {'word': 'x', 'menu': '', 'info': '', 'kind': 'v', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
+ \ {'word': 'x', 'dup': 0, 'menu': '', 'info': '', 'kind': 'v', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
\ ],
\ ale#completion#ParseLSPCompletions({
\ 'jsonrpc': '2.0',
@@ -463,9 +470,11 @@ Execute(Should handle missing keys):
\ })
Execute(Should handle documentation in the markdown format):
+ let g:ale_completion_autoimport = 0
+
AssertEqual
\ [
- \ {'word': 'migrations', 'menu': 'xxx', 'info': 'Markdown documentation', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
+ \ {'word': 'migrations', 'dup': 0, 'menu': 'xxx', 'info': 'Markdown documentation', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
\ ],
\ ale#completion#ParseLSPCompletions({
\ 'jsonrpc': '2.0',
@@ -487,9 +496,11 @@ Execute(Should handle documentation in the markdown format):
\ })
Execute(Should handle completion messages with textEdit objects):
+ let g:ale_completion_autoimport = 0
+
AssertEqual
\ [
- \ {'word': 'next_callback', 'menu': 'PlayTimeCallback', 'info': '', 'kind': 'v', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
+ \ {'word': 'next_callback', 'dup': 0, 'menu': 'PlayTimeCallback', 'info': '', 'kind': 'v', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
\ ],
\ ale#completion#ParseLSPCompletions({
\ 'id': 226,
@@ -518,9 +529,11 @@ Execute(Should handle completion messages with textEdit objects):
\ })
Execute(Should handle completion messages with the deprecated insertText attribute):
+ let g:ale_completion_autoimport = 0
+
AssertEqual
\ [
- \ {'word': 'next_callback', 'menu': 'PlayTimeCallback', 'info': '', 'kind': 'v', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
+ \ {'word': 'next_callback', 'dup': 0, 'menu': 'PlayTimeCallback', 'info': '', 'kind': 'v', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
\ ],
\ ale#completion#ParseLSPCompletions({
\ 'id': 226,
@@ -548,6 +561,7 @@ Execute(Should handle completion messages with additionalTextEdits when ale_comp
\ [
\ {
\ 'word': 'next_callback',
+ \ 'dup': 1,
\ 'menu': 'PlayTimeCallback',
\ 'info': '',
\ 'kind': 'v',
@@ -661,6 +675,7 @@ Execute(Should still handle completion messages with empty additionalTextEdits w
\ [
\ {
\ 'word': 'next_callback',
+ \ 'dup': 0,
\ 'menu': 'PlayTimeCallback',
\ 'info': '',
\ 'kind': 'v',
diff --git a/test/completion/test_omnifunc_completion.vader b/test/completion/test_omnifunc_completion.vader
index 3711f974..1db64705 100644
--- a/test/completion/test_omnifunc_completion.vader
+++ b/test/completion/test_omnifunc_completion.vader
@@ -45,15 +45,15 @@ Execute(The start position should be returned when results can be requested):
AssertEqual 11, ale#completion#OmniFunc(1, '')
Execute(The omnifunc function should return async results):
- " Neovim 0.2.0 struggles at running these tests.
- if !has('nvim') || has('nvim-0.3.0')
+ " Neovim 0.2.0 and 0.4.4 struggles at running these tests.
+ if !has('nvim')
call timer_start(0, function('SetCompletionResult'))
AssertEqual ['foo'], ale#completion#OmniFunc(0, '')
endif
Execute(The omnifunc function should parse and return async responses):
- if !has('nvim') || has('nvim-0.3.0')
+ if !has('nvim')
call timer_start(0, function('SetCompletionResponse'))
AssertEqual ['foo'], ale#completion#OmniFunc(0, '')
diff --git a/test/dumb_named_pipe_server.py b/test/dumb_named_pipe_server.py
new file mode 100644
index 00000000..a77e538c
--- /dev/null
+++ b/test/dumb_named_pipe_server.py
@@ -0,0 +1,42 @@
+"""
+This Python script creates a named pipe server that does nothing but send its input
+back to the client that connects to it. Only one argument must be given, the path
+of a named pipe to bind to.
+"""
+import os
+import socket
+import sys
+
+
+def main():
+ if len(sys.argv) < 2:
+ sys.exit('You must specify a filepath')
+
+ sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+ sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+ if os.path.exists(sys.argv[1]):
+ os.remove(sys.argv[1])
+ sock.bind(sys.argv[1])
+ sock.listen(0)
+
+ pid = os.fork()
+
+ if pid:
+ print(pid)
+ sys.exit()
+
+ while True:
+ connection = sock.accept()[0]
+ connection.settimeout(5)
+
+ while True:
+ try:
+ connection.send(connection.recv(1024))
+ except socket.timeout:
+ break
+
+ connection.close()
+
+
+if __name__ == "__main__":
+ main()
diff --git a/test/eslint-test-files/react-app/node_modules/xo/cli.js b/test/eslint-test-files/react-app/node_modules/xo/cli.js
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/test/eslint-test-files/react-app/node_modules/xo/cli.js
diff --git a/test/eslint-test-files/react-app/subdir/testfile.ts b/test/eslint-test-files/react-app/subdir/testfile.ts
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/test/eslint-test-files/react-app/subdir/testfile.ts
diff --git a/test/fixers/test_dhall_fixer_callback.vader b/test/fixers/test_dhall_fixer_callback.vader
deleted file mode 100644
index f27880b7..00000000
--- a/test/fixers/test_dhall_fixer_callback.vader
+++ /dev/null
@@ -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'
- \ }
diff --git a/test/fixers/test_dhall_format_fixer_callback.vader b/test/fixers/test_dhall_format_fixer_callback.vader
new file mode 100644
index 00000000..9bc17f7e
--- /dev/null
+++ b/test/fixers/test_dhall_format_fixer_callback.vader
@@ -0,0 +1,24 @@
+Before:
+ Save g:ale_dhall_executable
+ Save g:ale_dhall_options
+
+ " Use an invalid global executable, so we don’t 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,
+ \ }
diff --git a/test/fixers/test_dhall_freeze_fixer_callback.vader b/test/fixers/test_dhall_freeze_fixer_callback.vader
new file mode 100644
index 00000000..c8f820bb
--- /dev/null
+++ b/test/fixers/test_dhall_freeze_fixer_callback.vader
@@ -0,0 +1,24 @@
+Before:
+ Save g:ale_dhall_executable
+ Save g:ale_dhall_options
+
+ " Use an invalid global executable, so we don’t 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,
+ \ }
diff --git a/test/fixers/test_dhall_lint_fixer_callback.vader b/test/fixers/test_dhall_lint_fixer_callback.vader
new file mode 100644
index 00000000..82229363
--- /dev/null
+++ b/test/fixers/test_dhall_lint_fixer_callback.vader
@@ -0,0 +1,22 @@
+Before:
+ Save g:ale_dhall_executable
+ Save g:ale_dhall_options
+
+ " Use an invalid global executable, so we don’t 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,
+ \ }
diff --git a/test/fixers/test_isort_fixer_callback.vader b/test/fixers/test_isort_fixer_callback.vader
index 7f389dcf..3941f6dd 100644
--- a/test/fixers/test_isort_fixer_callback.vader
+++ b/test/fixers/test_isort_fixer_callback.vader
@@ -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(''))
diff --git a/test/fixers/test_standardrb_fixer_callback.vader b/test/fixers/test_standardrb_fixer_callback.vader
index 99234b79..d315651f 100644
--- a/test/fixers/test_standardrb_fixer_callback.vader
+++ b/test/fixers/test_standardrb_fixer_callback.vader
@@ -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(''))
diff --git a/test/fixers/test_xo_fixer_callback.vader b/test/fixers/test_xo_fixer_callback.vader
new file mode 100644
index 00000000..a473606e
--- /dev/null
+++ b/test/fixers/test_xo_fixer_callback.vader
@@ -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',
+ \ }
diff --git a/test/fixers/test_xots_fixer_callback.vader b/test/fixers/test_xots_fixer_callback.vader
new file mode 100644
index 00000000..5c7fa1d1
--- /dev/null
+++ b/test/fixers/test_xots_fixer_callback.vader
@@ -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',
+ \ }
diff --git a/test/handler/test_atools_handler.vader b/test/handler/test_atools_handler.vader
new file mode 100644
index 00000000..1bb9ca00
--- /dev/null
+++ b/test/handler/test_atools_handler.vader
@@ -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!',
+ \ ])
diff --git a/test/handler/test_dafny_handler.vader b/test/handler/test_dafny_handler.vader
index 674f691d..4ca288d2 100644
--- a/test/handler/test_dafny_handler.vader
+++ b/test/handler/test_dafny_handler.vader
@@ -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'
- \ }
+ \ },
+ \ {
+ \ 'filename': 'File.dfy',
+ \ '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",
\ ])
diff --git a/test/handler/test_ibm_openapi_validator_handler.vader b/test/handler/test_ibm_openapi_validator_handler.vader
new file mode 100644
index 00000000..e136d5d2
--- /dev/null
+++ b/test/handler/test_ibm_openapi_validator_handler.vader
@@ -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'
+ \ ])
diff --git a/test/handler/test_inko_handler.vader b/test/handler/test_inko_handler.vader
new file mode 100644
index 00000000..6621d2d6
--- /dev/null
+++ b/test/handler/test_inko_handler.vader
@@ -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(''), [])
diff --git a/test/handler/test_nix_handler.vader b/test/handler/test_nix_handler.vader
index 398e1ac8..87e8b68f 100644
--- a/test/handler/test_nix_handler.vader
+++ b/test/handler/test_nix_handler.vader
@@ -8,6 +8,29 @@ Execute(The nix handler should parse nix-instantiate error messages correctly):
AssertEqual
\ [
\ {
+ \ 'lnum': 6,
+ \ 'col': 3,
+ \ 'type': 'E',
+ \ 'text': "syntax error, unexpected ']', expecting ';'",
+ \ },
+ \ {
+ \ 'lnum': 3,
+ \ 'col': 5,
+ \ 'type': 'E',
+ \ 'text': "undefined variable 'foo'",
+ \ },
+ \
+ \ ],
+ \ ale_linters#nix#nix#Handle(bufnr(''), [
+ \ "@nix {\"line\":6,\"column\":3,\"raw_msg\":\"syntax error, unexpected ']', expecting ';'\"}",
+ \ "@nix {\"line\":3,\"column\":5,\"raw_msg\":\"undefined variable 'foo'\"}",
+ \ "@nix {\"unrelated\":\"message\"}"
+ \ ])
+
+Execute(The nix handler should parse message from old nix-instantiate correctly):
+ AssertEqual
+ \ [
+ \ {
\ 'lnum': 23,
\ 'col': 14,
\ 'text': 'error: syntax error, unexpected IN',
diff --git a/test/handler/test_salt_salt_lint.vader b/test/handler/test_salt_salt_lint.vader
new file mode 100644
index 00000000..7e234785
--- /dev/null
+++ b/test/handler/test_salt_salt_lint.vader
@@ -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"}]'
+ \ ])
diff --git a/test/handler/test_spectral_handler.vader b/test/handler/test_spectral_handler.vader
new file mode 100644
index 00000000..89a3ff1b
--- /dev/null
+++ b/test/handler/test_spectral_handler.vader
@@ -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`."',
+ \ ])
diff --git a/test/handler/test_swipl_handler.vader b/test/handler/test_swipl_handler.vader
index 9e425cf6..81b8b9e5 100644
--- a/test/handler/test_swipl_handler.vader
+++ b/test/handler/test_swipl_handler.vader
@@ -35,6 +35,22 @@ Execute (The swipl handler should handle a warning / error of two lines):
\ ' Singleton variables: [M]',
\ ])
+Execute (The swipl handler should handle a warning / error of two lines in the new format):
+ call ale#test#SetFilename('test.pl')
+ AssertEqual
+ \ [
+ \ {
+ \ 'lnum': 9,
+ \ 'col': 0,
+ \ 'text': 'Singleton variables: [M]',
+ \ 'type': 'W',
+ \ },
+ \ ],
+ \ ale_linters#prolog#swipl#Handle(bufnr(''), [
+ \ 'Warning: /path/to/test.pl:9:',
+ \ 'Warning: Singleton variables: [M]',
+ \ ])
+
Execute (The swipl handler should join three or more lines with '. '):
call ale#test#SetFilename('test.pl')
AssertEqual
@@ -79,6 +95,50 @@ Execute (The swipl handler should ignore warnings / errors 'No permission to cal
\ ' vimscript: (multifile A)',
\ ])
+Execute (The swipl handler should join three or more lines with '. ' on latest swipl):
+ call ale#test#SetFilename('test.pl')
+ AssertEqual
+ \ [
+ \ {
+ \ 'lnum': 10,
+ \ 'col': 0,
+ \ 'text': 'Clauses of fib/2 are not together in the source-file. Earlier definition at /path/to/test.pl:7. Current predicate: f/0. Use :- discontiguous fib/2. to suppress this message',
+ \ 'type': 'W',
+ \ },
+ \ ],
+ \ ale_linters#prolog#swipl#Handle(bufnr(''), [
+ \ 'Warning: /path/to/test.pl:10:',
+ \ 'Warning: Clauses of fib/2 are not together in the source-file',
+ \ 'Warning: Earlier definition at /path/to/test.pl:7',
+ \ 'Warning: Current predicate: f/0',
+ \ 'Warning: Use :- discontiguous fib/2. to suppress this message',
+ \ ])
+
+Execute (The swipl handler should ignore warnings / errors 'No permission to call sandboxed with latest swpl...'):
+ call ale#test#SetFilename('test.pl')
+ AssertEqual
+ \ [],
+ \ ale_linters#prolog#swipl#Handle(bufnr(''), [
+ \ 'ERROR: /path/to/test.pl:11:',
+ \ 'ERROR: No permission to call sandboxed `''$set_predicate_attribute''(_G3416:_G3417,_G3413,_G3414)''',
+ \ 'ERROR: Reachable from:',
+ \ 'ERROR: system:''$set_pattr''(A,B,C,D)',
+ \ 'ERROR: system:''$set_pattr''(vimscript:A,B,C)',
+ \ 'ERROR: vimscript: (multifile A)',
+ \ 'ERROR: /path/to/test.pl:12:',
+ \ 'ERROR: No permission to call sandboxed `''$set_predicate_attribute''(_G205:_G206,_G202,_G203)''',
+ \ 'ERROR: Reachable from:',
+ \ 'ERROR: system:''$set_pattr''(A,B,C,D)',
+ \ 'ERROR: system:''$set_pattr''(vimscript:A,B,C)',
+ \ 'ERROR: vimscript: (multifile A)',
+ \ 'ERROR: /path/to/test.pl:13:',
+ \ 'ERROR: No permission to call sandboxed `''$set_predicate_attribute''(_G1808:_G1809,_G1805,_G1806)''',
+ \ 'ERROR: Reachable from:',
+ \ 'ERROR: system:''$set_pattr''(A,B,C,D)',
+ \ 'ERROR: system:''$set_pattr''(vimscript:A,B,C)',
+ \ 'ERROR: vimscript: (multifile A)',
+ \ ])
+
Execute (The swipl handler should handle a warning / error with no line number):
call ale#test#SetFilename('test.pl')
AssertEqual
diff --git a/test/handler/test_terraform_handler.vader b/test/handler/test_terraform_handler.vader
index 976ce12a..64e2e578 100644
--- a/test/handler/test_terraform_handler.vader
+++ b/test/handler/test_terraform_handler.vader
@@ -1,34 +1,61 @@
Before:
" Load the file which defines the linter.
runtime ale_linters/terraform/terraform.vim
+ call ale#test#SetDirectory('/testplugin/test/terraform_files')
+ call ale#test#SetFilename('providers.tf')
After:
" Unload all linters again.
call ale#linter#Reset()
+ call ale#test#RestoreDirectory()
Execute(The output should be correct):
AssertEqual
\ [
\ {
- \ 'lnum': 1,
- \ 'col': 20,
- \ 'type': 'E',
- \ 'text': 'illegal char',
+ \ 'lnum': 17,
+ \ 'col': 13,
+ \ 'filename': ale#path#Simplify(g:dir . '/providers.tf'),
+ \ 'type': 'W',
+ \ 'text': 'Terraform 0.13 and earlier allowed provider version',
\ },
\ {
- \ 'lnum': 2,
- \ 'col': 14,
+ \ 'lnum': 0,
+ \ 'col': 0,
+ \ 'filename': ale#path#Simplify(g:dir . '/providers.tf'),
\ 'type': 'E',
- \ 'text': 'literal not terminated',
- \ },
- \ {
- \ 'lnum': 1,
- \ 'type': 'E',
- \ 'text': 'object expected closing RBRACE got: EOF',
- \ },
+ \ 'text': 'Plugin reinitialization required. Please run "terraform"',
+ \ }
\ ],
\ ale_linters#terraform#terraform#Handle(bufnr(''), [
- \ 'Error running fmt: In <standard input>: At 1:20: illegal char',
- \ 'Error running fmt: In <standard input>: At 2:14: literal not terminated',
- \ 'Error running fmt: In <standard input>: object expected closing RBRACE got: EOF',
+ \ '{',
+ \ '"valid": false,',
+ \ '"error_count": 1,',
+ \ '"warning_count": 1,',
+ \ '"diagnostics": [',
+ \ ' {',
+ \ ' "severity": "warning",',
+ \ ' "summary": "Version constraints inside provider configuration blocks are deprecated",',
+ \ ' "detail": "Terraform 0.13 and earlier allowed provider version",',
+ \ ' "range": {',
+ \ ' "filename": "providers.tf",',
+ \ ' "start": {',
+ \ ' "line": 17,',
+ \ ' "column": 13,',
+ \ ' "byte": 669',
+ \ ' },',
+ \ ' "end": {',
+ \ ' "line": 17,',
+ \ ' "column": 24,',
+ \ ' "byte": 680',
+ \ ' }',
+ \ ' }',
+ \ ' },',
+ \ ' {',
+ \ ' "severity": "error",',
+ \ ' "summary": "Could not load plugin",',
+ \ ' "detail": "Plugin reinitialization required. Please run \"terraform\""',
+ \ ' }',
+ \ ' ]',
+ \ '}',
\ ])
diff --git a/test/handler/test_vala_lint_handler.vader b/test/handler/test_vala_lint_handler.vader
new file mode 100644
index 00000000..b8a4fbfa
--- /dev/null
+++ b/test/handler/test_vala_lint_handler.vader
@@ -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',
+ \ ])
diff --git a/test/handler/test_yamllint_handler.vader b/test/handler/test_yamllint_handler.vader
index 1aa0b9f5..dd51119c 100644
--- a/test/handler/test_yamllint_handler.vader
+++ b/test/handler/test_yamllint_handler.vader
@@ -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)',
\ ])
diff --git a/test/nix/test.nix b/test/nix/test.nix
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/test/nix/test.nix
diff --git a/test/nix/test_rnix_lsp.vader b/test/nix/test_rnix_lsp.vader
new file mode 100644
index 00000000..bf62616b
--- /dev/null
+++ b/test/nix/test_rnix_lsp.vader
@@ -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('.')
diff --git a/test/script/check-duplicate-tags b/test/script/check-duplicate-tags
new file mode 100755
index 00000000..ec1de788
--- /dev/null
+++ b/test/script/check-duplicate-tags
@@ -0,0 +1,5 @@
+#!/usr/bin/env bash
+
+set -e
+
+grep --exclude=tags -roh '\*.*\*$' doc | sort | uniq -d
diff --git a/test/script/check-supported-tools-tables b/test/script/check-supported-tools-tables
index f4305707..d238e77f 100755
--- a/test/script/check-supported-tools-tables
+++ b/test/script/check-supported-tools-tables
@@ -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"
diff --git a/test/script/check-tag-alignment b/test/script/check-tag-alignment
new file mode 100755
index 00000000..d41db160
--- /dev/null
+++ b/test/script/check-tag-alignment
@@ -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
diff --git a/test/script/check-tag-references b/test/script/check-tag-references
new file mode 100755
index 00000000..45e741fb
--- /dev/null
+++ b/test/script/check-tag-references
@@ -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"
diff --git a/test/script/check-toc b/test/script/check-toc
index 87a61262..f3f8a9ea 100755
--- a/test/script/check-toc
+++ b/test/script/check-toc
@@ -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 \
diff --git a/test/script/custom-checks b/test/script/custom-checks
index ca9069e4..83afb28c 100755
--- a/test/script/custom-checks
+++ b/test/script/custom-checks
@@ -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'
diff --git a/test/script/custom-linting-rules b/test/script/custom-linting-rules
index 981a9459..69ab3cc8 100755
--- a/test/script/custom-linting-rules
+++ b/test/script/custom-linting-rules
@@ -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"
@@ -128,8 +143,8 @@ check_errors '\(!=.\?\|isnot\) type({})' "Use 'isnot v:t_dict' instead"
check_errors '\(!=.\?\|isnot\) type(function([^)]\+))' "Use 'isnot v:t_func' instead"
# Run a Python script to find lines that require padding around them. For
-# users without Python installed, we'll skip these checks. Travis CI will run
-# the script.
+# users without Python installed, we'll skip these checks. GitHub Actions will
+# run the script.
if command -v python > /dev/null; then
if ! test/script/block-padding-checker "$directory"/**/*.vim; then
RETURN_CODE=1
diff --git a/test/smoke_test.vader b/test/smoke_test.vader
index 0b126cc6..58206049 100644
--- a/test/smoke_test.vader
+++ b/test/smoke_test.vader
@@ -64,9 +64,9 @@ Execute(Linters should run with the default options):
\ 'valid': 1,
\ }]
- " Try the test a few times over in NeoVim 0.3 or Windows,
+ " Try the test a few times over in NeoVim 0.3 or Windows or Vim 8.2,
" where tests fail randomly.
- for g:i in range(has('nvim-0.3') || has('win32') ? 5 : 1)
+ for g:i in range(has('nvim-0.3') || has('win32') || has('patch-8.2.2401') ? 5 : 1)
call ale#Queue(0, '')
call ale#test#WaitForJobs(2000)
@@ -165,9 +165,9 @@ Execute(Previous errors should be removed when linters change):
\ 'valid': 1,
\}]
- " Try the test a few times over in NeoVim 0.3 or Windows,
+ " Try the test a few times over in NeoVim 0.3 or VIm 8.2 or Windows,
" where tests fail randomly.
- for g:i in range(has('nvim-0.3') || has('win32') ? 5 : 1)
+ for g:i in range(has('nvim-0.3') || has('win32') || has('patch-8.2.2401') ? 5 : 1)
call ale#Queue(0, '')
call ale#test#WaitForJobs(2000)
diff --git a/test/test_c_flag_parsing.vader b/test/test_c_flag_parsing.vader
index 99722b17..8b02f2b9 100644
--- a/test/test_c_flag_parsing.vader
+++ b/test/test_c_flag_parsing.vader
@@ -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',
diff --git a/test/test_deno_executable_detection.vader b/test/test_deno_executable_detection.vader
new file mode 100644
index 00000000..edd408b1
--- /dev/null
+++ b/test/test_deno_executable_detection.vader
@@ -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(''))
+
diff --git a/test/test_filetype_linter_defaults.vader b/test/test_filetype_linter_defaults.vader
index e9980536..d4e708ec 100644
--- a/test/test_filetype_linter_defaults.vader
+++ b/test/test_filetype_linter_defaults.vader
@@ -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')
diff --git a/test/test_floating_preview.vader b/test/test_floating_preview.vader
new file mode 100644
index 00000000..43415556
--- /dev/null
+++ b/test/test_floating_preview.vader
@@ -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
diff --git a/test/test_hover.vader b/test/test_hover.vader
index ed756396..7a9c8d91 100644
--- a/test/test_hover.vader
+++ b/test/test_hover.vader
@@ -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
@@ -168,6 +186,28 @@ 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, 'buffer': bufnr('')}})
@@ -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
diff --git a/test/test_linting_updates_loclist.vader b/test/test_linting_updates_loclist.vader
index 8a162703..41c86522 100644
--- a/test/test_linting_updates_loclist.vader
+++ b/test/test_linting_updates_loclist.vader
@@ -7,10 +7,12 @@ Before:
Save g:ale_run_synchronously
Save g:ale_set_lists_synchronously
Save g:ale_buffer_info
+ Save g:ale_sign_offset
" We want to check that sign IDs are set for this test.
let g:ale_set_signs = 1
let g:ale_set_loclist = 1
+ let g:ale_sign_offset = 2000000
" Disable features we don't need for these tests.
let g:ale_set_quickfix = 0
let g:ale_set_highlights = 0
@@ -77,7 +79,7 @@ Execute(The loclist should be updated after linting is done):
\ 'type': 'W',
\ 'col': 10,
\ 'text': 'Infix operators must be spaced. [Warning/space-infix-ops]',
- \ 'sign_id': 1000001,
+ \ 'sign_id': 2000001,
\ },
\ {
\ 'lnum': 2,
@@ -88,7 +90,7 @@ Execute(The loclist should be updated after linting is done):
\ 'type': 'E',
\ 'col': 10,
\ 'text': 'Missing semicolon. [Error/semi]',
- \ 'sign_id': 1000002,
+ \ 'sign_id': 2000002,
\ }
\ ],
\ get(get(g:ale_buffer_info, bufnr('%'), {}), 'loclist', [])
diff --git a/test/test_redundant_tsserver_rendering_avoided.vader b/test/test_redundant_tsserver_rendering_avoided.vader
index 6125ebc2..bde5d152 100644
--- a/test/test_redundant_tsserver_rendering_avoided.vader
+++ b/test/test_redundant_tsserver_rendering_avoided.vader
@@ -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
diff --git a/test/test_socket_connections.vader b/test/test_socket_connections.vader
index 6837fe51..9ea5580d 100644
--- a/test/test_socket_connections.vader
+++ b/test/test_socket_connections.vader
@@ -28,11 +28,17 @@ Before:
endfunction
let g:port = 10347
- let g:pid = str2nr(system(
+ let g:pid_tcp = str2nr(system(
\ 'python'
\ . ' ' . ale#Escape(g:dir . '/dumb_tcp_server.py')
\ . ' ' . g:port
\))
+ let g:pipe_path = 'tmp_named_pipe'
+ let g:pid_pipe = str2nr(system(
+ \ 'python'
+ \ . ' ' . ale#Escape(g:dir . '/dumb_named_pipe_server.py')
+ \ . ' ' . g:pipe_path
+ \))
endif
After:
@@ -46,17 +52,23 @@ After:
delfunction WaitForData
delfunction TestCallback
- if has_key(g:, 'pid')
- call system('kill ' . g:pid)
+ if has_key(g:, 'pid_tcp')
+ call system('kill ' . g:pid_tcp)
endif
- unlet! g:pid
+ if has_key(g:, 'pid_pipe')
+ call system('kill ' . g:pid_pipe)
+ endif
+
+ unlet! g:pid_tcp
unlet! g:port
+ unlet! g:pid_pipe
+ unlet! g:pipe_path
endif
unlet! g:can_run_socket_tests
-Execute(Sending and receiving connections to sockets should work):
+Execute(Sending and receiving connections to tcp sockets should work):
if g:can_run_socket_tests
let g:channel_id = ale#socket#Open(
\ '127.0.0.1:' . g:port,
@@ -90,3 +102,38 @@ Execute(Sending and receiving connections to sockets should work):
\ {'callback': function('function')}
\)
endif
+
+Execute(Sending and receiving connections to named pipe sockets should work):
+ if g:can_run_socket_tests && has('nvim')
+ let g:channel_id = ale#socket#Open(
+ \ g:pipe_path,
+ \ {'callback': function('TestCallback')}
+ \)
+
+ Assert g:channel_id >= 0, 'The socket was not opened!'
+
+ call ale#socket#Send(g:channel_id, 'hello')
+ call ale#socket#Send(g:channel_id, ' world')
+
+ AssertEqual 1, ale#socket#IsOpen(g:channel_id)
+
+ " Wait up to 1 second for the expected data to arrive.
+ call WaitForData('hello world', 1000)
+
+ AssertEqual g:channel_id, g:channel_id_received
+ AssertEqual 'hello world', g:data_received
+ AssertEqual g:pipe_path, ale#socket#GetAddress(g:channel_id)
+
+ call ale#socket#Close(g:channel_id)
+
+ AssertEqual 0, ale#socket#IsOpen(g:channel_id)
+ AssertEqual '', ale#socket#GetAddress(g:channel_id)
+ endif
+
+ " NeoVim versions which can't connect to sockets should just fail.
+ if has('nvim') && !exists('*chanclose')
+ AssertEqual -1, ale#socket#Open(
+ \ 'tmp_named_pipe',
+ \ {'callback': function('function')}
+ \)
+ endif
diff --git a/test/typescript/test.ts b/test/typescript/test.ts
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/test/typescript/test.ts
diff --git a/test/typescript/tsconfig.json b/test/typescript/tsconfig.json
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/test/typescript/tsconfig.json
diff --git a/test/xo-test-files/monorepo/node_modules/xo/cli.js b/test/xo-test-files/monorepo/node_modules/xo/cli.js
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/test/xo-test-files/monorepo/node_modules/xo/cli.js
diff --git a/test/xo-test-files/monorepo/package.json b/test/xo-test-files/monorepo/package.json
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/test/xo-test-files/monorepo/package.json
diff --git a/test/xo-test-files/monorepo/packages/a/index.js b/test/xo-test-files/monorepo/packages/a/index.js
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/test/xo-test-files/monorepo/packages/a/index.js
diff --git a/test/xo-test-files/monorepo/packages/a/index.ts b/test/xo-test-files/monorepo/packages/a/index.ts
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/test/xo-test-files/monorepo/packages/a/index.ts
diff --git a/test/xo-test-files/monorepo/packages/a/package.json b/test/xo-test-files/monorepo/packages/a/package.json
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/test/xo-test-files/monorepo/packages/a/package.json