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