#2132 - Replace command_chain and chain_with with ale#command#Run

This commit is contained in:
w0rp 2019-04-07 14:58:06 +01:00
parent cdf89f8269
commit 3bebcb5d48
No known key found for this signature in database
GPG Key ID: 0FC1ECAA8C81CD83
48 changed files with 751 additions and 694 deletions

View File

@ -19,9 +19,6 @@ call ale#linter#Define('c', {
\ 'name': 'clang', \ 'name': 'clang',
\ 'output_stream': 'stderr', \ 'output_stream': 'stderr',
\ 'executable': {b -> ale#Var(b, 'c_clang_executable')}, \ 'executable': {b -> ale#Var(b, 'c_clang_executable')},
\ 'command_chain': [ \ 'command': {b -> ale#c#RunMakeCommand(b, function('ale_linters#c#clang#GetCommand'))},
\ {'callback': 'ale#c#GetMakeCommand', 'output_stream': 'stdout'},
\ {'callback': 'ale_linters#c#clang#GetCommand'}
\ ],
\ 'callback': 'ale#handlers#gcc#HandleGCCFormatWithIncludes', \ 'callback': 'ale#handlers#gcc#HandleGCCFormatWithIncludes',
\}) \})

View File

@ -19,9 +19,6 @@ call ale#linter#Define('c', {
\ 'name': 'gcc', \ 'name': 'gcc',
\ 'output_stream': 'stderr', \ 'output_stream': 'stderr',
\ 'executable': {b -> ale#Var(b, 'c_gcc_executable')}, \ 'executable': {b -> ale#Var(b, 'c_gcc_executable')},
\ 'command_chain': [ \ 'command': {b -> ale#c#RunMakeCommand(b, function('ale_linters#c#gcc#GetCommand'))},
\ {'callback': 'ale#c#GetMakeCommand', 'output_stream': 'stdout'},
\ {'callback': 'ale_linters#c#gcc#GetCommand'}
\ ],
\ 'callback': 'ale#handlers#gcc#HandleGCCFormatWithIncludes', \ 'callback': 'ale#handlers#gcc#HandleGCCFormatWithIncludes',
\}) \})

View File

@ -19,9 +19,6 @@ call ale#linter#Define('cpp', {
\ 'name': 'clang', \ 'name': 'clang',
\ 'output_stream': 'stderr', \ 'output_stream': 'stderr',
\ 'executable': {b -> ale#Var(b, 'cpp_clang_executable')}, \ 'executable': {b -> ale#Var(b, 'cpp_clang_executable')},
\ 'command_chain': [ \ 'command': {b -> ale#c#RunMakeCommand(b, function('ale_linters#cpp#clang#GetCommand'))},
\ {'callback': 'ale#c#GetMakeCommand', 'output_stream': 'stdout'},
\ {'callback': 'ale_linters#cpp#clang#GetCommand'},
\ ],
\ 'callback': 'ale#handlers#gcc#HandleGCCFormatWithIncludes', \ 'callback': 'ale#handlers#gcc#HandleGCCFormatWithIncludes',
\}) \})

View File

@ -20,9 +20,6 @@ call ale#linter#Define('cpp', {
\ 'aliases': ['g++'], \ 'aliases': ['g++'],
\ 'output_stream': 'stderr', \ 'output_stream': 'stderr',
\ 'executable': {b -> ale#Var(b, 'cpp_gcc_executable')}, \ 'executable': {b -> ale#Var(b, 'cpp_gcc_executable')},
\ 'command_chain': [ \ 'command': {b -> ale#c#RunMakeCommand(b, function('ale_linters#cpp#gcc#GetCommand'))},
\ {'callback': 'ale#c#GetMakeCommand', 'output_stream': 'stdout'},
\ {'callback': 'ale_linters#cpp#gcc#GetCommand'},
\ ],
\ 'callback': 'ale#handlers#gcc#HandleGCCFormatWithIncludes', \ 'callback': 'ale#handlers#gcc#HandleGCCFormatWithIncludes',
\}) \})

View File

@ -1,7 +1,7 @@
" Author: w0rp <devw0rp@gmail.com> " Author: w0rp <devw0rp@gmail.com>
" Description: "dmd for D files" " Description: "dmd for D files"
function! ale_linters#d#dmd#DUBCommand(buffer) abort function! ale_linters#d#dmd#GetDUBCommand(buffer) abort
" If we can't run dub, then skip this command. " If we can't run dub, then skip this command.
if !executable('dub') if !executable('dub')
" Returning an empty string skips to the DMD command. " Returning an empty string skips to the DMD command.
@ -21,7 +21,18 @@ function! ale_linters#d#dmd#DUBCommand(buffer) abort
\ . ' && dub describe --import-paths' \ . ' && dub describe --import-paths'
endfunction endfunction
function! ale_linters#d#dmd#DMDCommand(buffer, dub_output) abort function! ale_linters#d#dmd#RunDUBCommand(buffer) abort
let l:command = ale_linters#d#dmd#GetDUBCommand(a:buffer)
if empty(l:command)
" If we can't run DUB, just run DMD.
return ale_linters#d#dmd#DMDCommand(a:buffer, [], {})
endif
return ale#command#Run(a:buffer, l:command, function('ale_linters#d#dmd#DMDCommand'))
endfunction
function! ale_linters#d#dmd#DMDCommand(buffer, dub_output, meta) abort
let l:import_list = [] let l:import_list = []
" Build a list of import paths generated from DUB, if available. " Build a list of import paths generated from DUB, if available.
@ -57,9 +68,7 @@ endfunction
call ale#linter#Define('d', { call ale#linter#Define('d', {
\ 'name': 'dmd', \ 'name': 'dmd',
\ 'executable': 'dmd', \ 'executable': 'dmd',
\ 'command_chain': [ \ 'command': function('ale_linters#d#dmd#RunDUBCommand'),
\ {'callback': 'ale_linters#d#dmd#DUBCommand', 'output_stream': 'stdout'},
\ {'callback': 'ale_linters#d#dmd#DMDCommand', 'output_stream': 'stderr'},
\ ],
\ 'callback': 'ale_linters#d#dmd#Handle', \ 'callback': 'ale_linters#d#dmd#Handle',
\ 'output_stream': 'stderr',
\}) \})

View File

@ -3,7 +3,17 @@
call ale#Set('erlang_syntaxerl_executable', 'syntaxerl') call ale#Set('erlang_syntaxerl_executable', 'syntaxerl')
function! ale_linters#erlang#syntaxerl#GetCommand(buffer, output) abort function! ale_linters#erlang#syntaxerl#RunHelpCommand(buffer) abort
let l:executable = ale#Var(a:buffer, 'erlang_syntaxerl_executable')
return ale#command#Run(
\ a:buffer,
\ ale#Escape(l:executable) . ' -h',
\ function('ale_linters#erlang#syntaxerl#GetCommand'),
\)
endfunction
function! ale_linters#erlang#syntaxerl#GetCommand(buffer, output, meta) abort
let l:use_b_option = match(a:output, '\C\V-b, --base\>') > -1 let l:use_b_option = match(a:output, '\C\V-b, --base\>') > -1
return '%e' . (l:use_b_option ? ' -b %s %t' : ' %t') return '%e' . (l:use_b_option ? ' -b %s %t' : ' %t')
@ -27,9 +37,6 @@ endfunction
call ale#linter#Define('erlang', { call ale#linter#Define('erlang', {
\ 'name': 'syntaxerl', \ 'name': 'syntaxerl',
\ 'executable': {b -> ale#Var(b, 'erlang_syntaxerl_executable')}, \ 'executable': {b -> ale#Var(b, 'erlang_syntaxerl_executable')},
\ 'command_chain': [ \ 'command': {b -> ale_linters#erlang#syntaxerl#RunHelpCommand(b)},
\ {'callback': {-> '%e -h'}},
\ {'callback': 'ale_linters#erlang#syntaxerl#GetCommand'},
\ ],
\ 'callback': 'ale_linters#erlang#syntaxerl#Handle', \ 'callback': 'ale_linters#erlang#syntaxerl#Handle',
\}) \})

View File

@ -1,14 +1,10 @@
" Author: Eddie Lebow https://github.com/elebow " Author: Eddie Lebow https://github.com/elebow
" Description: eruby checker using `erubi` " Description: eruby checker using `erubi`
function! ale_linters#eruby#erubi#CheckErubi(buffer) abort function! ale_linters#eruby#erubi#GetCommand(buffer, output, meta) abort
return 'ruby -r erubi/capture_end -e ' . ale#Escape('""')
endfunction
function! ale_linters#eruby#erubi#GetCommand(buffer, check_erubi_output) abort
let l:rails_root = ale#ruby#FindRailsRoot(a:buffer) let l:rails_root = ale#ruby#FindRailsRoot(a:buffer)
if (!empty(a:check_erubi_output)) if !empty(a:output)
" The empty command in CheckErubi returns nothing if erubi runs and " The empty command in CheckErubi returns nothing if erubi runs and
" emits an error if erubi is not present " emits an error if erubi is not present
return '' return ''
@ -27,9 +23,10 @@ endfunction
call ale#linter#Define('eruby', { call ale#linter#Define('eruby', {
\ 'name': 'erubi', \ 'name': 'erubi',
\ 'executable': 'ruby', \ 'executable': 'ruby',
\ 'command_chain': [ \ 'command': {buffer -> ale#command#Run(
\ {'callback': 'ale_linters#eruby#erubi#CheckErubi'}, \ buffer,
\ {'callback': 'ale_linters#eruby#erubi#GetCommand', 'output_stream': 'stderr'}, \ 'ruby -r erubi/capture_end -e ' . ale#Escape('""'),
\ ], \ function('ale_linters#eruby#erubi#GetCommand'),
\ )},
\ 'callback': 'ale#handlers#ruby#HandleSyntaxErrors', \ 'callback': 'ale#handlers#ruby#HandleSyntaxErrors',
\}) \})

View File

@ -7,21 +7,29 @@ call ale#Set('java_javac_executable', 'javac')
call ale#Set('java_javac_options', '') call ale#Set('java_javac_options', '')
call ale#Set('java_javac_classpath', '') call ale#Set('java_javac_classpath', '')
function! ale_linters#java#javac#GetImportPaths(buffer) abort function! ale_linters#java#javac#RunWithImportPaths(buffer) abort
let l:command = ''
let l:pom_path = ale#path#FindNearestFile(a:buffer, 'pom.xml') let l:pom_path = ale#path#FindNearestFile(a:buffer, 'pom.xml')
if !empty(l:pom_path) && executable('mvn') if !empty(l:pom_path) && executable('mvn')
return ale#path#CdString(fnamemodify(l:pom_path, ':h')) let l:command = ale#path#CdString(fnamemodify(l:pom_path, ':h'))
\ . 'mvn dependency:build-classpath' \ . 'mvn dependency:build-classpath'
endif endif
let l:classpath_command = ale#gradle#BuildClasspathCommand(a:buffer) " Try to use Gradle if Maven isn't available.
if empty(l:command)
if !empty(l:classpath_command) let l:command = ale#gradle#BuildClasspathCommand(a:buffer)
return l:classpath_command
endif endif
return '' if empty(l:command)
return ale_linters#java#javac#GetCommand(a:buffer, [], {})
endif
return ale#command#Run(
\ a:buffer,
\ l:command,
\ function('ale_linters#java#javac#GetCommand')
\)
endfunction endfunction
function! s:BuildClassPathOption(buffer, import_paths) abort function! s:BuildClassPathOption(buffer, import_paths) abort
@ -37,7 +45,7 @@ function! s:BuildClassPathOption(buffer, import_paths) abort
\ : '' \ : ''
endfunction endfunction
function! ale_linters#java#javac#GetCommand(buffer, import_paths) abort function! ale_linters#java#javac#GetCommand(buffer, import_paths, meta) abort
let l:cp_option = s:BuildClassPathOption(a:buffer, a:import_paths) let l:cp_option = s:BuildClassPathOption(a:buffer, a:import_paths)
let l:sp_option = '' let l:sp_option = ''
@ -120,9 +128,7 @@ endfunction
call ale#linter#Define('java', { call ale#linter#Define('java', {
\ 'name': 'javac', \ 'name': 'javac',
\ 'executable': {b -> ale#Var(b, 'java_javac_executable')}, \ 'executable': {b -> ale#Var(b, 'java_javac_executable')},
\ 'command_chain': [ \ 'command': function('ale_linters#java#javac#RunWithImportPaths'),
\ {'callback': 'ale_linters#java#javac#GetImportPaths', 'output_stream': 'stdout'}, \ 'output_stream': 'stderr',
\ {'callback': 'ale_linters#java#javac#GetCommand', 'output_stream': 'stderr'},
\ ],
\ 'callback': 'ale_linters#java#javac#Handle', \ 'callback': 'ale_linters#java#javac#Handle',
\}) \})

View File

@ -27,32 +27,13 @@ function! ale_linters#javascript#flow#GetExecutable(buffer) abort
\]) \])
endfunction endfunction
function! ale_linters#javascript#flow#VersionCheck(buffer) abort function! ale_linters#javascript#flow#GetCommand(buffer, version) abort
let l:executable = ale_linters#javascript#flow#GetExecutable(a:buffer)
if empty(l:executable)
return ''
endif
return ale#Escape(l:executable) . ' --version'
endfunction
function! ale_linters#javascript#flow#GetCommand(buffer, version_lines) abort
let l:executable = ale_linters#javascript#flow#GetExecutable(a:buffer)
if empty(l:executable)
return ''
endif
let l:version = ale#semver#GetVersion(l:executable, a:version_lines)
" If we can parse the version number, then only use --respect-pragma " If we can parse the version number, then only use --respect-pragma
" if the version is >= 0.36.0, which added the argument. " if the version is >= 0.36.0, which added the argument.
let l:use_respect_pragma = ale#Var(a:buffer, 'javascript_flow_use_respect_pragma') let l:use_respect_pragma = ale#Var(a:buffer, 'javascript_flow_use_respect_pragma')
\ && (empty(l:version) || ale#semver#GTE(l:version, [0, 36])) \ && (empty(a:version) || ale#semver#GTE(a:version, [0, 36]))
return ale#Escape(l:executable) return '%e check-contents'
\ . ' check-contents'
\ . (l:use_respect_pragma ? ' --respect-pragma': '') \ . (l:use_respect_pragma ? ' --respect-pragma': '')
\ . ' --json --from ale %s < %t' \ . ' --json --from ale %s < %t'
\ . (!has('win32') ? '; echo' : '') \ . (!has('win32') ? '; echo' : '')
@ -87,7 +68,6 @@ function! s:ExtraErrorMsg(current, new) abort
return l:newMsg return l:newMsg
endfunction endfunction
function! s:GetDetails(error) abort function! s:GetDetails(error) abort
let l:detail = '' let l:detail = ''
@ -169,10 +149,12 @@ endfunction
call ale#linter#Define('javascript', { call ale#linter#Define('javascript', {
\ 'name': 'flow', \ 'name': 'flow',
\ 'executable': function('ale_linters#javascript#flow#GetExecutable'), \ 'executable': function('ale_linters#javascript#flow#GetExecutable'),
\ 'command_chain': [ \ 'command': {buffer -> ale#semver#RunWithVersionCheck(
\ {'callback': 'ale_linters#javascript#flow#VersionCheck'}, \ buffer,
\ {'callback': 'ale_linters#javascript#flow#GetCommand'}, \ ale_linters#javascript#flow#GetExecutable(buffer),
\ ], \ '%e --version',
\ function('ale_linters#javascript#flow#GetCommand'),
\ )},
\ 'callback': 'ale_linters#javascript#flow#Handle', \ 'callback': 'ale_linters#javascript#flow#Handle',
\ 'read_buffer': 0, \ 'read_buffer': 0,
\}) \})

View File

@ -11,26 +11,33 @@ let g:ale_kotlin_kotlinc_module_filename = get(g:, 'ale_kotlin_kotlinc_module_fi
let s:classpath_sep = has('unix') ? ':' : ';' let s:classpath_sep = has('unix') ? ':' : ';'
function! ale_linters#kotlin#kotlinc#GetImportPaths(buffer) abort function! ale_linters#kotlin#kotlinc#RunWithImportPaths(buffer) abort
" exec maven/gradle only if classpath is not set " exec maven/gradle only if classpath is not set
if ale#Var(a:buffer, 'kotlin_kotlinc_classpath') isnot# '' if ale#Var(a:buffer, 'kotlin_kotlinc_classpath') isnot# ''
return '' return ale_linters#kotlin#kotlinc#GetCommand(a:buffer, [], {})
else
let l:pom_path = ale#path#FindNearestFile(a:buffer, 'pom.xml')
if !empty(l:pom_path) && executable('mvn')
return ale#path#CdString(fnamemodify(l:pom_path, ':h'))
\ . 'mvn dependency:build-classpath'
endif
let l:classpath_command = ale#gradle#BuildClasspathCommand(a:buffer)
if !empty(l:classpath_command)
return l:classpath_command
endif
return ''
endif endif
let l:pom_path = ale#path#FindNearestFile(a:buffer, 'pom.xml')
if !empty(l:pom_path) && executable('mvn')
let l:command = ale#path#CdString(fnamemodify(l:pom_path, ':h'))
\ . 'mvn dependency:build-classpath'
endif
" Try to use Gradle if Maven isn't available.
if empty(l:command)
let l:command = ale#gradle#BuildClasspathCommand(a:buffer)
endif
if empty(l:command)
return ale_linters#kotlin#kotlinc#GetCommand(a:buffer, [], {})
endif
return ale#command#Run(
\ a:buffer,
\ l:command,
\ function('ale_linters#kotlin#kotlinc#GetCommand')
\)
endfunction endfunction
function! s:BuildClassPathOption(buffer, import_paths) abort function! s:BuildClassPathOption(buffer, import_paths) abort
@ -46,7 +53,7 @@ function! s:BuildClassPathOption(buffer, import_paths) abort
\ : '' \ : ''
endfunction endfunction
function! ale_linters#kotlin#kotlinc#GetCommand(buffer, import_paths) abort function! ale_linters#kotlin#kotlinc#GetCommand(buffer, import_paths, meta) abort
let l:kotlinc_opts = ale#Var(a:buffer, 'kotlin_kotlinc_options') let l:kotlinc_opts = ale#Var(a:buffer, 'kotlin_kotlinc_options')
let l:command = 'kotlinc ' let l:command = 'kotlinc '
@ -165,11 +172,7 @@ endfunction
call ale#linter#Define('kotlin', { call ale#linter#Define('kotlin', {
\ 'name': 'kotlinc', \ 'name': 'kotlinc',
\ 'executable': 'kotlinc', \ 'executable': 'kotlinc',
\ 'command_chain': [ \ 'command': function('ale_linters#kotlin#kotlinc#RunWithImportPaths'),
\ {'callback': 'ale_linters#kotlin#kotlinc#GetImportPaths', 'output_stream': 'stdout'},
\ {'callback': 'ale_linters#kotlin#kotlinc#GetCommand', 'output_stream': 'stderr'},
\ ],
\ 'callback': 'ale_linters#kotlin#kotlinc#Handle', \ 'callback': 'ale_linters#kotlin#kotlinc#Handle',
\ 'lint_file': 1, \ 'lint_file': 1,
\}) \})

