aboutsummaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorJ-P Nurmi <jpnurmi@theqtcompany.com>2015-05-18 17:37:19 +0200
committerJ-P Nurmi <jpnurmi@theqtcompany.com>2015-06-10 06:56:18 +0000
commiteb7db5934b453eea2946ed7ae9a188c44467cf23 (patch)
treebeca3748a6fab9dadd4c4cb9d191f8c146e070b4 /tests
parentf12c07216e25f9a326000e45583b9d5216945ee7 (diff)
ObjectModel: add API for dynamic changes
Following the ListModel API: - object get(index) - append(object) - insert(int index, object) - move(int from, int to, int n) - remove(int index, int n) [ChangeLog][QtQml][ObjectModel] Added get(), append(), insert(), move() and remove() methods. Change-Id: I592e55b7c4c933a1100191bf5a9405944b347172 Reviewed-by: Alan Alpert <aalpert@blackberry.com> Reviewed-by: Gabriel de Dietrich <gabriel.dedietrich@theqtcompany.com>
Diffstat (limited to 'tests')
-rw-r--r--tests/auto/qml/qml.pro3
-rw-r--r--tests/auto/qml/qqmlobjectmodel/qqmlobjectmodel.pro10
-rw-r--r--tests/auto/qml/qqmlobjectmodel/tst_qqmlobjectmodel.cpp134
-rw-r--r--tests/auto/qmltest/objectmodel/tst_objectmodel.qml100
-rw-r--r--tests/auto/quick/qquicklistview/data/objectmodel.qml24
-rw-r--r--tests/auto/quick/qquicklistview/tst_qquicklistview.cpp62
-rw-r--r--tests/auto/quick/qquickrepeater/data/objectmodel.qml28
-rw-r--r--tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp60
8 files changed, 420 insertions, 1 deletions
diff --git a/tests/auto/qml/qml.pro b/tests/auto/qml/qml.pro
index a5c3211f0d..d9d31ae267 100644
--- a/tests/auto/qml/qml.pro
+++ b/tests/auto/qml/qml.pro
@@ -59,7 +59,8 @@ PRIVATETESTS += \
qqmlenginecleanup \
v4misc \
qqmltranslation \
- qqmlimport
+ qqmlimport \
+ qqmlobjectmodel
qtHaveModule(widgets) {
PUBLICTESTS += \
diff --git a/tests/auto/qml/qqmlobjectmodel/qqmlobjectmodel.pro b/tests/auto/qml/qqmlobjectmodel/qqmlobjectmodel.pro
new file mode 100644
index 0000000000..f8232f8854
--- /dev/null
+++ b/tests/auto/qml/qqmlobjectmodel/qqmlobjectmodel.pro
@@ -0,0 +1,10 @@
+CONFIG += testcase
+TARGET = tst_qqmlobjectmodel
+osx:CONFIG -= app_bundle
+
+SOURCES += tst_qqmlobjectmodel.cpp
+
+CONFIG += parallel_test
+
+QT += qml testlib
+QT += core-private qml-private
diff --git a/tests/auto/qml/qqmlobjectmodel/tst_qqmlobjectmodel.cpp b/tests/auto/qml/qqmlobjectmodel/tst_qqmlobjectmodel.cpp
new file mode 100644
index 0000000000..001739e38d
--- /dev/null
+++ b/tests/auto/qml/qqmlobjectmodel/tst_qqmlobjectmodel.cpp
@@ -0,0 +1,134 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** 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 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <QtQml/private/qqmlobjectmodel_p.h>
+#include <QtTest/qsignalspy.h>
+#include <QtTest/qtest.h>
+
+class tst_QQmlObjectModel : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void changes();
+};
+
+static bool compareItems(QQmlObjectModel *model, const QObjectList &items)
+{
+ for (int i = 0; i < items.count(); ++i) {
+ if (model->get(i) != items.at(i))
+ return false;
+ }
+ return true;
+}
+
+void tst_QQmlObjectModel::changes()
+{
+ QQmlObjectModel model;
+
+ QSignalSpy countSpy(&model, SIGNAL(countChanged()));
+ QSignalSpy childrenSpy(&model, SIGNAL(childrenChanged()));
+
+ int count = 0;
+ int countSignals = 0;
+ int childrenSignals = 0;
+
+ QObjectList items;
+ QObject item0, item1, item2, item3;
+
+ // append(item0) -> [item0]
+ model.append(&item0); items.append(&item0);
+ QCOMPARE(model.count(), ++count);
+ QVERIFY(compareItems(&model, items));
+ QCOMPARE(countSpy.count(), ++countSignals);
+ QCOMPARE(childrenSpy.count(), ++childrenSignals);
+
+ // insert(0, item1) -> [item1, item0]
+ model.insert(0, &item1); items.insert(0, &item1);
+ QCOMPARE(model.count(), ++count);
+ QVERIFY(compareItems(&model, items));
+ QCOMPARE(countSpy.count(), ++countSignals);
+ QCOMPARE(childrenSpy.count(), ++childrenSignals);
+
+ // append(item2) -> [item1, item0, item2]
+ model.append(&item2); items.append(&item2);
+ QCOMPARE(model.count(), ++count);
+ QVERIFY(compareItems(&model, items));
+ QCOMPARE(countSpy.count(), ++countSignals);
+ QCOMPARE(childrenSpy.count(), ++childrenSignals);
+
+ // insert(2, item3) -> [item1, item0, item3, item2]
+ model.insert(2, &item3); items.insert(2, &item3);
+ QCOMPARE(model.count(), ++count);
+ QVERIFY(compareItems(&model, items));
+ QCOMPARE(countSpy.count(), ++countSignals);
+ QCOMPARE(childrenSpy.count(), ++childrenSignals);
+
+ // move(0, 1) -> [item0, item1, item3, item2]
+ model.move(0, 1); items.move(0, 1);
+ QCOMPARE(model.count(), count);
+ QVERIFY(compareItems(&model, items));
+ QCOMPARE(countSpy.count(), countSignals);
+ QCOMPARE(childrenSpy.count(), ++childrenSignals);
+
+ // move(3, 2) -> [item0, item1, item2, item3]
+ model.move(3, 2); items.move(3, 2);
+ QCOMPARE(model.count(), count);
+ QVERIFY(compareItems(&model, items));
+ QCOMPARE(countSpy.count(), countSignals);
+ QCOMPARE(childrenSpy.count(), ++childrenSignals);
+
+ // remove(0) -> [item1, item2, item3]
+ model.remove(0); items.removeAt(0);
+ QCOMPARE(model.count(), --count);
+ QVERIFY(compareItems(&model, items));
+ QCOMPARE(countSpy.count(), ++countSignals);
+ QCOMPARE(childrenSpy.count(), ++childrenSignals);
+
+ // remove(2) -> [item1, item2]
+ model.remove(2); items.removeAt(2);
+ QCOMPARE(model.count(), --count);
+ QVERIFY(compareItems(&model, items));
+ QCOMPARE(countSpy.count(), ++countSignals);
+ QCOMPARE(childrenSpy.count(), ++childrenSignals);
+
+ // clear() -> []
+ model.clear(); items.clear();
+ QCOMPARE(model.count(), 0);
+ QVERIFY(compareItems(&model, items));
+ QCOMPARE(countSpy.count(), ++countSignals);
+ QCOMPARE(childrenSpy.count(), ++childrenSignals);
+}
+
+QTEST_MAIN(tst_QQmlObjectModel)
+
+#include "tst_qqmlobjectmodel.moc"
diff --git a/tests/auto/qmltest/objectmodel/tst_objectmodel.qml b/tests/auto/qmltest/objectmodel/tst_objectmodel.qml
new file mode 100644
index 0000000000..e8205a1486
--- /dev/null
+++ b/tests/auto/qmltest/objectmodel/tst_objectmodel.qml
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQml 2.1
+import QtQml.Models 2.3
+import QtTest 1.1
+
+TestCase {
+ name: "ObjectModel"
+
+ ObjectModel {
+ id: model
+ QtObject { id: static0 }
+ QtObject { id: static1 }
+ QtObject { id: static2 }
+ }
+
+ Component { id: object; QtObject { } }
+
+ function test_attached_index() {
+ compare(model.count, 3)
+ compare(static0.ObjectModel.index, 0)
+ compare(static1.ObjectModel.index, 1)
+ compare(static2.ObjectModel.index, 2)
+
+ var dynamic0 = object.createObject(model, {objectName: "dynamic0"})
+ compare(dynamic0.ObjectModel.index, -1)
+ model.append(dynamic0) // -> [static0, static1, static2, dynamic0]
+ compare(model.count, 4)
+ for (var i = 0; i < model.count; ++i)
+ compare(model.get(i).ObjectModel.index, i)
+
+ var dynamic1 = object.createObject(model, {objectName: "dynamic1"})
+ compare(dynamic1.ObjectModel.index, -1)
+ model.insert(0, dynamic1) // -> [dynamic1, static0, static1, static2, dynamic0]
+ compare(model.count, 5)
+ for (i = 0; i < model.count; ++i)
+ compare(model.get(i).ObjectModel.index, i)
+
+ model.move(1, 3) // -> [dynamic1, static1, static2, static0, dynamic0]
+ compare(model.count, 5)
+ for (i = 0; i < model.count; ++i)
+ compare(model.get(i).ObjectModel.index, i)
+
+ model.move(4, 0) // -> [dynamic0, dynamic1, static1, static2, static0]
+ compare(model.count, 5)
+ for (i = 0; i < model.count; ++i)
+ compare(model.get(i).ObjectModel.index, i)
+
+ model.remove(1) // -> [dynamic0, static1, static2, static0]
+ compare(model.count, 4)
+ compare(dynamic1.ObjectModel.index, -1)
+ for (i = 0; i < model.count; ++i)
+ compare(model.get(i).ObjectModel.index, i)
+
+ model.clear()
+ compare(static0.ObjectModel.index, -1)
+ compare(static1.ObjectModel.index, -1)
+ compare(static2.ObjectModel.index, -1)
+ compare(dynamic0.ObjectModel.index, -1)
+ compare(dynamic1.ObjectModel.index, -1)
+ }
+}
diff --git a/tests/auto/quick/qquicklistview/data/objectmodel.qml b/tests/auto/quick/qquicklistview/data/objectmodel.qml
new file mode 100644
index 0000000000..5c23d64cd3
--- /dev/null
+++ b/tests/auto/quick/qquicklistview/data/objectmodel.qml
@@ -0,0 +1,24 @@
+import QtQuick 2.0
+import QtQml.Models 2.1
+
+ListView {
+ width: 360
+ height: 360
+ model: ObjectModel {
+ Rectangle {
+ width: 20
+ height: 20
+ color: "red"
+ }
+ Rectangle {
+ width: 20
+ height: 20
+ color: "green"
+ }
+ Rectangle {
+ width: 20
+ height: 20
+ color: "blue"
+ }
+ }
+}
diff --git a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp
index 3e19b005b7..28025c3090 100644
--- a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp
+++ b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp
@@ -240,6 +240,7 @@ private slots:
void QTBUG_39492();
void jsArrayChange();
+ void objectModel();
private:
template <class T> void items(const QUrl &source);
@@ -8001,6 +8002,67 @@ void tst_QQuickListView::jsArrayChange()
QCOMPARE(spy.count(), 1);
}
+static bool compareObjectModel(QQuickListView *listview, QQmlObjectModel *model)
+{
+ if (listview->count() != model->count())
+ return false;
+ for (int i = 0; i < listview->count(); ++i) {
+ listview->setCurrentIndex(i);
+ if (listview->currentItem() != model->get(i))
+ return false;
+ }
+ return true;
+}
+
+void tst_QQuickListView::objectModel()
+{
+ QQmlEngine engine;
+ QQmlComponent component(&engine, testFileUrl("objectmodel.qml"));
+
+ QQuickListView *listview = qobject_cast<QQuickListView *>(component.create());
+ QVERIFY(listview);
+
+ QQmlObjectModel *model = listview->model().value<QQmlObjectModel *>();
+ QVERIFY(model);
+
+ listview->setCurrentIndex(0);
+ QVERIFY(listview->currentItem());
+ QCOMPARE(listview->currentItem()->property("color").toString(), QColor("red").name());
+
+ listview->setCurrentIndex(1);
+ QVERIFY(listview->currentItem());
+ QCOMPARE(listview->currentItem()->property("color").toString(), QColor("green").name());
+
+ listview->setCurrentIndex(2);
+ QVERIFY(listview->currentItem());
+ QCOMPARE(listview->currentItem()->property("color").toString(), QColor("blue").name());
+
+ QQuickItem *item0 = new QQuickItem(listview);
+ item0->setSize(QSizeF(20, 20));
+ model->append(item0);
+ QCOMPARE(model->count(), 4);
+ QVERIFY(compareObjectModel(listview, model));
+
+ QQuickItem *item1 = new QQuickItem(listview);
+ item1->setSize(QSizeF(20, 20));
+ model->insert(0, item1);
+ QCOMPARE(model->count(), 5);
+ QVERIFY(compareObjectModel(listview, model));
+
+ model->move(1, 2, 3);
+ QVERIFY(compareObjectModel(listview, model));
+
+ model->remove(2, 2);
+ QCOMPARE(model->count(), 3);
+ QVERIFY(compareObjectModel(listview, model));
+
+ model->clear();
+ QCOMPARE(model->count(), 0);
+ QCOMPARE(listview->count(), 0);
+
+ delete listview;
+}
+
QTEST_MAIN(tst_QQuickListView)
#include "tst_qquicklistview.moc"
diff --git a/tests/auto/quick/qquickrepeater/data/objectmodel.qml b/tests/auto/quick/qquickrepeater/data/objectmodel.qml
new file mode 100644
index 0000000000..780f53e802
--- /dev/null
+++ b/tests/auto/quick/qquickrepeater/data/objectmodel.qml
@@ -0,0 +1,28 @@
+import QtQuick 2.0
+import QtQml.Models 2.1
+
+Row {
+ width: 360
+ height: 360
+
+ Repeater {
+ objectName: "repeater"
+ model: ObjectModel {
+ Rectangle {
+ width: 20
+ height: 20
+ color: "red"
+ }
+ Rectangle {
+ width: 20
+ height: 20
+ color: "green"
+ }
+ Rectangle {
+ width: 20
+ height: 20
+ color: "blue"
+ }
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp b/tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp
index 71b1ffa0d6..3d0bb8f1ed 100644
--- a/tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp
+++ b/tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp
@@ -41,6 +41,7 @@
#include <private/qquickrepeater_p.h>
#include <QtQuick/private/qquicktext_p.h>
#include <QtQml/private/qqmllistmodel_p.h>
+#include <QtQml/private/qqmlobjectmodel_p.h>
#include "../../shared/util.h"
#include "../shared/viewtestutil.h"
@@ -77,6 +78,7 @@ private slots:
void clearRemovalOrder();
void destroyCount();
void stackingOrder();
+ void objectModel();
};
class TestObject : public QObject
@@ -913,6 +915,64 @@ void tst_QQuickRepeater::stackingOrder()
} while (count < 3);
}
+static bool compareObjectModel(QQuickRepeater *repeater, QQmlObjectModel *model)
+{
+ if (repeater->count() != model->count())
+ return false;
+ for (int i = 0; i < repeater->count(); ++i) {
+ if (repeater->itemAt(i) != model->get(i))
+ return false;
+ }
+ return true;
+}
+
+void tst_QQuickRepeater::objectModel()
+{
+ QQmlEngine engine;
+ QQmlComponent component(&engine, testFileUrl("objectmodel.qml"));
+
+ QQuickItem *positioner = qobject_cast<QQuickItem *>(component.create());
+ QVERIFY(positioner);
+
+ QQuickRepeater *repeater = findItem<QQuickRepeater>(positioner, "repeater");
+ QVERIFY(repeater);
+
+ QQmlObjectModel *model = repeater->model().value<QQmlObjectModel *>();
+ QVERIFY(model);
+
+ QVERIFY(repeater->itemAt(0));
+ QVERIFY(repeater->itemAt(1));
+ QVERIFY(repeater->itemAt(2));
+ QCOMPARE(repeater->itemAt(0)->property("color").toString(), QColor("red").name());
+ QCOMPARE(repeater->itemAt(1)->property("color").toString(), QColor("green").name());
+ QCOMPARE(repeater->itemAt(2)->property("color").toString(), QColor("blue").name());
+
+ QQuickItem *item0 = new QQuickItem(positioner);
+ item0->setSize(QSizeF(20, 20));
+ model->append(item0);
+ QCOMPARE(model->count(), 4);
+ QVERIFY(compareObjectModel(repeater, model));
+
+ QQuickItem *item1 = new QQuickItem(positioner);
+ item1->setSize(QSizeF(20, 20));
+ model->insert(0, item1);
+ QCOMPARE(model->count(), 5);
+ QVERIFY(compareObjectModel(repeater, model));
+
+ model->move(1, 2, 3);
+ QVERIFY(compareObjectModel(repeater, model));
+
+ model->remove(2, 2);
+ QCOMPARE(model->count(), 3);
+ QVERIFY(compareObjectModel(repeater, model));
+
+ model->clear();
+ QCOMPARE(model->count(), 0);
+ QCOMPARE(repeater->count(), 0);
+
+ delete positioner;
+}
+
QTEST_MAIN(tst_QQuickRepeater)
#include "tst_qquickrepeater.moc"