Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
ConsoleAPI: Use environment variable
Show detailed information, such as file and line number, for
console.log, console.debug and print when the environment variable
QML_CONSOLE_EXTENDED is set.

Change-Id: I8f660f58d0fd08971ce9706b4a418ed60f312980
Reviewed-by: Kai Koehne <kai.koehne@nokia.com>
  • Loading branch information
Aurindam Jana authored and Qt by Nokia committed Nov 24, 2011
1 parent 5aad0f5 commit 43b2d68
Show file tree
Hide file tree
Showing 11 changed files with 212 additions and 69 deletions.
34 changes: 19 additions & 15 deletions src/declarative/qml/v8/qdeclarativebuiltinfunctions.cpp
Expand Up @@ -65,6 +65,9 @@

QT_BEGIN_NAMESPACE

// send more information such as file, line etc for console APIs
DEFINE_BOOL_CONFIG_OPTION(qmlConsoleExtended, QML_CONSOLE_EXTENDED)

namespace QDeclarativeBuiltinFunctions {

enum ConsoleLogTypes {
Expand All @@ -75,19 +78,8 @@ enum ConsoleLogTypes {

v8::Handle<v8::Value> console(ConsoleLogTypes logType, const v8::Arguments &args)
{
int line = -1;
QString scriptName;
v8::HandleScope handleScope;

{
v8::Local<v8::StackTrace> stackTrace = v8::StackTrace::CurrentStackTrace(1);
if (stackTrace->GetFrameCount()) {
v8::Local<v8::StackFrame> currentStackFrame = stackTrace->GetFrame(0);
line = currentStackFrame->GetLineNumber();
scriptName = V8ENGINE()->toString(currentStackFrame->GetScriptName());
}
}

QString result;
for (int i = 0; i < args.Length(); ++i) {
if (i != 0)
Expand All @@ -109,17 +101,29 @@ v8::Handle<v8::Value> console(ConsoleLogTypes logType, const v8::Arguments &args
}
}

QString log = QString(QLatin1String("%1 (%2:%3)")).arg(result).arg(scriptName).arg(line);
if (qmlConsoleExtended()) {
int line = -1;
QString scriptName;
//get only current frame
v8::Local<v8::StackTrace> stackTrace = v8::StackTrace::CurrentStackTrace(1);
if (stackTrace->GetFrameCount()) {
v8::Local<v8::StackFrame> currentStackFrame = stackTrace->GetFrame(0);
line = currentStackFrame->GetLineNumber();
scriptName = V8ENGINE()->toString(currentStackFrame->GetScriptName());
}

result = QString(QLatin1String("%1 (%2:%3)")).arg(result).arg(scriptName).arg(line);
}

switch (logType) {
case Log:
qDebug("%s", qPrintable(log));
qDebug("%s", qPrintable(result));
break;
case Warn:
qWarning("%s", qPrintable(log));
qWarning("%s", qPrintable(result));
break;
case Error:
qCritical("%s", qPrintable(log));
qCritical("%s", qPrintable(result));
break;
default:
break;
Expand Down
1 change: 1 addition & 0 deletions tests/auto/declarative/declarative.pro
Expand Up @@ -11,6 +11,7 @@ PUBLICTESTS += \
parserstress \
qdeclarativecomponent \
qdeclarativecontext \
qdeclarativeconsole \
qdeclarativeengine \
qdeclarativeerror \
qdeclarativefolderlistmodel \
Expand Down
Expand Up @@ -806,11 +806,9 @@ void tst_qdeclarativeanimations::attached()
{
QDeclarativeEngine engine;

QUrl url(QUrl::fromLocalFile(TESTDATA("attached.qml")));
QDeclarativeComponent c(&engine, url);
QString messageFormat = QString(QLatin1String("%1 (%2:%3)"));
QTest::ignoreMessage(QtDebugMsg, messageFormat.arg(QLatin1String("off")).arg(url.toString()).arg(24).toLatin1());
QTest::ignoreMessage(QtDebugMsg, messageFormat.arg(QLatin1String("on")).arg(url.toString()).arg(20).toLatin1());
QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("attached.qml")));
QTest::ignoreMessage(QtDebugMsg, "off");
QTest::ignoreMessage(QtDebugMsg, "on");
QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
QVERIFY(rect);
}
Expand Down
32 changes: 32 additions & 0 deletions tests/auto/declarative/qdeclarativeconsole/data/consoleLog.qml
@@ -0,0 +1,32 @@
import QtQuick 2.0

QtObject {
id: root
Component.onCompleted: {
var a = [1, 2]
var b = {a: "hello", d: 1 }
var c
var d = 12
var e = function() { return 5;}
var f = true
var g = {toString: function() { throw new Error('toString'); }}


console.log("completed", "ok")
console.log("completed ok")
console.debug("completed ok")
console.warn("completed ok")
console.error("completed ok")
console.log(a)
console.log(b)
console.log(c)
console.log(d)
console.log(e)
console.log(f)
console.log(root)
console.log(g)
console.log(1, "pong!", new Object)
console.log(1, ["ping","pong"], new Object, 2)
console.log(exception) //This has to be at the end
}
}
12 changes: 12 additions & 0 deletions tests/auto/declarative/qdeclarativeconsole/qdeclarativeconsole.pro
@@ -0,0 +1,12 @@
CONFIG += testcase
TARGET = tst_qdeclarativeconsole
SOURCES += tst_qdeclarativeconsole.cpp
macx:CONFIG -= app_bundle

testDataFiles.files = data
testDataFiles.path = .
DEPLOYMENT += testDataFiles

CONFIG += parallel_test

QT += declarative testlib
112 changes: 112 additions & 0 deletions tests/auto/declarative/qdeclarativeconsole/tst_qdeclarativeconsole.cpp
@@ -0,0 +1,112 @@
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <qtest.h>
#include <QDebug>
#include <QDeclarativeEngine>
#include <QDeclarativeComponent>
#include "../shared/util.h"

class tst_qdeclarativeconsole : public QObject
{
Q_OBJECT
public:
tst_qdeclarativeconsole() {}

private slots:
void init();
void consoleLogExtended();

private:
QDeclarativeEngine engine;
};

inline QUrl TEST_FILE(const QString &filename)
{
return QUrl::fromLocalFile(TESTDATA(filename));
}

void tst_qdeclarativeconsole::init()
{
qputenv("QML_CONSOLE_EXTENDED", QByteArray("1"));
}

void tst_qdeclarativeconsole::consoleLogExtended()
{
int startLineNumber = 15;
QUrl testFileUrl = TEST_FILE("consoleLog.qml");
QString testString = QString(QLatin1String("completed ok (%1:%2)")).arg(testFileUrl.toString());
QTest::ignoreMessage(QtDebugMsg, qPrintable(testString.arg(startLineNumber++)));
QTest::ignoreMessage(QtDebugMsg, qPrintable(testString.arg(startLineNumber++)));
QTest::ignoreMessage(QtDebugMsg, qPrintable(testString.arg(startLineNumber++)));
QTest::ignoreMessage(QtWarningMsg, qPrintable(testString.arg(startLineNumber++)));
QTest::ignoreMessage(QtCriticalMsg, qPrintable(testString.arg(startLineNumber++)));

QString testArray = QString(QLatin1String("[1,2] (%1:%2)")).arg(testFileUrl.toString());
QTest::ignoreMessage(QtDebugMsg, qPrintable(testArray.arg(startLineNumber++)));
QString testObject = QString(QLatin1String("Object (%1:%2)")).arg(testFileUrl.toString());
QTest::ignoreMessage(QtDebugMsg, qPrintable(testObject.arg(startLineNumber++)));
QString testUndefined = QString(QLatin1String("undefined (%1:%2)")).arg(testFileUrl.toString());
QTest::ignoreMessage(QtDebugMsg, qPrintable(testUndefined.arg(startLineNumber++)));
QString testNumber = QString(QLatin1String("12 (%1:%2)")).arg(testFileUrl.toString());
QTest::ignoreMessage(QtDebugMsg, qPrintable(testNumber.arg(startLineNumber++)));
QString testFunction = QString(QLatin1String("function () { return 5;} (%1:%2)")).arg(testFileUrl.toString());
QTest::ignoreMessage(QtDebugMsg, qPrintable(testFunction.arg(startLineNumber++)));
QString testBoolean = QString(QLatin1String("true (%1:%2)")).arg(testFileUrl.toString());
QTest::ignoreMessage(QtDebugMsg, qPrintable(testBoolean.arg(startLineNumber++)));
QTest::ignoreMessage(QtDebugMsg, qPrintable(testObject.arg(startLineNumber++)));
QTest::ignoreMessage(QtDebugMsg, qPrintable(testObject.arg(startLineNumber++)));
QString testMix = QString::fromLatin1("1 pong! Object (%1:%2)").arg(testFileUrl.toString());
QTest::ignoreMessage(QtDebugMsg, qPrintable(testMix.arg(startLineNumber++)));
testMix = QString::fromLatin1("1 [ping,pong] Object 2 (%1:%2)").arg(testFileUrl.toString());
QTest::ignoreMessage(QtDebugMsg, qPrintable(testMix.arg(startLineNumber++)));

QString testException = QString(QLatin1String("%1:%2: ReferenceError: Can't find variable: exception")).arg(testFileUrl.toString());
QTest::ignoreMessage(QtWarningMsg, qPrintable(testException.arg(startLineNumber++)));

QDeclarativeComponent component(&engine, testFileUrl);
QObject *object = component.create();
QVERIFY(object != 0);
delete object;
}

QTEST_MAIN(tst_qdeclarativeconsole)

#include "tst_qdeclarativeconsole.moc"
Expand Up @@ -1595,8 +1595,8 @@ void tst_qdeclarativeecmascript::shutdownErrors()
void tst_qdeclarativeecmascript::compositePropertyType()
{
QDeclarativeComponent component(&engine, TEST_FILE("compositePropertyType.qml"));
QString messageFormat = QString(QLatin1String("hello world (%1:%2)")).arg(TEST_FILE("compositePropertyType.qml").toString()).arg(7);
QTest::ignoreMessage(QtDebugMsg, qPrintable(messageFormat));

QTest::ignoreMessage(QtDebugMsg, "hello world");
QObject *object = qobject_cast<QObject *>(component.create());
delete object;
}
Expand Down Expand Up @@ -4392,8 +4392,7 @@ void tst_qdeclarativeecmascript::qtbug_9792()
MyQmlObject *object = qobject_cast<MyQmlObject*>(component.create(context));
QVERIFY(object != 0);

QString message = QString(QLatin1String("Hello world! (%1:%2)")).arg(TEST_FILE("qtbug_9792.qml").toString()).arg(4);
QTest::ignoreMessage(QtDebugMsg, qPrintable(message));
QTest::ignoreMessage(QtDebugMsg, "Hello world!");
object->basicSignal();

delete context;
Expand Down
Expand Up @@ -850,8 +850,7 @@ void tst_qdeclarativelanguage::dynamicObjectProperties()
// Tests the declaration of dynamic signals and slots
void tst_qdeclarativelanguage::dynamicSignalsAndSlots()
{
QString message = QString(QLatin1String("1921 (%1:%2)")).arg(TEST_FILE("dynamicSignalsAndSlots.qml").toString()).arg(9);
QTest::ignoreMessage(QtDebugMsg, qPrintable(message));
QTest::ignoreMessage(QtDebugMsg, "1921");

QDeclarativeComponent component(&engine, TEST_FILE("dynamicSignalsAndSlots.qml"));
VERIFY_ERRORS(0);
Expand Down Expand Up @@ -1289,10 +1288,9 @@ void tst_qdeclarativelanguage::onCompleted()
{
QDeclarativeComponent component(&engine, TEST_FILE("onCompleted.qml"));
VERIFY_ERRORS(0);
QString formatMessage = QString(QLatin1String("%1 (%2:%3)"));
QTest::ignoreMessage(QtDebugMsg, formatMessage.arg(QLatin1String("Completed 6 10")).arg(TEST_FILE("onCompleted.qml").toString()).arg(8).toLatin1());
QTest::ignoreMessage(QtDebugMsg, formatMessage.arg(QLatin1String("Completed 6 10")).arg(TEST_FILE("onCompleted.qml").toString()).arg(14).toLatin1());
QTest::ignoreMessage(QtDebugMsg, formatMessage.arg(QLatin1String("Completed 10 11")).arg(TEST_FILE("OnCompletedType.qml").toString()).arg(7).toLatin1());
QTest::ignoreMessage(QtDebugMsg, "Completed 6 10");
QTest::ignoreMessage(QtDebugMsg, "Completed 6 10");
QTest::ignoreMessage(QtDebugMsg, "Completed 10 11");
QObject *object = component.create();
QVERIFY(object != 0);
}
Expand All @@ -1304,10 +1302,9 @@ void tst_qdeclarativelanguage::onDestruction()
VERIFY_ERRORS(0);
QObject *object = component.create();
QVERIFY(object != 0);
QString formatMessage = QString(QLatin1String("%1 (%2:%3)"));
QTest::ignoreMessage(QtDebugMsg, formatMessage.arg(QLatin1String("Destruction 6 10")).arg(TEST_FILE("onDestruction.qml").toString()).arg(8).toLatin1());
QTest::ignoreMessage(QtDebugMsg, formatMessage.arg(QLatin1String("Destruction 6 10")).arg(TEST_FILE("onDestruction.qml").toString()).arg(14).toLatin1());
QTest::ignoreMessage(QtDebugMsg, formatMessage.arg(QLatin1String("Destruction 10 11")).arg(TEST_FILE("OnDestructionType.qml").toString()).arg(7).toLatin1());
QTest::ignoreMessage(QtDebugMsg, "Destruction 6 10");
QTest::ignoreMessage(QtDebugMsg, "Destruction 6 10");
QTest::ignoreMessage(QtDebugMsg, "Destruction 10 11");
delete object;
}

Expand Down
46 changes: 18 additions & 28 deletions tests/auto/declarative/qdeclarativeqt/tst_qdeclarativeqt.cpp
Expand Up @@ -437,8 +437,7 @@ void tst_qdeclarativeqt::createQmlObject()
QString warning3 = component.url().toString()+ ":11: Error: Qt.createQmlObject(): failed to create object: \n " + TEST_FILE("main.qml").toString() + ":4:1: Duplicate property name";
QString warning4 = component.url().toString()+ ":9: Error: Qt.createQmlObject(): Missing parent object";
QString warning5 = component.url().toString()+ ":8: Error: Qt.createQmlObject(): Invalid arguments";
QString messageFormat = QString(QLatin1String("%1 (%2:%3)"));
QString warning6 = messageFormat.arg("RunTimeError: Qt.createQmlObject(): failed to create object: \n " + TEST_FILE("inline").toString() + ":3: Cannot assign object type QObject with no default method").arg(TEST_FILE("createQmlObject.qml").toString()).arg(23);
QString warning6 = "RunTimeError: Qt.createQmlObject(): failed to create object: \n " + TEST_FILE("inline").toString() + ":3: Cannot assign object type QObject with no default method";
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1));
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning2));
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning3));
Expand All @@ -461,33 +460,24 @@ void tst_qdeclarativeqt::createQmlObject()

