Compare commits

...

17 Commits

Author SHA1 Message Date
w0rp 5556fcbd1c Stop the completion tests from failing randomly 2017-11-21 14:57:28 +00:00
w0rp cf599f4470 #1149 Fix conversion from URIs to filenames on Windows 2017-11-21 14:56:37 +00:00
w0rp e71d831119 Fix #1124 - Handle stack-build errors with leading spaces 2017-11-13 22:48:30 +00:00
w0rp d8abe0d6a2 Fix #1101 - Ignore no-implicit-dependencies errors until TSLint supports checking via stdin properly 2017-11-09 10:33:56 +00:00
w0rp 55757e3d78 #1006 Fix raw message handling for LSP support in NeoVim 2017-11-06 22:53:27 +00:00
w0rp 8e7ede3be8 Fix #1085 - Add a final newline character to tsserver and LSP messages 2017-11-05 21:52:11 +00:00
w0rp 6f8db3e5c4 Fix #1061 - Handle the filenames returned by javac 2017-11-05 15:34:46 +00:00
w0rp 2398fd7456 Fix #1058 - Ignore all errors with bad calls to jobstop() in NeoVim 2017-11-04 10:54:06 +00:00
w0rp c1366f8a62 #1081 Remove the ale#python#IsExecutable function 2017-11-04 10:47:47 +00:00
w0rp 5089b09b7e #1081 Use executable() for Python executables on Windows, and rename the test files to .exe so they will pass the executable() check 2017-11-04 10:47:35 +00:00
Antoine Reilles 220ebb3a79 windows compatible warning match pattern for erlc (#1071)
* windows compatible warning match pattern for erlc
2017-11-03 18:57:21 +00:00
w0rp 25b5fad15c Merge pull request #1072 from drrcknlsn/master
Prevent logging of errors in the php linter.
2017-11-01 20:56:43 +00:00
w0rp 39f15811c3 Fix #936 - Check the actual files for gosimple and staticcheck 2017-10-31 13:01:52 +00:00
w0rp 34171774eb Fix #1041 - Do not request completions shortly after CompleteDone 2017-10-26 23:19:49 +01:00
w0rp 80328fa156 Fix #1051 - Support ash and dash for shellcheck and the sh linter 2017-10-26 21:17:47 +01:00
w0rp 1fcf6444dc Fix #1048 - Do not lint files named "." 2017-10-26 20:30:40 +01:00
w0rp e57978ddd6 Fix #1045 - Handle both output streams for Cargo 2017-10-26 10:04:52 +01:00
38 changed files with 251 additions and 90 deletions

View File

@ -95,7 +95,7 @@ formatting.
| Fortran | [gcc](https://gcc.gnu.org/) |
| FusionScript | [fusion-lint](https://github.com/RyanSquared/fusionscript) |
| GLSL | [glslang](https://github.com/KhronosGroup/glslang) |
| Go | [gofmt](https://golang.org/cmd/gofmt/), [go vet](https://golang.org/cmd/vet/), [golint](https://godoc.org/github.com/golang/lint), [gometalinter](https://github.com/alecthomas/gometalinter) !!, [go build](https://golang.org/cmd/go/) !!, [gosimple](https://github.com/dominikh/go-tools/tree/master/cmd/gosimple), [staticcheck](https://github.com/dominikh/go-tools/tree/master/cmd/staticcheck) |
| Go | [gofmt](https://golang.org/cmd/gofmt/), [go vet](https://golang.org/cmd/vet/), [golint](https://godoc.org/github.com/golang/lint), [gometalinter](https://github.com/alecthomas/gometalinter) !!, [go build](https://golang.org/cmd/go/) !!, [gosimple](https://github.com/dominikh/go-tools/tree/master/cmd/gosimple) !!, [staticcheck](https://github.com/dominikh/go-tools/tree/master/cmd/staticcheck) !! |
| GraphQL | [gqlint](https://github.com/happylinks/gqlint) |
| Haml | [haml-lint](https://github.com/brigade/haml-lint) |
| Handlebars | [ember-template-lint](https://github.com/rwjblue/ember-template-lint) |

View File

@ -17,7 +17,7 @@ function! ale_linters#erlang#erlc#Handle(buffer, lines) abort
" error.erl:4: variable 'B' is unbound
" error.erl:3: Warning: function main/0 is unused
" error.erl:4: Warning: variable 'A' is unused
let l:pattern = '\v^([^:]+):(\d+): (Warning: )?(.+)$'
let l:pattern = '\v^([a-zA-Z]?:?[^:]+):(\d+): (Warning: )?(.+)$'
" parse_transforms are a special case. The error message does not indicate a location:
" error.erl: undefined parse transform 'some_parse_transform'

View File

@ -4,7 +4,8 @@
call ale#linter#Define('go', {
\ 'name': 'gosimple',
\ 'executable': 'gosimple',
\ 'command': 'gosimple %t',
\ 'command': 'gosimple %s',
\ 'callback': 'ale#handlers#unix#HandleAsWarning',
\ 'output_stream': 'both'
\ 'output_stream': 'both',
\ 'lint_file': 1,
\})

View File

@ -4,7 +4,8 @@
call ale#linter#Define('go', {
\ 'name': 'staticcheck',
\ 'executable': 'staticcheck',
\ 'command': 'staticcheck %t',
\ 'command': 'staticcheck %s',
\ 'callback': 'ale#handlers#unix#HandleAsWarning',
\ 'output_stream': 'both'
\ 'output_stream': 'both',
\ 'lint_file': 1,
\})

View File

@ -49,7 +49,10 @@ function! ale_linters#java#javac#GetCommand(buffer, import_paths) abort
" Create .class files in a temporary directory, which we will delete later.
let l:class_file_directory = ale#engine#CreateDirectory(a:buffer)
return 'javac -Xlint'
" Always run javac from the directory the file is in, so we can resolve
" relative paths correctly.
return ale#path#BufferCdString(a:buffer)
\ . 'javac -Xlint'
\ . ' ' . l:cp_option
\ . ' ' . l:sp_option
\ . ' -d ' . ale#Escape(l:class_file_directory)
@ -63,14 +66,15 @@ function! ale_linters#java#javac#Handle(buffer, lines) abort
" Main.java:13: warning: [deprecation] donaught() in Testclass has been deprecated
" Main.java:16: error: ';' expected
let l:pattern = '\v^.*:(\d+): (.+):(.+)$'
let l:directory = expand('#' . a:buffer . ':p:h')
let l:pattern = '\v^(.*):(\d+): (.+):(.+)$'
let l:col_pattern = '\v^(\s*\^)$'
let l:symbol_pattern = '\v^ +symbol: *(class|method) +([^ ]+)'
let l:output = []
for l:match in ale#util#GetMatches(a:lines, [l:pattern, l:col_pattern, l:symbol_pattern])
if empty(l:match[2]) && empty(l:match[3])
let l:output[-1].col = len(l:match[1])
let l:output[-1].col = len(l:match[1])
elseif empty(l:match[3])
" Add symbols to 'cannot find symbol' errors.
if l:output[-1].text is# 'error: cannot find symbol'
@ -78,9 +82,10 @@ function! ale_linters#java#javac#Handle(buffer, lines) abort
endif
else
call add(l:output, {
\ 'lnum': l:match[1] + 0,
\ 'text': l:match[2] . ':' . l:match[3],
\ 'type': l:match[2] is# 'error' ? 'E' : 'W',
\ 'filename': ale#path#GetAbsPath(l:directory, l:match[1]),
\ 'lnum': l:match[2] + 0,
\ 'text': l:match[3] . ':' . l:match[4],
\ 'type': l:match[3] is# 'error' ? 'E' : 'W',
\})
endif
endfor

View File

@ -30,6 +30,6 @@ call ale#linter#Define('php', {
\ 'name': 'php',
\ 'executable': 'php',
\ 'output_stream': 'stdout',
\ 'command': 'php -l -d error_reporting=E_ALL -d display_errors=1 --',
\ 'command': 'php -l -d error_reporting=E_ALL -d display_errors=1 -d log_errors=0 --',
\ 'callback': 'ale_linters#php#php#Handle',
\})

View File

@ -26,6 +26,6 @@ call ale#linter#Define('rust', {
\ 'executable_callback': 'ale_linters#rust#cargo#GetCargoExecutable',
\ 'command_callback': 'ale_linters#rust#cargo#GetCommand',
\ 'callback': 'ale#handlers#rust#HandleRustErrors',
\ 'output_stream': 'stdout',
\ 'output_stream': 'both',
\ 'lint_file': 1,
\})

View File

@ -23,15 +23,20 @@ function! ale_linters#sh#shellcheck#GetDialectArgument(buffer) abort
let l:shell_type = ale#handlers#sh#GetShellType(a:buffer)
if !empty(l:shell_type)
" Use the dash dialect for /bin/ash, etc.
if l:shell_type is# 'ash'
return 'dash'
endif
return l:shell_type
endif
" If there's no hashbang, try using Vim's buffer variables.
if get(b:, 'is_bash')
if getbufvar(a:buffer, 'is_bash', 0)
return 'bash'
elseif get(b:, 'is_sh')
elseif getbufvar(a:buffer, 'is_sh', 0)
return 'sh'
elseif get(b:, 'is_kornshell')
elseif getbufvar(a:buffer, 'is_kornshell', 0)
return 'ksh'
endif

View File

@ -24,6 +24,10 @@ function! ale_linters#typescript#tslint#Handle(buffer, lines) abort
let l:output = []
for l:error in ale#util#FuzzyJSONDecode(a:lines, [])
if get(l:error, 'ruleName', '') is# 'no-implicit-dependencies'
continue
endif
call add(l:output, {
\ 'filename': ale#path#GetAbsPath(l:dir, l:error.name),
\ 'type': (get(l:error, 'ruleSeverity', '') is# 'WARNING' ? 'W' : 'E'),

View File

@ -61,6 +61,12 @@ function! ale#ShouldDoNothing(buffer) abort
return 1
endif
let l:filename = fnamemodify(bufname(a:buffer), ':t')
if l:filename is# '.'
return 1
endif
" Do nothing if running in the sandbox
if ale#util#InSandbox()
return 1

View File

@ -282,7 +282,23 @@ function! s:TimerHandler(...) abort
endif
endfunction
" Stop any completion timer that is queued. This is useful for tests.
function! ale#completion#StopTimer() abort
if s:timer_id != -1
call timer_stop(s:timer_id)
endif
let s:timer_id = -1
endfunction
function! ale#completion#Queue() abort
let l:time = get(b:, 'ale_complete_done_time', 0)
if l:time && ale#util#ClockMilliseconds() - l:time < 100
" Do not ask for completions shortly after we just closed the menu.
return
endif
let s:timer_pos = getcurpos()[1:2]
" If we changed the text again while we're still waiting for a response,
@ -291,9 +307,7 @@ function! ale#completion#Queue() abort
let b:ale_completion_info.request_id = 0
endif
if s:timer_id != -1
call timer_stop(s:timer_id)
endif
call ale#completion#StopTimer()
let s:timer_id = timer_start(g:ale_completion_delay, function('s:TimerHandler'))
endfunction
@ -311,6 +325,9 @@ function! ale#completion#Done() abort
let &l:completeopt = b:ale_old_completopt
unlet b:ale_old_completopt
endif
" Set a timestamp, so we can avoid requesting completions again.
let b:ale_complete_done_time = ale#util#ClockMilliseconds()
endfunction
function! s:Setup(enabled) abort

View File

@ -12,7 +12,7 @@ function! ale#fixers#autopep8#Fix(buffer) abort
\ ['autopep8'],
\)
if !ale#python#IsExecutable(l:executable)
if !executable(l:executable)
return 0
endif

View File

@ -11,7 +11,7 @@ function! ale#fixers#isort#Fix(buffer) abort
\ ['isort'],
\)
if !ale#python#IsExecutable(l:executable)
if !executable(l:executable)
return 0
endif

View File

@ -11,7 +11,7 @@ function! ale#fixers#yapf#Fix(buffer) abort
\ ['yapf'],
\)
if !ale#python#IsExecutable(l:executable)
if !executable(l:executable)
return 0
endif

View File

@ -19,7 +19,7 @@ function! ale#handlers#haskell#HandleGHCFormat(buffer, lines) abort
" in Haskell error messages with the basename for this file.
let l:temp_filename_regex = s:temp_regex_prefix . l:basename
let l:pattern = '\v^([a-zA-Z]?:?[^:]+):(\d+):(\d+):(.*)?$'
let l:pattern = '\v^\s*([a-zA-Z]?:?[^:]+):(\d+):(\d+):(.*)?$'
let l:output = []
let l:corrected_lines = []

View File

@ -9,7 +9,7 @@ function! ale#handlers#sh#GetShellType(buffer) abort
" Remove options like -e, etc.
let l:command = substitute(l:bang_line, ' --\?[a-zA-Z0-9]\+', '', 'g')
for l:possible_shell in ['bash', 'tcsh', 'csh', 'zsh', 'sh']
for l:possible_shell in ['bash', 'dash', 'ash', 'tcsh', 'csh', 'zsh', 'sh']
if l:command =~# l:possible_shell . '\s*$'
return l:possible_shell
endif

View File

@ -25,6 +25,11 @@ endfunction
" Note that jobs and IDs are the same thing on NeoVim.
function! ale#job#JoinNeovimOutput(job, last_line, data, mode, callback) abort
if a:mode is# 'raw'
call a:callback(a:job, join(a:data, "\n"))
return ''
endif
let l:lines = a:data[:-2]
if len(a:data) > 1
@ -34,15 +39,9 @@ function! ale#job#JoinNeovimOutput(job, last_line, data, mode, callback) abort
let l:new_last_line = a:last_line . a:data[0]
endif
if a:mode is# 'raw'
if !empty(l:lines)
call a:callback(a:job, join(l:lines, "\n") . "\n")
endif
else
for l:line in l:lines
call a:callback(a:job, l:line)
endfor
endif
for l:line in l:lines
call a:callback(a:job, l:line)
endfor
return l:new_last_line
endfunction
@ -290,7 +289,7 @@ function! ale#job#Stop(job_id) abort
" FIXME: NeoVim kills jobs on a timer, but will not kill any processes
" which are child processes on Unix. Some work needs to be done to
" kill child processes to stop long-running processes like pylint.
call jobstop(a:job_id)
silent! call jobstop(a:job_id)
else
let l:job = s:job_map[a:job_id].job

View File

@ -53,7 +53,7 @@ function! ale#lsp#message#DidOpen(buffer, language_id) abort
\ 'uri': ale#path#ToURI(expand('#' . a:buffer . ':p')),
\ 'languageId': a:language_id,
\ 'version': ale#lsp#message#GetNextVersionID(),
\ 'text': join(l:lines, "\n"),
\ 'text': join(l:lines, "\n") . "\n",
\ },
\}]
endfunction
@ -67,7 +67,7 @@ function! ale#lsp#message#DidChange(buffer) abort
\ 'uri': ale#path#ToURI(expand('#' . a:buffer . ':p')),
\ 'version': ale#lsp#message#GetNextVersionID(),
\ },
\ 'contentChanges': [{'text': join(l:lines, "\n")}]
\ 'contentChanges': [{'text': join(l:lines, "\n") . "\n"}]
\}]
endfunction

