Files
palemoon27/mobile/android/base/tests/helpers/JavascriptMessageParser.java
T
2018-07-24 23:11:02 +08:00

101 lines
4.0 KiB
Java

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.goanna.tests.helpers;
import org.mozilla.goanna.Assert;
import junit.framework.AssertionFailedError;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Route messages from Javascript's head.js test framework into Java's
* Mochitest framework.
*/
public final class JavascriptMessageParser {
/**
* The Javascript test harness sends test events to Java.
* Each such test event is wrapped in a Robocop:JS event.
*/
public static final String EVENT_TYPE = "Robocop:JS";
// Messages matching this pattern are handled specially. Messages not
// matching this pattern are still printed. This pattern should be able
// to handle having multiple lines in a message.
private static final Pattern testMessagePattern =
Pattern.compile("TEST-([A-Z\\-]+) \\| (.*?) \\| (.*)", Pattern.DOTALL);
private final Assert asserter;
// Used to help print stack traces neatly.
private String lastTestName = "";
// Have we seen a message saying the test is finished?
private boolean testFinishedMessageSeen = false;
private final boolean endOnAssertionFailure;
/**
* Constructs a message parser for test result messages sent from JavaScript. When seeing an
* assertion failure, the message parser can use the given {@link org.mozilla.goanna.Assert}
* instance to immediately end the test (typically if the underlying JS framework is not able
* to end the test itself) or to swallow the Errors - this functionality is determined by the
* <code>endOnAssertionFailure</code> parameter.
*
* @param asserter The Assert instance to which test results should be passed.
* @param endOnAssertionFailure
* true if the test should end if we see a JS assertion failure, false otherwise.
*/
public JavascriptMessageParser(final Assert asserter, final boolean endOnAssertionFailure) {
this.asserter = asserter;
this.endOnAssertionFailure = endOnAssertionFailure;
}
public boolean isTestFinished() {
return testFinishedMessageSeen;
}
public void logMessage(final String str) {
final Matcher m = testMessagePattern.matcher(str.trim());
if (m.matches()) {
final String type = m.group(1);
final String name = m.group(2);
final String message = m.group(3);
if ("INFO".equals(type)) {
asserter.info(name, message);
testFinishedMessageSeen = testFinishedMessageSeen ||
"exiting test".equals(message);
} else if ("PASS".equals(type)) {
asserter.ok(true, name, message);
} else if ("UNEXPECTED-FAIL".equals(type)) {
try {
asserter.ok(false, name, message);
} catch (AssertionFailedError e) {
// Above, we call the assert, allowing it to log.
// Now we can end the test, if applicable.
if (this.endOnAssertionFailure) {
throw e;
}
// Otherwise, swallow the Error. The JS framework we're
// logging messages from is likely capable of ending tests
// when it needs to, and we want to see all of its failures,
// not just the first one!
}
} else if ("KNOWN-FAIL".equals(type)) {
asserter.todo(false, name, message);
} else if ("UNEXPECTED-PASS".equals(type)) {
asserter.todo(true, name, message);
}
lastTestName = name;
} else {
// Generally, these extra lines are stack traces from failures,
// so we print them with the name of the last test seen.
asserter.info(lastTestName, str.trim());
}
}
}