void tst_qdeclarativeqt::consoleLog()
{
int startLineNumber = 15;
int startLineNumber = 30;
QUrl testFileUrl = TEST_FILE("consoleLog.qml");
QString testString = QString(QLatin1String("completed ok (%1:%2)")).arg(testFileUrl.toString());
QTest::ignoreMessage(QtDebugMsg, qPrintable(testString.arg(startLineNumber++)));
QTest::ignoreMessage(QtDebugMsg, qPrintable(testString.arg(startLineNumber++)));
QTest::ignoreMessage(QtDebugMsg, qPrintable(testString.arg(startLineNumber++)));
QTest::ignoreMessage(QtWarningMsg, qPrintable(testString.arg(startLineNumber++)));
QTest::ignoreMessage(QtCriticalMsg, qPrintable(testString.arg(startLineNumber++)));

QString testArray = QString(QLatin1String("[1,2] (%1:%2)")).arg(testFileUrl.toString());
QTest::ignoreMessage(QtDebugMsg, qPrintable(testArray.arg(startLineNumber++)));
QString testObject = QString(QLatin1String("Object (%1:%2)")).arg(testFileUrl.toString());
QTest::ignoreMessage(QtDebugMsg, qPrintable(testObject.arg(startLineNumber++)));
QString testUndefined = QString(QLatin1String("undefined (%1:%2)")).arg(testFileUrl.toString());
QTest::ignoreMessage(QtDebugMsg, qPrintable(testUndefined.arg(startLineNumber++)));
QString testNumber = QString(QLatin1String("12 (%1:%2)")).arg(testFileUrl.toString());
QTest::ignoreMessage(QtDebugMsg, qPrintable(testNumber.arg(startLineNumber++)));
QString testFunction = QString(QLatin1String("function () { return 5;} (%1:%2)")).arg(testFileUrl.toString());
QTest::ignoreMessage(QtDebugMsg, qPrintable(testFunction.arg(startLineNumber++)));
QString testBoolean = QString(QLatin1String("true (%1:%2)")).arg(testFileUrl.toString());
QTest::ignoreMessage(QtDebugMsg, qPrintable(testBoolean.arg(startLineNumber++)));
QTest::ignoreMessage(QtDebugMsg, qPrintable(testObject.arg(startLineNumber++)));
QTest::ignoreMessage(QtDebugMsg, qPrintable(testObject.arg(startLineNumber++)));
QString testMix = QString::fromLatin1("1 pong! Object (%1:%2)").arg(testFileUrl.toString());
QTest::ignoreMessage(QtDebugMsg, qPrintable(testMix.arg(startLineNumber++)));
testMix = QString::fromLatin1("1 [ping,pong] Object 2 (%1:%2)").arg(testFileUrl.toString());
QTest::ignoreMessage(QtDebugMsg, qPrintable(testMix.arg(startLineNumber++)));
QTest::ignoreMessage(QtDebugMsg, "completed ok");
QTest::ignoreMessage(QtDebugMsg, "completed ok");
QTest::ignoreMessage(QtDebugMsg, "completed ok");
QTest::ignoreMessage(QtWarningMsg, "completed ok");
QTest::ignoreMessage(QtCriticalMsg, "completed ok");

QTest::ignoreMessage(QtDebugMsg, "[1,2]");
QTest::ignoreMessage(QtDebugMsg, "Object");
QTest::ignoreMessage(QtDebugMsg, "undefined");
QTest::ignoreMessage(QtDebugMsg, "12");
QTest::ignoreMessage(QtDebugMsg, "function () { return 5;}");
QTest::ignoreMessage(QtDebugMsg, "true");
QTest::ignoreMessage(QtDebugMsg, "Object");
QTest::ignoreMessage(QtDebugMsg, "Object");
QTest::ignoreMessage(QtDebugMsg, "1 pong! Object");
QTest::ignoreMessage(QtDebugMsg, "1 [ping,pong] Object 2");

QString testException = QString(QLatin1String("%1:%2: ReferenceError: Can't find variable: exception")).arg(testFileUrl.toString());
QTest::ignoreMessage(QtWarningMsg, qPrintable(testException.arg(startLineNumber++)));
Expand Down
Expand Up @@ -74,7 +74,7 @@ class MyRect : public QQuickRectangle
MyRect() {}

void doSomething() { emit didSomething(); }

int propertyWithNotify() const { return m_prop; }
void setPropertyWithNotify(int i) { m_prop = i; emit oddlyNamedNotifySignal(); }

Expand Down Expand Up @@ -1229,9 +1229,8 @@ void tst_qdeclarativestates::tempState()
QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
QVERIFY(rect != 0);
QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
QString messageFormat = QString(QLatin1String("%1 (file://%2:%3)"));
QTest::ignoreMessage(QtDebugMsg, messageFormat.arg(QLatin1String("entering placed")).arg(TESTDATA("legalTempState.qml")).arg(11).toLatin1());
QTest::ignoreMessage(QtDebugMsg, messageFormat.arg(QLatin1String("entering idle")).arg(TESTDATA("legalTempState.qml")).arg(15).toLatin1());
QTest::ignoreMessage(QtDebugMsg, "entering placed");
QTest::ignoreMessage(QtDebugMsg, "entering idle");
rectPrivate->setState("placed");
QCOMPARE(rectPrivate->state(), QLatin1String("idle"));
}
Expand Down

0 comments on commit 43b2d68

Please sign in to comment.