1*b544f3c8SBram Moolenaar" Test various aspects of the Vim language.
2*b544f3c8SBram Moolenaar" Most of this was formerly in test49.
3*b544f3c8SBram Moolenaar
4*b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
5*b544f3c8SBram Moolenaar" Test environment							    {{{1
6*b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
7*b544f3c8SBram Moolenaar
8*b544f3c8SBram Moolenaarcom!               XpathINIT  let g:Xpath = ''
9*b544f3c8SBram Moolenaarcom! -nargs=1 -bar Xpath      let g:Xpath = g:Xpath . <args>
10*b544f3c8SBram Moolenaar
11*b544f3c8SBram Moolenaar" Append a message to the "messages" file
12*b544f3c8SBram Moolenaarfunc! Xout(text)
13*b544f3c8SBram Moolenaar    split messages
14*b544f3c8SBram Moolenaar    $put =a:text
15*b544f3c8SBram Moolenaar    wq
16*b544f3c8SBram Moolenaarendfunc
17*b544f3c8SBram Moolenaar
18*b544f3c8SBram Moolenaarcom! -nargs=1	     Xout     call Xout(<args>)
19*b544f3c8SBram Moolenaar
20*b544f3c8SBram Moolenaar" MakeScript() - Make a script file from a function.			    {{{2
21*b544f3c8SBram Moolenaar"
22*b544f3c8SBram Moolenaar" Create a script that consists of the body of the function a:funcname.
23*b544f3c8SBram Moolenaar" Replace any ":return" by a ":finish", any argument variable by a global
24*b544f3c8SBram Moolenaar" variable, and and every ":call" by a ":source" for the next following argument
25*b544f3c8SBram Moolenaar" in the variable argument list.  This function is useful if similar tests are
26*b544f3c8SBram Moolenaar" to be made for a ":return" from a function call or a ":finish" in a script
27*b544f3c8SBram Moolenaar" file.
28*b544f3c8SBram Moolenaarfunction! MakeScript(funcname, ...)
29*b544f3c8SBram Moolenaar    let script = tempname()
30*b544f3c8SBram Moolenaar    execute "redir! >" . script
31*b544f3c8SBram Moolenaar    execute "function" a:funcname
32*b544f3c8SBram Moolenaar    redir END
33*b544f3c8SBram Moolenaar    execute "edit" script
34*b544f3c8SBram Moolenaar    " Delete the "function" and the "endfunction" lines.  Do not include the
35*b544f3c8SBram Moolenaar    " word "function" in the pattern since it might be translated if LANG is
36*b544f3c8SBram Moolenaar    " set.  When MakeScript() is being debugged, this deletes also the debugging
37*b544f3c8SBram Moolenaar    " output of its line 3 and 4.
38*b544f3c8SBram Moolenaar    exec '1,/.*' . a:funcname . '(.*)/d'
39*b544f3c8SBram Moolenaar    /^\d*\s*endfunction\>/,$d
40*b544f3c8SBram Moolenaar    %s/^\d*//e
41*b544f3c8SBram Moolenaar    %s/return/finish/e
42*b544f3c8SBram Moolenaar    %s/\<a:\(\h\w*\)/g:\1/ge
43*b544f3c8SBram Moolenaar    normal gg0
44*b544f3c8SBram Moolenaar    let cnt = 0
45*b544f3c8SBram Moolenaar    while search('\<call\s*\%(\u\|s:\)\w*\s*(.*)', 'W') > 0
46*b544f3c8SBram Moolenaar	let cnt = cnt + 1
47*b544f3c8SBram Moolenaar	s/\<call\s*\%(\u\|s:\)\w*\s*(.*)/\='source ' . a:{cnt}/
48*b544f3c8SBram Moolenaar    endwhile
49*b544f3c8SBram Moolenaar    g/^\s*$/d
50*b544f3c8SBram Moolenaar    write
51*b544f3c8SBram Moolenaar    bwipeout
52*b544f3c8SBram Moolenaar    return script
53*b544f3c8SBram Moolenaarendfunction
54*b544f3c8SBram Moolenaar
55*b544f3c8SBram Moolenaar" ExecAsScript - Source a temporary script made from a function.	    {{{2
56*b544f3c8SBram Moolenaar"
57*b544f3c8SBram Moolenaar" Make a temporary script file from the function a:funcname, ":source" it, and
58*b544f3c8SBram Moolenaar" delete it afterwards.  However, if an exception is thrown the file may remain,
59*b544f3c8SBram Moolenaar" the caller should call DeleteTheScript() afterwards.
60*b544f3c8SBram Moolenaarlet s:script_name = ''
61*b544f3c8SBram Moolenaarfunction! ExecAsScript(funcname)
62*b544f3c8SBram Moolenaar    " Make a script from the function passed as argument.
63*b544f3c8SBram Moolenaar    let s:script_name = MakeScript(a:funcname)
64*b544f3c8SBram Moolenaar
65*b544f3c8SBram Moolenaar    " Source and delete the script.
66*b544f3c8SBram Moolenaar    exec "source" s:script_name
67*b544f3c8SBram Moolenaar    call delete(s:script_name)
68*b544f3c8SBram Moolenaar    let s:script_name = ''
69*b544f3c8SBram Moolenaarendfunction
70*b544f3c8SBram Moolenaar
71*b544f3c8SBram Moolenaarfunction! DeleteTheScript()
72*b544f3c8SBram Moolenaar    if s:script_name
73*b544f3c8SBram Moolenaar	call delete(s:script_name)
74*b544f3c8SBram Moolenaar	let s:script_name = ''
75*b544f3c8SBram Moolenaar    endif
76*b544f3c8SBram Moolenaarendfunc
77*b544f3c8SBram Moolenaar
78*b544f3c8SBram Moolenaarcom! -nargs=1 -bar ExecAsScript call ExecAsScript(<f-args>)
79*b544f3c8SBram Moolenaar
80*b544f3c8SBram Moolenaar
81*b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
82*b544f3c8SBram Moolenaar" Test 1:   :endwhile in function					    {{{1
83*b544f3c8SBram Moolenaar"
84*b544f3c8SBram Moolenaar"	    Detect if a broken loop is (incorrectly) reactivated by the
85*b544f3c8SBram Moolenaar"	    :endwhile.  Use a :return to prevent an endless loop, and make
86*b544f3c8SBram Moolenaar"	    this test first to get a meaningful result on an error before other
87*b544f3c8SBram Moolenaar"	    tests will hang.
88*b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
89*b544f3c8SBram Moolenaar
90*b544f3c8SBram Moolenaarfunction! T1_F()
91*b544f3c8SBram Moolenaar    Xpath 'a'
92*b544f3c8SBram Moolenaar    let first = 1
93*b544f3c8SBram Moolenaar    while 1
94*b544f3c8SBram Moolenaar	Xpath 'b'
95*b544f3c8SBram Moolenaar	if first
96*b544f3c8SBram Moolenaar	    Xpath 'c'
97*b544f3c8SBram Moolenaar	    let first = 0
98*b544f3c8SBram Moolenaar	    break
99*b544f3c8SBram Moolenaar	else
100*b544f3c8SBram Moolenaar	    Xpath 'd'
101*b544f3c8SBram Moolenaar	    return
102*b544f3c8SBram Moolenaar	endif
103*b544f3c8SBram Moolenaar    endwhile
104*b544f3c8SBram Moolenaarendfunction
105*b544f3c8SBram Moolenaar
106*b544f3c8SBram Moolenaarfunction! T1_G()
107*b544f3c8SBram Moolenaar    Xpath 'h'
108*b544f3c8SBram Moolenaar    let first = 1
109*b544f3c8SBram Moolenaar    while 1
110*b544f3c8SBram Moolenaar	Xpath 'i'
111*b544f3c8SBram Moolenaar	if first
112*b544f3c8SBram Moolenaar	    Xpath 'j'
113*b544f3c8SBram Moolenaar	    let first = 0
114*b544f3c8SBram Moolenaar	    break
115*b544f3c8SBram Moolenaar	else
116*b544f3c8SBram Moolenaar	    Xpath 'k'
117*b544f3c8SBram Moolenaar	    return
118*b544f3c8SBram Moolenaar	endif
119*b544f3c8SBram Moolenaar	if 1	" unmatched :if
120*b544f3c8SBram Moolenaar    endwhile
121*b544f3c8SBram Moolenaarendfunction
122*b544f3c8SBram Moolenaar
123*b544f3c8SBram Moolenaarfunc Test_endwhile_function()
124*b544f3c8SBram Moolenaar  XpathINIT
125*b544f3c8SBram Moolenaar  call T1_F()
126*b544f3c8SBram Moolenaar  Xpath 'F'
127*b544f3c8SBram Moolenaar
128*b544f3c8SBram Moolenaar  try
129*b544f3c8SBram Moolenaar    call T1_G()
130*b544f3c8SBram Moolenaar  catch
131*b544f3c8SBram Moolenaar    " Catch missing :endif
132*b544f3c8SBram Moolenaar    call assert_true(v:exception =~ 'E171')
133*b544f3c8SBram Moolenaar    Xpath 'x'
134*b544f3c8SBram Moolenaar  endtry
135*b544f3c8SBram Moolenaar  Xpath 'G'
136*b544f3c8SBram Moolenaar
137*b544f3c8SBram Moolenaar  call assert_equal('abcFhijxG', g:Xpath)
138*b544f3c8SBram Moolenaarendfunc
139*b544f3c8SBram Moolenaar
140*b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
141*b544f3c8SBram Moolenaar" Test 2:   :endwhile in script						    {{{1
142*b544f3c8SBram Moolenaar"
143*b544f3c8SBram Moolenaar"	    Detect if a broken loop is (incorrectly) reactivated by the
144*b544f3c8SBram Moolenaar"	    :endwhile.  Use a :finish to prevent an endless loop, and place
145*b544f3c8SBram Moolenaar"	    this test before others that might hang to get a meaningful result
146*b544f3c8SBram Moolenaar"	    on an error.
147*b544f3c8SBram Moolenaar"
148*b544f3c8SBram Moolenaar"	    This test executes the bodies of the functions T1_F and T1_G from
149*b544f3c8SBram Moolenaar"	    the previous test as script files (:return replaced by :finish).
150*b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
151*b544f3c8SBram Moolenaar
152*b544f3c8SBram Moolenaarfunc Test_endwhile_script()
153*b544f3c8SBram Moolenaar  XpathINIT
154*b544f3c8SBram Moolenaar  ExecAsScript T1_F
155*b544f3c8SBram Moolenaar  Xpath 'F'
156*b544f3c8SBram Moolenaar  call DeleteTheScript()
157*b544f3c8SBram Moolenaar
158*b544f3c8SBram Moolenaar  try
159*b544f3c8SBram Moolenaar    ExecAsScript T1_G
160*b544f3c8SBram Moolenaar  catch
161*b544f3c8SBram Moolenaar    " Catch missing :endif
162*b544f3c8SBram Moolenaar    call assert_true(v:exception =~ 'E171')
163*b544f3c8SBram Moolenaar    Xpath 'x'
164*b544f3c8SBram Moolenaar  endtry
165*b544f3c8SBram Moolenaar  Xpath 'G'
166*b544f3c8SBram Moolenaar  call DeleteTheScript()
167*b544f3c8SBram Moolenaar
168*b544f3c8SBram Moolenaar  call assert_equal('abcFhijxG', g:Xpath)
169*b544f3c8SBram Moolenaarendfunc
170*b544f3c8SBram Moolenaar
171*b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
172*b544f3c8SBram Moolenaar" Test 3:   :if, :elseif, :while, :continue, :break			    {{{1
173*b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
174*b544f3c8SBram Moolenaar
175*b544f3c8SBram Moolenaarfunction Test_if_while()
176*b544f3c8SBram Moolenaar    XpathINIT
177*b544f3c8SBram Moolenaar    if 1
178*b544f3c8SBram Moolenaar	Xpath 'a'
179*b544f3c8SBram Moolenaar	let loops = 3
180*b544f3c8SBram Moolenaar	while loops > -1	    " main loop: loops == 3, 2, 1 (which breaks)
181*b544f3c8SBram Moolenaar	    if loops <= 0
182*b544f3c8SBram Moolenaar		let break_err = 1
183*b544f3c8SBram Moolenaar		let loops = -1
184*b544f3c8SBram Moolenaar	    else
185*b544f3c8SBram Moolenaar		Xpath 'b' . loops
186*b544f3c8SBram Moolenaar	    endif
187*b544f3c8SBram Moolenaar	    if (loops == 2)
188*b544f3c8SBram Moolenaar		while loops == 2 " dummy loop
189*b544f3c8SBram Moolenaar		    Xpath 'c' . loops
190*b544f3c8SBram Moolenaar		    let loops = loops - 1
191*b544f3c8SBram Moolenaar		    continue    " stop dummy loop
192*b544f3c8SBram Moolenaar		    Xpath 'd' . loops
193*b544f3c8SBram Moolenaar		endwhile
194*b544f3c8SBram Moolenaar		continue	    " continue main loop
195*b544f3c8SBram Moolenaar		Xpath 'e' . loops
196*b544f3c8SBram Moolenaar	    elseif (loops == 1)
197*b544f3c8SBram Moolenaar		let p = 1
198*b544f3c8SBram Moolenaar		while p	    " dummy loop
199*b544f3c8SBram Moolenaar		    Xpath 'f' . loops
200*b544f3c8SBram Moolenaar		    let p = 0
201*b544f3c8SBram Moolenaar		    break	    " break dummy loop
202*b544f3c8SBram Moolenaar		    Xpath 'g' . loops
203*b544f3c8SBram Moolenaar		endwhile
204*b544f3c8SBram Moolenaar		Xpath 'h' . loops
205*b544f3c8SBram Moolenaar		unlet p
206*b544f3c8SBram Moolenaar		break	    " break main loop
207*b544f3c8SBram Moolenaar		Xpath 'i' . loops
208*b544f3c8SBram Moolenaar	    endif
209*b544f3c8SBram Moolenaar	    if (loops > 0)
210*b544f3c8SBram Moolenaar		Xpath 'j' . loops
211*b544f3c8SBram Moolenaar	    endif
212*b544f3c8SBram Moolenaar	    while loops == 3    " dummy loop
213*b544f3c8SBram Moolenaar		let loops = loops - 1
214*b544f3c8SBram Moolenaar	    endwhile	    " end dummy loop
215*b544f3c8SBram Moolenaar	endwhile		    " end main loop
216*b544f3c8SBram Moolenaar	Xpath 'k'
217*b544f3c8SBram Moolenaar    else
218*b544f3c8SBram Moolenaar	Xpath 'l'
219*b544f3c8SBram Moolenaar    endif
220*b544f3c8SBram Moolenaar    Xpath 'm'
221*b544f3c8SBram Moolenaar    if exists("break_err")
222*b544f3c8SBram Moolenaar	Xpath 'm'
223*b544f3c8SBram Moolenaar	unlet break_err
224*b544f3c8SBram Moolenaar    endif
225*b544f3c8SBram Moolenaar
226*b544f3c8SBram Moolenaar    unlet loops
227*b544f3c8SBram Moolenaar
228*b544f3c8SBram Moolenaar    call assert_equal('ab3j3b2c2b1f1h1km', g:Xpath)
229*b544f3c8SBram Moolenaarendfunc
230*b544f3c8SBram Moolenaar
231*b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
232*b544f3c8SBram Moolenaar" Test 4:   :return							    {{{1
233*b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
234*b544f3c8SBram Moolenaar
235*b544f3c8SBram Moolenaarfunction! T4_F()
236*b544f3c8SBram Moolenaar    if 1
237*b544f3c8SBram Moolenaar	Xpath 'a'
238*b544f3c8SBram Moolenaar	let loops = 3
239*b544f3c8SBram Moolenaar	while loops > 0				"    3:  2:     1:
240*b544f3c8SBram Moolenaar	    Xpath 'b' . loops
241*b544f3c8SBram Moolenaar	    if (loops == 2)
242*b544f3c8SBram Moolenaar		Xpath 'c' . loops
243*b544f3c8SBram Moolenaar		return
244*b544f3c8SBram Moolenaar		Xpath 'd' . loops
245*b544f3c8SBram Moolenaar	    endif
246*b544f3c8SBram Moolenaar	    Xpath 'e' . loops
247*b544f3c8SBram Moolenaar	    let loops = loops - 1
248*b544f3c8SBram Moolenaar	endwhile
249*b544f3c8SBram Moolenaar	Xpath 'f'
250*b544f3c8SBram Moolenaar    else
251*b544f3c8SBram Moolenaar	Xpath 'g'
252*b544f3c8SBram Moolenaar    endif
253*b544f3c8SBram Moolenaarendfunction
254*b544f3c8SBram Moolenaar
255*b544f3c8SBram Moolenaarfunction Test_return()
256*b544f3c8SBram Moolenaar    XpathINIT
257*b544f3c8SBram Moolenaar    call T4_F()
258*b544f3c8SBram Moolenaar    Xpath '4'
259*b544f3c8SBram Moolenaar
260*b544f3c8SBram Moolenaar    call assert_equal('ab3e3b2c24', g:Xpath)
261*b544f3c8SBram Moolenaarendfunction
262*b544f3c8SBram Moolenaar
263*b544f3c8SBram Moolenaar
264*b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
265*b544f3c8SBram Moolenaar" Test 5:   :finish							    {{{1
266*b544f3c8SBram Moolenaar"
267*b544f3c8SBram Moolenaar"	    This test executes the body of the function T4_F from the previous
268*b544f3c8SBram Moolenaar"	    test as a script file (:return replaced by :finish).
269*b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
270*b544f3c8SBram Moolenaar
271*b544f3c8SBram Moolenaarfunction Test_finish()
272*b544f3c8SBram Moolenaar    XpathINIT
273*b544f3c8SBram Moolenaar    ExecAsScript T4_F
274*b544f3c8SBram Moolenaar    Xpath '5'
275*b544f3c8SBram Moolenaar    call DeleteTheScript()
276*b544f3c8SBram Moolenaar
277*b544f3c8SBram Moolenaar    call assert_equal('ab3e3b2c25', g:Xpath)
278*b544f3c8SBram Moolenaarendfunction
279*b544f3c8SBram Moolenaar
280*b544f3c8SBram Moolenaar
281*b544f3c8SBram Moolenaar
282*b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
283*b544f3c8SBram Moolenaar" Test 6:   Defining functions in :while loops				    {{{1
284*b544f3c8SBram Moolenaar"
285*b544f3c8SBram Moolenaar"	     Functions can be defined inside other functions.  An inner function
286*b544f3c8SBram Moolenaar"	     gets defined when the outer function is executed.  Functions may
287*b544f3c8SBram Moolenaar"	     also be defined inside while loops.  Expressions in braces for
288*b544f3c8SBram Moolenaar"	     defining the function name are allowed.
289*b544f3c8SBram Moolenaar"
290*b544f3c8SBram Moolenaar"	     The functions are defined when sourcing the script, only the
291*b544f3c8SBram Moolenaar"	     resulting path is checked in the test function.
292*b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
293*b544f3c8SBram Moolenaar
294*b544f3c8SBram MoolenaarXpathINIT
295*b544f3c8SBram Moolenaar
296*b544f3c8SBram Moolenaar" The command CALL collects the argument of all its invocations in "calls"
297*b544f3c8SBram Moolenaar" when used from a function (that is, when the global variable "calls" needs
298*b544f3c8SBram Moolenaar" the "g:" prefix).  This is to check that the function code is skipped when
299*b544f3c8SBram Moolenaar" the function is defined.  For inner functions, do so only if the outer
300*b544f3c8SBram Moolenaar" function is not being executed.
301*b544f3c8SBram Moolenaar"
302*b544f3c8SBram Moolenaarlet calls = ""
303*b544f3c8SBram Moolenaarcom! -nargs=1 CALL
304*b544f3c8SBram Moolenaar    	\ if !exists("calls") && !exists("outer") |
305*b544f3c8SBram Moolenaar    	\ let g:calls = g:calls . <args> |
306*b544f3c8SBram Moolenaar    	\ endif
307*b544f3c8SBram Moolenaar
308*b544f3c8SBram Moolenaarlet i = 0
309*b544f3c8SBram Moolenaarwhile i < 3
310*b544f3c8SBram Moolenaar    let i = i + 1
311*b544f3c8SBram Moolenaar    if i == 1
312*b544f3c8SBram Moolenaar	Xpath 'a'
313*b544f3c8SBram Moolenaar	function! F1(arg)
314*b544f3c8SBram Moolenaar	    CALL a:arg
315*b544f3c8SBram Moolenaar	    let outer = 1
316*b544f3c8SBram Moolenaar
317*b544f3c8SBram Moolenaar	    let j = 0
318*b544f3c8SBram Moolenaar	    while j < 1
319*b544f3c8SBram Moolenaar		Xpath 'b'
320*b544f3c8SBram Moolenaar		let j = j + 1
321*b544f3c8SBram Moolenaar		function! G1(arg)
322*b544f3c8SBram Moolenaar		    CALL a:arg
323*b544f3c8SBram Moolenaar		endfunction
324*b544f3c8SBram Moolenaar		Xpath 'c'
325*b544f3c8SBram Moolenaar	    endwhile
326*b544f3c8SBram Moolenaar	endfunction
327*b544f3c8SBram Moolenaar	Xpath 'd'
328*b544f3c8SBram Moolenaar
329*b544f3c8SBram Moolenaar	continue
330*b544f3c8SBram Moolenaar    endif
331*b544f3c8SBram Moolenaar
332*b544f3c8SBram Moolenaar    Xpath 'e' . i
333*b544f3c8SBram Moolenaar    function! F{i}(i, arg)
334*b544f3c8SBram Moolenaar	CALL a:arg
335*b544f3c8SBram Moolenaar	let outer = 1
336*b544f3c8SBram Moolenaar
337*b544f3c8SBram Moolenaar	if a:i == 3
338*b544f3c8SBram Moolenaar	    Xpath 'f'
339*b544f3c8SBram Moolenaar	endif
340*b544f3c8SBram Moolenaar	let k = 0
341*b544f3c8SBram Moolenaar	while k < 3
342*b544f3c8SBram Moolenaar	    Xpath 'g' . k
343*b544f3c8SBram Moolenaar	    let k = k + 1
344*b544f3c8SBram Moolenaar	    function! G{a:i}{k}(arg)
345*b544f3c8SBram Moolenaar		CALL a:arg
346*b544f3c8SBram Moolenaar	    endfunction
347*b544f3c8SBram Moolenaar	    Xpath 'h' . k
348*b544f3c8SBram Moolenaar	endwhile
349*b544f3c8SBram Moolenaar    endfunction
350*b544f3c8SBram Moolenaar    Xpath 'i'
351*b544f3c8SBram Moolenaar
352*b544f3c8SBram Moolenaarendwhile
353*b544f3c8SBram Moolenaar
354*b544f3c8SBram Moolenaarif exists("*G1")
355*b544f3c8SBram Moolenaar    Xpath 'j'
356*b544f3c8SBram Moolenaarendif
357*b544f3c8SBram Moolenaarif exists("*F1")
358*b544f3c8SBram Moolenaar    call F1("F1")
359*b544f3c8SBram Moolenaar    if exists("*G1")
360*b544f3c8SBram Moolenaar        call G1("G1")
361*b544f3c8SBram Moolenaar    endif
362*b544f3c8SBram Moolenaarendif
363*b544f3c8SBram Moolenaar
364*b544f3c8SBram Moolenaarif exists("G21") || exists("G22") || exists("G23")
365*b544f3c8SBram Moolenaar    Xpath 'k'
366*b544f3c8SBram Moolenaarendif
367*b544f3c8SBram Moolenaarif exists("*F2")
368*b544f3c8SBram Moolenaar    call F2(2, "F2")
369*b544f3c8SBram Moolenaar    if exists("*G21")
370*b544f3c8SBram Moolenaar        call G21("G21")
371*b544f3c8SBram Moolenaar    endif
372*b544f3c8SBram Moolenaar    if exists("*G22")
373*b544f3c8SBram Moolenaar        call G22("G22")
374*b544f3c8SBram Moolenaar    endif
375*b544f3c8SBram Moolenaar    if exists("*G23")
376*b544f3c8SBram Moolenaar        call G23("G23")
377*b544f3c8SBram Moolenaar    endif
378*b544f3c8SBram Moolenaarendif
379*b544f3c8SBram Moolenaar
380*b544f3c8SBram Moolenaarif exists("G31") || exists("G32") || exists("G33")
381*b544f3c8SBram Moolenaar    Xpath 'l'
382*b544f3c8SBram Moolenaarendif
383*b544f3c8SBram Moolenaarif exists("*F3")
384*b544f3c8SBram Moolenaar    call F3(3, "F3")
385*b544f3c8SBram Moolenaar    if exists("*G31")
386*b544f3c8SBram Moolenaar        call G31("G31")
387*b544f3c8SBram Moolenaar    endif
388*b544f3c8SBram Moolenaar    if exists("*G32")
389*b544f3c8SBram Moolenaar        call G32("G32")
390*b544f3c8SBram Moolenaar    endif
391*b544f3c8SBram Moolenaar    if exists("*G33")
392*b544f3c8SBram Moolenaar        call G33("G33")
393*b544f3c8SBram Moolenaar    endif
394*b544f3c8SBram Moolenaarendif
395*b544f3c8SBram Moolenaar
396*b544f3c8SBram MoolenaarXpath 'm'
397*b544f3c8SBram Moolenaar
398*b544f3c8SBram Moolenaarlet g:test6_result = g:Xpath
399*b544f3c8SBram Moolenaarlet g:test6_calls = calls
400*b544f3c8SBram Moolenaar
401*b544f3c8SBram Moolenaarunlet calls
402*b544f3c8SBram Moolenaardelfunction F1
403*b544f3c8SBram Moolenaardelfunction G1
404*b544f3c8SBram Moolenaardelfunction F2
405*b544f3c8SBram Moolenaardelfunction G21
406*b544f3c8SBram Moolenaardelfunction G22
407*b544f3c8SBram Moolenaardelfunction G23
408*b544f3c8SBram Moolenaardelfunction G31
409*b544f3c8SBram Moolenaardelfunction G32
410*b544f3c8SBram Moolenaardelfunction G33
411*b544f3c8SBram Moolenaar
412*b544f3c8SBram Moolenaarfunction Test_defining_functions()
413*b544f3c8SBram Moolenaar    call assert_equal('ade2ie3ibcg0h1g1h2g2h3fg0h1g1h2g2h3m', g:test6_result)
414*b544f3c8SBram Moolenaar    call assert_equal('F1G1F2G21G22G23F3G31G32G33', g:test6_calls)
415*b544f3c8SBram Moolenaarendfunc
416*b544f3c8SBram Moolenaar
417*b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
418*b544f3c8SBram Moolenaar" Test 7:   Continuing on errors outside functions			    {{{1
419*b544f3c8SBram Moolenaar"
420*b544f3c8SBram Moolenaar"	    On an error outside a function, the script processing continues
421*b544f3c8SBram Moolenaar"	    at the line following the outermost :endif or :endwhile.  When not
422*b544f3c8SBram Moolenaar"	    inside an :if or :while, the script processing continues at the next
423*b544f3c8SBram Moolenaar"	    line.
424*b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
425*b544f3c8SBram Moolenaar
426*b544f3c8SBram MoolenaarXpathINIT
427*b544f3c8SBram Moolenaar
428*b544f3c8SBram Moolenaarif 1
429*b544f3c8SBram Moolenaar    Xpath 'a'
430*b544f3c8SBram Moolenaar    while 1
431*b544f3c8SBram Moolenaar	Xpath 'b'
432*b544f3c8SBram Moolenaar	asdf
433*b544f3c8SBram Moolenaar	Xpath 'c'
434*b544f3c8SBram Moolenaar	break
435*b544f3c8SBram Moolenaar    endwhile | Xpath 'd'
436*b544f3c8SBram Moolenaar    Xpath 'e'
437*b544f3c8SBram Moolenaarendif | Xpath 'f'
438*b544f3c8SBram MoolenaarXpath 'g'
439*b544f3c8SBram Moolenaar
440*b544f3c8SBram Moolenaarwhile 1
441*b544f3c8SBram Moolenaar    Xpath 'h'
442*b544f3c8SBram Moolenaar    if 1
443*b544f3c8SBram Moolenaar	Xpath 'i'
444*b544f3c8SBram Moolenaar	asdf
445*b544f3c8SBram Moolenaar	Xpath 'j'
446*b544f3c8SBram Moolenaar    endif | Xpath 'k'
447*b544f3c8SBram Moolenaar    Xpath 'l'
448*b544f3c8SBram Moolenaar    break
449*b544f3c8SBram Moolenaarendwhile | Xpath 'm'
450*b544f3c8SBram MoolenaarXpath 'n'
451*b544f3c8SBram Moolenaar
452*b544f3c8SBram Moolenaarasdf
453*b544f3c8SBram MoolenaarXpath 'o'
454*b544f3c8SBram Moolenaar
455*b544f3c8SBram Moolenaarasdf | Xpath 'p'
456*b544f3c8SBram MoolenaarXpath 'q'
457*b544f3c8SBram Moolenaar
458*b544f3c8SBram Moolenaarlet g:test7_result = g:Xpath
459*b544f3c8SBram Moolenaar
460*b544f3c8SBram Moolenaarfunc Test_error_in_script()
461*b544f3c8SBram Moolenaar    call assert_equal('abghinoq', g:test7_result)
462*b544f3c8SBram Moolenaarendfunc
463*b544f3c8SBram Moolenaar
464*b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
465*b544f3c8SBram Moolenaar" Test 8:   Aborting and continuing on errors inside functions		    {{{1
466*b544f3c8SBram Moolenaar"
467*b544f3c8SBram Moolenaar"	    On an error inside a function without the "abort" attribute, the
468*b544f3c8SBram Moolenaar"	    script processing continues at the next line (unless the error was
469*b544f3c8SBram Moolenaar"	    in a :return command).  On an error inside a function with the
470*b544f3c8SBram Moolenaar"	    "abort" attribute, the function is aborted and the script processing
471*b544f3c8SBram Moolenaar"	    continues after the function call; the value -1 is returned then.
472*b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
473*b544f3c8SBram Moolenaar
474*b544f3c8SBram MoolenaarXpathINIT
475*b544f3c8SBram Moolenaar
476*b544f3c8SBram Moolenaarfunction! T8_F()
477*b544f3c8SBram Moolenaar    if 1
478*b544f3c8SBram Moolenaar	Xpath 'a'
479*b544f3c8SBram Moolenaar	while 1
480*b544f3c8SBram Moolenaar	    Xpath 'b'
481*b544f3c8SBram Moolenaar	    asdf
482*b544f3c8SBram Moolenaar	    Xpath 'c'
483*b544f3c8SBram Moolenaar	    asdf | Xpath 'd'
484*b544f3c8SBram Moolenaar	    Xpath 'e'
485*b544f3c8SBram Moolenaar	    break
486*b544f3c8SBram Moolenaar	endwhile
487*b544f3c8SBram Moolenaar	Xpath 'f'
488*b544f3c8SBram Moolenaar    endif | Xpath 'g'
489*b544f3c8SBram Moolenaar    Xpath 'h'
490*b544f3c8SBram Moolenaar
491*b544f3c8SBram Moolenaar    while 1
492*b544f3c8SBram Moolenaar	Xpath 'i'
493*b544f3c8SBram Moolenaar	if 1
494*b544f3c8SBram Moolenaar	    Xpath 'j'
495*b544f3c8SBram Moolenaar	    asdf
496*b544f3c8SBram Moolenaar	    Xpath 'k'
497*b544f3c8SBram Moolenaar	    asdf | Xpath 'l'
498*b544f3c8SBram Moolenaar	    Xpath 'm'
499*b544f3c8SBram Moolenaar	endif
500*b544f3c8SBram Moolenaar	Xpath 'n'
501*b544f3c8SBram Moolenaar	break
502*b544f3c8SBram Moolenaar    endwhile | Xpath 'o'
503*b544f3c8SBram Moolenaar    Xpath 'p'
504*b544f3c8SBram Moolenaar
505*b544f3c8SBram Moolenaar    return novar		" returns (default return value 0)
506*b544f3c8SBram Moolenaar    Xpath 'q'
507*b544f3c8SBram Moolenaar    return 1			" not reached
508*b544f3c8SBram Moolenaarendfunction
509*b544f3c8SBram Moolenaar
510*b544f3c8SBram Moolenaarfunction! T8_G() abort
511*b544f3c8SBram Moolenaar    if 1
512*b544f3c8SBram Moolenaar	Xpath 'r'
513*b544f3c8SBram Moolenaar	while 1
514*b544f3c8SBram Moolenaar	    Xpath 's'
515*b544f3c8SBram Moolenaar	    asdf		" returns -1
516*b544f3c8SBram Moolenaar	    Xpath 't'
517*b544f3c8SBram Moolenaar	    break
518*b544f3c8SBram Moolenaar	endwhile
519*b544f3c8SBram Moolenaar	Xpath 'v'
520*b544f3c8SBram Moolenaar    endif | Xpath 'w'
521*b544f3c8SBram Moolenaar    Xpath 'x'
522*b544f3c8SBram Moolenaar
523*b544f3c8SBram Moolenaar    return -4			" not reached
524*b544f3c8SBram Moolenaarendfunction
525*b544f3c8SBram Moolenaar
526*b544f3c8SBram Moolenaarfunction! T8_H() abort
527*b544f3c8SBram Moolenaar    while 1
528*b544f3c8SBram Moolenaar	Xpath 'A'
529*b544f3c8SBram Moolenaar	if 1
530*b544f3c8SBram Moolenaar	    Xpath 'B'
531*b544f3c8SBram Moolenaar	    asdf		" returns -1
532*b544f3c8SBram Moolenaar	    Xpath 'C'
533*b544f3c8SBram Moolenaar	endif
534*b544f3c8SBram Moolenaar	Xpath 'D'
535*b544f3c8SBram Moolenaar	break
536*b544f3c8SBram Moolenaar    endwhile | Xpath 'E'
537*b544f3c8SBram Moolenaar    Xpath 'F'
538*b544f3c8SBram Moolenaar
539*b544f3c8SBram Moolenaar    return -4			" not reached
540*b544f3c8SBram Moolenaarendfunction
541*b544f3c8SBram Moolenaar
542*b544f3c8SBram Moolenaar" Aborted functions (T8_G and T8_H) return -1.
543*b544f3c8SBram Moolenaarlet g:test8_sum = (T8_F() + 1) - 4 * T8_G() - 8 * T8_H()
544*b544f3c8SBram MoolenaarXpath 'X'
545*b544f3c8SBram Moolenaarlet g:test8_result = g:Xpath
546*b544f3c8SBram Moolenaar
547*b544f3c8SBram Moolenaarfunc Test_error_in_function()
548*b544f3c8SBram Moolenaar    call assert_equal(13, g:test8_sum)
549*b544f3c8SBram Moolenaar    call assert_equal('abcefghijkmnoprsABX', g:test8_result)
550*b544f3c8SBram Moolenaar
551*b544f3c8SBram Moolenaar    delfunction T8_F
552*b544f3c8SBram Moolenaar    delfunction T8_G
553*b544f3c8SBram Moolenaar    delfunction T8_H
554*b544f3c8SBram Moolenaarendfunc
555*b544f3c8SBram Moolenaar
556*b544f3c8SBram Moolenaar
557*b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
558*b544f3c8SBram Moolenaar" Test 9:   Continuing after aborted functions				    {{{1
559*b544f3c8SBram Moolenaar"
560*b544f3c8SBram Moolenaar"	    When a function with the "abort" attribute is aborted due to an
561*b544f3c8SBram Moolenaar"	    error, the next function back in the call hierarchy without an
562*b544f3c8SBram Moolenaar"	    "abort" attribute continues; the value -1 is returned then.
563*b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
564*b544f3c8SBram Moolenaar
565*b544f3c8SBram MoolenaarXpathINIT
566*b544f3c8SBram Moolenaar
567*b544f3c8SBram Moolenaarfunction! F() abort
568*b544f3c8SBram Moolenaar    Xpath 'a'
569*b544f3c8SBram Moolenaar    let result = G()	" not aborted
570*b544f3c8SBram Moolenaar    Xpath 'b'
571*b544f3c8SBram Moolenaar    if result != 2
572*b544f3c8SBram Moolenaar	Xpath 'c'
573*b544f3c8SBram Moolenaar    endif
574*b544f3c8SBram Moolenaar    return 1
575*b544f3c8SBram Moolenaarendfunction
576*b544f3c8SBram Moolenaar
577*b544f3c8SBram Moolenaarfunction! G()		" no abort attribute
578*b544f3c8SBram Moolenaar    Xpath 'd'
579*b544f3c8SBram Moolenaar    if H() != -1	" aborted
580*b544f3c8SBram Moolenaar	Xpath 'e'
581*b544f3c8SBram Moolenaar    endif
582*b544f3c8SBram Moolenaar    Xpath 'f'
583*b544f3c8SBram Moolenaar    return 2
584*b544f3c8SBram Moolenaarendfunction
585*b544f3c8SBram Moolenaar
586*b544f3c8SBram Moolenaarfunction! H() abort
587*b544f3c8SBram Moolenaar    Xpath 'g'
588*b544f3c8SBram Moolenaar    call I()		" aborted
589*b544f3c8SBram Moolenaar    Xpath 'h'
590*b544f3c8SBram Moolenaar    return 4
591*b544f3c8SBram Moolenaarendfunction
592*b544f3c8SBram Moolenaar
593*b544f3c8SBram Moolenaarfunction! I() abort
594*b544f3c8SBram Moolenaar    Xpath 'i'
595*b544f3c8SBram Moolenaar    asdf		" error
596*b544f3c8SBram Moolenaar    Xpath 'j'
597*b544f3c8SBram Moolenaar    return 8
598*b544f3c8SBram Moolenaarendfunction
599*b544f3c8SBram Moolenaar
600*b544f3c8SBram Moolenaarif F() != 1
601*b544f3c8SBram Moolenaar    Xpath 'k'
602*b544f3c8SBram Moolenaarendif
603*b544f3c8SBram Moolenaar
604*b544f3c8SBram Moolenaarlet g:test9_result = g:Xpath
605*b544f3c8SBram Moolenaar
606*b544f3c8SBram Moolenaardelfunction F
607*b544f3c8SBram Moolenaardelfunction G
608*b544f3c8SBram Moolenaardelfunction H
609*b544f3c8SBram Moolenaardelfunction I
610*b544f3c8SBram Moolenaar
611*b544f3c8SBram Moolenaarfunc Test_func_abort()
612*b544f3c8SBram Moolenaar    call assert_equal('adgifb', g:test9_result)
613*b544f3c8SBram Moolenaarendfunc
614*b544f3c8SBram Moolenaar
615*b544f3c8SBram Moolenaar
616*b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
617*b544f3c8SBram Moolenaar" Test 10:  :if, :elseif, :while argument parsing			    {{{1
618*b544f3c8SBram Moolenaar"
619*b544f3c8SBram Moolenaar"	    A '"' or '|' in an argument expression must not be mixed up with
620*b544f3c8SBram Moolenaar"	    a comment or a next command after a bar.  Parsing errors should
621*b544f3c8SBram Moolenaar"	    be recognized.
622*b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
623*b544f3c8SBram Moolenaar
624*b544f3c8SBram MoolenaarXpathINIT
625*b544f3c8SBram Moolenaar
626*b544f3c8SBram Moolenaarfunction! MSG(enr, emsg)
627*b544f3c8SBram Moolenaar    let english = v:lang == "C" || v:lang =~ '^[Ee]n'
628*b544f3c8SBram Moolenaar    if a:enr == ""
629*b544f3c8SBram Moolenaar	Xout "TODO: Add message number for:" a:emsg
630*b544f3c8SBram Moolenaar	let v:errmsg = ":" . v:errmsg
631*b544f3c8SBram Moolenaar    endif
632*b544f3c8SBram Moolenaar    let match = 1
633*b544f3c8SBram Moolenaar    if v:errmsg !~ '^'.a:enr.':' || (english && v:errmsg !~ a:emsg)
634*b544f3c8SBram Moolenaar	let match = 0
635*b544f3c8SBram Moolenaar	if v:errmsg == ""
636*b544f3c8SBram Moolenaar	    Xout "Message missing."
637*b544f3c8SBram Moolenaar	else
638*b544f3c8SBram Moolenaar	    let v:errmsg = escape(v:errmsg, '"')
639*b544f3c8SBram Moolenaar	    Xout "Unexpected message:" v:errmsg
640*b544f3c8SBram Moolenaar	endif
641*b544f3c8SBram Moolenaar    endif
642*b544f3c8SBram Moolenaar    return match
643*b544f3c8SBram Moolenaarendfunction
644*b544f3c8SBram Moolenaar
645*b544f3c8SBram Moolenaarif 1 || strlen("\"") | Xpath 'a'
646*b544f3c8SBram Moolenaar    Xpath 'b'
647*b544f3c8SBram Moolenaarendif
648*b544f3c8SBram MoolenaarXpath 'c'
649*b544f3c8SBram Moolenaar
650*b544f3c8SBram Moolenaarif 0
651*b544f3c8SBram Moolenaarelseif 1 || strlen("\"") | Xpath 'd'
652*b544f3c8SBram Moolenaar    Xpath 'e'
653*b544f3c8SBram Moolenaarendif
654*b544f3c8SBram MoolenaarXpath 'f'
655*b544f3c8SBram Moolenaar
656*b544f3c8SBram Moolenaarwhile 1 || strlen("\"") | Xpath 'g'
657*b544f3c8SBram Moolenaar    Xpath 'h'
658*b544f3c8SBram Moolenaar    break
659*b544f3c8SBram Moolenaarendwhile
660*b544f3c8SBram MoolenaarXpath 'i'
661*b544f3c8SBram Moolenaar
662*b544f3c8SBram Moolenaarlet v:errmsg = ""
663*b544f3c8SBram Moolenaarif 1 ||| strlen("\"") | Xpath 'j'
664*b544f3c8SBram Moolenaar    Xpath 'k'
665*b544f3c8SBram Moolenaarendif
666*b544f3c8SBram MoolenaarXpath 'l'
667*b544f3c8SBram Moolenaarif !MSG('E15', "Invalid expression")
668*b544f3c8SBram Moolenaar    Xpath 'm'
669*b544f3c8SBram Moolenaarendif
670*b544f3c8SBram Moolenaar
671*b544f3c8SBram Moolenaarlet v:errmsg = ""
672*b544f3c8SBram Moolenaarif 0
673*b544f3c8SBram Moolenaarelseif 1 ||| strlen("\"") | Xpath 'n'
674*b544f3c8SBram Moolenaar    Xpath 'o'
675*b544f3c8SBram Moolenaarendif
676*b544f3c8SBram MoolenaarXpath 'p'
677*b544f3c8SBram Moolenaarif !MSG('E15', "Invalid expression")
678*b544f3c8SBram Moolenaar    Xpath 'q'
679*b544f3c8SBram Moolenaarendif
680*b544f3c8SBram Moolenaar
681*b544f3c8SBram Moolenaarlet v:errmsg = ""
682*b544f3c8SBram Moolenaarwhile 1 ||| strlen("\"") | Xpath 'r'
683*b544f3c8SBram Moolenaar    Xpath 's'
684*b544f3c8SBram Moolenaar    break
685*b544f3c8SBram Moolenaarendwhile
686*b544f3c8SBram MoolenaarXpath 't'
687*b544f3c8SBram Moolenaarif !MSG('E15', "Invalid expression")
688*b544f3c8SBram Moolenaar    Xpath 'u'
689*b544f3c8SBram Moolenaarendif
690*b544f3c8SBram Moolenaar
691*b544f3c8SBram Moolenaarlet g:test10_result = g:Xpath
692*b544f3c8SBram Moolenaardelfunction MSG
693*b544f3c8SBram Moolenaar
694*b544f3c8SBram Moolenaarfunc Test_expr_parsing()
695*b544f3c8SBram Moolenaar    call assert_equal('abcdefghilpt', g:test10_result)
696*b544f3c8SBram Moolenaarendfunc
697*b544f3c8SBram Moolenaar
698*b544f3c8SBram Moolenaar
699*b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
700*b544f3c8SBram Moolenaar" Test 11:  :if, :elseif, :while argument evaluation after abort	    {{{1
701*b544f3c8SBram Moolenaar"
702*b544f3c8SBram Moolenaar"	    When code is skipped over due to an error, the boolean argument to
703*b544f3c8SBram Moolenaar"	    an :if, :elseif, or :while must not be evaluated.
704*b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
705*b544f3c8SBram Moolenaar
706*b544f3c8SBram MoolenaarXpathINIT
707*b544f3c8SBram Moolenaar
708*b544f3c8SBram Moolenaarlet calls = 0
709*b544f3c8SBram Moolenaar
710*b544f3c8SBram Moolenaarfunction! P(num)
711*b544f3c8SBram Moolenaar    let g:calls = g:calls + a:num   " side effect on call
712*b544f3c8SBram Moolenaar    return 0
713*b544f3c8SBram Moolenaarendfunction
714*b544f3c8SBram Moolenaar
715*b544f3c8SBram Moolenaarif 1
716*b544f3c8SBram Moolenaar    Xpath 'a'
717*b544f3c8SBram Moolenaar    asdf		" error
718*b544f3c8SBram Moolenaar    Xpath 'b'
719*b544f3c8SBram Moolenaar    if P(1)		" should not be called
720*b544f3c8SBram Moolenaar	Xpath 'c'
721*b544f3c8SBram Moolenaar    elseif !P(2)	" should not be called
722*b544f3c8SBram Moolenaar	Xpath 'd'
723*b544f3c8SBram Moolenaar    else
724*b544f3c8SBram Moolenaar	Xpath 'e'
725*b544f3c8SBram Moolenaar    endif
726*b544f3c8SBram Moolenaar    Xpath 'f'
727*b544f3c8SBram Moolenaar    while P(4)		" should not be called
728*b544f3c8SBram Moolenaar	Xpath 'g'
729*b544f3c8SBram Moolenaar    endwhile
730*b544f3c8SBram Moolenaar    Xpath 'h'
731*b544f3c8SBram Moolenaarendif
732*b544f3c8SBram MoolenaarXpath 'x'
733*b544f3c8SBram Moolenaar
734*b544f3c8SBram Moolenaarlet g:test11_calls = calls
735*b544f3c8SBram Moolenaarlet g:test11_result = g:Xpath
736*b544f3c8SBram Moolenaar
737*b544f3c8SBram Moolenaarunlet calls
738*b544f3c8SBram Moolenaardelfunction P
739*b544f3c8SBram Moolenaar
740*b544f3c8SBram Moolenaarfunc Test_arg_abort()
741*b544f3c8SBram Moolenaar    call assert_equal(0, g:test11_calls)
742*b544f3c8SBram Moolenaar    call assert_equal('ax', g:test11_result)
743*b544f3c8SBram Moolenaarendfunc
744*b544f3c8SBram Moolenaar
745*b544f3c8SBram Moolenaar
746*b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
747*b544f3c8SBram Moolenaar" Test 12:  Expressions in braces in skipped code			    {{{1
748*b544f3c8SBram Moolenaar"
749*b544f3c8SBram Moolenaar"	    In code skipped over due to an error or inactive conditional,
750*b544f3c8SBram Moolenaar"	    an expression in braces as part of a variable or function name
751*b544f3c8SBram Moolenaar"	    should not be evaluated.
752*b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
753*b544f3c8SBram Moolenaar
754*b544f3c8SBram MoolenaarXpathINIT
755*b544f3c8SBram Moolenaar
756*b544f3c8SBram Moolenaarfunction! NULL()
757*b544f3c8SBram Moolenaar    Xpath 'a'
758*b544f3c8SBram Moolenaar    return 0
759*b544f3c8SBram Moolenaarendfunction
760*b544f3c8SBram Moolenaar
761*b544f3c8SBram Moolenaarfunction! ZERO()
762*b544f3c8SBram Moolenaar    Xpath 'b'
763*b544f3c8SBram Moolenaar    return 0
764*b544f3c8SBram Moolenaarendfunction
765*b544f3c8SBram Moolenaar
766*b544f3c8SBram Moolenaarfunction! F0()
767*b544f3c8SBram Moolenaar    Xpath 'c'
768*b544f3c8SBram Moolenaarendfunction
769*b544f3c8SBram Moolenaar
770*b544f3c8SBram Moolenaarfunction! F1(arg)
771*b544f3c8SBram Moolenaar    Xpath 'e'
772*b544f3c8SBram Moolenaarendfunction
773*b544f3c8SBram Moolenaar
774*b544f3c8SBram Moolenaarlet V0 = 1
775*b544f3c8SBram Moolenaar
776*b544f3c8SBram MoolenaarXpath 'f'
777*b544f3c8SBram Moolenaarecho 0 ? F{NULL() + V{ZERO()}}() : 1
778*b544f3c8SBram Moolenaar
779*b544f3c8SBram MoolenaarXpath 'g'
780*b544f3c8SBram Moolenaarif 0
781*b544f3c8SBram Moolenaar    Xpath 'h'
782*b544f3c8SBram Moolenaar    call F{NULL() + V{ZERO()}}()
783*b544f3c8SBram Moolenaarendif
784*b544f3c8SBram Moolenaar
785*b544f3c8SBram MoolenaarXpath 'i'
786*b544f3c8SBram Moolenaarif 1
787*b544f3c8SBram Moolenaar    asdf		" error
788*b544f3c8SBram Moolenaar    Xpath 'j'
789*b544f3c8SBram Moolenaar    call F1(F{NULL() + V{ZERO()}}())
790*b544f3c8SBram Moolenaarendif
791*b544f3c8SBram Moolenaar
792*b544f3c8SBram MoolenaarXpath 'k'
793*b544f3c8SBram Moolenaarif 1
794*b544f3c8SBram Moolenaar    asdf		" error
795*b544f3c8SBram Moolenaar    Xpath 'l'
796*b544f3c8SBram Moolenaar    call F{NULL() + V{ZERO()}}()
797*b544f3c8SBram Moolenaarendif
798*b544f3c8SBram Moolenaar
799*b544f3c8SBram Moolenaarlet g:test12_result = g:Xpath
800*b544f3c8SBram Moolenaar
801*b544f3c8SBram Moolenaarfunc Test_braces_skipped()
802*b544f3c8SBram Moolenaar    call assert_equal('fgik', g:test12_result)
803*b544f3c8SBram Moolenaarendfunc
804*b544f3c8SBram Moolenaar
805*b544f3c8SBram Moolenaar
806*b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
807*b544f3c8SBram Moolenaar" Test 13:  Failure in argument evaluation for :while			    {{{1
808*b544f3c8SBram Moolenaar"
809*b544f3c8SBram Moolenaar"	    A failure in the expression evaluation for the condition of a :while
810*b544f3c8SBram Moolenaar"	    causes the whole :while loop until the matching :endwhile being
811*b544f3c8SBram Moolenaar"	    ignored.  Continuation is at the next following line.
812*b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
813*b544f3c8SBram Moolenaar
814*b544f3c8SBram MoolenaarXpathINIT
815*b544f3c8SBram Moolenaar
816*b544f3c8SBram MoolenaarXpath 'a'
817*b544f3c8SBram Moolenaarwhile asdf
818*b544f3c8SBram Moolenaar    Xpath 'b'
819*b544f3c8SBram Moolenaar    while 1
820*b544f3c8SBram Moolenaar	Xpath 'c'
821*b544f3c8SBram Moolenaar	break
822*b544f3c8SBram Moolenaar    endwhile
823*b544f3c8SBram Moolenaar    Xpath 'd'
824*b544f3c8SBram Moolenaar    break
825*b544f3c8SBram Moolenaarendwhile
826*b544f3c8SBram MoolenaarXpath 'e'
827*b544f3c8SBram Moolenaar
828*b544f3c8SBram Moolenaarwhile asdf | Xpath 'f' | endwhile | Xpath 'g'
829*b544f3c8SBram MoolenaarXpath 'h'
830*b544f3c8SBram Moolenaarlet g:test13_result = g:Xpath
831*b544f3c8SBram Moolenaar
832*b544f3c8SBram Moolenaarfunc Test_while_fail()
833*b544f3c8SBram Moolenaar    call assert_equal('aeh', g:test13_result)
834*b544f3c8SBram Moolenaarendfunc
835*b544f3c8SBram Moolenaar
836*b544f3c8SBram Moolenaar
837*b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
838*b544f3c8SBram Moolenaar" Test 14:  Failure in argument evaluation for :if			    {{{1
839*b544f3c8SBram Moolenaar"
840*b544f3c8SBram Moolenaar"	    A failure in the expression evaluation for the condition of an :if
841*b544f3c8SBram Moolenaar"	    does not cause the corresponding :else or :endif being matched to
842*b544f3c8SBram Moolenaar"	    a previous :if/:elseif.  Neither of both branches of the failed :if
843*b544f3c8SBram Moolenaar"	    are executed.
844*b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
845*b544f3c8SBram Moolenaar
846*b544f3c8SBram MoolenaarXpathINIT
847*b544f3c8SBram Moolenaar
848*b544f3c8SBram Moolenaarfunction! F()
849*b544f3c8SBram Moolenaar    Xpath 'a'
850*b544f3c8SBram Moolenaar    let x = 0
851*b544f3c8SBram Moolenaar    if x		" false
852*b544f3c8SBram Moolenaar	Xpath 'b'
853*b544f3c8SBram Moolenaar    elseif !x		" always true
854*b544f3c8SBram Moolenaar	Xpath 'c'
855*b544f3c8SBram Moolenaar	let x = 1
856*b544f3c8SBram Moolenaar	if g:boolvar	" possibly undefined
857*b544f3c8SBram Moolenaar	    Xpath 'd'
858*b544f3c8SBram Moolenaar	else
859*b544f3c8SBram Moolenaar	    Xpath 'e'
860*b544f3c8SBram Moolenaar	endif
861*b544f3c8SBram Moolenaar	Xpath 'f'
862*b544f3c8SBram Moolenaar    elseif x		" never executed
863*b544f3c8SBram Moolenaar	Xpath 'g'
864*b544f3c8SBram Moolenaar    endif
865*b544f3c8SBram Moolenaar    Xpath 'h'
866*b544f3c8SBram Moolenaarendfunction
867*b544f3c8SBram Moolenaar
868*b544f3c8SBram Moolenaarlet boolvar = 1
869*b544f3c8SBram Moolenaarcall F()
870*b544f3c8SBram MoolenaarXpath '-'
871*b544f3c8SBram Moolenaar
872*b544f3c8SBram Moolenaarunlet boolvar
873*b544f3c8SBram Moolenaarcall F()
874*b544f3c8SBram Moolenaarlet g:test14_result = g:Xpath
875*b544f3c8SBram Moolenaar
876*b544f3c8SBram Moolenaardelfunction F
877*b544f3c8SBram Moolenaar
878*b544f3c8SBram Moolenaarfunc Test_if_fail()
879*b544f3c8SBram Moolenaar    call assert_equal('acdfh-acfh', g:test14_result)
880*b544f3c8SBram Moolenaarendfunc
881*b544f3c8SBram Moolenaar
882*b544f3c8SBram Moolenaar
883*b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
884*b544f3c8SBram Moolenaar" Test 15:  Failure in argument evaluation for :if (bar)		    {{{1
885*b544f3c8SBram Moolenaar"
886*b544f3c8SBram Moolenaar"	    Like previous test, except that the failing :if ... | ... | :endif
887*b544f3c8SBram Moolenaar"	    is in a single line.
888*b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
889*b544f3c8SBram Moolenaar
890*b544f3c8SBram MoolenaarXpathINIT
891*b544f3c8SBram Moolenaar
892*b544f3c8SBram Moolenaarfunction! F()
893*b544f3c8SBram Moolenaar    Xpath 'a'
894*b544f3c8SBram Moolenaar    let x = 0
895*b544f3c8SBram Moolenaar    if x		" false
896*b544f3c8SBram Moolenaar	Xpath 'b'
897*b544f3c8SBram Moolenaar    elseif !x		" always true
898*b544f3c8SBram Moolenaar	Xpath 'c'
899*b544f3c8SBram Moolenaar	let x = 1
900*b544f3c8SBram Moolenaar	if g:boolvar | Xpath 'd' | else | Xpath 'e' | endif
901*b544f3c8SBram Moolenaar	Xpath 'f'
902*b544f3c8SBram Moolenaar    elseif x		" never executed
903*b544f3c8SBram Moolenaar	Xpath 'g'
904*b544f3c8SBram Moolenaar    endif
905*b544f3c8SBram Moolenaar    Xpath 'h'
906*b544f3c8SBram Moolenaarendfunction
907*b544f3c8SBram Moolenaar
908*b544f3c8SBram Moolenaarlet boolvar = 1
909*b544f3c8SBram Moolenaarcall F()
910*b544f3c8SBram MoolenaarXpath '-'
911*b544f3c8SBram Moolenaar
912*b544f3c8SBram Moolenaarunlet boolvar
913*b544f3c8SBram Moolenaarcall F()
914*b544f3c8SBram Moolenaarlet g:test15_result = g:Xpath
915*b544f3c8SBram Moolenaar
916*b544f3c8SBram Moolenaardelfunction F
917*b544f3c8SBram Moolenaar
918*b544f3c8SBram Moolenaarfunc Test_if_bar_fail()
919*b544f3c8SBram Moolenaar    call assert_equal('acdfh-acfh', g:test15_result)
920*b544f3c8SBram Moolenaarendfunc
921*b544f3c8SBram Moolenaar
922*b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
923*b544f3c8SBram Moolenaar" Test 90:  Recognizing {} in variable name.			    {{{1
924*b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
925*b544f3c8SBram Moolenaar
926*b544f3c8SBram Moolenaarfunc Test_curlies()
927*b544f3c8SBram Moolenaar    let s:var = 66
928*b544f3c8SBram Moolenaar    let ns = 's'
929*b544f3c8SBram Moolenaar    call assert_equal(66, {ns}:var)
930*b544f3c8SBram Moolenaar
931*b544f3c8SBram Moolenaar    let g:a = {}
932*b544f3c8SBram Moolenaar    let g:b = 't'
933*b544f3c8SBram Moolenaar    let g:a[g:b] = 77
934*b544f3c8SBram Moolenaar    call assert_equal(77, g:a['t'])
935*b544f3c8SBram Moolenaarendfunc
936*b544f3c8SBram Moolenaar
937*b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
938*b544f3c8SBram Moolenaar" Test 91:  using type().					    {{{1
939*b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
940*b544f3c8SBram Moolenaar
941*b544f3c8SBram Moolenaarfunc Test_type()
942*b544f3c8SBram Moolenaar    call assert_equal(0, type(0))
943*b544f3c8SBram Moolenaar    call assert_equal(1, type(""))
944*b544f3c8SBram Moolenaar    call assert_equal(2, type(function("tr")))
945*b544f3c8SBram Moolenaar    call assert_equal(2, type(function("tr", [8])))
946*b544f3c8SBram Moolenaar    call assert_equal(3, type([]))
947*b544f3c8SBram Moolenaar    call assert_equal(4, type({}))
948*b544f3c8SBram Moolenaar    call assert_equal(5, type(0.0))
949*b544f3c8SBram Moolenaar    call assert_equal(6, type(v:false))
950*b544f3c8SBram Moolenaar    call assert_equal(6, type(v:true))
951*b544f3c8SBram Moolenaar    call assert_equal(7, type(v:none))
952*b544f3c8SBram Moolenaar    call assert_equal(7, type(v:null))
953*b544f3c8SBram Moolenaar    call assert_equal(8, v:t_job)
954*b544f3c8SBram Moolenaar    call assert_equal(9, v:t_channel)
955*b544f3c8SBram Moolenaar    call assert_equal(v:t_number, type(0))
956*b544f3c8SBram Moolenaar    call assert_equal(v:t_string, type(""))
957*b544f3c8SBram Moolenaar    call assert_equal(v:t_func, type(function("tr")))
958*b544f3c8SBram Moolenaar    call assert_equal(v:t_func, type(function("tr", [8])))
959*b544f3c8SBram Moolenaar    call assert_equal(v:t_list, type([]))
960*b544f3c8SBram Moolenaar    call assert_equal(v:t_dict, type({}))
961*b544f3c8SBram Moolenaar    call assert_equal(v:t_float, type(0.0))
962*b544f3c8SBram Moolenaar    call assert_equal(v:t_bool, type(v:false))
963*b544f3c8SBram Moolenaar    call assert_equal(v:t_bool, type(v:true))
964*b544f3c8SBram Moolenaar    call assert_equal(v:t_none, type(v:none))
965*b544f3c8SBram Moolenaar    call assert_equal(v:t_none, type(v:null))
966*b544f3c8SBram Moolenaar
967*b544f3c8SBram Moolenaar
968*b544f3c8SBram Moolenaar    call assert_equal(0, 0 + v:false)
969*b544f3c8SBram Moolenaar    call assert_equal(1, 0 + v:true)
970*b544f3c8SBram Moolenaar    call assert_equal(0, 0 + v:none)
971*b544f3c8SBram Moolenaar    call assert_equal(0, 0 + v:null)
972*b544f3c8SBram Moolenaar
973*b544f3c8SBram Moolenaar    call assert_equal('v:false', '' . v:false)
974*b544f3c8SBram Moolenaar    call assert_equal('v:true', '' . v:true)
975*b544f3c8SBram Moolenaar    call assert_equal('v:none', '' . v:none)
976*b544f3c8SBram Moolenaar    call assert_equal('v:null', '' . v:null)
977*b544f3c8SBram Moolenaar
978*b544f3c8SBram Moolenaar    call assert_true(v:false == 0)
979*b544f3c8SBram Moolenaar    call assert_false(v:false != 0)
980*b544f3c8SBram Moolenaar    call assert_true(v:true == 1)
981*b544f3c8SBram Moolenaar    call assert_false(v:true != 1)
982*b544f3c8SBram Moolenaar    call assert_false(v:true == v:false)
983*b544f3c8SBram Moolenaar    call assert_true(v:true != v:false)
984*b544f3c8SBram Moolenaar
985*b544f3c8SBram Moolenaar    call assert_true(v:null == 0)
986*b544f3c8SBram Moolenaar    call assert_false(v:null != 0)
987*b544f3c8SBram Moolenaar    call assert_true(v:none == 0)
988*b544f3c8SBram Moolenaar    call assert_false(v:none != 0)
989*b544f3c8SBram Moolenaar
990*b544f3c8SBram Moolenaar    call assert_true(v:false is v:false)
991*b544f3c8SBram Moolenaar    call assert_true(v:true is v:true)
992*b544f3c8SBram Moolenaar    call assert_true(v:none is v:none)
993*b544f3c8SBram Moolenaar    call assert_true(v:null is v:null)
994*b544f3c8SBram Moolenaar
995*b544f3c8SBram Moolenaar    call assert_false(v:false isnot v:false)
996*b544f3c8SBram Moolenaar    call assert_false(v:true isnot v:true)
997*b544f3c8SBram Moolenaar    call assert_false(v:none isnot v:none)
998*b544f3c8SBram Moolenaar    call assert_false(v:null isnot v:null)
999*b544f3c8SBram Moolenaar
1000*b544f3c8SBram Moolenaar    call assert_false(v:false is 0)
1001*b544f3c8SBram Moolenaar    call assert_false(v:true is 1)
1002*b544f3c8SBram Moolenaar    call assert_false(v:true is v:false)
1003*b544f3c8SBram Moolenaar    call assert_false(v:none is 0)
1004*b544f3c8SBram Moolenaar    call assert_false(v:null is 0)
1005*b544f3c8SBram Moolenaar    call assert_false(v:null is v:none)
1006*b544f3c8SBram Moolenaar
1007*b544f3c8SBram Moolenaar    call assert_true(v:false isnot 0)
1008*b544f3c8SBram Moolenaar    call assert_true(v:true isnot 1)
1009*b544f3c8SBram Moolenaar    call assert_true(v:true isnot v:false)
1010*b544f3c8SBram Moolenaar    call assert_true(v:none isnot 0)
1011*b544f3c8SBram Moolenaar    call assert_true(v:null isnot 0)
1012*b544f3c8SBram Moolenaar    call assert_true(v:null isnot v:none)
1013*b544f3c8SBram Moolenaar
1014*b544f3c8SBram Moolenaar    call assert_equal(v:false, eval(string(v:false)))
1015*b544f3c8SBram Moolenaar    call assert_equal(v:true, eval(string(v:true)))
1016*b544f3c8SBram Moolenaar    call assert_equal(v:none, eval(string(v:none)))
1017*b544f3c8SBram Moolenaar    call assert_equal(v:null, eval(string(v:null)))
1018*b544f3c8SBram Moolenaar
1019*b544f3c8SBram Moolenaar    call assert_equal(v:false, copy(v:false))
1020*b544f3c8SBram Moolenaar    call assert_equal(v:true, copy(v:true))
1021*b544f3c8SBram Moolenaar    call assert_equal(v:none, copy(v:none))
1022*b544f3c8SBram Moolenaar    call assert_equal(v:null, copy(v:null))
1023*b544f3c8SBram Moolenaar
1024*b544f3c8SBram Moolenaar    call assert_equal([v:false], deepcopy([v:false]))
1025*b544f3c8SBram Moolenaar    call assert_equal([v:true], deepcopy([v:true]))
1026*b544f3c8SBram Moolenaar    call assert_equal([v:none], deepcopy([v:none]))
1027*b544f3c8SBram Moolenaar    call assert_equal([v:null], deepcopy([v:null]))
1028*b544f3c8SBram Moolenaar
1029*b544f3c8SBram Moolenaar    call assert_true(empty(v:false))
1030*b544f3c8SBram Moolenaar    call assert_false(empty(v:true))
1031*b544f3c8SBram Moolenaar    call assert_true(empty(v:null))
1032*b544f3c8SBram Moolenaar    call assert_true(empty(v:none))
1033*b544f3c8SBram Moolenaar
1034*b544f3c8SBram Moolenaar    func ChangeYourMind()
1035*b544f3c8SBram Moolenaar      try
1036*b544f3c8SBram Moolenaar	return v:true
1037*b544f3c8SBram Moolenaar      finally
1038*b544f3c8SBram Moolenaar        return 'something else'
1039*b544f3c8SBram Moolenaar      endtry
1040*b544f3c8SBram Moolenaar    endfunc
1041*b544f3c8SBram Moolenaar
1042*b544f3c8SBram Moolenaar    call ChangeYourMind()
1043*b544f3c8SBram Moolenaarendfunc
1044*b544f3c8SBram Moolenaar
1045*b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
1046*b544f3c8SBram Moolenaar" Test 92:  skipping code					    {{{1
1047*b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
1048*b544f3c8SBram Moolenaar
1049*b544f3c8SBram Moolenaarfunc Test_skip()
1050*b544f3c8SBram Moolenaar    let Fn = function('Test_type')
1051*b544f3c8SBram Moolenaar    call assert_false(0 && Fn[1])
1052*b544f3c8SBram Moolenaar    call assert_false(0 && string(Fn))
1053*b544f3c8SBram Moolenaar    call assert_false(0 && len(Fn))
1054*b544f3c8SBram Moolenaar    let l = []
1055*b544f3c8SBram Moolenaar    call assert_false(0 && l[1])
1056*b544f3c8SBram Moolenaar    call assert_false(0 && string(l))
1057*b544f3c8SBram Moolenaar    call assert_false(0 && len(l))
1058*b544f3c8SBram Moolenaar    let f = 1.0
1059*b544f3c8SBram Moolenaar    call assert_false(0 && f[1])
1060*b544f3c8SBram Moolenaar    call assert_false(0 && string(f))
1061*b544f3c8SBram Moolenaar    call assert_false(0 && len(f))
1062*b544f3c8SBram Moolenaar    let sp = v:null
1063*b544f3c8SBram Moolenaar    call assert_false(0 && sp[1])
1064*b544f3c8SBram Moolenaar    call assert_false(0 && string(sp))
1065*b544f3c8SBram Moolenaar    call assert_false(0 && len(sp))
1066*b544f3c8SBram Moolenaar
1067*b544f3c8SBram Moolenaarendfunc
1068*b544f3c8SBram Moolenaar
1069*b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
1070*b544f3c8SBram Moolenaar" Test 93:  :echo and string()					    {{{1
1071*b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
1072*b544f3c8SBram Moolenaar
1073*b544f3c8SBram Moolenaarfunc Test_echo_and_string()
1074*b544f3c8SBram Moolenaar    " String
1075*b544f3c8SBram Moolenaar    let a = 'foo bar'
1076*b544f3c8SBram Moolenaar    redir => result
1077*b544f3c8SBram Moolenaar    echo a
1078*b544f3c8SBram Moolenaar    echo string(a)
1079*b544f3c8SBram Moolenaar    redir END
1080*b544f3c8SBram Moolenaar    let l = split(result, "\n")
1081*b544f3c8SBram Moolenaar    call assert_equal(["foo bar",
1082*b544f3c8SBram Moolenaar		     \ "'foo bar'"], l)
1083*b544f3c8SBram Moolenaar
1084*b544f3c8SBram Moolenaar    " Float
1085*b544f3c8SBram Moolenaar    if has('float')
1086*b544f3c8SBram Moolenaar	let a = -1.2e0
1087*b544f3c8SBram Moolenaar	redir => result
1088*b544f3c8SBram Moolenaar	echo a
1089*b544f3c8SBram Moolenaar	echo string(a)
1090*b544f3c8SBram Moolenaar	redir END
1091*b544f3c8SBram Moolenaar	let l = split(result, "\n")
1092*b544f3c8SBram Moolenaar	call assert_equal(["-1.2",
1093*b544f3c8SBram Moolenaar			 \ "-1.2"], l)
1094*b544f3c8SBram Moolenaar    endif
1095*b544f3c8SBram Moolenaar
1096*b544f3c8SBram Moolenaar    " Funcref
1097*b544f3c8SBram Moolenaar    redir => result
1098*b544f3c8SBram Moolenaar    echo function('string')
1099*b544f3c8SBram Moolenaar    echo string(function('string'))
1100*b544f3c8SBram Moolenaar    redir END
1101*b544f3c8SBram Moolenaar    let l = split(result, "\n")
1102*b544f3c8SBram Moolenaar    call assert_equal(["string",
1103*b544f3c8SBram Moolenaar		     \ "function('string')"], l)
1104*b544f3c8SBram Moolenaar
1105*b544f3c8SBram Moolenaar    " Recursive dictionary
1106*b544f3c8SBram Moolenaar    let a = {}
1107*b544f3c8SBram Moolenaar    let a["a"] = a
1108*b544f3c8SBram Moolenaar    redir => result
1109*b544f3c8SBram Moolenaar    echo a
1110*b544f3c8SBram Moolenaar    echo string(a)
1111*b544f3c8SBram Moolenaar    redir END
1112*b544f3c8SBram Moolenaar    let l = split(result, "\n")
1113*b544f3c8SBram Moolenaar    call assert_equal(["{'a': {...}}",
1114*b544f3c8SBram Moolenaar		     \ "{'a': {...}}"], l)
1115*b544f3c8SBram Moolenaar
1116*b544f3c8SBram Moolenaar    " Recursive list
1117*b544f3c8SBram Moolenaar    let a = [0]
1118*b544f3c8SBram Moolenaar    let a[0] = a
1119*b544f3c8SBram Moolenaar    redir => result
1120*b544f3c8SBram Moolenaar    echo a
1121*b544f3c8SBram Moolenaar    echo string(a)
1122*b544f3c8SBram Moolenaar    redir END
1123*b544f3c8SBram Moolenaar    let l = split(result, "\n")
1124*b544f3c8SBram Moolenaar    call assert_equal(["[[...]]",
1125*b544f3c8SBram Moolenaar		     \ "[[...]]"], l)
1126*b544f3c8SBram Moolenaar
1127*b544f3c8SBram Moolenaar    " Empty dictionaries in a list
1128*b544f3c8SBram Moolenaar    let a = {}
1129*b544f3c8SBram Moolenaar    redir => result
1130*b544f3c8SBram Moolenaar    echo [a, a, a]
1131*b544f3c8SBram Moolenaar    echo string([a, a, a])
1132*b544f3c8SBram Moolenaar    redir END
1133*b544f3c8SBram Moolenaar    let l = split(result, "\n")
1134*b544f3c8SBram Moolenaar    call assert_equal(["[{}, {}, {}]",
1135*b544f3c8SBram Moolenaar		     \ "[{}, {}, {}]"], l)
1136*b544f3c8SBram Moolenaar
1137*b544f3c8SBram Moolenaar    " Empty dictionaries in a dictionary
1138*b544f3c8SBram Moolenaar    let a = {}
1139*b544f3c8SBram Moolenaar    let b = {"a": a, "b": a}
1140*b544f3c8SBram Moolenaar    redir => result
1141*b544f3c8SBram Moolenaar    echo b
1142*b544f3c8SBram Moolenaar    echo string(b)
1143*b544f3c8SBram Moolenaar    redir END
1144*b544f3c8SBram Moolenaar    let l = split(result, "\n")
1145*b544f3c8SBram Moolenaar    call assert_equal(["{'a': {}, 'b': {}}",
1146*b544f3c8SBram Moolenaar		     \ "{'a': {}, 'b': {}}"], l)
1147*b544f3c8SBram Moolenaar
1148*b544f3c8SBram Moolenaar    " Empty lists in a list
1149*b544f3c8SBram Moolenaar    let a = []
1150*b544f3c8SBram Moolenaar    redir => result
1151*b544f3c8SBram Moolenaar    echo [a, a, a]
1152*b544f3c8SBram Moolenaar    echo string([a, a, a])
1153*b544f3c8SBram Moolenaar    redir END
1154*b544f3c8SBram Moolenaar    let l = split(result, "\n")
1155*b544f3c8SBram Moolenaar    call assert_equal(["[[], [], []]",
1156*b544f3c8SBram Moolenaar		     \ "[[], [], []]"], l)
1157*b544f3c8SBram Moolenaar
1158*b544f3c8SBram Moolenaar    " Empty lists in a dictionary
1159*b544f3c8SBram Moolenaar    let a = []
1160*b544f3c8SBram Moolenaar    let b = {"a": a, "b": a}
1161*b544f3c8SBram Moolenaar    redir => result
1162*b544f3c8SBram Moolenaar    echo b
1163*b544f3c8SBram Moolenaar    echo string(b)
1164*b544f3c8SBram Moolenaar    redir END
1165*b544f3c8SBram Moolenaar    let l = split(result, "\n")
1166*b544f3c8SBram Moolenaar    call assert_equal(["{'a': [], 'b': []}",
1167*b544f3c8SBram Moolenaar		     \ "{'a': [], 'b': []}"], l)
1168*b544f3c8SBram Moolenaar
1169*b544f3c8SBram Moolenaar    " Dictionaries in a list
1170*b544f3c8SBram Moolenaar    let a = {"one": "yes", "two": "yes", "three": "yes"}
1171*b544f3c8SBram Moolenaar    redir => result
1172*b544f3c8SBram Moolenaar    echo [a, a, a]
1173*b544f3c8SBram Moolenaar    echo string([a, a, a])
1174*b544f3c8SBram Moolenaar    redir END
1175*b544f3c8SBram Moolenaar    let l = split(result, "\n")
1176*b544f3c8SBram Moolenaar    call assert_equal(["[{'one': 'yes', 'two': 'yes', 'three': 'yes'}, {...}, {...}]",
1177*b544f3c8SBram Moolenaar		     \ "[{'one': 'yes', 'two': 'yes', 'three': 'yes'}, {'one': 'yes', 'two': 'yes', 'three': 'yes'}, {'one': 'yes', 'two': 'yes', 'three': 'yes'}]"], l)
1178*b544f3c8SBram Moolenaar
1179*b544f3c8SBram Moolenaar    " Dictionaries in a dictionary
1180*b544f3c8SBram Moolenaar    let a = {"one": "yes", "two": "yes", "three": "yes"}
1181*b544f3c8SBram Moolenaar    let b = {"a": a, "b": a}
1182*b544f3c8SBram Moolenaar    redir => result
1183*b544f3c8SBram Moolenaar    echo b
1184*b544f3c8SBram Moolenaar    echo string(b)
1185*b544f3c8SBram Moolenaar    redir END
1186*b544f3c8SBram Moolenaar    let l = split(result, "\n")
1187*b544f3c8SBram Moolenaar    call assert_equal(["{'a': {'one': 'yes', 'two': 'yes', 'three': 'yes'}, 'b': {...}}",
1188*b544f3c8SBram Moolenaar		     \ "{'a': {'one': 'yes', 'two': 'yes', 'three': 'yes'}, 'b': {'one': 'yes', 'two': 'yes', 'three': 'yes'}}"], l)
1189*b544f3c8SBram Moolenaar
1190*b544f3c8SBram Moolenaar    " Lists in a list
1191*b544f3c8SBram Moolenaar    let a = [1, 2, 3]
1192*b544f3c8SBram Moolenaar    redir => result
1193*b544f3c8SBram Moolenaar    echo [a, a, a]
1194*b544f3c8SBram Moolenaar    echo string([a, a, a])
1195*b544f3c8SBram Moolenaar    redir END
1196*b544f3c8SBram Moolenaar    let l = split(result, "\n")
1197*b544f3c8SBram Moolenaar    call assert_equal(["[[1, 2, 3], [...], [...]]",
1198*b544f3c8SBram Moolenaar		     \ "[[1, 2, 3], [1, 2, 3], [1, 2, 3]]"], l)
1199*b544f3c8SBram Moolenaar
1200*b544f3c8SBram Moolenaar    " Lists in a dictionary
1201*b544f3c8SBram Moolenaar    let a = [1, 2, 3]
1202*b544f3c8SBram Moolenaar    let b = {"a": a, "b": a}
1203*b544f3c8SBram Moolenaar    redir => result
1204*b544f3c8SBram Moolenaar    echo b
1205*b544f3c8SBram Moolenaar    echo string(b)
1206*b544f3c8SBram Moolenaar    redir END
1207*b544f3c8SBram Moolenaar    let l = split(result, "\n")
1208*b544f3c8SBram Moolenaar    call assert_equal(["{'a': [1, 2, 3], 'b': [...]}",
1209*b544f3c8SBram Moolenaar		     \ "{'a': [1, 2, 3], 'b': [1, 2, 3]}"], l)
1210*b544f3c8SBram Moolenaar
1211*b544f3c8SBram Moolenaarendfunc
1212*b544f3c8SBram Moolenaar
1213*b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
1214*b544f3c8SBram Moolenaar" Test 94:  64-bit Numbers					    {{{1
1215*b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
1216*b544f3c8SBram Moolenaar
1217*b544f3c8SBram Moolenaarfunc Test_num64()
1218*b544f3c8SBram Moolenaar    if !has('num64')
1219*b544f3c8SBram Moolenaar	return
1220*b544f3c8SBram Moolenaar    endif
1221*b544f3c8SBram Moolenaar
1222*b544f3c8SBram Moolenaar    call assert_notequal( 4294967296, 0)
1223*b544f3c8SBram Moolenaar    call assert_notequal(-4294967296, 0)
1224*b544f3c8SBram Moolenaar    call assert_equal( 4294967296,  0xFFFFffff + 1)
1225*b544f3c8SBram Moolenaar    call assert_equal(-4294967296, -0xFFFFffff - 1)
1226*b544f3c8SBram Moolenaar
1227*b544f3c8SBram Moolenaar    call assert_equal( 9223372036854775807,  1 / 0)
1228*b544f3c8SBram Moolenaar    call assert_equal(-9223372036854775807, -1 / 0)
1229*b544f3c8SBram Moolenaar    call assert_equal(-9223372036854775807 - 1,  0 / 0)
1230*b544f3c8SBram Moolenaar
1231*b544f3c8SBram Moolenaar    call assert_equal( 0x7FFFffffFFFFffff, float2nr( 1.0e150))
1232*b544f3c8SBram Moolenaar    call assert_equal(-0x7FFFffffFFFFffff, float2nr(-1.0e150))
1233*b544f3c8SBram Moolenaar
1234*b544f3c8SBram Moolenaar    let rng = range(0xFFFFffff, 0x100000001)
1235*b544f3c8SBram Moolenaar    call assert_equal([0xFFFFffff, 0x100000000, 0x100000001], rng)
1236*b544f3c8SBram Moolenaar    call assert_equal(0x100000001, max(rng))
1237*b544f3c8SBram Moolenaar    call assert_equal(0xFFFFffff, min(rng))
1238*b544f3c8SBram Moolenaar    call assert_equal(rng, sort(range(0x100000001, 0xFFFFffff, -1), 'N'))
1239*b544f3c8SBram Moolenaarendfunc
1240*b544f3c8SBram Moolenaar
1241*b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
1242*b544f3c8SBram Moolenaar" Test 95:  lines of :append, :change, :insert			    {{{1
1243*b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
1244*b544f3c8SBram Moolenaar
1245*b544f3c8SBram Moolenaarfunction! DefineFunction(name, body)
1246*b544f3c8SBram Moolenaar    let func = join(['function! ' . a:name . '()'] + a:body + ['endfunction'], "\n")
1247*b544f3c8SBram Moolenaar    exec func
1248*b544f3c8SBram Moolenaarendfunction
1249*b544f3c8SBram Moolenaar
1250*b544f3c8SBram Moolenaarfunc Test_script_lines()
1251*b544f3c8SBram Moolenaar    " :append
1252*b544f3c8SBram Moolenaar    try
1253*b544f3c8SBram Moolenaar        call DefineFunction('T_Append', [
1254*b544f3c8SBram Moolenaar                    \ 'append',
1255*b544f3c8SBram Moolenaar                    \ 'py <<EOS',
1256*b544f3c8SBram Moolenaar                    \ '.',
1257*b544f3c8SBram Moolenaar                    \ ])
1258*b544f3c8SBram Moolenaar    catch
1259*b544f3c8SBram Moolenaar        call assert_false(1, "Can't define function")
1260*b544f3c8SBram Moolenaar    endtry
1261*b544f3c8SBram Moolenaar    try
1262*b544f3c8SBram Moolenaar        call DefineFunction('T_Append', [
1263*b544f3c8SBram Moolenaar                    \ 'append',
1264*b544f3c8SBram Moolenaar                    \ 'abc',
1265*b544f3c8SBram Moolenaar                    \ ])
1266*b544f3c8SBram Moolenaar        call assert_false(1, "Shouldn't be able to define function")
1267*b544f3c8SBram Moolenaar    catch
1268*b544f3c8SBram Moolenaar        call assert_exception('Vim(function):E126: Missing :endfunction')
1269*b544f3c8SBram Moolenaar    endtry
1270*b544f3c8SBram Moolenaar
1271*b544f3c8SBram Moolenaar    " :change
1272*b544f3c8SBram Moolenaar    try
1273*b544f3c8SBram Moolenaar        call DefineFunction('T_Change', [
1274*b544f3c8SBram Moolenaar                    \ 'change',
1275*b544f3c8SBram Moolenaar                    \ 'py <<EOS',
1276*b544f3c8SBram Moolenaar                    \ '.',
1277*b544f3c8SBram Moolenaar                    \ ])
1278*b544f3c8SBram Moolenaar    catch
1279*b544f3c8SBram Moolenaar        call assert_false(1, "Can't define function")
1280*b544f3c8SBram Moolenaar    endtry
1281*b544f3c8SBram Moolenaar    try
1282*b544f3c8SBram Moolenaar        call DefineFunction('T_Change', [
1283*b544f3c8SBram Moolenaar                    \ 'change',
1284*b544f3c8SBram Moolenaar                    \ 'abc',
1285*b544f3c8SBram Moolenaar                    \ ])
1286*b544f3c8SBram Moolenaar        call assert_false(1, "Shouldn't be able to define function")
1287*b544f3c8SBram Moolenaar    catch
1288*b544f3c8SBram Moolenaar        call assert_exception('Vim(function):E126: Missing :endfunction')
1289*b544f3c8SBram Moolenaar    endtry
1290*b544f3c8SBram Moolenaar
1291*b544f3c8SBram Moolenaar    " :insert
1292*b544f3c8SBram Moolenaar    try
1293*b544f3c8SBram Moolenaar        call DefineFunction('T_Insert', [
1294*b544f3c8SBram Moolenaar                    \ 'insert',
1295*b544f3c8SBram Moolenaar                    \ 'py <<EOS',
1296*b544f3c8SBram Moolenaar                    \ '.',
1297*b544f3c8SBram Moolenaar                    \ ])
1298*b544f3c8SBram Moolenaar    catch
1299*b544f3c8SBram Moolenaar        call assert_false(1, "Can't define function")
1300*b544f3c8SBram Moolenaar    endtry
1301*b544f3c8SBram Moolenaar    try
1302*b544f3c8SBram Moolenaar        call DefineFunction('T_Insert', [
1303*b544f3c8SBram Moolenaar                    \ 'insert',
1304*b544f3c8SBram Moolenaar                    \ 'abc',
1305*b544f3c8SBram Moolenaar                    \ ])
1306*b544f3c8SBram Moolenaar        call assert_false(1, "Shouldn't be able to define function")
1307*b544f3c8SBram Moolenaar    catch
1308*b544f3c8SBram Moolenaar        call assert_exception('Vim(function):E126: Missing :endfunction')
1309*b544f3c8SBram Moolenaar    endtry
1310*b544f3c8SBram Moolenaarendfunc
1311*b544f3c8SBram Moolenaar
1312*b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
1313*b544f3c8SBram Moolenaar" Modelines								    {{{1
1314*b544f3c8SBram Moolenaar" vim: ts=8 sw=4 tw=80 fdm=marker
1315*b544f3c8SBram Moolenaar" vim: fdt=substitute(substitute(foldtext(),\ '\\%(^+--\\)\\@<=\\(\\s*\\)\\(.\\{-}\\)\:\ \\%(\"\ \\)\\=\\(Test\ \\d*\\)\:\\s*',\ '\\3\ (\\2)\:\ \\1',\ \"\"),\ '\\(Test\\s*\\)\\(\\d\\)\\D\\@=',\ '\\1\ \\2',\ "")
1316*b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
1317