Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 package org.mozilla.gecko.tests.helpers;
7 import org.mozilla.gecko.Assert;
9 import junit.framework.AssertionFailedError;
11 import java.util.regex.Matcher;
12 import java.util.regex.Pattern;
14 /**
15 * Route messages from Javascript's head.js test framework into Java's
16 * Mochitest framework.
17 */
18 public final class JavascriptMessageParser {
20 /**
21 * The Javascript test harness sends test events to Java.
22 * Each such test event is wrapped in a Robocop:JS event.
23 */
24 public static final String EVENT_TYPE = "Robocop:JS";
26 // Messages matching this pattern are handled specially. Messages not
27 // matching this pattern are still printed. This pattern should be able
28 // to handle having multiple lines in a message.
29 private static final Pattern testMessagePattern =
30 Pattern.compile("TEST-([A-Z\\-]+) \\| (.*?) \\| (.*)", Pattern.DOTALL);
32 private final Assert asserter;
33 // Used to help print stack traces neatly.
34 private String lastTestName = "";
35 // Have we seen a message saying the test is finished?
36 private boolean testFinishedMessageSeen = false;
37 private final boolean endOnAssertionFailure;
39 /**
40 * Constructs a message parser for test result messages sent from JavaScript. When seeing an
41 * assertion failure, the message parser can use the given {@link org.mozilla.gecko.Assert}
42 * instance to immediately end the test (typically if the underlying JS framework is not able
43 * to end the test itself) or to swallow the Errors - this functionality is determined by the
44 * <code>endOnAssertionFailure</code> parameter.
45 *
46 * @param asserter The Assert instance to which test results should be passed.
47 * @param endOnAssertionFailure
48 * true if the test should end if we see a JS assertion failure, false otherwise.
49 */
50 public JavascriptMessageParser(final Assert asserter, final boolean endOnAssertionFailure) {
51 this.asserter = asserter;
52 this.endOnAssertionFailure = endOnAssertionFailure;
53 }
55 public boolean isTestFinished() {
56 return testFinishedMessageSeen;
57 }
59 public void logMessage(final String str) {
60 final Matcher m = testMessagePattern.matcher(str.trim());
62 if (m.matches()) {
63 final String type = m.group(1);
64 final String name = m.group(2);
65 final String message = m.group(3);
67 if ("INFO".equals(type)) {
68 asserter.info(name, message);
69 testFinishedMessageSeen = testFinishedMessageSeen ||
70 "exiting test".equals(message);
71 } else if ("PASS".equals(type)) {
72 asserter.ok(true, name, message);
73 } else if ("UNEXPECTED-FAIL".equals(type)) {
74 try {
75 asserter.ok(false, name, message);
76 } catch (AssertionFailedError e) {
77 // Above, we call the assert, allowing it to log.
78 // Now we can end the test, if applicable.
79 if (this.endOnAssertionFailure) {
80 throw e;
81 }
82 // Otherwise, swallow the Error. The JS framework we're
83 // logging messages from is likely capable of ending tests
84 // when it needs to, and we want to see all of its failures,
85 // not just the first one!
86 }
87 } else if ("KNOWN-FAIL".equals(type)) {
88 asserter.todo(false, name, message);
89 } else if ("UNEXPECTED-PASS".equals(type)) {
90 asserter.todo(true, name, message);
91 }
93 lastTestName = name;
94 } else {
95 // Generally, these extra lines are stack traces from failures,
96 // so we print them with the name of the last test seen.
97 asserter.info(lastTestName, str.trim());
98 }
99 }
100 }