Vim/src/testdir/test_vim9_script.vim

360 lines
8.5 KiB
VimL

" Test various aspects of the Vim9 script language.
" Check that "lines" inside ":def" results in an "error" message.
func CheckDefFailure(lines, error)
call writefile(['def! Func()'] + a:lines + ['enddef'], 'Xdef')
call assert_fails('so Xdef', a:error, a:lines)
call delete('Xdef')
endfunc
func CheckScriptFailure(lines, error)
call writefile(a:lines, 'Xdef')
call assert_fails('so Xdef', a:error, a:lines)
call delete('Xdef')
endfunc
def Test_syntax()
let var = 234
let other: list<string> = ['asdf']
enddef
func Test_def_basic()
def SomeFunc(): string
return 'yes'
enddef
call assert_equal('yes', SomeFunc())
endfunc
def Test_assignment()
let bool1: bool = true
assert_equal(v:true, bool1)
let bool2: bool = false
assert_equal(v:false, bool2)
let list1: list<string> = ['sdf', 'asdf']
let list2: list<number> = [1, 2, 3]
" TODO: does not work yet
" let listS: list<string> = []
" let listN: list<number> = []
let dict1: dict<string> = #{key: 'value'}
let dict2: dict<number> = #{one: 1, two: 2}
enddef
func Test_assignment_failure()
call CheckDefFailure(['let var=234'], 'E1004:')
call CheckDefFailure(['let var =234'], 'E1004:')
call CheckDefFailure(['let var= 234'], 'E1004:')
call CheckDefFailure(['let true = 1'], 'E1034:')
call CheckDefFailure(['let false = 1'], 'E1034:')
call CheckDefFailure(['let var: list<string> = [123]'], 'expected list<string> but got list<number>')
call CheckDefFailure(['let var: list<number> = ["xx"]'], 'expected list<number> but got list<string>')
call CheckDefFailure(['let var: dict<string> = #{key: 123}'], 'expected dict<string> but got dict<number>')
call CheckDefFailure(['let var: dict<number> = #{key: "xx"}'], 'expected dict<number> but got dict<string>')
call CheckDefFailure(['let var = feedkeys("0")'], 'E1031:')
call CheckDefFailure(['let var: number = feedkeys("0")'], 'expected number but got void')
endfunc
func Test_const()
call CheckDefFailure(['const var = 234', 'var = 99'], 'E1018:')
call CheckDefFailure(['const one = 234', 'let one = 99'], 'E1017:')
call CheckDefFailure(['const two'], 'E1021:')
endfunc
def Test_block()
let outer = 1
{
let inner = 2
assert_equal(1, outer)
assert_equal(2, inner)
}
assert_equal(1, outer)
enddef
func Test_block_failure()
call CheckDefFailure(['{', 'let inner = 1', '}', 'echo inner'], 'E1001:')
endfunc
def ReturnString(): string
return 'string'
enddef
def ReturnNumber(): number
return 123
enddef
def Test_return_string()
assert_equal('string', ReturnString())
assert_equal(123, ReturnNumber())
enddef
func Increment()
let g:counter += 1
endfunc
def Test_call_ufunc_count()
g:counter = 1
Increment()
Increment()
Increment()
" works with and without :call
assert_equal(4, g:counter)
call assert_equal(4, g:counter)
unlet g:counter
enddef
def MyVarargs(arg: string, ...rest: list<string>): string
let res = arg
for s in rest
res ..= ',' .. s
endfor
return res
enddef
def Test_call_varargs()
assert_equal('one', MyVarargs('one'))
assert_equal('one,two', MyVarargs('one', 'two'))
assert_equal('one,two,three', MyVarargs('one', 'two', 'three'))
enddef
def Test_return_type_wrong()
" TODO: why is ! needed for Mac and FreeBSD?
CheckScriptFailure(['def! Func(): number', 'return "a"', 'enddef'], 'expected number but got string')
CheckScriptFailure(['def! Func(): string', 'return 1', 'enddef'], 'expected string but got number')
CheckScriptFailure(['def! Func(): void', 'return "a"', 'enddef'], 'expected void but got string')
CheckScriptFailure(['def! Func()', 'return "a"', 'enddef'], 'expected void but got string')
enddef
def Test_try_catch()
let l = []
try
add(l, '1')
throw 'wrong'
add(l, '2')
catch
add(l, v:exception)
finally
add(l, '3')
endtry
assert_equal(['1', 'wrong', '3'], l)
enddef
let s:export_script_lines =<< trim END
vim9script
let name: string = 'bob'
def Concat(arg: string): string
return name .. arg
enddef
let g:result = Concat('bie')
let g:localname = name
export const CONST = 1234
export let exported = 9876
export def Exported(): string
return 'Exported'
enddef
END
def Test_vim9script()
let import_script_lines =<< trim END
vim9script
import {exported, Exported} from './Xexport.vim'
g:imported = exported
g:imported_func = Exported()
END
writefile(import_script_lines, 'Ximport.vim')
writefile(s:export_script_lines, 'Xexport.vim')
source Ximport.vim
assert_equal('bobbie', g:result)
assert_equal('bob', g:localname)
assert_equal(9876, g:imported)
assert_equal('Exported', g:imported_func)
assert_false(exists('g:name'))
unlet g:result
unlet g:localname
unlet g:imported
unlet g:imported_func
delete('Ximport.vim')
delete('Xexport.vim')
CheckScriptFailure(['scriptversion 2', 'vim9script'], 'E1039:')
CheckScriptFailure(['vim9script', 'scriptversion 2'], 'E1040:')
enddef
def Test_vim9script_call()
let lines =<< trim END
vim9script
let var = ''
def MyFunc(arg: string)
var = arg
enddef
MyFunc('foobar')
assert_equal('foobar', var)
let str = 'barfoo'
str->MyFunc()
assert_equal('barfoo', var)
let g:value = 'value'
g:value->MyFunc()
assert_equal('value', var)
let listvar = []
def ListFunc(arg: list<number>)
listvar = arg
enddef
[1, 2, 3]->ListFunc()
assert_equal([1, 2, 3], listvar)
let dictvar = {}
def DictFunc(arg: dict<number>)
dictvar = arg
enddef
{'a': 1, 'b': 2}->DictFunc()
assert_equal(#{a: 1, b: 2}, dictvar)
#{a: 3, b: 4}->DictFunc()
assert_equal(#{a: 3, b: 4}, dictvar)
END
writefile(lines, 'Xcall.vim')
source Xcall.vim
delete('Xcall.vim')
enddef
def Test_vim9script_call_fail_decl()
let lines =<< trim END
vim9script
let var = ''
def MyFunc(arg: string)
let var = 123
enddef
END
writefile(lines, 'Xcall_decl.vim')
assert_fails('source Xcall_decl.vim', 'E1054:')
delete('Xcall_decl.vim')
enddef
def Test_vim9script_call_fail_const()
let lines =<< trim END
vim9script
const var = ''
def MyFunc(arg: string)
var = 'asdf'
enddef
END
writefile(lines, 'Xcall_const.vim')
assert_fails('source Xcall_const.vim', 'E46:')
delete('Xcall_const.vim')
enddef
def Test_vim9script_reload()
let lines =<< trim END
vim9script
const var = ''
let valone = 1234
def MyFunc(arg: string)
valone = 5678
enddef
END
let morelines =<< trim END
let valtwo = 222
export def GetValtwo(): number
return valtwo
enddef
END
writefile(lines + morelines, 'Xreload.vim')
source Xreload.vim
source Xreload.vim
source Xreload.vim
let testlines =<< trim END
vim9script
def TheFunc()
import GetValtwo from './Xreload.vim'
assert_equal(222, GetValtwo())
enddef
TheFunc()
END
writefile(testlines, 'Ximport.vim')
source Ximport.vim
" test that when not using "morelines" valtwo is still defined
" need to source Xreload.vim again, import doesn't reload a script
writefile(lines, 'Xreload.vim')
source Xreload.vim
source Ximport.vim
" cannot declare a var twice
lines =<< trim END
vim9script
let valone = 1234
let valone = 5678
END
writefile(lines, 'Xreload.vim')
assert_fails('source Xreload.vim', 'E1041:')
delete('Xreload.vim')
delete('Ximport.vim')
enddef
def Test_import_absolute()
let import_lines = [
\ 'vim9script',
\ 'import exported from "' .. escape(getcwd(), '\') .. '/Xexport_abs.vim"',
\ 'g:imported_abs = exported',
\ ]
writefile(import_lines, 'Ximport_abs.vim')
writefile(s:export_script_lines, 'Xexport_abs.vim')
source Ximport_abs.vim
assert_equal(9876, g:imported_abs)
unlet g:imported_abs
delete('Ximport_abs.vim')
delete('Xexport_abs.vim')
enddef
def Test_import_rtp()
let import_lines = [
\ 'vim9script',
\ 'import exported from "Xexport_rtp.vim"',
\ 'g:imported_rtp = exported',
\ ]
writefile(import_lines, 'Ximport_rtp.vim')
mkdir('import')
writefile(s:export_script_lines, 'import/Xexport_rtp.vim')
let save_rtp = &rtp
&rtp = getcwd()
source Ximport_rtp.vim
&rtp = save_rtp
assert_equal(9876, g:imported_rtp)
unlet g:imported_rtp
delete('Ximport_rtp.vim')
delete('import/Xexport_rtp.vim')
delete('import', 'd')
enddef
def Test_fixed_size_list()
" will be allocated as one piece of memory, check that changes work
let l = [1, 2, 3, 4]
l->remove(0)
l->add(5)
l->insert(99, 1)
call assert_equal([2, 99, 3, 4, 5], l)
enddef
" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker