package hudson.plugins.dry.parser.cpd;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.util.Collection;
import java.util.Iterator;
import org.junit.Test;
import static org.junit.Assert.*;
import hudson.plugins.dry.parser.DuplicateCode;
/**
* Tests the extraction of PMD's CPD analysis results.
*/
public class CpdParserTest {
/** First line in publisher. */
private static final int PUBLISHER_LINE = 69;
/** First line in reporter. */
private static final int REPORTER_LINE = 76;
/** File name of reporter. */
private static final String REPORTER = "/home/ulli/Hudson/jobs/M-Single-Freestyle/workspace/src/main/java/hudson/plugins/warnings/util/HealthAwareMavenReporter.java";
/** File name of publisher. */
private static final String PUBLISHER = "/home/ulli/Hudson/jobs/M-Single-Freestyle/workspace/src/main/java/hudson/plugins/warnings/util/HealthAwarePublisher.java";
/** Error message. */
private static final String WRONG_WARNING_PROPERTY = "Wrong warning property";
/** Error message. */
private static final String ERROR_MESSAGE = "Wrong number of warnings detected.";
/** Error message. */
private static final String VALID_CPD_FILE = "Parser does not accept valid CPD file.";
public static final CpdParser CPD_PARSER_DEFAULT_ENCODING = new CpdParser(50, 25, false);
/**
* Parses the specified file.
*
* @param fileName the file to read
* @return the parsed module
* @throws InvocationTargetException
* in case of an error
*/
private Collection<DuplicateCode> parseFile(final String fileName) throws InvocationTargetException {
return new CpdParser(50, 25).parse(getResource(fileName), "module");
}
/**
* Checks if the specified file is a CPD file.
*
* @param fileName the file to read
* @return <code>true</code> if the file is a CPD file
*/
private boolean acceptsFile(final String fileName) {
return new CpdParser(50, 25).accepts(getResource(fileName));
}
/**
* Returns the specified resource as input stream.
*
* @param fileName
* the file to read
* @return the input stream
*/
private InputStream getResource(final String fileName) {
return CpdParserTest.class.getResourceAsStream(fileName);
}
/**
* Checks whether we correctly detect a duplication.
*
* @throws InvocationTargetException
* Signals a test failure
*/
@Test
public void issue12516() throws InvocationTargetException {
String fileName = "issue12516.xml";
assertTrue(VALID_CPD_FILE, acceptsFile(fileName));
Collection<DuplicateCode> annotations = parseFile(fileName);
assertEquals(ERROR_MESSAGE, 2, annotations.size());
}
/**
* Checks whether we correctly detect a duplication.
*
* @throws InvocationTargetException
* Signals a test failure
*/
@Test
public void issue22356() throws InvocationTargetException {
String fileName = "issue22356.xml";
CpdParser parser = CPD_PARSER_DEFAULT_ENCODING;
assertTrue(VALID_CPD_FILE, parser.accepts(getResource(fileName)));
Collection<DuplicateCode> annotations = parser.parse(getResource(fileName), "module");
assertEquals(ERROR_MESSAGE, 8, annotations.size());
}
/**
* Checks whether we correctly detect all 2 duplications (i.e., 4 warnings).
*
* @throws InvocationTargetException
* Signals a test failure
*/
@Test
public void scanFileWithTwoDuplications() throws InvocationTargetException {
String fileName = "cpd.xml";
assertTrue(VALID_CPD_FILE, acceptsFile(fileName));
Collection<DuplicateCode> annotations = parseFile(fileName);
assertEquals(ERROR_MESSAGE, 4, annotations.size());
}
/**
* Checks whether we correctly detect 1 duplication (i.e., 2 warnings).
*
* @throws InvocationTargetException
* Signals a test failure
*/
@Test
public void scanFileWithOneDuplication() throws InvocationTargetException {
String fileName = "one-cpd.xml";
assertTrue(VALID_CPD_FILE, acceptsFile(fileName));
Collection<DuplicateCode> annotations = parseFile(fileName);
assertEquals(ERROR_MESSAGE, 2, annotations.size());
Iterator<DuplicateCode> iterator = annotations.iterator();
DuplicateCode first = iterator.next();
DuplicateCode second = iterator.next();
if (first.getPrimaryLineNumber() == REPORTER_LINE) {
assertDuplication(REPORTER_LINE, REPORTER, first);
assertDuplication(PUBLISHER_LINE, PUBLISHER, second);
}
else if (first.getPrimaryLineNumber() == PUBLISHER_LINE) {
assertDuplication(REPORTER_LINE, REPORTER, second);
assertDuplication(PUBLISHER_LINE, PUBLISHER, first);
}
else {
fail("No annotation has the correct line number.");
}
}
/**
* Asserts that all properties of the duplication have the expected
* properties.
*
* @param expectedLine
* expected line number
* @param expectedFileName
* expected file name
* @param duplication
* the actual duplication
*/
private void assertDuplication(final int expectedLine, final String expectedFileName, final DuplicateCode duplication) {
assertEquals(WRONG_WARNING_PROPERTY, expectedLine, duplication.getPrimaryLineNumber());
assertEquals(WRONG_WARNING_PROPERTY, expectedLine + 36 - 1, duplication.getLineRanges().iterator().next().getEnd());
assertEquals(WRONG_WARNING_PROPERTY, expectedFileName, duplication.getFileName());
assertTrue("Wrong duplicate code fragment", duplication.getSourceCode().startsWith("public HealthAwarePublisher(final String threshold, final String healthy, final String unHealthy"));
}
/**
* Checks whether we don't accept a file of the wrong type.
*/
@Test
public void scanOtherFile() {
assertFalse("Parser does accept invalid CPD file.", acceptsFile("otherfile.xml"));
}
/**
* Checks whether we accept a file with Windows encoding.
*/
@Test
public void assertCanReadWindowsFile() {
String fileName = "pmd-cpd.xml";
assertTrue(VALID_CPD_FILE, acceptsFile(fileName));
}
}