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