Ver código fonte

SONAR 1076 - Run PMD on Unit Tests

tags/3.1
David Gageot 12 anos atrás
pai
commit
1a6a18a5c4
56 arquivos alterados com 1289 adições e 1338 exclusões
  1. 1
    2
      plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/ViolationsDecorator.java
  2. 1
    2
      plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/NewViolationsDecorator.java
  3. 10
    0
      plugins/sonar-l10n-en-plugin/src/main/resources/org/sonar/l10n/pmd.properties
  4. 8
    0
      plugins/sonar-l10n-en-plugin/src/main/resources/org/sonar/l10n/pmd/rules/pmd-unit-tests/JUnitAssertionsShouldIncludeMessage.html
  5. 9
    0
      plugins/sonar-l10n-en-plugin/src/main/resources/org/sonar/l10n/pmd/rules/pmd-unit-tests/JUnitSpelling.html
  6. 9
    0
      plugins/sonar-l10n-en-plugin/src/main/resources/org/sonar/l10n/pmd/rules/pmd-unit-tests/JUnitStaticSuite.html
  7. 10
    0
      plugins/sonar-l10n-en-plugin/src/main/resources/org/sonar/l10n/pmd/rules/pmd-unit-tests/JUnitTestsShouldIncludeAssert.html
  8. 9
    0
      plugins/sonar-l10n-en-plugin/src/main/resources/org/sonar/l10n/pmd/rules/pmd-unit-tests/SimplifyBooleanAssertion.html
  9. 9
    0
      plugins/sonar-l10n-en-plugin/src/main/resources/org/sonar/l10n/pmd/rules/pmd-unit-tests/TestClassWithoutTestCases.html
  10. 7
    0
      plugins/sonar-l10n-en-plugin/src/main/resources/org/sonar/l10n/pmd/rules/pmd-unit-tests/UnnecessaryBooleanAssertion.html
  11. 10
    0
      plugins/sonar-l10n-en-plugin/src/main/resources/org/sonar/l10n/pmd/rules/pmd-unit-tests/UseAssertEqualsInsteadOfAssertTrue.html
  12. 13
    0
      plugins/sonar-l10n-en-plugin/src/main/resources/org/sonar/l10n/pmd/rules/pmd-unit-tests/UseAssertNullInsteadOfAssertTrue.html
  13. 11
    0
      plugins/sonar-l10n-en-plugin/src/main/resources/org/sonar/l10n/pmd/rules/pmd-unit-tests/UseAssertSameInsteadOfAssertTrue.html
  14. 7
    0
      plugins/sonar-pmd-plugin/pom.xml
  15. 13
    14
      plugins/sonar-pmd-plugin/src/main/java/org/sonar/plugins/pmd/JavaCpdMapping.java
  16. 49
    22
      plugins/sonar-pmd-plugin/src/main/java/org/sonar/plugins/pmd/PmdConfiguration.java
  17. 2
    0
      plugins/sonar-pmd-plugin/src/main/java/org/sonar/plugins/pmd/PmdConstants.java
  18. 57
    118
      plugins/sonar-pmd-plugin/src/main/java/org/sonar/plugins/pmd/PmdExecutor.java
  19. 12
    32
      plugins/sonar-pmd-plugin/src/main/java/org/sonar/plugins/pmd/PmdLevelUtils.java
  20. 4
    3
      plugins/sonar-pmd-plugin/src/main/java/org/sonar/plugins/pmd/PmdPlugin.java
  21. 19
    14
      plugins/sonar-pmd-plugin/src/main/java/org/sonar/plugins/pmd/PmdProfileExporter.java
  22. 2
    4
      plugins/sonar-pmd-plugin/src/main/java/org/sonar/plugins/pmd/PmdRuleRepository.java
  23. 18
    36
      plugins/sonar-pmd-plugin/src/main/java/org/sonar/plugins/pmd/PmdSensor.java
  24. 98
    0
      plugins/sonar-pmd-plugin/src/main/java/org/sonar/plugins/pmd/PmdTemplate.java
  25. 44
    0
      plugins/sonar-pmd-plugin/src/main/java/org/sonar/plugins/pmd/PmdUnitTestsRuleRepository.java
  26. 12
    8
      plugins/sonar-pmd-plugin/src/main/java/org/sonar/plugins/pmd/PmdVersion.java
  27. 82
    0
      plugins/sonar-pmd-plugin/src/main/java/org/sonar/plugins/pmd/PmdViolationToRuleViolation.java
  28. 17
    10
      plugins/sonar-pmd-plugin/src/main/java/org/sonar/plugins/pmd/SonarWayProfile.java
  29. 5
    6
      plugins/sonar-pmd-plugin/src/main/java/org/sonar/plugins/pmd/SonarWayWithFindbugsProfile.java
  30. 17
    11
      plugins/sonar-pmd-plugin/src/main/java/org/sonar/plugins/pmd/SunConventionsProfile.java
  31. 42
    0
      plugins/sonar-pmd-plugin/src/main/resources/org/sonar/plugins/pmd/rules-unit-tests.xml
  32. 63
    24
      plugins/sonar-pmd-plugin/src/test/java/org/sonar/plugins/pmd/PmdConfigurationTest.java
  33. 82
    63
      plugins/sonar-pmd-plugin/src/test/java/org/sonar/plugins/pmd/PmdExecutorTest.java
  34. 47
    0
      plugins/sonar-pmd-plugin/src/test/java/org/sonar/plugins/pmd/PmdLevelUtilsTest.java
  35. 10
    7
      plugins/sonar-pmd-plugin/src/test/java/org/sonar/plugins/pmd/PmdPluginTest.java
  36. 62
    100
      plugins/sonar-pmd-plugin/src/test/java/org/sonar/plugins/pmd/PmdProfileExporterTest.java
  37. 70
    58
      plugins/sonar-pmd-plugin/src/test/java/org/sonar/plugins/pmd/PmdProfileImporterTest.java
  38. 37
    22
      plugins/sonar-pmd-plugin/src/test/java/org/sonar/plugins/pmd/PmdProfilesTest.java
  39. 43
    16
      plugins/sonar-pmd-plugin/src/test/java/org/sonar/plugins/pmd/PmdRuleRepositoryTest.java
  40. 126
    0
      plugins/sonar-pmd-plugin/src/test/java/org/sonar/plugins/pmd/PmdSensorTest.java
  41. 59
    0
      plugins/sonar-pmd-plugin/src/test/java/org/sonar/plugins/pmd/PmdTemplateTest.java
  42. 71
    0
      plugins/sonar-pmd-plugin/src/test/java/org/sonar/plugins/pmd/PmdUnitTestsRuleRepositoryTest.java
  43. 3
    7
      plugins/sonar-pmd-plugin/src/test/java/org/sonar/plugins/pmd/PmdVersionTest.java
  44. 0
    66
      plugins/sonar-pmd-plugin/src/test/java/org/sonar/plugins/pmd/SonarWayProfileTest.java
  45. 0
    65
      plugins/sonar-pmd-plugin/src/test/java/org/sonar/plugins/pmd/SonarWayWithFindbugsProfileTest.java
  46. 0
    22
      plugins/sonar-pmd-plugin/src/test/resources/org/sonar/plugins/pmd/PmdConfigurationTest/failIfConfigurationToReuseDoesNotExist/pom.xml
  47. 0
    27
      plugins/sonar-pmd-plugin/src/test/resources/org/sonar/plugins/pmd/PmdConfigurationTest/findConfigurationToReuse/pom.xml
  48. 0
    8
      plugins/sonar-pmd-plugin/src/test/resources/org/sonar/plugins/pmd/PmdConfigurationTest/writeConfigurationToWorkingDir/pom.xml
  49. 0
    263
      plugins/sonar-pmd-plugin/src/test/resources/org/sonar/plugins/pmd/PmdExecutorTest/executeOnManySourceDirs/pmd.xml
  50. 0
    9
      plugins/sonar-pmd-plugin/src/test/resources/org/sonar/plugins/pmd/PmdExecutorTest/executeOnManySourceDirs/src1/FirstClass.java
  51. 0
    9
      plugins/sonar-pmd-plugin/src/test/resources/org/sonar/plugins/pmd/PmdExecutorTest/executeOnManySourceDirs/src2/SecondClass.java
  52. 7
    0
      plugins/sonar-pmd-plugin/src/test/resources/org/sonar/plugins/pmd/junit.xml
  53. 0
    20
      plugins/sonar-pmd-plugin/src/test/resources/org/sonar/plugins/pmd/test_xml_complete.xml
  54. 0
    5
      plugins/sonar-pmd-plugin/test-resources/ignorePmdFailures/DoesNotCompile.java
  55. 0
    263
      plugins/sonar-pmd-plugin/test-resources/ignorePmdFailures/pmd.xml
  56. 2
    2
      sonar-server/src/main/java/org/sonar/server/ui/DefaultPages.java

