// Variant value must be released with NPReleaseVariantValue() void convertValueToNPVariant(ExecState *exec, JSValue *value, NPVariant *result) { JSLock lock; JSType type = value->type(); VOID_TO_NPVARIANT(*result); if (type == StringType) { UString ustring = value->toString(exec); CString cstring = ustring.UTF8String(); NPString string = { (const NPUTF8 *)cstring.c_str(), static_cast<uint32_t>(cstring.size()) }; NPN_InitializeVariantWithStringCopy(result, &string); } else if (type == NumberType) { DOUBLE_TO_NPVARIANT(value->toNumber(exec), *result); } else if (type == BooleanType) { BOOLEAN_TO_NPVARIANT(value->toBoolean(exec), *result); } else if (type == UnspecifiedType) { VOID_TO_NPVARIANT(*result); } else if (type == NullType) { NULL_TO_NPVARIANT(*result); } else if (type == ObjectType) { JSObject* object = static_cast<JSObject*>(value); if (object->classInfo() == &RuntimeObjectImp::info) { RuntimeObjectImp* imp = static_cast<RuntimeObjectImp *>(value); CInstance* instance = static_cast<CInstance*>(imp->getInternalInstance()); if (instance) { NPObject* obj = instance->getObject(); _NPN_RetainObject(obj); OBJECT_TO_NPVARIANT(obj, *result); } } else { Interpreter* originInterpreter = exec->dynamicInterpreter(); RootObject* originRootObject = findRootObject(originInterpreter); Interpreter* interpreter = 0; if (originInterpreter->isGlobalObject(value)) { interpreter = originInterpreter->interpreterForGlobalObject(value); } if (!interpreter) interpreter = originInterpreter; RootObject* rootObject = findRootObject(interpreter); if (rootObject) { NPObject* npObject = _NPN_CreateScriptObject(0, object, originRootObject, rootObject); OBJECT_TO_NPVARIANT(npObject, *result); } } } }
void tst_QQmlEngineDebugService::watch_object() { QmlDebugObjectReference obj = findRootObject(); bool success; QQmlEngineDebugClient *unconnected = new QQmlEngineDebugClient(0); unconnected->addWatch(obj, &success); QVERIFY(!success); delete unconnected; m_dbg->addWatch(QmlDebugObjectReference(), &success); QVERIFY(success); QVERIFY(QQmlDebugTest::waitForSignal(m_dbg, SIGNAL(result()))); QCOMPARE(m_dbg->valid(), false); quint32 id = m_dbg->addWatch(obj, &success); QVERIFY(success); QVERIFY(QQmlDebugTest::waitForSignal(m_dbg, SIGNAL(result()))); QCOMPARE(m_dbg->valid(), true); QSignalSpy spy(m_dbg, SIGNAL(valueChanged(QByteArray,QVariant))); int origWidth = m_rootItem->property("width").toInt(); int origHeight = m_rootItem->property("height").toInt(); m_rootItem->setProperty("width", origWidth*2); QVERIFY(QQmlDebugTest::waitForSignal(m_dbg, SIGNAL(valueChanged(QByteArray,QVariant)))); m_rootItem->setProperty("height", origHeight*2); QVERIFY(QQmlDebugTest::waitForSignal(m_dbg, SIGNAL(valueChanged(QByteArray,QVariant)))); QVERIFY(spy.count() > 0); int newWidth = -1; int newHeight = -1; for (int i=0; i<spy.count(); i++) { const QVariantList &values = spy[i]; if (values[0].value<QByteArray>() == "width") newWidth = values[1].value<QVariant>().toInt(); else if (values[0].value<QByteArray>() == "height") newHeight = values[1].value<QVariant>().toInt(); } m_dbg->removeWatch(id, &success); QVERIFY(success); QVERIFY(QQmlDebugTest::waitForSignal(m_dbg, SIGNAL(result()))); QCOMPARE(m_dbg->valid(), true); // since watch has been removed, restoring the original values should not trigger a valueChanged() spy.clear(); m_rootItem->setProperty("width", origWidth); m_rootItem->setProperty("height", origHeight); QTest::qWait(100); QCOMPARE(spy.count(), 0); QCOMPARE(newWidth, origWidth * 2); QCOMPARE(newHeight, origHeight * 2); }
// Variant value must be released with NPReleaseVariantValue() void convertValueToNPVariant(ExecState* exec, JSValue value, NPVariant* result) { JSLock lock(SilenceAssertionsOnly); VOID_TO_NPVARIANT(*result); if (value.isString()) { UString ustring = value.toString(exec); CString cstring = ustring.utf8(); NPString string = { (const NPUTF8*)cstring.data(), static_cast<uint32_t>(cstring.length()) }; NPN_InitializeVariantWithStringCopy(result, &string); } else if (value.isNumber()) { DOUBLE_TO_NPVARIANT(value.toNumber(exec), *result); } else if (value.isBoolean()) { BOOLEAN_TO_NPVARIANT(value.toBoolean(exec), *result); } else if (value.isNull()) { NULL_TO_NPVARIANT(*result); } else if (value.isObject()) { JSObject* object = asObject(value); if (object->classInfo() == &CRuntimeObject::s_info) { CRuntimeObject* runtimeObject = static_cast<CRuntimeObject*>(object); CInstance* instance = runtimeObject->getInternalCInstance(); if (instance) { NPObject* obj = instance->getObject(); _NPN_RetainObject(obj); OBJECT_TO_NPVARIANT(obj, *result); } } else { #ifdef ANDROID RootObject* rootObject = findRootObject(exec->dynamicGlobalObject()); if (!rootObject) rootObject = findRootObject(exec->lexicalGlobalObject()); #else JSGlobalObject* globalObject = exec->dynamicGlobalObject(); RootObject* rootObject = findRootObject(globalObject); #endif if (rootObject) { NPObject* npObject = _NPN_CreateScriptObject(0, object, rootObject); OBJECT_TO_NPVARIANT(npObject, *result); } } } }
void tst_QQmlEngineDebugService::watch_expression() { QFETCH(QString, expr); QFETCH(int, increment); QFETCH(int, incrementCount); int origWidth = m_rootItem->property("width").toInt(); QmlDebugObjectReference obj = findRootObject(); bool success; QQmlEngineDebugClient *unconnected = new QQmlEngineDebugClient(0); unconnected->addWatch(obj, expr, &success); QVERIFY(!success); delete unconnected; m_dbg->addWatch(QmlDebugObjectReference(), expr, &success); QVERIFY(success); QVERIFY(QQmlDebugTest::waitForSignal(m_dbg, SIGNAL(result()))); QCOMPARE(m_dbg->valid(), false); quint32 id = m_dbg->addWatch(obj, expr, &success); QVERIFY(success); QVERIFY(QQmlDebugTest::waitForSignal(m_dbg, SIGNAL(result()))); QCOMPARE(m_dbg->valid(), true); QSignalSpy spy(m_dbg, SIGNAL(valueChanged(QByteArray,QVariant))); int width = origWidth; for (int i=0; i<incrementCount+1; i++) { if (i > 0) { width += increment; m_rootItem->setProperty("width", width); QVERIFY(QQmlDebugTest::waitForSignal(m_dbg, SIGNAL(valueChanged(QByteArray,QVariant)))); } } m_dbg->removeWatch(id, &success); QVERIFY(success); QVERIFY(QQmlDebugTest::waitForSignal(m_dbg, SIGNAL(result()))); QCOMPARE(m_dbg->valid(), true); // restore original value and verify spy doesn't get a signal since watch has been removed m_rootItem->setProperty("width", origWidth); QTest::qWait(100); QCOMPARE(spy.count(), incrementCount); width = origWidth + increment; for (int i=0; i<spy.count(); i++) { width += increment; QCOMPARE(spy.at(i).at(1).value<QVariant>().toInt(), width); } }
void tst_QDeclarativeDebug::watch_property() { QDeclarativeDebugObjectReference obj = findRootObject(); QDeclarativeDebugPropertyReference prop = findProperty(obj.properties(), "width"); QDeclarativeDebugPropertyWatch *watch; QDeclarativeEngineDebug *unconnected = new QDeclarativeEngineDebug(0); watch = unconnected->addWatch(prop, this); QCOMPARE(watch->state(), QDeclarativeDebugWatch::Dead); delete watch; delete unconnected; watch = m_dbg->addWatch(QDeclarativeDebugPropertyReference(), this); QVERIFY(QDeclarativeDebugTest::waitForSignal(watch, SIGNAL(stateChanged(QDeclarativeDebugWatch::State)))); QCOMPARE(watch->state(), QDeclarativeDebugWatch::Inactive); delete watch; watch = m_dbg->addWatch(prop, this); QCOMPARE(watch->state(), QDeclarativeDebugWatch::Waiting); QCOMPARE(watch->objectDebugId(), obj.debugId()); QCOMPARE(watch->name(), prop.name()); QSignalSpy spy(watch, SIGNAL(valueChanged(QByteArray,QVariant))); int origWidth = m_rootItem->property("width").toInt(); m_rootItem->setProperty("width", origWidth*2); // stateChanged() is received before valueChanged() QVERIFY(QDeclarativeDebugTest::waitForSignal(watch, SIGNAL(stateChanged(QDeclarativeDebugWatch::State)))); QCOMPARE(watch->state(), QDeclarativeDebugWatch::Active); QCOMPARE(spy.count(), 1); m_dbg->removeWatch(watch); delete watch; // restore original value and verify spy doesn't get additional signal since watch has been removed m_rootItem->setProperty("width", origWidth); QTest::qWait(100); QCOMPARE(spy.count(), 1); QCOMPARE(spy.at(0).at(0).value<QByteArray>(), prop.name().toUtf8()); QCOMPARE(spy.at(0).at(1).value<QVariant>(), qVariantFromValue(origWidth*2)); }
void tst_QQmlEngineDebugService::watch_property() { QmlDebugObjectReference obj = findRootObject(); QmlDebugPropertyReference prop = findProperty(obj.properties, "width"); bool success; QQmlEngineDebugClient *unconnected = new QQmlEngineDebugClient(0); unconnected->addWatch(prop, &success); QVERIFY(!success); delete unconnected; m_dbg->addWatch(QmlDebugPropertyReference(), &success); QVERIFY(success); QVERIFY(QQmlDebugTest::waitForSignal(m_dbg, SIGNAL(result()))); QCOMPARE(m_dbg->valid(), false); quint32 id = m_dbg->addWatch(prop, &success); QVERIFY(success); QVERIFY(QQmlDebugTest::waitForSignal(m_dbg, SIGNAL(result()))); QCOMPARE(m_dbg->valid(), true); QSignalSpy spy(m_dbg, SIGNAL(valueChanged(QByteArray,QVariant))); int origWidth = m_rootItem->property("width").toInt(); m_rootItem->setProperty("width", origWidth*2); QVERIFY(QQmlDebugTest::waitForSignal(m_dbg, SIGNAL(valueChanged(QByteArray,QVariant)))); QCOMPARE(spy.count(), 1); m_dbg->removeWatch(id, &success); QVERIFY(success); QVERIFY(QQmlDebugTest::waitForSignal(m_dbg, SIGNAL(result()))); QCOMPARE(m_dbg->valid(), true); // restore original value and verify spy doesn't get additional signal since watch has been removed m_rootItem->setProperty("width", origWidth); QTest::qWait(100); QCOMPARE(spy.count(), 1); QCOMPARE(spy.at(0).at(0).value<QByteArray>(), prop.name.toUtf8()); QCOMPARE(spy.at(0).at(1).value<QVariant>(), qVariantFromValue(origWidth*2)); }
void tst_QQmlEngineDebugService::setMethodBody() { bool success; QmlDebugObjectReference obj = findRootObject(2); QObject *root = m_components.at(2); // Without args { QVariant rv; QVERIFY(QMetaObject::invokeMethod(root, "myMethodNoArgs", Qt::DirectConnection, Q_RETURN_ARG(QVariant, rv))); QVERIFY(rv == QVariant(qreal(3))); QVERIFY(m_dbg->setMethodBody(obj.debugId, "myMethodNoArgs", "return 7", &success)); QVERIFY(success); QVERIFY(QQmlDebugTest::waitForSignal(m_dbg, SIGNAL(result()))); QVERIFY(QMetaObject::invokeMethod(root, "myMethodNoArgs", Qt::DirectConnection, Q_RETURN_ARG(QVariant, rv))); QVERIFY(rv == QVariant(qreal(7))); } // With args { QVariant rv; QVERIFY(QMetaObject::invokeMethod(root, "myMethod", Qt::DirectConnection, Q_RETURN_ARG(QVariant, rv), Q_ARG(QVariant, QVariant(19)))); QVERIFY(rv == QVariant(qreal(28))); QVERIFY(m_dbg->setMethodBody(obj.debugId, "myMethod", "return a + 7", &success)); QVERIFY(success); QVERIFY(QQmlDebugTest::waitForSignal(m_dbg, SIGNAL(result()))); QVERIFY(QMetaObject::invokeMethod(root, "myMethod", Qt::DirectConnection, Q_RETURN_ARG(QVariant, rv), Q_ARG(QVariant, QVariant(19)))); QVERIFY(rv == QVariant(qreal(26))); } }
// Variant value must be released with NPReleaseVariantValue() void convertValueToNPVariant(ExecState* exec, JSValuePtr value, NPVariant* result) { JSLock lock(false); VOID_TO_NPVARIANT(*result); if (value.isString()) { UString ustring = value.toString(exec); CString cstring = ustring.UTF8String(); NPString string = { (const NPUTF8*)cstring.c_str(), static_cast<uint32_t>(cstring.size()) }; NPN_InitializeVariantWithStringCopy(result, &string); } else if (value.isNumber()) { DOUBLE_TO_NPVARIANT(value.toNumber(exec), *result); } else if (value.isBoolean()) { BOOLEAN_TO_NPVARIANT(value.toBoolean(exec), *result); } else if (value.isNull()) { NULL_TO_NPVARIANT(*result); } else if (value.isObject()) { JSObject* object = asObject(value); if (object->classInfo() == &RuntimeObjectImp::s_info) { RuntimeObjectImp* imp = static_cast<RuntimeObjectImp*>(object); CInstance* instance = static_cast<CInstance*>(imp->getInternalInstance()); if (instance) { NPObject* obj = instance->getObject(); _NPN_RetainObject(obj); OBJECT_TO_NPVARIANT(obj, *result); } } else { JSGlobalObject* globalObject = exec->dynamicGlobalObject(); RootObject* rootObject = findRootObject(globalObject); if (rootObject) { NPObject* npObject = _NPN_CreateScriptObject(0, object, rootObject); OBJECT_TO_NPVARIANT(npObject, *result); } } } }
void tst_QDeclarativeDebug::setMethodBody() { QDeclarativeDebugObjectReference obj = findRootObject(2); QObject *root = m_components.at(2); // Without args { QVariant rv; QVERIFY(QMetaObject::invokeMethod(root, "myMethodNoArgs", Qt::DirectConnection, Q_RETURN_ARG(QVariant, rv))); QVERIFY(rv == QVariant(qreal(3))); QVERIFY(m_dbg->setMethodBody(obj.debugId(), "myMethodNoArgs", "return 7")); QTest::qWait(100); QVERIFY(QMetaObject::invokeMethod(root, "myMethodNoArgs", Qt::DirectConnection, Q_RETURN_ARG(QVariant, rv))); QVERIFY(rv == QVariant(qreal(7))); } // With args { QVariant rv; QVERIFY(QMetaObject::invokeMethod(root, "myMethod", Qt::DirectConnection, Q_RETURN_ARG(QVariant, rv), Q_ARG(QVariant, QVariant(19)))); QVERIFY(rv == QVariant(qreal(28))); QVERIFY(m_dbg->setMethodBody(obj.debugId(), "myMethod", "return a + 7")); QTest::qWait(100); QVERIFY(QMetaObject::invokeMethod(root, "myMethod", Qt::DirectConnection, Q_RETURN_ARG(QVariant, rv), Q_ARG(QVariant, QVariant(19)))); QVERIFY(rv == QVariant(qreal(26))); } }
void tst_QDeclarativeDebug::watch_expression() { QFETCH(QString, expr); QFETCH(int, increment); QFETCH(int, incrementCount); int origWidth = m_rootItem->property("width").toInt(); QDeclarativeDebugObjectReference obj = findRootObject(); QDeclarativeDebugObjectExpressionWatch *watch; QDeclarativeEngineDebug *unconnected = new QDeclarativeEngineDebug(0); watch = unconnected->addWatch(obj, expr, this); QCOMPARE(watch->state(), QDeclarativeDebugWatch::Dead); delete watch; delete unconnected; watch = m_dbg->addWatch(QDeclarativeDebugObjectReference(), expr, this); QVERIFY(QDeclarativeDebugTest::waitForSignal(watch, SIGNAL(stateChanged(QDeclarativeDebugWatch::State)))); QCOMPARE(watch->state(), QDeclarativeDebugWatch::Inactive); delete watch; watch = m_dbg->addWatch(obj, expr, this); QCOMPARE(watch->state(), QDeclarativeDebugWatch::Waiting); QCOMPARE(watch->objectDebugId(), obj.debugId()); QCOMPARE(watch->expression(), expr); QSignalSpy spyState(watch, SIGNAL(stateChanged(QDeclarativeDebugWatch::State))); QSignalSpy spy(watch, SIGNAL(valueChanged(QByteArray,QVariant))); int expectedSpyCount = incrementCount + 1; // should also get signal with expression's initial value int width = origWidth; for (int i=0; i<incrementCount+1; i++) { if (i > 0) { width += increment; m_rootItem->setProperty("width", width); } if (!QDeclarativeDebugTest::waitForSignal(watch, SIGNAL(valueChanged(QByteArray,QVariant)))) QFAIL("Did not receive valueChanged() for expression"); } if (spyState.count() == 0) QVERIFY(QDeclarativeDebugTest::waitForSignal(watch, SIGNAL(stateChanged(QDeclarativeDebugWatch::State)))); QCOMPARE(spyState.count(), 1); QCOMPARE(watch->state(), QDeclarativeDebugWatch::Active); m_dbg->removeWatch(watch); delete watch; // restore original value and verify spy doesn't get a signal since watch has been removed m_rootItem->setProperty("width", origWidth); QTest::qWait(100); QCOMPARE(spy.count(), expectedSpyCount); width = origWidth + increment; for (int i=0; i<spy.count(); i++) { QCOMPARE(spy.at(i).at(1).value<QVariant>().toInt(), width); width += increment; } }