Bug 760193 - Add console.assert; r=msucan
authorDennis Schubert <mozilla@dennis-schubert.de>
Sat, 07 Dec 2013 23:28:35 +0200
changeset 175082 aa759ea2238d64f8231ab6904737bd688f145251
parent 175081 8c564ccbafccc1d3d3b5a83092be400d637e721d
child 175083 5b91fd1ed7d6322f23597821a2accc96c35d306e
push id445
push userffxbld
push dateMon, 10 Mar 2014 22:05:19 +0000
treeherdermozilla-release@dc38b741b04e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmsucan
bugs760193
milestone28.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 760193 - Add console.assert; r=msucan
browser/devtools/webconsole/console-output.js
browser/devtools/webconsole/test/browser.ini
browser/devtools/webconsole/test/browser_webconsole_assert.js
browser/devtools/webconsole/test/test-console-assert.html
browser/devtools/webconsole/test/test-console-extras.html
browser/devtools/webconsole/webconsole.js
dom/base/ConsoleAPI.js
dom/tests/browser/browser_ConsoleAPITests.js
dom/tests/browser/test-console-api.html
dom/tests/mochitest/general/test_consoleAPI.html
--- a/browser/devtools/webconsole/console-output.js
+++ b/browser/devtools/webconsole/console-output.js
@@ -66,16 +66,17 @@ const COMPAT = {
   // The indent of a console group in pixels.
   GROUP_INDENT: 12,
 };
 
 // A map from the console API call levels to the Web Console severities.
 const CONSOLE_API_LEVELS_TO_SEVERITIES = {
   error: "error",
   exception: "error",
+  assert: "error",
   warn: "warning",
   info: "info",
   log: "log",
   trace: "log",
   debug: "log",
   dir: "log",
   group: "log",
   groupCollapsed: "log",
--- a/browser/devtools/webconsole/test/browser.ini
+++ b/browser/devtools/webconsole/test/browser.ini
@@ -55,16 +55,17 @@ support-files =
   test-bug-821877-csperrors.html^headers^
   test-bug-837351-security-errors.html
   test-bug-846918-hsts-invalid-headers.html
   test-bug-846918-hsts-invalid-headers.html^headers^
   test-bug-859170-longstring-hang.html
   test-bug-869003-iframe.html
   test-bug-869003-top-window.html
   test-closures.html
+  test-console-assert.html
   test-console-extras.html
   test-console-replaced-api.html
   test-console.html
   test-consoleiframes.html
   test-data.json
   test-data.json^headers^
   test-duplicate-error.html
   test-encoding-ISO-8859-1.html
@@ -130,16 +131,17 @@ support-files =
 [browser_netpanel_longstring_expand.js]
 [browser_output_breaks_after_console_dir_uninspectable.js]
 [browser_output_longstring_expand.js]
 [browser_repeated_messages_accuracy.js]
 [browser_result_format_as_string.js]
 [browser_warn_user_about_replaced_api.js]
 [browser_webconsole_abbreviate_source_url.js]
 [browser_webconsole_allow_mixedcontent_securityerrors.js]
+[browser_webconsole_assert.js]
 [browser_webconsole_basic_net_logging.js]
 [browser_webconsole_block_mixedcontent_securityerrors.js]
 [browser_webconsole_bug_579412_input_focus.js]
 [browser_webconsole_bug_580001_closing_after_completion.js]
 [browser_webconsole_bug_580030_errors_after_page_reload.js]
 [browser_webconsole_bug_580454_timestamp_l10n.js]
 [browser_webconsole_bug_582201_duplicate_errors.js]
 [browser_webconsole_bug_583816_No_input_and_Tab_key_pressed.js]
new file mode 100644
--- /dev/null
+++ b/browser/devtools/webconsole/test/browser_webconsole_assert.js
@@ -0,0 +1,50 @@
+/* vim:set ts=2 sw=2 sts=2 et: */
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+// Test that console.assert() works as expected (i.e. outputs only on falsy
+// asserts). See bug 760193.
+
+const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test/test-console-assert.html";
+
+function test() {
+  addTab(TEST_URI);
+  browser.addEventListener("load", function onLoad() {
+    browser.removeEventListener("load", onLoad, true);
+    openConsole(null, consoleOpened);
+  }, true);
+}
+
+function consoleOpened(hud) {
+  waitForMessages({
+    webconsole: hud,
+    messages: [{
+      text: "start",
+      category: CATEGORY_WEBDEV,
+      severity: SEVERITY_LOG,
+    },
+    {
+      text: "false assert",
+      category: CATEGORY_WEBDEV,
+      severity: SEVERITY_ERROR,
+    },
+    {
+      text: "falsy assert",
+      category: CATEGORY_WEBDEV,
+      severity: SEVERITY_ERROR,
+    },
+    {
+      text: "end",
+      category: CATEGORY_WEBDEV,
+      severity: SEVERITY_LOG,
+    }],
+  }).then(() => {
+    let nodes = hud.outputNode.querySelectorAll(".message");
+    is(nodes.length, 4, "only four messages are displayed, no output from the true assert");
+    finishTest();
+  });
+
+  let button = content.document.querySelector("button");
+  ok(button, "we have the button");
+  EventUtils.sendMouseEvent({ type: "click" }, button, content);
+}
new file mode 100644
--- /dev/null
+++ b/browser/devtools/webconsole/test/test-console-assert.html
@@ -0,0 +1,24 @@
+<!DOCTYPE HTML>
+<html dir="ltr" xml:lang="en-US" lang="en-US">
+  <head>
+    <!--
+      Any copyright is dedicated to the Public Domain.
+      http://creativecommons.org/publicdomain/zero/1.0/
+    -->
+    <meta charset="utf-8">
+    <title>console.assert() test</title>
+    <script type="text/javascript">
+      function test() {
+        console.log("start");
+        console.assert(false, "false assert");
+        console.assert(0, "falsy assert");
+        console.assert(true, "true assert");
+        console.log("end");
+      }
+    </script>
+  </head>
+  <body>
+    <p>test console.assert()</p>
+    <button onclick="test();">test console.assert()</button>
+  </body>
+</html>
--- a/browser/devtools/webconsole/test/test-console-extras.html
+++ b/browser/devtools/webconsole/test/test-console-extras.html
@@ -1,16 +1,15 @@
 <!DOCTYPE HTML>
 <html dir="ltr" xml:lang="en-US" lang="en-US"><head>
     <meta charset="utf-8">
     <title>Console extended API test</title>
     <script type="text/javascript">
       function test() {
         console.log("start");
-        console.assert()
         console.clear()
         console.dirxml()
         console.profile()
         console.profileEnd()
         console.count()
         console.table()
         console.log("end");
       }
--- a/browser/devtools/webconsole/webconsole.js
+++ b/browser/devtools/webconsole/webconsole.js
@@ -113,16 +113,17 @@ const MESSAGE_PREFERENCE_KEYS = [
   [ "secerror",   "secwarn",    null,     null,          ],  // Security
 ];
 
 // A mapping from the console API log event levels to the Web Console
 // severities.
 const LEVELS = {
   error: SEVERITY_ERROR,
   exception: SEVERITY_ERROR,
+  assert: SEVERITY_ERROR,
   warn: SEVERITY_WARNING,
   info: SEVERITY_INFO,
   log: SEVERITY_LOG,
   trace: SEVERITY_LOG,
   debug: SEVERITY_LOG,
   dir: SEVERITY_LOG,
   group: SEVERITY_LOG,
   groupCollapsed: SEVERITY_LOG,
@@ -1166,16 +1167,17 @@ WebConsoleFrame.prototype = {
     });
 
     switch (level) {
       case "log":
       case "info":
       case "warn":
       case "error":
       case "exception":
+      case "assert":
       case "debug": {
         let msg = new Messages.ConsoleGeneric(aMessage);
         node = msg.init(this.output).render().element;
         break;
       }
       case "dir": {
         body = { arguments: args };
         let clipboardArray = [];
--- a/dom/base/ConsoleAPI.js
+++ b/dom/base/ConsoleAPI.js
@@ -127,32 +127,39 @@ ConsoleAPI.prototype = {
         let consoleEvent = {
           action: "profileEnd",
           arguments: arguments
         };
         consoleEvent.wrappedJSObject = consoleEvent;
         Services.obs.notifyObservers(consoleEvent, "console-api-profiler",
                                      null);  
       },
+      assert: function CA_assert() {
+        let args = Array.prototype.slice.call(arguments);
+        if(!args.shift()) {
+          self.queueCall("assert", args);
+        }
+      },
       __exposedProps__: {
         log: "r",
         info: "r",
         warn: "r",
         error: "r",
         exception: "r",
         debug: "r",
         trace: "r",
         dir: "r",
         group: "r",
         groupCollapsed: "r",
         groupEnd: "r",
         time: "r",
         timeEnd: "r",
         profile: "r",
-        profileEnd: "r"
+        profileEnd: "r",
+        assert: "r"
       }
     };
 
     // We need to return an actual content object here, instead of a wrapped
     // chrome object. This allows things like console.log.bind() to work.
     let contentObj = Cu.createObjectIn(aWindow);
     function genPropDesc(fun) {
       return { enumerable: true, configurable: true, writable: true,
@@ -169,16 +176,17 @@ ConsoleAPI.prototype = {
       dir: genPropDesc('dir'),
       group: genPropDesc('group'),
       groupCollapsed: genPropDesc('groupCollapsed'),
       groupEnd: genPropDesc('groupEnd'),
       time: genPropDesc('time'),
       timeEnd: genPropDesc('timeEnd'),
       profile: genPropDesc('profile'),
       profileEnd: genPropDesc('profileEnd'),
+      assert: genPropDesc('assert'),
       __noSuchMethod__: { enumerable: true, configurable: true, writable: true,
                           value: function() {} },
       __mozillaConsole__: { value: true }
     };
 
     Object.defineProperties(contentObj, properties);
     Cu.makeObjectPropsNormal(contentObj);
 
@@ -290,16 +298,17 @@ ConsoleAPI.prototype = {
 
     switch (method) {
       case "log":
       case "info":
       case "warn":
       case "error":
       case "exception":
       case "debug":
+      case "assert":
         consoleEvent.arguments = this.processArguments(args);
         break;
       case "trace":
         consoleEvent.stacktrace = meta.stack;
         break;
       case "group":
       case "groupCollapsed":
       case "groupEnd":
--- a/dom/tests/browser/browser_ConsoleAPITests.js
+++ b/dom/tests/browser/browser_ConsoleAPITests.js
@@ -127,17 +127,17 @@ function testConsoleGroup(aMessageObject
   is(messageWindow, gWindow, "found correct window by window ID");
 
   ok(aMessageObject.level == "group" ||
      aMessageObject.level == "groupCollapsed" ||
      aMessageObject.level == "groupEnd",
      "expected level received");
 
   is(aMessageObject.functionName, "testGroups", "functionName matches");
-  ok(aMessageObject.lineNumber >= 45 && aMessageObject.lineNumber <= 48,
+  ok(aMessageObject.lineNumber >= 45 && aMessageObject.lineNumber <= 49,
      "lineNumber matches");
   if (aMessageObject.level == "groupCollapsed") {
     is(aMessageObject.groupName, "a group", "groupCollapsed groupName matches");
     is(aMessageObject.arguments[0], "a", "groupCollapsed arguments[0] matches");
     is(aMessageObject.arguments[1], "group", "groupCollapsed arguments[0] matches");
   }
   else if (aMessageObject.level == "group") {
     is(aMessageObject.groupName, "b group", "group groupName matches");
@@ -253,16 +253,20 @@ function observeConsoleTest() {
   win.console.exception("arg");
   yield undefined;
 
   let obj2 = { b: 2 };
   expect("log", "omg ", obj, " foo ", 4, obj2);
   win.console.log("omg %o foo %o", obj, 4, obj2);
   yield undefined;
 
+  expect("assert", "message");
+  win.console.assert(false, "message");
+  yield undefined;
+
   startTraceTest();
   yield undefined;
 
   startLocationTest();
   yield undefined;
 }
 
 function consoleAPISanityTest() {
@@ -277,16 +281,17 @@ function consoleAPISanityTest() {
   ok(win.console.exception, "console.exception is here");
   ok(win.console.trace, "console.trace is here");
   ok(win.console.dir, "console.dir is here");
   ok(win.console.group, "console.group is here");
   ok(win.console.groupCollapsed, "console.groupCollapsed is here");
   ok(win.console.groupEnd, "console.groupEnd is here");
   ok(win.console.time, "console.time is here");
   ok(win.console.timeEnd, "console.timeEnd is here");
+  ok(win.console.assert, "console.assert is here");
 }
 
 function startTimeTest() {
   // Reset the observer function to cope with the fabricated test data.
   ConsoleObserver.observe = function CO_observe(aSubject, aTopic, aData) {
     try {
       testConsoleTime(aSubject.wrappedJSObject);
     } catch (ex) {
--- a/dom/tests/browser/test-console-api.html
+++ b/dom/tests/browser/test-console-api.html
@@ -35,16 +35,17 @@
       function test() {
         var str = "Test Message."
         console.foobar(str); // if this throws, we don't execute following funcs
         console.log(str);
         console.info(str);
         console.warn(str);
         console.error(str);
         console.exception(str);
+        console.assert(false, str);
       }
 
       function testGroups() {
         console.groupCollapsed("a", "group");
         console.group("b", "group");
         console.groupEnd("b", "group");
       }
 
--- a/dom/tests/mochitest/general/test_consoleAPI.html
+++ b/dom/tests/mochitest/general/test_consoleAPI.html
@@ -30,16 +30,17 @@ function doTest() {
     "dir": "function",
     "group": "function",
     "groupCollapsed": "function",
     "groupEnd": "function",
     "time": "function",
     "timeEnd": "function",
     "profile": "function",
     "profileEnd": "function",
+    "assert": "function",
     "__noSuchMethod__": "function"
   };
 
   var foundProps = 0;
   for (var prop in console) {
     foundProps++;
     is(typeof(console[prop]), expectedProps[prop], "expect console prop " + prop + " exists");
   }