From 7db99f103981b6b45cb70a5837eb6b439d33e207 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Mon, 16 Nov 2009 18:30:04 +1000 Subject: Tests --- src/declarative/qml/qmlcompiler.cpp | 4 +- src/declarative/qml/qmlcomponent.h | 3 + src/declarative/qml/qmlengine.cpp | 75 ++++++++++++---------- tests/auto/declarative/qmlengine/tst_qmlengine.cpp | 53 +++++++++++++++ .../declarative/qmlqt/data/createComponent.qml | 23 +++++++ .../declarative/qmlqt/data/createComponentData.qml | 5 ++ .../declarative/qmlqt/data/createQmlObject.qml | 31 +++++++++ tests/auto/declarative/qmlqt/tst_qmlqt.cpp | 53 +++++++++++++++ 8 files changed, 211 insertions(+), 36 deletions(-) create mode 100644 tests/auto/declarative/qmlqt/data/createComponent.qml create mode 100644 tests/auto/declarative/qmlqt/data/createComponentData.qml create mode 100644 tests/auto/declarative/qmlqt/data/createQmlObject.qml diff --git a/src/declarative/qml/qmlcompiler.cpp b/src/declarative/qml/qmlcompiler.cpp index 2cb44a3..9000339 100644 --- a/src/declarative/qml/qmlcompiler.cpp +++ b/src/declarative/qml/qmlcompiler.cpp @@ -2044,12 +2044,12 @@ bool QmlCompiler::checkDynamicMeta(QmlParser::Object *obj) if (prop.isDefaultProperty) { if (seenDefaultProperty) - COMPILE_EXCEPTION(obj, qApp->translate("QmlCompiler","Duplicate default property")); + COMPILE_EXCEPTION(&prop, qApp->translate("QmlCompiler","Duplicate default property")); seenDefaultProperty = true; } if (propNames.contains(prop.name)) - COMPILE_EXCEPTION(obj, qApp->translate("QmlCompiler","Duplicate property name")); + COMPILE_EXCEPTION(&prop, qApp->translate("QmlCompiler","Duplicate property name")); propNames.insert(prop.name); } diff --git a/src/declarative/qml/qmlcomponent.h b/src/declarative/qml/qmlcomponent.h index 835bdc5..0abb58f 100644 --- a/src/declarative/qml/qmlcomponent.h +++ b/src/declarative/qml/qmlcomponent.h @@ -67,6 +67,9 @@ class Q_DECLARATIVE_EXPORT QmlComponent : public QObject Q_PROPERTY(bool isReady READ isReady NOTIFY statusChanged) Q_PROPERTY(bool isError READ isError NOTIFY statusChanged) Q_PROPERTY(bool isLoading READ isLoading NOTIFY statusChanged) + Q_PROPERTY(qreal progress READ progress NOTIFY progressChanged) + Q_PROPERTY(Status status READ status NOTIFY statusChanged) + Q_PROPERTY(QUrl url READ url CONSTANT) public: QmlComponent(QObject *parent = 0); diff --git a/src/declarative/qml/qmlengine.cpp b/src/declarative/qml/qmlengine.cpp index 1483c8c..9abd216 100644 --- a/src/declarative/qml/qmlengine.cpp +++ b/src/declarative/qml/qmlengine.cpp @@ -572,23 +572,23 @@ QmlContext *QmlEnginePrivate::getContext(QScriptContext *ctxt) QScriptValue QmlEnginePrivate::createComponent(QScriptContext *ctxt, QScriptEngine *engine) { - QmlComponent* c; - QmlEnginePrivate *activeEnginePriv = static_cast(engine)->p; QmlEngine* activeEngine = activeEnginePriv->q_func(); QmlContext* context = activeEnginePriv->getContext(ctxt); + Q_ASSERT(context); if(ctxt->argumentCount() != 1) { - c = new QmlComponent(activeEngine); + return engine->nullValue(); }else{ - QUrl url = QUrl(context->resolvedUrl(ctxt->argument(0).toString())); - if(!url.isValid()) - url = QUrl(ctxt->argument(0).toString()); - c = new QmlComponent(activeEngine, url, activeEngine); + QString arg = ctxt->argument(0).toString(); + if (arg.isEmpty()) + return engine->nullValue(); + QUrl url = QUrl(context->resolvedUrl(arg)); + QmlComponent *c = new QmlComponent(activeEngine, url, activeEngine); + c->setCreationContext(context); + return activeEnginePriv->objectClass->newQObject(c, qMetaTypeId()); } - c->setCreationContext(context); - return engine->newQObject(c); } QScriptValue QmlEnginePrivate::createQmlObject(QScriptContext *ctxt, QScriptEngine *engine) @@ -597,57 +597,64 @@ QScriptValue QmlEnginePrivate::createQmlObject(QScriptContext *ctxt, QScriptEngi static_cast(engine)->p; QmlEngine* activeEngine = activeEnginePriv->q_func(); - if(ctxt->argumentCount() < 2) + if(ctxt->argumentCount() < 2 || ctxt->argumentCount() > 3) return engine->nullValue(); + QmlContext* context = activeEnginePriv->getContext(ctxt); + Q_ASSERT(context); + QString qml = ctxt->argument(0).toString(); + if (qml.isEmpty()) + return engine->nullValue(); + QUrl url; if(ctxt->argumentCount() > 2) url = QUrl(ctxt->argument(2).toString()); + + if (url.isValid() && url.isRelative()) + url = context->resolvedUrl(url); + QObject *parentArg = activeEnginePriv->objectClass->toQObject(ctxt->argument(1)); - QmlContext *qmlCtxt = qmlContext(parentArg); - if(!parentArg || !qmlCtxt){ - //TODO: Could use a qmlInfo() like function for script functions - qWarning() << "createQmlObject called with invalid parent object"; + if(!parentArg) return engine->nullValue(); - } - if (url.isEmpty()) { - url = qmlCtxt->resolvedUrl(QUrl(QLatin1String(""))); - } else { - url = qmlCtxt->resolvedUrl(url); - } QmlComponent component(activeEngine, qml.toUtf8(), url); if(component.isError()) { QList errors = component.errors(); - qWarning() <<"QmlEngine::createQmlObject():"; + qWarning().nospace() << "QmlEngine::createQmlObject():"; foreach (const QmlError &error, errors) - qWarning() << " " << error; + qWarning().nospace() << " " << error; + + return engine->nullValue(); + } + + if (!component.isReady()) { + qWarning().nospace() << "QmlEngine::createQmlObject(): Component is not ready"; return engine->nullValue(); } - QObject *obj = component.create(qmlCtxt); + QObject *obj = component.create(context); if(component.isError()) { QList errors = component.errors(); - qWarning() <<"QmlEngine::createQmlObject():"; + qWarning().nospace() << "QmlEngine::createQmlObject():"; foreach (const QmlError &error, errors) - qWarning() << " " << error; + qWarning().nospace() << " " << error; return engine->nullValue(); } - if(obj) { - obj->setParent(parentArg); - QGraphicsObject* gobj = qobject_cast(obj); - QGraphicsObject* gparent = qobject_cast(parentArg); - if(gobj && gparent) - gobj->setParentItem(gparent); - return qmlScriptObject(obj, activeEngine); - } - return engine->nullValue(); + Q_ASSERT(obj); + + obj->setParent(parentArg); + QGraphicsObject* gobj = qobject_cast(obj); + QGraphicsObject* gparent = qobject_cast(parentArg); + if(gobj && gparent) + gobj->setParentItem(gparent); + + return qmlScriptObject(obj, activeEngine); } QScriptValue QmlEnginePrivate::vector(QScriptContext *ctxt, QScriptEngine *engine) diff --git a/tests/auto/declarative/qmlengine/tst_qmlengine.cpp b/tests/auto/declarative/qmlengine/tst_qmlengine.cpp index ef1eee5..54f916f 100644 --- a/tests/auto/declarative/qmlengine/tst_qmlengine.cpp +++ b/tests/auto/declarative/qmlengine/tst_qmlengine.cpp @@ -47,6 +47,7 @@ #include #include #include +#include class tst_qmlengine : public QObject { @@ -60,6 +61,7 @@ private slots: void baseUrl(); void contextForObject(); void offlineStoragePath(); + void clearComponentCache(); }; void tst_qmlengine::rootContext() @@ -171,6 +173,57 @@ void tst_qmlengine::offlineStoragePath() QCOMPARE(engine.offlineStoragePath(), QDir::homePath()); } +void tst_qmlengine::clearComponentCache() +{ + QmlEngine engine; + + // Create original qml file + { + QFile file("temp.qml"); + QVERIFY(file.open(QIODevice::WriteOnly)); + file.write("import Qt 4.6\nObject {\nproperty int test: 10\n}\n"); + file.close(); + } + + // Test "test" property + { + QmlComponent component(&engine, "temp.qml"); + QObject *obj = component.create(); + QVERIFY(obj != 0); + QCOMPARE(obj->property("test").toInt(), 10); + delete obj; + } + + // Modify qml file + { + QFile file("temp.qml"); + QVERIFY(file.open(QIODevice::WriteOnly)); + file.write("import Qt 4.6\nObject {\nproperty int test: 11\n}\n"); + file.close(); + } + + // Test cache hit + { + QmlComponent component(&engine, "temp.qml"); + QObject *obj = component.create(); + QVERIFY(obj != 0); + QCOMPARE(obj->property("test").toInt(), 10); + delete obj; + } + + // Clear cache + engine.clearComponentCache(); + + // Test cache refresh + { + QmlComponent component(&engine, "temp.qml"); + QObject *obj = component.create(); + QVERIFY(obj != 0); + QCOMPARE(obj->property("test").toInt(), 11); + delete obj; + } +} + QTEST_MAIN(tst_qmlengine) #include "tst_qmlengine.moc" diff --git a/tests/auto/declarative/qmlqt/data/createComponent.qml b/tests/auto/declarative/qmlqt/data/createComponent.qml new file mode 100644 index 0000000..57f50d8 --- /dev/null +++ b/tests/auto/declarative/qmlqt/data/createComponent.qml @@ -0,0 +1,23 @@ +import Qt 4.6 + +Object { + property bool incorrectArgCount1: false + property bool incorrectArgCount2: false + property bool emptyArg: false + + property string relativeUrl + property string absoluteUrl + + Component.onCompleted: { + // Test that using incorrect argument count returns a null object + incorrectArgCount1 = (createComponent() == null); + incorrectArgCount2 = (createComponent("main.qml", 10) == null); + emptyArg = (createComponent("") == null); + + var r = createComponent("createComponentData.qml"); + relativeUrl = r.url; + + var a = createComponent("http://www.example.com/test.qml"); + absoluteUrl = a.url; + } +} diff --git a/tests/auto/declarative/qmlqt/data/createComponentData.qml b/tests/auto/declarative/qmlqt/data/createComponentData.qml new file mode 100644 index 0000000..145fe78 --- /dev/null +++ b/tests/auto/declarative/qmlqt/data/createComponentData.qml @@ -0,0 +1,5 @@ +import Qt 4.6 + +Object { + property int test: 1913 +} diff --git a/tests/auto/declarative/qmlqt/data/createQmlObject.qml b/tests/auto/declarative/qmlqt/data/createQmlObject.qml new file mode 100644 index 0000000..8e8919a --- /dev/null +++ b/tests/auto/declarative/qmlqt/data/createQmlObject.qml @@ -0,0 +1,31 @@ +import Qt 4.6 + +Item { + id: root + + property bool incorrectArgCount1: false + property bool incorrectArgCount2: false + property bool emptyArg: false + property bool noParent: false + property bool notReady: false + property bool runtimeError: false + property bool errors: false + + property bool success: false + + Component.onCompleted: { + // errors + incorrectArgCount1 = (createQmlObject() == null); + incorrectArgCount2 = (createQmlObject("import Qt 4.6\nObject{}", root, "main.qml", 10) == null); + emptyArg = (createQmlObject("", root) == null); + errors = (createQmlObject("import Qt 4.6\nObject{\nproperty int test: 13\nproperty int test: 13\n}", root, "main.qml") == null); + noParent = (createQmlObject("import Qt 4.6\nObject{\nproperty int test: 13}", 0) == null); + notReady = (createQmlObject("import Qt 4.6\nObject{\nBlah{}\n}", root, "http://www.example.com/main.qml") == null); + runtimeError = (createQmlObject("import Qt 4.6\nObject{property int test\nonTestChanged: Object{}\n}", root) == null); + + var o = createQmlObject("import Qt 4.6\nObject{\nproperty int test: 13\n}", root); + success = (o.test == 13); + + createQmlObject("import Qt 4.6\nItem {}\n", root); + } +} diff --git a/tests/auto/declarative/qmlqt/tst_qmlqt.cpp b/tests/auto/declarative/qmlqt/tst_qmlqt.cpp index 4d09aee..292102a 100644 --- a/tests/auto/declarative/qmlqt/tst_qmlqt.cpp +++ b/tests/auto/declarative/qmlqt/tst_qmlqt.cpp @@ -47,6 +47,7 @@ #include #include #include +#include class tst_qmlqt : public QObject { @@ -69,6 +70,8 @@ private slots: void playSound(); void openUrlExternally(); void md5(); + void createComponent(); + void createQmlObject(); private: QmlEngine engine; @@ -299,6 +302,56 @@ void tst_qmlqt::md5() delete object; } +void tst_qmlqt::createComponent() +{ + QmlComponent component(&engine, TEST_FILE("createComponent.qml")); + QObject *object = component.create(); + QVERIFY(object != 0); + + QCOMPARE(object->property("incorrectArgCount1").toBool(), true); + QCOMPARE(object->property("incorrectArgCount2").toBool(), true); + QCOMPARE(object->property("emptyArg").toBool(), true); + + QCOMPARE(object->property("absoluteUrl").toString(), QString("http://www.example.com/test.qml")); + QCOMPARE(object->property("relativeUrl").toString(), TEST_FILE("createComponentData.qml").toString()); + + delete object; +} + +void tst_qmlqt::createQmlObject() +{ + QmlComponent component(&engine, TEST_FILE("createQmlObject.qml")); + + QString warning1 = "QmlEngine::createQmlObject():"; + QString warning2 = " " + TEST_FILE("main.qml").toString() + ":4:1: Duplicate property name"; + QString warning3 = "QmlEngine::createQmlObject(): Component is not ready"; + QString warning4 = "QmlEngine::createQmlObject():"; + QString warning5 = " :3: Cannot assign object type QObject with no default method"; + + QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1)); + QTest::ignoreMessage(QtWarningMsg, qPrintable(warning2)); + QTest::ignoreMessage(QtWarningMsg, qPrintable(warning3)); + QTest::ignoreMessage(QtWarningMsg, qPrintable(warning4)); + QTest::ignoreMessage(QtWarningMsg, qPrintable(warning5)); + + QObject *object = component.create(); + QVERIFY(object != 0); + + QCOMPARE(object->property("incorrectArgCount1").toBool(), true); + QCOMPARE(object->property("incorrectArgCount2").toBool(), true); + QCOMPARE(object->property("emptyArg").toBool(), true); + QCOMPARE(object->property("errors").toBool(), true); + QCOMPARE(object->property("noParent").toBool(), true); + QCOMPARE(object->property("notReady").toBool(), true); + QCOMPARE(object->property("runtimeError").toBool(), true); + QCOMPARE(object->property("success").toBool(), true); + + QmlGraphicsItem *item = qobject_cast(object); + QVERIFY(item != 0); + QVERIFY(item->childItems().count() == 1); + + delete object; +} QTEST_MAIN(tst_qmlqt) -- cgit v0.12 From 89464ba786864f8a905c0d9939033970ac10f978 Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Tue, 17 Nov 2009 09:42:38 +1000 Subject: Add missing file. --- tests/auto/declarative/states/data/propertyErrors.qml | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 tests/auto/declarative/states/data/propertyErrors.qml diff --git a/tests/auto/declarative/states/data/propertyErrors.qml b/tests/auto/declarative/states/data/propertyErrors.qml new file mode 100644 index 0000000..270462e --- /dev/null +++ b/tests/auto/declarative/states/data/propertyErrors.qml @@ -0,0 +1,10 @@ +import Qt 4.6 +Rectangle { + id: MyRectangle + width: 100; height: 100 + color: "red" + states: State { + name: "blue" + PropertyChanges { target: MyRectangle; colr: "blue"; wantsFocus: true } + } +} -- cgit v0.12 From b06323a055b19164601d8f6a5d11eaa247310bb2 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Tue, 17 Nov 2009 10:06:49 +1000 Subject: Fix listview highlight tests. --- .../auto/declarative/qmlgraphicslistview/tst_qmlgraphicslistview.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/auto/declarative/qmlgraphicslistview/tst_qmlgraphicslistview.cpp b/tests/auto/declarative/qmlgraphicslistview/tst_qmlgraphicslistview.cpp index 7e6dc0d..5a557bf 100644 --- a/tests/auto/declarative/qmlgraphicslistview/tst_qmlgraphicslistview.cpp +++ b/tests/auto/declarative/qmlgraphicslistview/tst_qmlgraphicslistview.cpp @@ -291,6 +291,7 @@ void tst_QmlGraphicsListView::items() QMetaObject::invokeMethod(canvas->root(), "checkProperties"); QVERIFY(testObject->error() == false); + QVERIFY(listview->highlightItem() != 0); QCOMPARE(listview->count(), model.count()); QCOMPARE(viewport->childItems().count(), model.count()+1); // assumes all are visible, +1 for the (default) highlight item @@ -315,6 +316,7 @@ void tst_QmlGraphicsListView::items() testObject->setInvalidHighlight(true); QMetaObject::invokeMethod(canvas->root(), "checkProperties"); QVERIFY(testObject->error() == false); + QVERIFY(listview->highlightItem() == 0); // set an empty model and confirm that items are destroyed T model2; @@ -1006,7 +1008,7 @@ void tst_QmlGraphicsListView::cacheBuffer() QVERIFY(viewport != 0); QVERIFY(listview->delegate() != 0); QVERIFY(listview->model() != 0); - QVERIFY(listview->highlight() == 0); + QVERIFY(listview->highlight() != 0); // Confirm items positioned correctly int itemCount = findItems(viewport, "wrapper").count(); -- cgit v0.12 From 5b3cc2f64f15b48edaa6f2470c96e87ab98390c5 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Tue, 17 Nov 2009 10:19:23 +1000 Subject: Improve ListView cacheBuffer test. --- .../qmlgraphicslistview/tst_qmlgraphicslistview.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/tests/auto/declarative/qmlgraphicslistview/tst_qmlgraphicslistview.cpp b/tests/auto/declarative/qmlgraphicslistview/tst_qmlgraphicslistview.cpp index 5a557bf..c5dadab 100644 --- a/tests/auto/declarative/qmlgraphicslistview/tst_qmlgraphicslistview.cpp +++ b/tests/auto/declarative/qmlgraphicslistview/tst_qmlgraphicslistview.cpp @@ -97,10 +97,12 @@ class TestObject : public QObject Q_PROPERTY(bool error READ error WRITE setError NOTIFY changedError) Q_PROPERTY(bool animate READ animate NOTIFY changedAnim) Q_PROPERTY(bool invalidHighlight READ invalidHighlight NOTIFY changedHl) + Q_PROPERTY(int cacheBuffer READ cacheBuffer NOTIFY changedCacheBuffer) public: TestObject(QObject *parent = 0) - : QObject(parent), mError(true), mAnimate(false), mInvalidHighlight(false) {} + : QObject(parent), mError(true), mAnimate(false), mInvalidHighlight(false) + , mCacheBuffer(0) {} bool error() const { return mError; } void setError(bool err) { mError = err; emit changedError(); } @@ -111,15 +113,20 @@ public: bool invalidHighlight() const { return mInvalidHighlight; } void setInvalidHighlight(bool invalid) { mInvalidHighlight = invalid; emit changedHl(); } + int cacheBuffer() const { return mCacheBuffer; } + void setCacheBuffer(int buffer) { mCacheBuffer = buffer; emit changedCacheBuffer(); } + signals: void changedError(); void changedAnim(); void changedHl(); + void changedCacheBuffer(); public: bool mError; bool mAnimate; bool mInvalidHighlight; + int mCacheBuffer; }; class TestModel : public QListModelInterface @@ -1019,7 +1026,7 @@ void tst_QmlGraphicsListView::cacheBuffer() QVERIFY(item->y() == i*20); } - listview->setCacheBuffer(400); + testObject->setCacheBuffer(400); QVERIFY(listview->cacheBuffer() == 400); int newItemCount = findItems(viewport, "wrapper").count(); -- cgit v0.12 From d2fc7cdc3eb436d4ed8149ec25f692864e518105 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Tue, 17 Nov 2009 11:01:29 +1000 Subject: Hit some more untested lines in ListView and GridView. --- .../tst_qmlgraphicsgridview.cpp | 36 ++++++++++++++++++++-- .../qmlgraphicslistview/data/listview.qml | 1 + .../tst_qmlgraphicslistview.cpp | 19 ++++++++++++ 3 files changed, 54 insertions(+), 2 deletions(-) diff --git a/tests/auto/declarative/qmlgraphicsgridview/tst_qmlgraphicsgridview.cpp b/tests/auto/declarative/qmlgraphicsgridview/tst_qmlgraphicsgridview.cpp index d0b7462..197191e 100644 --- a/tests/auto/declarative/qmlgraphicsgridview/tst_qmlgraphicsgridview.cpp +++ b/tests/auto/declarative/qmlgraphicsgridview/tst_qmlgraphicsgridview.cpp @@ -61,8 +61,8 @@ private slots: void inserted(); void removed(); void moved(); - void currentIndex(); void changeFlow(); + void currentIndex(); void defaultValues(); void properties(); @@ -310,7 +310,7 @@ void tst_QmlGraphicsGridView::removed() QmlView *canvas = createView(SRCDIR "/data/gridview.qml"); TestModel model; - for (int i = 0; i < 30; i++) + for (int i = 0; i < 40; i++) model.addItem("Item" + QString::number(i), ""); QmlContext *ctxt = canvas->rootContext(); @@ -388,6 +388,7 @@ void tst_QmlGraphicsGridView::removed() // Remove items before visible gridview->setViewportY(120); + QTest::qWait(500); gridview->setCurrentIndex(10); // let transitions settle. @@ -421,6 +422,14 @@ void tst_QmlGraphicsGridView::removed() QVERIFY(item->y() == (i/3)*60); } + // remove item outside current view. + gridview->setCurrentIndex(32); + QTest::qWait(500); + gridview->setViewportY(240); + + model.removeItem(30); + QVERIFY(gridview->currentIndex() == 31); + delete canvas; } @@ -623,6 +632,29 @@ void tst_QmlGraphicsGridView::currentIndex() QVERIFY(key.isAccepted()); QCOMPARE(gridview->currentIndex(), 0); + gridview->setFlow(QmlGraphicsGridView::TopToBottom); + + key = QKeyEvent(QEvent::KeyPress, Qt::Key_Right, Qt::NoModifier, "", false, 1); + QApplication::sendEvent(canvas, &key); + QVERIFY(key.isAccepted()); + QCOMPARE(gridview->currentIndex(), 5); + + key = QKeyEvent(QEvent::KeyPress, Qt::Key_Left, Qt::NoModifier, "", false, 1); + QApplication::sendEvent(canvas, &key); + QVERIFY(key.isAccepted()); + QCOMPARE(gridview->currentIndex(), 0); + + key = QKeyEvent(QEvent::KeyPress, Qt::Key_Down, Qt::NoModifier, "", false, 1); + QApplication::sendEvent(canvas, &key); + QVERIFY(key.isAccepted()); + QCOMPARE(gridview->currentIndex(), 1); + + key = QKeyEvent(QEvent::KeyPress, Qt::Key_Up, Qt::NoModifier, "", false, 1); + QApplication::sendEvent(canvas, &key); + QVERIFY(key.isAccepted()); + QCOMPARE(gridview->currentIndex(), 0); + + // turn off auto highlight gridview->setHighlightFollowsCurrentItem(false); QVERIFY(gridview->highlightFollowsCurrentItem() == false); diff --git a/tests/auto/declarative/qmlgraphicslistview/data/listview.qml b/tests/auto/declarative/qmlgraphicslistview/data/listview.qml index ec8bb68..b64b399 100644 --- a/tests/auto/declarative/qmlgraphicslistview/data/listview.qml +++ b/tests/auto/declarative/qmlgraphicslistview/data/listview.qml @@ -114,5 +114,6 @@ Rectangle { highlight: testObject.invalidHighlight ? invalidHl : myHighlight highlightMoveSpeed: 1000 highlightResizeSpeed: 1000 + cacheBuffer: testObject.cacheBuffer } } diff --git a/tests/auto/declarative/qmlgraphicslistview/tst_qmlgraphicslistview.cpp b/tests/auto/declarative/qmlgraphicslistview/tst_qmlgraphicslistview.cpp index c5dadab..36f4dc5 100644 --- a/tests/auto/declarative/qmlgraphicslistview/tst_qmlgraphicslistview.cpp +++ b/tests/auto/declarative/qmlgraphicslistview/tst_qmlgraphicslistview.cpp @@ -575,6 +575,25 @@ void tst_QmlGraphicsListView::removed(bool animated) QCOMPARE(item->y(),40+i*20.0); } + // remove current item beyond visible items. + listview->setCurrentIndex(20); + QTest::qWait(500); + model.removeItem(20); + QTest::qWait(500); + + QCOMPARE(listview->currentIndex(), 20); + QVERIFY(listview->currentItem() != 0); + + // remove item before current, but visible + listview->setCurrentIndex(8); + QTest::qWait(500); + QmlGraphicsItem *oldCurrent = listview->currentItem(); + model.removeItem(6); + QTest::qWait(500); + + QCOMPARE(listview->currentIndex(), 7); + QVERIFY(listview->currentItem() == oldCurrent); + delete canvas; } -- cgit v0.12 From 31d01e174c3a3a1bba2ec9bf40cdc22d4053d8ec Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Tue, 17 Nov 2009 11:51:40 +1000 Subject: More animation autotests. --- src/declarative/util/qmlanimation.cpp | 50 +++++----- src/declarative/util/qmlanimation_p.h | 2 +- src/declarative/util/qmlanimation_p_p.h | 2 +- .../auto/declarative/animations/tst_animations.cpp | 105 +++++++++++++++++++++ 4 files changed, 130 insertions(+), 29 deletions(-) diff --git a/src/declarative/util/qmlanimation.cpp b/src/declarative/util/qmlanimation.cpp index d78f0a1..780bc82 100644 --- a/src/declarative/util/qmlanimation.cpp +++ b/src/declarative/util/qmlanimation.cpp @@ -62,7 +62,7 @@ QT_BEGIN_NAMESPACE -QEasingCurve stringToCurve(const QString &curve) +static QEasingCurve stringToCurve(const QString &curve, QObject *obj) { QEasingCurve easingCurve; @@ -73,8 +73,7 @@ QEasingCurve stringToCurve(const QString &curve) if (hasParams) { QString easeName = curve.trimmed(); if (!easeName.endsWith(QLatin1Char(')'))) { - qWarning("QEasingCurve: Unmatched perenthesis in easing function '%s'", - qPrintable(curve)); + qmlInfo(obj) << obj->tr("Unmatched parenthesis in easing function \"%1\"").arg(curve); return easingCurve; } @@ -83,8 +82,8 @@ QEasingCurve stringToCurve(const QString &curve) easeName.mid(idx + 1, easeName.length() - 1 - idx - 1); normalizedCurve = easeName.left(idx); if (!normalizedCurve.startsWith(QLatin1String("ease"))) { - qWarning("QEasingCurve: Easing function '%s' must start with 'ease'", - qPrintable(curve)); + qmlInfo(obj) << obj->tr("Easing function \"%1\" must start with \"ease\"").arg(curve); + return easingCurve; } props = prop_str.split(QLatin1Char(',')); @@ -98,9 +97,8 @@ QEasingCurve stringToCurve(const QString &curve) int value = me.keyToValue(normalizedCurve.toUtf8().constData()); if (value < 0) { - qWarning("QEasingCurve: Unknown easing curve '%s'", - qPrintable(curve)); - value = 0; + qmlInfo(obj) << obj->tr("Unknown easing curve \"%1\"").arg(curve); + return easingCurve; } easingCurve.setType((QEasingCurve::Type)value); @@ -109,9 +107,8 @@ QEasingCurve stringToCurve(const QString &curve) int sep = str.indexOf(QLatin1Char(':')); if (sep == -1) { - qWarning("QEasingCurve: Improperly specified property in easing function '%s'", - qPrintable(curve)); - return easingCurve; + qmlInfo(obj) << obj->tr("Improperly specified parameter in easing function \"%1\"").arg(curve); + continue; } QString propName = str.left(sep).trimmed(); @@ -119,9 +116,8 @@ QEasingCurve stringToCurve(const QString &curve) qreal propValue = str.mid(sep + 1).trimmed().toDouble(&isOk); if (propName.isEmpty() || !isOk) { - qWarning("QEasingCurve: Improperly specified property in easing function '%s'", - qPrintable(curve)); - return easingCurve; + qmlInfo(obj) << obj->tr("Improperly specified parameter in easing function \"%1\"").arg(curve); + continue; } if (propName == QLatin1String("amplitude")) { @@ -130,10 +126,12 @@ QEasingCurve stringToCurve(const QString &curve) easingCurve.setPeriod(propValue); } else if (propName == QLatin1String("overshoot")) { easingCurve.setOvershoot(propValue); + } else { + qmlInfo(obj) << obj->tr("Unknown easing parameter \"%1\"").arg(propName); + continue; } } } - return easingCurve; } @@ -219,16 +217,14 @@ void QmlAbstractAnimationPrivate::commence() } } -//### make static? -QmlMetaProperty QmlAbstractAnimationPrivate::createProperty(QObject *obj, const QString &str) +QmlMetaProperty QmlAbstractAnimationPrivate::createProperty(QObject *obj, const QString &str, QObject *infoObj) { - Q_Q(QmlAbstractAnimation); QmlMetaProperty prop = QmlMetaProperty::createProperty(obj, str); if (!prop.isValid()) { - qmlInfo(q) << QmlAbstractAnimation::tr("Cannot animate non-existant property \"%1\"").arg(str); + qmlInfo(infoObj) << QmlAbstractAnimation::tr("Cannot animate non-existant property \"%1\"").arg(str); return QmlMetaProperty(); } else if (!prop.isWritable()) { - qmlInfo(q) << QmlAbstractAnimation::tr("Cannot animate read-only property \"%1\"").arg(str); + qmlInfo(infoObj) << QmlAbstractAnimation::tr("Cannot animate read-only property \"%1\"").arg(str); return QmlMetaProperty(); } return prop; @@ -436,7 +432,7 @@ void QmlAbstractAnimation::setTarget(QObject *o) d->target = o; if (d->target && !d->propertyName.isEmpty()) { - d->userProperty = d->createProperty(d->target, d->propertyName); + d->userProperty = d->createProperty(d->target, d->propertyName, this); } else { d->userProperty.invalidate(); } @@ -458,7 +454,7 @@ void QmlAbstractAnimation::setProperty(const QString &n) d->propertyName = n; if (d->target && !d->propertyName.isEmpty()) { - d->userProperty = d->createProperty(d->target, d->propertyName); + d->userProperty = d->createProperty(d->target, d->propertyName, this); } else { d->userProperty.invalidate(); } @@ -652,7 +648,7 @@ int QmlPauseAnimation::duration() const void QmlPauseAnimation::setDuration(int duration) { if (duration < 0) { - qWarning("QmlPauseAnimation: Cannot set a duration of < 0"); + qmlInfo(this) << tr("Cannot set a duration of < 0"); return; } @@ -1029,7 +1025,7 @@ void QmlPropertyAction::transition(QmlStateActions &actions, if (hasTarget && d->value.isValid()) { Action myAction; - myAction.property = d->createProperty(target(), d->propertyName); + myAction.property = d->createProperty(target(), d->propertyName, this); if (myAction.property.isValid()) { myAction.toValue = d->value; data->actions << myAction; @@ -1630,7 +1626,7 @@ int QmlPropertyAnimation::duration() const void QmlPropertyAnimation::setDuration(int duration) { if (duration < 0) { - qWarning("QmlPropertyAnimation: Cannot set a duration of < 0"); + qmlInfo(this) << tr("Cannot set a duration of < 0"); return; } @@ -1872,7 +1868,7 @@ void QmlPropertyAnimation::setEasing(const QString &e) return; d->easing = e; - d->va->setEasingCurve(stringToCurve(d->easing)); + d->va->setEasingCurve(stringToCurve(d->easing, this)); emit easingChanged(e); } @@ -2114,7 +2110,7 @@ void QmlPropertyAnimation::transition(QmlStateActions &actions, //an explicit animation has been specified if (hasTarget && d->toIsDefined) { Action myAction; - myAction.property = d->createProperty(target(), d->propertyName); + myAction.property = d->createProperty(target(), d->propertyName, this); if (myAction.property.isValid()) { if (d->fromIsDefined) { d->convertVariant(d->from, d->interpolatorType ? d->interpolatorType : myAction.property.propertyType()); diff --git a/src/declarative/util/qmlanimation_p.h b/src/declarative/util/qmlanimation_p.h index f126dee..87b6703 100644 --- a/src/declarative/util/qmlanimation_p.h +++ b/src/declarative/util/qmlanimation_p.h @@ -136,7 +136,7 @@ private Q_SLOTS: }; class QmlPauseAnimationPrivate; -class QmlPauseAnimation : public QmlAbstractAnimation +class Q_AUTOTEST_EXPORT QmlPauseAnimation : public QmlAbstractAnimation { Q_OBJECT Q_DECLARE_PRIVATE(QmlPauseAnimation) diff --git a/src/declarative/util/qmlanimation_p_p.h b/src/declarative/util/qmlanimation_p_p.h index e50415f..27c0cd7 100644 --- a/src/declarative/util/qmlanimation_p_p.h +++ b/src/declarative/util/qmlanimation_p_p.h @@ -208,7 +208,7 @@ public: QmlMetaProperty property; QmlAnimationGroup *group; - QmlMetaProperty createProperty(QObject *obj, const QString &str); + static QmlMetaProperty createProperty(QObject *obj, const QString &str, QObject *infoObj); }; class QmlPauseAnimationPrivate : public QmlAbstractAnimationPrivate diff --git a/tests/auto/declarative/animations/tst_animations.cpp b/tests/auto/declarative/animations/tst_animations.cpp index 2692cb6..2506337 100644 --- a/tests/auto/declarative/animations/tst_animations.cpp +++ b/tests/auto/declarative/animations/tst_animations.cpp @@ -57,6 +57,8 @@ private slots: void simpleNumber(); void simpleColor(); void alwaysRunToEnd(); + void complete(); + void resume(); void dotProperty(); void badTypes(); void badProperties(); @@ -64,6 +66,7 @@ private slots: void properties(); void propertiesTransition(); void easingStringConversion(); + void invalidDuration(); }; #define QTIMED_COMPARE(lhs, rhs) do { \ @@ -96,6 +99,7 @@ void tst_animations::simpleProperty() QVERIFY(animation.isRunning()); QVERIFY(animation.isPaused()); animation.setCurrentTime(125); + QVERIFY(animation.currentTime() == 125); QCOMPARE(rect.pos(), QPointF(100,100)); } @@ -120,6 +124,7 @@ void tst_animations::simpleNumber() QVERIFY(animation.isRunning()); QVERIFY(animation.isPaused()); animation.setCurrentTime(125); + QVERIFY(animation.currentTime() == 125); QCOMPARE(rect.x(), qreal(100)); } @@ -144,6 +149,7 @@ void tst_animations::simpleColor() QVERIFY(animation.isRunning()); QVERIFY(animation.isPaused()); animation.setCurrentTime(125); + QVERIFY(animation.currentTime() == 125); QCOMPARE(rect.color(), QColor::fromRgbF(0.498039, 0, 0.498039, 1)); } @@ -157,6 +163,8 @@ void tst_animations::alwaysRunToEnd() animation.setDuration(1000); animation.setRepeat(true); animation.setAlwaysRunToEnd(true); + QVERIFY(animation.repeat() == true); + QVERIFY(animation.alwaysRunToEnd() == true); animation.start(); QTest::qWait(1500); animation.stop(); @@ -165,6 +173,54 @@ void tst_animations::alwaysRunToEnd() QTIMED_COMPARE(rect.x(), qreal(200)); } +void tst_animations::complete() +{ + QmlGraphicsRectangle rect; + QmlPropertyAnimation animation; + animation.setTarget(&rect); + animation.setProperty("x"); + animation.setFrom(1); + animation.setTo(200); + animation.setDuration(500); + QVERIFY(animation.from() == 1); + animation.start(); + QTest::qWait(50); + animation.stop(); + QVERIFY(rect.x() != qreal(200)); + animation.start(); + QTest::qWait(50); + QVERIFY(animation.isRunning()); + animation.complete(); + QCOMPARE(rect.x(), qreal(200)); +} + +void tst_animations::resume() +{ + QmlGraphicsRectangle rect; + QmlPropertyAnimation animation; + animation.setTarget(&rect); + animation.setProperty("x"); + animation.setFrom(10); + animation.setTo(200); + animation.setDuration(500); + QVERIFY(animation.from() == 10); + + animation.start(); + QTest::qWait(50); + animation.pause(); + qreal x = rect.x(); + QVERIFY(x != qreal(200)); + QVERIFY(animation.isRunning()); + QVERIFY(animation.isPaused()); + + animation.resume(); + QVERIFY(animation.isRunning()); + QVERIFY(!animation.isPaused()); + QTest::qWait(50); + animation.stop(); + QVERIFY(rect.x() > x); +} + void tst_animations::dotProperty() { QmlGraphicsRectangle rect; @@ -180,6 +236,7 @@ void tst_animations::dotProperty() animation.start(); animation.pause(); animation.setCurrentTime(125); + QVERIFY(animation.currentTime() == 125); QCOMPARE(rect.border()->width(), 5); } @@ -427,6 +484,7 @@ void tst_animations::easingStringConversion() { QmlNumberAnimation *animation = new QmlNumberAnimation; animation->setEasing("easeInOutQuad"); + QCOMPARE(animation->easing(),QLatin1String("easeInOutQuad")); QCOMPARE(static_cast(((QmlAbstractAnimation*)animation)->qtAnimation())->easingCurve(), QEasingCurve(QEasingCurve::InOutQuad)); animation->setEasing("OutQuad"); @@ -436,9 +494,56 @@ void tst_animations::easingStringConversion() QCOMPARE(static_cast(((QmlAbstractAnimation*)animation)->qtAnimation())->easingCurve().type(), QEasingCurve::OutBounce); QCOMPARE(static_cast(((QmlAbstractAnimation*)animation)->qtAnimation())->easingCurve().amplitude(), qreal(5)); + animation->setEasing("easeOutElastic(amplitude: 5, period: 3)"); + QCOMPARE(static_cast(((QmlAbstractAnimation*)animation)->qtAnimation())->easingCurve().type(), QEasingCurve::OutElastic); + QCOMPARE(static_cast(((QmlAbstractAnimation*)animation)->qtAnimation())->easingCurve().amplitude(), qreal(5)); + QCOMPARE(static_cast(((QmlAbstractAnimation*)animation)->qtAnimation())->easingCurve().period(), qreal(3)); + + animation->setEasing("easeInOutBack(overshoot: 2)"); + QCOMPARE(static_cast(((QmlAbstractAnimation*)animation)->qtAnimation())->easingCurve().type(), QEasingCurve::InOutBack); + QCOMPARE(static_cast(((QmlAbstractAnimation*)animation)->qtAnimation())->easingCurve().overshoot(), qreal(2)); + + QTest::ignoreMessage(QtWarningMsg, "QML QmlNumberAnimation (unknown location) Unmatched parenthesis in easing function \"easeInOutBack(overshoot: 2\""); + animation->setEasing("easeInOutBack(overshoot: 2"); + QCOMPARE(static_cast(((QmlAbstractAnimation*)animation)->qtAnimation())->easingCurve().type(), QEasingCurve::Linear); + + QTest::ignoreMessage(QtWarningMsg, "QML QmlNumberAnimation (unknown location) Easing function \"InOutBack(overshoot: 2)\" must start with \"ease\""); + animation->setEasing("InOutBack(overshoot: 2)"); + QCOMPARE(static_cast(((QmlAbstractAnimation*)animation)->qtAnimation())->easingCurve().type(), QEasingCurve::Linear); + + QTest::ignoreMessage(QtWarningMsg, "QML QmlNumberAnimation (unknown location) Unknown easing curve \"NonExistantEase\""); + animation->setEasing("NonExistantEase"); + QCOMPARE(static_cast(((QmlAbstractAnimation*)animation)->qtAnimation())->easingCurve().type(), QEasingCurve::Linear); + + QTest::ignoreMessage(QtWarningMsg, "QML QmlNumberAnimation (unknown location) Improperly specified parameter in easing function \"easeInOutElastic(amplitude 5)\""); + animation->setEasing("easeInOutElastic(amplitude 5)"); + QCOMPARE(static_cast(((QmlAbstractAnimation*)animation)->qtAnimation())->easingCurve().type(), QEasingCurve::InOutElastic); + + QTest::ignoreMessage(QtWarningMsg, "QML QmlNumberAnimation (unknown location) Improperly specified parameter in easing function \"easeInOutElastic(amplitude: yes)\""); + animation->setEasing("easeInOutElastic(amplitude: yes)"); + QCOMPARE(static_cast(((QmlAbstractAnimation*)animation)->qtAnimation())->easingCurve().type(), QEasingCurve::InOutElastic); + QVERIFY(static_cast(((QmlAbstractAnimation*)animation)->qtAnimation())->easingCurve().amplitude() != qreal(5)); + + QTest::ignoreMessage(QtWarningMsg, "QML QmlNumberAnimation (unknown location) Unknown easing parameter \"nonexistantproperty\""); + animation->setEasing("easeOutQuad(nonexistantproperty: 12)"); + QCOMPARE(static_cast(((QmlAbstractAnimation*)animation)->qtAnimation())->easingCurve().type(), QEasingCurve::OutQuad); + delete animation; } +void tst_animations::invalidDuration() +{ + QmlPropertyAnimation *animation = new QmlPropertyAnimation; + QTest::ignoreMessage(QtWarningMsg, "QML QmlPropertyAnimation (unknown location) Cannot set a duration of < 0"); + animation->setDuration(-1); + QCOMPARE(animation->duration(), 250); + + QmlPauseAnimation *pauseAnimation = new QmlPauseAnimation; + QTest::ignoreMessage(QtWarningMsg, "QML QmlPauseAnimation (unknown location) Cannot set a duration of < 0"); + pauseAnimation->setDuration(-1); + QCOMPARE(pauseAnimation->duration(), 250); +} + QTEST_MAIN(tst_animations) #include "tst_animations.moc" -- cgit v0.12