View File

@ -28,7 +28,7 @@ function! ale#lsp#tsserver_message#Change(buffer) abort
\ 'offset': 1,
\ 'endLine': 1073741824,
\ 'endOffset': 1,
\ 'insertString': join(l:lines, "\n"),
\ 'insertString': join(l:lines, "\n") . "\n",
\}]
endfunction

View File

@ -185,5 +185,12 @@ function! ale#path#FromURI(uri) abort
let l:i = len('file://')
let l:encoded_path = a:uri[: l:i - 1] is# 'file://' ? a:uri[l:i :] : a:uri
return ale#uri#Decode(l:encoded_path)
let l:path = ale#uri#Decode(l:encoded_path)
" If the path is like /C:/foo/bar, it should be C:\foo\bar instead.
if l:path =~# '^/[a-zA-Z]:'
let l:path = substitute(l:path[1:], '/', '\\', 'g')
endif
return l:path
endfunction

View File

@ -74,12 +74,6 @@ function! ale#python#FindVirtualenv(buffer) abort
return $VIRTUAL_ENV
endfunction
" Run an executable check for Python scripts.
" On Windows, 1 will be returned if the file is merely readable.
function! ale#python#IsExecutable(path) abort
return has('win32') ? filereadable(a:path) : executable(a:path)
endfunction
" Given a buffer number and a command name, find the path to the executable.
" First search on a virtualenv for Python, if nothing is found, try the global
" command. Returns an empty string if cannot find the executable
@ -96,7 +90,7 @@ function! ale#python#FindExecutable(buffer, base_var_name, path_list) abort
\ join([l:virtualenv, s:bin_dir, l:path], s:sep)
\)
if ale#python#IsExecutable(l:ve_executable)
if executable(l:ve_executable)
return l:ve_executable
endif
endfor

