QDeclarativeDebugObjectReference tst_QDeclarativeDebug::findRootObject(int context, bool recursive) { QDeclarativeDebugEnginesQuery *q_engines = m_dbg->queryAvailableEngines(this); waitForQuery(q_engines); if (q_engines->engines().count() == 0) return QDeclarativeDebugObjectReference(); QDeclarativeDebugRootContextQuery *q_context = m_dbg->queryRootContexts(q_engines->engines()[0].debugId(), this); waitForQuery(q_context); if (q_context->rootContext().objects().count() == 0) return QDeclarativeDebugObjectReference(); QDeclarativeDebugObjectQuery *q_obj = recursive ? m_dbg->queryObjectRecursive(q_context->rootContext().objects()[context], this) : m_dbg->queryObject(q_context->rootContext().objects()[context], this); waitForQuery(q_obj); QDeclarativeDebugObjectReference result = q_obj->object(); delete q_engines; delete q_context; delete q_obj; return result; }
void QDeclarativeEngineDebugPrivate::decode(QDataStream &ds, QDeclarativeDebugObjectReference &o, bool simple) { QDeclarativeEngineDebugServer::QDeclarativeObjectData data; ds >> data; o.m_debugId = data.objectId; o.m_class = data.objectType; o.m_idString = data.idString; o.m_name = data.objectName; o.m_source.m_url = data.url; o.m_source.m_lineNumber = data.lineNumber; o.m_source.m_columnNumber = data.columnNumber; o.m_contextDebugId = data.contextId; if (simple) return; int childCount; bool recur; ds >> childCount >> recur; for (int ii = 0; ii < childCount; ++ii) { o.m_children.append(QDeclarativeDebugObjectReference()); decode(ds, o.m_children.last(), !recur); } int propCount; ds >> propCount; for (int ii = 0; ii < propCount; ++ii) { QDeclarativeEngineDebugServer::QDeclarativeObjectProperty data; ds >> data; QDeclarativeDebugPropertyReference prop; prop.m_objectDebugId = o.m_debugId; prop.m_name = data.name; prop.m_binding = data.binding; prop.m_hasNotifySignal = data.hasNotifySignal; prop.m_valueTypeName = data.valueTypeName; switch (data.type) { case QDeclarativeEngineDebugServer::QDeclarativeObjectProperty::Basic: case QDeclarativeEngineDebugServer::QDeclarativeObjectProperty::List: case QDeclarativeEngineDebugServer::QDeclarativeObjectProperty::SignalProperty: { prop.m_value = data.value; break; } case QDeclarativeEngineDebugServer::QDeclarativeObjectProperty::Object: { QDeclarativeDebugObjectReference obj; obj.m_debugId = prop.m_value.toInt(); prop.m_value = qVariantFromValue(obj); break; } case QDeclarativeEngineDebugServer::QDeclarativeObjectProperty::Unknown: break; } o.m_properties << prop; } }
void ObjectPropertiesView::clear() { setObject(QDeclarativeDebugObjectReference()); }
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; } }
void tst_QDeclarativeDebug::watch_object() { QDeclarativeDebugEnginesQuery *q_engines = m_dbg->queryAvailableEngines(this); waitForQuery(q_engines); QVERIFY(q_engines->engines().count() > 0); QDeclarativeDebugRootContextQuery *q_context = m_dbg->queryRootContexts(q_engines->engines()[0].debugId(), this); waitForQuery(q_context); QVERIFY(q_context->rootContext().objects().count() > 0); QDeclarativeDebugObjectQuery *q_obj = m_dbg->queryObject(q_context->rootContext().objects()[0], this); waitForQuery(q_obj); QDeclarativeDebugObjectReference obj = q_obj->object(); delete q_engines; delete q_context; delete q_obj; QDeclarativeDebugWatch *watch; QDeclarativeEngineDebug *unconnected = new QDeclarativeEngineDebug(0); watch = unconnected->addWatch(obj, this); QCOMPARE(watch->state(), QDeclarativeDebugWatch::Dead); delete watch; delete unconnected; watch = m_dbg->addWatch(QDeclarativeDebugObjectReference(), this); QVERIFY(QDeclarativeDebugTest::waitForSignal(watch, SIGNAL(stateChanged(QDeclarativeDebugWatch::State)))); QCOMPARE(watch->state(), QDeclarativeDebugWatch::Inactive); delete watch; watch = m_dbg->addWatch(obj, this); QCOMPARE(watch->state(), QDeclarativeDebugWatch::Waiting); QCOMPARE(watch->objectDebugId(), obj.debugId()); QSignalSpy spy(watch, SIGNAL(valueChanged(QByteArray,QVariant))); int origWidth = m_rootItem->property("width").toInt(); int origHeight = m_rootItem->property("height").toInt(); m_rootItem->setProperty("width", origWidth*2); m_rootItem->setProperty("height", origHeight*2); // stateChanged() is received before any valueChanged() signals QVERIFY(QDeclarativeDebugTest::waitForSignal(watch, SIGNAL(stateChanged(QDeclarativeDebugWatch::State)))); QCOMPARE(watch->state(), QDeclarativeDebugWatch::Active); 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(watch); delete watch; // 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); }