View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.plugin.compiler;
20  
21  import java.io.File;
22  import java.util.Arrays;
23  import java.util.HashSet;
24  import java.util.Set;
25  
26  import org.apache.maven.api.plugin.testing.InjectMojo;
27  import org.apache.maven.api.plugin.testing.MojoTest;
28  import org.apache.maven.artifact.Artifact;
29  import org.apache.maven.plugin.compiler.stubs.CompilerManagerStub;
30  import org.apache.maven.plugin.logging.Log;
31  import org.apache.maven.plugin.testing.stubs.ArtifactStub;
32  import org.junit.jupiter.api.Test;
33  
34  import static org.apache.maven.api.plugin.testing.MojoExtension.getVariableValueFromObject;
35  import static org.apache.maven.api.plugin.testing.MojoExtension.setVariableValueToObject;
36  import static org.apache.maven.plugin.compiler.MojoTestUtils.getMockMavenProject;
37  import static org.apache.maven.plugin.compiler.MojoTestUtils.getMockMavenSession;
38  import static org.junit.jupiter.api.Assertions.assertEquals;
39  import static org.junit.jupiter.api.Assertions.assertFalse;
40  import static org.junit.jupiter.api.Assertions.assertNotNull;
41  import static org.junit.jupiter.api.Assertions.assertNull;
42  import static org.junit.jupiter.api.Assertions.assertTrue;
43  import static org.junit.jupiter.api.Assertions.fail;
44  import static org.mockito.ArgumentMatchers.startsWith;
45  import static org.mockito.Mockito.mock;
46  import static org.mockito.Mockito.never;
47  import static org.mockito.Mockito.verify;
48  
49  @MojoTest
50  class CompilerMojoTest {
51  
52      private static final String COMPILE = "compile";
53  
54      /**
55       * tests the ability of the plugin to compile a basic file
56       *
57       * @throws Exception
58       */
59      @Test
60      @InjectMojo(goal = COMPILE, pom = "classpath:/unit/compiler-basic-test/plugin-config.xml")
61      void testCompilerBasic(CompilerMojo compilerMojo) throws Exception {
62          setUpCompilerMojoTestEnv(compilerMojo);
63  
64          Log log = mock(Log.class);
65  
66          compilerMojo.setLog(log);
67  
68          setVariableValueToObject(compilerMojo, "targetOrReleaseSet", false);
69          compilerMojo.execute();
70  
71          Artifact projectArtifact = (Artifact) getVariableValueFromObject(compilerMojo, "projectArtifact");
72          assertNotNull(
73                  projectArtifact.getFile(),
74                  "MCOMPILER-94: artifact file should only be null if there is nothing to compile");
75  
76          File testClass = new File(compilerMojo.getOutputDirectory(), "foo/TestCompile0.class");
77  
78          verify(log).warn(startsWith("No explicit value set for target or release!"));
79  
80          assertTrue(testClass::exists);
81      }
82  
83      @Test
84      @InjectMojo(goal = COMPILE, pom = "classpath:/unit/compiler-basic-sourcetarget/plugin-config.xml")
85      void testCompilerBasicSourceTarget(CompilerMojo compilerMojo) throws Exception {
86          setUpCompilerMojoTestEnv(compilerMojo);
87  
88          Log log = mock(Log.class);
89  
90          compilerMojo.setLog(log);
91  
92          compilerMojo.execute();
93  
94          verify(log, never()).warn(startsWith("No explicit value set for target or release!"));
95      }
96  
97      /**
98       * tests the ability of the plugin to respond to empty source
99       *
100      * @throws Exception
101      */
102     @Test
103     @InjectMojo(goal = COMPILE, pom = "classpath:/unit/compiler-empty-source-test/plugin-config.xml")
104     void testCompilerEmptySource(CompilerMojo compilerMojo) throws Exception {
105         setUpCompilerMojoTestEnv(compilerMojo);
106 
107         compilerMojo.execute();
108 
109         assertFalse(compilerMojo.getOutputDirectory().exists());
110 
111         Artifact projectArtifact = (Artifact) getVariableValueFromObject(compilerMojo, "projectArtifact");
112         assertNull(
113                 projectArtifact.getFile(), "MCOMPILER-94: artifact file should be null if there is nothing to compile");
114     }
115 
116     /**
117      * tests the ability of the plugin to respond to includes and excludes correctly
118      *
119      * @throws Exception
120      */
121     @Test
122     @InjectMojo(goal = COMPILE, pom = "classpath:/unit/compiler-includes-excludes-test/plugin-config.xml")
123     void testCompilerIncludesExcludes(CompilerMojo compilerMojo) throws Exception {
124         setUpCompilerMojoTestEnv(compilerMojo);
125 
126         Set<String> includes = new HashSet<>();
127         includes.add("**/TestCompile4*.java");
128         setVariableValueToObject(compilerMojo, "includes", includes);
129 
130         Set<String> excludes = new HashSet<>();
131         excludes.add("**/TestCompile2*.java");
132         excludes.add("**/TestCompile3*.java");
133         setVariableValueToObject(compilerMojo, "excludes", excludes);
134 
135         compilerMojo.execute();
136 
137         File testClass = new File(compilerMojo.getOutputDirectory(), "foo/TestCompile2.class");
138         assertFalse(testClass.exists());
139 
140         testClass = new File(compilerMojo.getOutputDirectory(), "foo/TestCompile3.class");
141         assertFalse(testClass.exists());
142 
143         testClass = new File(compilerMojo.getOutputDirectory(), "foo/TestCompile4.class");
144         assertTrue(testClass.exists());
145     }
146 
147     /**
148      * tests the ability of the plugin to fork and successfully compile
149      *
150      * @throws Exception
151      */
152     @Test
153     @InjectMojo(goal = COMPILE, pom = "classpath:/unit/compiler-fork-test/plugin-config.xml")
154     void testCompilerFork(CompilerMojo compilerMojo) throws Exception {
155         setUpCompilerMojoTestEnv(compilerMojo);
156         // JAVA_HOME doesn't have to be on the PATH.
157         setVariableValueToObject(
158                 compilerMojo, "executable", new File(System.getenv("JAVA_HOME"), "bin/javac").getPath());
159 
160         compilerMojo.execute();
161 
162         File testClass = new File(compilerMojo.getOutputDirectory(), "foo/TestCompile1.class");
163         assertTrue(testClass.exists());
164     }
165 
166     @Test
167     @InjectMojo(goal = COMPILE, pom = "classpath:/unit/compiler-one-output-file-test/plugin-config.xml")
168     void testOneOutputFileForAllInput(CompilerMojo compilerMojo) throws Exception {
169         setUpCompilerMojoTestEnv(compilerMojo);
170 
171         setVariableValueToObject(compilerMojo, "compilerManager", new CompilerManagerStub());
172 
173         compilerMojo.execute();
174 
175         File testClass = new File(compilerMojo.getOutputDirectory(), "compiled.class");
176         assertTrue(testClass.exists());
177     }
178 
179     @Test
180     @InjectMojo(goal = COMPILE, pom = "classpath:/unit/compiler-args-test/plugin-config.xml")
181     void testCompilerArgs(CompilerMojo compilerMojo) throws Exception {
182         setUpCompilerMojoTestEnv(compilerMojo);
183 
184         setVariableValueToObject(compilerMojo, "compilerManager", new CompilerManagerStub());
185 
186         compilerMojo.execute();
187 
188         File testClass = new File(compilerMojo.getOutputDirectory(), "compiled.class");
189         assertTrue(testClass.exists());
190         assertEquals(
191                 Arrays.asList("key1=value1", "-Xlint", "-my&special:param-with+chars/not>allowed_in_XML_element_names"),
192                 compilerMojo.compilerArgs);
193     }
194 
195     @Test
196     @InjectMojo(goal = COMPILE, pom = "classpath:/unit/compiler-implicit-test/plugin-config-none.xml")
197     void testImplicitFlagNone(CompilerMojo compilerMojo) throws Exception {
198         setUpCompilerMojoTestEnv(compilerMojo);
199 
200         assertEquals("none", compilerMojo.getImplicit());
201     }
202 
203     @Test
204     @InjectMojo(goal = COMPILE, pom = "classpath:/unit/compiler-implicit-test/plugin-config-not-set.xml")
205     void testImplicitFlagNotSet(CompilerMojo compilerMojo) throws Exception {
206         setUpCompilerMojoTestEnv(compilerMojo);
207 
208         assertNull(compilerMojo.getImplicit());
209     }
210 
211     @Test
212     @InjectMojo(goal = COMPILE, pom = "classpath:/unit/compiler-one-output-file-test2/plugin-config.xml")
213     void testOneOutputFileForAllInput2(CompilerMojo compilerMojo) throws Exception {
214         setUpCompilerMojoTestEnv(compilerMojo);
215 
216         setVariableValueToObject(compilerMojo, "compilerManager", new CompilerManagerStub());
217 
218         Set<String> includes = new HashSet<>();
219         includes.add("**/TestCompile4*.java");
220         setVariableValueToObject(compilerMojo, "includes", includes);
221 
222         Set<String> excludes = new HashSet<>();
223         excludes.add("**/TestCompile2*.java");
224         excludes.add("**/TestCompile3*.java");
225         setVariableValueToObject(compilerMojo, "excludes", excludes);
226 
227         compilerMojo.execute();
228 
229         File testClass = new File(compilerMojo.getOutputDirectory(), "compiled.class");
230         assertTrue(testClass.exists());
231     }
232 
233     @Test
234     @InjectMojo(goal = COMPILE, pom = "classpath:/unit/compiler-fail-test/plugin-config.xml")
235     void testCompileFailure(CompilerMojo compilerMojo) throws Exception {
236         setUpCompilerMojoTestEnv(compilerMojo);
237 
238         setVariableValueToObject(compilerMojo, "compilerManager", new CompilerManagerStub(true));
239 
240         try {
241             compilerMojo.execute();
242 
243             fail("Should throw an exception");
244         } catch (CompilationFailureException e) {
245             // expected
246         }
247     }
248 
249     @Test
250     @InjectMojo(goal = COMPILE, pom = "classpath:/unit/compiler-failonerror-test/plugin-config.xml")
251     void testCompileFailOnError(CompilerMojo compilerMojo) throws Exception {
252         setUpCompilerMojoTestEnv(compilerMojo);
253 
254         setVariableValueToObject(compilerMojo, "compilerManager", new CompilerManagerStub(true));
255 
256         try {
257             compilerMojo.execute();
258             assertTrue(true);
259         } catch (CompilationFailureException e) {
260             fail("The compilation error should have been consumed because failOnError = false");
261         }
262     }
263 
264     /**
265      * Tests that setting 'skipMain' to true skips compilation of the main Java source files, but that test Java source
266      * files are still compiled.
267      * @throws Exception
268      */
269     @Test
270     @InjectMojo(goal = COMPILE, pom = "classpath:/unit/compiler-skip-main/plugin-config.xml")
271     void testCompileSkipMain(CompilerMojo compilerMojo) throws Exception {
272         setUpCompilerMojoTestEnv(compilerMojo);
273         setVariableValueToObject(compilerMojo, "skipMain", true);
274         compilerMojo.execute();
275         File testClass = new File(compilerMojo.getOutputDirectory(), "foo/TestSkipMainCompile0.class");
276         assertFalse(testClass.exists());
277     }
278 
279     /**
280      * Tests that setting 'skip' to true skips compilation of the test Java source files, but that main Java source
281      * files are still compiled.
282      * @throws Exception
283      */
284     @Test
285     @InjectMojo(goal = COMPILE, pom = "classpath:/unit/compiler-skip-test/plugin-config.xml")
286     void testCompileSkipTest(CompilerMojo compilerMojo) throws Exception {
287         setUpCompilerMojoTestEnv(compilerMojo);
288 
289         compilerMojo.execute();
290 
291         File testClass = new File(compilerMojo.getOutputDirectory(), "foo/TestSkipTestCompile0.class");
292         assertTrue(testClass.exists());
293     }
294 
295     private void setUpCompilerMojoTestEnv(CompilerMojo mojo) throws Exception {
296         setVariableValueToObject(mojo, "projectArtifact", new ArtifactStub());
297         setVariableValueToObject(mojo, "session", getMockMavenSession());
298         setVariableValueToObject(mojo, "project", getMockMavenProject());
299     }
300 }