15deeb3f1SBram Moolenaar" Test various aspects of the Vim9 script language.
25deeb3f1SBram Moolenaar
35deeb3f1SBram Moolenaarsource check.vim
45deeb3f1SBram Moolenaarsource view_util.vim
55deeb3f1SBram Moolenaar
65deeb3f1SBram Moolenaar" Check that "lines" inside ":def" results in an "error" message.
75deeb3f1SBram Moolenaarfunc CheckDefFailure(lines, error)
85deeb3f1SBram Moolenaar  call writefile(['def Func()'] + a:lines + ['enddef'], 'Xdef')
95deeb3f1SBram Moolenaar  call assert_fails('so Xdef', a:error, a:lines)
105deeb3f1SBram Moolenaar  call delete('Xdef')
115deeb3f1SBram Moolenaarendfunc
125deeb3f1SBram Moolenaar
135deeb3f1SBram Moolenaarfunc CheckScriptFailure(lines, error)
145deeb3f1SBram Moolenaar  call writefile(a:lines, 'Xdef')
155deeb3f1SBram Moolenaar  call assert_fails('so Xdef', a:error, a:lines)
165deeb3f1SBram Moolenaar  call delete('Xdef')
175deeb3f1SBram Moolenaarendfunc
185deeb3f1SBram Moolenaar
195deeb3f1SBram Moolenaarfunc Test_def_basic()
205deeb3f1SBram Moolenaar  def SomeFunc(): string
215deeb3f1SBram Moolenaar    return 'yes'
225deeb3f1SBram Moolenaar  enddef
235deeb3f1SBram Moolenaar  call assert_equal('yes', SomeFunc())
245deeb3f1SBram Moolenaarendfunc
255deeb3f1SBram Moolenaar
265deeb3f1SBram Moolenaardef ReturnString(): string
275deeb3f1SBram Moolenaar  return 'string'
285deeb3f1SBram Moolenaarenddef
295deeb3f1SBram Moolenaar
305deeb3f1SBram Moolenaardef ReturnNumber(): number
315deeb3f1SBram Moolenaar  return 123
325deeb3f1SBram Moolenaarenddef
335deeb3f1SBram Moolenaar
345deeb3f1SBram Moolenaarlet g:notNumber = 'string'
355deeb3f1SBram Moolenaar
365deeb3f1SBram Moolenaardef ReturnGlobal(): number
375deeb3f1SBram Moolenaar  return g:notNumber
385deeb3f1SBram Moolenaarenddef
395deeb3f1SBram Moolenaar
405deeb3f1SBram Moolenaardef Test_return_something()
415deeb3f1SBram Moolenaar  assert_equal('string', ReturnString())
425deeb3f1SBram Moolenaar  assert_equal(123, ReturnNumber())
435deeb3f1SBram Moolenaar  assert_fails('call ReturnGlobal()', 'E1029: Expected number but got string')
445deeb3f1SBram Moolenaarenddef
455deeb3f1SBram Moolenaar
465deeb3f1SBram Moolenaarlet s:nothing = 0
475deeb3f1SBram Moolenaardef ReturnNothing()
485deeb3f1SBram Moolenaar  s:nothing = 1
495deeb3f1SBram Moolenaar  if true
505deeb3f1SBram Moolenaar    return
515deeb3f1SBram Moolenaar  endif
525deeb3f1SBram Moolenaar  s:nothing = 2
535deeb3f1SBram Moolenaarenddef
545deeb3f1SBram Moolenaar
555deeb3f1SBram Moolenaardef Test_return_nothing()
565deeb3f1SBram Moolenaar  ReturnNothing()
575deeb3f1SBram Moolenaar  assert_equal(1, s:nothing)
585deeb3f1SBram Moolenaarenddef
595deeb3f1SBram Moolenaar
605deeb3f1SBram Moolenaarfunc Increment()
615deeb3f1SBram Moolenaar  let g:counter += 1
625deeb3f1SBram Moolenaarendfunc
635deeb3f1SBram Moolenaar
645deeb3f1SBram Moolenaardef Test_call_ufunc_count()
655deeb3f1SBram Moolenaar  g:counter = 1
665deeb3f1SBram Moolenaar  Increment()
675deeb3f1SBram Moolenaar  Increment()
685deeb3f1SBram Moolenaar  Increment()
695deeb3f1SBram Moolenaar  " works with and without :call
705deeb3f1SBram Moolenaar  assert_equal(4, g:counter)
715deeb3f1SBram Moolenaar  call assert_equal(4, g:counter)
725deeb3f1SBram Moolenaar  unlet g:counter
735deeb3f1SBram Moolenaarenddef
745deeb3f1SBram Moolenaar
755deeb3f1SBram Moolenaardef MyVarargs(arg: string, ...rest: list<string>): string
765deeb3f1SBram Moolenaar  let res = arg
775deeb3f1SBram Moolenaar  for s in rest
785deeb3f1SBram Moolenaar    res ..= ',' .. s
795deeb3f1SBram Moolenaar  endfor
805deeb3f1SBram Moolenaar  return res
815deeb3f1SBram Moolenaarenddef
825deeb3f1SBram Moolenaar
835deeb3f1SBram Moolenaardef Test_call_varargs()
845deeb3f1SBram Moolenaar  assert_equal('one', MyVarargs('one'))
855deeb3f1SBram Moolenaar  assert_equal('one,two', MyVarargs('one', 'two'))
865deeb3f1SBram Moolenaar  assert_equal('one,two,three', MyVarargs('one', 'two', 'three'))
875deeb3f1SBram Moolenaarenddef
885deeb3f1SBram Moolenaar
895deeb3f1SBram Moolenaardef MyDefaultArgs(name = 'string'): string
905deeb3f1SBram Moolenaar  return name
915deeb3f1SBram Moolenaarenddef
925deeb3f1SBram Moolenaar
935deeb3f1SBram Moolenaardef Test_call_default_args()
945deeb3f1SBram Moolenaar  assert_equal('string', MyDefaultArgs())
955deeb3f1SBram Moolenaar  assert_equal('one', MyDefaultArgs('one'))
965deeb3f1SBram Moolenaar  assert_fails('call MyDefaultArgs("one", "two")', 'E118:')
975deeb3f1SBram Moolenaar
985deeb3f1SBram Moolenaar  call CheckScriptFailure(['def Func(arg: number = asdf)', 'enddef'], 'E1001:')
9999aaf0ceSBram Moolenaar  call CheckScriptFailure(['def Func(arg: number = "text")', 'enddef'], 'E1013: argument 1: type mismatch, expected number but got string')
1005deeb3f1SBram Moolenaarenddef
1015deeb3f1SBram Moolenaar
1025deeb3f1SBram Moolenaarfunc Test_call_default_args_from_func()
1035deeb3f1SBram Moolenaar  call assert_equal('string', MyDefaultArgs())
1045deeb3f1SBram Moolenaar  call assert_equal('one', MyDefaultArgs('one'))
1055deeb3f1SBram Moolenaar  call assert_fails('call MyDefaultArgs("one", "two")', 'E118:')
1065deeb3f1SBram Moolenaarendfunc
1075deeb3f1SBram Moolenaar
1085deeb3f1SBram Moolenaarfunc TakesOneArg(arg)
1095deeb3f1SBram Moolenaar  echo a:arg
1105deeb3f1SBram Moolenaarendfunc
1115deeb3f1SBram Moolenaar
1125deeb3f1SBram Moolenaardef Test_call_wrong_args()
1135deeb3f1SBram Moolenaar  call CheckDefFailure(['TakesOneArg()'], 'E119:')
1145deeb3f1SBram Moolenaar  call CheckDefFailure(['TakesOneArg(11, 22)'], 'E118:')
1155deeb3f1SBram Moolenaar  call CheckDefFailure(['bufnr(xxx)'], 'E1001:')
1165deeb3f1SBram Moolenaarenddef
1175deeb3f1SBram Moolenaar
1185deeb3f1SBram Moolenaar" Default arg and varargs
1195deeb3f1SBram Moolenaardef MyDefVarargs(one: string, two = 'foo', ...rest: list<string>): string
1205deeb3f1SBram Moolenaar  let res = one .. ',' .. two
1215deeb3f1SBram Moolenaar  for s in rest
1225deeb3f1SBram Moolenaar    res ..= ',' .. s
1235deeb3f1SBram Moolenaar  endfor
1245deeb3f1SBram Moolenaar  return res
1255deeb3f1SBram Moolenaarenddef
1265deeb3f1SBram Moolenaar
1275deeb3f1SBram Moolenaardef Test_call_def_varargs()
1285deeb3f1SBram Moolenaar  call assert_fails('call MyDefVarargs()', 'E119:')
1295deeb3f1SBram Moolenaar  assert_equal('one,foo', MyDefVarargs('one'))
1305deeb3f1SBram Moolenaar  assert_equal('one,two', MyDefVarargs('one', 'two'))
1315deeb3f1SBram Moolenaar  assert_equal('one,two,three', MyDefVarargs('one', 'two', 'three'))
13249cf7cc8SBram Moolenaar  call CheckDefFailure(['MyDefVarargs("one", 22)'], 'E1013: argument 2: type mismatch, expected string but got number')
1335deeb3f1SBram Moolenaarenddef
1345deeb3f1SBram Moolenaar
1351378fbc4SBram Moolenaarlet s:value = ''
1361378fbc4SBram Moolenaar
1371378fbc4SBram Moolenaardef FuncOneDefArg(opt = 'text')
1381378fbc4SBram Moolenaar  s:value = opt
1391378fbc4SBram Moolenaarenddef
1401378fbc4SBram Moolenaar
1411378fbc4SBram Moolenaardef FuncTwoDefArg(nr = 123, opt = 'text'): string
1421378fbc4SBram Moolenaar  return nr .. opt
1431378fbc4SBram Moolenaarenddef
1441378fbc4SBram Moolenaar
1451378fbc4SBram Moolenaardef FuncVarargs(...arg: list<string>): string
1461378fbc4SBram Moolenaar  return join(arg, ',')
1471378fbc4SBram Moolenaarenddef
1481378fbc4SBram Moolenaar
1491378fbc4SBram Moolenaardef Test_func_type_varargs()
1501378fbc4SBram Moolenaar  let RefDefArg: func(?string)
1511378fbc4SBram Moolenaar  RefDefArg = FuncOneDefArg
1521378fbc4SBram Moolenaar  RefDefArg()
1531378fbc4SBram Moolenaar  assert_equal('text', s:value)
1541378fbc4SBram Moolenaar  RefDefArg('some')
1551378fbc4SBram Moolenaar  assert_equal('some', s:value)
1561378fbc4SBram Moolenaar
1571378fbc4SBram Moolenaar  let RefDef2Arg: func(?number, ?string): string
1581378fbc4SBram Moolenaar  RefDef2Arg = FuncTwoDefArg
1591378fbc4SBram Moolenaar  assert_equal('123text', RefDef2Arg())
1601378fbc4SBram Moolenaar  assert_equal('99text', RefDef2Arg(99))
1611378fbc4SBram Moolenaar  assert_equal('77some', RefDef2Arg(77, 'some'))
1621378fbc4SBram Moolenaar
1631378fbc4SBram Moolenaar  call CheckDefFailure(['let RefWrong: func(string?)'], 'E1010:')
1641378fbc4SBram Moolenaar  call CheckDefFailure(['let RefWrong: func(?string, string)'], 'E1007:')
1651378fbc4SBram Moolenaar
1661378fbc4SBram Moolenaar  let RefVarargs: func(...list<string>): string
1671378fbc4SBram Moolenaar  RefVarargs = FuncVarargs
1681378fbc4SBram Moolenaar  assert_equal('', RefVarargs())
1691378fbc4SBram Moolenaar  assert_equal('one', RefVarargs('one'))
1701378fbc4SBram Moolenaar  assert_equal('one,two', RefVarargs('one', 'two'))
1711378fbc4SBram Moolenaar
1721378fbc4SBram Moolenaar  call CheckDefFailure(['let RefWrong: func(...list<string>, string)'], 'E110:')
1731378fbc4SBram Moolenaar  call CheckDefFailure(['let RefWrong: func(...list<string>, ?string)'], 'E110:')
1741378fbc4SBram Moolenaarenddef
1751378fbc4SBram Moolenaar
1760b76b42dSBram Moolenaar" Only varargs
1770b76b42dSBram Moolenaardef MyVarargsOnly(...args: list<string>): string
1780b76b42dSBram Moolenaar  return join(args, ',')
1790b76b42dSBram Moolenaarenddef
1800b76b42dSBram Moolenaar
1810b76b42dSBram Moolenaardef Test_call_varargs_only()
1820b76b42dSBram Moolenaar  assert_equal('', MyVarargsOnly())
1830b76b42dSBram Moolenaar  assert_equal('one', MyVarargsOnly('one'))
1840b76b42dSBram Moolenaar  assert_equal('one,two', MyVarargsOnly('one', 'two'))
1850b76b42dSBram Moolenaar  call CheckDefFailure(['MyVarargsOnly(1)'], 'E1013: argument 1: type mismatch, expected string but got number')
1860b76b42dSBram Moolenaar  call CheckDefFailure(['MyVarargsOnly("one", 2)'], 'E1013: argument 2: type mismatch, expected string but got number')
1870b76b42dSBram Moolenaarenddef
1880b76b42dSBram Moolenaar
1895deeb3f1SBram Moolenaardef Test_using_var_as_arg()
1905deeb3f1SBram Moolenaar  call writefile(['def Func(x: number)',  'let x = 234', 'enddef'], 'Xdef')
1915deeb3f1SBram Moolenaar  call assert_fails('so Xdef', 'E1006:')
1925deeb3f1SBram Moolenaar  call delete('Xdef')
1935deeb3f1SBram Moolenaarenddef
1945deeb3f1SBram Moolenaar
1955deeb3f1SBram Moolenaardef Test_call_func_defined_later()
1961df8b3fbSBram Moolenaar  call assert_equal('one', g:DefinedLater('one'))
1975deeb3f1SBram Moolenaar  call assert_fails('call NotDefined("one")', 'E117:')
1985deeb3f1SBram Moolenaarenddef
1995deeb3f1SBram Moolenaar
2001df8b3fbSBram Moolenaarfunc DefinedLater(arg)
2011df8b3fbSBram Moolenaar  return a:arg
2021df8b3fbSBram Moolenaarendfunc
2031df8b3fbSBram Moolenaar
2041df8b3fbSBram Moolenaardef Test_call_funcref()
2051df8b3fbSBram Moolenaar  assert_equal(3, g:SomeFunc('abc'))
2061df8b3fbSBram Moolenaar  assert_fails('NotAFunc()', 'E117:')
2071df8b3fbSBram Moolenaar  assert_fails('g:NotAFunc()', 'E117:')
2081df8b3fbSBram Moolenaarenddef
2091df8b3fbSBram Moolenaar
2101df8b3fbSBram Moolenaarlet SomeFunc = function('len')
2111df8b3fbSBram Moolenaarlet NotAFunc = 'text'
2121df8b3fbSBram Moolenaar
21399aaf0ceSBram Moolenaardef CombineFuncrefTypes()
21499aaf0ceSBram Moolenaar  " same arguments, different return type
21599aaf0ceSBram Moolenaar  let Ref1: func(bool): string
21699aaf0ceSBram Moolenaar  let Ref2: func(bool): number
21799aaf0ceSBram Moolenaar  let Ref3: func(bool): any
21899aaf0ceSBram Moolenaar  Ref3 = g:cond ? Ref1 : Ref2
21999aaf0ceSBram Moolenaar
22099aaf0ceSBram Moolenaar  " different number of arguments
22199aaf0ceSBram Moolenaar  let Refa1: func(bool): number
22299aaf0ceSBram Moolenaar  let Refa2: func(bool, number): number
22399aaf0ceSBram Moolenaar  let Refa3: func: number
22499aaf0ceSBram Moolenaar  Refa3 = g:cond ? Refa1 : Refa2
22599aaf0ceSBram Moolenaar
22699aaf0ceSBram Moolenaar  " different argument types
22799aaf0ceSBram Moolenaar  let Refb1: func(bool, string): number
22899aaf0ceSBram Moolenaar  let Refb2: func(string, number): number
22999aaf0ceSBram Moolenaar  let Refb3: func(any, any): number
23099aaf0ceSBram Moolenaar  Refb3 = g:cond ? Refb1 : Refb2
23199aaf0ceSBram Moolenaarenddef
23299aaf0ceSBram Moolenaar
2335deeb3f1SBram Moolenaardef FuncWithForwardCall()
2341df8b3fbSBram Moolenaar  return g:DefinedEvenLater("yes")
2355deeb3f1SBram Moolenaarenddef
2365deeb3f1SBram Moolenaar
2375deeb3f1SBram Moolenaardef DefinedEvenLater(arg: string): string
2385deeb3f1SBram Moolenaar  return arg
2395deeb3f1SBram Moolenaarenddef
2405deeb3f1SBram Moolenaar
2415deeb3f1SBram Moolenaardef Test_error_in_nested_function()
2425deeb3f1SBram Moolenaar  " Error in called function requires unwinding the call stack.
2435deeb3f1SBram Moolenaar  assert_fails('call FuncWithForwardCall()', 'E1029')
2445deeb3f1SBram Moolenaarenddef
2455deeb3f1SBram Moolenaar
2465deeb3f1SBram Moolenaardef Test_return_type_wrong()
2475deeb3f1SBram Moolenaar  CheckScriptFailure(['def Func(): number', 'return "a"', 'enddef'], 'expected number but got string')
2485deeb3f1SBram Moolenaar  CheckScriptFailure(['def Func(): string', 'return 1', 'enddef'], 'expected string but got number')
2495deeb3f1SBram Moolenaar  CheckScriptFailure(['def Func(): void', 'return "a"', 'enddef'], 'expected void but got string')
2505deeb3f1SBram Moolenaar  CheckScriptFailure(['def Func()', 'return "a"', 'enddef'], 'expected void but got string')
2515deeb3f1SBram Moolenaar
2525deeb3f1SBram Moolenaar  CheckScriptFailure(['def Func(): number', 'return', 'enddef'], 'E1003:')
2535deeb3f1SBram Moolenaar
2545deeb3f1SBram Moolenaar  CheckScriptFailure(['def Func(): list', 'return []', 'enddef'], 'E1008:')
2555deeb3f1SBram Moolenaar  CheckScriptFailure(['def Func(): dict', 'return {}', 'enddef'], 'E1008:')
256ee4e0c1eSBram Moolenaar  CheckScriptFailure(['def Func()', 'return 1'], 'E1057:')
2575deeb3f1SBram Moolenaarenddef
2585deeb3f1SBram Moolenaar
2595deeb3f1SBram Moolenaardef Test_arg_type_wrong()
2605deeb3f1SBram Moolenaar  CheckScriptFailure(['def Func3(items: list)', 'echo "a"', 'enddef'], 'E1008: Missing <type>')
261ee4e0c1eSBram Moolenaar  CheckScriptFailure(['def Func4(...)', 'echo "a"', 'enddef'], 'E1055: Missing name after ...')
262f93c7feaSBram Moolenaar  CheckScriptFailure(['def Func5(items:string)', 'echo "a"'], 'E1069:')
2636e949784SBram Moolenaar  CheckScriptFailure(['def Func5(items)', 'echo "a"'], 'E1077:')
2645deeb3f1SBram Moolenaarenddef
2655deeb3f1SBram Moolenaar
2665deeb3f1SBram Moolenaardef Test_vim9script_call()
2675deeb3f1SBram Moolenaar  let lines =<< trim END
2685deeb3f1SBram Moolenaar    vim9script
2695deeb3f1SBram Moolenaar    let var = ''
2705deeb3f1SBram Moolenaar    def MyFunc(arg: string)
2715deeb3f1SBram Moolenaar       var = arg
2725deeb3f1SBram Moolenaar    enddef
2735deeb3f1SBram Moolenaar    MyFunc('foobar')
2745deeb3f1SBram Moolenaar    assert_equal('foobar', var)
2755deeb3f1SBram Moolenaar
2765deeb3f1SBram Moolenaar    let str = 'barfoo'
2775deeb3f1SBram Moolenaar    str->MyFunc()
2785deeb3f1SBram Moolenaar    assert_equal('barfoo', var)
2795deeb3f1SBram Moolenaar
2805deeb3f1SBram Moolenaar    let g:value = 'value'
2815deeb3f1SBram Moolenaar    g:value->MyFunc()
2825deeb3f1SBram Moolenaar    assert_equal('value', var)
2835deeb3f1SBram Moolenaar
2845deeb3f1SBram Moolenaar    let listvar = []
2855deeb3f1SBram Moolenaar    def ListFunc(arg: list<number>)
2865deeb3f1SBram Moolenaar       listvar = arg
2875deeb3f1SBram Moolenaar    enddef
2885deeb3f1SBram Moolenaar    [1, 2, 3]->ListFunc()
2895deeb3f1SBram Moolenaar    assert_equal([1, 2, 3], listvar)
2905deeb3f1SBram Moolenaar
2915deeb3f1SBram Moolenaar    let dictvar = {}
2925deeb3f1SBram Moolenaar    def DictFunc(arg: dict<number>)
2935deeb3f1SBram Moolenaar       dictvar = arg
2945deeb3f1SBram Moolenaar    enddef
2955deeb3f1SBram Moolenaar    {'a': 1, 'b': 2}->DictFunc()
2965deeb3f1SBram Moolenaar    assert_equal(#{a: 1, b: 2}, dictvar)
2975deeb3f1SBram Moolenaar    def CompiledDict()
2985deeb3f1SBram Moolenaar      {'a': 3, 'b': 4}->DictFunc()
2995deeb3f1SBram Moolenaar    enddef
3005deeb3f1SBram Moolenaar    CompiledDict()
3015deeb3f1SBram Moolenaar    assert_equal(#{a: 3, b: 4}, dictvar)
3025deeb3f1SBram Moolenaar
3035deeb3f1SBram Moolenaar    #{a: 3, b: 4}->DictFunc()
3045deeb3f1SBram Moolenaar    assert_equal(#{a: 3, b: 4}, dictvar)
3055deeb3f1SBram Moolenaar
3065deeb3f1SBram Moolenaar    ('text')->MyFunc()
3075deeb3f1SBram Moolenaar    assert_equal('text', var)
3085deeb3f1SBram Moolenaar    ("some")->MyFunc()
3095deeb3f1SBram Moolenaar    assert_equal('some', var)
3105deeb3f1SBram Moolenaar  END
3115deeb3f1SBram Moolenaar  writefile(lines, 'Xcall.vim')
3125deeb3f1SBram Moolenaar  source Xcall.vim
3135deeb3f1SBram Moolenaar  delete('Xcall.vim')
3145deeb3f1SBram Moolenaarenddef
3155deeb3f1SBram Moolenaar
3165deeb3f1SBram Moolenaardef Test_vim9script_call_fail_decl()
3175deeb3f1SBram Moolenaar  let lines =<< trim END
3185deeb3f1SBram Moolenaar    vim9script
3195deeb3f1SBram Moolenaar    let var = ''
3205deeb3f1SBram Moolenaar    def MyFunc(arg: string)
3215deeb3f1SBram Moolenaar       let var = 123
3225deeb3f1SBram Moolenaar    enddef
3235deeb3f1SBram Moolenaar  END
3245deeb3f1SBram Moolenaar  writefile(lines, 'Xcall_decl.vim')
3255deeb3f1SBram Moolenaar  assert_fails('source Xcall_decl.vim', 'E1054:')
3265deeb3f1SBram Moolenaar  delete('Xcall_decl.vim')
3275deeb3f1SBram Moolenaarenddef
3285deeb3f1SBram Moolenaar
3295deeb3f1SBram Moolenaardef Test_vim9script_call_fail_const()
3305deeb3f1SBram Moolenaar  let lines =<< trim END
3315deeb3f1SBram Moolenaar    vim9script
3325deeb3f1SBram Moolenaar    const var = ''
3335deeb3f1SBram Moolenaar    def MyFunc(arg: string)
3345deeb3f1SBram Moolenaar       var = 'asdf'
3355deeb3f1SBram Moolenaar    enddef
3365deeb3f1SBram Moolenaar  END
3375deeb3f1SBram Moolenaar  writefile(lines, 'Xcall_const.vim')
3385deeb3f1SBram Moolenaar  assert_fails('source Xcall_const.vim', 'E46:')
3395deeb3f1SBram Moolenaar  delete('Xcall_const.vim')
3405deeb3f1SBram Moolenaarenddef
3415deeb3f1SBram Moolenaar
3425deeb3f1SBram Moolenaar" Test that inside :function a Python function can be defined, :def is not
3435deeb3f1SBram Moolenaar" recognized.
3445deeb3f1SBram Moolenaarfunc Test_function_python()
3455deeb3f1SBram Moolenaar  CheckFeature python3
3465deeb3f1SBram Moolenaar  let py = 'python3'
3475deeb3f1SBram Moolenaar  execute py "<< EOF"
3485deeb3f1SBram Moolenaardef do_something():
3495deeb3f1SBram Moolenaar  return 1
3505deeb3f1SBram MoolenaarEOF
3515deeb3f1SBram Moolenaarendfunc
3525deeb3f1SBram Moolenaar
3535deeb3f1SBram Moolenaardef Test_delfunc()
3545deeb3f1SBram Moolenaar  let lines =<< trim END
3555deeb3f1SBram Moolenaar    vim9script
3564c17ad94SBram Moolenaar    def g:GoneSoon()
3575deeb3f1SBram Moolenaar      echo 'hello'
3585deeb3f1SBram Moolenaar    enddef
3595deeb3f1SBram Moolenaar
3605deeb3f1SBram Moolenaar    def CallGoneSoon()
3615deeb3f1SBram Moolenaar      GoneSoon()
3625deeb3f1SBram Moolenaar    enddef
3635deeb3f1SBram Moolenaar
3644c17ad94SBram Moolenaar    delfunc g:GoneSoon
3655deeb3f1SBram Moolenaar    CallGoneSoon()
3665deeb3f1SBram Moolenaar  END
3675deeb3f1SBram Moolenaar  writefile(lines, 'XToDelFunc')
3685deeb3f1SBram Moolenaar  assert_fails('so XToDelFunc', 'E933')
3695deeb3f1SBram Moolenaar  assert_fails('so XToDelFunc', 'E933')
3705deeb3f1SBram Moolenaar
3715deeb3f1SBram Moolenaar  delete('XToDelFunc')
3725deeb3f1SBram Moolenaarenddef
3735deeb3f1SBram Moolenaar
3745deeb3f1SBram Moolenaardef Test_redef_failure()
3755deeb3f1SBram Moolenaar  call writefile(['def Func0(): string',  'return "Func0"', 'enddef'], 'Xdef')
3765deeb3f1SBram Moolenaar  so Xdef
3775deeb3f1SBram Moolenaar  call writefile(['def Func1(): string',  'return "Func1"', 'enddef'], 'Xdef')
3785deeb3f1SBram Moolenaar  so Xdef
3795deeb3f1SBram Moolenaar  call writefile(['def! Func0(): string', 'enddef'], 'Xdef')
3805deeb3f1SBram Moolenaar  call assert_fails('so Xdef', 'E1027:')
3815deeb3f1SBram Moolenaar  call writefile(['def Func2(): string',  'return "Func2"', 'enddef'], 'Xdef')
3825deeb3f1SBram Moolenaar  so Xdef
3835deeb3f1SBram Moolenaar  call delete('Xdef')
3845deeb3f1SBram Moolenaar
3851df8b3fbSBram Moolenaar  call assert_equal(0, g:Func0())
3861df8b3fbSBram Moolenaar  call assert_equal('Func1', g:Func1())
3871df8b3fbSBram Moolenaar  call assert_equal('Func2', g:Func2())
3885deeb3f1SBram Moolenaar
3895deeb3f1SBram Moolenaar  delfunc! Func0
3905deeb3f1SBram Moolenaar  delfunc! Func1
3915deeb3f1SBram Moolenaar  delfunc! Func2
3925deeb3f1SBram Moolenaarenddef
3935deeb3f1SBram Moolenaar
394f93c7feaSBram Moolenaardef Test_vim9script_func()
395f93c7feaSBram Moolenaar  let lines =<< trim END
396f93c7feaSBram Moolenaar    vim9script
397f93c7feaSBram Moolenaar    func Func(arg)
398f93c7feaSBram Moolenaar      echo a:arg
399f93c7feaSBram Moolenaar    endfunc
400f93c7feaSBram Moolenaar    Func('text')
401f93c7feaSBram Moolenaar  END
402f93c7feaSBram Moolenaar  writefile(lines, 'XVim9Func')
403f93c7feaSBram Moolenaar  so XVim9Func
404f93c7feaSBram Moolenaar
405f93c7feaSBram Moolenaar  delete('XVim9Func')
406f93c7feaSBram Moolenaarenddef
407f93c7feaSBram Moolenaar
4085deeb3f1SBram Moolenaar" Test for internal functions returning different types
4095deeb3f1SBram Moolenaarfunc Test_InternalFuncRetType()
4105deeb3f1SBram Moolenaar  let lines =<< trim END
4115deeb3f1SBram Moolenaar    def RetFloat(): float
4125deeb3f1SBram Moolenaar      return ceil(1.456)
4135deeb3f1SBram Moolenaar    enddef
4145deeb3f1SBram Moolenaar
4155deeb3f1SBram Moolenaar    def RetListAny(): list<any>
4165deeb3f1SBram Moolenaar      return items({'k' : 'v'})
4175deeb3f1SBram Moolenaar    enddef
4185deeb3f1SBram Moolenaar
4195deeb3f1SBram Moolenaar    def RetListString(): list<string>
4205deeb3f1SBram Moolenaar      return split('a:b:c', ':')
4215deeb3f1SBram Moolenaar    enddef
4225deeb3f1SBram Moolenaar
4235deeb3f1SBram Moolenaar    def RetListDictAny(): list<dict<any>>
4245deeb3f1SBram Moolenaar      return getbufinfo()
4255deeb3f1SBram Moolenaar    enddef
4265deeb3f1SBram Moolenaar
4275deeb3f1SBram Moolenaar    def RetDictNumber(): dict<number>
4285deeb3f1SBram Moolenaar      return wordcount()
4295deeb3f1SBram Moolenaar    enddef
4305deeb3f1SBram Moolenaar
4315deeb3f1SBram Moolenaar    def RetDictString(): dict<string>
4325deeb3f1SBram Moolenaar      return environ()
4335deeb3f1SBram Moolenaar    enddef
4345deeb3f1SBram Moolenaar  END
4355deeb3f1SBram Moolenaar  call writefile(lines, 'Xscript')
4365deeb3f1SBram Moolenaar  source Xscript
4375deeb3f1SBram Moolenaar
4385deeb3f1SBram Moolenaar  call assert_equal(2.0, RetFloat())
4395deeb3f1SBram Moolenaar  call assert_equal([['k', 'v']], RetListAny())
4405deeb3f1SBram Moolenaar  call assert_equal(['a', 'b', 'c'], RetListString())
4415deeb3f1SBram Moolenaar  call assert_notequal([], RetListDictAny())
4425deeb3f1SBram Moolenaar  call assert_notequal({}, RetDictNumber())
4435deeb3f1SBram Moolenaar  call assert_notequal({}, RetDictString())
4445deeb3f1SBram Moolenaar  call delete('Xscript')
4455deeb3f1SBram Moolenaarendfunc
4465deeb3f1SBram Moolenaar
4475deeb3f1SBram Moolenaar" Test for passing too many or too few arguments to internal functions
4485deeb3f1SBram Moolenaarfunc Test_internalfunc_arg_error()
4495deeb3f1SBram Moolenaar  let l =<< trim END
4505deeb3f1SBram Moolenaar    def! FArgErr(): float
4515deeb3f1SBram Moolenaar      return ceil(1.1, 2)
4525deeb3f1SBram Moolenaar    enddef
4535deeb3f1SBram Moolenaar  END
4545deeb3f1SBram Moolenaar  call writefile(l, 'Xinvalidarg')
4555deeb3f1SBram Moolenaar  call assert_fails('so Xinvalidarg', 'E118:')
4565deeb3f1SBram Moolenaar  let l =<< trim END
4575deeb3f1SBram Moolenaar    def! FArgErr(): float
4585deeb3f1SBram Moolenaar      return ceil()
4595deeb3f1SBram Moolenaar    enddef
4605deeb3f1SBram Moolenaar  END
4615deeb3f1SBram Moolenaar  call writefile(l, 'Xinvalidarg')
4625deeb3f1SBram Moolenaar  call assert_fails('so Xinvalidarg', 'E119:')
4635deeb3f1SBram Moolenaar  call delete('Xinvalidarg')
4645deeb3f1SBram Moolenaarendfunc
4655deeb3f1SBram Moolenaar
4665deeb3f1SBram Moolenaarlet s:funcResult = 0
4675deeb3f1SBram Moolenaar
4685deeb3f1SBram Moolenaardef FuncNoArgNoRet()
4695deeb3f1SBram Moolenaar  funcResult = 11
4705deeb3f1SBram Moolenaarenddef
4715deeb3f1SBram Moolenaar
4725deeb3f1SBram Moolenaardef FuncNoArgRetNumber(): number
4735deeb3f1SBram Moolenaar  funcResult = 22
4745deeb3f1SBram Moolenaar  return 1234
4755deeb3f1SBram Moolenaarenddef
4765deeb3f1SBram Moolenaar
477ec5929d0SBram Moolenaardef FuncNoArgRetString(): string
478ec5929d0SBram Moolenaar  funcResult = 45
479ec5929d0SBram Moolenaar  return 'text'
480ec5929d0SBram Moolenaarenddef
481ec5929d0SBram Moolenaar
4825deeb3f1SBram Moolenaardef FuncOneArgNoRet(arg: number)
4835deeb3f1SBram Moolenaar  funcResult = arg
4845deeb3f1SBram Moolenaarenddef
4855deeb3f1SBram Moolenaar
4865deeb3f1SBram Moolenaardef FuncOneArgRetNumber(arg: number): number
4875deeb3f1SBram Moolenaar  funcResult = arg
4885deeb3f1SBram Moolenaar  return arg
4895deeb3f1SBram Moolenaarenddef
4905deeb3f1SBram Moolenaar
49108938eebSBram Moolenaardef FuncTwoArgNoRet(one: bool, two: number)
49208938eebSBram Moolenaar  funcResult = two
49308938eebSBram Moolenaarenddef
49408938eebSBram Moolenaar
495ec5929d0SBram Moolenaardef FuncOneArgRetString(arg: string): string
496ec5929d0SBram Moolenaar  return arg
497ec5929d0SBram Moolenaarenddef
498ec5929d0SBram Moolenaar
4998922860aSBram Moolenaardef FuncOneArgRetAny(arg: any): any
5008922860aSBram Moolenaar  return arg
5018922860aSBram Moolenaarenddef
5028922860aSBram Moolenaar
5035deeb3f1SBram Moolenaardef Test_func_type()
5045deeb3f1SBram Moolenaar  let Ref1: func()
5055deeb3f1SBram Moolenaar  funcResult = 0
5065deeb3f1SBram Moolenaar  Ref1 = FuncNoArgNoRet
5075deeb3f1SBram Moolenaar  Ref1()
5085deeb3f1SBram Moolenaar  assert_equal(11, funcResult)
5094c683750SBram Moolenaar
5104c683750SBram Moolenaar  let Ref2: func
5114c683750SBram Moolenaar  funcResult = 0
5124c683750SBram Moolenaar  Ref2 = FuncNoArgNoRet
5134c683750SBram Moolenaar  Ref2()
5144c683750SBram Moolenaar  assert_equal(11, funcResult)
5154c683750SBram Moolenaar
5164c683750SBram Moolenaar  funcResult = 0
5174c683750SBram Moolenaar  Ref2 = FuncOneArgNoRet
5184c683750SBram Moolenaar  Ref2(12)
5194c683750SBram Moolenaar  assert_equal(12, funcResult)
5204c683750SBram Moolenaar
5214c683750SBram Moolenaar  funcResult = 0
5224c683750SBram Moolenaar  Ref2 = FuncNoArgRetNumber
5234c683750SBram Moolenaar  assert_equal(1234, Ref2())
5244c683750SBram Moolenaar  assert_equal(22, funcResult)
5254c683750SBram Moolenaar
5264c683750SBram Moolenaar  funcResult = 0
5274c683750SBram Moolenaar  Ref2 = FuncOneArgRetNumber
5284c683750SBram Moolenaar  assert_equal(13, Ref2(13))
5294c683750SBram Moolenaar  assert_equal(13, funcResult)
5305deeb3f1SBram Moolenaarenddef
5315deeb3f1SBram Moolenaar
532ec5929d0SBram Moolenaardef Test_func_type_part()
533ec5929d0SBram Moolenaar  let RefVoid: func: void
534ec5929d0SBram Moolenaar  RefVoid = FuncNoArgNoRet
535ec5929d0SBram Moolenaar  RefVoid = FuncOneArgNoRet
536ec5929d0SBram Moolenaar  CheckDefFailure(['let RefVoid: func: void', 'RefVoid = FuncNoArgRetNumber'], 'E1013: type mismatch, expected func() but got func(): number')
537ec5929d0SBram Moolenaar  CheckDefFailure(['let RefVoid: func: void', 'RefVoid = FuncNoArgRetString'], 'E1013: type mismatch, expected func() but got func(): string')
538ec5929d0SBram Moolenaar
539ec5929d0SBram Moolenaar  let RefAny: func(): any
540ec5929d0SBram Moolenaar  RefAny = FuncNoArgRetNumber
541ec5929d0SBram Moolenaar  RefAny = FuncNoArgRetString
542ec5929d0SBram Moolenaar  CheckDefFailure(['let RefAny: func(): any', 'RefAny = FuncNoArgNoRet'], 'E1013: type mismatch, expected func(): any but got func()')
543ec5929d0SBram Moolenaar  CheckDefFailure(['let RefAny: func(): any', 'RefAny = FuncOneArgNoRet'], 'E1013: type mismatch, expected func(): any but got func(number)')
544ec5929d0SBram Moolenaar
545ec5929d0SBram Moolenaar  let RefNr: func: number
546ec5929d0SBram Moolenaar  RefNr = FuncNoArgRetNumber
547ec5929d0SBram Moolenaar  RefNr = FuncOneArgRetNumber
548ec5929d0SBram Moolenaar  CheckDefFailure(['let RefNr: func: number', 'RefNr = FuncNoArgNoRet'], 'E1013: type mismatch, expected func(): number but got func()')
549ec5929d0SBram Moolenaar  CheckDefFailure(['let RefNr: func: number', 'RefNr = FuncNoArgRetString'], 'E1013: type mismatch, expected func(): number but got func(): string')
550ec5929d0SBram Moolenaar
551ec5929d0SBram Moolenaar  let RefStr: func: string
552ec5929d0SBram Moolenaar  RefStr = FuncNoArgRetString
553ec5929d0SBram Moolenaar  RefStr = FuncOneArgRetString
554ec5929d0SBram Moolenaar  CheckDefFailure(['let RefStr: func: string', 'RefStr = FuncNoArgNoRet'], 'E1013: type mismatch, expected func(): string but got func()')
555ec5929d0SBram Moolenaar  CheckDefFailure(['let RefStr: func: string', 'RefStr = FuncNoArgRetNumber'], 'E1013: type mismatch, expected func(): string but got func(): number')
556ec5929d0SBram Moolenaarenddef
557ec5929d0SBram Moolenaar
5585deeb3f1SBram Moolenaardef Test_func_type_fails()
5595deeb3f1SBram Moolenaar  CheckDefFailure(['let ref1: func()'], 'E704:')
5605deeb3f1SBram Moolenaar
5615deeb3f1SBram Moolenaar  CheckDefFailure(['let Ref1: func()', 'Ref1 = FuncNoArgRetNumber'], 'E1013: type mismatch, expected func() but got func(): number')
5625deeb3f1SBram Moolenaar  CheckDefFailure(['let Ref1: func()', 'Ref1 = FuncOneArgNoRet'], 'E1013: type mismatch, expected func() but got func(number)')
5635deeb3f1SBram Moolenaar  CheckDefFailure(['let Ref1: func()', 'Ref1 = FuncOneArgRetNumber'], 'E1013: type mismatch, expected func() but got func(number): number')
56408938eebSBram Moolenaar  CheckDefFailure(['let Ref1: func(bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1013: type mismatch, expected func(bool) but got func(bool, number)')
56508938eebSBram Moolenaar  CheckDefFailure(['let Ref1: func(?bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1013: type mismatch, expected func(?bool) but got func(bool, number)')
56608938eebSBram Moolenaar  CheckDefFailure(['let Ref1: func(...bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1013: type mismatch, expected func(...bool) but got func(bool, number)')
56708938eebSBram Moolenaar
56808938eebSBram Moolenaar  call CheckDefFailure(['let RefWrong: func(string ,number)'], 'E1068:')
56908938eebSBram Moolenaar  call CheckDefFailure(['let RefWrong: func(string,number)'], 'E1069:')
57008938eebSBram Moolenaar  call CheckDefFailure(['let RefWrong: func(bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool)'], 'E740:')
57108938eebSBram Moolenaar  call CheckDefFailure(['let RefWrong: func(bool):string'], 'E1069:')
5725deeb3f1SBram Moolenaarenddef
5735deeb3f1SBram Moolenaar
5748922860aSBram Moolenaardef Test_func_return_type()
5758922860aSBram Moolenaar  let nr: number
5768922860aSBram Moolenaar  nr = FuncNoArgRetNumber()
5778922860aSBram Moolenaar  assert_equal(1234, nr)
5788922860aSBram Moolenaar
5798922860aSBram Moolenaar  nr = FuncOneArgRetAny(122)
5808922860aSBram Moolenaar  assert_equal(122, nr)
5818922860aSBram Moolenaar
5828922860aSBram Moolenaar  let str: string
5838922860aSBram Moolenaar  str = FuncOneArgRetAny('yes')
5848922860aSBram Moolenaar  assert_equal('yes', str)
5858922860aSBram Moolenaar
5868922860aSBram Moolenaar  CheckDefFailure(['let str: string', 'str = FuncNoArgRetNumber()'], 'E1013: type mismatch, expected string but got number')
5878922860aSBram Moolenaarenddef
5888922860aSBram Moolenaar
5895e774c75SBram Moolenaardef MultiLine(
5905e774c75SBram Moolenaar    arg1: string,
5915e774c75SBram Moolenaar    arg2 = 1234,
5925e774c75SBram Moolenaar    ...rest: list<string>
5935e774c75SBram Moolenaar      ): string
5945e774c75SBram Moolenaar  return arg1 .. arg2 .. join(rest, '-')
5955e774c75SBram Moolenaarenddef
5965e774c75SBram Moolenaar
5972c330432SBram Moolenaardef MultiLineComment(
5982c330432SBram Moolenaar    arg1: string, # comment
5992c330432SBram Moolenaar    arg2 = 1234, # comment
6002c330432SBram Moolenaar    ...rest: list<string> # comment
6012c330432SBram Moolenaar      ): string # comment
6022c330432SBram Moolenaar  return arg1 .. arg2 .. join(rest, '-')
6032c330432SBram Moolenaarenddef
6042c330432SBram Moolenaar
6055e774c75SBram Moolenaardef Test_multiline()
6065e774c75SBram Moolenaar  assert_equal('text1234', MultiLine('text'))
6075e774c75SBram Moolenaar  assert_equal('text777', MultiLine('text', 777))
6085e774c75SBram Moolenaar  assert_equal('text777one', MultiLine('text', 777, 'one'))
6095e774c75SBram Moolenaar  assert_equal('text777one-two', MultiLine('text', 777, 'one', 'two'))
6105e774c75SBram Moolenaarenddef
6115e774c75SBram Moolenaar
61223e03252SBram Moolenaarfunc Test_multiline_not_vim9()
61323e03252SBram Moolenaar  call assert_equal('text1234', MultiLine('text'))
61423e03252SBram Moolenaar  call assert_equal('text777', MultiLine('text', 777))
61523e03252SBram Moolenaar  call assert_equal('text777one', MultiLine('text', 777, 'one'))
61623e03252SBram Moolenaar  call assert_equal('text777one-two', MultiLine('text', 777, 'one', 'two'))
61723e03252SBram Moolenaarendfunc
61823e03252SBram Moolenaar
6195e774c75SBram Moolenaar
620ee4e0c1eSBram Moolenaar" When using CheckScriptFailure() for the below test, E1010 is generated instead
621ee4e0c1eSBram Moolenaar" of E1056.
622ee4e0c1eSBram Moolenaarfunc Test_E1056_1059()
623ee4e0c1eSBram Moolenaar  let caught_1056 = 0
624ee4e0c1eSBram Moolenaar  try
625ee4e0c1eSBram Moolenaar    def F():
626ee4e0c1eSBram Moolenaar      return 1
627ee4e0c1eSBram Moolenaar    enddef
628ee4e0c1eSBram Moolenaar  catch /E1056:/
629ee4e0c1eSBram Moolenaar    let caught_1056 = 1
630ee4e0c1eSBram Moolenaar  endtry
631ee4e0c1eSBram Moolenaar  call assert_equal(1, caught_1056)
632ee4e0c1eSBram Moolenaar
633ee4e0c1eSBram Moolenaar  let caught_1059 = 0
634ee4e0c1eSBram Moolenaar  try
635ee4e0c1eSBram Moolenaar    def F5(items : list)
636ee4e0c1eSBram Moolenaar      echo 'a'
637ee4e0c1eSBram Moolenaar    enddef
638ee4e0c1eSBram Moolenaar  catch /E1059:/
639ee4e0c1eSBram Moolenaar    let caught_1059 = 1
640ee4e0c1eSBram Moolenaar  endtry
641ee4e0c1eSBram Moolenaar  call assert_equal(1, caught_1059)
642ee4e0c1eSBram Moolenaarendfunc
6435deeb3f1SBram Moolenaar
644*c8cd2b34SBram Moolenaardef RefFunc(Ref: func(string): string): string
645*c8cd2b34SBram Moolenaar  return Ref('more')
646*c8cd2b34SBram Moolenaarenddef
647*c8cd2b34SBram Moolenaar
648*c8cd2b34SBram Moolenaardef Test_closure_simple()
649*c8cd2b34SBram Moolenaar  let local = 'some '
650*c8cd2b34SBram Moolenaar  assert_equal('some more', RefFunc({s -> local .. s}))
651*c8cd2b34SBram Moolenaarenddef
652*c8cd2b34SBram Moolenaar
6535deeb3f1SBram Moolenaar" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
654