blob: 02cf2d1c484302d93552f138959a223711a6f06e [file] [log] [blame]
Bram Moolenaar5d7ead32018-02-27 17:17:42 +01001" Test various aspects of the Vim script language.
Bram Moolenaar4119cf82016-01-17 14:59:01 +01002" Most of this was formerly in test49.
Bram Moolenaarf49e2402015-12-30 15:59:25 +01003
Bram Moolenaar8c5a2782019-08-07 23:07:07 +02004source check.vim
Bram Moolenaar93344c22019-08-14 21:12:05 +02005source shared.vim
Bram Moolenaara6296202020-08-05 11:23:13 +02006source script_util.vim
Bram Moolenaar8c5a2782019-08-07 23:07:07 +02007
Bram Moolenaarf49e2402015-12-30 15:59:25 +01008"-------------------------------------------------------------------------------
9" Test environment {{{1
10"-------------------------------------------------------------------------------
11
Bram Moolenaarf49e2402015-12-30 15:59:25 +010012" Append a message to the "messages" file
Bram Moolenaar1e115362019-01-09 23:01:02 +010013func Xout(text)
Bram Moolenaarf49e2402015-12-30 15:59:25 +010014 split messages
15 $put =a:text
16 wq
17endfunc
18
19com! -nargs=1 Xout call Xout(<args>)
20
Bram Moolenaara6296202020-08-05 11:23:13 +020021" Create a new instance of Vim and run the commands in 'test' and then 'verify'
22" The commands in 'test' are expected to store the test results in the Xtest.out
23" file. If the test passes successfully, then Xtest.out should be empty.
24func RunInNewVim(test, verify)
25 let init =<< trim END
26 source script_util.vim
27 XpathINIT
28 XloopINIT
29 END
30 let cleanup =<< trim END
31 call writefile(v:errors, 'Xtest.out')
32 qall
33 END
34 call writefile(init, 'Xtest.vim')
35 call writefile(a:test, 'Xtest.vim', 'a')
36 call writefile(a:verify, 'Xverify.vim')
37 call writefile(cleanup, 'Xverify.vim', 'a')
38 call RunVim([], [], "-S Xtest.vim -S Xverify.vim")
39 call assert_equal([], readfile('Xtest.out'))
40 call delete('Xtest.out')
41 call delete('Xtest.vim')
42 call delete('Xverify.vim')
Bram Moolenaar1e115362019-01-09 23:01:02 +010043endfunc
Bram Moolenaarf49e2402015-12-30 15:59:25 +010044
Bram Moolenaarf49e2402015-12-30 15:59:25 +010045"-------------------------------------------------------------------------------
46" Test 1: :endwhile in function {{{1
47"
48" Detect if a broken loop is (incorrectly) reactivated by the
49" :endwhile. Use a :return to prevent an endless loop, and make
50" this test first to get a meaningful result on an error before other
51" tests will hang.
52"-------------------------------------------------------------------------------
53
Bram Moolenaara6296202020-08-05 11:23:13 +020054func T1_F()
Bram Moolenaarf49e2402015-12-30 15:59:25 +010055 Xpath 'a'
56 let first = 1
57 while 1
58 Xpath 'b'
59 if first
60 Xpath 'c'
61 let first = 0
62 break
63 else
64 Xpath 'd'
65 return
66 endif
67 endwhile
Bram Moolenaara6296202020-08-05 11:23:13 +020068endfunc
Bram Moolenaarf49e2402015-12-30 15:59:25 +010069
Bram Moolenaara6296202020-08-05 11:23:13 +020070func T1_G()
Bram Moolenaarf49e2402015-12-30 15:59:25 +010071 Xpath 'h'
72 let first = 1
73 while 1
74 Xpath 'i'
75 if first
76 Xpath 'j'
77 let first = 0
78 break
79 else
80 Xpath 'k'
81 return
82 endif
83 if 1 " unmatched :if
84 endwhile
Bram Moolenaara6296202020-08-05 11:23:13 +020085endfunc
Bram Moolenaarf49e2402015-12-30 15:59:25 +010086
87func Test_endwhile_function()
88 XpathINIT
89 call T1_F()
90 Xpath 'F'
91
92 try
93 call T1_G()
94 catch
95 " Catch missing :endif
96 call assert_true(v:exception =~ 'E171')
97 Xpath 'x'
98 endtry
99 Xpath 'G'
100
101 call assert_equal('abcFhijxG', g:Xpath)
102endfunc
103
104"-------------------------------------------------------------------------------
105" Test 2: :endwhile in script {{{1
106"
107" Detect if a broken loop is (incorrectly) reactivated by the
108" :endwhile. Use a :finish to prevent an endless loop, and place
109" this test before others that might hang to get a meaningful result
110" on an error.
111"
112" This test executes the bodies of the functions T1_F and T1_G from
113" the previous test as script files (:return replaced by :finish).
114"-------------------------------------------------------------------------------
115
116func Test_endwhile_script()
117 XpathINIT
118 ExecAsScript T1_F
119 Xpath 'F'
Bram Moolenaarf4f79b82016-01-25 20:38:30 +0100120 call DeleteTheScript()
Bram Moolenaarf49e2402015-12-30 15:59:25 +0100121
122 try
123 ExecAsScript T1_G
124 catch
125 " Catch missing :endif
126 call assert_true(v:exception =~ 'E171')
127 Xpath 'x'
128 endtry
129 Xpath 'G'
Bram Moolenaarf4f79b82016-01-25 20:38:30 +0100130 call DeleteTheScript()
Bram Moolenaarf49e2402015-12-30 15:59:25 +0100131
132 call assert_equal('abcFhijxG', g:Xpath)
133endfunc
134
135"-------------------------------------------------------------------------------
136" Test 3: :if, :elseif, :while, :continue, :break {{{1
137"-------------------------------------------------------------------------------
138
Bram Moolenaara6296202020-08-05 11:23:13 +0200139func Test_if_while()
Bram Moolenaarf49e2402015-12-30 15:59:25 +0100140 XpathINIT
141 if 1
142 Xpath 'a'
143 let loops = 3
144 while loops > -1 " main loop: loops == 3, 2, 1 (which breaks)
145 if loops <= 0
146 let break_err = 1
147 let loops = -1
148 else
149 Xpath 'b' . loops
150 endif
151 if (loops == 2)
152 while loops == 2 " dummy loop
153 Xpath 'c' . loops
154 let loops = loops - 1
155 continue " stop dummy loop
156 Xpath 'd' . loops
157 endwhile
158 continue " continue main loop
159 Xpath 'e' . loops
160 elseif (loops == 1)
161 let p = 1
162 while p " dummy loop
163 Xpath 'f' . loops
164 let p = 0
165 break " break dummy loop
166 Xpath 'g' . loops
167 endwhile
168 Xpath 'h' . loops
169 unlet p
170 break " break main loop
171 Xpath 'i' . loops
172 endif
173 if (loops > 0)
174 Xpath 'j' . loops
175 endif
176 while loops == 3 " dummy loop
177 let loops = loops - 1
178 endwhile " end dummy loop
179 endwhile " end main loop
180 Xpath 'k'
181 else
182 Xpath 'l'
183 endif
184 Xpath 'm'
185 if exists("break_err")
186 Xpath 'm'
187 unlet break_err
188 endif
189
190 unlet loops
191
192 call assert_equal('ab3j3b2c2b1f1h1km', g:Xpath)
193endfunc
194
195"-------------------------------------------------------------------------------
196" Test 4: :return {{{1
197"-------------------------------------------------------------------------------
198
Bram Moolenaara6296202020-08-05 11:23:13 +0200199func T4_F()
Bram Moolenaarf49e2402015-12-30 15:59:25 +0100200 if 1
201 Xpath 'a'
202 let loops = 3
203 while loops > 0 " 3: 2: 1:
204 Xpath 'b' . loops
205 if (loops == 2)
206 Xpath 'c' . loops
207 return
208 Xpath 'd' . loops
209 endif
210 Xpath 'e' . loops
211 let loops = loops - 1
212 endwhile
213 Xpath 'f'
214 else
215 Xpath 'g'
216 endif
Bram Moolenaara6296202020-08-05 11:23:13 +0200217endfunc
Bram Moolenaarf49e2402015-12-30 15:59:25 +0100218
Bram Moolenaara6296202020-08-05 11:23:13 +0200219func Test_return()
Bram Moolenaarf49e2402015-12-30 15:59:25 +0100220 XpathINIT
221 call T4_F()
222 Xpath '4'
223
224 call assert_equal('ab3e3b2c24', g:Xpath)
Bram Moolenaara6296202020-08-05 11:23:13 +0200225endfunc
Bram Moolenaarf49e2402015-12-30 15:59:25 +0100226
227
228"-------------------------------------------------------------------------------
229" Test 5: :finish {{{1
230"
231" This test executes the body of the function T4_F from the previous
232" test as a script file (:return replaced by :finish).
233"-------------------------------------------------------------------------------
234
Bram Moolenaara6296202020-08-05 11:23:13 +0200235func Test_finish()
Bram Moolenaarf49e2402015-12-30 15:59:25 +0100236 XpathINIT
237 ExecAsScript T4_F
238 Xpath '5'
Bram Moolenaarf4f79b82016-01-25 20:38:30 +0100239 call DeleteTheScript()
Bram Moolenaarf49e2402015-12-30 15:59:25 +0100240
241 call assert_equal('ab3e3b2c25', g:Xpath)
Bram Moolenaara6296202020-08-05 11:23:13 +0200242endfunc
Bram Moolenaarf49e2402015-12-30 15:59:25 +0100243
244
245
246"-------------------------------------------------------------------------------
247" Test 6: Defining functions in :while loops {{{1
248"
249" Functions can be defined inside other functions. An inner function
250" gets defined when the outer function is executed. Functions may
251" also be defined inside while loops. Expressions in braces for
252" defining the function name are allowed.
253"
254" The functions are defined when sourcing the script, only the
255" resulting path is checked in the test function.
256"-------------------------------------------------------------------------------
257
258XpathINIT
259
260" The command CALL collects the argument of all its invocations in "calls"
261" when used from a function (that is, when the global variable "calls" needs
262" the "g:" prefix). This is to check that the function code is skipped when
263" the function is defined. For inner functions, do so only if the outer
264" function is not being executed.
265"
266let calls = ""
267com! -nargs=1 CALL
Bram Moolenaar1e115362019-01-09 23:01:02 +0100268 \ if !exists("calls") && !exists("outer") |
269 \ let g:calls = g:calls . <args> |
270 \ endif
Bram Moolenaarf49e2402015-12-30 15:59:25 +0100271
272let i = 0
273while i < 3
274 let i = i + 1
275 if i == 1
276 Xpath 'a'
277 function! F1(arg)
278 CALL a:arg
279 let outer = 1
280
281 let j = 0
282 while j < 1
283 Xpath 'b'
284 let j = j + 1
285 function! G1(arg)
286 CALL a:arg
287 endfunction
288 Xpath 'c'
289 endwhile
290 endfunction
291 Xpath 'd'
292
293 continue
294 endif
295
296 Xpath 'e' . i
297 function! F{i}(i, arg)
298 CALL a:arg
299 let outer = 1
300
301 if a:i == 3
302 Xpath 'f'
303 endif
304 let k = 0
305 while k < 3
306 Xpath 'g' . k
307 let k = k + 1
308 function! G{a:i}{k}(arg)
309 CALL a:arg
310 endfunction
311 Xpath 'h' . k
312 endwhile
313 endfunction
314 Xpath 'i'
315
316endwhile
317
318if exists("*G1")
319 Xpath 'j'
320endif
321if exists("*F1")
322 call F1("F1")
323 if exists("*G1")
Bram Moolenaar1e115362019-01-09 23:01:02 +0100324 call G1("G1")
Bram Moolenaarf49e2402015-12-30 15:59:25 +0100325 endif
326endif
327
328if exists("G21") || exists("G22") || exists("G23")
329 Xpath 'k'
330endif
331if exists("*F2")
332 call F2(2, "F2")
333 if exists("*G21")
Bram Moolenaar1e115362019-01-09 23:01:02 +0100334 call G21("G21")
Bram Moolenaarf49e2402015-12-30 15:59:25 +0100335 endif
336 if exists("*G22")
Bram Moolenaar1e115362019-01-09 23:01:02 +0100337 call G22("G22")
Bram Moolenaarf49e2402015-12-30 15:59:25 +0100338 endif
339 if exists("*G23")
Bram Moolenaar1e115362019-01-09 23:01:02 +0100340 call G23("G23")
Bram Moolenaarf49e2402015-12-30 15:59:25 +0100341 endif
342endif
343
344if exists("G31") || exists("G32") || exists("G33")
345 Xpath 'l'
346endif
347if exists("*F3")
348 call F3(3, "F3")
349 if exists("*G31")
Bram Moolenaar1e115362019-01-09 23:01:02 +0100350 call G31("G31")
Bram Moolenaarf49e2402015-12-30 15:59:25 +0100351 endif
352 if exists("*G32")
Bram Moolenaar1e115362019-01-09 23:01:02 +0100353 call G32("G32")
Bram Moolenaarf49e2402015-12-30 15:59:25 +0100354 endif
355 if exists("*G33")
Bram Moolenaar1e115362019-01-09 23:01:02 +0100356 call G33("G33")
Bram Moolenaarf49e2402015-12-30 15:59:25 +0100357 endif
358endif
359
360Xpath 'm'
361
362let g:test6_result = g:Xpath
363let g:test6_calls = calls
364
365unlet calls
366delfunction F1
367delfunction G1
368delfunction F2
369delfunction G21
370delfunction G22
371delfunction G23
372delfunction G31
373delfunction G32
374delfunction G33
375
Bram Moolenaara6296202020-08-05 11:23:13 +0200376func Test_defining_functions()
Bram Moolenaarf49e2402015-12-30 15:59:25 +0100377 call assert_equal('ade2ie3ibcg0h1g1h2g2h3fg0h1g1h2g2h3m', g:test6_result)
378 call assert_equal('F1G1F2G21G22G23F3G31G32G33', g:test6_calls)
379endfunc
380
381"-------------------------------------------------------------------------------
Bram Moolenaara2cce862016-01-02 19:50:04 +0100382" Test 7: Continuing on errors outside functions {{{1
383"
384" On an error outside a function, the script processing continues
385" at the line following the outermost :endif or :endwhile. When not
386" inside an :if or :while, the script processing continues at the next
387" line.
388"-------------------------------------------------------------------------------
389
390XpathINIT
391
392if 1
393 Xpath 'a'
394 while 1
395 Xpath 'b'
396 asdf
397 Xpath 'c'
398 break
399 endwhile | Xpath 'd'
400 Xpath 'e'
401endif | Xpath 'f'
402Xpath 'g'
403
404while 1
405 Xpath 'h'
406 if 1
407 Xpath 'i'
408 asdf
409 Xpath 'j'
410 endif | Xpath 'k'
411 Xpath 'l'
412 break
413endwhile | Xpath 'm'
414Xpath 'n'
415
416asdf
417Xpath 'o'
418
419asdf | Xpath 'p'
420Xpath 'q'
421
422let g:test7_result = g:Xpath
423
424func Test_error_in_script()
425 call assert_equal('abghinoq', g:test7_result)
426endfunc
427
428"-------------------------------------------------------------------------------
429" Test 8: Aborting and continuing on errors inside functions {{{1
430"
431" On an error inside a function without the "abort" attribute, the
432" script processing continues at the next line (unless the error was
433" in a :return command). On an error inside a function with the
434" "abort" attribute, the function is aborted and the script processing
435" continues after the function call; the value -1 is returned then.
436"-------------------------------------------------------------------------------
437
438XpathINIT
439
Bram Moolenaara6296202020-08-05 11:23:13 +0200440func T8_F()
Bram Moolenaara2cce862016-01-02 19:50:04 +0100441 if 1
442 Xpath 'a'
443 while 1
444 Xpath 'b'
445 asdf
446 Xpath 'c'
447 asdf | Xpath 'd'
448 Xpath 'e'
449 break
450 endwhile
451 Xpath 'f'
452 endif | Xpath 'g'
453 Xpath 'h'
454
455 while 1
456 Xpath 'i'
457 if 1
458 Xpath 'j'
459 asdf
460 Xpath 'k'
461 asdf | Xpath 'l'
462 Xpath 'm'
463 endif
464 Xpath 'n'
465 break
466 endwhile | Xpath 'o'
467 Xpath 'p'
468
469 return novar " returns (default return value 0)
470 Xpath 'q'
471 return 1 " not reached
Bram Moolenaara6296202020-08-05 11:23:13 +0200472endfunc
Bram Moolenaara2cce862016-01-02 19:50:04 +0100473
Bram Moolenaara6296202020-08-05 11:23:13 +0200474func T8_G() abort
Bram Moolenaara2cce862016-01-02 19:50:04 +0100475 if 1
476 Xpath 'r'
477 while 1
478 Xpath 's'
479 asdf " returns -1
480 Xpath 't'
481 break
482 endwhile
483 Xpath 'v'
484 endif | Xpath 'w'
485 Xpath 'x'
486
487 return -4 " not reached
Bram Moolenaara6296202020-08-05 11:23:13 +0200488endfunc
Bram Moolenaara2cce862016-01-02 19:50:04 +0100489
Bram Moolenaara6296202020-08-05 11:23:13 +0200490func T8_H() abort
Bram Moolenaara2cce862016-01-02 19:50:04 +0100491 while 1
492 Xpath 'A'
493 if 1
494 Xpath 'B'
495 asdf " returns -1
496 Xpath 'C'
497 endif
498 Xpath 'D'
499 break
500 endwhile | Xpath 'E'
501 Xpath 'F'
502
503 return -4 " not reached
Bram Moolenaara6296202020-08-05 11:23:13 +0200504endfunc
Bram Moolenaara2cce862016-01-02 19:50:04 +0100505
506" Aborted functions (T8_G and T8_H) return -1.
507let g:test8_sum = (T8_F() + 1) - 4 * T8_G() - 8 * T8_H()
508Xpath 'X'
509let g:test8_result = g:Xpath
510
511func Test_error_in_function()
512 call assert_equal(13, g:test8_sum)
513 call assert_equal('abcefghijkmnoprsABX', g:test8_result)
514
515 delfunction T8_F
516 delfunction T8_G
517 delfunction T8_H
518endfunc
519
520
521"-------------------------------------------------------------------------------
522" Test 9: Continuing after aborted functions {{{1
523"
524" When a function with the "abort" attribute is aborted due to an
525" error, the next function back in the call hierarchy without an
526" "abort" attribute continues; the value -1 is returned then.
527"-------------------------------------------------------------------------------
528
529XpathINIT
530
Bram Moolenaara6296202020-08-05 11:23:13 +0200531func F() abort
Bram Moolenaara2cce862016-01-02 19:50:04 +0100532 Xpath 'a'
533 let result = G() " not aborted
534 Xpath 'b'
535 if result != 2
536 Xpath 'c'
537 endif
538 return 1
Bram Moolenaara6296202020-08-05 11:23:13 +0200539endfunc
Bram Moolenaara2cce862016-01-02 19:50:04 +0100540
Bram Moolenaara6296202020-08-05 11:23:13 +0200541func G() " no abort attribute
Bram Moolenaara2cce862016-01-02 19:50:04 +0100542 Xpath 'd'
543 if H() != -1 " aborted
544 Xpath 'e'
545 endif
546 Xpath 'f'
547 return 2
Bram Moolenaara6296202020-08-05 11:23:13 +0200548endfunc
Bram Moolenaara2cce862016-01-02 19:50:04 +0100549
Bram Moolenaara6296202020-08-05 11:23:13 +0200550func H() abort
Bram Moolenaara2cce862016-01-02 19:50:04 +0100551 Xpath 'g'
552 call I() " aborted
553 Xpath 'h'
554 return 4
Bram Moolenaara6296202020-08-05 11:23:13 +0200555endfunc
Bram Moolenaara2cce862016-01-02 19:50:04 +0100556
Bram Moolenaara6296202020-08-05 11:23:13 +0200557func I() abort
Bram Moolenaara2cce862016-01-02 19:50:04 +0100558 Xpath 'i'
559 asdf " error
560 Xpath 'j'
561 return 8
Bram Moolenaara6296202020-08-05 11:23:13 +0200562endfunc
Bram Moolenaara2cce862016-01-02 19:50:04 +0100563
564if F() != 1
565 Xpath 'k'
566endif
567
568let g:test9_result = g:Xpath
569
570delfunction F
571delfunction G
572delfunction H
573delfunction I
574
575func Test_func_abort()
576 call assert_equal('adgifb', g:test9_result)
577endfunc
578
579
580"-------------------------------------------------------------------------------
581" Test 10: :if, :elseif, :while argument parsing {{{1
582"
583" A '"' or '|' in an argument expression must not be mixed up with
584" a comment or a next command after a bar. Parsing errors should
585" be recognized.
586"-------------------------------------------------------------------------------
587
588XpathINIT
589
Bram Moolenaara6296202020-08-05 11:23:13 +0200590func MSG(enr, emsg)
Bram Moolenaara2cce862016-01-02 19:50:04 +0100591 let english = v:lang == "C" || v:lang =~ '^[Ee]n'
592 if a:enr == ""
593 Xout "TODO: Add message number for:" a:emsg
594 let v:errmsg = ":" . v:errmsg
595 endif
596 let match = 1
597 if v:errmsg !~ '^'.a:enr.':' || (english && v:errmsg !~ a:emsg)
598 let match = 0
599 if v:errmsg == ""
600 Xout "Message missing."
601 else
Bram Moolenaara4208962019-08-24 20:50:19 +0200602 let v:errmsg = v:errmsg->escape('"')
Bram Moolenaara2cce862016-01-02 19:50:04 +0100603 Xout "Unexpected message:" v:errmsg
604 endif
605 endif
606 return match
Bram Moolenaar1e115362019-01-09 23:01:02 +0100607endfunc
Bram Moolenaara2cce862016-01-02 19:50:04 +0100608
609if 1 || strlen("\"") | Xpath 'a'
610 Xpath 'b'
611endif
612Xpath 'c'
613
614if 0
615elseif 1 || strlen("\"") | Xpath 'd'
616 Xpath 'e'
617endif
618Xpath 'f'
619
620while 1 || strlen("\"") | Xpath 'g'
621 Xpath 'h'
622 break
623endwhile
624Xpath 'i'
625
626let v:errmsg = ""
627if 1 ||| strlen("\"") | Xpath 'j'
628 Xpath 'k'
629endif
630Xpath 'l'
631if !MSG('E15', "Invalid expression")
632 Xpath 'm'
633endif
634
635let v:errmsg = ""
636if 0
637elseif 1 ||| strlen("\"") | Xpath 'n'
638 Xpath 'o'
639endif
640Xpath 'p'
641if !MSG('E15', "Invalid expression")
642 Xpath 'q'
643endif
644
645let v:errmsg = ""
646while 1 ||| strlen("\"") | Xpath 'r'
647 Xpath 's'
648 break
649endwhile
650Xpath 't'
651if !MSG('E15', "Invalid expression")
652 Xpath 'u'
653endif
654
655let g:test10_result = g:Xpath
656delfunction MSG
657
658func Test_expr_parsing()
659 call assert_equal('abcdefghilpt', g:test10_result)
660endfunc
661
662
663"-------------------------------------------------------------------------------
664" Test 11: :if, :elseif, :while argument evaluation after abort {{{1
665"
666" When code is skipped over due to an error, the boolean argument to
667" an :if, :elseif, or :while must not be evaluated.
668"-------------------------------------------------------------------------------
669
670XpathINIT
671
672let calls = 0
673
Bram Moolenaara6296202020-08-05 11:23:13 +0200674func P(num)
Bram Moolenaara2cce862016-01-02 19:50:04 +0100675 let g:calls = g:calls + a:num " side effect on call
676 return 0
Bram Moolenaara6296202020-08-05 11:23:13 +0200677endfunc
Bram Moolenaara2cce862016-01-02 19:50:04 +0100678
679if 1
680 Xpath 'a'
681 asdf " error
682 Xpath 'b'
683 if P(1) " should not be called
684 Xpath 'c'
685 elseif !P(2) " should not be called
686 Xpath 'd'
687 else
688 Xpath 'e'
689 endif
690 Xpath 'f'
691 while P(4) " should not be called
692 Xpath 'g'
693 endwhile
694 Xpath 'h'
695endif
696Xpath 'x'
697
698let g:test11_calls = calls
699let g:test11_result = g:Xpath
700
701unlet calls
702delfunction P
703
704func Test_arg_abort()
705 call assert_equal(0, g:test11_calls)
706 call assert_equal('ax', g:test11_result)
707endfunc
708
709
710"-------------------------------------------------------------------------------
711" Test 12: Expressions in braces in skipped code {{{1
712"
713" In code skipped over due to an error or inactive conditional,
714" an expression in braces as part of a variable or function name
715" should not be evaluated.
716"-------------------------------------------------------------------------------
717
718XpathINIT
719
720function! NULL()
721 Xpath 'a'
722 return 0
723endfunction
724
725function! ZERO()
726 Xpath 'b'
727 return 0
728endfunction
729
730function! F0()
731 Xpath 'c'
732endfunction
733
734function! F1(arg)
735 Xpath 'e'
736endfunction
737
738let V0 = 1
739
740Xpath 'f'
741echo 0 ? F{NULL() + V{ZERO()}}() : 1
742
743Xpath 'g'
744if 0
745 Xpath 'h'
746 call F{NULL() + V{ZERO()}}()
747endif
748
749Xpath 'i'
750if 1
751 asdf " error
752 Xpath 'j'
753 call F1(F{NULL() + V{ZERO()}}())
754endif
755
756Xpath 'k'
757if 1
758 asdf " error
759 Xpath 'l'
760 call F{NULL() + V{ZERO()}}()
761endif
762
763let g:test12_result = g:Xpath
764
765func Test_braces_skipped()
766 call assert_equal('fgik', g:test12_result)
767endfunc
768
769
770"-------------------------------------------------------------------------------
771" Test 13: Failure in argument evaluation for :while {{{1
772"
773" A failure in the expression evaluation for the condition of a :while
774" causes the whole :while loop until the matching :endwhile being
775" ignored. Continuation is at the next following line.
776"-------------------------------------------------------------------------------
777
778XpathINIT
779
780Xpath 'a'
781while asdf
782 Xpath 'b'
783 while 1
784 Xpath 'c'
785 break
786 endwhile
787 Xpath 'd'
788 break
789endwhile
790Xpath 'e'
791
792while asdf | Xpath 'f' | endwhile | Xpath 'g'
793Xpath 'h'
794let g:test13_result = g:Xpath
795
796func Test_while_fail()
797 call assert_equal('aeh', g:test13_result)
798endfunc
799
800
801"-------------------------------------------------------------------------------
802" Test 14: Failure in argument evaluation for :if {{{1
803"
804" A failure in the expression evaluation for the condition of an :if
805" does not cause the corresponding :else or :endif being matched to
806" a previous :if/:elseif. Neither of both branches of the failed :if
807" are executed.
808"-------------------------------------------------------------------------------
809
810XpathINIT
811
812function! F()
813 Xpath 'a'
814 let x = 0
815 if x " false
816 Xpath 'b'
817 elseif !x " always true
818 Xpath 'c'
819 let x = 1
820 if g:boolvar " possibly undefined
821 Xpath 'd'
822 else
823 Xpath 'e'
824 endif
825 Xpath 'f'
826 elseif x " never executed
827 Xpath 'g'
828 endif
829 Xpath 'h'
830endfunction
831
832let boolvar = 1
833call F()
834Xpath '-'
835
836unlet boolvar
837call F()
838let g:test14_result = g:Xpath
839
840delfunction F
841
842func Test_if_fail()
843 call assert_equal('acdfh-acfh', g:test14_result)
844endfunc
845
846
847"-------------------------------------------------------------------------------
848" Test 15: Failure in argument evaluation for :if (bar) {{{1
849"
850" Like previous test, except that the failing :if ... | ... | :endif
851" is in a single line.
852"-------------------------------------------------------------------------------
853
854XpathINIT
855
856function! F()
857 Xpath 'a'
858 let x = 0
859 if x " false
860 Xpath 'b'
861 elseif !x " always true
862 Xpath 'c'
863 let x = 1
864 if g:boolvar | Xpath 'd' | else | Xpath 'e' | endif
865 Xpath 'f'
866 elseif x " never executed
867 Xpath 'g'
868 endif
869 Xpath 'h'
870endfunction
871
872let boolvar = 1
873call F()
874Xpath '-'
875
876unlet boolvar
877call F()
878let g:test15_result = g:Xpath
879
880delfunction F
881
882func Test_if_bar_fail()
883 call assert_equal('acdfh-acfh', g:test15_result)
884endfunc
885
Bram Moolenaar4119cf82016-01-17 14:59:01 +0100886"-------------------------------------------------------------------------------
Bram Moolenaar1f068232019-11-03 16:17:26 +0100887" Test 16: Double :else or :elseif after :else {{{1
888"
889" Multiple :elses or an :elseif after an :else are forbidden.
890"-------------------------------------------------------------------------------
891
892func T16_F() abort
893 if 0
894 Xpath 'a'
895 else
896 Xpath 'b'
897 else " aborts function
898 Xpath 'c'
899 endif
900 Xpath 'd'
901endfunc
902
903func T16_G() abort
904 if 0
905 Xpath 'a'
906 else
907 Xpath 'b'
908 elseif 1 " aborts function
909 Xpath 'c'
910 else
911 Xpath 'd'
912 endif
913 Xpath 'e'
914endfunc
915
916func T16_H() abort
917 if 0
918 Xpath 'a'
919 elseif 0
920 Xpath 'b'
921 else
922 Xpath 'c'
923 else " aborts function
924 Xpath 'd'
925 endif
926 Xpath 'e'
927endfunc
928
929func T16_I() abort
930 if 0
931 Xpath 'a'
932 elseif 0
933 Xpath 'b'
934 else
935 Xpath 'c'
936 elseif 1 " aborts function
937 Xpath 'd'
938 else
939 Xpath 'e'
940 endif
941 Xpath 'f'
942endfunc
943
944func Test_Multi_Else()
945 XpathINIT
946 try
947 call T16_F()
948 catch /E583:/
949 Xpath 'e'
950 endtry
951 call assert_equal('be', g:Xpath)
952
953 XpathINIT
954 try
955 call T16_G()
956 catch /E584:/
957 Xpath 'f'
958 endtry
959 call assert_equal('bf', g:Xpath)
960
961 XpathINIT
962 try
963 call T16_H()
964 catch /E583:/
965 Xpath 'f'
966 endtry
967 call assert_equal('cf', g:Xpath)
968
969 XpathINIT
970 try
971 call T16_I()
972 catch /E584:/
973 Xpath 'g'
974 endtry
975 call assert_equal('cg', g:Xpath)
976endfunc
977
978"-------------------------------------------------------------------------------
979" Test 17: Nesting of unmatched :if or :endif inside a :while {{{1
980"
981" The :while/:endwhile takes precedence in nesting over an unclosed
982" :if or an unopened :endif.
983"-------------------------------------------------------------------------------
984
985" While loops inside a function are continued on error.
986func T17_F()
987 let loops = 3
988 while loops > 0
989 let loops -= 1
990 Xpath 'a' . loops
991 if (loops == 1)
992 Xpath 'b' . loops
993 continue
994 elseif (loops == 0)
995 Xpath 'c' . loops
996 break
997 elseif 1
998 Xpath 'd' . loops
999 " endif missing!
1000 endwhile " :endwhile after :if 1
1001 Xpath 'e'
1002endfunc
1003
1004func T17_G()
1005 let loops = 2
1006 while loops > 0
1007 let loops -= 1
1008 Xpath 'a' . loops
1009 if 0
1010 Xpath 'b' . loops
1011 " endif missing
1012 endwhile " :endwhile after :if 0
1013endfunc
1014
1015func T17_H()
1016 let loops = 2
1017 while loops > 0
1018 let loops -= 1
1019 Xpath 'a' . loops
1020 " if missing!
1021 endif " :endif without :if in while
1022 Xpath 'b' . loops
1023 endwhile
1024endfunc
1025
1026" Error continuation outside a function is at the outermost :endwhile or :endif.
1027XpathINIT
1028let v:errmsg = ''
1029let loops = 2
1030while loops > 0
1031 let loops -= 1
1032 Xpath 'a' . loops
1033 if 0
1034 Xpath 'b' . loops
1035 " endif missing! Following :endwhile fails.
1036endwhile | Xpath 'c'
1037Xpath 'd'
1038call assert_match('E171:', v:errmsg)
1039call assert_equal('a1d', g:Xpath)
1040
1041func Test_unmatched_if_in_while()
1042 XpathINIT
1043 call assert_fails('call T17_F()', 'E171:')
1044 call assert_equal('a2d2a1b1a0c0e', g:Xpath)
1045
1046 XpathINIT
1047 call assert_fails('call T17_G()', 'E171:')
1048 call assert_equal('a1a0', g:Xpath)
1049
1050 XpathINIT
1051 call assert_fails('call T17_H()', 'E580:')
1052 call assert_equal('a1b1a0b0', g:Xpath)
1053endfunc
1054
1055"-------------------------------------------------------------------------------
Bram Moolenaara6296202020-08-05 11:23:13 +02001056" Test 18: Interrupt (Ctrl-C pressed) {{{1
1057"
1058" On an interrupt, the script processing is terminated immediately.
Bram Moolenaar1f068232019-11-03 16:17:26 +01001059"-------------------------------------------------------------------------------
Bram Moolenaara6296202020-08-05 11:23:13 +02001060
1061func Test_interrupt_while_if()
1062 let test =<< trim [CODE]
1063 try
1064 if 1
1065 Xpath 'a'
1066 while 1
1067 Xpath 'b'
1068 if 1
1069 Xpath 'c'
1070 call interrupt()
1071 call assert_report('should not get here')
1072 break
1073 finish
1074 endif | call assert_report('should not get here')
1075 call assert_report('should not get here')
1076 endwhile | call assert_report('should not get here')
1077 call assert_report('should not get here')
1078 endif | call assert_report('should not get here')
1079 call assert_report('should not get here')
1080 catch /^Vim:Interrupt$/
1081 Xpath 'd'
1082 endtry | Xpath 'e'
1083 Xpath 'f'
1084 [CODE]
1085 let verify =<< trim [CODE]
1086 call assert_equal('abcdef', g:Xpath)
1087 [CODE]
1088 call RunInNewVim(test, verify)
1089endfunc
1090
1091func Test_interrupt_try()
1092 let test =<< trim [CODE]
1093 try
1094 try
1095 Xpath 'a'
1096 call interrupt()
1097 call assert_report('should not get here')
1098 endtry | call assert_report('should not get here')
1099 call assert_report('should not get here')
1100 catch /^Vim:Interrupt$/
1101 Xpath 'b'
1102 endtry | Xpath 'c'
1103 Xpath 'd'
1104 [CODE]
1105 let verify =<< trim [CODE]
1106 call assert_equal('abcd', g:Xpath)
1107 [CODE]
1108 call RunInNewVim(test, verify)
1109endfunc
1110
1111func Test_interrupt_func_while_if()
1112 let test =<< trim [CODE]
1113 func F()
1114 if 1
1115 Xpath 'a'
1116 while 1
1117 Xpath 'b'
1118 if 1
1119 Xpath 'c'
1120 call interrupt()
1121 call assert_report('should not get here')
1122 break
1123 return
1124 endif | call assert_report('should not get here')
1125 call assert_report('should not get here')
1126 endwhile | call assert_report('should not get here')
1127 call assert_report('should not get here')
1128 endif | call assert_report('should not get here')
1129 call assert_report('should not get here')
1130 endfunc
1131
1132 Xpath 'd'
1133 try
1134 call F() | call assert_report('should not get here')
1135 catch /^Vim:Interrupt$/
1136 Xpath 'e'
1137 endtry | Xpath 'f'
1138 Xpath 'g'
1139 [CODE]
1140 let verify =<< trim [CODE]
1141 call assert_equal('dabcefg', g:Xpath)
1142 [CODE]
1143 call RunInNewVim(test, verify)
1144endfunc
1145
1146func Test_interrupt_func_try()
1147 let test =<< trim [CODE]
1148 func G()
1149 try
1150 Xpath 'a'
1151 call interrupt()
1152 call assert_report('should not get here')
1153 endtry | call assert_report('should not get here')
1154 call assert_report('should not get here')
1155 endfunc
1156
1157 Xpath 'b'
1158 try
1159 call G() | call assert_report('should not get here')
1160 catch /^Vim:Interrupt$/
1161 Xpath 'c'
1162 endtry | Xpath 'd'
1163 Xpath 'e'
1164 [CODE]
1165 let verify =<< trim [CODE]
1166 call assert_equal('bacde', g:Xpath)
1167 [CODE]
1168 call RunInNewVim(test, verify)
1169endfunc
1170
1171"-------------------------------------------------------------------------------
1172" Test 19: Aborting on errors inside :try/:endtry {{{1
1173"
1174" An error in a command dynamically enclosed in a :try/:endtry region
1175" aborts script processing immediately. It does not matter whether
1176" the failing command is outside or inside a function and whether a
1177" function has an "abort" attribute.
1178"-------------------------------------------------------------------------------
1179
1180func Test_try_error_abort_1()
1181 let test =<< trim [CODE]
1182 func F() abort
1183 Xpath 'a'
1184 asdf
1185 call assert_report('should not get here')
1186 endfunc
1187
1188 try
1189 Xpath 'b'
1190 call F()
1191 call assert_report('should not get here')
1192 endtry | call assert_report('should not get here')
1193 call assert_report('should not get here')
1194 [CODE]
1195 let verify =<< trim [CODE]
1196 call assert_equal('ba', g:Xpath)
1197 [CODE]
1198 call RunInNewVim(test, verify)
1199endfunc
1200
1201func Test_try_error_abort_2()
1202 let test =<< trim [CODE]
1203 func G()
1204 Xpath 'a'
1205 asdf
1206 call assert_report('should not get here')
1207 endfunc
1208
1209 try
1210 Xpath 'b'
1211 call G()
1212 call assert_report('should not get here')
1213 endtry | call assert_report('should not get here')
1214 call assert_report('should not get here')
1215 [CODE]
1216 let verify =<< trim [CODE]
1217 call assert_equal('ba', g:Xpath)
1218 [CODE]
1219 call RunInNewVim(test, verify)
1220endfunc
1221
1222func Test_try_error_abort_3()
1223 let test =<< trim [CODE]
1224 try
1225 Xpath 'a'
1226 asdf
1227 call assert_report('should not get here')
1228 endtry | call assert_report('should not get here')
1229 call assert_report('should not get here')
1230 [CODE]
1231 let verify =<< trim [CODE]
1232 call assert_equal('a', g:Xpath)
1233 [CODE]
1234 call RunInNewVim(test, verify)
1235endfunc
1236
1237func Test_try_error_abort_4()
1238 let test =<< trim [CODE]
1239 if 1
1240 try
1241 Xpath 'a'
1242 asdf
1243 call assert_report('should not get here')
1244 endtry | call assert_report('should not get here')
1245 endif | call assert_report('should not get here')
1246 call assert_report('should not get here')
1247 [CODE]
1248 let verify =<< trim [CODE]
1249 call assert_equal('a', g:Xpath)
1250 [CODE]
1251 call RunInNewVim(test, verify)
1252endfunc
1253
1254func Test_try_error_abort_5()
1255 let test =<< trim [CODE]
1256 let p = 1
1257 while p
1258 let p = 0
1259 try
1260 Xpath 'a'
1261 asdf
1262 call assert_report('should not get here')
1263 endtry | call assert_report('should not get here')
1264 endwhile | call assert_report('should not get here')
1265 call assert_report('should not get here')
1266 [CODE]
1267 let verify =<< trim [CODE]
1268 call assert_equal('a', g:Xpath)
1269 [CODE]
1270 call RunInNewVim(test, verify)
1271endfunc
1272
1273func Test_try_error_abort_6()
1274 let test =<< trim [CODE]
1275 let p = 1
1276 Xpath 'a'
1277 while p
1278 Xpath 'b'
1279 let p = 0
1280 try
1281 Xpath 'c'
1282 endwhile | call assert_report('should not get here')
1283 call assert_report('should not get here')
1284 [CODE]
1285 let verify =<< trim [CODE]
1286 call assert_equal('abc', g:Xpath)
1287 [CODE]
1288 call RunInNewVim(test, verify)
1289endfunc
1290
1291"-------------------------------------------------------------------------------
1292" Test 20: Aborting on errors after :try/:endtry {{{1
1293"
1294" When an error occurs after the last active :try/:endtry region has
1295" been left, termination behavior is as if no :try/:endtry has been
1296" seen.
1297"-------------------------------------------------------------------------------
1298
1299func Test_error_after_try_1()
1300 let test =<< trim [CODE]
1301 let p = 1
1302 while p
1303 let p = 0
1304 Xpath 'a'
1305 try
1306 Xpath 'b'
1307 endtry
1308 asdf
1309 call assert_report('should not get here')
1310 endwhile | call assert_report('should not get here')
1311 Xpath 'c'
1312 [CODE]
1313 let verify =<< trim [CODE]
1314 call assert_equal('abc', g:Xpath)
1315 [CODE]
1316 call RunInNewVim(test, verify)
1317endfunc
1318
1319func Test_error_after_try_2()
1320 let test =<< trim [CODE]
1321 while 1
1322 try
1323 Xpath 'a'
1324 break
1325 call assert_report('should not get here')
1326 endtry
1327 endwhile
1328 Xpath 'b'
1329 asdf
1330 Xpath 'c'
1331 [CODE]
1332 let verify =<< trim [CODE]
1333 call assert_equal('abc', g:Xpath)
1334 [CODE]
1335 call RunInNewVim(test, verify)
1336endfunc
1337
1338func Test_error_after_try_3()
1339 let test =<< trim [CODE]
1340 while 1
1341 try
1342 Xpath 'a'
1343 break
1344 call assert_report('should not get here')
1345 finally
1346 Xpath 'b'
1347 endtry
1348 endwhile
1349 Xpath 'c'
1350 asdf
1351 Xpath 'd'
1352 [CODE]
1353 let verify =<< trim [CODE]
1354 call assert_equal('abcd', g:Xpath)
1355 [CODE]
1356 call RunInNewVim(test, verify)
1357endfunc
1358
1359func Test_error_after_try_4()
1360 let test =<< trim [CODE]
1361 while 1
1362 try
1363 Xpath 'a'
1364 finally
1365 Xpath 'b'
1366 break
1367 call assert_report('should not get here')
1368 endtry
1369 endwhile
1370 Xpath 'c'
1371 asdf
1372 Xpath 'd'
1373 [CODE]
1374 let verify =<< trim [CODE]
1375 call assert_equal('abcd', g:Xpath)
1376 [CODE]
1377 call RunInNewVim(test, verify)
1378endfunc
1379
1380func Test_error_after_try_5()
1381 let test =<< trim [CODE]
1382 let p = 1
1383 while p
1384 let p = 0
1385 try
1386 Xpath 'a'
1387 continue
1388 call assert_report('should not get here')
1389 endtry
1390 endwhile
1391 Xpath 'b'
1392 asdf
1393 Xpath 'c'
1394 [CODE]
1395 let verify =<< trim [CODE]
1396 call assert_equal('abc', g:Xpath)
1397 [CODE]
1398 call RunInNewVim(test, verify)
1399endfunc
1400
1401func Test_error_after_try_6()
1402 let test =<< trim [CODE]
1403 let p = 1
1404 while p
1405 let p = 0
1406 try
1407 Xpath 'a'
1408 continue
1409 call assert_report('should not get here')
1410 finally
1411 Xpath 'b'
1412 endtry
1413 endwhile
1414 Xpath 'c'
1415 asdf
1416 Xpath 'd'
1417 [CODE]
1418 let verify =<< trim [CODE]
1419 call assert_equal('abcd', g:Xpath)
1420 [CODE]
1421 call RunInNewVim(test, verify)
1422endfunc
1423
1424func Test_error_after_try_7()
1425 let test =<< trim [CODE]
1426 let p = 1
1427 while p
1428 let p = 0
1429 try
1430 Xpath 'a'
1431 finally
1432 Xpath 'b'
1433 continue
1434 call assert_report('should not get here')
1435 endtry
1436 endwhile
1437 Xpath 'c'
1438 asdf
1439 Xpath 'd'
1440 [CODE]
1441 let verify =<< trim [CODE]
1442 call assert_equal('abcd', g:Xpath)
1443 [CODE]
1444 call RunInNewVim(test, verify)
1445endfunc
1446
1447"-------------------------------------------------------------------------------
1448" Test 21: :finally for :try after :continue/:break/:return/:finish {{{1
1449"
1450" If a :try conditional stays inactive due to a preceding :continue,
1451" :break, :return, or :finish, its :finally clause should not be
1452" executed.
1453"-------------------------------------------------------------------------------
1454
1455func Test_finally_after_loop_ctrl_statement()
1456 let test =<< trim [CODE]
1457 func F()
1458 let loops = 2
1459 while loops > 0
1460 XloopNEXT
1461 let loops = loops - 1
1462 try
1463 if loops == 1
1464 Xloop 'a'
1465 continue
1466 call assert_report('should not get here')
1467 elseif loops == 0
1468 Xloop 'b'
1469 break
1470 call assert_report('should not get here')
1471 endif
1472
1473 try " inactive
1474 call assert_report('should not get here')
1475 finally
1476 call assert_report('should not get here')
1477 endtry
1478 finally
1479 Xloop 'c'
1480 endtry
1481 call assert_report('should not get here')
1482 endwhile
1483
1484 try
1485 Xpath 'd'
1486 return
1487 call assert_report('should not get here')
1488 try " inactive
1489 call assert_report('should not get here')
1490 finally
1491 call assert_report('should not get here')
1492 endtry
1493 finally
1494 Xpath 'e'
1495 endtry
1496 call assert_report('should not get here')
1497 endfunc
1498
1499 try
1500 Xpath 'f'
1501 call F()
1502 Xpath 'g'
1503 finish
1504 call assert_report('should not get here')
1505 try " inactive
1506 call assert_report('should not get here')
1507 finally
1508 call assert_report('should not get here')
1509 endtry
1510 finally
1511 Xpath 'h'
1512 endtry
1513 call assert_report('should not get here')
1514 [CODE]
1515 let verify =<< trim [CODE]
1516 call assert_equal('fa2c2b3c3degh', g:Xpath)
1517 [CODE]
1518 call RunInNewVim(test, verify)
1519endfunc
1520
1521"-------------------------------------------------------------------------------
1522" Test 22: :finally for a :try after an error/interrupt/:throw {{{1
1523"
1524" If a :try conditional stays inactive due to a preceding error or
1525" interrupt or :throw, its :finally clause should not be executed.
1526"-------------------------------------------------------------------------------
1527
1528func Test_finally_after_error_in_func()
1529 let test =<< trim [CODE]
1530 func Error()
1531 try
1532 Xpath 'b'
1533 asdf " aborting error, triggering error exception
1534 call assert_report('should not get here')
1535 endtry
1536 call assert_report('should not get here')
1537 endfunc
1538
1539 Xpath 'a'
1540 call Error()
1541 call assert_report('should not get here')
1542
1543 if 1 " not active due to error
1544 try " not active since :if inactive
1545 call assert_report('should not get here')
1546 finally
1547 call assert_report('should not get here')
1548 endtry
1549 endif
1550
1551 try " not active due to error
1552 call assert_report('should not get here')
1553 finally
1554 call assert_report('should not get here')
1555 endtry
1556 [CODE]
1557 let verify =<< trim [CODE]
1558 call assert_equal('ab', g:Xpath)
1559 [CODE]
1560 call RunInNewVim(test, verify)
1561endfunc
1562
1563func Test_finally_after_interrupt()
1564 let test =<< trim [CODE]
1565 func Interrupt()
1566 try
1567 Xpath 'a'
1568 call interrupt() " triggering interrupt exception
1569 call assert_report('should not get here')
1570 endtry
1571 endfunc
1572
1573 Xpath 'b'
1574 try
1575 call Interrupt()
1576 catch /^Vim:Interrupt$/
1577 Xpath 'c'
1578 finish
1579 endtry
1580 call assert_report('should not get here')
1581
1582 if 1 " not active due to interrupt
1583 try " not active since :if inactive
1584 call assert_report('should not get here')
1585 finally
1586 call assert_report('should not get here')
1587 endtry
1588 endif
1589
1590 try " not active due to interrupt
1591 call assert_report('should not get here')
1592 finally
1593 call assert_report('should not get here')
1594 endtry
1595 [CODE]
1596 let verify =<< trim [CODE]
1597 call assert_equal('bac', g:Xpath)
1598 [CODE]
1599 call RunInNewVim(test, verify)
1600endfunc
1601
1602func Test_finally_after_throw()
1603 let test =<< trim [CODE]
1604 func Throw()
1605 Xpath 'a'
1606 throw 'xyz'
1607 endfunc
1608
1609 Xpath 'b'
1610 call Throw()
1611 call assert_report('should not get here')
1612
1613 if 1 " not active due to :throw
1614 try " not active since :if inactive
1615 call assert_report('should not get here')
1616 finally
1617 call assert_report('should not get here')
1618 endtry
1619 endif
1620
1621 try " not active due to :throw
1622 call assert_report('should not get here')
1623 finally
1624 call assert_report('should not get here')
1625 endtry
1626 [CODE]
1627 let verify =<< trim [CODE]
1628 call assert_equal('ba', g:Xpath)
1629 [CODE]
1630 call RunInNewVim(test, verify)
1631endfunc
1632
1633"-------------------------------------------------------------------------------
1634" Test 23: :catch clauses for a :try after a :throw {{{1
1635"
1636" If a :try conditional stays inactive due to a preceding :throw,
1637" none of its :catch clauses should be executed.
1638"-------------------------------------------------------------------------------
1639
1640func Test_catch_after_throw()
1641 let test =<< trim [CODE]
1642 try
1643 Xpath 'a'
1644 throw "xyz"
1645 call assert_report('should not get here')
1646
1647 if 1 " not active due to :throw
1648 try " not active since :if inactive
1649 call assert_report('should not get here')
1650 catch /xyz/
1651 call assert_report('should not get here')
1652 endtry
1653 endif
1654 catch /xyz/
1655 Xpath 'b'
1656 endtry
1657
1658 Xpath 'c'
1659 throw "abc"
1660 call assert_report('should not get here')
1661
1662 try " not active due to :throw
1663 call assert_report('should not get here')
1664 catch /abc/
1665 call assert_report('should not get here')
1666 endtry
1667 [CODE]
1668 let verify =<< trim [CODE]
1669 call assert_equal('abc', g:Xpath)
1670 [CODE]
1671 call RunInNewVim(test, verify)
1672endfunc
1673
1674"-------------------------------------------------------------------------------
1675" Test 24: :endtry for a :try after a :throw {{{1
1676"
1677" If a :try conditional stays inactive due to a preceding :throw,
1678" its :endtry should not rethrow the exception to the next surrounding
1679" active :try conditional.
1680"-------------------------------------------------------------------------------
1681
1682func Test_endtry_after_throw()
1683 let test =<< trim [CODE]
1684 try " try 1
1685 try " try 2
1686 Xpath 'a'
1687 throw "xyz" " makes try 2 inactive
1688 call assert_report('should not get here')
1689
1690 try " try 3
1691 call assert_report('should not get here')
1692 endtry " no rethrow to try 1
1693 catch /xyz/ " should catch although try 2 inactive
1694 Xpath 'b'
1695 endtry
1696 catch /xyz/ " try 1 active, but exception already caught
1697 call assert_report('should not get here')
1698 endtry
1699 Xpath 'c'
1700 [CODE]
1701 let verify =<< trim [CODE]
1702 call assert_equal('abc', g:Xpath)
1703 [CODE]
1704 call RunInNewVim(test, verify)
1705endfunc
1706
1707"-------------------------------------------------------------------------------
1708" Test 27: Executing :finally clauses after :return {{{1
1709"
1710" For a :return command dynamically enclosed in a :try/:endtry region,
1711" :finally clauses are executed and the called function is ended.
1712"-------------------------------------------------------------------------------
1713
1714func T27_F()
1715 try
1716 Xpath 'a'
1717 try
1718 Xpath 'b'
1719 return
1720 call assert_report('should not get here')
1721 finally
1722 Xpath 'c'
1723 endtry
1724 Xpath 'd'
1725 finally
1726 Xpath 'e'
1727 endtry
1728 call assert_report('should not get here')
1729endfunc
1730
1731func T27_G()
1732 try
1733 Xpath 'f'
1734 return
1735 call assert_report('should not get here')
1736 finally
1737 Xpath 'g'
1738 call T27_F()
1739 Xpath 'h'
1740 endtry
1741 call assert_report('should not get here')
1742endfunc
1743
1744func T27_H()
1745 try
1746 Xpath 'i'
1747 call T27_G()
1748 Xpath 'j'
1749 finally
1750 Xpath 'k'
1751 return
1752 call assert_report('should not get here')
1753 endtry
1754 call assert_report('should not get here')
1755endfunction
1756
1757func Test_finally_after_return()
1758 XpathINIT
1759 try
1760 Xpath 'l'
1761 call T27_H()
1762 Xpath 'm'
1763 finally
1764 Xpath 'n'
1765 endtry
1766 call assert_equal('lifgabcehjkmn', g:Xpath)
1767endfunc
1768
1769"-------------------------------------------------------------------------------
1770" Test 28: Executing :finally clauses after :finish {{{1
1771"
1772" For a :finish command dynamically enclosed in a :try/:endtry region,
1773" :finally clauses are executed and the sourced file is finished.
1774"
1775" This test executes the bodies of the functions F, G, and H from the
1776" previous test as script files (:return replaced by :finish).
1777"-------------------------------------------------------------------------------
1778
1779func Test_finally_after_finish()
1780 XpathINIT
1781
1782 let scriptF = MakeScript("T27_F")
1783 let scriptG = MakeScript("T27_G", scriptF)
1784 let scriptH = MakeScript("T27_H", scriptG)
1785
1786 try
1787 Xpath 'A'
1788 exec "source" scriptH
1789 Xpath 'B'
1790 finally
1791 Xpath 'C'
1792 endtry
1793 Xpath 'D'
1794 call assert_equal('AifgabcehjkBCD', g:Xpath)
1795 call delete(scriptF)
1796 call delete(scriptG)
1797 call delete(scriptH)
1798endfunc
1799
1800"-------------------------------------------------------------------------------
1801" Test 29: Executing :finally clauses on errors {{{1
1802"
1803" After an error in a command dynamically enclosed in a :try/:endtry
1804" region, :finally clauses are executed and the script processing is
1805" terminated.
1806"-------------------------------------------------------------------------------
1807
1808func Test_finally_after_error_1()
1809 let test =<< trim [CODE]
1810 func F()
1811 while 1
1812 try
1813 Xpath 'a'
1814 while 1
1815 try
1816 Xpath 'b'
1817 asdf " error
1818 call assert_report('should not get here')
1819 finally
1820 Xpath 'c'
1821 endtry | call assert_report('should not get here')
1822 call assert_report('should not get here')
1823 break
1824 endwhile
1825 call assert_report('should not get here')
1826 finally
1827 Xpath 'd'
1828 endtry | call assert_report('should not get here')
1829 call assert_report('should not get here')
1830 break
1831 endwhile
1832 call assert_report('should not get here')
1833 endfunc
1834
1835 while 1
1836 try
1837 Xpath 'e'
1838 while 1
1839 call F()
1840 call assert_report('should not get here')
1841 break
1842 endwhile | call assert_report('should not get here')
1843 call assert_report('should not get here')
1844 finally
1845 Xpath 'f'
1846 endtry | call assert_report('should not get here')
1847 endwhile | call assert_report('should not get here')
1848 call assert_report('should not get here')
1849 [CODE]
1850 let verify =<< trim [CODE]
1851 call assert_equal('eabcdf', g:Xpath)
1852 [CODE]
1853 call RunInNewVim(test, verify)
1854endfunc
1855
1856func Test_finally_after_error_2()
1857 let test =<< trim [CODE]
1858 func G() abort
1859 if 1
1860 try
1861 Xpath 'a'
1862 asdf " error
1863 call assert_report('should not get here')
1864 finally
1865 Xpath 'b'
1866 endtry | Xpath 'c'
1867 endif | Xpath 'd'
1868 call assert_report('should not get here')
1869 endfunc
1870
1871 if 1
1872 try
1873 Xpath 'e'
1874 call G()
1875 call assert_report('should not get here')
1876 finally
1877 Xpath 'f'
1878 endtry | call assert_report('should not get here')
1879 endif | call assert_report('should not get here')
1880 call assert_report('should not get here')
1881 [CODE]
1882 let verify =<< trim [CODE]
1883 call assert_equal('eabf', g:Xpath)
1884 [CODE]
1885 call RunInNewVim(test, verify)
1886endfunc
1887
1888"-------------------------------------------------------------------------------
1889" Test 30: Executing :finally clauses on interrupt {{{1
1890"
1891" After an interrupt in a command dynamically enclosed in
1892" a :try/:endtry region, :finally clauses are executed and the
1893" script processing is terminated.
1894"-------------------------------------------------------------------------------
1895
1896func Test_finally_on_interrupt()
1897 let test =<< trim [CODE]
1898 func F()
1899 try
1900 Xloop 'a'
1901 call interrupt()
1902 call assert_report('should not get here')
1903 finally
1904 Xloop 'b'
1905 endtry
1906 call assert_report('should not get here')
1907 endfunc
1908
1909 try
1910 try
1911 Xpath 'c'
1912 try
1913 Xpath 'd'
1914 call interrupt()
1915 call assert_report('should not get here')
1916 finally
1917 Xpath 'e'
1918 try
1919 Xpath 'f'
1920 try
1921 Xpath 'g'
1922 finally
1923 Xpath 'h'
1924 try
1925 Xpath 'i'
1926 call interrupt()
1927 call assert_report('should not get here')
1928 endtry
1929 call assert_report('should not get here')
1930 endtry
1931 call assert_report('should not get here')
1932 endtry
1933 call assert_report('should not get here')
1934 endtry
1935 call assert_report('should not get here')
1936 finally
1937 Xpath 'j'
1938 try
1939 Xpath 'k'
1940 call F()
1941 call assert_report('should not get here')
1942 finally
1943 Xpath 'l'
1944 try
1945 Xpath 'm'
1946 XloopNEXT
1947 ExecAsScript F
1948 call assert_report('should not get here')
1949 finally
1950 Xpath 'n'
1951 endtry
1952 call assert_report('should not get here')
1953 endtry
1954 call assert_report('should not get here')
1955 endtry
1956 call assert_report('should not get here')
1957 catch /^Vim:Interrupt$/
1958 Xpath 'o'
1959 endtry
1960 [CODE]
1961 let verify =<< trim [CODE]
1962 call assert_equal('cdefghijka1b1lma2b2no', g:Xpath)
1963 [CODE]
1964 call RunInNewVim(test, verify)
1965endfunc
1966
1967"-------------------------------------------------------------------------------
1968" Test 31: Executing :finally clauses after :throw {{{1
1969"
1970" After a :throw dynamically enclosed in a :try/:endtry region,
1971" :finally clauses are executed and the script processing is
1972" terminated.
1973"-------------------------------------------------------------------------------
1974
1975func Test_finally_after_throw_2()
1976 let test =<< trim [CODE]
1977 func F()
1978 try
1979 Xloop 'a'
1980 throw "exception"
1981 call assert_report('should not get here')
1982 finally
1983 Xloop 'b'
1984 endtry
1985 call assert_report('should not get here')
1986 endfunc
1987
1988 try
1989 Xpath 'c'
1990 try
1991 Xpath 'd'
1992 throw "exception"
1993 call assert_report('should not get here')
1994 finally
1995 Xpath 'e'
1996 try
1997 Xpath 'f'
1998 try
1999 Xpath 'g'
2000 finally
2001 Xpath 'h'
2002 try
2003 Xpath 'i'
2004 throw "exception"
2005 call assert_report('should not get here')
2006 endtry
2007 call assert_report('should not get here')
2008 endtry
2009 call assert_report('should not get here')
2010 endtry
2011 call assert_report('should not get here')
2012 endtry
2013 call assert_report('should not get here')
2014 finally
2015 Xpath 'j'
2016 try
2017 Xpath 'k'
2018 call F()
2019 call assert_report('should not get here')
2020 finally
2021 Xpath 'l'
2022 try
2023 Xpath 'm'
2024 XloopNEXT
2025 ExecAsScript F
2026 call assert_report('should not get here')
2027 finally
2028 Xpath 'n'
2029 endtry
2030 call assert_report('should not get here')
2031 endtry
2032 call assert_report('should not get here')
2033 endtry
2034 call assert_report('should not get here')
2035 [CODE]
2036 let verify =<< trim [CODE]
2037 call assert_equal('cdefghijka1b1lma2b2n', g:Xpath)
2038 [CODE]
2039 call RunInNewVim(test, verify)
2040endfunc
2041
2042"-------------------------------------------------------------------------------
2043" Test 34: :finally reason discarded by :continue {{{1
2044"
2045" When a :finally clause is executed due to a :continue, :break,
2046" :return, :finish, error, interrupt or :throw, the jump reason is
2047" discarded by a :continue in the finally clause.
2048"-------------------------------------------------------------------------------
2049
2050func Test_finally_after_continue()
2051 let test =<< trim [CODE]
2052 func C(jump)
2053 XloopNEXT
2054 let loop = 0
2055 while loop < 2
2056 let loop = loop + 1
2057 if loop == 1
2058 try
2059 if a:jump == "continue"
2060 continue
2061 elseif a:jump == "break"
2062 break
2063 elseif a:jump == "return" || a:jump == "finish"
2064 return
2065 elseif a:jump == "error"
2066 asdf
2067 elseif a:jump == "interrupt"
2068 call interrupt()
2069 let dummy = 0
2070 elseif a:jump == "throw"
2071 throw "abc"
2072 endif
2073 finally
2074 continue " discards jump that caused the :finally
2075 call assert_report('should not get here')
2076 endtry
2077 call assert_report('should not get here')
2078 elseif loop == 2
2079 Xloop 'a'
2080 endif
2081 endwhile
2082 endfunc
2083
2084 call C("continue")
2085 Xpath 'b'
2086 call C("break")
2087 Xpath 'c'
2088 call C("return")
2089 Xpath 'd'
2090 let g:jump = "finish"
2091 ExecAsScript C
2092 unlet g:jump
2093 Xpath 'e'
2094 try
2095 call C("error")
2096 Xpath 'f'
2097 finally
2098 Xpath 'g'
2099 try
2100 call C("interrupt")
2101 Xpath 'h'
2102 finally
2103 Xpath 'i'
2104 call C("throw")
2105 Xpath 'j'
2106 endtry
2107 endtry
2108 Xpath 'k'
2109 [CODE]
2110 let verify =<< trim [CODE]
2111 call assert_equal('a2ba3ca4da5ea6fga7hia8jk', g:Xpath)
2112 [CODE]
2113 call RunInNewVim(test, verify)
2114endfunc
2115
2116"-------------------------------------------------------------------------------
2117" Test 35: :finally reason discarded by :break {{{1
2118"
2119" When a :finally clause is executed due to a :continue, :break,
2120" :return, :finish, error, interrupt or :throw, the jump reason is
2121" discarded by a :break in the finally clause.
2122"-------------------------------------------------------------------------------
2123
2124func Test_finally_discard_by_break()
2125 let test =<< trim [CODE]
2126 func B(jump)
2127 XloopNEXT
2128 let loop = 0
2129 while loop < 2
2130 let loop = loop + 1
2131 if loop == 1
2132 try
2133 if a:jump == "continue"
2134 continue
2135 elseif a:jump == "break"
2136 break
2137 elseif a:jump == "return" || a:jump == "finish"
2138 return
2139 elseif a:jump == "error"
2140 asdf
2141 elseif a:jump == "interrupt"
2142 call interrupt()
2143 let dummy = 0
2144 elseif a:jump == "throw"
2145 throw "abc"
2146 endif
2147 finally
2148 break " discards jump that caused the :finally
2149 call assert_report('should not get here')
2150 endtry
2151 elseif loop == 2
2152 call assert_report('should not get here')
2153 endif
2154 endwhile
2155 Xloop 'a'
2156 endfunc
2157
2158 call B("continue")
2159 Xpath 'b'
2160 call B("break")
2161 Xpath 'c'
2162 call B("return")
2163 Xpath 'd'
2164 let g:jump = "finish"
2165 ExecAsScript B
2166 unlet g:jump
2167 Xpath 'e'
2168 try
2169 call B("error")
2170 Xpath 'f'
2171 finally
2172 Xpath 'g'
2173 try
2174 call B("interrupt")
2175 Xpath 'h'
2176 finally
2177 Xpath 'i'
2178 call B("throw")
2179 Xpath 'j'
2180 endtry
2181 endtry
2182 Xpath 'k'
2183 [CODE]
2184 let verify =<< trim [CODE]
2185 call assert_equal('a2ba3ca4da5ea6fga7hia8jk', g:Xpath)
2186 [CODE]
2187 call RunInNewVim(test, verify)
2188endfunc
2189
2190"-------------------------------------------------------------------------------
2191" Test 36: :finally reason discarded by :return {{{1
2192"
2193" When a :finally clause is executed due to a :continue, :break,
2194" :return, :finish, error, interrupt or :throw, the jump reason is
2195" discarded by a :return in the finally clause.
2196"-------------------------------------------------------------------------------
2197
2198func Test_finally_discard_by_return()
2199 let test =<< trim [CODE]
2200 func R(jump, retval) abort
2201 let loop = 0
2202 while loop < 2
2203 let loop = loop + 1
2204 if loop == 1
2205 try
2206 if a:jump == "continue"
2207 continue
2208 elseif a:jump == "break"
2209 break
2210 elseif a:jump == "return"
2211 return
2212 elseif a:jump == "error"
2213 asdf
2214 elseif a:jump == "interrupt"
2215 call interrupt()
2216 let dummy = 0
2217 elseif a:jump == "throw"
2218 throw "abc"
2219 endif
2220 finally
2221 return a:retval " discards jump that caused the :finally
2222 call assert_report('should not get here')
2223 endtry
2224 elseif loop == 2
2225 call assert_report('should not get here')
2226 endif
2227 endwhile
2228 call assert_report('should not get here')
2229 endfunc
2230
2231 let sum = -R("continue", -8)
2232 Xpath 'a'
2233 let sum = sum - R("break", -16)
2234 Xpath 'b'
2235 let sum = sum - R("return", -32)
2236 Xpath 'c'
2237 try
2238 let sum = sum - R("error", -64)
2239 Xpath 'd'
2240 finally
2241 Xpath 'e'
2242 try
2243 let sum = sum - R("interrupt", -128)
2244 Xpath 'f'
2245 finally
2246 Xpath 'g'
2247 let sum = sum - R("throw", -256)
2248 Xpath 'h'
2249 endtry
2250 endtry
2251 Xpath 'i'
2252
2253 let expected = 8 + 16 + 32 + 64 + 128 + 256
2254 call assert_equal(sum, expected)
2255 [CODE]
2256 let verify =<< trim [CODE]
2257 call assert_equal('abcdefghi', g:Xpath)
2258 [CODE]
2259 call RunInNewVim(test, verify)
2260endfunc
2261
2262"-------------------------------------------------------------------------------
2263" Test 37: :finally reason discarded by :finish {{{1
2264"
2265" When a :finally clause is executed due to a :continue, :break,
2266" :return, :finish, error, interrupt or :throw, the jump reason is
2267" discarded by a :finish in the finally clause.
2268"-------------------------------------------------------------------------------
2269
2270func Test_finally_discard_by_finish()
2271 let test =<< trim [CODE]
2272 func F(jump) " not executed as function, transformed to a script
2273 let loop = 0
2274 while loop < 2
2275 let loop = loop + 1
2276 if loop == 1
2277 try
2278 if a:jump == "continue"
2279 continue
2280 elseif a:jump == "break"
2281 break
2282 elseif a:jump == "finish"
2283 finish
2284 elseif a:jump == "error"
2285 asdf
2286 elseif a:jump == "interrupt"
2287 call interrupt()
2288 let dummy = 0
2289 elseif a:jump == "throw"
2290 throw "abc"
2291 endif
2292 finally
2293 finish " discards jump that caused the :finally
2294 call assert_report('should not get here')
2295 endtry
2296 elseif loop == 2
2297 call assert_report('should not get here')
2298 endif
2299 endwhile
2300 call assert_report('should not get here')
2301 endfunc
2302
2303 let scriptF = MakeScript("F")
2304 delfunction F
2305
2306 let g:jump = "continue"
2307 exec "source" scriptF
2308 Xpath 'a'
2309 let g:jump = "break"
2310 exec "source" scriptF
2311 Xpath 'b'
2312 let g:jump = "finish"
2313 exec "source" scriptF
2314 Xpath 'c'
2315 try
2316 let g:jump = "error"
2317 exec "source" scriptF
2318 Xpath 'd'
2319 finally
2320 Xpath 'e'
2321 try
2322 let g:jump = "interrupt"
2323 exec "source" scriptF
2324 Xpath 'f'
2325 finally
2326 Xpath 'g'
2327 try
2328 let g:jump = "throw"
2329 exec "source" scriptF
2330 Xpath 'h'
2331 finally
2332 Xpath 'i'
2333 endtry
2334 endtry
2335 endtry
2336 unlet g:jump
2337 call delete(scriptF)
2338 [CODE]
2339 let verify =<< trim [CODE]
2340 call assert_equal('abcdefghi', g:Xpath)
2341 [CODE]
2342 call RunInNewVim(test, verify)
2343endfunc
2344
2345"-------------------------------------------------------------------------------
2346" Test 38: :finally reason discarded by an error {{{1
2347"
2348" When a :finally clause is executed due to a :continue, :break,
2349" :return, :finish, error, interrupt or :throw, the jump reason is
2350" discarded by an error in the finally clause.
2351"-------------------------------------------------------------------------------
2352
2353func Test_finally_discard_by_error()
2354 let test =<< trim [CODE]
2355 func E(jump)
2356 let loop = 0
2357 while loop < 2
2358 let loop = loop + 1
2359 if loop == 1
2360 try
2361 if a:jump == "continue"
2362 continue
2363 elseif a:jump == "break"
2364 break
2365 elseif a:jump == "return" || a:jump == "finish"
2366 return
2367 elseif a:jump == "error"
2368 asdf
2369 elseif a:jump == "interrupt"
2370 call interrupt()
2371 let dummy = 0
2372 elseif a:jump == "throw"
2373 throw "abc"
2374 endif
2375 finally
2376 asdf " error; discards jump that caused the :finally
2377 endtry
2378 elseif loop == 2
2379 call assert_report('should not get here')
2380 endif
2381 endwhile
2382 call assert_report('should not get here')
2383 endfunc
2384
2385 try
2386 Xpath 'a'
2387 call E("continue")
2388 call assert_report('should not get here')
2389 finally
2390 try
2391 Xpath 'b'
2392 call E("break")
2393 call assert_report('should not get here')
2394 finally
2395 try
2396 Xpath 'c'
2397 call E("return")
2398 call assert_report('should not get here')
2399 finally
2400 try
2401 Xpath 'd'
2402 let g:jump = "finish"
2403 ExecAsScript E
2404 call assert_report('should not get here')
2405 finally
2406 unlet g:jump
2407 try
2408 Xpath 'e'
2409 call E("error")
2410 call assert_report('should not get here')
2411 finally
2412 try
2413 Xpath 'f'
2414 call E("interrupt")
2415 call assert_report('should not get here')
2416 finally
2417 try
2418 Xpath 'g'
2419 call E("throw")
2420 call assert_report('should not get here')
2421 finally
2422 Xpath 'h'
2423 delfunction E
2424 endtry
2425 endtry
2426 endtry
2427 endtry
2428 endtry
2429 endtry
2430 endtry
2431 call assert_report('should not get here')
2432 [CODE]
2433 let verify =<< trim [CODE]
2434 call assert_equal('abcdefgh', g:Xpath)
2435 [CODE]
2436 call RunInNewVim(test, verify)
2437endfunc
2438
2439"-------------------------------------------------------------------------------
2440" Test 39: :finally reason discarded by an interrupt {{{1
2441"
2442" When a :finally clause is executed due to a :continue, :break,
2443" :return, :finish, error, interrupt or :throw, the jump reason is
2444" discarded by an interrupt in the finally clause.
2445"-------------------------------------------------------------------------------
2446
2447func Test_finally_discarded_by_interrupt()
2448 let test =<< trim [CODE]
2449 func I(jump)
2450 let loop = 0
2451 while loop < 2
2452 let loop = loop + 1
2453 if loop == 1
2454 try
2455 if a:jump == "continue"
2456 continue
2457 elseif a:jump == "break"
2458 break
2459 elseif a:jump == "return" || a:jump == "finish"
2460 return
2461 elseif a:jump == "error"
2462 asdf
2463 elseif a:jump == "interrupt"
2464 call interrupt()
2465 let dummy = 0
2466 elseif a:jump == "throw"
2467 throw "abc"
2468 endif
2469 finally
2470 call interrupt()
2471 let dummy = 0
2472 endtry
2473 elseif loop == 2
2474 call assert_report('should not get here')
2475 endif
2476 endwhile
2477 call assert_report('should not get here')
2478 endfunc
2479
2480 try
2481 try
2482 Xpath 'a'
2483 call I("continue")
2484 call assert_report('should not get here')
2485 finally
2486 try
2487 Xpath 'b'
2488 call I("break")
2489 call assert_report('should not get here')
2490 finally
2491 try
2492 Xpath 'c'
2493 call I("return")
2494 call assert_report('should not get here')
2495 finally
2496 try
2497 Xpath 'd'
2498 let g:jump = "finish"
2499 ExecAsScript I
2500 call assert_report('should not get here')
2501 finally
2502 unlet g:jump
2503 try
2504 Xpath 'e'
2505 call I("error")
2506 call assert_report('should not get here')
2507 finally
2508 try
2509 Xpath 'f'
2510 call I("interrupt")
2511 call assert_report('should not get here')
2512 finally
2513 try
2514 Xpath 'g'
2515 call I("throw")
2516 call assert_report('should not get here')
2517 finally
2518 Xpath 'h'
2519 delfunction I
2520 endtry
2521 endtry
2522 endtry
2523 endtry
2524 endtry
2525 endtry
2526 endtry
2527 call assert_report('should not get here')
2528 catch /^Vim:Interrupt$/
2529 Xpath 'A'
2530 endtry
2531 [CODE]
2532 let verify =<< trim [CODE]
2533 call assert_equal('abcdefghA', g:Xpath)
2534 [CODE]
2535 call RunInNewVim(test, verify)
2536endfunc
2537
2538"-------------------------------------------------------------------------------
2539" Test 40: :finally reason discarded by :throw {{{1
2540"
2541" When a :finally clause is executed due to a :continue, :break,
2542" :return, :finish, error, interrupt or :throw, the jump reason is
2543" discarded by a :throw in the finally clause.
2544"-------------------------------------------------------------------------------
2545
2546func Test_finally_discard_by_throw()
2547 let test =<< trim [CODE]
2548 func T(jump)
2549 let loop = 0
2550 while loop < 2
2551 let loop = loop + 1
2552 if loop == 1
2553 try
2554 if a:jump == "continue"
2555 continue
2556 elseif a:jump == "break"
2557 break
2558 elseif a:jump == "return" || a:jump == "finish"
2559 return
2560 elseif a:jump == "error"
2561 asdf
2562 elseif a:jump == "interrupt"
2563 call interrupt()
2564 let dummy = 0
2565 elseif a:jump == "throw"
2566 throw "abc"
2567 endif
2568 finally
2569 throw "xyz" " discards jump that caused the :finally
2570 endtry
2571 elseif loop == 2
2572 call assert_report('should not get here')
2573 endif
2574 endwhile
2575 call assert_report('should not get here')
2576 endfunc
2577
2578 try
2579 Xpath 'a'
2580 call T("continue")
2581 call assert_report('should not get here')
2582 finally
2583 try
2584 Xpath 'b'
2585 call T("break")
2586 call assert_report('should not get here')
2587 finally
2588 try
2589 Xpath 'c'
2590 call T("return")
2591 call assert_report('should not get here')
2592 finally
2593 try
2594 Xpath 'd'
2595 let g:jump = "finish"
2596 ExecAsScript T
2597 call assert_report('should not get here')
2598 finally
2599 unlet g:jump
2600 try
2601 Xpath 'e'
2602 call T("error")
2603 call assert_report('should not get here')
2604 finally
2605 try
2606 Xpath 'f'
2607 call T("interrupt")
2608 call assert_report('should not get here')
2609 finally
2610 try
2611 Xpath 'g'
2612 call T("throw")
2613 call assert_report('should not get here')
2614 finally
2615 Xpath 'h'
2616 delfunction T
2617 endtry
2618 endtry
2619 endtry
2620 endtry
2621 endtry
2622 endtry
2623 endtry
2624 call assert_report('should not get here')
2625 [CODE]
2626 let verify =<< trim [CODE]
2627 call assert_equal('abcdefgh', g:Xpath)
2628 [CODE]
2629 call RunInNewVim(test, verify)
2630endfunc
2631
2632"-------------------------------------------------------------------------------
2633" Test 49: Throwing exceptions across functions {{{1
2634"
2635" When an exception is thrown but not caught inside a function, the
2636" caller is checked for a matching :catch clause.
2637"-------------------------------------------------------------------------------
2638
2639func T49_C()
2640 try
2641 Xpath 'a'
2642 throw "arrgh"
2643 call assert_report('should not get here')
2644 catch /arrgh/
2645 Xpath 'b'
2646 endtry
2647 Xpath 'c'
2648endfunc
2649
2650func T49_T1()
2651 XloopNEXT
2652 try
2653 Xloop 'd'
2654 throw "arrgh"
2655 call assert_report('should not get here')
2656 finally
2657 Xloop 'e'
2658 endtry
2659 Xloop 'f'
2660endfunc
2661
2662func T49_T2()
2663 try
2664 Xpath 'g'
2665 call T49_T1()
2666 call assert_report('should not get here')
2667 finally
2668 Xpath 'h'
2669 endtry
2670 call assert_report('should not get here')
2671endfunc
2672
2673func Test_throw_exception_across_funcs()
2674 XpathINIT
2675 XloopINIT
2676 try
2677 Xpath 'i'
2678 call T49_C() " throw and catch
2679 Xpath 'j'
2680 catch /.*/
2681 call assert_report('should not get here')
2682 endtry
2683
2684 try
2685 Xpath 'k'
2686 call T49_T1() " throw, one level
2687 call assert_report('should not get here')
2688 catch /arrgh/
2689 Xpath 'l'
2690 catch /.*/
2691 call assert_report('should not get here')
2692 endtry
2693
2694 try
2695 Xpath 'm'
2696 call T49_T2() " throw, two levels
2697 call assert_report('should not get here')
2698 catch /arrgh/
2699 Xpath 'n'
2700 catch /.*/
2701 call assert_report('should not get here')
2702 endtry
2703 Xpath 'o'
2704
2705 call assert_equal('iabcjkd2e2lmgd3e3hno', g:Xpath)
2706endfunc
2707
2708"-------------------------------------------------------------------------------
2709" Test 50: Throwing exceptions across script files {{{1
2710"
2711" When an exception is thrown but not caught inside a script file,
2712" the sourcing script or function is checked for a matching :catch
2713" clause.
2714"
2715" This test executes the bodies of the functions C, T1, and T2 from
2716" the previous test as script files (:return replaced by :finish).
2717"-------------------------------------------------------------------------------
2718
2719func T50_F()
2720 try
2721 Xpath 'A'
2722 exec "source" g:scriptC
2723 Xpath 'B'
2724 catch /.*/
2725 call assert_report('should not get here')
2726 endtry
2727
2728 try
2729 Xpath 'C'
2730 exec "source" g:scriptT1
2731 call assert_report('should not get here')
2732 catch /arrgh/
2733 Xpath 'D'
2734 catch /.*/
2735 call assert_report('should not get here')
2736 endtry
2737endfunc
2738
2739func Test_throw_across_script()
2740 XpathINIT
2741 XloopINIT
2742 let g:scriptC = MakeScript("T49_C")
2743 let g:scriptT1 = MakeScript("T49_T1")
2744 let scriptT2 = MakeScript("T49_T2", g:scriptT1)
2745
2746 try
2747 Xpath 'E'
2748 call T50_F()
2749 Xpath 'F'
2750 exec "source" scriptT2
2751 call assert_report('should not get here')
2752 catch /arrgh/
2753 Xpath 'G'
2754 catch /.*/
2755 call assert_report('should not get here')
2756 endtry
2757 Xpath 'H'
2758 call assert_equal('EAabcBCd2e2DFgd3e3hGH', g:Xpath)
2759
2760 call delete(g:scriptC)
2761 call delete(g:scriptT1)
2762 call delete(scriptT2)
2763 unlet g:scriptC g:scriptT1 scriptT2
2764endfunc
2765
Bram Moolenaar1f068232019-11-03 16:17:26 +01002766"-------------------------------------------------------------------------------
Bram Moolenaar9470a4d2020-08-07 16:49:11 +02002767" Test 52: Uncaught exceptions {{{1
2768"
2769" When an exception is thrown but not caught, an error message is
2770" displayed when the script is terminated. In case of an interrupt
2771" or error exception, the normal interrupt or error message(s) are
2772" displayed.
2773"-------------------------------------------------------------------------------
2774
2775func Test_uncaught_exception_1()
2776 CheckEnglish
2777
2778 let test =<< trim [CODE]
2779 Xpath 'a'
2780 throw "arrgh"
2781 call assert_report('should not get here')`
2782 [CODE]
2783 let verify =<< trim [CODE]
2784 call assert_equal('E605: Exception not caught: arrgh', v:errmsg)
2785 call assert_equal('a', g:Xpath)
2786 [CODE]
2787 call RunInNewVim(test, verify)
2788endfunc
2789
2790func Test_uncaught_exception_2()
2791 CheckEnglish
2792
2793 let test =<< trim [CODE]
2794 try
2795 Xpath 'a'
2796 throw "oops"
2797 call assert_report('should not get here')`
2798 catch /arrgh/
2799 call assert_report('should not get here')`
2800 endtry
2801 call assert_report('should not get here')`
2802 [CODE]
2803 let verify =<< trim [CODE]
2804 call assert_equal('E605: Exception not caught: oops', v:errmsg)
2805 call assert_equal('a', g:Xpath)
2806 [CODE]
2807 call RunInNewVim(test, verify)
2808endfunc
2809
2810func Test_uncaught_exception_3()
2811 CheckEnglish
2812
2813 let test =<< trim [CODE]
2814 func T()
2815 Xpath 'c'
2816 throw "brrr"
2817 call assert_report('should not get here')`
2818 endfunc
2819
2820 try
2821 Xpath 'a'
2822 throw "arrgh"
2823 call assert_report('should not get here')`
2824 catch /.*/
2825 Xpath 'b'
2826 call T()
2827 call assert_report('should not get here')`
2828 endtry
2829 call assert_report('should not get here')`
2830 [CODE]
2831 let verify =<< trim [CODE]
2832 call assert_equal('E605: Exception not caught: brrr', v:errmsg)
2833 call assert_equal('abc', g:Xpath)
2834 [CODE]
2835 call RunInNewVim(test, verify)
2836endfunc
2837
2838func Test_uncaught_exception_4()
2839 CheckEnglish
2840
2841 let test =<< trim [CODE]
2842 try
2843 Xpath 'a'
2844 throw "arrgh"
2845 call assert_report('should not get here')`
2846 finally
2847 Xpath 'b'
2848 throw "brrr"
2849 call assert_report('should not get here')`
2850 endtry
2851 call assert_report('should not get here')`
2852 [CODE]
2853 let verify =<< trim [CODE]
2854 call assert_equal('E605: Exception not caught: brrr', v:errmsg)
2855 call assert_equal('ab', g:Xpath)
2856 [CODE]
2857 call RunInNewVim(test, verify)
2858endfunc
2859
2860func Test_uncaught_exception_5()
2861 CheckEnglish
2862
2863 " Need to catch and handle interrupt, otherwise the test will wait for the
2864 " user to press <Enter> to continue
2865 let test =<< trim [CODE]
2866 try
2867 try
2868 Xpath 'a'
2869 call interrupt()
2870 call assert_report('should not get here')
2871 endtry
2872 call assert_report('should not get here')
2873 catch /^Vim:Interrupt$/
2874 Xpath 'b'
2875 endtry
2876 [CODE]
2877 let verify =<< trim [CODE]
2878 call assert_equal('ab', g:Xpath)
2879 [CODE]
2880 call RunInNewVim(test, verify)
2881endfunc
2882
2883func Test_uncaught_exception_6()
2884 CheckEnglish
2885
2886 let test =<< trim [CODE]
2887 try
2888 Xpath 'a'
2889 let x = novar " error E121; exception: E121
2890 catch /E15:/ " should not catch
2891 call assert_report('should not get here')
2892 endtry
2893 call assert_report('should not get here')
2894 [CODE]
2895 let verify =<< trim [CODE]
2896 call assert_equal('a', g:Xpath)
2897 call assert_equal('E121: Undefined variable: novar', v:errmsg)
2898 [CODE]
2899 call RunInNewVim(test, verify)
2900endfunc
2901
2902func Test_uncaught_exception_7()
2903 CheckEnglish
2904
2905 let test =<< trim [CODE]
2906 try
2907 Xpath 'a'
2908 " error E108/E488; exception: E488
2909 unlet novar #
2910 catch /E108:/ " should not catch
2911 call assert_report('should not get here')
2912 endtry
2913 call assert_report('should not get here')
2914 [CODE]
2915 let verify =<< trim [CODE]
2916 call assert_equal('a', g:Xpath)
2917 call assert_equal('E488: Trailing characters: #', v:errmsg)
2918 [CODE]
2919 call RunInNewVim(test, verify)
2920endfunc
2921
2922"-------------------------------------------------------------------------------
2923" Test 53: Nesting errors: :endif/:else/:elseif {{{1
2924"
2925" For nesting errors of :if conditionals the correct error messages
2926" should be given.
2927"-------------------------------------------------------------------------------
2928
2929func Test_nested_if_else_errors()
2930 CheckEnglish
2931
2932 " :endif without :if
2933 let code =<< trim END
2934 endif
2935 END
2936 call writefile(code, 'Xtest')
2937 call AssertException(['source Xtest'], 'Vim(endif):E580: :endif without :if')
2938
2939 " :endif without :if
2940 let code =<< trim END
2941 while 1
2942 endif
2943 endwhile
2944 END
2945 call writefile(code, 'Xtest')
2946 call AssertException(['source Xtest'], 'Vim(endif):E580: :endif without :if')
2947
2948 " :endif without :if
2949 let code =<< trim END
2950 try
2951 finally
2952 endif
2953 endtry
2954 END
2955 call writefile(code, 'Xtest')
2956 call AssertException(['source Xtest'], 'Vim(endif):E580: :endif without :if')
2957
2958 " :endif without :if
2959 let code =<< trim END
2960 try
2961 endif
2962 endtry
2963 END
2964 call writefile(code, 'Xtest')
2965 call AssertException(['source Xtest'], 'Vim(endif):E580: :endif without :if')
2966
2967 " :endif without :if
2968 let code =<< trim END
2969 try
2970 throw "a"
2971 catch /a/
2972 endif
2973 endtry
2974 END
2975 call writefile(code, 'Xtest')
2976 call AssertException(['source Xtest'], 'Vim(endif):E580: :endif without :if')
2977
2978 " :else without :if
2979 let code =<< trim END
2980 else
2981 END
2982 call writefile(code, 'Xtest')
2983 call AssertException(['source Xtest'], 'Vim(else):E581: :else without :if')
2984
2985 " :else without :if
2986 let code =<< trim END
2987 while 1
2988 else
2989 endwhile
2990 END
2991 call writefile(code, 'Xtest')
2992 call AssertException(['source Xtest'], 'Vim(else):E581: :else without :if')
2993
2994 " :else without :if
2995 let code =<< trim END
2996 try
2997 finally
2998 else
2999 endtry
3000 END
3001 call writefile(code, 'Xtest')
3002 call AssertException(['source Xtest'], 'Vim(else):E581: :else without :if')
3003
3004 " :else without :if
3005 let code =<< trim END
3006 try
3007 else
3008 endtry
3009 END
3010 call writefile(code, 'Xtest')
3011 call AssertException(['source Xtest'], 'Vim(else):E581: :else without :if')
3012
3013 " :else without :if
3014 let code =<< trim END
3015 try
3016 throw "a"
3017 catch /a/
3018 else
3019 endtry
3020 END
3021 call writefile(code, 'Xtest')
3022 call AssertException(['source Xtest'], 'Vim(else):E581: :else without :if')
3023
3024 " :elseif without :if
3025 let code =<< trim END
3026 elseif
3027 END
3028 call writefile(code, 'Xtest')
3029 call AssertException(['source Xtest'], 'Vim(elseif):E582: :elseif without :if')
3030
3031 " :elseif without :if
3032 let code =<< trim END
3033 while 1
3034 elseif
3035 endwhile
3036 END
3037 call writefile(code, 'Xtest')
3038 call AssertException(['source Xtest'], 'Vim(elseif):E582: :elseif without :if')
3039
3040 " :elseif without :if
3041 let code =<< trim END
3042 try
3043 finally
3044 elseif
3045 endtry
3046 END
3047 call writefile(code, 'Xtest')
3048 call AssertException(['source Xtest'], 'Vim(elseif):E582: :elseif without :if')
3049
3050 " :elseif without :if
3051 let code =<< trim END
3052 try
3053 elseif
3054 endtry
3055 END
3056 call writefile(code, 'Xtest')
3057 call AssertException(['source Xtest'], 'Vim(elseif):E582: :elseif without :if')
3058
3059 " :elseif without :if
3060 let code =<< trim END
3061 try
3062 throw "a"
3063 catch /a/
3064 elseif
3065 endtry
3066 END
3067 call writefile(code, 'Xtest')
3068 call AssertException(['source Xtest'], 'Vim(elseif):E582: :elseif without :if')
3069
3070 " multiple :else
3071 let code =<< trim END
3072 if 1
3073 else
3074 else
3075 endif
3076 END
3077 call writefile(code, 'Xtest')
3078 call AssertException(['source Xtest'], 'Vim(else):E583: multiple :else')
3079
3080 " :elseif after :else
3081 let code =<< trim END
3082 if 1
3083 else
3084 elseif 1
3085 endif
3086 END
3087 call writefile(code, 'Xtest')
3088 call AssertException(['source Xtest'], 'Vim(elseif):E584: :elseif after :else')
3089
3090 call delete('Xtest')
3091endfunc
3092
3093"-------------------------------------------------------------------------------
3094" Test 54: Nesting errors: :while/:endwhile {{{1
3095"
3096" For nesting errors of :while conditionals the correct error messages
3097" should be given.
3098"
3099" This test reuses the function MESSAGES() from the previous test.
3100" This functions checks the messages in g:msgfile.
3101"-------------------------------------------------------------------------------
3102
3103func Test_nested_while_error()
3104 CheckEnglish
3105
3106 " :endwhile without :while
3107 let code =<< trim END
3108 endwhile
3109 END
3110 call writefile(code, 'Xtest')
3111 call AssertException(['source Xtest'], 'Vim(endwhile):E588: :endwhile without :while')
3112
3113 " :endwhile without :while
3114 let code =<< trim END
3115 if 1
3116 endwhile
3117 endif
3118 END
3119 call writefile(code, 'Xtest')
3120 call AssertException(['source Xtest'], 'Vim(endwhile):E588: :endwhile without :while')
3121
3122 " Missing :endif
3123 let code =<< trim END
3124 while 1
3125 if 1
3126 endwhile
3127 END
3128 call writefile(code, 'Xtest')
3129 call AssertException(['source Xtest'], 'Vim(endwhile):E171: Missing :endif')
3130
3131 " :endwhile without :while
3132 let code =<< trim END
3133 try
3134 finally
3135 endwhile
3136 endtry
3137 END
3138 call writefile(code, 'Xtest')
3139 call AssertException(['source Xtest'], 'Vim(endwhile):E588: :endwhile without :while')
3140
3141 " Missing :endtry
3142 let code =<< trim END
3143 while 1
3144 try
3145 finally
3146 endwhile
3147 END
3148 call writefile(code, 'Xtest')
3149 call AssertException(['source Xtest'], 'Vim(endwhile):E600: Missing :endtry')
3150
3151 " Missing :endtry
3152 let code =<< trim END
3153 while 1
3154 if 1
3155 try
3156 finally
3157 endwhile
3158 END
3159 call writefile(code, 'Xtest')
3160 call AssertException(['source Xtest'], 'Vim(endwhile):E600: Missing :endtry')
3161
3162 " Missing :endif
3163 let code =<< trim END
3164 while 1
3165 try
3166 finally
3167 if 1
3168 endwhile
3169 END
3170 call writefile(code, 'Xtest')
3171 call AssertException(['source Xtest'], 'Vim(endwhile):E171: Missing :endif')
3172
3173 " :endwhile without :while
3174 let code =<< trim END
3175 try
3176 endwhile
3177 endtry
3178 END
3179 call writefile(code, 'Xtest')
3180 call AssertException(['source Xtest'], 'Vim(endwhile):E588: :endwhile without :while')
3181
3182 " :endwhile without :while
3183 let code =<< trim END
3184 while 1
3185 try
3186 endwhile
3187 endtry
3188 endwhile
3189 END
3190 call writefile(code, 'Xtest')
3191 call AssertException(['source Xtest'], 'Vim(endwhile):E588: :endwhile without :while')
3192
3193 " :endwhile without :while
3194 let code =<< trim END
3195 try
3196 throw "a"
3197 catch /a/
3198 endwhile
3199 endtry
3200 END
3201 call writefile(code, 'Xtest')
3202 call AssertException(['source Xtest'], 'Vim(endwhile):E588: :endwhile without :while')
3203
3204 " :endwhile without :while
3205 let code =<< trim END
3206 while 1
3207 try
3208 throw "a"
3209 catch /a/
3210 endwhile
3211 endtry
3212 endwhile
3213 END
3214 call writefile(code, 'Xtest')
3215 call AssertException(['source Xtest'], 'Vim(endwhile):E588: :endwhile without :while')
3216
3217 call delete('Xtest')
3218endfunc
3219
3220"-------------------------------------------------------------------------------
3221" Test 55: Nesting errors: :continue/:break {{{1
3222"
3223" For nesting errors of :continue and :break commands the correct
3224" error messages should be given.
3225"
3226" This test reuses the function MESSAGES() from the previous test.
3227" This functions checks the messages in g:msgfile.
3228"-------------------------------------------------------------------------------
3229
3230func Test_nested_cont_break_error()
3231 CheckEnglish
3232
3233 " :continue without :while
3234 let code =<< trim END
3235 continue
3236 END
3237 call writefile(code, 'Xtest')
3238 call AssertException(['source Xtest'], 'Vim(continue):E586: :continue without :while or :for')
3239
3240 " :continue without :while
3241 let code =<< trim END
3242 if 1
3243 continue
3244 endif
3245 END
3246 call writefile(code, 'Xtest')
3247 call AssertException(['source Xtest'], 'Vim(continue):E586: :continue without :while or :for')
3248
3249 " :continue without :while
3250 let code =<< trim END
3251 try
3252 finally
3253 continue
3254 endtry
3255 END
3256 call writefile(code, 'Xtest')
3257 call AssertException(['source Xtest'], 'Vim(continue):E586: :continue without :while or :for')
3258
3259 " :continue without :while
3260 let code =<< trim END
3261 try
3262 continue
3263 endtry
3264 END
3265 call writefile(code, 'Xtest')
3266 call AssertException(['source Xtest'], 'Vim(continue):E586: :continue without :while or :for')
3267
3268 " :continue without :while
3269 let code =<< trim END
3270 try
3271 throw "a"
3272 catch /a/
3273 continue
3274 endtry
3275 END
3276 call writefile(code, 'Xtest')
3277 call AssertException(['source Xtest'], 'Vim(continue):E586: :continue without :while or :for')
3278
3279 " :break without :while
3280 let code =<< trim END
3281 break
3282 END
3283 call writefile(code, 'Xtest')
3284 call AssertException(['source Xtest'], 'Vim(break):E587: :break without :while or :for')
3285
3286 " :break without :while
3287 let code =<< trim END
3288 if 1
3289 break
3290 endif
3291 END
3292 call writefile(code, 'Xtest')
3293 call AssertException(['source Xtest'], 'Vim(break):E587: :break without :while or :for')
3294
3295 " :break without :while
3296 let code =<< trim END
3297 try
3298 finally
3299 break
3300 endtry
3301 END
3302 call writefile(code, 'Xtest')
3303 call AssertException(['source Xtest'], 'Vim(break):E587: :break without :while or :for')
3304
3305 " :break without :while
3306 let code =<< trim END
3307 try
3308 break
3309 endtry
3310 END
3311 call writefile(code, 'Xtest')
3312 call AssertException(['source Xtest'], 'Vim(break):E587: :break without :while or :for')
3313
3314 " :break without :while
3315 let code =<< trim END
3316 try
3317 throw "a"
3318 catch /a/
3319 break
3320 endtry
3321 END
3322 call writefile(code, 'Xtest')
3323 call AssertException(['source Xtest'], 'Vim(break):E587: :break without :while or :for')
3324
3325 call delete('Xtest')
3326endfunc
3327
3328"-------------------------------------------------------------------------------
3329" Test 56: Nesting errors: :endtry {{{1
3330"
3331" For nesting errors of :try conditionals the correct error messages
3332" should be given.
3333"
3334" This test reuses the function MESSAGES() from the previous test.
3335" This functions checks the messages in g:msgfile.
3336"-------------------------------------------------------------------------------
3337
3338func Test_nested_endtry_error()
3339 CheckEnglish
3340
3341 " :endtry without :try
3342 let code =<< trim END
3343 endtry
3344 END
3345 call writefile(code, 'Xtest')
3346 call AssertException(['source Xtest'], 'Vim(endtry):E602: :endtry without :try')
3347
3348 " :endtry without :try
3349 let code =<< trim END
3350 if 1
3351 endtry
3352 endif
3353 END
3354 call writefile(code, 'Xtest')
3355 call AssertException(['source Xtest'], 'Vim(endtry):E602: :endtry without :try')
3356
3357 " :endtry without :try
3358 let code =<< trim END
3359 while 1
3360 endtry
3361 endwhile
3362 END
3363 call writefile(code, 'Xtest')
3364 call AssertException(['source Xtest'], 'Vim(endtry):E602: :endtry without :try')
3365
3366 " Missing :endif
3367 let code =<< trim END
3368 try
3369 if 1
3370 endtry
3371 END
3372 call writefile(code, 'Xtest')
3373 call AssertException(['source Xtest'], 'Vim(endtry):E171: Missing :endif')
3374
3375 " Missing :endwhile
3376 let code =<< trim END
3377 try
3378 while 1
3379 endtry
3380 END
3381 call writefile(code, 'Xtest')
3382 call AssertException(['source Xtest'], 'Vim(endtry):E170: Missing :endwhile')
3383
3384 " Missing :endif
3385 let code =<< trim END
3386 try
3387 finally
3388 if 1
3389 endtry
3390 END
3391 call writefile(code, 'Xtest')
3392 call AssertException(['source Xtest'], 'Vim(endtry):E171: Missing :endif')
3393
3394 " Missing :endwhile
3395 let code =<< trim END
3396 try
3397 finally
3398 while 1
3399 endtry
3400 END
3401 call writefile(code, 'Xtest')
3402 call AssertException(['source Xtest'], 'Vim(endtry):E170: Missing :endwhile')
3403
3404 " Missing :endif
3405 let code =<< trim END
3406 try
3407 throw "a"
3408 catch /a/
3409 if 1
3410 endtry
3411 END
3412 call writefile(code, 'Xtest')
3413 call AssertException(['source Xtest'], 'Vim(endtry):E171: Missing :endif')
3414
3415 " Missing :endwhile
3416 let code =<< trim END
3417 try
3418 throw "a"
3419 catch /a/
3420 while 1
3421 endtry
3422 END
3423 call writefile(code, 'Xtest')
3424 call AssertException(['source Xtest'], 'Vim(endtry):E170: Missing :endwhile')
3425
3426 call delete('Xtest')
3427endfunc
3428
3429"-------------------------------------------------------------------------------
3430" Test 57: v:exception and v:throwpoint for user exceptions {{{1
3431"
3432" v:exception evaluates to the value of the exception that was caught
3433" most recently and is not finished. (A caught exception is finished
3434" when the next ":catch", ":finally", or ":endtry" is reached.)
3435" v:throwpoint evaluates to the script/function name and line number
3436" where that exception has been thrown.
3437"-------------------------------------------------------------------------------
3438
3439func Test_user_exception_info()
3440 CheckEnglish
3441
3442 XpathINIT
3443 XloopINIT
3444
3445 func FuncException()
3446 let g:exception = v:exception
3447 endfunc
3448
3449 func FuncThrowpoint()
3450 let g:throwpoint = v:throwpoint
3451 endfunc
3452
3453 let scriptException = MakeScript("FuncException")
3454 let scriptThrowPoint = MakeScript("FuncThrowpoint")
3455
3456 command! CmdException let g:exception = v:exception
3457 command! CmdThrowpoint let g:throwpoint = v:throwpoint
3458
3459 func T(arg, line)
3460 if a:line == 2
3461 throw a:arg " in line 2
3462 elseif a:line == 4
3463 throw a:arg " in line 4
3464 elseif a:line == 6
3465 throw a:arg " in line 6
3466 elseif a:line == 8
3467 throw a:arg " in line 8
3468 endif
3469 endfunc
3470
3471 func G(arg, line)
3472 call T(a:arg, a:line)
3473 endfunc
3474
3475 func F(arg, line)
3476 call G(a:arg, a:line)
3477 endfunc
3478
3479 let scriptT = MakeScript("T")
3480 let scriptG = MakeScript("G", scriptT)
3481 let scriptF = MakeScript("F", scriptG)
3482
3483 try
3484 Xpath 'a'
3485 call F("oops", 2)
3486 catch /.*/
3487 Xpath 'b'
3488 let exception = v:exception
3489 let throwpoint = v:throwpoint
3490 call assert_equal("oops", v:exception)
3491 call assert_match('\<F\[1]\.\.G\[1]\.\.T\>', v:throwpoint)
3492 call assert_match('\<2\>', v:throwpoint)
3493
3494 exec "let exception = v:exception"
3495 exec "let throwpoint = v:throwpoint"
3496 call assert_equal("oops", v:exception)
3497 call assert_match('\<F\[1]\.\.G\[1]\.\.T\>', v:throwpoint)
3498 call assert_match('\<2\>', v:throwpoint)
3499
3500 CmdException
3501 CmdThrowpoint
3502 call assert_equal("oops", v:exception)
3503 call assert_match('\<F\[1]\.\.G\[1]\.\.T\>', v:throwpoint)
3504 call assert_match('\<2\>', v:throwpoint)
3505
3506 call FuncException()
3507 call FuncThrowpoint()
3508 call assert_equal("oops", v:exception)
3509 call assert_match('\<F\[1]\.\.G\[1]\.\.T\>', v:throwpoint)
3510 call assert_match('\<2\>', v:throwpoint)
3511
3512 exec "source" scriptException
3513 exec "source" scriptThrowPoint
3514 call assert_equal("oops", v:exception)
3515 call assert_match('\<F\[1]\.\.G\[1]\.\.T\>', v:throwpoint)
3516 call assert_match('\<2\>', v:throwpoint)
3517
3518 try
3519 Xpath 'c'
3520 call G("arrgh", 4)
3521 catch /.*/
3522 Xpath 'd'
3523 let exception = v:exception
3524 let throwpoint = v:throwpoint
3525 call assert_equal("arrgh", v:exception)
3526 call assert_match('\<G\[1]\.\.T\>', v:throwpoint)
3527 call assert_match('\<4\>', v:throwpoint)
3528
3529 try
3530 Xpath 'e'
3531 let g:arg = "autsch"
3532 let g:line = 6
3533 exec "source" scriptF
3534 catch /.*/
3535 Xpath 'f'
3536 let exception = v:exception
3537 let throwpoint = v:throwpoint
3538 call assert_equal("autsch", v:exception)
3539 call assert_match(fnamemodify(scriptT, ':t'), v:throwpoint)
3540 call assert_match('\<6\>', v:throwpoint)
3541 finally
3542 Xpath 'g'
3543 let exception = v:exception
3544 let throwpoint = v:throwpoint
3545 call assert_equal("arrgh", v:exception)
3546 call assert_match('\<G\[1]\.\.T\>', v:throwpoint)
3547 call assert_match('\<4\>', v:throwpoint)
3548 try
3549 Xpath 'h'
3550 let g:arg = "brrrr"
3551 let g:line = 8
3552 exec "source" scriptG
3553 catch /.*/
3554 Xpath 'i'
3555 let exception = v:exception
3556 let throwpoint = v:throwpoint
3557 " Resolve scriptT for matching it against v:throwpoint.
3558 call assert_equal("brrrr", v:exception)
3559 call assert_match(fnamemodify(scriptT, ':t'), v:throwpoint)
3560 call assert_match('\<8\>', v:throwpoint)
3561 finally
3562 Xpath 'j'
3563 let exception = v:exception
3564 let throwpoint = v:throwpoint
3565 call assert_equal("arrgh", v:exception)
3566 call assert_match('\<G\[1]\.\.T\>', v:throwpoint)
3567 call assert_match('\<4\>', v:throwpoint)
3568 endtry
3569 Xpath 'k'
3570 let exception = v:exception
3571 let throwpoint = v:throwpoint
3572 call assert_equal("arrgh", v:exception)
3573 call assert_match('\<G\[1]\.\.T\>', v:throwpoint)
3574 call assert_match('\<4\>', v:throwpoint)
3575 endtry
3576 Xpath 'l'
3577 let exception = v:exception
3578 let throwpoint = v:throwpoint
3579 call assert_equal("arrgh", v:exception)
3580 call assert_match('\<G\[1]\.\.T\>', v:throwpoint)
3581 call assert_match('\<4\>', v:throwpoint)
3582 finally
3583 Xpath 'm'
3584 let exception = v:exception
3585 let throwpoint = v:throwpoint
3586 call assert_equal("oops", v:exception)
3587 call assert_match('\<F\[1]\.\.G\[1]\.\.T\>', v:throwpoint)
3588 call assert_match('\<2\>', v:throwpoint)
3589 endtry
3590 Xpath 'n'
3591 let exception = v:exception
3592 let throwpoint = v:throwpoint
3593 call assert_equal("oops", v:exception)
3594 call assert_match('\<F\[1]\.\.G\[1]\.\.T\>', v:throwpoint)
3595 call assert_match('\<2\>', v:throwpoint)
3596 finally
3597 Xpath 'o'
3598 let exception = v:exception
3599 let throwpoint = v:throwpoint
3600 call assert_equal("", v:exception)
3601 call assert_match('^$', v:throwpoint)
3602 call assert_match('^$', v:throwpoint)
3603 endtry
3604
3605 call assert_equal('abcdefghijklmno', g:Xpath)
3606
3607 unlet exception throwpoint
3608 delfunction FuncException
3609 delfunction FuncThrowpoint
3610 call delete(scriptException)
3611 call delete(scriptThrowPoint)
3612 unlet scriptException scriptThrowPoint
3613 delcommand CmdException
3614 delcommand CmdThrowpoint
3615 delfunction T
3616 delfunction G
3617 delfunction F
3618 call delete(scriptT)
3619 call delete(scriptG)
3620 call delete(scriptF)
3621 unlet scriptT scriptG scriptF
3622endfunc
3623
3624"-------------------------------------------------------------------------------
3625"
3626" Test 58: v:exception and v:throwpoint for error/interrupt exceptions {{{1
3627"
3628" v:exception and v:throwpoint work also for error and interrupt
3629" exceptions.
3630"-------------------------------------------------------------------------------
3631
3632func Test_execption_info_for_error()
3633 CheckEnglish
3634
3635 let test =<< trim [CODE]
3636 func T(line)
3637 if a:line == 2
3638 delfunction T " error (function in use) in line 2
3639 elseif a:line == 4
3640 call interrupt()
3641 endif
3642 endfunc
3643
3644 while 1
3645 try
3646 Xpath 'a'
3647 call T(2)
3648 call assert_report('should not get here')
3649 catch /.*/
3650 Xpath 'b'
3651 if v:exception !~ 'Vim(delfunction):'
3652 call assert_report('should not get here')
3653 endif
3654 if v:throwpoint !~ '\<T\>'
3655 call assert_report('should not get here')
3656 endif
3657 if v:throwpoint !~ '\<2\>'
3658 call assert_report('should not get here')
3659 endif
3660 finally
3661 Xpath 'c'
3662 if v:exception != ""
3663 call assert_report('should not get here')
3664 endif
3665 if v:throwpoint != ""
3666 call assert_report('should not get here')
3667 endif
3668 break
3669 endtry
3670 endwhile
3671
3672 Xpath 'd'
3673 if v:exception != ""
3674 call assert_report('should not get here')
3675 endif
3676 if v:throwpoint != ""
3677 call assert_report('should not get here')
3678 endif
3679
3680 while 1
3681 try
3682 Xpath 'e'
3683 call T(4)
3684 call assert_report('should not get here')
3685 catch /.*/
3686 Xpath 'f'
3687 if v:exception != 'Vim:Interrupt'
3688 call assert_report('should not get here')
3689 endif
3690 if v:throwpoint !~ 'function T'
3691 call assert_report('should not get here')
3692 endif
3693 if v:throwpoint !~ '\<4\>'
3694 call assert_report('should not get here')
3695 endif
3696 finally
3697 Xpath 'g'
3698 if v:exception != ""
3699 call assert_report('should not get here')
3700 endif
3701 if v:throwpoint != ""
3702 call assert_report('should not get here')
3703 endif
3704 break
3705 endtry
3706 endwhile
3707
3708 Xpath 'h'
3709 if v:exception != ""
3710 call assert_report('should not get here')
3711 endif
3712 if v:throwpoint != ""
3713 call assert_report('should not get here')
3714 endif
3715 [CODE]
3716 let verify =<< trim [CODE]
3717 call assert_equal('abcdefgh', g:Xpath)
3718 [CODE]
3719 call RunInNewVim(test, verify)
3720endfunc
3721
3722"-------------------------------------------------------------------------------
3723" Test 61: Catching interrupt exceptions {{{1
3724"
3725" When an interrupt occurs inside a :try/:endtry region, an
3726" interrupt exception is thrown and can be caught. Its value is
3727" "Vim:Interrupt". If the interrupt occurs after an error or a :throw
3728" but before a matching :catch is reached, all following :catches of
3729" that try block are ignored, but the interrupt exception can be
3730" caught by the next surrounding try conditional. An interrupt is
3731" ignored when there is a previous interrupt that has not been caught
3732" or causes a :finally clause to be executed.
3733"-------------------------------------------------------------------------------
3734
3735func Test_catch_intr_exception()
3736 let test =<< trim [CODE]
3737 while 1
3738 try
3739 try
3740 Xpath 'a'
3741 call interrupt()
3742 call assert_report('should not get here')
3743 catch /^Vim:Interrupt$/
3744 Xpath 'b'
3745 finally
3746 Xpath 'c'
3747 endtry
3748 catch /.*/
3749 call assert_report('should not get here')
3750 finally
3751 Xpath 'd'
3752 break
3753 endtry
3754 endwhile
3755
3756 while 1
3757 try
3758 try
3759 try
3760 Xpath 'e'
3761 asdf
3762 call assert_report('should not get here')
3763 catch /do_not_catch/
3764 call assert_report('should not get here')
3765 catch /.*/
3766 Xpath 'f'
3767 call interrupt()
3768 call assert_report('should not get here')
3769 catch /.*/
3770 call assert_report('should not get here')
3771 finally
3772 Xpath 'g'
3773 call interrupt()
3774 call assert_report('should not get here')
3775 endtry
3776 catch /^Vim:Interrupt$/
3777 Xpath 'h'
3778 finally
3779 Xpath 'i'
3780 endtry
3781 catch /.*/
3782 call assert_report('should not get here')
3783 finally
3784 Xpath 'j'
3785 break
3786 endtry
3787 endwhile
3788
3789 while 1
3790 try
3791 try
3792 try
3793 Xpath 'k'
3794 throw "x"
3795 call assert_report('should not get here')
3796 catch /do_not_catch/
3797 call assert_report('should not get here')
3798 catch /x/
3799 Xpath 'l'
3800 call interrupt()
3801 call assert_report('should not get here')
3802 catch /.*/
3803 call assert_report('should not get here')
3804 endtry
3805 catch /^Vim:Interrupt$/
3806 Xpath 'm'
3807 finally
3808 Xpath 'n'
3809 endtry
3810 catch /.*/
3811 call assert_report('should not get here')
3812 finally
3813 Xpath 'o'
3814 break
3815 endtry
3816 endwhile
3817
3818 while 1
3819 try
3820 try
3821 Xpath 'p'
3822 call interrupt()
3823 call assert_report('should not get here')
3824 catch /do_not_catch/
3825 call interrupt()
3826 call assert_report('should not get here')
3827 catch /^Vim:Interrupt$/
3828 Xpath 'q'
3829 finally
3830 Xpath 'r'
3831 endtry
3832 catch /.*/
3833 call assert_report('should not get here')
3834 finally
3835 Xpath 's'
3836 break
3837 endtry
3838 endwhile
3839
3840 Xpath 't'
3841 [CODE]
3842 let verify =<< trim [CODE]
3843 call assert_equal('abcdefghijklmnopqrst', g:Xpath)
3844 [CODE]
3845 call RunInNewVim(test, verify)
3846endfunc
3847
3848"-------------------------------------------------------------------------------
3849" Test 65: Errors in the /pattern/ argument of a :catch {{{1
3850"
3851" On an error in the /pattern/ argument of a :catch, the :catch does
3852" not match. Any following :catches of the same :try/:endtry don't
3853" match either. Finally clauses are executed.
3854"-------------------------------------------------------------------------------
3855
3856func Test_catch_pattern_error()
3857 CheckEnglish
3858 XpathINIT
3859
3860 try
3861 try
3862 Xpath 'a'
3863 throw "oops"
3864 catch /^oops$/
3865 Xpath 'b'
3866 catch /\)/ " not checked; exception has already been caught
3867 call assert_report('should not get here')
3868 endtry
3869 Xpath 'c'
3870 catch /.*/
3871 call assert_report('should not get here')
3872 endtry
3873 call assert_equal('abc', g:Xpath)
3874
3875 XpathINIT
3876 func F()
3877 try
3878 try
3879 try
3880 Xpath 'a'
3881 throw "ab"
3882 catch /abc/ " does not catch
3883 call assert_report('should not get here')
3884 catch /\)/ " error; discards exception
3885 call assert_report('should not get here')
3886 catch /.*/ " not checked
3887 call assert_report('should not get here')
3888 finally
3889 Xpath 'b'
3890 endtry
3891 call assert_report('should not get here')
3892 catch /^ab$/ " checked, but original exception is discarded
3893 call assert_report('should not get here')
3894 catch /^Vim(catch):/
3895 Xpath 'c'
3896 call assert_match('Vim(catch):E475: Invalid argument:', v:exception)
3897 finally
3898 Xpath 'd'
3899 endtry
3900 Xpath 'e'
3901 catch /.*/
3902 call assert_report('should not get here')
3903 endtry
3904 Xpath 'f'
3905 endfunc
3906
3907 call F()
3908 call assert_equal('abcdef', g:Xpath)
3909
3910 delfunc F
3911endfunc
3912
3913"-------------------------------------------------------------------------------
Bram Moolenaar1f068232019-11-03 16:17:26 +01003914" Test 87 using (expr) ? funcref : funcref {{{1
3915"
3916" Vim needs to correctly parse the funcref and even when it does
3917" not execute the funcref, it needs to consume the trailing ()
3918"-------------------------------------------------------------------------------
3919
3920func Add2(x1, x2)
3921 return a:x1 + a:x2
3922endfu
3923
3924func GetStr()
3925 return "abcdefghijklmnopqrstuvwxyp"
3926endfu
3927
3928func Test_funcref_with_condexpr()
3929 call assert_equal(5, function('Add2')(2,3))
3930
3931 call assert_equal(3, 1 ? function('Add2')(1,2) : function('Add2')(2,3))
3932 call assert_equal(5, 0 ? function('Add2')(1,2) : function('Add2')(2,3))
3933 " Make sure, GetStr() still works.
3934 call assert_equal('abcdefghijk', GetStr()[0:10])
3935endfunc
3936
Bram Moolenaar4119cf82016-01-17 14:59:01 +01003937" Test 90: Recognizing {} in variable name. {{{1
3938"-------------------------------------------------------------------------------
3939
3940func Test_curlies()
3941 let s:var = 66
3942 let ns = 's'
3943 call assert_equal(66, {ns}:var)
3944
3945 let g:a = {}
3946 let g:b = 't'
3947 let g:a[g:b] = 77
3948 call assert_equal(77, g:a['t'])
3949endfunc
Bram Moolenaara2cce862016-01-02 19:50:04 +01003950
3951"-------------------------------------------------------------------------------
Bram Moolenaarf95534c2016-01-23 21:59:52 +01003952" Test 91: using type(). {{{1
3953"-------------------------------------------------------------------------------
3954
3955func Test_type()
3956 call assert_equal(0, type(0))
3957 call assert_equal(1, type(""))
3958 call assert_equal(2, type(function("tr")))
Bram Moolenaar953cc7f2016-03-19 18:52:29 +01003959 call assert_equal(2, type(function("tr", [8])))
Bram Moolenaarf95534c2016-01-23 21:59:52 +01003960 call assert_equal(3, type([]))
3961 call assert_equal(4, type({}))
Bram Moolenaar5feabe02020-01-30 18:24:53 +01003962 if has('float')
3963 call assert_equal(5, type(0.0))
3964 endif
Bram Moolenaarf95534c2016-01-23 21:59:52 +01003965 call assert_equal(6, type(v:false))
3966 call assert_equal(6, type(v:true))
3967 call assert_equal(7, type(v:none))
3968 call assert_equal(7, type(v:null))
Bram Moolenaarf562e722016-07-19 17:25:25 +02003969 call assert_equal(8, v:t_job)
3970 call assert_equal(9, v:t_channel)
3971 call assert_equal(v:t_number, type(0))
3972 call assert_equal(v:t_string, type(""))
3973 call assert_equal(v:t_func, type(function("tr")))
3974 call assert_equal(v:t_func, type(function("tr", [8])))
3975 call assert_equal(v:t_list, type([]))
3976 call assert_equal(v:t_dict, type({}))
Bram Moolenaar5feabe02020-01-30 18:24:53 +01003977 if has('float')
3978 call assert_equal(v:t_float, type(0.0))
3979 endif
Bram Moolenaarf562e722016-07-19 17:25:25 +02003980 call assert_equal(v:t_bool, type(v:false))
3981 call assert_equal(v:t_bool, type(v:true))
3982 call assert_equal(v:t_none, type(v:none))
3983 call assert_equal(v:t_none, type(v:null))
Bram Moolenaar92b83cc2020-04-25 15:24:44 +02003984 call assert_equal(v:t_string, type(test_null_string()))
3985 call assert_equal(v:t_func, type(test_null_function()))
3986 call assert_equal(v:t_func, type(test_null_partial()))
3987 call assert_equal(v:t_list, type(test_null_list()))
3988 call assert_equal(v:t_dict, type(test_null_dict()))
3989 if has('job')
3990 call assert_equal(v:t_job, type(test_null_job()))
3991 endif
3992 if has('channel')
3993 call assert_equal(v:t_channel, type(test_null_channel()))
3994 endif
3995 call assert_equal(v:t_blob, type(test_null_blob()))
Bram Moolenaarf562e722016-07-19 17:25:25 +02003996
Bram Moolenaar7c215c52020-02-29 13:43:27 +01003997 call assert_fails("call type(test_void())", 'E685:')
3998 call assert_fails("call type(test_unknown())", 'E685:')
Bram Moolenaar17a13432016-01-24 14:22:10 +01003999
4000 call assert_equal(0, 0 + v:false)
4001 call assert_equal(1, 0 + v:true)
4002 call assert_equal(0, 0 + v:none)
4003 call assert_equal(0, 0 + v:null)
4004
Bram Moolenaarf48aa162016-01-24 17:54:24 +01004005 call assert_equal('v:false', '' . v:false)
4006 call assert_equal('v:true', '' . v:true)
4007 call assert_equal('v:none', '' . v:none)
4008 call assert_equal('v:null', '' . v:null)
Bram Moolenaar6039c7f2016-01-24 15:05:32 +01004009
4010 call assert_true(v:false == 0)
4011 call assert_false(v:false != 0)
4012 call assert_true(v:true == 1)
4013 call assert_false(v:true != 1)
4014 call assert_false(v:true == v:false)
4015 call assert_true(v:true != v:false)
4016
4017 call assert_true(v:null == 0)
4018 call assert_false(v:null != 0)
4019 call assert_true(v:none == 0)
4020 call assert_false(v:none != 0)
Bram Moolenaar04369222016-01-24 17:21:29 +01004021
4022 call assert_true(v:false is v:false)
4023 call assert_true(v:true is v:true)
4024 call assert_true(v:none is v:none)
4025 call assert_true(v:null is v:null)
4026
4027 call assert_false(v:false isnot v:false)
4028 call assert_false(v:true isnot v:true)
4029 call assert_false(v:none isnot v:none)
4030 call assert_false(v:null isnot v:null)
4031
4032 call assert_false(v:false is 0)
4033 call assert_false(v:true is 1)
4034 call assert_false(v:true is v:false)
4035 call assert_false(v:none is 0)
4036 call assert_false(v:null is 0)
4037 call assert_false(v:null is v:none)
4038
4039 call assert_true(v:false isnot 0)
4040 call assert_true(v:true isnot 1)
4041 call assert_true(v:true isnot v:false)
4042 call assert_true(v:none isnot 0)
4043 call assert_true(v:null isnot 0)
4044 call assert_true(v:null isnot v:none)
Bram Moolenaar65591002016-01-24 21:51:57 +01004045
4046 call assert_equal(v:false, eval(string(v:false)))
4047 call assert_equal(v:true, eval(string(v:true)))
4048 call assert_equal(v:none, eval(string(v:none)))
4049 call assert_equal(v:null, eval(string(v:null)))
Bram Moolenaar767d8c12016-01-25 20:22:54 +01004050
Bram Moolenaar15550002016-01-31 18:45:24 +01004051 call assert_equal(v:false, copy(v:false))
4052 call assert_equal(v:true, copy(v:true))
4053 call assert_equal(v:none, copy(v:none))
4054 call assert_equal(v:null, copy(v:null))
4055
4056 call assert_equal([v:false], deepcopy([v:false]))
4057 call assert_equal([v:true], deepcopy([v:true]))
4058 call assert_equal([v:none], deepcopy([v:none]))
4059 call assert_equal([v:null], deepcopy([v:null]))
4060
Bram Moolenaar767d8c12016-01-25 20:22:54 +01004061 call assert_true(empty(v:false))
4062 call assert_false(empty(v:true))
4063 call assert_true(empty(v:null))
4064 call assert_true(empty(v:none))
Bram Moolenaar6650a692016-01-26 19:59:10 +01004065
4066 func ChangeYourMind()
Bram Moolenaar1e115362019-01-09 23:01:02 +01004067 try
4068 return v:true
4069 finally
4070 return 'something else'
4071 endtry
Bram Moolenaar6650a692016-01-26 19:59:10 +01004072 endfunc
4073
4074 call ChangeYourMind()
Bram Moolenaarf95534c2016-01-23 21:59:52 +01004075endfunc
4076
4077"-------------------------------------------------------------------------------
Bram Moolenaarea8c2192016-02-07 19:27:53 +01004078" Test 92: skipping code {{{1
4079"-------------------------------------------------------------------------------
4080
4081func Test_skip()
4082 let Fn = function('Test_type')
4083 call assert_false(0 && Fn[1])
4084 call assert_false(0 && string(Fn))
4085 call assert_false(0 && len(Fn))
4086 let l = []
4087 call assert_false(0 && l[1])
4088 call assert_false(0 && string(l))
4089 call assert_false(0 && len(l))
4090 let f = 1.0
4091 call assert_false(0 && f[1])
4092 call assert_false(0 && string(f))
4093 call assert_false(0 && len(f))
4094 let sp = v:null
4095 call assert_false(0 && sp[1])
4096 call assert_false(0 && string(sp))
4097 call assert_false(0 && len(sp))
4098
4099endfunc
4100
4101"-------------------------------------------------------------------------------
Bram Moolenaar18dfb442016-05-31 22:31:23 +02004102" Test 93: :echo and string() {{{1
4103"-------------------------------------------------------------------------------
4104
4105func Test_echo_and_string()
4106 " String
4107 let a = 'foo bar'
4108 redir => result
4109 echo a
4110 echo string(a)
4111 redir END
4112 let l = split(result, "\n")
4113 call assert_equal(["foo bar",
4114 \ "'foo bar'"], l)
4115
4116 " Float
4117 if has('float')
4118 let a = -1.2e0
4119 redir => result
4120 echo a
4121 echo string(a)
4122 redir END
4123 let l = split(result, "\n")
4124 call assert_equal(["-1.2",
4125 \ "-1.2"], l)
4126 endif
4127
4128 " Funcref
4129 redir => result
4130 echo function('string')
4131 echo string(function('string'))
4132 redir END
4133 let l = split(result, "\n")
4134 call assert_equal(["string",
4135 \ "function('string')"], l)
4136
4137 " Recursive dictionary
4138 let a = {}
4139 let a["a"] = a
4140 redir => result
4141 echo a
4142 echo string(a)
4143 redir END
4144 let l = split(result, "\n")
4145 call assert_equal(["{'a': {...}}",
4146 \ "{'a': {...}}"], l)
4147
4148 " Recursive list
4149 let a = [0]
4150 let a[0] = a
4151 redir => result
4152 echo a
4153 echo string(a)
4154 redir END
4155 let l = split(result, "\n")
4156 call assert_equal(["[[...]]",
4157 \ "[[...]]"], l)
4158
4159 " Empty dictionaries in a list
4160 let a = {}
4161 redir => result
4162 echo [a, a, a]
4163 echo string([a, a, a])
4164 redir END
4165 let l = split(result, "\n")
4166 call assert_equal(["[{}, {}, {}]",
4167 \ "[{}, {}, {}]"], l)
4168
4169 " Empty dictionaries in a dictionary
4170 let a = {}
4171 let b = {"a": a, "b": a}
4172 redir => result
4173 echo b
4174 echo string(b)
4175 redir END
4176 let l = split(result, "\n")
4177 call assert_equal(["{'a': {}, 'b': {}}",
4178 \ "{'a': {}, 'b': {}}"], l)
4179
4180 " Empty lists in a list
4181 let a = []
4182 redir => result
4183 echo [a, a, a]
4184 echo string([a, a, a])
4185 redir END
4186 let l = split(result, "\n")
4187 call assert_equal(["[[], [], []]",
4188 \ "[[], [], []]"], l)
4189
4190 " Empty lists in a dictionary
4191 let a = []
4192 let b = {"a": a, "b": a}
4193 redir => result
4194 echo b
4195 echo string(b)
4196 redir END
4197 let l = split(result, "\n")
4198 call assert_equal(["{'a': [], 'b': []}",
4199 \ "{'a': [], 'b': []}"], l)
4200
4201 " Dictionaries in a list
4202 let a = {"one": "yes", "two": "yes", "three": "yes"}
4203 redir => result
4204 echo [a, a, a]
4205 echo string([a, a, a])
4206 redir END
4207 let l = split(result, "\n")
4208 call assert_equal(["[{'one': 'yes', 'two': 'yes', 'three': 'yes'}, {...}, {...}]",
4209 \ "[{'one': 'yes', 'two': 'yes', 'three': 'yes'}, {'one': 'yes', 'two': 'yes', 'three': 'yes'}, {'one': 'yes', 'two': 'yes', 'three': 'yes'}]"], l)
4210
4211 " Dictionaries in a dictionary
4212 let a = {"one": "yes", "two": "yes", "three": "yes"}
4213 let b = {"a": a, "b": a}
4214 redir => result
4215 echo b
4216 echo string(b)
4217 redir END
4218 let l = split(result, "\n")
4219 call assert_equal(["{'a': {'one': 'yes', 'two': 'yes', 'three': 'yes'}, 'b': {...}}",
4220 \ "{'a': {'one': 'yes', 'two': 'yes', 'three': 'yes'}, 'b': {'one': 'yes', 'two': 'yes', 'three': 'yes'}}"], l)
4221
4222 " Lists in a list
4223 let a = [1, 2, 3]
4224 redir => result
4225 echo [a, a, a]
4226 echo string([a, a, a])
4227 redir END
4228 let l = split(result, "\n")
4229 call assert_equal(["[[1, 2, 3], [...], [...]]",
4230 \ "[[1, 2, 3], [1, 2, 3], [1, 2, 3]]"], l)
4231
4232 " Lists in a dictionary
4233 let a = [1, 2, 3]
4234 let b = {"a": a, "b": a}
4235 redir => result
4236 echo b
4237 echo string(b)
4238 redir END
4239 let l = split(result, "\n")
4240 call assert_equal(["{'a': [1, 2, 3], 'b': [...]}",
4241 \ "{'a': [1, 2, 3], 'b': [1, 2, 3]}"], l)
4242
Bram Moolenaar1363a302020-04-12 13:50:26 +02004243 call assert_fails('echo &:', 'E112:')
4244 call assert_fails('echo &g:', 'E112:')
4245 call assert_fails('echo &l:', 'E112:')
4246
Bram Moolenaar18dfb442016-05-31 22:31:23 +02004247endfunc
4248
4249"-------------------------------------------------------------------------------
Bram Moolenaar22fcfad2016-07-01 18:17:26 +02004250" Test 94: 64-bit Numbers {{{1
4251"-------------------------------------------------------------------------------
4252
4253func Test_num64()
Bram Moolenaar22fcfad2016-07-01 18:17:26 +02004254 call assert_notequal( 4294967296, 0)
4255 call assert_notequal(-4294967296, 0)
4256 call assert_equal( 4294967296, 0xFFFFffff + 1)
4257 call assert_equal(-4294967296, -0xFFFFffff - 1)
4258
4259 call assert_equal( 9223372036854775807, 1 / 0)
4260 call assert_equal(-9223372036854775807, -1 / 0)
Bram Moolenaar7a40ea22017-01-22 18:34:57 +01004261 call assert_equal(-9223372036854775807 - 1, 0 / 0)
Bram Moolenaar22fcfad2016-07-01 18:17:26 +02004262
Bram Moolenaar5feabe02020-01-30 18:24:53 +01004263 if has('float')
4264 call assert_equal( 0x7FFFffffFFFFffff, float2nr( 1.0e150))
4265 call assert_equal(-0x7FFFffffFFFFffff, float2nr(-1.0e150))
4266 endif
Bram Moolenaar22fcfad2016-07-01 18:17:26 +02004267
4268 let rng = range(0xFFFFffff, 0x100000001)
4269 call assert_equal([0xFFFFffff, 0x100000000, 0x100000001], rng)
4270 call assert_equal(0x100000001, max(rng))
4271 call assert_equal(0xFFFFffff, min(rng))
4272 call assert_equal(rng, sort(range(0x100000001, 0xFFFFffff, -1), 'N'))
4273endfunc
4274
4275"-------------------------------------------------------------------------------
Bram Moolenaar70bcd732017-01-12 22:20:54 +01004276" Test 95: lines of :append, :change, :insert {{{1
4277"-------------------------------------------------------------------------------
4278
4279function! DefineFunction(name, body)
4280 let func = join(['function! ' . a:name . '()'] + a:body + ['endfunction'], "\n")
4281 exec func
4282endfunction
4283
4284func Test_script_lines()
4285 " :append
4286 try
Bram Moolenaar1e115362019-01-09 23:01:02 +01004287 call DefineFunction('T_Append', [
4288 \ 'append',
4289 \ 'py <<EOS',
4290 \ '.',
4291 \ ])
Bram Moolenaar70bcd732017-01-12 22:20:54 +01004292 catch
Bram Moolenaar1e115362019-01-09 23:01:02 +01004293 call assert_report("Can't define function")
Bram Moolenaar70bcd732017-01-12 22:20:54 +01004294 endtry
4295 try
Bram Moolenaar1e115362019-01-09 23:01:02 +01004296 call DefineFunction('T_Append', [
4297 \ 'append',
4298 \ 'abc',
4299 \ ])
4300 call assert_report("Shouldn't be able to define function")
Bram Moolenaar70bcd732017-01-12 22:20:54 +01004301 catch
Bram Moolenaar1e115362019-01-09 23:01:02 +01004302 call assert_exception('Vim(function):E126: Missing :endfunction')
Bram Moolenaar70bcd732017-01-12 22:20:54 +01004303 endtry
4304
4305 " :change
4306 try
Bram Moolenaar1e115362019-01-09 23:01:02 +01004307 call DefineFunction('T_Change', [
4308 \ 'change',
4309 \ 'py <<EOS',
4310 \ '.',
4311 \ ])
Bram Moolenaar70bcd732017-01-12 22:20:54 +01004312 catch
Bram Moolenaar1e115362019-01-09 23:01:02 +01004313 call assert_report("Can't define function")
Bram Moolenaar70bcd732017-01-12 22:20:54 +01004314 endtry
4315 try
Bram Moolenaar1e115362019-01-09 23:01:02 +01004316 call DefineFunction('T_Change', [
4317 \ 'change',
4318 \ 'abc',
4319 \ ])
4320 call assert_report("Shouldn't be able to define function")
Bram Moolenaar70bcd732017-01-12 22:20:54 +01004321 catch
Bram Moolenaar1e115362019-01-09 23:01:02 +01004322 call assert_exception('Vim(function):E126: Missing :endfunction')
Bram Moolenaar70bcd732017-01-12 22:20:54 +01004323 endtry
4324
4325 " :insert
4326 try
Bram Moolenaar1e115362019-01-09 23:01:02 +01004327 call DefineFunction('T_Insert', [
4328 \ 'insert',
4329 \ 'py <<EOS',
4330 \ '.',
4331 \ ])
Bram Moolenaar70bcd732017-01-12 22:20:54 +01004332 catch
Bram Moolenaar1e115362019-01-09 23:01:02 +01004333 call assert_report("Can't define function")
Bram Moolenaar70bcd732017-01-12 22:20:54 +01004334 endtry
4335 try
Bram Moolenaar1e115362019-01-09 23:01:02 +01004336 call DefineFunction('T_Insert', [
4337 \ 'insert',
4338 \ 'abc',
4339 \ ])
4340 call assert_report("Shouldn't be able to define function")
Bram Moolenaar70bcd732017-01-12 22:20:54 +01004341 catch
Bram Moolenaar1e115362019-01-09 23:01:02 +01004342 call assert_exception('Vim(function):E126: Missing :endfunction')
Bram Moolenaar70bcd732017-01-12 22:20:54 +01004343 endtry
4344endfunc
4345
4346"-------------------------------------------------------------------------------
Bram Moolenaar478af672017-04-10 22:22:42 +02004347" Test 96: line continuation {{{1
4348"
Bram Moolenaar1e115362019-01-09 23:01:02 +01004349" Undefined behavior was detected by ubsan with line continuation
4350" after an empty line.
Bram Moolenaar478af672017-04-10 22:22:42 +02004351"-------------------------------------------------------------------------------
4352func Test_script_emty_line_continuation()
4353
4354 \
4355endfunc
4356
4357"-------------------------------------------------------------------------------
Bram Moolenaar863e80b2017-06-04 20:30:00 +02004358" Test 97: bitwise functions {{{1
4359"-------------------------------------------------------------------------------
4360func Test_bitwise_functions()
4361 " and
4362 call assert_equal(127, and(127, 127))
4363 call assert_equal(16, and(127, 16))
Bram Moolenaar073e4b92019-08-18 23:01:56 +02004364 eval 127->and(16)->assert_equal(16)
Bram Moolenaar863e80b2017-06-04 20:30:00 +02004365 call assert_equal(0, and(127, 128))
Bram Moolenaar863e80b2017-06-04 20:30:00 +02004366 call assert_fails("call and([], 1)", 'E745:')
4367 call assert_fails("call and({}, 1)", 'E728:')
Bram Moolenaar5feabe02020-01-30 18:24:53 +01004368 if has('float')
4369 call assert_fails("call and(1.0, 1)", 'E805:')
4370 call assert_fails("call and(1, 1.0)", 'E805:')
4371 endif
Bram Moolenaar863e80b2017-06-04 20:30:00 +02004372 call assert_fails("call and(1, [])", 'E745:')
4373 call assert_fails("call and(1, {})", 'E728:')
4374 " or
4375 call assert_equal(23, or(16, 7))
4376 call assert_equal(15, or(8, 7))
Bram Moolenaar073e4b92019-08-18 23:01:56 +02004377 eval 8->or(7)->assert_equal(15)
Bram Moolenaar863e80b2017-06-04 20:30:00 +02004378 call assert_equal(123, or(0, 123))
Bram Moolenaar863e80b2017-06-04 20:30:00 +02004379 call assert_fails("call or([], 1)", 'E745:')
4380 call assert_fails("call or({}, 1)", 'E728:')
Bram Moolenaar5feabe02020-01-30 18:24:53 +01004381 if has('float')
4382 call assert_fails("call or(1.0, 1)", 'E805:')
4383 call assert_fails("call or(1, 1.0)", 'E805:')
4384 endif
Bram Moolenaar863e80b2017-06-04 20:30:00 +02004385 call assert_fails("call or(1, [])", 'E745:')
4386 call assert_fails("call or(1, {})", 'E728:')
4387 " xor
4388 call assert_equal(0, xor(127, 127))
4389 call assert_equal(111, xor(127, 16))
Bram Moolenaar073e4b92019-08-18 23:01:56 +02004390 eval 127->xor(16)->assert_equal(111)
Bram Moolenaar863e80b2017-06-04 20:30:00 +02004391 call assert_equal(255, xor(127, 128))
Bram Moolenaar5feabe02020-01-30 18:24:53 +01004392 if has('float')
4393 call assert_fails("call xor(1.0, 1)", 'E805:')
4394 call assert_fails("call xor(1, 1.0)", 'E805:')
4395 endif
Bram Moolenaar863e80b2017-06-04 20:30:00 +02004396 call assert_fails("call xor([], 1)", 'E745:')
4397 call assert_fails("call xor({}, 1)", 'E728:')
Bram Moolenaar863e80b2017-06-04 20:30:00 +02004398 call assert_fails("call xor(1, [])", 'E745:')
4399 call assert_fails("call xor(1, {})", 'E728:')
4400 " invert
4401 call assert_equal(65408, and(invert(127), 65535))
Bram Moolenaar073e4b92019-08-18 23:01:56 +02004402 eval 127->invert()->and(65535)->assert_equal(65408)
Bram Moolenaar863e80b2017-06-04 20:30:00 +02004403 call assert_equal(65519, and(invert(16), 65535))
4404 call assert_equal(65407, and(invert(128), 65535))
Bram Moolenaar5feabe02020-01-30 18:24:53 +01004405 if has('float')
4406 call assert_fails("call invert(1.0)", 'E805:')
4407 endif
Bram Moolenaar863e80b2017-06-04 20:30:00 +02004408 call assert_fails("call invert([])", 'E745:')
4409 call assert_fails("call invert({})", 'E728:')
4410endfunc
4411
Bram Moolenaar6f9a4762017-06-22 20:39:17 +02004412" Test using bang after user command {{{1
4413func Test_user_command_with_bang()
4414 command -bang Nieuw let nieuw = 1
4415 Ni!
4416 call assert_equal(1, nieuw)
4417 unlet nieuw
4418 delcommand Nieuw
4419endfunc
4420
Bram Moolenaarb9adef72020-01-02 14:31:22 +01004421func Test_script_expand_sfile()
4422 let lines =<< trim END
4423 func s:snr()
4424 return expand('<sfile>')
4425 endfunc
4426 let g:result = s:snr()
4427 END
4428 call writefile(lines, 'Xexpand')
4429 source Xexpand
4430 call assert_match('<SNR>\d\+_snr', g:result)
4431 source Xexpand
4432 call assert_match('<SNR>\d\+_snr', g:result)
4433
4434 call delete('Xexpand')
4435 unlet g:result
4436endfunc
4437
Bram Moolenaarff697e62019-02-12 22:28:33 +01004438func Test_compound_assignment_operators()
4439 " Test for number
4440 let x = 1
4441 let x += 10
4442 call assert_equal(11, x)
4443 let x -= 5
4444 call assert_equal(6, x)
4445 let x *= 4
4446 call assert_equal(24, x)
4447 let x /= 3
4448 call assert_equal(8, x)
4449 let x %= 3
4450 call assert_equal(2, x)
4451 let x .= 'n'
4452 call assert_equal('2n', x)
4453
Bram Moolenaare21c1582019-03-02 11:57:09 +01004454 " Test special cases: division or modulus with 0.
4455 let x = 1
4456 let x /= 0
Bram Moolenaar82f654e2020-02-17 22:12:50 +01004457 call assert_equal(0x7FFFFFFFFFFFFFFF, x)
Bram Moolenaare21c1582019-03-02 11:57:09 +01004458
4459 let x = -1
4460 let x /= 0
Bram Moolenaar82f654e2020-02-17 22:12:50 +01004461 call assert_equal(-0x7FFFFFFFFFFFFFFF, x)
Bram Moolenaare21c1582019-03-02 11:57:09 +01004462
4463 let x = 0
4464 let x /= 0
Bram Moolenaar82f654e2020-02-17 22:12:50 +01004465 call assert_equal(-0x7FFFFFFFFFFFFFFF - 1, x)
Bram Moolenaare21c1582019-03-02 11:57:09 +01004466
4467 let x = 1
4468 let x %= 0
4469 call assert_equal(0, x)
4470
4471 let x = -1
4472 let x %= 0
4473 call assert_equal(0, x)
4474
4475 let x = 0
4476 let x %= 0
4477 call assert_equal(0, x)
4478
Bram Moolenaarff697e62019-02-12 22:28:33 +01004479 " Test for string
4480 let x = 'str'
4481 let x .= 'ing'
4482 call assert_equal('string', x)
4483 let x += 1
4484 call assert_equal(1, x)
Bram Moolenaarff697e62019-02-12 22:28:33 +01004485
4486 if has('float')
Bram Moolenaar5feabe02020-01-30 18:24:53 +01004487 " Test for float
4488 let x -= 1.5
4489 call assert_equal(-0.5, x)
4490 let x = 0.5
4491 let x += 4.5
4492 call assert_equal(5.0, x)
4493 let x -= 1.5
4494 call assert_equal(3.5, x)
4495 let x *= 3.0
4496 call assert_equal(10.5, x)
4497 let x /= 2.5
4498 call assert_equal(4.2, x)
4499 call assert_fails('let x %= 0.5', 'E734')
4500 call assert_fails('let x .= "f"', 'E734')
Bram Moolenaar8b633132020-03-20 18:20:51 +01004501 let x = !3.14
4502 call assert_equal(0.0, x)
Bram Moolenaarea04a6e2020-04-23 13:38:02 +02004503
4504 " integer and float operations
4505 let x = 1
4506 let x *= 2.1
4507 call assert_equal(2.1, x)
4508 let x = 1
4509 let x /= 0.25
4510 call assert_equal(4.0, x)
4511 let x = 1
4512 call assert_fails('let x %= 0.25', 'E734:')
4513 let x = 1
4514 call assert_fails('let x .= 0.25', 'E734:')
4515 let x = 1.0
4516 call assert_fails('let x += [1.1]', 'E734:')
Bram Moolenaarff697e62019-02-12 22:28:33 +01004517 endif
4518
4519 " Test for environment variable
4520 let $FOO = 1
4521 call assert_fails('let $FOO += 1', 'E734')
4522 call assert_fails('let $FOO -= 1', 'E734')
4523 call assert_fails('let $FOO *= 1', 'E734')
4524 call assert_fails('let $FOO /= 1', 'E734')
4525 call assert_fails('let $FOO %= 1', 'E734')
4526 let $FOO .= 's'
4527 call assert_equal('1s', $FOO)
4528 unlet $FOO
4529
4530 " Test for option variable (type: number)
4531 let &scrolljump = 1
4532 let &scrolljump += 5
4533 call assert_equal(6, &scrolljump)
4534 let &scrolljump -= 2
4535 call assert_equal(4, &scrolljump)
4536 let &scrolljump *= 3
4537 call assert_equal(12, &scrolljump)
4538 let &scrolljump /= 2
4539 call assert_equal(6, &scrolljump)
4540 let &scrolljump %= 5
4541 call assert_equal(1, &scrolljump)
4542 call assert_fails('let &scrolljump .= "j"', 'E734')
4543 set scrolljump&vim
4544
4545 " Test for register
4546 let @/ = 1
4547 call assert_fails('let @/ += 1', 'E734')
4548 call assert_fails('let @/ -= 1', 'E734')
4549 call assert_fails('let @/ *= 1', 'E734')
4550 call assert_fails('let @/ /= 1', 'E734')
4551 call assert_fails('let @/ %= 1', 'E734')
4552 let @/ .= 's'
4553 call assert_equal('1s', @/)
4554 let @/ = ''
4555endfunc
4556
Bram Moolenaar7e0868e2020-04-19 17:24:53 +02004557func Test_unlet_env()
4558 let $TESTVAR = 'yes'
4559 call assert_equal('yes', $TESTVAR)
4560 call assert_fails('lockvar $TESTVAR', 'E940')
4561 call assert_fails('unlockvar $TESTVAR', 'E940')
4562 call assert_equal('yes', $TESTVAR)
4563 if 0
4564 unlet $TESTVAR
4565 endif
4566 call assert_equal('yes', $TESTVAR)
4567 unlet $TESTVAR
4568 call assert_equal('', $TESTVAR)
4569endfunc
4570
Bram Moolenaarc3e92c12019-03-23 14:23:07 +01004571func Test_refcount()
4572 " Immediate values
4573 call assert_equal(-1, test_refcount(1))
4574 call assert_equal(-1, test_refcount('s'))
4575 call assert_equal(-1, test_refcount(v:true))
4576 call assert_equal(0, test_refcount([]))
4577 call assert_equal(0, test_refcount({}))
4578 call assert_equal(0, test_refcount(0zff))
4579 call assert_equal(0, test_refcount({-> line('.')}))
4580 if has('float')
4581 call assert_equal(-1, test_refcount(0.1))
4582 endif
4583 if has('job')
4584 call assert_equal(0, test_refcount(job_start([&shell, &shellcmdflag, 'echo .'])))
4585 endif
4586
4587 " No refcount types
4588 let x = 1
4589 call assert_equal(-1, test_refcount(x))
4590 let x = 's'
4591 call assert_equal(-1, test_refcount(x))
4592 let x = v:true
4593 call assert_equal(-1, test_refcount(x))
4594 if has('float')
4595 let x = 0.1
4596 call assert_equal(-1, test_refcount(x))
4597 endif
4598
4599 " Check refcount
4600 let x = []
4601 call assert_equal(1, test_refcount(x))
4602
4603 let x = {}
Bram Moolenaarce90e362019-09-08 18:58:44 +02004604 call assert_equal(1, x->test_refcount())
Bram Moolenaarc3e92c12019-03-23 14:23:07 +01004605
4606 let x = 0zff
4607 call assert_equal(1, test_refcount(x))
4608
4609 let X = {-> line('.')}
4610 call assert_equal(1, test_refcount(X))
4611 let Y = X
4612 call assert_equal(2, test_refcount(X))
4613
4614 if has('job')
4615 let job = job_start([&shell, &shellcmdflag, 'echo .'])
4616 call assert_equal(1, test_refcount(job))
4617 call assert_equal(1, test_refcount(job_getchannel(job)))
4618 call assert_equal(1, test_refcount(job))
4619 endif
4620
4621 " Function arguments, copying and unassigning
4622 func ExprCheck(x, i)
4623 let i = a:i + 1
4624 call assert_equal(i, test_refcount(a:x))
4625 let Y = a:x
4626 call assert_equal(i + 1, test_refcount(a:x))
4627 call assert_equal(test_refcount(a:x), test_refcount(Y))
4628 let Y = 0
4629 call assert_equal(i, test_refcount(a:x))
4630 endfunc
4631 call ExprCheck([], 0)
4632 call ExprCheck({}, 0)
4633 call ExprCheck(0zff, 0)
4634 call ExprCheck({-> line('.')}, 0)
4635 if has('job')
4636 call ExprCheck(job, 1)
4637 call ExprCheck(job_getchannel(job), 1)
4638 call job_stop(job)
4639 endif
4640 delfunc ExprCheck
4641
4642 " Regarding function
4643 func Func(x) abort
4644 call assert_equal(2, test_refcount(function('Func')))
4645 call assert_equal(0, test_refcount(funcref('Func')))
4646 endfunc
4647 call assert_equal(1, test_refcount(function('Func')))
4648 call assert_equal(0, test_refcount(function('Func', [1])))
4649 call assert_equal(0, test_refcount(funcref('Func')))
4650 call assert_equal(0, test_refcount(funcref('Func', [1])))
4651 let X = function('Func')
4652 let Y = X
4653 call assert_equal(1, test_refcount(X))
4654 let X = function('Func', [1])
4655 let Y = X
4656 call assert_equal(2, test_refcount(X))
4657 let X = funcref('Func')
4658 let Y = X
4659 call assert_equal(2, test_refcount(X))
4660 let X = funcref('Func', [1])
4661 let Y = X
4662 call assert_equal(2, test_refcount(X))
4663 unlet X
4664 unlet Y
4665 call Func(1)
4666 delfunc Func
4667
4668 " Function with dict
4669 func DictFunc() dict
4670 call assert_equal(3, test_refcount(self))
4671 endfunc
4672 let d = {'Func': function('DictFunc')}
4673 call assert_equal(1, test_refcount(d))
4674 call assert_equal(0, test_refcount(d.Func))
4675 call d.Func()
4676 unlet d
4677 delfunc DictFunc
4678endfunc
4679
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01004680" Test for missing :endif, :endfor, :endwhile and :endtry {{{1
4681func Test_missing_end()
4682 call writefile(['if 2 > 1', 'echo ">"'], 'Xscript')
4683 call assert_fails('source Xscript', 'E171:')
4684 call writefile(['for i in range(5)', 'echo i'], 'Xscript')
4685 call assert_fails('source Xscript', 'E170:')
4686 call writefile(['while v:true', 'echo "."'], 'Xscript')
4687 call assert_fails('source Xscript', 'E170:')
4688 call writefile(['try', 'echo "."'], 'Xscript')
4689 call assert_fails('source Xscript', 'E600:')
4690 call delete('Xscript')
Bram Moolenaar818fc9a2020-02-21 17:54:45 +01004691
4692 " Using endfor with :while
4693 let caught_e732 = 0
4694 try
4695 while v:true
4696 endfor
4697 catch /E732:/
4698 let caught_e732 = 1
4699 endtry
4700 call assert_equal(1, caught_e732)
4701
4702 " Using endwhile with :for
4703 let caught_e733 = 0
4704 try
4705 for i in range(1)
4706 endwhile
4707 catch /E733:/
4708 let caught_e733 = 1
4709 endtry
4710 call assert_equal(1, caught_e733)
4711
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02004712 " Using endfunc with :if
4713 call assert_fails('exe "if 1 | endfunc | endif"', 'E193:')
4714
Bram Moolenaar818fc9a2020-02-21 17:54:45 +01004715 " Missing 'in' in a :for statement
4716 call assert_fails('for i range(1) | endfor', 'E690:')
Bram Moolenaarea04a6e2020-04-23 13:38:02 +02004717
4718 " Incorrect number of variables in for
4719 call assert_fails('for [i,] in range(3) | endfor', 'E475:')
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01004720endfunc
4721
4722" Test for deep nesting of if/for/while/try statements {{{1
4723func Test_deep_nest()
Bram Moolenaar494e9062020-05-31 21:28:02 +02004724 CheckRunVimInTerminal
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01004725
4726 let lines =<< trim [SCRIPT]
4727 " Deep nesting of if ... endif
4728 func Test1()
4729 let @a = join(repeat(['if v:true'], 51), "\n")
4730 let @a ..= "\n"
4731 let @a ..= join(repeat(['endif'], 51), "\n")
4732 @a
4733 let @a = ''
4734 endfunc
4735
4736 " Deep nesting of for ... endfor
4737 func Test2()
4738 let @a = join(repeat(['for i in [1]'], 51), "\n")
4739 let @a ..= "\n"
4740 let @a ..= join(repeat(['endfor'], 51), "\n")
4741 @a
4742 let @a = ''
4743 endfunc
4744
4745 " Deep nesting of while ... endwhile
4746 func Test3()
4747 let @a = join(repeat(['while v:true'], 51), "\n")
4748 let @a ..= "\n"
4749 let @a ..= join(repeat(['endwhile'], 51), "\n")
4750 @a
4751 let @a = ''
4752 endfunc
4753
4754 " Deep nesting of try ... endtry
4755 func Test4()
4756 let @a = join(repeat(['try'], 51), "\n")
4757 let @a ..= "\necho v:true\n"
4758 let @a ..= join(repeat(['endtry'], 51), "\n")
4759 @a
4760 let @a = ''
4761 endfunc
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02004762
4763 " Deep nesting of function ... endfunction
4764 func Test5()
4765 let @a = join(repeat(['function X()'], 51), "\n")
4766 let @a ..= "\necho v:true\n"
4767 let @a ..= join(repeat(['endfunction'], 51), "\n")
4768 @a
4769 let @a = ''
4770 endfunc
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01004771 [SCRIPT]
4772 call writefile(lines, 'Xscript')
4773
4774 let buf = RunVimInTerminal('-S Xscript', {'rows': 6})
4775
4776 " Deep nesting of if ... endif
4777 call term_sendkeys(buf, ":call Test1()\n")
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +02004778 call TermWait(buf)
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01004779 call WaitForAssert({-> assert_match('^E579:', term_getline(buf, 5))})
4780
4781 " Deep nesting of for ... endfor
4782 call term_sendkeys(buf, ":call Test2()\n")
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +02004783 call TermWait(buf)
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01004784 call WaitForAssert({-> assert_match('^E585:', term_getline(buf, 5))})
4785
4786 " Deep nesting of while ... endwhile
4787 call term_sendkeys(buf, ":call Test3()\n")
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +02004788 call TermWait(buf)
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01004789 call WaitForAssert({-> assert_match('^E585:', term_getline(buf, 5))})
4790
4791 " Deep nesting of try ... endtry
4792 call term_sendkeys(buf, ":call Test4()\n")
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +02004793 call TermWait(buf)
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01004794 call WaitForAssert({-> assert_match('^E601:', term_getline(buf, 5))})
4795
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02004796 " Deep nesting of function ... endfunction
4797 call term_sendkeys(buf, ":call Test5()\n")
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +02004798 call TermWait(buf)
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02004799 call WaitForAssert({-> assert_match('^E1058:', term_getline(buf, 4))})
4800 call term_sendkeys(buf, "\<C-C>\n")
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +02004801 call TermWait(buf)
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02004802
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01004803 "let l = ''
4804 "for i in range(1, 6)
4805 " let l ..= term_getline(buf, i) . "\n"
4806 "endfor
4807 "call assert_report(l)
4808
4809 call StopVimInTerminal(buf)
4810 call delete('Xscript')
4811endfunc
4812
Bram Moolenaar8b633132020-03-20 18:20:51 +01004813" Test for errors in converting to float from various types {{{1
4814func Test_float_conversion_errors()
4815 if has('float')
4816 call assert_fails('let x = 4.0 % 2.0', 'E804')
4817 call assert_fails('echo 1.1[0]', 'E806')
4818 call assert_fails('echo sort([function("min"), 1], "f")', 'E891:')
4819 call assert_fails('echo 3.2 == "vim"', 'E892:')
4820 call assert_fails('echo sort([[], 1], "f")', 'E893:')
4821 call assert_fails('echo sort([{}, 1], "f")', 'E894:')
4822 call assert_fails('echo 3.2 == v:true', 'E362:')
4823 call assert_fails('echo 3.2 == v:none', 'E907:')
4824 endif
4825endfunc
4826
Bram Moolenaar8e6cbb72020-07-01 14:38:12 +02004827" invalid function names {{{1
Bram Moolenaar08f41572020-04-20 16:50:00 +02004828func Test_invalid_function_names()
4829 " function name not starting with capital
4830 let caught_e128 = 0
4831 try
4832 func! g:test()
4833 echo "test"
4834 endfunc
4835 catch /E128:/
4836 let caught_e128 = 1
4837 endtry
4838 call assert_equal(1, caught_e128)
4839
4840 " function name includes a colon
4841 let caught_e884 = 0
4842 try
4843 func! b:test()
4844 echo "test"
4845 endfunc
4846 catch /E884:/
4847 let caught_e884 = 1
4848 endtry
4849 call assert_equal(1, caught_e884)
4850
4851 " function name folowed by #
4852 let caught_e128 = 0
4853 try
4854 func! test2() "#
4855 echo "test2"
4856 endfunc
4857 catch /E128:/
4858 let caught_e128 = 1
4859 endtry
4860 call assert_equal(1, caught_e128)
4861
4862 " function name starting with/without "g:", buffer-local funcref.
4863 function! g:Foo(n)
4864 return 'called Foo(' . a:n . ')'
4865 endfunction
4866 let b:my_func = function('Foo')
4867 call assert_equal('called Foo(1)', b:my_func(1))
4868 call assert_equal('called Foo(2)', g:Foo(2))
4869 call assert_equal('called Foo(3)', Foo(3))
4870 delfunc g:Foo
4871
4872 " script-local function used in Funcref must exist.
4873 let lines =<< trim END
4874 func s:Testje()
4875 return "foo"
4876 endfunc
4877 let Bar = function('s:Testje')
4878 call assert_equal(0, exists('s:Testje'))
4879 call assert_equal(1, exists('*s:Testje'))
4880 call assert_equal(1, exists('Bar'))
4881 call assert_equal(1, exists('*Bar'))
4882 END
4883 call writefile(lines, 'Xscript')
4884 source Xscript
4885 call delete('Xscript')
4886endfunc
4887
Bram Moolenaar8e6cbb72020-07-01 14:38:12 +02004888" substring and variable name {{{1
Bram Moolenaar08f41572020-04-20 16:50:00 +02004889func Test_substring_var()
4890 let str = 'abcdef'
4891 let n = 3
4892 call assert_equal('def', str[n:])
4893 call assert_equal('abcd', str[:n])
4894 call assert_equal('d', str[n:n])
4895 unlet n
4896 let nn = 3
4897 call assert_equal('def', str[nn:])
4898 call assert_equal('abcd', str[:nn])
4899 call assert_equal('d', str[nn:nn])
4900 unlet nn
4901 let b:nn = 4
4902 call assert_equal('ef', str[b:nn:])
4903 call assert_equal('abcde', str[:b:nn])
4904 call assert_equal('e', str[b:nn:b:nn])
4905 unlet b:nn
4906endfunc
4907
Bram Moolenaar8e6cbb72020-07-01 14:38:12 +02004908" Test using s: with a typed command {{{1
4909func Test_typed_script_var()
4910 CheckRunVimInTerminal
4911
4912 let buf = RunVimInTerminal('', {'rows': 6})
4913
4914 " Deep nesting of if ... endif
4915 call term_sendkeys(buf, ":echo get(s:, 'foo', 'x')\n")
4916 call TermWait(buf)
4917 call WaitForAssert({-> assert_match('^E116:', term_getline(buf, 5))})
4918
4919 call StopVimInTerminal(buf)
4920endfunc
4921
Bram Moolenaar863e80b2017-06-04 20:30:00 +02004922"-------------------------------------------------------------------------------
Bram Moolenaarf49e2402015-12-30 15:59:25 +01004923" Modelines {{{1
Bram Moolenaar1f068232019-11-03 16:17:26 +01004924" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
Bram Moolenaarf49e2402015-12-30 15:59:25 +01004925"-------------------------------------------------------------------------------