Include: ../include/setup.vader

Execute (Setup: monkeypatch autoload/neomake/highlights.vim):
  " Monkeypatch to check setting of length.
  runtime autoload/neomake/highlights.vim
  Save g:neomake_tests_highlight_lengths
  let g:neomake_tests_highlight_lengths = []

  function! neomake#highlights#AddHighlight(entry, ...) abort
    let bufnr = get(a:entry, 'bufnr', -1)
    if !has_key(g:neomake_tests_highlight_lengths, bufnr)
      let g:neomake_tests_highlight_lengths[bufnr] = []
    endif
    call add(g:neomake_tests_highlight_lengths[bufnr],
    \ [get(a:entry, 'lnum', -1), get(a:entry, 'length', -1)])
  endfunction

Execute (vimlint: length postprocessing):
  let g:neomake_tests_highlight_lengths = {}
  new
  noautocmd edit tests/fixtures/vim/func-with-errors.vim
  let maker = neomake#makers#ft#vim#vimlint()
  let maker.exe = 'cat'
  let maker.args = 'tests/fixtures/vim/func-with-errors.vim.output'
  let maker.append_file = 0

  CallNeomake 1, [maker]

  let bufnr = bufnr('%')
  AssertEqualQf getloclist(0), [{
    \ 'lnum': 2,
    \ 'bufnr': bufnr,
    \ 'col': 6,
    \ 'valid': 1,
    \ 'vcol': 0,
    \ 'nr': 101,
    \ 'type': 'E',
    \ 'pattern': '',
    \ 'text': 'undefined variable `l:something`',
    \ }, {
    \ 'lnum': 5,
    \ 'bufnr': bufnr,
    \ 'col': 9,
    \ 'valid': 1,
    \ 'vcol': 0,
    \ 'nr': 104,
    \ 'type': 'E',
    \ 'pattern': '',
    \ 'text': 'variable may not be initialized on some execution path: `l:foo`',
    \ }]

  AssertEqual {string(bufnr): [[2, 11], [5, 3]]}, g:neomake_tests_highlight_lengths
  bwipe

Execute (vint: highlights syntax error for command):
  let g:neomake_tests_highlight_lengths = {}
  new
  file file1.vim
  norm! iwhile 1
  norm! oendfor
  let vint_maker = neomake#makers#ft#vim#vint()
  let vint_maker.exe = 'printf'
  let vint_maker.args = ["file1.vim:2:1:error:E588: :endfor without :for (SyntaxError)"]
  let vint_maker.append_file = 0

  CallNeomake 1, [vint_maker]
  let bufnr = bufnr('%')
  AssertEqualQf getloclist(0), [{
  \ 'lnum': 2,
  \ 'bufnr': bufnr,
  \ 'col': 1,
  \ 'valid': 1,
  \ 'vcol': 0,
  \ 'nr': 588,
  \ 'type': 'e',
  \ 'pattern': '',
  \ 'text': ':endfor without :for (SyntaxError)'}]
  bwipe!
  AssertEqual {string(bufnr): [[2, 6]]}, g:neomake_tests_highlight_lengths

