1*8a7d6542SBram Moolenaar" Test various aspects of the Vim9 script language. 2*8a7d6542SBram Moolenaar 3*8a7d6542SBram Moolenaar" Check that "lines" inside ":def" results in an "error" message. 4*8a7d6542SBram Moolenaarfunc CheckDefFailure(lines, error) 5*8a7d6542SBram Moolenaar call writefile(['def! Func()'] + a:lines + ['enddef'], 'Xdef') 6*8a7d6542SBram Moolenaar call assert_fails('so Xdef', a:error, a:lines) 7*8a7d6542SBram Moolenaar call delete('Xdef') 8*8a7d6542SBram Moolenaarendfunc 9*8a7d6542SBram Moolenaar 10*8a7d6542SBram Moolenaarfunc CheckScriptFailure(lines, error) 11*8a7d6542SBram Moolenaar call writefile(a:lines, 'Xdef') 12*8a7d6542SBram Moolenaar call assert_fails('so Xdef', a:error, a:lines) 13*8a7d6542SBram Moolenaar call delete('Xdef') 14*8a7d6542SBram Moolenaarendfunc 15*8a7d6542SBram Moolenaar 16*8a7d6542SBram Moolenaardef Test_syntax() 17*8a7d6542SBram Moolenaar let var = 234 18*8a7d6542SBram Moolenaar let other: list<string> = ['asdf'] 19*8a7d6542SBram Moolenaarenddef 20*8a7d6542SBram Moolenaar 21*8a7d6542SBram Moolenaarfunc Test_def_basic() 22*8a7d6542SBram Moolenaar def SomeFunc(): string 23*8a7d6542SBram Moolenaar return 'yes' 24*8a7d6542SBram Moolenaar enddef 25*8a7d6542SBram Moolenaar call assert_equal('yes', SomeFunc()) 26*8a7d6542SBram Moolenaarendfunc 27*8a7d6542SBram Moolenaar 28*8a7d6542SBram Moolenaardef Test_assignment() 29*8a7d6542SBram Moolenaar let bool1: bool = true 30*8a7d6542SBram Moolenaar assert_equal(v:true, bool1) 31*8a7d6542SBram Moolenaar let bool2: bool = false 32*8a7d6542SBram Moolenaar assert_equal(v:false, bool2) 33*8a7d6542SBram Moolenaar 34*8a7d6542SBram Moolenaar let list1: list<string> = ['sdf', 'asdf'] 35*8a7d6542SBram Moolenaar let list2: list<number> = [1, 2, 3] 36*8a7d6542SBram Moolenaar 37*8a7d6542SBram Moolenaar " TODO: does not work yet 38*8a7d6542SBram Moolenaar " let listS: list<string> = [] 39*8a7d6542SBram Moolenaar " let listN: list<number> = [] 40*8a7d6542SBram Moolenaar 41*8a7d6542SBram Moolenaar let dict1: dict<string> = #{key: 'value'} 42*8a7d6542SBram Moolenaar let dict2: dict<number> = #{one: 1, two: 2} 43*8a7d6542SBram Moolenaarenddef 44*8a7d6542SBram Moolenaar 45*8a7d6542SBram Moolenaarfunc Test_assignment_failure() 46*8a7d6542SBram Moolenaar call CheckDefFailure(['let var=234'], 'E1004:') 47*8a7d6542SBram Moolenaar call CheckDefFailure(['let var =234'], 'E1004:') 48*8a7d6542SBram Moolenaar call CheckDefFailure(['let var= 234'], 'E1004:') 49*8a7d6542SBram Moolenaar 50*8a7d6542SBram Moolenaar call CheckDefFailure(['let true = 1'], 'E1034:') 51*8a7d6542SBram Moolenaar call CheckDefFailure(['let false = 1'], 'E1034:') 52*8a7d6542SBram Moolenaar 53*8a7d6542SBram Moolenaar call CheckDefFailure(['let var: list<string> = [123]'], 'expected list<string> but got list<number>') 54*8a7d6542SBram Moolenaar call CheckDefFailure(['let var: list<number> = ["xx"]'], 'expected list<number> but got list<string>') 55*8a7d6542SBram Moolenaar 56*8a7d6542SBram Moolenaar call CheckDefFailure(['let var: dict<string> = #{key: 123}'], 'expected dict<string> but got dict<number>') 57*8a7d6542SBram Moolenaar call CheckDefFailure(['let var: dict<number> = #{key: "xx"}'], 'expected dict<number> but got dict<string>') 58*8a7d6542SBram Moolenaar 59*8a7d6542SBram Moolenaar call CheckDefFailure(['let var = feedkeys("0")'], 'E1031:') 60*8a7d6542SBram Moolenaar call CheckDefFailure(['let var: number = feedkeys("0")'], 'expected number but got void') 61*8a7d6542SBram Moolenaarendfunc 62*8a7d6542SBram Moolenaar 63*8a7d6542SBram Moolenaarfunc Test_const() 64*8a7d6542SBram Moolenaar call CheckDefFailure(['const var = 234', 'var = 99'], 'E1018:') 65*8a7d6542SBram Moolenaar call CheckDefFailure(['const one = 234', 'let one = 99'], 'E1017:') 66*8a7d6542SBram Moolenaar call CheckDefFailure(['const two'], 'E1021:') 67*8a7d6542SBram Moolenaarendfunc 68*8a7d6542SBram Moolenaar 69*8a7d6542SBram Moolenaardef Test_block() 70*8a7d6542SBram Moolenaar let outer = 1 71*8a7d6542SBram Moolenaar { 72*8a7d6542SBram Moolenaar let inner = 2 73*8a7d6542SBram Moolenaar assert_equal(1, outer) 74*8a7d6542SBram Moolenaar assert_equal(2, inner) 75*8a7d6542SBram Moolenaar } 76*8a7d6542SBram Moolenaar assert_equal(1, outer) 77*8a7d6542SBram Moolenaarenddef 78*8a7d6542SBram Moolenaar 79*8a7d6542SBram Moolenaarfunc Test_block_failure() 80*8a7d6542SBram Moolenaar call CheckDefFailure(['{', 'let inner = 1', '}', 'echo inner'], 'E1001:') 81*8a7d6542SBram Moolenaarendfunc 82*8a7d6542SBram Moolenaar 83*8a7d6542SBram Moolenaardef ReturnString(): string 84*8a7d6542SBram Moolenaar return 'string' 85*8a7d6542SBram Moolenaarenddef 86*8a7d6542SBram Moolenaar 87*8a7d6542SBram Moolenaardef ReturnNumber(): number 88*8a7d6542SBram Moolenaar return 123 89*8a7d6542SBram Moolenaarenddef 90*8a7d6542SBram Moolenaar 91*8a7d6542SBram Moolenaardef Test_return_string() 92*8a7d6542SBram Moolenaar assert_equal('string', ReturnString()) 93*8a7d6542SBram Moolenaar assert_equal(123, ReturnNumber()) 94*8a7d6542SBram Moolenaarenddef 95*8a7d6542SBram Moolenaar 96*8a7d6542SBram Moolenaarfunc Increment() 97*8a7d6542SBram Moolenaar let g:counter += 1 98*8a7d6542SBram Moolenaarendfunc 99*8a7d6542SBram Moolenaar 100*8a7d6542SBram Moolenaardef Test_call_ufunc_count() 101*8a7d6542SBram Moolenaar g:counter = 1 102*8a7d6542SBram Moolenaar Increment() 103*8a7d6542SBram Moolenaar Increment() 104*8a7d6542SBram Moolenaar Increment() 105*8a7d6542SBram Moolenaar " works with and without :call 106*8a7d6542SBram Moolenaar assert_equal(4, g:counter) 107*8a7d6542SBram Moolenaar call assert_equal(4, g:counter) 108*8a7d6542SBram Moolenaar unlet g:counter 109*8a7d6542SBram Moolenaarenddef 110*8a7d6542SBram Moolenaar 111*8a7d6542SBram Moolenaardef MyVarargs(arg: string, ...rest: list<string>): string 112*8a7d6542SBram Moolenaar let res = arg 113*8a7d6542SBram Moolenaar for s in rest 114*8a7d6542SBram Moolenaar res ..= ',' .. s 115*8a7d6542SBram Moolenaar endfor 116*8a7d6542SBram Moolenaar return res 117*8a7d6542SBram Moolenaarenddef 118*8a7d6542SBram Moolenaar 119*8a7d6542SBram Moolenaardef Test_call_varargs() 120*8a7d6542SBram Moolenaar assert_equal('one', MyVarargs('one')) 121*8a7d6542SBram Moolenaar assert_equal('one,two', MyVarargs('one', 'two')) 122*8a7d6542SBram Moolenaar assert_equal('one,two,three', MyVarargs('one', 'two', 'three')) 123*8a7d6542SBram Moolenaarenddef 124*8a7d6542SBram Moolenaar 125*8a7d6542SBram Moolenaardef Test_return_type_wrong() 126*8a7d6542SBram Moolenaar " TODO: why is ! needed for Mac and FreeBSD? 127*8a7d6542SBram Moolenaar CheckScriptFailure(['def! Func(): number', 'return "a"', 'enddef'], 'expected number but got string') 128*8a7d6542SBram Moolenaar CheckScriptFailure(['def! Func(): string', 'return 1', 'enddef'], 'expected string but got number') 129*8a7d6542SBram Moolenaar CheckScriptFailure(['def! Func(): void', 'return "a"', 'enddef'], 'expected void but got string') 130*8a7d6542SBram Moolenaar CheckScriptFailure(['def! Func()', 'return "a"', 'enddef'], 'expected void but got string') 131*8a7d6542SBram Moolenaarenddef 132*8a7d6542SBram Moolenaar 133*8a7d6542SBram Moolenaardef Test_try_catch() 134*8a7d6542SBram Moolenaar let l = [] 135*8a7d6542SBram Moolenaar try 136*8a7d6542SBram Moolenaar add(l, '1') 137*8a7d6542SBram Moolenaar throw 'wrong' 138*8a7d6542SBram Moolenaar add(l, '2') 139*8a7d6542SBram Moolenaar catch 140*8a7d6542SBram Moolenaar add(l, v:exception) 141*8a7d6542SBram Moolenaar finally 142*8a7d6542SBram Moolenaar add(l, '3') 143*8a7d6542SBram Moolenaar endtry 144*8a7d6542SBram Moolenaar assert_equal(['1', 'wrong', '3'], l) 145*8a7d6542SBram Moolenaarenddef 146*8a7d6542SBram Moolenaar 147*8a7d6542SBram Moolenaarlet s:export_script_lines =<< trim END 148*8a7d6542SBram Moolenaar vim9script 149*8a7d6542SBram Moolenaar let name: string = 'bob' 150*8a7d6542SBram Moolenaar def Concat(arg: string): string 151*8a7d6542SBram Moolenaar return name .. arg 152*8a7d6542SBram Moolenaar enddef 153*8a7d6542SBram Moolenaar let g:result = Concat('bie') 154*8a7d6542SBram Moolenaar let g:localname = name 155*8a7d6542SBram Moolenaar 156*8a7d6542SBram Moolenaar export const CONST = 1234 157*8a7d6542SBram Moolenaar export let exported = 9876 158*8a7d6542SBram Moolenaar export def Exported(): string 159*8a7d6542SBram Moolenaar return 'Exported' 160*8a7d6542SBram Moolenaar enddef 161*8a7d6542SBram MoolenaarEND 162*8a7d6542SBram Moolenaar 163*8a7d6542SBram Moolenaardef Test_vim9script() 164*8a7d6542SBram Moolenaar let import_script_lines =<< trim END 165*8a7d6542SBram Moolenaar vim9script 166*8a7d6542SBram Moolenaar import {exported, Exported} from './Xexport.vim' 167*8a7d6542SBram Moolenaar g:imported = exported 168*8a7d6542SBram Moolenaar g:imported_func = Exported() 169*8a7d6542SBram Moolenaar END 170*8a7d6542SBram Moolenaar 171*8a7d6542SBram Moolenaar writefile(import_script_lines, 'Ximport.vim') 172*8a7d6542SBram Moolenaar writefile(s:export_script_lines, 'Xexport.vim') 173*8a7d6542SBram Moolenaar 174*8a7d6542SBram Moolenaar source Ximport.vim 175*8a7d6542SBram Moolenaar 176*8a7d6542SBram Moolenaar assert_equal('bobbie', g:result) 177*8a7d6542SBram Moolenaar assert_equal('bob', g:localname) 178*8a7d6542SBram Moolenaar assert_equal(9876, g:imported) 179*8a7d6542SBram Moolenaar assert_equal('Exported', g:imported_func) 180*8a7d6542SBram Moolenaar assert_false(exists('g:name')) 181*8a7d6542SBram Moolenaar 182*8a7d6542SBram Moolenaar unlet g:result 183*8a7d6542SBram Moolenaar unlet g:localname 184*8a7d6542SBram Moolenaar unlet g:imported 185*8a7d6542SBram Moolenaar unlet g:imported_func 186*8a7d6542SBram Moolenaar delete('Ximport.vim') 187*8a7d6542SBram Moolenaar delete('Xexport.vim') 188*8a7d6542SBram Moolenaar 189*8a7d6542SBram Moolenaar CheckScriptFailure(['scriptversion 2', 'vim9script'], 'E1039:') 190*8a7d6542SBram Moolenaar CheckScriptFailure(['vim9script', 'scriptversion 2'], 'E1040:') 191*8a7d6542SBram Moolenaarenddef 192*8a7d6542SBram Moolenaar 193*8a7d6542SBram Moolenaardef Test_vim9script_call() 194*8a7d6542SBram Moolenaar let lines =<< trim END 195*8a7d6542SBram Moolenaar vim9script 196*8a7d6542SBram Moolenaar let var = '' 197*8a7d6542SBram Moolenaar def MyFunc(arg: string) 198*8a7d6542SBram Moolenaar var = arg 199*8a7d6542SBram Moolenaar enddef 200*8a7d6542SBram Moolenaar MyFunc('foobar') 201*8a7d6542SBram Moolenaar assert_equal('foobar', var) 202*8a7d6542SBram Moolenaar 203*8a7d6542SBram Moolenaar let str = 'barfoo' 204*8a7d6542SBram Moolenaar str->MyFunc() 205*8a7d6542SBram Moolenaar assert_equal('barfoo', var) 206*8a7d6542SBram Moolenaar 207*8a7d6542SBram Moolenaar let g:value = 'value' 208*8a7d6542SBram Moolenaar g:value->MyFunc() 209*8a7d6542SBram Moolenaar assert_equal('value', var) 210*8a7d6542SBram Moolenaar 211*8a7d6542SBram Moolenaar let listvar = [] 212*8a7d6542SBram Moolenaar def ListFunc(arg: list<number>) 213*8a7d6542SBram Moolenaar listvar = arg 214*8a7d6542SBram Moolenaar enddef 215*8a7d6542SBram Moolenaar [1, 2, 3]->ListFunc() 216*8a7d6542SBram Moolenaar assert_equal([1, 2, 3], listvar) 217*8a7d6542SBram Moolenaar 218*8a7d6542SBram Moolenaar let dictvar = {} 219*8a7d6542SBram Moolenaar def DictFunc(arg: dict<number>) 220*8a7d6542SBram Moolenaar dictvar = arg 221*8a7d6542SBram Moolenaar enddef 222*8a7d6542SBram Moolenaar {'a': 1, 'b': 2}->DictFunc() 223*8a7d6542SBram Moolenaar assert_equal(#{a: 1, b: 2}, dictvar) 224*8a7d6542SBram Moolenaar #{a: 3, b: 4}->DictFunc() 225*8a7d6542SBram Moolenaar assert_equal(#{a: 3, b: 4}, dictvar) 226*8a7d6542SBram Moolenaar END 227*8a7d6542SBram Moolenaar writefile(lines, 'Xcall.vim') 228*8a7d6542SBram Moolenaar source Xcall.vim 229*8a7d6542SBram Moolenaar delete('Xcall.vim') 230*8a7d6542SBram Moolenaarenddef 231*8a7d6542SBram Moolenaar 232*8a7d6542SBram Moolenaardef Test_vim9script_call_fail_decl() 233*8a7d6542SBram Moolenaar let lines =<< trim END 234*8a7d6542SBram Moolenaar vim9script 235*8a7d6542SBram Moolenaar let var = '' 236*8a7d6542SBram Moolenaar def MyFunc(arg: string) 237*8a7d6542SBram Moolenaar let var = 123 238*8a7d6542SBram Moolenaar enddef 239*8a7d6542SBram Moolenaar END 240*8a7d6542SBram Moolenaar writefile(lines, 'Xcall_decl.vim') 241*8a7d6542SBram Moolenaar assert_fails('source Xcall_decl.vim', 'E1054:') 242*8a7d6542SBram Moolenaar delete('Xcall_decl.vim') 243*8a7d6542SBram Moolenaarenddef 244*8a7d6542SBram Moolenaar 245*8a7d6542SBram Moolenaardef Test_vim9script_call_fail_const() 246*8a7d6542SBram Moolenaar let lines =<< trim END 247*8a7d6542SBram Moolenaar vim9script 248*8a7d6542SBram Moolenaar const var = '' 249*8a7d6542SBram Moolenaar def MyFunc(arg: string) 250*8a7d6542SBram Moolenaar var = 'asdf' 251*8a7d6542SBram Moolenaar enddef 252*8a7d6542SBram Moolenaar END 253*8a7d6542SBram Moolenaar writefile(lines, 'Xcall_const.vim') 254*8a7d6542SBram Moolenaar assert_fails('source Xcall_const.vim', 'E46:') 255*8a7d6542SBram Moolenaar delete('Xcall_const.vim') 256*8a7d6542SBram Moolenaarenddef 257*8a7d6542SBram Moolenaar 258*8a7d6542SBram Moolenaardef Test_vim9script_reload() 259*8a7d6542SBram Moolenaar let lines =<< trim END 260*8a7d6542SBram Moolenaar vim9script 261*8a7d6542SBram Moolenaar const var = '' 262*8a7d6542SBram Moolenaar let valone = 1234 263*8a7d6542SBram Moolenaar def MyFunc(arg: string) 264*8a7d6542SBram Moolenaar valone = 5678 265*8a7d6542SBram Moolenaar enddef 266*8a7d6542SBram Moolenaar END 267*8a7d6542SBram Moolenaar let morelines =<< trim END 268*8a7d6542SBram Moolenaar let valtwo = 222 269*8a7d6542SBram Moolenaar export def GetValtwo(): number 270*8a7d6542SBram Moolenaar return valtwo 271*8a7d6542SBram Moolenaar enddef 272*8a7d6542SBram Moolenaar END 273*8a7d6542SBram Moolenaar writefile(lines + morelines, 'Xreload.vim') 274*8a7d6542SBram Moolenaar source Xreload.vim 275*8a7d6542SBram Moolenaar source Xreload.vim 276*8a7d6542SBram Moolenaar source Xreload.vim 277*8a7d6542SBram Moolenaar 278*8a7d6542SBram Moolenaar let testlines =<< trim END 279*8a7d6542SBram Moolenaar vim9script 280*8a7d6542SBram Moolenaar def TheFunc() 281*8a7d6542SBram Moolenaar import GetValtwo from './Xreload.vim' 282*8a7d6542SBram Moolenaar assert_equal(222, GetValtwo()) 283*8a7d6542SBram Moolenaar enddef 284*8a7d6542SBram Moolenaar TheFunc() 285*8a7d6542SBram Moolenaar END 286*8a7d6542SBram Moolenaar writefile(testlines, 'Ximport.vim') 287*8a7d6542SBram Moolenaar source Ximport.vim 288*8a7d6542SBram Moolenaar 289*8a7d6542SBram Moolenaar " test that when not using "morelines" valtwo is still defined 290*8a7d6542SBram Moolenaar " need to source Xreload.vim again, import doesn't reload a script 291*8a7d6542SBram Moolenaar writefile(lines, 'Xreload.vim') 292*8a7d6542SBram Moolenaar source Xreload.vim 293*8a7d6542SBram Moolenaar source Ximport.vim 294*8a7d6542SBram Moolenaar 295*8a7d6542SBram Moolenaar " cannot declare a var twice 296*8a7d6542SBram Moolenaar lines =<< trim END 297*8a7d6542SBram Moolenaar vim9script 298*8a7d6542SBram Moolenaar let valone = 1234 299*8a7d6542SBram Moolenaar let valone = 5678 300*8a7d6542SBram Moolenaar END 301*8a7d6542SBram Moolenaar writefile(lines, 'Xreload.vim') 302*8a7d6542SBram Moolenaar assert_fails('source Xreload.vim', 'E1041:') 303*8a7d6542SBram Moolenaar 304*8a7d6542SBram Moolenaar delete('Xreload.vim') 305*8a7d6542SBram Moolenaar delete('Ximport.vim') 306*8a7d6542SBram Moolenaarenddef 307*8a7d6542SBram Moolenaar 308*8a7d6542SBram Moolenaardef Test_import_absolute() 309*8a7d6542SBram Moolenaar let import_lines = [ 310*8a7d6542SBram Moolenaar \ 'vim9script', 311*8a7d6542SBram Moolenaar \ 'import exported from "' .. escape(getcwd(), '\') .. '/Xexport_abs.vim"', 312*8a7d6542SBram Moolenaar \ 'g:imported_abs = exported', 313*8a7d6542SBram Moolenaar \ ] 314*8a7d6542SBram Moolenaar writefile(import_lines, 'Ximport_abs.vim') 315*8a7d6542SBram Moolenaar writefile(s:export_script_lines, 'Xexport_abs.vim') 316*8a7d6542SBram Moolenaar 317*8a7d6542SBram Moolenaar source Ximport_abs.vim 318*8a7d6542SBram Moolenaar 319*8a7d6542SBram Moolenaar assert_equal(9876, g:imported_abs) 320*8a7d6542SBram Moolenaar unlet g:imported_abs 321*8a7d6542SBram Moolenaar 322*8a7d6542SBram Moolenaar delete('Ximport_abs.vim') 323*8a7d6542SBram Moolenaar delete('Xexport_abs.vim') 324*8a7d6542SBram Moolenaarenddef 325*8a7d6542SBram Moolenaar 326*8a7d6542SBram Moolenaardef Test_import_rtp() 327*8a7d6542SBram Moolenaar let import_lines = [ 328*8a7d6542SBram Moolenaar \ 'vim9script', 329*8a7d6542SBram Moolenaar \ 'import exported from "Xexport_rtp.vim"', 330*8a7d6542SBram Moolenaar \ 'g:imported_rtp = exported', 331*8a7d6542SBram Moolenaar \ ] 332*8a7d6542SBram Moolenaar writefile(import_lines, 'Ximport_rtp.vim') 333*8a7d6542SBram Moolenaar mkdir('import') 334*8a7d6542SBram Moolenaar writefile(s:export_script_lines, 'import/Xexport_rtp.vim') 335*8a7d6542SBram Moolenaar 336*8a7d6542SBram Moolenaar let save_rtp = &rtp 337*8a7d6542SBram Moolenaar &rtp = getcwd() 338*8a7d6542SBram Moolenaar source Ximport_rtp.vim 339*8a7d6542SBram Moolenaar &rtp = save_rtp 340*8a7d6542SBram Moolenaar 341*8a7d6542SBram Moolenaar assert_equal(9876, g:imported_rtp) 342*8a7d6542SBram Moolenaar unlet g:imported_rtp 343*8a7d6542SBram Moolenaar 344*8a7d6542SBram Moolenaar delete('Ximport_rtp.vim') 345*8a7d6542SBram Moolenaar delete('import/Xexport_rtp.vim') 346*8a7d6542SBram Moolenaar delete('import', 'd') 347*8a7d6542SBram Moolenaarenddef 348*8a7d6542SBram Moolenaar 349*8a7d6542SBram Moolenaardef Test_fixed_size_list() 350*8a7d6542SBram Moolenaar " will be allocated as one piece of memory, check that changes work 351*8a7d6542SBram Moolenaar let l = [1, 2, 3, 4] 352*8a7d6542SBram Moolenaar l->remove(0) 353*8a7d6542SBram Moolenaar l->add(5) 354*8a7d6542SBram Moolenaar l->insert(99, 1) 355*8a7d6542SBram Moolenaar call assert_equal([2, 99, 3, 4, 5], l) 356*8a7d6542SBram Moolenaarenddef 357*8a7d6542SBram Moolenaar 358*8a7d6542SBram Moolenaar 359*8a7d6542SBram Moolenaar" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker 360