blob: 4c825e8f69026783a47fc42b415f0b18027ff357 [file] [log] [blame]
Bram Moolenaar971caf52020-09-21 22:21:42 +02001" Test Vim9 assignments
2
3source check.vim
4source vim9.vim
5
6let s:appendToMe = 'xxx'
7let s:addToMe = 111
8let g:existing = 'yes'
9let g:inc_counter = 1
10let $SOME_ENV_VAR = 'some'
11let g:alist = [7]
12let g:astring = 'text'
13
14def Test_assignment_bool()
15 let bool1: bool = true
16 assert_equal(v:true, bool1)
17 let bool2: bool = false
18 assert_equal(v:false, bool2)
19
20 let bool3: bool = 0
21 assert_equal(false, bool3)
22 let bool4: bool = 1
23 assert_equal(true, bool4)
24
25 let bool5: bool = 'yes' && 'no'
26 assert_equal(true, bool5)
27 let bool6: bool = [] && 99
28 assert_equal(false, bool6)
29 let bool7: bool = [] || #{a: 1} && 99
30 assert_equal(true, bool7)
31
32 let lines =<< trim END
33 vim9script
34 def GetFlag(): bool
35 let flag: bool = 1
36 return flag
37 enddef
38 let flag: bool = GetFlag()
39 assert_equal(true, flag)
40 flag = 0
41 assert_equal(false, flag)
42 flag = 1
43 assert_equal(true, flag)
44 flag = 99 || 123
45 assert_equal(true, flag)
46 flag = 'yes' && []
47 assert_equal(false, flag)
48 END
49 CheckScriptSuccess(lines)
50 CheckDefAndScriptFailure(['let x: bool = 2'], 'E1012:')
51 CheckDefAndScriptFailure(['let x: bool = -1'], 'E1012:')
52 CheckDefAndScriptFailure(['let x: bool = [1]'], 'E1012:')
53 CheckDefAndScriptFailure(['let x: bool = {}'], 'E1012:')
54 CheckDefAndScriptFailure(['let x: bool = "x"'], 'E1012:')
55enddef
56
57def Test_syntax()
58 let var = 234
59 let other: list<string> = ['asdf']
60enddef
61
62def Test_assignment()
63 CheckDefFailure(['let x:string'], 'E1069:')
64 CheckDefFailure(['let x:string = "x"'], 'E1069:')
65 CheckDefFailure(['let a:string = "x"'], 'E1069:')
66 CheckDefFailure(['let lambda = {-> "lambda"}'], 'E704:')
67
68 let nr: number = 1234
69 CheckDefFailure(['let nr: number = "asdf"'], 'E1012:')
70
71 let a: number = 6 #comment
72 assert_equal(6, a)
73
74 if has('channel')
75 let chan1: channel
76 let job1: job
77 let job2: job = job_start('willfail')
78 endif
79 if has('float')
80 let float1: float = 3.4
81 endif
82 let Funky1: func
83 let Funky2: func = function('len')
84 let Party2: func = funcref('g:Test_syntax')
85
86 g:newvar = 'new' #comment
87 assert_equal('new', g:newvar)
88
89 assert_equal('yes', g:existing)
90 g:existing = 'no'
91 assert_equal('no', g:existing)
92
93 v:char = 'abc'
94 assert_equal('abc', v:char)
95
96 $ENVVAR = 'foobar'
97 assert_equal('foobar', $ENVVAR)
98 $ENVVAR = ''
99
100 let lines =<< trim END
101 vim9script
102 $ENVVAR = 'barfoo'
103 assert_equal('barfoo', $ENVVAR)
104 $ENVVAR = ''
105 END
106 CheckScriptSuccess(lines)
107
108 s:appendToMe ..= 'yyy'
109 assert_equal('xxxyyy', s:appendToMe)
110 s:addToMe += 222
111 assert_equal(333, s:addToMe)
112 s:newVar = 'new'
113 assert_equal('new', s:newVar)
114
115 set ts=7
116 &ts += 1
117 assert_equal(8, &ts)
118 &ts -= 3
119 assert_equal(5, &ts)
120 &ts *= 2
121 assert_equal(10, &ts)
122 &ts /= 3
123 assert_equal(3, &ts)
124 set ts=10
125 &ts %= 4
126 assert_equal(2, &ts)
127
128 if has('float')
129 let f100: float = 100.0
130 f100 /= 5
131 assert_equal(20.0, f100)
132
133 let f200: float = 200.0
134 f200 /= 5.0
135 assert_equal(40.0, f200)
136
137 CheckDefFailure(['let nr: number = 200', 'nr /= 5.0'], 'E1012:')
138 endif
139
140 lines =<< trim END
141 &ts = 6
142 &ts += 3
143 assert_equal(9, &ts)
144
145 &l:ts = 6
146 assert_equal(6, &ts)
147 &l:ts += 2
148 assert_equal(8, &ts)
149
150 &g:ts = 6
151 assert_equal(6, &g:ts)
152 &g:ts += 2
153 assert_equal(8, &g:ts)
154 END
155 CheckDefAndScriptSuccess(lines)
156
157 CheckDefFailure(['&notex += 3'], 'E113:')
158 CheckDefFailure(['&ts ..= "xxx"'], 'E1019:')
159 CheckDefFailure(['&ts = [7]'], 'E1012:')
160 CheckDefExecFailure(['&ts = g:alist'], 'E1012: Type mismatch; expected number but got list<number>')
161 CheckDefFailure(['&ts = "xx"'], 'E1012:')
162 CheckDefExecFailure(['&ts = g:astring'], 'E1012: Type mismatch; expected number but got string')
163 CheckDefFailure(['&path += 3'], 'E1012:')
164 CheckDefExecFailure(['&bs = "asdf"'], 'E474:')
165 # test freeing ISN_STOREOPT
166 CheckDefFailure(['&ts = 3', 'let asdf'], 'E1022:')
167 &ts = 8
168
169 lines =<< trim END
170 let save_TI = &t_TI
171 &t_TI = ''
172 assert_equal('', &t_TI)
173 &t_TI = 'xxx'
174 assert_equal('xxx', &t_TI)
175 &t_TI = save_TI
176 END
177 CheckDefAndScriptSuccess(lines)
178
179 CheckDefFailure(['&t_TI = 123'], 'E1012:')
180 CheckScriptFailure(['vim9script', '&t_TI = 123'], 'E928:')
181
182 CheckDefFailure(['let s:var = 123'], 'E1101:')
183 CheckDefFailure(['let s:var: number'], 'E1101:')
184
185 lines =<< trim END
186 vim9script
187 def SomeFunc()
188 s:var = 123
189 enddef
190 defcompile
191 END
192 CheckScriptFailure(lines, 'E1089:')
193
194 g:inc_counter += 1
195 assert_equal(2, g:inc_counter)
196
197 $SOME_ENV_VAR ..= 'more'
198 assert_equal('somemore', $SOME_ENV_VAR)
199 CheckDefFailure(['$SOME_ENV_VAR += "more"'], 'E1051:')
200 CheckDefFailure(['$SOME_ENV_VAR += 123'], 'E1012:')
201
202 lines =<< trim END
203 @c = 'areg'
204 @c ..= 'add'
205 assert_equal('aregadd', @c)
206 END
207 CheckDefAndScriptSuccess(lines)
208
209 CheckDefFailure(['@a += "more"'], 'E1051:')
210 CheckDefFailure(['@a += 123'], 'E1012:')
211
212 v:errmsg = 'none'
213 v:errmsg ..= 'again'
214 assert_equal('noneagain', v:errmsg)
215 CheckDefFailure(['v:errmsg += "more"'], 'E1051:')
216 CheckDefFailure(['v:errmsg += 123'], 'E1012:')
217
218 # this should not leak
219 if 0
220 let text =<< trim END
221 some text
222 END
223 endif
224enddef
225
Bram Moolenaar81ed4962020-09-23 15:56:50 +0200226def Test_extend_list()
227 let lines =<< trim END
228 vim9script
229 let l: list<number>
230 l += [123]
231 assert_equal([123], l)
232
233 let d: dict<number>
234 d['one'] = 1
235 assert_equal(#{one: 1}, d)
236 END
237 CheckScriptSuccess(lines)
238enddef
239
Bram Moolenaar971caf52020-09-21 22:21:42 +0200240def Test_single_letter_vars()
241 # single letter variables
242 let a: number = 123
243 a = 123
244 assert_equal(123, a)
245 let b: number
246 b = 123
247 assert_equal(123, b)
248 let g: number
249 g = 123
250 assert_equal(123, g)
251 let s: number
252 s = 123
253 assert_equal(123, s)
254 let t: number
255 t = 123
256 assert_equal(123, t)
257 let v: number
258 v = 123
259 assert_equal(123, v)
260 let w: number
261 w = 123
262 assert_equal(123, w)
263enddef
264
265def Test_vim9_single_char_vars()
266 let lines =<< trim END
267 vim9script
268
269 # single character variable declarations work
270 let a: string
271 let b: number
272 let l: list<any>
273 let s: string
274 let t: number
275 let v: number
276 let w: number
277
278 # script-local variables can be used without s: prefix
279 a = 'script-a'
280 b = 111
281 l = [1, 2, 3]
282 s = 'script-s'
283 t = 222
284 v = 333
285 w = 444
286
287 assert_equal('script-a', a)
288 assert_equal(111, b)
289 assert_equal([1, 2, 3], l)
290 assert_equal('script-s', s)
291 assert_equal(222, t)
292 assert_equal(333, v)
293 assert_equal(444, w)
294 END
295 writefile(lines, 'Xsinglechar')
296 source Xsinglechar
297 delete('Xsinglechar')
298enddef
299
300def Test_assignment_list()
301 let list1: list<bool> = [false, true, false]
302 let list2: list<number> = [1, 2, 3]
303 let list3: list<string> = ['sdf', 'asdf']
304 let list4: list<any> = ['yes', true, 1234]
305 let list5: list<blob> = [0z01, 0z02]
306
307 let listS: list<string> = []
308 let listN: list<number> = []
309
310 assert_equal([1, 2, 3], list2)
311 list2[-1] = 99
312 assert_equal([1, 2, 99], list2)
313 list2[-2] = 88
314 assert_equal([1, 88, 99], list2)
315 list2[-3] = 77
316 assert_equal([77, 88, 99], list2)
317 list2 += [100]
318 assert_equal([77, 88, 99, 100], list2)
319
320 list3 += ['end']
321 assert_equal(['sdf', 'asdf', 'end'], list3)
322
323 CheckDefExecFailure(['let ll = [1, 2, 3]', 'll[-4] = 6'], 'E684:')
324 CheckDefExecFailure(['let [v1, v2] = [1, 2]'], 'E1092:')
325
326 # type becomes list<any>
327 let somelist = rand() > 0 ? [1, 2, 3] : ['a', 'b', 'c']
328enddef
329
330def Test_assignment_list_vim9script()
331 let lines =<< trim END
332 vim9script
333 let v1: number
334 let v2: number
335 let v3: number
336 [v1, v2, v3] = [1, 2, 3]
337 assert_equal([1, 2, 3], [v1, v2, v3])
338 END
339 CheckScriptSuccess(lines)
340enddef
341
342def Test_assignment_dict()
343 let dict1: dict<bool> = #{one: false, two: true}
344 let dict2: dict<number> = #{one: 1, two: 2}
345 let dict3: dict<string> = #{key: 'value'}
346 let dict4: dict<any> = #{one: 1, two: '2'}
347 let dict5: dict<blob> = #{one: 0z01, two: 0z02}
348
349 # overwrite
350 dict3['key'] = 'another'
351
352 # empty key can be used
353 let dd = {}
354 dd[""] = 6
355 assert_equal({'': 6}, dd)
356
357 # type becomes dict<any>
358 let somedict = rand() > 0 ? #{a: 1, b: 2} : #{a: 'a', b: 'b'}
359
360 # assignment to script-local dict
361 let lines =<< trim END
362 vim9script
363 let test: dict<any> = {}
364 def FillDict(): dict<any>
365 test['a'] = 43
366 return test
367 enddef
368 assert_equal(#{a: 43}, FillDict())
369 END
370 CheckScriptSuccess(lines)
371
372 lines =<< trim END
373 vim9script
374 let test: dict<any>
375 def FillDict(): dict<any>
376 test['a'] = 43
377 return test
378 enddef
379 FillDict()
380 END
381 CheckScriptFailure(lines, 'E1103:')
382
383 # assignment to global dict
384 lines =<< trim END
385 vim9script
386 g:test = {}
387 def FillDict(): dict<any>
388 g:test['a'] = 43
389 return g:test
390 enddef
391 assert_equal(#{a: 43}, FillDict())
392 END
393 CheckScriptSuccess(lines)
394
395 # assignment to buffer dict
396 lines =<< trim END
397 vim9script
398 b:test = {}
399 def FillDict(): dict<any>
400 b:test['a'] = 43
401 return b:test
402 enddef
403 assert_equal(#{a: 43}, FillDict())
404 END
405 CheckScriptSuccess(lines)
406enddef
407
408def Test_assignment_local()
409 # Test in a separated file in order not to the current buffer/window/tab is
410 # changed.
411 let script_lines: list<string> =<< trim END
412 let b:existing = 'yes'
413 let w:existing = 'yes'
414 let t:existing = 'yes'
415
416 def Test_assignment_local_internal()
417 b:newvar = 'new'
418 assert_equal('new', b:newvar)
419 assert_equal('yes', b:existing)
420 b:existing = 'no'
421 assert_equal('no', b:existing)
422 b:existing ..= 'NO'
423 assert_equal('noNO', b:existing)
424
425 w:newvar = 'new'
426 assert_equal('new', w:newvar)
427 assert_equal('yes', w:existing)
428 w:existing = 'no'
429 assert_equal('no', w:existing)
430 w:existing ..= 'NO'
431 assert_equal('noNO', w:existing)
432
433 t:newvar = 'new'
434 assert_equal('new', t:newvar)
435 assert_equal('yes', t:existing)
436 t:existing = 'no'
437 assert_equal('no', t:existing)
438 t:existing ..= 'NO'
439 assert_equal('noNO', t:existing)
440 enddef
441 call Test_assignment_local_internal()
442 END
443 CheckScriptSuccess(script_lines)
444enddef
445
446def Test_assignment_default()
447
448 # Test default values.
449 let thebool: bool
450 assert_equal(v:false, thebool)
451
452 let thenumber: number
453 assert_equal(0, thenumber)
454
455 if has('float')
456 let thefloat: float
457 assert_equal(0.0, thefloat)
458 endif
459
460 let thestring: string
461 assert_equal('', thestring)
462
463 let theblob: blob
464 assert_equal(0z, theblob)
465
466 let Thefunc: func
467 assert_equal(test_null_function(), Thefunc)
468
469 let thelist: list<any>
470 assert_equal([], thelist)
471
472 let thedict: dict<any>
473 assert_equal({}, thedict)
474
475 if has('channel')
476 let thejob: job
477 assert_equal(test_null_job(), thejob)
478
479 let thechannel: channel
480 assert_equal(test_null_channel(), thechannel)
481
482 if has('unix') && executable('cat')
483 # check with non-null job and channel, types must match
484 thejob = job_start("cat ", #{})
485 thechannel = job_getchannel(thejob)
486 job_stop(thejob, 'kill')
487 endif
488 endif
489
490 let nr = 1234 | nr = 5678
491 assert_equal(5678, nr)
492enddef
493
494def Test_assignment_var_list()
495 let v1: string
496 let v2: string
497 let vrem: list<string>
498 [v1] = ['aaa']
499 assert_equal('aaa', v1)
500
501 [v1, v2] = ['one', 'two']
502 assert_equal('one', v1)
503 assert_equal('two', v2)
504
505 [v1, v2; vrem] = ['one', 'two']
506 assert_equal('one', v1)
507 assert_equal('two', v2)
508 assert_equal([], vrem)
509
510 [v1, v2; vrem] = ['one', 'two', 'three']
511 assert_equal('one', v1)
512 assert_equal('two', v2)
513 assert_equal(['three'], vrem)
514
515 [&ts, &sw] = [3, 4]
516 assert_equal(3, &ts)
517 assert_equal(4, &sw)
518 set ts=8 sw=4
519enddef
520
521def Test_assignment_vim9script()
522 let lines =<< trim END
523 vim9script
524 def Func(): list<number>
525 return [1, 2]
526 enddef
527 let var1: number
528 let var2: number
529 [var1, var2] =
530 Func()
531 assert_equal(1, var1)
532 assert_equal(2, var2)
533 let ll =
534 Func()
535 assert_equal([1, 2], ll)
536
537 @/ = 'text'
538 assert_equal('text', @/)
539 @0 = 'zero'
540 assert_equal('zero', @0)
541 @1 = 'one'
542 assert_equal('one', @1)
543 @9 = 'nine'
544 assert_equal('nine', @9)
545 @- = 'minus'
546 assert_equal('minus', @-)
547 if has('clipboard_working')
548 @* = 'star'
549 assert_equal('star', @*)
550 @+ = 'plus'
551 assert_equal('plus', @+)
552 endif
553
554 let a: number = 123
555 assert_equal(123, a)
556 let s: string = 'yes'
557 assert_equal('yes', s)
558 let b: number = 42
559 assert_equal(42, b)
560 let w: number = 43
561 assert_equal(43, w)
562 let t: number = 44
563 assert_equal(44, t)
564 END
565 CheckScriptSuccess(lines)
566enddef
567
568def Mess(): string
569 v:foldstart = 123
570 return 'xxx'
571enddef
572
573def Test_assignment_failure()
574 CheckDefFailure(['let var=234'], 'E1004:')
575 CheckDefFailure(['let var =234'], 'E1004:')
576 CheckDefFailure(['let var= 234'], 'E1004:')
577
578 CheckScriptFailure(['vim9script', 'let var=234'], 'E1004:')
579 CheckScriptFailure(['vim9script', 'let var=234'], "before and after '='")
580 CheckScriptFailure(['vim9script', 'let var =234'], 'E1004:')
581 CheckScriptFailure(['vim9script', 'let var= 234'], 'E1004:')
582 CheckScriptFailure(['vim9script', 'let var = 234', 'var+=234'], 'E1004:')
583 CheckScriptFailure(['vim9script', 'let var = 234', 'var+=234'], "before and after '+='")
584 CheckScriptFailure(['vim9script', 'let var = "x"', 'var..="y"'], 'E1004:')
585 CheckScriptFailure(['vim9script', 'let var = "x"', 'var..="y"'], "before and after '..='")
586
587 CheckDefFailure(['let true = 1'], 'E1034:')
588 CheckDefFailure(['let false = 1'], 'E1034:')
589
590 CheckDefFailure(['[a; b; c] = g:list'], 'E452:')
591 CheckDefExecFailure(['let a: number',
592 '[a] = test_null_list()'], 'E1093:')
593 CheckDefExecFailure(['let a: number',
594 '[a] = []'], 'E1093:')
595 CheckDefExecFailure(['let x: number',
596 'let y: number',
597 '[x, y] = [1]'], 'E1093:')
598 CheckDefExecFailure(['let x: number',
599 'let y: number',
600 'let z: list<number>',
601 '[x, y; z] = [1]'], 'E1093:')
602
603 CheckDefFailure(['let somevar'], "E1022:")
604 CheckDefFailure(['let &tabstop = 4'], 'E1052:')
605 CheckDefFailure(['&g:option = 5'], 'E113:')
606 CheckScriptFailure(['vim9script', 'let &tabstop = 4'], 'E1052:')
607
608 CheckDefFailure(['let $VAR = 5'], 'E1016: Cannot declare an environment variable:')
609 CheckScriptFailure(['vim9script', 'let $ENV = "xxx"'], 'E1016:')
610
611 if has('dnd')
612 CheckDefFailure(['let @~ = 5'], 'E1066:')
613 else
614 CheckDefFailure(['let @~ = 5'], 'E354:')
615 CheckDefFailure(['@~ = 5'], 'E354:')
616 endif
617 CheckDefFailure(['let @a = 5'], 'E1066:')
618 CheckDefFailure(['let @/ = "x"'], 'E1066:')
619 CheckScriptFailure(['vim9script', 'let @a = "abc"'], 'E1066:')
620
621 CheckDefFailure(['let g:var = 5'], 'E1016: Cannot declare a global variable:')
622 CheckDefFailure(['let w:var = 5'], 'E1016: Cannot declare a window variable:')
623 CheckDefFailure(['let b:var = 5'], 'E1016: Cannot declare a buffer variable:')
624 CheckDefFailure(['let t:var = 5'], 'E1016: Cannot declare a tab variable:')
625
626 CheckDefFailure(['let anr = 4', 'anr ..= "text"'], 'E1019:')
627 CheckDefFailure(['let xnr += 4'], 'E1020:', 1)
628 CheckScriptFailure(['vim9script', 'let xnr += 4'], 'E1020:')
629 CheckDefFailure(["let xnr = xnr + 1"], 'E1001:', 1)
630 CheckScriptFailure(['vim9script', 'let xnr = xnr + 4'], 'E121:')
631
632 CheckScriptFailure(['vim9script', 'def Func()', 'let dummy = s:notfound', 'enddef', 'defcompile'], 'E1108:')
633
634 CheckDefFailure(['let var: list<string> = [123]'], 'expected list<string> but got list<number>')
635 CheckDefFailure(['let var: list<number> = ["xx"]'], 'expected list<number> but got list<string>')
636
637 CheckDefFailure(['let var: dict<string> = #{key: 123}'], 'expected dict<string> but got dict<number>')
638 CheckDefFailure(['let var: dict<number> = #{key: "xx"}'], 'expected dict<number> but got dict<string>')
639
640 CheckDefFailure(['let var = feedkeys("0")'], 'E1031:')
641 CheckDefFailure(['let var: number = feedkeys("0")'], 'expected number but got void')
642
643 CheckDefFailure(['let var: dict <number>'], 'E1068:')
644 CheckDefFailure(['let var: dict<number'], 'E1009:')
645
646 assert_fails('s/^/\=Mess()/n', 'E794:')
647 CheckDefFailure(['let var: dict<number'], 'E1009:')
648
649 CheckDefFailure(['w:foo: number = 10'],
650 'E488: Trailing characters: : number = 1')
651 CheckDefFailure(['t:foo: bool = true'],
652 'E488: Trailing characters: : bool = true')
653 CheckDefFailure(['b:foo: string = "x"'],
654 'E488: Trailing characters: : string = "x"')
655 CheckDefFailure(['g:foo: number = 123'],
656 'E488: Trailing characters: : number = 123')
657enddef
658
659def Test_assign_list()
660 let l: list<string> = []
661 l[0] = 'value'
662 assert_equal('value', l[0])
663
664 l[1] = 'asdf'
665 assert_equal('value', l[0])
666 assert_equal('asdf', l[1])
667 assert_equal('asdf', l[-1])
668 assert_equal('value', l[-2])
669
670 let nrl: list<number> = []
671 for i in range(5)
672 nrl[i] = i
673 endfor
674 assert_equal([0, 1, 2, 3, 4], nrl)
675enddef
676
677def Test_assign_dict()
678 let d: dict<string> = {}
679 d['key'] = 'value'
680 assert_equal('value', d['key'])
681
682 d[123] = 'qwerty'
683 assert_equal('qwerty', d[123])
684 assert_equal('qwerty', d['123'])
685
686 let nrd: dict<number> = {}
687 for i in range(3)
688 nrd[i] = i
689 endfor
690 assert_equal({'0': 0, '1': 1, '2': 2}, nrd)
691enddef
692
Bram Moolenaar04bdd572020-09-23 13:25:32 +0200693def Test_assign_dict_unknown_type()
694 let lines =<< trim END
695 vim9script
696 let mylist = []
697 mylist += [#{one: 'one'}]
698 def Func()
699 let dd = mylist[0]
700 assert_equal('one', dd.one)
701 enddef
702 Func()
703 END
704 CheckScriptSuccess(lines)
705
706 # doesn't work yet
707 #lines =<< trim END
708 # vim9script
709 # let mylist = [[]]
710 # mylist[0] += [#{one: 'one'}]
711 # def Func()
712 # let dd = mylist[0][0]
713 # assert_equal('one', dd.one)
714 # enddef
715 # Func()
716 #END
717 #CheckScriptSuccess(lines)
718enddef
719
Bram Moolenaar971caf52020-09-21 22:21:42 +0200720def Test_assign_lambda()
721 # check if assign a lambda to a variable which type is func or any.
722 let lines =<< trim END
723 vim9script
724 let FuncRef = {->123}
725 assert_equal(123, FuncRef())
726 let FuncRef_Func: func = {->123}
727 assert_equal(123, FuncRef_Func())
728 let FuncRef_Any: any = {->123}
729 assert_equal(123, FuncRef_Any())
730 END
731 CheckScriptSuccess(lines)
732enddef
733
734" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker