Skip to content

Commit

Permalink
test: Verify that compilable Java files still compile after repair (#569
Browse files Browse the repository at this point in the history
)

* Move assertCompiles into assertions helper class

* Add test to ensure that output after processing compiles

* Ignore MathOnFloat.java and CastArithmeticOperand.java in compile-after test
  • Loading branch information
slarse authored Jun 16, 2021
1 parent 08936e4 commit 130d644
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 46 deletions.
57 changes: 57 additions & 0 deletions src/test/java/sorald/Assertions.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package sorald;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.notNullValue;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.io.File;
import java.util.List;
import java.util.stream.Collectors;
import javax.tools.Diagnostic;
import javax.tools.DiagnosticCollector;
import javax.tools.JavaFileObject;
import javax.tools.ToolProvider;
import org.apache.commons.lang3.tuple.Pair;

/** High-level assertions. */
public class Assertions {

/**
* Assert that the given Java file compiles on its own.
*
* @param javaFile A Java source file.
*/
public static void assertCompiles(File javaFile) {
var compileResults = compile(javaFile);
boolean compileSuccessful = compileResults.getLeft();
String diagnosticsOutput = compileResults.getRight();

assertTrue(compileSuccessful, diagnosticsOutput);
}

/** Returns a pair (compileSuccess, diagnosticsOutput) */
private static Pair<Boolean, String> compile(File javaFile) {
// inspired comment by user GETah on StackOverflow: https://stackoverflow.com/a/8364016

var compiler = ToolProvider.getSystemJavaCompiler();
assertThat(
"System does not have a Java compiler, please run test suite with a JDK",
compiler,
notNullValue());

var diagnostics = new DiagnosticCollector<JavaFileObject>();
var fileManager = compiler.getStandardFileManager(diagnostics, null, null);
var compilationUnits =
fileManager.getJavaFileObjectsFromStrings(List.of(javaFile.getAbsolutePath()));
var task = compiler.getTask(null, fileManager, diagnostics, null, null, compilationUnits);

boolean success = task.call();

String diagnosticsOutput =
diagnostics.getDiagnostics().stream()
.map(Diagnostic::toString)
.collect(Collectors.joining(System.lineSeparator()));

return Pair.of(success, diagnosticsOutput);
}
}
29 changes: 29 additions & 0 deletions src/test/java/sorald/processor/ProcessorTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,16 @@
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assumptions.assumeFalse;
import static sorald.Assertions.assertCompiles;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Comparator;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.json.JSONArray;
Expand All @@ -21,6 +24,7 @@
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.ArgumentsProvider;
import org.junit.jupiter.params.provider.ArgumentsSource;
import org.junit.jupiter.params.provider.MethodSource;
import org.sonar.java.checks.ArrayHashCodeAndToStringCheck;
import org.sonar.java.checks.DeadStoreCheck;
import org.sonar.plugins.java.api.JavaFileScanner;
Expand All @@ -36,6 +40,9 @@

public class ProcessorTest {

private static final Set<String> FILES_THAT_DONT_COMPILE_AFTER_REPAIR =
Set.of("MathOnFloat.java", "CastArithmeticOperand.java");

/**
* Parameterized test that processes a single Java file at a time with a single processor.
*
Expand Down Expand Up @@ -116,6 +123,28 @@ public void testProcessSingleFile(
assertEquals(expectedImports, repairedImports);
}

@ParameterizedTest
@MethodSource("getCompilableProcessorTestCases")
void sorald_producesCompilableOutput_whenInputIsCompilable(
ProcessorTestHelper.ProcessorTestCase<?> compilableTestCase) throws Exception {
assumeFalse(
FILES_THAT_DONT_COMPILE_AFTER_REPAIR.contains(
compilableTestCase.nonCompliantFile.getName()),
"See https://github.com/SpoonLabs/sorald/issues/570");

ProcessorTestHelper.runSorald(compilableTestCase);
assertCompiles(compilableTestCase.repairedFilePath().toFile());
}

private static Stream<Arguments> getCompilableProcessorTestCases() throws IOException {
return ProcessorTestHelper.getTestCaseStream()
.filter(
tc ->
ProcessorTestHelper.isStandaloneCompilableTestFile(
tc.nonCompliantFile))
.map(Arguments::of);
}

/**
* Parameterized test that processes a single Java file at a time with a single processor, and
* asserts that literal exact matches are contained in the output.
Expand Down
48 changes: 2 additions & 46 deletions src/test/java/sorald/processor/ProcessorTestFilesCompileTest.java
Original file line number Diff line number Diff line change
@@ -1,20 +1,11 @@
package sorald.processor;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.notNullValue;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static sorald.Assertions.assertCompiles;

import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.tools.Diagnostic;
import javax.tools.DiagnosticCollector;
import javax.tools.JavaFileObject;
import javax.tools.ToolProvider;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.junit.jupiter.api.io.TempDir;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
Expand All @@ -25,8 +16,7 @@ class ProcessorTestFilesCompileTest {

@ParameterizedTest
@MethodSource("provideCompilableProcessorTestInputFile")
void processorTestCaseInputFile_notMarkedNOCOMPILE_shouldCompile(File testCaseJavaFile)
throws IOException {
void processorTestCaseInputFile_notMarkedNOCOMPILE_shouldCompile(File testCaseJavaFile) {
assertCompiles(testCaseJavaFile);
}

Expand Down Expand Up @@ -67,38 +57,4 @@ private static File copyFileToDirWithoutExpectedExtension(File expectedJavaFile,
ProcessorTestHelper.isStandaloneCompilableTestFile(
tc.nonCompliantFile));
}

private static void assertCompiles(File javaFile) throws IOException {
var compileResults = compile(javaFile);
boolean compileSuccessful = compileResults.getLeft();
String diagnosticsOutput = compileResults.getRight();

assertTrue(compileSuccessful, diagnosticsOutput);
}

/** Returns a pair (compileSuccess, diagnosticsOutput) */
private static Pair<Boolean, String> compile(File javaFile) {
// inspired comment by user GETah on StackOverflow: https://stackoverflow.com/a/8364016

var compiler = ToolProvider.getSystemJavaCompiler();
assertThat(
"System does not have a Java compiler, please run test suite with a JDK",
compiler,
notNullValue());

var diagnostics = new DiagnosticCollector<JavaFileObject>();
var fileManager = compiler.getStandardFileManager(diagnostics, null, null);
var compilationUnits =
fileManager.getJavaFileObjectsFromStrings(List.of(javaFile.getAbsolutePath()));
var task = compiler.getTask(null, fileManager, diagnostics, null, null, compilationUnits);

boolean success = task.call();

String diagnosticsOutput =
diagnostics.getDiagnostics().stream()
.map(Diagnostic::toString)
.collect(Collectors.joining(System.lineSeparator()));

return Pair.of(success, diagnosticsOutput);
}
}

0 comments on commit 130d644

Please sign in to comment.