Include: include/setup.vader Execute (list: default for debug): Save g:neomake_test_messages, g:neomake_debug_list, g:neomake_verbose unlet! g:neomake_test_messages unlet! g:neomake_debug_list unlet! g:neomake_verbose AssertEqual neomake#list#List('loclist').debug, 0 let g:neomake_debug_list = 1 AssertEqual neomake#list#List('loclist').debug, 1 let g:neomake_test_messages = [] let g:neomake_debug_list = 0 AssertEqual neomake#list#List('loclist').debug, 0 unlet g:neomake_debug_list AssertEqual neomake#list#List('loclist').debug, 1 unlet g:neomake_test_messages let g:neomake_verbose = 3 AssertEqual neomake#list#List('loclist').debug, 1 Restore Execute (List: basic: loclist): new normal! oline2 normal! gg0 let maker = {} function! maker.get_list_entries(...) let b = bufnr('%') return [ \ {'text': '1', 'lnum': 1, 'bufnr': b}, \ {'text': '2', 'lnum': 2, 'col': 3, 'bufnr': b}, \ ] endfunction CallNeomake 1, [maker] AssertNeomakeMessage 'Adding 2 list entries.', 3 let list1 = neomake#list#get() " Location list window can be found after make run has finished. " (via last_make_id without patch-7.4.1895). if has('patch-7.4.1895') AssertEqual list1._get_loclist_win(), win_getid() else AssertEqual list1._get_loclist_win(), winnr() endif AssertEqual getpos('.'), [0, 1, 1, 0] NeomakeNextLoclist AssertEqual getpos('.'), [0, 2, 3, 0] NeomakePrevLoclist AssertEqual getpos('.'), [0, 1, 1, 0] AssertNeomakeMessageAbsent 'Creating new List object.' " Knows about loclist in new window for the same buffer. split AssertNeomakeMessageAbsent 'Creating new List object.' AssertEqual neomake#list#get(), list1 bwipe! Execute (List: basic: quickfix): new normal! oline2 normal! gg0 let maker = {} function! maker.get_list_entries(...) let b = bufnr('%') return [ \ {'text': '1', 'lnum': 1, 'bufnr': b}, \ {'text': '2', 'lnum': 2, 'col': 3, 'bufnr': b}, \ ] endfunction CallNeomake 0, [maker] AssertEqual getpos('.'), [0, 1, 1, 0] NeomakeNextQuickfix AssertEqual getpos('.'), [0, 2, 3, 0] NeomakePrevQuickfix AssertEqual getpos('.'), [0, 1, 1, 0] AssertNeomakeMessageAbsent 'Creating new List object.' bwipe! Execute (Sorting by location): let list = neomake#list#List('loclist') AssertEqual list.sort_by_location(), [] let input = [ \ {'lnum': 1, 'col': 2, 'bufnr': 1, 'type': ''}, \ {'lnum': 1, 'col': 5, 'bufnr': 2, 'type': ''}, \ {'lnum': 2, 'col': 1, 'bufnr': 1, 'type': ''}, \ {'lnum': 3, 'col': 5, 'bufnr': 1, 'type': ''}, \ {'lnum': 1, 'col': 2, 'bufnr': 1, 'type': 'E'}, \ ] call list.add_entries(input) AssertEqual list.sort_by_location(), [ \ {'lnum': 1, 'col': 2, 'bufnr': 1, 'type': 'E'}, \ {'lnum': 1, 'col': 2, 'bufnr': 1, 'type': ''}, \ {'lnum': 2, 'col': 1, 'bufnr': 1, 'type': ''}, \ {'lnum': 3, 'col': 5, 'bufnr': 1, 'type': ''}, \ {'lnum': 1, 'col': 5, 'bufnr': 2, 'type': ''}, \ ] AssertEqual input[-1].lnum, 1, 'does not sort list in-place' " Sorts newly added entries. call list.add_entries([ \ {'lnum': 1, 'col': 1, 'bufnr': 1, 'type': 'W'}, \ ]) AssertEqual list._sorted_entries_by_location, [ \ {'lnum': 1, 'col': 1, 'bufnr': 1, 'type': 'W'}, \ {'lnum': 1, 'col': 2, 'bufnr': 1, 'type': 'E'}, \ {'lnum': 1, 'col': 2, 'bufnr': 1, 'type': ''}, \ {'lnum': 2, 'col': 1, 'bufnr': 1, 'type': ''}, \ {'lnum': 3, 'col': 5, 'bufnr': 1, 'type': ''}, \ {'lnum': 1, 'col': 5, 'bufnr': 2, 'type': ''}, \ ] Execute (list: error with duplicate nmqfidx (debug=1)): let list = neomake#list#List('loclist') AssertEqual list.debug, 1 call list.add_entries([ \ {'lnum': 1, 'col': 1, 'bufnr': 1, 'type': 'W'}, \ ]) let list.entries[0].nmqfidx = 2 call list.add_entries([ \ {'lnum': 1, 'col': 1, 'bufnr': 1, 'type': 'W'}, \ ]) AssertNeomakeMessage 'Duplicate qf indexes in list entries: [2, 2].', 0 Execute (list: no error with duplicate nmqfidx (debug=0)): let list = neomake#list#List('loclist') let list.debug = 0 call list.add_entries([ \ {'lnum': 1, 'col': 1, 'bufnr': 1, 'type': 'W'}, \ ]) let list.entries[0].nmqfidx = 2 call list.add_entries([ \ {'lnum': 1, 'col': 1, 'bufnr': 1, 'type': 'W'}, \ ]) Execute (quickfix list: gets local and sorts): Save g:_neomake_info unlet g:_neomake_info let list = neomake#list#List('quickfix') AssertEqual list.sort_by_location(), [] call setqflist([ \ {'lnum': 1, 'col': 2, 'bufnr': 1}, \ {'lnum': 1, 'col': 5, 'bufnr': 1}, \ {'lnum': 2, 'col': 1, 'bufnr': 1}, \ {'lnum': 3, 'col': 5, 'bufnr': 1}, \ {'lnum': 1, 'col': 1, 'bufnr': 1}, \ ]) let list = neomake#list#get_qflist() AssertEqual map(list.sort_by_location(), '[v:val.lnum, v:val.col, v:val.bufnr]'), [ \ [1, 1, 1], \ [1, 2, 1], \ [1, 5, 1], \ [2, 1, 1], \ [3, 5, 1], \ ] Execute (neomake#list#next): new let bufnr = bufnr('%') normal! iline1 normal! oline2 normal! oline3 normal! gg^ call setloclist(0, [ \ {'lnum': 1, 'col': 1, 'bufnr': bufnr, 'text': 'idx1'}, \ {'lnum': 1, 'col': 5, 'bufnr': bufnr, 'text': 'idx2'}, \ {'lnum': 2, 'col': 1, 'bufnr': bufnr, 'text': 'idx3'}, \ {'lnum': 3, 'col': 5, 'bufnr': bufnr, 'text': 'idx4'}, \ {'lnum': 1, 'col': 2, 'bufnr': bufnr, 'text': 'idx5'}, \ ]) AssertEqual map(getloclist(0), '[v:val.lnum, v:val.text]'), \ [[1, 'idx1'], [1, 'idx2'], [2, 'idx3'], [3, 'idx4'], [1, 'idx5']], \ 'Sane lnums' Assert !exists('b:_neomake_info.loclist') Assert !exists('w:_neomake_info.loclist') AssertEqual getpos('.'), [0, 1, 1, 0] NeomakeNextLoclist AssertEqual getpos('.'), [0, 1, 2, 0] NeomakePrevLoclist AssertEqual getpos('.'), [0, 1, 1, 0] NeomakePrevLoclist AssertNeomakeMessage 'No more previous items.' 3NeomakeNextLoclist AssertEqual getpos('.'), [0, 2, 1, 0] " Goes to last entry, without error message (like with :lnext). 99NeomakeNextLoclist AssertEqual getpos('.'), [0, 3, 5, 0] " Error message when at last entry already (like with :lnext). 99NeomakeNextLoclist AssertEqual getpos('.'), [0, 3, 5, 0] AssertNeomakeMessage 'No more next items.' " count=0 gets handles as 1. 0NeomakePrevLoclist AssertEqual getpos('.'), [0, 2, 1, 0] 0NeomakeNextLoclist AssertEqual getpos('.'), [0, 3, 5, 0] bwipe! Execute (neomake#list#_diff_new_entries): AssertEqual neomake#list#_diff_new_entries([], []), {} AssertEqual neomake#list#_diff_new_entries([{}], [{'valid': 0}]), {'0': {'changed': {'valid': [1, 0]}}} AssertEqual neomake#list#_diff_new_entries([{}, {}], [{}, {'valid': 0}]), {'1': {'changed': {'valid': [1, 0]}}} " Handles different lengths. AssertEqual neomake#list#_diff_new_entries([{}], []), {} AssertEqual neomake#list#_diff_new_entries([], [{}]), {} AssertEqual neomake#list#_diff_new_entries([{'length': 1}], [{}]), {} AssertEqual neomake#list#_diff_new_entries([{'text': 'error'}], [{'text': 'error', 'valid': 1, 'pattern': ''}]), \ {} Execute (Does not create list unnecessarily): if !has('patch-8.0.1040') " 'efm' in setqflist/getqflist NeomakeTestsSkip 'only with efm parsing' else new lgetexpr 'init' let list = neomake#list#ListForMake({'options': {'file_mode': 1}}) let jobinfo = NeomakeTestsFakeJobinfo() let jobinfo.maker.errorformat = '%m' call list.add_lines_with_efm([], jobinfo) AssertEqual map(getloclist(0), 'v:val.text'), ['init'] bwipe endif Execute (list: error handling): new let orig_bufnr = bufnr('%') let list = neomake#list#List('loclist') let threw = 0 try call list._get_loclist_win() catch AssertEqual v:exception, 'cannot handle type=loclist without make_info' let threw = 1 endtry AssertEqual threw, 1 " Invalid location list qfid (loclist). let jobinfo = NeomakeTestsFakeJobinfo() let list.make_info = neomake#GetStatus().make_info[-42] let threw = 0 try call list._get_fn_args('get') catch let threw = 1 AssertEqual v:exception, 'Neomake: could not find location list for make_id -42.' endtry AssertEqual threw, 1 " Uses winid from make_info. let list.make_info.options.winid = 1234 if has('patch-7.4.1895') AssertEqual list._get_fn_args('get'), [['getloclist', [1234]]] else let g:list = list AssertThrows call g:list._get_fn_args('get') AssertEqual g:vader_exception, 'Neomake: could not find location list for make_id -42.' unlet g:list endif unlet list.make_info.options.winid AssertEqual list._get_loclist_win(1), -1 " location list from another tab tabnew let w:neomake_make_ids = [-42] tabprev let threw = 0 try call list._get_fn_args('get') catch let threw = 1 AssertEqual v:exception, 'Neomake: trying to use location list from another tab (current=3 != target=4).' endtry AssertEqual threw, 1 AssertEqual list._get_loclist_win(1), -1 tabnext bwipe new let w:neomake_make_ids = [-42] AssertEqual list._get_fn_args('get'), [['getloclist', [0]]] AssertEqual list.need_init, 1 let fns_args = list._get_fn_args('set', ['item'], ' ') let title = 'Neomake[file]: buf:'.orig_bufnr.' (fake_jobinfo_name?)' if has('patch-7.4.2200') && has('patch-8.0.0657') let context = remove(fns_args[0][1][3], 'context') AssertEqual keys(context), ['neomake'] AssertEqual keys(context.neomake), ['make_info'] AssertEqual fns_args, \ [['setloclist', [0, [], ' ', {'title': title, 'items': ['item']}]]] elseif has('patch-7.4.2200') AssertEqual fns_args, \ [['setloclist', [0, ['item'], ' ']], ['setloclist', [0, [], 'a', {'title': title}]]] else AssertEqual fns_args, \ [['setloclist', [0, ['item'], ' ']]] endif wincmd p Assert !has_key(list, 'qfid') call list._call_qf_fn('set', [], ' ') if has('patch-8.0.1023') let list.qfid = list.qfid + 1 let list.make_info.options.winid = 1234 Assert !list._has_valid_qf() let threw = 0 try call list._get_fn_args('get') catch let threw = 1 AssertEqual v:exception, printf('Neomake: qfid %d for location list (1234) has become invalid.', list.qfid) endtry AssertEqual threw, 1 " Invalid location list qfid (qflist). let list.type = 'quickfix' let threw = 0 try call list._get_fn_args('get') catch let threw = 1 AssertEqual v:exception, printf('Neomake: qfid %d for quickfix list has become invalid.', list.qfid) endtry AssertEqual threw, 1 endif wincmd p bwipe bwipe Execute (list: add_lines_with_efm uses own list): new let jobinfo = NeomakeTestsFakeJobinfo() let jobinfo.maker.errorformat = '%m' let make_info = neomake#GetStatus().make_info[-42] let w:neomake_make_ids = [-42] let list = neomake#list#ListForMake(make_info) call list.add_lines_with_efm(['error1'], jobinfo) AssertEqual map(getloclist(0), 'v:val.text'), ['error1'] " Create new location list. lgetexpr 'new_list' call list.add_lines_with_efm(['error2'], jobinfo) if has('patch-8.0.1040') AssertEqual map(getloclist(0), 'v:val.text'), ['new_list'] lolder AssertEqual map(getloclist(0), 'v:val.text'), ['error1', 'error2'] else " TODO: check/fix this via nmcfg marker." AssertEqual map(getloclist(0), 'v:val.text'), ['new_list', 'error2'] lolder AssertEqual map(getloclist(0), 'v:val.text'), ['error1'] endif bwipe Execute (list: title): new let job1 = NeomakeTestsFakeJobinfo() let job1.maker.name = 'job1' let make_info = neomake#GetStatus().make_info[-42] let w:neomake_make_ids = [-42] let list = neomake#list#ListForMake(make_info) let prefix = 'Neomake[file]: buf:'.bufnr('%') AssertEqual list._get_title(), prefix.' (job1?)' let job2 = NeomakeTestsFakeJobinfo() let job2.maker.name = 'job2' let list.make_info.active_jobs = [job2] AssertEqual list._get_title(), prefix.' (job2..., job1?)' " Finished jobs with no entries are not displayed." let job3 = NeomakeTestsFakeJobinfo() let job3.maker.name = 'job3' let list.make_info.finished_jobs = [job3] AssertEqual list._get_title(), prefix.' (job3✓, job2..., job1?)' call list.add_entries_for_job([{'text': 'e2', 'bufnr': bufnr('%')}], job2) AssertEqual list._get_title(), prefix.' (job3✓, job2...(1), job1?)' call list.add_entries_for_job([{'text': 'e3', 'bufnr': bufnr('%')}], job3) AssertEqual list._get_title(), prefix.' (job3(1), job2...(1), job1?)' AssertEqual neomake#list#get_title('', 0, 'maker_info'), 'Neomake: maker_info' AssertEqual neomake#list#get_title('prefix', 0, 'maker_info'), 'Neomake[prefix]: maker_info' AssertEqual neomake#list#get_title('', 0, ''), 'Neomake' AssertEqual neomake#list#get_title('prefix', 0, ''), 'Neomake[prefix]' bwipe Execute (list: handles nmcfg marker): call neomake#quickfix#enable(1) try new let job1 = NeomakeTestsFakeJobinfo() let job1.maker.name = 'job1' let job2 = NeomakeTestsFakeJobinfo() let job2.maker.name = 'job2' let make_info = neomake#GetStatus().make_info[-42] let w:neomake_make_ids = [-42] let list = neomake#list#ListForMake(make_info) call list.add_entries_for_job([{'text': 'e1', 'bufnr': bufnr('%')}], job1) AssertEqual map(getloclist(0), 'v:val.text'), ["e1 nmcfg:{'short': 'job1', 'name': 'job1'}"] call list.add_entries_for_job([{'text': 'e2', 'bufnr': bufnr('%')}], job1) " NOTE: could be optimized to not add nmcfg in this case, but difficult " when list needs to be replaced. AssertEqual map(getloclist(0), 'v:val.text'), [ \ "e1 nmcfg:{'short': 'job1', 'name': 'job1'}", \ "e2 nmcfg:{'short': 'job1', 'name': 'job1'}", \ ] call list.add_entries_for_job([{'text': 'e3', 'bufnr': bufnr('%')}], job2) AssertEqual map(getloclist(0), 'v:val.text'), [ \ "e1 nmcfg:{'short': 'job1', 'name': 'job1'}", \ "e2 nmcfg:{'short': 'job1', 'name': 'job1'}", \ "e3 nmcfg:{'short': 'job2', 'name': 'job2'}", \ ] " Setting entries directly manages nmcfg. let before = getloclist(0) call list._replace_qflist_entries(list.entries) AssertEqual map(getloclist(0), 'v:val.text'), [ \ "e1 nmcfg:{'short': 'job1', 'name': 'job1'}", \ 'e2', \ "e3 nmcfg:{'short': 'job2', 'name': 'job2'}", \ ] bwipe finally call neomake#quickfix#disable() endtry Execute (list: handles invalid errorformat): Save &errorformat new " NOTE: needs to be global for lgetexpr. set errorformat=foo:%m:%l let jobinfo = NeomakeTestsFakeJobinfo() let make_info = neomake#GetStatus().make_info[-42] let w:neomake_make_ids = [-42] let list = neomake#list#ListForMake(make_info) let jobinfo.maker.errorformat = ['invalid'] call list.add_lines_with_efm(['foo:msg:42'], jobinfo) if has('patch-8.0.1040') AssertNeomakeMessage "Failed to get items via efm-parsing. Invalid errorformat? (['invalid'])", 0, jobinfo else AssertNeomakeMessage "\\VFailed to set errorformat (['invalid']): \\.\\*", 0, jobinfo endif " Falls back to default errorformat. AssertEqual map(getloclist(0), '[v:val.text, v:val.lnum]'), [['msg', 42]] bwipe Execute (list: can reuse location list): " Not really used (automake uses location lists), but can be covered. let jobinfo = NeomakeTestsFakeJobinfo() let make_info = neomake#GetStatus().make_info[-42] let make_info.options.file_mode = 1 let list = neomake#list#ListForMake(make_info) new let w:neomake_make_ids = [-42] call list._call_qf_fn('set', [{'text': 'e1', 'lnum': 1, 'bufnr': bufnr('%')}], ' ') AssertEqual map(getloclist(0), 'v:val.text'), ['e1'] let list = neomake#list#ListForMake(make_info) " let list.need_init = 1 let list.reset_existing_qflist = 1 call list._call_qf_fn('set', [{'text': 'e2', 'lnum': 1, 'bufnr': bufnr('%')}], ' ') AssertEqual map(getloclist(0), 'v:val.text'), ['e2'] AssertNeomakeMessage 'Reusing location list for entries.' AssertNeomakeMessage '\V\^list: call: set: [0, [\.\*], ''r''' bwipe Execute (list: can reuse quickfix list): " Not really used (automake uses location lists), but can be covered. let jobinfo = NeomakeTestsFakeJobinfo() let make_info = neomake#GetStatus().make_info[-42] let make_info.options.file_mode = 0 let list = neomake#list#ListForMake(make_info) AssertEqual list.type, 'quickfix' call list._call_qf_fn('set', [{'text': 'e1', 'lnum': 1, 'bufnr': bufnr('%')}], ' ') AssertEqual map(getqflist(), 'v:val.text'), ['e1'] let list.need_init = 1 let list.reset_existing_qflist = 1 call list._call_qf_fn('set', [{'text': 'e2', 'lnum': 1, 'bufnr': bufnr('%')}], ' ') AssertEqual map(getqflist(), 'v:val.text'), ['e2'] AssertNeomakeMessage 'Reusing quickfix list for entries.' AssertNeomakeMessage '\V\^list: call: set: [[\.\*], ''r''' Execute (list: reused with automake (qflist)): if !has('patch-7.4.2200') NeomakeTestsSkip 'only with title support.' else Save g:neomake_enabled_makers let g:neomake_enabled_makers = [g:true_maker] " Simulate previous automake run. " (file_mode=0 should look at quickfix title only) call setloclist(0, [], ' ', {'title': 'Neomake[auto]'}) augroup neomake_tests au CursorHold * Neomake! augroup END doautocmd CursorHold NeomakeTestsWaitForFinishedJobs copen " Does not use "auto" by default, even though triggered through autocommand. " (apparently since `expand('')` is empty in tests). AssertEqual w:quickfix_title, 'Neomake[project]: true-maker✓' " Uses "auto" with options.automake. wincmd p call neomake#Make({'file_mode': 0, 'enabled_makers': [g:true_maker], 'automake': 1}) NeomakeTestsWaitForFinishedJobs copen AssertEqual w:quickfix_title, 'Neomake[auto]: true-maker✓' " Re-uses list with "auto" in qf title. wincmd p call neomake#Make({'file_mode': 0, 'enabled_makers': [g:true_maker], 'automake': 1}) NeomakeTestsWaitForFinishedJobs copen Assert w:quickfix_title =~# '\V:\?Neomake[auto]', 'unexpected title: '.w:quickfix_title AssertNeomakeMessage 'Reusing quickfix list for entries.', 3 cclose endif