view src/testdir/test_source.vim @ 28139:f34afadbef47 v8.2.4594

patch 8.2.4594: need to write script to a file to be able to source them Commit: https://github.com/vim/vim/commit/36a5b6867bb6c0bd69c8da7d788000ab8a0b0ab0 Author: Yegappan Lakshmanan <yegappan@yahoo.com> Date: Sat Mar 19 12:56:51 2022 +0000 patch 8.2.4594: need to write script to a file to be able to source them Problem: Need to write script to a file to be able to source them. Solution: Make ":source" use lines from the current buffer. (Yegappan Lakshmanan et al., closes #9967)
author Bram Moolenaar <Bram@vim.org>
date Sat, 19 Mar 2022 14:00:03 +0100
parents fc859aea8cec
children e1d1fa6ba1ed
line wrap: on
line source

" Tests for the :source command.

source check.vim
source view_util.vim

func Test_source_autocmd()
  call writefile([
	\ 'let did_source = 1',
	\ ], 'Xsourced')
  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)

  call delete('Xsourced')
  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')
  source! Xsourcehello | echo
  call assert_equal('hello', getline(1))
  call assert_fails('sandbox source! Xsourcehello', 'E48:')
  bwipe!
  call delete('Xsourcehello')
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')
  source XoneScript
  call delete('XoneScript')
  call writefile(['let g:var = s:var'], 'XtwoScript')
  call assert_fails('source XtwoScript', 'E121:')
  call delete('XtwoScript')
endfunc

" When sourcing a vim script, shebang should be ignored.
func Test_source_ignore_shebang()
  call writefile(['#!./xyzabc', 'let g:val=369'], 'Xfile.vim')
  source Xfile.vim
  call assert_equal(g:val, 369)
  call delete('Xfile.vim')
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')
  source Xscript.vim
  call assert_equal('Xscript.vim', g:Sfile)
  call assert_equal('7', g:Slnum)
  call assert_equal('8', g:Sflnum)
  call delete('Xscript.vim')
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')
  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 delete('Xscript.vim')
  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)

  " 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')
  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)
  call delete('Xscript')

  " 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 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())

  %bw!
endfunc

" vim: shiftwidth=2 sts=2 expandtab