+ 1
- 2
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/ViolationsDecorator.java Ver arquivo

@@ -26,7 +26,6 @@ import org.sonar.api.batch.*;
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;
@@ -44,7 +43,7 @@ public class ViolationsDecorator implements Decorator {
}

private boolean shouldDecorateResource(Resource resource) {
return !ResourceUtils.isUnitTestClass(resource);
return true;
}

@DependedUpon

+ 1
- 2
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/NewViolationsDecorator.java Ver arquivo

@@ -96,8 +96,7 @@ public class NewViolationsDecorator implements Decorator {
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) {

+ 10
- 0
plugins/sonar-l10n-en-plugin/src/main/resources/org/sonar/l10n/pmd.properties Ver arquivo

@@ -275,3 +275,13 @@ rule.pmd.UseConcurrentHashMap.name=Use ConcurrentHashMap
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

+ 8
- 0
plugins/sonar-l10n-en-plugin/src/main/resources/org/sonar/l10n/pmd/rules/pmd-unit-tests/JUnitAssertionsShouldIncludeMessage.html Ver arquivo

@@ -0,0 +1,8 @@
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>

+ 9
- 0
plugins/sonar-l10n-en-plugin/src/main/resources/org/sonar/l10n/pmd/rules/pmd-unit-tests/JUnitSpelling.html Ver arquivo

@@ -0,0 +1,9 @@
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>

+ 9
- 0
plugins/sonar-l10n-en-plugin/src/main/resources/org/sonar/l10n/pmd/rules/pmd-unit-tests/JUnitStaticSuite.html Ver arquivo

@@ -0,0 +1,9 @@
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>

+ 10
- 0
plugins/sonar-l10n-en-plugin/src/main/resources/org/sonar/l10n/pmd/rules/pmd-unit-tests/JUnitTestsShouldIncludeAssert.html Ver arquivo

@@ -0,0 +1,10 @@
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>

+ 9
- 0
plugins/sonar-l10n-en-plugin/src/main/resources/org/sonar/l10n/pmd/rules/pmd-unit-tests/SimplifyBooleanAssertion.html Ver arquivo

@@ -0,0 +1,9 @@
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>

+ 9
- 0
plugins/sonar-l10n-en-plugin/src/main/resources/org/sonar/l10n/pmd/rules/pmd-unit-tests/TestClassWithoutTestCases.html Ver arquivo

@@ -0,0 +1,9 @@
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>

+ 7
- 0
plugins/sonar-l10n-en-plugin/src/main/resources/org/sonar/l10n/pmd/rules/pmd-unit-tests/UnnecessaryBooleanAssertion.html Ver arquivo

@@ -0,0 +1,7 @@
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>

+ 10
- 0
plugins/sonar-l10n-en-plugin/src/main/resources/org/sonar/l10n/pmd/rules/pmd-unit-tests/UseAssertEqualsInsteadOfAssertTrue.html Ver arquivo

@@ -0,0 +1,10 @@
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>

+ 13
- 0
plugins/sonar-l10n-en-plugin/src/main/resources/org/sonar/l10n/pmd/rules/pmd-unit-tests/UseAssertNullInsteadOfAssertTrue.html Ver arquivo

@@ -0,0 +1,13 @@
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>

+ 11
- 0
plugins/sonar-l10n-en-plugin/src/main/resources/org/sonar/l10n/pmd/rules/pmd-unit-tests/UseAssertSameInsteadOfAssertTrue.html Ver arquivo

@@ -0,0 +1,11 @@
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>

+ 7
- 0
plugins/sonar-pmd-plugin/pom.xml Ver arquivo

@@ -65,6 +65,13 @@
<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>

+ 13
- 14
plugins/sonar-pmd-plugin/src/main/java/org/sonar/plugins/pmd/JavaCpdMapping.java Ver arquivo

@@ -19,37 +19,36 @@
*/
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;

+ 49
- 22
plugins/sonar-pmd-plugin/src/main/java/org/sonar/plugins/pmd/PmdConfiguration.java Ver arquivo

@@ -19,18 +19,20 @@
*/
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(
@@ -42,40 +44,65 @@ import java.util.List;
)
})
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();
}
}

