| // Copyright (c) 2020, 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 com.android.tools.r8.utils.internal.ConsumerUtils.emptyThrowingConsumer; | |
| import static org.hamcrest.CoreMatchers.containsString; | |
| import static org.hamcrest.CoreMatchers.is; | |
| import static org.junit.Assert.assertNotNull; | |
| import com.android.tools.r8.TestRuntime.CfVm; | |
| import com.android.tools.r8.ToolHelper.DexVm; | |
| import com.android.tools.r8.debug.DebugTestConfig; | |
| import com.android.tools.r8.naming.retrace.StackTrace; | |
| import com.android.tools.r8.synthesis.SyntheticItemsTestUtils; | |
| import com.android.tools.r8.utils.AndroidApp; | |
| import com.android.tools.r8.utils.codeinspector.CodeInspector; | |
| import com.android.tools.r8.utils.internal.StringUtils; | |
| import com.android.tools.r8.utils.internal.ThrowingConsumer; | |
| import com.android.tools.r8.utils.internal.exceptions.Unreachable; | |
| import com.google.common.base.Predicates; | |
| import java.io.IOException; | |
| import java.io.PrintStream; | |
| import java.util.Arrays; | |
| import java.util.List; | |
| import java.util.concurrent.ExecutionException; | |
| import java.util.function.Function; | |
| import java.util.function.Predicate; | |
| import org.hamcrest.Matcher; | |
| /** | |
| * Abstract base for checking the result of executing (test) program(s). | |
| * | |
| * <p>All methods defined on this base must generalize to allow checking of multiple run results | |
| * simultaneously. For methods on single runs see the SingleTestRunResult subclass. | |
| */ | |
| public abstract class TestRunResult<RR extends TestRunResult<RR>> { | |
| private final TestState state; | |
| protected final AndroidApp app; | |
| protected final String proguardMap; | |
| protected TestRunResult() { | |
| this(null, null, null); | |
| } | |
| protected TestRunResult(AndroidApp app, String proguardMap, TestState state) { | |
| this.app = app; | |
| this.proguardMap = proguardMap; | |
| this.state = state; | |
| } | |
| abstract RR self(); | |
| public SingleTestRunResult asSingleRuntimeResult() { | |
| throw new Unreachable(); | |
| } | |
| public boolean isR8TestMultiRunResult() { | |
| return false; | |
| } | |
| public TestState getState() { | |
| return state; | |
| } | |
| public AndroidApp app() { | |
| return app; | |
| } | |
| public SyntheticItemsTestUtils getSyntheticItems() { | |
| return getState().getSyntheticItems(); | |
| } | |
| public abstract RR assertSuccess(); | |
| public abstract RR assertStdoutMatches(Matcher<String> matcher); | |
| public abstract RR assertStdoutLinesMatchesUnordered(Iterable<Matcher<String>> lines); | |
| public abstract RR assertFailure(); | |
| public abstract RR assertStderrMatches(Matcher<String> matcher); | |
| public <E extends Throwable> RR inspectStdOut(ThrowingConsumer<String, E> consumer) throws E { | |
| throw new Unreachable(); | |
| } | |
| protected CodeInspector internalGetCodeInspector() throws IOException { | |
| assertNotNull(app); | |
| return proguardMap == null ? new CodeInspector(app) : new CodeInspector(app, proguardMap); | |
| } | |
| public CodeInspector inspector() throws IOException { | |
| assertSuccess(); | |
| return internalGetCodeInspector(); | |
| } | |
| public <E extends Throwable> RR inspect(ThrowingConsumer<CodeInspector, E> consumer) | |
| throws IOException, ExecutionException, E { | |
| CodeInspector inspector = inspector(); | |
| consumer.accept(inspector); | |
| return self(); | |
| } | |
| public <E extends Throwable> RR inspectFailure(ThrowingConsumer<CodeInspector, E> consumer) | |
| throws IOException, E { | |
| assertFailure(); | |
| CodeInspector inspector = internalGetCodeInspector(); | |
| consumer.accept(inspector); | |
| return self(); | |
| } | |
| public <E extends Throwable> RR inspectStackTrace(ThrowingConsumer<StackTrace, E> consumer) | |
| throws E { | |
| throw new Unreachable(); | |
| } | |
| public <E extends Throwable> RR inspectOriginalStackTrace( | |
| ThrowingConsumer<StackTrace, E> consumer) throws E { | |
| throw new Unreachable(); | |
| } | |
| public RR disassemble(PrintStream ps) throws ExecutionException, IOException { | |
| ToolHelper.disassemble(app, ps); | |
| return self(); | |
| } | |
| public RR disassemble() throws IOException, ExecutionException { | |
| return disassemble(System.out); | |
| } | |
| @Override | |
| public String toString() { | |
| StringBuilder builder = new StringBuilder(); | |
| appendInfo(builder); | |
| return builder.toString(); | |
| } | |
| String errorMessage(String message) { | |
| return errorMessage(message, null); | |
| } | |
| String errorMessage(String message, String expected) { | |
| StringBuilder builder = new StringBuilder(message).append('\n'); | |
| if (expected != null) { | |
| if (expected.contains(System.lineSeparator())) { | |
| builder.append("EXPECTED:").append(System.lineSeparator()).append(expected); | |
| } else { | |
| builder.append("EXPECTED: ").append(expected); | |
| } | |
| builder.append(System.lineSeparator()); | |
| } | |
| appendInfo(builder); | |
| return builder.toString(); | |
| } | |
| protected void appendInfo(StringBuilder builder) { | |
| builder.append("APPLICATION: "); | |
| appendApplication(builder); | |
| builder.append('\n'); | |
| appendProcessResult(builder); | |
| } | |
| private void appendApplication(StringBuilder builder) { | |
| builder.append(app == null ? "<default>" : app.toString()); | |
| } | |
| void appendProcessResult(StringBuilder builder) { | |
| throw new Unreachable(); | |
| } | |
| public RR writeProcessResult(PrintStream ps) { | |
| throw new Unreachable(); | |
| } | |
| public <E extends Throwable> RR debugger(ThrowingConsumer<DebugTestConfig, E> consumer) | |
| throws E, IOException { | |
| throw new Unreachable(); | |
| } | |
| public <E extends Throwable> RR apply(ThrowingConsumer<? super RR, E> fn) throws E { | |
| fn.accept(self()); | |
| return self(); | |
| } | |
| public <T extends Throwable> RR applyIf(boolean condition, ThrowingConsumer<RR, T> thenConsumer) | |
| throws T { | |
| return applyIf(condition, thenConsumer, emptyThrowingConsumer()); | |
| } | |
| public <S extends Throwable, T extends Throwable> RR applyIf( | |
| boolean condition1, | |
| ThrowingConsumer<RR, S> thenConsumer1, | |
| ThrowingConsumer<RR, T> elseConsumer) | |
| throws S, T { | |
| boolean condition2 = false; | |
| ThrowingConsumer<RR, RuntimeException> thenConsumer2 = ThrowingConsumer.unreachable(); | |
| return applyIf(condition1, thenConsumer1, condition2, thenConsumer2, elseConsumer); | |
| } | |
| public <S extends Throwable, T extends Throwable, U extends Throwable> RR applyIf( | |
| boolean condition1, | |
| ThrowingConsumer<RR, S> thenConsumer1, | |
| boolean condition2, | |
| ThrowingConsumer<RR, T> thenConsumer2, | |
| ThrowingConsumer<RR, U> elseConsumer) | |
| throws S, T, U { | |
| boolean condition3 = false; | |
| ThrowingConsumer<RR, RuntimeException> thenConsumer3 = ThrowingConsumer.unreachable(); | |
| return applyIf( | |
| condition1, | |
| thenConsumer1, | |
| condition2, | |
| thenConsumer2, | |
| condition3, | |
| thenConsumer3, | |
| elseConsumer); | |
| } | |
| public <S extends Throwable, T extends Throwable, U extends Throwable, V extends Throwable> | |
| RR applyIf( | |
| boolean condition1, | |
| ThrowingConsumer<RR, S> thenConsumer1, | |
| boolean condition2, | |
| ThrowingConsumer<RR, T> thenConsumer2, | |
| boolean condition3, | |
| ThrowingConsumer<RR, U> thenConsumer3, | |
| ThrowingConsumer<RR, V> elseConsumer) | |
| throws S, T, U, V { | |
| boolean condition4 = false; | |
| ThrowingConsumer<RR, RuntimeException> thenConsumer4 = ThrowingConsumer.unreachable(); | |
| return applyIf( | |
| condition1, | |
| thenConsumer1, | |
| condition2, | |
| thenConsumer2, | |
| condition3, | |
| thenConsumer3, | |
| condition4, | |
| thenConsumer4, | |
| elseConsumer); | |
| } | |
| public < | |
| S extends Throwable, | |
| T extends Throwable, | |
| U extends Throwable, | |
| V extends Throwable, | |
| W extends Throwable> | |
| RR applyIf( | |
| boolean condition1, | |
| ThrowingConsumer<RR, S> thenConsumer1, | |
| boolean condition2, | |
| ThrowingConsumer<RR, T> thenConsumer2, | |
| boolean condition3, | |
| ThrowingConsumer<RR, U> thenConsumer3, | |
| boolean condition4, | |
| ThrowingConsumer<RR, W> thenConsumer4, | |
| ThrowingConsumer<RR, V> elseConsumer) | |
| throws S, T, U, V, W { | |
| if (condition1) { | |
| thenConsumer1.accept(self()); | |
| } else if (condition2) { | |
| thenConsumer2.accept(self()); | |
| } else if (condition3) { | |
| thenConsumer3.accept(self()); | |
| } else if (condition4) { | |
| thenConsumer4.accept(self()); | |
| } else { | |
| elseConsumer.accept(self()); | |
| } | |
| return self(); | |
| } | |
| public <T extends Throwable> RR applyIfCfRuntime( | |
| Predicate<CfVm> condition, ThrowingConsumer<? super SingleTestRunResult, T> thenConsumer) | |
| throws T { | |
| return applyIfCfRuntime(condition, thenConsumer, emptyThrowingConsumer()); | |
| } | |
| public <S extends Throwable, T extends Throwable> RR applyIfCfRuntime( | |
| Predicate<CfVm> condition1, | |
| ThrowingConsumer<? super SingleTestRunResult, S> thenConsumer1, | |
| ThrowingConsumer<? super SingleTestRunResult, T> elseConsumer) | |
| throws S, T { | |
| Predicate<CfVm> condition2 = Predicates.alwaysFalse(); | |
| ThrowingConsumer<SingleTestRunResult, RuntimeException> thenConsumer2 = | |
| ThrowingConsumer.unreachable(); | |
| return applyIfCfRuntime(condition1, thenConsumer1, condition2, thenConsumer2, elseConsumer); | |
| } | |
| public <S extends Throwable, T extends Throwable, U extends Throwable> RR applyIfCfRuntime( | |
| Predicate<CfVm> condition1, | |
| ThrowingConsumer<? super SingleTestRunResult, S> thenConsumer1, | |
| Predicate<CfVm> condition2, | |
| ThrowingConsumer<? super SingleTestRunResult, T> thenConsumer2, | |
| ThrowingConsumer<? super SingleTestRunResult, U> elseConsumer) | |
| throws S, T, U { | |
| Predicate<CfVm> condition3 = Predicates.alwaysFalse(); | |
| ThrowingConsumer<SingleTestRunResult, RuntimeException> thenConsumer3 = | |
| ThrowingConsumer.unreachable(); | |
| return applyIfCfRuntime( | |
| condition1, | |
| thenConsumer1, | |
| condition2, | |
| thenConsumer2, | |
| condition3, | |
| thenConsumer3, | |
| elseConsumer); | |
| } | |
| public <S extends Throwable, T extends Throwable, U extends Throwable, V extends Throwable> | |
| RR applyIfCfRuntime( | |
| Predicate<CfVm> condition1, | |
| ThrowingConsumer<? super SingleTestRunResult, S> thenConsumer1, | |
| Predicate<CfVm> condition2, | |
| ThrowingConsumer<? super SingleTestRunResult, T> thenConsumer2, | |
| Predicate<CfVm> condition3, | |
| ThrowingConsumer<? super SingleTestRunResult, U> thenConsumer3, | |
| ThrowingConsumer<? super SingleTestRunResult, V> elseConsumer) | |
| throws S, T, U, V { | |
| Predicate<CfVm> condition4 = Predicates.alwaysFalse(); | |
| ThrowingConsumer<SingleTestRunResult, RuntimeException> thenConsumer4 = | |
| ThrowingConsumer.unreachable(); | |
| return applyIfCfRuntime( | |
| condition1, | |
| thenConsumer1, | |
| condition2, | |
| thenConsumer2, | |
| condition3, | |
| thenConsumer3, | |
| condition4, | |
| thenConsumer4, | |
| elseConsumer); | |
| } | |
| public < | |
| S extends Throwable, | |
| T extends Throwable, | |
| U extends Throwable, | |
| V extends Throwable, | |
| W extends Throwable> | |
| RR applyIfCfRuntime( | |
| Predicate<CfVm> condition1, | |
| ThrowingConsumer<? super SingleTestRunResult, S> thenConsumer1, | |
| Predicate<CfVm> condition2, | |
| ThrowingConsumer<? super SingleTestRunResult, T> thenConsumer2, | |
| Predicate<CfVm> condition3, | |
| ThrowingConsumer<? super SingleTestRunResult, U> thenConsumer3, | |
| Predicate<CfVm> condition4, | |
| ThrowingConsumer<? super SingleTestRunResult, W> thenConsumer4, | |
| ThrowingConsumer<? super SingleTestRunResult, V> elseConsumer) | |
| throws S, T, U, V, W { | |
| throw new Unreachable(); | |
| } | |
| public <S extends Throwable, T extends Throwable, U extends Throwable> RR applyIfCfRuntime( | |
| boolean condition1, | |
| ThrowingConsumer<RR, S> thenConsumer1, | |
| Predicate<CfVm> condition2, | |
| ThrowingConsumer<? super SingleTestRunResult, T> thenConsumer2, | |
| ThrowingConsumer<? super SingleTestRunResult, U> elseConsumer) | |
| throws S, T, U { | |
| Predicate<CfVm> condition3 = Predicates.alwaysFalse(); | |
| ThrowingConsumer<SingleTestRunResult, RuntimeException> thenConsumer3 = | |
| ThrowingConsumer.unreachable(); | |
| return applyIfCfRuntime( | |
| condition1, | |
| thenConsumer1, | |
| condition2, | |
| thenConsumer2, | |
| condition3, | |
| thenConsumer3, | |
| elseConsumer); | |
| } | |
| public <S extends Throwable, T extends Throwable, U extends Throwable, V extends Throwable> | |
| RR applyIfCfRuntime( | |
| boolean condition1, | |
| ThrowingConsumer<RR, S> thenConsumer1, | |
| Predicate<CfVm> condition2, | |
| ThrowingConsumer<? super SingleTestRunResult, T> thenConsumer2, | |
| Predicate<CfVm> condition3, | |
| ThrowingConsumer<? super SingleTestRunResult, U> thenConsumer3, | |
| ThrowingConsumer<? super SingleTestRunResult, V> elseConsumer) | |
| throws S, T, U, V { | |
| Predicate<CfVm> condition4 = Predicates.alwaysFalse(); | |
| ThrowingConsumer<SingleTestRunResult, RuntimeException> thenConsumer4 = | |
| ThrowingConsumer.unreachable(); | |
| return applyIfCfRuntime( | |
| condition1, | |
| thenConsumer1, | |
| condition2, | |
| thenConsumer2, | |
| condition3, | |
| thenConsumer3, | |
| condition4, | |
| thenConsumer4, | |
| elseConsumer); | |
| } | |
| public < | |
| S extends Throwable, | |
| T extends Throwable, | |
| U extends Throwable, | |
| V extends Throwable, | |
| W extends Throwable> | |
| RR applyIfCfRuntime( | |
| boolean condition1, | |
| ThrowingConsumer<RR, S> thenConsumer1, | |
| Predicate<CfVm> condition2, | |
| ThrowingConsumer<? super SingleTestRunResult, T> thenConsumer2, | |
| Predicate<CfVm> condition3, | |
| ThrowingConsumer<? super SingleTestRunResult, U> thenConsumer3, | |
| Predicate<CfVm> condition4, | |
| ThrowingConsumer<? super SingleTestRunResult, W> thenConsumer4, | |
| ThrowingConsumer<? super SingleTestRunResult, V> elseConsumer) | |
| throws S, T, U, V, W { | |
| if (condition1) { | |
| thenConsumer1.accept(self()); | |
| return self(); | |
| } | |
| return applyIfCfRuntime( | |
| condition2, | |
| thenConsumer2, | |
| condition3, | |
| thenConsumer3, | |
| condition4, | |
| thenConsumer4, | |
| elseConsumer); | |
| } | |
| public <T extends Throwable> RR applyIfDexRuntime( | |
| Predicate<DexVm.Version> condition, | |
| ThrowingConsumer<? super SingleTestRunResult, T> thenConsumer) | |
| throws T { | |
| return applyIfDexRuntime(condition, thenConsumer, emptyThrowingConsumer()); | |
| } | |
| public <S extends Throwable, T extends Throwable> RR applyIfDexRuntime( | |
| Predicate<DexVm.Version> condition1, | |
| ThrowingConsumer<? super SingleTestRunResult, S> thenConsumer1, | |
| ThrowingConsumer<? super SingleTestRunResult, T> elseConsumer) | |
| throws S, T { | |
| Predicate<DexVm.Version> condition2 = Predicates.alwaysFalse(); | |
| ThrowingConsumer<SingleTestRunResult, RuntimeException> thenConsumer2 = | |
| ThrowingConsumer.unreachable(); | |
| return applyIfDexRuntime(condition1, thenConsumer1, condition2, thenConsumer2, elseConsumer); | |
| } | |
| public <S extends Throwable, T extends Throwable, U extends Throwable> RR applyIfDexRuntime( | |
| Predicate<DexVm.Version> condition1, | |
| ThrowingConsumer<? super SingleTestRunResult, S> thenConsumer1, | |
| Predicate<DexVm.Version> condition2, | |
| ThrowingConsumer<? super SingleTestRunResult, T> thenConsumer2, | |
| ThrowingConsumer<? super SingleTestRunResult, U> elseConsumer) | |
| throws S, T, U { | |
| Predicate<DexVm.Version> condition3 = Predicates.alwaysFalse(); | |
| ThrowingConsumer<SingleTestRunResult, RuntimeException> thenConsumer3 = | |
| ThrowingConsumer.unreachable(); | |
| return applyIfDexRuntime( | |
| condition1, | |
| thenConsumer1, | |
| condition2, | |
| thenConsumer2, | |
| condition3, | |
| thenConsumer3, | |
| elseConsumer); | |
| } | |
| public <S extends Throwable, T extends Throwable, U extends Throwable, V extends Throwable> | |
| RR applyIfDexRuntime( | |
| Predicate<DexVm.Version> condition1, | |
| ThrowingConsumer<? super SingleTestRunResult, S> thenConsumer1, | |
| Predicate<DexVm.Version> condition2, | |
| ThrowingConsumer<? super SingleTestRunResult, T> thenConsumer2, | |
| Predicate<DexVm.Version> condition3, | |
| ThrowingConsumer<? super SingleTestRunResult, U> thenConsumer3, | |
| ThrowingConsumer<? super SingleTestRunResult, V> elseConsumer) | |
| throws S, T, U, V { | |
| Predicate<DexVm.Version> condition4 = Predicates.alwaysFalse(); | |
| ThrowingConsumer<SingleTestRunResult, RuntimeException> thenConsumer4 = | |
| ThrowingConsumer.unreachable(); | |
| return applyIfDexRuntime( | |
| condition1, | |
| thenConsumer1, | |
| condition2, | |
| thenConsumer2, | |
| condition3, | |
| thenConsumer3, | |
| condition4, | |
| thenConsumer4, | |
| elseConsumer); | |
| } | |
| public < | |
| S extends Throwable, | |
| T extends Throwable, | |
| U extends Throwable, | |
| V extends Throwable, | |
| W extends Throwable> | |
| RR applyIfDexRuntime( | |
| Predicate<DexVm.Version> condition1, | |
| ThrowingConsumer<? super SingleTestRunResult, S> thenConsumer1, | |
| Predicate<DexVm.Version> condition2, | |
| ThrowingConsumer<? super SingleTestRunResult, T> thenConsumer2, | |
| Predicate<DexVm.Version> condition3, | |
| ThrowingConsumer<? super SingleTestRunResult, U> thenConsumer3, | |
| Predicate<DexVm.Version> condition4, | |
| ThrowingConsumer<? super SingleTestRunResult, W> thenConsumer4, | |
| ThrowingConsumer<? super SingleTestRunResult, V> elseConsumer) | |
| throws S, T, U, V, W { | |
| throw new Unreachable(); | |
| } | |
| public <S extends Throwable, T extends Throwable, U extends Throwable> RR applyIfDexRuntime( | |
| boolean condition1, | |
| ThrowingConsumer<RR, S> thenConsumer1, | |
| Predicate<DexVm.Version> condition2, | |
| ThrowingConsumer<? super SingleTestRunResult, T> thenConsumer2, | |
| ThrowingConsumer<? super SingleTestRunResult, U> elseConsumer) | |
| throws S, T, U { | |
| Predicate<DexVm.Version> condition3 = Predicates.alwaysFalse(); | |
| ThrowingConsumer<SingleTestRunResult, RuntimeException> thenConsumer3 = | |
| ThrowingConsumer.unreachable(); | |
| return applyIfDexRuntime( | |
| condition1, | |
| thenConsumer1, | |
| condition2, | |
| thenConsumer2, | |
| condition3, | |
| thenConsumer3, | |
| elseConsumer); | |
| } | |
| public <S extends Throwable, T extends Throwable, U extends Throwable, V extends Throwable> | |
| RR applyIfDexRuntime( | |
| boolean condition1, | |
| ThrowingConsumer<RR, S> thenConsumer1, | |
| Predicate<DexVm.Version> condition2, | |
| ThrowingConsumer<? super SingleTestRunResult, T> thenConsumer2, | |
| Predicate<DexVm.Version> condition3, | |
| ThrowingConsumer<? super SingleTestRunResult, U> thenConsumer3, | |
| ThrowingConsumer<? super SingleTestRunResult, V> elseConsumer) | |
| throws S, T, U, V { | |
| Predicate<DexVm.Version> condition4 = Predicates.alwaysFalse(); | |
| ThrowingConsumer<SingleTestRunResult, RuntimeException> thenConsumer4 = | |
| ThrowingConsumer.unreachable(); | |
| return applyIfDexRuntime( | |
| condition1, | |
| thenConsumer1, | |
| condition2, | |
| thenConsumer2, | |
| condition3, | |
| thenConsumer3, | |
| condition4, | |
| thenConsumer4, | |
| elseConsumer); | |
| } | |
| public < | |
| S extends Throwable, | |
| T extends Throwable, | |
| U extends Throwable, | |
| V extends Throwable, | |
| W extends Throwable> | |
| RR applyIfDexRuntime( | |
| boolean condition1, | |
| ThrowingConsumer<RR, S> thenConsumer1, | |
| Predicate<DexVm.Version> condition2, | |
| ThrowingConsumer<? super SingleTestRunResult, T> thenConsumer2, | |
| Predicate<DexVm.Version> condition3, | |
| ThrowingConsumer<? super SingleTestRunResult, U> thenConsumer3, | |
| Predicate<DexVm.Version> condition4, | |
| ThrowingConsumer<? super SingleTestRunResult, W> thenConsumer4, | |
| ThrowingConsumer<? super SingleTestRunResult, V> elseConsumer) | |
| throws S, T, U, V, W { | |
| if (condition1) { | |
| thenConsumer1.accept(self()); | |
| return self(); | |
| } | |
| return applyIfDexRuntime( | |
| condition2, | |
| thenConsumer2, | |
| condition3, | |
| thenConsumer3, | |
| condition4, | |
| thenConsumer4, | |
| elseConsumer); | |
| } | |
| public <S> S map(Function<RR, S> fn) { | |
| return fn.apply(self()); | |
| } | |
| public RR assertSuccessWithOutputThatMatches(Matcher<String> matcher) { | |
| assertStdoutMatches(matcher); | |
| return assertSuccess(); | |
| } | |
| public RR assertSuccessWithOutput(String expected) { | |
| return assertSuccessWithOutputThatMatches(is(expected)); | |
| } | |
| public RR assertSuccessWithOutputIf(boolean condition, String expected) { | |
| if (condition) { | |
| return assertSuccessWithOutput(expected); | |
| } | |
| return self(); | |
| } | |
| public RR assertSuccessWithEmptyOutput() { | |
| return assertSuccessWithOutput(""); | |
| } | |
| public RR assertSuccessWithOutputLines(String... expected) { | |
| return assertSuccessWithOutputLines(Arrays.asList(expected)); | |
| } | |
| public RR assertSuccessWithOutputLinesIf(boolean condition, String... expected) { | |
| return assertSuccessWithOutputLinesIf(condition, Arrays.asList(expected)); | |
| } | |
| public RR assertSuccessWithOutputLinesIf(boolean condition, List<String> expected) { | |
| if (condition) { | |
| return assertSuccessWithOutputLines(expected); | |
| } | |
| return self(); | |
| } | |
| public RR assertSuccessWithOutputLines(List<String> expected) { | |
| return assertSuccessWithOutput(StringUtils.lines(expected)); | |
| } | |
| public RR assertFailureWithErrorThatMatches(Matcher<String> matcher) { | |
| assertStderrMatches(matcher); | |
| return assertFailure(); | |
| } | |
| public RR assertFailureWithErrorThatMatchesIf(boolean condition, Matcher<String> matcher) { | |
| if (condition) { | |
| assertStderrMatches(matcher); | |
| return assertFailure(); | |
| } | |
| return self(); | |
| } | |
| public RR assertFailureWithOutput(String expected) { | |
| assertStdoutMatches(is(expected)); | |
| return assertFailure(); | |
| } | |
| public RR assertFailureWithOutputThatMatches(Matcher<String> matcher) { | |
| assertStdoutMatches(matcher); | |
| return assertFailure(); | |
| } | |
| public RR assertFailureWithErrorThatThrows(Class<? extends Throwable> expectedError) { | |
| return assertFailureWithErrorThatMatches(containsString(expectedError.getName())); | |
| } | |
| public RR assertFailureWithErrorThatThrowsIf( | |
| boolean condition, Class<? extends Throwable> expectedError) { | |
| if (condition) { | |
| return assertFailureWithErrorThatThrows(expectedError); | |
| } | |
| return self(); | |
| } | |
| } |