Skip to content

Commit

Permalink
QV8Engine: Console APIs
Browse files Browse the repository at this point in the history
Modified functionality for console.log, console.debug. Added
script and line information. Added functions console.warn
and console.error.

Change-Id: Id9f4dce5658a09b00522f8e087caf8f4242f418a
Reviewed-by: Kai Koehne <kai.koehne@nokia.com>
  • Loading branch information
Aurindam Jana authored and Qt by Nokia committed Nov 11, 2011
1 parent 3346a77 commit a7f5c93
Show file tree
Hide file tree
Showing 10 changed files with 164 additions and 45 deletions.
86 changes: 72 additions & 14 deletions src/declarative/qml/v8/qdeclarativebuiltinfunctions.cpp
Expand Up @@ -66,29 +66,69 @@ QT_BEGIN_NAMESPACE

namespace QDeclarativeBuiltinFunctions {

v8::Handle<v8::Value> gc(const v8::Arguments &args)
{
Q_UNUSED(args);
QV8Engine::gc();
return v8::Undefined();
}
enum ConsoleLogTypes {
Log,
Warn,
Error
};

v8::Handle<v8::Value> print(const v8::Arguments &args)
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)
result.append(QLatin1Char(' '));

v8::Local<v8::String> jsstr = args[i]->ToString();
if (!jsstr.IsEmpty()) {
QString qstr;
qstr.resize(jsstr->Length());
jsstr->Write((uint16_t*)qstr.data());
result.append(qstr);
v8::Local<v8::Value> value = args[i];
//Check for Object Type
if (value->IsObject() && !value->IsFunction()
&& !value->IsArray() && !value->IsDate()
&& !value->IsRegExp()) {
result = QLatin1String("Object");
} else {
v8::Local<v8::String> jsstr = value->ToString();
result.append(V8ENGINE()->toString(jsstr));
if (value->IsArray())
result = QString(QLatin1String("[%1]")).arg(result);
}
}
qDebug("%s", qPrintable(result));

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

switch (logType) {
case Log:
qDebug("%s", qPrintable(log));
break;
case Warn:
qWarning("%s", qPrintable(log));
break;
case Error:
qCritical("%s", qPrintable(log));
break;
default:
break;
}

return v8::Undefined();
}

v8::Handle<v8::Value> gc(const v8::Arguments &args)
{
Q_UNUSED(args);
QV8Engine::gc();
return v8::Undefined();
}

Expand All @@ -114,6 +154,24 @@ v8::Handle<v8::Value> consoleTimeEnd(const v8::Arguments &args)
return v8::Undefined();
}

v8::Handle<v8::Value> consoleLog(const v8::Arguments &args)
{
//console.log
//console.debug
//print
return console(Log, args);
}

v8::Handle<v8::Value> consoleWarn(const v8::Arguments &args)
{
return console(Warn, args);
}

v8::Handle<v8::Value> consoleError(const v8::Arguments &args)
{
return console(Error, args);
}

