// Copyright © 2011-2014, Esko Luontola <www.orfjackal.net>
// This software is released under the Apache License 2.0.
// The license text is at http://www.apache.org/licenses/LICENSE-2.0
package fi.jumi.core.suite;
import fi.jumi.actors.SingleThreadedActors;
import fi.jumi.actors.eventizers.dynamic.DynamicEventizerProvider;
import fi.jumi.actors.listeners.*;
import fi.jumi.core.api.*;
import org.apache.commons.io.output.NullOutputStream;
import org.junit.Test;
import java.io.*;
import java.util.concurrent.Executor;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.mockito.Matchers.eq;
import static org.mockito.Matchers.notNull;
import static org.mockito.Mockito.*;
public class InternalErrorReportingExecutorTest {
private final SuiteListener suiteListener = mock(SuiteListener.class);
private final ByteArrayOutputStream standardOutput = new ByteArrayOutputStream();
private final SingleThreadedActors backingExecutor = new SingleThreadedActors(new DynamicEventizerProvider(), new CrashEarlyFailureHandler(), new NullMessageListener());
private final InternalErrorReportingExecutor executor =
new InternalErrorReportingExecutor(backingExecutor.getExecutor(), suiteListener, new PrintStream(standardOutput));
@Test
public void reports_internal_errors() {
executor.execute(() -> {
throw new RuntimeException("the-exception-message");
});
backingExecutor.processEventsUntilIdle();
String expected = String.format("Uncaught exception in thread %s", Thread.currentThread().getName());
verify(suiteListener).onInternalError(eq(expected), notNull(StackTrace.class));
}
@Test
public void prints_internal_errors_to_standard_output() {
executor.execute(() -> {
throw new RuntimeException("the-exception-message");
});
backingExecutor.processEventsUntilIdle();
String output = standardOutput.toString();
assertThat(output, containsString("Uncaught exception in thread"));
assertThat(output, containsString("java.lang.RuntimeException: the-exception-message"));
}
@Test
public void the_toString_of_the_original_commands_should_not_be_hidden() {
SpyExecutor backingExecutor = new SpyExecutor();
InternalErrorReportingExecutor executor = new InternalErrorReportingExecutor(backingExecutor, suiteListener, new PrintStream(new NullOutputStream()));
Runnable originalCommand = () -> {
};
executor.execute(originalCommand);
assertThat(backingExecutor.lastCommand.toString(), containsString(originalCommand.toString()));
}
private static class SpyExecutor implements Executor {
public Runnable lastCommand;
@Override
public void execute(Runnable command) {
lastCommand = command;
}
}
// TODO: should we have special handling of InterruptedException and ThreadDeath?
}