View File

@ -6,34 +6,13 @@ let g:ale_php_phpstan_executable = get(g:, 'ale_php_phpstan_executable', 'phpsta
let g:ale_php_phpstan_level = get(g:, 'ale_php_phpstan_level', '4') let g:ale_php_phpstan_level = get(g:, 'ale_php_phpstan_level', '4')
let g:ale_php_phpstan_configuration = get(g:, 'ale_php_phpstan_configuration', '') let g:ale_php_phpstan_configuration = get(g:, 'ale_php_phpstan_configuration', '')
function! ale_linters#php#phpstan#GetExecutable(buffer) abort function! ale_linters#php#phpstan#GetCommand(buffer, version) abort
return ale#Var(a:buffer, 'php_phpstan_executable')
endfunction
function! ale_linters#php#phpstan#VersionCheck(buffer) abort
let l:executable = ale_linters#php#phpstan#GetExecutable(a:buffer)
" If we have previously stored the version number in a cache, then
" don't look it up again.
if ale#semver#HasVersion(l:executable)
" Returning an empty string skips this command.
return ''
endif
let l:executable = ale#Escape(l:executable)
return l:executable . ' --version'
endfunction
function! ale_linters#php#phpstan#GetCommand(buffer, version_output) abort
let l:configuration = ale#Var(a:buffer, 'php_phpstan_configuration') let l:configuration = ale#Var(a:buffer, 'php_phpstan_configuration')
let l:configuration_option = !empty(l:configuration) let l:configuration_option = !empty(l:configuration)
\ ? ' -c ' . l:configuration \ ? ' -c ' . l:configuration
\ : '' \ : ''
let l:executable = ale_linters#php#phpstan#GetExecutable(a:buffer) let l:error_format = ale#semver#GTE(a:version, [0, 10, 3])
let l:version = ale#semver#GetVersion(l:executable, a:version_output)
let l:error_format = ale#semver#GTE(l:version, [0, 10, 3])
\ ? ' --error-format raw' \ ? ' --error-format raw'
\ : ' --errorFormat raw' \ : ' --errorFormat raw'
@ -65,10 +44,12 @@ endfunction
call ale#linter#Define('php', { call ale#linter#Define('php', {
\ 'name': 'phpstan', \ 'name': 'phpstan',
\ 'executable': function('ale_linters#php#phpstan#GetExecutable'), \ 'executable': {b -> ale#Var(b, 'php_phpstan_executable')},
\ 'command_chain': [ \ 'command': {buffer -> ale#semver#RunWithVersionCheck(
\ {'callback': 'ale_linters#php#phpstan#VersionCheck'}, \ buffer,
\ {'callback': 'ale_linters#php#phpstan#GetCommand'}, \ ale#Var(buffer, 'php_phpstan_executable'),
\ ], \ '%e --version',
\ function('ale_linters#php#phpstan#GetCommand'),
\ )},
\ 'callback': 'ale_linters#php#phpstan#Handle', \ 'callback': 'ale_linters#php#phpstan#Handle',
\}) \})

View File

@ -24,28 +24,25 @@ function! ale_linters#python#flake8#GetExecutable(buffer) abort
return ale#Var(a:buffer, 'python_flake8_executable') return ale#Var(a:buffer, 'python_flake8_executable')
endfunction endfunction
function! ale_linters#python#flake8#VersionCheck(buffer) abort function! ale_linters#python#flake8#RunWithVersionCheck(buffer) abort
let l:executable = ale_linters#python#flake8#GetExecutable(a:buffer) let l:executable = ale_linters#python#flake8#GetExecutable(a:buffer)
" If we have previously stored the version number in a cache, then
" don't look it up again.
if ale#semver#HasVersion(l:executable)
" Returning an empty string skips this command.
return ''
endif
let l:executable = ale#Escape(l:executable)
let l:module_string = s:UsingModule(a:buffer) ? ' -m flake8' : '' let l:module_string = s:UsingModule(a:buffer) ? ' -m flake8' : ''
let l:command = ale#Escape(l:executable) . l:module_string . ' --version'
return l:executable . l:module_string . ' --version' return ale#semver#RunWithVersionCheck(
\ a:buffer,
\ l:executable,
\ l:command,
\ function('ale_linters#python#flake8#GetCommand'),
\)
endfunction endfunction
function! ale_linters#python#flake8#GetCommand(buffer, version_output) abort function! ale_linters#python#flake8#GetCommand(buffer, version) abort
let l:cd_string = ale#Var(a:buffer, 'python_flake8_change_directory') let l:cd_string = ale#Var(a:buffer, 'python_flake8_change_directory')
\ ? ale#path#BufferCdString(a:buffer) \ ? ale#path#BufferCdString(a:buffer)
\ : '' \ : ''
let l:executable = ale_linters#python#flake8#GetExecutable(a:buffer) let l:executable = ale_linters#python#flake8#GetExecutable(a:buffer)
let l:version = ale#semver#GetVersion(l:executable, a:version_output)
let l:exec_args = l:executable =~? 'pipenv$' let l:exec_args = l:executable =~? 'pipenv$'
\ ? ' run flake8' \ ? ' run flake8'
@ -53,7 +50,7 @@ function! ale_linters#python#flake8#GetCommand(buffer, version_output) abort
" Only include the --stdin-display-name argument if we can parse the " Only include the --stdin-display-name argument if we can parse the
" flake8 version, and it is recent enough to support it. " flake8 version, and it is recent enough to support it.
let l:display_name_args = ale#semver#GTE(l:version, [3, 0, 0]) let l:display_name_args = ale#semver#GTE(a:version, [3, 0, 0])
\ ? ' --stdin-display-name %s' \ ? ' --stdin-display-name %s'
\ : '' \ : ''
@ -144,9 +141,6 @@ endfunction
call ale#linter#Define('python', { call ale#linter#Define('python', {
\ 'name': 'flake8', \ 'name': 'flake8',
\ 'executable': function('ale_linters#python#flake8#GetExecutable'), \ 'executable': function('ale_linters#python#flake8#GetExecutable'),
\ 'command_chain': [ \ 'command': function('ale_linters#python#flake8#RunWithVersionCheck'),
\ {'callback': 'ale_linters#python#flake8#VersionCheck'},
\ {'callback': 'ale_linters#python#flake8#GetCommand', 'output_stream': 'both'},
\ ],
\ 'callback': 'ale_linters#python#flake8#Handle', \ 'callback': 'ale_linters#python#flake8#Handle',
\}) \})

View File

@ -6,26 +6,11 @@ call ale#Set('ruby_reek_show_wiki_link', 0)
call ale#Set('ruby_reek_options', '') call ale#Set('ruby_reek_options', '')
call ale#Set('ruby_reek_executable', 'reek') call ale#Set('ruby_reek_executable', 'reek')
function! ale_linters#ruby#reek#VersionCheck(buffer) abort function! ale_linters#ruby#reek#GetCommand(buffer, version) abort
" If we have previously stored the version number in a cache, then
" don't look it up again.
if ale#semver#HasVersion('reek')
" Returning an empty string skips this command.
return ''
endif
let l:executable = ale#Var(a:buffer, 'ruby_reek_executable')
return ale#handlers#ruby#EscapeExecutable(l:executable, 'reek')
\ . ' --version'
endfunction
function! ale_linters#ruby#reek#GetCommand(buffer, version_output) abort
let l:version = ale#semver#GetVersion('reek', a:version_output)
let l:executable = ale#Var(a:buffer, 'ruby_reek_executable') let l:executable = ale#Var(a:buffer, 'ruby_reek_executable')
" Tell reek what the filename is if the version of reek is new enough. " Tell reek what the filename is if the version of reek is new enough.
let l:display_name_args = ale#semver#GTE(l:version, [5, 0, 0]) let l:display_name_args = ale#semver#GTE(a:version, [5, 0, 0])
\ ? ' --stdin-filename %s' \ ? ' --stdin-filename %s'
\ : '' \ : ''
@ -70,9 +55,11 @@ endfunction
call ale#linter#Define('ruby', { call ale#linter#Define('ruby', {
\ 'name': 'reek', \ 'name': 'reek',
\ 'executable': {b -> ale#Var(b, 'ruby_reek_executable')}, \ 'executable': {b -> ale#Var(b, 'ruby_reek_executable')},
\ 'command_chain': [ \ 'command': {buffer -> ale#semver#RunWithVersionCheck(
\ {'callback': 'ale_linters#ruby#reek#VersionCheck'}, \ buffer,
\ {'callback': 'ale_linters#ruby#reek#GetCommand'}, \ ale#Var(buffer, 'ruby_reek_executable'),
\ ], \ '%e --version',
\ function('ale_linters#ruby#reek#GetCommand'),
\ )},
\ 'callback': 'ale_linters#ruby#reek#Handle', \ 'callback': 'ale_linters#ruby#reek#Handle',
\}) \})

View File

@ -22,26 +22,18 @@ function! ale_linters#rust#cargo#GetCargoExecutable(bufnr) abort
endif endif
endfunction endfunction
function! ale_linters#rust#cargo#VersionCheck(buffer) abort function! ale_linters#rust#cargo#GetCommand(buffer, version) abort
return !ale#semver#HasVersion('cargo')
\ ? 'cargo --version'
\ : ''
endfunction
function! ale_linters#rust#cargo#GetCommand(buffer, version_output) abort
let l:version = ale#semver#GetVersion('cargo', a:version_output)
let l:use_check = ale#Var(a:buffer, 'rust_cargo_use_check') let l:use_check = ale#Var(a:buffer, 'rust_cargo_use_check')
\ && ale#semver#GTE(l:version, [0, 17, 0]) \ && ale#semver#GTE(a:version, [0, 17, 0])
let l:use_all_targets = l:use_check let l:use_all_targets = l:use_check
\ && ale#Var(a:buffer, 'rust_cargo_check_all_targets') \ && ale#Var(a:buffer, 'rust_cargo_check_all_targets')
\ && ale#semver#GTE(l:version, [0, 22, 0]) \ && ale#semver#GTE(a:version, [0, 22, 0])
let l:use_examples = l:use_check let l:use_examples = l:use_check
\ && ale#Var(a:buffer, 'rust_cargo_check_examples') \ && ale#Var(a:buffer, 'rust_cargo_check_examples')
\ && ale#semver#GTE(l:version, [0, 22, 0]) \ && ale#semver#GTE(a:version, [0, 22, 0])
let l:use_tests = l:use_check let l:use_tests = l:use_check
\ && ale#Var(a:buffer, 'rust_cargo_check_tests') \ && ale#Var(a:buffer, 'rust_cargo_check_tests')
\ && ale#semver#GTE(l:version, [0, 22, 0]) \ && ale#semver#GTE(a:version, [0, 22, 0])
let l:include_features = ale#Var(a:buffer, 'rust_cargo_include_features') let l:include_features = ale#Var(a:buffer, 'rust_cargo_include_features')
@ -94,10 +86,12 @@ endfunction
call ale#linter#Define('rust', { call ale#linter#Define('rust', {
\ 'name': 'cargo', \ 'name': 'cargo',
\ 'executable': function('ale_linters#rust#cargo#GetCargoExecutable'), \ 'executable': function('ale_linters#rust#cargo#GetCargoExecutable'),
\ 'command_chain': [ \ 'command': {buffer -> ale#semver#RunWithVersionCheck(
\ {'callback': 'ale_linters#rust#cargo#VersionCheck'}, \ buffer,
\ {'callback': 'ale_linters#rust#cargo#GetCommand'}, \ ale_linters#rust#cargo#GetCargoExecutable(buffer),
\ ], \ '%e --version',
\ function('ale_linters#rust#cargo#GetCommand'),
\ )},
\ 'callback': 'ale#handlers#rust#HandleRustErrors', \ 'callback': 'ale#handlers#rust#HandleRustErrors',
\ 'output_stream': 'both', \ 'output_stream': 'both',
\ 'lint_file': 1, \ 'lint_file': 1,

View File

@ -11,10 +11,6 @@ call ale#Set('sh_shellcheck_executable', 'shellcheck')
call ale#Set('sh_shellcheck_dialect', 'auto') call ale#Set('sh_shellcheck_dialect', 'auto')
call ale#Set('sh_shellcheck_options', '') call ale#Set('sh_shellcheck_options', '')
function! ale_linters#sh#shellcheck#GetExecutable(buffer) abort
return ale#Var(a:buffer, 'sh_shellcheck_executable')
endfunction
function! ale_linters#sh#shellcheck#GetDialectArgument(buffer) abort function! ale_linters#sh#shellcheck#GetDialectArgument(buffer) abort
let l:shell_type = ale#handlers#sh#GetShellType(a:buffer) let l:shell_type = ale#handlers#sh#GetShellType(a:buffer)
@ -39,30 +35,18 @@ function! ale_linters#sh#shellcheck#GetDialectArgument(buffer) abort
return '' return ''
endfunction endfunction
function! ale_linters#sh#shellcheck#VersionCheck(buffer) abort function! ale_linters#sh#shellcheck#GetCommand(buffer, version) abort
let l:executable = ale_linters#sh#shellcheck#GetExecutable(a:buffer)
" Don't check the version again if we've already cached it.
return !ale#semver#HasVersion(l:executable)
\ ? ale#Escape(l:executable) . ' --version'
\ : ''
endfunction
function! ale_linters#sh#shellcheck#GetCommand(buffer, version_output) abort
let l:executable = ale_linters#sh#shellcheck#GetExecutable(a:buffer)
let l:version = ale#semver#GetVersion(l:executable, a:version_output)
let l:options = ale#Var(a:buffer, 'sh_shellcheck_options') let l:options = ale#Var(a:buffer, 'sh_shellcheck_options')
let l:exclude_option = ale#Var(a:buffer, 'sh_shellcheck_exclusions') let l:exclude_option = ale#Var(a:buffer, 'sh_shellcheck_exclusions')
let l:dialect = ale#Var(a:buffer, 'sh_shellcheck_dialect') let l:dialect = ale#Var(a:buffer, 'sh_shellcheck_dialect')
let l:external_option = ale#semver#GTE(l:version, [0, 4, 0]) ? ' -x' : '' let l:external_option = ale#semver#GTE(a:version, [0, 4, 0]) ? ' -x' : ''
if l:dialect is# 'auto' if l:dialect is# 'auto'
let l:dialect = ale_linters#sh#shellcheck#GetDialectArgument(a:buffer) let l:dialect = ale_linters#sh#shellcheck#GetDialectArgument(a:buffer)
endif endif
return ale#path#BufferCdString(a:buffer) return ale#path#BufferCdString(a:buffer)
\ . ale#Escape(l:executable) \ . '%e'
\ . (!empty(l:dialect) ? ' -s ' . l:dialect : '') \ . (!empty(l:dialect) ? ' -s ' . l:dialect : '')
\ . (!empty(l:options) ? ' ' . l:options : '') \ . (!empty(l:options) ? ' ' . l:options : '')
\ . (!empty(l:exclude_option) ? ' -e ' . l:exclude_option : '') \ . (!empty(l:exclude_option) ? ' -e ' . l:exclude_option : '')
@ -108,10 +92,12 @@ endfunction
call ale#linter#Define('sh', { call ale#linter#Define('sh', {
\ 'name': 'shellcheck', \ 'name': 'shellcheck',
\ 'executable': function('ale_linters#sh#shellcheck#GetExecutable'), \ 'executable': {buffer -> ale#Var(buffer, 'sh_shellcheck_executable')},
\ 'command_chain': [ \ 'command': {buffer -> ale#semver#RunWithVersionCheck(
\ {'callback': 'ale_linters#sh#shellcheck#VersionCheck'}, \ buffer,
\ {'callback': 'ale_linters#sh#shellcheck#GetCommand'}, \ ale#Var(buffer, 'sh_shellcheck_executable'),
\ ], \ '%e --version',
\ function('ale_linters#sh#shellcheck#GetCommand'),
\ )},
\ 'callback': 'ale_linters#sh#shellcheck#Handle', \ 'callback': 'ale_linters#sh#shellcheck#Handle',
\}) \})

View File

@ -7,29 +7,13 @@ call ale#Set('vim_vint_executable', 'vint')
let s:enable_neovim = has('nvim') ? ' --enable-neovim' : '' let s:enable_neovim = has('nvim') ? ' --enable-neovim' : ''
let s:format = '-f "{file_path}:{line_number}:{column_number}: {severity}: {description} (see {reference})"' let s:format = '-f "{file_path}:{line_number}:{column_number}: {severity}: {description} (see {reference})"'
function! ale_linters#vim#vint#GetExecutable(buffer) abort function! ale_linters#vim#vint#GetCommand(buffer, version) abort
return ale#Var(a:buffer, 'vim_vint_executable') let l:can_use_no_color_flag = empty(a:version)
endfunction \ || ale#semver#GTE(a:version, [0, 3, 7])
function! ale_linters#vim#vint#VersionCommand(buffer) abort
let l:executable = ale_linters#vim#vint#GetExecutable(a:buffer)
" Check the Vint version if we haven't checked it already.
return !ale#semver#HasVersion(l:executable)
\ ? ale#Escape(l:executable) . ' --version'
\ : ''
endfunction
function! ale_linters#vim#vint#GetCommand(buffer, version_output) abort
let l:executable = ale_linters#vim#vint#GetExecutable(a:buffer)
let l:version = ale#semver#GetVersion(l:executable, a:version_output)
let l:can_use_no_color_flag = empty(l:version)
\ || ale#semver#GTE(l:version, [0, 3, 7])
let l:warning_flag = ale#Var(a:buffer, 'vim_vint_show_style_issues') ? '-s' : '-w' let l:warning_flag = ale#Var(a:buffer, 'vim_vint_show_style_issues') ? '-s' : '-w'
return ale#Escape(l:executable) return '%e'
\ . ' ' . l:warning_flag \ . ' ' . l:warning_flag
\ . (l:can_use_no_color_flag ? ' --no-color' : '') \ . (l:can_use_no_color_flag ? ' --no-color' : '')
\ . s:enable_neovim \ . s:enable_neovim
@ -65,10 +49,12 @@ endfunction
call ale#linter#Define('vim', { call ale#linter#Define('vim', {
\ 'name': 'vint', \ 'name': 'vint',
\ 'executable': function('ale_linters#vim#vint#GetExecutable'), \ 'executable': {buffer -> ale#Var(buffer, 'vim_vint_executable')},
\ 'command_chain': [ \ 'command': {buffer -> ale#semver#RunWithVersionCheck(
\ {'callback': 'ale_linters#vim#vint#VersionCommand', 'output_stream': 'stderr'}, \ buffer,
\ {'callback': 'ale_linters#vim#vint#GetCommand', 'output_stream': 'stdout'}, \ ale#Var(buffer, 'vim_vint_executable'),
\ ], \ '%e --version',
\ function('ale_linters#vim#vint#GetCommand'),
\ )},
\ 'callback': 'ale_linters#vim#vint#Handle', \ 'callback': 'ale_linters#vim#vint#Handle',
\}) \})

View File

@ -1,7 +1,7 @@
let s:chain_results = [] let s:command_output = []
function! ale#assert#WithChainResults(...) abort function! ale#assert#GivenCommandOutput(...) abort
let s:chain_results = a:000 let s:command_output = a:000
endfunction endfunction
function! s:GetLinter() abort function! s:GetLinter() abort
@ -19,6 +19,39 @@ function! s:GetLinter() abort
return l:filetype_linters[0] return l:filetype_linters[0]
endfunction endfunction
function! s:FormatExe(command, executable) abort
return substitute(a:command, '%e', '\=ale#Escape(a:executable)', 'g')
endfunction
function! s:ProcessDeferredCommands(initial_result) abort
let l:result = a:initial_result
let l:command_index = 0
let l:command = []
while ale#command#IsDeferred(l:result)
call add(l:command, s:FormatExe(l:result.command, l:result.executable))
if get(g:, 'ale_run_synchronously_emulate_commands')
" Don't run commands, but simulate the results.
let l:Callback = g:ale_run_synchronously_callbacks[0]
let l:output = get(s:command_output, l:command_index, [])
call l:Callback(0, l:output)
unlet g:ale_run_synchronously_callbacks
let l:command_index += 1
else
" Run the commands in the shell, synchronously.
call ale#test#FlushJobs()
endif
let l:result = l:result.value
endwhile
call add(l:command, l:result)
return l:command
endfunction
" Load the currently loaded linter for a test case, and check that the command " Load the currently loaded linter for a test case, and check that the command
" matches the given string. " matches the given string.
function! ale#assert#Linter(expected_executable, expected_command) abort function! ale#assert#Linter(expected_executable, expected_command) abort
@ -31,47 +64,20 @@ function! ale#assert#Linter(expected_executable, expected_command) abort
let l:executable = l:executable.value let l:executable = l:executable.value
endwhile endwhile
if has_key(l:linter, 'command_chain') let l:command = s:ProcessDeferredCommands(
let l:callbacks = map(copy(l:linter.command_chain), 'v:val.callback') \ ale#linter#GetCommand(l:buffer, l:linter),
\)
" If the expected command is a string, just check the last one. if type(a:expected_command) isnot v:t_list
if type(a:expected_command) is v:t_string let l:command = l:command[-1]
if len(l:callbacks) is 1
let l:command = call(l:callbacks[0], [l:buffer])
else
let l:input = get(s:chain_results, len(l:callbacks) - 2, [])
let l:command = call(l:callbacks[-1], [l:buffer, l:input])
endif
else
let l:command = []
let l:chain_index = 0
for l:Callback in l:callbacks
if l:chain_index is 0
call add(l:command, call(l:Callback, [l:buffer]))
else
let l:input = get(s:chain_results, l:chain_index - 1, [])
call add(l:command, call(l:Callback, [l:buffer, l:input]))
endif
let l:chain_index += 1
endfor
endif
else
let l:command = ale#linter#GetCommand(l:buffer, l:linter)
while ale#command#IsDeferred(l:command)
call ale#test#FlushJobs()
let l:command = l:command.value
endwhile
endif endif
if type(l:command) is v:t_string if type(l:command) is v:t_string
" Replace %e with the escaped executable, so tests keep passing after " Replace %e with the escaped executable, so tests keep passing after
" linters are changed to use %e. " linters are changed to use %e.
let l:command = substitute(l:command, '%e', '\=ale#Escape(l:executable)', 'g') let l:command = s:FormatExe(l:command, l:executable)
elseif type(l:command) is v:t_list elseif type(l:command) is v:t_list
call map(l:command, 'substitute(v:val, ''%e'', ''\=ale#Escape(l:executable)'', ''g'')') call map(l:command, 's:FormatExe(v:val, l:executable)')
endif endif
AssertEqual AssertEqual
@ -79,6 +85,17 @@ function! ale#assert#Linter(expected_executable, expected_command) abort
\ [l:executable, l:command] \ [l:executable, l:command]
endfunction endfunction
function! ale#assert#Fixer(expected_result) abort
let l:buffer = bufnr('')
let l:result = s:ProcessDeferredCommands(s:FixerFunction(l:buffer))
if type(a:expected_result) isnot v:t_list
let l:result = l:result[-1]
endif
AssertEqual a:expected_result, l:result
endfunction
function! ale#assert#LinterNotExecuted() abort function! ale#assert#LinterNotExecuted() abort
let l:buffer = bufnr('') let l:buffer = bufnr('')
let l:linter = s:GetLinter() let l:linter = s:GetLinter()
@ -128,7 +145,7 @@ function! ale#assert#LSPAddress(expected_address) abort
endfunction endfunction
function! ale#assert#SetUpLinterTestCommands() abort function! ale#assert#SetUpLinterTestCommands() abort
command! -nargs=+ WithChainResults :call ale#assert#WithChainResults(<args>) command! -nargs=+ GivenCommandOutput :call ale#assert#GivenCommandOutput(<args>)
command! -nargs=+ AssertLinter :call ale#assert#Linter(<args>) command! -nargs=+ AssertLinter :call ale#assert#Linter(<args>)
command! -nargs=0 AssertLinterNotExecuted :call ale#assert#LinterNotExecuted() command! -nargs=0 AssertLinterNotExecuted :call ale#assert#LinterNotExecuted()
command! -nargs=+ AssertLSPOptions :call ale#assert#LSPOptions(<args>) command! -nargs=+ AssertLSPOptions :call ale#assert#LSPOptions(<args>)
@ -138,6 +155,11 @@ function! ale#assert#SetUpLinterTestCommands() abort
command! -nargs=+ AssertLSPAddress :call ale#assert#LSPAddress(<args>) command! -nargs=+ AssertLSPAddress :call ale#assert#LSPAddress(<args>)
endfunction endfunction
function! ale#assert#SetUpFixerTestCommands() abort
command! -nargs=+ GivenCommandOutput :call ale#assert#GivenCommandOutput(<args>)
command! -nargs=+ AssertFixer :call ale#assert#Fixer(<args>)
endfunction
" A dummy function for making sure this module is loaded. " A dummy function for making sure this module is loaded.
function! ale#assert#SetUpLinterTest(filetype, name) abort function! ale#assert#SetUpLinterTest(filetype, name) abort
" Set up a marker so ALE doesn't create real random temporary filenames. " Set up a marker so ALE doesn't create real random temporary filenames.
@ -179,14 +201,21 @@ function! ale#assert#SetUpLinterTest(filetype, name) abort
endif endif
call ale#assert#SetUpLinterTestCommands() call ale#assert#SetUpLinterTestCommands()
let g:ale_run_synchronously = 1
let g:ale_run_synchronously_emulate_commands = 1
endfunction endfunction
function! ale#assert#TearDownLinterTest() abort function! ale#assert#TearDownLinterTest() abort
unlet! g:ale_create_dummy_temporary_file unlet! g:ale_create_dummy_temporary_file
let s:chain_results = [] unlet! g:ale_run_synchronously
unlet! g:ale_run_synchronously_callbacks
unlet! g:ale_run_synchronously_emulate_commands
unlet! g:ale_run_synchronously_command_results
let s:command_output = []
if exists(':WithChainResults') if exists(':GivenCommandOutput')
delcommand WithChainResults delcommand GivenCommandOutput
endif endif
if exists(':AssertLinter') if exists(':AssertLinter')
@ -229,3 +258,62 @@ function! ale#assert#TearDownLinterTest() abort
call ale#semver#ResetVersionCache() call ale#semver#ResetVersionCache()
endif endif
endfunction endfunction
function! ale#assert#SetUpFixerTest(filetype, name) abort
" Set up a marker so ALE doesn't create real random temporary filenames.
let g:ale_create_dummy_temporary_file = 1
let l:function_name = ale#fix#registry#GetFunc(a:name)
let s:FixerFunction = function(l:function_name)
let l:prefix = 'ale_' . a:filetype . '_' . a:name
let b:filter_expr = 'v:val[: len(l:prefix) - 1] is# l:prefix'
for l:key in filter(keys(g:), b:filter_expr)
execute 'Save g:' . l:key
unlet g:[l:key]
endfor
for l:key in filter(keys(b:), b:filter_expr)
unlet b:[l:key]
endfor
execute 'runtime autoload/ale/fixers/' . a:name . '.vim'
if !exists('g:dir')
call ale#test#SetDirectory('/testplugin/test/fixers')
endif
call ale#assert#SetUpFixerTestCommands()
let g:ale_run_synchronously = 1
let g:ale_run_synchronously_emulate_commands = 1
endfunction
function! ale#assert#TearDownFixerTest() abort
unlet! g:ale_create_dummy_temporary_file
unlet! g:ale_run_synchronously
unlet! g:ale_run_synchronously_callbacks
unlet! g:ale_run_synchronously_emulate_commands
unlet! g:ale_run_synchronously_command_results
let s:command_output = []
unlet! s:FixerFunction
if exists('g:dir')
call ale#test#RestoreDirectory()
endif
Restore
if exists('*ale#semver#ResetVersionCache')
call ale#semver#ResetVersionCache()
endif
if exists(':GivenCommandOutput')
delcommand GivenCommandOutput
endif
if exists(':AssertFixer')
delcommand AssertFixer
endif
endfunction

View File

@ -284,6 +284,20 @@ function! ale#c#GetMakeCommand(buffer) abort
return '' return ''
endfunction endfunction
function! ale#c#RunMakeCommand(buffer, Callback) abort
let l:command = ale#c#GetMakeCommand(a:buffer)
if empty(l:command)
return a:Callback(a:buffer, [])
endif
return ale#command#Run(
\ a:buffer,
\ l:command,
\ {b, output -> a:Callback(a:buffer, output)},
\)
endfunction
" Given a buffer number, search for a project root, and output a List " Given a buffer number, search for a project root, and output a List
" of directories to include based on some heuristics. " of directories to include based on some heuristics.
" "

View File

@ -329,30 +329,46 @@ function! ale#command#Run(buffer, command, Callback, ...) abort
" "
" The `_deferred_job_id` is used for both checking the type of object, and " The `_deferred_job_id` is used for both checking the type of object, and
" for checking the job ID and status. " for checking the job ID and status.
let l:result = {'_deferred_job_id': l:job_id} "
" The original command here is used in tests.
let l:result = {
\ '_deferred_job_id': l:job_id,
\ 'executable': get(l:options, 'executable', ''),
\ 'command': a:command,
\}
if get(g:, 'ale_run_synchronously') == 1 && l:job_id if get(g:, 'ale_run_synchronously') == 1 && l:job_id
" Run a command synchronously if this test option is set.
call extend(l:line_list, systemlist(
\ type(l:command) is v:t_list
\ ? join(l:command[0:1]) . ' ' . ale#Escape(l:command[2])
\ : l:command
\))
" Don't capture output when the callbacks aren't set.
if !has_key(l:job_options, 'out_cb')
\&& !has_key(l:job_options, 'err_cb')
let l:line_list = []
endif
if !exists('g:ale_run_synchronously_callbacks') if !exists('g:ale_run_synchronously_callbacks')
let g:ale_run_synchronously_callbacks = [] let g:ale_run_synchronously_callbacks = []
endif endif
call add( if get(g:, 'ale_run_synchronously_emulate_commands', 0)
\ g:ale_run_synchronously_callbacks, call add(
\ {-> l:job_options.exit_cb(l:job_id, v:shell_error)} \ g:ale_run_synchronously_callbacks,
\) \ {exit_code, output -> [
\ extend(l:line_list, output),
\ l:job_options.exit_cb(l:job_id, exit_code),
\ ]}
\)
else
" Run a command synchronously if this test option is set.
call extend(l:line_list, systemlist(
\ type(l:command) is v:t_list
\ ? join(l:command[0:1]) . ' ' . ale#Escape(l:command[2])
\ : l:command
\))
" Don't capture output when the callbacks aren't set.
if !has_key(l:job_options, 'out_cb')
\&& !has_key(l:job_options, 'err_cb')
let l:line_list = []
endif
call add(
\ g:ale_run_synchronously_callbacks,
\ {-> l:job_options.exit_cb(l:job_id, v:shell_error)}
\)
endif
endif endif
return l:result return l:result

View File

@ -1,6 +1,10 @@
" Author: Auri <me@aurieh.me> " Author: Auri <me@aurieh.me>
" Description: Functions for integrating with D linters. " Description: Functions for integrating with D linters.
function! otherproject#util#Double(x) abort
return a:x * 2
endfunction
function! ale#d#FindDUBConfig(buffer) abort function! ale#d#FindDUBConfig(buffer) abort
" Find a DUB configuration file in ancestor paths. " Find a DUB configuration file in ancestor paths.
" The most DUB-specific names will be tried first. " The most DUB-specific names will be tried first.

View File

