packadd_spec.lua 16 KB

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