2020-04-05 17:08:17 +02:00
" Test various aspects of the Vim9 script language.
source check .vim
2020-09-06 18:22:53 +02:00
source term_util .vim
2020-04-05 17:08:17 +02:00
source view_util .vim
2022-01-29 21:45:34 +00:00
import './vim9.vim' as v9
2020-07-05 18:18:42 +02:00
source screendump .vim
2020-04-05 17:08:17 +02:00
func Test_def_basic ( )
def SomeFunc ( ) : string
return 'yes'
enddef
2020-09-11 19:09:48 +02:00
call SomeFunc ( ) - > assert_equal ( 'yes' )
2020-04-05 17:08:17 +02:00
endfunc
2020-10-13 18:38:11 +02:00
func Test_compiling_error ( )
" use a terminal to see the whole error message
2020-10-12 22:07:13 +02:00
CheckRunVimInTerminal
2020-10-13 18:38:11 +02:00
call TestCompilingError ( )
2021-04-05 22:27:37 +02:00
call TestCompilingErrorInTry ( )
2020-10-13 18:38:11 +02:00
endfunc
def TestCompilingError ( )
2020-10-12 22:07:13 +02:00
var lines = < < trim END
vim9script
def Fails ( )
echo nothing
enddef
defcompile
END
2021-04-05 22:27:37 +02:00
writefile ( lines , 'XTest_compile_error' )
2022-01-29 21:45:34 +00:00
var buf = g :RunVimInTerminal ( '-S XTest_compile_error' ,
2020-12-02 17:36:54 +01:00
{rows : 10 , wait_for_ruler : 0 })
2022-01-29 21:45:34 +00:00
g :WaitForAssert ( ( ) = > assert_match ( 'Error detected while compiling command line.*Fails.*Variable not found: nothing' ,
g :Term_getlines ( buf , range ( 1 , 9 ) ) ) )
2020-10-12 22:07:13 +02:00
# clean up
2022-01-29 21:45:34 +00:00
g :StopVimInTerminal ( buf )
2021-04-05 22:27:37 +02:00
delete ( 'XTest_compile_error' )
enddef
def TestCompilingErrorInTry ( )
var dir = 'Xdir/autoload'
mkdir ( dir , 'p' )
var lines = < < trim END
vim9script
2022-01-30 18:40:44 +00:00
export def OnlyCompiled ( )
2021-04-05 22:27:37 +02:00
g :runtime = 'yes'
invalid
enddef
END
writefile ( lines , dir .. '/script.vim' )
lines = < < trim END
vim9script
todo
try
script #OnlyCompiled ( )
catch /nothing/
endtry
END
lines [1 ] = 'set rtp=' .. getcwd ( ) .. '/Xdir'
writefile ( lines , 'XTest_compile_error' )
2022-01-29 21:45:34 +00:00
var buf = g :RunVimInTerminal ( '-S XTest_compile_error' , {rows : 10 , wait_for_ruler : 0 })
g :WaitForAssert ( ( ) = > assert_match ( 'Error detected while compiling command line.*function script#OnlyCompiled.*Invalid command: invalid' ,
g :Term_getlines ( buf , range ( 1 , 9 ) ) ) )
2021-04-05 22:27:37 +02:00
# clean up
2022-01-29 21:45:34 +00:00
g :StopVimInTerminal ( buf )
2021-04-05 22:27:37 +02:00
delete ( 'XTest_compile_error' )
delete ( 'Xdir' , 'rf' )
2020-10-12 22:07:13 +02:00
enddef
2021-06-08 22:01:53 +02:00
def Test_compile_error_in_called_function ( )
var lines = < < trim END
vim9script
var n : number
def Foo ( )
&hls = n
enddef
def Bar ( )
Foo ( )
enddef
silent ! Foo ( )
Bar ( )
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptFailureList ( lines , ['E1012:' , 'E1191:' ])
2021-06-08 22:01:53 +02:00
enddef
2021-06-21 20:48:58 +02:00
def Test_wrong_function_name ( )
var lines = < < trim END
vim9script
func _Foo ( )
echo 'foo'
endfunc
END
2022-02-07 21:54:01 +00:00
v9 .CheckScriptFailure ( lines , 'E1267:' )
2021-06-21 20:48:58 +02:00
lines = < < trim END
vim9script
def _Foo ( )
echo 'foo'
enddef
END
2022-02-07 21:54:01 +00:00
v9 .CheckScriptFailure ( lines , 'E1267:' )
2022-02-23 22:12:02 +00:00
lines = < < trim END
vim9script
var Object = {}
function Object .Method ( )
endfunction
END
v9 .CheckScriptFailure ( lines , 'E1182:' )
lines = < < trim END
vim9script
var Object = {}
def Object .Method ( )
enddef
END
v9 .CheckScriptFailure ( lines , 'E1182:' )
lines = < < trim END
vim9script
g :Object = {}
function g :Object .Method ( )
endfunction
END
v9 .CheckScriptFailure ( lines , 'E1182:' )
lines = < < trim END
let s :Object = {}
def Define ( )
function s :Object .Method ( )
endfunction
enddef
defcompile
END
v9 .CheckScriptFailure ( lines , 'E1182:' )
delfunc g :Define
lines = < < trim END
let s :Object = {}
def Define ( )
def Object .Method ( )
enddef
enddef
defcompile
END
v9 .CheckScriptFailure ( lines , 'E1182:' )
delfunc g :Define
lines = < < trim END
let g :Object = {}
def Define ( )
function g :Object .Method ( )
endfunction
enddef
defcompile
END
v9 .CheckScriptFailure ( lines , 'E1182:' )
delfunc g :Define
2021-06-21 20:48:58 +02:00
enddef
2021-04-12 22:02:36 +02:00
def Test_autoload_name_mismatch ( )
var dir = 'Xdir/autoload'
mkdir ( dir , 'p' )
var lines = < < trim END
vim9script
2022-01-30 18:40:44 +00:00
export def NoFunction ( )
2021-04-12 22:02:36 +02:00
# comment
g :runtime = 'yes'
enddef
END
writefile ( lines , dir .. '/script.vim' )
var save_rtp = &rtp
exe 'set rtp=' .. getcwd ( ) .. '/Xdir'
lines = < < trim END
call script #Function ( )
END
2022-01-30 18:40:44 +00:00
v9 .CheckScriptFailure ( lines , 'E117:' , 1 )
2021-04-12 22:02:36 +02:00
&rtp = save_rtp
delete ( dir , 'rf' )
enddef
2021-06-11 22:05:47 +02:00
def Test_autoload_names ( )
var dir = 'Xdir/autoload'
mkdir ( dir , 'p' )
var lines = < < trim END
func foobar #function ( )
return 'yes'
endfunc
let foobar #var = 'no'
END
writefile ( lines , dir .. '/foobar.vim' )
var save_rtp = &rtp
exe 'set rtp=' .. getcwd ( ) .. '/Xdir'
lines = < < trim END
assert_equal ( 'yes' , foobar #function ( ) )
var Function = foobar #function
assert_equal ( 'yes' , Function ( ) )
assert_equal ( 'no' , foobar #var )
END
2022-01-29 21:45:34 +00:00
v9 .CheckDefAndScriptSuccess ( lines )
2021-06-11 22:05:47 +02:00
&rtp = save_rtp
delete ( dir , 'rf' )
enddef
2021-08-14 14:01:05 +02:00
def Test_autoload_error_in_script ( )
var dir = 'Xdir/autoload'
mkdir ( dir , 'p' )
var lines = < < trim END
func scripterror #function ( )
let g :called_function = 'yes'
endfunc
let 0 = 1
END
writefile ( lines , dir .. '/scripterror.vim' )
var save_rtp = &rtp
exe 'set rtp=' .. getcwd ( ) .. '/Xdir'
g :called_function = 'no'
# The error in the autoload script cannot be checked with assert_fails ( ) , use
# CheckDefSuccess ( ) instead of CheckDefFailure ( )
try
2022-01-29 21:45:34 +00:00
v9 .CheckDefSuccess ( ['scripterror#function()' ])
2021-08-14 14:01:05 +02:00
catch
assert_match ( 'E121: Undefined variable: 0' , v :exception )
endtry
assert_equal ( 'no' , g :called_function )
lines = < < trim END
func scriptcaught #function ( )
let g :called_function = 'yes'
endfunc
try
let 0 = 1
catch
let g :caught = v :exception
endtry
END
writefile ( lines , dir .. '/scriptcaught.vim' )
g :called_function = 'no'
2022-01-29 21:45:34 +00:00
v9 .CheckDefSuccess ( ['scriptcaught#function()' ])
2021-08-14 14:01:05 +02:00
assert_match ( 'E121: Undefined variable: 0' , g :caught )
assert_equal ( 'yes' , g :called_function )
&rtp = save_rtp
delete ( dir , 'rf' )
enddef
2022-01-29 21:45:34 +00:00
def s :CallRecursive ( n : number ) : number
2020-11-17 18:23:19 +01:00
return CallRecursive ( n + 1 )
enddef
2022-01-29 21:45:34 +00:00
def s :CallMapRecursive ( l : list < number > ) : number
2020-12-31 21:28:47 +01:00
return map ( l , ( _ , v ) = > CallMapRecursive ( [v ]) ) [0 ]
2020-11-17 18:23:19 +01:00
enddef
def Test_funcdepth_error ( )
set maxfuncdepth = 10
var caught = false
try
CallRecursive ( 1 )
catch /E132:/
caught = true
endtry
assert_true ( caught )
caught = false
try
CallMapRecursive ( [1 ])
catch /E132:/
caught = true
endtry
assert_true ( caught )
set maxfuncdepth &
enddef
2021-01-01 18:43:51 +01:00
def Test_endfunc_enddef ( )
var lines = < < trim END
def Test ( )
echo 'test'
endfunc
enddef
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptFailure ( lines , 'E1151:' , 3 )
2021-01-01 18:43:51 +01:00
lines = < < trim END
def Test ( )
func Nested ( )
echo 'test'
enddef
enddef
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptFailure ( lines , 'E1152:' , 4 )
2021-03-22 20:49:02 +01:00
lines = < < trim END
def Ok ( )
echo 'hello'
enddef | echo 'there'
def Bad ( )
echo 'hello'
enddef there
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptFailure ( lines , 'E1173: Text found after enddef: there' , 6 )
2021-01-01 18:43:51 +01:00
enddef
2021-01-01 18:54:34 +01:00
def Test_missing_endfunc_enddef ( )
var lines = < < trim END
vim9script
def Test ( )
echo 'test'
endef
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptFailure ( lines , 'E1057:' , 2 )
2021-01-01 18:54:34 +01:00
lines = < < trim END
vim9script
func Some ( )
echo 'test'
enfffunc
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptFailure ( lines , 'E126:' , 2 )
2021-01-01 18:54:34 +01:00
enddef
2021-01-24 21:14:20 +01:00
def Test_white_space_before_paren ( )
var lines = < < trim END
vim9script
def Test ( )
echo 'test'
enddef
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptFailure ( lines , 'E1068:' , 2 )
2021-01-24 21:14:20 +01:00
lines = < < trim END
vim9script
func Test ( )
echo 'test'
endfunc
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptFailure ( lines , 'E1068:' , 2 )
2021-01-24 21:14:20 +01:00
lines = < < trim END
def Test ( )
echo 'test'
enddef
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptFailure ( lines , 'E1068:' , 1 )
2021-01-24 21:14:20 +01:00
lines = < < trim END
func Test ( )
echo 'test'
endfunc
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptSuccess ( lines )
2021-01-24 21:14:20 +01:00
enddef
2021-01-08 21:55:26 +01:00
def Test_enddef_dict_key ( )
var d = {
enddef : 'x' ,
endfunc : 'y' ,
}
assert_equal ( {enddef : 'x' , endfunc : 'y' }, d )
enddef
2020-04-05 17:08:17 +02:00
def ReturnString ( ) : string
return 'string'
enddef
def ReturnNumber ( ) : number
return 123
enddef
let g :notNumber = 'string'
def ReturnGlobal ( ) : number
return g :notNumber
enddef
def Test_return_something ( )
2022-01-29 21:45:34 +00:00
g :ReturnString ( ) - > assert_equal ( 'string' )
g :ReturnNumber ( ) - > assert_equal ( 123 )
2022-01-30 15:28:30 +00:00
assert_fails ( 'g:ReturnGlobal()' , 'E1012: Type mismatch; expected number but got string' , '' , 1 , 'ReturnGlobal' )
2022-01-18 18:46:07 +00:00
var lines = < < trim END
vim9script
def Msg ( )
echomsg 'in Msg()...'
enddef
def Func ( )
return Msg ( )
enddef
defcompile
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptFailure ( lines , 'E1096:' )
2020-04-05 17:08:17 +02:00
enddef
2021-01-21 20:21:29 +01:00
def Test_check_argument_type ( )
var lines = < < trim END
vim9script
def Val ( a : number , b : number ) : number
return 0
enddef
def Func ( )
var x : any = true
Val ( 0 , x )
enddef
disass Func
Func ( )
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptFailure ( lines , 'E1013: Argument 2: type mismatch, expected number but got bool' , 2 )
2021-01-21 20:21:29 +01:00
enddef
2020-06-18 20:50:10 +02:00
def Test_missing_return ( )
2022-01-29 21:45:34 +00:00
v9 .CheckDefFailure ( ['def Missing(): number' ,
2020-06-18 20:50:10 +02:00
' if g:cond' ,
' echo "no return"' ,
' else' ,
' return 0' ,
' endif'
'enddef' ], 'E1027:' )
2022-01-29 21:45:34 +00:00
v9 .CheckDefFailure ( ['def Missing(): number' ,
2020-06-18 20:50:10 +02:00
' if g:cond' ,
' return 1' ,
' else' ,
' echo "no return"' ,
' endif'
'enddef' ], 'E1027:' )
2022-01-29 21:45:34 +00:00
v9 .CheckDefFailure ( ['def Missing(): number' ,
2020-06-18 20:50:10 +02:00
' if g:cond' ,
' return 1' ,
' else' ,
' return 2' ,
' endif'
' return 3'
'enddef' ], 'E1095:' )
enddef
2020-10-17 19:29:51 +02:00
def Test_return_bool ( )
var lines = < < trim END
vim9script
def MenuFilter ( id : number , key : string ) : bool
return popup_filter_menu ( id , key )
enddef
def YesnoFilter ( id : number , key : string ) : bool
return popup_filter_yesno ( id , key )
enddef
defcompile
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptSuccess ( lines )
2020-10-17 19:29:51 +02:00
enddef
2020-04-05 17:08:17 +02:00
let s :nothing = 0
def ReturnNothing ( )
s :nothing = 1
if true
return
endif
s :nothing = 2
enddef
def Test_return_nothing ( )
2022-01-29 21:45:34 +00:00
g :ReturnNothing ( )
2020-09-11 19:09:48 +02:00
s :nothing - > assert_equal ( 1 )
2020-04-05 17:08:17 +02:00
enddef
2021-01-15 19:04:32 +01:00
def Test_return_invalid ( )
var lines = < < trim END
vim9script
def Func ( ) : invalid
return xxx
enddef
defcompile
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptFailure ( lines , 'E1010:' , 2 )
2021-02-12 22:10:21 +01:00
lines = < < trim END
vim9script
def Test ( Fun : func ( number ) : number ) : list < number >
return map ( [1 , 2 , 3 ], ( _ , i ) = > Fun ( i ) )
enddef
defcompile
def Inc ( nr : number ) : nr
return nr + 2
enddef
echo Test ( Inc )
END
# doing this twice was leaking memory
2022-01-29 21:45:34 +00:00
v9 .CheckScriptFailure ( lines , 'E1010:' )
v9 .CheckScriptFailure ( lines , 'E1010:' )
2021-01-15 19:04:32 +01:00
enddef
2021-09-09 22:30:52 +02:00
def Test_return_list_any ( )
2022-01-03 12:28:03 +00:00
# This used to fail but now the actual list type is checked , and since it has
# an item of type string it can be used as list < string > .
2021-09-09 22:30:52 +02:00
var lines = < < trim END
vim9script
def Func ( ) : list < string >
var l : list < any >
l - > add ( 'string' )
return l
enddef
echo Func ( )
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptSuccess ( lines )
2022-01-03 12:28:03 +00:00
2021-09-09 22:30:52 +02:00
lines = < < trim END
vim9script
def Func ( ) : list < string >
var l : list < any >
l + = ['string' ]
return l
enddef
echo Func ( )
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptSuccess ( lines )
2021-09-09 22:30:52 +02:00
enddef
2022-01-29 21:45:34 +00:00
func s :Increment ( )
2020-04-05 17:08:17 +02:00
let g :counter + = 1
endfunc
def Test_call_ufunc_count ( )
g :counter = 1
Increment ( )
Increment ( )
Increment ( )
2020-07-17 20:36:00 +02:00
# works with and without :call
2020-09-11 19:09:48 +02:00
g :counter - > assert_equal ( 4 )
eval g :counter - > assert_equal ( 4 )
2020-04-05 17:08:17 +02:00
unlet g :counter
enddef
2022-02-28 20:55:02 +00:00
def Test_call_ufunc_failure ( )
var lines = < < trim END
vim9script
def Tryit ( )
g :Global ( 1 , 2 , 3 )
enddef
func g :Global ( a , b , c )
echo a :a a :b a :c
endfunc
defcompile
func ! g :Global ( a , b )
echo a :a a :b
endfunc
Tryit ( )
END
v9 .CheckScriptFailure ( lines , 'E118: Too many arguments for function: Global' )
delfunc g :Global
lines = < < trim END
vim9script
g :Ref = function ( 'len' )
def Tryit ( )
g :Ref ( 'x' )
enddef
defcompile
g :Ref = function ( 'add' )
Tryit ( )
END
v9 .CheckScriptFailure ( lines , 'E119: Not enough arguments for function: add' )
unlet g :Ref
enddef
2022-01-29 21:45:34 +00:00
def s :MyVarargs ( arg : string , ...rest : list < string > ) : string
2020-09-27 22:47:05 +02:00
var res = arg
2020-04-05 17:08:17 +02:00
for s in rest
res ..= ',' .. s
endfor
return res
enddef
def Test_call_varargs ( )
2020-09-11 19:09:48 +02:00
MyVarargs ( 'one' ) - > assert_equal ( 'one' )
MyVarargs ( 'one' , 'two' ) - > assert_equal ( 'one,two' )
MyVarargs ( 'one' , 'two' , 'three' ) - > assert_equal ( 'one,two,three' )
2020-04-05 17:08:17 +02:00
enddef
2021-09-05 16:36:23 +02:00
def Test_call_white_space ( )
2022-01-29 21:45:34 +00:00
v9 .CheckDefAndScriptFailure ( ["call Test ('text')" ], ['E476:' , 'E1068:' ])
2021-09-05 16:36:23 +02:00
enddef
2020-04-05 17:08:17 +02:00
def MyDefaultArgs ( name = 'string' ) : string
return name
enddef
2022-01-29 21:45:34 +00:00
def s :MyDefaultSecond ( name : string , second : bool = true ) : string
2020-07-15 19:48:20 +02:00
return second ? name : 'none'
enddef
2021-03-29 22:14:55 +02:00
2020-04-05 17:08:17 +02:00
def Test_call_default_args ( )
2022-01-29 21:45:34 +00:00
g :MyDefaultArgs ( ) - > assert_equal ( 'string' )
g :MyDefaultArgs ( v :none ) - > assert_equal ( 'string' )
g :MyDefaultArgs ( 'one' ) - > assert_equal ( 'one' )
assert_fails ( 'g:MyDefaultArgs("one", "two")' , 'E118:' , '' , 4 , 'Test_call_default_args' )
2020-04-05 17:08:17 +02:00
2020-09-11 19:09:48 +02:00
MyDefaultSecond ( 'test' ) - > assert_equal ( 'test' )
MyDefaultSecond ( 'test' , true ) - > assert_equal ( 'test' )
MyDefaultSecond ( 'test' , false ) - > assert_equal ( 'none' )
2020-07-15 19:48:20 +02:00
2021-03-29 22:14:55 +02:00
var lines = < < trim END
def MyDefaultThird ( name : string , aa = 'aa' , bb = 'bb' ) : string
return name .. aa .. bb
enddef
MyDefaultThird ( '->' ) - > assert_equal ( '->aabb' )
MyDefaultThird ( '->' , v :none ) - > assert_equal ( '->aabb' )
MyDefaultThird ( '->' , 'xx' ) - > assert_equal ( '->xxbb' )
MyDefaultThird ( '->' , v :none , v :none ) - > assert_equal ( '->aabb' )
MyDefaultThird ( '->' , 'xx' , v :none ) - > assert_equal ( '->xxbb' )
MyDefaultThird ( '->' , v :none , 'yy' ) - > assert_equal ( '->aayy' )
MyDefaultThird ( '->' , 'xx' , 'yy' ) - > assert_equal ( '->xxyy' )
2021-07-03 18:56:53 +02:00
def DefArg ( mandatory : any , optional = mandatory ) : string
return mandatory .. optional
enddef
DefArg ( 1234 ) - > assert_equal ( '12341234' )
DefArg ( "ok" ) - > assert_equal ( 'okok' )
2021-03-29 22:14:55 +02:00
END
2022-01-29 21:45:34 +00:00
v9 .CheckDefAndScriptSuccess ( lines )
2021-03-29 22:14:55 +02:00
2022-01-29 21:45:34 +00:00
v9 .CheckScriptFailure ( ['def Func(arg: number = asdf)' , 'enddef' , 'defcompile' ], 'E1001:' )
2020-12-05 13:41:01 +01:00
delfunc g :Func
2022-01-29 21:45:34 +00:00
v9 .CheckScriptFailure ( ['def Func(arg: number = "text")' , 'enddef' , 'defcompile' ], 'E1013: Argument 1: type mismatch, expected number but got string' )
2020-12-05 13:41:01 +01:00
delfunc g :Func
2022-01-29 21:45:34 +00:00
v9 .CheckDefFailure ( ['def Func(x: number = )' , 'enddef' ], 'E15:' )
2021-03-11 20:04:04 +01:00
2021-03-29 22:14:55 +02:00
lines = < < trim END
2021-03-11 20:04:04 +01:00
vim9script
def Func ( a = b = = 0 ? 1 : 2 , b = 0 )
enddef
defcompile
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptFailure ( lines , 'E1001: Variable not found: b' )
2021-12-21 12:32:17 +00:00
2021-12-22 13:18:39 +00:00
# using script variable requires matching type or type cast when executed
2021-12-21 12:32:17 +00:00
lines = < < trim END
vim9script
var a : any
def Func ( arg : string = a )
echo arg
enddef
defcompile
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptSuccess ( lines + ['a = "text"' , 'Func()' ])
v9 .CheckScriptFailure ( lines + ['a = 123' , 'Func()' ], 'E1013: Argument 1: type mismatch, expected string but got number' )
2021-12-21 12:32:17 +00:00
# using global variable does not require type cast
lines = < < trim END
vim9script
def Func ( arg : string = g :str )
echo arg
enddef
g :str = 'works'
Func ( )
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptSuccess ( lines )
2020-05-04 23:24:44 +02:00
enddef
2022-01-29 21:45:34 +00:00
def s :FuncWithComment ( # comment
2021-01-04 14:09:43 +01:00
a : number , #comment
b : bool , # comment
c : string ) #comment
assert_equal ( 4 , a )
assert_equal ( true , b )
assert_equal ( 'yes' , c )
enddef
def Test_func_with_comments ( )
FuncWithComment ( 4 , true , 'yes' )
var lines = < < trim END
def Func ( # comment
arg : string )
enddef
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptFailure ( lines , 'E125:' , 1 )
2021-01-04 14:09:43 +01:00
lines = < < trim END
def Func (
arg : string # comment
)
enddef
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptFailure ( lines , 'E475:' , 2 )
2021-01-04 14:09:43 +01:00
lines = < < trim END
def Func (
arg : string
) # comment
enddef
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptFailure ( lines , 'E488:' , 3 )
2021-01-04 14:09:43 +01:00
enddef
2020-05-04 23:24:44 +02:00
def Test_nested_function ( )
2021-11-28 22:00:12 +00:00
def NestedDef ( arg : string ) : string
2020-05-04 23:24:44 +02:00
return 'nested ' .. arg
enddef
2021-11-28 22:00:12 +00:00
NestedDef ( ':def' ) - > assert_equal ( 'nested :def' )
func NestedFunc ( arg )
return 'nested ' .. a :arg
endfunc
NestedFunc ( ':func' ) - > assert_equal ( 'nested :func' )
2020-05-04 23:24:44 +02:00
2022-01-29 21:45:34 +00:00
v9 .CheckDefFailure ( ['def Nested()' , 'enddef' , 'Nested(66)' ], 'E118:' )
v9 .CheckDefFailure ( ['def Nested(arg: string)' , 'enddef' , 'Nested()' ], 'E119:' )
2020-05-05 17:53:16 +02:00
2022-01-29 21:45:34 +00:00
v9 .CheckDefFailure ( ['def s:Nested()' , 'enddef' ], 'E1075:' )
v9 .CheckDefFailure ( ['def b:Nested()' , 'enddef' ], 'E1075:' )
2020-09-10 22:28:01 +02:00
2020-12-06 18:50:36 +01:00
var lines = < < trim END
def Outer ( )
def Inner ( )
# comment
enddef
def Inner ( )
enddef
enddef
END
2022-01-29 21:45:34 +00:00
v9 .CheckDefFailure ( lines , 'E1073:' )
2020-12-06 18:50:36 +01:00
lines = < < trim END
def Outer ( )
def Inner ( )
# comment
enddef
def ! Inner ( )
enddef
enddef
END
2022-01-29 21:45:34 +00:00
v9 .CheckDefFailure ( lines , 'E1117:' )
2020-12-06 18:50:36 +01:00
2021-12-25 19:58:22 +00:00
lines = < < trim END
vim9script
def Outer ( )
def Inner ( )
g :result = 'ok'
enddef
Inner ( )
enddef
Outer ( )
Inner ( )
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptFailure ( lines , 'E117: Unknown function: Inner' )
2021-12-25 19:58:22 +00:00
assert_equal ( 'ok' , g :result )
unlet g :result
2022-02-07 20:30:57 +00:00
lines = < < trim END
vim9script
def Outer ( )
def _Inner ( )
echo 'bad'
enddef
2022-02-07 21:54:01 +00:00
_Inner ( )
2022-02-07 20:30:57 +00:00
enddef
defcompile
END
2022-02-07 21:54:01 +00:00
v9 .CheckScriptFailure ( lines , 'E1267:' )
2022-02-07 20:30:57 +00:00
lines = < < trim END
vim9script
def Outer ( )
def g :inner ( )
echo 'bad'
enddef
2022-02-07 21:54:01 +00:00
g :inner ( )
2022-02-07 20:30:57 +00:00
enddef
defcompile
END
2022-02-07 21:54:01 +00:00
v9 .CheckScriptFailure ( lines , 'E1267:' )
lines = < < trim END
vim9script
def g :_Func ( )
echo 'bad'
enddef
END
v9 .CheckScriptFailure ( lines , 'E1267:' )
lines = < < trim END
vim9script
2022-02-12 19:52:25 +00:00
def _Func ( )
2022-02-07 21:54:01 +00:00
echo 'bad'
enddef
END
v9 .CheckScriptFailure ( lines , 'E1267:' )
2022-02-07 20:30:57 +00:00
2020-12-06 18:50:36 +01:00
# nested function inside conditional
lines = < < trim END
vim9script
var thecount = 0
if true
def Test ( ) : number
def TheFunc ( ) : number
2021-03-17 18:42:08 +01:00
thecount + = 1
return thecount
enddef
return TheFunc ( )
enddef
endif
defcompile
assert_equal ( 1 , Test ( ) )
assert_equal ( 2 , Test ( ) )
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptSuccess ( lines )
2021-03-17 18:42:08 +01:00
# also works when "thecount" is inside the "if" block
lines = < < trim END
vim9script
if true
var thecount = 0
def Test ( ) : number
def TheFunc ( ) : number
2020-12-06 18:50:36 +01:00
thecount + = 1
return thecount
enddef
return TheFunc ( )
enddef
endif
defcompile
assert_equal ( 1 , Test ( ) )
assert_equal ( 2 , Test ( ) )
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptSuccess ( lines )
2021-08-15 19:28:05 +02:00
lines = < < trim END
vim9script
def Outer ( )
def Inner ( )
echo 'hello'
enddef burp
enddef
defcompile
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptFailure ( lines , 'E1173: Text found after enddef: burp' , 3 )
2020-04-05 17:08:17 +02:00
enddef
2020-12-31 18:28:18 +01:00
def Test_not_nested_function ( )
echo printf ( '%d' ,
function ( 'len' ) ( 'xxx' ) )
enddef
2020-08-01 00:03:09 +02:00
func Test_call_default_args_from_func ( )
2020-09-11 19:09:48 +02:00
call MyDefaultArgs ( ) - > assert_equal ( 'string' )
call MyDefaultArgs ( 'one' ) - > assert_equal ( 'one' )
2020-09-06 21:47:48 +02:00
call assert_fails ( 'call MyDefaultArgs("one", "two")' , 'E118:' , '' , 3 , 'Test_call_default_args_from_func' )
2020-08-01 00:03:09 +02:00
endfunc
2020-07-31 22:05:04 +02:00
def Test_nested_global_function ( )
2020-09-27 22:47:05 +02:00
var lines = < < trim END
2020-07-31 22:05:04 +02:00
vim9script
def Outer ( )
def g :Inner ( ) : string
return 'inner'
enddef
enddef
2020-08-01 00:03:09 +02:00
defcompile
Outer ( )
2020-09-11 19:09:48 +02:00
g :Inner ( ) - > assert_equal ( 'inner' )
2020-08-01 00:03:09 +02:00
delfunc g :Inner
Outer ( )
2020-09-11 19:09:48 +02:00
g :Inner ( ) - > assert_equal ( 'inner' )
2020-08-01 00:03:09 +02:00
delfunc g :Inner
Outer ( )
2020-09-11 19:09:48 +02:00
g :Inner ( ) - > assert_equal ( 'inner' )
2020-08-01 00:03:09 +02:00
delfunc g :Inner
2020-07-31 22:05:04 +02:00
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptSuccess ( lines )
2020-08-01 18:57:52 +02:00
2021-11-28 22:00:12 +00:00
lines = < < trim END
vim9script
def Outer ( )
func g :Inner ( )
return 'inner'
endfunc
enddef
defcompile
Outer ( )
g :Inner ( ) - > assert_equal ( 'inner' )
delfunc g :Inner
Outer ( )
g :Inner ( ) - > assert_equal ( 'inner' )
delfunc g :Inner
Outer ( )
g :Inner ( ) - > assert_equal ( 'inner' )
delfunc g :Inner
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptSuccess ( lines )
2021-11-28 22:00:12 +00:00
2020-08-01 18:57:52 +02:00
lines = < < trim END
vim9script
def Outer ( )
def g :Inner ( ) : string
return 'inner'
enddef
enddef
defcompile
Outer ( )
Outer ( )
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptFailure ( lines , "E122:" )
2020-12-22 17:35:54 +01:00
delfunc g :Inner
2020-08-01 23:22:18 +02:00
2020-12-22 18:56:55 +01:00
lines = < < trim END
vim9script
def Outer ( )
def g :Inner ( )
2020-12-31 21:28:47 +01:00
echo map ( [1 , 2 , 3 ], ( _ , v ) = > v + 1 )
2020-12-22 18:56:55 +01:00
enddef
g :Inner ( )
enddef
Outer ( )
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptSuccess ( lines )
2020-12-22 18:56:55 +01:00
delfunc g :Inner
2020-08-01 23:22:18 +02:00
lines = < < trim END
vim9script
def Func ( )
echo 'script'
enddef
def Outer ( )
def Func ( )
echo 'inner'
enddef
enddef
defcompile
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptFailure ( lines , "E1073:" , 1 )
2021-11-20 21:46:20 +00:00
lines = < < trim END
vim9script
def Func ( )
echo 'script'
enddef
def Func ( )
echo 'script'
enddef
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptFailure ( lines , "E1073:" , 5 )
2020-07-31 22:05:04 +02:00
enddef
2020-11-22 18:15:44 +01:00
def DefListAll ( )
def
enddef
def DefListOne ( )
def DefListOne
enddef
def DefListMatches ( )
def /DefList
enddef
def Test_nested_def_list ( )
var funcs = split ( execute ( 'call DefListAll()' ) , "\n" )
assert_true ( len ( funcs ) > 10 )
assert_true ( funcs - > index ( 'def DefListAll()' ) > = 0 )
funcs = split ( execute ( 'call DefListOne()' ) , "\n" )
assert_equal ( [' def DefListOne()' , '1 def DefListOne' , ' enddef' ], funcs )
funcs = split ( execute ( 'call DefListMatches()' ) , "\n" )
assert_true ( len ( funcs ) > = 3 )
assert_true ( funcs - > index ( 'def DefListAll()' ) > = 0 )
assert_true ( funcs - > index ( 'def DefListOne()' ) > = 0 )
assert_true ( funcs - > index ( 'def DefListMatches()' ) > = 0 )
2020-12-06 18:50:36 +01:00
var lines = < < trim END
vim9script
def Func ( )
def + Func +
enddef
defcompile
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptFailure ( lines , 'E476:' , 1 )
2020-11-22 18:15:44 +01:00
enddef
2022-02-17 13:08:26 +00:00
def Test_global_function_not_found ( )
var lines = < < trim END
g :Ref = 123
call g :Ref ( )
END
v9 .CheckDefExecAndScriptFailure ( lines , ['E117:' , 'E1085:' ], 2 )
enddef
2020-08-01 18:53:07 +02:00
def Test_global_local_function ( )
2020-09-27 22:47:05 +02:00
var lines = < < trim END
2020-08-01 18:53:07 +02:00
vim9script
def g :Func ( ) : string
return 'global'
enddef
def Func ( ) : string
return 'local'
enddef
2020-09-11 19:09:48 +02:00
g :Func ( ) - > assert_equal ( 'global' )
Func ( ) - > assert_equal ( 'local' )
2020-12-05 13:41:01 +01:00
delfunc g :Func
2020-08-01 18:53:07 +02:00
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptSuccess ( lines )
2020-08-11 22:30:42 +02:00
lines = < < trim END
vim9script
def g :Funcy ( )
echo 'funcy'
enddef
2022-02-12 19:52:25 +00:00
Funcy ( )
2020-08-11 22:30:42 +02:00
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptFailure ( lines , 'E117:' )
2020-08-01 18:53:07 +02:00
enddef
2020-09-12 18:32:34 +02:00
def Test_local_function_shadows_global ( )
2020-09-27 22:47:05 +02:00
var lines = < < trim END
2020-09-12 18:32:34 +02:00
vim9script
def g :Gfunc ( ) : string
return 'global'
enddef
def AnotherFunc ( ) : number
2020-09-27 22:47:05 +02:00
var Gfunc = function ( 'len' )
2020-09-12 18:32:34 +02:00
return Gfunc ( 'testing' )
enddef
g :Gfunc ( ) - > assert_equal ( 'global' )
AnotherFunc ( ) - > assert_equal ( 7 )
delfunc g :Gfunc
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptSuccess ( lines )
2020-09-12 18:32:34 +02:00
lines = < < trim END
vim9script
def g :Func ( ) : string
return 'global'
enddef
def AnotherFunc ( )
g :Func = function ( 'len' )
enddef
AnotherFunc ( )
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptFailure ( lines , 'E705:' )
2020-09-12 18:32:34 +02:00
delfunc g :Func
2021-04-05 15:38:51 +02:00
2022-01-29 21:45:34 +00:00
# global function is not found with g : prefix
2021-04-05 15:38:51 +02:00
lines = < < trim END
vim9script
def g :Func ( ) : string
return 'global'
enddef
def AnotherFunc ( ) : string
return Func ( )
enddef
assert_equal ( 'global' , AnotherFunc ( ) )
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptFailure ( lines , 'E117:' )
delfunc g :Func
2021-04-05 15:38:51 +02:00
lines = < < trim END
vim9script
def g :Func ( ) : string
return 'global'
enddef
2022-01-30 15:28:30 +00:00
assert_equal ( 'global' , g :Func ( ) )
2021-04-05 15:38:51 +02:00
delfunc g :Func
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptSuccess ( lines )
2022-01-06 12:23:30 +00:00
# This does not shadow "i" which is visible only inside the for loop
lines = < < trim END
vim9script
def Foo ( i : number )
echo i
enddef
for i in range ( 3 )
# Foo ( ) is compiled here
Foo ( i )
endfor
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptSuccess ( lines )
2020-09-12 18:32:34 +02:00
enddef
2020-04-05 17:08:17 +02:00
func TakesOneArg ( arg )
echo a :arg
endfunc
def Test_call_wrong_args ( )
2022-01-29 21:45:34 +00:00
v9 .CheckDefFailure ( ['g:TakesOneArg()' ], 'E119:' )
v9 .CheckDefFailure ( ['g:TakesOneArg(11, 22)' ], 'E118:' )
v9 .CheckDefFailure ( ['bufnr(xxx)' ], 'E1001:' )
v9 .CheckScriptFailure ( ['def Func(Ref: func(s: string))' ], 'E475:' )
2020-08-28 17:19:07 +02:00
2020-09-27 22:47:05 +02:00
var lines = < < trim END
2020-08-28 17:19:07 +02:00
vim9script
def Func ( s : string )
echo s
enddef
Func ( [])
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptFailure ( lines , 'E1013: Argument 1: type mismatch, expected string but got list<unknown>' , 5 )
2020-09-18 22:42:00 +02:00
2021-12-31 14:06:45 +00:00
# argument name declared earlier is found when declaring a function
2021-02-21 22:20:24 +01:00
lines = < < trim END
vim9script
var name = 'piet'
def FuncOne ( name : string )
2022-02-08 19:23:35 +00:00
echo name
2021-02-21 22:20:24 +01:00
enddef
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptFailure ( lines , 'E1168:' )
2021-02-21 22:20:24 +01:00
2022-02-08 19:23:35 +00:00
# same , inside the same block
lines = < < trim END
vim9script
if true
var name = 'piet'
def FuncOne ( name : string )
echo name
enddef
endif
END
v9 .CheckScriptFailure ( lines , 'E1168:' )
# variable in other block is OK
lines = < < trim END
vim9script
if true
var name = 'piet'
endif
def FuncOne ( name : string )
echo name
enddef
END
v9 .CheckScriptSuccess ( lines )
2022-02-08 20:35:30 +00:00
# with another variable in another block
lines = < < trim END
vim9script
if true
var name = 'piet'
# define a function so that the variable isn 't cleared
def GetItem ( ) : string
return item
enddef
endif
if true
var name = 'peter'
def FuncOne ( name : string )
echo name
enddef
endif
END
v9 .CheckScriptFailure ( lines , 'E1168:' )
# only variable in another block is OK
lines = < < trim END
vim9script
if true
var name = 'piet'
# define a function so that the variable isn 't cleared
def GetItem ( ) : string
return item
enddef
endif
if true
def FuncOne ( name : string )
echo name
enddef
endif
END
v9 .CheckScriptSuccess ( lines )
2021-12-31 14:06:45 +00:00
# argument name declared later is only found when compiling
lines = < < trim END
vim9script
def FuncOne ( name : string )
echo nr
enddef
var name = 'piet'
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptSuccess ( lines )
v9 .CheckScriptFailure ( lines + ['defcompile' ], 'E1168:' )
2021-12-31 14:06:45 +00:00
2020-09-18 22:42:00 +02:00
lines = < < trim END
vim9script
def FuncOne ( nr : number )
echo nr
enddef
def FuncTwo ( )
FuncOne ( )
enddef
defcompile
END
writefile ( lines , 'Xscript' )
2020-09-27 22:47:05 +02:00
var didCatch = false
2020-09-18 22:42:00 +02:00
try
source Xscript
catch
assert_match ( 'E119: Not enough arguments for function: <SNR>\d\+_FuncOne' , v :exception )
assert_match ( 'Xscript\[8\]..function <SNR>\d\+_FuncTwo, line 1' , v :throwpoint )
didCatch = true
endtry
assert_true ( didCatch )
lines = < < trim END
vim9script
def FuncOne ( nr : number )
echo nr
enddef
def FuncTwo ( )
FuncOne ( 1 , 2 )
enddef
defcompile
END
writefile ( lines , 'Xscript' )
didCatch = false
try
source Xscript
catch
assert_match ( 'E118: Too many arguments for function: <SNR>\d\+_FuncOne' , v :exception )
assert_match ( 'Xscript\[8\]..function <SNR>\d\+_FuncTwo, line 1' , v :throwpoint )
didCatch = true
endtry
assert_true ( didCatch )
delete ( 'Xscript' )
2020-04-05 17:08:17 +02:00
enddef
2020-12-20 21:10:17 +01:00
def Test_call_funcref_wrong_args ( )
var head = < < trim END
vim9script
def Func3 ( a1 : string , a2 : number , a3 : list < number > )
echo a1 .. a2 .. a3 [0 ]
enddef
def Testme ( )
var funcMap : dict < func > = {func : Func3 }
END
var tail = < < trim END
enddef
Testme ( )
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptSuccess ( head + ["funcMap['func']('str', 123, [1, 2, 3])" ] + tail )
2020-12-20 21:10:17 +01:00
2022-01-29 21:45:34 +00:00
v9 .CheckScriptFailure ( head + ["funcMap['func']('str', 123)" ] + tail , 'E119:' )
v9 .CheckScriptFailure ( head + ["funcMap['func']('str', 123, [1], 4)" ] + tail , 'E118:' )
2021-01-06 21:59:39 +01:00
var lines = < < trim END
vim9script
var Ref : func ( number ) : any
Ref = ( j ) = > ! j
echo Ref ( false )
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptFailure ( lines , 'E1013: Argument 1: type mismatch, expected number but got bool' , 4 )
2021-01-06 21:59:39 +01:00
lines = < < trim END
vim9script
var Ref : func ( number ) : any
Ref = ( j ) = > ! j
call Ref ( false )
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptFailure ( lines , 'E1013: Argument 1: type mismatch, expected number but got bool' , 4 )
2020-12-20 21:10:17 +01:00
enddef
2020-11-05 18:45:46 +01:00
def Test_call_lambda_args ( )
2021-04-09 20:24:31 +02:00
var lines = < < trim END
var Callback = ( ..._ ) = > 'anything'
assert_equal ( 'anything' , Callback ( ) )
assert_equal ( 'anything' , Callback ( 1 ) )
assert_equal ( 'anything' , Callback ( 'a' , 2 ) )
2021-04-09 22:12:44 +02:00
assert_equal ( 'xyz' , ( ( a : string ) : string = > a ) ( 'xyz' ) )
2021-04-09 20:24:31 +02:00
END
2022-01-29 21:45:34 +00:00
v9 .CheckDefAndScriptSuccess ( lines )
2021-04-09 20:24:31 +02:00
2022-01-29 21:45:34 +00:00
v9 .CheckDefFailure ( ['echo ((i) => 0)()' ],
2020-12-31 21:28:47 +01:00
'E119: Not enough arguments for function: ((i) => 0)()' )
2020-11-05 18:45:46 +01:00
2021-04-09 20:24:31 +02:00
lines = < < trim END
2020-12-31 21:28:47 +01:00
var Ref = ( x : number , y : number ) = > x + y
2020-11-05 18:45:46 +01:00
echo Ref ( 1 , 'x' )
END
2022-01-29 21:45:34 +00:00
v9 .CheckDefFailure ( lines , 'E1013: Argument 2: type mismatch, expected number but got string' )
2021-01-03 13:09:51 +01:00
lines = < < trim END
var Ref : func ( job , string , number )
Ref = ( x , y ) = > 0
END
2022-01-29 21:45:34 +00:00
v9 .CheckDefAndScriptFailure ( lines , 'E1012:' )
2021-01-03 13:09:51 +01:00
lines = < < trim END
var Ref : func ( job , string )
Ref = ( x , y , z ) = > 0
END
2022-01-29 21:45:34 +00:00
v9 .CheckDefAndScriptFailure ( lines , 'E1012:' )
2021-02-28 16:55:11 +01:00
lines = < < trim END
var one = 1
var l = [1 , 2 , 3 ]
echo map ( l , ( one ) = > one )
END
2022-01-29 21:45:34 +00:00
v9 .CheckDefFailure ( lines , 'E1167:' )
v9 .CheckScriptFailure ( ['vim9script' ] + lines , 'E1168:' )
2021-02-28 16:55:11 +01:00
2021-06-26 19:25:49 +02:00
lines = < < trim END
var Ref : func ( any , ?any ) : bool
Ref = ( _ , y = 1 ) = > false
END
2022-01-29 21:45:34 +00:00
v9 .CheckDefAndScriptFailure ( lines , 'E1172:' )
2021-06-26 19:25:49 +02:00
2021-06-26 21:52:02 +02:00
lines = < < trim END
var a = 0
var b = ( a = = 0 ? 1 : 2 )
assert_equal ( 1 , b )
2021-06-26 22:22:38 +02:00
var txt = 'a'
b = ( txt = ~ 'x' ? 1 : 2 )
assert_equal ( 2 , b )
2021-06-26 21:52:02 +02:00
END
2022-01-29 21:45:34 +00:00
v9 .CheckDefAndScriptSuccess ( lines )
2021-06-26 21:52:02 +02:00
2021-02-28 16:55:11 +01:00
lines = < < trim END
def ShadowLocal ( )
var one = 1
var l = [1 , 2 , 3 ]
echo map ( l , ( one ) = > one )
enddef
END
2022-01-29 21:45:34 +00:00
v9 .CheckDefFailure ( lines , 'E1167:' )
2021-02-28 16:55:11 +01:00
lines = < < trim END
def Shadowarg ( one : number )
var l = [1 , 2 , 3 ]
echo map ( l , ( one ) = > one )
enddef
END
2022-01-29 21:45:34 +00:00
v9 .CheckDefFailure ( lines , 'E1167:' )
2021-04-09 17:24:52 +02:00
lines = < < trim END
echo ( ( a ) = > a ) ( 'aa' , 'bb' )
END
2022-01-29 21:45:34 +00:00
v9 .CheckDefAndScriptFailure ( lines , 'E118:' , 1 )
2021-07-21 20:38:46 +02:00
lines = < < trim END
echo 'aa' - > ( ( a ) = > a ) ( 'bb' )
END
2022-01-29 21:45:34 +00:00
v9 .CheckDefFailure ( lines , 'E118: Too many arguments for function: ->((a) => a)(''bb'')' , 1 )
v9 .CheckScriptFailure ( ['vim9script' ] + lines , 'E118: Too many arguments for function: <lambda>' , 2 )
2020-11-05 18:45:46 +01:00
enddef
2021-11-20 21:35:41 +00:00
def Test_lambda_line_nr ( )
var lines = < < trim END
vim9script
# comment
# comment
var id = timer_start ( 1 '000 , ( _ ) = > 0 )
var out = execute ( 'verbose ' .. timer_info ( id ) [0 ].callback
- > string ( )
- > substitute ( "('\\|')" , ' ' , 'g' ) )
assert_match ( 'Last set from .* line 4' , out )
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptSuccess ( lines )
2021-11-20 21:35:41 +00:00
enddef
2021-03-17 21:29:29 +01:00
def FilterWithCond ( x : string , Cond : func ( string ) : bool ) : bool
return Cond ( x )
enddef
2021-01-31 22:18:29 +01:00
def Test_lambda_return_type ( )
var lines = < < trim END
var Ref = ( ) : = > 123
END
2022-01-29 21:45:34 +00:00
v9 .CheckDefAndScriptFailure ( lines , 'E1157:' , 1 )
2021-03-17 21:29:29 +01:00
2021-05-24 15:15:47 +02:00
# no space before the return type
lines = < < trim END
var Ref = ( x ) :number = > x + 1
END
2022-01-29 21:45:34 +00:00
v9 .CheckDefAndScriptFailure ( lines , 'E1069:' , 1 )
2021-05-24 15:15:47 +02:00
2021-03-17 21:29:29 +01:00
# this works
for x in ['foo' , 'boo' ]
2022-01-29 21:45:34 +00:00
echo g :FilterWithCond ( x , ( v ) = > v = ~ '^b' )
2021-03-17 21:29:29 +01:00
endfor
# this fails
lines = < < trim END
2022-01-29 21:45:34 +00:00
echo g :FilterWithCond ( 'foo' , ( v ) = > v .. '^b' )
2021-03-17 21:29:29 +01:00
END
2022-01-29 21:45:34 +00:00
v9 .CheckDefAndScriptFailure ( lines , 'E1013: Argument 2: type mismatch, expected func(string): bool but got func(any): string' , 1 )
2021-06-12 15:58:16 +02:00
lines = < < trim END
var Lambda1 = ( x ) = > {
return x
}
assert_equal ( 'asdf' , Lambda1 ( 'asdf' ) )
var Lambda2 = ( x ) : string = > {
return x
}
assert_equal ( 'foo' , Lambda2 ( 'foo' ) )
END
2022-01-29 21:45:34 +00:00
v9 .CheckDefAndScriptSuccess ( lines )
2021-06-12 15:58:16 +02:00
lines = < < trim END
var Lambda = ( x ) : string = > {
return x
}
echo Lambda ( ['foo' ])
END
2022-01-29 21:45:34 +00:00
v9 .CheckDefExecAndScriptFailure ( lines , 'E1012:' )
2021-01-31 22:18:29 +01:00
enddef
2020-12-12 14:33:41 +01:00
def Test_lambda_uses_assigned_var ( )
2022-01-29 21:45:34 +00:00
v9 .CheckDefSuccess ( [
2020-12-12 14:33:41 +01:00
'var x: any = "aaa"'
2020-12-31 21:28:47 +01:00
'x = filter(["bbb"], (_, v) => v =~ x)' ])
2020-12-12 14:33:41 +01:00
enddef
2021-03-05 21:35:47 +01:00
def Test_pass_legacy_lambda_to_def_func ( )
var lines = < < trim END
vim9script
func Foo ( )
eval s :Bar ( {x - > 0 })
endfunc
def Bar ( y : any )
enddef
Foo ( )
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptSuccess ( lines )
2021-06-22 19:32:17 +02:00
lines = < < trim END
vim9script
2021-07-04 15:54:08 +02:00
def g :TestFunc ( f : func )
2021-06-22 19:32:17 +02:00
enddef
legacy call g :TestFunc ( {- > 0 })
delfunc g :TestFunc
def g :TestFunc ( f : func ( number ) )
enddef
legacy call g :TestFunc ( {nr - > 0 })
delfunc g :TestFunc
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptSuccess ( lines )
2021-03-05 21:35:47 +01:00
enddef
2021-10-23 13:32:30 +01:00
def Test_lambda_in_reduce_line_break ( )
# this was using freed memory
var lines = < < trim END
vim9script
const result : dict < number > =
['Bob' , 'Sam' , 'Cat' , 'Bob' , 'Cat' , 'Cat' ]
- > reduce ( ( acc , val ) = > {
if has_key ( acc , val )
acc [val ] + = 1
return acc
else
acc [val ] = 1
return acc
endif
}, {})
assert_equal ( {Bob : 2 , Sam : 1 , Cat : 3 }, result )
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptSuccess ( lines )
2021-10-23 13:32:30 +01:00
enddef
2021-12-09 14:23:43 +00:00
def Test_set_opfunc_to_lambda ( )
var lines = < < trim END
vim9script
nnoremap < expr > < F4 > < SID > CountSpaces ( ) .. '_'
def CountSpaces ( type = '' ) : string
if type = = ''
&operatorfunc = ( t ) = > CountSpaces ( t )
return 'g@'
endif
normal ! '[V' ]y
g :result = getreg ( '"' ) - > count ( ' ' )
return ''
enddef
new
'a b c d e' - > setline ( 1 )
feedkeys ( "\<F4>" , 'x' )
assert_equal ( 4 , g :result )
bwipe !
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptSuccess ( lines )
2021-12-09 14:23:43 +00:00
enddef
2021-12-12 21:02:03 +00:00
def Test_set_opfunc_to_global_function ( )
var lines = < < trim END
vim9script
def g :CountSpaces ( type = '' ) : string
normal ! '[V' ]y
g :result = getreg ( '"' ) - > count ( ' ' )
return ''
enddef
2021-12-16 15:49:43 +00:00
# global function works at script level
2021-12-12 21:02:03 +00:00
&operatorfunc = g :CountSpaces
new
'a b c d e' - > setline ( 1 )
feedkeys ( "g@_" , 'x' )
assert_equal ( 4 , g :result )
2021-12-16 15:49:43 +00:00
&operatorfunc = ''
g :result = 0
# global function works in :def function
def Func ( )
&operatorfunc = g :CountSpaces
enddef
Func ( )
feedkeys ( "g@_" , 'x' )
assert_equal ( 4 , g :result )
2021-12-12 21:02:03 +00:00
bwipe !
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptSuccess ( lines )
2021-12-12 21:02:03 +00:00
&operatorfunc = ''
enddef
2021-12-13 11:31:04 +00:00
def Test_use_script_func_name_with_prefix ( )
var lines = < < trim END
vim9script
2022-02-12 19:52:25 +00:00
func g :Getit ( )
2021-12-13 11:31:04 +00:00
return 'it'
endfunc
2022-02-12 19:52:25 +00:00
var Fn = g :Getit
2021-12-13 11:31:04 +00:00
assert_equal ( 'it' , Fn ( ) )
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptSuccess ( lines )
2021-12-13 11:31:04 +00:00
enddef
2021-12-10 10:37:38 +00:00
def Test_lambda_type_allocated ( )
# Check that unreferencing a partial using a lambda can use the variable type
# after the lambda has been freed and does not leak memory .
var lines = < < trim END
vim9script
func MyomniFunc1 ( val , findstart , base )
return a :findstart ? 0 : []
endfunc
var Lambda = ( a , b ) = > MyomniFunc1 ( 19 , a , b )
&omnifunc = Lambda
Lambda = ( a , b ) = > MyomniFunc1 ( 20 , a , b )
&omnifunc = string ( Lambda )
Lambda = ( a , b ) = > strlen ( a )
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptSuccess ( lines )
2021-12-10 10:37:38 +00:00
enddef
2020-04-05 17:08:17 +02:00
" Default arg and varargs
def MyDefVarargs ( one : string , two = 'foo' , ...rest : list < string > ) : string
2020-09-27 22:47:05 +02:00
var res = one .. ',' .. two
2020-04-05 17:08:17 +02:00
for s in rest
res ..= ',' .. s
endfor
return res
enddef
def Test_call_def_varargs ( )
2022-01-29 21:45:34 +00:00
assert_fails ( 'g:MyDefVarargs()' , 'E119:' , '' , 1 , 'Test_call_def_varargs' )
g :MyDefVarargs ( 'one' ) - > assert_equal ( 'one,foo' )
g :MyDefVarargs ( 'one' , 'two' ) - > assert_equal ( 'one,two' )
g :MyDefVarargs ( 'one' , 'two' , 'three' ) - > assert_equal ( 'one,two,three' )
v9 .CheckDefFailure ( ['g:MyDefVarargs("one", 22)' ],
2020-09-16 17:55:40 +02:00
'E1013: Argument 2: type mismatch, expected string but got number' )
2022-01-29 21:45:34 +00:00
v9 .CheckDefFailure ( ['g:MyDefVarargs("one", "two", 123)' ],
2020-09-16 17:55:40 +02:00
'E1013: Argument 3: type mismatch, expected string but got number' )
2020-07-25 16:33:02 +02:00
2020-09-27 22:47:05 +02:00
var lines = < < trim END
2020-07-25 16:33:02 +02:00
vim9script
def Func ( ...l : list < string > )
echo l
enddef
Func ( 'a' , 'b' , 'c' )
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptSuccess ( lines )
2020-07-25 16:33:02 +02:00
lines = < < trim END
vim9script
def Func ( ...l : list < string > )
echo l
enddef
Func ( )
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptSuccess ( lines )
2020-07-25 16:33:02 +02:00
2020-09-16 17:22:59 +02:00
lines = < < trim END
vim9script
2021-04-09 20:24:31 +02:00
def Func ( ...l : list < any > )
2020-09-16 17:22:59 +02:00
echo l
enddef
Func ( 0 )
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptSuccess ( lines )
2020-09-16 17:22:59 +02:00
2021-04-09 20:24:31 +02:00
lines = < < trim END
vim9script
def Func ( ...l : any )
echo l
enddef
Func ( 0 )
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptFailure ( lines , 'E1180:' , 2 )
2021-04-09 20:24:31 +02:00
2020-09-21 22:02:49 +02:00
lines = < < trim END
vim9script
def Func ( ..._l : list < string > )
echo _l
enddef
Func ( 'a' , 'b' , 'c' )
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptSuccess ( lines )
2020-09-21 22:02:49 +02:00
2020-07-25 16:33:02 +02:00
lines = < < trim END
vim9script
def Func ( ...l : list < string > )
echo l
enddef
Func ( 1 , 2 , 3 )
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptFailure ( lines , 'E1013: Argument 1: type mismatch' )
2020-07-25 16:33:02 +02:00
lines = < < trim END
vim9script
def Func ( ...l : list < string > )
echo l
enddef
Func ( 'a' , 9 )
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptFailure ( lines , 'E1013: Argument 2: type mismatch' )
2020-07-25 16:33:02 +02:00
lines = < < trim END
vim9script
def Func ( ...l : list < string > )
echo l
enddef
Func ( 1 , 'a' )
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptFailure ( lines , 'E1013: Argument 1: type mismatch' )
2021-02-07 15:59:49 +01:00
lines = < < trim END
vim9script
def Func ( # some comment
...l = []
)
echo l
enddef
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptFailure ( lines , 'E1160:' )
2021-08-07 15:35:36 +02:00
lines = < < trim END
vim9script
def DoIt ( )
g :Later ( '' )
enddef
defcompile
def g :Later ( ...l : list < number > )
enddef
DoIt ( )
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptFailure ( lines , 'E1013: Argument 1: type mismatch, expected number but got string' )
2020-04-05 17:08:17 +02:00
enddef
2020-04-11 20:50:33 +02:00
let s :value = ''
def FuncOneDefArg ( opt = 'text' )
s :value = opt
enddef
def FuncTwoDefArg ( nr = 123 , opt = 'text' ) : string
return nr .. opt
enddef
def FuncVarargs ( ...arg : list < string > ) : string
return join ( arg , ',' )
enddef
def Test_func_type_varargs ( )
2020-09-27 22:47:05 +02:00
var RefDefArg : func ( ?string )
2022-01-30 15:28:30 +00:00
RefDefArg = g :FuncOneDefArg
2020-04-11 20:50:33 +02:00
RefDefArg ( )
2020-09-11 19:09:48 +02:00
s :value - > assert_equal ( 'text' )
2020-04-11 20:50:33 +02:00
RefDefArg ( 'some' )
2020-09-11 19:09:48 +02:00
s :value - > assert_equal ( 'some' )
2020-04-11 20:50:33 +02:00
2020-09-27 22:47:05 +02:00
var RefDef2Arg : func ( ?number , ?string ) : string
2022-01-30 15:28:30 +00:00
RefDef2Arg = g :FuncTwoDefArg
2020-09-11 19:09:48 +02:00
RefDef2Arg ( ) - > assert_equal ( '123text' )
RefDef2Arg ( 99 ) - > assert_equal ( '99text' )
RefDef2Arg ( 77 , 'some' ) - > assert_equal ( '77some' )
2020-04-11 20:50:33 +02:00
2022-01-29 21:45:34 +00:00
v9 .CheckDefFailure ( ['var RefWrong: func(string?)' ], 'E1010:' )
v9 .CheckDefFailure ( ['var RefWrong: func(?string, string)' ], 'E1007:' )
2020-04-11 20:50:33 +02:00
2020-09-27 22:47:05 +02:00
var RefVarargs : func ( ...list < string > ) : string
2022-01-30 15:28:30 +00:00
RefVarargs = g :FuncVarargs
2020-09-11 19:09:48 +02:00
RefVarargs ( ) - > assert_equal ( '' )
RefVarargs ( 'one' ) - > assert_equal ( 'one' )
RefVarargs ( 'one' , 'two' ) - > assert_equal ( 'one,two' )
2020-04-11 20:50:33 +02:00
2022-01-29 21:45:34 +00:00
v9 .CheckDefFailure ( ['var RefWrong: func(...list<string>, string)' ], 'E110:' )
v9 .CheckDefFailure ( ['var RefWrong: func(...list<string>, ?string)' ], 'E110:' )
2020-04-11 20:50:33 +02:00
enddef
2020-04-07 22:05:08 +02:00
" Only varargs
def MyVarargsOnly ( ...args : list < string > ) : string
return join ( args , ',' )
enddef
def Test_call_varargs_only ( )
2022-01-29 21:45:34 +00:00
g :MyVarargsOnly ( ) - > assert_equal ( '' )
g :MyVarargsOnly ( 'one' ) - > assert_equal ( 'one' )
g :MyVarargsOnly ( 'one' , 'two' ) - > assert_equal ( 'one,two' )
v9 .CheckDefFailure ( ['g:MyVarargsOnly(1)' ], 'E1013: Argument 1: type mismatch, expected string but got number' )
v9 .CheckDefFailure ( ['g:MyVarargsOnly("one", 2)' ], 'E1013: Argument 2: type mismatch, expected string but got number' )
2020-04-07 22:05:08 +02:00
enddef
2020-04-05 17:08:17 +02:00
def Test_using_var_as_arg ( )
2021-12-30 17:09:05 +00:00
var lines = < < trim END
def Func ( x : number )
var x = 234
enddef
END
2022-01-29 21:45:34 +00:00
v9 .CheckDefFailure ( lines , 'E1006:' )
2021-12-30 17:09:05 +00:00
lines = < < trim END
def Func ( Ref : number )
def Ref ( )
enddef
enddef
END
2022-01-29 21:45:34 +00:00
v9 .CheckDefFailure ( lines , 'E1073:' )
2020-04-05 17:08:17 +02:00
enddef
2022-01-29 21:45:34 +00:00
def s :DictArg ( arg : dict < string > )
2020-05-10 22:53:56 +02:00
arg ['key' ] = 'value'
enddef
2022-01-29 21:45:34 +00:00
def s :ListArg ( arg : list < string > )
2020-05-10 22:53:56 +02:00
arg [0 ] = 'value'
enddef
def Test_assign_to_argument ( )
2020-07-17 20:36:00 +02:00
# works for dict and list
2020-09-27 22:47:05 +02:00
var d : dict < string > = {}
2020-05-10 22:53:56 +02:00
DictArg ( d )
2020-09-11 19:09:48 +02:00
d ['key' ]- > assert_equal ( 'value' )
2020-09-27 22:47:05 +02:00
var l : list < string > = []
2020-05-10 22:53:56 +02:00
ListArg ( l )
2020-09-11 19:09:48 +02:00
l [0 ]- > assert_equal ( 'value' )
2020-05-10 22:53:56 +02:00
2022-01-29 21:45:34 +00:00
v9 .CheckScriptFailure ( ['def Func(arg: number)' , 'arg = 3' , 'enddef' , 'defcompile' ], 'E1090:' )
2020-12-05 13:41:01 +01:00
delfunc ! g :Func
2020-05-10 22:53:56 +02:00
enddef
2020-09-20 22:04:00 +02:00
" These argument names are reserved in legacy functions.
2022-01-29 21:45:34 +00:00
def s :WithReservedNames ( firstline : string , lastline : string ) : string
2020-09-20 22:04:00 +02:00
return firstline .. lastline
enddef
def Test_argument_names ( )
assert_equal ( 'OK' , WithReservedNames ( 'O' , 'K' ) )
enddef
2020-04-05 17:08:17 +02:00
def Test_call_func_defined_later ( )
2020-09-11 19:09:48 +02:00
g :DefinedLater ( 'one' ) - > assert_equal ( 'one' )
2020-09-06 21:47:48 +02:00
assert_fails ( 'NotDefined("one")' , 'E117:' , '' , 2 , 'Test_call_func_defined_later' )
2020-04-05 17:08:17 +02:00
enddef
2020-04-23 18:13:23 +02:00
func DefinedLater ( arg )
return a :arg
endfunc
def Test_call_funcref ( )
2020-09-11 19:09:48 +02:00
g :SomeFunc ( 'abc' ) - > assert_equal ( 3 )
2020-09-06 21:47:48 +02:00
assert_fails ( 'NotAFunc()' , 'E117:' , '' , 2 , 'Test_call_funcref' ) # comment after call
2021-12-11 16:14:07 +00:00
assert_fails ( 'g:NotAFunc()' , 'E1085:' , '' , 3 , 'Test_call_funcref' )
2020-07-22 19:30:06 +02:00
2020-09-27 22:47:05 +02:00
var lines = < < trim END
2020-07-22 19:30:06 +02:00
vim9script
def RetNumber ( ) : number
return 123
enddef
2020-09-27 22:47:05 +02:00
var Funcref : func : number = function ( 'RetNumber' )
2020-09-11 19:09:48 +02:00
Funcref ( ) - > assert_equal ( 123 )
2020-07-22 19:30:06 +02:00
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptSuccess ( lines )
2020-07-22 20:16:11 +02:00
lines = < < trim END
vim9script
def RetNumber ( ) : number
return 123
enddef
def Bar ( F : func : number ) : number
return F ( )
enddef
2020-09-27 22:47:05 +02:00
var Funcref = function ( 'RetNumber' )
2020-09-11 19:09:48 +02:00
Bar ( Funcref ) - > assert_equal ( 123 )
2020-07-22 20:16:11 +02:00
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptSuccess ( lines )
2020-07-23 20:09:10 +02:00
lines = < < trim END
vim9script
def UseNumber ( nr : number )
echo nr
enddef
2020-09-27 22:47:05 +02:00
var Funcref : func ( number ) = function ( 'UseNumber' )
2020-07-23 20:09:10 +02:00
Funcref ( 123 )
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptSuccess ( lines )
2020-07-23 20:56:04 +02:00
lines = < < trim END
vim9script
def UseNumber ( nr : number )
echo nr
enddef
2020-09-27 22:47:05 +02:00
var Funcref : func ( string ) = function ( 'UseNumber' )
2020-07-23 20:56:04 +02:00
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptFailure ( lines , 'E1012: Type mismatch; expected func(string) but got func(number)' )
2020-07-26 17:56:25 +02:00
lines = < < trim END
vim9script
def EchoNr ( nr = 34 )
g :echo = nr
enddef
2020-09-27 22:47:05 +02:00
var Funcref : func ( ?number ) = function ( 'EchoNr' )
2020-07-26 17:56:25 +02:00
Funcref ( )
2020-09-11 19:09:48 +02:00
g :echo - > assert_equal ( 34 )
2020-07-26 17:56:25 +02:00
Funcref ( 123 )
2020-09-11 19:09:48 +02:00
g :echo - > assert_equal ( 123 )
2020-07-26 17:56:25 +02:00
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptSuccess ( lines )
2020-07-26 18:16:58 +02:00
lines = < < trim END
vim9script
def EchoList ( ...l : list < number > )
g :echo = l
enddef
2020-09-27 22:47:05 +02:00
var Funcref : func ( ...list < number > ) = function ( 'EchoList' )
2020-07-26 18:16:58 +02:00
Funcref ( )
2020-09-11 19:09:48 +02:00
g :echo - > assert_equal ( [])
2020-07-26 18:16:58 +02:00
Funcref ( 1 , 2 , 3 )
2020-09-11 19:09:48 +02:00
g :echo - > assert_equal ( [1 , 2 , 3 ])
2020-07-26 18:16:58 +02:00
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptSuccess ( lines )
2020-07-26 18:33:09 +02:00
lines = < < trim END
vim9script
def OptAndVar ( nr : number , opt = 12 , ...l : list < number > ) : number
g :optarg = opt
g :listarg = l
return nr
enddef
2020-09-27 22:47:05 +02:00
var Funcref : func ( number , ?number , ...list < number > ) : number = function ( 'OptAndVar' )
2020-09-11 19:09:48 +02:00
Funcref ( 10 ) - > assert_equal ( 10 )
g :optarg - > assert_equal ( 12 )
g :listarg - > assert_equal ( [])
2020-07-26 18:33:09 +02:00
2020-09-11 19:09:48 +02:00
Funcref ( 11 , 22 ) - > assert_equal ( 11 )
g :optarg - > assert_equal ( 22 )
g :listarg - > assert_equal ( [])
2020-07-26 18:33:09 +02:00
2020-09-11 19:09:48 +02:00
Funcref ( 17 , 18 , 1 , 2 , 3 ) - > assert_equal ( 17 )
g :optarg - > assert_equal ( 18 )
g :listarg - > assert_equal ( [1 , 2 , 3 ])
2020-07-26 18:33:09 +02:00
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptSuccess ( lines )
2020-04-23 18:13:23 +02:00
enddef
let SomeFunc = function ( 'len' )
let NotAFunc = 'text'
2020-04-12 14:39:53 +02:00
def CombineFuncrefTypes ( )
2020-07-17 20:36:00 +02:00
# same arguments , different return type
2020-09-27 22:47:05 +02:00
var Ref1 : func ( bool ) : string
var Ref2 : func ( bool ) : number
var Ref3 : func ( bool ) : any
2020-04-12 14:39:53 +02:00
Ref3 = g :cond ? Ref1 : Ref2
2020-07-17 20:36:00 +02:00
# different number of arguments
2020-09-27 22:47:05 +02:00
var Refa1 : func ( bool ) : number
var Refa2 : func ( bool , number ) : number
var Refa3 : func : number
2020-04-12 14:39:53 +02:00
Refa3 = g :cond ? Refa1 : Refa2
2020-07-17 20:36:00 +02:00
# different argument types
2020-09-27 22:47:05 +02:00
var Refb1 : func ( bool , string ) : number
var Refb2 : func ( string , number ) : number
var Refb3 : func ( any , any ) : number
2020-04-12 14:39:53 +02:00
Refb3 = g :cond ? Refb1 : Refb2
enddef
2020-04-05 17:08:17 +02:00
def FuncWithForwardCall ( )
2020-04-23 18:13:23 +02:00
return g :DefinedEvenLater ( "yes" )
2020-04-05 17:08:17 +02:00
enddef
def DefinedEvenLater ( arg : string ) : string
return arg
enddef
def Test_error_in_nested_function ( )
2020-07-17 20:36:00 +02:00
# Error in called function requires unwinding the call stack .
2022-01-30 15:28:30 +00:00
assert_fails ( 'g:FuncWithForwardCall()' , 'E1096:' , '' , 1 , 'FuncWithForwardCall' )
2020-04-05 17:08:17 +02:00
enddef
2021-12-28 17:23:12 +00:00
def Test_nested_function_with_nextcmd ( )
2021-12-26 14:23:22 +00:00
var lines = < < trim END
vim9script
# Define an outer function
def FirstFunction ( )
# Define an inner function
def SecondFunction ( )
# the function has a body , a double free is detected .
AAAAA
# enddef followed by | or } followed by # one or more characters
enddef | BBBB
enddef
# Compile all functions
defcompile
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptFailure ( lines , 'E1173: Text found after enddef: BBBB' )
2021-12-26 14:23:22 +00:00
enddef
2021-12-28 17:23:12 +00:00
def Test_nested_function_with_args_split ( )
var lines = < < trim END
vim9script
def FirstFunction ( )
def SecondFunction (
)
# had a double free if the right parenthesis of the nested function is
# on the next line
enddef | BBBB
enddef
# Compile all functions
defcompile
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptFailure ( lines , 'E1173: Text found after enddef: BBBB' )
2021-12-28 17:55:26 +00:00
lines = < < trim END
vim9script
def FirstFunction ( )
func SecondFunction ( )
endfunc | BBBB
enddef
defcompile
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptFailure ( lines , 'E1173: Text found after endfunction: BBBB' )
2021-12-28 17:23:12 +00:00
enddef
2022-01-08 15:39:39 +00:00
def Test_error_in_function_args ( )
var lines = < < trim END
def FirstFunction ( )
def SecondFunction ( J =
# Nois
# one
enddef | BBBB
enddef
# Compile all functions
defcompile
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptFailure ( lines , 'E488:' )
2022-01-08 15:39:39 +00:00
enddef
2020-04-05 17:08:17 +02:00
def Test_return_type_wrong ( )
2022-01-29 21:45:34 +00:00
v9 .CheckScriptFailure ( [
2020-08-08 16:47:30 +02:00
'def Func(): number' ,
'return "a"' ,
'enddef' ,
'defcompile' ], 'expected number but got string' )
2020-12-05 13:41:01 +01:00
delfunc ! g :Func
2022-01-29 21:45:34 +00:00
v9 .CheckScriptFailure ( [
2020-08-08 16:47:30 +02:00
'def Func(): string' ,
'return 1' ,
'enddef' ,
'defcompile' ], 'expected string but got number' )
2020-12-05 13:41:01 +01:00
delfunc ! g :Func
2022-01-29 21:45:34 +00:00
v9 .CheckScriptFailure ( [
2020-08-08 16:47:30 +02:00
'def Func(): void' ,
'return "a"' ,
'enddef' ,
'defcompile' ],
'E1096: Returning a value in a function without a return type' )
2020-12-05 13:41:01 +01:00
delfunc ! g :Func
2022-01-29 21:45:34 +00:00
v9 .CheckScriptFailure ( [
2020-08-08 16:47:30 +02:00
'def Func()' ,
'return "a"' ,
'enddef' ,
'defcompile' ],
'E1096: Returning a value in a function without a return type' )
2020-12-05 13:41:01 +01:00
delfunc ! g :Func
2020-08-08 16:47:30 +02:00
2022-01-29 21:45:34 +00:00
v9 .CheckScriptFailure ( [
2020-08-08 16:47:30 +02:00
'def Func(): number' ,
'return' ,
'enddef' ,
'defcompile' ], 'E1003:' )
2020-12-05 13:41:01 +01:00
delfunc ! g :Func
2020-04-05 17:08:17 +02:00
2022-01-29 21:45:34 +00:00
v9 .CheckScriptFailure ( [
2021-08-08 19:07:37 +02:00
'def Func():number' ,
'return 123' ,
'enddef' ,
'defcompile' ], 'E1069:' )
delfunc ! g :Func
2022-01-29 21:45:34 +00:00
v9 .CheckScriptFailure ( [
2021-08-08 19:07:37 +02:00
'def Func() :number' ,
'return 123' ,
'enddef' ,
'defcompile' ], 'E1059:' )
delfunc ! g :Func
2022-01-29 21:45:34 +00:00
v9 .CheckScriptFailure ( [
2021-08-08 19:07:37 +02:00
'def Func() : number' ,
'return 123' ,
'enddef' ,
'defcompile' ], 'E1059:' )
delfunc ! g :Func
2022-01-29 21:45:34 +00:00
v9 .CheckScriptFailure ( ['def Func(): list' , 'return []' , 'enddef' ], 'E1008:' )
2020-12-05 13:41:01 +01:00
delfunc ! g :Func
2022-01-29 21:45:34 +00:00
v9 .CheckScriptFailure ( ['def Func(): dict' , 'return {}' , 'enddef' ], 'E1008:' )
2020-12-05 13:41:01 +01:00
delfunc ! g :Func
2022-01-29 21:45:34 +00:00
v9 .CheckScriptFailure ( ['def Func()' , 'return 1' ], 'E1057:' )
2020-12-05 13:41:01 +01:00
delfunc ! g :Func
2020-08-08 16:47:30 +02:00
2022-01-29 21:45:34 +00:00
v9 .CheckScriptFailure ( [
2020-08-08 16:47:30 +02:00
'vim9script' ,
'def FuncB()' ,
' return 123' ,
'enddef' ,
'def FuncA()' ,
' FuncB()' ,
'enddef' ,
'defcompile' ], 'E1096:' )
2020-04-05 17:08:17 +02:00
enddef
def Test_arg_type_wrong ( )
2022-01-29 21:45:34 +00:00
v9 .CheckScriptFailure ( ['def Func3(items: list)' , 'echo "a"' , 'enddef' ], 'E1008: Missing <type>' )
v9 .CheckScriptFailure ( ['def Func4(...)' , 'echo "a"' , 'enddef' ], 'E1055: Missing name after ...' )
v9 .CheckScriptFailure ( ['def Func5(items:string)' , 'echo "a"' ], 'E1069:' )
v9 .CheckScriptFailure ( ['def Func5(items)' , 'echo "a"' ], 'E1077:' )
v9 .CheckScriptFailure ( ['def Func6(...x:list<number>)' , 'echo "a"' , 'enddef' ], 'E1069:' )
v9 .CheckScriptFailure ( ['def Func7(...x: int)' , 'echo "a"' , 'enddef' ], 'E1010:' )
2020-04-05 17:08:17 +02:00
enddef
2021-04-06 19:01:03 +02:00
def Test_white_space_before_comma ( )
var lines = < < trim END
vim9script
def Func ( a : number , b : number )
enddef
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptFailure ( lines , 'E1068:' )
2021-05-24 15:15:47 +02:00
call assert_fails ( 'vim9cmd echo stridx("a" .. "b" , "a")' , 'E1068:' )
2021-04-06 19:01:03 +02:00
enddef
2021-03-06 22:33:12 +01:00
def Test_white_space_after_comma ( )
var lines = < < trim END
vim9script
def Func ( a : number , b : number )
enddef
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptFailure ( lines , 'E1069:' )
2021-03-06 22:33:12 +01:00
# OK in legacy function
lines = < < trim END
vim9script
func Func ( a , b )
endfunc
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptSuccess ( lines )
2021-03-06 22:33:12 +01:00
enddef
2020-04-05 17:08:17 +02:00
def Test_vim9script_call ( )
2020-09-27 22:47:05 +02:00
var lines = < < trim END
2020-04-05 17:08:17 +02:00
vim9script
2020-09-27 22:47:05 +02:00
var name = ''
2020-04-05 17:08:17 +02:00
def MyFunc ( arg : string )
2020-09-27 22:47:05 +02:00
name = arg
2020-04-05 17:08:17 +02:00
enddef
MyFunc ( 'foobar' )
2020-09-27 22:47:05 +02:00
name - > assert_equal ( 'foobar' )
2020-04-05 17:08:17 +02:00
2020-09-27 22:47:05 +02:00
var str = 'barfoo'
2020-04-05 17:08:17 +02:00
str - > MyFunc ( )
2020-09-27 22:47:05 +02:00
name - > assert_equal ( 'barfoo' )
2020-04-05 17:08:17 +02:00
2020-06-20 22:50:47 +02:00
g :value = 'value'
2020-04-05 17:08:17 +02:00
g :value - > MyFunc ( )
2020-09-27 22:47:05 +02:00
name - > assert_equal ( 'value' )
2020-04-05 17:08:17 +02:00
2020-09-27 22:47:05 +02:00
var listvar = []
2020-04-05 17:08:17 +02:00
def ListFunc ( arg : list < number > )
listvar = arg
enddef
[1 , 2 , 3 ]- > ListFunc ( )
2020-09-11 19:09:48 +02:00
listvar - > assert_equal ( [1 , 2 , 3 ])
2020-04-05 17:08:17 +02:00
2020-09-27 22:47:05 +02:00
var dictvar = {}
2020-04-05 17:08:17 +02:00
def DictFunc ( arg : dict < number > )
dictvar = arg
enddef
2020-12-02 17:36:54 +01:00
{a : 1 , b : 2 }- > DictFunc ( )
dictvar - > assert_equal ( {a : 1 , b : 2 })
2020-04-05 17:08:17 +02:00
def CompiledDict ( )
2020-12-02 17:36:54 +01:00
{a : 3 , b : 4 }- > DictFunc ( )
2020-04-05 17:08:17 +02:00
enddef
CompiledDict ( )
2020-12-02 17:36:54 +01:00
dictvar - > assert_equal ( {a : 3 , b : 4 })
2020-04-05 17:08:17 +02:00
2020-12-02 17:36:54 +01:00
{a : 3 , b : 4 }- > DictFunc ( )
dictvar - > assert_equal ( {a : 3 , b : 4 })
2020-04-05 17:08:17 +02:00
( 'text' ) - > MyFunc ( )
2020-09-27 22:47:05 +02:00
name - > assert_equal ( 'text' )
2020-04-05 17:08:17 +02:00
( "some" ) - > MyFunc ( )
2020-09-27 22:47:05 +02:00
name - > assert_equal ( 'some' )
2020-07-01 17:28:33 +02:00
2020-07-24 18:47:22 +02:00
# line starting with single quote is not a mark
2020-07-29 20:00:38 +02:00
# line starting with double quote can be a method call
2020-07-15 14:15:52 +02:00
'asdfasdf' - > MyFunc ( )
2020-09-27 22:47:05 +02:00
name - > assert_equal ( 'asdfasdf' )
2020-07-29 20:00:38 +02:00
"xyz"->MyFunc()
2020-09-27 22:47:05 +02:00
name - > assert_equal ( 'xyz' )
2020-07-15 14:15:52 +02:00
def UseString ( )
'xyork' - > MyFunc ( )
enddef
UseString ( )
2020-09-27 22:47:05 +02:00
name - > assert_equal ( 'xyork' )
2020-07-15 14:15:52 +02:00
2020-07-29 20:00:38 +02:00
def UseString2 ( )
"knife"->MyFunc()
enddef
UseString2 ( )
2020-09-27 22:47:05 +02:00
name - > assert_equal ( 'knife' )
2020-07-29 20:00:38 +02:00
2020-07-24 18:47:22 +02:00
# prepending a colon makes it a mark
new
setline ( 1 , ['aaa' , 'bbb' , 'ccc' ])
normal ! 3 Gmt1 G
:'t
2020-09-11 19:09:48 +02:00
getcurpos ( ) [1 ]- > assert_equal ( 3 )
2020-07-24 18:47:22 +02:00
bwipe !
2020-07-01 17:28:33 +02:00
MyFunc (
'continued'
)
assert_equal ( 'continued' ,
2020-09-27 22:47:05 +02:00
name
2020-07-01 17:28:33 +02:00
)
call MyFunc (
'more'
..
'lines'
)
assert_equal (
'morelines' ,
2020-09-27 22:47:05 +02:00
name )
2020-04-05 17:08:17 +02:00
END
writefile ( lines , 'Xcall.vim' )
source Xcall .vim
delete ( 'Xcall.vim' )
enddef
def Test_vim9script_call_fail_decl ( )
2020-09-27 22:47:05 +02:00
var lines = < < trim END
2020-04-05 17:08:17 +02:00
vim9script
2020-09-27 22:47:05 +02:00
var name = ''
2020-04-05 17:08:17 +02:00
def MyFunc ( arg : string )
2020-09-27 22:47:05 +02:00
var name = 123
2020-04-05 17:08:17 +02:00
enddef
2020-05-24 23:00:18 +02:00
defcompile
2020-04-05 17:08:17 +02:00
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptFailure ( lines , 'E1054:' )
2020-04-05 17:08:17 +02:00
enddef
2020-07-19 14:03:09 +02:00
def Test_vim9script_call_fail_type ( )
2020-09-27 22:47:05 +02:00
var lines = < < trim END
2020-07-19 14:03:09 +02:00
vim9script
def MyFunc ( arg : string )
echo arg
enddef
MyFunc ( 1234 )
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptFailure ( lines , 'E1013: Argument 1: type mismatch, expected string but got number' )
2020-07-19 14:03:09 +02:00
enddef
2020-04-05 17:08:17 +02:00
def Test_vim9script_call_fail_const ( )
2020-09-27 22:47:05 +02:00
var lines = < < trim END
2020-04-05 17:08:17 +02:00
vim9script
const var = ''
def MyFunc ( arg : string )
var = 'asdf'
enddef
2020-05-24 23:00:18 +02:00
defcompile
2020-04-05 17:08:17 +02:00
END
writefile ( lines , 'Xcall_const.vim' )
2020-09-06 21:47:48 +02:00
assert_fails ( 'source Xcall_const.vim' , 'E46:' , '' , 1 , 'MyFunc' )
2020-04-05 17:08:17 +02:00
delete ( 'Xcall_const.vim' )
2020-12-22 20:35:40 +01:00
lines = < < trim END
const g :Aconst = 77
def Change ( )
# comment
g :Aconst = 99
enddef
call Change ( )
unlet g :Aconst
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptFailure ( lines , 'E741: Value is locked: Aconst' , 2 )
2020-04-05 17:08:17 +02:00
enddef
" Test that inside :function a Python function can be defined, :def is not
" recognized.
func Test_function_python ( )
CheckFeature python3
2020-09-27 23:33:59 +02:00
let py = 'python3'
2020-04-05 17:08:17 +02:00
execute py "<< EOF"
def do_something ( ) :
return 1
EOF
endfunc
def Test_delfunc ( )
2020-09-27 22:47:05 +02:00
var lines = < < trim END
2020-04-05 17:08:17 +02:00
vim9script
2020-04-27 22:47:51 +02:00
def g :GoneSoon ( )
2020-04-05 17:08:17 +02:00
echo 'hello'
enddef
def CallGoneSoon ( )
2022-01-29 21:45:34 +00:00
g :GoneSoon ( )
2020-04-05 17:08:17 +02:00
enddef
2020-05-24 23:00:18 +02:00
defcompile
2020-04-05 17:08:17 +02:00
2020-04-27 22:47:51 +02:00
delfunc g :GoneSoon
2020-04-05 17:08:17 +02:00
CallGoneSoon ( )
END
writefile ( lines , 'XToDelFunc' )
2020-09-06 21:47:48 +02:00
assert_fails ( 'so XToDelFunc' , 'E933:' , '' , 1 , 'CallGoneSoon' )
assert_fails ( 'so XToDelFunc' , 'E933:' , '' , 1 , 'CallGoneSoon' )
2020-04-05 17:08:17 +02:00
delete ( 'XToDelFunc' )
enddef
2021-12-14 18:14:37 +00:00
func Test_free_dict_while_in_funcstack ( )
" relies on the sleep command
CheckUnix
call Run_Test_free_dict_while_in_funcstack ( )
endfunc
def Run_Test_free_dict_while_in_funcstack ( )
# this was freeing the TermRun ( ) default argument dictionary while it was
# still referenced in a funcstack_T
var lines = < < trim END
vim9script
&updatetime = 400
def TermRun ( _ = {})
def Post ( )
enddef
def Exec ( )
term_start ( 'sleep 1' , {
term_finish : 'close' ,
exit_cb : ( _ , _ ) = > Post ( ) ,
})
enddef
Exec ( )
enddef
nnoremap < F4 > < Cmd > call < SID > TermRun ( ) < CR >
timer_start ( 100 , ( _ ) = > feedkeys ( "\<F4>" ) )
timer_start ( 1000 , ( _ ) = > feedkeys ( "\<F4>" ) )
sleep 1500 m
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptSuccess ( lines )
2021-12-14 18:14:37 +00:00
nunmap < F4 >
set updatetime &
enddef
2020-04-05 17:08:17 +02:00
def Test_redef_failure ( )
2020-09-06 15:58:36 +02:00
writefile ( ['def Func0(): string' , 'return "Func0"' , 'enddef' ], 'Xdef' )
2020-04-05 17:08:17 +02:00
so Xdef
2020-09-06 15:58:36 +02:00
writefile ( ['def Func1(): string' , 'return "Func1"' , 'enddef' ], 'Xdef' )
2020-04-05 17:08:17 +02:00
so Xdef
2020-09-06 15:58:36 +02:00
writefile ( ['def! Func0(): string' , 'enddef' , 'defcompile' ], 'Xdef' )
2020-09-06 21:47:48 +02:00
assert_fails ( 'so Xdef' , 'E1027:' , '' , 1 , 'Func0' )
2020-09-06 15:58:36 +02:00
writefile ( ['def Func2(): string' , 'return "Func2"' , 'enddef' ], 'Xdef' )
2020-04-05 17:08:17 +02:00
so Xdef
2020-09-06 15:58:36 +02:00
delete ( 'Xdef' )
2020-04-05 17:08:17 +02:00
2021-04-10 13:33:48 +02:00
assert_fails ( 'g:Func0()' , 'E1091:' )
2020-09-11 19:09:48 +02:00
g :Func1 ( ) - > assert_equal ( 'Func1' )
g :Func2 ( ) - > assert_equal ( 'Func2' )
2020-04-05 17:08:17 +02:00
delfunc ! Func0
delfunc ! Func1
delfunc ! Func2
enddef
2020-04-23 22:16:53 +02:00
def Test_vim9script_func ( )
2020-09-27 22:47:05 +02:00
var lines = < < trim END
2020-04-23 22:16:53 +02:00
vim9script
func Func ( arg )
echo a :arg
endfunc
Func ( 'text' )
END
writefile ( lines , 'XVim9Func' )
so XVim9Func
delete ( 'XVim9Func' )
enddef
2020-04-05 17:08:17 +02:00
let s :funcResult = 0
def FuncNoArgNoRet ( )
2020-08-22 19:02:02 +02:00
s :funcResult = 11
2020-04-05 17:08:17 +02:00
enddef
def FuncNoArgRetNumber ( ) : number
2020-08-22 19:02:02 +02:00
s :funcResult = 22
2020-04-05 17:08:17 +02:00
return 1234
enddef
2020-04-07 20:53:39 +02:00
def FuncNoArgRetString ( ) : string
2020-08-22 19:02:02 +02:00
s :funcResult = 45
2020-04-07 20:53:39 +02:00
return 'text'
enddef
2020-04-05 17:08:17 +02:00
def FuncOneArgNoRet ( arg : number )
2020-08-22 19:02:02 +02:00
s :funcResult = arg
2020-04-05 17:08:17 +02:00
enddef
def FuncOneArgRetNumber ( arg : number ) : number
2020-08-22 19:02:02 +02:00
s :funcResult = arg
2020-04-05 17:08:17 +02:00
return arg
enddef
2020-04-11 23:17:17 +02:00
def FuncTwoArgNoRet ( one : bool , two : number )
2020-08-22 19:02:02 +02:00
s :funcResult = two
2020-04-11 23:17:17 +02:00
enddef
2022-01-29 21:45:34 +00:00
def s :FuncOneArgRetString ( arg : string ) : string
2020-04-07 20:53:39 +02:00
return arg
enddef
2022-01-29 21:45:34 +00:00
def s :FuncOneArgRetAny ( arg : any ) : any
2020-04-05 22:14:54 +02:00
return arg
enddef
2020-04-05 17:08:17 +02:00
def Test_func_type ( )
2020-09-27 22:47:05 +02:00
var Ref1 : func ( )
2020-08-22 19:02:02 +02:00
s :funcResult = 0
2022-01-29 21:45:34 +00:00
Ref1 = g :FuncNoArgNoRet
2020-04-05 17:08:17 +02:00
Ref1 ( )
2020-09-11 19:09:48 +02:00
s :funcResult - > assert_equal ( 11 )
2020-04-05 21:38:23 +02:00
2020-09-27 22:47:05 +02:00
var Ref2 : func
2020-08-22 19:02:02 +02:00
s :funcResult = 0
2022-01-29 21:45:34 +00:00
Ref2 = g :FuncNoArgNoRet
2020-04-05 21:38:23 +02:00
Ref2 ( )
2020-09-11 19:09:48 +02:00
s :funcResult - > assert_equal ( 11 )
2020-04-05 21:38:23 +02:00
2020-08-22 19:02:02 +02:00
s :funcResult = 0
2022-01-29 21:45:34 +00:00
Ref2 = g :FuncOneArgNoRet
2020-04-05 21:38:23 +02:00
Ref2 ( 12 )
2020-09-11 19:09:48 +02:00
s :funcResult - > assert_equal ( 12 )
2020-04-05 21:38:23 +02:00
2020-08-22 19:02:02 +02:00
s :funcResult = 0
2022-01-29 21:45:34 +00:00
Ref2 = g :FuncNoArgRetNumber
2020-09-11 19:09:48 +02:00
Ref2 ( ) - > assert_equal ( 1234 )
s :funcResult - > assert_equal ( 22 )
2020-04-05 21:38:23 +02:00
2020-08-22 19:02:02 +02:00
s :funcResult = 0
2022-01-30 15:28:30 +00:00
Ref2 = g :FuncOneArgRetNumber
2020-09-11 19:09:48 +02:00
Ref2 ( 13 ) - > assert_equal ( 13 )
s :funcResult - > assert_equal ( 13 )
2020-04-05 17:08:17 +02:00
enddef
2020-07-05 16:01:56 +02:00
def Test_repeat_return_type ( )
2020-09-27 22:47:05 +02:00
var res = 0
2020-07-05 16:01:56 +02:00
for n in repeat ( [1 ], 3 )
res + = n
endfor
2020-09-11 19:09:48 +02:00
res - > assert_equal ( 3 )
2020-07-05 16:07:21 +02:00
res = 0
for n in add ( [1 , 2 ], 3 )
res + = n
endfor
2020-09-11 19:09:48 +02:00
res - > assert_equal ( 6 )
2020-07-05 16:01:56 +02:00
enddef
2020-07-05 17:04:13 +02:00
def Test_argv_return_type ( )
next fileone filetwo
2020-09-27 22:47:05 +02:00
var res = ''
2020-07-05 17:04:13 +02:00
for name in argv ( )
res ..= name
endfor
2020-09-11 19:09:48 +02:00
res - > assert_equal ( 'fileonefiletwo' )
2020-07-05 17:04:13 +02:00
enddef
2020-04-07 20:53:39 +02:00
def Test_func_type_part ( )
2020-09-27 22:47:05 +02:00
var RefVoid : func : void
2022-01-29 21:45:34 +00:00
RefVoid = g :FuncNoArgNoRet
RefVoid = g :FuncOneArgNoRet
v9 .CheckDefFailure ( ['var RefVoid: func: void' , 'RefVoid = g:FuncNoArgRetNumber' ], 'E1012: Type mismatch; expected func(...) but got func(): number' )
2022-01-30 15:28:30 +00:00
v9 .CheckDefFailure ( ['var RefVoid: func: void' , 'RefVoid = g:FuncNoArgRetString' ], 'E1012: Type mismatch; expected func(...) but got func(): string' )
2020-04-07 20:53:39 +02:00
2020-09-27 22:47:05 +02:00
var RefAny : func ( ) : any
2022-01-29 21:45:34 +00:00
RefAny = g :FuncNoArgRetNumber
2022-01-30 15:28:30 +00:00
RefAny = g :FuncNoArgRetString
2022-01-29 21:45:34 +00:00
v9 .CheckDefFailure ( ['var RefAny: func(): any' , 'RefAny = g:FuncNoArgNoRet' ], 'E1012: Type mismatch; expected func(): any but got func()' )
v9 .CheckDefFailure ( ['var RefAny: func(): any' , 'RefAny = g:FuncOneArgNoRet' ], 'E1012: Type mismatch; expected func(): any but got func(number)' )
2020-04-07 20:53:39 +02:00
2020-10-04 14:17:32 +02:00
var RefAnyNoArgs : func : any = RefAny
2020-09-27 22:47:05 +02:00
var RefNr : func : number
2022-01-29 21:45:34 +00:00
RefNr = g :FuncNoArgRetNumber
2022-01-30 15:28:30 +00:00
RefNr = g :FuncOneArgRetNumber
2022-01-29 21:45:34 +00:00
v9 .CheckDefFailure ( ['var RefNr: func: number' , 'RefNr = g:FuncNoArgNoRet' ], 'E1012: Type mismatch; expected func(...): number but got func()' )
2022-01-30 15:28:30 +00:00
v9 .CheckDefFailure ( ['var RefNr: func: number' , 'RefNr = g:FuncNoArgRetString' ], 'E1012: Type mismatch; expected func(...): number but got func(): string' )
2020-04-07 20:53:39 +02:00
2020-09-27 22:47:05 +02:00
var RefStr : func : string
2022-01-30 15:28:30 +00:00
RefStr = g :FuncNoArgRetString
2020-04-07 20:53:39 +02:00
RefStr = FuncOneArgRetString
2022-01-29 21:45:34 +00:00
v9 .CheckDefFailure ( ['var RefStr: func: string' , 'RefStr = g:FuncNoArgNoRet' ], 'E1012: Type mismatch; expected func(...): string but got func()' )
v9 .CheckDefFailure ( ['var RefStr: func: string' , 'RefStr = g:FuncNoArgRetNumber' ], 'E1012: Type mismatch; expected func(...): string but got func(): number' )
2020-04-07 20:53:39 +02:00
enddef
2020-04-05 17:08:17 +02:00
def Test_func_type_fails ( )
2022-01-29 21:45:34 +00:00
v9 .CheckDefFailure ( ['var ref1: func()' ], 'E704:' )
2020-04-05 17:08:17 +02:00
2022-01-29 21:45:34 +00:00
v9 .CheckDefFailure ( ['var Ref1: func()' , 'Ref1 = g:FuncNoArgRetNumber' ], 'E1012: Type mismatch; expected func() but got func(): number' )
v9 .CheckDefFailure ( ['var Ref1: func()' , 'Ref1 = g:FuncOneArgNoRet' ], 'E1012: Type mismatch; expected func() but got func(number)' )
2022-01-30 15:28:30 +00:00
v9 .CheckDefFailure ( ['var Ref1: func()' , 'Ref1 = g:FuncOneArgRetNumber' ], 'E1012: Type mismatch; expected func() but got func(number): number' )
2022-01-29 21:45:34 +00:00
v9 .CheckDefFailure ( ['var Ref1: func(bool)' , 'Ref1 = g:FuncTwoArgNoRet' ], 'E1012: Type mismatch; expected func(bool) but got func(bool, number)' )
v9 .CheckDefFailure ( ['var Ref1: func(?bool)' , 'Ref1 = g:FuncTwoArgNoRet' ], 'E1012: Type mismatch; expected func(?bool) but got func(bool, number)' )
v9 .CheckDefFailure ( ['var Ref1: func(...bool)' , 'Ref1 = g:FuncTwoArgNoRet' ], 'E1012: Type mismatch; expected func(...bool) but got func(bool, number)' )
2020-04-11 23:17:17 +02:00
2022-01-29 21:45:34 +00:00
v9 .CheckDefFailure ( ['var RefWrong: func(string ,number)' ], 'E1068:' )
v9 .CheckDefFailure ( ['var RefWrong: func(string,number)' ], 'E1069:' )
v9 .CheckDefFailure ( ['var RefWrong: func(bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool)' ], 'E1005:' )
v9 .CheckDefFailure ( ['var RefWrong: func(bool):string' ], 'E1069:' )
2020-04-05 17:08:17 +02:00
enddef
2020-04-05 22:14:54 +02:00
def Test_func_return_type ( )
2020-09-27 22:47:05 +02:00
var nr : number
2022-01-29 21:45:34 +00:00
nr = g :FuncNoArgRetNumber ( )
2020-09-11 19:09:48 +02:00
nr - > assert_equal ( 1234 )
2020-04-05 22:14:54 +02:00
nr = FuncOneArgRetAny ( 122 )
2020-09-11 19:09:48 +02:00
nr - > assert_equal ( 122 )
2020-04-05 22:14:54 +02:00
2020-09-27 22:47:05 +02:00
var str : string
2020-04-05 22:14:54 +02:00
str = FuncOneArgRetAny ( 'yes' )
2020-09-11 19:09:48 +02:00
str - > assert_equal ( 'yes' )
2020-04-05 22:14:54 +02:00
2022-01-29 21:45:34 +00:00
v9 .CheckDefFailure ( ['var str: string' , 'str = g:FuncNoArgRetNumber()' ], 'E1012: Type mismatch; expected string but got number' )
2020-04-05 22:14:54 +02:00
enddef
2020-10-04 14:17:32 +02:00
def Test_func_common_type ( )
def FuncOne ( n : number ) : number
return n
enddef
def FuncTwo ( s : string ) : number
return len ( s )
enddef
def FuncThree ( n : number , s : string ) : number
return n + len ( s )
enddef
var list = [FuncOne , FuncTwo , FuncThree ]
assert_equal ( 8 , list [0 ]( 8 ) )
assert_equal ( 4 , list [1 ]( 'word' ) )
assert_equal ( 7 , list [2 ]( 3 , 'word' ) )
enddef
2022-01-29 21:45:34 +00:00
def s :MultiLine (
2020-04-12 21:53:00 +02:00
arg1 : string ,
arg2 = 1234 ,
...rest : list < string >
) : string
return arg1 .. arg2 .. join ( rest , '-' )
enddef
2020-04-13 14:41:35 +02:00
def MultiLineComment (
arg1 : string , # comment
arg2 = 1234 , # comment
...rest : list < string > # comment
) : string # comment
return arg1 .. arg2 .. join ( rest , '-' )
enddef
2020-04-12 21:53:00 +02:00
def Test_multiline ( )
2020-09-11 19:09:48 +02:00
MultiLine ( 'text' ) - > assert_equal ( 'text1234' )
MultiLine ( 'text' , 777 ) - > assert_equal ( 'text777' )
MultiLine ( 'text' , 777 , 'one' ) - > assert_equal ( 'text777one' )
MultiLine ( 'text' , 777 , 'one' , 'two' ) - > assert_equal ( 'text777one-two' )
2020-04-12 21:53:00 +02:00
enddef
2020-04-12 22:22:31 +02:00
func Test_multiline_not_vim9 ( )
2022-01-29 21:45:34 +00:00
call s :MultiLine ( 'text' ) - > assert_equal ( 'text1234' )
call s :MultiLine ( 'text' , 777 ) - > assert_equal ( 'text777' )
call s :MultiLine ( 'text' , 777 , 'one' ) - > assert_equal ( 'text777one' )
call s :MultiLine ( 'text' , 777 , 'one' , 'two' ) - > assert_equal ( 'text777one-two' )
2020-04-12 22:22:31 +02:00
endfunc
2020-04-12 21:53:00 +02:00
2020-04-06 21:35:05 +02:00
" When using CheckScriptFailure() for the below test, E1010 is generated instead
" of E1056.
func Test_E1056_1059 ( )
let caught_1056 = 0
try
def F ( ) :
return 1
enddef
catch /E1056:/
let caught_1056 = 1
endtry
2020-09-11 19:09:48 +02:00
eval caught_1056 - > assert_equal ( 1 )
2020-04-06 21:35:05 +02:00
let caught_1059 = 0
try
def F5 ( items : list )
echo 'a'
enddef
catch /E1059:/
let caught_1059 = 1
endtry
2020-09-11 19:09:48 +02:00
eval caught_1059 - > assert_equal ( 1 )
2020-04-06 21:35:05 +02:00
endfunc
2020-04-05 17:08:17 +02:00
2020-05-05 21:25:22 +02:00
func DelMe ( )
echo 'DelMe'
endfunc
2020-08-08 14:26:31 +02:00
def Test_error_reporting ( )
# comment lines at the start of the function
2020-09-27 22:47:05 +02:00
var lines = < < trim END
2020-08-08 14:26:31 +02:00
" comment
def Func ( )
# comment
# comment
invalid
enddef
defcompile
END
2020-09-14 17:04:31 +02:00
writefile ( lines , 'Xdef' )
2020-08-08 14:26:31 +02:00
try
source Xdef
2020-08-14 18:35:07 +02:00
assert_report ( 'should have failed' )
2020-08-08 14:26:31 +02:00
catch /E476:/
2020-09-11 19:09:48 +02:00
v :exception - > assert_match ( 'Invalid command: invalid' )
v :throwpoint - > assert_match ( ', line 3$' )
2020-08-08 14:26:31 +02:00
endtry
2020-12-05 13:41:01 +01:00
delfunc ! g :Func
2020-08-08 14:26:31 +02:00
# comment lines after the start of the function
lines = < < trim END
" comment
def Func ( )
2020-09-27 22:47:05 +02:00
var x = 1234
2020-08-08 14:26:31 +02:00
# comment
# comment
invalid
enddef
defcompile
END
2020-09-14 17:04:31 +02:00
writefile ( lines , 'Xdef' )
2020-08-08 14:26:31 +02:00
try
source Xdef
2020-08-14 18:35:07 +02:00
assert_report ( 'should have failed' )
2020-08-08 14:26:31 +02:00
catch /E476:/
2020-09-11 19:09:48 +02:00
v :exception - > assert_match ( 'Invalid command: invalid' )
v :throwpoint - > assert_match ( ', line 4$' )
2020-08-08 14:26:31 +02:00
endtry
2020-12-05 13:41:01 +01:00
delfunc ! g :Func
2020-08-08 14:26:31 +02:00
2020-08-14 18:35:07 +02:00
lines = < < trim END
vim9script
def Func ( )
2020-12-02 17:36:54 +01:00
var db = {foo : 1 , bar : 2 }
2020-08-14 18:35:07 +02:00
# comment
2020-09-27 22:47:05 +02:00
var x = db .asdf
2020-08-14 18:35:07 +02:00
enddef
defcompile
Func ( )
END
2020-09-14 17:04:31 +02:00
writefile ( lines , 'Xdef' )
2020-08-14 18:35:07 +02:00
try
source Xdef
assert_report ( 'should have failed' )
catch /E716:/
2020-09-11 19:09:48 +02:00
v :throwpoint - > assert_match ( '_Func, line 3$' )
2020-08-14 18:35:07 +02:00
endtry
2020-12-05 13:41:01 +01:00
delfunc ! g :Func
2020-08-14 18:35:07 +02:00
2020-09-14 17:04:31 +02:00
delete ( 'Xdef' )
2020-08-08 14:26:31 +02:00
enddef
2020-05-05 21:25:22 +02:00
def Test_deleted_function ( )
2022-01-29 21:45:34 +00:00
v9 .CheckDefExecFailure ( [
2020-09-27 22:47:05 +02:00
'var RefMe: func = function("g:DelMe")' ,
2020-05-05 21:25:22 +02:00
'delfunc g:DelMe' ,
'echo RefMe()' ], 'E117:' )
enddef
def Test_unknown_function ( )
2022-01-29 21:45:34 +00:00
v9 .CheckDefExecFailure ( [
2020-09-27 22:47:05 +02:00
'var Ref: func = function("NotExist")' ,
2020-07-11 22:14:59 +02:00
'delfunc g:NotExist' ], 'E700:' )
2020-05-05 21:25:22 +02:00
enddef
2022-01-29 21:45:34 +00:00
def s :RefFunc ( Ref : func ( any ) : any ) : string
2020-05-01 19:29:08 +02:00
return Ref ( 'more' )
enddef
def Test_closure_simple ( )
2020-09-27 22:47:05 +02:00
var local = 'some '
2020-12-31 21:28:47 +01:00
RefFunc ( ( s ) = > local .. s ) - > assert_equal ( 'some more' )
2020-05-01 19:29:08 +02:00
enddef
2022-01-29 21:45:34 +00:00
def s :MakeRef ( )
2020-09-27 22:47:05 +02:00
var local = 'some '
2020-12-31 21:28:47 +01:00
g :Ref = ( s ) = > local .. s
2020-05-02 17:52:42 +02:00
enddef
def Test_closure_ref_after_return ( )
MakeRef ( )
2020-09-11 19:09:48 +02:00
g :Ref ( 'thing' ) - > assert_equal ( 'some thing' )
2020-05-02 17:52:42 +02:00
unlet g :Ref
enddef
2022-01-29 21:45:34 +00:00
def s :MakeTwoRefs ( )
2020-09-27 22:47:05 +02:00
var local = ['some' ]
2020-12-31 21:28:47 +01:00
g :Extend = ( s ) = > local - > add ( s )
g :Read = ( ) = > local
2020-05-02 23:12:58 +02:00
enddef
def Test_closure_two_refs ( )
MakeTwoRefs ( )
2020-09-11 19:09:48 +02:00
join ( g :Read ( ) , ' ' ) - > assert_equal ( 'some' )
2020-05-02 23:12:58 +02:00
g :Extend ( 'more' )
2020-09-11 19:09:48 +02:00
join ( g :Read ( ) , ' ' ) - > assert_equal ( 'some more' )
2020-05-02 23:12:58 +02:00
g :Extend ( 'even' )
2020-09-11 19:09:48 +02:00
join ( g :Read ( ) , ' ' ) - > assert_equal ( 'some more even' )
2020-05-02 23:12:58 +02:00
unlet g :Extend
unlet g :Read
enddef
2022-01-29 21:45:34 +00:00
def s :ReadRef ( Ref : func ( ) : list < string > ) : string
2020-05-02 23:12:58 +02:00
return join ( Ref ( ) , ' ' )
enddef
2022-01-29 21:45:34 +00:00
def s :ExtendRef ( Ref : func ( string ) : list < string > , add : string )
2020-05-02 23:12:58 +02:00
Ref ( add )
enddef
def Test_closure_two_indirect_refs ( )
2020-05-03 15:38:16 +02:00
MakeTwoRefs ( )
2020-09-11 19:09:48 +02:00
ReadRef ( g :Read ) - > assert_equal ( 'some' )
2020-05-02 23:12:58 +02:00
ExtendRef ( g :Extend , 'more' )
2020-09-11 19:09:48 +02:00
ReadRef ( g :Read ) - > assert_equal ( 'some more' )
2020-05-02 23:12:58 +02:00
ExtendRef ( g :Extend , 'even' )
2020-09-11 19:09:48 +02:00
ReadRef ( g :Read ) - > assert_equal ( 'some more even' )
2020-05-02 23:12:58 +02:00
unlet g :Extend
unlet g :Read
enddef
2020-05-02 17:52:42 +02:00
2022-01-29 21:45:34 +00:00
def s :MakeArgRefs ( theArg : string )
2020-09-27 22:47:05 +02:00
var local = 'loc_val'
2020-12-31 21:28:47 +01:00
g :UseArg = ( s ) = > theArg .. '/' .. local .. '/' .. s
2020-05-03 22:30:49 +02:00
enddef
2022-01-29 21:45:34 +00:00
def s :MakeArgRefsVarargs ( theArg : string , ...rest : list < string > )
2020-09-27 22:47:05 +02:00
var local = 'the_loc'
2020-12-31 21:28:47 +01:00
g :UseVararg = ( s ) = > theArg .. '/' .. local .. '/' .. s .. '/' .. join ( rest )
2020-05-03 22:30:49 +02:00
enddef
def Test_closure_using_argument ( )
MakeArgRefs ( 'arg_val' )
2020-09-11 19:09:48 +02:00
g :UseArg ( 'call_val' ) - > assert_equal ( 'arg_val/loc_val/call_val' )
2020-05-03 22:30:49 +02:00
MakeArgRefsVarargs ( 'arg_val' , 'one' , 'two' )
2020-09-11 19:09:48 +02:00
g :UseVararg ( 'call_val' ) - > assert_equal ( 'arg_val/the_loc/call_val/one two' )
2020-05-03 22:30:49 +02:00
unlet g :UseArg
unlet g :UseVararg
2021-02-12 21:50:57 +01:00
var lines = < < trim END
vim9script
def Test ( Fun : func ( number ) : number ) : list < number >
return map ( [1 , 2 , 3 ], ( _ , i ) = > Fun ( i ) )
enddef
def Inc ( nr : number ) : number
return nr + 2
enddef
assert_equal ( [3 , 4 , 5 ], Test ( Inc ) )
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptSuccess ( lines )
2020-05-03 22:30:49 +02:00
enddef
2022-01-29 21:45:34 +00:00
def s :MakeGetAndAppendRefs ( )
2020-10-10 14:13:01 +02:00
var local = 'a'
def Append ( arg : string )
local ..= arg
enddef
g :Append = Append
def Get ( ) : string
return local
enddef
g :Get = Get
enddef
def Test_closure_append_get ( )
MakeGetAndAppendRefs ( )
g :Get ( ) - > assert_equal ( 'a' )
g :Append ( '-b' )
g :Get ( ) - > assert_equal ( 'a-b' )
g :Append ( '-c' )
g :Get ( ) - > assert_equal ( 'a-b-c' )
unlet g :Append
unlet g :Get
enddef
2020-05-06 21:06:30 +02:00
2020-05-04 23:24:44 +02:00
def Test_nested_closure ( )
2020-09-27 22:47:05 +02:00
var local = 'text'
2020-05-04 23:24:44 +02:00
def Closure ( arg : string ) : string
return local .. arg
enddef
2020-09-11 19:09:48 +02:00
Closure ( '!!!' ) - > assert_equal ( 'text!!!' )
2020-05-04 23:24:44 +02:00
enddef
2022-01-29 21:45:34 +00:00
func s :GetResult ( Ref )
2020-05-16 21:20:12 +02:00
return a :Ref ( 'some' )
endfunc
def Test_call_closure_not_compiled ( )
2020-09-27 22:47:05 +02:00
var text = 'text'
2020-12-31 21:28:47 +01:00
g :Ref = ( s ) = > s .. text
2020-09-11 19:09:48 +02:00
GetResult ( g :Ref ) - > assert_equal ( 'sometext' )
2020-05-16 21:20:12 +02:00
enddef
2020-09-18 21:25:32 +02:00
def Test_double_closure_fails ( )
2020-09-27 22:47:05 +02:00
var lines = < < trim END
2020-09-18 21:25:32 +02:00
vim9script
def Func ( )
2020-09-27 22:47:05 +02:00
var name = 0
for i in range ( 2 )
2020-12-31 21:28:47 +01:00
timer_start ( 0 , ( ) = > name )
2020-09-27 22:47:05 +02:00
endfor
2020-09-18 21:25:32 +02:00
enddef
Func ( )
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptSuccess ( lines )
2020-09-18 21:25:32 +02:00
enddef
2020-10-10 14:13:01 +02:00
def Test_nested_closure_used ( )
var lines = < < trim END
vim9script
def Func ( )
var x = 'hello'
2020-12-31 21:28:47 +01:00
var Closure = ( ) = > x
g :Myclosure = ( ) = > Closure ( )
2020-10-10 14:13:01 +02:00
enddef
Func ( )
assert_equal ( 'hello' , g :Myclosure ( ) )
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptSuccess ( lines )
2020-10-10 14:13:01 +02:00
enddef
2020-10-07 19:08:04 +02:00
2020-09-26 19:59:38 +02:00
def Test_nested_closure_fails ( )
2020-09-27 22:47:05 +02:00
var lines = < < trim END
2020-09-26 19:59:38 +02:00
vim9script
def FuncA ( )
FuncB ( 0 )
enddef
def FuncB ( n : number ) : list < string >
2020-12-31 21:28:47 +01:00
return map ( [0 ], ( _ , v ) = > n )
2020-09-26 19:59:38 +02:00
enddef
FuncA ( )
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptFailure ( lines , 'E1012:' )
2020-09-26 19:59:38 +02:00
enddef
2020-12-20 17:47:52 +01:00
def Test_global_closure ( )
var lines = < < trim END
vim9script
def ReverseEveryNLines ( n : number , line1 : number , line2 : number )
var mods = 'sil keepj keepp lockm '
var range = ':' .. line1 .. ',' .. line2
def g :Offset ( ) : number
var offset = ( line ( '.' ) - line1 + 1 ) % n
return offset ! = 0 ? offset : n
enddef
exe mods .. range .. 'g/^/exe "m .-" .. g:Offset()'
enddef
new
repeat ( ['aaa' , 'bbb' , 'ccc' ], 3 ) - > setline ( 1 )
ReverseEveryNLines ( 3 , 1 , 9 )
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptSuccess ( lines )
2020-12-20 17:47:52 +01:00
var expected = repeat ( ['ccc' , 'bbb' , 'aaa' ], 3 )
assert_equal ( expected , getline ( 1 , 9 ) )
bwipe !
enddef
2020-12-22 17:35:54 +01:00
def Test_global_closure_called_directly ( )
var lines = < < trim END
vim9script
def Outer ( )
var x = 1
def g :Inner ( )
var y = x
x + = 1
assert_equal ( 1 , y )
enddef
g :Inner ( )
assert_equal ( 2 , x )
enddef
Outer ( )
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptSuccess ( lines )
2020-12-22 17:35:54 +01:00
delfunc g :Inner
enddef
2021-12-02 16:38:52 +00:00
def Test_closure_called_from_legacy ( )
var lines = < < trim END
vim9script
def Func ( )
var outer = 'foo'
var F = ( ) = > {
outer = 'bar'
}
execute printf ( 'call %s()' , string ( F ) )
enddef
Func ( )
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptFailure ( lines , 'E1248' )
2021-12-02 16:38:52 +00:00
enddef
2020-11-25 19:15:19 +01:00
def Test_failure_in_called_function ( )
# this was using the frame index as the return value
var lines = < < trim END
vim9script
au TerminalWinOpen * eval [][0 ]
def PopupTerm ( a : any )
# make sure typvals on stack are string
['a' , 'b' , 'c' , 'd' , 'e' , 'f' , 'g' ]- > join ( )
FireEvent ( )
enddef
def FireEvent ( )
do TerminalWinOpen
enddef
# use try /catch to make eval fail
try
call PopupTerm ( 0 )
catch
endtry
au ! TerminalWinOpen
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptSuccess ( lines )
2020-11-25 19:15:19 +01:00
enddef
2020-10-01 13:01:34 +02:00
def Test_nested_lambda ( )
var lines = < < trim END
vim9script
def Func ( )
var x = 4
2020-12-31 21:28:47 +01:00
var Lambda1 = ( ) = > 7
var Lambda2 = ( ) = > [Lambda1 ( ) , x ]
2020-10-01 13:01:34 +02:00
var res = Lambda2 ( )
assert_equal ( [7 , 4 ], res )
enddef
Func ( )
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptSuccess ( lines )
2020-10-01 13:01:34 +02:00
enddef
2021-06-09 19:30:03 +02:00
def Test_double_nested_lambda ( )
var lines = < < trim END
vim9script
def F ( head : string ) : func ( string ) : func ( string ) : string
return ( sep : string ) : func ( string ) : string = > ( ( tail : string ) : string = > {
return head .. sep .. tail
})
enddef
assert_equal ( 'hello-there' , F ( 'hello' ) ( '-' ) ( 'there' ) )
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptSuccess ( lines )
2021-06-09 19:30:03 +02:00
enddef
2021-05-18 11:47:44 +02:00
def Test_nested_inline_lambda ( )
var lines = < < trim END
vim9script
def F ( text : string ) : func ( string ) : func ( string ) : string
return ( arg : string ) : func ( string ) : string = > ( ( sep : string ) : string = > {
2021-08-03 21:16:18 +02:00
return sep .. arg .. text
2021-05-18 11:47:44 +02:00
})
enddef
2021-08-03 21:16:18 +02:00
assert_equal ( '--there++' , F ( '++' ) ( 'there' ) ( '--' ) )
2021-05-18 11:47:44 +02:00
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptSuccess ( lines )
2021-07-15 22:03:50 +02:00
lines = < < trim END
vim9script
echo range ( 4 ) - > mapnew ( ( _ , v ) = > {
return range ( v ) - > mapnew ( ( _ , s ) = > {
return string ( s )
})
})
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptSuccess ( lines )
2021-07-18 13:42:29 +02:00
lines = < < trim END
vim9script
2022-02-12 19:52:25 +00:00
def Func ( )
2021-07-18 13:42:29 +02:00
range ( 10 )
- > mapnew ( ( _ , _ ) = > ( {
key : range ( 10 ) - > mapnew ( ( _ , _ ) = > {
return ' '
}) ,
}) )
enddef
defcomp
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptSuccess ( lines )
2021-05-18 11:47:44 +02:00
enddef
2020-11-17 18:50:44 +01:00
def Shadowed ( ) : list < number >
2020-12-31 21:28:47 +01:00
var FuncList : list < func : number > = [( ) = > 42 ]
2021-01-10 22:42:50 +01:00
return FuncList - > mapnew ( ( _ , Shadowed ) = > Shadowed ( ) )
2020-11-17 18:50:44 +01:00
enddef
def Test_lambda_arg_shadows_func ( )
2022-01-29 21:45:34 +00:00
assert_equal ( [42 ], g :Shadowed ( ) )
2020-11-17 18:50:44 +01:00
enddef
2022-01-29 21:45:34 +00:00
def s :Line_continuation_in_def ( dir : string = '' ) : string
2020-09-27 22:47:05 +02:00
var path : string = empty ( dir )
\ ? 'empty'
\ : 'full'
return path
2020-06-22 19:39:03 +02:00
enddef
def Test_line_continuation_in_def ( )
2020-09-11 19:09:48 +02:00
Line_continuation_in_def ( '.' ) - > assert_equal ( 'full' )
2020-06-22 19:39:03 +02:00
enddef
2020-11-19 21:47:56 +01:00
def Test_script_var_in_lambda ( )
var lines = < < trim END
vim9script
var script = 'test'
2021-04-10 20:10:26 +02:00
assert_equal ( ['test' ], map ( ['one' ], ( _ , _ ) = > script ) )
2020-11-19 21:47:56 +01:00
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptSuccess ( lines )
2020-11-19 21:47:56 +01:00
enddef
2022-01-29 21:45:34 +00:00
def s :Line_continuation_in_lambda ( ) : list < string >
2020-09-27 22:47:05 +02:00
var x = range ( 97 , 100 )
2021-01-10 22:42:50 +01:00
- > mapnew ( ( _ , v ) = > nr2char ( v )
2020-12-31 21:28:47 +01:00
- > toupper ( ) )
2020-07-08 17:36:21 +02:00
- > reverse ( )
return x
enddef
def Test_line_continuation_in_lambda ( )
2020-09-11 19:09:48 +02:00
Line_continuation_in_lambda ( ) - > assert_equal ( ['D' , 'C' , 'B' , 'A' ])
2021-01-16 18:09:52 +01:00
var lines = < < trim END
vim9script
var res = [{n : 1 , m : 2 , s : 'xxx' }]
- > mapnew ( ( _ , v : dict < any > ) : string = > printf ( '%d:%d:%s' ,
v .n ,
v .m ,
substitute ( v .s , '.*' , 'yyy' , '' )
) )
assert_equal ( ['1:2:yyy' ], res )
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptSuccess ( lines )
2020-07-08 17:36:21 +02:00
enddef
2021-01-08 22:24:19 +01:00
def Test_list_lambda ( )
timer_start ( 1000 , ( _ ) = > 0 )
var body = execute ( timer_info ( ) [0 ].callback
- > string ( )
- > substitute ( "('" , ' ' , '' )
- > substitute ( "')" , '' , '' )
- > substitute ( 'function\zs' , ' ' , '' ) )
2021-04-09 17:24:52 +02:00
assert_match ( 'def <lambda>\d\+(_: any): number\n1 return 0\n enddef' , body )
2021-01-08 22:24:19 +01:00
enddef
2021-07-25 18:07:00 +02:00
def Test_lambda_block_variable ( )
2021-07-24 14:14:52 +02:00
var lines = < < trim END
vim9script
var flist : list < func >
for i in range ( 10 )
var inloop = i
flist [i ] = ( ) = > inloop
endfor
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptSuccess ( lines )
2021-07-24 14:14:52 +02:00
lines = < < trim END
vim9script
if true
var outloop = 5
var flist : list < func >
for i in range ( 10 )
flist [i ] = ( ) = > outloop
endfor
endif
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptSuccess ( lines )
2021-07-24 14:14:52 +02:00
lines = < < trim END
vim9script
if true
var outloop = 5
endif
var flist : list < func >
for i in range ( 10 )
flist [i ] = ( ) = > outloop
endfor
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptFailure ( lines , 'E1001: Variable not found: outloop' , 1 )
2021-07-25 18:07:00 +02:00
lines = < < trim END
vim9script
for i in range ( 10 )
var Ref = ( ) = > 0
endfor
assert_equal ( 0 , ( ( i ) = > 0 ) ( 0 ) )
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptSuccess ( lines )
2021-07-24 14:14:52 +02:00
enddef
2021-04-24 14:15:41 +02:00
def Test_legacy_lambda ( )
legacy echo {x - > 'hello ' .. x }( 'foo' )
2021-04-25 13:54:42 +02:00
2021-04-24 14:15:41 +02:00
var lines = < < trim END
echo {x - > 'hello ' .. x }( 'foo' )
END
2022-01-29 21:45:34 +00:00
v9 .CheckDefAndScriptFailure ( lines , 'E720:' )
2021-04-25 13:54:42 +02:00
lines = < < trim END
vim9script
def Func ( )
echo ( ( ) = > 'no error' ) ( )
enddef
legacy call s :Func ( )
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptSuccess ( lines )
2021-04-24 14:15:41 +02:00
enddef
2021-06-26 13:00:49 +02:00
def Test_legacy ( )
var lines = < < trim END
vim9script
func g :LegacyFunction ( )
let g :legacyvar = 1
endfunc
def Testit ( )
legacy call g :LegacyFunction ( )
enddef
Testit ( )
assert_equal ( 1 , g :legacyvar )
unlet g :legacyvar
delfunc g :LegacyFunction
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptSuccess ( lines )
2021-06-26 13:00:49 +02:00
enddef
2021-06-02 16:47:53 +02:00
def Test_legacy_errors ( )
for cmd in ['if' , 'elseif' , 'else' , 'endif' ,
'for' , 'endfor' , 'continue' , 'break' ,
'while' , 'endwhile' ,
'try' , 'catch' , 'finally' , 'endtry' ]
2022-01-29 21:45:34 +00:00
v9 .CheckDefFailure ( ['legacy ' .. cmd .. ' expr' ], 'E1189:' )
2021-06-02 16:47:53 +02:00
endfor
enddef
2021-09-13 18:25:54 +02:00
def Test_call_legacy_with_dict ( )
var lines = < < trim END
vim9script
func Legacy ( ) dict
let g :result = self .value
endfunc
def TestDirect ( )
var d = {value : 'yes' , func : Legacy }
d .func ( )
enddef
TestDirect ( )
assert_equal ( 'yes' , g :result )
unlet g :result
def TestIndirect ( )
var d = {value : 'foo' , func : Legacy }
var Fi = d .func
Fi ( )
enddef
TestIndirect ( )
assert_equal ( 'foo' , g :result )
unlet g :result
var d = {value : 'bar' , func : Legacy }
d .func ( )
assert_equal ( 'bar' , g :result )
unlet g :result
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptSuccess ( lines )
2021-09-13 18:25:54 +02:00
enddef
2022-01-29 21:45:34 +00:00
def s :DoFilterThis ( a : string ) : list < string >
2021-01-10 14:02:28 +01:00
# closure nested inside another closure using argument
var Filter = ( l ) = > filter ( l , ( _ , v ) = > stridx ( v , a ) = = 0 )
return ['x' , 'y' , 'a' , 'x2' , 'c' ]- > Filter ( )
enddef
def Test_nested_closure_using_argument ( )
assert_equal ( ['x' , 'x2' ], DoFilterThis ( 'x' ) )
enddef
2021-01-10 18:33:11 +01:00
def Test_triple_nested_closure ( )
var what = 'x'
var Match = ( val : string , cmp : string ) : bool = > stridx ( val , cmp ) = = 0
var Filter = ( l ) = > filter ( l , ( _ , v ) = > Match ( v , what ) )
assert_equal ( ['x' , 'x2' ], ['x' , 'y' , 'a' , 'x2' , 'c' ]- > Filter ( ) )
enddef
2020-07-05 18:48:23 +02:00
func Test_silent_echo ( )
2020-07-05 18:18:42 +02:00
CheckScreendump
2021-12-13 18:19:55 +00:00
call Run_Test_silent_echo ( )
endfunc
2020-07-05 18:18:42 +02:00
2021-12-13 18:19:55 +00:00
def Run_Test_silent_echo ( )
var lines = < < trim END
2020-07-05 18:18:42 +02:00
vim9script
def EchoNothing ( )
silent echo ''
enddef
defcompile
END
2021-12-13 18:19:55 +00:00
writefile ( lines , 'XTest_silent_echo' )
2020-07-05 18:18:42 +02:00
2021-12-13 18:19:55 +00:00
# Check that the balloon shows up after a mouse move
2022-01-29 21:45:34 +00:00
var buf = g :RunVimInTerminal ( '-S XTest_silent_echo' , {'rows' : 6 })
2021-12-13 18:19:55 +00:00
term_sendkeys ( buf , ":abc" )
2022-01-29 21:45:34 +00:00
g :VerifyScreenDump ( buf , 'Test_vim9_silent_echo' , {})
2020-07-05 18:18:42 +02:00
2021-12-13 18:19:55 +00:00
# clean up
2022-01-29 21:45:34 +00:00
g :StopVimInTerminal ( buf )
2021-12-13 18:19:55 +00:00
delete ( 'XTest_silent_echo' )
enddef
2020-07-05 18:18:42 +02:00
2020-10-28 16:54:47 +01:00
def SilentlyError ( )
execute ( 'silent! invalid' )
g :did_it = 'yes'
enddef
2022-01-29 21:45:34 +00:00
func s :UserError ( )
2020-10-28 20:20:00 +01:00
silent ! invalid
endfunc
def SilentlyUserError ( )
UserError ( )
g :did_it = 'yes'
enddef
2020-10-28 16:54:47 +01:00
" This can't be a :def function, because the assert would not be reached.
func Test_ignore_silent_error ( )
let g :did_it = 'no'
call SilentlyError ( )
call assert_equal ( 'yes' , g :did_it )
2020-10-28 20:20:00 +01:00
let g :did_it = 'no'
call SilentlyUserError ( )
call assert_equal ( 'yes' , g :did_it )
2020-10-28 16:54:47 +01:00
unlet g :did_it
endfunc
2020-10-30 21:49:40 +01:00
def Test_ignore_silent_error_in_filter ( )
var lines = < < trim END
vim9script
def Filter ( winid : number , key : string ) : bool
if key = = 'o'
silent ! eval [][0 ]
return true
endif
return popup_filter_menu ( winid , key )
enddef
2020-12-02 17:36:54 +01:00
popup_create ( 'popup' , {filter : Filter })
2020-10-30 21:49:40 +01:00
feedkeys ( "o\r" , 'xnt' )
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptSuccess ( lines )
2020-10-30 21:49:40 +01:00
enddef
2022-01-29 21:45:34 +00:00
def s :Fibonacci ( n : number ) : number
2020-09-05 21:57:53 +02:00
if n < 2
return n
else
return Fibonacci ( n - 1 ) + Fibonacci ( n - 2 )
endif
enddef
2020-07-12 17:31:09 +02:00
def Test_recursive_call ( )
2020-09-11 19:09:48 +02:00
Fibonacci ( 20 ) - > assert_equal ( 6765 )
2020-07-12 17:31:09 +02:00
enddef
2022-01-29 21:45:34 +00:00
def s :TreeWalk ( dir : string ) : list < any >
2021-01-10 22:42:50 +01:00
return readdir ( dir ) - > mapnew ( ( _ , val ) = >
2020-07-13 20:41:08 +02:00
fnamemodify ( dir .. '/' .. val , ':p' ) - > isdirectory ( )
2020-11-19 18:53:18 +01:00
? {[val ]: TreeWalk ( dir .. '/' .. val ) }
2020-07-13 20:41:08 +02:00
: val
2020-12-31 21:28:47 +01:00
)
2020-07-13 20:41:08 +02:00
enddef
def Test_closure_in_map ( )
mkdir ( 'XclosureDir/tdir' , 'p' )
writefile ( ['111' ], 'XclosureDir/file1' )
writefile ( ['222' ], 'XclosureDir/file2' )
writefile ( ['333' ], 'XclosureDir/tdir/file3' )
2020-12-02 17:36:54 +01:00
TreeWalk ( 'XclosureDir' ) - > assert_equal ( ['file1' , 'file2' , {tdir : ['file3' ]}])
2020-07-13 20:41:08 +02:00
delete ( 'XclosureDir' , 'rf' )
enddef
2020-10-04 13:42:34 +02:00
def Test_invalid_function_name ( )
var lines = < < trim END
vim9script
def s : list < string >
END
2022-02-12 19:52:25 +00:00
v9 .CheckScriptFailure ( lines , 'E1268:' )
2020-10-04 13:42:34 +02:00
lines = < < trim END
vim9script
def g : list < string >
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptFailure ( lines , 'E129:' )
2020-10-04 13:42:34 +02:00
lines = < < trim END
vim9script
def < SID > : list < string >
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptFailure ( lines , 'E884:' )
2020-10-04 13:42:34 +02:00
lines = < < trim END
vim9script
def F list < string >
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptFailure ( lines , 'E488:' )
2020-10-04 13:42:34 +02:00
enddef
2020-07-15 22:38:56 +02:00
def Test_partial_call ( )
2021-08-01 15:40:31 +02:00
var lines = < < trim END
var Xsetlist : func
Xsetlist = function ( 'setloclist' , [0 ])
Xsetlist ( [], ' ' , {title : 'test' })
getloclist ( 0 , {title : 1 }) - > assert_equal ( {title : 'test' })
Xsetlist = function ( 'setloclist' , [0 , [], ' ' ])
Xsetlist ( {title : 'test' })
getloclist ( 0 , {title : 1 }) - > assert_equal ( {title : 'test' })
2020-07-15 22:38:56 +02:00
2021-08-01 15:40:31 +02:00
Xsetlist = function ( 'setqflist' )
Xsetlist ( [], ' ' , {title : 'test' })
getqflist ( {title : 1 }) - > assert_equal ( {title : 'test' })
2020-07-15 22:38:56 +02:00
2021-08-01 15:40:31 +02:00
Xsetlist = function ( 'setqflist' , [[], ' ' ])
Xsetlist ( {title : 'test' })
getqflist ( {title : 1 }) - > assert_equal ( {title : 'test' })
2020-07-15 22:38:56 +02:00
2021-08-01 15:40:31 +02:00
var Len : func : number = function ( 'len' , ['word' ])
assert_equal ( 4 , Len ( ) )
2020-10-04 14:17:32 +02:00
2021-08-01 15:40:31 +02:00
var RepeatFunc = function ( 'repeat' , ['o' ])
assert_equal ( 'ooooo' , RepeatFunc ( 5 ) )
END
2022-01-29 21:45:34 +00:00
v9 .CheckDefAndScriptSuccess ( lines )
2021-08-19 21:08:30 +02:00
lines = < < trim END
vim9script
def Foo ( Parser : any )
enddef
var Expr : func ( dict < any > ) : dict < any >
const Call = Foo ( Expr )
END
2022-03-08 13:18:55 +00:00
v9 .CheckScriptFailure ( lines , 'E1031:' )
2020-07-15 22:38:56 +02:00
enddef
2022-02-16 21:48:25 +00:00
def Test_partial_double_nested ( )
var idx = 123
var Get = ( ) = > idx
var Ref = function ( Get , [])
var RefRef = function ( Ref , [])
assert_equal ( 123 , RefRef ( ) )
enddef
2022-03-08 16:52:24 +00:00
def Test_partial_null_function ( )
var lines = < < trim END
var d : dict < func > = {f : null_function }
var Ref = d .f
2022-03-08 19:43:55 +00:00
assert_equal ( 'func(...): unknown' , typename ( Ref ) )
2022-03-08 16:52:24 +00:00
END
v9 .CheckDefAndScriptSuccess ( lines )
enddef
2022-02-06 13:55:03 +00:00
" Using "idx" from a legacy global function does not work.
" This caused a crash when called from legacy context.
func Test_partial_call_fails ( )
let lines = < < trim END
vim9script
var l = ['a' , 'b' , 'c' ]
def Iter ( container : any ) : any
var idx = -1
var obj = {state : container }
2022-02-07 20:30:57 +00:00
def g :NextItem__ ( self : dict < any > ) : any
2022-02-06 13:55:03 +00:00
+ + idx
return self .state [idx ]
enddef
2022-02-07 20:30:57 +00:00
obj .__next__ = function ( 'g:NextItem__' , [obj ])
2022-02-06 13:55:03 +00:00
return obj
enddef
var it = Iter ( l )
echo it .__next__ ( )
END
call writefile ( lines , 'XpartialCall' )
try
source XpartialCall
catch /E1248:/
endtry
call delete ( 'XpartialCall' )
endfunc
2020-08-08 15:10:27 +02:00
def Test_cmd_modifier ( )
tab echo '0'
2022-01-29 21:45:34 +00:00
v9 .CheckDefFailure ( ['5tab echo 3' ], 'E16:' )
2020-08-08 15:10:27 +02:00
enddef
def Test_restore_modifiers ( )
# check that when compiling a :def function command modifiers are not messed
# up .
2020-09-27 22:47:05 +02:00
var lines = < < trim END
2020-08-08 15:10:27 +02:00
vim9script
set eventignore =
autocmd QuickFixCmdPost * copen
def AutocmdsDisabled ( )
2021-07-10 19:42:03 +02:00
eval 1 + 2
2020-08-08 15:10:27 +02:00
enddef
func Func ( )
noautocmd call s :AutocmdsDisabled ( )
let g :ei_after = &eventignore
endfunc
Func ( )
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptSuccess ( lines )
2020-09-11 19:09:48 +02:00
g :ei_after - > assert_equal ( '' )
2020-08-08 15:10:27 +02:00
enddef
2020-09-10 22:05:08 +02:00
def StackTop ( )
2021-07-10 19:42:03 +02:00
eval 1 + 2
eval 2 + 3
2020-09-10 22:05:08 +02:00
# call not on fourth line
2022-01-29 21:45:34 +00:00
g :StackBot ( )
2020-09-10 22:05:08 +02:00
enddef
def StackBot ( )
# throw an error
eval [][0 ]
enddef
def Test_callstack_def ( )
try
2022-01-29 21:45:34 +00:00
g :StackTop ( )
2020-09-10 22:05:08 +02:00
catch
2020-09-11 19:09:48 +02:00
v :throwpoint - > assert_match ( 'Test_callstack_def\[2\]..StackTop\[4\]..StackBot, line 2' )
2020-09-10 22:05:08 +02:00
endtry
enddef
2020-10-09 22:04:29 +02:00
" Re-using spot for variable used in block
def Test_block_scoped_var ( )
var lines = < < trim END
vim9script
def Func ( )
var x = ['a' , 'b' , 'c' ]
if 1
var y = 'x'
2021-04-10 20:10:26 +02:00
map ( x , ( _ , _ ) = > y )
2020-10-09 22:04:29 +02:00
endif
var z = x
assert_equal ( ['x' , 'x' , 'x' ], z )
enddef
Func ( )
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptSuccess ( lines )
2020-10-09 22:04:29 +02:00
enddef
2020-11-20 19:26:48 +01:00
def Test_reset_did_emsg ( )
var lines = < < trim END
@s = 'blah'
au BufWinLeave * #
def Func ( )
var winid = popup_create ( 'popup' , {})
exe '*s'
popup_close ( winid )
enddef
Func ( )
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptFailure ( lines , 'E492:' , 8 )
2020-12-05 13:41:01 +01:00
delfunc ! g :Func
2020-11-20 19:26:48 +01:00
enddef
2020-12-12 20:42:19 +01:00
def Test_did_emsg_reset ( )
# executing an autocommand resets did_emsg , this should not result in a
# builtin function considered failing
var lines = < < trim END
vim9script
au BufWinLeave * #
def Func ( )
2021-04-09 17:24:52 +02:00
popup_menu ( '' , {callback : ( a , b ) = > popup_create ( '' , {}) - > popup_close ( ) })
2020-12-12 20:42:19 +01:00
eval [][0 ]
enddef
nno < F3 > < cmd > call < sid > Func ( ) < cr >
feedkeys ( "\<F3>\e" , 'xt' )
END
writefile ( lines , 'XemsgReset' )
assert_fails ( 'so XemsgReset' , ['E684:' , 'E684:' ], lines , 2 )
delete ( 'XemsgReset' )
nunmap < F3 >
au ! BufWinLeave
enddef
2020-12-05 21:22:08 +01:00
def Test_abort_with_silent_call ( )
var lines = < < trim END
vim9script
g :result = 'none'
def Func ( )
g :result + = 3
g :result = 'yes'
enddef
# error is silenced , but function aborts on error
silent ! Func ( )
assert_equal ( 'none' , g :result )
unlet g :result
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptSuccess ( lines )
2020-12-05 21:22:08 +01:00
enddef
2020-12-05 19:17:16 +01:00
def Test_continues_with_silent_error ( )
var lines = < < trim END
vim9script
g :result = 'none'
def Func ( )
silent ! g :result + = 3
g :result = 'yes'
enddef
# error is silenced , function does not abort
Func ( )
assert_equal ( 'yes' , g :result )
unlet g :result
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptSuccess ( lines )
2020-12-05 19:17:16 +01:00
enddef
2020-12-02 20:51:22 +01:00
def Test_abort_even_with_silent ( )
var lines = < < trim END
vim9script
g :result = 'none'
def Func ( )
eval {- > '' }( ) .. '' .. {}['X' ]
g :result = 'yes'
enddef
2020-12-05 19:17:16 +01:00
silent ! Func ( )
2020-12-02 20:51:22 +01:00
assert_equal ( 'none' , g :result )
2020-12-05 18:13:27 +01:00
unlet g :result
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptSuccess ( lines )
2020-12-05 18:13:27 +01:00
enddef
2020-12-05 19:17:16 +01:00
def Test_cmdmod_silent_restored ( )
var lines = < < trim END
vim9script
def Func ( )
g :result = 'none'
silent ! g :result + = 3
g :result = 'none'
g :result + = 3
enddef
Func ( )
END
# can 't use CheckScriptFailure , it ignores the :silent !
var fname = 'Xdefsilent'
writefile ( lines , fname )
var caught = 'no'
try
exe 'source ' .. fname
catch /E1030:/
caught = 'yes'
assert_match ( 'Func, line 4' , v :throwpoint )
endtry
assert_equal ( 'yes' , caught )
delete ( fname )
enddef
2021-03-24 22:00:56 +01:00
def Test_cmdmod_silent_nested ( )
var lines = < < trim END
vim9script
var result = ''
def Error ( )
result ..= 'Eb'
eval [][0 ]
result ..= 'Ea'
enddef
def Crash ( )
result ..= 'Cb'
sil ! Error ( )
result ..= 'Ca'
enddef
Crash ( )
assert_equal ( 'CbEbEaCa' , result )
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptSuccess ( lines )
2021-03-24 22:00:56 +01:00
enddef
2020-12-05 18:13:27 +01:00
def Test_dict_member_with_silent ( )
var lines = < < trim END
vim9script
g :result = 'none'
var d : dict < any >
def Func ( )
try
2020-12-31 21:28:47 +01:00
g :result = map ( [], ( _ , v ) = > ( {}[v ]) ) - > join ( ) .. d ['' ]
2020-12-05 18:13:27 +01:00
catch
endtry
enddef
silent ! Func ( )
assert_equal ( '0' , g :result )
unlet g :result
2020-12-02 20:51:22 +01:00
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptSuccess ( lines )
2020-12-02 20:51:22 +01:00
enddef
2021-01-21 19:41:16 +01:00
def Test_skip_cmds_with_silent ( )
var lines = < < trim END
vim9script
def Func ( b : bool )
Crash ( )
enddef
def Crash ( )
sil ! :/not found/ d _
sil ! :/not found/ put _
enddef
Func ( true )
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptSuccess ( lines )
2021-01-21 19:41:16 +01:00
enddef
2020-12-22 12:20:08 +01:00
def Test_opfunc ( )
2022-01-30 15:28:30 +00:00
nnoremap < F3 > < cmd > set opfunc = g :Opfunc < cr > g @
2020-12-22 12:20:08 +01:00
def g :Opfunc ( _ : any ) : string
setline ( 1 , 'ASDF' )
return ''
enddef
new
setline ( 1 , 'asdf' )
feedkeys ( "\<F3>$" , 'x' )
assert_equal ( 'ASDF' , getline ( 1 ) )
bwipe !
nunmap < F3 >
enddef
2021-12-13 18:19:55 +00:00
func Test_opfunc_error ( )
CheckScreendump
call Run_Test_opfunc_error ( )
endfunc
def Run_Test_opfunc_error ( )
# test that the error from Opfunc ( ) is displayed right away
var lines = < < trim END
vim9script
def Opfunc ( type : string )
try
eval [][0 ]
catch /nothing/ # error not caught
endtry
enddef
&operatorfunc = Opfunc
nnoremap < expr > l < SID > L ( )
def L ( ) : string
return 'l'
enddef
'x' - > repeat ( 10 ) - > setline ( 1 )
feedkeys ( 'g@l' , 'n' )
feedkeys ( 'llll' )
END
call writefile ( lines , 'XTest_opfunc_error' )
2022-01-29 21:45:34 +00:00
var buf = g :RunVimInTerminal ( '-S XTest_opfunc_error' , {rows : 6 , wait_for_ruler : 0 })
g :WaitForAssert ( ( ) = > assert_match ( 'Press ENTER' , term_getline ( buf , 6 ) ) )
g :WaitForAssert ( ( ) = > assert_match ( 'E684: list index out of range: 0' , term_getline ( buf , 5 ) ) )
2021-12-13 18:19:55 +00:00
# clean up
2022-01-29 21:45:34 +00:00
g :StopVimInTerminal ( buf )
2021-12-13 18:19:55 +00:00
delete ( 'XTest_opfunc_error' )
enddef
2020-12-22 18:33:27 +01:00
" this was crashing on exit
def Test_nested_lambda_in_closure ( )
var lines = < < trim END
vim9script
2021-04-28 20:40:44 +02:00
command WriteDone writefile ( ['Done' ], 'XnestedDone' )
2020-12-22 18:33:27 +01:00
def Outer ( )
def g :Inner ( )
echo map ( [1 , 2 , 3 ], {_ , v - > v + 1 })
enddef
g :Inner ( )
enddef
defcompile
2021-04-28 20:40:44 +02:00
# not reached
2020-12-22 18:33:27 +01:00
END
2022-01-29 21:45:34 +00:00
if ! g :RunVim ( [], lines , '--clean -c WriteDone -c quit' )
2020-12-22 18:33:27 +01:00
return
endif
assert_equal ( ['Done' ], readfile ( 'XnestedDone' ) )
delete ( 'XnestedDone' )
enddef
2022-02-07 17:50:39 +00:00
def Test_nested_closure_funcref ( )
var lines = < < trim END
vim9script
def Func ( )
var n : number
def Nested ( )
+ + n
enddef
Nested ( )
g :result_one = n
var Ref = function ( Nested )
Ref ( )
g :result_two = n
enddef
Func ( )
END
v9 .CheckScriptSuccess ( lines )
assert_equal ( 1 , g :result_one )
assert_equal ( 2 , g :result_two )
unlet g :result_one g :result_two
enddef
2022-02-07 19:56:43 +00:00
def Test_nested_closure_in_dict ( )
var lines = < < trim END
vim9script
def Func ( ) : dict < any >
var n : number
def Inc ( ) : number
+ + n
return n
enddef
return {inc : function ( Inc ) }
enddef
disas Func
var d = Func ( )
assert_equal ( 1 , d .inc ( ) )
assert_equal ( 2 , d .inc ( ) )
END
v9 .CheckScriptSuccess ( lines )
enddef
2021-03-06 19:26:46 +01:00
def Test_check_func_arg_types ( )
var lines = < < trim END
vim9script
def F1 ( x : string ) : string
return x
enddef
def F2 ( x : number ) : number
return x + 1
enddef
def G ( g : func ) : dict < func >
return {f : g }
enddef
def H ( d : dict < func > ) : string
return d .f ( 'a' )
enddef
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptSuccess ( lines + ['echo H(G(F1))' ])
v9 .CheckScriptFailure ( lines + ['echo H(G(F2))' ], 'E1013:' )
2021-03-06 19:26:46 +01:00
enddef
2021-08-10 22:52:02 +02:00
def Test_list_any_type_checked ( )
var lines = < < trim END
vim9script
def Foo ( )
- - decl - -
Bar ( l )
enddef
def Bar ( ll : list < dict < any > > )
enddef
Foo ( )
END
2022-02-03 12:34:05 +00:00
# "any" could be "dict<any>" , thus OK
2021-08-10 22:52:02 +02:00
lines [2 ] = 'var l: list<any>'
2022-02-03 12:34:05 +00:00
v9 .CheckScriptSuccess ( lines )
2021-08-10 22:52:02 +02:00
lines [2 ] = 'var l: list<any> = []'
2022-02-03 12:34:05 +00:00
v9 .CheckScriptSuccess ( lines )
2021-08-10 22:52:02 +02:00
lines [2 ] = 'var l: list<any> = [11]'
2022-01-29 21:45:34 +00:00
v9 .CheckScriptFailure ( lines , 'E1013: Argument 1: type mismatch, expected list<dict<any>> but got list<number>' , 2 )
2021-08-10 22:52:02 +02:00
enddef
2021-04-10 13:33:48 +02:00
def Test_compile_error ( )
var lines = < < trim END
def g :Broken ( )
echo 'a' + {}
enddef
call g :Broken ( )
END
# First call : compilation error
2022-01-29 21:45:34 +00:00
v9 .CheckScriptFailure ( lines , 'E1051: Wrong argument type for +' )
2021-04-10 13:33:48 +02:00
# Second call won 't try compiling again
assert_fails ( 'call g:Broken()' , 'E1091: Function is not compiled: Broken' )
2021-04-10 14:03:43 +02:00
delfunc g :Broken
# No error when compiling with :silent !
lines = < < trim END
def g :Broken ( )
echo 'a' + []
enddef
silent ! defcompile
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptSuccess ( lines )
2021-04-10 14:03:43 +02:00
# Calling the function won 't try compiling again
assert_fails ( 'call g:Broken()' , 'E1091: Function is not compiled: Broken' )
delfunc g :Broken
2021-04-10 13:33:48 +02:00
enddef
2021-04-10 17:18:09 +02:00
def Test_ignored_argument ( )
var lines = < < trim END
vim9script
def Ignore ( _ , _ ) : string
return 'yes'
enddef
assert_equal ( 'yes' , Ignore ( 1 , 2 ) )
func Ok ( _ )
return a :_
endfunc
assert_equal ( 'ok' , Ok ( 'ok' ) )
func Oktoo ( )
let _ = 'too'
return _
endfunc
assert_equal ( 'too' , Oktoo ( ) )
2021-04-10 21:01:38 +02:00
assert_equal ( [[1 ], [2 ], [3 ]], range ( 3 ) - > mapnew ( ( _ , v ) = > [v ]- > map ( ( _ , w ) = > w + 1 ) ) )
2021-04-10 17:18:09 +02:00
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptSuccess ( lines )
2021-04-10 17:18:09 +02:00
lines = < < trim END
def Ignore ( _ : string ) : string
return _
enddef
defcompile
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptFailure ( lines , 'E1181:' , 1 )
2021-04-10 17:18:09 +02:00
lines = < < trim END
var _ = 1
END
2022-01-29 21:45:34 +00:00
v9 .CheckDefAndScriptFailure ( lines , 'E1181:' , 1 )
2021-05-25 20:14:00 +02:00
lines = < < trim END
var x = _
END
2022-01-29 21:45:34 +00:00
v9 .CheckDefAndScriptFailure ( lines , 'E1181:' , 1 )
2021-04-10 17:18:09 +02:00
enddef
2021-04-10 20:10:26 +02:00
def Test_too_many_arguments ( )
var lines = < < trim END
echo [0 , 1 , 2 ]- > map ( ( ) = > 123 )
END
2022-02-20 15:52:28 +00:00
v9 .CheckDefAndScriptFailure ( lines , ['E176:' , 'E1106: 2 arguments too many' ], 1 )
2021-04-10 20:10:26 +02:00
lines = < < trim END
echo [0 , 1 , 2 ]- > map ( ( _ ) = > 123 )
END
2022-02-20 15:52:28 +00:00
v9 .CheckDefAndScriptFailure ( lines , ['E176' , 'E1106: One argument too many' ], 1 )
2021-04-10 20:10:26 +02:00
enddef
2020-12-22 18:33:27 +01:00
2021-04-23 19:32:23 +02:00
def Test_closing_brace_at_start_of_line ( )
var lines = < < trim END
def Func ( )
enddef
Func (
)
END
2022-01-29 21:45:34 +00:00
v9 .CheckDefAndScriptSuccess ( lines )
2021-04-23 19:32:23 +02:00
enddef
2022-01-29 21:45:34 +00:00
func s :CreateMydict ( )
2021-08-15 16:08:36 +02:00
let g :mydict = {}
func g :mydict .afunc ( )
let g :result = self .key
endfunc
endfunc
def Test_numbered_function_reference ( )
CreateMydict ( )
var output = execute ( 'legacy func g:mydict.afunc' )
var funcName = 'g:' .. substitute ( output , '.*function \(\d\+\).*' , '\1' , '' )
execute 'function(' .. funcName .. ', [], {key: 42})()'
# check that the function still exists
assert_equal ( output , execute ( 'legacy func g:mydict.afunc' ) )
unlet g :mydict
enddef
2022-01-05 16:50:40 +00:00
def Test_go_beyond_end_of_cmd ( )
# this was reading the byte after the end of the line
var lines = < < trim END
def F ( )
cal
enddef
defcompile
END
2022-01-29 21:45:34 +00:00
v9 .CheckScriptFailure ( lines , 'E476:' )
2022-01-05 16:50:40 +00:00
enddef
2022-02-15 21:17:56 +00:00
" The following messes up syntax highlight, keep near the end.
2021-06-06 17:02:53 +02:00
if has ( 'python3' )
2022-02-15 21:17:56 +00:00
def Test_python3_command ( )
py3 import vim
2022-02-15 21:33:29 +00:00
py3 vim .command ( "g:done = 'yes'" )
2022-02-15 21:17:56 +00:00
assert_equal ( 'yes' , g :done )
unlet g :done
enddef
2021-06-06 17:02:53 +02:00
def Test_python3_heredoc ( )
py3 < < trim EOF
import vim
vim .vars ['didit' ] = 'yes'
EOF
assert_equal ( 'yes' , g :didit )
python3 < < trim EOF
import vim
vim .vars ['didit' ] = 'again'
EOF
assert_equal ( 'again' , g :didit )
enddef
endif
if has ( 'lua' )
def Test_lua_heredoc ( )
g :d = {}
lua < < trim EOF
x = vim .eval ( 'g:d' )
x ['key' ] = 'val'
EOF
assert_equal ( 'val' , g :d .key )
enddef
endif
2020-05-03 15:38:16 +02:00
2020-04-05 17:08:17 +02:00
" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker