Skip to content

Commit

Permalink
Console API: Add console.assert
Browse files Browse the repository at this point in the history
console.assert tests if an expression is true. If it is false,
it writes a message to the console and prints the JavaScript
stack trace at that point.

Change-Id: I5487552cb8a947e1947914166834e0bdedba3354
Reviewed-by: Kai Koehne <kai.koehne@nokia.com>
  • Loading branch information
Aurindam Jana authored and Qt by Nokia committed Jan 24, 2012
1 parent 47a5c70 commit b514fec
Show file tree
Hide file tree
Showing 6 changed files with 136 additions and 13 deletions.
13 changes: 13 additions & 0 deletions doc/src/declarative/qdeclarativedebugging.qdoc
Expand Up @@ -49,6 +49,19 @@ The output is generated using the qDebug, qWarning, qCritical methods in C++
\hint Setting the environment variable QML_CONSOLE_EXTENDED also prints the source
code location of the call.

\section2 Assert

\c console.assert tests that an expression is true. If not, it will write an optional message
to the console and print the stack trace.

\qml
function f() {
var x = 12
console.assert(x == 12, "This will pass");
console.assert(x > 12, "This will fail");
}
\endqml

\section2 Timer

\c console.time and console.timeEnd log the time (in milliseconds) that was spent between
Expand Down
52 changes: 39 additions & 13 deletions src/declarative/qml/v8/qdeclarativebuiltinfunctions.cpp
Expand Up @@ -94,6 +94,22 @@ static QString extendMessage(const QString &msg) {
return msg;
}

static void printStack() {
//The v8 default is currently 10 stack frames.
v8::Handle<v8::StackTrace> stackTrace =
v8::StackTrace::CurrentStackTrace(10, v8::StackTrace::kOverview);
int stackCount = stackTrace->GetFrameCount();

for (int i = 0; i < stackCount; i++) {
v8::Local<v8::StackFrame> frame = stackTrace->GetFrame(i);
v8::String::Utf8Value func_name(frame->GetFunctionName());
v8::String::Utf8Value script_name(frame->GetScriptName());
int lineNumber = frame->GetLineNumber();
int columnNumber = frame->GetColumn();
qDebug("%s (%s:%d:%d)\n", *func_name, *script_name, lineNumber, columnNumber);
}
}

v8::Handle<v8::Value> console(ConsoleLogTypes logType, const v8::Arguments &args)
{
v8::HandleScope handleScope;
Expand Down Expand Up @@ -252,19 +268,7 @@ v8::Handle<v8::Value> consoleTrace(const v8::Arguments &args)
if (args.Length() != 0)
V8THROW_ERROR("console.trace(): Invalid arguments");

//The v8 default is currently 10 stack frames.
v8::Handle<v8::StackTrace> stackTrace =
v8::StackTrace::CurrentStackTrace(10, v8::StackTrace::kOverview);
int stackCount = stackTrace->GetFrameCount();

for (int i = 0; i < stackCount; i++) {
v8::Local<v8::StackFrame> frame = stackTrace->GetFrame(i);
v8::String::Utf8Value func_name(frame->GetFunctionName());
v8::String::Utf8Value script_name(frame->GetScriptName());
int lineNumber = frame->GetLineNumber();
int columnNumber = frame->GetColumn();
qDebug("%s (%s:%d:%d)\n", *func_name, *script_name, lineNumber, columnNumber);
}
printStack();
return v8::Undefined();
}

Expand All @@ -273,6 +277,28 @@ v8::Handle<v8::Value> consoleWarn(const v8::Arguments &args)
return console(Warn, args);
}

v8::Handle<v8::Value> consoleAssert(const v8::Arguments &args)
{
if (args.Length() == 0)
V8THROW_ERROR("console.assert(): Missing argument");

if (!args[0]->ToBoolean()->Value()) {
QString message;
for (int i = 1; i < args.Length(); ++i) {
if (i != 1)
message.append(QLatin1Char(' '));

v8::Local<v8::Value> value = args[i];
message.append(V8ENGINE()->toString(value->ToString()));
}

message = extendMessage(message);
qCritical("%s", qPrintable(message));
printStack();
}
return v8::Undefined();
}

v8::Handle<v8::Value> stringArg(const v8::Arguments &args)
{
QString value = V8ENGINE()->toString(args.This()->ToString());
Expand Down
1 change: 1 addition & 0 deletions src/declarative/qml/v8/qdeclarativebuiltinfunctions_p.h
Expand Up @@ -70,6 +70,7 @@ v8::Handle<v8::Value> consoleTimeEnd(const v8::Arguments &args);
v8::Handle<v8::Value> consoleCount(const v8::Arguments &args);
v8::Handle<v8::Value> consoleTrace(const v8::Arguments &args);
v8::Handle<v8::Value> consoleWarn(const v8::Arguments &args);
v8::Handle<v8::Value> consoleAssert(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
1 change: 1 addition & 0 deletions src/declarative/qml/v8/qv8engine.cpp
Expand Up @@ -530,6 +530,7 @@ void QV8Engine::initializeGlobal(v8::Handle<v8::Object> global)
console->Set(v8::String::New("info"), consoleLogFn);
console->Set(v8::String::New("warn"), V8FUNCTION(consoleWarn, this));
console->Set(v8::String::New("error"), V8FUNCTION(consoleError, this));
console->Set(v8::String::New("assert"), V8FUNCTION(consoleAssert, this));

console->Set(v8::String::New("count"), V8FUNCTION(consoleCount, this));
console->Set(v8::String::New("profile"), V8FUNCTION(consoleProfile, this));
Expand Down
62 changes: 62 additions & 0 deletions tests/auto/declarative/qdeclarativeconsole/data/assert.qml
@@ -0,0 +1,62 @@
/****************************************************************************
**
** 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$
**
****************************************************************************/

import QtQuick 2.0

QtObject {
property int q:1
function assertFail() {
console.assert(0, "This will fail too")
}

Component.onCompleted: {
var x = 12;
console.assert(x == 12, "This will pass");
try {
console.assert(x < 12, "This will fail");
} catch (e) {
console.log(e);
}
console.assert("x < 12", "This will pass too")
assertFail();
console.assert(1)
}
}
Expand Up @@ -54,6 +54,7 @@ private slots:
void logging();
void tracing();
void profiling();
void assert();

private:
QDeclarativeEngine engine;
Expand Down Expand Up @@ -120,6 +121,25 @@ void tst_qdeclarativeconsole::profiling()
delete object;
}

void tst_qdeclarativeconsole::assert()
{
QUrl testUrl = testFileUrl("assert.qml");

// assert()
QTest::ignoreMessage(QtCriticalMsg, "This will fail");
QTest::ignoreMessage(QtCriticalMsg, "This will fail too");
QString trace1 = QString::fromLatin1("onCompleted (%1:%2:%3)\n").arg(testUrl.toString()).arg(54).arg(17);
QString trace2 = QString::fromLatin1("onCompleted (%1:%2:%3)\n").arg(testUrl.toString()).arg(59).arg(9);
QString trace3 = QString::fromLatin1("assertFail (%1:%2:%3)\n").arg(testUrl.toString()).arg(47).arg(17);
QTest::ignoreMessage(QtDebugMsg, qPrintable(trace1));
QTest::ignoreMessage(QtDebugMsg, qPrintable(trace2));
QTest::ignoreMessage(QtDebugMsg, qPrintable(trace3));

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

QTEST_MAIN(tst_qdeclarativeconsole)

Expand Down

0 comments on commit b514fec

Please sign in to comment.