test_source.vim 14 KB

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