@ -3,15 +3,15 @@
function! ale#fixers#eslint#Fix(buffer) abort function! ale#fixers#eslint#Fix(buffer) abort
let l:executable = ale#handlers#eslint#GetExecutable(a:buffer) let l:executable = ale#handlers#eslint#GetExecutable(a:buffer)
let l:command = ale#node#Executable(a:buffer, l:executable)
\ . ' --version'
let l:command = ale#semver#HasVersion(l:executable) return ale#semver#RunWithVersionCheck(
\ ? '' \ a:buffer,
\ : ale#node#Executable(a:buffer, l:executable) . ' --version' \ l:executable,
\ l:command,
return { \ function('ale#fixers#eslint#ApplyFixForVersion'),
\ 'command': l:command, \)
\ 'chain_with': 'ale#fixers#eslint#ApplyFixForVersion',
\}
endfunction endfunction
function! ale#fixers#eslint#ProcessFixDryRunOutput(buffer, output) abort function! ale#fixers#eslint#ProcessFixDryRunOutput(buffer, output) abort
@ -33,10 +33,8 @@ function! ale#fixers#eslint#ProcessEslintDOutput(buffer, output) abort
return a:output return a:output
endfunction endfunction
function! ale#fixers#eslint#ApplyFixForVersion(buffer, version_output) abort function! ale#fixers#eslint#ApplyFixForVersion(buffer, version) abort
let l:executable = ale#handlers#eslint#GetExecutable(a:buffer) let l:executable = ale#handlers#eslint#GetExecutable(a:buffer)
let l:version = ale#semver#GetVersion(l:executable, a:version_output)
let l:config = ale#handlers#eslint#FindConfig(a:buffer) let l:config = ale#handlers#eslint#FindConfig(a:buffer)
if empty(l:config) if empty(l:config)
@ -44,7 +42,7 @@ function! ale#fixers#eslint#ApplyFixForVersion(buffer, version_output) abort
endif endif
" Use --fix-to-stdout with eslint_d " Use --fix-to-stdout with eslint_d
if l:executable =~# 'eslint_d$' && ale#semver#GTE(l:version, [3, 19, 0]) if l:executable =~# 'eslint_d$' && ale#semver#GTE(a:version, [3, 19, 0])
return { return {
\ 'command': ale#node#Executable(a:buffer, l:executable) \ 'command': ale#node#Executable(a:buffer, l:executable)
\ . ' --stdin-filename %s --stdin --fix-to-stdout', \ . ' --stdin-filename %s --stdin --fix-to-stdout',
@ -53,7 +51,7 @@ function! ale#fixers#eslint#ApplyFixForVersion(buffer, version_output) abort
endif endif
" 4.9.0 is the first version with --fix-dry-run " 4.9.0 is the first version with --fix-dry-run
if ale#semver#GTE(l:version, [4, 9, 0]) if ale#semver#GTE(a:version, [4, 9, 0])
return { return {
\ 'command': ale#node#Executable(a:buffer, l:executable) \ 'command': ale#node#Executable(a:buffer, l:executable)
\ . ' --stdin-filename %s --stdin --fix-dry-run --format=json', \ . ' --stdin-filename %s --stdin --fix-dry-run --format=json',

View File

@ -15,16 +15,12 @@ function! ale#fixers#prettier#GetExecutable(buffer) abort
endfunction endfunction
function! ale#fixers#prettier#Fix(buffer) abort function! ale#fixers#prettier#Fix(buffer) abort
let l:executable = ale#fixers#prettier#GetExecutable(a:buffer) return ale#semver#RunWithVersionCheck(
\ a:buffer,
let l:command = ale#semver#HasVersion(l:executable) \ ale#fixers#prettier#GetExecutable(a:buffer),
\ ? '' \ '%e --version',
\ : ale#Escape(l:executable) . ' --version' \ function('ale#fixers#prettier#ApplyFixForVersion'),
\)
return {
\ 'command': l:command,
\ 'chain_with': 'ale#fixers#prettier#ApplyFixForVersion',
\}
endfunction endfunction
function! ale#fixers#prettier#ProcessPrettierDOutput(buffer, output) abort function! ale#fixers#prettier#ProcessPrettierDOutput(buffer, output) abort
@ -38,10 +34,9 @@ function! ale#fixers#prettier#ProcessPrettierDOutput(buffer, output) abort
return a:output return a:output
endfunction endfunction
function! ale#fixers#prettier#ApplyFixForVersion(buffer, version_output) abort function! ale#fixers#prettier#ApplyFixForVersion(buffer, version) abort
let l:executable = ale#fixers#prettier#GetExecutable(a:buffer) let l:executable = ale#fixers#prettier#GetExecutable(a:buffer)
let l:options = ale#Var(a:buffer, 'javascript_prettier_options') let l:options = ale#Var(a:buffer, 'javascript_prettier_options')
let l:version = ale#semver#GetVersion(l:executable, a:version_output)
let l:parser = '' let l:parser = ''
" Append the --parser flag depending on the current filetype (unless it's " Append the --parser flag depending on the current filetype (unless it's
@ -50,7 +45,7 @@ function! ale#fixers#prettier#ApplyFixForVersion(buffer, version_output) abort
" Mimic Prettier's defaults. In cases without a file extension or " Mimic Prettier's defaults. In cases without a file extension or
" filetype (scratch buffer), Prettier needs `parser` set to know how " filetype (scratch buffer), Prettier needs `parser` set to know how
" to process the buffer. " to process the buffer.
if ale#semver#GTE(l:version, [1, 16, 0]) if ale#semver#GTE(a:version, [1, 16, 0])
let l:parser = 'babel' let l:parser = 'babel'
else else
let l:parser = 'babylon' let l:parser = 'babylon'
@ -94,7 +89,7 @@ function! ale#fixers#prettier#ApplyFixForVersion(buffer, version_output) abort
endif endif
" 1.4.0 is the first version with --stdin-filepath " 1.4.0 is the first version with --stdin-filepath
if ale#semver#GTE(l:version, [1, 4, 0]) if ale#semver#GTE(a:version, [1, 4, 0])
return { return {
\ 'command': ale#path#BufferCdString(a:buffer) \ 'command': ale#path#BufferCdString(a:buffer)
\ . ale#Escape(l:executable) \ . ale#Escape(l:executable)

View File

@ -2,13 +2,9 @@
" w0rp <devw0rp@gmail.com>, morhetz (Pavel Pertsev) <morhetz@gmail.com> " w0rp <devw0rp@gmail.com>, morhetz (Pavel Pertsev) <morhetz@gmail.com>
" Description: Integration between Prettier and ESLint. " Description: Integration between Prettier and ESLint.
function! ale#fixers#prettier_eslint#SetOptionDefaults() abort call ale#Set('javascript_prettier_eslint_executable', 'prettier-eslint')
call ale#Set('javascript_prettier_eslint_executable', 'prettier-eslint') call ale#Set('javascript_prettier_eslint_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#Set('javascript_prettier_eslint_use_global', get(g:, 'ale_use_global_executables', 0)) call ale#Set('javascript_prettier_eslint_options', '')
call ale#Set('javascript_prettier_eslint_options', '')
endfunction
call ale#fixers#prettier_eslint#SetOptionDefaults()
function! ale#fixers#prettier_eslint#GetExecutable(buffer) abort function! ale#fixers#prettier_eslint#GetExecutable(buffer) abort
return ale#node#FindExecutable(a:buffer, 'javascript_prettier_eslint', [ return ale#node#FindExecutable(a:buffer, 'javascript_prettier_eslint', [
@ -18,26 +14,20 @@ function! ale#fixers#prettier_eslint#GetExecutable(buffer) abort
endfunction endfunction
function! ale#fixers#prettier_eslint#Fix(buffer) abort function! ale#fixers#prettier_eslint#Fix(buffer) abort
let l:executable = ale#fixers#prettier_eslint#GetExecutable(a:buffer) return ale#semver#RunWithVersionCheck(
\ a:buffer,
let l:command = ale#semver#HasVersion(l:executable) \ ale#fixers#prettier_eslint#GetExecutable(a:buffer),
\ ? '' \ '%e --version',
\ : ale#Escape(l:executable) . ' --version' \ function('ale#fixers#prettier_eslint#ApplyFixForVersion'),
\)
return {
\ 'command': l:command,
\ 'chain_with': 'ale#fixers#prettier_eslint#ApplyFixForVersion',
\}
endfunction endfunction
function! ale#fixers#prettier_eslint#ApplyFixForVersion(buffer, version_output) abort function! ale#fixers#prettier_eslint#ApplyFixForVersion(buffer, version) abort
let l:options = ale#Var(a:buffer, 'javascript_prettier_eslint_options') let l:options = ale#Var(a:buffer, 'javascript_prettier_eslint_options')
let l:executable = ale#fixers#prettier_eslint#GetExecutable(a:buffer) let l:executable = ale#fixers#prettier_eslint#GetExecutable(a:buffer)
let l:version = ale#semver#GetVersion(l:executable, a:version_output)
" 4.2.0 is the first version with --eslint-config-path " 4.2.0 is the first version with --eslint-config-path
let l:config = ale#semver#GTE(l:version, [4, 2, 0]) let l:config = ale#semver#GTE(a:version, [4, 2, 0])
\ ? ale#handlers#eslint#FindConfig(a:buffer) \ ? ale#handlers#eslint#FindConfig(a:buffer)
\ : '' \ : ''
let l:eslint_config_option = !empty(l:config) let l:eslint_config_option = !empty(l:config)
@ -45,7 +35,7 @@ function! ale#fixers#prettier_eslint#ApplyFixForVersion(buffer, version_output)
\ : '' \ : ''
" 4.4.0 is the first version with --stdin-filepath " 4.4.0 is the first version with --stdin-filepath
if ale#semver#GTE(l:version, [4, 4, 0]) if ale#semver#GTE(a:version, [4, 4, 0])
return { return {
\ 'command': ale#path#BufferCdString(a:buffer) \ 'command': ale#path#BufferCdString(a:buffer)
\ . ale#Escape(l:executable) \ . ale#Escape(l:executable)

View File

@ -32,7 +32,7 @@ endfunction
" "
" The executable is only prefixed for Windows machines " The executable is only prefixed for Windows machines
function! ale#node#Executable(buffer, executable) abort function! ale#node#Executable(buffer, executable) abort
if ale#Has('win32') && a:executable =~? '\.js$' if has('win32') && a:executable =~? '\.js$'
let l:node = ale#Var(a:buffer, 'windows_node_executable_path') let l:node = ale#Var(a:buffer, 'windows_node_executable_path')
return ale#Escape(l:node) . ' ' . ale#Escape(a:executable) return ale#Escape(l:node) . ' ' . ale#Escape(a:executable)

View File

@ -5,31 +5,52 @@ function! ale#semver#ResetVersionCache() abort
let s:version_cache = {} let s:version_cache = {}
endfunction endfunction
function! ale#semver#ParseVersion(version_lines) abort
for l:line in a:version_lines
let l:match = matchlist(l:line, '\v(\d+)\.(\d+)(\.(\d+))?')
if !empty(l:match)
return [l:match[1] + 0, l:match[2] + 0, l:match[4] + 0]
endif
endfor
return []
endfunction
" Given an executable name and some lines of output, which can be empty, " Given an executable name and some lines of output, which can be empty,
" parse the version from the lines of output, or return the cached version " parse the version from the lines of output, or return the cached version
" triple [major, minor, patch] " triple [major, minor, patch]
" "
" If the version cannot be found, an empty List will be returned instead. " If the version cannot be found, an empty List will be returned instead.
function! ale#semver#GetVersion(executable, version_lines) abort function! s:GetVersion(executable, version_lines) abort
let l:version = get(s:version_cache, a:executable, []) let l:version = get(s:version_cache, a:executable, [])
let l:parsed_version = ale#semver#ParseVersion(a:version_lines)
for l:line in a:version_lines if !empty(l:parsed_version)
let l:match = matchlist(l:line, '\v(\d+)\.(\d+)(\.(\d+))?') let l:version = l:parsed_version
let s:version_cache[a:executable] = l:version
if !empty(l:match) endif
let l:version = [l:match[1] + 0, l:match[2] + 0, l:match[4] + 0]
let s:version_cache[a:executable] = l:version
break
endif
endfor
return l:version return l:version
endfunction endfunction
" Return 1 if the semver version has been cached for a given executable. function! ale#semver#RunWithVersionCheck(buffer, executable, command, Callback) abort
function! ale#semver#HasVersion(executable) abort if empty(a:executable)
return has_key(s:version_cache, a:executable) return ''
endif
let l:cache = s:version_cache
if has_key(s:version_cache, a:executable)
return a:Callback(a:buffer, s:version_cache[a:executable])
endif
return ale#command#Run(
\ a:buffer,
\ a:command,
\ {_, output -> a:Callback(a:buffer, s:GetVersion(a:executable, output))},
\ {'output_stream': 'both', 'executable': a:executable}
\)
endfunction endfunction
" Given two triples of integers [major, minor, patch], compare the triples " Given two triples of integers [major, minor, patch], compare the triples

View File

@ -12,6 +12,7 @@ CONTENTS *ale-development-contents*
3. Coding Standards.....................|ale-coding-standards| 3. Coding Standards.....................|ale-coding-standards|
4. Testing ALE..........................|ale-development-tests| 4. Testing ALE..........................|ale-development-tests|
4.1. Writing Linter Tests.............|ale-development-linter-tests| 4.1. Writing Linter Tests.............|ale-development-linter-tests|
4.2. Writing Fixer Tests..............|ale-development-fixer-tests|
=============================================================================== ===============================================================================
1. Introduction *ale-development-introduction* 1. Introduction *ale-development-introduction*
@ -288,10 +289,10 @@ and should be written like so. >
AssertLinter 'some-command', ale#Escape('some-command') . ' --foo' AssertLinter 'some-command', ale#Escape('some-command') . ' --foo'
Execute(Check chained commands): Execute(Check chained commands):
" WithChainResults can be called with 1 or more list for passing output " GivenCommandOutput can be called with 1 or more list for passing output
" to chained commands. The output for each callback defaults to an empty " to chained commands. The output for each callback defaults to an empty
" list. " list.
WithChainResults ['v2.1.2'] GivenCommandOutput ['v2.1.2']
" Given a List of commands, check all of them. " Given a List of commands, check all of them.
" Given a String, only the last command in the chain will be checked. " Given a String, only the last command in the chain will be checked.
AssertLinter 'some-command', [ AssertLinter 'some-command', [
@ -302,7 +303,7 @@ and should be written like so. >
The full list of commands that will be temporarily defined for linter tests The full list of commands that will be temporarily defined for linter tests
given the above setup are as follows. given the above setup are as follows.
`WithChainResults [...]` - Define output for command chain functions. `GivenCommandOutput [...]` - Define output for ale#command#Run.
`AssertLinter executable, command` - Check the executable and command. `AssertLinter executable, command` - Check the executable and command.
`AssertLinterNotExecuted` - Check that linters will not be executed. `AssertLinterNotExecuted` - Check that linters will not be executed.
`AssertLSPLanguage language` - Check the language given to an LSP server. `AssertLSPLanguage language` - Check the language given to an LSP server.
@ -311,5 +312,46 @@ given the above setup are as follows.
`AssertLSPProject project_root` - Check the root given to an LSP server. `AssertLSPProject project_root` - Check the root given to an LSP server.
`AssertLSPAddress address` - Check the address to an LSP server. `AssertLSPAddress address` - Check the address to an LSP server.
===============================================================================
4.2 Writing Fixer Tests *ale-development-fixer-tests*
Tests for ALE fixers should go in the `test/fixers` directory, and should
be written like so. >
Before:
" Load the fixer and set up a series of commands, reset fixer variables,
" clear caches, etc.
"
" Vader's 'Save' command will be called here for fixer variables.
call ale#assert#SetUpFixerTest('filetype', 'fixer_name')
After:
" Reset fixers, variables, etc.
"
" Vader's 'Restore' command will be called here.
call ale#assert#TearDownFixerTest()
Execute(The default command should be correct):
" AssertFixer checks the result of the loaded fixer function.
AssertFixer {'command': ale#Escape('some-command') . ' --foo'}
Execute(Check chained commands):
" Same as above for linter tests.
GivenCommandOutput ['v2.1.2']
" Given a List of commands, check all of them.
" Given anything else, only the last result will be checked.
AssertFixer [
\ ale#Escape('some-command') . ' --version',
\ {'command': ale#Escape('some-command') . ' --foo'}
\]
<
The full list of commands that will be temporarily defined for fixer tests
given the above setup are as follows.
`GivenCommandOutput [...]` - Define output for ale#command#Run.
`AssertFixer results` - Check the fixer results
=============================================================================== ===============================================================================
vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:

View File

@ -13,8 +13,8 @@ After:
call ale#assert#TearDownLinterTest() call ale#assert#TearDownLinterTest()
Execute(The executable should be configurable): Execute(The executable should be configurable):
AssertLinter 'clang', ['', ale#Escape('clang') . b:command_tail] AssertLinter 'clang', [ale#Escape('clang') . b:command_tail]
let b:ale_c_clang_executable = 'foobar' let b:ale_c_clang_executable = 'foobar'
AssertLinter 'foobar', ['', ale#Escape('foobar') . b:command_tail] AssertLinter 'foobar', [ale#Escape('foobar') . b:command_tail]

View File

@ -14,8 +14,8 @@ After:
unlet! b:command_tail unlet! b:command_tail
Execute(The executable should be configurable): Execute(The executable should be configurable):
AssertLinter 'gcc', ['', ale#Escape('gcc') . b:command_tail] AssertLinter 'gcc', [ale#Escape('gcc') . b:command_tail]
let b:ale_c_gcc_executable = 'foobar' let b:ale_c_gcc_executable = 'foobar'
AssertLinter 'foobar', ['', ale#Escape('foobar') . b:command_tail] AssertLinter 'foobar', [ale#Escape('foobar') . b:command_tail]

View File

@ -1,106 +1,113 @@
Before: Before:
call ale#assert#SetUpLinterTest('rust', 'cargo') call ale#assert#SetUpLinterTest('rust', 'cargo')
call ale#test#SetFilename('cargo_paths/test.rs')
let g:cd = 'cd ' . ale#Escape(ale#path#Simplify(g:dir . '/cargo_paths')) . ' && '
let g:suffix = ' --frozen --message-format=json -q' let g:suffix = ' --frozen --message-format=json -q'
let g:ale_rust_cargo_avoid_whole_workspace = 0
" Test with version 0.22.0 by default. " Test with version 0.22.0 by default.
WithChainResults ['cargo 0.22.0 (3423351a5 2017-10-06)'] GivenCommandOutput ['cargo 0.22.0 (3423351a5 2017-10-06)']
After: After:
call ale#assert#TearDownLinterTest() call ale#assert#TearDownLinterTest()
unlet! g:cd
unlet! g:suffix unlet! g:suffix
Execute(The linter should not be executed when there's no Cargo.toml file): Execute(The linter should not be executed when there's no Cargo.toml file):
call ale#test#SetFilename('../foo.rs')
AssertLinterNotExecuted AssertLinterNotExecuted
Execute(The linter should be executed when there is a Cargo.toml file): Execute(The linter should be executed when there is a Cargo.toml file):
call ale#test#SetFilename('cargo_paths/test.rs') GivenCommandOutput []
AssertLinter 'cargo', 'cargo build --frozen --message-format=json -q'
WithChainResults []
AssertLinter 'cargo',
\ 'cd ' . ale#Escape(ale#path#Simplify(g:dir . '/cargo_paths')) . ' && '
\ . 'cargo build --frozen --message-format=json -q'
Execute(The default command should be correct):
WithChainResults []
AssertLinter '', ['cargo --version', 'cargo build' . g:suffix]
Execute(`cargo check` should be used when the version is new enough): Execute(`cargo check` should be used when the version is new enough):
WithChainResults ['cargo 0.17.0 (3423351a5 2017-10-06)'] GivenCommandOutput ['cargo 0.17.0 (3423351a5 2017-10-06)']
AssertLinter '', ['cargo --version', 'cargo check' . g:suffix] AssertLinter 'cargo', [
\ ale#Escape('cargo') . ' --version',
\ 'cargo check' . g:suffix,
\]
" We should cache the version check " We should cache the version check
WithChainResults [] GivenCommandOutput []
AssertLinter '', ['', 'cargo check' . g:suffix] AssertLinter 'cargo', ['cargo check' . g:suffix]
Execute(`cargo build` should be used when cargo is too old): Execute(`cargo build` should be used when cargo is too old):
WithChainResults ['cargo 0.16.0 (3423351a5 2017-10-06)'] GivenCommandOutput ['cargo 0.16.0 (3423351a5 2017-10-06)']
AssertLinter '', ['cargo --version', 'cargo build' . g:suffix] AssertLinter 'cargo', [
\ ale#Escape('cargo') . ' --version',
\ 'cargo build' . g:suffix,
\]
WithChainResults [] GivenCommandOutput []
AssertLinter '', ['', 'cargo build' . g:suffix] AssertLinter 'cargo', ['cargo build' . g:suffix]
Execute(`cargo build` should be used when g:ale_rust_cargo_use_check is set to 0): Execute(`cargo build` should be used when g:ale_rust_cargo_use_check is set to 0):
let g:ale_rust_cargo_use_check = 0 let g:ale_rust_cargo_use_check = 0
WithChainResults ['cargo 0.24.0 (3423351a5 2017-10-06)'] GivenCommandOutput ['cargo 0.24.0 (3423351a5 2017-10-06)']
AssertLinter '', ['cargo --version', 'cargo build' . g:suffix] AssertLinter 'cargo', [
\ ale#Escape('cargo') . ' --version',
\ 'cargo build' . g:suffix,
\]
" We should cache the version check " We should cache the version check
WithChainResults [] GivenCommandOutput []
AssertLinter '', ['', 'cargo build' . g:suffix] AssertLinter 'cargo', ['cargo build' . g:suffix]
Execute(`cargo check` should be used when the version is new enough): Execute(`cargo check` should be used when the version is new enough):
AssertLinter '', ['cargo --version', 'cargo check' . g:suffix] AssertLinter 'cargo', [
\ ale#Escape('cargo') . ' --version',
\ 'cargo check' . g:suffix,
\]
" We should cache the version check " We should cache the version check
WithChainResults [] GivenCommandOutput []
AssertLinter '', ['', 'cargo check' . g:suffix] AssertLinter 'cargo', ['cargo check' . g:suffix]
Execute(--all-targets should be used when g:ale_rust_cargo_check_all_targets is set to 1): Execute(--all-targets should be used when g:ale_rust_cargo_check_all_targets is set to 1):
let g:ale_rust_cargo_check_all_targets = 1 let g:ale_rust_cargo_check_all_targets = 1
AssertLinter '', ['cargo --version', 'cargo check --all-targets' . g:suffix] AssertLinter 'cargo', [ale#Escape('cargo') . ' --version', 'cargo check --all-targets' . g:suffix]
" We should cache the version check " We should cache the version check
WithChainResults [] AssertLinter 'cargo', ['cargo check --all-targets' . g:suffix]
AssertLinter '', ['', 'cargo check --all-targets' . g:suffix]
Execute(--tests should be used when g:ale_rust_cargo_check_tests is set to 1): Execute(--tests should be used when g:ale_rust_cargo_check_tests is set to 1):
let g:ale_rust_cargo_check_tests = 1 let g:ale_rust_cargo_check_tests = 1
AssertLinter '', ['cargo --version', 'cargo check --tests' . g:suffix] AssertLinter 'cargo', [ale#Escape('cargo') . ' --version', 'cargo check --tests' . g:suffix]
" We should cache the version check " We should cache the version check
WithChainResults [] GivenCommandOutput []
AssertLinter '', ['', 'cargo check --tests' . g:suffix] AssertLinter 'cargo', ['cargo check --tests' . g:suffix]
Execute(--examples should be used when g:ale_rust_cargo_check_examples is set to 1): Execute(--examples should be used when g:ale_rust_cargo_check_examples is set to 1):
let g:ale_rust_cargo_check_examples = 1 let g:ale_rust_cargo_check_examples = 1
AssertLinter '', ['cargo --version', 'cargo check --examples' . g:suffix] AssertLinter 'cargo', [ale#Escape('cargo') . ' --version', 'cargo check --examples' . g:suffix]
" We should cache the version check " We should cache the version check
WithChainResults [] GivenCommandOutput []
AssertLinter '', ['', 'cargo check --examples' . g:suffix] AssertLinter 'cargo', ['cargo check --examples' . g:suffix]
Execute(--no-default-features should be used when g:ale_rust_cargo_default_feature_behavior is none): Execute(--no-default-features should be used when g:ale_rust_cargo_default_feature_behavior is none):
let b:ale_rust_cargo_default_feature_behavior = 'none' let b:ale_rust_cargo_default_feature_behavior = 'none'
AssertLinter '', ['cargo --version', 'cargo check --frozen --message-format=json -q --no-default-features'] AssertLinter 'cargo', [ale#Escape('cargo') . ' --version', 'cargo check --frozen --message-format=json -q --no-default-features']
Execute(g:ale_rust_cargo_include_features added when g:ale_rust_cargo_default_feature_behavior is none): Execute(g:ale_rust_cargo_include_features added when g:ale_rust_cargo_default_feature_behavior is none):
let b:ale_rust_cargo_default_feature_behavior = 'none' let b:ale_rust_cargo_default_feature_behavior = 'none'
let b:ale_rust_cargo_include_features = 'foo bar' let b:ale_rust_cargo_include_features = 'foo bar'
AssertLinter '', ['cargo --version', 'cargo check --frozen --message-format=json -q --no-default-features --features ' . ale#Escape('foo bar')] AssertLinter 'cargo', [ale#Escape('cargo') . ' --version', 'cargo check --frozen --message-format=json -q --no-default-features --features ' . ale#Escape('foo bar')]
Execute(g:ale_rust_cargo_include_features added and escaped): Execute(g:ale_rust_cargo_include_features added and escaped):
let b:ale_rust_cargo_default_feature_behavior = 'default' let b:ale_rust_cargo_default_feature_behavior = 'default'
let b:ale_rust_cargo_include_features = "foo bar baz" let b:ale_rust_cargo_include_features = "foo bar baz"
AssertLinter '', ['cargo --version', 'cargo check --frozen --message-format=json -q --features ' . ale#Escape('foo bar baz')] AssertLinter 'cargo', [ale#Escape('cargo') . ' --version', 'cargo check --frozen --message-format=json -q --features ' . ale#Escape('foo bar baz')]
Execute(--all-features should be used when g:ale_rust_cargo_default_feature_behavior is all): Execute(--all-features should be used when g:ale_rust_cargo_default_feature_behavior is all):
let b:ale_rust_cargo_default_feature_behavior = 'all' let b:ale_rust_cargo_default_feature_behavior = 'all'
@ -108,14 +115,15 @@ Execute(--all-features should be used when g:ale_rust_cargo_default_feature_beha
" since it won't do anything " since it won't do anything
let b:ale_rust_cargo_include_features = 'foo bar' let b:ale_rust_cargo_include_features = 'foo bar'
WithChainResults ['cargo 0.22.0 (3423351a5 2017-10-06)'] GivenCommandOutput ['cargo 0.22.0 (3423351a5 2017-10-06)']
AssertLinter '', ['cargo --version', 'cargo check --frozen --message-format=json -q --all-features'] AssertLinter 'cargo', [ale#Escape('cargo') . ' --version', 'cargo check --frozen --message-format=json -q --all-features']
Execute(When a crate belongs to a workspace we should cd into the crate): Execute(When a crate belongs to a workspace we should cd into the crate):
let g:ale_rust_cargo_avoid_whole_workspace = 1
call ale#test#SetFilename('cargo_workspace_paths/subpath/test.rs') call ale#test#SetFilename('cargo_workspace_paths/subpath/test.rs')
AssertLinter 'cargo', [ AssertLinter 'cargo', [
\ 'cargo --version', \ ale#Escape('cargo') . ' --version',
\ 'cd ' . ale#Escape(ale#path#Simplify(g:dir . '/cargo_workspace_paths/subpath')) . ' && ' \ 'cd ' . ale#Escape(ale#path#Simplify(g:dir . '/cargo_workspace_paths/subpath')) . ' && '
\ . 'cargo check --frozen --message-format=json -q', \ . 'cargo check --frozen --message-format=json -q',
\] \]
@ -125,22 +133,22 @@ Execute(When a crate belongs to a workspace we chdir into the crate, unless we d
call ale#test#SetFilename('cargo_workspace_paths/subpath/test.rs') call ale#test#SetFilename('cargo_workspace_paths/subpath/test.rs')
AssertLinter 'cargo', [ AssertLinter 'cargo', [
\ 'cargo --version', \ ale#Escape('cargo') . ' --version',
\ 'cargo check --frozen --message-format=json -q', \ 'cargo check --frozen --message-format=json -q',
\] \]
Execute(When ale_rust_cargo_use_clippy is set, cargo-clippy is used as linter): Execute(When ale_rust_cargo_use_clippy is set, cargo-clippy is used as linter):
let b:ale_rust_cargo_use_clippy = 1 let b:ale_rust_cargo_use_clippy = 1
AssertLinter '', [ AssertLinter 'cargo', [
\ 'cargo --version', \ ale#Escape('cargo') . ' --version',
\ 'cargo clippy --frozen --message-format=json -q ', \ 'cargo clippy --frozen --message-format=json -q ',
\] \]
Execute(When ale_rust_cargo_clippy_options is set, cargo-clippy appends it to commandline): Execute(When ale_rust_cargo_clippy_options is set, cargo-clippy appends it to commandline):
let b:ale_rust_cargo_use_clippy = 1 let b:ale_rust_cargo_use_clippy = 1
let b:ale_rust_cargo_clippy_options = '-- -D warnings' let b:ale_rust_cargo_clippy_options = '-- -D warnings'
AssertLinter '', [ AssertLinter 'cargo', [
\ 'cargo --version', \ ale#Escape('cargo') . ' --version',
\ 'cargo clippy --frozen --message-format=json -q -- -D warnings', \ 'cargo clippy --frozen --message-format=json -q -- -D warnings',
\] \]
@ -148,7 +156,7 @@ Execute(cargo-check does not refer ale_rust_cargo_clippy_options):
let b:ale_rust_cargo_use_clippy = 0 let b:ale_rust_cargo_use_clippy = 0
let b:ale_rust_cargo_use_check = 1 let b:ale_rust_cargo_use_check = 1
let b:ale_rust_cargo_clippy_options = '-- -D warnings' let b:ale_rust_cargo_clippy_options = '-- -D warnings'
AssertLinter '', [ AssertLinter 'cargo', [
\ 'cargo --version', \ ale#Escape('cargo') . ' --version',
\ 'cargo check --frozen --message-format=json -q', \ 'cargo check --frozen --message-format=json -q',
\] \]

View File

@ -19,7 +19,7 @@ Execute (The executable should be configurable):
\] \]
Execute (The -b option should be used when available): Execute (The -b option should be used when available):
WithChainResults [ GivenCommandOutput [
\ 'Syntax checker for Erlang (0.14.0)', \ 'Syntax checker for Erlang (0.14.0)',
\ 'Usage: syntaxerl [-d | --debug] <FILENAME>', \ 'Usage: syntaxerl [-d | --debug] <FILENAME>',
\ ' syntaxerl <-h | --help>', \ ' syntaxerl <-h | --help>',
@ -31,7 +31,7 @@ Execute (The -b option should be used when available):
\ ale#Escape('syntaxerl') . ' %t', \ ale#Escape('syntaxerl') . ' %t',
\] \]
WithChainResults [ GivenCommandOutput [
\ 'Syntax checker for Erlang (0.14.0)', \ 'Syntax checker for Erlang (0.14.0)',
\ 'Usage: syntaxerl [-b | --base <FILENAME>] [-d | --debug] <FILENAME>', \ 'Usage: syntaxerl [-b | --base <FILENAME>] [-d | --debug] <FILENAME>',
\ ' syntaxerl <-h | --help>', \ ' syntaxerl <-h | --help>',

View File

@ -21,7 +21,7 @@ Execute(Executable should filter invalid eRuby when inside a Rails project):
\] \]
Execute(Command should be blank if the first command in the chain returns output): Execute(Command should be blank if the first command in the chain returns output):
WithChainResults [ GivenCommandOutput [
\ "/usr/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require': cannot load such file -- erubi/capture_end (LoadError)", \ "/usr/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require': cannot load such file -- erubi/capture_end (LoadError)",
\ " from /usr/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require'", \ " from /usr/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require'",
\] \]

View File

@ -3,7 +3,7 @@ Before:
let b:bin_dir = has('win32') ? 'Scripts' : 'bin' let b:bin_dir = has('win32') ? 'Scripts' : 'bin'
WithChainResults ['3.0.0'] GivenCommandOutput ['3.0.0']
After: After:
unlet! b:executable unlet! b:executable
@ -18,16 +18,15 @@ Execute(The flake8 callbacks should return the correct default values):
\] \]
" The version check should be cached. " The version check should be cached.
WithChainResults [] GivenCommandOutput []
AssertLinter 'flake8', [ AssertLinter 'flake8', [
\ '',
\ ale#path#BufferCdString(bufnr('')) \ ale#path#BufferCdString(bufnr(''))
\ . ale#Escape('flake8') . ' --format=default --stdin-display-name %s -', \ . ale#Escape('flake8') . ' --format=default --stdin-display-name %s -',
\] \]
" Try with older versions. " Try with older versions.
call ale#semver#ResetVersionCache() call ale#semver#ResetVersionCache()
WithChainResults ['2.9.9'] GivenCommandOutput ['2.9.9']
AssertLinter 'flake8', [ AssertLinter 'flake8', [
\ ale#Escape('flake8') . ' --version', \ ale#Escape('flake8') . ' --version',
\ ale#path#BufferCdString(bufnr('')) \ ale#path#BufferCdString(bufnr(''))
@ -45,7 +44,7 @@ Execute(The option for disabling changing directories should work):
Execute(The flake8 command callback should let you set options): Execute(The flake8 command callback should let you set options):
let g:ale_python_flake8_options = '--some-option' let g:ale_python_flake8_options = '--some-option'
WithChainResults ['3.0.4'] GivenCommandOutput ['3.0.4']
AssertLinter 'flake8', [ AssertLinter 'flake8', [
\ ale#Escape('flake8') . ' --version', \ ale#Escape('flake8') . ' --version',
\ ale#path#BufferCdString(bufnr('')) \ ale#path#BufferCdString(bufnr(''))
@ -54,7 +53,7 @@ Execute(The flake8 command callback should let you set options):
\] \]
call ale#semver#ResetVersionCache() call ale#semver#ResetVersionCache()
WithChainResults ['2.9.9'] GivenCommandOutput ['2.9.9']
AssertLinter 'flake8', [ AssertLinter 'flake8', [
\ ale#Escape('flake8') . ' --version', \ ale#Escape('flake8') . ' --version',
\ ale#path#BufferCdString(bufnr('')) \ ale#path#BufferCdString(bufnr(''))
@ -129,7 +128,7 @@ Execute(Using `python -m flake8` should be supported for running flake8):
let g:ale_python_flake8_executable = 'python' let g:ale_python_flake8_executable = 'python'
let g:ale_python_flake8_options = '-m flake8 --some-option' let g:ale_python_flake8_options = '-m flake8 --some-option'
WithChainResults ['2.9.9'] GivenCommandOutput ['2.9.9']
AssertLinter 'python', [ AssertLinter 'python', [
\ ale#Escape('python') . ' -m flake8 --version', \ ale#Escape('python') . ' -m flake8 --version',
\ ale#path#BufferCdString(bufnr('')) \ ale#path#BufferCdString(bufnr(''))
@ -142,7 +141,7 @@ Execute(Using `python -m flake8` should be supported for running flake8):
" Leading spaces shouldn't matter " Leading spaces shouldn't matter
let g:ale_python_flake8_options = ' -m flake8 --some-option' let g:ale_python_flake8_options = ' -m flake8 --some-option'
WithChainResults ['2.9.9'] GivenCommandOutput ['2.9.9']
AssertLinter 'python', [ AssertLinter 'python', [
\ ale#Escape('python') . ' -m flake8 --version', \ ale#Escape('python') . ' -m flake8 --version',
\ ale#path#BufferCdString(bufnr('')) \ ale#path#BufferCdString(bufnr(''))
@ -154,14 +153,14 @@ Execute(Setting executable to 'pipenv' should append 'run flake8'):
let g:ale_python_flake8_executable = 'path/to/pipenv' let g:ale_python_flake8_executable = 'path/to/pipenv'
" FIXME: pipenv should check the version with flake8. " FIXME: pipenv should check the version with flake8.
WithChainResults [] GivenCommandOutput []
AssertLinter 'path/to/pipenv', AssertLinter 'path/to/pipenv',
\ ale#path#BufferCdString(bufnr('')) \ ale#path#BufferCdString(bufnr(''))
\ . ale#Escape('path/to/pipenv') . ' run flake8 --format=default -' \ . ale#Escape('path/to/pipenv') . ' run flake8 --format=default -'
Execute(Pipenv is detected when python_flake8_auto_pipenv is set): Execute(Pipenv is detected when python_flake8_auto_pipenv is set):
let g:ale_python_flake8_auto_pipenv = 1 let g:ale_python_flake8_auto_pipenv = 1
call ale#test#SetFilename('/testplugin/test/python_fixtures/pipenv/whatever.py') call ale#test#SetFilename('../python_fixtures/pipenv/whatever.py')
AssertLinter 'pipenv', AssertLinter 'pipenv',
\ ale#path#BufferCdString(bufnr('')) \ ale#path#BufferCdString(bufnr(''))

View File

@ -3,7 +3,7 @@ Before:
call ale#assert#SetUpLinterTest('go', 'gobuild') call ale#assert#SetUpLinterTest('go', 'gobuild')
WithChainResults ['/foo/bar', '/foo/baz'] GivenCommandOutput ['/foo/bar', '/foo/baz']
After: After:
Restore Restore

View File

@ -48,30 +48,30 @@ Execute(The executable should be configurable):
\ . ' -d ' . ale#Escape('TEMP_DIR') . ' %t' \ . ' -d ' . ale#Escape('TEMP_DIR') . ' %t'
Execute(The javac callback should include discovered classpaths): Execute(The javac callback should include discovered classpaths):
WithChainResults [ let b:command = ale_linters#java#javac#GetCommand(bufnr(''), [
\ '[DEBUG] Ignore this.', \ '[DEBUG] Ignore this.',
\ '[INFO] Something we should ignore.', \ '[INFO] Something we should ignore.',
\ '/foo/bar.jar', \ '/foo/bar.jar',
\ '/xyz/abc.jar', \ '/xyz/abc.jar',
\] \], {})
AssertLinter 'javac', AssertEqual
\ g:prefix \ g:prefix
\ . ' -cp ' \ . ' -cp '
\ . ale#Escape(join(['/foo/bar.jar', '/xyz/abc.jar'], g:cp_sep)) \ . ale#Escape(join(['/foo/bar.jar', '/xyz/abc.jar'], g:cp_sep))
\ . ' -d ' . ale#Escape('TEMP_DIR') . ' %t' \ . ' -d ' . ale#Escape('TEMP_DIR') . ' %t',
\ substitute(b:command, '%e', '\=ale#Escape(''javac'')', 'g')
Execute(The javac callback should combine discovered classpaths and manual ones): Execute(The javac callback should combine discovered classpaths and manual ones):
let g:ale_java_javac_classpath = 'configured.jar' let g:ale_java_javac_classpath = 'configured.jar'
let b:command = ale_linters#java#javac#GetCommand(bufnr(''), [
WithChainResults [
\ '[DEBUG] Ignore this.', \ '[DEBUG] Ignore this.',
\ '[INFO] Something we should ignore.', \ '[INFO] Something we should ignore.',
\ '/foo/bar.jar', \ '/foo/bar.jar',
\ '/xyz/abc.jar', \ '/xyz/abc.jar',
\] \], {})
AssertLinter 'javac', AssertEqual
\ g:prefix \ g:prefix
\ . ' -cp ' \ . ' -cp '
\ . ale#Escape(join( \ . ale#Escape(join(
@ -82,11 +82,18 @@ Execute(The javac callback should combine discovered classpaths and manual ones)
\ ], \ ],
\ g:cp_sep \ g:cp_sep
\ )) \ ))
\ . ' -d ' . ale#Escape('TEMP_DIR') . ' %t' \ . ' -d ' . ale#Escape('TEMP_DIR') . ' %t',
\ substitute(b:command, '%e', '\=ale#Escape(''javac'')', 'g')
let g:ale_java_javac_classpath = 'configured.jar' . g:cp_sep . 'configured2.jar' let g:ale_java_javac_classpath = 'configured.jar' . g:cp_sep . 'configured2.jar'
let b:command = ale_linters#java#javac#GetCommand(bufnr(''), [
\ '[DEBUG] Ignore this.',
\ '[INFO] Something we should ignore.',
\ '/foo/bar.jar',
\ '/xyz/abc.jar',
\], {})
AssertLinter 'javac', AssertEqual
\ g:prefix \ g:prefix
\ . ' -cp ' \ . ' -cp '
\ . ale#Escape(join( \ . ale#Escape(join(
@ -98,7 +105,8 @@ Execute(The javac callback should combine discovered classpaths and manual ones)
\ ], \ ],
\ g:cp_sep \ g:cp_sep
\ )) \ ))
\ . ' -d ' . ale#Escape('TEMP_DIR') . ' %t' \ . ' -d ' . ale#Escape('TEMP_DIR') . ' %t',
\ substitute(b:command, '%e', '\=ale#Escape(''javac'')', 'g')
Execute(The javac callback should detect source directories): Execute(The javac callback should detect source directories):
call ale#engine#Cleanup(bufnr('')) call ale#engine#Cleanup(bufnr(''))
@ -117,25 +125,25 @@ Execute(The javac callback should combine detected source directories and classp
call ale#test#SetFilename('java_paths/src/main/java/com/something/dummy.java') call ale#test#SetFilename('java_paths/src/main/java/com/something/dummy.java')
call ale#engine#InitBufferInfo(bufnr('')) call ale#engine#InitBufferInfo(bufnr(''))
WithChainResults [ let b:command = ale_linters#java#javac#GetCommand(bufnr(''), [
\ '[DEBUG] Ignore this.', \ '[DEBUG] Ignore this.',
\ '[INFO] Something we should ignore.', \ '[INFO] Something we should ignore.',
\ '/foo/bar.jar', \ '/foo/bar.jar',
\ '/xyz/abc.jar', \ '/xyz/abc.jar',
\] \], {})
AssertLinter 'javac',
AssertEqual
\ ale#path#CdString(expand('%:p:h')) . ale#Escape('javac') . ' -Xlint' \ ale#path#CdString(expand('%:p:h')) . ale#Escape('javac') . ' -Xlint'
\ . ' -cp ' . ale#Escape(join(['/foo/bar.jar', '/xyz/abc.jar'], g:cp_sep)) \ . ' -cp ' . ale#Escape(join(['/foo/bar.jar', '/xyz/abc.jar'], g:cp_sep))
\ . ' -sourcepath ' . ale#Escape( \ . ' -sourcepath ' . ale#Escape(
\ ale#path#Simplify(g:dir . '/java_paths/src/main/java/') \ ale#path#Simplify(g:dir . '/java_paths/src/main/java/')
\ ) \ )
\ . ' -d ' . ale#Escape('TEMP_DIR') . ' %t' \ . ' -d ' . ale#Escape('TEMP_DIR') . ' %t',
\ substitute(b:command, '%e', '\=ale#Escape(''javac'')', 'g')
Execute(The javac callback should use g:ale_java_javac_options correctly): Execute(The javac callback should use g:ale_java_javac_options correctly):
let g:ale_java_javac_options = '--anything --else' let g:ale_java_javac_options = '--anything --else'
let b:command = ale_linters#java#javac#GetCommand(bufnr(''), [])
AssertLinter 'javac', AssertLinter 'javac',
\ g:prefix . ' -d ' . ale#Escape('TEMP_DIR') . ' --anything --else %t' \ g:prefix . ' -d ' . ale#Escape('TEMP_DIR') . ' --anything --else %t'

View File

@ -1,7 +1,7 @@
Before: Before:
call ale#assert#SetUpLinterTest('php', 'phpstan') call ale#assert#SetUpLinterTest('php', 'phpstan')
WithChainResults ['0.10.2'] GivenCommandOutput ['0.10.2']
After: After:
call ale#assert#TearDownLinterTest() call ale#assert#TearDownLinterTest()
@ -26,7 +26,7 @@ Execute(Custom phpstan configuration file):
\ ale#Escape('phpstan') . ' analyze -l4 --errorFormat raw -c phpstan_config %s' \ ale#Escape('phpstan') . ' analyze -l4 --errorFormat raw -c phpstan_config %s'
Execute(Choose the right format for error format param): Execute(Choose the right format for error format param):
WithChainResults ['0.10.3'] GivenCommandOutput ['0.10.3']
AssertLinter 'phpstan', [ AssertLinter 'phpstan', [
\ ale#Escape('phpstan') . ' --version', \ ale#Escape('phpstan') . ' --version',

View File

@ -5,7 +5,7 @@ After:
call ale#assert#TearDownLinterTest() call ale#assert#TearDownLinterTest()
Execute(The reek callbacks should return the correct default values): Execute(The reek callbacks should return the correct default values):
WithChainResults ['reek 5.0.0'] GivenCommandOutput ['reek 5.0.0']
AssertLinter 'reek', [ AssertLinter 'reek', [
\ ale#Escape('reek') . ' --version', \ ale#Escape('reek') . ' --version',
\ ale#Escape('reek') . ' -f json --no-progress --no-color --force-exclusion --stdin-filename %s', \ ale#Escape('reek') . ' -f json --no-progress --no-color --force-exclusion --stdin-filename %s',
@ -14,7 +14,7 @@ Execute(The reek callbacks should return the correct default values):
" Try with older versions. " Try with older versions.
call ale#semver#ResetVersionCache() call ale#semver#ResetVersionCache()
WithChainResults ['reek 4.8.2'] GivenCommandOutput ['reek 4.8.2']
AssertLinter 'reek', [ AssertLinter 'reek', [
\ ale#Escape('reek') . ' --version', \ ale#Escape('reek') . ' --version',
\ ale#Escape('reek') . ' -f json --no-progress --no-color --force-exclusion', \ ale#Escape('reek') . ' -f json --no-progress --no-color --force-exclusion',
@ -23,7 +23,7 @@ Execute(The reek callbacks should return the correct default values):
Execute(Setting bundle appends 'exec reek'): Execute(Setting bundle appends 'exec reek'):
let g:ale_ruby_reek_executable = 'bundle' let g:ale_ruby_reek_executable = 'bundle'
WithChainResults ['reek 5.0.0'] GivenCommandOutput ['reek 5.0.0']
AssertLinter 'bundle', ale#Escape('bundle') AssertLinter 'bundle', ale#Escape('bundle')
\ . ' exec reek' \ . ' exec reek'
\ . ' -f json --no-progress --no-color --force-exclusion --stdin-filename %s', \ . ' -f json --no-progress --no-color --force-exclusion --stdin-filename %s',
@ -31,20 +31,19 @@ Execute(Setting bundle appends 'exec reek'):
" Try with older versions. " Try with older versions.
call ale#semver#ResetVersionCache() call ale#semver#ResetVersionCache()
WithChainResults ['reek 4.8.2'] GivenCommandOutput ['reek 4.8.2']
AssertLinter 'bundle', ale#Escape('bundle') AssertLinter 'bundle', ale#Escape('bundle')
\ . ' exec reek' \ . ' exec reek'
\ . ' -f json --no-progress --no-color --force-exclusion' \ . ' -f json --no-progress --no-color --force-exclusion'
Execute(The reek version check should be cached): Execute(The reek version check should be cached):
WithChainResults ['reek 5.0.0'] GivenCommandOutput ['reek 5.0.0']
AssertLinter 'reek', [ AssertLinter 'reek', [
\ ale#Escape('reek') . ' --version', \ ale#Escape('reek') . ' --version',
\ ale#Escape('reek') . ' -f json --no-progress --no-color --force-exclusion --stdin-filename %s', \ ale#Escape('reek') . ' -f json --no-progress --no-color --force-exclusion --stdin-filename %s',
\] \]
WithChainResults [] GivenCommandOutput []
AssertLinter 'reek', [ AssertLinter 'reek', [
\ '',
\ ale#Escape('reek') . ' -f json --no-progress --no-color --force-exclusion --stdin-filename %s', \ ale#Escape('reek') . ' -f json --no-progress --no-color --force-exclusion --stdin-filename %s',
\] \]

View File

@ -60,7 +60,7 @@ Execute(The -x option should be added when the version is new enough):
\ b:prefix . ale#Escape('shellcheck') . b:suffix, \ b:prefix . ale#Escape('shellcheck') . b:suffix,
\] \]
WithChainResults [ GivenCommandOutput [
\ 'ShellCheck - shell script analysis tool', \ 'ShellCheck - shell script analysis tool',
\ 'version: 0.4.4', \ 'version: 0.4.4',
\ 'license: GNU General Public License, version 3', \ 'license: GNU General Public License, version 3',
@ -72,14 +72,13 @@ Execute(The -x option should be added when the version is new enough):
\] \]
" We should cache the version check " We should cache the version check
WithChainResults [] GivenCommandOutput []
AssertLinter 'shellcheck', [ AssertLinter 'shellcheck', [
\ '',
\ b:prefix . ale#Escape('shellcheck') . ' -x' . b:suffix, \ b:prefix . ale#Escape('shellcheck') . ' -x' . b:suffix,
\] \]
Execute(The -x option should not be added when the version is too old): Execute(The -x option should not be added when the version is too old):
WithChainResults [ GivenCommandOutput [
\ 'ShellCheck - shell script analysis tool', \ 'ShellCheck - shell script analysis tool',
\ 'version: 0.3.9', \ 'version: 0.3.9',
\ 'license: GNU General Public License, version 3', \ 'license: GNU General Public License, version 3',
@ -91,7 +90,7 @@ Execute(The -x option should not be added when the version is too old):
\] \]
Execute(The version check shouldn't be run again for old versions): Execute(The version check shouldn't be run again for old versions):
WithChainResults [ GivenCommandOutput [
\ 'ShellCheck - shell script analysis tool', \ 'ShellCheck - shell script analysis tool',
\ 'version: 0.3.9', \ 'version: 0.3.9',
\ 'license: GNU General Public License, version 3', \ 'license: GNU General Public License, version 3',
@ -102,6 +101,5 @@ Execute(The version check shouldn't be run again for old versions):
\ b:prefix . ale#Escape('shellcheck') . b:suffix, \ b:prefix . ale#Escape('shellcheck') . b:suffix,
\] \]
AssertLinter 'shellcheck', [ AssertLinter 'shellcheck', [
\ '',
\ b:prefix . ale#Escape('shellcheck') . b:suffix, \ b:prefix . ale#Escape('shellcheck') . b:suffix,
\] \]

View File

@ -11,7 +11,6 @@ Before:
let g:ale_enabled = 0 let g:ale_enabled = 0
let g:ale_echo_cursor = 0 let g:ale_echo_cursor = 0
let g:ale_run_synchronously = 1 let g:ale_run_synchronously = 1
unlet! g:ale_run_synchronously_callbacks
let g:ale_set_lists_synchronously = 1 let g:ale_set_lists_synchronously = 1
let g:ale_fix_buffer_data = {} let g:ale_fix_buffer_data = {}
let g:ale_fixers = { let g:ale_fixers = {

View File

@ -1,143 +1,129 @@
Before: Before:
call ale#test#SetDirectory('/testplugin/test/fixers') call ale#assert#SetUpFixerTest('javascript', 'eslint')
runtime autoload/ale/handlers/eslint.vim
After: After:
call ale#test#RestoreDirectory() call ale#assert#TearDownFixerTest()
call ale#semver#ResetVersionCache()
Execute(The executable path should be correct): Execute(The executable path should be correct):
call ale#test#SetFilename('../eslint-test-files/react-app/subdir/testfile.js') call ale#test#SetFilename('../eslint-test-files/react-app/subdir/testfile.js')
" eslint_d output with an older eslint version is used here. " eslint_d output with an older eslint version is used here.
AssertEqual GivenCommandOutput ['v4.4.1 (eslint_d v5.1.0)']
AssertFixer
\ { \ {
\ 'read_temporary_file': 1, \ 'read_temporary_file': 1,
\ 'command': (has('win32') ? 'node.exe ' : '') \ 'command': (has('win32') ? 'node.exe ' : '')
\ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/eslint/bin/eslint.js')) \ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/eslint/bin/eslint.js'))
\ . ' -c ' . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/.eslintrc.js')) \ . ' -c ' . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/.eslintrc.js'))
\ . ' --fix %t', \ . ' --fix %t',
\ }, \ }
\ ale#fixers#eslint#ApplyFixForVersion(bufnr(''), ['v4.4.1 (eslint_d v5.1.0)'])
Execute(The lower priority configuration file in a nested directory should be preferred): Execute(The lower priority configuration file in a nested directory should be preferred):
call ale#test#SetFilename('../eslint-test-files/react-app/subdir-with-config/testfile.js') call ale#test#SetFilename('../eslint-test-files/react-app/subdir-with-config/testfile.js')
AssertEqual AssertFixer
\ { \ {
\ 'read_temporary_file': 1, \ 'read_temporary_file': 1,
\ 'command': (has('win32') ? 'node.exe ' : '') \ 'command': (has('win32') ? 'node.exe ' : '')
\ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/eslint/bin/eslint.js')) \ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/eslint/bin/eslint.js'))
\ . ' -c ' . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/subdir-with-config/.eslintrc')) \ . ' -c ' . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/subdir-with-config/.eslintrc'))
\ . ' --fix %t', \ . ' --fix %t',
\ }, \ }
\ ale#fixers#eslint#ApplyFixForVersion(bufnr(''), [])
Execute(package.json should be used as a last resort): Execute(package.json should be used as a last resort):
call ale#test#SetFilename('../eslint-test-files/react-app/subdir-with-package-json/testfile.js') call ale#test#SetFilename('../eslint-test-files/react-app/subdir-with-package-json/testfile.js')
AssertEqual AssertFixer
\ { \ {
\ 'read_temporary_file': 1, \ 'read_temporary_file': 1,
\ 'command': (has('win32') ? 'node.exe ' : '') \ 'command': (has('win32') ? 'node.exe ' : '')
\ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/eslint/bin/eslint.js')) \ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/eslint/bin/eslint.js'))
\ . ' -c ' . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/.eslintrc.js')) \ . ' -c ' . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/.eslintrc.js'))
\ . ' --fix %t', \ . ' --fix %t',
\ }, \ }
\ ale#fixers#eslint#ApplyFixForVersion(bufnr(''), [])
call ale#test#SetFilename('../eslint-test-files/package.json') call ale#test#SetFilename('../eslint-test-files/package.json')
AssertEqual AssertFixer
\ { \ {
\ 'read_temporary_file': 1, \ 'read_temporary_file': 1,
\ 'command': \ 'command':
\ ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/node_modules/.bin/eslint')) \ ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/node_modules/.bin/eslint'))
\ . ' -c ' . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/package.json')) \ . ' -c ' . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/package.json'))
\ . ' --fix %t', \ . ' --fix %t',
\ }, \ }
\ ale#fixers#eslint#ApplyFixForVersion(bufnr(''), [])
Execute(The version check should be correct): Execute(The version check should be correct):
call ale#test#SetFilename('../eslint-test-files/react-app/subdir/testfile.js') call ale#test#SetFilename('../eslint-test-files/react-app/subdir-with-config/testfile.js')
AssertEqual " We should run the command to get the version the first time.
\ { GivenCommandOutput ['4.9.0']
\ 'chain_with': 'ale#fixers#eslint#ApplyFixForVersion', AssertFixer [
\ 'command': (has('win32') ? 'node.exe ' : '') \ (has('win32') ? 'node.exe ' : '')
\ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/eslint/bin/eslint.js')) \ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/eslint/bin/eslint.js'))
\ . ' --version' \ . ' --version',
\ },
\ ale#fixers#eslint#Fix(bufnr(''))
Execute(--fix-dry-run should be used for 4.9.0 and up):
call ale#test#SetFilename('../eslint-test-files/react-app/subdir/testfile.js')
AssertEqual
\ { \ {
\ 'command': (has('win32') ? 'node.exe ' : '') \ 'command': (has('win32') ? 'node.exe ' : '')
\ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/eslint/bin/eslint.js')) \ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/eslint/bin/eslint.js'))
\ . ' --stdin-filename %s --stdin --fix-dry-run --format=json', \ . ' --stdin-filename %s --stdin --fix-dry-run --format=json',
\ 'process_with': 'ale#fixers#eslint#ProcessFixDryRunOutput', \ 'process_with': 'ale#fixers#eslint#ProcessFixDryRunOutput',
\ }, \ },
\ ale#fixers#eslint#ApplyFixForVersion(bufnr(''), ['4.9.0']) \]
AssertFixer [
\ {
\ 'command': (has('win32') ? 'node.exe ' : '')
\ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/eslint/bin/eslint.js'))
\ . ' --stdin-filename %s --stdin --fix-dry-run --format=json',
\ 'process_with': 'ale#fixers#eslint#ProcessFixDryRunOutput',
\ },
\]
Execute(--fix-dry-run should be used for 4.9.0 and up):
call ale#test#SetFilename('../eslint-test-files/react-app/subdir/testfile.js')
GivenCommandOutput ['4.9.0']
AssertFixer
\ {
\ 'command': (has('win32') ? 'node.exe ' : '')
\ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/eslint/bin/eslint.js'))
\ . ' --stdin-filename %s --stdin --fix-dry-run --format=json',
\ 'process_with': 'ale#fixers#eslint#ProcessFixDryRunOutput',
\ }
Execute(--fix-to-stdout should be used for eslint_d): Execute(--fix-to-stdout should be used for eslint_d):
call ale#test#SetFilename('../eslint-test-files/app-with-eslint-d/testfile.js') call ale#test#SetFilename('../eslint-test-files/app-with-eslint-d/testfile.js')
AssertEqual AssertFixer
\ { \ {
\ 'read_temporary_file': 1, \ 'read_temporary_file': 1,
\ 'command': \ 'command':
\ ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/app-with-eslint-d/node_modules/.bin/eslint_d')) \ ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/app-with-eslint-d/node_modules/.bin/eslint_d'))
\ . ' -c ' . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/package.json')) \ . ' -c ' . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/package.json'))
\ . ' --fix %t', \ . ' --fix %t',
\ }, \ }
\ ale#fixers#eslint#ApplyFixForVersion(bufnr(''), [''])
" The option should be used when eslint_d is new enough. " The option should be used when eslint_d is new enough.
" We look at the ESLint version instead of the eslint_d version. " We look at the ESLint version instead of the eslint_d version.
AssertEqual GivenCommandOutput ['v3.19.0 (eslint_d v4.2.0)']
AssertFixer
\ { \ {
\ 'command': \ 'command':
\ ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/app-with-eslint-d/node_modules/.bin/eslint_d')) \ ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/app-with-eslint-d/node_modules/.bin/eslint_d'))
\ . ' --stdin-filename %s --stdin --fix-to-stdout', \ . ' --stdin-filename %s --stdin --fix-to-stdout',
\ 'process_with': 'ale#fixers#eslint#ProcessEslintDOutput', \ 'process_with': 'ale#fixers#eslint#ProcessEslintDOutput',
\ }, \ }
\ ale#fixers#eslint#ApplyFixForVersion(bufnr(''), ['v3.19.0 (eslint_d v4.2.0)'])
" The option should be used for new versions too. " The option should be used for new versions too.
AssertEqual GivenCommandOutput ['4.9.0']
AssertFixer
\ { \ {
\ 'command': \ 'command':
\ ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/app-with-eslint-d/node_modules/.bin/eslint_d')) \ ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/app-with-eslint-d/node_modules/.bin/eslint_d'))
\ . ' --stdin-filename %s --stdin --fix-to-stdout', \ . ' --stdin-filename %s --stdin --fix-to-stdout',
\ 'process_with': 'ale#fixers#eslint#ProcessEslintDOutput', \ 'process_with': 'ale#fixers#eslint#ProcessEslintDOutput',
\ }, \ }
\ ale#fixers#eslint#ApplyFixForVersion(bufnr(''), ['4.9.0'])
Execute(The version number should be cached):
call ale#test#SetFilename('../eslint-test-files/react-app/subdir-with-config/testfile.js')
" Call the second callback with the version output.
call ale#fixers#eslint#ApplyFixForVersion(bufnr(''), ['4.9.0'])
" The version command should be skipped.
AssertEqual
\ {
\ 'chain_with': 'ale#fixers#eslint#ApplyFixForVersion',
\ 'command': '',
\ },
\ ale#fixers#eslint#Fix(bufnr(''))
" Call it again without the version output. We should use the newer command.
AssertEqual
\ {
\ 'command': (has('win32') ? 'node.exe ' : '')
\ . ale#Escape(ale#path#Simplify(g:dir . '/../eslint-test-files/react-app/node_modules/eslint/bin/eslint.js'))
\ . ' --stdin-filename %s --stdin --fix-dry-run --format=json',
\ 'process_with': 'ale#fixers#eslint#ProcessFixDryRunOutput',
\ },
\ ale#fixers#eslint#ApplyFixForVersion(bufnr(''), [])
Execute(The --fix-dry-run post-processor should handle JSON output correctly): Execute(The --fix-dry-run post-processor should handle JSON output correctly):
AssertEqual AssertEqual

View File

@ -1,54 +1,36 @@
Before: Before:
call ale#test#SetDirectory('/testplugin/test/fixers') call ale#assert#SetUpFixerTest('javascript', 'prettier_eslint')
Save g:ale_javascript_prettier_eslint_executable
Save g:ale_javascript_prettier_eslint_use_global
Save g:ale_javascript_prettier_eslint_options
unlet! g:ale_javascript_prettier_eslint_executable
unlet! g:ale_javascript_prettier_eslint_use_global
unlet! g:ale_javascript_prettier_eslint_options
call ale#fixers#prettier_eslint#SetOptionDefaults()
After: After:
Restore call ale#assert#TearDownFixerTest()
unlet! b:ale_javascript_prettier_eslint_executable
unlet! b:ale_javascript_prettier_eslint_use_global
unlet! b:ale_javascript_prettier_eslint_options
call ale#test#RestoreDirectory()
call ale#semver#ResetVersionCache()
Execute(The default command should be correct): Execute(The default command should be correct):
AssertEqual AssertFixer
\ { \ {
\ 'read_temporary_file': 1, \ 'read_temporary_file': 1,
\ 'command': \ 'command':
\ ale#Escape('prettier-eslint') \ ale#Escape('prettier-eslint')
\ . ' %t' \ . ' %t'
\ . ' --write' \ . ' --write'
\ }, \ }
\ ale#fixers#prettier_eslint#ApplyFixForVersion(bufnr(''), [])
Execute(Additional options should be used when set): Execute(Additional options should be used when set):
let b:ale_javascript_prettier_eslint_options = '--foobar' let b:ale_javascript_prettier_eslint_options = '--foobar'
AssertEqual AssertFixer
\ { \ {
\ 'read_temporary_file': 1, \ 'read_temporary_file': 1,
\ 'command': \ 'command':
\ ale#Escape('prettier-eslint') \ ale#Escape('prettier-eslint')
\ . ' %t' \ . ' %t'
\ . ' --foobar --write' \ . ' --foobar --write'
\ }, \ }
\ ale#fixers#prettier_eslint#ApplyFixForVersion(bufnr(''), [])
Execute(--eslint-config-path should be set for 4.2.0 and up): Execute(--eslint-config-path should be set for 4.2.0 and up):
call ale#test#SetFilename('eslint-test-files/react-app/foo/bar.js') call ale#test#SetFilename('eslint-test-files/react-app/foo/bar.js')
AssertEqual GivenCommandOutput ['4.2.0']
AssertFixer
\ { \ {
\ 'read_temporary_file': 1, \ 'read_temporary_file': 1,
\ 'command': \ 'command':
@ -56,58 +38,57 @@ Execute(--eslint-config-path should be set for 4.2.0 and up):
\ . ' %t' \ . ' %t'
\ . ' --eslint-config-path ' . ale#Escape(ale#path#Simplify(g:dir . '/eslint-test-files/react-app/.eslintrc.js')) \ . ' --eslint-config-path ' . ale#Escape(ale#path#Simplify(g:dir . '/eslint-test-files/react-app/.eslintrc.js'))
\ . ' --write' \ . ' --write'
\ }, \ }
\ ale#fixers#prettier_eslint#ApplyFixForVersion(bufnr(''), ['4.2.0'])
Execute(--eslint-config-path shouldn't be used for older versions): Execute(--eslint-config-path shouldn't be used for older versions):
call ale#test#SetFilename('eslint-test-files/react-app/foo/bar.js') call ale#test#SetFilename('eslint-test-files/react-app/foo/bar.js')
AssertEqual AssertFixer
\ { \ {
\ 'read_temporary_file': 1, \ 'read_temporary_file': 1,
\ 'command': \ 'command':
\ ale#Escape('prettier-eslint') \ ale#Escape('prettier-eslint')
\ . ' %t' \ . ' %t'
\ . ' --write' \ . ' --write'
\ }, \ }
\ ale#fixers#prettier_eslint#ApplyFixForVersion(bufnr(''), [])
Execute(The version check should be correct): Execute(The version check should be correct):
AssertEqual AssertFixer [
\ ale#Escape('prettier-eslint') . ' --version',
\ { \ {
\ 'chain_with': 'ale#fixers#prettier_eslint#ApplyFixForVersion', \ 'read_temporary_file': 1,
\ 'command': ale#Escape('prettier-eslint') . ' --version', \ 'command':
\ }, \ ale#Escape('prettier-eslint')
\ ale#fixers#prettier_eslint#Fix(bufnr('')) \ . ' %t'
\ . ' --write'
\ }
\]
Execute(The new --stdin-filepath option should be used when the version is new enough): Execute(The new --stdin-filepath option should be used when the version is new enough):
call ale#test#SetFilename('eslint-test-files/react-app/foo/bar.js') call ale#test#SetFilename('eslint-test-files/react-app/foo/bar.js')
AssertEqual GivenCommandOutput ['4.4.0']
AssertFixer
\ { \ {
\ 'command': ale#path#CdString(expand('%:p:h')) \ 'command': ale#path#CdString(expand('%:p:h'))
\ . ale#Escape('prettier-eslint') \ . ale#Escape('prettier-eslint')
\ . ' --eslint-config-path ' . ale#Escape(ale#path#Simplify(g:dir . '/eslint-test-files/react-app/.eslintrc.js')) \ . ' --eslint-config-path ' . ale#Escape(ale#path#Simplify(g:dir . '/eslint-test-files/react-app/.eslintrc.js'))
\ . ' --stdin-filepath %s --stdin', \ . ' --stdin-filepath %s --stdin',
\ }, \ }
\ ale#fixers#prettier_eslint#ApplyFixForVersion(bufnr(''), ['4.4.0'])
Execute(The version number should be cached): Execute(The version number should be cached):
call ale#fixers#prettier_eslint#ApplyFixForVersion(bufnr(''), ['4.4.0']) GivenCommandOutput ['4.4.0']
AssertFixer
" The version command should be skipped.
AssertEqual
\ {
\ 'chain_with': 'ale#fixers#prettier_eslint#ApplyFixForVersion',
\ 'command': '',
\ },
\ ale#fixers#prettier_eslint#Fix(bufnr(''))
" The newer command should be used.
AssertEqual
\ { \ {
\ 'command': ale#path#CdString(expand('%:p:h')) \ 'command': ale#path#CdString(expand('%:p:h'))
\ . ale#Escape('prettier-eslint') \ . ale#Escape('prettier-eslint')
\ . ' --stdin-filepath %s --stdin', \ . ' --stdin-filepath %s --stdin',
\ }, \ }
\ ale#fixers#prettier_eslint#ApplyFixForVersion(bufnr(''), [])
GivenCommandOutput []
AssertFixer
\ {
\ 'command': ale#path#CdString(expand('%:p:h'))
\ . ale#Escape('prettier-eslint')
\ . ' --stdin-filepath %s --stdin',
\ }

