xref: /vim-8.2.3635/src/testdir/test_tagjump.vim (revision fcfe1a9b)
1" Tests for tagjump (tags and special searches)
2
3" SEGV occurs in older versions.  (At least 7.4.1748 or older)
4func Test_ptag_with_notagstack()
5  set notagstack
6  call assert_fails('ptag does_not_exist_tag_name', 'E426')
7  set tagstack&vim
8endfunc
9
10func Test_cancel_ptjump()
11  set tags=Xtags
12  call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//",
13        \ "word\tfile1\tcmd1",
14        \ "word\tfile2\tcmd2"],
15        \ 'Xtags')
16
17  only!
18  call feedkeys(":ptjump word\<CR>\<CR>", "xt")
19  help
20  call assert_equal(2, winnr('$'))
21
22  call delete('Xtags')
23  set tags&
24  quit
25endfunc
26
27func Test_static_tagjump()
28  set tags=Xtags
29  call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//",
30        \ "one\tXfile1\t/^one/;\"\tf\tfile:\tsignature:(void)",
31        \ "word\tXfile2\tcmd2"],
32        \ 'Xtags')
33  new Xfile1
34  call setline(1, ['empty', 'one()', 'empty'])
35  write
36  tag one
37  call assert_equal(2, line('.'))
38
39  bwipe!
40  set tags&
41  call delete('Xtags')
42  call delete('Xfile1')
43endfunc
44
45func Test_duplicate_tagjump()
46  set tags=Xtags
47  call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//",
48        \ "thesame\tXfile1\t1;\"\td\tfile:",
49        \ "thesame\tXfile1\t2;\"\td\tfile:",
50        \ "thesame\tXfile1\t3;\"\td\tfile:",
51        \ ],
52        \ 'Xtags')
53  new Xfile1
54  call setline(1, ['thesame one', 'thesame two', 'thesame three'])
55  write
56  tag thesame
57  call assert_equal(1, line('.'))
58  tnext
59  call assert_equal(2, line('.'))
60  tnext
61  call assert_equal(3, line('.'))
62
63  bwipe!
64  set tags&
65  call delete('Xtags')
66  call delete('Xfile1')
67endfunc
68
69func Test_tagjump_switchbuf()
70  set tags=Xtags
71  call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//",
72        \ "second\tXfile1\t2",
73        \ "third\tXfile1\t3",],
74        \ 'Xtags')
75  call writefile(['first', 'second', 'third'], 'Xfile1')
76
77  enew | only
78  set switchbuf=
79  stag second
80  call assert_equal(2, winnr('$'))
81  call assert_equal(2, line('.'))
82  stag third
83  call assert_equal(3, winnr('$'))
84  call assert_equal(3, line('.'))
85
86  enew | only
87  set switchbuf=useopen
88  stag second
89  call assert_equal(2, winnr('$'))
90  call assert_equal(2, line('.'))
91  stag third
92  call assert_equal(2, winnr('$'))
93  call assert_equal(3, line('.'))
94
95  enew | only
96  set switchbuf=usetab
97  tab stag second
98  call assert_equal(2, tabpagenr('$'))
99  call assert_equal(2, line('.'))
100  1tabnext | stag third
101  call assert_equal(2, tabpagenr('$'))
102  call assert_equal(3, line('.'))
103
104  tabclose!
105  enew | only
106  call delete('Xfile1')
107  call delete('Xtags')
108  set tags&
109  set switchbuf&vim
110endfunc
111
112" Tests for [ CTRL-I and CTRL-W CTRL-I commands
113function Test_keyword_jump()
114  call writefile(["#include Xinclude", "",
115	      \ "",
116	      \ "/* test text test tex start here",
117	      \ "		some text",
118	      \ "		test text",
119	      \ "		start OK if found this line",
120	      \ "	start found wrong line",
121	      \ "test text"], 'Xtestfile')
122  call writefile(["/* test text test tex start here",
123	      \ "		some text",
124	      \ "		test text",
125	      \ "		start OK if found this line",
126	      \ "	start found wrong line",
127	      \ "test text"], 'Xinclude')
128  new Xtestfile
129  call cursor(1,1)
130  call search("start")
131  exe "normal! 5[\<C-I>"
132  call assert_equal("		start OK if found this line", getline('.'))
133  call cursor(1,1)
134  call search("start")
135  exe "normal! 5\<C-W>\<C-I>"
136  call assert_equal("		start OK if found this line", getline('.'))
137  enew! | only
138  call delete('Xtestfile')
139  call delete('Xinclude')
140endfunction
141
142" Test for jumping to a tag with 'hidden' set, with symbolic link in path of
143" tag.  This only works for Unix, because of the symbolic link.
144func Test_tag_symbolic()
145  if !has('unix')
146    return
147  endif
148  set hidden
149  call delete("Xtest.dir", "rf")
150  call system("ln -s . Xtest.dir")
151  " Create a tags file with the current directory name inserted.
152  call writefile([
153        \ "SECTION_OFF	" . getcwd() . "/Xtest.dir/Xtest.c	/^#define  SECTION_OFF  3$/",
154        \ '',
155        \ ], 'Xtags')
156  call writefile(['#define  SECTION_OFF  3',
157        \ '#define  NUM_SECTIONS 3'], 'Xtest.c')
158
159  " Try jumping to a tag, but with a path that contains a symbolic link.  When
160  " wrong, this will give the ATTENTION message.  The next space will then be
161  " eaten by hit-return, instead of moving the cursor to 'd'.
162  set tags=Xtags
163  enew!
164  call append(0, 'SECTION_OFF')
165  call cursor(1,1)
166  exe "normal \<C-]> "
167  call assert_equal('Xtest.c', expand('%:t'))
168  call assert_equal(2, col('.'))
169
170  set hidden&
171  set tags&
172  enew!
173  call delete('Xtags')
174  call delete('Xtest.c')
175  call delete("Xtest.dir", "rf")
176  %bwipe!
177endfunc
178
179" Tests for tag search with !_TAG_FILE_ENCODING.
180" Depends on the test83-tags2 and test83-tags3 files.
181func Test_tag_file_encoding()
182  if has('vms')
183    return
184  endif
185
186  if !has('iconv') || iconv("\x82\x60", "cp932", "utf-8") != "\uff21"
187    return
188  endif
189
190  let save_enc = &encoding
191  set encoding=utf8
192
193  let content = ['text for tags1', 'abcdefghijklmnopqrs']
194  call writefile(content, 'Xtags1.txt')
195  let content = ['text for tags2', 'ABC']
196  call writefile(content, 'Xtags2.txt')
197  let content = ['text for tags3', 'ABC']
198  call writefile(content, 'Xtags3.txt')
199  let content = ['!_TAG_FILE_ENCODING	utf-8	//', 'abcdefghijklmnopqrs	Xtags1.txt	/abcdefghijklmnopqrs']
200  call writefile(content, 'Xtags1')
201
202  " case1:
203  new
204  set tags=Xtags1
205  tag abcdefghijklmnopqrs
206  call assert_equal('Xtags1.txt', expand('%:t'))
207  call assert_equal('abcdefghijklmnopqrs', getline('.'))
208  close
209
210  " case2:
211  new
212  set tags=test83-tags2
213  tag /.BC
214  call assert_equal('Xtags2.txt', expand('%:t'))
215  call assert_equal('ABC', getline('.'))
216  close
217
218  " case3:
219  new
220  set tags=test83-tags3
221  tag abc50
222  call assert_equal('Xtags3.txt', expand('%:t'))
223  call assert_equal('ABC', getline('.'))
224  close
225
226  set tags&
227  let &encoding = save_enc
228  call delete('Xtags1.txt')
229  call delete('Xtags2.txt')
230  call delete('Xtags3.txt')
231  call delete('Xtags1')
232endfunc
233
234func Test_tagjump_etags()
235  if !has('emacs_tags')
236    return
237  endif
238  call writefile([
239        \ "void foo() {}",
240        \ "int main(int argc, char **argv)",
241        \ "{",
242        \ "\tfoo();",
243        \ "\treturn 0;",
244        \ "}",
245        \ ], 'Xmain.c')
246
247  call writefile([
248	\ "\x0c",
249        \ "Xmain.c,64",
250        \ "void foo() {}\x7ffoo\x011,0",
251        \ "int main(int argc, char **argv)\x7fmain\x012,14",
252	\ ], 'Xtags')
253  set tags=Xtags
254  ta foo
255  call assert_equal('void foo() {}', getline('.'))
256
257  call delete('Xtags')
258  call delete('Xmain.c')
259  bwipe!
260endfunc
261
262" Test for getting and modifying the tag stack
263func Test_getsettagstack()
264  call writefile(['line1', 'line2', 'line3'], 'Xfile1')
265  call writefile(['line1', 'line2', 'line3'], 'Xfile2')
266  call writefile(['line1', 'line2', 'line3'], 'Xfile3')
267
268  enew | only
269  call settagstack(1, {'items' : []})
270  call assert_equal(0, gettagstack(1).length)
271  call assert_equal([], gettagstack(1).items)
272  " Error cases
273  call assert_equal({}, gettagstack(100))
274  call assert_equal(-1, settagstack(100, {'items' : []}))
275  call assert_fails('call settagstack(1, [1, 10])', 'E715')
276  call assert_fails("call settagstack(1, {'items' : 10})", 'E714')
277  call assert_fails("call settagstack(1, {'items' : []}, 10)", 'E928')
278  call assert_fails("call settagstack(1, {'items' : []}, 'b')", 'E962')
279
280  set tags=Xtags
281  call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//",
282        \ "one\tXfile1\t1",
283        \ "three\tXfile3\t3",
284        \ "two\tXfile2\t2"],
285        \ 'Xtags')
286
287  let stk = []
288  call add(stk, {'bufnr' : bufnr('%'), 'tagname' : 'one',
289	\ 'from' : [bufnr('%'), line('.'), col('.'), 0], 'matchnr' : 1})
290  tag one
291  call add(stk, {'bufnr' : bufnr('%'), 'tagname' : 'two',
292	\ 'from' : [bufnr('%'), line('.'), col('.'), 0], 'matchnr' : 1})
293  tag two
294  call add(stk, {'bufnr' : bufnr('%'), 'tagname' : 'three',
295	\ 'from' : [bufnr('%'), line('.'), col('.'), 0], 'matchnr' : 1})
296  tag three
297  call assert_equal(3, gettagstack(1).length)
298  call assert_equal(stk, gettagstack(1).items)
299  " Check for default - current window
300  call assert_equal(3, gettagstack().length)
301  call assert_equal(stk, gettagstack().items)
302
303  " Try to set current index to invalid values
304  call settagstack(1, {'curidx' : -1})
305  call assert_equal(1, gettagstack().curidx)
306  call settagstack(1, {'curidx' : 50})
307  call assert_equal(4, gettagstack().curidx)
308
309  " Try pushing invalid items onto the stack
310  call settagstack(1, {'items' : []})
311  call settagstack(1, {'items' : ["plate"]}, 'a')
312  call assert_equal(0, gettagstack().length)
313  call assert_equal([], gettagstack().items)
314  call settagstack(1, {'items' : [{"tagname" : "abc"}]}, 'a')
315  call assert_equal(0, gettagstack().length)
316  call assert_equal([], gettagstack().items)
317  call settagstack(1, {'items' : [{"from" : 100}]}, 'a')
318  call assert_equal(0, gettagstack().length)
319  call assert_equal([], gettagstack().items)
320  call settagstack(1, {'items' : [{"from" : [2, 1, 0, 0]}]}, 'a')
321  call assert_equal(0, gettagstack().length)
322  call assert_equal([], gettagstack().items)
323
324  " Push one item at a time to the stack
325  call settagstack(1, {'items' : []})
326  call settagstack(1, {'items' : [stk[0]]}, 'a')
327  call settagstack(1, {'items' : [stk[1]]}, 'a')
328  call settagstack(1, {'items' : [stk[2]]}, 'a')
329  call settagstack(1, {'curidx' : 4})
330  call assert_equal({'length' : 3, 'curidx' : 4, 'items' : stk},
331        \ gettagstack(1))
332
333  " Try pushing items onto a full stack
334  for i in range(7)
335    call settagstack(1, {'items' : stk}, 'a')
336  endfor
337  call assert_equal(20, gettagstack().length)
338  call settagstack(1,
339        \ {'items' : [{'tagname' : 'abc', 'from' : [1, 10, 1, 0]}]}, 'a')
340  call assert_equal('abc', gettagstack().items[19].tagname)
341
342  " Tag with multiple matches
343  call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//",
344        \ "two\tXfile1\t1",
345        \ "two\tXfile2\t3",
346        \ "two\tXfile3\t2"],
347        \ 'Xtags')
348  call settagstack(1, {'items' : []})
349  tag two
350  tnext
351  tnext
352  call assert_equal(1, gettagstack().length)
353  call assert_equal(3, gettagstack().items[0].matchnr)
354
355  " Memory allocation failures
356  call test_alloc_fail(GetAllocId('tagstack_items'), 0, 0)
357  call assert_fails('call gettagstack()', 'E342:')
358  call test_alloc_fail(GetAllocId('tagstack_from'), 0, 0)
359  call assert_fails('call gettagstack()', 'E342:')
360  call test_alloc_fail(GetAllocId('tagstack_details'), 0, 0)
361  call assert_fails('call gettagstack()', 'E342:')
362
363  call settagstack(1, {'items' : []})
364  call delete('Xfile1')
365  call delete('Xfile2')
366  call delete('Xfile3')
367  call delete('Xtags')
368  set tags&
369endfunc
370
371func Test_tag_with_count()
372  call writefile([
373	\ 'test	Xtest.h	/^void test();$/;"	p	typeref:typename:void	signature:()',
374	\ ], 'Xtags')
375  call writefile([
376	\ 'main	Xtest.c	/^int main()$/;"	f	typeref:typename:int	signature:()',
377	\ 'test	Xtest.c	/^void test()$/;"	f	typeref:typename:void	signature:()',
378	\ ], 'Ytags')
379  cal writefile([
380	\ 'int main()',
381	\ 'void test()',
382	\ ], 'Xtest.c')
383  cal writefile([
384	\ 'void test();',
385	\ ], 'Xtest.h')
386  set tags=Xtags,Ytags
387
388  new Xtest.c
389  let tl = taglist('test', 'Xtest.c')
390  call assert_equal(tl[0].filename, 'Xtest.c')
391  call assert_equal(tl[1].filename, 'Xtest.h')
392
393  tag test
394  call assert_equal(bufname('%'), 'Xtest.c')
395  1tag test
396  call assert_equal(bufname('%'), 'Xtest.c')
397  2tag test
398  call assert_equal(bufname('%'), 'Xtest.h')
399
400  set tags&
401  call delete('Xtags')
402  call delete('Ytags')
403  bwipe Xtest.h
404  bwipe Xtest.c
405  call delete('Xtest.h')
406  call delete('Xtest.c')
407endfunc
408
409func Test_tagnr_recall()
410  call writefile([
411	\ 'test	Xtest.h	/^void test();$/;"	p',
412	\ 'main	Xtest.c	/^int main()$/;"	f',
413	\ 'test	Xtest.c	/^void test()$/;"	f',
414	\ ], 'Xtags')
415  cal writefile([
416	\ 'int main()',
417	\ 'void test()',
418	\ ], 'Xtest.c')
419  cal writefile([
420	\ 'void test();',
421	\ ], 'Xtest.h')
422  set tags=Xtags
423
424  new Xtest.c
425  let tl = taglist('test', 'Xtest.c')
426  call assert_equal(tl[0].filename, 'Xtest.c')
427  call assert_equal(tl[1].filename, 'Xtest.h')
428
429  2tag test
430  call assert_equal(bufname('%'), 'Xtest.h')
431  pop
432  call assert_equal(bufname('%'), 'Xtest.c')
433  tag
434  call assert_equal(bufname('%'), 'Xtest.h')
435
436  set tags&
437  call delete('Xtags')
438  bwipe Xtest.h
439  bwipe Xtest.c
440  call delete('Xtest.h')
441  call delete('Xtest.c')
442endfunc
443
444func Test_tag_line_toolong()
445  call writefile([
446	\ '1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678	django/contrib/admin/templates/admin/edit_inline/stacked.html	16;"	j	line:16	language:HTML'
447	\ ], 'Xtags')
448  set tags=Xtags
449  let old_vbs = &verbose
450  set verbose=5
451  " ":tjump" should give "tag not found" not "Format error in tags file"
452  call assert_fails('tj /foo', 'E426')
453  try
454    tj /foo
455  catch /^Vim\%((\a\+)\)\=:E431/
456    call assert_report(v:exception)
457  catch /.*/
458  endtry
459  call assert_equal('Ignoring long line in tags file', split(execute('messages'), '\n')[-1])
460  call writefile([
461	\ '123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567	django/contrib/admin/templates/admin/edit_inline/stacked.html	16;"	j	line:16	language:HTML'
462	\ ], 'Xtags')
463  call assert_fails('tj /foo', 'E426')
464  try
465    tj /foo
466  catch /^Vim\%((\a\+)\)\=:E431/
467    call assert_report(v:exception)
468  catch /.*/
469  endtry
470  call assert_equal('Ignoring long line in tags file', split(execute('messages'), '\n')[-1])
471  call delete('Xtags')
472  set tags&
473  let &verbose = old_vbs
474endfunc
475
476" vim: shiftwidth=2 sts=2 expandtab
477