diff options
Diffstat (limited to 'tests/auto')
269 files changed, 12429 insertions, 6 deletions
diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro index a65c172..c1bf2f4 100644 --- a/tests/auto/auto.pro +++ b/tests/auto/auto.pro @@ -6,9 +6,11 @@ TEMPLATE = subdirs SUBDIRS += _networkselftest \ bic \ + dynamicobject \ collections \ compile \ compilerwarnings \ + dynamicobject \ exceptionsafety \ macgui \ macplist \ @@ -441,3 +443,5 @@ contains(QT_CONFIG, webkit): SUBDIRS += \ qwebpage SUBDIRS += math3d + +contains(QT_CONFIG, declarative): SUBDIRS += declarative diff --git a/tests/auto/declarative/.gitignore b/tests/auto/declarative/.gitignore new file mode 100644 index 0000000..c8bbd2f --- /dev/null +++ b/tests/auto/declarative/.gitignore @@ -0,0 +1,3 @@ +tst_* +!tst_*.* +tst_*~ diff --git a/tests/auto/declarative/anchors/anchors.pro b/tests/auto/declarative/anchors/anchors.pro new file mode 100644 index 0000000..7b22cfb --- /dev/null +++ b/tests/auto/declarative/anchors/anchors.pro @@ -0,0 +1,5 @@ +load(qttest_p4) +contains(QT_CONFIG,declarative): QT += declarative +SOURCES += tst_anchors.cpp + +DEFINES += SRCDIR=\\\"$$PWD\\\" diff --git a/tests/auto/declarative/anchors/data/anchors.qml b/tests/auto/declarative/anchors/data/anchors.qml new file mode 100644 index 0000000..6a87390 --- /dev/null +++ b/tests/auto/declarative/anchors/data/anchors.qml @@ -0,0 +1,115 @@ +Rect { + color: "white" + width: 240 + height: 320 + Rect { id: MasterRect; x: 26; width: 96; height: 20; color: "red" } + Rect { + id: Rect1 + y: 20; width: 10; height: 10 + anchors.left: MasterRect.left + } + Rect { + id: Rect2 + y: 20; width: 10; height: 10 + anchors.left: MasterRect.right + } + Rect { + id: Rect3 + y: 20; width: 10; height: 10 + anchors.left: MasterRect.horizontalCenter + } + Rect { + id: Rect4 + y: 30; width: 10; height: 10 + anchors.right: MasterRect.left + } + Rect { + id: Rect5 + y: 30; width: 10; height: 10 + anchors.right: MasterRect.right + } + Rect { + id: Rect6 + y: 30; width: 10; height: 10 + anchors.right: MasterRect.horizontalCenter + } + Rect { + id: Rect7 + y: 50; width: 10; height: 10 + anchors.left: parent.left + } + Rect { + id: Rect8 + y: 50; width: 10; height: 10 + anchors.left: parent.right + } + Rect { + id: Rect9 + y: 50; width: 10; height: 10 + anchors.left: parent.horizontalCenter + } + Rect { + id: Rect10 + y: 60; width: 10; height: 10 + anchors.right: parent.left + } + Rect { + id: Rect11 + y: 60; width: 10; height: 10 + anchors.right: parent.right + } + Rect { + id: Rect12 + y: 60; width: 10; height: 10 + anchors.right: parent.horizontalCenter + } + Rect { + id: Rect13 + x: 200; width: 10; height: 10 + anchors.top: MasterRect.bottom + } + Rect { + id: Rect14 + width: 10; height: 10; color: "steelblue" + anchors.verticalCenter: parent.verticalCenter + } + Rect { + id: Rect15 + y: 200; height: 10 + anchors.left: MasterRect.left + anchors.right: MasterRect.right + } + Rect { + id: Rect16 + y: 220; height: 10 + anchors.left: MasterRect.left + anchors.horizontalCenter: MasterRect.right + } + Rect { + id: Rect17 + y: 240; height: 10 + anchors.right: MasterRect.right + anchors.horizontalCenter: MasterRect.left + } + Rect { + id: Rect18 + x: 180; width: 10 + anchors.top: MasterRect.bottom + anchors.bottom: Rect12.top + } + Rect { + id: Rect19 + y: 70; width: 10; height: 10 + anchors.horizontalCenter: parent.horizontalCenter + } + Rect { + id: Rect20 + y: 70; width: 10; height: 10 + anchors.horizontalCenter: parent.right + } + Rect { + id: Rect21 + y: 70; width: 10; height: 10 + anchors.horizontalCenter: parent.left + } +} diff --git a/tests/auto/declarative/anchors/data/illegal1.qml b/tests/auto/declarative/anchors/data/illegal1.qml new file mode 100644 index 0000000..635bf95 --- /dev/null +++ b/tests/auto/declarative/anchors/data/illegal1.qml @@ -0,0 +1,10 @@ +Rect { + id: rect + width: 120; height: 200; color: "white" + Rect { id: TheRect; width: 100; height: 100 } + Rect { + anchors.left: TheRect.left + anchors.right: TheRect.right + anchors.horizontalCenter: TheRect.horizontalCenter + } +} diff --git a/tests/auto/declarative/anchors/data/illegal2.qml b/tests/auto/declarative/anchors/data/illegal2.qml new file mode 100644 index 0000000..425d0e4 --- /dev/null +++ b/tests/auto/declarative/anchors/data/illegal2.qml @@ -0,0 +1,11 @@ +Rect { + id: rect + width: 120; height: 200; color: "white" + Text { id: Text1; text: "Hello" } + Text { + id: Text2; + anchors.baseline: Text1.baseline; + anchors.top: Text1.top; + text: "World" + } +} diff --git a/tests/auto/declarative/anchors/data/illegal3.qml b/tests/auto/declarative/anchors/data/illegal3.qml new file mode 100644 index 0000000..fa48b78 --- /dev/null +++ b/tests/auto/declarative/anchors/data/illegal3.qml @@ -0,0 +1,10 @@ +Rect { + id: rect + width: 120; height: 200; color: "white" + Item { + Rect { id: TheRect; width: 100; height: 100 } + } + Rect { + anchors.left: TheRect.left + } +} diff --git a/tests/auto/declarative/anchors/data/loop1.qml b/tests/auto/declarative/anchors/data/loop1.qml new file mode 100644 index 0000000..a4de1bf --- /dev/null +++ b/tests/auto/declarative/anchors/data/loop1.qml @@ -0,0 +1,6 @@ +Rect { + id: rect + width: 120; height: 200; color: "white" + Text { id: Text1; anchors.right: Text2.right; text: "Hello" } + Text { id: Text2; anchors.right: Text1.right; anchors.rightMargin: 10; text: "World" } +} diff --git a/tests/auto/declarative/anchors/data/loop2.qml b/tests/auto/declarative/anchors/data/loop2.qml new file mode 100644 index 0000000..4b2c74e --- /dev/null +++ b/tests/auto/declarative/anchors/data/loop2.qml @@ -0,0 +1,18 @@ +Rect { + id: container; + width: 600; + height: 600; + + Image { + id: Image1 + source: "http://labs.trolltech.com/blogs/wp-content/uploads/2009/03/3311388091_ac2a257feb.jpg" + anchors.right: Image2.left + } + + Image { + id: Image2 + source: "http://labs.trolltech.com/blogs/wp-content/uploads/2009/03/oslo_groupphoto.jpg" + anchors.left: Image1.right + anchors.leftMargin: 20 + } +} diff --git a/tests/auto/declarative/anchors/tst_anchors.cpp b/tests/auto/declarative/anchors/tst_anchors.cpp new file mode 100644 index 0000000..587b4ab --- /dev/null +++ b/tests/auto/declarative/anchors/tst_anchors.cpp @@ -0,0 +1,166 @@ +#include <qtest.h> +#include <QtDeclarative/qmlengine.h> +#include <QtDeclarative/qmlcomponent.h> +#include <QtDeclarative/qfxview.h> +#include <QtDeclarative/qfxrect.h> + +class tst_anchors : public QObject +{ + Q_OBJECT +public: + tst_anchors() {} + + template<typename T> + T *findItem(QFxItem *parent, const QString &id); + +private slots: + void basicAnchors(); + void loops(); + void illegalSets(); +}; + +/* + Find an item with the specified id. +*/ +template<typename T> +T *tst_anchors::findItem(QFxItem *parent, const QString &id) +{ + const QMetaObject &mo = T::staticMetaObject; + for (int i = 0; i < parent->QSimpleCanvasItem::children().count(); ++i) { + QFxItem *item = qobject_cast<QFxItem*>(parent->QSimpleCanvasItem::children().at(i)); + if (mo.cast(item) && (id.isEmpty() || item->id() == id)) { + return static_cast<T*>(item); + } + item = findItem<T>(item, id); + if (item) + return static_cast<T*>(item); + } + + return 0; +} + +void tst_anchors::basicAnchors() +{ + QFxView *view = new QFxView; + view->setUrl(QUrl("file://" SRCDIR "/data/anchors.qml")); + + view->execute(); + qApp->processEvents(); + + //sibling horizontal + QCOMPARE(findItem<QFxRect>(view->root(), QLatin1String("Rect1"))->x(), 26.0); + QCOMPARE(findItem<QFxRect>(view->root(), QLatin1String("Rect2"))->x(), 122.0); + QCOMPARE(findItem<QFxRect>(view->root(), QLatin1String("Rect3"))->x(), 74.0); + QCOMPARE(findItem<QFxRect>(view->root(), QLatin1String("Rect4"))->x(), 16.0); + QCOMPARE(findItem<QFxRect>(view->root(), QLatin1String("Rect5"))->x(), 112.0); + QCOMPARE(findItem<QFxRect>(view->root(), QLatin1String("Rect6"))->x(), 64.0); + + //parent horizontal + QCOMPARE(findItem<QFxRect>(view->root(), QLatin1String("Rect7"))->x(), 0.0); + QCOMPARE(findItem<QFxRect>(view->root(), QLatin1String("Rect8"))->x(), 240.0); + QCOMPARE(findItem<QFxRect>(view->root(), QLatin1String("Rect9"))->x(), 120.0); + QCOMPARE(findItem<QFxRect>(view->root(), QLatin1String("Rect10"))->x(), -10.0); + QCOMPARE(findItem<QFxRect>(view->root(), QLatin1String("Rect11"))->x(), 230.0); + QCOMPARE(findItem<QFxRect>(view->root(), QLatin1String("Rect12"))->x(), 110.0); + + //vertical + QCOMPARE(findItem<QFxRect>(view->root(), QLatin1String("Rect13"))->y(), 20.0); + QCOMPARE(findItem<QFxRect>(view->root(), QLatin1String("Rect14"))->y(), 155.0); + + //stretch + QCOMPARE(findItem<QFxRect>(view->root(), QLatin1String("Rect15"))->x(), 26.0); + QCOMPARE(findItem<QFxRect>(view->root(), QLatin1String("Rect15"))->width(), 96.0); + QCOMPARE(findItem<QFxRect>(view->root(), QLatin1String("Rect16"))->x(), 26.0); + QCOMPARE(findItem<QFxRect>(view->root(), QLatin1String("Rect16"))->width(), 192.0); + QCOMPARE(findItem<QFxRect>(view->root(), QLatin1String("Rect17"))->x(), -70.0); + QCOMPARE(findItem<QFxRect>(view->root(), QLatin1String("Rect17"))->width(), 192.0); + + //vertical stretch + QCOMPARE(findItem<QFxRect>(view->root(), QLatin1String("Rect18"))->y(), 20.0); + QCOMPARE(findItem<QFxRect>(view->root(), QLatin1String("Rect18"))->height(), 40.0); + + //more parent horizontal + QCOMPARE(findItem<QFxRect>(view->root(), QLatin1String("Rect19"))->x(), 115.0); + QCOMPARE(findItem<QFxRect>(view->root(), QLatin1String("Rect20"))->x(), 235.0); + QCOMPARE(findItem<QFxRect>(view->root(), QLatin1String("Rect21"))->x(), -5.0); + + delete view; +} + +// mostly testing that we don't crash +void tst_anchors::loops() +{ + { + QFxView *view = new QFxView; + + view->setUrl(QUrl("file://" SRCDIR "/data/loop1.qml")); + + //### ignoreMessage doesn't seem to work + //QTest::ignoreMessage(QtWarningMsg, "QML QFxText (unknown location): Anchor loop detected on horizontal anchor."); + //QTest::ignoreMessage(QtWarningMsg, "QML QFxText (unknown location): Anchor loop detected on horizontal anchor."); + view->execute(); + qApp->processEvents(); + + delete view; + } + + { + QFxView *view = new QFxView; + + view->setUrl(QUrl("file://" SRCDIR "/data/loop2.qml")); + + //### ignoreMessage doesn't seem to work here + //QTest::ignoreMessage(QtWarningMsg, "QML QFxImage (unknown location): Anchor loop detected on horizontal anchor."); + //QTest::ignoreMessage(QtWarningMsg, "QML QFxImage (unknown location): Anchor loop detected on horizontal anchor."); + view->execute(); + qApp->processEvents(); + + delete view; + } +} + +void tst_anchors::illegalSets() +{ + { + QFxView *view = new QFxView; + + view->setUrl(QUrl("file://" SRCDIR "/data/illegal1.qml")); + + //### ignoreMessage doesn't seem to work + //QTest::ignoreMessage(QtWarningMsg, "QML QFxRect (unknown location): Can't specify left, right, and hcenter anchors."); + view->execute(); + qApp->processEvents(); + + delete view; + } + + { + QFxView *view = new QFxView; + + view->setUrl(QUrl("file://" SRCDIR "/data/illegal2.qml")); + + //### ignoreMessage doesn't seem to work here + //QTest::ignoreMessage(QtWarningMsg, "QML QFxText (unknown location): Baseline anchor can't be used in conjunction with top, bottom, or vcenter anchors."); + view->execute(); + //qApp->processEvents(); + + delete view; + } + + { + QFxView *view = new QFxView; + + view->setUrl(QUrl("file://" SRCDIR "/data/illegal3.qml")); + + //### ignoreMessage doesn't seem to work here + //QTest::ignoreMessage(QtWarningMsg, "Can't anchor to an item that isn't a parent or sibling."); + view->execute(); + qApp->processEvents(); + + delete view; + } +} + +QTEST_MAIN(tst_anchors) + +#include "tst_anchors.moc" diff --git a/tests/auto/declarative/datetimeformatter/datetimeformatter.pro b/tests/auto/declarative/datetimeformatter/datetimeformatter.pro new file mode 100644 index 0000000..e3d6cd0 --- /dev/null +++ b/tests/auto/declarative/datetimeformatter/datetimeformatter.pro @@ -0,0 +1,3 @@ +load(qttest_p4) +contains(QT_CONFIG,declarative): QT += declarative +SOURCES += tst_datetimeformatter.cpp diff --git a/tests/auto/declarative/datetimeformatter/tst_datetimeformatter.cpp b/tests/auto/declarative/datetimeformatter/tst_datetimeformatter.cpp new file mode 100644 index 0000000..67cff02 --- /dev/null +++ b/tests/auto/declarative/datetimeformatter/tst_datetimeformatter.cpp @@ -0,0 +1,83 @@ +#include <qtest.h> +#include <QtDeclarative/qmlengine.h> +#include <QtDeclarative/qmlcomponent.h> +#include <QtDeclarative/qmldatetimeformatter.h> + +class tst_datetimeformatter : public QObject +{ + Q_OBJECT +public: + tst_datetimeformatter() {} + +private slots: + void date(); + void time(); + void dateTime(); +}; + +void tst_datetimeformatter::date() +{ + QmlEngine engine; + QmlComponent formatterComponent(&engine, "DateTimeFormatter { date: \"2008-12-24\" }"); + QmlDateTimeFormatter *formatter = qobject_cast<QmlDateTimeFormatter*>(formatterComponent.create()); + QVERIFY(formatter != 0); + + QDate date(2008,12,24); + QCOMPARE(formatter->dateText(),date.toString(Qt::SystemLocaleShortDate)); + + formatter->setLongStyle(true); + QCOMPARE(formatter->dateText(),date.toString(Qt::SystemLocaleLongDate)); + + formatter->setDateFormat("ddd MMMM d yy"); + QCOMPARE(formatter->dateText(),date.toString("ddd MMMM d yy")); + + QVERIFY(formatter->timeText().isEmpty()); + QVERIFY(formatter->dateTimeText().isEmpty()); +} + +void tst_datetimeformatter::time() +{ + QmlEngine engine; + QmlComponent formatterComponent(&engine, "DateTimeFormatter { time: \"14:15:38.200\" }"); + QmlDateTimeFormatter *formatter = qobject_cast<QmlDateTimeFormatter*>(formatterComponent.create()); + QVERIFY(formatter != 0); + + QTime time(14,15,38,200); + + QCOMPARE(formatter->time(),time); + + QCOMPARE(formatter->timeText(),time.toString(Qt::SystemLocaleShortDate)); + + formatter->setLongStyle(true); + QCOMPARE(formatter->timeText(),time.toString(Qt::SystemLocaleLongDate)); + + formatter->setTimeFormat("H:m:s a"); + QCOMPARE(formatter->timeText(),time.toString("H:m:s a")); + + formatter->setTimeFormat("hh:mm:ss.zzz"); + QCOMPARE(formatter->timeText(),time.toString("hh:mm:ss.zzz")); + + QVERIFY(formatter->dateText().isEmpty()); + QVERIFY(formatter->dateTimeText().isEmpty()); +} + +void tst_datetimeformatter::dateTime() +{ + QmlEngine engine; + QmlComponent formatterComponent(&engine, "DateTimeFormatter { dateTime: \"1978-03-04T09:13:54\" }"); + QmlDateTimeFormatter *formatter = qobject_cast<QmlDateTimeFormatter*>(formatterComponent.create()); + QVERIFY(formatter != 0); + + QDateTime dateTime(QDate(1978,03,04),QTime(9,13,54)); + QCOMPARE(formatter->dateTimeText(),dateTime.toString(Qt::SystemLocaleShortDate)); + + formatter->setLongStyle(true); + QCOMPARE(formatter->dateTimeText(),dateTime.toString(Qt::SystemLocaleLongDate)); + + formatter->setDateTimeFormat("M/d/yy H:m:s a"); + QCOMPARE(formatter->dateTimeText(),dateTime.toString("M/d/yy H:m:s a")); +} + +QTEST_MAIN(tst_datetimeformatter) + +#include "tst_datetimeformatter.moc" diff --git a/tests/auto/declarative/declarative.pro b/tests/auto/declarative/declarative.pro new file mode 100644 index 0000000..14d8c24 --- /dev/null +++ b/tests/auto/declarative/declarative.pro @@ -0,0 +1,23 @@ +TEMPLATE = subdirs +SUBDIRS += datetimeformatter \ + numberformatter \ + qbindablemap \ + layouts \ + listview \ + pathview \ + qfxtext \ + qfxtextedit \ + simplecanvasitem \ + repeater \ + qmlparser \ + qmlbindengine \ + qmlmetaproperty \ + qmllist \ + qmllistaccessor \ + visual\ + qmlengine + +# Tests which should run in Pulse +PULSE_TESTS = $$SUBDIRS +PULSE_TESTS -= visual # All except 'visual' tests, allegedly too flaky + diff --git a/tests/auto/declarative/layouts/data/grid-margin.qml b/tests/auto/declarative/layouts/data/grid-margin.qml new file mode 100644 index 0000000..bae47f9 --- /dev/null +++ b/tests/auto/declarative/layouts/data/grid-margin.qml @@ -0,0 +1,38 @@ +Item { + width: 640 + height: 480 + GridLayout { + columns: 3 + margin: 8 + Rect { + id: one + color: "red" + width: 50 + height: 50 + } + Rect { + id: two + color: "green" + width: 20 + height: 50 + } + Rect { + id: three + color: "blue" + width: 50 + height: 20 + } + Rect { + id: four + color: "cyan" + width: 50 + height: 50 + } + Rect { + id: five + color: "magenta" + width: 10 + height: 10 + } + } +} diff --git a/tests/auto/declarative/layouts/data/grid-spacing-margin.qml b/tests/auto/declarative/layouts/data/grid-spacing-margin.qml new file mode 100644 index 0000000..100d8c5 --- /dev/null +++ b/tests/auto/declarative/layouts/data/grid-spacing-margin.qml @@ -0,0 +1,39 @@ +Item { + width: 640 + height: 480 + GridLayout { + columns: 3 + spacing: 4 + margin: 8 + Rect { + id: one + color: "red" + width: 50 + height: 50 + } + Rect { + id: two + color: "green" + width: 20 + height: 50 + } + Rect { + id: three + color: "blue" + width: 50 + height: 20 + } + Rect { + id: four + color: "cyan" + width: 50 + height: 50 + } + Rect { + id: five + color: "magenta" + width: 10 + height: 10 + } + } +} diff --git a/tests/auto/declarative/layouts/data/grid-spacing.qml b/tests/auto/declarative/layouts/data/grid-spacing.qml new file mode 100644 index 0000000..494127b --- /dev/null +++ b/tests/auto/declarative/layouts/data/grid-spacing.qml @@ -0,0 +1,38 @@ +Item { + width: 640 + height: 480 + GridLayout { + columns: 3 + spacing: 4 + Rect { + id: one + color: "red" + width: 50 + height: 50 + } + Rect { + id: two + color: "green" + width: 20 + height: 50 + } + Rect { + id: three + color: "blue" + width: 50 + height: 20 + } + Rect { + id: four + color: "cyan" + width: 50 + height: 50 + } + Rect { + id: five + color: "magenta" + width: 10 + height: 10 + } + } +} diff --git a/tests/auto/declarative/layouts/data/grid.qml b/tests/auto/declarative/layouts/data/grid.qml new file mode 100644 index 0000000..598915f --- /dev/null +++ b/tests/auto/declarative/layouts/data/grid.qml @@ -0,0 +1,37 @@ +Item { + width: 640 + height: 480 + GridLayout { + columns: 3 + Rect { + id: one + color: "red" + width: 50 + height: 50 + } + Rect { + id: two + color: "green" + width: 20 + height: 50 + } + Rect { + id: three + color: "blue" + width: 50 + height: 20 + } + Rect { + id: four + color: "cyan" + width: 50 + height: 50 + } + Rect { + id: five + color: "magenta" + width: 10 + height: 10 + } + } +} diff --git a/tests/auto/declarative/layouts/data/horizontal-margin.qml b/tests/auto/declarative/layouts/data/horizontal-margin.qml new file mode 100644 index 0000000..8bf2329 --- /dev/null +++ b/tests/auto/declarative/layouts/data/horizontal-margin.qml @@ -0,0 +1,25 @@ +Item { + width: 640 + height: 480 + HorizontalLayout { + margin: 10 + Rect { + id: one + color: "red" + width: 50 + height: 50 + } + Rect { + id: two + color: "red" + width: 20 + height: 10 + } + Rect { + id: three + color: "red" + width: 40 + height: 20 + } + } +} diff --git a/tests/auto/declarative/layouts/data/horizontal-spacing-margin.qml b/tests/auto/declarative/layouts/data/horizontal-spacing-margin.qml new file mode 100644 index 0000000..79652f6 --- /dev/null +++ b/tests/auto/declarative/layouts/data/horizontal-spacing-margin.qml @@ -0,0 +1,26 @@ +Item { + width: 640 + height: 480 + HorizontalLayout { + spacing: 5 + margin: 10 + Rect { + id: one + color: "red" + width: 50 + height: 50 + } + Rect { + id: two + color: "red" + width: 20 + height: 10 + } + Rect { + id: three + color: "red" + width: 40 + height: 20 + } + } +} diff --git a/tests/auto/declarative/layouts/data/horizontal-spacing.qml b/tests/auto/declarative/layouts/data/horizontal-spacing.qml new file mode 100644 index 0000000..5130e4a --- /dev/null +++ b/tests/auto/declarative/layouts/data/horizontal-spacing.qml @@ -0,0 +1,25 @@ +Item { + width: 640 + height: 480 + HorizontalLayout { + spacing: 10 + Rect { + id: one + color: "red" + width: 50 + height: 50 + } + Rect { + id: two + color: "red" + width: 20 + height: 10 + } + Rect { + id: three + color: "red" + width: 40 + height: 20 + } + } +} diff --git a/tests/auto/declarative/layouts/data/horizontal.qml b/tests/auto/declarative/layouts/data/horizontal.qml new file mode 100644 index 0000000..7ad6b55 --- /dev/null +++ b/tests/auto/declarative/layouts/data/horizontal.qml @@ -0,0 +1,24 @@ +Item { + width: 640 + height: 480 + HorizontalLayout { + Rect { + id: one + color: "red" + width: 50 + height: 50 + } + Rect { + id: two + color: "red" + width: 20 + height: 10 + } + Rect { + id: three + color: "red" + width: 40 + height: 20 + } + } +} diff --git a/tests/auto/declarative/layouts/data/vertical-margin.qml b/tests/auto/declarative/layouts/data/vertical-margin.qml new file mode 100644 index 0000000..ad34906 --- /dev/null +++ b/tests/auto/declarative/layouts/data/vertical-margin.qml @@ -0,0 +1,25 @@ +Item { + width: 640 + height: 480 + VerticalLayout { + margin: 10 + Rect { + id: one + color: "red" + width: 50 + height: 50 + } + Rect { + id: two + color: "red" + width: 20 + height: 10 + } + Rect { + id: three + color: "red" + width: 40 + height: 20 + } + } +} diff --git a/tests/auto/declarative/layouts/data/vertical-spacing-margin.qml b/tests/auto/declarative/layouts/data/vertical-spacing-margin.qml new file mode 100644 index 0000000..5de50b3 --- /dev/null +++ b/tests/auto/declarative/layouts/data/vertical-spacing-margin.qml @@ -0,0 +1,26 @@ +Item { + width: 640 + height: 480 + VerticalLayout { + spacing: 5 + margin: 10 + Rect { + id: one + color: "red" + width: 50 + height: 50 + } + Rect { + id: two + color: "red" + width: 20 + height: 10 + } + Rect { + id: three + color: "red" + width: 40 + height: 20 + } + } +} diff --git a/tests/auto/declarative/layouts/data/vertical-spacing.qml b/tests/auto/declarative/layouts/data/vertical-spacing.qml new file mode 100644 index 0000000..c364e3f --- /dev/null +++ b/tests/auto/declarative/layouts/data/vertical-spacing.qml @@ -0,0 +1,25 @@ +Item { + width: 640 + height: 480 + VerticalLayout { + spacing: 10 + Rect { + id: one + color: "red" + width: 50 + height: 50 + } + Rect { + id: two + color: "red" + width: 20 + height: 10 + } + Rect { + id: three + color: "red" + width: 40 + height: 20 + } + } +} diff --git a/tests/auto/declarative/layouts/data/vertical.qml b/tests/auto/declarative/layouts/data/vertical.qml new file mode 100644 index 0000000..50931cd --- /dev/null +++ b/tests/auto/declarative/layouts/data/vertical.qml @@ -0,0 +1,24 @@ +Item { + width: 640 + height: 480 + VerticalLayout { + Rect { + id: one + color: "red" + width: 50 + height: 50 + } + Rect { + id: two + color: "red" + width: 20 + height: 10 + } + Rect { + id: three + color: "red" + width: 40 + height: 20 + } + } +} diff --git a/tests/auto/declarative/layouts/layouts.pro b/tests/auto/declarative/layouts/layouts.pro new file mode 100644 index 0000000..f7e7622 --- /dev/null +++ b/tests/auto/declarative/layouts/layouts.pro @@ -0,0 +1,6 @@ +load(qttest_p4) +contains(QT_CONFIG,declarative): QT += declarative +SOURCES += tst_layouts.cpp + +# Define SRCDIR equal to test's source directory +DEFINES += SRCDIR=\\\"$$PWD\\\" diff --git a/tests/auto/declarative/layouts/tst_layouts.cpp b/tests/auto/declarative/layouts/tst_layouts.cpp new file mode 100644 index 0000000..732551c --- /dev/null +++ b/tests/auto/declarative/layouts/tst_layouts.cpp @@ -0,0 +1,392 @@ +#include <QtTest/QtTest> +#include <qlistmodelinterface.h> +#include <qfxview.h> +#include <qfxrect.h> +#include <qmlexpression.h> + +class tst_QFxLayouts : public QObject +{ + Q_OBJECT +public: + tst_QFxLayouts(); + +private slots: + void test_horizontal(); + void test_horizontal_spacing(); + void test_horizontal_margin(); + void test_horizontal_spacing_margin(); + void test_vertical(); + void test_vertical_spacing(); + void test_vertical_margin(); + void test_vertical_spacing_margin(); + void test_grid(); + void test_grid_spacing(); + void test_grid_margin(); + void test_grid_spacing_margin(); + +private: + QFxView *createView(const QString &filename); + template<typename T> + T *findItem(QFxItem *parent, const QString &id, int index=0); +}; + +tst_QFxLayouts::tst_QFxLayouts() +{ +} + +void tst_QFxLayouts::test_horizontal() +{ + QFxView *canvas = createView(SRCDIR "/data/horizontal.qml"); + + canvas->execute(); + qApp->processEvents(); + + QFxRect *one = findItem<QFxRect>(canvas->root(), "one"); + QVERIFY(one != 0); + + QFxRect *two = findItem<QFxRect>(canvas->root(), "two"); + QVERIFY(two != 0); + + QFxRect *three = findItem<QFxRect>(canvas->root(), "three"); + QVERIFY(three != 0); + + QCOMPARE(one->x(), 0.0); + QCOMPARE(one->y(), 0.0); + QCOMPARE(two->x(), 50.0); + QCOMPARE(two->y(), 0.0); + QCOMPARE(three->x(), 70.0); + QCOMPARE(three->y(), 0.0); +} + +void tst_QFxLayouts::test_horizontal_spacing() +{ + QFxView *canvas = createView(SRCDIR "/data/horizontal-spacing.qml"); + + canvas->execute(); + qApp->processEvents(); + + QFxRect *one = findItem<QFxRect>(canvas->root(), "one"); + QVERIFY(one != 0); + + QFxRect *two = findItem<QFxRect>(canvas->root(), "two"); + QVERIFY(two != 0); + + QFxRect *three = findItem<QFxRect>(canvas->root(), "three"); + QVERIFY(three != 0); + + QCOMPARE(one->x(), 0.0); + QCOMPARE(one->y(), 0.0); + QCOMPARE(two->x(), 60.0); + QCOMPARE(two->y(), 0.0); + QCOMPARE(three->x(), 90.0); + QCOMPARE(three->y(), 0.0); +} + +void tst_QFxLayouts::test_horizontal_margin() +{ + QFxView *canvas = createView(SRCDIR "/data/horizontal-margin.qml"); + + canvas->execute(); + qApp->processEvents(); + + QFxRect *one = findItem<QFxRect>(canvas->root(), "one"); + QVERIFY(one != 0); + + QFxRect *two = findItem<QFxRect>(canvas->root(), "two"); + QVERIFY(two != 0); + + QFxRect *three = findItem<QFxRect>(canvas->root(), "three"); + QVERIFY(three != 0); + + QCOMPARE(one->x(), 10.0); + QCOMPARE(one->y(), 10.0); + QCOMPARE(two->x(), 60.0); + QCOMPARE(two->y(), 10.0); + QCOMPARE(three->x(), 80.0); + QCOMPARE(three->y(), 10.0); +} + +void tst_QFxLayouts::test_horizontal_spacing_margin() +{ + QFxView *canvas = createView(SRCDIR "/data/horizontal-spacing-margin.qml"); + + canvas->execute(); + qApp->processEvents(); + + QFxRect *one = findItem<QFxRect>(canvas->root(), "one"); + QVERIFY(one != 0); + + QFxRect *two = findItem<QFxRect>(canvas->root(), "two"); + QVERIFY(two != 0); + + QFxRect *three = findItem<QFxRect>(canvas->root(), "three"); + QVERIFY(three != 0); + + QCOMPARE(one->x(), 10.0); + QCOMPARE(one->y(), 10.0); + QCOMPARE(two->x(), 65.0); + QCOMPARE(two->y(), 10.0); + QCOMPARE(three->x(), 90.0); + QCOMPARE(three->y(), 10.0); +} + +void tst_QFxLayouts::test_vertical() +{ + QFxView *canvas = createView(SRCDIR "/data/vertical.qml"); + + canvas->execute(); + qApp->processEvents(); + + QFxRect *one = findItem<QFxRect>(canvas->root(), "one"); + QVERIFY(one != 0); + + QFxRect *two = findItem<QFxRect>(canvas->root(), "two"); + QVERIFY(two != 0); + + QFxRect *three = findItem<QFxRect>(canvas->root(), "three"); + QVERIFY(three != 0); + + QCOMPARE(one->x(), 0.0); + QCOMPARE(one->y(), 0.0); + QCOMPARE(two->x(), 0.0); + QCOMPARE(two->y(), 50.0); + QCOMPARE(three->x(), 0.0); + QCOMPARE(three->y(), 60.0); +} + +void tst_QFxLayouts::test_vertical_spacing() +{ + QFxView *canvas = createView(SRCDIR "/data/vertical-spacing.qml"); + + canvas->execute(); + qApp->processEvents(); + + QFxRect *one = findItem<QFxRect>(canvas->root(), "one"); + QVERIFY(one != 0); + + QFxRect *two = findItem<QFxRect>(canvas->root(), "two"); + QVERIFY(two != 0); + + QFxRect *three = findItem<QFxRect>(canvas->root(), "three"); + QVERIFY(three != 0); + + QCOMPARE(one->x(), 0.0); + QCOMPARE(one->y(), 0.0); + QCOMPARE(two->x(), 0.0); + QCOMPARE(two->y(), 60.0); + QCOMPARE(three->x(), 0.0); + QCOMPARE(three->y(), 80.0); +} + +void tst_QFxLayouts::test_vertical_margin() +{ + QFxView *canvas = createView(SRCDIR "/data/vertical-margin.qml"); + + canvas->execute(); + qApp->processEvents(); + + QFxRect *one = findItem<QFxRect>(canvas->root(), "one"); + QVERIFY(one != 0); + + QFxRect *two = findItem<QFxRect>(canvas->root(), "two"); + QVERIFY(two != 0); + + QFxRect *three = findItem<QFxRect>(canvas->root(), "three"); + QVERIFY(three != 0); + + QCOMPARE(one->x(), 10.0); + QCOMPARE(one->y(), 10.0); + QCOMPARE(two->x(), 10.0); + QCOMPARE(two->y(), 60.0); + QCOMPARE(three->x(), 10.0); + QCOMPARE(three->y(), 70.0); +} + +void tst_QFxLayouts::test_vertical_spacing_margin() +{ + QFxView *canvas = createView(SRCDIR "/data/vertical-spacing-margin.qml"); + + canvas->execute(); + qApp->processEvents(); + + QFxRect *one = findItem<QFxRect>(canvas->root(), "one"); + QVERIFY(one != 0); + + QFxRect *two = findItem<QFxRect>(canvas->root(), "two"); + QVERIFY(two != 0); + + QFxRect *three = findItem<QFxRect>(canvas->root(), "three"); + QVERIFY(three != 0); + + QCOMPARE(one->x(), 10.0); + QCOMPARE(one->y(), 10.0); + QCOMPARE(two->x(), 10.0); + QCOMPARE(two->y(), 65.0); + QCOMPARE(three->x(), 10.0); + QCOMPARE(three->y(), 80.0); +} + +void tst_QFxLayouts::test_grid() +{ + QFxView *canvas = createView("data/grid.qml"); + + canvas->execute(); + qApp->processEvents(); + + QFxRect *one = findItem<QFxRect>(canvas->root(), "one"); + QVERIFY(one != 0); + QFxRect *two = findItem<QFxRect>(canvas->root(), "two"); + QVERIFY(two != 0); + QFxRect *three = findItem<QFxRect>(canvas->root(), "three"); + QVERIFY(three != 0); + QFxRect *four = findItem<QFxRect>(canvas->root(), "four"); + QVERIFY(four != 0); + QFxRect *five = findItem<QFxRect>(canvas->root(), "five"); + QVERIFY(five != 0); + + QCOMPARE(one->x(), 0.0); + QCOMPARE(one->y(), 0.0); + QCOMPARE(two->x(), 50.0); + QCOMPARE(two->y(), 0.0); + QCOMPARE(three->x(), 70.0); + QCOMPARE(three->y(), 0.0); + QCOMPARE(four->x(), 0.0); + QCOMPARE(four->y(), 50.0); + QCOMPARE(five->x(), 50.0); + QCOMPARE(five->y(), 50.0); +} + +void tst_QFxLayouts::test_grid_spacing() +{ + QFxView *canvas = createView("data/grid-spacing.qml"); + + canvas->execute(); + qApp->processEvents(); + + QFxRect *one = findItem<QFxRect>(canvas->root(), "one"); + QVERIFY(one != 0); + QFxRect *two = findItem<QFxRect>(canvas->root(), "two"); + QVERIFY(two != 0); + QFxRect *three = findItem<QFxRect>(canvas->root(), "three"); + QVERIFY(three != 0); + QFxRect *four = findItem<QFxRect>(canvas->root(), "four"); + QVERIFY(four != 0); + QFxRect *five = findItem<QFxRect>(canvas->root(), "five"); + QVERIFY(five != 0); + + QCOMPARE(one->x(), 0.0); + QCOMPARE(one->y(), 0.0); + QCOMPARE(two->x(), 54.0); + QCOMPARE(two->y(), 0.0); + QCOMPARE(three->x(), 78.0); + QCOMPARE(three->y(), 0.0); + QCOMPARE(four->x(), 0.0); + QCOMPARE(four->y(), 54.0); + QCOMPARE(five->x(), 54.0); + QCOMPARE(five->y(), 54.0); +} + +void tst_QFxLayouts::test_grid_margin() +{ + QFxView *canvas = createView("data/grid-margin.qml"); + + canvas->execute(); + qApp->processEvents(); + + QFxRect *one = findItem<QFxRect>(canvas->root(), "one"); + QVERIFY(one != 0); + QFxRect *two = findItem<QFxRect>(canvas->root(), "two"); + QVERIFY(two != 0); + QFxRect *three = findItem<QFxRect>(canvas->root(), "three"); + QVERIFY(three != 0); + QFxRect *four = findItem<QFxRect>(canvas->root(), "four"); + QVERIFY(four != 0); + QFxRect *five = findItem<QFxRect>(canvas->root(), "five"); + QVERIFY(five != 0); + + QCOMPARE(one->x(), 8.0); + QCOMPARE(one->y(), 8.0); + QCOMPARE(two->x(), 58.0); + QCOMPARE(two->y(), 8.0); + QCOMPARE(three->x(), 78.0); + QCOMPARE(three->y(), 8.0); + QCOMPARE(four->x(), 8.0); + QCOMPARE(four->y(), 58.0); + QCOMPARE(five->x(), 58.0); + QCOMPARE(five->y(), 58.0); +} + + +void tst_QFxLayouts::test_grid_spacing_margin() +{ + QFxView *canvas = createView("data/grid-spacing-margin.qml"); + + canvas->execute(); + qApp->processEvents(); + + QFxRect *one = findItem<QFxRect>(canvas->root(), "one"); + QVERIFY(one != 0); + QFxRect *two = findItem<QFxRect>(canvas->root(), "two"); + QVERIFY(two != 0); + QFxRect *three = findItem<QFxRect>(canvas->root(), "three"); + QVERIFY(three != 0); + QFxRect *four = findItem<QFxRect>(canvas->root(), "four"); + QVERIFY(four != 0); + QFxRect *five = findItem<QFxRect>(canvas->root(), "five"); + QVERIFY(five != 0); + + QCOMPARE(one->x(), 8.0); + QCOMPARE(one->y(), 8.0); + QCOMPARE(two->x(), 62.0); + QCOMPARE(two->y(), 8.0); + QCOMPARE(three->x(), 86.0); + QCOMPARE(three->y(), 8.0); + QCOMPARE(four->x(), 8.0); + QCOMPARE(four->y(), 62.0); + QCOMPARE(five->x(), 62.0); + QCOMPARE(five->y(), 62.0); +} + +QFxView *tst_QFxLayouts::createView(const QString &filename) +{ + QFxView *canvas = new QFxView(0); + + QFile file(filename); + file.open(QFile::ReadOnly); + QString xml = file.readAll(); + canvas->setQml(xml, filename); + + return canvas; +} + +/* + Find an item with the specified id. If index is supplied then the + item must also evaluate the {index} expression equal to index +*/ +template<typename T> +T *tst_QFxLayouts::findItem(QFxItem *parent, const QString &id, int index) +{ + const QMetaObject &mo = T::staticMetaObject; + for (int i = 0; i < parent->children()->count(); ++i) { + QFxItem *item = parent->children()->at(i); + if (mo.cast(item) && (id.isEmpty() || item->id() == id)) { + if (index != -1) { + QmlExpression e(qmlContext(item), "index", item); + e.setTrackChange(false); + if (e.value().toInt() == index) + return static_cast<T*>(item); + } else { + return static_cast<T*>(item); + } + } + item = findItem<T>(item, id, index); + if (item) + return static_cast<T*>(item); + } + + return 0; +} + +QTEST_MAIN(tst_QFxLayouts) + +#include "tst_layouts.moc" diff --git a/tests/auto/declarative/listview/data/listview.qml b/tests/auto/declarative/listview/data/listview.qml new file mode 100644 index 0000000..891f9a8 --- /dev/null +++ b/tests/auto/declarative/listview/data/listview.qml @@ -0,0 +1,39 @@ +Rect { + width: 240 + height: 320 + color: "#ffffff" + resources: [ + Component { + id: Delegate + Item { + id: wrapper + height: 20 + width: 240 + Text { + text: index + } + Text { + x: 30 + id: textName + text: name + } + Text { + x: 120 + id: textNumber + text: number + } + Text { + x: 200 + text: wrapper.y + } + } + } + ] + ListView { + id: list + width: 240 + height: 320 + model: testModel + delegate: Delegate + } +} diff --git a/tests/auto/declarative/listview/listview.pro b/tests/auto/declarative/listview/listview.pro new file mode 100644 index 0000000..bf68268 --- /dev/null +++ b/tests/auto/declarative/listview/listview.pro @@ -0,0 +1,6 @@ +load(qttest_p4) +contains(QT_CONFIG,declarative): QT += declarative +SOURCES += tst_listview.cpp + +# Define SRCDIR equal to test's source directory +DEFINES += SRCDIR=\\\"$$PWD\\\" diff --git a/tests/auto/declarative/listview/tst_listview.cpp b/tests/auto/declarative/listview/tst_listview.cpp new file mode 100644 index 0000000..8cf0a85 --- /dev/null +++ b/tests/auto/declarative/listview/tst_listview.cpp @@ -0,0 +1,486 @@ +#include <QtTest/QtTest> +#include <qlistmodelinterface.h> +#include <qfxview.h> +#include <qfxlistview.h> +#include <qfxtext.h> +#include <qmlcontext.h> +#include <qmlexpression.h> + +class tst_QFxListView : public QObject +{ + Q_OBJECT +public: + tst_QFxListView(); + +private slots: + // Test both QListModelInterface and QAbstractItemModel model types + void qListModelInterface_items(); + void qAbstractItemModel_items(); + + void qListModelInterface_changed(); + void qAbstractItemModel_changed(); + + void qListModelInterface_inserted(); + void qAbstractItemModel_inserted(); + + void qListModelInterface_removed(); + void qAbstractItemModel_removed(); + +private: + template <class T> void items(); + template <class T> void changed(); + template <class T> void inserted(); + template <class T> void removed(); + QFxView *createView(const QString &filename); + template<typename T> + T *findItem(QFxItem *parent, const QString &id, int index=0); +}; + +class TestModel : public QListModelInterface +{ + Q_OBJECT +public: + TestModel(QObject *parent = 0) : QListModelInterface(parent) {} + ~TestModel() {} + + enum Roles { Name, Number }; + + QString name(int index) const { return list.at(index).first; } + QString number(int index) const { return list.at(index).second; } + + int count() const { return list.count(); } + + QList<int> roles() const { return QList<int>() << Name << Number; } + QString toString(int role) const { + switch(role) { + case Name: + return "name"; + case Number: + return "number"; + default: + return ""; + } + } + + QHash<int, QVariant> data(int index, const QList<int> &roles) const { + QHash<int,QVariant> returnHash; + + for (int i = 0; i < roles.size(); ++i) { + int role = roles.at(i); + QVariant info; + switch(role) { + case Name: + info = list.at(index).first; + break; + case Number: + info = list.at(index).second; + break; + default: + break; + } + returnHash.insert(role, info); + } + return returnHash; + } + + void addItem(const QString &name, const QString &number) { + list.append(QPair<QString,QString>(name, number)); + emit itemsInserted(list.count()-1, 1); + } + + void insertItem(int index, const QString &name, const QString &number) { + list.insert(index, QPair<QString,QString>(name, number)); + emit itemsInserted(index, 1); + } + + void removeItem(int index) { + list.removeAt(index); + emit itemsRemoved(index, 1); + } + + void modifyItem(int index, const QString &name, const QString &number) { + list[index] = QPair<QString,QString>(name, number); + emit itemsChanged(index, 1, roles()); + } + +private: + QList<QPair<QString,QString> > list; +}; + + +class TestModel2 : public QAbstractListModel +{ +public: + enum Roles { Name = Qt::UserRole+1, Number = Qt::UserRole+2 }; + + TestModel2(QObject *parent=0) : QAbstractListModel(parent) { + QHash<int, QByteArray> roles; + roles[Name] = "name"; + roles[Number] = "number"; + setRoleNames(roles); + } + + int rowCount(const QModelIndex &parent=QModelIndex()) const { return list.count(); } + QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const { + QVariant rv; + if (role == Name) + rv = list.at(index.row()).first; + else if (role == Number) + rv = list.at(index.row()).second; + + return rv; + } + + int count() const { return rowCount(); } + QString name(int index) const { return list.at(index).first; } + QString number(int index) const { return list.at(index).second; } + + void addItem(const QString &name, const QString &number) { + emit beginInsertRows(QModelIndex(), list.count(), list.count()); + list.append(QPair<QString,QString>(name, number)); + emit endInsertRows(); + } + + void insertItem(int index, const QString &name, const QString &number) { + emit beginInsertRows(QModelIndex(), index, index); + list.insert(index, QPair<QString,QString>(name, number)); + emit endInsertRows(); + } + + void removeItem(int index) { + emit beginRemoveRows(QModelIndex(), index, index); + list.removeAt(index); + emit endRemoveRows(); + } + + void modifyItem(int idx, const QString &name, const QString &number) { + list[idx] = QPair<QString,QString>(name, number); + emit dataChanged(index(idx,0), index(idx,0)); + } + +private: + QList<QPair<QString,QString> > list; +}; + +tst_QFxListView::tst_QFxListView() +{ +} + +template <class T> +void tst_QFxListView::items() +{ + QFxView *canvas = createView(SRCDIR "/data/listview.qml"); + + T model; + model.addItem("Fred", "12345"); + model.addItem("John", "2345"); + model.addItem("Bob", "54321"); + + QmlContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + + canvas->execute(); + qApp->processEvents(); + + QFxFlickable *listview = findItem<QFxFlickable>(canvas->root(), "list"); + QVERIFY(listview != 0); + + QFxItem *viewport = listview->viewport(); + QVERIFY(viewport != 0); + + QCOMPARE(viewport->children()->count(), model.count()); // assumes all are visible + + for (int i = 0; i < model.count(); ++i) { + QFxText *name = findItem<QFxText>(viewport, "textName", i); + QVERIFY(name != 0); + QCOMPARE(name->text(), model.name(i)); + QFxText *number = findItem<QFxText>(viewport, "textNumber", i); + QVERIFY(number != 0); + QCOMPARE(number->text(), model.number(i)); + } + + delete canvas; +} + +template <class T> +void tst_QFxListView::changed() +{ + QFxView *canvas = createView(SRCDIR "/data/listview.qml"); + + T model; + model.addItem("Fred", "12345"); + model.addItem("John", "2345"); + model.addItem("Bob", "54321"); + + QmlContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + + canvas->execute(); + qApp->processEvents(); + + QFxFlickable *listview = findItem<QFxFlickable>(canvas->root(), "list"); + QVERIFY(listview != 0); + + QFxItem *viewport = listview->viewport(); + QVERIFY(viewport != 0); + + model.modifyItem(1, "Will", "9876"); + QFxText *name = findItem<QFxText>(viewport, "textName", 1); + QVERIFY(name != 0); + QCOMPARE(name->text(), model.name(1)); + QFxText *number = findItem<QFxText>(viewport, "textNumber", 1); + QVERIFY(number != 0); + QCOMPARE(number->text(), model.number(1)); + + delete canvas; +} + +template <class T> +void tst_QFxListView::inserted() +{ + QFxView *canvas = createView(SRCDIR "/data/listview.qml"); + + T model; + model.addItem("Fred", "12345"); + model.addItem("John", "2345"); + model.addItem("Bob", "54321"); + + QmlContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + + canvas->execute(); + qApp->processEvents(); + + QFxListView *listview = findItem<QFxListView>(canvas->root(), "list"); + QVERIFY(listview != 0); + + QFxItem *viewport = listview->viewport(); + QVERIFY(viewport != 0); + + model.insertItem(1, "Will", "9876"); + + // let transitions settle. + QTest::qWait(1000); + + QCOMPARE(viewport->children()->count(), model.count()); // assumes all are visible + + QFxText *name = findItem<QFxText>(viewport, "textName", 1); + QVERIFY(name != 0); + QCOMPARE(name->text(), model.name(1)); + QFxText *number = findItem<QFxText>(viewport, "textNumber", 1); + QVERIFY(number != 0); + QCOMPARE(number->text(), model.number(1)); + + // Confirm items positioned correctly + for (int i = 0; i < model.count(); ++i) { + QFxItem *item = findItem<QFxItem>(viewport, "wrapper", i); + QVERIFY(item->y() == i*20); + } + + model.insertItem(0, "Foo", "1111"); // zero index, and current item + + // let transitions settle. + QTest::qWait(1000); + + QCOMPARE(viewport->children()->count(), model.count()); // assumes all are visible + + name = findItem<QFxText>(viewport, "textName", 0); + QVERIFY(name != 0); + QCOMPARE(name->text(), model.name(0)); + number = findItem<QFxText>(viewport, "textNumber", 0); + QVERIFY(number != 0); + QCOMPARE(number->text(), model.number(0)); + + QCOMPARE(listview->currentIndex(), 1); + + // Confirm items positioned correctly + for (int i = 0; i < model.count(); ++i) { + QFxItem *item = findItem<QFxItem>(viewport, "wrapper", i); + QVERIFY(item->y() == i*20); + } + + delete canvas; +} + +template <class T> +void tst_QFxListView::removed() +{ + QFxView *canvas = createView(SRCDIR "/data/listview.qml"); + + T model; + for (int i = 0; i < 30; i++) + model.addItem("Item" + QString::number(i), ""); + + QmlContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + + canvas->execute(); + qApp->processEvents(); + + QFxListView *listview = findItem<QFxListView>(canvas->root(), "list"); + QVERIFY(listview != 0); + + QFxItem *viewport = listview->viewport(); + QVERIFY(viewport != 0); + + model.removeItem(1); + + // let transitions settle. + QTest::qWait(1000); + + QFxText *name = findItem<QFxText>(viewport, "textName", 1); + QVERIFY(name != 0); + QCOMPARE(name->text(), model.name(1)); + QFxText *number = findItem<QFxText>(viewport, "textNumber", 1); + QVERIFY(number != 0); + QCOMPARE(number->text(), model.number(1)); + + // Confirm items positioned correctly + for (int i = 0; i < model.count() && i < viewport->children()->count(); ++i) { + QFxItem *item = findItem<QFxItem>(viewport, "wrapper", i); + QVERIFY(item->y() == i*20); + } + + // Remove first item (which is the current item); + model.removeItem(0); // post: top item starts at 20 + + // let transitions settle. + QTest::qWait(1000); + + name = findItem<QFxText>(viewport, "textName", 0); + QVERIFY(name != 0); + QCOMPARE(name->text(), model.name(0)); + number = findItem<QFxText>(viewport, "textNumber", 0); + QVERIFY(number != 0); + QCOMPARE(number->text(), model.number(0)); + + // Confirm items positioned correctly + for (int i = 0; i < model.count() && i < viewport->children()->count(); ++i) { + QFxItem *item = findItem<QFxItem>(viewport, "wrapper", i); + QCOMPARE(item->y(),i*20.0 + 20.0); + } + + // Remove items not visible + model.removeItem(18); + // let transitions settle. + QTest::qWait(1000); + + // Confirm items positioned correctly + for (int i = 0; i < model.count() && i < viewport->children()->count(); ++i) { + QFxItem *item = findItem<QFxItem>(viewport, "wrapper", i); + QCOMPARE(item->y(),i*20.0+20.0); + } + + // Remove items before visible + listview->setYPosition(80); + listview->setCurrentIndex(10); + + model.removeItem(1); // post: top item will be at 40 + // let transitions settle. + QTest::qWait(1000); + + // Confirm items positioned correctly + for (int i = 2; i < 18; ++i) { + QFxItem *item = findItem<QFxItem>(viewport, "wrapper", i); + QCOMPARE(item->y(),40+i*20.0); + } + + listview->setYPosition(40); // That's the top now + // let transitions settle. + QTest::qWait(1000); + + // Confirm items positioned correctly + for (int i = 0; i < model.count() && i < viewport->children()->count(); ++i) { + QFxItem *item = findItem<QFxItem>(viewport, "wrapper", i); + QCOMPARE(item->y(),40+i*20.0); + } + + delete canvas; +} + +void tst_QFxListView::qListModelInterface_items() +{ + items<TestModel>(); +} + +void tst_QFxListView::qAbstractItemModel_items() +{ + items<TestModel2>(); +} + +void tst_QFxListView::qListModelInterface_changed() +{ + changed<TestModel>(); +} + +void tst_QFxListView::qAbstractItemModel_changed() +{ + changed<TestModel2>(); +} + +void tst_QFxListView::qListModelInterface_inserted() +{ + inserted<TestModel>(); +} + +void tst_QFxListView::qAbstractItemModel_inserted() +{ + inserted<TestModel2>(); +} + +void tst_QFxListView::qListModelInterface_removed() +{ + removed<TestModel>(); +} + +void tst_QFxListView::qAbstractItemModel_removed() +{ + removed<TestModel2>(); +} + +QFxView *tst_QFxListView::createView(const QString &filename) +{ + QFxView *canvas = new QFxView(0); + canvas->setFixedSize(240,320); + + QFile file(filename); + file.open(QFile::ReadOnly); + QString qml = file.readAll(); + canvas->setQml(qml, filename); + + return canvas; +} + +/* + Find an item with the specified id. If index is supplied then the + item must also evaluate the {index} expression equal to index +*/ +template<typename T> +T *tst_QFxListView::findItem(QFxItem *parent, const QString &id, int index) +{ + const QMetaObject &mo = T::staticMetaObject; + qDebug() << parent->children()->count() << "children"; + for (int i = 0; i < parent->children()->count(); ++i) { + QFxItem *item = parent->children()->at(i); + qDebug() << "try" << item; + if (mo.cast(item) && (id.isEmpty() || item->id() == id)) { + if (index != -1) { + QmlExpression e(qmlContext(item), "index", item); + e.setTrackChange(false); + if (e.value().toInt() == index) + return static_cast<T*>(item); + } else { + return static_cast<T*>(item); + } + } + item = findItem<T>(item, id, index); + if (item) + return static_cast<T*>(item); + } + + return 0; +} + +QTEST_MAIN(tst_QFxListView) + +#include "tst_listview.moc" diff --git a/tests/auto/declarative/numberformatter/numberformatter.pro b/tests/auto/declarative/numberformatter/numberformatter.pro new file mode 100644 index 0000000..ba391ed --- /dev/null +++ b/tests/auto/declarative/numberformatter/numberformatter.pro @@ -0,0 +1,3 @@ +load(qttest_p4) +contains(QT_CONFIG,declarative): QT += declarative +SOURCES += tst_numberformatter.cpp diff --git a/tests/auto/declarative/numberformatter/tst_numberformatter.cpp b/tests/auto/declarative/numberformatter/tst_numberformatter.cpp new file mode 100644 index 0000000..e70d651 --- /dev/null +++ b/tests/auto/declarative/numberformatter/tst_numberformatter.cpp @@ -0,0 +1,216 @@ +#include <qtest.h> +#include <QtDeclarative/qmlengine.h> +#include <QtDeclarative/qmlcomponent.h> +#include <QtDeclarative/qnumberformat.h> +#include <QtDeclarative/qmlnumberformatter.h> + +class tst_numberformat : public QObject +{ + Q_OBJECT +public: + tst_numberformat(); + + void init() {} + void initTestCase() {} + + void cleanup() {} + void cleanupTestCase() {} + +private slots: + void number_data(); + void number(); + + void text_data(); + void text(); + +private: + QStringList strings; + QList<float> numbers; + QStringList formats; + QStringList texts; +}; + +tst_numberformat::tst_numberformat() +{ + strings << "100.0" + << "12345" + << "1234567" + << "0.123" + << "0.9999" + << "0.989" + << "1" + << "1.0" + << "1.01"; + + numbers << 100 + << 12345 + << 1234567 + << 0.123 + << 0.9999 + << 0.989 + << 1 + << 1.0 + << 1.01; + + formats << "" + << "0000" + << "0000.00" + << "##" + << "##.##" + << "#0.00#" + << "##,##0.##" + << "(000) 000 - 000" + << "00000,000.0000"; + + //US locale only. + texts << "100.000000" + << "12345.000000" + << "1234567.000000" + << "0.123000" + << "0.999900" + << "0.989000" + << "1.000000" + << "1.000000" + << "1.010000" //end "" + << "0100" + << "12345" + << "1234567" + << "0000" + << "0001" + << "0001" + << "0001" + << "0001" + << "0001" // end "0000" + << "0100.00" + << "12345.00" + << "1234567.00" + << "0000.12" + << "0001.00" + << "0000.99" + << "0001.00" + << "0001.00" + << "0001.01" // end "0000.00" + << "100" + << "12345" + << "1234567" + << "0" + << "1" + << "1" + << "1" + << "1" + << "1" // end "##" + << "100"//start "##.##" + << "12345" + << "1234567" + << "0.12" + << "1" + << "0.99" + << "1" + << "1" + << "1.01" // end "##.##" -- ### EXPECT FAIL ### QNumberFormat::formatDecimal() bug + << "100.00" //start "#0.00#" + << "12345.00" + << "1234567.00" + << "0.123" + << "1.00" + << "0.989" + << "1.00" + << "1.00" + << "1.01" //end "#0.00#" + << "100" //start "##,##0.##" + << "12,345" + << "1,234,567" + << "0.12" + << "1" + << "0.99" + << "1" + << "1" + << "1.01" //end "##,##0.##" -- ### EXPECT FAIL ### QNumberFormat::formatDecimal() bug + << "(000) 000 - 100" //start "(000) 000 - 000" + << "(000) 012 - 345" + << "(001) 234 - 567" + << "(000) 000 - 000" + << "(000) 000 - 001" + << "(000) 000 - 001" + << "(000) 000 - 001" + << "(000) 000 - 001" + << "(000) 000 - 001" // end "(000) 000 - 000" + << "00,000,100.0000" // start "00000,000.0000" + << "00,012,345.0000" + << "01,234,567.0000" + << "00,000,000.1230" + << "00,000,000.9999" + << "00,000,000.9890" + << "00,000,001.0000" + << "00,000,001.0000" + << "00,000,001.0100"; // end + + qDebug() << "strings.size()" << strings.size() + << "\nformats.size()" << formats.size() + << "texts.size()" << texts.size(); +} + +void tst_numberformat::number_data() +{ + QTest::addColumn<QString>("string"); + QTest::addColumn<float>("number"); + + for (int i = 0; i < strings.size(); i++) + QTest::newRow(QString::number(i).toAscii()) << strings.at(i) << numbers.at(i); +} + +void tst_numberformat::number() +{ + // ### tests the conversion from string to float + QFETCH(QString, string); + QFETCH(float, number); + + QString componentStr = QString("NumberFormatter { number: \"") + string + QString("\" }"); + + QmlEngine engine; + QmlComponent formatterComponent(&engine, componentStr.toAscii()); + QmlNumberFormatter *formatter = qobject_cast<QmlNumberFormatter*>(formatterComponent.create()); + QVERIFY(formatter != 0); + QCOMPARE((float)formatter->number(), number); + //qDebug() << formatter->format() << formatter->text(); + QVERIFY(formatter->format().isEmpty()); + QVERIFY(formatter->text() == QString("%1").arg(number, -1, 'f', -1)); +} + +void tst_numberformat::text_data() +{ + QTest::addColumn<QString>("string"); + QTest::addColumn<QString>("format"); + QTest::addColumn<QString>("text"); + + for (int j=0; j < formats.size(); j++) + { + for (int i=0; i < strings.size(); i++) + { + QTest::newRow(QString("%1, %2").arg(strings.at(i)).arg(formats.at(j)).toAscii()) + << strings.at(i) << formats.at(j) << texts.at(j*formats.size()+i); + } + } + +} + +void tst_numberformat::text() +{ + QFETCH(QString, string); + QFETCH(QString, format); + QFETCH(QString, text); + + QString componentStr = QString("NumberFormatter { number: \"") + string + QString("\"; format: \"") + format + QString("\" }"); + + QmlEngine engine; + QmlComponent formatterComponent(&engine, componentStr.toAscii()); + QmlNumberFormatter *formatter = qobject_cast<QmlNumberFormatter*>(formatterComponent.create()); + QVERIFY(formatter != 0); + + QCOMPARE(formatter->format(), format); + QCOMPARE(formatter->text(), text); +} + +QTEST_MAIN(tst_numberformat) + +#include "tst_numberformatter.moc" diff --git a/tests/auto/declarative/pathview/data/pathview.qml b/tests/auto/declarative/pathview/data/pathview.qml new file mode 100644 index 0000000..0fec1e9 --- /dev/null +++ b/tests/auto/declarative/pathview/data/pathview.qml @@ -0,0 +1,60 @@ +Rect { + width: 240 + height: 320 + color: "#ffffff" + resources: [ + Component { + id: Delegate + Rect { + id: wrapper + height: 20 + width: 60 + color: "white" + pen.color: "black" + Text { + text: index + } + Text { + x: 20 + id: textName + text: name + } + Text { + x: 40 + id: textNumber + text: number + } + } + } + ] + PathView { + id: view + width: 240 + height: 320 + model: testModel + delegate: Delegate + snapPos: 0.01 + path: Path { + startY: 120 + startX: 160 + PathQuad { + y: 120 + x: 80 + controlY: 330 + controlX: 100 + } + PathLine { + y: 160 + x: 20 + } + PathCubic { + y: 120 + x: 160 + control1Y: 0 + control1X: 100 + control2Y: 000 + control2X: 200 + } + } + } +} diff --git a/tests/auto/declarative/pathview/pathview.pro b/tests/auto/declarative/pathview/pathview.pro new file mode 100644 index 0000000..28bbe49 --- /dev/null +++ b/tests/auto/declarative/pathview/pathview.pro @@ -0,0 +1,6 @@ +load(qttest_p4) +contains(QT_CONFIG,declarative): QT += declarative +SOURCES += tst_pathview.cpp + +# Define SRCDIR equal to test's source directory +DEFINES += SRCDIR=\\\"$$PWD\\\" diff --git a/tests/auto/declarative/pathview/tst_pathview.cpp b/tests/auto/declarative/pathview/tst_pathview.cpp new file mode 100644 index 0000000..92890ba --- /dev/null +++ b/tests/auto/declarative/pathview/tst_pathview.cpp @@ -0,0 +1,259 @@ +#include <QtTest/QtTest> +#include <qlistmodelinterface.h> +#include <qfxview.h> +#include <qfxpathview.h> +#include <qfxtext.h> +#include <qfxrect.h> +#include <qmlcontext.h> +#include <qmlexpression.h> + +class tst_QFxPathView : public QObject +{ + Q_OBJECT +public: + tst_QFxPathView(); + +private slots: + void items(); + void pathMoved(); + void limitedItems(); + +private: + QFxView *createView(const QString &filename); + template<typename T> + T *findItem(QFxItem *parent, const QString &id, int index=0); +}; + +class TestModel : public QListModelInterface +{ + Q_OBJECT +public: + TestModel(QObject *parent = 0) : QListModelInterface(parent) {} + ~TestModel() {} + + enum Roles { Name, Number }; + + QString name(int index) const { return list.at(index).first; } + QString number(int index) const { return list.at(index).second; } + + int count() const { return list.count(); } + + QList<int> roles() const { return QList<int>() << Name << Number; } + QString toString(int role) const { + switch(role) { + case Name: + return "name"; + case Number: + return "number"; + default: + return ""; + } + } + + QHash<int, QVariant> data(int index, const QList<int> &roles) const { + QHash<int,QVariant> returnHash; + + for (int i = 0; i < roles.size(); ++i) { + int role = roles.at(i); + QVariant info; + switch(role) { + case Name: + info = list.at(index).first; + break; + case Number: + info = list.at(index).second; + break; + default: + break; + } + returnHash.insert(role, info); + } + return returnHash; + } + + void addItem(const QString &name, const QString &number) { + list.append(QPair<QString,QString>(name, number)); + emit itemsInserted(list.count()-1, 1); + } + + void insertItem(int index, const QString &name, const QString &number) { + list.insert(index, QPair<QString,QString>(name, number)); + emit itemsInserted(index, 1); + } + + void removeItem(int index) { + list.removeAt(index); + emit itemsRemoved(index, 1); + } + + void modifyItem(int index, const QString &name, const QString &number) { + list[index] = QPair<QString,QString>(name, number); + emit itemsChanged(index, 1, roles()); + } + +private: + QList<QPair<QString,QString> > list; +}; + +tst_QFxPathView::tst_QFxPathView() +{ +} + +void tst_QFxPathView::items() +{ + QFxView *canvas = createView(SRCDIR "/data/pathview.xml"); + + TestModel model; + model.addItem("Fred", "12345"); + model.addItem("John", "2345"); + model.addItem("Bob", "54321"); + + QmlContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + + canvas->execute(); + qApp->processEvents(); + + QFxPathView *pathview = findItem<QFxPathView>(canvas->root(), "view"); + QVERIFY(pathview != 0); + + QCOMPARE(pathview->children()->count(), model.count()); // assumes all are visible + + for (int i = 0; i < model.count(); ++i) { + QFxText *name = findItem<QFxText>(pathview, "textName", i); + QVERIFY(name != 0); + QCOMPARE(name->text(), model.name(i)); + QFxText *number = findItem<QFxText>(pathview, "textNumber", i); + QVERIFY(number != 0); + QCOMPARE(number->text(), model.number(i)); + } + + delete canvas; +} + +void tst_QFxPathView::pathMoved() +{ + QFxView *canvas = createView(SRCDIR "/data/pathview.xml"); + + TestModel model; + model.addItem("Ben", "12345"); + model.addItem("Bohn", "2345"); + model.addItem("Bob", "54321"); + model.addItem("Bill", "4321"); + + QmlContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + + canvas->execute(); + qApp->processEvents(); + + QFxPathView *pathview = findItem<QFxPathView>(canvas->root(), "view"); + QVERIFY(pathview != 0); + + QFxRect *firstItem = findItem<QFxRect>(pathview, "wrapper", 0); + QVERIFY(firstItem); + QFxPath *path = qobject_cast<QFxPath*>(pathview->path()); + QVERIFY(path); + QPointF start = path->pointAt(0.0); + QPointF offset;//Center of item is at point, but pos is from corner + offset.setX(firstItem->width()/2); + offset.setY(firstItem->height()/2); + QCOMPARE(firstItem->pos() + offset, start); + pathview->setOffset(10); + QTest::qWait(1000);//Moving is animated? + + for(int i=0; i<model.count(); i++){ + QFxRect *curItem = findItem<QFxRect>(pathview, "wrapper", i); + QCOMPARE(curItem->pos() + offset, path->pointAt(0.1 + i*0.25)); + } + + pathview->setOffset(100); + QTest::qWait(1000);//Moving is animated? + QCOMPARE(firstItem->pos() + offset, start); + + delete canvas; +} + +void tst_QFxPathView::limitedItems() +{ + QFxView *canvas = createView(SRCDIR "/data/pathview.xml"); + + TestModel model; + for(int i=0; i<100; i++) + model.addItem("Bob", QString::number(i)); + + QmlContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + + canvas->execute(); + qApp->processEvents(); + + QFxPathView *pathview = findItem<QFxPathView>(canvas->root(), "view"); + QVERIFY(pathview != 0); + + pathview->setPathItemCount(10); + QCOMPARE(pathview->pathItemCount(), 10); + + QFxRect *testItem = findItem<QFxRect>(pathview, "wrapper", 0); + QVERIFY(testItem != 0); + testItem = findItem<QFxRect>(pathview, "wrapper", 9); + QVERIFY(testItem != 0); + testItem = findItem<QFxRect>(pathview, "wrapper", 10); + QVERIFY(testItem == 0); + + pathview->setCurrentIndex(50); + QTest::qWait(5100);//Moving is animated and it's travelling far - should be reconsidered. + testItem = findItem<QFxRect>(pathview, "wrapper", 0); + QVERIFY(testItem == 0); + testItem = findItem<QFxRect>(pathview, "wrapper", 1); + QVERIFY(testItem == 0); + testItem = findItem<QFxRect>(pathview, "wrapper", 9); + QVERIFY(testItem == 0); + testItem = findItem<QFxRect>(pathview, "wrapper", 50); + QVERIFY(testItem != 0); +} + +QFxView *tst_QFxPathView::createView(const QString &filename) +{ + QFxView *canvas = new QFxView(0); + canvas->setFixedSize(240,320); + + QFile file(filename); + file.open(QFile::ReadOnly); + QString xml = file.readAll(); + canvas->setQml(xml, filename); + + return canvas; +} + +/* + Find an item with the specified id. If index is supplied then the + item must also evaluate the {index} expression equal to index +*/ +template<typename T> +T *tst_QFxPathView::findItem(QFxItem *parent, const QString &id, int index) +{ + const QMetaObject &mo = T::staticMetaObject; + for (int i = 0; i < parent->children()->count(); ++i) { + QFxItem *item = parent->children()->at(i); + if (mo.cast(item) && (id.isEmpty() || item->id() == id)) { + if (index != -1) { + QmlExpression e(qmlContext(item), "index", item); + e.setTrackChange(false); + if (e.value().toInt() == index) + return static_cast<T*>(item); + } else { + return static_cast<T*>(item); + } + } + item = findItem<T>(item, id, index); + if (item) + return static_cast<T*>(item); + } + + return 0; +} + +QTEST_MAIN(tst_QFxPathView) + +#include "tst_pathview.moc" diff --git a/tests/auto/declarative/qbindablemap/qbindablemap.pro b/tests/auto/declarative/qbindablemap/qbindablemap.pro new file mode 100644 index 0000000..b042405 --- /dev/null +++ b/tests/auto/declarative/qbindablemap/qbindablemap.pro @@ -0,0 +1,3 @@ +load(qttest_p4) +contains(QT_CONFIG,declarative): QT += declarative +SOURCES += tst_qbindablemap.cpp diff --git a/tests/auto/declarative/qbindablemap/tst_qbindablemap.cpp b/tests/auto/declarative/qbindablemap/tst_qbindablemap.cpp new file mode 100644 index 0000000..a8046e6 --- /dev/null +++ b/tests/auto/declarative/qbindablemap/tst_qbindablemap.cpp @@ -0,0 +1,72 @@ +#include <qtest.h> +#include <QtDeclarative/qmlengine.h> +#include <QtDeclarative/qmlcontext.h> +#include <QtDeclarative/qbindablemap.h> +#include <QtDeclarative/qmlcomponent.h> +#include <QSignalSpy> + +class tst_QBindableMap : public QObject +{ + Q_OBJECT +public: + tst_QBindableMap() {} + +private slots: + void insert(); + void clear(); + void changed(); +}; + +void tst_QBindableMap::insert() +{ + QBindableMap map; + map.setValue(QLatin1String("key1"),100); + map.setValue(QLatin1String("key2"),200); + QVERIFY(map.keys().count() == 2); + + QCOMPARE(map.value(QLatin1String("key1")), QVariant(100)); + QCOMPARE(map.value(QLatin1String("key2")), QVariant(200)); + + map.setValue(QLatin1String("key1"),"Hello World"); + QCOMPARE(map.value(QLatin1String("key1")), QVariant("Hello World")); +} + +void tst_QBindableMap::clear() +{ + QBindableMap map; + map.setValue(QLatin1String("key1"),100); + QVERIFY(map.keys().count() == 1); + + QCOMPARE(map.value(QLatin1String("key1")), QVariant(100)); + + map.clearValue(QLatin1String("key1")); + QVERIFY(map.keys().count() == 1); + QCOMPARE(map.value(QLatin1String("key1")), QVariant()); +} + +void tst_QBindableMap::changed() +{ + QBindableMap map; + QSignalSpy spy(&map, SIGNAL(changed(const QString&))); + map.setValue(QLatin1String("key1"),100); + map.setValue(QLatin1String("key2"),200); + QCOMPARE(spy.count(), 0); + + map.clearValue(QLatin1String("key1")); + QCOMPARE(spy.count(), 0); + + //make changes in QML + QmlEngine engine; + QmlContext *ctxt = engine.rootContext(); + ctxt->setContextProperty(QLatin1String("data"), &map); + QmlComponent component(&engine, "Script { script: \"data.key1 = 'Hello World';\" }"); + component.create(); + QCOMPARE(spy.count(), 1); + QList<QVariant> arguments = spy.takeFirst(); + QCOMPARE(arguments.at(0).toString(),QLatin1String("key1")); + QCOMPARE(map.value(QLatin1String("key1")), QVariant("Hello World")); +} + +QTEST_MAIN(tst_QBindableMap) + +#include "tst_qbindablemap.moc" diff --git a/tests/auto/declarative/qfxtext/qfxtext.pro b/tests/auto/declarative/qfxtext/qfxtext.pro new file mode 100644 index 0000000..f705334 --- /dev/null +++ b/tests/auto/declarative/qfxtext/qfxtext.pro @@ -0,0 +1,3 @@ +load(qttest_p4) +contains(QT_CONFIG,declarative): QT += declarative gui +SOURCES += tst_qfxtext.cpp diff --git a/tests/auto/declarative/qfxtext/tst_qfxtext.cpp b/tests/auto/declarative/qfxtext/tst_qfxtext.cpp new file mode 100644 index 0000000..0eb9f97 --- /dev/null +++ b/tests/auto/declarative/qfxtext/tst_qfxtext.cpp @@ -0,0 +1,413 @@ +#include <qtest.h> +#include <QTextDocument> +#include <QtDeclarative/qmlengine.h> +#include <QtDeclarative/qmlcomponent.h> +#include <QtDeclarative/qfxtext.h> +#include <QFontMetrics> + +class tst_qfxtext : public QObject + +{ + Q_OBJECT +public: + tst_qfxtext(); + +private slots: + void text(); + void width(); + void wrap(); + void elide(); + + // ### these tests may be trivial + void hAlign(); + void vAlign(); + void font(); + void style(); + void color(); + +private: + QStringList standard; + QStringList richText; + + QStringList hAlignmentStrings; + QStringList vAlignmentStrings; + + QList<Qt::Alignment> vAlignments; + QList<Qt::Alignment> hAlignments; + + QStringList styleStrings; + QList<QFxText::TextStyle> styles; + + QStringList colorStrings; + + QmlEngine engine; +}; + +tst_qfxtext::tst_qfxtext() +{ + standard << "the quick brown fox jumped over the lazy dog" + << "the quick brown fox\n jumped over the lazy dog"; + + richText << "<i>the <b>quick</b> brown <a href=\\\"http://www.google.com\\\">fox</a> jumped over the <b>lazy</b> dog</i>" + << "<i>the <b>quick</b> brown <a href=\\\"http://www.google.com\\\">fox</a><br>jumped over the <b>lazy</b> dog</i>"; + + hAlignmentStrings << "AlignLeft" + << "AlignRight" + << "AlignHCenter"; + + vAlignmentStrings << "AlignTop" + << "AlignBottom" + << "AlignVCenter"; + + hAlignments << Qt::AlignLeft + << Qt::AlignRight + << Qt::AlignHCenter; + + vAlignments << Qt::AlignTop + << Qt::AlignBottom + << Qt::AlignVCenter; + + styleStrings << "Normal" + << "Outline" + << "Raised" + << "Sunken"; + + styles << QFxText::Normal + << QFxText::Outline + << QFxText::Raised + << QFxText::Sunken; + + colorStrings << "aliceblue" + << "antiquewhite" + << "aqua" + << "darkkhaki" + << "darkolivegreen" + << "dimgray" + << "palevioletred" + << "lightsteelblue" + << "#000000" + << "#AAAAAA" + << "#FFFFFF" + << "#2AC05F"; + // + // need a different test to do alpha channel test + // << "#AA0011DD" + // << "#00F16B11"; + // +} + +void tst_qfxtext::text() +{ + { + QmlComponent textComponent(&engine, "Text { text: \"\" }"); + QFxText *textObject = qobject_cast<QFxText*>(textComponent.create()); + + QVERIFY(textObject != 0); + QCOMPARE(textObject->text(), QString("")); + } + + for (int i = 0; i < standard.size(); i++) + { + QString componentStr = "Text { text: \"" + standard.at(i) + "\" }"; + QmlComponent textComponent(&engine, componentStr.toLatin1()); + QFxText *textObject = qobject_cast<QFxText*>(textComponent.create()); + + QVERIFY(textObject != 0); + QCOMPARE(textObject->text(), standard.at(i)); + } + + for (int i = 0; i < richText.size(); i++) + { + QString componentStr = "Text { text: \"" + richText.at(i) + "\" }"; + QmlComponent textComponent(&engine, componentStr.toLatin1()); + QFxText *textObject = qobject_cast<QFxText*>(textComponent.create()); + + QVERIFY(textObject != 0); + QString expected = richText.at(i); + QCOMPARE(textObject->text(), expected.replace("\\\"", "\"")); + } +} + +void tst_qfxtext::width() +{ + // uses Font metrics to find the width for standard and document to find the width for rich + { + QmlComponent textComponent(&engine, "Text { text: \"\" }"); + QFxText *textObject = qobject_cast<QFxText*>(textComponent.create()); + + QCOMPARE(textObject->width(), 0.); + } + + for (int i = 0; i < standard.size(); i++) + { + QFont f; + QFontMetrics fm(f); + int metricWidth = fm.size(Qt::TextExpandTabs && Qt::TextShowMnemonic, standard.at(i)).width(); + + QString componentStr = "Text { text: \"" + standard.at(i) + "\" }"; + QmlComponent textComponent(&engine, componentStr.toLatin1()); + QFxText *textObject = qobject_cast<QFxText*>(textComponent.create()); + + QCOMPARE(textObject->width(), qreal(metricWidth)); + } + + for (int i = 0; i < richText.size(); i++) + { + QTextDocument document; + document.setHtml(richText.at(i)); + document.setDocumentMargin(0); + + int documentWidth = document.idealWidth(); + + QString componentStr = "Text { text: \"" + richText.at(i) + "\" }"; + QmlComponent textComponent(&engine, componentStr.toLatin1()); + QFxText *textObject = qobject_cast<QFxText*>(textComponent.create()); + + QCOMPARE(textObject->width(), qreal(documentWidth)); + } +} + +void tst_qfxtext::wrap() +{ + // XXX Poor coverage - should at least be testing an expected height. + + // for specified width and wrap set true + { + QmlComponent textComponent(&engine, "Text { text: \"\"; wrap: true; width: 300 }"); + QFxText *textObject = qobject_cast<QFxText*>(textComponent.create()); + + QCOMPARE(textObject->width(), 300.); + } + + for (int i = 0; i < standard.size(); i++) + { + QString componentStr = "Text { wrap: true; width: 300; text: \"" + standard.at(i) + "\" }"; + QmlComponent textComponent(&engine, componentStr.toLatin1()); + QFxText *textObject = qobject_cast<QFxText*>(textComponent.create()); + + QCOMPARE(textObject->width(), 300.); + } + + for (int i = 0; i < richText.size(); i++) + { + QString componentStr = "Text { wrap: true; width: 300; text: \"" + richText.at(i) + "\" }"; + QmlComponent textComponent(&engine, componentStr.toLatin1()); + QFxText *textObject = qobject_cast<QFxText*>(textComponent.create()); + + QCOMPARE(textObject->width(), 300.); + } + +} + +void tst_qfxtext::elide() +{ + for (Qt::TextElideMode m = Qt::ElideLeft; m<=Qt::ElideNone; m=Qt::TextElideMode(int(m)+1)) { + const char* elidename[]={"ElideLeft", "ElideRight", "ElideMiddle", "ElideNone"}; + QString elide = "elide: \""+QString(elidename[int(m)])+"\";"; + + // XXX Poor coverage. + + { + QmlComponent textComponent(&engine, ("Text { text: \"\"; "+elide+" width: 300 }").toLatin1()); + QFxText *textObject = qobject_cast<QFxText*>(textComponent.create()); + + QCOMPARE(textObject->width(), 300.); + } + + for (int i = 0; i < standard.size(); i++) + { + QString componentStr = "Text { "+elide+" width: 300; text: \"" + standard.at(i) + "\" }"; + QmlComponent textComponent(&engine, componentStr.toLatin1()); + QFxText *textObject = qobject_cast<QFxText*>(textComponent.create()); + + QCOMPARE(textObject->width(), 300.); + } + + // richtext - does nothing + for (int i = 0; i < richText.size(); i++) + { + QString componentStr = "Text { "+elide+" width: 300; text: \"" + richText.at(i) + "\" }"; + QmlComponent textComponent(&engine, componentStr.toLatin1()); + QFxText *textObject = qobject_cast<QFxText*>(textComponent.create()); + + QCOMPARE(textObject->width(), 300.); + } + } +} + +//the alignment tests may be trivial o.oa +void tst_qfxtext::hAlign() +{ + //test one align each, and then test if two align fails. + + for (int i = 0; i < standard.size(); i++) + { + for (int j=0; j < hAlignmentStrings.size(); j++) + { + QString componentStr = "Text { hAlign: \"" + hAlignmentStrings.at(j) + "\"; text: \"" + standard.at(i) + "\" }"; + QmlComponent textComponent(&engine, componentStr.toLatin1()); + QFxText *textObject = qobject_cast<QFxText*>(textComponent.create()); + + QCOMPARE((int)textObject->hAlign(), (int)hAlignments.at(j)); + } + } + + for (int i = 0; i < richText.size(); i++) + { + for (int j=0; j < hAlignmentStrings.size(); j++) + { + QString componentStr = "Text { hAlign: \"" + hAlignmentStrings.at(j) + "\"; text: \"" + richText.at(i) + "\" }"; + QmlComponent textComponent(&engine, componentStr.toLatin1()); + QFxText *textObject = qobject_cast<QFxText*>(textComponent.create()); + + QCOMPARE((int)textObject->hAlign(), (int)hAlignments.at(j)); + } + } + +} + +void tst_qfxtext::vAlign() +{ + //test one align each, and then test if two align fails. + + for (int i = 0; i < standard.size(); i++) + { + for (int j=0; j < vAlignmentStrings.size(); j++) + { + QString componentStr = "Text { vAlign: \"" + vAlignmentStrings.at(j) + "\"; text: \"" + standard.at(i) + "\" }"; + QmlComponent textComponent(&engine, componentStr.toLatin1()); + QFxText *textObject = qobject_cast<QFxText*>(textComponent.create()); + + QCOMPARE((int)textObject->vAlign(), (int)vAlignments.at(j)); + } + } + + for (int i = 0; i < richText.size(); i++) + { + for (int j=0; j < vAlignmentStrings.size(); j++) + { + QString componentStr = "Text { vAlign: \"" + vAlignmentStrings.at(j) + "\"; text: \"" + richText.at(i) + "\" }"; + QmlComponent textComponent(&engine, componentStr.toLatin1()); + QFxText *textObject = qobject_cast<QFxText*>(textComponent.create()); + + QCOMPARE((int)textObject->vAlign(), (int)vAlignments.at(j)); + } + } + +} + +void tst_qfxtext::font() +{ + //test size, then bold, then italic, then family + { + QString componentStr = "Text { font.size: 40; text: \"Hello World\" }"; + QmlComponent textComponent(&engine, componentStr.toLatin1()); + QFxText *textObject = qobject_cast<QFxText*>(textComponent.create()); + + QCOMPARE(textObject->font()->size(), qreal(40)); + QCOMPARE(textObject->font()->bold(), false); + QCOMPARE(textObject->font()->italic(), false); + } + + { + QString componentStr = "Text { font.bold: true; text: \"Hello World\" }"; + QmlComponent textComponent(&engine, componentStr.toLatin1()); + QFxText *textObject = qobject_cast<QFxText*>(textComponent.create()); + + QCOMPARE(textObject->font()->bold(), true); + QCOMPARE(textObject->font()->italic(), false); + } + + { + QString componentStr = "Text { font.italic: true; text: \"Hello World\" }"; + QmlComponent textComponent(&engine, componentStr.toLatin1()); + QFxText *textObject = qobject_cast<QFxText*>(textComponent.create()); + + QCOMPARE(textObject->font()->italic(), true); + QCOMPARE(textObject->font()->bold(), false); + } + + { + QString componentStr = "Text { font.family: \"Helvetica\"; text: \"Hello World\" }"; + QmlComponent textComponent(&engine, componentStr.toLatin1()); + QFxText *textObject = qobject_cast<QFxText*>(textComponent.create()); + + QCOMPARE(textObject->font()->family(), QString("Helvetica")); + QCOMPARE(textObject->font()->bold(), false); + QCOMPARE(textObject->font()->italic(), false); + } + + { + QString componentStr = "Text { font.family: \"\"; text: \"Hello World\" }"; + QmlComponent textComponent(&engine, componentStr.toLatin1()); + QFxText *textObject = qobject_cast<QFxText*>(textComponent.create()); + + QCOMPARE(textObject->font()->family(), QString("")); + } +} + +void tst_qfxtext::style() +{ + //test style + for (int i = 0; i < styles.size(); i++) + { + QString componentStr = "Text { style: \"" + styleStrings.at(i) + "\"; text: \"Hello World\" }"; + QmlComponent textComponent(&engine, componentStr.toLatin1()); + QFxText *textObject = qobject_cast<QFxText*>(textComponent.create()); + + QCOMPARE((int)textObject->style(), (int)styles.at(i)); + QCOMPARE(textObject->styleColor(), QColor()); + } +} + +void tst_qfxtext::color() +{ + //test style + for (int i = 0; i < colorStrings.size(); i++) + { + QString componentStr = "Text { color: \"" + colorStrings.at(i) + "\"; text: \"Hello World\" }"; + QmlComponent textComponent(&engine, componentStr.toLatin1()); + QFxText *textObject = qobject_cast<QFxText*>(textComponent.create()); + + QCOMPARE(textObject->color(), QColor(colorStrings.at(i))); + QCOMPARE(textObject->styleColor(), QColor()); + } + + for (int i = 0; i < colorStrings.size(); i++) + { + QString componentStr = "Text { styleColor: \"" + colorStrings.at(i) + "\"; text: \"Hello World\" }"; + QmlComponent textComponent(&engine, componentStr.toLatin1()); + QFxText *textObject = qobject_cast<QFxText*>(textComponent.create()); + + QCOMPARE(textObject->styleColor(), QColor(colorStrings.at(i))); + // default color to black? + QCOMPARE(textObject->color(), QColor("black")); + } + + for (int i = 0; i < colorStrings.size(); i++) + { + for (int j = 0; j < colorStrings.size(); j++) + { + QString componentStr = "Text { color: \"" + colorStrings.at(i) + "\"; styleColor: \"" + colorStrings.at(j) + "\"; text: \"Hello World\" }"; + QmlComponent textComponent(&engine, componentStr.toLatin1()); + QFxText *textObject = qobject_cast<QFxText*>(textComponent.create()); + + QCOMPARE(textObject->color(), QColor(colorStrings.at(i))); + QCOMPARE(textObject->styleColor(), QColor(colorStrings.at(j))); + } + } + { + QString colorStr = "#AA001234"; + QColor testColor("#001234"); + testColor.setAlpha(170); + + QString componentStr = "Text { color: \"" + colorStr + "\"; text: \"Hello World\" }"; + QmlComponent textComponent(&engine, componentStr.toLatin1()); + QFxText *textObject = qobject_cast<QFxText*>(textComponent.create()); + + QCOMPARE(textObject->color(), testColor); + } +} +QTEST_MAIN(tst_qfxtext) + +#include "tst_qfxtext.moc" diff --git a/tests/auto/declarative/qfxtextedit/qfxtextedit.pro b/tests/auto/declarative/qfxtextedit/qfxtextedit.pro new file mode 100644 index 0000000..59ab6e5 --- /dev/null +++ b/tests/auto/declarative/qfxtextedit/qfxtextedit.pro @@ -0,0 +1,3 @@ +load(qttest_p4) +contains(QT_CONFIG,declarative): QT += declarative gui +SOURCES += tst_qfxtextedit.cpp diff --git a/tests/auto/declarative/qfxtextedit/tst_qfxtextedit.cpp b/tests/auto/declarative/qfxtextedit/tst_qfxtextedit.cpp new file mode 100644 index 0000000..7be5b50 --- /dev/null +++ b/tests/auto/declarative/qfxtextedit/tst_qfxtextedit.cpp @@ -0,0 +1,326 @@ +#include <qtest.h> +#include <QTextDocument> +#include <QtDeclarative/qmlengine.h> +#include <QtDeclarative/qmlcomponent.h> +#include <QtDeclarative/qfxtextedit.h> +#include <QFontMetrics> + +class tst_qfxtextedit : public QObject + +{ + Q_OBJECT +public: + tst_qfxtextedit(); + +private slots: + void text(); + void width(); + void wrap(); + + // ### these tests may be trivial + void hAlign(); + void vAlign(); + void font(); + void color(); + +private: + QStringList standard; + QStringList richText; + + QStringList hAlignmentStrings; + QStringList vAlignmentStrings; + + QList<Qt::Alignment> vAlignments; + QList<Qt::Alignment> hAlignments; + + QStringList colorStrings; + + QmlEngine engine; +}; + +tst_qfxtextedit::tst_qfxtextedit() +{ + standard << "the quick brown fox jumped over the lazy dog" + << "the quick brown fox\n jumped over the lazy dog"; + + richText << "<i>the <b>quick</b> brown <a href=\\\"http://www.google.com\\\">fox</a> jumped over the <b>lazy</b> dog</i>" + << "<i>the <b>quick</b> brown <a href=\\\"http://www.google.com\\\">fox</a><br>jumped over the <b>lazy</b> dog</i>"; + + hAlignmentStrings << "AlignLeft" + << "AlignRight" + << "AlignHCenter"; + + vAlignmentStrings << "AlignTop" + << "AlignBottom" + << "AlignVCenter"; + + hAlignments << Qt::AlignLeft + << Qt::AlignRight + << Qt::AlignHCenter; + + vAlignments << Qt::AlignTop + << Qt::AlignBottom + << Qt::AlignVCenter; + + colorStrings << "aliceblue" + << "antiquewhite" + << "aqua" + << "darkkhaki" + << "darkolivegreen" + << "dimgray" + << "palevioletred" + << "lightsteelblue" + << "#000000" + << "#AAAAAA" + << "#FFFFFF" + << "#2AC05F"; + // + // need a different test to do alpha channel test + // << "#AA0011DD" + // << "#00F16B11"; + // +} + +void tst_qfxtextedit::text() +{ + { + QmlComponent texteditComponent(&engine, "TextEdit { text: \"\" }"); + QFxTextEdit *textEditObject = qobject_cast<QFxTextEdit*>(texteditComponent.create()); + + QVERIFY(textEditObject != 0); + QCOMPARE(textEditObject->text(), QString("")); + } + + for (int i = 0; i < standard.size(); i++) + { + QString componentStr = "TextEdit { text: \"" + standard.at(i) + "\" }"; + QmlComponent texteditComponent(&engine, componentStr.toLatin1()); + QFxTextEdit *textEditObject = qobject_cast<QFxTextEdit*>(texteditComponent.create()); + + QVERIFY(textEditObject != 0); + QCOMPARE(textEditObject->text(), standard.at(i)); + } + + for (int i = 0; i < richText.size(); i++) + { + QString componentStr = "TextEdit { text: \"" + richText.at(i) + "\" }"; + QmlComponent texteditComponent(&engine, componentStr.toLatin1()); + QFxTextEdit *textEditObject = qobject_cast<QFxTextEdit*>(texteditComponent.create()); + + QVERIFY(textEditObject != 0); + QString actual = textEditObject->text(); + QString expected = richText.at(i); + actual.replace(QRegExp(".*<body[^>]*>"),""); + actual.replace(QRegExp("(<[^>]*>)+"),"<>"); + expected.replace(QRegExp("(<[^>]*>)+"),"<>"); + QCOMPARE(actual.simplified(),expected.simplified()); + } +} + +void tst_qfxtextedit::width() +{ + // uses Font metrics to find the width for standard and document to find the width for rich + { + QmlComponent texteditComponent(&engine, "TextEdit { text: \"\" }"); + QFxTextEdit *textEditObject = qobject_cast<QFxTextEdit*>(texteditComponent.create()); + + QCOMPARE(textEditObject->width(), 0.); + } + + for (int i = 0; i < standard.size(); i++) + { + QFont f; + QFontMetrics fm(f); + int metricWidth = fm.size(Qt::TextExpandTabs && Qt::TextShowMnemonic, standard.at(i)).width(); + + QString componentStr = "TextEdit { text: \"" + standard.at(i) + "\" }"; + QmlComponent texteditComponent(&engine, componentStr.toLatin1()); + QFxTextEdit *textEditObject = qobject_cast<QFxTextEdit*>(texteditComponent.create()); + + QCOMPARE(textEditObject->width(), qreal(metricWidth)); + } + + for (int i = 0; i < richText.size(); i++) + { + QTextDocument document; + document.setHtml(richText.at(i)); + document.setDocumentMargin(0); + + int documentWidth = document.idealWidth(); + + QString componentStr = "TextEdit { text: \"" + richText.at(i) + "\" }"; + QmlComponent texteditComponent(&engine, componentStr.toLatin1()); + QFxTextEdit *textEditObject = qobject_cast<QFxTextEdit*>(texteditComponent.create()); + + QCOMPARE(textEditObject->width(), qreal(documentWidth)); + } +} + +void tst_qfxtextedit::wrap() +{ + // for specified width and wrap set true + { + QmlComponent texteditComponent(&engine, "TextEdit { text: \"\"; wrap: true; width: 300 }"); + QFxTextEdit *textEditObject = qobject_cast<QFxTextEdit*>(texteditComponent.create()); + + QCOMPARE(textEditObject->width(), 300.); + } + + for (int i = 0; i < standard.size(); i++) + { + QString componentStr = "TextEdit { wrap: true; width: 300; text: \"" + standard.at(i) + "\" }"; + QmlComponent texteditComponent(&engine, componentStr.toLatin1()); + QFxTextEdit *textEditObject = qobject_cast<QFxTextEdit*>(texteditComponent.create()); + + QCOMPARE(textEditObject->width(), 300.); + } + + for (int i = 0; i < richText.size(); i++) + { + QString componentStr = "TextEdit { wrap: true; width: 300; text: \"" + richText.at(i) + "\" }"; + QmlComponent texteditComponent(&engine, componentStr.toLatin1()); + QFxTextEdit *textEditObject = qobject_cast<QFxTextEdit*>(texteditComponent.create()); + + QCOMPARE(textEditObject->width(), 300.); + } + +} + +//the alignment tests may be trivial o.oa +void tst_qfxtextedit::hAlign() +{ + //test one align each, and then test if two align fails. + + for (int i = 0; i < standard.size(); i++) + { + for (int j=0; j < hAlignmentStrings.size(); j++) + { + QString componentStr = "TextEdit { hAlign: \"" + hAlignmentStrings.at(j) + "\"; text: \"" + standard.at(i) + "\" }"; + QmlComponent texteditComponent(&engine, componentStr.toLatin1()); + QFxTextEdit *textEditObject = qobject_cast<QFxTextEdit*>(texteditComponent.create()); + + QCOMPARE((int)textEditObject->hAlign(), (int)hAlignments.at(j)); + } + } + + for (int i = 0; i < richText.size(); i++) + { + for (int j=0; j < hAlignmentStrings.size(); j++) + { + QString componentStr = "TextEdit { hAlign: \"" + hAlignmentStrings.at(j) + "\"; text: \"" + richText.at(i) + "\" }"; + QmlComponent texteditComponent(&engine, componentStr.toLatin1()); + QFxTextEdit *textEditObject = qobject_cast<QFxTextEdit*>(texteditComponent.create()); + + QCOMPARE((int)textEditObject->hAlign(), (int)hAlignments.at(j)); + } + } + +} + +void tst_qfxtextedit::vAlign() +{ + //test one align each, and then test if two align fails. + + for (int i = 0; i < standard.size(); i++) + { + for (int j=0; j < vAlignmentStrings.size(); j++) + { + QString componentStr = "TextEdit { vAlign: \"" + vAlignmentStrings.at(j) + "\"; text: \"" + standard.at(i) + "\" }"; + QmlComponent texteditComponent(&engine, componentStr.toLatin1()); + QFxTextEdit *textEditObject = qobject_cast<QFxTextEdit*>(texteditComponent.create()); + + QCOMPARE((int)textEditObject->vAlign(), (int)vAlignments.at(j)); + } + } + + for (int i = 0; i < richText.size(); i++) + { + for (int j=0; j < vAlignmentStrings.size(); j++) + { + QString componentStr = "TextEdit { vAlign: \"" + vAlignmentStrings.at(j) + "\"; text: \"" + richText.at(i) + "\" }"; + QmlComponent texteditComponent(&engine, componentStr.toLatin1()); + QFxTextEdit *textEditObject = qobject_cast<QFxTextEdit*>(texteditComponent.create()); + + QCOMPARE((int)textEditObject->vAlign(), (int)vAlignments.at(j)); + } + } + +} + +void tst_qfxtextedit::font() +{ + //test size, then bold, then italic, then family + { + QString componentStr = "TextEdit { font.size: 40; text: \"Hello World\" }"; + QmlComponent texteditComponent(&engine, componentStr.toLatin1()); + QFxTextEdit *textEditObject = qobject_cast<QFxTextEdit*>(texteditComponent.create()); + + QCOMPARE(textEditObject->font()->size(), qreal(40)); + QCOMPARE(textEditObject->font()->bold(), false); + QCOMPARE(textEditObject->font()->italic(), false); + } + + { + QString componentStr = "TextEdit { font.bold: true; text: \"Hello World\" }"; + QmlComponent texteditComponent(&engine, componentStr.toLatin1()); + QFxTextEdit *textEditObject = qobject_cast<QFxTextEdit*>(texteditComponent.create()); + + QCOMPARE(textEditObject->font()->bold(), true); + QCOMPARE(textEditObject->font()->italic(), false); + } + + { + QString componentStr = "TextEdit { font.italic: true; text: \"Hello World\" }"; + QmlComponent texteditComponent(&engine, componentStr.toLatin1()); + QFxTextEdit *textEditObject = qobject_cast<QFxTextEdit*>(texteditComponent.create()); + + QCOMPARE(textEditObject->font()->italic(), true); + QCOMPARE(textEditObject->font()->bold(), false); + } + + { + QString componentStr = "TextEdit { font.family: \"Helvetica\"; text: \"Hello World\" }"; + QmlComponent texteditComponent(&engine, componentStr.toLatin1()); + QFxTextEdit *textEditObject = qobject_cast<QFxTextEdit*>(texteditComponent.create()); + + QCOMPARE(textEditObject->font()->family(), QString("Helvetica")); + QCOMPARE(textEditObject->font()->bold(), false); + QCOMPARE(textEditObject->font()->italic(), false); + } + + { + QString componentStr = "TextEdit { font.family: \"\"; text: \"Hello World\" }"; + QmlComponent texteditComponent(&engine, componentStr.toLatin1()); + QFxTextEdit *textEditObject = qobject_cast<QFxTextEdit*>(texteditComponent.create()); + + QCOMPARE(textEditObject->font()->family(), QString("")); + } +} + +void tst_qfxtextedit::color() +{ + //test style + for (int i = 0; i < colorStrings.size(); i++) + { + QString componentStr = "TextEdit { color: \"" + colorStrings.at(i) + "\"; text: \"Hello World\" }"; + QmlComponent texteditComponent(&engine, componentStr.toLatin1()); + QFxTextEdit *textEditObject = qobject_cast<QFxTextEdit*>(texteditComponent.create()); + //qDebug() << "textEditObject: " << textEditObject->color() << "vs. " << QColor(colorStrings.at(i)); + QCOMPARE(textEditObject->color(), QColor(colorStrings.at(i))); + } + + { + QString colorStr = "#AA001234"; + QColor testColor("#001234"); + testColor.setAlpha(170); + + QString componentStr = "TextEdit { color: \"" + colorStr + "\"; text: \"Hello World\" }"; + QmlComponent texteditComponent(&engine, componentStr.toLatin1()); + QFxTextEdit *textEditObject = qobject_cast<QFxTextEdit*>(texteditComponent.create()); + + QCOMPARE(textEditObject->color(), testColor); + } +} +QTEST_MAIN(tst_qfxtextedit) + +#include "tst_qfxtextedit.moc" diff --git a/tests/auto/declarative/qmlbindengine/bindingLoop.txt b/tests/auto/declarative/qmlbindengine/bindingLoop.txt new file mode 100644 index 0000000..e27a76c --- /dev/null +++ b/tests/auto/declarative/qmlbindengine/bindingLoop.txt @@ -0,0 +1,12 @@ +MyQmlContainer { + children : [ + MyQmlObject { + id: Object1 + stringProperty: "hello" + Object2.stringProperty + }, + MyQmlObject { + id: Object2 + stringProperty: "hello" + Object1.stringProperty + } + ] +} diff --git a/tests/auto/declarative/qmlbindengine/boolPropertiesEvaluateAsBool.1.txt b/tests/auto/declarative/qmlbindengine/boolPropertiesEvaluateAsBool.1.txt new file mode 100644 index 0000000..7368ff6 --- /dev/null +++ b/tests/auto/declarative/qmlbindengine/boolPropertiesEvaluateAsBool.1.txt @@ -0,0 +1,3 @@ +MyQmlObject { + stringProperty: trueProperty?'pass':'fail' +} diff --git a/tests/auto/declarative/qmlbindengine/boolPropertiesEvaluateAsBool.2.txt b/tests/auto/declarative/qmlbindengine/boolPropertiesEvaluateAsBool.2.txt new file mode 100644 index 0000000..c74493e --- /dev/null +++ b/tests/auto/declarative/qmlbindengine/boolPropertiesEvaluateAsBool.2.txt @@ -0,0 +1,3 @@ +MyQmlObject { + stringProperty: falseProperty?'fail':'pass' +} diff --git a/tests/auto/declarative/qmlbindengine/idShortcutInvalidates.1.txt b/tests/auto/declarative/qmlbindengine/idShortcutInvalidates.1.txt new file mode 100644 index 0000000..2687465 --- /dev/null +++ b/tests/auto/declarative/qmlbindengine/idShortcutInvalidates.1.txt @@ -0,0 +1,10 @@ +MyQmlObject { + objectProperty: if(1) OtherObject + + property var obj + + obj: Object { + id: OtherObject + } +} + diff --git a/tests/auto/declarative/qmlbindengine/idShortcutInvalidates.txt b/tests/auto/declarative/qmlbindengine/idShortcutInvalidates.txt new file mode 100644 index 0000000..4aa20ae --- /dev/null +++ b/tests/auto/declarative/qmlbindengine/idShortcutInvalidates.txt @@ -0,0 +1,9 @@ +MyQmlObject { + objectProperty: OtherObject + + property var obj + + obj: Object { + id: OtherObject + } +} diff --git a/tests/auto/declarative/qmlbindengine/methods.1.txt b/tests/auto/declarative/qmlbindengine/methods.1.txt new file mode 100644 index 0000000..35279e0 --- /dev/null +++ b/tests/auto/declarative/qmlbindengine/methods.1.txt @@ -0,0 +1,4 @@ +MyQmlObject { + id: MyObject + onBasicSignal: MyObject.method() +} diff --git a/tests/auto/declarative/qmlbindengine/methods.2.txt b/tests/auto/declarative/qmlbindengine/methods.2.txt new file mode 100644 index 0000000..352913a --- /dev/null +++ b/tests/auto/declarative/qmlbindengine/methods.2.txt @@ -0,0 +1,4 @@ +MyQmlObject { + id: MyObject + onBasicSignal: MyObject.method(163) +} diff --git a/tests/auto/declarative/qmlbindengine/qmlbindengine.pro b/tests/auto/declarative/qmlbindengine/qmlbindengine.pro new file mode 100644 index 0000000..4a38ac9 --- /dev/null +++ b/tests/auto/declarative/qmlbindengine/qmlbindengine.pro @@ -0,0 +1,9 @@ +load(qttest_p4) +contains(QT_CONFIG,declarative): QT += declarative +macx:CONFIG -= app_bundle +SOURCES += tst_qmlbindengine.cpp \ + testtypes.cpp +HEADERS += testtypes.h + +# QMAKE_CXXFLAGS = -fprofile-arcs -ftest-coverage +# LIBS += -lgcov diff --git a/tests/auto/declarative/qmlbindengine/signalAssignment.1.txt b/tests/auto/declarative/qmlbindengine/signalAssignment.1.txt new file mode 100644 index 0000000..ca682fa --- /dev/null +++ b/tests/auto/declarative/qmlbindengine/signalAssignment.1.txt @@ -0,0 +1,3 @@ +MyQmlObject { + onBasicSignal: setString('pass') +} diff --git a/tests/auto/declarative/qmlbindengine/signalAssignment.2.txt b/tests/auto/declarative/qmlbindengine/signalAssignment.2.txt new file mode 100644 index 0000000..5efd583 --- /dev/null +++ b/tests/auto/declarative/qmlbindengine/signalAssignment.2.txt @@ -0,0 +1,3 @@ +MyQmlObject { + onArgumentSignal: setString('pass ' + a + ' ' + b + ' ' + c) +} diff --git a/tests/auto/declarative/qmlbindengine/testtypes.cpp b/tests/auto/declarative/qmlbindengine/testtypes.cpp new file mode 100644 index 0000000..4bb0dc8 --- /dev/null +++ b/tests/auto/declarative/qmlbindengine/testtypes.cpp @@ -0,0 +1,4 @@ +#include "testtypes.h" + +QML_DEFINE_TYPE(MyQmlObject,MyQmlObject); +QML_DEFINE_TYPE(MyQmlContainer,MyQmlContainer); diff --git a/tests/auto/declarative/qmlbindengine/testtypes.h b/tests/auto/declarative/qmlbindengine/testtypes.h new file mode 100644 index 0000000..6a4bda6 --- /dev/null +++ b/tests/auto/declarative/qmlbindengine/testtypes.h @@ -0,0 +1,127 @@ +#ifndef TESTTYPES_H +#define TESTTYPES_H + +#include <QtCore/qobject.h> +#include <QtDeclarative/qml.h> +#include <QtDeclarative/qmlexpression.h> + +class MyQmlObject : public QObject +{ + Q_OBJECT + Q_PROPERTY(bool trueProperty READ trueProperty) + Q_PROPERTY(bool falseProperty READ falseProperty) + Q_PROPERTY(QString stringProperty READ stringProperty WRITE setStringProperty NOTIFY stringChanged) + Q_PROPERTY(QObject *objectProperty READ objectProperty WRITE setObjectProperty NOTIFY objectChanged); +public: + MyQmlObject(): m_methodCalled(false), m_methodIntCalled(false), m_object(0) {} + + bool trueProperty() const { return true; } + bool falseProperty() const { return false; } + + QString stringProperty() const { return m_string; } + void setStringProperty(const QString &s) + { + if (s == m_string) + return; + m_string = s; + emit stringChanged(); + } + + QObject *objectProperty() const { return m_object; } + void setObjectProperty(QObject *obj) { + if (obj == m_object) + return; + m_object = obj; + emit objectChanged(); + } + + bool methodCalled() const { return m_methodCalled; } + bool methodIntCalled() const { return m_methodIntCalled; } + + QString string() const { return m_string; } +signals: + void basicSignal(); + void argumentSignal(int a, QString b, qreal c); + void stringChanged(); + void objectChanged(); + +public slots: + void method() { m_methodCalled = true; } + void method(int a) { if(a == 163) m_methodIntCalled = true; } + void setString(const QString &s) { m_string = s; } + +private: + friend class tst_qmlbindengine; + bool m_methodCalled; + bool m_methodIntCalled; + + QObject *m_object; + QString m_string; +}; + +QML_DECLARE_TYPE(MyQmlObject); + +class MyQmlContainer : public QObject +{ + Q_OBJECT + Q_PROPERTY(QList<MyQmlContainer*>* children READ children) +public: + MyQmlContainer() {} + + QList<MyQmlContainer*> *children() { return &m_children; } + +private: + QList<MyQmlContainer*> m_children; +}; + +QML_DECLARE_TYPE(MyQmlContainer); + +class MyExpression : public QmlExpression +{ +public: + MyExpression(QmlContext *ctxt, const QString &expr) + : QmlExpression(ctxt, expr, 0), changed(false) + { + } + + virtual void valueChanged() { + changed = true; + } + bool changed; +}; + + +class MyDefaultObject1 : public QObject +{ + Q_OBJECT + Q_PROPERTY(int horseLegs READ horseLegs); + Q_PROPERTY(int antLegs READ antLegs); +public: + int horseLegs() const { return 4; } + int antLegs() const { return 6; } +}; + +class MyDefaultObject2 : public QObject +{ + Q_OBJECT + Q_PROPERTY(int antLegs READ antLegs); + Q_PROPERTY(int emuLegs READ emuLegs); +public: + int antLegs() const { return 5; } // Had an accident + int emuLegs() const { return 2; } +}; + +class MyDefaultObject3 : public QObject +{ + Q_OBJECT + Q_PROPERTY(int antLegs READ antLegs); + Q_PROPERTY(int humanLegs READ humanLegs); +public: + int antLegs() const { return 7; } // Mutant + int humanLegs() const { return 2; } + int millipedeLegs() const { return 1000; } +}; + + +#endif // TESTTYPES_H + diff --git a/tests/auto/declarative/qmlbindengine/tst_qmlbindengine.cpp b/tests/auto/declarative/qmlbindengine/tst_qmlbindengine.cpp new file mode 100644 index 0000000..a1efc5f --- /dev/null +++ b/tests/auto/declarative/qmlbindengine/tst_qmlbindengine.cpp @@ -0,0 +1,342 @@ +#include <qtest.h> +#include <QtDeclarative/qmlcomponent.h> +#include <QtDeclarative/qmlengine.h> +#include <QtDeclarative/qmlexpression.h> +#include <QtDeclarative/qmlcontext.h> +#include <QtCore/qfileinfo.h> +#include <QtCore/qdebug.h> +#include <QtCore/qdir.h> +#include "testtypes.h" + +inline QUrl TEST_FILE(const QString &filename) +{ + QFileInfo fileInfo(__FILE__); + return QUrl::fromLocalFile(fileInfo.absoluteDir().filePath(filename)); +} + +inline QUrl TEST_FILE(const char *filename) +{ + return TEST_FILE(QLatin1String(filename)); +} + +class tst_qmlbindengine : public QObject +{ + Q_OBJECT +public: + tst_qmlbindengine() {} + +private slots: + void idShortcutInvalidates(); + void boolPropertiesEvaluateAsBool(); + void methods(); + void signalAssignment(); + void bindingLoop(); + void basicExpressions(); + void basicExpressions_data(); + void arrayExpressions(); + void contextPropertiesTriggerReeval(); + void objectPropertiesTriggerReeval(); + +private: + QmlEngine engine; +}; + +void tst_qmlbindengine::idShortcutInvalidates() +{ + { + QmlComponent component(&engine, TEST_FILE("idShortcutInvalidates.txt")); + MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create()); + QVERIFY(object != 0); + QVERIFY(object->objectProperty() != 0); + delete object->objectProperty(); + QVERIFY(object->objectProperty() == 0); + } + + { + QmlComponent component(&engine, TEST_FILE("idShortcutInvalidates.1.txt")); + MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create()); + QVERIFY(object != 0); + QVERIFY(object->objectProperty() != 0); + delete object->objectProperty(); + QVERIFY(object->objectProperty() == 0); + } +} + +void tst_qmlbindengine::boolPropertiesEvaluateAsBool() +{ + { + QmlComponent component(&engine, TEST_FILE("boolPropertiesEvaluateAsBool.1.txt")); + MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create()); + QVERIFY(object != 0); + QCOMPARE(object->stringProperty(), QLatin1String("pass")); + } + { + QmlComponent component(&engine, TEST_FILE("boolPropertiesEvaluateAsBool.2.txt")); + MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create()); + QVERIFY(object != 0); + QCOMPARE(object->stringProperty(), QLatin1String("pass")); + } +} + +void tst_qmlbindengine::signalAssignment() +{ + { + QmlComponent component(&engine, TEST_FILE("signalAssignment.1.txt")); + MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create()); + QVERIFY(object != 0); + QCOMPARE(object->string(), QString()); + emit object->basicSignal(); + QCOMPARE(object->string(), QString("pass")); + } + + { + QmlComponent component(&engine, TEST_FILE("signalAssignment.2.txt")); + MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create()); + QVERIFY(object != 0); + QCOMPARE(object->string(), QString()); + emit object->argumentSignal(19, "Hello world!", 10.3); + QCOMPARE(object->string(), QString("pass 19 Hello world! 10.3")); + } +} + +void tst_qmlbindengine::methods() +{ + { + QmlComponent component(&engine, TEST_FILE("methods.1.txt")); + MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create()); + QVERIFY(object != 0); + QCOMPARE(object->methodCalled(), false); + QCOMPARE(object->methodIntCalled(), false); + emit object->basicSignal(); + QCOMPARE(object->methodCalled(), true); + QCOMPARE(object->methodIntCalled(), false); + } + + { + QmlComponent component(&engine, TEST_FILE("methods.2.txt")); + MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create()); + QVERIFY(object != 0); + QCOMPARE(object->methodCalled(), false); + QCOMPARE(object->methodIntCalled(), false); + emit object->basicSignal(); + QCOMPARE(object->methodCalled(), false); + QCOMPARE(object->methodIntCalled(), true); + } +} + +void tst_qmlbindengine::bindingLoop() +{ + QmlComponent component(&engine, TEST_FILE("bindingLoop.txt")); + QTest::ignoreMessage(QtWarningMsg, "QML MyQmlObject (unknown location): Binding loop detected for property \"stringProperty\" "); + QObject *object = component.create(); + QVERIFY(object != 0); +} + +void tst_qmlbindengine::basicExpressions_data() +{ + QTest::addColumn<QString>("expression"); + QTest::addColumn<QVariant>("result"); + QTest::addColumn<bool>("nest"); + + QTest::newRow("Context property") << "a" << QVariant(1944) << false; + QTest::newRow("Context property") << "a" << QVariant(1944) << true; + QTest::newRow("Context property expression") << "a * 2" << QVariant(3888) << false; + QTest::newRow("Context property expression") << "a * 2" << QVariant(3888) << true; + QTest::newRow("Overridden context property") << "b" << QVariant("Milk") << false; + QTest::newRow("Overridden context property") << "b" << QVariant("Cow") << true; + QTest::newRow("Object property") << "object.stringProperty" << QVariant("Object1") << false; + QTest::newRow("Object property") << "object.stringProperty" << QVariant("Object1") << true; + QTest::newRow("Overridden object property") << "objectOverride.stringProperty" << QVariant("Object2") << false; + QTest::newRow("Overridden object property") << "objectOverride.stringProperty" << QVariant("Object3") << true; + QTest::newRow("Default object property") << "horseLegs" << QVariant(4) << false; + QTest::newRow("Default object property") << "antLegs" << QVariant(6) << false; + QTest::newRow("Default object property") << "emuLegs" << QVariant(2) << false; + QTest::newRow("Nested default object property") << "horseLegs" << QVariant(4) << true; + QTest::newRow("Nested default object property") << "antLegs" << QVariant(7) << true; + QTest::newRow("Nested default object property") << "emuLegs" << QVariant(2) << true; + QTest::newRow("Nested default object property") << "humanLegs" << QVariant(2) << true; + QTest::newRow("Context property override default object property") << "millipedeLegs" << QVariant(100) << true; +} + +void tst_qmlbindengine::basicExpressions() +{ + QFETCH(QString, expression); + QFETCH(QVariant, result); + QFETCH(bool, nest); + + MyQmlObject object1; + MyQmlObject object2; + MyQmlObject object3; + MyDefaultObject1 default1; + MyDefaultObject2 default2; + MyDefaultObject3 default3; + object1.setStringProperty("Object1"); + object2.setStringProperty("Object2"); + object3.setStringProperty("Object3"); + + QmlContext context(engine.rootContext()); + QmlContext nestedContext(&context); + + context.addDefaultObject(&default1); + context.addDefaultObject(&default2); + context.setContextProperty("a", QVariant(1944)); + context.setContextProperty("b", QVariant("Milk")); + context.setContextProperty("object", &object1); + context.setContextProperty("objectOverride", &object2); + nestedContext.addDefaultObject(&default3); + nestedContext.setContextProperty("b", QVariant("Cow")); + nestedContext.setContextProperty("objectOverride", &object3); + nestedContext.setContextProperty("millipedeLegs", QVariant(100)); + + MyExpression expr(nest?&nestedContext:&context, expression); + QCOMPARE(expr.value(), result); +} + +Q_DECLARE_METATYPE(QList<QObject *>); +void tst_qmlbindengine::arrayExpressions() +{ + QObject obj1; + QObject obj2; + QObject obj3; + + QmlContext context(engine.rootContext()); + context.setContextProperty("a", &obj1); + context.setContextProperty("b", &obj2); + context.setContextProperty("c", &obj3); + + MyExpression expr(&context, "[a, b, c, 10]"); + QVariant result = expr.value(); + QCOMPARE(result.userType(), qMetaTypeId<QList<QObject *> >()); + QList<QObject *> list = qvariant_cast<QList<QObject *> >(result); + QCOMPARE(list.count(), 4); + QCOMPARE(list.at(0), &obj1); + QCOMPARE(list.at(1), &obj2); + QCOMPARE(list.at(2), &obj3); + QCOMPARE(list.at(3), (QObject *)0); +} + +// Tests that modifying a context property will reevaluate expressions +void tst_qmlbindengine::contextPropertiesTriggerReeval() +{ + QmlContext context(engine.rootContext()); + MyQmlObject object1; + MyQmlObject object2; + MyQmlObject *object3 = new MyQmlObject; + + object1.setStringProperty("Hello"); + object2.setStringProperty("World"); + + context.setContextProperty("testProp", QVariant(1)); + context.setContextProperty("testObj", &object1); + context.setContextProperty("testObj2", object3); + + { + MyExpression expr(&context, "testProp + 1"); + QCOMPARE(expr.changed, false); + QCOMPARE(expr.value(), QVariant(2)); + + context.setContextProperty("testProp", QVariant(2)); + QCOMPARE(expr.changed, true); + QCOMPARE(expr.value(), QVariant(3)); + } + + { + MyExpression expr(&context, "testProp + testProp + testProp"); + QCOMPARE(expr.changed, false); + QCOMPARE(expr.value(), QVariant(6)); + + context.setContextProperty("testProp", QVariant(4)); + QCOMPARE(expr.changed, true); + QCOMPARE(expr.value(), QVariant(12)); + } + + { + MyExpression expr(&context, "testObj.stringProperty"); + QCOMPARE(expr.changed, false); + QCOMPARE(expr.value(), QVariant("Hello")); + + context.setContextProperty("testObj", &object2); + QCOMPARE(expr.changed, true); + QCOMPARE(expr.value(), QVariant("World")); + } + + { + MyExpression expr(&context, "testObj.stringProperty /**/"); + QCOMPARE(expr.changed, false); + QCOMPARE(expr.value(), QVariant("World")); + + context.setContextProperty("testObj", &object1); + QCOMPARE(expr.changed, true); + QCOMPARE(expr.value(), QVariant("Hello")); + } + + { + MyExpression expr(&context, "testObj2"); + QCOMPARE(expr.changed, false); + QCOMPARE(expr.value(), QVariant::fromValue((QObject *)object3)); + + delete object3; + + QCOMPARE(expr.changed, true); + QCOMPARE(expr.value(), QVariant()); + } + +} + +void tst_qmlbindengine::objectPropertiesTriggerReeval() +{ + QmlContext context(engine.rootContext()); + MyQmlObject object1; + MyQmlObject object2; + MyQmlObject object3; + context.setContextProperty("testObj", &object1); + + object1.setStringProperty(QLatin1String("Hello")); + object2.setStringProperty(QLatin1String("Dog")); + object3.setStringProperty(QLatin1String("Cat")); + + { + MyExpression expr(&context, "testObj.stringProperty"); + QCOMPARE(expr.changed, false); + QCOMPARE(expr.value(), QVariant("Hello")); + + object1.setStringProperty(QLatin1String("World")); + QCOMPARE(expr.changed, true); + QCOMPARE(expr.value(), QVariant("World")); + } + + { + MyExpression expr(&context, "testObj.objectProperty.stringProperty"); + QCOMPARE(expr.changed, false); + QCOMPARE(expr.value(), QVariant()); + + object1.setObjectProperty(&object2); + QCOMPARE(expr.changed, true); + expr.changed = false; + QCOMPARE(expr.value(), QVariant("Dog")); + + object1.setObjectProperty(&object3); + QCOMPARE(expr.changed, true); + expr.changed = false; + QCOMPARE(expr.value(), QVariant("Cat")); + + object1.setObjectProperty(0); + QCOMPARE(expr.changed, true); + expr.changed = false; + QCOMPARE(expr.value(), QVariant()); + + object1.setObjectProperty(&object3); + QCOMPARE(expr.changed, true); + expr.changed = false; + QCOMPARE(expr.value(), QVariant("Cat")); + + object3.setStringProperty("Donkey"); + QCOMPARE(expr.changed, true); + expr.changed = false; + QCOMPARE(expr.value(), QVariant("Donkey")); + } +} + +QTEST_MAIN(tst_qmlbindengine) + +#include "tst_qmlbindengine.moc" diff --git a/tests/auto/declarative/qmldom/qmldom.pro b/tests/auto/declarative/qmldom/qmldom.pro new file mode 100644 index 0000000..d566354 --- /dev/null +++ b/tests/auto/declarative/qmldom/qmldom.pro @@ -0,0 +1,5 @@ +load(qttest_p4) +contains(QT_CONFIG,declarative): QT += declarative +SOURCES += tst_qmldom.cpp + +DEFINES += SRCDIR=\\\"$$PWD\\\" diff --git a/tests/auto/declarative/qmldom/tst_qmldom.cpp b/tests/auto/declarative/qmldom/tst_qmldom.cpp new file mode 100644 index 0000000..ca8929d --- /dev/null +++ b/tests/auto/declarative/qmldom/tst_qmldom.cpp @@ -0,0 +1,146 @@ +#include <qtest.h> +#include <QtDeclarative/qmlengine.h> +#include <QtDeclarative/qmlcomponent.h> +#include <QtDeclarative/qmldom.h> + +#include <QtCore/QDebug> +#include <QtCore/QFile> + +class tst_qmldom : public QObject +{ + Q_OBJECT +public: + tst_qmldom() {} + +private slots: + void loadSimple(); + void loadProperties(); + void loadChildObject(); + void loadComposite(); + + void testValueSource(); + +private: + QmlEngine engine; +}; + + +void tst_qmldom::loadSimple() +{ + QByteArray qml = "Item {}"; + //QByteArray qml = "<Item/>"; + + QmlDomDocument document; + QVERIFY(document.load(&engine, qml)); + QVERIFY(document.errors().isEmpty()); + + QmlDomObject rootObject = document.rootObject(); + QVERIFY(rootObject.isValid()); + QVERIFY(!rootObject.isComponent()); + QVERIFY(!rootObject.isCustomType()); + QVERIFY(rootObject.objectType() == "Item"); +} + +void tst_qmldom::loadProperties() +{ + QByteArray qml = "Item { id : item; x : 300; visible : true }"; + //QByteArray qml = "<Item id='item' x='300' visible='true'/>"; + + QmlDomDocument document; + QVERIFY(document.load(&engine, qml)); + + QmlDomObject rootObject = document.rootObject(); + QVERIFY(rootObject.isValid()); + QVERIFY(rootObject.objectId() == "item"); + QVERIFY(rootObject.properties().size() == 2); + + QmlDomProperty xProperty = rootObject.property("x"); + QVERIFY(xProperty.propertyName() == "x"); + QVERIFY(xProperty.value().isLiteral()); + QVERIFY(xProperty.value().toLiteral().literal() == "300"); + + QmlDomProperty visibleProperty = rootObject.property("visible"); + QVERIFY(visibleProperty.propertyName() == "visible"); + QVERIFY(visibleProperty.value().isLiteral()); + QVERIFY(visibleProperty.value().toLiteral().literal() == "true"); +} + +void tst_qmldom::loadChildObject() +{ + QByteArray qml = "Item { Item {} }"; + //QByteArray qml = "<Item> <Item/> </Item>"; + + QmlDomDocument document; + QVERIFY(document.load(&engine, qml)); + + QmlDomObject rootItem = document.rootObject(); + QVERIFY(rootItem.isValid()); + QVERIFY(rootItem.properties().size() == 1); + + QmlDomProperty listProperty = rootItem.properties().at(0); + QVERIFY(listProperty.isDefaultProperty()); + QVERIFY(listProperty.value().isList()); + + QmlDomList list = listProperty.value().toList(); + QVERIFY(list.values().size() == 1); + + QmlDomObject childItem = list.values().first().toObject(); + QVERIFY(childItem.isValid()); + QVERIFY(childItem.objectType() == "Item"); +} + +void tst_qmldom::loadComposite() +{ + QFile file(SRCDIR "/top.qml"); + QVERIFY(file.open(QIODevice::ReadOnly | QIODevice::Text)); + + QmlDomDocument document; + QVERIFY(document.load(&engine, file.readAll(), QUrl::fromLocalFile(file.fileName()))); + QVERIFY(document.errors().isEmpty()); + + QmlDomObject rootItem = document.rootObject(); + QVERIFY(rootItem.isValid()); + QCOMPARE(rootItem.objectType(), QByteArray("MyComponent")); + QCOMPARE(rootItem.properties().size(), 2); + + QmlDomProperty widthProperty = rootItem.property("width"); + QVERIFY(widthProperty.value().isLiteral()); + + QmlDomProperty heightProperty = rootItem.property("height"); + QVERIFY(heightProperty.value().isLiteral()); +} + +void tst_qmldom::testValueSource() +{ + QByteArray qml = "Rect { height: Follow { spring: 1.4; damping: .15; source: Math.min(Math.max(-130, value*2.2 - 130), 133); }}"; + + QmlEngine freshEngine; + QmlDomDocument document; + QVERIFY(document.load(&freshEngine, qml)); + + QmlDomObject rootItem = document.rootObject(); + QVERIFY(rootItem.isValid()); + QmlDomProperty heightProperty = rootItem.properties().at(0); + QVERIFY(heightProperty.propertyName() == "height"); + QVERIFY(heightProperty.value().isValueSource()); + + const QmlDomValueValueSource valueSource = heightProperty.value().toValueSource(); + QmlDomObject valueSourceObject = valueSource.object(); + QVERIFY(valueSourceObject.isValid()); + + QVERIFY(valueSourceObject.objectType() == "Follow"); + + const QmlDomValue springValue = valueSourceObject.property("spring").value(); + QVERIFY(!springValue.isInvalid()); + QVERIFY(springValue.isLiteral()); + QVERIFY(springValue.toLiteral().literal() == "1.4"); + + const QmlDomValue sourceValue = valueSourceObject.property("source").value(); + QVERIFY(!sourceValue.isInvalid()); + QVERIFY(sourceValue.isBinding()); + QVERIFY(sourceValue.toBinding().binding() == "Math.min(Math.max(-130, value*2.2 - 130), 133)"); +} + +QTEST_MAIN(tst_qmldom) + +#include "tst_qmldom.moc" diff --git a/tests/auto/declarative/qmlengine/qmlengine.pro b/tests/auto/declarative/qmlengine/qmlengine.pro new file mode 100644 index 0000000..4ac81e9 --- /dev/null +++ b/tests/auto/declarative/qmlengine/qmlengine.pro @@ -0,0 +1,5 @@ +load(qttest_p4) +contains(QT_CONFIG,declarative): QT += declarative +SOURCES += tst_qmlengine.cpp + +DEFINES += SRCDIR=\\\"$$PWD\\\" diff --git a/tests/auto/declarative/qmlengine/tst_qmlengine.cpp b/tests/auto/declarative/qmlengine/tst_qmlengine.cpp new file mode 100644 index 0000000..9a04c61 --- /dev/null +++ b/tests/auto/declarative/qmlengine/tst_qmlengine.cpp @@ -0,0 +1,43 @@ +#include <qtest.h> +#include <QtDeclarative/QmlEngine> + +#include <QtCore/QDebug> +#include <QtCore/QFile> +#include <QtCore/QUrl> + +class tst_qmlengine : public QObject +{ + Q_OBJECT +public: + tst_qmlengine() {} + +private slots: + void componentSearchPath(); +}; + + +void tst_qmlengine::componentSearchPath() +{ + QFile file(SRCDIR "/imports.qml"); + QVERIFY(file.open(QIODevice::ReadOnly)); + + QmlEngine engine; + + QList<QUrl> searchPath = engine.componentSearchPath(file.readAll(), + QUrl::fromLocalFile(file.fileName())); + + QList<QUrl> expected; + expected << QUrl::fromLocalFile(SRCDIR); + expected << QUrl::fromLocalFile(file.fileName()).resolved(QUrl("import1")); + expected << QUrl::fromLocalFile(file.fileName()).resolved(QUrl("import2")); + + QCOMPARE(searchPath.size(), expected.size()); + for (int i = 0; i < expected.size(); ++i) { + QCOMPARE(searchPath.at(i).toString(QUrl::StripTrailingSlash), + expected.at(i).toString(QUrl::StripTrailingSlash)); + } +} + +QTEST_MAIN(tst_qmlengine) + +#include "tst_qmlengine.moc" diff --git a/tests/auto/declarative/qmllist/qmllist.pro b/tests/auto/declarative/qmllist/qmllist.pro new file mode 100644 index 0000000..e5558f1 --- /dev/null +++ b/tests/auto/declarative/qmllist/qmllist.pro @@ -0,0 +1,3 @@ +load(qttest_p4) +contains(QT_CONFIG,declarative): QT += declarative +SOURCES += tst_qmllist.cpp diff --git a/tests/auto/declarative/qmllist/tst_qmllist.cpp b/tests/auto/declarative/qmllist/tst_qmllist.cpp new file mode 100644 index 0000000..541ca64 --- /dev/null +++ b/tests/auto/declarative/qmllist/tst_qmllist.cpp @@ -0,0 +1,38 @@ +#include <qtest.h> +#include <QtDeclarative/qml.h> +#include <QtDeclarative/qmlprivate.h> + +class tst_QmlList : public QObject +{ + Q_OBJECT +public: + tst_QmlList() {} + +private slots: + void interface(); +}; + +void tst_QmlList::interface() +{ + QmlConcreteList<QObject*> list; + QObject *obj = new QObject; + obj->setObjectName("foo"); + list.append(obj); + QVERIFY(list.count() == 1); + QCOMPARE(list.at(0), obj); + + QmlPrivate::ListInterface *li = (QmlPrivate::ListInterface*)&list; + + void *ptr[1]; + li->at(0, ptr); + QVERIFY(li->count() == 1); + QCOMPARE(ptr[0], obj); + + li->removeAt(0); + QVERIFY(li->count() == 0); + QVERIFY(list.count() == 0); +} + +QTEST_MAIN(tst_QmlList) + +#include "tst_qmllist.moc" diff --git a/tests/auto/declarative/qmllistaccessor/qmllistaccessor.pro b/tests/auto/declarative/qmllistaccessor/qmllistaccessor.pro new file mode 100644 index 0000000..4aa0450 --- /dev/null +++ b/tests/auto/declarative/qmllistaccessor/qmllistaccessor.pro @@ -0,0 +1,3 @@ +load(qttest_p4) +contains(QT_CONFIG,declarative): QT += declarative +SOURCES += tst_qmllistaccessor.cpp diff --git a/tests/auto/declarative/qmllistaccessor/tst_qmllistaccessor.cpp b/tests/auto/declarative/qmllistaccessor/tst_qmllistaccessor.cpp new file mode 100644 index 0000000..f5b57ea --- /dev/null +++ b/tests/auto/declarative/qmllistaccessor/tst_qmllistaccessor.cpp @@ -0,0 +1,61 @@ +#include <qtest.h> +#include <QtDeclarative/qml.h> +#include <QtDeclarative/qmllistaccessor.h> + +class tst_QmlListAccessor : public QObject +{ + Q_OBJECT +public: + tst_QmlListAccessor() {} + +private slots: + void qmllist(); + //void qlist(); + //void qstringlist(); +}; + +void tst_QmlListAccessor::qmllist() +{ + QmlConcreteList<QObject*> list; + QObject *obj = new QObject; + list.append(obj); + QVERIFY(list.count() == 1); + QCOMPARE(list.at(0), obj); + + QmlListAccessor accessor; + accessor.setList(qVariantFromValue((QmlList<QObject*>*)&list)); + + QVERIFY(accessor.isValid()); + QVERIFY(accessor.count() == 1); + + QVariant v = accessor.at(0); + QCOMPARE(qvariant_cast<QObject*>(v), obj); + + accessor.removeAt(3); + QVERIFY(accessor.count() == 1); + + accessor.removeAt(0); + QVERIFY(accessor.count() == 0); + + accessor.insert(4, qVariantFromValue(obj)); + QVERIFY(accessor.count() == 1); + + v = accessor.at(0); + QCOMPARE(qvariant_cast<QObject*>(v), obj); + + QObject *obj2 = new QObject; + accessor.append(qVariantFromValue(obj2)); + QVERIFY(accessor.count() == 2); + + v = accessor.at(1); + QCOMPARE(qvariant_cast<QObject*>(v), obj2); + + accessor.clear(); + QVERIFY(accessor.count() == 0); + + QVERIFY(accessor.isValid()); +} + +QTEST_MAIN(tst_QmlListAccessor) + +#include "tst_qmllistaccessor.moc" diff --git a/tests/auto/declarative/qmlmetaproperty/qmlmetaproperty.pro b/tests/auto/declarative/qmlmetaproperty/qmlmetaproperty.pro new file mode 100644 index 0000000..af67373 --- /dev/null +++ b/tests/auto/declarative/qmlmetaproperty/qmlmetaproperty.pro @@ -0,0 +1,3 @@ +load(qttest_p4) +contains(QT_CONFIG,declarative): QT += declarative +SOURCES += tst_qmlmetaproperty.cpp diff --git a/tests/auto/declarative/qmlmetaproperty/tst_qmlmetaproperty.cpp b/tests/auto/declarative/qmlmetaproperty/tst_qmlmetaproperty.cpp new file mode 100644 index 0000000..e35a006 --- /dev/null +++ b/tests/auto/declarative/qmlmetaproperty/tst_qmlmetaproperty.cpp @@ -0,0 +1,104 @@ +#include <qtest.h> +#include <QtDeclarative/qmlengine.h> +#include <QtDeclarative/qmlcomponent.h> +#include <QtDeclarative/qmlmetaproperty.h> +#include <QtGui/QLineEdit> + +class MyQmlObject : public QObject +{ + Q_OBJECT +public: + MyQmlObject() {} +}; + +QML_DECLARE_TYPE(MyQmlObject); +QML_DEFINE_TYPE(MyQmlObject,MyQmlObject); + +class MyContainer : public QObject +{ + Q_OBJECT + Q_PROPERTY(QList<MyQmlObject*>* children READ children) + Q_PROPERTY(QmlList<MyQmlObject*>* qmlChildren READ qmlChildren) +public: + MyContainer() {} + + QList<MyQmlObject*> *children() { return &m_children; } + QmlConcreteList<MyQmlObject *> *qmlChildren() { return &m_qmlChildren; } + +private: + QList<MyQmlObject*> m_children; + QmlConcreteList<MyQmlObject *> m_qmlChildren; +}; + +QML_DECLARE_TYPE(MyContainer); +QML_DEFINE_TYPE(MyContainer,MyContainer); + +class tst_QmlMetaProperty : public QObject +{ + Q_OBJECT +public: + tst_QmlMetaProperty() {} + +private slots: + void writeObjectToList(); + void writeListToList(); + void writeObjectToQmlList(); + + //writeToReadOnly(); + +private: + QmlEngine engine; +}; + +void tst_QmlMetaProperty::writeObjectToList() +{ + QmlComponent containerComponent(&engine, "MyContainer { children: MyQmlObject {} }"); + MyContainer *container = qobject_cast<MyContainer*>(containerComponent.create()); + QVERIFY(container != 0); + QVERIFY(container->children()->size() == 1); + + MyQmlObject *object = new MyQmlObject; + QmlMetaProperty prop(container, "children"); + prop.write(qVariantFromValue(object)); + QCOMPARE(container->children()->size(), 2); + QCOMPARE(container->children()->at(1), object); +} + +Q_DECLARE_METATYPE(QList<QObject *>); +void tst_QmlMetaProperty::writeListToList() +{ + QmlComponent containerComponent(&engine, "MyContainer { children: MyQmlObject {} }"); + MyContainer *container = qobject_cast<MyContainer*>(containerComponent.create()); + QVERIFY(container != 0); + QVERIFY(container->children()->size() == 1); + + QList<QObject*> objList; + objList << new MyQmlObject() << new MyQmlObject() << new MyQmlObject() << new MyQmlObject(); + QmlMetaProperty prop(container, "children"); + prop.write(qVariantFromValue(objList)); + QCOMPARE(container->children()->size(), 4); + + //XXX need to try this with read/write prop (for read-only it correctly doesn't write) + /*QList<MyQmlObject*> typedObjList; + typedObjList << new MyQmlObject(); + prop.write(qVariantFromValue(&typedObjList)); + QCOMPARE(container->children()->size(), 1);*/ +} + +void tst_QmlMetaProperty::writeObjectToQmlList() +{ + QmlComponent containerComponent(&engine, "MyContainer { qmlChildren: MyQmlObject {} }"); + MyContainer *container = qobject_cast<MyContainer*>(containerComponent.create()); + QVERIFY(container != 0); + QVERIFY(container->qmlChildren()->size() == 1); + + MyQmlObject *object = new MyQmlObject; + QmlMetaProperty prop(container, "qmlChildren"); + prop.write(qVariantFromValue(object)); + QCOMPARE(container->qmlChildren()->size(), 2); + QCOMPARE(container->qmlChildren()->at(1), object); +} + +QTEST_MAIN(tst_QmlMetaProperty) + +#include "tst_qmlmetaproperty.moc" diff --git a/tests/auto/declarative/qmlparser/FailingComponent.qml b/tests/auto/declarative/qmlparser/FailingComponent.qml new file mode 100644 index 0000000..b604e0b --- /dev/null +++ b/tests/auto/declarative/qmlparser/FailingComponent.qml @@ -0,0 +1,3 @@ +Object { + a: 10 +} diff --git a/tests/auto/declarative/qmlparser/MyComponent.qml b/tests/auto/declarative/qmlparser/MyComponent.qml new file mode 100644 index 0000000..8a9f57d --- /dev/null +++ b/tests/auto/declarative/qmlparser/MyComponent.qml @@ -0,0 +1,4 @@ +MyQmlObject { + property real x; + property real y; +} diff --git a/tests/auto/declarative/qmlparser/MyContainerComponent.qml b/tests/auto/declarative/qmlparser/MyContainerComponent.qml new file mode 100644 index 0000000..5746928 --- /dev/null +++ b/tests/auto/declarative/qmlparser/MyContainerComponent.qml @@ -0,0 +1,3 @@ +MyContainer { + property int x +} diff --git a/tests/auto/declarative/qmlparser/assignBasicTypes.txt b/tests/auto/declarative/qmlparser/assignBasicTypes.txt new file mode 100644 index 0000000..71e400d --- /dev/null +++ b/tests/auto/declarative/qmlparser/assignBasicTypes.txt @@ -0,0 +1,25 @@ +MyTypeObject { + flagProperty: "FlagVal1 | FlagVal3" + enumProperty: "EnumVal2" + stringProperty: "Hello World!" + uintProperty: 10 + intProperty: -19 + realProperty: 23.2 + doubleProperty: -19.7 + colorProperty: "red" + dateProperty: "1982-11-25" + timeProperty: "11:11:31" + timeProperty: "11:11:32" + timeProperty: "11:11:32" + dateTimeProperty: "2009-05-12T13:22:01" + pointProperty: "99,13" + pointFProperty: "-10.1,12.3" + sizeProperty: "99x13" + sizeFProperty: "0.1x0.2" + rectProperty: "9,7,100x200" + rectFProperty: "1000.1,-10.9,400x90.99" + boolProperty: true + variantProperty: "Hello World!" + + objectProperty: MyTypeObject { intProperty: 8 } +} diff --git a/tests/auto/declarative/qmlparser/assignLiteralSignalProperty.txt b/tests/auto/declarative/qmlparser/assignLiteralSignalProperty.txt new file mode 100644 index 0000000..f3a7ac7 --- /dev/null +++ b/tests/auto/declarative/qmlparser/assignLiteralSignalProperty.txt @@ -0,0 +1,3 @@ +MyQmlObject { + onLiteralSignal: 10 +} diff --git a/tests/auto/declarative/qmlparser/assignObjectToSignal.txt b/tests/auto/declarative/qmlparser/assignObjectToSignal.txt new file mode 100644 index 0000000..0d6bc4e --- /dev/null +++ b/tests/auto/declarative/qmlparser/assignObjectToSignal.txt @@ -0,0 +1,3 @@ +MyQmlObject { + onBasicSignal: MyQmlObject {} +} diff --git a/tests/auto/declarative/qmlparser/assignObjectToVariant.txt b/tests/auto/declarative/qmlparser/assignObjectToVariant.txt new file mode 100644 index 0000000..180221d --- /dev/null +++ b/tests/auto/declarative/qmlparser/assignObjectToVariant.txt @@ -0,0 +1,4 @@ +Object { + property var a; + a: MyQmlObject {} +} diff --git a/tests/auto/declarative/qmlparser/assignQmlComponent.txt b/tests/auto/declarative/qmlparser/assignQmlComponent.txt new file mode 100644 index 0000000..6b6d77f --- /dev/null +++ b/tests/auto/declarative/qmlparser/assignQmlComponent.txt @@ -0,0 +1,3 @@ +MyContainer { + MyComponent { x: 10; y: 11; } +} diff --git a/tests/auto/declarative/qmlparser/assignSignal.txt b/tests/auto/declarative/qmlparser/assignSignal.txt new file mode 100644 index 0000000..6c0fd54 --- /dev/null +++ b/tests/auto/declarative/qmlparser/assignSignal.txt @@ -0,0 +1,3 @@ +MyQmlObject { + onBasicSignal: basicSlot() +} diff --git a/tests/auto/declarative/qmlparser/assignTypeExtremes.txt b/tests/auto/declarative/qmlparser/assignTypeExtremes.txt new file mode 100644 index 0000000..dbd281a --- /dev/null +++ b/tests/auto/declarative/qmlparser/assignTypeExtremes.txt @@ -0,0 +1,4 @@ +MyTypeObject { + uintProperty: 4000000000 + intProperty: -2000000000 +} diff --git a/tests/auto/declarative/qmlparser/attachedProperties.txt b/tests/auto/declarative/qmlparser/attachedProperties.txt new file mode 100644 index 0000000..bfe5733 --- /dev/null +++ b/tests/auto/declarative/qmlparser/attachedProperties.txt @@ -0,0 +1,3 @@ +Object { + MyQmlObject.value: 10 +} diff --git a/tests/auto/declarative/qmlparser/autoComponentCreation.txt b/tests/auto/declarative/qmlparser/autoComponentCreation.txt new file mode 100644 index 0000000..e0dbbae --- /dev/null +++ b/tests/auto/declarative/qmlparser/autoComponentCreation.txt @@ -0,0 +1,3 @@ +MyTypeObject { + componentProperty : MyTypeObject { realProperty: 9 } +} diff --git a/tests/auto/declarative/qmlparser/customParserTypes.txt b/tests/auto/declarative/qmlparser/customParserTypes.txt new file mode 100644 index 0000000..52848fa --- /dev/null +++ b/tests/auto/declarative/qmlparser/customParserTypes.txt @@ -0,0 +1,4 @@ +ListModel { + ListElement { a: 10 } + ListElement { a: 12 } +} diff --git a/tests/auto/declarative/qmlparser/customVariantTypes.txt b/tests/auto/declarative/qmlparser/customVariantTypes.txt new file mode 100644 index 0000000..dc5031e --- /dev/null +++ b/tests/auto/declarative/qmlparser/customVariantTypes.txt @@ -0,0 +1,3 @@ +MyQmlObject { + customType: "10" +} diff --git a/tests/auto/declarative/qmlparser/duplicateIDs.errors.txt b/tests/auto/declarative/qmlparser/duplicateIDs.errors.txt new file mode 100644 index 0000000..b03f735 --- /dev/null +++ b/tests/auto/declarative/qmlparser/duplicateIDs.errors.txt @@ -0,0 +1 @@ +3:5:id is not unique diff --git a/tests/auto/declarative/qmlparser/duplicateIDs.txt b/tests/auto/declarative/qmlparser/duplicateIDs.txt new file mode 100644 index 0000000..e76ee21 --- /dev/null +++ b/tests/auto/declarative/qmlparser/duplicateIDs.txt @@ -0,0 +1,5 @@ +MyContainer { + MyQmlObject { id: MyID } + MyQmlObject { id: MyID } +} + diff --git a/tests/auto/declarative/qmlparser/dynamicObject.1.txt b/tests/auto/declarative/qmlparser/dynamicObject.1.txt new file mode 100644 index 0000000..ac892c3 --- /dev/null +++ b/tests/auto/declarative/qmlparser/dynamicObject.1.txt @@ -0,0 +1,6 @@ +SetProperties { + propa: a + 10 + propb: Math.min(a, 10) + propc: MyPropertyValueSource {} + onPropA: a +} diff --git a/tests/auto/declarative/qmlparser/dynamicProperties.txt b/tests/auto/declarative/qmlparser/dynamicProperties.txt new file mode 100644 index 0000000..14c85a7 --- /dev/null +++ b/tests/auto/declarative/qmlparser/dynamicProperties.txt @@ -0,0 +1,11 @@ +Object { + default property int intProperty : 10 + property bool boolProperty: false + property double doubleProperty: -10.1 + property real realProperty: -19.9 + property string stringProperty: "Hello World!" + property color colorProperty: "red" + property date dateProperty: "1945-09-02" + property var varProperty: "Hello World!" + property variant variantProperty: 12 +} diff --git a/tests/auto/declarative/qmlparser/dynamicSignalsAndSlots.txt b/tests/auto/declarative/qmlparser/dynamicSignalsAndSlots.txt new file mode 100644 index 0000000..7cf65ee --- /dev/null +++ b/tests/auto/declarative/qmlparser/dynamicSignalsAndSlots.txt @@ -0,0 +1,6 @@ +Object { + signal signal1 + function slot1() {} + signal signal2 + function slot2() {} +} diff --git a/tests/auto/declarative/qmlparser/empty.errors.txt b/tests/auto/declarative/qmlparser/empty.errors.txt new file mode 100644 index 0000000..e0ed268 --- /dev/null +++ b/tests/auto/declarative/qmlparser/empty.errors.txt @@ -0,0 +1 @@ +0:0:Expected token `identifier' diff --git a/tests/auto/declarative/qmlparser/empty.txt b/tests/auto/declarative/qmlparser/empty.txt new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/auto/declarative/qmlparser/empty.txt diff --git a/tests/auto/declarative/qmlparser/failingComponent.errors.txt b/tests/auto/declarative/qmlparser/failingComponent.errors.txt new file mode 100644 index 0000000..12fb4e7 --- /dev/null +++ b/tests/auto/declarative/qmlparser/failingComponent.errors.txt @@ -0,0 +1,2 @@ +-1:-1:Unable to create type FailingComponent +2:5:Cannot assign value to non-existant property "a" diff --git a/tests/auto/declarative/qmlparser/failingComponent.txt b/tests/auto/declarative/qmlparser/failingComponent.txt new file mode 100644 index 0000000..8c43f84 --- /dev/null +++ b/tests/auto/declarative/qmlparser/failingComponent.txt @@ -0,0 +1,4 @@ +MyContainer { + FailingComponent {} +} + diff --git a/tests/auto/declarative/qmlparser/fakeDotProperty.errors.txt b/tests/auto/declarative/qmlparser/fakeDotProperty.errors.txt new file mode 100644 index 0000000..a94b38e --- /dev/null +++ b/tests/auto/declarative/qmlparser/fakeDotProperty.errors.txt @@ -0,0 +1 @@ +2:11:Cannot assign value to non-existant property "something" diff --git a/tests/auto/declarative/qmlparser/fakeDotProperty.txt b/tests/auto/declarative/qmlparser/fakeDotProperty.txt new file mode 100644 index 0000000..28eb9dc --- /dev/null +++ b/tests/auto/declarative/qmlparser/fakeDotProperty.txt @@ -0,0 +1,3 @@ +MyQmlObject { + value.something: "hello" +} diff --git a/tests/auto/declarative/qmlparser/idProperty.txt b/tests/auto/declarative/qmlparser/idProperty.txt new file mode 100644 index 0000000..9c7d6fb --- /dev/null +++ b/tests/auto/declarative/qmlparser/idProperty.txt @@ -0,0 +1,7 @@ +MyContainer { + property var object : MyObjectId + + MyTypeObject { + id: MyObjectId + } +} diff --git a/tests/auto/declarative/qmlparser/inlineQmlComponents.txt b/tests/auto/declarative/qmlparser/inlineQmlComponents.txt new file mode 100644 index 0000000..e713a88 --- /dev/null +++ b/tests/auto/declarative/qmlparser/inlineQmlComponents.txt @@ -0,0 +1,8 @@ +MyContainer { + Component { + id: MyComponent + MyQmlObject { + value: 11 + } + } +} diff --git a/tests/auto/declarative/qmlparser/interfaceProperty.txt b/tests/auto/declarative/qmlparser/interfaceProperty.txt new file mode 100644 index 0000000..cbad7f1 --- /dev/null +++ b/tests/auto/declarative/qmlparser/interfaceProperty.txt @@ -0,0 +1,3 @@ +MyQmlObject { + interface: MyQmlObject {} +} diff --git a/tests/auto/declarative/qmlparser/interfaceQList.txt b/tests/auto/declarative/qmlparser/interfaceQList.txt new file mode 100644 index 0000000..6c6ab4b --- /dev/null +++ b/tests/auto/declarative/qmlparser/interfaceQList.txt @@ -0,0 +1,6 @@ +MyContainer { + qlistInterfaces: [ + MyQmlObject {}, + MyQmlObject {} + ] +} diff --git a/tests/auto/declarative/qmlparser/interfaceQmlList.txt b/tests/auto/declarative/qmlparser/interfaceQmlList.txt new file mode 100644 index 0000000..f41c105 --- /dev/null +++ b/tests/auto/declarative/qmlparser/interfaceQmlList.txt @@ -0,0 +1,6 @@ +MyContainer { + qmllistInterfaces: [ + MyQmlObject {}, + MyQmlObject {} + ] +} diff --git a/tests/auto/declarative/qmlparser/invalidID.2.errors.txt b/tests/auto/declarative/qmlparser/invalidID.2.errors.txt new file mode 100644 index 0000000..6380750 --- /dev/null +++ b/tests/auto/declarative/qmlparser/invalidID.2.errors.txt @@ -0,0 +1,2 @@ +1:1:"" is not a valid id + diff --git a/tests/auto/declarative/qmlparser/invalidID.2.txt b/tests/auto/declarative/qmlparser/invalidID.2.txt new file mode 100644 index 0000000..a7af29e --- /dev/null +++ b/tests/auto/declarative/qmlparser/invalidID.2.txt @@ -0,0 +1,4 @@ +MyQmlObject { + id: "" +} + diff --git a/tests/auto/declarative/qmlparser/invalidID.3.errors.txt b/tests/auto/declarative/qmlparser/invalidID.3.errors.txt new file mode 100644 index 0000000..05937f0 --- /dev/null +++ b/tests/auto/declarative/qmlparser/invalidID.3.errors.txt @@ -0,0 +1 @@ +2:5:The id property cannot be fetched diff --git a/tests/auto/declarative/qmlparser/invalidID.3.txt b/tests/auto/declarative/qmlparser/invalidID.3.txt new file mode 100644 index 0000000..c686914 --- /dev/null +++ b/tests/auto/declarative/qmlparser/invalidID.3.txt @@ -0,0 +1,4 @@ +MyQmlObject { + id.other: 10 +} + diff --git a/tests/auto/declarative/qmlparser/invalidID.4.errors.txt b/tests/auto/declarative/qmlparser/invalidID.4.errors.txt new file mode 100644 index 0000000..50c8960 --- /dev/null +++ b/tests/auto/declarative/qmlparser/invalidID.4.errors.txt @@ -0,0 +1 @@ +3:5:The object id may only be set once diff --git a/tests/auto/declarative/qmlparser/invalidID.4.txt b/tests/auto/declarative/qmlparser/invalidID.4.txt new file mode 100644 index 0000000..734ccc4 --- /dev/null +++ b/tests/auto/declarative/qmlparser/invalidID.4.txt @@ -0,0 +1,5 @@ +MyQmlObject { + id: Hello + id: World +} + diff --git a/tests/auto/declarative/qmlparser/invalidID.errors.txt b/tests/auto/declarative/qmlparser/invalidID.errors.txt new file mode 100644 index 0000000..eed1869 --- /dev/null +++ b/tests/auto/declarative/qmlparser/invalidID.errors.txt @@ -0,0 +1 @@ +1:1:"1" is not a valid id diff --git a/tests/auto/declarative/qmlparser/invalidID.txt b/tests/auto/declarative/qmlparser/invalidID.txt new file mode 100644 index 0000000..f91e8c4 --- /dev/null +++ b/tests/auto/declarative/qmlparser/invalidID.txt @@ -0,0 +1,3 @@ +MyQmlObject { + id: 1 +} diff --git a/tests/auto/declarative/qmlparser/listAssignment.1.errors.txt b/tests/auto/declarative/qmlparser/listAssignment.1.errors.txt new file mode 100644 index 0000000..44a275b --- /dev/null +++ b/tests/auto/declarative/qmlparser/listAssignment.1.errors.txt @@ -0,0 +1 @@ +1:1:Cannot assign primitives to lists diff --git a/tests/auto/declarative/qmlparser/listAssignment.1.txt b/tests/auto/declarative/qmlparser/listAssignment.1.txt new file mode 100644 index 0000000..e2376f2 --- /dev/null +++ b/tests/auto/declarative/qmlparser/listAssignment.1.txt @@ -0,0 +1,3 @@ +MyContainer { + qmllistInterfaces: 1 +} diff --git a/tests/auto/declarative/qmlparser/listAssignment.2.errors.txt b/tests/auto/declarative/qmlparser/listAssignment.2.errors.txt new file mode 100644 index 0000000..572d662 --- /dev/null +++ b/tests/auto/declarative/qmlparser/listAssignment.2.errors.txt @@ -0,0 +1,2 @@ +1:1:Cannot assign primitives to lists + diff --git a/tests/auto/declarative/qmlparser/listAssignment.2.txt b/tests/auto/declarative/qmlparser/listAssignment.2.txt new file mode 100644 index 0000000..375e4b4 --- /dev/null +++ b/tests/auto/declarative/qmlparser/listAssignment.2.txt @@ -0,0 +1,3 @@ +MyContainer { + children: 2 +} diff --git a/tests/auto/declarative/qmlparser/listAssignment.3.errors.txt b/tests/auto/declarative/qmlparser/listAssignment.3.errors.txt new file mode 100644 index 0000000..ab6fec8 --- /dev/null +++ b/tests/auto/declarative/qmlparser/listAssignment.3.errors.txt @@ -0,0 +1 @@ +1:1:Can only assign one binding to lists diff --git a/tests/auto/declarative/qmlparser/listAssignment.3.txt b/tests/auto/declarative/qmlparser/listAssignment.3.txt new file mode 100644 index 0000000..b776bee --- /dev/null +++ b/tests/auto/declarative/qmlparser/listAssignment.3.txt @@ -0,0 +1,5 @@ +MyContainer { + children: childBinding.expression + children: childBinding2.expression +} + diff --git a/tests/auto/declarative/qmlparser/missingObject.errors.txt b/tests/auto/declarative/qmlparser/missingObject.errors.txt new file mode 100644 index 0000000..8438b9e --- /dev/null +++ b/tests/auto/declarative/qmlparser/missingObject.errors.txt @@ -0,0 +1 @@ +1:10:Syntax error diff --git a/tests/auto/declarative/qmlparser/missingObject.txt b/tests/auto/declarative/qmlparser/missingObject.txt new file mode 100644 index 0000000..2f17045 --- /dev/null +++ b/tests/auto/declarative/qmlparser/missingObject.txt @@ -0,0 +1 @@ +something: 24 diff --git a/tests/auto/declarative/qmlparser/missingSignal.errors.txt b/tests/auto/declarative/qmlparser/missingSignal.errors.txt new file mode 100644 index 0000000..5c612cc --- /dev/null +++ b/tests/auto/declarative/qmlparser/missingSignal.errors.txt @@ -0,0 +1 @@ +2:5:Cannot assign binding to non-existant property "onClicked" diff --git a/tests/auto/declarative/qmlparser/missingSignal.txt b/tests/auto/declarative/qmlparser/missingSignal.txt new file mode 100644 index 0000000..07d1bfa --- /dev/null +++ b/tests/auto/declarative/qmlparser/missingSignal.txt @@ -0,0 +1,3 @@ +Object { + onClicked: print("Hello world!") +} diff --git a/tests/auto/declarative/qmlparser/nonexistantProperty.1.errors.txt b/tests/auto/declarative/qmlparser/nonexistantProperty.1.errors.txt new file mode 100644 index 0000000..e8f1a91 --- /dev/null +++ b/tests/auto/declarative/qmlparser/nonexistantProperty.1.errors.txt @@ -0,0 +1 @@ +1:15:Cannot assign value to non-existant property "something" diff --git a/tests/auto/declarative/qmlparser/nonexistantProperty.1.txt b/tests/auto/declarative/qmlparser/nonexistantProperty.1.txt new file mode 100644 index 0000000..5023b38 --- /dev/null +++ b/tests/auto/declarative/qmlparser/nonexistantProperty.1.txt @@ -0,0 +1 @@ +MyQmlObject { something: 24 } diff --git a/tests/auto/declarative/qmlparser/nonexistantProperty.2.errors.txt b/tests/auto/declarative/qmlparser/nonexistantProperty.2.errors.txt new file mode 100644 index 0000000..c154f91 --- /dev/null +++ b/tests/auto/declarative/qmlparser/nonexistantProperty.2.errors.txt @@ -0,0 +1 @@ +2:5:Cannot assign value to non-existant property "something" diff --git a/tests/auto/declarative/qmlparser/nonexistantProperty.2.txt b/tests/auto/declarative/qmlparser/nonexistantProperty.2.txt new file mode 100644 index 0000000..3b6cfa6 --- /dev/null +++ b/tests/auto/declarative/qmlparser/nonexistantProperty.2.txt @@ -0,0 +1,3 @@ +MyQmlObject { + something: 24 +} diff --git a/tests/auto/declarative/qmlparser/nonexistantProperty.3.errors.txt b/tests/auto/declarative/qmlparser/nonexistantProperty.3.errors.txt new file mode 100644 index 0000000..a254d7d --- /dev/null +++ b/tests/auto/declarative/qmlparser/nonexistantProperty.3.errors.txt @@ -0,0 +1 @@ +2:5:Cannot assign binding to non-existant property "something" diff --git a/tests/auto/declarative/qmlparser/nonexistantProperty.3.txt b/tests/auto/declarative/qmlparser/nonexistantProperty.3.txt new file mode 100644 index 0000000..61f3625 --- /dev/null +++ b/tests/auto/declarative/qmlparser/nonexistantProperty.3.txt @@ -0,0 +1,3 @@ +MyQmlObject { + something: 1 + 1 +} diff --git a/tests/auto/declarative/qmlparser/nonexistantProperty.4.errors.txt b/tests/auto/declarative/qmlparser/nonexistantProperty.4.errors.txt new file mode 100644 index 0000000..a254d7d --- /dev/null +++ b/tests/auto/declarative/qmlparser/nonexistantProperty.4.errors.txt @@ -0,0 +1 @@ +2:5:Cannot assign binding to non-existant property "something" diff --git a/tests/auto/declarative/qmlparser/nonexistantProperty.4.txt b/tests/auto/declarative/qmlparser/nonexistantProperty.4.txt new file mode 100644 index 0000000..5ee1d3a --- /dev/null +++ b/tests/auto/declarative/qmlparser/nonexistantProperty.4.txt @@ -0,0 +1,3 @@ +MyQmlObject { + something: ; +} diff --git a/tests/auto/declarative/qmlparser/nonexistantProperty.5.errors.txt b/tests/auto/declarative/qmlparser/nonexistantProperty.5.errors.txt new file mode 100644 index 0000000..4234fca4 --- /dev/null +++ b/tests/auto/declarative/qmlparser/nonexistantProperty.5.errors.txt @@ -0,0 +1 @@ +2:5:Unexpected token `numeric literal' diff --git a/tests/auto/declarative/qmlparser/nonexistantProperty.5.txt b/tests/auto/declarative/qmlparser/nonexistantProperty.5.txt new file mode 100644 index 0000000..1dc6985 --- /dev/null +++ b/tests/auto/declarative/qmlparser/nonexistantProperty.5.txt @@ -0,0 +1,3 @@ +MyQmlObject { + 24 +} diff --git a/tests/auto/declarative/qmlparser/nonexistantProperty.6.errors.txt b/tests/auto/declarative/qmlparser/nonexistantProperty.6.errors.txt new file mode 100644 index 0000000..3183b6d --- /dev/null +++ b/tests/auto/declarative/qmlparser/nonexistantProperty.6.errors.txt @@ -0,0 +1 @@ +2:-1:Cannot assign to default property diff --git a/tests/auto/declarative/qmlparser/nonexistantProperty.6.txt b/tests/auto/declarative/qmlparser/nonexistantProperty.6.txt new file mode 100644 index 0000000..4940833 --- /dev/null +++ b/tests/auto/declarative/qmlparser/nonexistantProperty.6.txt @@ -0,0 +1,3 @@ +MyQmlObject { + MyQmlObject {} +} diff --git a/tests/auto/declarative/qmlparser/nullDotProperty.errors.txt b/tests/auto/declarative/qmlparser/nullDotProperty.errors.txt new file mode 100644 index 0000000..8482634 --- /dev/null +++ b/tests/auto/declarative/qmlparser/nullDotProperty.errors.txt @@ -0,0 +1 @@ +2:-1:Cannot set properties on obj as it is null diff --git a/tests/auto/declarative/qmlparser/nullDotProperty.txt b/tests/auto/declarative/qmlparser/nullDotProperty.txt new file mode 100644 index 0000000..5c60c5b --- /dev/null +++ b/tests/auto/declarative/qmlparser/nullDotProperty.txt @@ -0,0 +1,3 @@ +MyDotPropertyObject { + obj.value: 1 +} diff --git a/tests/auto/declarative/qmlparser/propertyValueSource.txt b/tests/auto/declarative/qmlparser/propertyValueSource.txt new file mode 100644 index 0000000..780f527 --- /dev/null +++ b/tests/auto/declarative/qmlparser/propertyValueSource.txt @@ -0,0 +1,3 @@ +MyTypeObject { + intProperty : MyPropertyValueSource {} +} diff --git a/tests/auto/declarative/qmlparser/qmlparser.pro b/tests/auto/declarative/qmlparser/qmlparser.pro new file mode 100644 index 0000000..dda5c61 --- /dev/null +++ b/tests/auto/declarative/qmlparser/qmlparser.pro @@ -0,0 +1,9 @@ +load(qttest_p4) +contains(QT_CONFIG,declarative): QT += declarative +SOURCES += tst_qmlparser.cpp \ + testtypes.cpp +HEADERS = testtypes.h +macx:CONFIG -= app_bundle + +# QMAKE_CXXFLAGS = -fprofile-arcs -ftest-coverage +# LIBS += -lgcov diff --git a/tests/auto/declarative/qmlparser/readOnly.1.errors.txt b/tests/auto/declarative/qmlparser/readOnly.1.errors.txt new file mode 100644 index 0000000..89009ce --- /dev/null +++ b/tests/auto/declarative/qmlparser/readOnly.1.errors.txt @@ -0,0 +1 @@ +2:21:Cannot assign value "Hello World" to the read-only property readOnlyString diff --git a/tests/auto/declarative/qmlparser/readOnly.1.txt b/tests/auto/declarative/qmlparser/readOnly.1.txt new file mode 100644 index 0000000..c47fdf3 --- /dev/null +++ b/tests/auto/declarative/qmlparser/readOnly.1.txt @@ -0,0 +1,3 @@ +MyQmlObject { + readOnlyString: "Hello World" +} diff --git a/tests/auto/declarative/qmlparser/readOnly.2.errors.txt b/tests/auto/declarative/qmlparser/readOnly.2.errors.txt new file mode 100644 index 0000000..ab27946 --- /dev/null +++ b/tests/auto/declarative/qmlparser/readOnly.2.errors.txt @@ -0,0 +1 @@ +2:-1:Cannot assign a binding to read-only property "readOnlyString" diff --git a/tests/auto/declarative/qmlparser/readOnly.2.txt b/tests/auto/declarative/qmlparser/readOnly.2.txt new file mode 100644 index 0000000..2b6f733 --- /dev/null +++ b/tests/auto/declarative/qmlparser/readOnly.2.txt @@ -0,0 +1,3 @@ +MyQmlObject { + readOnlyString: "Hello" + "World" +} diff --git a/tests/auto/declarative/qmlparser/rootAsQmlComponent.txt b/tests/auto/declarative/qmlparser/rootAsQmlComponent.txt new file mode 100644 index 0000000..8cb57ff --- /dev/null +++ b/tests/auto/declarative/qmlparser/rootAsQmlComponent.txt @@ -0,0 +1,5 @@ +MyContainerComponent { + x: 11 + MyQmlObject {} + MyQmlObject {} +} diff --git a/tests/auto/declarative/qmlparser/simpleBindings.txt b/tests/auto/declarative/qmlparser/simpleBindings.txt new file mode 100644 index 0000000..78f2503 --- /dev/null +++ b/tests/auto/declarative/qmlparser/simpleBindings.txt @@ -0,0 +1,17 @@ +MyTypeObject { + id: Me + property int v1: 10 + property int v2: 11 + + property int value1 + property int value2 + property int value3 + property int value4 + + value1: v1 + value2: Me.v1 + value3: v1 + v2 + value4: Math.min(v1, v2) + + objectProperty: Me +} diff --git a/tests/auto/declarative/qmlparser/simpleContainer.txt b/tests/auto/declarative/qmlparser/simpleContainer.txt new file mode 100644 index 0000000..8b30ed9 --- /dev/null +++ b/tests/auto/declarative/qmlparser/simpleContainer.txt @@ -0,0 +1,4 @@ +MyContainer { + MyQmlObject {} + MyQmlObject {} +} diff --git a/tests/auto/declarative/qmlparser/simpleObject.txt b/tests/auto/declarative/qmlparser/simpleObject.txt new file mode 100644 index 0000000..05ed87a --- /dev/null +++ b/tests/auto/declarative/qmlparser/simpleObject.txt @@ -0,0 +1 @@ +MyQmlObject {} diff --git a/tests/auto/declarative/qmlparser/testtypes.cpp b/tests/auto/declarative/qmlparser/testtypes.cpp new file mode 100644 index 0000000..69df5c3 --- /dev/null +++ b/tests/auto/declarative/qmlparser/testtypes.cpp @@ -0,0 +1,9 @@ +#include "testtypes.h" + +QML_DEFINE_INTERFACE(MyInterface); +QML_DEFINE_TYPE(MyQmlObject,MyQmlObject); +QML_DEFINE_TYPE(MyTypeObject,MyTypeObject); +QML_DEFINE_TYPE(MyContainer,MyContainer); +QML_DEFINE_TYPE(MyPropertyValueSource,MyPropertyValueSource); +QML_DEFINE_TYPE(MyDotPropertyObject,MyDotPropertyObject); + diff --git a/tests/auto/declarative/qmlparser/testtypes.h b/tests/auto/declarative/qmlparser/testtypes.h new file mode 100644 index 0000000..e124631 --- /dev/null +++ b/tests/auto/declarative/qmlparser/testtypes.h @@ -0,0 +1,391 @@ +#ifndef TESTTYPES_H +#define TESTTYPES_H + +#include <QtCore/qobject.h> +#include <QtCore/qrect.h> +#include <QtCore/qdatetime.h> +#include <QtGui/qmatrix.h> +#include <QtGui/qcolor.h> +#include <QtDeclarative/qml.h> +#include <QtDeclarative/qmlcomponent.h> +#include <QtDeclarative/qmlparserstatus.h> +#include <QtDeclarative/qmlpropertyvaluesource.h> + +class MyInterface +{ +public: + MyInterface() : id(913) {} + int id; +}; +Q_DECLARE_INTERFACE(MyInterface, "com.trolltech.Qt.Test.MyInterface"); +QML_DECLARE_INTERFACE(MyInterface); + +struct MyCustomVariantType +{ + MyCustomVariantType() : a(0) {} + int a; +}; +Q_DECLARE_METATYPE(MyCustomVariantType); + +static QVariant myCustomVariantTypeConverter(const QString &data) +{ + MyCustomVariantType rv; + rv.a = data.toInt(); + return QVariant::fromValue(rv); +} + +class MyQmlObject : public QObject, public MyInterface, public QmlParserStatus +{ + Q_OBJECT + Q_PROPERTY(int value READ value WRITE setValue) + Q_PROPERTY(QString readOnlyString READ readOnlyString) + Q_PROPERTY(bool enabled READ enabled WRITE setEnabled) + Q_PROPERTY(QRect rect READ rect WRITE setRect) + Q_PROPERTY(QMatrix matrix READ matrix WRITE setMatrix) //assumed to be unsupported by QML + Q_PROPERTY(MyInterface *interface READ interface WRITE setInterface) + Q_PROPERTY(int onLiteralSignal READ onLiteralSignal WRITE setOnLiteralSignal); + Q_PROPERTY(MyCustomVariantType customType READ customType WRITE setCustomType); + Q_INTERFACES(MyInterface QmlParserStatus) +public: + MyQmlObject() : m_value(-1), m_interface(0) { qRegisterMetaType<MyCustomVariantType>("MyCustomVariantType"); } + + int value() const { return m_value; } + void setValue(int v) { m_value = v; } + + QString readOnlyString() const { return QLatin1String(""); } + + bool enabled() const { return false; } + void setEnabled(bool) {} + + QRect rect() const { return QRect(); } + void setRect(const QRect&) {} + + QMatrix matrix() const { return QMatrix(); } + void setMatrix(const QMatrix&) {} + + MyInterface *interface() const { return m_interface; } + void setInterface(MyInterface *iface) { m_interface = iface; } + + static MyQmlObject *qmlAttachedProperties(QObject *other) { + MyQmlObject *rv = new MyQmlObject; + rv->setParent(other); + return rv; + } + Q_CLASSINFO("DefaultMethod", "basicSlot()"); + + int onLiteralSignal() const { return m_value; } + void setOnLiteralSignal(int v) { m_value = v; } + + MyCustomVariantType customType() const { return m_custom; } + void setCustomType(const MyCustomVariantType &v) { m_custom = v; } +public slots: + void basicSlot() { qWarning("MyQmlObject::basicSlot"); } + +signals: + void basicSignal(); + +private: + friend class tst_qmlparser; + int m_value; + MyInterface *m_interface; + MyCustomVariantType m_custom; +}; +QML_DECLARE_TYPE(MyQmlObject); + +class MyTypeObject : public QObject +{ + Q_OBJECT + Q_ENUMS(MyEnum) + Q_FLAGS(MyFlags) + + Q_PROPERTY(QString id READ id WRITE setId); + Q_PROPERTY(QObject *objectProperty READ objectProperty WRITE setObjectProperty); + Q_PROPERTY(QmlComponent *componentProperty READ componentProperty WRITE setComponentProperty); + Q_PROPERTY(MyFlags flagProperty READ flagProperty WRITE setFlagProperty); + Q_PROPERTY(MyEnum enumProperty READ enumProperty WRITE setEnumProperty); + Q_PROPERTY(QString stringProperty READ stringProperty WRITE setStringProperty); + Q_PROPERTY(uint uintProperty READ uintProperty WRITE setUintProperty); + Q_PROPERTY(int intProperty READ intProperty WRITE setIntProperty); + Q_PROPERTY(qreal realProperty READ realProperty WRITE setRealProperty); + Q_PROPERTY(double doubleProperty READ doubleProperty WRITE setDoubleProperty); + Q_PROPERTY(QColor colorProperty READ colorProperty WRITE setColorProperty); + Q_PROPERTY(QDate dateProperty READ dateProperty WRITE setDateProperty); + Q_PROPERTY(QTime timeProperty READ timeProperty WRITE setTimeProperty); + Q_PROPERTY(QDateTime dateTimeProperty READ dateTimeProperty WRITE setDateTimeProperty); + Q_PROPERTY(QPoint pointProperty READ pointProperty WRITE setPointProperty); + Q_PROPERTY(QPointF pointFProperty READ pointFProperty WRITE setPointFProperty); + Q_PROPERTY(QSize sizeProperty READ sizeProperty WRITE setSizeProperty); + Q_PROPERTY(QSizeF sizeFProperty READ sizeFProperty WRITE setSizeFProperty); + Q_PROPERTY(QRect rectProperty READ rectProperty WRITE setRectProperty); + Q_PROPERTY(QRectF rectFProperty READ rectFProperty WRITE setRectFProperty); + Q_PROPERTY(bool boolProperty READ boolProperty WRITE setBoolProperty); + Q_PROPERTY(QVariant variantProperty READ variantProperty WRITE setVariantProperty); + +public: + MyTypeObject() + : objectPropertyValue(0), componentPropertyValue(0) {} + + QString idValue; + QString id() const { + return idValue; + } + void setId(const QString &v) { + idValue = v; + } + + QObject *objectPropertyValue; + QObject *objectProperty() const { + return objectPropertyValue; + } + void setObjectProperty(QObject *v) { + objectPropertyValue = v; + } + + QmlComponent *componentPropertyValue; + QmlComponent *componentProperty() const { + return componentPropertyValue; + } + void setComponentProperty(QmlComponent *v) { + componentPropertyValue = v; + } + + enum MyFlag { FlagVal1 = 0x01, FlagVal2 = 0x02, FlagVal3 = 0x04 }; + Q_DECLARE_FLAGS(MyFlags, MyFlag) + MyFlags flagPropertyValue; + MyFlags flagProperty() const { + return flagPropertyValue; + } + void setFlagProperty(MyFlags v) { + flagPropertyValue = v; + } + + enum MyEnum { EnumVal1, EnumVal2 }; + MyEnum enumPropertyValue; + MyEnum enumProperty() const { + return enumPropertyValue; + } + void setEnumProperty(MyEnum v) { + enumPropertyValue = v; + } + + QString stringPropertyValue; + QString stringProperty() const { + return stringPropertyValue; + } + void setStringProperty(const QString &v) { + stringPropertyValue = v; + } + + uint uintPropertyValue; + uint uintProperty() const { + return uintPropertyValue; + } + void setUintProperty(const uint &v) { + uintPropertyValue = v; + } + + int intPropertyValue; + int intProperty() const { + return intPropertyValue; + } + void setIntProperty(const int &v) { + intPropertyValue = v; + } + + qreal realPropertyValue; + qreal realProperty() const { + return realPropertyValue; + } + void setRealProperty(const qreal &v) { + realPropertyValue = v; + } + + double doublePropertyValue; + double doubleProperty() const { + return doublePropertyValue; + } + void setDoubleProperty(const double &v) { + doublePropertyValue = v; + } + + QColor colorPropertyValue; + QColor colorProperty() const { + return colorPropertyValue; + } + void setColorProperty(const QColor &v) { + colorPropertyValue = v; + } + + QDate datePropertyValue; + QDate dateProperty() const { + return datePropertyValue; + } + void setDateProperty(const QDate &v) { + datePropertyValue = v; + } + + QTime timePropertyValue; + QTime timeProperty() const { + return timePropertyValue; + } + void setTimeProperty(const QTime &v) { + timePropertyValue = v; + } + + QDateTime dateTimePropertyValue; + QDateTime dateTimeProperty() const { + return dateTimePropertyValue; + } + void setDateTimeProperty(const QDateTime &v) { + dateTimePropertyValue = v; + } + + QPoint pointPropertyValue; + QPoint pointProperty() const { + return pointPropertyValue; + } + void setPointProperty(const QPoint &v) { + pointPropertyValue = v; + } + + QPointF pointFPropertyValue; + QPointF pointFProperty() const { + return pointFPropertyValue; + } + void setPointFProperty(const QPointF &v) { + pointFPropertyValue = v; + } + + QSize sizePropertyValue; + QSize sizeProperty() const { + return sizePropertyValue; + } + void setSizeProperty(const QSize &v) { + sizePropertyValue = v; + } + + QSizeF sizeFPropertyValue; + QSizeF sizeFProperty() const { + return sizeFPropertyValue; + } + void setSizeFProperty(const QSizeF &v) { + sizeFPropertyValue = v; + } + + QRect rectPropertyValue; + QRect rectProperty() const { + return rectPropertyValue; + } + void setRectProperty(const QRect &v) { + rectPropertyValue = v; + } + + QRectF rectFPropertyValue; + QRectF rectFProperty() const { + return rectFPropertyValue; + } + void setRectFProperty(const QRectF &v) { + rectFPropertyValue = v; + } + + bool boolPropertyValue; + bool boolProperty() const { + return boolPropertyValue; + } + void setBoolProperty(const bool &v) { + boolPropertyValue = v; + } + + QVariant variantPropertyValue; + QVariant variantProperty() const { + return variantPropertyValue; + } + void setVariantProperty(const QVariant &v) { + variantPropertyValue = v; + } +}; +Q_DECLARE_OPERATORS_FOR_FLAGS(MyTypeObject::MyFlags) +QML_DECLARE_TYPE(MyTypeObject); + +class MyContainer : public QObject +{ + Q_OBJECT + Q_PROPERTY(QList<QObject*>* children READ children) + Q_PROPERTY(QList<MyInterface*>* qlistInterfaces READ qlistInterfaces) + Q_PROPERTY(QmlList<MyInterface*>* qmllistInterfaces READ qmllistInterfaces) + Q_CLASSINFO("DefaultProperty", "children"); +public: + MyContainer() {} + + QList<QObject*> *children() { return &m_children; } + QList<MyInterface *> *qlistInterfaces() { return &m_interfaces; } + QmlList<MyInterface *> *qmllistInterfaces() { return &m_qmlinterfaces; } + const QmlConcreteList<MyInterface *> &qmllistAccessor() const { return m_qmlinterfaces; } + +private: + QList<QObject*> m_children; + QList<MyInterface *> m_interfaces; + QmlConcreteList<MyInterface *> m_qmlinterfaces; +}; + +QML_DECLARE_TYPE(MyContainer); + +class MyPropertyValueSource : public QmlPropertyValueSource +{ + Q_OBJECT +public: + MyPropertyValueSource() + : QmlPropertyValueSource(0) {} + + QmlMetaProperty prop; + virtual void setTarget(const QmlMetaProperty &p) + { + prop = p; + } +}; +QML_DECLARE_TYPE(MyPropertyValueSource); + +class MyDotPropertyObject : public QObject +{ + Q_OBJECT + Q_PROPERTY(MyQmlObject *obj READ obj) + Q_PROPERTY(MyQmlObject *readWriteObj READ readWriteObj WRITE setReadWriteObj) +public: + MyDotPropertyObject() : m_rwobj(0), m_ownRWObj(false) {} + ~MyDotPropertyObject() + { + if (m_ownRWObj) + delete m_rwobj; + } + + MyQmlObject *obj() { return 0; } + + MyQmlObject *readWriteObj() + { + if (!m_rwobj) { + m_rwobj = new MyQmlObject; + m_ownRWObj = true; + } + return m_rwobj; + } + + void setReadWriteObj(MyQmlObject *obj) + { + if (m_ownRWObj) { + delete m_rwobj; + m_ownRWObj = false; + } + + m_rwobj = obj; + } + +private: + MyQmlObject *m_rwobj; + bool m_ownRWObj; +}; + +QML_DECLARE_TYPE(MyDotPropertyObject); + + + +#endif // TESTTYPES_H diff --git a/tests/auto/declarative/qmlparser/tst_qmlparser.cpp b/tests/auto/declarative/qmlparser/tst_qmlparser.cpp new file mode 100644 index 0000000..cdc2a72 --- /dev/null +++ b/tests/auto/declarative/qmlparser/tst_qmlparser.cpp @@ -0,0 +1,440 @@ +#include <qtest.h> +#include <QtDeclarative/qmlengine.h> +#include <QtDeclarative/qmlcomponent.h> +#include <QtCore/qfile.h> +#include <QtCore/qdebug.h> +#include <QtCore/qfileinfo.h> +#include <QtCore/qdir.h> +#include "testtypes.h" + +class tst_qmlparser : public QObject +{ + Q_OBJECT +public: + tst_qmlparser() { + QmlMetaType::registerCustomStringConverter(qMetaTypeId<MyCustomVariantType>(), myCustomVariantTypeConverter); + } + +private slots: + + void errors_data(); + void errors(); + + void simpleObject(); + void simpleContainer(); + void interfaceProperty(); + void interfaceQmlList(); + void interfaceQList(); + void assignObjectToSignal(); + void assignObjectToVariant(); + void assignLiteralSignalProperty(); + void assignQmlComponent(); + void assignBasicTypes(); + void assignTypeExtremes(); + void customParserTypes(); + void rootAsQmlComponent(); + void inlineQmlComponents(); + void idProperty(); + void assignSignal(); + void dynamicProperties(); + void dynamicSignalsAndSlots(); + void simpleBindings(); + void autoComponentCreation(); + void propertyValueSource(); + void attachedProperties(); + void dynamicObjects(); + void customVariantTypes(); + + // regression tests for crashes + void crash1(); + +private: + QmlEngine engine; +}; + +#define VERIFY_ERRORS(errorfile) \ + if (!errorfile) { \ + QVERIFY(!component.isError()); \ + QVERIFY(component.errors().isEmpty()); \ + } else { \ + QFile file(errorfile); \ + QVERIFY(file.open(QIODevice::ReadOnly)); \ + QByteArray data = file.readAll(); \ + QList<QByteArray> expected = data.split('\n'); \ + expected.removeAll(QByteArray("")); \ + QList<QmlError> errors = component.errors(); \ + QList<QByteArray> actual; \ + for (int ii = 0; ii < errors.count(); ++ii) { \ + const QmlError &error = errors.at(ii); \ + QByteArray errorStr = QByteArray::number(error.line()) + ":" + \ + QByteArray::number(error.column()) + ":" + \ + error.description().toUtf8(); \ + actual << errorStr; \ + } \ + if (qgetenv("DEBUG") != "" && expected != actual) \ + qWarning() << "Expected:" << expected << "Actual:" << actual; \ + QCOMPARE(expected, actual); \ + } + +inline QUrl TEST_FILE(const QString &filename) +{ + QFileInfo fileInfo(__FILE__); + return QUrl::fromLocalFile(fileInfo.absoluteDir().filePath(filename)); +} + +inline QUrl TEST_FILE(const char *filename) +{ + return TEST_FILE(QLatin1String(filename)); +} + +void tst_qmlparser::errors_data() +{ + QTest::addColumn<QString>("file"); + QTest::addColumn<QString>("errorFile"); + QTest::addColumn<bool>("create"); + + QTest::newRow("nonExistantProperty.1") << "nonexistantProperty.1.txt" << "nonexistantProperty.1.errors.txt" << false; + QTest::newRow("nonExistantProperty.2") << "nonexistantProperty.2.txt" << "nonexistantProperty.2.errors.txt" << false; + QTest::newRow("nonExistantProperty.3") << "nonexistantProperty.3.txt" << "nonexistantProperty.3.errors.txt" << false; + QTest::newRow("nonExistantProperty.4") << "nonexistantProperty.4.txt" << "nonexistantProperty.4.errors.txt" << false; + QTest::newRow("nonExistantProperty.5") << "nonexistantProperty.5.txt" << "nonexistantProperty.5.errors.txt" << false; + QTest::newRow("nonExistantProperty.6") << "nonexistantProperty.6.txt" << "nonexistantProperty.6.errors.txt" << true; + + QTest::newRow("wrongType (string for int)") << "wrongType.1.txt" << "wrongType.1.errors.txt" << false; + QTest::newRow("wrongType (int for bool)") << "wrongType.2.txt" << "wrongType.2.errors.txt" << false; + QTest::newRow("wrongType (bad rect)") << "wrongType.3.txt" << "wrongType.3.errors.txt" << false; + + QTest::newRow("wrongType (invalid enum)") << "wrongType.4.txt" << "wrongType.4.errors.txt" << false; + QTest::newRow("wrongType (int for uint)") << "wrongType.5.txt" << "wrongType.5.errors.txt" << false; + QTest::newRow("wrongType (string for real)") << "wrongType.6.txt" << "wrongType.6.errors.txt" << false; + QTest::newRow("wrongType (int for color)") << "wrongType.7.txt" << "wrongType.7.errors.txt" << false; + QTest::newRow("wrongType (int for date)") << "wrongType.8.txt" << "wrongType.8.errors.txt" << false; + QTest::newRow("wrongType (int for time)") << "wrongType.9.txt" << "wrongType.9.errors.txt" << false; + QTest::newRow("wrongType (int for datetime)") << "wrongType.10.txt" << "wrongType.10.errors.txt" << false; + QTest::newRow("wrongType (string for point)") << "wrongType.11.txt" << "wrongType.11.errors.txt" << false; + QTest::newRow("wrongType (color for size)") << "wrongType.12.txt" << "wrongType.12.errors.txt" << false; + QTest::newRow("wrongType (number string for int)") << "wrongType.13.txt" << "wrongType.13.errors.txt" << false; + QTest::newRow("wrongType (int for string)") << "wrongType.14.txt" << "wrongType.14.errors.txt" << false; + + QTest::newRow("readOnly.1") << "readOnly.1.txt" << "readOnly.1.errors.txt" << false; + QTest::newRow("readOnly.2") << "readOnly.2.txt" << "readOnly.2.errors.txt" << true; + + QTest::newRow("listAssignment.1") << "listAssignment.1.txt" << "listAssignment.1.errors.txt" << false; + QTest::newRow("listAssignment.2") << "listAssignment.2.txt" << "listAssignment.2.errors.txt" << false; + QTest::newRow("listAssignment.3") << "listAssignment.3.txt" << "listAssignment.3.errors.txt" << false; + + QTest::newRow("invalidID.1") << "invalidID.txt" << "invalidID.errors.txt" << false; + QTest::newRow("invalidID.2") << "invalidID.2.txt" << "invalidID.2.errors.txt" << false; + QTest::newRow("invalidID.3") << "invalidID.3.txt" << "invalidID.3.errors.txt" << false; + QTest::newRow("invalidID.4") << "invalidID.4.txt" << "invalidID.4.errors.txt" << false; + + QTest::newRow("unsupportedProperty") << "unsupportedProperty.txt" << "unsupportedProperty.errors.txt" << false; + QTest::newRow("nullDotProperty") << "nullDotProperty.txt" << "nullDotProperty.errors.txt" << true; + QTest::newRow("fakeDotProperty") << "fakeDotProperty.txt" << "fakeDotProperty.errors.txt" << false; + QTest::newRow("duplicateIDs") << "duplicateIDs.txt" << "duplicateIDs.errors.txt" << false; + QTest::newRow("unregisteredObject") << "unregisteredObject.txt" << "unregisteredObject.errors.txt" << false; + QTest::newRow("empty") << "empty.txt" << "empty.errors.txt" << false; + QTest::newRow("missingObject") << "missingObject.txt" << "missingObject.errors.txt" << false; + QTest::newRow("failingComponent") << "failingComponent.txt" << "failingComponent.errors.txt" << false; + QTest::newRow("missingSignal") << "missingSignal.txt" << "missingSignal.errors.txt" << false; +} + +void tst_qmlparser::errors() +{ + QFETCH(QString, file); + QFETCH(QString, errorFile); + QFETCH(bool, create); + + QmlComponent component(&engine, TEST_FILE(file)); + + if(create) { + QObject *object = component.create(); + QVERIFY(object == 0); + } + + VERIFY_ERRORS(errorFile.toLatin1().constData()); +} + +void tst_qmlparser::simpleObject() +{ + QmlComponent component(&engine, TEST_FILE("simpleObject.txt")); + VERIFY_ERRORS(0); + QObject *object = component.create(); + QVERIFY(object != 0); +} + +void tst_qmlparser::simpleContainer() +{ + QmlComponent component(&engine, TEST_FILE("simpleContainer.txt")); + MyContainer *container= qobject_cast<MyContainer*>(component.create()); + QVERIFY(container != 0); + QCOMPARE(container->children()->count(),2); +} + +void tst_qmlparser::interfaceProperty() +{ + QmlComponent component(&engine, TEST_FILE("interfaceProperty.txt")); + MyQmlObject *object = qobject_cast<MyQmlObject*>(component.create()); + QVERIFY(object != 0); + QVERIFY(object->interface()); + QVERIFY(object->interface()->id == 913); +} + +void tst_qmlparser::interfaceQmlList() +{ + QmlComponent component(&engine, TEST_FILE("interfaceQmlList.txt")); + MyContainer *container= qobject_cast<MyContainer*>(component.create()); + QVERIFY(container != 0); + QVERIFY(container->qmllistAccessor().count() == 2); + for(int ii = 0; ii < 2; ++ii) + QVERIFY(container->qmllistAccessor().at(ii)->id == 913); +} + +void tst_qmlparser::interfaceQList() +{ + QmlComponent component(&engine, TEST_FILE("interfaceQList.txt")); + MyContainer *container= qobject_cast<MyContainer*>(component.create()); + QVERIFY(container != 0); + QVERIFY(container->qlistInterfaces()->count() == 2); + for(int ii = 0; ii < 2; ++ii) + QVERIFY(container->qlistInterfaces()->at(ii)->id == 913); +} + +void tst_qmlparser::assignObjectToSignal() +{ + QmlComponent component(&engine, TEST_FILE("assignObjectToSignal.txt")); + MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create()); + QVERIFY(object != 0); + QTest::ignoreMessage(QtWarningMsg, "MyQmlObject::basicSlot"); + emit object->basicSignal(); +} + +void tst_qmlparser::assignObjectToVariant() +{ + QmlComponent component(&engine, TEST_FILE("assignObjectToVariant.txt")); + QObject *object = component.create(); + QVERIFY(object != 0); + QVariant v = object->property("a"); + QVERIFY(v.userType() == qMetaTypeId<QObject *>()); +} + +void tst_qmlparser::assignLiteralSignalProperty() +{ + QmlComponent component(&engine, TEST_FILE("assignLiteralSignalProperty.txt")); + MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create()); + QVERIFY(object != 0); + QCOMPARE(object->onLiteralSignal(), 10); +} + +// Test is an external component can be loaded and assigned (to a qlist) +void tst_qmlparser::assignQmlComponent() +{ + QmlComponent component(&engine, TEST_FILE("assignQmlComponent.txt")); + MyContainer *object = qobject_cast<MyContainer *>(component.create()); + QVERIFY(object != 0); + QVERIFY(object->children()->count() == 1); + QObject *child = object->children()->at(0); + QCOMPARE(child->property("x"), QVariant(10)); + QCOMPARE(child->property("y"), QVariant(11)); +} + +// Test literal assignment to all the basic types +void tst_qmlparser::assignBasicTypes() +{ + QmlComponent component(&engine, TEST_FILE("assignBasicTypes.txt")); + MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create()); + QVERIFY(object != 0); + QCOMPARE(object->flagProperty(), MyTypeObject::FlagVal1 | MyTypeObject::FlagVal3); + QCOMPARE(object->enumProperty(), MyTypeObject::EnumVal2); + QCOMPARE(object->stringProperty(), QString("Hello World!")); + QCOMPARE(object->uintProperty(), uint(10)); + QCOMPARE(object->intProperty(), -19); + QCOMPARE((float)object->realProperty(), float(23.2)); + QCOMPARE((float)object->doubleProperty(), float(-19.7)); + QCOMPARE(object->colorProperty(), QColor("red")); + QCOMPARE(object->dateProperty(), QDate(1982, 11, 25)); + QCOMPARE(object->timeProperty(), QTime(11, 11, 32)); + QCOMPARE(object->dateTimeProperty(), QDateTime(QDate(2009, 5, 12), QTime(13, 22, 1))); + QCOMPARE(object->pointProperty(), QPoint(99,13)); + QCOMPARE(object->pointFProperty(), QPointF((float)-10.1, (float)12.3)); + QCOMPARE(object->sizeProperty(), QSize(99, 13)); + QCOMPARE(object->sizeFProperty(), QSizeF((float)0.1, (float)0.2)); + QCOMPARE(object->rectProperty(), QRect(9, 7, 100, 200)); + QCOMPARE(object->rectFProperty(), QRectF((float)1000.1, (float)-10.9, (float)400, (float)90.99)); + QCOMPARE(object->boolProperty(), true); + QCOMPARE(object->variantProperty(), QVariant("Hello World!")); + QVERIFY(object->objectProperty() != 0); + MyTypeObject *child = qobject_cast<MyTypeObject *>(object->objectProperty()); + QVERIFY(child != 0); + QCOMPARE(child->intProperty(), 8); +} + +// Test edge case type assignments +void tst_qmlparser::assignTypeExtremes() +{ + QmlComponent component(&engine, TEST_FILE("assignTypeExtremes.txt")); + MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create()); + QVERIFY(object != 0); + QCOMPARE(object->uintProperty(), 0xEE6B2800); + QCOMPARE(object->intProperty(), -0x77359400); +} + +// Tests that custom parser tyeps can be instantiated +void tst_qmlparser::customParserTypes() +{ + QmlComponent component(&engine, TEST_FILE("customParserTypes.txt")); + QObject *object = component.create(); + QVERIFY(object != 0); + QVERIFY(object->property("count") == QVariant(2)); +} + +// Tests that the root item can be a custom component +void tst_qmlparser::rootAsQmlComponent() +{ + QmlComponent component(&engine, TEST_FILE("rootAsQmlComponent.txt")); + MyContainer *object = qobject_cast<MyContainer *>(component.create()); + QVERIFY(object != 0); + QCOMPARE(object->property("x"), QVariant(11)); + QCOMPARE(object->children()->count(), 2); +} + +// Tests that components can be specified inline +void tst_qmlparser::inlineQmlComponents() +{ + QmlComponent component(&engine, TEST_FILE("inlineQmlComponents.txt")); + MyContainer *object = qobject_cast<MyContainer *>(component.create()); + QVERIFY(object != 0); + QCOMPARE(object->children()->count(), 1); + QmlComponent *comp = qobject_cast<QmlComponent *>(object->children()->at(0)); + QVERIFY(comp != 0); + MyQmlObject *compObject = qobject_cast<MyQmlObject *>(comp->create()); + QVERIFY(compObject != 0); + QCOMPARE(compObject->value(), 11); +} + +// Tests that types that have an id property have it set +void tst_qmlparser::idProperty() +{ + QmlComponent component(&engine, TEST_FILE("idProperty.txt")); + MyContainer *object = qobject_cast<MyContainer *>(component.create()); + QVERIFY(object != 0); + QCOMPARE(object->children()->count(), 1); + MyTypeObject *child = + qobject_cast<MyTypeObject *>(object->children()->at(0)); + QVERIFY(child != 0); + QCOMPARE(child->id(), QString("MyObjectId")); + QCOMPARE(object->property("object"), QVariant::fromValue((QObject *)child)); +} + +// Tests that signals can be assigned to +void tst_qmlparser::assignSignal() +{ + QmlComponent component(&engine, TEST_FILE("assignSignal.txt")); + MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create()); + QVERIFY(object != 0); + QTest::ignoreMessage(QtWarningMsg, "MyQmlObject::basicSlot"); + emit object->basicSignal(); +} + +// Tests the creation and assignment of dynamic properties +void tst_qmlparser::dynamicProperties() +{ + QmlComponent component(&engine, TEST_FILE("dynamicProperties.txt")); + QObject *object = component.create(); + QVERIFY(object != 0); + QCOMPARE(object->property("intProperty"), QVariant(10)); + QCOMPARE(object->property("boolProperty"), QVariant(false)); + QCOMPARE(object->property("doubleProperty"), QVariant((float)-10.1)); + QCOMPARE(object->property("realProperty"), QVariant((float)-19.9)); + QCOMPARE(object->property("stringProperty"), QVariant("Hello World!")); + QCOMPARE(object->property("colorProperty"), QVariant(QColor("red"))); + QCOMPARE(object->property("dateProperty"), QVariant(QDate(1945, 9, 2))); + QCOMPARE(object->property("varProperty"), QVariant("Hello World!")); + QCOMPARE(object->property("variantProperty"), QVariant(12)); +} + +// Tests the declaration of dynamic signals and slots +void tst_qmlparser::dynamicSignalsAndSlots() +{ + QmlComponent component(&engine, TEST_FILE("dynamicSignalsAndSlots.txt")); + QObject *object = component.create(); + QVERIFY(object != 0); + QVERIFY(object->metaObject()->indexOfMethod("signal1()") != -1); + QVERIFY(object->metaObject()->indexOfMethod("signal2()") != -1); + QVERIFY(object->metaObject()->indexOfMethod("slot1()") != -1); + QVERIFY(object->metaObject()->indexOfMethod("slot2()") != -1); +} + +void tst_qmlparser::simpleBindings() +{ + QmlComponent component(&engine, TEST_FILE("simpleBindings.txt")); + QObject *object = component.create(); + QVERIFY(object != 0); + QCOMPARE(object->property("value1"), QVariant(10)); + QCOMPARE(object->property("value2"), QVariant(10)); + QCOMPARE(object->property("value3"), QVariant(21)); + QCOMPARE(object->property("value4"), QVariant(10)); + QCOMPARE(object->property("objectProperty"), QVariant::fromValue(object)); +} + +void tst_qmlparser::autoComponentCreation() +{ + QmlComponent component(&engine, TEST_FILE("autoComponentCreation.txt")); + MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create()); + QVERIFY(object != 0); + QVERIFY(object->componentProperty() != 0); + MyTypeObject *child = qobject_cast<MyTypeObject *>(object->componentProperty()->create()); + QVERIFY(child != 0); + QCOMPARE(child->realProperty(), qreal(9)); +} + +void tst_qmlparser::propertyValueSource() +{ + QmlComponent component(&engine, TEST_FILE("propertyValueSource.txt")); + MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create()); + QVERIFY(object != 0); + QList<QmlPropertyValueSource *> valueSources = + object->findChildren<QmlPropertyValueSource *>(); + QCOMPARE(valueSources.count(), 1); + MyPropertyValueSource *valueSource = + qobject_cast<MyPropertyValueSource *>(valueSources.at(0)); + QVERIFY(valueSource != 0); + QCOMPARE(valueSource->prop.object(), object); + QCOMPARE(valueSource->prop.name(), QString(QLatin1String("intProperty"))); +} + +void tst_qmlparser::attachedProperties() +{ + QmlComponent component(&engine, TEST_FILE("attachedProperties.txt")); + QObject *object = component.create(); + QVERIFY(object != 0); + QObject *attached = qmlAttachedPropertiesObject<MyQmlObject>(object); + QVERIFY(attached != 0); + QCOMPARE(attached->property("value"), QVariant(10)); +} + +// Tests non-static object properties +void tst_qmlparser::dynamicObjects() +{ + QmlComponent component(&engine, TEST_FILE("dynamicObject.1.txt")); + QObject *object = component.create(); + QVERIFY(object != 0); +} + +// Tests the registration of custom variant string converters +void tst_qmlparser::customVariantTypes() +{ + QmlComponent component(&engine, TEST_FILE("customVariantTypes.txt")); + MyQmlObject *object = qobject_cast<MyQmlObject*>(component.create()); + QVERIFY(object != 0); + QCOMPARE(object->customType().a, 10); +} + +void tst_qmlparser::crash1() +{ + QmlComponent component(&engine, "Component {}"); +} + +QTEST_MAIN(tst_qmlparser) + +#include "tst_qmlparser.moc" diff --git a/tests/auto/declarative/qmlparser/unregisteredObject.errors.txt b/tests/auto/declarative/qmlparser/unregisteredObject.errors.txt new file mode 100644 index 0000000..11e4e16 --- /dev/null +++ b/tests/auto/declarative/qmlparser/unregisteredObject.errors.txt @@ -0,0 +1 @@ +-1:-1:Type UnregisteredObject unavailable diff --git a/tests/auto/declarative/qmlparser/unregisteredObject.txt b/tests/auto/declarative/qmlparser/unregisteredObject.txt new file mode 100644 index 0000000..ff46457 --- /dev/null +++ b/tests/auto/declarative/qmlparser/unregisteredObject.txt @@ -0,0 +1 @@ +UnregisteredObject {} diff --git a/tests/auto/declarative/qmlparser/unsupportedProperty.errors.txt b/tests/auto/declarative/qmlparser/unsupportedProperty.errors.txt new file mode 100644 index 0000000..a067ecb --- /dev/null +++ b/tests/auto/declarative/qmlparser/unsupportedProperty.errors.txt @@ -0,0 +1 @@ +2:5:Cannot assign value to property matrix of unknown type diff --git a/tests/auto/declarative/qmlparser/unsupportedProperty.txt b/tests/auto/declarative/qmlparser/unsupportedProperty.txt new file mode 100644 index 0000000..bbbd31d --- /dev/null +++ b/tests/auto/declarative/qmlparser/unsupportedProperty.txt @@ -0,0 +1,3 @@ +MyQmlObject { + matrix: "1,0,0,0,1,0,0,0,1" +} diff --git a/tests/auto/declarative/qmlparser/wrongType.1.errors.txt b/tests/auto/declarative/qmlparser/wrongType.1.errors.txt new file mode 100644 index 0000000..8976ee1 --- /dev/null +++ b/tests/auto/declarative/qmlparser/wrongType.1.errors.txt @@ -0,0 +1 @@ +2:12:Cannot assign value "hello" to property value diff --git a/tests/auto/declarative/qmlparser/wrongType.1.txt b/tests/auto/declarative/qmlparser/wrongType.1.txt new file mode 100644 index 0000000..281a227 --- /dev/null +++ b/tests/auto/declarative/qmlparser/wrongType.1.txt @@ -0,0 +1,3 @@ +MyQmlObject { + value: "hello" +} diff --git a/tests/auto/declarative/qmlparser/wrongType.10.errors.txt b/tests/auto/declarative/qmlparser/wrongType.10.errors.txt new file mode 100644 index 0000000..562cd6c --- /dev/null +++ b/tests/auto/declarative/qmlparser/wrongType.10.errors.txt @@ -0,0 +1 @@ +2:23:Cannot assign value "12" to property dateTimeProperty diff --git a/tests/auto/declarative/qmlparser/wrongType.10.txt b/tests/auto/declarative/qmlparser/wrongType.10.txt new file mode 100644 index 0000000..07a90e0 --- /dev/null +++ b/tests/auto/declarative/qmlparser/wrongType.10.txt @@ -0,0 +1,4 @@ +MyTypeObject { + dateTimeProperty: 12 +} + diff --git a/tests/auto/declarative/qmlparser/wrongType.11.errors.txt b/tests/auto/declarative/qmlparser/wrongType.11.errors.txt new file mode 100644 index 0000000..24d27d5 --- /dev/null +++ b/tests/auto/declarative/qmlparser/wrongType.11.errors.txt @@ -0,0 +1 @@ +2:20:Cannot assign value "apples" to property pointProperty diff --git a/tests/auto/declarative/qmlparser/wrongType.11.txt b/tests/auto/declarative/qmlparser/wrongType.11.txt new file mode 100644 index 0000000..90a3797 --- /dev/null +++ b/tests/auto/declarative/qmlparser/wrongType.11.txt @@ -0,0 +1,4 @@ +MyTypeObject { + pointProperty: "apples" +} + diff --git a/tests/auto/declarative/qmlparser/wrongType.12.errors.txt b/tests/auto/declarative/qmlparser/wrongType.12.errors.txt new file mode 100644 index 0000000..b57e70e --- /dev/null +++ b/tests/auto/declarative/qmlparser/wrongType.12.errors.txt @@ -0,0 +1 @@ +2:19:Cannot assign value "red" to property sizeProperty diff --git a/tests/auto/declarative/qmlparser/wrongType.12.txt b/tests/auto/declarative/qmlparser/wrongType.12.txt new file mode 100644 index 0000000..c3fa4a0 --- /dev/null +++ b/tests/auto/declarative/qmlparser/wrongType.12.txt @@ -0,0 +1,4 @@ +MyTypeObject { + sizeProperty: "red" +} + diff --git a/tests/auto/declarative/qmlparser/wrongType.13.errors.txt b/tests/auto/declarative/qmlparser/wrongType.13.errors.txt new file mode 100644 index 0000000..7ff4bf3 --- /dev/null +++ b/tests/auto/declarative/qmlparser/wrongType.13.errors.txt @@ -0,0 +1 @@ +2:12:Cannot assign value "12" to property value diff --git a/tests/auto/declarative/qmlparser/wrongType.13.txt b/tests/auto/declarative/qmlparser/wrongType.13.txt new file mode 100644 index 0000000..075ec03 --- /dev/null +++ b/tests/auto/declarative/qmlparser/wrongType.13.txt @@ -0,0 +1,3 @@ +MyQmlObject { + value: "12" +} diff --git a/tests/auto/declarative/qmlparser/wrongType.14.errors.txt b/tests/auto/declarative/qmlparser/wrongType.14.errors.txt new file mode 100644 index 0000000..ec41e01 --- /dev/null +++ b/tests/auto/declarative/qmlparser/wrongType.14.errors.txt @@ -0,0 +1 @@ +2:23:Cannot assign value 10 to property stringProperty diff --git a/tests/auto/declarative/qmlparser/wrongType.14.txt b/tests/auto/declarative/qmlparser/wrongType.14.txt new file mode 100644 index 0000000..3d39c87 --- /dev/null +++ b/tests/auto/declarative/qmlparser/wrongType.14.txt @@ -0,0 +1,4 @@ +MyTypeObject { + stringProperty: 10 +} + diff --git a/tests/auto/declarative/qmlparser/wrongType.2.errors.txt b/tests/auto/declarative/qmlparser/wrongType.2.errors.txt new file mode 100644 index 0000000..301d258 --- /dev/null +++ b/tests/auto/declarative/qmlparser/wrongType.2.errors.txt @@ -0,0 +1 @@ +2:14:Cannot assign value "5" to property enabled diff --git a/tests/auto/declarative/qmlparser/wrongType.2.txt b/tests/auto/declarative/qmlparser/wrongType.2.txt new file mode 100644 index 0000000..cdedf8c --- /dev/null +++ b/tests/auto/declarative/qmlparser/wrongType.2.txt @@ -0,0 +1,3 @@ +MyQmlObject { + enabled: 5 +} diff --git a/tests/auto/declarative/qmlparser/wrongType.3.errors.txt b/tests/auto/declarative/qmlparser/wrongType.3.errors.txt new file mode 100644 index 0000000..3afcc2b --- /dev/null +++ b/tests/auto/declarative/qmlparser/wrongType.3.errors.txt @@ -0,0 +1 @@ +2:11:Cannot assign value "5,5x10" to property rect diff --git a/tests/auto/declarative/qmlparser/wrongType.3.txt b/tests/auto/declarative/qmlparser/wrongType.3.txt new file mode 100644 index 0000000..839e0c7 --- /dev/null +++ b/tests/auto/declarative/qmlparser/wrongType.3.txt @@ -0,0 +1,3 @@ +MyQmlObject { + rect: "5,5x10" +} diff --git a/tests/auto/declarative/qmlparser/wrongType.4.errors.txt b/tests/auto/declarative/qmlparser/wrongType.4.errors.txt new file mode 100644 index 0000000..6bf88be --- /dev/null +++ b/tests/auto/declarative/qmlparser/wrongType.4.errors.txt @@ -0,0 +1 @@ +2:19:Cannot assign value "InvalidEnumName" to property enumProperty diff --git a/tests/auto/declarative/qmlparser/wrongType.4.txt b/tests/auto/declarative/qmlparser/wrongType.4.txt new file mode 100644 index 0000000..6fa4a9c --- /dev/null +++ b/tests/auto/declarative/qmlparser/wrongType.4.txt @@ -0,0 +1,3 @@ +MyTypeObject { + enumProperty: "InvalidEnumName" +} diff --git a/tests/auto/declarative/qmlparser/wrongType.5.errors.txt b/tests/auto/declarative/qmlparser/wrongType.5.errors.txt new file mode 100644 index 0000000..0e40d84 --- /dev/null +++ b/tests/auto/declarative/qmlparser/wrongType.5.errors.txt @@ -0,0 +1 @@ +2:19:Cannot assign value "-13" to property uintProperty diff --git a/tests/auto/declarative/qmlparser/wrongType.5.txt b/tests/auto/declarative/qmlparser/wrongType.5.txt new file mode 100644 index 0000000..95b0904 --- /dev/null +++ b/tests/auto/declarative/qmlparser/wrongType.5.txt @@ -0,0 +1,4 @@ +MyTypeObject { + uintProperty: -13 +} + diff --git a/tests/auto/declarative/qmlparser/wrongType.6.errors.txt b/tests/auto/declarative/qmlparser/wrongType.6.errors.txt new file mode 100644 index 0000000..9692997 --- /dev/null +++ b/tests/auto/declarative/qmlparser/wrongType.6.errors.txt @@ -0,0 +1 @@ +2:19:Cannot assign value "Hello" to property realProperty diff --git a/tests/auto/declarative/qmlparser/wrongType.6.txt b/tests/auto/declarative/qmlparser/wrongType.6.txt new file mode 100644 index 0000000..78351f4 --- /dev/null +++ b/tests/auto/declarative/qmlparser/wrongType.6.txt @@ -0,0 +1,4 @@ +MyTypeObject { + realProperty: "Hello" +} + diff --git a/tests/auto/declarative/qmlparser/wrongType.7.errors.txt b/tests/auto/declarative/qmlparser/wrongType.7.errors.txt new file mode 100644 index 0000000..f44073a --- /dev/null +++ b/tests/auto/declarative/qmlparser/wrongType.7.errors.txt @@ -0,0 +1 @@ +2:20:Cannot assign value "12" to property colorProperty diff --git a/tests/auto/declarative/qmlparser/wrongType.7.txt b/tests/auto/declarative/qmlparser/wrongType.7.txt new file mode 100644 index 0000000..8279ffa --- /dev/null +++ b/tests/auto/declarative/qmlparser/wrongType.7.txt @@ -0,0 +1,4 @@ +MyTypeObject { + colorProperty: 12 +} + diff --git a/tests/auto/declarative/qmlparser/wrongType.8.errors.txt b/tests/auto/declarative/qmlparser/wrongType.8.errors.txt new file mode 100644 index 0000000..8a45ffb --- /dev/null +++ b/tests/auto/declarative/qmlparser/wrongType.8.errors.txt @@ -0,0 +1 @@ +2:19:Cannot assign value "12" to property dateProperty diff --git a/tests/auto/declarative/qmlparser/wrongType.8.txt b/tests/auto/declarative/qmlparser/wrongType.8.txt new file mode 100644 index 0000000..e1cfe9a --- /dev/null +++ b/tests/auto/declarative/qmlparser/wrongType.8.txt @@ -0,0 +1,4 @@ +MyTypeObject { + dateProperty: 12 +} + diff --git a/tests/auto/declarative/qmlparser/wrongType.9.errors.txt b/tests/auto/declarative/qmlparser/wrongType.9.errors.txt new file mode 100644 index 0000000..cba3339 --- /dev/null +++ b/tests/auto/declarative/qmlparser/wrongType.9.errors.txt @@ -0,0 +1 @@ +2:19:Cannot assign value "12" to property timeProperty diff --git a/tests/auto/declarative/qmlparser/wrongType.9.txt b/tests/auto/declarative/qmlparser/wrongType.9.txt new file mode 100644 index 0000000..84dfa66 --- /dev/null +++ b/tests/auto/declarative/qmlparser/wrongType.9.txt @@ -0,0 +1,4 @@ +MyTypeObject { + timeProperty: 12 +} + diff --git a/tests/auto/declarative/repeater/data/repeater.qml b/tests/auto/declarative/repeater/data/repeater.qml new file mode 100644 index 0000000..2498646 --- /dev/null +++ b/tests/auto/declarative/repeater/data/repeater.qml @@ -0,0 +1,18 @@ +Rect { + id: container + width: 240 + height: 320 + color: "white" + Repeater { + id: repeater + width: 240 + height: 320 + dataSource: testData + Component { + Text { + y: index*20 + text: modelData + } + } + } +} diff --git a/tests/auto/declarative/repeater/repeater.pro b/tests/auto/declarative/repeater/repeater.pro new file mode 100644 index 0000000..0ecd7ee --- /dev/null +++ b/tests/auto/declarative/repeater/repeater.pro @@ -0,0 +1,6 @@ +load(qttest_p4) +contains(QT_CONFIG,declarative): QT += declarative +SOURCES += tst_repeater.cpp + +# Define SRCDIR equal to test's source directory +DEFINES += SRCDIR=\\\"$$PWD\\\" diff --git a/tests/auto/declarative/repeater/tst_repeater.cpp b/tests/auto/declarative/repeater/tst_repeater.cpp new file mode 100644 index 0000000..0d3ec98 --- /dev/null +++ b/tests/auto/declarative/repeater/tst_repeater.cpp @@ -0,0 +1,91 @@ +#include <QtTest/QtTest> +#include <qlistmodelinterface.h> +#include <qfxview.h> +#include <qfxrepeater.h> +#include <qfxtext.h> +#include <qmlcontext.h> + +class tst_QFxRepeater : public QObject +{ + Q_OBJECT +public: + tst_QFxRepeater(); + +private slots: + void stringList(); + +private: + QFxView *createView(const QString &filename); + template<typename T> + T *findItem(QFxItem *parent, const QString &id); +}; + +tst_QFxRepeater::tst_QFxRepeater() +{ +} + +void tst_QFxRepeater::stringList() +{ + QFxView *canvas = createView(SRCDIR "/data/repeater.xml"); + + QStringList data; + data << "One"; + data << "Two"; + data << "Three"; + data << "Four"; + + QmlContext *ctxt = canvas->rootContext(); + ctxt->setProperty("testData", data); + + canvas->execute(); + qApp->processEvents(); + + QFxRepeater *repeater = findItem<QFxRepeater>(canvas->root(), "repeater"); + QVERIFY(repeater != 0); + + QFxItem *container = findItem<QFxItem>(canvas->root(), "container"); + QVERIFY(container != 0); + + QCOMPARE(container->children()->count(), data.count() + 1); + + for (int i = 1; i < container->children()->count(); ++i) { + QFxText *name = qobject_cast<QFxText*>(container->children()->at(i)); + QVERIFY(name != 0); + QCOMPARE(name->text(), data.at(i-1)); + } + + delete canvas; +} + + +QFxView *tst_QFxRepeater::createView(const QString &filename) +{ + QFxView *canvas = new QFxView(0); + canvas->setFixedSize(240,320); + + QFile file(filename); + file.open(QFile::ReadOnly); + QString xml = file.readAll(); + canvas->setQml(xml, filename); + + return canvas; +} + +template<typename T> +T *tst_QFxRepeater::findItem(QFxItem *parent, const QString &id) +{ + const QMetaObject &mo = T::staticMetaObject; + if (mo.cast(parent) && (id.isEmpty() || parent->id() == id)) + return static_cast<T*>(parent); + for (int i = 0; i < parent->children()->count(); ++i) { + QFxItem *item = findItem<T>(parent->children()->at(i), id); + if (item) + return static_cast<T*>(item); + } + + return 0; +} + +QTEST_MAIN(tst_QFxRepeater) + +#include "tst_repeater.moc" diff --git a/tests/auto/declarative/simplecanvasitem/data/test.qml b/tests/auto/declarative/simplecanvasitem/data/test.qml new file mode 100644 index 0000000..d206a6b --- /dev/null +++ b/tests/auto/declarative/simplecanvasitem/data/test.qml @@ -0,0 +1,58 @@ +Item { + width: 320 + height: 480 + Rect { + color: "blue" + x: 20 + y: 20 + width: 20 + height: 20 + Rect { + color: "black" + x: 20 + y: 20 + width: 10 + height: 10 + } + } + Rect { + color: "red" + x: 40 + y: 20 + width: 20 + height: 20 + } + Rect { + color: "green" + x: 60 + y: 20 + width: 20 + height: 20 + } + Rect { + color: "yellow" + x: 20 + y: 40 + width: 20 + height: 20 + } + Rect { + color: "purple" + x: 20 + y: 60 + width: 20 + height: 20 + } + Rect { + color: "white" + x: 40 + y: 40 + width: 20 + height: 20 + } + Rect { + anchors.fill: parent + color: "gray" + z: -1 + } +} diff --git a/tests/auto/declarative/simplecanvasitem/simplecanvasitem.pro b/tests/auto/declarative/simplecanvasitem/simplecanvasitem.pro new file mode 100644 index 0000000..114be8e --- /dev/null +++ b/tests/auto/declarative/simplecanvasitem/simplecanvasitem.pro @@ -0,0 +1,6 @@ +load(qttest_p4) +contains(QT_CONFIG,declarative): QT += declarative +SOURCES += tst_simplecanvasitem.cpp + +# Define SRCDIR equal to test's source directory +DEFINES += SRCDIR=\\\"$$PWD\\\" diff --git a/tests/auto/declarative/simplecanvasitem/tst_simplecanvasitem.cpp b/tests/auto/declarative/simplecanvasitem/tst_simplecanvasitem.cpp new file mode 100644 index 0000000..cce4df1 --- /dev/null +++ b/tests/auto/declarative/simplecanvasitem/tst_simplecanvasitem.cpp @@ -0,0 +1,79 @@ +#include <QtTest/QtTest> +#include <qfxview.h> +#include <qfxitem.h> +#include <qsimplecanvasitem.h> + +/* + Note: this autotest is specifically to test SimpleCanvasItem as a component of + Qt Declarative, and therefore will have all items created in XML. +*/ +class tst_SimpleCanvasItem : public QObject +{ + Q_OBJECT +public: + tst_SimpleCanvasItem(); + +private slots: + void test_pos(); + void test_scenePos(); +private: + QFxView *createView(const QString &filename); +}; + +tst_SimpleCanvasItem::tst_SimpleCanvasItem() +{ +} + +void tst_SimpleCanvasItem::test_pos() +{ + QFxView *canvas = createView(SRCDIR "/data/test.qml"); + canvas->execute(); + qApp->processEvents(); + QSimpleCanvasItem* root = qobject_cast<QSimpleCanvasItem*>(canvas->root()); + QVERIFY(root); + + QCOMPARE(root->pos(), QPointF(0,0)); + QCOMPARE(root->children().at(0)->pos(), QPointF(20,20)); + QCOMPARE(root->children().at(0)->children().at(0)->pos(), QPointF(20,20)); + QCOMPARE(root->children().at(2)->pos(), QPointF(60,20)); + QCOMPARE(root->children().at(3)->pos(), QPointF(20,40)); + QCOMPARE(root->children().at(5)->pos(), QPointF(40,40)); +} + +void tst_SimpleCanvasItem::test_scenePos() +{ + QFxView *canvas = createView(SRCDIR "/data/test.qml"); + canvas->execute(); + qApp->processEvents(); + QSimpleCanvasItem* root = qobject_cast<QSimpleCanvasItem*>(canvas->root()); + QVERIFY(root); + +#ifdef CANVAS_GL + QCOMPARE(root->transform(), QMatrix4x4()); +#else + QCOMPARE(root->transform(), QTransform()); +#endif + QCOMPARE(root->scenePos(), QPointF(0,0)); + QCOMPARE(root->children().at(0)->scenePos(), QPointF(20,20)); + QCOMPARE(root->children().at(0)->children().at(0)->scenePos(), QPointF(40,40)); + QCOMPARE(root->children().at(2)->scenePos(), QPointF(60,20)); + QCOMPARE(root->children().at(3)->scenePos(), QPointF(20,40)); + QCOMPARE(root->children().at(5)->scenePos(), QPointF(40,40)); +} + +QFxView *tst_SimpleCanvasItem::createView(const QString &filename) +{ + QFxView *canvas = new QFxView(0); + canvas->setFixedSize(240,320); + + QFile file(filename); + file.open(QFile::ReadOnly); + QString xml = file.readAll(); + canvas->setQml(xml, filename); + + return canvas; +} + +QTEST_MAIN(tst_SimpleCanvasItem) + +#include "tst_simplecanvasitem.moc" diff --git a/tests/auto/declarative/visual/ListView/basic1/basic1.qml b/tests/auto/declarative/visual/ListView/basic1/basic1.qml new file mode 100644 index 0000000..d9cd030 --- /dev/null +++ b/tests/auto/declarative/visual/ListView/basic1/basic1.qml @@ -0,0 +1,25 @@ +Rect { + color: "blue" + width: 200 + height: 300 + id: Page + ListView { + anchors.fill: parent + delegate: Rect { + color: "red" + width: 100 + height: 100 + Text { + text: name + } + } + model: ListModel { + ListElement { + name: "January" + } + ListElement { + name: "February" + } + } + } +} diff --git a/tests/auto/declarative/visual/ListView/basic1/data/raster/image0.png b/tests/auto/declarative/visual/ListView/basic1/data/raster/image0.png Binary files differnew file mode 100644 index 0000000..f8a4830 --- /dev/null +++ b/tests/auto/declarative/visual/ListView/basic1/data/raster/image0.png diff --git a/tests/auto/declarative/visual/ListView/basic1/data/raster/manifest.qml b/tests/auto/declarative/visual/ListView/basic1/data/raster/manifest.qml new file mode 100644 index 0000000..6d900f5 --- /dev/null +++ b/tests/auto/declarative/visual/ListView/basic1/data/raster/manifest.qml @@ -0,0 +1,6 @@ +TestLog { + TestFullFrame { + time: 0 + frameId: 0 + } +} diff --git a/tests/auto/declarative/visual/ListView/basic1/test b/tests/auto/declarative/visual/ListView/basic1/test new file mode 100644 index 0000000..49fcf5a --- /dev/null +++ b/tests/auto/declarative/visual/ListView/basic1/test @@ -0,0 +1 @@ +basic1.qml diff --git a/tests/auto/declarative/visual/ListView/basic2/basic2.qml b/tests/auto/declarative/visual/ListView/basic2/basic2.qml new file mode 100644 index 0000000..e5996cf --- /dev/null +++ b/tests/auto/declarative/visual/ListView/basic2/basic2.qml @@ -0,0 +1,29 @@ +Rect { + color: "blue" + width: 200 + height: 300 + id: Page + Component { + id: Delegate + Rect { + color: "red" + width: 100 + height: 100 + Text { + text: name + } + } + } + ListView { + anchors.fill: parent + delegate: Delegate + model: ListModel { + ListElement { + name: "January" + } + ListElement { + name: "February" + } + } + } +} diff --git a/tests/auto/declarative/visual/ListView/basic2/data/raster/image0.png b/tests/auto/declarative/visual/ListView/basic2/data/raster/image0.png Binary files differnew file mode 100644 index 0000000..f8a4830 --- /dev/null +++ b/tests/auto/declarative/visual/ListView/basic2/data/raster/image0.png diff --git a/tests/auto/declarative/visual/ListView/basic2/data/raster/manifest.qml b/tests/auto/declarative/visual/ListView/basic2/data/raster/manifest.qml new file mode 100644 index 0000000..6d900f5 --- /dev/null +++ b/tests/auto/declarative/visual/ListView/basic2/data/raster/manifest.qml @@ -0,0 +1,6 @@ +TestLog { + TestFullFrame { + time: 0 + frameId: 0 + } +} diff --git a/tests/auto/declarative/visual/ListView/basic2/test b/tests/auto/declarative/visual/ListView/basic2/test new file mode 100644 index 0000000..eb79495 --- /dev/null +++ b/tests/auto/declarative/visual/ListView/basic2/test @@ -0,0 +1 @@ +basic2.qml diff --git a/tests/auto/declarative/visual/ListView/basic3/basic3.qml b/tests/auto/declarative/visual/ListView/basic3/basic3.qml new file mode 100644 index 0000000..98aa5fb --- /dev/null +++ b/tests/auto/declarative/visual/ListView/basic3/basic3.qml @@ -0,0 +1,27 @@ +Rect { + color: "blue" + width: 200 + height: 300 + id: Page + ListModel { + id: Model + ListElement { + name: "January" + } + ListElement { + name: "February" + } + } + ListView { + anchors.fill: parent + model: Model + delegate: Rect { + color: "red" + width: 100 + height: 100 + Text { + text: name + } + } + } +} diff --git a/tests/auto/declarative/visual/ListView/basic3/data/raster/image0.png b/tests/auto/declarative/visual/ListView/basic3/data/raster/image0.png Binary files differnew file mode 100644 index 0000000..f8a4830 --- /dev/null +++ b/tests/auto/declarative/visual/ListView/basic3/data/raster/image0.png diff --git a/tests/auto/declarative/visual/ListView/basic3/data/raster/manifest.qml b/tests/auto/declarative/visual/ListView/basic3/data/raster/manifest.qml new file mode 100644 index 0000000..6d900f5 --- /dev/null +++ b/tests/auto/declarative/visual/ListView/basic3/data/raster/manifest.qml @@ -0,0 +1,6 @@ +TestLog { + TestFullFrame { + time: 0 + frameId: 0 + } +} diff --git a/tests/auto/declarative/visual/ListView/basic3/test b/tests/auto/declarative/visual/ListView/basic3/test new file mode 100644 index 0000000..9ec306b --- /dev/null +++ b/tests/auto/declarative/visual/ListView/basic3/test @@ -0,0 +1 @@ +basic3.qml diff --git a/tests/auto/declarative/visual/ListView/basic4/basic4.qml b/tests/auto/declarative/visual/ListView/basic4/basic4.qml new file mode 100644 index 0000000..9e5229a --- /dev/null +++ b/tests/auto/declarative/visual/ListView/basic4/basic4.qml @@ -0,0 +1,31 @@ +Rect { + color: "blue" + width: 200 + height: 300 + id: Page + ListModel { + id: Model + ListElement { + name: "January" + } + ListElement { + name: "February" + } + } + Component { + id: Delegate + Rect { + color: "red" + width: 100 + height: 100 + Text { + text: name + } + } + } + ListView { + anchors.fill: parent + model: Model + delegate: Delegate + } +} diff --git a/tests/auto/declarative/visual/ListView/basic4/data/raster/image0.png b/tests/auto/declarative/visual/ListView/basic4/data/raster/image0.png Binary files differnew file mode 100644 index 0000000..f8a4830 --- /dev/null +++ b/tests/auto/declarative/visual/ListView/basic4/data/raster/image0.png diff --git a/tests/auto/declarative/visual/ListView/basic4/data/raster/manifest.qml b/tests/auto/declarative/visual/ListView/basic4/data/raster/manifest.qml new file mode 100644 index 0000000..6d900f5 --- /dev/null +++ b/tests/auto/declarative/visual/ListView/basic4/data/raster/manifest.qml @@ -0,0 +1,6 @@ +TestLog { + TestFullFrame { + time: 0 + frameId: 0 + } +} diff --git a/tests/auto/declarative/visual/ListView/basic4/test b/tests/auto/declarative/visual/ListView/basic4/test new file mode 100644 index 0000000..2a7f227 --- /dev/null +++ b/tests/auto/declarative/visual/ListView/basic4/test @@ -0,0 +1 @@ +basic4.qml diff --git a/tests/auto/declarative/visual/bindinganimation/bindinganimation.qml b/tests/auto/declarative/visual/bindinganimation/bindinganimation.qml new file mode 100644 index 0000000..61cedc2 --- /dev/null +++ b/tests/auto/declarative/visual/bindinganimation/bindinganimation.qml @@ -0,0 +1,40 @@ +Rect { + color: "blue" + width: 320 + height: 240 + id: Page + Rect { + id: MyRect + width: 100 + height: 100 + color: "red" + x: 10 + } + states: [ + State { + name: "hello" + SetProperty { + target: MyRect + property: "x" + binding: 100 + } + SetProperty { + target: MyMouseRegion + property: "onClicked" + value: "Page.currentState = ''" + } + } + ] + transitions: [ + Transition { + NumericAnimation { + properties: "x" + } + } + ] + MouseRegion { + id: MyMouseRegion + anchors.fill: parent + onClicked: { Page.state= 'hello' } + } +} diff --git a/tests/auto/declarative/visual/bindinganimation/data/raster/image0.png b/tests/auto/declarative/visual/bindinganimation/data/raster/image0.png Binary files differnew file mode 100644 index 0000000..92f8cdd --- /dev/null +++ b/tests/auto/declarative/visual/bindinganimation/data/raster/image0.png diff --git a/tests/auto/declarative/visual/bindinganimation/data/raster/manifest.qml b/tests/auto/declarative/visual/bindinganimation/data/raster/manifest.qml new file mode 100644 index 0000000..1454949 --- /dev/null +++ b/tests/auto/declarative/visual/bindinganimation/data/raster/manifest.qml @@ -0,0 +1,86 @@ +TestLog { + TestFullFrame { + time: 0 + frameId: 0 + } + TestMouse { + time: 1296 + type: 2 + button: 1 + buttons: 1 + globalPos: '87,985' + pos: '83,29' + } + TestMouse { + time: 1360 + type: 3 + button: 1 + buttons: 0 + globalPos: '87,985' + pos: '83,29' + } + TestFrame { + time: 1376 + hash: '7CB5FC371040E587DE9F06CE14A4B29A' + } + TestFrame { + time: 1392 + hash: 'A5E5DBD179C7E48D34B8107F8CC6B5BE' + } + TestFrame { + time: 1408 + hash: 'A5E5DBD179C7E48D34B8107F8CC6B5BE' + } + TestFrame { + time: 1424 + hash: '69FB651AA84E07E4A6DEAA31CB10641B' + } + TestFrame { + time: 1440 + hash: '3FFC4C4BD282010A359DCEAF2D8496AC' + } + TestFrame { + time: 1456 + hash: '3FFC4C4BD282010A359DCEAF2D8496AC' + } + TestFrame { + time: 1472 + hash: 'ADA58B13247A654BBCECF3F254AB797F' + } + TestFrame { + time: 1488 + hash: 'B314799BC732B6BD8C42A622B720E3D5' + } + TestFrame { + time: 1504 + hash: 'B314799BC732B6BD8C42A622B720E3D5' + } + TestFrame { + time: 1520 + hash: '7377569C13CF5DE368B22209AB8AE395' + } + TestFrame { + time: 1536 + hash: '7C1E4A1F80C68EE57D052A9D7851F937' + } + TestFrame { + time: 1552 + hash: '7C1E4A1F80C68EE57D052A9D7851F937' + } + TestFrame { + time: 1568 + hash: '24D6DB9544205075836A86A54B55A820' + } + TestFrame { + time: 1584 + hash: '24D6DB9544205075836A86A54B55A820' + } + TestFrame { + time: 1600 + hash: '8A84E4C3E8AD4C6A9A7BD3E1620718C1' + } + TestFrame { + time: 1616 + hash: 'B8EA544A4EF3B7E0A9E0A7777B55EDC7' + } +} diff --git a/tests/auto/declarative/visual/bindinganimation/test b/tests/auto/declarative/visual/bindinganimation/test new file mode 100644 index 0000000..bb59333 --- /dev/null +++ b/tests/auto/declarative/visual/bindinganimation/test @@ -0,0 +1 @@ +bindinganimation.qml diff --git a/tests/auto/declarative/visual/colorAnimation/colorAnimation.qml b/tests/auto/declarative/visual/colorAnimation/colorAnimation.qml new file mode 100644 index 0000000..d351b8c --- /dev/null +++ b/tests/auto/declarative/visual/colorAnimation/colorAnimation.qml @@ -0,0 +1,41 @@ +Rect { + id: mainrect + width: 200; height: 200 + state: "first" + states: [ + State { + name: "first" + SetProperty { + target: mainrect + property: "color" + value: "red" + } + }, + State { + name: "second" + SetProperty { + target: mainrect + property: "color" + value: "blue" + } + } + ] + transitions: [ + Transition { + fromState: "first" + toState: "second" + reversible: true + SequentialAnimation { + ColorAnimation { + duration: 2000 + target: mainrect + property: "color" + } + } + } + ] + MouseRegion { + anchors.fill: parent + onClicked: { mainrect.state = 'second' } + } +} diff --git a/tests/auto/declarative/visual/colorAnimation/data/raster/image0.png b/tests/auto/declarative/visual/colorAnimation/data/raster/image0.png Binary files differnew file mode 100644 index 0000000..f00a2e2 --- /dev/null +++ b/tests/auto/declarative/visual/colorAnimation/data/raster/image0.png diff --git a/tests/auto/declarative/visual/colorAnimation/data/raster/manifest.qml b/tests/auto/declarative/visual/colorAnimation/data/raster/manifest.qml new file mode 100644 index 0000000..0eb8b12 --- /dev/null +++ b/tests/auto/declarative/visual/colorAnimation/data/raster/manifest.qml @@ -0,0 +1,522 @@ +TestLog { + TestFullFrame { + time: 0 + frameId: 0 + } + TestMouse { + time: 944 + type: 2 + button: 1 + buttons: 1 + globalPos: '1789,188' + pos: '73,76' + } + TestMouse { + time: 992 + type: 3 + button: 1 + buttons: 0 + globalPos: '1789,188' + pos: '73,76' + } + TestFrame { + time: 1008 + hash: 'E5BDA0DAF98288CE18DB6CE06EDA3BA0' + } + TestFrame { + time: 1024 + hash: 'D35008F75B8C992F80FB16BA7203649D' + } + TestFrame { + time: 1040 + hash: '14F43E0784DDF42EA8550DB88C501BF1' + } + TestFrame { + time: 1056 + hash: '02276E158B5391480B1BDEAADF1FB903' + } + TestFrame { + time: 1072 + hash: '35D9513EB97A2C482B7CD197DE910934' + } + TestFrame { + time: 1088 + hash: 'FAF0FD681E60BB2489099F5DF772B6CD' + } + TestFrame { + time: 1104 + hash: 'A863D3E346F94785A3A392FDC91526EB' + } + TestFrame { + time: 1120 + hash: 'FDF328D3F6EB8410DA59A91345E41A44' + } + TestFrame { + time: 1136 + hash: '83514A3B10D5BE8F6C3B128D0F3E0B1C' + } + TestFrame { + time: 1152 + hash: 'EAD0EAE76CD00189075964671EFFBAEA' + } + TestFrame { + time: 1168 + hash: '24D2457FCD51490FDA23071BF9929D12' + } + TestFrame { + time: 1184 + hash: '1478683446CF543DACBE31D0B76A98A6' + } + TestFrame { + time: 1200 + hash: '99F7DA1F31FE920F6C02ADD4042AE925' + } + TestFrame { + time: 1216 + hash: '22DEF892006CF66667770B0F17BAF6C0' + } + TestFrame { + time: 1232 + hash: '6A36D5A77099BFD58BAF285478FF04E4' + } + TestFrame { + time: 1248 + hash: '6258150666B59B20AB476724C07FC20C' + } + TestFrame { + time: 1264 + hash: 'F1636315BC950A6DD400D9C7ED263B88' + } + TestFrame { + time: 1280 + hash: '18447EA8DC2E8DA956788E5B3CF3790A' + } + TestFrame { + time: 1296 + hash: '1D2A6E65997A73E9E670356C8E8B63B2' + } + TestFrame { + time: 1312 + hash: 'BED0242C0F9EF229D1392835286D5782' + } + TestFrame { + time: 1328 + hash: '88923C190E9E5BEADEF8A409C06DF9D6' + } + TestFrame { + time: 1344 + hash: '2D133E7EE60C97386F57838B3F0976C7' + } + TestFrame { + time: 1360 + hash: '85B1821CC50F2A9F3ED6944F792B7A2F' + } + TestFrame { + time: 1376 + hash: '395195716D76BC0BE7B2033ED37A7A1C' + } + TestFrame { + time: 1392 + hash: '243DBFFCF416926242BBCB7348974C4C' + } + TestFrame { + time: 1408 + hash: 'A755068679616D8AC65C2AA7431F2A19' + } + TestFrame { + time: 1424 + hash: 'E8249B35A47EB492CBDF2D91CC8426F0' + } + TestFrame { + time: 1440 + hash: '15F3DA1C0E6F0779B96859D51171DD27' + } + TestFrame { + time: 1456 + hash: '258C0C756AAC3DE743B43051F2AACE6B' + } + TestFrame { + time: 1472 + hash: 'A58B9FDF301D72B2CC5C93934CC8927B' + } + TestFrame { + time: 1488 + hash: 'A9181D30870D472521F8904818CE520F' + } + TestFrame { + time: 1504 + hash: '7F9E94069CCF3897C26A71BD7BECD903' + } + TestFrame { + time: 1520 + hash: 'BDF305C2F46CDB86DBF57B1E0CC5A65B' + } + TestFrame { + time: 1536 + hash: 'FE5B6865D7E4FC7D1D42C1E74F8666F7' + } + TestFrame { + time: 1552 + hash: '734F0DE45A6E34C9EAB7EF606196F96A' + } + TestFrame { + time: 1568 + hash: '02A361C4534FDF7F286DC3E6DC23275C' + } + TestFrame { + time: 1584 + hash: 'E649155AD69999C14B92F6561E4D1185' + } + TestFrame { + time: 1600 + hash: '01AF177084FAB755D622973F64B92018' + } + TestFrame { + time: 1616 + hash: '097CC4A082DFAB995D213A3A73883C97' + } + TestFrame { + time: 1632 + hash: 'D7B4239A3280B1EB8E885E3F422DF8E9' + } + TestFrame { + time: 1648 + hash: '59893977994E34E83F91E7CE3AD65D6D' + } + TestFrame { + time: 1664 + hash: 'B68E3FBB5CDCD6BD96DF7DEC558DB42B' + } + TestFrame { + time: 1680 + hash: '94AD0580648F36A1E18A9EA7E249B04D' + } + TestFrame { + time: 1696 + hash: '750A4C01D2F5806A89A1C6CC6A9B9A68' + } + TestFrame { + time: 1712 + hash: '4F109F50F388F1BFA4BC6B03B3E6E514' + } + TestFrame { + time: 1728 + hash: 'C6168D5CF27A533E8EE636637667BE47' + } + TestFrame { + time: 1744 + hash: 'F8120547BED987AA34C00DA5A01A4D1E' + } + TestFrame { + time: 1760 + hash: 'CBFF526136FA2C128C8B898FBBEF9E5C' + } + TestFrame { + time: 1776 + hash: 'F29E52398FAB1A239A63DF4C32F2FC69' + } + TestFrame { + time: 1792 + hash: '7178BFE86FD2FD513218B33760460F8D' + } + TestFrame { + time: 1808 + hash: 'CA83285BC8AC633403896FE976896EB0' + } + TestFrame { + time: 1824 + hash: '96BA486C09CC69D5AA38C46C00DF1181' + } + TestFrame { + time: 1840 + hash: 'B88EAB335842787869F4A14824C19DD8' + } + TestFrame { + time: 1856 + hash: '065AA59012729E1E1A246A2083142690' + } + TestFrame { + time: 1872 + hash: 'DD0E98C8398861002C5F178C5F9F612D' + } + TestFrame { + time: 1888 + hash: '04192C2B545948048ECCF4D81BBDE198' + } + TestFrame { + time: 1904 + hash: 'BB7502C7208281EF9FD41714AB88A1A8' + } + TestFrame { + time: 1920 + hash: '5397195471890D08B703DCA101E5BC7C' + } + TestFrame { + time: 1936 + hash: '4C678CDBEBB2FFD2CBF012CA77800CDE' + } + TestFrame { + time: 1952 + hash: '0D7A34ECD0C7F52B2C015037BF1902C6' + } + TestFrame { + time: 1968 + hash: 'FD9D5048BE749AC4369FDA2D018B43AE' + } + TestFrame { + time: 1984 + hash: '93EE03795CD57AE6F7FE3A020B039AD4' + } + TestFrame { + time: 2000 + hash: '5E1118963F219C39761CA7FBF564A9CA' + } + TestFrame { + time: 2016 + hash: '8F40038741903150136170503649D941' + } + TestFrame { + time: 2032 + hash: 'B087B7D0AA6224821F8E18718FF5E77D' + } + TestFrame { + time: 2048 + hash: 'AA46B04A3C67DC772265ED2901955565' + } + TestFrame { + time: 2064 + hash: 'AC024BF2AEB4BECDF31A09FE0A6DB8F3' + } + TestFrame { + time: 2080 + hash: '13745A174E4D06E2108A5BF125BA50CC' + } + TestFrame { + time: 2096 + hash: 'BD972F0D8E230ECA0B3FEA1B8C960C08' + } + TestFrame { + time: 2112 + hash: 'CBDBEC802A58E7CED0CF45B3AB0BC0BA' + } + TestFrame { + time: 2128 + hash: '5128584C50305C7D218B81B8367FA3D5' + } + TestFrame { + time: 2144 + hash: 'A71461D3593F3685620668916DE870BD' + } + TestFrame { + time: 2160 + hash: '74EBAC8F32CF044B58D9883DBCD9A722' + } + TestFrame { + time: 2176 + hash: 'FEDC5B638F339B90FE59B478721E65B7' + } + TestFrame { + time: 2192 + hash: 'BCB8C7159F54C353551DD3BFF3203966' + } + TestFrame { + time: 2208 + hash: '4E9B083075BC5E9287A8ABC982778B56' + } + TestFrame { + time: 2224 + hash: '1D6F02AA99AFA47D77FC49AB894B365A' + } + TestFrame { + time: 2240 + hash: 'A204FEEC783B3B05DE4C209C21745826' + } + TestFrame { + time: 2256 + hash: '665A2A8FF00B9663157802767F504754' + } + TestFrame { + time: 2272 + hash: '624FB09EBE60CB87D767FAF8D2420B1E' + } + TestFrame { + time: 2288 + hash: 'E5AF0CDC33F3275A25ABB09E9165F310' + } + TestFrame { + time: 2304 + hash: '02BAFB5A81CA66F7670AC93DE5123860' + } + TestFrame { + time: 2320 + hash: 'E7AA6374C73832E57CEB2427A1E258AA' + } + TestFrame { + time: 2336 + hash: 'B5ABD0DFF1AB076FAAC7CC226E83F5D0' + } + TestFrame { + time: 2352 + hash: 'B759ACC35BCCFF8EFC2E6FE276DDC0F7' + } + TestFrame { + time: 2368 + hash: 'CE52E18C1F7732768779863B45314FF5' + } + TestFrame { + time: 2384 + hash: '99D30652559DD6931E0C95543EEAA149' + } + TestFrame { + time: 2400 + hash: 'FFBD9A00E05E085B89296D19D5CAEC57' + } + TestFrame { + time: 2416 + hash: '9C9D658B9C25602816B8066BF19105DB' + } + TestFrame { + time: 2432 + hash: '2B7FD058E6601E22A30BB7106B1C683B' + } + TestFrame { + time: 2448 + hash: 'F4C7E26B19EE0A3E7C9688685EB7BD05' + } + TestFrame { + time: 2464 + hash: '0DC6D593BCEFF56B7F81F2A49D37FEFB' + } + TestFrame { + time: 2480 + hash: '9BFD7AD5091CCBDDE43C593E133A7B10' + } + TestFrame { + time: 2496 + hash: '2703B617937914A90EA42EBF249D79EE' + } + TestFrame { + time: 2512 + hash: 'B77E2983138254016C4CCA53100F46FA' + } + TestFrame { + time: 2528 + hash: '60C4DD24187D1281081479E586F02B37' + } + TestFrame { + time: 2544 + hash: '62F2511ABD99EF1231C9FA4B91D4ABFE' + } + TestFrame { + time: 2560 + hash: 'E309B3353FD174E883D309571CADDC98' + } + TestFrame { + time: 2576 + hash: '1E2D6A134C7B12DDE551B148EF4F088C' + } + TestFrame { + time: 2592 + hash: 'E5DC5450604A491CC24A0DCF5C278B58' + } + TestFrame { + time: 2608 + hash: 'C8DAE97C10E1962C1E6A51AB3AB8579E' + } + TestFrame { + time: 2624 + hash: '4E1B7E06F55FB084080689B474F1FE1D' + } + TestFrame { + time: 2640 + hash: 'B4639C907FA937BF15FAC62421170CD8' + } + TestFrame { + time: 2656 + hash: 'C250208A0CAEB5F6CB4D3AAC3D7D350B' + } + TestFrame { + time: 2672 + hash: 'A73351EABECF0D71149EFE31F197413E' + } + TestFrame { + time: 2688 + hash: '479425F1B7AFF79E4DFB7FCA534AF018' + } + TestFrame { + time: 2704 + hash: '046D0F0040A52D1F26BA9F7C5DE06EF4' + } + TestFrame { + time: 2720 + hash: '655778BF13C6080903150B0EB43A7EDC' + } + TestFrame { + time: 2736 + hash: '72DA0BBE81514870655FDD3354ADAC60' + } + TestFrame { + time: 2752 + hash: 'DEFE0BDF675C65FFF55AAACED1E4DAE7' + } + TestFrame { + time: 2768 + hash: 'C988628B6C3D3780E9A865C7694926CD' + } + TestFrame { + time: 2784 + hash: '5AB17563655231089EDD986FF13D6012' + } + TestFrame { + time: 2800 + hash: 'C1ADFF1D2E5800ED466D1691D3B17382' + } + TestFrame { + time: 2816 + hash: '70129BA01FBB19592B9DC0D0A3B3E7DF' + } + TestFrame { + time: 2832 + hash: '0000829EF7ED908BF430D42904D59CC2' + } + TestFrame { + time: 2848 + hash: '843D2927F50AB87B4A86B7A6AAEED91F' + } + TestFrame { + time: 2864 + hash: 'DA86D21756025E7DE8050586D5E2A1F8' + } + TestFrame { + time: 2880 + hash: '48DD1BD6580133B0793FEE327EA4F1E6' + } + TestFrame { + time: 2896 + hash: 'F0618193DCD0BA2837249515A1898B1C' + } + TestFrame { + time: 2912 + hash: 'A530184E57251065286C0CBBA7301E9C' + } + TestFrame { + time: 2928 + hash: '64A1D7203973D65DD342793007A61C58' + } + TestFrame { + time: 2944 + hash: '5B830DFC6BA442772DE87D75D5A578DE' + } + TestFrame { + time: 2960 + hash: '5563B056B0409B65F60DD16DD0DD890E' + } + TestFrame { + time: 2976 + hash: 'B8BCF9AD2CA8720C11563A23D8280804' + } + TestFrame { + time: 2992 + hash: '8C0FCDA4F8956394C53FC4BA18CAA850' + } +} diff --git a/tests/auto/declarative/visual/colorAnimation/data/raster/manifest.xml b/tests/auto/declarative/visual/colorAnimation/data/raster/manifest.xml new file mode 100644 index 0000000..1fe2f15 --- /dev/null +++ b/tests/auto/declarative/visual/colorAnimation/data/raster/manifest.xml @@ -0,0 +1,522 @@ +TestLog { + TestFullFrame { + time: 0 + frameId: 0 + } + TestFrame { + time: 16 + hash: 'E5BDA0DAF98288CE18DB6CE06EDA3BA0' + } + TestFrame { + time: 32 + hash: 'D35008F75B8C992F80FB16BA7203649D' + } + TestFrame { + time: 48 + hash: '14F43E0784DDF42EA8550DB88C501BF1' + } + TestFrame { + time: 64 + hash: '02276E158B5391480B1BDEAADF1FB903' + } + TestFrame { + time: 80 + hash: '35D9513EB97A2C482B7CD197DE910934' + } + TestFrame { + time: 96 + hash: 'FAF0FD681E60BB2489099F5DF772B6CD' + } + TestFrame { + time: 112 + hash: 'A863D3E346F94785A3A392FDC91526EB' + } + TestFrame { + time: 128 + hash: 'FDF328D3F6EB8410DA59A91345E41A44' + } + TestFrame { + time: 144 + hash: '83514A3B10D5BE8F6C3B128D0F3E0B1C' + } + TestFrame { + time: 160 + hash: 'EAD0EAE76CD00189075964671EFFBAEA' + } + TestFrame { + time: 176 + hash: '24D2457FCD51490FDA23071BF9929D12' + } + TestFrame { + time: 192 + hash: '1478683446CF543DACBE31D0B76A98A6' + } + TestFrame { + time: 208 + hash: '99F7DA1F31FE920F6C02ADD4042AE925' + } + TestFrame { + time: 224 + hash: '22DEF892006CF66667770B0F17BAF6C0' + } + TestFrame { + time: 240 + hash: '6A36D5A77099BFD58BAF285478FF04E4' + } + TestFrame { + time: 256 + hash: '6258150666B59B20AB476724C07FC20C' + } + TestFrame { + time: 272 + hash: 'F1636315BC950A6DD400D9C7ED263B88' + } + TestFrame { + time: 288 + hash: '18447EA8DC2E8DA956788E5B3CF3790A' + } + TestFrame { + time: 304 + hash: '1D2A6E65997A73E9E670356C8E8B63B2' + } + TestFrame { + time: 320 + hash: 'BED0242C0F9EF229D1392835286D5782' + } + TestFrame { + time: 336 + hash: '88923C190E9E5BEADEF8A409C06DF9D6' + } + TestFrame { + time: 352 + hash: '2D133E7EE60C97386F57838B3F0976C7' + } + TestFrame { + time: 368 + hash: '85B1821CC50F2A9F3ED6944F792B7A2F' + } + TestFrame { + time: 384 + hash: '395195716D76BC0BE7B2033ED37A7A1C' + } + TestFrame { + time: 400 + hash: '243DBFFCF416926242BBCB7348974C4C' + } + TestFrame { + time: 416 + hash: 'A755068679616D8AC65C2AA7431F2A19' + } + TestFrame { + time: 432 + hash: 'E8249B35A47EB492CBDF2D91CC8426F0' + } + TestFrame { + time: 448 + hash: '15F3DA1C0E6F0779B96859D51171DD27' + } + TestFrame { + time: 464 + hash: '258C0C756AAC3DE743B43051F2AACE6B' + } + TestFrame { + time: 480 + hash: 'A58B9FDF301D72B2CC5C93934CC8927B' + } + TestFrame { + time: 496 + hash: 'A9181D30870D472521F8904818CE520F' + } + TestFrame { + time: 512 + hash: '7F9E94069CCF3897C26A71BD7BECD903' + } + TestFrame { + time: 528 + hash: 'BDF305C2F46CDB86DBF57B1E0CC5A65B' + } + TestFrame { + time: 544 + hash: 'FE5B6865D7E4FC7D1D42C1E74F8666F7' + } + TestFrame { + time: 560 + hash: '734F0DE45A6E34C9EAB7EF606196F96A' + } + TestFrame { + time: 576 + hash: '02A361C4534FDF7F286DC3E6DC23275C' + } + TestFrame { + time: 592 + hash: 'E649155AD69999C14B92F6561E4D1185' + } + TestFrame { + time: 608 + hash: '01AF177084FAB755D622973F64B92018' + } + TestFrame { + time: 624 + hash: '097CC4A082DFAB995D213A3A73883C97' + } + TestFrame { + time: 640 + hash: 'D7B4239A3280B1EB8E885E3F422DF8E9' + } + TestFrame { + time: 656 + hash: '59893977994E34E83F91E7CE3AD65D6D' + } + TestFrame { + time: 672 + hash: 'B68E3FBB5CDCD6BD96DF7DEC558DB42B' + } + TestFrame { + time: 688 + hash: '94AD0580648F36A1E18A9EA7E249B04D' + } + TestFrame { + time: 704 + hash: '750A4C01D2F5806A89A1C6CC6A9B9A68' + } + TestFrame { + time: 720 + hash: '4F109F50F388F1BFA4BC6B03B3E6E514' + } + TestFrame { + time: 736 + hash: 'C6168D5CF27A533E8EE636637667BE47' + } + TestFrame { + time: 752 + hash: 'F8120547BED987AA34C00DA5A01A4D1E' + } + TestFrame { + time: 768 + hash: 'CBFF526136FA2C128C8B898FBBEF9E5C' + } + TestFrame { + time: 784 + hash: 'F29E52398FAB1A239A63DF4C32F2FC69' + } + TestFrame { + time: 800 + hash: '7178BFE86FD2FD513218B33760460F8D' + } + TestFrame { + time: 816 + hash: 'CA83285BC8AC633403896FE976896EB0' + } + TestFrame { + time: 832 + hash: '96BA486C09CC69D5AA38C46C00DF1181' + } + TestFrame { + time: 848 + hash: 'B88EAB335842787869F4A14824C19DD8' + } + TestFrame { + time: 864 + hash: '065AA59012729E1E1A246A2083142690' + } + TestFrame { + time: 880 + hash: 'DD0E98C8398861002C5F178C5F9F612D' + } + TestFrame { + time: 896 + hash: '04192C2B545948048ECCF4D81BBDE198' + } + TestMouse { + time: 912 + type: 2 + button: 1 + buttons: 1 + globalPos: '1739,207' + pos: '75,95' + } + TestFrame { + time: 912 + hash: 'BB7502C7208281EF9FD41714AB88A1A8' + } + TestFrame { + time: 928 + hash: '5397195471890D08B703DCA101E5BC7C' + } + TestFrame { + time: 944 + hash: '4C678CDBEBB2FFD2CBF012CA77800CDE' + } + TestFrame { + time: 960 + hash: '0D7A34ECD0C7F52B2C015037BF1902C6' + } + TestMouse { + time: 976 + type: 3 + button: 1 + buttons: 0 + globalPos: '1739,207' + pos: '75,95' + } + TestFrame { + time: 976 + hash: 'FD9D5048BE749AC4369FDA2D018B43AE' + } + TestFrame { + time: 992 + hash: '93EE03795CD57AE6F7FE3A020B039AD4' + } + TestFrame { + time: 1008 + hash: '5E1118963F219C39761CA7FBF564A9CA' + } + TestFrame { + time: 1024 + hash: '8F40038741903150136170503649D941' + } + TestFrame { + time: 1040 + hash: 'B087B7D0AA6224821F8E18718FF5E77D' + } + TestFrame { + time: 1056 + hash: 'AA46B04A3C67DC772265ED2901955565' + } + TestFrame { + time: 1072 + hash: 'AC024BF2AEB4BECDF31A09FE0A6DB8F3' + } + TestFrame { + time: 1088 + hash: '13745A174E4D06E2108A5BF125BA50CC' + } + TestFrame { + time: 1104 + hash: 'BD972F0D8E230ECA0B3FEA1B8C960C08' + } + TestFrame { + time: 1120 + hash: 'CBDBEC802A58E7CED0CF45B3AB0BC0BA' + } + TestFrame { + time: 1136 + hash: '5128584C50305C7D218B81B8367FA3D5' + } + TestFrame { + time: 1152 + hash: 'A71461D3593F3685620668916DE870BD' + } + TestFrame { + time: 1168 + hash: '74EBAC8F32CF044B58D9883DBCD9A722' + } + TestFrame { + time: 1184 + hash: 'FEDC5B638F339B90FE59B478721E65B7' + } + TestFrame { + time: 1200 + hash: 'BCB8C7159F54C353551DD3BFF3203966' + } + TestFrame { + time: 1216 + hash: '4E9B083075BC5E9287A8ABC982778B56' + } + TestFrame { + time: 1232 + hash: '1D6F02AA99AFA47D77FC49AB894B365A' + } + TestFrame { + time: 1248 + hash: 'A204FEEC783B3B05DE4C209C21745826' + } + TestFrame { + time: 1264 + hash: '665A2A8FF00B9663157802767F504754' + } + TestFrame { + time: 1280 + hash: '624FB09EBE60CB87D767FAF8D2420B1E' + } + TestFrame { + time: 1296 + hash: 'E5AF0CDC33F3275A25ABB09E9165F310' + } + TestFrame { + time: 1312 + hash: '02BAFB5A81CA66F7670AC93DE5123860' + } + TestFrame { + time: 1328 + hash: 'E7AA6374C73832E57CEB2427A1E258AA' + } + TestFrame { + time: 1344 + hash: 'B5ABD0DFF1AB076FAAC7CC226E83F5D0' + } + TestFrame { + time: 1360 + hash: 'B759ACC35BCCFF8EFC2E6FE276DDC0F7' + } + TestFrame { + time: 1376 + hash: 'CE52E18C1F7732768779863B45314FF5' + } + TestFrame { + time: 1392 + hash: '99D30652559DD6931E0C95543EEAA149' + } + TestFrame { + time: 1408 + hash: 'FFBD9A00E05E085B89296D19D5CAEC57' + } + TestFrame { + time: 1424 + hash: '9C9D658B9C25602816B8066BF19105DB' + } + TestFrame { + time: 1440 + hash: '2B7FD058E6601E22A30BB7106B1C683B' + } + TestFrame { + time: 1456 + hash: 'F4C7E26B19EE0A3E7C9688685EB7BD05' + } + TestFrame { + time: 1472 + hash: '0DC6D593BCEFF56B7F81F2A49D37FEFB' + } + TestFrame { + time: 1488 + hash: '9BFD7AD5091CCBDDE43C593E133A7B10' + } + TestFrame { + time: 1504 + hash: '2703B617937914A90EA42EBF249D79EE' + } + TestFrame { + time: 1520 + hash: 'B77E2983138254016C4CCA53100F46FA' + } + TestFrame { + time: 1536 + hash: '60C4DD24187D1281081479E586F02B37' + } + TestFrame { + time: 1552 + hash: '62F2511ABD99EF1231C9FA4B91D4ABFE' + } + TestFrame { + time: 1568 + hash: 'E309B3353FD174E883D309571CADDC98' + } + TestFrame { + time: 1584 + hash: '1E2D6A134C7B12DDE551B148EF4F088C' + } + TestFrame { + time: 1600 + hash: 'E5DC5450604A491CC24A0DCF5C278B58' + } + TestFrame { + time: 1616 + hash: 'C8DAE97C10E1962C1E6A51AB3AB8579E' + } + TestFrame { + time: 1632 + hash: '4E1B7E06F55FB084080689B474F1FE1D' + } + TestFrame { + time: 1648 + hash: 'B4639C907FA937BF15FAC62421170CD8' + } + TestFrame { + time: 1664 + hash: 'C250208A0CAEB5F6CB4D3AAC3D7D350B' + } + TestFrame { + time: 1680 + hash: 'A73351EABECF0D71149EFE31F197413E' + } + TestFrame { + time: 1696 + hash: '479425F1B7AFF79E4DFB7FCA534AF018' + } + TestFrame { + time: 1712 + hash: '046D0F0040A52D1F26BA9F7C5DE06EF4' + } + TestFrame { + time: 1728 + hash: '655778BF13C6080903150B0EB43A7EDC' + } + TestFrame { + time: 1744 + hash: '72DA0BBE81514870655FDD3354ADAC60' + } + TestFrame { + time: 1760 + hash: 'DEFE0BDF675C65FFF55AAACED1E4DAE7' + } + TestFrame { + time: 1776 + hash: 'C988628B6C3D3780E9A865C7694926CD' + } + TestFrame { + time: 1792 + hash: '5AB17563655231089EDD986FF13D6012' + } + TestFrame { + time: 1808 + hash: 'C1ADFF1D2E5800ED466D1691D3B17382' + } + TestFrame { + time: 1824 + hash: '70129BA01FBB19592B9DC0D0A3B3E7DF' + } + TestFrame { + time: 1840 + hash: '0000829EF7ED908BF430D42904D59CC2' + } + TestFrame { + time: 1856 + hash: '843D2927F50AB87B4A86B7A6AAEED91F' + } + TestFrame { + time: 1872 + hash: 'DA86D21756025E7DE8050586D5E2A1F8' + } + TestFrame { + time: 1888 + hash: '48DD1BD6580133B0793FEE327EA4F1E6' + } + TestFrame { + time: 1904 + hash: 'F0618193DCD0BA2837249515A1898B1C' + } + TestFrame { + time: 1920 + hash: 'A530184E57251065286C0CBBA7301E9C' + } + TestFrame { + time: 1936 + hash: '64A1D7203973D65DD342793007A61C58' + } + TestFrame { + time: 1952 + hash: '5B830DFC6BA442772DE87D75D5A578DE' + } + TestFrame { + time: 1968 + hash: '5563B056B0409B65F60DD16DD0DD890E' + } + TestFrame { + time: 1984 + hash: 'B8BCF9AD2CA8720C11563A23D8280804' + } + TestFrame { + time: 2000 + hash: '8C0FCDA4F8956394C53FC4BA18CAA850' + } +} diff --git a/tests/auto/declarative/visual/colorAnimation/manifest-play.xml b/tests/auto/declarative/visual/colorAnimation/manifest-play.xml new file mode 100644 index 0000000..8e3de2e --- /dev/null +++ b/tests/auto/declarative/visual/colorAnimation/manifest-play.xml @@ -0,0 +1,73 @@ +<?xml version="1.0" encoding="UTF-8"?> +<TestLog> + <TestFullFrame time="30" frameId="0"/> + <TestMouse time="480" type="2" button="1" buttons="1" globalPos="93,129" pos="89,102"/> + <TestMouse time="570" type="3" button="1" buttons="0" globalPos="93,129" pos="89,102"/> + <TestFrame time="630" hash="D42762ECD293C6922C5F9593126DE636"/> + <TestFrame time="660" hash="8962505FCCB2E7559A99A8EDD325A82B"/> + <TestFrame time="690" hash="6812EFDA80607D4FA05CD3A5077F8EF7"/> + <TestFrame time="720" hash="A116DF73809679C1C5F9261F49B989F0"/> + <TestFrame time="750" hash="DC1B9D40AEE306171AD6625DDCA4EB45"/> + <TestFrame time="780" hash="B2DAF0E4C32080229664A8B0A155DE3B"/> + <TestFrame time="810" hash="496677B0D8707B91566D1244C46D50DB"/> + <TestFrame time="840" hash="A6558D8B0D1FB1D11BEBE36C078386CE"/> + <TestFrame time="870" hash="601436BB436D391B0BD5FCC289666208"/> + <TestFrame time="900" hash="8CF3CF9EAD875497870CC7C1035802DC"/> + <TestFrame time="930" hash="FF6BA6BAC30DADD3DBBFD96F127EB1FE"/> + <TestFrame time="960" hash="1D97A2A6890078DCF4CE9E508E5F9F08"/> + <TestFrame time="990" hash="58C9116FDDD03DD036820EFCD0DCD392"/> + <TestFrame time="1020" hash="E51287B911C140B41D350FCB2091AB80"/> + <TestFrame time="1050" hash="7B107411B436FABE469A069E6E5B0C3C"/> + <TestFrame time="1080" hash="9D1CB0E58F2BD00DDA0FB463F6BFF526"/> + <TestFrame time="1110" hash="35AB7788489B79E5A5C6F2BE11AFC9E1"/> + <TestFrame time="1140" hash="C82177AC4A7A497469292C5F0F8C4913"/> + <TestFrame time="1170" hash="18763D1B911FDC524DB9E7B2569FE984"/> + <TestFrame time="1200" hash="27F63572AAEF6D835272D5D65FCF608B"/> + <TestFrame time="1230" hash="585727CAEC1F83ADB9E422BAF058A622"/> + <TestFrame time="1260" hash="2C3BBFEFBE6E5FDA1905E9F50985E1B4"/> + <TestFrame time="1290" hash="81675C4ABB2696D960BC5F204F05F16B"/> + <TestFrame time="1320" hash="6D0F3CCC06EF1E3A895ECC9A8DE90039"/> + <TestFrame time="1350" hash="0BF36093CCAEA8BDAE96D4939A8DDE20"/> + <TestFrame time="1380" hash="5A1CBC68AB59977B65492B0F8A664418"/> + <TestFrame time="1410" hash="C35831A8C59D56193CED2C4AADB4DFCE"/> + <TestFrame time="1440" hash="ED15973425A8B8528896B344A61393AA"/> + <TestFrame time="1470" hash="EA8FC02A8606680C089F0C0CE454ABE3"/> + <TestFrame time="1500" hash="CFB5CFBA0A0BC62C0D03908FB9599A8E"/> + <TestFrame time="1530" hash="09FAA04AFB50B48BD6A83F9E25F9DDDB"/> + <TestFrame time="1560" hash="0FDD0B8CDCCEB78C7C67AB0F5EA74D6A"/> + <TestFrame time="1590" hash="058D26146879900B5E5CCE05AE38BA0E"/> + <TestFrame time="1620" hash="80F9074C50F967C99D4C3A3FF9EC3E71"/> + <TestFrame time="1650" hash="AD9BDCEEC1C058D6B658C5BA0D0BC1F0"/> + <TestFrame time="1680" hash="AC14DF5458F91001181154F8C68BCE2B"/> + <TestFrame time="1710" hash="AE9225263E4C8E75E4D0F1D7192B4260"/> + <TestFrame time="1740" hash="D3D50F1B7F476E79E5B99E0E6D4CF827"/> + <TestFrame time="1770" hash="A1367445C5232ACCBF4904A415416EA4"/> + <TestFrame time="1800" hash="A21C0F1DA9B64A5B000558BA1F2E495D"/> + <TestFrame time="1830" hash="61AF477B6FB22E38E698375EA5793D22"/> + <TestFrame time="1860" hash="B3AD3501D527939CEAA4F124AB10B2DF"/> + <TestFrame time="1890" hash="0C2BF65A43AE87AFB0068F9FA4A74707"/> + <TestFrame time="1920" hash="5B7F96C797BEE4FD1B04538DE5549C1B"/> + <TestFrame time="1950" hash="4C861E936A3F1AFE323395E30174F8CC"/> + <TestFrame time="1980" hash="87F1966E5B0E924EB7CEED5520D120BF"/> + <TestFrame time="2010" hash="1980755E0D80469D4DC0B9B0309F2DEB"/> + <TestFrame time="2040" hash="38A7ACC2E5607FC0965B7B376A0D3524"/> + <TestFrame time="2070" hash="4434746833EFF5A3A76491024763990A"/> + <TestFrame time="2100" hash="A8BAD928F92E851B45723068B7FEF739"/> + <TestFrame time="2130" hash="A96F5C522C0ECA5C78E982E4235218CB"/> + <TestFrame time="2160" hash="135F0EFEDE2832B76F49966EBD629879"/> + <TestFrame time="2190" hash="A51C6E443413F184CAAE8A7F98A369C8"/> + <TestFrame time="2220" hash="62A7521EE62E6A2543B3141C1EFCE72A"/> + <TestFrame time="2250" hash="D416A41125659167B3E6AD68F66F6E64"/> + <TestFrame time="2280" hash="0F653B5E965665A43F50437724DC704C"/> + <TestFrame time="2310" hash="13A6E2485179501FF3AA8BA91A5050B4"/> + <TestFrame time="2340" hash="9423475D3832FBABEC56B80FA9161020"/> + <TestFrame time="2370" hash="497B21108A6CB127DB066B32D06D992A"/> + <TestFrame time="2400" hash="22F01CB9B4F8FF01410566A61E281373"/> + <TestFrame time="2430" hash="A099640BC088E14E20585CB87FC5C6F1"/> + <TestFrame time="2460" hash="AC2954553C333EA1D524CE51CD35958A"/> + <TestFrame time="2490" hash="771E882CC788BECAA82E71E6FBAB150D"/> + <TestFrame time="2520" hash="42CEDA45D88A8D2B3DA5B749F4C3C1BF"/> + <TestFrame time="2550" hash="C6E1F91B917E47246E012D1B203E0DC2"/> + <TestFrame time="2580" hash="EFB3E57CF265B6E36AA4DF72771D119C"/> + <TestFrame time="2610" hash="657FC7FD496E5A2FC84F63930E0D1DE3"/> +</TestLog> diff --git a/tests/auto/declarative/visual/easing/easing.qml b/tests/auto/declarative/visual/easing/easing.qml new file mode 100644 index 0000000..4a0ed14 --- /dev/null +++ b/tests/auto/declarative/visual/easing/easing.qml @@ -0,0 +1,186 @@ +Rect { + id: item + width: 600 + height: layout.height + color: "white" + resources: [ + ListModel { + id: easingtypes + ListElement { + type: "easeNone" + } + ListElement { + type: "easeInQuad" + } + ListElement { + type: "easeOutQuad" + } + ListElement { + type: "easeInOutQuad" + } + ListElement { + type: "easeOutInQuad" + } + ListElement { + type: "easeInCubic" + } + ListElement { + type: "easeOutCubic" + } + ListElement { + type: "easeInOutCubic" + } + ListElement { + type: "easeOutInCubic" + } + ListElement { + type: "easeInQuart" + } + ListElement { + type: "easeOutQuart" + } + ListElement { + type: "easeInOutQuart" + } + ListElement { + type: "easeOutInQuart" + } + ListElement { + type: "easeInQuint" + } + ListElement { + type: "easeOutQuint" + } + ListElement { + type: "easeInOutQuint" + } + ListElement { + type: "easeOutInQuint" + } + ListElement { + type: "easeInSine" + } + ListElement { + type: "easeOutSine" + } + ListElement { + type: "easeInOutSine" + } + ListElement { + type: "easeOutInSine" + } + ListElement { + type: "easeInExpo" + } + ListElement { + type: "easeOutExpo" + } + ListElement { + type: "easeInOutExpo" + } + ListElement { + type: "easeOutInExpo" + } + ListElement { + type: "easeInCirc" + } + ListElement { + type: "easeOutCirc" + } + ListElement { + type: "easeInOutCirc" + } + ListElement { + type: "easeOutInCirc" + } + ListElement { + type: "easeInElastic" + } + ListElement { + type: "easeOutElastic" + } + ListElement { + type: "easeInOutElastic" + } + ListElement { + type: "easeOutInElastic" + } + ListElement { + type: "easeInBack" + } + ListElement { + type: "easeOutBack" + } + ListElement { + type: "easeInOutBack" + } + ListElement { + type: "easeOutInBack" + } + ListElement { + type: "easeOutBounce" + } + ListElement { + type: "easeInBounce" + } + ListElement { + type: "easeInOutBounce" + } + ListElement { + type: "easeOutInBounce" + } + } + ] + VerticalLayout { + id: layout + anchors.left: item.left + anchors.right: item.right + Repeater { + dataSource: easingtypes + Component { + Text { + id: text + text: type + height: 18 + font.italic: true + color: "black" + states: [ + State { + name: "from" + when: !mouse.pressed + SetProperty { + target: text + property: "x" + value: 0 + } + }, + State { + name: "to" + when: mouse.pressed + SetProperty { + target: text + property: "x" + value: item.width-100 + } + } + ] + transitions: [ + Transition { + fromState: "*" + toState: "to" + reversible: true + NumericAnimation { + properties: "x" + easing: type + } + } + ] + } + } + } + } + MouseRegion { + id: mouse + anchors.fill: layout + } +} diff --git a/tests/auto/declarative/visual/easing/image0.png b/tests/auto/declarative/visual/easing/image0.png Binary files differnew file mode 100644 index 0000000..dbe03aa --- /dev/null +++ b/tests/auto/declarative/visual/easing/image0.png diff --git a/tests/auto/declarative/visual/easing/manifest-play.xml b/tests/auto/declarative/visual/easing/manifest-play.xml new file mode 100644 index 0000000..3c84452 --- /dev/null +++ b/tests/auto/declarative/visual/easing/manifest-play.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="UTF-8"?> +<TestLog> + <TestFullFrame time="30" frameId="0"/> + <TestMouse time="480" type="2" button="1" buttons="1" globalPos="487,444" pos="483,417"/> + <TestFrame time="510" hash="83FB660D6CABAAFCB27C6EC001B14110"/> + <TestFrame time="540" hash="27FCD68F610024000CA6D3A8D9F0CF09"/> + <TestFrame time="570" hash="14728A6160AF51FCA8562D6A020BBA79"/> + <TestFrame time="600" hash="BDDB81682B30A6918927ACB59608D14E"/> + <TestFrame time="630" hash="03F16A41DCD31E41935E54763757C6D5"/> + <TestFrame time="660" hash="2D04EA1EBEDC77CF5D42A1B491A57EA6"/> + <TestFrame time="690" hash="762C36B33B75F24427CA45F4AD06B64E"/> + <TestFrame time="720" hash="AA02624CC889C95A99BBE58365F4FAAD"/> + <TestFrame time="750" hash="0529200188188708A18CE0F931780DBD"/> + <TestFrame time="780" hash="56036B63822AF34F26B149069CD189C6"/> + <TestFrame time="810" hash="CFFC6583E2BA1E47E1439BED6FE69665"/> + <TestFrame time="840" hash="25A1AFDC945D5264FF0337A421143A3C"/> + <TestFrame time="870" hash="601FA34B5E15E7B87E6490580C2E1858"/> + <TestFrame time="900" hash="1CA085F6CB8509957A51F6182F7F5443"/> + <TestFrame time="930" hash="09B5849DF18F6817F7450230DFEC0E95"/> + <TestFrame time="960" hash="15D212C1291DF97E3DEA5AA8793AD5CB"/> + <TestFrame time="990" hash="D6E42E8F4D06BDDBAE998079AC2C79AD"/> + <TestFrame time="1020" hash="7016B5C435006D859AB087A73299B6D5"/> +</TestLog> diff --git a/tests/auto/declarative/visual/easing/manifest.xml b/tests/auto/declarative/visual/easing/manifest.xml new file mode 100644 index 0000000..3c84452 --- /dev/null +++ b/tests/auto/declarative/visual/easing/manifest.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="UTF-8"?> +<TestLog> + <TestFullFrame time="30" frameId="0"/> + <TestMouse time="480" type="2" button="1" buttons="1" globalPos="487,444" pos="483,417"/> + <TestFrame time="510" hash="83FB660D6CABAAFCB27C6EC001B14110"/> + <TestFrame time="540" hash="27FCD68F610024000CA6D3A8D9F0CF09"/> + <TestFrame time="570" hash="14728A6160AF51FCA8562D6A020BBA79"/> + <TestFrame time="600" hash="BDDB81682B30A6918927ACB59608D14E"/> + <TestFrame time="630" hash="03F16A41DCD31E41935E54763757C6D5"/> + <TestFrame time="660" hash="2D04EA1EBEDC77CF5D42A1B491A57EA6"/> + <TestFrame time="690" hash="762C36B33B75F24427CA45F4AD06B64E"/> + <TestFrame time="720" hash="AA02624CC889C95A99BBE58365F4FAAD"/> + <TestFrame time="750" hash="0529200188188708A18CE0F931780DBD"/> + <TestFrame time="780" hash="56036B63822AF34F26B149069CD189C6"/> + <TestFrame time="810" hash="CFFC6583E2BA1E47E1439BED6FE69665"/> + <TestFrame time="840" hash="25A1AFDC945D5264FF0337A421143A3C"/> + <TestFrame time="870" hash="601FA34B5E15E7B87E6490580C2E1858"/> + <TestFrame time="900" hash="1CA085F6CB8509957A51F6182F7F5443"/> + <TestFrame time="930" hash="09B5849DF18F6817F7450230DFEC0E95"/> + <TestFrame time="960" hash="15D212C1291DF97E3DEA5AA8793AD5CB"/> + <TestFrame time="990" hash="D6E42E8F4D06BDDBAE998079AC2C79AD"/> + <TestFrame time="1020" hash="7016B5C435006D859AB087A73299B6D5"/> +</TestLog> diff --git a/tests/auto/declarative/visual/easing/pics/qtlogo.png b/tests/auto/declarative/visual/easing/pics/qtlogo.png Binary files differnew file mode 100644 index 0000000..399bd0b --- /dev/null +++ b/tests/auto/declarative/visual/easing/pics/qtlogo.png diff --git a/tests/auto/declarative/visual/flickable/Day.qml b/tests/auto/declarative/visual/flickable/Day.qml new file mode 100644 index 0000000..63fbc78 --- /dev/null +++ b/tests/auto/declarative/visual/flickable/Day.qml @@ -0,0 +1,26 @@ +Rect { + property string day + + width: 400 + height: 500 + radius: 7 + pen.color: "black" + id: Page + Image { + x: 10 + y: 10 + source: "cork.jpg" + opaque: true + } + Text { + x: 20 + y: 20 + height: 40 + font.size: 14 + font.bold: true + width: 370 + text: day + style: "Outline" + styleColor: "#dedede" + } +} diff --git a/tests/auto/declarative/visual/flickable/cork.jpg b/tests/auto/declarative/visual/flickable/cork.jpg Binary files differnew file mode 100644 index 0000000..d4d706c --- /dev/null +++ b/tests/auto/declarative/visual/flickable/cork.jpg diff --git a/tests/auto/declarative/visual/flickable/flickable.qml b/tests/auto/declarative/visual/flickable/flickable.qml new file mode 100644 index 0000000..5946c40 --- /dev/null +++ b/tests/auto/declarative/visual/flickable/flickable.qml @@ -0,0 +1,53 @@ +Rect { + color: "lightSteelBlue" + width: 800 + height: 500 + ListModel { + id: List + ListElement { + name: "Sunday" + dayColor: "#808080" + } + ListElement { + name: "Monday" + dayColor: "blue" + } + ListElement { + name: "Tuesday" + dayColor: "yellow" + } + ListElement { + name: "Wednesday" + dayColor: "purple" + } + ListElement { + name: "Thursday" + dayColor: "blue" + } + ListElement { + name: "Friday" + dayColor: "green" + } + ListElement { + name: "Saturday" + dayColor: "orange" + } + } + Flickable { + id: Flick + anchors.fill: parent + viewportWidth: Lay.width + HorizontalLayout { + id: Lay + Repeater { + dataSource: List + Component { + Day { + day: name + color: dayColor + } + } + } + } + } +} diff --git a/tests/auto/declarative/visual/flickable/image0.png b/tests/auto/declarative/visual/flickable/image0.png Binary files differnew file mode 100644 index 0000000..a70ec71 --- /dev/null +++ b/tests/auto/declarative/visual/flickable/image0.png diff --git a/tests/auto/declarative/visual/flickable/manifest-fail.xml b/tests/auto/declarative/visual/flickable/manifest-fail.xml new file mode 100644 index 0000000..0701fa1 --- /dev/null +++ b/tests/auto/declarative/visual/flickable/manifest-fail.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="UTF-8"?> +<TestLog> + <TestFullFrame time="30" frameId="0"/> + <TestMouse time="930" type="2" button="1" buttons="1" globalPos="1459,490" pos="712,463"/> + <TestMouse time="1020" type="5" button="0" buttons="1" globalPos="1457,490" pos="710,463"/> + <TestMouse time="1020" type="5" button="0" buttons="1" globalPos="1454,490" pos="707,463"/> + <TestMouse time="1020" type="5" button="0" buttons="1" globalPos="1446,488" pos="699,461"/> + <TestMouse time="1020" type="5" button="0" buttons="1" globalPos="1438,488" pos="691,461"/> + <TestFrame time="1020" hash="3A44CE7B924456B70E9ACAA4D6211036"/> + <TestMouse time="1050" type="5" button="0" buttons="1" globalPos="1402,484" pos="655,457"/> + <TestMouse time="1050" type="5" button="0" buttons="1" globalPos="1386,484" pos="639,457"/> + <TestFrame time="1050" hash="CC4B8F76C3758329C4792CC2499588B9"/> + <TestMouse time="1080" type="5" button="0" buttons="1" globalPos="1328,478" pos="581,451"/> + <TestFrame time="1080" hash="A314FC89F9915A0F62E77C649052F30B"/> + <TestMouse time="1110" type="5" button="0" buttons="1" globalPos="1306,476" pos="559,449"/> + <TestMouse time="1110" type="5" button="0" buttons="1" globalPos="1258,472" pos="511,445"/> + <TestMouse time="1110" type="5" button="0" buttons="1" globalPos="1234,468" pos="487,441"/> + <TestFrame time="1110" hash="496BEE45FD87ACA4335EB656DAB38E7C"/> + <TestMouse time="1140" type="5" button="0" buttons="1" globalPos="1206,466" pos="459,439"/> + <TestMouse time="1140" type="5" button="0" buttons="1" globalPos="1140,460" pos="393,433"/> + <TestMouse time="1140" type="5" button="0" buttons="1" globalPos="1106,454" pos="359,427"/> + <TestFrame time="1140" hash="9052B7F038D1BE19B5C603F2B376D95C"/> + <TestMouse time="1170" type="5" button="0" buttons="1" globalPos="980,438" pos="233,411"/> + <TestFrame time="1170" hash="75EBD16D2210983178EC267DD5C7E3DC"/> + <TestMouse time="1200" type="5" button="0" buttons="1" globalPos="930,432" pos="183,405"/> + <TestMouse time="1200" type="3" button="1" buttons="0" globalPos="930,432" pos="183,405"/> + <TestFrame time="1200" hash="A016C7981ACC7C26D0CDE0CF7D71E929"/> + <TestFrame time="1260" hash="A2EA153F54B2D98DEC895FC72D3279F0"/> + <TestFrame time="1290" hash="2702B6D7429FC955B2061C368910309F"/> +</TestLog> diff --git a/tests/auto/declarative/visual/flickable/manifest.xml b/tests/auto/declarative/visual/flickable/manifest.xml new file mode 100644 index 0000000..84d6890 --- /dev/null +++ b/tests/auto/declarative/visual/flickable/manifest.xml @@ -0,0 +1,190 @@ +<?xml version="1.0" encoding="UTF-8"?> +<TestLog> + <TestFullFrame time="30" frameId="0"/> + <TestMouse time="930" type="2" button="1" buttons="1" globalPos="1459,490" pos="712,463"/> + <TestMouse time="1020" type="5" button="0" buttons="1" globalPos="1457,490" pos="710,463"/> + <TestMouse time="1020" type="5" button="0" buttons="1" globalPos="1454,490" pos="707,463"/> + <TestMouse time="1020" type="5" button="0" buttons="1" globalPos="1446,488" pos="699,461"/> + <TestMouse time="1020" type="5" button="0" buttons="1" globalPos="1438,488" pos="691,461"/> + <TestFrame time="1020" hash="3A44CE7B924456B70E9ACAA4D6211036"/> + <TestMouse time="1050" type="5" button="0" buttons="1" globalPos="1402,484" pos="655,457"/> + <TestMouse time="1050" type="5" button="0" buttons="1" globalPos="1386,484" pos="639,457"/> + <TestFrame time="1050" hash="CC4B8F76C3758329C4792CC2499588B9"/> + <TestMouse time="1080" type="5" button="0" buttons="1" globalPos="1328,478" pos="581,451"/> + <TestFrame time="1080" hash="A314FC89F9915A0F62E77C649052F30B"/> + <TestMouse time="1110" type="5" button="0" buttons="1" globalPos="1306,476" pos="559,449"/> + <TestMouse time="1110" type="5" button="0" buttons="1" globalPos="1258,472" pos="511,445"/> + <TestMouse time="1110" type="5" button="0" buttons="1" globalPos="1234,468" pos="487,441"/> + <TestFrame time="1110" hash="496BEE45FD87ACA4335EB656DAB38E7C"/> + <TestMouse time="1140" type="5" button="0" buttons="1" globalPos="1206,466" pos="459,439"/> + <TestMouse time="1140" type="5" button="0" buttons="1" globalPos="1140,460" pos="393,433"/> + <TestMouse time="1140" type="5" button="0" buttons="1" globalPos="1106,454" pos="359,427"/> + <TestFrame time="1140" hash="9052B7F038D1BE19B5C603F2B376D95C"/> + <TestMouse time="1170" type="5" button="0" buttons="1" globalPos="980,438" pos="233,411"/> + <TestFrame time="1170" hash="75EBD16D2210983178EC267DD5C7E3DC"/> + <TestMouse time="1200" type="5" button="0" buttons="1" globalPos="930,432" pos="183,405"/> + <TestMouse time="1200" type="3" button="1" buttons="0" globalPos="930,432" pos="183,405"/> + <TestFrame time="1200" hash="A016C7981ACC7C26D0CDE0CF7D71E929"/> + <TestFrame time="1260" hash="203B3D2224AA0B9CB9DB64C837402047"/> + <TestFrame time="1290" hash="E9974E5662F22716C9BC2CF8D1FF12FE"/> + <TestFrame time="1320" hash="1218CCCC399AE53D5D99D3E7AFD73A16"/> + <TestFrame time="1350" hash="FA5D19578629F56972955E9FE530BE59"/> + <TestFrame time="1380" hash="B5B23BBDF1FEB6E6B55AE3909F607D96"/> + <TestFrame time="1410" hash="17EDC257AF24F178455CDEE7B9D73A9F"/> + <TestFrame time="1440" hash="F62E75656DC8AEF20426535DC25FC9F7"/> + <TestFrame time="1470" hash="973D39071B13FBBC700964CA1E4995DA"/> + <TestFrame time="1500" hash="391C67A59AC71B498381FC4D3DA1E8BB"/> + <TestFrame time="1530" hash="C1D86256E4BE487CB61AB1CC8D277FF2"/> + <TestFrame time="1560" hash="D5324FF0B16AA4B532007236222FEEAA"/> + <TestFrame time="1590" hash="4B14446DE1B9DE22D3DFF86A7CC46A05"/> + <TestFrame time="1620" hash="49E6FF8DEB537ECE9BDF56135FCB8BE3"/> + <TestFrame time="1650" hash="25D8D454CD32513F2E711D1B09DF87AF"/> + <TestFrame time="1680" hash="AB511F44DD761AC1070733CB81731451"/> + <TestFrame time="1710" hash="3441D361DB85B2522C8CCB8C21D95E70"/> + <TestFrame time="1740" hash="DB333DF49E6DB519F1F5436F6EEEF18E"/> + <TestFrame time="1770" hash="97044C41A8C27B534707352334CB100E"/> + <TestFrame time="1800" hash="C9EE4321669BB45A574D2CD3448553FE"/> + <TestFrame time="1830" hash="6E1067FB547479F8AC0214B1DE4F1ABD"/> + <TestFrame time="1860" hash="9AC3067759043EF1C8138C6E3D3B26D1"/> + <TestFrame time="1890" hash="F90BB455E7D0266C631BFD6657AC673F"/> + <TestFrame time="1920" hash="064CA0BCE5BCE1E5409F7E95F501843A"/> + <TestFrame time="1950" hash="AC5489FE171E537E5AF6EC9F8B5241DA"/> + <TestFrame time="1980" hash="BBF5D953DCF7FF64D99BF10E244FACE0"/> + <TestFrame time="2010" hash="309FC8E37A3EC93C41BC5E2F8F2962DB"/> + <TestFrame time="2040" hash="192B13ADD78B36E54E3D39E998641F82"/> + <TestFrame time="2070" hash="10F9D012CD1ECD9C8A872AA28191599E"/> + <TestFrame time="2100" hash="E3C9CE476A02915B7EEAA5D16747BD74"/> + <TestFrame time="2130" hash="24AD4F88A8BE8E4059517DA5AB9EC3F9"/> + <TestFrame time="2160" hash="74CE8AFFE7BAC8380E9EE27E482107E8"/> + <TestFrame time="2190" hash="C3377013131C3D1EEFFAEC37C0359E7B"/> + <TestFrame time="2220" hash="1850C61F261E6E148E12C9D9508411E4"/> + <TestFrame time="2250" hash="30EEAD3AC4C869FEB9A2E2F18BB5F335"/> + <TestFrame time="2280" hash="EB0F744274AF8FF27CAFC73053B63C87"/> + <TestFrame time="2310" hash="ADF16B9E820CF7F77E17E2383E0BF345"/> + <TestFrame time="2340" hash="8623C727CB6605607679B7C973E5CE61"/> + <TestFrame time="2370" hash="DE795BC19AD3B24FF091D6EB500C0C9A"/> + <TestFrame time="2400" hash="E85F53F766BE13A62272442916217181"/> + <TestFrame time="2430" hash="B5B05BF6D74AC22BC0DC5ECF8AFFD571"/> + <TestFrame time="2460" hash="C9DB0041AEA560EA3569FA6A37A8E226"/> + <TestFrame time="2490" hash="96B6E45404C4CB7C65A7113294679C96"/> + <TestFrame time="2520" hash="780599814A9AEEB63B6604F8627966FC"/> + <TestFrame time="2550" hash="40D7E36CD63DC9B6F5E0340F8E61DE4F"/> + <TestFrame time="2580" hash="127E4A92CC2AF9B6C7B5686ECED260E3"/> + <TestFrame time="2610" hash="10FEB4963AAD931587BAC2101367CB92"/> + <TestFrame time="2640" hash="2926893CD68516281E47EAD04720E4DB"/> + <TestFrame time="2670" hash="23F790EF701E37C3959465BF5298C9C2"/> + <TestFrame time="2700" hash="461224D0A6662450BA361FAF90CA3087"/> + <TestFrame time="2730" hash="3779C1CC5CD18633C70CE5614C2FCA33"/> + <TestFrame time="2760" hash="D93F3000F95110464793C9BAEF58D694"/> + <TestFrame time="2790" hash="0BFCCED8AE73FBCAC251442F002D603C"/> + <TestFrame time="2820" hash="AC1D13A5508255DCA994CC4685FB0AE3"/> + <TestFrame time="2850" hash="A6709853B44AB203FC8806D3F4159639"/> + <TestFrame time="2880" hash="171589A0F67D72F1685836F5EFF2DD10"/> + <TestFrame time="2910" hash="D4984C2B663CFA0CDE95F9AD5BC9937B"/> + <TestFrame time="2940" hash="1BB6D261C9E800004B180FB8EC0B45AD"/> + <TestFrame time="2970" hash="46CD4E37C989FACF2B7CD71A16DB495A"/> + <TestFrame time="3000" hash="8ED436FF855C96A8CEB795AE175A7C54"/> + <TestFrame time="3030" hash="8ED436FF855C96A8CEB795AE175A7C54"/> + <TestFrame time="3060" hash="138D8CC351C847F266C63F323BABD7FE"/> + <TestFrame time="3090" hash="8D90560CCF5EEB1475F3AA46295E4DD0"/> + <TestFrame time="3120" hash="DD893A953B945365B0F9287A79826A6D"/> + <TestFrame time="3150" hash="386A768FD485BB66C9DC1465399B58C8"/> + <TestFrame time="3180" hash="21340437F1A05C216005157A8E8A9EEF"/> + <TestFrame time="3210" hash="6E2DA9DA5964F59715B08FD59D8BC3EF"/> + <TestFrame time="3240" hash="DC7108F44E225D70349889D9E3F62E74"/> + <TestMouse time="4110" type="2" button="1" buttons="1" globalPos="853,492" pos="106,465"/> + <TestMouse time="4170" type="5" button="0" buttons="1" globalPos="854,493" pos="107,466"/> + <TestMouse time="4170" type="5" button="0" buttons="1" globalPos="855,493" pos="108,466"/> + <TestMouse time="4170" type="5" button="0" buttons="1" globalPos="856,494" pos="109,467"/> + <TestMouse time="4170" type="5" button="0" buttons="1" globalPos="857,494" pos="110,467"/> + <TestMouse time="4200" type="5" button="0" buttons="1" globalPos="859,494" pos="112,467"/> + <TestMouse time="4200" type="5" button="0" buttons="1" globalPos="860,495" pos="113,468"/> + <TestMouse time="4200" type="5" button="0" buttons="1" globalPos="862,495" pos="115,468"/> + <TestFrame time="4200" hash="3946A595E81E4388AFDDDB2539B21BF3"/> + <TestMouse time="4230" type="5" button="0" buttons="1" globalPos="864,495" pos="117,468"/> + <TestMouse time="4230" type="5" button="0" buttons="1" globalPos="869,495" pos="122,468"/> + <TestMouse time="4230" type="5" button="0" buttons="1" globalPos="872,495" pos="125,468"/> + <TestFrame time="4230" hash="D9F7C86886CC5309846694F5DA98A123"/> + <TestMouse time="4260" type="5" button="0" buttons="1" globalPos="875,495" pos="128,468"/> + <TestMouse time="4260" type="5" button="0" buttons="1" globalPos="892,497" pos="145,470"/> + <TestFrame time="4260" hash="0B923428F4EAF40CB032FE8880B10943"/> + <TestMouse time="4290" type="5" button="0" buttons="1" globalPos="911,499" pos="164,472"/> + <TestMouse time="4290" type="5" button="0" buttons="1" globalPos="919,499" pos="172,472"/> + <TestFrame time="4290" hash="F1FCED7910188DBEDC62E289EC98D14A"/> + <TestMouse time="4320" type="5" button="0" buttons="1" globalPos="938,499" pos="191,472"/> + <TestFrame time="4320" hash="71A01976611816A5D42BBB6BC6DE5336"/> + <TestMouse time="4350" type="5" button="0" buttons="1" globalPos="957,501" pos="210,474"/> + <TestMouse time="4350" type="5" button="0" buttons="1" globalPos="960,501" pos="213,474"/> + <TestFrame time="4350" hash="204D5511DFAA28AF3E499FD5E503592A"/> + <TestMouse time="4380" type="5" button="0" buttons="1" globalPos="968,501" pos="221,474"/> + <TestMouse time="4380" type="5" button="0" buttons="1" globalPos="986,503" pos="239,476"/> + <TestMouse time="4380" type="5" button="0" buttons="1" globalPos="989,503" pos="242,476"/> + <TestFrame time="4380" hash="E7F2934FB80FD155AAE4E558B1D31AF9"/> + <TestMouse time="4410" type="5" button="0" buttons="1" globalPos="1015,501" pos="268,474"/> + <TestMouse time="4410" type="5" button="0" buttons="1" globalPos="1025,499" pos="278,472"/> + <TestFrame time="4410" hash="DE795BC19AD3B24FF091D6EB500C0C9A"/> + <TestMouse time="4440" type="5" button="0" buttons="1" globalPos="1065,497" pos="318,470"/> + <TestFrame time="4440" hash="3A2D5734CCC3E5690EF24D412B5ADE32"/> + <TestMouse time="4470" type="5" button="0" buttons="1" globalPos="1083,495" pos="336,468"/> + <TestMouse time="4470" type="5" button="0" buttons="1" globalPos="1135,493" pos="388,466"/> + <TestMouse time="4470" type="5" button="0" buttons="1" globalPos="1171,489" pos="424,462"/> + <TestFrame time="4470" hash="A5F66816E008610C1DA44270F837C9DF"/> + <TestMouse time="4500" type="5" button="0" buttons="1" globalPos="1215,489" pos="468,462"/> + <TestMouse time="4500" type="5" button="0" buttons="1" globalPos="1319,483" pos="572,456"/> + <TestMouse time="4500" type="5" button="0" buttons="1" globalPos="1379,479" pos="632,452"/> + <TestFrame time="4500" hash="6AE11928E7948AD5F9CE5EE07B5E7390"/> + <TestMouse time="4530" type="5" button="0" buttons="1" globalPos="1441,475" pos="694,448"/> + <TestMouse time="4530" type="3" button="1" buttons="0" globalPos="1441,475" pos="694,448"/> + <TestFrame time="4530" hash="47B438BC833CFF7984D3E158B54F0EA5"/> + <TestFrame time="4590" hash="DA134DD6826A87BC08F3BE59F3D2866D"/> + <TestFrame time="4620" hash="D1E87BD1C6264CE83979D34500EEB85B"/> + <TestFrame time="4650" hash="37C13A368649152DD1D43BDD17BEEE97"/> + <TestFrame time="4680" hash="C461AE2C388F4B06E958C12B543E53C0"/> + <TestFrame time="4710" hash="6070DD498E15C27243F09FD8CF8C0D2F"/> + <TestFrame time="4740" hash="FB74E95CF41BDA785991BA01369E9320"/> + <TestFrame time="4770" hash="F52AE455BBA3BAD36ABB4DB2480549D6"/> + <TestFrame time="4800" hash="9BC4E043F6595493ED32BBAAB949CC15"/> + <TestFrame time="4830" hash="4C87F70F6A46B2066021A68435BB285D"/> + <TestFrame time="4860" hash="282A523039F702F22C5D7F2B00BCA1F4"/> + <TestFrame time="4890" hash="D1623E75F20C00F6F357346F57E5C343"/> + <TestFrame time="4920" hash="F96CC72E3671C64D87719E5DF8303FA9"/> + <TestFrame time="4950" hash="44D4E09F9AB5C20E7A7F1AEF920B3599"/> + <TestFrame time="4980" hash="BBAD1BD87E29C1F0834B16DA9C1317A4"/> + <TestFrame time="5010" hash="66DF69AD2EA4823E59F6FC296910822F"/> + <TestFrame time="5040" hash="A0DCE22CFADFE091C5474C231EAD191E"/> + <TestFrame time="5070" hash="AE67DD3CD8B77D001288558E3C67E675"/> + <TestFrame time="5100" hash="B028CC11B70C5288436E49DD439F9F46"/> + <TestFrame time="5130" hash="2FBEFA9C751317D668A1074E8BCB8B10"/> + <TestFrame time="5160" hash="2DB3A59F7CB89B89CD45B86008CC0541"/> + <TestFrame time="5190" hash="AFE0FD3CB16F9DDD3E8DAD46656BE099"/> + <TestFrame time="5220" hash="90C04F980A0C008D4B919D9A4B663762"/> + <TestFrame time="5250" hash="215CB75F6359548B7A4A408E83049A25"/> + <TestFrame time="5280" hash="8EC68EA3F6B54415EC9B860B0207351E"/> + <TestFrame time="5310" hash="8FC14C2EB103B4FDC5B17E6E0F2386D1"/> + <TestFrame time="5340" hash="938DA507656430E1758CB8B5E9D874B1"/> + <TestFrame time="5370" hash="30A3166F0169715DA9FECD48DA257625"/> + <TestFrame time="5400" hash="0C24CD68AFE9C24380178417FE835494"/> + <TestFrame time="5430" hash="C8A18880023CB12BA98EBDFF65875874"/> + <TestFrame time="5460" hash="FE3BCA8DC715A19161FCD48C728366A0"/> + <TestFrame time="5490" hash="4771F9D8AA2A177A190879EB543FA138"/> + <TestFrame time="5520" hash="971D611BC939AB20B998D659DF2235FE"/> + <TestFrame time="5550" hash="7AF899892AE28C61B71A5682F9540DB5"/> + <TestFrame time="5580" hash="CCF349DCA802D5D68B6C9CB368104EF8"/> + <TestFrame time="5610" hash="3DC13F8B693648ABBE8FD6935832BEC7"/> + <TestFrame time="5640" hash="ED2AD5E716D69FD1A87133209695E911"/> + <TestFrame time="5670" hash="037B45A66950DF70D8BD7BC0E000ECC7"/> + <TestFrame time="5700" hash="43B59CF46A829CAFF7D9C0A6D1175581"/> + <TestFrame time="5730" hash="6FF016CE82BFD220418C0A9A644F2F81"/> + <TestFrame time="5760" hash="96D37AFF283210D59287526798E9376D"/> + <TestFrame time="5790" hash="7289570ABB671359AC2F2DF1898748CA"/> + <TestFrame time="5820" hash="2B3AF6424765512B8949BBB9BF6571DC"/> + <TestFrame time="5850" hash="23054E1F931342B8A6C5F6D30A9FF158"/> + <TestFrame time="5880" hash="E3D6EBB07FC90AD2483E95C09CB9E074"/> + <TestFrame time="5910" hash="08EE4C4D9F161AB4118EAD4F4AA8D5B3"/> + <TestFrame time="5940" hash="96D37AFF283210D59287526798E9376D"/> + <TestFrame time="5970" hash="40FB8747AACD078576573CF346E2C418"/> + <TestFrame time="6000" hash="4095D9B46D265D28C88DE0D0E02AC840"/> + <TestFrame time="6030" hash="E370C2A5451DC73AE4F742D52E3DAD4D"/> + <TestFrame time="6060" hash="AC4DC18BEFE0895C1ADF8EE2E3094A09"/> + <TestFrame time="6090" hash="AC4DC18BEFE0895C1ADF8EE2E3094A09"/> +</TestLog> diff --git a/tests/auto/declarative/visual/flipable/flipable.xml b/tests/auto/declarative/visual/flipable/flipable.xml new file mode 100644 index 0000000..d769e55 --- /dev/null +++ b/tests/auto/declarative/visual/flipable/flipable.xml @@ -0,0 +1,138 @@ +<Rect color="lightsteelblue" height="400" width="500"> + <VisualModel id="MyVisualModel"> + <model> + <ListModel id="ListModel"> + <Person> + <name>Jessica</name> + <picture>face.png</picture> + </Person> + <Person> + <name>John</name> + <picture>photo0.png</picture> + </Person> + <Person> + <name>Susan</name> + <picture>photo10.png</picture> + </Person> + <Person> + <name>Samantha</name> + <picture>photo1.png</picture> + </Person> + <Person> + <name>Mark</name> + <picture>photo2.png</picture> + </Person> + <Person> + <name>Sarah</name> + <picture>photo3.png</picture> + </Person> + <Person> + <name>Pam</name> + <picture>photo4.png</picture> + </Person> + <Person> + <name>April</name> + <picture>photo5.png</picture> + </Person> + <Person> + <name>Tarryn</name> + <picture>photo6.png</picture> + </Person> + <Person> + <name>Geoff</name> + <picture>photo7.png</picture> + </Person> + <Person> + <name>Bill</name> + <picture>photo8.png</picture> + </Person> + <Person> + <name>Stuart</name> + <picture>photo9.png</picture> + </Person> + </ListModel> + </model> + <delegate> + <Package> + <Flipable id="MeRect" width="100" height="100"> + <properties> + <Property name="r" type="Real" /> + </properties> + <transform> + <Perspective angle="90" x="50" y="50" aspect="1" scale="256"/> + <Axis xStart="50" xEnd="50" yStart="0" yEnd="1" rotation="{MeRect.r}" /> + </transform> + + <front> + <Rect radius="5" color="red" width="100" height="100"> + <Text text="{name}" /> + </Rect> + </front> + + <back> + <Rect radius="5" color="red" width="100" height="100"> + <Image anchors.horizontalCenter="{parent.horizontalCenter}" anchors.verticalCenter="{parent.verticalCenter}" file="{picture}" /> + </Rect> + </back> + </Flipable> + + <Item Package.name="leftBox" id="LeftBox" + width="100" height="100"> + <Rect opacity="0.1" width="80" height="80" radius="4" + color="grey" x="10" y="10"> + <Text text="{name}" /> + <MouseRegion anchors.fill="{parent}" onClick="if(MyItem.currentState=='left') MyItem.currentState='right'; else MyItem.currentState='left';" /> + </Rect> + </Item> + <Item Package.name="rightBox" id="RightBox" + width="100" height="100"> + <Rect opacity="0.1" width="80" height="80" radius="4" + color="grey" x="10" y="10"> + <Text text="{name}" /> + <MouseRegion anchors.fill="{parent}" onClick="if(MyItem.currentState=='left') MyItem.currentState='right'; else MyItem.currentState='left';" /> + </Rect> + </Item> + <Item id="MyItem"> + <states> + <State name="left"> + <SetProperty target="{MeRect}" property="moveToParent" value="{LeftBox}" /> + </State> + <State name="right"> + <SetProperty target="{MeRect}" property="moveToParent" value="{RightBox}" /> + <SetProperty target="{MeRect}" property="r" value="180" /> + </State> + </states> + <transitions> + <Transition fromState="*" toState="*"> + <NumericAnimation property="r" duration="500" /> + <SerialAnimation> + <SetPropertyAction target="{MeRect}" property="moveToParent" value="{Bounce}" /> + <ParallelAnimation> + <NumericAnimation target="{MeRect}" properties="x" to="0" duration="250" /> + <NumericAnimation target="{MeRect}" properties="y" to="0" easing="easeInQuad" duration="250"/> + </ParallelAnimation> + <SetPropertyAction target="{MeRect}" property="moveToParent" /> + <ParallelAnimation> + <NumericAnimation target="{MeRect}" properties="x" to="0" duration="250"/> + <NumericAnimation target="{MeRect}" properties="y" to="0" easing="easeOutQuad" duration="250"/> + </ParallelAnimation> + </SerialAnimation> + </Transition> + </transitions> + <currentState>left</currentState> + </Item> + + </Package> + </delegate> + </VisualModel> + + <Item width="800" height="400" clip="true"> + <Item z="100" id="Bounce" x="200" y="300" /> + <ListView id="MyListView" width="400" height="400" x="400" + model="{MyVisualModel.parts.rightBox}" /> + + <ListView id="MyListView2" width="400" height="400" + model="{MyVisualModel.parts.leftBox}" /> + </Item> + +</Rect> diff --git a/tests/auto/declarative/visual/flipable/image0.png b/tests/auto/declarative/visual/flipable/image0.png Binary files differnew file mode 100644 index 0000000..affb8a5 --- /dev/null +++ b/tests/auto/declarative/visual/flipable/image0.png diff --git a/tests/auto/declarative/visual/flipable/manifest-play.xml b/tests/auto/declarative/visual/flipable/manifest-play.xml new file mode 100644 index 0000000..81c08e4 --- /dev/null +++ b/tests/auto/declarative/visual/flipable/manifest-play.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<TestLog> + <TestFullFrame time="30" frameId="0"/> + <TestMouse time="2040" type="2" button="1" buttons="1" globalPos="812,72" pos="65,45"/> + <TestMouse time="2100" type="3" button="1" buttons="0" globalPos="812,72" pos="65,45"/> + <TestFrame time="2130" hash="210454ECF70EEA9CA43DD391BC23178B"/> + <TestFrame time="2160" hash="F6612DAD879208F4AF100337271C445C"/> + <TestFrame time="2190" hash="C77FC41100D0B066F8F0BF4ABCF2F0BF"/> + <TestFrame time="2220" hash="1AB3A42E6FC271E049E6071A88AB8EE4"/> + <TestFrame time="2250" hash="DB3D5BC6882699DCC0208E4F5294B609"/> + <TestFrame time="2280" hash="DC5A8B44283DA4A81D3994B873FC5695"/> + <TestFrame time="2310" hash="5149027ECF7813BA64D3AB8FFE0265F5"/> + <TestFrame time="2340" hash="B7E801DF476C012AC3E9E48A9D4AA321"/> + <TestFrame time="2370" hash="F31A647A6A3EC86D7F16EB3147E5FC29"/> + <TestFrame time="2400" hash="FBB068C39D5188A175075667B584F1BE"/> + <TestFrame time="2430" hash="EC487AB66384A4A3A718D03555EBFD41"/> + <TestFrame time="2460" hash="C7AD11EB051B11ACBA38027013215A05"/> + <TestFrame time="2490" hash="AA38FD8E97EC394488274127630E7946"/> + <TestFrame time="2520" hash="1CA2B617AC966B54FFA1A61914F68A9D"/> + <TestFrame time="2550" hash="1726C0BAA930CAF282154F14AC2FD120"/> + <TestFrame time="2580" hash="58F8196148C8B64191AF7B897A811CFB"/> + <TestFrame time="2610" hash="D56D3FA137AA63A0215611450B40F3E0"/> + <TestFrame time="2640" hash="5E1BCDF996B2903D1EAEAC65E17783C2"/> +</TestLog> diff --git a/tests/auto/declarative/visual/flipable/manifest.xml b/tests/auto/declarative/visual/flipable/manifest.xml new file mode 100644 index 0000000..81c08e4 --- /dev/null +++ b/tests/auto/declarative/visual/flipable/manifest.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<TestLog> + <TestFullFrame time="30" frameId="0"/> + <TestMouse time="2040" type="2" button="1" buttons="1" globalPos="812,72" pos="65,45"/> + <TestMouse time="2100" type="3" button="1" buttons="0" globalPos="812,72" pos="65,45"/> + <TestFrame time="2130" hash="210454ECF70EEA9CA43DD391BC23178B"/> + <TestFrame time="2160" hash="F6612DAD879208F4AF100337271C445C"/> + <TestFrame time="2190" hash="C77FC41100D0B066F8F0BF4ABCF2F0BF"/> + <TestFrame time="2220" hash="1AB3A42E6FC271E049E6071A88AB8EE4"/> + <TestFrame time="2250" hash="DB3D5BC6882699DCC0208E4F5294B609"/> + <TestFrame time="2280" hash="DC5A8B44283DA4A81D3994B873FC5695"/> + <TestFrame time="2310" hash="5149027ECF7813BA64D3AB8FFE0265F5"/> + <TestFrame time="2340" hash="B7E801DF476C012AC3E9E48A9D4AA321"/> + <TestFrame time="2370" hash="F31A647A6A3EC86D7F16EB3147E5FC29"/> + <TestFrame time="2400" hash="FBB068C39D5188A175075667B584F1BE"/> + <TestFrame time="2430" hash="EC487AB66384A4A3A718D03555EBFD41"/> + <TestFrame time="2460" hash="C7AD11EB051B11ACBA38027013215A05"/> + <TestFrame time="2490" hash="AA38FD8E97EC394488274127630E7946"/> + <TestFrame time="2520" hash="1CA2B617AC966B54FFA1A61914F68A9D"/> + <TestFrame time="2550" hash="1726C0BAA930CAF282154F14AC2FD120"/> + <TestFrame time="2580" hash="58F8196148C8B64191AF7B897A811CFB"/> + <TestFrame time="2610" hash="D56D3FA137AA63A0215611450B40F3E0"/> + <TestFrame time="2640" hash="5E1BCDF996B2903D1EAEAC65E17783C2"/> +</TestLog> diff --git a/tests/auto/declarative/visual/flipable/pics/arrow.png b/tests/auto/declarative/visual/flipable/pics/arrow.png Binary files differnew file mode 100644 index 0000000..997190d --- /dev/null +++ b/tests/auto/declarative/visual/flipable/pics/arrow.png diff --git a/tests/auto/declarative/visual/flipable/pics/face.png b/tests/auto/declarative/visual/flipable/pics/face.png Binary files differnew file mode 100644 index 0000000..e9529ac --- /dev/null +++ b/tests/auto/declarative/visual/flipable/pics/face.png diff --git a/tests/auto/declarative/visual/flipable/pics/photo0.png b/tests/auto/declarative/visual/flipable/pics/photo0.png Binary files differnew file mode 100644 index 0000000..26bbf5b --- /dev/null +++ b/tests/auto/declarative/visual/flipable/pics/photo0.png diff --git a/tests/auto/declarative/visual/flipable/pics/photo1.png b/tests/auto/declarative/visual/flipable/pics/photo1.png Binary files differnew file mode 100644 index 0000000..2230f71 --- /dev/null +++ b/tests/auto/declarative/visual/flipable/pics/photo1.png diff --git a/tests/auto/declarative/visual/flipable/pics/photo10.png b/tests/auto/declarative/visual/flipable/pics/photo10.png Binary files differnew file mode 100644 index 0000000..119f142 --- /dev/null +++ b/tests/auto/declarative/visual/flipable/pics/photo10.png diff --git a/tests/auto/declarative/visual/flipable/pics/photo2.png b/tests/auto/declarative/visual/flipable/pics/photo2.png Binary files differnew file mode 100644 index 0000000..e3d58c1 --- /dev/null +++ b/tests/auto/declarative/visual/flipable/pics/photo2.png diff --git a/tests/auto/declarative/visual/flipable/pics/photo3.png b/tests/auto/declarative/visual/flipable/pics/photo3.png Binary files differnew file mode 100644 index 0000000..4b58df4 --- /dev/null +++ b/tests/auto/declarative/visual/flipable/pics/photo3.png diff --git a/tests/auto/declarative/visual/flipable/pics/photo4.png b/tests/auto/declarative/visual/flipable/pics/photo4.png Binary files differnew file mode 100644 index 0000000..4ed4bd2 --- /dev/null +++ b/tests/auto/declarative/visual/flipable/pics/photo4.png diff --git a/tests/auto/declarative/visual/flipable/pics/photo5.png b/tests/auto/declarative/visual/flipable/pics/photo5.png Binary files differnew file mode 100644 index 0000000..eb26704 --- /dev/null +++ b/tests/auto/declarative/visual/flipable/pics/photo5.png diff --git a/tests/auto/declarative/visual/flipable/pics/photo6.png b/tests/auto/declarative/visual/flipable/pics/photo6.png Binary files differnew file mode 100644 index 0000000..69875ce --- /dev/null +++ b/tests/auto/declarative/visual/flipable/pics/photo6.png diff --git a/tests/auto/declarative/visual/flipable/pics/photo7.png b/tests/auto/declarative/visual/flipable/pics/photo7.png Binary files differnew file mode 100644 index 0000000..0b117c9 --- /dev/null +++ b/tests/auto/declarative/visual/flipable/pics/photo7.png diff --git a/tests/auto/declarative/visual/flipable/pics/photo8.png b/tests/auto/declarative/visual/flipable/pics/photo8.png Binary files differnew file mode 100644 index 0000000..b77b997 --- /dev/null +++ b/tests/auto/declarative/visual/flipable/pics/photo8.png diff --git a/tests/auto/declarative/visual/flipable/pics/photo9.png b/tests/auto/declarative/visual/flipable/pics/photo9.png Binary files differnew file mode 100644 index 0000000..8a974d6 --- /dev/null +++ b/tests/auto/declarative/visual/flipable/pics/photo9.png diff --git a/tests/auto/declarative/visual/pauseAnimation/data/raster/image0.png b/tests/auto/declarative/visual/pauseAnimation/data/raster/image0.png Binary files differnew file mode 100644 index 0000000..8082422 --- /dev/null +++ b/tests/auto/declarative/visual/pauseAnimation/data/raster/image0.png diff --git a/tests/auto/declarative/visual/pauseAnimation/data/raster/manifest.qml b/tests/auto/declarative/visual/pauseAnimation/data/raster/manifest.qml new file mode 100644 index 0000000..de3f32e --- /dev/null +++ b/tests/auto/declarative/visual/pauseAnimation/data/raster/manifest.qml @@ -0,0 +1,1262 @@ +TestLog { + TestFullFrame { + time: 0 + frameId: 0 + } + TestFrame { + time: 16 + hash: 'A350B70C5238A340E85FD4A3EC0390A3' + } + TestFrame { + time: 32 + hash: '675EBBDD22DD22CE45993DF4AF1ACFE9' + } + TestFrame { + time: 48 + hash: 'DCF2867C127E041970047EC8F3EDC04F' + } + TestFrame { + time: 64 + hash: '41BA853C3403F68A23E708DF82E21C53' + } + TestFrame { + time: 80 + hash: 'A725B59B4947357546BBFC7DF3D830AF' + } + TestFrame { + time: 96 + hash: '336D31586171F22D541B989D24B95CBB' + } + TestFrame { + time: 112 + hash: '6D63FB5C8A80F0280E88B2CDF8641BB9' + } + TestFrame { + time: 128 + hash: 'EF8941674CB61F54853DC33652BB854E' + } + TestFrame { + time: 144 + hash: 'B3F4A2165EC1EE971542B8EF89656CEA' + } + TestFrame { + time: 160 + hash: 'AF3120FE262D2489C0ED33FBBEE1549F' + } + TestFrame { + time: 176 + hash: '1373545E43FFF7251CEC9E8375EA267F' + } + TestFrame { + time: 192 + hash: '21F0B0437A999BBDE66A913032D495C2' + } + TestFrame { + time: 208 + hash: '0809D32D5BC1BFCE199B1F39A1C68D4F' + } + TestFrame { + time: 224 + hash: '022137587B39F5123835482178A1F1CF' + } + TestFrame { + time: 240 + hash: '97566CE9558D13EA0780BCE233097B27' + } + TestFrame { + time: 256 + hash: '96D79B07DA105B7F631ED61582B26F7E' + } + TestFrame { + time: 272 + hash: 'F4732FF2DF93FE67CB850DEC34184924' + } + TestFrame { + time: 288 + hash: '054E6E52F74A3E24F04E6AD0071F79F8' + } + TestFrame { + time: 304 + hash: 'F541AF93A9FDE62E4BD1C91D30F91E65' + } + TestFrame { + time: 320 + hash: 'C4F844EE71F23635BB3EC7375F6A134F' + } + TestFrame { + time: 336 + hash: '3E52E06DB2BF78762BB9816FE6B105D9' + } + TestFrame { + time: 352 + hash: 'D9604BE23A91327E6AB454609A9D4A13' + } + TestFrame { + time: 368 + hash: 'DC98A9BDD99367C1E9B838D4BE489DCC' + } + TestFrame { + time: 384 + hash: 'E87B00BFC2C2A75A4234EC02A057AD3A' + } + TestFrame { + time: 400 + hash: '5BE4F5C67941EFB6FCEA363C79F1E321' + } + TestFrame { + time: 416 + hash: '6CC9DE62A0C8FA5E42EAC1B01E99AC32' + } + TestFrame { + time: 432 + hash: '62A7133012348F2EC3A388FB685ECC3F' + } + TestFrame { + time: 448 + hash: '4AC43A03CC6F2020AB5F894D704092AC' + } + TestFrame { + time: 464 + hash: 'C1A7B7D6D64AC5584C073C2881290696' + } + TestFrame { + time: 480 + hash: '29ECE1BCA4D21FB5862091317D430A13' + } + TestFrame { + time: 496 + hash: '29ECE1BCA4D21FB5862091317D430A13' + } + TestFrame { + time: 512 + hash: '29ECE1BCA4D21FB5862091317D430A13' + } + TestFrame { + time: 528 + hash: '29ECE1BCA4D21FB5862091317D430A13' + } + TestFrame { + time: 544 + hash: '29ECE1BCA4D21FB5862091317D430A13' + } + TestFrame { + time: 560 + hash: 'C1A7B7D6D64AC5584C073C2881290696' + } + TestFrame { + time: 576 + hash: 'C1A7B7D6D64AC5584C073C2881290696' + } + TestFrame { + time: 592 + hash: '4AC43A03CC6F2020AB5F894D704092AC' + } + TestFrame { + time: 608 + hash: '4AC43A03CC6F2020AB5F894D704092AC' + } + TestFrame { + time: 624 + hash: 'FFD39C1122FE2F7877EF30591B539B40' + } + TestFrame { + time: 640 + hash: '62A7133012348F2EC3A388FB685ECC3F' + } + TestFrame { + time: 656 + hash: '45281A70021F81DBEF30334B1480DA1B' + } + TestFrame { + time: 672 + hash: '6CC9DE62A0C8FA5E42EAC1B01E99AC32' + } + TestFrame { + time: 688 + hash: '79EC710576427DF73DD03F39FBA6E2EB' + } + TestFrame { + time: 704 + hash: '5BE4F5C67941EFB6FCEA363C79F1E321' + } + TestFrame { + time: 720 + hash: '7D9096B1EB940C82A37BAF39EF3CCF3E' + } + TestFrame { + time: 736 + hash: 'E87B00BFC2C2A75A4234EC02A057AD3A' + } + TestFrame { + time: 752 + hash: 'DA60100DC55023C3BAB367D97C8F6A85' + } + TestFrame { + time: 768 + hash: 'DC98A9BDD99367C1E9B838D4BE489DCC' + } + TestFrame { + time: 784 + hash: '3F869538028A09020D5E8F528F4FB119' + } + TestFrame { + time: 800 + hash: '9650FD0364C01B11E4F5DCCE51D008AF' + } + TestFrame { + time: 816 + hash: '2CB09D9655ECC30AE6A591B28C0D355C' + } + TestFrame { + time: 832 + hash: '4DB9BC6C11CAF1D77794C2EABB62A44E' + } + TestFrame { + time: 848 + hash: 'CE2B5DD7418868ACF86FEA6AD19CC0C5' + } + TestFrame { + time: 864 + hash: '7C27EF654E645679C90520D6CF00B0C4' + } + TestFrame { + time: 880 + hash: 'AB3E211DF3EF7F5F7A8D712EDC891C0F' + } + TestFrame { + time: 896 + hash: '19D2AE617A49B57DD012677E2834469C' + } + TestFrame { + time: 912 + hash: '5025EB75C88F0760F637E0342B7F88A2' + } + TestFrame { + time: 928 + hash: '005ACBEF952A8EE536E6308A48223E65' + } + TestFrame { + time: 944 + hash: 'F1E0301430D153FB9D15EAFFDFCD5C58' + } + TestFrame { + time: 960 + hash: '5F18A81707F23D377E81A27C1FC41CE9' + } + TestFrame { + time: 976 + hash: 'BCC35497884C158396C7F60759D1FDA4' + } + TestFrame { + time: 992 + hash: '7A4528B000A4EA142D1C77407FA1F581' + } + TestFrame { + time: 1008 + hash: 'BA967A7D810A4531E577E5F6BD2DEF33' + } + TestFrame { + time: 1024 + hash: 'F5AFD9CF8FFE27E9992454B9E68688CB' + } + TestFrame { + time: 1040 + hash: '51D475C7F64A86D3A18FB115297A7B6B' + } + TestFrame { + time: 1056 + hash: '49F5D6FD45C195A8D245B7FEFC1277AB' + } + TestFrame { + time: 1072 + hash: 'F9B0B278659E3A0F78611E6B7F0F2176' + } + TestFrame { + time: 1088 + hash: '0809D32D5BC1BFCE199B1F39A1C68D4F' + } + TestFrame { + time: 1104 + hash: 'B7208D103B63A936DFF8DD8ED224237F' + } + TestFrame { + time: 1120 + hash: 'A57C81049B0DC68090EC7C3327B9922C' + } + TestFrame { + time: 1136 + hash: 'E553F365912586C6408C8C53B1B7D118' + } + TestFrame { + time: 1152 + hash: 'AF3120FE262D2489C0ED33FBBEE1549F' + } + TestFrame { + time: 1168 + hash: '0C20D12464ABBDC45041EA5D9F2719B1' + } + TestFrame { + time: 1184 + hash: 'DD60CBAFF6F34027474E92315DBC0EBC' + } + TestFrame { + time: 1200 + hash: '336D31586171F22D541B989D24B95CBB' + } + TestFrame { + time: 1216 + hash: '41BA853C3403F68A23E708DF82E21C53' + } + TestFrame { + time: 1232 + hash: '675EBBDD22DD22CE45993DF4AF1ACFE9' + } + TestFrame { + time: 1248 + hash: '41BA853C3403F68A23E708DF82E21C53' + } + TestFrame { + time: 1264 + hash: 'A725B59B4947357546BBFC7DF3D830AF' + } + TestFrame { + time: 1280 + hash: '336D31586171F22D541B989D24B95CBB' + } + TestFrame { + time: 1296 + hash: 'F0D8132489C2F2EF760E905B3C093726' + } + TestFrame { + time: 1312 + hash: '6D63FB5C8A80F0280E88B2CDF8641BB9' + } + TestFrame { + time: 1328 + hash: 'DD60CBAFF6F34027474E92315DBC0EBC' + } + TestFrame { + time: 1344 + hash: 'EF8941674CB61F54853DC33652BB854E' + } + TestFrame { + time: 1360 + hash: 'BC426FB7C31751665B0D3F16E2CB0173' + } + TestFrame { + time: 1376 + hash: '0C20D12464ABBDC45041EA5D9F2719B1' + } + TestFrame { + time: 1392 + hash: '53AE93140252373EAA4D9DA73756BD8E' + } + TestFrame { + time: 1408 + hash: '721D7061811B5439C2E8E395917494BC' + } + TestFrame { + time: 1424 + hash: 'AF3120FE262D2489C0ED33FBBEE1549F' + } + TestFrame { + time: 1440 + hash: 'A8B624EBFC9AB713D1CE55F318A6E90D' + } + TestFrame { + time: 1456 + hash: 'A88A8129259F86DF5A73ADDC3649AD37' + } + TestFrame { + time: 1472 + hash: 'A88A8129259F86DF5A73ADDC3649AD37' + } + TestFrame { + time: 1488 + hash: '3DB5E30EF19EA693C21CCF72892C4390' + } + TestFrame { + time: 1504 + hash: 'E553F365912586C6408C8C53B1B7D118' + } + TestFrame { + time: 1520 + hash: 'E553F365912586C6408C8C53B1B7D118' + } + TestFrame { + time: 1536 + hash: 'E553F365912586C6408C8C53B1B7D118' + } + TestFrame { + time: 1552 + hash: '1373545E43FFF7251CEC9E8375EA267F' + } + TestFrame { + time: 1568 + hash: '1373545E43FFF7251CEC9E8375EA267F' + } + TestFrame { + time: 1584 + hash: '1373545E43FFF7251CEC9E8375EA267F' + } + TestFrame { + time: 1600 + hash: '1373545E43FFF7251CEC9E8375EA267F' + } + TestFrame { + time: 1616 + hash: '1373545E43FFF7251CEC9E8375EA267F' + } + TestFrame { + time: 1632 + hash: '1373545E43FFF7251CEC9E8375EA267F' + } + TestFrame { + time: 1648 + hash: 'E553F365912586C6408C8C53B1B7D118' + } + TestFrame { + time: 1664 + hash: 'E553F365912586C6408C8C53B1B7D118' + } + TestFrame { + time: 1680 + hash: '3DB5E30EF19EA693C21CCF72892C4390' + } + TestFrame { + time: 1696 + hash: '3DB5E30EF19EA693C21CCF72892C4390' + } + TestFrame { + time: 1712 + hash: 'A88A8129259F86DF5A73ADDC3649AD37' + } + TestFrame { + time: 1728 + hash: 'A8B624EBFC9AB713D1CE55F318A6E90D' + } + TestFrame { + time: 1744 + hash: 'A8B624EBFC9AB713D1CE55F318A6E90D' + } + TestFrame { + time: 1760 + hash: 'AF3120FE262D2489C0ED33FBBEE1549F' + } + TestFrame { + time: 1776 + hash: '721D7061811B5439C2E8E395917494BC' + } + TestFrame { + time: 1792 + hash: 'B3F4A2165EC1EE971542B8EF89656CEA' + } + TestFrame { + time: 1808 + hash: '0C20D12464ABBDC45041EA5D9F2719B1' + } + TestFrame { + time: 1824 + hash: 'BC426FB7C31751665B0D3F16E2CB0173' + } + TestFrame { + time: 1840 + hash: 'EF8941674CB61F54853DC33652BB854E' + } + TestFrame { + time: 1856 + hash: 'DD60CBAFF6F34027474E92315DBC0EBC' + } + TestFrame { + time: 1872 + hash: '6D63FB5C8A80F0280E88B2CDF8641BB9' + } + TestFrame { + time: 1888 + hash: 'E74FE4A6BD92CBE8629C8BC8A870104D' + } + TestFrame { + time: 1904 + hash: '3042003C067B257DE2CB32F650DDE693' + } + TestFrame { + time: 1920 + hash: 'A725B59B4947357546BBFC7DF3D830AF' + } + TestFrame { + time: 1936 + hash: 'DCF2867C127E041970047EC8F3EDC04F' + } + TestFrame { + time: 1952 + hash: 'A350B70C5238A340E85FD4A3EC0390A3' + } + TestFrame { + time: 1968 + hash: '675EBBDD22DD22CE45993DF4AF1ACFE9' + } + TestFrame { + time: 1984 + hash: 'DCF2867C127E041970047EC8F3EDC04F' + } + TestFrame { + time: 2000 + hash: '41BA853C3403F68A23E708DF82E21C53' + } + TestFrame { + time: 2016 + hash: 'CE57E27AF329EBA4FAC3AB891F0407CE' + } + TestFrame { + time: 2032 + hash: 'CE57E27AF329EBA4FAC3AB891F0407CE' + } + TestFrame { + time: 2048 + hash: 'A725B59B4947357546BBFC7DF3D830AF' + } + TestFrame { + time: 2064 + hash: 'A725B59B4947357546BBFC7DF3D830AF' + } + TestFrame { + time: 2080 + hash: '3042003C067B257DE2CB32F650DDE693' + } + TestFrame { + time: 2096 + hash: '3042003C067B257DE2CB32F650DDE693' + } + TestFrame { + time: 2112 + hash: '3042003C067B257DE2CB32F650DDE693' + } + TestFrame { + time: 2128 + hash: '3042003C067B257DE2CB32F650DDE693' + } + TestFrame { + time: 2144 + hash: '3042003C067B257DE2CB32F650DDE693' + } + TestFrame { + time: 2160 + hash: '3042003C067B257DE2CB32F650DDE693' + } + TestFrame { + time: 2176 + hash: '3042003C067B257DE2CB32F650DDE693' + } + TestFrame { + time: 2192 + hash: '3042003C067B257DE2CB32F650DDE693' + } + TestFrame { + time: 2208 + hash: 'A725B59B4947357546BBFC7DF3D830AF' + } + TestFrame { + time: 2224 + hash: 'A725B59B4947357546BBFC7DF3D830AF' + } + TestFrame { + time: 2240 + hash: 'CE57E27AF329EBA4FAC3AB891F0407CE' + } + TestFrame { + time: 2256 + hash: 'CE57E27AF329EBA4FAC3AB891F0407CE' + } + TestFrame { + time: 2272 + hash: '41BA853C3403F68A23E708DF82E21C53' + } + TestFrame { + time: 2288 + hash: 'DCF2867C127E041970047EC8F3EDC04F' + } + TestFrame { + time: 2304 + hash: '675EBBDD22DD22CE45993DF4AF1ACFE9' + } + TestFrame { + time: 2320 + hash: 'A350B70C5238A340E85FD4A3EC0390A3' + } + TestFrame { + time: 2336 + hash: '675EBBDD22DD22CE45993DF4AF1ACFE9' + } + TestFrame { + time: 2352 + hash: '675EBBDD22DD22CE45993DF4AF1ACFE9' + } + TestFrame { + time: 2368 + hash: '675EBBDD22DD22CE45993DF4AF1ACFE9' + } + TestFrame { + time: 2384 + hash: '675EBBDD22DD22CE45993DF4AF1ACFE9' + } + TestFrame { + time: 2400 + hash: 'DCF2867C127E041970047EC8F3EDC04F' + } + TestFrame { + time: 2416 + hash: 'DCF2867C127E041970047EC8F3EDC04F' + } + TestFrame { + time: 2432 + hash: '675EBBDD22DD22CE45993DF4AF1ACFE9' + } + TestFrame { + time: 2448 + hash: '675EBBDD22DD22CE45993DF4AF1ACFE9' + } + TestFrame { + time: 2464 + hash: '675EBBDD22DD22CE45993DF4AF1ACFE9' + } + TestFrame { + time: 2480 + hash: '675EBBDD22DD22CE45993DF4AF1ACFE9' + } + TestFrame { + time: 2496 + hash: 'A350B70C5238A340E85FD4A3EC0390A3' + } + TestFrame { + time: 2512 + hash: 'A350B70C5238A340E85FD4A3EC0390A3' + } + TestFrame { + time: 3504 + hash: 'A350B70C5238A340E85FD4A3EC0390A3' + } + TestFrame { + time: 3520 + hash: 'A350B70C5238A340E85FD4A3EC0390A3' + } + TestFrame { + time: 3536 + hash: '675EBBDD22DD22CE45993DF4AF1ACFE9' + } + TestFrame { + time: 3552 + hash: 'DCF2867C127E041970047EC8F3EDC04F' + } + TestFrame { + time: 3568 + hash: 'CE57E27AF329EBA4FAC3AB891F0407CE' + } + TestFrame { + time: 3584 + hash: '3042003C067B257DE2CB32F650DDE693' + } + TestFrame { + time: 3600 + hash: 'E74FE4A6BD92CBE8629C8BC8A870104D' + } + TestFrame { + time: 3616 + hash: 'E11455D4E23A5A865E222A7ABA4BA4F9' + } + TestFrame { + time: 3632 + hash: '8757668E56BE6449EC375F0B8FED1BE3' + } + TestFrame { + time: 3648 + hash: '53AE93140252373EAA4D9DA73756BD8E' + } + TestFrame { + time: 3664 + hash: 'A88A8129259F86DF5A73ADDC3649AD37' + } + TestFrame { + time: 3680 + hash: '630D90EEF2673A69E8EBC4EF1BA40E81' + } + TestFrame { + time: 3696 + hash: 'B7208D103B63A936DFF8DD8ED224237F' + } + TestFrame { + time: 3712 + hash: '1516C3547C7CF64832B3BC7DA7C44521' + } + TestFrame { + time: 3728 + hash: '49F5D6FD45C195A8D245B7FEFC1277AB' + } + TestFrame { + time: 3744 + hash: 'F5AFD9CF8FFE27E9992454B9E68688CB' + } + TestFrame { + time: 3760 + hash: '7A4528B000A4EA142D1C77407FA1F581' + } + TestFrame { + time: 3776 + hash: '5F18A81707F23D377E81A27C1FC41CE9' + } + TestFrame { + time: 3792 + hash: '005ACBEF952A8EE536E6308A48223E65' + } + TestFrame { + time: 3808 + hash: '85C135EF72D3D25658A3663E69FFB7C2' + } + TestFrame { + time: 3824 + hash: '7C27EF654E645679C90520D6CF00B0C4' + } + TestFrame { + time: 3840 + hash: '20258F07C613958C32F783466771391A' + } + TestFrame { + time: 3856 + hash: '9650FD0364C01B11E4F5DCCE51D008AF' + } + TestFrame { + time: 3872 + hash: 'F340CDF60C6D4C29D26B7202A093EC70' + } + TestFrame { + time: 3888 + hash: 'D754D35D0793F9F7D4F6249A874E4C45' + } + TestFrame { + time: 3904 + hash: '79EC710576427DF73DD03F39FBA6E2EB' + } + TestFrame { + time: 3920 + hash: '45281A70021F81DBEF30334B1480DA1B' + } + TestFrame { + time: 3936 + hash: 'FFD39C1122FE2F7877EF30591B539B40' + } + TestFrame { + time: 3952 + hash: '4AC43A03CC6F2020AB5F894D704092AC' + } + TestFrame { + time: 3968 + hash: 'C1A7B7D6D64AC5584C073C2881290696' + } + TestFrame { + time: 3984 + hash: '29ECE1BCA4D21FB5862091317D430A13' + } + TestFrame { + time: 4000 + hash: '29ECE1BCA4D21FB5862091317D430A13' + } + TestFrame { + time: 4016 + hash: '29ECE1BCA4D21FB5862091317D430A13' + } + TestFrame { + time: 4032 + hash: '29ECE1BCA4D21FB5862091317D430A13' + } + TestFrame { + time: 4048 + hash: '29ECE1BCA4D21FB5862091317D430A13' + } + TestFrame { + time: 4064 + hash: 'C1A7B7D6D64AC5584C073C2881290696' + } + TestFrame { + time: 4080 + hash: 'C1A7B7D6D64AC5584C073C2881290696' + } + TestFrame { + time: 4096 + hash: '4AC43A03CC6F2020AB5F894D704092AC' + } + TestFrame { + time: 4112 + hash: '4AC43A03CC6F2020AB5F894D704092AC' + } + TestFrame { + time: 4128 + hash: 'FFD39C1122FE2F7877EF30591B539B40' + } + TestFrame { + time: 4144 + hash: '62A7133012348F2EC3A388FB685ECC3F' + } + TestFrame { + time: 4160 + hash: '45281A70021F81DBEF30334B1480DA1B' + } + TestFrame { + time: 4176 + hash: '6CC9DE62A0C8FA5E42EAC1B01E99AC32' + } + TestFrame { + time: 4192 + hash: '79EC710576427DF73DD03F39FBA6E2EB' + } + TestFrame { + time: 4208 + hash: '5BE4F5C67941EFB6FCEA363C79F1E321' + } + TestFrame { + time: 4224 + hash: '7D9096B1EB940C82A37BAF39EF3CCF3E' + } + TestFrame { + time: 4240 + hash: 'E87B00BFC2C2A75A4234EC02A057AD3A' + } + TestFrame { + time: 4256 + hash: 'DA60100DC55023C3BAB367D97C8F6A85' + } + TestFrame { + time: 4272 + hash: 'DC98A9BDD99367C1E9B838D4BE489DCC' + } + TestFrame { + time: 4288 + hash: 'B2C778A5EFF5F01EDC54F03D8B4DE8C7' + } + TestFrame { + time: 4304 + hash: '9650FD0364C01B11E4F5DCCE51D008AF' + } + TestFrame { + time: 4320 + hash: '2CB09D9655ECC30AE6A591B28C0D355C' + } + TestFrame { + time: 4336 + hash: '4DB9BC6C11CAF1D77794C2EABB62A44E' + } + TestFrame { + time: 4352 + hash: 'CE2B5DD7418868ACF86FEA6AD19CC0C5' + } + TestFrame { + time: 4368 + hash: 'C4F844EE71F23635BB3EC7375F6A134F' + } + TestFrame { + time: 4384 + hash: '4E1FDA8A0495EF968C1CFFB1257426D7' + } + TestFrame { + time: 4400 + hash: '19D2AE617A49B57DD012677E2834469C' + } + TestFrame { + time: 4416 + hash: 'F438E8D2C16B5DE677924C8411219B19' + } + TestFrame { + time: 4432 + hash: '005ACBEF952A8EE536E6308A48223E65' + } + TestFrame { + time: 4448 + hash: '87B71778D52CD8563D171151D4D32407' + } + TestFrame { + time: 4464 + hash: '691CD8BF5C7802FF6C5024827A379FC6' + } + TestFrame { + time: 4480 + hash: 'AB442C0173C3D221B6782D28001DAC77' + } + TestFrame { + time: 4496 + hash: '6F886D4538704C2FAD4D84C68214109F' + } + TestFrame { + time: 4512 + hash: '56D39F233FAE41C60499D6161F891CBC' + } + TestFrame { + time: 4528 + hash: '95D987C3FD1352FB81C42C63634FE53B' + } + TestFrame { + time: 4544 + hash: '96DC84C0C548021910E7C5B580179054' + } + TestFrame { + time: 4560 + hash: 'DDB71CBD57F6E43744D533D4F72B08DB' + } + TestFrame { + time: 4576 + hash: 'F7AB4B197BEA455B22F259913438D207' + } + TestFrame { + time: 4592 + hash: '2AD64CB01C9D50E0118D5ECE0A644DF2' + } + TestFrame { + time: 4608 + hash: '6579681C59DD571DF0EE4429D74FB5C7' + } + TestFrame { + time: 4624 + hash: '630D90EEF2673A69E8EBC4EF1BA40E81' + } + TestFrame { + time: 4640 + hash: '3DB5E30EF19EA693C21CCF72892C4390' + } + TestFrame { + time: 4656 + hash: '721D7061811B5439C2E8E395917494BC' + } + TestFrame { + time: 4672 + hash: 'BC426FB7C31751665B0D3F16E2CB0173' + } + TestFrame { + time: 4688 + hash: 'E11455D4E23A5A865E222A7ABA4BA4F9' + } + TestFrame { + time: 4704 + hash: '3042003C067B257DE2CB32F650DDE693' + } + TestFrame { + time: 4720 + hash: 'DCF2867C127E041970047EC8F3EDC04F' + } + TestFrame { + time: 4736 + hash: '675EBBDD22DD22CE45993DF4AF1ACFE9' + } + TestFrame { + time: 4752 + hash: '41BA853C3403F68A23E708DF82E21C53' + } + TestFrame { + time: 4768 + hash: 'A725B59B4947357546BBFC7DF3D830AF' + } + TestFrame { + time: 4784 + hash: '336D31586171F22D541B989D24B95CBB' + } + TestFrame { + time: 4800 + hash: 'F0D8132489C2F2EF760E905B3C093726' + } + TestFrame { + time: 4816 + hash: 'E11455D4E23A5A865E222A7ABA4BA4F9' + } + TestFrame { + time: 4832 + hash: 'DD60CBAFF6F34027474E92315DBC0EBC' + } + TestFrame { + time: 4848 + hash: '8757668E56BE6449EC375F0B8FED1BE3' + } + TestFrame { + time: 4864 + hash: 'BC426FB7C31751665B0D3F16E2CB0173' + } + TestFrame { + time: 4880 + hash: 'B3F4A2165EC1EE971542B8EF89656CEA' + } + TestFrame { + time: 4896 + hash: '53AE93140252373EAA4D9DA73756BD8E' + } + TestFrame { + time: 4912 + hash: '721D7061811B5439C2E8E395917494BC' + } + TestFrame { + time: 4928 + hash: 'AF3120FE262D2489C0ED33FBBEE1549F' + } + TestFrame { + time: 4944 + hash: 'A8B624EBFC9AB713D1CE55F318A6E90D' + } + TestFrame { + time: 4960 + hash: 'A88A8129259F86DF5A73ADDC3649AD37' + } + TestFrame { + time: 4976 + hash: '3DB5E30EF19EA693C21CCF72892C4390' + } + TestFrame { + time: 4992 + hash: '3DB5E30EF19EA693C21CCF72892C4390' + } + TestFrame { + time: 5008 + hash: 'E553F365912586C6408C8C53B1B7D118' + } + TestFrame { + time: 5024 + hash: 'E553F365912586C6408C8C53B1B7D118' + } + TestFrame { + time: 5040 + hash: '1373545E43FFF7251CEC9E8375EA267F' + } + TestFrame { + time: 5056 + hash: '1373545E43FFF7251CEC9E8375EA267F' + } + TestFrame { + time: 5072 + hash: '1373545E43FFF7251CEC9E8375EA267F' + } + TestFrame { + time: 5088 + hash: '1373545E43FFF7251CEC9E8375EA267F' + } + TestFrame { + time: 5104 + hash: '1373545E43FFF7251CEC9E8375EA267F' + } + TestFrame { + time: 5120 + hash: '1373545E43FFF7251CEC9E8375EA267F' + } + TestFrame { + time: 5136 + hash: '1373545E43FFF7251CEC9E8375EA267F' + } + TestFrame { + time: 5152 + hash: 'E553F365912586C6408C8C53B1B7D118' + } + TestFrame { + time: 5168 + hash: 'E553F365912586C6408C8C53B1B7D118' + } + TestFrame { + time: 5184 + hash: '3DB5E30EF19EA693C21CCF72892C4390' + } + TestFrame { + time: 5200 + hash: '3DB5E30EF19EA693C21CCF72892C4390' + } + TestFrame { + time: 5216 + hash: 'A88A8129259F86DF5A73ADDC3649AD37' + } + TestFrame { + time: 5232 + hash: 'A8B624EBFC9AB713D1CE55F318A6E90D' + } + TestFrame { + time: 5248 + hash: 'AF3120FE262D2489C0ED33FBBEE1549F' + } + TestFrame { + time: 5264 + hash: '721D7061811B5439C2E8E395917494BC' + } + TestFrame { + time: 5280 + hash: '53AE93140252373EAA4D9DA73756BD8E' + } + TestFrame { + time: 5296 + hash: 'B3F4A2165EC1EE971542B8EF89656CEA' + } + TestFrame { + time: 5312 + hash: '0C20D12464ABBDC45041EA5D9F2719B1' + } + TestFrame { + time: 5328 + hash: '8757668E56BE6449EC375F0B8FED1BE3' + } + TestFrame { + time: 5344 + hash: 'EF8941674CB61F54853DC33652BB854E' + } + TestFrame { + time: 5360 + hash: 'E11455D4E23A5A865E222A7ABA4BA4F9' + } + TestFrame { + time: 5376 + hash: '6D63FB5C8A80F0280E88B2CDF8641BB9' + } + TestFrame { + time: 5392 + hash: 'E74FE4A6BD92CBE8629C8BC8A870104D' + } + TestFrame { + time: 5408 + hash: '3042003C067B257DE2CB32F650DDE693' + } + TestFrame { + time: 5424 + hash: 'CE57E27AF329EBA4FAC3AB891F0407CE' + } + TestFrame { + time: 5440 + hash: 'DCF2867C127E041970047EC8F3EDC04F' + } + TestFrame { + time: 5456 + hash: 'A350B70C5238A340E85FD4A3EC0390A3' + } + TestFrame { + time: 5472 + hash: '675EBBDD22DD22CE45993DF4AF1ACFE9' + } + TestFrame { + time: 5488 + hash: 'DCF2867C127E041970047EC8F3EDC04F' + } + TestFrame { + time: 5504 + hash: '41BA853C3403F68A23E708DF82E21C53' + } + TestFrame { + time: 5520 + hash: 'CE57E27AF329EBA4FAC3AB891F0407CE' + } + TestFrame { + time: 5536 + hash: 'CE57E27AF329EBA4FAC3AB891F0407CE' + } + TestFrame { + time: 5552 + hash: 'A725B59B4947357546BBFC7DF3D830AF' + } + TestFrame { + time: 5568 + hash: 'A725B59B4947357546BBFC7DF3D830AF' + } + TestFrame { + time: 5584 + hash: '3042003C067B257DE2CB32F650DDE693' + } + TestFrame { + time: 5600 + hash: '3042003C067B257DE2CB32F650DDE693' + } + TestFrame { + time: 5616 + hash: '3042003C067B257DE2CB32F650DDE693' + } + TestFrame { + time: 5632 + hash: '3042003C067B257DE2CB32F650DDE693' + } + TestFrame { + time: 5648 + hash: '3042003C067B257DE2CB32F650DDE693' + } + TestFrame { + time: 5664 + hash: '3042003C067B257DE2CB32F650DDE693' + } + TestFrame { + time: 5680 + hash: '3042003C067B257DE2CB32F650DDE693' + } + TestFrame { + time: 5696 + hash: '3042003C067B257DE2CB32F650DDE693' + } + TestFrame { + time: 5712 + hash: 'A725B59B4947357546BBFC7DF3D830AF' + } + TestFrame { + time: 5728 + hash: 'A725B59B4947357546BBFC7DF3D830AF' + } + TestFrame { + time: 5744 + hash: 'CE57E27AF329EBA4FAC3AB891F0407CE' + } + TestFrame { + time: 5760 + hash: '41BA853C3403F68A23E708DF82E21C53' + } + TestFrame { + time: 5776 + hash: '41BA853C3403F68A23E708DF82E21C53' + } + TestFrame { + time: 5792 + hash: 'DCF2867C127E041970047EC8F3EDC04F' + } + TestFrame { + time: 5808 + hash: '675EBBDD22DD22CE45993DF4AF1ACFE9' + } + TestFrame { + time: 5824 + hash: 'A350B70C5238A340E85FD4A3EC0390A3' + } + TestFrame { + time: 5840 + hash: '675EBBDD22DD22CE45993DF4AF1ACFE9' + } + TestFrame { + time: 5856 + hash: '675EBBDD22DD22CE45993DF4AF1ACFE9' + } + TestFrame { + time: 5872 + hash: '675EBBDD22DD22CE45993DF4AF1ACFE9' + } + TestFrame { + time: 5888 + hash: '675EBBDD22DD22CE45993DF4AF1ACFE9' + } + TestFrame { + time: 5904 + hash: 'DCF2867C127E041970047EC8F3EDC04F' + } + TestFrame { + time: 5920 + hash: 'DCF2867C127E041970047EC8F3EDC04F' + } + TestFrame { + time: 5936 + hash: '675EBBDD22DD22CE45993DF4AF1ACFE9' + } + TestFrame { + time: 5952 + hash: '675EBBDD22DD22CE45993DF4AF1ACFE9' + } + TestFrame { + time: 5968 + hash: '675EBBDD22DD22CE45993DF4AF1ACFE9' + } + TestFrame { + time: 5984 + hash: '675EBBDD22DD22CE45993DF4AF1ACFE9' + } + TestFrame { + time: 6000 + hash: 'A350B70C5238A340E85FD4A3EC0390A3' + } +} diff --git a/tests/auto/declarative/visual/pauseAnimation/pauseAnimation.qml b/tests/auto/declarative/visual/pauseAnimation/pauseAnimation.qml new file mode 100644 index 0000000..5c00f58 --- /dev/null +++ b/tests/auto/declarative/visual/pauseAnimation/pauseAnimation.qml @@ -0,0 +1,28 @@ +Rect { + id: rect + width: 120 + height: 200 + color: "white" + Image { + id: img + source: "pics/qtlogo.png" + x: 60-width/2 + y: 200-height + y: SequentialAnimation { + running: true + repeat: true + NumericAnimation { + to: 0; duration: 500 + easing: "easeInOutQuad" + } + NumericAnimation { + to: 200-img.height + easing: "easeOutBounce" + duration: 2000 + } + PauseAnimation { + duration: 1000 + } + } + } +} diff --git a/tests/auto/declarative/visual/pauseAnimation/pics/qtlogo.png b/tests/auto/declarative/visual/pauseAnimation/pics/qtlogo.png Binary files differnew file mode 100644 index 0000000..399bd0b --- /dev/null +++ b/tests/auto/declarative/visual/pauseAnimation/pics/qtlogo.png diff --git a/tests/auto/declarative/visual/pauseAnimation/test b/tests/auto/declarative/visual/pauseAnimation/test new file mode 100644 index 0000000..85bc3c1 --- /dev/null +++ b/tests/auto/declarative/visual/pauseAnimation/test @@ -0,0 +1 @@ +pauseAnimation.qml diff --git a/tests/auto/declarative/visual/qfxtext/elide/data/raster/image0.png b/tests/auto/declarative/visual/qfxtext/elide/data/raster/image0.png Binary files differnew file mode 100644 index 0000000..05dc9ab --- /dev/null +++ b/tests/auto/declarative/visual/qfxtext/elide/data/raster/image0.png diff --git a/tests/auto/declarative/visual/qfxtext/elide/data/raster/manifest.qml b/tests/auto/declarative/visual/qfxtext/elide/data/raster/manifest.qml new file mode 100644 index 0000000..6d900f5 --- /dev/null +++ b/tests/auto/declarative/visual/qfxtext/elide/data/raster/manifest.qml @@ -0,0 +1,6 @@ +TestLog { + TestFullFrame { + time: 0 + frameId: 0 + } +} diff --git a/tests/auto/declarative/visual/qfxtext/elide/elide.qml b/tests/auto/declarative/visual/qfxtext/elide/elide.qml new file mode 100644 index 0000000..23e6885 --- /dev/null +++ b/tests/auto/declarative/visual/qfxtext/elide/elide.qml @@ -0,0 +1,33 @@ +Rect { + width: contents.width + height: contents.height + VerticalLayout { + width: 80 + height: Text.height*4 + Text { + elide: "ElideLeft" + text: "aaa bbb ccc ddd eee fff" + width: 80 + color: "white" + id: Text + } + Text { + elide: "ElideMiddle" + text: "aaa bbb ccc ddd eee fff" + width: 80 + color: "white" + } + Text { + elide: "ElideRight" + text: "aaa bbb ccc ddd eee fff" + width: 80 + color: "white" + } + Text { + elide: "ElideNone" + text: "aaa bbb ccc ddd eee fff" + width: 80 + color: "white" + } + } +} diff --git a/tests/auto/declarative/visual/qfxtext/elide/test b/tests/auto/declarative/visual/qfxtext/elide/test new file mode 100644 index 0000000..bde7c7c --- /dev/null +++ b/tests/auto/declarative/visual/qfxtext/elide/test @@ -0,0 +1 @@ +elide.qml diff --git a/tests/auto/declarative/visual/repeater/basic1/basic1.qml b/tests/auto/declarative/visual/repeater/basic1/basic1.qml new file mode 100644 index 0000000..ba8f44d --- /dev/null +++ b/tests/auto/declarative/visual/repeater/basic1/basic1.qml @@ -0,0 +1,26 @@ +Rect { + color: "blue" + width: 300 + height: 200 + id: Page + HorizontalLayout { + Repeater { + component: Rect { + color: "red" + width: 100 + height: 100 + Text { + text: name + } + } + dataSource: ListModel { + ListElement { + name: "January" + } + ListElement { + name: "February" + } + } + } + } +} diff --git a/tests/auto/declarative/visual/repeater/basic1/data/raster/image0.png b/tests/auto/declarative/visual/repeater/basic1/data/raster/image0.png Binary files differnew file mode 100644 index 0000000..868eaa3 --- /dev/null +++ b/tests/auto/declarative/visual/repeater/basic1/data/raster/image0.png diff --git a/tests/auto/declarative/visual/repeater/basic1/data/raster/manifest.qml b/tests/auto/declarative/visual/repeater/basic1/data/raster/manifest.qml new file mode 100644 index 0000000..6d900f5 --- /dev/null +++ b/tests/auto/declarative/visual/repeater/basic1/data/raster/manifest.qml @@ -0,0 +1,6 @@ +TestLog { + TestFullFrame { + time: 0 + frameId: 0 + } +} diff --git a/tests/auto/declarative/visual/repeater/basic1/test b/tests/auto/declarative/visual/repeater/basic1/test new file mode 100644 index 0000000..49fcf5a --- /dev/null +++ b/tests/auto/declarative/visual/repeater/basic1/test @@ -0,0 +1 @@ +basic1.qml diff --git a/tests/auto/declarative/visual/repeater/basic2/basic2.qml b/tests/auto/declarative/visual/repeater/basic2/basic2.qml new file mode 100644 index 0000000..d975ea4 --- /dev/null +++ b/tests/auto/declarative/visual/repeater/basic2/basic2.qml @@ -0,0 +1,30 @@ +Rect { + color: "blue" + width: 300 + height: 200 + id: Page + Component { + id: Delegate + Rect { + color: "red" + width: 100 + height: 100 + Text { + text: name + } + } + } + HorizontalLayout { + Repeater { + component: Delegate + dataSource: ListModel { + ListElement { + name: "January" + } + ListElement { + name: "February" + } + } + } + } +} diff --git a/tests/auto/declarative/visual/repeater/basic2/data/raster/image0.png b/tests/auto/declarative/visual/repeater/basic2/data/raster/image0.png Binary files differnew file mode 100644 index 0000000..868eaa3 --- /dev/null +++ b/tests/auto/declarative/visual/repeater/basic2/data/raster/image0.png diff --git a/tests/auto/declarative/visual/repeater/basic2/data/raster/manifest.qml b/tests/auto/declarative/visual/repeater/basic2/data/raster/manifest.qml new file mode 100644 index 0000000..6d900f5 --- /dev/null +++ b/tests/auto/declarative/visual/repeater/basic2/data/raster/manifest.qml @@ -0,0 +1,6 @@ +TestLog { + TestFullFrame { + time: 0 + frameId: 0 + } +} diff --git a/tests/auto/declarative/visual/repeater/basic2/test b/tests/auto/declarative/visual/repeater/basic2/test new file mode 100644 index 0000000..eb79495 --- /dev/null +++ b/tests/auto/declarative/visual/repeater/basic2/test @@ -0,0 +1 @@ +basic2.qml diff --git a/tests/auto/declarative/visual/repeater/basic3/basic3.qml b/tests/auto/declarative/visual/repeater/basic3/basic3.qml new file mode 100644 index 0000000..cecba33 --- /dev/null +++ b/tests/auto/declarative/visual/repeater/basic3/basic3.qml @@ -0,0 +1,28 @@ +Rect { + color: "blue" + width: 300 + height: 200 + id: Page + ListModel { + id: DataSource + ListElement { + name: "January" + } + ListElement { + name: "February" + } + } + HorizontalLayout { + Repeater { + dataSource: DataSource + component: Rect { + color: "red" + width: 100 + height: 100 + Text { + text: name + } + } + } + } +} diff --git a/tests/auto/declarative/visual/repeater/basic3/data/raster/image0.png b/tests/auto/declarative/visual/repeater/basic3/data/raster/image0.png Binary files differnew file mode 100644 index 0000000..868eaa3 --- /dev/null +++ b/tests/auto/declarative/visual/repeater/basic3/data/raster/image0.png diff --git a/tests/auto/declarative/visual/repeater/basic3/data/raster/manifest.qml b/tests/auto/declarative/visual/repeater/basic3/data/raster/manifest.qml new file mode 100644 index 0000000..47d36c3 --- /dev/null +++ b/tests/auto/declarative/visual/repeater/basic3/data/raster/manifest.qml @@ -0,0 +1,13 @@ +TestLog { + TestFullFrame { + time: 0 + frameId: 0 + } + TestKey { + time: 1296 + type: 6 + modifiers: 0 + key: 16777251 + text: '' + } +} diff --git a/tests/auto/declarative/visual/repeater/basic3/test b/tests/auto/declarative/visual/repeater/basic3/test new file mode 100644 index 0000000..9ec306b --- /dev/null +++ b/tests/auto/declarative/visual/repeater/basic3/test @@ -0,0 +1 @@ +basic3.qml diff --git a/tests/auto/declarative/visual/repeater/basic4/basic4.qml b/tests/auto/declarative/visual/repeater/basic4/basic4.qml new file mode 100644 index 0000000..050a2c5 --- /dev/null +++ b/tests/auto/declarative/visual/repeater/basic4/basic4.qml @@ -0,0 +1,32 @@ +Rect { + color: "blue" + width: 300 + height: 200 + id: Page + ListModel { + id: DataSource + ListElement { + name: "January" + } + ListElement { + name: "February" + } + } + Component { + id: Delegate + Rect { + color: "red" + width: 100 + height: 100 + Text { + text: name + } + } + } + HorizontalLayout { + Repeater { + dataSource: DataSource + component: Delegate + } + } +} diff --git a/tests/auto/declarative/visual/repeater/basic4/data/raster/image0.png b/tests/auto/declarative/visual/repeater/basic4/data/raster/image0.png Binary files differnew file mode 100644 index 0000000..868eaa3 --- /dev/null +++ b/tests/auto/declarative/visual/repeater/basic4/data/raster/image0.png diff --git a/tests/auto/declarative/visual/repeater/basic4/data/raster/manifest.qml b/tests/auto/declarative/visual/repeater/basic4/data/raster/manifest.qml new file mode 100644 index 0000000..6d900f5 --- /dev/null +++ b/tests/auto/declarative/visual/repeater/basic4/data/raster/manifest.qml @@ -0,0 +1,6 @@ +TestLog { + TestFullFrame { + time: 0 + frameId: 0 + } +} diff --git a/tests/auto/declarative/visual/repeater/basic4/test b/tests/auto/declarative/visual/repeater/basic4/test new file mode 100644 index 0000000..2a7f227 --- /dev/null +++ b/tests/auto/declarative/visual/repeater/basic4/test @@ -0,0 +1 @@ +basic4.qml diff --git a/tests/auto/declarative/visual/runtests.sh b/tests/auto/declarative/visual/runtests.sh new file mode 100755 index 0000000..4380884 --- /dev/null +++ b/tests/auto/declarative/visual/runtests.sh @@ -0,0 +1,3 @@ +#!/bin/sh +export QFX_USE_SIMPLECANVAS=1 +for a in `cat tests`; do ./tst_visual -testdir $a; done diff --git a/tests/auto/declarative/visual/tests b/tests/auto/declarative/visual/tests new file mode 100644 index 0000000..ca72e9e --- /dev/null +++ b/tests/auto/declarative/visual/tests @@ -0,0 +1,11 @@ +ListView/basic1 +ListView/basic2 +ListView/basic3 +ListView/basic4 +bindinganimation +repeater/basic1 +repeater/basic2 +repeater/basic3 +repeater/basic4 +webview/autosize +qfxtext/elide diff --git a/tests/auto/declarative/visual/tst_visual.cpp b/tests/auto/declarative/visual/tst_visual.cpp new file mode 100644 index 0000000..f540e62 --- /dev/null +++ b/tests/auto/declarative/visual/tst_visual.cpp @@ -0,0 +1,74 @@ +#include <qtest.h> +#include <QFxView> +#include <QApplication> +#include <QFxTestView> +#include <QFile> + +static QString testdir; +class tst_visual : public QObject +{ + Q_OBJECT +public: + tst_visual() {} + +private slots: + void visual(); +}; + +#ifdef QT_OPENGL_ES +#define RASTER_TESTDIR "/data/opengl" +#else +#define RASTER_TESTDIR "/data/raster" +#endif + +void tst_visual::visual() +{ + QVERIFY(!testdir.isEmpty()); + + QString filename = QLatin1String(QT_TEST_SOURCE_DIR) + "/" + testdir + "/test"; + qWarning() << "Using config:" << filename; + QFile configFile(filename); + QVERIFY(configFile.open(QIODevice::ReadOnly)); + + QString testfile = configFile.readLine().trimmed(); + QVERIFY(!testfile.isEmpty()); + + if(testfile.startsWith("QTDIR/")) { + testfile.remove(0, 6); + testfile.prepend(QLatin1String(QT_TEST_SOURCE_DIR) + "/../../../../"); + } else { + testfile.prepend(QLatin1String(QT_TEST_SOURCE_DIR) + "/" + testdir + "/"); + } + + QFxTestView *view = new QFxTestView(testfile, QLatin1String(QT_TEST_SOURCE_DIR) + "/" + testdir + RASTER_TESTDIR); + QVERIFY(view->runTest()); +} + +#include <QtTest/qtest_gui.h> + +int main(int argc, char *argv[]) +{ + int newArgc = 1; + char **newArgv = new char*[argc]; + + newArgv[0] = argv[0]; + + QApplication app(newArgc, newArgv); + + for(int ii = 1; ii < argc; ii++) { + if(QLatin1String(argv[ii]) == "-testdir" && (ii + 1) < argc) { + testdir = QLatin1String(argv[ii + 1]); + ii++; + } else { + newArgv[newArgc++] = argv[ii]; + } + } + + tst_visual tc; + int rv = QTest::qExec(&tc, newArgc, newArgv); + + delete [] newArgv; + return rv; +} + +#include "tst_visual.moc" diff --git a/tests/auto/declarative/visual/visual.pro b/tests/auto/declarative/visual/visual.pro new file mode 100644 index 0000000..203b691 --- /dev/null +++ b/tests/auto/declarative/visual/visual.pro @@ -0,0 +1,5 @@ +load(qttest_p4) +contains(QT_CONFIG,declarative): QT += declarative +SOURCES += tst_visual.cpp + +DEFINES += QT_TEST_SOURCE_DIR=\"\\\"$$PWD\\\"\" diff --git a/tests/auto/declarative/visual/webview/autosize/data/raster/image0.png b/tests/auto/declarative/visual/webview/autosize/data/raster/image0.png Binary files differnew file mode 100644 index 0000000..206952d --- /dev/null +++ b/tests/auto/declarative/visual/webview/autosize/data/raster/image0.png diff --git a/tests/auto/declarative/visual/webview/autosize/data/raster/manifest.qml b/tests/auto/declarative/visual/webview/autosize/data/raster/manifest.qml new file mode 100644 index 0000000..6d900f5 --- /dev/null +++ b/tests/auto/declarative/visual/webview/autosize/data/raster/manifest.qml @@ -0,0 +1,6 @@ +TestLog { + TestFullFrame { + time: 0 + frameId: 0 + } +} diff --git a/tests/auto/declarative/visual/webview/autosize/test b/tests/auto/declarative/visual/webview/autosize/test new file mode 100644 index 0000000..446d3f9 --- /dev/null +++ b/tests/auto/declarative/visual/webview/autosize/test @@ -0,0 +1 @@ +QTDIR/examples/declarative/webview/autosize.qml diff --git a/tests/auto/dynamicobject/dynamicobject.pro b/tests/auto/dynamicobject/dynamicobject.pro new file mode 100644 index 0000000..1b2a075 --- /dev/null +++ b/tests/auto/dynamicobject/dynamicobject.pro @@ -0,0 +1,6 @@ +load(qttest_p4) +SOURCES += tst_qobject.cpp qmetaobjectbuilder.cpp qdynamicmetaobject.cpp +HEADERS += qmetaobjectbuilder.h qdynamicmetaobject.h + +QT = core + diff --git a/tests/auto/dynamicobject/qdynamicmetaobject.cpp b/tests/auto/dynamicobject/qdynamicmetaobject.cpp new file mode 100644 index 0000000..b44555f --- /dev/null +++ b/tests/auto/dynamicobject/qdynamicmetaobject.cpp @@ -0,0 +1,254 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +****************************************************************************/ + +#include <qcoreapplication.h> + +#include <qmetaobject.h> + +#include "qobject.h" +#include "private/qobject_p.h" +#include "qmetaobjectbuilder.h" +#include "qdynamicmetaobject.h" + +class QDynamicMetaObjectData +{ +public: + QDynamicMetaObjectData() : ref(1), baseMeta(0), meta(0) {} + ~QDynamicMetaObjectData() { qFree(meta); } + + QAtomicInt ref; + QMetaObjectBuilder builder; + const QMetaObject *baseMeta; + QMetaObject *meta; +}; + +/*! + \class QDynamicMetaObject + \brief The QDynamicMetaObject class allows adding signals, slots and properties to + QObjects at runtime. + + Any QObject derived class can be extended by creating a QDynamicMetaObject + based on the QObject's QMetaObject. + + QObject::setDynamicMetaObject() is called to set the dynamic meta-object for + the QObject. + + \sa QMetaObject +*/ + +/*! + Constructs a dynamic meta-object based on \a baseMetaObject. + + QObject::setDynamicMetaObject() should be called to install it. +*/ +QDynamicMetaObject::QDynamicMetaObject(const QMetaObject *baseMetaObject) +{ + data_ptr = new QDynamicMetaObjectData; + data_ptr->baseMeta = baseMetaObject; + data_ptr->builder.setSuperClass(data_ptr->baseMeta); + data_ptr->builder.setClassName(data_ptr->baseMeta->className()); + updateMetaData(); +} + +/*! + Constructs a dynamic meta-object that is a copy of \a other. +*/ +QDynamicMetaObject::QDynamicMetaObject(const QDynamicMetaObject &other) +{ + data_ptr = other.data_ptr; + data_ptr->ref.ref(); +} + +/*! + Destroys the dynamic meta-ovject. +*/ +QDynamicMetaObject::~QDynamicMetaObject() +{ + if (!data_ptr->ref.deref()) + delete data_ptr; +} + +/*! + Copies the dynamic metadata from \a that. The static metadata must be identical, + i.e. the dynamic metadata is constructed for the same class. +*/ +QDynamicMetaObject &QDynamicMetaObject::operator=(const QDynamicMetaObject &that) +{ + Q_ASSERT(data_ptr->baseMeta == that.data_ptr->baseMeta); + qAtomicAssign(data_ptr, that.data_ptr); + return *this; +} + +/*! + \internal +*/ +QDynamicMetaObject &QDynamicMetaObject::operator=(const QMetaObject &that) +{ + static_cast<QMetaObject*>(this)->d = that.d; + return *this; +} + +/*! + \internal +*/ +void QDynamicMetaObject::detach() +{ + if (data_ptr->ref == 1) + return; + + //XXX copy builder faster. + QByteArray buf; + QDataStream ds(&buf, QIODevice::ReadWrite); + data_ptr->builder.serialize(ds); + if (!data_ptr->ref.deref()) + delete data_ptr; + data_ptr = new QDynamicMetaObjectData; + QMap<QByteArray, const QMetaObject *> refs; + data_ptr->builder.deserialize(ds, refs); + updateMetaData(); +} + +/*! + Adds the signal with \a signature. +*/ +void QDynamicMetaObject::addSignal(const char *signature) +{ + detach(); + data_ptr->builder.addSignal(signature); + updateMetaData(); +} + +/*! + Adds the signal with \a signature and sets the \a parameterNames. +*/ +void QDynamicMetaObject::addSignal(const char *signature, const QList<QByteArray> ¶meterNames) +{ + detach(); + QMetaMethodBuilder method = data_ptr->builder.addSignal(signature); + method.setParameterNames(parameterNames); + updateMetaData(); +} + +/*! + Adds the slot with \a signature. +*/ +void QDynamicMetaObject::addSlot(const char *signature) +{ + detach(); + data_ptr->builder.addSlot(signature); + updateMetaData(); +} + + +/*! + Adds the slot with \a signature and sets the \a parameterNames. +*/ +void QDynamicMetaObject::addSlot(const char *signature, const QList<QByteArray> ¶meterNames) +{ + detach(); + QMetaMethodBuilder method = data_ptr->builder.addSlot(signature); + method.setParameterNames(parameterNames); + updateMetaData(); +} + +/*! + Adds the property with \a name of \a type. If \a notifier specified it is + set as the change notifier for the property. +*/ +void QDynamicMetaObject::addProperty(const char *name, const char *type, const char *notifier) +{ + int notifierId = -1; + if (notifier) + notifierId = data_ptr->builder.indexOfSignal(notifier); + data_ptr->builder.addProperty(name, type, notifierId); + updateMetaData(); +} + +/*! + Adds the property with \a name of \a type. If \a notifierId is specified it is + set as the change notifier for the property. +*/ +void QDynamicMetaObject::addProperty(const char *name, const char *type, int notifierId) +{ + data_ptr->builder.addProperty(name, type, notifierId); + updateMetaData(); +} + +/*! + \reimp +*/ +int QDynamicMetaObject::metaCall(QObject *object, QMetaObject::Call _c, int _id, void **_a) +{ + if (_c == QMetaObject::InvokeMetaMethod && _id >= data_ptr->baseMeta->methodCount()) { + QMetaMethod metaMethod = method(_id); + if (metaMethod.methodType() == QMetaMethod::Slot) { + if (metaMethod.parameterTypes().count() == 0) { + static QList<QVariant> noArgs; + callSlot(object, _id, noArgs); + } else { + QList<QVariant> args; + for (int i = 0; i < metaMethod.parameterTypes().count(); ++i) { + int typeId = QVariant::nameToType(metaMethod.parameterTypes().at(i)); + args.append(QVariant(typeId, _a[i+1])); + } + callSlot(object, _id, args); + } + } else if (metaMethod.methodType() == QMetaMethod::Signal) + activate(object, _id, _a); + _id = -1; + } else if (_c == QMetaObject::ReadProperty && _id >= data_ptr->baseMeta->propertyCount()) { + *(reinterpret_cast<QVariant*>(_a[1])) = readProperty(object, _id); + _id = -1; + } else if (_c == QMetaObject::WriteProperty && _id >= data_ptr->baseMeta->propertyCount()) { + writeProperty(object, _id, *(reinterpret_cast<QVariant*>(_a[1]))); + if (property(_id).hasNotifySignal()) + activate(object, property(_id).notifySignalIndex(), 0); + _id = -1; + } else { + _id = object->qt_metacall(_c, _id, _a); + } + + return _id; +} + +/*! + The slot with \a id has been called for \a object. The parameters are available via \a args. +*/ +void QDynamicMetaObject::callSlot(QObject *object, int id, const QList<QVariant> &args) +{ + Q_UNUSED(object); + Q_UNUSED(id); + Q_UNUSED(args); +} + +/*! + The \a value of property with \a id has changed for \a object. +*/ +void QDynamicMetaObject::writeProperty(QObject *object, int id, const QVariant &value) +{ + Q_UNUSED(object); + Q_UNUSED(id); + Q_UNUSED(value); +} + +/*! + Return the value of the property with \a id belonging to \a object. +*/ +QVariant QDynamicMetaObject::readProperty(QObject *object, int id) const +{ + Q_UNUSED(object); + Q_UNUSED(id); + return QVariant(); +} + +void QDynamicMetaObject::updateMetaData() +{ + qFree(data_ptr->meta); + data_ptr->meta = data_ptr->builder.toMetaObject(); + *this = *data_ptr->meta; +} + diff --git a/tests/auto/dynamicobject/qdynamicmetaobject.h b/tests/auto/dynamicobject/qdynamicmetaobject.h new file mode 100644 index 0000000..747d118 --- /dev/null +++ b/tests/auto/dynamicobject/qdynamicmetaobject.h @@ -0,0 +1,47 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +****************************************************************************/ + +#ifndef _QDYNAMICMETAOBJECT_H_ +#define _QDYNAMICMETAOBJECT_H_ + +#include <qmetaobject.h> +#include <qobject.h> + +class QDynamicMetaObjectData; + +class QDynamicMetaObject : public QAbstractDynamicMetaObject +{ +public: + QDynamicMetaObject(const QMetaObject *baseMetaObject); + QDynamicMetaObject(const QDynamicMetaObject &other); + virtual ~QDynamicMetaObject(); + + QDynamicMetaObject &operator=(const QDynamicMetaObject &that); + + void addSignal(const char *sigName); + void addSignal(const char *sigName, const QList<QByteArray> ¶meterNames); + void addSlot(const char *slotName); + void addSlot(const char *slotName, const QList<QByteArray> ¶meterNames); + void addProperty(const char *name, const char *type, const char *notifier); + void addProperty(const char *name, const char *type, int notifierId=-1); + +protected: + virtual int metaCall(QObject *object, QMetaObject::Call _c, int _id, void **_a); + virtual void callSlot(QObject *object, int id, const QList<QVariant> &args); + virtual void writeProperty(QObject *object, int id, const QVariant &value); + virtual QVariant readProperty(QObject *object, int id) const; + +private: + void detach(); + void updateMetaData(); + QDynamicMetaObject &operator=(const QMetaObject &that); + +private: + QDynamicMetaObjectData *data_ptr; +}; + +#endif diff --git a/tests/auto/dynamicobject/qmetaobjectbuilder.cpp b/tests/auto/dynamicobject/qmetaobjectbuilder.cpp new file mode 100644 index 0000000..3927f6a --- /dev/null +++ b/tests/auto/dynamicobject/qmetaobjectbuilder.cpp @@ -0,0 +1,2347 @@ +/**************************************************************************** +** +** This file is part of the $PACKAGE_NAME$. +** +** Copyright (C) $THISYEAR$ $COMPANY_NAME$. +** +** $QT_EXTENDED_DUAL_LICENSE$ +** +****************************************************************************/ + +#include "qmetaobjectbuilder.h" +#include <QDebug> + +/*! + \class QMetaObjectBuilder + \brief The QMetaObjectBuilder class supports the building of QMetaObject objects at runtime. + + See the QDynamicMetaObject class documentation for an example + of using this class. + + \sa QDynamicMetaObject, QDynamicObject +*/ + +/*! + \enum QMetaObjectBuilder::AddMember + This enum defines which members of QMetaObject should be copied by QMetaObjectBuilder::addMetaObject() + + \value ClassName Add the class name. + \value SuperClass Add the super class. + \value Methods Add methods that aren't signals or slots. + \value Signals Add signals. + \value Slots Add slots. + \value Constructors Add constructors. + \value Properties Add properties. + \value Enumerators Add enumerators. + \value ClassInfos Add items of class information. + \value RelatedMetaObjects Add related meta objects. + \value StaticMetacall Add the static metacall function. + \value PublicMethods Add public methods (ignored for signals). + \value ProtectedMethods Add protected methods (ignored for signals). + \value PrivateMethods All private methods (ignored for signals). + \value AllMembers Add all members. + \value AllPrimaryMembers Add everything except the class name, super class, and static metacall function. +*/ + +// copied from qmetaobject.cpp +// do not touch without touching the moc as well +enum PropertyFlags { + Invalid = 0x00000000, + Readable = 0x00000001, + Writable = 0x00000002, + Resettable = 0x00000004, + EnumOrFlag = 0x00000008, + StdCppSet = 0x00000100, +// Override = 0x00000200, + Designable = 0x00001000, + ResolveDesignable = 0x00002000, + Scriptable = 0x00004000, + ResolveScriptable = 0x00008000, + Stored = 0x00010000, + ResolveStored = 0x00020000, + Editable = 0x00040000, + ResolveEditable = 0x00080000, + User = 0x00100000, + ResolveUser = 0x00200000, + Notify = 0x00400000 +}; + +enum MethodFlags { + AccessPrivate = 0x00, + AccessProtected = 0x01, + AccessPublic = 0x02, + AccessMask = 0x03, //mask + + MethodMethod = 0x00, + MethodSignal = 0x04, + MethodSlot = 0x08, + MethodConstructor = 0x0c, + MethodTypeMask = 0x0c, + + MethodCompatibility = 0x10, + MethodCloned = 0x20, + MethodScriptable = 0x40 +}; + +struct QMetaObjectPrivate +{ + int revision; + int className; + int classInfoCount, classInfoData; + int methodCount, methodData; + int propertyCount, propertyData; + int enumeratorCount, enumeratorData; + int constructorCount, constructorData; +}; + +static inline const QMetaObjectPrivate *priv(const uint* data) +{ return reinterpret_cast<const QMetaObjectPrivate*>(data); } +// end of copied lines from qmetaobject.cpp + +class QMetaMethodBuilderPrivate +{ +public: + QMetaMethodBuilderPrivate + (QMetaMethod::MethodType _methodType, + const QByteArray& _signature, + const QByteArray& _returnType = QByteArray(), + QMetaMethod::Access _access = QMetaMethod::Public) + : signature(QMetaObject::normalizedSignature(_signature.constData())), + returnType(QMetaObject::normalizedType(_returnType)), + attributes(((int)_access) | (((int)_methodType) << 2)) + { + } + + QByteArray signature; + QByteArray returnType; + QList<QByteArray> parameterNames; + QByteArray tag; + int attributes; + + QMetaMethod::MethodType methodType() const + { + return (QMetaMethod::MethodType)((attributes & MethodTypeMask) >> 2); + } + + QMetaMethod::Access access() const + { + return (QMetaMethod::Access)(attributes & AccessMask); + } + + void setAccess(QMetaMethod::Access value) + { + attributes = ((attributes & ~AccessMask) | (int)value); + } +}; + +class QMetaPropertyBuilderPrivate +{ +public: + QMetaPropertyBuilderPrivate + (const QByteArray& _name, const QByteArray& _type, int notifierIdx=-1) + : name(_name), + type(QMetaObject::normalizedType(_type.constData())), + flags(Readable | Writable), notifySignal(-1) + { + if (notifierIdx >= 0) { + flags |= Notify; + notifySignal = notifierIdx; + } + } + + QByteArray name; + QByteArray type; + int flags; + int notifySignal; + + bool flag(int f) const + { + return ((flags & f) != 0); + } + + void setFlag(int f, bool value) + { + if (value) + flags |= f; + else + flags &= ~f; + } +}; + +class QMetaEnumBuilderPrivate +{ +public: + QMetaEnumBuilderPrivate(const QByteArray& _name) + : name(_name), isFlag(false) + { + } + + QByteArray name; + bool isFlag; + QList<QByteArray> keys; + QList<int> values; +}; + +class QMetaObjectBuilderPrivate +{ +public: + QMetaObjectBuilderPrivate() + { + superClass = &QObject::staticMetaObject; + staticMetacallFunction = 0; + } + + QByteArray className; + const QMetaObject *superClass; + QMetaObjectBuilder::StaticMetacallFunction staticMetacallFunction; + QList<QMetaMethodBuilderPrivate> methods; + QList<QMetaMethodBuilderPrivate> constructors; + QList<QMetaPropertyBuilderPrivate> properties; + QList<QByteArray> classInfoNames; + QList<QByteArray> classInfoValues; + QList<QMetaEnumBuilderPrivate> enumerators; + QList<const QMetaObject *> relatedMetaObjects; +}; + +/*! + Constructs a new QMetaObjectBuilder. +*/ +QMetaObjectBuilder::QMetaObjectBuilder() +{ + d = new QMetaObjectBuilderPrivate(); +} + +/*! + Constructs a new QMetaObjectBuilder which is a copy of the + meta object information in \a prototype. Note: the super class + contents for \a prototype are not copied, only the immediate + class that is defined by \a prototype. + + The \a members parameter indicates which members of \a prototype + should be added. The default is AllMembers. + + \sa addMetaObject() +*/ +QMetaObjectBuilder::QMetaObjectBuilder + (const QMetaObject *prototype, QMetaObjectBuilder::AddMembers members) +{ + d = new QMetaObjectBuilderPrivate(); + addMetaObject(prototype, members); +} + +/*! + Destroys this meta object builder. +*/ +QMetaObjectBuilder::~QMetaObjectBuilder() +{ + delete d; +} + +/*! + Returns the name of the class being constructed by this + meta object builder. The default value is an empty QByteArray. + + \sa setClassName(), superClass() +*/ +QByteArray QMetaObjectBuilder::className() const +{ + return d->className; +} + +/*! + Sets the \a name of the class being constructed by this + meta object builder. + + \sa className(), setSuperClass() +*/ +void QMetaObjectBuilder::setClassName(const QByteArray& name) +{ + d->className = name; +} + +/*! + Returns the superclass meta object of the class being constructed + by this meta object builder. The default value is the meta object + for QObject. + + \sa setSuperClass(), className() +*/ +const QMetaObject *QMetaObjectBuilder::superClass() const +{ + return d->superClass; +} + +/*! + Sets the superclass meta object of the class being constructed + by this meta object builder to \a meta. The \a meta parameter + must not be null. + + \sa superClass(), setClassName() +*/ +void QMetaObjectBuilder::setSuperClass(const QMetaObject *meta) +{ + Q_ASSERT(meta); + d->superClass = meta; +} + +/*! + Returns the number of methods in this class, excluding the number + of methods in the base class. These include signals and slots + as well as normal member functions. + + \sa addMethod(), method(), removeMethod(), indexOfMethod() +*/ +int QMetaObjectBuilder::methodCount() const +{ + return d->methods.size(); +} + +/*! + Returns the number of constructors in this class. + + \sa addConstructor(), constructor(), removeConstructor(), indexOfConstructor() +*/ +int QMetaObjectBuilder::constructorCount() const +{ + return d->constructors.size(); +} + +/*! + Returns the number of properties in this class, excluding the number + of properties in the base class. + + \sa addProperty(), property(), removeProperty(), indexOfProperty() +*/ +int QMetaObjectBuilder::propertyCount() const +{ + return d->properties.size(); +} + +/*! + Returns the number of enumerators in this class, excluding the + number of enumerators in the base class. + + \sa addEnumerator(), enumerator(), removeEnumerator() + \sa indexOfEnumerator() +*/ +int QMetaObjectBuilder::enumeratorCount() const +{ + return d->enumerators.size(); +} + +/*! + Returns the number of items of class information in this class, + exclusing the number of items of class information in the base class. + + \sa addClassInfo(), classInfoName(), classInfoValue(), removeClassInfo() + \sa indexOfClassInfo() +*/ +int QMetaObjectBuilder::classInfoCount() const +{ + return d->classInfoNames.size(); +} + +/*! + Returns the number of related meta objects that are associated + with this class. + + Related meta objects are used when resolving the enumerated type + associated with a property, where the enumerated type is in a + different class from the property. + + \sa addRelatedMetaObject(), relatedMetaObject() + \sa removeRelatedMetaObject() +*/ +int QMetaObjectBuilder::relatedMetaObjectCount() const +{ + return d->relatedMetaObjects.size(); +} + +/*! + Adds a new public method to this class with the specified \a signature. + Returns an object that can be used to adjust the other attributes + of the method. The \a signature will be normalized before it is + added to the class. + + \sa method(), methodCount(), removeMethod(), indexOfMethod() +*/ +QMetaMethodBuilder QMetaObjectBuilder::addMethod(const QByteArray& signature) +{ + int index = d->methods.size(); + d->methods.append(QMetaMethodBuilderPrivate(QMetaMethod::Method, signature)); + return QMetaMethodBuilder(this, index); +} + +/*! + Adds a new public method to this class with the specified + \a signature and \a returnType. Returns an object that can be + used to adjust the other attributes of the method. The \a signature + and \a returnType will be normalized before they are added to + the class. If \a returnType is empty, then it indicates that + the method has \c{void} as its return type. + + \sa method(), methodCount(), removeMethod(), indexOfMethod() +*/ +QMetaMethodBuilder QMetaObjectBuilder::addMethod + (const QByteArray& signature, const QByteArray& returnType) +{ + int index = d->methods.size(); + d->methods.append(QMetaMethodBuilderPrivate + (QMetaMethod::Method, signature, returnType)); + return QMetaMethodBuilder(this, index); +} + +/*! + Adds a new public method to this class that has the same information as + \a prototype. This is used to clone the methods of an existing + QMetaObject. Returns an object that can be used to adjust the + attributes of the method. + + This function will detect if \a prototype is an ordinary method, + signal, slot, or constructor and act accordingly. + + \sa method(), methodCount(), removeMethod(), indexOfMethod() +*/ +QMetaMethodBuilder QMetaObjectBuilder::addMethod(const QMetaMethod& prototype) +{ + QMetaMethodBuilder method; + if (prototype.methodType() == QMetaMethod::Method) + method = addMethod(prototype.signature()); + else if (prototype.methodType() == QMetaMethod::Signal) + method = addSignal(prototype.signature()); + else if (prototype.methodType() == QMetaMethod::Slot) + method = addSlot(prototype.signature()); + else if (prototype.methodType() == QMetaMethod::Constructor) + method = addConstructor(prototype.signature()); + method.setReturnType(prototype.typeName()); + method.setParameterNames(prototype.parameterNames()); + method.setTag(prototype.tag()); + method.setAccess(prototype.access()); + method.setAttributes(prototype.attributes()); + return method; +} + +/*! + Adds a new public slot to this class with the specified \a signature. + Returns an object that can be used to adjust the other attributes + of the slot. The \a signature will be normalized before it is + added to the class. + + \sa addMethod(), addSignal(), indexOfSlot() +*/ +QMetaMethodBuilder QMetaObjectBuilder::addSlot(const QByteArray& signature) +{ + int index = d->methods.size(); + d->methods.append(QMetaMethodBuilderPrivate(QMetaMethod::Slot, signature)); + return QMetaMethodBuilder(this, index); +} + +/*! + Adds a new signal to this class with the specified \a signature. + Returns an object that can be used to adjust the other attributes + of the signal. The \a signature will be normalized before it is + added to the class. + + \sa addMethod(), addSlot(), indexOfSignal() +*/ +QMetaMethodBuilder QMetaObjectBuilder::addSignal(const QByteArray& signature) +{ + int index = d->methods.size(); + d->methods.append(QMetaMethodBuilderPrivate + (QMetaMethod::Signal, signature, QByteArray(), QMetaMethod::Protected)); + return QMetaMethodBuilder(this, index); +} + +/*! + Adds a new constructor to this class with the specified \a signature. + Returns an object that can be used to adjust the other attributes + of the constructor. The \a signature will be normalized before it is + added to the class. + + \sa constructor(), constructorCount(), removeConstructor() + \sa indexOfConstructor() +*/ +QMetaMethodBuilder QMetaObjectBuilder::addConstructor(const QByteArray& signature) +{ + int index = d->constructors.size(); + d->constructors.append(QMetaMethodBuilderPrivate(QMetaMethod::Constructor, signature)); + return QMetaMethodBuilder(this, -(index + 1)); +} + +/*! + Adds a new constructor to this class that has the same information as + \a prototype. This is used to clone the constructors of an existing + QMetaObject. Returns an object that can be used to adjust the + attributes of the constructor. + + This function requires that \a prototype be a constructor. + + \sa constructor(), constructorCount(), removeConstructor() + \sa indexOfConstructor() +*/ +QMetaMethodBuilder QMetaObjectBuilder::addConstructor(const QMetaMethod& prototype) +{ + Q_ASSERT(prototype.methodType() == QMetaMethod::Constructor); + QMetaMethodBuilder ctor = addConstructor(prototype.signature()); + ctor.setReturnType(prototype.typeName()); + ctor.setParameterNames(prototype.parameterNames()); + ctor.setTag(prototype.tag()); + ctor.setAccess(prototype.access()); + ctor.setAttributes(prototype.attributes()); + return ctor; +} + +/*! + Adds a new readable/writable property to this class with the specified + \a name and \a type. Returns an object that can be used to adjust + the other attributes of the property. The \a type will be + normalized before it is added to the class. + + \sa property(), propertyCount(), removeProperty(), indexOfProperty() +*/ +QMetaPropertyBuilder QMetaObjectBuilder::addProperty + (const QByteArray& name, const QByteArray& type, int notifierId) +{ + int index = d->properties.size(); + d->properties.append(QMetaPropertyBuilderPrivate(name, type, notifierId)); + return QMetaPropertyBuilder(this, index); +} + +/*! + Adds a new property to this class that has the same information as + \a prototype. This is used to clone the properties of an existing + QMetaObject. Returns an object that can be used to adjust the + attributes of the property. + + \sa property(), propertyCount(), removeProperty(), indexOfProperty() +*/ +QMetaPropertyBuilder QMetaObjectBuilder::addProperty(const QMetaProperty& prototype) +{ + QMetaPropertyBuilder property = addProperty(prototype.name(), prototype.typeName()); + property.setReadable(prototype.isReadable()); + property.setWritable(prototype.isWritable()); + property.setResettable(prototype.isResettable()); + property.setDesignable(prototype.isDesignable()); + property.setScriptable(prototype.isScriptable()); + property.setStored(prototype.isStored()); + property.setEditable(prototype.isEditable()); + property.setUser(prototype.isUser()); + property.setStdCppSet(prototype.hasStdCppSet()); + property.setEnumOrFlag(prototype.isEnumType()); + if (prototype.hasNotifySignal()) { + // Find an existing method for the notify signal, or add a new one. + QMetaMethod method = prototype.notifySignal(); + int index = indexOfMethod(method.signature()); + if (index == -1) + index = addMethod(method).index(); + d->properties[property._index].notifySignal = index; + d->properties[property._index].setFlag(Notify, true); + } + return property; +} + +/*! + Adds a new enumerator to this class with the specified + \a name. Returns an object that can be used to adjust + the other attributes of the enumerator. + + \sa enumerator(), enumeratorCount(), removeEnumerator(), + \sa indexOfEnumerator() +*/ +QMetaEnumBuilder QMetaObjectBuilder::addEnumerator(const QByteArray& name) +{ + int index = d->enumerators.size(); + d->enumerators.append(QMetaEnumBuilderPrivate(name)); + return QMetaEnumBuilder(this, index); +} + +/*! + Adds a new enumerator to this class that has the same information as + \a prototype. This is used to clone the enumerators of an existing + QMetaObject. Returns an object that can be used to adjust the + attributes of the enumerator. + + \sa enumerator(), enumeratorCount(), removeEnumerator(), + \sa indexOfEnumerator() +*/ +QMetaEnumBuilder QMetaObjectBuilder::addEnumerator(const QMetaEnum& prototype) +{ + QMetaEnumBuilder en = addEnumerator(prototype.name()); + en.setIsFlag(prototype.isFlag()); + int count = prototype.keyCount(); + for (int index = 0; index < count; ++index) + en.addKey(prototype.key(index), prototype.value(index)); + return en; +} + +/*! + Adds \a name and \a value as an item of class information to this class. + Returns the index of the new item of class information. + + \sa classInfoCount(), classInfoName(), classInfoValue(), removeClassInfo() + \sa indexOfClassInfo() +*/ +int QMetaObjectBuilder::addClassInfo(const QByteArray& name, const QByteArray& value) +{ + int index = d->classInfoNames.size(); + d->classInfoNames += name; + d->classInfoValues += value; + return index; +} + +/*! + Adds \a meta to this class as a related meta object. Returns + the index of the new related meta object entry. + + Related meta objects are used when resolving the enumerated type + associated with a property, where the enumerated type is in a + different class from the property. + + \sa relatedMetaObjectCount(), relatedMetaObject() + \sa removeRelatedMetaObject() +*/ +int QMetaObjectBuilder::addRelatedMetaObject(const QMetaObject *meta) +{ + Q_ASSERT(meta); + int index = d->relatedMetaObjects.size(); + d->relatedMetaObjects.append(meta); + return index; +} + +/*! + Adds the contents of \a prototype to this meta object builder. + This function is useful for cloning the contents of an existing QMetaObject. + + The \a members parameter indicates which members of \a prototype + should be added. The default is AllMembers. +*/ +void QMetaObjectBuilder::addMetaObject + (const QMetaObject *prototype, QMetaObjectBuilder::AddMembers members) +{ + Q_ASSERT(prototype); + int index; + + if ((members & ClassName) != 0) + d->className = prototype->className(); + + if ((members & SuperClass) != 0) + d->superClass = prototype->superClass(); + + if ((members & (Methods | Signals | Slots)) != 0) { + for (index = prototype->methodOffset(); index < prototype->methodCount(); ++index) { + QMetaMethod method = prototype->method(index); + if (method.methodType() != QMetaMethod::Signal) { + if (method.access() == QMetaMethod::Public && (members & PublicMethods) == 0) + continue; + if (method.access() == QMetaMethod::Private && (members & PrivateMethods) == 0) + continue; + if (method.access() == QMetaMethod::Protected && (members & ProtectedMethods) == 0) + continue; + } + if (method.methodType() == QMetaMethod::Method && (members & Methods) != 0) { + addMethod(method); + } else if (method.methodType() == QMetaMethod::Signal && + (members & Signals) != 0) { + addMethod(method); + } else if (method.methodType() == QMetaMethod::Slot && + (members & Slots) != 0) { + addMethod(method); + } + } + } + + if ((members & Constructors) != 0) { + for (index = 0; index < prototype->constructorCount(); ++index) + addConstructor(prototype->constructor(index)); + } + + if ((members & Properties) != 0) { + for (index = prototype->propertyOffset(); index < prototype->propertyCount(); ++index) + addProperty(prototype->property(index)); + } + + if ((members & Enumerators) != 0) { + for (index = prototype->enumeratorOffset(); index < prototype->enumeratorCount(); ++index) + addEnumerator(prototype->enumerator(index)); + } + + if ((members & ClassInfos) != 0) { + for (index = prototype->classInfoOffset(); index < prototype->classInfoCount(); ++index) { + QMetaClassInfo ci = prototype->classInfo(index); + addClassInfo(ci.name(), ci.value()); + } + } + + if ((members & RelatedMetaObjects) != 0) { + const QMetaObject **objects; + if (priv(prototype->d.data)->revision < 2) { + objects = (const QMetaObject **)(prototype->d.extradata); + } else { + const QMetaObjectExtraData *extra = (const QMetaObjectExtraData *)(prototype->d.extradata); + if (extra) + objects = extra->objects; + else + objects = 0; + } + if (objects) { + while (*objects != 0) { + addRelatedMetaObject(*objects); + ++objects; + } + } + } + + if ((members & StaticMetacall) != 0) { + if (priv(prototype->d.data)->revision >= 2) { + const QMetaObjectExtraData *extra = + (const QMetaObjectExtraData *)(prototype->d.extradata); + if (extra && extra->static_metacall) + setStaticMetacallFunction(extra->static_metacall); + } + } +} + +/*! + Returns the method at \a index in this class. + + \sa methodCount(), addMethod(), removeMethod(), indexOfMethod() +*/ +QMetaMethodBuilder QMetaObjectBuilder::method(int index) const +{ + if (index >= 0 && index < d->methods.size()) + return QMetaMethodBuilder(this, index); + else + return QMetaMethodBuilder(); +} + +/*! + Returns the constructor at \a index in this class. + + \sa methodCount(), addMethod(), removeMethod(), indexOfConstructor() +*/ +QMetaMethodBuilder QMetaObjectBuilder::constructor(int index) const +{ + if (index >= 0 && index < d->constructors.size()) + return QMetaMethodBuilder(this, -(index + 1)); + else + return QMetaMethodBuilder(); +} + +/*! + Returns the property at \a index in this class. + + \sa methodCount(), addMethod(), removeMethod(), indexOfProperty() +*/ +QMetaPropertyBuilder QMetaObjectBuilder::property(int index) const +{ + if (index >= 0 && index < d->properties.size()) + return QMetaPropertyBuilder(this, index); + else + return QMetaPropertyBuilder(); +} + +/*! + Returns the enumerator at \a index in this class. + + \sa enumeratorCount(), addEnumerator(), removeEnumerator() + \sa indexOfEnumerator() +*/ +QMetaEnumBuilder QMetaObjectBuilder::enumerator(int index) const +{ + if (index >= 0 && index < d->enumerators.size()) + return QMetaEnumBuilder(this, index); + else + return QMetaEnumBuilder(); +} + +/*! + Returns the related meta object at \a index in this class. + + Related meta objects are used when resolving the enumerated type + associated with a property, where the enumerated type is in a + different class from the property. + + \sa relatedMetaObjectCount(), addRelatedMetaObject() + \sa removeRelatedMetaObject() +*/ +const QMetaObject *QMetaObjectBuilder::relatedMetaObject(int index) const +{ + if (index >= 0 && index < d->relatedMetaObjects.size()) + return d->relatedMetaObjects[index]; + else + return 0; +} + +/*! + Returns the name of the item of class information at \a index + in this class. + + \sa classInfoCount(), addClassInfo(), classInfoValue(), removeClassInfo() + \sa indexOfClassInfo() +*/ +QByteArray QMetaObjectBuilder::classInfoName(int index) const +{ + if (index >= 0 && index < d->classInfoNames.size()) + return d->classInfoNames[index]; + else + return QByteArray(); +} + +/*! + Returns the value of the item of class information at \a index + in this class. + + \sa classInfoCount(), addClassInfo(), classInfoName(), removeClassInfo() + \sa indexOfClassInfo() +*/ +QByteArray QMetaObjectBuilder::classInfoValue(int index) const +{ + if (index >= 0 && index < d->classInfoValues.size()) + return d->classInfoValues[index]; + else + return QByteArray(); +} + +/*! + Removes the method at \a index from this class. The indices of + all following methods will be adjusted downwards by 1. If the + method is registered as a notify signal on a property, then the + notify signal will be removed from the property. + + \sa methodCount(), addMethod(), method(), indexOfMethod() +*/ +void QMetaObjectBuilder::removeMethod(int index) +{ + if (index >= 0 && index < d->methods.size()) { + d->methods.removeAt(index); + for (int prop = 0; prop < d->properties.size(); ++prop) { + // Adjust the indices of property notify signal references. + if (d->properties[prop].notifySignal == index) + d->properties[prop].notifySignal = -1; + else if (d->properties[prop].notifySignal > index) + (d->properties[prop].notifySignal)--; + } + } +} + +/*! + Removes the constructor at \a index from this class. The indices of + all following constructors will be adjusted downwards by 1. + + \sa constructorCount(), addConstructor(), constructor() + \sa indexOfConstructor() +*/ +void QMetaObjectBuilder::removeConstructor(int index) +{ + if (index >= 0 && index < d->constructors.size()) + d->constructors.removeAt(index); +} + +/*! + Removes the property at \a index from this class. The indices of + all following properties will be adjusted downwards by 1. + + \sa propertyCount(), addProperty(), property(), indexOfProperty() +*/ +void QMetaObjectBuilder::removeProperty(int index) +{ + if (index >= 0 && index < d->properties.size()) + d->properties.removeAt(index); +} + +/*! + Removes the enumerator at \a index from this class. The indices of + all following enumerators will be adjusted downwards by 1. + + \sa enumertorCount(), addEnumerator(), enumerator() + \sa indexOfEnumerator() +*/ +void QMetaObjectBuilder::removeEnumerator(int index) +{ + if (index >= 0 && index < d->enumerators.size()) + d->enumerators.removeAt(index); +} + +/*! + Removes the item of class information at \a index from this class. + The indices of all following items will be adjusted downwards by 1. + + \sa classInfoCount(), addClassInfo(), classInfoName(), classInfoValue() + \sa indexOfClassInfo() +*/ +void QMetaObjectBuilder::removeClassInfo(int index) +{ + if (index >= 0 && index < d->classInfoNames.size()) { + d->classInfoNames.removeAt(index); + d->classInfoValues.removeAt(index); + } +} + +/*! + Removes the related meta object at \a index from this class. + The indices of all following related meta objects will be adjusted + downwards by 1. + + Related meta objects are used when resolving the enumerated type + associated with a property, where the enumerated type is in a + different class from the property. + + \sa relatedMetaObjectCount(), addRelatedMetaObject() + \sa relatedMetaObject() +*/ +void QMetaObjectBuilder::removeRelatedMetaObject(int index) +{ + if (index >= 0 && index < d->relatedMetaObjects.size()) + d->relatedMetaObjects.removeAt(index); +} + +/*! + Finds a method with the specified \a signature and returns its index; + otherwise returns -1. The \a signature will be normalized by this method. + + \sa method(), methodCount(), addMethod(), removeMethod() +*/ +int QMetaObjectBuilder::indexOfMethod(const QByteArray& signature) +{ + QByteArray sig = QMetaObject::normalizedSignature(signature); + for (int index = 0; index < d->methods.size(); ++index) { + if (sig == d->methods[index].signature) + return index; + } + return -1; +} + +/*! + Finds a signal with the specified \a signature and returns its index; + otherwise returns -1. The \a signature will be normalized by this method. + + \sa indexOfMethod(), indexOfSlot() +*/ +int QMetaObjectBuilder::indexOfSignal(const QByteArray& signature) +{ + QByteArray sig = QMetaObject::normalizedSignature(signature); + for (int index = 0; index < d->methods.size(); ++index) { + if (sig == d->methods[index].signature && + d->methods[index].methodType() == QMetaMethod::Signal) + return index; + } + return -1; +} + +/*! + Finds a slot with the specified \a signature and returns its index; + otherwise returns -1. The \a signature will be normalized by this method. + + \sa indexOfMethod(), indexOfSignal() +*/ +int QMetaObjectBuilder::indexOfSlot(const QByteArray& signature) +{ + QByteArray sig = QMetaObject::normalizedSignature(signature); + for (int index = 0; index < d->methods.size(); ++index) { + if (sig == d->methods[index].signature && + d->methods[index].methodType() == QMetaMethod::Slot) + return index; + } + return -1; +} + +/*! + Finds a constructor with the specified \a signature and returns its index; + otherwise returns -1. The \a signature will be normalized by this method. + + \sa constructor(), constructorCount(), addConstructor(), removeConstructor() +*/ +int QMetaObjectBuilder::indexOfConstructor(const QByteArray& signature) +{ + QByteArray sig = QMetaObject::normalizedSignature(signature); + for (int index = 0; index < d->constructors.size(); ++index) { + if (sig == d->constructors[index].signature) + return index; + } + return -1; +} + +/*! + Finds a property with the specified \a name and returns its index; + otherwise returns -1. + + \sa property(), propertyCount(), addProperty(), removeProperty() +*/ +int QMetaObjectBuilder::indexOfProperty(const QByteArray& name) +{ + for (int index = 0; index < d->properties.size(); ++index) { + if (name == d->properties[index].name) + return index; + } + return -1; +} + +/*! + Finds an enumerator with the specified \a name and returns its index; + otherwise returns -1. + + \sa enumertor(), enumeratorCount(), addEnumerator(), removeEnumerator() +*/ +int QMetaObjectBuilder::indexOfEnumerator(const QByteArray& name) +{ + for (int index = 0; index < d->enumerators.size(); ++index) { + if (name == d->enumerators[index].name) + return index; + } + return -1; +} + +/*! + Finds an item of class information with the specified \a name and + returns its index; otherwise returns -1. + + \sa classInfoName(), classInfoValue(), classInfoCount(), addClassInfo() + \sa removeClassInfo() +*/ +int QMetaObjectBuilder::indexOfClassInfo(const QByteArray& name) +{ + for (int index = 0; index < d->classInfoNames.size(); ++index) { + if (name == d->classInfoNames[index]) + return index; + } + return -1; +} + +// Align on a specific type boundary. +#define ALIGN(size,type) \ + (size) = ((size) + sizeof(type) - 1) & ~(sizeof(type) - 1) + +// Build a string into a QMetaObject representation. Returns the +// position in the string table where the string was placed. +static int buildString + (char *buf, char *str, int *offset, const QByteArray& value, int empty) +{ + if (value.size() == 0 && empty >= 0) + return empty; + if (buf) { + memcpy(str + *offset, value.constData(), value.size()); + str[*offset + value.size()] = '\0'; + } + int posn = *offset; + *offset += value.size() + 1; + return posn; +} + +// Build the parameter array string for a method. +static QByteArray buildParameterNames + (const QByteArray& signature, const QList<QByteArray>& parameterNames) +{ + // If the parameter name list is specified, then concatenate them. + if (!parameterNames.isEmpty()) { + QByteArray names; + bool first = true; + foreach (QByteArray name, parameterNames) { + if (first) + first = false; + else + names += (char)','; + names += name; + } + return names; + } + + // Count commas in the signature, excluding those inside template arguments. + int index = signature.indexOf('('); + if (index < 0) + return QByteArray(); + ++index; + if (index >= signature.size()) + return QByteArray(); + if (signature[index] == ')') + return QByteArray(); + int count = 1; + int brackets = 0; + while (index < signature.size() && signature[index] != ',') { + char ch = signature[index++]; + if (ch == '<') + ++brackets; + else if (ch == '>') + --brackets; + else if (ch == ',' && brackets <= 0) + ++count; + } + return QByteArray(count - 1, ','); +} + +// Build a QMetaObject in "buf" based on the information in "d". +// If "buf" is null, then return the number of bytes needed to +// build the QMetaObject. +static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf) +{ + int size = 0; + int dataIndex; + int enumIndex; + int index; + bool hasNotifySignals = false; + + // Create the main QMetaObject structure at the start of the buffer. + QMetaObject *meta = reinterpret_cast<QMetaObject *>(buf); + size += sizeof(QMetaObject); + ALIGN(size, int); + if (buf) { + meta->d.superdata = d->superClass; + meta->d.extradata = 0; + } + + // Populate the QMetaObjectPrivate structure. + QMetaObjectPrivate *pmeta + = reinterpret_cast<QMetaObjectPrivate *>(buf + size); + dataIndex = 12; // Number of fields in the QMetaObjectPrivate. + for (index = 0; index < d->properties.size(); ++index) { + if (d->properties[index].notifySignal != -1) { + hasNotifySignals = true; + break; + } + } + if (buf) { + pmeta->revision = 2; + pmeta->className = 0; // Class name is always the first string. + + pmeta->classInfoCount = d->classInfoNames.size(); + pmeta->classInfoData = dataIndex; + dataIndex += 2 * d->classInfoNames.size(); + + pmeta->methodCount = d->methods.size(); + pmeta->methodData = dataIndex; + dataIndex += 5 * d->methods.size(); + + pmeta->propertyCount = d->properties.size(); + pmeta->propertyData = dataIndex; + dataIndex += 3 * d->properties.size(); + if (hasNotifySignals) + dataIndex += d->properties.size(); + + pmeta->enumeratorCount = d->enumerators.size(); + pmeta->enumeratorData = dataIndex; + dataIndex += 4 * d->enumerators.size(); + + pmeta->constructorCount = d->constructors.size(); + pmeta->constructorData = dataIndex; + dataIndex += 5 * d->constructors.size(); + } else { + dataIndex += 2 * d->classInfoNames.size(); + dataIndex += 5 * d->methods.size(); + dataIndex += 3 * d->properties.size(); + if (hasNotifySignals) + dataIndex += d->properties.size(); + dataIndex += 4 * d->enumerators.size(); + dataIndex += 5 * d->constructors.size(); + } + + // Allocate space for the enumerator key names and values. + enumIndex = dataIndex; + for (index = 0; index < d->enumerators.size(); ++index) { + QMetaEnumBuilderPrivate *enumerator = &(d->enumerators[index]); + dataIndex += 2 * enumerator->keys.size(); + } + + // Zero terminator at the end of the data offset table. + ++dataIndex; + + // Find the start of the data and string tables. + int *data = reinterpret_cast<int *>(pmeta); + size += dataIndex * sizeof(int); + char *str = reinterpret_cast<char *>(buf + size); + if (buf) { + meta->d.stringdata = str; + meta->d.data = reinterpret_cast<uint *>(data); + } + + // Reset the current data position to just past the QMetaObjectPrivate. + dataIndex = 12; + + // Add the class name to the string table. + int offset = 0; + buildString(buf, str, &offset, d->className, -1); + + // Add a common empty string, which is used to indicate "void" + // method returns, empty tag strings, etc. + int empty = buildString(buf, str, &offset, QByteArray(), -1); + + // Output the class infos, + for (index = 0; index < d->classInfoNames.size(); ++index) { + int name = buildString(buf, str, &offset, d->classInfoNames[index], empty); + int value = buildString(buf, str, &offset, d->classInfoValues[index], empty); + if (buf) { + data[dataIndex] = name; + data[dataIndex + 1] = value; + } + dataIndex += 2; + } + + // Output the methods in the class. + for (index = 0; index < d->methods.size(); ++index) { + QMetaMethodBuilderPrivate *method = &(d->methods[index]); + int sig = buildString(buf, str, &offset, method->signature, empty); + int params; + QByteArray names = buildParameterNames + (method->signature, method->parameterNames); + params = buildString(buf, str, &offset, names, empty); + int ret = buildString(buf, str, &offset, method->returnType, empty); + int tag = buildString(buf, str, &offset, method->tag, empty); + int attrs = method->attributes; + if (buf) { + data[dataIndex] = sig; + data[dataIndex + 1] = params; + data[dataIndex + 2] = ret; + data[dataIndex + 3] = tag; + data[dataIndex + 4] = attrs; + } + dataIndex += 5; + } + + // Output the properties in the class. + for (index = 0; index < d->properties.size(); ++index) { + QMetaPropertyBuilderPrivate *prop = &(d->properties[index]); + int name = buildString(buf, str, &offset, prop->name, empty); + int type = buildString(buf, str, &offset, prop->type, empty); + int flags = prop->flags; + if (buf) { + data[dataIndex] = name; + data[dataIndex + 1] = type; + data[dataIndex + 2] = flags; + } + dataIndex += 3; + } + if (hasNotifySignals) { + for (index = 0; index < d->properties.size(); ++index) { + QMetaPropertyBuilderPrivate *prop = &(d->properties[index]); + if (buf) { + if (prop->notifySignal != -1) + data[dataIndex] = prop->notifySignal; + else + data[dataIndex] = 0; + } + ++dataIndex; + } + } + + // Output the enumerators in the class. + for (index = 0; index < d->enumerators.size(); ++index) { + QMetaEnumBuilderPrivate *enumerator = &(d->enumerators[index]); + int name = buildString(buf, str, &offset, enumerator->name, empty); + int isFlag = (int)(enumerator->isFlag); + int count = enumerator->keys.size(); + int enumOffset = enumIndex; + if (buf) { + data[dataIndex] = name; + data[dataIndex + 1] = isFlag; + data[dataIndex + 2] = count; + data[dataIndex + 3] = enumOffset; + } + for (int key = 0; key < count; ++key) { + int keyIndex = buildString(buf, str, &offset, enumerator->keys[key], empty); + if (buf) { + data[enumOffset++] = keyIndex; + data[enumOffset++] = enumerator->values[key]; + } + } + dataIndex += 4; + enumIndex += 2 * count; + } + + // Output the constructors in the class. + for (index = 0; index < d->constructors.size(); ++index) { + QMetaMethodBuilderPrivate *method = &(d->constructors[index]); + int sig = buildString(buf, str, &offset, method->signature, empty); + int params; + QByteArray names = buildParameterNames + (method->signature, method->parameterNames); + params = buildString(buf, str, &offset, names, empty); + int ret = buildString(buf, str, &offset, method->returnType, empty); + int tag = buildString(buf, str, &offset, method->tag, empty); + int attrs = method->attributes; + if (buf) { + data[dataIndex] = sig; + data[dataIndex + 1] = params; + data[dataIndex + 2] = ret; + data[dataIndex + 3] = tag; + data[dataIndex + 4] = attrs; + } + dataIndex += 5; + } + + // One more empty string to act as a terminator. + buildString(buf, str, &offset, QByteArray(), -1); + size += offset; + + // Output the zero terminator in the data array. + if (buf) + data[enumIndex] = 0; + + // Create the extradata block if we need one. + if (d->relatedMetaObjects.size() > 0 || d->staticMetacallFunction) { + ALIGN(size, QMetaObject **); + ALIGN(size, QMetaObjectBuilder::StaticMetacallFunction); + QMetaObjectExtraData *extra = + reinterpret_cast<QMetaObjectExtraData *>(buf + size); + size += sizeof(QMetaObjectExtraData); + ALIGN(size, QMetaObject *); + const QMetaObject **objects = + reinterpret_cast<const QMetaObject **>(buf + size); + if (buf) { + if (d->relatedMetaObjects.size() > 0) { + extra->objects = objects; + for (index = 0; index < d->relatedMetaObjects.size(); ++index) + objects[index] = d->relatedMetaObjects[index]; + objects[index] = 0; + } else { + extra->objects = 0; + } + extra->static_metacall = d->staticMetacallFunction; + meta->d.extradata = reinterpret_cast<void *>(extra); + } + if (d->relatedMetaObjects.size() > 0) + size += sizeof(QMetaObject *) * (d->relatedMetaObjects.size() + 1); + } + + // Align the final size and return it. + ALIGN(size, void *); + return size; +} + +/*! + Converts this meta object builder into a concrete QMetaObject. + The return value should be deallocated using qFree() once it + is no longer needed. + + The returned meta object is a snapshot of the state of the + QMetaObjectBuilder. Any further modifications to the QMetaObjectBuilder + will not be reflected in previous meta objects returned by + this method. +*/ +QMetaObject *QMetaObjectBuilder::toMetaObject() const +{ + int size = buildMetaObject(d, 0); + char *buf = reinterpret_cast<char *>(qMalloc(size)); + buildMetaObject(d, buf); + return reinterpret_cast<QMetaObject *>(buf); +} + +/*! + \typedef QMetaObjectBuilder::StaticMetacallFunction + + Typedef for static metacall functions. The three parameters are + the call type value, the constructor index, and the + array of parameters. +*/ + +/*! + Returns the static metacall function to use to construct objects + of this class. The default value is null. + + \sa setStaticMetacallFunction() +*/ +QMetaObjectBuilder::StaticMetacallFunction QMetaObjectBuilder::staticMetacallFunction() const +{ + return d->staticMetacallFunction; +} + +/*! + Sets the static metacall function to use to construct objects + of this class to \a value. The default value is null. + + \sa staticMetacallFunction() +*/ +void QMetaObjectBuilder::setStaticMetacallFunction + (QMetaObjectBuilder::StaticMetacallFunction value) +{ + d->staticMetacallFunction = value; +} + +#ifndef QT_NO_DATASTREAM + +/*! + Serializes the contents of the meta object builder onto \a stream. + + \sa deserialize() +*/ +void QMetaObjectBuilder::serialize(QDataStream& stream) const +{ + int index; + + // Write the class and super class names. + stream << d->className; + if (d->superClass) + stream << QByteArray(d->superClass->className()); + else + stream << QByteArray(); + + // Write the counts for each type of class member. + stream << d->classInfoNames.size(); + stream << d->methods.size(); + stream << d->properties.size(); + stream << d->enumerators.size(); + stream << d->constructors.size(); + stream << d->relatedMetaObjects.size(); + + // Write the items of class information. + for (index = 0; index < d->classInfoNames.size(); ++index) { + stream << d->classInfoNames[index]; + stream << d->classInfoValues[index]; + } + + // Write the methods. + for (index = 0; index < d->methods.size(); ++index) { + const QMetaMethodBuilderPrivate *method = &(d->methods[index]); + stream << method->signature; + stream << method->returnType; + stream << method->parameterNames; + stream << method->tag; + stream << method->attributes; + } + + // Write the properties. + for (index = 0; index < d->properties.size(); ++index) { + const QMetaPropertyBuilderPrivate *property = &(d->properties[index]); + stream << property->name; + stream << property->type; + stream << property->flags; + stream << property->notifySignal; + } + + // Write the enumerators. + for (index = 0; index < d->enumerators.size(); ++index) { + const QMetaEnumBuilderPrivate *enumerator = &(d->enumerators[index]); + stream << enumerator->name; + stream << enumerator->isFlag; + stream << enumerator->keys; + stream << enumerator->values; + } + + // Write the constructors. + for (index = 0; index < d->constructors.size(); ++index) { + const QMetaMethodBuilderPrivate *method = &(d->constructors[index]); + stream << method->signature; + stream << method->returnType; + stream << method->parameterNames; + stream << method->tag; + stream << method->attributes; + } + + // Write the related meta objects. + for (index = 0; index < d->relatedMetaObjects.size(); ++index) { + const QMetaObject *meta = d->relatedMetaObjects[index]; + stream << QByteArray(meta->className()); + } + + // Add an extra empty QByteArray for additional data in future versions. + // This should help maintain backwards compatibility, allowing older + // versions to read newer data. + stream << QByteArray(); +} + +// Resolve a class name using the name reference map. +static const QMetaObject *resolveClassName + (const QMap<QByteArray, const QMetaObject *>& references, + const QByteArray& name) +{ + if (name == QByteArray("QObject")) + return &QObject::staticMetaObject; + else + return references.value(name, 0); +} + +/*! + Deserializes a meta object builder from \a stream into + this meta object builder. + + The \a references parameter specifies a mapping from class names + to QMetaObject instances for resolving the super class name and + related meta objects in the object that is deserialized. + The meta object for QObject is implicitly added to \a references + and does not need to be supplied. + + The QDataStream::status() value on \a stream will be set to + QDataStream::ReadCorruptData if the input data is corrupt. + The status will be set to QDataStream::ReadPastEnd if the + input was exhausted before the full meta object was read. + + \sa serialize() +*/ +void QMetaObjectBuilder::deserialize + (QDataStream& stream, + const QMap<QByteArray, const QMetaObject *>& references) +{ + QByteArray name; + const QMetaObject *cl; + int index; + + // Clear all members in the builder to their default states. + d->className.clear(); + d->superClass = &QObject::staticMetaObject; + d->classInfoNames.clear(); + d->classInfoValues.clear(); + d->methods.clear(); + d->properties.clear(); + d->enumerators.clear(); + d->constructors.clear(); + d->relatedMetaObjects.clear(); + d->staticMetacallFunction = 0; + + // Read the class and super class names. + stream >> d->className; + stream >> name; + if (name.isEmpty()) { + d->superClass = 0; + } else if ((cl = resolveClassName(references, name)) != 0) { + d->superClass = cl; + } else { + stream.setStatus(QDataStream::ReadCorruptData); + return; + } + + // Read the counts for each type of class member. + int classInfoCount, methodCount, propertyCount; + int enumeratorCount, constructorCount, relatedMetaObjectCount; + stream >> classInfoCount; + stream >> methodCount; + stream >> propertyCount; + stream >> enumeratorCount; + stream >> constructorCount; + stream >> relatedMetaObjectCount; + if (classInfoCount < 0 || methodCount < 0 || + propertyCount < 0 || enumeratorCount < 0 || + constructorCount < 0 || relatedMetaObjectCount < 0) { + stream.setStatus(QDataStream::ReadCorruptData); + return; + } + + // Read the items of class information. + for (index = 0; index < classInfoCount; ++index) { + if (stream.status() != QDataStream::Ok) + return; + QByteArray value; + stream >> name; + stream >> value; + addClassInfo(name, value); + } + + // Read the member methods. + for (index = 0; index < methodCount; ++index) { + if (stream.status() != QDataStream::Ok) + return; + stream >> name; + addMethod(name); + QMetaMethodBuilderPrivate *method = &(d->methods[index]); + stream >> method->returnType; + stream >> method->parameterNames; + stream >> method->tag; + stream >> method->attributes; + if (method->methodType() == QMetaMethod::Constructor) { + // Cannot add a constructor in this set of methods. + stream.setStatus(QDataStream::ReadCorruptData); + return; + } + } + + // Read the properties. + for (index = 0; index < propertyCount; ++index) { + if (stream.status() != QDataStream::Ok) + return; + QByteArray type; + stream >> name; + stream >> type; + addProperty(name, type); + QMetaPropertyBuilderPrivate *property = &(d->properties[index]); + stream >> property->flags; + stream >> property->notifySignal; + if (property->notifySignal < -1 || + property->notifySignal >= d->methods.size()) { + // Notify signal method index is out of range. + stream.setStatus(QDataStream::ReadCorruptData); + return; + } + if (property->notifySignal >= 0 && + d->methods[property->notifySignal].methodType() != QMetaMethod::Signal) { + // Notify signal method index does not refer to a signal. + stream.setStatus(QDataStream::ReadCorruptData); + return; + } + } + + // Read the enumerators. + for (index = 0; index < enumeratorCount; ++index) { + if (stream.status() != QDataStream::Ok) + return; + stream >> name; + addEnumerator(name); + QMetaEnumBuilderPrivate *enumerator = &(d->enumerators[index]); + stream >> enumerator->isFlag; + stream >> enumerator->keys; + stream >> enumerator->values; + if (enumerator->keys.size() != enumerator->values.size()) { + // Mismatch between number of keys and number of values. + stream.setStatus(QDataStream::ReadCorruptData); + return; + } + } + + // Read the constructor methods. + for (index = 0; index < constructorCount; ++index) { + if (stream.status() != QDataStream::Ok) + return; + stream >> name; + addConstructor(name); + QMetaMethodBuilderPrivate *method = &(d->constructors[index]); + stream >> method->returnType; + stream >> method->parameterNames; + stream >> method->tag; + stream >> method->attributes; + if (method->methodType() != QMetaMethod::Constructor) { + // The type must be Constructor. + stream.setStatus(QDataStream::ReadCorruptData); + return; + } + } + + // Read the related meta objects. + for (index = 0; index < relatedMetaObjectCount; ++index) { + if (stream.status() != QDataStream::Ok) + return; + stream >> name; + cl = resolveClassName(references, name); + if (!cl) { + stream.setStatus(QDataStream::ReadCorruptData); + return; + } + addRelatedMetaObject(cl); + } + + // Read the extra data block, which is reserved for future use. + stream >> name; +} + +#endif // !QT_NO_DATASTREAM + +/*! + \class QMetaMethodBuilder + \brief The QMetaMethodBuilder class enables modifications to a method definition on a meta object builder. +*/ + +QMetaMethodBuilderPrivate *QMetaMethodBuilder::d_func() const +{ + // Positive indices indicate methods, negative indices indicate constructors. + if (_mobj && _index >= 0 && _index < _mobj->d->methods.size()) + return &(_mobj->d->methods[_index]); + else if (_mobj && -_index >= 1 && -_index <= _mobj->d->constructors.size()) + return &(_mobj->d->constructors[(-_index) - 1]); + else + return 0; +} + +/*! + \fn QMetaMethodBuilder::QMetaMethodBuilder() + \internal +*/ + +/*! + Returns the index of this method within its QMetaObjectBuilder. +*/ +int QMetaMethodBuilder::index() const +{ + if (_index >= 0) + return _index; // Method, signal, or slot + else + return (-_index) - 1; // Constructor +} + +/*! + Returns the type of this method (signal, slot, method, or constructor). +*/ +QMetaMethod::MethodType QMetaMethodBuilder::methodType() const +{ + QMetaMethodBuilderPrivate *d = d_func(); + if (d) + return d->methodType(); + else + return QMetaMethod::Method; +} + +/*! + Returns the signature of this method. + + \sa parameterNames(), returnType() +*/ +QByteArray QMetaMethodBuilder::signature() const +{ + QMetaMethodBuilderPrivate *d = d_func(); + if (d) + return d->signature; + else + return QByteArray(); +} + +/*! + Returns the return type for this method; empty if the method's + return type is \c{void}. + + \sa setReturnType(), signature() +*/ +QByteArray QMetaMethodBuilder::returnType() const +{ + QMetaMethodBuilderPrivate *d = d_func(); + if (d) + return d->returnType; + else + return QByteArray(); +} + +/*! + Sets the return type for this method to \a value. If \a value + is empty, then the method's return type is \c{void}. The \a value + will be normalized before it is added to the method. + + \sa returnType(), signature() +*/ +void QMetaMethodBuilder::setReturnType(const QByteArray& value) +{ + QMetaMethodBuilderPrivate *d = d_func(); + if (d) + d->returnType = QMetaObject::normalizedType(value); +} + +/*! + Returns the list of parameter names for this method. + + \sa setParameterNames() +*/ +QList<QByteArray> QMetaMethodBuilder::parameterNames() const +{ + QMetaMethodBuilderPrivate *d = d_func(); + if (d) + return d->parameterNames; + else + return QList<QByteArray>(); +} + +/*! + Sets the list of parameter names for this method to \a value. + + \sa parameterNames() +*/ +void QMetaMethodBuilder::setParameterNames(const QList<QByteArray>& value) +{ + QMetaMethodBuilderPrivate *d = d_func(); + if (d) + d->parameterNames = value; +} + +/*! + Returns the tag associated with this method. + + \sa setTag() +*/ +QByteArray QMetaMethodBuilder::tag() const +{ + QMetaMethodBuilderPrivate *d = d_func(); + if (d) + return d->tag; + else + return QByteArray(); +} + +/*! + Sets the tag associated with this method to \a value. + + \sa setTag() +*/ +void QMetaMethodBuilder::setTag(const QByteArray& value) +{ + QMetaMethodBuilderPrivate *d = d_func(); + if (d) + d->tag = value; +} + +/*! + Returns the access specification of this method (private, protected, + or public). The default value is QMetaMethod::Public for methods, + slots, and constructors. The default value is QMetaMethod::Protected + for signals. + + \sa setAccess() +*/ +QMetaMethod::Access QMetaMethodBuilder::access() const +{ + QMetaMethodBuilderPrivate *d = d_func(); + if (d) + return d->access(); + else + return QMetaMethod::Public; +} + +/*! + Sets the access specification of this method (private, protected, + or public) to \a value. If the method is a signal, this function + will be ignored. + + \sa access() +*/ +void QMetaMethodBuilder::setAccess(QMetaMethod::Access value) +{ + QMetaMethodBuilderPrivate *d = d_func(); + if (d && d->methodType() != QMetaMethod::Signal) + d->setAccess(value); +} + +/*! + Returns the additional attributes for this method. + + \sa setAttributes() +*/ +int QMetaMethodBuilder::attributes() const +{ + QMetaMethodBuilderPrivate *d = d_func(); + if (d) + return (d->attributes >> 4); + else + return 0; +} + +/*! + Sets the additional attributes for this method to \a value. + + \sa attributes() +*/ +void QMetaMethodBuilder::setAttributes(int value) +{ + QMetaMethodBuilderPrivate *d = d_func(); + if (d) + d->attributes = ((d->attributes & 0x0f) | (value << 4)); +} + +/*! + \class QMetaPropertyBuilder + \brief The QMetaPropertyBuilder class enables modifications to a property definition on a meta object builder. +*/ + +QMetaPropertyBuilderPrivate *QMetaPropertyBuilder::d_func() const +{ + if (_mobj && _index >= 0 && _index < _mobj->d->properties.size()) + return &(_mobj->d->properties[_index]); + else + return 0; +} + +/*! + \fn QMetaPropertyBuilder::QMetaPropertyBuilder() + \internal +*/ + +/*! + \fn int QMetaPropertyBuilder::index() const + + Returns the index of this property within its QMetaObjectBuilder. +*/ + +/*! + Returns the name associated with this property. + + \sa type() +*/ +QByteArray QMetaPropertyBuilder::name() const +{ + QMetaPropertyBuilderPrivate *d = d_func(); + if (d) + return d->name; + else + return QByteArray(); +} + +/*! + Returns the type associated with this property. + + \sa name() +*/ +QByteArray QMetaPropertyBuilder::type() const +{ + QMetaPropertyBuilderPrivate *d = d_func(); + if (d) + return d->type; + else + return QByteArray(); +} + +/*! + Returns true if this property has a notify signal; false otherwise. + + \sa notifySignal(), setNotifySignal(), removeNotifySignal() +*/ +bool QMetaPropertyBuilder::hasNotifySignal() const +{ + QMetaPropertyBuilderPrivate *d = d_func(); + if (d) + return d->flag(Notify); + else + return false; +} + +/*! + Returns the notify signal associated with this property. + + \sa hasNotifySignal(), setNotifySignal(), removeNotifySignal() +*/ +QMetaMethodBuilder QMetaPropertyBuilder::notifySignal() const +{ + QMetaPropertyBuilderPrivate *d = d_func(); + if (d && d->notifySignal >= 0) + return QMetaMethodBuilder(_mobj, d->notifySignal); + else + return QMetaMethodBuilder(); +} + +/*! + Sets the notify signal associated with this property to \a value. + + \sa hasNotifySignal(), notifySignal(), removeNotifySignal() +*/ +void QMetaPropertyBuilder::setNotifySignal(const QMetaMethodBuilder& value) +{ + QMetaPropertyBuilderPrivate *d = d_func(); + if (d) { + if (value._mobj) { + d->notifySignal = value._index; + d->setFlag(Notify, true); + } else { + d->notifySignal = -1; + d->setFlag(Notify, false); + } + } +} + +/*! + Removes the notify signal from this property. + + \sa hasNotifySignal(), notifySignal(), setNotifySignal() +*/ +void QMetaPropertyBuilder::removeNotifySignal() +{ + QMetaPropertyBuilderPrivate *d = d_func(); + if (d) { + d->notifySignal = -1; + d->setFlag(Notify, false); + } +} + +/*! + Returns true if this property is readable; otherwise returns false. + The default value is true. + + \sa setReadable(), isWritable() +*/ +bool QMetaPropertyBuilder::isReadable() const +{ + QMetaPropertyBuilderPrivate *d = d_func(); + if (d) + return d->flag(Readable); + else + return false; +} + +/*! + Returns true if this property is writable; otherwise returns false. + The default value is true. + + \sa setWritable(), isReadable() +*/ +bool QMetaPropertyBuilder::isWritable() const +{ + QMetaPropertyBuilderPrivate *d = d_func(); + if (d) + return d->flag(Writable); + else + return false; +} + +/*! + Returns true if this property can be reset to a default value; otherwise + returns false. The default value is false. + + \sa setResettable() +*/ +bool QMetaPropertyBuilder::isResettable() const +{ + QMetaPropertyBuilderPrivate *d = d_func(); + if (d) + return d->flag(Resettable); + else + return false; +} + +/*! + Returns true if this property is designable; otherwise returns false. + This default value is false. + + \sa setDesignable(), isScriptable(), isStored() +*/ +bool QMetaPropertyBuilder::isDesignable() const +{ + QMetaPropertyBuilderPrivate *d = d_func(); + if (d) + return d->flag(Designable); + else + return false; +} + +/*! + Returns true if the property is scriptable; otherwise returns false. + This default value is false. + + \sa setScriptable(), isDesignable(), isStored() +*/ +bool QMetaPropertyBuilder::isScriptable() const +{ + QMetaPropertyBuilderPrivate *d = d_func(); + if (d) + return d->flag(Scriptable); + else + return false; +} + +/*! + Returns true if the property is stored; otherwise returns false. + This default value is false. + + \sa setStored(), isDesignable(), isScriptable() +*/ +bool QMetaPropertyBuilder::isStored() const +{ + QMetaPropertyBuilderPrivate *d = d_func(); + if (d) + return d->flag(Stored); + else + return false; +} + +/*! + Returns true if the property is editable; otherwise returns false. + This default value is false. + + \sa setEditable(), isDesignable(), isScriptable(), isStored() +*/ +bool QMetaPropertyBuilder::isEditable() const +{ + QMetaPropertyBuilderPrivate *d = d_func(); + if (d) + return d->flag(Editable); + else + return false; +} + +/*! + Returns true if this property is designated as the \c USER + property, i.e., the one that the user can edit or that is + significant in some other way. Otherwise it returns + false. This default value is false. + + \sa setUser(), isDesignable(), isScriptable() +*/ +bool QMetaPropertyBuilder::isUser() const +{ + QMetaPropertyBuilderPrivate *d = d_func(); + if (d) + return d->flag(User); + else + return false; +} + +/*! + Returns true if the property has a C++ setter function that + follows Qt's standard "name" / "setName" pattern. Designer and uic + query hasStdCppSet() in order to avoid expensive + QObject::setProperty() calls. All properties in Qt [should] follow + this pattern. The default value is false. + + \sa setStdCppSet() +*/ +bool QMetaPropertyBuilder::hasStdCppSet() const +{ + QMetaPropertyBuilderPrivate *d = d_func(); + if (d) + return d->flag(StdCppSet); + else + return false; +} + +/*! + Returns true if the property is an enumerator or flag type; + otherwise returns false. This default value is false. + + \sa setEnumOrFlag() +*/ +bool QMetaPropertyBuilder::isEnumOrFlag() const +{ + QMetaPropertyBuilderPrivate *d = d_func(); + if (d) + return d->flag(EnumOrFlag); + else + return false; +} + +/*! + Sets this property to readable if \a value is true. + + \sa isReadable(), setWritable() +*/ +void QMetaPropertyBuilder::setReadable(bool value) +{ + QMetaPropertyBuilderPrivate *d = d_func(); + if (d) + d->setFlag(Readable, value); +} + +/*! + Sets this property to writable if \a value is true. + + \sa isWritable(), setReadable() +*/ +void QMetaPropertyBuilder::setWritable(bool value) +{ + QMetaPropertyBuilderPrivate *d = d_func(); + if (d) + d->setFlag(Writable, value); +} + +/*! + Sets this property to resettable if \a value is true. + + \sa isResettable() +*/ +void QMetaPropertyBuilder::setResettable(bool value) +{ + QMetaPropertyBuilderPrivate *d = d_func(); + if (d) + d->setFlag(Resettable, value); +} + +/*! + Sets this property to designable if \a value is true. + + \sa isDesignable(), setScriptable(), setStored() +*/ +void QMetaPropertyBuilder::setDesignable(bool value) +{ + QMetaPropertyBuilderPrivate *d = d_func(); + if (d) + d->setFlag(Designable, value); +} + +/*! + Sets this property to scriptable if \a value is true. + + \sa isScriptable(), setDesignable(), setStored() +*/ +void QMetaPropertyBuilder::setScriptable(bool value) +{ + QMetaPropertyBuilderPrivate *d = d_func(); + if (d) + d->setFlag(Scriptable, value); +} + +/*! + Sets this property to storable if \a value is true. + + \sa isStored(), setDesignable(), setScriptable() +*/ +void QMetaPropertyBuilder::setStored(bool value) +{ + QMetaPropertyBuilderPrivate *d = d_func(); + if (d) + d->setFlag(Stored, value); +} + +/*! + Sets this property to editable if \a value is true. + + \sa isEditable(), setDesignable(), setScriptable(), setStored() +*/ +void QMetaPropertyBuilder::setEditable(bool value) +{ + QMetaPropertyBuilderPrivate *d = d_func(); + if (d) + d->setFlag(Editable, value); +} + +/*! + Sets the \c USER flag on this property to \a value. + + \sa isUser(), setDesignable(), setScriptable() +*/ +void QMetaPropertyBuilder::setUser(bool value) +{ + QMetaPropertyBuilderPrivate *d = d_func(); + if (d) + d->setFlag(User, value); +} + +/*! + Sets the C++ setter flag on this property to \a value, which is + true if the property has a C++ setter function that follows Qt's + standard "name" / "setName" pattern. + + \sa hasStdCppSet() +*/ +void QMetaPropertyBuilder::setStdCppSet(bool value) +{ + QMetaPropertyBuilderPrivate *d = d_func(); + if (d) + d->setFlag(StdCppSet, value); +} + +/*! + Sets this property to be of an enumerator or flag type if + \a value is true. + + \sa isEnumOrFlag() +*/ +void QMetaPropertyBuilder::setEnumOrFlag(bool value) +{ + QMetaPropertyBuilderPrivate *d = d_func(); + if (d) + d->setFlag(EnumOrFlag, value); +} + +/*! + \class QMetaEnumBuilder + \brief The QMetaEnumBuilder class enables modifications to an enumerator definition on a meta object builder. +*/ + +QMetaEnumBuilderPrivate *QMetaEnumBuilder::d_func() const +{ + if (_mobj && _index >= 0 && _index < _mobj->d->enumerators.size()) + return &(_mobj->d->enumerators[_index]); + else + return 0; +} + +/*! + \fn QMetaEnumBuilder::QMetaEnumBuilder() + \internal +*/ + +/*! + \fn int QMetaEnumBuilder::index() const + + Returns the index of this enumerator within its QMetaObjectBuilder. +*/ + +/*! + Returns the name of the enumerator (without the scope). +*/ +QByteArray QMetaEnumBuilder::name() const +{ + QMetaEnumBuilderPrivate *d = d_func(); + if (d) + return d->name; + else + return QByteArray(); +} + +/*! + Returns true if this enumerator is used as a flag; otherwise returns + false. + + \sa setIsFlag() +*/ +bool QMetaEnumBuilder::isFlag() const +{ + QMetaEnumBuilderPrivate *d = d_func(); + if (d) + return d->isFlag; + else + return false; +} + +/*! + Sets this enumerator to be used as a flag if \a value is true. + + \sa isFlag() +*/ +void QMetaEnumBuilder::setIsFlag(bool value) +{ + QMetaEnumBuilderPrivate *d = d_func(); + if (d) + d->isFlag = value; +} + +/*! + Returns the number of keys. + + \sa key(), addKey() +*/ +int QMetaEnumBuilder::keyCount() const +{ + QMetaEnumBuilderPrivate *d = d_func(); + if (d) + return d->keys.size(); + else + return 0; +} + +/*! + Returns the key with the given \a index, or an empty QByteArray + if no such key exists. + + \sa keyCount(), addKey(), value() +*/ +QByteArray QMetaEnumBuilder::key(int index) const +{ + QMetaEnumBuilderPrivate *d = d_func(); + if (d && index >= 0 && index < d->keys.size()) + return d->keys[index]; + else + return QByteArray(); +} + +/*! + Returns the value with the given \a index; or returns -1 if there + is no such value. + + \sa keyCount(), addKey(), key() +*/ +int QMetaEnumBuilder::value(int index) const +{ + QMetaEnumBuilderPrivate *d = d_func(); + if (d && index >= 0 && index < d->keys.size()) + return d->values[index]; + else + return -1; +} + +/*! + Adds a new key called \a name to this enumerator, associated + with \a value. Returns the index of the new key. + + \sa keyCount(), key(), value(), removeKey() +*/ +int QMetaEnumBuilder::addKey(const QByteArray& name, int value) +{ + QMetaEnumBuilderPrivate *d = d_func(); + if (d) { + int index = d->keys.size(); + d->keys += name; + d->values += value; + return index; + } else { + return -1; + } +} + +/*! + Removes the key at \a index from this enumerator. + + \sa addKey() +*/ +void QMetaEnumBuilder::removeKey(int index) +{ + QMetaEnumBuilderPrivate *d = d_func(); + if (d && index >= 0 && index < d->keys.size()) { + d->keys.removeAt(index); + d->values.removeAt(index); + } +} diff --git a/tests/auto/dynamicobject/qmetaobjectbuilder.h b/tests/auto/dynamicobject/qmetaobjectbuilder.h new file mode 100644 index 0000000..d820860 --- /dev/null +++ b/tests/auto/dynamicobject/qmetaobjectbuilder.h @@ -0,0 +1,258 @@ +/**************************************************************************** +** +** This file is part of the $PACKAGE_NAME$. +** +** Copyright (C) $THISYEAR$ $COMPANY_NAME$. +** +** $QT_EXTENDED_DUAL_LICENSE$ +** +****************************************************************************/ + +#ifndef QMETAOBJECTBUILDER_H +#define QMETAOBJECTBUILDER_H + +#include <QtCore/qobject.h> +#include <QtCore/qmetaobject.h> +#include <QtCore/qdatastream.h> +#include <QtCore/qmap.h> + +class QMetaObjectBuilderPrivate; +class QMetaMethodBuilder; +class QMetaMethodBuilderPrivate; +class QMetaPropertyBuilder; +class QMetaPropertyBuilderPrivate; +class QMetaEnumBuilder; +class QMetaEnumBuilderPrivate; + +class QMetaObjectBuilder +{ +public: + enum AddMember + { + ClassName = 0x00000001, + SuperClass = 0x00000002, + Methods = 0x00000004, + Signals = 0x00000008, + Slots = 0x00000010, + Constructors = 0x00000020, + Properties = 0x00000040, + Enumerators = 0x00000080, + ClassInfos = 0x00000100, + RelatedMetaObjects = 0x00000200, + StaticMetacall = 0x00000400, + PublicMethods = 0x00000800, + ProtectedMethods = 0x00001000, + PrivateMethods = 0x00002000, + AllMembers = 0x7FFFFFFF, + AllPrimaryMembers = 0x7FFFFBFC + }; + Q_DECLARE_FLAGS(AddMembers, AddMember) + + QMetaObjectBuilder(); + explicit QMetaObjectBuilder(const QMetaObject *prototype, QMetaObjectBuilder::AddMembers members = AllMembers); + virtual ~QMetaObjectBuilder(); + + QByteArray className() const; + void setClassName(const QByteArray& name); + + const QMetaObject *superClass() const; + void setSuperClass(const QMetaObject *meta); + + int methodCount() const; + int constructorCount() const; + int propertyCount() const; + int enumeratorCount() const; + int classInfoCount() const; + int relatedMetaObjectCount() const; + + QMetaMethodBuilder addMethod(const QByteArray& signature); + QMetaMethodBuilder addMethod(const QByteArray& signature, const QByteArray& returnType); + QMetaMethodBuilder addMethod(const QMetaMethod& prototype); + + QMetaMethodBuilder addSlot(const QByteArray& signature); + QMetaMethodBuilder addSignal(const QByteArray& signature); + + QMetaMethodBuilder addConstructor(const QByteArray& signature); + QMetaMethodBuilder addConstructor(const QMetaMethod& prototype); + + QMetaPropertyBuilder addProperty(const QByteArray& name, const QByteArray& type, int notifierId=-1); + QMetaPropertyBuilder addProperty(const QMetaProperty& prototype); + + QMetaEnumBuilder addEnumerator(const QByteArray& name); + QMetaEnumBuilder addEnumerator(const QMetaEnum& prototype); + + int addClassInfo(const QByteArray& name, const QByteArray& value); + + int addRelatedMetaObject(const QMetaObject *meta); + + void addMetaObject(const QMetaObject *prototype, QMetaObjectBuilder::AddMembers members = AllMembers); + + QMetaMethodBuilder method(int index) const; + QMetaMethodBuilder constructor(int index) const; + QMetaPropertyBuilder property(int index) const; + QMetaEnumBuilder enumerator(int index) const; + const QMetaObject *relatedMetaObject(int index) const; + + QByteArray classInfoName(int index) const; + QByteArray classInfoValue(int index) const; + + void removeMethod(int index); + void removeConstructor(int index); + void removeProperty(int index); + void removeEnumerator(int index); + void removeClassInfo(int index); + void removeRelatedMetaObject(int index); + + int indexOfMethod(const QByteArray& signature); + int indexOfSignal(const QByteArray& signature); + int indexOfSlot(const QByteArray& signature); + int indexOfConstructor(const QByteArray& signature); + int indexOfProperty(const QByteArray& name); + int indexOfEnumerator(const QByteArray& name); + int indexOfClassInfo(const QByteArray& name); + + typedef int (*StaticMetacallFunction)(QMetaObject::Call, int, void **); + + QMetaObjectBuilder::StaticMetacallFunction staticMetacallFunction() const; + void setStaticMetacallFunction(QMetaObjectBuilder::StaticMetacallFunction value); + + QMetaObject *toMetaObject() const; + +#ifndef QT_NO_DATASTREAM + void serialize(QDataStream& stream) const; + void deserialize + (QDataStream& stream, + const QMap<QByteArray, const QMetaObject *>& references); +#endif + +private: + Q_DISABLE_COPY(QMetaObjectBuilder); + + QMetaObjectBuilderPrivate *d; + + friend class QMetaMethodBuilder; + friend class QMetaPropertyBuilder; + friend class QMetaEnumBuilder; +}; + +class QMetaMethodBuilder +{ +public: + QMetaMethodBuilder() : _mobj(0), _index(0) {} + + int index() const; + + QMetaMethod::MethodType methodType() const; + QByteArray signature() const; + + QByteArray returnType() const; + void setReturnType(const QByteArray& value); + + QList<QByteArray> parameterNames() const; + void setParameterNames(const QList<QByteArray>& value); + + QByteArray tag() const; + void setTag(const QByteArray& value); + + QMetaMethod::Access access() const; + void setAccess(QMetaMethod::Access value); + + int attributes() const; + void setAttributes(int value); + +private: + const QMetaObjectBuilder *_mobj; + int _index; + + friend class QMetaObjectBuilder; + friend class QMetaPropertyBuilder; + + QMetaMethodBuilder(const QMetaObjectBuilder *mobj, int index) + : _mobj(mobj), _index(index) {} + + QMetaMethodBuilderPrivate *d_func() const; +}; + +class QMetaPropertyBuilder +{ +public: + QMetaPropertyBuilder() : _mobj(0), _index(0) {} + + int index() const { return _index; } + + QByteArray name() const; + QByteArray type() const; + + bool hasNotifySignal() const; + QMetaMethodBuilder notifySignal() const; + void setNotifySignal(const QMetaMethodBuilder& value); + void removeNotifySignal(); + + bool isReadable() const; + bool isWritable() const; + bool isResettable() const; + bool isDesignable() const; + bool isScriptable() const; + bool isStored() const; + bool isEditable() const; + bool isUser() const; + bool hasStdCppSet() const; + bool isEnumOrFlag() const; + + void setReadable(bool value); + void setWritable(bool value); + void setResettable(bool value); + void setDesignable(bool value); + void setScriptable(bool value); + void setStored(bool value); + void setEditable(bool value); + void setUser(bool value); + void setStdCppSet(bool value); + void setEnumOrFlag(bool value); + +private: + const QMetaObjectBuilder *_mobj; + int _index; + + friend class QMetaObjectBuilder; + + QMetaPropertyBuilder(const QMetaObjectBuilder *mobj, int index) + : _mobj(mobj), _index(index) {} + + QMetaPropertyBuilderPrivate *d_func() const; +}; + +class QMetaEnumBuilder +{ +public: + QMetaEnumBuilder() : _mobj(0), _index(0) {} + + int index() const { return _index; } + + QByteArray name() const; + + bool isFlag() const; + void setIsFlag(bool value); + + int keyCount() const; + QByteArray key(int index) const; + int value(int index) const; + + int addKey(const QByteArray& name, int value); + void removeKey(int index); + +private: + const QMetaObjectBuilder *_mobj; + int _index; + + friend class QMetaObjectBuilder; + + QMetaEnumBuilder(const QMetaObjectBuilder *mobj, int index) + : _mobj(mobj), _index(index) {} + + QMetaEnumBuilderPrivate *d_func() const; +}; + +Q_DECLARE_OPERATORS_FOR_FLAGS(QMetaObjectBuilder::AddMembers) + +#endif diff --git a/tests/auto/dynamicobject/tst_qobject.cpp b/tests/auto/dynamicobject/tst_qobject.cpp new file mode 100644 index 0000000..18805f7 --- /dev/null +++ b/tests/auto/dynamicobject/tst_qobject.cpp @@ -0,0 +1,325 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +****************************************************************************/ + +#define QT3_SUPPORT +#include <QtTest/QtTest> + + +#include <qcoreapplication.h> + +#include <qmetaobject.h> + +#include "qobject.h" +#include "private/qobject_p.h" +#include "qmetaobjectbuilder.h" +#include "qdynamicmetaobject.h" + + +//TESTED_CLASS= +//TESTED_FILES= + +class tst_QObject : public QObject +{ + Q_OBJECT + +public: + tst_QObject(); + virtual ~tst_QObject(); + + +public slots: + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); + +private slots: + void addSignal(); + void addSlot(); + void addProperty(); + void dynamicProperty(); +}; + +//=========================================================================== + +class MyDynamicMetaObject : public QDynamicMetaObject +{ +public: + MyDynamicMetaObject(const QMetaObject *base); + + int createProperty(const QObject *object, const char *, const char *); + + virtual void callSlot(QObject *object, int id, const QList<QVariant> &args); + + virtual void writeProperty(QObject *, int id, const QVariant &value) { + props[property(id).name()] = value; + } + + virtual QVariant readProperty(QObject *, int id) const { + return props[property(id).name()]; + } + + QString calledSlot; + QString string; + +private: + QMap<QString,QVariant> props; +}; + +MyDynamicMetaObject::MyDynamicMetaObject(const QMetaObject *_base) + : QDynamicMetaObject(_base) +{ +} + +void MyDynamicMetaObject::callSlot(QObject *object, int id, const QList<QVariant> &args) +{ + calledSlot = method(id).signature(); + qDebug() << "Handled slot" << id << calledSlot << args; + if (calledSlot == "string(QString)") { + string = args[0].toString(); + } +} + +int MyDynamicMetaObject::createProperty(const QObject *, const char *name, const char *type) +{ + qDebug() << "createProperty" << name; + if (name == QString("dynamicProp")) { + addProperty(name, type); + int id = indexOfProperty(name); + return id; + } + + return -1; +} + +//=========================================================================== + +class MyDynamicObject : public QObject +{ + Q_OBJECT +public: + MyDynamicObject(); + + void addSignal(const char *sigName) { + dynamicMeta->addSignal(sigName); + } + + void addSignal(const char *sigName, const QList<QByteArray> ¶meterNames) { + dynamicMeta->addSignal(sigName, parameterNames); + } + + void emitSignal(const char *sigName) { + int idx = dynamicMeta->indexOfSignal(sigName); + if (idx >= 0) + dynamicMeta->activate(this, idx, 0); + } + + void emitSignal(const char *sigName, QGenericArgument val0 + , QGenericArgument val1=QGenericArgument(0) + , QGenericArgument val2=QGenericArgument(0) + , QGenericArgument val3=QGenericArgument(0) + , QGenericArgument val4=QGenericArgument(0) + , QGenericArgument val5=QGenericArgument(0) + , QGenericArgument val6=QGenericArgument(0) + , QGenericArgument val7=QGenericArgument(0)) + { + int idx = dynamicMeta->indexOfSignal(sigName); + if (idx >= 0) { + QGenericReturnArgument rv; + dynamicMeta->method(idx).invoke(this, Qt::DirectConnection, rv, + val0, val1, val2, val3, val4, val5, val6, val7); + } + } + + void addSlot(const char *slotName) { + dynamicMeta->addSlot(slotName); + } + + void addSlot(const char *slotName, const QList<QByteArray> ¶meterNames) { + dynamicMeta->addSlot(slotName, parameterNames); + } + + void addProperty(const char *name, const char *type, const char *notifier) { + dynamicMeta->addProperty(name, type, notifier); + } + + QString calledSlot() const { return dynamicMeta->calledSlot; } + + void emitNormalSignal() { emit normalSignal(); } + + MyDynamicMetaObject *dynamicMeta; + +public slots: + void normalSlot() {} + +signals: + void normalSignal(); + +}; + +MyDynamicObject::MyDynamicObject() + : QObject() +{ + dynamicMeta = new MyDynamicMetaObject(&staticMetaObject); + setDynamicMetaObject(dynamicMeta); +} + +//=========================================================================== + +class TestObject : public QObject +{ + Q_OBJECT +public: + TestObject() : slot1Called(false), slot2Called(false) {} + + void emitSignal() { emit triggered(); } + void setText(const QString &str) { emit textChanged(str); } + + bool slot1Called; + bool slot2Called; + QString string; + +public slots: + void slot1() { + slot1Called = true; + qDebug() << "Called slot1()"; + } + + void slot2() { + slot2Called = true; + qDebug() << "Called slot2()"; + } + + void slotString(QString str) { + string = str; + qDebug() << "Called slotString()" << str; + } + +signals: + void triggered(); + void textChanged(QString); +}; + + +tst_QObject::tst_QObject() +{ + +} + +tst_QObject::~tst_QObject() +{ + +} + +void tst_QObject::initTestCase() +{ +} + +void tst_QObject::cleanupTestCase() +{ +} + +void tst_QObject::init() +{ +} + +void tst_QObject::cleanup() +{ +} + +void tst_QObject::addSignal() +{ + MyDynamicObject myObj; + myObj.addSignal("testSignal()"); + + TestObject testObj; + + connect(&myObj, SIGNAL(testSignal()), &testObj, SLOT(slot1())); + connect(&myObj, SIGNAL(normalSignal()), &testObj, SLOT(slot2())); + + myObj.emitSignal("testSignal()"); + + QVERIFY(testObj.slot1Called); + QVERIFY(!testObj.slot2Called); + + testObj.slot1Called = false; + + myObj.emitNormalSignal(); + + QVERIFY(!testObj.slot1Called); + QVERIFY(testObj.slot2Called); + + // With parameter + myObj.addSignal("stringSignal(QString)"); + connect(&myObj, SIGNAL(stringSignal(QString)), &testObj, SLOT(slotString(QString))); + + QString param("Hello"); + myObj.emitSignal("stringSignal(QString)", Q_ARG(QString, param)); + + QCOMPARE(testObj.string, QString("Hello")); +} + +void tst_QObject::addSlot() +{ + MyDynamicObject myObj; + myObj.addSlot("testSlot1()"); + myObj.addSignal("testSignal()"); + myObj.addSlot("testSlot()"); + + TestObject testObj; + + connect(&testObj, SIGNAL(triggered()), &myObj, SLOT(testSlot())); + connect(&testObj, SIGNAL(triggered()), &myObj, SIGNAL(testSignal())); // signal chaining + connect(&myObj, SIGNAL(testSignal()), &testObj, SLOT(slot1())); + + testObj.emitSignal(); + + QCOMPARE(myObj.calledSlot(), QString("testSlot()")); + QVERIFY(testObj.slot1Called); + + // Verify parameter type and name + myObj.addSlot("string(QString)", QList<QByteArray>() << "name"); + int idx = myObj.metaObject()->indexOfSlot("string(QString)"); + QVERIFY(idx > 0); + QMetaMethod method = myObj.metaObject()->method(idx); + QVERIFY(method.parameterTypes()[0] == "QString"); + QVERIFY(method.parameterNames()[0] == "name"); + + connect(&testObj, SIGNAL(textChanged(QString)), &myObj, SLOT(string(QString))); + testObj.setText("Hello"); + QCOMPARE(myObj.dynamicMeta->string, QString("Hello")); +} + +void tst_QObject::addProperty() +{ + MyDynamicObject myObj; + myObj.addSignal("propChanged()"); + myObj.addProperty("myProp", QVariant::typeToName(QVariant::String), "propChanged()"); + + myObj.setProperty("myProp", QString("hello")); + qDebug() << "property value" << myObj.property("myProp").toString(); + QCOMPARE(myObj.property("myProp").toString(), QString("hello")); + + TestObject testObj; + connect(&myObj, SIGNAL(propChanged()), &testObj, SLOT(slot1())); + myObj.setProperty("myProp", QString("there")); + + QCOMPARE(myObj.property("myProp").toString(), QString("there")); + QVERIFY(testObj.slot1Called); +} + +void tst_QObject::dynamicProperty() +{ + MyDynamicObject myObj; + + myObj.setProperty("dynamicProp", QString("hello")); + qDebug() << "property value" << myObj.property("dynamicProp").toString(); + QCOMPARE(myObj.property("dynamicProp").toString(), QString("hello")); +} + +QTEST_MAIN(tst_QObject) +#include "tst_qobject.moc" diff --git a/tests/auto/qmake/testdata/bundle-spaces/some-file b/tests/auto/qmake/testdata/bundle-spaces/some-file index 9975dba..e69de29 100644 --- a/tests/auto/qmake/testdata/bundle-spaces/some-file +++ b/tests/auto/qmake/testdata/bundle-spaces/some-file @@ -1,6 +0,0 @@ -all: - C:\git\qt-kinetic-animations\bin\qmake qdir.pro -o Makefile -spec win32-msvc2008 - nmake -f Makefile -first: all -qmake: - C:\git\qt-kinetic-animations\bin\qmake qdir.pro -o Makefile -spec win32-msvc2008 |