" Tests for the :source command. source check.vim source view_util.vim func Test_source_autocmd() call writefile([ \ 'let did_source = 1', \ ], 'Xsourced', 'D') au SourcePre *source* let did_source_pre = 1 au SourcePost *source* let did_source_post = 1 source Xsourced call assert_equal(g:did_source, 1) call assert_equal(g:did_source_pre, 1) call assert_equal(g:did_source_post, 1) au! SourcePre au! SourcePost unlet g:did_source unlet g:did_source_pre unlet g:did_source_post endfunc func Test_source_cmd() au SourceCmd *source* let did_source = expand('') au SourcePre *source* let did_source_pre = 2 au SourcePost *source* let did_source_post = 2 source Xsourced call assert_equal(g:did_source, 'Xsourced') call assert_false(exists('g:did_source_pre')) call assert_equal(g:did_source_post, 2) au! SourceCmd au! SourcePre au! SourcePost endfunc func Test_source_sandbox() new call writefile(["Ohello\"], 'Xsourcehello', 'D') source! Xsourcehello | echo call assert_equal('hello', getline(1)) call assert_fails('sandbox source! Xsourcehello', 'E48:') bwipe! endfunc " When deleting a file and immediately creating a new one the inode may be " recycled. Vim should not recognize it as the same script. func Test_different_script() call writefile(['let s:var = "asdf"'], 'XoneScript', 'D') source XoneScript call writefile(['let g:var = s:var'], 'XtwoScript', 'D') call assert_fails('source XtwoScript', 'E121:') endfunc " When sourcing a vim script, shebang should be ignored. func Test_source_ignore_shebang() call writefile(['#!./xyzabc', 'let g:val=369'], 'Xsisfile.vim', 'D') source Xsisfile.vim call assert_equal(g:val, 369) endfunc " Test for expanding in an autocmd and for and func Test_source_autocmd_sfile() let code =<< trim [CODE] let g:SfileName = '' augroup sfiletest au! autocmd User UserAutoCmd let g:Sfile = ':t' augroup END doautocmd User UserAutoCmd let g:Slnum = expand('') let g:Sflnum = expand('') augroup! sfiletest [CODE] call writefile(code, 'Xscript.vim', 'D') source Xscript.vim call assert_equal('Xscript.vim', g:Sfile) call assert_equal('7', g:Slnum) call assert_equal('8', g:Sflnum) endfunc func Test_source_error() call assert_fails('scriptencoding utf-8', 'E167:') call assert_fails('finish', 'E168:') call assert_fails('scriptversion 2', 'E984:') call assert_fails('source!', 'E471:') new call setline(1, ['', '', '', '']) call assert_fails('1,3source Xscript.vim', 'E481:') call assert_fails('1,3source! Xscript.vim', 'E481:') bw! endfunc " Test for sourcing a script recursively func Test_nested_script() CheckRunVimInTerminal call writefile([':source! Xscript.vim', ''], 'Xscript.vim', 'D') let buf = RunVimInTerminal('', {'rows': 6}) call term_wait(buf) call term_sendkeys(buf, ":set noruler\n") call term_sendkeys(buf, ":source! Xscript.vim\n") call term_wait(buf) call WaitForAssert({-> assert_match('E22: Scripts nested too deep\s*', term_getline(buf, 6))}) call StopVimInTerminal(buf) endfunc " Test for sourcing a script from the current buffer func Test_source_buffer() new " Source a simple script let lines =<< trim END let a = "Test" let b = 20 let c = [1.1] END call setline(1, lines) source call assert_equal(['Test', 20, [1.1]], [g:a, g:b, g:c]) " Source a range of lines in the current buffer %d _ let lines =<< trim END let a = 10 let a += 20 let a += 30 let a += 40 END call setline(1, lines) .source call assert_equal(10, g:a) 3source call assert_equal(40, g:a) 2,3source call assert_equal(90, g:a) " Make sure the script line number is correct when sourcing a range of " lines. %d _ let lines =<< trim END Line 1 Line 2 func Xtestfunc() return expand("") endfunc Line 3 Line 4 END call setline(1, lines) 3,5source call assert_equal('4', Xtestfunc()) delfunc Xtestfunc " Source a script with line continuation lines %d _ let lines =<< trim END let m = [ \ 1, \ 2, \ ] call add(m, 3) END call setline(1, lines) source call assert_equal([1, 2, 3], g:m) " Source a script with line continuation lines and a comment %d _ let lines =<< trim END let m = [ "\ first entry \ 'a', "\ second entry \ 'b', \ ] " third entry call add(m, 'c') END call setline(1, lines) source call assert_equal(['a', 'b', 'c'], g:m) " Source an incomplete line continuation line %d _ let lines =<< trim END let k = [ \ END call setline(1, lines) call assert_fails('source', 'E697:') " Source a function with a for loop %d _ let lines =<< trim END let m = [] " test function func! Xtest() for i in range(5, 7) call add(g:m, i) endfor endfunc call Xtest() END call setline(1, lines) source call assert_equal([5, 6, 7], g:m) " Source an empty buffer %d _ source " test for script local functions and variables let lines =<< trim END let s:var1 = 10 func s:F1() let s:var1 += 1 return s:var1 endfunc func s:F2() endfunc let g:ScriptID = expand("") END call setline(1, lines) source call assert_true(g:ScriptID != '') call assert_true(exists('*' .. g:ScriptID .. 'F1')) call assert_true(exists('*' .. g:ScriptID .. 'F2')) call assert_equal(11, call(g:ScriptID .. 'F1', [])) " the same script ID should be used even if the buffer is sourced more than " once %d _ let lines =<< trim END let g:ScriptID = expand("") let g:Count += 1 END call setline(1, lines) let g:Count = 0 source call assert_true(g:ScriptID != '') let scid = g:ScriptID source call assert_equal(scid, g:ScriptID) call assert_equal(2, g:Count) source call assert_equal(scid, g:ScriptID) call assert_equal(3, g:Count) " test for the script line number %d _ let lines =<< trim END " comment let g:Slnum1 = expand("") let i = 1 + \ 2 + "\ comment \ 3 let g:Slnum2 = expand("") END call setline(1, lines) source call assert_equal('2', g:Slnum1) call assert_equal('7', g:Slnum2) " test for retaining the same script number across source calls let lines =<< trim END let g:ScriptID1 = expand("") let g:Slnum1 = expand("") let l =<< trim END let g:Slnum2 = expand("") let g:ScriptID2 = expand("") END new call setline(1, l) source bw! let g:ScriptID3 = expand("") let g:Slnum3 = expand("") END call writefile(lines, 'Xscript', 'D') source Xscript call assert_true(g:ScriptID1 != g:ScriptID2) call assert_equal(g:ScriptID1, g:ScriptID3) call assert_equal('2', g:Slnum1) call assert_equal('1', g:Slnum2) call assert_equal('12', g:Slnum3) " test for sourcing a heredoc %d _ let lines =<< trim END let a = 1 let heredoc =<< trim DATA red green blue DATA let b = 2 END call setline(1, lines) source call assert_equal(['red', ' green', 'blue'], g:heredoc) " test for a while and for statement %d _ let lines =<< trim END let a = 0 let b = 1 while b <= 10 let a += 10 let b += 1 endwhile for i in range(5) let a += 10 endfor END call setline(1, lines) source call assert_equal(150, g:a) " test for sourcing the same buffer multiple times after changing a function %d _ let lines =<< trim END func Xtestfunc() return "one" endfunc END call setline(1, lines) source call assert_equal("one", Xtestfunc()) call setline(2, ' return "two"') source call assert_equal("two", Xtestfunc()) call setline(2, ' return "three"') source call assert_equal("three", Xtestfunc()) delfunc Xtestfunc " test for using try/catch %d _ let lines =<< trim END let Trace = '1' try let a1 = b1 catch let Trace ..= '2' finally let Trace ..= '3' endtry END call setline(1, lines) source call assert_equal("123", g:Trace) " test with the finish command %d _ let lines =<< trim END let g:Color = 'blue' finish let g:Color = 'green' END call setline(1, lines) source call assert_equal('blue', g:Color) " Test for the SourcePre and SourcePost autocmds augroup Xtest au! au SourcePre * let g:XsourcePre=4 \ | let g:XsourcePreFile = expand("") au SourcePost * let g:XsourcePost=6 \ | let g:XsourcePostFile = expand("") augroup END %d _ let lines =<< trim END let a = 1 END call setline(1, lines) source call assert_equal(4, g:XsourcePre) call assert_equal(6, g:XsourcePost) call assert_equal(':source buffer=' .. bufnr(), g:XsourcePreFile) call assert_equal(':source buffer=' .. bufnr(), g:XsourcePostFile) augroup Xtest au! augroup END augroup! Xtest %bw! endfunc " Test for sourcing a Vim9 script from the current buffer func Test_source_buffer_vim9() new " test for sourcing a Vim9 script %d _ let lines =<< trim END vim9script # check dict var x: number = 10 def g:Xtestfunc(): number return x enddef END call setline(1, lines) source call assert_equal(10, Xtestfunc()) " test for sourcing a vim9 script with line continuation %d _ let lines =<< trim END vim9script g:Str1 = "hello " .. "world" .. ", how are you?" g:Colors = [ 'red', # comment 'blue' ] g:Dict = { a: 22, # comment b: 33 } # calling a function with line continuation def Sum(...values: list): number var sum: number = 0 for v in values sum += v endfor return sum enddef g:Total1 = Sum(10, 20, 30) var i: number = 0 while i < 10 # while loop i += 1 endwhile g:Count1 = i # for loop g:Count2 = 0 for j in range(10, 20) g:Count2 += i endfor g:Total2 = 10 + 20 - 5 g:Result1 = g:Total2 > 1 ? 'red' : 'blue' g:Str2 = 'x' ->repeat(10) ->trim() ->strpart(4) g:Result2 = g:Dict .a augroup Test au! au BufNewFile Xsubfile g:readFile = 1 | g:readExtra = 2 augroup END g:readFile = 0 g:readExtra = 0 new Xsubfile bwipe! augroup Test au! augroup END END call setline(1, lines) source call assert_equal("hello world, how are you?", g:Str1) call assert_equal(['red', 'blue'], g:Colors) call assert_equal(#{a: 22, b: 33}, g:Dict) call assert_equal(60, g:Total1) call assert_equal(10, g:Count1) call assert_equal(110, g:Count2) call assert_equal(25, g:Total2) call assert_equal('red', g:Result1) call assert_equal('xxxxxx', g:Str2) call assert_equal(22, g:Result2) call assert_equal(1, g:readFile) call assert_equal(2, g:readExtra) " test for sourcing the same buffer multiple times after changing a function %d _ let lines =<< trim END vim9script def g:Xtestfunc(): string return "one" enddef END call setline(1, lines) source call assert_equal("one", Xtestfunc()) call setline(3, ' return "two"') source call assert_equal("two", Xtestfunc()) call setline(3, ' return "three"') source call assert_equal("three", Xtestfunc()) delfunc Xtestfunc " Test for sourcing a range of lines. Make sure the script line number is " correct. %d _ let lines =<< trim END Line 1 Line 2 vim9script def g:Xtestfunc(): string return expand("") enddef Line 3 Line 4 END call setline(1, lines) 3,6source call assert_equal('5', Xtestfunc()) delfunc Xtestfunc " test for sourcing a heredoc %d _ let lines =<< trim END vim9script var a = 1 g:heredoc =<< trim DATA red green blue DATA var b = 2 END call setline(1, lines) source call assert_equal(['red', ' green', 'blue'], g:heredoc) " test for using the :vim9cmd modifier %d _ let lines =<< trim END first line g:Math = { pi: 3.12, e: 2.71828 } g:Editors = [ 'vim', # comment 'nano' ] last line END call setline(1, lines) vim9cmd :2,10source call assert_equal(#{pi: 3.12, e: 2.71828}, g:Math) call assert_equal(['vim', 'nano'], g:Editors) " '<,'> range before the cmd modifier works unlet g:Math unlet g:Editors exe "normal 6GV4j:vim9cmd source\" call assert_equal(['vim', 'nano'], g:Editors) unlet g:Editors " test for using try/catch %d _ let lines =<< trim END vim9script g:Trace = '1' try a1 = b1 catch g:Trace ..= '2' finally g:Trace ..= '3' endtry END call setline(1, lines) source call assert_equal('123', g:Trace) " test with the finish command %d _ let lines =<< trim END vim9script g:Color = 'red' finish g:Color = 'blue' END call setline(1, lines) source call assert_equal('red', g:Color) " test for ++clear argument to clear all the functions/variables %d _ let lines =<< trim END g:ScriptVarFound = exists("color") g:MyFuncFound = exists('*Myfunc') if g:MyFuncFound finish endif var color = 'blue' def Myfunc() enddef END call setline(1, lines) vim9cmd source call assert_false(g:MyFuncFound) call assert_false(g:ScriptVarFound) vim9cmd source call assert_true(g:MyFuncFound) call assert_true(g:ScriptVarFound) vim9cmd source ++clear call assert_false(g:MyFuncFound) call assert_false(g:ScriptVarFound) vim9cmd source ++clear call assert_false(g:MyFuncFound) call assert_false(g:ScriptVarFound) call assert_fails('vim9cmd source ++clearx', 'E475:') call assert_fails('vim9cmd source ++abcde', 'E484:') %bw! endfunc func Test_source_buffer_long_line() " This was reading past the end of the line. new norm300gr0 so bwipe! let lines =<< trim END new norm 10a0000000000ΓΈ00000000000 norm i0000000000000000000 silent! so END call writefile(lines, 'Xtest.vim', 'D') source Xtest.vim bwipe! endfunc func Test_source_buffer_with_NUL_char() " This was trying to use a line below the buffer. let lines =<< trim END if !exists('g:loaded') let g:loaded = 1 source endif END " Can't have a NL in heredoc let lines += ["silent! vim9 echo [0 \ ? 'a' : 'b']"] call writefile(lines, 'XsourceNul', 'D') edit XsourceNul source bwipe! endfunc " vim: shiftwidth=2 sts=2 expandtab