+ 2
- 0
plugins/sonar-pmd-plugin/src/main/java/org/sonar/plugins/pmd/PmdConstants.java Ver arquivo

@@ -24,6 +24,8 @@ import org.sonar.api.CoreProperties;
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";

+ 57
- 118
plugins/sonar-pmd-plugin/src/main/java/org/sonar/plugins/pmd/PmdExecutor.java Ver arquivo

@@ -19,166 +19,105 @@
*/
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));
}
}

+ 12
- 32
plugins/sonar-pmd-plugin/src/main/java/org/sonar/plugins/pmd/PmdLevelUtils.java Ver arquivo

@@ -19,49 +19,29 @@
*/
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);
}
}

+ 4
- 3
plugins/sonar-pmd-plugin/src/main/java/org/sonar/plugins/pmd/PmdPlugin.java Ver arquivo

@@ -26,19 +26,20 @@ import org.sonar.api.SonarPlugin;
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);
}
}

+ 19
- 14
plugins/sonar-pmd-plugin/src/main/java/org/sonar/plugins/pmd/PmdProfileExporter.java Ver arquivo

@@ -19,12 +19,7 @@
*/
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;
@@ -40,8 +35,13 @@ import org.sonar.plugins.pmd.xml.PmdProperty;
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);
@@ -51,21 +51,25 @@ public class PmdProfileExporter extends ProfileExporter {
@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()));
@@ -79,7 +83,8 @@ public class PmdProfileExporter extends ProfileExporter {
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);
@@ -98,7 +103,7 @@ public class PmdProfileExporter extends ProfileExporter {
}
}

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");

