blob: 2ca4e752e4c89571f107901f229f4792dfe0b348 [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 Moolenaar8c5a2782019-08-07 23:07:07 +02006
Bram Moolenaarf49e2402015-12-30 15:59:25 +01007"-------------------------------------------------------------------------------
8" Test environment {{{1
9"-------------------------------------------------------------------------------
10
Bram Moolenaar1e115362019-01-09 23:01:02 +010011com! XpathINIT let g:Xpath = ''
Bram Moolenaarf49e2402015-12-30 15:59:25 +010012com! -nargs=1 -bar Xpath let g:Xpath = g:Xpath . <args>
13
14" Append a message to the "messages" file
Bram Moolenaar1e115362019-01-09 23:01:02 +010015func Xout(text)
Bram Moolenaarf49e2402015-12-30 15:59:25 +010016 split messages
17 $put =a:text
18 wq
19endfunc
20
21com! -nargs=1 Xout call Xout(<args>)
22
23" MakeScript() - Make a script file from a function. {{{2
24"
25" Create a script that consists of the body of the function a:funcname.
26" Replace any ":return" by a ":finish", any argument variable by a global
Bram Moolenaare21c1582019-03-02 11:57:09 +010027" variable, and every ":call" by a ":source" for the next following argument
Bram Moolenaarf49e2402015-12-30 15:59:25 +010028" in the variable argument list. This function is useful if similar tests are
29" to be made for a ":return" from a function call or a ":finish" in a script
30" file.
Bram Moolenaar1e115362019-01-09 23:01:02 +010031func MakeScript(funcname, ...)
Bram Moolenaarf49e2402015-12-30 15:59:25 +010032 let script = tempname()
33 execute "redir! >" . script
34 execute "function" a:funcname
35 redir END
36 execute "edit" script
37 " Delete the "function" and the "endfunction" lines. Do not include the
38 " word "function" in the pattern since it might be translated if LANG is
39 " set. When MakeScript() is being debugged, this deletes also the debugging
40 " output of its line 3 and 4.
41 exec '1,/.*' . a:funcname . '(.*)/d'
42 /^\d*\s*endfunction\>/,$d
43 %s/^\d*//e
44 %s/return/finish/e
45 %s/\<a:\(\h\w*\)/g:\1/ge
46 normal gg0
47 let cnt = 0
48 while search('\<call\s*\%(\u\|s:\)\w*\s*(.*)', 'W') > 0
49 let cnt = cnt + 1
50 s/\<call\s*\%(\u\|s:\)\w*\s*(.*)/\='source ' . a:{cnt}/
51 endwhile
52 g/^\s*$/d
53 write
54 bwipeout
55 return script
Bram Moolenaar1e115362019-01-09 23:01:02 +010056endfunc
Bram Moolenaarf49e2402015-12-30 15:59:25 +010057
58" ExecAsScript - Source a temporary script made from a function. {{{2
59"
60" Make a temporary script file from the function a:funcname, ":source" it, and
Bram Moolenaarf4f79b82016-01-25 20:38:30 +010061" delete it afterwards. However, if an exception is thrown the file may remain,
62" the caller should call DeleteTheScript() afterwards.
63let s:script_name = ''
Bram Moolenaarf49e2402015-12-30 15:59:25 +010064function! ExecAsScript(funcname)
65 " Make a script from the function passed as argument.
Bram Moolenaarf4f79b82016-01-25 20:38:30 +010066 let s:script_name = MakeScript(a:funcname)
Bram Moolenaarf49e2402015-12-30 15:59:25 +010067
68 " Source and delete the script.
Bram Moolenaarf4f79b82016-01-25 20:38:30 +010069 exec "source" s:script_name
70 call delete(s:script_name)
71 let s:script_name = ''
Bram Moolenaarf49e2402015-12-30 15:59:25 +010072endfunction
73
Bram Moolenaarf4f79b82016-01-25 20:38:30 +010074function! DeleteTheScript()
75 if s:script_name
76 call delete(s:script_name)
77 let s:script_name = ''
78 endif
79endfunc
80
Bram Moolenaarf49e2402015-12-30 15:59:25 +010081com! -nargs=1 -bar ExecAsScript call ExecAsScript(<f-args>)
82
83
84"-------------------------------------------------------------------------------
85" Test 1: :endwhile in function {{{1
86"
87" Detect if a broken loop is (incorrectly) reactivated by the
88" :endwhile. Use a :return to prevent an endless loop, and make
89" this test first to get a meaningful result on an error before other
90" tests will hang.
91"-------------------------------------------------------------------------------
92
93function! T1_F()
94 Xpath 'a'
95 let first = 1
96 while 1
97 Xpath 'b'
98 if first
99 Xpath 'c'
100 let first = 0
101 break
102 else
103 Xpath 'd'
104 return
105 endif
106 endwhile
107endfunction
108
109function! T1_G()
110 Xpath 'h'
111 let first = 1
112 while 1
113 Xpath 'i'
114 if first
115 Xpath 'j'
116 let first = 0
117 break
118 else
119 Xpath 'k'
120 return
121 endif
122 if 1 " unmatched :if
123 endwhile
124endfunction
125
126func Test_endwhile_function()
127 XpathINIT
128 call T1_F()
129 Xpath 'F'
130
131 try
132 call T1_G()
133 catch
134 " Catch missing :endif
135 call assert_true(v:exception =~ 'E171')
136 Xpath 'x'
137 endtry
138 Xpath 'G'
139
140 call assert_equal('abcFhijxG', g:Xpath)
141endfunc
142
143"-------------------------------------------------------------------------------
144" Test 2: :endwhile in script {{{1
145"
146" Detect if a broken loop is (incorrectly) reactivated by the
147" :endwhile. Use a :finish to prevent an endless loop, and place
148" this test before others that might hang to get a meaningful result
149" on an error.
150"
151" This test executes the bodies of the functions T1_F and T1_G from
152" the previous test as script files (:return replaced by :finish).
153"-------------------------------------------------------------------------------
154
155func Test_endwhile_script()
156 XpathINIT
157 ExecAsScript T1_F
158 Xpath 'F'
Bram Moolenaarf4f79b82016-01-25 20:38:30 +0100159 call DeleteTheScript()
Bram Moolenaarf49e2402015-12-30 15:59:25 +0100160
161 try
162 ExecAsScript T1_G
163 catch
164 " Catch missing :endif
165 call assert_true(v:exception =~ 'E171')
166 Xpath 'x'
167 endtry
168 Xpath 'G'
Bram Moolenaarf4f79b82016-01-25 20:38:30 +0100169 call DeleteTheScript()
Bram Moolenaarf49e2402015-12-30 15:59:25 +0100170
171 call assert_equal('abcFhijxG', g:Xpath)
172endfunc
173
174"-------------------------------------------------------------------------------
175" Test 3: :if, :elseif, :while, :continue, :break {{{1
176"-------------------------------------------------------------------------------
177
178function Test_if_while()
179 XpathINIT
180 if 1
181 Xpath 'a'
182 let loops = 3
183 while loops > -1 " main loop: loops == 3, 2, 1 (which breaks)
184 if loops <= 0
185 let break_err = 1
186 let loops = -1
187 else
188 Xpath 'b' . loops
189 endif
190 if (loops == 2)
191 while loops == 2 " dummy loop
192 Xpath 'c' . loops
193 let loops = loops - 1
194 continue " stop dummy loop
195 Xpath 'd' . loops
196 endwhile
197 continue " continue main loop
198 Xpath 'e' . loops
199 elseif (loops == 1)
200 let p = 1
201 while p " dummy loop
202 Xpath 'f' . loops
203 let p = 0
204 break " break dummy loop
205 Xpath 'g' . loops
206 endwhile
207 Xpath 'h' . loops
208 unlet p
209 break " break main loop
210 Xpath 'i' . loops
211 endif
212 if (loops > 0)
213 Xpath 'j' . loops
214 endif
215 while loops == 3 " dummy loop
216 let loops = loops - 1
217 endwhile " end dummy loop
218 endwhile " end main loop
219 Xpath 'k'
220 else
221 Xpath 'l'
222 endif
223 Xpath 'm'
224 if exists("break_err")
225 Xpath 'm'
226 unlet break_err
227 endif
228
229 unlet loops
230
231 call assert_equal('ab3j3b2c2b1f1h1km', g:Xpath)
232endfunc
233
234"-------------------------------------------------------------------------------
235" Test 4: :return {{{1
236"-------------------------------------------------------------------------------
237
238function! T4_F()
239 if 1
240 Xpath 'a'
241 let loops = 3
242 while loops > 0 " 3: 2: 1:
243 Xpath 'b' . loops
244 if (loops == 2)
245 Xpath 'c' . loops
246 return
247 Xpath 'd' . loops
248 endif
249 Xpath 'e' . loops
250 let loops = loops - 1
251 endwhile
252 Xpath 'f'
253 else
254 Xpath 'g'
255 endif
256endfunction
257
258function Test_return()
259 XpathINIT
260 call T4_F()
261 Xpath '4'
262
263 call assert_equal('ab3e3b2c24', g:Xpath)
264endfunction
265
266
267"-------------------------------------------------------------------------------
268" Test 5: :finish {{{1
269"
270" This test executes the body of the function T4_F from the previous
271" test as a script file (:return replaced by :finish).
272"-------------------------------------------------------------------------------
273
274function Test_finish()
275 XpathINIT
276 ExecAsScript T4_F
277 Xpath '5'
Bram Moolenaarf4f79b82016-01-25 20:38:30 +0100278 call DeleteTheScript()
Bram Moolenaarf49e2402015-12-30 15:59:25 +0100279
280 call assert_equal('ab3e3b2c25', g:Xpath)
281endfunction
282
283
284
285"-------------------------------------------------------------------------------
286" Test 6: Defining functions in :while loops {{{1
287"
288" Functions can be defined inside other functions. An inner function
289" gets defined when the outer function is executed. Functions may
290" also be defined inside while loops. Expressions in braces for
291" defining the function name are allowed.
292"
293" The functions are defined when sourcing the script, only the
294" resulting path is checked in the test function.
295"-------------------------------------------------------------------------------
296
297XpathINIT
298
299" The command CALL collects the argument of all its invocations in "calls"
300" when used from a function (that is, when the global variable "calls" needs
301" the "g:" prefix). This is to check that the function code is skipped when
302" the function is defined. For inner functions, do so only if the outer
303" function is not being executed.
304"
305let calls = ""
306com! -nargs=1 CALL
Bram Moolenaar1e115362019-01-09 23:01:02 +0100307 \ if !exists("calls") && !exists("outer") |
308 \ let g:calls = g:calls . <args> |
309 \ endif
Bram Moolenaarf49e2402015-12-30 15:59:25 +0100310
311let i = 0
312while i < 3
313 let i = i + 1
314 if i == 1
315 Xpath 'a'
316 function! F1(arg)
317 CALL a:arg
318 let outer = 1
319
320 let j = 0
321 while j < 1
322 Xpath 'b'
323 let j = j + 1
324 function! G1(arg)
325 CALL a:arg
326 endfunction
327 Xpath 'c'
328 endwhile
329 endfunction
330 Xpath 'd'
331
332 continue
333 endif
334
335 Xpath 'e' . i
336 function! F{i}(i, arg)
337 CALL a:arg
338 let outer = 1
339
340 if a:i == 3
341 Xpath 'f'
342 endif
343 let k = 0
344 while k < 3
345 Xpath 'g' . k
346 let k = k + 1
347 function! G{a:i}{k}(arg)
348 CALL a:arg
349 endfunction
350 Xpath 'h' . k
351 endwhile
352 endfunction
353 Xpath 'i'
354
355endwhile
356
357if exists("*G1")
358 Xpath 'j'
359endif
360if exists("*F1")
361 call F1("F1")
362 if exists("*G1")
Bram Moolenaar1e115362019-01-09 23:01:02 +0100363 call G1("G1")
Bram Moolenaarf49e2402015-12-30 15:59:25 +0100364 endif
365endif
366
367if exists("G21") || exists("G22") || exists("G23")
368 Xpath 'k'
369endif
370if exists("*F2")
371 call F2(2, "F2")
372 if exists("*G21")
Bram Moolenaar1e115362019-01-09 23:01:02 +0100373 call G21("G21")
Bram Moolenaarf49e2402015-12-30 15:59:25 +0100374 endif
375 if exists("*G22")
Bram Moolenaar1e115362019-01-09 23:01:02 +0100376 call G22("G22")
Bram Moolenaarf49e2402015-12-30 15:59:25 +0100377 endif
378 if exists("*G23")
Bram Moolenaar1e115362019-01-09 23:01:02 +0100379 call G23("G23")
Bram Moolenaarf49e2402015-12-30 15:59:25 +0100380 endif
381endif
382
383if exists("G31") || exists("G32") || exists("G33")
384 Xpath 'l'
385endif
386if exists("*F3")
387 call F3(3, "F3")
388 if exists("*G31")
Bram Moolenaar1e115362019-01-09 23:01:02 +0100389 call G31("G31")
Bram Moolenaarf49e2402015-12-30 15:59:25 +0100390 endif
391 if exists("*G32")
Bram Moolenaar1e115362019-01-09 23:01:02 +0100392 call G32("G32")
Bram Moolenaarf49e2402015-12-30 15:59:25 +0100393 endif
394 if exists("*G33")
Bram Moolenaar1e115362019-01-09 23:01:02 +0100395 call G33("G33")
Bram Moolenaarf49e2402015-12-30 15:59:25 +0100396 endif
397endif
398
399Xpath 'm'
400
401let g:test6_result = g:Xpath
402let g:test6_calls = calls
403
404unlet calls
405delfunction F1
406delfunction G1
407delfunction F2
408delfunction G21
409delfunction G22
410delfunction G23
411delfunction G31
412delfunction G32
413delfunction G33
414
415function Test_defining_functions()
416 call assert_equal('ade2ie3ibcg0h1g1h2g2h3fg0h1g1h2g2h3m', g:test6_result)
417 call assert_equal('F1G1F2G21G22G23F3G31G32G33', g:test6_calls)
418endfunc
419
420"-------------------------------------------------------------------------------
Bram Moolenaara2cce862016-01-02 19:50:04 +0100421" Test 7: Continuing on errors outside functions {{{1
422"
423" On an error outside a function, the script processing continues
424" at the line following the outermost :endif or :endwhile. When not
425" inside an :if or :while, the script processing continues at the next
426" line.
427"-------------------------------------------------------------------------------
428
429XpathINIT
430
431if 1
432 Xpath 'a'
433 while 1
434 Xpath 'b'
435 asdf
436 Xpath 'c'
437 break
438 endwhile | Xpath 'd'
439 Xpath 'e'
440endif | Xpath 'f'
441Xpath 'g'
442
443while 1
444 Xpath 'h'
445 if 1
446 Xpath 'i'
447 asdf
448 Xpath 'j'
449 endif | Xpath 'k'
450 Xpath 'l'
451 break
452endwhile | Xpath 'm'
453Xpath 'n'
454
455asdf
456Xpath 'o'
457
458asdf | Xpath 'p'
459Xpath 'q'
460
461let g:test7_result = g:Xpath
462
463func Test_error_in_script()
464 call assert_equal('abghinoq', g:test7_result)
465endfunc
466
467"-------------------------------------------------------------------------------
468" Test 8: Aborting and continuing on errors inside functions {{{1
469"
470" On an error inside a function without the "abort" attribute, the
471" script processing continues at the next line (unless the error was
472" in a :return command). On an error inside a function with the
473" "abort" attribute, the function is aborted and the script processing
474" continues after the function call; the value -1 is returned then.
475"-------------------------------------------------------------------------------
476
477XpathINIT
478
479function! T8_F()
480 if 1
481 Xpath 'a'
482 while 1
483 Xpath 'b'
484 asdf
485 Xpath 'c'
486 asdf | Xpath 'd'
487 Xpath 'e'
488 break
489 endwhile
490 Xpath 'f'
491 endif | Xpath 'g'
492 Xpath 'h'
493
494 while 1
495 Xpath 'i'
496 if 1
497 Xpath 'j'
498 asdf
499 Xpath 'k'
500 asdf | Xpath 'l'
501 Xpath 'm'
502 endif
503 Xpath 'n'
504 break
505 endwhile | Xpath 'o'
506 Xpath 'p'
507
508 return novar " returns (default return value 0)
509 Xpath 'q'
510 return 1 " not reached
511endfunction
512
513function! T8_G() abort
514 if 1
515 Xpath 'r'
516 while 1
517 Xpath 's'
518 asdf " returns -1
519 Xpath 't'
520 break
521 endwhile
522 Xpath 'v'
523 endif | Xpath 'w'
524 Xpath 'x'
525
526 return -4 " not reached
527endfunction
528
529function! T8_H() abort
530 while 1
531 Xpath 'A'
532 if 1
533 Xpath 'B'
534 asdf " returns -1
535 Xpath 'C'
536 endif
537 Xpath 'D'
538 break
539 endwhile | Xpath 'E'
540 Xpath 'F'
541
542 return -4 " not reached
543endfunction
544
545" Aborted functions (T8_G and T8_H) return -1.
546let g:test8_sum = (T8_F() + 1) - 4 * T8_G() - 8 * T8_H()
547Xpath 'X'
548let g:test8_result = g:Xpath
549
550func Test_error_in_function()
551 call assert_equal(13, g:test8_sum)
552 call assert_equal('abcefghijkmnoprsABX', g:test8_result)
553
554 delfunction T8_F
555 delfunction T8_G
556 delfunction T8_H
557endfunc
558
559
560"-------------------------------------------------------------------------------
561" Test 9: Continuing after aborted functions {{{1
562"
563" When a function with the "abort" attribute is aborted due to an
564" error, the next function back in the call hierarchy without an
565" "abort" attribute continues; the value -1 is returned then.
566"-------------------------------------------------------------------------------
567
568XpathINIT
569
570function! F() abort
571 Xpath 'a'
572 let result = G() " not aborted
573 Xpath 'b'
574 if result != 2
575 Xpath 'c'
576 endif
577 return 1
578endfunction
579
580function! G() " no abort attribute
581 Xpath 'd'
582 if H() != -1 " aborted
583 Xpath 'e'
584 endif
585 Xpath 'f'
586 return 2
587endfunction
588
589function! H() abort
590 Xpath 'g'
591 call I() " aborted
592 Xpath 'h'
593 return 4
594endfunction
595
596function! I() abort
597 Xpath 'i'
598 asdf " error
599 Xpath 'j'
600 return 8
601endfunction
602
603if F() != 1
604 Xpath 'k'
605endif
606
607let g:test9_result = g:Xpath
608
609delfunction F
610delfunction G
611delfunction H
612delfunction I
613
614func Test_func_abort()
615 call assert_equal('adgifb', g:test9_result)
616endfunc
617
618
619"-------------------------------------------------------------------------------
620" Test 10: :if, :elseif, :while argument parsing {{{1
621"
622" A '"' or '|' in an argument expression must not be mixed up with
623" a comment or a next command after a bar. Parsing errors should
624" be recognized.
625"-------------------------------------------------------------------------------
626
627XpathINIT
628
629function! MSG(enr, emsg)
630 let english = v:lang == "C" || v:lang =~ '^[Ee]n'
631 if a:enr == ""
632 Xout "TODO: Add message number for:" a:emsg
633 let v:errmsg = ":" . v:errmsg
634 endif
635 let match = 1
636 if v:errmsg !~ '^'.a:enr.':' || (english && v:errmsg !~ a:emsg)
637 let match = 0
638 if v:errmsg == ""
639 Xout "Message missing."
640 else
Bram Moolenaara4208962019-08-24 20:50:19 +0200641 let v:errmsg = v:errmsg->escape('"')
Bram Moolenaara2cce862016-01-02 19:50:04 +0100642 Xout "Unexpected message:" v:errmsg
643 endif
644 endif
645 return match
Bram Moolenaar1e115362019-01-09 23:01:02 +0100646endfunc
Bram Moolenaara2cce862016-01-02 19:50:04 +0100647
648if 1 || strlen("\"") | Xpath 'a'
649 Xpath 'b'
650endif
651Xpath 'c'
652
653if 0
654elseif 1 || strlen("\"") | Xpath 'd'
655 Xpath 'e'
656endif
657Xpath 'f'
658
659while 1 || strlen("\"") | Xpath 'g'
660 Xpath 'h'
661 break
662endwhile
663Xpath 'i'
664
665let v:errmsg = ""
666if 1 ||| strlen("\"") | Xpath 'j'
667 Xpath 'k'
668endif
669Xpath 'l'
670if !MSG('E15', "Invalid expression")
671 Xpath 'm'
672endif
673
674let v:errmsg = ""
675if 0
676elseif 1 ||| strlen("\"") | Xpath 'n'
677 Xpath 'o'
678endif
679Xpath 'p'
680if !MSG('E15', "Invalid expression")
681 Xpath 'q'
682endif
683
684let v:errmsg = ""
685while 1 ||| strlen("\"") | Xpath 'r'
686 Xpath 's'
687 break
688endwhile
689Xpath 't'
690if !MSG('E15', "Invalid expression")
691 Xpath 'u'
692endif
693
694let g:test10_result = g:Xpath
695delfunction MSG
696
697func Test_expr_parsing()
698 call assert_equal('abcdefghilpt', g:test10_result)
699endfunc
700
701
702"-------------------------------------------------------------------------------
703" Test 11: :if, :elseif, :while argument evaluation after abort {{{1
704"
705" When code is skipped over due to an error, the boolean argument to
706" an :if, :elseif, or :while must not be evaluated.
707"-------------------------------------------------------------------------------
708
709XpathINIT
710
711let calls = 0
712
713function! P(num)
714 let g:calls = g:calls + a:num " side effect on call
715 return 0
716endfunction
717
718if 1
719 Xpath 'a'
720 asdf " error
721 Xpath 'b'
722 if P(1) " should not be called
723 Xpath 'c'
724 elseif !P(2) " should not be called
725 Xpath 'd'
726 else
727 Xpath 'e'
728 endif
729 Xpath 'f'
730 while P(4) " should not be called
731 Xpath 'g'
732 endwhile
733 Xpath 'h'
734endif
735Xpath 'x'
736
737let g:test11_calls = calls
738let g:test11_result = g:Xpath
739
740unlet calls
741delfunction P
742
743func Test_arg_abort()
744 call assert_equal(0, g:test11_calls)
745 call assert_equal('ax', g:test11_result)
746endfunc
747
748
749"-------------------------------------------------------------------------------
750" Test 12: Expressions in braces in skipped code {{{1
751"
752" In code skipped over due to an error or inactive conditional,
753" an expression in braces as part of a variable or function name
754" should not be evaluated.
755"-------------------------------------------------------------------------------
756
757XpathINIT
758
759function! NULL()
760 Xpath 'a'
761 return 0
762endfunction
763
764function! ZERO()
765 Xpath 'b'
766 return 0
767endfunction
768
769function! F0()
770 Xpath 'c'
771endfunction
772
773function! F1(arg)
774 Xpath 'e'
775endfunction
776
777let V0 = 1
778
779Xpath 'f'
780echo 0 ? F{NULL() + V{ZERO()}}() : 1
781
782Xpath 'g'
783if 0
784 Xpath 'h'
785 call F{NULL() + V{ZERO()}}()
786endif
787
788Xpath 'i'
789if 1
790 asdf " error
791 Xpath 'j'
792 call F1(F{NULL() + V{ZERO()}}())
793endif
794
795Xpath 'k'
796if 1
797 asdf " error
798 Xpath 'l'
799 call F{NULL() + V{ZERO()}}()
800endif
801
802let g:test12_result = g:Xpath
803
804func Test_braces_skipped()
805 call assert_equal('fgik', g:test12_result)
806endfunc
807
808
809"-------------------------------------------------------------------------------
810" Test 13: Failure in argument evaluation for :while {{{1
811"
812" A failure in the expression evaluation for the condition of a :while
813" causes the whole :while loop until the matching :endwhile being
814" ignored. Continuation is at the next following line.
815"-------------------------------------------------------------------------------
816
817XpathINIT
818
819Xpath 'a'
820while asdf
821 Xpath 'b'
822 while 1
823 Xpath 'c'
824 break
825 endwhile
826 Xpath 'd'
827 break
828endwhile
829Xpath 'e'
830
831while asdf | Xpath 'f' | endwhile | Xpath 'g'
832Xpath 'h'
833let g:test13_result = g:Xpath
834
835func Test_while_fail()
836 call assert_equal('aeh', g:test13_result)
837endfunc
838
839
840"-------------------------------------------------------------------------------
841" Test 14: Failure in argument evaluation for :if {{{1
842"
843" A failure in the expression evaluation for the condition of an :if
844" does not cause the corresponding :else or :endif being matched to
845" a previous :if/:elseif. Neither of both branches of the failed :if
846" are executed.
847"-------------------------------------------------------------------------------
848
849XpathINIT
850
851function! F()
852 Xpath 'a'
853 let x = 0
854 if x " false
855 Xpath 'b'
856 elseif !x " always true
857 Xpath 'c'
858 let x = 1
859 if g:boolvar " possibly undefined
860 Xpath 'd'
861 else
862 Xpath 'e'
863 endif
864 Xpath 'f'
865 elseif x " never executed
866 Xpath 'g'
867 endif
868 Xpath 'h'
869endfunction
870
871let boolvar = 1
872call F()
873Xpath '-'
874
875unlet boolvar
876call F()
877let g:test14_result = g:Xpath
878
879delfunction F
880
881func Test_if_fail()
882 call assert_equal('acdfh-acfh', g:test14_result)
883endfunc
884
885
886"-------------------------------------------------------------------------------
887" Test 15: Failure in argument evaluation for :if (bar) {{{1
888"
889" Like previous test, except that the failing :if ... | ... | :endif
890" is in a single line.
891"-------------------------------------------------------------------------------
892
893XpathINIT
894
895function! F()
896 Xpath 'a'
897 let x = 0
898 if x " false
899 Xpath 'b'
900 elseif !x " always true
901 Xpath 'c'
902 let x = 1
903 if g:boolvar | Xpath 'd' | else | Xpath 'e' | endif
904 Xpath 'f'
905 elseif x " never executed
906 Xpath 'g'
907 endif
908 Xpath 'h'
909endfunction
910
911let boolvar = 1
912call F()
913Xpath '-'
914
915unlet boolvar
916call F()
917let g:test15_result = g:Xpath
918
919delfunction F
920
921func Test_if_bar_fail()
922 call assert_equal('acdfh-acfh', g:test15_result)
923endfunc
924
Bram Moolenaar4119cf82016-01-17 14:59:01 +0100925"-------------------------------------------------------------------------------
Bram Moolenaar1f068232019-11-03 16:17:26 +0100926" Test 16: Double :else or :elseif after :else {{{1
927"
928" Multiple :elses or an :elseif after an :else are forbidden.
929"-------------------------------------------------------------------------------
930
931func T16_F() abort
932 if 0
933 Xpath 'a'
934 else
935 Xpath 'b'
936 else " aborts function
937 Xpath 'c'
938 endif
939 Xpath 'd'
940endfunc
941
942func T16_G() abort
943 if 0
944 Xpath 'a'
945 else
946 Xpath 'b'
947 elseif 1 " aborts function
948 Xpath 'c'
949 else
950 Xpath 'd'
951 endif
952 Xpath 'e'
953endfunc
954
955func T16_H() abort
956 if 0
957 Xpath 'a'
958 elseif 0
959 Xpath 'b'
960 else
961 Xpath 'c'
962 else " aborts function
963 Xpath 'd'
964 endif
965 Xpath 'e'
966endfunc
967
968func T16_I() abort
969 if 0
970 Xpath 'a'
971 elseif 0
972 Xpath 'b'
973 else
974 Xpath 'c'
975 elseif 1 " aborts function
976 Xpath 'd'
977 else
978 Xpath 'e'
979 endif
980 Xpath 'f'
981endfunc
982
983func Test_Multi_Else()
984 XpathINIT
985 try
986 call T16_F()
987 catch /E583:/
988 Xpath 'e'
989 endtry
990 call assert_equal('be', g:Xpath)
991
992 XpathINIT
993 try
994 call T16_G()
995 catch /E584:/
996 Xpath 'f'
997 endtry
998 call assert_equal('bf', g:Xpath)
999
1000 XpathINIT
1001 try
1002 call T16_H()
1003 catch /E583:/
1004 Xpath 'f'
1005 endtry
1006 call assert_equal('cf', g:Xpath)
1007
1008 XpathINIT
1009 try
1010 call T16_I()
1011 catch /E584:/
1012 Xpath 'g'
1013 endtry
1014 call assert_equal('cg', g:Xpath)
1015endfunc
1016
1017"-------------------------------------------------------------------------------
1018" Test 17: Nesting of unmatched :if or :endif inside a :while {{{1
1019"
1020" The :while/:endwhile takes precedence in nesting over an unclosed
1021" :if or an unopened :endif.
1022"-------------------------------------------------------------------------------
1023
1024" While loops inside a function are continued on error.
1025func T17_F()
1026 let loops = 3
1027 while loops > 0
1028 let loops -= 1
1029 Xpath 'a' . loops
1030 if (loops == 1)
1031 Xpath 'b' . loops
1032 continue
1033 elseif (loops == 0)
1034 Xpath 'c' . loops
1035 break
1036 elseif 1
1037 Xpath 'd' . loops
1038 " endif missing!
1039 endwhile " :endwhile after :if 1
1040 Xpath 'e'
1041endfunc
1042
1043func T17_G()
1044 let loops = 2
1045 while loops > 0
1046 let loops -= 1
1047 Xpath 'a' . loops
1048 if 0
1049 Xpath 'b' . loops
1050 " endif missing
1051 endwhile " :endwhile after :if 0
1052endfunc
1053
1054func T17_H()
1055 let loops = 2
1056 while loops > 0
1057 let loops -= 1
1058 Xpath 'a' . loops
1059 " if missing!
1060 endif " :endif without :if in while
1061 Xpath 'b' . loops
1062 endwhile
1063endfunc
1064
1065" Error continuation outside a function is at the outermost :endwhile or :endif.
1066XpathINIT
1067let v:errmsg = ''
1068let loops = 2
1069while loops > 0
1070 let loops -= 1
1071 Xpath 'a' . loops
1072 if 0
1073 Xpath 'b' . loops
1074 " endif missing! Following :endwhile fails.
1075endwhile | Xpath 'c'
1076Xpath 'd'
1077call assert_match('E171:', v:errmsg)
1078call assert_equal('a1d', g:Xpath)
1079
1080func Test_unmatched_if_in_while()
1081 XpathINIT
1082 call assert_fails('call T17_F()', 'E171:')
1083 call assert_equal('a2d2a1b1a0c0e', g:Xpath)
1084
1085 XpathINIT
1086 call assert_fails('call T17_G()', 'E171:')
1087 call assert_equal('a1a0', g:Xpath)
1088
1089 XpathINIT
1090 call assert_fails('call T17_H()', 'E580:')
1091 call assert_equal('a1b1a0b0', g:Xpath)
1092endfunc
1093
1094"-------------------------------------------------------------------------------
1095"-------------------------------------------------------------------------------
1096"-------------------------------------------------------------------------------
1097" Test 87 using (expr) ? funcref : funcref {{{1
1098"
1099" Vim needs to correctly parse the funcref and even when it does
1100" not execute the funcref, it needs to consume the trailing ()
1101"-------------------------------------------------------------------------------
1102
1103func Add2(x1, x2)
1104 return a:x1 + a:x2
1105endfu
1106
1107func GetStr()
1108 return "abcdefghijklmnopqrstuvwxyp"
1109endfu
1110
1111func Test_funcref_with_condexpr()
1112 call assert_equal(5, function('Add2')(2,3))
1113
1114 call assert_equal(3, 1 ? function('Add2')(1,2) : function('Add2')(2,3))
1115 call assert_equal(5, 0 ? function('Add2')(1,2) : function('Add2')(2,3))
1116 " Make sure, GetStr() still works.
1117 call assert_equal('abcdefghijk', GetStr()[0:10])
1118endfunc
1119
Bram Moolenaar4119cf82016-01-17 14:59:01 +01001120" Test 90: Recognizing {} in variable name. {{{1
1121"-------------------------------------------------------------------------------
1122
1123func Test_curlies()
1124 let s:var = 66
1125 let ns = 's'
1126 call assert_equal(66, {ns}:var)
1127
1128 let g:a = {}
1129 let g:b = 't'
1130 let g:a[g:b] = 77
1131 call assert_equal(77, g:a['t'])
1132endfunc
Bram Moolenaara2cce862016-01-02 19:50:04 +01001133
1134"-------------------------------------------------------------------------------
Bram Moolenaarf95534c2016-01-23 21:59:52 +01001135" Test 91: using type(). {{{1
1136"-------------------------------------------------------------------------------
1137
1138func Test_type()
1139 call assert_equal(0, type(0))
1140 call assert_equal(1, type(""))
1141 call assert_equal(2, type(function("tr")))
Bram Moolenaar953cc7f2016-03-19 18:52:29 +01001142 call assert_equal(2, type(function("tr", [8])))
Bram Moolenaarf95534c2016-01-23 21:59:52 +01001143 call assert_equal(3, type([]))
1144 call assert_equal(4, type({}))
Bram Moolenaar5feabe02020-01-30 18:24:53 +01001145 if has('float')
1146 call assert_equal(5, type(0.0))
1147 endif
Bram Moolenaarf95534c2016-01-23 21:59:52 +01001148 call assert_equal(6, type(v:false))
1149 call assert_equal(6, type(v:true))
1150 call assert_equal(7, type(v:none))
1151 call assert_equal(7, type(v:null))
Bram Moolenaarf562e722016-07-19 17:25:25 +02001152 call assert_equal(8, v:t_job)
1153 call assert_equal(9, v:t_channel)
1154 call assert_equal(v:t_number, type(0))
1155 call assert_equal(v:t_string, type(""))
1156 call assert_equal(v:t_func, type(function("tr")))
1157 call assert_equal(v:t_func, type(function("tr", [8])))
1158 call assert_equal(v:t_list, type([]))
1159 call assert_equal(v:t_dict, type({}))
Bram Moolenaar5feabe02020-01-30 18:24:53 +01001160 if has('float')
1161 call assert_equal(v:t_float, type(0.0))
1162 endif
Bram Moolenaarf562e722016-07-19 17:25:25 +02001163 call assert_equal(v:t_bool, type(v:false))
1164 call assert_equal(v:t_bool, type(v:true))
1165 call assert_equal(v:t_none, type(v:none))
1166 call assert_equal(v:t_none, type(v:null))
Bram Moolenaar92b83cc2020-04-25 15:24:44 +02001167 call assert_equal(v:t_string, type(test_null_string()))
1168 call assert_equal(v:t_func, type(test_null_function()))
1169 call assert_equal(v:t_func, type(test_null_partial()))
1170 call assert_equal(v:t_list, type(test_null_list()))
1171 call assert_equal(v:t_dict, type(test_null_dict()))
1172 if has('job')
1173 call assert_equal(v:t_job, type(test_null_job()))
1174 endif
1175 if has('channel')
1176 call assert_equal(v:t_channel, type(test_null_channel()))
1177 endif
1178 call assert_equal(v:t_blob, type(test_null_blob()))
Bram Moolenaarf562e722016-07-19 17:25:25 +02001179
Bram Moolenaar7c215c52020-02-29 13:43:27 +01001180 call assert_fails("call type(test_void())", 'E685:')
1181 call assert_fails("call type(test_unknown())", 'E685:')
Bram Moolenaar17a13432016-01-24 14:22:10 +01001182
1183 call assert_equal(0, 0 + v:false)
1184 call assert_equal(1, 0 + v:true)
1185 call assert_equal(0, 0 + v:none)
1186 call assert_equal(0, 0 + v:null)
1187
Bram Moolenaarf48aa162016-01-24 17:54:24 +01001188 call assert_equal('v:false', '' . v:false)
1189 call assert_equal('v:true', '' . v:true)
1190 call assert_equal('v:none', '' . v:none)
1191 call assert_equal('v:null', '' . v:null)
Bram Moolenaar6039c7f2016-01-24 15:05:32 +01001192
1193 call assert_true(v:false == 0)
1194 call assert_false(v:false != 0)
1195 call assert_true(v:true == 1)
1196 call assert_false(v:true != 1)
1197 call assert_false(v:true == v:false)
1198 call assert_true(v:true != v:false)
1199
1200 call assert_true(v:null == 0)
1201 call assert_false(v:null != 0)
1202 call assert_true(v:none == 0)
1203 call assert_false(v:none != 0)
Bram Moolenaar04369222016-01-24 17:21:29 +01001204
1205 call assert_true(v:false is v:false)
1206 call assert_true(v:true is v:true)
1207 call assert_true(v:none is v:none)
1208 call assert_true(v:null is v:null)
1209
1210 call assert_false(v:false isnot v:false)
1211 call assert_false(v:true isnot v:true)
1212 call assert_false(v:none isnot v:none)
1213 call assert_false(v:null isnot v:null)
1214
1215 call assert_false(v:false is 0)
1216 call assert_false(v:true is 1)
1217 call assert_false(v:true is v:false)
1218 call assert_false(v:none is 0)
1219 call assert_false(v:null is 0)
1220 call assert_false(v:null is v:none)
1221
1222 call assert_true(v:false isnot 0)
1223 call assert_true(v:true isnot 1)
1224 call assert_true(v:true isnot v:false)
1225 call assert_true(v:none isnot 0)
1226 call assert_true(v:null isnot 0)
1227 call assert_true(v:null isnot v:none)
Bram Moolenaar65591002016-01-24 21:51:57 +01001228
1229 call assert_equal(v:false, eval(string(v:false)))
1230 call assert_equal(v:true, eval(string(v:true)))
1231 call assert_equal(v:none, eval(string(v:none)))
1232 call assert_equal(v:null, eval(string(v:null)))
Bram Moolenaar767d8c12016-01-25 20:22:54 +01001233
Bram Moolenaar15550002016-01-31 18:45:24 +01001234 call assert_equal(v:false, copy(v:false))
1235 call assert_equal(v:true, copy(v:true))
1236 call assert_equal(v:none, copy(v:none))
1237 call assert_equal(v:null, copy(v:null))
1238
1239 call assert_equal([v:false], deepcopy([v:false]))
1240 call assert_equal([v:true], deepcopy([v:true]))
1241 call assert_equal([v:none], deepcopy([v:none]))
1242 call assert_equal([v:null], deepcopy([v:null]))
1243
Bram Moolenaar767d8c12016-01-25 20:22:54 +01001244 call assert_true(empty(v:false))
1245 call assert_false(empty(v:true))
1246 call assert_true(empty(v:null))
1247 call assert_true(empty(v:none))
Bram Moolenaar6650a692016-01-26 19:59:10 +01001248
1249 func ChangeYourMind()
Bram Moolenaar1e115362019-01-09 23:01:02 +01001250 try
1251 return v:true
1252 finally
1253 return 'something else'
1254 endtry
Bram Moolenaar6650a692016-01-26 19:59:10 +01001255 endfunc
1256
1257 call ChangeYourMind()
Bram Moolenaarf95534c2016-01-23 21:59:52 +01001258endfunc
1259
1260"-------------------------------------------------------------------------------
Bram Moolenaarea8c2192016-02-07 19:27:53 +01001261" Test 92: skipping code {{{1
1262"-------------------------------------------------------------------------------
1263
1264func Test_skip()
1265 let Fn = function('Test_type')
1266 call assert_false(0 && Fn[1])
1267 call assert_false(0 && string(Fn))
1268 call assert_false(0 && len(Fn))
1269 let l = []
1270 call assert_false(0 && l[1])
1271 call assert_false(0 && string(l))
1272 call assert_false(0 && len(l))
1273 let f = 1.0
1274 call assert_false(0 && f[1])
1275 call assert_false(0 && string(f))
1276 call assert_false(0 && len(f))
1277 let sp = v:null
1278 call assert_false(0 && sp[1])
1279 call assert_false(0 && string(sp))
1280 call assert_false(0 && len(sp))
1281
1282endfunc
1283
1284"-------------------------------------------------------------------------------
Bram Moolenaar18dfb442016-05-31 22:31:23 +02001285" Test 93: :echo and string() {{{1
1286"-------------------------------------------------------------------------------
1287
1288func Test_echo_and_string()
1289 " String
1290 let a = 'foo bar'
1291 redir => result
1292 echo a
1293 echo string(a)
1294 redir END
1295 let l = split(result, "\n")
1296 call assert_equal(["foo bar",
1297 \ "'foo bar'"], l)
1298
1299 " Float
1300 if has('float')
1301 let a = -1.2e0
1302 redir => result
1303 echo a
1304 echo string(a)
1305 redir END
1306 let l = split(result, "\n")
1307 call assert_equal(["-1.2",
1308 \ "-1.2"], l)
1309 endif
1310
1311 " Funcref
1312 redir => result
1313 echo function('string')
1314 echo string(function('string'))
1315 redir END
1316 let l = split(result, "\n")
1317 call assert_equal(["string",
1318 \ "function('string')"], l)
1319
1320 " Recursive dictionary
1321 let a = {}
1322 let a["a"] = a
1323 redir => result
1324 echo a
1325 echo string(a)
1326 redir END
1327 let l = split(result, "\n")
1328 call assert_equal(["{'a': {...}}",
1329 \ "{'a': {...}}"], l)
1330
1331 " Recursive list
1332 let a = [0]
1333 let a[0] = a
1334 redir => result
1335 echo a
1336 echo string(a)
1337 redir END
1338 let l = split(result, "\n")
1339 call assert_equal(["[[...]]",
1340 \ "[[...]]"], l)
1341
1342 " Empty dictionaries in a list
1343 let a = {}
1344 redir => result
1345 echo [a, a, a]
1346 echo string([a, a, a])
1347 redir END
1348 let l = split(result, "\n")
1349 call assert_equal(["[{}, {}, {}]",
1350 \ "[{}, {}, {}]"], l)
1351
1352 " Empty dictionaries in a dictionary
1353 let a = {}
1354 let b = {"a": a, "b": a}
1355 redir => result
1356 echo b
1357 echo string(b)
1358 redir END
1359 let l = split(result, "\n")
1360 call assert_equal(["{'a': {}, 'b': {}}",
1361 \ "{'a': {}, 'b': {}}"], l)
1362
1363 " Empty lists in a list
1364 let a = []
1365 redir => result
1366 echo [a, a, a]
1367 echo string([a, a, a])
1368 redir END
1369 let l = split(result, "\n")
1370 call assert_equal(["[[], [], []]",
1371 \ "[[], [], []]"], l)
1372
1373 " Empty lists in a dictionary
1374 let a = []
1375 let b = {"a": a, "b": a}
1376 redir => result
1377 echo b
1378 echo string(b)
1379 redir END
1380 let l = split(result, "\n")
1381 call assert_equal(["{'a': [], 'b': []}",
1382 \ "{'a': [], 'b': []}"], l)
1383
1384 " Dictionaries in a list
1385 let a = {"one": "yes", "two": "yes", "three": "yes"}
1386 redir => result
1387 echo [a, a, a]
1388 echo string([a, a, a])
1389 redir END
1390 let l = split(result, "\n")
1391 call assert_equal(["[{'one': 'yes', 'two': 'yes', 'three': 'yes'}, {...}, {...}]",
1392 \ "[{'one': 'yes', 'two': 'yes', 'three': 'yes'}, {'one': 'yes', 'two': 'yes', 'three': 'yes'}, {'one': 'yes', 'two': 'yes', 'three': 'yes'}]"], l)
1393
1394 " Dictionaries in a dictionary
1395 let a = {"one": "yes", "two": "yes", "three": "yes"}
1396 let b = {"a": a, "b": a}
1397 redir => result
1398 echo b
1399 echo string(b)
1400 redir END
1401 let l = split(result, "\n")
1402 call assert_equal(["{'a': {'one': 'yes', 'two': 'yes', 'three': 'yes'}, 'b': {...}}",
1403 \ "{'a': {'one': 'yes', 'two': 'yes', 'three': 'yes'}, 'b': {'one': 'yes', 'two': 'yes', 'three': 'yes'}}"], l)
1404
1405 " Lists in a list
1406 let a = [1, 2, 3]
1407 redir => result
1408 echo [a, a, a]
1409 echo string([a, a, a])
1410 redir END
1411 let l = split(result, "\n")
1412 call assert_equal(["[[1, 2, 3], [...], [...]]",
1413 \ "[[1, 2, 3], [1, 2, 3], [1, 2, 3]]"], l)
1414
1415 " Lists in a dictionary
1416 let a = [1, 2, 3]
1417 let b = {"a": a, "b": a}
1418 redir => result
1419 echo b
1420 echo string(b)
1421 redir END
1422 let l = split(result, "\n")
1423 call assert_equal(["{'a': [1, 2, 3], 'b': [...]}",
1424 \ "{'a': [1, 2, 3], 'b': [1, 2, 3]}"], l)
1425
Bram Moolenaar1363a302020-04-12 13:50:26 +02001426 call assert_fails('echo &:', 'E112:')
1427 call assert_fails('echo &g:', 'E112:')
1428 call assert_fails('echo &l:', 'E112:')
1429
Bram Moolenaar18dfb442016-05-31 22:31:23 +02001430endfunc
1431
1432"-------------------------------------------------------------------------------
Bram Moolenaar22fcfad2016-07-01 18:17:26 +02001433" Test 94: 64-bit Numbers {{{1
1434"-------------------------------------------------------------------------------
1435
1436func Test_num64()
Bram Moolenaar22fcfad2016-07-01 18:17:26 +02001437 call assert_notequal( 4294967296, 0)
1438 call assert_notequal(-4294967296, 0)
1439 call assert_equal( 4294967296, 0xFFFFffff + 1)
1440 call assert_equal(-4294967296, -0xFFFFffff - 1)
1441
1442 call assert_equal( 9223372036854775807, 1 / 0)
1443 call assert_equal(-9223372036854775807, -1 / 0)
Bram Moolenaar7a40ea22017-01-22 18:34:57 +01001444 call assert_equal(-9223372036854775807 - 1, 0 / 0)
Bram Moolenaar22fcfad2016-07-01 18:17:26 +02001445
Bram Moolenaar5feabe02020-01-30 18:24:53 +01001446 if has('float')
1447 call assert_equal( 0x7FFFffffFFFFffff, float2nr( 1.0e150))
1448 call assert_equal(-0x7FFFffffFFFFffff, float2nr(-1.0e150))
1449 endif
Bram Moolenaar22fcfad2016-07-01 18:17:26 +02001450
1451 let rng = range(0xFFFFffff, 0x100000001)
1452 call assert_equal([0xFFFFffff, 0x100000000, 0x100000001], rng)
1453 call assert_equal(0x100000001, max(rng))
1454 call assert_equal(0xFFFFffff, min(rng))
1455 call assert_equal(rng, sort(range(0x100000001, 0xFFFFffff, -1), 'N'))
1456endfunc
1457
1458"-------------------------------------------------------------------------------
Bram Moolenaar70bcd732017-01-12 22:20:54 +01001459" Test 95: lines of :append, :change, :insert {{{1
1460"-------------------------------------------------------------------------------
1461
1462function! DefineFunction(name, body)
1463 let func = join(['function! ' . a:name . '()'] + a:body + ['endfunction'], "\n")
1464 exec func
1465endfunction
1466
1467func Test_script_lines()
1468 " :append
1469 try
Bram Moolenaar1e115362019-01-09 23:01:02 +01001470 call DefineFunction('T_Append', [
1471 \ 'append',
1472 \ 'py <<EOS',
1473 \ '.',
1474 \ ])
Bram Moolenaar70bcd732017-01-12 22:20:54 +01001475 catch
Bram Moolenaar1e115362019-01-09 23:01:02 +01001476 call assert_report("Can't define function")
Bram Moolenaar70bcd732017-01-12 22:20:54 +01001477 endtry
1478 try
Bram Moolenaar1e115362019-01-09 23:01:02 +01001479 call DefineFunction('T_Append', [
1480 \ 'append',
1481 \ 'abc',
1482 \ ])
1483 call assert_report("Shouldn't be able to define function")
Bram Moolenaar70bcd732017-01-12 22:20:54 +01001484 catch
Bram Moolenaar1e115362019-01-09 23:01:02 +01001485 call assert_exception('Vim(function):E126: Missing :endfunction')
Bram Moolenaar70bcd732017-01-12 22:20:54 +01001486 endtry
1487
1488 " :change
1489 try
Bram Moolenaar1e115362019-01-09 23:01:02 +01001490 call DefineFunction('T_Change', [
1491 \ 'change',
1492 \ 'py <<EOS',
1493 \ '.',
1494 \ ])
Bram Moolenaar70bcd732017-01-12 22:20:54 +01001495 catch
Bram Moolenaar1e115362019-01-09 23:01:02 +01001496 call assert_report("Can't define function")
Bram Moolenaar70bcd732017-01-12 22:20:54 +01001497 endtry
1498 try
Bram Moolenaar1e115362019-01-09 23:01:02 +01001499 call DefineFunction('T_Change', [
1500 \ 'change',
1501 \ 'abc',
1502 \ ])
1503 call assert_report("Shouldn't be able to define function")
Bram Moolenaar70bcd732017-01-12 22:20:54 +01001504 catch
Bram Moolenaar1e115362019-01-09 23:01:02 +01001505 call assert_exception('Vim(function):E126: Missing :endfunction')
Bram Moolenaar70bcd732017-01-12 22:20:54 +01001506 endtry
1507
1508 " :insert
1509 try
Bram Moolenaar1e115362019-01-09 23:01:02 +01001510 call DefineFunction('T_Insert', [
1511 \ 'insert',
1512 \ 'py <<EOS',
1513 \ '.',
1514 \ ])
Bram Moolenaar70bcd732017-01-12 22:20:54 +01001515 catch
Bram Moolenaar1e115362019-01-09 23:01:02 +01001516 call assert_report("Can't define function")
Bram Moolenaar70bcd732017-01-12 22:20:54 +01001517 endtry
1518 try
Bram Moolenaar1e115362019-01-09 23:01:02 +01001519 call DefineFunction('T_Insert', [
1520 \ 'insert',
1521 \ 'abc',
1522 \ ])
1523 call assert_report("Shouldn't be able to define function")
Bram Moolenaar70bcd732017-01-12 22:20:54 +01001524 catch
Bram Moolenaar1e115362019-01-09 23:01:02 +01001525 call assert_exception('Vim(function):E126: Missing :endfunction')
Bram Moolenaar70bcd732017-01-12 22:20:54 +01001526 endtry
1527endfunc
1528
1529"-------------------------------------------------------------------------------
Bram Moolenaar478af672017-04-10 22:22:42 +02001530" Test 96: line continuation {{{1
1531"
Bram Moolenaar1e115362019-01-09 23:01:02 +01001532" Undefined behavior was detected by ubsan with line continuation
1533" after an empty line.
Bram Moolenaar478af672017-04-10 22:22:42 +02001534"-------------------------------------------------------------------------------
1535func Test_script_emty_line_continuation()
1536
1537 \
1538endfunc
1539
1540"-------------------------------------------------------------------------------
Bram Moolenaar863e80b2017-06-04 20:30:00 +02001541" Test 97: bitwise functions {{{1
1542"-------------------------------------------------------------------------------
1543func Test_bitwise_functions()
1544 " and
1545 call assert_equal(127, and(127, 127))
1546 call assert_equal(16, and(127, 16))
Bram Moolenaar073e4b92019-08-18 23:01:56 +02001547 eval 127->and(16)->assert_equal(16)
Bram Moolenaar863e80b2017-06-04 20:30:00 +02001548 call assert_equal(0, and(127, 128))
Bram Moolenaar863e80b2017-06-04 20:30:00 +02001549 call assert_fails("call and([], 1)", 'E745:')
1550 call assert_fails("call and({}, 1)", 'E728:')
Bram Moolenaar5feabe02020-01-30 18:24:53 +01001551 if has('float')
1552 call assert_fails("call and(1.0, 1)", 'E805:')
1553 call assert_fails("call and(1, 1.0)", 'E805:')
1554 endif
Bram Moolenaar863e80b2017-06-04 20:30:00 +02001555 call assert_fails("call and(1, [])", 'E745:')
1556 call assert_fails("call and(1, {})", 'E728:')
1557 " or
1558 call assert_equal(23, or(16, 7))
1559 call assert_equal(15, or(8, 7))
Bram Moolenaar073e4b92019-08-18 23:01:56 +02001560 eval 8->or(7)->assert_equal(15)
Bram Moolenaar863e80b2017-06-04 20:30:00 +02001561 call assert_equal(123, or(0, 123))
Bram Moolenaar863e80b2017-06-04 20:30:00 +02001562 call assert_fails("call or([], 1)", 'E745:')
1563 call assert_fails("call or({}, 1)", 'E728:')
Bram Moolenaar5feabe02020-01-30 18:24:53 +01001564 if has('float')
1565 call assert_fails("call or(1.0, 1)", 'E805:')
1566 call assert_fails("call or(1, 1.0)", 'E805:')
1567 endif
Bram Moolenaar863e80b2017-06-04 20:30:00 +02001568 call assert_fails("call or(1, [])", 'E745:')
1569 call assert_fails("call or(1, {})", 'E728:')
1570 " xor
1571 call assert_equal(0, xor(127, 127))
1572 call assert_equal(111, xor(127, 16))
Bram Moolenaar073e4b92019-08-18 23:01:56 +02001573 eval 127->xor(16)->assert_equal(111)
Bram Moolenaar863e80b2017-06-04 20:30:00 +02001574 call assert_equal(255, xor(127, 128))
Bram Moolenaar5feabe02020-01-30 18:24:53 +01001575 if has('float')
1576 call assert_fails("call xor(1.0, 1)", 'E805:')
1577 call assert_fails("call xor(1, 1.0)", 'E805:')
1578 endif
Bram Moolenaar863e80b2017-06-04 20:30:00 +02001579 call assert_fails("call xor([], 1)", 'E745:')
1580 call assert_fails("call xor({}, 1)", 'E728:')
Bram Moolenaar863e80b2017-06-04 20:30:00 +02001581 call assert_fails("call xor(1, [])", 'E745:')
1582 call assert_fails("call xor(1, {})", 'E728:')
1583 " invert
1584 call assert_equal(65408, and(invert(127), 65535))
Bram Moolenaar073e4b92019-08-18 23:01:56 +02001585 eval 127->invert()->and(65535)->assert_equal(65408)
Bram Moolenaar863e80b2017-06-04 20:30:00 +02001586 call assert_equal(65519, and(invert(16), 65535))
1587 call assert_equal(65407, and(invert(128), 65535))
Bram Moolenaar5feabe02020-01-30 18:24:53 +01001588 if has('float')
1589 call assert_fails("call invert(1.0)", 'E805:')
1590 endif
Bram Moolenaar863e80b2017-06-04 20:30:00 +02001591 call assert_fails("call invert([])", 'E745:')
1592 call assert_fails("call invert({})", 'E728:')
1593endfunc
1594
Bram Moolenaar6f9a4762017-06-22 20:39:17 +02001595" Test using bang after user command {{{1
1596func Test_user_command_with_bang()
1597 command -bang Nieuw let nieuw = 1
1598 Ni!
1599 call assert_equal(1, nieuw)
1600 unlet nieuw
1601 delcommand Nieuw
1602endfunc
1603
Bram Moolenaarb9adef72020-01-02 14:31:22 +01001604func Test_script_expand_sfile()
1605 let lines =<< trim END
1606 func s:snr()
1607 return expand('<sfile>')
1608 endfunc
1609 let g:result = s:snr()
1610 END
1611 call writefile(lines, 'Xexpand')
1612 source Xexpand
1613 call assert_match('<SNR>\d\+_snr', g:result)
1614 source Xexpand
1615 call assert_match('<SNR>\d\+_snr', g:result)
1616
1617 call delete('Xexpand')
1618 unlet g:result
1619endfunc
1620
Bram Moolenaarff697e62019-02-12 22:28:33 +01001621func Test_compound_assignment_operators()
1622 " Test for number
1623 let x = 1
1624 let x += 10
1625 call assert_equal(11, x)
1626 let x -= 5
1627 call assert_equal(6, x)
1628 let x *= 4
1629 call assert_equal(24, x)
1630 let x /= 3
1631 call assert_equal(8, x)
1632 let x %= 3
1633 call assert_equal(2, x)
1634 let x .= 'n'
1635 call assert_equal('2n', x)
1636
Bram Moolenaare21c1582019-03-02 11:57:09 +01001637 " Test special cases: division or modulus with 0.
1638 let x = 1
1639 let x /= 0
Bram Moolenaar82f654e2020-02-17 22:12:50 +01001640 call assert_equal(0x7FFFFFFFFFFFFFFF, x)
Bram Moolenaare21c1582019-03-02 11:57:09 +01001641
1642 let x = -1
1643 let x /= 0
Bram Moolenaar82f654e2020-02-17 22:12:50 +01001644 call assert_equal(-0x7FFFFFFFFFFFFFFF, x)
Bram Moolenaare21c1582019-03-02 11:57:09 +01001645
1646 let x = 0
1647 let x /= 0
Bram Moolenaar82f654e2020-02-17 22:12:50 +01001648 call assert_equal(-0x7FFFFFFFFFFFFFFF - 1, x)
Bram Moolenaare21c1582019-03-02 11:57:09 +01001649
1650 let x = 1
1651 let x %= 0
1652 call assert_equal(0, x)
1653
1654 let x = -1
1655 let x %= 0
1656 call assert_equal(0, x)
1657
1658 let x = 0
1659 let x %= 0
1660 call assert_equal(0, x)
1661
Bram Moolenaarff697e62019-02-12 22:28:33 +01001662 " Test for string
1663 let x = 'str'
1664 let x .= 'ing'
1665 call assert_equal('string', x)
1666 let x += 1
1667 call assert_equal(1, x)
Bram Moolenaarff697e62019-02-12 22:28:33 +01001668
1669 if has('float')
Bram Moolenaar5feabe02020-01-30 18:24:53 +01001670 " Test for float
1671 let x -= 1.5
1672 call assert_equal(-0.5, x)
1673 let x = 0.5
1674 let x += 4.5
1675 call assert_equal(5.0, x)
1676 let x -= 1.5
1677 call assert_equal(3.5, x)
1678 let x *= 3.0
1679 call assert_equal(10.5, x)
1680 let x /= 2.5
1681 call assert_equal(4.2, x)
1682 call assert_fails('let x %= 0.5', 'E734')
1683 call assert_fails('let x .= "f"', 'E734')
Bram Moolenaar8b633132020-03-20 18:20:51 +01001684 let x = !3.14
1685 call assert_equal(0.0, x)
Bram Moolenaarea04a6e2020-04-23 13:38:02 +02001686
1687 " integer and float operations
1688 let x = 1
1689 let x *= 2.1
1690 call assert_equal(2.1, x)
1691 let x = 1
1692 let x /= 0.25
1693 call assert_equal(4.0, x)
1694 let x = 1
1695 call assert_fails('let x %= 0.25', 'E734:')
1696 let x = 1
1697 call assert_fails('let x .= 0.25', 'E734:')
1698 let x = 1.0
1699 call assert_fails('let x += [1.1]', 'E734:')
Bram Moolenaarff697e62019-02-12 22:28:33 +01001700 endif
1701
1702 " Test for environment variable
1703 let $FOO = 1
1704 call assert_fails('let $FOO += 1', 'E734')
1705 call assert_fails('let $FOO -= 1', 'E734')
1706 call assert_fails('let $FOO *= 1', 'E734')
1707 call assert_fails('let $FOO /= 1', 'E734')
1708 call assert_fails('let $FOO %= 1', 'E734')
1709 let $FOO .= 's'
1710 call assert_equal('1s', $FOO)
1711 unlet $FOO
1712
1713 " Test for option variable (type: number)
1714 let &scrolljump = 1
1715 let &scrolljump += 5
1716 call assert_equal(6, &scrolljump)
1717 let &scrolljump -= 2
1718 call assert_equal(4, &scrolljump)
1719 let &scrolljump *= 3
1720 call assert_equal(12, &scrolljump)
1721 let &scrolljump /= 2
1722 call assert_equal(6, &scrolljump)
1723 let &scrolljump %= 5
1724 call assert_equal(1, &scrolljump)
1725 call assert_fails('let &scrolljump .= "j"', 'E734')
1726 set scrolljump&vim
1727
1728 " Test for register
1729 let @/ = 1
1730 call assert_fails('let @/ += 1', 'E734')
1731 call assert_fails('let @/ -= 1', 'E734')
1732 call assert_fails('let @/ *= 1', 'E734')
1733 call assert_fails('let @/ /= 1', 'E734')
1734 call assert_fails('let @/ %= 1', 'E734')
1735 let @/ .= 's'
1736 call assert_equal('1s', @/)
1737 let @/ = ''
1738endfunc
1739
Bram Moolenaar7e0868e2020-04-19 17:24:53 +02001740func Test_unlet_env()
1741 let $TESTVAR = 'yes'
1742 call assert_equal('yes', $TESTVAR)
1743 call assert_fails('lockvar $TESTVAR', 'E940')
1744 call assert_fails('unlockvar $TESTVAR', 'E940')
1745 call assert_equal('yes', $TESTVAR)
1746 if 0
1747 unlet $TESTVAR
1748 endif
1749 call assert_equal('yes', $TESTVAR)
1750 unlet $TESTVAR
1751 call assert_equal('', $TESTVAR)
1752endfunc
1753
Bram Moolenaarc3e92c12019-03-23 14:23:07 +01001754func Test_refcount()
1755 " Immediate values
1756 call assert_equal(-1, test_refcount(1))
1757 call assert_equal(-1, test_refcount('s'))
1758 call assert_equal(-1, test_refcount(v:true))
1759 call assert_equal(0, test_refcount([]))
1760 call assert_equal(0, test_refcount({}))
1761 call assert_equal(0, test_refcount(0zff))
1762 call assert_equal(0, test_refcount({-> line('.')}))
1763 if has('float')
1764 call assert_equal(-1, test_refcount(0.1))
1765 endif
1766 if has('job')
1767 call assert_equal(0, test_refcount(job_start([&shell, &shellcmdflag, 'echo .'])))
1768 endif
1769
1770 " No refcount types
1771 let x = 1
1772 call assert_equal(-1, test_refcount(x))
1773 let x = 's'
1774 call assert_equal(-1, test_refcount(x))
1775 let x = v:true
1776 call assert_equal(-1, test_refcount(x))
1777 if has('float')
1778 let x = 0.1
1779 call assert_equal(-1, test_refcount(x))
1780 endif
1781
1782 " Check refcount
1783 let x = []
1784 call assert_equal(1, test_refcount(x))
1785
1786 let x = {}
Bram Moolenaarce90e362019-09-08 18:58:44 +02001787 call assert_equal(1, x->test_refcount())
Bram Moolenaarc3e92c12019-03-23 14:23:07 +01001788
1789 let x = 0zff
1790 call assert_equal(1, test_refcount(x))
1791
1792 let X = {-> line('.')}
1793 call assert_equal(1, test_refcount(X))
1794 let Y = X
1795 call assert_equal(2, test_refcount(X))
1796
1797 if has('job')
1798 let job = job_start([&shell, &shellcmdflag, 'echo .'])
1799 call assert_equal(1, test_refcount(job))
1800 call assert_equal(1, test_refcount(job_getchannel(job)))
1801 call assert_equal(1, test_refcount(job))
1802 endif
1803
1804 " Function arguments, copying and unassigning
1805 func ExprCheck(x, i)
1806 let i = a:i + 1
1807 call assert_equal(i, test_refcount(a:x))
1808 let Y = a:x
1809 call assert_equal(i + 1, test_refcount(a:x))
1810 call assert_equal(test_refcount(a:x), test_refcount(Y))
1811 let Y = 0
1812 call assert_equal(i, test_refcount(a:x))
1813 endfunc
1814 call ExprCheck([], 0)
1815 call ExprCheck({}, 0)
1816 call ExprCheck(0zff, 0)
1817 call ExprCheck({-> line('.')}, 0)
1818 if has('job')
1819 call ExprCheck(job, 1)
1820 call ExprCheck(job_getchannel(job), 1)
1821 call job_stop(job)
1822 endif
1823 delfunc ExprCheck
1824
1825 " Regarding function
1826 func Func(x) abort
1827 call assert_equal(2, test_refcount(function('Func')))
1828 call assert_equal(0, test_refcount(funcref('Func')))
1829 endfunc
1830 call assert_equal(1, test_refcount(function('Func')))
1831 call assert_equal(0, test_refcount(function('Func', [1])))
1832 call assert_equal(0, test_refcount(funcref('Func')))
1833 call assert_equal(0, test_refcount(funcref('Func', [1])))
1834 let X = function('Func')
1835 let Y = X
1836 call assert_equal(1, test_refcount(X))
1837 let X = function('Func', [1])
1838 let Y = X
1839 call assert_equal(2, test_refcount(X))
1840 let X = funcref('Func')
1841 let Y = X
1842 call assert_equal(2, test_refcount(X))
1843 let X = funcref('Func', [1])
1844 let Y = X
1845 call assert_equal(2, test_refcount(X))
1846 unlet X
1847 unlet Y
1848 call Func(1)
1849 delfunc Func
1850
1851 " Function with dict
1852 func DictFunc() dict
1853 call assert_equal(3, test_refcount(self))
1854 endfunc
1855 let d = {'Func': function('DictFunc')}
1856 call assert_equal(1, test_refcount(d))
1857 call assert_equal(0, test_refcount(d.Func))
1858 call d.Func()
1859 unlet d
1860 delfunc DictFunc
1861endfunc
1862
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01001863" Test for missing :endif, :endfor, :endwhile and :endtry {{{1
1864func Test_missing_end()
1865 call writefile(['if 2 > 1', 'echo ">"'], 'Xscript')
1866 call assert_fails('source Xscript', 'E171:')
1867 call writefile(['for i in range(5)', 'echo i'], 'Xscript')
1868 call assert_fails('source Xscript', 'E170:')
1869 call writefile(['while v:true', 'echo "."'], 'Xscript')
1870 call assert_fails('source Xscript', 'E170:')
1871 call writefile(['try', 'echo "."'], 'Xscript')
1872 call assert_fails('source Xscript', 'E600:')
1873 call delete('Xscript')
Bram Moolenaar818fc9a2020-02-21 17:54:45 +01001874
1875 " Using endfor with :while
1876 let caught_e732 = 0
1877 try
1878 while v:true
1879 endfor
1880 catch /E732:/
1881 let caught_e732 = 1
1882 endtry
1883 call assert_equal(1, caught_e732)
1884
1885 " Using endwhile with :for
1886 let caught_e733 = 0
1887 try
1888 for i in range(1)
1889 endwhile
1890 catch /E733:/
1891 let caught_e733 = 1
1892 endtry
1893 call assert_equal(1, caught_e733)
1894
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02001895 " Using endfunc with :if
1896 call assert_fails('exe "if 1 | endfunc | endif"', 'E193:')
1897
Bram Moolenaar818fc9a2020-02-21 17:54:45 +01001898 " Missing 'in' in a :for statement
1899 call assert_fails('for i range(1) | endfor', 'E690:')
Bram Moolenaarea04a6e2020-04-23 13:38:02 +02001900
1901 " Incorrect number of variables in for
1902 call assert_fails('for [i,] in range(3) | endfor', 'E475:')
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01001903endfunc
1904
1905" Test for deep nesting of if/for/while/try statements {{{1
1906func Test_deep_nest()
Bram Moolenaar494e9062020-05-31 21:28:02 +02001907 CheckRunVimInTerminal
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01001908
1909 let lines =<< trim [SCRIPT]
1910 " Deep nesting of if ... endif
1911 func Test1()
1912 let @a = join(repeat(['if v:true'], 51), "\n")
1913 let @a ..= "\n"
1914 let @a ..= join(repeat(['endif'], 51), "\n")
1915 @a
1916 let @a = ''
1917 endfunc
1918
1919 " Deep nesting of for ... endfor
1920 func Test2()
1921 let @a = join(repeat(['for i in [1]'], 51), "\n")
1922 let @a ..= "\n"
1923 let @a ..= join(repeat(['endfor'], 51), "\n")
1924 @a
1925 let @a = ''
1926 endfunc
1927
1928 " Deep nesting of while ... endwhile
1929 func Test3()
1930 let @a = join(repeat(['while v:true'], 51), "\n")
1931 let @a ..= "\n"
1932 let @a ..= join(repeat(['endwhile'], 51), "\n")
1933 @a
1934 let @a = ''
1935 endfunc
1936
1937 " Deep nesting of try ... endtry
1938 func Test4()
1939 let @a = join(repeat(['try'], 51), "\n")
1940 let @a ..= "\necho v:true\n"
1941 let @a ..= join(repeat(['endtry'], 51), "\n")
1942 @a
1943 let @a = ''
1944 endfunc
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02001945
1946 " Deep nesting of function ... endfunction
1947 func Test5()
1948 let @a = join(repeat(['function X()'], 51), "\n")
1949 let @a ..= "\necho v:true\n"
1950 let @a ..= join(repeat(['endfunction'], 51), "\n")
1951 @a
1952 let @a = ''
1953 endfunc
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01001954 [SCRIPT]
1955 call writefile(lines, 'Xscript')
1956
1957 let buf = RunVimInTerminal('-S Xscript', {'rows': 6})
1958
1959 " Deep nesting of if ... endif
1960 call term_sendkeys(buf, ":call Test1()\n")
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +02001961 call TermWait(buf)
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01001962 call WaitForAssert({-> assert_match('^E579:', term_getline(buf, 5))})
1963
1964 " Deep nesting of for ... endfor
1965 call term_sendkeys(buf, ":call Test2()\n")
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +02001966 call TermWait(buf)
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01001967 call WaitForAssert({-> assert_match('^E585:', term_getline(buf, 5))})
1968
1969 " Deep nesting of while ... endwhile
1970 call term_sendkeys(buf, ":call Test3()\n")
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +02001971 call TermWait(buf)
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01001972 call WaitForAssert({-> assert_match('^E585:', term_getline(buf, 5))})
1973
1974 " Deep nesting of try ... endtry
1975 call term_sendkeys(buf, ":call Test4()\n")
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +02001976 call TermWait(buf)
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01001977 call WaitForAssert({-> assert_match('^E601:', term_getline(buf, 5))})
1978
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02001979 " Deep nesting of function ... endfunction
1980 call term_sendkeys(buf, ":call Test5()\n")
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +02001981 call TermWait(buf)
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02001982 call WaitForAssert({-> assert_match('^E1058:', term_getline(buf, 4))})
1983 call term_sendkeys(buf, "\<C-C>\n")
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +02001984 call TermWait(buf)
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02001985
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01001986 "let l = ''
1987 "for i in range(1, 6)
1988 " let l ..= term_getline(buf, i) . "\n"
1989 "endfor
1990 "call assert_report(l)
1991
1992 call StopVimInTerminal(buf)
1993 call delete('Xscript')
1994endfunc
1995
Bram Moolenaar8b633132020-03-20 18:20:51 +01001996" Test for errors in converting to float from various types {{{1
1997func Test_float_conversion_errors()
1998 if has('float')
1999 call assert_fails('let x = 4.0 % 2.0', 'E804')
2000 call assert_fails('echo 1.1[0]', 'E806')
2001 call assert_fails('echo sort([function("min"), 1], "f")', 'E891:')
2002 call assert_fails('echo 3.2 == "vim"', 'E892:')
2003 call assert_fails('echo sort([[], 1], "f")', 'E893:')
2004 call assert_fails('echo sort([{}, 1], "f")', 'E894:')
2005 call assert_fails('echo 3.2 == v:true', 'E362:')
2006 call assert_fails('echo 3.2 == v:none', 'E907:')
2007 endif
2008endfunc
2009
Bram Moolenaar08f41572020-04-20 16:50:00 +02002010func Test_invalid_function_names()
2011 " function name not starting with capital
2012 let caught_e128 = 0
2013 try
2014 func! g:test()
2015 echo "test"
2016 endfunc
2017 catch /E128:/
2018 let caught_e128 = 1
2019 endtry
2020 call assert_equal(1, caught_e128)
2021
2022 " function name includes a colon
2023 let caught_e884 = 0
2024 try
2025 func! b:test()
2026 echo "test"
2027 endfunc
2028 catch /E884:/
2029 let caught_e884 = 1
2030 endtry
2031 call assert_equal(1, caught_e884)
2032
2033 " function name folowed by #
2034 let caught_e128 = 0
2035 try
2036 func! test2() "#
2037 echo "test2"
2038 endfunc
2039 catch /E128:/
2040 let caught_e128 = 1
2041 endtry
2042 call assert_equal(1, caught_e128)
2043
2044 " function name starting with/without "g:", buffer-local funcref.
2045 function! g:Foo(n)
2046 return 'called Foo(' . a:n . ')'
2047 endfunction
2048 let b:my_func = function('Foo')
2049 call assert_equal('called Foo(1)', b:my_func(1))
2050 call assert_equal('called Foo(2)', g:Foo(2))
2051 call assert_equal('called Foo(3)', Foo(3))
2052 delfunc g:Foo
2053
2054 " script-local function used in Funcref must exist.
2055 let lines =<< trim END
2056 func s:Testje()
2057 return "foo"
2058 endfunc
2059 let Bar = function('s:Testje')
2060 call assert_equal(0, exists('s:Testje'))
2061 call assert_equal(1, exists('*s:Testje'))
2062 call assert_equal(1, exists('Bar'))
2063 call assert_equal(1, exists('*Bar'))
2064 END
2065 call writefile(lines, 'Xscript')
2066 source Xscript
2067 call delete('Xscript')
2068endfunc
2069
2070" substring and variable name
2071func Test_substring_var()
2072 let str = 'abcdef'
2073 let n = 3
2074 call assert_equal('def', str[n:])
2075 call assert_equal('abcd', str[:n])
2076 call assert_equal('d', str[n:n])
2077 unlet n
2078 let nn = 3
2079 call assert_equal('def', str[nn:])
2080 call assert_equal('abcd', str[:nn])
2081 call assert_equal('d', str[nn:nn])
2082 unlet nn
2083 let b:nn = 4
2084 call assert_equal('ef', str[b:nn:])
2085 call assert_equal('abcde', str[:b:nn])
2086 call assert_equal('e', str[b:nn:b:nn])
2087 unlet b:nn
2088endfunc
2089
Bram Moolenaar863e80b2017-06-04 20:30:00 +02002090"-------------------------------------------------------------------------------
Bram Moolenaarf49e2402015-12-30 15:59:25 +01002091" Modelines {{{1
Bram Moolenaar1f068232019-11-03 16:17:26 +01002092" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
Bram Moolenaarf49e2402015-12-30 15:59:25 +01002093"-------------------------------------------------------------------------------