View File

@ -1,296 +1,286 @@
Before: Before:
call ale#test#SetDirectory('/testplugin/test/fixers') call ale#assert#SetUpFixerTest('javascript', 'prettier')
Save g:ale_javascript_prettier_executable
Save g:ale_javascript_prettier_options
" Use an invalid global executable, so we don't match it.
let g:ale_javascript_prettier_executable = 'xxxinvalid'
let g:ale_javascript_prettier_options = ''
call ale#test#SetDirectory('/testplugin/test/fixers')
silent cd .. silent cd ..
silent cd command_callback silent cd command_callback
let g:dir = getcwd() let g:dir = getcwd()
After: After:
let g:ale_has_override = {} call ale#assert#TearDownFixerTest()
call ale#test#RestoreDirectory() let g:ale_has_override = {}
call ale#semver#ResetVersionCache()
Execute(The prettier callback should return the correct default values): Execute(The prettier callback should return the correct default values):
call ale#test#SetFilename('../prettier-test-files/testfile.js') call ale#test#SetFilename('../prettier-test-files/testfile.js')
AssertEqual AssertFixer
\ { \ {
\ 'read_temporary_file': 1, \ 'read_temporary_file': 1,
\ 'command': ale#Escape(g:ale_javascript_prettier_executable) \ 'command': ale#Escape(g:ale_javascript_prettier_executable)
\ . ' %t' \ . ' %t'
\ . ' --write', \ . ' --write',
\ }, \ }
\ ale#fixers#prettier#ApplyFixForVersion(bufnr(''), [])
Execute(The --config option should not be set automatically): Execute(The --config option should not be set automatically):
let g:ale_javascript_prettier_use_local_config = 1 let g:ale_javascript_prettier_use_local_config = 1
call ale#test#SetFilename('../prettier-test-files/with_config/testfile.js') call ale#test#SetFilename('../prettier-test-files/with_config/testfile.js')
AssertEqual AssertFixer
\ { \ {
\ 'read_temporary_file': 1, \ 'read_temporary_file': 1,
\ 'command': ale#Escape(g:ale_javascript_prettier_executable) \ 'command': ale#Escape(g:ale_javascript_prettier_executable)
\ . ' %t' \ . ' %t'
\ . ' --write', \ . ' --write',
\ }, \ }
\ ale#fixers#prettier#ApplyFixForVersion(bufnr(''), [])
Execute(The prettier callback should include custom prettier options): Execute(The prettier callback should include custom prettier options):
let g:ale_javascript_prettier_options = '--no-semi' let g:ale_javascript_prettier_options = '--no-semi'
call ale#test#SetFilename('../prettier-test-files/with_config/testfile.js') call ale#test#SetFilename('../prettier-test-files/with_config/testfile.js')
AssertEqual AssertFixer
\ { \ {
\ 'read_temporary_file': 1, \ 'read_temporary_file': 1,
\ 'command': ale#Escape(g:ale_javascript_prettier_executable) \ 'command': ale#Escape(g:ale_javascript_prettier_executable)
\ . ' %t' \ . ' %t'
\ . ' --no-semi' \ . ' --no-semi'
\ . ' --write', \ . ' --write',
\ }, \ }
\ ale#fixers#prettier#ApplyFixForVersion(bufnr(''), [])
Execute(The version check should be correct): Execute(The version check should be correct):
call ale#test#SetFilename('../prettier-test-files/testfile.js') call ale#test#SetFilename('../prettier-test-files/testfile.js')
AssertEqual AssertFixer [
\ { \ ale#Escape('prettier') . ' --version',
\ 'chain_with': 'ale#fixers#prettier#ApplyFixForVersion', \ {'read_temporary_file': 1, 'command': ale#Escape('prettier') . ' %t --write'}
\ 'command': ale#Escape(g:ale_javascript_prettier_executable) \]
\ . ' --version',
\ },
\ ale#fixers#prettier#Fix(bufnr(''))
Execute(--stdin-filepath should be used when prettier is new enough): Execute(--stdin-filepath should be used when prettier is new enough):
let g:ale_javascript_prettier_options = '--no-semi' let g:ale_javascript_prettier_options = '--no-semi'
call ale#test#SetFilename('../prettier-test-files/with_config/testfile.js') call ale#test#SetFilename('../prettier-test-files/with_config/testfile.js')
AssertEqual GivenCommandOutput ['1.6.0']
AssertFixer
\ { \ {
\ 'command': ale#path#CdString(expand('%:p:h')) \ 'command': ale#path#CdString(expand('%:p:h'))
\ . ale#Escape(g:ale_javascript_prettier_executable) \ . ale#Escape(g:ale_javascript_prettier_executable)
\ . ' --no-semi' \ . ' --no-semi'
\ . ' --stdin-filepath %s --stdin', \ . ' --stdin-filepath %s --stdin',
\ }, \ }
\ ale#fixers#prettier#ApplyFixForVersion(bufnr(''), ['1.6.0'])
Execute(The version number should be cached): Execute(The version number should be cached):
call ale#test#SetFilename('../prettier-test-files/with_config/testfile.js') call ale#test#SetFilename('../prettier-test-files/with_config/testfile.js')
" Call the second callback with the version output. GivenCommandOutput ['1.6.0']
call ale#fixers#prettier#ApplyFixForVersion(bufnr(''), ['1.6.0']) AssertFixer
" Call it again without the version output. We should use the newer command.
AssertEqual
\ { \ {
\ 'command': ale#path#CdString(expand('%:p:h')) \ 'command': ale#path#CdString(expand('%:p:h'))
\ . ale#Escape(g:ale_javascript_prettier_executable) \ . ale#Escape(g:ale_javascript_prettier_executable)
\ . ' --stdin-filepath %s --stdin', \ . ' --stdin-filepath %s --stdin',
\ }, \ }
\ ale#fixers#prettier#ApplyFixForVersion(bufnr(''), [])
GivenCommandOutput []
AssertFixer
\ {
\ 'command': ale#path#CdString(expand('%:p:h'))
\ . ale#Escape(g:ale_javascript_prettier_executable)
\ . ' --stdin-filepath %s --stdin',
\ }
Execute(Should set --parser to `babylon` by default, < 1.16.0): Execute(Should set --parser to `babylon` by default, < 1.16.0):
call ale#test#SetFilename('../prettier-test-files/testfile') call ale#test#SetFilename('../prettier-test-files/testfile')
set filetype=javascript set filetype=javascript
AssertEqual GivenCommandOutput ['1.6.0']
AssertFixer
\ { \ {
\ 'command': ale#path#CdString(expand('%:p:h')) \ 'command': ale#path#CdString(expand('%:p:h'))
\ . ale#Escape(g:ale_javascript_prettier_executable) \ . ale#Escape(g:ale_javascript_prettier_executable)
\ . ' --parser babylon' \ . ' --parser babylon'
\ . ' --stdin-filepath %s --stdin', \ . ' --stdin-filepath %s --stdin',
\ }, \ }
\ ale#fixers#prettier#ApplyFixForVersion(bufnr(''), ['1.6.0'])
Execute(Should set --parser to `babel` by default, >= 1.16.0): Execute(Should set --parser to `babel` by default, >= 1.16.0):
call ale#test#SetFilename('../prettier-test-files/testfile') call ale#test#SetFilename('../prettier-test-files/testfile')
set filetype=javascript set filetype=javascript
AssertEqual GivenCommandOutput ['1.16.0']
AssertFixer
\ { \ {
\ 'command': ale#path#CdString(expand('%:p:h')) \ 'command': ale#path#CdString(expand('%:p:h'))
\ . ale#Escape(g:ale_javascript_prettier_executable) \ . ale#Escape(g:ale_javascript_prettier_executable)
\ . ' --parser babel' \ . ' --parser babel'
\ . ' --stdin-filepath %s --stdin', \ . ' --stdin-filepath %s --stdin',
\ }, \ }
\ ale#fixers#prettier#ApplyFixForVersion(bufnr(''), ['1.16.0'])
Execute(Should set --parser based on filetype, TypeScript): Execute(Should set --parser based on filetype, TypeScript):
call ale#test#SetFilename('../prettier-test-files/testfile') call ale#test#SetFilename('../prettier-test-files/testfile')
set filetype=typescript set filetype=typescript
AssertEqual GivenCommandOutput ['1.6.0']
AssertFixer
\ { \ {
\ 'command': ale#path#CdString(expand('%:p:h')) \ 'command': ale#path#CdString(expand('%:p:h'))
\ . ale#Escape(g:ale_javascript_prettier_executable) \ . ale#Escape(g:ale_javascript_prettier_executable)
\ . ' --parser typescript' \ . ' --parser typescript'
\ . ' --stdin-filepath %s --stdin', \ . ' --stdin-filepath %s --stdin',
\ }, \ }
\ ale#fixers#prettier#ApplyFixForVersion(bufnr(''), ['1.6.0'])
Execute(Should set --parser based on filetype, CSS): Execute(Should set --parser based on filetype, CSS):
call ale#test#SetFilename('../prettier-test-files/testfile') call ale#test#SetFilename('../prettier-test-files/testfile')
set filetype=css set filetype=css
AssertEqual GivenCommandOutput ['1.6.0']
AssertFixer
\ { \ {
\ 'command': ale#path#CdString(expand('%:p:h')) \ 'command': ale#path#CdString(expand('%:p:h'))
\ . ale#Escape(g:ale_javascript_prettier_executable) \ . ale#Escape(g:ale_javascript_prettier_executable)
\ . ' --parser css' \ . ' --parser css'
\ . ' --stdin-filepath %s --stdin', \ . ' --stdin-filepath %s --stdin',
\ }, \ }
\ ale#fixers#prettier#ApplyFixForVersion(bufnr(''), ['1.6.0'])
Execute(Should set --parser based on filetype, LESS): Execute(Should set --parser based on filetype, LESS):
call ale#test#SetFilename('../prettier-test-files/testfile') call ale#test#SetFilename('../prettier-test-files/testfile')
set filetype=less set filetype=less
AssertEqual GivenCommandOutput ['1.6.0']
AssertFixer
\ { \ {
\ 'command': ale#path#CdString(expand('%:p:h')) \ 'command': ale#path#CdString(expand('%:p:h'))
\ . ale#Escape(g:ale_javascript_prettier_executable) \ . ale#Escape(g:ale_javascript_prettier_executable)
\ . ' --parser less' \ . ' --parser less'
\ . ' --stdin-filepath %s --stdin', \ . ' --stdin-filepath %s --stdin',
\ }, \ }
\ ale#fixers#prettier#ApplyFixForVersion(bufnr(''), ['1.6.0'])
Execute(Should set --parser based on filetype, SCSS): Execute(Should set --parser based on filetype, SCSS):
call ale#test#SetFilename('../prettier-test-files/testfile') call ale#test#SetFilename('../prettier-test-files/testfile')
set filetype=scss set filetype=scss
AssertEqual GivenCommandOutput ['1.6.0']
AssertFixer
\ { \ {
\ 'command': ale#path#CdString(expand('%:p:h')) \ 'command': ale#path#CdString(expand('%:p:h'))
\ . ale#Escape(g:ale_javascript_prettier_executable) \ . ale#Escape(g:ale_javascript_prettier_executable)
\ . ' --parser scss' \ . ' --parser scss'
\ . ' --stdin-filepath %s --stdin', \ . ' --stdin-filepath %s --stdin',
\ }, \ }
\ ale#fixers#prettier#ApplyFixForVersion(bufnr(''), ['1.6.0'])
Execute(Should set --parser based on filetype, JSON): Execute(Should set --parser based on filetype, JSON):
call ale#test#SetFilename('../prettier-test-files/testfile') call ale#test#SetFilename('../prettier-test-files/testfile')
set filetype=json set filetype=json
AssertEqual GivenCommandOutput ['1.6.0']
AssertFixer
\ { \ {
\ 'command': ale#path#CdString(expand('%:p:h')) \ 'command': ale#path#CdString(expand('%:p:h'))
\ . ale#Escape(g:ale_javascript_prettier_executable) \ . ale#Escape(g:ale_javascript_prettier_executable)
\ . ' --parser json' \ . ' --parser json'
\ . ' --stdin-filepath %s --stdin', \ . ' --stdin-filepath %s --stdin',
\ }, \ }
\ ale#fixers#prettier#ApplyFixForVersion(bufnr(''), ['1.6.0'])
Execute(Should set --parser based on filetype, JSON5): Execute(Should set --parser based on filetype, JSON5):
call ale#test#SetFilename('../prettier-test-files/testfile') call ale#test#SetFilename('../prettier-test-files/testfile')
set filetype=json5 set filetype=json5
AssertEqual GivenCommandOutput ['1.6.0']
AssertFixer
\ { \ {
\ 'command': ale#path#CdString(expand('%:p:h')) \ 'command': ale#path#CdString(expand('%:p:h'))
\ . ale#Escape(g:ale_javascript_prettier_executable) \ . ale#Escape(g:ale_javascript_prettier_executable)
\ . ' --parser json5' \ . ' --parser json5'
\ . ' --stdin-filepath %s --stdin', \ . ' --stdin-filepath %s --stdin',
\ }, \ }
\ ale#fixers#prettier#ApplyFixForVersion(bufnr(''), ['1.6.0'])
Execute(Should set --parser based on filetype, GraphQL): Execute(Should set --parser based on filetype, GraphQL):
call ale#test#SetFilename('../prettier-test-files/testfile') call ale#test#SetFilename('../prettier-test-files/testfile')
set filetype=graphql set filetype=graphql
AssertEqual GivenCommandOutput ['1.6.0']
AssertFixer
\ { \ {
\ 'command': ale#path#CdString(expand('%:p:h')) \ 'command': ale#path#CdString(expand('%:p:h'))
\ . ale#Escape(g:ale_javascript_prettier_executable) \ . ale#Escape(g:ale_javascript_prettier_executable)
\ . ' --parser graphql' \ . ' --parser graphql'
\ . ' --stdin-filepath %s --stdin', \ . ' --stdin-filepath %s --stdin',
\ }, \ }
\ ale#fixers#prettier#ApplyFixForVersion(bufnr(''), ['1.6.0'])
Execute(Should set --parser based on filetype, Markdown): Execute(Should set --parser based on filetype, Markdown):
call ale#test#SetFilename('../prettier-test-files/testfile') call ale#test#SetFilename('../prettier-test-files/testfile')
set filetype=markdown set filetype=markdown
AssertEqual GivenCommandOutput ['1.6.0']
AssertFixer
\ { \ {
\ 'command': ale#path#CdString(expand('%:p:h')) \ 'command': ale#path#CdString(expand('%:p:h'))
\ . ale#Escape(g:ale_javascript_prettier_executable) \ . ale#Escape(g:ale_javascript_prettier_executable)
\ . ' --parser markdown' \ . ' --parser markdown'
\ . ' --stdin-filepath %s --stdin', \ . ' --stdin-filepath %s --stdin',
\ }, \ }
\ ale#fixers#prettier#ApplyFixForVersion(bufnr(''), ['1.6.0'])
Execute(Should set --parser based on filetype, Vue): Execute(Should set --parser based on filetype, Vue):
call ale#test#SetFilename('../prettier-test-files/testfile') call ale#test#SetFilename('../prettier-test-files/testfile')
set filetype=vue set filetype=vue
AssertEqual GivenCommandOutput ['1.6.0']
AssertFixer
\ { \ {
\ 'command': ale#path#CdString(expand('%:p:h')) \ 'command': ale#path#CdString(expand('%:p:h'))
\ . ale#Escape(g:ale_javascript_prettier_executable) \ . ale#Escape(g:ale_javascript_prettier_executable)
\ . ' --parser vue' \ . ' --parser vue'
\ . ' --stdin-filepath %s --stdin', \ . ' --stdin-filepath %s --stdin',
\ }, \ }
\ ale#fixers#prettier#ApplyFixForVersion(bufnr(''), ['1.6.0'])
Execute(Should set --parser based on filetype, YAML): Execute(Should set --parser based on filetype, YAML):
call ale#test#SetFilename('../prettier-test-files/testfile') call ale#test#SetFilename('../prettier-test-files/testfile')
set filetype=yaml set filetype=yaml
AssertEqual GivenCommandOutput ['1.6.0']
AssertFixer
\ { \ {
\ 'command': ale#path#CdString(expand('%:p:h')) \ 'command': ale#path#CdString(expand('%:p:h'))
\ . ale#Escape(g:ale_javascript_prettier_executable) \ . ale#Escape(g:ale_javascript_prettier_executable)
\ . ' --parser yaml' \ . ' --parser yaml'
\ . ' --stdin-filepath %s --stdin', \ . ' --stdin-filepath %s --stdin',
\ }, \ }
\ ale#fixers#prettier#ApplyFixForVersion(bufnr(''), ['1.6.0'])
Execute(Should set --parser based on filetype, HTML): Execute(Should set --parser based on filetype, HTML):
call ale#test#SetFilename('../prettier-test-files/testfile') call ale#test#SetFilename('../prettier-test-files/testfile')
set filetype=html set filetype=html
AssertEqual GivenCommandOutput ['1.6.0']
AssertFixer
\ { \ {
\ 'command': ale#path#CdString(expand('%:p:h')) \ 'command': ale#path#CdString(expand('%:p:h'))
\ . ale#Escape(g:ale_javascript_prettier_executable) \ . ale#Escape(g:ale_javascript_prettier_executable)
\ . ' --parser html' \ . ' --parser html'
\ . ' --stdin-filepath %s --stdin', \ . ' --stdin-filepath %s --stdin',
\ }, \ }
\ ale#fixers#prettier#ApplyFixForVersion(bufnr(''), ['1.6.0'])
Execute(Should set --parser based on first filetype of multiple filetypes): Execute(Should set --parser based on first filetype of multiple filetypes):
call ale#test#SetFilename('../prettier-test-files/testfile') call ale#test#SetFilename('../prettier-test-files/testfile')
set filetype=css.scss set filetype=css.scss
AssertEqual GivenCommandOutput ['1.6.0']
AssertFixer
\ { \ {
\ 'command': ale#path#CdString(expand('%:p:h')) \ 'command': ale#path#CdString(expand('%:p:h'))
\ . ale#Escape(g:ale_javascript_prettier_executable) \ . ale#Escape(g:ale_javascript_prettier_executable)
\ . ' --parser css' \ . ' --parser css'
\ . ' --stdin-filepath %s --stdin', \ . ' --stdin-filepath %s --stdin',
\ }, \ }
\ ale#fixers#prettier#ApplyFixForVersion(bufnr(''), ['1.6.0'])
Execute(The prettier_d post-processor should permit regular JavaScript content): Execute(The prettier_d post-processor should permit regular JavaScript content):
AssertEqual AssertEqual

View File

@ -3,6 +3,7 @@ Before:
let g:ale_run_synchronously = 1 let g:ale_run_synchronously = 1
unlet! g:ale_run_synchronously_callbacks unlet! g:ale_run_synchronously_callbacks
unlet! g:ale_run_synchronously_emulate_commands
runtime autoload/ale/lsp.vim runtime autoload/ale/lsp.vim
runtime autoload/ale/lsp_linter.vim runtime autoload/ale/lsp_linter.vim
@ -234,6 +235,7 @@ After:
call ale#linter#Reset() call ale#linter#Reset()
call ale#lsp#ResetConnections() call ale#lsp#ResetConnections()
unlet! g:ale_run_synchronously_callbacks
unlet! g:job_map unlet! g:job_map
unlet! g:emulate_job_failure unlet! g:emulate_job_failure
unlet! g:next_job_id unlet! g:next_job_id

View File

@ -13,6 +13,7 @@ Before:
let g:ale_buffer_info = {} let g:ale_buffer_info = {}
let g:ale_run_synchronously = 1 let g:ale_run_synchronously = 1
unlet! g:ale_run_synchronously_callbacks
let g:ale_set_signs = 1 let g:ale_set_signs = 1
" Disable features we don't need for these tests. " Disable features we don't need for these tests.
let g:ale_set_quickfix = 0 let g:ale_set_quickfix = 0
@ -58,6 +59,7 @@ After:
delfunction TestCallback delfunction TestCallback
delfunction CollectSigns delfunction CollectSigns
unlet! g:ale_run_synchronously_callbacks
sign unplace * sign unplace *
call ale#linter#Reset() call ale#linter#Reset()

View File

@ -87,6 +87,7 @@ Before:
After: After:
Restore Restore
unlet! g:ale_run_synchronously_callbacks
unlet! g:loclist unlet! g:loclist
delfunction GenerateResults delfunction GenerateResults
delfunction ParseSigns delfunction ParseSigns

View File

@ -17,10 +17,14 @@ Before:
\ 'read_buffer': 0, \ 'read_buffer': 0,
\}) \})
" Run the test commands in the shell.
let g:ale_run_synchronously_emulate_commands = 0
After: After:
Restore Restore
call ale#assert#TearDownLinterTest() call ale#assert#TearDownLinterTest()
unlet! g:ale_run_synchronously_callbacks
Given foobar (Some imaginary filetype): Given foobar (Some imaginary filetype):
Execute(It should be possible to compute an executable to check based on the result of commands): Execute(It should be possible to compute an executable to check based on the result of commands):

View File

@ -54,11 +54,17 @@ Execute(eslint_d should be detected correctly):
Execute(eslint.js executables should be run with node on Windows): Execute(eslint.js executables should be run with node on Windows):
call ale#test#SetFilename('eslint-test-files/react-app/subdir/testfile.js') call ale#test#SetFilename('eslint-test-files/react-app/subdir/testfile.js')
let g:ale_has_override['win32'] = 1
" We have to execute the file with node. " We have to execute the file with node.
AssertEqual if has('win32')
\ ale#Escape('node.exe') . ' ' AssertEqual
\ . ale#Escape(ale#path#Simplify(g:dir . '/eslint-test-files/react-app/node_modules/eslint/bin/eslint.js')) \ ale#Escape('node.exe') . ' '
\ . ' -f unix --stdin --stdin-filename %s', \ . ale#Escape(ale#path#Simplify(g:dir . '/eslint-test-files/react-app/node_modules/eslint/bin/eslint.js'))
\ ale#handlers#eslint#GetCommand(bufnr('')) \ . ' -f unix --stdin --stdin-filename %s',
\ ale#handlers#eslint#GetCommand(bufnr(''))
else
AssertEqual
\ ale#Escape(ale#path#Simplify(g:dir . '/eslint-test-files/react-app/node_modules/eslint/bin/eslint.js'))
\ . ' -f unix --stdin --stdin-filename %s',
\ ale#handlers#eslint#GetCommand(bufnr(''))
endif

