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.plugins.pmd;
20  
21  import javax.xml.parsers.DocumentBuilder;
22  import javax.xml.parsers.DocumentBuilderFactory;
23  
24  import java.io.File;
25  import java.io.IOException;
26  import java.nio.charset.StandardCharsets;
27  import java.nio.file.Files;
28  import java.nio.file.Path;
29  import java.nio.file.Paths;
30  
31  import org.apache.commons.io.FileUtils;
32  import org.apache.commons.lang3.StringUtils;
33  import org.apache.maven.plugin.MojoExecutionException;
34  import org.apache.maven.reporting.MavenReportException;
35  import org.w3c.dom.Document;
36  
37  /**
38   * @author <a href="mailto:oching@apache.org">Maria Odea Ching</a>
39   * @version $Id$
40   */
41  public class CpdReportTest extends AbstractPmdReportTestCase {
42      /**
43       * {@inheritDoc}
44       */
45      @Override
46      protected void setUp() throws Exception {
47          super.setUp();
48          FileUtils.deleteDirectory(new File(getBasedir(), "target/test/unit"));
49      }
50  
51      /**
52       * Test CPDReport given the default configuration
53       */
54      public void testDefaultConfiguration() throws Exception {
55          File generatedReport =
56                  generateReport(getGoal(), "default-configuration/cpd-default-configuration-plugin-config.xml");
57          assertTrue(new File(generatedReport.getAbsolutePath()).exists());
58  
59          // check if the CPD files were generated
60          File generatedFile = new File(getBasedir(), "target/test/unit/default-configuration/target/cpd.xml");
61          assertTrue(generatedFile.exists());
62  
63          // check the contents of cpd.html
64          String str = readFile(generatedReport);
65          assertTrue(lowerCaseContains(str, "AppSample.java"));
66          assertTrue(lowerCaseContains(str, "App.java"));
67          assertTrue(lowerCaseContains(str, "public String dup( String str )"));
68          assertTrue(lowerCaseContains(str, "tmp = tmp + str.substring( i, i + 1);"));
69      }
70  
71      /**
72       * Test CPDReport with the text renderer given as "format=txt"
73       */
74      public void testTxtFormat() throws Exception {
75          generateReport(getGoal(), "custom-configuration/cpd-txt-format-configuration-plugin-config.xml");
76  
77          // check if the CPD files were generated
78          File xmlFile = new File(getBasedir(), "target/test/unit/custom-configuration/target/cpd.xml");
79          assertTrue(new File(xmlFile.getAbsolutePath()).exists());
80          File txtFile = new File(getBasedir(), "target/test/unit/custom-configuration/target/cpd.txt");
81          assertTrue(new File(txtFile.getAbsolutePath()).exists());
82  
83          // check the contents of cpd.txt
84          String str = readFile(txtFile);
85          // Contents that should NOT be in the report
86          assertFalse(lowerCaseContains(str, "public static void main( String[] args )"));
87          // Contents that should be in the report
88          assertTrue(lowerCaseContains(str, "public void duplicateMethod( int i )"));
89      }
90  
91      /**
92       * Test CpdReport using custom configuration
93       */
94      public void testCustomConfiguration() throws Exception {
95          File generatedReport =
96                  generateReport(getGoal(), "custom-configuration/cpd-custom-configuration-plugin-config.xml");
97          assertTrue(generatedReport.exists());
98  
99          // check if the CPD files were generated
100         File generatedFile = new File(getBasedir(), "target/test/unit/custom-configuration/target/cpd.csv");
101         assertTrue(generatedFile.exists());
102 
103         String str = readFile(generatedReport);
104         // Contents that should NOT be in the report
105         assertFalse(lowerCaseContains(str, "/Sample.java"));
106         assertFalse(lowerCaseContains(str, "public void duplicateMethod( int i )"));
107         // Contents that should be in the report
108         assertTrue(lowerCaseContains(str, "AnotherSample.java"));
109         assertTrue(lowerCaseContains(str, "public static void main( String[] args )"));
110         assertTrue(lowerCaseContains(str, "private String unusedMethod("));
111     }
112 
113     /**
114      * Test CPDReport with invalid format
115      */
116     public void testInvalidFormat() throws Exception {
117         try {
118             File testPom = new File(
119                     getBasedir(), "src/test/resources/unit/invalid-format/cpd-invalid-format-plugin-config.xml");
120             AbstractPmdReport mojo = createReportMojo(getGoal(), testPom);
121             setVariableValueToObject(
122                     mojo, "compileSourceRoots", mojo.getProject().getCompileSourceRoots());
123             generateReport(mojo, testPom);
124 
125             // TODO this should be a more specific subclass
126             fail("RuntimeException must be thrown");
127         } catch (RuntimeException e) {
128             assertMavenReportException("Can't find CPD custom format xhtml", e);
129         }
130     }
131 
132     public void testWriteNonHtml() throws Exception {
133         generateReport(getGoal(), "default-configuration/cpd-default-configuration-plugin-config.xml");
134 
135         // check if the CPD files were generated
136         File generatedFile = new File(getBasedir(), "target/test/unit/default-configuration/target/cpd.xml");
137         assertTrue(generatedFile.exists());
138 
139         DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
140         Document pmdCpdDocument = builder.parse(generatedFile);
141         assertNotNull(pmdCpdDocument);
142 
143         String str = readFile(generatedFile);
144         assertTrue(lowerCaseContains(str, "AppSample.java"));
145         assertTrue(lowerCaseContains(str, "App.java"));
146         assertTrue(lowerCaseContains(str, "public String dup( String str )"));
147         assertTrue(lowerCaseContains(str, "tmp = tmp + str.substring( i, i + 1);"));
148     }
149 
150     /**
151      * verify the cpd.xml file is included in the reports when requested.
152      *
153      * @throws Exception
154      */
155     public void testIncludeXmlInReports() throws Exception {
156         generateReport(getGoal(), "default-configuration/cpd-report-include-xml-in-reports-config.xml");
157 
158         File generatedFile = new File(getBasedir(), "target/test/unit/default-configuration/target/cpd.xml");
159         assertTrue(generatedFile.exists());
160 
161         DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
162         Document pmdCpdDocument = builder.parse(generatedFile);
163         assertNotNull(pmdCpdDocument);
164 
165         String str = readFile(generatedFile);
166         assertTrue(str.contains("</pmd-cpd>"));
167 
168         File siteReport = new File(getBasedir(), "target/test/unit/default-configuration/target/site/cpd.xml");
169         assertTrue(new File(siteReport.getAbsolutePath()).exists());
170         String siteReportContent = readFile(siteReport);
171         assertTrue(siteReportContent.contains("</pmd-cpd>"));
172         assertEquals(str, siteReportContent);
173     }
174 
175     public void testSkipEmptyReportConfiguration() throws Exception {
176         // verify the generated files do not exist because PMD was skipped
177         File generatedReport = generateReport(getGoal(), "empty-report/cpd-skip-empty-report-plugin-config.xml");
178         assertFalse(new File(generatedReport.getAbsolutePath()).exists());
179     }
180 
181     public void testEmptyReportConfiguration() throws Exception {
182         // verify the generated files do exist, even if there are no violations
183         File generatedReport = generateReport(getGoal(), "empty-report/cpd-empty-report-plugin-config.xml");
184         assertTrue(
185                 generatedReport.getAbsolutePath() + " does not exist",
186                 new File(generatedReport.getAbsolutePath()).exists());
187 
188         String str = readFile(generatedReport);
189         assertFalse(lowerCaseContains(str, "Hello.java"));
190         assertTrue(str.contains("CPD found no problems in your source code."));
191     }
192 
193     public void testCpdEncodingConfiguration() throws Exception {
194         String originalEncoding = System.getProperty("file.encoding");
195         try {
196             System.setProperty("file.encoding", "UTF-16");
197 
198             generateReport(getGoal(), "default-configuration/cpd-default-configuration-plugin-config.xml");
199 
200             // check if the CPD files were generated
201             File generatedFile = new File(getBasedir(), "target/test/unit/default-configuration/target/cpd.xml");
202             assertTrue(generatedFile.exists());
203             String str = readFile(generatedFile);
204             assertTrue(lowerCaseContains(str, "AppSample.java"));
205         } finally {
206             System.setProperty("file.encoding", originalEncoding);
207         }
208     }
209 
210     public void testCpdJavascriptConfiguration() throws Exception {
211         generateReport(getGoal(), "default-configuration/cpd-javascript-plugin-config.xml");
212 
213         // verify the generated file exists and violations are reported
214         File generatedFile = new File(getBasedir(), "target/test/unit/default-configuration/target/cpd.xml");
215         assertTrue(generatedFile.exists());
216         String str = readFile(generatedFile);
217         assertTrue(lowerCaseContains(str, "Sample.js"));
218         assertTrue(lowerCaseContains(str, "SampleDup.js"));
219     }
220 
221     public void testCpdJspConfiguration() throws Exception {
222         generateReport(getGoal(), "default-configuration/cpd-jsp-plugin-config.xml");
223 
224         // verify the generated file exists and violations are reported
225         File generatedFile = new File(getBasedir(), "target/test/unit/default-configuration/target/cpd.xml");
226         assertTrue(generatedFile.exists());
227         String str = readFile(generatedFile);
228         assertTrue(lowerCaseContains(str, "sample.jsp"));
229         assertTrue(lowerCaseContains(str, "sampleDup.jsp"));
230     }
231 
232     public void testExclusionsConfiguration() throws Exception {
233         generateReport(getGoal(), "default-configuration/cpd-report-cpd-exclusions-configuration-plugin-config.xml");
234 
235         // verify the generated file exists and no duplications are reported
236         File generatedFile = new File(getBasedir(), "target/test/unit/default-configuration/target/cpd.xml");
237         assertTrue(generatedFile.exists());
238         String str = readFile(generatedFile);
239         assertEquals(0, StringUtils.countMatches(str, "<duplication"));
240     }
241 
242     public void testWithCpdErrors() throws Exception {
243         try {
244             generateReport(getGoal(), "CpdReportTest/with-cpd-errors/pom.xml");
245 
246             fail("MojoExecutionException must be thrown");
247         } catch (MojoExecutionException e) {
248             assertMavenReportException("There was 1 error while executing CPD", e);
249             assertReportContains("Lexical error in file");
250             assertReportContains("BadFile.java");
251         }
252     }
253 
254     private static void assertMavenReportException(String expectedMessage, Exception exception) {
255         MavenReportException cause = (MavenReportException) exception.getCause();
256         String message = cause.getMessage();
257         assertTrue(
258                 "Wrong message: expected: " + expectedMessage + ", but was: " + message,
259                 message.contains(expectedMessage));
260     }
261 
262     private static void assertReportContains(String expectedMessage) throws IOException {
263         Path path = Paths.get(getBasedir(), "target/test/unit/CpdReportTest/with-cpd-errors/target/cpd.xml");
264         String report = new String(Files.readAllBytes(path), StandardCharsets.UTF_8);
265 
266         assertTrue(
267                 "Expected '" + expectedMessage + "' in cpd.xml, but was:\n" + report, report.contains(expectedMessage));
268     }
269 
270     @Override
271     protected String getGoal() {
272         return "cpd";
273     }
274 }