blob: 7e7c03450912f8d49bbd2ef31e00faf256402d24 [file]
// Copyright (c) 2017, the R8 project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.fail;
import com.android.tools.r8.utils.ListUtils;
import com.google.common.collect.Iterables;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.function.BiFunction;
import org.hamcrest.Matcher;
public class TestDiagnosticMessagesImpl extends TestDiagnosticMessages
implements DiagnosticsHandler {
private final List<Diagnostic> infos = new ArrayList<>();
private final List<Diagnostic> warnings = new ArrayList<>();
private final List<Diagnostic> errors = new ArrayList<>();
BiFunction<DiagnosticsLevel, Diagnostic, DiagnosticsLevel> modifier;
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("Infos: ").append('\n');
for (Diagnostic info : infos) {
builder.append(" - ").append(info.getDiagnosticMessage()).append('\n');
}
builder.append("Warnings: ").append('\n');
for (Diagnostic warning : warnings) {
builder.append(" - ").append(warning.getDiagnosticMessage()).append('\n');
}
builder.append("Errors: ").append('\n');
for (Diagnostic error : errors) {
builder.append(" - ").append(error.getDiagnosticMessage()).append('\n');
}
return builder.toString();
}
@Override
public void info(Diagnostic info) {
// We are almost always compiling with assertions enabled and R8 will print a message. We
// discard the message here because for almost all tests, this message is not relevant.
if (!info.getDiagnosticMessage()
.equals("Running R8 version " + Version.LABEL + " with assertions enabled.")) {
infos.add(info);
}
}
@Override
public void warning(Diagnostic warning) {
warnings.add(warning);
}
@Override
public void error(Diagnostic error) {
errors.add(error);
}
@Override
public DiagnosticsLevel modifyDiagnosticsLevel(DiagnosticsLevel level, Diagnostic diagnostic) {
return modifier == null ? level : modifier.apply(level, diagnostic);
}
@Override
public List<Diagnostic> getInfos() {
return infos;
}
@Override
public List<Diagnostic> getWarnings() {
return warnings;
}
@Override
public List<Diagnostic> getErrors() {
return errors;
}
private void assertEmpty(String type, List<Diagnostic> messages) {
assertEquals(
"Expected no "
+ type
+ " messages, got:\n"
+ String.join("\n", ListUtils.map(messages, Diagnostic::getDiagnosticMessage)),
0,
messages.size());
}
@Override
public TestDiagnosticMessages assertNoMessages() {
assertEmpty("info", getInfos());
assertEmpty("warning", getWarnings());
assertEmpty("error", getErrors());
return this;
}
@Override
public TestDiagnosticMessages assertHasWarnings() {
assertFalse(warnings.isEmpty());
return this;
}
@Override
public TestDiagnosticMessages assertOnlyInfos() {
assertNotEquals(0, getInfos().size());
assertEmpty("warning", getWarnings());
assertEmpty("error", getErrors());
return this;
}
@Override
public TestDiagnosticMessages assertOnlyWarnings() {
assertEmpty("info", getInfos());
assertNotEquals(0, getWarnings().size());
assertEmpty("error", getErrors());
return this;
}
@Override
public TestDiagnosticMessages assertOnlyErrors() {
assertEmpty("info", getInfos());
assertEmpty("warning", getWarnings());
assertNotEquals(0, getErrors().size());
return this;
}
@Override
public TestDiagnosticMessages assertInfosCount(int count) {
assertEquals(count, getInfos().size());
return this;
}
@Override
public TestDiagnosticMessages assertWarningsCount(int count) {
assertEquals(count, getWarnings().size());
return this;
}
@Override
public TestDiagnosticMessages assertErrorsCount(int count) {
assertEquals(count, getErrors().size());
return this;
}
private TestDiagnosticMessages assertAllDiagnosticsMatches(
Iterable<Diagnostic> diagnostics, String tag, Matcher<Diagnostic> matcher) {
for (Diagnostic diagnostic : diagnostics) {
assertThat(diagnostic, matcher);
}
return this;
}
private TestDiagnosticMessages assertDiagnosticThatMatches(
Iterable<Diagnostic> diagnostics, String tag, Matcher<Diagnostic> matcher) {
int numberOfDiagnostics = 0;
for (Diagnostic diagnostic : diagnostics) {
if (matcher.matches(diagnostic)) {
return this;
}
numberOfDiagnostics++;
}
StringBuilder builder = new StringBuilder("No " + tag + " matches " + matcher.toString());
builder.append(System.lineSeparator());
if (numberOfDiagnostics == 0) {
builder.append("There were no " + tag + "s.");
} else {
builder.append("There were " + numberOfDiagnostics + " " + tag + "s:");
builder.append(System.lineSeparator());
for (Diagnostic diagnostic : diagnostics) {
builder.append(diagnostic.getDiagnosticMessage());
builder.append(System.lineSeparator());
}
}
fail(builder.toString());
return this;
}
private static void assertDiagnosticsMatch(
Iterable<Diagnostic> diagnostics, String tag, Collection<Matcher<Diagnostic>> matchers) {
assertThat(
diagnostics,
UnorderedCollectionMatcher.matchesOneToOne(matchers, Diagnostic::getDiagnosticMessage));
}
@Override
public TestDiagnosticMessages assertDiagnosticsMatch(Collection<Matcher<Diagnostic>> matchers) {
assertDiagnosticsMatch(getAllDiagnostics(), "diagnostics", matchers);
return this;
}
@Override
public TestDiagnosticMessages assertInfosMatch(Collection<Matcher<Diagnostic>> matchers) {
assertDiagnosticsMatch(getInfos(), "infos", matchers);
return this;
}
@Override
public TestDiagnosticMessages assertWarningsMatch(Collection<Matcher<Diagnostic>> matchers) {
assertDiagnosticsMatch(getWarnings(), "warnings", matchers);
return this;
}
@Override
public TestDiagnosticMessages assertErrorsMatch(Collection<Matcher<Diagnostic>> matchers) {
assertDiagnosticsMatch(getErrors(), "errors", matchers);
return this;
}
@Override
public TestDiagnosticMessages assertDiagnosticThatMatches(Matcher<Diagnostic> matcher) {
return assertDiagnosticThatMatches(getAllDiagnostics(), "diagnostic message", matcher);
}
private Iterable<Diagnostic> getAllDiagnostics() {
return Iterables.concat(getInfos(), getWarnings(), getErrors());
}
@Override
public TestDiagnosticMessages assertInfoThatMatches(Matcher<Diagnostic> matcher) {
return assertDiagnosticThatMatches(getInfos(), "info", matcher);
}
@Override
public TestDiagnosticMessages assertWarningThatMatches(Matcher<Diagnostic> matcher) {
return assertDiagnosticThatMatches(getWarnings(), "warning", matcher);
}
@Override
public TestDiagnosticMessages assertErrorThatMatches(Matcher<Diagnostic> matcher) {
return assertDiagnosticThatMatches(getErrors(), "error", matcher);
}
@Override
public TestDiagnosticMessages assertAllDiagnosticsMatch(Matcher<Diagnostic> matcher) {
return assertAllDiagnosticsMatches(getAllDiagnostics(), "diagnostic message", matcher);
}
@Override
public TestDiagnosticMessages assertAllInfosMatch(Matcher<Diagnostic> matcher) {
return assertAllDiagnosticsMatches(getInfos(), "info", matcher);
}
@Override
public TestDiagnosticMessages assertAllWarningsMatch(Matcher<Diagnostic> matcher) {
return assertAllDiagnosticsMatches(getWarnings(), "warning", matcher);
}
@Override
public TestDiagnosticMessages assertAllErrorsMatch(Matcher<Diagnostic> matcher) {
return assertAllDiagnosticsMatches(getErrors(), "error", matcher);
}
void setDiagnosticsLevelModifier(
BiFunction<DiagnosticsLevel, Diagnostic, DiagnosticsLevel> modifier) {
this.modifier = modifier;
}
}