View File

@ -247,7 +247,7 @@ Notes:
* Fortran: `gcc`
* FusionScript: `fusion-lint`
* GLSL: glslang
* Go: `gofmt`, `go vet`, `golint`, `gometalinter`!!, `go build`!!, `gosimple`, `staticcheck`
* Go: `gofmt`, `go vet`, `golint`, `gometalinter`!!, `go build`!!, `gosimple`!!, `staticcheck`!!
* GraphQL: `gqlint`
* Haml: `haml-lint`
* Handlebars: `ember-template-lint`

View File

@ -28,12 +28,15 @@ Before:
call ale#test#SetFilename('dummy.java')
let g:prefix = 'cd ' . ale#Escape(expand('%:p:h')) . ' && javac -Xlint'
After:
call ale#test#RestoreDirectory()
Restore
unlet! g:cp_sep
unlet! g:prefix
delfunction GetCommand
@ -43,20 +46,21 @@ After:
call ale#engine#Cleanup(bufnr(''))
Execute(The javac callback should return the correct default value):
AssertEqual 'javac -Xlint -d TEMP %t', GetCommand([])
AssertEqual g:prefix . ' -d TEMP %t', GetCommand([])
Execute(The javac callback should use g:ale_java_javac_classpath correctly):
let g:ale_java_javac_classpath = 'foo.jar'
AssertEqual
\ 'javac -Xlint'
\ g:prefix
\ . ' -cp ' . ale#Escape('foo.jar')
\ . ' -d TEMP %t',
\ GetCommand([])
Execute(The javac callback should include discovered classpaths):
AssertEqual
\ 'javac -Xlint -cp '
\ g:prefix
\ . ' -cp '
\ . ale#Escape(join(['/foo/bar.jar', '/xyz/abc.jar'], g:cp_sep))
\ . ' -d TEMP %t',
\ GetCommand([
@ -70,7 +74,8 @@ Execute(The javac callback should combine discovered classpaths and manual ones)
let g:ale_java_javac_classpath = 'configured.jar'
AssertEqual
\ 'javac -Xlint -cp '
\ g:prefix
\ . ' -cp '
\ . ale#Escape(join(
\ [
\ '/foo/bar.jar',
@ -90,7 +95,8 @@ Execute(The javac callback should combine discovered classpaths and manual ones)
let g:ale_java_javac_classpath = 'configured.jar' . g:cp_sep . 'configured2.jar'
AssertEqual
\ 'javac -Xlint -cp '
\ g:prefix
\ . ' -cp '
\ . ale#Escape(join(
\ [
\ '/foo/bar.jar',
@ -114,7 +120,7 @@ Execute(The javac callback should detect source directories):
call ale#engine#InitBufferInfo(bufnr(''))
AssertEqual
\ 'javac -Xlint'
\ 'cd ' . ale#Escape(expand('%:p:h')) . ' && javac -Xlint'
\ . ' -sourcepath ' . ale#Escape(
\ ale#path#Winify(g:dir . '/java_paths/src/main/java/')
\ )
@ -127,7 +133,7 @@ Execute(The javac callback should combine detected source directories and classp
call ale#engine#InitBufferInfo(bufnr(''))
AssertEqual
\ 'javac -Xlint'
\ 'cd ' . ale#Escape(expand('%:p:h')) . ' && javac -Xlint'
\ . ' -cp ' . ale#Escape(join(['/foo/bar.jar', '/xyz/abc.jar'], g:cp_sep))
\ . ' -sourcepath ' . ale#Escape(
\ ale#path#Winify(g:dir . '/java_paths/src/main/java/')
@ -146,6 +152,6 @@ Execute(The javac callback should use g:ale_java_javac_options correctly):
let b:command = ale_linters#java#javac#GetCommand(bufnr(''), [])
AssertEqual
\ 'javac -Xlint'
\ g:prefix
\ . ' -d TEMP --anything --else %t',
\ GetCommand([])

View File

@ -76,3 +76,25 @@ Execute(The ghc handler should handle ghc 7 output):
\ ale#path#Winify('src/Main.hs') . ':94:5:Error:',
\ ' Some other error',
\ ])
Execute(The ghc handler should handle stack 1.5.1 output):
call ale#test#SetFilename('src/Main.hs')
AssertEqual
\ [
\ {
\ 'lnum': 160,
\ 'col': 14,
\ 'type': 'E',
\ 'text': '• Expecting one fewer arguments to Exp Expected kind k0 -> *, but Exp has kind * • In the type Exp a | 160 | pattern F :: Exp a | ^^^^^',
\ },
\ ],
\ ale#handlers#haskell#HandleGHCFormat(bufnr(''), [
\ ' ' . ale#path#Winify('src/Main.hs') . ':160:14: error:',
\ ' • Expecting one fewer arguments to Exp',
\ ' Expected kind k0 -> *, but Exp has kind *',
\ ' • In the type Exp a',
\ ' |',
\ ' 160 | pattern F :: Exp a',
\ ' | ^^^^^',
\ ])

View File

@ -1,42 +1,51 @@
Before:
runtime ale_linters/java/javac.vim
call ale#test#SetDirectory('/testplugin/test')
call ale#test#SetFilename('dummy.java')
After:
call ale#test#RestoreDirectory()
call ale#linter#Reset()
Execute(The javac handler should handle cannot find symbol errors):
AssertEqual
\ [
\ {
\ 'filename': '/tmp/vLPr4Q5/33/foo.java',
\ 'lnum': 1,
\ 'text': 'error: some error',
\ 'type': 'E',
\ },
\ {
\ 'filename': '/tmp/vLPr4Q5/33/foo.java',
\ 'lnum': 2,
\ 'col': 5,
\ 'text': 'error: cannot find symbol: BadName',
\ 'type': 'E',
\ },
\ {
\ 'filename': '/tmp/vLPr4Q5/33/foo.java',
\ 'lnum': 34,
\ 'col': 5,
\ 'text': 'error: cannot find symbol: BadName2',
\ 'type': 'E',
\ },
\ {
\ 'filename': '/tmp/vLPr4Q5/33/foo.java',
\ 'lnum': 37,
\ 'text': 'warning: some warning',
\ 'type': 'W',
\ },
\ {
\ 'filename': '/tmp/vLPr4Q5/33/foo.java',
\ 'lnum': 42,
\ 'col': 11,
\ 'text': 'error: cannot find symbol: bar()',
\ 'type': 'E',
\ },
\ ],
\ ale_linters#java#javac#Handle(347, [
\ ale_linters#java#javac#Handle(bufnr(''), [
\ '/tmp/vLPr4Q5/33/foo.java:1: error: some error',
\ '/tmp/vLPr4Q5/33/foo.java:2: error: cannot find symbol',
\ ' BadName foo() {',
@ -49,9 +58,30 @@ Execute(The javac handler should handle cannot find symbol errors):
\ ' symbol: class BadName2',
\ ' location: class Bar',
\ '/tmp/vLPr4Q5/33/foo.java:37: warning: some warning',
\ '/tmp/vLPr4Q5/264/foo.java:42: error: cannot find symbol',
\ '/tmp/vLPr4Q5/33/foo.java:42: error: cannot find symbol',
\ ' this.bar();',
\ ' ^',
\ ' symbol: method bar()',
\ '5 errors',
\ ])
Execute(The javac handler should resolve files from different directories):
AssertEqual
\ [
\ {
\ 'filename': ale#path#Winify(g:dir . '/Foo.java'),
\ 'lnum': 1,
\ 'text': 'error: some error',
\ 'type': 'E',
\ },
\ {
\ 'filename': ale#path#Winify(g:dir . '/Bar.java'),
\ 'lnum': 1,
\ 'text': 'error: some error',
\ 'type': 'E',
\ },
\ ],
\ ale_linters#java#javac#Handle(bufnr(''), [
\ './Foo.java:1: error: some error',
\ './Bar.java:1: error: some error',
\ ])

View File

@ -252,3 +252,26 @@ Execute(The tslint handler should report errors when the ignore option is on, bu
\ 'position': 1
\ }
\ }])])
Execute(The tslint handler should not report no-implicit-dependencies errors):
call ale#test#SetFilename('app/test.ts')
AssertEqual
\ [
\ ],
\ ale_linters#typescript#tslint#Handle(bufnr(''), [json_encode([{
\ 'endPosition': {
\ 'character': 0,
\ 'line': 1,
\ 'position': 1
\ },
\ 'failure': 'this is ignored',
\ 'name': 'test.ts',
\ 'ruleName': 'no-implicit-dependencies',
\ 'ruleSeverity': 'ERROR',
\ 'startPosition': {
\ 'character': 0,
\ 'line': 1,
\ 'position': 1
\ }
\ }])])

View File

@ -45,7 +45,7 @@ Execute(ale#lsp#message#DidOpen() should return correct messages):
\ 'uri': ale#path#ToURI(g:dir . '/foo/bar.ts'),
\ 'languageId': 'typescript',
\ 'version': 12,
\ 'text': "foo()\nbar()\nbaz()",
\ 'text': "foo()\nbar()\nbaz()\n",
\ },
\ }
\ ],
@ -63,7 +63,7 @@ Execute(ale#lsp#message#DidChange() should return correct messages):
\ 'uri': ale#path#ToURI(g:dir . '/foo/bar.ts'),
\ 'version': 34,
\ },
\ 'contentChanges': [{'text': "foo()\nbar()\nbaz()"}],
\ 'contentChanges': [{'text': "foo()\nbar()\nbaz()\n"}],
\ }
\ ],
\ ale#lsp#message#DidChange(bufnr(''))
@ -134,7 +134,7 @@ Execute(ale#lsp#tsserver_message#Change() should return correct messages):
\ 'offset': 1,
\ 'endLine': 1073741824,
\ 'endOffset': 1,
\ 'insertString': "foo()\nbar()\nbaz()",
\ 'insertString': "foo()\nbar()\nbaz()\n",
\ }
\ ],
\ ale#lsp#tsserver_message#Change(bufnr(''))

View File

@ -13,6 +13,21 @@ Before:
call add(g:test_vars.feedkeys_calls, [a:string, a:mode])
endfunction
function! CheckCompletionCalled(expect_success) abort
let g:test_vars.get_completions_called = 0
" We just want to check if the function is called.
function! ale#completion#GetCompletions()
let g:test_vars.get_completions_called = 1
endfunction
let g:ale_completion_delay = 0
call ale#completion#Queue()
sleep 1m
AssertEqual a:expect_success, g:test_vars.get_completions_called
endfunction
After:
Restore
@ -22,6 +37,13 @@ After:
unlet! b:ale_completion_info
unlet! b:ale_completion_response
unlet! b:ale_completion_parser
unlet! b:ale_complete_done_time
delfunction CheckCompletionCalled
" Stop any timers we left behind.
" This stops the tests from failing randomly.
call ale#completion#StopTimer()
runtime autoload/ale/completion.vim
runtime autoload/ale/lsp.vim
@ -294,18 +316,7 @@ Execute(b:ale_completion_info should be set up correctly when requesting complet
\ b:ale_completion_info
Execute(ale#completion#GetCompletions should be called when the cursor position stays the same):
let g:test_vars.get_completions_called = 0
" We just want to check if the function is called.
function! ale#completion#GetCompletions()
let g:test_vars.get_completions_called = 1
endfunction
let g:ale_completion_delay = 0
call ale#completion#Queue()
sleep 1m
Assert g:test_vars.get_completions_called
call CheckCompletionCalled(1)
Execute(ale#completion#GetCompletions should not be called when the cursor position changes):
call setpos('.', [bufnr(''), 1, 2, 0])
@ -326,3 +337,8 @@ Execute(ale#completion#GetCompletions should not be called when the cursor posit
sleep 1m
Assert !g:test_vars.get_completions_called
Execute(Completion should not be done shortly after the CompleteDone function):
call CheckCompletionCalled(1)
call ale#completion#Done()
call CheckCompletionCalled(0)

View File

@ -62,8 +62,8 @@ Execute (ALE should pass on full lines for NeoVim for raw data):
Execute (ALE should pass on a single long line):
let g:last_line = ale#job#JoinNeovimOutput(1, '', ['x'], 'raw', function('RawCallback'))
AssertEqual '', g:data
AssertEqual 'x', g:last_line
AssertEqual 'x', g:data
AssertEqual '', g:last_line
Execute (ALE should handle just a single line of output):
let g:last_line = ale#job#JoinNeovimOutput(1, '', ['x', ''], 'raw', function('RawCallback'))
@ -71,20 +71,8 @@ Execute (ALE should handle just a single line of output):
AssertEqual "x\n", g:data
AssertEqual '', g:last_line
Execute (ALE should join two incomplete pieces of large lines together):
let g:last_line = ale#job#JoinNeovimOutput(1, 'x', ['y'], 'raw', function('RawCallback'))
Execute (ALE should pass on two lines and one incomplete one):
let g:last_line = ale#job#JoinNeovimOutput(1, '', ['y', 'z', 'a'], 'raw', function('RawCallback'))
AssertEqual '', g:data
AssertEqual 'xy', g:last_line
Execute (ALE join incomplete lines, and set new ones):
let g:last_line = ale#job#JoinNeovimOutput(1, 'x', ['y', 'z', 'a'], 'raw', function('RawCallback'))
AssertEqual "xy\nz\n", g:data
AssertEqual 'a', g:last_line
Execute (ALE join incomplete lines, and set new ones, with two elements):
let g:last_line = ale#job#JoinNeovimOutput(1, 'x', ['y', 'z'], 'raw', function('RawCallback'))
AssertEqual "xy\n", g:data
AssertEqual 'z', g:last_line
AssertEqual "y\nz\na", g:data
AssertEqual '', g:last_line

View File

@ -2,6 +2,9 @@ Execute(ale#path#ToURI should work for Windows paths):
AssertEqual 'file:///C:/foo/bar/baz.tst', ale#path#ToURI('C:\foo\bar\baz.tst')
AssertEqual 'foo/bar/baz.tst', ale#path#ToURI('foo\bar\baz.tst')
Execute(ale#path#FromURI should work for Windows paths):
AssertEqual 'C:\foo\bar\baz.tst', ale#path#FromURI('file:///C:/foo/bar/baz.tst')
Execute(ale#path#ToURI should work for Unix paths):
AssertEqual 'file:///foo/bar/baz.tst', ale#path#ToURI('/foo/bar/baz.tst')
AssertEqual 'foo/bar/baz.tst', ale#path#ToURI('foo/bar/baz.tst')

View File

@ -81,3 +81,23 @@ Execute(The ksh dialect should be used for shellcheck if b:is_kornshell is 1):
let b:is_kornshell = 1
AssertEqual 'ksh', ale_linters#sh#shellcheck#GetDialectArgument(bufnr(''))
Given(A file with /bin/ash):
#!/bin/ash
Execute(The ash dialect should be used for the shell and the base function):
AssertEqual 'ash', ale#handlers#sh#GetShellType(bufnr(''))
AssertEqual 'ash', ale_linters#sh#shell#GetExecutable(bufnr(''))
Execute(dash should be used for shellcheck, which has no ash dialect):
AssertEqual 'dash', ale_linters#sh#shellcheck#GetDialectArgument(bufnr(''))
Given(A file with /bin/dash):
#!/bin/dash
Execute(The dash dialect should be used for the shell and the base function):
AssertEqual 'dash', ale#handlers#sh#GetShellType(bufnr(''))
AssertEqual 'dash', ale_linters#sh#shell#GetExecutable(bufnr(''))
Execute(dash should be used for shellcheck):
AssertEqual 'dash', ale_linters#sh#shellcheck#GetDialectArgument(bufnr(''))

View File

@ -1,6 +1,8 @@
Before:
Save &l:statusline
call ale#test#SetDirectory('/testplugin/test')
let b:funky_command_created = 0
" We will test for the existence of this command, so create one if needed.
@ -10,6 +12,8 @@ Before:
endif
After:
call ale#test#RestoreDirectory()
if b:funky_command_created
delcommand CtrlPFunky
let b:funky_command_created = 0
@ -25,3 +29,13 @@ Execute(ALE shouldn't do much of anything for ctrlp-funky buffers):
let &l:statusline = '%#CtrlPMode2# prt %*%#CtrlPMode1# line %* <mru>={%#CtrlPMode1# funky %*}=<fil> <-> %=%<%#CtrlPMode2# %{getcwd()} %*'
Assert ale#ShouldDoNothing(bufnr(''))
Execute(ALE shouldn't try to check buffers with '.' as the filename):
AssertEqual
\ 0,
\ ale#ShouldDoNothing(bufnr('')),
\ 'ShouldDoNothing() was 1 for some other reason'
silent! noautocmd file .
Assert ale#ShouldDoNothing(bufnr(''))