View File

@ -1,48 +1,46 @@
Before: Before:
runtime ale_linters/javascript/flow.vim runtime ale_linters/javascript/flow.vim
call ale#test#SetDirectory('/testplugin/test') call ale#assert#SetUpLinterTest('javascript', 'flow')
call ale#test#SetDirectory('/testplugin/test/')
After: After:
unlet! b:ale_javascript_flow_use_respect_pragma unlet! b:ale_javascript_flow_use_respect_pragma
call ale#assert#TearDownLinterTest()
call ale#test#RestoreDirectory()
call ale#linter#Reset()
call ale#semver#ResetVersionCache()
Execute(flow should return a command to run if a .flowconfig file exists): Execute(flow should return a command to run if a .flowconfig file exists):
call ale#test#SetFilename('flow/a/sub/dummy') call ale#test#SetFilename('flow/a/sub/dummy')
AssertEqual AssertLinter 'flow',
\ ale#Escape('flow') \ ale#Escape('flow')
\ . ' check-contents --respect-pragma --json --from ale %s < %t' \ . ' check-contents --respect-pragma --json --from ale %s < %t'
\ . (!has('win32') ? '; echo' : ''), \ . (!has('win32') ? '; echo' : '')
\ ale_linters#javascript#flow#GetCommand(bufnr('%'), [])
Execute(flow should not use the respect pragma argument if the option is off): Execute(flow should not use the respect pragma argument if the option is off):
call ale#test#SetFilename('flow/a/sub/dummy') call ale#test#SetFilename('flow/a/sub/dummy')
let b:ale_javascript_flow_use_respect_pragma = 0 let b:ale_javascript_flow_use_respect_pragma = 0
AssertEqual AssertLinter 'flow',
\ ale#Escape('flow') \ ale#Escape('flow')
\ . ' check-contents --json --from ale %s < %t' \ . ' check-contents --json --from ale %s < %t'
\ . (!has('win32') ? '; echo' : ''), \ . (!has('win32') ? '; echo' : '')
\ ale_linters#javascript#flow#GetCommand(bufnr('%'), [])
Execute(flow should should not use --respect-pragma for old versions): Execute(flow should should not use --respect-pragma for old versions):
call ale#test#SetFilename('flow/a/sub/dummy') call ale#test#SetFilename('flow/a/sub/dummy')
AssertEqual GivenCommandOutput [
\ 'Warning: `flow --version` is deprecated in favor of `flow version`',
\ 'Flow, a static type checker for JavaScript, version 0.27.0',
\]
AssertLinter 'flow', [
\ ale#Escape('flow') . ' --version',
\ ale#Escape('flow') \ ale#Escape('flow')
\ . ' check-contents --json --from ale %s < %t' \ . ' check-contents --json --from ale %s < %t'
\ . (!has('win32') ? '; echo' : ''), \ . (!has('win32') ? '; echo' : ''),
\ ale_linters#javascript#flow#GetCommand(bufnr('%'), [ \]
\ 'Warning: `flow --version` is deprecated in favor of `flow version`',
\ 'Flow, a static type checker for JavaScript, version 0.27.0',
\ ])
Execute(flow should not return a command to run if no .flowconfig file exists): Execute(flow should not return a command to run if no .flowconfig file exists):
call ale#test#SetFilename('flow/b/sub/dummy') call ale#test#SetFilename('flow/b/sub/dummy')
AssertEqual '', ale_linters#javascript#flow#GetCommand(bufnr('%'), []) AssertLinterNotExecuted

View File

@ -1,32 +1,20 @@
After: After:
call ale#semver#ResetVersionCache() call ale#semver#ResetVersionCache()
Execute(GetVersion should return the version from the lines of output): Execute(ParseVersion should return the version from the lines of output):
" We should be able to parse the semver string from flake8 " We should be able to parse the semver string from flake8
AssertEqual [3, 0, 4], ale#semver#GetVersion('dummy', [ AssertEqual [3, 0, 4], ale#semver#ParseVersion([
\ '3.0.4 (mccabe: 0.5.2, pyflakes: 1.2.3, pycodestyle: 2.0.0) CPython 2.7.12 on Linux', \ '3.0.4 (mccabe: 0.5.2, pyflakes: 1.2.3, pycodestyle: 2.0.0) CPython 2.7.12 on Linux',
\ '1.2.3', \ '1.2.3',
\]) \])
Execute(GetVersion should return an empty list when no vesrion can be found): Execute(ParseVersion should return an empty list when no vesrion can be found):
AssertEqual [], ale#semver#GetVersion('dummy', ['x']) AssertEqual [], ale#semver#ParseVersion(['x'])
AssertEqual [], ale#semver#GetVersion('dummy', []) AssertEqual [], ale#semver#ParseVersion([])
Execute(GetVersion should cache the version): Execute(ParseVersion should tolerate missing patch numbers):
AssertEqual [], ale#semver#GetVersion('dummy', [])
AssertEqual [3, 4, 7], ale#semver#GetVersion('dummy', ['Version 3.4.7'])
AssertEqual [3, 4, 17], ale#semver#GetVersion('dummy', ['Version 3.4.17'])
AssertEqual [3, 4, 17], ale#semver#GetVersion('dummy', [])
Execute(GetVersion should tolerate missing patch numbers):
" This goes against the semver spec, but we handle it anyway. " This goes against the semver spec, but we handle it anyway.
AssertEqual [3, 4, 0], ale#semver#GetVersion('dummy', ['Version 3.4']) AssertEqual [3, 4, 0], ale#semver#ParseVersion(['Version 3.4'])
Execute(HasVersion should return 1 when the version has been cached):
call ale#semver#GetVersion('dummy', [])
AssertEqual 0, ale#semver#HasVersion('dummy')
call ale#semver#GetVersion('dummy', ['3.4.7'])
AssertEqual 1, ale#semver#HasVersion('dummy')
Execute(GTE should compare triples correctly): Execute(GTE should compare triples correctly):
Assert ale#semver#GTE([3, 0, 4], [3, 0, 0]) Assert ale#semver#GTE([3, 0, 4], [3, 0, 0])