mirror of
https://github.com/amix/vimrc
synced 2025-06-16 09:35:01 +08:00
Update Ale.
This commit is contained in:
176
sources_non_forked/ale/test/lsp/test_closing_documents.vader
Normal file
176
sources_non_forked/ale/test/lsp/test_closing_documents.vader
Normal file
@ -0,0 +1,176 @@
|
||||
Before:
|
||||
runtime autoload/ale/lsp.vim
|
||||
|
||||
let g:message_list = []
|
||||
|
||||
function! MarkAllConnectionsInitialized() abort
|
||||
for l:conn in values(ale#lsp#GetConnections())
|
||||
let l:conn.initialized = 1
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
function! MarkDocumentOpened() abort
|
||||
for l:conn in values(ale#lsp#GetConnections())
|
||||
let l:conn.open_documents[bufnr('')] = 1
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
function! ale#lsp#Send(conn_id, message) abort
|
||||
let l:connections = ale#lsp#GetConnections()
|
||||
|
||||
if !l:connections[a:conn_id].initialized
|
||||
throw 'LSP server not initialized yet!'
|
||||
endif
|
||||
|
||||
call add(g:message_list, [a:conn_id] + a:message)
|
||||
endfunction
|
||||
|
||||
call ale#lsp#ResetConnections()
|
||||
|
||||
After:
|
||||
unlet! g:message_list
|
||||
delfunction MarkAllConnectionsInitialized
|
||||
delfunction MarkDocumentOpened
|
||||
|
||||
call ale#lsp#ResetConnections()
|
||||
|
||||
runtime autoload/ale/lsp.vim
|
||||
|
||||
Execute(No errors should be thrown if the connection is not initialized):
|
||||
call ale#lsp#Register('command', '/foo', {})
|
||||
call MarkDocumentOpened()
|
||||
|
||||
call ale#engine#Cleanup(bufnr(''))
|
||||
AssertEqual [], g:message_list
|
||||
|
||||
Execute(No messages should be sent if the document wasn't opened):
|
||||
call ale#lsp#Register('command', '/foo', {})
|
||||
call MarkAllConnectionsInitialized()
|
||||
|
||||
call ale#engine#Cleanup(bufnr(''))
|
||||
AssertEqual [], g:message_list
|
||||
|
||||
Execute(A message should be sent if the document was opened):
|
||||
call ale#lsp#Register('command', '/foo', {})
|
||||
call MarkAllConnectionsInitialized()
|
||||
|
||||
call ale#lsp#OpenDocument('command:/foo', bufnr(''), 'lang')
|
||||
call ale#engine#Cleanup(bufnr(''))
|
||||
" We should only send the message once.
|
||||
call ale#engine#Cleanup(bufnr(''))
|
||||
|
||||
AssertEqual
|
||||
\ [
|
||||
\ ['command:/foo', 1, 'textDocument/didOpen', {
|
||||
\ 'textDocument': {
|
||||
\ 'uri': ale#path#ToFileURI(expand('%:p')),
|
||||
\ 'version': g:ale_lsp_next_version_id - 1,
|
||||
\ 'languageId': 'lang',
|
||||
\ 'text': "\n",
|
||||
\ },
|
||||
\ }],
|
||||
\ ['command:/foo', 1, 'textDocument/didClose', {
|
||||
\ 'textDocument': {
|
||||
\ 'uri': ale#path#ToFileURI(expand('%:p')),
|
||||
\ },
|
||||
\ }],
|
||||
\ ],
|
||||
\ g:message_list
|
||||
|
||||
Execute(A message should be sent if the document was opened for tsserver):
|
||||
call ale#lsp#Register('command', '/foo', {})
|
||||
call ale#lsp#MarkConnectionAsTsserver('command:/foo')
|
||||
|
||||
call ale#lsp#OpenDocument('command:/foo', bufnr(''), 'lang')
|
||||
call ale#engine#Cleanup(bufnr(''))
|
||||
" We should only send the message once.
|
||||
call ale#engine#Cleanup(bufnr(''))
|
||||
|
||||
AssertEqual
|
||||
\ [
|
||||
\ ['command:/foo', 1, 'ts@open', {'file': expand('%:p')}],
|
||||
\ ['command:/foo', 1, 'ts@close', {'file': expand('%:p')}],
|
||||
\ ],
|
||||
\ g:message_list
|
||||
|
||||
Execute(Re-opening and closing the documents should work):
|
||||
call ale#lsp#Register('command', '/foo', {})
|
||||
call MarkAllConnectionsInitialized()
|
||||
|
||||
call ale#lsp#OpenDocument('command:/foo', bufnr(''), 'lang')
|
||||
call ale#engine#Cleanup(bufnr(''))
|
||||
call ale#lsp#OpenDocument('command:/foo', bufnr(''), 'lang')
|
||||
call ale#engine#Cleanup(bufnr(''))
|
||||
|
||||
AssertEqual
|
||||
\ [
|
||||
\ ['command:/foo', 1, 'textDocument/didOpen', {
|
||||
\ 'textDocument': {
|
||||
\ 'uri': ale#path#ToFileURI(expand('%:p')),
|
||||
\ 'version': g:ale_lsp_next_version_id - 2,
|
||||
\ 'languageId': 'lang',
|
||||
\ 'text': "\n",
|
||||
\ },
|
||||
\ }],
|
||||
\ ['command:/foo', 1, 'textDocument/didClose', {
|
||||
\ 'textDocument': {
|
||||
\ 'uri': ale#path#ToFileURI(expand('%:p')),
|
||||
\ },
|
||||
\ }],
|
||||
\ ['command:/foo', 1, 'textDocument/didOpen', {
|
||||
\ 'textDocument': {
|
||||
\ 'uri': ale#path#ToFileURI(expand('%:p')),
|
||||
\ 'version': g:ale_lsp_next_version_id - 1,
|
||||
\ 'languageId': 'lang',
|
||||
\ 'text': "\n",
|
||||
\ },
|
||||
\ }],
|
||||
\ ['command:/foo', 1, 'textDocument/didClose', {
|
||||
\ 'textDocument': {
|
||||
\ 'uri': ale#path#ToFileURI(expand('%:p')),
|
||||
\ },
|
||||
\ }],
|
||||
\ ],
|
||||
\ g:message_list
|
||||
|
||||
Execute(Messages for closing documents should be sent to each server):
|
||||
call ale#lsp#Register('command', '/foo', {})
|
||||
call ale#lsp#Register('command', '/bar', {})
|
||||
call MarkAllConnectionsInitialized()
|
||||
|
||||
call ale#lsp#OpenDocument('command:/foo', bufnr(''), 'lang')
|
||||
call ale#lsp#OpenDocument('command:/bar', bufnr(''), 'lang')
|
||||
call ale#engine#Cleanup(bufnr(''))
|
||||
" We should only send the message once.
|
||||
call ale#engine#Cleanup(bufnr(''))
|
||||
|
||||
AssertEqual
|
||||
\ [
|
||||
\ ['command:/foo', 1, 'textDocument/didOpen', {
|
||||
\ 'textDocument': {
|
||||
\ 'uri': ale#path#ToFileURI(expand('%:p')),
|
||||
\ 'version': g:ale_lsp_next_version_id - 2,
|
||||
\ 'languageId': 'lang',
|
||||
\ 'text': "\n",
|
||||
\ },
|
||||
\ }],
|
||||
\ ['command:/bar', 1, 'textDocument/didOpen', {
|
||||
\ 'textDocument': {
|
||||
\ 'uri': ale#path#ToFileURI(expand('%:p')),
|
||||
\ 'version': g:ale_lsp_next_version_id - 1,
|
||||
\ 'languageId': 'lang',
|
||||
\ 'text': "\n",
|
||||
\ },
|
||||
\ }],
|
||||
\ ['command:/bar', 1, 'textDocument/didClose', {
|
||||
\ 'textDocument': {
|
||||
\ 'uri': ale#path#ToFileURI(expand('%:p')),
|
||||
\ },
|
||||
\ }],
|
||||
\ ['command:/foo', 1, 'textDocument/didClose', {
|
||||
\ 'textDocument': {
|
||||
\ 'uri': ale#path#ToFileURI(expand('%:p')),
|
||||
\ },
|
||||
\ }],
|
||||
\ ],
|
||||
\ g:message_list
|
147
sources_non_forked/ale/test/lsp/test_did_save_event.vader
Normal file
147
sources_non_forked/ale/test/lsp/test_did_save_event.vader
Normal file
@ -0,0 +1,147 @@
|
||||
Before:
|
||||
Save g:ale_lint_on_save
|
||||
Save g:ale_enabled
|
||||
Save g:ale_linters
|
||||
Save g:ale_run_synchronously
|
||||
Save g:ale_disable_lsp
|
||||
|
||||
call ale#test#SetDirectory('/testplugin/test/completion')
|
||||
call ale#test#SetFilename('dummy.txt')
|
||||
|
||||
runtime autoload/ale/lsp.vim
|
||||
runtime autoload/ale/lsp_linter.vim
|
||||
|
||||
let g:ale_disable_lsp = 0
|
||||
unlet! b:ale_disable_lsp
|
||||
let g:ale_lint_on_save = 1
|
||||
let b:ale_enabled = 1
|
||||
let g:ale_lsp_next_message_id = 1
|
||||
let g:ale_run_synchronously = 1
|
||||
let g:conn_id = v:null
|
||||
let g:message_list = []
|
||||
|
||||
function! LanguageCallback() abort
|
||||
return 'foobar'
|
||||
endfunction
|
||||
|
||||
function! ProjectRootCallback() abort
|
||||
return expand('.')
|
||||
endfunction
|
||||
|
||||
call ale#linter#Define('foobar', {
|
||||
\ 'name': 'dummy_linter',
|
||||
\ 'lsp': 'stdio',
|
||||
\ 'command': 'cat - > /dev/null',
|
||||
\ 'executable': has('win32') ? 'cmd' : 'echo',
|
||||
\ 'language': function('LanguageCallback'),
|
||||
\ 'project_root': function('ProjectRootCallback'),
|
||||
\ })
|
||||
let g:ale_linters = {'foobar': ['dummy_linter']}
|
||||
|
||||
function! ale#lsp_linter#StartLSP(buffer, linter, Callback) abort
|
||||
let g:conn_id = ale#lsp#Register('executable', '/foo/bar', {})
|
||||
call ale#lsp#MarkDocumentAsOpen(g:conn_id, a:buffer)
|
||||
let l:details = {
|
||||
\ 'command': 'foobar',
|
||||
\ 'buffer': a:buffer,
|
||||
\ 'connection_id': g:conn_id,
|
||||
\ 'project_root': '/foo/bar',
|
||||
\}
|
||||
|
||||
call a:Callback(a:linter, l:details)
|
||||
|
||||
return 1
|
||||
endfunction
|
||||
|
||||
" Replace the Send function for LSP, so we can monitor calls to it.
|
||||
function! ale#lsp#Send(conn_id, message) abort
|
||||
call add(g:message_list, a:message)
|
||||
endfunction
|
||||
|
||||
After:
|
||||
Restore
|
||||
|
||||
if g:conn_id isnot v:null
|
||||
call ale#lsp#RemoveConnectionWithID(g:conn_id)
|
||||
endif
|
||||
|
||||
unlet! b:ale_enabled
|
||||
unlet! b:ale_linters
|
||||
unlet! g:message_list
|
||||
unlet! b:ale_save_event_fired
|
||||
|
||||
delfunction LanguageCallback
|
||||
delfunction ProjectRootCallback
|
||||
|
||||
call ale#test#RestoreDirectory()
|
||||
call ale#linter#Reset()
|
||||
|
||||
" 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
|
||||
runtime autoload/ale/lsp_linter.vim
|
||||
|
||||
Given foobar (Some imaginary filetype):
|
||||
<contents>
|
||||
|
||||
Execute(Server should be notified on save):
|
||||
call ale#events#SaveEvent(bufnr(''))
|
||||
|
||||
AssertEqual
|
||||
\ [
|
||||
\ [1, 'textDocument/didChange', {
|
||||
\ 'textDocument': {
|
||||
\ 'uri': ale#path#ToFileURI(expand('%:p')),
|
||||
\ 'version': g:ale_lsp_next_version_id - 1,
|
||||
\ },
|
||||
\ 'contentChanges': [{'text': join(getline(1, '$'), "\n") . "\n"}],
|
||||
\ }],
|
||||
\ ],
|
||||
\ g:message_list
|
||||
|
||||
Execute(Server should be notified on save with didSave is supported by server):
|
||||
|
||||
" Replace has capability function to simulate didSave server capability
|
||||
function! ale#lsp#HasCapability(conn_id, capability) abort
|
||||
if a:capability == 'did_save'
|
||||
return 1
|
||||
endif
|
||||
return 0
|
||||
endfunction
|
||||
|
||||
call ale#events#SaveEvent(bufnr(''))
|
||||
|
||||
AssertEqual
|
||||
\ [
|
||||
\ [1, 'textDocument/didChange', {
|
||||
\ 'textDocument': {
|
||||
\ 'uri': ale#path#ToFileURI(expand('%:p')),
|
||||
\ 'version': g:ale_lsp_next_version_id - 1,
|
||||
\ },
|
||||
\ 'contentChanges': [{'text': join(getline(1, '$'), "\n") . "\n"}],
|
||||
\ }],
|
||||
\ [1, 'textDocument/didSave', {
|
||||
\ 'textDocument': {
|
||||
\ 'uri': ale#path#ToFileURI(expand('%:p')),
|
||||
\ },
|
||||
\ }],
|
||||
\ ],
|
||||
\ g:message_list
|
||||
|
||||
Execute(Server should be notified on change):
|
||||
call ale#events#FileChangedEvent(bufnr(''))
|
||||
|
||||
AssertEqual
|
||||
\ [
|
||||
\ [1, 'textDocument/didChange', {
|
||||
\ 'textDocument': {
|
||||
\ 'uri': ale#path#ToFileURI(expand('%:p')),
|
||||
\ 'version': g:ale_lsp_next_version_id - 1,
|
||||
\ },
|
||||
\ 'contentChanges': [{'text': join(getline(1, '$'), "\n") . "\n"}],
|
||||
\ }],
|
||||
\ ],
|
||||
\ g:message_list
|
@ -0,0 +1,428 @@
|
||||
Before:
|
||||
Save g:ale_set_lists_synchronously
|
||||
Save g:ale_buffer_info
|
||||
Save g:ale_lsp_error_messages
|
||||
Save g:ale_set_loclist
|
||||
Save g:ale_set_signs
|
||||
Save g:ale_set_quickfix
|
||||
Save g:ale_set_highlights
|
||||
Save g:ale_echo_cursor
|
||||
Save g:ale_disable_lsp
|
||||
Save g:ale_history_enabled
|
||||
Save g:ale_history_log_output
|
||||
|
||||
let g:ale_disable_lsp = 0
|
||||
let g:ale_set_lists_synchronously = 1
|
||||
let g:ale_buffer_info = {}
|
||||
let g:ale_set_loclist = 1
|
||||
" Disable features we don't need for these tests.
|
||||
let g:ale_set_signs = 0
|
||||
let g:ale_set_quickfix = 0
|
||||
let g:ale_set_highlights = 0
|
||||
let g:ale_echo_cursor = 0
|
||||
let g:ale_history_enabled = 1
|
||||
let g:ale_history_log_output = 1
|
||||
|
||||
unlet! g:ale_lsp_error_messages
|
||||
unlet! b:ale_linters
|
||||
unlet! b:ale_disable_lsp
|
||||
|
||||
call ale#linter#Reset()
|
||||
call ale#test#SetDirectory('/testplugin/test')
|
||||
call setloclist(0, [])
|
||||
|
||||
After:
|
||||
Restore
|
||||
|
||||
unlet! b:ale_linters
|
||||
|
||||
call setloclist(0, [])
|
||||
call ale#test#RestoreDirectory()
|
||||
call ale#linter#Reset()
|
||||
call ale#lsp_linter#ClearLSPData()
|
||||
|
||||
Given foobar(An empty file):
|
||||
Execute(tsserver syntax error responses should be handled correctly):
|
||||
runtime ale_linters/typescript/tsserver.vim
|
||||
|
||||
if has('win32')
|
||||
call ale#test#SetFilename('filename,[]^$.ts')
|
||||
else
|
||||
call ale#test#SetFilename('filename*?,{}[]^$.ts')
|
||||
endif
|
||||
|
||||
call ale#engine#InitBufferInfo(bufnr(''))
|
||||
|
||||
if has('win32')
|
||||
AssertEqual 'filename,[]^$.ts', expand('%:p:t')
|
||||
else
|
||||
AssertEqual 'filename*?,{}[]^$.ts', expand('%:p:t')
|
||||
endif
|
||||
|
||||
" When we get syntax errors and no semantic errors, we should keep the
|
||||
" syntax errors.
|
||||
call ale#lsp_linter#HandleLSPResponse(1, {
|
||||
\ 'seq': 0,
|
||||
\ 'type': 'event',
|
||||
\ 'event': 'syntaxDiag',
|
||||
\ 'body': {
|
||||
\ 'file': expand('%:p'),
|
||||
\ 'diagnostics':[
|
||||
\ {
|
||||
\ 'start': {
|
||||
\ 'line':2,
|
||||
\ 'offset':14,
|
||||
\ },
|
||||
\ 'end': {
|
||||
\ 'line':2,
|
||||
\ 'offset':15,
|
||||
\ },
|
||||
\ 'text': ''','' expected.',
|
||||
\ "code":1005
|
||||
\ },
|
||||
\ ],
|
||||
\ },
|
||||
\})
|
||||
call ale#lsp_linter#HandleLSPResponse(1, {
|
||||
\ 'seq': 0,
|
||||
\ 'type': 'event',
|
||||
\ 'event': 'semanticDiag',
|
||||
\ 'body': {
|
||||
\ 'file': expand('%:p'),
|
||||
\ 'diagnostics':[
|
||||
\ ],
|
||||
\ },
|
||||
\})
|
||||
|
||||
AssertEqual
|
||||
\ [
|
||||
\ {
|
||||
\ 'lnum': 1,
|
||||
\ 'bufnr': bufnr(''),
|
||||
\ 'col': 14,
|
||||
\ 'vcol': 0,
|
||||
\ 'nr': 1005,
|
||||
\ 'type': 'E',
|
||||
\ 'text': '1005: '','' expected.',
|
||||
\ 'valid': 1,
|
||||
\ 'pattern': '',
|
||||
\ },
|
||||
\ ],
|
||||
\ ale#test#GetLoclistWithoutNewerKeys()
|
||||
|
||||
" After we get empty syntax errors, we should clear them.
|
||||
call ale#lsp_linter#HandleLSPResponse(1, {
|
||||
\ 'seq': 0,
|
||||
\ 'type': 'event',
|
||||
\ 'event': 'syntaxDiag',
|
||||
\ 'body': {
|
||||
\ 'file': expand('%:p'),
|
||||
\ 'diagnostics':[
|
||||
\ ],
|
||||
\ },
|
||||
\})
|
||||
|
||||
AssertEqual
|
||||
\ [
|
||||
\ ],
|
||||
\ ale#test#GetLoclistWithoutNewerKeys()
|
||||
|
||||
" Syntax errors on the project root should not populate the LocList.
|
||||
call ale#lsp_linter#HandleLSPResponse(1, {
|
||||
\ 'seq': 0,
|
||||
\ 'type': 'event',
|
||||
\ 'event': 'syntaxDiag',
|
||||
\ 'body': {
|
||||
\ 'file': g:dir,
|
||||
\ 'diagnostics':[
|
||||
\ {
|
||||
\ 'start': {
|
||||
\ 'line':2,
|
||||
\ 'offset':14,
|
||||
\ },
|
||||
\ 'end': {
|
||||
\ 'line':2,
|
||||
\ 'offset':15,
|
||||
\ },
|
||||
\ 'text': ''','' expected.',
|
||||
\ "code":1005
|
||||
\ },
|
||||
\ ],
|
||||
\ },
|
||||
\})
|
||||
|
||||
AssertEqual
|
||||
\ [
|
||||
\ ],
|
||||
\ ale#test#GetLoclistWithoutNewerKeys()
|
||||
|
||||
Execute(tsserver semantic error responses should be handled correctly):
|
||||
runtime ale_linters/typescript/tsserver.vim
|
||||
|
||||
if has('win32')
|
||||
call ale#test#SetFilename('filename,[]^$.ts')
|
||||
else
|
||||
call ale#test#SetFilename('filename*?,{}[]^$.ts')
|
||||
endif
|
||||
|
||||
call ale#engine#InitBufferInfo(bufnr(''))
|
||||
|
||||
if has('win32')
|
||||
AssertEqual 'filename,[]^$.ts', expand('%:p:t')
|
||||
else
|
||||
AssertEqual 'filename*?,{}[]^$.ts', expand('%:p:t')
|
||||
endif
|
||||
|
||||
" When we get syntax errors and no semantic errors, we should keep the
|
||||
" syntax errors.
|
||||
call ale#lsp_linter#HandleLSPResponse(1, {
|
||||
\ 'seq': 0,
|
||||
\ 'type': 'event',
|
||||
\ 'event': 'syntaxDiag',
|
||||
\ 'body': {
|
||||
\ 'file': expand('%:p'),
|
||||
\ 'diagnostics':[
|
||||
\ ],
|
||||
\ },
|
||||
\})
|
||||
call ale#lsp_linter#HandleLSPResponse(1, {
|
||||
\ 'seq': 0,
|
||||
\ 'type': 'event',
|
||||
\ 'event': 'semanticDiag',
|
||||
\ 'body': {
|
||||
\ 'file': expand('%:p'),
|
||||
\ 'diagnostics':[
|
||||
\ {
|
||||
\ 'start': {
|
||||
\ 'line':2,
|
||||
\ 'offset':14,
|
||||
\ },
|
||||
\ 'end': {
|
||||
\ 'line':2,
|
||||
\ 'offset':15,
|
||||
\ },
|
||||
\ 'text': 'Some semantic error',
|
||||
\ "code":1005
|
||||
\ },
|
||||
\ ],
|
||||
\ },
|
||||
\})
|
||||
|
||||
AssertEqual
|
||||
\ [
|
||||
\ {
|
||||
\ 'lnum': 1,
|
||||
\ 'bufnr': bufnr(''),
|
||||
\ 'col': 14,
|
||||
\ 'vcol': 0,
|
||||
\ 'nr': 1005,
|
||||
\ 'type': 'E',
|
||||
\ 'text': '1005: Some semantic error',
|
||||
\ 'valid': 1,
|
||||
\ 'pattern': '',
|
||||
\ },
|
||||
\ ],
|
||||
\ ale#test#GetLoclistWithoutNewerKeys()
|
||||
|
||||
" After we get empty syntax errors, we should clear them.
|
||||
call ale#lsp_linter#HandleLSPResponse(1, {
|
||||
\ 'seq': 0,
|
||||
\ 'type': 'event',
|
||||
\ 'event': 'semanticDiag',
|
||||
\ 'body': {
|
||||
\ 'file': expand('%:p'),
|
||||
\ 'diagnostics':[
|
||||
\ ],
|
||||
\ },
|
||||
\})
|
||||
|
||||
AssertEqual
|
||||
\ [
|
||||
\ ],
|
||||
\ ale#test#GetLoclistWithoutNewerKeys()
|
||||
|
||||
" Semantic errors on the project root should not populate the LocList.
|
||||
call ale#lsp_linter#HandleLSPResponse(1, {
|
||||
\ 'seq': 0,
|
||||
\ 'type': 'event',
|
||||
\ 'event': 'semanticDiag',
|
||||
\ 'body': {
|
||||
\ 'file': g:dir,
|
||||
\ 'diagnostics':[
|
||||
\ {
|
||||
\ 'start': {
|
||||
\ 'line':2,
|
||||
\ 'offset':14,
|
||||
\ },
|
||||
\ 'end': {
|
||||
\ 'line':2,
|
||||
\ 'offset':15,
|
||||
\ },
|
||||
\ 'text': 'Some semantic error',
|
||||
\ "code":1005
|
||||
\ },
|
||||
\ ],
|
||||
\ },
|
||||
\})
|
||||
|
||||
AssertEqual
|
||||
\ [
|
||||
\ ],
|
||||
\ ale#test#GetLoclistWithoutNewerKeys()
|
||||
|
||||
Execute(tsserver errors should mark tsserver no longer active):
|
||||
let b:ale_linters = ['tsserver']
|
||||
runtime ale_linters/typescript/tsserver.vim
|
||||
call ale#test#SetFilename('filename.ts')
|
||||
call ale#engine#InitBufferInfo(bufnr(''))
|
||||
|
||||
let g:ale_buffer_info[bufnr('')].active_linter_list = ale#linter#Get('typescript')
|
||||
Assert !empty(g:ale_buffer_info[bufnr('')].active_linter_list)
|
||||
|
||||
call ale#lsp_linter#HandleLSPResponse(1, {
|
||||
\ 'seq': 0,
|
||||
\ 'type': 'event',
|
||||
\ 'event': 'semanticDiag',
|
||||
\ 'body': {
|
||||
\ 'file': g:dir . '/filename.ts',
|
||||
\ 'diagnostics':[],
|
||||
\ },
|
||||
\})
|
||||
|
||||
AssertEqual [], g:ale_buffer_info[bufnr('')].active_linter_list
|
||||
|
||||
Execute(LSP diagnostics responses should be handled correctly):
|
||||
let b:ale_linters = ['eclipselsp']
|
||||
runtime ale_linters/java/eclipselsp.vim
|
||||
|
||||
if has('win32')
|
||||
call ale#test#SetFilename('filename,[]^$.ts')
|
||||
else
|
||||
call ale#test#SetFilename('filename*?,{}[]^$.java')
|
||||
endif
|
||||
|
||||
call ale#engine#InitBufferInfo(bufnr(''))
|
||||
call ale#lsp_linter#SetLSPLinterMap({'1': 'eclipselsp'})
|
||||
|
||||
if has('win32')
|
||||
AssertEqual 'filename,[]^$.ts', expand('%:p:t')
|
||||
else
|
||||
AssertEqual 'filename*?,{}[]^$.java', expand('%:p:t')
|
||||
endif
|
||||
|
||||
call ale#lsp_linter#HandleLSPResponse(1, {
|
||||
\ 'jsonrpc':'2.0',
|
||||
\ 'method':'textDocument/publishDiagnostics',
|
||||
\ 'params': {
|
||||
\ 'uri': ale#path#ToFileURI(expand('%:p')),
|
||||
\ 'diagnostics': [
|
||||
\ {
|
||||
\ 'range': {
|
||||
\ 'start': {
|
||||
\ 'line': 0,
|
||||
\ 'character':0
|
||||
\ },
|
||||
\ 'end': {
|
||||
\ 'line': 0,
|
||||
\ 'character':0
|
||||
\ }
|
||||
\ },
|
||||
\ 'severity': 2,
|
||||
\ 'code': "",
|
||||
\ 'source': 'Java',
|
||||
\ 'message': 'Missing JRE 1-8'
|
||||
\ }
|
||||
\ ]
|
||||
\ }
|
||||
\})
|
||||
|
||||
AssertEqual
|
||||
\ [
|
||||
\ {
|
||||
\ 'lnum': 1,
|
||||
\ 'bufnr': bufnr(''),
|
||||
\ 'col': 1,
|
||||
\ 'pattern': '',
|
||||
\ 'valid': 1,
|
||||
\ 'vcol': 0,
|
||||
\ 'nr': -1,
|
||||
\ 'type': 'W',
|
||||
\ 'text': 'Missing JRE 1-8'
|
||||
\ }
|
||||
\ ],
|
||||
\ ale#test#GetLoclistWithoutNewerKeys()
|
||||
|
||||
Execute(LSP diagnostics responses on project root should not populate loclist):
|
||||
let b:ale_linters = ['eclipselsp']
|
||||
runtime ale_linters/java/eclipselsp.vim
|
||||
call ale#test#SetFilename('filename.java')
|
||||
call ale#engine#InitBufferInfo(bufnr(''))
|
||||
call ale#lsp_linter#SetLSPLinterMap({'1': 'eclipselsp'})
|
||||
|
||||
call ale#lsp_linter#HandleLSPResponse(1, {
|
||||
\ 'jsonrpc':'2.0',
|
||||
\ 'method':'textDocument/publishDiagnostics',
|
||||
\ 'params': {
|
||||
\ 'uri':'file://' . g:dir,
|
||||
\ 'diagnostics': [
|
||||
\ {
|
||||
\ 'range': {
|
||||
\ 'start': {
|
||||
\ 'line': 0,
|
||||
\ 'character':0
|
||||
\ },
|
||||
\ 'end': {
|
||||
\ 'line': 0,
|
||||
\ 'character':0
|
||||
\ }
|
||||
\ },
|
||||
\ 'severity': 2,
|
||||
\ 'code': "",
|
||||
\ 'source': 'Java',
|
||||
\ 'message': 'Missing JRE 1-8'
|
||||
\ }
|
||||
\ ]
|
||||
\ }
|
||||
\})
|
||||
|
||||
AssertEqual
|
||||
\ [
|
||||
\ ],
|
||||
\ ale#test#GetLoclistWithoutNewerKeys()
|
||||
|
||||
Execute(LSP errors should mark linters no longer active):
|
||||
let b:ale_linters = ['pylsp']
|
||||
runtime ale_linters/python/pylsp.vim
|
||||
call ale#test#SetFilename('filename.py')
|
||||
call ale#engine#InitBufferInfo(bufnr(''))
|
||||
call ale#lsp_linter#SetLSPLinterMap({1: 'pylsp'})
|
||||
|
||||
let g:ale_buffer_info[bufnr('')].active_linter_list = ale#linter#Get('python')
|
||||
Assert !empty(g:ale_buffer_info[bufnr('')].active_linter_list)
|
||||
|
||||
call ale#lsp_linter#HandleLSPResponse(1, {
|
||||
\ 'method': 'textDocument/publishDiagnostics',
|
||||
\ 'params': {
|
||||
\ 'uri': ale#path#ToFileURI(g:dir . '/filename.py'),
|
||||
\ 'diagnostics': [],
|
||||
\ },
|
||||
\})
|
||||
|
||||
AssertEqual [], g:ale_buffer_info[bufnr('')].active_linter_list
|
||||
|
||||
Execute(LSP errors should be logged in the history):
|
||||
call ale#lsp_linter#SetLSPLinterMap({'347': 'foobar'})
|
||||
call ale#lsp_linter#HandleLSPResponse(347, {
|
||||
\ 'jsonrpc': '2.0',
|
||||
\ 'error': {
|
||||
\ 'code': -32602,
|
||||
\ 'message': 'xyz',
|
||||
\ 'data': {
|
||||
\ 'traceback': ['123', '456'],
|
||||
\ },
|
||||
\ },
|
||||
\})
|
||||
|
||||
AssertEqual
|
||||
\ {'foobar': ["xyz\n123\n456"]},
|
||||
\ get(g:, 'ale_lsp_error_messages', {})
|
@ -0,0 +1,94 @@
|
||||
Before:
|
||||
let g:expr_list = []
|
||||
let g:linter_name = 'some_linter'
|
||||
let g:format = '%severity%:%linter%: %s'
|
||||
" Get the default value to restore it
|
||||
let g:default_severity = g:ale_lsp_show_message_severity
|
||||
let g:ale_lsp_show_message_severity = 'information'
|
||||
|
||||
function! ale#util#ShowMessage(expr) abort
|
||||
call add(g:expr_list, a:expr)
|
||||
endfunction
|
||||
|
||||
After:
|
||||
unlet! g:expr_list
|
||||
unlet! g:linter_name
|
||||
unlet! g:format
|
||||
let g:ale_lsp_show_message_severity = g:default_severity
|
||||
unlet! g:default_severity
|
||||
|
||||
Execute(ale#lsp_window#HandleShowMessage() should only show errors when severity is set to "error"):
|
||||
let g:ale_lsp_show_message_severity = 'error'
|
||||
call ale#lsp_window#HandleShowMessage(g:linter_name, g:format, {'type':1,'message':'an error'})
|
||||
call ale#lsp_window#HandleShowMessage(g:linter_name, g:format, {'type':2,'message':'a warning'})
|
||||
call ale#lsp_window#HandleShowMessage(g:linter_name, g:format, {'type':3,'message':'an info'})
|
||||
call ale#lsp_window#HandleShowMessage(g:linter_name, g:format, {'type':4,'message':'a log'})
|
||||
AssertEqual ['Error:some_linter: an error'], g:expr_list
|
||||
|
||||
Execute(ale#lsp_window#HandleShowMessage() should only show errors and warnings when severity is set to "warning"):
|
||||
let g:ale_lsp_show_message_severity = 'warning'
|
||||
call ale#lsp_window#HandleShowMessage(g:linter_name, g:format, {'type':1,'message':'an error'})
|
||||
call ale#lsp_window#HandleShowMessage(g:linter_name, g:format, {'type':2,'message':'a warning'})
|
||||
call ale#lsp_window#HandleShowMessage(g:linter_name, g:format, {'type':3,'message':'an info'})
|
||||
call ale#lsp_window#HandleShowMessage(g:linter_name, g:format, {'type':4,'message':'a log'})
|
||||
AssertEqual ['Error:some_linter: an error', 'Warning:some_linter: a warning'], g:expr_list
|
||||
|
||||
Execute(ale#lsp_window#HandleShowMessage() should only show errors, warnings and infos when severity is set to "information"):
|
||||
let g:ale_lsp_show_message_severity = 'information'
|
||||
call ale#lsp_window#HandleShowMessage(g:linter_name, g:format, {'type':1,'message':'an error'})
|
||||
call ale#lsp_window#HandleShowMessage(g:linter_name, g:format, {'type':2,'message':'a warning'})
|
||||
call ale#lsp_window#HandleShowMessage(g:linter_name, g:format, {'type':3,'message':'an info'})
|
||||
call ale#lsp_window#HandleShowMessage(g:linter_name, g:format, {'type':4,'message':'a log'})
|
||||
AssertEqual [
|
||||
\ 'Error:some_linter: an error',
|
||||
\ 'Warning:some_linter: a warning',
|
||||
\ 'Info:some_linter: an info'],
|
||||
\ g:expr_list
|
||||
|
||||
Execute(ale#lsp_window#HandleShowMessage() should only show errors, warnings and infos when severity is set to "info"):
|
||||
let g:ale_lsp_show_message_severity = 'info'
|
||||
call ale#lsp_window#HandleShowMessage(g:linter_name, g:format, {'type':1,'message':'an error'})
|
||||
call ale#lsp_window#HandleShowMessage(g:linter_name, g:format, {'type':2,'message':'a warning'})
|
||||
call ale#lsp_window#HandleShowMessage(g:linter_name, g:format, {'type':3,'message':'an info'})
|
||||
call ale#lsp_window#HandleShowMessage(g:linter_name, g:format, {'type':4,'message':'a log'})
|
||||
AssertEqual [
|
||||
\ 'Error:some_linter: an error',
|
||||
\ 'Warning:some_linter: a warning',
|
||||
\ 'Info:some_linter: an info'],
|
||||
\ g:expr_list
|
||||
|
||||
Execute(ale#lsp_window#HandleShowMessage() should show all messages is severity is set to "log"):
|
||||
let g:ale_lsp_show_message_severity = 'log'
|
||||
call ale#lsp_window#HandleShowMessage(g:linter_name, g:format, {'type':1,'message':'an error'})
|
||||
call ale#lsp_window#HandleShowMessage(g:linter_name, g:format, {'type':2,'message':'a warning'})
|
||||
call ale#lsp_window#HandleShowMessage(g:linter_name, g:format, {'type':3,'message':'an info'})
|
||||
call ale#lsp_window#HandleShowMessage(g:linter_name, g:format, {'type':4,'message':'a log'})
|
||||
AssertEqual [
|
||||
\ 'Error:some_linter: an error',
|
||||
\ 'Warning:some_linter: a warning',
|
||||
\ 'Info:some_linter: an info',
|
||||
\ 'Log:some_linter: a log'],
|
||||
\ g:expr_list
|
||||
|
||||
Execute(ale#lsp_window#HandleShowMessage() should not show anything if severity is configured as disabled):
|
||||
let g:ale_lsp_show_message_severity = 'disabled'
|
||||
call ale#lsp_window#HandleShowMessage(g:linter_name, g:format, {'type':1,'message':'an error'})
|
||||
call ale#lsp_window#HandleShowMessage(g:linter_name, g:format, {'type':2,'message':'a warning'})
|
||||
call ale#lsp_window#HandleShowMessage(g:linter_name, g:format, {'type':3,'message':'an info'})
|
||||
call ale#lsp_window#HandleShowMessage(g:linter_name, g:format, {'type':4,'message':'a log'})
|
||||
AssertEqual [], g:expr_list
|
||||
|
||||
Execute(ale#lsp_window#HandleShowMessage() should use "warning" when severity is set to an invalid value):
|
||||
let g:ale_lsp_show_message_severity = 'foo'
|
||||
call ale#lsp_window#HandleShowMessage(g:linter_name, g:format, {'type':1,'message':'an error'})
|
||||
call ale#lsp_window#HandleShowMessage(g:linter_name, g:format, {'type':2,'message':'a warning'})
|
||||
call ale#lsp_window#HandleShowMessage(g:linter_name, g:format, {'type':3,'message':'an info'})
|
||||
call ale#lsp_window#HandleShowMessage(g:linter_name, g:format, {'type':4,'message':'a log'})
|
||||
AssertEqual [
|
||||
\ 'Error:some_linter: an error',
|
||||
\ 'Warning:some_linter: a warning'],
|
||||
\ g:expr_list
|
||||
|
||||
Execute(ale#lsp_window#HandleShowMessage() should escape quotes on messages):
|
||||
call ale#lsp_window#HandleShowMessage(g:linter_name, g:format, {'type':3,'message':"this is an 'info'"})
|
||||
AssertEqual ['Info:some_linter: this is an ''info'''], g:expr_list
|
389
sources_non_forked/ale/test/lsp/test_lsp_client_messages.vader
Normal file
389
sources_non_forked/ale/test/lsp/test_lsp_client_messages.vader
Normal file
@ -0,0 +1,389 @@
|
||||
Before:
|
||||
let g:ale_lsp_next_version_id = 1
|
||||
|
||||
call ale#test#SetDirectory('/testplugin/test/lsp')
|
||||
call ale#test#SetFilename('foo/bar.ts')
|
||||
|
||||
After:
|
||||
call ale#test#RestoreDirectory()
|
||||
|
||||
Execute(ale#lsp#message#Initialize() should return correct messages):
|
||||
AssertEqual
|
||||
\ [
|
||||
\ 0,
|
||||
\ 'initialize',
|
||||
\ {
|
||||
\ 'processId': getpid(),
|
||||
\ 'rootPath': '/foo/bar',
|
||||
\ 'capabilities': {},
|
||||
\ 'initializationOptions': {'foo': 'bar'},
|
||||
\ 'rootUri': 'file:///foo/bar',
|
||||
\ }
|
||||
\ ],
|
||||
\ ale#lsp#message#Initialize('/foo/bar', {'foo': 'bar'}, {})
|
||||
|
||||
Execute(ale#lsp#message#Initialized() should return correct messages):
|
||||
AssertEqual [1, 'initialized', {}], ale#lsp#message#Initialized()
|
||||
|
||||
Execute(ale#lsp#message#Shutdown() should return correct messages):
|
||||
AssertEqual [0, 'shutdown'], ale#lsp#message#Shutdown()
|
||||
|
||||
Execute(ale#lsp#message#Exit() should return correct messages):
|
||||
AssertEqual [1, 'exit'], ale#lsp#message#Exit(),
|
||||
|
||||
Given typescript(A TypeScript file with 3 lines):
|
||||
foo()
|
||||
bar()
|
||||
baz()
|
||||
|
||||
Execute(ale#lsp#message#DidOpen() should return correct messages):
|
||||
let g:ale_lsp_next_version_id = 12
|
||||
AssertEqual
|
||||
\ [
|
||||
\ 1,
|
||||
\ 'textDocument/didOpen',
|
||||
\ {
|
||||
\ 'textDocument': {
|
||||
\ 'uri': ale#path#ToFileURI(g:dir . '/foo/bar.ts'),
|
||||
\ 'languageId': 'typescript',
|
||||
\ 'version': 12,
|
||||
\ 'text': "foo()\nbar()\nbaz()\n",
|
||||
\ },
|
||||
\ }
|
||||
\ ],
|
||||
\ ale#lsp#message#DidOpen(bufnr(''), 'typescript')
|
||||
|
||||
Execute(ale#lsp#message#DidChange() should return correct messages):
|
||||
let g:ale_lsp_next_version_id = 34
|
||||
|
||||
AssertEqual
|
||||
\ [
|
||||
\ 1,
|
||||
\ 'textDocument/didChange',
|
||||
\ {
|
||||
\ 'textDocument': {
|
||||
\ 'uri': ale#path#ToFileURI(g:dir . '/foo/bar.ts'),
|
||||
\ 'version': 34,
|
||||
\ },
|
||||
\ 'contentChanges': [{'text': "foo()\nbar()\nbaz()\n"}],
|
||||
\ }
|
||||
\ ],
|
||||
\ ale#lsp#message#DidChange(bufnr(''))
|
||||
" The version numbers should increment.
|
||||
AssertEqual
|
||||
\ 35,
|
||||
\ ale#lsp#message#DidChange(bufnr(''))[2].textDocument.version
|
||||
AssertEqual
|
||||
\ 36,
|
||||
\ ale#lsp#message#DidChange(bufnr(''))[2].textDocument.version
|
||||
|
||||
Execute(ale#lsp#message#DidSave() should return correct messages):
|
||||
AssertEqual
|
||||
\ [
|
||||
\ 1,
|
||||
\ 'textDocument/didSave',
|
||||
\ {
|
||||
\ 'textDocument': {
|
||||
\ 'uri': ale#path#ToFileURI(g:dir . '/foo/bar.ts'),
|
||||
\ },
|
||||
\ }
|
||||
\ ],
|
||||
\ ale#lsp#message#DidSave(bufnr(''), v:false)
|
||||
|
||||
Execute(ale#lsp#message#DidSave() should return correct message with includeText capability):
|
||||
AssertEqual
|
||||
\ [
|
||||
\ 1,
|
||||
\ 'textDocument/didSave',
|
||||
\ {
|
||||
\ 'textDocument': {
|
||||
\ 'uri': ale#path#ToFileURI(g:dir . '/foo/bar.ts'),
|
||||
\ 'version': 1,
|
||||
\ },
|
||||
\ 'text': ale#util#GetBufferContents(bufnr('')),
|
||||
\ }
|
||||
\ ],
|
||||
\ ale#lsp#message#DidSave(bufnr(''), v:true)
|
||||
|
||||
Execute(ale#lsp#message#DidClose() should return correct messages):
|
||||
AssertEqual
|
||||
\ [
|
||||
\ 1,
|
||||
\ 'textDocument/didClose',
|
||||
\ {
|
||||
\ 'textDocument': {
|
||||
\ 'uri': ale#path#ToFileURI(g:dir . '/foo/bar.ts'),
|
||||
\ },
|
||||
\ }
|
||||
\ ],
|
||||
\ ale#lsp#message#DidClose(bufnr(''))
|
||||
|
||||
Execute(ale#lsp#message#Completion() should return correct messages):
|
||||
AssertEqual
|
||||
\ [
|
||||
\ 0,
|
||||
\ 'textDocument/completion',
|
||||
\ {
|
||||
\ 'textDocument': {
|
||||
\ 'uri': ale#path#ToFileURI(g:dir . '/foo/bar.ts'),
|
||||
\ },
|
||||
\ 'position': {'line': 11, 'character': 33},
|
||||
\ }
|
||||
\ ],
|
||||
\ ale#lsp#message#Completion(bufnr(''), 12, 34, '')
|
||||
|
||||
Execute(ale#lsp#message#Completion() should return correct messages with a trigger charaacter):
|
||||
AssertEqual
|
||||
\ [
|
||||
\ 0,
|
||||
\ 'textDocument/completion',
|
||||
\ {
|
||||
\ 'textDocument': {
|
||||
\ 'uri': ale#path#ToFileURI(g:dir . '/foo/bar.ts'),
|
||||
\ },
|
||||
\ 'position': {'line': 11, 'character': 33},
|
||||
\ 'context': {'triggerKind': 2, 'triggerCharacter': '.'},
|
||||
\ }
|
||||
\ ],
|
||||
\ ale#lsp#message#Completion(bufnr(''), 12, 34, '.')
|
||||
\
|
||||
Execute(ale#lsp#message#Definition() should return correct messages):
|
||||
AssertEqual
|
||||
\ [
|
||||
\ 0,
|
||||
\ 'textDocument/definition',
|
||||
\ {
|
||||
\ 'textDocument': {
|
||||
\ 'uri': ale#path#ToFileURI(g:dir . '/foo/bar.ts'),
|
||||
\ },
|
||||
\ 'position': {'line': 11, 'character': 33},
|
||||
\ }
|
||||
\ ],
|
||||
\ ale#lsp#message#Definition(bufnr(''), 12, 34)
|
||||
|
||||
Execute(ale#lsp#message#TypeDefinition() should return correct messages):
|
||||
AssertEqual
|
||||
\ [
|
||||
\ 0,
|
||||
\ 'textDocument/typeDefinition',
|
||||
\ {
|
||||
\ 'textDocument': {
|
||||
\ 'uri': ale#path#ToFileURI(g:dir . '/foo/bar.ts'),
|
||||
\ },
|
||||
\ 'position': {'line': 11, 'character': 33},
|
||||
\ }
|
||||
\ ],
|
||||
\ ale#lsp#message#TypeDefinition(bufnr(''), 12, 34)
|
||||
|
||||
Execute(ale#lsp#message#Implementation() should return correct messages):
|
||||
AssertEqual
|
||||
\ [
|
||||
\ 0,
|
||||
\ 'textDocument/implementation',
|
||||
\ {
|
||||
\ 'textDocument': {
|
||||
\ 'uri': ale#path#ToFileURI(g:dir . '/foo/bar.ts'),
|
||||
\ },
|
||||
\ 'position': {'line': 11, 'character': 33},
|
||||
\ }
|
||||
\ ],
|
||||
\ ale#lsp#message#Implementation(bufnr(''), 12, 34)
|
||||
|
||||
Execute(ale#lsp#message#References() should return correct messages):
|
||||
AssertEqual
|
||||
\ [
|
||||
\ 0,
|
||||
\ 'textDocument/references',
|
||||
\ {
|
||||
\ 'textDocument': {
|
||||
\ 'uri': ale#path#ToFileURI(g:dir . '/foo/bar.ts'),
|
||||
\ },
|
||||
\ 'position': {'line': 11, 'character': 33},
|
||||
\ 'context': {'includeDeclaration': v:false},
|
||||
\ }
|
||||
\ ],
|
||||
\ ale#lsp#message#References(bufnr(''), 12, 34)
|
||||
|
||||
Execute(ale#lsp#message#Symbol() should return correct messages):
|
||||
AssertEqual
|
||||
\ [
|
||||
\ 0,
|
||||
\ 'workspace/symbol',
|
||||
\ {
|
||||
\ 'query': 'foobar',
|
||||
\ }
|
||||
\ ],
|
||||
\ ale#lsp#message#Symbol('foobar')
|
||||
|
||||
Execute(ale#lsp#message#Hover() should return correct messages):
|
||||
AssertEqual
|
||||
\ [
|
||||
\ 0,
|
||||
\ 'textDocument/hover',
|
||||
\ {
|
||||
\ 'textDocument': {
|
||||
\ 'uri': ale#path#ToFileURI(g:dir . '/foo/bar.ts'),
|
||||
\ },
|
||||
\ 'position': {'line': 11, 'character': 33},
|
||||
\ }
|
||||
\ ],
|
||||
\ ale#lsp#message#Hover(bufnr(''), 12, 34)
|
||||
|
||||
Execute(ale#lsp#message#DidChangeConfiguration() should return correct messages):
|
||||
let g:ale_lsp_configuration = {
|
||||
\ 'foo': 'bar'
|
||||
\ }
|
||||
AssertEqual
|
||||
\ [
|
||||
\ 1,
|
||||
\ 'workspace/didChangeConfiguration',
|
||||
\ {
|
||||
\ 'settings': {
|
||||
\ 'foo': 'bar',
|
||||
\ }
|
||||
\ }
|
||||
\ ],
|
||||
\ ale#lsp#message#DidChangeConfiguration(bufnr(''), g:ale_lsp_configuration)
|
||||
|
||||
Execute(ale#lsp#tsserver_message#Open() should return correct messages):
|
||||
AssertEqual
|
||||
\ [
|
||||
\ 1,
|
||||
\ 'ts@open',
|
||||
\ {
|
||||
\ 'file': ale#path#Simplify(g:dir . '/foo/bar.ts'),
|
||||
\ }
|
||||
\ ],
|
||||
\ ale#lsp#tsserver_message#Open(bufnr(''))
|
||||
|
||||
Execute(ale#lsp#tsserver_message#Close() should return correct messages):
|
||||
AssertEqual
|
||||
\ [
|
||||
\ 1,
|
||||
\ 'ts@close',
|
||||
\ {
|
||||
\ 'file': ale#path#Simplify(g:dir . '/foo/bar.ts'),
|
||||
\ }
|
||||
\ ],
|
||||
\ ale#lsp#tsserver_message#Close(bufnr(''))
|
||||
|
||||
Execute(ale#lsp#tsserver_message#Change() should return correct messages):
|
||||
AssertEqual
|
||||
\ [
|
||||
\ 1,
|
||||
\ 'ts@change',
|
||||
\ {
|
||||
\ 'file': ale#path#Simplify(g:dir . '/foo/bar.ts'),
|
||||
\ 'line': 1,
|
||||
\ 'offset': 1,
|
||||
\ 'endLine': 1073741824,
|
||||
\ 'endOffset': 1,
|
||||
\ 'insertString': "foo()\nbar()\nbaz()\n",
|
||||
\ }
|
||||
\ ],
|
||||
\ ale#lsp#tsserver_message#Change(bufnr(''))
|
||||
|
||||
Execute(ale#lsp#tsserver_message#Geterr() should return correct messages):
|
||||
AssertEqual
|
||||
\ [
|
||||
\ 1,
|
||||
\ 'ts@geterr',
|
||||
\ {
|
||||
\ 'files': [ale#path#Simplify(g:dir . '/foo/bar.ts')],
|
||||
\ }
|
||||
\ ],
|
||||
\ ale#lsp#tsserver_message#Geterr(bufnr(''))
|
||||
|
||||
Execute(ale#lsp#tsserver_message#Completions() should return correct messages):
|
||||
AssertEqual
|
||||
\ [
|
||||
\ 0,
|
||||
\ 'ts@completions',
|
||||
\ {
|
||||
\ 'file': ale#path#Simplify(g:dir . '/foo/bar.ts'),
|
||||
\ 'line': 347,
|
||||
\ 'offset': 12,
|
||||
\ 'prefix': 'abc',
|
||||
\ 'includeExternalModuleExports': 1,
|
||||
\ }
|
||||
\ ],
|
||||
\ ale#lsp#tsserver_message#Completions(bufnr(''), 347, 12, 'abc', 1)
|
||||
|
||||
Execute(ale#lsp#tsserver_message#CompletionEntryDetails() should return correct messages):
|
||||
AssertEqual
|
||||
\ [
|
||||
\ 0,
|
||||
\ 'ts@completionEntryDetails',
|
||||
\ {
|
||||
\ 'file': ale#path#Simplify(g:dir . '/foo/bar.ts'),
|
||||
\ 'line': 347,
|
||||
\ 'offset': 12,
|
||||
\ 'entryNames': ['foo', 'bar'],
|
||||
\ }
|
||||
\ ],
|
||||
\ ale#lsp#tsserver_message#CompletionEntryDetails(bufnr(''), 347, 12, ['foo', 'bar'])
|
||||
|
||||
Execute(ale#lsp#tsserver_message#Definition() should return correct messages):
|
||||
AssertEqual
|
||||
\ [
|
||||
\ 0,
|
||||
\ 'ts@definition',
|
||||
\ {
|
||||
\ 'file': ale#path#Simplify(g:dir . '/foo/bar.ts'),
|
||||
\ 'line': 347,
|
||||
\ 'offset': 12,
|
||||
\ }
|
||||
\ ],
|
||||
\ ale#lsp#tsserver_message#Definition(bufnr(''), 347, 12)
|
||||
|
||||
Execute(ale#lsp#tsserver_message#TypeDefinition() should return correct messages):
|
||||
AssertEqual
|
||||
\ [
|
||||
\ 0,
|
||||
\ 'ts@typeDefinition',
|
||||
\ {
|
||||
\ 'file': ale#path#Simplify(g:dir . '/foo/bar.ts'),
|
||||
\ 'line': 347,
|
||||
\ 'offset': 12,
|
||||
\ }
|
||||
\ ],
|
||||
\ ale#lsp#tsserver_message#TypeDefinition(bufnr(''), 347, 12)
|
||||
|
||||
Execute(ale#lsp#tsserver_message#Implementation() should return correct messages):
|
||||
AssertEqual
|
||||
\ [
|
||||
\ 0,
|
||||
\ 'ts@implementation',
|
||||
\ {
|
||||
\ 'file': ale#path#Simplify(g:dir . '/foo/bar.ts'),
|
||||
\ 'line': 347,
|
||||
\ 'offset': 12,
|
||||
\ }
|
||||
\ ],
|
||||
\ ale#lsp#tsserver_message#Implementation(bufnr(''), 347, 12)
|
||||
|
||||
Execute(ale#lsp#tsserver_message#References() should return correct messages):
|
||||
AssertEqual
|
||||
\ [
|
||||
\ 0,
|
||||
\ 'ts@references',
|
||||
\ {
|
||||
\ 'file': ale#path#Simplify(g:dir . '/foo/bar.ts'),
|
||||
\ 'line': 347,
|
||||
\ 'offset': 12,
|
||||
\ }
|
||||
\ ],
|
||||
\ ale#lsp#tsserver_message#References(bufnr(''), 347, 12)
|
||||
|
||||
Execute(ale#lsp#tsserver_message#Quickinfo() should return correct messages):
|
||||
AssertEqual
|
||||
\ [
|
||||
\ 0,
|
||||
\ 'ts@quickinfo',
|
||||
\ {
|
||||
\ 'file': ale#path#Simplify(g:dir . '/foo/bar.ts'),
|
||||
\ 'line': 347,
|
||||
\ 'offset': 12,
|
||||
\ }
|
||||
\ ],
|
||||
\ ale#lsp#tsserver_message#Quickinfo(bufnr(''), 347, 12)
|
@ -0,0 +1,44 @@
|
||||
Before:
|
||||
Save g:ale_command_wrapper
|
||||
|
||||
runtime autoload/ale/lsp.vim
|
||||
|
||||
let g:ale_command_wrapper = ''
|
||||
|
||||
let g:args = []
|
||||
|
||||
" Mock the StartProgram function so we can just capture the arguments.
|
||||
function! ale#lsp#StartProgram(...) abort
|
||||
let g:args = a:000[1:]
|
||||
endfunction
|
||||
|
||||
After:
|
||||
Restore
|
||||
|
||||
unlet! g:args
|
||||
|
||||
runtime autoload/ale/lsp.vim
|
||||
|
||||
Execute(Command formatting should be applied correctly for LSP linters):
|
||||
call ale#lsp_linter#StartLSP(
|
||||
\ bufnr(''),
|
||||
\ {
|
||||
\ 'name': 'linter',
|
||||
\ 'language': {-> 'x'},
|
||||
\ 'project_root': {-> '/foo/bar'},
|
||||
\ 'lsp': 'stdio',
|
||||
\ 'executable': has('win32') ? 'cmd': 'true',
|
||||
\ 'command': '%e --foo',
|
||||
\ },
|
||||
\ {-> 0}
|
||||
\)
|
||||
|
||||
if has('win32')
|
||||
AssertEqual
|
||||
\ ['cmd', 'cmd /s/c "cmd --foo"'],
|
||||
\ g:args
|
||||
else
|
||||
AssertEqual
|
||||
\ ['true', [&shell, '-c', '''true'' --foo']],
|
||||
\ g:args
|
||||
endif
|
227
sources_non_forked/ale/test/lsp/test_lsp_connections.vader
Normal file
227
sources_non_forked/ale/test/lsp/test_lsp_connections.vader
Normal file
@ -0,0 +1,227 @@
|
||||
Before:
|
||||
let g:ale_lsp_next_message_id = 1
|
||||
|
||||
After:
|
||||
if exists('b:conn') && has_key(b:conn, 'id')
|
||||
call ale#lsp#RemoveConnectionWithID(b:conn.id)
|
||||
endif
|
||||
|
||||
unlet! b:data
|
||||
unlet! b:conn
|
||||
|
||||
Execute(GetNextMessageID() should increment appropriately):
|
||||
" We should get the initial ID, and increment a bit.
|
||||
AssertEqual 1, ale#lsp#GetNextMessageID()
|
||||
AssertEqual 2, ale#lsp#GetNextMessageID()
|
||||
AssertEqual 3, ale#lsp#GetNextMessageID()
|
||||
|
||||
" Set the maximum ID.
|
||||
let g:ale_lsp_next_message_id = 9223372036854775807
|
||||
|
||||
" When we hit the maximum ID, the next ID afterwards should be 1.
|
||||
AssertEqual 9223372036854775807, ale#lsp#GetNextMessageID()
|
||||
AssertEqual 1, ale#lsp#GetNextMessageID()
|
||||
|
||||
Execute(ale#lsp#CreateMessageData() should create an appropriate message):
|
||||
" NeoVim outputs JSON with spaces, so the output is a little different.
|
||||
if has('nvim')
|
||||
" 79 is the size in bytes for UTF-8, not the number of characters.
|
||||
AssertEqual
|
||||
\ [
|
||||
\ 1,
|
||||
\ "Content-Length: 79\r\n\r\n"
|
||||
\ . '{"method": "someMethod", "jsonrpc": "2.0", "id": 1, "params": {"foo": "barÜ"}}',
|
||||
\ ],
|
||||
\ ale#lsp#CreateMessageData([0, 'someMethod', {'foo': 'barÜ'}])
|
||||
" Check again to ensure that we use the next ID.
|
||||
AssertEqual
|
||||
\ [
|
||||
\ 2,
|
||||
\ "Content-Length: 79\r\n\r\n"
|
||||
\ . '{"method": "someMethod", "jsonrpc": "2.0", "id": 2, "params": {"foo": "barÜ"}}',
|
||||
\ ],
|
||||
\ ale#lsp#CreateMessageData([0, 'someMethod', {'foo': 'barÜ'}])
|
||||
else
|
||||
AssertEqual
|
||||
\ [
|
||||
\ 1,
|
||||
\ "Content-Length: 71\r\n\r\n"
|
||||
\ . '{"method":"someMethod","jsonrpc":"2.0","id":1,"params":{"foo":"barÜ"}}',
|
||||
\ ],
|
||||
\ ale#lsp#CreateMessageData([0, 'someMethod', {'foo': 'barÜ'}])
|
||||
AssertEqual
|
||||
\ [
|
||||
\ 2,
|
||||
\ "Content-Length: 71\r\n\r\n"
|
||||
\ . '{"method":"someMethod","jsonrpc":"2.0","id":2,"params":{"foo":"barÜ"}}',
|
||||
\ ],
|
||||
\ ale#lsp#CreateMessageData([0, 'someMethod', {'foo': 'barÜ'}])
|
||||
endif
|
||||
|
||||
Execute(ale#lsp#CreateMessageData() should create messages without params):
|
||||
if has('nvim')
|
||||
AssertEqual
|
||||
\ [
|
||||
\ 1,
|
||||
\ "Content-Length: 56\r\n\r\n"
|
||||
\ . '{"method": "someOtherMethod", "jsonrpc": "2.0", "id": 1}',
|
||||
\ ],
|
||||
\ ale#lsp#CreateMessageData([0, 'someOtherMethod'])
|
||||
else
|
||||
AssertEqual
|
||||
\ [
|
||||
\ 1,
|
||||
\ "Content-Length: 51\r\n\r\n"
|
||||
\ . '{"method":"someOtherMethod","jsonrpc":"2.0","id":1}',
|
||||
\ ],
|
||||
\ ale#lsp#CreateMessageData([0, 'someOtherMethod'])
|
||||
endif
|
||||
|
||||
Execute(ale#lsp#CreateMessageData() should create notifications):
|
||||
if has('nvim')
|
||||
AssertEqual
|
||||
\ [
|
||||
\ 0,
|
||||
\ "Content-Length: 48\r\n\r\n"
|
||||
\ . '{"method": "someNotification", "jsonrpc": "2.0"}',
|
||||
\ ],
|
||||
\ ale#lsp#CreateMessageData([1, 'someNotification'])
|
||||
AssertEqual
|
||||
\ [
|
||||
\ 0,
|
||||
\ "Content-Length: 74\r\n\r\n"
|
||||
\ . '{"method": "someNotification", "jsonrpc": "2.0", "params": {"foo": "bar"}}',
|
||||
\ ],
|
||||
\ ale#lsp#CreateMessageData([1, 'someNotification', {'foo': 'bar'}])
|
||||
else
|
||||
AssertEqual
|
||||
\ [
|
||||
\ 0,
|
||||
\ "Content-Length: 45\r\n\r\n"
|
||||
\ . '{"method":"someNotification","jsonrpc":"2.0"}',
|
||||
\ ],
|
||||
\ ale#lsp#CreateMessageData([1, 'someNotification'])
|
||||
AssertEqual
|
||||
\ [
|
||||
\ 0,
|
||||
\ "Content-Length: 68\r\n\r\n"
|
||||
\ . '{"method":"someNotification","jsonrpc":"2.0","params":{"foo":"bar"}}',
|
||||
\ ],
|
||||
\ ale#lsp#CreateMessageData([1, 'someNotification', {'foo': 'bar'}])
|
||||
endif
|
||||
|
||||
Execute(ale#lsp#CreateMessageData() should create tsserver notification messages):
|
||||
if has('nvim')
|
||||
AssertEqual
|
||||
\ [
|
||||
\ 0,
|
||||
\ '{"seq": null, "type": "request", "command": "someNotification"}'
|
||||
\ . "\n",
|
||||
\ ],
|
||||
\ ale#lsp#CreateMessageData([1, 'ts@someNotification'])
|
||||
AssertEqual
|
||||
\ [
|
||||
\ 0,
|
||||
\ '{"seq": null, "arguments": {"foo": "bar"}, "type": "request", "command": "someNotification"}'
|
||||
\ . "\n",
|
||||
\ ],
|
||||
\ ale#lsp#CreateMessageData([1, 'ts@someNotification', {'foo': 'bar'}])
|
||||
else
|
||||
AssertEqual
|
||||
\ [
|
||||
\ 0,
|
||||
\ '{"seq":null,"type":"request","command":"someNotification"}'
|
||||
\ . "\n",
|
||||
\ ],
|
||||
\ ale#lsp#CreateMessageData([1, 'ts@someNotification'])
|
||||
AssertEqual
|
||||
\ [
|
||||
\ 0,
|
||||
\ '{"seq":null,"arguments":{"foo":"bar"},"type":"request","command":"someNotification"}'
|
||||
\ . "\n",
|
||||
\ ],
|
||||
\ ale#lsp#CreateMessageData([1, 'ts@someNotification', {'foo': 'bar'}])
|
||||
endif
|
||||
|
||||
Execute(ale#lsp#CreateMessageData() should create tsserver messages expecting responses):
|
||||
if has('nvim')
|
||||
AssertEqual
|
||||
\ [
|
||||
\ 1,
|
||||
\ '{"seq": 1, "type": "request", "command": "someMessage"}'
|
||||
\ . "\n",
|
||||
\ ],
|
||||
\ ale#lsp#CreateMessageData([0, 'ts@someMessage'])
|
||||
AssertEqual
|
||||
\ [
|
||||
\ 2,
|
||||
\ '{"seq": 2, "arguments": {"foo": "bar"}, "type": "request", "command": "someMessage"}'
|
||||
\ . "\n",
|
||||
\ ],
|
||||
\ ale#lsp#CreateMessageData([0, 'ts@someMessage', {'foo': 'bar'}])
|
||||
else
|
||||
AssertEqual
|
||||
\ [
|
||||
\ 1,
|
||||
\ '{"seq":1,"type":"request","command":"someMessage"}'
|
||||
\ . "\n",
|
||||
\ ],
|
||||
\ ale#lsp#CreateMessageData([0, 'ts@someMessage'])
|
||||
AssertEqual
|
||||
\ [
|
||||
\ 2,
|
||||
\ '{"seq":2,"arguments":{"foo":"bar"},"type":"request","command":"someMessage"}'
|
||||
\ . "\n",
|
||||
\ ],
|
||||
\ ale#lsp#CreateMessageData([0, 'ts@someMessage', {'foo': 'bar'}])
|
||||
endif
|
||||
|
||||
Execute(ale#lsp#ReadMessageData() should read single whole messages):
|
||||
AssertEqual
|
||||
\ ['', [{'id': 2, 'jsonrpc': '2.0', 'result': {'foo': 'barÜ'}}]],
|
||||
\ ale#lsp#ReadMessageData(
|
||||
\ "Content-Length: 49\r\n\r\n"
|
||||
\ . '{"id":2,"jsonrpc":"2.0","result":{"foo":"barÜ"}}'
|
||||
\ )
|
||||
|
||||
Execute(ale#lsp#ReadMessageData() should ignore other headers):
|
||||
AssertEqual
|
||||
\ ['', [{'id': 2, 'jsonrpc': '2.0', 'result': {'foo': 'barÜ'}}]],
|
||||
\ ale#lsp#ReadMessageData(
|
||||
\ "First-Header: 49\r\n"
|
||||
\ . "Content-Length: 49\r\n"
|
||||
\ . "Other-Header: 49\r\n"
|
||||
\ . "\r\n"
|
||||
\ . '{"id":2,"jsonrpc":"2.0","result":{"foo":"barÜ"}}'
|
||||
\ )
|
||||
|
||||
Execute(ale#lsp#ReadMessageData() should handle partial messages):
|
||||
let b:data = "Content-Length: 49\r\n\r\n" . '{"id":2,"jsonrpc":"2.0","result":'
|
||||
|
||||
AssertEqual [b:data, []], ale#lsp#ReadMessageData(b:data)
|
||||
|
||||
Execute(ale#lsp#ReadMessageData() should handle multiple messages):
|
||||
AssertEqual
|
||||
\ ['', [
|
||||
\ {'id': 2, 'jsonrpc': '2.0', 'result': {'foo': 'barÜ'}},
|
||||
\ {'id': 2, 'jsonrpc': '2.0', 'result': {'foo123': 'barÜ'}},
|
||||
\ ]],
|
||||
\ ale#lsp#ReadMessageData(
|
||||
\ "Content-Length: 49\r\n\r\n"
|
||||
\ . '{"id":2,"jsonrpc":"2.0","result":{"foo":"barÜ"}}'
|
||||
\ . "Content-Length: 52\r\n\r\n"
|
||||
\ . '{"id":2,"jsonrpc":"2.0","result":{"foo123":"barÜ"}}'
|
||||
\ )
|
||||
|
||||
Execute(ale#lsp#ReadMessageData() should handle a message with part of a second message):
|
||||
let b:data = "Content-Length: 52\r\n\r\n" . '{"id":2,"jsonrpc":"2.'
|
||||
|
||||
AssertEqual
|
||||
\ [b:data, [
|
||||
\ {'id': 2, 'jsonrpc': '2.0', 'result': {'foo': 'barÜ'}},
|
||||
\ ]],
|
||||
\ ale#lsp#ReadMessageData(
|
||||
\ "Content-Length: 49\r\n\r\n"
|
||||
\ . '{"id":2,"jsonrpc":"2.0","result":{"foo":"barÜ"}}'
|
||||
\ . b:data
|
||||
\ )
|
158
sources_non_forked/ale/test/lsp/test_lsp_custom_request.vader
Normal file
158
sources_non_forked/ale/test/lsp/test_lsp_custom_request.vader
Normal file
@ -0,0 +1,158 @@
|
||||
Before:
|
||||
runtime autoload/ale/linter.vim
|
||||
runtime autoload/ale/lsp.vim
|
||||
runtime autoload/ale/lsp_linter.vim
|
||||
|
||||
let g:address = 'ccls_address'
|
||||
let g:conn_id = -1
|
||||
let g:executable = 'ccls'
|
||||
let g:executable_or_address = ''
|
||||
let g:linter_name = 'ccls'
|
||||
let g:magic_number = 42
|
||||
let g:no_result = 0
|
||||
let g:message_list = []
|
||||
let g:message_id = 1
|
||||
let g:method = '$ccls/call'
|
||||
let g:parameters = {}
|
||||
let g:project_root = '/project/root'
|
||||
let g:response = ''
|
||||
let g:return_value = -1
|
||||
|
||||
let g:linter_list = [{
|
||||
\ 'output_stream': 'stdout',
|
||||
\ 'lint_file': 0,
|
||||
\ 'language': 'cpp',
|
||||
\ 'name': g:linter_name,
|
||||
\ 'project_root': {b -> g:project_root},
|
||||
\ 'aliases': [],
|
||||
\ 'read_buffer': 1,
|
||||
\ 'command': '%e'
|
||||
\ }]
|
||||
|
||||
let g:callback_result = g:no_result
|
||||
|
||||
" Encode dictionary to jsonrpc
|
||||
function! Encode(obj) abort
|
||||
let l:body = json_encode(a:obj)
|
||||
return 'Content-Length: ' . strlen(l:body) . "\r\n\r\n" . l:body
|
||||
endfunction
|
||||
|
||||
" Replace the StartLSP function to mock an LSP linter
|
||||
function! ale#lsp_linter#StartLSP(buffer, linter, Callback) abort
|
||||
let g:conn_id = ale#lsp#Register(g:executable_or_address, g:project_root, {})
|
||||
call ale#lsp#MarkDocumentAsOpen(g:conn_id, a:buffer)
|
||||
call ale#lsp#HandleMessage(g:conn_id, Encode({'method': 'initialize'}))
|
||||
|
||||
let l:details = {
|
||||
\ 'command': g:executable,
|
||||
\ 'buffer': a:buffer,
|
||||
\ 'connection_id': g:conn_id,
|
||||
\ 'project_root': g:project_root,
|
||||
\}
|
||||
|
||||
call ale#lsp_linter#OnInit(a:linter, l:details, a:Callback)
|
||||
endfunction
|
||||
|
||||
" Dummy callback
|
||||
function! Callback(response) abort
|
||||
let g:callback_result = a:response.result.value
|
||||
endfunction
|
||||
|
||||
" Replace the GetAll function to mock an LSP linter
|
||||
function! ale#linter#GetAll(filetype) abort
|
||||
return g:linter_list
|
||||
endfunction
|
||||
|
||||
" Replace the Send function to mock an LSP linter
|
||||
function! ale#lsp#Send(conn_id, message) abort
|
||||
call add(g:message_list, a:message)
|
||||
return g:message_id
|
||||
endfunction
|
||||
|
||||
" Code for a test case
|
||||
function! TestCase(is_notification) abort
|
||||
" Test sending a custom request
|
||||
let g:return_value = ale#lsp_linter#SendRequest(
|
||||
\ bufnr('%'),
|
||||
\ g:linter_name,
|
||||
\ [a:is_notification, g:method, g:parameters],
|
||||
\ function('Callback'))
|
||||
|
||||
Assert index(g:message_list, [a:is_notification, g:method, g:parameters]) >= 0
|
||||
|
||||
" Mock an incoming response to the request
|
||||
let g:response = Encode({
|
||||
\ 'id': g:message_id,
|
||||
\ 'jsonrpc': '2.0',
|
||||
\ 'result': {'value': g:magic_number}
|
||||
\ })
|
||||
call ale#lsp#HandleMessage(g:conn_id, g:response)
|
||||
|
||||
AssertEqual
|
||||
\ a:is_notification ? g:no_result : g:magic_number,
|
||||
\ g:callback_result
|
||||
endfunction
|
||||
|
||||
After:
|
||||
if g:conn_id isnot v:null
|
||||
call ale#lsp#RemoveConnectionWithID(g:conn_id)
|
||||
endif
|
||||
|
||||
unlet! g:callback_result
|
||||
unlet! g:conn_id
|
||||
unlet! g:executable
|
||||
unlet! g:is_notification
|
||||
unlet! g:linter_name
|
||||
unlet! g:magic_number
|
||||
unlet! g:message_list
|
||||
unlet! g:message_id
|
||||
unlet! g:method
|
||||
unlet! g:no_result
|
||||
unlet! g:parameters
|
||||
unlet! g:project_root
|
||||
unlet! g:response
|
||||
unlet! g:return_value
|
||||
|
||||
delfunction Encode
|
||||
delfunction Callback
|
||||
delfunction TestCase
|
||||
|
||||
runtime autoload/ale/linter.vim
|
||||
runtime autoload/ale/lsp.vim
|
||||
runtime autoload/ale/lsp_linter.vim
|
||||
|
||||
Given cpp(Empty cpp file):
|
||||
Execute(Test custom request to server identified by executable):
|
||||
let g:executable_or_address = g:executable
|
||||
let g:linter_list[0].executable = {b -> g:executable}
|
||||
let g:linter_list[0].lsp = 'stdio'
|
||||
let g:is_notification = 0
|
||||
|
||||
call TestCase(g:is_notification)
|
||||
|
||||
Given cpp(Empty cpp file):
|
||||
Execute(Test custom notification to server identified by executable):
|
||||
let g:executable_or_address = g:executable
|
||||
let g:linter_list[0].executable = {b -> g:executable}
|
||||
let g:linter_list[0].lsp = 'stdio'
|
||||
let g:is_notification = 1
|
||||
|
||||
call TestCase(g:is_notification)
|
||||
|
||||
Given cpp(Empty cpp file):
|
||||
Execute(Test custom request to server identified by address):
|
||||
let g:executable_or_address = g:address
|
||||
let g:linter_list[0].address = {b -> g:address}
|
||||
let g:linter_list[0].lsp = 'socket'
|
||||
let g:is_notification = 0
|
||||
|
||||
call TestCase(g:is_notification)
|
||||
|
||||
Given cpp(Empty cpp file):
|
||||
Execute(Test custom notification to server identified by address):
|
||||
let g:executable_or_address = g:address
|
||||
let g:linter_list[0].address = {b -> g:address}
|
||||
let g:linter_list[0].lsp = 'socket'
|
||||
let g:is_notification = 1
|
||||
|
||||
call TestCase(g:is_notification)
|
74
sources_non_forked/ale/test/lsp/test_lsp_error_parsing.vader
Normal file
74
sources_non_forked/ale/test/lsp/test_lsp_error_parsing.vader
Normal file
@ -0,0 +1,74 @@
|
||||
Execute(Invalid responses should be handled):
|
||||
AssertEqual '', ale#lsp#response#GetErrorMessage({})
|
||||
AssertEqual '', ale#lsp#response#GetErrorMessage({'error': 0})
|
||||
AssertEqual '', ale#lsp#response#GetErrorMessage({'error': {}})
|
||||
AssertEqual '', ale#lsp#response#GetErrorMessage({
|
||||
\ 'error': {
|
||||
\ 'code': 0,
|
||||
\ 'message': 'x',
|
||||
\ },
|
||||
\})
|
||||
AssertEqual '', ale#lsp#response#GetErrorMessage({'error': {'code': -32602}})
|
||||
AssertEqual '', ale#lsp#response#GetErrorMessage({'error': {'code': -32603}})
|
||||
|
||||
Execute(Messages without tracebacks should be handled):
|
||||
AssertEqual 'xyz', ale#lsp#response#GetErrorMessage({
|
||||
\ 'error': {
|
||||
\ 'code': -32602,
|
||||
\ 'message': 'xyz',
|
||||
\ },
|
||||
\})
|
||||
AssertEqual 'abc', ale#lsp#response#GetErrorMessage({
|
||||
\ 'error': {
|
||||
\ 'code': -32603,
|
||||
\ 'message': 'abc',
|
||||
\ },
|
||||
\})
|
||||
|
||||
Execute(Invalid traceback data should be tolerated):
|
||||
AssertEqual 'xyz', ale#lsp#response#GetErrorMessage({
|
||||
\ 'error': {
|
||||
\ 'code': -32602,
|
||||
\ 'message': 'xyz',
|
||||
\ 'data': {
|
||||
\ },
|
||||
\ },
|
||||
\})
|
||||
AssertEqual 'xyz', ale#lsp#response#GetErrorMessage({
|
||||
\ 'error': {
|
||||
\ 'code': -32602,
|
||||
\ 'message': 'xyz',
|
||||
\ 'data': {
|
||||
\ 'traceback': 0,
|
||||
\ },
|
||||
\ },
|
||||
\})
|
||||
AssertEqual 'xyz', ale#lsp#response#GetErrorMessage({
|
||||
\ 'error': {
|
||||
\ 'code': -32602,
|
||||
\ 'message': 'xyz',
|
||||
\ 'data': {
|
||||
\ 'traceback': [],
|
||||
\ },
|
||||
\ },
|
||||
\})
|
||||
|
||||
Execute(Messages with tracebacks should be handled):
|
||||
AssertEqual "xyz\n123\n456", ale#lsp#response#GetErrorMessage({
|
||||
\ 'error': {
|
||||
\ 'code': -32602,
|
||||
\ 'message': 'xyz',
|
||||
\ 'data': {
|
||||
\ 'traceback': ['123', '456'],
|
||||
\ },
|
||||
\ },
|
||||
\})
|
||||
|
||||
Execute(Messages with string data should be handled):
|
||||
AssertEqual "xyz\nUncaught Exception", ale#lsp#response#GetErrorMessage({
|
||||
\ 'error': {
|
||||
\ 'code': -32602,
|
||||
\ 'message': 'xyz',
|
||||
\ 'data': 'Uncaught Exception',
|
||||
\ },
|
||||
\})
|
@ -0,0 +1,90 @@
|
||||
Before:
|
||||
Save g:ale_lsp_root
|
||||
Save g:ale_root
|
||||
Save b:ale_lsp_root
|
||||
Save b:ale_root
|
||||
|
||||
unlet! g:ale_lsp_root
|
||||
let g:ale_root = {}
|
||||
|
||||
call ale#assert#SetUpLinterTest('c', 'clangd')
|
||||
|
||||
function! Hook1(buffer)
|
||||
return 'abc123'
|
||||
endfunction
|
||||
|
||||
After:
|
||||
Restore
|
||||
|
||||
delfunction Hook1
|
||||
|
||||
call ale#assert#TearDownLinterTest()
|
||||
|
||||
Execute(The buffer-specific variable can be a string):
|
||||
let b:ale_root = '/some/path'
|
||||
call ale#test#SetFilename('other-file.c')
|
||||
|
||||
AssertLSPProject '/some/path'
|
||||
|
||||
Execute(The buffer-specific variable can be a dictionary):
|
||||
let b:ale_root = {'clangd': '/some/path', 'golangserver': '/other/path'}
|
||||
call ale#test#SetFilename('other-file.c')
|
||||
|
||||
AssertLSPProject '/some/path'
|
||||
|
||||
Execute(The buffer-specific variable can have funcrefs):
|
||||
let b:ale_root = {'clangd': function('Hook1'), 'golangserver': '/path'}
|
||||
call ale#test#SetFilename('other-file.c')
|
||||
|
||||
AssertLSPProject 'abc123'
|
||||
|
||||
Execute(The buffer-specific variable can be the old ale_lsp_root setting):
|
||||
let b:ale_lsp_root = '/some/path'
|
||||
call ale#test#SetFilename('other-file.c')
|
||||
|
||||
AssertLSPProject '/some/path'
|
||||
|
||||
Execute(The global variable can be a dictionary):
|
||||
let g:ale_root = {'clangd': '/some/path', 'golangserver': '/other/path'}
|
||||
call ale#test#SetFilename('other-file.c')
|
||||
|
||||
AssertLSPProject '/some/path'
|
||||
|
||||
Execute(The global variable can have funcrefs):
|
||||
let g:ale_root = {'clangd': function('Hook1'), 'golangserver': '/path'}
|
||||
call ale#test#SetFilename('other-file.c')
|
||||
|
||||
AssertLSPProject 'abc123'
|
||||
|
||||
Execute(The buffer-specific variable overrides the global variable):
|
||||
let b:ale_root = {'clangd': '/some/path', 'golangserver': '/other/path'}
|
||||
let g:ale_root = {'clangd': '/not/this/path', 'golangserver': '/elsewhere'}
|
||||
call ale#test#SetFilename('other-file.c')
|
||||
|
||||
AssertLSPProject '/some/path'
|
||||
|
||||
Execute(The global variable is queried if the buffer-specific has no value):
|
||||
let b:ale_root = {'golangserver': '/other/path'}
|
||||
let g:ale_root = {'clangd': '/some/path', 'golangserver': '/elsewhere'}
|
||||
call ale#test#SetFilename('other-file.c')
|
||||
|
||||
AssertLSPProject '/some/path'
|
||||
|
||||
Execute(The global variable can be the old ale_lsp_root setting):
|
||||
let g:ale_root = {}
|
||||
let g:ale_lsp_root = {'clangd': '/some/path', 'golangserver': '/other/path'}
|
||||
call ale#test#SetFilename('other-file.c')
|
||||
|
||||
AssertLSPProject '/some/path'
|
||||
|
||||
Execute(A non-empty ale_root setting should replace the old ale_lsp_root):
|
||||
let g:ale_root = {'clangd': '/some/path', 'golangserver': '/other/path'}
|
||||
let g:ale_lsp_root = {'clangd': '/xxx', 'golangserver': '/xxx'}
|
||||
call ale#test#SetFilename('other-file.c')
|
||||
|
||||
AssertLSPProject '/some/path'
|
||||
|
||||
Execute(No path should be returned by default):
|
||||
call ale#test#SetFilename(tempname() . '/other-file.c')
|
||||
|
||||
AssertLSPProject ''
|
492
sources_non_forked/ale/test/lsp/test_lsp_startup.vader
Normal file
492
sources_non_forked/ale/test/lsp/test_lsp_startup.vader
Normal file
@ -0,0 +1,492 @@
|
||||
Before:
|
||||
Save g:ale_run_synchronously
|
||||
|
||||
let g:ale_run_synchronously = 1
|
||||
unlet! g:ale_run_synchronously_callbacks
|
||||
unlet! g:ale_run_synchronously_emulate_commands
|
||||
|
||||
runtime autoload/ale/lsp.vim
|
||||
runtime autoload/ale/lsp_linter.vim
|
||||
runtime autoload/ale/engine.vim
|
||||
runtime autoload/ale/job.vim
|
||||
runtime autoload/ale/socket.vim
|
||||
|
||||
let g:job_map = {}
|
||||
let g:emulate_job_failure = 0
|
||||
let g:next_job_id = 1
|
||||
let g:lsp_started = 0
|
||||
|
||||
let g:socket_map = {}
|
||||
let g:emulate_socket_failure = 0
|
||||
let g:next_channel_id = 0
|
||||
|
||||
let g:message_buffer = ''
|
||||
let g:calls = []
|
||||
|
||||
function! ale#engine#IsExecutable(buffer, executable) abort
|
||||
return !empty(a:executable)
|
||||
endfunction
|
||||
|
||||
function! ale#job#HasOpenChannel(job_id) abort
|
||||
return has_key(g:job_map, a:job_id)
|
||||
endfunction
|
||||
|
||||
function! ale#job#Stop(job_id) abort
|
||||
if has_key(g:job_map, a:job_id)
|
||||
call remove(g:job_map, a:job_id)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! ale#job#Start(command, options) abort
|
||||
if g:emulate_job_failure
|
||||
return 0
|
||||
endif
|
||||
|
||||
let l:job_id = g:next_job_id
|
||||
let g:next_job_id += 1
|
||||
let g:job_map[l:job_id] = [a:command, a:options]
|
||||
|
||||
return l:job_id
|
||||
endfunction
|
||||
|
||||
function! ale#job#SendRaw(job_id, data) abort
|
||||
let g:message_buffer .= a:data
|
||||
endfunction
|
||||
|
||||
function! ale#socket#IsOpen(channel_id) abort
|
||||
return has_key(g:socket_map, a:channel_id)
|
||||
endfunction
|
||||
|
||||
function! ale#socket#Close(channel_id) abort
|
||||
if has_key(g:socket_map, a:channel_id)
|
||||
call remove(g:socket_map, a:channel_id)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! ale#socket#Open(address, options) abort
|
||||
if g:emulate_socket_failure
|
||||
return -1
|
||||
endif
|
||||
|
||||
let l:channel_id = g:next_channel_id
|
||||
let g:next_channel_id += 1
|
||||
let g:socket_map[l:channel_id] = [a:address, a:options]
|
||||
|
||||
return l:channel_id
|
||||
endfunction
|
||||
|
||||
function! ale#socket#Send(channel_id, data) abort
|
||||
let g:message_buffer .= a:data
|
||||
endfunction
|
||||
|
||||
function! PopMessages() abort
|
||||
let l:message_list = []
|
||||
|
||||
for l:line in split(g:message_buffer, '\(\r\|\n\|Content-Length\)\+')
|
||||
if l:line[:0] is '{'
|
||||
let l:data = json_decode(l:line)
|
||||
|
||||
call add(l:message_list, l:data)
|
||||
endif
|
||||
endfor
|
||||
|
||||
let g:message_buffer = ''
|
||||
|
||||
return l:message_list
|
||||
endfunction
|
||||
|
||||
function! SendMessage(message) abort
|
||||
let l:conn_id = keys(ale#lsp#GetConnections())[0]
|
||||
let l:body = json_encode(a:message)
|
||||
let l:data = 'Content-Length: ' . strlen(l:body) . "\r\n\r\n" . l:body
|
||||
|
||||
call ale#lsp#HandleMessage(l:conn_id, l:data)
|
||||
endfunction
|
||||
|
||||
function! Start(buffer) abort
|
||||
let l:linter = values(ale#linter#GetLintersLoaded())[0][0]
|
||||
|
||||
return ale#lsp_linter#StartLSP(
|
||||
\ a:buffer,
|
||||
\ l:linter,
|
||||
\ {linter, details -> add(g:calls, [linter.name, details])},
|
||||
\)
|
||||
endfunction
|
||||
|
||||
function! AssertInitSuccess(linter_name, conn_prefix, language, root, command, buffer) abort
|
||||
let l:messages = PopMessages()
|
||||
|
||||
if a:linter_name is# 'tsserver'
|
||||
AssertEqual
|
||||
\ [
|
||||
\ {
|
||||
\ 'seq': v:null,
|
||||
\ 'arguments': {
|
||||
\ 'file': expand('#' . a:buffer . ':p'),
|
||||
\ },
|
||||
\ 'type': 'request',
|
||||
\ 'command': 'open',
|
||||
\ },
|
||||
\ ],
|
||||
\ l:messages
|
||||
else
|
||||
AssertEqual
|
||||
\ [
|
||||
\ {
|
||||
\ 'method': 'initialize',
|
||||
\ 'jsonrpc': '2.0',
|
||||
\ 'id': 1,
|
||||
\ 'params': {
|
||||
\ 'initializationOptions': {},
|
||||
\ 'rootUri': ale#path#ToFileURI(a:root),
|
||||
\ 'rootPath': a:root,
|
||||
\ 'processId': getpid(),
|
||||
\ 'capabilities': {
|
||||
\ 'workspace': {
|
||||
\ 'applyEdit': v:false,
|
||||
\ 'didChangeConfiguration': {
|
||||
\ 'dynamicRegistration': v:false,
|
||||
\ },
|
||||
\ 'symbol': {
|
||||
\ 'dynamicRegistration': v:false,
|
||||
\ },
|
||||
\ 'workspaceFolders': v:false,
|
||||
\ 'configuration': v:false,
|
||||
\ },
|
||||
\ 'textDocument': {
|
||||
\ 'synchronization': {
|
||||
\ 'dynamicRegistration': v:false,
|
||||
\ 'willSave': v:false,
|
||||
\ 'willSaveWaitUntil': v:false,
|
||||
\ 'didSave': v:true,
|
||||
\ },
|
||||
\ 'completion': {
|
||||
\ 'dynamicRegistration': v:false,
|
||||
\ 'completionItem': {
|
||||
\ 'snippetSupport': v:false,
|
||||
\ 'commitCharactersSupport': v:false,
|
||||
\ 'documentationFormat': ['plaintext'],
|
||||
\ 'deprecatedSupport': v:false,
|
||||
\ 'preselectSupport': v:false,
|
||||
\ },
|
||||
\ 'contextSupport': v:false,
|
||||
\ },
|
||||
\ 'hover': {
|
||||
\ 'dynamicRegistration': v:false,
|
||||
\ 'contentFormat': ['plaintext'],
|
||||
\ },
|
||||
\ 'references': {
|
||||
\ 'dynamicRegistration': v:false,
|
||||
\ },
|
||||
\ 'documentSymbol': {
|
||||
\ 'dynamicRegistration': v:false,
|
||||
\ 'hierarchicalDocumentSymbolSupport': v:false,
|
||||
\ },
|
||||
\ 'definition': {
|
||||
\ 'dynamicRegistration': v:false,
|
||||
\ 'linkSupport': v:false,
|
||||
\ },
|
||||
\ 'typeDefinition': {
|
||||
\ 'dynamicRegistration': v:false,
|
||||
\ },
|
||||
\ 'implementation': {
|
||||
\ 'dynamicRegistration': v:false,
|
||||
\ 'linkSupport': v:false,
|
||||
\ },
|
||||
\ 'publishDiagnostics': {
|
||||
\ 'relatedInformation': v:true,
|
||||
\ },
|
||||
\ 'codeAction': {
|
||||
\ 'dynamicRegistration': v:false,
|
||||
\ 'codeActionLiteralSupport': {
|
||||
\ 'codeActionKind': {
|
||||
\ 'valueSet': []
|
||||
\ }
|
||||
\ }
|
||||
\ },
|
||||
\ 'rename': {
|
||||
\ 'dynamicRegistration': v:false,
|
||||
\ },
|
||||
\ },
|
||||
\ },
|
||||
\ },
|
||||
\ },
|
||||
\ ],
|
||||
\ l:messages
|
||||
|
||||
call SendMessage({
|
||||
\ 'jsonrpc': '2.0',
|
||||
\ 'id': 1,
|
||||
\ 'result': {
|
||||
\ 'capabilities': {
|
||||
\ 'renameProvider': v:true,
|
||||
\ 'executeCommandProvider': {
|
||||
\ 'commands': [],
|
||||
\ },
|
||||
\ 'hoverProvider': v:true,
|
||||
\ 'documentSymbolProvider': v:true,
|
||||
\ 'documentRangeFormattingProvider': v:true,
|
||||
\ 'codeLensProvider': {
|
||||
\ 'resolveProvider': v:false
|
||||
\ },
|
||||
\ 'referencesProvider': v:true,
|
||||
\ 'textDocumentSync': 2,
|
||||
\ 'documentFormattingProvider': v:true,
|
||||
\ 'codeActionProvider': v:true,
|
||||
\ 'signatureHelpProvider': {
|
||||
\ 'triggerCharacters': ['(', ','],
|
||||
\ },
|
||||
\ 'completionProvider': {
|
||||
\ 'triggerCharacters': ['.'],
|
||||
\ 'resolveProvider': v:false
|
||||
\ },
|
||||
\ 'definitionProvider': v:true,
|
||||
\ 'experimental': {},
|
||||
\ 'documentHighlightProvider': v:true,
|
||||
\ 'workspaceSymbolProvider': v:true,
|
||||
\ },
|
||||
\ },
|
||||
\})
|
||||
|
||||
let l:messages = PopMessages()
|
||||
|
||||
AssertEqual
|
||||
\ [
|
||||
\ {
|
||||
\ 'method': 'initialized',
|
||||
\ 'jsonrpc': '2.0',
|
||||
\ 'params': {},
|
||||
\ },
|
||||
\ {
|
||||
\ 'method': 'textDocument/didOpen',
|
||||
\ 'jsonrpc': '2.0',
|
||||
\ 'params': {
|
||||
\ 'textDocument': {
|
||||
\ 'uri': ale#path#ToFileURI(expand('#' . a:buffer . ':p')),
|
||||
\ 'version': ale#lsp#message#GetNextVersionID() - 1,
|
||||
\ 'languageId': a:language,
|
||||
\ 'text': "\n",
|
||||
\ },
|
||||
\ },
|
||||
\ },
|
||||
\ ],
|
||||
\ l:messages
|
||||
endif
|
||||
|
||||
AssertEqual
|
||||
\ [
|
||||
\ [
|
||||
\ a:linter_name,
|
||||
\ {
|
||||
\ 'connection_id': a:conn_prefix . ':' . a:root,
|
||||
\ 'project_root': a:root,
|
||||
\ 'buffer': a:buffer,
|
||||
\ 'command': !empty(a:command) ? ale#job#PrepareCommand(a:buffer, a:command) : '',
|
||||
\ },
|
||||
\ ],
|
||||
\ ],
|
||||
\ g:calls
|
||||
endfunction
|
||||
|
||||
function! AssertInitFailure() abort
|
||||
let l:messages = PopMessages()
|
||||
|
||||
AssertEqual [], l:messages
|
||||
AssertEqual [], g:calls
|
||||
endfunction
|
||||
|
||||
call ale#linter#Reset()
|
||||
|
||||
After:
|
||||
Restore
|
||||
|
||||
call ale#linter#Reset()
|
||||
call ale#lsp#ResetConnections()
|
||||
|
||||
unlet! g:ale_run_synchronously_callbacks
|
||||
unlet! g:job_map
|
||||
unlet! g:emulate_job_failure
|
||||
unlet! g:next_job_id
|
||||
unlet! g:lsp_started
|
||||
|
||||
unlet! g:socket_map
|
||||
unlet! g:emulate_socket_failure
|
||||
unlet! g:next_channel_id
|
||||
|
||||
unlet! g:message_buffer
|
||||
unlet! g:calls
|
||||
|
||||
augroup VaderTest
|
||||
autocmd!
|
||||
augroup END
|
||||
|
||||
augroup! VaderTest
|
||||
|
||||
delfunction PopMessages
|
||||
delfunction Start
|
||||
delfunction AssertInitSuccess
|
||||
delfunction AssertInitFailure
|
||||
|
||||
runtime autoload/ale/engine.vim
|
||||
runtime autoload/ale/job.vim
|
||||
runtime autoload/ale/socket.vim
|
||||
|
||||
Execute(tsserver should be started correctly):
|
||||
runtime ale_linters/typescript/tsserver.vim
|
||||
|
||||
Assert Start(bufnr(''))
|
||||
call AssertInitSuccess('tsserver', 'tsserver', '', '', ale#Escape('tsserver'), bufnr(''))
|
||||
|
||||
Execute(tsserver failures should be handled appropriately):
|
||||
runtime ale_linters/typescript/tsserver.vim
|
||||
|
||||
let g:emulate_job_failure = 1
|
||||
|
||||
Assert !Start(bufnr(''))
|
||||
call AssertInitFailure()
|
||||
|
||||
Execute(LSP jobs should start correctly):
|
||||
call ale#linter#Define('foobar', {
|
||||
\ 'name': 'foo',
|
||||
\ 'lsp': 'stdio',
|
||||
\ 'executable': 'foo',
|
||||
\ 'command': 'foo',
|
||||
\ 'project_root': '/foo/bar',
|
||||
\ 'initialization_options': {},
|
||||
\})
|
||||
|
||||
Assert Start(bufnr(''))
|
||||
call AssertInitSuccess('foo', 'foo', 'foobar', '/foo/bar', 'foo', bufnr(''))
|
||||
|
||||
Execute(LSP job failures should be handled):
|
||||
call ale#linter#Define('foobar', {
|
||||
\ 'name': 'foo',
|
||||
\ 'lsp': 'stdio',
|
||||
\ 'executable': 'foo',
|
||||
\ 'command': 'foo',
|
||||
\ 'project_root': '/foo/bar',
|
||||
\ 'initialization_options': {},
|
||||
\})
|
||||
|
||||
let g:emulate_job_failure = 1
|
||||
|
||||
Assert !Start(bufnr(''))
|
||||
call AssertInitFailure()
|
||||
|
||||
Execute(LSP TCP connections should start correctly):
|
||||
call ale#linter#Define('foobar', {
|
||||
\ 'name': 'foo',
|
||||
\ 'lsp': 'socket',
|
||||
\ 'address': 'foo',
|
||||
\ 'project_root': '/foo/bar',
|
||||
\ 'initialization_options': {},
|
||||
\})
|
||||
|
||||
Assert Start(bufnr(''))
|
||||
call AssertInitSuccess('foo', 'foo', 'foobar', '/foo/bar', '', bufnr(''))
|
||||
|
||||
Execute(LSP TCP connection failures should be handled):
|
||||
call ale#linter#Define('foobar', {
|
||||
\ 'name': 'foo',
|
||||
\ 'lsp': 'socket',
|
||||
\ 'address': 'foo',
|
||||
\ 'project_root': '/foo/bar',
|
||||
\ 'initialization_options': {},
|
||||
\})
|
||||
|
||||
let g:emulate_socket_failure = 1
|
||||
|
||||
Assert !Start(bufnr(''))
|
||||
call AssertInitFailure()
|
||||
|
||||
Execute(Deferred executables should be handled correctly):
|
||||
call ale#linter#Define('foobar', {
|
||||
\ 'name': 'foo',
|
||||
\ 'lsp': 'stdio',
|
||||
\ 'executable': {b -> ale#command#Run(b, 'echo', {-> 'foo'})},
|
||||
\ 'command': '%e -c',
|
||||
\ 'project_root': '/foo/bar',
|
||||
\ 'initialization_options': {},
|
||||
\})
|
||||
|
||||
Assert Start(bufnr(''))
|
||||
call ale#test#FlushJobs()
|
||||
call AssertInitSuccess('foo', 'foo', 'foobar', '/foo/bar', ale#Escape('foo') . ' -c', bufnr(''))
|
||||
|
||||
Execute(Deferred commands should be handled correctly):
|
||||
call ale#linter#Define('foobar', {
|
||||
\ 'name': 'foo',
|
||||
\ 'lsp': 'stdio',
|
||||
\ 'executable': 'foo',
|
||||
\ 'command': {b -> ale#command#Run(b, 'echo', {-> '%e -c'})},
|
||||
\ 'project_root': '/foo/bar',
|
||||
\ 'initialization_options': {},
|
||||
\})
|
||||
|
||||
Assert Start(bufnr(''))
|
||||
call ale#test#FlushJobs()
|
||||
call AssertInitSuccess('foo', 'foo', 'foobar', '/foo/bar', ale#Escape('foo') . ' -c', bufnr(''))
|
||||
|
||||
Execute(Deferred addresses should be handled correctly):
|
||||
call ale#linter#Define('foobar', {
|
||||
\ 'name': 'foo',
|
||||
\ 'lsp': 'socket',
|
||||
\ 'address': {b -> ale#command#Run(b, 'echo', {-> 'localhost:1234'})},
|
||||
\ 'project_root': '/foo/bar',
|
||||
\ 'initialization_options': {},
|
||||
\})
|
||||
|
||||
Assert Start(bufnr(''))
|
||||
call ale#test#FlushJobs()
|
||||
call AssertInitSuccess('foo', 'localhost:1234', 'foobar', '/foo/bar', '', bufnr(''))
|
||||
|
||||
Execute(Servers that have crashed should be restarted):
|
||||
call ale#lsp#Register('foo', '/foo/bar', {})
|
||||
call extend(ale#lsp#GetConnections()['foo:/foo/bar'], {'initialized': 1})
|
||||
|
||||
" Starting the program again should reset initialized to `0`.
|
||||
call ale#lsp#StartProgram('foo:/foo/bar', 'foobar', 'foobar --start')
|
||||
|
||||
AssertEqual 0, ale#lsp#GetConnections()['foo:/foo/bar']['initialized']
|
||||
AssertEqual ['initialize'], map(PopMessages(), 'v:val[''method'']')
|
||||
|
||||
Execute(Current LSP buffer should receive ALELSPStarted):
|
||||
call ale#linter#Define('foobar', {
|
||||
\ 'name': 'foo',
|
||||
\ 'lsp': 'socket',
|
||||
\ 'address': 'foo',
|
||||
\ 'project_root': '/foo/bar',
|
||||
\ 'initialization_options': {},
|
||||
\})
|
||||
|
||||
augroup VaderTest
|
||||
autocmd!
|
||||
autocmd User ALELSPStarted let g:lsp_started = 1
|
||||
augroup END
|
||||
|
||||
Assert Start(bufnr(''))
|
||||
call AssertInitSuccess('foo', 'foo', 'foobar', '/foo/bar', '', bufnr(''))
|
||||
AssertEqual g:lsp_started, 1
|
||||
|
||||
Execute(Target LSP buffer should receive ALELSPStarted):
|
||||
call ale#linter#Define('foobar', {
|
||||
\ 'name': 'foo',
|
||||
\ 'lsp': 'socket',
|
||||
\ 'address': 'foo',
|
||||
\ 'project_root': '/foo/bar',
|
||||
\ 'initialization_options': {},
|
||||
\})
|
||||
|
||||
augroup VaderTest
|
||||
autocmd!
|
||||
autocmd User ALELSPStarted let g:lsp_started = 1
|
||||
augroup END
|
||||
|
||||
let buffer = bufnr('')
|
||||
|
||||
enew!
|
||||
Assert Start(buffer)
|
||||
call AssertInitSuccess('foo', 'foo', 'foobar', '/foo/bar', '', buffer)
|
||||
execute 'buffer' . buffer
|
||||
|
||||
AssertEqual g:lsp_started, 1
|
@ -0,0 +1,216 @@
|
||||
Before:
|
||||
runtime autoload/ale/lsp.vim
|
||||
|
||||
let g:message_list = []
|
||||
let b:conn = {
|
||||
\ 'id': 1,
|
||||
\ 'is_tsserver': 0,
|
||||
\ 'data': '',
|
||||
\ 'root': '/foo/bar',
|
||||
\ 'open_documents': {},
|
||||
\ 'initialized': 0,
|
||||
\ 'init_request_id': 0,
|
||||
\ 'init_options': {},
|
||||
\ 'config': {},
|
||||
\ 'callback_list': [],
|
||||
\ 'message_queue': [],
|
||||
\ 'init_queue': [],
|
||||
\ 'capabilities': {
|
||||
\ 'hover': 0,
|
||||
\ 'rename': 0,
|
||||
\ 'references': 0,
|
||||
\ 'completion': 0,
|
||||
\ 'completion_trigger_characters': [],
|
||||
\ 'definition': 0,
|
||||
\ 'symbol_search': 0,
|
||||
\ 'code_actions': 0,
|
||||
\ },
|
||||
\}
|
||||
|
||||
function! ale#lsp#Send(conn_id, message) abort
|
||||
call add(g:message_list, a:message)
|
||||
|
||||
return 42
|
||||
endfunction
|
||||
|
||||
After:
|
||||
unlet! b:conn
|
||||
unlet! g:message_list
|
||||
|
||||
runtime autoload/ale/lsp.vim
|
||||
|
||||
Execute(Messages with no method and capabilities should initialize projects):
|
||||
call ale#lsp#HandleInitResponse(b:conn, {
|
||||
\ 'result': {'capabilities': {}},
|
||||
\})
|
||||
|
||||
AssertEqual 1, b:conn.initialized
|
||||
AssertEqual [[1, 'initialized', {}]], g:message_list
|
||||
|
||||
Execute(Other messages should not initialize projects):
|
||||
call ale#lsp#HandleInitResponse(b:conn, {'method': 'lolwat'})
|
||||
|
||||
AssertEqual 0, b:conn.initialized
|
||||
AssertEqual [], g:message_list
|
||||
|
||||
call ale#lsp#HandleInitResponse(b:conn, {'result': {'x': {}}})
|
||||
|
||||
AssertEqual 0, b:conn.initialized
|
||||
AssertEqual [], g:message_list
|
||||
|
||||
Execute(Capabilities should bet set up correctly):
|
||||
call ale#lsp#HandleInitResponse(b:conn, {
|
||||
\ 'jsonrpc': '2.0',
|
||||
\ 'id': 1,
|
||||
\ 'result': {
|
||||
\ 'capabilities': {
|
||||
\ 'renameProvider': v:true,
|
||||
\ 'executeCommandProvider': {
|
||||
\ 'commands': [],
|
||||
\ },
|
||||
\ 'hoverProvider': v:true,
|
||||
\ 'documentSymbolProvider': v:true,
|
||||
\ 'documentRangeFormattingProvider': v:true,
|
||||
\ 'codeLensProvider': {
|
||||
\ 'resolveProvider': v:false
|
||||
\ },
|
||||
\ 'referencesProvider': v:true,
|
||||
\ 'textDocumentSync': 2,
|
||||
\ 'documentFormattingProvider': v:true,
|
||||
\ 'codeActionProvider': v:true,
|
||||
\ 'signatureHelpProvider': {
|
||||
\ 'triggerCharacters': ['(', ','],
|
||||
\ },
|
||||
\ 'completionProvider': {
|
||||
\ 'triggerCharacters': ['.'],
|
||||
\ 'resolveProvider': v:false
|
||||
\ },
|
||||
\ 'definitionProvider': v:true,
|
||||
\ 'experimental': {},
|
||||
\ 'documentHighlightProvider': v:true,
|
||||
\ 'workspaceSymbolProvider': v:true
|
||||
\ },
|
||||
\ },
|
||||
\})
|
||||
|
||||
AssertEqual 1, b:conn.initialized
|
||||
AssertEqual
|
||||
\ {
|
||||
\ 'completion_trigger_characters': ['.'],
|
||||
\ 'completion': 1,
|
||||
\ 'references': 1,
|
||||
\ 'hover': 1,
|
||||
\ 'definition': 1,
|
||||
\ 'symbol_search': 1,
|
||||
\ 'rename': 1,
|
||||
\ 'code_actions': 1,
|
||||
\ },
|
||||
\ b:conn.capabilities
|
||||
AssertEqual [[1, 'initialized', {}]], g:message_list
|
||||
|
||||
Execute(Disabled capabilities should be recognised correctly):
|
||||
call ale#lsp#HandleInitResponse(b:conn, {
|
||||
\ 'jsonrpc': '2.0',
|
||||
\ 'id': 1,
|
||||
\ 'result': {
|
||||
\ 'capabilities': {
|
||||
\ 'renameProvider': v:false,
|
||||
\ 'executeCommandProvider': {
|
||||
\ 'commands': [],
|
||||
\ },
|
||||
\ 'hoverProvider': v:false,
|
||||
\ 'documentSymbolProvider': v:true,
|
||||
\ 'documentRangeFormattingProvider': v:true,
|
||||
\ 'codeLensProvider': {
|
||||
\ 'resolveProvider': v:false
|
||||
\ },
|
||||
\ 'referencesProvider': v:false,
|
||||
\ 'textDocumentSync': 2,
|
||||
\ 'documentFormattingProvider': v:true,
|
||||
\ 'codeActionProvider': v:false,
|
||||
\ 'signatureHelpProvider': {
|
||||
\ 'triggerCharacters': ['(', ','],
|
||||
\ },
|
||||
\ 'definitionProvider': v:false,
|
||||
\ 'experimental': {},
|
||||
\ 'documentHighlightProvider': v:true,
|
||||
\ },
|
||||
\ },
|
||||
\})
|
||||
|
||||
AssertEqual 1, b:conn.initialized
|
||||
AssertEqual
|
||||
\ {
|
||||
\ 'completion_trigger_characters': [],
|
||||
\ 'completion': 0,
|
||||
\ 'references': 0,
|
||||
\ 'hover': 0,
|
||||
\ 'definition': 0,
|
||||
\ 'symbol_search': 0,
|
||||
\ 'rename': 0,
|
||||
\ 'code_actions': 0,
|
||||
\ },
|
||||
\ b:conn.capabilities
|
||||
AssertEqual [[1, 'initialized', {}]], g:message_list
|
||||
|
||||
Execute(Capabilities should be enabled when send as Dictionaries):
|
||||
call ale#lsp#HandleInitResponse(b:conn, {
|
||||
\ 'jsonrpc': '2.0',
|
||||
\ 'id': 1,
|
||||
\ 'result': {
|
||||
\ 'capabilities': {
|
||||
\ 'renameProvider': {},
|
||||
\ 'executeCommandProvider': {
|
||||
\ 'commands': [],
|
||||
\ },
|
||||
\ 'hoverProvider': {},
|
||||
\ 'documentSymbolProvider': v:true,
|
||||
\ 'documentRangeFormattingProvider': v:true,
|
||||
\ 'codeLensProvider': {
|
||||
\ 'resolveProvider': v:false
|
||||
\ },
|
||||
\ 'completionProvider': {
|
||||
\ 'triggerCharacters': ['.'],
|
||||
\ 'resolveProvider': v:false
|
||||
\ },
|
||||
\ 'referencesProvider': {},
|
||||
\ 'textDocumentSync': 2,
|
||||
\ 'documentFormattingProvider': v:true,
|
||||
\ 'codeActionProvider': v:true,
|
||||
\ 'signatureHelpProvider': {
|
||||
\ 'triggerCharacters': ['(', ','],
|
||||
\ },
|
||||
\ 'definitionProvider': {},
|
||||
\ 'typeDefinitionProvider': {},
|
||||
\ 'implementationProvider': {},
|
||||
\ 'experimental': {},
|
||||
\ 'documentHighlightProvider': v:true,
|
||||
\ 'workspaceSymbolProvider': {}
|
||||
\ },
|
||||
\ },
|
||||
\})
|
||||
|
||||
AssertEqual 1, b:conn.initialized
|
||||
AssertEqual
|
||||
\ {
|
||||
\ 'completion_trigger_characters': ['.'],
|
||||
\ 'completion': 1,
|
||||
\ 'references': 1,
|
||||
\ 'hover': 1,
|
||||
\ 'definition': 1,
|
||||
\ 'typeDefinition': 1,
|
||||
\ 'implementation': 1,
|
||||
\ 'symbol_search': 1,
|
||||
\ 'rename': 1,
|
||||
\ 'code_actions': 1,
|
||||
\ },
|
||||
\ b:conn.capabilities
|
||||
AssertEqual [[1, 'initialized', {}]], g:message_list
|
||||
|
||||
Execute(Results that are not dictionaries should be handled correctly):
|
||||
call ale#lsp#HandleInitResponse(b:conn, {
|
||||
\ 'jsonrpc': '2.0',
|
||||
\ 'id': 1,
|
||||
\ 'result': v:null,
|
||||
\})
|
||||
AssertEqual [], g:message_list
|
257
sources_non_forked/ale/test/lsp/test_read_lsp_diagnostics.vader
Normal file
257
sources_non_forked/ale/test/lsp/test_read_lsp_diagnostics.vader
Normal file
@ -0,0 +1,257 @@
|
||||
Before:
|
||||
function Range(start_line, start_char, end_line, end_char) abort
|
||||
return {
|
||||
\ 'start': {'line': a:start_line, 'character': a:start_char},
|
||||
\ 'end': {'line': a:end_line, 'character': a:end_char},
|
||||
\}
|
||||
endfunction
|
||||
|
||||
After:
|
||||
delfunction Range
|
||||
|
||||
Execute(ale#lsp#response#ReadDiagnostics() should handle errors):
|
||||
AssertEqual [
|
||||
\ {
|
||||
\ 'type': 'E',
|
||||
\ 'text': 'Something went wrong!',
|
||||
\ 'lnum': 3,
|
||||
\ 'col': 11,
|
||||
\ 'end_lnum': 5,
|
||||
\ 'end_col': 15,
|
||||
\ 'code': 'some-error',
|
||||
\ }
|
||||
\ ],
|
||||
\ ale#lsp#response#ReadDiagnostics({'params': {'uri': 'filename.ts', 'diagnostics': [
|
||||
\ {
|
||||
\ 'severity': 1,
|
||||
\ 'range': Range(2, 10, 4, 15),
|
||||
\ 'code': 'some-error',
|
||||
\ 'message': 'Something went wrong!',
|
||||
\ },
|
||||
\ ]}})
|
||||
|
||||
Execute(ale#lsp#response#ReadDiagnostics() should handle warnings):
|
||||
AssertEqual [
|
||||
\ {
|
||||
\ 'type': 'W',
|
||||
\ 'text': 'Something went wrong!',
|
||||
\ 'lnum': 2,
|
||||
\ 'col': 4,
|
||||
\ 'end_lnum': 2,
|
||||
\ 'end_col': 3,
|
||||
\ 'code': 'some-warning',
|
||||
\ }
|
||||
\ ],
|
||||
\ ale#lsp#response#ReadDiagnostics({'params': {'uri': 'filename.ts', 'diagnostics': [
|
||||
\ {
|
||||
\ 'severity': 2,
|
||||
\ 'range': Range(1, 3, 1, 3),
|
||||
\ 'code': 'some-warning',
|
||||
\ 'message': 'Something went wrong!',
|
||||
\ },
|
||||
\ ]}})
|
||||
|
||||
Execute(ale#lsp#response#ReadDiagnostics() should treat messages with missing severity as errors):
|
||||
AssertEqual [
|
||||
\ {
|
||||
\ 'type': 'E',
|
||||
\ 'text': 'Something went wrong!',
|
||||
\ 'lnum': 3,
|
||||
\ 'col': 11,
|
||||
\ 'end_lnum': 5,
|
||||
\ 'end_col': 15,
|
||||
\ 'code': 'some-error',
|
||||
\ }
|
||||
\ ],
|
||||
\ ale#lsp#response#ReadDiagnostics({'params': {'uri': 'filename.ts', 'diagnostics': [
|
||||
\ {
|
||||
\ 'range': Range(2, 10, 4, 15),
|
||||
\ 'code': 'some-error',
|
||||
\ 'message': 'Something went wrong!',
|
||||
\ },
|
||||
\ ]}})
|
||||
|
||||
Execute(ale#lsp#response#ReadDiagnostics() should handle messages without codes):
|
||||
AssertEqual [
|
||||
\ {
|
||||
\ 'type': 'E',
|
||||
\ 'text': 'Something went wrong!',
|
||||
\ 'lnum': 3,
|
||||
\ 'col': 11,
|
||||
\ 'end_lnum': 5,
|
||||
\ 'end_col': 15,
|
||||
\ }
|
||||
\ ],
|
||||
\ ale#lsp#response#ReadDiagnostics({'params': {'uri': 'filename.ts', 'diagnostics': [
|
||||
\ {
|
||||
\ 'range': Range(2, 10, 4, 15),
|
||||
\ 'message': 'Something went wrong!',
|
||||
\ },
|
||||
\ ]}})
|
||||
|
||||
Execute(ale#lsp#response#ReadDiagnostics() should include sources in detail):
|
||||
AssertEqual [
|
||||
\ {
|
||||
\ 'type': 'E',
|
||||
\ 'text': 'Something went wrong!',
|
||||
\ 'detail': '[tslint] Something went wrong!',
|
||||
\ 'lnum': 10,
|
||||
\ 'col': 15,
|
||||
\ 'end_lnum': 12,
|
||||
\ 'end_col': 22,
|
||||
\ }
|
||||
\ ],
|
||||
\ ale#lsp#response#ReadDiagnostics({'params': {'uri': 'filename.ts', 'diagnostics': [
|
||||
\ {
|
||||
\ 'range': Range(9, 14, 11, 22),
|
||||
\ 'message': 'Something went wrong!',
|
||||
\ 'source': 'tslint',
|
||||
\ }
|
||||
\ ]}})
|
||||
|
||||
Execute(ale#lsp#response#ReadDiagnostics() should keep detail with line breaks but replace with spaces in text):
|
||||
AssertEqual [
|
||||
\ {
|
||||
\ 'type': 'E',
|
||||
\ 'text': 'cannot borrow `cap` as mutable more than once at a time mutable borrow starts here in previous iteration of loop',
|
||||
\ 'detail': "[rustc] cannot borrow `cap` as mutable\r\nmore than once at a time\n\nmutable borrow starts here\rin previous iteration of loop",
|
||||
\ 'lnum': 10,
|
||||
\ 'col': 15,
|
||||
\ 'end_lnum': 12,
|
||||
\ 'end_col': 22,
|
||||
\ }
|
||||
\ ],
|
||||
\ ale#lsp#response#ReadDiagnostics({'params': {'uri': 'filename.ts', 'diagnostics': [
|
||||
\ {
|
||||
\ 'range': Range(9, 14, 11, 22),
|
||||
\ 'message': "cannot borrow `cap` as mutable\r\nmore than once at a time\n\nmutable borrow starts here\rin previous iteration of loop",
|
||||
\ 'source': 'rustc',
|
||||
\ }
|
||||
\ ]}})
|
||||
|
||||
Execute(ale#lsp#response#ReadDiagnostics() should consider -1 to be a meaningless code):
|
||||
AssertEqual [
|
||||
\ {
|
||||
\ 'type': 'E',
|
||||
\ 'text': 'Something went wrong!',
|
||||
\ 'lnum': 3,
|
||||
\ 'col': 11,
|
||||
\ 'end_lnum': 5,
|
||||
\ 'end_col': 15,
|
||||
\ }
|
||||
\ ],
|
||||
\ ale#lsp#response#ReadDiagnostics({'params': {'uri': 'filename.ts', 'diagnostics': [
|
||||
\ {
|
||||
\ 'range': Range(2, 10, 4, 15),
|
||||
\ 'message': 'Something went wrong!',
|
||||
\ 'code': -1,
|
||||
\ },
|
||||
\ ]}})
|
||||
|
||||
Execute(ale#lsp#response#ReadDiagnostics() should handle multiple messages):
|
||||
AssertEqual [
|
||||
\ {
|
||||
\ 'type': 'E',
|
||||
\ 'text': 'Something went wrong!',
|
||||
\ 'lnum': 1,
|
||||
\ 'col': 3,
|
||||
\ 'end_lnum': 1,
|
||||
\ 'end_col': 2,
|
||||
\ },
|
||||
\ {
|
||||
\ 'type': 'W',
|
||||
\ 'text': 'A warning',
|
||||
\ 'lnum': 2,
|
||||
\ 'col': 5,
|
||||
\ 'end_lnum': 2,
|
||||
\ 'end_col': 4,
|
||||
\ },
|
||||
\ ],
|
||||
\ ale#lsp#response#ReadDiagnostics({'params': {'uri': 'filename.ts', 'diagnostics': [
|
||||
\ {
|
||||
\ 'range': Range(0, 2, 0, 2),
|
||||
\ 'message': 'Something went wrong!',
|
||||
\ },
|
||||
\ {
|
||||
\ 'severity': 2,
|
||||
\ 'range': Range(1, 4, 1, 4),
|
||||
\ 'message': 'A warning',
|
||||
\ },
|
||||
\ ]}})
|
||||
|
||||
Execute(ale#lsp#response#ReadDiagnostics() should use relatedInformation for detail):
|
||||
AssertEqual [
|
||||
\ {
|
||||
\ 'type': 'E',
|
||||
\ 'text': 'Something went wrong!',
|
||||
\ 'lnum': 1,
|
||||
\ 'col': 3,
|
||||
\ 'end_lnum': 1,
|
||||
\ 'end_col': 2,
|
||||
\ 'detail': "Something went wrong!\n/tmp/someotherfile.txt:43:80:\n\tmight be this"
|
||||
\ }
|
||||
\ ],
|
||||
\ ale#lsp#response#ReadDiagnostics({'params': {'uri': 'filename.ts', 'diagnostics': [
|
||||
\ {
|
||||
\ 'range': Range(0, 2, 0, 2),
|
||||
\ 'message': 'Something went wrong!',
|
||||
\ 'relatedInformation': [{
|
||||
\ 'message': 'might be this',
|
||||
\ 'location': {
|
||||
\ 'uri': 'file:///tmp/someotherfile.txt',
|
||||
\ 'range': {
|
||||
\ 'start': { 'line': 42, 'character': 79 },
|
||||
\ 'end': { 'line': 142, 'character': 179},
|
||||
\ }
|
||||
\ }
|
||||
\ }]
|
||||
\ }
|
||||
\ ]}})
|
||||
|
||||
Execute(ale#lsp#response#ReadTSServerDiagnostics() should handle tsserver responses):
|
||||
AssertEqual
|
||||
\ [
|
||||
\ {
|
||||
\ 'type': 'E',
|
||||
\ 'nr': 2365,
|
||||
\ 'code': '2365',
|
||||
\ 'text': 'Operator ''''+'''' cannot be applied to types ''''3'''' and ''''{}''''.',
|
||||
\ 'lnum': 1,
|
||||
\ 'col': 11,
|
||||
\ 'end_lnum': 1,
|
||||
\ 'end_col': 16,
|
||||
\ },
|
||||
\ ],
|
||||
\ ale#lsp#response#ReadTSServerDiagnostics({"seq":0,"type":"event","event":"semanticDiag","body":{"file":"/bar/foo.ts","diagnostics":[{"start":{"line":1,"offset":11},"end":{"line":1,"offset":17},"text":"Operator ''+'' cannot be applied to types ''3'' and ''{}''.","code":2365}]}})
|
||||
|
||||
Execute(ale#lsp#response#ReadTSServerDiagnostics() should handle warnings from tsserver):
|
||||
AssertEqual
|
||||
\ [
|
||||
\ {
|
||||
\ 'lnum': 27,
|
||||
\ 'col': 3,
|
||||
\ 'nr': 2515,
|
||||
\ 'code': '2515',
|
||||
\ 'end_lnum': 27,
|
||||
\ 'type': 'W',
|
||||
\ 'end_col': 13,
|
||||
\ 'text': 'Calls to ''console.log'' are not allowed. (no-console)',
|
||||
\ }
|
||||
\ ],
|
||||
\ ale#lsp#response#ReadTSServerDiagnostics({"seq":0,"type":"event","event":"semanticDiag","body":{"file":"<removed>","diagnostics":[{"start":{"line":27,"offset":3},"end":{"line":27,"offset":14},"text":"Calls to 'console.log' are not allowed. (no-console)","code":2515,"category":"warning","source":"tslint"}]}})
|
||||
|
||||
Execute(ale#lsp#response#ReadTSServerDiagnostics() should handle suggestions from tsserver):
|
||||
AssertEqual
|
||||
\ [
|
||||
\ {
|
||||
\ 'lnum': 27,
|
||||
\ 'col': 3,
|
||||
\ 'nr': 2515,
|
||||
\ 'code': '2515',
|
||||
\ 'end_lnum': 27,
|
||||
\ 'type': 'I',
|
||||
\ 'end_col': 13,
|
||||
\ 'text': 'Some info',
|
||||
\ }
|
||||
\ ],
|
||||
\ ale#lsp#response#ReadTSServerDiagnostics({"seq":0,"type":"event","event":"semanticDiag","body":{"file":"<removed>","diagnostics":[{"start":{"line":27,"offset":3},"end":{"line":27,"offset":14},"text":"Some info","code":2515,"category":"suggestion","source":"tslint"}]}})
|
98
sources_non_forked/ale/test/lsp/test_reset_lsp.vader
Normal file
98
sources_non_forked/ale/test/lsp/test_reset_lsp.vader
Normal file
@ -0,0 +1,98 @@
|
||||
Before:
|
||||
Save g:ale_enabled
|
||||
Save g:ale_set_signs
|
||||
Save g:ale_set_quickfix
|
||||
Save g:ale_set_loclist
|
||||
Save g:ale_set_highlights
|
||||
Save g:ale_echo_cursor
|
||||
|
||||
let g:ale_enabled = 0
|
||||
let g:ale_set_signs = 0
|
||||
let g:ale_set_quickfix = 0
|
||||
let g:ale_set_loclist = 0
|
||||
let g:ale_set_highlights = 0
|
||||
let g:ale_echo_cursor = 0
|
||||
|
||||
function EmptyString() abort
|
||||
return ''
|
||||
endfunction
|
||||
|
||||
call ale#engine#InitBufferInfo(bufnr(''))
|
||||
" Call this function first, so we can be sure the module is loaded before we
|
||||
" check if it exists.
|
||||
call ale#lsp_linter#ClearLSPData()
|
||||
|
||||
call ale#linter#Define('testft', {
|
||||
\ 'name': 'lsplinter',
|
||||
\ 'lsp': 'tsserver',
|
||||
\ 'executable': function('EmptyString'),
|
||||
\ 'command': function('EmptyString'),
|
||||
\ 'project_root': function('EmptyString'),
|
||||
\ 'language': function('EmptyString'),
|
||||
\})
|
||||
|
||||
call ale#linter#Define('testft', {
|
||||
\ 'name': 'otherlinter',
|
||||
\ 'callback': 'TestCallback',
|
||||
\ 'executable': has('win32') ? 'cmd': 'true',
|
||||
\ 'command': 'true',
|
||||
\ 'read_buffer': 0,
|
||||
\})
|
||||
|
||||
After:
|
||||
Restore
|
||||
|
||||
unlet! b:ale_save_event_fired
|
||||
|
||||
delfunction EmptyString
|
||||
call ale#linter#Reset()
|
||||
|
||||
Given testft(Some file with an imaginary filetype):
|
||||
Execute(ALEStopAllLSPs should clear the loclist):
|
||||
let g:ale_buffer_info[bufnr('')].loclist = [
|
||||
\ {
|
||||
\ 'text': 'a',
|
||||
\ 'lnum': 10,
|
||||
\ 'col': 0,
|
||||
\ 'bufnr': bufnr(''),
|
||||
\ 'vcol': 0,
|
||||
\ 'type': 'E',
|
||||
\ 'nr': -1,
|
||||
\ 'linter_name': 'lsplinter',
|
||||
\ },
|
||||
\ {
|
||||
\ 'text': 'a',
|
||||
\ 'lnum': 10,
|
||||
\ 'col': 0,
|
||||
\ 'bufnr': bufnr(''),
|
||||
\ 'vcol': 0,
|
||||
\ 'type': 'E',
|
||||
\ 'nr': -1,
|
||||
\ 'linter_name': 'otherlinter',
|
||||
\ },
|
||||
\]
|
||||
let g:ale_buffer_info[bufnr('')].active_linter_list = [
|
||||
\ {'name': 'lsplinter'},
|
||||
\ {'name': 'otherlinter'},
|
||||
\]
|
||||
|
||||
ALEStopAllLSPs
|
||||
|
||||
" The loclist should be updated.
|
||||
AssertEqual g:ale_buffer_info[bufnr('')].loclist, [
|
||||
\ {
|
||||
\ 'text': 'a',
|
||||
\ 'lnum': 10,
|
||||
\ 'col': 0,
|
||||
\ 'bufnr': bufnr(''),
|
||||
\ 'vcol': 0,
|
||||
\ 'type': 'E',
|
||||
\ 'nr': -1,
|
||||
\ 'linter_name': 'otherlinter',
|
||||
\ },
|
||||
\]
|
||||
|
||||
" The LSP linter should be removed from the active linter list.
|
||||
AssertEqual
|
||||
\ ['otherlinter'],
|
||||
\ map(copy(g:ale_buffer_info[bufnr('')].active_linter_list), 'v:val.name')
|
21
sources_non_forked/ale/test/lsp/test_update_config.vader
Normal file
21
sources_non_forked/ale/test/lsp/test_update_config.vader
Normal file
@ -0,0 +1,21 @@
|
||||
Before:
|
||||
runtime autoload/ale/lsp.vim
|
||||
|
||||
let g:conn_id = ale#lsp#Register('executable', '/foo/bar', {})
|
||||
|
||||
" Stub out this function, so we test updating configs.
|
||||
function! ale#lsp#Send(conn_id, message) abort
|
||||
endfunction
|
||||
|
||||
After:
|
||||
Restore
|
||||
|
||||
unlet! g:conn_id
|
||||
|
||||
runtime autoload/ale/lsp.vim
|
||||
|
||||
Execute(Only send updates when the configuration dictionary changes):
|
||||
AssertEqual 0, ale#lsp#UpdateConfig(g:conn_id, bufnr(''), {})
|
||||
AssertEqual 1, ale#lsp#UpdateConfig(g:conn_id, bufnr(''), {'a': 1})
|
||||
AssertEqual 0, ale#lsp#UpdateConfig(g:conn_id, bufnr(''), {'a': 1})
|
||||
AssertEqual 1, ale#lsp#UpdateConfig(g:conn_id, bufnr(''), {})
|
Reference in New Issue
Block a user