// Copyright © 2011-2013, 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.results; import fi.jumi.api.drivers.TestId; import fi.jumi.core.api.*; import fi.jumi.core.events.SuiteListenerEventizer; import fi.jumi.core.util.*; import org.junit.*; import org.junit.rules.ExpectedException; import java.lang.reflect.Method; import java.util.*; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; import static org.mockito.Mockito.*; public class SuiteEventDemuxerTest { private static final TestFile TEST_FILE_1 = TestFile.fromClassName("Test1"); private static final TestFile TEST_FILE_2 = TestFile.fromClassName("Test2"); @Rule public final ExpectedException thrown = ExpectedException.none(); private final SuiteEventDemuxer demuxer = new SuiteEventDemuxer(); private final SuiteListener toDemuxer = new SuiteListenerEventizer().newFrontend(demuxer); @Test public void allows_runs_to_be_visited_individually() { toDemuxer.onRunStarted(new RunId(1), TEST_FILE_1); toDemuxer.onRunStarted(new RunId(2), TEST_FILE_2); RunVisitor visitor = mock(RunVisitor.class); demuxer.visitRun(new RunId(1), visitor); verify(visitor).onRunStarted(new RunId(1), TEST_FILE_1); verifyNoMoreInteractions(visitor); } @Test public void allows_all_runs_to_be_visited() { toDemuxer.onRunStarted(new RunId(1), TEST_FILE_1); toDemuxer.onRunStarted(new RunId(2), TEST_FILE_2); RunVisitor visitor = mock(RunVisitor.class); demuxer.visitAllRuns(visitor); verify(visitor).onRunStarted(new RunId(1), TEST_FILE_1); verify(visitor).onRunStarted(new RunId(2), TEST_FILE_2); verifyNoMoreInteractions(visitor); } @Test public void collects_all_types_of_run_events() { RunId runId = new RunId(1); TestId testId = TestId.of(1); TestFile testFile = TEST_FILE_1; toDemuxer.onRunStarted(runId, testFile); toDemuxer.onTestStarted(runId, testId); toDemuxer.onFailure(runId, StackTrace.from(new Throwable("dummy"))); toDemuxer.onPrintedOut(runId, "to out"); toDemuxer.onPrintedErr(runId, "to err"); toDemuxer.onTestFinished(runId); toDemuxer.onRunFinished(runId); SpyListener<RunVisitor> spy = new SpyListener<>(RunVisitor.class); RunVisitor expect = spy.getListener(); expect.onRunStarted(runId, testFile); expect.onTestStarted(runId, testFile, testId); expect.onFailure(runId, testFile, testId, StackTrace.from(new Throwable("dummy"))); expect.onPrintedOut(runId, testFile, testId, "to out"); expect.onPrintedErr(runId, testFile, testId, "to err"); expect.onTestFinished(runId, testFile, testId); expect.onRunFinished(runId, testFile); checkExpectations(spy, runId); checkNoRunEventTypesWereMissedByThisTest(runId); } private void checkExpectations(SpyListener<RunVisitor> spy, RunId runId) { spy.replay(); demuxer.visitRun(runId, spy.getListener()); spy.verify(); } private void checkNoRunEventTypesWereMissedByThisTest(RunId runId) { MethodCallSpy spy = new MethodCallSpy(); demuxer.visitRun(runId, spy.createProxyTo(RunVisitor.class)); SortedSet<String> testedEvents = new TreeSet<>(spy.getMethodCalls()); assertThat("this test should check all run event types, but did not", testedEvents, is(getMethods(RunVisitor.class))); } private static SortedSet<String> getMethods(Class<?> type) { SortedSet<String> names = new TreeSet<>(); for (Method method : type.getMethods()) { names.add(method.getName()); } return names; } @Test public void supports_printing_after_the_run_is_finished() { RunId runId = new RunId(1); toDemuxer.onRunStarted(runId, TEST_FILE_1); toDemuxer.onTestStarted(runId, TestId.ROOT); toDemuxer.onTestFinished(runId); toDemuxer.onRunFinished(runId); toDemuxer.onPrintedOut(runId, "to out"); toDemuxer.onPrintedErr(runId, "to err"); RunVisitor visitor = mock(RunVisitor.class); demuxer.visitRun(runId, visitor); verify(visitor).onPrintedOut(runId, TEST_FILE_1, null, "to out"); verify(visitor).onPrintedErr(runId, TEST_FILE_1, null, "to err"); } @Test public void tells_when_the_suite_is_finished() { assertThat("before finished", demuxer.isSuiteFinished(), is(false)); toDemuxer.onSuiteFinished(); assertThat("after finished", demuxer.isSuiteFinished(), is(true)); } @Test public void tells_the_names_of_the_tests() { // name found toDemuxer.onTestFound(TEST_FILE_1, TestId.ROOT, "test name"); assertThat(demuxer.getTestName(TEST_FILE_1, TestId.ROOT), is("test name")); // name not found thrown.expect(IllegalArgumentException.class); thrown.expectMessage("name not found for Test1 and TestId(0)"); demuxer.getTestName(TEST_FILE_1, TestId.of(0)); } // TODO: these tests don't fire the onSuiteStarted event; is that a problem? for now the class is quite lenient }