blob: e63f647bb5bc72685fddcfb4c987025d8c0f82ad [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
Bram Moolenaarefb64822020-08-10 22:15:30 +020026 set cpo-=C " support line-continuation in sourced script
Bram Moolenaara6296202020-08-05 11:23:13 +020027 source script_util.vim
28 XpathINIT
29 XloopINIT
30 END
31 let cleanup =<< trim END
32 call writefile(v:errors, 'Xtest.out')
33 qall
34 END
35 call writefile(init, 'Xtest.vim')
36 call writefile(a:test, 'Xtest.vim', 'a')
37 call writefile(a:verify, 'Xverify.vim')
38 call writefile(cleanup, 'Xverify.vim', 'a')
39 call RunVim([], [], "-S Xtest.vim -S Xverify.vim")
40 call assert_equal([], readfile('Xtest.out'))
41 call delete('Xtest.out')
42 call delete('Xtest.vim')
43 call delete('Xverify.vim')
Bram Moolenaar1e115362019-01-09 23:01:02 +010044endfunc
Bram Moolenaarf49e2402015-12-30 15:59:25 +010045
Bram Moolenaarf49e2402015-12-30 15:59:25 +010046"-------------------------------------------------------------------------------
47" Test 1: :endwhile in function {{{1
48"
49" Detect if a broken loop is (incorrectly) reactivated by the
50" :endwhile. Use a :return to prevent an endless loop, and make
51" this test first to get a meaningful result on an error before other
52" tests will hang.
53"-------------------------------------------------------------------------------
54
Bram Moolenaara6296202020-08-05 11:23:13 +020055func T1_F()
Bram Moolenaarf49e2402015-12-30 15:59:25 +010056 Xpath 'a'
57 let first = 1
58 while 1
59 Xpath 'b'
60 if first
61 Xpath 'c'
62 let first = 0
63 break
64 else
65 Xpath 'd'
66 return
67 endif
68 endwhile
Bram Moolenaara6296202020-08-05 11:23:13 +020069endfunc
Bram Moolenaarf49e2402015-12-30 15:59:25 +010070
Bram Moolenaara6296202020-08-05 11:23:13 +020071func T1_G()
Bram Moolenaarf49e2402015-12-30 15:59:25 +010072 Xpath 'h'
73 let first = 1
74 while 1
75 Xpath 'i'
76 if first
77 Xpath 'j'
78 let first = 0
79 break
80 else
81 Xpath 'k'
82 return
83 endif
84 if 1 " unmatched :if
85 endwhile
Bram Moolenaara6296202020-08-05 11:23:13 +020086endfunc
Bram Moolenaarf49e2402015-12-30 15:59:25 +010087
88func Test_endwhile_function()
89 XpathINIT
90 call T1_F()
91 Xpath 'F'
92
93 try
94 call T1_G()
95 catch
96 " Catch missing :endif
97 call assert_true(v:exception =~ 'E171')
98 Xpath 'x'
99 endtry
100 Xpath 'G'
101
102 call assert_equal('abcFhijxG', g:Xpath)
103endfunc
104
105"-------------------------------------------------------------------------------
106" Test 2: :endwhile in script {{{1
107"
108" Detect if a broken loop is (incorrectly) reactivated by the
109" :endwhile. Use a :finish to prevent an endless loop, and place
110" this test before others that might hang to get a meaningful result
111" on an error.
112"
113" This test executes the bodies of the functions T1_F and T1_G from
114" the previous test as script files (:return replaced by :finish).
115"-------------------------------------------------------------------------------
116
117func Test_endwhile_script()
118 XpathINIT
119 ExecAsScript T1_F
120 Xpath 'F'
Bram Moolenaarf4f79b82016-01-25 20:38:30 +0100121 call DeleteTheScript()
Bram Moolenaarf49e2402015-12-30 15:59:25 +0100122
123 try
124 ExecAsScript T1_G
125 catch
126 " Catch missing :endif
127 call assert_true(v:exception =~ 'E171')
128 Xpath 'x'
129 endtry
130 Xpath 'G'
Bram Moolenaarf4f79b82016-01-25 20:38:30 +0100131 call DeleteTheScript()
Bram Moolenaarf49e2402015-12-30 15:59:25 +0100132
133 call assert_equal('abcFhijxG', g:Xpath)
134endfunc
135
136"-------------------------------------------------------------------------------
137" Test 3: :if, :elseif, :while, :continue, :break {{{1
138"-------------------------------------------------------------------------------
139
Bram Moolenaara6296202020-08-05 11:23:13 +0200140func Test_if_while()
Bram Moolenaarf49e2402015-12-30 15:59:25 +0100141 XpathINIT
142 if 1
143 Xpath 'a'
144 let loops = 3
145 while loops > -1 " main loop: loops == 3, 2, 1 (which breaks)
146 if loops <= 0
147 let break_err = 1
148 let loops = -1
149 else
150 Xpath 'b' . loops
151 endif
152 if (loops == 2)
153 while loops == 2 " dummy loop
154 Xpath 'c' . loops
155 let loops = loops - 1
156 continue " stop dummy loop
157 Xpath 'd' . loops
158 endwhile
159 continue " continue main loop
160 Xpath 'e' . loops
161 elseif (loops == 1)
162 let p = 1
163 while p " dummy loop
164 Xpath 'f' . loops
165 let p = 0
166 break " break dummy loop
167 Xpath 'g' . loops
168 endwhile
169 Xpath 'h' . loops
170 unlet p
171 break " break main loop
172 Xpath 'i' . loops
173 endif
174 if (loops > 0)
175 Xpath 'j' . loops
176 endif
177 while loops == 3 " dummy loop
178 let loops = loops - 1
179 endwhile " end dummy loop
180 endwhile " end main loop
181 Xpath 'k'
182 else
183 Xpath 'l'
184 endif
185 Xpath 'm'
186 if exists("break_err")
187 Xpath 'm'
188 unlet break_err
189 endif
190
191 unlet loops
192
193 call assert_equal('ab3j3b2c2b1f1h1km', g:Xpath)
194endfunc
195
196"-------------------------------------------------------------------------------
197" Test 4: :return {{{1
198"-------------------------------------------------------------------------------
199
Bram Moolenaara6296202020-08-05 11:23:13 +0200200func T4_F()
Bram Moolenaarf49e2402015-12-30 15:59:25 +0100201 if 1
202 Xpath 'a'
203 let loops = 3
204 while loops > 0 " 3: 2: 1:
205 Xpath 'b' . loops
206 if (loops == 2)
207 Xpath 'c' . loops
208 return
209 Xpath 'd' . loops
210 endif
211 Xpath 'e' . loops
212 let loops = loops - 1
213 endwhile
214 Xpath 'f'
215 else
216 Xpath 'g'
217 endif
Bram Moolenaara6296202020-08-05 11:23:13 +0200218endfunc
Bram Moolenaarf49e2402015-12-30 15:59:25 +0100219
Bram Moolenaara6296202020-08-05 11:23:13 +0200220func Test_return()
Bram Moolenaarf49e2402015-12-30 15:59:25 +0100221 XpathINIT
222 call T4_F()
223 Xpath '4'
224
225 call assert_equal('ab3e3b2c24', g:Xpath)
Bram Moolenaara6296202020-08-05 11:23:13 +0200226endfunc
Bram Moolenaarf49e2402015-12-30 15:59:25 +0100227
228
229"-------------------------------------------------------------------------------
230" Test 5: :finish {{{1
231"
232" This test executes the body of the function T4_F from the previous
233" test as a script file (:return replaced by :finish).
234"-------------------------------------------------------------------------------
235
Bram Moolenaara6296202020-08-05 11:23:13 +0200236func Test_finish()
Bram Moolenaarf49e2402015-12-30 15:59:25 +0100237 XpathINIT
238 ExecAsScript T4_F
239 Xpath '5'
Bram Moolenaarf4f79b82016-01-25 20:38:30 +0100240 call DeleteTheScript()
Bram Moolenaarf49e2402015-12-30 15:59:25 +0100241
242 call assert_equal('ab3e3b2c25', g:Xpath)
Bram Moolenaara6296202020-08-05 11:23:13 +0200243endfunc
Bram Moolenaarf49e2402015-12-30 15:59:25 +0100244
245
246
247"-------------------------------------------------------------------------------
248" Test 6: Defining functions in :while loops {{{1
249"
250" Functions can be defined inside other functions. An inner function
251" gets defined when the outer function is executed. Functions may
252" also be defined inside while loops. Expressions in braces for
253" defining the function name are allowed.
254"
255" The functions are defined when sourcing the script, only the
256" resulting path is checked in the test function.
257"-------------------------------------------------------------------------------
258
259XpathINIT
260
261" The command CALL collects the argument of all its invocations in "calls"
262" when used from a function (that is, when the global variable "calls" needs
263" the "g:" prefix). This is to check that the function code is skipped when
264" the function is defined. For inner functions, do so only if the outer
265" function is not being executed.
266"
267let calls = ""
268com! -nargs=1 CALL
Bram Moolenaar1e115362019-01-09 23:01:02 +0100269 \ if !exists("calls") && !exists("outer") |
270 \ let g:calls = g:calls . <args> |
271 \ endif
Bram Moolenaarf49e2402015-12-30 15:59:25 +0100272
273let i = 0
274while i < 3
275 let i = i + 1
276 if i == 1
277 Xpath 'a'
278 function! F1(arg)
279 CALL a:arg
280 let outer = 1
281
282 let j = 0
283 while j < 1
284 Xpath 'b'
285 let j = j + 1
286 function! G1(arg)
287 CALL a:arg
288 endfunction
289 Xpath 'c'
290 endwhile
291 endfunction
292 Xpath 'd'
293
294 continue
295 endif
296
297 Xpath 'e' . i
298 function! F{i}(i, arg)
299 CALL a:arg
300 let outer = 1
301
302 if a:i == 3
303 Xpath 'f'
304 endif
305 let k = 0
306 while k < 3
307 Xpath 'g' . k
308 let k = k + 1
309 function! G{a:i}{k}(arg)
310 CALL a:arg
311 endfunction
312 Xpath 'h' . k
313 endwhile
314 endfunction
315 Xpath 'i'
316
317endwhile
318
319if exists("*G1")
320 Xpath 'j'
321endif
322if exists("*F1")
323 call F1("F1")
324 if exists("*G1")
Bram Moolenaar1e115362019-01-09 23:01:02 +0100325 call G1("G1")
Bram Moolenaarf49e2402015-12-30 15:59:25 +0100326 endif
327endif
328
329if exists("G21") || exists("G22") || exists("G23")
330 Xpath 'k'
331endif
332if exists("*F2")
333 call F2(2, "F2")
334 if exists("*G21")
Bram Moolenaar1e115362019-01-09 23:01:02 +0100335 call G21("G21")
Bram Moolenaarf49e2402015-12-30 15:59:25 +0100336 endif
337 if exists("*G22")
Bram Moolenaar1e115362019-01-09 23:01:02 +0100338 call G22("G22")
Bram Moolenaarf49e2402015-12-30 15:59:25 +0100339 endif
340 if exists("*G23")
Bram Moolenaar1e115362019-01-09 23:01:02 +0100341 call G23("G23")
Bram Moolenaarf49e2402015-12-30 15:59:25 +0100342 endif
343endif
344
345if exists("G31") || exists("G32") || exists("G33")
346 Xpath 'l'
347endif
348if exists("*F3")
349 call F3(3, "F3")
350 if exists("*G31")
Bram Moolenaar1e115362019-01-09 23:01:02 +0100351 call G31("G31")
Bram Moolenaarf49e2402015-12-30 15:59:25 +0100352 endif
353 if exists("*G32")
Bram Moolenaar1e115362019-01-09 23:01:02 +0100354 call G32("G32")
Bram Moolenaarf49e2402015-12-30 15:59:25 +0100355 endif
356 if exists("*G33")
Bram Moolenaar1e115362019-01-09 23:01:02 +0100357 call G33("G33")
Bram Moolenaarf49e2402015-12-30 15:59:25 +0100358 endif
359endif
360
361Xpath 'm'
362
363let g:test6_result = g:Xpath
364let g:test6_calls = calls
365
366unlet calls
367delfunction F1
368delfunction G1
369delfunction F2
370delfunction G21
371delfunction G22
372delfunction G23
373delfunction G31
374delfunction G32
375delfunction G33
376
Bram Moolenaara6296202020-08-05 11:23:13 +0200377func Test_defining_functions()
Bram Moolenaarf49e2402015-12-30 15:59:25 +0100378 call assert_equal('ade2ie3ibcg0h1g1h2g2h3fg0h1g1h2g2h3m', g:test6_result)
379 call assert_equal('F1G1F2G21G22G23F3G31G32G33', g:test6_calls)
380endfunc
381
382"-------------------------------------------------------------------------------
Bram Moolenaara2cce862016-01-02 19:50:04 +0100383" Test 7: Continuing on errors outside functions {{{1
384"
385" On an error outside a function, the script processing continues
386" at the line following the outermost :endif or :endwhile. When not
387" inside an :if or :while, the script processing continues at the next
388" line.
389"-------------------------------------------------------------------------------
390
391XpathINIT
392
393if 1
394 Xpath 'a'
395 while 1
396 Xpath 'b'
397 asdf
398 Xpath 'c'
399 break
400 endwhile | Xpath 'd'
401 Xpath 'e'
402endif | Xpath 'f'
403Xpath 'g'
404
405while 1
406 Xpath 'h'
407 if 1
408 Xpath 'i'
409 asdf
410 Xpath 'j'
411 endif | Xpath 'k'
412 Xpath 'l'
413 break
414endwhile | Xpath 'm'
415Xpath 'n'
416
417asdf
418Xpath 'o'
419
420asdf | Xpath 'p'
421Xpath 'q'
422
423let g:test7_result = g:Xpath
424
425func Test_error_in_script()
426 call assert_equal('abghinoq', g:test7_result)
427endfunc
428
429"-------------------------------------------------------------------------------
430" Test 8: Aborting and continuing on errors inside functions {{{1
431"
432" On an error inside a function without the "abort" attribute, the
433" script processing continues at the next line (unless the error was
434" in a :return command). On an error inside a function with the
435" "abort" attribute, the function is aborted and the script processing
436" continues after the function call; the value -1 is returned then.
437"-------------------------------------------------------------------------------
438
439XpathINIT
440
Bram Moolenaara6296202020-08-05 11:23:13 +0200441func T8_F()
Bram Moolenaara2cce862016-01-02 19:50:04 +0100442 if 1
443 Xpath 'a'
444 while 1
445 Xpath 'b'
446 asdf
447 Xpath 'c'
448 asdf | Xpath 'd'
449 Xpath 'e'
450 break
451 endwhile
452 Xpath 'f'
453 endif | Xpath 'g'
454 Xpath 'h'
455
456 while 1
457 Xpath 'i'
458 if 1
459 Xpath 'j'
460 asdf
461 Xpath 'k'
462 asdf | Xpath 'l'
463 Xpath 'm'
464 endif
465 Xpath 'n'
466 break
467 endwhile | Xpath 'o'
468 Xpath 'p'
469
470 return novar " returns (default return value 0)
471 Xpath 'q'
472 return 1 " not reached
Bram Moolenaara6296202020-08-05 11:23:13 +0200473endfunc
Bram Moolenaara2cce862016-01-02 19:50:04 +0100474
Bram Moolenaara6296202020-08-05 11:23:13 +0200475func T8_G() abort
Bram Moolenaara2cce862016-01-02 19:50:04 +0100476 if 1
477 Xpath 'r'
478 while 1
479 Xpath 's'
480 asdf " returns -1
481 Xpath 't'
482 break
483 endwhile
484 Xpath 'v'
485 endif | Xpath 'w'
486 Xpath 'x'
487
488 return -4 " not reached
Bram Moolenaara6296202020-08-05 11:23:13 +0200489endfunc
Bram Moolenaara2cce862016-01-02 19:50:04 +0100490
Bram Moolenaara6296202020-08-05 11:23:13 +0200491func T8_H() abort
Bram Moolenaara2cce862016-01-02 19:50:04 +0100492 while 1
493 Xpath 'A'
494 if 1
495 Xpath 'B'
496 asdf " returns -1
497 Xpath 'C'
498 endif
499 Xpath 'D'
500 break
501 endwhile | Xpath 'E'
502 Xpath 'F'
503
504 return -4 " not reached
Bram Moolenaara6296202020-08-05 11:23:13 +0200505endfunc
Bram Moolenaara2cce862016-01-02 19:50:04 +0100506
507" Aborted functions (T8_G and T8_H) return -1.
508let g:test8_sum = (T8_F() + 1) - 4 * T8_G() - 8 * T8_H()
509Xpath 'X'
510let g:test8_result = g:Xpath
511
512func Test_error_in_function()
513 call assert_equal(13, g:test8_sum)
514 call assert_equal('abcefghijkmnoprsABX', g:test8_result)
515
516 delfunction T8_F
517 delfunction T8_G
518 delfunction T8_H
519endfunc
520
521
522"-------------------------------------------------------------------------------
523" Test 9: Continuing after aborted functions {{{1
524"
525" When a function with the "abort" attribute is aborted due to an
526" error, the next function back in the call hierarchy without an
527" "abort" attribute continues; the value -1 is returned then.
528"-------------------------------------------------------------------------------
529
530XpathINIT
531
Bram Moolenaara6296202020-08-05 11:23:13 +0200532func F() abort
Bram Moolenaara2cce862016-01-02 19:50:04 +0100533 Xpath 'a'
534 let result = G() " not aborted
535 Xpath 'b'
536 if result != 2
537 Xpath 'c'
538 endif
539 return 1
Bram Moolenaara6296202020-08-05 11:23:13 +0200540endfunc
Bram Moolenaara2cce862016-01-02 19:50:04 +0100541
Bram Moolenaara6296202020-08-05 11:23:13 +0200542func G() " no abort attribute
Bram Moolenaara2cce862016-01-02 19:50:04 +0100543 Xpath 'd'
544 if H() != -1 " aborted
545 Xpath 'e'
546 endif
547 Xpath 'f'
548 return 2
Bram Moolenaara6296202020-08-05 11:23:13 +0200549endfunc
Bram Moolenaara2cce862016-01-02 19:50:04 +0100550
Bram Moolenaara6296202020-08-05 11:23:13 +0200551func H() abort
Bram Moolenaara2cce862016-01-02 19:50:04 +0100552 Xpath 'g'
553 call I() " aborted
554 Xpath 'h'
555 return 4
Bram Moolenaara6296202020-08-05 11:23:13 +0200556endfunc
Bram Moolenaara2cce862016-01-02 19:50:04 +0100557
Bram Moolenaara6296202020-08-05 11:23:13 +0200558func I() abort
Bram Moolenaara2cce862016-01-02 19:50:04 +0100559 Xpath 'i'
560 asdf " error
561 Xpath 'j'
562 return 8
Bram Moolenaara6296202020-08-05 11:23:13 +0200563endfunc
Bram Moolenaara2cce862016-01-02 19:50:04 +0100564
565if F() != 1
566 Xpath 'k'
567endif
568
569let g:test9_result = g:Xpath
570
571delfunction F
572delfunction G
573delfunction H
574delfunction I
575
576func Test_func_abort()
577 call assert_equal('adgifb', g:test9_result)
578endfunc
579
580
581"-------------------------------------------------------------------------------
582" Test 10: :if, :elseif, :while argument parsing {{{1
583"
584" A '"' or '|' in an argument expression must not be mixed up with
585" a comment or a next command after a bar. Parsing errors should
586" be recognized.
587"-------------------------------------------------------------------------------
588
589XpathINIT
590
Bram Moolenaara6296202020-08-05 11:23:13 +0200591func MSG(enr, emsg)
Bram Moolenaara2cce862016-01-02 19:50:04 +0100592 let english = v:lang == "C" || v:lang =~ '^[Ee]n'
593 if a:enr == ""
594 Xout "TODO: Add message number for:" a:emsg
595 let v:errmsg = ":" . v:errmsg
596 endif
597 let match = 1
598 if v:errmsg !~ '^'.a:enr.':' || (english && v:errmsg !~ a:emsg)
599 let match = 0
600 if v:errmsg == ""
601 Xout "Message missing."
602 else
Bram Moolenaara4208962019-08-24 20:50:19 +0200603 let v:errmsg = v:errmsg->escape('"')
Bram Moolenaara2cce862016-01-02 19:50:04 +0100604 Xout "Unexpected message:" v:errmsg
605 endif
606 endif
607 return match
Bram Moolenaar1e115362019-01-09 23:01:02 +0100608endfunc
Bram Moolenaara2cce862016-01-02 19:50:04 +0100609
610if 1 || strlen("\"") | Xpath 'a'
611 Xpath 'b'
612endif
613Xpath 'c'
614
615if 0
616elseif 1 || strlen("\"") | Xpath 'd'
617 Xpath 'e'
618endif
619Xpath 'f'
620
621while 1 || strlen("\"") | Xpath 'g'
622 Xpath 'h'
623 break
624endwhile
625Xpath 'i'
626
627let v:errmsg = ""
628if 1 ||| strlen("\"") | Xpath 'j'
629 Xpath 'k'
630endif
631Xpath 'l'
632if !MSG('E15', "Invalid expression")
633 Xpath 'm'
634endif
635
636let v:errmsg = ""
637if 0
638elseif 1 ||| strlen("\"") | Xpath 'n'
639 Xpath 'o'
640endif
641Xpath 'p'
642if !MSG('E15', "Invalid expression")
643 Xpath 'q'
644endif
645
646let v:errmsg = ""
647while 1 ||| strlen("\"") | Xpath 'r'
648 Xpath 's'
649 break
650endwhile
651Xpath 't'
652if !MSG('E15', "Invalid expression")
653 Xpath 'u'
654endif
655
656let g:test10_result = g:Xpath
657delfunction MSG
658
659func Test_expr_parsing()
660 call assert_equal('abcdefghilpt', g:test10_result)
661endfunc
662
663
664"-------------------------------------------------------------------------------
665" Test 11: :if, :elseif, :while argument evaluation after abort {{{1
666"
667" When code is skipped over due to an error, the boolean argument to
668" an :if, :elseif, or :while must not be evaluated.
669"-------------------------------------------------------------------------------
670
671XpathINIT
672
673let calls = 0
674
Bram Moolenaara6296202020-08-05 11:23:13 +0200675func P(num)
Bram Moolenaara2cce862016-01-02 19:50:04 +0100676 let g:calls = g:calls + a:num " side effect on call
677 return 0
Bram Moolenaara6296202020-08-05 11:23:13 +0200678endfunc
Bram Moolenaara2cce862016-01-02 19:50:04 +0100679
680if 1
681 Xpath 'a'
682 asdf " error
683 Xpath 'b'
684 if P(1) " should not be called
685 Xpath 'c'
686 elseif !P(2) " should not be called
687 Xpath 'd'
688 else
689 Xpath 'e'
690 endif
691 Xpath 'f'
692 while P(4) " should not be called
693 Xpath 'g'
694 endwhile
695 Xpath 'h'
696endif
697Xpath 'x'
698
699let g:test11_calls = calls
700let g:test11_result = g:Xpath
701
702unlet calls
703delfunction P
704
705func Test_arg_abort()
706 call assert_equal(0, g:test11_calls)
707 call assert_equal('ax', g:test11_result)
708endfunc
709
710
711"-------------------------------------------------------------------------------
712" Test 12: Expressions in braces in skipped code {{{1
713"
714" In code skipped over due to an error or inactive conditional,
715" an expression in braces as part of a variable or function name
716" should not be evaluated.
717"-------------------------------------------------------------------------------
718
719XpathINIT
720
721function! NULL()
722 Xpath 'a'
723 return 0
724endfunction
725
726function! ZERO()
727 Xpath 'b'
728 return 0
729endfunction
730
731function! F0()
732 Xpath 'c'
733endfunction
734
735function! F1(arg)
736 Xpath 'e'
737endfunction
738
739let V0 = 1
740
741Xpath 'f'
742echo 0 ? F{NULL() + V{ZERO()}}() : 1
743
744Xpath 'g'
745if 0
746 Xpath 'h'
747 call F{NULL() + V{ZERO()}}()
748endif
749
750Xpath 'i'
751if 1
752 asdf " error
753 Xpath 'j'
754 call F1(F{NULL() + V{ZERO()}}())
755endif
756
757Xpath 'k'
758if 1
759 asdf " error
760 Xpath 'l'
761 call F{NULL() + V{ZERO()}}()
762endif
763
764let g:test12_result = g:Xpath
765
766func Test_braces_skipped()
767 call assert_equal('fgik', g:test12_result)
768endfunc
769
770
771"-------------------------------------------------------------------------------
772" Test 13: Failure in argument evaluation for :while {{{1
773"
774" A failure in the expression evaluation for the condition of a :while
775" causes the whole :while loop until the matching :endwhile being
776" ignored. Continuation is at the next following line.
777"-------------------------------------------------------------------------------
778
779XpathINIT
780
781Xpath 'a'
782while asdf
783 Xpath 'b'
784 while 1
785 Xpath 'c'
786 break
787 endwhile
788 Xpath 'd'
789 break
790endwhile
791Xpath 'e'
792
793while asdf | Xpath 'f' | endwhile | Xpath 'g'
794Xpath 'h'
795let g:test13_result = g:Xpath
796
797func Test_while_fail()
798 call assert_equal('aeh', g:test13_result)
799endfunc
800
801
802"-------------------------------------------------------------------------------
803" Test 14: Failure in argument evaluation for :if {{{1
804"
805" A failure in the expression evaluation for the condition of an :if
806" does not cause the corresponding :else or :endif being matched to
807" a previous :if/:elseif. Neither of both branches of the failed :if
808" are executed.
809"-------------------------------------------------------------------------------
810
811XpathINIT
812
813function! F()
814 Xpath 'a'
815 let x = 0
816 if x " false
817 Xpath 'b'
818 elseif !x " always true
819 Xpath 'c'
820 let x = 1
821 if g:boolvar " possibly undefined
822 Xpath 'd'
823 else
824 Xpath 'e'
825 endif
826 Xpath 'f'
827 elseif x " never executed
828 Xpath 'g'
829 endif
830 Xpath 'h'
831endfunction
832
833let boolvar = 1
834call F()
835Xpath '-'
836
837unlet boolvar
838call F()
839let g:test14_result = g:Xpath
840
841delfunction F
842
843func Test_if_fail()
844 call assert_equal('acdfh-acfh', g:test14_result)
845endfunc
846
847
848"-------------------------------------------------------------------------------
849" Test 15: Failure in argument evaluation for :if (bar) {{{1
850"
851" Like previous test, except that the failing :if ... | ... | :endif
852" is in a single line.
853"-------------------------------------------------------------------------------
854
855XpathINIT
856
857function! F()
858 Xpath 'a'
859 let x = 0
860 if x " false
861 Xpath 'b'
862 elseif !x " always true
863 Xpath 'c'
864 let x = 1
865 if g:boolvar | Xpath 'd' | else | Xpath 'e' | endif
866 Xpath 'f'
867 elseif x " never executed
868 Xpath 'g'
869 endif
870 Xpath 'h'
871endfunction
872
873let boolvar = 1
874call F()
875Xpath '-'
876
877unlet boolvar
878call F()
879let g:test15_result = g:Xpath
880
881delfunction F
882
883func Test_if_bar_fail()
884 call assert_equal('acdfh-acfh', g:test15_result)
885endfunc
886
Bram Moolenaar4119cf82016-01-17 14:59:01 +0100887"-------------------------------------------------------------------------------
Bram Moolenaar1f068232019-11-03 16:17:26 +0100888" Test 16: Double :else or :elseif after :else {{{1
889"
890" Multiple :elses or an :elseif after an :else are forbidden.
891"-------------------------------------------------------------------------------
892
893func T16_F() abort
894 if 0
895 Xpath 'a'
896 else
897 Xpath 'b'
898 else " aborts function
899 Xpath 'c'
900 endif
901 Xpath 'd'
902endfunc
903
904func T16_G() abort
905 if 0
906 Xpath 'a'
907 else
908 Xpath 'b'
909 elseif 1 " aborts function
910 Xpath 'c'
911 else
912 Xpath 'd'
913 endif
914 Xpath 'e'
915endfunc
916
917func T16_H() abort
918 if 0
919 Xpath 'a'
920 elseif 0
921 Xpath 'b'
922 else
923 Xpath 'c'
924 else " aborts function
925 Xpath 'd'
926 endif
927 Xpath 'e'
928endfunc
929
930func T16_I() abort
931 if 0
932 Xpath 'a'
933 elseif 0
934 Xpath 'b'
935 else
936 Xpath 'c'
937 elseif 1 " aborts function
938 Xpath 'd'
939 else
940 Xpath 'e'
941 endif
942 Xpath 'f'
943endfunc
944
945func Test_Multi_Else()
946 XpathINIT
947 try
948 call T16_F()
949 catch /E583:/
950 Xpath 'e'
951 endtry
952 call assert_equal('be', g:Xpath)
953
954 XpathINIT
955 try
956 call T16_G()
957 catch /E584:/
958 Xpath 'f'
959 endtry
960 call assert_equal('bf', g:Xpath)
961
962 XpathINIT
963 try
964 call T16_H()
965 catch /E583:/
966 Xpath 'f'
967 endtry
968 call assert_equal('cf', g:Xpath)
969
970 XpathINIT
971 try
972 call T16_I()
973 catch /E584:/
974 Xpath 'g'
975 endtry
976 call assert_equal('cg', g:Xpath)
977endfunc
978
979"-------------------------------------------------------------------------------
980" Test 17: Nesting of unmatched :if or :endif inside a :while {{{1
981"
982" The :while/:endwhile takes precedence in nesting over an unclosed
983" :if or an unopened :endif.
984"-------------------------------------------------------------------------------
985
986" While loops inside a function are continued on error.
987func T17_F()
988 let loops = 3
989 while loops > 0
990 let loops -= 1
991 Xpath 'a' . loops
992 if (loops == 1)
993 Xpath 'b' . loops
994 continue
995 elseif (loops == 0)
996 Xpath 'c' . loops
997 break
998 elseif 1
999 Xpath 'd' . loops
1000 " endif missing!
1001 endwhile " :endwhile after :if 1
1002 Xpath 'e'
1003endfunc
1004
1005func T17_G()
1006 let loops = 2
1007 while loops > 0
1008 let loops -= 1
1009 Xpath 'a' . loops
1010 if 0
1011 Xpath 'b' . loops
1012 " endif missing
1013 endwhile " :endwhile after :if 0
1014endfunc
1015
1016func T17_H()
1017 let loops = 2
1018 while loops > 0
1019 let loops -= 1
1020 Xpath 'a' . loops
1021 " if missing!
1022 endif " :endif without :if in while
1023 Xpath 'b' . loops
1024 endwhile
1025endfunc
1026
1027" Error continuation outside a function is at the outermost :endwhile or :endif.
1028XpathINIT
1029let v:errmsg = ''
1030let loops = 2
1031while loops > 0
1032 let loops -= 1
1033 Xpath 'a' . loops
1034 if 0
1035 Xpath 'b' . loops
1036 " endif missing! Following :endwhile fails.
1037endwhile | Xpath 'c'
1038Xpath 'd'
1039call assert_match('E171:', v:errmsg)
1040call assert_equal('a1d', g:Xpath)
1041
1042func Test_unmatched_if_in_while()
1043 XpathINIT
1044 call assert_fails('call T17_F()', 'E171:')
1045 call assert_equal('a2d2a1b1a0c0e', g:Xpath)
1046
1047 XpathINIT
1048 call assert_fails('call T17_G()', 'E171:')
1049 call assert_equal('a1a0', g:Xpath)
1050
1051 XpathINIT
1052 call assert_fails('call T17_H()', 'E580:')
1053 call assert_equal('a1b1a0b0', g:Xpath)
1054endfunc
1055
1056"-------------------------------------------------------------------------------
Bram Moolenaara6296202020-08-05 11:23:13 +02001057" Test 18: Interrupt (Ctrl-C pressed) {{{1
1058"
1059" On an interrupt, the script processing is terminated immediately.
Bram Moolenaar1f068232019-11-03 16:17:26 +01001060"-------------------------------------------------------------------------------
Bram Moolenaara6296202020-08-05 11:23:13 +02001061
1062func Test_interrupt_while_if()
1063 let test =<< trim [CODE]
1064 try
1065 if 1
1066 Xpath 'a'
1067 while 1
1068 Xpath 'b'
1069 if 1
1070 Xpath 'c'
1071 call interrupt()
1072 call assert_report('should not get here')
1073 break
1074 finish
1075 endif | call assert_report('should not get here')
1076 call assert_report('should not get here')
1077 endwhile | call assert_report('should not get here')
1078 call assert_report('should not get here')
1079 endif | call assert_report('should not get here')
1080 call assert_report('should not get here')
1081 catch /^Vim:Interrupt$/
1082 Xpath 'd'
1083 endtry | Xpath 'e'
1084 Xpath 'f'
1085 [CODE]
1086 let verify =<< trim [CODE]
1087 call assert_equal('abcdef', g:Xpath)
1088 [CODE]
1089 call RunInNewVim(test, verify)
1090endfunc
1091
1092func Test_interrupt_try()
1093 let test =<< trim [CODE]
1094 try
1095 try
1096 Xpath 'a'
1097 call interrupt()
1098 call assert_report('should not get here')
1099 endtry | call assert_report('should not get here')
1100 call assert_report('should not get here')
1101 catch /^Vim:Interrupt$/
1102 Xpath 'b'
1103 endtry | Xpath 'c'
1104 Xpath 'd'
1105 [CODE]
1106 let verify =<< trim [CODE]
1107 call assert_equal('abcd', g:Xpath)
1108 [CODE]
1109 call RunInNewVim(test, verify)
1110endfunc
1111
1112func Test_interrupt_func_while_if()
1113 let test =<< trim [CODE]
1114 func F()
1115 if 1
1116 Xpath 'a'
1117 while 1
1118 Xpath 'b'
1119 if 1
1120 Xpath 'c'
1121 call interrupt()
1122 call assert_report('should not get here')
1123 break
1124 return
1125 endif | call assert_report('should not get here')
1126 call assert_report('should not get here')
1127 endwhile | call assert_report('should not get here')
1128 call assert_report('should not get here')
1129 endif | call assert_report('should not get here')
1130 call assert_report('should not get here')
1131 endfunc
1132
1133 Xpath 'd'
1134 try
1135 call F() | call assert_report('should not get here')
1136 catch /^Vim:Interrupt$/
1137 Xpath 'e'
1138 endtry | Xpath 'f'
1139 Xpath 'g'
1140 [CODE]
1141 let verify =<< trim [CODE]
1142 call assert_equal('dabcefg', g:Xpath)
1143 [CODE]
1144 call RunInNewVim(test, verify)
1145endfunc
1146
1147func Test_interrupt_func_try()
1148 let test =<< trim [CODE]
1149 func G()
1150 try
1151 Xpath 'a'
1152 call interrupt()
1153 call assert_report('should not get here')
1154 endtry | call assert_report('should not get here')
1155 call assert_report('should not get here')
1156 endfunc
1157
1158 Xpath 'b'
1159 try
1160 call G() | call assert_report('should not get here')
1161 catch /^Vim:Interrupt$/
1162 Xpath 'c'
1163 endtry | Xpath 'd'
1164 Xpath 'e'
1165 [CODE]
1166 let verify =<< trim [CODE]
1167 call assert_equal('bacde', g:Xpath)
1168 [CODE]
1169 call RunInNewVim(test, verify)
1170endfunc
1171
1172"-------------------------------------------------------------------------------
1173" Test 19: Aborting on errors inside :try/:endtry {{{1
1174"
1175" An error in a command dynamically enclosed in a :try/:endtry region
1176" aborts script processing immediately. It does not matter whether
1177" the failing command is outside or inside a function and whether a
1178" function has an "abort" attribute.
1179"-------------------------------------------------------------------------------
1180
1181func Test_try_error_abort_1()
1182 let test =<< trim [CODE]
1183 func F() abort
1184 Xpath 'a'
1185 asdf
1186 call assert_report('should not get here')
1187 endfunc
1188
1189 try
1190 Xpath 'b'
1191 call F()
1192 call assert_report('should not get here')
1193 endtry | call assert_report('should not get here')
1194 call assert_report('should not get here')
1195 [CODE]
1196 let verify =<< trim [CODE]
1197 call assert_equal('ba', g:Xpath)
1198 [CODE]
1199 call RunInNewVim(test, verify)
1200endfunc
1201
1202func Test_try_error_abort_2()
1203 let test =<< trim [CODE]
1204 func G()
1205 Xpath 'a'
1206 asdf
1207 call assert_report('should not get here')
1208 endfunc
1209
1210 try
1211 Xpath 'b'
1212 call G()
1213 call assert_report('should not get here')
1214 endtry | call assert_report('should not get here')
1215 call assert_report('should not get here')
1216 [CODE]
1217 let verify =<< trim [CODE]
1218 call assert_equal('ba', g:Xpath)
1219 [CODE]
1220 call RunInNewVim(test, verify)
1221endfunc
1222
1223func Test_try_error_abort_3()
1224 let test =<< trim [CODE]
1225 try
1226 Xpath 'a'
1227 asdf
1228 call assert_report('should not get here')
1229 endtry | call assert_report('should not get here')
1230 call assert_report('should not get here')
1231 [CODE]
1232 let verify =<< trim [CODE]
1233 call assert_equal('a', g:Xpath)
1234 [CODE]
1235 call RunInNewVim(test, verify)
1236endfunc
1237
1238func Test_try_error_abort_4()
1239 let test =<< trim [CODE]
1240 if 1
1241 try
1242 Xpath 'a'
1243 asdf
1244 call assert_report('should not get here')
1245 endtry | call assert_report('should not get here')
1246 endif | call assert_report('should not get here')
1247 call assert_report('should not get here')
1248 [CODE]
1249 let verify =<< trim [CODE]
1250 call assert_equal('a', g:Xpath)
1251 [CODE]
1252 call RunInNewVim(test, verify)
1253endfunc
1254
1255func Test_try_error_abort_5()
1256 let test =<< trim [CODE]
1257 let p = 1
1258 while p
1259 let p = 0
1260 try
1261 Xpath 'a'
1262 asdf
1263 call assert_report('should not get here')
1264 endtry | call assert_report('should not get here')
1265 endwhile | call assert_report('should not get here')
1266 call assert_report('should not get here')
1267 [CODE]
1268 let verify =<< trim [CODE]
1269 call assert_equal('a', g:Xpath)
1270 [CODE]
1271 call RunInNewVim(test, verify)
1272endfunc
1273
1274func Test_try_error_abort_6()
1275 let test =<< trim [CODE]
1276 let p = 1
1277 Xpath 'a'
1278 while p
1279 Xpath 'b'
1280 let p = 0
1281 try
1282 Xpath 'c'
1283 endwhile | call assert_report('should not get here')
1284 call assert_report('should not get here')
1285 [CODE]
1286 let verify =<< trim [CODE]
1287 call assert_equal('abc', g:Xpath)
1288 [CODE]
1289 call RunInNewVim(test, verify)
1290endfunc
1291
1292"-------------------------------------------------------------------------------
1293" Test 20: Aborting on errors after :try/:endtry {{{1
1294"
1295" When an error occurs after the last active :try/:endtry region has
1296" been left, termination behavior is as if no :try/:endtry has been
1297" seen.
1298"-------------------------------------------------------------------------------
1299
1300func Test_error_after_try_1()
1301 let test =<< trim [CODE]
1302 let p = 1
1303 while p
1304 let p = 0
1305 Xpath 'a'
1306 try
1307 Xpath 'b'
1308 endtry
1309 asdf
1310 call assert_report('should not get here')
1311 endwhile | call assert_report('should not get here')
1312 Xpath 'c'
1313 [CODE]
1314 let verify =<< trim [CODE]
1315 call assert_equal('abc', g:Xpath)
1316 [CODE]
1317 call RunInNewVim(test, verify)
1318endfunc
1319
1320func Test_error_after_try_2()
1321 let test =<< trim [CODE]
1322 while 1
1323 try
1324 Xpath 'a'
1325 break
1326 call assert_report('should not get here')
1327 endtry
1328 endwhile
1329 Xpath 'b'
1330 asdf
1331 Xpath 'c'
1332 [CODE]
1333 let verify =<< trim [CODE]
1334 call assert_equal('abc', g:Xpath)
1335 [CODE]
1336 call RunInNewVim(test, verify)
1337endfunc
1338
1339func Test_error_after_try_3()
1340 let test =<< trim [CODE]
1341 while 1
1342 try
1343 Xpath 'a'
1344 break
1345 call assert_report('should not get here')
1346 finally
1347 Xpath 'b'
1348 endtry
1349 endwhile
1350 Xpath 'c'
1351 asdf
1352 Xpath 'd'
1353 [CODE]
1354 let verify =<< trim [CODE]
1355 call assert_equal('abcd', g:Xpath)
1356 [CODE]
1357 call RunInNewVim(test, verify)
1358endfunc
1359
1360func Test_error_after_try_4()
1361 let test =<< trim [CODE]
1362 while 1
1363 try
1364 Xpath 'a'
1365 finally
1366 Xpath 'b'
1367 break
1368 call assert_report('should not get here')
1369 endtry
1370 endwhile
1371 Xpath 'c'
1372 asdf
1373 Xpath 'd'
1374 [CODE]
1375 let verify =<< trim [CODE]
1376 call assert_equal('abcd', g:Xpath)
1377 [CODE]
1378 call RunInNewVim(test, verify)
1379endfunc
1380
1381func Test_error_after_try_5()
1382 let test =<< trim [CODE]
1383 let p = 1
1384 while p
1385 let p = 0
1386 try
1387 Xpath 'a'
1388 continue
1389 call assert_report('should not get here')
1390 endtry
1391 endwhile
1392 Xpath 'b'
1393 asdf
1394 Xpath 'c'
1395 [CODE]
1396 let verify =<< trim [CODE]
1397 call assert_equal('abc', g:Xpath)
1398 [CODE]
1399 call RunInNewVim(test, verify)
1400endfunc
1401
1402func Test_error_after_try_6()
1403 let test =<< trim [CODE]
1404 let p = 1
1405 while p
1406 let p = 0
1407 try
1408 Xpath 'a'
1409 continue
1410 call assert_report('should not get here')
1411 finally
1412 Xpath 'b'
1413 endtry
1414 endwhile
1415 Xpath 'c'
1416 asdf
1417 Xpath 'd'
1418 [CODE]
1419 let verify =<< trim [CODE]
1420 call assert_equal('abcd', g:Xpath)
1421 [CODE]
1422 call RunInNewVim(test, verify)
1423endfunc
1424
1425func Test_error_after_try_7()
1426 let test =<< trim [CODE]
1427 let p = 1
1428 while p
1429 let p = 0
1430 try
1431 Xpath 'a'
1432 finally
1433 Xpath 'b'
1434 continue
1435 call assert_report('should not get here')
1436 endtry
1437 endwhile
1438 Xpath 'c'
1439 asdf
1440 Xpath 'd'
1441 [CODE]
1442 let verify =<< trim [CODE]
1443 call assert_equal('abcd', g:Xpath)
1444 [CODE]
1445 call RunInNewVim(test, verify)
1446endfunc
1447
1448"-------------------------------------------------------------------------------
1449" Test 21: :finally for :try after :continue/:break/:return/:finish {{{1
1450"
1451" If a :try conditional stays inactive due to a preceding :continue,
1452" :break, :return, or :finish, its :finally clause should not be
1453" executed.
1454"-------------------------------------------------------------------------------
1455
1456func Test_finally_after_loop_ctrl_statement()
1457 let test =<< trim [CODE]
1458 func F()
1459 let loops = 2
1460 while loops > 0
1461 XloopNEXT
1462 let loops = loops - 1
1463 try
1464 if loops == 1
1465 Xloop 'a'
1466 continue
1467 call assert_report('should not get here')
1468 elseif loops == 0
1469 Xloop 'b'
1470 break
1471 call assert_report('should not get here')
1472 endif
1473
1474 try " inactive
1475 call assert_report('should not get here')
1476 finally
1477 call assert_report('should not get here')
1478 endtry
1479 finally
1480 Xloop 'c'
1481 endtry
1482 call assert_report('should not get here')
1483 endwhile
1484
1485 try
1486 Xpath 'd'
1487 return
1488 call assert_report('should not get here')
1489 try " inactive
1490 call assert_report('should not get here')
1491 finally
1492 call assert_report('should not get here')
1493 endtry
1494 finally
1495 Xpath 'e'
1496 endtry
1497 call assert_report('should not get here')
1498 endfunc
1499
1500 try
1501 Xpath 'f'
1502 call F()
1503 Xpath 'g'
1504 finish
1505 call assert_report('should not get here')
1506 try " inactive
1507 call assert_report('should not get here')
1508 finally
1509 call assert_report('should not get here')
1510 endtry
1511 finally
1512 Xpath 'h'
1513 endtry
1514 call assert_report('should not get here')
1515 [CODE]
1516 let verify =<< trim [CODE]
1517 call assert_equal('fa2c2b3c3degh', g:Xpath)
1518 [CODE]
1519 call RunInNewVim(test, verify)
1520endfunc
1521
1522"-------------------------------------------------------------------------------
1523" Test 22: :finally for a :try after an error/interrupt/:throw {{{1
1524"
1525" If a :try conditional stays inactive due to a preceding error or
1526" interrupt or :throw, its :finally clause should not be executed.
1527"-------------------------------------------------------------------------------
1528
1529func Test_finally_after_error_in_func()
1530 let test =<< trim [CODE]
1531 func Error()
1532 try
1533 Xpath 'b'
1534 asdf " aborting error, triggering error exception
1535 call assert_report('should not get here')
1536 endtry
1537 call assert_report('should not get here')
1538 endfunc
1539
1540 Xpath 'a'
1541 call Error()
1542 call assert_report('should not get here')
1543
1544 if 1 " not active due to error
1545 try " not active since :if inactive
1546 call assert_report('should not get here')
1547 finally
1548 call assert_report('should not get here')
1549 endtry
1550 endif
1551
1552 try " not active due to error
1553 call assert_report('should not get here')
1554 finally
1555 call assert_report('should not get here')
1556 endtry
1557 [CODE]
1558 let verify =<< trim [CODE]
1559 call assert_equal('ab', g:Xpath)
1560 [CODE]
1561 call RunInNewVim(test, verify)
1562endfunc
1563
1564func Test_finally_after_interrupt()
1565 let test =<< trim [CODE]
1566 func Interrupt()
1567 try
1568 Xpath 'a'
1569 call interrupt() " triggering interrupt exception
1570 call assert_report('should not get here')
1571 endtry
1572 endfunc
1573
1574 Xpath 'b'
1575 try
1576 call Interrupt()
1577 catch /^Vim:Interrupt$/
1578 Xpath 'c'
1579 finish
1580 endtry
1581 call assert_report('should not get here')
1582
1583 if 1 " not active due to interrupt
1584 try " not active since :if inactive
1585 call assert_report('should not get here')
1586 finally
1587 call assert_report('should not get here')
1588 endtry
1589 endif
1590
1591 try " not active due to interrupt
1592 call assert_report('should not get here')
1593 finally
1594 call assert_report('should not get here')
1595 endtry
1596 [CODE]
1597 let verify =<< trim [CODE]
1598 call assert_equal('bac', g:Xpath)
1599 [CODE]
1600 call RunInNewVim(test, verify)
1601endfunc
1602
1603func Test_finally_after_throw()
1604 let test =<< trim [CODE]
1605 func Throw()
1606 Xpath 'a'
1607 throw 'xyz'
1608 endfunc
1609
1610 Xpath 'b'
1611 call Throw()
1612 call assert_report('should not get here')
1613
1614 if 1 " not active due to :throw
1615 try " not active since :if inactive
1616 call assert_report('should not get here')
1617 finally
1618 call assert_report('should not get here')
1619 endtry
1620 endif
1621
1622 try " not active due to :throw
1623 call assert_report('should not get here')
1624 finally
1625 call assert_report('should not get here')
1626 endtry
1627 [CODE]
1628 let verify =<< trim [CODE]
1629 call assert_equal('ba', g:Xpath)
1630 [CODE]
1631 call RunInNewVim(test, verify)
1632endfunc
1633
1634"-------------------------------------------------------------------------------
1635" Test 23: :catch clauses for a :try after a :throw {{{1
1636"
1637" If a :try conditional stays inactive due to a preceding :throw,
1638" none of its :catch clauses should be executed.
1639"-------------------------------------------------------------------------------
1640
1641func Test_catch_after_throw()
1642 let test =<< trim [CODE]
1643 try
1644 Xpath 'a'
1645 throw "xyz"
1646 call assert_report('should not get here')
1647
1648 if 1 " not active due to :throw
1649 try " not active since :if inactive
1650 call assert_report('should not get here')
1651 catch /xyz/
1652 call assert_report('should not get here')
1653 endtry
1654 endif
1655 catch /xyz/
1656 Xpath 'b'
1657 endtry
1658
1659 Xpath 'c'
1660 throw "abc"
1661 call assert_report('should not get here')
1662
1663 try " not active due to :throw
1664 call assert_report('should not get here')
1665 catch /abc/
1666 call assert_report('should not get here')
1667 endtry
1668 [CODE]
1669 let verify =<< trim [CODE]
1670 call assert_equal('abc', g:Xpath)
1671 [CODE]
1672 call RunInNewVim(test, verify)
1673endfunc
1674
1675"-------------------------------------------------------------------------------
1676" Test 24: :endtry for a :try after a :throw {{{1
1677"
1678" If a :try conditional stays inactive due to a preceding :throw,
1679" its :endtry should not rethrow the exception to the next surrounding
1680" active :try conditional.
1681"-------------------------------------------------------------------------------
1682
1683func Test_endtry_after_throw()
1684 let test =<< trim [CODE]
1685 try " try 1
1686 try " try 2
1687 Xpath 'a'
1688 throw "xyz" " makes try 2 inactive
1689 call assert_report('should not get here')
1690
1691 try " try 3
1692 call assert_report('should not get here')
1693 endtry " no rethrow to try 1
1694 catch /xyz/ " should catch although try 2 inactive
1695 Xpath 'b'
1696 endtry
1697 catch /xyz/ " try 1 active, but exception already caught
1698 call assert_report('should not get here')
1699 endtry
1700 Xpath 'c'
1701 [CODE]
1702 let verify =<< trim [CODE]
1703 call assert_equal('abc', g:Xpath)
1704 [CODE]
1705 call RunInNewVim(test, verify)
1706endfunc
1707
1708"-------------------------------------------------------------------------------
1709" Test 27: Executing :finally clauses after :return {{{1
1710"
1711" For a :return command dynamically enclosed in a :try/:endtry region,
1712" :finally clauses are executed and the called function is ended.
1713"-------------------------------------------------------------------------------
1714
1715func T27_F()
1716 try
1717 Xpath 'a'
1718 try
1719 Xpath 'b'
1720 return
1721 call assert_report('should not get here')
1722 finally
1723 Xpath 'c'
1724 endtry
1725 Xpath 'd'
1726 finally
1727 Xpath 'e'
1728 endtry
1729 call assert_report('should not get here')
1730endfunc
1731
1732func T27_G()
1733 try
1734 Xpath 'f'
1735 return
1736 call assert_report('should not get here')
1737 finally
1738 Xpath 'g'
1739 call T27_F()
1740 Xpath 'h'
1741 endtry
1742 call assert_report('should not get here')
1743endfunc
1744
1745func T27_H()
1746 try
1747 Xpath 'i'
1748 call T27_G()
1749 Xpath 'j'
1750 finally
1751 Xpath 'k'
1752 return
1753 call assert_report('should not get here')
1754 endtry
1755 call assert_report('should not get here')
1756endfunction
1757
1758func Test_finally_after_return()
1759 XpathINIT
1760 try
1761 Xpath 'l'
1762 call T27_H()
1763 Xpath 'm'
1764 finally
1765 Xpath 'n'
1766 endtry
1767 call assert_equal('lifgabcehjkmn', g:Xpath)
1768endfunc
1769
1770"-------------------------------------------------------------------------------
1771" Test 28: Executing :finally clauses after :finish {{{1
1772"
1773" For a :finish command dynamically enclosed in a :try/:endtry region,
1774" :finally clauses are executed and the sourced file is finished.
1775"
1776" This test executes the bodies of the functions F, G, and H from the
1777" previous test as script files (:return replaced by :finish).
1778"-------------------------------------------------------------------------------
1779
1780func Test_finally_after_finish()
1781 XpathINIT
1782
1783 let scriptF = MakeScript("T27_F")
1784 let scriptG = MakeScript("T27_G", scriptF)
1785 let scriptH = MakeScript("T27_H", scriptG)
1786
1787 try
1788 Xpath 'A'
1789 exec "source" scriptH
1790 Xpath 'B'
1791 finally
1792 Xpath 'C'
1793 endtry
1794 Xpath 'D'
1795 call assert_equal('AifgabcehjkBCD', g:Xpath)
1796 call delete(scriptF)
1797 call delete(scriptG)
1798 call delete(scriptH)
1799endfunc
1800
1801"-------------------------------------------------------------------------------
1802" Test 29: Executing :finally clauses on errors {{{1
1803"
1804" After an error in a command dynamically enclosed in a :try/:endtry
1805" region, :finally clauses are executed and the script processing is
1806" terminated.
1807"-------------------------------------------------------------------------------
1808
1809func Test_finally_after_error_1()
1810 let test =<< trim [CODE]
1811 func F()
1812 while 1
1813 try
1814 Xpath 'a'
1815 while 1
1816 try
1817 Xpath 'b'
1818 asdf " error
1819 call assert_report('should not get here')
1820 finally
1821 Xpath 'c'
1822 endtry | call assert_report('should not get here')
1823 call assert_report('should not get here')
1824 break
1825 endwhile
1826 call assert_report('should not get here')
1827 finally
1828 Xpath 'd'
1829 endtry | call assert_report('should not get here')
1830 call assert_report('should not get here')
1831 break
1832 endwhile
1833 call assert_report('should not get here')
1834 endfunc
1835
1836 while 1
1837 try
1838 Xpath 'e'
1839 while 1
1840 call F()
1841 call assert_report('should not get here')
1842 break
1843 endwhile | call assert_report('should not get here')
1844 call assert_report('should not get here')
1845 finally
1846 Xpath 'f'
1847 endtry | call assert_report('should not get here')
1848 endwhile | call assert_report('should not get here')
1849 call assert_report('should not get here')
1850 [CODE]
1851 let verify =<< trim [CODE]
1852 call assert_equal('eabcdf', g:Xpath)
1853 [CODE]
1854 call RunInNewVim(test, verify)
1855endfunc
1856
1857func Test_finally_after_error_2()
1858 let test =<< trim [CODE]
1859 func G() abort
1860 if 1
1861 try
1862 Xpath 'a'
1863 asdf " error
1864 call assert_report('should not get here')
1865 finally
1866 Xpath 'b'
1867 endtry | Xpath 'c'
1868 endif | Xpath 'd'
1869 call assert_report('should not get here')
1870 endfunc
1871
1872 if 1
1873 try
1874 Xpath 'e'
1875 call G()
1876 call assert_report('should not get here')
1877 finally
1878 Xpath 'f'
1879 endtry | call assert_report('should not get here')
1880 endif | call assert_report('should not get here')
1881 call assert_report('should not get here')
1882 [CODE]
1883 let verify =<< trim [CODE]
1884 call assert_equal('eabf', g:Xpath)
1885 [CODE]
1886 call RunInNewVim(test, verify)
1887endfunc
1888
1889"-------------------------------------------------------------------------------
1890" Test 30: Executing :finally clauses on interrupt {{{1
1891"
1892" After an interrupt in a command dynamically enclosed in
1893" a :try/:endtry region, :finally clauses are executed and the
1894" script processing is terminated.
1895"-------------------------------------------------------------------------------
1896
1897func Test_finally_on_interrupt()
1898 let test =<< trim [CODE]
1899 func F()
1900 try
1901 Xloop 'a'
1902 call interrupt()
1903 call assert_report('should not get here')
1904 finally
1905 Xloop 'b'
1906 endtry
1907 call assert_report('should not get here')
1908 endfunc
1909
1910 try
1911 try
1912 Xpath 'c'
1913 try
1914 Xpath 'd'
1915 call interrupt()
1916 call assert_report('should not get here')
1917 finally
1918 Xpath 'e'
1919 try
1920 Xpath 'f'
1921 try
1922 Xpath 'g'
1923 finally
1924 Xpath 'h'
1925 try
1926 Xpath 'i'
1927 call interrupt()
1928 call assert_report('should not get here')
1929 endtry
1930 call assert_report('should not get here')
1931 endtry
1932 call assert_report('should not get here')
1933 endtry
1934 call assert_report('should not get here')
1935 endtry
1936 call assert_report('should not get here')
1937 finally
1938 Xpath 'j'
1939 try
1940 Xpath 'k'
1941 call F()
1942 call assert_report('should not get here')
1943 finally
1944 Xpath 'l'
1945 try
1946 Xpath 'm'
1947 XloopNEXT
1948 ExecAsScript F
1949 call assert_report('should not get here')
1950 finally
1951 Xpath 'n'
1952 endtry
1953 call assert_report('should not get here')
1954 endtry
1955 call assert_report('should not get here')
1956 endtry
1957 call assert_report('should not get here')
1958 catch /^Vim:Interrupt$/
1959 Xpath 'o'
1960 endtry
1961 [CODE]
1962 let verify =<< trim [CODE]
1963 call assert_equal('cdefghijka1b1lma2b2no', g:Xpath)
1964 [CODE]
1965 call RunInNewVim(test, verify)
1966endfunc
1967
1968"-------------------------------------------------------------------------------
1969" Test 31: Executing :finally clauses after :throw {{{1
1970"
1971" After a :throw dynamically enclosed in a :try/:endtry region,
1972" :finally clauses are executed and the script processing is
1973" terminated.
1974"-------------------------------------------------------------------------------
1975
1976func Test_finally_after_throw_2()
1977 let test =<< trim [CODE]
1978 func F()
1979 try
1980 Xloop 'a'
1981 throw "exception"
1982 call assert_report('should not get here')
1983 finally
1984 Xloop 'b'
1985 endtry
1986 call assert_report('should not get here')
1987 endfunc
1988
1989 try
1990 Xpath 'c'
1991 try
1992 Xpath 'd'
1993 throw "exception"
1994 call assert_report('should not get here')
1995 finally
1996 Xpath 'e'
1997 try
1998 Xpath 'f'
1999 try
2000 Xpath 'g'
2001 finally
2002 Xpath 'h'
2003 try
2004 Xpath 'i'
2005 throw "exception"
2006 call assert_report('should not get here')
2007 endtry
2008 call assert_report('should not get here')
2009 endtry
2010 call assert_report('should not get here')
2011 endtry
2012 call assert_report('should not get here')
2013 endtry
2014 call assert_report('should not get here')
2015 finally
2016 Xpath 'j'
2017 try
2018 Xpath 'k'
2019 call F()
2020 call assert_report('should not get here')
2021 finally
2022 Xpath 'l'
2023 try
2024 Xpath 'm'
2025 XloopNEXT
2026 ExecAsScript F
2027 call assert_report('should not get here')
2028 finally
2029 Xpath 'n'
2030 endtry
2031 call assert_report('should not get here')
2032 endtry
2033 call assert_report('should not get here')
2034 endtry
2035 call assert_report('should not get here')
2036 [CODE]
2037 let verify =<< trim [CODE]
2038 call assert_equal('cdefghijka1b1lma2b2n', g:Xpath)
2039 [CODE]
2040 call RunInNewVim(test, verify)
2041endfunc
2042
2043"-------------------------------------------------------------------------------
2044" Test 34: :finally reason discarded by :continue {{{1
2045"
2046" When a :finally clause is executed due to a :continue, :break,
2047" :return, :finish, error, interrupt or :throw, the jump reason is
2048" discarded by a :continue in the finally clause.
2049"-------------------------------------------------------------------------------
2050
2051func Test_finally_after_continue()
2052 let test =<< trim [CODE]
2053 func C(jump)
2054 XloopNEXT
2055 let loop = 0
2056 while loop < 2
2057 let loop = loop + 1
2058 if loop == 1
2059 try
2060 if a:jump == "continue"
2061 continue
2062 elseif a:jump == "break"
2063 break
2064 elseif a:jump == "return" || a:jump == "finish"
2065 return
2066 elseif a:jump == "error"
2067 asdf
2068 elseif a:jump == "interrupt"
2069 call interrupt()
2070 let dummy = 0
2071 elseif a:jump == "throw"
2072 throw "abc"
2073 endif
2074 finally
2075 continue " discards jump that caused the :finally
2076 call assert_report('should not get here')
2077 endtry
2078 call assert_report('should not get here')
2079 elseif loop == 2
2080 Xloop 'a'
2081 endif
2082 endwhile
2083 endfunc
2084
2085 call C("continue")
2086 Xpath 'b'
2087 call C("break")
2088 Xpath 'c'
2089 call C("return")
2090 Xpath 'd'
2091 let g:jump = "finish"
2092 ExecAsScript C
2093 unlet g:jump
2094 Xpath 'e'
2095 try
2096 call C("error")
2097 Xpath 'f'
2098 finally
2099 Xpath 'g'
2100 try
2101 call C("interrupt")
2102 Xpath 'h'
2103 finally
2104 Xpath 'i'
2105 call C("throw")
2106 Xpath 'j'
2107 endtry
2108 endtry
2109 Xpath 'k'
2110 [CODE]
2111 let verify =<< trim [CODE]
2112 call assert_equal('a2ba3ca4da5ea6fga7hia8jk', g:Xpath)
2113 [CODE]
2114 call RunInNewVim(test, verify)
2115endfunc
2116
2117"-------------------------------------------------------------------------------
2118" Test 35: :finally reason discarded by :break {{{1
2119"
2120" When a :finally clause is executed due to a :continue, :break,
2121" :return, :finish, error, interrupt or :throw, the jump reason is
2122" discarded by a :break in the finally clause.
2123"-------------------------------------------------------------------------------
2124
2125func Test_finally_discard_by_break()
2126 let test =<< trim [CODE]
2127 func B(jump)
2128 XloopNEXT
2129 let loop = 0
2130 while loop < 2
2131 let loop = loop + 1
2132 if loop == 1
2133 try
2134 if a:jump == "continue"
2135 continue
2136 elseif a:jump == "break"
2137 break
2138 elseif a:jump == "return" || a:jump == "finish"
2139 return
2140 elseif a:jump == "error"
2141 asdf
2142 elseif a:jump == "interrupt"
2143 call interrupt()
2144 let dummy = 0
2145 elseif a:jump == "throw"
2146 throw "abc"
2147 endif
2148 finally
2149 break " discards jump that caused the :finally
2150 call assert_report('should not get here')
2151 endtry
2152 elseif loop == 2
2153 call assert_report('should not get here')
2154 endif
2155 endwhile
2156 Xloop 'a'
2157 endfunc
2158
2159 call B("continue")
2160 Xpath 'b'
2161 call B("break")
2162 Xpath 'c'
2163 call B("return")
2164 Xpath 'd'
2165 let g:jump = "finish"
2166 ExecAsScript B
2167 unlet g:jump
2168 Xpath 'e'
2169 try
2170 call B("error")
2171 Xpath 'f'
2172 finally
2173 Xpath 'g'
2174 try
2175 call B("interrupt")
2176 Xpath 'h'
2177 finally
2178 Xpath 'i'
2179 call B("throw")
2180 Xpath 'j'
2181 endtry
2182 endtry
2183 Xpath 'k'
2184 [CODE]
2185 let verify =<< trim [CODE]
2186 call assert_equal('a2ba3ca4da5ea6fga7hia8jk', g:Xpath)
2187 [CODE]
2188 call RunInNewVim(test, verify)
2189endfunc
2190
2191"-------------------------------------------------------------------------------
2192" Test 36: :finally reason discarded by :return {{{1
2193"
2194" When a :finally clause is executed due to a :continue, :break,
2195" :return, :finish, error, interrupt or :throw, the jump reason is
2196" discarded by a :return in the finally clause.
2197"-------------------------------------------------------------------------------
2198
2199func Test_finally_discard_by_return()
2200 let test =<< trim [CODE]
2201 func R(jump, retval) abort
2202 let loop = 0
2203 while loop < 2
2204 let loop = loop + 1
2205 if loop == 1
2206 try
2207 if a:jump == "continue"
2208 continue
2209 elseif a:jump == "break"
2210 break
2211 elseif a:jump == "return"
2212 return
2213 elseif a:jump == "error"
2214 asdf
2215 elseif a:jump == "interrupt"
2216 call interrupt()
2217 let dummy = 0
2218 elseif a:jump == "throw"
2219 throw "abc"
2220 endif
2221 finally
2222 return a:retval " discards jump that caused the :finally
2223 call assert_report('should not get here')
2224 endtry
2225 elseif loop == 2
2226 call assert_report('should not get here')
2227 endif
2228 endwhile
2229 call assert_report('should not get here')
2230 endfunc
2231
2232 let sum = -R("continue", -8)
2233 Xpath 'a'
2234 let sum = sum - R("break", -16)
2235 Xpath 'b'
2236 let sum = sum - R("return", -32)
2237 Xpath 'c'
2238 try
2239 let sum = sum - R("error", -64)
2240 Xpath 'd'
2241 finally
2242 Xpath 'e'
2243 try
2244 let sum = sum - R("interrupt", -128)
2245 Xpath 'f'
2246 finally
2247 Xpath 'g'
2248 let sum = sum - R("throw", -256)
2249 Xpath 'h'
2250 endtry
2251 endtry
2252 Xpath 'i'
2253
2254 let expected = 8 + 16 + 32 + 64 + 128 + 256
2255 call assert_equal(sum, expected)
2256 [CODE]
2257 let verify =<< trim [CODE]
2258 call assert_equal('abcdefghi', g:Xpath)
2259 [CODE]
2260 call RunInNewVim(test, verify)
2261endfunc
2262
2263"-------------------------------------------------------------------------------
2264" Test 37: :finally reason discarded by :finish {{{1
2265"
2266" When a :finally clause is executed due to a :continue, :break,
2267" :return, :finish, error, interrupt or :throw, the jump reason is
2268" discarded by a :finish in the finally clause.
2269"-------------------------------------------------------------------------------
2270
2271func Test_finally_discard_by_finish()
2272 let test =<< trim [CODE]
2273 func F(jump) " not executed as function, transformed to a script
2274 let loop = 0
2275 while loop < 2
2276 let loop = loop + 1
2277 if loop == 1
2278 try
2279 if a:jump == "continue"
2280 continue
2281 elseif a:jump == "break"
2282 break
2283 elseif a:jump == "finish"
2284 finish
2285 elseif a:jump == "error"
2286 asdf
2287 elseif a:jump == "interrupt"
2288 call interrupt()
2289 let dummy = 0
2290 elseif a:jump == "throw"
2291 throw "abc"
2292 endif
2293 finally
2294 finish " discards jump that caused the :finally
2295 call assert_report('should not get here')
2296 endtry
2297 elseif loop == 2
2298 call assert_report('should not get here')
2299 endif
2300 endwhile
2301 call assert_report('should not get here')
2302 endfunc
2303
2304 let scriptF = MakeScript("F")
2305 delfunction F
2306
2307 let g:jump = "continue"
2308 exec "source" scriptF
2309 Xpath 'a'
2310 let g:jump = "break"
2311 exec "source" scriptF
2312 Xpath 'b'
2313 let g:jump = "finish"
2314 exec "source" scriptF
2315 Xpath 'c'
2316 try
2317 let g:jump = "error"
2318 exec "source" scriptF
2319 Xpath 'd'
2320 finally
2321 Xpath 'e'
2322 try
2323 let g:jump = "interrupt"
2324 exec "source" scriptF
2325 Xpath 'f'
2326 finally
2327 Xpath 'g'
2328 try
2329 let g:jump = "throw"
2330 exec "source" scriptF
2331 Xpath 'h'
2332 finally
2333 Xpath 'i'
2334 endtry
2335 endtry
2336 endtry
2337 unlet g:jump
2338 call delete(scriptF)
2339 [CODE]
2340 let verify =<< trim [CODE]
2341 call assert_equal('abcdefghi', g:Xpath)
2342 [CODE]
2343 call RunInNewVim(test, verify)
2344endfunc
2345
2346"-------------------------------------------------------------------------------
2347" Test 38: :finally reason discarded by an error {{{1
2348"
2349" When a :finally clause is executed due to a :continue, :break,
2350" :return, :finish, error, interrupt or :throw, the jump reason is
2351" discarded by an error in the finally clause.
2352"-------------------------------------------------------------------------------
2353
2354func Test_finally_discard_by_error()
2355 let test =<< trim [CODE]
2356 func E(jump)
2357 let loop = 0
2358 while loop < 2
2359 let loop = loop + 1
2360 if loop == 1
2361 try
2362 if a:jump == "continue"
2363 continue
2364 elseif a:jump == "break"
2365 break
2366 elseif a:jump == "return" || a:jump == "finish"
2367 return
2368 elseif a:jump == "error"
2369 asdf
2370 elseif a:jump == "interrupt"
2371 call interrupt()
2372 let dummy = 0
2373 elseif a:jump == "throw"
2374 throw "abc"
2375 endif
2376 finally
2377 asdf " error; discards jump that caused the :finally
2378 endtry
2379 elseif loop == 2
2380 call assert_report('should not get here')
2381 endif
2382 endwhile
2383 call assert_report('should not get here')
2384 endfunc
2385
2386 try
2387 Xpath 'a'
2388 call E("continue")
2389 call assert_report('should not get here')
2390 finally
2391 try
2392 Xpath 'b'
2393 call E("break")
2394 call assert_report('should not get here')
2395 finally
2396 try
2397 Xpath 'c'
2398 call E("return")
2399 call assert_report('should not get here')
2400 finally
2401 try
2402 Xpath 'd'
2403 let g:jump = "finish"
2404 ExecAsScript E
2405 call assert_report('should not get here')
2406 finally
2407 unlet g:jump
2408 try
2409 Xpath 'e'
2410 call E("error")
2411 call assert_report('should not get here')
2412 finally
2413 try
2414 Xpath 'f'
2415 call E("interrupt")
2416 call assert_report('should not get here')
2417 finally
2418 try
2419 Xpath 'g'
2420 call E("throw")
2421 call assert_report('should not get here')
2422 finally
2423 Xpath 'h'
2424 delfunction E
2425 endtry
2426 endtry
2427 endtry
2428 endtry
2429 endtry
2430 endtry
2431 endtry
2432 call assert_report('should not get here')
2433 [CODE]
2434 let verify =<< trim [CODE]
2435 call assert_equal('abcdefgh', g:Xpath)
2436 [CODE]
2437 call RunInNewVim(test, verify)
2438endfunc
2439
2440"-------------------------------------------------------------------------------
2441" Test 39: :finally reason discarded by an interrupt {{{1
2442"
2443" When a :finally clause is executed due to a :continue, :break,
2444" :return, :finish, error, interrupt or :throw, the jump reason is
2445" discarded by an interrupt in the finally clause.
2446"-------------------------------------------------------------------------------
2447
2448func Test_finally_discarded_by_interrupt()
2449 let test =<< trim [CODE]
2450 func I(jump)
2451 let loop = 0
2452 while loop < 2
2453 let loop = loop + 1
2454 if loop == 1
2455 try
2456 if a:jump == "continue"
2457 continue
2458 elseif a:jump == "break"
2459 break
2460 elseif a:jump == "return" || a:jump == "finish"
2461 return
2462 elseif a:jump == "error"
2463 asdf
2464 elseif a:jump == "interrupt"
2465 call interrupt()
2466 let dummy = 0
2467 elseif a:jump == "throw"
2468 throw "abc"
2469 endif
2470 finally
2471 call interrupt()
2472 let dummy = 0
2473 endtry
2474 elseif loop == 2
2475 call assert_report('should not get here')
2476 endif
2477 endwhile
2478 call assert_report('should not get here')
2479 endfunc
2480
2481 try
2482 try
2483 Xpath 'a'
2484 call I("continue")
2485 call assert_report('should not get here')
2486 finally
2487 try
2488 Xpath 'b'
2489 call I("break")
2490 call assert_report('should not get here')
2491 finally
2492 try
2493 Xpath 'c'
2494 call I("return")
2495 call assert_report('should not get here')
2496 finally
2497 try
2498 Xpath 'd'
2499 let g:jump = "finish"
2500 ExecAsScript I
2501 call assert_report('should not get here')
2502 finally
2503 unlet g:jump
2504 try
2505 Xpath 'e'
2506 call I("error")
2507 call assert_report('should not get here')
2508 finally
2509 try
2510 Xpath 'f'
2511 call I("interrupt")
2512 call assert_report('should not get here')
2513 finally
2514 try
2515 Xpath 'g'
2516 call I("throw")
2517 call assert_report('should not get here')
2518 finally
2519 Xpath 'h'
2520 delfunction I
2521 endtry
2522 endtry
2523 endtry
2524 endtry
2525 endtry
2526 endtry
2527 endtry
2528 call assert_report('should not get here')
2529 catch /^Vim:Interrupt$/
2530 Xpath 'A'
2531 endtry
2532 [CODE]
2533 let verify =<< trim [CODE]
2534 call assert_equal('abcdefghA', g:Xpath)
2535 [CODE]
2536 call RunInNewVim(test, verify)
2537endfunc
2538
2539"-------------------------------------------------------------------------------
2540" Test 40: :finally reason discarded by :throw {{{1
2541"
2542" When a :finally clause is executed due to a :continue, :break,
2543" :return, :finish, error, interrupt or :throw, the jump reason is
2544" discarded by a :throw in the finally clause.
2545"-------------------------------------------------------------------------------
2546
2547func Test_finally_discard_by_throw()
2548 let test =<< trim [CODE]
2549 func T(jump)
2550 let loop = 0
2551 while loop < 2
2552 let loop = loop + 1
2553 if loop == 1
2554 try
2555 if a:jump == "continue"
2556 continue
2557 elseif a:jump == "break"
2558 break
2559 elseif a:jump == "return" || a:jump == "finish"
2560 return
2561 elseif a:jump == "error"
2562 asdf
2563 elseif a:jump == "interrupt"
2564 call interrupt()
2565 let dummy = 0
2566 elseif a:jump == "throw"
2567 throw "abc"
2568 endif
2569 finally
2570 throw "xyz" " discards jump that caused the :finally
2571 endtry
2572 elseif loop == 2
2573 call assert_report('should not get here')
2574 endif
2575 endwhile
2576 call assert_report('should not get here')
2577 endfunc
2578
2579 try
2580 Xpath 'a'
2581 call T("continue")
2582 call assert_report('should not get here')
2583 finally
2584 try
2585 Xpath 'b'
2586 call T("break")
2587 call assert_report('should not get here')
2588 finally
2589 try
2590 Xpath 'c'
2591 call T("return")
2592 call assert_report('should not get here')
2593 finally
2594 try
2595 Xpath 'd'
2596 let g:jump = "finish"
2597 ExecAsScript T
2598 call assert_report('should not get here')
2599 finally
2600 unlet g:jump
2601 try
2602 Xpath 'e'
2603 call T("error")
2604 call assert_report('should not get here')
2605 finally
2606 try
2607 Xpath 'f'
2608 call T("interrupt")
2609 call assert_report('should not get here')
2610 finally
2611 try
2612 Xpath 'g'
2613 call T("throw")
2614 call assert_report('should not get here')
2615 finally
2616 Xpath 'h'
2617 delfunction T
2618 endtry
2619 endtry
2620 endtry
2621 endtry
2622 endtry
2623 endtry
2624 endtry
2625 call assert_report('should not get here')
2626 [CODE]
2627 let verify =<< trim [CODE]
2628 call assert_equal('abcdefgh', g:Xpath)
2629 [CODE]
2630 call RunInNewVim(test, verify)
2631endfunc
2632
2633"-------------------------------------------------------------------------------
2634" Test 49: Throwing exceptions across functions {{{1
2635"
2636" When an exception is thrown but not caught inside a function, the
2637" caller is checked for a matching :catch clause.
2638"-------------------------------------------------------------------------------
2639
2640func T49_C()
2641 try
2642 Xpath 'a'
2643 throw "arrgh"
2644 call assert_report('should not get here')
2645 catch /arrgh/
2646 Xpath 'b'
2647 endtry
2648 Xpath 'c'
2649endfunc
2650
2651func T49_T1()
2652 XloopNEXT
2653 try
2654 Xloop 'd'
2655 throw "arrgh"
2656 call assert_report('should not get here')
2657 finally
2658 Xloop 'e'
2659 endtry
2660 Xloop 'f'
2661endfunc
2662
2663func T49_T2()
2664 try
2665 Xpath 'g'
2666 call T49_T1()
2667 call assert_report('should not get here')
2668 finally
2669 Xpath 'h'
2670 endtry
2671 call assert_report('should not get here')
2672endfunc
2673
2674func Test_throw_exception_across_funcs()
2675 XpathINIT
2676 XloopINIT
2677 try
2678 Xpath 'i'
2679 call T49_C() " throw and catch
2680 Xpath 'j'
2681 catch /.*/
2682 call assert_report('should not get here')
2683 endtry
2684
2685 try
2686 Xpath 'k'
2687 call T49_T1() " throw, one level
2688 call assert_report('should not get here')
2689 catch /arrgh/
2690 Xpath 'l'
2691 catch /.*/
2692 call assert_report('should not get here')
2693 endtry
2694
2695 try
2696 Xpath 'm'
2697 call T49_T2() " throw, two levels
2698 call assert_report('should not get here')
2699 catch /arrgh/
2700 Xpath 'n'
2701 catch /.*/
2702 call assert_report('should not get here')
2703 endtry
2704 Xpath 'o'
2705
2706 call assert_equal('iabcjkd2e2lmgd3e3hno', g:Xpath)
2707endfunc
2708
2709"-------------------------------------------------------------------------------
2710" Test 50: Throwing exceptions across script files {{{1
2711"
2712" When an exception is thrown but not caught inside a script file,
2713" the sourcing script or function is checked for a matching :catch
2714" clause.
2715"
2716" This test executes the bodies of the functions C, T1, and T2 from
2717" the previous test as script files (:return replaced by :finish).
2718"-------------------------------------------------------------------------------
2719
2720func T50_F()
2721 try
2722 Xpath 'A'
2723 exec "source" g:scriptC
2724 Xpath 'B'
2725 catch /.*/
2726 call assert_report('should not get here')
2727 endtry
2728
2729 try
2730 Xpath 'C'
2731 exec "source" g:scriptT1
2732 call assert_report('should not get here')
2733 catch /arrgh/
2734 Xpath 'D'
2735 catch /.*/
2736 call assert_report('should not get here')
2737 endtry
2738endfunc
2739
2740func Test_throw_across_script()
2741 XpathINIT
2742 XloopINIT
2743 let g:scriptC = MakeScript("T49_C")
2744 let g:scriptT1 = MakeScript("T49_T1")
2745 let scriptT2 = MakeScript("T49_T2", g:scriptT1)
2746
2747 try
2748 Xpath 'E'
2749 call T50_F()
2750 Xpath 'F'
2751 exec "source" scriptT2
2752 call assert_report('should not get here')
2753 catch /arrgh/
2754 Xpath 'G'
2755 catch /.*/
2756 call assert_report('should not get here')
2757 endtry
2758 Xpath 'H'
2759 call assert_equal('EAabcBCd2e2DFgd3e3hGH', g:Xpath)
2760
2761 call delete(g:scriptC)
2762 call delete(g:scriptT1)
2763 call delete(scriptT2)
2764 unlet g:scriptC g:scriptT1 scriptT2
2765endfunc
2766
Bram Moolenaar1f068232019-11-03 16:17:26 +01002767"-------------------------------------------------------------------------------
Bram Moolenaar9470a4d2020-08-07 16:49:11 +02002768" Test 52: Uncaught exceptions {{{1
2769"
2770" When an exception is thrown but not caught, an error message is
2771" displayed when the script is terminated. In case of an interrupt
2772" or error exception, the normal interrupt or error message(s) are
2773" displayed.
2774"-------------------------------------------------------------------------------
2775
2776func Test_uncaught_exception_1()
2777 CheckEnglish
2778
2779 let test =<< trim [CODE]
2780 Xpath 'a'
2781 throw "arrgh"
2782 call assert_report('should not get here')`
2783 [CODE]
2784 let verify =<< trim [CODE]
2785 call assert_equal('E605: Exception not caught: arrgh', v:errmsg)
2786 call assert_equal('a', g:Xpath)
2787 [CODE]
2788 call RunInNewVim(test, verify)
2789endfunc
2790
2791func Test_uncaught_exception_2()
2792 CheckEnglish
2793
2794 let test =<< trim [CODE]
2795 try
2796 Xpath 'a'
2797 throw "oops"
2798 call assert_report('should not get here')`
2799 catch /arrgh/
2800 call assert_report('should not get here')`
2801 endtry
2802 call assert_report('should not get here')`
2803 [CODE]
2804 let verify =<< trim [CODE]
2805 call assert_equal('E605: Exception not caught: oops', v:errmsg)
2806 call assert_equal('a', g:Xpath)
2807 [CODE]
2808 call RunInNewVim(test, verify)
2809endfunc
2810
2811func Test_uncaught_exception_3()
2812 CheckEnglish
2813
2814 let test =<< trim [CODE]
2815 func T()
2816 Xpath 'c'
2817 throw "brrr"
2818 call assert_report('should not get here')`
2819 endfunc
2820
2821 try
2822 Xpath 'a'
2823 throw "arrgh"
2824 call assert_report('should not get here')`
2825 catch /.*/
2826 Xpath 'b'
2827 call T()
2828 call assert_report('should not get here')`
2829 endtry
2830 call assert_report('should not get here')`
2831 [CODE]
2832 let verify =<< trim [CODE]
2833 call assert_equal('E605: Exception not caught: brrr', v:errmsg)
2834 call assert_equal('abc', g:Xpath)
2835 [CODE]
2836 call RunInNewVim(test, verify)
2837endfunc
2838
2839func Test_uncaught_exception_4()
2840 CheckEnglish
2841
2842 let test =<< trim [CODE]
2843 try
2844 Xpath 'a'
2845 throw "arrgh"
2846 call assert_report('should not get here')`
2847 finally
2848 Xpath 'b'
2849 throw "brrr"
2850 call assert_report('should not get here')`
2851 endtry
2852 call assert_report('should not get here')`
2853 [CODE]
2854 let verify =<< trim [CODE]
2855 call assert_equal('E605: Exception not caught: brrr', v:errmsg)
2856 call assert_equal('ab', g:Xpath)
2857 [CODE]
2858 call RunInNewVim(test, verify)
2859endfunc
2860
2861func Test_uncaught_exception_5()
2862 CheckEnglish
2863
2864 " Need to catch and handle interrupt, otherwise the test will wait for the
2865 " user to press <Enter> to continue
2866 let test =<< trim [CODE]
2867 try
2868 try
2869 Xpath 'a'
2870 call interrupt()
2871 call assert_report('should not get here')
2872 endtry
2873 call assert_report('should not get here')
2874 catch /^Vim:Interrupt$/
2875 Xpath 'b'
2876 endtry
2877 [CODE]
2878 let verify =<< trim [CODE]
2879 call assert_equal('ab', g:Xpath)
2880 [CODE]
2881 call RunInNewVim(test, verify)
2882endfunc
2883
2884func Test_uncaught_exception_6()
2885 CheckEnglish
2886
2887 let test =<< trim [CODE]
2888 try
2889 Xpath 'a'
2890 let x = novar " error E121; exception: E121
2891 catch /E15:/ " should not catch
2892 call assert_report('should not get here')
2893 endtry
2894 call assert_report('should not get here')
2895 [CODE]
2896 let verify =<< trim [CODE]
2897 call assert_equal('a', g:Xpath)
2898 call assert_equal('E121: Undefined variable: novar', v:errmsg)
2899 [CODE]
2900 call RunInNewVim(test, verify)
2901endfunc
2902
2903func Test_uncaught_exception_7()
2904 CheckEnglish
2905
2906 let test =<< trim [CODE]
2907 try
2908 Xpath 'a'
2909 " error E108/E488; exception: E488
2910 unlet novar #
2911 catch /E108:/ " should not catch
2912 call assert_report('should not get here')
2913 endtry
2914 call assert_report('should not get here')
2915 [CODE]
2916 let verify =<< trim [CODE]
2917 call assert_equal('a', g:Xpath)
2918 call assert_equal('E488: Trailing characters: #', v:errmsg)
2919 [CODE]
2920 call RunInNewVim(test, verify)
2921endfunc
2922
2923"-------------------------------------------------------------------------------
2924" Test 53: Nesting errors: :endif/:else/:elseif {{{1
2925"
2926" For nesting errors of :if conditionals the correct error messages
2927" should be given.
2928"-------------------------------------------------------------------------------
2929
2930func Test_nested_if_else_errors()
2931 CheckEnglish
2932
2933 " :endif without :if
2934 let code =<< trim END
2935 endif
2936 END
2937 call writefile(code, 'Xtest')
2938 call AssertException(['source Xtest'], 'Vim(endif):E580: :endif without :if')
2939
2940 " :endif without :if
2941 let code =<< trim END
2942 while 1
2943 endif
2944 endwhile
2945 END
2946 call writefile(code, 'Xtest')
2947 call AssertException(['source Xtest'], 'Vim(endif):E580: :endif without :if')
2948
2949 " :endif without :if
2950 let code =<< trim END
2951 try
2952 finally
2953 endif
2954 endtry
2955 END
2956 call writefile(code, 'Xtest')
2957 call AssertException(['source Xtest'], 'Vim(endif):E580: :endif without :if')
2958
2959 " :endif without :if
2960 let code =<< trim END
2961 try
2962 endif
2963 endtry
2964 END
2965 call writefile(code, 'Xtest')
2966 call AssertException(['source Xtest'], 'Vim(endif):E580: :endif without :if')
2967
2968 " :endif without :if
2969 let code =<< trim END
2970 try
2971 throw "a"
2972 catch /a/
2973 endif
2974 endtry
2975 END
2976 call writefile(code, 'Xtest')
2977 call AssertException(['source Xtest'], 'Vim(endif):E580: :endif without :if')
2978
2979 " :else without :if
2980 let code =<< trim END
2981 else
2982 END
2983 call writefile(code, 'Xtest')
2984 call AssertException(['source Xtest'], 'Vim(else):E581: :else without :if')
2985
2986 " :else without :if
2987 let code =<< trim END
2988 while 1
2989 else
2990 endwhile
2991 END
2992 call writefile(code, 'Xtest')
2993 call AssertException(['source Xtest'], 'Vim(else):E581: :else without :if')
2994
2995 " :else without :if
2996 let code =<< trim END
2997 try
2998 finally
2999 else
3000 endtry
3001 END
3002 call writefile(code, 'Xtest')
3003 call AssertException(['source Xtest'], 'Vim(else):E581: :else without :if')
3004
3005 " :else without :if
3006 let code =<< trim END
3007 try
3008 else
3009 endtry
3010 END
3011 call writefile(code, 'Xtest')
3012 call AssertException(['source Xtest'], 'Vim(else):E581: :else without :if')
3013
3014 " :else without :if
3015 let code =<< trim END
3016 try
3017 throw "a"
3018 catch /a/
3019 else
3020 endtry
3021 END
3022 call writefile(code, 'Xtest')
3023 call AssertException(['source Xtest'], 'Vim(else):E581: :else without :if')
3024
3025 " :elseif without :if
3026 let code =<< trim END
3027 elseif
3028 END
3029 call writefile(code, 'Xtest')
3030 call AssertException(['source Xtest'], 'Vim(elseif):E582: :elseif without :if')
3031
3032 " :elseif without :if
3033 let code =<< trim END
3034 while 1
3035 elseif
3036 endwhile
3037 END
3038 call writefile(code, 'Xtest')
3039 call AssertException(['source Xtest'], 'Vim(elseif):E582: :elseif without :if')
3040
3041 " :elseif without :if
3042 let code =<< trim END
3043 try
3044 finally
3045 elseif
3046 endtry
3047 END
3048 call writefile(code, 'Xtest')
3049 call AssertException(['source Xtest'], 'Vim(elseif):E582: :elseif without :if')
3050
3051 " :elseif without :if
3052 let code =<< trim END
3053 try
3054 elseif
3055 endtry
3056 END
3057 call writefile(code, 'Xtest')
3058 call AssertException(['source Xtest'], 'Vim(elseif):E582: :elseif without :if')
3059
3060 " :elseif without :if
3061 let code =<< trim END
3062 try
3063 throw "a"
3064 catch /a/
3065 elseif
3066 endtry
3067 END
3068 call writefile(code, 'Xtest')
3069 call AssertException(['source Xtest'], 'Vim(elseif):E582: :elseif without :if')
3070
3071 " multiple :else
3072 let code =<< trim END
3073 if 1
3074 else
3075 else
3076 endif
3077 END
3078 call writefile(code, 'Xtest')
3079 call AssertException(['source Xtest'], 'Vim(else):E583: multiple :else')
3080
3081 " :elseif after :else
3082 let code =<< trim END
3083 if 1
3084 else
3085 elseif 1
3086 endif
3087 END
3088 call writefile(code, 'Xtest')
3089 call AssertException(['source Xtest'], 'Vim(elseif):E584: :elseif after :else')
3090
3091 call delete('Xtest')
3092endfunc
3093
3094"-------------------------------------------------------------------------------
3095" Test 54: Nesting errors: :while/:endwhile {{{1
3096"
3097" For nesting errors of :while conditionals the correct error messages
3098" should be given.
3099"
3100" This test reuses the function MESSAGES() from the previous test.
3101" This functions checks the messages in g:msgfile.
3102"-------------------------------------------------------------------------------
3103
3104func Test_nested_while_error()
3105 CheckEnglish
3106
3107 " :endwhile without :while
3108 let code =<< trim END
3109 endwhile
3110 END
3111 call writefile(code, 'Xtest')
3112 call AssertException(['source Xtest'], 'Vim(endwhile):E588: :endwhile without :while')
3113
3114 " :endwhile without :while
3115 let code =<< trim END
3116 if 1
3117 endwhile
3118 endif
3119 END
3120 call writefile(code, 'Xtest')
3121 call AssertException(['source Xtest'], 'Vim(endwhile):E588: :endwhile without :while')
3122
3123 " Missing :endif
3124 let code =<< trim END
3125 while 1
3126 if 1
3127 endwhile
3128 END
3129 call writefile(code, 'Xtest')
3130 call AssertException(['source Xtest'], 'Vim(endwhile):E171: Missing :endif')
3131
3132 " :endwhile without :while
3133 let code =<< trim END
3134 try
3135 finally
3136 endwhile
3137 endtry
3138 END
3139 call writefile(code, 'Xtest')
3140 call AssertException(['source Xtest'], 'Vim(endwhile):E588: :endwhile without :while')
3141
3142 " Missing :endtry
3143 let code =<< trim END
3144 while 1
3145 try
3146 finally
3147 endwhile
3148 END
3149 call writefile(code, 'Xtest')
3150 call AssertException(['source Xtest'], 'Vim(endwhile):E600: Missing :endtry')
3151
3152 " Missing :endtry
3153 let code =<< trim END
3154 while 1
3155 if 1
3156 try
3157 finally
3158 endwhile
3159 END
3160 call writefile(code, 'Xtest')
3161 call AssertException(['source Xtest'], 'Vim(endwhile):E600: Missing :endtry')
3162
3163 " Missing :endif
3164 let code =<< trim END
3165 while 1
3166 try
3167 finally
3168 if 1
3169 endwhile
3170 END
3171 call writefile(code, 'Xtest')
3172 call AssertException(['source Xtest'], 'Vim(endwhile):E171: Missing :endif')
3173
3174 " :endwhile without :while
3175 let code =<< trim END
3176 try
3177 endwhile
3178 endtry
3179 END
3180 call writefile(code, 'Xtest')
3181 call AssertException(['source Xtest'], 'Vim(endwhile):E588: :endwhile without :while')
3182
3183 " :endwhile without :while
3184 let code =<< trim END
3185 while 1
3186 try
3187 endwhile
3188 endtry
3189 endwhile
3190 END
3191 call writefile(code, 'Xtest')
3192 call AssertException(['source Xtest'], 'Vim(endwhile):E588: :endwhile without :while')
3193
3194 " :endwhile without :while
3195 let code =<< trim END
3196 try
3197 throw "a"
3198 catch /a/
3199 endwhile
3200 endtry
3201 END
3202 call writefile(code, 'Xtest')
3203 call AssertException(['source Xtest'], 'Vim(endwhile):E588: :endwhile without :while')
3204
3205 " :endwhile without :while
3206 let code =<< trim END
3207 while 1
3208 try
3209 throw "a"
3210 catch /a/
3211 endwhile
3212 endtry
3213 endwhile
3214 END
3215 call writefile(code, 'Xtest')
3216 call AssertException(['source Xtest'], 'Vim(endwhile):E588: :endwhile without :while')
3217
3218 call delete('Xtest')
3219endfunc
3220
3221"-------------------------------------------------------------------------------
3222" Test 55: Nesting errors: :continue/:break {{{1
3223"
3224" For nesting errors of :continue and :break commands the correct
3225" error messages should be given.
3226"
3227" This test reuses the function MESSAGES() from the previous test.
3228" This functions checks the messages in g:msgfile.
3229"-------------------------------------------------------------------------------
3230
3231func Test_nested_cont_break_error()
3232 CheckEnglish
3233
3234 " :continue without :while
3235 let code =<< trim END
3236 continue
3237 END
3238 call writefile(code, 'Xtest')
3239 call AssertException(['source Xtest'], 'Vim(continue):E586: :continue without :while or :for')
3240
3241 " :continue without :while
3242 let code =<< trim END
3243 if 1
3244 continue
3245 endif
3246 END
3247 call writefile(code, 'Xtest')
3248 call AssertException(['source Xtest'], 'Vim(continue):E586: :continue without :while or :for')
3249
3250 " :continue without :while
3251 let code =<< trim END
3252 try
3253 finally
3254 continue
3255 endtry
3256 END
3257 call writefile(code, 'Xtest')
3258 call AssertException(['source Xtest'], 'Vim(continue):E586: :continue without :while or :for')
3259
3260 " :continue without :while
3261 let code =<< trim END
3262 try
3263 continue
3264 endtry
3265 END
3266 call writefile(code, 'Xtest')
3267 call AssertException(['source Xtest'], 'Vim(continue):E586: :continue without :while or :for')
3268
3269 " :continue without :while
3270 let code =<< trim END
3271 try
3272 throw "a"
3273 catch /a/
3274 continue
3275 endtry
3276 END
3277 call writefile(code, 'Xtest')
3278 call AssertException(['source Xtest'], 'Vim(continue):E586: :continue without :while or :for')
3279
3280 " :break without :while
3281 let code =<< trim END
3282 break
3283 END
3284 call writefile(code, 'Xtest')
3285 call AssertException(['source Xtest'], 'Vim(break):E587: :break without :while or :for')
3286
3287 " :break without :while
3288 let code =<< trim END
3289 if 1
3290 break
3291 endif
3292 END
3293 call writefile(code, 'Xtest')
3294 call AssertException(['source Xtest'], 'Vim(break):E587: :break without :while or :for')
3295
3296 " :break without :while
3297 let code =<< trim END
3298 try
3299 finally
3300 break
3301 endtry
3302 END
3303 call writefile(code, 'Xtest')
3304 call AssertException(['source Xtest'], 'Vim(break):E587: :break without :while or :for')
3305
3306 " :break without :while
3307 let code =<< trim END
3308 try
3309 break
3310 endtry
3311 END
3312 call writefile(code, 'Xtest')
3313 call AssertException(['source Xtest'], 'Vim(break):E587: :break without :while or :for')
3314
3315 " :break without :while
3316 let code =<< trim END
3317 try
3318 throw "a"
3319 catch /a/
3320 break
3321 endtry
3322 END
3323 call writefile(code, 'Xtest')
3324 call AssertException(['source Xtest'], 'Vim(break):E587: :break without :while or :for')
3325
3326 call delete('Xtest')
3327endfunc
3328
3329"-------------------------------------------------------------------------------
3330" Test 56: Nesting errors: :endtry {{{1
3331"
3332" For nesting errors of :try conditionals the correct error messages
3333" should be given.
3334"
3335" This test reuses the function MESSAGES() from the previous test.
3336" This functions checks the messages in g:msgfile.
3337"-------------------------------------------------------------------------------
3338
3339func Test_nested_endtry_error()
3340 CheckEnglish
3341
3342 " :endtry without :try
3343 let code =<< trim END
3344 endtry
3345 END
3346 call writefile(code, 'Xtest')
3347 call AssertException(['source Xtest'], 'Vim(endtry):E602: :endtry without :try')
3348
3349 " :endtry without :try
3350 let code =<< trim END
3351 if 1
3352 endtry
3353 endif
3354 END
3355 call writefile(code, 'Xtest')
3356 call AssertException(['source Xtest'], 'Vim(endtry):E602: :endtry without :try')
3357
3358 " :endtry without :try
3359 let code =<< trim END
3360 while 1
3361 endtry
3362 endwhile
3363 END
3364 call writefile(code, 'Xtest')
3365 call AssertException(['source Xtest'], 'Vim(endtry):E602: :endtry without :try')
3366
3367 " Missing :endif
3368 let code =<< trim END
3369 try
3370 if 1
3371 endtry
3372 END
3373 call writefile(code, 'Xtest')
3374 call AssertException(['source Xtest'], 'Vim(endtry):E171: Missing :endif')
3375
3376 " Missing :endwhile
3377 let code =<< trim END
3378 try
3379 while 1
3380 endtry
3381 END
3382 call writefile(code, 'Xtest')
3383 call AssertException(['source Xtest'], 'Vim(endtry):E170: Missing :endwhile')
3384
3385 " Missing :endif
3386 let code =<< trim END
3387 try
3388 finally
3389 if 1
3390 endtry
3391 END
3392 call writefile(code, 'Xtest')
3393 call AssertException(['source Xtest'], 'Vim(endtry):E171: Missing :endif')
3394
3395 " Missing :endwhile
3396 let code =<< trim END
3397 try
3398 finally
3399 while 1
3400 endtry
3401 END
3402 call writefile(code, 'Xtest')
3403 call AssertException(['source Xtest'], 'Vim(endtry):E170: Missing :endwhile')
3404
3405 " Missing :endif
3406 let code =<< trim END
3407 try
3408 throw "a"
3409 catch /a/
3410 if 1
3411 endtry
3412 END
3413 call writefile(code, 'Xtest')
3414 call AssertException(['source Xtest'], 'Vim(endtry):E171: Missing :endif')
3415
3416 " Missing :endwhile
3417 let code =<< trim END
3418 try
3419 throw "a"
3420 catch /a/
3421 while 1
3422 endtry
3423 END
3424 call writefile(code, 'Xtest')
3425 call AssertException(['source Xtest'], 'Vim(endtry):E170: Missing :endwhile')
3426
3427 call delete('Xtest')
3428endfunc
3429
3430"-------------------------------------------------------------------------------
3431" Test 57: v:exception and v:throwpoint for user exceptions {{{1
3432"
3433" v:exception evaluates to the value of the exception that was caught
3434" most recently and is not finished. (A caught exception is finished
3435" when the next ":catch", ":finally", or ":endtry" is reached.)
3436" v:throwpoint evaluates to the script/function name and line number
3437" where that exception has been thrown.
3438"-------------------------------------------------------------------------------
3439
3440func Test_user_exception_info()
3441 CheckEnglish
3442
3443 XpathINIT
3444 XloopINIT
3445
3446 func FuncException()
3447 let g:exception = v:exception
3448 endfunc
3449
3450 func FuncThrowpoint()
3451 let g:throwpoint = v:throwpoint
3452 endfunc
3453
3454 let scriptException = MakeScript("FuncException")
3455 let scriptThrowPoint = MakeScript("FuncThrowpoint")
3456
3457 command! CmdException let g:exception = v:exception
3458 command! CmdThrowpoint let g:throwpoint = v:throwpoint
3459
3460 func T(arg, line)
3461 if a:line == 2
3462 throw a:arg " in line 2
3463 elseif a:line == 4
3464 throw a:arg " in line 4
3465 elseif a:line == 6
3466 throw a:arg " in line 6
3467 elseif a:line == 8
3468 throw a:arg " in line 8
3469 endif
3470 endfunc
3471
3472 func G(arg, line)
3473 call T(a:arg, a:line)
3474 endfunc
3475
3476 func F(arg, line)
3477 call G(a:arg, a:line)
3478 endfunc
3479
3480 let scriptT = MakeScript("T")
3481 let scriptG = MakeScript("G", scriptT)
3482 let scriptF = MakeScript("F", scriptG)
3483
3484 try
3485 Xpath 'a'
3486 call F("oops", 2)
3487 catch /.*/
3488 Xpath 'b'
3489 let exception = v:exception
3490 let throwpoint = v:throwpoint
3491 call assert_equal("oops", v:exception)
3492 call assert_match('\<F\[1]\.\.G\[1]\.\.T\>', v:throwpoint)
3493 call assert_match('\<2\>', v:throwpoint)
3494
3495 exec "let exception = v:exception"
3496 exec "let throwpoint = v:throwpoint"
3497 call assert_equal("oops", v:exception)
3498 call assert_match('\<F\[1]\.\.G\[1]\.\.T\>', v:throwpoint)
3499 call assert_match('\<2\>', v:throwpoint)
3500
3501 CmdException
3502 CmdThrowpoint
3503 call assert_equal("oops", v:exception)
3504 call assert_match('\<F\[1]\.\.G\[1]\.\.T\>', v:throwpoint)
3505 call assert_match('\<2\>', v:throwpoint)
3506
3507 call FuncException()
3508 call FuncThrowpoint()
3509 call assert_equal("oops", v:exception)
3510 call assert_match('\<F\[1]\.\.G\[1]\.\.T\>', v:throwpoint)
3511 call assert_match('\<2\>', v:throwpoint)
3512
3513 exec "source" scriptException
3514 exec "source" scriptThrowPoint
3515 call assert_equal("oops", v:exception)
3516 call assert_match('\<F\[1]\.\.G\[1]\.\.T\>', v:throwpoint)
3517 call assert_match('\<2\>', v:throwpoint)
3518
3519 try
3520 Xpath 'c'
3521 call G("arrgh", 4)
3522 catch /.*/
3523 Xpath 'd'
3524 let exception = v:exception
3525 let throwpoint = v:throwpoint
3526 call assert_equal("arrgh", v:exception)
3527 call assert_match('\<G\[1]\.\.T\>', v:throwpoint)
3528 call assert_match('\<4\>', v:throwpoint)
3529
3530 try
3531 Xpath 'e'
3532 let g:arg = "autsch"
3533 let g:line = 6
3534 exec "source" scriptF
3535 catch /.*/
3536 Xpath 'f'
3537 let exception = v:exception
3538 let throwpoint = v:throwpoint
3539 call assert_equal("autsch", v:exception)
3540 call assert_match(fnamemodify(scriptT, ':t'), v:throwpoint)
3541 call assert_match('\<6\>', v:throwpoint)
3542 finally
3543 Xpath 'g'
3544 let exception = v:exception
3545 let throwpoint = v:throwpoint
3546 call assert_equal("arrgh", v:exception)
3547 call assert_match('\<G\[1]\.\.T\>', v:throwpoint)
3548 call assert_match('\<4\>', v:throwpoint)
3549 try
3550 Xpath 'h'
3551 let g:arg = "brrrr"
3552 let g:line = 8
3553 exec "source" scriptG
3554 catch /.*/
3555 Xpath 'i'
3556 let exception = v:exception
3557 let throwpoint = v:throwpoint
3558 " Resolve scriptT for matching it against v:throwpoint.
3559 call assert_equal("brrrr", v:exception)
3560 call assert_match(fnamemodify(scriptT, ':t'), v:throwpoint)
3561 call assert_match('\<8\>', v:throwpoint)
3562 finally
3563 Xpath 'j'
3564 let exception = v:exception
3565 let throwpoint = v:throwpoint
3566 call assert_equal("arrgh", v:exception)
3567 call assert_match('\<G\[1]\.\.T\>', v:throwpoint)
3568 call assert_match('\<4\>', v:throwpoint)
3569 endtry
3570 Xpath 'k'
3571 let exception = v:exception
3572 let throwpoint = v:throwpoint
3573 call assert_equal("arrgh", v:exception)
3574 call assert_match('\<G\[1]\.\.T\>', v:throwpoint)
3575 call assert_match('\<4\>', v:throwpoint)
3576 endtry
3577 Xpath 'l'
3578 let exception = v:exception
3579 let throwpoint = v:throwpoint
3580 call assert_equal("arrgh", v:exception)
3581 call assert_match('\<G\[1]\.\.T\>', v:throwpoint)
3582 call assert_match('\<4\>', v:throwpoint)
3583 finally
3584 Xpath 'm'
3585 let exception = v:exception
3586 let throwpoint = v:throwpoint
3587 call assert_equal("oops", v:exception)
3588 call assert_match('\<F\[1]\.\.G\[1]\.\.T\>', v:throwpoint)
3589 call assert_match('\<2\>', v:throwpoint)
3590 endtry
3591 Xpath 'n'
3592 let exception = v:exception
3593 let throwpoint = v:throwpoint
3594 call assert_equal("oops", v:exception)
3595 call assert_match('\<F\[1]\.\.G\[1]\.\.T\>', v:throwpoint)
3596 call assert_match('\<2\>', v:throwpoint)
3597 finally
3598 Xpath 'o'
3599 let exception = v:exception
3600 let throwpoint = v:throwpoint
3601 call assert_equal("", v:exception)
3602 call assert_match('^$', v:throwpoint)
3603 call assert_match('^$', v:throwpoint)
3604 endtry
3605
3606 call assert_equal('abcdefghijklmno', g:Xpath)
3607
3608 unlet exception throwpoint
3609 delfunction FuncException
3610 delfunction FuncThrowpoint
3611 call delete(scriptException)
3612 call delete(scriptThrowPoint)
3613 unlet scriptException scriptThrowPoint
3614 delcommand CmdException
3615 delcommand CmdThrowpoint
3616 delfunction T
3617 delfunction G
3618 delfunction F
3619 call delete(scriptT)
3620 call delete(scriptG)
3621 call delete(scriptF)
3622 unlet scriptT scriptG scriptF
3623endfunc
3624
3625"-------------------------------------------------------------------------------
3626"
3627" Test 58: v:exception and v:throwpoint for error/interrupt exceptions {{{1
3628"
3629" v:exception and v:throwpoint work also for error and interrupt
3630" exceptions.
3631"-------------------------------------------------------------------------------
3632
3633func Test_execption_info_for_error()
3634 CheckEnglish
3635
3636 let test =<< trim [CODE]
3637 func T(line)
3638 if a:line == 2
3639 delfunction T " error (function in use) in line 2
3640 elseif a:line == 4
3641 call interrupt()
3642 endif
3643 endfunc
3644
3645 while 1
3646 try
3647 Xpath 'a'
3648 call T(2)
3649 call assert_report('should not get here')
3650 catch /.*/
3651 Xpath 'b'
3652 if v:exception !~ 'Vim(delfunction):'
3653 call assert_report('should not get here')
3654 endif
3655 if v:throwpoint !~ '\<T\>'
3656 call assert_report('should not get here')
3657 endif
3658 if v:throwpoint !~ '\<2\>'
3659 call assert_report('should not get here')
3660 endif
3661 finally
3662 Xpath 'c'
3663 if v:exception != ""
3664 call assert_report('should not get here')
3665 endif
3666 if v:throwpoint != ""
3667 call assert_report('should not get here')
3668 endif
3669 break
3670 endtry
3671 endwhile
3672
3673 Xpath 'd'
3674 if v:exception != ""
3675 call assert_report('should not get here')
3676 endif
3677 if v:throwpoint != ""
3678 call assert_report('should not get here')
3679 endif
3680
3681 while 1
3682 try
3683 Xpath 'e'
3684 call T(4)
3685 call assert_report('should not get here')
3686 catch /.*/
3687 Xpath 'f'
3688 if v:exception != 'Vim:Interrupt'
3689 call assert_report('should not get here')
3690 endif
3691 if v:throwpoint !~ 'function T'
3692 call assert_report('should not get here')
3693 endif
3694 if v:throwpoint !~ '\<4\>'
3695 call assert_report('should not get here')
3696 endif
3697 finally
3698 Xpath 'g'
3699 if v:exception != ""
3700 call assert_report('should not get here')
3701 endif
3702 if v:throwpoint != ""
3703 call assert_report('should not get here')
3704 endif
3705 break
3706 endtry
3707 endwhile
3708
3709 Xpath 'h'
3710 if v:exception != ""
3711 call assert_report('should not get here')
3712 endif
3713 if v:throwpoint != ""
3714 call assert_report('should not get here')
3715 endif
3716 [CODE]
3717 let verify =<< trim [CODE]
3718 call assert_equal('abcdefgh', g:Xpath)
3719 [CODE]
3720 call RunInNewVim(test, verify)
3721endfunc
3722
3723"-------------------------------------------------------------------------------
Bram Moolenaarefb64822020-08-10 22:15:30 +02003724"
3725" Test 59: v:exception and v:throwpoint when discarding exceptions {{{1
3726"
3727" When a :catch clause is left by a ":break" etc or an error or
3728" interrupt exception, v:exception and v:throwpoint are reset. They
3729" are not affected by an exception that is discarded before being
3730" caught.
3731"-------------------------------------------------------------------------------
3732func Test_exception_info_on_discard()
3733 CheckEnglish
3734
3735 let test =<< trim [CODE]
3736 let sfile = expand("<sfile>")
3737
3738 while 1
3739 try
3740 throw "x1"
3741 catch /.*/
3742 break
3743 endtry
3744 endwhile
3745 call assert_equal('', v:exception)
3746 call assert_equal('', v:throwpoint)
3747
3748 while 1
3749 try
3750 throw "x2"
3751 catch /.*/
3752 break
3753 finally
3754 call assert_equal('', v:exception)
3755 call assert_equal('', v:throwpoint)
3756 endtry
3757 break
3758 endwhile
3759 call assert_equal('', v:exception)
3760 call assert_equal('', v:throwpoint)
3761
3762 while 1
3763 try
3764 let errcaught = 0
3765 try
3766 try
3767 throw "x3"
3768 catch /.*/
3769 let lnum = expand("<sflnum>")
3770 asdf
3771 endtry
3772 catch /.*/
3773 let errcaught = 1
3774 call assert_match('Vim:E492: Not an editor command:', v:exception)
3775 call assert_match('line ' .. (lnum + 1), v:throwpoint)
3776 endtry
3777 finally
3778 call assert_equal(1, errcaught)
3779 break
3780 endtry
3781 endwhile
3782 call assert_equal('', v:exception)
3783 call assert_equal('', v:throwpoint)
3784
3785 Xpath 'a'
3786
3787 while 1
3788 try
3789 let intcaught = 0
3790 try
3791 try
3792 throw "x4"
3793 catch /.*/
3794 let lnum = expand("<sflnum>")
3795 call interrupt()
3796 endtry
3797 catch /.*/
3798 let intcaught = 1
3799 call assert_match('Vim:Interrupt', v:exception)
3800 call assert_match('line ' .. (lnum + 1), v:throwpoint)
3801 endtry
3802 finally
3803 call assert_equal(1, intcaught)
3804 break
3805 endtry
3806 endwhile
3807 call assert_equal('', v:exception)
3808 call assert_equal('', v:throwpoint)
3809
3810 Xpath 'b'
3811
3812 while 1
3813 try
3814 let errcaught = 0
3815 try
3816 try
3817 if 1
3818 let lnum = expand("<sflnum>")
3819 throw "x5"
3820 " missing endif
3821 catch /.*/
3822 call assert_report('should not get here')
3823 endtry
3824 catch /.*/
3825 let errcaught = 1
3826 call assert_match('Vim(catch):E171: Missing :endif:', v:exception)
3827 call assert_match('line ' .. (lnum + 3), v:throwpoint)
3828 endtry
3829 finally
3830 call assert_equal(1, errcaught)
3831 break
3832 endtry
3833 endwhile
3834 call assert_equal('', v:exception)
3835 call assert_equal('', v:throwpoint)
3836
3837 Xpath 'c'
3838
3839 try
3840 while 1
3841 try
3842 throw "x6"
3843 finally
3844 break
3845 endtry
3846 break
3847 endwhile
3848 catch /.*/
3849 call assert_report('should not get here')
3850 endtry
3851 call assert_equal('', v:exception)
3852 call assert_equal('', v:throwpoint)
3853
3854 try
3855 while 1
3856 try
3857 throw "x7"
3858 finally
3859 break
3860 endtry
3861 break
3862 endwhile
3863 catch /.*/
3864 call assert_report('should not get here')
3865 finally
3866 call assert_equal('', v:exception)
3867 call assert_equal('', v:throwpoint)
3868 endtry
3869 call assert_equal('', v:exception)
3870 call assert_equal('', v:throwpoint)
3871
3872 while 1
3873 try
3874 let errcaught = 0
3875 try
3876 try
3877 throw "x8"
3878 finally
3879 let lnum = expand("<sflnum>")
3880 asdf
3881 endtry
3882 catch /.*/
3883 let errcaught = 1
3884 call assert_match('Vim:E492: Not an editor command:', v:exception)
3885 call assert_match('line ' .. (lnum + 1), v:throwpoint)
3886 endtry
3887 finally
3888 call assert_equal(1, errcaught)
3889 break
3890 endtry
3891 endwhile
3892 call assert_equal('', v:exception)
3893 call assert_equal('', v:throwpoint)
3894
3895 Xpath 'd'
3896
3897 while 1
3898 try
3899 let intcaught = 0
3900 try
3901 try
3902 throw "x9"
3903 finally
3904 let lnum = expand("<sflnum>")
3905 call interrupt()
3906 endtry
3907 catch /.*/
3908 let intcaught = 1
3909 call assert_match('Vim:Interrupt', v:exception)
3910 call assert_match('line ' .. (lnum + 1), v:throwpoint)
3911 endtry
3912 finally
3913 call assert_equal(1, intcaught)
3914 break
3915 endtry
3916 endwhile
3917 call assert_equal('', v:exception)
3918 call assert_equal('', v:throwpoint)
3919
3920 Xpath 'e'
3921
3922 while 1
3923 try
3924 let errcaught = 0
3925 try
3926 try
3927 if 1
3928 let lnum = expand("<sflnum>")
3929 throw "x10"
3930 " missing endif
3931 finally
3932 call assert_equal('', v:exception)
3933 call assert_equal('', v:throwpoint)
3934 endtry
3935 catch /.*/
3936 let errcaught = 1
3937 call assert_match('Vim(finally):E171: Missing :endif:', v:exception)
3938 call assert_match('line ' .. (lnum + 3), v:throwpoint)
3939 endtry
3940 finally
3941 call assert_equal(1, errcaught)
3942 break
3943 endtry
3944 endwhile
3945 call assert_equal('', v:exception)
3946 call assert_equal('', v:throwpoint)
3947
3948 Xpath 'f'
3949
3950 while 1
3951 try
3952 let errcaught = 0
3953 try
3954 try
3955 if 1
3956 let lnum = expand("<sflnum>")
3957 throw "x11"
3958 " missing endif
3959 endtry
3960 catch /.*/
3961 let errcaught = 1
3962 call assert_match('Vim(endtry):E171: Missing :endif:', v:exception)
3963 call assert_match('line ' .. (lnum + 3), v:throwpoint)
3964 endtry
3965 finally
3966 call assert_equal(1, errcaught)
3967 break
3968 endtry
3969 endwhile
3970 call assert_equal('', v:exception)
3971 call assert_equal('', v:throwpoint)
3972
3973 Xpath 'g'
3974 [CODE]
3975 let verify =<< trim [CODE]
3976 call assert_equal('abcdefg', g:Xpath)
3977 [CODE]
3978 call RunInNewVim(test, verify)
3979endfunc
3980
3981"-------------------------------------------------------------------------------
3982"
3983" Test 60: (Re)throwing v:exception; :echoerr. {{{1
3984"
3985" A user exception can be rethrown after catching by throwing
3986" v:exception. An error or interrupt exception cannot be rethrown
3987" because Vim exceptions cannot be faked. A Vim exception using the
3988" value of v:exception can, however, be triggered by the :echoerr
3989" command.
3990"-------------------------------------------------------------------------------
3991
3992func Test_rethrow_exception_1()
3993 XpathINIT
3994 try
3995 try
3996 Xpath 'a'
3997 throw "oops"
3998 catch /oops/
3999 Xpath 'b'
4000 throw v:exception " rethrow user exception
4001 catch /.*/
4002 call assert_report('should not get here')
4003 endtry
4004 catch /^oops$/ " catches rethrown user exception
4005 Xpath 'c'
4006 catch /.*/
4007 call assert_report('should not get here')
4008 endtry
4009 call assert_equal('abc', g:Xpath)
4010endfunc
4011
4012func Test_rethrow_exception_2()
4013 XpathINIT
4014 try
4015 let caught = 0
4016 try
4017 Xpath 'a'
4018 write /n/o/n/w/r/i/t/a/b/l/e/_/f/i/l/e
4019 call assert_report('should not get here')
4020 catch /^Vim(write):/
4021 let caught = 1
4022 throw v:exception " throw error: cannot fake Vim exception
4023 catch /.*/
4024 call assert_report('should not get here')
4025 finally
4026 Xpath 'b'
4027 call assert_equal(1, caught)
4028 endtry
4029 catch /^Vim(throw):/ " catches throw error
4030 let caught = caught + 1
4031 catch /.*/
4032 call assert_report('should not get here')
4033 finally
4034 Xpath 'c'
4035 call assert_equal(2, caught)
4036 endtry
4037 call assert_equal('abc', g:Xpath)
4038endfunc
4039
4040func Test_rethrow_exception_3()
4041 XpathINIT
4042 try
4043 let caught = 0
4044 try
4045 Xpath 'a'
4046 asdf
4047 catch /^Vim/ " catch error exception
4048 let caught = 1
4049 " Trigger Vim error exception with value specified after :echoerr
4050 let value = substitute(v:exception, '^Vim\((.*)\)\=:', '', "")
4051 echoerr value
4052 catch /.*/
4053 call assert_report('should not get here')
4054 finally
4055 Xpath 'b'
4056 call assert_equal(1, caught)
4057 endtry
4058 catch /^Vim(echoerr):/
4059 let caught = caught + 1
4060 call assert_match(value, v:exception)
4061 catch /.*/
4062 call assert_report('should not get here')
4063 finally
4064 Xpath 'c'
4065 call assert_equal(2, caught)
4066 endtry
4067 call assert_equal('abc', g:Xpath)
4068endfunc
4069
4070func Test_rethrow_exception_3()
4071 XpathINIT
4072 try
4073 let errcaught = 0
4074 try
4075 Xpath 'a'
4076 let intcaught = 0
4077 call interrupt()
4078 catch /^Vim:/ " catch interrupt exception
4079 let intcaught = 1
4080 " Trigger Vim error exception with value specified after :echoerr
4081 echoerr substitute(v:exception, '^Vim\((.*)\)\=:', '', "")
4082 catch /.*/
4083 call assert_report('should not get here')
4084 finally
4085 Xpath 'b'
4086 call assert_equal(1, intcaught)
4087 endtry
4088 catch /^Vim(echoerr):/
4089 let errcaught = 1
4090 call assert_match('Interrupt', v:exception)
4091 finally
4092 Xpath 'c'
4093 call assert_equal(1, errcaught)
4094 endtry
4095 call assert_equal('abc', g:Xpath)
4096endfunc
4097
4098"-------------------------------------------------------------------------------
Bram Moolenaar9470a4d2020-08-07 16:49:11 +02004099" Test 61: Catching interrupt exceptions {{{1
4100"
4101" When an interrupt occurs inside a :try/:endtry region, an
4102" interrupt exception is thrown and can be caught. Its value is
4103" "Vim:Interrupt". If the interrupt occurs after an error or a :throw
4104" but before a matching :catch is reached, all following :catches of
4105" that try block are ignored, but the interrupt exception can be
4106" caught by the next surrounding try conditional. An interrupt is
4107" ignored when there is a previous interrupt that has not been caught
4108" or causes a :finally clause to be executed.
4109"-------------------------------------------------------------------------------
4110
4111func Test_catch_intr_exception()
4112 let test =<< trim [CODE]
4113 while 1
4114 try
4115 try
4116 Xpath 'a'
4117 call interrupt()
4118 call assert_report('should not get here')
4119 catch /^Vim:Interrupt$/
4120 Xpath 'b'
4121 finally
4122 Xpath 'c'
4123 endtry
4124 catch /.*/
4125 call assert_report('should not get here')
4126 finally
4127 Xpath 'd'
4128 break
4129 endtry
4130 endwhile
4131
4132 while 1
4133 try
4134 try
4135 try
4136 Xpath 'e'
4137 asdf
4138 call assert_report('should not get here')
4139 catch /do_not_catch/
4140 call assert_report('should not get here')
4141 catch /.*/
4142 Xpath 'f'
4143 call interrupt()
4144 call assert_report('should not get here')
4145 catch /.*/
4146 call assert_report('should not get here')
4147 finally
4148 Xpath 'g'
4149 call interrupt()
4150 call assert_report('should not get here')
4151 endtry
4152 catch /^Vim:Interrupt$/
4153 Xpath 'h'
4154 finally
4155 Xpath 'i'
4156 endtry
4157 catch /.*/
4158 call assert_report('should not get here')
4159 finally
4160 Xpath 'j'
4161 break
4162 endtry
4163 endwhile
4164
4165 while 1
4166 try
4167 try
4168 try
4169 Xpath 'k'
4170 throw "x"
4171 call assert_report('should not get here')
4172 catch /do_not_catch/
4173 call assert_report('should not get here')
4174 catch /x/
4175 Xpath 'l'
4176 call interrupt()
4177 call assert_report('should not get here')
4178 catch /.*/
4179 call assert_report('should not get here')
4180 endtry
4181 catch /^Vim:Interrupt$/
4182 Xpath 'm'
4183 finally
4184 Xpath 'n'
4185 endtry
4186 catch /.*/
4187 call assert_report('should not get here')
4188 finally
4189 Xpath 'o'
4190 break
4191 endtry
4192 endwhile
4193
4194 while 1
4195 try
4196 try
4197 Xpath 'p'
4198 call interrupt()
4199 call assert_report('should not get here')
4200 catch /do_not_catch/
4201 call interrupt()
4202 call assert_report('should not get here')
4203 catch /^Vim:Interrupt$/
4204 Xpath 'q'
4205 finally
4206 Xpath 'r'
4207 endtry
4208 catch /.*/
4209 call assert_report('should not get here')
4210 finally
4211 Xpath 's'
4212 break
4213 endtry
4214 endwhile
4215
4216 Xpath 't'
4217 [CODE]
4218 let verify =<< trim [CODE]
4219 call assert_equal('abcdefghijklmnopqrst', g:Xpath)
4220 [CODE]
4221 call RunInNewVim(test, verify)
4222endfunc
4223
4224"-------------------------------------------------------------------------------
Bram Moolenaarefb64822020-08-10 22:15:30 +02004225" Test 62: Catching error exceptions {{{1
4226"
4227" An error inside a :try/:endtry region is converted to an exception
4228" and can be caught. The error exception has a "Vim(cmdname):" prefix
4229" where cmdname is the name of the failing command, or a "Vim:" prefix
4230" if no command name is known. The "Vim" prefixes cannot be faked.
4231"-------------------------------------------------------------------------------
4232
4233func Test_catch_err_exception_1()
4234 XpathINIT
4235 while 1
4236 try
4237 try
4238 let caught = 0
4239 unlet novar
4240 catch /^Vim(unlet):/
4241 Xpath 'a'
4242 let caught = 1
4243 let v:errmsg = substitute(v:exception, '^Vim(unlet):', '', "")
4244 finally
4245 Xpath 'b'
4246 call assert_equal(1, caught)
4247 call assert_match('E108: No such variable: "novar"', v:errmsg)
4248 endtry
4249 catch /.*/
4250 call assert_report('should not get here')
4251 finally
4252 Xpath 'c'
4253 break
4254 endtry
4255 call assert_report('should not get here')
4256 endwhile
4257 call assert_equal('abc', g:Xpath)
4258endfunc
4259
4260func Test_catch_err_exception_2()
4261 XpathINIT
4262 while 1
4263 try
4264 try
4265 let caught = 0
4266 throw novar " error in :throw
4267 catch /^Vim(throw):/
4268 Xpath 'a'
4269 let caught = 1
4270 let v:errmsg = substitute(v:exception, '^Vim(throw):', '', "")
4271 finally
4272 Xpath 'b'
4273 call assert_equal(1, caught)
4274 call assert_match('E121: Undefined variable: novar', v:errmsg)
4275 endtry
4276 catch /.*/
4277 call assert_report('should not get here')
4278 finally
4279 Xpath 'c'
4280 break
4281 endtry
4282 call assert_report('should not get here')
4283 endwhile
4284 call assert_equal('abc', g:Xpath)
4285endfunc
4286
4287func Test_catch_err_exception_3()
4288 XpathINIT
4289 while 1
4290 try
4291 try
4292 let caught = 0
4293 throw "Vim:faked" " error: cannot fake Vim exception
4294 catch /^Vim(throw):/
4295 Xpath 'a'
4296 let caught = 1
4297 let v:errmsg = substitute(v:exception, '^Vim(throw):', '', "")
4298 finally
4299 Xpath 'b'
4300 call assert_equal(1, caught)
4301 call assert_match("E608: Cannot :throw exceptions with 'Vim' prefix",
4302 \ v:errmsg)
4303 endtry
4304 catch /.*/
4305 call assert_report('should not get here')
4306 finally
4307 Xpath 'c'
4308 break
4309 endtry
4310 call assert_report('should not get here')
4311 endwhile
4312 call assert_equal('abc', g:Xpath)
4313endfunc
4314
4315func Test_catch_err_exception_4()
4316 XpathINIT
4317 func F()
4318 while 1
4319 " Missing :endwhile
4320 endfunc
4321
4322 while 1
4323 try
4324 try
4325 let caught = 0
4326 call F()
4327 catch /^Vim(endfunction):/
4328 Xpath 'a'
4329 let caught = 1
4330 let v:errmsg = substitute(v:exception, '^Vim(endfunction):', '', "")
4331 finally
4332 Xpath 'b'
4333 call assert_equal(1, caught)
4334 call assert_match("E170: Missing :endwhile", v:errmsg)
4335 endtry
4336 catch /.*/
4337 call assert_report('should not get here')
4338 finally
4339 Xpath 'c'
4340 break
4341 endtry
4342 call assert_report('should not get here')
4343 endwhile
4344 call assert_equal('abc', g:Xpath)
4345 delfunc F
4346endfunc
4347
4348func Test_catch_err_exception_5()
4349 XpathINIT
4350 func F()
4351 while 1
4352 " Missing :endwhile
4353 endfunc
4354
4355 while 1
4356 try
4357 try
4358 let caught = 0
4359 ExecAsScript F
4360 catch /^Vim:/
4361 Xpath 'a'
4362 let caught = 1
4363 let v:errmsg = substitute(v:exception, '^Vim:', '', "")
4364 finally
4365 Xpath 'b'
4366 call assert_equal(1, caught)
4367 call assert_match("E170: Missing :endwhile", v:errmsg)
4368 endtry
4369 catch /.*/
4370 call assert_report('should not get here')
4371 finally
4372 Xpath 'c'
4373 break
4374 endtry
4375 call assert_report('should not get here')
4376 endwhile
4377 call assert_equal('abc', g:Xpath)
4378 delfunc F
4379endfunc
4380
4381func Test_catch_err_exception_6()
4382 XpathINIT
4383 func G()
4384 call G()
4385 endfunc
4386
4387 while 1
4388 try
4389 let mfd_save = &mfd
4390 set mfd=3
4391 try
4392 let caught = 0
4393 call G()
4394 catch /^Vim(call):/
4395 Xpath 'a'
4396 let caught = 1
4397 let v:errmsg = substitute(v:exception, '^Vim(call):', '', "")
4398 finally
4399 Xpath 'b'
4400 call assert_equal(1, caught)
4401 call assert_match("E132: Function call depth is higher than 'maxfuncdepth'", v:errmsg)
4402 endtry
4403 catch /.*/
4404 call assert_report('should not get here')
4405 finally
4406 Xpath 'c'
4407 let &mfd = mfd_save
4408 break
4409 endtry
4410 call assert_report('should not get here')
4411 endwhile
4412 call assert_equal('abc', g:Xpath)
4413 delfunc G
4414endfunc
4415
4416func Test_catch_err_exception_7()
4417 XpathINIT
4418 func H()
4419 return H()
4420 endfunc
4421
4422 while 1
4423 try
4424 let mfd_save = &mfd
4425 set mfd=3
4426 try
4427 let caught = 0
4428 call H()
4429 catch /^Vim(return):/
4430 Xpath 'a'
4431 let caught = 1
4432 let v:errmsg = substitute(v:exception, '^Vim(return):', '', "")
4433 finally
4434 Xpath 'b'
4435 call assert_equal(1, caught)
4436 call assert_match("E132: Function call depth is higher than 'maxfuncdepth'", v:errmsg)
4437 endtry
4438 catch /.*/
4439 call assert_report('should not get here')
4440 finally
4441 Xpath 'c'
4442 let &mfd = mfd_save
4443 break " discard error for $VIMNOERRTHROW
4444 endtry
4445 call assert_report('should not get here')
4446 endwhile
4447
4448 call assert_equal('abc', g:Xpath)
4449 delfunc H
4450endfunc
4451
4452"-------------------------------------------------------------------------------
4453" Test 63: Suppressing error exceptions by :silent!. {{{1
4454"
4455" A :silent! command inside a :try/:endtry region suppresses the
4456" conversion of errors to an exception and the immediate abortion on
4457" error. When the commands executed by the :silent! themselves open
4458" a new :try/:endtry region, conversion of errors to exception and
4459" immediate abortion is switched on again - until the next :silent!
4460" etc. The :silent! has the effect of setting v:errmsg to the error
4461" message text (without displaying it) and continuing with the next
4462" script line.
4463"
4464" When a command triggering autocommands is executed by :silent!
4465" inside a :try/:endtry, the autocommand execution is not suppressed
4466" on error.
4467"
4468" This test reuses the function MSG() from the previous test.
4469"-------------------------------------------------------------------------------
4470
4471func Test_silent_exception()
4472 XpathINIT
4473 XloopINIT
4474 let g:taken = ""
4475
4476 func S(n) abort
4477 XloopNEXT
4478 let g:taken = g:taken . "E" . a:n
4479 let v:errmsg = ""
4480 exec "asdf" . a:n
4481
4482 " Check that ":silent!" continues:
4483 Xloop 'a'
4484
4485 " Check that ":silent!" sets "v:errmsg":
4486 call assert_match("E492: Not an editor command", v:errmsg)
4487 endfunc
4488
4489 func Foo()
4490 while 1
4491 try
4492 try
4493 let caught = 0
4494 " This is not silent:
4495 call S(3)
4496 catch /^Vim:/
4497 Xpath 'b'
4498 let caught = 1
4499 let errmsg3 = substitute(v:exception, '^Vim:', '', "")
4500 silent! call S(4)
4501 finally
4502 call assert_equal(1, caught)
4503 Xpath 'c'
4504 call assert_match("E492: Not an editor command", errmsg3)
4505 silent! call S(5)
4506 " Break out of try conditionals that cover ":silent!". This also
4507 " discards the aborting error when $VIMNOERRTHROW is non-zero.
4508 break
4509 endtry
4510 catch /.*/
4511 call assert_report('should not get here')
4512 endtry
4513 endwhile
4514 " This is a double ":silent!" (see caller).
4515 silent! call S(6)
4516 endfunc
4517
4518 func Bar()
4519 try
4520 silent! call S(2)
4521 silent! execute "call Foo() | call S(7)"
4522 silent! call S(8)
4523 endtry " normal end of try cond that covers ":silent!"
4524 " This has a ":silent!" from the caller:
4525 call S(9)
4526 endfunc
4527
4528 silent! call S(1)
4529 silent! call Bar()
4530 silent! call S(10)
4531
4532 call assert_equal("E1E2E3E4E5E6E7E8E9E10", g:taken)
4533
4534 augroup TMP
4535 au!
4536 autocmd BufWritePost * Xpath 'd'
4537 augroup END
4538
4539 Xpath 'e'
4540 silent! write /i/m/p/o/s/s/i/b/l/e
4541 Xpath 'f'
4542
4543 call assert_equal('a2a3ba5ca6a7a8a9a10a11edf', g:Xpath)
4544
4545 augroup TMP
4546 au!
4547 augroup END
4548 augroup! TMP
4549 delfunction S
4550 delfunction Foo
4551 delfunction Bar
4552endfunc
4553
4554"-------------------------------------------------------------------------------
4555" Test 64: Error exceptions after error, interrupt or :throw {{{1
4556"
4557" When an error occurs after an interrupt or a :throw but before
4558" a matching :catch is reached, all following :catches of that try
4559" block are ignored, but the error exception can be caught by the next
4560" surrounding try conditional. Any previous error exception is
4561" discarded. An error is ignored when there is a previous error that
4562" has not been caught.
4563"-------------------------------------------------------------------------------
4564
4565func Test_exception_after_error_1()
4566 XpathINIT
4567 while 1
4568 try
4569 try
4570 Xpath 'a'
4571 let caught = 0
4572 while 1
4573 if 1
4574 " Missing :endif
4575 endwhile " throw error exception
4576 catch /^Vim(/
4577 Xpath 'b'
4578 let caught = 1
4579 finally
4580 Xpath 'c'
4581 call assert_equal(1, caught)
4582 endtry
4583 catch /.*/
4584 call assert_report('should not get here')
4585 finally
4586 Xpath 'd'
4587 break
4588 endtry
4589 call assert_report('should not get here')
4590 endwhile
4591 call assert_equal('abcd', g:Xpath)
4592endfunc
4593
4594func Test_exception_after_error_2()
4595 XpathINIT
4596 while 1
4597 try
4598 try
4599 Xpath 'a'
4600 let caught = 0
4601 try
4602 if 1
4603 " Missing :endif
4604 catch /.*/ " throw error exception
4605 call assert_report('should not get here')
4606 catch /.*/
4607 call assert_report('should not get here')
4608 endtry
4609 catch /^Vim(/
4610 Xpath 'b'
4611 let caught = 1
4612 finally
4613 Xpath 'c'
4614 call assert_equal(1, caught)
4615 endtry
4616 catch /.*/
4617 call assert_report('should not get here')
4618 finally
4619 Xpath 'd'
4620 break
4621 endtry
4622 call assert_report('should not get here')
4623 endwhile
4624 call assert_equal('abcd', g:Xpath)
4625endfunc
4626
4627func Test_exception_after_error_3()
4628 XpathINIT
4629 while 1
4630 try
4631 try
4632 let caught = 0
4633 try
4634 Xpath 'a'
4635 call interrupt()
4636 catch /do_not_catch/
4637 call assert_report('should not get here')
4638 if 1
4639 " Missing :endif
4640 catch /.*/ " throw error exception
4641 call assert_report('should not get here')
4642 catch /.*/
4643 call assert_report('should not get here')
4644 endtry
4645 catch /^Vim(/
4646 Xpath 'b'
4647 let caught = 1
4648 finally
4649 Xpath 'c'
4650 call assert_equal(1, caught)
4651 endtry
4652 catch /.*/
4653 call assert_report('should not get here')
4654 finally
4655 Xpath 'd'
4656 break
4657 endtry
4658 call assert_report('should not get here')
4659 endwhile
4660 call assert_equal('abcd', g:Xpath)
4661endfunc
4662
4663func Test_exception_after_error_4()
4664 XpathINIT
4665 while 1
4666 try
4667 try
4668 let caught = 0
4669 try
4670 Xpath 'a'
4671 throw "x"
4672 catch /do_not_catch/
4673 call assert_report('should not get here')
4674 if 1
4675 " Missing :endif
4676 catch /x/ " throw error exception
4677 call assert_report('should not get here')
4678 catch /.*/
4679 call assert_report('should not get here')
4680 endtry
4681 catch /^Vim(/
4682 Xpath 'b'
4683 let caught = 1
4684 finally
4685 Xpath 'c'
4686 call assert_equal(1, caught)
4687 endtry
4688 catch /.*/
4689 call assert_report('should not get here')
4690 finally
4691 Xpath 'd'
4692 break
4693 endtry
4694 call assert_report('should not get here')
4695 endwhile
4696 call assert_equal('abcd', g:Xpath)
4697endfunc
4698
4699func Test_exception_after_error_5()
4700 XpathINIT
4701 while 1
4702 try
4703 try
4704 let caught = 0
4705 Xpath 'a'
4706 endif " :endif without :if; throw error exception
4707 if 1
4708 " Missing :endif
4709 catch /do_not_catch/ " ignore new error
4710 call assert_report('should not get here')
4711 catch /^Vim(endif):/
4712 Xpath 'b'
4713 let caught = 1
4714 catch /^Vim(/
4715 call assert_report('should not get here')
4716 finally
4717 Xpath 'c'
4718 call assert_equal(1, caught)
4719 endtry
4720 catch /.*/
4721 call assert_report('should not get here')
4722 finally
4723 Xpath 'd'
4724 break
4725 endtry
4726 call assert_report('should not get here')
4727 endwhile
4728 call assert_equal('abcd', g:Xpath)
4729endfunc
4730
4731"-------------------------------------------------------------------------------
Bram Moolenaar9470a4d2020-08-07 16:49:11 +02004732" Test 65: Errors in the /pattern/ argument of a :catch {{{1
4733"
4734" On an error in the /pattern/ argument of a :catch, the :catch does
4735" not match. Any following :catches of the same :try/:endtry don't
4736" match either. Finally clauses are executed.
4737"-------------------------------------------------------------------------------
4738
4739func Test_catch_pattern_error()
4740 CheckEnglish
4741 XpathINIT
4742
4743 try
4744 try
4745 Xpath 'a'
4746 throw "oops"
4747 catch /^oops$/
4748 Xpath 'b'
4749 catch /\)/ " not checked; exception has already been caught
4750 call assert_report('should not get here')
4751 endtry
4752 Xpath 'c'
4753 catch /.*/
4754 call assert_report('should not get here')
4755 endtry
4756 call assert_equal('abc', g:Xpath)
4757
4758 XpathINIT
4759 func F()
4760 try
4761 try
4762 try
4763 Xpath 'a'
4764 throw "ab"
4765 catch /abc/ " does not catch
4766 call assert_report('should not get here')
4767 catch /\)/ " error; discards exception
4768 call assert_report('should not get here')
4769 catch /.*/ " not checked
4770 call assert_report('should not get here')
4771 finally
4772 Xpath 'b'
4773 endtry
4774 call assert_report('should not get here')
4775 catch /^ab$/ " checked, but original exception is discarded
4776 call assert_report('should not get here')
4777 catch /^Vim(catch):/
4778 Xpath 'c'
4779 call assert_match('Vim(catch):E475: Invalid argument:', v:exception)
4780 finally
4781 Xpath 'd'
4782 endtry
4783 Xpath 'e'
4784 catch /.*/
4785 call assert_report('should not get here')
4786 endtry
4787 Xpath 'f'
4788 endfunc
4789
4790 call F()
4791 call assert_equal('abcdef', g:Xpath)
4792
4793 delfunc F
4794endfunc
4795
4796"-------------------------------------------------------------------------------
Bram Moolenaarefb64822020-08-10 22:15:30 +02004797" Test 66: Stop range :call on error, interrupt, or :throw {{{1
4798"
4799" When a function which is multiply called for a range since it
4800" doesn't handle the range itself has an error in a command
4801" dynamically enclosed by :try/:endtry or gets an interrupt or
4802" executes a :throw, no more calls for the remaining lines in the
4803" range are made. On an error in a command not dynamically enclosed
4804" by :try/:endtry, the function is executed again for the remaining
4805" lines in the range.
4806"-------------------------------------------------------------------------------
4807
4808func Test_stop_range_on_error()
4809 let test =<< trim [CODE]
4810 let file = tempname()
4811 exec "edit" file
4812 call setline(1, ['line 1', 'line 2', 'line 3'])
4813 let taken = ""
4814 let expected = "G1EF1E(1)F1E(2)F1E(3)G2EF2E(1)G3IF3I(1)G4TF4T(1)G5AF5A(1)"
4815
4816 func F(reason, n) abort
4817 let g:taken = g:taken .. "F" .. a:n ..
4818 \ substitute(a:reason, '\(\l\).*', '\u\1', "") ..
4819 \ "(" .. line(".") .. ")"
4820
4821 if a:reason == "error"
4822 asdf
4823 elseif a:reason == "interrupt"
4824 call interrupt()
4825 elseif a:reason == "throw"
4826 throw "xyz"
4827 elseif a:reason == "aborting error"
4828 XloopNEXT
4829 call assert_equal(g:taken, g:expected)
4830 try
4831 bwipeout!
4832 call delete(g:file)
4833 asdf
4834 endtry
4835 endif
4836 endfunc
4837
4838 func G(reason, n)
4839 let g:taken = g:taken .. "G" .. a:n ..
4840 \ substitute(a:reason, '\(\l\).*', '\u\1', "")
4841 1,3call F(a:reason, a:n)
4842 endfunc
4843
4844 Xpath 'a'
4845 call G("error", 1)
4846 try
4847 Xpath 'b'
4848 try
4849 call G("error", 2)
4850 call assert_report('should not get here')
4851 finally
4852 Xpath 'c'
4853 try
4854 call G("interrupt", 3)
4855 call assert_report('should not get here')
4856 finally
4857 Xpath 'd'
4858 try
4859 call G("throw", 4)
4860 call assert_report('should not get here')
4861 endtry
4862 endtry
4863 endtry
4864 catch /xyz/
4865 Xpath 'e'
4866 catch /.*/
4867 call assert_report('should not get here')
4868 endtry
4869 Xpath 'f'
4870 call G("aborting error", 5)
4871 call assert_report('should not get here')
4872 [CODE]
4873 let verify =<< trim [CODE]
4874 call assert_equal('abcdef', g:Xpath)
4875 [CODE]
4876 call RunInNewVim(test, verify)
4877endfunc
4878
4879"-------------------------------------------------------------------------------
4880" Test 67: :throw across :call command {{{1
4881"
4882" On a call command, an exception might be thrown when evaluating the
4883" function name, during evaluation of the arguments, or when the
4884" function is being executed. The exception can be caught by the
4885" caller.
4886"-------------------------------------------------------------------------------
4887
4888func THROW(x, n)
4889 if a:n == 1
4890 Xpath 'A'
4891 elseif a:n == 2
4892 Xpath 'B'
4893 elseif a:n == 3
4894 Xpath 'C'
4895 endif
4896 throw a:x
4897endfunc
4898
4899func NAME(x, n)
4900 if a:n == 1
4901 call assert_report('should not get here')
4902 elseif a:n == 2
4903 Xpath 'D'
4904 elseif a:n == 3
4905 Xpath 'E'
4906 elseif a:n == 4
4907 Xpath 'F'
4908 endif
4909 return a:x
4910endfunc
4911
4912func ARG(x, n)
4913 if a:n == 1
4914 call assert_report('should not get here')
4915 elseif a:n == 2
4916 call assert_report('should not get here')
4917 elseif a:n == 3
4918 Xpath 'G'
4919 elseif a:n == 4
4920 Xpath 'I'
4921 endif
4922 return a:x
4923endfunc
4924
4925func Test_throw_across_call_cmd()
4926 XpathINIT
4927
4928 func F(x, n)
4929 if a:n == 2
4930 call assert_report('should not get here')
4931 elseif a:n == 4
4932 Xpath 'a'
4933 endif
4934 endfunc
4935
4936 while 1
4937 try
4938 let v:errmsg = ""
4939
4940 while 1
4941 try
4942 Xpath 'b'
4943 call {NAME(THROW("name", 1), 1)}(ARG(4711, 1), 1)
4944 call assert_report('should not get here')
4945 catch /^name$/
4946 Xpath 'c'
4947 catch /.*/
4948 call assert_report('should not get here')
4949 finally
4950 call assert_equal("", v:errmsg)
4951 let v:errmsg = ""
4952 break
4953 endtry
4954 endwhile
4955
4956 while 1
4957 try
4958 Xpath 'd'
4959 call {NAME("F", 2)}(ARG(THROW("arg", 2), 2), 2)
4960 call assert_report('should not get here')
4961 catch /^arg$/
4962 Xpath 'e'
4963 catch /.*/
4964 call assert_report('should not get here')
4965 finally
4966 call assert_equal("", v:errmsg)
4967 let v:errmsg = ""
4968 break
4969 endtry
4970 endwhile
4971
4972 while 1
4973 try
4974 Xpath 'f'
4975 call {NAME("THROW", 3)}(ARG("call", 3), 3)
4976 call assert_report('should not get here')
4977 catch /^call$/
4978 Xpath 'g'
4979 catch /^0$/ " default return value
4980 call assert_report('should not get here')
4981 catch /.*/
4982 call assert_report('should not get here')
4983 finally
4984 call assert_equal("", v:errmsg)
4985 let v:errmsg = ""
4986 break
4987 endtry
4988 endwhile
4989
4990 while 1
4991 try
4992 Xpath 'h'
4993 call {NAME("F", 4)}(ARG(4711, 4), 4)
4994 Xpath 'i'
4995 catch /.*/
4996 call assert_report('should not get here')
4997 finally
4998 call assert_equal("", v:errmsg)
4999 let v:errmsg = ""
5000 break
5001 endtry
5002 endwhile
5003
5004 catch /^0$/ " default return value
5005 call assert_report('should not get here')
5006 catch /.*/
5007 call assert_report('should not get here')
5008 finally
5009 call assert_equal("", v:errmsg)
5010 let v:errmsg = ""
5011 break
5012 endtry
5013 endwhile
5014
5015 call assert_equal('bAcdDBefEGCghFIai', g:Xpath)
5016 delfunction F
5017endfunc
5018
5019"-------------------------------------------------------------------------------
5020" Test 68: :throw across function calls in expressions {{{1
5021"
5022" On a function call within an expression, an exception might be
5023" thrown when evaluating the function name, during evaluation of the
5024" arguments, or when the function is being executed. The exception
5025" can be caught by the caller.
5026"
5027" This test reuses the functions THROW(), NAME(), and ARG() from the
5028" previous test.
5029"-------------------------------------------------------------------------------
5030
5031func Test_throw_across_call_expr()
5032 XpathINIT
5033
5034 func F(x, n)
5035 if a:n == 2
5036 call assert_report('should not get here')
5037 elseif a:n == 4
5038 Xpath 'a'
5039 endif
5040 return a:x
5041 endfunction
5042
5043 while 1
5044 try
5045 let error = 0
5046 let v:errmsg = ""
5047
5048 while 1
5049 try
5050 Xpath 'b'
5051 let var1 = {NAME(THROW("name", 1), 1)}(ARG(4711, 1), 1)
5052 call assert_report('should not get here')
5053 catch /^name$/
5054 Xpath 'c'
5055 catch /.*/
5056 call assert_report('should not get here')
5057 finally
5058 call assert_equal("", v:errmsg)
5059 let v:errmsg = ""
5060 break
5061 endtry
5062 endwhile
5063 call assert_true(!exists('var1'))
5064
5065 while 1
5066 try
5067 Xpath 'd'
5068 let var2 = {NAME("F", 2)}(ARG(THROW("arg", 2), 2), 2)
5069 call assert_report('should not get here')
5070 catch /^arg$/
5071 Xpath 'e'
5072 catch /.*/
5073 call assert_report('should not get here')
5074 finally
5075 call assert_equal("", v:errmsg)
5076 let v:errmsg = ""
5077 break
5078 endtry
5079 endwhile
5080 call assert_true(!exists('var2'))
5081
5082 while 1
5083 try
5084 Xpath 'f'
5085 let var3 = {NAME("THROW", 3)}(ARG("call", 3), 3)
5086 call assert_report('should not get here')
5087 catch /^call$/
5088 Xpath 'g'
5089 catch /^0$/ " default return value
5090 call assert_report('should not get here')
5091 catch /.*/
5092 call assert_report('should not get here')
5093 finally
5094 call assert_equal("", v:errmsg)
5095 let v:errmsg = ""
5096 break
5097 endtry
5098 endwhile
5099 call assert_true(!exists('var3'))
5100
5101 while 1
5102 try
5103 Xpath 'h'
5104 let var4 = {NAME("F", 4)}(ARG(4711, 4), 4)
5105 Xpath 'i'
5106 catch /.*/
5107 call assert_report('should not get here')
5108 finally
5109 call assert_equal("", v:errmsg)
5110 let v:errmsg = ""
5111 break
5112 endtry
5113 endwhile
5114 call assert_true(exists('var4') && var4 == 4711)
5115
5116 catch /^0$/ " default return value
5117 call assert_report('should not get here')
5118 catch /.*/
5119 call assert_report('should not get here')
5120 finally
5121 call assert_equal("", v:errmsg)
5122 break
5123 endtry
5124 endwhile
5125
5126 call assert_equal('bAcdDBefEGCghFIai', g:Xpath)
5127 delfunc F
5128endfunc
5129
5130"-------------------------------------------------------------------------------
5131" Test 76: Errors, interrupts, :throw during expression evaluation {{{1
5132"
5133" When a function call made during expression evaluation is aborted
5134" due to an error inside a :try/:endtry region or due to an interrupt
5135" or a :throw, the expression evaluation is aborted as well. No
5136" message is displayed for the cancelled expression evaluation. On an
5137" error not inside :try/:endtry, the expression evaluation continues.
5138"-------------------------------------------------------------------------------
5139
5140func Test_expr_eval_error()
5141 let test =<< trim [CODE]
5142 let taken = ""
5143
5144 func ERR(n)
5145 let g:taken = g:taken .. "E" .. a:n
5146 asdf
5147 endfunc
5148
5149 func ERRabort(n) abort
5150 let g:taken = g:taken .. "A" .. a:n
5151 asdf
5152 endfunc " returns -1; may cause follow-up msg for illegal var/func name
5153
5154 func WRAP(n, arg)
5155 let g:taken = g:taken .. "W" .. a:n
5156 let g:saved_errmsg = v:errmsg
5157 return arg
5158 endfunc
5159
5160 func INT(n)
5161 let g:taken = g:taken .. "I" .. a:n
5162 call interrupt()
5163 endfunc
5164
5165 func THR(n)
5166 let g:taken = g:taken .. "T" .. a:n
5167 throw "should not be caught"
5168 endfunc
5169
5170 func CONT(n)
5171 let g:taken = g:taken .. "C" .. a:n
5172 endfunc
5173
5174 func MSG(n)
5175 let g:taken = g:taken .. "M" .. a:n
5176 let errmsg = (a:n >= 37 && a:n <= 44) ? g:saved_errmsg : v:errmsg
5177 let msgptn = (a:n >= 10 && a:n <= 27) ? "^$" : "asdf"
5178 call assert_match(msgptn, errmsg)
5179 let v:errmsg = ""
5180 let g:saved_errmsg = ""
5181 endfunc
5182
5183 let v:errmsg = ""
5184
5185 try
5186 let t = 1
5187 while t <= 9
5188 Xloop 'a'
5189 try
5190 if t == 1
5191 let v{ERR(t) + CONT(t)} = 0
5192 elseif t == 2
5193 let v{ERR(t) + CONT(t)}
5194 elseif t == 3
5195 let var = exists('v{ERR(t) + CONT(t)}')
5196 elseif t == 4
5197 unlet v{ERR(t) + CONT(t)}
5198 elseif t == 5
5199 function F{ERR(t) + CONT(t)}()
5200 endfunction
5201 elseif t == 6
5202 function F{ERR(t) + CONT(t)}
5203 elseif t == 7
5204 let var = exists('*F{ERR(t) + CONT(t)}')
5205 elseif t == 8
5206 delfunction F{ERR(t) + CONT(t)}
5207 elseif t == 9
5208 let var = ERR(t) + CONT(t)
5209 endif
5210 catch /asdf/
5211 " v:errmsg is not set when the error message is converted to an
5212 " exception. Set it to the original error message.
5213 let v:errmsg = substitute(v:exception, '^Vim:', '', "")
5214 catch /^Vim\((\a\+)\)\=:/
5215 " An error exception has been thrown after the original error.
5216 let v:errmsg = ""
5217 finally
5218 call MSG(t)
5219 let t = t + 1
5220 XloopNEXT
5221 continue " discard an aborting error
5222 endtry
5223 endwhile
5224 catch /.*/
5225 call assert_report('should not get here')
5226 endtry
5227
5228 try
5229 let t = 10
5230 while t <= 18
5231 Xloop 'b'
5232 try
5233 if t == 10
5234 let v{INT(t) + CONT(t)} = 0
5235 elseif t == 11
5236 let v{INT(t) + CONT(t)}
5237 elseif t == 12
5238 let var = exists('v{INT(t) + CONT(t)}')
5239 elseif t == 13
5240 unlet v{INT(t) + CONT(t)}
5241 elseif t == 14
5242 function F{INT(t) + CONT(t)}()
5243 endfunction
5244 elseif t == 15
5245 function F{INT(t) + CONT(t)}
5246 elseif t == 16
5247 let var = exists('*F{INT(t) + CONT(t)}')
5248 elseif t == 17
5249 delfunction F{INT(t) + CONT(t)}
5250 elseif t == 18
5251 let var = INT(t) + CONT(t)
5252 endif
5253 catch /^Vim\((\a\+)\)\=:\(Interrupt\)\@!/
5254 " An error exception has been triggered after the interrupt.
5255 let v:errmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "")
5256 finally
5257 call MSG(t)
5258 let t = t + 1
5259 XloopNEXT
5260 continue " discard interrupt
5261 endtry
5262 endwhile
5263 catch /.*/
5264 call assert_report('should not get here')
5265 endtry
5266
5267 try
5268 let t = 19
5269 while t <= 27
5270 Xloop 'c'
5271 try
5272 if t == 19
5273 let v{THR(t) + CONT(t)} = 0
5274 elseif t == 20
5275 let v{THR(t) + CONT(t)}
5276 elseif t == 21
5277 let var = exists('v{THR(t) + CONT(t)}')
5278 elseif t == 22
5279 unlet v{THR(t) + CONT(t)}
5280 elseif t == 23
5281 function F{THR(t) + CONT(t)}()
5282 endfunction
5283 elseif t == 24
5284 function F{THR(t) + CONT(t)}
5285 elseif t == 25
5286 let var = exists('*F{THR(t) + CONT(t)}')
5287 elseif t == 26
5288 delfunction F{THR(t) + CONT(t)}
5289 elseif t == 27
5290 let var = THR(t) + CONT(t)
5291 endif
5292 catch /^Vim\((\a\+)\)\=:/
5293 " An error exception has been triggered after the :throw.
5294 let v:errmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "")
5295 finally
5296 call MSG(t)
5297 let t = t + 1
5298 XloopNEXT
5299 continue " discard exception
5300 endtry
5301 endwhile
5302 catch /.*/
5303 call assert_report('should not get here')
5304 endtry
5305
5306 let v{ERR(28) + CONT(28)} = 0
5307 call MSG(28)
5308 let v{ERR(29) + CONT(29)}
5309 call MSG(29)
5310 let var = exists('v{ERR(30) + CONT(30)}')
5311 call MSG(30)
5312 unlet v{ERR(31) + CONT(31)}
5313 call MSG(31)
5314 function F{ERR(32) + CONT(32)}()
5315 endfunction
5316 call MSG(32)
5317 function F{ERR(33) + CONT(33)}
5318 call MSG(33)
5319 let var = exists('*F{ERR(34) + CONT(34)}')
5320 call MSG(34)
5321 delfunction F{ERR(35) + CONT(35)}
5322 call MSG(35)
5323 let var = ERR(36) + CONT(36)
5324 call MSG(36)
5325
5326 let saved_errmsg = ""
5327
5328 let v{WRAP(37, ERRabort(37)) + CONT(37)} = 0
5329 call MSG(37)
5330 let v{WRAP(38, ERRabort(38)) + CONT(38)}
5331 call MSG(38)
5332 let var = exists('v{WRAP(39, ERRabort(39)) + CONT(39)}')
5333 call MSG(39)
5334 unlet v{WRAP(40, ERRabort(40)) + CONT(40)}
5335 call MSG(40)
5336 function F{WRAP(41, ERRabort(41)) + CONT(41)}()
5337 endfunction
5338 call MSG(41)
5339 function F{WRAP(42, ERRabort(42)) + CONT(42)}
5340 call MSG(42)
5341 let var = exists('*F{WRAP(43, ERRabort(43)) + CONT(43)}')
5342 call MSG(43)
5343 delfunction F{WRAP(44, ERRabort(44)) + CONT(44)}
5344 call MSG(44)
5345 let var = ERRabort(45) + CONT(45)
5346 call MSG(45)
5347 Xpath 'd'
5348
5349 let expected = ""
5350 \ .. "E1M1E2M2E3M3E4M4E5M5E6M6E7M7E8M8E9M9"
5351 \ .. "I10M10I11M11I12M12I13M13I14M14I15M15I16M16I17M17I18M18"
5352 \ .. "T19M19T20M20T21M21T22M22T23M23T24M24T25M25T26M26T27M27"
5353 \ .. "E28C28M28E29C29M29E30C30M30E31C31M31E32C32M32E33C33M33"
5354 \ .. "E34C34M34E35C35M35E36C36M36"
5355 \ .. "A37W37C37M37A38W38C38M38A39W39C39M39A40W40C40M40A41W41C41M41"
5356 \ .. "A42W42C42M42A43W43C43M43A44W44C44M44A45C45M45"
5357 call assert_equal(expected, taken)
5358 [CODE]
5359 let verify =<< trim [CODE]
5360 let expected = "a1a2a3a4a5a6a7a8a9"
5361 \ .. "b10b11b12b13b14b15b16b17b18"
5362 \ .. "c19c20c21c22c23c24c25c26c27d"
5363 call assert_equal(expected, g:Xpath)
5364 [CODE]
5365 call RunInNewVim(test, verify)
5366endfunc
5367
5368"-------------------------------------------------------------------------------
5369" Test 77: Errors, interrupts, :throw in name{brace-expression} {{{1
5370"
5371" When a function call made during evaluation of an expression in
5372" braces as part of a function name after ":function" is aborted due
5373" to an error inside a :try/:endtry region or due to an interrupt or
5374" a :throw, the expression evaluation is aborted as well, and the
5375" function definition is ignored, skipping all commands to the
5376" ":endfunction". On an error not inside :try/:endtry, the expression
5377" evaluation continues and the function gets defined, and can be
5378" called and deleted.
5379"-------------------------------------------------------------------------------
5380func Test_brace_expr_error()
5381 let test =<< trim [CODE]
5382 func ERR() abort
5383 Xloop 'a'
5384 asdf
5385 endfunc " returns -1
5386
5387 func OK()
5388 Xloop 'b'
5389 let v:errmsg = ""
5390 return 0
5391 endfunc
5392
5393 let v:errmsg = ""
5394
5395 Xpath 'c'
5396 func F{1 + ERR() + OK()}(arg)
5397 " F0 should be defined.
5398 if exists("a:arg") && a:arg == "calling"
5399 Xpath 'd'
5400 else
5401 call assert_report('should not get here')
5402 endif
5403 endfunction
5404 call assert_equal("", v:errmsg)
5405 XloopNEXT
5406
5407 Xpath 'e'
5408 call F{1 + ERR() + OK()}("calling")
5409 call assert_equal("", v:errmsg)
5410 XloopNEXT
5411
5412 Xpath 'f'
5413 delfunction F{1 + ERR() + OK()}
5414 call assert_equal("", v:errmsg)
5415 XloopNEXT
5416
5417 try
5418 while 1
5419 try
5420 Xpath 'g'
5421 func G{1 + ERR() + OK()}(arg)
5422 " G0 should not be defined, and the function body should be
5423 " skipped.
5424 call assert_report('should not get here')
5425 " Use an unmatched ":finally" to check whether the body is
5426 " skipped when an error occurs in ERR(). This works whether or
5427 " not the exception is converted to an exception.
5428 finally
5429 call assert_report('should not get here')
5430 endtry
5431 try
5432 call assert_report('should not get here')
5433 endfunction
5434
5435 call assert_report('should not get here')
5436 catch /asdf/
5437 " Jumped to when the function is not defined and the body is
5438 " skipped.
5439 Xpath 'h'
5440 catch /.*/
5441 call assert_report('should not get here')
5442 finally
5443 Xpath 'i'
5444 break
5445 endtry " jumped to when the body is not skipped
5446 endwhile
5447 catch /.*/
5448 call assert_report('should not get here')
5449 endtry
5450 [CODE]
5451 let verify =<< trim [CODE]
5452 call assert_equal('ca1b1ea2b2dfa3b3ga4hi', g:Xpath)
5453 [CODE]
5454 call RunInNewVim(test, verify)
5455endfunc
5456
5457"-------------------------------------------------------------------------------
5458" Test 78: Messages on parsing errors in expression evaluation {{{1
5459"
5460" When an expression evaluation detects a parsing error, an error
5461" message is given and converted to an exception, and the expression
5462" evaluation is aborted.
5463"-------------------------------------------------------------------------------
5464func Test_expr_eval_error_msg()
5465 CheckEnglish
5466
5467 let test =<< trim [CODE]
5468 let taken = ""
5469
5470 func F(n)
5471 let g:taken = g:taken . "F" . a:n
5472 endfunc
5473
5474 func MSG(n, enr, emsg)
5475 let g:taken = g:taken . "M" . a:n
5476 call assert_match('^' .. a:enr .. ':', v:errmsg)
5477 call assert_match(a:emsg, v:errmsg)
5478 endfunc
5479
5480 func CONT(n)
5481 let g:taken = g:taken . "C" . a:n
5482 endfunc
5483
5484 let v:errmsg = ""
5485 try
5486 let t = 1
5487 while t <= 14
5488 let g:taken = g:taken . "T" . t
5489 let v:errmsg = ""
5490 try
5491 if t == 1
5492 let v{novar + CONT(t)} = 0
5493 elseif t == 2
5494 let v{novar + CONT(t)}
5495 elseif t == 3
5496 let var = exists('v{novar + CONT(t)}')
5497 elseif t == 4
5498 unlet v{novar + CONT(t)}
5499 elseif t == 5
5500 function F{novar + CONT(t)}()
5501 endfunction
5502 elseif t == 6
5503 function F{novar + CONT(t)}
5504 elseif t == 7
5505 let var = exists('*F{novar + CONT(t)}')
5506 elseif t == 8
5507 delfunction F{novar + CONT(t)}
5508 elseif t == 9
5509 echo novar + CONT(t)
5510 elseif t == 10
5511 echo v{novar + CONT(t)}
5512 elseif t == 11
5513 echo F{novar + CONT(t)}
5514 elseif t == 12
5515 let var = novar + CONT(t)
5516 elseif t == 13
5517 let var = v{novar + CONT(t)}
5518 elseif t == 14
5519 let var = F{novar + CONT(t)}()
5520 endif
5521 catch /^Vim\((\a\+)\)\=:/
5522 Xloop 'a'
5523 " v:errmsg is not set when the error message is converted to an
5524 " exception. Set it to the original error message.
5525 let v:errmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "")
5526 finally
5527 Xloop 'b'
5528 if t <= 8 && t != 3 && t != 7
5529 call MSG(t, 'E475', 'Invalid argument\>')
5530 else
5531 call MSG(t, 'E121', "Undefined variable")
5532 endif
5533 let t = t + 1
5534 XloopNEXT
5535 continue " discard an aborting error
5536 endtry
5537 endwhile
5538 catch /.*/
5539 call assert_report('should not get here')
5540 endtry
5541
5542 func T(n, expr, enr, emsg)
5543 try
5544 let g:taken = g:taken . "T" . a:n
5545 let v:errmsg = ""
5546 try
5547 execute "let var = " . a:expr
5548 catch /^Vim\((\a\+)\)\=:/
5549 Xloop 'c'
5550 " v:errmsg is not set when the error message is converted to an
5551 " exception. Set it to the original error message.
5552 let v:errmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "")
5553 finally
5554 Xloop 'd'
5555 call MSG(a:n, a:enr, a:emsg)
5556 XloopNEXT
5557 " Discard an aborting error:
5558 return
5559 endtry
5560 catch /.*/
5561 call assert_report('should not get here')
5562 endtry
5563 endfunc
5564
5565 call T(15, 'Nofunc() + CONT(15)', 'E117', "Unknown function")
5566 call T(16, 'F(1 2 + CONT(16))', 'E116', "Invalid arguments")
5567 call T(17, 'F(1, 2) + CONT(17)', 'E118', "Too many arguments")
5568 call T(18, 'F() + CONT(18)', 'E119', "Not enough arguments")
5569 call T(19, '{(1} + CONT(19)', 'E110', "Missing ')'")
5570 call T(20, '("abc"[1) + CONT(20)', 'E111', "Missing ']'")
5571 call T(21, '(1 +) + CONT(21)', 'E15', "Invalid expression")
5572 call T(22, '1 2 + CONT(22)', 'E15', "Invalid expression")
5573 call T(23, '(1 ? 2) + CONT(23)', 'E109', "Missing ':' after '?'")
5574 call T(24, '("abc) + CONT(24)', 'E114', "Missing quote")
5575 call T(25, "('abc) + CONT(25)", 'E115', "Missing quote")
5576 call T(26, '& + CONT(26)', 'E112', "Option name missing")
5577 call T(27, '&asdf + CONT(27)', 'E113', "Unknown option")
5578
5579 let expected = ""
5580 \ .. "T1M1T2M2T3M3T4M4T5M5T6M6T7M7T8M8T9M9T10M10T11M11T12M12T13M13T14M14"
5581 \ .. "T15M15T16M16T17M17T18M18T19M19T20M20T21M21T22M22T23M23T24M24T25M25"
5582 \ .. "T26M26T27M27"
5583
5584 call assert_equal(expected, taken)
5585 [CODE]
5586 let verify =<< trim [CODE]
5587 let expected = "a1b1a2b2a3b3a4b4a5b5a6b6a7b7a8b8a9b9a10b10a11b11a12b12"
5588 \ .. "a13b13a14b14c15d15c16d16c17d17c18d18c19d19c20d20"
5589 \ .. "c21d21c22d22c23d23c24d24c25d25c26d26c27d27"
5590 call assert_equal(expected, g:Xpath)
5591 [CODE]
5592 call RunInNewVim(test, verify)
5593endfunc
5594
5595"-------------------------------------------------------------------------------
5596" Test 79: Throwing one of several errors for the same command {{{1
5597"
5598" When several errors appear in a row (for instance during expression
5599" evaluation), the first as the most specific one is used when
5600" throwing an error exception. If, however, a syntax error is
5601" detected afterwards, this one is used for the error exception.
5602" On a syntax error, the next command is not executed, on a normal
5603" error, however, it is (relevant only in a function without the
5604" "abort" flag). v:errmsg is not set.
5605"
5606" If throwing error exceptions is configured off, v:errmsg is always
5607" set to the latest error message, that is, to the more general
5608" message or the syntax error, respectively.
5609"-------------------------------------------------------------------------------
5610func Test_throw_multi_error()
5611 CheckEnglish
5612
5613 let test =<< trim [CODE]
5614 func NEXT(cmd)
5615 exec a:cmd . " | Xloop 'a'"
5616 endfun
5617
5618 call NEXT('echo novar') " (checks nextcmd)
5619 XloopNEXT
5620 call NEXT('let novar #') " (skips nextcmd)
5621 XloopNEXT
5622 call NEXT('unlet novar #') " (skips nextcmd)
5623 XloopNEXT
5624 call NEXT('let {novar}') " (skips nextcmd)
5625 XloopNEXT
5626 call NEXT('unlet{ novar}') " (skips nextcmd)
5627
5628 call assert_equal('a1', g:Xpath)
5629 XpathINIT
5630 XloopINIT
5631
5632 func EXEC(cmd)
5633 exec a:cmd
5634 endfunc
5635
5636 try
5637 while 1 " dummy loop
5638 try
5639 let v:errmsg = ""
5640 call EXEC('echo novar') " normal error
5641 catch /^Vim\((\a\+)\)\=:/
5642 Xpath 'b'
5643 call assert_match('E121: Undefined variable: novar', v:exception)
5644 finally
5645 Xpath 'c'
5646 call assert_equal("", v:errmsg)
5647 break
5648 endtry
5649 endwhile
5650
5651 Xpath 'd'
5652 let cmd = "let"
5653 while cmd != ""
5654 try
5655 let v:errmsg = ""
5656 call EXEC(cmd . ' novar #') " normal plus syntax error
5657 catch /^Vim\((\a\+)\)\=:/
5658 Xloop 'e'
5659 call assert_match('E488: Trailing characters', v:exception)
5660 finally
5661 Xloop 'f'
5662 call assert_equal("", v:errmsg)
5663 if cmd == "let"
5664 let cmd = "unlet"
5665 else
5666 let cmd = ""
5667 endif
5668 XloopNEXT
5669 continue
5670 endtry
5671 endwhile
5672
5673 Xpath 'g'
5674 let cmd = "let"
5675 while cmd != ""
5676 try
5677 let v:errmsg = ""
5678 call EXEC(cmd . ' {novar}') " normal plus syntax error
5679 catch /^Vim\((\a\+)\)\=:/
5680 Xloop 'h'
5681 call assert_match('E475: Invalid argument: {novar}', v:exception)
5682 finally
5683 Xloop 'i'
5684 call assert_equal("", v:errmsg)
5685 if cmd == "let"
5686 let cmd = "unlet"
5687 else
5688 let cmd = ""
5689 endif
5690 XloopNEXT
5691 continue
5692 endtry
5693 endwhile
5694 catch /.*/
5695 call assert_report('should not get here')
5696 endtry
5697 Xpath 'j'
5698 [CODE]
5699 let verify =<< trim [CODE]
5700 call assert_equal('bcde1f1e2f2gh3i3h4i4j', g:Xpath)
5701 [CODE]
5702 call RunInNewVim(test, verify)
5703endfunc
5704
5705"-------------------------------------------------------------------------------
5706" Test 80: Syntax error in expression for illegal :elseif {{{1
5707"
5708" If there is a syntax error in the expression after an illegal
5709" :elseif, an error message is given (or an error exception thrown)
5710" for the illegal :elseif rather than the expression error.
5711"-------------------------------------------------------------------------------
5712func Test_if_syntax_error()
5713 CheckEnglish
5714
5715 let test =<< trim [CODE]
5716 let v:errmsg = ""
5717 if 0
5718 else
5719 elseif 1 ||| 2
5720 endif
5721 Xpath 'a'
5722 call assert_match('E584: :elseif after :else', v:errmsg)
5723
5724 let v:errmsg = ""
5725 if 1
5726 else
5727 elseif 1 ||| 2
5728 endif
5729 Xpath 'b'
5730 call assert_match('E584: :elseif after :else', v:errmsg)
5731
5732 let v:errmsg = ""
5733 elseif 1 ||| 2
5734 Xpath 'c'
5735 call assert_match('E582: :elseif without :if', v:errmsg)
5736
5737 let v:errmsg = ""
5738 while 1
5739 elseif 1 ||| 2
5740 endwhile
5741 Xpath 'd'
5742 call assert_match('E582: :elseif without :if', v:errmsg)
5743
5744 while 1
5745 try
5746 try
5747 let v:errmsg = ""
5748 if 0
5749 else
5750 elseif 1 ||| 2
5751 endif
5752 catch /^Vim\((\a\+)\)\=:/
5753 Xpath 'e'
5754 call assert_match('E584: :elseif after :else', v:exception)
5755 finally
5756 Xpath 'f'
5757 call assert_equal("", v:errmsg)
5758 endtry
5759 catch /.*/
5760 call assert_report('should not get here')
5761 finally
5762 Xpath 'g'
5763 break
5764 endtry
5765 endwhile
5766
5767 while 1
5768 try
5769 try
5770 let v:errmsg = ""
5771 if 1
5772 else
5773 elseif 1 ||| 2
5774 endif
5775 catch /^Vim\((\a\+)\)\=:/
5776 Xpath 'h'
5777 call assert_match('E584: :elseif after :else', v:exception)
5778 finally
5779 Xpath 'i'
5780 call assert_equal("", v:errmsg)
5781 endtry
5782 catch /.*/
5783 call assert_report('should not get here')
5784 finally
5785 Xpath 'j'
5786 break
5787 endtry
5788 endwhile
5789
5790 while 1
5791 try
5792 try
5793 let v:errmsg = ""
5794 elseif 1 ||| 2
5795 catch /^Vim\((\a\+)\)\=:/
5796 Xpath 'k'
5797 call assert_match('E582: :elseif without :if', v:exception)
5798 finally
5799 Xpath 'l'
5800 call assert_equal("", v:errmsg)
5801 endtry
5802 catch /.*/
5803 call assert_report('should not get here')
5804 finally
5805 Xpath 'm'
5806 break
5807 endtry
5808 endwhile
5809
5810 while 1
5811 try
5812 try
5813 let v:errmsg = ""
5814 while 1
5815 elseif 1 ||| 2
5816 endwhile
5817 catch /^Vim\((\a\+)\)\=:/
5818 Xpath 'n'
5819 call assert_match('E582: :elseif without :if', v:exception)
5820 finally
5821 Xpath 'o'
5822 call assert_equal("", v:errmsg)
5823 endtry
5824 catch /.*/
5825 call assert_report('should not get here')
5826 finally
5827 Xpath 'p'
5828 break
5829 endtry
5830 endwhile
5831 Xpath 'q'
5832 [CODE]
5833 let verify =<< trim [CODE]
5834 call assert_equal('abcdefghijklmnopq', g:Xpath)
5835 [CODE]
5836 call RunInNewVim(test, verify)
5837endfunc
5838
5839"-------------------------------------------------------------------------------
5840" Test 81: Discarding exceptions after an error or interrupt {{{1
5841"
5842" When an exception is thrown from inside a :try conditional without
5843" :catch and :finally clauses and an error or interrupt occurs before
5844" the :endtry is reached, the exception is discarded.
5845"-------------------------------------------------------------------------------
5846
5847func Test_discard_exception_after_error_1()
5848 let test =<< trim [CODE]
5849 try
5850 Xpath 'a'
5851 try
5852 Xpath 'b'
5853 throw "arrgh"
5854 call assert_report('should not get here')
5855 if 1
5856 call assert_report('should not get here')
5857 " error after :throw: missing :endif
5858 endtry
5859 call assert_report('should not get here')
5860 catch /arrgh/
5861 call assert_report('should not get here')
5862 endtry
5863 call assert_report('should not get here')
5864 [CODE]
5865 let verify =<< trim [CODE]
5866 call assert_equal('ab', g:Xpath)
5867 [CODE]
5868 call RunInNewVim(test, verify)
5869endfunc
5870
5871" TODO: Not able inject an interrupt after throwing an exception
5872func Disable_Test_discard_exception_after_error_2()
5873 let test =<< trim [CODE]
5874 try
5875 Xpath 'a'
5876 try
5877 Xpath 'b'
5878 throw "arrgh"
5879 call interrupt() " FIXME: throw is not interrupted here
5880 call assert_report('should not get here')
5881 endtry
5882 call assert_report('should not get here')
5883 catch /arrgh/
5884 call assert_report('should not get here')
5885 endtry
5886 call assert_report('should not get here')
5887 [CODE]
5888 let verify =<< trim [CODE]
5889 call assert_equal('ab', g:Xpath)
5890 [CODE]
5891 call RunInNewVim(test, verify)
5892endfunc
5893
5894"-------------------------------------------------------------------------------
Bram Moolenaar1f068232019-11-03 16:17:26 +01005895" Test 87 using (expr) ? funcref : funcref {{{1
5896"
5897" Vim needs to correctly parse the funcref and even when it does
5898" not execute the funcref, it needs to consume the trailing ()
5899"-------------------------------------------------------------------------------
5900
5901func Add2(x1, x2)
5902 return a:x1 + a:x2
5903endfu
5904
5905func GetStr()
5906 return "abcdefghijklmnopqrstuvwxyp"
5907endfu
5908
5909func Test_funcref_with_condexpr()
5910 call assert_equal(5, function('Add2')(2,3))
5911
5912 call assert_equal(3, 1 ? function('Add2')(1,2) : function('Add2')(2,3))
5913 call assert_equal(5, 0 ? function('Add2')(1,2) : function('Add2')(2,3))
5914 " Make sure, GetStr() still works.
5915 call assert_equal('abcdefghijk', GetStr()[0:10])
5916endfunc
5917
Bram Moolenaar4119cf82016-01-17 14:59:01 +01005918" Test 90: Recognizing {} in variable name. {{{1
5919"-------------------------------------------------------------------------------
5920
5921func Test_curlies()
5922 let s:var = 66
5923 let ns = 's'
5924 call assert_equal(66, {ns}:var)
5925
5926 let g:a = {}
5927 let g:b = 't'
5928 let g:a[g:b] = 77
5929 call assert_equal(77, g:a['t'])
5930endfunc
Bram Moolenaara2cce862016-01-02 19:50:04 +01005931
5932"-------------------------------------------------------------------------------
Bram Moolenaarf95534c2016-01-23 21:59:52 +01005933" Test 91: using type(). {{{1
5934"-------------------------------------------------------------------------------
5935
5936func Test_type()
5937 call assert_equal(0, type(0))
5938 call assert_equal(1, type(""))
5939 call assert_equal(2, type(function("tr")))
Bram Moolenaar953cc7f2016-03-19 18:52:29 +01005940 call assert_equal(2, type(function("tr", [8])))
Bram Moolenaarf95534c2016-01-23 21:59:52 +01005941 call assert_equal(3, type([]))
5942 call assert_equal(4, type({}))
Bram Moolenaar5feabe02020-01-30 18:24:53 +01005943 if has('float')
5944 call assert_equal(5, type(0.0))
5945 endif
Bram Moolenaarf95534c2016-01-23 21:59:52 +01005946 call assert_equal(6, type(v:false))
5947 call assert_equal(6, type(v:true))
5948 call assert_equal(7, type(v:none))
5949 call assert_equal(7, type(v:null))
Bram Moolenaarf562e722016-07-19 17:25:25 +02005950 call assert_equal(8, v:t_job)
5951 call assert_equal(9, v:t_channel)
5952 call assert_equal(v:t_number, type(0))
5953 call assert_equal(v:t_string, type(""))
5954 call assert_equal(v:t_func, type(function("tr")))
5955 call assert_equal(v:t_func, type(function("tr", [8])))
5956 call assert_equal(v:t_list, type([]))
5957 call assert_equal(v:t_dict, type({}))
Bram Moolenaar5feabe02020-01-30 18:24:53 +01005958 if has('float')
5959 call assert_equal(v:t_float, type(0.0))
5960 endif
Bram Moolenaarf562e722016-07-19 17:25:25 +02005961 call assert_equal(v:t_bool, type(v:false))
5962 call assert_equal(v:t_bool, type(v:true))
5963 call assert_equal(v:t_none, type(v:none))
5964 call assert_equal(v:t_none, type(v:null))
Bram Moolenaar92b83cc2020-04-25 15:24:44 +02005965 call assert_equal(v:t_string, type(test_null_string()))
5966 call assert_equal(v:t_func, type(test_null_function()))
5967 call assert_equal(v:t_func, type(test_null_partial()))
5968 call assert_equal(v:t_list, type(test_null_list()))
5969 call assert_equal(v:t_dict, type(test_null_dict()))
5970 if has('job')
5971 call assert_equal(v:t_job, type(test_null_job()))
5972 endif
5973 if has('channel')
5974 call assert_equal(v:t_channel, type(test_null_channel()))
5975 endif
5976 call assert_equal(v:t_blob, type(test_null_blob()))
Bram Moolenaarf562e722016-07-19 17:25:25 +02005977
Bram Moolenaar7c215c52020-02-29 13:43:27 +01005978 call assert_fails("call type(test_void())", 'E685:')
5979 call assert_fails("call type(test_unknown())", 'E685:')
Bram Moolenaar17a13432016-01-24 14:22:10 +01005980
5981 call assert_equal(0, 0 + v:false)
5982 call assert_equal(1, 0 + v:true)
5983 call assert_equal(0, 0 + v:none)
5984 call assert_equal(0, 0 + v:null)
5985
Bram Moolenaarf48aa162016-01-24 17:54:24 +01005986 call assert_equal('v:false', '' . v:false)
5987 call assert_equal('v:true', '' . v:true)
5988 call assert_equal('v:none', '' . v:none)
5989 call assert_equal('v:null', '' . v:null)
Bram Moolenaar6039c7f2016-01-24 15:05:32 +01005990
5991 call assert_true(v:false == 0)
5992 call assert_false(v:false != 0)
5993 call assert_true(v:true == 1)
5994 call assert_false(v:true != 1)
5995 call assert_false(v:true == v:false)
5996 call assert_true(v:true != v:false)
5997
5998 call assert_true(v:null == 0)
5999 call assert_false(v:null != 0)
6000 call assert_true(v:none == 0)
6001 call assert_false(v:none != 0)
Bram Moolenaar04369222016-01-24 17:21:29 +01006002
6003 call assert_true(v:false is v:false)
6004 call assert_true(v:true is v:true)
6005 call assert_true(v:none is v:none)
6006 call assert_true(v:null is v:null)
6007
6008 call assert_false(v:false isnot v:false)
6009 call assert_false(v:true isnot v:true)
6010 call assert_false(v:none isnot v:none)
6011 call assert_false(v:null isnot v:null)
6012
6013 call assert_false(v:false is 0)
6014 call assert_false(v:true is 1)
6015 call assert_false(v:true is v:false)
6016 call assert_false(v:none is 0)
6017 call assert_false(v:null is 0)
6018 call assert_false(v:null is v:none)
6019
6020 call assert_true(v:false isnot 0)
6021 call assert_true(v:true isnot 1)
6022 call assert_true(v:true isnot v:false)
6023 call assert_true(v:none isnot 0)
6024 call assert_true(v:null isnot 0)
6025 call assert_true(v:null isnot v:none)
Bram Moolenaar65591002016-01-24 21:51:57 +01006026
6027 call assert_equal(v:false, eval(string(v:false)))
6028 call assert_equal(v:true, eval(string(v:true)))
6029 call assert_equal(v:none, eval(string(v:none)))
6030 call assert_equal(v:null, eval(string(v:null)))
Bram Moolenaar767d8c12016-01-25 20:22:54 +01006031
Bram Moolenaar15550002016-01-31 18:45:24 +01006032 call assert_equal(v:false, copy(v:false))
6033 call assert_equal(v:true, copy(v:true))
6034 call assert_equal(v:none, copy(v:none))
6035 call assert_equal(v:null, copy(v:null))
6036
6037 call assert_equal([v:false], deepcopy([v:false]))
6038 call assert_equal([v:true], deepcopy([v:true]))
6039 call assert_equal([v:none], deepcopy([v:none]))
6040 call assert_equal([v:null], deepcopy([v:null]))
6041
Bram Moolenaar767d8c12016-01-25 20:22:54 +01006042 call assert_true(empty(v:false))
6043 call assert_false(empty(v:true))
6044 call assert_true(empty(v:null))
6045 call assert_true(empty(v:none))
Bram Moolenaar6650a692016-01-26 19:59:10 +01006046
6047 func ChangeYourMind()
Bram Moolenaar1e115362019-01-09 23:01:02 +01006048 try
6049 return v:true
6050 finally
6051 return 'something else'
6052 endtry
Bram Moolenaar6650a692016-01-26 19:59:10 +01006053 endfunc
6054
6055 call ChangeYourMind()
Bram Moolenaarf95534c2016-01-23 21:59:52 +01006056endfunc
6057
6058"-------------------------------------------------------------------------------
Bram Moolenaarea8c2192016-02-07 19:27:53 +01006059" Test 92: skipping code {{{1
6060"-------------------------------------------------------------------------------
6061
6062func Test_skip()
6063 let Fn = function('Test_type')
6064 call assert_false(0 && Fn[1])
6065 call assert_false(0 && string(Fn))
6066 call assert_false(0 && len(Fn))
6067 let l = []
6068 call assert_false(0 && l[1])
6069 call assert_false(0 && string(l))
6070 call assert_false(0 && len(l))
6071 let f = 1.0
6072 call assert_false(0 && f[1])
6073 call assert_false(0 && string(f))
6074 call assert_false(0 && len(f))
6075 let sp = v:null
6076 call assert_false(0 && sp[1])
6077 call assert_false(0 && string(sp))
6078 call assert_false(0 && len(sp))
6079
6080endfunc
6081
6082"-------------------------------------------------------------------------------
Bram Moolenaar18dfb442016-05-31 22:31:23 +02006083" Test 93: :echo and string() {{{1
6084"-------------------------------------------------------------------------------
6085
6086func Test_echo_and_string()
6087 " String
6088 let a = 'foo bar'
6089 redir => result
6090 echo a
6091 echo string(a)
6092 redir END
6093 let l = split(result, "\n")
6094 call assert_equal(["foo bar",
6095 \ "'foo bar'"], l)
6096
6097 " Float
6098 if has('float')
6099 let a = -1.2e0
6100 redir => result
6101 echo a
6102 echo string(a)
6103 redir END
6104 let l = split(result, "\n")
6105 call assert_equal(["-1.2",
6106 \ "-1.2"], l)
6107 endif
6108
6109 " Funcref
6110 redir => result
6111 echo function('string')
6112 echo string(function('string'))
6113 redir END
6114 let l = split(result, "\n")
6115 call assert_equal(["string",
6116 \ "function('string')"], l)
6117
6118 " Recursive dictionary
6119 let a = {}
6120 let a["a"] = a
6121 redir => result
6122 echo a
6123 echo string(a)
6124 redir END
6125 let l = split(result, "\n")
6126 call assert_equal(["{'a': {...}}",
6127 \ "{'a': {...}}"], l)
6128
6129 " Recursive list
6130 let a = [0]
6131 let a[0] = a
6132 redir => result
6133 echo a
6134 echo string(a)
6135 redir END
6136 let l = split(result, "\n")
6137 call assert_equal(["[[...]]",
6138 \ "[[...]]"], l)
6139
6140 " Empty dictionaries in a list
6141 let a = {}
6142 redir => result
6143 echo [a, a, a]
6144 echo string([a, a, a])
6145 redir END
6146 let l = split(result, "\n")
6147 call assert_equal(["[{}, {}, {}]",
6148 \ "[{}, {}, {}]"], l)
6149
6150 " Empty dictionaries in a dictionary
6151 let a = {}
6152 let b = {"a": a, "b": a}
6153 redir => result
6154 echo b
6155 echo string(b)
6156 redir END
6157 let l = split(result, "\n")
6158 call assert_equal(["{'a': {}, 'b': {}}",
6159 \ "{'a': {}, 'b': {}}"], l)
6160
6161 " Empty lists in a list
6162 let a = []
6163 redir => result
6164 echo [a, a, a]
6165 echo string([a, a, a])
6166 redir END
6167 let l = split(result, "\n")
6168 call assert_equal(["[[], [], []]",
6169 \ "[[], [], []]"], l)
6170
6171 " Empty lists in a dictionary
6172 let a = []
6173 let b = {"a": a, "b": a}
6174 redir => result
6175 echo b
6176 echo string(b)
6177 redir END
6178 let l = split(result, "\n")
6179 call assert_equal(["{'a': [], 'b': []}",
6180 \ "{'a': [], 'b': []}"], l)
6181
6182 " Dictionaries in a list
6183 let a = {"one": "yes", "two": "yes", "three": "yes"}
6184 redir => result
6185 echo [a, a, a]
6186 echo string([a, a, a])
6187 redir END
6188 let l = split(result, "\n")
6189 call assert_equal(["[{'one': 'yes', 'two': 'yes', 'three': 'yes'}, {...}, {...}]",
6190 \ "[{'one': 'yes', 'two': 'yes', 'three': 'yes'}, {'one': 'yes', 'two': 'yes', 'three': 'yes'}, {'one': 'yes', 'two': 'yes', 'three': 'yes'}]"], l)
6191
6192 " Dictionaries in a dictionary
6193 let a = {"one": "yes", "two": "yes", "three": "yes"}
6194 let b = {"a": a, "b": a}
6195 redir => result
6196 echo b
6197 echo string(b)
6198 redir END
6199 let l = split(result, "\n")
6200 call assert_equal(["{'a': {'one': 'yes', 'two': 'yes', 'three': 'yes'}, 'b': {...}}",
6201 \ "{'a': {'one': 'yes', 'two': 'yes', 'three': 'yes'}, 'b': {'one': 'yes', 'two': 'yes', 'three': 'yes'}}"], l)
6202
6203 " Lists in a list
6204 let a = [1, 2, 3]
6205 redir => result
6206 echo [a, a, a]
6207 echo string([a, a, a])
6208 redir END
6209 let l = split(result, "\n")
6210 call assert_equal(["[[1, 2, 3], [...], [...]]",
6211 \ "[[1, 2, 3], [1, 2, 3], [1, 2, 3]]"], l)
6212
6213 " Lists in a dictionary
6214 let a = [1, 2, 3]
6215 let b = {"a": a, "b": a}
6216 redir => result
6217 echo b
6218 echo string(b)
6219 redir END
6220 let l = split(result, "\n")
6221 call assert_equal(["{'a': [1, 2, 3], 'b': [...]}",
6222 \ "{'a': [1, 2, 3], 'b': [1, 2, 3]}"], l)
6223
Bram Moolenaar1363a302020-04-12 13:50:26 +02006224 call assert_fails('echo &:', 'E112:')
6225 call assert_fails('echo &g:', 'E112:')
6226 call assert_fails('echo &l:', 'E112:')
6227
Bram Moolenaar18dfb442016-05-31 22:31:23 +02006228endfunc
6229
6230"-------------------------------------------------------------------------------
Bram Moolenaar22fcfad2016-07-01 18:17:26 +02006231" Test 94: 64-bit Numbers {{{1
6232"-------------------------------------------------------------------------------
6233
6234func Test_num64()
Bram Moolenaar22fcfad2016-07-01 18:17:26 +02006235 call assert_notequal( 4294967296, 0)
6236 call assert_notequal(-4294967296, 0)
6237 call assert_equal( 4294967296, 0xFFFFffff + 1)
6238 call assert_equal(-4294967296, -0xFFFFffff - 1)
6239
6240 call assert_equal( 9223372036854775807, 1 / 0)
6241 call assert_equal(-9223372036854775807, -1 / 0)
Bram Moolenaar7a40ea22017-01-22 18:34:57 +01006242 call assert_equal(-9223372036854775807 - 1, 0 / 0)
Bram Moolenaar22fcfad2016-07-01 18:17:26 +02006243
Bram Moolenaar5feabe02020-01-30 18:24:53 +01006244 if has('float')
6245 call assert_equal( 0x7FFFffffFFFFffff, float2nr( 1.0e150))
6246 call assert_equal(-0x7FFFffffFFFFffff, float2nr(-1.0e150))
6247 endif
Bram Moolenaar22fcfad2016-07-01 18:17:26 +02006248
6249 let rng = range(0xFFFFffff, 0x100000001)
6250 call assert_equal([0xFFFFffff, 0x100000000, 0x100000001], rng)
6251 call assert_equal(0x100000001, max(rng))
6252 call assert_equal(0xFFFFffff, min(rng))
6253 call assert_equal(rng, sort(range(0x100000001, 0xFFFFffff, -1), 'N'))
6254endfunc
6255
6256"-------------------------------------------------------------------------------
Bram Moolenaar70bcd732017-01-12 22:20:54 +01006257" Test 95: lines of :append, :change, :insert {{{1
6258"-------------------------------------------------------------------------------
6259
6260function! DefineFunction(name, body)
6261 let func = join(['function! ' . a:name . '()'] + a:body + ['endfunction'], "\n")
6262 exec func
6263endfunction
6264
6265func Test_script_lines()
6266 " :append
6267 try
Bram Moolenaar1e115362019-01-09 23:01:02 +01006268 call DefineFunction('T_Append', [
6269 \ 'append',
6270 \ 'py <<EOS',
6271 \ '.',
6272 \ ])
Bram Moolenaar70bcd732017-01-12 22:20:54 +01006273 catch
Bram Moolenaar1e115362019-01-09 23:01:02 +01006274 call assert_report("Can't define function")
Bram Moolenaar70bcd732017-01-12 22:20:54 +01006275 endtry
6276 try
Bram Moolenaar1e115362019-01-09 23:01:02 +01006277 call DefineFunction('T_Append', [
6278 \ 'append',
6279 \ 'abc',
6280 \ ])
6281 call assert_report("Shouldn't be able to define function")
Bram Moolenaar70bcd732017-01-12 22:20:54 +01006282 catch
Bram Moolenaar1e115362019-01-09 23:01:02 +01006283 call assert_exception('Vim(function):E126: Missing :endfunction')
Bram Moolenaar70bcd732017-01-12 22:20:54 +01006284 endtry
6285
6286 " :change
6287 try
Bram Moolenaar1e115362019-01-09 23:01:02 +01006288 call DefineFunction('T_Change', [
6289 \ 'change',
6290 \ 'py <<EOS',
6291 \ '.',
6292 \ ])
Bram Moolenaar70bcd732017-01-12 22:20:54 +01006293 catch
Bram Moolenaar1e115362019-01-09 23:01:02 +01006294 call assert_report("Can't define function")
Bram Moolenaar70bcd732017-01-12 22:20:54 +01006295 endtry
6296 try
Bram Moolenaar1e115362019-01-09 23:01:02 +01006297 call DefineFunction('T_Change', [
6298 \ 'change',
6299 \ 'abc',
6300 \ ])
6301 call assert_report("Shouldn't be able to define function")
Bram Moolenaar70bcd732017-01-12 22:20:54 +01006302 catch
Bram Moolenaar1e115362019-01-09 23:01:02 +01006303 call assert_exception('Vim(function):E126: Missing :endfunction')
Bram Moolenaar70bcd732017-01-12 22:20:54 +01006304 endtry
6305
6306 " :insert
6307 try
Bram Moolenaar1e115362019-01-09 23:01:02 +01006308 call DefineFunction('T_Insert', [
6309 \ 'insert',
6310 \ 'py <<EOS',
6311 \ '.',
6312 \ ])
Bram Moolenaar70bcd732017-01-12 22:20:54 +01006313 catch
Bram Moolenaar1e115362019-01-09 23:01:02 +01006314 call assert_report("Can't define function")
Bram Moolenaar70bcd732017-01-12 22:20:54 +01006315 endtry
6316 try
Bram Moolenaar1e115362019-01-09 23:01:02 +01006317 call DefineFunction('T_Insert', [
6318 \ 'insert',
6319 \ 'abc',
6320 \ ])
6321 call assert_report("Shouldn't be able to define function")
Bram Moolenaar70bcd732017-01-12 22:20:54 +01006322 catch
Bram Moolenaar1e115362019-01-09 23:01:02 +01006323 call assert_exception('Vim(function):E126: Missing :endfunction')
Bram Moolenaar70bcd732017-01-12 22:20:54 +01006324 endtry
6325endfunc
6326
6327"-------------------------------------------------------------------------------
Bram Moolenaar478af672017-04-10 22:22:42 +02006328" Test 96: line continuation {{{1
6329"
Bram Moolenaar1e115362019-01-09 23:01:02 +01006330" Undefined behavior was detected by ubsan with line continuation
6331" after an empty line.
Bram Moolenaar478af672017-04-10 22:22:42 +02006332"-------------------------------------------------------------------------------
6333func Test_script_emty_line_continuation()
6334
6335 \
6336endfunc
6337
6338"-------------------------------------------------------------------------------
Bram Moolenaar863e80b2017-06-04 20:30:00 +02006339" Test 97: bitwise functions {{{1
6340"-------------------------------------------------------------------------------
6341func Test_bitwise_functions()
6342 " and
6343 call assert_equal(127, and(127, 127))
6344 call assert_equal(16, and(127, 16))
Bram Moolenaar073e4b92019-08-18 23:01:56 +02006345 eval 127->and(16)->assert_equal(16)
Bram Moolenaar863e80b2017-06-04 20:30:00 +02006346 call assert_equal(0, and(127, 128))
Bram Moolenaar863e80b2017-06-04 20:30:00 +02006347 call assert_fails("call and([], 1)", 'E745:')
6348 call assert_fails("call and({}, 1)", 'E728:')
Bram Moolenaar5feabe02020-01-30 18:24:53 +01006349 if has('float')
6350 call assert_fails("call and(1.0, 1)", 'E805:')
6351 call assert_fails("call and(1, 1.0)", 'E805:')
6352 endif
Bram Moolenaar863e80b2017-06-04 20:30:00 +02006353 call assert_fails("call and(1, [])", 'E745:')
6354 call assert_fails("call and(1, {})", 'E728:')
6355 " or
6356 call assert_equal(23, or(16, 7))
6357 call assert_equal(15, or(8, 7))
Bram Moolenaar073e4b92019-08-18 23:01:56 +02006358 eval 8->or(7)->assert_equal(15)
Bram Moolenaar863e80b2017-06-04 20:30:00 +02006359 call assert_equal(123, or(0, 123))
Bram Moolenaar863e80b2017-06-04 20:30:00 +02006360 call assert_fails("call or([], 1)", 'E745:')
6361 call assert_fails("call or({}, 1)", 'E728:')
Bram Moolenaar5feabe02020-01-30 18:24:53 +01006362 if has('float')
6363 call assert_fails("call or(1.0, 1)", 'E805:')
6364 call assert_fails("call or(1, 1.0)", 'E805:')
6365 endif
Bram Moolenaar863e80b2017-06-04 20:30:00 +02006366 call assert_fails("call or(1, [])", 'E745:')
6367 call assert_fails("call or(1, {})", 'E728:')
6368 " xor
6369 call assert_equal(0, xor(127, 127))
6370 call assert_equal(111, xor(127, 16))
Bram Moolenaar073e4b92019-08-18 23:01:56 +02006371 eval 127->xor(16)->assert_equal(111)
Bram Moolenaar863e80b2017-06-04 20:30:00 +02006372 call assert_equal(255, xor(127, 128))
Bram Moolenaar5feabe02020-01-30 18:24:53 +01006373 if has('float')
6374 call assert_fails("call xor(1.0, 1)", 'E805:')
6375 call assert_fails("call xor(1, 1.0)", 'E805:')
6376 endif
Bram Moolenaar863e80b2017-06-04 20:30:00 +02006377 call assert_fails("call xor([], 1)", 'E745:')
6378 call assert_fails("call xor({}, 1)", 'E728:')
Bram Moolenaar863e80b2017-06-04 20:30:00 +02006379 call assert_fails("call xor(1, [])", 'E745:')
6380 call assert_fails("call xor(1, {})", 'E728:')
6381 " invert
6382 call assert_equal(65408, and(invert(127), 65535))
Bram Moolenaar073e4b92019-08-18 23:01:56 +02006383 eval 127->invert()->and(65535)->assert_equal(65408)
Bram Moolenaar863e80b2017-06-04 20:30:00 +02006384 call assert_equal(65519, and(invert(16), 65535))
6385 call assert_equal(65407, and(invert(128), 65535))
Bram Moolenaar5feabe02020-01-30 18:24:53 +01006386 if has('float')
6387 call assert_fails("call invert(1.0)", 'E805:')
6388 endif
Bram Moolenaar863e80b2017-06-04 20:30:00 +02006389 call assert_fails("call invert([])", 'E745:')
6390 call assert_fails("call invert({})", 'E728:')
6391endfunc
6392
Bram Moolenaar6f9a4762017-06-22 20:39:17 +02006393" Test using bang after user command {{{1
6394func Test_user_command_with_bang()
6395 command -bang Nieuw let nieuw = 1
6396 Ni!
6397 call assert_equal(1, nieuw)
6398 unlet nieuw
6399 delcommand Nieuw
6400endfunc
6401
Bram Moolenaarb9adef72020-01-02 14:31:22 +01006402func Test_script_expand_sfile()
6403 let lines =<< trim END
6404 func s:snr()
6405 return expand('<sfile>')
6406 endfunc
6407 let g:result = s:snr()
6408 END
6409 call writefile(lines, 'Xexpand')
6410 source Xexpand
6411 call assert_match('<SNR>\d\+_snr', g:result)
6412 source Xexpand
6413 call assert_match('<SNR>\d\+_snr', g:result)
6414
6415 call delete('Xexpand')
6416 unlet g:result
6417endfunc
6418
Bram Moolenaarff697e62019-02-12 22:28:33 +01006419func Test_compound_assignment_operators()
6420 " Test for number
6421 let x = 1
6422 let x += 10
6423 call assert_equal(11, x)
6424 let x -= 5
6425 call assert_equal(6, x)
6426 let x *= 4
6427 call assert_equal(24, x)
6428 let x /= 3
6429 call assert_equal(8, x)
6430 let x %= 3
6431 call assert_equal(2, x)
6432 let x .= 'n'
6433 call assert_equal('2n', x)
6434
Bram Moolenaare21c1582019-03-02 11:57:09 +01006435 " Test special cases: division or modulus with 0.
6436 let x = 1
6437 let x /= 0
Bram Moolenaar82f654e2020-02-17 22:12:50 +01006438 call assert_equal(0x7FFFFFFFFFFFFFFF, x)
Bram Moolenaare21c1582019-03-02 11:57:09 +01006439
6440 let x = -1
6441 let x /= 0
Bram Moolenaar82f654e2020-02-17 22:12:50 +01006442 call assert_equal(-0x7FFFFFFFFFFFFFFF, x)
Bram Moolenaare21c1582019-03-02 11:57:09 +01006443
6444 let x = 0
6445 let x /= 0
Bram Moolenaar82f654e2020-02-17 22:12:50 +01006446 call assert_equal(-0x7FFFFFFFFFFFFFFF - 1, x)
Bram Moolenaare21c1582019-03-02 11:57:09 +01006447
6448 let x = 1
6449 let x %= 0
6450 call assert_equal(0, x)
6451
6452 let x = -1
6453 let x %= 0
6454 call assert_equal(0, x)
6455
6456 let x = 0
6457 let x %= 0
6458 call assert_equal(0, x)
6459
Bram Moolenaarff697e62019-02-12 22:28:33 +01006460 " Test for string
6461 let x = 'str'
6462 let x .= 'ing'
6463 call assert_equal('string', x)
6464 let x += 1
6465 call assert_equal(1, x)
Bram Moolenaarff697e62019-02-12 22:28:33 +01006466
6467 if has('float')
Bram Moolenaar5feabe02020-01-30 18:24:53 +01006468 " Test for float
6469 let x -= 1.5
6470 call assert_equal(-0.5, x)
6471 let x = 0.5
6472 let x += 4.5
6473 call assert_equal(5.0, x)
6474 let x -= 1.5
6475 call assert_equal(3.5, x)
6476 let x *= 3.0
6477 call assert_equal(10.5, x)
6478 let x /= 2.5
6479 call assert_equal(4.2, x)
6480 call assert_fails('let x %= 0.5', 'E734')
6481 call assert_fails('let x .= "f"', 'E734')
Bram Moolenaar8b633132020-03-20 18:20:51 +01006482 let x = !3.14
6483 call assert_equal(0.0, x)
Bram Moolenaarea04a6e2020-04-23 13:38:02 +02006484
6485 " integer and float operations
6486 let x = 1
6487 let x *= 2.1
6488 call assert_equal(2.1, x)
6489 let x = 1
6490 let x /= 0.25
6491 call assert_equal(4.0, x)
6492 let x = 1
6493 call assert_fails('let x %= 0.25', 'E734:')
6494 let x = 1
6495 call assert_fails('let x .= 0.25', 'E734:')
6496 let x = 1.0
6497 call assert_fails('let x += [1.1]', 'E734:')
Bram Moolenaarff697e62019-02-12 22:28:33 +01006498 endif
6499
6500 " Test for environment variable
6501 let $FOO = 1
6502 call assert_fails('let $FOO += 1', 'E734')
6503 call assert_fails('let $FOO -= 1', 'E734')
6504 call assert_fails('let $FOO *= 1', 'E734')
6505 call assert_fails('let $FOO /= 1', 'E734')
6506 call assert_fails('let $FOO %= 1', 'E734')
6507 let $FOO .= 's'
6508 call assert_equal('1s', $FOO)
6509 unlet $FOO
6510
6511 " Test for option variable (type: number)
6512 let &scrolljump = 1
6513 let &scrolljump += 5
6514 call assert_equal(6, &scrolljump)
6515 let &scrolljump -= 2
6516 call assert_equal(4, &scrolljump)
6517 let &scrolljump *= 3
6518 call assert_equal(12, &scrolljump)
6519 let &scrolljump /= 2
6520 call assert_equal(6, &scrolljump)
6521 let &scrolljump %= 5
6522 call assert_equal(1, &scrolljump)
6523 call assert_fails('let &scrolljump .= "j"', 'E734')
6524 set scrolljump&vim
6525
6526 " Test for register
6527 let @/ = 1
6528 call assert_fails('let @/ += 1', 'E734')
6529 call assert_fails('let @/ -= 1', 'E734')
6530 call assert_fails('let @/ *= 1', 'E734')
6531 call assert_fails('let @/ /= 1', 'E734')
6532 call assert_fails('let @/ %= 1', 'E734')
6533 let @/ .= 's'
6534 call assert_equal('1s', @/)
6535 let @/ = ''
6536endfunc
6537
Bram Moolenaar7e0868e2020-04-19 17:24:53 +02006538func Test_unlet_env()
6539 let $TESTVAR = 'yes'
6540 call assert_equal('yes', $TESTVAR)
6541 call assert_fails('lockvar $TESTVAR', 'E940')
6542 call assert_fails('unlockvar $TESTVAR', 'E940')
6543 call assert_equal('yes', $TESTVAR)
6544 if 0
6545 unlet $TESTVAR
6546 endif
6547 call assert_equal('yes', $TESTVAR)
6548 unlet $TESTVAR
6549 call assert_equal('', $TESTVAR)
6550endfunc
6551
Bram Moolenaarc3e92c12019-03-23 14:23:07 +01006552func Test_refcount()
6553 " Immediate values
6554 call assert_equal(-1, test_refcount(1))
6555 call assert_equal(-1, test_refcount('s'))
6556 call assert_equal(-1, test_refcount(v:true))
6557 call assert_equal(0, test_refcount([]))
6558 call assert_equal(0, test_refcount({}))
6559 call assert_equal(0, test_refcount(0zff))
6560 call assert_equal(0, test_refcount({-> line('.')}))
6561 if has('float')
6562 call assert_equal(-1, test_refcount(0.1))
6563 endif
6564 if has('job')
6565 call assert_equal(0, test_refcount(job_start([&shell, &shellcmdflag, 'echo .'])))
6566 endif
6567
6568 " No refcount types
6569 let x = 1
6570 call assert_equal(-1, test_refcount(x))
6571 let x = 's'
6572 call assert_equal(-1, test_refcount(x))
6573 let x = v:true
6574 call assert_equal(-1, test_refcount(x))
6575 if has('float')
6576 let x = 0.1
6577 call assert_equal(-1, test_refcount(x))
6578 endif
6579
6580 " Check refcount
6581 let x = []
6582 call assert_equal(1, test_refcount(x))
6583
6584 let x = {}
Bram Moolenaarce90e362019-09-08 18:58:44 +02006585 call assert_equal(1, x->test_refcount())
Bram Moolenaarc3e92c12019-03-23 14:23:07 +01006586
6587 let x = 0zff
6588 call assert_equal(1, test_refcount(x))
6589
6590 let X = {-> line('.')}
6591 call assert_equal(1, test_refcount(X))
6592 let Y = X
6593 call assert_equal(2, test_refcount(X))
6594
6595 if has('job')
6596 let job = job_start([&shell, &shellcmdflag, 'echo .'])
6597 call assert_equal(1, test_refcount(job))
6598 call assert_equal(1, test_refcount(job_getchannel(job)))
6599 call assert_equal(1, test_refcount(job))
6600 endif
6601
6602 " Function arguments, copying and unassigning
6603 func ExprCheck(x, i)
6604 let i = a:i + 1
6605 call assert_equal(i, test_refcount(a:x))
6606 let Y = a:x
6607 call assert_equal(i + 1, test_refcount(a:x))
6608 call assert_equal(test_refcount(a:x), test_refcount(Y))
6609 let Y = 0
6610 call assert_equal(i, test_refcount(a:x))
6611 endfunc
6612 call ExprCheck([], 0)
6613 call ExprCheck({}, 0)
6614 call ExprCheck(0zff, 0)
6615 call ExprCheck({-> line('.')}, 0)
6616 if has('job')
6617 call ExprCheck(job, 1)
6618 call ExprCheck(job_getchannel(job), 1)
6619 call job_stop(job)
6620 endif
6621 delfunc ExprCheck
6622
6623 " Regarding function
6624 func Func(x) abort
6625 call assert_equal(2, test_refcount(function('Func')))
6626 call assert_equal(0, test_refcount(funcref('Func')))
6627 endfunc
6628 call assert_equal(1, test_refcount(function('Func')))
6629 call assert_equal(0, test_refcount(function('Func', [1])))
6630 call assert_equal(0, test_refcount(funcref('Func')))
6631 call assert_equal(0, test_refcount(funcref('Func', [1])))
6632 let X = function('Func')
6633 let Y = X
6634 call assert_equal(1, test_refcount(X))
6635 let X = function('Func', [1])
6636 let Y = X
6637 call assert_equal(2, test_refcount(X))
6638 let X = funcref('Func')
6639 let Y = X
6640 call assert_equal(2, test_refcount(X))
6641 let X = funcref('Func', [1])
6642 let Y = X
6643 call assert_equal(2, test_refcount(X))
6644 unlet X
6645 unlet Y
6646 call Func(1)
6647 delfunc Func
6648
6649 " Function with dict
6650 func DictFunc() dict
6651 call assert_equal(3, test_refcount(self))
6652 endfunc
6653 let d = {'Func': function('DictFunc')}
6654 call assert_equal(1, test_refcount(d))
6655 call assert_equal(0, test_refcount(d.Func))
6656 call d.Func()
6657 unlet d
6658 delfunc DictFunc
6659endfunc
6660
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01006661" Test for missing :endif, :endfor, :endwhile and :endtry {{{1
6662func Test_missing_end()
6663 call writefile(['if 2 > 1', 'echo ">"'], 'Xscript')
6664 call assert_fails('source Xscript', 'E171:')
6665 call writefile(['for i in range(5)', 'echo i'], 'Xscript')
6666 call assert_fails('source Xscript', 'E170:')
6667 call writefile(['while v:true', 'echo "."'], 'Xscript')
6668 call assert_fails('source Xscript', 'E170:')
6669 call writefile(['try', 'echo "."'], 'Xscript')
6670 call assert_fails('source Xscript', 'E600:')
6671 call delete('Xscript')
Bram Moolenaar818fc9a2020-02-21 17:54:45 +01006672
6673 " Using endfor with :while
6674 let caught_e732 = 0
6675 try
6676 while v:true
6677 endfor
6678 catch /E732:/
6679 let caught_e732 = 1
6680 endtry
6681 call assert_equal(1, caught_e732)
6682
6683 " Using endwhile with :for
6684 let caught_e733 = 0
6685 try
6686 for i in range(1)
6687 endwhile
6688 catch /E733:/
6689 let caught_e733 = 1
6690 endtry
6691 call assert_equal(1, caught_e733)
6692
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02006693 " Using endfunc with :if
6694 call assert_fails('exe "if 1 | endfunc | endif"', 'E193:')
6695
Bram Moolenaar818fc9a2020-02-21 17:54:45 +01006696 " Missing 'in' in a :for statement
6697 call assert_fails('for i range(1) | endfor', 'E690:')
Bram Moolenaarea04a6e2020-04-23 13:38:02 +02006698
6699 " Incorrect number of variables in for
6700 call assert_fails('for [i,] in range(3) | endfor', 'E475:')
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01006701endfunc
6702
6703" Test for deep nesting of if/for/while/try statements {{{1
6704func Test_deep_nest()
Bram Moolenaar494e9062020-05-31 21:28:02 +02006705 CheckRunVimInTerminal
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01006706
6707 let lines =<< trim [SCRIPT]
6708 " Deep nesting of if ... endif
6709 func Test1()
6710 let @a = join(repeat(['if v:true'], 51), "\n")
6711 let @a ..= "\n"
6712 let @a ..= join(repeat(['endif'], 51), "\n")
6713 @a
6714 let @a = ''
6715 endfunc
6716
6717 " Deep nesting of for ... endfor
6718 func Test2()
6719 let @a = join(repeat(['for i in [1]'], 51), "\n")
6720 let @a ..= "\n"
6721 let @a ..= join(repeat(['endfor'], 51), "\n")
6722 @a
6723 let @a = ''
6724 endfunc
6725
6726 " Deep nesting of while ... endwhile
6727 func Test3()
6728 let @a = join(repeat(['while v:true'], 51), "\n")
6729 let @a ..= "\n"
6730 let @a ..= join(repeat(['endwhile'], 51), "\n")
6731 @a
6732 let @a = ''
6733 endfunc
6734
6735 " Deep nesting of try ... endtry
6736 func Test4()
6737 let @a = join(repeat(['try'], 51), "\n")
6738 let @a ..= "\necho v:true\n"
6739 let @a ..= join(repeat(['endtry'], 51), "\n")
6740 @a
6741 let @a = ''
6742 endfunc
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02006743
6744 " Deep nesting of function ... endfunction
6745 func Test5()
6746 let @a = join(repeat(['function X()'], 51), "\n")
6747 let @a ..= "\necho v:true\n"
6748 let @a ..= join(repeat(['endfunction'], 51), "\n")
6749 @a
6750 let @a = ''
6751 endfunc
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01006752 [SCRIPT]
6753 call writefile(lines, 'Xscript')
6754
6755 let buf = RunVimInTerminal('-S Xscript', {'rows': 6})
6756
6757 " Deep nesting of if ... endif
6758 call term_sendkeys(buf, ":call Test1()\n")
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +02006759 call TermWait(buf)
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01006760 call WaitForAssert({-> assert_match('^E579:', term_getline(buf, 5))})
6761
6762 " Deep nesting of for ... endfor
6763 call term_sendkeys(buf, ":call Test2()\n")
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +02006764 call TermWait(buf)
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01006765 call WaitForAssert({-> assert_match('^E585:', term_getline(buf, 5))})
6766
6767 " Deep nesting of while ... endwhile
6768 call term_sendkeys(buf, ":call Test3()\n")
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +02006769 call TermWait(buf)
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01006770 call WaitForAssert({-> assert_match('^E585:', term_getline(buf, 5))})
6771
6772 " Deep nesting of try ... endtry
6773 call term_sendkeys(buf, ":call Test4()\n")
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +02006774 call TermWait(buf)
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01006775 call WaitForAssert({-> assert_match('^E601:', term_getline(buf, 5))})
6776
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02006777 " Deep nesting of function ... endfunction
6778 call term_sendkeys(buf, ":call Test5()\n")
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +02006779 call TermWait(buf)
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02006780 call WaitForAssert({-> assert_match('^E1058:', term_getline(buf, 4))})
6781 call term_sendkeys(buf, "\<C-C>\n")
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +02006782 call TermWait(buf)
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02006783
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01006784 "let l = ''
6785 "for i in range(1, 6)
6786 " let l ..= term_getline(buf, i) . "\n"
6787 "endfor
6788 "call assert_report(l)
6789
6790 call StopVimInTerminal(buf)
6791 call delete('Xscript')
6792endfunc
6793
Bram Moolenaar8b633132020-03-20 18:20:51 +01006794" Test for errors in converting to float from various types {{{1
6795func Test_float_conversion_errors()
6796 if has('float')
6797 call assert_fails('let x = 4.0 % 2.0', 'E804')
6798 call assert_fails('echo 1.1[0]', 'E806')
6799 call assert_fails('echo sort([function("min"), 1], "f")', 'E891:')
6800 call assert_fails('echo 3.2 == "vim"', 'E892:')
6801 call assert_fails('echo sort([[], 1], "f")', 'E893:')
6802 call assert_fails('echo sort([{}, 1], "f")', 'E894:')
6803 call assert_fails('echo 3.2 == v:true', 'E362:')
6804 call assert_fails('echo 3.2 == v:none', 'E907:')
6805 endif
6806endfunc
6807
Bram Moolenaar8e6cbb72020-07-01 14:38:12 +02006808" invalid function names {{{1
Bram Moolenaar08f41572020-04-20 16:50:00 +02006809func Test_invalid_function_names()
6810 " function name not starting with capital
6811 let caught_e128 = 0
6812 try
6813 func! g:test()
6814 echo "test"
6815 endfunc
6816 catch /E128:/
6817 let caught_e128 = 1
6818 endtry
6819 call assert_equal(1, caught_e128)
6820
6821 " function name includes a colon
6822 let caught_e884 = 0
6823 try
6824 func! b:test()
6825 echo "test"
6826 endfunc
6827 catch /E884:/
6828 let caught_e884 = 1
6829 endtry
6830 call assert_equal(1, caught_e884)
6831
6832 " function name folowed by #
6833 let caught_e128 = 0
6834 try
6835 func! test2() "#
6836 echo "test2"
6837 endfunc
6838 catch /E128:/
6839 let caught_e128 = 1
6840 endtry
6841 call assert_equal(1, caught_e128)
6842
6843 " function name starting with/without "g:", buffer-local funcref.
6844 function! g:Foo(n)
6845 return 'called Foo(' . a:n . ')'
6846 endfunction
6847 let b:my_func = function('Foo')
6848 call assert_equal('called Foo(1)', b:my_func(1))
6849 call assert_equal('called Foo(2)', g:Foo(2))
6850 call assert_equal('called Foo(3)', Foo(3))
6851 delfunc g:Foo
6852
6853 " script-local function used in Funcref must exist.
6854 let lines =<< trim END
6855 func s:Testje()
6856 return "foo"
6857 endfunc
6858 let Bar = function('s:Testje')
6859 call assert_equal(0, exists('s:Testje'))
6860 call assert_equal(1, exists('*s:Testje'))
6861 call assert_equal(1, exists('Bar'))
6862 call assert_equal(1, exists('*Bar'))
6863 END
6864 call writefile(lines, 'Xscript')
6865 source Xscript
6866 call delete('Xscript')
6867endfunc
6868
Bram Moolenaar8e6cbb72020-07-01 14:38:12 +02006869" substring and variable name {{{1
Bram Moolenaar08f41572020-04-20 16:50:00 +02006870func Test_substring_var()
6871 let str = 'abcdef'
6872 let n = 3
6873 call assert_equal('def', str[n:])
6874 call assert_equal('abcd', str[:n])
6875 call assert_equal('d', str[n:n])
6876 unlet n
6877 let nn = 3
6878 call assert_equal('def', str[nn:])
6879 call assert_equal('abcd', str[:nn])
6880 call assert_equal('d', str[nn:nn])
6881 unlet nn
6882 let b:nn = 4
6883 call assert_equal('ef', str[b:nn:])
6884 call assert_equal('abcde', str[:b:nn])
6885 call assert_equal('e', str[b:nn:b:nn])
6886 unlet b:nn
6887endfunc
6888
Bram Moolenaar8e6cbb72020-07-01 14:38:12 +02006889" Test using s: with a typed command {{{1
6890func Test_typed_script_var()
6891 CheckRunVimInTerminal
6892
6893 let buf = RunVimInTerminal('', {'rows': 6})
6894
6895 " Deep nesting of if ... endif
6896 call term_sendkeys(buf, ":echo get(s:, 'foo', 'x')\n")
6897 call TermWait(buf)
6898 call WaitForAssert({-> assert_match('^E116:', term_getline(buf, 5))})
6899
6900 call StopVimInTerminal(buf)
6901endfunc
6902
Bram Moolenaar863e80b2017-06-04 20:30:00 +02006903"-------------------------------------------------------------------------------
Bram Moolenaarf49e2402015-12-30 15:59:25 +01006904" Modelines {{{1
Bram Moolenaar1f068232019-11-03 16:17:26 +01006905" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
Bram Moolenaarf49e2402015-12-30 15:59:25 +01006906"-------------------------------------------------------------------------------