summaryrefslogtreecommitdiff
path: root/test/fix/test_ale_fix.vader
diff options
context:
space:
mode:
Diffstat (limited to 'test/fix/test_ale_fix.vader')
-rw-r--r--test/fix/test_ale_fix.vader614
1 files changed, 614 insertions, 0 deletions
diff --git a/test/fix/test_ale_fix.vader b/test/fix/test_ale_fix.vader
new file mode 100644
index 00000000..47932930
--- /dev/null
+++ b/test/fix/test_ale_fix.vader
@@ -0,0 +1,614 @@
+Before:
+ Save g:ale_fixers
+ Save &shell
+ Save g:ale_enabled
+ Save g:ale_fix_on_save
+ Save g:ale_lint_on_save
+ Save g:ale_echo_cursor
+
+ silent! cd /testplugin/test/fix
+
+ let g:ale_enabled = 0
+ let g:ale_echo_cursor = 0
+ let g:ale_run_synchronously = 1
+ let g:ale_set_lists_synchronously = 1
+ let g:ale_fix_buffer_data = {}
+ let g:ale_fixers = {
+ \ 'testft': [],
+ \}
+
+ if !has('win32')
+ let &shell = '/bin/bash'
+ endif
+
+ call ale#test#SetDirectory('/testplugin/test')
+ call ale#test#SetFilename('test.txt')
+
+ function AddCarets(buffer, lines) abort
+ " map() is applied to the original lines here.
+ " This way, we can ensure that defensive copies are made.
+ return map(a:lines, '''^'' . v:val')
+ endfunction
+
+ function AddDollars(buffer, lines) abort
+ return map(a:lines, '''$'' . v:val')
+ endfunction
+
+ function DoNothing(buffer, lines) abort
+ return 0
+ endfunction
+
+ function CatLine(buffer, lines) abort
+ return {'command': 'cat - <(echo d)'}
+ endfunction
+
+ function CatLineOneArg(buffer) abort
+ return {'command': 'cat - <(echo d)'}
+ endfunction
+
+ function ReplaceWithTempFile(buffer, lines) abort
+ return {'command': 'echo x > %t', 'read_temporary_file': 1}
+ endfunction
+
+ function RemoveLastLine(buffer, lines) abort
+ return ['a', 'b']
+ endfunction
+
+ function RemoveLastLineOneArg(buffer) abort
+ return ['a', 'b']
+ endfunction
+
+ function! TestCallback(buffer, output)
+ return [{'lnum': 1, 'col': 1, 'text': 'xxx'}]
+ endfunction
+
+ function! FirstChainCallback(buffer)
+ return {'command': 'echo echoline', 'chain_with': 'SecondChainCallback'}
+ endfunction
+
+ function! FirstChainCallbackSkipped(buffer)
+ return {'command': '', 'chain_with': 'SecondChainCallback'}
+ endfunction
+
+ function! FirstChainCallbackSecondSkipped(buffer)
+ return {'command': 'echo skipit', 'chain_with': 'SecondChainCallback'}
+ endfunction
+
+ function! SecondChainCallback(buffer, output)
+ let l:previous_line = empty(a:output)
+ \ ? 'emptydefault'
+ \ : join(split(a:output[0]))
+
+ if l:previous_line is# 'skipit'
+ return {'command': '', 'chain_with': 'ThirdChainCallback'}
+ endif
+
+ return {
+ \ 'command': 'echo ' . l:previous_line,
+ \ 'chain_with': 'ThirdChainCallback',
+ \}
+ endfunction
+
+ function! ThirdChainCallback(buffer, output, input)
+ let l:previous_line = empty(a:output)
+ \ ? 'thirddefault'
+ \ : join(split(a:output[0]))
+
+ return a:input + [l:previous_line]
+ endfunction
+
+ function! ChainWhereLastIsSkipped(buffer)
+ return {'command': 'echo echoline', 'chain_with': 'ChainEndSkipped'}
+ endfunction
+
+ function! ChainEndSkipped(buffer, output)
+ return {'command': ''}
+ endfunction
+
+ " echo will output a single blank line, and we should ingore it.
+ function! IgnoredEmptyOutput(buffer, output)
+ return {'command': has('win32') ? 'echo(' : 'echo'}
+ endfunction
+
+ function! EchoLineNoPipe(buffer, output)
+ return {'command': 'echo new line', 'read_buffer': 0}
+ endfunction
+
+ function! SetUpLinters()
+ call ale#linter#Define('testft', {
+ \ 'name': 'testlinter',
+ \ 'callback': 'TestCallback',
+ \ 'executable': 'true',
+ \ 'command': 'true',
+ \})
+ endfunction
+
+ function GetLastMessage()
+ redir => l:output
+ silent mess
+ redir END
+
+ let l:lines = split(l:output, "\n")
+
+ return empty(l:lines) ? '' : l:lines[-1]
+ endfunction
+
+After:
+ Restore
+ unlet! g:ale_run_synchronously
+ unlet! g:ale_set_lists_synchronously
+ unlet! g:ale_emulate_job_failure
+ unlet! b:ale_fixers
+ unlet! b:ale_fix_on_save
+ delfunction AddCarets
+ delfunction AddDollars
+ delfunction DoNothing
+ delfunction CatLine
+ delfunction CatLineOneArg
+ delfunction ReplaceWithTempFile
+ delfunction RemoveLastLine
+ delfunction RemoveLastLineOneArg
+ delfunction TestCallback
+ delfunction FirstChainCallback
+ delfunction FirstChainCallbackSkipped
+ delfunction FirstChainCallbackSecondSkipped
+ delfunction SecondChainCallback
+ delfunction ThirdChainCallback
+ delfunction ChainWhereLastIsSkipped
+ delfunction ChainEndSkipped
+ delfunction SetUpLinters
+ delfunction GetLastMessage
+ delfunction IgnoredEmptyOutput
+ delfunction EchoLineNoPipe
+
+ call ale#test#RestoreDirectory()
+
+ call ale#fix#registry#ResetToDefaults()
+ call ale#linter#Reset()
+
+ setlocal buftype=nofile
+
+ if filereadable('fix_test_file')
+ call delete('fix_test_file')
+ endif
+
+ call setloclist(0, [])
+
+ let g:ale_fix_buffer_data = {}
+
+ " Clear the messages between tests.
+ echomsg ''
+
+Given testft (A file with three lines):
+ a
+ b
+ c
+
+Execute(ALEFix should complain when there are no functions to call):
+ ALEFix
+ AssertEqual 'No fixers have been defined. Try :ALEFixSuggest', GetLastMessage()
+
+Execute(ALEFix should apply simple functions):
+ let g:ale_fixers.testft = ['AddCarets']
+ ALEFix
+
+Expect(The first function should be used):
+ ^a
+ ^b
+ ^c
+
+Execute(ALEFix should apply simple functions in a chain):
+ let g:ale_fixers.testft = ['AddCarets', 'AddDollars']
+ ALEFix
+
+Expect(Both functions should be used):
+ $^a
+ $^b
+ $^c
+
+Execute(ALEFix should allow 0 to be returned to skip functions):
+ let g:ale_fixers.testft = ['DoNothing', 'AddDollars']
+ ALEFix
+
+Expect(Only the second function should be applied):
+ $a
+ $b
+ $c
+
+Execute(ALEFix should allow commands to be run):
+ if has('win32')
+ " Just skip this test on Windows, we can't run it.
+ call setline(1, ['a', 'b', 'c', 'd'])
+ else
+ let g:ale_fixers.testft = ['CatLine']
+ ALEFix
+ endif
+
+Expect(An extra line should be added):
+ a
+ b
+ c
+ d
+
+Execute(ALEFix should allow temporary files to be read):
+ if has('win32')
+ " Just skip this test on Windows, we can't run it.
+ call setline(1, ['x'])
+ 2,3d
+ else
+ let g:ale_fixers.testft = ['ReplaceWithTempFile']
+ ALEFix
+ endif
+
+Expect(The line we wrote to the temporary file should be used here):
+ x
+
+Execute(ALEFix should allow jobs and simple functions to be combined):
+ if has('win32')
+ " Just skip this test on Windows, we can't run it.
+ call setline(1, ['$x'])
+ 2,3d
+ else
+ let g:ale_fixers.testft = ['ReplaceWithTempFile', 'AddDollars']
+ ALEFix
+ endif
+
+Expect(The lines from the temporary file should be modified):
+ $x
+
+Execute(ALEFix should send lines modified by functions to jobs):
+ if has('win32')
+ " Just skip this test on Windows, we can't run it.
+ call setline(1, ['$a', '$b', '$c', 'd'])
+ else
+ let g:ale_fixers.testft = ['AddDollars', 'CatLine']
+ ALEFix
+ endif
+
+Expect(The lines should first be modified by the function, then the job):
+ $a
+ $b
+ $c
+ d
+
+Execute(ALEFix should skip commands when jobs fail to run):
+ let g:ale_emulate_job_failure = 1
+ let g:ale_fixers.testft = ['CatLine', 'AddDollars']
+ ALEFix
+
+Expect(Only the second function should be applied):
+ $a
+ $b
+ $c
+
+Execute(ALEFix should handle strings for selecting a single function):
+ let g:ale_fixers.testft = 'AddCarets'
+ ALEFix
+
+Expect(The first function should be used):
+ ^a
+ ^b
+ ^c
+
+Execute(ALEFix should use functions from the registry):
+ call ale#fix#registry#Add('add_carets', 'AddCarets', [], 'Add some carets')
+ let g:ale_fixers.testft = ['add_carets']
+ ALEFix
+
+Expect(The registry function should be used):
+ ^a
+ ^b
+ ^c
+
+Execute(ALEFix should be able to remove the last line for files):
+ let g:ale_fixers.testft = ['RemoveLastLine']
+ ALEFix
+
+Expect(There should be only two lines):
+ a
+ b
+
+Execute(ALEFix should accept funcrefs):
+ let g:ale_fixers.testft = [function('RemoveLastLine')]
+ ALEFix
+
+Expect(There should be only two lines):
+ a
+ b
+
+Execute(ALEFix should accept lambdas):
+ if has('nvim')
+ " NeoVim 0.1.7 can't interpret lambdas correctly, so just set the lines
+ " to make the test pass.
+ call setline(1, ['a', 'b', 'c', 'd'])
+ else
+ let g:ale_fixers.testft = [{buffer, lines -> lines + ['d']}]
+ ALEFix
+ endif
+
+Expect(There should be an extra line):
+ a
+ b
+ c
+ d
+
+Execute(ALEFix should user buffer-local fixer settings):
+ let g:ale_fixers.testft = ['AddCarets', 'AddDollars']
+ let b:ale_fixers = {'testft': ['RemoveLastLine']}
+ ALEFix
+
+Expect(There should be only two lines):
+ a
+ b
+
+Execute(ALEFix should allow Lists to be used for buffer-local fixer settings):
+ let g:ale_fixers.testft = ['AddCarets', 'AddDollars']
+ let b:ale_fixers = ['RemoveLastLine']
+ ALEFix
+
+Expect(There should be only two lines):
+ a
+ b
+
+Given testft (A file with three lines):
+ a
+ b
+ c
+
+Execute(ALEFix should save files on the save event):
+ let g:ale_fix_on_save = 1
+ let g:ale_lint_on_save = 1
+ let g:ale_enabled = 1
+
+ noautocmd silent file fix_test_file
+ call writefile(getline(1, '$'), 'fix_test_file')
+
+ let g:ale_fixers.testft = ['AddDollars']
+
+ " We have to set the buftype to empty so the file will be written.
+ setlocal buftype=
+
+ call SetUpLinters()
+ call ale#events#SaveEvent(bufnr(''))
+
+ " We should save the file.
+ AssertEqual ['$a', '$b', '$c'], readfile('fix_test_file')
+ Assert !&modified, 'The was marked as ''modified'''
+
+ if !has('win32')
+ " We should have run the linter.
+ AssertEqual [{
+ \ 'bufnr': bufnr('%'),
+ \ 'lnum': 1,
+ \ 'vcol': 0,
+ \ 'col': 1,
+ \ 'text': 'xxx',
+ \ 'type': 'E',
+ \ 'nr': -1,
+ \ 'pattern': '',
+ \ 'valid': 1,
+ \}], getloclist(0)
+ endif
+
+Expect(The buffer should be modified):
+ $a
+ $b
+ $c
+
+Given testft (A file with three lines):
+ a
+ b
+ c
+
+Execute(ALEFix should still lint with no linters to be applied):
+ let g:ale_fix_on_save = 1
+ let g:ale_lint_on_save = 1
+ let g:ale_enabled = 1
+
+ noautocmd silent file fix_test_file
+
+ let g:ale_fixers.testft = []
+
+ call SetUpLinters()
+ call ale#events#SaveEvent(bufnr(''))
+
+ Assert !filereadable('fix_test_file'), 'The file should not have been saved'
+
+ if !has('win32')
+ " We have run the linter.
+ AssertEqual [{
+ \ 'bufnr': bufnr('%'),
+ \ 'lnum': 1,
+ \ 'vcol': 0,
+ \ 'col': 1,
+ \ 'text': 'xxx',
+ \ 'type': 'E',
+ \ 'nr': -1,
+ \ 'pattern': '',
+ \ 'valid': 1,
+ \}], getloclist(0)
+ endif
+
+Expect(The buffer should be the same):
+ a
+ b
+ c
+
+Execute(ALEFix should still lint when nothing was fixed on save):
+ let g:ale_fix_on_save = 1
+ let g:ale_lint_on_save = 1
+ let g:ale_enabled = 1
+
+ noautocmd silent file fix_test_file
+
+ let g:ale_fixers.testft = ['DoNothing']
+
+ call SetUpLinters()
+ call ale#events#SaveEvent(bufnr(''))
+
+ Assert !filereadable('fix_test_file'), 'The file should not have been saved'
+
+ if !has('win32')
+ " We should have run the linter.
+ AssertEqual [{
+ \ 'bufnr': bufnr('%'),
+ \ 'lnum': 1,
+ \ 'vcol': 0,
+ \ 'col': 1,
+ \ 'text': 'xxx',
+ \ 'type': 'E',
+ \ 'nr': -1,
+ \ 'pattern': '',
+ \ 'valid': 1,
+ \}], getloclist(0)
+ endif
+
+Expect(The buffer should be the same):
+ a
+ b
+ c
+
+Given testft (A file with three lines):
+ a
+ b
+ c
+
+Execute(ale#fix#InitBufferData() should set up the correct data):
+ noautocmd silent file fix_test_file
+
+ call ale#fix#InitBufferData(bufnr(''), 'save_file')
+
+ AssertEqual {
+ \ bufnr(''): {
+ \ 'temporary_directory_list': [],
+ \ 'vars': b:,
+ \ 'filename': ale#path#Winify(getcwd() . '/fix_test_file'),
+ \ 'done': 0,
+ \ 'lines_before': ['a', 'b', 'c'],
+ \ 'should_save': 1,
+ \ },
+ \}, g:ale_fix_buffer_data
+
+Execute(ALEFix simple functions should be able to accept one argument, the buffer):
+ let g:ale_fixers.testft = ['RemoveLastLineOneArg']
+ ALEFix
+
+Expect(There should be only two lines):
+ a
+ b
+
+Execute(b:ale_fix_on_save = 1 should override g:ale_fix_on_save = 0):
+ let g:ale_fix_on_save = 0
+ let b:ale_fix_on_save = 1
+
+ let g:ale_fixers.testft = ['RemoveLastLineOneArg']
+ call ale#events#SaveEvent(bufnr(''))
+
+Expect(There should be only two lines):
+ a
+ b
+
+Execute(b:ale_fix_on_save = 0 should override g:ale_fix_on_save = 1):
+ let g:ale_fix_on_save = 1
+ let b:ale_fix_on_save = 0
+
+ let g:ale_fixers.testft = ['RemoveLastLineOneArg']
+ call ale#events#SaveEvent(bufnr(''))
+
+Expect(The lines should be the same):
+ a
+ b
+ c
+
+Execute(ALEFix functions returning jobs should be able to accept one argument):
+ if has('win32')
+ " Just skip this test on Windows, we can't run it.
+ call setline(1, ['a', 'b', 'c', 'd'])
+ else
+ let g:ale_fixers.testft = ['CatLine']
+ ALEFix
+ endif
+
+Expect(An extra line should be added):
+ a
+ b
+ c
+ d
+
+Execute(ALE should print a message telling you something isn't a valid fixer when you type some nonsense):
+ let g:ale_fixers.testft = ['CatLine', 'invalidname']
+ ALEFix
+
+ AssertEqual 'There is no fixer named `invalidname`. Check :ALEFixSuggest', GetLastMessage()
+
+Execute(Test fixing with chained callbacks):
+ let g:ale_fixers.testft = ['FirstChainCallback']
+ ALEFix
+
+ " The buffer shouldn't be piped in for earlier commands in the chain.
+ AssertEqual
+ \ [
+ \ string(ale#job#PrepareCommand('echo echoline')),
+ \ string(ale#job#PrepareCommand('echo echoline')),
+ \ ],
+ \ map(ale#history#Get(bufnr(''))[-2:-1], 'string(v:val.command)')
+
+Expect(The echoed line should be added):
+ a
+ b
+ c
+ echoline
+
+Execute(Test fixing with chained callback where the first command is skipped):
+ let g:ale_fixers.testft = ['FirstChainCallbackSkipped']
+ ALEFix
+
+Expect(The default line should be added):
+ a
+ b
+ c
+ emptydefault
+
+Execute(Test fixing with chained callback where the second command is skipped):
+ let g:ale_fixers.testft = ['FirstChainCallbackSecondSkipped']
+ ALEFix
+
+Expect(The default line should be added):
+ a
+ b
+ c
+ thirddefault
+
+Execute(Test fixing with chained callback where the final callback is skipped):
+ let g:ale_fixers.testft = ['ChainWhereLastIsSkipped']
+ ALEFix
+
+Expect(The lines should be the same):
+ a
+ b
+ c
+
+Execute(Empty output should be ignored):
+ let g:ale_fixers.testft = ['IgnoredEmptyOutput']
+ ALEFix
+
+Expect(The lines should be the same):
+ a
+ b
+ c
+
+Execute(A temporary file shouldn't be piped into the command when disabled):
+ let g:ale_fixers.testft = ['EchoLineNoPipe']
+ ALEFix
+
+ AssertEqual
+ \ string(ale#job#PrepareCommand('echo new line')),
+ \ string(ale#history#Get(bufnr(''))[-1].command)
+
+ " Remove trailing whitespace for Windows.
+ if has('win32')
+ %s/[[:space:]]*$//g
+ endif
+
+Expect(The new line should be used):
+ new line