v8::Handle<v8::Value> stringArg(const v8::Arguments &args)
{
QString value = V8ENGINE()->toString(args.This()->ToString());
Expand Down
8 changes: 5 additions & 3 deletions src/declarative/qml/v8/qdeclarativebuiltinfunctions_p.h
Expand Up @@ -61,7 +61,11 @@ QT_BEGIN_NAMESPACE
namespace QDeclarativeBuiltinFunctions
{
v8::Handle<v8::Value> gc(const v8::Arguments &args);
v8::Handle<v8::Value> print(const v8::Arguments &args);
v8::Handle<v8::Value> consoleLog(const v8::Arguments &args);
v8::Handle<v8::Value> consoleWarn(const v8::Arguments &args);
v8::Handle<v8::Value> consoleError(const v8::Arguments &args);
v8::Handle<v8::Value> consoleTime(const v8::Arguments &args);
v8::Handle<v8::Value> consoleTimeEnd(const v8::Arguments &args);
v8::Handle<v8::Value> isQtObject(const v8::Arguments &args);
v8::Handle<v8::Value> rgba(const v8::Arguments &args);
v8::Handle<v8::Value> hsla(const v8::Arguments &args);
Expand Down Expand Up @@ -91,8 +95,6 @@ v8::Handle<v8::Value> qsTr(const v8::Arguments &args);
v8::Handle<v8::Value> qsTrNoOp(const v8::Arguments &args);
v8::Handle<v8::Value> qsTrId(const v8::Arguments &args);
v8::Handle<v8::Value> qsTrIdNoOp(const v8::Arguments &args);
v8::Handle<v8::Value> consoleTime(const v8::Arguments &args);
v8::Handle<v8::Value> consoleTimeEnd(const v8::Arguments &args);
v8::Handle<v8::Value> stringArg(const v8::Arguments &args);
}

Expand Down
16 changes: 10 additions & 6 deletions src/declarative/qml/v8/qv8engine.cpp
Expand Up @@ -518,13 +518,17 @@ struct StaticQtMetaObject : public QObject
void QV8Engine::initializeGlobal(v8::Handle<v8::Object> global)
{
using namespace QDeclarativeBuiltinFunctions;
v8::Local<v8::Function> printFn = V8FUNCTION(print, this);
v8::Local<v8::Function> consoleTimeFn = V8FUNCTION(consoleTime, this);
v8::Local<v8::Function> consoleTimeEndFn = V8FUNCTION(consoleTimeEnd, this);

v8::Local<v8::Object> console = v8::Object::New();
console->Set(v8::String::New("log"), printFn);
console->Set(v8::String::New("debug"), printFn);
v8::Local<v8::Function> consoleLogFn = V8FUNCTION(consoleLog, this);
v8::Local<v8::Function> consoleWarnFn = V8FUNCTION(consoleWarn, this);
v8::Local<v8::Function> consoleErrorFn = V8FUNCTION(consoleError, this);
v8::Local<v8::Function> consoleTimeFn = V8FUNCTION(consoleTime, this);
v8::Local<v8::Function> consoleTimeEndFn = V8FUNCTION(consoleTimeEnd, this);
console->Set(v8::String::New("log"), consoleLogFn);
console->Set(v8::String::New("debug"), consoleLogFn);
console->Set(v8::String::New("warn"), consoleWarnFn);
console->Set(v8::String::New("error"), consoleErrorFn);
console->Set(v8::String::New("time"), consoleTimeFn);
console->Set(v8::String::New("timeEnd"), consoleTimeEndFn);

Expand Down Expand Up @@ -579,7 +583,7 @@ void QV8Engine::initializeGlobal(v8::Handle<v8::Object> global)
global->Set(v8::String::New("qsTrId"), V8FUNCTION(qsTrId, this));
global->Set(v8::String::New("QT_TRID_NOOP"), V8FUNCTION(qsTrIdNoOp, this));

global->Set(v8::String::New("print"), printFn);
global->Set(v8::String::New("print"), consoleLogFn);
global->Set(v8::String::New("console"), console);
global->Set(v8::String::New("Qt"), qt);
global->Set(v8::String::New("gc"), V8FUNCTION(QDeclarativeBuiltinFunctions::gc, this));
Expand Down
Expand Up @@ -806,9 +806,11 @@ void tst_qdeclarativeanimations::attached()
{
QDeclarativeEngine engine;

QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("attached.qml")));
QTest::ignoreMessage(QtDebugMsg, "off");
QTest::ignoreMessage(QtDebugMsg, "on");
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());
QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
QVERIFY(rect);
}
Expand Down
Expand Up @@ -1590,7 +1590,8 @@ void tst_qdeclarativeecmascript::shutdownErrors()
void tst_qdeclarativeecmascript::compositePropertyType()
{
QDeclarativeComponent component(&engine, TEST_FILE("compositePropertyType.qml"));
QTest::ignoreMessage(QtDebugMsg, "hello world");
QString messageFormat = QString(QLatin1String("hello world (%1:%2)")).arg(TEST_FILE("compositePropertyType.qml").toString()).arg(7);
QTest::ignoreMessage(QtDebugMsg, qPrintable(messageFormat));
QObject *object = qobject_cast<QObject *>(component.create());
delete object;
}
Expand Down Expand Up @@ -4362,7 +4363,8 @@ void tst_qdeclarativeecmascript::qtbug_9792()
MyQmlObject *object = qobject_cast<MyQmlObject*>(component.create(context));
QVERIFY(object != 0);

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

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

QDeclarativeComponent component(&engine, TEST_FILE("dynamicSignalsAndSlots.qml"));
VERIFY_ERRORS(0);
Expand Down Expand Up @@ -1288,9 +1289,10 @@ void tst_qdeclarativelanguage::onCompleted()
{
QDeclarativeComponent component(&engine, TEST_FILE("onCompleted.qml"));
VERIFY_ERRORS(0);
QTest::ignoreMessage(QtDebugMsg, "Completed 6 10");
QTest::ignoreMessage(QtDebugMsg, "Completed 6 10");
QTest::ignoreMessage(QtDebugMsg, "Completed 10 11");
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());
QObject *object = component.create();
QVERIFY(object != 0);
}
Expand All @@ -1302,10 +1304,10 @@ void tst_qdeclarativelanguage::onDestruction()
VERIFY_ERRORS(0);
QObject *object = component.create();
QVERIFY(object != 0);

QTest::ignoreMessage(QtDebugMsg, "Destruction 6 10");
QTest::ignoreMessage(QtDebugMsg, "Destruction 6 10");
QTest::ignoreMessage(QtDebugMsg, "Destruction 10 11");
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());
delete object;
}

Expand Down
22 changes: 22 additions & 0 deletions tests/auto/declarative/qdeclarativeqt/data/consoleLog.qml
@@ -1,8 +1,30 @@
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(exception) //This has to be at the end
}
}
35 changes: 30 additions & 5 deletions tests/auto/declarative/qdeclarativeqt/tst_qdeclarativeqt.cpp
Expand Up @@ -437,8 +437,8 @@ 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 warning6 = "RunTimeError: Qt.createQmlObject(): failed to create object: \n " + TEST_FILE("inline").toString() + ":3: Cannot assign object type QObject with no default method";

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);
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1));
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning2));
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning3));
Expand All @@ -461,9 +461,34 @@ void tst_qdeclarativeqt::createQmlObject()

void tst_qdeclarativeqt::consoleLog()
{
QTest::ignoreMessage(QtDebugMsg, "completed ok");
QTest::ignoreMessage(QtDebugMsg, "completed ok");
QDeclarativeComponent component(&engine, TEST_FILE("consoleLog.qml"));
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 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;
Expand Down
Expand Up @@ -1228,8 +1228,9 @@ void tst_qdeclarativestates::tempState()
QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
QVERIFY(rect != 0);
QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
QTest::ignoreMessage(QtDebugMsg, "entering placed");
QTest::ignoreMessage(QtDebugMsg, "entering idle");
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());
rectPrivate->setState("placed");
QCOMPARE(rectPrivate->state(), QLatin1String("idle"));
}
Expand Down
Expand Up @@ -1059,16 +1059,17 @@ void tst_qdeclarativevaluetypes::bindingConflict()
// doesn't crash
void tst_qdeclarativevaluetypes::deletedObject()
{
QString messageFormat = QString(QLatin1String("%1 (%2:%3)"));
QDeclarativeComponent component(&engine, TEST_FILE("deletedObject.qml"));
QTest::ignoreMessage(QtDebugMsg, "Test: 2");
QTest::ignoreMessage(QtDebugMsg, messageFormat.arg(QLatin1String("Test: 2")).arg(TEST_FILE("deletedObject.js").toString()).arg(6).toLatin1());
MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
QVERIFY(object != 0);

QObject *dObject = qvariant_cast<QObject *>(object->property("object"));
QVERIFY(dObject != 0);
delete dObject;

QTest::ignoreMessage(QtDebugMsg, "Test: undefined");
QTest::ignoreMessage(QtDebugMsg, messageFormat.arg(QLatin1String("Test: undefined")).arg(TEST_FILE("deletedObject.js").toString()).arg(11).toLatin1());
object->emitRunScript();

delete object;
Expand Down

0 comments on commit a7f5c93

Please sign in to comment.