blob: b7b0d117538a157e959ab01cebcf92b33fc562c5 [file] [log] [blame] [edit]
" Tests for the :source command.
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('<afile>')
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\<Esc>"], '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 <sfile> in an autocmd and for <slnum> and <sflnum>
func Test_source_autocmd_sfile()
let code =<< trim [CODE]
let g:SfileName = ''
augroup sfiletest
au!
autocmd User UserAutoCmd let g:Sfile = '<sfile>:t'
augroup END
doautocmd User UserAutoCmd
let g:Slnum = expand('<slnum>')
let g:Sflnum = expand('<sflnum>')
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("<sflnum>")
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("<SID>")
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("<SID>")
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("<slnum>")
let i = 1 +
\ 2 +
"\ comment
\ 3
let g:Slnum2 = expand("<slnum>")
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("<SID>")
let g:Slnum1 = expand("<slnum>")
let l =<< trim END
let g:Slnum2 = expand("<slnum>")
let g:ScriptID2 = expand("<SID>")
END
new
call setline(1, l)
source
bw!
let g:ScriptID3 = expand("<SID>")
let g:Slnum3 = expand("<slnum>")
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("<afile>")
au SourcePost * let g:XsourcePost=6
\ | let g:XsourcePostFile = expand("<afile>")
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>): 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("<sflnum>")
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\<CR>"
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 \<NL> ? 'a' : 'b']"]
call writefile(lines, 'XsourceNul', 'D')
edit XsourceNul
source
bwipe!
endfunc
" vim: shiftwidth=2 sts=2 expandtab