123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914 |
- " Test for user functions.
- " Also test an <expr> mapping calling a function.
- " Also test that a builtin function cannot be replaced.
- " Also test for regression when calling arbitrary expression.
- source check.vim
- source shared.vim
- source vim9.vim
- func Table(title, ...)
- let ret = a:title
- let idx = 1
- while idx <= a:0
- exe "let ret = ret . a:" . idx
- let idx = idx + 1
- endwhile
- return ret
- endfunc
- func Compute(n1, n2, divname)
- if a:n2 == 0
- return "fail"
- endif
- exe "let g:" . a:divname . " = ". a:n1 / a:n2
- return "ok"
- endfunc
- func Expr1()
- silent! normal! v
- return "111"
- endfunc
- func Expr2()
- call search('XX', 'b')
- return "222"
- endfunc
- func ListItem()
- let g:counter += 1
- return g:counter . '. '
- endfunc
- func ListReset()
- let g:counter = 0
- return ''
- endfunc
- func FuncWithRef(a)
- unlet g:FuncRef
- return a:a
- endfunc
- func Test_user_func()
- let g:FuncRef = function("FuncWithRef")
- let g:counter = 0
- inoremap <expr> ( ListItem()
- inoremap <expr> [ ListReset()
- imap <expr> + Expr1()
- imap <expr> * Expr2()
- let g:retval = "nop"
- call assert_equal('xxx4asdf', Table("xxx", 4, "asdf"))
- call assert_equal('fail', Compute(45, 0, "retval"))
- call assert_equal('nop', g:retval)
- call assert_equal('ok', Compute(45, 5, "retval"))
- call assert_equal(9, g:retval)
- call assert_equal(333, g:FuncRef(333))
- let g:retval = "nop"
- call assert_equal('xxx4asdf', "xxx"->Table(4, "asdf"))
- call assert_equal('fail', 45->Compute(0, "retval"))
- call assert_equal('nop', g:retval)
- call assert_equal('ok', 45->Compute(5, "retval"))
- call assert_equal(9, g:retval)
- " call assert_equal(333, 333->g:FuncRef())
- enew
- normal oXX+-XX
- call assert_equal('XX111-XX', getline('.'))
- normal o---*---
- call assert_equal('---222---', getline('.'))
- normal o(one
- call assert_equal('1. one', getline('.'))
- normal o(two
- call assert_equal('2. two', getline('.'))
- normal o[(one again
- call assert_equal('1. one again', getline('.'))
- " Try to overwrite a function in the global (g:) scope
- call assert_equal(3, max([1, 2, 3]))
- call assert_fails("call extend(g:, {'max': function('min')})", 'E704')
- call assert_equal(3, max([1, 2, 3]))
- " Try to overwrite an user defined function with a function reference
- call assert_fails("let Expr1 = function('min')", 'E705:')
- " Regression: the first line below used to throw ?E110: Missing ')'?
- " Second is here just to prove that this line is correct when not skipping
- " rhs of &&.
- call assert_equal(0, (0 && (function('tr'))(1, 2, 3)))
- call assert_equal(1, (1 && (function('tr'))(1, 2, 3)))
- delfunc Table
- delfunc Compute
- delfunc Expr1
- delfunc Expr2
- delfunc ListItem
- delfunc ListReset
- unlet g:retval g:counter
- enew!
- endfunc
- func Log(val, base = 10)
- return log(a:val) / log(a:base)
- endfunc
- func Args(mandatory, optional = v:null, ...)
- return deepcopy(a:)
- endfunc
- func Args2(a = 1, b = 2, c = 3)
- return deepcopy(a:)
- endfunc
- func MakeBadFunc()
- func s:fcn(a, b=1, c)
- endfunc
- endfunc
- func Test_default_arg()
- if has('float')
- call assert_equal(1.0, Log(10))
- call assert_equal(log(10), Log(10, exp(1)))
- call assert_fails("call Log(1,2,3)", 'E118')
- endif
- let res = Args(1)
- call assert_equal(res.mandatory, 1)
- call assert_equal(res.optional, v:null)
- call assert_equal(res['0'], 0)
- let res = Args(1,2)
- call assert_equal(res.mandatory, 1)
- call assert_equal(res.optional, 2)
- call assert_equal(res['0'], 0)
- let res = Args(1,2,3)
- call assert_equal(res.mandatory, 1)
- call assert_equal(res.optional, 2)
- call assert_equal(res['0'], 1)
- call assert_fails("call MakeBadFunc()", 'E989:')
- call assert_fails("fu F(a=1 ,) | endf", 'E1068:')
- " Since neovim does not have v:none, the ability to use the default
- " argument with the intermediate argument set to v:none has been omitted.
- " Therefore, this test is not performed.
- " let d = Args2(7, v:none, 9)
- " call assert_equal([7, 2, 9], [d.a, d.b, d.c])
- call assert_equal("\n"
- \ .. " function Args2(a = 1, b = 2, c = 3)\n"
- \ .. "1 return deepcopy(a:)\n"
- \ .. " endfunction",
- \ execute('func Args2'))
- " Error in default argument expression
- let l =<< trim END
- func F1(x = y)
- return a:x * 2
- endfunc
- echo F1()
- END
- let @a = l->join("\n")
- call assert_fails("exe @a", 'E121:')
- endfunc
- func s:addFoo(lead)
- return a:lead .. 'foo'
- endfunc
- func Test_user_method()
- eval 'bar'->s:addFoo()->assert_equal('barfoo')
- endfunc
- func Test_failed_call_in_try()
- try | call UnknownFunc() | catch | endtry
- endfunc
- " Test for listing user-defined functions
- func Test_function_list()
- call assert_fails("function Xabc", 'E123:')
- endfunc
- " Test for <sfile>, <slnum> in a function
- func Test_sfile_in_function()
- func Xfunc()
- call assert_match('..Test_sfile_in_function\[5]..Xfunc', expand('<sfile>'))
- call assert_equal('2', expand('<slnum>'))
- endfunc
- call Xfunc()
- delfunc Xfunc
- endfunc
- " Test trailing text after :endfunction {{{1
- func Test_endfunction_trailing()
- call assert_false(exists('*Xtest'))
- exe "func Xtest()\necho 'hello'\nendfunc\nlet done = 'yes'"
- call assert_true(exists('*Xtest'))
- call assert_equal('yes', done)
- delfunc Xtest
- unlet done
- exe "func Xtest()\necho 'hello'\nendfunc|let done = 'yes'"
- call assert_true(exists('*Xtest'))
- call assert_equal('yes', done)
- delfunc Xtest
- unlet done
- " trailing line break
- exe "func Xtest()\necho 'hello'\nendfunc\n"
- call assert_true(exists('*Xtest'))
- delfunc Xtest
- set verbose=1
- exe "func Xtest()\necho 'hello'\nendfunc \" garbage"
- call assert_notmatch('W22:', split(execute('1messages'), "\n")[0])
- call assert_true(exists('*Xtest'))
- delfunc Xtest
- exe "func Xtest()\necho 'hello'\nendfunc garbage"
- call assert_match('W22:', split(execute('1messages'), "\n")[0])
- call assert_true(exists('*Xtest'))
- delfunc Xtest
- set verbose=0
- func Xtest(a1, a2)
- echo a:a1 .. a:a2
- endfunc
- set verbose=15
- redir @a
- call Xtest(123, repeat('x', 100))
- redir END
- call assert_match('calling Xtest(123, ''xxxxxxx.*x\.\.\.x.*xxxx'')', getreg('a'))
- delfunc Xtest
- set verbose=0
- function Foo()
- echo 'hello'
- endfunction | echo 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
- delfunc Foo
- endfunc
- func Test_delfunction_force()
- delfunc! Xtest
- delfunc! Xtest
- func Xtest()
- echo 'nothing'
- endfunc
- delfunc! Xtest
- delfunc! Xtest
- " Try deleting the current function
- call assert_fails('delfunc Test_delfunction_force', 'E131:')
- endfunc
- func Test_function_defined_line()
- CheckNotGui
- let lines =<< trim [CODE]
- " F1
- func F1()
- " F2
- func F2()
- "
- "
- "
- return
- endfunc
- " F3
- execute "func F3()\n\n\n\nreturn\nendfunc"
- " F4
- execute "func F4()\n
- \\n
- \\n
- \\n
- \return\n
- \endfunc"
- endfunc
- " F5
- execute "func F5()\n\n\n\nreturn\nendfunc"
- " F6
- execute "func F6()\n
- \\n
- \\n
- \\n
- \return\n
- \endfunc"
- call F1()
- verbose func F1
- verbose func F2
- verbose func F3
- verbose func F4
- verbose func F5
- verbose func F6
- qall!
- [CODE]
- call writefile(lines, 'Xtest.vim')
- let res = system(GetVimCommandClean() .. ' -es -X -S Xtest.vim')
- call assert_equal(0, v:shell_error)
- let m = matchstr(res, 'function F1()[^[:print:]]*[[:print:]]*')
- call assert_match(' line 2$', m)
- let m = matchstr(res, 'function F2()[^[:print:]]*[[:print:]]*')
- call assert_match(' line 4$', m)
- let m = matchstr(res, 'function F3()[^[:print:]]*[[:print:]]*')
- call assert_match(' line 11$', m)
- let m = matchstr(res, 'function F4()[^[:print:]]*[[:print:]]*')
- call assert_match(' line 13$', m)
- let m = matchstr(res, 'function F5()[^[:print:]]*[[:print:]]*')
- call assert_match(' line 21$', m)
- let m = matchstr(res, 'function F6()[^[:print:]]*[[:print:]]*')
- call assert_match(' line 23$', m)
- call delete('Xtest.vim')
- endfunc
- " Test for defining a function reference in the global scope
- func Test_add_funcref_to_global_scope()
- let x = g:
- let caught_E862 = 0
- try
- func x.Xfunc()
- return 1
- endfunc
- catch /E862:/
- let caught_E862 = 1
- endtry
- call assert_equal(1, caught_E862)
- endfunc
- func Test_funccall_garbage_collect()
- func Func(x, ...)
- call add(a:x, a:000)
- endfunc
- call Func([], [])
- " Must not crash cause by invalid freeing
- call test_garbagecollect_now()
- call assert_true(v:true)
- delfunc Func
- endfunc
- " Test for script-local function
- func <SID>DoLast()
- call append(line('$'), "last line")
- endfunc
- func s:DoNothing()
- call append(line('$'), "nothing line")
- endfunc
- func Test_script_local_func()
- set nocp nomore viminfo+=nviminfo
- new
- nnoremap <buffer> _x :call <SID>DoNothing()<bar>call <SID>DoLast()<bar>delfunc <SID>DoNothing<bar>delfunc <SID>DoLast<cr>
- normal _x
- call assert_equal('nothing line', getline(2))
- call assert_equal('last line', getline(3))
- close!
- " Try to call a script local function in global scope
- let lines =<< trim [CODE]
- :call assert_fails('call s:Xfunc()', 'E81:')
- :call assert_fails('let x = call("<SID>Xfunc", [])', 'E120:')
- :call writefile(v:errors, 'Xresult')
- :qall
- [CODE]
- call writefile(lines, 'Xscript')
- if RunVim([], [], '-s Xscript')
- call assert_equal([], readfile('Xresult'))
- endif
- call delete('Xresult')
- call delete('Xscript')
- endfunc
- " Test for errors in defining new functions
- func Test_func_def_error()
- call assert_fails('func Xfunc abc ()', 'E124:')
- call assert_fails('func Xfunc(', 'E125:')
- call assert_fails('func xfunc()', 'E128:')
- " Try to redefine a function that is in use
- let caught_E127 = 0
- try
- func! Test_func_def_error()
- endfunc
- catch /E127:/
- let caught_E127 = 1
- endtry
- call assert_equal(1, caught_E127)
- " Try to define a function in a dict twice
- let d = {}
- let lines =<< trim END
- func d.F1()
- return 1
- endfunc
- END
- let l = join(lines, "\n") . "\n"
- exe l
- call assert_fails('exe l', 'E717:')
- " Define an autoload function with an incorrect file name
- call writefile(['func foo#Bar()', 'return 1', 'endfunc'], 'Xscript')
- call assert_fails('source Xscript', 'E746:')
- call delete('Xscript')
- " Try to list functions using an invalid search pattern
- call assert_fails('function /\%(/', 'E53:')
- endfunc
- " Test for deleting a function
- func Test_del_func()
- call assert_fails('delfunction Xabc', 'E130:')
- let d = {'a' : 10}
- call assert_fails('delfunc d.a', 'E718:')
- func d.fn()
- return 1
- endfunc
- " cannot delete the dict function by number
- let nr = substitute(execute('echo d'), '.*function(''\(\d\+\)'').*', '\1', '')
- call assert_fails('delfunction g:' .. nr, 'E475: Invalid argument: g:')
- delfunc d.fn
- call assert_equal({'a' : 10}, d)
- endfunc
- " Test for calling return outside of a function
- func Test_return_outside_func()
- call writefile(['return 10'], 'Xscript')
- call assert_fails('source Xscript', 'E133:')
- call delete('Xscript')
- endfunc
- " Test for errors in calling a function
- func Test_func_arg_error()
- " Too many arguments
- call assert_fails("call call('min', range(1,20))", 'E118:')
- call assert_fails("call call('min', range(1,21))", 'E699:')
- 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)',
- \ 'E740:')
- " Missing dict argument
- func Xfunc() dict
- return 1
- endfunc
- call assert_fails('call Xfunc()', 'E725:')
- delfunc Xfunc
- endfunc
- func Test_func_dict()
- let mydict = {'a': 'b'}
- function mydict.somefunc() dict
- return len(self)
- endfunc
- call assert_equal("{'a': 'b', 'somefunc': function('3')}", string(mydict))
- call assert_equal(2, mydict.somefunc())
- call assert_match("^\n function \\d\\\+() dict"
- \ .. "\n1 return len(self)"
- \ .. "\n endfunction$", execute('func mydict.somefunc'))
- call assert_fails('call mydict.nonexist()', 'E716:')
- endfunc
- func Test_func_range()
- new
- call setline(1, range(1, 8))
- func FuncRange() range
- echo a:firstline
- echo a:lastline
- endfunc
- 3
- call assert_equal("\n3\n3", execute('call FuncRange()'))
- call assert_equal("\n4\n6", execute('4,6 call FuncRange()'))
- call assert_equal("\n function FuncRange() range"
- \ .. "\n1 echo a:firstline"
- \ .. "\n2 echo a:lastline"
- \ .. "\n endfunction",
- \ execute('function FuncRange'))
- bwipe!
- endfunc
- " Test for memory allocation failure when defining a new function
- func Test_funcdef_alloc_failure()
- CheckFunction test_alloc_fail
- new
- let lines =<< trim END
- func Xtestfunc()
- return 321
- endfunc
- END
- call setline(1, lines)
- call test_alloc_fail(GetAllocId('get_func'), 0, 0)
- call assert_fails('source', 'E342:')
- call assert_false(exists('*Xtestfunc'))
- call assert_fails('delfunc Xtestfunc', 'E117:')
- %d _
- let lines =<< trim END
- def g:Xvim9func(): number
- return 456
- enddef
- END
- call setline(1, lines)
- call test_alloc_fail(GetAllocId('get_func'), 0, 0)
- call assert_fails('source', 'E342:')
- call assert_false(exists('*Xvim9func'))
- "call test_alloc_fail(GetAllocId('get_func'), 0, 0)
- "call assert_fails('source', 'E342:')
- "call assert_false(exists('*Xtestfunc'))
- "call assert_fails('delfunc Xtestfunc', 'E117:')
- bw!
- endfunc
- func AddDefer(arg1, ...)
- call extend(g:deferred, [a:arg1])
- if a:0 == 1
- call extend(g:deferred, [a:1])
- endif
- endfunc
- func WithDeferTwo()
- call extend(g:deferred, ['in Two'])
- for nr in range(3)
- defer AddDefer('Two' .. nr)
- endfor
- call extend(g:deferred, ['end Two'])
- endfunc
- func WithDeferOne()
- call extend(g:deferred, ['in One'])
- call writefile(['text'], 'Xfuncdefer')
- defer delete('Xfuncdefer')
- defer AddDefer('One')
- call WithDeferTwo()
- call extend(g:deferred, ['end One'])
- endfunc
- func WithPartialDefer()
- call extend(g:deferred, ['in Partial'])
- let Part = funcref('AddDefer', ['arg1'])
- defer Part("arg2")
- call extend(g:deferred, ['end Partial'])
- endfunc
- func Test_defer()
- let g:deferred = []
- call WithDeferOne()
- call assert_equal(['in One', 'in Two', 'end Two', 'Two2', 'Two1', 'Two0', 'end One', 'One'], g:deferred)
- unlet g:deferred
- call assert_equal('', glob('Xfuncdefer'))
- call assert_fails('defer delete("Xfuncdefer")->Another()', 'E488:')
- call assert_fails('defer delete("Xfuncdefer").member', 'E488:')
- let g:deferred = []
- call WithPartialDefer()
- call assert_equal(['in Partial', 'end Partial', 'arg1', 'arg2'], g:deferred)
- unlet g:deferred
- let Part = funcref('AddDefer', ['arg1'], {})
- call assert_fails('defer Part("arg2")', 'E1300:')
- endfunc
- func DeferLevelTwo()
- call writefile(['text'], 'XDeleteTwo', 'D')
- throw 'someerror'
- endfunc
- " def DeferLevelOne()
- func DeferLevelOne()
- call writefile(['text'], 'XDeleteOne', 'D')
- call g:DeferLevelTwo()
- " enddef
- endfunc
- func Test_defer_throw()
- let caught = 'no'
- try
- call DeferLevelOne()
- catch /someerror/
- let caught = 'yes'
- endtry
- call assert_equal('yes', caught)
- call assert_false(filereadable('XDeleteOne'))
- call assert_false(filereadable('XDeleteTwo'))
- endfunc
- func Test_defer_quitall_func()
- let lines =<< trim END
- func DeferLevelTwo()
- call writefile(['text'], 'XQuitallFuncTwo', 'D')
- call writefile(['quit'], 'XQuitallFuncThree', 'a')
- qa!
- endfunc
- func DeferLevelOne()
- call writefile(['text'], 'XQuitalFunclOne', 'D')
- defer DeferLevelTwo()
- endfunc
- call DeferLevelOne()
- END
- call writefile(lines, 'XdeferQuitallFunc', 'D')
- call system(GetVimCommand() .. ' -X -S XdeferQuitallFunc')
- call assert_equal(0, v:shell_error)
- call assert_false(filereadable('XQuitallFuncOne'))
- call assert_false(filereadable('XQuitallFuncTwo'))
- call assert_equal(['quit'], readfile('XQuitallFuncThree'))
- call delete('XQuitallFuncThree')
- endfunc
- func Test_defer_quitall_def()
- throw 'Skipped: Vim9 script is N/A'
- let lines =<< trim END
- vim9script
- def DeferLevelTwo()
- call writefile(['text'], 'XQuitallDefTwo', 'D')
- call writefile(['quit'], 'XQuitallDefThree', 'a')
- qa!
- enddef
- def DeferLevelOne()
- call writefile(['text'], 'XQuitallDefOne', 'D')
- defer DeferLevelTwo()
- enddef
- DeferLevelOne()
- END
- call writefile(lines, 'XdeferQuitallDef', 'D')
- call system(GetVimCommand() .. ' -X -S XdeferQuitallDef')
- call assert_equal(0, v:shell_error)
- call assert_false(filereadable('XQuitallDefOne'))
- call assert_false(filereadable('XQuitallDefTwo'))
- call assert_equal(['quit'], readfile('XQuitallDefThree'))
- call delete('XQuitallDefThree')
- endfunc
- func Test_defer_quitall_autocmd()
- let lines =<< trim END
- func DeferLevelFive()
- defer writefile(['5'], 'XQuitallAutocmd', 'a')
- qa!
- endfunc
- autocmd User DeferAutocmdFive call DeferLevelFive()
- " def DeferLevelFour()
- func DeferLevelFour()
- defer writefile(['4'], 'XQuitallAutocmd', 'a')
- doautocmd User DeferAutocmdFive
- " enddef
- endfunc
- func DeferLevelThree()
- defer writefile(['3'], 'XQuitallAutocmd', 'a')
- call DeferLevelFour()
- endfunc
- autocmd User DeferAutocmdThree ++nested call DeferLevelThree()
- " def DeferLevelTwo()
- func DeferLevelTwo()
- defer writefile(['2'], 'XQuitallAutocmd', 'a')
- doautocmd User DeferAutocmdThree
- " enddef
- endfunc
- func DeferLevelOne()
- defer writefile(['1'], 'XQuitallAutocmd', 'a')
- call DeferLevelTwo()
- endfunc
- autocmd User DeferAutocmdOne ++nested call DeferLevelOne()
- doautocmd User DeferAutocmdOne
- END
- call writefile(lines, 'XdeferQuitallAutocmd', 'D')
- call system(GetVimCommand() .. ' -X -S XdeferQuitallAutocmd')
- call assert_equal(0, v:shell_error)
- call assert_equal(['5', '4', '3', '2', '1'], readfile('XQuitallAutocmd'))
- call delete('XQuitallAutocmd')
- endfunc
- func Test_defer_quitall_in_expr_func()
- throw 'Skipped: Vim9 script is N/A'
- let lines =<< trim END
- def DefIndex(idx: number, val: string): bool
- call writefile([idx .. ': ' .. val], 'Xentry' .. idx, 'D')
- if val == 'b'
- qa!
- endif
- return val == 'c'
- enddef
- def Test_defer_in_funcref()
- assert_equal(2, indexof(['a', 'b', 'c'], funcref('g:DefIndex')))
- enddef
- call Test_defer_in_funcref()
- END
- call writefile(lines, 'XdeferQuitallExpr', 'D')
- call system(GetVimCommand() .. ' -X -S XdeferQuitallExpr')
- call assert_equal(0, v:shell_error)
- call assert_false(filereadable('Xentry0'))
- call assert_false(filereadable('Xentry1'))
- call assert_false(filereadable('Xentry2'))
- endfunc
- func FuncIndex(idx, val)
- call writefile([a:idx .. ': ' .. a:val], 'Xentry' .. a:idx, 'D')
- return a:val == 'c'
- endfunc
- func Test_defer_wrong_arguments()
- call assert_fails('defer delete()', 'E119:')
- call assert_fails('defer FuncIndex(1)', 'E119:')
- call assert_fails('defer delete(1, 2, 3)', 'E118:')
- call assert_fails('defer FuncIndex(1, 2, 3)', 'E118:')
- throw 'Skipped: Vim9 script is N/A'
- let lines =<< trim END
- def DeferFunc0()
- defer delete()
- enddef
- defcompile
- END
- call v9.CheckScriptFailure(lines, 'E119:')
- let lines =<< trim END
- def DeferFunc3()
- defer delete(1, 2, 3)
- enddef
- defcompile
- END
- call v9.CheckScriptFailure(lines, 'E118:')
- let lines =<< trim END
- def DeferFunc2()
- defer delete(1, 2)
- enddef
- defcompile
- END
- call v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got number')
- def g:FuncOneArg(arg: string)
- echo arg
- enddef
- let lines =<< trim END
- def DeferUserFunc0()
- defer g:FuncOneArg()
- enddef
- defcompile
- END
- call v9.CheckScriptFailure(lines, 'E119:')
- let lines =<< trim END
- def DeferUserFunc2()
- defer g:FuncOneArg(1, 2)
- enddef
- defcompile
- END
- call v9.CheckScriptFailure(lines, 'E118:')
- let lines =<< trim END
- def DeferUserFunc1()
- defer g:FuncOneArg(1)
- enddef
- defcompile
- END
- call v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got number')
- endfunc
- " Test for calling a deferred function after an exception
- func Test_defer_after_exception()
- let g:callTrace = []
- func Bar()
- let g:callTrace += [1]
- throw 'InnerException'
- endfunc
- func Defer()
- let g:callTrace += [2]
- let g:callTrace += [3]
- try
- call Bar()
- catch /InnerException/
- let g:callTrace += [4]
- endtry
- let g:callTrace += [5]
- let g:callTrace += [6]
- endfunc
- func Foo()
- defer Defer()
- throw "TestException"
- endfunc
- try
- call Foo()
- catch /TestException/
- let g:callTrace += [7]
- endtry
- call assert_equal([2, 3, 1, 4, 5, 6, 7], g:callTrace)
- delfunc Defer
- delfunc Foo
- delfunc Bar
- unlet g:callTrace
- endfunc
- " Test for multiple deferred function which throw exceptions.
- " Exceptions thrown by deferred functions should result in error messages but
- " not propagated into the calling functions.
- func Test_multidefer_with_exception()
- let g:callTrace = []
- func Except()
- let g:callTrace += [1]
- throw 'InnerException'
- let g:callTrace += [2]
- endfunc
- func FirstDefer()
- let g:callTrace += [3]
- let g:callTrace += [4]
- endfunc
- func SecondDeferWithExcept()
- let g:callTrace += [5]
- call Except()
- let g:callTrace += [6]
- endfunc
- func ThirdDefer()
- let g:callTrace += [7]
- let g:callTrace += [8]
- endfunc
- func Foo()
- let g:callTrace += [9]
- defer FirstDefer()
- defer SecondDeferWithExcept()
- defer ThirdDefer()
- let g:callTrace += [10]
- endfunc
- let v:errmsg = ''
- try
- let g:callTrace += [11]
- call Foo()
- let g:callTrace += [12]
- catch /TestException/
- let g:callTrace += [13]
- catch
- let g:callTrace += [14]
- finally
- let g:callTrace += [15]
- endtry
- let g:callTrace += [16]
- call assert_equal('E605: Exception not caught: InnerException', v:errmsg)
- call assert_equal([11, 9, 10, 7, 8, 5, 1, 3, 4, 12, 15, 16], g:callTrace)
- unlet g:callTrace
- delfunc Except
- delfunc FirstDefer
- delfunc SecondDeferWithExcept
- delfunc ThirdDefer
- delfunc Foo
- endfunc
- func Test_func_curly_brace_invalid_name()
- func Fail()
- func Foo{'()'}bar()
- endfunc
- endfunc
- call assert_fails('call Fail()', 'E475: Invalid argument: Foo()bar')
- silent! call Fail()
- call assert_equal([], getcompletion('Foo', 'function'))
- set formatexpr=Fail()
- normal! gqq
- call assert_equal([], getcompletion('Foo', 'function'))
- set formatexpr&
- delfunc Fail
- endfunc
- " vim: shiftwidth=2 sts=2 expandtab
|