Execute (get_list_entries: based on example from doc):
  let g:neomake_tests_highlight_lengths = {}
  new
  call g:NeomakeSetupAutocmdWrappers()
  let buf1 = bufnr('%')
  file get_list_entries_buf1

  let winnr = winnr()

  let maker = {'name': 'My maker', 'my_orig_bufnr': buf1}
  function! maker.get_list_entries(jobinfo) abort
    " Change bufnr.
    new
    return [
      \ {'text': 'Some error', 'lnum': 1, 'bufnr': a:jobinfo.bufnr},
      \ {'text': 'Some warning without bufnr', 'type': 'W', 'lnum': 2,
      \  'col': 1, 'length': 5},
      \ {'text': 'Some warning', 'type': 'W', 'lnum': 2, 'col': 1,
      \  'bufnr': a:jobinfo.maker.my_orig_bufnr, 'length': 2},
      \ {'text': 'Some info', 'type': 'I', 'lnum': 3, 'col': 1,
      \  'filename': '/path/to/file'},
      \ {'text': 'Some non-type', 'type': '', 'lnum': 4, 'col': 1, 'length': 23,
      \  'filename': 'get_list_entries_buf1'},
      \ ]
  endfunction
  call neomake#Make(1, [maker])
  AssertNeomakeMessage 'Queuing action ProcessEntries for BufEnter, WinEnter.'
  AssertEqual {}, g:neomake_tests_highlight_lengths, 'No highlights have been added yet'
  AssertEqual [], getloclist(0)

  wincmd p
  AssertEqual winnr, winnr()

  let llist = getloclist(0)

  " Check that unlisted buffer was created for filename.
  let unlisted_bufnr = bufnr('/path/to/file')
  Assert !empty(unlisted_bufnr), 'Unlisted buffer was created (1)'
  Assert !buflisted(unlisted_bufnr), 'Unlisted buffer was created (2)'

  AssertEqual {
  \ string(buf1): [[1, -1], [2, 2], [4, 23]],
  \ string(unlisted_bufnr): [[3, -1]]}, g:neomake_tests_highlight_lengths

  " Check that existing buffer was used for filename.
  AssertEqual llist[4].bufnr, buf1, 'get_list_entries_buf1 was picked up'

  AssertNeomakeMessage "Entry 2 differs after adding: {'changed': {'valid': [1, 0]}}.", 3
  AssertNeomakeMessage "Entry 4 differs after adding: {'changed': {'bufnr': [0, ".unlisted_bufnr."]}, 'removed': {'filename': '/path/to/file'}}.", 3
  AssertNeomakeMessage "Entry 5 differs after adding: {'changed': {'bufnr': [0, ".buf1."]}, 'removed': {'filename': 'get_list_entries_buf1'}}.", 3

  AssertEqualQf llist, [
  \ {'lnum': 1, 'bufnr': buf1, 'col': 0, 'valid': 1, 'vcol': 0, 'nr': -1,
  \  'type': 'W', 'pattern': '', 'text': 'Some error'},
  \ {'lnum': 2, 'bufnr': 0, 'col': 1, 'valid': 0, 'vcol': 0, 'nr': -1,
  \  'type': 'W', 'pattern': '', 'text': 'Some warning without bufnr'},
  \ {'lnum': 2, 'bufnr': buf1, 'col': 1, 'valid': 1, 'vcol': 0, 'nr': -1,
  \  'type': 'W', 'pattern': '', 'text': 'Some warning'},
  \ {'lnum': 3, 'bufnr': unlisted_bufnr, 'col': 1, 'valid': 1, 'vcol': 0, 'nr': -1,
  \  'type': 'I', 'pattern': '', 'text': 'Some info'},
  \ {'lnum': 4, 'bufnr': buf1, 'col': 1, 'valid': 1, 'vcol': 0, 'nr': -1,
  \  'type': '', 'pattern': '', 'text': 'Some non-type'} ]
  wincmd p
  bwipe
  bwipe
  exe 'bwipe '.unlisted_bufnr
  AssertEqual len(g:neomake_test_countschanged), 1
  AssertEqual len(g:neomake_test_finished), 1
  AssertEqual len(g:neomake_test_jobfinished), 1

Execute (cargo error message):
  let g:neomake_tests_highlight_lengths = {}
  new
  file build/lib.rs
  let cargo = NeomakeTestsGetMakerWithOutput(neomake#makers#ft#rust#cargo(),
    \ '../tests/fixtures/rust/cargo_error.json')

  call neomake#Make(1, [cargo])
  NeomakeTestsWaitForFinishedJobs

  let bufnr = bufnr('%')
  AssertEqualQf getloclist(0), [{
    \ 'type': 'E',
    \ 'bufnr': bufnr,
    \ 'nr': 308,
    \ 'lnum': 19,
    \ 'col': 46,
    \ 'valid': 1,
    \ 'vcol': 0,
    \ 'pattern': '',
    \ 'text': 'mismatched types: expected str, found struct `proc_macro::TokenStream`'
    \ }, {
    \ 'type': 'E',
    \ 'bufnr': bufnr,
    \ 'nr': 308,
    \ 'lnum': 25,
    \ 'col': 1,
    \ 'valid': 1,
    \ 'vcol': 0,
    \ 'pattern': '',
    \ 'text': 'mismatched types: expected str, found struct `proc_macro::TokenStream`'
    \ }, {
    \ 'type': 'I',
    \ 'bufnr':  bufnr,
    \ 'nr': 308,
    \ 'lnum': 25,
    \ 'col': 1,
    \ 'valid': 1,
    \ 'vcol': 0,
    \ 'pattern': '',
    \ 'text': 'found type `&proc_macro::TokenStream`'
    \ }]

  " TODO: should not call it for the same highlight twice?!
  AssertEqual {string(bufnr): [[19, 2], [25, 40], [25, 40]]}, g:neomake_tests_highlight_lengths
  bwipe

Execute (cargo warning message):
  let g:neomake_tests_highlight_lengths = {}
  new
  file build/add_assign_like.rs
  let cargo = NeomakeTestsGetMakerWithOutput(neomake#makers#ft#rust#cargo(),
    \ '../tests/fixtures/rust/cargo_warning.json')

  call neomake#Make(1, [cargo])
  NeomakeTestsWaitForFinishedJobs

  let bufnr = bufnr('%')
  AssertEqualQf getloclist(0), [{
    \ 'type': 'W',
    \ 'bufnr': bufnr,
    \ 'nr': -1,
    \ 'lnum': 2,
    \ 'col': 24,
    \ 'valid': 1,
    \ 'vcol': 0,
    \ 'pattern': '',
    \ 'text': 'unused import: `Variant`, #[warn(unused_imports)] on by default'}]
  AssertEqual {string(bufnr): [[2, 7]]}, g:neomake_tests_highlight_lengths
  bwipe

Execute (cargo warning for file that is not open):
  let g:neomake_tests_highlight_lengths = {}
  new
  file build/some_other_file.rs

  " Uses build/add_assign_like.rs.
  let cargo = NeomakeTestsGetMakerWithOutput(neomake#makers#ft#rust#cargo(),
    \ '../tests/fixtures/rust/cargo_warning.json')

  call neomake#Make(1, [cargo])
  NeomakeTestsWaitForFinishedJobs

  let unlisted_bufnr = bufnr('^build/add_assign_like.rs$')
  AssertNotEqual -1, unlisted_bufnr

  AssertEqualQf getloclist(0), [{
    \ 'type': 'W',
    \ 'bufnr': unlisted_bufnr,
    \ 'nr': -1,
    \ 'lnum': 2,
    \ 'col': 24,
    \ 'valid': 1,
    \ 'vcol': 0,
    \ 'pattern': '',
    \ 'text': 'unused import: `Variant`, #[warn(unused_imports)] on by default'}]
  AssertEqual {string(unlisted_bufnr): [[2, 7]]}, g:neomake_tests_highlight_lengths
  bwipe
  exe 'bwipe' unlisted_bufnr

Execute (cargo error message children):
  let g:neomake_tests_highlight_lengths = {}
  new
  file tests/from.rs
  let cargo = NeomakeTestsGetMakerWithOutput(neomake#makers#ft#rust#cargo(),
    \ '../tests/fixtures/rust/cargo_error_children.json')

  call neomake#Make(1, [cargo])
  NeomakeTestsWaitForFinishedJobs

  let bufnr = bufnr('%')
  AssertEqualQf getloclist(0), [{
    \ 'type': 'E',
    \ 'bufnr': bufnr,
    \ 'nr': -1,
    \ 'lnum': 11,
    \ 'col': 10,
    \ 'valid': 1,
    \ 'vcol': 0,
    \ 'pattern': '',
    \ 'text': 'custom derive attribute panicked. message: Only structs and enums can derive From'}]
  AssertEqual {string(bufnr): [[11, 4]]}, g:neomake_tests_highlight_lengths
  bwipe

Execute (Teardown: undo monkeypatching):
  " Restore if not profiling.
  if !v:profiling
    runtime autoload/neomake/highlights.vim
  endif