Before: Save g:ale_buffer_info Save g:ale_lsp_error_messages unlet! g:ale_lsp_error_messages call ale#test#SetDirectory('/testplugin/test') After: Restore 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 call ale#test#SetFilename('filename.ts') call ale#engine#InitBufferInfo(bufnr('')) " 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': g:dir . '/filename.ts', \ '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': g:dir . '/filename.ts', \ 'diagnostics':[ \ ], \ }, \}) AssertEqual \ [ \ { \ 'lnum': 1, \ 'bufnr': bufnr(''), \ 'col': 14, \ 'vcol': 0, \ 'nr': 1005, \ 'code': '1005', \ 'type': 'E', \ 'text': ''','' expected.', \ 'valid': 1, \ 'pattern': '', \ }, \ ], \ ale#test#GetLoclistWithoutModule() " After we get empty syntax errors, we should clear them. call ale#lsp_linter#HandleLSPResponse(1, { \ 'seq': 0, \ 'type': 'event', \ 'event': 'syntaxDiag', \ 'body': { \ 'file': g:dir . '/filename.ts', \ 'diagnostics':[ \ ], \ }, \}) AssertEqual \ [ \ ], \ ale#test#GetLoclistWithoutModule() Execute(tsserver semantic error responses should be handled correctly): runtime ale_linters/typescript/tsserver.vim call ale#test#SetFilename('filename.ts') call ale#engine#InitBufferInfo(bufnr('')) " 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': g:dir . '/filename.ts', \ 'diagnostics':[ \ ], \ }, \}) call ale#lsp_linter#HandleLSPResponse(1, { \ 'seq': 0, \ 'type': 'event', \ 'event': 'semanticDiag', \ 'body': { \ 'file': g:dir . '/filename.ts', \ '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, \ 'code': '1005', \ 'type': 'E', \ 'text': 'Some semantic error', \ 'valid': 1, \ 'pattern': '', \ }, \ ], \ ale#test#GetLoclistWithoutModule() " After we get empty syntax errors, we should clear them. call ale#lsp_linter#HandleLSPResponse(1, { \ 'seq': 0, \ 'type': 'event', \ 'event': 'semanticDiag', \ 'body': { \ 'file': g:dir . '/filename.ts', \ 'diagnostics':[ \ ], \ }, \}) AssertEqual \ [ \ ], \ ale#test#GetLoclistWithoutModule() 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', {})