diff options
Diffstat (limited to 'old/interpreter/qscriptsystemtest.cpp')
-rw-r--r-- | old/interpreter/qscriptsystemtest.cpp | 838 |
1 files changed, 838 insertions, 0 deletions
diff --git a/old/interpreter/qscriptsystemtest.cpp b/old/interpreter/qscriptsystemtest.cpp new file mode 100644 index 0000000..641bfb4 --- /dev/null +++ b/old/interpreter/qscriptsystemtest.cpp @@ -0,0 +1,838 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of QtUiTest. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qscriptsystemtest.h" +#include "scriptpreprocessor.h" + +#include <QScriptEngine> +#include <QScriptValue> +#include <QScriptValueIterator> +#include <QScriptContextInfo> + +//#include <qtestprotocol_p.h> +#include <qtestide.h> +#include <QtTest/QtTest> + +#include "qtscript_bindings.h" +#include "qtuitestengineagent.h" + +#include <QDebug> + +QStringList builtins; + +Q_DECLARE_METATYPE(QVariant) +Q_DECLARE_METATYPE(QList<qint64>) + +template <typename Tp> +QScriptValue qScriptValueFromQObject(QScriptEngine *engine, Tp const &qobject) +{ + return engine->newQObject(qobject, QScriptEngine::AutoOwnership); +} + +template <typename Tp> +void qScriptValueToQObject(const QScriptValue &value, Tp &qobject) +{ qobject = qobject_cast<Tp>(value.toQObject()); +} + +template <typename Tp> +int qScriptRegisterQObjectMetaType( + QScriptEngine *engine, + const QScriptValue &prototype = QScriptValue(), + Tp * /* dummy */ = 0 + ) +{ + return qScriptRegisterMetaType<Tp>(engine, qScriptValueFromQObject, + qScriptValueToQObject, prototype); +} + +void setupEnums(QScriptEngine *engine) { + QScriptValue qsvObject = engine->newObject(); +#define S(val) qsvObject.setProperty(#val, engine->toScriptValue((int)QScriptValue::val)); + S(PropertySetter);S(ReadOnly);S(Undeletable);S(SkipInEnumeration); + S(PropertyGetter);S(QObjectMember);S(KeepExistingFlags);S(UserRange); +#undef S + engine->globalObject().setProperty("QScriptValue", qsvObject ); +} + +static QScriptValue dateToString(QScriptContext *ctx, QScriptEngine *eng) +{ + QDateTime dt = ctx->thisObject().toDateTime(); + QString fmt = ctx->argument(0).toString(); + + return eng->toScriptValue(dt.toString(fmt)); +} + +static QString findIncludeScript(const QString& name) +{ + QList<QDir> includeDirs; + foreach (QByteArray const& split, qgetenv("QTUITEST_INCLUDE_PATH").split(':')) { + if (split.isEmpty()) continue; + QDir dir(split); + if (dir.exists()) includeDirs << dir; + } + + foreach (QDir const& dir, includeDirs) { + QString file = dir.canonicalPath() + "/" + name; + if (QFile::exists(file)) { + return file; + } + } + + return QString(); +} + +// Include a single script into an engine. +static QScriptValue includeScriptFunction + (QScriptEngine *engine, const QString& name) +{ + // Find the script, relative to the entry script. + QString script; + QtScript::getLocation(engine->currentContext(), &script, 0); + QString directory = QFileInfo(QFileInfo(script).canonicalFilePath()).dir().canonicalPath(); + QDir dir(directory); + QFileInfo file(dir, name); + QString filename = name; + if (file.exists()) filename = file.canonicalFilePath(); + + // Check if the script has already been loaded. + static const char includesProperty[] = "_qtuitest_includes"; + QStringList included = qscriptvalue_cast<QStringList>(engine->globalObject().property(includesProperty)); + if (included.contains(filename)) { + return QScriptValue(); + } + + // Try to load the script into memory. + QFile scriptFile(filename); + if (!scriptFile.exists() || !scriptFile.open(QIODevice::ReadOnly)) { + int pos = directory.indexOf("/interpreter"); + if (pos > 0) { + directory = directory.left(pos) + "/tests/shared"; + QDir dir(directory); + QFileInfo file(dir, name); + filename = file.filePath(); + scriptFile.setFileName(filename); + } else { + scriptFile.setFileName(findIncludeScript(filename)); + } + } + + if (!scriptFile.exists() || (!scriptFile.isOpen() && !scriptFile.open(QIODevice::ReadOnly))) { + return engine->currentContext()->throwError("Could not find " + name + " in either the shared or testcase directory"); + } + + QString contents = QTextStream(&scriptFile).readAll(); + scriptFile.close(); + + contents.prepend("with(ParentTestMetaObject) {"); + contents.append("\n}"); + + ScriptPreprocessor().preprocess(contents); + + // Evaluate the contents of the script. + engine->pushContext()->setActivationObject(engine->globalObject()); + // Note that we have included this script. + if (!engine->globalObject().property(includesProperty).isValid()) { + engine->globalObject().setProperty(includesProperty, engine->newArray()); + } + engine->globalObject().property(includesProperty).setProperty( + engine->globalObject().property(includesProperty).property("length").toUInt32(), + qScriptValueFromValue(engine, filename)); + QScriptValue ret = engine->evaluate(contents, filename); + engine->popContext(); + + return ret; +} + +// Implementation of the "include()" function in scripts, which imports scripts. +static QScriptValue includeFunction + (QScriptContext *context, QScriptEngine *engine) +{ + QScriptValue value; + if (context->argumentCount() == 0) { + return context->throwError + ("script name must be supplied to include()"); + } + value = context->argument(0); + if (!value.isString()) { + return context->throwError + ("invalid script name supplied to include()"); + } + + QString name = value.toString(); + if (name.contains(QChar('*'))) { + //FIXME: This path doesn't look in the tests/shared/ directory. + // Expand the wildcard and include all matching scripts. + QString script; + QtScript::getLocation(context, &script, 0); + QDir dir(QFileInfo(script).dir()); + QStringList files = dir.entryList(QStringList(name)); + foreach (QString filename, files) { + value = includeScriptFunction(engine, dir.filePath(filename)); + if (engine->hasUncaughtException()) + return value; + } + return engine->undefinedValue(); + } else { + // Include a single script file. + return includeScriptFunction(engine, name); + } +} + +static QScriptValue setFlags + (QScriptContext *context, QScriptEngine* /*engine*/) +{ + Q_ASSERT(context); + if (context->argumentCount() != 3) { + return context->throwError + ("setFlags() needs three arguments"); + } + QScriptValue o = context->argument(0); + if (!o.isObject()) return QScriptValue(); + QString name = context->argument(1).toString(); + int flags = context->argument(2).toInt32(); + + o.setProperty(name, o.property(name), QFlag(flags)); + return QScriptValue(); +} + + +QScriptSystemTest::QScriptSystemTest() + : m_engine(0), + m_agent(0), + m_contextDepth(0), + testObject(0), + m_checkOnly(false) +{ +} + +QScriptSystemTest::~QScriptSystemTest() +{ +} + +void QScriptSystemTest::initEngine(bool createNewEngine) +{ + if (m_engine) { + if (createNewEngine) { + delete m_engine; + } else { + return; + } + } + + m_engine = new QScriptEngine(); + m_agent = new QtUiTestEngineAgent(m_engine, this); + + // Ensure we process events periodically. + m_engine->setProcessEventsInterval(100); + + m_engine->importExtension("qt.core"); + setupEnums(m_engine); + + // include() imports scripts directly into the parent script. + m_engine->globalObject().setProperty + ("include", m_engine->newFunction(includeFunction, 1)); + m_engine->globalObject().setProperty + ("setFlags", m_engine->newFunction(setFlags, 3)); + + + m_engine->globalObject().setProperty("_dateToString", m_engine->newFunction(dateToString)); + m_engine->evaluate("_old_date_toString = Date.prototype.toString;" + "Date.prototype.toString = function() {" + " if (arguments[0] == undefined)" + " return _old_date_toString.apply(this, arguments);" + " return _dateToString.apply(this, arguments);" + "}"); + + m_engine->globalObject().setProperty("ParentTestObject", m_engine->newQObject(this)); + m_engine->globalObject().setProperty("ParentTestMetaObject", m_engine->newQMetaObject(metaObject())); + + loadBuiltins(m_engine); + importIntoGlobalNamespace(m_engine, "ParentTestObject"); +} + +QString QScriptSystemTest::testCaseName() const +{ + if (testObject) + return testObject->metaObject()->className(); + return QAbstractTest::testCaseName(); +} + +void QScriptSystemTest::loadBuiltins(QScriptEngine *engine) +{ + QScriptEngine configEngine; + QScriptSystemTest::loadInternalScript("config.js", &configEngine); + for (int i = 0; i < configEngine.globalObject().property("builtin_files").property("length").toInt32(); ++i) { + QString file = configEngine.globalObject().property("builtin_files").property(i).toString(); + QtScript::addInternalFile( QScriptSystemTest::loadInternalScript(file, engine, true) ); + } +} + +void QScriptSystemTest::importIntoGlobalNamespace(QScriptEngine *engine, QString const& object) +{ + QScriptValue obj = engine->globalObject().property(object); + + QScriptValueIterator it(obj); + while (it.hasNext()) { + it.next(); + QString name = it.name(); + + // Transform name of enter(QString,QString) to enter + if (it.value().isFunction() && name.contains('(')) { + name = name.left(name.indexOf('(')); + } + + // Import this property into the global object iff one doesn't already + // exist with this name + if (engine->globalObject().property(name).isValid()) continue; + + // For functions, to keep the QObject slot resolution working right, we + // must wrap the property instead of simply copying it. + if (it.value().isFunction()) { + engine->evaluate(QString("%1 = function(){ return %2.%1.apply(this, arguments); };") + .arg(name) + .arg(object)); + } else { + engine->globalObject().setProperty(name, it.value()); + } + } +} + +QString QScriptSystemTest::loadInternalScript(QString const &name, QScriptEngine *engine, bool withParentObject) +{ + QString filename = QFileInfo(QString::fromAscii(__FILE__)).absolutePath() + "/" + name; + if (!QFileInfo(filename).exists()) filename = ":/" + name; + QFile f(filename); + QString data; + if (!f.open(QIODevice::ReadOnly) || (data = QTextStream(&f).readAll()).isEmpty()) { + qWarning("QtUiTest: Couldn't load config file '%s' (using '%s')", qPrintable(name), qPrintable(filename)); + return QString(); + } + + if (withParentObject) { + data.prepend("with(ParentTestMetaObject) {"); + data.append("\n}"); + } + + QScriptValue e = engine->evaluate(data, filename); + if (e.isError()) { + QString backtrace = engine->uncaughtExceptionBacktrace().join("\n"); + qWarning("In QtUiTest config file %s:\n%s\n%s", qPrintable(filename), qPrintable(e.toString()), + qPrintable(backtrace)); + } + builtins << filename; + return filename; +} + +QScriptValue variantToScriptValue(QScriptEngine *engine, const QVariant &v) +{ + QScriptValue ret; + if (v.isNull()) { + ret = QScriptValue( engine, QScriptValue::NullValue ); + } else if (v.canConvert<QStringList>()) { + ret = engine->toScriptValue(v.value<QStringList>()); + } else if (v.canConvert<qreal>()) { + ret = engine->toScriptValue(v.value<qreal>()); + } else if (v.canConvert<int>()) { + ret = engine->toScriptValue(v.value<int>()); + } else if (v.canConvert<QString>()) { + ret = engine->toScriptValue(v.value<QString>()); + } else { + ret = engine->newVariant(v); + } + return ret; +} + +void variantFromScriptValue(const QScriptValue &obj, QVariant &v) +{ + v = obj.toVariant(); +} + +QString QScriptSystemTest::currentFile() +{ + QString fileName = QString(); + int lineNumber = 0; + + QtScript::getLocation(m_engine->currentContext(), &fileName, &lineNumber); + + return fileName; +} + +int QScriptSystemTest::currentLine() +{ + QString fileName = QString(); + int lineNumber = 0; + + QtScript::getLocation(m_engine->currentContext(), &fileName, &lineNumber); + + return lineNumber; +} + +void QScriptSystemTest::outputBacktrace() +{ + QScriptContext *ctx = m_engine->currentContext(); + QString bt("Backtrace:"); + while (ctx) { + QScriptContextInfo ctxInfo(ctx); + QString fn = ctxInfo.fileName(); + int ln = ctxInfo.lineNumber(); + if (!fn.isEmpty() && ln != -1) + bt += "\n " + fn + "(" + QString::number(ln) + ")"; + ctx = ctx->parentContext(); + } + QDebug(QtDebugMsg) << qPrintable(bt); +} + +void QScriptSystemTest::skip(QString const &message, QSystemTest::SkipMode mode) +{ + QSystemTest::skip(message, mode); + m_engine->evaluate("throw new QTestFailure('QSKIP');"); +} + +bool QScriptSystemTest::fail(QString const &message) +{ + bool ret = QSystemTest::fail( message ); + if (!ret) { + outputBacktrace(); + m_engine->evaluate("throw new QTestFailure('QFAIL');"); + } + return ret; +} + +void QScriptSystemTest::verify(bool statement, QString const &message) +{ + if (!QTest::qVerify(statement, "<statement>", qPrintable(message), qPrintable(currentFile()), currentLine() )) { + outputBacktrace(); + m_engine->evaluate("throw new QTestFailure('QFAIL');"); + } +} + +void QScriptSystemTest::compare(const QString &actual, const QString &expected) +{ + if (QSystemTest::runAsManualTest()) { + QString act; + if (actual == "MAGIC_DATA" || actual.contains("'")) act = actual; + else act = "'" + actual + "'"; + QString exp; + if (expected == "MAGIC_DATA" || expected.contains("'")) exp = expected; + else exp = "'" + expected + "'"; + manualTest( QString("verify that %1 is equal to %2").arg(act).arg(exp)); + return; + } + + if (!QTest::qCompare( actual, expected, qPrintable(actual), qPrintable(expected), qPrintable(currentFile()), currentLine() )) { + outputBacktrace(); + m_engine->evaluate("throw new QTestFailure('QFAIL');"); + } +} + +void QScriptSystemTest::compare(const QStringList &actual, const QStringList &expected) +{ + if (QSystemTest::runAsManualTest()) { + QString act = actual.count() > 0 ? actual[0] : ""; + QString exp = expected.count() > 0 ? expected[0] : ""; + manualTest( QString("verify that %1 is equal to %2").arg(act).arg(exp)); + return; + } + + if (!QTest::qCompare( actual.count(), expected.count(), qPrintable(actual.join("\n")), qPrintable(expected.join("\n")), qPrintable(currentFile()), currentLine() )) { + outputBacktrace(); + m_engine->evaluate("throw new QTestFailure('QFAIL');"); + return; + } + + for (int i=0; i<actual.count(); i++) { + if (!QTest::qCompare( actual[i], expected[i], qPrintable(actual[i]), qPrintable(expected[i]), qPrintable(currentFile()), currentLine() )) { + outputBacktrace(); + m_engine->evaluate("throw new QTestFailure('QFAIL');"); + } + } +} + +bool QScriptSystemTest::isFailExpected() +{ + return (expect_fail_function == currentTestFunction() && expect_fail_datatag == currentDataTag()); +} + +void QScriptSystemTest::expectFail( const QString &reason ) +{ + expect_fail_function = currentTestFunction(); + expect_fail_datatag = currentDataTag(); + expect_fail_reason = reason; + int line = currentLine(); + + if (testObject) { + testObject->setProperty("expectFailLineNumber", line); + } + + bool ok = QTest::qExpectFail(currentDataTag().toLatin1(), reason.toLatin1(), + QTest::TestFailMode(1),//mode), + qPrintable(currentFile()), line); + if (!ok) + m_engine->evaluate("throw new QTestFailure('QFAIL');"); +} + +bool QScriptSystemTest::setQueryError( const QTestMessage &message ) +{ + QString errorString = message["status"].toString(); + QVariant response = message["_q_inResponseTo"]; + if (response.isValid()) { + errorString += QString("\nIn response to message: %2").arg(response.toString()); + } + return setQueryError( errorString ); +} + +bool QScriptSystemTest::setQueryError( const QString &errString ) +{ + if (queryFailed()) return false; + QSystemTest::setQueryError(errString); + bool ret = fail(errString); + if (!ret) { + m_engine->evaluate("throw new QTestFailure('QFAIL');"); + } + return ret; +} + +int QScriptSystemTest::runTest(const QString &fname, const QStringList ¶meters, + const QStringList &environment) +{ + m_env = environment; + bool createNewEngine = filename == fname; + filename = fname; + + QFile file(filename); + if (!file.open(QFile::ReadOnly)) { + qDebug() << "Can't open " << filename; + return -1; + } + + QTextStream stream(&file); + QString script = stream.readAll(); + + ScriptPreprocessor().preprocess(script); + + initEngine(createNewEngine); + + // Allow shebangs without giving syntax errors. + if (script.startsWith("#!")) script.prepend("//"); + script.prepend("with(ParentTestMetaObject){"); + script.append("\n}"); + + QtScriptTest tc(filename, script, m_engine); + + if (tc.status() != QtScriptTest::StatusNormal) { + return -1; + } + + testObject = &tc; + + qScriptRegisterMetaType(m_engine, variantToScriptValue, variantFromScriptValue); + qScriptRegisterSequenceMetaType<QList<qint64> >(m_engine); + + // Only set up the test data path if not explicitly set by user + if (!QCoreApplication::arguments().contains("-data")) { + setupTestDataPath(qPrintable(filename)); + } + + enableQueryWarnings(false); + + // If we get here, the syntax of the script is definitely OK + // (a syntax error causes a qFatal in the QtScriptTest ctor). + if (m_checkOnly) + return 0; + + // If an IDE is connected, set the agent to enable script debugging + if (QTestIDE::instance()->isConnected()) { + m_engine->setAgent(m_agent); + } + + if (QTest::testObject()) { + qDebug() << "Test already in progress?"; + return -1; + } + int retval = QTest::qExec(&tc, parameters); + + testObject = 0; + + // After a full test run, QTestLib sometimes returns 0 or sometimes returns + // the number of test failures, depending on how it was compiled. In both + // cases, a negative number denotes an error. + // We don't want test failures to affect the exit code. + return (retval < 0) ? retval : 0; +} + +/*! + \internal + Send a raw message from within script to the connected system. + + This can be used to extend the API for new messages on the target device + without modifying QSystemTest. + + If the message doesn't elicit a response of "OK", the current test fails. +*/ +QVariantMap QScriptSystemTest::sendRaw(const QString& event, const QScriptValue& object) +{ + QVariantMap ret; + if (object.isValid() && !object.isObject()) { + setQueryError("Second argument to sendRaw must be an object."); + return ret; + } + if (event.isEmpty()) { + setQueryError("First argument to sendRaw cannot be an empty string."); + return ret; + } + + QTestMessage message(event); + + // Treat object like a variant map and load it into message. + QScriptValueIterator it(object); + while (it.hasNext()) { + it.next(); + QScriptValue v = it.value(); + // Map must be flat; we don't handle objects within objects. + if (v.isObject() && !v.isArray()) { + setQueryError("Object passed to sendRaw must not have any child objects."); + return ret; + } + // toVariant appears to flatten stringlists into strings, which we don't want. + if (v.isArray()) { + QVariantList list; + for (int i = 0, max = qscriptvalue_cast<int>(v.property("length")); i < max; ++i) + list << v.property(i).toVariant(); + message[it.name()] = list; + } else { + message[it.name()] = v.toVariant(); + } + } + + QTestMessage reply; + if (!doQuery(message, QString(), &reply)) { + setQueryError("Raw " + event + " message failed: " + reply["status"].toString()); + return ret; + } + + foreach (QString const& key, reply.keys()) + ret[key] = reply[key]; + return ret; +} + +//#ifndef QTCREATOR_QTEST +/*! + \internal + Print any special usage information which should be shown when test is launched + with -help. +*/ +void QScriptSystemTest::printUsage() const +{ + QSystemTest::printUsage(); + qWarning( + " Script options:\n" + " -c : Check the syntax of the test only. Returns a non-zero exit code if the test\n" + " contains any syntax errors.\n" + ); +} +//#endif + +/*! + \internal + If \a func is a function, install it as a handler for all messages received from the test + system. + + Whenever a new message is received, \a func will be called with two arguments. + The first is the message event as a string. + The second is an object containing one property for each parameter of the message. + + If \a func returns true, processing of the message ends. +*/ +void QScriptSystemTest::installMessageHandler(const QScriptValue& func) +{ + if (!func.isFunction()) { + setQueryError("Argument to installMessageHandler must be a function."); + return; + } + m_messageHandlers << func; +} + + +QString qDumpScriptValue(QString const& name, QScriptValue const& v, int indent = 0) +{ + const QString spc = QString().fill(' ', indent); + + QString ret; + + ret += spc + name + ": "; + if (name != "global" && v.engine()->globalObject().strictlyEquals(v)) + ret += "global"; + else if (v.isBoolean()) + ret += "Boolean:" + v.toString(); + else if (v.isDate()) + ret += "Date:" + v.toString(); + else if (v.isFunction()) + ret += "Function"; + else if (v.isNull()) + ret += "null"; + else if (v.isNumber()) + ret += "Number:" + v.toString(); + else if (v.isString()) + ret += "String:" + v.toString(); + else if (v.isUndefined()) + ret += "undef"; + else { + QString inner; + QScriptValueIterator it(v); + QString sep; + while (it.hasNext()) { + it.next(); + inner += sep + qDumpScriptValue(it.name(), it.value(), indent+2); + sep = ",\n"; + } + if (inner.isEmpty()) { + ret += "{}"; + } else { + ret += "{\n" + inner + "\n" + spc + "} /* " + name + " */"; + } + } + + return ret; +} + +/*! + \internal + Write out most of the state of the script engine to stderr. +*/ +void QScriptSystemTest::dumpEngine() +{ + QString state; + + { + QScriptContext* ctx = m_engine->currentContext(); + state += "context: {"; + int i = 0; + QString sep; + while (ctx) { + state += QString("%1\n %2: {\n").arg(sep).arg(i++); + state += " toString: " + ctx->toString() + "\n"; + state += qDumpScriptValue("activationObject", ctx->activationObject(), 4) + ",\n"; + state += qDumpScriptValue("thisObject", ctx->thisObject(), 4) + "\n"; + state += " }"; + sep = ","; + ctx = ctx->parentContext(); + } + state += "\n};\n"; + } + + state += qDumpScriptValue("global", m_engine->globalObject()); + state += ";"; + + fprintf(stderr, "%s\n", qPrintable(state)); +} + +/*! + \internal + Passes the test message through any installed QtScript message handlers. + If none of them handle the message, it will be passed to the superclass. +*/ +void QScriptSystemTest::processMessage(const QTestMessage& message) +{ + if (m_messageHandlers.count()) { + QVariantMap map; + foreach (QString const& key, message.keys()) + map[key] = message[key]; + + QScriptValueList args; + args << m_engine->toScriptValue(message.event()); + args << m_engine->toScriptValue(map); + + for (int i = 0; i < m_messageHandlers.count(); ++i) { + QScriptValue out = m_messageHandlers[i].call(QScriptValue(), args); + if (out.isBoolean() && out.toBoolean()) + return; + } + } + + QSystemTest::processMessage(message); +} + +/*! + \internal + Processes the command line parameters. +*/ +void QScriptSystemTest::processCommandLine( QStringList &args ) +{ + QMutableStringListIterator it(args); + + while (it.hasNext()) { + QString arg = it.next(); + if (!arg.compare("-c", Qt::CaseInsensitive)) { + m_checkOnly = true; + it.remove(); + } + } + + QSystemTest::processCommandLine(args); +} + +void QScriptSystemTest::scriptPositionChange(qint64 scriptId, int line, int column) +{ + Q_UNUSED(scriptId); + Q_UNUSED(line); + Q_UNUSED(column); + + QScriptContextInfo ctxInfo(m_engine->currentContext()); + if (!ctxInfo.fileName().isEmpty() && !builtins.contains(ctxInfo.fileName())) { + QString functionName; + if (ctxInfo.functionName().isEmpty()) { + functionName = currentTestFunction(); + } else { + functionName = ctxInfo.functionName(); + } + if (QTestIDE::instance()->queryBreakpoint(ctxInfo.fileName(), ctxInfo.lineNumber(), functionName, m_contextDepth)) { + QTestIDE::instance()->breakpointContext(m_engine->currentContext()); + } + } +} + +void QScriptSystemTest::scriptContextChange(bool isNew) +{ + if (isNew) + ++m_contextDepth; + else + --m_contextDepth; +}
\ No newline at end of file |