15d7ead3bSBram Moolenaar" Test various aspects of the Vim script language.
2b544f3c8SBram Moolenaar" Most of this was formerly in test49.
3b544f3c8SBram Moolenaar
48c5a278fSBram Moolenaarsource check.vim
593344c2dSBram Moolenaarsource shared.vim
68c5a278fSBram Moolenaar
7b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
8b544f3c8SBram Moolenaar" Test environment							    {{{1
9b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
10b544f3c8SBram Moolenaar
11b544f3c8SBram Moolenaarcom!		   XpathINIT  let g:Xpath = ''
12b544f3c8SBram Moolenaarcom! -nargs=1 -bar Xpath      let g:Xpath = g:Xpath . <args>
13b544f3c8SBram Moolenaar
14b544f3c8SBram Moolenaar" Append a message to the "messages" file
151e115360SBram Moolenaarfunc Xout(text)
16b544f3c8SBram Moolenaar    split messages
17b544f3c8SBram Moolenaar    $put =a:text
18b544f3c8SBram Moolenaar    wq
19b544f3c8SBram Moolenaarendfunc
20b544f3c8SBram Moolenaar
21b544f3c8SBram Moolenaarcom! -nargs=1	     Xout     call Xout(<args>)
22b544f3c8SBram Moolenaar
23b544f3c8SBram Moolenaar" MakeScript() - Make a script file from a function.			    {{{2
24b544f3c8SBram Moolenaar"
25b544f3c8SBram Moolenaar" Create a script that consists of the body of the function a:funcname.
26b544f3c8SBram Moolenaar" Replace any ":return" by a ":finish", any argument variable by a global
27e21c1580SBram Moolenaar" variable, and every ":call" by a ":source" for the next following argument
28b544f3c8SBram Moolenaar" in the variable argument list.  This function is useful if similar tests are
29b544f3c8SBram Moolenaar" to be made for a ":return" from a function call or a ":finish" in a script
30b544f3c8SBram Moolenaar" file.
311e115360SBram Moolenaarfunc MakeScript(funcname, ...)
32b544f3c8SBram Moolenaar    let script = tempname()
33b544f3c8SBram Moolenaar    execute "redir! >" . script
34b544f3c8SBram Moolenaar    execute "function" a:funcname
35b544f3c8SBram Moolenaar    redir END
36b544f3c8SBram Moolenaar    execute "edit" script
37b544f3c8SBram Moolenaar    " Delete the "function" and the "endfunction" lines.  Do not include the
38b544f3c8SBram Moolenaar    " word "function" in the pattern since it might be translated if LANG is
39b544f3c8SBram Moolenaar    " set.  When MakeScript() is being debugged, this deletes also the debugging
40b544f3c8SBram Moolenaar    " output of its line 3 and 4.
41b544f3c8SBram Moolenaar    exec '1,/.*' . a:funcname . '(.*)/d'
42b544f3c8SBram Moolenaar    /^\d*\s*endfunction\>/,$d
43b544f3c8SBram Moolenaar    %s/^\d*//e
44b544f3c8SBram Moolenaar    %s/return/finish/e
45b544f3c8SBram Moolenaar    %s/\<a:\(\h\w*\)/g:\1/ge
46b544f3c8SBram Moolenaar    normal gg0
47b544f3c8SBram Moolenaar    let cnt = 0
48b544f3c8SBram Moolenaar    while search('\<call\s*\%(\u\|s:\)\w*\s*(.*)', 'W') > 0
49b544f3c8SBram Moolenaar	let cnt = cnt + 1
50b544f3c8SBram Moolenaar	s/\<call\s*\%(\u\|s:\)\w*\s*(.*)/\='source ' . a:{cnt}/
51b544f3c8SBram Moolenaar    endwhile
52b544f3c8SBram Moolenaar    g/^\s*$/d
53b544f3c8SBram Moolenaar    write
54b544f3c8SBram Moolenaar    bwipeout
55b544f3c8SBram Moolenaar    return script
561e115360SBram Moolenaarendfunc
57b544f3c8SBram Moolenaar
58b544f3c8SBram Moolenaar" ExecAsScript - Source a temporary script made from a function.	    {{{2
59b544f3c8SBram Moolenaar"
60b544f3c8SBram Moolenaar" Make a temporary script file from the function a:funcname, ":source" it, and
61b544f3c8SBram Moolenaar" delete it afterwards.  However, if an exception is thrown the file may remain,
62b544f3c8SBram Moolenaar" the caller should call DeleteTheScript() afterwards.
63b544f3c8SBram Moolenaarlet s:script_name = ''
64b544f3c8SBram Moolenaarfunction! ExecAsScript(funcname)
65b544f3c8SBram Moolenaar    " Make a script from the function passed as argument.
66b544f3c8SBram Moolenaar    let s:script_name = MakeScript(a:funcname)
67b544f3c8SBram Moolenaar
68b544f3c8SBram Moolenaar    " Source and delete the script.
69b544f3c8SBram Moolenaar    exec "source" s:script_name
70b544f3c8SBram Moolenaar    call delete(s:script_name)
71b544f3c8SBram Moolenaar    let s:script_name = ''
72b544f3c8SBram Moolenaarendfunction
73b544f3c8SBram Moolenaar
74b544f3c8SBram Moolenaarfunction! DeleteTheScript()
75b544f3c8SBram Moolenaar    if s:script_name
76b544f3c8SBram Moolenaar	call delete(s:script_name)
77b544f3c8SBram Moolenaar	let s:script_name = ''
78b544f3c8SBram Moolenaar    endif
79b544f3c8SBram Moolenaarendfunc
80b544f3c8SBram Moolenaar
81b544f3c8SBram Moolenaarcom! -nargs=1 -bar ExecAsScript call ExecAsScript(<f-args>)
82b544f3c8SBram Moolenaar
83b544f3c8SBram Moolenaar
84b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
85b544f3c8SBram Moolenaar" Test 1:   :endwhile in function					    {{{1
86b544f3c8SBram Moolenaar"
87b544f3c8SBram Moolenaar"	    Detect if a broken loop is (incorrectly) reactivated by the
88b544f3c8SBram Moolenaar"	    :endwhile.  Use a :return to prevent an endless loop, and make
89b544f3c8SBram Moolenaar"	    this test first to get a meaningful result on an error before other
90b544f3c8SBram Moolenaar"	    tests will hang.
91b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
92b544f3c8SBram Moolenaar
93b544f3c8SBram Moolenaarfunction! T1_F()
94b544f3c8SBram Moolenaar    Xpath 'a'
95b544f3c8SBram Moolenaar    let first = 1
96b544f3c8SBram Moolenaar    while 1
97b544f3c8SBram Moolenaar	Xpath 'b'
98b544f3c8SBram Moolenaar	if first
99b544f3c8SBram Moolenaar	    Xpath 'c'
100b544f3c8SBram Moolenaar	    let first = 0
101b544f3c8SBram Moolenaar	    break
102b544f3c8SBram Moolenaar	else
103b544f3c8SBram Moolenaar	    Xpath 'd'
104b544f3c8SBram Moolenaar	    return
105b544f3c8SBram Moolenaar	endif
106b544f3c8SBram Moolenaar    endwhile
107b544f3c8SBram Moolenaarendfunction
108b544f3c8SBram Moolenaar
109b544f3c8SBram Moolenaarfunction! T1_G()
110b544f3c8SBram Moolenaar    Xpath 'h'
111b544f3c8SBram Moolenaar    let first = 1
112b544f3c8SBram Moolenaar    while 1
113b544f3c8SBram Moolenaar	Xpath 'i'
114b544f3c8SBram Moolenaar	if first
115b544f3c8SBram Moolenaar	    Xpath 'j'
116b544f3c8SBram Moolenaar	    let first = 0
117b544f3c8SBram Moolenaar	    break
118b544f3c8SBram Moolenaar	else
119b544f3c8SBram Moolenaar	    Xpath 'k'
120b544f3c8SBram Moolenaar	    return
121b544f3c8SBram Moolenaar	endif
122b544f3c8SBram Moolenaar	if 1	" unmatched :if
123b544f3c8SBram Moolenaar    endwhile
124b544f3c8SBram Moolenaarendfunction
125b544f3c8SBram Moolenaar
126b544f3c8SBram Moolenaarfunc Test_endwhile_function()
127b544f3c8SBram Moolenaar  XpathINIT
128b544f3c8SBram Moolenaar  call T1_F()
129b544f3c8SBram Moolenaar  Xpath 'F'
130b544f3c8SBram Moolenaar
131b544f3c8SBram Moolenaar  try
132b544f3c8SBram Moolenaar    call T1_G()
133b544f3c8SBram Moolenaar  catch
134b544f3c8SBram Moolenaar    " Catch missing :endif
135b544f3c8SBram Moolenaar    call assert_true(v:exception =~ 'E171')
136b544f3c8SBram Moolenaar    Xpath 'x'
137b544f3c8SBram Moolenaar  endtry
138b544f3c8SBram Moolenaar  Xpath 'G'
139b544f3c8SBram Moolenaar
140b544f3c8SBram Moolenaar  call assert_equal('abcFhijxG', g:Xpath)
141b544f3c8SBram Moolenaarendfunc
142b544f3c8SBram Moolenaar
143b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
144b544f3c8SBram Moolenaar" Test 2:   :endwhile in script						    {{{1
145b544f3c8SBram Moolenaar"
146b544f3c8SBram Moolenaar"	    Detect if a broken loop is (incorrectly) reactivated by the
147b544f3c8SBram Moolenaar"	    :endwhile.  Use a :finish to prevent an endless loop, and place
148b544f3c8SBram Moolenaar"	    this test before others that might hang to get a meaningful result
149b544f3c8SBram Moolenaar"	    on an error.
150b544f3c8SBram Moolenaar"
151b544f3c8SBram Moolenaar"	    This test executes the bodies of the functions T1_F and T1_G from
152b544f3c8SBram Moolenaar"	    the previous test as script files (:return replaced by :finish).
153b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
154b544f3c8SBram Moolenaar
155b544f3c8SBram Moolenaarfunc Test_endwhile_script()
156b544f3c8SBram Moolenaar  XpathINIT
157b544f3c8SBram Moolenaar  ExecAsScript T1_F
158b544f3c8SBram Moolenaar  Xpath 'F'
159b544f3c8SBram Moolenaar  call DeleteTheScript()
160b544f3c8SBram Moolenaar
161b544f3c8SBram Moolenaar  try
162b544f3c8SBram Moolenaar    ExecAsScript T1_G
163b544f3c8SBram Moolenaar  catch
164b544f3c8SBram Moolenaar    " Catch missing :endif
165b544f3c8SBram Moolenaar    call assert_true(v:exception =~ 'E171')
166b544f3c8SBram Moolenaar    Xpath 'x'
167b544f3c8SBram Moolenaar  endtry
168b544f3c8SBram Moolenaar  Xpath 'G'
169b544f3c8SBram Moolenaar  call DeleteTheScript()
170b544f3c8SBram Moolenaar
171b544f3c8SBram Moolenaar  call assert_equal('abcFhijxG', g:Xpath)
172b544f3c8SBram Moolenaarendfunc
173b544f3c8SBram Moolenaar
174b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
175b544f3c8SBram Moolenaar" Test 3:   :if, :elseif, :while, :continue, :break			    {{{1
176b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
177b544f3c8SBram Moolenaar
178b544f3c8SBram Moolenaarfunction Test_if_while()
179b544f3c8SBram Moolenaar    XpathINIT
180b544f3c8SBram Moolenaar    if 1
181b544f3c8SBram Moolenaar	Xpath 'a'
182b544f3c8SBram Moolenaar	let loops = 3
183b544f3c8SBram Moolenaar	while loops > -1	    " main loop: loops == 3, 2, 1 (which breaks)
184b544f3c8SBram Moolenaar	    if loops <= 0
185b544f3c8SBram Moolenaar		let break_err = 1
186b544f3c8SBram Moolenaar		let loops = -1
187b544f3c8SBram Moolenaar	    else
188b544f3c8SBram Moolenaar		Xpath 'b' . loops
189b544f3c8SBram Moolenaar	    endif
190b544f3c8SBram Moolenaar	    if (loops == 2)
191b544f3c8SBram Moolenaar		while loops == 2 " dummy loop
192b544f3c8SBram Moolenaar		    Xpath 'c' . loops
193b544f3c8SBram Moolenaar		    let loops = loops - 1
194b544f3c8SBram Moolenaar		    continue    " stop dummy loop
195b544f3c8SBram Moolenaar		    Xpath 'd' . loops
196b544f3c8SBram Moolenaar		endwhile
197b544f3c8SBram Moolenaar		continue	    " continue main loop
198b544f3c8SBram Moolenaar		Xpath 'e' . loops
199b544f3c8SBram Moolenaar	    elseif (loops == 1)
200b544f3c8SBram Moolenaar		let p = 1
201b544f3c8SBram Moolenaar		while p	    " dummy loop
202b544f3c8SBram Moolenaar		    Xpath 'f' . loops
203b544f3c8SBram Moolenaar		    let p = 0
204b544f3c8SBram Moolenaar		    break	    " break dummy loop
205b544f3c8SBram Moolenaar		    Xpath 'g' . loops
206b544f3c8SBram Moolenaar		endwhile
207b544f3c8SBram Moolenaar		Xpath 'h' . loops
208b544f3c8SBram Moolenaar		unlet p
209b544f3c8SBram Moolenaar		break	    " break main loop
210b544f3c8SBram Moolenaar		Xpath 'i' . loops
211b544f3c8SBram Moolenaar	    endif
212b544f3c8SBram Moolenaar	    if (loops > 0)
213b544f3c8SBram Moolenaar		Xpath 'j' . loops
214b544f3c8SBram Moolenaar	    endif
215b544f3c8SBram Moolenaar	    while loops == 3    " dummy loop
216b544f3c8SBram Moolenaar		let loops = loops - 1
217b544f3c8SBram Moolenaar	    endwhile	    " end dummy loop
218b544f3c8SBram Moolenaar	endwhile		    " end main loop
219b544f3c8SBram Moolenaar	Xpath 'k'
220b544f3c8SBram Moolenaar    else
221b544f3c8SBram Moolenaar	Xpath 'l'
222b544f3c8SBram Moolenaar    endif
223b544f3c8SBram Moolenaar    Xpath 'm'
224b544f3c8SBram Moolenaar    if exists("break_err")
225b544f3c8SBram Moolenaar	Xpath 'm'
226b544f3c8SBram Moolenaar	unlet break_err
227b544f3c8SBram Moolenaar    endif
228b544f3c8SBram Moolenaar
229b544f3c8SBram Moolenaar    unlet loops
230b544f3c8SBram Moolenaar
231b544f3c8SBram Moolenaar    call assert_equal('ab3j3b2c2b1f1h1km', g:Xpath)
232b544f3c8SBram Moolenaarendfunc
233b544f3c8SBram Moolenaar
234b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
235b544f3c8SBram Moolenaar" Test 4:   :return							    {{{1
236b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
237b544f3c8SBram Moolenaar
238b544f3c8SBram Moolenaarfunction! T4_F()
239b544f3c8SBram Moolenaar    if 1
240b544f3c8SBram Moolenaar	Xpath 'a'
241b544f3c8SBram Moolenaar	let loops = 3
242b544f3c8SBram Moolenaar	while loops > 0				"    3:  2:     1:
243b544f3c8SBram Moolenaar	    Xpath 'b' . loops
244b544f3c8SBram Moolenaar	    if (loops == 2)
245b544f3c8SBram Moolenaar		Xpath 'c' . loops
246b544f3c8SBram Moolenaar		return
247b544f3c8SBram Moolenaar		Xpath 'd' . loops
248b544f3c8SBram Moolenaar	    endif
249b544f3c8SBram Moolenaar	    Xpath 'e' . loops
250b544f3c8SBram Moolenaar	    let loops = loops - 1
251b544f3c8SBram Moolenaar	endwhile
252b544f3c8SBram Moolenaar	Xpath 'f'
253b544f3c8SBram Moolenaar    else
254b544f3c8SBram Moolenaar	Xpath 'g'
255b544f3c8SBram Moolenaar    endif
256b544f3c8SBram Moolenaarendfunction
257b544f3c8SBram Moolenaar
258b544f3c8SBram Moolenaarfunction Test_return()
259b544f3c8SBram Moolenaar    XpathINIT
260b544f3c8SBram Moolenaar    call T4_F()
261b544f3c8SBram Moolenaar    Xpath '4'
262b544f3c8SBram Moolenaar
263b544f3c8SBram Moolenaar    call assert_equal('ab3e3b2c24', g:Xpath)
264b544f3c8SBram Moolenaarendfunction
265b544f3c8SBram Moolenaar
266b544f3c8SBram Moolenaar
267b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
268b544f3c8SBram Moolenaar" Test 5:   :finish							    {{{1
269b544f3c8SBram Moolenaar"
270b544f3c8SBram Moolenaar"	    This test executes the body of the function T4_F from the previous
271b544f3c8SBram Moolenaar"	    test as a script file (:return replaced by :finish).
272b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
273b544f3c8SBram Moolenaar
274b544f3c8SBram Moolenaarfunction Test_finish()
275b544f3c8SBram Moolenaar    XpathINIT
276b544f3c8SBram Moolenaar    ExecAsScript T4_F
277b544f3c8SBram Moolenaar    Xpath '5'
278b544f3c8SBram Moolenaar    call DeleteTheScript()
279b544f3c8SBram Moolenaar
280b544f3c8SBram Moolenaar    call assert_equal('ab3e3b2c25', g:Xpath)
281b544f3c8SBram Moolenaarendfunction
282b544f3c8SBram Moolenaar
283b544f3c8SBram Moolenaar
284b544f3c8SBram Moolenaar
285b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
286b544f3c8SBram Moolenaar" Test 6:   Defining functions in :while loops				    {{{1
287b544f3c8SBram Moolenaar"
288b544f3c8SBram Moolenaar"	     Functions can be defined inside other functions.  An inner function
289b544f3c8SBram Moolenaar"	     gets defined when the outer function is executed.  Functions may
290b544f3c8SBram Moolenaar"	     also be defined inside while loops.  Expressions in braces for
291b544f3c8SBram Moolenaar"	     defining the function name are allowed.
292b544f3c8SBram Moolenaar"
293b544f3c8SBram Moolenaar"	     The functions are defined when sourcing the script, only the
294b544f3c8SBram Moolenaar"	     resulting path is checked in the test function.
295b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
296b544f3c8SBram Moolenaar
297b544f3c8SBram MoolenaarXpathINIT
298b544f3c8SBram Moolenaar
299b544f3c8SBram Moolenaar" The command CALL collects the argument of all its invocations in "calls"
300b544f3c8SBram Moolenaar" when used from a function (that is, when the global variable "calls" needs
301b544f3c8SBram Moolenaar" the "g:" prefix).  This is to check that the function code is skipped when
302b544f3c8SBram Moolenaar" the function is defined.  For inner functions, do so only if the outer
303b544f3c8SBram Moolenaar" function is not being executed.
304b544f3c8SBram Moolenaar"
305b544f3c8SBram Moolenaarlet calls = ""
306b544f3c8SBram Moolenaarcom! -nargs=1 CALL
307b544f3c8SBram Moolenaar	    \ if !exists("calls") && !exists("outer") |
308b544f3c8SBram Moolenaar	    \ let g:calls = g:calls . <args> |
309b544f3c8SBram Moolenaar	    \ endif
310b544f3c8SBram Moolenaar
311b544f3c8SBram Moolenaarlet i = 0
312b544f3c8SBram Moolenaarwhile i < 3
313b544f3c8SBram Moolenaar    let i = i + 1
314b544f3c8SBram Moolenaar    if i == 1
315b544f3c8SBram Moolenaar	Xpath 'a'
316b544f3c8SBram Moolenaar	function! F1(arg)
317b544f3c8SBram Moolenaar	    CALL a:arg
318b544f3c8SBram Moolenaar	    let outer = 1
319b544f3c8SBram Moolenaar
320b544f3c8SBram Moolenaar	    let j = 0
321b544f3c8SBram Moolenaar	    while j < 1
322b544f3c8SBram Moolenaar		Xpath 'b'
323b544f3c8SBram Moolenaar		let j = j + 1
324b544f3c8SBram Moolenaar		function! G1(arg)
325b544f3c8SBram Moolenaar		    CALL a:arg
326b544f3c8SBram Moolenaar		endfunction
327b544f3c8SBram Moolenaar		Xpath 'c'
328b544f3c8SBram Moolenaar	    endwhile
329b544f3c8SBram Moolenaar	endfunction
330b544f3c8SBram Moolenaar	Xpath 'd'
331b544f3c8SBram Moolenaar
332b544f3c8SBram Moolenaar	continue
333b544f3c8SBram Moolenaar    endif
334b544f3c8SBram Moolenaar
335b544f3c8SBram Moolenaar    Xpath 'e' . i
336b544f3c8SBram Moolenaar    function! F{i}(i, arg)
337b544f3c8SBram Moolenaar	CALL a:arg
338b544f3c8SBram Moolenaar	let outer = 1
339b544f3c8SBram Moolenaar
340b544f3c8SBram Moolenaar	if a:i == 3
341b544f3c8SBram Moolenaar	    Xpath 'f'
342b544f3c8SBram Moolenaar	endif
343b544f3c8SBram Moolenaar	let k = 0
344b544f3c8SBram Moolenaar	while k < 3
345b544f3c8SBram Moolenaar	    Xpath 'g' . k
346b544f3c8SBram Moolenaar	    let k = k + 1
347b544f3c8SBram Moolenaar	    function! G{a:i}{k}(arg)
348b544f3c8SBram Moolenaar		CALL a:arg
349b544f3c8SBram Moolenaar	    endfunction
350b544f3c8SBram Moolenaar	    Xpath 'h' . k
351b544f3c8SBram Moolenaar	endwhile
352b544f3c8SBram Moolenaar    endfunction
353b544f3c8SBram Moolenaar    Xpath 'i'
354b544f3c8SBram Moolenaar
355b544f3c8SBram Moolenaarendwhile
356b544f3c8SBram Moolenaar
357b544f3c8SBram Moolenaarif exists("*G1")
358b544f3c8SBram Moolenaar    Xpath 'j'
359b544f3c8SBram Moolenaarendif
360b544f3c8SBram Moolenaarif exists("*F1")
361b544f3c8SBram Moolenaar    call F1("F1")
362b544f3c8SBram Moolenaar    if exists("*G1")
363b544f3c8SBram Moolenaar       call G1("G1")
364b544f3c8SBram Moolenaar    endif
365b544f3c8SBram Moolenaarendif
366b544f3c8SBram Moolenaar
367b544f3c8SBram Moolenaarif exists("G21") || exists("G22") || exists("G23")
368b544f3c8SBram Moolenaar    Xpath 'k'
369b544f3c8SBram Moolenaarendif
370b544f3c8SBram Moolenaarif exists("*F2")
371b544f3c8SBram Moolenaar    call F2(2, "F2")
372b544f3c8SBram Moolenaar    if exists("*G21")
373b544f3c8SBram Moolenaar       call G21("G21")
374b544f3c8SBram Moolenaar    endif
375b544f3c8SBram Moolenaar    if exists("*G22")
376b544f3c8SBram Moolenaar       call G22("G22")
377b544f3c8SBram Moolenaar    endif
378b544f3c8SBram Moolenaar    if exists("*G23")
379b544f3c8SBram Moolenaar       call G23("G23")
380b544f3c8SBram Moolenaar    endif
381b544f3c8SBram Moolenaarendif
382b544f3c8SBram Moolenaar
383b544f3c8SBram Moolenaarif exists("G31") || exists("G32") || exists("G33")
384b544f3c8SBram Moolenaar    Xpath 'l'
385b544f3c8SBram Moolenaarendif
386b544f3c8SBram Moolenaarif exists("*F3")
387b544f3c8SBram Moolenaar    call F3(3, "F3")
388b544f3c8SBram Moolenaar    if exists("*G31")
389b544f3c8SBram Moolenaar       call G31("G31")
390b544f3c8SBram Moolenaar    endif
391b544f3c8SBram Moolenaar    if exists("*G32")
392b544f3c8SBram Moolenaar       call G32("G32")
393b544f3c8SBram Moolenaar    endif
394b544f3c8SBram Moolenaar    if exists("*G33")
395b544f3c8SBram Moolenaar       call G33("G33")
396b544f3c8SBram Moolenaar    endif
397b544f3c8SBram Moolenaarendif
398b544f3c8SBram Moolenaar
399b544f3c8SBram MoolenaarXpath 'm'
400b544f3c8SBram Moolenaar
401b544f3c8SBram Moolenaarlet g:test6_result = g:Xpath
402b544f3c8SBram Moolenaarlet g:test6_calls = calls
403b544f3c8SBram Moolenaar
404b544f3c8SBram Moolenaarunlet calls
405b544f3c8SBram Moolenaardelfunction F1
406b544f3c8SBram Moolenaardelfunction G1
407b544f3c8SBram Moolenaardelfunction F2
408b544f3c8SBram Moolenaardelfunction G21
409b544f3c8SBram Moolenaardelfunction G22
410b544f3c8SBram Moolenaardelfunction G23
411b544f3c8SBram Moolenaardelfunction G31
412b544f3c8SBram Moolenaardelfunction G32
413b544f3c8SBram Moolenaardelfunction G33
414b544f3c8SBram Moolenaar
415b544f3c8SBram Moolenaarfunction Test_defining_functions()
416b544f3c8SBram Moolenaar    call assert_equal('ade2ie3ibcg0h1g1h2g2h3fg0h1g1h2g2h3m', g:test6_result)
417b544f3c8SBram Moolenaar    call assert_equal('F1G1F2G21G22G23F3G31G32G33', g:test6_calls)
418b544f3c8SBram Moolenaarendfunc
419b544f3c8SBram Moolenaar
420b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
421b544f3c8SBram Moolenaar" Test 7:   Continuing on errors outside functions			    {{{1
422b544f3c8SBram Moolenaar"
423b544f3c8SBram Moolenaar"	    On an error outside a function, the script processing continues
424b544f3c8SBram Moolenaar"	    at the line following the outermost :endif or :endwhile.  When not
425b544f3c8SBram Moolenaar"	    inside an :if or :while, the script processing continues at the next
426b544f3c8SBram Moolenaar"	    line.
427b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
428b544f3c8SBram Moolenaar
429b544f3c8SBram MoolenaarXpathINIT
430b544f3c8SBram Moolenaar
431b544f3c8SBram Moolenaarif 1
432b544f3c8SBram Moolenaar    Xpath 'a'
433b544f3c8SBram Moolenaar    while 1
434b544f3c8SBram Moolenaar	Xpath 'b'
435b544f3c8SBram Moolenaar	asdf
436b544f3c8SBram Moolenaar	Xpath 'c'
437b544f3c8SBram Moolenaar	break
438b544f3c8SBram Moolenaar    endwhile | Xpath 'd'
439b544f3c8SBram Moolenaar    Xpath 'e'
440b544f3c8SBram Moolenaarendif | Xpath 'f'
441b544f3c8SBram MoolenaarXpath 'g'
442b544f3c8SBram Moolenaar
443b544f3c8SBram Moolenaarwhile 1
444b544f3c8SBram Moolenaar    Xpath 'h'
445b544f3c8SBram Moolenaar    if 1
446b544f3c8SBram Moolenaar	Xpath 'i'
447b544f3c8SBram Moolenaar	asdf
448b544f3c8SBram Moolenaar	Xpath 'j'
449b544f3c8SBram Moolenaar    endif | Xpath 'k'
450b544f3c8SBram Moolenaar    Xpath 'l'
451b544f3c8SBram Moolenaar    break
452b544f3c8SBram Moolenaarendwhile | Xpath 'm'
453b544f3c8SBram MoolenaarXpath 'n'
454b544f3c8SBram Moolenaar
455b544f3c8SBram Moolenaarasdf
456b544f3c8SBram MoolenaarXpath 'o'
457b544f3c8SBram Moolenaar
458b544f3c8SBram Moolenaarasdf | Xpath 'p'
459b544f3c8SBram MoolenaarXpath 'q'
460b544f3c8SBram Moolenaar
461b544f3c8SBram Moolenaarlet g:test7_result = g:Xpath
462b544f3c8SBram Moolenaar
463b544f3c8SBram Moolenaarfunc Test_error_in_script()
464b544f3c8SBram Moolenaar    call assert_equal('abghinoq', g:test7_result)
465b544f3c8SBram Moolenaarendfunc
466b544f3c8SBram Moolenaar
467b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
468b544f3c8SBram Moolenaar" Test 8:   Aborting and continuing on errors inside functions		    {{{1
469b544f3c8SBram Moolenaar"
470b544f3c8SBram Moolenaar"	    On an error inside a function without the "abort" attribute, the
471b544f3c8SBram Moolenaar"	    script processing continues at the next line (unless the error was
472b544f3c8SBram Moolenaar"	    in a :return command).  On an error inside a function with the
473b544f3c8SBram Moolenaar"	    "abort" attribute, the function is aborted and the script processing
474b544f3c8SBram Moolenaar"	    continues after the function call; the value -1 is returned then.
475b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
476b544f3c8SBram Moolenaar
477b544f3c8SBram MoolenaarXpathINIT
478b544f3c8SBram Moolenaar
479b544f3c8SBram Moolenaarfunction! T8_F()
480b544f3c8SBram Moolenaar    if 1
481b544f3c8SBram Moolenaar	Xpath 'a'
482b544f3c8SBram Moolenaar	while 1
483b544f3c8SBram Moolenaar	    Xpath 'b'
484b544f3c8SBram Moolenaar	    asdf
485b544f3c8SBram Moolenaar	    Xpath 'c'
486b544f3c8SBram Moolenaar	    asdf | Xpath 'd'
487b544f3c8SBram Moolenaar	    Xpath 'e'
488b544f3c8SBram Moolenaar	    break
489b544f3c8SBram Moolenaar	endwhile
490b544f3c8SBram Moolenaar	Xpath 'f'
491b544f3c8SBram Moolenaar    endif | Xpath 'g'
492b544f3c8SBram Moolenaar    Xpath 'h'
493b544f3c8SBram Moolenaar
494b544f3c8SBram Moolenaar    while 1
495b544f3c8SBram Moolenaar	Xpath 'i'
496b544f3c8SBram Moolenaar	if 1
497b544f3c8SBram Moolenaar	    Xpath 'j'
498b544f3c8SBram Moolenaar	    asdf
499b544f3c8SBram Moolenaar	    Xpath 'k'
500b544f3c8SBram Moolenaar	    asdf | Xpath 'l'
501b544f3c8SBram Moolenaar	    Xpath 'm'
502b544f3c8SBram Moolenaar	endif
503b544f3c8SBram Moolenaar	Xpath 'n'
504b544f3c8SBram Moolenaar	break
505b544f3c8SBram Moolenaar    endwhile | Xpath 'o'
506b544f3c8SBram Moolenaar    Xpath 'p'
507b544f3c8SBram Moolenaar
508b544f3c8SBram Moolenaar    return novar		" returns (default return value 0)
509b544f3c8SBram Moolenaar    Xpath 'q'
510b544f3c8SBram Moolenaar    return 1			" not reached
511b544f3c8SBram Moolenaarendfunction
512b544f3c8SBram Moolenaar
513b544f3c8SBram Moolenaarfunction! T8_G() abort
514b544f3c8SBram Moolenaar    if 1
515b544f3c8SBram Moolenaar	Xpath 'r'
516b544f3c8SBram Moolenaar	while 1
517b544f3c8SBram Moolenaar	    Xpath 's'
518b544f3c8SBram Moolenaar	    asdf		" returns -1
519b544f3c8SBram Moolenaar	    Xpath 't'
520b544f3c8SBram Moolenaar	    break
521b544f3c8SBram Moolenaar	endwhile
522b544f3c8SBram Moolenaar	Xpath 'v'
523b544f3c8SBram Moolenaar    endif | Xpath 'w'
524b544f3c8SBram Moolenaar    Xpath 'x'
525b544f3c8SBram Moolenaar
526b544f3c8SBram Moolenaar    return -4			" not reached
527b544f3c8SBram Moolenaarendfunction
528b544f3c8SBram Moolenaar
529b544f3c8SBram Moolenaarfunction! T8_H() abort
530b544f3c8SBram Moolenaar    while 1
531b544f3c8SBram Moolenaar	Xpath 'A'
532b544f3c8SBram Moolenaar	if 1
533b544f3c8SBram Moolenaar	    Xpath 'B'
534b544f3c8SBram Moolenaar	    asdf		" returns -1
535b544f3c8SBram Moolenaar	    Xpath 'C'
536b544f3c8SBram Moolenaar	endif
537b544f3c8SBram Moolenaar	Xpath 'D'
538b544f3c8SBram Moolenaar	break
539b544f3c8SBram Moolenaar    endwhile | Xpath 'E'
540b544f3c8SBram Moolenaar    Xpath 'F'
541b544f3c8SBram Moolenaar
542b544f3c8SBram Moolenaar    return -4			" not reached
543b544f3c8SBram Moolenaarendfunction
544b544f3c8SBram Moolenaar
545b544f3c8SBram Moolenaar" Aborted functions (T8_G and T8_H) return -1.
546b544f3c8SBram Moolenaarlet g:test8_sum = (T8_F() + 1) - 4 * T8_G() - 8 * T8_H()
547b544f3c8SBram MoolenaarXpath 'X'
548b544f3c8SBram Moolenaarlet g:test8_result = g:Xpath
549b544f3c8SBram Moolenaar
550b544f3c8SBram Moolenaarfunc Test_error_in_function()
551b544f3c8SBram Moolenaar    call assert_equal(13, g:test8_sum)
552b544f3c8SBram Moolenaar    call assert_equal('abcefghijkmnoprsABX', g:test8_result)
553b544f3c8SBram Moolenaar
554b544f3c8SBram Moolenaar    delfunction T8_F
555b544f3c8SBram Moolenaar    delfunction T8_G
556b544f3c8SBram Moolenaar    delfunction T8_H
557b544f3c8SBram Moolenaarendfunc
558b544f3c8SBram Moolenaar
559b544f3c8SBram Moolenaar
560b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
561b544f3c8SBram Moolenaar" Test 9:   Continuing after aborted functions				    {{{1
562b544f3c8SBram Moolenaar"
563b544f3c8SBram Moolenaar"	    When a function with the "abort" attribute is aborted due to an
564b544f3c8SBram Moolenaar"	    error, the next function back in the call hierarchy without an
565b544f3c8SBram Moolenaar"	    "abort" attribute continues; the value -1 is returned then.
566b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
567b544f3c8SBram Moolenaar
568b544f3c8SBram MoolenaarXpathINIT
569b544f3c8SBram Moolenaar
570b544f3c8SBram Moolenaarfunction! F() abort
571b544f3c8SBram Moolenaar    Xpath 'a'
572b544f3c8SBram Moolenaar    let result = G()	" not aborted
573b544f3c8SBram Moolenaar    Xpath 'b'
574b544f3c8SBram Moolenaar    if result != 2
575b544f3c8SBram Moolenaar	Xpath 'c'
576b544f3c8SBram Moolenaar    endif
577b544f3c8SBram Moolenaar    return 1
578b544f3c8SBram Moolenaarendfunction
579b544f3c8SBram Moolenaar
580b544f3c8SBram Moolenaarfunction! G()		" no abort attribute
581b544f3c8SBram Moolenaar    Xpath 'd'
582b544f3c8SBram Moolenaar    if H() != -1	" aborted
583b544f3c8SBram Moolenaar	Xpath 'e'
584b544f3c8SBram Moolenaar    endif
585b544f3c8SBram Moolenaar    Xpath 'f'
586b544f3c8SBram Moolenaar    return 2
587b544f3c8SBram Moolenaarendfunction
588b544f3c8SBram Moolenaar
589b544f3c8SBram Moolenaarfunction! H() abort
590b544f3c8SBram Moolenaar    Xpath 'g'
591b544f3c8SBram Moolenaar    call I()		" aborted
592b544f3c8SBram Moolenaar    Xpath 'h'
593b544f3c8SBram Moolenaar    return 4
594b544f3c8SBram Moolenaarendfunction
595b544f3c8SBram Moolenaar
596b544f3c8SBram Moolenaarfunction! I() abort
597b544f3c8SBram Moolenaar    Xpath 'i'
598b544f3c8SBram Moolenaar    asdf		" error
599b544f3c8SBram Moolenaar    Xpath 'j'
600b544f3c8SBram Moolenaar    return 8
601b544f3c8SBram Moolenaarendfunction
602b544f3c8SBram Moolenaar
603b544f3c8SBram Moolenaarif F() != 1
604b544f3c8SBram Moolenaar    Xpath 'k'
605b544f3c8SBram Moolenaarendif
606b544f3c8SBram Moolenaar
607b544f3c8SBram Moolenaarlet g:test9_result = g:Xpath
608b544f3c8SBram Moolenaar
609b544f3c8SBram Moolenaardelfunction F
610b544f3c8SBram Moolenaardelfunction G
611b544f3c8SBram Moolenaardelfunction H
612b544f3c8SBram Moolenaardelfunction I
613b544f3c8SBram Moolenaar
614b544f3c8SBram Moolenaarfunc Test_func_abort()
615b544f3c8SBram Moolenaar    call assert_equal('adgifb', g:test9_result)
616b544f3c8SBram Moolenaarendfunc
617b544f3c8SBram Moolenaar
618b544f3c8SBram Moolenaar
619b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
620b544f3c8SBram Moolenaar" Test 10:  :if, :elseif, :while argument parsing			    {{{1
621b544f3c8SBram Moolenaar"
622b544f3c8SBram Moolenaar"	    A '"' or '|' in an argument expression must not be mixed up with
623b544f3c8SBram Moolenaar"	    a comment or a next command after a bar.  Parsing errors should
624b544f3c8SBram Moolenaar"	    be recognized.
625b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
626b544f3c8SBram Moolenaar
627b544f3c8SBram MoolenaarXpathINIT
628b544f3c8SBram Moolenaar
629b544f3c8SBram Moolenaarfunction! MSG(enr, emsg)
630b544f3c8SBram Moolenaar    let english = v:lang == "C" || v:lang =~ '^[Ee]n'
631b544f3c8SBram Moolenaar    if a:enr == ""
632b544f3c8SBram Moolenaar	Xout "TODO: Add message number for:" a:emsg
633b544f3c8SBram Moolenaar	let v:errmsg = ":" . v:errmsg
634b544f3c8SBram Moolenaar    endif
635b544f3c8SBram Moolenaar    let match = 1
636b544f3c8SBram Moolenaar    if v:errmsg !~ '^'.a:enr.':' || (english && v:errmsg !~ a:emsg)
637b544f3c8SBram Moolenaar	let match = 0
638b544f3c8SBram Moolenaar	if v:errmsg == ""
639b544f3c8SBram Moolenaar	    Xout "Message missing."
640b544f3c8SBram Moolenaar	else
641a4208966SBram Moolenaar	    let v:errmsg = v:errmsg->escape('"')
642b544f3c8SBram Moolenaar	    Xout "Unexpected message:" v:errmsg
643b544f3c8SBram Moolenaar	endif
644b544f3c8SBram Moolenaar    endif
645b544f3c8SBram Moolenaar    return match
6461e115360SBram Moolenaarendfunc
647b544f3c8SBram Moolenaar
648b544f3c8SBram Moolenaarif 1 || strlen("\"") | Xpath 'a'
649b544f3c8SBram Moolenaar    Xpath 'b'
650b544f3c8SBram Moolenaarendif
651b544f3c8SBram MoolenaarXpath 'c'
652b544f3c8SBram Moolenaar
653b544f3c8SBram Moolenaarif 0
654b544f3c8SBram Moolenaarelseif 1 || strlen("\"") | Xpath 'd'
655b544f3c8SBram Moolenaar    Xpath 'e'
656b544f3c8SBram Moolenaarendif
657b544f3c8SBram MoolenaarXpath 'f'
658b544f3c8SBram Moolenaar
659b544f3c8SBram Moolenaarwhile 1 || strlen("\"") | Xpath 'g'
660b544f3c8SBram Moolenaar    Xpath 'h'
661b544f3c8SBram Moolenaar    break
662b544f3c8SBram Moolenaarendwhile
663b544f3c8SBram MoolenaarXpath 'i'
664b544f3c8SBram Moolenaar
665b544f3c8SBram Moolenaarlet v:errmsg = ""
666b544f3c8SBram Moolenaarif 1 ||| strlen("\"") | Xpath 'j'
667b544f3c8SBram Moolenaar    Xpath 'k'
668b544f3c8SBram Moolenaarendif
669b544f3c8SBram MoolenaarXpath 'l'
670b544f3c8SBram Moolenaarif !MSG('E15', "Invalid expression")
671b544f3c8SBram Moolenaar    Xpath 'm'
672b544f3c8SBram Moolenaarendif
673b544f3c8SBram Moolenaar
674b544f3c8SBram Moolenaarlet v:errmsg = ""
675b544f3c8SBram Moolenaarif 0
676b544f3c8SBram Moolenaarelseif 1 ||| strlen("\"") | Xpath 'n'
677b544f3c8SBram Moolenaar    Xpath 'o'
678b544f3c8SBram Moolenaarendif
679b544f3c8SBram MoolenaarXpath 'p'
680b544f3c8SBram Moolenaarif !MSG('E15', "Invalid expression")
681b544f3c8SBram Moolenaar    Xpath 'q'
682b544f3c8SBram Moolenaarendif
683b544f3c8SBram Moolenaar
684b544f3c8SBram Moolenaarlet v:errmsg = ""
685b544f3c8SBram Moolenaarwhile 1 ||| strlen("\"") | Xpath 'r'
686b544f3c8SBram Moolenaar    Xpath 's'
687b544f3c8SBram Moolenaar    break
688b544f3c8SBram Moolenaarendwhile
689b544f3c8SBram MoolenaarXpath 't'
690b544f3c8SBram Moolenaarif !MSG('E15', "Invalid expression")
691b544f3c8SBram Moolenaar    Xpath 'u'
692b544f3c8SBram Moolenaarendif
693b544f3c8SBram Moolenaar
694b544f3c8SBram Moolenaarlet g:test10_result = g:Xpath
695b544f3c8SBram Moolenaardelfunction MSG
696b544f3c8SBram Moolenaar
697b544f3c8SBram Moolenaarfunc Test_expr_parsing()
698b544f3c8SBram Moolenaar    call assert_equal('abcdefghilpt', g:test10_result)
699b544f3c8SBram Moolenaarendfunc
700b544f3c8SBram Moolenaar
701b544f3c8SBram Moolenaar
702b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
703b544f3c8SBram Moolenaar" Test 11:  :if, :elseif, :while argument evaluation after abort	    {{{1
704b544f3c8SBram Moolenaar"
705b544f3c8SBram Moolenaar"	    When code is skipped over due to an error, the boolean argument to
706b544f3c8SBram Moolenaar"	    an :if, :elseif, or :while must not be evaluated.
707b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
708b544f3c8SBram Moolenaar
709b544f3c8SBram MoolenaarXpathINIT
710b544f3c8SBram Moolenaar
711b544f3c8SBram Moolenaarlet calls = 0
712b544f3c8SBram Moolenaar
713b544f3c8SBram Moolenaarfunction! P(num)
714b544f3c8SBram Moolenaar    let g:calls = g:calls + a:num   " side effect on call
715b544f3c8SBram Moolenaar    return 0
716b544f3c8SBram Moolenaarendfunction
717b544f3c8SBram Moolenaar
718b544f3c8SBram Moolenaarif 1
719b544f3c8SBram Moolenaar    Xpath 'a'
720b544f3c8SBram Moolenaar    asdf		" error
721b544f3c8SBram Moolenaar    Xpath 'b'
722b544f3c8SBram Moolenaar    if P(1)		" should not be called
723b544f3c8SBram Moolenaar	Xpath 'c'
724b544f3c8SBram Moolenaar    elseif !P(2)	" should not be called
725b544f3c8SBram Moolenaar	Xpath 'd'
726b544f3c8SBram Moolenaar    else
727b544f3c8SBram Moolenaar	Xpath 'e'
728b544f3c8SBram Moolenaar    endif
729b544f3c8SBram Moolenaar    Xpath 'f'
730b544f3c8SBram Moolenaar    while P(4)		" should not be called
731b544f3c8SBram Moolenaar	Xpath 'g'
732b544f3c8SBram Moolenaar    endwhile
733b544f3c8SBram Moolenaar    Xpath 'h'
734b544f3c8SBram Moolenaarendif
735b544f3c8SBram MoolenaarXpath 'x'
736b544f3c8SBram Moolenaar
737b544f3c8SBram Moolenaarlet g:test11_calls = calls
738b544f3c8SBram Moolenaarlet g:test11_result = g:Xpath
739b544f3c8SBram Moolenaar
740b544f3c8SBram Moolenaarunlet calls
741b544f3c8SBram Moolenaardelfunction P
742b544f3c8SBram Moolenaar
743b544f3c8SBram Moolenaarfunc Test_arg_abort()
744b544f3c8SBram Moolenaar    call assert_equal(0, g:test11_calls)
745b544f3c8SBram Moolenaar    call assert_equal('ax', g:test11_result)
746b544f3c8SBram Moolenaarendfunc
747b544f3c8SBram Moolenaar
748b544f3c8SBram Moolenaar
749b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
750b544f3c8SBram Moolenaar" Test 12:  Expressions in braces in skipped code			    {{{1
751b544f3c8SBram Moolenaar"
752b544f3c8SBram Moolenaar"	    In code skipped over due to an error or inactive conditional,
753b544f3c8SBram Moolenaar"	    an expression in braces as part of a variable or function name
754b544f3c8SBram Moolenaar"	    should not be evaluated.
755b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
756b544f3c8SBram Moolenaar
757b544f3c8SBram MoolenaarXpathINIT
758b544f3c8SBram Moolenaar
759b544f3c8SBram Moolenaarfunction! NULL()
760b544f3c8SBram Moolenaar    Xpath 'a'
761b544f3c8SBram Moolenaar    return 0
762b544f3c8SBram Moolenaarendfunction
763b544f3c8SBram Moolenaar
764b544f3c8SBram Moolenaarfunction! ZERO()
765b544f3c8SBram Moolenaar    Xpath 'b'
766b544f3c8SBram Moolenaar    return 0
767b544f3c8SBram Moolenaarendfunction
768b544f3c8SBram Moolenaar
769b544f3c8SBram Moolenaarfunction! F0()
770b544f3c8SBram Moolenaar    Xpath 'c'
771b544f3c8SBram Moolenaarendfunction
772b544f3c8SBram Moolenaar
773b544f3c8SBram Moolenaarfunction! F1(arg)
774b544f3c8SBram Moolenaar    Xpath 'e'
775b544f3c8SBram Moolenaarendfunction
776b544f3c8SBram Moolenaar
777b544f3c8SBram Moolenaarlet V0 = 1
778b544f3c8SBram Moolenaar
779b544f3c8SBram MoolenaarXpath 'f'
780b544f3c8SBram Moolenaarecho 0 ? F{NULL() + V{ZERO()}}() : 1
781b544f3c8SBram Moolenaar
782b544f3c8SBram MoolenaarXpath 'g'
783b544f3c8SBram Moolenaarif 0
784b544f3c8SBram Moolenaar    Xpath 'h'
785b544f3c8SBram Moolenaar    call F{NULL() + V{ZERO()}}()
786b544f3c8SBram Moolenaarendif
787b544f3c8SBram Moolenaar
788b544f3c8SBram MoolenaarXpath 'i'
789b544f3c8SBram Moolenaarif 1
790b544f3c8SBram Moolenaar    asdf		" error
791b544f3c8SBram Moolenaar    Xpath 'j'
792b544f3c8SBram Moolenaar    call F1(F{NULL() + V{ZERO()}}())
793b544f3c8SBram Moolenaarendif
794b544f3c8SBram Moolenaar
795b544f3c8SBram MoolenaarXpath 'k'
796b544f3c8SBram Moolenaarif 1
797b544f3c8SBram Moolenaar    asdf		" error
798b544f3c8SBram Moolenaar    Xpath 'l'
799b544f3c8SBram Moolenaar    call F{NULL() + V{ZERO()}}()
800b544f3c8SBram Moolenaarendif
801b544f3c8SBram Moolenaar
802b544f3c8SBram Moolenaarlet g:test12_result = g:Xpath
803b544f3c8SBram Moolenaar
804b544f3c8SBram Moolenaarfunc Test_braces_skipped()
805b544f3c8SBram Moolenaar    call assert_equal('fgik', g:test12_result)
806b544f3c8SBram Moolenaarendfunc
807b544f3c8SBram Moolenaar
808b544f3c8SBram Moolenaar
809b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
810b544f3c8SBram Moolenaar" Test 13:  Failure in argument evaluation for :while			    {{{1
811b544f3c8SBram Moolenaar"
812b544f3c8SBram Moolenaar"	    A failure in the expression evaluation for the condition of a :while
813b544f3c8SBram Moolenaar"	    causes the whole :while loop until the matching :endwhile being
814b544f3c8SBram Moolenaar"	    ignored.  Continuation is at the next following line.
815b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
816b544f3c8SBram Moolenaar
817b544f3c8SBram MoolenaarXpathINIT
818b544f3c8SBram Moolenaar
819b544f3c8SBram MoolenaarXpath 'a'
820b544f3c8SBram Moolenaarwhile asdf
821b544f3c8SBram Moolenaar    Xpath 'b'
822b544f3c8SBram Moolenaar    while 1
823b544f3c8SBram Moolenaar	Xpath 'c'
824b544f3c8SBram Moolenaar	break
825b544f3c8SBram Moolenaar    endwhile
826b544f3c8SBram Moolenaar    Xpath 'd'
827b544f3c8SBram Moolenaar    break
828b544f3c8SBram Moolenaarendwhile
829b544f3c8SBram MoolenaarXpath 'e'
830b544f3c8SBram Moolenaar
831b544f3c8SBram Moolenaarwhile asdf | Xpath 'f' | endwhile | Xpath 'g'
832b544f3c8SBram MoolenaarXpath 'h'
833b544f3c8SBram Moolenaarlet g:test13_result = g:Xpath
834b544f3c8SBram Moolenaar
835b544f3c8SBram Moolenaarfunc Test_while_fail()
836b544f3c8SBram Moolenaar    call assert_equal('aeh', g:test13_result)
837b544f3c8SBram Moolenaarendfunc
838b544f3c8SBram Moolenaar
839b544f3c8SBram Moolenaar
840b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
841b544f3c8SBram Moolenaar" Test 14:  Failure in argument evaluation for :if			    {{{1
842b544f3c8SBram Moolenaar"
843b544f3c8SBram Moolenaar"	    A failure in the expression evaluation for the condition of an :if
844b544f3c8SBram Moolenaar"	    does not cause the corresponding :else or :endif being matched to
845b544f3c8SBram Moolenaar"	    a previous :if/:elseif.  Neither of both branches of the failed :if
846b544f3c8SBram Moolenaar"	    are executed.
847b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
848b544f3c8SBram Moolenaar
849b544f3c8SBram MoolenaarXpathINIT
850b544f3c8SBram Moolenaar
851b544f3c8SBram Moolenaarfunction! F()
852b544f3c8SBram Moolenaar    Xpath 'a'
853b544f3c8SBram Moolenaar    let x = 0
854b544f3c8SBram Moolenaar    if x		" false
855b544f3c8SBram Moolenaar	Xpath 'b'
856b544f3c8SBram Moolenaar    elseif !x		" always true
857b544f3c8SBram Moolenaar	Xpath 'c'
858b544f3c8SBram Moolenaar	let x = 1
859b544f3c8SBram Moolenaar	if g:boolvar	" possibly undefined
860b544f3c8SBram Moolenaar	    Xpath 'd'
861b544f3c8SBram Moolenaar	else
862b544f3c8SBram Moolenaar	    Xpath 'e'
863b544f3c8SBram Moolenaar	endif
864b544f3c8SBram Moolenaar	Xpath 'f'
865b544f3c8SBram Moolenaar    elseif x		" never executed
866b544f3c8SBram Moolenaar	Xpath 'g'
867b544f3c8SBram Moolenaar    endif
868b544f3c8SBram Moolenaar    Xpath 'h'
869b544f3c8SBram Moolenaarendfunction
870b544f3c8SBram Moolenaar
871b544f3c8SBram Moolenaarlet boolvar = 1
872b544f3c8SBram Moolenaarcall F()
873b544f3c8SBram MoolenaarXpath '-'
874b544f3c8SBram Moolenaar
875b544f3c8SBram Moolenaarunlet boolvar
876b544f3c8SBram Moolenaarcall F()
877b544f3c8SBram Moolenaarlet g:test14_result = g:Xpath
878b544f3c8SBram Moolenaar
879b544f3c8SBram Moolenaardelfunction F
880b544f3c8SBram Moolenaar
881b544f3c8SBram Moolenaarfunc Test_if_fail()
882b544f3c8SBram Moolenaar    call assert_equal('acdfh-acfh', g:test14_result)
883b544f3c8SBram Moolenaarendfunc
884b544f3c8SBram Moolenaar
885b544f3c8SBram Moolenaar
886b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
887b544f3c8SBram Moolenaar" Test 15:  Failure in argument evaluation for :if (bar)		    {{{1
888b544f3c8SBram Moolenaar"
889b544f3c8SBram Moolenaar"	    Like previous test, except that the failing :if ... | ... | :endif
890b544f3c8SBram Moolenaar"	    is in a single line.
891b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
892b544f3c8SBram Moolenaar
893b544f3c8SBram MoolenaarXpathINIT
894b544f3c8SBram Moolenaar
895b544f3c8SBram Moolenaarfunction! F()
896b544f3c8SBram Moolenaar    Xpath 'a'
897b544f3c8SBram Moolenaar    let x = 0
898b544f3c8SBram Moolenaar    if x		" false
899b544f3c8SBram Moolenaar	Xpath 'b'
900b544f3c8SBram Moolenaar    elseif !x		" always true
901b544f3c8SBram Moolenaar	Xpath 'c'
902b544f3c8SBram Moolenaar	let x = 1
903b544f3c8SBram Moolenaar	if g:boolvar | Xpath 'd' | else | Xpath 'e' | endif
904b544f3c8SBram Moolenaar	Xpath 'f'
905b544f3c8SBram Moolenaar    elseif x		" never executed
906b544f3c8SBram Moolenaar	Xpath 'g'
907b544f3c8SBram Moolenaar    endif
908b544f3c8SBram Moolenaar    Xpath 'h'
909b544f3c8SBram Moolenaarendfunction
910b544f3c8SBram Moolenaar
911b544f3c8SBram Moolenaarlet boolvar = 1
912b544f3c8SBram Moolenaarcall F()
913b544f3c8SBram MoolenaarXpath '-'
914b544f3c8SBram Moolenaar
915b544f3c8SBram Moolenaarunlet boolvar
916b544f3c8SBram Moolenaarcall F()
917b544f3c8SBram Moolenaarlet g:test15_result = g:Xpath
918b544f3c8SBram Moolenaar
919b544f3c8SBram Moolenaardelfunction F
920b544f3c8SBram Moolenaar
921b544f3c8SBram Moolenaarfunc Test_if_bar_fail()
922b544f3c8SBram Moolenaar    call assert_equal('acdfh-acfh', g:test15_result)
923b544f3c8SBram Moolenaarendfunc
924b544f3c8SBram Moolenaar
925b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
9261f068233SBram Moolenaar" Test 16:  Double :else or :elseif after :else				    {{{1
9271f068233SBram Moolenaar"
9281f068233SBram Moolenaar"	    Multiple :elses or an :elseif after an :else are forbidden.
9291f068233SBram Moolenaar"-------------------------------------------------------------------------------
9301f068233SBram Moolenaar
9311f068233SBram Moolenaarfunc T16_F() abort
9321f068233SBram Moolenaar  if 0
9331f068233SBram Moolenaar    Xpath 'a'
9341f068233SBram Moolenaar  else
9351f068233SBram Moolenaar    Xpath 'b'
9361f068233SBram Moolenaar  else		" aborts function
9371f068233SBram Moolenaar    Xpath 'c'
9381f068233SBram Moolenaar  endif
9391f068233SBram Moolenaar  Xpath 'd'
9401f068233SBram Moolenaarendfunc
9411f068233SBram Moolenaar
9421f068233SBram Moolenaarfunc T16_G() abort
9431f068233SBram Moolenaar  if 0
9441f068233SBram Moolenaar    Xpath 'a'
9451f068233SBram Moolenaar  else
9461f068233SBram Moolenaar    Xpath 'b'
9471f068233SBram Moolenaar  elseif 1		" aborts function
9481f068233SBram Moolenaar    Xpath 'c'
9491f068233SBram Moolenaar  else
9501f068233SBram Moolenaar    Xpath 'd'
9511f068233SBram Moolenaar  endif
9521f068233SBram Moolenaar  Xpath 'e'
9531f068233SBram Moolenaarendfunc
9541f068233SBram Moolenaar
9551f068233SBram Moolenaarfunc T16_H() abort
9561f068233SBram Moolenaar  if 0
9571f068233SBram Moolenaar    Xpath 'a'
9581f068233SBram Moolenaar  elseif 0
9591f068233SBram Moolenaar    Xpath 'b'
9601f068233SBram Moolenaar  else
9611f068233SBram Moolenaar    Xpath 'c'
9621f068233SBram Moolenaar  else		" aborts function
9631f068233SBram Moolenaar    Xpath 'd'
9641f068233SBram Moolenaar  endif
9651f068233SBram Moolenaar  Xpath 'e'
9661f068233SBram Moolenaarendfunc
9671f068233SBram Moolenaar
9681f068233SBram Moolenaarfunc T16_I() abort
9691f068233SBram Moolenaar  if 0
9701f068233SBram Moolenaar    Xpath 'a'
9711f068233SBram Moolenaar  elseif 0
9721f068233SBram Moolenaar    Xpath 'b'
9731f068233SBram Moolenaar  else
9741f068233SBram Moolenaar    Xpath 'c'
9751f068233SBram Moolenaar  elseif 1		" aborts function
9761f068233SBram Moolenaar    Xpath 'd'
9771f068233SBram Moolenaar  else
9781f068233SBram Moolenaar    Xpath 'e'
9791f068233SBram Moolenaar  endif
9801f068233SBram Moolenaar  Xpath 'f'
9811f068233SBram Moolenaarendfunc
9821f068233SBram Moolenaar
9831f068233SBram Moolenaarfunc Test_Multi_Else()
9841f068233SBram Moolenaar  XpathINIT
9851f068233SBram Moolenaar  try
9861f068233SBram Moolenaar    call T16_F()
9871f068233SBram Moolenaar  catch /E583:/
9881f068233SBram Moolenaar    Xpath 'e'
9891f068233SBram Moolenaar  endtry
9901f068233SBram Moolenaar  call assert_equal('be', g:Xpath)
9911f068233SBram Moolenaar
9921f068233SBram Moolenaar  XpathINIT
9931f068233SBram Moolenaar  try
9941f068233SBram Moolenaar    call T16_G()
9951f068233SBram Moolenaar  catch /E584:/
9961f068233SBram Moolenaar    Xpath 'f'
9971f068233SBram Moolenaar  endtry
9981f068233SBram Moolenaar  call assert_equal('bf', g:Xpath)
9991f068233SBram Moolenaar
10001f068233SBram Moolenaar  XpathINIT
10011f068233SBram Moolenaar  try
10021f068233SBram Moolenaar    call T16_H()
10031f068233SBram Moolenaar  catch /E583:/
10041f068233SBram Moolenaar    Xpath 'f'
10051f068233SBram Moolenaar  endtry
10061f068233SBram Moolenaar  call assert_equal('cf', g:Xpath)
10071f068233SBram Moolenaar
10081f068233SBram Moolenaar  XpathINIT
10091f068233SBram Moolenaar  try
10101f068233SBram Moolenaar    call T16_I()
10111f068233SBram Moolenaar  catch /E584:/
10121f068233SBram Moolenaar    Xpath 'g'
10131f068233SBram Moolenaar  endtry
10141f068233SBram Moolenaar  call assert_equal('cg', g:Xpath)
10151f068233SBram Moolenaarendfunc
10161f068233SBram Moolenaar
10171f068233SBram Moolenaar"-------------------------------------------------------------------------------
10181f068233SBram Moolenaar" Test 17:  Nesting of unmatched :if or :endif inside a :while		    {{{1
10191f068233SBram Moolenaar"
10201f068233SBram Moolenaar"	    The :while/:endwhile takes precedence in nesting over an unclosed
10211f068233SBram Moolenaar"	    :if or an unopened :endif.
10221f068233SBram Moolenaar"-------------------------------------------------------------------------------
10231f068233SBram Moolenaar
10241f068233SBram Moolenaar" While loops inside a function are continued on error.
10251f068233SBram Moolenaarfunc T17_F()
10261f068233SBram Moolenaar  let loops = 3
10271f068233SBram Moolenaar  while loops > 0
10281f068233SBram Moolenaar    let loops -= 1
10291f068233SBram Moolenaar    Xpath 'a' . loops
10301f068233SBram Moolenaar    if (loops == 1)
10311f068233SBram Moolenaar      Xpath 'b' . loops
10321f068233SBram Moolenaar      continue
10331f068233SBram Moolenaar    elseif (loops == 0)
10341f068233SBram Moolenaar      Xpath 'c' . loops
10351f068233SBram Moolenaar      break
10361f068233SBram Moolenaar    elseif 1
10371f068233SBram Moolenaar      Xpath 'd' . loops
10381f068233SBram Moolenaar    " endif missing!
10391f068233SBram Moolenaar  endwhile	" :endwhile after :if 1
10401f068233SBram Moolenaar  Xpath 'e'
10411f068233SBram Moolenaarendfunc
10421f068233SBram Moolenaar
10431f068233SBram Moolenaarfunc T17_G()
10441f068233SBram Moolenaar  let loops = 2
10451f068233SBram Moolenaar  while loops > 0
10461f068233SBram Moolenaar    let loops -= 1
10471f068233SBram Moolenaar    Xpath 'a' . loops
10481f068233SBram Moolenaar    if 0
10491f068233SBram Moolenaar      Xpath 'b' . loops
10501f068233SBram Moolenaar    " endif missing
10511f068233SBram Moolenaar  endwhile	" :endwhile after :if 0
10521f068233SBram Moolenaarendfunc
10531f068233SBram Moolenaar
10541f068233SBram Moolenaarfunc T17_H()
10551f068233SBram Moolenaar  let loops = 2
10561f068233SBram Moolenaar  while loops > 0
10571f068233SBram Moolenaar    let loops -= 1
10581f068233SBram Moolenaar    Xpath 'a' . loops
10591f068233SBram Moolenaar    " if missing!
10601f068233SBram Moolenaar    endif	" :endif without :if in while
10611f068233SBram Moolenaar    Xpath 'b' . loops
10621f068233SBram Moolenaar  endwhile
10631f068233SBram Moolenaarendfunc
10641f068233SBram Moolenaar
10651f068233SBram Moolenaar" Error continuation outside a function is at the outermost :endwhile or :endif.
10661f068233SBram MoolenaarXpathINIT
10671f068233SBram Moolenaarlet v:errmsg = ''
10681f068233SBram Moolenaarlet loops = 2
10691f068233SBram Moolenaarwhile loops > 0
10701f068233SBram Moolenaar    let loops -= 1
10711f068233SBram Moolenaar    Xpath 'a' . loops
10721f068233SBram Moolenaar    if 0
10731f068233SBram Moolenaar	Xpath 'b' . loops
10741f068233SBram Moolenaar    " endif missing! Following :endwhile fails.
10751f068233SBram Moolenaarendwhile | Xpath 'c'
10761f068233SBram MoolenaarXpath 'd'
10771f068233SBram Moolenaarcall assert_match('E171:', v:errmsg)
10781f068233SBram Moolenaarcall assert_equal('a1d', g:Xpath)
10791f068233SBram Moolenaar
10801f068233SBram Moolenaarfunc Test_unmatched_if_in_while()
10811f068233SBram Moolenaar  XpathINIT
10821f068233SBram Moolenaar  call assert_fails('call T17_F()', 'E171:')
10831f068233SBram Moolenaar  call assert_equal('a2d2a1b1a0c0e', g:Xpath)
10841f068233SBram Moolenaar
10851f068233SBram Moolenaar  XpathINIT
10861f068233SBram Moolenaar  call assert_fails('call T17_G()', 'E171:')
10871f068233SBram Moolenaar  call assert_equal('a1a0', g:Xpath)
10881f068233SBram Moolenaar
10891f068233SBram Moolenaar  XpathINIT
10901f068233SBram Moolenaar  call assert_fails('call T17_H()', 'E580:')
10911f068233SBram Moolenaar  call assert_equal('a1b1a0b0', g:Xpath)
10921f068233SBram Moolenaarendfunc
10931f068233SBram Moolenaar
10941f068233SBram Moolenaar"-------------------------------------------------------------------------------
10951f068233SBram Moolenaar"-------------------------------------------------------------------------------
10961f068233SBram Moolenaar"-------------------------------------------------------------------------------
10971f068233SBram Moolenaar" Test 87   using (expr) ? funcref : funcref				    {{{1
10981f068233SBram Moolenaar"
10991f068233SBram Moolenaar"	    Vim needs to correctly parse the funcref and even when it does
11001f068233SBram Moolenaar"	    not execute the funcref, it needs to consume the trailing ()
11011f068233SBram Moolenaar"-------------------------------------------------------------------------------
11021f068233SBram Moolenaar
11031f068233SBram Moolenaarfunc Add2(x1, x2)
11041f068233SBram Moolenaar  return a:x1 + a:x2
11051f068233SBram Moolenaarendfu
11061f068233SBram Moolenaar
11071f068233SBram Moolenaarfunc GetStr()
11081f068233SBram Moolenaar  return "abcdefghijklmnopqrstuvwxyp"
11091f068233SBram Moolenaarendfu
11101f068233SBram Moolenaar
11111f068233SBram Moolenaarfunc Test_funcref_with_condexpr()
11121f068233SBram Moolenaar  call assert_equal(5, function('Add2')(2,3))
11131f068233SBram Moolenaar
11141f068233SBram Moolenaar  call assert_equal(3, 1 ? function('Add2')(1,2) : function('Add2')(2,3))
11151f068233SBram Moolenaar  call assert_equal(5, 0 ? function('Add2')(1,2) : function('Add2')(2,3))
11161f068233SBram Moolenaar  " Make sure, GetStr() still works.
11171f068233SBram Moolenaar  call assert_equal('abcdefghijk', GetStr()[0:10])
11181f068233SBram Moolenaarendfunc
11191f068233SBram Moolenaar
1120b544f3c8SBram Moolenaar" Test 90:  Recognizing {} in variable name.			    {{{1
1121b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
1122b544f3c8SBram Moolenaar
1123b544f3c8SBram Moolenaarfunc Test_curlies()
1124b544f3c8SBram Moolenaar    let s:var = 66
1125b544f3c8SBram Moolenaar    let ns = 's'
1126b544f3c8SBram Moolenaar    call assert_equal(66, {ns}:var)
1127b544f3c8SBram Moolenaar
1128b544f3c8SBram Moolenaar    let g:a = {}
1129b544f3c8SBram Moolenaar    let g:b = 't'
1130b544f3c8SBram Moolenaar    let g:a[g:b] = 77
1131b544f3c8SBram Moolenaar    call assert_equal(77, g:a['t'])
1132b544f3c8SBram Moolenaarendfunc
1133b544f3c8SBram Moolenaar
1134b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
1135b544f3c8SBram Moolenaar" Test 91:  using type().					    {{{1
1136b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
1137b544f3c8SBram Moolenaar
1138b544f3c8SBram Moolenaarfunc Test_type()
1139b544f3c8SBram Moolenaar    call assert_equal(0, type(0))
1140b544f3c8SBram Moolenaar    call assert_equal(1, type(""))
1141b544f3c8SBram Moolenaar    call assert_equal(2, type(function("tr")))
1142b544f3c8SBram Moolenaar    call assert_equal(2, type(function("tr", [8])))
1143b544f3c8SBram Moolenaar    call assert_equal(3, type([]))
1144b544f3c8SBram Moolenaar    call assert_equal(4, type({}))
11455feabe00SBram Moolenaar    if has('float')
1146b544f3c8SBram Moolenaar      call assert_equal(5, type(0.0))
11475feabe00SBram Moolenaar    endif
1148b544f3c8SBram Moolenaar    call assert_equal(6, type(v:false))
1149b544f3c8SBram Moolenaar    call assert_equal(6, type(v:true))
1150b544f3c8SBram Moolenaar    call assert_equal(7, type(v:none))
1151b544f3c8SBram Moolenaar    call assert_equal(7, type(v:null))
1152b544f3c8SBram Moolenaar    call assert_equal(8, v:t_job)
1153b544f3c8SBram Moolenaar    call assert_equal(9, v:t_channel)
1154b544f3c8SBram Moolenaar    call assert_equal(v:t_number, type(0))
1155b544f3c8SBram Moolenaar    call assert_equal(v:t_string, type(""))
1156b544f3c8SBram Moolenaar    call assert_equal(v:t_func, type(function("tr")))
1157b544f3c8SBram Moolenaar    call assert_equal(v:t_func, type(function("tr", [8])))
1158b544f3c8SBram Moolenaar    call assert_equal(v:t_list, type([]))
1159b544f3c8SBram Moolenaar    call assert_equal(v:t_dict, type({}))
11605feabe00SBram Moolenaar    if has('float')
1161b544f3c8SBram Moolenaar      call assert_equal(v:t_float, type(0.0))
11625feabe00SBram Moolenaar    endif
1163b544f3c8SBram Moolenaar    call assert_equal(v:t_bool, type(v:false))
1164b544f3c8SBram Moolenaar    call assert_equal(v:t_bool, type(v:true))
1165b544f3c8SBram Moolenaar    call assert_equal(v:t_none, type(v:none))
1166b544f3c8SBram Moolenaar    call assert_equal(v:t_none, type(v:null))
1167*92b83ccfSBram Moolenaar    call assert_equal(v:t_string, type(test_null_string()))
1168*92b83ccfSBram Moolenaar    call assert_equal(v:t_func, type(test_null_function()))
1169*92b83ccfSBram Moolenaar    call assert_equal(v:t_func, type(test_null_partial()))
1170*92b83ccfSBram Moolenaar    call assert_equal(v:t_list, type(test_null_list()))
1171*92b83ccfSBram Moolenaar    call assert_equal(v:t_dict, type(test_null_dict()))
1172*92b83ccfSBram Moolenaar    if has('job')
1173*92b83ccfSBram Moolenaar      call assert_equal(v:t_job, type(test_null_job()))
1174*92b83ccfSBram Moolenaar    endif
1175*92b83ccfSBram Moolenaar    if has('channel')
1176*92b83ccfSBram Moolenaar      call assert_equal(v:t_channel, type(test_null_channel()))
1177*92b83ccfSBram Moolenaar    endif
1178*92b83ccfSBram Moolenaar    call assert_equal(v:t_blob, type(test_null_blob()))
1179b544f3c8SBram Moolenaar
11807c215c58SBram Moolenaar    call assert_fails("call type(test_void())", 'E685:')
11817c215c58SBram Moolenaar    call assert_fails("call type(test_unknown())", 'E685:')
1182b544f3c8SBram Moolenaar
1183b544f3c8SBram Moolenaar    call assert_equal(0, 0 + v:false)
1184b544f3c8SBram Moolenaar    call assert_equal(1, 0 + v:true)
1185b544f3c8SBram Moolenaar    call assert_equal(0, 0 + v:none)
1186b544f3c8SBram Moolenaar    call assert_equal(0, 0 + v:null)
1187b544f3c8SBram Moolenaar
1188b544f3c8SBram Moolenaar    call assert_equal('v:false', '' . v:false)
1189b544f3c8SBram Moolenaar    call assert_equal('v:true', '' . v:true)
1190b544f3c8SBram Moolenaar    call assert_equal('v:none', '' . v:none)
1191b544f3c8SBram Moolenaar    call assert_equal('v:null', '' . v:null)
1192b544f3c8SBram Moolenaar
1193b544f3c8SBram Moolenaar    call assert_true(v:false == 0)
1194b544f3c8SBram Moolenaar    call assert_false(v:false != 0)
1195b544f3c8SBram Moolenaar    call assert_true(v:true == 1)
1196b544f3c8SBram Moolenaar    call assert_false(v:true != 1)
1197b544f3c8SBram Moolenaar    call assert_false(v:true == v:false)
1198b544f3c8SBram Moolenaar    call assert_true(v:true != v:false)
1199b544f3c8SBram Moolenaar
1200b544f3c8SBram Moolenaar    call assert_true(v:null == 0)
1201b544f3c8SBram Moolenaar    call assert_false(v:null != 0)
1202b544f3c8SBram Moolenaar    call assert_true(v:none == 0)
1203b544f3c8SBram Moolenaar    call assert_false(v:none != 0)
1204b544f3c8SBram Moolenaar
1205b544f3c8SBram Moolenaar    call assert_true(v:false is v:false)
1206b544f3c8SBram Moolenaar    call assert_true(v:true is v:true)
1207b544f3c8SBram Moolenaar    call assert_true(v:none is v:none)
1208b544f3c8SBram Moolenaar    call assert_true(v:null is v:null)
1209b544f3c8SBram Moolenaar
1210b544f3c8SBram Moolenaar    call assert_false(v:false isnot v:false)
1211b544f3c8SBram Moolenaar    call assert_false(v:true isnot v:true)
1212b544f3c8SBram Moolenaar    call assert_false(v:none isnot v:none)
1213b544f3c8SBram Moolenaar    call assert_false(v:null isnot v:null)
1214b544f3c8SBram Moolenaar
1215b544f3c8SBram Moolenaar    call assert_false(v:false is 0)
1216b544f3c8SBram Moolenaar    call assert_false(v:true is 1)
1217b544f3c8SBram Moolenaar    call assert_false(v:true is v:false)
1218b544f3c8SBram Moolenaar    call assert_false(v:none is 0)
1219b544f3c8SBram Moolenaar    call assert_false(v:null is 0)
1220b544f3c8SBram Moolenaar    call assert_false(v:null is v:none)
1221b544f3c8SBram Moolenaar
1222b544f3c8SBram Moolenaar    call assert_true(v:false isnot 0)
1223b544f3c8SBram Moolenaar    call assert_true(v:true isnot 1)
1224b544f3c8SBram Moolenaar    call assert_true(v:true isnot v:false)
1225b544f3c8SBram Moolenaar    call assert_true(v:none isnot 0)
1226b544f3c8SBram Moolenaar    call assert_true(v:null isnot 0)
1227b544f3c8SBram Moolenaar    call assert_true(v:null isnot v:none)
1228b544f3c8SBram Moolenaar
1229b544f3c8SBram Moolenaar    call assert_equal(v:false, eval(string(v:false)))
1230b544f3c8SBram Moolenaar    call assert_equal(v:true, eval(string(v:true)))
1231b544f3c8SBram Moolenaar    call assert_equal(v:none, eval(string(v:none)))
1232b544f3c8SBram Moolenaar    call assert_equal(v:null, eval(string(v:null)))
1233b544f3c8SBram Moolenaar
1234b544f3c8SBram Moolenaar    call assert_equal(v:false, copy(v:false))
1235b544f3c8SBram Moolenaar    call assert_equal(v:true, copy(v:true))
1236b544f3c8SBram Moolenaar    call assert_equal(v:none, copy(v:none))
1237b544f3c8SBram Moolenaar    call assert_equal(v:null, copy(v:null))
1238b544f3c8SBram Moolenaar
1239b544f3c8SBram Moolenaar    call assert_equal([v:false], deepcopy([v:false]))
1240b544f3c8SBram Moolenaar    call assert_equal([v:true], deepcopy([v:true]))
1241b544f3c8SBram Moolenaar    call assert_equal([v:none], deepcopy([v:none]))
1242b544f3c8SBram Moolenaar    call assert_equal([v:null], deepcopy([v:null]))
1243b544f3c8SBram Moolenaar
1244b544f3c8SBram Moolenaar    call assert_true(empty(v:false))
1245b544f3c8SBram Moolenaar    call assert_false(empty(v:true))
1246b544f3c8SBram Moolenaar    call assert_true(empty(v:null))
1247b544f3c8SBram Moolenaar    call assert_true(empty(v:none))
1248b544f3c8SBram Moolenaar
1249b544f3c8SBram Moolenaar    func ChangeYourMind()
1250b544f3c8SBram Moolenaar	try
1251b544f3c8SBram Moolenaar	    return v:true
1252b544f3c8SBram Moolenaar	finally
1253b544f3c8SBram Moolenaar	    return 'something else'
1254b544f3c8SBram Moolenaar	endtry
1255b544f3c8SBram Moolenaar    endfunc
1256b544f3c8SBram Moolenaar
1257b544f3c8SBram Moolenaar    call ChangeYourMind()
1258b544f3c8SBram Moolenaarendfunc
1259b544f3c8SBram Moolenaar
1260b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
1261b544f3c8SBram Moolenaar" Test 92:  skipping code					    {{{1
1262b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
1263b544f3c8SBram Moolenaar
1264b544f3c8SBram Moolenaarfunc Test_skip()
1265b544f3c8SBram Moolenaar    let Fn = function('Test_type')
1266b544f3c8SBram Moolenaar    call assert_false(0 && Fn[1])
1267b544f3c8SBram Moolenaar    call assert_false(0 && string(Fn))
1268b544f3c8SBram Moolenaar    call assert_false(0 && len(Fn))
1269b544f3c8SBram Moolenaar    let l = []
1270b544f3c8SBram Moolenaar    call assert_false(0 && l[1])
1271b544f3c8SBram Moolenaar    call assert_false(0 && string(l))
1272b544f3c8SBram Moolenaar    call assert_false(0 && len(l))
1273b544f3c8SBram Moolenaar    let f = 1.0
1274b544f3c8SBram Moolenaar    call assert_false(0 && f[1])
1275b544f3c8SBram Moolenaar    call assert_false(0 && string(f))
1276b544f3c8SBram Moolenaar    call assert_false(0 && len(f))
1277b544f3c8SBram Moolenaar    let sp = v:null
1278b544f3c8SBram Moolenaar    call assert_false(0 && sp[1])
1279b544f3c8SBram Moolenaar    call assert_false(0 && string(sp))
1280b544f3c8SBram Moolenaar    call assert_false(0 && len(sp))
1281b544f3c8SBram Moolenaar
1282b544f3c8SBram Moolenaarendfunc
1283b544f3c8SBram Moolenaar
1284b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
1285b544f3c8SBram Moolenaar" Test 93:  :echo and string()					    {{{1
1286b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
1287b544f3c8SBram Moolenaar
1288b544f3c8SBram Moolenaarfunc Test_echo_and_string()
1289b544f3c8SBram Moolenaar    " String
1290b544f3c8SBram Moolenaar    let a = 'foo bar'
1291b544f3c8SBram Moolenaar    redir => result
1292b544f3c8SBram Moolenaar    echo a
1293b544f3c8SBram Moolenaar    echo string(a)
1294b544f3c8SBram Moolenaar    redir END
1295b544f3c8SBram Moolenaar    let l = split(result, "\n")
1296b544f3c8SBram Moolenaar    call assert_equal(["foo bar",
1297b544f3c8SBram Moolenaar		     \ "'foo bar'"], l)
1298b544f3c8SBram Moolenaar
1299b544f3c8SBram Moolenaar    " Float
1300b544f3c8SBram Moolenaar    if has('float')
1301b544f3c8SBram Moolenaar	let a = -1.2e0
1302b544f3c8SBram Moolenaar	redir => result
1303b544f3c8SBram Moolenaar	echo a
1304b544f3c8SBram Moolenaar	echo string(a)
1305b544f3c8SBram Moolenaar	redir END
1306b544f3c8SBram Moolenaar	let l = split(result, "\n")
1307b544f3c8SBram Moolenaar	call assert_equal(["-1.2",
1308b544f3c8SBram Moolenaar			 \ "-1.2"], l)
1309b544f3c8SBram Moolenaar    endif
1310b544f3c8SBram Moolenaar
1311b544f3c8SBram Moolenaar    " Funcref
1312b544f3c8SBram Moolenaar    redir => result
1313b544f3c8SBram Moolenaar    echo function('string')
1314b544f3c8SBram Moolenaar    echo string(function('string'))
1315b544f3c8SBram Moolenaar    redir END
1316b544f3c8SBram Moolenaar    let l = split(result, "\n")
1317b544f3c8SBram Moolenaar    call assert_equal(["string",
1318b544f3c8SBram Moolenaar		     \ "function('string')"], l)
1319b544f3c8SBram Moolenaar
1320b544f3c8SBram Moolenaar    " Recursive dictionary
1321b544f3c8SBram Moolenaar    let a = {}
1322b544f3c8SBram Moolenaar    let a["a"] = a
1323b544f3c8SBram Moolenaar    redir => result
1324b544f3c8SBram Moolenaar    echo a
1325b544f3c8SBram Moolenaar    echo string(a)
1326b544f3c8SBram Moolenaar    redir END
1327b544f3c8SBram Moolenaar    let l = split(result, "\n")
1328b544f3c8SBram Moolenaar    call assert_equal(["{'a': {...}}",
1329b544f3c8SBram Moolenaar		     \ "{'a': {...}}"], l)
1330b544f3c8SBram Moolenaar
1331b544f3c8SBram Moolenaar    " Recursive list
1332b544f3c8SBram Moolenaar    let a = [0]
1333b544f3c8SBram Moolenaar    let a[0] = a
1334b544f3c8SBram Moolenaar    redir => result
1335b544f3c8SBram Moolenaar    echo a
1336b544f3c8SBram Moolenaar    echo string(a)
1337b544f3c8SBram Moolenaar    redir END
1338b544f3c8SBram Moolenaar    let l = split(result, "\n")
1339b544f3c8SBram Moolenaar    call assert_equal(["[[...]]",
1340b544f3c8SBram Moolenaar		     \ "[[...]]"], l)
1341b544f3c8SBram Moolenaar
1342b544f3c8SBram Moolenaar    " Empty dictionaries in a list
1343b544f3c8SBram Moolenaar    let a = {}
1344b544f3c8SBram Moolenaar    redir => result
1345b544f3c8SBram Moolenaar    echo [a, a, a]
1346b544f3c8SBram Moolenaar    echo string([a, a, a])
1347b544f3c8SBram Moolenaar    redir END
1348b544f3c8SBram Moolenaar    let l = split(result, "\n")
1349b544f3c8SBram Moolenaar    call assert_equal(["[{}, {}, {}]",
1350b544f3c8SBram Moolenaar		     \ "[{}, {}, {}]"], l)
1351b544f3c8SBram Moolenaar
1352b544f3c8SBram Moolenaar    " Empty dictionaries in a dictionary
1353b544f3c8SBram Moolenaar    let a = {}
1354b544f3c8SBram Moolenaar    let b = {"a": a, "b": a}
1355b544f3c8SBram Moolenaar    redir => result
1356b544f3c8SBram Moolenaar    echo b
1357b544f3c8SBram Moolenaar    echo string(b)
1358b544f3c8SBram Moolenaar    redir END
1359b544f3c8SBram Moolenaar    let l = split(result, "\n")
1360b544f3c8SBram Moolenaar    call assert_equal(["{'a': {}, 'b': {}}",
1361b544f3c8SBram Moolenaar		     \ "{'a': {}, 'b': {}}"], l)
1362b544f3c8SBram Moolenaar
1363b544f3c8SBram Moolenaar    " Empty lists in a list
1364b544f3c8SBram Moolenaar    let a = []
1365b544f3c8SBram Moolenaar    redir => result
1366b544f3c8SBram Moolenaar    echo [a, a, a]
1367b544f3c8SBram Moolenaar    echo string([a, a, a])
1368b544f3c8SBram Moolenaar    redir END
1369b544f3c8SBram Moolenaar    let l = split(result, "\n")
1370b544f3c8SBram Moolenaar    call assert_equal(["[[], [], []]",
1371b544f3c8SBram Moolenaar		     \ "[[], [], []]"], l)
1372b544f3c8SBram Moolenaar
1373b544f3c8SBram Moolenaar    " Empty lists in a dictionary
1374b544f3c8SBram Moolenaar    let a = []
1375b544f3c8SBram Moolenaar    let b = {"a": a, "b": a}
1376b544f3c8SBram Moolenaar    redir => result
1377b544f3c8SBram Moolenaar    echo b
1378b544f3c8SBram Moolenaar    echo string(b)
1379b544f3c8SBram Moolenaar    redir END
1380b544f3c8SBram Moolenaar    let l = split(result, "\n")
1381b544f3c8SBram Moolenaar    call assert_equal(["{'a': [], 'b': []}",
1382b544f3c8SBram Moolenaar		     \ "{'a': [], 'b': []}"], l)
1383b544f3c8SBram Moolenaar
1384b544f3c8SBram Moolenaar    " Dictionaries in a list
1385b544f3c8SBram Moolenaar    let a = {"one": "yes", "two": "yes", "three": "yes"}
1386b544f3c8SBram Moolenaar    redir => result
1387b544f3c8SBram Moolenaar    echo [a, a, a]
1388b544f3c8SBram Moolenaar    echo string([a, a, a])
1389b544f3c8SBram Moolenaar    redir END
1390b544f3c8SBram Moolenaar    let l = split(result, "\n")
1391b544f3c8SBram Moolenaar    call assert_equal(["[{'one': 'yes', 'two': 'yes', 'three': 'yes'}, {...}, {...}]",
1392b544f3c8SBram Moolenaar		     \ "[{'one': 'yes', 'two': 'yes', 'three': 'yes'}, {'one': 'yes', 'two': 'yes', 'three': 'yes'}, {'one': 'yes', 'two': 'yes', 'three': 'yes'}]"], l)
1393b544f3c8SBram Moolenaar
1394b544f3c8SBram Moolenaar    " Dictionaries in a dictionary
1395b544f3c8SBram Moolenaar    let a = {"one": "yes", "two": "yes", "three": "yes"}
1396b544f3c8SBram Moolenaar    let b = {"a": a, "b": a}
1397b544f3c8SBram Moolenaar    redir => result
1398b544f3c8SBram Moolenaar    echo b
1399b544f3c8SBram Moolenaar    echo string(b)
1400b544f3c8SBram Moolenaar    redir END
1401b544f3c8SBram Moolenaar    let l = split(result, "\n")
1402b544f3c8SBram Moolenaar    call assert_equal(["{'a': {'one': 'yes', 'two': 'yes', 'three': 'yes'}, 'b': {...}}",
1403b544f3c8SBram Moolenaar		     \ "{'a': {'one': 'yes', 'two': 'yes', 'three': 'yes'}, 'b': {'one': 'yes', 'two': 'yes', 'three': 'yes'}}"], l)
1404b544f3c8SBram Moolenaar
1405b544f3c8SBram Moolenaar    " Lists in a list
1406b544f3c8SBram Moolenaar    let a = [1, 2, 3]
1407b544f3c8SBram Moolenaar    redir => result
1408b544f3c8SBram Moolenaar    echo [a, a, a]
1409b544f3c8SBram Moolenaar    echo string([a, a, a])
1410b544f3c8SBram Moolenaar    redir END
1411b544f3c8SBram Moolenaar    let l = split(result, "\n")
1412b544f3c8SBram Moolenaar    call assert_equal(["[[1, 2, 3], [...], [...]]",
1413b544f3c8SBram Moolenaar		     \ "[[1, 2, 3], [1, 2, 3], [1, 2, 3]]"], l)
1414b544f3c8SBram Moolenaar
1415b544f3c8SBram Moolenaar    " Lists in a dictionary
1416b544f3c8SBram Moolenaar    let a = [1, 2, 3]
1417b544f3c8SBram Moolenaar    let b = {"a": a, "b": a}
1418b544f3c8SBram Moolenaar    redir => result
1419b544f3c8SBram Moolenaar    echo b
1420b544f3c8SBram Moolenaar    echo string(b)
1421b544f3c8SBram Moolenaar    redir END
1422b544f3c8SBram Moolenaar    let l = split(result, "\n")
1423b544f3c8SBram Moolenaar    call assert_equal(["{'a': [1, 2, 3], 'b': [...]}",
1424b544f3c8SBram Moolenaar		     \ "{'a': [1, 2, 3], 'b': [1, 2, 3]}"], l)
1425b544f3c8SBram Moolenaar
14261363a30cSBram Moolenaar    call assert_fails('echo &:', 'E112:')
14271363a30cSBram Moolenaar    call assert_fails('echo &g:', 'E112:')
14281363a30cSBram Moolenaar    call assert_fails('echo &l:', 'E112:')
14291363a30cSBram Moolenaar
1430b544f3c8SBram Moolenaarendfunc
1431b544f3c8SBram Moolenaar
1432b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
1433b544f3c8SBram Moolenaar" Test 94:  64-bit Numbers					    {{{1
1434b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
1435b544f3c8SBram Moolenaar
1436b544f3c8SBram Moolenaarfunc Test_num64()
1437b544f3c8SBram Moolenaar    call assert_notequal( 4294967296, 0)
1438b544f3c8SBram Moolenaar    call assert_notequal(-4294967296, 0)
1439b544f3c8SBram Moolenaar    call assert_equal( 4294967296,  0xFFFFffff + 1)
1440b544f3c8SBram Moolenaar    call assert_equal(-4294967296, -0xFFFFffff - 1)
1441b544f3c8SBram Moolenaar
1442b544f3c8SBram Moolenaar    call assert_equal( 9223372036854775807,  1 / 0)
1443b544f3c8SBram Moolenaar    call assert_equal(-9223372036854775807, -1 / 0)
1444b544f3c8SBram Moolenaar    call assert_equal(-9223372036854775807 - 1,  0 / 0)
1445b544f3c8SBram Moolenaar
14465feabe00SBram Moolenaar    if has('float')
1447b544f3c8SBram Moolenaar      call assert_equal( 0x7FFFffffFFFFffff, float2nr( 1.0e150))
1448b544f3c8SBram Moolenaar      call assert_equal(-0x7FFFffffFFFFffff, float2nr(-1.0e150))
14495feabe00SBram Moolenaar    endif
1450b544f3c8SBram Moolenaar
1451b544f3c8SBram Moolenaar    let rng = range(0xFFFFffff, 0x100000001)
1452b544f3c8SBram Moolenaar    call assert_equal([0xFFFFffff, 0x100000000, 0x100000001], rng)
1453b544f3c8SBram Moolenaar    call assert_equal(0x100000001, max(rng))
1454b544f3c8SBram Moolenaar    call assert_equal(0xFFFFffff, min(rng))
1455b544f3c8SBram Moolenaar    call assert_equal(rng, sort(range(0x100000001, 0xFFFFffff, -1), 'N'))
1456b544f3c8SBram Moolenaarendfunc
1457b544f3c8SBram Moolenaar
1458b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
1459b544f3c8SBram Moolenaar" Test 95:  lines of :append, :change, :insert			    {{{1
1460b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
1461b544f3c8SBram Moolenaar
1462b544f3c8SBram Moolenaarfunction! DefineFunction(name, body)
1463b544f3c8SBram Moolenaar    let func = join(['function! ' . a:name . '()'] + a:body + ['endfunction'], "\n")
1464b544f3c8SBram Moolenaar    exec func
1465b544f3c8SBram Moolenaarendfunction
1466b544f3c8SBram Moolenaar
1467b544f3c8SBram Moolenaarfunc Test_script_lines()
1468b544f3c8SBram Moolenaar    " :append
1469b544f3c8SBram Moolenaar    try
1470b544f3c8SBram Moolenaar	call DefineFunction('T_Append', [
1471b544f3c8SBram Moolenaar		    \ 'append',
1472b544f3c8SBram Moolenaar		    \ 'py <<EOS',
1473b544f3c8SBram Moolenaar		    \ '.',
1474b544f3c8SBram Moolenaar		    \ ])
1475b544f3c8SBram Moolenaar    catch
147637175409SBram Moolenaar	call assert_report("Can't define function")
1477b544f3c8SBram Moolenaar    endtry
1478b544f3c8SBram Moolenaar    try
1479b544f3c8SBram Moolenaar	call DefineFunction('T_Append', [
1480b544f3c8SBram Moolenaar		    \ 'append',
1481b544f3c8SBram Moolenaar		    \ 'abc',
1482b544f3c8SBram Moolenaar		    \ ])
148337175409SBram Moolenaar	call assert_report("Shouldn't be able to define function")
1484b544f3c8SBram Moolenaar    catch
1485b544f3c8SBram Moolenaar	call assert_exception('Vim(function):E126: Missing :endfunction')
1486b544f3c8SBram Moolenaar    endtry
1487b544f3c8SBram Moolenaar
1488b544f3c8SBram Moolenaar    " :change
1489b544f3c8SBram Moolenaar    try
1490b544f3c8SBram Moolenaar	call DefineFunction('T_Change', [
1491b544f3c8SBram Moolenaar		    \ 'change',
1492b544f3c8SBram Moolenaar		    \ 'py <<EOS',
1493b544f3c8SBram Moolenaar		    \ '.',
1494b544f3c8SBram Moolenaar		    \ ])
1495b544f3c8SBram Moolenaar    catch
149637175409SBram Moolenaar	call assert_report("Can't define function")
1497b544f3c8SBram Moolenaar    endtry
1498b544f3c8SBram Moolenaar    try
1499b544f3c8SBram Moolenaar	call DefineFunction('T_Change', [
1500b544f3c8SBram Moolenaar		    \ 'change',
1501b544f3c8SBram Moolenaar		    \ 'abc',
1502b544f3c8SBram Moolenaar		    \ ])
150337175409SBram Moolenaar	call assert_report("Shouldn't be able to define function")
1504b544f3c8SBram Moolenaar    catch
1505b544f3c8SBram Moolenaar	call assert_exception('Vim(function):E126: Missing :endfunction')
1506b544f3c8SBram Moolenaar    endtry
1507b544f3c8SBram Moolenaar
1508b544f3c8SBram Moolenaar    " :insert
1509b544f3c8SBram Moolenaar    try
1510b544f3c8SBram Moolenaar	call DefineFunction('T_Insert', [
1511b544f3c8SBram Moolenaar		    \ 'insert',
1512b544f3c8SBram Moolenaar		    \ 'py <<EOS',
1513b544f3c8SBram Moolenaar		    \ '.',
1514b544f3c8SBram Moolenaar		    \ ])
1515b544f3c8SBram Moolenaar    catch
151637175409SBram Moolenaar	call assert_report("Can't define function")
1517b544f3c8SBram Moolenaar    endtry
1518b544f3c8SBram Moolenaar    try
1519b544f3c8SBram Moolenaar	call DefineFunction('T_Insert', [
1520b544f3c8SBram Moolenaar		    \ 'insert',
1521b544f3c8SBram Moolenaar		    \ 'abc',
1522b544f3c8SBram Moolenaar		    \ ])
152337175409SBram Moolenaar	call assert_report("Shouldn't be able to define function")
1524b544f3c8SBram Moolenaar    catch
1525b544f3c8SBram Moolenaar	call assert_exception('Vim(function):E126: Missing :endfunction')
1526b544f3c8SBram Moolenaar    endtry
1527b544f3c8SBram Moolenaarendfunc
1528b544f3c8SBram Moolenaar
1529b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
1530478af67dSBram Moolenaar" Test 96:  line continuation						    {{{1
1531478af67dSBram Moolenaar"
1532478af67dSBram Moolenaar"	    Undefined behavior was detected by ubsan with line continuation
1533478af67dSBram Moolenaar"	    after an empty line.
1534478af67dSBram Moolenaar"-------------------------------------------------------------------------------
1535478af67dSBram Moolenaarfunc Test_script_emty_line_continuation()
1536478af67dSBram Moolenaar
1537478af67dSBram Moolenaar    \
1538478af67dSBram Moolenaarendfunc
1539478af67dSBram Moolenaar
1540478af67dSBram Moolenaar"-------------------------------------------------------------------------------
1541863e80b4SBram Moolenaar" Test 97:  bitwise functions						    {{{1
1542863e80b4SBram Moolenaar"-------------------------------------------------------------------------------
1543863e80b4SBram Moolenaarfunc Test_bitwise_functions()
1544863e80b4SBram Moolenaar    " and
1545863e80b4SBram Moolenaar    call assert_equal(127, and(127, 127))
1546863e80b4SBram Moolenaar    call assert_equal(16, and(127, 16))
1547073e4b92SBram Moolenaar    eval 127->and(16)->assert_equal(16)
1548863e80b4SBram Moolenaar    call assert_equal(0, and(127, 128))
1549863e80b4SBram Moolenaar    call assert_fails("call and([], 1)", 'E745:')
1550863e80b4SBram Moolenaar    call assert_fails("call and({}, 1)", 'E728:')
15515feabe00SBram Moolenaar    if has('float')
15525feabe00SBram Moolenaar      call assert_fails("call and(1.0, 1)", 'E805:')
1553863e80b4SBram Moolenaar      call assert_fails("call and(1, 1.0)", 'E805:')
15545feabe00SBram Moolenaar    endif
1555863e80b4SBram Moolenaar    call assert_fails("call and(1, [])", 'E745:')
1556863e80b4SBram Moolenaar    call assert_fails("call and(1, {})", 'E728:')
1557863e80b4SBram Moolenaar    " or
1558863e80b4SBram Moolenaar    call assert_equal(23, or(16, 7))
1559863e80b4SBram Moolenaar    call assert_equal(15, or(8, 7))
1560073e4b92SBram Moolenaar    eval 8->or(7)->assert_equal(15)
1561863e80b4SBram Moolenaar    call assert_equal(123, or(0, 123))
1562863e80b4SBram Moolenaar    call assert_fails("call or([], 1)", 'E745:')
1563863e80b4SBram Moolenaar    call assert_fails("call or({}, 1)", 'E728:')
15645feabe00SBram Moolenaar    if has('float')
15655feabe00SBram Moolenaar      call assert_fails("call or(1.0, 1)", 'E805:')
1566863e80b4SBram Moolenaar      call assert_fails("call or(1, 1.0)", 'E805:')
15675feabe00SBram Moolenaar    endif
1568863e80b4SBram Moolenaar    call assert_fails("call or(1, [])", 'E745:')
1569863e80b4SBram Moolenaar    call assert_fails("call or(1, {})", 'E728:')
1570863e80b4SBram Moolenaar    " xor
1571863e80b4SBram Moolenaar    call assert_equal(0, xor(127, 127))
1572863e80b4SBram Moolenaar    call assert_equal(111, xor(127, 16))
1573073e4b92SBram Moolenaar    eval 127->xor(16)->assert_equal(111)
1574863e80b4SBram Moolenaar    call assert_equal(255, xor(127, 128))
15755feabe00SBram Moolenaar    if has('float')
1576863e80b4SBram Moolenaar      call assert_fails("call xor(1.0, 1)", 'E805:')
15775feabe00SBram Moolenaar      call assert_fails("call xor(1, 1.0)", 'E805:')
15785feabe00SBram Moolenaar    endif
1579863e80b4SBram Moolenaar    call assert_fails("call xor([], 1)", 'E745:')
1580863e80b4SBram Moolenaar    call assert_fails("call xor({}, 1)", 'E728:')
1581863e80b4SBram Moolenaar    call assert_fails("call xor(1, [])", 'E745:')
1582863e80b4SBram Moolenaar    call assert_fails("call xor(1, {})", 'E728:')
1583863e80b4SBram Moolenaar    " invert
1584863e80b4SBram Moolenaar    call assert_equal(65408, and(invert(127), 65535))
1585073e4b92SBram Moolenaar    eval 127->invert()->and(65535)->assert_equal(65408)
1586863e80b4SBram Moolenaar    call assert_equal(65519, and(invert(16), 65535))
1587863e80b4SBram Moolenaar    call assert_equal(65407, and(invert(128), 65535))
15885feabe00SBram Moolenaar    if has('float')
1589863e80b4SBram Moolenaar      call assert_fails("call invert(1.0)", 'E805:')
15905feabe00SBram Moolenaar    endif
1591863e80b4SBram Moolenaar    call assert_fails("call invert([])", 'E745:')
1592863e80b4SBram Moolenaar    call assert_fails("call invert({})", 'E728:')
1593863e80b4SBram Moolenaarendfunc
1594863e80b4SBram Moolenaar
15956f9a476bSBram Moolenaar" Test using bang after user command				    {{{1
15966f9a476bSBram Moolenaarfunc Test_user_command_with_bang()
15976f9a476bSBram Moolenaar    command -bang Nieuw let nieuw = 1
15986f9a476bSBram Moolenaar    Ni!
15996f9a476bSBram Moolenaar    call assert_equal(1, nieuw)
16006f9a476bSBram Moolenaar    unlet nieuw
16016f9a476bSBram Moolenaar    delcommand Nieuw
16026f9a476bSBram Moolenaarendfunc
16036f9a476bSBram Moolenaar
1604b9adef79SBram Moolenaarfunc Test_script_expand_sfile()
1605b9adef79SBram Moolenaar  let lines =<< trim END
1606b9adef79SBram Moolenaar    func s:snr()
1607b9adef79SBram Moolenaar      return expand('<sfile>')
1608b9adef79SBram Moolenaar    endfunc
1609b9adef79SBram Moolenaar    let g:result = s:snr()
1610b9adef79SBram Moolenaar  END
1611b9adef79SBram Moolenaar  call writefile(lines, 'Xexpand')
1612b9adef79SBram Moolenaar  source Xexpand
1613b9adef79SBram Moolenaar  call assert_match('<SNR>\d\+_snr', g:result)
1614b9adef79SBram Moolenaar  source Xexpand
1615b9adef79SBram Moolenaar  call assert_match('<SNR>\d\+_snr', g:result)
1616b9adef79SBram Moolenaar
1617b9adef79SBram Moolenaar  call delete('Xexpand')
1618b9adef79SBram Moolenaar  unlet g:result
1619b9adef79SBram Moolenaarendfunc
1620b9adef79SBram Moolenaar
1621ff697e6cSBram Moolenaarfunc Test_compound_assignment_operators()
1622ff697e6cSBram Moolenaar    " Test for number
1623ff697e6cSBram Moolenaar    let x = 1
1624ff697e6cSBram Moolenaar    let x += 10
1625ff697e6cSBram Moolenaar    call assert_equal(11, x)
1626ff697e6cSBram Moolenaar    let x -= 5
1627ff697e6cSBram Moolenaar    call assert_equal(6, x)
1628ff697e6cSBram Moolenaar    let x *= 4
1629ff697e6cSBram Moolenaar    call assert_equal(24, x)
1630ff697e6cSBram Moolenaar    let x /= 3
1631ff697e6cSBram Moolenaar    call assert_equal(8, x)
1632ff697e6cSBram Moolenaar    let x %= 3
1633ff697e6cSBram Moolenaar    call assert_equal(2, x)
1634ff697e6cSBram Moolenaar    let x .= 'n'
1635ff697e6cSBram Moolenaar    call assert_equal('2n', x)
1636ff697e6cSBram Moolenaar
1637e21c1580SBram Moolenaar    " Test special cases: division or modulus with 0.
1638e21c1580SBram Moolenaar    let x = 1
1639e21c1580SBram Moolenaar    let x /= 0
1640e21c1580SBram Moolenaar    call assert_equal(0x7FFFFFFFFFFFFFFF, x)
1641e21c1580SBram Moolenaar
1642e21c1580SBram Moolenaar    let x = -1
1643e21c1580SBram Moolenaar    let x /= 0
1644e21c1580SBram Moolenaar    call assert_equal(-0x7FFFFFFFFFFFFFFF, x)
1645e21c1580SBram Moolenaar
1646e21c1580SBram Moolenaar    let x = 0
1647e21c1580SBram Moolenaar    let x /= 0
1648e21c1580SBram Moolenaar    call assert_equal(-0x7FFFFFFFFFFFFFFF - 1, x)
1649e21c1580SBram Moolenaar
1650e21c1580SBram Moolenaar    let x = 1
1651e21c1580SBram Moolenaar    let x %= 0
1652e21c1580SBram Moolenaar    call assert_equal(0, x)
1653e21c1580SBram Moolenaar
1654e21c1580SBram Moolenaar    let x = -1
1655e21c1580SBram Moolenaar    let x %= 0
1656e21c1580SBram Moolenaar    call assert_equal(0, x)
1657e21c1580SBram Moolenaar
1658e21c1580SBram Moolenaar    let x = 0
1659e21c1580SBram Moolenaar    let x %= 0
1660e21c1580SBram Moolenaar    call assert_equal(0, x)
1661e21c1580SBram Moolenaar
1662ff697e6cSBram Moolenaar    " Test for string
1663ff697e6cSBram Moolenaar    let x = 'str'
1664ff697e6cSBram Moolenaar    let x .= 'ing'
1665ff697e6cSBram Moolenaar    call assert_equal('string', x)
1666ff697e6cSBram Moolenaar    let x += 1
1667ff697e6cSBram Moolenaar    call assert_equal(1, x)
1668ff697e6cSBram Moolenaar
1669ff697e6cSBram Moolenaar    if has('float')
1670ff697e6cSBram Moolenaar      " Test for float
16715feabe00SBram Moolenaar      let x -= 1.5
16725feabe00SBram Moolenaar      call assert_equal(-0.5, x)
1673ff697e6cSBram Moolenaar      let x = 0.5
1674ff697e6cSBram Moolenaar      let x += 4.5
1675ff697e6cSBram Moolenaar      call assert_equal(5.0, x)
1676ff697e6cSBram Moolenaar      let x -= 1.5
1677ff697e6cSBram Moolenaar      call assert_equal(3.5, x)
1678ff697e6cSBram Moolenaar      let x *= 3.0
1679ff697e6cSBram Moolenaar      call assert_equal(10.5, x)
1680ff697e6cSBram Moolenaar      let x /= 2.5
1681ff697e6cSBram Moolenaar      call assert_equal(4.2, x)
1682ff697e6cSBram Moolenaar      call assert_fails('let x %= 0.5', 'E734')
1683ff697e6cSBram Moolenaar      call assert_fails('let x .= "f"', 'E734')
16848b633135SBram Moolenaar      let x = !3.14
16858b633135SBram Moolenaar      call assert_equal(0.0, x)
1686ea04a6e8SBram Moolenaar
1687ea04a6e8SBram Moolenaar      " integer and float operations
1688ea04a6e8SBram Moolenaar      let x = 1
1689ea04a6e8SBram Moolenaar      let x *= 2.1
1690ea04a6e8SBram Moolenaar      call assert_equal(2.1, x)
1691ea04a6e8SBram Moolenaar      let x = 1
1692ea04a6e8SBram Moolenaar      let x /= 0.25
1693ea04a6e8SBram Moolenaar      call assert_equal(4.0, x)
1694ea04a6e8SBram Moolenaar      let x = 1
1695ea04a6e8SBram Moolenaar      call assert_fails('let x %= 0.25', 'E734:')
1696ea04a6e8SBram Moolenaar      let x = 1
1697ea04a6e8SBram Moolenaar      call assert_fails('let x .= 0.25', 'E734:')
1698ea04a6e8SBram Moolenaar      let x = 1.0
1699ea04a6e8SBram Moolenaar      call assert_fails('let x += [1.1]', 'E734:')
1700ff697e6cSBram Moolenaar    endif
1701ff697e6cSBram Moolenaar
1702ff697e6cSBram Moolenaar    " Test for environment variable
1703ff697e6cSBram Moolenaar    let $FOO = 1
1704ff697e6cSBram Moolenaar    call assert_fails('let $FOO += 1', 'E734')
1705ff697e6cSBram Moolenaar    call assert_fails('let $FOO -= 1', 'E734')
1706ff697e6cSBram Moolenaar    call assert_fails('let $FOO *= 1', 'E734')
1707ff697e6cSBram Moolenaar    call assert_fails('let $FOO /= 1', 'E734')
1708ff697e6cSBram Moolenaar    call assert_fails('let $FOO %= 1', 'E734')
1709ff697e6cSBram Moolenaar    let $FOO .= 's'
1710ff697e6cSBram Moolenaar    call assert_equal('1s', $FOO)
1711ff697e6cSBram Moolenaar    unlet $FOO
1712ff697e6cSBram Moolenaar
1713ff697e6cSBram Moolenaar    " Test for option variable (type: number)
1714ff697e6cSBram Moolenaar    let &scrolljump = 1
1715ff697e6cSBram Moolenaar    let &scrolljump += 5
1716ff697e6cSBram Moolenaar    call assert_equal(6, &scrolljump)
1717ff697e6cSBram Moolenaar    let &scrolljump -= 2
1718ff697e6cSBram Moolenaar    call assert_equal(4, &scrolljump)
1719ff697e6cSBram Moolenaar    let &scrolljump *= 3
1720ff697e6cSBram Moolenaar    call assert_equal(12, &scrolljump)
1721ff697e6cSBram Moolenaar    let &scrolljump /= 2
1722ff697e6cSBram Moolenaar    call assert_equal(6, &scrolljump)
1723ff697e6cSBram Moolenaar    let &scrolljump %= 5
1724ff697e6cSBram Moolenaar    call assert_equal(1, &scrolljump)
1725ff697e6cSBram Moolenaar    call assert_fails('let &scrolljump .= "j"', 'E734')
1726ff697e6cSBram Moolenaar    set scrolljump&vim
1727ff697e6cSBram Moolenaar
1728ff697e6cSBram Moolenaar    " Test for register
1729ff697e6cSBram Moolenaar    let @/ = 1
1730ff697e6cSBram Moolenaar    call assert_fails('let @/ += 1', 'E734')
1731ff697e6cSBram Moolenaar    call assert_fails('let @/ -= 1', 'E734')
1732ff697e6cSBram Moolenaar    call assert_fails('let @/ *= 1', 'E734')
1733ff697e6cSBram Moolenaar    call assert_fails('let @/ /= 1', 'E734')
1734ff697e6cSBram Moolenaar    call assert_fails('let @/ %= 1', 'E734')
1735ff697e6cSBram Moolenaar    let @/ .= 's'
1736ff697e6cSBram Moolenaar    call assert_equal('1s', @/)
1737ff697e6cSBram Moolenaar    let @/ = ''
1738ff697e6cSBram Moolenaarendfunc
1739ff697e6cSBram Moolenaar
17407e0868efSBram Moolenaarfunc Test_unlet_env()
17417e0868efSBram Moolenaar  let $TESTVAR = 'yes'
17427e0868efSBram Moolenaar  call assert_equal('yes', $TESTVAR)
17437e0868efSBram Moolenaar  call assert_fails('lockvar $TESTVAR', 'E940')
17447e0868efSBram Moolenaar  call assert_fails('unlockvar $TESTVAR', 'E940')
17457e0868efSBram Moolenaar  call assert_equal('yes', $TESTVAR)
17467e0868efSBram Moolenaar  if 0
17477e0868efSBram Moolenaar    unlet $TESTVAR
17487e0868efSBram Moolenaar  endif
17497e0868efSBram Moolenaar  call assert_equal('yes', $TESTVAR)
17507e0868efSBram Moolenaar  unlet $TESTVAR
17517e0868efSBram Moolenaar  call assert_equal('', $TESTVAR)
17527e0868efSBram Moolenaarendfunc
17537e0868efSBram Moolenaar
1754c3e92c16SBram Moolenaarfunc Test_refcount()
1755c3e92c16SBram Moolenaar    " Immediate values
1756c3e92c16SBram Moolenaar    call assert_equal(-1, test_refcount(1))
1757c3e92c16SBram Moolenaar    call assert_equal(-1, test_refcount('s'))
1758c3e92c16SBram Moolenaar    call assert_equal(-1, test_refcount(v:true))
1759c3e92c16SBram Moolenaar    call assert_equal(0, test_refcount([]))
1760c3e92c16SBram Moolenaar    call assert_equal(0, test_refcount({}))
1761c3e92c16SBram Moolenaar    call assert_equal(0, test_refcount(0zff))
1762c3e92c16SBram Moolenaar    call assert_equal(0, test_refcount({-> line('.')}))
1763c3e92c16SBram Moolenaar    if has('float')
1764c3e92c16SBram Moolenaar        call assert_equal(-1, test_refcount(0.1))
1765c3e92c16SBram Moolenaar    endif
1766c3e92c16SBram Moolenaar    if has('job')
1767c3e92c16SBram Moolenaar        call assert_equal(0, test_refcount(job_start([&shell, &shellcmdflag, 'echo .'])))
1768c3e92c16SBram Moolenaar    endif
1769c3e92c16SBram Moolenaar
1770c3e92c16SBram Moolenaar    " No refcount types
1771c3e92c16SBram Moolenaar    let x = 1
1772c3e92c16SBram Moolenaar    call assert_equal(-1, test_refcount(x))
1773c3e92c16SBram Moolenaar    let x = 's'
1774c3e92c16SBram Moolenaar    call assert_equal(-1, test_refcount(x))
1775c3e92c16SBram Moolenaar    let x = v:true
1776c3e92c16SBram Moolenaar    call assert_equal(-1, test_refcount(x))
1777c3e92c16SBram Moolenaar    if has('float')
1778c3e92c16SBram Moolenaar        let x = 0.1
1779c3e92c16SBram Moolenaar        call assert_equal(-1, test_refcount(x))
1780c3e92c16SBram Moolenaar    endif
1781c3e92c16SBram Moolenaar
1782c3e92c16SBram Moolenaar    " Check refcount
1783c3e92c16SBram Moolenaar    let x = []
1784c3e92c16SBram Moolenaar    call assert_equal(1, test_refcount(x))
1785c3e92c16SBram Moolenaar
1786c3e92c16SBram Moolenaar    let x = {}
1787ce90e36fSBram Moolenaar    call assert_equal(1, x->test_refcount())
1788c3e92c16SBram Moolenaar
1789c3e92c16SBram Moolenaar    let x = 0zff
1790c3e92c16SBram Moolenaar    call assert_equal(1, test_refcount(x))
1791c3e92c16SBram Moolenaar
1792c3e92c16SBram Moolenaar    let X = {-> line('.')}
1793c3e92c16SBram Moolenaar    call assert_equal(1, test_refcount(X))
1794c3e92c16SBram Moolenaar    let Y = X
1795c3e92c16SBram Moolenaar    call assert_equal(2, test_refcount(X))
1796c3e92c16SBram Moolenaar
1797c3e92c16SBram Moolenaar    if has('job')
1798c3e92c16SBram Moolenaar        let job = job_start([&shell, &shellcmdflag, 'echo .'])
1799c3e92c16SBram Moolenaar        call assert_equal(1, test_refcount(job))
1800c3e92c16SBram Moolenaar        call assert_equal(1, test_refcount(job_getchannel(job)))
1801c3e92c16SBram Moolenaar        call assert_equal(1, test_refcount(job))
1802c3e92c16SBram Moolenaar    endif
1803c3e92c16SBram Moolenaar
1804c3e92c16SBram Moolenaar    " Function arguments, copying and unassigning
1805c3e92c16SBram Moolenaar    func ExprCheck(x, i)
1806c3e92c16SBram Moolenaar        let i = a:i + 1
1807c3e92c16SBram Moolenaar        call assert_equal(i, test_refcount(a:x))
1808c3e92c16SBram Moolenaar        let Y = a:x
1809c3e92c16SBram Moolenaar        call assert_equal(i + 1, test_refcount(a:x))
1810c3e92c16SBram Moolenaar        call assert_equal(test_refcount(a:x), test_refcount(Y))
1811c3e92c16SBram Moolenaar        let Y = 0
1812c3e92c16SBram Moolenaar        call assert_equal(i, test_refcount(a:x))
1813c3e92c16SBram Moolenaar    endfunc
1814c3e92c16SBram Moolenaar    call ExprCheck([], 0)
1815c3e92c16SBram Moolenaar    call ExprCheck({}, 0)
1816c3e92c16SBram Moolenaar    call ExprCheck(0zff, 0)
1817c3e92c16SBram Moolenaar    call ExprCheck({-> line('.')}, 0)
1818c3e92c16SBram Moolenaar    if has('job')
1819c3e92c16SBram Moolenaar	call ExprCheck(job, 1)
1820c3e92c16SBram Moolenaar	call ExprCheck(job_getchannel(job), 1)
1821c3e92c16SBram Moolenaar	call job_stop(job)
1822c3e92c16SBram Moolenaar    endif
1823c3e92c16SBram Moolenaar    delfunc ExprCheck
1824c3e92c16SBram Moolenaar
1825c3e92c16SBram Moolenaar    " Regarding function
1826c3e92c16SBram Moolenaar    func Func(x) abort
1827c3e92c16SBram Moolenaar        call assert_equal(2, test_refcount(function('Func')))
1828c3e92c16SBram Moolenaar        call assert_equal(0, test_refcount(funcref('Func')))
1829c3e92c16SBram Moolenaar    endfunc
1830c3e92c16SBram Moolenaar    call assert_equal(1, test_refcount(function('Func')))
1831c3e92c16SBram Moolenaar    call assert_equal(0, test_refcount(function('Func', [1])))
1832c3e92c16SBram Moolenaar    call assert_equal(0, test_refcount(funcref('Func')))
1833c3e92c16SBram Moolenaar    call assert_equal(0, test_refcount(funcref('Func', [1])))
1834c3e92c16SBram Moolenaar    let X = function('Func')
1835c3e92c16SBram Moolenaar    let Y = X
1836c3e92c16SBram Moolenaar    call assert_equal(1, test_refcount(X))
1837c3e92c16SBram Moolenaar    let X = function('Func', [1])
1838c3e92c16SBram Moolenaar    let Y = X
1839c3e92c16SBram Moolenaar    call assert_equal(2, test_refcount(X))
1840c3e92c16SBram Moolenaar    let X = funcref('Func')
1841c3e92c16SBram Moolenaar    let Y = X
1842c3e92c16SBram Moolenaar    call assert_equal(2, test_refcount(X))
1843c3e92c16SBram Moolenaar    let X = funcref('Func', [1])
1844c3e92c16SBram Moolenaar    let Y = X
1845c3e92c16SBram Moolenaar    call assert_equal(2, test_refcount(X))
1846c3e92c16SBram Moolenaar    unlet X
1847c3e92c16SBram Moolenaar    unlet Y
1848c3e92c16SBram Moolenaar    call Func(1)
1849c3e92c16SBram Moolenaar    delfunc Func
1850c3e92c16SBram Moolenaar
1851c3e92c16SBram Moolenaar    " Function with dict
1852c3e92c16SBram Moolenaar    func DictFunc() dict
1853c3e92c16SBram Moolenaar        call assert_equal(3, test_refcount(self))
1854c3e92c16SBram Moolenaar    endfunc
1855c3e92c16SBram Moolenaar    let d = {'Func': function('DictFunc')}
1856c3e92c16SBram Moolenaar    call assert_equal(1, test_refcount(d))
1857c3e92c16SBram Moolenaar    call assert_equal(0, test_refcount(d.Func))
1858c3e92c16SBram Moolenaar    call d.Func()
1859c3e92c16SBram Moolenaar    unlet d
1860c3e92c16SBram Moolenaar    delfunc DictFunc
1861c3e92c16SBram Moolenaarendfunc
1862c3e92c16SBram Moolenaar
18639f6277bdSBram Moolenaar" Test for missing :endif, :endfor, :endwhile and :endtry           {{{1
18649f6277bdSBram Moolenaarfunc Test_missing_end()
18659f6277bdSBram Moolenaar  call writefile(['if 2 > 1', 'echo ">"'], 'Xscript')
18669f6277bdSBram Moolenaar  call assert_fails('source Xscript', 'E171:')
18679f6277bdSBram Moolenaar  call writefile(['for i in range(5)', 'echo i'], 'Xscript')
18689f6277bdSBram Moolenaar  call assert_fails('source Xscript', 'E170:')
18699f6277bdSBram Moolenaar  call writefile(['while v:true', 'echo "."'], 'Xscript')
18709f6277bdSBram Moolenaar  call assert_fails('source Xscript', 'E170:')
18719f6277bdSBram Moolenaar  call writefile(['try', 'echo "."'], 'Xscript')
18729f6277bdSBram Moolenaar  call assert_fails('source Xscript', 'E600:')
18739f6277bdSBram Moolenaar  call delete('Xscript')
1874818fc9adSBram Moolenaar
1875818fc9adSBram Moolenaar  " Using endfor with :while
1876818fc9adSBram Moolenaar  let caught_e732 = 0
1877818fc9adSBram Moolenaar  try
1878818fc9adSBram Moolenaar    while v:true
1879818fc9adSBram Moolenaar    endfor
1880818fc9adSBram Moolenaar  catch /E732:/
1881818fc9adSBram Moolenaar    let caught_e732 = 1
1882818fc9adSBram Moolenaar  endtry
1883818fc9adSBram Moolenaar  call assert_equal(1, caught_e732)
1884818fc9adSBram Moolenaar
1885818fc9adSBram Moolenaar  " Using endwhile with :for
1886818fc9adSBram Moolenaar  let caught_e733 = 0
1887818fc9adSBram Moolenaar  try
1888818fc9adSBram Moolenaar    for i in range(1)
1889818fc9adSBram Moolenaar    endwhile
1890818fc9adSBram Moolenaar  catch /E733:/
1891818fc9adSBram Moolenaar    let caught_e733 = 1
1892818fc9adSBram Moolenaar  endtry
1893818fc9adSBram Moolenaar  call assert_equal(1, caught_e733)
1894818fc9adSBram Moolenaar
1895ee4e0c1eSBram Moolenaar  " Using endfunc with :if
1896ee4e0c1eSBram Moolenaar  call assert_fails('exe "if 1 | endfunc | endif"', 'E193:')
1897ee4e0c1eSBram Moolenaar
1898818fc9adSBram Moolenaar  " Missing 'in' in a :for statement
1899818fc9adSBram Moolenaar  call assert_fails('for i range(1) | endfor', 'E690:')
1900ea04a6e8SBram Moolenaar
1901ea04a6e8SBram Moolenaar  " Incorrect number of variables in for
1902ea04a6e8SBram Moolenaar  call assert_fails('for [i,] in range(3) | endfor', 'E475:')
19039f6277bdSBram Moolenaarendfunc
19049f6277bdSBram Moolenaar
19059f6277bdSBram Moolenaar" Test for deep nesting of if/for/while/try statements              {{{1
19069f6277bdSBram Moolenaarfunc Test_deep_nest()
19079f6277bdSBram Moolenaar  if !CanRunVimInTerminal()
19089f6277bdSBram Moolenaar    throw 'Skipped: cannot run vim in terminal'
19099f6277bdSBram Moolenaar  endif
19109f6277bdSBram Moolenaar
19119f6277bdSBram Moolenaar  let lines =<< trim [SCRIPT]
19129f6277bdSBram Moolenaar    " Deep nesting of if ... endif
19139f6277bdSBram Moolenaar    func Test1()
19149f6277bdSBram Moolenaar      let @a = join(repeat(['if v:true'], 51), "\n")
19159f6277bdSBram Moolenaar      let @a ..= "\n"
19169f6277bdSBram Moolenaar      let @a ..= join(repeat(['endif'], 51), "\n")
19179f6277bdSBram Moolenaar      @a
19189f6277bdSBram Moolenaar      let @a = ''
19199f6277bdSBram Moolenaar    endfunc
19209f6277bdSBram Moolenaar
19219f6277bdSBram Moolenaar    " Deep nesting of for ... endfor
19229f6277bdSBram Moolenaar    func Test2()
19239f6277bdSBram Moolenaar      let @a = join(repeat(['for i in [1]'], 51), "\n")
19249f6277bdSBram Moolenaar      let @a ..= "\n"
19259f6277bdSBram Moolenaar      let @a ..= join(repeat(['endfor'], 51), "\n")
19269f6277bdSBram Moolenaar      @a
19279f6277bdSBram Moolenaar      let @a = ''
19289f6277bdSBram Moolenaar    endfunc
19299f6277bdSBram Moolenaar
19309f6277bdSBram Moolenaar    " Deep nesting of while ... endwhile
19319f6277bdSBram Moolenaar    func Test3()
19329f6277bdSBram Moolenaar      let @a = join(repeat(['while v:true'], 51), "\n")
19339f6277bdSBram Moolenaar      let @a ..= "\n"
19349f6277bdSBram Moolenaar      let @a ..= join(repeat(['endwhile'], 51), "\n")
19359f6277bdSBram Moolenaar      @a
19369f6277bdSBram Moolenaar      let @a = ''
19379f6277bdSBram Moolenaar    endfunc
19389f6277bdSBram Moolenaar
19399f6277bdSBram Moolenaar    " Deep nesting of try ... endtry
19409f6277bdSBram Moolenaar    func Test4()
19419f6277bdSBram Moolenaar      let @a = join(repeat(['try'], 51), "\n")
19429f6277bdSBram Moolenaar      let @a ..= "\necho v:true\n"
19439f6277bdSBram Moolenaar      let @a ..= join(repeat(['endtry'], 51), "\n")
19449f6277bdSBram Moolenaar      @a
19459f6277bdSBram Moolenaar      let @a = ''
19469f6277bdSBram Moolenaar    endfunc
1947ee4e0c1eSBram Moolenaar
1948ee4e0c1eSBram Moolenaar    " Deep nesting of function ... endfunction
1949ee4e0c1eSBram Moolenaar    func Test5()
1950ee4e0c1eSBram Moolenaar      let @a = join(repeat(['function X()'], 51), "\n")
1951ee4e0c1eSBram Moolenaar      let @a ..= "\necho v:true\n"
1952ee4e0c1eSBram Moolenaar      let @a ..= join(repeat(['endfunction'], 51), "\n")
1953ee4e0c1eSBram Moolenaar      @a
1954ee4e0c1eSBram Moolenaar      let @a = ''
1955ee4e0c1eSBram Moolenaar    endfunc
19569f6277bdSBram Moolenaar  [SCRIPT]
19579f6277bdSBram Moolenaar  call writefile(lines, 'Xscript')
19589f6277bdSBram Moolenaar
19599f6277bdSBram Moolenaar  let buf = RunVimInTerminal('-S Xscript', {'rows': 6})
19609f6277bdSBram Moolenaar
19619f6277bdSBram Moolenaar  " Deep nesting of if ... endif
19629f6277bdSBram Moolenaar  call term_sendkeys(buf, ":call Test1()\n")
19636a2c5a7dSBram Moolenaar  call TermWait(buf)
19649f6277bdSBram Moolenaar  call WaitForAssert({-> assert_match('^E579:', term_getline(buf, 5))})
19659f6277bdSBram Moolenaar
19669f6277bdSBram Moolenaar  " Deep nesting of for ... endfor
19679f6277bdSBram Moolenaar  call term_sendkeys(buf, ":call Test2()\n")
19686a2c5a7dSBram Moolenaar  call TermWait(buf)
19699f6277bdSBram Moolenaar  call WaitForAssert({-> assert_match('^E585:', term_getline(buf, 5))})
19709f6277bdSBram Moolenaar
19719f6277bdSBram Moolenaar  " Deep nesting of while ... endwhile
19729f6277bdSBram Moolenaar  call term_sendkeys(buf, ":call Test3()\n")
19736a2c5a7dSBram Moolenaar  call TermWait(buf)
19749f6277bdSBram Moolenaar  call WaitForAssert({-> assert_match('^E585:', term_getline(buf, 5))})
19759f6277bdSBram Moolenaar
19769f6277bdSBram Moolenaar  " Deep nesting of try ... endtry
19779f6277bdSBram Moolenaar  call term_sendkeys(buf, ":call Test4()\n")
19786a2c5a7dSBram Moolenaar  call TermWait(buf)
19799f6277bdSBram Moolenaar  call WaitForAssert({-> assert_match('^E601:', term_getline(buf, 5))})
19809f6277bdSBram Moolenaar
1981ee4e0c1eSBram Moolenaar  " Deep nesting of function ... endfunction
1982ee4e0c1eSBram Moolenaar  call term_sendkeys(buf, ":call Test5()\n")
19836a2c5a7dSBram Moolenaar  call TermWait(buf)
1984ee4e0c1eSBram Moolenaar  call WaitForAssert({-> assert_match('^E1058:', term_getline(buf, 4))})
1985ee4e0c1eSBram Moolenaar  call term_sendkeys(buf, "\<C-C>\n")
19866a2c5a7dSBram Moolenaar  call TermWait(buf)
1987ee4e0c1eSBram Moolenaar
19889f6277bdSBram Moolenaar  "let l = ''
19899f6277bdSBram Moolenaar  "for i in range(1, 6)
19909f6277bdSBram Moolenaar  "  let l ..= term_getline(buf, i) . "\n"
19919f6277bdSBram Moolenaar  "endfor
19929f6277bdSBram Moolenaar  "call assert_report(l)
19939f6277bdSBram Moolenaar
19949f6277bdSBram Moolenaar  call StopVimInTerminal(buf)
19959f6277bdSBram Moolenaar  call delete('Xscript')
19969f6277bdSBram Moolenaarendfunc
19979f6277bdSBram Moolenaar
19988b633135SBram Moolenaar" Test for errors in converting to float from various types         {{{1
19998b633135SBram Moolenaarfunc Test_float_conversion_errors()
20008b633135SBram Moolenaar  if has('float')
20018b633135SBram Moolenaar    call assert_fails('let x = 4.0 % 2.0', 'E804')
20028b633135SBram Moolenaar    call assert_fails('echo 1.1[0]', 'E806')
20038b633135SBram Moolenaar    call assert_fails('echo sort([function("min"), 1], "f")', 'E891:')
20048b633135SBram Moolenaar    call assert_fails('echo 3.2 == "vim"', 'E892:')
20058b633135SBram Moolenaar    call assert_fails('echo sort([[], 1], "f")', 'E893:')
20068b633135SBram Moolenaar    call assert_fails('echo sort([{}, 1], "f")', 'E894:')
20078b633135SBram Moolenaar    call assert_fails('echo 3.2 == v:true', 'E362:')
20088b633135SBram Moolenaar    call assert_fails('echo 3.2 == v:none', 'E907:')
20098b633135SBram Moolenaar  endif
20108b633135SBram Moolenaarendfunc
20118b633135SBram Moolenaar
201208f4157cSBram Moolenaarfunc Test_invalid_function_names()
201308f4157cSBram Moolenaar  " function name not starting with capital
201408f4157cSBram Moolenaar  let caught_e128 = 0
201508f4157cSBram Moolenaar  try
201608f4157cSBram Moolenaar    func! g:test()
201708f4157cSBram Moolenaar      echo "test"
201808f4157cSBram Moolenaar    endfunc
201908f4157cSBram Moolenaar  catch /E128:/
202008f4157cSBram Moolenaar    let caught_e128 = 1
202108f4157cSBram Moolenaar  endtry
202208f4157cSBram Moolenaar  call assert_equal(1, caught_e128)
202308f4157cSBram Moolenaar
202408f4157cSBram Moolenaar  " function name includes a colon
202508f4157cSBram Moolenaar  let caught_e884 = 0
202608f4157cSBram Moolenaar  try
202708f4157cSBram Moolenaar    func! b:test()
202808f4157cSBram Moolenaar      echo "test"
202908f4157cSBram Moolenaar    endfunc
203008f4157cSBram Moolenaar  catch /E884:/
203108f4157cSBram Moolenaar    let caught_e884 = 1
203208f4157cSBram Moolenaar  endtry
203308f4157cSBram Moolenaar  call assert_equal(1, caught_e884)
203408f4157cSBram Moolenaar
203508f4157cSBram Moolenaar  " function name folowed by #
203608f4157cSBram Moolenaar  let caught_e128 = 0
203708f4157cSBram Moolenaar  try
203808f4157cSBram Moolenaar    func! test2() "#
203908f4157cSBram Moolenaar      echo "test2"
204008f4157cSBram Moolenaar    endfunc
204108f4157cSBram Moolenaar  catch /E128:/
204208f4157cSBram Moolenaar    let caught_e128 = 1
204308f4157cSBram Moolenaar  endtry
204408f4157cSBram Moolenaar  call assert_equal(1, caught_e128)
204508f4157cSBram Moolenaar
204608f4157cSBram Moolenaar  " function name starting with/without "g:", buffer-local funcref.
204708f4157cSBram Moolenaar  function! g:Foo(n)
204808f4157cSBram Moolenaar    return 'called Foo(' . a:n . ')'
204908f4157cSBram Moolenaar  endfunction
205008f4157cSBram Moolenaar  let b:my_func = function('Foo')
205108f4157cSBram Moolenaar  call assert_equal('called Foo(1)', b:my_func(1))
205208f4157cSBram Moolenaar  call assert_equal('called Foo(2)', g:Foo(2))
205308f4157cSBram Moolenaar  call assert_equal('called Foo(3)', Foo(3))
205408f4157cSBram Moolenaar  delfunc g:Foo
205508f4157cSBram Moolenaar
205608f4157cSBram Moolenaar  " script-local function used in Funcref must exist.
205708f4157cSBram Moolenaar  let lines =<< trim END
205808f4157cSBram Moolenaar    func s:Testje()
205908f4157cSBram Moolenaar      return "foo"
206008f4157cSBram Moolenaar    endfunc
206108f4157cSBram Moolenaar    let Bar = function('s:Testje')
206208f4157cSBram Moolenaar    call assert_equal(0, exists('s:Testje'))
206308f4157cSBram Moolenaar    call assert_equal(1, exists('*s:Testje'))
206408f4157cSBram Moolenaar    call assert_equal(1, exists('Bar'))
206508f4157cSBram Moolenaar    call assert_equal(1, exists('*Bar'))
206608f4157cSBram Moolenaar  END
206708f4157cSBram Moolenaar  call writefile(lines, 'Xscript')
206808f4157cSBram Moolenaar  source Xscript
206908f4157cSBram Moolenaar  call delete('Xscript')
207008f4157cSBram Moolenaarendfunc
207108f4157cSBram Moolenaar
207208f4157cSBram Moolenaar" substring and variable name
207308f4157cSBram Moolenaarfunc Test_substring_var()
207408f4157cSBram Moolenaar  let str = 'abcdef'
207508f4157cSBram Moolenaar  let n = 3
207608f4157cSBram Moolenaar  call assert_equal('def', str[n:])
207708f4157cSBram Moolenaar  call assert_equal('abcd', str[:n])
207808f4157cSBram Moolenaar  call assert_equal('d', str[n:n])
207908f4157cSBram Moolenaar  unlet n
208008f4157cSBram Moolenaar  let nn = 3
208108f4157cSBram Moolenaar  call assert_equal('def', str[nn:])
208208f4157cSBram Moolenaar  call assert_equal('abcd', str[:nn])
208308f4157cSBram Moolenaar  call assert_equal('d', str[nn:nn])
208408f4157cSBram Moolenaar  unlet nn
208508f4157cSBram Moolenaar  let b:nn = 4
208608f4157cSBram Moolenaar  call assert_equal('ef', str[b:nn:])
208708f4157cSBram Moolenaar  call assert_equal('abcde', str[:b:nn])
208808f4157cSBram Moolenaar  call assert_equal('e', str[b:nn:b:nn])
208908f4157cSBram Moolenaar  unlet b:nn
209008f4157cSBram Moolenaarendfunc
209108f4157cSBram Moolenaar
2092863e80b4SBram Moolenaar"-------------------------------------------------------------------------------
2093b544f3c8SBram Moolenaar" Modelines								    {{{1
20941f068233SBram Moolenaar" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
2095b544f3c8SBram Moolenaar"-------------------------------------------------------------------------------
2096