Fix crash calling VisualDataGroup.setGroups during initialization.
authorAndrew den Exter <andrew.den-exter@nokia.com>
Fri, 25 Nov 2011 06:09:38 +0000 (16:09 +1000)
committerQt by Nokia <qt-info@nokia.com>
Fri, 25 Nov 2011 07:10:20 +0000 (08:10 +0100)
A VisualDataModel's meta type is constructed in componentComplete(),
avoid accessing it before then.

Change-Id: Ic9fdfa3c458d5da3014289b777f74df87aa97103
Reviewed-by: Martin Jones <martin.jones@nokia.com>

src/declarative/items/qquickvisualdatamodel.cpp
tests/auto/declarative/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp

index 7d0abfc..ce85484 100644 (file)
@@ -2116,7 +2116,7 @@ void QQuickVisualDataGroup::remove(QDeclarativeV8Function *args)
 bool QQuickVisualDataGroupPrivate::parseGroupArgs(
         QDeclarativeV8Function *args, int *index, int *count, int *groups) const
 {
-    if (!model)
+    if (!model || !QQuickVisualDataModelPrivate::get(model)->m_cacheMetaType)
         return false;
 
     if (args->Length() < 2)
@@ -2300,6 +2300,7 @@ void QQuickVisualDataGroup::move(QDeclarativeV8Function *args)
         model->itemsMoved(removes, inserts);
         model->emitChanges();
     }
+
 }
 
 /*!
index 44759d4..e382a01 100644 (file)
@@ -146,6 +146,7 @@ private slots:
     void onChanged_data();
     void onChanged();
     void create();
+    void incompleteModel();
 
 private:
     template <int N> void groups_verify(
@@ -563,7 +564,7 @@ void tst_qquickvisualdatamodel::modelProperties()
 
         QUrl source(QUrl::fromLocalFile(TESTDATA("modelproperties2.qml")));
 
-        //3 items, 3 warnings each
+        //3 items, 3 i each
         QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":13: ReferenceError: Can't find variable: modelData");
         QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":13: ReferenceError: Can't find variable: modelData");
         QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":13: ReferenceError: Can't find variable: modelData");
@@ -1789,6 +1790,49 @@ void tst_qquickvisualdatamodel::create()
     QCOMPARE(evaluate<bool>(delegate, "destroyed"), false);
 }
 
+
+void tst_qquickvisualdatamodel::incompleteModel()
+{
+    // VisualDataModel is first populated in componentComplete.  Verify various functions are
+    // harmlessly ignored until then.
+
+    QDeclarativeComponent component(&engine);
+    component.setData("import QtQuick 2.0\n VisualDataModel {}", QUrl::fromLocalFile(TESTDATA("")));
+
+    QScopedPointer<QObject> object(component.beginCreate(engine.rootContext()));
+
+    QQuickVisualDataModel *model = qobject_cast<QQuickVisualDataModel *>(object.data());
+    QVERIFY(model);
+
+    QSignalSpy itemsSpy(model->items(), SIGNAL(countChanged()));
+    QSignalSpy persistedItemsSpy(model->items(), SIGNAL(countChanged()));
+
+    evaluate<void>(model, "items.removeGroups(0, items.count, \"items\")");
+    QCOMPARE(itemsSpy.count(), 0);
+    QCOMPARE(persistedItemsSpy.count(), 0);
+
+    evaluate<void>(model, "items.setGroups(0, items.count, \"persistedItems\")");
+    QCOMPARE(itemsSpy.count(), 0);
+    QCOMPARE(persistedItemsSpy.count(), 0);
+
+    evaluate<void>(model, "items.addGroups(0, items.count, \"persistedItems\")");
+    QCOMPARE(itemsSpy.count(), 0);
+    QCOMPARE(persistedItemsSpy.count(), 0);
+
+    evaluate<void>(model, "items.remove(0, items.count)");
+    QCOMPARE(itemsSpy.count(), 0);
+    QCOMPARE(persistedItemsSpy.count(), 0);
+
+    evaluate<void>(model, "items.insert([ \"color\": \"blue\" ])");
+    QCOMPARE(itemsSpy.count(), 0);
+    QCOMPARE(persistedItemsSpy.count(), 0);
+
+    QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: get: index out of range");
+    QVERIFY(evaluate<bool>(model, "items.get(0) === undefined"));
+
+    component.completeCreate();
+}
+
 template<typename T>
 T *tst_qquickvisualdatamodel::findItem(QQuickItem *parent, const QString &objectName, int index)
 {