| package org.checkerframework.framework.test; |
| |
| import java.util.ArrayList; |
| import java.util.LinkedHashSet; |
| import java.util.List; |
| import java.util.Set; |
| import java.util.StringJoiner; |
| import javax.tools.Diagnostic; |
| import javax.tools.JavaFileObject; |
| import org.checkerframework.framework.test.diagnostics.TestDiagnostic; |
| import org.checkerframework.framework.test.diagnostics.TestDiagnosticUtils; |
| import org.plumelib.util.StringsPlume; |
| |
| /** |
| * Represents the test results from typechecking one or more Java files using the given |
| * TestConfiguration. |
| */ |
| public class TypecheckResult { |
| private final TestConfiguration configuration; |
| private final CompilationResult compilationResult; |
| private final List<TestDiagnostic> expectedDiagnostics; |
| |
| private final List<TestDiagnostic> missingDiagnostics; |
| private final List<TestDiagnostic> unexpectedDiagnostics; |
| |
| protected TypecheckResult( |
| TestConfiguration configuration, |
| CompilationResult compilationResult, |
| List<TestDiagnostic> expectedDiagnostics, |
| List<TestDiagnostic> missingDiagnostics, |
| List<TestDiagnostic> unexpectedDiagnostics) { |
| this.configuration = configuration; |
| this.compilationResult = compilationResult; |
| this.expectedDiagnostics = expectedDiagnostics; |
| this.missingDiagnostics = missingDiagnostics; |
| this.unexpectedDiagnostics = unexpectedDiagnostics; |
| } |
| |
| public TestConfiguration getConfiguration() { |
| return configuration; |
| } |
| |
| public CompilationResult getCompilationResult() { |
| return compilationResult; |
| } |
| |
| public List<Diagnostic<? extends JavaFileObject>> getActualDiagnostics() { |
| return compilationResult.getDiagnostics(); |
| } |
| |
| public List<TestDiagnostic> getExpectedDiagnostics() { |
| return expectedDiagnostics; |
| } |
| |
| public boolean didTestFail() { |
| return !unexpectedDiagnostics.isEmpty() || !missingDiagnostics.isEmpty(); |
| } |
| |
| public List<TestDiagnostic> getMissingDiagnostics() { |
| return missingDiagnostics; |
| } |
| |
| public List<TestDiagnostic> getUnexpectedDiagnostics() { |
| return unexpectedDiagnostics; |
| } |
| |
| public List<String> getErrorHeaders() { |
| List<String> errorHeaders = new ArrayList<>(); |
| |
| // none of these should be true if the test didn't fail |
| if (didTestFail()) { |
| if (compilationResult.compiledWithoutError() && !expectedDiagnostics.isEmpty()) { |
| errorHeaders.add("The test run was expected to issue errors/warnings, but it did not."); |
| |
| } else if (!compilationResult.compiledWithoutError() && expectedDiagnostics.isEmpty()) { |
| errorHeaders.add("The test run was not expected to issue errors/warnings, but it did."); |
| } |
| |
| if (!unexpectedDiagnostics.isEmpty() || !missingDiagnostics.isEmpty()) { |
| int numExpected = expectedDiagnostics.size(); |
| int numFound = numExpected - missingDiagnostics.size(); |
| errorHeaders.add( |
| numFound |
| + " out of " |
| + StringsPlume.nplural(numExpected, "expected diagnostic") |
| + " " |
| + (numFound == 1 ? "was" : "were") |
| + " found."); |
| } |
| } |
| |
| return errorHeaders; |
| } |
| |
| /** |
| * Summarize unexpected and missing diagnostics. |
| * |
| * @return summary of failures |
| */ |
| public String summarize() { |
| if (!didTestFail()) { |
| return ""; |
| } |
| StringJoiner summaryBuilder = new StringJoiner(System.lineSeparator()); |
| summaryBuilder.add(StringsPlume.joinLines(getErrorHeaders())); |
| |
| if (!unexpectedDiagnostics.isEmpty()) { |
| int numUnexpected = unexpectedDiagnostics.size(); |
| if (numUnexpected == 1) { |
| summaryBuilder.add("1 unexpected diagnostic was found"); |
| } else { |
| summaryBuilder.add(numUnexpected + " unexpected diagnostics were found"); |
| } |
| |
| for (TestDiagnostic unexpected : unexpectedDiagnostics) { |
| summaryBuilder.add(unexpected.toString()); |
| } |
| } |
| |
| if (!missingDiagnostics.isEmpty()) { |
| int numMissing = missingDiagnostics.size(); |
| summaryBuilder.add( |
| StringsPlume.nplural(numMissing, "expected diagnostic") |
| + " " |
| + (numMissing == 1 ? "was" : "were") |
| + " not found:"); |
| |
| for (TestDiagnostic missing : missingDiagnostics) { |
| summaryBuilder.add(missing.toString()); |
| } |
| } |
| |
| summaryBuilder.add( |
| "While type-checking " |
| + TestUtilities.summarizeSourceFiles(configuration.getTestSourceFiles())); |
| return summaryBuilder.toString(); |
| } |
| |
| public static TypecheckResult fromCompilationResults( |
| TestConfiguration configuration, |
| CompilationResult result, |
| List<TestDiagnostic> expectedDiagnostics) { |
| |
| boolean usingAnomsgtxt = configuration.getOptions().containsKey("-Anomsgtext"); |
| final Set<TestDiagnostic> actualDiagnostics = |
| TestDiagnosticUtils.fromJavaxDiagnosticList(result.getDiagnostics(), usingAnomsgtxt); |
| |
| final Set<TestDiagnostic> unexpectedDiagnostics = new LinkedHashSet<>(); |
| unexpectedDiagnostics.addAll(actualDiagnostics); |
| unexpectedDiagnostics.removeAll(expectedDiagnostics); |
| |
| final List<TestDiagnostic> missingDiagnostics = new ArrayList<>(expectedDiagnostics); |
| missingDiagnostics.removeAll(actualDiagnostics); |
| |
| return new TypecheckResult( |
| configuration, |
| result, |
| expectedDiagnostics, |
| missingDiagnostics, |
| new ArrayList<>(unexpectedDiagnostics)); |
| } |
| } |