void tst_QDeclarativeDebug::recursiveCompareObjects(const QDeclarativeDebugObjectReference &a, const QDeclarativeDebugObjectReference &b) const { QCOMPARE(a.debugId(), b.debugId()); QCOMPARE(a.className(), b.className()); QCOMPARE(a.name(), b.name()); QCOMPARE(a.contextDebugId(), b.contextDebugId()); QCOMPARE(a.source().url(), b.source().url()); QCOMPARE(a.source().lineNumber(), b.source().lineNumber()); QCOMPARE(a.source().columnNumber(), b.source().columnNumber()); QCOMPARE(a.properties().count(), b.properties().count()); QCOMPARE(a.children().count(), b.children().count()); QList<QDeclarativeDebugPropertyReference> aprops = a.properties(); QList<QDeclarativeDebugPropertyReference> bprops = b.properties(); for (int i=0; i<aprops.count(); i++) compareProperties(aprops[i], bprops[i]); for (int i=0; i<a.children().count(); i++) recursiveCompareObjects(a.children()[i], b.children()[i]); }
QString ObjectPropertiesView::propertyBaseClass(const QDeclarativeDebugObjectReference &object, const QDeclarativeDebugPropertyReference &property, int &depth) { ExtensionSystem::PluginManager *pluginManager = ExtensionSystem::PluginManager::instance(); QmlJSEditor::ModelManagerInterface *modelManager = pluginManager->getObject<QmlJSEditor::ModelManagerInterface>(); QmlJS::Snapshot snapshot = modelManager->snapshot(); QmlJS::Document::Ptr document = snapshot.document(object.source().url().path()); if (document.isNull()) { QFile inFile(object.source().url().path()); QString contents; if (inFile.open(QIODevice::ReadOnly)) { QTextStream ins(&inFile); contents = ins.readAll(); inFile.close(); } document = QmlJS::Document::create(object.source().url().path()); document->setSource(contents); if (!document->parse()) return QString(); snapshot.insert(document); } PropertyTypeFinder find(document, snapshot, modelManager->importPaths()); QString baseClassName = find(object.source().lineNumber(), object.source().columnNumber(), property.name()); if (baseClassName.isEmpty()) { if (!object.idString().isEmpty()) baseClassName = object.idString(); else baseClassName = QString("<%1>").arg(object.className()); } depth = find.depth(); return baseClassName; }
void tst_QDeclarativeDebug::recursiveObjectTest(QObject *o, const QDeclarativeDebugObjectReference &oref, bool recursive) const { const QMetaObject *meta = o->metaObject(); QDeclarativeType *type = QDeclarativeMetaType::qmlType(meta); QString className = type ? QString(type->qmlTypeName()) : QString(meta->className()); className = className.mid(className.lastIndexOf(QLatin1Char('/'))+1); QCOMPARE(oref.debugId(), QDeclarativeDebugService::idForObject(o)); QCOMPARE(oref.name(), o->objectName()); QCOMPARE(oref.className(), className); QCOMPARE(oref.contextDebugId(), QDeclarativeDebugService::idForObject(qmlContext(o))); const QObjectList &children = o->children(); for (int i=0; i<children.count(); i++) { QObject *child = children[i]; if (!qmlContext(child)) continue; int debugId = QDeclarativeDebugService::idForObject(child); QVERIFY(debugId >= 0); QDeclarativeDebugObjectReference cref; foreach (const QDeclarativeDebugObjectReference &ref, oref.children()) { if (ref.debugId() == debugId) { cref = ref; break; } } QVERIFY(cref.debugId() >= 0); if (recursive) recursiveObjectTest(child, cref, true); } foreach (const QDeclarativeDebugPropertyReference &p, oref.properties()) { QCOMPARE(p.objectDebugId(), QDeclarativeDebugService::idForObject(o)); // signal properties are fake - they are generated from QDeclarativeBoundSignal children if (p.name().startsWith("on") && p.name().length() > 2 && p.name()[2].isUpper()) { QVERIFY(p.value().toString().startsWith('{') && p.value().toString().endsWith('}')); QVERIFY(p.valueTypeName().isEmpty()); QVERIFY(p.binding().isEmpty()); QVERIFY(!p.hasNotifySignal()); continue; } QMetaProperty pmeta = meta->property(meta->indexOfProperty(p.name().toUtf8().constData())); QCOMPARE(p.name(), QString::fromUtf8(pmeta.name())); if (pmeta.type() > 0 && pmeta.type() < QVariant::UserType) // TODO test complex types QCOMPARE(p.value(), pmeta.read(o)); if (p.name() == "parent") QVERIFY(p.valueTypeName() == "QGraphicsObject*" || p.valueTypeName() == "QDeclarativeItem*"); else QCOMPARE(p.valueTypeName(), QString::fromUtf8(pmeta.typeName())); QDeclarativeAbstractBinding *binding = QDeclarativePropertyPrivate::binding(QDeclarativeProperty(o, p.name())); if (binding) QCOMPARE(binding->expression(), p.binding()); QCOMPARE(p.hasNotifySignal(), pmeta.hasNotifySignal()); QVERIFY(pmeta.isValid()); } }