diff options
author | Evgeny Mandrikov <mandrikov@gmail.com> | 2011-08-26 21:49:33 +0400 |
---|---|---|
committer | Evgeny Mandrikov <mandrikov@gmail.com> | 2011-08-29 17:12:08 +0400 |
commit | 26d659360faed0a648fec99f03e42dc8126e3bdf (patch) | |
tree | 046c99bd3d55e91e6a36666e75af325dff421764 | |
parent | 0baf8c2ea040d0b614d113e412b5dac379aa9be0 (diff) | |
download | sonarqube-26d659360faed0a648fec99f03e42dc8126e3bdf.tar.gz sonarqube-26d659360faed0a648fec99f03e42dc8126e3bdf.zip |
Update sonar-cpd-plugin to use new Sonar-CPD engine
7 files changed, 378 insertions, 81 deletions
diff --git a/plugins/sonar-cpd-plugin/pom.xml b/plugins/sonar-cpd-plugin/pom.xml index ea0eea7c185..3ab104c9075 100644 --- a/plugins/sonar-cpd-plugin/pom.xml +++ b/plugins/sonar-cpd-plugin/pom.xml @@ -33,6 +33,13 @@ </exclusion> </exclusions> </dependency> + + <dependency> + <groupId>org.codehaus.sonar.gsoc</groupId> + <artifactId>sonar-gsoc-duplications</artifactId> + <version>1.0-SNAPSHOT</version> + </dependency> + <dependency> <groupId>org.codehaus.sonar</groupId> <artifactId>sonar-duplications</artifactId> diff --git a/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/CpdEngine.java b/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/CpdEngine.java new file mode 100644 index 00000000000..2f8a5883f29 --- /dev/null +++ b/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/CpdEngine.java @@ -0,0 +1,33 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2008-2011 SonarSource + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.cpd; + +import org.sonar.api.BatchExtension; +import org.sonar.api.batch.SensorContext; +import org.sonar.api.resources.Language; +import org.sonar.api.resources.Project; + +public interface CpdEngine extends BatchExtension { + + boolean isLanguageSupported(Language language); + + void analyse(Project project, SensorContext context); + +} diff --git a/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/CpdPlugin.java b/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/CpdPlugin.java index 7a11a8fcd0f..da09e8e5adf 100644 --- a/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/CpdPlugin.java +++ b/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/CpdPlugin.java @@ -19,6 +19,9 @@ */ package org.sonar.plugins.cpd; +import java.util.Arrays; +import java.util.List; + import org.sonar.api.CoreProperties; import org.sonar.api.Properties; import org.sonar.api.Property; @@ -26,9 +29,6 @@ import org.sonar.api.SonarPlugin; import org.sonar.plugins.cpd.decorators.DuplicationDensityDecorator; import org.sonar.plugins.cpd.decorators.SumDuplicationsDecorator; -import java.util.Arrays; -import java.util.List; - @Properties({ @Property( key = CoreProperties.CPD_MINIMUM_TOKENS_PROPERTY, @@ -67,6 +67,7 @@ import java.util.List; public class CpdPlugin extends SonarPlugin { public List getExtensions() { - return Arrays.asList(CpdSensor.class, SumDuplicationsDecorator.class, DuplicationDensityDecorator.class, JavaCpdMapping.class); + return Arrays.asList(CpdSensor.class, SumDuplicationsDecorator.class, DuplicationDensityDecorator.class, JavaCpdMapping.class, SonarEngine.class, PmdEngine.class); } -}
\ No newline at end of file + +} diff --git a/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/CpdSensor.java b/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/CpdSensor.java index 3e65dd742ea..522d6db766c 100644 --- a/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/CpdSensor.java +++ b/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/CpdSensor.java @@ -19,101 +19,63 @@ */ package org.sonar.plugins.cpd; -import net.sourceforge.pmd.cpd.AbstractLanguage; -import net.sourceforge.pmd.cpd.TokenEntry; import org.apache.commons.configuration.Configuration; +import org.apache.commons.lang.StringUtils; import org.slf4j.LoggerFactory; -import org.sonar.api.CoreProperties; -import org.sonar.api.batch.CpdMapping; import org.sonar.api.batch.Sensor; import org.sonar.api.batch.SensorContext; -import org.sonar.api.resources.Language; import org.sonar.api.resources.Project; -import org.sonar.duplications.cpd.CPD; - -import java.io.IOException; -import java.nio.charset.Charset; public class CpdSensor implements Sensor { - private CpdMapping[] mappings; + private CpdEngine sonarEngine; + private CpdEngine pmdEngine; - public CpdSensor(CpdMapping[] mappings) { - this.mappings = mappings; + public CpdSensor(SonarEngine sonarEngine, PmdEngine pmdEngine) { + this.sonarEngine = sonarEngine; + this.pmdEngine = pmdEngine; } public boolean shouldExecuteOnProject(Project project) { - CpdMapping mapping = getMapping(project.getLanguage()); - if (mapping == null) { - LoggerFactory.getLogger(getClass()).info("Detection of duplication code is not supported for {}.", project.getLanguage()); + if (isSkipped(project)) { + LoggerFactory.getLogger(getClass()).info("Detection of duplicated code is skipped"); return false; } - if (isSkipped(project)) { - LoggerFactory.getLogger(getClass()).info("Detection of duplicated code is skipped"); + if (!getEngine(project).isLanguageSupported(project.getLanguage())) { + LoggerFactory.getLogger(getClass()).info("Detection of duplication code is not supported for {}.", project.getLanguage()); return false; } return true; } - boolean isSkipped(Project project) { - Configuration conf = project.getConfiguration(); - return conf.getBoolean("sonar.cpd." + project.getLanguageKey() + ".skip", - conf.getBoolean("sonar.cpd.skip", false)); - } - - public void analyse(Project project, SensorContext context) { - CpdMapping mapping = getMapping(project.getLanguage()); - CPD cpd = executeCPD(project, mapping, project.getFileSystem().getSourceCharset()); - saveResults(cpd, mapping, project, context); - } - - private CpdMapping getMapping(Language language) { - for (CpdMapping cpdMapping : mappings) { - if (cpdMapping.getLanguage().equals(language)) { - return cpdMapping; + private CpdEngine getEngine(Project project) { + if (isSonarEngineEnabled(project)) { + if (sonarEngine.isLanguageSupported(project.getLanguage())) { + return sonarEngine; + } else { + // fallback to PMD + return pmdEngine; } + } else { + return pmdEngine; } - return null; - } - - private void saveResults(CPD cpd, CpdMapping mapping, Project project, SensorContext context) { - CpdAnalyser cpdAnalyser = new CpdAnalyser(project, context, mapping); - cpdAnalyser.analyse(cpd.getMatches()); } - private CPD executeCPD(Project project, CpdMapping mapping, Charset encoding) { - try { - CPD cpd = configureCPD(project, mapping, encoding); - cpd.go(); - return cpd; - - } catch (Exception e) { - throw new CpdException(e); - } + private boolean isSonarEngineEnabled(Project project) { + Configuration conf = project.getConfiguration(); + return StringUtils.equalsIgnoreCase(conf.getString("sonar.cpd.engine", "pmd"), "sonar"); } - private CPD configureCPD(Project project, CpdMapping mapping, Charset encoding) throws IOException { - // To avoid a cpd bug generating error as "java.lang.IndexOutOfBoundsException: Index: 259, Size: 248" - // See http://sourceforge.net/tracker/?func=detail&atid=479921&aid=1947823&group_id=56262 for more details - TokenEntry.clearImages(); - - int minTokens = getMinimumTokens(project); - AbstractLanguage cpdLanguage = new AbstractLanguage(mapping.getTokenizer()) { - }; - - CPD cpd = new CPD(minTokens, cpdLanguage); - cpd.setEncoding(encoding.name()); - cpd.setLoadSourceCodeSlices(false); - cpd.add(project.getFileSystem().getSourceFiles(project.getLanguage())); - return cpd; + boolean isSkipped(Project project) { + Configuration conf = project.getConfiguration(); + return conf.getBoolean("sonar.cpd." + project.getLanguageKey() + ".skip", + conf.getBoolean("sonar.cpd.skip", false)); } - int getMinimumTokens(Project project) { - Configuration conf = project.getConfiguration(); - return conf.getInt("sonar.cpd." + project.getLanguageKey() + ".minimumTokens", - conf.getInt("sonar.cpd.minimumTokens", CoreProperties.CPD_MINIMUM_TOKENS_DEFAULT_VALUE)); + public void analyse(Project project, SensorContext context) { + getEngine(project).analyse(project, context); } @Override diff --git a/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/PmdEngine.java b/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/PmdEngine.java new file mode 100644 index 00000000000..8bad74bebe4 --- /dev/null +++ b/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/PmdEngine.java @@ -0,0 +1,101 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2008-2011 SonarSource + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.cpd; + +import java.io.IOException; +import java.nio.charset.Charset; + +import net.sourceforge.pmd.cpd.AbstractLanguage; +import net.sourceforge.pmd.cpd.TokenEntry; + +import org.apache.commons.configuration.Configuration; +import org.sonar.api.CoreProperties; +import org.sonar.api.batch.CpdMapping; +import org.sonar.api.batch.SensorContext; +import org.sonar.api.resources.Language; +import org.sonar.api.resources.Project; +import org.sonar.duplications.cpd.CPD; + +public class PmdEngine implements CpdEngine { + + private CpdMapping[] mappings; + + public PmdEngine(CpdMapping[] mappings) { + this.mappings = mappings; + } + + public boolean isLanguageSupported(Language language) { + return getMapping(language) != null; + } + + private CpdMapping getMapping(Language language) { + for (CpdMapping cpdMapping : mappings) { + if (cpdMapping.getLanguage().equals(language)) { + return cpdMapping; + } + } + return null; + } + + public void analyse(Project project, SensorContext context) { + CpdMapping mapping = getMapping(project.getLanguage()); + CPD cpd = executeCPD(project, mapping, project.getFileSystem().getSourceCharset()); + saveResults(cpd, mapping, project, context); + } + + private void saveResults(CPD cpd, CpdMapping mapping, Project project, SensorContext context) { + CpdAnalyser cpdAnalyser = new CpdAnalyser(project, context, mapping); + cpdAnalyser.analyse(cpd.getMatches()); + } + + private CPD executeCPD(Project project, CpdMapping mapping, Charset encoding) { + try { + CPD cpd = configureCPD(project, mapping, encoding); + cpd.go(); + return cpd; + + } catch (Exception e) { + throw new CpdException(e); + } + } + + private CPD configureCPD(Project project, CpdMapping mapping, Charset encoding) throws IOException { + // To avoid a cpd bug generating error as "java.lang.IndexOutOfBoundsException: Index: 259, Size: 248" + // See http://sourceforge.net/tracker/?func=detail&atid=479921&aid=1947823&group_id=56262 for more details + TokenEntry.clearImages(); + + int minTokens = getMinimumTokens(project); + AbstractLanguage cpdLanguage = new AbstractLanguage(mapping.getTokenizer()) { + }; + + CPD cpd = new CPD(minTokens, cpdLanguage); + cpd.setEncoding(encoding.name()); + cpd.setLoadSourceCodeSlices(false); + cpd.add(project.getFileSystem().getSourceFiles(project.getLanguage())); + return cpd; + } + + int getMinimumTokens(Project project) { + Configuration conf = project.getConfiguration(); + return conf.getInt("sonar.cpd." + project.getLanguageKey() + ".minimumTokens", + conf.getInt("sonar.cpd.minimumTokens", CoreProperties.CPD_MINIMUM_TOKENS_DEFAULT_VALUE)); + } + +} diff --git a/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/SonarEngine.java b/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/SonarEngine.java new file mode 100644 index 00000000000..b992598b6f8 --- /dev/null +++ b/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/SonarEngine.java @@ -0,0 +1,193 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2008-2011 SonarSource + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.cpd; + +import java.io.File; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.sonar.api.batch.SensorContext; +import org.sonar.api.measures.CoreMetrics; +import org.sonar.api.measures.Measure; +import org.sonar.api.resources.InputFile; +import org.sonar.api.resources.Java; +import org.sonar.api.resources.JavaFile; +import org.sonar.api.resources.Language; +import org.sonar.api.resources.Project; +import org.sonar.api.resources.Resource; +import org.sonar.duplications.block.Block; +import org.sonar.duplications.block.BlockChunker; +import org.sonar.duplications.detector.original.OriginalCloneDetectionAlgorithm; +import org.sonar.duplications.index.CloneGroup; +import org.sonar.duplications.index.CloneIndex; +import org.sonar.duplications.index.ClonePart; +import org.sonar.duplications.index.PackedMemoryCloneIndex; +import org.sonar.duplications.java.JavaStatementBuilder; +import org.sonar.duplications.java.JavaTokenProducer; +import org.sonar.duplications.statement.Statement; +import org.sonar.duplications.statement.StatementChunker; +import org.sonar.duplications.token.TokenChunker; +import org.sonar.duplications.token.TokenQueue; + +import com.google.common.collect.Lists; + +public class SonarEngine implements CpdEngine { + + private static final int BLOCK_SIZE = 13; + + public boolean isLanguageSupported(Language language) { + return Java.INSTANCE.equals(language); + } + + public void analyse(Project project, SensorContext context) { + List<InputFile> inputFiles = project.getFileSystem().mainFiles(project.getLanguageKey()); + if (inputFiles.isEmpty()) { + return; + } + + // Create index + CloneIndex index = new PackedMemoryCloneIndex(); + + TokenChunker tokenChunker = JavaTokenProducer.build(); + StatementChunker statementChunker = JavaStatementBuilder.build(); + BlockChunker blockChunker = new BlockChunker(BLOCK_SIZE); + + for (InputFile inputFile : inputFiles) { + File file = inputFile.getFile(); + TokenQueue tokenQueue = tokenChunker.chunk(file); + List<Statement> statements = statementChunker.chunk(tokenQueue); + Resource resource = getResource(inputFile); + List<Block> blocks = blockChunker.chunk(resource.getKey(), statements); + for (Block block : blocks) { + index.insert(block); + } + } + + // Detect + for (InputFile inputFile : inputFiles) { + Resource resource = getResource(inputFile); + + List<Block> fileBlocks = Lists.newArrayList(index.getByResourceId(resource.getKey())); + List<CloneGroup> clones = OriginalCloneDetectionAlgorithm.detect(index, fileBlocks); + if (!clones.isEmpty()) { + // Save + DuplicationsData data = new DuplicationsData(); + for (CloneGroup clone : clones) { + poplulateData(data, clone); + } + data.save(context, resource); + } + } + } + + private Resource getResource(InputFile inputFile) { + return JavaFile.fromRelativePath(inputFile.getRelativePath(), false); + } + + private void poplulateData(DuplicationsData data, CloneGroup clone) { + ClonePart origin = clone.getOriginPart(); + int originLines = origin.getLineEnd() - origin.getLineStart() + 1; + + data.incrementDuplicatedBlock(); + for (ClonePart part : clone.getCloneParts()) { + if (part.equals(origin)) { + continue; + } + data.cumulate(part.getResourceId(), part.getLineStart(), origin.getLineStart(), originLines); + + if (part.getResourceId().equals(origin.getResourceId())) { + data.incrementDuplicatedBlock(); + data.cumulate(origin.getResourceId(), origin.getLineStart(), part.getLineStart(), originLines); + } + } + } + + // TODO Godin: reuse this class for PMD-CPD + private static final class DuplicationsData { + + protected Set<Integer> duplicatedLines = new HashSet<Integer>(); + protected double duplicatedBlocks = 0; + private List<XmlEntry> duplicationXMLEntries = new ArrayList<XmlEntry>(); + + private static final class XmlEntry { + protected StringBuilder xml; + protected int startLine; + protected int lines; + + private XmlEntry(int startLine, int lines, StringBuilder xml) { + this.xml = xml; + this.startLine = startLine; + this.lines = lines; + } + } + + private DuplicationsData() { + } + + protected void cumulate(String targetResource, int targetDuplicationStartLine, int duplicationStartLine, int duplicatedLines) { + StringBuilder xml = new StringBuilder(); + xml.append("<duplication lines=\"").append(duplicatedLines).append("\" start=\"").append(duplicationStartLine) + .append("\" target-start=\"").append(targetDuplicationStartLine).append("\" target-resource=\"") + .append(targetResource).append("\"/>"); + + duplicationXMLEntries.add(new XmlEntry(duplicationStartLine, duplicatedLines, xml)); + + for (int duplicatedLine = duplicationStartLine; duplicatedLine < duplicationStartLine + duplicatedLines; duplicatedLine++) { + this.duplicatedLines.add(duplicatedLine); + } + } + + protected void incrementDuplicatedBlock() { + duplicatedBlocks++; + } + + protected void save(SensorContext context, Resource resource) { + context.saveMeasure(resource, CoreMetrics.DUPLICATED_FILES, 1d); + context.saveMeasure(resource, CoreMetrics.DUPLICATED_LINES, (double) duplicatedLines.size()); + context.saveMeasure(resource, CoreMetrics.DUPLICATED_BLOCKS, duplicatedBlocks); + context.saveMeasure(resource, new Measure(CoreMetrics.DUPLICATIONS_DATA, getDuplicationXMLData())); + } + + private String getDuplicationXMLData() { + StringBuilder duplicationXML = new StringBuilder("<duplications>"); + + Comparator<XmlEntry> comp = new Comparator<XmlEntry>() { + public int compare(XmlEntry o1, XmlEntry o2) { + if (o1.startLine == o2.startLine) { + return o2.lines - o1.lines; + } + return o1.startLine - o2.startLine; + } + }; + Collections.sort(duplicationXMLEntries, comp); + + for (XmlEntry xmlEntry : duplicationXMLEntries) { + duplicationXML.append(xmlEntry.xml); + } + duplicationXML.append("</duplications>"); + return duplicationXML.toString(); + } + } + +} diff --git a/plugins/sonar-cpd-plugin/src/test/java/org/sonar/plugins/cpd/CpdSensorTest.java b/plugins/sonar-cpd-plugin/src/test/java/org/sonar/plugins/cpd/CpdSensorTest.java index a7699d21c4c..42c1f59d3a4 100644 --- a/plugins/sonar-cpd-plugin/src/test/java/org/sonar/plugins/cpd/CpdSensorTest.java +++ b/plugins/sonar-cpd-plugin/src/test/java/org/sonar/plugins/cpd/CpdSensorTest.java @@ -19,16 +19,16 @@ */ package org.sonar.plugins.cpd; +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertFalse; +import static junit.framework.Assert.assertTrue; + import org.apache.commons.configuration.PropertiesConfiguration; import org.junit.Test; import org.sonar.api.CoreProperties; import org.sonar.api.batch.CpdMapping; import org.sonar.api.resources.Project; -import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.assertFalse; -import static junit.framework.Assert.assertTrue; - public class CpdSensorTest { @Test @@ -38,7 +38,7 @@ public class CpdSensorTest { Project project = createJavaProject().setConfiguration(conf); - CpdSensor sensor = new CpdSensor(new CpdMapping[0]); + CpdSensor sensor = new CpdSensor(new SonarEngine(), new PmdEngine(new CpdMapping[0])); assertTrue(sensor.isSkipped(project)); } @@ -46,7 +46,7 @@ public class CpdSensorTest { public void doNotSkipByDefault() { Project project = createJavaProject().setConfiguration(new PropertiesConfiguration()); - CpdSensor sensor = new CpdSensor(new CpdMapping[0]); + CpdSensor sensor = new CpdSensor(new SonarEngine(), new PmdEngine(new CpdMapping[0])); assertFalse(sensor.isSkipped(project)); } @@ -59,7 +59,7 @@ public class CpdSensorTest { Project phpProject = createPhpProject().setConfiguration(conf); Project javaProject = createJavaProject().setConfiguration(conf); - CpdSensor sensor = new CpdSensor(new CpdMapping[0]); + CpdSensor sensor = new CpdSensor(new SonarEngine(), new PmdEngine(new CpdMapping[0])); assertTrue(sensor.isSkipped(phpProject)); assertFalse(sensor.isSkipped(javaProject)); } @@ -68,7 +68,7 @@ public class CpdSensorTest { public void defaultMinimumTokens() { Project project = createJavaProject().setConfiguration(new PropertiesConfiguration()); - CpdSensor sensor = new CpdSensor(new CpdMapping[0]); + PmdEngine sensor = new PmdEngine(new CpdMapping[0]); assertEquals(CoreProperties.CPD_MINIMUM_TOKENS_DEFAULT_VALUE, sensor.getMinimumTokens(project)); } @@ -78,7 +78,7 @@ public class CpdSensorTest { conf.setProperty("sonar.cpd.minimumTokens", "33"); Project project = createJavaProject().setConfiguration(conf); - CpdSensor sensor = new CpdSensor(new CpdMapping[0]); + PmdEngine sensor = new PmdEngine(new CpdMapping[0]); assertEquals(33, sensor.getMinimumTokens(project)); } @@ -91,7 +91,7 @@ public class CpdSensorTest { Project phpProject = createPhpProject().setConfiguration(conf); Project javaProject = createJavaProject().setConfiguration(conf); - CpdSensor sensor = new CpdSensor(new CpdMapping[0]); + PmdEngine sensor = new PmdEngine(new CpdMapping[0]); assertEquals(100, sensor.getMinimumTokens(javaProject)); assertEquals(33, sensor.getMinimumTokens(phpProject)); } |