blob: 010401084cdf3752c4ff6c236b9d280d9ef6c37d [file] [log] [blame]
Bram Moolenaar2b618522019-01-12 13:26:03 +01001" Tests for the :source command.
2
Bram Moolenaar5c504f62021-04-01 13:39:51 +02003source check.vim
4source view_util.vim
5
Bram Moolenaar2b618522019-01-12 13:26:03 +01006func Test_source_autocmd()
7 call writefile([
8 \ 'let did_source = 1',
9 \ ], 'Xsourced')
10 au SourcePre *source* let did_source_pre = 1
11 au SourcePost *source* let did_source_post = 1
12
13 source Xsourced
14
15 call assert_equal(g:did_source, 1)
16 call assert_equal(g:did_source_pre, 1)
17 call assert_equal(g:did_source_post, 1)
18
19 call delete('Xsourced')
20 au! SourcePre
21 au! SourcePost
22 unlet g:did_source
23 unlet g:did_source_pre
24 unlet g:did_source_post
25endfunc
26
27func Test_source_cmd()
28 au SourceCmd *source* let did_source = expand('<afile>')
29 au SourcePre *source* let did_source_pre = 2
30 au SourcePost *source* let did_source_post = 2
31
32 source Xsourced
33
34 call assert_equal(g:did_source, 'Xsourced')
35 call assert_false(exists('g:did_source_pre'))
36 call assert_equal(g:did_source_post, 2)
37
38 au! SourceCmd
39 au! SourcePre
40 au! SourcePost
41endfunc
Bram Moolenaar53575522019-05-22 22:38:25 +020042
43func Test_source_sandbox()
44 new
45 call writefile(["Ohello\<Esc>"], 'Xsourcehello')
46 source! Xsourcehello | echo
47 call assert_equal('hello', getline(1))
48 call assert_fails('sandbox source! Xsourcehello', 'E48:')
49 bwipe!
Bram Moolenaarddd33082019-06-03 23:07:25 +020050 call delete('Xsourcehello')
Bram Moolenaar53575522019-05-22 22:38:25 +020051endfunc
Bram Moolenaarca33eb22020-01-19 20:18:09 +010052
53" When deleting a file and immediately creating a new one the inode may be
54" recycled. Vim should not recognize it as the same script.
55func Test_different_script()
Bram Moolenaarca33eb22020-01-19 20:18:09 +010056 call writefile(['let s:var = "asdf"'], 'XoneScript')
57 source XoneScript
58 call delete('XoneScript')
59 call writefile(['let g:var = s:var'], 'XtwoScript')
60 call assert_fails('source XtwoScript', 'E121:')
61 call delete('XtwoScript')
62endfunc
Bram Moolenaar9f6277b2020-02-11 22:04:02 +010063
64" When sourcing a vim script, shebang should be ignored.
65func Test_source_ignore_shebang()
66 call writefile(['#!./xyzabc', 'let g:val=369'], 'Xfile.vim')
67 source Xfile.vim
68 call assert_equal(g:val, 369)
69 call delete('Xfile.vim')
70endfunc
71
Dominique Pelleaf4a61a2021-12-27 17:21:41 +000072" Test for expanding <sfile> in an autocmd and for <slnum> and <sflnum>
Bram Moolenaarbc2b71d2020-02-17 21:33:30 +010073func Test_source_autocmd_sfile()
74 let code =<< trim [CODE]
75 let g:SfileName = ''
76 augroup sfiletest
77 au!
78 autocmd User UserAutoCmd let g:Sfile = '<sfile>:t'
79 augroup END
80 doautocmd User UserAutoCmd
81 let g:Slnum = expand('<slnum>')
82 let g:Sflnum = expand('<sflnum>')
83 augroup! sfiletest
84 [CODE]
85 call writefile(code, 'Xscript.vim')
86 source Xscript.vim
87 call assert_equal('Xscript.vim', g:Sfile)
88 call assert_equal('7', g:Slnum)
89 call assert_equal('8', g:Sflnum)
90 call delete('Xscript.vim')
91endfunc
92
Bram Moolenaar476a6132020-04-08 19:48:56 +020093func Test_source_error()
94 call assert_fails('scriptencoding utf-8', 'E167:')
95 call assert_fails('finish', 'E168:')
96 call assert_fails('scriptversion 2', 'E984:')
Yegappan Lakshmanan36a5b682022-03-19 12:56:51 +000097 call assert_fails('source!', 'E471:')
98 new
99 call setline(1, ['', '', '', ''])
100 call assert_fails('1,3source Xscript.vim', 'E481:')
101 call assert_fails('1,3source! Xscript.vim', 'E481:')
102 bw!
Bram Moolenaar476a6132020-04-08 19:48:56 +0200103endfunc
104
Bram Moolenaar5c504f62021-04-01 13:39:51 +0200105" Test for sourcing a script recursively
106func Test_nested_script()
107 CheckRunVimInTerminal
108 call writefile([':source! Xscript.vim', ''], 'Xscript.vim')
109 let buf = RunVimInTerminal('', {'rows': 6})
110 call term_wait(buf)
111 call term_sendkeys(buf, ":set noruler\n")
112 call term_sendkeys(buf, ":source! Xscript.vim\n")
113 call term_wait(buf)
114 call WaitForAssert({-> assert_match('E22: Scripts nested too deep\s*', term_getline(buf, 6))})
115 call delete('Xscript.vim')
116 call StopVimInTerminal(buf)
117endfunc
118
Yegappan Lakshmanan36a5b682022-03-19 12:56:51 +0000119" Test for sourcing a script from the current buffer
120func Test_source_buffer()
121 new
122 " Source a simple script
123 let lines =<< trim END
124 let a = "Test"
125 let b = 20
126
127 let c = [1.1]
128 END
129 call setline(1, lines)
130 source
131 call assert_equal(['Test', 20, [1.1]], [g:a, g:b, g:c])
132
133 " Source a range of lines in the current buffer
134 %d _
135 let lines =<< trim END
136 let a = 10
137 let a += 20
138 let a += 30
139 let a += 40
140 END
141 call setline(1, lines)
142 .source
143 call assert_equal(10, g:a)
144 3source
145 call assert_equal(40, g:a)
146 2,3source
147 call assert_equal(90, g:a)
148
Yegappan Lakshmanan85b43c62022-03-21 19:45:17 +0000149 " Make sure the script line number is correct when sourcing a range of
150 " lines.
151 %d _
152 let lines =<< trim END
153 Line 1
154 Line 2
155 func Xtestfunc()
156 return expand("<sflnum>")
157 endfunc
158 Line 3
159 Line 4
160 END
161 call setline(1, lines)
162 3,5source
163 call assert_equal('4', Xtestfunc())
164 delfunc Xtestfunc
165
Yegappan Lakshmanan36a5b682022-03-19 12:56:51 +0000166 " Source a script with line continuation lines
167 %d _
168 let lines =<< trim END
169 let m = [
170 \ 1,
171 \ 2,
172 \ ]
173 call add(m, 3)
174 END
175 call setline(1, lines)
176 source
177 call assert_equal([1, 2, 3], g:m)
178 " Source a script with line continuation lines and a comment
179 %d _
180 let lines =<< trim END
181 let m = [
182 "\ first entry
183 \ 'a',
184 "\ second entry
185 \ 'b',
186 \ ]
187 " third entry
188 call add(m, 'c')
189 END
190 call setline(1, lines)
191 source
192 call assert_equal(['a', 'b', 'c'], g:m)
193 " Source an incomplete line continuation line
194 %d _
195 let lines =<< trim END
196 let k = [
197 \
198 END
199 call setline(1, lines)
200 call assert_fails('source', 'E697:')
201 " Source a function with a for loop
202 %d _
203 let lines =<< trim END
204 let m = []
205 " test function
206 func! Xtest()
207 for i in range(5, 7)
208 call add(g:m, i)
209 endfor
210 endfunc
211 call Xtest()
212 END
213 call setline(1, lines)
214 source
215 call assert_equal([5, 6, 7], g:m)
216 " Source an empty buffer
217 %d _
218 source
219
220 " test for script local functions and variables
221 let lines =<< trim END
222 let s:var1 = 10
223 func s:F1()
224 let s:var1 += 1
225 return s:var1
226 endfunc
227 func s:F2()
228 endfunc
229 let g:ScriptID = expand("<SID>")
230 END
231 call setline(1, lines)
232 source
233 call assert_true(g:ScriptID != '')
234 call assert_true(exists('*' .. g:ScriptID .. 'F1'))
235 call assert_true(exists('*' .. g:ScriptID .. 'F2'))
236 call assert_equal(11, call(g:ScriptID .. 'F1', []))
237
238 " the same script ID should be used even if the buffer is sourced more than
239 " once
240 %d _
241 let lines =<< trim END
242 let g:ScriptID = expand("<SID>")
243 let g:Count += 1
244 END
245 call setline(1, lines)
246 let g:Count = 0
247 source
248 call assert_true(g:ScriptID != '')
249 let scid = g:ScriptID
250 source
251 call assert_equal(scid, g:ScriptID)
252 call assert_equal(2, g:Count)
253 source
254 call assert_equal(scid, g:ScriptID)
255 call assert_equal(3, g:Count)
256
257 " test for the script line number
258 %d _
259 let lines =<< trim END
260 " comment
261 let g:Slnum1 = expand("<slnum>")
262 let i = 1 +
263 \ 2 +
264 "\ comment
265 \ 3
266 let g:Slnum2 = expand("<slnum>")
267 END
268 call setline(1, lines)
269 source
270 call assert_equal('2', g:Slnum1)
271 call assert_equal('7', g:Slnum2)
272
273 " test for retaining the same script number across source calls
274 let lines =<< trim END
275 let g:ScriptID1 = expand("<SID>")
276 let g:Slnum1 = expand("<slnum>")
277 let l =<< trim END
278 let g:Slnum2 = expand("<slnum>")
279 let g:ScriptID2 = expand("<SID>")
280 END
281 new
282 call setline(1, l)
283 source
284 bw!
285 let g:ScriptID3 = expand("<SID>")
286 let g:Slnum3 = expand("<slnum>")
287 END
288 call writefile(lines, 'Xscript')
289 source Xscript
290 call assert_true(g:ScriptID1 != g:ScriptID2)
291 call assert_equal(g:ScriptID1, g:ScriptID3)
292 call assert_equal('2', g:Slnum1)
293 call assert_equal('1', g:Slnum2)
294 call assert_equal('12', g:Slnum3)
295 call delete('Xscript')
296
297 " test for sourcing a heredoc
298 %d _
299 let lines =<< trim END
300 let a = 1
301 let heredoc =<< trim DATA
302 red
303 green
304 blue
305 DATA
306 let b = 2
307 END
308 call setline(1, lines)
309 source
310 call assert_equal(['red', ' green', 'blue'], g:heredoc)
311
312 " test for a while and for statement
313 %d _
314 let lines =<< trim END
315 let a = 0
316 let b = 1
317 while b <= 10
318 let a += 10
319 let b += 1
320 endwhile
321 for i in range(5)
322 let a += 10
323 endfor
324 END
325 call setline(1, lines)
326 source
327 call assert_equal(150, g:a)
328
329 " test for sourcing the same buffer multiple times after changing a function
330 %d _
331 let lines =<< trim END
332 func Xtestfunc()
333 return "one"
334 endfunc
335 END
336 call setline(1, lines)
337 source
338 call assert_equal("one", Xtestfunc())
339 call setline(2, ' return "two"')
340 source
341 call assert_equal("two", Xtestfunc())
342 call setline(2, ' return "three"')
343 source
344 call assert_equal("three", Xtestfunc())
345 delfunc Xtestfunc
346
Yegappan Lakshmanan85b43c62022-03-21 19:45:17 +0000347 " test for using try/catch
348 %d _
349 let lines =<< trim END
350 let Trace = '1'
351 try
352 let a1 = b1
353 catch
354 let Trace ..= '2'
355 finally
356 let Trace ..= '3'
357 endtry
358 END
359 call setline(1, lines)
360 source
361 call assert_equal("123", g:Trace)
362
363 " test with the finish command
364 %d _
365 let lines =<< trim END
366 let g:Color = 'blue'
367 finish
368 let g:Color = 'green'
369 END
370 call setline(1, lines)
371 source
372 call assert_equal('blue', g:Color)
373
374 " Test for the SourcePre and SourcePost autocmds
375 augroup Xtest
376 au!
377 au SourcePre * let g:XsourcePre=4
378 \ | let g:XsourcePreFile = expand("<afile>")
379 au SourcePost * let g:XsourcePost=6
380 \ | let g:XsourcePostFile = expand("<afile>")
381 augroup END
382 %d _
383 let lines =<< trim END
384 let a = 1
385 END
386 call setline(1, lines)
387 source
388 call assert_equal(4, g:XsourcePre)
389 call assert_equal(6, g:XsourcePost)
390 call assert_equal(':source buffer=' .. bufnr(), g:XsourcePreFile)
391 call assert_equal(':source buffer=' .. bufnr(), g:XsourcePostFile)
392 augroup Xtest
393 au!
394 augroup END
395 augroup! Xtest
396
397 %bw!
398endfunc
399
400" Test for sourcing a Vim9 script from the current buffer
401func Test_source_buffer_vim9()
402 new
403
Yegappan Lakshmanan36a5b682022-03-19 12:56:51 +0000404 " test for sourcing a Vim9 script
405 %d _
406 let lines =<< trim END
407 vim9script
408
409 # check dict
410 var x: number = 10
411 def g:Xtestfunc(): number
412 return x
413 enddef
414 END
415 call setline(1, lines)
416 source
417 call assert_equal(10, Xtestfunc())
418
Yegappan Lakshmanan85b43c62022-03-21 19:45:17 +0000419 " test for sourcing a vim9 script with line continuation
420 %d _
421 let lines =<< trim END
422 vim9script
423
424 g:Str1 = "hello "
425 .. "world"
426 .. ", how are you?"
427 g:Colors = [
428 'red',
429 # comment
430 'blue'
431 ]
432 g:Dict = {
433 a: 22,
434 # comment
435 b: 33
436 }
437
438 # calling a function with line continuation
439 def Sum(...values: list<number>): number
440 var sum: number = 0
441 for v in values
442 sum += v
443 endfor
444 return sum
445 enddef
446 g:Total1 = Sum(10,
447 20,
448 30)
449
450 var i: number = 0
451 while i < 10
452 # while loop
453 i +=
454 1
455 endwhile
456 g:Count1 = i
457
458 # for loop
459 g:Count2 = 0
460 for j in range(10, 20)
461 g:Count2 +=
462 i
463 endfor
464
465 g:Total2 = 10 +
466 20 -
467 5
468
469 g:Result1 = g:Total2 > 1
470 ? 'red'
471 : 'blue'
472
473 g:Str2 = 'x'
474 ->repeat(10)
475 ->trim()
476 ->strpart(4)
477
478 g:Result2 = g:Dict
479 .a
480
481 augroup Test
482 au!
483 au BufNewFile Xfile g:readFile = 1
484 | g:readExtra = 2
485 augroup END
486 g:readFile = 0
487 g:readExtra = 0
488 new Xfile
489 bwipe!
490 augroup Test
491 au!
492 augroup END
493 END
494 call setline(1, lines)
495 source
496 call assert_equal("hello world, how are you?", g:Str1)
497 call assert_equal(['red', 'blue'], g:Colors)
498 call assert_equal(#{a: 22, b: 33}, g:Dict)
499 call assert_equal(60, g:Total1)
500 call assert_equal(10, g:Count1)
501 call assert_equal(110, g:Count2)
502 call assert_equal(25, g:Total2)
503 call assert_equal('red', g:Result1)
504 call assert_equal('xxxxxx', g:Str2)
505 call assert_equal(22, g:Result2)
506 call assert_equal(1, g:readFile)
507 call assert_equal(2, g:readExtra)
508
509 " test for sourcing the same buffer multiple times after changing a function
510 %d _
511 let lines =<< trim END
512 vim9script
513 def g:Xtestfunc(): string
514 return "one"
515 enddef
516 END
517 call setline(1, lines)
518 source
519 call assert_equal("one", Xtestfunc())
520 call setline(3, ' return "two"')
521 source
522 call assert_equal("two", Xtestfunc())
523 call setline(3, ' return "three"')
524 source
525 call assert_equal("three", Xtestfunc())
526 delfunc Xtestfunc
527
528 " Test for sourcing a range of lines. Make sure the script line number is
529 " correct.
530 %d _
531 let lines =<< trim END
532 Line 1
533 Line 2
534 vim9script
535 def g:Xtestfunc(): string
536 return expand("<sflnum>")
537 enddef
538 Line 3
539 Line 4
540 END
541 call setline(1, lines)
542 3,6source
543 call assert_equal('5', Xtestfunc())
544 delfunc Xtestfunc
545
546 " test for sourcing a heredoc
547 %d _
548 let lines =<< trim END
549 vim9script
550 var a = 1
551 g:heredoc =<< trim DATA
552 red
553 green
554 blue
555 DATA
556 var b = 2
557 END
558 call setline(1, lines)
559 source
560 call assert_equal(['red', ' green', 'blue'], g:heredoc)
561
562 " test for using the :vim9cmd modifier
563 %d _
564 let lines =<< trim END
565 first line
566 g:Math = {
567 pi: 3.12,
568 e: 2.71828
569 }
570 g:Editors = [
571 'vim',
572 # comment
573 'nano'
574 ]
575 last line
576 END
577 call setline(1, lines)
578 vim9cmd :2,10source
579 call assert_equal(#{pi: 3.12, e: 2.71828}, g:Math)
580 call assert_equal(['vim', 'nano'], g:Editors)
581
582 " test for using try/catch
583 %d _
584 let lines =<< trim END
585 vim9script
586 g:Trace = '1'
587 try
588 a1 = b1
589 catch
590 g:Trace ..= '2'
591 finally
592 g:Trace ..= '3'
593 endtry
594 END
595 call setline(1, lines)
596 source
597 call assert_equal('123', g:Trace)
598
599 " test with the finish command
600 %d _
601 let lines =<< trim END
602 vim9script
603 g:Color = 'red'
604 finish
605 g:Color = 'blue'
606 END
607 call setline(1, lines)
608 source
609 call assert_equal('red', g:Color)
610
Yegappan Lakshmanan35dc1762022-03-22 12:13:54 +0000611 " test for ++clear argument to clear all the functions/variables
612 %d _
613 let lines =<< trim END
614 g:ScriptVarFound = exists("color")
615 g:MyFuncFound = exists('*Myfunc')
616 if g:MyFuncFound
617 finish
618 endif
619 var color = 'blue'
620 def Myfunc()
621 enddef
622 END
623 call setline(1, lines)
624 vim9cmd source
625 call assert_false(g:MyFuncFound)
626 call assert_false(g:ScriptVarFound)
627 vim9cmd source
628 call assert_true(g:MyFuncFound)
629 call assert_true(g:ScriptVarFound)
630 vim9cmd source ++clear
631 call assert_false(g:MyFuncFound)
632 call assert_false(g:ScriptVarFound)
633 vim9cmd source ++clear
634 call assert_false(g:MyFuncFound)
635 call assert_false(g:ScriptVarFound)
636 call assert_fails('vim9cmd source ++clearx', 'E475:')
637 call assert_fails('vim9cmd source ++abcde', 'E484:')
638
Yegappan Lakshmanan36a5b682022-03-19 12:56:51 +0000639 %bw!
640endfunc
641
Bram Moolenaar9f6277b2020-02-11 22:04:02 +0100642" vim: shiftwidth=2 sts=2 expandtab