/******************************************************************************* * Copyright (c) 2017 Rogue Wave Software Inc. and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Rogue Wave Software Inc. - initial implementation *******************************************************************************/ package org.eclipse.php.phpunit.model.connection; import java.util.ArrayList; import java.util.Map; import org.eclipse.debug.core.model.IDebugTarget; import org.eclipse.php.internal.debug.core.zend.debugger.RemoteDebugger; import org.eclipse.php.internal.debug.core.zend.model.PHPDebugTarget; import org.eclipse.php.phpunit.model.elements.*; import org.eclipse.php.phpunit.ui.view.TestViewer; public class PHPUnitMessageParser { public static final String CALL_DYNAMIC = "->"; //$NON-NLS-1$ public static final String CALL_STATIC = "::"; //$NON-NLS-1$ private static final String ELEMENT_EVENT = "event"; //$NON-NLS-1$ private static final String ELEMENT_EXCEPTION = "exception"; //$NON-NLS-1$ private static final String ELEMENT_TARGET_TESTSUITE = "testsuite"; //$NON-NLS-1$ private static final String ELEMENT_TARGET_TESTCASE = "testcase"; //$NON-NLS-1$ private static final String ELEMENT_TEST = "test"; //$NON-NLS-1$ private static final String ELEMENT_WARNINGS = "warnings"; //$NON-NLS-1$ public static final String PROPERTY_CLASS = "class"; //$NON-NLS-1$ public static final String PROPERTY_CODE = "code"; //$NON-NLS-1$ public static final String PROPERTY_COUNT = "tests"; //$NON-NLS-1$ public static final String PROPERTY_FILE = "file"; //$NON-NLS-1$ public static final String PROPERTY_FILTERED = "filtered"; //$NON-NLS-1$ public static final String PROPERTY_LINE = "line"; //$NON-NLS-1$ public static final String PROPERTY_MESSAGE = "message"; //$NON-NLS-1$ public static final String PROPERTY_DIFF = "diff"; //$NON-NLS-1$ public static final String PROPERTY_NAME = "name"; //$NON-NLS-1$ private static final String PROPERTY_TARGET = "target"; //$NON-NLS-1$ public static final String PROPERTY_TRACE = "trace"; //$NON-NLS-1$ public static final String STATUS_ERROR = "error"; //$NON-NLS-1$ public static final String STATUS_FAIL = "fail"; //$NON-NLS-1$ public static final String STATUS_INCOMPLETE = "incomplete"; //$NON-NLS-1$ public static final String STATUS_PASS = "pass"; //$NON-NLS-1$ public static final String STATUS_SKIP = "skip"; //$NON-NLS-1$ public static final String TAG_END = "end"; //$NON-NLS-1$ public static final String TAG_START = "start"; //$NON-NLS-1$ private static PHPUnitMessageParser instance; /** * @return Singleton */ public static PHPUnitMessageParser getInstance() { if (instance == null) instance = new PHPUnitMessageParser(); return instance; } private RemoteDebugger remoteDebugger; private PHPUnitTestGroup currentGroup; private PHPUnitTestCase currentTestCase; private boolean inProgress = false; private PHPUnitMessageParser() { } public void parseMessage(final Map<?, ?> message, final TestViewer viewer) { if (!isInProgress()) { setInProgress(true); } if (message == null) { return; } final String target = (String) message.get(PROPERTY_TARGET); final String event = (String) message.get(ELEMENT_EVENT); final Map<?, ?> mTest = (Map<?, ?>) message.get(ELEMENT_TEST); if (target.equals(ELEMENT_TARGET_TESTSUITE)) { parseGroupStart(viewer, event, mTest); if (event.equals(TAG_END)) { parseGroupEnd(viewer); } } else if (target.equals(ELEMENT_TARGET_TESTCASE)) { if (event.equals(TAG_START)) { parseTestStart(viewer, event, mTest); } else { parseTestEnd(message, viewer, event, mTest); } } } private void parseGroupStart(final TestViewer viewer, final String event, final Map<?, ?> mTest) { if (!event.equals(TAG_START)) { return; } final PHPUnitTestGroup group = new PHPUnitTestGroup(mTest, currentGroup, remoteDebugger); mapTest(group); if (currentGroup.getTotalCount() > 0) { currentGroup.addChild(group, false); viewer.registerViewerUpdate(currentGroup); viewer.registerTestAdded(); group.setParent(currentGroup); } currentGroup = group; currentTestCase = null; if (currentGroup.getTotalCount() > 0 && PHPUnitElementManager.getInstance().getRoot().getTotalCount() == 0) { PHPUnitElementManager.getInstance().setRoot(currentGroup); viewer.registerTestAdded(); } } private void parseTestStart(final TestViewer viewer, final String event, final Map<?, ?> mTest) { final PHPUnitTestCase testCase = new PHPUnitTestCase(mTest, currentGroup, event, remoteDebugger); currentTestCase = testCase; mapTest(testCase); currentGroup.addChild(testCase, false); viewer.registerTestAdded(); } private void parseTestEnd(final Map message, final TestViewer viewer, final String event, final Map mTest) { final PHPUnitTestCase testCase = currentTestCase; testCase.updateStatus(event); final Map exception = (Map) message.get(ELEMENT_EXCEPTION); if (exception != null) { mapException(testCase, exception); } final Map warnings = (Map) message.get(ELEMENT_WARNINGS); if (warnings != null) { mapWarnings(testCase, warnings); } currentGroup.addChild(testCase, true); viewer.registerTestAdded(); if (testCase.getStatus() > PHPUnitTest.STATUS_PASS) { viewer.registerAutoScrollTarget(testCase); viewer.registerFailedForAutoScroll(testCase); } } public void clean() { final PHPUnitElementManager manager = PHPUnitElementManager.getInstance(); manager.initialize(); currentGroup = manager.getRoot(); currentTestCase = null; } public boolean isInProgress() { return inProgress; } /** * @param testCase * @param exception */ public void mapException(final PHPUnitTestCase testCase, final Map exception) { testCase.setException(new PHPUnitTestException(exception, testCase, remoteDebugger)); mapTest(testCase.getException()); } private void mapTest(final PHPUnitElement test) { PHPUnitElementManager.getInstance().add(test.getTestId(), test); } private void mapWarnings(final PHPUnitTestCase testCase, final Map<?, ?> warnings) { Map<?, ?> mWarning; // keep initial order for (int i = 0; (mWarning = (Map<?, ?>) warnings.get(String.valueOf(i))) != null; ++i) { if (testCase.getWarnings() == null) testCase.setWarnings(new ArrayList<PHPUnitElement>(warnings.size())); final PHPUnitTestWarning warning = new PHPUnitTestWarning(mWarning, testCase, remoteDebugger); mapTest(warning); testCase.getWarnings().add(i, warning); } } private void parseGroupEnd(final TestViewer viewer) { currentGroup = (PHPUnitTestGroup) currentGroup.getParent(); currentTestCase = null; viewer.registerViewerUpdate(currentGroup); } public void setInProgress(final boolean inProgress) { this.inProgress = inProgress; } public void setDebugTarget(IDebugTarget debugTarget) { if (debugTarget instanceof PHPDebugTarget) { PHPDebugTarget phpDebugTarget = (PHPDebugTarget) debugTarget; this.remoteDebugger = (RemoteDebugger) phpDebugTarget.getRemoteDebugger(); } else { this.remoteDebugger = null; } } public PHPUnitTestCase getCurrentTestCase() { return currentTestCase; } }