packadd_spec.lua 17 KB

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