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