Compare commits
9 commits
9ea433edce
...
9a59526408
Author | SHA1 | Date | |
---|---|---|---|
9a59526408 | |||
e56791fdb0 | |||
a5f479189e | |||
be90889b8d | |||
630f3fa8d2 | |||
71e9ab7f98 | |||
cebccf754c | |||
a5d070a022 | |||
8a605ad62d |
13 changed files with 1037 additions and 725 deletions
3
.github/workflows/bld.yml
vendored
3
.github/workflows/bld.yml
vendored
|
@ -7,7 +7,6 @@ jobs:
|
|||
strategy:
|
||||
matrix:
|
||||
java-version: [ 17, 21, 24 ]
|
||||
kotlin-version: [ 1.9.25, 2.0.21, 2.1.20 ]
|
||||
os: [ ubuntu-latest, windows-latest, macos-latest ]
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
@ -28,4 +27,4 @@ jobs:
|
|||
run: ./bld download
|
||||
|
||||
- name: Run tests
|
||||
run: ./bld compile test
|
||||
run: ./bld compile test
|
||||
|
|
2
.idea/misc.xml
generated
2
.idea/misc.xml
generated
|
@ -25,7 +25,7 @@
|
|||
</option>
|
||||
<option name="skipTestSources" value="false" />
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" project-jdk-name="17" project-jdk-type="JavaSDK">
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="17" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/build" />
|
||||
</component>
|
||||
</project>
|
|
@ -1,5 +1,6 @@
|
|||
bld.downloadExtensionJavadoc=false
|
||||
bld.downloadExtensionSources=true
|
||||
bld.downloadLocation=
|
||||
bld.extension-exec=com.uwyn.rife2:bld-exec:1.0.5
|
||||
bld.repositories=MAVEN_LOCAL,MAVEN_CENTRAL,RIFE2_SNAPSHOTS,RIFE2_RELEASES
|
||||
bld.version=2.2.1
|
||||
|
|
|
@ -21,6 +21,9 @@ import rife.bld.publish.PublishDeveloper;
|
|||
import rife.bld.publish.PublishLicense;
|
||||
import rife.bld.publish.PublishScm;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
|
||||
import static rife.bld.dependencies.Repository.*;
|
||||
|
@ -31,24 +34,24 @@ public class PmdOperationBuild extends Project {
|
|||
public PmdOperationBuild() {
|
||||
pkg = "rife.bld.extension";
|
||||
name = "bld-pmd";
|
||||
version = version(1, 2, 3);
|
||||
version = version(1, 3, 0);
|
||||
|
||||
javaRelease = 17;
|
||||
|
||||
downloadSources = true;
|
||||
autoDownloadPurge = true;
|
||||
|
||||
|
||||
repositories = List.of(MAVEN_LOCAL, MAVEN_CENTRAL, RIFE2_RELEASES, RIFE2_SNAPSHOTS);
|
||||
|
||||
var pmd = version(7, 13, 0);
|
||||
var pmd = version(7, 14, 0);
|
||||
scope(compile)
|
||||
.include(dependency("com.uwyn.rife2", "bld", version(2, 2, 1)))
|
||||
.include(dependency("net.sourceforge.pmd", "pmd-java", pmd));
|
||||
scope(runtime)
|
||||
.include(dependency("org.slf4j", "slf4j-simple", version(2, 0, 17)));
|
||||
scope(test)
|
||||
.include(dependency("org.junit.jupiter", "junit-jupiter", version(5, 12, 2)))
|
||||
.include(dependency("org.junit.platform", "junit-platform-console-standalone", version(1, 12, 2)))
|
||||
.include(dependency("org.junit.jupiter", "junit-jupiter", version(5, 13, 0)))
|
||||
.include(dependency("org.junit.platform", "junit-platform-console-standalone", version(1, 13, 0)))
|
||||
.include(dependency("org.assertj", "assertj-core", version(3, 27, 3)));
|
||||
|
||||
javadocOperation()
|
||||
|
@ -88,4 +91,35 @@ public class PmdOperationBuild extends Project {
|
|||
public static void main(String[] args) {
|
||||
new PmdOperationBuild().start(args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void test() throws Exception {
|
||||
var testResultsDir = "build/test-results/test/";
|
||||
|
||||
var op = testOperation().fromProject(this);
|
||||
op.testToolOptions().reportsDir(new File(testResultsDir));
|
||||
|
||||
Exception ex = null;
|
||||
try {
|
||||
op.execute();
|
||||
} catch (Exception e) {
|
||||
ex = e;
|
||||
}
|
||||
|
||||
var xunitViewer = new File("/usr/bin/xunit-viewer");
|
||||
if (xunitViewer.exists() && xunitViewer.canExecute()) {
|
||||
var reportsDir = "build/reports/tests/test/";
|
||||
|
||||
Files.createDirectories(Path.of(reportsDir));
|
||||
|
||||
new ExecOperation()
|
||||
.fromProject(this)
|
||||
.command(xunitViewer.getPath(), "-r", testResultsDir, "-o", reportsDir + "index.html")
|
||||
.execute();
|
||||
}
|
||||
|
||||
if (ex != null) {
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,9 @@ import net.sourceforge.pmd.PMDConfiguration;
|
|||
import net.sourceforge.pmd.PmdAnalysis;
|
||||
import net.sourceforge.pmd.lang.LanguageVersion;
|
||||
import net.sourceforge.pmd.lang.rule.RulePriority;
|
||||
import net.sourceforge.pmd.reporting.Report;
|
||||
import rife.bld.BaseProject;
|
||||
import rife.bld.extension.pmd.PmdAnalysisResults;
|
||||
import rife.bld.operations.AbstractOperation;
|
||||
import rife.bld.operations.exceptions.ExitStatusException;
|
||||
|
||||
|
@ -41,105 +43,41 @@ import java.util.logging.Logger;
|
|||
* @since 1.0
|
||||
*/
|
||||
public class PmdOperation extends AbstractOperation<PmdOperation> {
|
||||
/**
|
||||
* The default logger.
|
||||
*/
|
||||
public static final Logger LOGGER = Logger.getLogger(PmdOperation.class.getName());
|
||||
/**
|
||||
* The default rule set.
|
||||
* <p>
|
||||
* Set to: {@code rulesets/java/quickstart.xml}
|
||||
*/
|
||||
public static final String RULE_SET_DEFAULT = "rulesets/java/quickstart.xml";
|
||||
private static final Logger LOGGER = Logger.getLogger(PmdOperation.class.getName());
|
||||
|
||||
private static final String PMD_DIR = "pmd";
|
||||
/**
|
||||
* The list of paths to exclude.
|
||||
*/
|
||||
private final Collection<Path> excludes_ = new ArrayList<>();
|
||||
/**
|
||||
* The input paths (source) list.
|
||||
*/
|
||||
private final Collection<Path> inputPaths_ = new ArrayList<>();
|
||||
/**
|
||||
* The relative roots paths.
|
||||
*/
|
||||
private final Collection<Path> relativizeRoots_ = new ArrayList<>();
|
||||
/**
|
||||
* The rule sets list.
|
||||
*/
|
||||
private final Collection<String> ruleSets_ = new ArrayList<>();
|
||||
/**
|
||||
* The cache location.
|
||||
*/
|
||||
private Path cache_;
|
||||
/**
|
||||
* The encoding.
|
||||
*/
|
||||
private boolean collectFilesRecursively_ = true;
|
||||
private Charset encoding_ = StandardCharsets.UTF_8;
|
||||
/**
|
||||
* The fail on error toggle.
|
||||
*/
|
||||
private boolean failOnError_ = true;
|
||||
/**
|
||||
* The fail on violation toggle.
|
||||
*/
|
||||
private boolean failOnViolation_;
|
||||
/**
|
||||
* The forced language.
|
||||
*/
|
||||
private LanguageVersion forcedLanguageVersion_;
|
||||
/**
|
||||
* The path of the ignore file
|
||||
*/
|
||||
private Path ignoreFile_;
|
||||
/**
|
||||
* The include line number toggle.
|
||||
*/
|
||||
private boolean includeLineNumber_ = true;
|
||||
/**
|
||||
* The incremental analysis toggle.
|
||||
*/
|
||||
private boolean incrementalAnalysis_ = true;
|
||||
/**
|
||||
* The input URI.
|
||||
*/
|
||||
private URI inputUri_;
|
||||
/**
|
||||
* The default language version(s).
|
||||
*/
|
||||
private Collection<LanguageVersion> languageVersions_ = new ArrayList<>();
|
||||
/**
|
||||
* The classpath to prepend.
|
||||
*/
|
||||
private String prependClasspath_;
|
||||
/**
|
||||
* The project reference.
|
||||
*/
|
||||
private BaseProject project_;
|
||||
/**
|
||||
* The path to the report page.
|
||||
*/
|
||||
private Path reportFile_;
|
||||
/**
|
||||
* The report format.
|
||||
*/
|
||||
private String reportFormat_ = "text";
|
||||
/**
|
||||
* The report properties.
|
||||
*/
|
||||
private Properties reportProperties_;
|
||||
/**
|
||||
* The rule priority.
|
||||
*/
|
||||
private RulePriority rulePriority_ = RulePriority.LOW;
|
||||
/**
|
||||
* The show suppressed flag.
|
||||
*/
|
||||
private boolean showSuppressed_;
|
||||
/**
|
||||
* THe suppressed marker.
|
||||
*/
|
||||
private String suppressedMarker_ = "NOPMD";
|
||||
/**
|
||||
* The number of threads.
|
||||
*/
|
||||
private int threads_ = 1;
|
||||
|
||||
/**
|
||||
|
@ -216,18 +154,18 @@ public class PmdOperation extends AbstractOperation<PmdOperation> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Adds paths to source files, or directories containing source files to analyze.\
|
||||
* Adds paths to source files or directories containing source files to analyze.\
|
||||
*
|
||||
* @param inputPath one or more paths
|
||||
* @return this operation
|
||||
* @see #inputPaths(Path...)
|
||||
*/
|
||||
public PmdOperation addInputPaths(Path... inputPath) {
|
||||
return inputPaths(List.of(inputPath));
|
||||
return addInputPaths(List.of(inputPath));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds paths to source files, or directories containing source files to analyze.
|
||||
* Adds paths to source files or directories containing source files to analyze.
|
||||
*
|
||||
* @param inputPath one or more paths
|
||||
* @return this operation
|
||||
|
@ -238,7 +176,7 @@ public class PmdOperation extends AbstractOperation<PmdOperation> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Adds paths to source files, or directories containing source files to analyze.
|
||||
* Adds paths to source files or directories containing source files to analyze.
|
||||
*
|
||||
* @param inputPath one or more paths
|
||||
* @return this operation
|
||||
|
@ -249,7 +187,7 @@ public class PmdOperation extends AbstractOperation<PmdOperation> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Adds paths to source files, or directories containing source files to analyze.
|
||||
* Adds paths to source files or directories containing source files to analyze.
|
||||
*
|
||||
* @param inputPath a collection of input paths
|
||||
* @return this operation
|
||||
|
@ -261,7 +199,7 @@ public class PmdOperation extends AbstractOperation<PmdOperation> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Adds paths to source files, or directories containing source files to analyze.
|
||||
* Adds paths to source files or directories containing source files to analyze.
|
||||
*
|
||||
* @param inputPath a collection of input paths
|
||||
* @return this operation
|
||||
|
@ -272,7 +210,7 @@ public class PmdOperation extends AbstractOperation<PmdOperation> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Adds paths to source files, or directories containing source files to analyze.
|
||||
* Adds paths to source files or directories containing source files to analyze.
|
||||
*
|
||||
* @param inputPath a collection of input paths
|
||||
* @return this operation
|
||||
|
@ -353,6 +291,19 @@ public class PmdOperation extends AbstractOperation<PmdOperation> {
|
|||
return cache(Path.of(cache));
|
||||
}
|
||||
|
||||
/**
|
||||
* When specified, any directory mentioned with {@link #inputPaths()} will only be searched for files that are
|
||||
* direct children. By default, subdirectories are recursively included.
|
||||
*
|
||||
* @param collectFilesRecursively whether to collect files recursively or not
|
||||
* @return this operation
|
||||
* @since 1.2.4
|
||||
*/
|
||||
public PmdOperation collectFilesRecursively(boolean collectFilesRecursively) {
|
||||
this.collectFilesRecursively_ = collectFilesRecursively;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the default language version to be used for all input files.
|
||||
*
|
||||
|
@ -366,7 +317,7 @@ public class PmdOperation extends AbstractOperation<PmdOperation> {
|
|||
/**
|
||||
* Sets the default language version to be used for all input files.
|
||||
*
|
||||
* @param languageVersion a collection language versions
|
||||
* @param languageVersion a collection language version
|
||||
* @return this operation
|
||||
*/
|
||||
public PmdOperation defaultLanguageVersions(Collection<LanguageVersion> languageVersion) {
|
||||
|
@ -625,6 +576,11 @@ public class PmdOperation extends AbstractOperation<PmdOperation> {
|
|||
// addRelativizeRoots
|
||||
config.addRelativizeRoots(relativizeRoots_.stream().toList());
|
||||
|
||||
// collectFilesRecursively
|
||||
if (!collectFilesRecursively_) {
|
||||
config.collectFilesRecursively(false);
|
||||
}
|
||||
|
||||
// prependAuxClasspath
|
||||
if (prependClasspath_ != null) {
|
||||
config.prependAuxClasspath(prependClasspath_);
|
||||
|
@ -715,7 +671,7 @@ public class PmdOperation extends AbstractOperation<PmdOperation> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Sets paths to source files, or directories containing source files to analyze.
|
||||
* Sets paths to source files or directories containing source files to analyze.
|
||||
*
|
||||
* @param inputPath one or more paths
|
||||
* @return this operation
|
||||
|
@ -726,7 +682,7 @@ public class PmdOperation extends AbstractOperation<PmdOperation> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Sets paths to source files, or directories containing source files to analyze.
|
||||
* Sets paths to source files or directories containing source files to analyze.
|
||||
* <p>
|
||||
* Previous entries are disregarded.
|
||||
*
|
||||
|
@ -739,7 +695,7 @@ public class PmdOperation extends AbstractOperation<PmdOperation> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Sets paths to source files, or directories containing source files to analyze.
|
||||
* Sets paths to source files or directories containing source files to analyze.
|
||||
* <p>
|
||||
* Previous entries are disregarded.
|
||||
*
|
||||
|
@ -752,7 +708,7 @@ public class PmdOperation extends AbstractOperation<PmdOperation> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Sets paths to source files, or directories containing source files to analyze.
|
||||
* Sets paths to source files or directories containing source files to analyze.
|
||||
* <p>
|
||||
* Previous entries are disregarded.
|
||||
*
|
||||
|
@ -767,7 +723,7 @@ public class PmdOperation extends AbstractOperation<PmdOperation> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns paths to source files, or directories containing source files to analyze.
|
||||
* Returns paths to source files or directories containing source files to analyze.
|
||||
*
|
||||
* @return the input paths
|
||||
*/
|
||||
|
@ -776,7 +732,7 @@ public class PmdOperation extends AbstractOperation<PmdOperation> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Sets paths to source files, or directories containing source files to analyze.
|
||||
* Sets paths to source files or directories containing source files to analyze.
|
||||
* <p>
|
||||
* Previous entries are disregarded.
|
||||
*
|
||||
|
@ -789,7 +745,7 @@ public class PmdOperation extends AbstractOperation<PmdOperation> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Sets paths to source files, or directories containing source files to analyze.
|
||||
* Sets paths to source files or directories containing source files to analyze.
|
||||
* <p>
|
||||
* Previous entries are disregarded.
|
||||
*
|
||||
|
@ -814,7 +770,7 @@ public class PmdOperation extends AbstractOperation<PmdOperation> {
|
|||
/**
|
||||
* Sets the default language versions.
|
||||
*
|
||||
* @param languageVersions a collection language versions
|
||||
* @param languageVersions a collection language version
|
||||
* @return this operation
|
||||
*/
|
||||
public PmdOperation languageVersions(Collection<LanguageVersion> languageVersions) {
|
||||
|
@ -849,63 +805,66 @@ public class PmdOperation extends AbstractOperation<PmdOperation> {
|
|||
* @return the number of violations
|
||||
* @throws ExitStatusException if an error occurs
|
||||
*/
|
||||
@SuppressWarnings({"PMD.CloseResource", "PMD.AvoidInstantiatingObjectsInLoops"})
|
||||
public int performPmdAnalysis(String commandName, PMDConfiguration config) throws ExitStatusException {
|
||||
var pmd = PmdAnalysis.create(config);
|
||||
var report = pmd.performAnalysisAndCollectReport();
|
||||
if (LOGGER.isLoggable(Level.INFO) && !silent()) {
|
||||
LOGGER.log(Level.INFO, "[{0}] inputPaths{1}", new Object[]{commandName, inputPaths_});
|
||||
LOGGER.log(Level.INFO, "[{0}] ruleSets{1}", new Object[]{commandName, ruleSets_});
|
||||
}
|
||||
public PmdAnalysisResults performPmdAnalysis(String commandName, PMDConfiguration config)
|
||||
throws ExitStatusException {
|
||||
try (var pmd = PmdAnalysis.create(config)) {
|
||||
var report = pmd.performAnalysisAndCollectReport();
|
||||
|
||||
var numViolations = report.getViolations().size();
|
||||
if (numViolations > 0) {
|
||||
for (var v : report.getViolations()) {
|
||||
if (LOGGER.isLoggable(Level.WARNING) && !silent()) {
|
||||
final String msg;
|
||||
if (includeLineNumber_) {
|
||||
msg = "[{0}] {1}:{2}\n\t{3} ({4})\n\t\t--> {5}";
|
||||
} else {
|
||||
msg = "[{0}] {1} (line: {2})\n\t{3} ({4})\n\t\t--> {5}";
|
||||
}
|
||||
LOGGER.log(Level.WARNING, msg,
|
||||
new Object[]{commandName,
|
||||
v.getFileId().getUriString(),
|
||||
v.getBeginLine(),
|
||||
v.getRule().getName(),
|
||||
v.getRule().getExternalInfoUrl() //TODO bug in PMD?
|
||||
.replace("${pmd.website.baseurl}",
|
||||
"https://docs.pmd-code.org/latest"),
|
||||
v.getDescription()});
|
||||
}
|
||||
if (LOGGER.isLoggable(Level.INFO) && !silent()) {
|
||||
LOGGER.log(Level.INFO, "[{0}] inputPaths{1}", new Object[]{commandName, inputPaths_});
|
||||
LOGGER.log(Level.INFO, "[{0}] ruleSets{1}", new Object[]{commandName, ruleSets_});
|
||||
}
|
||||
|
||||
var violations = String.format(
|
||||
"[%s] %d rule violations were found. See the report at: %s", commandName, numViolations,
|
||||
config.getReportFilePath().toUri());
|
||||
if (config.isFailOnViolation()) {
|
||||
if (LOGGER.isLoggable(Level.SEVERE) && !silent()) {
|
||||
LOGGER.log(Level.SEVERE, violations);
|
||||
}
|
||||
var numViolations = report.getViolations().size();
|
||||
if (numViolations > 0) {
|
||||
printViolations(commandName, config, report);
|
||||
} else if (pmd.getReporter().numErrors() > 0 && failOnError_) {
|
||||
throw new ExitStatusException(ExitStatusException.EXIT_FAILURE);
|
||||
} else if (LOGGER.isLoggable(Level.WARNING) && !silent()) {
|
||||
LOGGER.warning(violations);
|
||||
}
|
||||
} else if (pmd.getReporter().numErrors() > 0 && failOnError_) {
|
||||
throw new ExitStatusException(ExitStatusException.EXIT_FAILURE);
|
||||
} else {
|
||||
|
||||
var rulesChecked = 0;
|
||||
var rules = pmd.getRulesets();
|
||||
if (!rules.isEmpty()) {
|
||||
int count = 0;
|
||||
for (var rule : rules) {
|
||||
count += rule.getRules().size();
|
||||
}
|
||||
if (LOGGER.isLoggable(Level.INFO) && !silent()) {
|
||||
LOGGER.info(String.format("[%s] %d rules were checked.", commandName, count));
|
||||
rulesChecked += rule.getRules().size();
|
||||
}
|
||||
}
|
||||
|
||||
var result = new PmdAnalysisResults(
|
||||
numViolations,
|
||||
report.getSuppressedViolations().size(),
|
||||
pmd.getReporter().numErrors(),
|
||||
report.getProcessingErrors().size(),
|
||||
report.getConfigurationErrors().size(),
|
||||
rulesChecked
|
||||
);
|
||||
|
||||
if (!silent()) {
|
||||
if (LOGGER.isLoggable(Level.INFO)) {
|
||||
LOGGER.info(String.format("[%s] %d rules were checked.", commandName, result.rulesChecked()));
|
||||
}
|
||||
|
||||
if (LOGGER.isLoggable(Level.WARNING)) {
|
||||
if (result.processingErrors() > 0) {
|
||||
for (var err : report.getProcessingErrors()) {
|
||||
LOGGER.warning(String.format("[%s] %s", commandName, err.getMsg()));
|
||||
}
|
||||
}
|
||||
|
||||
if (result.configurationErrors() > 0) {
|
||||
for (var err : report.getConfigurationErrors()) {
|
||||
LOGGER.warning(String.format("[%s] %s", commandName, err.issue()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (LOGGER.isLoggable(Level.FINEST)) {
|
||||
LOGGER.finest(result.toString());
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
return numViolations;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -913,7 +872,7 @@ public class PmdOperation extends AbstractOperation<PmdOperation> {
|
|||
* is currently configured, the ClassLoader used to load the PMDConfiguration class will be used as the parent
|
||||
* ClassLoader of the created ClassLoader.
|
||||
* <p>
|
||||
* If the classpath String looks like a URL to a file (i.e. starts with {@code file://}) the file will be read with
|
||||
* If the classpath String looks like a URL to a file (i.e., starts with {@code file://}) the file will be read with
|
||||
* each line representing an entry on the classpath.
|
||||
*
|
||||
* @param classpath one or more classpath
|
||||
|
@ -933,6 +892,44 @@ public class PmdOperation extends AbstractOperation<PmdOperation> {
|
|||
return prependClasspath_;
|
||||
}
|
||||
|
||||
private void printViolations(String commandName, PMDConfiguration config, Report report)
|
||||
throws ExitStatusException {
|
||||
for (var v : report.getViolations()) {
|
||||
if (LOGGER.isLoggable(Level.WARNING) && !silent()) {
|
||||
final String msg;
|
||||
if (includeLineNumber_) {
|
||||
msg = "[%s] %s:%d\n\t%s (%s)\n\t\t--> %s";
|
||||
} else {
|
||||
msg = "[%s] %s (line: %d)\n\t%s (%s)\n\t\t--> %s";
|
||||
}
|
||||
LOGGER.log(Level.WARNING,
|
||||
String.format(msg,
|
||||
commandName,
|
||||
v.getFileId().getUriString(),
|
||||
v.getBeginLine(),
|
||||
v.getRule().getName(),
|
||||
v.getRule().getExternalInfoUrl(),
|
||||
v.getDescription()));
|
||||
}
|
||||
}
|
||||
|
||||
var violations = new StringBuilder(
|
||||
String.format("[%s] %d rule violations were found.", commandName, report.getViolations().size()));
|
||||
|
||||
if (config.getReportFilePath() != null) {
|
||||
violations.append(" See the report at: ").append(config.getReportFilePath().toUri());
|
||||
}
|
||||
|
||||
if (config.isFailOnViolation()) {
|
||||
if (LOGGER.isLoggable(Level.SEVERE) && !silent()) {
|
||||
LOGGER.log(Level.SEVERE, violations.toString());
|
||||
}
|
||||
throw new ExitStatusException(ExitStatusException.EXIT_FAILURE);
|
||||
} else if (LOGGER.isLoggable(Level.WARNING) && !silent()) {
|
||||
LOGGER.warning(violations.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds several paths to shorten paths that are output in the report.
|
||||
*
|
||||
|
|
47
src/main/java/rife/bld/extension/pmd/PmdAnalysisResults.java
Normal file
47
src/main/java/rife/bld/extension/pmd/PmdAnalysisResults.java
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright 2023-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package rife.bld.extension.pmd;
|
||||
|
||||
/**
|
||||
* Represents the results of a PMD analysis, containing various counts
|
||||
* related to violations, errors, and rules.
|
||||
*
|
||||
* @param violations The number of violations found during the analysis
|
||||
* @param suppressedViolations The number of suppressed violations found during the analysis
|
||||
* @param errors The number of errors returned during the analysis
|
||||
* @param processingErrors The number of processing errors returned during the analysis
|
||||
* @param configurationErrors The number of processing errors returning during the analysis
|
||||
* @param rulesChecked The number of rules checked during the analysis
|
||||
* @since 1.2.4
|
||||
*/
|
||||
public record PmdAnalysisResults(
|
||||
int violations,
|
||||
int suppressedViolations,
|
||||
int errors,
|
||||
int processingErrors,
|
||||
int configurationErrors,
|
||||
int rulesChecked) {
|
||||
|
||||
/**
|
||||
* Checks if the analysis results indicate no errors of any type.
|
||||
*
|
||||
* @return {@code true} if there are no errors, {@code false} otherwise.
|
||||
*/
|
||||
public boolean hasNoErrors() {
|
||||
return errors == 0 && processingErrors == 0 && configurationErrors == 0;
|
||||
}
|
||||
}
|
|
@ -1,584 +0,0 @@
|
|||
/*
|
||||
* Copyright 2023-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package rife.bld.extension;
|
||||
|
||||
import net.sourceforge.pmd.PMDConfiguration;
|
||||
import net.sourceforge.pmd.lang.LanguageRegistry;
|
||||
import net.sourceforge.pmd.lang.rule.RulePriority;
|
||||
import org.assertj.core.api.AutoCloseableSoftAssertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import rife.bld.BaseProject;
|
||||
import rife.bld.operations.exceptions.ExitStatusException;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatCode;
|
||||
|
||||
/**
|
||||
* PmdOperationTest class
|
||||
*
|
||||
* @author <a href="https://erik.thauvin.net/">Erik C. Thauvin</a>
|
||||
* @since 1.0
|
||||
*/
|
||||
class PmdOperationTest {
|
||||
static final String BAR = "bar";
|
||||
static final String CATEGORY_FOO = "category/foo.xml";
|
||||
static final Path CODE_STYLE_SAMPLE = Path.of("src/test/resources/java/CodeStyle.java");
|
||||
static final String CODE_STYLE_XML = "category/java/codestyle.xml";
|
||||
static final String COMMAND_NAME = "pmd";
|
||||
static final String DESIGN_XML = "category/java/design.xml";
|
||||
static final String DOCUMENTATION_XML = "category/java/documentation.xml";
|
||||
static final Path ERROR_PRONE_SAMPLE = Path.of("src/test/resources/java/ErrorProne.java");
|
||||
static final String ERROR_PRONE_XML = "category/java/errorprone.xml";
|
||||
static final File FILE_BAR = new File(BAR);
|
||||
static final String FOO = "foo";
|
||||
static final File FILE_FOO = new File(FOO);
|
||||
static final Path PATH_BAR = Path.of(BAR);
|
||||
static final Path PATH_FOO = Path.of(FOO);
|
||||
static final String PERFORMANCE_XML = "category/java/performance.xml";
|
||||
static final String SECURITY_XML = "category/java/security.xml";
|
||||
static final String TEST = "test";
|
||||
|
||||
PmdOperation newPmdOperation() {
|
||||
return new PmdOperation()
|
||||
.inputPaths(Path.of("src/main"), Path.of("src/test"))
|
||||
.cache("build/" + COMMAND_NAME + "/pmd-cache")
|
||||
.failOnViolation(false)
|
||||
.reportFile(Paths.get("build", COMMAND_NAME, "pmd-test-report.txt"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAddExcludes() {
|
||||
var pmd = newPmdOperation().ruleSets(CATEGORY_FOO).addExcludes(PATH_FOO);
|
||||
var config = pmd.initConfiguration(COMMAND_NAME);
|
||||
assertThat(config.getExcludes()).containsExactly(PATH_FOO);
|
||||
|
||||
pmd = pmd.addExcludes(PATH_BAR);
|
||||
config = pmd.initConfiguration(COMMAND_NAME);
|
||||
assertThat(config.getExcludes()).containsExactly(PATH_FOO, PATH_BAR);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAddExcludesFiles() {
|
||||
var pmd = newPmdOperation().ruleSets(CATEGORY_FOO).addExcludesFiles(FILE_FOO);
|
||||
var config = pmd.initConfiguration(COMMAND_NAME);
|
||||
assertThat(config.getExcludes()).containsExactly(FILE_FOO.toPath());
|
||||
|
||||
pmd = pmd.addExcludesFiles(FILE_BAR);
|
||||
config = pmd.initConfiguration(COMMAND_NAME);
|
||||
assertThat(config.getExcludes()).containsExactly(FILE_FOO.toPath(), FILE_BAR.toPath());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAddExcludesStrings() {
|
||||
var pmd = newPmdOperation().ruleSets(CATEGORY_FOO).addExcludesStrings(FOO);
|
||||
var config = pmd.initConfiguration(COMMAND_NAME);
|
||||
assertThat(config.getExcludes()).containsExactly(PATH_FOO);
|
||||
|
||||
pmd = pmd.addExcludesStrings(BAR);
|
||||
config = pmd.initConfiguration(COMMAND_NAME);
|
||||
assertThat(config.getExcludes()).containsExactly(PATH_FOO, PATH_BAR);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAddInputPaths() throws ExitStatusException {
|
||||
var project = new BaseProject();
|
||||
var pmd = new PmdOperation().fromProject(project);
|
||||
|
||||
assertThat(pmd.inputPaths()).as("default").containsExactly(project.srcMainDirectory().toPath(),
|
||||
project.srcTestDirectory().toPath());
|
||||
|
||||
var err = pmd.performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME));
|
||||
|
||||
pmd.inputPaths().clear();
|
||||
pmd = pmd.addInputPaths(project.srcMainDirectory(), project.srcTestDirectory());
|
||||
|
||||
assertThat(pmd.inputPaths()).as("File...").containsExactly(project.srcMainDirectory().toPath(),
|
||||
project.srcTestDirectory().toPath());
|
||||
|
||||
pmd.inputPaths().clear();
|
||||
pmd = pmd.addInputPathsFiles(List.of(project.srcMainDirectory(), project.srcTestDirectory()));
|
||||
|
||||
assertThat(pmd.inputPaths()).as("List(File...)")
|
||||
.containsExactly(project.srcMainDirectory().toPath(), project.srcTestDirectory().toPath());
|
||||
|
||||
pmd.inputPaths().clear();
|
||||
pmd = pmd.addInputPaths(project.srcMainDirectory().getAbsolutePath(),
|
||||
project.srcTestDirectory().getAbsolutePath());
|
||||
|
||||
assertThat(pmd.inputPaths()).as("String...")
|
||||
.containsExactly(project.srcMainDirectory().toPath(), project.srcTestDirectory().toPath());
|
||||
|
||||
pmd.inputPaths().clear();
|
||||
pmd = pmd.addInputPathsStrings(
|
||||
List.of(project.srcMainDirectory().getAbsolutePath(), project.srcTestDirectory().getAbsolutePath()));
|
||||
|
||||
assertThat(pmd.inputPaths()).as("List(String...)")
|
||||
.containsExactly(project.srcMainDirectory().toPath(), project.srcTestDirectory().toPath());
|
||||
|
||||
pmd.inputPaths().clear();
|
||||
pmd = pmd.addInputPaths(project.srcMainDirectory().toPath(), project.srcTestDirectory().toPath());
|
||||
|
||||
assertThat(pmd.inputPaths()).as("Path...")
|
||||
.containsExactly(project.srcMainDirectory().toPath(), project.srcTestDirectory().toPath());
|
||||
|
||||
pmd.inputPaths().clear();
|
||||
pmd = pmd.addInputPaths(List.of(project.srcMainDirectory().toPath(), project.srcTestDirectory().toPath()));
|
||||
|
||||
assertThat(pmd.inputPaths()).as("List(Path)")
|
||||
.containsExactly(project.srcMainDirectory().toPath(), project.srcTestDirectory().toPath());
|
||||
|
||||
assertThat(pmd.performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME)))
|
||||
.isGreaterThan(0).isEqualTo(err);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAddRuleSets() throws ExitStatusException {
|
||||
var pmd = new PmdOperation().fromProject(new BaseProject());
|
||||
|
||||
assertThat(pmd.ruleSets()).containsExactly(PmdOperation.RULE_SET_DEFAULT);
|
||||
|
||||
pmd.addRuleSet(ERROR_PRONE_XML);
|
||||
|
||||
assertThat(pmd.ruleSets()).containsExactly(PmdOperation.RULE_SET_DEFAULT, ERROR_PRONE_XML);
|
||||
|
||||
var err = pmd.performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME));
|
||||
|
||||
pmd.ruleSets().clear();
|
||||
|
||||
pmd.addRuleSet(List.of(PmdOperation.RULE_SET_DEFAULT, ERROR_PRONE_XML));
|
||||
|
||||
assertThat(pmd.ruleSets()).as("collection")
|
||||
.containsExactly(PmdOperation.RULE_SET_DEFAULT, ERROR_PRONE_XML);
|
||||
|
||||
assertThat(pmd.performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME)))
|
||||
.isGreaterThan(0).isEqualTo(err);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCache() throws ExitStatusException {
|
||||
var cache = Path.of("build/pmd/temp-cache");
|
||||
var pmd = newPmdOperation()
|
||||
.ruleSets(CODE_STYLE_XML)
|
||||
.inputPaths(List.of(CODE_STYLE_SAMPLE))
|
||||
.cache(cache);
|
||||
assertThat(pmd.performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME))).isGreaterThan(0);
|
||||
var f = cache.toFile();
|
||||
assertThat(f.exists()).as("file exits").isTrue();
|
||||
assertThat(f.delete()).as("delete file").isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testEncoding() {
|
||||
var pmd = newPmdOperation().ruleSets(CATEGORY_FOO).encoding("UTF-16");
|
||||
PMDConfiguration config = pmd.initConfiguration(COMMAND_NAME);
|
||||
assertThat(config.getSourceEncoding()).as("UTF-16").isEqualTo(StandardCharsets.UTF_16);
|
||||
|
||||
pmd = pmd.encoding(StandardCharsets.ISO_8859_1);
|
||||
config = pmd.initConfiguration(COMMAND_NAME);
|
||||
assertThat(config.getSourceEncoding()).as("ISO_8859").isEqualTo(StandardCharsets.ISO_8859_1);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testExcludes() {
|
||||
var foz = Path.of("foz/baz");
|
||||
var baz = Path.of("baz/foz");
|
||||
|
||||
var pmd = newPmdOperation().ruleSets(CATEGORY_FOO).excludes(PATH_FOO, PATH_BAR);
|
||||
var config = pmd.initConfiguration(COMMAND_NAME);
|
||||
assertThat(pmd.excludes()).containsExactly(List.of(PATH_FOO, PATH_BAR).toArray(new Path[0]));
|
||||
assertThat(config.getExcludes()).containsExactly(List.of(PATH_FOO, PATH_BAR).toArray(new Path[0]));
|
||||
|
||||
var excludes = List.of(List.of(PATH_FOO, PATH_BAR), List.of(foz, baz));
|
||||
for (var exclude : excludes) {
|
||||
pmd = newPmdOperation().ruleSets(CATEGORY_FOO).excludes(exclude);
|
||||
config = pmd.initConfiguration(COMMAND_NAME);
|
||||
assertThat(config.getExcludes()).containsExactly(exclude.toArray(new Path[0]));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testExcludesFiles() {
|
||||
var foz = new File("foz");
|
||||
var baz = new File("baz");
|
||||
|
||||
var pmd = newPmdOperation().ruleSets(CATEGORY_FOO).excludesFiles(FILE_FOO, FILE_BAR);
|
||||
var config = pmd.initConfiguration(COMMAND_NAME);
|
||||
assertThat(config.getExcludes()).containsExactly(FILE_FOO.toPath(), FILE_BAR.toPath());
|
||||
|
||||
var excludes = List.of(List.of(FILE_FOO, FILE_BAR), List.of(foz, baz));
|
||||
for (var exclude : excludes) {
|
||||
pmd = newPmdOperation().ruleSets(CATEGORY_FOO).excludesFiles(exclude);
|
||||
config = pmd.initConfiguration(COMMAND_NAME);
|
||||
assertThat(config.getExcludes()).containsExactly(exclude.stream().map(File::toPath).toArray(Path[]::new));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testExcludesStrings() {
|
||||
var foz = "foz";
|
||||
var baz = "baz";
|
||||
|
||||
var pmd = newPmdOperation().ruleSets(CATEGORY_FOO).excludesStrings(FOO, BAR);
|
||||
var config = pmd.initConfiguration(COMMAND_NAME);
|
||||
assertThat(pmd.excludes()).containsExactly(PATH_FOO, PATH_BAR);
|
||||
assertThat(config.getExcludes()).containsExactly(PATH_FOO, PATH_BAR);
|
||||
|
||||
var excludes = List.of(List.of(FOO, BAR), List.of(foz, baz));
|
||||
for (var exclude : excludes) {
|
||||
pmd = newPmdOperation().ruleSets(CATEGORY_FOO).excludesStrings(exclude);
|
||||
config = pmd.initConfiguration(COMMAND_NAME);
|
||||
assertThat(config.getExcludes()).containsExactly(exclude.stream().map(Paths::get).toArray(Path[]::new));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testExecute() throws ExitStatusException {
|
||||
var pmd = new PmdOperation().fromProject(new BaseProject());
|
||||
|
||||
assertThat(pmd.inputPaths()).containsExactly(Paths.get("src/main").toAbsolutePath(),
|
||||
Paths.get("src/test").toAbsolutePath());
|
||||
|
||||
pmd.inputPaths().clear();
|
||||
pmd.inputPaths("src/main/java", "src/test/java")
|
||||
.ruleSets("config/pmd.xml");
|
||||
|
||||
assertThat(pmd.ruleSets()).containsExactly("config/pmd.xml");
|
||||
assertThat(pmd.performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME))).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testExecuteNoProject() {
|
||||
var pmd = new PmdOperation();
|
||||
assertThatCode(pmd::execute).isInstanceOf(ExitStatusException.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailOnError() {
|
||||
var pmd = newPmdOperation().ruleSets("src/test/resources/xml/old.xml")
|
||||
.inputPaths(Path.of("src/test/resources/java/Documentation.java"));
|
||||
assertThatCode(() -> pmd.performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME)))
|
||||
.isInstanceOf(ExitStatusException.class);
|
||||
assertThatCode(() -> pmd.failOnError(false).performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME)))
|
||||
.doesNotThrowAnyException();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailOnValidation() {
|
||||
var pmd = newPmdOperation().ruleSets(DOCUMENTATION_XML)
|
||||
.inputPaths(Path.of("src/test/resources/java/Documentation.java"));
|
||||
assertThatCode(() -> pmd.failOnViolation(true).performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME)))
|
||||
.isInstanceOf(ExitStatusException.class);
|
||||
assertThatCode(() -> pmd.failOnViolation(false).performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME)))
|
||||
.doesNotThrowAnyException();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testIgnoreFile() throws ExitStatusException {
|
||||
var pmd = newPmdOperation()
|
||||
.ruleSets(ERROR_PRONE_XML, CODE_STYLE_XML)
|
||||
.ignoreFile(Path.of("src/test/resources/ignore.txt"));
|
||||
assertThat(pmd.performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME))).isGreaterThan(0);
|
||||
|
||||
pmd.inputPaths().clear();
|
||||
pmd.inputPaths(ERROR_PRONE_SAMPLE, CODE_STYLE_SAMPLE);
|
||||
assertThat(pmd.performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME))).isEqualTo(0);
|
||||
|
||||
pmd.ruleSets().clear();
|
||||
pmd.inputPaths().clear();
|
||||
assertThat(pmd.inputPaths(ERROR_PRONE_SAMPLE)
|
||||
.ignoreFile(new File("src/test/resources/ignore-single.txt"))
|
||||
.performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME))).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testIncrementalAnalysis() {
|
||||
var pmd = newPmdOperation().ruleSets(CATEGORY_FOO).incrementalAnalysis(true);
|
||||
var config = pmd.initConfiguration(COMMAND_NAME);
|
||||
assertThat(config.isIgnoreIncrementalAnalysis()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testInputPaths() throws ExitStatusException {
|
||||
var pmd = newPmdOperation()
|
||||
.ruleSets(PmdOperation.RULE_SET_DEFAULT, CODE_STYLE_XML)
|
||||
.inputPaths(ERROR_PRONE_SAMPLE, CODE_STYLE_SAMPLE);
|
||||
assertThat(pmd.inputPaths()).as("Path....").containsExactly(ERROR_PRONE_SAMPLE, CODE_STYLE_SAMPLE);
|
||||
assertThat(pmd.performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME))).isGreaterThan(0);
|
||||
|
||||
pmd = newPmdOperation()
|
||||
.ruleSets(PmdOperation.RULE_SET_DEFAULT, CODE_STYLE_XML)
|
||||
.inputPaths(ERROR_PRONE_SAMPLE.toFile(), CODE_STYLE_SAMPLE.toFile());
|
||||
assertThat(pmd.inputPaths()).as("File...").containsExactly(ERROR_PRONE_SAMPLE, CODE_STYLE_SAMPLE);
|
||||
assertThat(pmd.performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME))).isGreaterThan(0);
|
||||
|
||||
pmd = newPmdOperation()
|
||||
.ruleSets(PmdOperation.RULE_SET_DEFAULT, CODE_STYLE_XML)
|
||||
.inputPaths(ERROR_PRONE_SAMPLE.toString(), CODE_STYLE_SAMPLE.toString());
|
||||
assertThat(pmd.inputPaths()).as("String...").containsExactly(ERROR_PRONE_SAMPLE, CODE_STYLE_SAMPLE);
|
||||
assertThat(pmd.performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME))).isGreaterThan(0);
|
||||
|
||||
pmd = newPmdOperation()
|
||||
.ruleSets(PmdOperation.RULE_SET_DEFAULT, CODE_STYLE_XML)
|
||||
.inputPathsFiles(List.of(ERROR_PRONE_SAMPLE.toFile(), CODE_STYLE_SAMPLE.toFile()));
|
||||
assertThat(pmd.inputPaths()).as("List(Path...)").containsExactly(ERROR_PRONE_SAMPLE, CODE_STYLE_SAMPLE);
|
||||
assertThat(pmd.performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME))).isGreaterThan(0);
|
||||
|
||||
pmd = newPmdOperation()
|
||||
.ruleSets(PmdOperation.RULE_SET_DEFAULT, CODE_STYLE_XML)
|
||||
.inputPathsStrings(List.of(ERROR_PRONE_SAMPLE.toString(), CODE_STYLE_SAMPLE.toString()));
|
||||
assertThat(pmd.inputPaths()).as("List(String...)").containsExactly(ERROR_PRONE_SAMPLE, CODE_STYLE_SAMPLE);
|
||||
assertThat(pmd.performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME))).isGreaterThan(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testJavaBestPractices() throws ExitStatusException {
|
||||
var pmd = newPmdOperation().ruleSets("category/java/bestpractices.xml")
|
||||
.inputPaths(Path.of("src/test/resources/java/BestPractices.java"));
|
||||
assertThat(pmd.performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME))).isGreaterThan(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testJavaCodeStyle() throws ExitStatusException {
|
||||
var pmd = newPmdOperation().ruleSets(CODE_STYLE_XML).inputPaths(CODE_STYLE_SAMPLE);
|
||||
assertThat(pmd.performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME))).isGreaterThan(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testJavaCodeStyleAndErrorProne() throws ExitStatusException {
|
||||
var pmd = newPmdOperation().ruleSets(CODE_STYLE_XML).inputPaths(CODE_STYLE_SAMPLE);
|
||||
assertThat(pmd.performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME)))
|
||||
.as("code style").isGreaterThan(0);
|
||||
|
||||
pmd = pmd.ruleSets(ERROR_PRONE_XML).inputPaths(ERROR_PRONE_SAMPLE);
|
||||
assertThat(pmd.performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME)))
|
||||
.as("code style + error prone").isGreaterThan(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testJavaDesign() throws ExitStatusException {
|
||||
var pmd = newPmdOperation()
|
||||
.ruleSets(DESIGN_XML)
|
||||
.inputPaths("src/test/resources/java/Design.java")
|
||||
.cache(new File("build/pmd/design-cache"));
|
||||
assertThat(pmd.performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME))).isGreaterThan(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testJavaDocumentation() throws ExitStatusException {
|
||||
var pmd = newPmdOperation()
|
||||
.ruleSets(DOCUMENTATION_XML)
|
||||
.inputPaths(Path.of("src/test/resources/java/Documentation.java"));
|
||||
assertThat(pmd.performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME))).isGreaterThan(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testJavaErrorProne() throws ExitStatusException {
|
||||
var pmd = newPmdOperation().ruleSets(ERROR_PRONE_XML).inputPaths(ERROR_PRONE_SAMPLE);
|
||||
assertThat(pmd.performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME))).isGreaterThan(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testJavaMultiThreading() throws ExitStatusException {
|
||||
var pmd = newPmdOperation().ruleSets("category/java/multithreading.xml")
|
||||
.inputPaths(Path.of("src/test/resources/java/MultiThreading.java"));
|
||||
assertThat(pmd.performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME))).isGreaterThan(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testJavaPerformance() throws ExitStatusException {
|
||||
var pmd = newPmdOperation()
|
||||
.ruleSets(PERFORMANCE_XML)
|
||||
.inputPaths(Path.of("src/test/resources/java/Performance.java"));
|
||||
assertThat(pmd.performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME))).isGreaterThan(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testJavaQuickStart() throws ExitStatusException {
|
||||
var pmd = newPmdOperation().ruleSets(PmdOperation.RULE_SET_DEFAULT)
|
||||
.inputPaths(new File("src/test/resources/java/"));
|
||||
assertThat(pmd.ruleSets()).containsExactly(PmdOperation.RULE_SET_DEFAULT);
|
||||
assertThat(pmd.performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME))).isGreaterThan(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testJavaSecurity() throws ExitStatusException {
|
||||
var pmd = newPmdOperation().ruleSets(SECURITY_XML)
|
||||
.inputPaths(Path.of("src/test/resources/java/Security.java"));
|
||||
assertThat(pmd.performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME))).isGreaterThan(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLanguageVersions() throws ExitStatusException {
|
||||
var language = LanguageRegistry.PMD.getLanguageById("java");
|
||||
assertThat(language).isNotNull();
|
||||
|
||||
var pmd = newPmdOperation()
|
||||
.forceLanguageVersion(language.getLatestVersion())
|
||||
.defaultLanguageVersions(language.getVersions())
|
||||
.languageVersions(language.getDefaultVersion())
|
||||
.ruleSets(PmdOperation.RULE_SET_DEFAULT);
|
||||
assertThat(pmd.languageVersions()).contains(language.getDefaultVersion());
|
||||
assertThat(pmd.performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME))).isGreaterThan(0);
|
||||
|
||||
assertThat(pmd.defaultLanguageVersions(language.getVersion("17"), language.getVersion("21"))
|
||||
.languageVersions(language.getVersions()).performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME)))
|
||||
.as("17 & 21").isGreaterThan(0);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void testMainOperation() throws ExitStatusException {
|
||||
var pmd = newPmdOperation().inputPaths(new File("src/main"))
|
||||
.performPmdAnalysis(TEST, newPmdOperation().initConfiguration(COMMAND_NAME));
|
||||
assertThat(pmd).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testPrependAuxClasspath() {
|
||||
var pmd = newPmdOperation().ruleSets(CATEGORY_FOO).prependAuxClasspath(FOO, BAR);
|
||||
assertThat(pmd.prependAuxClasspath()).isEqualTo(FOO + File.pathSeparator + BAR);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testPriority() throws ExitStatusException {
|
||||
var pmd = newPmdOperation().inputPaths(CODE_STYLE_SAMPLE).minimumPriority(RulePriority.HIGH);
|
||||
assertThat(pmd.performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME))).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRelativizeRoots() {
|
||||
var baz = Path.of("baz/foz");
|
||||
|
||||
var pmd = newPmdOperation().ruleSets(List.of(CATEGORY_FOO)).relativizeRoots(PATH_FOO).
|
||||
relativizeRoots(PATH_BAR.toFile()).relativizeRoots(baz.toString())
|
||||
.relativizeRoots(List.of(PATH_FOO, PATH_BAR, baz));
|
||||
var config = pmd.initConfiguration(COMMAND_NAME);
|
||||
assertThat(config.getRelativizeRoots()).isEqualTo(pmd.relativizeRoots())
|
||||
.containsExactly(PATH_FOO, PATH_BAR, baz, PATH_FOO, PATH_BAR, baz);
|
||||
|
||||
pmd = newPmdOperation().ruleSets(List.of(CATEGORY_FOO))
|
||||
.relativizeRootsFiles(List.of(PATH_FOO.toFile(), PATH_BAR.toFile(), baz.toFile()));
|
||||
config = pmd.initConfiguration(COMMAND_NAME);
|
||||
assertThat(config.getRelativizeRoots()).as("List(File...)").isEqualTo(pmd.relativizeRoots())
|
||||
.containsExactly(PATH_FOO, PATH_BAR, baz);
|
||||
|
||||
pmd = newPmdOperation().ruleSets(List.of(CATEGORY_FOO))
|
||||
.relativizeRootsStrings(List.of(PATH_FOO.toString(), PATH_BAR.toString(), baz.toString()));
|
||||
config = pmd.initConfiguration(COMMAND_NAME);
|
||||
assertThat(config.getRelativizeRoots()).as("List(String....)").isEqualTo(pmd.relativizeRoots())
|
||||
.containsExactly(PATH_FOO, PATH_BAR, baz);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testReportFile() throws FileNotFoundException, ExitStatusException {
|
||||
var report = new File("build", "pmd-report-file");
|
||||
report.deleteOnExit();
|
||||
var pmd = newPmdOperation().ruleSets(List.of(ERROR_PRONE_XML, DESIGN_XML)).reportFile(report);
|
||||
pmd.performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME));
|
||||
assertThat(report).exists();
|
||||
|
||||
try (var writer = new PrintWriter(report)) {
|
||||
writer.write("");
|
||||
}
|
||||
assertThat(report).isEmpty();
|
||||
|
||||
pmd.reportFile(report.getAbsolutePath()).performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME));
|
||||
assertThat(report).isNotEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testReportFormat() throws IOException, ExitStatusException {
|
||||
var pmd = newPmdOperation().ruleSets(ERROR_PRONE_XML).reportFormat("xml").inputPaths(ERROR_PRONE_SAMPLE);
|
||||
assertThat(pmd.performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME))).isGreaterThan(0);
|
||||
try (var softly = new AutoCloseableSoftAssertions()) {
|
||||
try (var br = Files.newBufferedReader(pmd.reportFile())) {
|
||||
softly.assertThat(br.readLine()).as("xml report")
|
||||
.startsWith("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testReportProperties() throws ExitStatusException {
|
||||
var pmd = newPmdOperation().ruleSets(CODE_STYLE_XML, ERROR_PRONE_XML)
|
||||
.includeLineNumber(true)
|
||||
.reportProperties(new Properties());
|
||||
assertThat(pmd.performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME))).isGreaterThan(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRuleSetsConfigFile() throws ExitStatusException {
|
||||
var pmd = newPmdOperation().ruleSets("src/test/resources/pmd.xml")
|
||||
.ignoreFile("src/test/resources/ignore-all.txt");
|
||||
assertThat(pmd.performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME))).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRuleSetsEmpty() throws ExitStatusException {
|
||||
var pmd = newPmdOperation().ruleSets("").failOnError(false);
|
||||
assertThat(pmd.performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME))).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testShowSuppressed() {
|
||||
var pmd = newPmdOperation().ruleSets(ERROR_PRONE_XML).showSuppressed(true);
|
||||
var config = pmd.initConfiguration(COMMAND_NAME);
|
||||
assertThat(config.isShowSuppressedViolations()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuppressedMarker() {
|
||||
var pmd = newPmdOperation().ruleSets(ERROR_PRONE_XML).suppressedMarker(TEST);
|
||||
var config = pmd.initConfiguration(COMMAND_NAME);
|
||||
assertThat(config.getSuppressMarker()).isEqualTo(TEST);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testThreads() {
|
||||
var pmd = newPmdOperation().ruleSets(ERROR_PRONE_XML).threads(5);
|
||||
var config = pmd.initConfiguration(COMMAND_NAME);
|
||||
assertThat(config.getThreads()).isEqualTo(5);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUri() throws URISyntaxException {
|
||||
var uri = new URI("https://example.com");
|
||||
var pmd = newPmdOperation().ruleSets(ERROR_PRONE_XML).uri(uri);
|
||||
var config = pmd.initConfiguration(COMMAND_NAME);
|
||||
assertThat(config.getUri()).isEqualTo(uri);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testXml() throws ExitStatusException {
|
||||
var pmd = newPmdOperation().addInputPaths("src/test/resources/pmd.xml")
|
||||
.ruleSets("src/test/resources/xml/basic.xml");
|
||||
assertThat(pmd.performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME))).isGreaterThan(0);
|
||||
}
|
||||
}
|
761
src/test/java/rife/bld/extension/PmdOperationTests.java
Normal file
761
src/test/java/rife/bld/extension/PmdOperationTests.java
Normal file
|
@ -0,0 +1,761 @@
|
|||
/*
|
||||
* Copyright 2023-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package rife.bld.extension;
|
||||
|
||||
import net.sourceforge.pmd.PMDConfiguration;
|
||||
import net.sourceforge.pmd.lang.LanguageRegistry;
|
||||
import net.sourceforge.pmd.lang.rule.RulePriority;
|
||||
import org.assertj.core.api.AutoCloseableSoftAssertions;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import rife.bld.BaseProject;
|
||||
import rife.bld.operations.exceptions.ExitStatusException;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.logging.ConsoleHandler;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatCode;
|
||||
|
||||
/**
|
||||
* PmdOperationTests class
|
||||
*
|
||||
* @author <a href="https://erik.thauvin.net/">Erik C. Thauvin</a>
|
||||
* @since 1.0
|
||||
*/
|
||||
class PmdOperationTests {
|
||||
private static final String ANALYSIS_FAILURE = "analysis should fail";
|
||||
private static final String ANALYSIS_SUCCESS = "analysis should succeed";
|
||||
private static final String BAR = "bar";
|
||||
private static final String CATEGORY_FOO = "category/foo.xml";
|
||||
private static final Path CODE_STYLE_SAMPLE = Path.of("src/test/resources/java/CodeStyle.java");
|
||||
private static final String CODE_STYLE_XML = "category/java/codestyle.xml";
|
||||
private static final String COMMAND_NAME = "pmd";
|
||||
private static final String DESIGN_XML = "category/java/design.xml";
|
||||
private static final String DOCUMENTATION_XML = "category/java/documentation.xml";
|
||||
private static final Path ERROR_PRONE_SAMPLE = Path.of("src/test/resources/java/ErrorProne.java");
|
||||
private static final String ERROR_PRONE_XML = "category/java/errorprone.xml";
|
||||
private static final File FILE_BAR = new File(BAR);
|
||||
private static final String FOO = "foo";
|
||||
private static final File FILE_FOO = new File(FOO);
|
||||
private static final Path PATH_BAR = Path.of(BAR);
|
||||
private static final Path PATH_FOO = Path.of(FOO);
|
||||
private static final String PERFORMANCE_XML = "category/java/performance.xml";
|
||||
private static final String SECURITY_XML = "category/java/security.xml";
|
||||
private static final String TEST = "test";
|
||||
|
||||
@BeforeAll
|
||||
public static void beforeAll() {
|
||||
var consoleHandler = new ConsoleHandler();
|
||||
var logger = PmdOperation.LOGGER;
|
||||
|
||||
consoleHandler.setLevel(Level.ALL);
|
||||
logger.addHandler(consoleHandler);
|
||||
logger.setLevel(Level.ALL);
|
||||
logger.setUseParentHandlers(false);
|
||||
}
|
||||
|
||||
PmdOperation newPmdOperation() {
|
||||
return new PmdOperation()
|
||||
.inputPaths(Path.of("src/main"), Path.of("src/test"))
|
||||
.cache("build/" + COMMAND_NAME + "/pmd-cache")
|
||||
.failOnViolation(false)
|
||||
.reportFile(Paths.get("build", COMMAND_NAME, "pmd-test-report.txt"));
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("Configuration Tests")
|
||||
class ConfigurationTests {
|
||||
@Test
|
||||
void cache() throws ExitStatusException {
|
||||
var cache = Path.of("build/pmd/temp-cache");
|
||||
var pmd = newPmdOperation()
|
||||
.ruleSets(CODE_STYLE_XML)
|
||||
.inputPaths(List.of(CODE_STYLE_SAMPLE))
|
||||
.cache(cache);
|
||||
|
||||
assertThat(pmd.performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME)).rulesChecked())
|
||||
.isGreaterThan(0);
|
||||
var f = cache.toFile();
|
||||
assertThat(f.exists()).as("cache should exist").isTrue();
|
||||
assertThat(f.delete()).as("cache should be deleted").isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void collectFilesRecursively() {
|
||||
var pmd = newPmdOperation().ruleSets(ERROR_PRONE_XML).collectFilesRecursively(false);
|
||||
|
||||
var config = pmd.initConfiguration(COMMAND_NAME);
|
||||
assertThat(config.collectFilesRecursively()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void encoding() {
|
||||
var pmd = newPmdOperation().ruleSets(CATEGORY_FOO).encoding("UTF-16");
|
||||
|
||||
PMDConfiguration config = pmd.initConfiguration(COMMAND_NAME);
|
||||
assertThat(config.getSourceEncoding()).as("encoding should be UTF-16")
|
||||
.isEqualTo(StandardCharsets.UTF_16);
|
||||
|
||||
pmd = pmd.encoding(StandardCharsets.ISO_8859_1);
|
||||
config = pmd.initConfiguration(COMMAND_NAME);
|
||||
assertThat(config.getSourceEncoding()).as("encoding should be ISO_8859")
|
||||
.isEqualTo(StandardCharsets.ISO_8859_1);
|
||||
}
|
||||
|
||||
@Test
|
||||
void incrementalAnalysis() {
|
||||
var pmd = newPmdOperation().ruleSets(CATEGORY_FOO).incrementalAnalysis(true);
|
||||
|
||||
var config = pmd.initConfiguration(COMMAND_NAME);
|
||||
assertThat(config.isIgnoreIncrementalAnalysis()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void languageVersions() throws ExitStatusException {
|
||||
var language = LanguageRegistry.PMD.getLanguageById("java");
|
||||
assertThat(language).isNotNull();
|
||||
|
||||
var pmd = newPmdOperation()
|
||||
.forceLanguageVersion(language.getLatestVersion())
|
||||
.defaultLanguageVersions(language.getVersions())
|
||||
.languageVersions(language.getDefaultVersion())
|
||||
.ruleSets(PmdOperation.RULE_SET_DEFAULT);
|
||||
|
||||
assertThat(pmd.languageVersions()).as("should contain default language version")
|
||||
.contains(language.getDefaultVersion());
|
||||
assertThat(pmd.performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME)).processingErrors())
|
||||
.as("should have processing errors").isGreaterThan(0);
|
||||
|
||||
assertThat(pmd.defaultLanguageVersions(language.getVersion("17"), language.getVersion("21"))
|
||||
.languageVersions(language.getVersions())
|
||||
.excludesStrings("src/test/resources/txt", "src/test/resources/xml")
|
||||
.performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME)).configurationErrors())
|
||||
.as("should have no processing errors").isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void prependAuxClasspath() {
|
||||
var pmd = newPmdOperation().ruleSets(CATEGORY_FOO).prependAuxClasspath(FOO, BAR);
|
||||
assertThat(pmd.prependAuxClasspath()).isEqualTo(FOO + File.pathSeparator + BAR);
|
||||
}
|
||||
|
||||
@Test
|
||||
void priority() throws ExitStatusException {
|
||||
var pmd = newPmdOperation().inputPaths(CODE_STYLE_SAMPLE).minimumPriority(RulePriority.HIGH);
|
||||
assertThat(pmd.performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME)).rulesChecked())
|
||||
.as(ANALYSIS_SUCCESS).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void relativizeRoots() {
|
||||
var baz = Path.of("baz/foz");
|
||||
|
||||
var pmd = newPmdOperation()
|
||||
.ruleSets(List.of(CATEGORY_FOO))
|
||||
.relativizeRoots(PATH_FOO)
|
||||
.relativizeRoots(PATH_BAR.toFile()).relativizeRoots(baz.toString())
|
||||
.relativizeRoots(List.of(PATH_FOO, PATH_BAR, baz));
|
||||
|
||||
var config = pmd.initConfiguration(COMMAND_NAME);
|
||||
assertThat(config.getRelativizeRoots()).as("multiple roots").isEqualTo(pmd.relativizeRoots())
|
||||
.containsExactly(PATH_FOO, PATH_BAR, baz, PATH_FOO, PATH_BAR, baz);
|
||||
|
||||
pmd = newPmdOperation().ruleSets(List.of(CATEGORY_FOO))
|
||||
.relativizeRootsFiles(List.of(PATH_FOO.toFile(), PATH_BAR.toFile(), baz.toFile()));
|
||||
config = pmd.initConfiguration(COMMAND_NAME);
|
||||
assertThat(config.getRelativizeRoots()).as("List(File...)").isEqualTo(pmd.relativizeRoots())
|
||||
.containsExactly(PATH_FOO, PATH_BAR, baz);
|
||||
|
||||
pmd = newPmdOperation().ruleSets(List.of(CATEGORY_FOO))
|
||||
.relativizeRootsStrings(List.of(PATH_FOO.toString(), PATH_BAR.toString(), baz.toString()));
|
||||
config = pmd.initConfiguration(COMMAND_NAME);
|
||||
assertThat(config.getRelativizeRoots()).as("List(String....)").isEqualTo(pmd.relativizeRoots())
|
||||
.containsExactly(PATH_FOO, PATH_BAR, baz);
|
||||
}
|
||||
|
||||
@Test
|
||||
void showSuppressed() {
|
||||
var pmd = newPmdOperation().ruleSets(ERROR_PRONE_XML).showSuppressed(true);
|
||||
var config = pmd.initConfiguration(COMMAND_NAME);
|
||||
assertThat(config.isShowSuppressedViolations()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void suppressedMarker() {
|
||||
var pmd = newPmdOperation().ruleSets(ERROR_PRONE_XML).suppressedMarker(TEST);
|
||||
var config = pmd.initConfiguration(COMMAND_NAME);
|
||||
assertThat(config.getSuppressMarker()).isEqualTo(TEST);
|
||||
}
|
||||
|
||||
@Test
|
||||
void threads() {
|
||||
var pmd = newPmdOperation().ruleSets(ERROR_PRONE_XML).threads(5);
|
||||
var config = pmd.initConfiguration(COMMAND_NAME);
|
||||
assertThat(config.getThreads()).isEqualTo(5);
|
||||
}
|
||||
|
||||
@Test
|
||||
void uri() throws URISyntaxException {
|
||||
var uri = new URI("https://example.com");
|
||||
var pmd = newPmdOperation().ruleSets(ERROR_PRONE_XML).uri(uri);
|
||||
var config = pmd.initConfiguration(COMMAND_NAME);
|
||||
assertThat(config.getUri()).isEqualTo(uri);
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("Exclusion Tests")
|
||||
class ExclusionTests {
|
||||
@Test
|
||||
void addExcludes() {
|
||||
var pmd = newPmdOperation().ruleSets(CATEGORY_FOO).addExcludes(PATH_FOO);
|
||||
var config = pmd.initConfiguration(COMMAND_NAME);
|
||||
assertThat(config.getExcludes()).containsExactly(PATH_FOO);
|
||||
|
||||
pmd = pmd.addExcludes(PATH_BAR);
|
||||
config = pmd.initConfiguration(COMMAND_NAME);
|
||||
assertThat(config.getExcludes()).containsExactly(PATH_FOO, PATH_BAR);
|
||||
}
|
||||
|
||||
@Test
|
||||
void addExcludesFiles() {
|
||||
var pmd = newPmdOperation().ruleSets(CATEGORY_FOO).addExcludesFiles(FILE_FOO);
|
||||
var config = pmd.initConfiguration(COMMAND_NAME);
|
||||
assertThat(config.getExcludes()).containsExactly(FILE_FOO.toPath());
|
||||
|
||||
pmd = pmd.addExcludesFiles(FILE_BAR);
|
||||
config = pmd.initConfiguration(COMMAND_NAME);
|
||||
assertThat(config.getExcludes()).containsExactly(FILE_FOO.toPath(), FILE_BAR.toPath());
|
||||
}
|
||||
|
||||
@Test
|
||||
void addExcludesStrings() {
|
||||
var pmd = newPmdOperation().ruleSets(CATEGORY_FOO).addExcludesStrings(FOO);
|
||||
var config = pmd.initConfiguration(COMMAND_NAME);
|
||||
assertThat(config.getExcludes()).containsExactly(PATH_FOO);
|
||||
|
||||
pmd = pmd.addExcludesStrings(BAR);
|
||||
config = pmd.initConfiguration(COMMAND_NAME);
|
||||
assertThat(config.getExcludes()).containsExactly(PATH_FOO, PATH_BAR);
|
||||
}
|
||||
|
||||
@Test
|
||||
void excludes() {
|
||||
var foz = Path.of("foz/baz");
|
||||
var baz = Path.of("baz/foz");
|
||||
|
||||
var pmd = newPmdOperation().ruleSets(CATEGORY_FOO).excludes(PATH_FOO, PATH_BAR);
|
||||
var config = pmd.initConfiguration(COMMAND_NAME);
|
||||
assertThat(pmd.excludes()).containsExactly(List.of(PATH_FOO, PATH_BAR).toArray(new Path[0]));
|
||||
assertThat(config.getExcludes()).containsExactly(List.of(PATH_FOO, PATH_BAR).toArray(new Path[0]));
|
||||
|
||||
var excludes = List.of(List.of(PATH_FOO, PATH_BAR), List.of(foz, baz));
|
||||
for (var exclude : excludes) {
|
||||
pmd = newPmdOperation().ruleSets(CATEGORY_FOO).excludes(exclude);
|
||||
config = pmd.initConfiguration(COMMAND_NAME);
|
||||
assertThat(config.getExcludes()).containsExactly(exclude.toArray(new Path[0]));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void excludesFiles() {
|
||||
var foz = new File("foz");
|
||||
var baz = new File("baz");
|
||||
|
||||
var pmd = newPmdOperation().ruleSets(CATEGORY_FOO).excludesFiles(FILE_FOO, FILE_BAR);
|
||||
var config = pmd.initConfiguration(COMMAND_NAME);
|
||||
assertThat(config.getExcludes()).containsExactly(FILE_FOO.toPath(), FILE_BAR.toPath());
|
||||
|
||||
var excludes = List.of(List.of(FILE_FOO, FILE_BAR), List.of(foz, baz));
|
||||
for (var exclude : excludes) {
|
||||
pmd = newPmdOperation().ruleSets(CATEGORY_FOO).excludesFiles(exclude);
|
||||
config = pmd.initConfiguration(COMMAND_NAME);
|
||||
assertThat(config.getExcludes())
|
||||
.containsExactly(exclude.stream().map(File::toPath).toArray(Path[]::new));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void excludesStrings() {
|
||||
var foz = "foz";
|
||||
var baz = "baz";
|
||||
|
||||
var pmd = newPmdOperation().ruleSets(CATEGORY_FOO).excludesStrings(FOO, BAR);
|
||||
var config = pmd.initConfiguration(COMMAND_NAME);
|
||||
assertThat(pmd.excludes()).containsExactly(PATH_FOO, PATH_BAR);
|
||||
assertThat(config.getExcludes()).containsExactly(PATH_FOO, PATH_BAR);
|
||||
|
||||
var excludes = List.of(List.of(FOO, BAR), List.of(foz, baz));
|
||||
for (var exclude : excludes) {
|
||||
pmd = newPmdOperation().ruleSets(CATEGORY_FOO).excludesStrings(exclude);
|
||||
config = pmd.initConfiguration(COMMAND_NAME);
|
||||
assertThat(config.getExcludes())
|
||||
.containsExactly(exclude.stream().map(Paths::get).toArray(Path[]::new));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("Failure Tests")
|
||||
class FailureTests {
|
||||
@Test
|
||||
void failOnError() {
|
||||
var pmd = newPmdOperation().ruleSets("src/test/resources/xml/old.xml")
|
||||
.inputPaths(Path.of("src/test/resources/java/Documentation.java"));
|
||||
assertThatCode(() -> pmd.performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME)))
|
||||
.isInstanceOf(ExitStatusException.class);
|
||||
assertThatCode(() -> pmd.failOnError(false).performPmdAnalysis(TEST,
|
||||
pmd.initConfiguration(COMMAND_NAME))).doesNotThrowAnyException();
|
||||
}
|
||||
|
||||
@Test
|
||||
void failOnValidation() {
|
||||
var pmd = newPmdOperation().ruleSets(DOCUMENTATION_XML)
|
||||
.inputPaths(Path.of("src/test/resources/java/Documentation.java"));
|
||||
assertThatCode(() -> pmd.failOnViolation(true).performPmdAnalysis(TEST,
|
||||
pmd.initConfiguration(COMMAND_NAME))).isInstanceOf(ExitStatusException.class);
|
||||
assertThatCode(() -> pmd.failOnViolation(false).performPmdAnalysis(TEST,
|
||||
pmd.initConfiguration(COMMAND_NAME))).doesNotThrowAnyException();
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("Ignore File Tests")
|
||||
class IgnoreFileTests {
|
||||
@Test
|
||||
void ignoreFile() throws ExitStatusException {
|
||||
var pmd = newPmdOperation()
|
||||
.ruleSets(ERROR_PRONE_XML, CODE_STYLE_XML)
|
||||
.inputPaths(ERROR_PRONE_SAMPLE, CODE_STYLE_SAMPLE)
|
||||
.ignoreFile(Path.of("src/test/resources/txt/ignore.txt"));
|
||||
|
||||
assertThat(pmd.performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME)).violations())
|
||||
.as("%s for error prone and code style", ANALYSIS_SUCCESS).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void ignoreSingleFile() throws ExitStatusException {
|
||||
var pmd = newPmdOperation()
|
||||
.ruleSets(ERROR_PRONE_XML)
|
||||
.inputPaths(ERROR_PRONE_SAMPLE)
|
||||
.ignoreFile(new File("src/test/resources/txt/ignore-single.txt"));
|
||||
|
||||
assertThat(pmd.performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME)).violations())
|
||||
.as("%s for error prone sample", ANALYSIS_SUCCESS).isEqualTo(0);
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("Input Paths Tests")
|
||||
class InputPathsTests {
|
||||
@Test
|
||||
void fileArray() throws ExitStatusException {
|
||||
var pmd = newPmdOperation()
|
||||
.ruleSets(PmdOperation.RULE_SET_DEFAULT, CODE_STYLE_XML)
|
||||
.inputPaths(ERROR_PRONE_SAMPLE.toFile(), CODE_STYLE_SAMPLE.toFile());
|
||||
|
||||
assertThat(pmd.inputPaths()).containsExactly(ERROR_PRONE_SAMPLE, CODE_STYLE_SAMPLE);
|
||||
assertThat(pmd.performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME)).violations())
|
||||
.as(ANALYSIS_FAILURE).isGreaterThan(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void mainOperation() throws ExitStatusException {
|
||||
var pmd = newPmdOperation()
|
||||
.inputPaths(new File("src/main"))
|
||||
.performPmdAnalysis(TEST, newPmdOperation().initConfiguration(COMMAND_NAME))
|
||||
.violations();
|
||||
|
||||
assertThat(pmd).as(ANALYSIS_SUCCESS).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void pathArray() throws ExitStatusException {
|
||||
var pmd = newPmdOperation()
|
||||
.ruleSets(PmdOperation.RULE_SET_DEFAULT, CODE_STYLE_XML)
|
||||
.inputPaths(ERROR_PRONE_SAMPLE, CODE_STYLE_SAMPLE);
|
||||
|
||||
assertThat(pmd.inputPaths()).containsExactly(ERROR_PRONE_SAMPLE, CODE_STYLE_SAMPLE);
|
||||
assertThat(pmd.performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME)).violations())
|
||||
.as(ANALYSIS_FAILURE).isGreaterThan(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void pathList() throws ExitStatusException {
|
||||
var pmd = newPmdOperation()
|
||||
.ruleSets(PmdOperation.RULE_SET_DEFAULT, CODE_STYLE_XML)
|
||||
.inputPathsFiles(List.of(ERROR_PRONE_SAMPLE.toFile(), CODE_STYLE_SAMPLE.toFile()));
|
||||
|
||||
assertThat(pmd.inputPaths()).containsExactly(ERROR_PRONE_SAMPLE, CODE_STYLE_SAMPLE);
|
||||
assertThat(pmd.performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME)).violations())
|
||||
.as(ANALYSIS_FAILURE).isGreaterThan(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void stringArray() throws ExitStatusException {
|
||||
var pmd = newPmdOperation()
|
||||
.ruleSets(PmdOperation.RULE_SET_DEFAULT, CODE_STYLE_XML)
|
||||
.inputPaths(ERROR_PRONE_SAMPLE.toString(), CODE_STYLE_SAMPLE.toString());
|
||||
|
||||
assertThat(pmd.inputPaths()).containsExactly(ERROR_PRONE_SAMPLE, CODE_STYLE_SAMPLE);
|
||||
assertThat(pmd.performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME)).violations())
|
||||
.as(ANALYSIS_FAILURE).isGreaterThan(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void stringList() throws ExitStatusException {
|
||||
var pmd = newPmdOperation()
|
||||
.ruleSets(PmdOperation.RULE_SET_DEFAULT, CODE_STYLE_XML)
|
||||
.inputPathsStrings(List.of(ERROR_PRONE_SAMPLE.toString(), CODE_STYLE_SAMPLE.toString()));
|
||||
|
||||
assertThat(pmd.inputPaths()).containsExactly(ERROR_PRONE_SAMPLE, CODE_STYLE_SAMPLE);
|
||||
assertThat(pmd.performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME)).violations())
|
||||
.as(ANALYSIS_FAILURE).isGreaterThan(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void xml() throws ExitStatusException {
|
||||
var pmd = newPmdOperation().addInputPaths("src/test/resources/xml/pmd.xml")
|
||||
.ruleSets("src/test/resources/xml/basic.xml");
|
||||
|
||||
assertThat(pmd.performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME)).configurationErrors())
|
||||
.isEqualTo(0);
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("Add Input Paths Tests")
|
||||
class AddInputPathsTests {
|
||||
final BaseProject project = new BaseProject();
|
||||
|
||||
@Test
|
||||
void addInputPathsAsFileArray() {
|
||||
var pmd = new PmdOperation().fromProject(project);
|
||||
pmd.inputPaths().clear();
|
||||
pmd = pmd.addInputPaths(project.srcMainDirectory(), project.srcTestDirectory());
|
||||
|
||||
assertThat(pmd.inputPaths()).as("File...").containsExactly(project.srcMainDirectory().toPath(),
|
||||
project.srcTestDirectory().toPath());
|
||||
}
|
||||
|
||||
@Test
|
||||
void addInputPathsAsFileList() {
|
||||
var pmd = new PmdOperation().fromProject(project);
|
||||
pmd.inputPaths().clear();
|
||||
pmd = pmd.addInputPathsFiles(List.of(project.srcMainDirectory(), project.srcTestDirectory()));
|
||||
|
||||
assertThat(pmd.inputPaths()).as("List(File...)")
|
||||
.containsExactly(project.srcMainDirectory().toPath(), project.srcTestDirectory().toPath());
|
||||
}
|
||||
|
||||
@Test
|
||||
void addInputPathsAsPathArray() {
|
||||
var pmd = new PmdOperation().fromProject(project);
|
||||
pmd.inputPaths().clear();
|
||||
pmd = pmd.addInputPaths(project.srcMainDirectory().toPath(), project.srcTestDirectory().toPath());
|
||||
|
||||
assertThat(pmd.inputPaths()).as("Path...")
|
||||
.containsExactly(project.srcMainDirectory().toPath(), project.srcTestDirectory().toPath());
|
||||
}
|
||||
|
||||
@Test
|
||||
void addInputPathsAsPathList() {
|
||||
var pmd = new PmdOperation().fromProject(project);
|
||||
pmd.inputPaths().clear();
|
||||
pmd = pmd.addInputPaths(List.of(project.srcMainDirectory().toPath(),
|
||||
project.srcTestDirectory().toPath()));
|
||||
|
||||
assertThat(pmd.inputPaths()).as("List(Path)")
|
||||
.containsExactly(project.srcMainDirectory().toPath(), project.srcTestDirectory().toPath());
|
||||
}
|
||||
|
||||
@Test
|
||||
void addInputPathsAsStringArray() {
|
||||
var pmd = new PmdOperation().fromProject(project);
|
||||
pmd.inputPaths().clear();
|
||||
pmd = pmd.addInputPaths(project.srcMainDirectory().getAbsolutePath(),
|
||||
project.srcTestDirectory().getAbsolutePath());
|
||||
|
||||
assertThat(pmd.inputPaths()).as("String...")
|
||||
.containsExactly(project.srcMainDirectory().toPath(), project.srcTestDirectory().toPath());
|
||||
}
|
||||
|
||||
@Test
|
||||
void addInputPathsAsStringList() {
|
||||
var pmd = new PmdOperation().fromProject(project);
|
||||
pmd.inputPaths().clear();
|
||||
pmd = pmd.addInputPathsStrings(
|
||||
List.of(project.srcMainDirectory().getAbsolutePath(),
|
||||
project.srcTestDirectory().getAbsolutePath())
|
||||
);
|
||||
|
||||
assertThat(pmd.inputPaths()).as("List(String...)")
|
||||
.containsExactly(project.srcMainDirectory().toPath(), project.srcTestDirectory().toPath());
|
||||
}
|
||||
|
||||
@Test
|
||||
void addInputPathsWithDefaults() {
|
||||
var pmd = new PmdOperation().fromProject(project);
|
||||
assertThat(pmd.inputPaths()).as("default input paths")
|
||||
.containsExactly(project.srcMainDirectory().toPath(), project.srcTestDirectory().toPath());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("Reporting Tests")
|
||||
class ReportingTests {
|
||||
@Test
|
||||
void reportFile() throws FileNotFoundException, ExitStatusException {
|
||||
var report = new File("build", "pmd-report-file");
|
||||
report.deleteOnExit();
|
||||
var pmd = newPmdOperation()
|
||||
.ruleSets(List.of(ERROR_PRONE_XML, DESIGN_XML))
|
||||
.reportFile(report);
|
||||
|
||||
pmd.performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME));
|
||||
assertThat(report).as("report should exist").exists();
|
||||
|
||||
try (var writer = new PrintWriter(report)) {
|
||||
writer.write("");
|
||||
}
|
||||
assertThat(report).as("report should not be empty").isEmpty();
|
||||
|
||||
pmd.reportFile(report.getAbsolutePath()).performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME));
|
||||
assertThat(report).as("report should not be empty").isNotEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void reportFormat() throws IOException, ExitStatusException {
|
||||
var pmd = newPmdOperation()
|
||||
.ruleSets(ERROR_PRONE_XML)
|
||||
.reportFormat("xml")
|
||||
.inputPaths(ERROR_PRONE_SAMPLE);
|
||||
|
||||
assertThat(pmd.performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME)).violations())
|
||||
.as(ANALYSIS_FAILURE).isGreaterThan(0);
|
||||
try (var softly = new AutoCloseableSoftAssertions()) {
|
||||
try (var br = Files.newBufferedReader(pmd.reportFile())) {
|
||||
softly.assertThat(br.readLine()).as("XML report for %s", pmd.reportFile().toString())
|
||||
.startsWith("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void reportProperties() throws ExitStatusException {
|
||||
var pmd = newPmdOperation().ruleSets(CODE_STYLE_XML, ERROR_PRONE_XML)
|
||||
.includeLineNumber(true)
|
||||
.reportProperties(new Properties());
|
||||
|
||||
assertThat(pmd.performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME)).processingErrors())
|
||||
.isEqualTo(0);
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("RuleSets Tests")
|
||||
class RuleSetsTests {
|
||||
@Test
|
||||
void javaBestPractices() throws ExitStatusException {
|
||||
var pmd = newPmdOperation()
|
||||
.ruleSets("category/java/bestpractices.xml")
|
||||
.inputPaths(Path.of("src/test/resources/java/BestPractices.java"));
|
||||
|
||||
assertThat(pmd.performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME)).violations())
|
||||
.as(ANALYSIS_FAILURE).isGreaterThan(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void javaCodeStyle() throws ExitStatusException {
|
||||
var pmd = newPmdOperation().ruleSets(CODE_STYLE_XML).inputPaths(CODE_STYLE_SAMPLE);
|
||||
|
||||
assertThat(pmd.performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME)).violations())
|
||||
.as(ANALYSIS_FAILURE).isGreaterThan(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void javaCodeStyleAndErrorProne() throws ExitStatusException {
|
||||
var pmd = newPmdOperation().ruleSets(CODE_STYLE_XML).inputPaths(CODE_STYLE_SAMPLE);
|
||||
|
||||
assertThat(pmd.performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME)).violations())
|
||||
.as("analysis with code style").isGreaterThan(0);
|
||||
|
||||
pmd = pmd.ruleSets(ERROR_PRONE_XML).inputPaths(ERROR_PRONE_SAMPLE);
|
||||
assertThat(pmd.performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME)).violations())
|
||||
.as("analysis with code style and error prone").isGreaterThan(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void javaDesign() throws ExitStatusException {
|
||||
var pmd = newPmdOperation()
|
||||
.ruleSets(DESIGN_XML)
|
||||
.inputPaths("src/test/resources/java/Design.java")
|
||||
.cache(new File("build/pmd/design-cache"));
|
||||
|
||||
assertThat(pmd.performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME)).violations())
|
||||
.as(ANALYSIS_FAILURE).isGreaterThan(0);
|
||||
assertThat(pmd.performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME)).configurationErrors())
|
||||
.as(ANALYSIS_FAILURE).isGreaterThan(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void javaDocumentation() throws ExitStatusException {
|
||||
var pmd = newPmdOperation()
|
||||
.ruleSets(DOCUMENTATION_XML)
|
||||
.inputPaths(Path.of("src/test/resources/java/Documentation.java"));
|
||||
|
||||
assertThat(pmd.performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME)).violations())
|
||||
.as(ANALYSIS_FAILURE).isGreaterThan(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void javaErrorProne() throws ExitStatusException {
|
||||
var pmd = newPmdOperation().ruleSets(ERROR_PRONE_XML).inputPaths(ERROR_PRONE_SAMPLE);
|
||||
|
||||
assertThat(pmd.performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME)).violations())
|
||||
.as(ANALYSIS_FAILURE).isGreaterThan(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void javaMultiThreading() throws ExitStatusException {
|
||||
var pmd = newPmdOperation()
|
||||
.ruleSets("category/java/multithreading.xml")
|
||||
.inputPaths(Path.of("src/test/resources/java/MultiThreading.java"));
|
||||
|
||||
assertThat(pmd.performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME)).violations())
|
||||
.as(ANALYSIS_FAILURE).isGreaterThan(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void javaPerformance() throws ExitStatusException {
|
||||
var pmd = newPmdOperation()
|
||||
.ruleSets(PERFORMANCE_XML)
|
||||
.inputPaths(Path.of("src/test/resources/java/Performance.java"));
|
||||
|
||||
assertThat(pmd.performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME)).violations())
|
||||
.as(ANALYSIS_FAILURE).isGreaterThan(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void javaQuickStart() throws ExitStatusException {
|
||||
var pmd = newPmdOperation()
|
||||
.ruleSets(PmdOperation.RULE_SET_DEFAULT)
|
||||
.inputPaths(new File("src/test/resources/java/"));
|
||||
|
||||
assertThat(pmd.ruleSets()).containsExactly(PmdOperation.RULE_SET_DEFAULT);
|
||||
assertThat(pmd.performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME)).violations())
|
||||
.as(ANALYSIS_FAILURE).isGreaterThan(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void javaSecurity() throws ExitStatusException {
|
||||
var pmd = newPmdOperation()
|
||||
.ruleSets(SECURITY_XML)
|
||||
.inputPaths(Path.of("src/test/resources/java/Security.java"));
|
||||
|
||||
assertThat(pmd.performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME)).violations())
|
||||
.as(ANALYSIS_FAILURE).isGreaterThan(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void ruleSetsConfigFile() throws ExitStatusException {
|
||||
var pmd = newPmdOperation()
|
||||
.ruleSets("src/test/resources/xml/pmd.xml")
|
||||
.ignoreFile("src/test/resources/txt/ignore-all.txt");
|
||||
|
||||
assertThat(pmd.performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME)).hasNoErrors()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void ruleSetsEmpty() throws ExitStatusException {
|
||||
var pmd = newPmdOperation().ruleSets("").failOnError(false);
|
||||
assertThat(pmd.performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME)).errors())
|
||||
.isEqualTo(1);
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("Add RuleSets Tests")
|
||||
class AddRuleSetsTests {
|
||||
@Test
|
||||
void addRuleSetsWithDefault() {
|
||||
var pmd = new PmdOperation().fromProject(new BaseProject());
|
||||
|
||||
assertThat(pmd.ruleSets()).containsExactly(PmdOperation.RULE_SET_DEFAULT);
|
||||
}
|
||||
|
||||
@Test
|
||||
void addRuleSetsWithErrorProne() {
|
||||
var pmd = new PmdOperation().fromProject(new BaseProject());
|
||||
|
||||
pmd.addRuleSet(ERROR_PRONE_XML);
|
||||
|
||||
assertThat(pmd.ruleSets()).containsExactly(PmdOperation.RULE_SET_DEFAULT, ERROR_PRONE_XML);
|
||||
}
|
||||
|
||||
@Test
|
||||
void addRuleSetsWithList() {
|
||||
var pmd = new PmdOperation().fromProject(new BaseProject());
|
||||
pmd.ruleSets().clear();
|
||||
pmd.addRuleSet(List.of(PmdOperation.RULE_SET_DEFAULT, ERROR_PRONE_XML));
|
||||
|
||||
assertThat(pmd.ruleSets()).as("rulesets as collection")
|
||||
.containsExactly(PmdOperation.RULE_SET_DEFAULT, ERROR_PRONE_XML);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("Execution Tests")
|
||||
class ExecutionTests {
|
||||
@Test
|
||||
void execute() throws ExitStatusException {
|
||||
var pmd = new PmdOperation().fromProject(new BaseProject());
|
||||
|
||||
assertThat(pmd.inputPaths()).containsExactly(Paths.get("src/main").toAbsolutePath(),
|
||||
Paths.get("src/test").toAbsolutePath());
|
||||
|
||||
pmd.inputPaths().clear();
|
||||
pmd.inputPaths("src/main/java", "src/test/java")
|
||||
.ruleSets("config/pmd.xml");
|
||||
|
||||
assertThat(pmd.ruleSets()).containsExactly("config/pmd.xml");
|
||||
assertThat(pmd.performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME)).violations())
|
||||
.as(ANALYSIS_SUCCESS).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void executeNoProject() {
|
||||
var pmd = new PmdOperation();
|
||||
assertThatCode(pmd::execute).isInstanceOf(ExitStatusException.class);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Copyright 2023-2025 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package rife.bld.extension.pmd;
|
||||
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
|
||||
|
||||
class PmdAnalysisResultsTests {
|
||||
@Nested
|
||||
@DisplayName("Errors Tests")
|
||||
class ErrorsTests {
|
||||
@Test
|
||||
void hasConfigurationErrors() {
|
||||
var results = new PmdAnalysisResults(
|
||||
0, 0, 0, 0, 1, 0);
|
||||
assertThat(results.hasNoErrors()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void hasErrors() {
|
||||
var results = new PmdAnalysisResults(
|
||||
0, 0, 1, 0, 0, 0);
|
||||
assertThat(results.hasNoErrors()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void hasNoErrors() {
|
||||
var results = new PmdAnalysisResults(
|
||||
0, 0, 0, 0, 0, 0);
|
||||
assertThat(results.hasNoErrors()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void hasProcessingErrors() {
|
||||
var results = new PmdAnalysisResults(
|
||||
0, 0, 0, 1, 0, 0);
|
||||
assertThat(results.hasNoErrors()).isFalse();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue