15d7ead3bSBram Moolenaar" Test various aspects of the Vim script language.
2b544f3c8SBram Moolenaar" Most of this was formerly in test49.
3b544f3c8SBram Moolenaar
4b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
5b544f3c8SBram Moolenaar" Test environment							    {{{1
6b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
7b544f3c8SBram Moolenaar
8b544f3c8SBram Moolenaarcom!		   XpathINIT  let g:Xpath = ''
9b544f3c8SBram Moolenaarcom! -nargs=1 -bar Xpath      let g:Xpath = g:Xpath . <args>
10b544f3c8SBram Moolenaar
11b544f3c8SBram Moolenaar" Append a message to the "messages" file
121e115360SBram Moolenaarfunc Xout(text)
13b544f3c8SBram Moolenaar    split messages
14b544f3c8SBram Moolenaar    $put =a:text
15b544f3c8SBram Moolenaar    wq
16b544f3c8SBram Moolenaarendfunc
17b544f3c8SBram Moolenaar
18b544f3c8SBram Moolenaarcom! -nargs=1	     Xout     call Xout(<args>)
19b544f3c8SBram Moolenaar
20b544f3c8SBram Moolenaar" MakeScript() - Make a script file from a function.			    {{{2
21b544f3c8SBram Moolenaar"
22b544f3c8SBram Moolenaar" Create a script that consists of the body of the function a:funcname.
23b544f3c8SBram Moolenaar" Replace any ":return" by a ":finish", any argument variable by a global
24e21c1580SBram Moolenaar" variable, and every ":call" by a ":source" for the next following argument
25b544f3c8SBram Moolenaar" in the variable argument list.  This function is useful if similar tests are
26b544f3c8SBram Moolenaar" to be made for a ":return" from a function call or a ":finish" in a script
27b544f3c8SBram Moolenaar" file.
281e115360SBram Moolenaarfunc MakeScript(funcname, ...)
29b544f3c8SBram Moolenaar    let script = tempname()
30b544f3c8SBram Moolenaar    execute "redir! >" . script
31b544f3c8SBram Moolenaar    execute "function" a:funcname
32b544f3c8SBram Moolenaar    redir END
33b544f3c8SBram Moolenaar    execute "edit" script
34b544f3c8SBram Moolenaar    " Delete the "function" and the "endfunction" lines.  Do not include the
35b544f3c8SBram Moolenaar    " word "function" in the pattern since it might be translated if LANG is
36b544f3c8SBram Moolenaar    " set.  When MakeScript() is being debugged, this deletes also the debugging
37b544f3c8SBram Moolenaar    " output of its line 3 and 4.
38b544f3c8SBram Moolenaar    exec '1,/.*' . a:funcname . '(.*)/d'
39b544f3c8SBram Moolenaar    /^\d*\s*endfunction\>/,$d
40b544f3c8SBram Moolenaar    %s/^\d*//e
41b544f3c8SBram Moolenaar    %s/return/finish/e
42b544f3c8SBram Moolenaar    %s/\<a:\(\h\w*\)/g:\1/ge
43b544f3c8SBram Moolenaar    normal gg0
44b544f3c8SBram Moolenaar    let cnt = 0
45b544f3c8SBram Moolenaar    while search('\<call\s*\%(\u\|s:\)\w*\s*(.*)', 'W') > 0
46b544f3c8SBram Moolenaar	let cnt = cnt + 1
47b544f3c8SBram Moolenaar	s/\<call\s*\%(\u\|s:\)\w*\s*(.*)/\='source ' . a:{cnt}/
48b544f3c8SBram Moolenaar    endwhile
49b544f3c8SBram Moolenaar    g/^\s*$/d
50b544f3c8SBram Moolenaar    write
51b544f3c8SBram Moolenaar    bwipeout
52b544f3c8SBram Moolenaar    return script
531e115360SBram Moolenaarendfunc
54b544f3c8SBram Moolenaar
55b544f3c8SBram Moolenaar" ExecAsScript - Source a temporary script made from a function.	    {{{2
56b544f3c8SBram Moolenaar"
57b544f3c8SBram Moolenaar" Make a temporary script file from the function a:funcname, ":source" it, and
58b544f3c8SBram Moolenaar" delete it afterwards.  However, if an exception is thrown the file may remain,
59b544f3c8SBram Moolenaar" the caller should call DeleteTheScript() afterwards.
60b544f3c8SBram Moolenaarlet s:script_name = ''
61b544f3c8SBram Moolenaarfunction! ExecAsScript(funcname)
62b544f3c8SBram Moolenaar    " Make a script from the function passed as argument.
63b544f3c8SBram Moolenaar    let s:script_name = MakeScript(a:funcname)
64b544f3c8SBram Moolenaar
65b544f3c8SBram Moolenaar    " Source and delete the script.
66b544f3c8SBram Moolenaar    exec "source" s:script_name
67b544f3c8SBram Moolenaar    call delete(s:script_name)
68b544f3c8SBram Moolenaar    let s:script_name = ''
69b544f3c8SBram Moolenaarendfunction
70b544f3c8SBram Moolenaar
71b544f3c8SBram Moolenaarfunction! DeleteTheScript()
72b544f3c8SBram Moolenaar    if s:script_name
73b544f3c8SBram Moolenaar	call delete(s:script_name)
74b544f3c8SBram Moolenaar	let s:script_name = ''
75b544f3c8SBram Moolenaar    endif
76b544f3c8SBram Moolenaarendfunc
77b544f3c8SBram Moolenaar
78b544f3c8SBram Moolenaarcom! -nargs=1 -bar ExecAsScript call ExecAsScript(<f-args>)
79b544f3c8SBram Moolenaar
80b544f3c8SBram Moolenaar
81b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
82b544f3c8SBram Moolenaar" Test 1:   :endwhile in function					    {{{1
83b544f3c8SBram Moolenaar"
84b544f3c8SBram Moolenaar"	    Detect if a broken loop is (incorrectly) reactivated by the
85b544f3c8SBram Moolenaar"	    :endwhile.  Use a :return to prevent an endless loop, and make
86b544f3c8SBram Moolenaar"	    this test first to get a meaningful result on an error before other
87b544f3c8SBram Moolenaar"	    tests will hang.
88b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
89b544f3c8SBram Moolenaar
90b544f3c8SBram Moolenaarfunction! T1_F()
91b544f3c8SBram Moolenaar    Xpath 'a'
92b544f3c8SBram Moolenaar    let first = 1
93b544f3c8SBram Moolenaar    while 1
94b544f3c8SBram Moolenaar	Xpath 'b'
95b544f3c8SBram Moolenaar	if first
96b544f3c8SBram Moolenaar	    Xpath 'c'
97b544f3c8SBram Moolenaar	    let first = 0
98b544f3c8SBram Moolenaar	    break
99b544f3c8SBram Moolenaar	else
100b544f3c8SBram Moolenaar	    Xpath 'd'
101b544f3c8SBram Moolenaar	    return
102b544f3c8SBram Moolenaar	endif
103b544f3c8SBram Moolenaar    endwhile
104b544f3c8SBram Moolenaarendfunction
105b544f3c8SBram Moolenaar
106b544f3c8SBram Moolenaarfunction! T1_G()
107b544f3c8SBram Moolenaar    Xpath 'h'
108b544f3c8SBram Moolenaar    let first = 1
109b544f3c8SBram Moolenaar    while 1
110b544f3c8SBram Moolenaar	Xpath 'i'
111b544f3c8SBram Moolenaar	if first
112b544f3c8SBram Moolenaar	    Xpath 'j'
113b544f3c8SBram Moolenaar	    let first = 0
114b544f3c8SBram Moolenaar	    break
115b544f3c8SBram Moolenaar	else
116b544f3c8SBram Moolenaar	    Xpath 'k'
117b544f3c8SBram Moolenaar	    return
118b544f3c8SBram Moolenaar	endif
119b544f3c8SBram Moolenaar	if 1	" unmatched :if
120b544f3c8SBram Moolenaar    endwhile
121b544f3c8SBram Moolenaarendfunction
122b544f3c8SBram Moolenaar
123b544f3c8SBram Moolenaarfunc Test_endwhile_function()
124b544f3c8SBram Moolenaar  XpathINIT
125b544f3c8SBram Moolenaar  call T1_F()
126b544f3c8SBram Moolenaar  Xpath 'F'
127b544f3c8SBram Moolenaar
128b544f3c8SBram Moolenaar  try
129b544f3c8SBram Moolenaar    call T1_G()
130b544f3c8SBram Moolenaar  catch
131b544f3c8SBram Moolenaar    " Catch missing :endif
132b544f3c8SBram Moolenaar    call assert_true(v:exception =~ 'E171')
133b544f3c8SBram Moolenaar    Xpath 'x'
134b544f3c8SBram Moolenaar  endtry
135b544f3c8SBram Moolenaar  Xpath 'G'
136b544f3c8SBram Moolenaar
137b544f3c8SBram Moolenaar  call assert_equal('abcFhijxG', g:Xpath)
138b544f3c8SBram Moolenaarendfunc
139b544f3c8SBram Moolenaar
140b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
141b544f3c8SBram Moolenaar" Test 2:   :endwhile in script						    {{{1
142b544f3c8SBram Moolenaar"
143b544f3c8SBram Moolenaar"	    Detect if a broken loop is (incorrectly) reactivated by the
144b544f3c8SBram Moolenaar"	    :endwhile.  Use a :finish to prevent an endless loop, and place
145b544f3c8SBram Moolenaar"	    this test before others that might hang to get a meaningful result
146b544f3c8SBram Moolenaar"	    on an error.
147b544f3c8SBram Moolenaar"
148b544f3c8SBram Moolenaar"	    This test executes the bodies of the functions T1_F and T1_G from
149b544f3c8SBram Moolenaar"	    the previous test as script files (:return replaced by :finish).
150b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
151b544f3c8SBram Moolenaar
152b544f3c8SBram Moolenaarfunc Test_endwhile_script()
153b544f3c8SBram Moolenaar  XpathINIT
154b544f3c8SBram Moolenaar  ExecAsScript T1_F
155b544f3c8SBram Moolenaar  Xpath 'F'
156b544f3c8SBram Moolenaar  call DeleteTheScript()
157b544f3c8SBram Moolenaar
158b544f3c8SBram Moolenaar  try
159b544f3c8SBram Moolenaar    ExecAsScript T1_G
160b544f3c8SBram Moolenaar  catch
161b544f3c8SBram Moolenaar    " Catch missing :endif
162b544f3c8SBram Moolenaar    call assert_true(v:exception =~ 'E171')
163b544f3c8SBram Moolenaar    Xpath 'x'
164b544f3c8SBram Moolenaar  endtry
165b544f3c8SBram Moolenaar  Xpath 'G'
166b544f3c8SBram Moolenaar  call DeleteTheScript()
167b544f3c8SBram Moolenaar
168b544f3c8SBram Moolenaar  call assert_equal('abcFhijxG', g:Xpath)
169b544f3c8SBram Moolenaarendfunc
170b544f3c8SBram Moolenaar
171b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
172b544f3c8SBram Moolenaar" Test 3:   :if, :elseif, :while, :continue, :break			    {{{1
173b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
174b544f3c8SBram Moolenaar
175b544f3c8SBram Moolenaarfunction Test_if_while()
176b544f3c8SBram Moolenaar    XpathINIT
177b544f3c8SBram Moolenaar    if 1
178b544f3c8SBram Moolenaar	Xpath 'a'
179b544f3c8SBram Moolenaar	let loops = 3
180b544f3c8SBram Moolenaar	while loops > -1	    " main loop: loops == 3, 2, 1 (which breaks)
181b544f3c8SBram Moolenaar	    if loops <= 0
182b544f3c8SBram Moolenaar		let break_err = 1
183b544f3c8SBram Moolenaar		let loops = -1
184b544f3c8SBram Moolenaar	    else
185b544f3c8SBram Moolenaar		Xpath 'b' . loops
186b544f3c8SBram Moolenaar	    endif
187b544f3c8SBram Moolenaar	    if (loops == 2)
188b544f3c8SBram Moolenaar		while loops == 2 " dummy loop
189b544f3c8SBram Moolenaar		    Xpath 'c' . loops
190b544f3c8SBram Moolenaar		    let loops = loops - 1
191b544f3c8SBram Moolenaar		    continue    " stop dummy loop
192b544f3c8SBram Moolenaar		    Xpath 'd' . loops
193b544f3c8SBram Moolenaar		endwhile
194b544f3c8SBram Moolenaar		continue	    " continue main loop
195b544f3c8SBram Moolenaar		Xpath 'e' . loops
196b544f3c8SBram Moolenaar	    elseif (loops == 1)
197b544f3c8SBram Moolenaar		let p = 1
198b544f3c8SBram Moolenaar		while p	    " dummy loop
199b544f3c8SBram Moolenaar		    Xpath 'f' . loops
200b544f3c8SBram Moolenaar		    let p = 0
201b544f3c8SBram Moolenaar		    break	    " break dummy loop
202b544f3c8SBram Moolenaar		    Xpath 'g' . loops
203b544f3c8SBram Moolenaar		endwhile
204b544f3c8SBram Moolenaar		Xpath 'h' . loops
205b544f3c8SBram Moolenaar		unlet p
206b544f3c8SBram Moolenaar		break	    " break main loop
207b544f3c8SBram Moolenaar		Xpath 'i' . loops
208b544f3c8SBram Moolenaar	    endif
209b544f3c8SBram Moolenaar	    if (loops > 0)
210b544f3c8SBram Moolenaar		Xpath 'j' . loops
211b544f3c8SBram Moolenaar	    endif
212b544f3c8SBram Moolenaar	    while loops == 3    " dummy loop
213b544f3c8SBram Moolenaar		let loops = loops - 1
214b544f3c8SBram Moolenaar	    endwhile	    " end dummy loop
215b544f3c8SBram Moolenaar	endwhile		    " end main loop
216b544f3c8SBram Moolenaar	Xpath 'k'
217b544f3c8SBram Moolenaar    else
218b544f3c8SBram Moolenaar	Xpath 'l'
219b544f3c8SBram Moolenaar    endif
220b544f3c8SBram Moolenaar    Xpath 'm'
221b544f3c8SBram Moolenaar    if exists("break_err")
222b544f3c8SBram Moolenaar	Xpath 'm'
223b544f3c8SBram Moolenaar	unlet break_err
224b544f3c8SBram Moolenaar    endif
225b544f3c8SBram Moolenaar
226b544f3c8SBram Moolenaar    unlet loops
227b544f3c8SBram Moolenaar
228b544f3c8SBram Moolenaar    call assert_equal('ab3j3b2c2b1f1h1km', g:Xpath)
229b544f3c8SBram Moolenaarendfunc
230b544f3c8SBram Moolenaar
231b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
232b544f3c8SBram Moolenaar" Test 4:   :return							    {{{1
233b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
234b544f3c8SBram Moolenaar
235b544f3c8SBram Moolenaarfunction! T4_F()
236b544f3c8SBram Moolenaar    if 1
237b544f3c8SBram Moolenaar	Xpath 'a'
238b544f3c8SBram Moolenaar	let loops = 3
239b544f3c8SBram Moolenaar	while loops > 0				"    3:  2:     1:
240b544f3c8SBram Moolenaar	    Xpath 'b' . loops
241b544f3c8SBram Moolenaar	    if (loops == 2)
242b544f3c8SBram Moolenaar		Xpath 'c' . loops
243b544f3c8SBram Moolenaar		return
244b544f3c8SBram Moolenaar		Xpath 'd' . loops
245b544f3c8SBram Moolenaar	    endif
246b544f3c8SBram Moolenaar	    Xpath 'e' . loops
247b544f3c8SBram Moolenaar	    let loops = loops - 1
248b544f3c8SBram Moolenaar	endwhile
249b544f3c8SBram Moolenaar	Xpath 'f'
250b544f3c8SBram Moolenaar    else
251b544f3c8SBram Moolenaar	Xpath 'g'
252b544f3c8SBram Moolenaar    endif
253b544f3c8SBram Moolenaarendfunction
254b544f3c8SBram Moolenaar
255b544f3c8SBram Moolenaarfunction Test_return()
256b544f3c8SBram Moolenaar    XpathINIT
257b544f3c8SBram Moolenaar    call T4_F()
258b544f3c8SBram Moolenaar    Xpath '4'
259b544f3c8SBram Moolenaar
260b544f3c8SBram Moolenaar    call assert_equal('ab3e3b2c24', g:Xpath)
261b544f3c8SBram Moolenaarendfunction
262b544f3c8SBram Moolenaar
263b544f3c8SBram Moolenaar
264b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
265b544f3c8SBram Moolenaar" Test 5:   :finish							    {{{1
266b544f3c8SBram Moolenaar"
267b544f3c8SBram Moolenaar"	    This test executes the body of the function T4_F from the previous
268b544f3c8SBram Moolenaar"	    test as a script file (:return replaced by :finish).
269b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
270b544f3c8SBram Moolenaar
271b544f3c8SBram Moolenaarfunction Test_finish()
272b544f3c8SBram Moolenaar    XpathINIT
273b544f3c8SBram Moolenaar    ExecAsScript T4_F
274b544f3c8SBram Moolenaar    Xpath '5'
275b544f3c8SBram Moolenaar    call DeleteTheScript()
276b544f3c8SBram Moolenaar
277b544f3c8SBram Moolenaar    call assert_equal('ab3e3b2c25', g:Xpath)
278b544f3c8SBram Moolenaarendfunction
279b544f3c8SBram Moolenaar
280b544f3c8SBram Moolenaar
281b544f3c8SBram Moolenaar
282b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
283b544f3c8SBram Moolenaar" Test 6:   Defining functions in :while loops				    {{{1
284b544f3c8SBram Moolenaar"
285b544f3c8SBram Moolenaar"	     Functions can be defined inside other functions.  An inner function
286b544f3c8SBram Moolenaar"	     gets defined when the outer function is executed.  Functions may
287b544f3c8SBram Moolenaar"	     also be defined inside while loops.  Expressions in braces for
288b544f3c8SBram Moolenaar"	     defining the function name are allowed.
289b544f3c8SBram Moolenaar"
290b544f3c8SBram Moolenaar"	     The functions are defined when sourcing the script, only the
291b544f3c8SBram Moolenaar"	     resulting path is checked in the test function.
292b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
293b544f3c8SBram Moolenaar
294b544f3c8SBram MoolenaarXpathINIT
295b544f3c8SBram Moolenaar
296b544f3c8SBram Moolenaar" The command CALL collects the argument of all its invocations in "calls"
297b544f3c8SBram Moolenaar" when used from a function (that is, when the global variable "calls" needs
298b544f3c8SBram Moolenaar" the "g:" prefix).  This is to check that the function code is skipped when
299b544f3c8SBram Moolenaar" the function is defined.  For inner functions, do so only if the outer
300b544f3c8SBram Moolenaar" function is not being executed.
301b544f3c8SBram Moolenaar"
302b544f3c8SBram Moolenaarlet calls = ""
303b544f3c8SBram Moolenaarcom! -nargs=1 CALL
304b544f3c8SBram Moolenaar	    \ if !exists("calls") && !exists("outer") |
305b544f3c8SBram Moolenaar	    \ let g:calls = g:calls . <args> |
306b544f3c8SBram Moolenaar	    \ endif
307b544f3c8SBram Moolenaar
308b544f3c8SBram Moolenaarlet i = 0
309b544f3c8SBram Moolenaarwhile i < 3
310b544f3c8SBram Moolenaar    let i = i + 1
311b544f3c8SBram Moolenaar    if i == 1
312b544f3c8SBram Moolenaar	Xpath 'a'
313b544f3c8SBram Moolenaar	function! F1(arg)
314b544f3c8SBram Moolenaar	    CALL a:arg
315b544f3c8SBram Moolenaar	    let outer = 1
316b544f3c8SBram Moolenaar
317b544f3c8SBram Moolenaar	    let j = 0
318b544f3c8SBram Moolenaar	    while j < 1
319b544f3c8SBram Moolenaar		Xpath 'b'
320b544f3c8SBram Moolenaar		let j = j + 1
321b544f3c8SBram Moolenaar		function! G1(arg)
322b544f3c8SBram Moolenaar		    CALL a:arg
323b544f3c8SBram Moolenaar		endfunction
324b544f3c8SBram Moolenaar		Xpath 'c'
325b544f3c8SBram Moolenaar	    endwhile
326b544f3c8SBram Moolenaar	endfunction
327b544f3c8SBram Moolenaar	Xpath 'd'
328b544f3c8SBram Moolenaar
329b544f3c8SBram Moolenaar	continue
330b544f3c8SBram Moolenaar    endif
331b544f3c8SBram Moolenaar
332b544f3c8SBram Moolenaar    Xpath 'e' . i
333b544f3c8SBram Moolenaar    function! F{i}(i, arg)
334b544f3c8SBram Moolenaar	CALL a:arg
335b544f3c8SBram Moolenaar	let outer = 1
336b544f3c8SBram Moolenaar
337b544f3c8SBram Moolenaar	if a:i == 3
338b544f3c8SBram Moolenaar	    Xpath 'f'
339b544f3c8SBram Moolenaar	endif
340b544f3c8SBram Moolenaar	let k = 0
341b544f3c8SBram Moolenaar	while k < 3
342b544f3c8SBram Moolenaar	    Xpath 'g' . k
343b544f3c8SBram Moolenaar	    let k = k + 1
344b544f3c8SBram Moolenaar	    function! G{a:i}{k}(arg)
345b544f3c8SBram Moolenaar		CALL a:arg
346b544f3c8SBram Moolenaar	    endfunction
347b544f3c8SBram Moolenaar	    Xpath 'h' . k
348b544f3c8SBram Moolenaar	endwhile
349b544f3c8SBram Moolenaar    endfunction
350b544f3c8SBram Moolenaar    Xpath 'i'
351b544f3c8SBram Moolenaar
352b544f3c8SBram Moolenaarendwhile
353b544f3c8SBram Moolenaar
354b544f3c8SBram Moolenaarif exists("*G1")
355b544f3c8SBram Moolenaar    Xpath 'j'
356b544f3c8SBram Moolenaarendif
357b544f3c8SBram Moolenaarif exists("*F1")
358b544f3c8SBram Moolenaar    call F1("F1")
359b544f3c8SBram Moolenaar    if exists("*G1")
360b544f3c8SBram Moolenaar       call G1("G1")
361b544f3c8SBram Moolenaar    endif
362b544f3c8SBram Moolenaarendif
363b544f3c8SBram Moolenaar
364b544f3c8SBram Moolenaarif exists("G21") || exists("G22") || exists("G23")
365b544f3c8SBram Moolenaar    Xpath 'k'
366b544f3c8SBram Moolenaarendif
367b544f3c8SBram Moolenaarif exists("*F2")
368b544f3c8SBram Moolenaar    call F2(2, "F2")
369b544f3c8SBram Moolenaar    if exists("*G21")
370b544f3c8SBram Moolenaar       call G21("G21")
371b544f3c8SBram Moolenaar    endif
372b544f3c8SBram Moolenaar    if exists("*G22")
373b544f3c8SBram Moolenaar       call G22("G22")
374b544f3c8SBram Moolenaar    endif
375b544f3c8SBram Moolenaar    if exists("*G23")
376b544f3c8SBram Moolenaar       call G23("G23")
377b544f3c8SBram Moolenaar    endif
378b544f3c8SBram Moolenaarendif
379b544f3c8SBram Moolenaar
380b544f3c8SBram Moolenaarif exists("G31") || exists("G32") || exists("G33")
381b544f3c8SBram Moolenaar    Xpath 'l'
382b544f3c8SBram Moolenaarendif
383b544f3c8SBram Moolenaarif exists("*F3")
384b544f3c8SBram Moolenaar    call F3(3, "F3")
385b544f3c8SBram Moolenaar    if exists("*G31")
386b544f3c8SBram Moolenaar       call G31("G31")
387b544f3c8SBram Moolenaar    endif
388b544f3c8SBram Moolenaar    if exists("*G32")
389b544f3c8SBram Moolenaar       call G32("G32")
390b544f3c8SBram Moolenaar    endif
391b544f3c8SBram Moolenaar    if exists("*G33")
392b544f3c8SBram Moolenaar       call G33("G33")
393b544f3c8SBram Moolenaar    endif
394b544f3c8SBram Moolenaarendif
395b544f3c8SBram Moolenaar
396b544f3c8SBram MoolenaarXpath 'm'
397b544f3c8SBram Moolenaar
398b544f3c8SBram Moolenaarlet g:test6_result = g:Xpath
399b544f3c8SBram Moolenaarlet g:test6_calls = calls
400b544f3c8SBram Moolenaar
401b544f3c8SBram Moolenaarunlet calls
402b544f3c8SBram Moolenaardelfunction F1
403b544f3c8SBram Moolenaardelfunction G1
404b544f3c8SBram Moolenaardelfunction F2
405b544f3c8SBram Moolenaardelfunction G21
406b544f3c8SBram Moolenaardelfunction G22
407b544f3c8SBram Moolenaardelfunction G23
408b544f3c8SBram Moolenaardelfunction G31
409b544f3c8SBram Moolenaardelfunction G32
410b544f3c8SBram Moolenaardelfunction G33
411b544f3c8SBram Moolenaar
412b544f3c8SBram Moolenaarfunction Test_defining_functions()
413b544f3c8SBram Moolenaar    call assert_equal('ade2ie3ibcg0h1g1h2g2h3fg0h1g1h2g2h3m', g:test6_result)
414b544f3c8SBram Moolenaar    call assert_equal('F1G1F2G21G22G23F3G31G32G33', g:test6_calls)
415b544f3c8SBram Moolenaarendfunc
416b544f3c8SBram Moolenaar
417b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
418b544f3c8SBram Moolenaar" Test 7:   Continuing on errors outside functions			    {{{1
419b544f3c8SBram Moolenaar"
420b544f3c8SBram Moolenaar"	    On an error outside a function, the script processing continues
421b544f3c8SBram Moolenaar"	    at the line following the outermost :endif or :endwhile.  When not
422b544f3c8SBram Moolenaar"	    inside an :if or :while, the script processing continues at the next
423b544f3c8SBram Moolenaar"	    line.
424b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
425b544f3c8SBram Moolenaar
426b544f3c8SBram MoolenaarXpathINIT
427b544f3c8SBram Moolenaar
428b544f3c8SBram Moolenaarif 1
429b544f3c8SBram Moolenaar    Xpath 'a'
430b544f3c8SBram Moolenaar    while 1
431b544f3c8SBram Moolenaar	Xpath 'b'
432b544f3c8SBram Moolenaar	asdf
433b544f3c8SBram Moolenaar	Xpath 'c'
434b544f3c8SBram Moolenaar	break
435b544f3c8SBram Moolenaar    endwhile | Xpath 'd'
436b544f3c8SBram Moolenaar    Xpath 'e'
437b544f3c8SBram Moolenaarendif | Xpath 'f'
438b544f3c8SBram MoolenaarXpath 'g'
439b544f3c8SBram Moolenaar
440b544f3c8SBram Moolenaarwhile 1
441b544f3c8SBram Moolenaar    Xpath 'h'
442b544f3c8SBram Moolenaar    if 1
443b544f3c8SBram Moolenaar	Xpath 'i'
444b544f3c8SBram Moolenaar	asdf
445b544f3c8SBram Moolenaar	Xpath 'j'
446b544f3c8SBram Moolenaar    endif | Xpath 'k'
447b544f3c8SBram Moolenaar    Xpath 'l'
448b544f3c8SBram Moolenaar    break
449b544f3c8SBram Moolenaarendwhile | Xpath 'm'
450b544f3c8SBram MoolenaarXpath 'n'
451b544f3c8SBram Moolenaar
452b544f3c8SBram Moolenaarasdf
453b544f3c8SBram MoolenaarXpath 'o'
454b544f3c8SBram Moolenaar
455b544f3c8SBram Moolenaarasdf | Xpath 'p'
456b544f3c8SBram MoolenaarXpath 'q'
457b544f3c8SBram Moolenaar
458b544f3c8SBram Moolenaarlet g:test7_result = g:Xpath
459b544f3c8SBram Moolenaar
460b544f3c8SBram Moolenaarfunc Test_error_in_script()
461b544f3c8SBram Moolenaar    call assert_equal('abghinoq', g:test7_result)
462b544f3c8SBram Moolenaarendfunc
463b544f3c8SBram Moolenaar
464b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
465b544f3c8SBram Moolenaar" Test 8:   Aborting and continuing on errors inside functions		    {{{1
466b544f3c8SBram Moolenaar"
467b544f3c8SBram Moolenaar"	    On an error inside a function without the "abort" attribute, the
468b544f3c8SBram Moolenaar"	    script processing continues at the next line (unless the error was
469b544f3c8SBram Moolenaar"	    in a :return command).  On an error inside a function with the
470b544f3c8SBram Moolenaar"	    "abort" attribute, the function is aborted and the script processing
471b544f3c8SBram Moolenaar"	    continues after the function call; the value -1 is returned then.
472b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
473b544f3c8SBram Moolenaar
474b544f3c8SBram MoolenaarXpathINIT
475b544f3c8SBram Moolenaar
476b544f3c8SBram Moolenaarfunction! T8_F()
477b544f3c8SBram Moolenaar    if 1
478b544f3c8SBram Moolenaar	Xpath 'a'
479b544f3c8SBram Moolenaar	while 1
480b544f3c8SBram Moolenaar	    Xpath 'b'
481b544f3c8SBram Moolenaar	    asdf
482b544f3c8SBram Moolenaar	    Xpath 'c'
483b544f3c8SBram Moolenaar	    asdf | Xpath 'd'
484b544f3c8SBram Moolenaar	    Xpath 'e'
485b544f3c8SBram Moolenaar	    break
486b544f3c8SBram Moolenaar	endwhile
487b544f3c8SBram Moolenaar	Xpath 'f'
488b544f3c8SBram Moolenaar    endif | Xpath 'g'
489b544f3c8SBram Moolenaar    Xpath 'h'
490b544f3c8SBram Moolenaar
491b544f3c8SBram Moolenaar    while 1
492b544f3c8SBram Moolenaar	Xpath 'i'
493b544f3c8SBram Moolenaar	if 1
494b544f3c8SBram Moolenaar	    Xpath 'j'
495b544f3c8SBram Moolenaar	    asdf
496b544f3c8SBram Moolenaar	    Xpath 'k'
497b544f3c8SBram Moolenaar	    asdf | Xpath 'l'
498b544f3c8SBram Moolenaar	    Xpath 'm'
499b544f3c8SBram Moolenaar	endif
500b544f3c8SBram Moolenaar	Xpath 'n'
501b544f3c8SBram Moolenaar	break
502b544f3c8SBram Moolenaar    endwhile | Xpath 'o'
503b544f3c8SBram Moolenaar    Xpath 'p'
504b544f3c8SBram Moolenaar
505b544f3c8SBram Moolenaar    return novar		" returns (default return value 0)
506b544f3c8SBram Moolenaar    Xpath 'q'
507b544f3c8SBram Moolenaar    return 1			" not reached
508b544f3c8SBram Moolenaarendfunction
509b544f3c8SBram Moolenaar
510b544f3c8SBram Moolenaarfunction! T8_G() abort
511b544f3c8SBram Moolenaar    if 1
512b544f3c8SBram Moolenaar	Xpath 'r'
513b544f3c8SBram Moolenaar	while 1
514b544f3c8SBram Moolenaar	    Xpath 's'
515b544f3c8SBram Moolenaar	    asdf		" returns -1
516b544f3c8SBram Moolenaar	    Xpath 't'
517b544f3c8SBram Moolenaar	    break
518b544f3c8SBram Moolenaar	endwhile
519b544f3c8SBram Moolenaar	Xpath 'v'
520b544f3c8SBram Moolenaar    endif | Xpath 'w'
521b544f3c8SBram Moolenaar    Xpath 'x'
522b544f3c8SBram Moolenaar
523b544f3c8SBram Moolenaar    return -4			" not reached
524b544f3c8SBram Moolenaarendfunction
525b544f3c8SBram Moolenaar
526b544f3c8SBram Moolenaarfunction! T8_H() abort
527b544f3c8SBram Moolenaar    while 1
528b544f3c8SBram Moolenaar	Xpath 'A'
529b544f3c8SBram Moolenaar	if 1
530b544f3c8SBram Moolenaar	    Xpath 'B'
531b544f3c8SBram Moolenaar	    asdf		" returns -1
532b544f3c8SBram Moolenaar	    Xpath 'C'
533b544f3c8SBram Moolenaar	endif
534b544f3c8SBram Moolenaar	Xpath 'D'
535b544f3c8SBram Moolenaar	break
536b544f3c8SBram Moolenaar    endwhile | Xpath 'E'
537b544f3c8SBram Moolenaar    Xpath 'F'
538b544f3c8SBram Moolenaar
539b544f3c8SBram Moolenaar    return -4			" not reached
540b544f3c8SBram Moolenaarendfunction
541b544f3c8SBram Moolenaar
542b544f3c8SBram Moolenaar" Aborted functions (T8_G and T8_H) return -1.
543b544f3c8SBram Moolenaarlet g:test8_sum = (T8_F() + 1) - 4 * T8_G() - 8 * T8_H()
544b544f3c8SBram MoolenaarXpath 'X'
545b544f3c8SBram Moolenaarlet g:test8_result = g:Xpath
546b544f3c8SBram Moolenaar
547b544f3c8SBram Moolenaarfunc Test_error_in_function()
548b544f3c8SBram Moolenaar    call assert_equal(13, g:test8_sum)
549b544f3c8SBram Moolenaar    call assert_equal('abcefghijkmnoprsABX', g:test8_result)
550b544f3c8SBram Moolenaar
551b544f3c8SBram Moolenaar    delfunction T8_F
552b544f3c8SBram Moolenaar    delfunction T8_G
553b544f3c8SBram Moolenaar    delfunction T8_H
554b544f3c8SBram Moolenaarendfunc
555b544f3c8SBram Moolenaar
556b544f3c8SBram Moolenaar
557b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
558b544f3c8SBram Moolenaar" Test 9:   Continuing after aborted functions				    {{{1
559b544f3c8SBram Moolenaar"
560b544f3c8SBram Moolenaar"	    When a function with the "abort" attribute is aborted due to an
561b544f3c8SBram Moolenaar"	    error, the next function back in the call hierarchy without an
562b544f3c8SBram Moolenaar"	    "abort" attribute continues; the value -1 is returned then.
563b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
564b544f3c8SBram Moolenaar
565b544f3c8SBram MoolenaarXpathINIT
566b544f3c8SBram Moolenaar
567b544f3c8SBram Moolenaarfunction! F() abort
568b544f3c8SBram Moolenaar    Xpath 'a'
569b544f3c8SBram Moolenaar    let result = G()	" not aborted
570b544f3c8SBram Moolenaar    Xpath 'b'
571b544f3c8SBram Moolenaar    if result != 2
572b544f3c8SBram Moolenaar	Xpath 'c'
573b544f3c8SBram Moolenaar    endif
574b544f3c8SBram Moolenaar    return 1
575b544f3c8SBram Moolenaarendfunction
576b544f3c8SBram Moolenaar
577b544f3c8SBram Moolenaarfunction! G()		" no abort attribute
578b544f3c8SBram Moolenaar    Xpath 'd'
579b544f3c8SBram Moolenaar    if H() != -1	" aborted
580b544f3c8SBram Moolenaar	Xpath 'e'
581b544f3c8SBram Moolenaar    endif
582b544f3c8SBram Moolenaar    Xpath 'f'
583b544f3c8SBram Moolenaar    return 2
584b544f3c8SBram Moolenaarendfunction
585b544f3c8SBram Moolenaar
586b544f3c8SBram Moolenaarfunction! H() abort
587b544f3c8SBram Moolenaar    Xpath 'g'
588b544f3c8SBram Moolenaar    call I()		" aborted
589b544f3c8SBram Moolenaar    Xpath 'h'
590b544f3c8SBram Moolenaar    return 4
591b544f3c8SBram Moolenaarendfunction
592b544f3c8SBram Moolenaar
593b544f3c8SBram Moolenaarfunction! I() abort
594b544f3c8SBram Moolenaar    Xpath 'i'
595b544f3c8SBram Moolenaar    asdf		" error
596b544f3c8SBram Moolenaar    Xpath 'j'
597b544f3c8SBram Moolenaar    return 8
598b544f3c8SBram Moolenaarendfunction
599b544f3c8SBram Moolenaar
600b544f3c8SBram Moolenaarif F() != 1
601b544f3c8SBram Moolenaar    Xpath 'k'
602b544f3c8SBram Moolenaarendif
603b544f3c8SBram Moolenaar
604b544f3c8SBram Moolenaarlet g:test9_result = g:Xpath
605b544f3c8SBram Moolenaar
606b544f3c8SBram Moolenaardelfunction F
607b544f3c8SBram Moolenaardelfunction G
608b544f3c8SBram Moolenaardelfunction H
609b544f3c8SBram Moolenaardelfunction I
610b544f3c8SBram Moolenaar
611b544f3c8SBram Moolenaarfunc Test_func_abort()
612b544f3c8SBram Moolenaar    call assert_equal('adgifb', g:test9_result)
613b544f3c8SBram Moolenaarendfunc
614b544f3c8SBram Moolenaar
615b544f3c8SBram Moolenaar
616b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
617b544f3c8SBram Moolenaar" Test 10:  :if, :elseif, :while argument parsing			    {{{1
618b544f3c8SBram Moolenaar"
619b544f3c8SBram Moolenaar"	    A '"' or '|' in an argument expression must not be mixed up with
620b544f3c8SBram Moolenaar"	    a comment or a next command after a bar.  Parsing errors should
621b544f3c8SBram Moolenaar"	    be recognized.
622b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
623b544f3c8SBram Moolenaar
624b544f3c8SBram MoolenaarXpathINIT
625b544f3c8SBram Moolenaar
626b544f3c8SBram Moolenaarfunction! MSG(enr, emsg)
627b544f3c8SBram Moolenaar    let english = v:lang == "C" || v:lang =~ '^[Ee]n'
628b544f3c8SBram Moolenaar    if a:enr == ""
629b544f3c8SBram Moolenaar	Xout "TODO: Add message number for:" a:emsg
630b544f3c8SBram Moolenaar	let v:errmsg = ":" . v:errmsg
631b544f3c8SBram Moolenaar    endif
632b544f3c8SBram Moolenaar    let match = 1
633b544f3c8SBram Moolenaar    if v:errmsg !~ '^'.a:enr.':' || (english && v:errmsg !~ a:emsg)
634b544f3c8SBram Moolenaar	let match = 0
635b544f3c8SBram Moolenaar	if v:errmsg == ""
636b544f3c8SBram Moolenaar	    Xout "Message missing."
637b544f3c8SBram Moolenaar	else
638b544f3c8SBram Moolenaar	    let v:errmsg = escape(v:errmsg, '"')
639b544f3c8SBram Moolenaar	    Xout "Unexpected message:" v:errmsg
640b544f3c8SBram Moolenaar	endif
641b544f3c8SBram Moolenaar    endif
642b544f3c8SBram Moolenaar    return match
6431e115360SBram Moolenaarendfunc
644b544f3c8SBram Moolenaar
645b544f3c8SBram Moolenaarif 1 || strlen("\"") | Xpath 'a'
646b544f3c8SBram Moolenaar    Xpath 'b'
647b544f3c8SBram Moolenaarendif
648b544f3c8SBram MoolenaarXpath 'c'
649b544f3c8SBram Moolenaar
650b544f3c8SBram Moolenaarif 0
651b544f3c8SBram Moolenaarelseif 1 || strlen("\"") | Xpath 'd'
652b544f3c8SBram Moolenaar    Xpath 'e'
653b544f3c8SBram Moolenaarendif
654b544f3c8SBram MoolenaarXpath 'f'
655b544f3c8SBram Moolenaar
656b544f3c8SBram Moolenaarwhile 1 || strlen("\"") | Xpath 'g'
657b544f3c8SBram Moolenaar    Xpath 'h'
658b544f3c8SBram Moolenaar    break
659b544f3c8SBram Moolenaarendwhile
660b544f3c8SBram MoolenaarXpath 'i'
661b544f3c8SBram Moolenaar
662b544f3c8SBram Moolenaarlet v:errmsg = ""
663b544f3c8SBram Moolenaarif 1 ||| strlen("\"") | Xpath 'j'
664b544f3c8SBram Moolenaar    Xpath 'k'
665b544f3c8SBram Moolenaarendif
666b544f3c8SBram MoolenaarXpath 'l'
667b544f3c8SBram Moolenaarif !MSG('E15', "Invalid expression")
668b544f3c8SBram Moolenaar    Xpath 'm'
669b544f3c8SBram Moolenaarendif
670b544f3c8SBram Moolenaar
671b544f3c8SBram Moolenaarlet v:errmsg = ""
672b544f3c8SBram Moolenaarif 0
673b544f3c8SBram Moolenaarelseif 1 ||| strlen("\"") | Xpath 'n'
674b544f3c8SBram Moolenaar    Xpath 'o'
675b544f3c8SBram Moolenaarendif
676b544f3c8SBram MoolenaarXpath 'p'
677b544f3c8SBram Moolenaarif !MSG('E15', "Invalid expression")
678b544f3c8SBram Moolenaar    Xpath 'q'
679b544f3c8SBram Moolenaarendif
680b544f3c8SBram Moolenaar
681b544f3c8SBram Moolenaarlet v:errmsg = ""
682b544f3c8SBram Moolenaarwhile 1 ||| strlen("\"") | Xpath 'r'
683b544f3c8SBram Moolenaar    Xpath 's'
684b544f3c8SBram Moolenaar    break
685b544f3c8SBram Moolenaarendwhile
686b544f3c8SBram MoolenaarXpath 't'
687b544f3c8SBram Moolenaarif !MSG('E15', "Invalid expression")
688b544f3c8SBram Moolenaar    Xpath 'u'
689b544f3c8SBram Moolenaarendif
690b544f3c8SBram Moolenaar
691b544f3c8SBram Moolenaarlet g:test10_result = g:Xpath
692b544f3c8SBram Moolenaardelfunction MSG
693b544f3c8SBram Moolenaar
694b544f3c8SBram Moolenaarfunc Test_expr_parsing()
695b544f3c8SBram Moolenaar    call assert_equal('abcdefghilpt', g:test10_result)
696b544f3c8SBram Moolenaarendfunc
697b544f3c8SBram Moolenaar
698b544f3c8SBram Moolenaar
699b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
700b544f3c8SBram Moolenaar" Test 11:  :if, :elseif, :while argument evaluation after abort	    {{{1
701b544f3c8SBram Moolenaar"
702b544f3c8SBram Moolenaar"	    When code is skipped over due to an error, the boolean argument to
703b544f3c8SBram Moolenaar"	    an :if, :elseif, or :while must not be evaluated.
704b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
705b544f3c8SBram Moolenaar
706b544f3c8SBram MoolenaarXpathINIT
707b544f3c8SBram Moolenaar
708b544f3c8SBram Moolenaarlet calls = 0
709b544f3c8SBram Moolenaar
710b544f3c8SBram Moolenaarfunction! P(num)
711b544f3c8SBram Moolenaar    let g:calls = g:calls + a:num   " side effect on call
712b544f3c8SBram Moolenaar    return 0
713b544f3c8SBram Moolenaarendfunction
714b544f3c8SBram Moolenaar
715b544f3c8SBram Moolenaarif 1
716b544f3c8SBram Moolenaar    Xpath 'a'
717b544f3c8SBram Moolenaar    asdf		" error
718b544f3c8SBram Moolenaar    Xpath 'b'
719b544f3c8SBram Moolenaar    if P(1)		" should not be called
720b544f3c8SBram Moolenaar	Xpath 'c'
721b544f3c8SBram Moolenaar    elseif !P(2)	" should not be called
722b544f3c8SBram Moolenaar	Xpath 'd'
723b544f3c8SBram Moolenaar    else
724b544f3c8SBram Moolenaar	Xpath 'e'
725b544f3c8SBram Moolenaar    endif
726b544f3c8SBram Moolenaar    Xpath 'f'
727b544f3c8SBram Moolenaar    while P(4)		" should not be called
728b544f3c8SBram Moolenaar	Xpath 'g'
729b544f3c8SBram Moolenaar    endwhile
730b544f3c8SBram Moolenaar    Xpath 'h'
731b544f3c8SBram Moolenaarendif
732b544f3c8SBram MoolenaarXpath 'x'
733b544f3c8SBram Moolenaar
734b544f3c8SBram Moolenaarlet g:test11_calls = calls
735b544f3c8SBram Moolenaarlet g:test11_result = g:Xpath
736b544f3c8SBram Moolenaar
737b544f3c8SBram Moolenaarunlet calls
738b544f3c8SBram Moolenaardelfunction P
739b544f3c8SBram Moolenaar
740b544f3c8SBram Moolenaarfunc Test_arg_abort()
741b544f3c8SBram Moolenaar    call assert_equal(0, g:test11_calls)
742b544f3c8SBram Moolenaar    call assert_equal('ax', g:test11_result)
743b544f3c8SBram Moolenaarendfunc
744b544f3c8SBram Moolenaar
745b544f3c8SBram Moolenaar
746b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
747b544f3c8SBram Moolenaar" Test 12:  Expressions in braces in skipped code			    {{{1
748b544f3c8SBram Moolenaar"
749b544f3c8SBram Moolenaar"	    In code skipped over due to an error or inactive conditional,
750b544f3c8SBram Moolenaar"	    an expression in braces as part of a variable or function name
751b544f3c8SBram Moolenaar"	    should not be evaluated.
752b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
753b544f3c8SBram Moolenaar
754b544f3c8SBram MoolenaarXpathINIT
755b544f3c8SBram Moolenaar
756b544f3c8SBram Moolenaarfunction! NULL()
757b544f3c8SBram Moolenaar    Xpath 'a'
758b544f3c8SBram Moolenaar    return 0
759b544f3c8SBram Moolenaarendfunction
760b544f3c8SBram Moolenaar
761b544f3c8SBram Moolenaarfunction! ZERO()
762b544f3c8SBram Moolenaar    Xpath 'b'
763b544f3c8SBram Moolenaar    return 0
764b544f3c8SBram Moolenaarendfunction
765b544f3c8SBram Moolenaar
766b544f3c8SBram Moolenaarfunction! F0()
767b544f3c8SBram Moolenaar    Xpath 'c'
768b544f3c8SBram Moolenaarendfunction
769b544f3c8SBram Moolenaar
770b544f3c8SBram Moolenaarfunction! F1(arg)
771b544f3c8SBram Moolenaar    Xpath 'e'
772b544f3c8SBram Moolenaarendfunction
773b544f3c8SBram Moolenaar
774b544f3c8SBram Moolenaarlet V0 = 1
775b544f3c8SBram Moolenaar
776b544f3c8SBram MoolenaarXpath 'f'
777b544f3c8SBram Moolenaarecho 0 ? F{NULL() + V{ZERO()}}() : 1
778b544f3c8SBram Moolenaar
779b544f3c8SBram MoolenaarXpath 'g'
780b544f3c8SBram Moolenaarif 0
781b544f3c8SBram Moolenaar    Xpath 'h'
782b544f3c8SBram Moolenaar    call F{NULL() + V{ZERO()}}()
783b544f3c8SBram Moolenaarendif
784b544f3c8SBram Moolenaar
785b544f3c8SBram MoolenaarXpath 'i'
786b544f3c8SBram Moolenaarif 1
787b544f3c8SBram Moolenaar    asdf		" error
788b544f3c8SBram Moolenaar    Xpath 'j'
789b544f3c8SBram Moolenaar    call F1(F{NULL() + V{ZERO()}}())
790b544f3c8SBram Moolenaarendif
791b544f3c8SBram Moolenaar
792b544f3c8SBram MoolenaarXpath 'k'
793b544f3c8SBram Moolenaarif 1
794b544f3c8SBram Moolenaar    asdf		" error
795b544f3c8SBram Moolenaar    Xpath 'l'
796b544f3c8SBram Moolenaar    call F{NULL() + V{ZERO()}}()
797b544f3c8SBram Moolenaarendif
798b544f3c8SBram Moolenaar
799b544f3c8SBram Moolenaarlet g:test12_result = g:Xpath
800b544f3c8SBram Moolenaar
801b544f3c8SBram Moolenaarfunc Test_braces_skipped()
802b544f3c8SBram Moolenaar    call assert_equal('fgik', g:test12_result)
803b544f3c8SBram Moolenaarendfunc
804b544f3c8SBram Moolenaar
805b544f3c8SBram Moolenaar
806b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
807b544f3c8SBram Moolenaar" Test 13:  Failure in argument evaluation for :while			    {{{1
808b544f3c8SBram Moolenaar"
809b544f3c8SBram Moolenaar"	    A failure in the expression evaluation for the condition of a :while
810b544f3c8SBram Moolenaar"	    causes the whole :while loop until the matching :endwhile being
811b544f3c8SBram Moolenaar"	    ignored.  Continuation is at the next following line.
812b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
813b544f3c8SBram Moolenaar
814b544f3c8SBram MoolenaarXpathINIT
815b544f3c8SBram Moolenaar
816b544f3c8SBram MoolenaarXpath 'a'
817b544f3c8SBram Moolenaarwhile asdf
818b544f3c8SBram Moolenaar    Xpath 'b'
819b544f3c8SBram Moolenaar    while 1
820b544f3c8SBram Moolenaar	Xpath 'c'
821b544f3c8SBram Moolenaar	break
822b544f3c8SBram Moolenaar    endwhile
823b544f3c8SBram Moolenaar    Xpath 'd'
824b544f3c8SBram Moolenaar    break
825b544f3c8SBram Moolenaarendwhile
826b544f3c8SBram MoolenaarXpath 'e'
827b544f3c8SBram Moolenaar
828b544f3c8SBram Moolenaarwhile asdf | Xpath 'f' | endwhile | Xpath 'g'
829b544f3c8SBram MoolenaarXpath 'h'
830b544f3c8SBram Moolenaarlet g:test13_result = g:Xpath
831b544f3c8SBram Moolenaar
832b544f3c8SBram Moolenaarfunc Test_while_fail()
833b544f3c8SBram Moolenaar    call assert_equal('aeh', g:test13_result)
834b544f3c8SBram Moolenaarendfunc
835b544f3c8SBram Moolenaar
836b544f3c8SBram Moolenaar
837b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
838b544f3c8SBram Moolenaar" Test 14:  Failure in argument evaluation for :if			    {{{1
839b544f3c8SBram Moolenaar"
840b544f3c8SBram Moolenaar"	    A failure in the expression evaluation for the condition of an :if
841b544f3c8SBram Moolenaar"	    does not cause the corresponding :else or :endif being matched to
842b544f3c8SBram Moolenaar"	    a previous :if/:elseif.  Neither of both branches of the failed :if
843b544f3c8SBram Moolenaar"	    are executed.
844b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
845b544f3c8SBram Moolenaar
846b544f3c8SBram MoolenaarXpathINIT
847b544f3c8SBram Moolenaar
848b544f3c8SBram Moolenaarfunction! F()
849b544f3c8SBram Moolenaar    Xpath 'a'
850b544f3c8SBram Moolenaar    let x = 0
851b544f3c8SBram Moolenaar    if x		" false
852b544f3c8SBram Moolenaar	Xpath 'b'
853b544f3c8SBram Moolenaar    elseif !x		" always true
854b544f3c8SBram Moolenaar	Xpath 'c'
855b544f3c8SBram Moolenaar	let x = 1
856b544f3c8SBram Moolenaar	if g:boolvar	" possibly undefined
857b544f3c8SBram Moolenaar	    Xpath 'd'
858b544f3c8SBram Moolenaar	else
859b544f3c8SBram Moolenaar	    Xpath 'e'
860b544f3c8SBram Moolenaar	endif
861b544f3c8SBram Moolenaar	Xpath 'f'
862b544f3c8SBram Moolenaar    elseif x		" never executed
863b544f3c8SBram Moolenaar	Xpath 'g'
864b544f3c8SBram Moolenaar    endif
865b544f3c8SBram Moolenaar    Xpath 'h'
866b544f3c8SBram Moolenaarendfunction
867b544f3c8SBram Moolenaar
868b544f3c8SBram Moolenaarlet boolvar = 1
869b544f3c8SBram Moolenaarcall F()
870b544f3c8SBram MoolenaarXpath '-'
871b544f3c8SBram Moolenaar
872b544f3c8SBram Moolenaarunlet boolvar
873b544f3c8SBram Moolenaarcall F()
874b544f3c8SBram Moolenaarlet g:test14_result = g:Xpath
875b544f3c8SBram Moolenaar
876b544f3c8SBram Moolenaardelfunction F
877b544f3c8SBram Moolenaar
878b544f3c8SBram Moolenaarfunc Test_if_fail()
879b544f3c8SBram Moolenaar    call assert_equal('acdfh-acfh', g:test14_result)
880b544f3c8SBram Moolenaarendfunc
881b544f3c8SBram Moolenaar
882b544f3c8SBram Moolenaar
883b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
884b544f3c8SBram Moolenaar" Test 15:  Failure in argument evaluation for :if (bar)		    {{{1
885b544f3c8SBram Moolenaar"
886b544f3c8SBram Moolenaar"	    Like previous test, except that the failing :if ... | ... | :endif
887b544f3c8SBram Moolenaar"	    is in a single line.
888b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
889b544f3c8SBram Moolenaar
890b544f3c8SBram MoolenaarXpathINIT
891b544f3c8SBram Moolenaar
892b544f3c8SBram Moolenaarfunction! F()
893b544f3c8SBram Moolenaar    Xpath 'a'
894b544f3c8SBram Moolenaar    let x = 0
895b544f3c8SBram Moolenaar    if x		" false
896b544f3c8SBram Moolenaar	Xpath 'b'
897b544f3c8SBram Moolenaar    elseif !x		" always true
898b544f3c8SBram Moolenaar	Xpath 'c'
899b544f3c8SBram Moolenaar	let x = 1
900b544f3c8SBram Moolenaar	if g:boolvar | Xpath 'd' | else | Xpath 'e' | endif
901b544f3c8SBram Moolenaar	Xpath 'f'
902b544f3c8SBram Moolenaar    elseif x		" never executed
903b544f3c8SBram Moolenaar	Xpath 'g'
904b544f3c8SBram Moolenaar    endif
905b544f3c8SBram Moolenaar    Xpath 'h'
906b544f3c8SBram Moolenaarendfunction
907b544f3c8SBram Moolenaar
908b544f3c8SBram Moolenaarlet boolvar = 1
909b544f3c8SBram Moolenaarcall F()
910b544f3c8SBram MoolenaarXpath '-'
911b544f3c8SBram Moolenaar
912b544f3c8SBram Moolenaarunlet boolvar
913b544f3c8SBram Moolenaarcall F()
914b544f3c8SBram Moolenaarlet g:test15_result = g:Xpath
915b544f3c8SBram Moolenaar
916b544f3c8SBram Moolenaardelfunction F
917b544f3c8SBram Moolenaar
918b544f3c8SBram Moolenaarfunc Test_if_bar_fail()
919b544f3c8SBram Moolenaar    call assert_equal('acdfh-acfh', g:test15_result)
920b544f3c8SBram Moolenaarendfunc
921b544f3c8SBram Moolenaar
922b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
923b544f3c8SBram Moolenaar" Test 90:  Recognizing {} in variable name.			    {{{1
924b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
925b544f3c8SBram Moolenaar
926b544f3c8SBram Moolenaarfunc Test_curlies()
927b544f3c8SBram Moolenaar    let s:var = 66
928b544f3c8SBram Moolenaar    let ns = 's'
929b544f3c8SBram Moolenaar    call assert_equal(66, {ns}:var)
930b544f3c8SBram Moolenaar
931b544f3c8SBram Moolenaar    let g:a = {}
932b544f3c8SBram Moolenaar    let g:b = 't'
933b544f3c8SBram Moolenaar    let g:a[g:b] = 77
934b544f3c8SBram Moolenaar    call assert_equal(77, g:a['t'])
935b544f3c8SBram Moolenaarendfunc
936b544f3c8SBram Moolenaar
937b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
938b544f3c8SBram Moolenaar" Test 91:  using type().					    {{{1
939b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
940b544f3c8SBram Moolenaar
941b544f3c8SBram Moolenaarfunc Test_type()
942b544f3c8SBram Moolenaar    call assert_equal(0, type(0))
943b544f3c8SBram Moolenaar    call assert_equal(1, type(""))
944b544f3c8SBram Moolenaar    call assert_equal(2, type(function("tr")))
945b544f3c8SBram Moolenaar    call assert_equal(2, type(function("tr", [8])))
946b544f3c8SBram Moolenaar    call assert_equal(3, type([]))
947b544f3c8SBram Moolenaar    call assert_equal(4, type({}))
948b544f3c8SBram Moolenaar    call assert_equal(5, type(0.0))
949b544f3c8SBram Moolenaar    call assert_equal(6, type(v:false))
950b544f3c8SBram Moolenaar    call assert_equal(6, type(v:true))
951b544f3c8SBram Moolenaar    call assert_equal(7, type(v:none))
952b544f3c8SBram Moolenaar    call assert_equal(7, type(v:null))
953b544f3c8SBram Moolenaar    call assert_equal(8, v:t_job)
954b544f3c8SBram Moolenaar    call assert_equal(9, v:t_channel)
955b544f3c8SBram Moolenaar    call assert_equal(v:t_number, type(0))
956b544f3c8SBram Moolenaar    call assert_equal(v:t_string, type(""))
957b544f3c8SBram Moolenaar    call assert_equal(v:t_func, type(function("tr")))
958b544f3c8SBram Moolenaar    call assert_equal(v:t_func, type(function("tr", [8])))
959b544f3c8SBram Moolenaar    call assert_equal(v:t_list, type([]))
960b544f3c8SBram Moolenaar    call assert_equal(v:t_dict, type({}))
961b544f3c8SBram Moolenaar    call assert_equal(v:t_float, type(0.0))
962b544f3c8SBram Moolenaar    call assert_equal(v:t_bool, type(v:false))
963b544f3c8SBram Moolenaar    call assert_equal(v:t_bool, type(v:true))
964b544f3c8SBram Moolenaar    call assert_equal(v:t_none, type(v:none))
965b544f3c8SBram Moolenaar    call assert_equal(v:t_none, type(v:null))
966b544f3c8SBram Moolenaar
967b544f3c8SBram Moolenaar
968b544f3c8SBram Moolenaar    call assert_equal(0, 0 + v:false)
969b544f3c8SBram Moolenaar    call assert_equal(1, 0 + v:true)
970b544f3c8SBram Moolenaar    call assert_equal(0, 0 + v:none)
971b544f3c8SBram Moolenaar    call assert_equal(0, 0 + v:null)
972b544f3c8SBram Moolenaar
973b544f3c8SBram Moolenaar    call assert_equal('v:false', '' . v:false)
974b544f3c8SBram Moolenaar    call assert_equal('v:true', '' . v:true)
975b544f3c8SBram Moolenaar    call assert_equal('v:none', '' . v:none)
976b544f3c8SBram Moolenaar    call assert_equal('v:null', '' . v:null)
977b544f3c8SBram Moolenaar
978b544f3c8SBram Moolenaar    call assert_true(v:false == 0)
979b544f3c8SBram Moolenaar    call assert_false(v:false != 0)
980b544f3c8SBram Moolenaar    call assert_true(v:true == 1)
981b544f3c8SBram Moolenaar    call assert_false(v:true != 1)
982b544f3c8SBram Moolenaar    call assert_false(v:true == v:false)
983b544f3c8SBram Moolenaar    call assert_true(v:true != v:false)
984b544f3c8SBram Moolenaar
985b544f3c8SBram Moolenaar    call assert_true(v:null == 0)
986b544f3c8SBram Moolenaar    call assert_false(v:null != 0)
987b544f3c8SBram Moolenaar    call assert_true(v:none == 0)
988b544f3c8SBram Moolenaar    call assert_false(v:none != 0)
989b544f3c8SBram Moolenaar
990b544f3c8SBram Moolenaar    call assert_true(v:false is v:false)
991b544f3c8SBram Moolenaar    call assert_true(v:true is v:true)
992b544f3c8SBram Moolenaar    call assert_true(v:none is v:none)
993b544f3c8SBram Moolenaar    call assert_true(v:null is v:null)
994b544f3c8SBram Moolenaar
995b544f3c8SBram Moolenaar    call assert_false(v:false isnot v:false)
996b544f3c8SBram Moolenaar    call assert_false(v:true isnot v:true)
997b544f3c8SBram Moolenaar    call assert_false(v:none isnot v:none)
998b544f3c8SBram Moolenaar    call assert_false(v:null isnot v:null)
999b544f3c8SBram Moolenaar
1000b544f3c8SBram Moolenaar    call assert_false(v:false is 0)
1001b544f3c8SBram Moolenaar    call assert_false(v:true is 1)
1002b544f3c8SBram Moolenaar    call assert_false(v:true is v:false)
1003b544f3c8SBram Moolenaar    call assert_false(v:none is 0)
1004b544f3c8SBram Moolenaar    call assert_false(v:null is 0)
1005b544f3c8SBram Moolenaar    call assert_false(v:null is v:none)
1006b544f3c8SBram Moolenaar
1007b544f3c8SBram Moolenaar    call assert_true(v:false isnot 0)
1008b544f3c8SBram Moolenaar    call assert_true(v:true isnot 1)
1009b544f3c8SBram Moolenaar    call assert_true(v:true isnot v:false)
1010b544f3c8SBram Moolenaar    call assert_true(v:none isnot 0)
1011b544f3c8SBram Moolenaar    call assert_true(v:null isnot 0)
1012b544f3c8SBram Moolenaar    call assert_true(v:null isnot v:none)
1013b544f3c8SBram Moolenaar
1014b544f3c8SBram Moolenaar    call assert_equal(v:false, eval(string(v:false)))
1015b544f3c8SBram Moolenaar    call assert_equal(v:true, eval(string(v:true)))
1016b544f3c8SBram Moolenaar    call assert_equal(v:none, eval(string(v:none)))
1017b544f3c8SBram Moolenaar    call assert_equal(v:null, eval(string(v:null)))
1018b544f3c8SBram Moolenaar
1019b544f3c8SBram Moolenaar    call assert_equal(v:false, copy(v:false))
1020b544f3c8SBram Moolenaar    call assert_equal(v:true, copy(v:true))
1021b544f3c8SBram Moolenaar    call assert_equal(v:none, copy(v:none))
1022b544f3c8SBram Moolenaar    call assert_equal(v:null, copy(v:null))
1023b544f3c8SBram Moolenaar
1024b544f3c8SBram Moolenaar    call assert_equal([v:false], deepcopy([v:false]))
1025b544f3c8SBram Moolenaar    call assert_equal([v:true], deepcopy([v:true]))
1026b544f3c8SBram Moolenaar    call assert_equal([v:none], deepcopy([v:none]))
1027b544f3c8SBram Moolenaar    call assert_equal([v:null], deepcopy([v:null]))
1028b544f3c8SBram Moolenaar
1029b544f3c8SBram Moolenaar    call assert_true(empty(v:false))
1030b544f3c8SBram Moolenaar    call assert_false(empty(v:true))
1031b544f3c8SBram Moolenaar    call assert_true(empty(v:null))
1032b544f3c8SBram Moolenaar    call assert_true(empty(v:none))
1033b544f3c8SBram Moolenaar
1034b544f3c8SBram Moolenaar    func ChangeYourMind()
1035b544f3c8SBram Moolenaar	try
1036b544f3c8SBram Moolenaar	    return v:true
1037b544f3c8SBram Moolenaar	finally
1038b544f3c8SBram Moolenaar	    return 'something else'
1039b544f3c8SBram Moolenaar	endtry
1040b544f3c8SBram Moolenaar    endfunc
1041b544f3c8SBram Moolenaar
1042b544f3c8SBram Moolenaar    call ChangeYourMind()
1043b544f3c8SBram Moolenaarendfunc
1044b544f3c8SBram Moolenaar
1045b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
1046b544f3c8SBram Moolenaar" Test 92:  skipping code					    {{{1
1047b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
1048b544f3c8SBram Moolenaar
1049b544f3c8SBram Moolenaarfunc Test_skip()
1050b544f3c8SBram Moolenaar    let Fn = function('Test_type')
1051b544f3c8SBram Moolenaar    call assert_false(0 && Fn[1])
1052b544f3c8SBram Moolenaar    call assert_false(0 && string(Fn))
1053b544f3c8SBram Moolenaar    call assert_false(0 && len(Fn))
1054b544f3c8SBram Moolenaar    let l = []
1055b544f3c8SBram Moolenaar    call assert_false(0 && l[1])
1056b544f3c8SBram Moolenaar    call assert_false(0 && string(l))
1057b544f3c8SBram Moolenaar    call assert_false(0 && len(l))
1058b544f3c8SBram Moolenaar    let f = 1.0
1059b544f3c8SBram Moolenaar    call assert_false(0 && f[1])
1060b544f3c8SBram Moolenaar    call assert_false(0 && string(f))
1061b544f3c8SBram Moolenaar    call assert_false(0 && len(f))
1062b544f3c8SBram Moolenaar    let sp = v:null
1063b544f3c8SBram Moolenaar    call assert_false(0 && sp[1])
1064b544f3c8SBram Moolenaar    call assert_false(0 && string(sp))
1065b544f3c8SBram Moolenaar    call assert_false(0 && len(sp))
1066b544f3c8SBram Moolenaar
1067b544f3c8SBram Moolenaarendfunc
1068b544f3c8SBram Moolenaar
1069b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
1070b544f3c8SBram Moolenaar" Test 93:  :echo and string()					    {{{1
1071b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
1072b544f3c8SBram Moolenaar
1073b544f3c8SBram Moolenaarfunc Test_echo_and_string()
1074b544f3c8SBram Moolenaar    " String
1075b544f3c8SBram Moolenaar    let a = 'foo bar'
1076b544f3c8SBram Moolenaar    redir => result
1077b544f3c8SBram Moolenaar    echo a
1078b544f3c8SBram Moolenaar    echo string(a)
1079b544f3c8SBram Moolenaar    redir END
1080b544f3c8SBram Moolenaar    let l = split(result, "\n")
1081b544f3c8SBram Moolenaar    call assert_equal(["foo bar",
1082b544f3c8SBram Moolenaar		     \ "'foo bar'"], l)
1083b544f3c8SBram Moolenaar
1084b544f3c8SBram Moolenaar    " Float
1085b544f3c8SBram Moolenaar    if has('float')
1086b544f3c8SBram Moolenaar	let a = -1.2e0
1087b544f3c8SBram Moolenaar	redir => result
1088b544f3c8SBram Moolenaar	echo a
1089b544f3c8SBram Moolenaar	echo string(a)
1090b544f3c8SBram Moolenaar	redir END
1091b544f3c8SBram Moolenaar	let l = split(result, "\n")
1092b544f3c8SBram Moolenaar	call assert_equal(["-1.2",
1093b544f3c8SBram Moolenaar			 \ "-1.2"], l)
1094b544f3c8SBram Moolenaar    endif
1095b544f3c8SBram Moolenaar
1096b544f3c8SBram Moolenaar    " Funcref
1097b544f3c8SBram Moolenaar    redir => result
1098b544f3c8SBram Moolenaar    echo function('string')
1099b544f3c8SBram Moolenaar    echo string(function('string'))
1100b544f3c8SBram Moolenaar    redir END
1101b544f3c8SBram Moolenaar    let l = split(result, "\n")
1102b544f3c8SBram Moolenaar    call assert_equal(["string",
1103b544f3c8SBram Moolenaar		     \ "function('string')"], l)
1104b544f3c8SBram Moolenaar
1105b544f3c8SBram Moolenaar    " Recursive dictionary
1106b544f3c8SBram Moolenaar    let a = {}
1107b544f3c8SBram Moolenaar    let a["a"] = a
1108b544f3c8SBram Moolenaar    redir => result
1109b544f3c8SBram Moolenaar    echo a
1110b544f3c8SBram Moolenaar    echo string(a)
1111b544f3c8SBram Moolenaar    redir END
1112b544f3c8SBram Moolenaar    let l = split(result, "\n")
1113b544f3c8SBram Moolenaar    call assert_equal(["{'a': {...}}",
1114b544f3c8SBram Moolenaar		     \ "{'a': {...}}"], l)
1115b544f3c8SBram Moolenaar
1116b544f3c8SBram Moolenaar    " Recursive list
1117b544f3c8SBram Moolenaar    let a = [0]
1118b544f3c8SBram Moolenaar    let a[0] = a
1119b544f3c8SBram Moolenaar    redir => result
1120b544f3c8SBram Moolenaar    echo a
1121b544f3c8SBram Moolenaar    echo string(a)
1122b544f3c8SBram Moolenaar    redir END
1123b544f3c8SBram Moolenaar    let l = split(result, "\n")
1124b544f3c8SBram Moolenaar    call assert_equal(["[[...]]",
1125b544f3c8SBram Moolenaar		     \ "[[...]]"], l)
1126b544f3c8SBram Moolenaar
1127b544f3c8SBram Moolenaar    " Empty dictionaries in a list
1128b544f3c8SBram Moolenaar    let a = {}
1129b544f3c8SBram Moolenaar    redir => result
1130b544f3c8SBram Moolenaar    echo [a, a, a]
1131b544f3c8SBram Moolenaar    echo string([a, a, a])
1132b544f3c8SBram Moolenaar    redir END
1133b544f3c8SBram Moolenaar    let l = split(result, "\n")
1134b544f3c8SBram Moolenaar    call assert_equal(["[{}, {}, {}]",
1135b544f3c8SBram Moolenaar		     \ "[{}, {}, {}]"], l)
1136b544f3c8SBram Moolenaar
1137b544f3c8SBram Moolenaar    " Empty dictionaries in a dictionary
1138b544f3c8SBram Moolenaar    let a = {}
1139b544f3c8SBram Moolenaar    let b = {"a": a, "b": a}
1140b544f3c8SBram Moolenaar    redir => result
1141b544f3c8SBram Moolenaar    echo b
1142b544f3c8SBram Moolenaar    echo string(b)
1143b544f3c8SBram Moolenaar    redir END
1144b544f3c8SBram Moolenaar    let l = split(result, "\n")
1145b544f3c8SBram Moolenaar    call assert_equal(["{'a': {}, 'b': {}}",
1146b544f3c8SBram Moolenaar		     \ "{'a': {}, 'b': {}}"], l)
1147b544f3c8SBram Moolenaar
1148b544f3c8SBram Moolenaar    " Empty lists in a list
1149b544f3c8SBram Moolenaar    let a = []
1150b544f3c8SBram Moolenaar    redir => result
1151b544f3c8SBram Moolenaar    echo [a, a, a]
1152b544f3c8SBram Moolenaar    echo string([a, a, a])
1153b544f3c8SBram Moolenaar    redir END
1154b544f3c8SBram Moolenaar    let l = split(result, "\n")
1155b544f3c8SBram Moolenaar    call assert_equal(["[[], [], []]",
1156b544f3c8SBram Moolenaar		     \ "[[], [], []]"], l)
1157b544f3c8SBram Moolenaar
1158b544f3c8SBram Moolenaar    " Empty lists in a dictionary
1159b544f3c8SBram Moolenaar    let a = []
1160b544f3c8SBram Moolenaar    let b = {"a": a, "b": a}
1161b544f3c8SBram Moolenaar    redir => result
1162b544f3c8SBram Moolenaar    echo b
1163b544f3c8SBram Moolenaar    echo string(b)
1164b544f3c8SBram Moolenaar    redir END
1165b544f3c8SBram Moolenaar    let l = split(result, "\n")
1166b544f3c8SBram Moolenaar    call assert_equal(["{'a': [], 'b': []}",
1167b544f3c8SBram Moolenaar		     \ "{'a': [], 'b': []}"], l)
1168b544f3c8SBram Moolenaar
1169b544f3c8SBram Moolenaar    " Dictionaries in a list
1170b544f3c8SBram Moolenaar    let a = {"one": "yes", "two": "yes", "three": "yes"}
1171b544f3c8SBram Moolenaar    redir => result
1172b544f3c8SBram Moolenaar    echo [a, a, a]
1173b544f3c8SBram Moolenaar    echo string([a, a, a])
1174b544f3c8SBram Moolenaar    redir END
1175b544f3c8SBram Moolenaar    let l = split(result, "\n")
1176b544f3c8SBram Moolenaar    call assert_equal(["[{'one': 'yes', 'two': 'yes', 'three': 'yes'}, {...}, {...}]",
1177b544f3c8SBram Moolenaar		     \ "[{'one': 'yes', 'two': 'yes', 'three': 'yes'}, {'one': 'yes', 'two': 'yes', 'three': 'yes'}, {'one': 'yes', 'two': 'yes', 'three': 'yes'}]"], l)
1178b544f3c8SBram Moolenaar
1179b544f3c8SBram Moolenaar    " Dictionaries in a dictionary
1180b544f3c8SBram Moolenaar    let a = {"one": "yes", "two": "yes", "three": "yes"}
1181b544f3c8SBram Moolenaar    let b = {"a": a, "b": a}
1182b544f3c8SBram Moolenaar    redir => result
1183b544f3c8SBram Moolenaar    echo b
1184b544f3c8SBram Moolenaar    echo string(b)
1185b544f3c8SBram Moolenaar    redir END
1186b544f3c8SBram Moolenaar    let l = split(result, "\n")
1187b544f3c8SBram Moolenaar    call assert_equal(["{'a': {'one': 'yes', 'two': 'yes', 'three': 'yes'}, 'b': {...}}",
1188b544f3c8SBram Moolenaar		     \ "{'a': {'one': 'yes', 'two': 'yes', 'three': 'yes'}, 'b': {'one': 'yes', 'two': 'yes', 'three': 'yes'}}"], l)
1189b544f3c8SBram Moolenaar
1190b544f3c8SBram Moolenaar    " Lists in a list
1191b544f3c8SBram Moolenaar    let a = [1, 2, 3]
1192b544f3c8SBram Moolenaar    redir => result
1193b544f3c8SBram Moolenaar    echo [a, a, a]
1194b544f3c8SBram Moolenaar    echo string([a, a, a])
1195b544f3c8SBram Moolenaar    redir END
1196b544f3c8SBram Moolenaar    let l = split(result, "\n")
1197b544f3c8SBram Moolenaar    call assert_equal(["[[1, 2, 3], [...], [...]]",
1198b544f3c8SBram Moolenaar		     \ "[[1, 2, 3], [1, 2, 3], [1, 2, 3]]"], l)
1199b544f3c8SBram Moolenaar
1200b544f3c8SBram Moolenaar    " Lists in a dictionary
1201b544f3c8SBram Moolenaar    let a = [1, 2, 3]
1202b544f3c8SBram Moolenaar    let b = {"a": a, "b": a}
1203b544f3c8SBram Moolenaar    redir => result
1204b544f3c8SBram Moolenaar    echo b
1205b544f3c8SBram Moolenaar    echo string(b)
1206b544f3c8SBram Moolenaar    redir END
1207b544f3c8SBram Moolenaar    let l = split(result, "\n")
1208b544f3c8SBram Moolenaar    call assert_equal(["{'a': [1, 2, 3], 'b': [...]}",
1209b544f3c8SBram Moolenaar		     \ "{'a': [1, 2, 3], 'b': [1, 2, 3]}"], l)
1210b544f3c8SBram Moolenaar
1211b544f3c8SBram Moolenaarendfunc
1212b544f3c8SBram Moolenaar
1213b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
1214b544f3c8SBram Moolenaar" Test 94:  64-bit Numbers					    {{{1
1215b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
1216b544f3c8SBram Moolenaar
1217b544f3c8SBram Moolenaarfunc Test_num64()
1218b544f3c8SBram Moolenaar    if !has('num64')
1219b544f3c8SBram Moolenaar	return
1220b544f3c8SBram Moolenaar    endif
1221b544f3c8SBram Moolenaar
1222b544f3c8SBram Moolenaar    call assert_notequal( 4294967296, 0)
1223b544f3c8SBram Moolenaar    call assert_notequal(-4294967296, 0)
1224b544f3c8SBram Moolenaar    call assert_equal( 4294967296,  0xFFFFffff + 1)
1225b544f3c8SBram Moolenaar    call assert_equal(-4294967296, -0xFFFFffff - 1)
1226b544f3c8SBram Moolenaar
1227b544f3c8SBram Moolenaar    call assert_equal( 9223372036854775807,  1 / 0)
1228b544f3c8SBram Moolenaar    call assert_equal(-9223372036854775807, -1 / 0)
1229b544f3c8SBram Moolenaar    call assert_equal(-9223372036854775807 - 1,  0 / 0)
1230b544f3c8SBram Moolenaar
1231b544f3c8SBram Moolenaar    call assert_equal( 0x7FFFffffFFFFffff, float2nr( 1.0e150))
1232b544f3c8SBram Moolenaar    call assert_equal(-0x7FFFffffFFFFffff, float2nr(-1.0e150))
1233b544f3c8SBram Moolenaar
1234b544f3c8SBram Moolenaar    let rng = range(0xFFFFffff, 0x100000001)
1235b544f3c8SBram Moolenaar    call assert_equal([0xFFFFffff, 0x100000000, 0x100000001], rng)
1236b544f3c8SBram Moolenaar    call assert_equal(0x100000001, max(rng))
1237b544f3c8SBram Moolenaar    call assert_equal(0xFFFFffff, min(rng))
1238b544f3c8SBram Moolenaar    call assert_equal(rng, sort(range(0x100000001, 0xFFFFffff, -1), 'N'))
1239b544f3c8SBram Moolenaarendfunc
1240b544f3c8SBram Moolenaar
1241b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
1242b544f3c8SBram Moolenaar" Test 95:  lines of :append, :change, :insert			    {{{1
1243b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
1244b544f3c8SBram Moolenaar
1245b544f3c8SBram Moolenaarfunction! DefineFunction(name, body)
1246b544f3c8SBram Moolenaar    let func = join(['function! ' . a:name . '()'] + a:body + ['endfunction'], "\n")
1247b544f3c8SBram Moolenaar    exec func
1248b544f3c8SBram Moolenaarendfunction
1249b544f3c8SBram Moolenaar
1250b544f3c8SBram Moolenaarfunc Test_script_lines()
1251b544f3c8SBram Moolenaar    " :append
1252b544f3c8SBram Moolenaar    try
1253b544f3c8SBram Moolenaar	call DefineFunction('T_Append', [
1254b544f3c8SBram Moolenaar		    \ 'append',
1255b544f3c8SBram Moolenaar		    \ 'py <<EOS',
1256b544f3c8SBram Moolenaar		    \ '.',
1257b544f3c8SBram Moolenaar		    \ ])
1258b544f3c8SBram Moolenaar    catch
125937175409SBram Moolenaar	call assert_report("Can't define function")
1260b544f3c8SBram Moolenaar    endtry
1261b544f3c8SBram Moolenaar    try
1262b544f3c8SBram Moolenaar	call DefineFunction('T_Append', [
1263b544f3c8SBram Moolenaar		    \ 'append',
1264b544f3c8SBram Moolenaar		    \ 'abc',
1265b544f3c8SBram Moolenaar		    \ ])
126637175409SBram Moolenaar	call assert_report("Shouldn't be able to define function")
1267b544f3c8SBram Moolenaar    catch
1268b544f3c8SBram Moolenaar	call assert_exception('Vim(function):E126: Missing :endfunction')
1269b544f3c8SBram Moolenaar    endtry
1270b544f3c8SBram Moolenaar
1271b544f3c8SBram Moolenaar    " :change
1272b544f3c8SBram Moolenaar    try
1273b544f3c8SBram Moolenaar	call DefineFunction('T_Change', [
1274b544f3c8SBram Moolenaar		    \ 'change',
1275b544f3c8SBram Moolenaar		    \ 'py <<EOS',
1276b544f3c8SBram Moolenaar		    \ '.',
1277b544f3c8SBram Moolenaar		    \ ])
1278b544f3c8SBram Moolenaar    catch
127937175409SBram Moolenaar	call assert_report("Can't define function")
1280b544f3c8SBram Moolenaar    endtry
1281b544f3c8SBram Moolenaar    try
1282b544f3c8SBram Moolenaar	call DefineFunction('T_Change', [
1283b544f3c8SBram Moolenaar		    \ 'change',
1284b544f3c8SBram Moolenaar		    \ 'abc',
1285b544f3c8SBram Moolenaar		    \ ])
128637175409SBram Moolenaar	call assert_report("Shouldn't be able to define function")
1287b544f3c8SBram Moolenaar    catch
1288b544f3c8SBram Moolenaar	call assert_exception('Vim(function):E126: Missing :endfunction')
1289b544f3c8SBram Moolenaar    endtry
1290b544f3c8SBram Moolenaar
1291b544f3c8SBram Moolenaar    " :insert
1292b544f3c8SBram Moolenaar    try
1293b544f3c8SBram Moolenaar	call DefineFunction('T_Insert', [
1294b544f3c8SBram Moolenaar		    \ 'insert',
1295b544f3c8SBram Moolenaar		    \ 'py <<EOS',
1296b544f3c8SBram Moolenaar		    \ '.',
1297b544f3c8SBram Moolenaar		    \ ])
1298b544f3c8SBram Moolenaar    catch
129937175409SBram Moolenaar	call assert_report("Can't define function")
1300b544f3c8SBram Moolenaar    endtry
1301b544f3c8SBram Moolenaar    try
1302b544f3c8SBram Moolenaar	call DefineFunction('T_Insert', [
1303b544f3c8SBram Moolenaar		    \ 'insert',
1304b544f3c8SBram Moolenaar		    \ 'abc',
1305b544f3c8SBram Moolenaar		    \ ])
130637175409SBram Moolenaar	call assert_report("Shouldn't be able to define function")
1307b544f3c8SBram Moolenaar    catch
1308b544f3c8SBram Moolenaar	call assert_exception('Vim(function):E126: Missing :endfunction')
1309b544f3c8SBram Moolenaar    endtry
1310b544f3c8SBram Moolenaarendfunc
1311b544f3c8SBram Moolenaar
1312b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
1313478af67dSBram Moolenaar" Test 96:  line continuation						    {{{1
1314478af67dSBram Moolenaar"
1315478af67dSBram Moolenaar"	    Undefined behavior was detected by ubsan with line continuation
1316478af67dSBram Moolenaar"	    after an empty line.
1317478af67dSBram Moolenaar"-------------------------------------------------------------------------------
1318478af67dSBram Moolenaarfunc Test_script_emty_line_continuation()
1319478af67dSBram Moolenaar
1320478af67dSBram Moolenaar    \
1321478af67dSBram Moolenaarendfunc
1322478af67dSBram Moolenaar
1323478af67dSBram Moolenaar"-------------------------------------------------------------------------------
1324863e80b4SBram Moolenaar" Test 97:  bitwise functions						    {{{1
1325863e80b4SBram Moolenaar"-------------------------------------------------------------------------------
1326863e80b4SBram Moolenaarfunc Test_bitwise_functions()
1327863e80b4SBram Moolenaar    " and
1328863e80b4SBram Moolenaar    call assert_equal(127, and(127, 127))
1329863e80b4SBram Moolenaar    call assert_equal(16, and(127, 16))
1330863e80b4SBram Moolenaar    call assert_equal(0, and(127, 128))
1331863e80b4SBram Moolenaar    call assert_fails("call and(1.0, 1)", 'E805:')
1332863e80b4SBram Moolenaar    call assert_fails("call and([], 1)", 'E745:')
1333863e80b4SBram Moolenaar    call assert_fails("call and({}, 1)", 'E728:')
1334863e80b4SBram Moolenaar    call assert_fails("call and(1, 1.0)", 'E805:')
1335863e80b4SBram Moolenaar    call assert_fails("call and(1, [])", 'E745:')
1336863e80b4SBram Moolenaar    call assert_fails("call and(1, {})", 'E728:')
1337863e80b4SBram Moolenaar    " or
1338863e80b4SBram Moolenaar    call assert_equal(23, or(16, 7))
1339863e80b4SBram Moolenaar    call assert_equal(15, or(8, 7))
1340863e80b4SBram Moolenaar    call assert_equal(123, or(0, 123))
1341863e80b4SBram Moolenaar    call assert_fails("call or(1.0, 1)", 'E805:')
1342863e80b4SBram Moolenaar    call assert_fails("call or([], 1)", 'E745:')
1343863e80b4SBram Moolenaar    call assert_fails("call or({}, 1)", 'E728:')
1344863e80b4SBram Moolenaar    call assert_fails("call or(1, 1.0)", 'E805:')
1345863e80b4SBram Moolenaar    call assert_fails("call or(1, [])", 'E745:')
1346863e80b4SBram Moolenaar    call assert_fails("call or(1, {})", 'E728:')
1347863e80b4SBram Moolenaar    " xor
1348863e80b4SBram Moolenaar    call assert_equal(0, xor(127, 127))
1349863e80b4SBram Moolenaar    call assert_equal(111, xor(127, 16))
1350863e80b4SBram Moolenaar    call assert_equal(255, xor(127, 128))
1351863e80b4SBram Moolenaar    call assert_fails("call xor(1.0, 1)", 'E805:')
1352863e80b4SBram Moolenaar    call assert_fails("call xor([], 1)", 'E745:')
1353863e80b4SBram Moolenaar    call assert_fails("call xor({}, 1)", 'E728:')
1354863e80b4SBram Moolenaar    call assert_fails("call xor(1, 1.0)", 'E805:')
1355863e80b4SBram Moolenaar    call assert_fails("call xor(1, [])", 'E745:')
1356863e80b4SBram Moolenaar    call assert_fails("call xor(1, {})", 'E728:')
1357863e80b4SBram Moolenaar    " invert
1358863e80b4SBram Moolenaar    call assert_equal(65408, and(invert(127), 65535))
1359863e80b4SBram Moolenaar    call assert_equal(65519, and(invert(16), 65535))
1360863e80b4SBram Moolenaar    call assert_equal(65407, and(invert(128), 65535))
1361863e80b4SBram Moolenaar    call assert_fails("call invert(1.0)", 'E805:')
1362863e80b4SBram Moolenaar    call assert_fails("call invert([])", 'E745:')
1363863e80b4SBram Moolenaar    call assert_fails("call invert({})", 'E728:')
1364863e80b4SBram Moolenaarendfunc
1365863e80b4SBram Moolenaar
1366663bb233SBram Moolenaar" Test trailing text after :endfunction				    {{{1
1367663bb233SBram Moolenaarfunc Test_endfunction_trailing()
1368663bb233SBram Moolenaar    call assert_false(exists('*Xtest'))
1369663bb233SBram Moolenaar
1370663bb233SBram Moolenaar    exe "func Xtest()\necho 'hello'\nendfunc\nlet done = 'yes'"
1371663bb233SBram Moolenaar    call assert_true(exists('*Xtest'))
1372663bb233SBram Moolenaar    call assert_equal('yes', done)
1373663bb233SBram Moolenaar    delfunc Xtest
1374663bb233SBram Moolenaar    unlet done
1375663bb233SBram Moolenaar
1376663bb233SBram Moolenaar    exe "func Xtest()\necho 'hello'\nendfunc|let done = 'yes'"
1377663bb233SBram Moolenaar    call assert_true(exists('*Xtest'))
1378663bb233SBram Moolenaar    call assert_equal('yes', done)
1379663bb233SBram Moolenaar    delfunc Xtest
1380663bb233SBram Moolenaar    unlet done
1381663bb233SBram Moolenaar
138253564f7cSBram Moolenaar    " trailing line break
138353564f7cSBram Moolenaar    exe "func Xtest()\necho 'hello'\nendfunc\n"
138453564f7cSBram Moolenaar    call assert_true(exists('*Xtest'))
138553564f7cSBram Moolenaar    delfunc Xtest
138653564f7cSBram Moolenaar
1387663bb233SBram Moolenaar    set verbose=1
1388663bb233SBram Moolenaar    exe "func Xtest()\necho 'hello'\nendfunc \" garbage"
1389f8be461dSBram Moolenaar    call assert_notmatch('W22:', split(execute('1messages'), "\n")[0])
1390663bb233SBram Moolenaar    call assert_true(exists('*Xtest'))
1391663bb233SBram Moolenaar    delfunc Xtest
1392663bb233SBram Moolenaar
1393f8be461dSBram Moolenaar    exe "func Xtest()\necho 'hello'\nendfunc garbage"
1394f8be461dSBram Moolenaar    call assert_match('W22:', split(execute('1messages'), "\n")[0])
1395663bb233SBram Moolenaar    call assert_true(exists('*Xtest'))
1396663bb233SBram Moolenaar    delfunc Xtest
1397663bb233SBram Moolenaar    set verbose=0
139853564f7cSBram Moolenaar
139953564f7cSBram Moolenaar    function Foo()
140053564f7cSBram Moolenaar	echo 'hello'
140153564f7cSBram Moolenaar    endfunction | echo 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
140253564f7cSBram Moolenaar    delfunc Foo
1403663bb233SBram Moolenaarendfunc
1404663bb233SBram Moolenaar
1405d6abcd15SBram Moolenaarfunc Test_delfunction_force()
1406d6abcd15SBram Moolenaar    delfunc! Xtest
1407d6abcd15SBram Moolenaar    delfunc! Xtest
1408d6abcd15SBram Moolenaar    func Xtest()
1409d6abcd15SBram Moolenaar	echo 'nothing'
1410d6abcd15SBram Moolenaar    endfunc
1411d6abcd15SBram Moolenaar    delfunc! Xtest
1412d6abcd15SBram Moolenaar    delfunc! Xtest
1413d6abcd15SBram Moolenaarendfunc
1414d6abcd15SBram Moolenaar
14156f9a476bSBram Moolenaar" Test using bang after user command				    {{{1
14166f9a476bSBram Moolenaarfunc Test_user_command_with_bang()
14176f9a476bSBram Moolenaar    command -bang Nieuw let nieuw = 1
14186f9a476bSBram Moolenaar    Ni!
14196f9a476bSBram Moolenaar    call assert_equal(1, nieuw)
14206f9a476bSBram Moolenaar    unlet nieuw
14216f9a476bSBram Moolenaar    delcommand Nieuw
14226f9a476bSBram Moolenaarendfunc
14236f9a476bSBram Moolenaar
1424bb3e6416SBram Moolenaar" Test for script-local function
1425bb3e6416SBram Moolenaarfunc <SID>DoLast()
1426bb3e6416SBram Moolenaar  call append(line('$'), "last line")
1427bb3e6416SBram Moolenaarendfunc
1428bb3e6416SBram Moolenaar
1429bb3e6416SBram Moolenaarfunc s:DoNothing()
1430bb3e6416SBram Moolenaar  call append(line('$'), "nothing line")
1431bb3e6416SBram Moolenaarendfunc
1432bb3e6416SBram Moolenaar
1433bb3e6416SBram Moolenaarfunc Test_script_local_func()
1434bb3e6416SBram Moolenaar  set nocp viminfo+=nviminfo
1435bb3e6416SBram Moolenaar  new
1436bb3e6416SBram Moolenaar  nnoremap <buffer> _x	:call <SID>DoNothing()<bar>call <SID>DoLast()<bar>delfunc <SID>DoNothing<bar>delfunc <SID>DoLast<cr>
1437bb3e6416SBram Moolenaar
1438bb3e6416SBram Moolenaar  normal _x
1439bb3e6416SBram Moolenaar  call assert_equal('nothing line', getline(2))
1440bb3e6416SBram Moolenaar  call assert_equal('last line', getline(3))
1441bb3e6416SBram Moolenaar  enew! | close
1442bb3e6416SBram Moolenaarendfunc
1443bb3e6416SBram Moolenaar
1444ff697e6cSBram Moolenaarfunc Test_compound_assignment_operators()
1445ff697e6cSBram Moolenaar    " Test for number
1446ff697e6cSBram Moolenaar    let x = 1
1447ff697e6cSBram Moolenaar    let x += 10
1448ff697e6cSBram Moolenaar    call assert_equal(11, x)
1449ff697e6cSBram Moolenaar    let x -= 5
1450ff697e6cSBram Moolenaar    call assert_equal(6, x)
1451ff697e6cSBram Moolenaar    let x *= 4
1452ff697e6cSBram Moolenaar    call assert_equal(24, x)
1453ff697e6cSBram Moolenaar    let x /= 3
1454ff697e6cSBram Moolenaar    call assert_equal(8, x)
1455ff697e6cSBram Moolenaar    let x %= 3
1456ff697e6cSBram Moolenaar    call assert_equal(2, x)
1457ff697e6cSBram Moolenaar    let x .= 'n'
1458ff697e6cSBram Moolenaar    call assert_equal('2n', x)
1459ff697e6cSBram Moolenaar
1460e21c1580SBram Moolenaar    " Test special cases: division or modulus with 0.
1461e21c1580SBram Moolenaar    let x = 1
1462e21c1580SBram Moolenaar    let x /= 0
1463e21c1580SBram Moolenaar    if has('num64')
1464e21c1580SBram Moolenaar        call assert_equal(0x7FFFFFFFFFFFFFFF, x)
1465e21c1580SBram Moolenaar    else
1466e21c1580SBram Moolenaar        call assert_equal(0x7fffffff, x)
1467e21c1580SBram Moolenaar    endif
1468e21c1580SBram Moolenaar
1469e21c1580SBram Moolenaar    let x = -1
1470e21c1580SBram Moolenaar    let x /= 0
1471e21c1580SBram Moolenaar    if has('num64')
1472e21c1580SBram Moolenaar        call assert_equal(-0x7FFFFFFFFFFFFFFF, x)
1473e21c1580SBram Moolenaar    else
1474e21c1580SBram Moolenaar        call assert_equal(-0x7fffffff, x)
1475e21c1580SBram Moolenaar    endif
1476e21c1580SBram Moolenaar
1477e21c1580SBram Moolenaar    let x = 0
1478e21c1580SBram Moolenaar    let x /= 0
1479e21c1580SBram Moolenaar    if has('num64')
1480e21c1580SBram Moolenaar        call assert_equal(-0x7FFFFFFFFFFFFFFF - 1, x)
1481e21c1580SBram Moolenaar    else
1482e21c1580SBram Moolenaar        call assert_equal(-0x7FFFFFFF - 1, x)
1483e21c1580SBram Moolenaar    endif
1484e21c1580SBram Moolenaar
1485e21c1580SBram Moolenaar    let x = 1
1486e21c1580SBram Moolenaar    let x %= 0
1487e21c1580SBram Moolenaar    call assert_equal(0, x)
1488e21c1580SBram Moolenaar
1489e21c1580SBram Moolenaar    let x = -1
1490e21c1580SBram Moolenaar    let x %= 0
1491e21c1580SBram Moolenaar    call assert_equal(0, x)
1492e21c1580SBram Moolenaar
1493e21c1580SBram Moolenaar    let x = 0
1494e21c1580SBram Moolenaar    let x %= 0
1495e21c1580SBram Moolenaar    call assert_equal(0, x)
1496e21c1580SBram Moolenaar
1497ff697e6cSBram Moolenaar    " Test for string
1498ff697e6cSBram Moolenaar    let x = 'str'
1499ff697e6cSBram Moolenaar    let x .= 'ing'
1500ff697e6cSBram Moolenaar    call assert_equal('string', x)
1501ff697e6cSBram Moolenaar    let x += 1
1502ff697e6cSBram Moolenaar    call assert_equal(1, x)
1503ff697e6cSBram Moolenaar    let x -= 1.5
1504ff697e6cSBram Moolenaar    call assert_equal(-0.5, x)
1505ff697e6cSBram Moolenaar
1506ff697e6cSBram Moolenaar    if has('float')
1507ff697e6cSBram Moolenaar        " Test for float
1508ff697e6cSBram Moolenaar        let x = 0.5
1509ff697e6cSBram Moolenaar        let x += 4.5
1510ff697e6cSBram Moolenaar        call assert_equal(5.0, x)
1511ff697e6cSBram Moolenaar        let x -= 1.5
1512ff697e6cSBram Moolenaar        call assert_equal(3.5, x)
1513ff697e6cSBram Moolenaar        let x *= 3.0
1514ff697e6cSBram Moolenaar        call assert_equal(10.5, x)
1515ff697e6cSBram Moolenaar        let x /= 2.5
1516ff697e6cSBram Moolenaar        call assert_equal(4.2, x)
1517ff697e6cSBram Moolenaar        call assert_fails('let x %= 0.5', 'E734')
1518ff697e6cSBram Moolenaar        call assert_fails('let x .= "f"', 'E734')
1519ff697e6cSBram Moolenaar    endif
1520ff697e6cSBram Moolenaar
1521ff697e6cSBram Moolenaar    " Test for environment variable
1522ff697e6cSBram Moolenaar    let $FOO = 1
1523ff697e6cSBram Moolenaar    call assert_fails('let $FOO += 1', 'E734')
1524ff697e6cSBram Moolenaar    call assert_fails('let $FOO -= 1', 'E734')
1525ff697e6cSBram Moolenaar    call assert_fails('let $FOO *= 1', 'E734')
1526ff697e6cSBram Moolenaar    call assert_fails('let $FOO /= 1', 'E734')
1527ff697e6cSBram Moolenaar    call assert_fails('let $FOO %= 1', 'E734')
1528ff697e6cSBram Moolenaar    let $FOO .= 's'
1529ff697e6cSBram Moolenaar    call assert_equal('1s', $FOO)
1530ff697e6cSBram Moolenaar    unlet $FOO
1531ff697e6cSBram Moolenaar
1532ff697e6cSBram Moolenaar    " Test for option variable (type: number)
1533ff697e6cSBram Moolenaar    let &scrolljump = 1
1534ff697e6cSBram Moolenaar    let &scrolljump += 5
1535ff697e6cSBram Moolenaar    call assert_equal(6, &scrolljump)
1536ff697e6cSBram Moolenaar    let &scrolljump -= 2
1537ff697e6cSBram Moolenaar    call assert_equal(4, &scrolljump)
1538ff697e6cSBram Moolenaar    let &scrolljump *= 3
1539ff697e6cSBram Moolenaar    call assert_equal(12, &scrolljump)
1540ff697e6cSBram Moolenaar    let &scrolljump /= 2
1541ff697e6cSBram Moolenaar    call assert_equal(6, &scrolljump)
1542ff697e6cSBram Moolenaar    let &scrolljump %= 5
1543ff697e6cSBram Moolenaar    call assert_equal(1, &scrolljump)
1544ff697e6cSBram Moolenaar    call assert_fails('let &scrolljump .= "j"', 'E734')
1545ff697e6cSBram Moolenaar    set scrolljump&vim
1546ff697e6cSBram Moolenaar
1547ff697e6cSBram Moolenaar    " Test for register
1548ff697e6cSBram Moolenaar    let @/ = 1
1549ff697e6cSBram Moolenaar    call assert_fails('let @/ += 1', 'E734')
1550ff697e6cSBram Moolenaar    call assert_fails('let @/ -= 1', 'E734')
1551ff697e6cSBram Moolenaar    call assert_fails('let @/ *= 1', 'E734')
1552ff697e6cSBram Moolenaar    call assert_fails('let @/ /= 1', 'E734')
1553ff697e6cSBram Moolenaar    call assert_fails('let @/ %= 1', 'E734')
1554ff697e6cSBram Moolenaar    let @/ .= 's'
1555ff697e6cSBram Moolenaar    call assert_equal('1s', @/)
1556ff697e6cSBram Moolenaar    let @/ = ''
1557ff697e6cSBram Moolenaarendfunc
1558ff697e6cSBram Moolenaar
1559c3e92c16SBram Moolenaarfunc Test_refcount()
1560c3e92c16SBram Moolenaar    " Immediate values
1561c3e92c16SBram Moolenaar    call assert_equal(-1, test_refcount(1))
1562c3e92c16SBram Moolenaar    call assert_equal(-1, test_refcount('s'))
1563c3e92c16SBram Moolenaar    call assert_equal(-1, test_refcount(v:true))
1564c3e92c16SBram Moolenaar    call assert_equal(0, test_refcount([]))
1565c3e92c16SBram Moolenaar    call assert_equal(0, test_refcount({}))
1566c3e92c16SBram Moolenaar    call assert_equal(0, test_refcount(0zff))
1567c3e92c16SBram Moolenaar    call assert_equal(0, test_refcount({-> line('.')}))
1568c3e92c16SBram Moolenaar    if has('float')
1569c3e92c16SBram Moolenaar        call assert_equal(-1, test_refcount(0.1))
1570c3e92c16SBram Moolenaar    endif
1571c3e92c16SBram Moolenaar    if has('job')
1572c3e92c16SBram Moolenaar        call assert_equal(0, test_refcount(job_start([&shell, &shellcmdflag, 'echo .'])))
1573c3e92c16SBram Moolenaar    endif
1574c3e92c16SBram Moolenaar
1575c3e92c16SBram Moolenaar    " No refcount types
1576c3e92c16SBram Moolenaar    let x = 1
1577c3e92c16SBram Moolenaar    call assert_equal(-1, test_refcount(x))
1578c3e92c16SBram Moolenaar    let x = 's'
1579c3e92c16SBram Moolenaar    call assert_equal(-1, test_refcount(x))
1580c3e92c16SBram Moolenaar    let x = v:true
1581c3e92c16SBram Moolenaar    call assert_equal(-1, test_refcount(x))
1582c3e92c16SBram Moolenaar    if has('float')
1583c3e92c16SBram Moolenaar        let x = 0.1
1584c3e92c16SBram Moolenaar        call assert_equal(-1, test_refcount(x))
1585c3e92c16SBram Moolenaar    endif
1586c3e92c16SBram Moolenaar
1587c3e92c16SBram Moolenaar    " Check refcount
1588c3e92c16SBram Moolenaar    let x = []
1589c3e92c16SBram Moolenaar    call assert_equal(1, test_refcount(x))
1590c3e92c16SBram Moolenaar
1591c3e92c16SBram Moolenaar    let x = {}
1592c3e92c16SBram Moolenaar    call assert_equal(1, test_refcount(x))
1593c3e92c16SBram Moolenaar
1594c3e92c16SBram Moolenaar    let x = 0zff
1595c3e92c16SBram Moolenaar    call assert_equal(1, test_refcount(x))
1596c3e92c16SBram Moolenaar
1597c3e92c16SBram Moolenaar    let X = {-> line('.')}
1598c3e92c16SBram Moolenaar    call assert_equal(1, test_refcount(X))
1599c3e92c16SBram Moolenaar    let Y = X
1600c3e92c16SBram Moolenaar    call assert_equal(2, test_refcount(X))
1601c3e92c16SBram Moolenaar
1602c3e92c16SBram Moolenaar    if has('job')
1603c3e92c16SBram Moolenaar        let job = job_start([&shell, &shellcmdflag, 'echo .'])
1604c3e92c16SBram Moolenaar        call assert_equal(1, test_refcount(job))
1605c3e92c16SBram Moolenaar        call assert_equal(1, test_refcount(job_getchannel(job)))
1606c3e92c16SBram Moolenaar        call assert_equal(1, test_refcount(job))
1607c3e92c16SBram Moolenaar    endif
1608c3e92c16SBram Moolenaar
1609c3e92c16SBram Moolenaar    " Function arguments, copying and unassigning
1610c3e92c16SBram Moolenaar    func ExprCheck(x, i)
1611c3e92c16SBram Moolenaar        let i = a:i + 1
1612c3e92c16SBram Moolenaar        call assert_equal(i, test_refcount(a:x))
1613c3e92c16SBram Moolenaar        let Y = a:x
1614c3e92c16SBram Moolenaar        call assert_equal(i + 1, test_refcount(a:x))
1615c3e92c16SBram Moolenaar        call assert_equal(test_refcount(a:x), test_refcount(Y))
1616c3e92c16SBram Moolenaar        let Y = 0
1617c3e92c16SBram Moolenaar        call assert_equal(i, test_refcount(a:x))
1618c3e92c16SBram Moolenaar    endfunc
1619c3e92c16SBram Moolenaar    call ExprCheck([], 0)
1620c3e92c16SBram Moolenaar    call ExprCheck({}, 0)
1621c3e92c16SBram Moolenaar    call ExprCheck(0zff, 0)
1622c3e92c16SBram Moolenaar    call ExprCheck({-> line('.')}, 0)
1623c3e92c16SBram Moolenaar    if has('job')
1624c3e92c16SBram Moolenaar	call ExprCheck(job, 1)
1625c3e92c16SBram Moolenaar	call ExprCheck(job_getchannel(job), 1)
1626c3e92c16SBram Moolenaar	call job_stop(job)
1627c3e92c16SBram Moolenaar    endif
1628c3e92c16SBram Moolenaar    delfunc ExprCheck
1629c3e92c16SBram Moolenaar
1630c3e92c16SBram Moolenaar    " Regarding function
1631c3e92c16SBram Moolenaar    func Func(x) abort
1632c3e92c16SBram Moolenaar        call assert_equal(2, test_refcount(function('Func')))
1633c3e92c16SBram Moolenaar        call assert_equal(0, test_refcount(funcref('Func')))
1634c3e92c16SBram Moolenaar    endfunc
1635c3e92c16SBram Moolenaar    call assert_equal(1, test_refcount(function('Func')))
1636c3e92c16SBram Moolenaar    call assert_equal(0, test_refcount(function('Func', [1])))
1637c3e92c16SBram Moolenaar    call assert_equal(0, test_refcount(funcref('Func')))
1638c3e92c16SBram Moolenaar    call assert_equal(0, test_refcount(funcref('Func', [1])))
1639c3e92c16SBram Moolenaar    let X = function('Func')
1640c3e92c16SBram Moolenaar    let Y = X
1641c3e92c16SBram Moolenaar    call assert_equal(1, test_refcount(X))
1642c3e92c16SBram Moolenaar    let X = function('Func', [1])
1643c3e92c16SBram Moolenaar    let Y = X
1644c3e92c16SBram Moolenaar    call assert_equal(2, test_refcount(X))
1645c3e92c16SBram Moolenaar    let X = funcref('Func')
1646c3e92c16SBram Moolenaar    let Y = X
1647c3e92c16SBram Moolenaar    call assert_equal(2, test_refcount(X))
1648c3e92c16SBram Moolenaar    let X = funcref('Func', [1])
1649c3e92c16SBram Moolenaar    let Y = X
1650c3e92c16SBram Moolenaar    call assert_equal(2, test_refcount(X))
1651c3e92c16SBram Moolenaar    unlet X
1652c3e92c16SBram Moolenaar    unlet Y
1653c3e92c16SBram Moolenaar    call Func(1)
1654c3e92c16SBram Moolenaar    delfunc Func
1655c3e92c16SBram Moolenaar
1656c3e92c16SBram Moolenaar    " Function with dict
1657c3e92c16SBram Moolenaar    func DictFunc() dict
1658c3e92c16SBram Moolenaar        call assert_equal(3, test_refcount(self))
1659c3e92c16SBram Moolenaar    endfunc
1660c3e92c16SBram Moolenaar    let d = {'Func': function('DictFunc')}
1661c3e92c16SBram Moolenaar    call assert_equal(1, test_refcount(d))
1662c3e92c16SBram Moolenaar    call assert_equal(0, test_refcount(d.Func))
1663c3e92c16SBram Moolenaar    call d.Func()
1664c3e92c16SBram Moolenaar    unlet d
1665c3e92c16SBram Moolenaar    delfunc DictFunc
1666c3e92c16SBram Moolenaarendfunc
1667c3e92c16SBram Moolenaar
1668*6e5000d4SBram Moolenaarfunc! Test_funccall_garbage_collect()
1669*6e5000d4SBram Moolenaar    func Func(x, ...)
1670*6e5000d4SBram Moolenaar        call add(a:x, a:000)
1671*6e5000d4SBram Moolenaar    endfunc
1672*6e5000d4SBram Moolenaar    call Func([], [])
1673*6e5000d4SBram Moolenaar    " Must not crash cause by invalid freeing
1674*6e5000d4SBram Moolenaar    call test_garbagecollect_now()
1675*6e5000d4SBram Moolenaar    call assert_true(v:true)
1676*6e5000d4SBram Moolenaar    delfunc Func
1677*6e5000d4SBram Moolenaarendfunc
1678*6e5000d4SBram Moolenaar
1679863e80b4SBram Moolenaar"-------------------------------------------------------------------------------
1680b544f3c8SBram Moolenaar" Modelines								    {{{1
1681b544f3c8SBram Moolenaar" vim: ts=8 sw=4 tw=80 fdm=marker
1682b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
1683