packadd_spec.lua 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493
  1. -- Tests for 'packpath' and :packadd
  2. local helpers = require('test.functional.helpers')(after_each)
  3. local clear, source, command = helpers.clear, helpers.source, helpers.command
  4. local call, eq, nvim = helpers.call, helpers.eq, helpers.meths
  5. local feed = helpers.feed
  6. local function expected_empty()
  7. eq({}, nvim.get_vvar('errors'))
  8. end
  9. describe('packadd', function()
  10. before_each(function()
  11. clear()
  12. source([=[
  13. func Escape(s)
  14. return escape(a:s, '\~')
  15. endfunc
  16. func SetUp()
  17. let s:topdir = expand(getcwd() . '/Xdir')
  18. exe 'set packpath=' . s:topdir
  19. let s:plugdir = expand(s:topdir . '/pack/mine/opt/mytest')
  20. endfunc
  21. func TearDown()
  22. call delete(s:topdir, 'rf')
  23. endfunc
  24. func Test_packadd()
  25. if !exists('s:plugdir')
  26. echomsg 'when running this test manually, call SetUp() first'
  27. return
  28. endif
  29. call mkdir(s:plugdir . '/plugin/also', 'p')
  30. call mkdir(s:plugdir . '/ftdetect', 'p')
  31. call mkdir(s:plugdir . '/after', 'p')
  32. set rtp&
  33. let rtp = &rtp
  34. filetype on
  35. let rtp_entries = split(rtp, ',')
  36. for entry in rtp_entries
  37. if entry =~? '\<after\>'
  38. let first_after_entry = entry
  39. break
  40. endif
  41. endfor
  42. exe 'split ' . s:plugdir . '/plugin/test.vim'
  43. call setline(1, 'let g:plugin_works = 42')
  44. wq
  45. exe 'split ' . s:plugdir . '/plugin/also/loaded.vim'
  46. call setline(1, 'let g:plugin_also_works = 77')
  47. wq
  48. exe 'split ' . s:plugdir . '/ftdetect/test.vim'
  49. call setline(1, 'let g:ftdetect_works = 17')
  50. wq
  51. packadd mytest
  52. call assert_true(42, g:plugin_works)
  53. call assert_equal(77, g:plugin_also_works)
  54. call assert_true(17, g:ftdetect_works)
  55. call assert_true(len(&rtp) > len(rtp))
  56. call assert_match(Escape(s:plugdir) . '\($\|,\)', &rtp)
  57. let new_after = match(&rtp, Escape(expand(s:plugdir . '/after') . ','))
  58. let forwarded = substitute(first_after_entry, '\\', '[/\\\\]', 'g')
  59. let old_after = match(&rtp, ',' . escape(forwarded, '~') . '\>')
  60. call assert_true(new_after > 0, 'rtp is ' . &rtp)
  61. call assert_true(old_after > 0, 'match ' . forwarded . ' in ' . &rtp)
  62. call assert_true(new_after < old_after, 'rtp is ' . &rtp)
  63. " NOTE: '/.../opt/myte' forwardly matches with '/.../opt/mytest'
  64. call mkdir(fnamemodify(s:plugdir, ':h') . '/myte', 'p')
  65. let rtp = &rtp
  66. packadd myte
  67. " Check the path of 'myte' is added
  68. call assert_true(len(&rtp) > len(rtp))
  69. call assert_match(Escape(s:plugdir) . '\($\|,\)', &rtp)
  70. " Check exception
  71. call assert_fails("packadd directorynotfound", 'E919:')
  72. call assert_fails("packadd", 'E471:')
  73. endfunc
  74. func Test_packadd_start()
  75. let plugdir = expand(s:topdir . '/pack/mine/start/other')
  76. call mkdir(plugdir . '/plugin', 'p')
  77. set rtp&
  78. let rtp = &rtp
  79. filetype on
  80. exe 'split ' . plugdir . '/plugin/test.vim'
  81. call setline(1, 'let g:plugin_works = 24')
  82. wq
  83. packadd other
  84. call assert_equal(24, g:plugin_works)
  85. call assert_true(len(&rtp) > len(rtp))
  86. call assert_match(Escape(plugdir) . '\($\|,\)', &rtp)
  87. endfunc
  88. func Test_packadd_noload()
  89. call mkdir(s:plugdir . '/plugin', 'p')
  90. call mkdir(s:plugdir . '/syntax', 'p')
  91. set rtp&
  92. let rtp = &rtp
  93. exe 'split ' . s:plugdir . '/plugin/test.vim'
  94. call setline(1, 'let g:plugin_works = 42')
  95. wq
  96. let g:plugin_works = 0
  97. packadd! mytest
  98. call assert_true(len(&rtp) > len(rtp))
  99. call assert_match(Escape(s:plugdir) . '\($\|,\)', &rtp)
  100. call assert_equal(0, g:plugin_works)
  101. " check the path is not added twice
  102. let new_rtp = &rtp
  103. packadd! mytest
  104. call assert_equal(new_rtp, &rtp)
  105. endfunc
  106. func Test_packadd_symlink_dir()
  107. let top2_dir = expand(s:topdir . '/Xdir2')
  108. let real_dir = expand(s:topdir . '/Xsym')
  109. call mkdir(real_dir, 'p')
  110. if has('win32')
  111. exec "silent! !mklink /d" top2_dir "Xsym"
  112. else
  113. exec "silent! !ln -s Xsym" top2_dir
  114. endif
  115. let &rtp = top2_dir . ',' . expand(top2_dir . '/after')
  116. let &packpath = &rtp
  117. let s:plugdir = expand(top2_dir . '/pack/mine/opt/mytest')
  118. call mkdir(s:plugdir . '/plugin', 'p')
  119. exe 'split ' . s:plugdir . '/plugin/test.vim'
  120. call setline(1, 'let g:plugin_works = 44')
  121. wq
  122. let g:plugin_works = 0
  123. packadd mytest
  124. " Must have been inserted in the middle, not at the end
  125. call assert_match(Escape(expand('/pack/mine/opt/mytest').','), &rtp)
  126. call assert_equal(44, g:plugin_works)
  127. " No change when doing it again.
  128. let rtp_before = &rtp
  129. packadd mytest
  130. call assert_equal(rtp_before, &rtp)
  131. set rtp&
  132. let rtp = &rtp
  133. exec "silent !" (has('win32') ? "rd /q/s" : "rm") top2_dir
  134. endfunc
  135. func Test_packadd_symlink_dir2()
  136. let top2_dir = expand(s:topdir . '/Xdir2')
  137. let real_dir = expand(s:topdir . '/Xsym/pack')
  138. call mkdir(top2_dir, 'p')
  139. call mkdir(real_dir, 'p')
  140. let &rtp = top2_dir . ',' . top2_dir . '/after'
  141. let &packpath = &rtp
  142. if has('win32')
  143. exec "silent! !mklink /d" top2_dir "Xsym"
  144. else
  145. exec "silent !ln -s ../Xsym/pack" top2_dir . '/pack'
  146. endif
  147. let s:plugdir = expand(top2_dir . '/pack/mine/opt/mytest')
  148. call mkdir(s:plugdir . '/plugin', 'p')
  149. exe 'split ' . s:plugdir . '/plugin/test.vim'
  150. call setline(1, 'let g:plugin_works = 48')
  151. wq
  152. let g:plugin_works = 0
  153. packadd mytest
  154. " Must have been inserted in the middle, not at the end
  155. call assert_match(Escape(expand('/Xdir2/pack/mine/opt/mytest').','), &rtp)
  156. call assert_equal(48, g:plugin_works)
  157. " No change when doing it again.
  158. let rtp_before = &rtp
  159. packadd mytest
  160. call assert_equal(rtp_before, &rtp)
  161. set rtp&
  162. let rtp = &rtp
  163. if has('win32')
  164. exec "silent !rd /q/s" top2_dir
  165. else
  166. exec "silent !rm" top2_dir . '/pack'
  167. exec "silent !rmdir" top2_dir
  168. endif
  169. endfunc
  170. func Test_packloadall()
  171. " plugin foo with an autoload directory
  172. let fooplugindir = &packpath . '/pack/mine/start/foo/plugin'
  173. call mkdir(fooplugindir, 'p')
  174. call writefile(['let g:plugin_foo_number = 1234',
  175. \ 'let g:plugin_foo_auto = bbb#value',
  176. \ 'let g:plugin_extra_auto = extra#value'], fooplugindir . '/bar.vim')
  177. let fooautodir = &packpath . '/pack/mine/start/foo/autoload'
  178. call mkdir(fooautodir, 'p')
  179. call writefile(['let bar#value = 77'], fooautodir . '/bar.vim')
  180. " plugin aaa with an autoload directory
  181. let aaaplugindir = &packpath . '/pack/mine/start/aaa/plugin'
  182. call mkdir(aaaplugindir, 'p')
  183. call writefile(['let g:plugin_aaa_number = 333',
  184. \ 'let g:plugin_aaa_auto = bar#value'], aaaplugindir . '/bbb.vim')
  185. let aaaautodir = &packpath . '/pack/mine/start/aaa/autoload'
  186. call mkdir(aaaautodir, 'p')
  187. call writefile(['let bbb#value = 55'], aaaautodir . '/bbb.vim')
  188. " plugin extra with only an autoload directory
  189. let extraautodir = &packpath . '/pack/mine/start/extra/autoload'
  190. call mkdir(extraautodir, 'p')
  191. call writefile(['let extra#value = 99'], extraautodir . '/extra.vim')
  192. packloadall
  193. call assert_equal(1234, g:plugin_foo_number)
  194. call assert_equal(55, g:plugin_foo_auto)
  195. call assert_equal(99, g:plugin_extra_auto)
  196. call assert_equal(333, g:plugin_aaa_number)
  197. call assert_equal(77, g:plugin_aaa_auto)
  198. " only works once
  199. call writefile(['let g:plugin_bar_number = 4321'],
  200. \ fooplugindir . '/bar2.vim')
  201. packloadall
  202. call assert_false(exists('g:plugin_bar_number'))
  203. " works when ! used
  204. packloadall!
  205. call assert_equal(4321, g:plugin_bar_number)
  206. endfunc
  207. func Test_helptags()
  208. let docdir1 = &packpath . '/pack/mine/start/foo/doc'
  209. let docdir2 = &packpath . '/pack/mine/start/bar/doc'
  210. call mkdir(docdir1, 'p')
  211. call mkdir(docdir2, 'p')
  212. call writefile(['look here: *look-here*'], docdir1 . '/bar.txt')
  213. call writefile(['look away: *look-away*'], docdir2 . '/foo.txt')
  214. exe 'set rtp=' . &packpath . '/pack/mine/start/foo,' . &packpath . '/pack/mine/start/bar'
  215. helptags ALL
  216. let tags1 = readfile(docdir1 . '/tags')
  217. call assert_match('look-here', tags1[0])
  218. let tags2 = readfile(docdir2 . '/tags')
  219. call assert_match('look-away', tags2[0])
  220. endfunc
  221. func Test_colorscheme()
  222. let colordirrun = &packpath . '/runtime/colors'
  223. let colordirstart = &packpath . '/pack/mine/start/foo/colors'
  224. let colordiropt = &packpath . '/pack/mine/opt/bar/colors'
  225. call mkdir(colordirrun, 'p')
  226. call mkdir(colordirstart, 'p')
  227. call mkdir(colordiropt, 'p')
  228. call writefile(['let g:found_one = 1'], colordirrun . '/one.vim')
  229. call writefile(['let g:found_two = 1'], colordirstart . '/two.vim')
  230. call writefile(['let g:found_three = 1'], colordiropt . '/three.vim')
  231. exe 'set rtp=' . &packpath . '/runtime'
  232. colorscheme one
  233. call assert_equal(1, g:found_one)
  234. colorscheme two
  235. call assert_equal(1, g:found_two)
  236. colorscheme three
  237. call assert_equal(1, g:found_three)
  238. endfunc
  239. func Test_runtime()
  240. let rundir = &packpath . '/runtime/extra'
  241. let startdir = &packpath . '/pack/mine/start/foo/extra'
  242. let optdir = &packpath . '/pack/mine/opt/bar/extra'
  243. call mkdir(rundir, 'p')
  244. call mkdir(startdir, 'p')
  245. call mkdir(optdir, 'p')
  246. call writefile(['let g:sequence .= "run"'], rundir . '/bar.vim')
  247. call writefile(['let g:sequence .= "start"'], startdir . '/bar.vim')
  248. call writefile(['let g:sequence .= "foostart"'], startdir . '/foo.vim')
  249. call writefile(['let g:sequence .= "opt"'], optdir . '/bar.vim')
  250. call writefile(['let g:sequence .= "xxxopt"'], optdir . '/xxx.vim')
  251. exe 'set rtp=' . &packpath . '/runtime'
  252. let g:sequence = ''
  253. runtime extra/bar.vim
  254. call assert_equal('run', g:sequence)
  255. let g:sequence = ''
  256. runtime START extra/bar.vim
  257. call assert_equal('start', g:sequence)
  258. let g:sequence = ''
  259. runtime OPT extra/bar.vim
  260. call assert_equal('opt', g:sequence)
  261. let g:sequence = ''
  262. runtime PACK extra/bar.vim
  263. call assert_equal('start', g:sequence)
  264. let g:sequence = ''
  265. runtime! PACK extra/bar.vim
  266. call assert_equal('startopt', g:sequence)
  267. let g:sequence = ''
  268. runtime PACK extra/xxx.vim
  269. call assert_equal('xxxopt', g:sequence)
  270. let g:sequence = ''
  271. runtime ALL extra/bar.vim
  272. call assert_equal('run', g:sequence)
  273. let g:sequence = ''
  274. runtime ALL extra/foo.vim
  275. call assert_equal('foostart', g:sequence)
  276. let g:sequence = ''
  277. runtime! ALL extra/xxx.vim
  278. call assert_equal('xxxopt', g:sequence)
  279. let g:sequence = ''
  280. runtime! ALL extra/bar.vim
  281. call assert_equal('runstartopt', g:sequence)
  282. endfunc
  283. ]=])
  284. call('SetUp')
  285. end)
  286. after_each(function()
  287. call('TearDown')
  288. end)
  289. it('is working', function()
  290. call('Test_packadd')
  291. expected_empty()
  292. end)
  293. it('works with packadd!', function()
  294. call('Test_packadd_noload')
  295. expected_empty()
  296. end)
  297. it('works with symlinks', function()
  298. call('Test_packadd_symlink_dir')
  299. expected_empty()
  300. end)
  301. it('works with :packloadall', function()
  302. call('Test_packloadall')
  303. expected_empty()
  304. end)
  305. it('works with helptags', function()
  306. call('Test_helptags')
  307. expected_empty()
  308. end)
  309. it('works with colorschemes', function()
  310. call('Test_colorscheme')
  311. expected_empty()
  312. end)
  313. it('works with :runtime [what]', function()
  314. call('Test_runtime')
  315. expected_empty()
  316. end)
  317. it('loads packages from "start" directory', function()
  318. call('Test_packadd_start')
  319. expected_empty()
  320. end)
  321. describe('command line completion', function()
  322. local Screen = require('test.functional.ui.screen')
  323. local screen
  324. before_each(function()
  325. screen = Screen.new(30, 5)
  326. screen:attach()
  327. screen:set_default_attr_ids({
  328. [0] = {bold=true, foreground=Screen.colors.Blue},
  329. [1] = {
  330. foreground = Screen.colors.Black,
  331. background = Screen.colors.Yellow,
  332. },
  333. [2] = {bold = true, reverse = true}
  334. })
  335. command([[let optdir1 = &packpath . '/pack/mine/opt']])
  336. command([[let optdir2 = &packpath . '/pack/candidate/opt']])
  337. command([[call mkdir(optdir1 . '/pluginA', 'p')]])
  338. command([[call mkdir(optdir1 . '/pluginC', 'p')]])
  339. command([[call mkdir(optdir2 . '/pluginB', 'p')]])
  340. command([[call mkdir(optdir2 . '/pluginC', 'p')]])
  341. end)
  342. it('works', function()
  343. feed(':packadd <Tab>')
  344. screen:expect([=[
  345. |
  346. {0:~ }|
  347. {0:~ }|
  348. {1:pluginA}{2: pluginB pluginC }|
  349. :packadd pluginA^ |
  350. ]=])
  351. feed('<Tab>')
  352. screen:expect([=[
  353. |
  354. {0:~ }|
  355. {0:~ }|
  356. {2:pluginA }{1:pluginB}{2: pluginC }|
  357. :packadd pluginB^ |
  358. ]=])
  359. feed('<Tab>')
  360. screen:expect([=[
  361. |
  362. {0:~ }|
  363. {0:~ }|
  364. {2:pluginA pluginB }{1:pluginC}{2: }|
  365. :packadd pluginC^ |
  366. ]=])
  367. feed('<Tab>')
  368. screen:expect([=[
  369. |
  370. {0:~ }|
  371. {0:~ }|
  372. {2:pluginA pluginB pluginC }|
  373. :packadd ^ |
  374. ]=])
  375. end)
  376. it('works for colorschemes', function()
  377. source([[
  378. let colordirrun = &packpath . '/runtime/colors'
  379. let colordirstart = &packpath . '/pack/mine/start/foo/colors'
  380. let colordiropt = &packpath . '/pack/mine/opt/bar/colors'
  381. call mkdir(colordirrun, 'p')
  382. call mkdir(colordirstart, 'p')
  383. call mkdir(colordiropt, 'p')
  384. call writefile(['let g:found_one = 1'], colordirrun . '/one.vim')
  385. call writefile(['let g:found_two = 1'], colordirstart . '/two.vim')
  386. call writefile(['let g:found_three = 1'], colordiropt . '/three.vim')
  387. exe 'set rtp=' . &packpath . '/runtime']])
  388. feed(':colorscheme <Tab>')
  389. screen:expect([=[
  390. |
  391. {0:~ }|
  392. {0:~ }|
  393. {1:one}{2: three two }|
  394. :colorscheme one^ |
  395. ]=])
  396. feed('<Tab>')
  397. screen:expect([=[
  398. |
  399. {0:~ }|
  400. {0:~ }|
  401. {2:one }{1:three}{2: two }|
  402. :colorscheme three^ |
  403. ]=])
  404. feed('<Tab>')
  405. screen:expect([=[
  406. |
  407. {0:~ }|
  408. {0:~ }|
  409. {2:one three }{1:two}{2: }|
  410. :colorscheme two^ |
  411. ]=])
  412. feed('<Tab>')
  413. screen:expect([=[
  414. |
  415. {0:~ }|
  416. {0:~ }|
  417. {2:one three two }|
  418. :colorscheme ^ |
  419. ]=])
  420. end)
  421. end)
  422. end)