+ 2
- 4
plugins/sonar-pmd-plugin/src/main/java/org/sonar/plugins/pmd/PmdRuleRepository.java Ver arquivo

@@ -30,10 +30,8 @@ import java.io.File;
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);

+ 18
- 36
plugins/sonar-pmd-plugin/src/main/java/org/sonar/plugins/pmd/PmdSensor.java Ver arquivo

@@ -21,70 +21,52 @@ package org.sonar.plugins.pmd;

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();

+ 98
- 0
plugins/sonar-pmd-plugin/src/main/java/org/sonar/plugins/pmd/PmdTemplate.java Ver arquivo

@@ -0,0 +1,98 @@
/*
* 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();
}
}

+ 44
- 0
plugins/sonar-pmd-plugin/src/main/java/org/sonar/plugins/pmd/PmdUnitTestsRuleRepository.java Ver arquivo

@@ -0,0 +1,44 @@
/*
* 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);
}
}

+ 12
- 8
plugins/sonar-pmd-plugin/src/main/java/org/sonar/plugins/pmd/PmdVersion.java Ver arquivo

@@ -19,7 +19,7 @@
*/
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;
@@ -37,18 +37,22 @@ public enum PmdVersion {
}

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", "");
}
}

+ 82
- 0
plugins/sonar-pmd-plugin/src/main/java/org/sonar/plugins/pmd/PmdViolationToRuleViolation.java Ver arquivo

@@ -0,0 +1,82 @@
/*
* 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();
}
}

+ 17
- 10
plugins/sonar-pmd-plugin/src/main/java/org/sonar/plugins/pmd/SonarWayProfile.java Ver arquivo

@@ -19,16 +19,16 @@
*/
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) {
@@ -36,11 +36,18 @@ public final class SonarWayProfile extends ProfileDefinition {
}

@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);
}
}
}

+ 5
- 6
plugins/sonar-pmd-plugin/src/main/java/org/sonar/plugins/pmd/SonarWayWithFindbugsProfile.java Ver arquivo

@@ -25,20 +25,19 @@ import org.sonar.api.resources.Java;
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;
}
}


+ 17
- 11
plugins/sonar-pmd-plugin/src/main/java/org/sonar/plugins/pmd/SunConventionsProfile.java Ver arquivo

@@ -19,16 +19,16 @@
*/
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) {
@@ -36,12 +36,18 @@ public final class SunConventionsProfile extends ProfileDefinition {
}

@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);
}
}
}

+ 42
- 0
plugins/sonar-pmd-plugin/src/main/resources/org/sonar/plugins/pmd/rules-unit-tests.xml Ver arquivo

@@ -0,0 +1,42 @@
<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>

+ 63
- 24
plugins/sonar-pmd-plugin/src/test/java/org/sonar/plugins/pmd/PmdConfigurationTest.java Ver arquivo

@@ -19,51 +19,90 @@
*/
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);
}
}

+ 82
- 63
plugins/sonar-pmd-plugin/src/test/java/org/sonar/plugins/pmd/PmdExecutorTest.java Ver arquivo

@@ -20,90 +20,109 @@
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;
}
}

+ 47
- 0
plugins/sonar-pmd-plugin/src/test/java/org/sonar/plugins/pmd/PmdLevelUtilsTest.java Ver arquivo

@@ -0,0 +1,47 @@
/*
* 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");
}
}

+ 10
- 7
plugins/sonar-pmd-plugin/src/test/java/org/sonar/plugins/pmd/PmdPluginTest.java Ver arquivo

@@ -19,17 +19,20 @@
*/
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);
}
}

+ 62
- 100
plugins/sonar-pmd-plugin/src/test/java/org/sonar/plugins/pmd/PmdProfileExporterTest.java Ver arquivo

@@ -19,12 +19,9 @@
*/
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;
@@ -38,144 +35,109 @@ import org.sonar.plugins.pmd.xml.PmdProperty;
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;
}
}

+ 70
- 58
plugins/sonar-pmd-plugin/src/test/java/org/sonar/plugins/pmd/PmdProfileImporterTest.java Ver arquivo

@@ -24,7 +24,11 @@ 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.*;
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;
@@ -32,127 +36,135 @@ 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");
}

plugins/sonar-pmd-plugin/src/test/java/org/sonar/plugins/pmd/SunConventionsProfileTest.java → plugins/sonar-pmd-plugin/src/test/java/org/sonar/plugins/pmd/PmdProfilesTest.java Ver arquivo

@@ -22,44 +22,59 @@ 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.fest.assertions.Assertions.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

public class SunConventionsProfileTest {
public class PmdProfilesTest {
ValidationMessages validation = ValidationMessages.create();

@Test
public void shouldCreateProfile() {
SunConventionsProfile sunConvention = new SunConventionsProfile(createPmdProfileImporter());
ValidationMessages validation = ValidationMessages.create();
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).size(), greaterThan(1));
assertThat(validation.hasErrors(), is(false));

assertThat(profile.getActiveRulesByRepository(PmdConstants.REPOSITORY_KEY)).isNotEmpty();
assertThat(validation.hasErrors()).isFalse();
}

private PmdProfileImporter createPmdProfileImporter() {
@Test
public void should_create_sonar_way_profile() {
ProfileDefinition sonarWay = new SonarWayProfile(new PmdProfileImporter(ruleFinder()));

RuleFinder ruleFinder = mock(RuleFinder.class);
when(ruleFinder.find((RuleQuery) anyObject())).thenAnswer(new Answer<Rule>() {
RulesProfile profile = sonarWay.createProfile(validation);

assertThat(profile.getActiveRulesByRepository(PmdConstants.REPOSITORY_KEY)).isNotEmpty();
assertThat(validation.hasErrors()).isFalse();
}

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;
@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(), "", "");
}
});
PmdProfileImporter importer = new PmdProfileImporter(ruleFinder);
return importer;
return ruleFinder;
}

}

+ 43
- 16
plugins/sonar-pmd-plugin/src/test/java/org/sonar/plugins/pmd/PmdRuleRepositoryTest.java Ver arquivo

@@ -19,41 +19,68 @@
*/
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, "");
}
}

+ 126
- 0
plugins/sonar-pmd-plugin/src/test/java/org/sonar/plugins/pmd/PmdSensorTest.java Ver arquivo

