1 package org.codehaus.plexus.compiler;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 import javax.inject.Inject;
27
28 import java.io.File;
29 import java.security.CodeSource;
30 import java.util.ArrayList;
31 import java.util.Collection;
32 import java.util.Collections;
33 import java.util.Iterator;
34 import java.util.List;
35 import java.util.Map;
36 import java.util.stream.Collectors;
37
38 import org.codehaus.plexus.testing.PlexusTest;
39 import org.codehaus.plexus.util.FileUtils;
40 import org.codehaus.plexus.util.StringUtils;
41 import org.junit.jupiter.api.Test;
42
43 import static org.junit.jupiter.api.Assertions.assertEquals;
44 import static org.junit.jupiter.api.Assertions.assertNotNull;
45 import static org.junit.jupiter.api.Assertions.assertTrue;
46
47
48
49
50 @PlexusTest
51 public abstract class AbstractCompilerTest {
52 private boolean compilerDebug = false;
53
54 private boolean compilerDeprecationWarnings = false;
55
56 private boolean forceJavacCompilerUse = false;
57
58 @Inject
59 private Map<String, Compiler> compilers;
60
61 protected abstract String getRoleHint();
62
63 protected void setCompilerDebug(boolean flag) {
64 compilerDebug = flag;
65 }
66
67 protected void setCompilerDeprecationWarnings(boolean flag) {
68 compilerDeprecationWarnings = flag;
69 }
70
71 public void setForceJavacCompilerUse(boolean forceJavacCompilerUse) {
72 this.forceJavacCompilerUse = forceJavacCompilerUse;
73 }
74
75 protected final Compiler getCompiler() {
76 return compilers.get(getRoleHint());
77 }
78
79 protected List<String> getClasspath() throws Exception {
80 List<String> cp = new ArrayList<>();
81
82 cp.add(getJarPath("org.apache.commons.lang3.StringUtils").getAbsolutePath());
83
84 return cp;
85 }
86
87
88
89
90
91
92
93
94
95 protected static File getJarPath(String className) throws Exception {
96 Class<?> type = Class.forName(className);
97 CodeSource source = type.getProtectionDomain().getCodeSource();
98 assertNotNull(source, "test prerequisite: no code source for " + className);
99
100 File jar = new File(source.getLocation().toURI());
101 assertTrue(jar.canRead(), "test prerequisite: unreadable jar for " + className + ": " + jar);
102
103 return jar;
104 }
105
106 protected void configureCompilerConfig(CompilerConfiguration compilerConfig) {}
107
108 @Test
109 public void testCompilingSources() throws Exception {
110 List<CompilerMessage> messages = new ArrayList<>();
111 Collection<String> files = new ArrayList<>();
112
113 for (CompilerConfiguration compilerConfig : getCompilerConfigurations()) {
114 File outputDir = new File(compilerConfig.getOutputLocation());
115
116 messages.addAll(getCompiler().performCompile(compilerConfig).getCompilerMessages());
117
118 if (outputDir.isDirectory()) {
119 files.addAll(normalizePaths(FileUtils.getFileNames(outputDir, null, null, false)));
120 }
121 }
122
123 int numCompilerErrors = compilerErrorCount(messages);
124
125 int numCompilerWarnings = compilerWarningCount(messages);
126
127 int expectedErrors = expectedErrors();
128
129 if (expectedErrors != numCompilerErrors) {
130 System.out.println(numCompilerErrors + " error(s) found:");
131 List<String> errors = new ArrayList<>();
132 for (CompilerMessage error : messages) {
133 if (!error.isError()) {
134 continue;
135 }
136
137 System.out.println("----");
138 System.out.println(error.getFile());
139 System.out.println(error.getMessage());
140 System.out.println("----");
141 errors.add(error.getMessage());
142 }
143
144 assertEquals(
145 expectedErrors,
146 numCompilerErrors,
147 "Wrong number of compilation errors (" + numCompilerErrors + "/" + expectedErrors + ") : "
148 + displayLines(errors));
149 }
150
151 int expectedWarnings = expectedWarnings();
152 if (expectedWarnings != numCompilerWarnings) {
153 List<String> warnings = new ArrayList<>();
154 System.out.println(numCompilerWarnings + " warning(s) found:");
155 for (CompilerMessage warning : messages) {
156 if (!isWarning(warning)) {
157 continue;
158 }
159
160 System.out.println("----");
161 System.out.println(warning.getFile());
162 System.out.println(warning.getMessage());
163 System.out.println("----");
164 warnings.add(warning.getMessage());
165 }
166
167 assertEquals(
168 expectedWarnings,
169 numCompilerWarnings,
170 "Wrong number (" + numCompilerWarnings + "/" + expectedWarnings + ") of compilation warnings: "
171 + displayLines(warnings));
172 }
173
174 List<String> expectedFiles = normalizePaths(expectedOutputFiles());
175 assertEquals(
176 expectedFiles.size(),
177 files.size(),
178 "Number of expected output files does not match: " + files + " vs " + expectedFiles);
179 assertTrue(
180 files.containsAll(expectedFiles),
181 "Output files do not contain all expected files: expected=" + expectedFiles + " actual=" + files);
182 }
183
184 protected String displayLines(List<String> warnings) {
185
186 StringBuilder sb = new StringBuilder(System.lineSeparator());
187 for (String warning : warnings) {
188 sb.append('-').append(warning).append(System.lineSeparator());
189 }
190 return sb.toString();
191 }
192
193 private List<CompilerConfiguration> getCompilerConfigurations() throws Exception {
194 String sourceDir = "src/test-input/src/main";
195
196 List<String> filenames = FileUtils.getFileNames(new File(sourceDir), "**/*.java", null, false, true);
197 Collections.sort(filenames);
198
199 List<CompilerConfiguration> compilerConfigurations = new ArrayList<>();
200
201 int index = 0;
202 for (Iterator<String> it = filenames.iterator(); it.hasNext(); index++) {
203 String filename = it.next();
204
205 CompilerConfiguration compilerConfig = new CompilerConfiguration();
206
207 compilerConfig.setDebug(compilerDebug);
208
209 compilerConfig.setShowDeprecation(compilerDeprecationWarnings);
210
211 compilerConfig.setClasspathEntries(getClasspath());
212
213 compilerConfig.addSourceLocation(sourceDir);
214
215 compilerConfig.setOutputLocation("target/" + getRoleHint() + "/classes-" + index);
216
217 FileUtils.deleteDirectory(compilerConfig.getOutputLocation());
218
219 compilerConfig.addInclude(filename);
220
221 compilerConfig.setForceJavacCompilerUse(this.forceJavacCompilerUse);
222
223 configureCompilerConfig(compilerConfig);
224
225 String target = getTargetVersion();
226 if (StringUtils.isNotEmpty(target)) {
227 compilerConfig.setTargetVersion(target);
228 }
229
230 String source = getSourceVersion();
231 if (StringUtils.isNotEmpty(source)) {
232 compilerConfig.setSourceVersion(source);
233 }
234
235 compilerConfigurations.add(compilerConfig);
236 }
237
238 return compilerConfigurations;
239 }
240
241 public String getTargetVersion() {
242 return null;
243 }
244
245 public String getSourceVersion() {
246 return null;
247 }
248
249 private List<String> normalizePaths(Collection<String> relativePaths) {
250 return relativePaths.stream()
251 .map(s -> s.replace(File.separatorChar, '/'))
252 .collect(Collectors.toList());
253 }
254
255 protected int compilerErrorCount(List<CompilerMessage> messages) {
256 int count = 0;
257
258 for (CompilerMessage message : messages) {
259 count += message.isError() ? 1 : 0;
260 }
261
262 return count;
263 }
264
265 protected int compilerWarningCount(List<CompilerMessage> messages) {
266 int count = 0;
267
268 for (CompilerMessage message : messages) {
269 count += isWarning(message) ? 1 : 0;
270 }
271
272 return count;
273 }
274
275 private static boolean isWarning(CompilerMessage message) {
276 return message.getKind() == CompilerMessage.Kind.WARNING
277 || message.getKind() == CompilerMessage.Kind.MANDATORY_WARNING;
278 }
279
280 protected int expectedErrors() {
281 return 1;
282 }
283
284 protected int expectedWarnings() {
285 return 0;
286 }
287
288 protected Collection<String> expectedOutputFiles() {
289 return Collections.emptyList();
290 }
291
292 protected String getJavaVersion() {
293 String javaVersion = System.getProperty("java.version");
294 String realJavaVersion = javaVersion;
295
296 int dotIdx = javaVersion.indexOf(".");
297 if (dotIdx > -1) {
298 int lastDot = dotIdx;
299
300
301 dotIdx = javaVersion.indexOf(".", lastDot + 1);
302 if (dotIdx > lastDot) {
303 javaVersion = javaVersion.substring(0, dotIdx);
304 }
305 }
306
307 System.out.println("java.version is: " + realJavaVersion + "\ntrimmed java version is: " + javaVersion
308 + "\ncomparison: \"1.5\".compareTo( \"" + javaVersion + "\" ) == " + ("1.5".compareTo(javaVersion))
309 + "\n");
310
311 return javaVersion;
312 }
313 }