From 49f7ce4f6dbca39a013be6d5714d11a2b882d17c Mon Sep 17 00:00:00 2001 From: w0rp Date: Fri, 10 Feb 2017 22:47:56 +0000 Subject: [PATCH] Fix #246 Don't run flow if there's no .flowconfig --- ale_linters/javascript/flow.vim | 100 ++++++++++++------------ test/flow/a/.flowconfig | 0 test/flow/a/sub/dummy | 0 test/flow/b/sub/dummy | 0 test/test_flow_command.vader | 17 ++++ test/test_flow_handler.vader | 132 ++++++++++++++++++++++++++++++++ 6 files changed, 202 insertions(+), 47 deletions(-) create mode 100644 test/flow/a/.flowconfig create mode 100644 test/flow/a/sub/dummy create mode 100644 test/flow/b/sub/dummy create mode 100644 test/test_flow_command.vader create mode 100644 test/test_flow_handler.vader diff --git a/ale_linters/javascript/flow.vim b/ale_linters/javascript/flow.vim index f0b81b1..c1ee4b2 100644 --- a/ale_linters/javascript/flow.vim +++ b/ale_linters/javascript/flow.vim @@ -8,68 +8,74 @@ let g:ale_javascript_flow_use_global = \ get(g:, 'ale_javascript_flow_use_global', 0) function! ale_linters#javascript#flow#GetExecutable(buffer) abort - if g:ale_javascript_flow_use_global - return g:ale_javascript_flow_executable - endif + if g:ale_javascript_flow_use_global + return g:ale_javascript_flow_executable + endif - return ale#util#ResolveLocalPath( - \ a:buffer, - \ 'node_modules/.bin/flow', - \ g:ale_javascript_flow_executable - \) + return ale#util#ResolveLocalPath( + \ a:buffer, + \ 'node_modules/.bin/flow', + \ g:ale_javascript_flow_executable + \) endfunction function! ale_linters#javascript#flow#GetCommand(buffer) abort - return ale_linters#javascript#flow#GetExecutable(a:buffer) - \ . ' check-contents --respect-pragma --json --from ale %s' + let l:flow_config = ale#util#FindNearestFile(a:buffer, '.flowconfig') + + if empty(l:flow_config) + " Don't run Flow if we can't find a .flowconfig file. + return '' + endif + + return ale_linters#javascript#flow#GetExecutable(a:buffer) + \ . ' check-contents --respect-pragma --json --from ale %s' endfunction function! ale_linters#javascript#flow#Handle(buffer, lines) abort - let l:str = join(a:lines, '') - if l:str ==# '' - return [] - endif - let l:flow_output = json_decode(l:str) + let l:str = join(a:lines, '') - if has_key(l:flow_output, 'errors') + if l:str ==# '' + return [] + endif + + let l:flow_output = json_decode(l:str) let l:output = [] - for l:error in l:flow_output.errors - " Each error is broken up into parts - let l:text = '' - let l:line = 0 - let l:col = 0 - for l:message in l:error.message - " Comments have no line of column information - if has_key(l:message, 'loc') && l:line ==# 0 - let l:line = l:message.loc.start.line + 0 - let l:col = l:message.loc.start.column + 0 - endif - if l:text ==# '' - let l:text = l:message.descr . ':' - else - let l:text = l:text . ' ' . l:message.descr - endif - endfor + for l:error in get(l:flow_output, 'errors', []) + " Each error is broken up into parts + let l:text = '' + let l:line = 0 + let l:col = 0 - if has_key(l:error, 'operation') - let l:text = l:text . ' See also: ' . l:error.operation.descr - endif + for l:message in l:error.message + " Comments have no line of column information + if has_key(l:message, 'loc') && l:line ==# 0 + let l:line = l:message.loc.start.line + 0 + let l:col = l:message.loc.start.column + 0 + endif - call add(l:output, { - \ 'bufnr': a:buffer, - \ 'lnum': l:line, - \ 'vcol': 0, - \ 'col': l:col, - \ 'text': l:text, - \ 'type': l:error.level ==# 'error' ? 'E' : 'W', - \}) + if l:text ==# '' + let l:text = l:message.descr . ':' + else + let l:text = l:text . ' ' . l:message.descr + endif + endfor + + if has_key(l:error, 'operation') + let l:text = l:text . ' See also: ' . l:error.operation.descr + endif + + call add(l:output, { + \ 'bufnr': a:buffer, + \ 'lnum': l:line, + \ 'vcol': 0, + \ 'col': l:col, + \ 'text': l:text, + \ 'type': l:error.level ==# 'error' ? 'E' : 'W', + \}) endfor return l:output - else - return [] - endif endfunction call ale#linter#Define('javascript', { diff --git a/test/flow/a/.flowconfig b/test/flow/a/.flowconfig new file mode 100644 index 0000000..e69de29 diff --git a/test/flow/a/sub/dummy b/test/flow/a/sub/dummy new file mode 100644 index 0000000..e69de29 diff --git a/test/flow/b/sub/dummy b/test/flow/b/sub/dummy new file mode 100644 index 0000000..e69de29 diff --git a/test/test_flow_command.vader b/test/test_flow_command.vader new file mode 100644 index 0000000..00a2c2a --- /dev/null +++ b/test/test_flow_command.vader @@ -0,0 +1,17 @@ +Before: + runtime ale_linters/javascript/flow.vim + +After: + call ale#linter#Reset() + +Execute(flow should return a command to run if a .flowconfig file exists): + silent! cd /testplugin/test + :e! flow/a/sub/dummy + + AssertEqual 'flow check-contents --respect-pragma --json --from ale %s', ale_linters#javascript#flow#GetCommand(bufnr('%')) + +Execute(flow should not return a command to run if no .flowconfig file exists): + silent! cd /testplugin/test + :e! flow/b/sub/dummy + + AssertEqual '', ale_linters#javascript#flow#GetCommand(bufnr('%')) diff --git a/test/test_flow_handler.vader b/test/test_flow_handler.vader new file mode 100644 index 0000000..12fe089 --- /dev/null +++ b/test/test_flow_handler.vader @@ -0,0 +1,132 @@ +Before: + let g:flow_output = { + \ "flowVersion": "0.39.0", + \ "errors": [ + \ { + \ "kind": "infer", + \ "level": "error", + \ "message": [ + \ { + \ "context": " return 1", + \ "descr": "number", + \ "type": "Blame", + \ "loc": { + \ "source": "/home/w0rp/Downloads/graphql-js/src/language/parser.js", + \ "type": "SourceFile", + \ "start": { + \ "line": 417, + \ "column": 10, + \ "offset": 9503 + \ }, + \ "end": { + \ "line": 417, + \ "column": 10, + \ "offset": 9504 + \ } + \ }, + \ "path": "/home/w0rp/Downloads/graphql-js/src/language/parser.js", + \ "line": 417, + \ "endline": 417, + \ "start": 10, + \ "end": 10 + \ }, + \ { + \ "context": v:null, + \ "descr": "This type is incompatible with the expected return type of", + \ "type": "Comment", + \ "path": "", + \ "line": 0, + \ "endline": 0, + \ "start": 1, + \ "end": 0 + \ }, + \ { + \ "context": "function parseArguments(lexer: Lexer<*>): Array {", + \ "descr": "array type", + \ "type": "Blame", + \ "loc": { + \ "source": "/home/w0rp/Downloads/graphql-js/src/language/parser.js", + \ "type": "SourceFile", + \ "start": { + \ "line": 416, + \ "column": 43, + \ "offset": 9472 + \ }, + \ "end": { + \ "line": 416, + \ "column": 61, + \ "offset": 9491 + \ } + \ }, + \ "path": "/home/w0rp/Downloads/graphql-js/src/language/parser.js", + \ "line": 416, + \ "endline": 416, + \ "start": 43, + \ "end": 61 + \ } + \ ] + \ }, + \ { + \ "kind": "infer", + \ "level": "warning", + \ "message": [ + \ { + \ "context": " return peek(lexer, TokenKind.PAREN_L) ?", + \ "descr": "unreachable code", + \ "type": "Blame", + \ "loc": { + \ "source": "/home/w0rp/Downloads/graphql-js/src/language/parser.js", + \ "type": "SourceFile", + \ "start": { + \ "line": 419, + \ "column": 3, + \ "offset": 9508 + \ }, + \ "end": { + \ "line": 421, + \ "column": 7, + \ "offset": 9626 + \ } + \ }, + \ "path": "/home/w0rp/Downloads/graphql-js/src/language/parser.js", + \ "line": 419, + \ "endline": 421, + \ "start": 3, + \ "end": 7 + \ } + \ ] + \ } + \ ], + \ "passed": v:false + \} + + runtime ale_linters/javascript/flow.vim + +After: + unlet! g:flow_output + unlet! g:expected + unlet! g:actual + call ale#linter#Reset() + +Execute(The flow handler should process errors correctly.): + let g:actual = ale_linters#javascript#flow#Handle(347, [json_encode(g:flow_output)]) + let g:expected = [ + \ { + \ 'lnum': 417, + \ 'bufnr': 347, + \ 'vcol': 0, + \ 'type': 'E', + \ 'col': 10, + \ 'text': 'number: This type is incompatible with the expected return type of array type', + \ }, + \ { + \ 'lnum': 419, + \ 'bufnr': 347, + \ 'vcol': 0, + \ 'type': 'W', + \ 'col': 3, + \ 'text': 'unreachable code:', + \ }, + \] + + AssertEqual g:expected, g:actual