This repository has been archived on 2024-07-19. You can view files and clone it, but cannot push or open issues or pull requests.
ale/test/test_code_action_corner_cases.vader

180 lines
8.4 KiB
Text
Raw Normal View History

" Tests for various corner cases of applying code changes from LSP.
"
" These can be verified against the reference vscode implementation using the
" following javascript program:
"
" const { TextDocument } = require('vscode-languageserver-textdocument');
" const { TextEdit, Position, Range } = require('vscode-languageserver-types');
" function MkPos(line, offset) { return Position.create(line - 1, offset - 1); }
" function MkInsert(pos, newText) { return TextEdit.insert(pos, newText); }
" function MkDelete(start, end) { return TextEdit.del(Range.create(start, end)); }
" function TestChanges(s, es) {
" return TextDocument.applyEdits(TextDocument.create(null, null, null, s), es);
" }
"
" const fs = require("fs");
" const assert = require('assert').strict;
" const testRegex = /(?<!vscode skip.*)AssertEqual\s+("[^"]*"),\s*TestChanges\(("[^"]*"),\s*(\[[^\]]*\])/g;
" const data = fs.readFileSync(0, "utf-8");
" const tests = data.matchAll(testRegex);
" for (const test of tests) {
" console.log(test[0]);
" assert.equal(eval(test[1]), TestChanges(eval(test[2]), eval(test[3])));
" }
"
" Save it to test_code_action_corner_cases.js and invoke it using:
"
" $ npm install vscode-languageserver-{textdocument,types}
" $ node test_code_action_corner_cases.js <test_code_action_corner_cases.vader
Before:
Save &fixeol
set nofixeol
Save &fileformats
set fileformats=unix
" two files, one accessed through a buffer, the other using write/readfile only
let g:files = [tempname(), tempname()]
function! TestChanges(contents, changes, mode) abort
let l:file = g:files[a:mode is 'file' ? 0 : 1]
call writefile(split(a:contents, '\n', 1), l:file, 'bS')
if a:mode isnot 'file'
execute 'edit ' . l:file
endif
call ale#code_action#ApplyChanges(l:file, a:changes, a:mode isnot 'buffer')
if a:mode is 'buffer'
execute 'write ' . l:file
endif
return join(readfile(l:file, 'b'), "\n")
endfunction!
function! MkPos(line, offset) abort
return {'line': a:line, 'offset': a:offset}
endfunction!
function! MkInsert(pos, newText) abort
return {'start': a:pos, 'end': a:pos, 'newText': a:newText}
endfunction!
function! MkDelete(start, end) abort
return {'start': a:start, 'end': a:end, 'newText': ''}
endfunction!
After:
for g:file in g:files
if bufnr(g:file) != -1
execute ':bp! | :bd! ' . bufnr(g:file)
endif
if filereadable(g:file)
call delete(g:file)
endif
endfor
unlet! g:files g:file
unlet! g:mode
delfunction TestChanges
delfunction MkPos
delfunction MkInsert
delfunction MkDelete
Restore
Execute(Preserve (no)eol at eof):
for g:mode in ['save', 'file', 'buffer']
Log g:mode
AssertEqual "noeol", TestChanges("noeol", [], g:mode)
AssertEqual "eol\n", TestChanges("eol\n", [], g:mode)
AssertEqual "eols\n\n", TestChanges("eols\n\n", [], g:mode)
endfor
" there doesn't seem to be a way to tell if a buffer is empty or contains one
" empty line :-(
AssertEqual "", TestChanges("", [], 'file')
Execute(Respect fixeol):
set fixeol
for g:mode in ['save', 'file', 'buffer']
Log g:mode
silent echo "vscode skip" | AssertEqual "noeol\n", TestChanges("noeol", [], g:mode)
silent echo "vscode skip" | AssertEqual "eol\n", TestChanges("eol\n", [], g:mode)
endfor
Execute(Add/del eol at eof):
for g:mode in ['save', 'file', 'buffer']
Log g:mode
AssertEqual "addeol\n", TestChanges("addeol", [MkInsert(MkPos(1, 7), "\n")], g:mode)
AssertEqual "deleol", TestChanges("deleol\n", [MkDelete(MkPos(1, 7), MkPos(1, 8))], g:mode)
endfor
Execute(One character insertions to first line):
for g:mode in ['save', 'file', 'buffer']
Log g:mode
AssertEqual "xabc\ndef1\nghi\n", TestChanges("abc\ndef1\nghi\n", [MkInsert(MkPos(1, 0), "x")], g:mode)
AssertEqual "xabc\ndef2\nghi\n", TestChanges("abc\ndef2\nghi\n", [MkInsert(MkPos(1, 1), "x")], g:mode)
AssertEqual "axbc\ndef3\nghi\n", TestChanges("abc\ndef3\nghi\n", [MkInsert(MkPos(1, 2), "x")], g:mode)
AssertEqual "abcx\ndef4\nghi\n", TestChanges("abc\ndef4\nghi\n", [MkInsert(MkPos(1, 4), "x")], g:mode)
AssertEqual "abc\nxdef5\nghi\n", TestChanges("abc\ndef5\nghi\n", [MkInsert(MkPos(1, 5), "x")], g:mode)
AssertEqual "abc\nxdef6\nghi\n", TestChanges("abc\ndef6\nghi\n", [MkInsert(MkPos(1, 6), "x")], g:mode)
endfor
Execute(One character + newline insertions to first line):
for g:mode in ['save', 'file', 'buffer']
Log g:mode
AssertEqual "x\nabc\ndef1\nghi\n", TestChanges("abc\ndef1\nghi\n", [MkInsert(MkPos(1, 0), "x\n")], g:mode)
AssertEqual "x\nabc\ndef2\nghi\n", TestChanges("abc\ndef2\nghi\n", [MkInsert(MkPos(1, 1), "x\n")], g:mode)
AssertEqual "ax\nbc\ndef3\nghi\n", TestChanges("abc\ndef3\nghi\n", [MkInsert(MkPos(1, 2), "x\n")], g:mode)
AssertEqual "abcx\n\ndef4\nghi\n", TestChanges("abc\ndef4\nghi\n", [MkInsert(MkPos(1, 4), "x\n")], g:mode)
AssertEqual "abc\nx\ndef5\nghi\n", TestChanges("abc\ndef5\nghi\n", [MkInsert(MkPos(1, 5), "x\n")], g:mode)
AssertEqual "abc\nx\ndef6\nghi\n", TestChanges("abc\ndef6\nghi\n", [MkInsert(MkPos(1, 6), "x\n")], g:mode)
endfor
Execute(One character insertions near end):
for g:mode in ['save', 'file', 'buffer']
Log g:mode
AssertEqual "abc\ndef1\nghxi\n", TestChanges("abc\ndef1\nghi\n", [MkInsert(MkPos(3, 3), "x")], g:mode)
AssertEqual "abc\ndef2\nghix\n", TestChanges("abc\ndef2\nghi\n", [MkInsert(MkPos(3, 4), "x")], g:mode)
AssertEqual "abc\ndef3\nghi\nx", TestChanges("abc\ndef3\nghi\n", [MkInsert(MkPos(3, 5), "x")], g:mode)
AssertEqual "abc\ndef4\nghi\nx", TestChanges("abc\ndef4\nghi\n", [MkInsert(MkPos(3, 6), "x")], g:mode)
AssertEqual "abc\ndef5\nghi\nx", TestChanges("abc\ndef5\nghi\n", [MkInsert(MkPos(4, 1), "x")], g:mode)
AssertEqual "abc\ndef6\nghi\nx", TestChanges("abc\ndef6\nghi\n", [MkInsert(MkPos(4, 2), "x")], g:mode)
AssertEqual "abc\ndef7\nghi\nx", TestChanges("abc\ndef7\nghi\n", [MkInsert(MkPos(5, 1), "x")], g:mode)
AssertEqual "abc\ndef8\nghi\nx", TestChanges("abc\ndef8\nghi\n", [MkInsert(MkPos(5, 2), "x")], g:mode)
endfor
Execute(One character + newline insertions near end):
for g:mode in ['save', 'file', 'buffer']
Log g:mode
AssertEqual "abc\ndef1\nghx\ni\n", TestChanges("abc\ndef1\nghi\n", [MkInsert(MkPos(3, 3), "x\n")], g:mode)
AssertEqual "abc\ndef2\nghix\n\n", TestChanges("abc\ndef2\nghi\n", [MkInsert(MkPos(3, 4), "x\n")], g:mode)
AssertEqual "abc\ndef3\nghi\nx\n", TestChanges("abc\ndef3\nghi\n", [MkInsert(MkPos(3, 5), "x\n")], g:mode)
AssertEqual "abc\ndef4\nghi\nx\n", TestChanges("abc\ndef4\nghi\n", [MkInsert(MkPos(3, 6), "x\n")], g:mode)
AssertEqual "abc\ndef5\nghi\nx\n", TestChanges("abc\ndef5\nghi\n", [MkInsert(MkPos(4, 1), "x\n")], g:mode)
AssertEqual "abc\ndef6\nghi\nx\n", TestChanges("abc\ndef6\nghi\n", [MkInsert(MkPos(4, 2), "x\n")], g:mode)
endfor
Execute(Newline insertions near end):
for g:mode in ['save', 'file', 'buffer']
Log g:mode
AssertEqual "abc\ndef1\ngh\ni\n", TestChanges("abc\ndef1\nghi\n", [MkInsert(MkPos(3, 3), "\n")], g:mode)
AssertEqual "abc\ndef2\nghi\n\n", TestChanges("abc\ndef2\nghi\n", [MkInsert(MkPos(3, 4), "\n")], g:mode)
AssertEqual "abc\ndef3\nghi\n\n", TestChanges("abc\ndef3\nghi\n", [MkInsert(MkPos(3, 5), "\n")], g:mode)
AssertEqual "abc\ndef4\nghi\n\n", TestChanges("abc\ndef4\nghi\n", [MkInsert(MkPos(3, 6), "\n")], g:mode)
AssertEqual "abc\ndef5\nghi\n\n", TestChanges("abc\ndef5\nghi\n", [MkInsert(MkPos(4, 1), "\n")], g:mode)
endfor
Execute(Single char deletions):
for g:mode in ['save', 'file', 'buffer']
Log g:mode
AssertEqual "bc\ndef1\nghi\n", TestChanges("abc\ndef1\nghi\n", [MkDelete(MkPos(1, 1), MkPos(1, 2))], g:mode)
AssertEqual "ab\ndef2\nghi\n", TestChanges("abc\ndef2\nghi\n", [MkDelete(MkPos(1, 3), MkPos(1, 4))], g:mode)
AssertEqual "abcdef3\nghi\n", TestChanges("abc\ndef3\nghi\n", [MkDelete(MkPos(1, 4), MkPos(1, 5))], g:mode)
AssertEqual "abcdef4\nghi\n", TestChanges("abc\ndef4\nghi\n", [MkDelete(MkPos(1, 4), MkPos(1, 6))], g:mode)
AssertEqual "abc\ndef5\ngh\n", TestChanges("abc\ndef5\nghi\n", [MkDelete(MkPos(3, 3), MkPos(3, 4))], g:mode)
AssertEqual "abc\ndef6\nghi", TestChanges("abc\ndef6\nghi\n", [MkDelete(MkPos(3, 4), MkPos(3, 5))], g:mode)
AssertEqual "abc\ndef7\nghi", TestChanges("abc\ndef7\nghi\n", [MkDelete(MkPos(3, 4), MkPos(3, 6))], g:mode)
AssertEqual "abc\ndef8\nghi\n", TestChanges("abc\ndef8\nghi\n", [MkDelete(MkPos(4, 1), MkPos(4, 2))], g:mode)
endfor