From 387384fa3c4f2bd8bafac93344032d24842d2e6d Mon Sep 17 00:00:00 2001 From: Panos Astithas Date: Thu, 12 May 2011 09:29:17 -0300 Subject: [PATCH] Bug 646025 - Add file location to console.log, info, debug, etc.; f=mihai.sucan r=gavin.sharp --- dom/base/ConsoleAPI.js | 8 +- dom/tests/browser/browser_ConsoleAPITests.js | 52 ++++++++++-- dom/tests/browser/test-console-api.html | 5 ++ .../console/hudservice/HUDService.jsm | 41 +++++----- .../hudservice/tests/browser/Makefile.in | 3 + ...onsole_bug_646025_console_file_location.js | 80 +++++++++++++++++++ ...test-bug-646025-console-file-location.html | 11 +++ .../tests/browser/test-file-location.js | 9 +++ 8 files changed, 180 insertions(+), 29 deletions(-) create mode 100644 toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_646025_console_file_location.js create mode 100644 toolkit/components/console/hudservice/tests/browser/test-bug-646025-console-file-location.html create mode 100644 toolkit/components/console/hudservice/tests/browser/test-file-location.js diff --git a/dom/base/ConsoleAPI.js b/dom/base/ConsoleAPI.js index 194595ee4690..afec5653b218 100644 --- a/dom/base/ConsoleAPI.js +++ b/dom/base/ConsoleAPI.js @@ -122,9 +122,15 @@ ConsoleAPI.prototype = { if (!aID) return; + let stack = this.getStackTrace(); + // Skip the first frame since it contains an internal call. + let frame = stack[1]; let consoleEvent = { ID: aID, level: aLevel, + filename: frame.filename, + lineNumber: frame.lineNumber, + functionName: frame.functionName, arguments: aArguments }; @@ -157,7 +163,7 @@ ConsoleAPI.prototype = { } return stack; - }, + } }; let NSGetFactory = XPCOMUtils.generateNSGetFactory([ConsoleAPI]); diff --git a/dom/tests/browser/browser_ConsoleAPITests.js b/dom/tests/browser/browser_ConsoleAPITests.js index 4c086a85ae26..ae16708cfd2c 100644 --- a/dom/tests/browser/browser_ConsoleAPITests.js +++ b/dom/tests/browser/browser_ConsoleAPITests.js @@ -22,6 +22,7 @@ * David Dahl * Rob Campbell * Mihai Sucan + * Panos Astithas * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or @@ -39,7 +40,7 @@ const TEST_URI = "http://example.com/browser/dom/tests/browser/test-console-api.html"; -var gWindow; +var gWindow, gLevel, gArgs; function test() { waitForExplicitFinish(); @@ -65,8 +66,6 @@ function test() { }, false); } -var gWindow; - function testConsoleData(aMessageObject) { let messageWindow = getWindowByWindowId(aMessageObject.ID); is(messageWindow, gWindow, "found correct window by window ID"); @@ -79,9 +78,8 @@ function testConsoleData(aMessageObject) { is(aMessageObject.arguments.toSource(), gArgs.toSource(), "stack trace is correct"); - // Test finished - ConsoleObserver.destroy(); - finish(); + // Now test the location information in console.log() + startLocationTest(); } else { gArgs.forEach(function (a, i) { @@ -95,6 +93,26 @@ function testConsoleData(aMessageObject) { } } +function testLocationData(aMessageObject) { + let messageWindow = getWindowByWindowId(aMessageObject.ID); + is(messageWindow, gWindow, "found correct window by window ID"); + + is(aMessageObject.level, gLevel, "expected level received"); + ok(aMessageObject.arguments, "we have arguments"); + + is(aMessageObject.filename, gArgs[0].filename, "filename matches"); + is(aMessageObject.lineNumber, gArgs[0].lineNumber, "lineNumber matches"); + is(aMessageObject.functionName, gArgs[0].functionName, "functionName matches"); + is(aMessageObject.arguments.length, gArgs[0].arguments.length, "arguments.length matches"); + gArgs[0].arguments.forEach(function (a, i) { + is(aMessageObject.arguments[i], a, "correct arg " + i); + }); + + // Test finished + ConsoleObserver.destroy(); + finish(); +} + function startTraceTest() { gLevel = "trace"; gArgs = [ @@ -109,7 +127,27 @@ function startTraceTest() { EventUtils.synthesizeMouse(button, 2, 2, {}, gWindow); } -var gLevel, gArgs; +function startLocationTest() { + // Reset the observer function to cope with the fabricated test data. + ConsoleObserver.observe = function CO_observe(aSubject, aTopic, aData) { + try { + testLocationData(aSubject.wrappedJSObject); + } catch (ex) { + // XXX Exceptions in this function currently aren't reported, because of + // some XPConnect weirdness, so report them manually + ok(false, "Exception thrown in CO_observe: " + ex); + } + }; + gLevel = "log"; + gArgs = [ + {filename: TEST_URI, lineNumber: 19, functionName: "foobar646025", arguments: ["omg", "o", "d"]} + ]; + + let button = gWindow.document.getElementById("test-location"); + ok(button, "found #test-location button"); + EventUtils.synthesizeMouse(button, 2, 2, {}, gWindow); +} + function expect(level) { gLevel = level; gArgs = Array.slice(arguments, 1); diff --git a/dom/tests/browser/test-console-api.html b/dom/tests/browser/test-console-api.html index ea58306f420f..58dc264750f7 100644 --- a/dom/tests/browser/test-console-api.html +++ b/dom/tests/browser/test-console-api.html @@ -15,6 +15,10 @@ return foobar585956b(omg + "a"); } + function foobar646025(omg) { + console.log(omg, "o", "d"); + } + function test() { var str = "Test Message." console.foobar(str); // if this throws, we don't execute following funcs @@ -29,5 +33,6 @@

Console API Test Page

+ diff --git a/toolkit/components/console/hudservice/HUDService.jsm b/toolkit/components/console/hudservice/HUDService.jsm index 2b09e5ad9e42..592c9b8ff60b 100644 --- a/toolkit/components/console/hudservice/HUDService.jsm +++ b/toolkit/components/console/hudservice/HUDService.jsm @@ -1972,16 +1972,11 @@ HUD_SERVICE.prototype = * * @param string aHUDId * The ID of the Web Console to which to send the message. - * @param string aLevel - * The level reported by the console service. This will be one of the - * strings "error", "warn", "info", or "log". - * @param Array aArguments - * The list of arguments reported by the console service. + * @param object aMessage + * The message reported by the console service. * @return void */ - logConsoleAPIMessage: function HS_logConsoleAPIMessage(aHUDId, - aLevel, - aArguments) + logConsoleAPIMessage: function HS_logConsoleAPIMessage(aHUDId, aMessage) { // Pipe the message to createMessageNode(). let hud = HUDService.hudReferences[aHUDId]; @@ -1993,32 +1988,36 @@ HUD_SERVICE.prototype = let clipboardText = null; let sourceURL = null; let sourceLine = 0; + let level = aMessage.level; + let args = aMessage.arguments; - switch (aLevel) { + switch (level) { case "log": case "info": case "warn": case "error": case "debug": - let mappedArguments = Array.map(aArguments, formatResult); + let mappedArguments = Array.map(args, formatResult); body = Array.join(mappedArguments, " "); + sourceURL = aMessage.filename; + sourceLine = aMessage.lineNumber; break; case "trace": - let filename = ConsoleUtils.abbreviateSourceURL(aArguments[0].filename); - let functionName = aArguments[0].functionName || + let filename = ConsoleUtils.abbreviateSourceURL(args[0].filename); + let functionName = args[0].functionName || this.getStr("stacktrace.anonymousFunction"); - let lineNumber = aArguments[0].lineNumber; + let lineNumber = args[0].lineNumber; body = this.getFormatStr("stacktrace.outputMessage", [filename, functionName, lineNumber]); - sourceURL = aArguments[0].filename; - sourceLine = aArguments[0].lineNumber; + sourceURL = args[0].filename; + sourceLine = args[0].lineNumber; clipboardText = ""; - aArguments.forEach(function(aFrame) { + args.forEach(function(aFrame) { clipboardText += aFrame.filename + " :: " + aFrame.functionName + " :: " + aFrame.lineNumber + "\n"; @@ -2028,13 +2027,13 @@ HUD_SERVICE.prototype = break; default: - Cu.reportError("Unknown Console API log level: " + aLevel); + Cu.reportError("Unknown Console API log level: " + level); return; } let node = ConsoleUtils.createMessageNode(hud.outputNode.ownerDocument, CATEGORY_WEBDEV, - LEVELS[aLevel], + LEVELS[level], body, sourceURL, sourceLine, @@ -2042,8 +2041,8 @@ HUD_SERVICE.prototype = // Make the node bring up the property panel, to allow the user to inspect // the stack trace. - if (aLevel == "trace") { - node._stacktrace = aArguments; + if (level == "trace") { + node._stacktrace = args; let linkNode = node.querySelector(".webconsole-msg-body"); linkNode.classList.add("hud-clickable"); @@ -3598,7 +3597,7 @@ let ConsoleAPIObserver = { if (!hudId) return; - HUDService.logConsoleAPIMessage(hudId, aMessage.level, aMessage.arguments); + HUDService.logConsoleAPIMessage(hudId, aMessage); } else if (aTopic == "quit-application-granted") { HUDService.shutdown(); diff --git a/toolkit/components/console/hudservice/tests/browser/Makefile.in b/toolkit/components/console/hudservice/tests/browser/Makefile.in index 40aee0b60672..f0e2afb4ecd5 100644 --- a/toolkit/components/console/hudservice/tests/browser/Makefile.in +++ b/toolkit/components/console/hudservice/tests/browser/Makefile.in @@ -135,6 +135,7 @@ _BROWSER_TEST_FILES = \ browser_webconsole_bug_585956_console_trace.js \ browser_webconsole_bug_595223_file_uri.js \ browser_webconsole_bug_632275_getters_document_width.js \ + browser_webconsole_bug_646025_console_file_location.js \ head.js \ $(NULL) @@ -203,6 +204,8 @@ _BROWSER_TEST_PAGES = \ test-bug-632347-iterators-generators.html \ test-bug-585956-console-trace.html \ test-bug-632275-getters.html \ + test-bug-646025-console-file-location.html \ + test-file-location.js \ $(NULL) libs:: $(_BROWSER_TEST_FILES) diff --git a/toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_646025_console_file_location.js b/toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_646025_console_file_location.js new file mode 100644 index 000000000000..61701c0a3c1a --- /dev/null +++ b/toolkit/components/console/hudservice/tests/browser/browser_webconsole_bug_646025_console_file_location.js @@ -0,0 +1,80 @@ +/* vim:set ts=2 sw=2 sts=2 et: */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is DevTools test code. + * + * The Initial Developer of the Original Code is Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * David Dahl + * Patrick Walton + * Julian Viereck + * Mihai Sucan + * Panos Astithas + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +// Tests that console logging methods display the method location along with +// the output in the console. + +const TEST_URI = "http://example.com/browser/toolkit/components/console/" + + "hudservice/tests/browser/" + + "test-bug-646025-console-file-location.html"; + +function test() { + addTab("data:text/html,Web Console file location display test"); + browser.addEventListener("load", onLoad, true); +} + +function onLoad(aEvent) { + browser.removeEventListener(aEvent.type, arguments.callee, true); + openConsole(); + hudId = HUDService.getHudIdByWindow(content); + + browser.addEventListener("load", testConsoleFileLocation, true); + content.location = TEST_URI; +} + +function testConsoleFileLocation(aEvent) { + browser.removeEventListener(aEvent.type, arguments.callee, true); + + outputNode = HUDService.hudReferences[hudId].outputNode; + + executeSoon(function() { + findLogEntry("test-file-location.js"); + findLogEntry("message for level"); + findLogEntry("test-file-location.js:5"); + findLogEntry("test-file-location.js:6"); + findLogEntry("test-file-location.js:7"); + findLogEntry("test-file-location.js:8"); + findLogEntry("test-file-location.js:9"); + + finishTest(); + }); +} + diff --git a/toolkit/components/console/hudservice/tests/browser/test-bug-646025-console-file-location.html b/toolkit/components/console/hudservice/tests/browser/test-bug-646025-console-file-location.html new file mode 100644 index 000000000000..8ae111f2b728 --- /dev/null +++ b/toolkit/components/console/hudservice/tests/browser/test-bug-646025-console-file-location.html @@ -0,0 +1,11 @@ + + + Console file location test + + + + +

Web Console File Location Test Page

+ + diff --git a/toolkit/components/console/hudservice/tests/browser/test-file-location.js b/toolkit/components/console/hudservice/tests/browser/test-file-location.js new file mode 100644 index 000000000000..f97ce57259dd --- /dev/null +++ b/toolkit/components/console/hudservice/tests/browser/test-file-location.js @@ -0,0 +1,9 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ +console.log("message for level log"); +console.info("message for level info"); +console.warn("message for level warn"); +console.error("message for level error"); +console.debug("message for level debug");