153f0c962SBram Moolenaar" Test for user functions.
253f0c962SBram Moolenaar" Also test an <expr> mapping calling a function.
353f0c962SBram Moolenaar" Also test that a builtin function cannot be replaced.
453f0c962SBram Moolenaar" Also test for regression when calling arbitrary expression.
553f0c962SBram Moolenaar
6476a6131SBram Moolenaarsource check.vim
7476a6131SBram Moolenaarsource shared.vim
8476a6131SBram Moolenaar
953f0c962SBram Moolenaarfunc Table(title, ...)
1053f0c962SBram Moolenaar  let ret = a:title
1153f0c962SBram Moolenaar  let idx = 1
1253f0c962SBram Moolenaar  while idx <= a:0
1353f0c962SBram Moolenaar    exe "let ret = ret . a:" . idx
1453f0c962SBram Moolenaar    let idx = idx + 1
1553f0c962SBram Moolenaar  endwhile
1653f0c962SBram Moolenaar  return ret
1753f0c962SBram Moolenaarendfunc
1853f0c962SBram Moolenaar
1953f0c962SBram Moolenaarfunc Compute(n1, n2, divname)
2053f0c962SBram Moolenaar  if a:n2 == 0
2153f0c962SBram Moolenaar    return "fail"
2253f0c962SBram Moolenaar  endif
2353f0c962SBram Moolenaar  exe "let g:" . a:divname . " = ". a:n1 / a:n2
2453f0c962SBram Moolenaar  return "ok"
2553f0c962SBram Moolenaarendfunc
2653f0c962SBram Moolenaar
2753f0c962SBram Moolenaarfunc Expr1()
2853f0c962SBram Moolenaar  silent! normal! v
2953f0c962SBram Moolenaar  return "111"
3053f0c962SBram Moolenaarendfunc
3153f0c962SBram Moolenaar
3253f0c962SBram Moolenaarfunc Expr2()
3353f0c962SBram Moolenaar  call search('XX', 'b')
3453f0c962SBram Moolenaar  return "222"
3553f0c962SBram Moolenaarendfunc
3653f0c962SBram Moolenaar
3753f0c962SBram Moolenaarfunc ListItem()
3853f0c962SBram Moolenaar  let g:counter += 1
3953f0c962SBram Moolenaar  return g:counter . '. '
4053f0c962SBram Moolenaarendfunc
4153f0c962SBram Moolenaar
4253f0c962SBram Moolenaarfunc ListReset()
4353f0c962SBram Moolenaar  let g:counter = 0
4453f0c962SBram Moolenaar  return ''
4553f0c962SBram Moolenaarendfunc
4653f0c962SBram Moolenaar
4753f0c962SBram Moolenaarfunc FuncWithRef(a)
4853f0c962SBram Moolenaar  unlet g:FuncRef
4953f0c962SBram Moolenaar  return a:a
5053f0c962SBram Moolenaarendfunc
5153f0c962SBram Moolenaar
5253f0c962SBram Moolenaarfunc Test_user_func()
5353f0c962SBram Moolenaar  let g:FuncRef = function("FuncWithRef")
5453f0c962SBram Moolenaar  let g:counter = 0
5553f0c962SBram Moolenaar  inoremap <expr> ( ListItem()
5653f0c962SBram Moolenaar  inoremap <expr> [ ListReset()
5753f0c962SBram Moolenaar  imap <expr> + Expr1()
5853f0c962SBram Moolenaar  imap <expr> * Expr2()
5953f0c962SBram Moolenaar  let g:retval = "nop"
6053f0c962SBram Moolenaar
6153f0c962SBram Moolenaar  call assert_equal('xxx4asdf', Table("xxx", 4, "asdf"))
6253f0c962SBram Moolenaar  call assert_equal('fail', Compute(45, 0, "retval"))
6353f0c962SBram Moolenaar  call assert_equal('nop', g:retval)
6453f0c962SBram Moolenaar  call assert_equal('ok', Compute(45, 5, "retval"))
6553f0c962SBram Moolenaar  call assert_equal(9, g:retval)
6653f0c962SBram Moolenaar  call assert_equal(333, g:FuncRef(333))
6753f0c962SBram Moolenaar
68fcfe1a9bSBram Moolenaar  let g:retval = "nop"
69fcfe1a9bSBram Moolenaar  call assert_equal('xxx4asdf', "xxx"->Table(4, "asdf"))
70fcfe1a9bSBram Moolenaar  call assert_equal('fail', 45->Compute(0, "retval"))
71fcfe1a9bSBram Moolenaar  call assert_equal('nop', g:retval)
72fcfe1a9bSBram Moolenaar  call assert_equal('ok', 45->Compute(5, "retval"))
73fcfe1a9bSBram Moolenaar  call assert_equal(9, g:retval)
74fcfe1a9bSBram Moolenaar  " call assert_equal(333, 333->g:FuncRef())
75fcfe1a9bSBram Moolenaar
7653f0c962SBram Moolenaar  enew
7753f0c962SBram Moolenaar
7853f0c962SBram Moolenaar  normal oXX+-XX
7953f0c962SBram Moolenaar  call assert_equal('XX111-XX', getline('.'))
8053f0c962SBram Moolenaar  normal o---*---
8153f0c962SBram Moolenaar  call assert_equal('---222---', getline('.'))
8253f0c962SBram Moolenaar  normal o(one
8353f0c962SBram Moolenaar  call assert_equal('1. one', getline('.'))
8453f0c962SBram Moolenaar  normal o(two
8553f0c962SBram Moolenaar  call assert_equal('2. two', getline('.'))
8653f0c962SBram Moolenaar  normal o[(one again
8753f0c962SBram Moolenaar  call assert_equal('1. one again', getline('.'))
8853f0c962SBram Moolenaar
89476a6131SBram Moolenaar  " Try to overwrite a function in the global (g:) scope
9053f0c962SBram Moolenaar  call assert_equal(3, max([1, 2, 3]))
91e2e4075fSBram Moolenaar  call assert_fails("call extend(g:, {'max': function('min')})", 'E704:')
9253f0c962SBram Moolenaar  call assert_equal(3, max([1, 2, 3]))
9353f0c962SBram Moolenaar
948dfcce3aSBram Moolenaar  " Try to overwrite an user defined function with a function reference
958dfcce3aSBram Moolenaar  call assert_fails("let Expr1 = function('min')", 'E705:')
968dfcce3aSBram Moolenaar
9753f0c962SBram Moolenaar  " Regression: the first line below used to throw ?E110: Missing ')'?
9853f0c962SBram Moolenaar  " Second is here just to prove that this line is correct when not skipping
9953f0c962SBram Moolenaar  " rhs of &&.
10053f0c962SBram Moolenaar  call assert_equal(0, (0 && (function('tr'))(1, 2, 3)))
10153f0c962SBram Moolenaar  call assert_equal(1, (1 && (function('tr'))(1, 2, 3)))
10253f0c962SBram Moolenaar
10353f0c962SBram Moolenaar  delfunc Table
10453f0c962SBram Moolenaar  delfunc Compute
10553f0c962SBram Moolenaar  delfunc Expr1
10653f0c962SBram Moolenaar  delfunc Expr2
10753f0c962SBram Moolenaar  delfunc ListItem
10853f0c962SBram Moolenaar  delfunc ListReset
10953f0c962SBram Moolenaar  unlet g:retval g:counter
11053f0c962SBram Moolenaar  enew!
11153f0c962SBram Moolenaarendfunc
11242ae78cfSBram Moolenaar
11342ae78cfSBram Moolenaarfunc Log(val, base = 10)
11442ae78cfSBram Moolenaar  return log(a:val) / log(a:base)
11542ae78cfSBram Moolenaarendfunc
11642ae78cfSBram Moolenaar
11742ae78cfSBram Moolenaarfunc Args(mandatory, optional = v:null, ...)
11842ae78cfSBram Moolenaar  return deepcopy(a:)
11942ae78cfSBram Moolenaarendfunc
12042ae78cfSBram Moolenaar
12142ae78cfSBram Moolenaarfunc Args2(a = 1, b = 2, c = 3)
12242ae78cfSBram Moolenaar  return deepcopy(a:)
12342ae78cfSBram Moolenaarendfunc
12442ae78cfSBram Moolenaar
12542ae78cfSBram Moolenaarfunc MakeBadFunc()
12642ae78cfSBram Moolenaar  func s:fcn(a, b=1, c)
12742ae78cfSBram Moolenaar  endfunc
12842ae78cfSBram Moolenaarendfunc
12942ae78cfSBram Moolenaar
13042ae78cfSBram Moolenaarfunc Test_default_arg()
1315feabe00SBram Moolenaar  if has('float')
13242ae78cfSBram Moolenaar    call assert_equal(1.0, Log(10))
13342ae78cfSBram Moolenaar    call assert_equal(log(10), Log(10, exp(1)))
134e2e4075fSBram Moolenaar    call assert_fails("call Log(1,2,3)", 'E118:')
1355feabe00SBram Moolenaar  endif
13642ae78cfSBram Moolenaar
13742ae78cfSBram Moolenaar  let res = Args(1)
13842ae78cfSBram Moolenaar  call assert_equal(res.mandatory, 1)
13942ae78cfSBram Moolenaar  call assert_equal(res.optional, v:null)
14042ae78cfSBram Moolenaar  call assert_equal(res['0'], 0)
14142ae78cfSBram Moolenaar
14242ae78cfSBram Moolenaar  let res = Args(1,2)
14342ae78cfSBram Moolenaar  call assert_equal(res.mandatory, 1)
14442ae78cfSBram Moolenaar  call assert_equal(res.optional, 2)
14542ae78cfSBram Moolenaar  call assert_equal(res['0'], 0)
14642ae78cfSBram Moolenaar
14742ae78cfSBram Moolenaar  let res = Args(1,2,3)
14842ae78cfSBram Moolenaar  call assert_equal(res.mandatory, 1)
14942ae78cfSBram Moolenaar  call assert_equal(res.optional, 2)
15042ae78cfSBram Moolenaar  call assert_equal(res['0'], 1)
15142ae78cfSBram Moolenaar
152e2e4075fSBram Moolenaar  call assert_fails("call MakeBadFunc()", 'E989:')
153e9b8b78eSBram Moolenaar  call assert_fails("fu F(a=1 ,) | endf", 'E1068:')
15442ae78cfSBram Moolenaar
15542ae78cfSBram Moolenaar  let d = Args2(7, v:none, 9)
15642ae78cfSBram Moolenaar  call assert_equal([7, 2, 9], [d.a, d.b, d.c])
15742ae78cfSBram Moolenaar
15842ae78cfSBram Moolenaar  call assert_equal("\n"
15942ae78cfSBram Moolenaar	\ .. "   function Args2(a = 1, b = 2, c = 3)\n"
16042ae78cfSBram Moolenaar	\ .. "1    return deepcopy(a:)\n"
16142ae78cfSBram Moolenaar	\ .. "   endfunction",
16242ae78cfSBram Moolenaar	\ execute('func Args2'))
16334fcb697SYegappan Lakshmanan
16434fcb697SYegappan Lakshmanan  " Error in default argument expression
16534fcb697SYegappan Lakshmanan  let l =<< trim END
16634fcb697SYegappan Lakshmanan    func F1(x = y)
16734fcb697SYegappan Lakshmanan      return a:x * 2
16834fcb697SYegappan Lakshmanan    endfunc
16934fcb697SYegappan Lakshmanan    echo F1()
17034fcb697SYegappan Lakshmanan  END
17134fcb697SYegappan Lakshmanan  let @a = l->join("\n")
17234fcb697SYegappan Lakshmanan  call assert_fails("exe @a", 'E121:')
17342ae78cfSBram Moolenaarendfunc
174fcfe1a9bSBram Moolenaar
175fcfe1a9bSBram Moolenaarfunc s:addFoo(lead)
176fcfe1a9bSBram Moolenaar  return a:lead .. 'foo'
177fcfe1a9bSBram Moolenaarendfunc
178fcfe1a9bSBram Moolenaar
179fcfe1a9bSBram Moolenaarfunc Test_user_method()
180fcfe1a9bSBram Moolenaar  eval 'bar'->s:addFoo()->assert_equal('barfoo')
181fcfe1a9bSBram Moolenaarendfunc
182e51bb17dSBram Moolenaar
183e51bb17dSBram Moolenaarfunc Test_failed_call_in_try()
184e51bb17dSBram Moolenaar  try | call UnknownFunc() | catch | endtry
185e51bb17dSBram Moolenaarendfunc
186ee4e0c1eSBram Moolenaar
187ee4e0c1eSBram Moolenaar" Test for listing user-defined functions
188ee4e0c1eSBram Moolenaarfunc Test_function_list()
189ee4e0c1eSBram Moolenaar  call assert_fails("function Xabc", 'E123:')
190ee4e0c1eSBram Moolenaarendfunc
191ee4e0c1eSBram Moolenaar
192476a6131SBram Moolenaar" Test for <sfile>, <slnum> in a function
193476a6131SBram Moolenaarfunc Test_sfile_in_function()
194476a6131SBram Moolenaar  func Xfunc()
195476a6131SBram Moolenaar    call assert_match('..Test_sfile_in_function\[5]..Xfunc', expand('<sfile>'))
196476a6131SBram Moolenaar    call assert_equal('2', expand('<slnum>'))
197476a6131SBram Moolenaar  endfunc
198476a6131SBram Moolenaar  call Xfunc()
199476a6131SBram Moolenaar  delfunc Xfunc
200476a6131SBram Moolenaarendfunc
201476a6131SBram Moolenaar
202476a6131SBram Moolenaar" Test trailing text after :endfunction				    {{{1
203476a6131SBram Moolenaarfunc Test_endfunction_trailing()
204476a6131SBram Moolenaar  call assert_false(exists('*Xtest'))
205476a6131SBram Moolenaar
206476a6131SBram Moolenaar  exe "func Xtest()\necho 'hello'\nendfunc\nlet done = 'yes'"
207476a6131SBram Moolenaar  call assert_true(exists('*Xtest'))
208476a6131SBram Moolenaar  call assert_equal('yes', done)
209476a6131SBram Moolenaar  delfunc Xtest
210476a6131SBram Moolenaar  unlet done
211476a6131SBram Moolenaar
212476a6131SBram Moolenaar  exe "func Xtest()\necho 'hello'\nendfunc|let done = 'yes'"
213476a6131SBram Moolenaar  call assert_true(exists('*Xtest'))
214476a6131SBram Moolenaar  call assert_equal('yes', done)
215476a6131SBram Moolenaar  delfunc Xtest
216476a6131SBram Moolenaar  unlet done
217476a6131SBram Moolenaar
218476a6131SBram Moolenaar  " trailing line break
219476a6131SBram Moolenaar  exe "func Xtest()\necho 'hello'\nendfunc\n"
220476a6131SBram Moolenaar  call assert_true(exists('*Xtest'))
221476a6131SBram Moolenaar  delfunc Xtest
222476a6131SBram Moolenaar
223476a6131SBram Moolenaar  set verbose=1
224476a6131SBram Moolenaar  exe "func Xtest()\necho 'hello'\nendfunc \" garbage"
225476a6131SBram Moolenaar  call assert_notmatch('W22:', split(execute('1messages'), "\n")[0])
226476a6131SBram Moolenaar  call assert_true(exists('*Xtest'))
227476a6131SBram Moolenaar  delfunc Xtest
228476a6131SBram Moolenaar
229476a6131SBram Moolenaar  exe "func Xtest()\necho 'hello'\nendfunc garbage"
230476a6131SBram Moolenaar  call assert_match('W22:', split(execute('1messages'), "\n")[0])
231476a6131SBram Moolenaar  call assert_true(exists('*Xtest'))
232476a6131SBram Moolenaar  delfunc Xtest
233476a6131SBram Moolenaar  set verbose=0
234476a6131SBram Moolenaar
235a0d072efSBram Moolenaar  func Xtest(a1, a2)
236a0d072efSBram Moolenaar    echo a:a1 .. a:a2
237a0d072efSBram Moolenaar  endfunc
238a0d072efSBram Moolenaar  set verbose=15
239a0d072efSBram Moolenaar  redir @a
240a0d072efSBram Moolenaar  call Xtest(123, repeat('x', 100))
241a0d072efSBram Moolenaar  redir END
242a0d072efSBram Moolenaar  call assert_match('calling Xtest(123, ''xxxxxxx.*x\.\.\.x.*xxxx'')', getreg('a'))
243a0d072efSBram Moolenaar  delfunc Xtest
244a0d072efSBram Moolenaar  set verbose=0
245a0d072efSBram Moolenaar
246476a6131SBram Moolenaar  function Foo()
247476a6131SBram Moolenaar    echo 'hello'
248476a6131SBram Moolenaar  endfunction | echo 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
249476a6131SBram Moolenaar  delfunc Foo
250476a6131SBram Moolenaarendfunc
251476a6131SBram Moolenaar
252476a6131SBram Moolenaarfunc Test_delfunction_force()
253476a6131SBram Moolenaar  delfunc! Xtest
254476a6131SBram Moolenaar  delfunc! Xtest
255476a6131SBram Moolenaar  func Xtest()
256476a6131SBram Moolenaar    echo 'nothing'
257476a6131SBram Moolenaar  endfunc
258476a6131SBram Moolenaar  delfunc! Xtest
259476a6131SBram Moolenaar  delfunc! Xtest
260476a6131SBram Moolenaar
261476a6131SBram Moolenaar  " Try deleting the current function
262476a6131SBram Moolenaar  call assert_fails('delfunc Test_delfunction_force', 'E131:')
263476a6131SBram Moolenaarendfunc
264476a6131SBram Moolenaar
265476a6131SBram Moolenaarfunc Test_function_defined_line()
266476a6131SBram Moolenaar  CheckNotGui
267476a6131SBram Moolenaar
268476a6131SBram Moolenaar  let lines =<< trim [CODE]
269476a6131SBram Moolenaar  " F1
270476a6131SBram Moolenaar  func F1()
271476a6131SBram Moolenaar    " F2
272476a6131SBram Moolenaar    func F2()
273476a6131SBram Moolenaar      "
274476a6131SBram Moolenaar      "
275476a6131SBram Moolenaar      "
276476a6131SBram Moolenaar      return
277476a6131SBram Moolenaar    endfunc
278476a6131SBram Moolenaar    " F3
279476a6131SBram Moolenaar    execute "func F3()\n\n\n\nreturn\nendfunc"
280476a6131SBram Moolenaar    " F4
281476a6131SBram Moolenaar    execute "func F4()\n
282476a6131SBram Moolenaar                \\n
283476a6131SBram Moolenaar                \\n
284476a6131SBram Moolenaar                \\n
285476a6131SBram Moolenaar                \return\n
286476a6131SBram Moolenaar                \endfunc"
287476a6131SBram Moolenaar  endfunc
288476a6131SBram Moolenaar  " F5
289476a6131SBram Moolenaar  execute "func F5()\n\n\n\nreturn\nendfunc"
290476a6131SBram Moolenaar  " F6
291476a6131SBram Moolenaar  execute "func F6()\n
292476a6131SBram Moolenaar              \\n
293476a6131SBram Moolenaar              \\n
294476a6131SBram Moolenaar              \\n
295476a6131SBram Moolenaar              \return\n
296476a6131SBram Moolenaar              \endfunc"
297476a6131SBram Moolenaar  call F1()
298476a6131SBram Moolenaar  verbose func F1
299476a6131SBram Moolenaar  verbose func F2
300476a6131SBram Moolenaar  verbose func F3
301476a6131SBram Moolenaar  verbose func F4
302476a6131SBram Moolenaar  verbose func F5
303476a6131SBram Moolenaar  verbose func F6
304476a6131SBram Moolenaar  qall!
305476a6131SBram Moolenaar  [CODE]
306476a6131SBram Moolenaar
307476a6131SBram Moolenaar  call writefile(lines, 'Xtest.vim')
308476a6131SBram Moolenaar  let res = system(GetVimCommandClean() .. ' -es -X -S Xtest.vim')
309476a6131SBram Moolenaar  call assert_equal(0, v:shell_error)
310476a6131SBram Moolenaar
311476a6131SBram Moolenaar  let m = matchstr(res, 'function F1()[^[:print:]]*[[:print:]]*')
312476a6131SBram Moolenaar  call assert_match(' line 2$', m)
313476a6131SBram Moolenaar
314476a6131SBram Moolenaar  let m = matchstr(res, 'function F2()[^[:print:]]*[[:print:]]*')
315476a6131SBram Moolenaar  call assert_match(' line 4$', m)
316476a6131SBram Moolenaar
317476a6131SBram Moolenaar  let m = matchstr(res, 'function F3()[^[:print:]]*[[:print:]]*')
318476a6131SBram Moolenaar  call assert_match(' line 11$', m)
319476a6131SBram Moolenaar
320476a6131SBram Moolenaar  let m = matchstr(res, 'function F4()[^[:print:]]*[[:print:]]*')
321476a6131SBram Moolenaar  call assert_match(' line 13$', m)
322476a6131SBram Moolenaar
323476a6131SBram Moolenaar  let m = matchstr(res, 'function F5()[^[:print:]]*[[:print:]]*')
324476a6131SBram Moolenaar  call assert_match(' line 21$', m)
325476a6131SBram Moolenaar
326476a6131SBram Moolenaar  let m = matchstr(res, 'function F6()[^[:print:]]*[[:print:]]*')
327476a6131SBram Moolenaar  call assert_match(' line 23$', m)
328476a6131SBram Moolenaar
329476a6131SBram Moolenaar  call delete('Xtest.vim')
330476a6131SBram Moolenaarendfunc
331476a6131SBram Moolenaar
332476a6131SBram Moolenaar" Test for defining a function reference in the global scope
333476a6131SBram Moolenaarfunc Test_add_funcref_to_global_scope()
334476a6131SBram Moolenaar  let x = g:
335476a6131SBram Moolenaar  let caught_E862 = 0
336476a6131SBram Moolenaar  try
337476a6131SBram Moolenaar    func x.Xfunc()
338476a6131SBram Moolenaar      return 1
339476a6131SBram Moolenaar    endfunc
340476a6131SBram Moolenaar  catch /E862:/
341476a6131SBram Moolenaar    let caught_E862 = 1
342476a6131SBram Moolenaar  endtry
343476a6131SBram Moolenaar  call assert_equal(1, caught_E862)
344476a6131SBram Moolenaarendfunc
345476a6131SBram Moolenaar
346476a6131SBram Moolenaarfunc Test_funccall_garbage_collect()
347476a6131SBram Moolenaar  func Func(x, ...)
348476a6131SBram Moolenaar    call add(a:x, a:000)
349476a6131SBram Moolenaar  endfunc
350476a6131SBram Moolenaar  call Func([], [])
351476a6131SBram Moolenaar  " Must not crash cause by invalid freeing
352476a6131SBram Moolenaar  call test_garbagecollect_now()
353476a6131SBram Moolenaar  call assert_true(v:true)
354476a6131SBram Moolenaar  delfunc Func
355476a6131SBram Moolenaarendfunc
356476a6131SBram Moolenaar
357476a6131SBram Moolenaar" Test for script-local function
358476a6131SBram Moolenaarfunc <SID>DoLast()
359476a6131SBram Moolenaar  call append(line('$'), "last line")
360476a6131SBram Moolenaarendfunc
361476a6131SBram Moolenaar
362476a6131SBram Moolenaarfunc s:DoNothing()
363476a6131SBram Moolenaar  call append(line('$'), "nothing line")
364476a6131SBram Moolenaarendfunc
365476a6131SBram Moolenaar
366476a6131SBram Moolenaarfunc Test_script_local_func()
367476a6131SBram Moolenaar  set nocp nomore viminfo+=nviminfo
368476a6131SBram Moolenaar  new
369476a6131SBram Moolenaar  nnoremap <buffer> _x	:call <SID>DoNothing()<bar>call <SID>DoLast()<bar>delfunc <SID>DoNothing<bar>delfunc <SID>DoLast<cr>
370476a6131SBram Moolenaar
371476a6131SBram Moolenaar  normal _x
372476a6131SBram Moolenaar  call assert_equal('nothing line', getline(2))
373476a6131SBram Moolenaar  call assert_equal('last line', getline(3))
374476a6131SBram Moolenaar  close!
375476a6131SBram Moolenaar
376476a6131SBram Moolenaar  " Try to call a script local function in global scope
377476a6131SBram Moolenaar  let lines =<< trim [CODE]
378476a6131SBram Moolenaar    :call assert_fails('call s:Xfunc()', 'E81:')
379476a6131SBram Moolenaar    :call assert_fails('let x = call("<SID>Xfunc", [])', 'E120:')
380476a6131SBram Moolenaar    :call writefile(v:errors, 'Xresult')
381476a6131SBram Moolenaar    :qall
382476a6131SBram Moolenaar
383476a6131SBram Moolenaar  [CODE]
384476a6131SBram Moolenaar  call writefile(lines, 'Xscript')
385476a6131SBram Moolenaar  if RunVim([], [], '-s Xscript')
386476a6131SBram Moolenaar    call assert_equal([], readfile('Xresult'))
387476a6131SBram Moolenaar  endif
388476a6131SBram Moolenaar  call delete('Xresult')
389476a6131SBram Moolenaar  call delete('Xscript')
390476a6131SBram Moolenaarendfunc
391476a6131SBram Moolenaar
392476a6131SBram Moolenaar" Test for errors in defining new functions
393476a6131SBram Moolenaarfunc Test_func_def_error()
394476a6131SBram Moolenaar  call assert_fails('func Xfunc abc ()', 'E124:')
395476a6131SBram Moolenaar  call assert_fails('func Xfunc(', 'E125:')
396476a6131SBram Moolenaar  call assert_fails('func xfunc()', 'E128:')
397476a6131SBram Moolenaar
398476a6131SBram Moolenaar  " Try to redefine a function that is in use
399476a6131SBram Moolenaar  let caught_E127 = 0
400476a6131SBram Moolenaar  try
401476a6131SBram Moolenaar    func! Test_func_def_error()
402476a6131SBram Moolenaar    endfunc
403476a6131SBram Moolenaar  catch /E127:/
404476a6131SBram Moolenaar    let caught_E127 = 1
405476a6131SBram Moolenaar  endtry
406476a6131SBram Moolenaar  call assert_equal(1, caught_E127)
407476a6131SBram Moolenaar
408476a6131SBram Moolenaar  " Try to define a function in a dict twice
409476a6131SBram Moolenaar  let d = {}
410476a6131SBram Moolenaar  let lines =<< trim END
411476a6131SBram Moolenaar    func d.F1()
412476a6131SBram Moolenaar      return 1
413476a6131SBram Moolenaar    endfunc
414476a6131SBram Moolenaar  END
415476a6131SBram Moolenaar  let l = join(lines, "\n") . "\n"
416476a6131SBram Moolenaar  exe l
417476a6131SBram Moolenaar  call assert_fails('exe l', 'E717:')
418611728f8SYegappan Lakshmanan  call assert_fails('call feedkeys(":func d.F1()\<CR>", "xt")', 'E717:')
419476a6131SBram Moolenaar
420476a6131SBram Moolenaar  " Define an autoload function with an incorrect file name
421476a6131SBram Moolenaar  call writefile(['func foo#Bar()', 'return 1', 'endfunc'], 'Xscript')
422476a6131SBram Moolenaar  call assert_fails('source Xscript', 'E746:')
423476a6131SBram Moolenaar  call delete('Xscript')
424531be47aSBram Moolenaar
425531be47aSBram Moolenaar  " Try to list functions using an invalid search pattern
426531be47aSBram Moolenaar  call assert_fails('function /\%(/', 'E53:')
427476a6131SBram Moolenaarendfunc
428476a6131SBram Moolenaar
429476a6131SBram Moolenaar" Test for deleting a function
430476a6131SBram Moolenaarfunc Test_del_func()
431476a6131SBram Moolenaar  call assert_fails('delfunction Xabc', 'E130:')
432476a6131SBram Moolenaar  let d = {'a' : 10}
433476a6131SBram Moolenaar  call assert_fails('delfunc d.a', 'E718:')
434611728f8SYegappan Lakshmanan  func d.fn()
435611728f8SYegappan Lakshmanan    return 1
436611728f8SYegappan Lakshmanan  endfunc
437*ddfc0510SBram Moolenaar
438*ddfc0510SBram Moolenaar  " cannot delete the dict function by number
439*ddfc0510SBram Moolenaar  let nr = substitute(execute('echo d'), '.*function(''\(\d\+\)'').*', '\1', '')
440*ddfc0510SBram Moolenaar  call assert_fails('delfunction g:' .. nr, 'E475: Invalid argument: g:')
441*ddfc0510SBram Moolenaar
442611728f8SYegappan Lakshmanan  delfunc d.fn
443611728f8SYegappan Lakshmanan  call assert_equal({'a' : 10}, d)
444476a6131SBram Moolenaarendfunc
445476a6131SBram Moolenaar
446476a6131SBram Moolenaar" Test for calling return outside of a function
447476a6131SBram Moolenaarfunc Test_return_outside_func()
448476a6131SBram Moolenaar  call writefile(['return 10'], 'Xscript')
449476a6131SBram Moolenaar  call assert_fails('source Xscript', 'E133:')
450476a6131SBram Moolenaar  call delete('Xscript')
451476a6131SBram Moolenaarendfunc
452476a6131SBram Moolenaar
453476a6131SBram Moolenaar" Test for errors in calling a function
454476a6131SBram Moolenaarfunc Test_func_arg_error()
455476a6131SBram Moolenaar  " Too many arguments
456476a6131SBram Moolenaar  call assert_fails("call call('min', range(1,20))", 'E118:')
457476a6131SBram Moolenaar  call assert_fails("call call('min', range(1,21))", 'E699:')
458476a6131SBram Moolenaar  call assert_fails('echo min(0,1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7,8,9,0,1)',
459476a6131SBram Moolenaar        \ 'E740:')
460476a6131SBram Moolenaar
461476a6131SBram Moolenaar  " Missing dict argument
462476a6131SBram Moolenaar  func Xfunc() dict
463476a6131SBram Moolenaar    return 1
464476a6131SBram Moolenaar  endfunc
465476a6131SBram Moolenaar  call assert_fails('call Xfunc()', 'E725:')
466476a6131SBram Moolenaar  delfunc Xfunc
467476a6131SBram Moolenaarendfunc
468476a6131SBram Moolenaar
46967322bf7SBram Moolenaarfunc Test_func_dict()
47067322bf7SBram Moolenaar  let mydict = {'a': 'b'}
47167322bf7SBram Moolenaar  function mydict.somefunc() dict
47267322bf7SBram Moolenaar    return len(self)
47367322bf7SBram Moolenaar  endfunc
47467322bf7SBram Moolenaar
475611728f8SYegappan Lakshmanan  call assert_equal("{'a': 'b', 'somefunc': function('3')}", string(mydict))
47667322bf7SBram Moolenaar  call assert_equal(2, mydict.somefunc())
47767322bf7SBram Moolenaar  call assert_match("^\n   function \\d\\\+() dict"
47867322bf7SBram Moolenaar  \              .. "\n1      return len(self)"
47967322bf7SBram Moolenaar  \              .. "\n   endfunction$", execute('func mydict.somefunc'))
480611728f8SYegappan Lakshmanan  call assert_fails('call mydict.nonexist()', 'E716:')
48167322bf7SBram Moolenaarendfunc
48267322bf7SBram Moolenaar
48367322bf7SBram Moolenaarfunc Test_func_range()
48467322bf7SBram Moolenaar  new
48567322bf7SBram Moolenaar  call setline(1, range(1, 8))
48667322bf7SBram Moolenaar  func FuncRange() range
48767322bf7SBram Moolenaar    echo a:firstline
48867322bf7SBram Moolenaar    echo a:lastline
48967322bf7SBram Moolenaar  endfunc
49067322bf7SBram Moolenaar  3
49167322bf7SBram Moolenaar  call assert_equal("\n3\n3", execute('call FuncRange()'))
49267322bf7SBram Moolenaar  call assert_equal("\n4\n6", execute('4,6 call FuncRange()'))
49367322bf7SBram Moolenaar  call assert_equal("\n   function FuncRange() range"
49467322bf7SBram Moolenaar  \              .. "\n1      echo a:firstline"
49567322bf7SBram Moolenaar  \              .. "\n2      echo a:lastline"
49667322bf7SBram Moolenaar  \              .. "\n   endfunction",
49767322bf7SBram Moolenaar  \                 execute('function FuncRange'))
49867322bf7SBram Moolenaar
49967322bf7SBram Moolenaar  bwipe!
50067322bf7SBram Moolenaarendfunc
50167322bf7SBram Moolenaar
502ee4e0c1eSBram Moolenaar" vim: shiftwidth=2 sts=2 expandtab
503