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