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