From 5160f814d929e0936c3d920087e0c4d16040ae9c Mon Sep 17 00:00:00 2001 From: w0rp Date: Wed, 22 Nov 2017 23:23:14 +0000 Subject: [PATCH] Fix #988 - Support --fix-dry-run for ESLint by processing the JSON output --- autoload/ale/fixers/eslint.vim | 17 +++++++++ autoload/ale/util.vim | 9 ++++- test/fixers/test_eslint_fixer_callback.vader | 36 ++++++++++++++++++++ test/test_fuzzy_json_decode.vader | 8 +++++ 4 files changed, 69 insertions(+), 1 deletion(-) diff --git a/autoload/ale/fixers/eslint.vim b/autoload/ale/fixers/eslint.vim index d30f1ba6..76615fb5 100644 --- a/autoload/ale/fixers/eslint.vim +++ b/autoload/ale/fixers/eslint.vim @@ -14,6 +14,14 @@ function! ale#fixers#eslint#Fix(buffer) abort \} endfunction +function! ale#fixers#eslint#ProcessFixDryRunOutput(buffer, output) abort + for l:item in ale#util#FuzzyJSONDecode(a:output, []) + return split(get(l:item, 'output', ''), "\n") + endfor + + return [] +endfunction + function! ale#fixers#eslint#ApplyFixForVersion(buffer, version_output) abort let l:executable = ale#handlers#eslint#GetExecutable(a:buffer) let l:version = ale#semver#GetVersion(l:executable, a:version_output) @@ -32,6 +40,15 @@ function! ale#fixers#eslint#ApplyFixForVersion(buffer, version_output) abort \} endif + " 4.9.0 is the first version with --fix-dry-run + if ale#semver#GTE(l:version, [4, 9, 0]) + return { + \ 'command': ale#node#Executable(a:buffer, l:executable) + \ . ' --stdin-filename %s --stdin --fix-dry-run --format=json', + \ 'process_with': 'ale#fixers#eslint#ProcessFixDryRunOutput', + \} + endif + return { \ 'command': ale#node#Executable(a:buffer, l:executable) \ . ' -c ' . ale#Escape(l:config) diff --git a/autoload/ale/util.vim b/autoload/ale/util.vim index cf8d5bec..1f590adc 100644 --- a/autoload/ale/util.vim +++ b/autoload/ale/util.vim @@ -250,7 +250,14 @@ function! ale#util#FuzzyJSONDecode(data, default) abort let l:str = type(a:data) == type('') ? a:data : join(a:data, '') try - return json_decode(l:str) + let l:result = json_decode(l:str) + + " Vim 8 only uses the value v:none for decoding blank strings. + if !has('nvim') && l:result is v:none + return a:default + endif + + return l:result catch /E474/ return a:default endtry diff --git a/test/fixers/test_eslint_fixer_callback.vader b/test/fixers/test_eslint_fixer_callback.vader index 8a5eaa4e..afb267a2 100644 --- a/test/fixers/test_eslint_fixer_callback.vader +++ b/test/fixers/test_eslint_fixer_callback.vader @@ -69,6 +69,18 @@ Execute(The version check should be correct): \ }, \ 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 ' : '') + \ . ale#Escape(ale#path#Winify(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(''), ['4.9.0']) + Execute(--fix-to-stdout should be used for eslint_d): call ale#test#SetFilename('../eslint-test-files/app-with-eslint-d/testfile.js') @@ -114,3 +126,27 @@ Execute(The version number should be cached): \ '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#Winify(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): + AssertEqual + \ [], + \ ale#fixers#eslint#ProcessFixDryRunOutput(bufnr(''), []) + AssertEqual + \ [], + \ ale#fixers#eslint#ProcessFixDryRunOutput(bufnr(''), ['']) + AssertEqual + \ [], + \ ale#fixers#eslint#ProcessFixDryRunOutput(bufnr(''), ['[{}]']) + AssertEqual + \ ['foo', 'bar'], + \ ale#fixers#eslint#ProcessFixDryRunOutput(bufnr(''), ['[{"output": "foo\nbar"}]']) diff --git a/test/test_fuzzy_json_decode.vader b/test/test_fuzzy_json_decode.vader index 4ac0ca1b..4b1c6088 100644 --- a/test/test_fuzzy_json_decode.vader +++ b/test/test_fuzzy_json_decode.vader @@ -6,6 +6,14 @@ Execute(FuzzyJSONDecode should return the default for empty Strings): AssertEqual [], ale#util#FuzzyJSONDecode('', []) AssertEqual {}, ale#util#FuzzyJSONDecode('', {}) +Execute(FuzzyJSONDecode should return the default value for ['']): + AssertEqual [], ale#util#FuzzyJSONDecode([''], []) + AssertEqual {}, ale#util#FuzzyJSONDecode([''], {}) + +Execute(FuzzyJSONDecode should return the default value for only whitespace lines): + AssertEqual [], ale#util#FuzzyJSONDecode(['', "\n"], []) + AssertEqual {}, ale#util#FuzzyJSONDecode(['', "\n"], {}) + Execute(FuzzyJSONDecode should return the default for Lists with invalid JSON): AssertEqual [], ale#util#FuzzyJSONDecode(['x'], []) AssertEqual {}, ale#util#FuzzyJSONDecode(['x'], {})