/******************************************************************************* * Copyright Technophobia Ltd 2012 * * This file is part of the Substeps Eclipse Plugin. * * The Substeps Eclipse Plugin is free software: you can redistribute it and/or modify * it under the terms of the Eclipse Public License v1.0. * * The Substeps Eclipse Plugin is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * Eclipse Public License for more details. * * You should have received a copy of the Eclipse Public License * along with the Substeps Eclipse Plugin. If not, see <http://www.eclipse.org/legal/epl-v10.html>. ******************************************************************************/ package com.technophobia.substeps.junit.ui; import java.text.MessageFormat; import java.text.NumberFormat; import com.technophobia.eclipse.transformer.Callback; import com.technophobia.eclipse.ui.Notifier; import com.technophobia.eclipse.ui.Resettable; import com.technophobia.eclipse.ui.UiUpdater; import com.technophobia.substeps.junit.ui.component.FeatureViewer; import com.technophobia.substeps.junit.ui.job.UpdateJobManager; import com.technophobia.substeps.junit.ui.testsession.TestResultsView; import com.technophobia.substeps.model.SubstepsSessionListener; import com.technophobia.substeps.model.structure.Status; import com.technophobia.substeps.model.structure.SubstepsTestElement; import com.technophobia.substeps.model.structure.SubstepsTestLeafElement; import com.technophobia.substeps.supplier.Supplier; public class TestSessionListener implements SubstepsSessionListener { private final FeatureViewer testViewer; private final Notifier<Boolean> showOnErrorOnlyNotifier; private final UpdateJobManager updateJobManager; private final SubstepsActionManager actionManager; private final Notifier<String> infoMessageNotifier; private final SubstepsRunSessionManager sessionManager; private final Notifier<Runnable> postSyncNotifier; private final UiUpdater substepsFeatureUiUpdater; private final Supplier<Boolean> disposedChecker; private final Callback contentChangeCallback; private final Resettable viewIconResetter; private final Notifier<Boolean> autoScrollNotifier; private final TestResultsView testResultsView; private final FailureTrace failureTrace; private final DirtyListener dirtyListener; private final Supplier<TestRunStats> testRunStatsSupplier; public TestSessionListener(final FeatureViewer testViewer, final Notifier<Runnable> postSyncNotifier, final Notifier<String> infoMessageNotifier, final UiUpdater substepsFeatureUiUpdater, final Notifier<Boolean> showOnErrorOnlyNotifier, final UpdateJobManager updateJobManager, final SubstepsActionManager actionManager, final SubstepsRunSessionManager sessionManager, final Supplier<TestRunStats> testRunStatsSupplier, final Supplier<Boolean> disposedChecker, final Notifier<Boolean> autoScrollNotifier, final Callback contentChangeCallback, final Resettable viewIconResetter, final TestResultsView testResultsView, final FailureTrace failureTrace, final DirtyListener dirtyListener) { this.testViewer = testViewer; this.postSyncNotifier = postSyncNotifier; this.infoMessageNotifier = infoMessageNotifier; this.substepsFeatureUiUpdater = substepsFeatureUiUpdater; this.showOnErrorOnlyNotifier = showOnErrorOnlyNotifier; this.updateJobManager = updateJobManager; this.actionManager = actionManager; this.sessionManager = sessionManager; this.testRunStatsSupplier = testRunStatsSupplier; this.disposedChecker = disposedChecker; this.autoScrollNotifier = autoScrollNotifier; this.contentChangeCallback = contentChangeCallback; this.viewIconResetter = viewIconResetter; this.testResultsView = testResultsView; this.failureTrace = failureTrace; this.dirtyListener = dirtyListener; } @Override public void sessionStarted() { testViewer.registerViewersRefresh(); updateJobManager.startUpdateJobs(); actionManager.setStopActionEnabled(true); actionManager.setRerunLastTestActionEnabled(true); } @Override public void sessionEnded(final long elapsedTime) { sessionManager.deregisterTestSessionListener(false); testViewer.registerAutoScrollTarget(null); final Object[] keys = { elapsedTimeAsString(elapsedTime) }; final String msg = MessageFormat.format( SubstepsFeatureMessages.SubstepsFeatureTestRunnerViewPart_message_finish, keys); infoMessageNotifier.notify(msg); postSyncNotifier.notify(new Runnable() { @Override public void run() { if (disposedChecker.get().booleanValue()) return; actionManager.setStopActionEnabled(sessionManager.get().isKeptAlive()); sessionManager.updateRerunFailedFirstAction(); substepsFeatureUiUpdater.doUpdate(); if (testRunStatsSupplier.get().hasErrorsOrFailures()) { testViewer.selectFirstFailure(); } dirtyListener.addNewDirtyListener(); contentChangeCallback.callback(); } }); updateJobManager.stopUpdateJobs(); } @Override public void sessionStopped(final long elapsedTime) { sessionManager.deregisterTestSessionListener(false); testViewer.registerAutoScrollTarget(null); infoMessageNotifier.notify(SubstepsFeatureMessages.SubstepsFeatureTestRunnerViewPart_message_stopped); handleStopped(); } @Override public void sessionTerminated() { sessionManager.deregisterTestSessionListener(true); testViewer.registerAutoScrollTarget(null); infoMessageNotifier.notify(SubstepsFeatureMessages.SubstepsFeatureTestRunnerViewPart_message_terminated); handleStopped(); } @Override public void runningBegins() { if (!showOnErrorOnlyNotifier.currentValue().booleanValue()) { postShowTestResultsView(); } } @Override public void testStarted(final SubstepsTestLeafElement testCaseElement) { testViewer.registerAutoScrollTarget(testCaseElement); testViewer.registerViewerUpdate(testCaseElement); final String className = testCaseElement.getClassName(); final String method = testCaseElement.getTestMethodName(); final String status = MessageFormat.format( SubstepsFeatureMessages.SubstepsFeatureTestRunnerViewPart_message_started, new Object[] { className, method }); infoMessageNotifier.notify(status); } @Override public void testFailed(final SubstepsTestElement testElement, final Status status, final String trace, final String expected, final String actual) { if (autoScrollNotifier.currentValue().booleanValue()) { testViewer.registerFailedForAutoScroll(testElement); } testViewer.registerViewerUpdate(testElement); // show the view on the first error only if (showOnErrorOnlyNotifier.currentValue().booleanValue() && (testRunStatsSupplier.get().getErrorCount() + testRunStatsSupplier.get().getFailureCount() == 1)) postShowTestResultsView(); // TODO: // [Bug 35590] JUnit window doesn't report errors from // junit.extensions.TestSetup [JUnit] // when a failure occurs in test setup then no test is running // to update the views we artificially signal the end of a test run // if (!fTestIsRunning) { // fTestIsRunning= false; // testEnded(testCaseElement); // } } @Override public void testEnded(final SubstepsTestLeafElement testCaseElement) { testViewer.registerViewerUpdate(testCaseElement); } @Override public void testReran(final SubstepsTestLeafElement testCaseElement, final Status status, final String trace, final String expectedResult, final String actualResult) { testViewer.registerViewerUpdate(testCaseElement); // TODO: autoExpand? postSyncNotifier.notify(new Runnable() { @Override public void run() { substepsFeatureUiUpdater.doUpdate(); } }); showFailure(testCaseElement); } @Override public void sessionLaunched(final SubstepsRunSession substepsRunSession) { // TODO Auto-generated method stub } private void showFailure(final SubstepsTestLeafElement testCaseElement) { postSyncNotifier.notify(new Runnable() { @Override public void run() { if (!disposedChecker.get().booleanValue()) failureTrace.showFailure(testCaseElement); } }); } @Override public void testAdded(final SubstepsTestElement testElement) { testViewer.registerTestAdded(testElement); } @Override public boolean acceptsSwapToDisk() { return false; } private String elapsedTimeAsString(final long runTime) { return NumberFormat.getInstance().format((double) runTime / 1000); } private void handleStopped() { postSyncNotifier.notify(new Runnable() { @Override public void run() { if (disposedChecker.get().booleanValue()) return; viewIconResetter.reset(); actionManager.setStopActionEnabled(false); sessionManager.updateRerunFailedFirstAction(); } }); updateJobManager.stopUpdateJobs(); } private void postShowTestResultsView() { postSyncNotifier.notify(new Runnable() { @Override public void run() { if (!disposedChecker.get().booleanValue()) { testResultsView.showTestResultsView(); } } }); } }