blob: b752bc8ddbd7e33b1171faf64b703a96e954961e [file] [log] [blame]
Bram Moolenaar5d7ead32018-02-27 17:17:42 +01001" Test various aspects of the Vim script language.
Bram Moolenaar4119cf82016-01-17 14:59:01 +01002" Most of this was formerly in test49.
Bram Moolenaarf49e2402015-12-30 15:59:25 +01003
Bram Moolenaar8c5a2782019-08-07 23:07:07 +02004source check.vim
Bram Moolenaar93344c22019-08-14 21:12:05 +02005source shared.vim
Bram Moolenaara6296202020-08-05 11:23:13 +02006source script_util.vim
Bram Moolenaar8c5a2782019-08-07 23:07:07 +02007
Bram Moolenaarf49e2402015-12-30 15:59:25 +01008"-------------------------------------------------------------------------------
9" Test environment {{{1
10"-------------------------------------------------------------------------------
11
Bram Moolenaarf49e2402015-12-30 15:59:25 +010012" Append a message to the "messages" file
Bram Moolenaar1e115362019-01-09 23:01:02 +010013func Xout(text)
Bram Moolenaarf49e2402015-12-30 15:59:25 +010014 split messages
15 $put =a:text
16 wq
17endfunc
18
19com! -nargs=1 Xout call Xout(<args>)
20
Bram Moolenaara6296202020-08-05 11:23:13 +020021" Create a new instance of Vim and run the commands in 'test' and then 'verify'
22" The commands in 'test' are expected to store the test results in the Xtest.out
23" file. If the test passes successfully, then Xtest.out should be empty.
24func RunInNewVim(test, verify)
25 let init =<< trim END
26 source script_util.vim
27 XpathINIT
28 XloopINIT
29 END
30 let cleanup =<< trim END
31 call writefile(v:errors, 'Xtest.out')
32 qall
33 END
34 call writefile(init, 'Xtest.vim')
35 call writefile(a:test, 'Xtest.vim', 'a')
36 call writefile(a:verify, 'Xverify.vim')
37 call writefile(cleanup, 'Xverify.vim', 'a')
38 call RunVim([], [], "-S Xtest.vim -S Xverify.vim")
39 call assert_equal([], readfile('Xtest.out'))
40 call delete('Xtest.out')
41 call delete('Xtest.vim')
42 call delete('Xverify.vim')
Bram Moolenaar1e115362019-01-09 23:01:02 +010043endfunc
Bram Moolenaarf49e2402015-12-30 15:59:25 +010044
Bram Moolenaarf49e2402015-12-30 15:59:25 +010045"-------------------------------------------------------------------------------
46" Test 1: :endwhile in function {{{1
47"
48" Detect if a broken loop is (incorrectly) reactivated by the
49" :endwhile. Use a :return to prevent an endless loop, and make
50" this test first to get a meaningful result on an error before other
51" tests will hang.
52"-------------------------------------------------------------------------------
53
Bram Moolenaara6296202020-08-05 11:23:13 +020054func T1_F()
Bram Moolenaarf49e2402015-12-30 15:59:25 +010055 Xpath 'a'
56 let first = 1
57 while 1
58 Xpath 'b'
59 if first
60 Xpath 'c'
61 let first = 0
62 break
63 else
64 Xpath 'd'
65 return
66 endif
67 endwhile
Bram Moolenaara6296202020-08-05 11:23:13 +020068endfunc
Bram Moolenaarf49e2402015-12-30 15:59:25 +010069
Bram Moolenaara6296202020-08-05 11:23:13 +020070func T1_G()
Bram Moolenaarf49e2402015-12-30 15:59:25 +010071 Xpath 'h'
72 let first = 1
73 while 1
74 Xpath 'i'
75 if first
76 Xpath 'j'
77 let first = 0
78 break
79 else
80 Xpath 'k'
81 return
82 endif
83 if 1 " unmatched :if
84 endwhile
Bram Moolenaara6296202020-08-05 11:23:13 +020085endfunc
Bram Moolenaarf49e2402015-12-30 15:59:25 +010086
87func Test_endwhile_function()
88 XpathINIT
89 call T1_F()
90 Xpath 'F'
91
92 try
93 call T1_G()
94 catch
95 " Catch missing :endif
96 call assert_true(v:exception =~ 'E171')
97 Xpath 'x'
98 endtry
99 Xpath 'G'
100
101 call assert_equal('abcFhijxG', g:Xpath)
102endfunc
103
104"-------------------------------------------------------------------------------
105" Test 2: :endwhile in script {{{1
106"
107" Detect if a broken loop is (incorrectly) reactivated by the
108" :endwhile. Use a :finish to prevent an endless loop, and place
109" this test before others that might hang to get a meaningful result
110" on an error.
111"
112" This test executes the bodies of the functions T1_F and T1_G from
113" the previous test as script files (:return replaced by :finish).
114"-------------------------------------------------------------------------------
115
116func Test_endwhile_script()
117 XpathINIT
118 ExecAsScript T1_F
119 Xpath 'F'
Bram Moolenaarf4f79b82016-01-25 20:38:30 +0100120 call DeleteTheScript()
Bram Moolenaarf49e2402015-12-30 15:59:25 +0100121
122 try
123 ExecAsScript T1_G
124 catch
125 " Catch missing :endif
126 call assert_true(v:exception =~ 'E171')
127 Xpath 'x'
128 endtry
129 Xpath 'G'
Bram Moolenaarf4f79b82016-01-25 20:38:30 +0100130 call DeleteTheScript()
Bram Moolenaarf49e2402015-12-30 15:59:25 +0100131
132 call assert_equal('abcFhijxG', g:Xpath)
133endfunc
134
135"-------------------------------------------------------------------------------
136" Test 3: :if, :elseif, :while, :continue, :break {{{1
137"-------------------------------------------------------------------------------
138
Bram Moolenaara6296202020-08-05 11:23:13 +0200139func Test_if_while()
Bram Moolenaarf49e2402015-12-30 15:59:25 +0100140 XpathINIT
141 if 1
142 Xpath 'a'
143 let loops = 3
144 while loops > -1 " main loop: loops == 3, 2, 1 (which breaks)
145 if loops <= 0
146 let break_err = 1
147 let loops = -1
148 else
149 Xpath 'b' . loops
150 endif
151 if (loops == 2)
152 while loops == 2 " dummy loop
153 Xpath 'c' . loops
154 let loops = loops - 1
155 continue " stop dummy loop
156 Xpath 'd' . loops
157 endwhile
158 continue " continue main loop
159 Xpath 'e' . loops
160 elseif (loops == 1)
161 let p = 1
162 while p " dummy loop
163 Xpath 'f' . loops
164 let p = 0
165 break " break dummy loop
166 Xpath 'g' . loops
167 endwhile
168 Xpath 'h' . loops
169 unlet p
170 break " break main loop
171 Xpath 'i' . loops
172 endif
173 if (loops > 0)
174 Xpath 'j' . loops
175 endif
176 while loops == 3 " dummy loop
177 let loops = loops - 1
178 endwhile " end dummy loop
179 endwhile " end main loop
180 Xpath 'k'
181 else
182 Xpath 'l'
183 endif
184 Xpath 'm'
185 if exists("break_err")
186 Xpath 'm'
187 unlet break_err
188 endif
189
190 unlet loops
191
192 call assert_equal('ab3j3b2c2b1f1h1km', g:Xpath)
193endfunc
194
195"-------------------------------------------------------------------------------
196" Test 4: :return {{{1
197"-------------------------------------------------------------------------------
198
Bram Moolenaara6296202020-08-05 11:23:13 +0200199func T4_F()
Bram Moolenaarf49e2402015-12-30 15:59:25 +0100200 if 1
201 Xpath 'a'
202 let loops = 3
203 while loops > 0 " 3: 2: 1:
204 Xpath 'b' . loops
205 if (loops == 2)
206 Xpath 'c' . loops
207 return
208 Xpath 'd' . loops
209 endif
210 Xpath 'e' . loops
211 let loops = loops - 1
212 endwhile
213 Xpath 'f'
214 else
215 Xpath 'g'
216 endif
Bram Moolenaara6296202020-08-05 11:23:13 +0200217endfunc
Bram Moolenaarf49e2402015-12-30 15:59:25 +0100218
Bram Moolenaara6296202020-08-05 11:23:13 +0200219func Test_return()
Bram Moolenaarf49e2402015-12-30 15:59:25 +0100220 XpathINIT
221 call T4_F()
222 Xpath '4'
223
224 call assert_equal('ab3e3b2c24', g:Xpath)
Bram Moolenaara6296202020-08-05 11:23:13 +0200225endfunc
Bram Moolenaarf49e2402015-12-30 15:59:25 +0100226
227
228"-------------------------------------------------------------------------------
229" Test 5: :finish {{{1
230"
231" This test executes the body of the function T4_F from the previous
232" test as a script file (:return replaced by :finish).
233"-------------------------------------------------------------------------------
234
Bram Moolenaara6296202020-08-05 11:23:13 +0200235func Test_finish()
Bram Moolenaarf49e2402015-12-30 15:59:25 +0100236 XpathINIT
237 ExecAsScript T4_F
238 Xpath '5'
Bram Moolenaarf4f79b82016-01-25 20:38:30 +0100239 call DeleteTheScript()
Bram Moolenaarf49e2402015-12-30 15:59:25 +0100240
241 call assert_equal('ab3e3b2c25', g:Xpath)
Bram Moolenaara6296202020-08-05 11:23:13 +0200242endfunc
Bram Moolenaarf49e2402015-12-30 15:59:25 +0100243
244
245
246"-------------------------------------------------------------------------------
247" Test 6: Defining functions in :while loops {{{1
248"
249" Functions can be defined inside other functions. An inner function
250" gets defined when the outer function is executed. Functions may
251" also be defined inside while loops. Expressions in braces for
252" defining the function name are allowed.
253"
254" The functions are defined when sourcing the script, only the
255" resulting path is checked in the test function.
256"-------------------------------------------------------------------------------
257
258XpathINIT
259
260" The command CALL collects the argument of all its invocations in "calls"
261" when used from a function (that is, when the global variable "calls" needs
262" the "g:" prefix). This is to check that the function code is skipped when
263" the function is defined. For inner functions, do so only if the outer
264" function is not being executed.
265"
266let calls = ""
267com! -nargs=1 CALL
Bram Moolenaar1e115362019-01-09 23:01:02 +0100268 \ if !exists("calls") && !exists("outer") |
269 \ let g:calls = g:calls . <args> |
270 \ endif
Bram Moolenaarf49e2402015-12-30 15:59:25 +0100271
272let i = 0
273while i < 3
274 let i = i + 1
275 if i == 1
276 Xpath 'a'
277 function! F1(arg)
278 CALL a:arg
279 let outer = 1
280
281 let j = 0
282 while j < 1
283 Xpath 'b'
284 let j = j + 1
285 function! G1(arg)
286 CALL a:arg
287 endfunction
288 Xpath 'c'
289 endwhile
290 endfunction
291 Xpath 'd'
292
293 continue
294 endif
295
296 Xpath 'e' . i
297 function! F{i}(i, arg)
298 CALL a:arg
299 let outer = 1
300
301 if a:i == 3
302 Xpath 'f'
303 endif
304 let k = 0
305 while k < 3
306 Xpath 'g' . k
307 let k = k + 1
308 function! G{a:i}{k}(arg)
309 CALL a:arg
310 endfunction
311 Xpath 'h' . k
312 endwhile
313 endfunction
314 Xpath 'i'
315
316endwhile
317
318if exists("*G1")
319 Xpath 'j'
320endif
321if exists("*F1")
322 call F1("F1")
323 if exists("*G1")
Bram Moolenaar1e115362019-01-09 23:01:02 +0100324 call G1("G1")
Bram Moolenaarf49e2402015-12-30 15:59:25 +0100325 endif
326endif
327
328if exists("G21") || exists("G22") || exists("G23")
329 Xpath 'k'
330endif
331if exists("*F2")
332 call F2(2, "F2")
333 if exists("*G21")
Bram Moolenaar1e115362019-01-09 23:01:02 +0100334 call G21("G21")
Bram Moolenaarf49e2402015-12-30 15:59:25 +0100335 endif
336 if exists("*G22")
Bram Moolenaar1e115362019-01-09 23:01:02 +0100337 call G22("G22")
Bram Moolenaarf49e2402015-12-30 15:59:25 +0100338 endif
339 if exists("*G23")
Bram Moolenaar1e115362019-01-09 23:01:02 +0100340 call G23("G23")
Bram Moolenaarf49e2402015-12-30 15:59:25 +0100341 endif
342endif
343
344if exists("G31") || exists("G32") || exists("G33")
345 Xpath 'l'
346endif
347if exists("*F3")
348 call F3(3, "F3")
349 if exists("*G31")
Bram Moolenaar1e115362019-01-09 23:01:02 +0100350 call G31("G31")
Bram Moolenaarf49e2402015-12-30 15:59:25 +0100351 endif
352 if exists("*G32")
Bram Moolenaar1e115362019-01-09 23:01:02 +0100353 call G32("G32")
Bram Moolenaarf49e2402015-12-30 15:59:25 +0100354 endif
355 if exists("*G33")
Bram Moolenaar1e115362019-01-09 23:01:02 +0100356 call G33("G33")
Bram Moolenaarf49e2402015-12-30 15:59:25 +0100357 endif
358endif
359
360Xpath 'm'
361
362let g:test6_result = g:Xpath
363let g:test6_calls = calls
364
365unlet calls
366delfunction F1
367delfunction G1
368delfunction F2
369delfunction G21
370delfunction G22
371delfunction G23
372delfunction G31
373delfunction G32
374delfunction G33
375
Bram Moolenaara6296202020-08-05 11:23:13 +0200376func Test_defining_functions()
Bram Moolenaarf49e2402015-12-30 15:59:25 +0100377 call assert_equal('ade2ie3ibcg0h1g1h2g2h3fg0h1g1h2g2h3m', g:test6_result)
378 call assert_equal('F1G1F2G21G22G23F3G31G32G33', g:test6_calls)
379endfunc
380
381"-------------------------------------------------------------------------------
Bram Moolenaara2cce862016-01-02 19:50:04 +0100382" Test 7: Continuing on errors outside functions {{{1
383"
384" On an error outside a function, the script processing continues
385" at the line following the outermost :endif or :endwhile. When not
386" inside an :if or :while, the script processing continues at the next
387" line.
388"-------------------------------------------------------------------------------
389
390XpathINIT
391
392if 1
393 Xpath 'a'
394 while 1
395 Xpath 'b'
396 asdf
397 Xpath 'c'
398 break
399 endwhile | Xpath 'd'
400 Xpath 'e'
401endif | Xpath 'f'
402Xpath 'g'
403
404while 1
405 Xpath 'h'
406 if 1
407 Xpath 'i'
408 asdf
409 Xpath 'j'
410 endif | Xpath 'k'
411 Xpath 'l'
412 break
413endwhile | Xpath 'm'
414Xpath 'n'
415
416asdf
417Xpath 'o'
418
419asdf | Xpath 'p'
420Xpath 'q'
421
422let g:test7_result = g:Xpath
423
424func Test_error_in_script()
425 call assert_equal('abghinoq', g:test7_result)
426endfunc
427
428"-------------------------------------------------------------------------------
429" Test 8: Aborting and continuing on errors inside functions {{{1
430"
431" On an error inside a function without the "abort" attribute, the
432" script processing continues at the next line (unless the error was
433" in a :return command). On an error inside a function with the
434" "abort" attribute, the function is aborted and the script processing
435" continues after the function call; the value -1 is returned then.
436"-------------------------------------------------------------------------------
437
438XpathINIT
439
Bram Moolenaara6296202020-08-05 11:23:13 +0200440func T8_F()
Bram Moolenaara2cce862016-01-02 19:50:04 +0100441 if 1
442 Xpath 'a'
443 while 1
444 Xpath 'b'
445 asdf
446 Xpath 'c'
447 asdf | Xpath 'd'
448 Xpath 'e'
449 break
450 endwhile
451 Xpath 'f'
452 endif | Xpath 'g'
453 Xpath 'h'
454
455 while 1
456 Xpath 'i'
457 if 1
458 Xpath 'j'
459 asdf
460 Xpath 'k'
461 asdf | Xpath 'l'
462 Xpath 'm'
463 endif
464 Xpath 'n'
465 break
466 endwhile | Xpath 'o'
467 Xpath 'p'
468
469 return novar " returns (default return value 0)
470 Xpath 'q'
471 return 1 " not reached
Bram Moolenaara6296202020-08-05 11:23:13 +0200472endfunc
Bram Moolenaara2cce862016-01-02 19:50:04 +0100473
Bram Moolenaara6296202020-08-05 11:23:13 +0200474func T8_G() abort
Bram Moolenaara2cce862016-01-02 19:50:04 +0100475 if 1
476 Xpath 'r'
477 while 1
478 Xpath 's'
479 asdf " returns -1
480 Xpath 't'
481 break
482 endwhile
483 Xpath 'v'
484 endif | Xpath 'w'
485 Xpath 'x'
486
487 return -4 " not reached
Bram Moolenaara6296202020-08-05 11:23:13 +0200488endfunc
Bram Moolenaara2cce862016-01-02 19:50:04 +0100489
Bram Moolenaara6296202020-08-05 11:23:13 +0200490func T8_H() abort
Bram Moolenaara2cce862016-01-02 19:50:04 +0100491 while 1
492 Xpath 'A'
493 if 1
494 Xpath 'B'
495 asdf " returns -1
496 Xpath 'C'
497 endif
498 Xpath 'D'
499 break
500 endwhile | Xpath 'E'
501 Xpath 'F'
502
503 return -4 " not reached
Bram Moolenaara6296202020-08-05 11:23:13 +0200504endfunc
Bram Moolenaara2cce862016-01-02 19:50:04 +0100505
506" Aborted functions (T8_G and T8_H) return -1.
507let g:test8_sum = (T8_F() + 1) - 4 * T8_G() - 8 * T8_H()
508Xpath 'X'
509let g:test8_result = g:Xpath
510
511func Test_error_in_function()
512 call assert_equal(13, g:test8_sum)
513 call assert_equal('abcefghijkmnoprsABX', g:test8_result)
514
515 delfunction T8_F
516 delfunction T8_G
517 delfunction T8_H
518endfunc
519
520
521"-------------------------------------------------------------------------------
522" Test 9: Continuing after aborted functions {{{1
523"
524" When a function with the "abort" attribute is aborted due to an
525" error, the next function back in the call hierarchy without an
526" "abort" attribute continues; the value -1 is returned then.
527"-------------------------------------------------------------------------------
528
529XpathINIT
530
Bram Moolenaara6296202020-08-05 11:23:13 +0200531func F() abort
Bram Moolenaara2cce862016-01-02 19:50:04 +0100532 Xpath 'a'
533 let result = G() " not aborted
534 Xpath 'b'
535 if result != 2
536 Xpath 'c'
537 endif
538 return 1
Bram Moolenaara6296202020-08-05 11:23:13 +0200539endfunc
Bram Moolenaara2cce862016-01-02 19:50:04 +0100540
Bram Moolenaara6296202020-08-05 11:23:13 +0200541func G() " no abort attribute
Bram Moolenaara2cce862016-01-02 19:50:04 +0100542 Xpath 'd'
543 if H() != -1 " aborted
544 Xpath 'e'
545 endif
546 Xpath 'f'
547 return 2
Bram Moolenaara6296202020-08-05 11:23:13 +0200548endfunc
Bram Moolenaara2cce862016-01-02 19:50:04 +0100549
Bram Moolenaara6296202020-08-05 11:23:13 +0200550func H() abort
Bram Moolenaara2cce862016-01-02 19:50:04 +0100551 Xpath 'g'
552 call I() " aborted
553 Xpath 'h'
554 return 4
Bram Moolenaara6296202020-08-05 11:23:13 +0200555endfunc
Bram Moolenaara2cce862016-01-02 19:50:04 +0100556
Bram Moolenaara6296202020-08-05 11:23:13 +0200557func I() abort
Bram Moolenaara2cce862016-01-02 19:50:04 +0100558 Xpath 'i'
559 asdf " error
560 Xpath 'j'
561 return 8
Bram Moolenaara6296202020-08-05 11:23:13 +0200562endfunc
Bram Moolenaara2cce862016-01-02 19:50:04 +0100563
564if F() != 1
565 Xpath 'k'
566endif
567
568let g:test9_result = g:Xpath
569
570delfunction F
571delfunction G
572delfunction H
573delfunction I
574
575func Test_func_abort()
576 call assert_equal('adgifb', g:test9_result)
577endfunc
578
579
580"-------------------------------------------------------------------------------
581" Test 10: :if, :elseif, :while argument parsing {{{1
582"
583" A '"' or '|' in an argument expression must not be mixed up with
584" a comment or a next command after a bar. Parsing errors should
585" be recognized.
586"-------------------------------------------------------------------------------
587
588XpathINIT
589
Bram Moolenaara6296202020-08-05 11:23:13 +0200590func MSG(enr, emsg)
Bram Moolenaara2cce862016-01-02 19:50:04 +0100591 let english = v:lang == "C" || v:lang =~ '^[Ee]n'
592 if a:enr == ""
593 Xout "TODO: Add message number for:" a:emsg
594 let v:errmsg = ":" . v:errmsg
595 endif
596 let match = 1
597 if v:errmsg !~ '^'.a:enr.':' || (english && v:errmsg !~ a:emsg)
598 let match = 0
599 if v:errmsg == ""
600 Xout "Message missing."
601 else
Bram Moolenaara4208962019-08-24 20:50:19 +0200602 let v:errmsg = v:errmsg->escape('"')
Bram Moolenaara2cce862016-01-02 19:50:04 +0100603 Xout "Unexpected message:" v:errmsg
604 endif
605 endif
606 return match
Bram Moolenaar1e115362019-01-09 23:01:02 +0100607endfunc
Bram Moolenaara2cce862016-01-02 19:50:04 +0100608
609if 1 || strlen("\"") | Xpath 'a'
610 Xpath 'b'
611endif
612Xpath 'c'
613
614if 0
615elseif 1 || strlen("\"") | Xpath 'd'
616 Xpath 'e'
617endif
618Xpath 'f'
619
620while 1 || strlen("\"") | Xpath 'g'
621 Xpath 'h'
622 break
623endwhile
624Xpath 'i'
625
626let v:errmsg = ""
627if 1 ||| strlen("\"") | Xpath 'j'
628 Xpath 'k'
629endif
630Xpath 'l'
631if !MSG('E15', "Invalid expression")
632 Xpath 'm'
633endif
634
635let v:errmsg = ""
636if 0
637elseif 1 ||| strlen("\"") | Xpath 'n'
638 Xpath 'o'
639endif
640Xpath 'p'
641if !MSG('E15', "Invalid expression")
642 Xpath 'q'
643endif
644
645let v:errmsg = ""
646while 1 ||| strlen("\"") | Xpath 'r'
647 Xpath 's'
648 break
649endwhile
650Xpath 't'
651if !MSG('E15', "Invalid expression")
652 Xpath 'u'
653endif
654
655let g:test10_result = g:Xpath
656delfunction MSG
657
658func Test_expr_parsing()
659 call assert_equal('abcdefghilpt', g:test10_result)
660endfunc
661
662
663"-------------------------------------------------------------------------------
664" Test 11: :if, :elseif, :while argument evaluation after abort {{{1
665"
666" When code is skipped over due to an error, the boolean argument to
667" an :if, :elseif, or :while must not be evaluated.
668"-------------------------------------------------------------------------------
669
670XpathINIT
671
672let calls = 0
673
Bram Moolenaara6296202020-08-05 11:23:13 +0200674func P(num)
Bram Moolenaara2cce862016-01-02 19:50:04 +0100675 let g:calls = g:calls + a:num " side effect on call
676 return 0
Bram Moolenaara6296202020-08-05 11:23:13 +0200677endfunc
Bram Moolenaara2cce862016-01-02 19:50:04 +0100678
679if 1
680 Xpath 'a'
681 asdf " error
682 Xpath 'b'
683 if P(1) " should not be called
684 Xpath 'c'
685 elseif !P(2) " should not be called
686 Xpath 'd'
687 else
688 Xpath 'e'
689 endif
690 Xpath 'f'
691 while P(4) " should not be called
692 Xpath 'g'
693 endwhile
694 Xpath 'h'
695endif
696Xpath 'x'
697
698let g:test11_calls = calls
699let g:test11_result = g:Xpath
700
701unlet calls
702delfunction P
703
704func Test_arg_abort()
705 call assert_equal(0, g:test11_calls)
706 call assert_equal('ax', g:test11_result)
707endfunc
708
709
710"-------------------------------------------------------------------------------
711" Test 12: Expressions in braces in skipped code {{{1
712"
713" In code skipped over due to an error or inactive conditional,
714" an expression in braces as part of a variable or function name
715" should not be evaluated.
716"-------------------------------------------------------------------------------
717
718XpathINIT
719
720function! NULL()
721 Xpath 'a'
722 return 0
723endfunction
724
725function! ZERO()
726 Xpath 'b'
727 return 0
728endfunction
729
730function! F0()
731 Xpath 'c'
732endfunction
733
734function! F1(arg)
735 Xpath 'e'
736endfunction
737
738let V0 = 1
739
740Xpath 'f'
741echo 0 ? F{NULL() + V{ZERO()}}() : 1
742
743Xpath 'g'
744if 0
745 Xpath 'h'
746 call F{NULL() + V{ZERO()}}()
747endif
748
749Xpath 'i'
750if 1
751 asdf " error
752 Xpath 'j'
753 call F1(F{NULL() + V{ZERO()}}())
754endif
755
756Xpath 'k'
757if 1
758 asdf " error
759 Xpath 'l'
760 call F{NULL() + V{ZERO()}}()
761endif
762
763let g:test12_result = g:Xpath
764
765func Test_braces_skipped()
766 call assert_equal('fgik', g:test12_result)
767endfunc
768
769
770"-------------------------------------------------------------------------------
771" Test 13: Failure in argument evaluation for :while {{{1
772"
773" A failure in the expression evaluation for the condition of a :while
774" causes the whole :while loop until the matching :endwhile being
775" ignored. Continuation is at the next following line.
776"-------------------------------------------------------------------------------
777
778XpathINIT
779
780Xpath 'a'
781while asdf
782 Xpath 'b'
783 while 1
784 Xpath 'c'
785 break
786 endwhile
787 Xpath 'd'
788 break
789endwhile
790Xpath 'e'
791
792while asdf | Xpath 'f' | endwhile | Xpath 'g'
793Xpath 'h'
794let g:test13_result = g:Xpath
795
796func Test_while_fail()
797 call assert_equal('aeh', g:test13_result)
798endfunc
799
800
801"-------------------------------------------------------------------------------
802" Test 14: Failure in argument evaluation for :if {{{1
803"
804" A failure in the expression evaluation for the condition of an :if
805" does not cause the corresponding :else or :endif being matched to
806" a previous :if/:elseif. Neither of both branches of the failed :if
807" are executed.
808"-------------------------------------------------------------------------------
809
810XpathINIT
811
812function! F()
813 Xpath 'a'
814 let x = 0
815 if x " false
816 Xpath 'b'
817 elseif !x " always true
818 Xpath 'c'
819 let x = 1
820 if g:boolvar " possibly undefined
821 Xpath 'd'
822 else
823 Xpath 'e'
824 endif
825 Xpath 'f'
826 elseif x " never executed
827 Xpath 'g'
828 endif
829 Xpath 'h'
830endfunction
831
832let boolvar = 1
833call F()
834Xpath '-'
835
836unlet boolvar
837call F()
838let g:test14_result = g:Xpath
839
840delfunction F
841
842func Test_if_fail()
843 call assert_equal('acdfh-acfh', g:test14_result)
844endfunc
845
846
847"-------------------------------------------------------------------------------
848" Test 15: Failure in argument evaluation for :if (bar) {{{1
849"
850" Like previous test, except that the failing :if ... | ... | :endif
851" is in a single line.
852"-------------------------------------------------------------------------------
853
854XpathINIT
855
856function! F()
857 Xpath 'a'
858 let x = 0
859 if x " false
860 Xpath 'b'
861 elseif !x " always true
862 Xpath 'c'
863 let x = 1
864 if g:boolvar | Xpath 'd' | else | Xpath 'e' | endif
865 Xpath 'f'
866 elseif x " never executed
867 Xpath 'g'
868 endif
869 Xpath 'h'
870endfunction
871
872let boolvar = 1
873call F()
874Xpath '-'
875
876unlet boolvar
877call F()
878let g:test15_result = g:Xpath
879
880delfunction F
881
882func Test_if_bar_fail()
883 call assert_equal('acdfh-acfh', g:test15_result)
884endfunc
885
Bram Moolenaar4119cf82016-01-17 14:59:01 +0100886"-------------------------------------------------------------------------------
Bram Moolenaar1f068232019-11-03 16:17:26 +0100887" Test 16: Double :else or :elseif after :else {{{1
888"
889" Multiple :elses or an :elseif after an :else are forbidden.
890"-------------------------------------------------------------------------------
891
892func T16_F() abort
893 if 0
894 Xpath 'a'
895 else
896 Xpath 'b'
897 else " aborts function
898 Xpath 'c'
899 endif
900 Xpath 'd'
901endfunc
902
903func T16_G() abort
904 if 0
905 Xpath 'a'
906 else
907 Xpath 'b'
908 elseif 1 " aborts function
909 Xpath 'c'
910 else
911 Xpath 'd'
912 endif
913 Xpath 'e'
914endfunc
915
916func T16_H() abort
917 if 0
918 Xpath 'a'
919 elseif 0
920 Xpath 'b'
921 else
922 Xpath 'c'
923 else " aborts function
924 Xpath 'd'
925 endif
926 Xpath 'e'
927endfunc
928
929func T16_I() abort
930 if 0
931 Xpath 'a'
932 elseif 0
933 Xpath 'b'
934 else
935 Xpath 'c'
936 elseif 1 " aborts function
937 Xpath 'd'
938 else
939 Xpath 'e'
940 endif
941 Xpath 'f'
942endfunc
943
944func Test_Multi_Else()
945 XpathINIT
946 try
947 call T16_F()
948 catch /E583:/
949 Xpath 'e'
950 endtry
951 call assert_equal('be', g:Xpath)
952
953 XpathINIT
954 try
955 call T16_G()
956 catch /E584:/
957 Xpath 'f'
958 endtry
959 call assert_equal('bf', g:Xpath)
960
961 XpathINIT
962 try
963 call T16_H()
964 catch /E583:/
965 Xpath 'f'
966 endtry
967 call assert_equal('cf', g:Xpath)
968
969 XpathINIT
970 try
971 call T16_I()
972 catch /E584:/
973 Xpath 'g'
974 endtry
975 call assert_equal('cg', g:Xpath)
976endfunc
977
978"-------------------------------------------------------------------------------
979" Test 17: Nesting of unmatched :if or :endif inside a :while {{{1
980"
981" The :while/:endwhile takes precedence in nesting over an unclosed
982" :if or an unopened :endif.
983"-------------------------------------------------------------------------------
984
985" While loops inside a function are continued on error.
986func T17_F()
987 let loops = 3
988 while loops > 0
989 let loops -= 1
990 Xpath 'a' . loops
991 if (loops == 1)
992 Xpath 'b' . loops
993 continue
994 elseif (loops == 0)
995 Xpath 'c' . loops
996 break
997 elseif 1
998 Xpath 'd' . loops
999 " endif missing!
1000 endwhile " :endwhile after :if 1
1001 Xpath 'e'
1002endfunc
1003
1004func T17_G()
1005 let loops = 2
1006 while loops > 0
1007 let loops -= 1
1008 Xpath 'a' . loops
1009 if 0
1010 Xpath 'b' . loops
1011 " endif missing
1012 endwhile " :endwhile after :if 0
1013endfunc
1014
1015func T17_H()
1016 let loops = 2
1017 while loops > 0
1018 let loops -= 1
1019 Xpath 'a' . loops
1020 " if missing!
1021 endif " :endif without :if in while
1022 Xpath 'b' . loops
1023 endwhile
1024endfunc
1025
1026" Error continuation outside a function is at the outermost :endwhile or :endif.
1027XpathINIT
1028let v:errmsg = ''
1029let loops = 2
1030while loops > 0
1031 let loops -= 1
1032 Xpath 'a' . loops
1033 if 0
1034 Xpath 'b' . loops
1035 " endif missing! Following :endwhile fails.
1036endwhile | Xpath 'c'
1037Xpath 'd'
1038call assert_match('E171:', v:errmsg)
1039call assert_equal('a1d', g:Xpath)
1040
1041func Test_unmatched_if_in_while()
1042 XpathINIT
1043 call assert_fails('call T17_F()', 'E171:')
1044 call assert_equal('a2d2a1b1a0c0e', g:Xpath)
1045
1046 XpathINIT
1047 call assert_fails('call T17_G()', 'E171:')
1048 call assert_equal('a1a0', g:Xpath)
1049
1050 XpathINIT
1051 call assert_fails('call T17_H()', 'E580:')
1052 call assert_equal('a1b1a0b0', g:Xpath)
1053endfunc
1054
1055"-------------------------------------------------------------------------------
Bram Moolenaara6296202020-08-05 11:23:13 +02001056" Test 18: Interrupt (Ctrl-C pressed) {{{1
1057"
1058" On an interrupt, the script processing is terminated immediately.
Bram Moolenaar1f068232019-11-03 16:17:26 +01001059"-------------------------------------------------------------------------------
Bram Moolenaara6296202020-08-05 11:23:13 +02001060
1061func Test_interrupt_while_if()
1062 let test =<< trim [CODE]
1063 try
1064 if 1
1065 Xpath 'a'
1066 while 1
1067 Xpath 'b'
1068 if 1
1069 Xpath 'c'
1070 call interrupt()
1071 call assert_report('should not get here')
1072 break
1073 finish
1074 endif | call assert_report('should not get here')
1075 call assert_report('should not get here')
1076 endwhile | call assert_report('should not get here')
1077 call assert_report('should not get here')
1078 endif | call assert_report('should not get here')
1079 call assert_report('should not get here')
1080 catch /^Vim:Interrupt$/
1081 Xpath 'd'
1082 endtry | Xpath 'e'
1083 Xpath 'f'
1084 [CODE]
1085 let verify =<< trim [CODE]
1086 call assert_equal('abcdef', g:Xpath)
1087 [CODE]
1088 call RunInNewVim(test, verify)
1089endfunc
1090
1091func Test_interrupt_try()
1092 let test =<< trim [CODE]
1093 try
1094 try
1095 Xpath 'a'
1096 call interrupt()
1097 call assert_report('should not get here')
1098 endtry | call assert_report('should not get here')
1099 call assert_report('should not get here')
1100 catch /^Vim:Interrupt$/
1101 Xpath 'b'
1102 endtry | Xpath 'c'
1103 Xpath 'd'
1104 [CODE]
1105 let verify =<< trim [CODE]
1106 call assert_equal('abcd', g:Xpath)
1107 [CODE]
1108 call RunInNewVim(test, verify)
1109endfunc
1110
1111func Test_interrupt_func_while_if()
1112 let test =<< trim [CODE]
1113 func F()
1114 if 1
1115 Xpath 'a'
1116 while 1
1117 Xpath 'b'
1118 if 1
1119 Xpath 'c'
1120 call interrupt()
1121 call assert_report('should not get here')
1122 break
1123 return
1124 endif | call assert_report('should not get here')
1125 call assert_report('should not get here')
1126 endwhile | call assert_report('should not get here')
1127 call assert_report('should not get here')
1128 endif | call assert_report('should not get here')
1129 call assert_report('should not get here')
1130 endfunc
1131
1132 Xpath 'd'
1133 try
1134 call F() | call assert_report('should not get here')
1135 catch /^Vim:Interrupt$/
1136 Xpath 'e'
1137 endtry | Xpath 'f'
1138 Xpath 'g'
1139 [CODE]
1140 let verify =<< trim [CODE]
1141 call assert_equal('dabcefg', g:Xpath)
1142 [CODE]
1143 call RunInNewVim(test, verify)
1144endfunc
1145
1146func Test_interrupt_func_try()
1147 let test =<< trim [CODE]
1148 func G()
1149 try
1150 Xpath 'a'
1151 call interrupt()
1152 call assert_report('should not get here')
1153 endtry | call assert_report('should not get here')
1154 call assert_report('should not get here')
1155 endfunc
1156
1157 Xpath 'b'
1158 try
1159 call G() | call assert_report('should not get here')
1160 catch /^Vim:Interrupt$/
1161 Xpath 'c'
1162 endtry | Xpath 'd'
1163 Xpath 'e'
1164 [CODE]
1165 let verify =<< trim [CODE]
1166 call assert_equal('bacde', g:Xpath)
1167 [CODE]
1168 call RunInNewVim(test, verify)
1169endfunc
1170
1171"-------------------------------------------------------------------------------
1172" Test 19: Aborting on errors inside :try/:endtry {{{1
1173"
1174" An error in a command dynamically enclosed in a :try/:endtry region
1175" aborts script processing immediately. It does not matter whether
1176" the failing command is outside or inside a function and whether a
1177" function has an "abort" attribute.
1178"-------------------------------------------------------------------------------
1179
1180func Test_try_error_abort_1()
1181 let test =<< trim [CODE]
1182 func F() abort
1183 Xpath 'a'
1184 asdf
1185 call assert_report('should not get here')
1186 endfunc
1187
1188 try
1189 Xpath 'b'
1190 call F()
1191 call assert_report('should not get here')
1192 endtry | call assert_report('should not get here')
1193 call assert_report('should not get here')
1194 [CODE]
1195 let verify =<< trim [CODE]
1196 call assert_equal('ba', g:Xpath)
1197 [CODE]
1198 call RunInNewVim(test, verify)
1199endfunc
1200
1201func Test_try_error_abort_2()
1202 let test =<< trim [CODE]
1203 func G()
1204 Xpath 'a'
1205 asdf
1206 call assert_report('should not get here')
1207 endfunc
1208
1209 try
1210 Xpath 'b'
1211 call G()
1212 call assert_report('should not get here')
1213 endtry | call assert_report('should not get here')
1214 call assert_report('should not get here')
1215 [CODE]
1216 let verify =<< trim [CODE]
1217 call assert_equal('ba', g:Xpath)
1218 [CODE]
1219 call RunInNewVim(test, verify)
1220endfunc
1221
1222func Test_try_error_abort_3()
1223 let test =<< trim [CODE]
1224 try
1225 Xpath 'a'
1226 asdf
1227 call assert_report('should not get here')
1228 endtry | call assert_report('should not get here')
1229 call assert_report('should not get here')
1230 [CODE]
1231 let verify =<< trim [CODE]
1232 call assert_equal('a', g:Xpath)
1233 [CODE]
1234 call RunInNewVim(test, verify)
1235endfunc
1236
1237func Test_try_error_abort_4()
1238 let test =<< trim [CODE]
1239 if 1
1240 try
1241 Xpath 'a'
1242 asdf
1243 call assert_report('should not get here')
1244 endtry | call assert_report('should not get here')
1245 endif | call assert_report('should not get here')
1246 call assert_report('should not get here')
1247 [CODE]
1248 let verify =<< trim [CODE]
1249 call assert_equal('a', g:Xpath)
1250 [CODE]
1251 call RunInNewVim(test, verify)
1252endfunc
1253
1254func Test_try_error_abort_5()
1255 let test =<< trim [CODE]
1256 let p = 1
1257 while p
1258 let p = 0
1259 try
1260 Xpath 'a'
1261 asdf
1262 call assert_report('should not get here')
1263 endtry | call assert_report('should not get here')
1264 endwhile | call assert_report('should not get here')
1265 call assert_report('should not get here')
1266 [CODE]
1267 let verify =<< trim [CODE]
1268 call assert_equal('a', g:Xpath)
1269 [CODE]
1270 call RunInNewVim(test, verify)
1271endfunc
1272
1273func Test_try_error_abort_6()
1274 let test =<< trim [CODE]
1275 let p = 1
1276 Xpath 'a'
1277 while p
1278 Xpath 'b'
1279 let p = 0
1280 try
1281 Xpath 'c'
1282 endwhile | call assert_report('should not get here')
1283 call assert_report('should not get here')
1284 [CODE]
1285 let verify =<< trim [CODE]
1286 call assert_equal('abc', g:Xpath)
1287 [CODE]
1288 call RunInNewVim(test, verify)
1289endfunc
1290
1291"-------------------------------------------------------------------------------
1292" Test 20: Aborting on errors after :try/:endtry {{{1
1293"
1294" When an error occurs after the last active :try/:endtry region has
1295" been left, termination behavior is as if no :try/:endtry has been
1296" seen.
1297"-------------------------------------------------------------------------------
1298
1299func Test_error_after_try_1()
1300 let test =<< trim [CODE]
1301 let p = 1
1302 while p
1303 let p = 0
1304 Xpath 'a'
1305 try
1306 Xpath 'b'
1307 endtry
1308 asdf
1309 call assert_report('should not get here')
1310 endwhile | call assert_report('should not get here')
1311 Xpath 'c'
1312 [CODE]
1313 let verify =<< trim [CODE]
1314 call assert_equal('abc', g:Xpath)
1315 [CODE]
1316 call RunInNewVim(test, verify)
1317endfunc
1318
1319func Test_error_after_try_2()
1320 let test =<< trim [CODE]
1321 while 1
1322 try
1323 Xpath 'a'
1324 break
1325 call assert_report('should not get here')
1326 endtry
1327 endwhile
1328 Xpath 'b'
1329 asdf
1330 Xpath 'c'
1331 [CODE]
1332 let verify =<< trim [CODE]
1333 call assert_equal('abc', g:Xpath)
1334 [CODE]
1335 call RunInNewVim(test, verify)
1336endfunc
1337
1338func Test_error_after_try_3()
1339 let test =<< trim [CODE]
1340 while 1
1341 try
1342 Xpath 'a'
1343 break
1344 call assert_report('should not get here')
1345 finally
1346 Xpath 'b'
1347 endtry
1348 endwhile
1349 Xpath 'c'
1350 asdf
1351 Xpath 'd'
1352 [CODE]
1353 let verify =<< trim [CODE]
1354 call assert_equal('abcd', g:Xpath)
1355 [CODE]
1356 call RunInNewVim(test, verify)
1357endfunc
1358
1359func Test_error_after_try_4()
1360 let test =<< trim [CODE]
1361 while 1
1362 try
1363 Xpath 'a'
1364 finally
1365 Xpath 'b'
1366 break
1367 call assert_report('should not get here')
1368 endtry
1369 endwhile
1370 Xpath 'c'
1371 asdf
1372 Xpath 'd'
1373 [CODE]
1374 let verify =<< trim [CODE]
1375 call assert_equal('abcd', g:Xpath)
1376 [CODE]
1377 call RunInNewVim(test, verify)
1378endfunc
1379
1380func Test_error_after_try_5()
1381 let test =<< trim [CODE]
1382 let p = 1
1383 while p
1384 let p = 0
1385 try
1386 Xpath 'a'
1387 continue
1388 call assert_report('should not get here')
1389 endtry
1390 endwhile
1391 Xpath 'b'
1392 asdf
1393 Xpath 'c'
1394 [CODE]
1395 let verify =<< trim [CODE]
1396 call assert_equal('abc', g:Xpath)
1397 [CODE]
1398 call RunInNewVim(test, verify)
1399endfunc
1400
1401func Test_error_after_try_6()
1402 let test =<< trim [CODE]
1403 let p = 1
1404 while p
1405 let p = 0
1406 try
1407 Xpath 'a'
1408 continue
1409 call assert_report('should not get here')
1410 finally
1411 Xpath 'b'
1412 endtry
1413 endwhile
1414 Xpath 'c'
1415 asdf
1416 Xpath 'd'
1417 [CODE]
1418 let verify =<< trim [CODE]
1419 call assert_equal('abcd', g:Xpath)
1420 [CODE]
1421 call RunInNewVim(test, verify)
1422endfunc
1423
1424func Test_error_after_try_7()
1425 let test =<< trim [CODE]
1426 let p = 1
1427 while p
1428 let p = 0
1429 try
1430 Xpath 'a'
1431 finally
1432 Xpath 'b'
1433 continue
1434 call assert_report('should not get here')
1435 endtry
1436 endwhile
1437 Xpath 'c'
1438 asdf
1439 Xpath 'd'
1440 [CODE]
1441 let verify =<< trim [CODE]
1442 call assert_equal('abcd', g:Xpath)
1443 [CODE]
1444 call RunInNewVim(test, verify)
1445endfunc
1446
1447"-------------------------------------------------------------------------------
1448" Test 21: :finally for :try after :continue/:break/:return/:finish {{{1
1449"
1450" If a :try conditional stays inactive due to a preceding :continue,
1451" :break, :return, or :finish, its :finally clause should not be
1452" executed.
1453"-------------------------------------------------------------------------------
1454
1455func Test_finally_after_loop_ctrl_statement()
1456 let test =<< trim [CODE]
1457 func F()
1458 let loops = 2
1459 while loops > 0
1460 XloopNEXT
1461 let loops = loops - 1
1462 try
1463 if loops == 1
1464 Xloop 'a'
1465 continue
1466 call assert_report('should not get here')
1467 elseif loops == 0
1468 Xloop 'b'
1469 break
1470 call assert_report('should not get here')
1471 endif
1472
1473 try " inactive
1474 call assert_report('should not get here')
1475 finally
1476 call assert_report('should not get here')
1477 endtry
1478 finally
1479 Xloop 'c'
1480 endtry
1481 call assert_report('should not get here')
1482 endwhile
1483
1484 try
1485 Xpath 'd'
1486 return
1487 call assert_report('should not get here')
1488 try " inactive
1489 call assert_report('should not get here')
1490 finally
1491 call assert_report('should not get here')
1492 endtry
1493 finally
1494 Xpath 'e'
1495 endtry
1496 call assert_report('should not get here')
1497 endfunc
1498
1499 try
1500 Xpath 'f'
1501 call F()
1502 Xpath 'g'
1503 finish
1504 call assert_report('should not get here')
1505 try " inactive
1506 call assert_report('should not get here')
1507 finally
1508 call assert_report('should not get here')
1509 endtry
1510 finally
1511 Xpath 'h'
1512 endtry
1513 call assert_report('should not get here')
1514 [CODE]
1515 let verify =<< trim [CODE]
1516 call assert_equal('fa2c2b3c3degh', g:Xpath)
1517 [CODE]
1518 call RunInNewVim(test, verify)
1519endfunc
1520
1521"-------------------------------------------------------------------------------
1522" Test 22: :finally for a :try after an error/interrupt/:throw {{{1
1523"
1524" If a :try conditional stays inactive due to a preceding error or
1525" interrupt or :throw, its :finally clause should not be executed.
1526"-------------------------------------------------------------------------------
1527
1528func Test_finally_after_error_in_func()
1529 let test =<< trim [CODE]
1530 func Error()
1531 try
1532 Xpath 'b'
1533 asdf " aborting error, triggering error exception
1534 call assert_report('should not get here')
1535 endtry
1536 call assert_report('should not get here')
1537 endfunc
1538
1539 Xpath 'a'
1540 call Error()
1541 call assert_report('should not get here')
1542
1543 if 1 " not active due to error
1544 try " not active since :if inactive
1545 call assert_report('should not get here')
1546 finally
1547 call assert_report('should not get here')
1548 endtry
1549 endif
1550
1551 try " not active due to error
1552 call assert_report('should not get here')
1553 finally
1554 call assert_report('should not get here')
1555 endtry
1556 [CODE]
1557 let verify =<< trim [CODE]
1558 call assert_equal('ab', g:Xpath)
1559 [CODE]
1560 call RunInNewVim(test, verify)
1561endfunc
1562
1563func Test_finally_after_interrupt()
1564 let test =<< trim [CODE]
1565 func Interrupt()
1566 try
1567 Xpath 'a'
1568 call interrupt() " triggering interrupt exception
1569 call assert_report('should not get here')
1570 endtry
1571 endfunc
1572
1573 Xpath 'b'
1574 try
1575 call Interrupt()
1576 catch /^Vim:Interrupt$/
1577 Xpath 'c'
1578 finish
1579 endtry
1580 call assert_report('should not get here')
1581
1582 if 1 " not active due to interrupt
1583 try " not active since :if inactive
1584 call assert_report('should not get here')
1585 finally
1586 call assert_report('should not get here')
1587 endtry
1588 endif
1589
1590 try " not active due to interrupt
1591 call assert_report('should not get here')
1592 finally
1593 call assert_report('should not get here')
1594 endtry
1595 [CODE]
1596 let verify =<< trim [CODE]
1597 call assert_equal('bac', g:Xpath)
1598 [CODE]
1599 call RunInNewVim(test, verify)
1600endfunc
1601
1602func Test_finally_after_throw()
1603 let test =<< trim [CODE]
1604 func Throw()
1605 Xpath 'a'
1606 throw 'xyz'
1607 endfunc
1608
1609 Xpath 'b'
1610 call Throw()
1611 call assert_report('should not get here')
1612
1613 if 1 " not active due to :throw
1614 try " not active since :if inactive
1615 call assert_report('should not get here')
1616 finally
1617 call assert_report('should not get here')
1618 endtry
1619 endif
1620
1621 try " not active due to :throw
1622 call assert_report('should not get here')
1623 finally
1624 call assert_report('should not get here')
1625 endtry
1626 [CODE]
1627 let verify =<< trim [CODE]
1628 call assert_equal('ba', g:Xpath)
1629 [CODE]
1630 call RunInNewVim(test, verify)
1631endfunc
1632
1633"-------------------------------------------------------------------------------
1634" Test 23: :catch clauses for a :try after a :throw {{{1
1635"
1636" If a :try conditional stays inactive due to a preceding :throw,
1637" none of its :catch clauses should be executed.
1638"-------------------------------------------------------------------------------
1639
1640func Test_catch_after_throw()
1641 let test =<< trim [CODE]
1642 try
1643 Xpath 'a'
1644 throw "xyz"
1645 call assert_report('should not get here')
1646
1647 if 1 " not active due to :throw
1648 try " not active since :if inactive
1649 call assert_report('should not get here')
1650 catch /xyz/
1651 call assert_report('should not get here')
1652 endtry
1653 endif
1654 catch /xyz/
1655 Xpath 'b'
1656 endtry
1657
1658 Xpath 'c'
1659 throw "abc"
1660 call assert_report('should not get here')
1661
1662 try " not active due to :throw
1663 call assert_report('should not get here')
1664 catch /abc/
1665 call assert_report('should not get here')
1666 endtry
1667 [CODE]
1668 let verify =<< trim [CODE]
1669 call assert_equal('abc', g:Xpath)
1670 [CODE]
1671 call RunInNewVim(test, verify)
1672endfunc
1673
1674"-------------------------------------------------------------------------------
1675" Test 24: :endtry for a :try after a :throw {{{1
1676"
1677" If a :try conditional stays inactive due to a preceding :throw,
1678" its :endtry should not rethrow the exception to the next surrounding
1679" active :try conditional.
1680"-------------------------------------------------------------------------------
1681
1682func Test_endtry_after_throw()
1683 let test =<< trim [CODE]
1684 try " try 1
1685 try " try 2
1686 Xpath 'a'
1687 throw "xyz" " makes try 2 inactive
1688 call assert_report('should not get here')
1689
1690 try " try 3
1691 call assert_report('should not get here')
1692 endtry " no rethrow to try 1
1693 catch /xyz/ " should catch although try 2 inactive
1694 Xpath 'b'
1695 endtry
1696 catch /xyz/ " try 1 active, but exception already caught
1697 call assert_report('should not get here')
1698 endtry
1699 Xpath 'c'
1700 [CODE]
1701 let verify =<< trim [CODE]
1702 call assert_equal('abc', g:Xpath)
1703 [CODE]
1704 call RunInNewVim(test, verify)
1705endfunc
1706
1707"-------------------------------------------------------------------------------
1708" Test 27: Executing :finally clauses after :return {{{1
1709"
1710" For a :return command dynamically enclosed in a :try/:endtry region,
1711" :finally clauses are executed and the called function is ended.
1712"-------------------------------------------------------------------------------
1713
1714func T27_F()
1715 try
1716 Xpath 'a'
1717 try
1718 Xpath 'b'
1719 return
1720 call assert_report('should not get here')
1721 finally
1722 Xpath 'c'
1723 endtry
1724 Xpath 'd'
1725 finally
1726 Xpath 'e'
1727 endtry
1728 call assert_report('should not get here')
1729endfunc
1730
1731func T27_G()
1732 try
1733 Xpath 'f'
1734 return
1735 call assert_report('should not get here')
1736 finally
1737 Xpath 'g'
1738 call T27_F()
1739 Xpath 'h'
1740 endtry
1741 call assert_report('should not get here')
1742endfunc
1743
1744func T27_H()
1745 try
1746 Xpath 'i'
1747 call T27_G()
1748 Xpath 'j'
1749 finally
1750 Xpath 'k'
1751 return
1752 call assert_report('should not get here')
1753 endtry
1754 call assert_report('should not get here')
1755endfunction
1756
1757func Test_finally_after_return()
1758 XpathINIT
1759 try
1760 Xpath 'l'
1761 call T27_H()
1762 Xpath 'm'
1763 finally
1764 Xpath 'n'
1765 endtry
1766 call assert_equal('lifgabcehjkmn', g:Xpath)
1767endfunc
1768
1769"-------------------------------------------------------------------------------
1770" Test 28: Executing :finally clauses after :finish {{{1
1771"
1772" For a :finish command dynamically enclosed in a :try/:endtry region,
1773" :finally clauses are executed and the sourced file is finished.
1774"
1775" This test executes the bodies of the functions F, G, and H from the
1776" previous test as script files (:return replaced by :finish).
1777"-------------------------------------------------------------------------------
1778
1779func Test_finally_after_finish()
1780 XpathINIT
1781
1782 let scriptF = MakeScript("T27_F")
1783 let scriptG = MakeScript("T27_G", scriptF)
1784 let scriptH = MakeScript("T27_H", scriptG)
1785
1786 try
1787 Xpath 'A'
1788 exec "source" scriptH
1789 Xpath 'B'
1790 finally
1791 Xpath 'C'
1792 endtry
1793 Xpath 'D'
1794 call assert_equal('AifgabcehjkBCD', g:Xpath)
1795 call delete(scriptF)
1796 call delete(scriptG)
1797 call delete(scriptH)
1798endfunc
1799
1800"-------------------------------------------------------------------------------
1801" Test 29: Executing :finally clauses on errors {{{1
1802"
1803" After an error in a command dynamically enclosed in a :try/:endtry
1804" region, :finally clauses are executed and the script processing is
1805" terminated.
1806"-------------------------------------------------------------------------------
1807
1808func Test_finally_after_error_1()
1809 let test =<< trim [CODE]
1810 func F()
1811 while 1
1812 try
1813 Xpath 'a'
1814 while 1
1815 try
1816 Xpath 'b'
1817 asdf " error
1818 call assert_report('should not get here')
1819 finally
1820 Xpath 'c'
1821 endtry | call assert_report('should not get here')
1822 call assert_report('should not get here')
1823 break
1824 endwhile
1825 call assert_report('should not get here')
1826 finally
1827 Xpath 'd'
1828 endtry | call assert_report('should not get here')
1829 call assert_report('should not get here')
1830 break
1831 endwhile
1832 call assert_report('should not get here')
1833 endfunc
1834
1835 while 1
1836 try
1837 Xpath 'e'
1838 while 1
1839 call F()
1840 call assert_report('should not get here')
1841 break
1842 endwhile | call assert_report('should not get here')
1843 call assert_report('should not get here')
1844 finally
1845 Xpath 'f'
1846 endtry | call assert_report('should not get here')
1847 endwhile | call assert_report('should not get here')
1848 call assert_report('should not get here')
1849 [CODE]
1850 let verify =<< trim [CODE]
1851 call assert_equal('eabcdf', g:Xpath)
1852 [CODE]
1853 call RunInNewVim(test, verify)
1854endfunc
1855
1856func Test_finally_after_error_2()
1857 let test =<< trim [CODE]
1858 func G() abort
1859 if 1
1860 try
1861 Xpath 'a'
1862 asdf " error
1863 call assert_report('should not get here')
1864 finally
1865 Xpath 'b'
1866 endtry | Xpath 'c'
1867 endif | Xpath 'd'
1868 call assert_report('should not get here')
1869 endfunc
1870
1871 if 1
1872 try
1873 Xpath 'e'
1874 call G()
1875 call assert_report('should not get here')
1876 finally
1877 Xpath 'f'
1878 endtry | call assert_report('should not get here')
1879 endif | call assert_report('should not get here')
1880 call assert_report('should not get here')
1881 [CODE]
1882 let verify =<< trim [CODE]
1883 call assert_equal('eabf', g:Xpath)
1884 [CODE]
1885 call RunInNewVim(test, verify)
1886endfunc
1887
1888"-------------------------------------------------------------------------------
1889" Test 30: Executing :finally clauses on interrupt {{{1
1890"
1891" After an interrupt in a command dynamically enclosed in
1892" a :try/:endtry region, :finally clauses are executed and the
1893" script processing is terminated.
1894"-------------------------------------------------------------------------------
1895
1896func Test_finally_on_interrupt()
1897 let test =<< trim [CODE]
1898 func F()
1899 try
1900 Xloop 'a'
1901 call interrupt()
1902 call assert_report('should not get here')
1903 finally
1904 Xloop 'b'
1905 endtry
1906 call assert_report('should not get here')
1907 endfunc
1908
1909 try
1910 try
1911 Xpath 'c'
1912 try
1913 Xpath 'd'
1914 call interrupt()
1915 call assert_report('should not get here')
1916 finally
1917 Xpath 'e'
1918 try
1919 Xpath 'f'
1920 try
1921 Xpath 'g'
1922 finally
1923 Xpath 'h'
1924 try
1925 Xpath 'i'
1926 call interrupt()
1927 call assert_report('should not get here')
1928 endtry
1929 call assert_report('should not get here')
1930 endtry
1931 call assert_report('should not get here')
1932 endtry
1933 call assert_report('should not get here')
1934 endtry
1935 call assert_report('should not get here')
1936 finally
1937 Xpath 'j'
1938 try
1939 Xpath 'k'
1940 call F()
1941 call assert_report('should not get here')
1942 finally
1943 Xpath 'l'
1944 try
1945 Xpath 'm'
1946 XloopNEXT
1947 ExecAsScript F
1948 call assert_report('should not get here')
1949 finally
1950 Xpath 'n'
1951 endtry
1952 call assert_report('should not get here')
1953 endtry
1954 call assert_report('should not get here')
1955 endtry
1956 call assert_report('should not get here')
1957 catch /^Vim:Interrupt$/
1958 Xpath 'o'
1959 endtry
1960 [CODE]
1961 let verify =<< trim [CODE]
1962 call assert_equal('cdefghijka1b1lma2b2no', g:Xpath)
1963 [CODE]
1964 call RunInNewVim(test, verify)
1965endfunc
1966
1967"-------------------------------------------------------------------------------
1968" Test 31: Executing :finally clauses after :throw {{{1
1969"
1970" After a :throw dynamically enclosed in a :try/:endtry region,
1971" :finally clauses are executed and the script processing is
1972" terminated.
1973"-------------------------------------------------------------------------------
1974
1975func Test_finally_after_throw_2()
1976 let test =<< trim [CODE]
1977 func F()
1978 try
1979 Xloop 'a'
1980 throw "exception"
1981 call assert_report('should not get here')
1982 finally
1983 Xloop 'b'
1984 endtry
1985 call assert_report('should not get here')
1986 endfunc
1987
1988 try
1989 Xpath 'c'
1990 try
1991 Xpath 'd'
1992 throw "exception"
1993 call assert_report('should not get here')
1994 finally
1995 Xpath 'e'
1996 try
1997 Xpath 'f'
1998 try
1999 Xpath 'g'
2000 finally
2001 Xpath 'h'
2002 try
2003 Xpath 'i'
2004 throw "exception"
2005 call assert_report('should not get here')
2006 endtry
2007 call assert_report('should not get here')
2008 endtry
2009 call assert_report('should not get here')
2010 endtry
2011 call assert_report('should not get here')
2012 endtry
2013 call assert_report('should not get here')
2014 finally
2015 Xpath 'j'
2016 try
2017 Xpath 'k'
2018 call F()
2019 call assert_report('should not get here')
2020 finally
2021 Xpath 'l'
2022 try
2023 Xpath 'm'
2024 XloopNEXT
2025 ExecAsScript F
2026 call assert_report('should not get here')
2027 finally
2028 Xpath 'n'
2029 endtry
2030 call assert_report('should not get here')
2031 endtry
2032 call assert_report('should not get here')
2033 endtry
2034 call assert_report('should not get here')
2035 [CODE]
2036 let verify =<< trim [CODE]
2037 call assert_equal('cdefghijka1b1lma2b2n', g:Xpath)
2038 [CODE]
2039 call RunInNewVim(test, verify)
2040endfunc
2041
2042"-------------------------------------------------------------------------------
2043" Test 34: :finally reason discarded by :continue {{{1
2044"
2045" When a :finally clause is executed due to a :continue, :break,
2046" :return, :finish, error, interrupt or :throw, the jump reason is
2047" discarded by a :continue in the finally clause.
2048"-------------------------------------------------------------------------------
2049
2050func Test_finally_after_continue()
2051 let test =<< trim [CODE]
2052 func C(jump)
2053 XloopNEXT
2054 let loop = 0
2055 while loop < 2
2056 let loop = loop + 1
2057 if loop == 1
2058 try
2059 if a:jump == "continue"
2060 continue
2061 elseif a:jump == "break"
2062 break
2063 elseif a:jump == "return" || a:jump == "finish"
2064 return
2065 elseif a:jump == "error"
2066 asdf
2067 elseif a:jump == "interrupt"
2068 call interrupt()
2069 let dummy = 0
2070 elseif a:jump == "throw"
2071 throw "abc"
2072 endif
2073 finally
2074 continue " discards jump that caused the :finally
2075 call assert_report('should not get here')
2076 endtry
2077 call assert_report('should not get here')
2078 elseif loop == 2
2079 Xloop 'a'
2080 endif
2081 endwhile
2082 endfunc
2083
2084 call C("continue")
2085 Xpath 'b'
2086 call C("break")
2087 Xpath 'c'
2088 call C("return")
2089 Xpath 'd'
2090 let g:jump = "finish"
2091 ExecAsScript C
2092 unlet g:jump
2093 Xpath 'e'
2094 try
2095 call C("error")
2096 Xpath 'f'
2097 finally
2098 Xpath 'g'
2099 try
2100 call C("interrupt")
2101 Xpath 'h'
2102 finally
2103 Xpath 'i'
2104 call C("throw")
2105 Xpath 'j'
2106 endtry
2107 endtry
2108 Xpath 'k'
2109 [CODE]
2110 let verify =<< trim [CODE]
2111 call assert_equal('a2ba3ca4da5ea6fga7hia8jk', g:Xpath)
2112 [CODE]
2113 call RunInNewVim(test, verify)
2114endfunc
2115
2116"-------------------------------------------------------------------------------
2117" Test 35: :finally reason discarded by :break {{{1
2118"
2119" When a :finally clause is executed due to a :continue, :break,
2120" :return, :finish, error, interrupt or :throw, the jump reason is
2121" discarded by a :break in the finally clause.
2122"-------------------------------------------------------------------------------
2123
2124func Test_finally_discard_by_break()
2125 let test =<< trim [CODE]
2126 func B(jump)
2127 XloopNEXT
2128 let loop = 0
2129 while loop < 2
2130 let loop = loop + 1
2131 if loop == 1
2132 try
2133 if a:jump == "continue"
2134 continue
2135 elseif a:jump == "break"
2136 break
2137 elseif a:jump == "return" || a:jump == "finish"
2138 return
2139 elseif a:jump == "error"
2140 asdf
2141 elseif a:jump == "interrupt"
2142 call interrupt()
2143 let dummy = 0
2144 elseif a:jump == "throw"
2145 throw "abc"
2146 endif
2147 finally
2148 break " discards jump that caused the :finally
2149 call assert_report('should not get here')
2150 endtry
2151 elseif loop == 2
2152 call assert_report('should not get here')
2153 endif
2154 endwhile
2155 Xloop 'a'
2156 endfunc
2157
2158 call B("continue")
2159 Xpath 'b'
2160 call B("break")
2161 Xpath 'c'
2162 call B("return")
2163 Xpath 'd'
2164 let g:jump = "finish"
2165 ExecAsScript B
2166 unlet g:jump
2167 Xpath 'e'
2168 try
2169 call B("error")
2170 Xpath 'f'
2171 finally
2172 Xpath 'g'
2173 try
2174 call B("interrupt")
2175 Xpath 'h'
2176 finally
2177 Xpath 'i'
2178 call B("throw")
2179 Xpath 'j'
2180 endtry
2181 endtry
2182 Xpath 'k'
2183 [CODE]
2184 let verify =<< trim [CODE]
2185 call assert_equal('a2ba3ca4da5ea6fga7hia8jk', g:Xpath)
2186 [CODE]
2187 call RunInNewVim(test, verify)
2188endfunc
2189
2190"-------------------------------------------------------------------------------
2191" Test 36: :finally reason discarded by :return {{{1
2192"
2193" When a :finally clause is executed due to a :continue, :break,
2194" :return, :finish, error, interrupt or :throw, the jump reason is
2195" discarded by a :return in the finally clause.
2196"-------------------------------------------------------------------------------
2197
2198func Test_finally_discard_by_return()
2199 let test =<< trim [CODE]
2200 func R(jump, retval) abort
2201 let loop = 0
2202 while loop < 2
2203 let loop = loop + 1
2204 if loop == 1
2205 try
2206 if a:jump == "continue"
2207 continue
2208 elseif a:jump == "break"
2209 break
2210 elseif a:jump == "return"
2211 return
2212 elseif a:jump == "error"
2213 asdf
2214 elseif a:jump == "interrupt"
2215 call interrupt()
2216 let dummy = 0
2217 elseif a:jump == "throw"
2218 throw "abc"
2219 endif
2220 finally
2221 return a:retval " discards jump that caused the :finally
2222 call assert_report('should not get here')
2223 endtry
2224 elseif loop == 2
2225 call assert_report('should not get here')
2226 endif
2227 endwhile
2228 call assert_report('should not get here')
2229 endfunc
2230
2231 let sum = -R("continue", -8)
2232 Xpath 'a'
2233 let sum = sum - R("break", -16)
2234 Xpath 'b'
2235 let sum = sum - R("return", -32)
2236 Xpath 'c'
2237 try
2238 let sum = sum - R("error", -64)
2239 Xpath 'd'
2240 finally
2241 Xpath 'e'
2242 try
2243 let sum = sum - R("interrupt", -128)
2244 Xpath 'f'
2245 finally
2246 Xpath 'g'
2247 let sum = sum - R("throw", -256)
2248 Xpath 'h'
2249 endtry
2250 endtry
2251 Xpath 'i'
2252
2253 let expected = 8 + 16 + 32 + 64 + 128 + 256
2254 call assert_equal(sum, expected)
2255 [CODE]
2256 let verify =<< trim [CODE]
2257 call assert_equal('abcdefghi', g:Xpath)
2258 [CODE]
2259 call RunInNewVim(test, verify)
2260endfunc
2261
2262"-------------------------------------------------------------------------------
2263" Test 37: :finally reason discarded by :finish {{{1
2264"
2265" When a :finally clause is executed due to a :continue, :break,
2266" :return, :finish, error, interrupt or :throw, the jump reason is
2267" discarded by a :finish in the finally clause.
2268"-------------------------------------------------------------------------------
2269
2270func Test_finally_discard_by_finish()
2271 let test =<< trim [CODE]
2272 func F(jump) " not executed as function, transformed to a script
2273 let loop = 0
2274 while loop < 2
2275 let loop = loop + 1
2276 if loop == 1
2277 try
2278 if a:jump == "continue"
2279 continue
2280 elseif a:jump == "break"
2281 break
2282 elseif a:jump == "finish"
2283 finish
2284 elseif a:jump == "error"
2285 asdf
2286 elseif a:jump == "interrupt"
2287 call interrupt()
2288 let dummy = 0
2289 elseif a:jump == "throw"
2290 throw "abc"
2291 endif
2292 finally
2293 finish " discards jump that caused the :finally
2294 call assert_report('should not get here')
2295 endtry
2296 elseif loop == 2
2297 call assert_report('should not get here')
2298 endif
2299 endwhile
2300 call assert_report('should not get here')
2301 endfunc
2302
2303 let scriptF = MakeScript("F")
2304 delfunction F
2305
2306 let g:jump = "continue"
2307 exec "source" scriptF
2308 Xpath 'a'
2309 let g:jump = "break"
2310 exec "source" scriptF
2311 Xpath 'b'
2312 let g:jump = "finish"
2313 exec "source" scriptF
2314 Xpath 'c'
2315 try
2316 let g:jump = "error"
2317 exec "source" scriptF
2318 Xpath 'd'
2319 finally
2320 Xpath 'e'
2321 try
2322 let g:jump = "interrupt"
2323 exec "source" scriptF
2324 Xpath 'f'
2325 finally
2326 Xpath 'g'
2327 try
2328 let g:jump = "throw"
2329 exec "source" scriptF
2330 Xpath 'h'
2331 finally
2332 Xpath 'i'
2333 endtry
2334 endtry
2335 endtry
2336 unlet g:jump
2337 call delete(scriptF)
2338 [CODE]
2339 let verify =<< trim [CODE]
2340 call assert_equal('abcdefghi', g:Xpath)
2341 [CODE]
2342 call RunInNewVim(test, verify)
2343endfunc
2344
2345"-------------------------------------------------------------------------------
2346" Test 38: :finally reason discarded by an error {{{1
2347"
2348" When a :finally clause is executed due to a :continue, :break,
2349" :return, :finish, error, interrupt or :throw, the jump reason is
2350" discarded by an error in the finally clause.
2351"-------------------------------------------------------------------------------
2352
2353func Test_finally_discard_by_error()
2354 let test =<< trim [CODE]
2355 func E(jump)
2356 let loop = 0
2357 while loop < 2
2358 let loop = loop + 1
2359 if loop == 1
2360 try
2361 if a:jump == "continue"
2362 continue
2363 elseif a:jump == "break"
2364 break
2365 elseif a:jump == "return" || a:jump == "finish"
2366 return
2367 elseif a:jump == "error"
2368 asdf
2369 elseif a:jump == "interrupt"
2370 call interrupt()
2371 let dummy = 0
2372 elseif a:jump == "throw"
2373 throw "abc"
2374 endif
2375 finally
2376 asdf " error; discards jump that caused the :finally
2377 endtry
2378 elseif loop == 2
2379 call assert_report('should not get here')
2380 endif
2381 endwhile
2382 call assert_report('should not get here')
2383 endfunc
2384
2385 try
2386 Xpath 'a'
2387 call E("continue")
2388 call assert_report('should not get here')
2389 finally
2390 try
2391 Xpath 'b'
2392 call E("break")
2393 call assert_report('should not get here')
2394 finally
2395 try
2396 Xpath 'c'
2397 call E("return")
2398 call assert_report('should not get here')
2399 finally
2400 try
2401 Xpath 'd'
2402 let g:jump = "finish"
2403 ExecAsScript E
2404 call assert_report('should not get here')
2405 finally
2406 unlet g:jump
2407 try
2408 Xpath 'e'
2409 call E("error")
2410 call assert_report('should not get here')
2411 finally
2412 try
2413 Xpath 'f'
2414 call E("interrupt")
2415 call assert_report('should not get here')
2416 finally
2417 try
2418 Xpath 'g'
2419 call E("throw")
2420 call assert_report('should not get here')
2421 finally
2422 Xpath 'h'
2423 delfunction E
2424 endtry
2425 endtry
2426 endtry
2427 endtry
2428 endtry
2429 endtry
2430 endtry
2431 call assert_report('should not get here')
2432 [CODE]
2433 let verify =<< trim [CODE]
2434 call assert_equal('abcdefgh', g:Xpath)
2435 [CODE]
2436 call RunInNewVim(test, verify)
2437endfunc
2438
2439"-------------------------------------------------------------------------------
2440" Test 39: :finally reason discarded by an interrupt {{{1
2441"
2442" When a :finally clause is executed due to a :continue, :break,
2443" :return, :finish, error, interrupt or :throw, the jump reason is
2444" discarded by an interrupt in the finally clause.
2445"-------------------------------------------------------------------------------
2446
2447func Test_finally_discarded_by_interrupt()
2448 let test =<< trim [CODE]
2449 func I(jump)
2450 let loop = 0
2451 while loop < 2
2452 let loop = loop + 1
2453 if loop == 1
2454 try
2455 if a:jump == "continue"
2456 continue
2457 elseif a:jump == "break"
2458 break
2459 elseif a:jump == "return" || a:jump == "finish"
2460 return
2461 elseif a:jump == "error"
2462 asdf
2463 elseif a:jump == "interrupt"
2464 call interrupt()
2465 let dummy = 0
2466 elseif a:jump == "throw"
2467 throw "abc"
2468 endif
2469 finally
2470 call interrupt()
2471 let dummy = 0
2472 endtry
2473 elseif loop == 2
2474 call assert_report('should not get here')
2475 endif
2476 endwhile
2477 call assert_report('should not get here')
2478 endfunc
2479
2480 try
2481 try
2482 Xpath 'a'
2483 call I("continue")
2484 call assert_report('should not get here')
2485 finally
2486 try
2487 Xpath 'b'
2488 call I("break")
2489 call assert_report('should not get here')
2490 finally
2491 try
2492 Xpath 'c'
2493 call I("return")
2494 call assert_report('should not get here')
2495 finally
2496 try
2497 Xpath 'd'
2498 let g:jump = "finish"
2499 ExecAsScript I
2500 call assert_report('should not get here')
2501 finally
2502 unlet g:jump
2503 try
2504 Xpath 'e'
2505 call I("error")
2506 call assert_report('should not get here')
2507 finally
2508 try
2509 Xpath 'f'
2510 call I("interrupt")
2511 call assert_report('should not get here')
2512 finally
2513 try
2514 Xpath 'g'
2515 call I("throw")
2516 call assert_report('should not get here')
2517 finally
2518 Xpath 'h'
2519 delfunction I
2520 endtry
2521 endtry
2522 endtry
2523 endtry
2524 endtry
2525 endtry
2526 endtry
2527 call assert_report('should not get here')
2528 catch /^Vim:Interrupt$/
2529 Xpath 'A'
2530 endtry
2531 [CODE]
2532 let verify =<< trim [CODE]
2533 call assert_equal('abcdefghA', g:Xpath)
2534 [CODE]
2535 call RunInNewVim(test, verify)
2536endfunc
2537
2538"-------------------------------------------------------------------------------
2539" Test 40: :finally reason discarded by :throw {{{1
2540"
2541" When a :finally clause is executed due to a :continue, :break,
2542" :return, :finish, error, interrupt or :throw, the jump reason is
2543" discarded by a :throw in the finally clause.
2544"-------------------------------------------------------------------------------
2545
2546func Test_finally_discard_by_throw()
2547 let test =<< trim [CODE]
2548 func T(jump)
2549 let loop = 0
2550 while loop < 2
2551 let loop = loop + 1
2552 if loop == 1
2553 try
2554 if a:jump == "continue"
2555 continue
2556 elseif a:jump == "break"
2557 break
2558 elseif a:jump == "return" || a:jump == "finish"
2559 return
2560 elseif a:jump == "error"
2561 asdf
2562 elseif a:jump == "interrupt"
2563 call interrupt()
2564 let dummy = 0
2565 elseif a:jump == "throw"
2566 throw "abc"
2567 endif
2568 finally
2569 throw "xyz" " discards jump that caused the :finally
2570 endtry
2571 elseif loop == 2
2572 call assert_report('should not get here')
2573 endif
2574 endwhile
2575 call assert_report('should not get here')
2576 endfunc
2577
2578 try
2579 Xpath 'a'
2580 call T("continue")
2581 call assert_report('should not get here')
2582 finally
2583 try
2584 Xpath 'b'
2585 call T("break")
2586 call assert_report('should not get here')
2587 finally
2588 try
2589 Xpath 'c'
2590 call T("return")
2591 call assert_report('should not get here')
2592 finally
2593 try
2594 Xpath 'd'
2595 let g:jump = "finish"
2596 ExecAsScript T
2597 call assert_report('should not get here')
2598 finally
2599 unlet g:jump
2600 try
2601 Xpath 'e'
2602 call T("error")
2603 call assert_report('should not get here')
2604 finally
2605 try
2606 Xpath 'f'
2607 call T("interrupt")
2608 call assert_report('should not get here')
2609 finally
2610 try
2611 Xpath 'g'
2612 call T("throw")
2613 call assert_report('should not get here')
2614 finally
2615 Xpath 'h'
2616 delfunction T
2617 endtry
2618 endtry
2619 endtry
2620 endtry
2621 endtry
2622 endtry
2623 endtry
2624 call assert_report('should not get here')
2625 [CODE]
2626 let verify =<< trim [CODE]
2627 call assert_equal('abcdefgh', g:Xpath)
2628 [CODE]
2629 call RunInNewVim(test, verify)
2630endfunc
2631
2632"-------------------------------------------------------------------------------
2633" Test 49: Throwing exceptions across functions {{{1
2634"
2635" When an exception is thrown but not caught inside a function, the
2636" caller is checked for a matching :catch clause.
2637"-------------------------------------------------------------------------------
2638
2639func T49_C()
2640 try
2641 Xpath 'a'
2642 throw "arrgh"
2643 call assert_report('should not get here')
2644 catch /arrgh/
2645 Xpath 'b'
2646 endtry
2647 Xpath 'c'
2648endfunc
2649
2650func T49_T1()
2651 XloopNEXT
2652 try
2653 Xloop 'd'
2654 throw "arrgh"
2655 call assert_report('should not get here')
2656 finally
2657 Xloop 'e'
2658 endtry
2659 Xloop 'f'
2660endfunc
2661
2662func T49_T2()
2663 try
2664 Xpath 'g'
2665 call T49_T1()
2666 call assert_report('should not get here')
2667 finally
2668 Xpath 'h'
2669 endtry
2670 call assert_report('should not get here')
2671endfunc
2672
2673func Test_throw_exception_across_funcs()
2674 XpathINIT
2675 XloopINIT
2676 try
2677 Xpath 'i'
2678 call T49_C() " throw and catch
2679 Xpath 'j'
2680 catch /.*/
2681 call assert_report('should not get here')
2682 endtry
2683
2684 try
2685 Xpath 'k'
2686 call T49_T1() " throw, one level
2687 call assert_report('should not get here')
2688 catch /arrgh/
2689 Xpath 'l'
2690 catch /.*/
2691 call assert_report('should not get here')
2692 endtry
2693
2694 try
2695 Xpath 'm'
2696 call T49_T2() " throw, two levels
2697 call assert_report('should not get here')
2698 catch /arrgh/
2699 Xpath 'n'
2700 catch /.*/
2701 call assert_report('should not get here')
2702 endtry
2703 Xpath 'o'
2704
2705 call assert_equal('iabcjkd2e2lmgd3e3hno', g:Xpath)
2706endfunc
2707
2708"-------------------------------------------------------------------------------
2709" Test 50: Throwing exceptions across script files {{{1
2710"
2711" When an exception is thrown but not caught inside a script file,
2712" the sourcing script or function is checked for a matching :catch
2713" clause.
2714"
2715" This test executes the bodies of the functions C, T1, and T2 from
2716" the previous test as script files (:return replaced by :finish).
2717"-------------------------------------------------------------------------------
2718
2719func T50_F()
2720 try
2721 Xpath 'A'
2722 exec "source" g:scriptC
2723 Xpath 'B'
2724 catch /.*/
2725 call assert_report('should not get here')
2726 endtry
2727
2728 try
2729 Xpath 'C'
2730 exec "source" g:scriptT1
2731 call assert_report('should not get here')
2732 catch /arrgh/
2733 Xpath 'D'
2734 catch /.*/
2735 call assert_report('should not get here')
2736 endtry
2737endfunc
2738
2739func Test_throw_across_script()
2740 XpathINIT
2741 XloopINIT
2742 let g:scriptC = MakeScript("T49_C")
2743 let g:scriptT1 = MakeScript("T49_T1")
2744 let scriptT2 = MakeScript("T49_T2", g:scriptT1)
2745
2746 try
2747 Xpath 'E'
2748 call T50_F()
2749 Xpath 'F'
2750 exec "source" scriptT2
2751 call assert_report('should not get here')
2752 catch /arrgh/
2753 Xpath 'G'
2754 catch /.*/
2755 call assert_report('should not get here')
2756 endtry
2757 Xpath 'H'
2758 call assert_equal('EAabcBCd2e2DFgd3e3hGH', g:Xpath)
2759
2760 call delete(g:scriptC)
2761 call delete(g:scriptT1)
2762 call delete(scriptT2)
2763 unlet g:scriptC g:scriptT1 scriptT2
2764endfunc
2765
Bram Moolenaar1f068232019-11-03 16:17:26 +01002766"-------------------------------------------------------------------------------
2767" Test 87 using (expr) ? funcref : funcref {{{1
2768"
2769" Vim needs to correctly parse the funcref and even when it does
2770" not execute the funcref, it needs to consume the trailing ()
2771"-------------------------------------------------------------------------------
2772
2773func Add2(x1, x2)
2774 return a:x1 + a:x2
2775endfu
2776
2777func GetStr()
2778 return "abcdefghijklmnopqrstuvwxyp"
2779endfu
2780
2781func Test_funcref_with_condexpr()
2782 call assert_equal(5, function('Add2')(2,3))
2783
2784 call assert_equal(3, 1 ? function('Add2')(1,2) : function('Add2')(2,3))
2785 call assert_equal(5, 0 ? function('Add2')(1,2) : function('Add2')(2,3))
2786 " Make sure, GetStr() still works.
2787 call assert_equal('abcdefghijk', GetStr()[0:10])
2788endfunc
2789
Bram Moolenaar4119cf82016-01-17 14:59:01 +01002790" Test 90: Recognizing {} in variable name. {{{1
2791"-------------------------------------------------------------------------------
2792
2793func Test_curlies()
2794 let s:var = 66
2795 let ns = 's'
2796 call assert_equal(66, {ns}:var)
2797
2798 let g:a = {}
2799 let g:b = 't'
2800 let g:a[g:b] = 77
2801 call assert_equal(77, g:a['t'])
2802endfunc
Bram Moolenaara2cce862016-01-02 19:50:04 +01002803
2804"-------------------------------------------------------------------------------
Bram Moolenaarf95534c2016-01-23 21:59:52 +01002805" Test 91: using type(). {{{1
2806"-------------------------------------------------------------------------------
2807
2808func Test_type()
2809 call assert_equal(0, type(0))
2810 call assert_equal(1, type(""))
2811 call assert_equal(2, type(function("tr")))
Bram Moolenaar953cc7f2016-03-19 18:52:29 +01002812 call assert_equal(2, type(function("tr", [8])))
Bram Moolenaarf95534c2016-01-23 21:59:52 +01002813 call assert_equal(3, type([]))
2814 call assert_equal(4, type({}))
Bram Moolenaar5feabe02020-01-30 18:24:53 +01002815 if has('float')
2816 call assert_equal(5, type(0.0))
2817 endif
Bram Moolenaarf95534c2016-01-23 21:59:52 +01002818 call assert_equal(6, type(v:false))
2819 call assert_equal(6, type(v:true))
2820 call assert_equal(7, type(v:none))
2821 call assert_equal(7, type(v:null))
Bram Moolenaarf562e722016-07-19 17:25:25 +02002822 call assert_equal(8, v:t_job)
2823 call assert_equal(9, v:t_channel)
2824 call assert_equal(v:t_number, type(0))
2825 call assert_equal(v:t_string, type(""))
2826 call assert_equal(v:t_func, type(function("tr")))
2827 call assert_equal(v:t_func, type(function("tr", [8])))
2828 call assert_equal(v:t_list, type([]))
2829 call assert_equal(v:t_dict, type({}))
Bram Moolenaar5feabe02020-01-30 18:24:53 +01002830 if has('float')
2831 call assert_equal(v:t_float, type(0.0))
2832 endif
Bram Moolenaarf562e722016-07-19 17:25:25 +02002833 call assert_equal(v:t_bool, type(v:false))
2834 call assert_equal(v:t_bool, type(v:true))
2835 call assert_equal(v:t_none, type(v:none))
2836 call assert_equal(v:t_none, type(v:null))
Bram Moolenaar92b83cc2020-04-25 15:24:44 +02002837 call assert_equal(v:t_string, type(test_null_string()))
2838 call assert_equal(v:t_func, type(test_null_function()))
2839 call assert_equal(v:t_func, type(test_null_partial()))
2840 call assert_equal(v:t_list, type(test_null_list()))
2841 call assert_equal(v:t_dict, type(test_null_dict()))
2842 if has('job')
2843 call assert_equal(v:t_job, type(test_null_job()))
2844 endif
2845 if has('channel')
2846 call assert_equal(v:t_channel, type(test_null_channel()))
2847 endif
2848 call assert_equal(v:t_blob, type(test_null_blob()))
Bram Moolenaarf562e722016-07-19 17:25:25 +02002849
Bram Moolenaar7c215c52020-02-29 13:43:27 +01002850 call assert_fails("call type(test_void())", 'E685:')
2851 call assert_fails("call type(test_unknown())", 'E685:')
Bram Moolenaar17a13432016-01-24 14:22:10 +01002852
2853 call assert_equal(0, 0 + v:false)
2854 call assert_equal(1, 0 + v:true)
2855 call assert_equal(0, 0 + v:none)
2856 call assert_equal(0, 0 + v:null)
2857
Bram Moolenaarf48aa162016-01-24 17:54:24 +01002858 call assert_equal('v:false', '' . v:false)
2859 call assert_equal('v:true', '' . v:true)
2860 call assert_equal('v:none', '' . v:none)
2861 call assert_equal('v:null', '' . v:null)
Bram Moolenaar6039c7f2016-01-24 15:05:32 +01002862
2863 call assert_true(v:false == 0)
2864 call assert_false(v:false != 0)
2865 call assert_true(v:true == 1)
2866 call assert_false(v:true != 1)
2867 call assert_false(v:true == v:false)
2868 call assert_true(v:true != v:false)
2869
2870 call assert_true(v:null == 0)
2871 call assert_false(v:null != 0)
2872 call assert_true(v:none == 0)
2873 call assert_false(v:none != 0)
Bram Moolenaar04369222016-01-24 17:21:29 +01002874
2875 call assert_true(v:false is v:false)
2876 call assert_true(v:true is v:true)
2877 call assert_true(v:none is v:none)
2878 call assert_true(v:null is v:null)
2879
2880 call assert_false(v:false isnot v:false)
2881 call assert_false(v:true isnot v:true)
2882 call assert_false(v:none isnot v:none)
2883 call assert_false(v:null isnot v:null)
2884
2885 call assert_false(v:false is 0)
2886 call assert_false(v:true is 1)
2887 call assert_false(v:true is v:false)
2888 call assert_false(v:none is 0)
2889 call assert_false(v:null is 0)
2890 call assert_false(v:null is v:none)
2891
2892 call assert_true(v:false isnot 0)
2893 call assert_true(v:true isnot 1)
2894 call assert_true(v:true isnot v:false)
2895 call assert_true(v:none isnot 0)
2896 call assert_true(v:null isnot 0)
2897 call assert_true(v:null isnot v:none)
Bram Moolenaar65591002016-01-24 21:51:57 +01002898
2899 call assert_equal(v:false, eval(string(v:false)))
2900 call assert_equal(v:true, eval(string(v:true)))
2901 call assert_equal(v:none, eval(string(v:none)))
2902 call assert_equal(v:null, eval(string(v:null)))
Bram Moolenaar767d8c12016-01-25 20:22:54 +01002903
Bram Moolenaar15550002016-01-31 18:45:24 +01002904 call assert_equal(v:false, copy(v:false))
2905 call assert_equal(v:true, copy(v:true))
2906 call assert_equal(v:none, copy(v:none))
2907 call assert_equal(v:null, copy(v:null))
2908
2909 call assert_equal([v:false], deepcopy([v:false]))
2910 call assert_equal([v:true], deepcopy([v:true]))
2911 call assert_equal([v:none], deepcopy([v:none]))
2912 call assert_equal([v:null], deepcopy([v:null]))
2913
Bram Moolenaar767d8c12016-01-25 20:22:54 +01002914 call assert_true(empty(v:false))
2915 call assert_false(empty(v:true))
2916 call assert_true(empty(v:null))
2917 call assert_true(empty(v:none))
Bram Moolenaar6650a692016-01-26 19:59:10 +01002918
2919 func ChangeYourMind()
Bram Moolenaar1e115362019-01-09 23:01:02 +01002920 try
2921 return v:true
2922 finally
2923 return 'something else'
2924 endtry
Bram Moolenaar6650a692016-01-26 19:59:10 +01002925 endfunc
2926
2927 call ChangeYourMind()
Bram Moolenaarf95534c2016-01-23 21:59:52 +01002928endfunc
2929
2930"-------------------------------------------------------------------------------
Bram Moolenaarea8c2192016-02-07 19:27:53 +01002931" Test 92: skipping code {{{1
2932"-------------------------------------------------------------------------------
2933
2934func Test_skip()
2935 let Fn = function('Test_type')
2936 call assert_false(0 && Fn[1])
2937 call assert_false(0 && string(Fn))
2938 call assert_false(0 && len(Fn))
2939 let l = []
2940 call assert_false(0 && l[1])
2941 call assert_false(0 && string(l))
2942 call assert_false(0 && len(l))
2943 let f = 1.0
2944 call assert_false(0 && f[1])
2945 call assert_false(0 && string(f))
2946 call assert_false(0 && len(f))
2947 let sp = v:null
2948 call assert_false(0 && sp[1])
2949 call assert_false(0 && string(sp))
2950 call assert_false(0 && len(sp))
2951
2952endfunc
2953
2954"-------------------------------------------------------------------------------
Bram Moolenaar18dfb442016-05-31 22:31:23 +02002955" Test 93: :echo and string() {{{1
2956"-------------------------------------------------------------------------------
2957
2958func Test_echo_and_string()
2959 " String
2960 let a = 'foo bar'
2961 redir => result
2962 echo a
2963 echo string(a)
2964 redir END
2965 let l = split(result, "\n")
2966 call assert_equal(["foo bar",
2967 \ "'foo bar'"], l)
2968
2969 " Float
2970 if has('float')
2971 let a = -1.2e0
2972 redir => result
2973 echo a
2974 echo string(a)
2975 redir END
2976 let l = split(result, "\n")
2977 call assert_equal(["-1.2",
2978 \ "-1.2"], l)
2979 endif
2980
2981 " Funcref
2982 redir => result
2983 echo function('string')
2984 echo string(function('string'))
2985 redir END
2986 let l = split(result, "\n")
2987 call assert_equal(["string",
2988 \ "function('string')"], l)
2989
2990 " Recursive dictionary
2991 let a = {}
2992 let a["a"] = a
2993 redir => result
2994 echo a
2995 echo string(a)
2996 redir END
2997 let l = split(result, "\n")
2998 call assert_equal(["{'a': {...}}",
2999 \ "{'a': {...}}"], l)
3000
3001 " Recursive list
3002 let a = [0]
3003 let a[0] = a
3004 redir => result
3005 echo a
3006 echo string(a)
3007 redir END
3008 let l = split(result, "\n")
3009 call assert_equal(["[[...]]",
3010 \ "[[...]]"], l)
3011
3012 " Empty dictionaries in a list
3013 let a = {}
3014 redir => result
3015 echo [a, a, a]
3016 echo string([a, a, a])
3017 redir END
3018 let l = split(result, "\n")
3019 call assert_equal(["[{}, {}, {}]",
3020 \ "[{}, {}, {}]"], l)
3021
3022 " Empty dictionaries in a dictionary
3023 let a = {}
3024 let b = {"a": a, "b": a}
3025 redir => result
3026 echo b
3027 echo string(b)
3028 redir END
3029 let l = split(result, "\n")
3030 call assert_equal(["{'a': {}, 'b': {}}",
3031 \ "{'a': {}, 'b': {}}"], l)
3032
3033 " Empty lists in a list
3034 let a = []
3035 redir => result
3036 echo [a, a, a]
3037 echo string([a, a, a])
3038 redir END
3039 let l = split(result, "\n")
3040 call assert_equal(["[[], [], []]",
3041 \ "[[], [], []]"], l)
3042
3043 " Empty lists in a dictionary
3044 let a = []
3045 let b = {"a": a, "b": a}
3046 redir => result
3047 echo b
3048 echo string(b)
3049 redir END
3050 let l = split(result, "\n")
3051 call assert_equal(["{'a': [], 'b': []}",
3052 \ "{'a': [], 'b': []}"], l)
3053
3054 " Dictionaries in a list
3055 let a = {"one": "yes", "two": "yes", "three": "yes"}
3056 redir => result
3057 echo [a, a, a]
3058 echo string([a, a, a])
3059 redir END
3060 let l = split(result, "\n")
3061 call assert_equal(["[{'one': 'yes', 'two': 'yes', 'three': 'yes'}, {...}, {...}]",
3062 \ "[{'one': 'yes', 'two': 'yes', 'three': 'yes'}, {'one': 'yes', 'two': 'yes', 'three': 'yes'}, {'one': 'yes', 'two': 'yes', 'three': 'yes'}]"], l)
3063
3064 " Dictionaries in a dictionary
3065 let a = {"one": "yes", "two": "yes", "three": "yes"}
3066 let b = {"a": a, "b": a}
3067 redir => result
3068 echo b
3069 echo string(b)
3070 redir END
3071 let l = split(result, "\n")
3072 call assert_equal(["{'a': {'one': 'yes', 'two': 'yes', 'three': 'yes'}, 'b': {...}}",
3073 \ "{'a': {'one': 'yes', 'two': 'yes', 'three': 'yes'}, 'b': {'one': 'yes', 'two': 'yes', 'three': 'yes'}}"], l)
3074
3075 " Lists in a list
3076 let a = [1, 2, 3]
3077 redir => result
3078 echo [a, a, a]
3079 echo string([a, a, a])
3080 redir END
3081 let l = split(result, "\n")
3082 call assert_equal(["[[1, 2, 3], [...], [...]]",
3083 \ "[[1, 2, 3], [1, 2, 3], [1, 2, 3]]"], l)
3084
3085 " Lists in a dictionary
3086 let a = [1, 2, 3]
3087 let b = {"a": a, "b": a}
3088 redir => result
3089 echo b
3090 echo string(b)
3091 redir END
3092 let l = split(result, "\n")
3093 call assert_equal(["{'a': [1, 2, 3], 'b': [...]}",
3094 \ "{'a': [1, 2, 3], 'b': [1, 2, 3]}"], l)
3095
Bram Moolenaar1363a302020-04-12 13:50:26 +02003096 call assert_fails('echo &:', 'E112:')
3097 call assert_fails('echo &g:', 'E112:')
3098 call assert_fails('echo &l:', 'E112:')
3099
Bram Moolenaar18dfb442016-05-31 22:31:23 +02003100endfunc
3101
3102"-------------------------------------------------------------------------------
Bram Moolenaar22fcfad2016-07-01 18:17:26 +02003103" Test 94: 64-bit Numbers {{{1
3104"-------------------------------------------------------------------------------
3105
3106func Test_num64()
Bram Moolenaar22fcfad2016-07-01 18:17:26 +02003107 call assert_notequal( 4294967296, 0)
3108 call assert_notequal(-4294967296, 0)
3109 call assert_equal( 4294967296, 0xFFFFffff + 1)
3110 call assert_equal(-4294967296, -0xFFFFffff - 1)
3111
3112 call assert_equal( 9223372036854775807, 1 / 0)
3113 call assert_equal(-9223372036854775807, -1 / 0)
Bram Moolenaar7a40ea22017-01-22 18:34:57 +01003114 call assert_equal(-9223372036854775807 - 1, 0 / 0)
Bram Moolenaar22fcfad2016-07-01 18:17:26 +02003115
Bram Moolenaar5feabe02020-01-30 18:24:53 +01003116 if has('float')
3117 call assert_equal( 0x7FFFffffFFFFffff, float2nr( 1.0e150))
3118 call assert_equal(-0x7FFFffffFFFFffff, float2nr(-1.0e150))
3119 endif
Bram Moolenaar22fcfad2016-07-01 18:17:26 +02003120
3121 let rng = range(0xFFFFffff, 0x100000001)
3122 call assert_equal([0xFFFFffff, 0x100000000, 0x100000001], rng)
3123 call assert_equal(0x100000001, max(rng))
3124 call assert_equal(0xFFFFffff, min(rng))
3125 call assert_equal(rng, sort(range(0x100000001, 0xFFFFffff, -1), 'N'))
3126endfunc
3127
3128"-------------------------------------------------------------------------------
Bram Moolenaar70bcd732017-01-12 22:20:54 +01003129" Test 95: lines of :append, :change, :insert {{{1
3130"-------------------------------------------------------------------------------
3131
3132function! DefineFunction(name, body)
3133 let func = join(['function! ' . a:name . '()'] + a:body + ['endfunction'], "\n")
3134 exec func
3135endfunction
3136
3137func Test_script_lines()
3138 " :append
3139 try
Bram Moolenaar1e115362019-01-09 23:01:02 +01003140 call DefineFunction('T_Append', [
3141 \ 'append',
3142 \ 'py <<EOS',
3143 \ '.',
3144 \ ])
Bram Moolenaar70bcd732017-01-12 22:20:54 +01003145 catch
Bram Moolenaar1e115362019-01-09 23:01:02 +01003146 call assert_report("Can't define function")
Bram Moolenaar70bcd732017-01-12 22:20:54 +01003147 endtry
3148 try
Bram Moolenaar1e115362019-01-09 23:01:02 +01003149 call DefineFunction('T_Append', [
3150 \ 'append',
3151 \ 'abc',
3152 \ ])
3153 call assert_report("Shouldn't be able to define function")
Bram Moolenaar70bcd732017-01-12 22:20:54 +01003154 catch
Bram Moolenaar1e115362019-01-09 23:01:02 +01003155 call assert_exception('Vim(function):E126: Missing :endfunction')
Bram Moolenaar70bcd732017-01-12 22:20:54 +01003156 endtry
3157
3158 " :change
3159 try
Bram Moolenaar1e115362019-01-09 23:01:02 +01003160 call DefineFunction('T_Change', [
3161 \ 'change',
3162 \ 'py <<EOS',
3163 \ '.',
3164 \ ])
Bram Moolenaar70bcd732017-01-12 22:20:54 +01003165 catch
Bram Moolenaar1e115362019-01-09 23:01:02 +01003166 call assert_report("Can't define function")
Bram Moolenaar70bcd732017-01-12 22:20:54 +01003167 endtry
3168 try
Bram Moolenaar1e115362019-01-09 23:01:02 +01003169 call DefineFunction('T_Change', [
3170 \ 'change',
3171 \ 'abc',
3172 \ ])
3173 call assert_report("Shouldn't be able to define function")
Bram Moolenaar70bcd732017-01-12 22:20:54 +01003174 catch
Bram Moolenaar1e115362019-01-09 23:01:02 +01003175 call assert_exception('Vim(function):E126: Missing :endfunction')
Bram Moolenaar70bcd732017-01-12 22:20:54 +01003176 endtry
3177
3178 " :insert
3179 try
Bram Moolenaar1e115362019-01-09 23:01:02 +01003180 call DefineFunction('T_Insert', [
3181 \ 'insert',
3182 \ 'py <<EOS',
3183 \ '.',
3184 \ ])
Bram Moolenaar70bcd732017-01-12 22:20:54 +01003185 catch
Bram Moolenaar1e115362019-01-09 23:01:02 +01003186 call assert_report("Can't define function")
Bram Moolenaar70bcd732017-01-12 22:20:54 +01003187 endtry
3188 try
Bram Moolenaar1e115362019-01-09 23:01:02 +01003189 call DefineFunction('T_Insert', [
3190 \ 'insert',
3191 \ 'abc',
3192 \ ])
3193 call assert_report("Shouldn't be able to define function")
Bram Moolenaar70bcd732017-01-12 22:20:54 +01003194 catch
Bram Moolenaar1e115362019-01-09 23:01:02 +01003195 call assert_exception('Vim(function):E126: Missing :endfunction')
Bram Moolenaar70bcd732017-01-12 22:20:54 +01003196 endtry
3197endfunc
3198
3199"-------------------------------------------------------------------------------
Bram Moolenaar478af672017-04-10 22:22:42 +02003200" Test 96: line continuation {{{1
3201"
Bram Moolenaar1e115362019-01-09 23:01:02 +01003202" Undefined behavior was detected by ubsan with line continuation
3203" after an empty line.
Bram Moolenaar478af672017-04-10 22:22:42 +02003204"-------------------------------------------------------------------------------
3205func Test_script_emty_line_continuation()
3206
3207 \
3208endfunc
3209
3210"-------------------------------------------------------------------------------
Bram Moolenaar863e80b2017-06-04 20:30:00 +02003211" Test 97: bitwise functions {{{1
3212"-------------------------------------------------------------------------------
3213func Test_bitwise_functions()
3214 " and
3215 call assert_equal(127, and(127, 127))
3216 call assert_equal(16, and(127, 16))
Bram Moolenaar073e4b92019-08-18 23:01:56 +02003217 eval 127->and(16)->assert_equal(16)
Bram Moolenaar863e80b2017-06-04 20:30:00 +02003218 call assert_equal(0, and(127, 128))
Bram Moolenaar863e80b2017-06-04 20:30:00 +02003219 call assert_fails("call and([], 1)", 'E745:')
3220 call assert_fails("call and({}, 1)", 'E728:')
Bram Moolenaar5feabe02020-01-30 18:24:53 +01003221 if has('float')
3222 call assert_fails("call and(1.0, 1)", 'E805:')
3223 call assert_fails("call and(1, 1.0)", 'E805:')
3224 endif
Bram Moolenaar863e80b2017-06-04 20:30:00 +02003225 call assert_fails("call and(1, [])", 'E745:')
3226 call assert_fails("call and(1, {})", 'E728:')
3227 " or
3228 call assert_equal(23, or(16, 7))
3229 call assert_equal(15, or(8, 7))
Bram Moolenaar073e4b92019-08-18 23:01:56 +02003230 eval 8->or(7)->assert_equal(15)
Bram Moolenaar863e80b2017-06-04 20:30:00 +02003231 call assert_equal(123, or(0, 123))
Bram Moolenaar863e80b2017-06-04 20:30:00 +02003232 call assert_fails("call or([], 1)", 'E745:')
3233 call assert_fails("call or({}, 1)", 'E728:')
Bram Moolenaar5feabe02020-01-30 18:24:53 +01003234 if has('float')
3235 call assert_fails("call or(1.0, 1)", 'E805:')
3236 call assert_fails("call or(1, 1.0)", 'E805:')
3237 endif
Bram Moolenaar863e80b2017-06-04 20:30:00 +02003238 call assert_fails("call or(1, [])", 'E745:')
3239 call assert_fails("call or(1, {})", 'E728:')
3240 " xor
3241 call assert_equal(0, xor(127, 127))
3242 call assert_equal(111, xor(127, 16))
Bram Moolenaar073e4b92019-08-18 23:01:56 +02003243 eval 127->xor(16)->assert_equal(111)
Bram Moolenaar863e80b2017-06-04 20:30:00 +02003244 call assert_equal(255, xor(127, 128))
Bram Moolenaar5feabe02020-01-30 18:24:53 +01003245 if has('float')
3246 call assert_fails("call xor(1.0, 1)", 'E805:')
3247 call assert_fails("call xor(1, 1.0)", 'E805:')
3248 endif
Bram Moolenaar863e80b2017-06-04 20:30:00 +02003249 call assert_fails("call xor([], 1)", 'E745:')
3250 call assert_fails("call xor({}, 1)", 'E728:')
Bram Moolenaar863e80b2017-06-04 20:30:00 +02003251 call assert_fails("call xor(1, [])", 'E745:')
3252 call assert_fails("call xor(1, {})", 'E728:')
3253 " invert
3254 call assert_equal(65408, and(invert(127), 65535))
Bram Moolenaar073e4b92019-08-18 23:01:56 +02003255 eval 127->invert()->and(65535)->assert_equal(65408)
Bram Moolenaar863e80b2017-06-04 20:30:00 +02003256 call assert_equal(65519, and(invert(16), 65535))
3257 call assert_equal(65407, and(invert(128), 65535))
Bram Moolenaar5feabe02020-01-30 18:24:53 +01003258 if has('float')
3259 call assert_fails("call invert(1.0)", 'E805:')
3260 endif
Bram Moolenaar863e80b2017-06-04 20:30:00 +02003261 call assert_fails("call invert([])", 'E745:')
3262 call assert_fails("call invert({})", 'E728:')
3263endfunc
3264
Bram Moolenaar6f9a4762017-06-22 20:39:17 +02003265" Test using bang after user command {{{1
3266func Test_user_command_with_bang()
3267 command -bang Nieuw let nieuw = 1
3268 Ni!
3269 call assert_equal(1, nieuw)
3270 unlet nieuw
3271 delcommand Nieuw
3272endfunc
3273
Bram Moolenaarb9adef72020-01-02 14:31:22 +01003274func Test_script_expand_sfile()
3275 let lines =<< trim END
3276 func s:snr()
3277 return expand('<sfile>')
3278 endfunc
3279 let g:result = s:snr()
3280 END
3281 call writefile(lines, 'Xexpand')
3282 source Xexpand
3283 call assert_match('<SNR>\d\+_snr', g:result)
3284 source Xexpand
3285 call assert_match('<SNR>\d\+_snr', g:result)
3286
3287 call delete('Xexpand')
3288 unlet g:result
3289endfunc
3290
Bram Moolenaarff697e62019-02-12 22:28:33 +01003291func Test_compound_assignment_operators()
3292 " Test for number
3293 let x = 1
3294 let x += 10
3295 call assert_equal(11, x)
3296 let x -= 5
3297 call assert_equal(6, x)
3298 let x *= 4
3299 call assert_equal(24, x)
3300 let x /= 3
3301 call assert_equal(8, x)
3302 let x %= 3
3303 call assert_equal(2, x)
3304 let x .= 'n'
3305 call assert_equal('2n', x)
3306
Bram Moolenaare21c1582019-03-02 11:57:09 +01003307 " Test special cases: division or modulus with 0.
3308 let x = 1
3309 let x /= 0
Bram Moolenaar82f654e2020-02-17 22:12:50 +01003310 call assert_equal(0x7FFFFFFFFFFFFFFF, x)
Bram Moolenaare21c1582019-03-02 11:57:09 +01003311
3312 let x = -1
3313 let x /= 0
Bram Moolenaar82f654e2020-02-17 22:12:50 +01003314 call assert_equal(-0x7FFFFFFFFFFFFFFF, x)
Bram Moolenaare21c1582019-03-02 11:57:09 +01003315
3316 let x = 0
3317 let x /= 0
Bram Moolenaar82f654e2020-02-17 22:12:50 +01003318 call assert_equal(-0x7FFFFFFFFFFFFFFF - 1, x)
Bram Moolenaare21c1582019-03-02 11:57:09 +01003319
3320 let x = 1
3321 let x %= 0
3322 call assert_equal(0, x)
3323
3324 let x = -1
3325 let x %= 0
3326 call assert_equal(0, x)
3327
3328 let x = 0
3329 let x %= 0
3330 call assert_equal(0, x)
3331
Bram Moolenaarff697e62019-02-12 22:28:33 +01003332 " Test for string
3333 let x = 'str'
3334 let x .= 'ing'
3335 call assert_equal('string', x)
3336 let x += 1
3337 call assert_equal(1, x)
Bram Moolenaarff697e62019-02-12 22:28:33 +01003338
3339 if has('float')
Bram Moolenaar5feabe02020-01-30 18:24:53 +01003340 " Test for float
3341 let x -= 1.5
3342 call assert_equal(-0.5, x)
3343 let x = 0.5
3344 let x += 4.5
3345 call assert_equal(5.0, x)
3346 let x -= 1.5
3347 call assert_equal(3.5, x)
3348 let x *= 3.0
3349 call assert_equal(10.5, x)
3350 let x /= 2.5
3351 call assert_equal(4.2, x)
3352 call assert_fails('let x %= 0.5', 'E734')
3353 call assert_fails('let x .= "f"', 'E734')
Bram Moolenaar8b633132020-03-20 18:20:51 +01003354 let x = !3.14
3355 call assert_equal(0.0, x)
Bram Moolenaarea04a6e2020-04-23 13:38:02 +02003356
3357 " integer and float operations
3358 let x = 1
3359 let x *= 2.1
3360 call assert_equal(2.1, x)
3361 let x = 1
3362 let x /= 0.25
3363 call assert_equal(4.0, x)
3364 let x = 1
3365 call assert_fails('let x %= 0.25', 'E734:')
3366 let x = 1
3367 call assert_fails('let x .= 0.25', 'E734:')
3368 let x = 1.0
3369 call assert_fails('let x += [1.1]', 'E734:')
Bram Moolenaarff697e62019-02-12 22:28:33 +01003370 endif
3371
3372 " Test for environment variable
3373 let $FOO = 1
3374 call assert_fails('let $FOO += 1', 'E734')
3375 call assert_fails('let $FOO -= 1', 'E734')
3376 call assert_fails('let $FOO *= 1', 'E734')
3377 call assert_fails('let $FOO /= 1', 'E734')
3378 call assert_fails('let $FOO %= 1', 'E734')
3379 let $FOO .= 's'
3380 call assert_equal('1s', $FOO)
3381 unlet $FOO
3382
3383 " Test for option variable (type: number)
3384 let &scrolljump = 1
3385 let &scrolljump += 5
3386 call assert_equal(6, &scrolljump)
3387 let &scrolljump -= 2
3388 call assert_equal(4, &scrolljump)
3389 let &scrolljump *= 3
3390 call assert_equal(12, &scrolljump)
3391 let &scrolljump /= 2
3392 call assert_equal(6, &scrolljump)
3393 let &scrolljump %= 5
3394 call assert_equal(1, &scrolljump)
3395 call assert_fails('let &scrolljump .= "j"', 'E734')
3396 set scrolljump&vim
3397
3398 " Test for register
3399 let @/ = 1
3400 call assert_fails('let @/ += 1', 'E734')
3401 call assert_fails('let @/ -= 1', 'E734')
3402 call assert_fails('let @/ *= 1', 'E734')
3403 call assert_fails('let @/ /= 1', 'E734')
3404 call assert_fails('let @/ %= 1', 'E734')
3405 let @/ .= 's'
3406 call assert_equal('1s', @/)
3407 let @/ = ''
3408endfunc
3409
Bram Moolenaar7e0868e2020-04-19 17:24:53 +02003410func Test_unlet_env()
3411 let $TESTVAR = 'yes'
3412 call assert_equal('yes', $TESTVAR)
3413 call assert_fails('lockvar $TESTVAR', 'E940')
3414 call assert_fails('unlockvar $TESTVAR', 'E940')
3415 call assert_equal('yes', $TESTVAR)
3416 if 0
3417 unlet $TESTVAR
3418 endif
3419 call assert_equal('yes', $TESTVAR)
3420 unlet $TESTVAR
3421 call assert_equal('', $TESTVAR)
3422endfunc
3423
Bram Moolenaarc3e92c12019-03-23 14:23:07 +01003424func Test_refcount()
3425 " Immediate values
3426 call assert_equal(-1, test_refcount(1))
3427 call assert_equal(-1, test_refcount('s'))
3428 call assert_equal(-1, test_refcount(v:true))
3429 call assert_equal(0, test_refcount([]))
3430 call assert_equal(0, test_refcount({}))
3431 call assert_equal(0, test_refcount(0zff))
3432 call assert_equal(0, test_refcount({-> line('.')}))
3433 if has('float')
3434 call assert_equal(-1, test_refcount(0.1))
3435 endif
3436 if has('job')
3437 call assert_equal(0, test_refcount(job_start([&shell, &shellcmdflag, 'echo .'])))
3438 endif
3439
3440 " No refcount types
3441 let x = 1
3442 call assert_equal(-1, test_refcount(x))
3443 let x = 's'
3444 call assert_equal(-1, test_refcount(x))
3445 let x = v:true
3446 call assert_equal(-1, test_refcount(x))
3447 if has('float')
3448 let x = 0.1
3449 call assert_equal(-1, test_refcount(x))
3450 endif
3451
3452 " Check refcount
3453 let x = []
3454 call assert_equal(1, test_refcount(x))
3455
3456 let x = {}
Bram Moolenaarce90e362019-09-08 18:58:44 +02003457 call assert_equal(1, x->test_refcount())
Bram Moolenaarc3e92c12019-03-23 14:23:07 +01003458
3459 let x = 0zff
3460 call assert_equal(1, test_refcount(x))
3461
3462 let X = {-> line('.')}
3463 call assert_equal(1, test_refcount(X))
3464 let Y = X
3465 call assert_equal(2, test_refcount(X))
3466
3467 if has('job')
3468 let job = job_start([&shell, &shellcmdflag, 'echo .'])
3469 call assert_equal(1, test_refcount(job))
3470 call assert_equal(1, test_refcount(job_getchannel(job)))
3471 call assert_equal(1, test_refcount(job))
3472 endif
3473
3474 " Function arguments, copying and unassigning
3475 func ExprCheck(x, i)
3476 let i = a:i + 1
3477 call assert_equal(i, test_refcount(a:x))
3478 let Y = a:x
3479 call assert_equal(i + 1, test_refcount(a:x))
3480 call assert_equal(test_refcount(a:x), test_refcount(Y))
3481 let Y = 0
3482 call assert_equal(i, test_refcount(a:x))
3483 endfunc
3484 call ExprCheck([], 0)
3485 call ExprCheck({}, 0)
3486 call ExprCheck(0zff, 0)
3487 call ExprCheck({-> line('.')}, 0)
3488 if has('job')
3489 call ExprCheck(job, 1)
3490 call ExprCheck(job_getchannel(job), 1)
3491 call job_stop(job)
3492 endif
3493 delfunc ExprCheck
3494
3495 " Regarding function
3496 func Func(x) abort
3497 call assert_equal(2, test_refcount(function('Func')))
3498 call assert_equal(0, test_refcount(funcref('Func')))
3499 endfunc
3500 call assert_equal(1, test_refcount(function('Func')))
3501 call assert_equal(0, test_refcount(function('Func', [1])))
3502 call assert_equal(0, test_refcount(funcref('Func')))
3503 call assert_equal(0, test_refcount(funcref('Func', [1])))
3504 let X = function('Func')
3505 let Y = X
3506 call assert_equal(1, test_refcount(X))
3507 let X = function('Func', [1])
3508 let Y = X
3509 call assert_equal(2, test_refcount(X))
3510 let X = funcref('Func')
3511 let Y = X
3512 call assert_equal(2, test_refcount(X))
3513 let X = funcref('Func', [1])
3514 let Y = X
3515 call assert_equal(2, test_refcount(X))
3516 unlet X
3517 unlet Y
3518 call Func(1)
3519 delfunc Func
3520
3521 " Function with dict
3522 func DictFunc() dict
3523 call assert_equal(3, test_refcount(self))
3524 endfunc
3525 let d = {'Func': function('DictFunc')}
3526 call assert_equal(1, test_refcount(d))
3527 call assert_equal(0, test_refcount(d.Func))
3528 call d.Func()
3529 unlet d
3530 delfunc DictFunc
3531endfunc
3532
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01003533" Test for missing :endif, :endfor, :endwhile and :endtry {{{1
3534func Test_missing_end()
3535 call writefile(['if 2 > 1', 'echo ">"'], 'Xscript')
3536 call assert_fails('source Xscript', 'E171:')
3537 call writefile(['for i in range(5)', 'echo i'], 'Xscript')
3538 call assert_fails('source Xscript', 'E170:')
3539 call writefile(['while v:true', 'echo "."'], 'Xscript')
3540 call assert_fails('source Xscript', 'E170:')
3541 call writefile(['try', 'echo "."'], 'Xscript')
3542 call assert_fails('source Xscript', 'E600:')
3543 call delete('Xscript')
Bram Moolenaar818fc9a2020-02-21 17:54:45 +01003544
3545 " Using endfor with :while
3546 let caught_e732 = 0
3547 try
3548 while v:true
3549 endfor
3550 catch /E732:/
3551 let caught_e732 = 1
3552 endtry
3553 call assert_equal(1, caught_e732)
3554
3555 " Using endwhile with :for
3556 let caught_e733 = 0
3557 try
3558 for i in range(1)
3559 endwhile
3560 catch /E733:/
3561 let caught_e733 = 1
3562 endtry
3563 call assert_equal(1, caught_e733)
3564
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02003565 " Using endfunc with :if
3566 call assert_fails('exe "if 1 | endfunc | endif"', 'E193:')
3567
Bram Moolenaar818fc9a2020-02-21 17:54:45 +01003568 " Missing 'in' in a :for statement
3569 call assert_fails('for i range(1) | endfor', 'E690:')
Bram Moolenaarea04a6e2020-04-23 13:38:02 +02003570
3571 " Incorrect number of variables in for
3572 call assert_fails('for [i,] in range(3) | endfor', 'E475:')
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01003573endfunc
3574
3575" Test for deep nesting of if/for/while/try statements {{{1
3576func Test_deep_nest()
Bram Moolenaar494e9062020-05-31 21:28:02 +02003577 CheckRunVimInTerminal
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01003578
3579 let lines =<< trim [SCRIPT]
3580 " Deep nesting of if ... endif
3581 func Test1()
3582 let @a = join(repeat(['if v:true'], 51), "\n")
3583 let @a ..= "\n"
3584 let @a ..= join(repeat(['endif'], 51), "\n")
3585 @a
3586 let @a = ''
3587 endfunc
3588
3589 " Deep nesting of for ... endfor
3590 func Test2()
3591 let @a = join(repeat(['for i in [1]'], 51), "\n")
3592 let @a ..= "\n"
3593 let @a ..= join(repeat(['endfor'], 51), "\n")
3594 @a
3595 let @a = ''
3596 endfunc
3597
3598 " Deep nesting of while ... endwhile
3599 func Test3()
3600 let @a = join(repeat(['while v:true'], 51), "\n")
3601 let @a ..= "\n"
3602 let @a ..= join(repeat(['endwhile'], 51), "\n")
3603 @a
3604 let @a = ''
3605 endfunc
3606
3607 " Deep nesting of try ... endtry
3608 func Test4()
3609 let @a = join(repeat(['try'], 51), "\n")
3610 let @a ..= "\necho v:true\n"
3611 let @a ..= join(repeat(['endtry'], 51), "\n")
3612 @a
3613 let @a = ''
3614 endfunc
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02003615
3616 " Deep nesting of function ... endfunction
3617 func Test5()
3618 let @a = join(repeat(['function X()'], 51), "\n")
3619 let @a ..= "\necho v:true\n"
3620 let @a ..= join(repeat(['endfunction'], 51), "\n")
3621 @a
3622 let @a = ''
3623 endfunc
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01003624 [SCRIPT]
3625 call writefile(lines, 'Xscript')
3626
3627 let buf = RunVimInTerminal('-S Xscript', {'rows': 6})
3628
3629 " Deep nesting of if ... endif
3630 call term_sendkeys(buf, ":call Test1()\n")
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +02003631 call TermWait(buf)
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01003632 call WaitForAssert({-> assert_match('^E579:', term_getline(buf, 5))})
3633
3634 " Deep nesting of for ... endfor
3635 call term_sendkeys(buf, ":call Test2()\n")
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +02003636 call TermWait(buf)
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01003637 call WaitForAssert({-> assert_match('^E585:', term_getline(buf, 5))})
3638
3639 " Deep nesting of while ... endwhile
3640 call term_sendkeys(buf, ":call Test3()\n")
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +02003641 call TermWait(buf)
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01003642 call WaitForAssert({-> assert_match('^E585:', term_getline(buf, 5))})
3643
3644 " Deep nesting of try ... endtry
3645 call term_sendkeys(buf, ":call Test4()\n")
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +02003646 call TermWait(buf)
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01003647 call WaitForAssert({-> assert_match('^E601:', term_getline(buf, 5))})
3648
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02003649 " Deep nesting of function ... endfunction
3650 call term_sendkeys(buf, ":call Test5()\n")
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +02003651 call TermWait(buf)
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02003652 call WaitForAssert({-> assert_match('^E1058:', term_getline(buf, 4))})
3653 call term_sendkeys(buf, "\<C-C>\n")
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +02003654 call TermWait(buf)
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02003655
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01003656 "let l = ''
3657 "for i in range(1, 6)
3658 " let l ..= term_getline(buf, i) . "\n"
3659 "endfor
3660 "call assert_report(l)
3661
3662 call StopVimInTerminal(buf)
3663 call delete('Xscript')
3664endfunc
3665
Bram Moolenaar8b633132020-03-20 18:20:51 +01003666" Test for errors in converting to float from various types {{{1
3667func Test_float_conversion_errors()
3668 if has('float')
3669 call assert_fails('let x = 4.0 % 2.0', 'E804')
3670 call assert_fails('echo 1.1[0]', 'E806')
3671 call assert_fails('echo sort([function("min"), 1], "f")', 'E891:')
3672 call assert_fails('echo 3.2 == "vim"', 'E892:')
3673 call assert_fails('echo sort([[], 1], "f")', 'E893:')
3674 call assert_fails('echo sort([{}, 1], "f")', 'E894:')
3675 call assert_fails('echo 3.2 == v:true', 'E362:')
3676 call assert_fails('echo 3.2 == v:none', 'E907:')
3677 endif
3678endfunc
3679
Bram Moolenaar8e6cbb72020-07-01 14:38:12 +02003680" invalid function names {{{1
Bram Moolenaar08f41572020-04-20 16:50:00 +02003681func Test_invalid_function_names()
3682 " function name not starting with capital
3683 let caught_e128 = 0
3684 try
3685 func! g:test()
3686 echo "test"
3687 endfunc
3688 catch /E128:/
3689 let caught_e128 = 1
3690 endtry
3691 call assert_equal(1, caught_e128)
3692
3693 " function name includes a colon
3694 let caught_e884 = 0
3695 try
3696 func! b:test()
3697 echo "test"
3698 endfunc
3699 catch /E884:/
3700 let caught_e884 = 1
3701 endtry
3702 call assert_equal(1, caught_e884)
3703
3704 " function name folowed by #
3705 let caught_e128 = 0
3706 try
3707 func! test2() "#
3708 echo "test2"
3709 endfunc
3710 catch /E128:/
3711 let caught_e128 = 1
3712 endtry
3713 call assert_equal(1, caught_e128)
3714
3715 " function name starting with/without "g:", buffer-local funcref.
3716 function! g:Foo(n)
3717 return 'called Foo(' . a:n . ')'
3718 endfunction
3719 let b:my_func = function('Foo')
3720 call assert_equal('called Foo(1)', b:my_func(1))
3721 call assert_equal('called Foo(2)', g:Foo(2))
3722 call assert_equal('called Foo(3)', Foo(3))
3723 delfunc g:Foo
3724
3725 " script-local function used in Funcref must exist.
3726 let lines =<< trim END
3727 func s:Testje()
3728 return "foo"
3729 endfunc
3730 let Bar = function('s:Testje')
3731 call assert_equal(0, exists('s:Testje'))
3732 call assert_equal(1, exists('*s:Testje'))
3733 call assert_equal(1, exists('Bar'))
3734 call assert_equal(1, exists('*Bar'))
3735 END
3736 call writefile(lines, 'Xscript')
3737 source Xscript
3738 call delete('Xscript')
3739endfunc
3740
Bram Moolenaar8e6cbb72020-07-01 14:38:12 +02003741" substring and variable name {{{1
Bram Moolenaar08f41572020-04-20 16:50:00 +02003742func Test_substring_var()
3743 let str = 'abcdef'
3744 let n = 3
3745 call assert_equal('def', str[n:])
3746 call assert_equal('abcd', str[:n])
3747 call assert_equal('d', str[n:n])
3748 unlet n
3749 let nn = 3
3750 call assert_equal('def', str[nn:])
3751 call assert_equal('abcd', str[:nn])
3752 call assert_equal('d', str[nn:nn])
3753 unlet nn
3754 let b:nn = 4
3755 call assert_equal('ef', str[b:nn:])
3756 call assert_equal('abcde', str[:b:nn])
3757 call assert_equal('e', str[b:nn:b:nn])
3758 unlet b:nn
3759endfunc
3760
Bram Moolenaar8e6cbb72020-07-01 14:38:12 +02003761" Test using s: with a typed command {{{1
3762func Test_typed_script_var()
3763 CheckRunVimInTerminal
3764
3765 let buf = RunVimInTerminal('', {'rows': 6})
3766
3767 " Deep nesting of if ... endif
3768 call term_sendkeys(buf, ":echo get(s:, 'foo', 'x')\n")
3769 call TermWait(buf)
3770 call WaitForAssert({-> assert_match('^E116:', term_getline(buf, 5))})
3771
3772 call StopVimInTerminal(buf)
3773endfunc
3774
Bram Moolenaar863e80b2017-06-04 20:30:00 +02003775"-------------------------------------------------------------------------------
Bram Moolenaarf49e2402015-12-30 15:59:25 +01003776" Modelines {{{1
Bram Moolenaar1f068232019-11-03 16:17:26 +01003777" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
Bram Moolenaarf49e2402015-12-30 15:59:25 +01003778"-------------------------------------------------------------------------------