@@ -0,0 +1,126 @@
/*
* 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;
}
}

+ 59
- 0
plugins/sonar-pmd-plugin/src/test/java/org/sonar/plugins/pmd/PmdTemplateTest.java Ver arquivo

@@ -0,0 +1,59 @@
/*
* 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);
}
}

+ 71
- 0
plugins/sonar-pmd-plugin/src/test/java/org/sonar/plugins/pmd/PmdUnitTestsRuleRepositoryTest.java Ver arquivo

@@ -0,0 +1,71 @@
/*
* 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, "");
}
}

+ 3
- 7
plugins/sonar-pmd-plugin/src/test/java/org/sonar/plugins/pmd/PmdVersionTest.java Ver arquivo

@@ -21,15 +21,11 @@ package org.sonar.plugins.pmd;

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());
}

}

+ 0
- 66
plugins/sonar-pmd-plugin/src/test/java/org/sonar/plugins/pmd/SonarWayProfileTest.java Ver arquivo

@@ -1,66 +0,0 @@
/*
* 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;
}
}

+ 0
- 65
plugins/sonar-pmd-plugin/src/test/java/org/sonar/plugins/pmd/SonarWayWithFindbugsProfileTest.java Ver arquivo

@@ -1,65 +0,0 @@
/*
* 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;
}
}

+ 0
- 22
plugins/sonar-pmd-plugin/src/test/resources/org/sonar/plugins/pmd/PmdConfigurationTest/failIfConfigurationToReuseDoesNotExist/pom.xml Ver arquivo

@@ -1,22 +0,0 @@
<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>

+ 0
- 27
plugins/sonar-pmd-plugin/src/test/resources/org/sonar/plugins/pmd/PmdConfigurationTest/findConfigurationToReuse/pom.xml Ver arquivo

@@ -1,27 +0,0 @@
<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>

+ 0
- 8
plugins/sonar-pmd-plugin/src/test/resources/org/sonar/plugins/pmd/PmdConfigurationTest/writeConfigurationToWorkingDir/pom.xml Ver arquivo

@@ -1,8 +0,0 @@
<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>

+ 0
- 263
plugins/sonar-pmd-plugin/src/test/resources/org/sonar/plugins/pmd/PmdExecutorTest/executeOnManySourceDirs/pmd.xml Ver arquivo

@@ -1,263 +0,0 @@
<?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>

+ 0
- 9
plugins/sonar-pmd-plugin/src/test/resources/org/sonar/plugins/pmd/PmdExecutorTest/executeOnManySourceDirs/src1/FirstClass.java Ver arquivo

@@ -1,9 +0,0 @@
public class FirstClass {

private FirstClass() {
int unused= new Integer(0);
if (true) {
unused += new Integer(12345);
}
}
}

+ 0
- 9
plugins/sonar-pmd-plugin/src/test/resources/org/sonar/plugins/pmd/PmdExecutorTest/executeOnManySourceDirs/src2/SecondClass.java Ver arquivo

@@ -1,9 +0,0 @@
public class SecondClass {

private SecondClass() {
int unused= 0;
if (true) {
unused += 12345;
}
}
}

+ 7
- 0
plugins/sonar-pmd-plugin/src/test/resources/org/sonar/plugins/pmd/junit.xml Ver arquivo

@@ -0,0 +1,7 @@
<?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>

+ 0
- 20
plugins/sonar-pmd-plugin/src/test/resources/org/sonar/plugins/pmd/test_xml_complete.xml Ver arquivo

@@ -1,20 +0,0 @@
<?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>

+ 0
- 5
plugins/sonar-pmd-plugin/test-resources/ignorePmdFailures/DoesNotCompile.java Ver arquivo

@@ -1,5 +0,0 @@
public class DoesNotCompile {

/ not java /
Yeeaah !
}

+ 0
- 263
plugins/sonar-pmd-plugin/test-resources/ignorePmdFailures/pmd.xml Ver arquivo

@@ -1,263 +0,0 @@
<?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>

+ 2
- 2
sonar-server/src/main/java/org/sonar/server/ui/DefaultPages.java Ver arquivo

@@ -96,8 +96,8 @@ public final class DefaultPages {
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() {

Carregando…
Cancelar
Salvar