import org.sonar.api.measures.*;
import org.sonar.api.resources.Project;
import org.sonar.api.resources.Resource;
-import org.sonar.api.resources.ResourceUtils;
import org.sonar.api.rules.Rule;
import org.sonar.api.rules.RulePriority;
import org.sonar.api.rules.Violation;
}
private boolean shouldDecorateResource(Resource resource) {
- return !ResourceUtils.isUnitTestClass(resource);
+ return true;
}
@DependedUpon
private boolean shouldDecorateResource(Resource<?> resource, DecoratorContext context) {
return (StringUtils.equals(Scopes.PROJECT, resource.getScope()) || StringUtils.equals(Scopes.DIRECTORY, resource.getScope()) || StringUtils
.equals(Scopes.FILE, resource.getScope()))
- && !ResourceUtils.isUnitTestClass(resource)
- && context.getMeasure(CoreMetrics.NEW_VIOLATIONS) == null;
+ && (context.getMeasure(CoreMetrics.NEW_VIOLATIONS) == null);
}
private void computeNewViolations(DecoratorContext context) {
rule.pmd.DoNotHardCodeSDCard.name=Android - Do Not Hard Code SD Card
rule.pmd.DontCallThreadRun.name=Dont Call Thread Run
rule.pmd.GuardDebugLogging.name=Guard Debug Logging
+rule.pmd-unit-tests.JUnitStaticSuite.name=JUnit static suite
+rule.pmd-unit-tests.JUnitSpelling.name= JUnit spelling
+rule.pmd-unit-tests.JUnitAssertionsShouldIncludeMessage.name=JUnit assertions should include a message
+rule.pmd-unit-tests.JUnitTestsShouldIncludeAssert.name=JUnit tests should include an assert
+rule.pmd-unit-tests.TestClassWithoutTestCases.name=Test class without test cases
+rule.pmd-unit-tests.UnnecessaryBooleanAssertion.name=Unnecessary boolean assertion
+rule.pmd-unit-tests.UseAssertEqualsInsteadOfAssertTrue.name=Use assertEquals instead of assertTrue
+rule.pmd-unit-tests.UseAssertSameInsteadOfAssertTrue.name=Use assertSame instead of assertTrue
+rule.pmd-unit-tests.UseAssertNullInsteadOfAssertTrue.name=Use assertNull instead of assertTrue
+rule.pmd-unit-tests.SimplifyBooleanAssertion.name=Simplify boolean assertion
--- /dev/null
+JUnit assertions should include a message - i.e., use the three argument version of assertEquals(), not the two argument version.
+<pre>
+public class Foo extends TestCase {
+ public void testSomething() {
+ assertEquals("foo", "bar"); // violation, should be assertEquals("Foo does not equals bar", "foo", "bar");
+ }
+}
+</pre>
\ No newline at end of file
--- /dev/null
+Some JUnit framework methods are easy to misspell.
+<pre>
+import junit.framework.*;
+
+public class Foo extends TestCase {
+ public void setup() {} // violation, should be setUp()
+ public void TearDown() {} // violation, should be tearDown()
+}
+</pre>
\ No newline at end of file
--- /dev/null
+The suite() method in a JUnit test needs to be both public and static.
+<pre>
+import junit.framework.*;
+
+public class Foo extends TestCase {
+ public void suite() {} // violation, should be static
+ private static void suite() {} // violation, should be public
+}
+</pre>
\ No newline at end of file
--- /dev/null
+JUnit tests should include at least one assertion. This makes the tests more robust, and using assert with messages provide the developer a clearer idea of what the test does.
+<pre>
+public class Foo extends TestCase {
+ public void testSomething() {
+ Bar b = findBar();
+ b.work();
+ // violation, we could use assertNotNull("bar not found", b);
+ }
+}
+</pre>
\ No newline at end of file
--- /dev/null
+Avoid negation in an assertTrue or assertFalse test. For example, rephrase: assertTrue(!expr); as: assertFalse(expr);
+<pre>
+public class SimpleTest extends TestCase {
+ public void testX() {
+ assertTrue("not empty", !r.isEmpty()); // violation, replace with assertFalse("not empty", r.isEmpty())
+ assertFalse(!r.isEmpty()); // violation, replace with assertTrue("empty", r.isEmpty())
+ }
+}
+</pre>
\ No newline at end of file
--- /dev/null
+Test classes end with the suffix Test. Having a non-test class with that name is not a good practice, since most people will assume it is a test case. Test classes have test methods named testXXX.
+<pre>
+public class CarTest { // violation, consider changing the name of the class if it is not a test
+ // consider adding test methods if it is a test
+ public static void main(String[] args) {
+ // do something
+ }
+}
+</pre>
\ No newline at end of file
--- /dev/null
+A JUnit test assertion with a boolean literal is unnecessary since it always will eval to the same thing. Consider using flow control (in case of assertTrue(false) or similar) or simply removing statements like assertTrue(true) and assertFalse(false). If you just want a test to halt, use the fail method.
+<pre>
+public class SimpleTest extends TestCase {
+ public void testX() {
+ assertTrue(true); // violation
+ }
+}</pre>
\ No newline at end of file
--- /dev/null
+This rule detects JUnit assertions in object equality. These assertions should be made by more specific methods, like assertEquals.
+<pre>
+public class FooTest extends TestCase {
+ void testCode() {
+ Object a, b;
+
+ assertTrue(a.equals(b)); // violation
+ assertEquals("a should equals b", a, b); // good usage
+ }
+}</pre>
\ No newline at end of file
--- /dev/null
+This rule detects JUnit assertions in object references equality. These assertions should be made by more specific methods, like assertNull, assertNotNull.
+<pre>
+public class FooTest extends TestCase {
+ void testCode() {
+ Object a = doSomething();
+
+ assertTrue(a==null); // violation
+ assertNull(a); // good usage
+ assertTrue(a != null); // violation
+ assertNotNull(a); // good usage
+ }
+}
+</pre>
\ No newline at end of file
--- /dev/null
+This rule detects JUnit assertions in object references equality. These assertions should be made by more specific methods, like assertSame, assertNotSame.
+<pre>
+public class FooTest extends TestCase {
+ void testCode() {
+ Object a, b;
+
+ assertTrue(a==b); // violation
+ assertSame(a, b); // good usage
+ }
+}
+</pre>
\ No newline at end of file
<artifactId>sonar-testing-harness</artifactId>
<scope>test</scope>
</dependency>
+
+ <dependency>
+ <groupId>org.codehaus.sonar.plugins</groupId>
+ <artifactId>sonar-l10n-en-plugin</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<build>
*/
package org.sonar.plugins.pmd;
-import java.io.File;
-import java.util.List;
-import java.util.Properties;
-
import net.sourceforge.pmd.cpd.JavaTokenizer;
import net.sourceforge.pmd.cpd.Tokenizer;
-
import org.sonar.api.CoreProperties;
import org.sonar.api.batch.CpdMapping;
+import org.sonar.api.config.Settings;
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;
-public class JavaCpdMapping implements CpdMapping {
+import java.io.File;
+import java.util.List;
+import java.util.Properties;
- private String ignore_literals;
- private String ignore_identifiers;
+import static com.google.common.base.Objects.firstNonNull;
- public JavaCpdMapping(Project project) {
- ignore_literals = project.getConfiguration().getString(CoreProperties.CPD_IGNORE_LITERALS_PROPERTY,
- CoreProperties.CPD_IGNORE_LITERALS_DEFAULT_VALUE);
- ignore_identifiers = project.getConfiguration().getString(CoreProperties.CPD_IGNORE_IDENTIFIERS_PROPERTY,
- CoreProperties.CPD_IGNORE_IDENTIFIERS_DEFAULT_VALUE);
+public class JavaCpdMapping implements CpdMapping {
+ private final String ignore_literals;
+ private final String ignore_identifiers;
+
+ public JavaCpdMapping(Settings settings) {
+ ignore_literals = firstNonNull(settings.getString(CoreProperties.CPD_IGNORE_LITERALS_PROPERTY), CoreProperties.CPD_IGNORE_LITERALS_DEFAULT_VALUE);
+ ignore_identifiers = firstNonNull(settings.getString(CoreProperties.CPD_IGNORE_IDENTIFIERS_PROPERTY), CoreProperties.CPD_IGNORE_IDENTIFIERS_DEFAULT_VALUE);
}
public Tokenizer getTokenizer() {
Properties props = new Properties();
props.setProperty(JavaTokenizer.IGNORE_LITERALS, ignore_literals);
props.setProperty(JavaTokenizer.IGNORE_IDENTIFIERS, ignore_identifiers);
+
JavaTokenizer tokenizer = new JavaTokenizer();
tokenizer.setProperties(props);
return tokenizer;
*/
package org.sonar.plugins.pmd;
+import net.sourceforge.pmd.Report;
+import net.sourceforge.pmd.renderers.Renderer;
+import net.sourceforge.pmd.renderers.XMLRenderer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.sonar.api.BatchExtension;
import org.sonar.api.Property;
import org.sonar.api.config.Settings;
-import org.sonar.api.profiles.RulesProfile;
-import org.sonar.api.resources.Project;
+import org.sonar.api.resources.ProjectFileSystem;
import org.sonar.api.utils.SonarException;
import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
-import java.util.Arrays;
-import java.util.List;
@org.sonar.api.Properties({
@Property(
)
})
public class PmdConfiguration implements BatchExtension {
+ private static final Logger LOG = LoggerFactory.getLogger(PmdConfiguration.class);
public static final String PROPERTY_GENERATE_XML = "sonar.pmd.generateXml";
+ public static final String PMD_RESULT_XML = "pmd-result.xml";
- private PmdProfileExporter pmdProfileExporter;
- private RulesProfile rulesProfile;
- private Project project;
- private Settings settings;
+ private final ProjectFileSystem projectFileSystem;
+ private final Settings settings;
- public PmdConfiguration(PmdProfileExporter pmdRulesRepository, RulesProfile rulesProfile, Project project, Settings settings) {
- this.pmdProfileExporter = pmdRulesRepository;
- this.rulesProfile = rulesProfile;
- this.project = project;
+ public PmdConfiguration(ProjectFileSystem projectFileSystem, Settings settings) {
+ this.projectFileSystem = projectFileSystem;
this.settings = settings;
}
- public List<String> getRulesets() {
- return Arrays.asList(saveXmlFile().getAbsolutePath());
+ public File getTargetXMLReport() {
+ if (settings.getBoolean(PROPERTY_GENERATE_XML)) {
+ return projectFileSystem.resolvePath(PMD_RESULT_XML);
+ }
+ return null;
}
- private File saveXmlFile() {
+ public File dumpXmlRuleSet(String repositoryKey, String rulesXml) {
try {
- StringWriter pmdConfiguration = new StringWriter();
- pmdProfileExporter.exportProfile(rulesProfile, pmdConfiguration);
- return project.getFileSystem().writeToWorkingDirectory(pmdConfiguration.toString(), "pmd.xml");
+ File configurationFile = projectFileSystem.writeToWorkingDirectory(rulesXml, repositoryKey + ".xml");
+
+ LOG.info("PMD configuration: " + configurationFile.getAbsolutePath());
+ return configurationFile;
} catch (IOException e) {
throw new SonarException("Fail to save the PMD configuration", e);
}
}
- public File getTargetXMLReport() {
- if (settings.getBoolean(PROPERTY_GENERATE_XML)) {
- return new File(project.getFileSystem().getSonarWorkingDirectory(), "pmd-result.xml");
+ public File dumpXmlReport(Report report) {
+ if (!settings.getBoolean(PROPERTY_GENERATE_XML)) {
+ return null;
}
- return null;
+
+ try {
+ String reportAsString = reportToString(report);
+
+ File reportFile = projectFileSystem.writeToWorkingDirectory(reportAsString, PMD_RESULT_XML);
+
+ LOG.info("PMD output report: " + reportFile.getAbsolutePath());
+
+ return reportFile;
+ } catch (IOException e) {
+ throw new SonarException("Fail to save the PMD report", e);
+ }
+ }
+
+ private static String reportToString(Report report) throws IOException {
+ StringWriter output = new StringWriter();
+
+ Renderer xmlRenderer = new XMLRenderer();
+ xmlRenderer.setWriter(output);
+ xmlRenderer.start();
+ xmlRenderer.renderFileReport(report);
+ xmlRenderer.end();
+
+ return output.toString();
}
}
public final class PmdConstants {
public static final String REPOSITORY_KEY = CoreProperties.PMD_PLUGIN;
public static final String REPOSITORY_NAME = "PMD";
+ public static final String TEST_REPOSITORY_KEY = "pmd-unit-tests";
+ public static final String TEST_REPOSITORY_NAME = "PMD Unit Tests";
public static final String PLUGIN_NAME = "PMD";
public static final String PLUGIN_KEY = CoreProperties.PMD_PLUGIN;
public static final String XPATH_CLASS = "net.sourceforge.pmd.rules.XPathRule";
*/
package org.sonar.plugins.pmd;
-import net.sourceforge.pmd.PMD;
-import net.sourceforge.pmd.PMDException;
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.io.Closeables;
import net.sourceforge.pmd.Report;
import net.sourceforge.pmd.RuleContext;
+import net.sourceforge.pmd.RuleSet;
import net.sourceforge.pmd.RuleSetFactory;
import net.sourceforge.pmd.RuleSets;
-import net.sourceforge.pmd.SourceType;
-import net.sourceforge.pmd.renderers.Renderer;
-import net.sourceforge.pmd.renderers.XMLRenderer;
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.lang.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import org.sonar.api.BatchExtension;
+import org.sonar.api.profiles.RulesProfile;
+import org.sonar.api.resources.InputFile;
import org.sonar.api.resources.Java;
import org.sonar.api.resources.Project;
-import org.sonar.api.utils.SonarException;
+import org.sonar.api.resources.ProjectFileSystem;
import org.sonar.api.utils.TimeProfiler;
import org.sonar.java.api.JavaUtils;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
+import java.io.ByteArrayInputStream;
import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.Reader;
-import java.io.StringWriter;
-import java.io.Writer;
+import java.nio.charset.Charset;
import java.util.List;
public class PmdExecutor implements BatchExtension {
-
- private static final Logger LOG = LoggerFactory.getLogger(PmdExecutor.class);
-
- private final PmdConfiguration configuration;
private final Project project;
+ private final ProjectFileSystem projectFileSystem;
+ private final RulesProfile rulesProfile;
+ private final PmdProfileExporter pmdProfileExporter;
+ private final PmdConfiguration pmdConfiguration;
- public PmdExecutor(Project project, PmdConfiguration configuration) {
+ public PmdExecutor(Project project, ProjectFileSystem projectFileSystem, RulesProfile rulesProfile, PmdProfileExporter pmdProfileExporter, PmdConfiguration pmdConfiguration) {
this.project = project;
- this.configuration = configuration;
+ this.projectFileSystem = projectFileSystem;
+ this.rulesProfile = rulesProfile;
+ this.pmdProfileExporter = pmdProfileExporter;
+ this.pmdConfiguration = pmdConfiguration;
}
- public Report execute() throws IOException {
+ public Report execute() {
TimeProfiler profiler = new TimeProfiler().start("Execute PMD " + PmdVersion.getVersion());
ClassLoader initialClassLoader = Thread.currentThread().getContextClassLoader();
- Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
try {
- PMD pmd = new PMD();
- setJavaVersion(pmd, project);
- RuleContext ruleContext = new RuleContext();
- Report report = new Report();
- ruleContext.setReport(report);
+ Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
- RuleSets rulesets = createRulesets();
+ return executePmd();
+ } finally {
+ Thread.currentThread().setContextClassLoader(initialClassLoader);
+ profiler.stop();
+ }
+ }
- for (File file : project.getFileSystem().getSourceFiles(Java.INSTANCE)) {
- ruleContext.setSourceCodeFilename(file.getAbsolutePath());
- Reader fileReader = new InputStreamReader(new FileInputStream(file), project.getFileSystem().getSourceCharset());
- try {
- pmd.processFile(fileReader, rulesets, ruleContext);
+ private Report executePmd() {
+ Report report = new Report();
- } catch (PMDException e) {
- LOG.error("Fail to execute PMD. Following file is ignored: " + file, e.getCause());
+ RuleContext context = new RuleContext();
+ context.setReport(report);
- } catch (Exception e) {
- LOG.error("Fail to execute PMD. Following file is ignored: " + file, e);
+ PmdTemplate pmdFactory = createPmdTemplate();
+ executeRules(pmdFactory, context, projectFileSystem.mainFiles(Java.KEY), PmdConstants.REPOSITORY_KEY);
+ executeRules(pmdFactory, context, projectFileSystem.testFiles(Java.KEY), PmdConstants.TEST_REPOSITORY_KEY);
- } finally {
- IOUtils.closeQuietly(fileReader);
- }
- }
+ pmdConfiguration.dumpXmlReport(report);
- writeXmlReport(report);
+ return report;
+ }
- return report;
+ public void executeRules(PmdTemplate pmdFactory, RuleContext ruleContext, List<InputFile> files, String repositoryKey) {
+ if (files.isEmpty()) {
+ return; // Nothing to analyse
+ }
- } finally {
- profiler.stop();
- Thread.currentThread().setContextClassLoader(initialClassLoader);
+ Charset encoding = projectFileSystem.getSourceCharset();
+ RuleSets rulesets = createRulesets(repositoryKey);
+
+ for (InputFile file : files) {
+ pmdFactory.process(file.getFile(), encoding, rulesets, ruleContext);
}
}
- private RuleSets createRulesets() {
- RuleSets rulesets = new RuleSets();
- RuleSetFactory ruleSetFactory = new RuleSetFactory();
+ private RuleSets createRulesets(String repositoryKey) {
+ String rulesXml = pmdProfileExporter.exportProfile(repositoryKey, rulesProfile);
- List<String> rulesetPaths = configuration.getRulesets();
- LOG.info("PMD configuration: " + StringUtils.join(rulesetPaths, ", "));
+ pmdConfiguration.dumpXmlRuleSet(repositoryKey, rulesXml);
- for (String rulesetPath : rulesetPaths) {
- InputStream rulesInput = openRuleset(rulesetPath);
- rulesets.addRuleSet(ruleSetFactory.createRuleSet(rulesInput));
- IOUtils.closeQuietly(rulesInput);
- }
- return rulesets;
+ return new RuleSets(readRuleSet(rulesXml));
}
- private InputStream openRuleset(String rulesetPath) {
+ private static RuleSet readRuleSet(String rulesXml) {
+ InputStream rulesInput = null;
try {
- File file = new File(rulesetPath);
- boolean found;
- if (file.exists()) {
- found = true;
- } else {
- file = new File(project.getFileSystem().getBasedir(), rulesetPath);
- found = file.exists();
- }
- if (found) {
- return new FileInputStream(file);
- }
- InputStream stream = PmdExecutor.class.getResourceAsStream(rulesetPath);
- if (stream == null) {
- throw new SonarException("The PMD ruleset can not be found: " + rulesetPath);
- }
- return stream;
-
- } catch (FileNotFoundException e) {
- throw new SonarException("The PMD ruleset can not be found: " + rulesetPath, e);
- }
- }
+ rulesInput = new ByteArrayInputStream(rulesXml.getBytes());
- private void writeXmlReport(Report report) throws IOException {
- File xmlReport = configuration.getTargetXMLReport();
- if (xmlReport != null) {
- Renderer xmlRenderer = new XMLRenderer();
- Writer stringwriter = new StringWriter();
- xmlRenderer.setWriter(stringwriter);
- xmlRenderer.start();
- xmlRenderer.renderFileReport(report);
- xmlRenderer.end();
-
- LOG.info("PMD output report: " + xmlReport.getAbsolutePath());
- FileUtils.write(xmlReport, stringwriter.toString());
- }
- }
-
- static String getNormalizedJavaVersion(String javaVersion) {
- if (StringUtils.equals("1.1", javaVersion) || StringUtils.equals("1.2", javaVersion)) {
- javaVersion = "1.3";
- } else if (StringUtils.equals("5", javaVersion)) {
- javaVersion = "1.5";
- } else if (StringUtils.equals("6", javaVersion)) {
- javaVersion = "1.6";
+ return new RuleSetFactory().createRuleSet(rulesInput);
+ } finally {
+ Closeables.closeQuietly(rulesInput);
}
- return javaVersion;
}
- private void setJavaVersion(PMD pmd, Project project) {
- String javaVersion = getNormalizedJavaVersion(JavaUtils.getSourceVersion(project));
- if (javaVersion != null) {
- SourceType sourceType = SourceType.getSourceTypeForId("java " + javaVersion);
- if (sourceType != null) {
- LOG.info("Java version: " + javaVersion);
- pmd.setJavaVersion(sourceType);
- } else {
- throw new SonarException("Unsupported Java version for PMD: " + javaVersion);
- }
- }
+ @VisibleForTesting
+ PmdTemplate createPmdTemplate() {
+ return new PmdTemplate(JavaUtils.getSourceVersion(project));
}
}
*/
package org.sonar.plugins.pmd;
+import com.google.common.collect.BiMap;
+import com.google.common.collect.EnumHashBiMap;
import org.sonar.api.rules.RulePriority;
+import static com.google.common.collect.ImmutableMap.of;
+
public final class PmdLevelUtils {
+ private static final BiMap<RulePriority, String> LEVELS_PER_PRIORITY = EnumHashBiMap.create(of(
+ RulePriority.BLOCKER, "1",
+ RulePriority.CRITICAL, "2",
+ RulePriority.MAJOR, "3",
+ RulePriority.MINOR, "4",
+ RulePriority.INFO, "5"));
private PmdLevelUtils() {
// only static methods
}
public static RulePriority fromLevel(String level) {
- if ("1".equals(level)) {
- return RulePriority.BLOCKER;
- }
- if ("2".equals(level)) {
- return RulePriority.CRITICAL;
- }
- if ("3".equals(level)) {
- return RulePriority.MAJOR;
- }
- if ("4".equals(level)) {
- return RulePriority.MINOR;
- }
- if ("5".equals(level)) {
- return RulePriority.INFO;
- }
- return null;
+ return LEVELS_PER_PRIORITY.inverse().get(level);
}
public static String toLevel(RulePriority priority) {
- if (priority.equals(RulePriority.BLOCKER)) {
- return "1";
- }
- if (priority.equals(RulePriority.CRITICAL)) {
- return "2";
- }
- if (priority.equals(RulePriority.MAJOR)) {
- return "3";
- }
- if (priority.equals(RulePriority.MINOR)) {
- return "4";
- }
- if (priority.equals(RulePriority.INFO)) {
- return "5";
- }
- throw new IllegalArgumentException("Level not supported: " + priority);
+ return LEVELS_PER_PRIORITY.get(priority);
}
}
import java.util.List;
public class PmdPlugin extends SonarPlugin {
-
+ @SuppressWarnings("unchecked")
public List<Class<? extends Extension>> getExtensions() {
return ImmutableList.of(
PmdSensor.class,
PmdConfiguration.class,
PmdExecutor.class,
PmdRuleRepository.class,
+ PmdUnitTestsRuleRepository.class,
PmdProfileExporter.class,
PmdProfileImporter.class,
SonarWayProfile.class,
SonarWayWithFindbugsProfile.class,
SunConventionsProfile.class,
- JavaCpdMapping.class
- );
+ JavaCpdMapping.class,
+ PmdViolationToRuleViolation.class);
}
}
*/
package org.sonar.plugins.pmd;
-import java.io.IOException;
-import java.io.StringWriter;
-import java.io.Writer;
-import java.util.ArrayList;
-import java.util.List;
-
+import com.google.common.annotations.VisibleForTesting;
import org.jdom.CDATA;
import org.jdom.Document;
import org.jdom.Element;
import org.sonar.plugins.pmd.xml.PmdRule;
import org.sonar.plugins.pmd.xml.PmdRuleset;
-public class PmdProfileExporter extends ProfileExporter {
+import java.io.IOException;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.List;
+public class PmdProfileExporter extends ProfileExporter {
public PmdProfileExporter() {
super(PmdConstants.REPOSITORY_KEY, PmdConstants.PLUGIN_NAME);
setSupportedLanguages(Java.KEY);
@Override
public void exportProfile(RulesProfile profile, Writer writer) {
try {
- PmdRuleset tree = createPmdRuleset(profile.getActiveRulesByRepository(PmdConstants.REPOSITORY_KEY), profile.getName());
- String xmlModules = exportPmdRulesetToXml(tree);
+ String xmlModules = exportProfile(PmdConstants.REPOSITORY_KEY, profile);
writer.append(xmlModules);
} catch (IOException e) {
throw new SonarException("Fail to export the profile " + profile, e);
}
}
- protected PmdRuleset createPmdRuleset(List<ActiveRule> activeRules, String profileName) {
+ public String exportProfile(String repositoryKey, RulesProfile profile) {
+ PmdRuleset tree = createPmdRuleset(repositoryKey, profile.getActiveRulesByRepository(repositoryKey), profile.getName());
+ return exportPmdRulesetToXml(tree);
+ }
+
+ private PmdRuleset createPmdRuleset(String repositoryKey, List<ActiveRule> activeRules, String profileName) {
PmdRuleset ruleset = new PmdRuleset(profileName);
for (ActiveRule activeRule : activeRules) {
- if (activeRule.getRule().getRepositoryKey().equals(PmdConstants.REPOSITORY_KEY)) {
+ if (activeRule.getRule().getRepositoryKey().equals(repositoryKey)) {
String configKey = activeRule.getRule().getConfigKey();
PmdRule rule = new PmdRule(configKey, PmdLevelUtils.toLevel(activeRule.getSeverity()));
- if (activeRule.getActiveRuleParams() != null && !activeRule.getActiveRuleParams().isEmpty()) {
+ if ((activeRule.getActiveRuleParams() != null) && !activeRule.getActiveRuleParams().isEmpty()) {
List<PmdProperty> properties = new ArrayList<PmdProperty>();
for (ActiveRuleParam activeRuleParam : activeRule.getActiveRuleParams()) {
properties.add(new PmdProperty(activeRuleParam.getRuleParam().getKey(), activeRuleParam.getValue()));
return ruleset;
}
- protected void processXPathRule(String sonarRuleKey, PmdRule rule) {
+ @VisibleForTesting
+ void processXPathRule(String sonarRuleKey, PmdRule rule) {
if (PmdConstants.XPATH_CLASS.equals(rule.getRef())) {
rule.setRef(null);
PmdProperty xpathMessage = rule.getProperty(PmdConstants.XPATH_MESSAGE_PARAM);
}
}
- protected String exportPmdRulesetToXml(PmdRuleset pmdRuleset) {
+ private String exportPmdRulesetToXml(PmdRuleset pmdRuleset) {
Element eltRuleset = new Element("ruleset");
for (PmdRule pmdRule : pmdRuleset.getPmdRules()) {
Element eltRule = new Element("rule");
import java.util.List;
public final class PmdRuleRepository extends RuleRepository {
-
- // for user extensions
- private ServerFileSystem fileSystem;
- private XMLRuleParser xmlRuleParser;
+ private final ServerFileSystem fileSystem;
+ private final XMLRuleParser xmlRuleParser;
public PmdRuleRepository(ServerFileSystem fileSystem, XMLRuleParser xmlRuleParser) {
super(PmdConstants.REPOSITORY_KEY, Java.KEY);
import net.sourceforge.pmd.IRuleViolation;
import net.sourceforge.pmd.Report;
-import org.sonar.api.CoreProperties;
import org.sonar.api.batch.Sensor;
import org.sonar.api.batch.SensorContext;
import org.sonar.api.profiles.RulesProfile;
import org.sonar.api.resources.Java;
-import org.sonar.api.resources.JavaFile;
import org.sonar.api.resources.Project;
-import org.sonar.api.resources.Resource;
-import org.sonar.api.rules.Rule;
-import org.sonar.api.rules.RuleFinder;
import org.sonar.api.rules.Violation;
import org.sonar.api.utils.XmlParserException;
import java.util.Iterator;
public class PmdSensor implements Sensor {
+ private final RulesProfile profile;
+ private final PmdExecutor executor;
+ private final PmdViolationToRuleViolation pmdViolationToRuleViolation;
- private RulesProfile profile;
- private RuleFinder rulesFinder;
- private PmdExecutor executor;
-
- public PmdSensor(RulesProfile profile, RuleFinder rulesFinder, PmdExecutor executor) {
+ public PmdSensor(RulesProfile profile, PmdExecutor executor, PmdViolationToRuleViolation pmdViolationToRuleViolation) {
this.profile = profile;
- this.rulesFinder = rulesFinder;
this.executor = executor;
+ this.pmdViolationToRuleViolation = pmdViolationToRuleViolation;
+ }
+
+ public boolean shouldExecuteOnProject(Project project) {
+ return (!project.getFileSystem().mainFiles(Java.KEY).isEmpty() && !profile.getActiveRulesByRepository(PmdConstants.REPOSITORY_KEY).isEmpty())
+ || (!project.getFileSystem().testFiles(Java.KEY).isEmpty() && !profile.getActiveRulesByRepository(PmdConstants.TEST_REPOSITORY_KEY).isEmpty());
}
public void analyse(Project project, SensorContext context) {
try {
Report report = executor.execute();
- analyseReport(report, project, context);
-
+ reportViolations(report.iterator(), context);
} catch (Exception e) {
- // TOFIX
throw new XmlParserException(e);
}
}
- private void analyseReport(Report report, Project project, SensorContext context) {
- Iterator<IRuleViolation> pmdViolationIter = report.iterator();
- while (pmdViolationIter.hasNext()) {
- IRuleViolation pmdViolation = pmdViolationIter.next();
- int lineId = pmdViolation.getBeginLine();
- String ruleKey = pmdViolation.getRule().getName();
- String message = pmdViolation.getDescription();
- String filename = pmdViolation.getFilename();
- Resource resource = JavaFile.fromAbsolutePath(filename, project.getFileSystem().getSourceDirs(), false);
- // Save violations only for existing resources
- if (context.getResource(resource) != null) {
- Rule rule = rulesFinder.findByKey(CoreProperties.PMD_PLUGIN, ruleKey);
- // Save violations only for enabled rules
- if (rule != null) {
- Violation violation = Violation.create(rule, resource).setLineId(lineId).setMessage(message);
- context.saveViolation(violation);
- }
+ private void reportViolations(Iterator<IRuleViolation> violations, SensorContext context) {
+ while (violations.hasNext()) {
+ IRuleViolation pmdViolation = violations.next();
+
+ Violation violation = pmdViolationToRuleViolation.toViolation(pmdViolation, context);
+ if (null != violation) {
+ context.saveViolation(violation);
}
}
}
- public boolean shouldExecuteOnProject(Project project) {
- return !project.getFileSystem().mainFiles(Java.KEY).isEmpty() &&
- !profile.getActiveRulesByRepository(PmdConstants.REPOSITORY_KEY).isEmpty();
- }
-
@Override
public String toString() {
return getClass().getSimpleName();
--- /dev/null
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 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.pmd;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Functions;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.io.Closeables;
+import net.sourceforge.pmd.PMD;
+import net.sourceforge.pmd.PMDException;
+import net.sourceforge.pmd.RuleContext;
+import net.sourceforge.pmd.RuleSets;
+import net.sourceforge.pmd.SourceType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.sonar.api.utils.SonarException;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.nio.charset.Charset;
+import java.util.Map;
+
+public class PmdTemplate {
+ private static final Logger LOG = LoggerFactory.getLogger(PmdTemplate.class);
+
+ private static final Map<String, String> JAVA_VERSIONS = ImmutableMap.of(
+ "1.1", "1.3",
+ "1.2", "1.3",
+ "5", "1.5",
+ "6", "1.6");
+
+ private final PMD pmd;
+
+ public PmdTemplate(String javaVersion) {
+ pmd = new PMD();
+ setJavaVersion(pmd, javaVersion);
+ }
+
+ public void process(File file, Charset encoding, RuleSets rulesets, RuleContext ruleContext) {
+ ruleContext.setSourceCodeFilename(file.getAbsolutePath());
+
+ InputStream inputStream = null;
+ try {
+ inputStream = new FileInputStream(file);
+
+ pmd.processFile(inputStream, encoding.displayName(), rulesets, ruleContext);
+ } catch (PMDException e) {
+ LOG.error("Fail to execute PMD. Following file is ignored: " + file, e.getCause());
+ } catch (Exception e) {
+ LOG.error("Fail to execute PMD. Following file is ignored: " + file, e);
+ } finally {
+ Closeables.closeQuietly(inputStream);
+ }
+ }
+
+ @VisibleForTesting
+ static void setJavaVersion(PMD pmd, String javaVersion) {
+ String version = normalize(javaVersion);
+ if (version == null) {
+ return; // Do nothing
+ }
+
+ SourceType sourceType = SourceType.getSourceTypeForId("java " + version);
+ if (sourceType == null) {
+ throw new SonarException("Unsupported Java version for PMD: " + version);
+ }
+
+ LOG.info("Java version: " + version);
+ pmd.setJavaVersion(sourceType);
+ }
+
+ private static String normalize(String version) {
+ return Functions.forMap(JAVA_VERSIONS, version).apply(version);
+ }
+
+ @Override
+ public String toString() {
+ return getClass().getSimpleName();
+ }
+}
--- /dev/null
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 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.pmd;
+
+import org.sonar.api.resources.Java;
+import org.sonar.api.rules.Rule;
+import org.sonar.api.rules.RuleRepository;
+import org.sonar.api.rules.XMLRuleParser;
+
+import java.io.InputStream;
+import java.util.List;
+
+public final class PmdUnitTestsRuleRepository extends RuleRepository {
+ private final XMLRuleParser xmlRuleParser;
+
+ public PmdUnitTestsRuleRepository(XMLRuleParser xmlRuleParser) {
+ super(PmdConstants.TEST_REPOSITORY_KEY, Java.KEY);
+ setName(PmdConstants.TEST_REPOSITORY_NAME);
+ this.xmlRuleParser = xmlRuleParser;
+ }
+
+ @Override
+ public List<Rule> createRules() {
+ InputStream input = getClass().getResourceAsStream("/org/sonar/plugins/pmd/rules-unit-tests.xml");
+ return xmlRuleParser.parse(input);
+ }
+}
*/
package org.sonar.plugins.pmd;
-import org.apache.commons.io.IOUtils;
+import com.google.common.io.Closeables;
import org.slf4j.LoggerFactory;
import java.io.IOException;
}
private PmdVersion() {
- InputStream input = getClass().getResourceAsStream(PROPERTIES_PATH);
+ version = readVersion();
+ }
+
+ public String readVersion() {
+ Properties properties = new Properties();
+
+ InputStream input = null;
try {
- Properties properties = new Properties();
+ input = getClass().getResourceAsStream(PROPERTIES_PATH);
properties.load(input);
- this.version = properties.getProperty("pmd.version");
-
} catch (IOException e) {
LoggerFactory.getLogger(getClass()).warn("Can not load the PMD version from the file " + PROPERTIES_PATH);
- this.version = "";
-
} finally {
- IOUtils.closeQuietly(input);
+ Closeables.closeQuietly(input);
}
+
+ return properties.getProperty("pmd.version", "");
}
}
--- /dev/null
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 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.pmd;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+import net.sourceforge.pmd.IRuleViolation;
+import org.sonar.api.BatchExtension;
+import org.sonar.api.batch.SensorContext;
+import org.sonar.api.resources.JavaFile;
+import org.sonar.api.resources.ProjectFileSystem;
+import org.sonar.api.resources.Resource;
+import org.sonar.api.rules.Rule;
+import org.sonar.api.rules.RuleFinder;
+import org.sonar.api.rules.Violation;
+
+import java.io.File;
+import java.util.List;
+
+public class PmdViolationToRuleViolation implements BatchExtension {
+ private final ProjectFileSystem projectFileSystem;
+ private final RuleFinder ruleFinder;
+
+ public PmdViolationToRuleViolation(ProjectFileSystem projectFileSystem, RuleFinder ruleFinder) {
+ this.projectFileSystem = projectFileSystem;
+ this.ruleFinder = ruleFinder;
+ }
+
+ public Violation toViolation(IRuleViolation pmdViolation, SensorContext context) {
+ Resource resource = findResourceFor(pmdViolation);
+ if (context.getResource(resource) == null) {
+ return null; // Save violations only for existing resources
+ }
+
+ Rule rule = findRuleFor(pmdViolation);
+ if (rule == null) {
+ return null; // Save violations only for enabled rules
+ }
+
+ int lineId = pmdViolation.getBeginLine();
+ String message = pmdViolation.getDescription();
+
+ return Violation.create(rule, resource).setLineId(lineId).setMessage(message);
+ }
+
+ private Resource findResourceFor(IRuleViolation violation) {
+ List<File> allSources = ImmutableList.copyOf(Iterables.concat(projectFileSystem.getSourceDirs(), projectFileSystem.getTestDirs()));
+
+ return JavaFile.fromAbsolutePath(violation.getFilename(), allSources, true);
+ }
+
+ private Rule findRuleFor(IRuleViolation violation) {
+ String ruleKey = violation.getRule().getName();
+ Rule rule = ruleFinder.findByKey(PmdConstants.REPOSITORY_KEY, ruleKey);
+ if (rule != null) {
+ return rule;
+ }
+ return ruleFinder.findByKey(PmdConstants.TEST_REPOSITORY_KEY, ruleKey);
+ }
+
+ @Override
+ public String toString() {
+ return getClass().getSimpleName();
+ }
+}
*/
package org.sonar.plugins.pmd;
-import java.io.InputStreamReader;
-import java.io.Reader;
-
+import com.google.common.io.Closeables;
import org.sonar.api.profiles.ProfileDefinition;
import org.sonar.api.profiles.RulesProfile;
import org.sonar.api.resources.Java;
import org.sonar.api.utils.ValidationMessages;
-public final class SonarWayProfile extends ProfileDefinition {
+import java.io.InputStreamReader;
+import java.io.Reader;
+public final class SonarWayProfile extends ProfileDefinition {
private final PmdProfileImporter importer;
public SonarWayProfile(PmdProfileImporter importer) {
}
@Override
- public RulesProfile createProfile(ValidationMessages messages) {
- Reader pmdSonarWayProfile = new InputStreamReader(this.getClass().getResourceAsStream("/org/sonar/plugins/pmd/profile-sonar-way.xml"));
- RulesProfile profile = importer.importProfile(pmdSonarWayProfile, messages);
- profile.setLanguage(Java.KEY);
- profile.setName(RulesProfile.SONAR_WAY_NAME);
- return profile;
+ public RulesProfile createProfile(ValidationMessages validation) {
+ Reader config = null;
+ try {
+ config = new InputStreamReader(this.getClass().getResourceAsStream("/org/sonar/plugins/pmd/profile-sonar-way.xml"));
+
+ RulesProfile profile = importer.importProfile(config, validation);
+ profile.setLanguage(Java.KEY);
+ profile.setName(RulesProfile.SONAR_WAY_NAME);
+
+ return profile;
+ } finally {
+ Closeables.closeQuietly(config);
+ }
}
}
import org.sonar.api.utils.ValidationMessages;
public class SonarWayWithFindbugsProfile extends ProfileDefinition {
-
- private SonarWayProfile sonarWay;
+ private final SonarWayProfile sonarWay;
public SonarWayWithFindbugsProfile(SonarWayProfile sonarWay) {
this.sonarWay = sonarWay;
}
-
@Override
- public RulesProfile createProfile(ValidationMessages validationMessages) {
- RulesProfile profile = sonarWay.createProfile(validationMessages);
+ public RulesProfile createProfile(ValidationMessages validation) {
+ RulesProfile profile = sonarWay.createProfile(validation);
+
profile.setName(RulesProfile.SONAR_WAY_FINDBUGS_NAME);
profile.setLanguage(Java.KEY);
+
return profile;
}
}
-
*/
package org.sonar.plugins.pmd;
-import java.io.InputStreamReader;
-import java.io.Reader;
-
+import com.google.common.io.Closeables;
import org.sonar.api.profiles.ProfileDefinition;
import org.sonar.api.profiles.RulesProfile;
import org.sonar.api.resources.Java;
import org.sonar.api.utils.ValidationMessages;
-public final class SunConventionsProfile extends ProfileDefinition {
+import java.io.InputStreamReader;
+import java.io.Reader;
+public final class SunConventionsProfile extends ProfileDefinition {
private final PmdProfileImporter importer;
public SunConventionsProfile(PmdProfileImporter importer) {
}
@Override
- public RulesProfile createProfile(ValidationMessages messages) {
- Reader pmdSonarWayProfile = new InputStreamReader(this.getClass().getResourceAsStream(
- "/org/sonar/plugins/pmd/profile-sun-conventions.xml"));
- RulesProfile profile = importer.importProfile(pmdSonarWayProfile, messages);
- profile.setName(RulesProfile.SUN_CONVENTIONS_NAME);
- profile.setLanguage(Java.KEY);
- return profile;
+ public RulesProfile createProfile(ValidationMessages validation) {
+ Reader config = null;
+ try {
+ config = new InputStreamReader(this.getClass().getResourceAsStream("/org/sonar/plugins/pmd/profile-sun-conventions.xml"));
+
+ RulesProfile profile = importer.importProfile(config, validation);
+ profile.setLanguage(Java.KEY);
+ profile.setName(RulesProfile.SUN_CONVENTIONS_NAME);
+
+ return profile;
+ } finally {
+ Closeables.closeQuietly(config);
+ }
}
}
--- /dev/null
+<rules>
+ <rule key="JUnitStaticSuite">
+ <priority>MAJOR</priority>
+ <configKey><![CDATA[rulesets/junit.xml/JUnitStaticSuite]]></configKey>
+ </rule>
+ <rule key="JUnitSpelling">
+ <priority>MAJOR</priority>
+ <configKey><![CDATA[rulesets/junit.xml/JUnitSpelling]]></configKey>
+ </rule>
+ <rule key="JUnitAssertionsShouldIncludeMessage">
+ <priority>MINOR</priority>
+ <configKey><![CDATA[rulesets/junit.xml/JUnitAssertionsShouldIncludeMessage]]></configKey>
+ </rule>
+ <rule key="JUnitTestsShouldIncludeAssert">
+ <priority>MAJOR</priority>
+ <configKey><![CDATA[rulesets/junit.xml/JUnitTestsShouldIncludeAssert]]></configKey>
+ </rule>
+ <rule key="TestClassWithoutTestCases">
+ <priority>MAJOR</priority>
+ <configKey><![CDATA[rulesets/junit.xml/TestClassWithoutTestCases]]></configKey>
+ </rule>
+ <rule key="UnnecessaryBooleanAssertion">
+ <priority>MINOR</priority>
+ <configKey><![CDATA[rulesets/junit.xml/UnnecessaryBooleanAssertion]]></configKey>
+ </rule>
+ <rule key="UseAssertEqualsInsteadOfAssertTrue">
+ <priority>MINOR</priority>
+ <configKey><![CDATA[rulesets/junit.xml/UseAssertEqualsInsteadOfAssertTrue]]></configKey>
+ </rule>
+ <rule key="UseAssertSameInsteadOfAssertTrue">
+ <priority>MINOR</priority>
+ <configKey><![CDATA[rulesets/junit.xml/UseAssertSameInsteadOfAssertTrue]]></configKey>
+ </rule>
+ <rule key="UseAssertNullInsteadOfAssertTrue">
+ <priority>MINOR</priority>
+ <configKey><![CDATA[rulesets/junit.xml/UseAssertNullInsteadOfAssertTrue]]></configKey>
+ </rule>
+ <rule key="SimplifyBooleanAssertion">
+ <priority>MINOR</priority>
+ <configKey><![CDATA[rulesets/junit.xml/SimplifyBooleanAssertion]]></configKey>
+ </rule>
+</rules>
\ No newline at end of file
*/
package org.sonar.plugins.pmd;
-import org.apache.commons.io.FileUtils;
+import net.sourceforge.pmd.Report;
+import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
+import org.junit.rules.ExpectedException;
import org.sonar.api.config.Settings;
-import org.sonar.api.profiles.RulesProfile;
-import org.sonar.api.resources.Project;
import org.sonar.api.resources.ProjectFileSystem;
-import org.sonar.api.test.MavenTestUtils;
+import org.sonar.api.utils.SonarException;
import java.io.File;
import java.io.IOException;
-import java.util.List;
-import static org.hamcrest.Matchers.*;
-import static org.junit.Assert.assertThat;
+import static org.fest.assertions.Assertions.assertThat;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Matchers.matches;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
public class PmdConfigurationTest {
+ PmdConfiguration configuration;
+
+ Settings settings = new Settings();
+ ProjectFileSystem fs = mock(ProjectFileSystem.class);
+
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+
+ @Before
+ public void setUpPmdConfiguration() {
+ configuration = new PmdConfiguration(fs, settings);
+ }
+
+ @Test
+ public void should_return_default_target_xml_report_when_property_is_not_set() {
+ File targetXMLReport = configuration.getTargetXMLReport();
+
+ assertThat(targetXMLReport).isNull();
+ }
+
+ @Test
+ public void should_set_target_xml_report() {
+ when(fs.resolvePath("pmd-result.xml")).thenReturn(new File("/workingDir/pmd-result.xml"));
+
+ settings.setProperty(PmdConfiguration.PROPERTY_GENERATE_XML, true);
+ File targetXMLReport = configuration.getTargetXMLReport();
+
+ assertThat(targetXMLReport).isEqualTo(new File("/workingDir/pmd-result.xml"));
+ }
@Test
- public void writeConfigurationToWorkingDir() throws IOException {
- Project project = MavenTestUtils.loadProjectFromPom(getClass(), "writeConfigurationToWorkingDir/pom.xml");
+ public void should_dump_xml_rule_set() throws IOException {
+ when(fs.writeToWorkingDirectory("<rules>", "pmd.xml")).thenReturn(new File("/workingDir/pmd.xml"));
- PmdConfiguration configuration = new PmdConfiguration(new PmdProfileExporter(), RulesProfile.create(), project, null);
- List<String> rulesets = configuration.getRulesets();
+ File rulesFile = configuration.dumpXmlRuleSet("pmd", "<rules>");
- assertThat(rulesets.size(), is(1));
- File xmlFile = new File(rulesets.get(0));
- assertThat(xmlFile.exists(), is(true));
- assertThat(FileUtils.readFileToString(xmlFile), is("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<ruleset />\r\n\r\n"));
+ assertThat(rulesFile).isEqualTo(new File("/workingDir/pmd.xml"));
}
@Test
- public void shouldReturnTargetXMLReport() {
- Project project = new Project("key");
- ProjectFileSystem fs = mock(ProjectFileSystem.class);
- when(fs.getSonarWorkingDirectory()).thenReturn(new File("/tmp"));
- project.setFileSystem(fs);
- Settings settings = new Settings();
- PmdConfiguration configuration = new PmdConfiguration(null, null, project, settings);
+ public void should_fail_to_dump_xml_rule_set() throws IOException {
+ when(fs.writeToWorkingDirectory("<xml>", "pmd.xml")).thenThrow(new IOException("BUG"));
- assertThat(configuration.getTargetXMLReport(), nullValue());
+ expectedException.expect(SonarException.class);
+ expectedException.expectMessage("Fail to save the PMD configuration");
+
+ configuration.dumpXmlRuleSet("pmd", "<xml>");
+ }
+
+ @Test
+ public void should_dump_xml_report() throws IOException {
+ when(fs.writeToWorkingDirectory(matches(".*[\r\n]*<pmd.*[\r\n].*</pmd>"), eq("pmd-result.xml"))).thenReturn(new File("/workingDir/pmd-result.xml"));
settings.setProperty(PmdConfiguration.PROPERTY_GENERATE_XML, true);
- assertThat(configuration.getTargetXMLReport(), equalTo(new File("/tmp/pmd-result.xml")));
+ File reportFile = configuration.dumpXmlReport(new Report());
+
+ assertThat(reportFile).isEqualTo(new File("/workingDir/pmd-result.xml"));
}
+ @Test
+ public void should_ignore_xml_report_when_property_is_not_set() {
+ File reportFile = configuration.dumpXmlReport(new Report());
+
+ assertThat(reportFile).isNull();
+ verifyZeroInteractions(fs);
+ }
}
package org.sonar.plugins.pmd;
import com.google.common.base.Charsets;
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.lang.StringUtils;
-import org.junit.Rule;
+import net.sourceforge.pmd.Report;
+import net.sourceforge.pmd.RuleContext;
+import net.sourceforge.pmd.RuleSets;
+import org.junit.Before;
import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
+import org.mockito.Mockito;
+import org.sonar.api.profiles.RulesProfile;
+import org.sonar.api.resources.InputFile;
import org.sonar.api.resources.Java;
import org.sonar.api.resources.Project;
import org.sonar.api.resources.ProjectFileSystem;
+import org.sonar.test.TestUtils;
import java.io.File;
-import java.io.IOException;
import java.util.Arrays;
+import java.util.Collections;
-import static org.hamcrest.Matchers.nullValue;
-import static org.hamcrest.core.Is.is;
-import static org.hamcrest.number.OrderingComparisons.greaterThan;
-import static org.junit.Assert.assertThat;
+import static org.fest.assertions.Assertions.assertThat;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
public class PmdExecutorTest {
+ PmdExecutor pmdExecutor;
- @Rule
- public TemporaryFolder temp = new TemporaryFolder();
+ Project project = mock(Project.class);
+ ProjectFileSystem projectFileSystem = mock(ProjectFileSystem.class);
+ RulesProfile rulesProfile = mock(RulesProfile.class);
+ PmdProfileExporter pmdProfileExporter = mock(PmdProfileExporter.class);
+ PmdConfiguration pmdConfiguration = mock(PmdConfiguration.class);
+ PmdTemplate pmdTemplate = mock(PmdTemplate.class);
+
+ @Before
+ public void setUpPmdExecutor() {
+ pmdExecutor = Mockito.spy(new PmdExecutor(project, projectFileSystem, rulesProfile, pmdProfileExporter, pmdConfiguration));
+
+ doReturn(pmdTemplate).when(pmdExecutor).createPmdTemplate();
+ }
@Test
- public void executeOnManySourceDirs() throws IOException {
- File workDir = temp.getRoot();
- Project project = new Project("two-source-dirs");
-
- ProjectFileSystem fs = mock(ProjectFileSystem.class);
- File root = new File(getClass().getResource("/org/sonar/plugins/pmd/PmdExecutorTest/executeOnManySourceDirs/").toURI());
- when(fs.getSourceFiles(Java.INSTANCE)).thenReturn(Arrays.asList(new File(root, "src1/FirstClass.java"), new File(root, "src2/SecondClass.java")));
- when(fs.getSourceCharset()).thenReturn(Charsets.UTF_8);
- when(fs.getSonarWorkingDirectory()).thenReturn(workDir);
- project.setFileSystem(fs);
-
- PmdConfiguration conf = mock(PmdConfiguration.class);
- File file = FileUtils.toFile(getClass().getResource("/org/sonar/plugins/pmd/PmdExecutorTest/executeOnManySourceDirs/pmd.xml").toURI().toURL());
- when(conf.getRulesets()).thenReturn(Arrays.asList(file.getAbsolutePath()));
- File xmlReport = new File(workDir, "pmd-result.xml");
- when(conf.getTargetXMLReport()).thenReturn(xmlReport);
-
- PmdExecutor executor = new PmdExecutor(project, conf);
- executor.execute();
- assertThat(xmlReport.exists(), is(true));
-
- String xml = FileUtils.readFileToString(xmlReport);
-
- // errors on the two source files
- assertThat(StringUtils.countMatches(xml, "<file"), is(2));
- assertThat(StringUtils.countMatches(xml, "<violation"), greaterThan(2));
+ public void should_execute_pmd_on_source_files_and_test_files() {
+ InputFile srcFile = file("src/Class.java");
+ InputFile tstFile = file("test/ClassTest.java");
+ when(pmdProfileExporter.exportProfile(PmdConstants.REPOSITORY_KEY, rulesProfile)).thenReturn(TestUtils.getResourceContent("/org/sonar/plugins/pmd/simple.xml"));
+ when(pmdProfileExporter.exportProfile(PmdConstants.TEST_REPOSITORY_KEY, rulesProfile)).thenReturn(TestUtils.getResourceContent("/org/sonar/plugins/pmd/junit.xml"));
+ when(projectFileSystem.getSourceCharset()).thenReturn(Charsets.UTF_8);
+ when(projectFileSystem.mainFiles(Java.KEY)).thenReturn(Arrays.asList(srcFile));
+ when(projectFileSystem.testFiles(Java.KEY)).thenReturn(Arrays.asList(tstFile));
+
+ Report report = pmdExecutor.execute();
+
+ verify(pmdTemplate).process(eq(new File("src/Class.java")), eq(Charsets.UTF_8), any(RuleSets.class), any(RuleContext.class));
+ verify(pmdTemplate).process(eq(new File("test/ClassTest.java")), eq(Charsets.UTF_8), any(RuleSets.class), any(RuleContext.class));
+ assertThat(report).isNotNull();
}
@Test
- public void ignorePmdFailures() throws IOException {
- final File workDir = temp.getRoot();
- Project project = new Project("ignorePmdFailures");
-
- ProjectFileSystem fs = mock(ProjectFileSystem.class);
- when(fs.getSourceFiles(Java.INSTANCE)).thenReturn(Arrays.asList(new File("test-resources/ignorePmdFailures/DoesNotCompile.java")));
- when(fs.getSourceCharset()).thenReturn(Charsets.UTF_8);
- when(fs.getSonarWorkingDirectory()).thenReturn(workDir);
- project.setFileSystem(fs);
-
- PmdConfiguration conf = mock(PmdConfiguration.class);
- when(conf.getRulesets()).thenReturn(Arrays.asList(new File("test-resources/ignorePmdFailures/pmd.xml").getAbsolutePath()));
- File xmlReport = new File(workDir, "pmd-result.xml");
- when(conf.getTargetXMLReport()).thenReturn(xmlReport);
- PmdExecutor executor = new PmdExecutor(project, conf);
-
- executor.execute();
- assertThat(xmlReport.exists(), is(true));
+ public void should_dump_configuration_as_xml() {
+ when(pmdProfileExporter.exportProfile(PmdConstants.REPOSITORY_KEY, rulesProfile)).thenReturn(TestUtils.getResourceContent("/org/sonar/plugins/pmd/simple.xml"));
+ when(pmdProfileExporter.exportProfile(PmdConstants.TEST_REPOSITORY_KEY, rulesProfile)).thenReturn(TestUtils.getResourceContent("/org/sonar/plugins/pmd/junit.xml"));
+
+ Report report = pmdExecutor.execute();
+
+ verify(pmdConfiguration).dumpXmlReport(report);
}
@Test
- public void shouldNormalizeJavaVersion() {
- assertThat(PmdExecutor.getNormalizedJavaVersion(null), nullValue());
- assertThat(PmdExecutor.getNormalizedJavaVersion(""), is(""));
- assertThat(PmdExecutor.getNormalizedJavaVersion("1.1"), is("1.3"));
- assertThat(PmdExecutor.getNormalizedJavaVersion("1.2"), is("1.3"));
- assertThat(PmdExecutor.getNormalizedJavaVersion("1.4"), is("1.4"));
- assertThat(PmdExecutor.getNormalizedJavaVersion("5"), is("1.5"));
- assertThat(PmdExecutor.getNormalizedJavaVersion("6"), is("1.6"));
+ public void should_dump_ruleset_as_xml() {
+ InputFile srcFile = file("src/Class.java");
+ InputFile tstFile = file("test/ClassTest.java");
+ when(pmdProfileExporter.exportProfile(PmdConstants.REPOSITORY_KEY, rulesProfile)).thenReturn(TestUtils.getResourceContent("/org/sonar/plugins/pmd/simple.xml"));
+ when(pmdProfileExporter.exportProfile(PmdConstants.TEST_REPOSITORY_KEY, rulesProfile)).thenReturn(TestUtils.getResourceContent("/org/sonar/plugins/pmd/junit.xml"));
+ when(projectFileSystem.mainFiles(Java.KEY)).thenReturn(Arrays.asList(srcFile));
+ when(projectFileSystem.testFiles(Java.KEY)).thenReturn(Arrays.asList(tstFile));
+
+ pmdExecutor.execute();
+
+ verify(pmdConfiguration).dumpXmlRuleSet(PmdConstants.REPOSITORY_KEY, TestUtils.getResourceContent("/org/sonar/plugins/pmd/simple.xml"));
+ verify(pmdConfiguration).dumpXmlRuleSet(PmdConstants.TEST_REPOSITORY_KEY, TestUtils.getResourceContent("/org/sonar/plugins/pmd/junit.xml"));
}
+ @Test
+ public void should_ignore_empty_test_dir() {
+ InputFile srcFile = file("src/Class.java");
+ doReturn(pmdTemplate).when(pmdExecutor).createPmdTemplate();
+ when(pmdProfileExporter.exportProfile(PmdConstants.REPOSITORY_KEY, rulesProfile)).thenReturn(TestUtils.getResourceContent("/org/sonar/plugins/pmd/simple.xml"));
+ when(projectFileSystem.getSourceCharset()).thenReturn(Charsets.UTF_8);
+ when(projectFileSystem.mainFiles(Java.KEY)).thenReturn(Arrays.asList(srcFile));
+ when(projectFileSystem.testFiles(Java.KEY)).thenReturn(Collections.<InputFile> emptyList());
+
+ pmdExecutor.execute();
+
+ verify(pmdTemplate).process(eq(new File("src/Class.java")), eq(Charsets.UTF_8), any(RuleSets.class), any(RuleContext.class));
+ verifyNoMoreInteractions(pmdTemplate);
+ }
+
+ static InputFile file(String path) {
+ InputFile inputFile = mock(InputFile.class);
+ when(inputFile.getFile()).thenReturn(new File(path));
+ return inputFile;
+ }
}
--- /dev/null
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 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.pmd;
+
+import org.junit.Test;
+import org.sonar.api.rules.RulePriority;
+
+import static org.fest.assertions.Assertions.assertThat;
+
+public class PmdLevelUtilsTest {
+ @Test
+ public void should_get_priority_from_level() {
+ assertThat(PmdLevelUtils.fromLevel("1")).isSameAs(RulePriority.BLOCKER);
+ assertThat(PmdLevelUtils.fromLevel("2")).isSameAs(RulePriority.CRITICAL);
+ assertThat(PmdLevelUtils.fromLevel("3")).isSameAs(RulePriority.MAJOR);
+ assertThat(PmdLevelUtils.fromLevel("4")).isSameAs(RulePriority.MINOR);
+ assertThat(PmdLevelUtils.fromLevel("5")).isSameAs(RulePriority.INFO);
+ assertThat(PmdLevelUtils.fromLevel("?")).isNull();
+ assertThat(PmdLevelUtils.fromLevel(null)).isNull();
+ }
+
+ @Test
+ public void should_get_level_from_priority() {
+ assertThat(PmdLevelUtils.toLevel(RulePriority.BLOCKER)).isEqualTo("1");
+ assertThat(PmdLevelUtils.toLevel(RulePriority.CRITICAL)).isEqualTo("2");
+ assertThat(PmdLevelUtils.toLevel(RulePriority.MAJOR)).isEqualTo("3");
+ assertThat(PmdLevelUtils.toLevel(RulePriority.MINOR)).isEqualTo("4");
+ assertThat(PmdLevelUtils.toLevel(RulePriority.INFO)).isEqualTo("5");
+ }
+}
*/
package org.sonar.plugins.pmd;
-import static org.hamcrest.number.OrderingComparisons.greaterThan;
-import static org.junit.Assert.assertThat;
-
import org.junit.Test;
+import org.sonar.api.Extension;
+
+import java.util.List;
+
+import static org.fest.assertions.Assertions.assertThat;
public class PmdPluginTest {
+ PmdPlugin plugin = new PmdPlugin();
@Test
- public void testGetExtensions() {
- PmdPlugin plugin = new PmdPlugin();
- assertThat(plugin.getExtensions().size(), greaterThan(1));
- }
+ public void should_contain_both_rule_repositories() {
+ List<Class<? extends Extension>> extensions = plugin.getExtensions();
+ assertThat(extensions).contains(PmdRuleRepository.class, PmdUnitTestsRuleRepository.class);
+ }
}
*/
package org.sonar.plugins.pmd;
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.io.input.CharSequenceReader;
-import org.apache.commons.lang.StringUtils;
-import org.hamcrest.Description;
-import org.hamcrest.TypeSafeMatcher;
import org.junit.Test;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
import org.sonar.api.platform.ServerFileSystem;
import org.sonar.api.profiles.RulesProfile;
import org.sonar.api.rules.ActiveRule;
import org.sonar.plugins.pmd.xml.PmdRule;
import org.sonar.test.TestUtils;
-import java.io.Reader;
import java.io.StringReader;
-import java.io.StringWriter;
-import java.util.Collection;
import java.util.List;
-import static org.hamcrest.Matchers.is;
-import static org.hamcrest.Matchers.nullValue;
-import static org.junit.Assert.assertThat;
+import static org.fest.assertions.Assertions.assertThat;
+import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static org.sonar.test.MoreConditions.equalsIgnoreEOL;
public class PmdProfileExporterTest {
-
- private final PmdProfileExporter exporter = new PmdProfileExporter();
+ PmdProfileExporter exporter = new PmdProfileExporter();
@Test
- public void testExportProfile() {
- ServerFileSystem fileSystem = mock(ServerFileSystem.class);
- PmdRuleRepository repository = new PmdRuleRepository(fileSystem, new XMLRuleParser());
- List<Rule> rules = repository.createRules();
+ public void should_export_pmd_profile() {
+ String importedXml = TestUtils.getResourceContent("/org/sonar/plugins/pmd/export_simple.xml");
- RuleFinder ruleFinder = new FakeRuleFinder(rules);
- PmdProfileImporter importer = new PmdProfileImporter(ruleFinder);
- Reader reader = new StringReader(TestUtils.getResourceContent("/org/sonar/plugins/pmd/simple.xml"));
- RulesProfile rulesProfile = importer.importProfile(reader, ValidationMessages.create());
+ String exportedXml = exporter.exportProfile(PmdConstants.REPOSITORY_KEY, importProfile(importedXml));
- StringWriter xmlOutput = new StringWriter();
- exporter.exportProfile(rulesProfile, xmlOutput);
+ assertThat(exportedXml).satisfies(equalsIgnoreEOL(importedXml));
+ }
- assertThat(xmlOutput.toString(), new IsEqualIgnoringEOL(TestUtils.getResourceContent("/org/sonar/plugins/pmd/export_simple.xml")));
+ @Test
+ public void should_export_empty_configuration_as_xml() {
+ String exportedXml = exporter.exportProfile(PmdConstants.REPOSITORY_KEY, RulesProfile.create());
+
+ assertThat(exportedXml).satisfies(equalsIgnoreEOL("<?xml version=\"1.0\" encoding=\"UTF-8\"?><ruleset />"));
}
@Test
- public void testExportXPathRule() {
- StringWriter xmlOutput = new StringWriter();
+ public void should_export_xPath_rule() {
+ Rule rule = Rule.create(PmdConstants.REPOSITORY_KEY, "MyOwnRule", "This is my own xpath rule.")
+ .setConfigKey(PmdConstants.XPATH_CLASS)
+ .setRepositoryKey(PmdConstants.REPOSITORY_KEY);
+ rule.createParameter(PmdConstants.XPATH_EXPRESSION_PARAM);
+ rule.createParameter(PmdConstants.XPATH_MESSAGE_PARAM);
+
RulesProfile profile = RulesProfile.create();
- Rule xpathTemplate = Rule.create(PmdConstants.REPOSITORY_KEY, "MyOwnRule", "This is my own xpath rule.")
- .setConfigKey(PmdConstants.XPATH_CLASS).setRepositoryKey(PmdConstants.REPOSITORY_KEY);
- xpathTemplate.createParameter(PmdConstants.XPATH_EXPRESSION_PARAM);
- xpathTemplate.createParameter(PmdConstants.XPATH_MESSAGE_PARAM);
- ActiveRule xpath = profile.activateRule(xpathTemplate, null);
+ ActiveRule xpath = profile.activateRule(rule, null);
xpath.setParameter(PmdConstants.XPATH_EXPRESSION_PARAM, "//FieldDeclaration");
xpath.setParameter(PmdConstants.XPATH_MESSAGE_PARAM, "This is bad");
- exporter.exportProfile(profile, xmlOutput);
- assertThat(xmlOutput.toString(), new IsEqualIgnoringEOL(TestUtils.getResourceContent("/org/sonar/plugins/pmd/export_xpath_rules.xml")));
- }
- private static class IsEqualIgnoringEOL extends TypeSafeMatcher<CharSequence> {
- private final String expected;
+ String exportedXml = exporter.exportProfile(PmdConstants.REPOSITORY_KEY, profile);
- public IsEqualIgnoringEOL(CharSequence expected) {
- this.expected = normalize(expected);
- }
-
- public void describeTo(Description description) {
- description.appendText("string equal ").appendText(expected);
- }
-
- @Override
- public boolean matchesSafely(CharSequence item) {
- return StringUtils.equals(expected, normalize(item));
- }
-
- private static String normalize(CharSequence charSequence) {
- return StringUtils.join(IOUtils.lineIterator(new CharSequenceReader(charSequence)), IOUtils.LINE_SEPARATOR_UNIX);
- }
+ assertThat(exportedXml).satisfies(equalsIgnoreEOL(TestUtils.getResourceContent("/org/sonar/plugins/pmd/export_xpath_rules.xml")));
}
@Test(expected = SonarException.class)
- public void shouldFailIfMessageNotProvidedForXPathRule() {
- String xpathExpression = "xpathExpression";
-
+ public void should_fail_if_message_not_provided_for_xPath_rule() {
PmdRule rule = new PmdRule(PmdConstants.XPATH_CLASS);
- rule.addProperty(new PmdProperty(PmdConstants.XPATH_EXPRESSION_PARAM, xpathExpression));
+
+ rule.addProperty(new PmdProperty(PmdConstants.XPATH_EXPRESSION_PARAM, "xpathExpression"));
rule.setName("MyOwnRule");
exporter.processXPathRule("xpathKey", rule);
}
- @Test(expected = SonarException.class)
- public void shouldFailIfXPathNotProvidedForXPathRule() {
- String message = "This is bad";
-
+ @Test
+ public void should_process_xPath_rule() {
PmdRule rule = new PmdRule(PmdConstants.XPATH_CLASS);
- rule.addProperty(new PmdProperty(PmdConstants.XPATH_MESSAGE_PARAM, message));
rule.setName("MyOwnRule");
+ rule.addProperty(new PmdProperty(PmdConstants.XPATH_EXPRESSION_PARAM, "xpathExpression"));
+ rule.addProperty(new PmdProperty(PmdConstants.XPATH_MESSAGE_PARAM, "message"));
exporter.processXPathRule("xpathKey", rule);
- }
- @Test
- public void testProcessingXPathRule() {
- String message = "This is bad";
- String xpathExpression = "xpathExpression";
+ assertThat(rule.getMessage()).isEqualTo("message");
+ assertThat(rule.getRef()).isNull();
+ assertThat(rule.getClazz()).isEqualTo(PmdConstants.XPATH_CLASS);
+ assertThat(rule.getProperty(PmdConstants.XPATH_MESSAGE_PARAM)).isNull();
+ assertThat(rule.getName()).isEqualTo("xpathKey");
+ assertThat(rule.getProperty(PmdConstants.XPATH_EXPRESSION_PARAM).getValue()).isEqualTo("xpathExpression");
+ }
+ @Test(expected = SonarException.class)
+ public void should_fail_if_xPath_not_provided() {
PmdRule rule = new PmdRule(PmdConstants.XPATH_CLASS);
- rule.addProperty(new PmdProperty(PmdConstants.XPATH_EXPRESSION_PARAM, xpathExpression));
- rule.addProperty(new PmdProperty(PmdConstants.XPATH_MESSAGE_PARAM, message));
rule.setName("MyOwnRule");
+ rule.addProperty(new PmdProperty(PmdConstants.XPATH_MESSAGE_PARAM, "This is bad"));
exporter.processXPathRule("xpathKey", rule);
-
- assertThat(rule.getMessage(), is(message));
- assertThat(rule.getRef(), is(nullValue()));
- assertThat(rule.getClazz(), is(PmdConstants.XPATH_CLASS));
- assertThat(rule.getProperty(PmdConstants.XPATH_MESSAGE_PARAM), is(nullValue()));
- assertThat(rule.getName(), is("xpathKey"));
- assertThat(rule.getProperty(PmdConstants.XPATH_EXPRESSION_PARAM).getValue(), is(xpathExpression));
}
- private static class FakeRuleFinder implements RuleFinder {
-
- private final List<Rule> rules;
-
- public FakeRuleFinder(List<Rule> rules) {
- this.rules = rules;
- }
-
- public Rule findById(int ruleId) {
- throw new UnsupportedOperationException();
- }
-
- public Rule findByKey(String repositoryKey, String key) {
- throw new UnsupportedOperationException();
- }
+ static RulesProfile importProfile(String configuration) {
+ PmdRuleRepository pmdRuleRepository = new PmdRuleRepository(mock(ServerFileSystem.class), new XMLRuleParser());
+ RuleFinder ruleFinder = createRuleFinder(pmdRuleRepository.createRules());
+ PmdProfileImporter importer = new PmdProfileImporter(ruleFinder);
- public Collection<Rule> findAll(RuleQuery query) {
- throw new UnsupportedOperationException();
- }
+ return importer.importProfile(new StringReader(configuration), ValidationMessages.create());
+ }
- public Rule find(RuleQuery query) {
- for (Rule rule : rules) {
- if (query.getConfigKey().equals(rule.getConfigKey())) {
- rule.setRepositoryKey(PmdConstants.REPOSITORY_KEY);
- return rule;
+ static RuleFinder createRuleFinder(final List<Rule> rules) {
+ RuleFinder ruleFinder = mock(RuleFinder.class);
+ when(ruleFinder.find(any(RuleQuery.class))).then(new Answer<Rule>() {
+ public Rule answer(InvocationOnMock invocation) {
+ RuleQuery query = (RuleQuery) invocation.getArguments()[0];
+ for (Rule rule : rules) {
+ if (query.getConfigKey().equals(rule.getConfigKey())) {
+ return rule.setRepositoryKey(PmdConstants.REPOSITORY_KEY);
+ }
}
+ return null;
}
- return null;
- }
+ });
+ return ruleFinder;
}
}
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.sonar.api.profiles.RulesProfile;
-import org.sonar.api.rules.*;
+import org.sonar.api.rules.ActiveRule;
+import org.sonar.api.rules.Rule;
+import org.sonar.api.rules.RuleFinder;
+import org.sonar.api.rules.RulePriority;
+import org.sonar.api.rules.RuleQuery;
import org.sonar.api.utils.ValidationMessages;
import org.sonar.plugins.pmd.xml.PmdRuleset;
import org.sonar.test.TestUtils;
import java.io.Reader;
import java.io.StringReader;
-import static org.hamcrest.Matchers.is;
-import static org.hamcrest.Matchers.nullValue;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertThat;
+import static org.fest.assertions.Assertions.assertThat;
import static org.mockito.Matchers.anyObject;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class PmdProfileImporterTest {
-
- private PmdProfileImporter importer;
- private ValidationMessages messages;
+ PmdProfileImporter importer;
+ ValidationMessages messages;
@Before
- public void before() {
+ public void setUpImporter() {
messages = ValidationMessages.create();
- RuleFinder finder = createRuleFinder();
- importer = new PmdProfileImporter(finder);
+ importer = new PmdProfileImporter(createRuleFinder());
}
@Test
- public void testBuildPmdRuleset() {
- Reader reader = new StringReader(TestUtils.getResourceContent("/org/sonar/plugins/pmd/simple.xml"));
+ public void should_import_pmd_ruleset() {
+ Reader reader = read("/org/sonar/plugins/pmd/simple.xml");
+
PmdRuleset pmdRuleset = importer.parsePmdRuleset(reader, messages);
- assertThat(pmdRuleset.getPmdRules().size(), is(3));
+
+ assertThat(pmdRuleset.getPmdRules()).hasSize(3);
}
@Test
- public void testImportingSimpleProfile() {
- Reader reader = new StringReader(TestUtils.getResourceContent("/org/sonar/plugins/pmd/simple.xml"));
+ public void should_import_simple_profile() {
+ Reader reader = read("/org/sonar/plugins/pmd/simple.xml");
+
RulesProfile profile = importer.importProfile(reader, messages);
- assertThat(profile.getActiveRules().size(), is(3));
- assertNotNull(profile.getActiveRuleByConfigKey("pmd", "rulesets/coupling.xml/ExcessiveImports"));
- assertNotNull(profile.getActiveRuleByConfigKey("pmd", "rulesets/design.xml/UseNotifyAllInsteadOfNotify"));
- assertThat(messages.hasErrors(), is(false));
+ assertThat(profile.getActiveRules()).hasSize(3);
+ assertThat(profile.getActiveRuleByConfigKey("pmd", "rulesets/coupling.xml/ExcessiveImports")).isNotNull();
+ assertThat(profile.getActiveRuleByConfigKey("pmd", "rulesets/design.xml/UseNotifyAllInsteadOfNotify")).isNotNull();
+ assertThat(messages.hasErrors()).isFalse();
}
@Test
- public void testImportingProfileWithXPathRule() {
- Reader reader = new StringReader(TestUtils.getResourceContent("/org/sonar/plugins/pmd/export_xpath_rules.xml"));
+ public void should_import_profile_with_xpath_rule() {
+ Reader reader = read("/org/sonar/plugins/pmd/export_xpath_rules.xml");
+
RulesProfile profile = importer.importProfile(reader, messages);
- assertThat(profile.getActiveRules().size(), is(0));
- assertThat(messages.hasWarnings(), is(true));
+ assertThat(profile.getActiveRules()).isEmpty();
+ assertThat(messages.hasWarnings()).isTrue();
}
@Test
- public void testImportingParameters() {
- Reader reader = new StringReader(TestUtils.getResourceContent("/org/sonar/plugins/pmd/simple.xml"));
- RulesProfile profile = importer.importProfile(reader, messages);
+ public void should_import_parameter() {
+ Reader reader = read("/org/sonar/plugins/pmd/simple.xml");
+ RulesProfile profile = importer.importProfile(reader, messages);
ActiveRule activeRule = profile.getActiveRuleByConfigKey("pmd", "rulesets/coupling.xml/ExcessiveImports");
- assertThat(activeRule.getActiveRuleParams().size(), is(1));
- assertThat(activeRule.getParameter("max"), is("30"));
+
+ assertThat(activeRule.getParameter("max")).isEqualTo("30");
}
@Test
- public void testImportingDefaultPriority() {
- Reader reader = new StringReader(TestUtils.getResourceContent("/org/sonar/plugins/pmd/simple.xml"));
- RulesProfile profile = importer.importProfile(reader, messages);
+ public void should_import_default_priority() {
+ Reader reader = read("/org/sonar/plugins/pmd/simple.xml");
+ RulesProfile profile = importer.importProfile(reader, messages);
ActiveRule activeRule = profile.getActiveRuleByConfigKey("pmd", "rulesets/coupling.xml/ExcessiveImports");
- assertThat(activeRule.getSeverity(), is(RulePriority.BLOCKER)); // reuse the rule default priority
+
+ assertThat(activeRule.getSeverity()).isSameAs(RulePriority.BLOCKER);
}
@Test
- public void testImportingPriority() {
- Reader reader = new StringReader(TestUtils.getResourceContent("/org/sonar/plugins/pmd/simple.xml"));
+ public void should_import_priority() {
+ Reader reader = read("/org/sonar/plugins/pmd/simple.xml");
+
RulesProfile profile = importer.importProfile(reader, messages);
ActiveRule activeRule = profile.getActiveRuleByConfigKey("pmd", "rulesets/design.xml/UseNotifyAllInsteadOfNotify");
- assertThat(activeRule.getSeverity(), is(RulePriority.MINOR));
+ assertThat(activeRule.getSeverity()).isSameAs(RulePriority.MINOR);
activeRule = profile.getActiveRuleByConfigKey("pmd", "rulesets/coupling.xml/CouplingBetweenObjects");
- assertThat(activeRule.getSeverity(), is(RulePriority.CRITICAL));
+ assertThat(activeRule.getSeverity()).isSameAs(RulePriority.CRITICAL);
}
@Test
- public void testImportingPmdConfigurationWithUnknownNodes() {
- Reader reader = new StringReader(TestUtils.getResourceContent("/org/sonar/plugins/pmd/complex-with-unknown-nodes.xml"));
+ public void should_import_pmd_configuration_with_unknown_nodes() {
+ Reader reader = read("/org/sonar/plugins/pmd/complex-with-unknown-nodes.xml");
+
RulesProfile profile = importer.importProfile(reader, messages);
- assertThat(profile.getActiveRules().size(), is(3));
+ assertThat(profile.getActiveRules()).hasSize(3);
}
@Test
- public void testUnsupportedProperty() {
- Reader reader = new StringReader(TestUtils.getResourceContent("/org/sonar/plugins/pmd/simple.xml"));
- RulesProfile profile = importer.importProfile(reader, messages);
+ public void should_deal_with_unsupported_property() {
+ Reader reader = read("/org/sonar/plugins/pmd/simple.xml");
+ RulesProfile profile = importer.importProfile(reader, messages);
ActiveRule check = profile.getActiveRuleByConfigKey("pmd", "rulesets/coupling.xml/CouplingBetweenObjects");
- assertThat(check.getParameter("threshold"), nullValue());
- assertThat(messages.getWarnings().size(), is(1));
+
+ assertThat(check.getParameter("threshold")).isNull();
+ assertThat(messages.getWarnings()).hasSize(1);
}
@Test
- public void testUnvalidXML() {
+ public void should_fail_on_invalid_xml() {
Reader reader = new StringReader("not xml");
+
importer.importProfile(reader, messages);
- assertThat(messages.getErrors().size(), is(1));
+
+ assertThat(messages.getErrors()).hasSize(1);
}
@Test
- public void testImportingUnknownRules() {
- Reader reader = new StringReader(TestUtils.getResourceContent("/org/sonar/plugins/pmd/simple.xml"));
+ public void should_warn_on_unknown_rule() {
+ Reader reader = read("/org/sonar/plugins/pmd/simple.xml");
+
importer = new PmdProfileImporter(mock(RuleFinder.class));
RulesProfile profile = importer.importProfile(reader, messages);
- assertThat(profile.getActiveRules().size(), is(0));
- assertThat(messages.getWarnings().size(), is(3));
+ assertThat(profile.getActiveRules()).isEmpty();
+ assertThat(messages.getWarnings()).hasSize(3);
}
- private RuleFinder createRuleFinder() {
- RuleFinder ruleFinder = mock(RuleFinder.class);
- when(ruleFinder.find((RuleQuery) anyObject())).thenAnswer(new Answer<Rule>() {
+ static Reader read(String path) {
+ return new StringReader(TestUtils.getResourceContent(path));
+ }
- public Rule answer(InvocationOnMock iom) throws Throwable {
- RuleQuery query = (RuleQuery) iom.getArguments()[0];
- Rule rule = Rule.create(query.getRepositoryKey(), query.getConfigKey(), "Rule name - " + query.getConfigKey())
- .setConfigKey(query.getConfigKey()).setSeverity(RulePriority.BLOCKER);
+ static RuleFinder createRuleFinder() {
+ RuleFinder ruleFinder = mock(RuleFinder.class);
+ when(ruleFinder.find((RuleQuery) anyObject())).then(new Answer<Rule>() {
+ public Rule answer(InvocationOnMock invocation) {
+ RuleQuery query = (RuleQuery) invocation.getArguments()[0];
+ Rule rule = Rule.create(query.getRepositoryKey(), "", "").setConfigKey(query.getConfigKey()).setSeverity(RulePriority.BLOCKER);
if (rule.getConfigKey().equals("rulesets/coupling.xml/ExcessiveImports")) {
rule.createParameter("max");
}
--- /dev/null
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 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.pmd;
+
+import org.junit.Test;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+import org.sonar.api.profiles.ProfileDefinition;
+import org.sonar.api.profiles.RulesProfile;
+import org.sonar.api.rules.Rule;
+import org.sonar.api.rules.RuleFinder;
+import org.sonar.api.rules.RuleQuery;
+import org.sonar.api.utils.ValidationMessages;
+
+import static org.fest.assertions.Assertions.assertThat;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class PmdProfilesTest {
+ ValidationMessages validation = ValidationMessages.create();
+
+ @Test
+ public void should_create_sun_convention_profile() {
+ SunConventionsProfile sunConvention = new SunConventionsProfile(new PmdProfileImporter(ruleFinder()));
+
+ RulesProfile profile = sunConvention.createProfile(validation);
+
+ assertThat(profile.getActiveRulesByRepository(PmdConstants.REPOSITORY_KEY)).isNotEmpty();
+ assertThat(validation.hasErrors()).isFalse();
+ }
+
+ @Test
+ public void should_create_sonar_way_profile() {
+ ProfileDefinition sonarWay = new SonarWayProfile(new PmdProfileImporter(ruleFinder()));
+
+ RulesProfile profile = sonarWay.createProfile(validation);
+
+ assertThat(profile.getActiveRulesByRepository(PmdConstants.REPOSITORY_KEY)).isNotEmpty();
+ assertThat(validation.hasErrors()).isFalse();
+ }
+
+ @Test
+ public void should_create_sonar_way_with_findbugs_profile() {
+ ProfileDefinition sonarWayWithFindbugs = new SonarWayWithFindbugsProfile(new SonarWayProfile(new PmdProfileImporter(ruleFinder())));
+
+ RulesProfile profile = sonarWayWithFindbugs.createProfile(validation);
+
+ assertThat(profile.getActiveRulesByRepository(PmdConstants.REPOSITORY_KEY)).isNotEmpty();
+ assertThat(validation.hasErrors()).isFalse();
+ }
+
+ static RuleFinder ruleFinder() {
+ RuleFinder ruleFinder = mock(RuleFinder.class);
+ when(ruleFinder.find(any(RuleQuery.class))).then(new Answer<Rule>() {
+ public Rule answer(InvocationOnMock invocation) {
+ RuleQuery query = (RuleQuery) invocation.getArguments()[0];
+ return Rule.create(query.getRepositoryKey(), "", "");
+ }
+ });
+ return ruleFinder;
+ }
+}
*/
package org.sonar.plugins.pmd;
-import org.apache.commons.io.FileUtils;
+import org.junit.Before;
import org.junit.Test;
import org.sonar.api.platform.ServerFileSystem;
import org.sonar.api.rules.Rule;
import org.sonar.api.rules.XMLRuleParser;
+import org.sonar.test.TestUtils;
+import org.sonar.test.i18n.RuleRepositoryTestHelper;
import java.io.File;
-import java.util.Collections;
+import java.util.Arrays;
import java.util.List;
-import static org.hamcrest.Matchers.greaterThan;
-import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertThat;
+import static org.fest.assertions.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class PmdRuleRepositoryTest {
+ PmdRuleRepository repository;
+
+ ServerFileSystem fileSystem = mock(ServerFileSystem.class);
+
+ @Before
+ public void setUpRuleRepository() {
+ repository = new PmdRuleRepository(fileSystem, new XMLRuleParser());
+ }
@Test
- public void testLoadRepositoryFromXml() {
- ServerFileSystem fileSystem = mock(ServerFileSystem.class);
- PmdRuleRepository repository = new PmdRuleRepository(fileSystem, new XMLRuleParser());
+ public void should_have_correct_name_and_key() {
+ assertThat(repository.getKey()).isEqualTo("pmd");
+ assertThat(repository.getLanguage()).isEqualTo("java");
+ assertThat(repository.getName()).isEqualTo("PMD");
+ }
+
+ @Test
+ public void should_load_repository_from_xml() {
List<Rule> rules = repository.createRules();
- assertThat(rules.size(), greaterThan(100));
+
+ assertThat(rules.size()).isGreaterThan(100);
}
@Test
- public void shouldLoadExtensions() {
- ServerFileSystem fileSystem = mock(ServerFileSystem.class);
- File file = FileUtils.toFile(getClass().getResource("/org/sonar/plugins/pmd/rules-extension.xml"));
- when(fileSystem.getExtensions("pmd", "xml")).thenReturn(Collections.singletonList(file));
- PmdRuleRepository repository = new PmdRuleRepository(fileSystem, new XMLRuleParser());
+ public void should_load_extensions() {
+ File file = TestUtils.getResource("/org/sonar/plugins/pmd/rules-extension.xml");
+ when(fileSystem.getExtensions("pmd", "xml")).thenReturn(Arrays.asList(file));
+
List<Rule> rules = repository.createRules();
- assertThat(rules.size(), greaterThan(100));
- assertThat(rules.get(rules.size() - 1).getKey(), is("Extension"));
+
+ assertThat(rules).onProperty("key").contains("Extension");
}
+ @Test
+ public void should_exclude_junit_rules() {
+ List<Rule> rules = repository.createRules();
+
+ assertThat(rules).onProperty("key").excludes("JUnitStaticSuite");
+ }
+
+ @Test
+ public void should_provide_a_name_and_description_for_each_rule() {
+ List<Rule> rules = RuleRepositoryTestHelper.createRulesWithNameAndDescription("pmd", repository);
+
+ assertThat(rules).onProperty("name").excludes(null, "");
+ assertThat(rules).onProperty("description").excludes(null, "");
+ }
}
--- /dev/null
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 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.pmd;
+
+import com.google.common.collect.Iterators;
+import net.sourceforge.pmd.IRuleViolation;
+import net.sourceforge.pmd.Report;
+import org.junit.Before;
+import org.junit.Test;
+import org.sonar.api.batch.SensorContext;
+import org.sonar.api.profiles.RulesProfile;
+import org.sonar.api.resources.Java;
+import org.sonar.api.resources.Project;
+import org.sonar.api.rules.Violation;
+
+import static org.fest.assertions.Assertions.assertThat;
+import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.when;
+
+public class PmdSensorTest {
+ PmdSensor pmdSensor;
+
+ Project project = mock(Project.class, RETURNS_DEEP_STUBS);
+ RulesProfile profile = mock(RulesProfile.class, RETURNS_DEEP_STUBS);
+ PmdExecutor executor = mock(PmdExecutor.class);
+ PmdViolationToRuleViolation pmdViolationToRuleViolation = mock(PmdViolationToRuleViolation.class);
+ SensorContext sensorContext = mock(SensorContext.class);
+ Violation violation = mock(Violation.class);
+
+ @Before
+ public void setUpPmdSensor() {
+ pmdSensor = new PmdSensor(profile, executor, pmdViolationToRuleViolation);
+ }
+
+ @Test
+ public void should_execute_on_project_with_main_files_and_active_rules() {
+ boolean shouldExecute = pmdSensor.shouldExecuteOnProject(project);
+
+ assertThat(shouldExecute).isTrue();
+ }
+
+ @Test
+ public void should_not_execute_on_project_without_files() {
+ when(project.getFileSystem().mainFiles(Java.KEY).isEmpty()).thenReturn(true);
+ when(project.getFileSystem().testFiles(Java.KEY).isEmpty()).thenReturn(true);
+
+ boolean shouldExecute = pmdSensor.shouldExecuteOnProject(project);
+
+ assertThat(shouldExecute).isFalse();
+ }
+
+ @Test
+ public void should_not_execute_on_project_without_active_rules() {
+ when(profile.getActiveRulesByRepository(PmdConstants.REPOSITORY_KEY).isEmpty()).thenReturn(true);
+ when(profile.getActiveRulesByRepository(PmdConstants.TEST_REPOSITORY_KEY).isEmpty()).thenReturn(true);
+
+ boolean shouldExecute = pmdSensor.shouldExecuteOnProject(project);
+
+ assertThat(shouldExecute).isFalse();
+ }
+
+ @Test
+ public void should_report_violations() {
+ IRuleViolation pmdViolation = violation();
+ Report report = report(pmdViolation);
+ when(executor.execute()).thenReturn(report);
+ when(pmdViolationToRuleViolation.toViolation(pmdViolation, sensorContext)).thenReturn(violation);
+
+ pmdSensor.analyse(project, sensorContext);
+
+ verify(sensorContext).saveViolation(violation);
+ }
+
+ @Test
+ public void shouldnt_report_zero_violation() {
+ Report report = report();
+ when(executor.execute()).thenReturn(report);
+
+ pmdSensor.analyse(project, sensorContext);
+
+ verifyZeroInteractions(sensorContext);
+ }
+
+ @Test
+ public void shouldnt_report_invalid_violation() {
+ IRuleViolation pmdViolation = violation();
+ Report report = report(pmdViolation);
+ when(executor.execute()).thenReturn(report);
+ when(report.iterator()).thenReturn(Iterators.forArray(pmdViolation));
+ when(pmdViolationToRuleViolation.toViolation(pmdViolation, sensorContext)).thenReturn(null);
+
+ pmdSensor.analyse(project, sensorContext);
+
+ verifyZeroInteractions(sensorContext);
+ }
+
+ static IRuleViolation violation() {
+ return mock(IRuleViolation.class);
+ }
+
+ static Report report(IRuleViolation... violations) {
+ Report report = mock(Report.class);
+ when(report.iterator()).thenReturn(Iterators.forArray(violations));
+ return report;
+ }
+}
--- /dev/null
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 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.pmd;
+
+import net.sourceforge.pmd.PMD;
+import net.sourceforge.pmd.SourceType;
+import org.junit.Test;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+public class PmdTemplateTest {
+ PMD pmd = mock(PMD.class);
+
+ @Test
+ public void should_set_java11_version() {
+ PmdTemplate.setJavaVersion(pmd, "1.1");
+
+ verify(pmd).setJavaVersion(SourceType.JAVA_13);
+ }
+
+ @Test
+ public void should_set_java12_version() {
+ PmdTemplate.setJavaVersion(pmd, "1.2");
+
+ verify(pmd).setJavaVersion(SourceType.JAVA_13);
+ }
+
+ @Test
+ public void should_set_java5_version() {
+ PmdTemplate.setJavaVersion(pmd, "5");
+
+ verify(pmd).setJavaVersion(SourceType.JAVA_15);
+ }
+
+ @Test
+ public void should_set_java6_version() {
+ PmdTemplate.setJavaVersion(pmd, "6");
+
+ verify(pmd).setJavaVersion(SourceType.JAVA_16);
+ }
+}
--- /dev/null
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 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.pmd;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.sonar.api.rules.Rule;
+import org.sonar.api.rules.XMLRuleParser;
+import org.sonar.test.i18n.RuleRepositoryTestHelper;
+
+import java.util.List;
+
+import static org.fest.assertions.Assertions.assertThat;
+
+public class PmdUnitTestsRuleRepositoryTest {
+ PmdUnitTestsRuleRepository repository;
+
+ @Before
+ public void setUpRuleRepository() {
+ repository = new PmdUnitTestsRuleRepository(new XMLRuleParser());
+ }
+
+ @Test
+ public void should_have_correct_name_and_key() {
+ assertThat(repository.getKey()).isEqualTo("pmd-unit-tests");
+ assertThat(repository.getLanguage()).isEqualTo("java");
+ assertThat(repository.getName()).isEqualTo("PMD Unit Tests");
+ }
+
+ @Test
+ public void should_load_repository_from_xml() {
+ List<Rule> rules = repository.createRules();
+
+ assertThat(rules).onProperty("key").containsOnly(
+ "JUnitStaticSuite",
+ "JUnitSpelling",
+ "JUnitAssertionsShouldIncludeMessage",
+ "JUnitTestsShouldIncludeAssert",
+ "TestClassWithoutTestCases",
+ "UnnecessaryBooleanAssertion",
+ "UseAssertEqualsInsteadOfAssertTrue",
+ "UseAssertSameInsteadOfAssertTrue",
+ "UseAssertNullInsteadOfAssertTrue",
+ "SimplifyBooleanAssertion");
+ }
+
+ @Test
+ public void should_provide_a_name_and_description_for_each_rule() {
+ List<Rule> rules = RuleRepositoryTestHelper.createRulesWithNameAndDescription("pmd", repository);
+
+ assertThat(rules).onProperty("name").excludes(null, "");
+ assertThat(rules).onProperty("description").excludes(null, "");
+ }
+}
import org.junit.Test;
-import static junit.framework.Assert.assertEquals;
-import static org.hamcrest.number.OrderingComparisons.greaterThan;
-import static org.junit.Assert.assertThat;
+import static org.fest.assertions.Assertions.assertThat;
public class PmdVersionTest {
@Test
- public void getCheckstyleVersion() {
- assertThat(PmdVersion.getVersion().length(), greaterThan(1));
- assertEquals(PmdVersion.getVersion(), PmdVersion.getVersion());
+ public void should_get_pmd_version() {
+ assertThat(PmdVersion.getVersion()).isNotEmpty().isSameAs(PmdVersion.getVersion());
}
-
}
+++ /dev/null
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 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.pmd;
-
-import org.junit.Test;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
-import org.sonar.api.profiles.ProfileDefinition;
-import org.sonar.api.profiles.RulesProfile;
-import org.sonar.api.rules.Rule;
-import org.sonar.api.rules.RuleFinder;
-import org.sonar.api.rules.RulePriority;
-import org.sonar.api.rules.RuleQuery;
-import org.sonar.api.utils.ValidationMessages;
-
-import static org.hamcrest.core.Is.is;
-import static org.hamcrest.number.OrderingComparisons.greaterThan;
-import static org.junit.Assert.assertThat;
-import static org.mockito.Matchers.anyObject;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-public class SonarWayProfileTest {
-
- @Test
- public void shouldCreateProfile() {
- ProfileDefinition sonarWay = new SonarWayProfile(createPmdProfileImporter());
- ValidationMessages validation = ValidationMessages.create();
- RulesProfile profile = sonarWay.createProfile(validation);
- assertThat(profile.getActiveRulesByRepository(PmdConstants.REPOSITORY_KEY).size(), greaterThan(1));
- assertThat(validation.hasErrors(), is(false));
- }
-
- private PmdProfileImporter createPmdProfileImporter() {
-
- RuleFinder ruleFinder = mock(RuleFinder.class);
- when(ruleFinder.find((RuleQuery) anyObject())).thenAnswer(new Answer<Rule>() {
-
- public Rule answer(InvocationOnMock iom) throws Throwable {
- RuleQuery query = (RuleQuery) iom.getArguments()[0];
- Rule rule = Rule.create(query.getRepositoryKey(), query.getConfigKey(), "Rule name - " + query.getConfigKey())
- .setConfigKey(query.getConfigKey()).setSeverity(RulePriority.BLOCKER);
- return rule;
- }
- });
- PmdProfileImporter importer = new PmdProfileImporter(ruleFinder);
- return importer;
- }
-}
+++ /dev/null
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 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.pmd;
-
-import org.junit.Test;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
-import org.sonar.api.profiles.RulesProfile;
-import org.sonar.api.rules.Rule;
-import org.sonar.api.rules.RuleFinder;
-import org.sonar.api.rules.RulePriority;
-import org.sonar.api.rules.RuleQuery;
-import org.sonar.api.utils.ValidationMessages;
-
-import static org.hamcrest.core.Is.is;
-import static org.hamcrest.number.OrderingComparisons.greaterThan;
-import static org.junit.Assert.assertThat;
-import static org.mockito.Matchers.anyObject;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-public class SonarWayWithFindbugsProfileTest {
-
- @Test
- public void shouldCreateProfile() {
- SonarWayWithFindbugsProfile sonarWayWithFindbugs = new SonarWayWithFindbugsProfile(new SonarWayProfile(createPmdProfileImporter()));
- ValidationMessages validation = ValidationMessages.create();
- RulesProfile profile = sonarWayWithFindbugs.createProfile(validation);
- assertThat(profile.getActiveRulesByRepository(PmdConstants.REPOSITORY_KEY).size(), greaterThan(1));
- assertThat(validation.hasErrors(), is(false));
- }
-
- private PmdProfileImporter createPmdProfileImporter() {
-
- RuleFinder ruleFinder = mock(RuleFinder.class);
- when(ruleFinder.find((RuleQuery) anyObject())).thenAnswer(new Answer<Rule>() {
-
- public Rule answer(InvocationOnMock iom) throws Throwable {
- RuleQuery query = (RuleQuery) iom.getArguments()[0];
- Rule rule = Rule.create(query.getRepositoryKey(), query.getConfigKey(), "Rule name - " + query.getConfigKey())
- .setConfigKey(query.getConfigKey()).setSeverity(RulePriority.BLOCKER);
- return rule;
- }
- });
- PmdProfileImporter importer = new PmdProfileImporter(ruleFinder);
- return importer;
- }
-}
+++ /dev/null
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 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.pmd;
-
-import org.junit.Test;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
-import org.sonar.api.profiles.RulesProfile;
-import org.sonar.api.rules.Rule;
-import org.sonar.api.rules.RuleFinder;
-import org.sonar.api.rules.RulePriority;
-import org.sonar.api.rules.RuleQuery;
-import org.sonar.api.utils.ValidationMessages;
-
-import static org.hamcrest.core.Is.is;
-import static org.hamcrest.number.OrderingComparisons.greaterThan;
-import static org.junit.Assert.assertThat;
-import static org.mockito.Matchers.anyObject;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-public class SunConventionsProfileTest {
- @Test
- public void shouldCreateProfile() {
- SunConventionsProfile sunConvention = new SunConventionsProfile(createPmdProfileImporter());
- ValidationMessages validation = ValidationMessages.create();
- RulesProfile profile = sunConvention.createProfile(validation);
- assertThat(profile.getActiveRulesByRepository(PmdConstants.REPOSITORY_KEY).size(), greaterThan(1));
- assertThat(validation.hasErrors(), is(false));
- }
-
- private PmdProfileImporter createPmdProfileImporter() {
-
- RuleFinder ruleFinder = mock(RuleFinder.class);
- when(ruleFinder.find((RuleQuery) anyObject())).thenAnswer(new Answer<Rule>() {
-
- public Rule answer(InvocationOnMock iom) throws Throwable {
- RuleQuery query = (RuleQuery) iom.getArguments()[0];
- Rule rule = Rule.create(query.getRepositoryKey(), query.getConfigKey(), "Rule name - " + query.getConfigKey())
- .setConfigKey(query.getConfigKey()).setSeverity(RulePriority.BLOCKER);
- return rule;
- }
- });
- PmdProfileImporter importer = new PmdProfileImporter(ruleFinder);
- return importer;
- }
-
-}
+++ /dev/null
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <groupId>fake.group</groupId>
- <artifactId>fake.artifactId</artifactId>
- <packaging>jar</packaging>
- <version>1.0-SNAPSHOT</version>
-
- <properties>
- <sonar.reuseExistingRulesConfiguration>true</sonar.reuseExistingRulesConfiguration>
- </properties>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-pmd-plugin</artifactId>
- <!-- rulesets are not set in <configuration> -->
- </plugin>
- </plugins>
- </build>
-</project>
\ No newline at end of file
+++ /dev/null
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <groupId>fake.group</groupId>
- <artifactId>fake.artifactId</artifactId>
- <packaging>jar</packaging>
- <version>1.0-SNAPSHOT</version>
-
- <properties>
- <sonar.reuseExistingRulesConfiguration>true</sonar.reuseExistingRulesConfiguration>
- </properties>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-pmd-plugin</artifactId>
- <configuration>
- <rulesets>
- <ruleset>ruleset/maven.xml</ruleset>
- <ruleset>ruleset/basic.xml</ruleset>
- </rulesets>
- </configuration>
- </plugin>
- </plugins>
- </build>
-</project>
\ No newline at end of file
+++ /dev/null
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <groupId>fake.group</groupId>
- <artifactId>fake.artifactId</artifactId>
- <packaging>jar</packaging>
- <version>1.0-SNAPSHOT</version>
-</project>
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- generated by Sonar -->
-<ruleset>
- <description>Sonar way</description>
- <rule ref="rulesets/unusedcode.xml/UnusedLocalVariable">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/finalizers.xml/AvoidCallingFinalize">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/unusedcode.xml/UnusedPrivateField">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/finalizers.xml/FinalizeOverloaded">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/finalizers.xml/FinalizeDoesNotCallSuperFinalize">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/finalizers.xml/EmptyFinalizer">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/unusedcode.xml/UnusedPrivateMethod">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/unusedcode.xml/UnusedFormalParameter">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/controversial.xml/UnusedModifier">
- <priority>5</priority>
- </rule>
- <rule ref="rulesets/controversial.xml/DontImportSun">
- <priority>4</priority>
- </rule>
- <rule ref="rulesets/design.xml/SingularField">
- <priority>4</priority>
- </rule>
- <rule ref="rulesets/coupling.xml/LooseCoupling">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/optimizations.xml/UseArrayListInsteadOfVector">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/optimizations.xml/UseArraysAsList">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/optimizations.xml/AvoidArrayLoops">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/basic.xml/EmptyIfStmt">
- <priority>2</priority>
- </rule>
- <rule ref="rulesets/basic.xml/EmptyWhileStmt">
- <priority>2</priority>
- </rule>
- <rule ref="rulesets/basic.xml/EmptyTryBlock">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/basic.xml/EmptyFinallyBlock">
- <priority>2</priority>
- </rule>
- <rule ref="rulesets/basic.xml/EmptySwitchStatements">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/basic.xml/EmptySynchronizedBlock">
- <priority>2</priority>
- </rule>
- <rule ref="rulesets/basic.xml/EmptyStaticInitializer">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/basic.xml/UnconditionalIfStatement">
- <priority>2</priority>
- </rule>
- <rule ref="rulesets/basic.xml/BooleanInstantiation">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/basic.xml/CollapsibleIfStatements">
- <priority>4</priority>
- </rule>
- <rule ref="rulesets/basic.xml/UselessOverridingMethod">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/basic.xml/ClassCastExceptionWithToArray">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/basic.xml/AvoidDecimalLiteralsInBigDecimalConstructor">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/basic.xml/UselessOperationOnImmutable">
- <priority>2</priority>
- </rule>
- <rule ref="rulesets/basic.xml/UnusedNullCheckInEquals">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/basic.xml/BrokenNullCheck">
- <priority>2</priority>
- </rule>
- <rule ref="rulesets/basic.xml/BigIntegerInstantiation">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/design.xml/ConstructorCallsOverridableMethod">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/design.xml/FinalFieldCouldBeStatic">
- <priority>4</priority>
- </rule>
- <rule ref="rulesets/design.xml/CloseResource">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/design.xml/EqualsNull">
- <priority>2</priority>
- </rule>
- <rule ref="rulesets/design.xml/InstantiationToGetClass">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/design.xml/IdempotentOperations">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/design.xml/MissingStaticMethodInNonInstantiatableClass">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/design.xml/AvoidInstanceofChecksInCatchClause">
- <priority>4</priority>
- </rule>
- <rule ref="rulesets/design.xml/SimplifyConditional">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/design.xml/CompareObjectsWithEquals">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/design.xml/UnnecessaryLocalBeforeReturn">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/design.xml/PreserveStackTrace">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/sunsecure.xml/ArrayIsStoredDirectly">
- <priority>2</priority>
- </rule>
- <rule ref="rulesets/strictexception.xml/AvoidCatchingThrowable">
- <priority>2</priority>
- </rule>
- <rule ref="rulesets/strictexception.xml/SignatureDeclareThrowsException">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/strictexception.xml/ExceptionAsFlowControl">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/strictexception.xml/AvoidCatchingNPE">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/strictexception.xml/AvoidThrowingRawExceptionTypes">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/strictexception.xml/AvoidThrowingNullPointerException">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/strictexception.xml/AvoidRethrowingException">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/strings.xml/AvoidDuplicateLiterals">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/strings.xml/StringInstantiation">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/strings.xml/StringToString">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/strings.xml/InefficientStringBuffering">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/strings.xml/UnnecessaryCaseChange">
- <priority>4</priority>
- </rule>
- <rule ref="rulesets/strings.xml/UseStringBufferLength">
- <priority>4</priority>
- </rule>
- <rule ref="rulesets/strings.xml/UseIndexOfChar">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/strings.xml/UselessStringValueOf">
- <priority>4</priority>
- </rule>
- <rule ref="rulesets/strings.xml/StringBufferInstantiationWithChar">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/codesize.xml/NcssMethodCount">
- <priority>3</priority>
- <properties>
- <property name="minimum" value="50"/>
- </properties>
- </rule>
- <rule ref="rulesets/codesize.xml/NcssTypeCount">
- <priority>3</priority>
- <properties>
- <property name="minimum" value="800"/>
- </properties>
- </rule>
- <rule ref="rulesets/imports.xml/DontImportJavaLang">
- <priority>4</priority>
- </rule>
- <rule ref="rulesets/clone.xml/CloneThrowsCloneNotSupportedException">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/logging-jakarta-commons.xml/UseCorrectExceptionLogging">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/naming.xml/ClassNamingConventions">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/naming.xml/AvoidDollarSigns">
- <priority>4</priority>
- </rule>
- <rule ref="rulesets/naming.xml/MethodWithSameNameAsEnclosingClass">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/naming.xml/SuspiciousHashcodeMethodName">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/naming.xml/SuspiciousConstantFieldName">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/naming.xml/SuspiciousEqualsMethodName">
- <priority>2</priority>
- </rule>
- <rule ref="rulesets/migrating.xml/ReplaceVectorWithList">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/migrating.xml/ReplaceHashtableWithMap">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/migrating.xml/ReplaceEnumerationWithIterator">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/migrating.xml/AvoidEnumAsIdentifier">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/migrating.xml/AvoidAssertAsIdentifier">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/migrating.xml/IntegerInstantiation">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/logging-java.xml/SystemPrintln">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/logging-java.xml/AvoidPrintStackTrace">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/braces.xml/IfStmtsMustUseBraces">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/braces.xml/WhileLoopsMustUseBraces">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/braces.xml/IfElseStmtsMustUseBraces">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/braces.xml/ForLoopsMustUseBraces">
- <priority>3</priority>
- </rule>
-</ruleset>
\ No newline at end of file
+++ /dev/null
-public class FirstClass {
-
- private FirstClass() {
- int unused= new Integer(0);
- if (true) {
- unused += new Integer(12345);
- }
- }
-}
+++ /dev/null
-public class SecondClass {
-
- private SecondClass() {
- int unused= 0;
- if (true) {
- unused += 12345;
- }
- }
-}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<ruleset>
+ <description>Sonar PMD Unit Tests rules</description>
+ <rule ref="rulesets/junit.xml/SimplifyBooleanAssertion">
+ <priority>2</priority>
+ </rule>
+</ruleset>
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Sonar PMD rules generated configuration -->
-<ruleset>
- <description>A test profile</description>
- <rule ref="rulesets/coupling.xml/CouplingBetweenObjects">
- <priority>2</priority>
- <properties>
- <property name="threshold" value="20"/>
- </properties>
- </rule>
- <rule ref="rulesets/coupling.xml/ExcessiveImports">
- <priority>3</priority>
- <properties>
- <property name="max" value="30"/>
- </properties>
- </rule>
- <rule ref="rulesets/design.xml/UseNotifyAllInsteadOfNotify">
- <priority>4</priority>
- </rule>
-</ruleset>
\ No newline at end of file
+++ /dev/null
-public class DoesNotCompile {
-
- / not java /
- Yeeaah !
-}
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- generated by Sonar -->
-<ruleset>
- <description>Sonar way</description>
- <rule ref="rulesets/unusedcode.xml/UnusedLocalVariable">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/finalizers.xml/AvoidCallingFinalize">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/unusedcode.xml/UnusedPrivateField">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/finalizers.xml/FinalizeOverloaded">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/finalizers.xml/FinalizeDoesNotCallSuperFinalize">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/finalizers.xml/EmptyFinalizer">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/unusedcode.xml/UnusedPrivateMethod">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/unusedcode.xml/UnusedFormalParameter">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/controversial.xml/UnusedModifier">
- <priority>5</priority>
- </rule>
- <rule ref="rulesets/controversial.xml/DontImportSun">
- <priority>4</priority>
- </rule>
- <rule ref="rulesets/design.xml/SingularField">
- <priority>4</priority>
- </rule>
- <rule ref="rulesets/coupling.xml/LooseCoupling">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/optimizations.xml/UseArrayListInsteadOfVector">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/optimizations.xml/UseArraysAsList">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/optimizations.xml/AvoidArrayLoops">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/basic.xml/EmptyIfStmt">
- <priority>2</priority>
- </rule>
- <rule ref="rulesets/basic.xml/EmptyWhileStmt">
- <priority>2</priority>
- </rule>
- <rule ref="rulesets/basic.xml/EmptyTryBlock">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/basic.xml/EmptyFinallyBlock">
- <priority>2</priority>
- </rule>
- <rule ref="rulesets/basic.xml/EmptySwitchStatements">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/basic.xml/EmptySynchronizedBlock">
- <priority>2</priority>
- </rule>
- <rule ref="rulesets/basic.xml/EmptyStaticInitializer">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/basic.xml/UnconditionalIfStatement">
- <priority>2</priority>
- </rule>
- <rule ref="rulesets/basic.xml/BooleanInstantiation">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/basic.xml/CollapsibleIfStatements">
- <priority>4</priority>
- </rule>
- <rule ref="rulesets/basic.xml/UselessOverridingMethod">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/basic.xml/ClassCastExceptionWithToArray">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/basic.xml/AvoidDecimalLiteralsInBigDecimalConstructor">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/basic.xml/UselessOperationOnImmutable">
- <priority>2</priority>
- </rule>
- <rule ref="rulesets/basic.xml/UnusedNullCheckInEquals">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/basic.xml/BrokenNullCheck">
- <priority>2</priority>
- </rule>
- <rule ref="rulesets/basic.xml/BigIntegerInstantiation">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/design.xml/ConstructorCallsOverridableMethod">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/design.xml/FinalFieldCouldBeStatic">
- <priority>4</priority>
- </rule>
- <rule ref="rulesets/design.xml/CloseResource">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/design.xml/EqualsNull">
- <priority>2</priority>
- </rule>
- <rule ref="rulesets/design.xml/InstantiationToGetClass">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/design.xml/IdempotentOperations">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/design.xml/MissingStaticMethodInNonInstantiatableClass">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/design.xml/AvoidInstanceofChecksInCatchClause">
- <priority>4</priority>
- </rule>
- <rule ref="rulesets/design.xml/SimplifyConditional">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/design.xml/CompareObjectsWithEquals">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/design.xml/UnnecessaryLocalBeforeReturn">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/design.xml/PreserveStackTrace">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/sunsecure.xml/ArrayIsStoredDirectly">
- <priority>2</priority>
- </rule>
- <rule ref="rulesets/strictexception.xml/AvoidCatchingThrowable">
- <priority>2</priority>
- </rule>
- <rule ref="rulesets/strictexception.xml/SignatureDeclareThrowsException">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/strictexception.xml/ExceptionAsFlowControl">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/strictexception.xml/AvoidCatchingNPE">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/strictexception.xml/AvoidThrowingRawExceptionTypes">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/strictexception.xml/AvoidThrowingNullPointerException">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/strictexception.xml/AvoidRethrowingException">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/strings.xml/AvoidDuplicateLiterals">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/strings.xml/StringInstantiation">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/strings.xml/StringToString">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/strings.xml/InefficientStringBuffering">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/strings.xml/UnnecessaryCaseChange">
- <priority>4</priority>
- </rule>
- <rule ref="rulesets/strings.xml/UseStringBufferLength">
- <priority>4</priority>
- </rule>
- <rule ref="rulesets/strings.xml/UseIndexOfChar">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/strings.xml/UselessStringValueOf">
- <priority>4</priority>
- </rule>
- <rule ref="rulesets/strings.xml/StringBufferInstantiationWithChar">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/codesize.xml/NcssMethodCount">
- <priority>3</priority>
- <properties>
- <property name="minimum" value="50"/>
- </properties>
- </rule>
- <rule ref="rulesets/codesize.xml/NcssTypeCount">
- <priority>3</priority>
- <properties>
- <property name="minimum" value="800"/>
- </properties>
- </rule>
- <rule ref="rulesets/imports.xml/DontImportJavaLang">
- <priority>4</priority>
- </rule>
- <rule ref="rulesets/clone.xml/CloneThrowsCloneNotSupportedException">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/logging-jakarta-commons.xml/UseCorrectExceptionLogging">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/naming.xml/ClassNamingConventions">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/naming.xml/AvoidDollarSigns">
- <priority>4</priority>
- </rule>
- <rule ref="rulesets/naming.xml/MethodWithSameNameAsEnclosingClass">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/naming.xml/SuspiciousHashcodeMethodName">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/naming.xml/SuspiciousConstantFieldName">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/naming.xml/SuspiciousEqualsMethodName">
- <priority>2</priority>
- </rule>
- <rule ref="rulesets/migrating.xml/ReplaceVectorWithList">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/migrating.xml/ReplaceHashtableWithMap">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/migrating.xml/ReplaceEnumerationWithIterator">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/migrating.xml/AvoidEnumAsIdentifier">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/migrating.xml/AvoidAssertAsIdentifier">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/migrating.xml/IntegerInstantiation">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/logging-java.xml/SystemPrintln">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/logging-java.xml/AvoidPrintStackTrace">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/braces.xml/IfStmtsMustUseBraces">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/braces.xml/WhileLoopsMustUseBraces">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/braces.xml/IfElseStmtsMustUseBraces">
- <priority>3</priority>
- </rule>
- <rule ref="rulesets/braces.xml/ForLoopsMustUseBraces">
- <priority>3</priority>
- </rule>
-</ruleset>
\ No newline at end of file
CoreMetrics.NEW_VIOLATIONS_KEY, CoreMetrics.NEW_BLOCKER_VIOLATIONS_KEY, CoreMetrics.NEW_CRITICAL_VIOLATIONS_KEY, CoreMetrics.NEW_MAJOR_VIOLATIONS_KEY,
CoreMetrics.NEW_MINOR_VIOLATIONS_KEY, CoreMetrics.NEW_INFO_VIOLATIONS_KEY, CoreMetrics.ACTIVE_REVIEWS_KEY, CoreMetrics.UNASSIGNED_REVIEWS_KEY,
CoreMetrics.UNPLANNED_REVIEWS_KEY, CoreMetrics.FALSE_POSITIVE_REVIEWS_KEY, CoreMetrics.UNREVIEWED_VIOLATIONS_KEY, CoreMetrics.NEW_UNREVIEWED_VIOLATIONS_KEY})
- @ResourceQualifier({Qualifiers.VIEW, Qualifiers.SUBVIEW, Qualifiers.PROJECT, Qualifiers.MODULE, Qualifiers.PACKAGE, Qualifiers.DIRECTORY, Qualifiers.FILE, Qualifiers.CLASS})
- /* all exept unit tests...*/
+ @ResourceQualifier({Qualifiers.VIEW, Qualifiers.SUBVIEW, Qualifiers.PROJECT, Qualifiers.MODULE, Qualifiers.PACKAGE, Qualifiers.DIRECTORY, Qualifiers.FILE, Qualifiers.CLASS,
+ Qualifiers.UNIT_TEST_FILE})
@UserRole(UserRole.CODEVIEWER)
private static final class ViolationsTab implements RubyRailsPage {
public String getTemplate() {