Add basic CLI test

This commit is contained in:
Juan Martín Sotuyo Dodero
2022-08-17 14:47:31 -03:00
parent ccf6adfcd6
commit 52d2616181
2 changed files with 262 additions and 0 deletions

View File

@ -284,6 +284,17 @@
<artifactId>system-lambda</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<!-- Test classes of pmd-core, which contain dummy language modules. -->
<groupId>net.sourceforge.pmd</groupId>
<artifactId>pmd-core</artifactId>
<version>${project.version}</version>
<scope>test</scope>
<classifier>tests</classifier>
<type>test-jar</type>
</dependency>
<!-- TODO : Review if this should be part of pmd-cli… probably it does -->
<dependency>
<groupId>me.tongfei</groupId>

View File

@ -0,0 +1,251 @@
/*
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.cli;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.containsStringIgnoringCase;
import static org.hamcrest.Matchers.not;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import net.sourceforge.pmd.cli.internal.ExecutionResult;
import net.sourceforge.pmd.internal.Slf4jSimpleConfiguration;
import com.github.stefanbirkner.systemlambda.SystemLambda;
class PmdCliTest {
@TempDir
private Path tempDir;
private static final String DUMMY_RULESET = "net/sourceforge/pmd/cli/FakeRuleset.xml";
private static final String STRING_TO_REPLACE = "__should_be_replaced__";
private Path srcDir;
@AfterAll
static void resetLogging() {
// reset logging in case "--debug" changed the logging properties
// See also Slf4jSimpleConfigurationForAnt
Slf4jSimpleConfiguration.reconfigureDefaultLogLevel(null);
}
@BeforeEach
void setup() throws IOException {
// set current directory to wd
Path root = tempRoot();
System.setProperty("user.dir", root.toString());
// create a few files
srcDir = Files.createDirectories(root.resolve("src"));
writeString(srcDir.resolve("someSource.dummy"), "dummy text");
}
@Test
void testPreExistingReportFile() throws Exception {
Path reportFile = tempRoot().resolve("out/reportFile.txt");
// now we create the file
Files.createDirectories(reportFile.getParent());
writeString(reportFile, STRING_TO_REPLACE);
assertTrue(Files.exists(reportFile), "Report file should exist");
runPmdSuccessfully("-d", srcDir.toString(), "-R", DUMMY_RULESET, "-r", reportFile.toString());
assertNotEquals(readString(reportFile), STRING_TO_REPLACE);
}
@Test
void testPreExistingReportFileLongOption() throws Exception {
Path reportFile = tempRoot().resolve("out/reportFile.txt");
// now we create the file
Files.createDirectories(reportFile.getParent());
writeString(reportFile, STRING_TO_REPLACE);
assertTrue(Files.exists(reportFile), "Report file should exist");
runPmdSuccessfully("--dir", srcDir.toString(), "--rulesets", DUMMY_RULESET, "--report-file", reportFile.toString());
assertNotEquals(readString(reportFile), STRING_TO_REPLACE, "Report file should have been overwritten");
}
@Test
void testNonExistentReportFile() throws Exception {
Path reportFile = tempRoot().resolve("out/reportFile.txt");
assertFalse(Files.exists(reportFile), "Report file should not exist");
try {
runPmdSuccessfully("-d", srcDir.toString(), "-R", DUMMY_RULESET, "-r", reportFile.toString());
assertTrue(Files.exists(reportFile), "Report file should have been created");
} finally {
Files.deleteIfExists(reportFile);
}
}
@Test
void testNonExistentReportFileLongOption() throws Exception {
Path reportFile = tempRoot().resolve("out/reportFile.txt");
assertFalse(Files.exists(reportFile), "Report file should not exist");
runPmdSuccessfully("--dir", srcDir.toString(), "--rulesets", DUMMY_RULESET, "--report-file", reportFile.toString());
assertTrue(Files.exists(reportFile), "Report file should have been created");
}
@Test
void testFileCollectionWithUnknownFiles() throws Exception {
Path reportFile = tempRoot().resolve("out/reportFile.txt");
Files.createFile(srcDir.resolve("foo.not_analysable"));
assertFalse(Files.exists(reportFile), "Report file should not exist");
// restoring system properties: --debug might change logging properties
SystemLambda.restoreSystemProperties(() -> {
runPmdSuccessfully("--dir", srcDir.toString(), "--rulesets", DUMMY_RULESET, "--report-file", reportFile.toString(), "--debug");
});
assertTrue(Files.exists(reportFile), "Report file should have been created");
String reportText = readString(reportFile);
assertThat(reportText, not(containsStringIgnoringCase("error")));
}
/**
* This tests to create the report file in the current working directory.
*
* <p>Note: We can't change the cwd in the running VM, so the file will not be created
* in the temporary folder, but really in the cwd. The test fails if a file already exists
* and makes sure to cleanup the file afterwards.
*/
@Test
void testRelativeReportFile() throws Exception {
String reportFile = "reportFile.txt";
Path absoluteReportFile = FileSystems.getDefault().getPath(reportFile).toAbsolutePath();
// verify the file doesn't exist yet - we will delete the file at the end!
assertFalse(Files.exists(absoluteReportFile), "Report file must not exist yet! " + absoluteReportFile);
try {
runPmdSuccessfully("-d", srcDir.toString(), "-R", DUMMY_RULESET, "-r", reportFile.toString());
assertTrue(Files.exists(absoluteReportFile), "Report file should have been created");
} finally {
Files.deleteIfExists(absoluteReportFile);
}
}
@Test
void testRelativeReportFileLongOption() throws Exception {
String reportFile = "reportFile.txt";
Path absoluteReportFile = FileSystems.getDefault().getPath(reportFile).toAbsolutePath();
// verify the file doesn't exist yet - we will delete the file at the end!
assertFalse(Files.exists(absoluteReportFile), "Report file must not exist yet!");
try {
runPmdSuccessfully("--dir", srcDir.toString(), "--rulesets", DUMMY_RULESET, "--report-file", reportFile.toString());
assertTrue(Files.exists(absoluteReportFile), "Report file should have been created");
} finally {
Files.deleteIfExists(absoluteReportFile);
}
}
@Test
void debugLogging() throws Exception {
// restoring system properties: --debug might change logging properties
SystemLambda.restoreSystemProperties(() -> {
String log = runPmdSuccessfully("--debug", "--dir", srcDir.toString(), "--rulesets", DUMMY_RULESET);
assertThat(log, containsString("[main] INFO net.sourceforge.pmd.cli.commands.internal.AbstractPmdSubcommand - Log level is at TRACE"));
});
}
@Test
void defaultLogging() throws Exception {
String log = runPmdSuccessfully("--dir", srcDir.toString(), "--rulesets", DUMMY_RULESET);
assertThat(log, containsString("[main] INFO net.sourceforge.pmd.cli.commands.internal.AbstractPmdSubcommand - Log level is at INFO"));
}
@Test
void testDeprecatedRulesetSyntaxOnCommandLine() throws Exception {
String log = SystemLambda.tapSystemErrAndOut(() -> {
runPmd(ExecutionResult.VIOLATIONS_FOUND, "--dir", srcDir.toString(), "--rulesets", "dummy-basic");
});
assertThat(log, containsString("Ruleset reference 'dummy-basic' uses a deprecated form, use 'rulesets/dummy/basic.xml' instead"));
}
@Test
void testWrongCliOptionsDoNotPrintUsage() throws Exception {
final String log = SystemLambda.tapSystemErrAndOut(() -> {
final int actualExitCode = SystemLambda.catchSystemExit(() -> {
PmdCli.main(new String[] { "run", "--invalid" });
});
assertEquals(2, actualExitCode);
});
assertThat(log, not(containsStringIgnoringCase("Available report formats and")));
}
// utilities
private Path tempRoot() {
return tempDir;
}
private static String runPmdSuccessfully(String... args) throws Exception {
return SystemLambda.tapSystemErrAndOut(() -> {
runPmd(ExecutionResult.OK, args);
});
}
// available in Files on java 11+
private static void writeString(Path path, String text) throws IOException {
ByteBuffer encoded = StandardCharsets.UTF_8.encode(text);
Files.write(path, encoded.array());
}
// available in Files on java 11+
private static String readString(Path path) throws IOException {
byte[] bytes = Files.readAllBytes(path);
ByteBuffer buf = ByteBuffer.wrap(bytes);
return StandardCharsets.UTF_8.decode(buf).toString();
}
private static void runPmd(ExecutionResult expectedExitCode, String... args) throws Exception {
final int actualExitCode = SystemLambda.catchSystemExit(() -> {
final List<String> argList = new ArrayList<>();
// Always run against dummy language without logging not cache to remove all logging noise
argList.add("run");
argList.add("--use-version");
argList.add("dummy");
argList.add("--no-cache");
argList.add("--no-progress");
argList.addAll(Arrays.asList(args));
PmdCli.main(argList.toArray(new String[0]));
});
assertEquals(expectedExitCode.getExitCode(), actualExitCode, "Exit code");
}
}