Before:
  Save g:ale_buffer_info
  Save g:ale_lsp_error_messages

  let g:ale_buffer_info = {}

  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,
  \     'type': 'E',
  \     'text': '1005: '','' 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,
  \     'type': 'E',
  \     'text': '1005: 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', {})