test_compiler.vim 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714
  1. " Test the :compiler command
  2. source check.vim
  3. source shared.vim
  4. func Test_compiler()
  5. CheckExecutable perl
  6. CheckFeature quickfix
  7. let save_LC_ALL = $LC_ALL
  8. let $LC_ALL= "C"
  9. let save_shellslash = &shellslash
  10. " Nvim doesn't allow setting value of a hidden option to non-default value
  11. if exists('+shellslash')
  12. " %:S does not work properly with 'shellslash' set
  13. set noshellslash
  14. endif
  15. e Xfoo.pl
  16. " Play nice with other tests.
  17. defer setqflist([])
  18. compiler perl
  19. call assert_equal('perl', b:current_compiler)
  20. call assert_fails('let g:current_compiler', 'E121:')
  21. let verbose_efm = execute('verbose set efm')
  22. call assert_match('Last set from .*[/\\]compiler[/\\]perl.vim ', verbose_efm)
  23. call setline(1, ['#!/usr/bin/perl -w', 'use strict;', 'my $foo=1'])
  24. w!
  25. call feedkeys(":make\<CR>\<CR>", 'tx')
  26. call assert_fails('clist', 'E42:')
  27. call setline(1, ['#!/usr/bin/perl -w', 'use strict;', '$foo=1'])
  28. w!
  29. call feedkeys(":make\<CR>\<CR>", 'tx')
  30. let a=execute('clist')
  31. call assert_match('\n \d\+ Xfoo.pl:3: Global symbol "$foo" '
  32. \ . 'requires explicit package name', a)
  33. let &shellslash = save_shellslash
  34. call delete('Xfoo.pl')
  35. bw!
  36. let $LC_ALL = save_LC_ALL
  37. endfunc
  38. func GetCompilerNames()
  39. return glob('$VIMRUNTIME/compiler/*.vim', 0, 1)
  40. \ ->map({i, v -> substitute(v, '.*[\\/]\([a-zA-Z0-9_\-]*\).vim', '\1', '')})
  41. \ ->sort()
  42. endfunc
  43. func Test_compiler_without_arg()
  44. let runtime = substitute($VIMRUNTIME, '\\', '/', 'g')
  45. let a = split(execute('compiler'))
  46. let exp = GetCompilerNames()
  47. call assert_match(runtime .. '/compiler/' .. exp[0] .. '.vim$', a[0])
  48. call assert_match(runtime .. '/compiler/' .. exp[1] .. '.vim$', a[1])
  49. call assert_match(runtime .. '/compiler/' .. exp[-1] .. '.vim$', a[-1])
  50. endfunc
  51. func Test_compiler_completion()
  52. let clist = GetCompilerNames()->join(' ')
  53. call feedkeys(":compiler \<C-A>\<C-B>\"\<CR>", 'tx')
  54. call assert_match('^"compiler ' .. clist .. '$', @:)
  55. call feedkeys(":compiler p\<C-A>\<C-B>\"\<CR>", 'tx')
  56. call assert_match('"compiler pandoc pbx perl\( p[a-z_]\+\)\+ pyunit', @:)
  57. call feedkeys(":compiler! p\<C-A>\<C-B>\"\<CR>", 'tx')
  58. call assert_match('"compiler! pandoc pbx perl\( p[a-z_]\+\)\+ pyunit', @:)
  59. endfunc
  60. func Test_compiler_error()
  61. let g:current_compiler = 'abc'
  62. call assert_fails('compiler doesnotexist', 'E666:')
  63. call assert_equal('abc', g:current_compiler)
  64. call assert_fails('compiler! doesnotexist', 'E666:')
  65. unlet! g:current_compiler
  66. endfunc
  67. func s:SpotBugsParseFilterMakePrg(dirname, makeprg)
  68. let result = {}
  69. let result.sourcepath = ''
  70. let result.classfiles = []
  71. " Get the argument after the rightmost occurrence of "-sourcepath".
  72. let offset = strridx(a:makeprg, '-sourcepath')
  73. if offset < 0
  74. return result
  75. endif
  76. let offset += 1 + strlen('-sourcepath')
  77. let result.sourcepath = matchstr(strpart(a:makeprg, offset), '.\{-}\ze[ \t]')
  78. let offset += 1 + strlen(result.sourcepath)
  79. " Get the class file arguments, dropping the pathname prefix.
  80. let offset = stridx(a:makeprg, a:dirname, offset)
  81. if offset < 0
  82. return result
  83. endif
  84. while offset > -1
  85. let candidate = matchstr(a:makeprg, '[^ \t]\{-}\.class\>', offset)
  86. if empty(candidate)
  87. break
  88. endif
  89. call add(result.classfiles, candidate)
  90. let offset = stridx(a:makeprg, a:dirname, (1 + strlen(candidate) + offset))
  91. endwhile
  92. call sort(result.classfiles)
  93. return result
  94. endfunc
  95. func Test_compiler_spotbugs_makeprg()
  96. let save_shellslash = &shellslash
  97. set shellslash
  98. call assert_true(mkdir('Xspotbugs/src/tests/α/β/γ/δ', 'pR'))
  99. call assert_true(mkdir('Xspotbugs/tests/α/β/γ/δ', 'pR'))
  100. let lines =<< trim END
  101. // EOL comment. /*
  102. abstract class
  103. 𐌂1 /* Multiline comment. */ {
  104. /* Multiline comment. */ // EOL comment. /*
  105. static final String COMMENT_A_LIKE = "/*";
  106. { new Object() {/* Try globbing. */}; }
  107. static { interface 𐌉𐌉1 {} }
  108. static class 𐌂11 { interface 𐌉𐌉2 {} }
  109. }
  110. /* Multiline comment. */ // EOL comment. /*
  111. final class 𐌂2 {
  112. public static void main(String... aa) {
  113. record 𐌓() {}
  114. enum 𐌄 {}
  115. }
  116. } // class
  117. END
  118. " THE EXPECTED RESULTS.
  119. let results = {}
  120. let results['Xspotbugs/src/tests/𐌂1.java'] = {
  121. \ 'Sourcepath': {-> fnamemodify('Xspotbugs/src/tests/𐌂1.java',
  122. \ ':p:h:S')},
  123. \ 'classfiles': sort([
  124. \ 'Xspotbugs/tests/𐌂1$1.class',
  125. \ 'Xspotbugs/tests/𐌂1$1𐌉𐌉1.class',
  126. \ 'Xspotbugs/tests/𐌂1$𐌂11$𐌉𐌉2.class',
  127. \ 'Xspotbugs/tests/𐌂1$𐌂11.class',
  128. \ 'Xspotbugs/tests/𐌂1.class',
  129. \ 'Xspotbugs/tests/𐌂2$1𐌄.class',
  130. \ 'Xspotbugs/tests/𐌂2$1𐌓.class',
  131. \ 'Xspotbugs/tests/𐌂2.class']),
  132. \ }
  133. " No class file for an empty source file even with "-Xpkginfo:always".
  134. let results['Xspotbugs/src/tests/package-info.java'] = {
  135. \ 'Sourcepath': {-> ''},
  136. \ 'classfiles': [],
  137. \ }
  138. let results['Xspotbugs/src/tests/α/𐌂1.java'] = {
  139. \ 'Sourcepath': {-> fnamemodify('Xspotbugs/src/tests/α/𐌂1.java',
  140. \ ':p:h:h:S')},
  141. \ 'classfiles': sort([
  142. \ 'Xspotbugs/tests/α/𐌂1$1.class',
  143. \ 'Xspotbugs/tests/α/𐌂1$1𐌉𐌉1.class',
  144. \ 'Xspotbugs/tests/α/𐌂1$𐌂11$𐌉𐌉2.class',
  145. \ 'Xspotbugs/tests/α/𐌂1$𐌂11.class',
  146. \ 'Xspotbugs/tests/α/𐌂1.class',
  147. \ 'Xspotbugs/tests/α/𐌂2$1𐌄.class',
  148. \ 'Xspotbugs/tests/α/𐌂2$1𐌓.class',
  149. \ 'Xspotbugs/tests/α/𐌂2.class']),
  150. \ }
  151. let results['Xspotbugs/src/tests/α/package-info.java'] = {
  152. \ 'Sourcepath': {-> fnamemodify('Xspotbugs/src/tests/α/package-info.java',
  153. \ ':p:h:S')},
  154. \ 'classfiles': ['Xspotbugs/tests/α/package-info.class'],
  155. \ }
  156. let results['Xspotbugs/src/tests/α/β/𐌂1.java'] = {
  157. \ 'Sourcepath': {-> fnamemodify('Xspotbugs/src/tests/α/β/𐌂1.java',
  158. \ ':p:h:h:h:S')},
  159. \ 'classfiles': sort([
  160. \ 'Xspotbugs/tests/α/β/𐌂1$1.class',
  161. \ 'Xspotbugs/tests/α/β/𐌂1$1𐌉𐌉1.class',
  162. \ 'Xspotbugs/tests/α/β/𐌂1$𐌂11$𐌉𐌉2.class',
  163. \ 'Xspotbugs/tests/α/β/𐌂1$𐌂11.class',
  164. \ 'Xspotbugs/tests/α/β/𐌂1.class',
  165. \ 'Xspotbugs/tests/α/β/𐌂2$1𐌄.class',
  166. \ 'Xspotbugs/tests/α/β/𐌂2$1𐌓.class',
  167. \ 'Xspotbugs/tests/α/β/𐌂2.class']),
  168. \ }
  169. let results['Xspotbugs/src/tests/α/β/package-info.java'] = {
  170. \ 'Sourcepath': {-> fnamemodify('Xspotbugs/src/tests/α/β/package-info.java',
  171. \ ':p:h:S')},
  172. \ 'classfiles': ['Xspotbugs/tests/α/β/package-info.class'],
  173. \ }
  174. let results['Xspotbugs/src/tests/α/β/γ/𐌂1.java'] = {
  175. \ 'Sourcepath': {-> fnamemodify('Xspotbugs/src/tests/α/β/γ/𐌂1.java',
  176. \ ':p:h:h:h:h:S')},
  177. \ 'classfiles': sort([
  178. \ 'Xspotbugs/tests/α/β/γ/𐌂1$1.class',
  179. \ 'Xspotbugs/tests/α/β/γ/𐌂1$1𐌉𐌉1.class',
  180. \ 'Xspotbugs/tests/α/β/γ/𐌂1$𐌂11$𐌉𐌉2.class',
  181. \ 'Xspotbugs/tests/α/β/γ/𐌂1$𐌂11.class',
  182. \ 'Xspotbugs/tests/α/β/γ/𐌂1.class',
  183. \ 'Xspotbugs/tests/α/β/γ/𐌂2$1𐌄.class',
  184. \ 'Xspotbugs/tests/α/β/γ/𐌂2$1𐌓.class',
  185. \ 'Xspotbugs/tests/α/β/γ/𐌂2.class']),
  186. \ }
  187. let results['Xspotbugs/src/tests/α/β/γ/package-info.java'] = {
  188. \ 'Sourcepath': {-> fnamemodify('Xspotbugs/src/tests/α/β/γ/package-info.java',
  189. \ ':p:h:S')},
  190. \ 'classfiles': ['Xspotbugs/tests/α/β/γ/package-info.class'],
  191. \ }
  192. let results['Xspotbugs/src/tests/α/β/γ/δ/𐌂1.java'] = {
  193. \ 'Sourcepath': {-> fnamemodify('Xspotbugs/src/tests/α/β/γ/δ/𐌂1.java',
  194. \ ':p:h:h:h:h:h:S')},
  195. \ 'classfiles': sort([
  196. \ 'Xspotbugs/tests/α/β/γ/δ/𐌂1$1.class',
  197. \ 'Xspotbugs/tests/α/β/γ/δ/𐌂1$1𐌉𐌉1.class',
  198. \ 'Xspotbugs/tests/α/β/γ/δ/𐌂1$𐌂11$𐌉𐌉2.class',
  199. \ 'Xspotbugs/tests/α/β/γ/δ/𐌂1$𐌂11.class',
  200. \ 'Xspotbugs/tests/α/β/γ/δ/𐌂1.class',
  201. \ 'Xspotbugs/tests/α/β/γ/δ/𐌂2$1𐌄.class',
  202. \ 'Xspotbugs/tests/α/β/γ/δ/𐌂2$1𐌓.class',
  203. \ 'Xspotbugs/tests/α/β/γ/δ/𐌂2.class']),
  204. \ }
  205. let results['Xspotbugs/src/tests/α/β/γ/δ/package-info.java'] = {
  206. \ 'Sourcepath': {-> fnamemodify('Xspotbugs/src/tests/α/β/γ/δ/package-info.java',
  207. \ ':p:h:S')},
  208. \ 'classfiles': ['Xspotbugs/tests/α/β/γ/δ/package-info.class'],
  209. \ }
  210. " MAKE CLASS FILES DISCOVERABLE!
  211. let g:spotbugs_properties = {
  212. \ 'sourceDirPath': ['src/tests'],
  213. \ 'classDirPath': ['tests'],
  214. \ }
  215. call assert_true(has_key(s:SpotBugsParseFilterMakePrg('Xspotbugs', ''), 'sourcepath'))
  216. call assert_true(has_key(s:SpotBugsParseFilterMakePrg('Xspotbugs', ''), 'classfiles'))
  217. " Write 45 mock-up class files for 10 source files.
  218. for [class_dir, src_dir, package] in [
  219. \ ['Xspotbugs/tests/', 'Xspotbugs/src/tests/', ''],
  220. \ ['Xspotbugs/tests/α/', 'Xspotbugs/src/tests/α/', 'package α;'],
  221. \ ['Xspotbugs/tests/α/β/', 'Xspotbugs/src/tests/α/β/', 'package α.β;'],
  222. \ ['Xspotbugs/tests/α/β/γ/', 'Xspotbugs/src/tests/α/β/γ/', 'package α.β.γ;'],
  223. \ ['Xspotbugs/tests/α/β/γ/δ/', 'Xspotbugs/src/tests/α/β/γ/δ/', 'package α.β.γ.δ;']]
  224. for class_file in ['𐌂1$1.class', '𐌂1$1𐌉𐌉1.class', '𐌂1$𐌂11$𐌉𐌉2.class',
  225. \ '𐌂1$𐌂11.class', '𐌂1.class', '𐌂2$1𐌄.class', '𐌂2$1𐌓.class', '𐌂2.class']
  226. call writefile(0zcafe.babe.0000.0041, class_dir .. class_file)
  227. endfor
  228. call writefile(0zcafe.babe.0000.0041, class_dir .. 'package-info.class')
  229. " Write Java source files.
  230. let type_file = src_dir .. '𐌂1.java'
  231. call writefile(insert(copy(lines), package), type_file)
  232. let package_file = src_dir .. 'package-info.java'
  233. call writefile([package], src_dir .. 'package-info.java')
  234. " Note that using "off" for the first _outer_ iteration is preferable
  235. " because only then "hlexists()" may be 0 (see "compiler/spotbugs.vim").
  236. for s in ['off', 'on']
  237. execute 'syntax ' .. s
  238. execute 'edit ' .. type_file
  239. compiler spotbugs
  240. let result = s:SpotBugsParseFilterMakePrg('Xspotbugs', &l:makeprg)
  241. call assert_equal(results[type_file].Sourcepath(), result.sourcepath)
  242. call assert_equal(results[type_file].classfiles, result.classfiles)
  243. bwipeout
  244. execute 'edit ' .. package_file
  245. compiler spotbugs
  246. let result = s:SpotBugsParseFilterMakePrg('Xspotbugs', &l:makeprg)
  247. call assert_equal(results[package_file].Sourcepath(), result.sourcepath)
  248. call assert_equal(results[package_file].classfiles, result.classfiles)
  249. bwipeout
  250. endfor
  251. endfor
  252. let &shellslash = save_shellslash
  253. endfunc
  254. func s:SpotBugsBeforeFileTypeTryPluginAndClearCache(state)
  255. " Ponder over "extend(spotbugs#DefaultProperties(), g:spotbugs_properties)"
  256. " in "ftplugin/java.vim".
  257. let g:spotbugs#state = a:state
  258. runtime autoload/spotbugs.vim
  259. endfunc
  260. func Test_compiler_spotbugs_properties()
  261. let save_shellslash = &shellslash
  262. set shellslash
  263. setlocal makeprg=
  264. filetype plugin on
  265. call assert_true(mkdir('Xspotbugs/src', 'pR'))
  266. call assert_true(mkdir('Xspotbugs/tests', 'pR'))
  267. let type_file = 'Xspotbugs/src/𐌄.java'
  268. let test_file = 'Xspotbugs/tests/𐌄$.java'
  269. call writefile(['enum 𐌄{}'], type_file)
  270. call writefile(['class 𐌄${}'], test_file)
  271. " TEST INTEGRATION WITH A BOGUS COMPILER PLUGIN.
  272. if !filereadable($VIMRUNTIME .. '/compiler/foo.vim') && !executable('foo')
  273. let g:spotbugs_properties = {'compiler': 'foo'}
  274. " XXX: In case this "if" block is no longer first.
  275. call s:SpotBugsBeforeFileTypeTryPluginAndClearCache({
  276. \ 'compiler': g:spotbugs_properties.compiler,
  277. \ })
  278. execute 'edit ' .. type_file
  279. call assert_equal('java', &l:filetype)
  280. " This variable will indefinitely keep the compiler name.
  281. call assert_equal('foo', g:spotbugs#state.compiler)
  282. " The "compiler" entry should be gone after FileType and default entries
  283. " should only appear for a supported compiler.
  284. call assert_false(has_key(g:spotbugs_properties, 'compiler'))
  285. call assert_true(empty(g:spotbugs_properties))
  286. " Query default implementations.
  287. call assert_true(exists('*spotbugs#DefaultProperties'))
  288. call assert_true(exists('*spotbugs#DefaultPreCompilerAction'))
  289. call assert_true(exists('*spotbugs#DefaultPreCompilerTestAction'))
  290. call assert_true(empty(spotbugs#DefaultProperties()))
  291. " Get a ":message".
  292. redir => out
  293. call spotbugs#DefaultPreCompilerAction()
  294. redir END
  295. call assert_equal('Not supported: "foo"', out[stridx(out, 'Not') :])
  296. " Get a ":message".
  297. redir => out
  298. call spotbugs#DefaultPreCompilerTestAction()
  299. redir END
  300. call assert_equal('Not supported: "foo"', out[stridx(out, 'Not') :])
  301. " No ":autocmd"s without one of "PreCompiler*Action", "PostCompilerAction".
  302. call assert_false(exists('#java_spotbugs'))
  303. bwipeout
  304. endif
  305. let s:spotbugs_results = {
  306. \ 'preActionDone': 0,
  307. \ 'preTestActionDone': 0,
  308. \ 'preTestLocalActionDone': 0,
  309. \ 'postActionDone': 0,
  310. \ 'preCommandArguments': '',
  311. \ 'preTestCommandArguments': '',
  312. \ 'postCommandArguments': '',
  313. \ }
  314. defer execute('unlet s:spotbugs_results')
  315. func! g:SpotBugsPreAction() abort
  316. let s:spotbugs_results.preActionDone = 1
  317. " XXX: Notify the spotbugs compiler about success or failure.
  318. cc
  319. endfunc
  320. defer execute('delfunction g:SpotBugsPreAction')
  321. func! g:SpotBugsPreTestAction() abort
  322. let s:spotbugs_results.preTestActionDone = 1
  323. " XXX: Let see compilation fail.
  324. throw 'Oops'
  325. endfunc
  326. defer execute('delfunction g:SpotBugsPreTestAction')
  327. func! g:SpotBugsPreTestLocalAction() abort
  328. let s:spotbugs_results.preTestLocalActionDone = 1
  329. " XXX: Notify the spotbugs compiler about success or failure.
  330. cc
  331. endfunc
  332. defer execute('delfunction g:SpotBugsPreTestLocalAction')
  333. func! g:SpotBugsPostAction() abort
  334. let s:spotbugs_results.postActionDone = 1
  335. endfunc
  336. defer execute('delfunction g:SpotBugsPostAction')
  337. func! g:SpotBugsPreCommand(arguments) abort
  338. let s:spotbugs_results.preActionDone = 1
  339. let s:spotbugs_results.preCommandArguments = a:arguments
  340. " XXX: Notify the spotbugs compiler about success or failure.
  341. cc
  342. endfunc
  343. defer execute('delfunction g:SpotBugsPreCommand')
  344. func! g:SpotBugsPreTestCommand(arguments) abort
  345. let s:spotbugs_results.preTestActionDone = 1
  346. let s:spotbugs_results.preTestCommandArguments = a:arguments
  347. " XXX: Notify the spotbugs compiler about success or failure.
  348. cc
  349. endfunc
  350. defer execute('delfunction g:SpotBugsPreTestCommand')
  351. func! g:SpotBugsPostCommand(arguments) abort
  352. let s:spotbugs_results.postActionDone = 1
  353. let s:spotbugs_results.postCommandArguments = a:arguments
  354. endfunc
  355. defer execute('delfunction g:SpotBugsPostCommand')
  356. func! g:SpotBugsPostCompilerActionExecutor(action) abort
  357. try
  358. " XXX: Notify the spotbugs compiler about success or failure.
  359. cc
  360. catch /\<E42:/
  361. execute a:action
  362. endtry
  363. endfunc
  364. defer execute('delfunction g:SpotBugsPostCompilerActionExecutor')
  365. " TEST INTEGRATION WITH A SUPPORTED COMPILER PLUGIN.
  366. if filereadable($VIMRUNTIME .. '/compiler/maven.vim')
  367. let save_PATH = $PATH
  368. if !executable('mvn')
  369. if has('win32')
  370. let $PATH = 'Xspotbugs;' .. $PATH
  371. " This is what ":help executable()" suggests.
  372. call writefile([], 'Xspotbugs/mvn.cmd')
  373. else
  374. let $PATH = 'Xspotbugs:' .. $PATH
  375. call writefile([], 'Xspotbugs/mvn')
  376. call setfperm('Xspotbugs/mvn', 'rwx------')
  377. endif
  378. endif
  379. let g:spotbugs_properties = {
  380. \ 'compiler': 'maven',
  381. \ 'PreCompilerAction': function('g:SpotBugsPreAction'),
  382. \ 'PreCompilerTestAction': function('g:SpotBugsPreTestAction'),
  383. \ 'PostCompilerAction': function('g:SpotBugsPostAction'),
  384. \ }
  385. " XXX: In case this is a runner-up ":edit".
  386. call s:SpotBugsBeforeFileTypeTryPluginAndClearCache({
  387. \ 'compiler': g:spotbugs_properties.compiler,
  388. \ })
  389. execute 'edit ' .. type_file
  390. call assert_equal('java', &l:filetype)
  391. call assert_equal('maven', g:spotbugs#state.compiler)
  392. call assert_false(has_key(g:spotbugs_properties, 'compiler'))
  393. call assert_false(empty(g:spotbugs_properties))
  394. " Query default implementations.
  395. call assert_true(exists('*spotbugs#DefaultProperties'))
  396. call assert_equal(sort([
  397. \ 'PreCompilerAction',
  398. \ 'PreCompilerTestAction',
  399. \ 'PostCompilerAction',
  400. \ 'sourceDirPath',
  401. \ 'classDirPath',
  402. \ 'testSourceDirPath',
  403. \ 'testClassDirPath',
  404. \ ]),
  405. \ sort(keys(spotbugs#DefaultProperties())))
  406. " Some ":autocmd"s with one of "PreCompiler*Action", "PostCompilerAction".
  407. call assert_true(exists('#java_spotbugs'))
  408. call assert_true(exists('#java_spotbugs#Syntax'))
  409. call assert_true(exists('#java_spotbugs#User'))
  410. call assert_equal(2, exists(':SpotBugsDefineBufferAutocmd'))
  411. " SpotBugsDefineBufferAutocmd SigUSR1 User SigUSR1 User SigUSR1 User
  412. " call assert_true(exists('#java_spotbugs#SigUSR1'))
  413. SpotBugsDefineBufferAutocmd Signal User Signal User Signal User
  414. call assert_true(exists('#java_spotbugs#Signal'))
  415. call assert_true(exists('#java_spotbugs#Syntax'))
  416. call assert_true(exists('#java_spotbugs#User'))
  417. call assert_equal(2, exists(':SpotBugsRemoveBufferAutocmd'))
  418. " SpotBugsRemoveBufferAutocmd SigUSR1 User SigUSR1 User UserGettingBored
  419. " call assert_false(exists('#java_spotbugs#SigUSR1'))
  420. SpotBugsRemoveBufferAutocmd Signal User Signal User UserGettingBored
  421. call assert_false(exists('#java_spotbugs#Signal'))
  422. call assert_true(exists('#java_spotbugs#Syntax'))
  423. call assert_true(exists('#java_spotbugs#User'))
  424. let s:spotbugs_results.preActionDone = 0
  425. let s:spotbugs_results.preTestActionDone = 0
  426. let s:spotbugs_results.postActionDone = 0
  427. doautocmd java_spotbugs Syntax
  428. call assert_false(exists('#java_spotbugs#Syntax'))
  429. " No match: "type_file !~# 'src/main/java'".
  430. call assert_false(s:spotbugs_results.preActionDone)
  431. " No match: "type_file !~# 'src/test/java'".
  432. call assert_false(s:spotbugs_results.preTestActionDone)
  433. " No pre-match, no post-action.
  434. call assert_false(s:spotbugs_results.postActionDone)
  435. " Without a match, confirm that ":compiler spotbugs" has NOT run.
  436. call assert_true(empty(&l:makeprg))
  437. let s:spotbugs_results.preActionDone = 0
  438. let s:spotbugs_results.preTestActionDone = 0
  439. let s:spotbugs_results.postActionDone = 0
  440. " Update path entries. (Note that we cannot use just "src" because there
  441. " is another "src" directory nearer the filesystem root directory, i.e.
  442. " "vim/vim/src/testdir/Xspotbugs/src", and "s:DispatchAction()" (see
  443. " "ftplugin/java.vim") will match "vim/vim/src/testdir/Xspotbugs/tests"
  444. " against "src".)
  445. let g:spotbugs_properties.sourceDirPath = ['Xspotbugs/src']
  446. let g:spotbugs_properties.classDirPath = ['Xspotbugs/src']
  447. let g:spotbugs_properties.testSourceDirPath = ['tests']
  448. let g:spotbugs_properties.testClassDirPath = ['tests']
  449. doautocmd java_spotbugs User
  450. " No match: "type_file !~# 'src/main/java'" (with old "*DirPath" values
  451. " cached).
  452. call assert_false(s:spotbugs_results.preActionDone)
  453. " No match: "type_file !~# 'src/test/java'" (with old "*DirPath" values
  454. " cached).
  455. call assert_false(s:spotbugs_results.preTestActionDone)
  456. " No pre-match, no post-action.
  457. call assert_false(s:spotbugs_results.postActionDone)
  458. " Without a match, confirm that ":compiler spotbugs" has NOT run.
  459. call assert_true(empty(&l:makeprg))
  460. let s:spotbugs_results.preActionDone = 0
  461. let s:spotbugs_results.preTestActionDone = 0
  462. let s:spotbugs_results.postActionDone = 0
  463. " XXX: Re-build ":autocmd"s from scratch with new values applied.
  464. doautocmd FileType
  465. call assert_true(exists('b:spotbugs_syntax_once'))
  466. doautocmd java_spotbugs User
  467. " A match: "type_file =~# 'Xspotbugs/src'" (with new "*DirPath" values
  468. " cached).
  469. call assert_true(s:spotbugs_results.preActionDone)
  470. " No match: "type_file !~# 'tests'" (with new "*DirPath" values cached).
  471. call assert_false(s:spotbugs_results.preTestActionDone)
  472. " For a pre-match, a post-action.
  473. call assert_true(s:spotbugs_results.postActionDone)
  474. " With a match, confirm that ":compiler spotbugs" has run.
  475. if has('win32')
  476. call assert_match('^spotbugs\.bat\s', &l:makeprg)
  477. else
  478. call assert_match('^spotbugs\s', &l:makeprg)
  479. endif
  480. bwipeout
  481. setlocal makeprg=
  482. let s:spotbugs_results.preActionDone = 0
  483. let s:spotbugs_results.preTestActionDone = 0
  484. let s:spotbugs_results.preTestLocalActionDone = 0
  485. let s:spotbugs_results.postActionDone = 0
  486. execute 'edit ' .. test_file
  487. " Prepare a buffer-local, incomplete variant of properties, relying on
  488. " "ftplugin/java.vim" to take care of merging in unique entries, if any,
  489. " from "g:spotbugs_properties".
  490. let b:spotbugs_properties = {
  491. \ 'PreCompilerTestAction': function('g:SpotBugsPreTestLocalAction'),
  492. \ }
  493. call assert_equal('java', &l:filetype)
  494. call assert_true(exists('#java_spotbugs'))
  495. call assert_true(exists('#java_spotbugs#Syntax'))
  496. call assert_true(exists('#java_spotbugs#User'))
  497. call assert_fails('doautocmd java_spotbugs Syntax', 'Oops')
  498. call assert_false(exists('#java_spotbugs#Syntax'))
  499. " No match: "test_file !~# 'Xspotbugs/src'".
  500. call assert_false(s:spotbugs_results.preActionDone)
  501. " A match: "test_file =~# 'tests'".
  502. call assert_true(s:spotbugs_results.preTestActionDone)
  503. call assert_false(s:spotbugs_results.preTestLocalActionDone)
  504. " No action after pre-failure (the thrown "Oops" doesn't qualify for ":cc").
  505. call assert_false(s:spotbugs_results.postActionDone)
  506. " No ":compiler spotbugs" will be run after pre-failure.
  507. call assert_true(empty(&l:makeprg))
  508. let s:spotbugs_results.preActionDone = 0
  509. let s:spotbugs_results.preTestActionDone = 0
  510. let s:spotbugs_results.preTestLocalActionDone = 0
  511. let s:spotbugs_results.postActionDone = 0
  512. " XXX: Re-build ":autocmd"s from scratch with buffer-local values applied.
  513. doautocmd FileType
  514. call assert_true(exists('b:spotbugs_syntax_once'))
  515. doautocmd java_spotbugs User
  516. " No match: "test_file !~# 'Xspotbugs/src'".
  517. call assert_false(s:spotbugs_results.preActionDone)
  518. " A match: "test_file =~# 'tests'".
  519. call assert_true(s:spotbugs_results.preTestLocalActionDone)
  520. call assert_false(s:spotbugs_results.preTestActionDone)
  521. " For a pre-match, a post-action.
  522. call assert_true(s:spotbugs_results.postActionDone)
  523. " With a match, confirm that ":compiler spotbugs" has run.
  524. if has('win32')
  525. call assert_match('^spotbugs\.bat\s', &l:makeprg)
  526. else
  527. call assert_match('^spotbugs\s', &l:makeprg)
  528. endif
  529. setlocal makeprg=
  530. let s:spotbugs_results.preActionDone = 0
  531. let s:spotbugs_results.preTestActionDone = 0
  532. let s:spotbugs_results.preTestLocalActionDone = 0
  533. let s:spotbugs_results.postActionDone = 0
  534. let s:spotbugs_results.preCommandArguments = ''
  535. let s:spotbugs_results.preTestCommandArguments = ''
  536. let s:spotbugs_results.postCommandArguments = ''
  537. " XXX: Compose the assigned "*Command"s with the default Maven "*Action"s.
  538. let b:spotbugs_properties = {
  539. \ 'compiler': 'maven',
  540. \ 'DefaultPreCompilerTestCommand': function('g:SpotBugsPreTestCommand'),
  541. \ 'DefaultPreCompilerCommand': function('g:SpotBugsPreCommand'),
  542. \ 'DefaultPostCompilerCommand': function('g:SpotBugsPostCommand'),
  543. \ 'PostCompilerActionExecutor': function('g:SpotBugsPostCompilerActionExecutor'),
  544. \ 'augroupForPostCompilerAction': 'java_spotbugs_test',
  545. \ 'sourceDirPath': ['Xspotbugs/src'],
  546. \ 'classDirPath': ['Xspotbugs/src'],
  547. \ 'testSourceDirPath': ['tests'],
  548. \ 'testClassDirPath': ['tests'],
  549. \ }
  550. unlet g:spotbugs_properties
  551. " XXX: Re-build ":autocmd"s from scratch with buffer-local values applied.
  552. call s:SpotBugsBeforeFileTypeTryPluginAndClearCache({
  553. \ 'compiler': b:spotbugs_properties.compiler,
  554. \ 'commands': {
  555. \ 'DefaultPreCompilerTestCommand':
  556. \ b:spotbugs_properties.DefaultPreCompilerTestCommand,
  557. \ 'DefaultPreCompilerCommand':
  558. \ b:spotbugs_properties.DefaultPreCompilerCommand,
  559. \ 'DefaultPostCompilerCommand':
  560. \ b:spotbugs_properties.DefaultPostCompilerCommand,
  561. \ },
  562. \ })
  563. doautocmd FileType
  564. call assert_equal('maven', g:spotbugs#state.compiler)
  565. call assert_equal(sort([
  566. \ 'DefaultPreCompilerTestCommand',
  567. \ 'DefaultPreCompilerCommand',
  568. \ 'DefaultPostCompilerCommand',
  569. \ ]),
  570. \ sort(keys(g:spotbugs#state.commands)))
  571. call assert_true(exists('b:spotbugs_syntax_once'))
  572. doautocmd java_spotbugs User
  573. " No match: "test_file !~# 'Xspotbugs/src'".
  574. call assert_false(s:spotbugs_results.preActionDone)
  575. call assert_true(empty(s:spotbugs_results.preCommandArguments))
  576. " A match: "test_file =~# 'tests'".
  577. call assert_true(s:spotbugs_results.preTestActionDone)
  578. call assert_equal('test-compile', s:spotbugs_results.preTestCommandArguments)
  579. " For a pre-match, a post-action.
  580. call assert_true(s:spotbugs_results.postActionDone)
  581. call assert_equal('%:S', s:spotbugs_results.postCommandArguments)
  582. " With a match, confirm that ":compiler spotbugs" has run.
  583. if has('win32')
  584. call assert_match('^spotbugs\.bat\s', &l:makeprg)
  585. else
  586. call assert_match('^spotbugs\s', &l:makeprg)
  587. endif
  588. setlocal makeprg=
  589. let s:spotbugs_results.preActionDone = 0
  590. let s:spotbugs_results.preTestActionOtherDone = 0
  591. let s:spotbugs_results.preTestLocalActionDone = 0
  592. let s:spotbugs_results.postActionDone = 0
  593. let s:spotbugs_results.preCommandArguments = ''
  594. let s:spotbugs_results.preTestCommandArguments = ''
  595. let s:spotbugs_results.postCommandArguments = ''
  596. " When "PostCompilerActionExecutor", "Pre*Action" and/or "Pre*TestAction",
  597. " and "Post*Action" are available, "#java_spotbugs_post" must be defined.
  598. call assert_true(exists('#java_spotbugs_post'))
  599. call assert_true(exists('#java_spotbugs_post#User'))
  600. call assert_false(exists('#java_spotbugs_post#ShellCmdPost'))
  601. call assert_false(exists('#java_spotbugs_test#ShellCmdPost'))
  602. " Re-link a Funcref on the fly.
  603. func! g:SpotBugsPreTestCommand(arguments) abort
  604. let s:spotbugs_results.preTestActionOtherDone = 1
  605. let s:spotbugs_results.preTestCommandArguments = a:arguments
  606. " Define a once-only ":autocmd" for "#java_spotbugs_test#ShellCmdPost".
  607. doautocmd java_spotbugs_post User
  608. " XXX: Do NOT use ":cc" to notify the spotbugs compiler about success or
  609. " failure, and assume the transfer of control to a ShellCmdPost command.
  610. endfunc
  611. doautocmd java_spotbugs User
  612. " No match: "test_file !~# 'Xspotbugs/src'".
  613. call assert_false(s:spotbugs_results.preActionDone)
  614. call assert_true(empty(s:spotbugs_results.preCommandArguments))
  615. " A match: "test_file =~# 'tests'".
  616. call assert_true(s:spotbugs_results.preTestActionOtherDone)
  617. call assert_equal('test-compile', s:spotbugs_results.preTestCommandArguments)
  618. " For a pre-match, no post-action (without ":cc") UNLESS a ShellCmdPost
  619. " event is consumed whose command will invoke "PostCompilerActionExecutor"
  620. " and the latter will accept a post-compiler action argument.
  621. call assert_false(s:spotbugs_results.postActionDone)
  622. call assert_true(exists('#java_spotbugs_test#ShellCmdPost'))
  623. doautocmd ShellCmdPost
  624. call assert_false(exists('#java_spotbugs_test#ShellCmdPost'))
  625. call assert_true(s:spotbugs_results.postActionDone)
  626. call assert_equal('%:S', s:spotbugs_results.postCommandArguments)
  627. " With a match, confirm that ":compiler spotbugs" has run.
  628. if has('win32')
  629. call assert_match('^spotbugs\.bat\s', &l:makeprg)
  630. else
  631. call assert_match('^spotbugs\s', &l:makeprg)
  632. endif
  633. bwipeout
  634. setlocal makeprg=
  635. let $PATH = save_PATH
  636. endif
  637. filetype plugin off
  638. setlocal makeprg=
  639. let &shellslash = save_shellslash
  640. endfunc
  641. " vim: shiftwidth=2 sts=2 expandtab