diff options
Diffstat (limited to 'tests/auto')
157 files changed, 7575 insertions, 341 deletions
diff --git a/tests/auto/bic/tst_bic.cpp b/tests/auto/bic/tst_bic.cpp index fcf6deb..9ef2be1 100644 --- a/tests/auto/bic/tst_bic.cpp +++ b/tests/auto/bic/tst_bic.cpp @@ -135,6 +135,9 @@ tst_Bic::tst_Bic() /* This structure is semi-private and should never shrink */ bic.addBlacklistedClass(QLatin1String("QVFbHeader")); + + /* This structure has a version field that allows extension */ + bic.addBlacklistedClass(QLatin1String("QDeclarativePrivate::RegisterType")); } void tst_Bic::initTestCase_data() diff --git a/tests/auto/declarative/declarative.pro b/tests/auto/declarative/declarative.pro index f0fcfa9..1f0d32a 100644 --- a/tests/auto/declarative/declarative.pro +++ b/tests/auto/declarative/declarative.pro @@ -11,6 +11,7 @@ SUBDIRS += \ qdeclarativeanchors \ qdeclarativeanimatedimage \ qdeclarativeanimations \ + qdeclarativeapplication \ qdeclarativebehaviors \ qdeclarativebinding \ qdeclarativeborderimage \ @@ -45,6 +46,7 @@ SUBDIRS += \ qdeclarativemousearea \ qdeclarativeparticles \ qdeclarativepathview \ + qdeclarativepincharea \ qdeclarativepixmapcache \ qdeclarativepositioners \ qdeclarativeproperty \ diff --git a/tests/auto/declarative/qdeclarativeanimatedimage/data/hearts.gif b/tests/auto/declarative/qdeclarativeanimatedimage/data/hearts.gif Binary files differnew file mode 100644 index 0000000..cfb55f2 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeanimatedimage/data/hearts.gif diff --git a/tests/auto/declarative/qdeclarativeanimatedimage/data/hearts.qml b/tests/auto/declarative/qdeclarativeanimatedimage/data/hearts.qml new file mode 100644 index 0000000..8729dd2 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeanimatedimage/data/hearts.qml @@ -0,0 +1,6 @@ +import QtQuick 1.0 + +AnimatedImage { + source: "hearts.gif" + playing: false +} diff --git a/tests/auto/declarative/qdeclarativeanimatedimage/tst_qdeclarativeanimatedimage.cpp b/tests/auto/declarative/qdeclarativeanimatedimage/tst_qdeclarativeanimatedimage.cpp index 1790e92..eba4239 100644 --- a/tests/auto/declarative/qdeclarativeanimatedimage/tst_qdeclarativeanimatedimage.cpp +++ b/tests/auto/declarative/qdeclarativeanimatedimage/tst_qdeclarativeanimatedimage.cpp @@ -45,6 +45,7 @@ #include <private/qdeclarativerectangle_p.h> #include <private/qdeclarativeimage_p.h> #include <private/qdeclarativeanimatedimage_p.h> +#include <QSignalSpy> #include "../shared/testhttpserver.h" #include "../../../shared/util.h" @@ -66,13 +67,28 @@ private slots: void stopped(); void setFrame(); void frameCount(); + void mirror_running(); + void mirror_notRunning(); + void mirror_notRunning_data(); void remote(); void remote_data(); void sourceSize(); void sourceSizeReadOnly(); void invalidSource(); + +private: + QPixmap grabScene(QGraphicsScene *scene, int width, int height); }; +QPixmap tst_qdeclarativeanimatedimage::grabScene(QGraphicsScene *scene, int width, int height) +{ + QPixmap screenshot(width, height); + screenshot.fill(); + QPainter p_screenshot(&screenshot); + scene->render(&p_screenshot, QRect(0, 0, width, height), QRect(0, 0, width, height)); + return screenshot; +} + void tst_qdeclarativeanimatedimage::play() { QDeclarativeEngine engine; @@ -132,6 +148,93 @@ void tst_qdeclarativeanimatedimage::frameCount() delete anim; } +void tst_qdeclarativeanimatedimage::mirror_running() +{ + // test where mirror is set to true after animation has started + + QDeclarativeEngine engine; + QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/hearts.qml")); + QDeclarativeAnimatedImage *anim = qobject_cast<QDeclarativeAnimatedImage *>(component.create()); + QVERIFY(anim); + + QGraphicsScene scene; + int width = anim->property("width").toInt(); + int height = anim->property("height").toInt(); + scene.addItem(qobject_cast<QGraphicsObject *>(anim)); + + QCOMPARE(anim->currentFrame(), 0); + QPixmap frame0 = grabScene(&scene, width, height); + anim->setCurrentFrame(1); + QPixmap frame1 = grabScene(&scene, width, height); + + anim->setCurrentFrame(0); + + QSignalSpy spy(anim, SIGNAL(frameChanged())); + anim->setPlaying(true); + + QTRY_VERIFY(spy.count() == 1); spy.clear(); + anim->setProperty("mirror", true); + + QCOMPARE(anim->currentFrame(), 1); + QPixmap frame1_flipped = grabScene(&scene, width, height); + + QTRY_VERIFY(spy.count() == 1); spy.clear(); + QCOMPARE(anim->currentFrame(), 0); // animation only has 2 frames, should cycle back to first + QPixmap frame0_flipped = grabScene(&scene, width, height); + + QTransform transform; + transform.translate(width, 0).scale(-1, 1.0); + QPixmap frame0_expected = frame0.transformed(transform); + QPixmap frame1_expected = frame1.transformed(transform); + + QCOMPARE(frame0_flipped, frame0_expected); + QCOMPARE(frame1_flipped, frame1_expected); +} + +void tst_qdeclarativeanimatedimage::mirror_notRunning() +{ + QFETCH(QUrl, fileUrl); + + QDeclarativeEngine engine; + QDeclarativeComponent component(&engine, fileUrl); + QDeclarativeAnimatedImage *anim = qobject_cast<QDeclarativeAnimatedImage *>(component.create()); + QVERIFY(anim); + + QGraphicsScene scene; + int width = anim->property("width").toInt(); + int height = anim->property("height").toInt(); + scene.addItem(qobject_cast<QGraphicsObject *>(anim)); + QPixmap screenshot = grabScene(&scene, width, height); + + QTransform transform; + transform.translate(width, 0).scale(-1, 1.0); + QPixmap expected = screenshot.transformed(transform); + + int frame = anim->currentFrame(); + bool playing = anim->isPlaying(); + bool paused = anim->isPlaying(); + + anim->setProperty("mirror", true); + screenshot = grabScene(&scene, width, height); + + QCOMPARE(screenshot, expected); + + // mirroring should not change the current frame or playing status + QCOMPARE(anim->currentFrame(), frame); + QCOMPARE(anim->isPlaying(), playing); + QCOMPARE(anim->isPaused(), paused); + + delete anim; +} + +void tst_qdeclarativeanimatedimage::mirror_notRunning_data() +{ + QTest::addColumn<QUrl>("fileUrl"); + + QTest::newRow("paused") << QUrl::fromLocalFile(SRCDIR "/data/stickmanpause.qml"); + QTest::newRow("stopped") << QUrl::fromLocalFile(SRCDIR "/data/stickmanstopped.qml"); +} + void tst_qdeclarativeanimatedimage::remote() { QFETCH(QString, fileName); diff --git a/tests/auto/declarative/qdeclarativeapplication/qdeclarativeapplication.pro b/tests/auto/declarative/qdeclarativeapplication/qdeclarativeapplication.pro new file mode 100644 index 0000000..91e5468 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeapplication/qdeclarativeapplication.pro @@ -0,0 +1,5 @@ +load(qttest_p4) +contains(QT_CONFIG,declarative): QT += declarative gui +macx:CONFIG -= app_bundle + +SOURCES += tst_qdeclarativeapplication.cpp diff --git a/tests/auto/declarative/qdeclarativeapplication/tst_qdeclarativeapplication.cpp b/tests/auto/declarative/qdeclarativeapplication/tst_qdeclarativeapplication.cpp new file mode 100644 index 0000000..64f327b --- /dev/null +++ b/tests/auto/declarative/qdeclarativeapplication/tst_qdeclarativeapplication.cpp @@ -0,0 +1,123 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <qtest.h> +#include "../../../shared/util.h" +#include <QtDeclarative/qdeclarativecomponent.h> +#include <QtDeclarative/qdeclarativeengine.h> +#include <QtDeclarative/qdeclarativeitem.h> +#include <QtGui/qgraphicsview.h> +#include <QtGui/qgraphicsscene.h> + +class tst_qdeclarativeapplication : public QObject +{ + Q_OBJECT +public: + tst_qdeclarativeapplication(); + +private slots: + void active(); + void layoutDirection(); + +private: + QDeclarativeEngine engine; +}; + +tst_qdeclarativeapplication::tst_qdeclarativeapplication() +{ +} + +void tst_qdeclarativeapplication::active() +{ + QDeclarativeComponent component(&engine); + component.setData("import QtQuick 1.0; Item { property bool active: Qt.application.active }", QUrl::fromLocalFile("")); + QDeclarativeItem *item = qobject_cast<QDeclarativeItem *>(component.create()); + QVERIFY(item); + QGraphicsScene scene; + QGraphicsView view(&scene); + scene.addItem(item); + + // not active + QVERIFY(!item->property("active").toBool()); + QCOMPARE(item->property("active").toBool(), QApplication::activeWindow() != 0); + + // active + view.show(); + QApplication::setActiveWindow(&view); + QTest::qWaitForWindowShown(&view); + QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&view)); + QCOMPARE(item->property("active").toBool(), QApplication::activeWindow() != 0); + + // not active again + // on mac, setActiveWindow(0) on mac does not deactivate the current application + // (you have to switch to a different app or hide the current app to trigger this) +#if !defined(Q_WS_MAC) + QApplication::setActiveWindow(0); + QVERIFY(!item->property("active").toBool()); + QCOMPARE(item->property("active").toBool(), QApplication::activeWindow() != 0); +#endif +} + +void tst_qdeclarativeapplication::layoutDirection() +{ + QDeclarativeComponent component(&engine); + component.setData("import QtQuick 1.0; Item { property bool layoutDirection: Qt.application.layoutDirection }", QUrl::fromLocalFile("")); + QDeclarativeItem *item = qobject_cast<QDeclarativeItem *>(component.create()); + QVERIFY(item); + QGraphicsScene scene; + QGraphicsView view(&scene); + scene.addItem(item); + + // not mirrored + QCOMPARE(Qt::LayoutDirection(item->property("layoutDirection").toInt()), Qt::LeftToRight); + + // mirrored + QApplication::setLayoutDirection(Qt::RightToLeft); + QCOMPARE(Qt::LayoutDirection(item->property("layoutDirection").toInt()), Qt::RightToLeft); + + // not mirrored again + QApplication::setLayoutDirection(Qt::LeftToRight); + QCOMPARE(Qt::LayoutDirection(item->property("layoutDirection").toInt()), Qt::LeftToRight); +} + +QTEST_MAIN(tst_qdeclarativeapplication) + +#include "tst_qdeclarativeapplication.moc" diff --git a/tests/auto/declarative/qdeclarativeborderimage/data/heart200.png b/tests/auto/declarative/qdeclarativeborderimage/data/heart200.png Binary files differnew file mode 100644 index 0000000..5a31ae8 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeborderimage/data/heart200.png diff --git a/tests/auto/declarative/qdeclarativeborderimage/tst_qdeclarativeborderimage.cpp b/tests/auto/declarative/qdeclarativeborderimage/tst_qdeclarativeborderimage.cpp index bc2f170..d85b92a 100644 --- a/tests/auto/declarative/qdeclarativeborderimage/tst_qdeclarativeborderimage.cpp +++ b/tests/auto/declarative/qdeclarativeborderimage/tst_qdeclarativeborderimage.cpp @@ -43,6 +43,8 @@ #include <QTcpServer> #include <QTcpSocket> #include <QDir> +#include <QGraphicsScene> +#include <QPainter> #include <QtDeclarative/qdeclarativeengine.h> #include <QtDeclarative/qdeclarativecomponent.h> @@ -77,12 +79,15 @@ private slots: void clearSource(); void resized(); void smooth(); + void mirror(); void tileModes(); void sciSource(); void sciSource_data(); void invalidSciFile(); void pendingRemoteRequest(); void pendingRemoteRequest_data(); + void testQtQuick11Attributes(); + void testQtQuick11Attributes_data(); private: QDeclarativeEngine engine; @@ -153,6 +158,8 @@ void tst_qdeclarativeborderimage::imageSource() QTRY_VERIFY(obj->status() == QDeclarativeBorderImage::Ready); QCOMPARE(obj->width(), 120.); QCOMPARE(obj->height(), 120.); + QCOMPARE(obj->sourceSize().width(), 120); + QCOMPARE(obj->sourceSize().height(), 120); QCOMPARE(obj->horizontalTileMode(), QDeclarativeBorderImage::Stretch); QCOMPARE(obj->verticalTileMode(), QDeclarativeBorderImage::Stretch); } else { @@ -192,6 +199,8 @@ void tst_qdeclarativeborderimage::resized() QVERIFY(obj != 0); QCOMPARE(obj->width(), 300.); QCOMPARE(obj->height(), 300.); + QCOMPARE(obj->sourceSize().width(), 120); + QCOMPARE(obj->sourceSize().height(), 120); QCOMPARE(obj->horizontalTileMode(), QDeclarativeBorderImage::Stretch); QCOMPARE(obj->verticalTileMode(), QDeclarativeBorderImage::Stretch); @@ -214,6 +223,37 @@ void tst_qdeclarativeborderimage::smooth() delete obj; } +void tst_qdeclarativeborderimage::mirror() +{ + QString componentStr = "import QtQuick 1.0\nBorderImage { source: \"" SRCDIR "/data/heart200.png\"; smooth: true; width: 300; height: 300; border { top: 50; right: 50; bottom: 50; left: 50 } }"; + QDeclarativeComponent component(&engine); + component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QDeclarativeBorderImage *obj = qobject_cast<QDeclarativeBorderImage*>(component.create()); + QVERIFY(obj != 0); + + int width = obj->property("width").toInt(); + int height = obj->property("height").toInt(); + + QGraphicsScene scene; + scene.addItem(qobject_cast<QGraphicsObject *>(obj)); + QPixmap screenshot(width, height); + screenshot.fill(); + QPainter p_screenshot(&screenshot); + scene.render(&p_screenshot, QRect(0, 0, width, height), QRect(0, 0, width, height)); + + QTransform transform; + transform.translate(width, 0).scale(-1, 1.0); + QPixmap expected = screenshot.transformed(transform); + + obj->setProperty("mirror", true); + p_screenshot.fillRect(QRect(0, 0, width, height), Qt::white); + scene.render(&p_screenshot, QRect(0, 0, width, height), QRect(0, 0, width, height)); + + QCOMPARE(screenshot, expected); + + delete obj; +} + void tst_qdeclarativeborderimage::tileModes() { { @@ -342,6 +382,45 @@ void tst_qdeclarativeborderimage::pendingRemoteRequest_data() QTest::newRow("sci file") << "http://localhost/none.sci"; } +void tst_qdeclarativeborderimage::testQtQuick11Attributes() +{ + QFETCH(QString, code); + QFETCH(QString, warning); + QFETCH(QString, error); + + QDeclarativeEngine engine; + QObject *obj; + + QDeclarativeComponent valid(&engine); + valid.setData("import QtQuick 1.1; BorderImage { " + code.toUtf8() + " }", QUrl("")); + obj = valid.create(); + QVERIFY(obj); + QVERIFY(valid.errorString().isEmpty()); + delete obj; + + QDeclarativeComponent invalid(&engine); + invalid.setData("import QtQuick 1.0; BorderImage { " + code.toUtf8() + " }", QUrl("")); + QTest::ignoreMessage(QtWarningMsg, warning.toUtf8()); + obj = invalid.create(); + QCOMPARE(invalid.errorString(), error); + delete obj; +} + +void tst_qdeclarativeborderimage::testQtQuick11Attributes_data() +{ + QTest::addColumn<QString>("code"); + QTest::addColumn<QString>("warning"); + QTest::addColumn<QString>("error"); + + QTest::newRow("mirror") << "mirror: true" + << "QDeclarativeComponent: Component is not ready" + << ":1 \"BorderImage.mirror\" is not available in QtQuick 1.0.\n"; + + QTest::newRow("cache") << "cache: true" + << "QDeclarativeComponent: Component is not ready" + << ":1 \"BorderImage.cache\" is not available in QtQuick 1.0.\n"; +} + QTEST_MAIN(tst_qdeclarativeborderimage) #include "tst_qdeclarativeborderimage.moc" diff --git a/tests/auto/declarative/qdeclarativecomponent/data/createObjectWithScript.qml b/tests/auto/declarative/qdeclarativecomponent/data/createObjectWithScript.qml new file mode 100644 index 0000000..0da3bda --- /dev/null +++ b/tests/auto/declarative/qdeclarativecomponent/data/createObjectWithScript.qml @@ -0,0 +1,43 @@ +import QtQuick 1.0 + +Item{ + id: root + property QtObject declarativerectangle : null + property QtObject declarativeitem : null + + property QtObject bindingTestObject : null + property QtObject bindingThisTestObject : null + + Component{ + id: a + Rectangle { + property Rectangle innerRect: Rectangle { border.width: 20 } + } + } + Component{ + id: b + Item{ + property bool testBool: false + property int testInt: null + property QtObject testObject: null + } + } + + // test passing in bindings + width: 100 + Component { + id: c + Item { + property int testValue + width: 300 + } + } + + Component.onCompleted: { + root.declarativerectangle = a.createObject(root, {"x":17,"y":17, "color":"white", "border.width":3, "innerRect.border.width": 20}); + root.declarativeitem = b.createObject(root, {"x":17,"y":17,"testBool":true,"testInt":17,"testObject":root}); + + root.bindingTestObject = c.createObject(root, {'testValue': (function(){return width * 3}) }) // use root.width + root.bindingThisTestObject = c.createObject(root, {'testValue': (function(){return this.width * 3}) }) // use width of Item within 'c' + } +} diff --git a/tests/auto/declarative/qdeclarativecomponent/tst_qdeclarativecomponent.cpp b/tests/auto/declarative/qdeclarativecomponent/tst_qdeclarativecomponent.cpp index 4db538e..4340fce 100644 --- a/tests/auto/declarative/qdeclarativecomponent/tst_qdeclarativecomponent.cpp +++ b/tests/auto/declarative/qdeclarativecomponent/tst_qdeclarativecomponent.cpp @@ -44,6 +44,9 @@ #include <QtGui/qgraphicsitem.h> #include <QtDeclarative/qdeclarativeengine.h> #include <QtDeclarative/qdeclarativecomponent.h> +#include <QtDeclarative/qdeclarativeitem.h> +#include <QtDeclarative/qdeclarativeproperty.h> +#include <qcolor.h> #ifdef Q_OS_SYMBIAN // In Symbian OS test data is located in applications private dir @@ -60,6 +63,7 @@ private slots: void null(); void loadEmptyUrl(); void qmlCreateObject(); + void qmlCreateObjectWithProperties(); private: QDeclarativeEngine engine; @@ -118,6 +122,52 @@ void tst_qdeclarativecomponent::qmlCreateObject() QCOMPARE(testObject3->metaObject()->className(), "QDeclarativeGraphicsWidget"); } +void tst_qdeclarativecomponent::qmlCreateObjectWithProperties() +{ + QDeclarativeEngine engine; + QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/createObjectWithScript.qml")); + QVERIFY2(component.errorString().isEmpty(), component.errorString().toUtf8()); + QObject *object = component.create(); + QVERIFY(object != 0); + + QObject *testObject1 = object->property("declarativerectangle").value<QObject*>(); + QVERIFY(testObject1); + QVERIFY(testObject1->parent() == object); + QCOMPARE(testObject1->property("x").value<int>(), 17); + QCOMPARE(testObject1->property("y").value<int>(), 17); + QCOMPARE(testObject1->property("color").value<QColor>(), QColor(255,255,255)); + QCOMPARE(QDeclarativeProperty::read(testObject1,"border.width").toInt(), 3); + QCOMPARE(QDeclarativeProperty::read(testObject1,"innerRect.border.width").toInt(), 20); + delete testObject1; + + QObject *testObject2 = object->property("declarativeitem").value<QObject*>(); + QVERIFY(testObject2); + QVERIFY(testObject2->parent() == object); + //QCOMPARE(testObject2->metaObject()->className(), "QDeclarativeItem_QML_2"); + QCOMPARE(testObject2->property("x").value<int>(), 17); + QCOMPARE(testObject2->property("y").value<int>(), 17); + QCOMPARE(testObject2->property("testBool").value<bool>(), true); + QCOMPARE(testObject2->property("testInt").value<int>(), 17); + QCOMPARE(testObject2->property("testObject").value<QObject*>(), object); + delete testObject2; + + QObject *testBindingObj = object->property("bindingTestObject").value<QObject*>(); + QVERIFY(testBindingObj); + QCOMPARE(testBindingObj->parent(), object); + QCOMPARE(testBindingObj->property("testValue").value<int>(), 300); + object->setProperty("width", 150); + QCOMPARE(testBindingObj->property("testValue").value<int>(), 150 * 3); + delete testBindingObj; + + QObject *testBindingThisObj = object->property("bindingThisTestObject").value<QObject*>(); + QVERIFY(testBindingThisObj); + QCOMPARE(testBindingThisObj->parent(), object); + QCOMPARE(testBindingThisObj->property("testValue").value<int>(), 900); + testBindingThisObj->setProperty("width", 200); + QCOMPARE(testBindingThisObj->property("testValue").value<int>(), 200 * 3); + delete testBindingThisObj; +} + QTEST_MAIN(tst_qdeclarativecomponent) #include "tst_qdeclarativecomponent.moc" diff --git a/tests/auto/declarative/qdeclarativedebug/tst_qdeclarativedebug.cpp b/tests/auto/declarative/qdeclarativedebug/tst_qdeclarativedebug.cpp index 7ccedfd..917b8d8 100644 --- a/tests/auto/declarative/qdeclarativedebug/tst_qdeclarativedebug.cpp +++ b/tests/auto/declarative/qdeclarativedebug/tst_qdeclarativedebug.cpp @@ -72,7 +72,7 @@ class tst_QDeclarativeDebug : public QObject Q_OBJECT private: - QDeclarativeDebugObjectReference findRootObject(int context = 0); + QDeclarativeDebugObjectReference findRootObject(int context = 0, bool recursive = false); QDeclarativeDebugPropertyReference findProperty(const QList<QDeclarativeDebugPropertyReference> &props, const QString &name) const; void waitForQuery(QDeclarativeDebugQuery *query); @@ -114,9 +114,11 @@ private slots: void tst_QDeclarativeDebugPropertyReference(); void setMethodBody(); + void queryObjectTree(); + void setBindingInStates(); }; -QDeclarativeDebugObjectReference tst_QDeclarativeDebug::findRootObject(int context) +QDeclarativeDebugObjectReference tst_QDeclarativeDebug::findRootObject(int context, bool recursive) { QDeclarativeDebugEnginesQuery *q_engines = m_dbg->queryAvailableEngines(this); waitForQuery(q_engines); @@ -128,7 +130,9 @@ QDeclarativeDebugObjectReference tst_QDeclarativeDebug::findRootObject(int conte if (q_context->rootContext().objects().count() == 0) return QDeclarativeDebugObjectReference(); - QDeclarativeDebugObjectQuery *q_obj = m_dbg->queryObject(q_context->rootContext().objects()[context], this); + QDeclarativeDebugObjectQuery *q_obj = recursive ? + m_dbg->queryObjectRecursive(q_context->rootContext().objects()[context], this) : + m_dbg->queryObject(q_context->rootContext().objects()[context], this); waitForQuery(q_obj); QDeclarativeDebugObjectReference result = q_obj->object(); @@ -308,6 +312,34 @@ void tst_QDeclarativeDebug::initTestCase() "function myMethodIndirect() { myMethod(3); }\n" "}"; + // and a fourth to test states + qml << "import QtQuick 1.0\n" + "Rectangle {\n" + "id:rootRect\n" + "width:100\n" + "states: [\n" + "State {\n" + "name:\"state1\"\n" + "PropertyChanges {\n" + "target:rootRect\n" + "width:200\n" + "}\n" + "}\n" + "]\n" + "transitions: [\n" + "Transition {\n" + "from:\"*\"\n" + "to:\"state1\"\n" + "PropertyAnimation {\n" + "target:rootRect\n" + "property:\"width\"\n" + "duration:100\n" + "}\n" + "}\n" + "]\n" + "}\n" + ; + for (int i=0; i<qml.count(); i++) { QDeclarativeComponent component(m_engine); component.setData(qml[i], QUrl::fromLocalFile("")); @@ -635,14 +667,14 @@ void tst_QDeclarativeDebug::queryRootContexts() QCOMPARE(context.debugId(), QDeclarativeDebugService::idForObject(actualContext)); QCOMPARE(context.name(), actualContext->objectName()); - QCOMPARE(context.objects().count(), 3); // 3 qml component objects created for context in main() + QCOMPARE(context.objects().count(), 4); // 4 qml component objects created for context in main() // root context query sends only root object data - it doesn't fill in // the children or property info QCOMPARE(context.objects()[0].properties().count(), 0); QCOMPARE(context.objects()[0].children().count(), 0); - QCOMPARE(context.contexts().count(), 4); + QCOMPARE(context.contexts().count(), 5); QVERIFY(context.contexts()[0].debugId() >= 0); QCOMPARE(context.contexts()[0].name(), QString("tst_QDeclarativeDebug_childContext")); @@ -897,6 +929,162 @@ void tst_QDeclarativeDebug::tst_QDeclarativeDebugPropertyReference() compareProperties(r, ref); } +void tst_QDeclarativeDebug::setBindingInStates() +{ + // Check if changing bindings of propertychanges works + + const int sourceIndex = 3; + + QDeclarativeDebugObjectReference obj = findRootObject(sourceIndex); + + QVERIFY(obj.debugId() != -1); + QVERIFY(obj.children().count() >= 2); + + // We are going to switch state a couple of times, we need to get rid of the transition before + QDeclarativeDebugExpressionQuery *q_deleteTransition = m_dbg->queryExpressionResult(obj.debugId(),QString("transitions = []"),this); + waitForQuery(q_deleteTransition); + delete q_deleteTransition; + + + // check initial value of the property that is changing + QDeclarativeDebugExpressionQuery *q_setState; + q_setState = m_dbg->queryExpressionResult(obj.debugId(),QString("state=\"state1\""),this); + waitForQuery(q_setState); + delete q_setState; + + obj = findRootObject(sourceIndex); + QCOMPARE(findProperty(obj.properties(),"width").value().toInt(),200); + + + q_setState = m_dbg->queryExpressionResult(obj.debugId(),QString("state=\"\""),this); + waitForQuery(q_setState); + delete q_setState; + + + obj = findRootObject(sourceIndex, true); + QCOMPARE(findProperty(obj.properties(),"width").value().toInt(),100); + + + // change the binding + QDeclarativeDebugObjectReference state = obj.children()[0]; + QCOMPARE(state.className(), QString("State")); + QVERIFY(state.children().count() > 0); + + QDeclarativeDebugObjectReference propertyChange = state.children()[0]; + QVERIFY(propertyChange.debugId() != -1); + + QVERIFY( m_dbg->setBindingForObject(propertyChange.debugId(), "width",QVariant(300),true) ); + + // check properties changed in state + obj = findRootObject(sourceIndex); + QCOMPARE(findProperty(obj.properties(),"width").value().toInt(),100); + + + q_setState = m_dbg->queryExpressionResult(obj.debugId(),QString("state=\"state1\""),this); + waitForQuery(q_setState); + delete q_setState; + + obj = findRootObject(sourceIndex); + QCOMPARE(findProperty(obj.properties(),"width").value().toInt(),300); + + // check changing properties of base state from within a state + QVERIFY(m_dbg->setBindingForObject(obj.debugId(),"width","height*2",false)); + QVERIFY(m_dbg->setBindingForObject(obj.debugId(),"height","200",true)); + + obj = findRootObject(sourceIndex); + QCOMPARE(findProperty(obj.properties(),"width").value().toInt(),300); + + q_setState = m_dbg->queryExpressionResult(obj.debugId(),QString("state=\"\""),this); + waitForQuery(q_setState); + delete q_setState; + + obj = findRootObject(sourceIndex); + QCOMPARE(findProperty(obj.properties(),"width").value().toInt(), 400); + + // reset binding while in a state + q_setState = m_dbg->queryExpressionResult(obj.debugId(),QString("state=\"state1\""),this); + waitForQuery(q_setState); + delete q_setState; + + obj = findRootObject(sourceIndex); + QCOMPARE(findProperty(obj.properties(),"width").value().toInt(), 300); + + m_dbg->resetBindingForObject(propertyChange.debugId(), "width"); + + obj = findRootObject(sourceIndex); + QCOMPARE(findProperty(obj.properties(),"width").value().toInt(), 400); + + // re-add binding + m_dbg->setBindingForObject(propertyChange.debugId(), "width", "300", true); + + obj = findRootObject(sourceIndex); + QCOMPARE(findProperty(obj.properties(),"width").value().toInt(), 300); +} + +void tst_QDeclarativeDebug::queryObjectTree() +{ + const int sourceIndex = 3; + + // Check if states/transitions are initialized when fetching root item + QDeclarativeDebugEnginesQuery *q_engines = m_dbg->queryAvailableEngines(this); + waitForQuery(q_engines); + + QDeclarativeDebugRootContextQuery *q_context = m_dbg->queryRootContexts(q_engines->engines()[0].debugId(), this); + waitForQuery(q_context); + + QVERIFY(q_context->rootContext().objects().count() > sourceIndex); + QDeclarativeDebugObjectReference rootObject = q_context->rootContext().objects()[sourceIndex]; + + QDeclarativeDebugObjectQuery *q_obj = m_dbg->queryObjectRecursive(rootObject, this); + waitForQuery(q_obj); + + QDeclarativeDebugObjectReference obj = q_obj->object(); + + delete q_engines; + delete q_context; + delete q_obj; + + QVERIFY(obj.debugId() != -1); + QVERIFY(obj.children().count() >= 2); + + + + // check state + QDeclarativeDebugObjectReference state = obj.children()[0]; + QCOMPARE(state.className(), QString("State")); + QVERIFY(state.children().count() > 0); + + QDeclarativeDebugObjectReference propertyChange = state.children()[0]; + QVERIFY(propertyChange.debugId() != -1); + + QDeclarativeDebugPropertyReference propertyChangeTarget = findProperty(propertyChange.properties(),"target"); + QCOMPARE(propertyChangeTarget.objectDebugId(), propertyChange.debugId()); + + QDeclarativeDebugObjectReference targetReference = qvariant_cast<QDeclarativeDebugObjectReference>(propertyChangeTarget.value()); + QVERIFY(targetReference.debugId() != -1); + + + + // check transition + QDeclarativeDebugObjectReference transition = obj.children()[1]; + QCOMPARE(transition.className(), QString("Transition")); + QCOMPARE(findProperty(transition.properties(),"from").value().toString(), QString("*")); + QCOMPARE(findProperty(transition.properties(),"to").value(), findProperty(state.properties(),"name").value()); + QVERIFY(transition.children().count() > 0); + + QDeclarativeDebugObjectReference animation = transition.children()[0]; + QVERIFY(animation.debugId() != -1); + + QDeclarativeDebugPropertyReference animationTarget = findProperty(animation.properties(),"target"); + QCOMPARE(animationTarget.objectDebugId(), animation.debugId()); + + targetReference = qvariant_cast<QDeclarativeDebugObjectReference>(animationTarget.value()); + QVERIFY(targetReference.debugId() != -1); + + QCOMPARE(findProperty(animation.properties(),"property").value().toString(), QString("width")); + QCOMPARE(findProperty(animation.properties(),"duration").value().toInt(), 100); +} + int main(int argc, char *argv[]) { int _argc = argc + 1; diff --git a/tests/auto/declarative/qdeclarativedebugclient/tst_qdeclarativedebugclient.cpp b/tests/auto/declarative/qdeclarativedebugclient/tst_qdeclarativedebugclient.cpp index e3f0349..c182893 100644 --- a/tests/auto/declarative/qdeclarativedebugclient/tst_qdeclarativedebugclient.cpp +++ b/tests/auto/declarative/qdeclarativedebugclient/tst_qdeclarativedebugclient.cpp @@ -76,7 +76,7 @@ void tst_QDeclarativeDebugClient::initTestCase() QTest::ignoreMessage(QtWarningMsg, "Qml debugging is enabled. Only use this in a safe environment!"); QDeclarativeDebugHelper::enableDebugging(); - QTest::ignoreMessage(QtWarningMsg, "QDeclarativeDebugServer: Waiting for connection on port 3770..."); + QTest::ignoreMessage(QtWarningMsg, "QDeclarativeDebugServer: Waiting for connection on port 13770..."); new QDeclarativeEngine(this); m_conn = new QDeclarativeDebugConnection(this); @@ -84,7 +84,7 @@ void tst_QDeclarativeDebugClient::initTestCase() QDeclarativeDebugTestClient client("tst_QDeclarativeDebugClient::handshake()", m_conn); QDeclarativeDebugTestService service("tst_QDeclarativeDebugClient::handshake()"); - m_conn->connectToHost("127.0.0.1", 3770); + m_conn->connectToHost("127.0.0.1", 13770); QTest::ignoreMessage(QtWarningMsg, "QDeclarativeDebugServer: Connection established"); bool ok = m_conn->waitForConnected(); @@ -149,7 +149,7 @@ int main(int argc, char *argv[]) char **_argv = new char*[_argc]; for (int i = 0; i < argc; ++i) _argv[i] = argv[i]; - _argv[_argc - 1] = "-qmljsdebugger=port:3770"; + _argv[_argc - 1] = "-qmljsdebugger=port:13770"; QApplication app(_argc, _argv); tst_QDeclarativeDebugClient tc; diff --git a/tests/auto/declarative/qdeclarativedebugservice/tst_qdeclarativedebugservice.cpp b/tests/auto/declarative/qdeclarativedebugservice/tst_qdeclarativedebugservice.cpp index aacdea5..0911a83 100644 --- a/tests/auto/declarative/qdeclarativedebugservice/tst_qdeclarativedebugservice.cpp +++ b/tests/auto/declarative/qdeclarativedebugservice/tst_qdeclarativedebugservice.cpp @@ -79,11 +79,11 @@ void tst_QDeclarativeDebugService::initTestCase() QTest::ignoreMessage(QtWarningMsg, "Qml debugging is enabled. Only use this in a safe environment!"); QDeclarativeDebugHelper::enableDebugging(); - QTest::ignoreMessage(QtWarningMsg, "QDeclarativeDebugServer: Waiting for connection on port 3769..."); + QTest::ignoreMessage(QtWarningMsg, "QDeclarativeDebugServer: Waiting for connection on port 13769..."); new QDeclarativeEngine(this); m_conn = new QDeclarativeDebugConnection(this); - m_conn->connectToHost("127.0.0.1", 3769); + m_conn->connectToHost("127.0.0.1", 13769); QTest::ignoreMessage(QtWarningMsg, "QDeclarativeDebugServer: Connection established"); bool ok = m_conn->waitForConnected(); @@ -133,6 +133,10 @@ void tst_QDeclarativeDebugService::sendMessage() client.sendMessage(msg); QByteArray resp = client.waitForResponse(); QCOMPARE(resp, msg); + + QTest::ignoreMessage(QtWarningMsg, "QDeclarativeDebugService: Conflicting plugin name \"tst_QDeclarativeDebugService::sendMessage()\" "); + QDeclarativeDebugService duplicate("tst_QDeclarativeDebugService::sendMessage()"); + duplicate.sendMessage("msg"); } void tst_QDeclarativeDebugService::idForObject() @@ -189,7 +193,7 @@ int main(int argc, char *argv[]) char **_argv = new char*[_argc]; for (int i = 0; i < argc; ++i) _argv[i] = argv[i]; - _argv[_argc - 1] = "-qmljsdebugger=port:3769"; + _argv[_argc - 1] = "-qmljsdebugger=port:13769"; QApplication app(_argc, _argv); tst_QDeclarativeDebugService tc; diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/functionAssignment.2.qml b/tests/auto/declarative/qdeclarativeecmascript/data/functionAssignment.2.qml index 948b39c..c8c926a 100644 --- a/tests/auto/declarative/qdeclarativeecmascript/data/functionAssignment.2.qml +++ b/tests/auto/declarative/qdeclarativeecmascript/data/functionAssignment.2.qml @@ -1,13 +1,73 @@ import Qt.test 1.0 +import QtQuick 1.0 + +import "functionAssignment.js" as Script MyQmlObject { property variant a - property bool runTest: false - onRunTestChanged: { + property int aNumber: 10 + + property bool assignToProperty: false + property bool assignToPropertyFromJsFile: false + + property bool assignWithThis: false + property bool assignWithThisFromJsFile: false + + property bool assignToValueType: false + + property bool assignFuncWithoutReturn: false + property bool assignWrongType: false + property bool assignWrongTypeToValueType: false + + + onAssignToPropertyChanged: { + function myFunction() { + return aNumber * 10; + } + a = myFunction; + } + + property QtObject obj: QtObject { + property int aNumber: 4212 + function myFunction() { + return this.aNumber * 10; // should use the aNumber from root, not this object + } + } + onAssignWithThisChanged: { + a = obj.myFunction; + } + + onAssignToPropertyFromJsFileChanged: { + Script.bindPropertyWithThis() + } + + onAssignWithThisFromJsFileChanged: { + Script.bindProperty() + } + + property Text text: Text { } + onAssignToValueTypeChanged: { + text.font.pixelSize = (function() { return aNumber * 10; }) + a = (function() { return text.font.pixelSize; }) + } + + + // detecting errors: + + onAssignFuncWithoutReturnChanged: { function myFunction() { - console.log("hello world"); } a = myFunction; } + onAssignWrongTypeChanged: { + function myFunction() { + return 'a string'; + } + aNumber = myFunction; + } + + onAssignWrongTypeToValueTypeChanged: { + text.font.pixelSize = (function() { return 'a string'; }) + } } diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/functionAssignment.js b/tests/auto/declarative/qdeclarativeecmascript/data/functionAssignment.js new file mode 100644 index 0000000..14daa76 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/functionAssignment.js @@ -0,0 +1,17 @@ +function bindProperty() +{ + a = (function(){ return aNumber * 10 }) +} + + +function TestObject() { } +TestObject.prototype.aNumber = 928349 +TestObject.prototype.bindFunction = function() { + return this.aNumber * 10 // this should not use the TestObject's aNumber +} +var testObj = new TestObject() + +function bindPropertyWithThis() +{ + a = testObj.bindFunction +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/metaobjectRevision.qml b/tests/auto/declarative/qdeclarativeecmascript/data/metaobjectRevision.qml new file mode 100644 index 0000000..77accd8 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/metaobjectRevision.qml @@ -0,0 +1,7 @@ +import Qt.test 1.1 + +MyRevisionedClass +{ + prop1: prop2 + onSignal1: method2() +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/metaobjectRevision2.qml b/tests/auto/declarative/qdeclarativeecmascript/data/metaobjectRevision2.qml new file mode 100644 index 0000000..36057cb --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/metaobjectRevision2.qml @@ -0,0 +1,9 @@ +import Qt.test 1.1 + +MyRevisionedSubclass +{ + prop1: prop3 + onSignal1: method2() + prop3: prop4 + onSignal3: method4() +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/metaobjectRevision3.qml b/tests/auto/declarative/qdeclarativeecmascript/data/metaobjectRevision3.qml new file mode 100644 index 0000000..81769e9 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/metaobjectRevision3.qml @@ -0,0 +1,8 @@ +import Qt.test 1.0 + +MyRevisionedSubclass +{ + prop1: prop3 + onSignal1: method1() + onSignal3: method3() +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/metaobjectRevision4.qml b/tests/auto/declarative/qdeclarativeecmascript/data/metaobjectRevision4.qml new file mode 100644 index 0000000..81ea536 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/metaobjectRevision4.qml @@ -0,0 +1,14 @@ +import Qt.test 1.1 +import QtQuick 1.0 + +QtObject { + property variant a + property real test + + a: MyRevisionedClass { + prop2: 11 + + Component.onCompleted: test = prop2 + } +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/metaobjectRevisionErrors.qml b/tests/auto/declarative/qdeclarativeecmascript/data/metaobjectRevisionErrors.qml new file mode 100644 index 0000000..44d421e --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/metaobjectRevisionErrors.qml @@ -0,0 +1,14 @@ +import QtQuick 1.0 +import Qt.test 1.0 + +MyRevisionedClass +{ + // Will not hit optimizer + property real p1: prop1 % 3 + property real p2: prop2 % 3 + + // Should hit optimizer + property real p3: prop2 + + Component.onCompleted: method2() +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/metaobjectRevisionErrors2.qml b/tests/auto/declarative/qdeclarativeecmascript/data/metaobjectRevisionErrors2.qml new file mode 100644 index 0000000..121642e --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/metaobjectRevisionErrors2.qml @@ -0,0 +1,24 @@ +import QtQuick 1.0 +import Qt.test 1.0 + +MyRevisionedSubclass +{ + // Will not hit optimizer + property real p1: prop1 % 3 + property real p2: prop2 % 3 + property real p3: prop3 % 3 + property real p4: prop4 % 3 + + // Should hit optimizer + property real p5: prop1 + property real p6: prop2 + property real p7: prop3 + property real p8: prop4 + + Component.onCompleted: { + method1() + method2() + method3() + method4() + } +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/metaobjectRevisionErrors3.qml b/tests/auto/declarative/qdeclarativeecmascript/data/metaobjectRevisionErrors3.qml new file mode 100644 index 0000000..123650e --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/metaobjectRevisionErrors3.qml @@ -0,0 +1,36 @@ +import QtQuick 1.0 +import Qt.test 1.1 + +MyRevisionedSubclass +{ + // Will not hit optimizer + property real pA: propA % 3 + property real pB: propB % 3 + property real pC: propC % 3 + property real pD: propD % 3 + property real p1: prop1 % 3 + property real p2: prop2 % 3 + property real p3: prop3 % 3 + property real p4: prop4 % 3 + + // Should hit optimizer + property real pE: propA + property real pF: propB + property real pG: propC + property real pH: propD + property real p5: prop1 + property real p6: prop2 + property real p7: prop3 + property real p8: prop4 + + Component.onCompleted: { + methodA() + methodB() + methodC() + methodD() + method1() + method2() + method3() + method4() + } +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/nonExistantAttachedObject.qml b/tests/auto/declarative/qdeclarativeecmascript/data/nonExistentAttachedObject.qml index f9585db..f9585db 100644 --- a/tests/auto/declarative/qdeclarativeecmascript/data/nonExistantAttachedObject.qml +++ b/tests/auto/declarative/qdeclarativeecmascript/data/nonExistentAttachedObject.qml diff --git a/tests/auto/declarative/qdeclarativeecmascript/testtypes.cpp b/tests/auto/declarative/qdeclarativeecmascript/testtypes.cpp index 1257da6..d7f0f42 100644 --- a/tests/auto/declarative/qdeclarativeecmascript/testtypes.cpp +++ b/tests/auto/declarative/qdeclarativeecmascript/testtypes.cpp @@ -113,6 +113,15 @@ void registerTypes() qmlRegisterType<NumberAssignment>("Qt.test", 1,0, "NumberAssignment"); qmlRegisterExtendedType<DefaultPropertyExtendedObject, DefaultPropertyExtensionObject>("Qt.test", 1,0, "DefaultPropertyExtendedObject"); qmlRegisterType<OverrideDefaultPropertyObject>("Qt.test", 1,0, "OverrideDefaultPropertyObject"); + qmlRegisterType<MyRevisionedClass>("Qt.test",1,0,"MyRevisionedClass"); + qmlRegisterType<MyRevisionedClass,1>("Qt.test",1,1,"MyRevisionedClass"); + + // Register the uncreatable base class + qmlRegisterRevision<MyRevisionedBaseClassRegistered,1>("Qt.test",1,1); + // MyRevisionedSubclass 1.0 uses MyRevisionedClass revision 0 + qmlRegisterType<MyRevisionedSubclass>("Qt.test",1,0,"MyRevisionedSubclass"); + // MyRevisionedSubclass 1.1 uses MyRevisionedClass revision 1 + qmlRegisterType<MyRevisionedSubclass,1>("Qt.test",1,1,"MyRevisionedSubclass"); qmlRegisterExtendedType<QWidget,QWidgetDeclarativeUI>("Qt.test",1,0,"QWidget"); qmlRegisterType<QPlainTextEdit>("Qt.test",1,0,"QPlainTextEdit"); diff --git a/tests/auto/declarative/qdeclarativeecmascript/testtypes.h b/tests/auto/declarative/qdeclarativeecmascript/testtypes.h index 6c6ad1f..fb54a54 100644 --- a/tests/auto/declarative/qdeclarativeecmascript/testtypes.h +++ b/tests/auto/declarative/qdeclarativeecmascript/testtypes.h @@ -738,6 +738,167 @@ public: OverrideDefaultPropertyObject() {} }; +class MyRevisionedBaseClassRegistered : public QObject +{ +Q_OBJECT + Q_PROPERTY(qreal propA READ propA WRITE setPropA NOTIFY propAChanged) + Q_PROPERTY(qreal propB READ propB WRITE setPropB NOTIFY propBChanged REVISION 1) + +public: + MyRevisionedBaseClassRegistered() : m_pa(1), m_pb(2) {} + + qreal propA() const { return m_pa; } + void setPropA(qreal p) { + if (p != m_pa) { + m_pa = p; + emit propAChanged(); + } + } + qreal propB() const { return m_pb; } + void setPropB(qreal p) { + if (p != m_pb) { + m_pb = p; + emit propBChanged(); + } + } + + Q_INVOKABLE void methodA() { } + Q_INVOKABLE Q_REVISION(1) void methodB() { } + +signals: + void propAChanged(); + void propBChanged(); + + void signalA(); + Q_REVISION(1) void signalB(); + +protected: + qreal m_pa; + qreal m_pb; +}; + +class MyRevisionedBaseClassUnregistered : public MyRevisionedBaseClassRegistered +{ +Q_OBJECT + Q_PROPERTY(qreal propC READ propC WRITE setPropC NOTIFY propCChanged) + Q_PROPERTY(qreal propD READ propD WRITE setPropD NOTIFY propDChanged REVISION 1) + +public: + MyRevisionedBaseClassUnregistered() : m_pc(1), m_pd(2) {} + + qreal propC() const { return m_pc; } + void setPropC(qreal p) { + if (p != m_pc) { + m_pc = p; + emit propCChanged(); + } + } + qreal propD() const { return m_pd; } + void setPropD(qreal p) { + if (p != m_pd) { + m_pd = p; + emit propDChanged(); + } + } + + Q_INVOKABLE void methodC() { } + Q_INVOKABLE Q_REVISION(1) void methodD() { } + +signals: + void propCChanged(); + void propDChanged(); + + void signalC(); + Q_REVISION(1) void signalD(); + +protected: + qreal m_pc; + qreal m_pd; +}; + +class MyRevisionedClass : public MyRevisionedBaseClassUnregistered +{ + Q_OBJECT + Q_PROPERTY(qreal prop1 READ prop1 WRITE setProp1 NOTIFY prop1Changed) + Q_PROPERTY(qreal prop2 READ prop2 WRITE setProp2 NOTIFY prop2Changed REVISION 1) + +public: + MyRevisionedClass() {} + + qreal prop1() const { return m_p1; } + void setProp1(qreal p) { + if (p != m_p1) { + m_p1 = p; + emit prop1Changed(); + } + } + qreal prop2() const { return m_p2; } + void setProp2(qreal p) { + if (p != m_p2) { + m_p2 = p; + emit prop2Changed(); + } + } + + Q_INVOKABLE void method1() { } + Q_INVOKABLE Q_REVISION(1) void method2() { } + +signals: + void prop1Changed(); + void prop2Changed(); + + void signal1(); + Q_REVISION(1) void signal2(); + +protected: + qreal m_p1; + qreal m_p2; +}; + +class MyRevisionedSubclass : public MyRevisionedClass +{ + Q_OBJECT + Q_PROPERTY(qreal prop3 READ prop3 WRITE setProp3 NOTIFY prop3Changed) + Q_PROPERTY(qreal prop4 READ prop4 WRITE setProp4 NOTIFY prop4Changed REVISION 1) + +public: + MyRevisionedSubclass() : m_p3(3), m_p4(4) {} + + qreal prop3() const { return m_p3; } + void setProp3(qreal p) { + if (p != m_p3) { + m_p3 = p; + emit prop3Changed(); + } + } + qreal prop4() const { return m_p4; } + void setProp4(qreal p) { + if (p != m_p4) { + m_p4 = p; + emit prop4Changed(); + } + } + + Q_INVOKABLE void method3() { } + Q_INVOKABLE Q_REVISION(1) void method4() { } + +signals: + void prop3Changed(); + void prop4Changed(); + + void signal3(); + Q_REVISION(1) void signal4(); + +protected: + qreal m_p3; + qreal m_p4; +}; + +QML_DECLARE_TYPE(MyRevisionedBaseClassRegistered) +QML_DECLARE_TYPE(MyRevisionedBaseClassUnregistered) +QML_DECLARE_TYPE(MyRevisionedClass) +QML_DECLARE_TYPE(MyRevisionedSubclass) + void registerTypes(); #endif // TESTTYPES_H diff --git a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp index 034adf7..f66cd0b 100644 --- a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp +++ b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp @@ -105,7 +105,7 @@ private slots: void constantsOverrideBindings(); void outerBindingOverridesInnerBinding(); void aliasPropertyAndBinding(); - void nonExistantAttachedObject(); + void nonExistentAttachedObject(); void scope(); void signalParameterTypes(); void objectsCompareAsEqual(); @@ -155,7 +155,10 @@ private slots: void qtcreatorbug_1289(); void noSpuriousWarningsAtShutdown(); void canAssignNullToQObject(); - void functionAssignment(); + void functionAssignment_fromBinding(); + void functionAssignment_fromJS(); + void functionAssignment_fromJS_data(); + void functionAssignmentfromJS_invalid(); void eval(); void function(); void qtbug_10696(); @@ -176,6 +179,9 @@ private slots: void callQtInvokables(); void invokableObjectArg(); void invokableObjectRet(); + + void revisionErrors(); + void revision(); private: QDeclarativeEngine engine; }; @@ -643,7 +649,7 @@ void tst_qdeclarativeecmascript::attachedProperties() void tst_qdeclarativeecmascript::enums() { - // Existant enums + // Existent enums { QDeclarativeComponent component(&engine, TEST_FILE("enums.1.qml")); QObject *object = component.create(); @@ -785,9 +791,9 @@ Access a non-existent attached object. Tests for a regression where this used to crash. */ -void tst_qdeclarativeecmascript::nonExistantAttachedObject() +void tst_qdeclarativeecmascript::nonExistentAttachedObject() { - QDeclarativeComponent component(&engine, TEST_FILE("nonExistantAttachedObject.qml")); + QDeclarativeComponent component(&engine, TEST_FILE("nonExistentAttachedObject.qml")); QString warning = component.url().toString() + ":4: Unable to assign [undefined] to QString stringProperty"; QTest::ignoreMessage(QtWarningMsg, qPrintable(warning)); @@ -2511,9 +2517,8 @@ void tst_qdeclarativeecmascript::canAssignNullToQObject() } } -void tst_qdeclarativeecmascript::functionAssignment() +void tst_qdeclarativeecmascript::functionAssignment_fromBinding() { - { QDeclarativeComponent component(&engine, TEST_FILE("functionAssignment.1.qml")); QString url = component.url().toString(); @@ -2526,26 +2531,64 @@ void tst_qdeclarativeecmascript::functionAssignment() QVERIFY(!o->property("a").isValid()); delete o; - } +} - { +void tst_qdeclarativeecmascript::functionAssignment_fromJS() +{ + QFETCH(QString, triggerProperty); + + QDeclarativeComponent component(&engine, TEST_FILE("functionAssignment.2.qml")); + QVERIFY2(component.errorString().isEmpty(), qPrintable(component.errorString())); + + MyQmlObject *o = qobject_cast<MyQmlObject *>(component.create()); + QVERIFY(o != 0); + QVERIFY(!o->property("a").isValid()); + + o->setProperty("aNumber", QVariant(5)); + o->setProperty(triggerProperty.toUtf8().constData(), true); + QCOMPARE(o->property("a"), QVariant(50)); + + o->setProperty("aNumber", QVariant(10)); + QCOMPARE(o->property("a"), QVariant(100)); + + delete o; +} + +void tst_qdeclarativeecmascript::functionAssignment_fromJS_data() +{ + QTest::addColumn<QString>("triggerProperty"); + + QTest::newRow("assign to property") << "assignToProperty"; + QTest::newRow("assign to property, from JS file") << "assignToPropertyFromJsFile"; + + QTest::newRow("assign to value type") << "assignToValueType"; + + QTest::newRow("use 'this'") << "assignWithThis"; + QTest::newRow("use 'this' from JS file") << "assignWithThisFromJsFile"; +} + +void tst_qdeclarativeecmascript::functionAssignmentfromJS_invalid() +{ QDeclarativeComponent component(&engine, TEST_FILE("functionAssignment.2.qml")); + QVERIFY2(component.errorString().isEmpty(), qPrintable(component.errorString())); MyQmlObject *o = qobject_cast<MyQmlObject *>(component.create()); QVERIFY(o != 0); + QVERIFY(!o->property("a").isValid()); + o->setProperty("assignFuncWithoutReturn", true); QVERIFY(!o->property("a").isValid()); - + QString url = component.url().toString(); - QString warning = url + ":10: Error: Cannot assign a function to a property."; + QString warning = url + ":63: Unable to assign QString to int"; QTest::ignoreMessage(QtWarningMsg, warning.toLatin1().constData()); - - o->setProperty("runTest", true); - - QVERIFY(!o->property("a").isValid()); + o->setProperty("assignWrongType", true); + + warning = url + ":70: Unable to assign QString to int"; + QTest::ignoreMessage(QtWarningMsg, warning.toLatin1().constData()); + o->setProperty("assignWrongTypeToValueType", true); delete o; - } } void tst_qdeclarativeecmascript::eval() @@ -2863,6 +2906,94 @@ void tst_qdeclarativeecmascript::aliasWritesOverrideBindings() } } +void tst_qdeclarativeecmascript::revisionErrors() +{ + { + QDeclarativeComponent component(&engine, TEST_FILE("metaobjectRevisionErrors.qml")); + QString url = component.url().toString(); + + QString warning1 = url + ":8: ReferenceError: Can't find variable: prop2"; + QString warning2 = url + ":11: ReferenceError: Can't find variable: prop2"; + QString warning3 = url + ":13: ReferenceError: Can't find variable: method2"; + + QTest::ignoreMessage(QtWarningMsg, warning1.toLatin1().constData()); + QTest::ignoreMessage(QtWarningMsg, warning2.toLatin1().constData()); + QTest::ignoreMessage(QtWarningMsg, warning3.toLatin1().constData()); + MyRevisionedClass *object = qobject_cast<MyRevisionedClass *>(component.create()); + QVERIFY(object != 0); + } + { + QDeclarativeComponent component(&engine, TEST_FILE("metaobjectRevisionErrors2.qml")); + QString url = component.url().toString(); + + // MyRevisionedSubclass 1.0 uses MyRevisionedClass revision 0 + // method2, prop2 from MyRevisionedClass not available + // method4, prop4 from MyRevisionedSubclass not available + QString warning1 = url + ":8: ReferenceError: Can't find variable: prop2"; + QString warning2 = url + ":14: ReferenceError: Can't find variable: prop2"; + QString warning3 = url + ":10: ReferenceError: Can't find variable: prop4"; + QString warning4 = url + ":16: ReferenceError: Can't find variable: prop4"; + QString warning5 = url + ":20: ReferenceError: Can't find variable: method2"; + + QTest::ignoreMessage(QtWarningMsg, warning1.toLatin1().constData()); + QTest::ignoreMessage(QtWarningMsg, warning2.toLatin1().constData()); + QTest::ignoreMessage(QtWarningMsg, warning3.toLatin1().constData()); + QTest::ignoreMessage(QtWarningMsg, warning4.toLatin1().constData()); + QTest::ignoreMessage(QtWarningMsg, warning5.toLatin1().constData()); + MyRevisionedClass *object = qobject_cast<MyRevisionedClass *>(component.create()); + QVERIFY(object != 0); + } + { + QDeclarativeComponent component(&engine, TEST_FILE("metaobjectRevisionErrors3.qml")); + QString url = component.url().toString(); + + // MyRevisionedSubclass 1.1 uses MyRevisionedClass revision 1 + // All properties/methods available, except MyRevisionedBaseClassUnregistered rev 1 + QString warning1 = url + ":30: ReferenceError: Can't find variable: methodD"; + QString warning2 = url + ":10: ReferenceError: Can't find variable: propD"; + QString warning3 = url + ":20: ReferenceError: Can't find variable: propD"; + QTest::ignoreMessage(QtWarningMsg, warning1.toLatin1().constData()); + QTest::ignoreMessage(QtWarningMsg, warning2.toLatin1().constData()); + QTest::ignoreMessage(QtWarningMsg, warning3.toLatin1().constData()); + MyRevisionedClass *object = qobject_cast<MyRevisionedClass *>(component.create()); + QVERIFY(object != 0); + } +} + +void tst_qdeclarativeecmascript::revision() +{ + { + QDeclarativeComponent component(&engine, TEST_FILE("metaobjectRevision.qml")); + QString url = component.url().toString(); + + MyRevisionedClass *object = qobject_cast<MyRevisionedClass *>(component.create()); + QVERIFY(object != 0); + } + { + QDeclarativeComponent component(&engine, TEST_FILE("metaobjectRevision2.qml")); + QString url = component.url().toString(); + + MyRevisionedClass *object = qobject_cast<MyRevisionedClass *>(component.create()); + QVERIFY(object != 0); + } + { + QDeclarativeComponent component(&engine, TEST_FILE("metaobjectRevision3.qml")); + QString url = component.url().toString(); + + MyRevisionedClass *object = qobject_cast<MyRevisionedClass *>(component.create()); + QVERIFY(object != 0); + } + // Test that non-root classes can resolve revisioned methods + { + QDeclarativeComponent component(&engine, TEST_FILE("metaobjectRevision4.qml")); + + QObject *object = component.create(); + QVERIFY(object != 0); + QCOMPARE(object->property("test").toReal(), 11.); + delete object; + } +} + QTEST_MAIN(tst_qdeclarativeecmascript) #include "tst_qdeclarativeecmascript.moc" diff --git a/tests/auto/declarative/qdeclarativeflickable/data/resize.qml b/tests/auto/declarative/qdeclarativeflickable/data/resize.qml new file mode 100644 index 0000000..e2abb99 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeflickable/data/resize.qml @@ -0,0 +1,27 @@ +import QtQuick 1.1 + +Rectangle { + function resizeContent() { + flick.resizeContent(600, 600, Qt.point(100, 100)) + } + function returnToBounds() { + flick.returnToBounds() + } + width: 400 + height: 360 + color: "gray" + + Flickable { + id: flick + objectName: "flick" + anchors.fill: parent + contentWidth: 300 + contentHeight: 300 + + Rectangle { + width: flick.contentWidth + height: flick.contentHeight + color: "red" + } + } +} diff --git a/tests/auto/declarative/qdeclarativeflickable/data/wheel.qml b/tests/auto/declarative/qdeclarativeflickable/data/wheel.qml new file mode 100644 index 0000000..6ea81b2 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeflickable/data/wheel.qml @@ -0,0 +1,21 @@ +import QtQuick 1.1 + +Rectangle { + width: 400 + height: 400 + color: "gray" + + Flickable { + id: flick + objectName: "flick" + anchors.fill: parent + contentWidth: 800 + contentHeight: 800 + + Rectangle { + width: flick.contentWidth + height: flick.contentHeight + color: "red" + } + } +} diff --git a/tests/auto/declarative/qdeclarativeflickable/tst_qdeclarativeflickable.cpp b/tests/auto/declarative/qdeclarativeflickable/tst_qdeclarativeflickable.cpp index 1bf93ee..f4bec8f 100644 --- a/tests/auto/declarative/qdeclarativeflickable/tst_qdeclarativeflickable.cpp +++ b/tests/auto/declarative/qdeclarativeflickable/tst_qdeclarativeflickable.cpp @@ -42,10 +42,12 @@ #include <QtTest/QSignalSpy> #include <QtDeclarative/qdeclarativeengine.h> #include <QtDeclarative/qdeclarativecomponent.h> +#include <QtDeclarative/qdeclarativeview.h> #include <private/qdeclarativeflickable_p.h> #include <private/qdeclarativevaluetype_p.h> #include <QtGui/qgraphicswidget.h> #include <math.h> +#include "../../../shared/util.h" #ifdef Q_OS_SYMBIAN // In Symbian OS test data is located in applications private dir @@ -69,6 +71,11 @@ private slots: void pressDelay(); void flickableDirection(); void qgraphicswidget(); + void resizeContent(); + void returnToBounds(); + void testQtQuick11Attributes(); + void testQtQuick11Attributes_data(); + void wheel(); private: QDeclarativeEngine engine; @@ -277,6 +284,135 @@ void tst_qdeclarativeflickable::qgraphicswidget() QVERIFY(widget); } +// QtQuick 1.1 +void tst_qdeclarativeflickable::resizeContent() +{ + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/resize.qml")); + QDeclarativeItem *root = qobject_cast<QDeclarativeItem*>(c.create()); + QDeclarativeFlickable *obj = findItem<QDeclarativeFlickable>(root, "flick"); + + QVERIFY(obj != 0); + QCOMPARE(obj->contentX(), 0.); + QCOMPARE(obj->contentY(), 0.); + QCOMPARE(obj->contentWidth(), 300.); + QCOMPARE(obj->contentHeight(), 300.); + + QMetaObject::invokeMethod(root, "resizeContent"); + + QCOMPARE(obj->contentX(), 100.); + QCOMPARE(obj->contentY(), 100.); + QCOMPARE(obj->contentWidth(), 600.); + QCOMPARE(obj->contentHeight(), 600.); + + delete root; +} + +// QtQuick 1.1 +void tst_qdeclarativeflickable::returnToBounds() +{ + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/resize.qml")); + QDeclarativeItem *root = qobject_cast<QDeclarativeItem*>(c.create()); + QDeclarativeFlickable *obj = findItem<QDeclarativeFlickable>(root, "flick"); + + QVERIFY(obj != 0); + QCOMPARE(obj->contentX(), 0.); + QCOMPARE(obj->contentY(), 0.); + QCOMPARE(obj->contentWidth(), 300.); + QCOMPARE(obj->contentHeight(), 300.); + + obj->setContentX(100); + obj->setContentY(400); + QTRY_COMPARE(obj->contentX(), 100.); + QTRY_COMPARE(obj->contentY(), 400.); + + QMetaObject::invokeMethod(root, "returnToBounds"); + + QTRY_COMPARE(obj->contentX(), 0.); + QTRY_COMPARE(obj->contentY(), 0.); + + delete root; +} + +void tst_qdeclarativeflickable::testQtQuick11Attributes() +{ + QFETCH(QString, code); + QFETCH(QString, warning); + QFETCH(QString, error); + + QDeclarativeEngine engine; + QObject *obj; + + QDeclarativeComponent invalid(&engine); + invalid.setData("import QtQuick 1.0; Flickable { " + code.toUtf8() + " }", QUrl("")); + QTest::ignoreMessage(QtWarningMsg, warning.toUtf8()); + obj = invalid.create(); + QCOMPARE(invalid.errorString(), error); + delete obj; + + QDeclarativeComponent valid(&engine); + valid.setData("import QtQuick 1.1; Flickable { " + code.toUtf8() + " }", QUrl("")); + obj = valid.create(); + QVERIFY(obj); + QVERIFY(valid.errorString().isEmpty()); + delete obj; +} + +void tst_qdeclarativeflickable::testQtQuick11Attributes_data() +{ + QTest::addColumn<QString>("code"); + QTest::addColumn<QString>("warning"); + QTest::addColumn<QString>("error"); + + QTest::newRow("resizeContent") << "Component.onCompleted: resizeContent(100,100,Qt.point(50,50))" + << "<Unknown File>:1: ReferenceError: Can't find variable: resizeContent" + << ""; + + QTest::newRow("returnToBounds") << "Component.onCompleted: returnToBounds()" + << "<Unknown File>:1: ReferenceError: Can't find variable: returnToBounds" + << ""; + +} + +void tst_qdeclarativeflickable::wheel() +{ + QDeclarativeView *canvas = new QDeclarativeView; + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/wheel.qml")); + canvas->show(); + canvas->setFocus(); + QVERIFY(canvas->rootObject() != 0); + + QDeclarativeFlickable *flick = canvas->rootObject()->findChild<QDeclarativeFlickable*>("flick"); + QVERIFY(flick != 0); + + QGraphicsScene *scene = canvas->scene(); + QGraphicsSceneWheelEvent event(QEvent::GraphicsSceneWheel); + event.setScenePos(QPointF(200, 200)); + event.setDelta(-120); + event.setOrientation(Qt::Vertical); + event.setAccepted(false); + QApplication::sendEvent(scene, &event); + + QTRY_VERIFY(flick->contentY() > 0); + QVERIFY(flick->contentX() == 0); + + flick->setContentY(0); + QVERIFY(flick->contentY() == 0); + + event.setScenePos(QPointF(200, 200)); + event.setDelta(-120); + event.setOrientation(Qt::Horizontal); + event.setAccepted(false); + QApplication::sendEvent(scene, &event); + + QTRY_VERIFY(flick->contentX() > 0); + QVERIFY(flick->contentY() == 0); + + delete canvas; +} + + template<typename T> T *tst_qdeclarativeflickable::findItem(QGraphicsObject *parent, const QString &objectName) { diff --git a/tests/auto/declarative/qdeclarativegridview/data/footer.qml b/tests/auto/declarative/qdeclarativegridview/data/footer.qml index ad69a25..b41e2ac 100644 --- a/tests/auto/declarative/qdeclarativegridview/data/footer.qml +++ b/tests/auto/declarative/qdeclarativegridview/data/footer.qml @@ -1,6 +1,9 @@ import QtQuick 1.0 Rectangle { + function changeFooter() { + grid.footer = footer2 + } width: 240 height: 320 color: "#ffffff" @@ -29,4 +32,9 @@ Rectangle { delegate: myDelegate footer: Text { objectName: "footer"; text: "Footer"; height: 30 } } + + Component { + id: footer2 + Text { objectName: "footer2"; text: "Footer 2"; height: 20 } + } } diff --git a/tests/auto/declarative/qdeclarativegridview/data/gridview1.qml b/tests/auto/declarative/qdeclarativegridview/data/gridview1.qml index 77c94ba..e4e699c 100644 --- a/tests/auto/declarative/qdeclarativegridview/data/gridview1.qml +++ b/tests/auto/declarative/qdeclarativegridview/data/gridview1.qml @@ -2,6 +2,8 @@ import QtQuick 1.0 Rectangle { id: root + property bool showHeader: false + property bool showFooter: false property int added: -1 property variant removed @@ -40,6 +42,10 @@ Rectangle { GridView.onAdd: root.added = index GridView.onRemove: root.removed = name } + }, + Component { + id: headerFooter + Rectangle { width: 30; height: 320; color: "blue" } } ] GridView { @@ -52,5 +58,7 @@ Rectangle { flow: (testTopToBottom == false) ? "LeftToRight" : "TopToBottom" model: testModel delegate: myDelegate + header: root.showHeader ? headerFooter : null + footer: root.showFooter ? headerFooter : null } } diff --git a/tests/auto/declarative/qdeclarativegridview/data/header.qml b/tests/auto/declarative/qdeclarativegridview/data/header.qml index 99baacd..f39da55 100644 --- a/tests/auto/declarative/qdeclarativegridview/data/header.qml +++ b/tests/auto/declarative/qdeclarativegridview/data/header.qml @@ -1,6 +1,9 @@ import QtQuick 1.0 Rectangle { + function changeHeader() { + grid.header = header2 + } width: 240 height: 320 color: "#ffffff" @@ -29,4 +32,9 @@ Rectangle { delegate: myDelegate header: Text { objectName: "header"; text: "Header"; height: 30 } } + + Component { + id: header2 + Text { objectName: "header2"; text: "Header 2"; height: 20 } + } } diff --git a/tests/auto/declarative/qdeclarativegridview/tst_qdeclarativegridview.cpp b/tests/auto/declarative/qdeclarativegridview/tst_qdeclarativegridview.cpp index 0fac0fc..82a1a4a 100644 --- a/tests/auto/declarative/qdeclarativegridview/tst_qdeclarativegridview.cpp +++ b/tests/auto/declarative/qdeclarativegridview/tst_qdeclarativegridview.cpp @@ -78,6 +78,7 @@ private slots: void componentChanges(); void modelChanges(); void positionViewAtIndex(); + void snapping(); void resetModel(); void enforceRange(); void QTBUG_8456(); @@ -85,6 +86,8 @@ private slots: void footer(); void header(); void indexAt(); + void testQtQuick11Attributes(); + void testQtQuick11Attributes_data(); private: QDeclarativeView *createView(); @@ -994,6 +997,7 @@ void tst_QDeclarativeGridView::positionViewAtIndex() // Position on a currently visible item gridview->positionViewAtIndex(4, QDeclarativeGridView::Beginning); + QTRY_COMPARE(gridview->indexAt(120, 90), 4); QTRY_COMPARE(gridview->contentY(), 60.); // Confirm items positioned correctly @@ -1008,6 +1012,7 @@ void tst_QDeclarativeGridView::positionViewAtIndex() // Position on an item beyond the visible items gridview->positionViewAtIndex(21, QDeclarativeGridView::Beginning); + QTRY_COMPARE(gridview->indexAt(40, 450), 21); QTRY_COMPARE(gridview->contentY(), 420.); // Confirm items positioned correctly @@ -1022,6 +1027,7 @@ void tst_QDeclarativeGridView::positionViewAtIndex() // Position on an item that would leave empty space if positioned at the top gridview->positionViewAtIndex(31, QDeclarativeGridView::Beginning); + QTRY_COMPARE(gridview->indexAt(120, 630), 31); QTRY_COMPARE(gridview->contentY(), 520.); // Confirm items positioned correctly @@ -1036,6 +1042,9 @@ void tst_QDeclarativeGridView::positionViewAtIndex() // Position at the beginning again gridview->positionViewAtIndex(0, QDeclarativeGridView::Beginning); + QTRY_COMPARE(gridview->indexAt(0, 0), 0); + QTRY_COMPARE(gridview->indexAt(40, 30), 0); + QTRY_COMPARE(gridview->indexAt(80, 60), 4); QTRY_COMPARE(gridview->contentY(), 0.); // Confirm items positioned correctly @@ -1089,6 +1098,100 @@ void tst_QDeclarativeGridView::positionViewAtIndex() gridview->positionViewAtIndex(20, QDeclarativeGridView::Contain); QTRY_COMPARE(gridview->contentY(), 100.); + // Test for Top To Bottom layout + ctxt->setContextProperty("testTopToBottom", QVariant(true)); + + // Confirm items positioned correctly + itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count(); + for (int i = 0; i < model.count() && i < itemCount-1; ++i) { + QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i); + if (!item) qWarning() << "Item" << i << "not found"; + QTRY_VERIFY(item); + QTRY_COMPARE(item->x(), (i/5)*80.); + QTRY_COMPARE(item->y(), (i%5)*60.); + } + + // Position at End + gridview->positionViewAtIndex(30, QDeclarativeGridView::End); + QTRY_COMPARE(gridview->contentX(), 320.); + QTRY_COMPARE(gridview->contentY(), 0.); + + // Position in Center + gridview->positionViewAtIndex(15, QDeclarativeGridView::Center); + QTRY_COMPARE(gridview->contentX(), 160.); + + // Ensure at least partially visible + gridview->positionViewAtIndex(15, QDeclarativeGridView::Visible); + QTRY_COMPARE(gridview->contentX(), 160.); + + gridview->setContentX(170); + gridview->positionViewAtIndex(25, QDeclarativeGridView::Visible); + QTRY_COMPARE(gridview->contentX(), 170.); + + gridview->positionViewAtIndex(30, QDeclarativeGridView::Visible); + QTRY_COMPARE(gridview->contentX(), 320.); + + gridview->setContentX(170); + gridview->positionViewAtIndex(25, QDeclarativeGridView::Contain); + QTRY_COMPARE(gridview->contentX(), 240.); + + // positionViewAtBeginning + gridview->positionViewAtBeginning(); + QTRY_COMPARE(gridview->contentX(), 0.); + + gridview->setContentX(80); + canvas->rootObject()->setProperty("showHeader", true); + gridview->positionViewAtBeginning(); + QTRY_COMPARE(gridview->contentX(), -30.); + + // positionViewAtEnd + gridview->positionViewAtEnd(); + QTRY_COMPARE(gridview->contentX(), 430.); + + gridview->setContentX(80); + canvas->rootObject()->setProperty("showFooter", true); + gridview->positionViewAtEnd(); + QTRY_COMPARE(gridview->contentX(), 460.); + + delete canvas; +} + +void tst_QDeclarativeGridView::snapping() +{ + QDeclarativeView *canvas = createView(); + + TestModel model; + for (int i = 0; i < 40; i++) + model.addItem("Item" + QString::number(i), ""); + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + ctxt->setContextProperty("testTopToBottom", QVariant(false)); + + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml")); + qApp->processEvents(); + + QDeclarativeGridView *gridview = findItem<QDeclarativeGridView>(canvas->rootObject(), "grid"); + QTRY_VERIFY(gridview != 0); + + gridview->setHeight(220); + QCOMPARE(gridview->height(), 220.); + + gridview->positionViewAtIndex(12, QDeclarativeGridView::Visible); + QCOMPARE(gridview->contentY(), 80.); + + gridview->setContentY(0); + QCOMPARE(gridview->contentY(), 0.); + + gridview->setSnapMode(QDeclarativeGridView::SnapToRow); + QCOMPARE(gridview->snapMode(), QDeclarativeGridView::SnapToRow); + + gridview->positionViewAtIndex(12, QDeclarativeGridView::Visible); + QCOMPARE(gridview->contentY(), 60.); + + gridview->positionViewAtIndex(15, QDeclarativeGridView::End); + QCOMPARE(gridview->contentY(), 120.); + delete canvas; } @@ -1232,6 +1335,15 @@ void tst_QDeclarativeGridView::manualHighlight() QTRY_COMPARE(gridview->currentItem(), findItem<QDeclarativeItem>(contentItem, "wrapper", 2)); QTRY_COMPARE(gridview->highlightItem()->y() - 5, gridview->currentItem()->y()); QTRY_COMPARE(gridview->highlightItem()->x() - 5, gridview->currentItem()->x()); + + gridview->setFlow(QDeclarativeGridView::TopToBottom); + QTRY_COMPARE(gridview->flow(), QDeclarativeGridView::TopToBottom); + + gridview->setCurrentIndex(0); + QTRY_COMPARE(gridview->currentIndex(), 0); + QTRY_COMPARE(gridview->currentItem(), findItem<QDeclarativeItem>(contentItem, "wrapper", 0)); + QTRY_COMPARE(gridview->highlightItem()->y() - 5, gridview->currentItem()->y()); + QTRY_COMPARE(gridview->highlightItem()->x() - 5, gridview->currentItem()->x()); } void tst_QDeclarativeGridView::footer() @@ -1258,12 +1370,27 @@ void tst_QDeclarativeGridView::footer() QVERIFY(footer); QCOMPARE(footer->y(), 180.0); + QCOMPARE(footer->height(), 30.0); model.removeItem(2); QTRY_COMPARE(footer->y(), 120.0); model.clear(); QTRY_COMPARE(footer->y(), 0.0); + + for (int i = 0; i < 30; i++) + model.addItem("Item" + QString::number(i), ""); + + QMetaObject::invokeMethod(canvas->rootObject(), "changeFooter"); + + footer = findItem<QDeclarativeText>(contentItem, "footer"); + QVERIFY(!footer); + footer = findItem<QDeclarativeText>(contentItem, "footer2"); + QVERIFY(footer); + + QCOMPARE(footer->y(), 0.0); + QCOMPARE(footer->height(), 20.0); + QCOMPARE(gridview->contentY(), 0.0); } void tst_QDeclarativeGridView::header() @@ -1290,6 +1417,7 @@ void tst_QDeclarativeGridView::header() QVERIFY(header); QCOMPARE(header->y(), 0.0); + QCOMPARE(header->height(), 30.0); QCOMPARE(gridview->contentY(), 0.0); QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", 0); @@ -1298,6 +1426,20 @@ void tst_QDeclarativeGridView::header() model.clear(); QTRY_COMPARE(header->y(), 0.0); + + for (int i = 0; i < 30; i++) + model.addItem("Item" + QString::number(i), ""); + + QMetaObject::invokeMethod(canvas->rootObject(), "changeHeader"); + + header = findItem<QDeclarativeText>(contentItem, "header"); + QVERIFY(!header); + header = findItem<QDeclarativeText>(contentItem, "header2"); + QVERIFY(header); + + QCOMPARE(header->y(), 0.0); + QCOMPARE(header->height(), 20.0); + QCOMPARE(gridview->contentY(), 0.0); } void tst_QDeclarativeGridView::indexAt() @@ -1337,6 +1479,45 @@ void tst_QDeclarativeGridView::indexAt() delete canvas; } +void tst_QDeclarativeGridView::testQtQuick11Attributes() +{ + QFETCH(QString, code); + QFETCH(QString, warning); + QFETCH(QString, error); + + QDeclarativeEngine engine; + QObject *obj; + + QDeclarativeComponent valid(&engine); + valid.setData("import QtQuick 1.1; GridView { " + code.toUtf8() + " }", QUrl("")); + obj = valid.create(); + QVERIFY(obj); + QVERIFY(valid.errorString().isEmpty()); + delete obj; + + QDeclarativeComponent invalid(&engine); + invalid.setData("import QtQuick 1.0; GridView { " + code.toUtf8() + " }", QUrl("")); + QTest::ignoreMessage(QtWarningMsg, warning.toUtf8()); + obj = invalid.create(); + QCOMPARE(invalid.errorString(), error); + delete obj; +} + +void tst_QDeclarativeGridView::testQtQuick11Attributes_data() +{ + QTest::addColumn<QString>("code"); + QTest::addColumn<QString>("warning"); + QTest::addColumn<QString>("error"); + + QTest::newRow("positionViewAtBeginning") << "Component.onCompleted: positionViewAtBeginning()" + << "<Unknown File>:1: ReferenceError: Can't find variable: positionViewAtBeginning" + << ""; + + QTest::newRow("positionViewAtEnd") << "Component.onCompleted: positionViewAtEnd()" + << "<Unknown File>:1: ReferenceError: Can't find variable: positionViewAtEnd" + << ""; +} + QDeclarativeView *tst_QDeclarativeGridView::createView() { QDeclarativeView *canvas = new QDeclarativeView(0); diff --git a/tests/auto/declarative/qdeclarativeimage/tst_qdeclarativeimage.cpp b/tests/auto/declarative/qdeclarativeimage/tst_qdeclarativeimage.cpp index ddecf7e..f1fe2bd 100644 --- a/tests/auto/declarative/qdeclarativeimage/tst_qdeclarativeimage.cpp +++ b/tests/auto/declarative/qdeclarativeimage/tst_qdeclarativeimage.cpp @@ -79,6 +79,8 @@ private slots: void resized(); void preserveAspectRatio(); void smooth(); + void mirror(); + void mirror_data(); void svg(); void geometry(); void geometry_data(); @@ -88,6 +90,8 @@ private slots: void paintedWidthHeight(); void sourceSize_QTBUG_14303(); void nullPixmapPaint(); + void testQtQuick11Attributes(); + void testQtQuick11Attributes_data(); private: template<typename T> @@ -124,19 +128,21 @@ void tst_qdeclarativeimage::imageSource_data() QTest::addColumn<double>("height"); QTest::addColumn<bool>("remote"); QTest::addColumn<bool>("async"); + QTest::addColumn<bool>("cache"); QTest::addColumn<QString>("error"); - QTest::newRow("local") << QUrl::fromLocalFile(SRCDIR "/data/colors.png").toString() << 120.0 << 120.0 << false << false << ""; - QTest::newRow("local async") << QUrl::fromLocalFile(SRCDIR "/data/colors1.png").toString() << 120.0 << 120.0 << false << true << ""; + QTest::newRow("local") << QUrl::fromLocalFile(SRCDIR "/data/colors.png").toString() << 120.0 << 120.0 << false << false << true << ""; + QTest::newRow("local no cache") << QUrl::fromLocalFile(SRCDIR "/data/colors.png").toString() << 120.0 << 120.0 << false << false << false << ""; + QTest::newRow("local async") << QUrl::fromLocalFile(SRCDIR "/data/colors1.png").toString() << 120.0 << 120.0 << false << true << true << ""; QTest::newRow("local not found") << QUrl::fromLocalFile(SRCDIR "/data/no-such-file.png").toString() << 0.0 << 0.0 << false - << false << "file::2:1: QML Image: Cannot open: " + QUrl::fromLocalFile(SRCDIR "/data/no-such-file.png").toString(); + << false << true << "file::2:1: QML Image: Cannot open: " + QUrl::fromLocalFile(SRCDIR "/data/no-such-file.png").toString(); QTest::newRow("local async not found") << QUrl::fromLocalFile(SRCDIR "/data/no-such-file-1.png").toString() << 0.0 << 0.0 << false - << true << "file::2:1: QML Image: Cannot open: " + QUrl::fromLocalFile(SRCDIR "/data/no-such-file-1.png").toString(); - QTest::newRow("remote") << SERVER_ADDR "/colors.png" << 120.0 << 120.0 << true << false << ""; - QTest::newRow("remote redirected") << SERVER_ADDR "/oldcolors.png" << 120.0 << 120.0 << true << false << ""; - QTest::newRow("remote svg") << SERVER_ADDR "/heart.svg" << 550.0 << 500.0 << true << false << ""; + << true << true << "file::2:1: QML Image: Cannot open: " + QUrl::fromLocalFile(SRCDIR "/data/no-such-file-1.png").toString(); + QTest::newRow("remote") << SERVER_ADDR "/colors.png" << 120.0 << 120.0 << true << false << true << ""; + QTest::newRow("remote redirected") << SERVER_ADDR "/oldcolors.png" << 120.0 << 120.0 << true << false << false << ""; + QTest::newRow("remote svg") << SERVER_ADDR "/heart.svg" << 550.0 << 500.0 << true << false << false << ""; QTest::newRow("remote not found") << SERVER_ADDR "/no-such-file.png" << 0.0 << 0.0 << true - << false << "file::2:1: QML Image: Error downloading " SERVER_ADDR "/no-such-file.png - server replied: Not found"; + << false << true << "file::2:1: QML Image: Error downloading " SERVER_ADDR "/no-such-file.png - server replied: Not found"; } @@ -147,6 +153,7 @@ void tst_qdeclarativeimage::imageSource() QFETCH(double, height); QFETCH(bool, remote); QFETCH(bool, async); + QFETCH(bool, cache); QFETCH(QString, error); TestHTTPServer server(SERVER_PORT); @@ -159,8 +166,9 @@ void tst_qdeclarativeimage::imageSource() if (!error.isEmpty()) QTest::ignoreMessage(QtWarningMsg, error.toUtf8()); - QString componentStr = "import QtQuick 1.0\nImage { source: \"" + source + "\"; asynchronous: " - + (async ? QLatin1String("true") : QLatin1String("false")) + " }"; + QString componentStr = "import QtQuick 1.1\nImage { source: \"" + source + "\"; asynchronous: " + + (async ? QLatin1String("true") : QLatin1String("false")) + "; cache: " + + (cache ? QLatin1String("true") : QLatin1String("false")) + " }"; QDeclarativeComponent component(&engine); component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); QDeclarativeImage *obj = qobject_cast<QDeclarativeImage*>(component.create()); @@ -168,6 +176,13 @@ void tst_qdeclarativeimage::imageSource() if (async) QVERIFY(obj->asynchronous() == true); + else + QVERIFY(obj->asynchronous() == false); + + if (cache) + QVERIFY(obj->cache() == true); + else + QVERIFY(obj->cache() == false); if (remote || async) QTRY_VERIFY(obj->status() == QDeclarativeImage::Loading); @@ -259,6 +274,90 @@ void tst_qdeclarativeimage::smooth() delete obj; } +void tst_qdeclarativeimage::mirror() +{ + QFETCH(int, fillMode); + + qreal width = 300; + qreal height = 250; + + QString src = QUrl::fromLocalFile(SRCDIR "/data/heart200.png").toString(); + QString componentStr = "import QtQuick 1.1\nImage { source: \"" + src + "\"; }"; + + QDeclarativeComponent component(&engine); + component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QDeclarativeImage *obj = qobject_cast<QDeclarativeImage*>(component.create()); + QVERIFY(obj != 0); + + obj->setProperty("width", width); + obj->setProperty("height", height); + obj->setFillMode((QDeclarativeImage::FillMode)fillMode); + obj->setProperty("mirror", true); + + QGraphicsScene scene; + scene.addItem(qobject_cast<QGraphicsObject *>(obj)); + QPixmap screenshot(width, height); + screenshot.fill(); + QPainter p_screenshot(&screenshot); + scene.render(&p_screenshot, QRect(0, 0, width, height), QRect(0, 0, width, height)); + + QPixmap srcPixmap; + QVERIFY(srcPixmap.load(SRCDIR "/data/heart200.png")); + + QPixmap expected(width, height); + expected.fill(); + QPainter p_e(&expected); + QTransform transform; + transform.translate(width, 0).scale(-1, 1.0); + p_e.setTransform(transform); + + switch (fillMode) { + case QDeclarativeImage::Stretch: + p_e.drawPixmap(QRect(0, 0, width, height), srcPixmap, QRect(0, 0, srcPixmap.width(), srcPixmap.height())); + break; + case QDeclarativeImage::PreserveAspectFit: + p_e.drawPixmap(QRect(25, 0, width / (width/height), height), srcPixmap, QRect(0, 0, srcPixmap.width(), srcPixmap.height())); + break; + case QDeclarativeImage::PreserveAspectCrop: + { + qreal ratio = width/srcPixmap.width(); // width is the longer side + QRect rect(0, 0, srcPixmap.width()*ratio, srcPixmap.height()*ratio); + rect.moveCenter(QRect(0, 0, width, height).center()); + p_e.drawPixmap(rect, srcPixmap, QRect(0, 0, srcPixmap.width(), srcPixmap.height())); + break; + } + case QDeclarativeImage::Tile: + p_e.drawTiledPixmap(QRect(0, 0, width, height), srcPixmap); + break; + case QDeclarativeImage::TileVertically: + transform.scale(width / srcPixmap.width(), 1.0); + p_e.setTransform(transform); + p_e.drawTiledPixmap(QRect(0, 0, width, height), srcPixmap); + break; + case QDeclarativeImage::TileHorizontally: + transform.scale(1.0, height / srcPixmap.height()); + p_e.setTransform(transform); + p_e.drawTiledPixmap(QRect(0, 0, width, height), srcPixmap); + break; + } + + QCOMPARE(screenshot, expected); + + delete obj; +} + +void tst_qdeclarativeimage::mirror_data() +{ + QTest::addColumn<int>("fillMode"); + + QTest::newRow("Stretch") << int(QDeclarativeImage::Stretch); + QTest::newRow("PreserveAspectFit") << int(QDeclarativeImage::PreserveAspectFit); + QTest::newRow("PreserveAspectCrop") << int(QDeclarativeImage::PreserveAspectCrop); + QTest::newRow("Tile") << int(QDeclarativeImage::Tile); + QTest::newRow("TileVertically") << int(QDeclarativeImage::TileVertically); + QTest::newRow("TileHorizontally") << int(QDeclarativeImage::TileHorizontally); +} + void tst_qdeclarativeimage::svg() { QString src = QUrl::fromLocalFile(SRCDIR "/data/heart.svg").toString(); @@ -570,6 +669,45 @@ void tst_qdeclarativeimage::nullPixmapPaint() delete image; } +void tst_qdeclarativeimage::testQtQuick11Attributes() +{ + QFETCH(QString, code); + QFETCH(QString, warning); + QFETCH(QString, error); + + QDeclarativeEngine engine; + QObject *obj; + + QDeclarativeComponent valid(&engine); + valid.setData("import QtQuick 1.1; Image { " + code.toUtf8() + " }", QUrl("")); + obj = valid.create(); + QVERIFY(obj); + QVERIFY(valid.errorString().isEmpty()); + delete obj; + + QDeclarativeComponent invalid(&engine); + invalid.setData("import QtQuick 1.0; Image { " + code.toUtf8() + " }", QUrl("")); + QTest::ignoreMessage(QtWarningMsg, warning.toUtf8()); + obj = invalid.create(); + QCOMPARE(invalid.errorString(), error); + delete obj; +} + +void tst_qdeclarativeimage::testQtQuick11Attributes_data() +{ + QTest::addColumn<QString>("code"); + QTest::addColumn<QString>("warning"); + QTest::addColumn<QString>("error"); + + QTest::newRow("mirror") << "mirror: true" + << "QDeclarativeComponent: Component is not ready" + << ":1 \"Image.mirror\" is not available in QtQuick 1.0.\n"; + + QTest::newRow("cache") << "cache: true" + << "QDeclarativeComponent: Component is not ready" + << ":1 \"Image.cache\" is not available in QtQuick 1.0.\n"; +} + /* Find an item with the specified objectName. If index is supplied then the item must also evaluate the {index} expression equal to index diff --git a/tests/auto/declarative/qdeclarativeinstruction/tst_qdeclarativeinstruction.cpp b/tests/auto/declarative/qdeclarativeinstruction/tst_qdeclarativeinstruction.cpp index 9ac6137..b5edec8 100644 --- a/tests/auto/declarative/qdeclarativeinstruction/tst_qdeclarativeinstruction.cpp +++ b/tests/auto/declarative/qdeclarativeinstruction/tst_qdeclarativeinstruction.cpp @@ -512,7 +512,7 @@ void tst_qdeclarativeinstruction::dump() { QDeclarativeInstruction i; i.line = 50; - i.type = (QDeclarativeInstruction::Type)(1234); // Non-existant + i.type = (QDeclarativeInstruction::Type)(1234); // Non-existent data->bytecode << i; } diff --git a/tests/auto/declarative/qdeclarativeitem/data/implicitsize.qml b/tests/auto/declarative/qdeclarativeitem/data/implicitsize.qml new file mode 100644 index 0000000..869c0fc --- /dev/null +++ b/tests/auto/declarative/qdeclarativeitem/data/implicitsize.qml @@ -0,0 +1,19 @@ +import QtQuick 1.1 + +Item { + implicitWidth: 200 + implicitHeight: 100 + + width: 80 + height: 60 + + function resetSize() { + width = undefined + height = undefined + } + + function changeImplicit() { + implicitWidth = 150 + implicitHeight = 80 + } +} diff --git a/tests/auto/declarative/qdeclarativeitem/data/qtbug_16871.qml b/tests/auto/declarative/qdeclarativeitem/data/qtbug_16871.qml new file mode 100644 index 0000000..8102df1 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeitem/data/qtbug_16871.qml @@ -0,0 +1,5 @@ +import QtQuick 1.0 + +Item { + children: [ 10 ] +} diff --git a/tests/auto/declarative/qdeclarativeitem/tst_qdeclarativeitem.cpp b/tests/auto/declarative/qdeclarativeitem/tst_qdeclarativeitem.cpp index 57f7a95..137522d 100644 --- a/tests/auto/declarative/qdeclarativeitem/tst_qdeclarativeitem.cpp +++ b/tests/auto/declarative/qdeclarativeitem/tst_qdeclarativeitem.cpp @@ -65,6 +65,7 @@ private slots: void keys(); void keysProcessingOrder(); void keyNavigation(); + void keyNavigation_skipNotVisible(); void smooth(); void clip(); void mapCoordinates(); @@ -82,6 +83,10 @@ private slots: void mouseFocus(); void transformCrash(); + void implicitSize(); + void testQtQuick11Attributes(); + void testQtQuick11Attributes_data(); + void qtbug_16871(); private: template<typename T> @@ -455,6 +460,84 @@ void tst_QDeclarativeItem::keyNavigation() delete canvas; } +void tst_QDeclarativeItem::keyNavigation_skipNotVisible() +{ + QDeclarativeView *canvas = new QDeclarativeView(0); + canvas->setFixedSize(240,320); + + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/keynavigationtest.qml")); + canvas->show(); + qApp->processEvents(); + + QEvent wa(QEvent::WindowActivate); + QApplication::sendEvent(canvas, &wa); + QFocusEvent fe(QEvent::FocusIn); + QApplication::sendEvent(canvas, &fe); + + QDeclarativeItem *item = findItem<QDeclarativeItem>(canvas->rootObject(), "item1"); + QVERIFY(item); + QVERIFY(item->hasActiveFocus()); + + // Set item 2 to not visible + item = findItem<QDeclarativeItem>(canvas->rootObject(), "item2"); + QVERIFY(item); + item->setVisible(false); + QVERIFY(!item->isVisible()); + + // right + QKeyEvent key(QEvent::KeyPress, Qt::Key_Right, Qt::NoModifier, "", false, 1); + QApplication::sendEvent(canvas, &key); + QVERIFY(key.isAccepted()); + + item = findItem<QDeclarativeItem>(canvas->rootObject(), "item1"); + QVERIFY(item); + QVERIFY(item->hasActiveFocus()); + + // tab + key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "", false, 1); + QApplication::sendEvent(canvas, &key); + QVERIFY(key.isAccepted()); + + item = findItem<QDeclarativeItem>(canvas->rootObject(), "item3"); + QVERIFY(item); + QVERIFY(item->hasActiveFocus()); + + // backtab + key = QKeyEvent(QEvent::KeyPress, Qt::Key_Backtab, Qt::NoModifier, "", false, 1); + QApplication::sendEvent(canvas, &key); + QVERIFY(key.isAccepted()); + + item = findItem<QDeclarativeItem>(canvas->rootObject(), "item1"); + QVERIFY(item); + QVERIFY(item->hasActiveFocus()); + + //Set item 3 to not visible + item = findItem<QDeclarativeItem>(canvas->rootObject(), "item3"); + QVERIFY(item); + item->setVisible(false); + QVERIFY(!item->isVisible()); + + // tab + key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "", false, 1); + QApplication::sendEvent(canvas, &key); + QVERIFY(key.isAccepted()); + + item = findItem<QDeclarativeItem>(canvas->rootObject(), "item4"); + QVERIFY(item); + QVERIFY(item->hasActiveFocus()); + + // backtab + key = QKeyEvent(QEvent::KeyPress, Qt::Key_Backtab, Qt::NoModifier, "", false, 1); + QApplication::sendEvent(canvas, &key); + QVERIFY(key.isAccepted()); + + item = findItem<QDeclarativeItem>(canvas->rootObject(), "item1"); + QVERIFY(item); + QVERIFY(item->hasActiveFocus()); + + delete canvas; +} + void tst_QDeclarativeItem::smooth() { QDeclarativeComponent component(&engine); @@ -836,6 +919,91 @@ void tst_QDeclarativeItem::transformCrash() delete canvas; } +void tst_QDeclarativeItem::implicitSize() +{ + QDeclarativeView *canvas = new QDeclarativeView(0); + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/implicitsize.qml")); + canvas->show(); + + QDeclarativeItem *item = qobject_cast<QDeclarativeItem*>(canvas->rootObject()); + QVERIFY(item); + QCOMPARE(item->width(), qreal(80)); + QCOMPARE(item->height(), qreal(60)); + + QCOMPARE(item->implicitWidth(), qreal(200)); + QCOMPARE(item->implicitHeight(), qreal(100)); + + QMetaObject::invokeMethod(item, "resetSize"); + + QCOMPARE(item->width(), qreal(200)); + QCOMPARE(item->height(), qreal(100)); + + QMetaObject::invokeMethod(item, "changeImplicit"); + + QCOMPARE(item->implicitWidth(), qreal(150)); + QCOMPARE(item->implicitHeight(), qreal(80)); + QCOMPARE(item->width(), qreal(150)); + QCOMPARE(item->height(), qreal(80)); + + delete canvas; +} + +void tst_QDeclarativeItem::testQtQuick11Attributes() +{ + QFETCH(QString, code); + QFETCH(QString, warning); + QFETCH(QString, error); + + QDeclarativeEngine engine; + QObject *obj; + + QDeclarativeComponent valid(&engine); + valid.setData("import QtQuick 1.1; Item { " + code.toUtf8() + " }", QUrl("")); + obj = valid.create(); + QVERIFY(obj); + QVERIFY(valid.errorString().isEmpty()); + delete obj; + + QDeclarativeComponent invalid(&engine); + invalid.setData("import QtQuick 1.0; Item { " + code.toUtf8() + " }", QUrl("")); + QTest::ignoreMessage(QtWarningMsg, warning.toUtf8()); + obj = invalid.create(); + QCOMPARE(invalid.errorString(), error); + delete obj; +} + +void tst_QDeclarativeItem::testQtQuick11Attributes_data() +{ + QTest::addColumn<QString>("code"); + QTest::addColumn<QString>("warning"); + QTest::addColumn<QString>("error"); + + QTest::newRow("implicitWidth") << "implicitWidth: 100" + << "QDeclarativeComponent: Component is not ready" + << ":1 \"Item.implicitWidth\" is not available in QtQuick 1.0.\n"; + + QTest::newRow("implicitHeight") << "implicitHeight: 100" + << "QDeclarativeComponent: Component is not ready" + << ":1 \"Item.implicitHeight\" is not available in QtQuick 1.0.\n"; + + QTest::newRow("onImplicitWidthChanged") << "onImplicitWidthChanged: x" + << "QDeclarativeComponent: Component is not ready" + << ":1 \"Item.onImplicitWidthChanged\" is not available in QtQuick 1.0.\n"; + + QTest::newRow("onImplicitHeightChanged") << "onImplicitHeightChanged: x" + << "QDeclarativeComponent: Component is not ready" + << ":1 \"Item.onImplicitHeightChanged\" is not available in QtQuick 1.0.\n"; +} + +void tst_QDeclarativeItem::qtbug_16871() +{ + QDeclarativeComponent component(&engine, SRCDIR "/data/qtbug_16871.qml"); + QObject *o = component.create(); + QVERIFY(o != 0); + delete o; +} + + template<typename T> T *tst_QDeclarativeItem::findItem(QGraphicsObject *parent, const QString &objectName) { diff --git a/tests/auto/declarative/qdeclarativelanguage/data/allowedRevisionOverloads.qml b/tests/auto/declarative/qdeclarativelanguage/data/allowedRevisionOverloads.qml new file mode 100644 index 0000000..64acbd1 --- /dev/null +++ b/tests/auto/declarative/qdeclarativelanguage/data/allowedRevisionOverloads.qml @@ -0,0 +1,6 @@ +import Test 1.0 + +MyRevisionedLegalOverload +{ +} + diff --git a/tests/auto/declarative/qdeclarativelanguage/data/disallowedRevisionOverloads.errors.txt b/tests/auto/declarative/qdeclarativelanguage/data/disallowedRevisionOverloads.errors.txt new file mode 100644 index 0000000..e9b449d --- /dev/null +++ b/tests/auto/declarative/qdeclarativelanguage/data/disallowedRevisionOverloads.errors.txt @@ -0,0 +1 @@ +3:1:Type Test/MyRevisionedIllegalOverload 1.0 contains an illegal property "propA". This is an error in the type's implementation. diff --git a/tests/auto/declarative/qdeclarativelanguage/data/disallowedRevisionOverloads.qml b/tests/auto/declarative/qdeclarativelanguage/data/disallowedRevisionOverloads.qml new file mode 100644 index 0000000..612bcfe --- /dev/null +++ b/tests/auto/declarative/qdeclarativelanguage/data/disallowedRevisionOverloads.qml @@ -0,0 +1,7 @@ +import Test 1.0 + +MyRevisionedIllegalOverload +{ +} + + diff --git a/tests/auto/declarative/qdeclarativelanguage/data/metaobjectRevision.1.errors.txt b/tests/auto/declarative/qdeclarativelanguage/data/metaobjectRevision.1.errors.txt new file mode 100644 index 0000000..29342dc --- /dev/null +++ b/tests/auto/declarative/qdeclarativelanguage/data/metaobjectRevision.1.errors.txt @@ -0,0 +1 @@ +8:5:"MyRevisionedClass.prop2" is not available in Test 1.0. diff --git a/tests/auto/declarative/qdeclarativelanguage/data/metaobjectRevision.1.qml b/tests/auto/declarative/qdeclarativelanguage/data/metaobjectRevision.1.qml new file mode 100644 index 0000000..4b37ed3 --- /dev/null +++ b/tests/auto/declarative/qdeclarativelanguage/data/metaobjectRevision.1.qml @@ -0,0 +1,9 @@ +// Check that a property in a later revision (prop2) cannot be assigned +import QtQuick 1.0 +import Test 1.0 + +MyRevisionedClass +{ + prop1: 1 + prop2: 2 +} diff --git a/tests/auto/declarative/qdeclarativelanguage/data/metaobjectRevision.2.errors.txt b/tests/auto/declarative/qdeclarativelanguage/data/metaobjectRevision.2.errors.txt new file mode 100644 index 0000000..57b5764 --- /dev/null +++ b/tests/auto/declarative/qdeclarativelanguage/data/metaobjectRevision.2.errors.txt @@ -0,0 +1 @@ +6:5:"MyRevisionedClass.onSignal2" is not available in Test 1.0. diff --git a/tests/auto/declarative/qdeclarativelanguage/data/metaobjectRevision.2.qml b/tests/auto/declarative/qdeclarativelanguage/data/metaobjectRevision.2.qml new file mode 100644 index 0000000..8da7a25 --- /dev/null +++ b/tests/auto/declarative/qdeclarativelanguage/data/metaobjectRevision.2.qml @@ -0,0 +1,7 @@ +import Test 1.0 + +MyRevisionedClass +{ + onSignal1: prop1 = 2 + onSignal2: prop1 = 3 +} diff --git a/tests/auto/declarative/qdeclarativelanguage/data/metaobjectRevision.3.errors.txt b/tests/auto/declarative/qdeclarativelanguage/data/metaobjectRevision.3.errors.txt new file mode 100644 index 0000000..45364a0 --- /dev/null +++ b/tests/auto/declarative/qdeclarativelanguage/data/metaobjectRevision.3.errors.txt @@ -0,0 +1 @@ +9:5:"MyRevisionedClass.propD" is not available in Test 1.1. diff --git a/tests/auto/declarative/qdeclarativelanguage/data/metaobjectRevision.3.qml b/tests/auto/declarative/qdeclarativelanguage/data/metaobjectRevision.3.qml new file mode 100644 index 0000000..195be21 --- /dev/null +++ b/tests/auto/declarative/qdeclarativelanguage/data/metaobjectRevision.3.qml @@ -0,0 +1,10 @@ +import Test 1.1 + +MyRevisionedClass +{ + propA: 10 + propB: 10 + propC: 10 + // propD is in rev 1 of MyRevisionedClassUnregistered, but not registered in 1.1 + propD: 10 +} diff --git a/tests/auto/declarative/qdeclarativelanguage/data/revisions11.qml b/tests/auto/declarative/qdeclarativelanguage/data/revisions11.qml new file mode 100644 index 0000000..4d3d7d2 --- /dev/null +++ b/tests/auto/declarative/qdeclarativelanguage/data/revisions11.qml @@ -0,0 +1,10 @@ +import QtQuick 1.0 +import Test 1.1 + +MyRevisionedClass +{ + prop1: 1 + prop2: 10 + + onSignal2: prop2 = 3 +} diff --git a/tests/auto/declarative/qdeclarativelanguage/data/revisionsbasesub11.qml b/tests/auto/declarative/qdeclarativelanguage/data/revisionsbasesub11.qml new file mode 100644 index 0000000..57d76b1 --- /dev/null +++ b/tests/auto/declarative/qdeclarativelanguage/data/revisionsbasesub11.qml @@ -0,0 +1,16 @@ +import QtQuick 1.0 +import Test 1.1 + +MyRevisionedSubclass +{ + propA: 10 + propB: 10 + propC: 10 + // propD is not registered in 1.1 + prop1: 10 + prop2: 10 + prop3: 10 + prop4: 10 + + onSignal4: prop4 = 2 +} diff --git a/tests/auto/declarative/qdeclarativelanguage/data/revisionssub11.qml b/tests/auto/declarative/qdeclarativelanguage/data/revisionssub11.qml new file mode 100644 index 0000000..f107356 --- /dev/null +++ b/tests/auto/declarative/qdeclarativelanguage/data/revisionssub11.qml @@ -0,0 +1,12 @@ +import QtQuick 1.0 +import Test 1.1 + +MyRevisionedSubclass +{ + prop1: 10 + prop2: 10 + prop3: 10 + prop4: 10 + + onSignal4: prop4 = 2 +} diff --git a/tests/auto/declarative/qdeclarativelanguage/data/versionedbase.qml b/tests/auto/declarative/qdeclarativelanguage/data/versionedbase.qml new file mode 100644 index 0000000..8c74715 --- /dev/null +++ b/tests/auto/declarative/qdeclarativelanguage/data/versionedbase.qml @@ -0,0 +1,8 @@ +import QtQuick 1.0 +import Test 1.1 + +MySubclass +{ + prop1: 10 + prop2: 10 +} diff --git a/tests/auto/declarative/qdeclarativelanguage/testtypes.cpp b/tests/auto/declarative/qdeclarativelanguage/testtypes.cpp index e312e31..69cba76 100644 --- a/tests/auto/declarative/qdeclarativelanguage/testtypes.cpp +++ b/tests/auto/declarative/qdeclarativelanguage/testtypes.cpp @@ -52,6 +52,20 @@ void registerTypes() qmlRegisterType<MyNamespace::MySecondNamespacedType>("Test",1,0,"MySecondNamespacedType"); qmlRegisterType<MyParserStatus>("Test",1,0,"MyParserStatus"); qmlRegisterType<MyGroupedObject>(); + qmlRegisterType<MyRevisionedClass>("Test",1,0,"MyRevisionedClass"); + qmlRegisterType<MyRevisionedClass,1>("Test",1,1,"MyRevisionedClass"); + qmlRegisterType<MyRevisionedIllegalOverload>("Test",1,0,"MyRevisionedIllegalOverload"); + qmlRegisterType<MyRevisionedLegalOverload>("Test",1,0,"MyRevisionedLegalOverload"); + + // Register the uncreatable base class + qmlRegisterRevision<MyRevisionedBaseClassRegistered,1>("Test",1,1); + // MyRevisionedSubclass 1.0 uses MyRevisionedClass revision 0 + qmlRegisterType<MyRevisionedSubclass>("Test",1,0,"MyRevisionedSubclass"); + // MyRevisionedSubclass 1.1 uses MyRevisionedClass revision 1 + qmlRegisterType<MyRevisionedSubclass,1>("Test",1,1,"MyRevisionedSubclass"); + + // Only version 1.0, but its super class is registered in version 1.1 also + qmlRegisterType<MySubclass>("Test",1,0,"MySubclass"); qmlRegisterCustomType<MyCustomParserType>("Test", 1, 0, "MyCustomParserType", new MyCustomParserTypeParser); diff --git a/tests/auto/declarative/qdeclarativelanguage/testtypes.h b/tests/auto/declarative/qdeclarativelanguage/testtypes.h index 2cdf580..12424d0 100644 --- a/tests/auto/declarative/qdeclarativelanguage/testtypes.h +++ b/tests/auto/declarative/qdeclarativelanguage/testtypes.h @@ -601,6 +601,207 @@ private: int m_ccc; }; +class MyRevisionedBaseClassRegistered : public QObject +{ + Q_OBJECT + Q_PROPERTY(qreal propA READ propA WRITE setPropA NOTIFY propAChanged) + Q_PROPERTY(qreal propB READ propB WRITE setPropB NOTIFY propBChanged REVISION 1) + +public: + MyRevisionedBaseClassRegistered() : m_pa(1), m_pb(2) {} + + qreal propA() const { return m_pa; } + void setPropA(qreal p) { + if (p != m_pa) { + m_pa = p; + emit propAChanged(); + } + } + qreal propB() const { return m_pb; } + void setPropB(qreal p) { + if (p != m_pb) { + m_pb = p; + emit propBChanged(); + } + } + + Q_INVOKABLE void methodA() { } + Q_INVOKABLE Q_REVISION(1) void methodB() { } + +signals: + void propAChanged(); + void propBChanged(); + + void signalA(); + Q_REVISION(1) void signalB(); + +protected: + qreal m_pa; + qreal m_pb; +}; + +class MyRevisionedIllegalOverload : public MyRevisionedBaseClassRegistered +{ + Q_OBJECT + Q_PROPERTY(qreal propA READ propA WRITE setPropA REVISION 1); +}; + +class MyRevisionedLegalOverload : public MyRevisionedBaseClassRegistered +{ + Q_OBJECT + Q_PROPERTY(qreal propB READ propB WRITE setPropB REVISION 1); +}; + +class MyRevisionedBaseClassUnregistered : public MyRevisionedBaseClassRegistered +{ + Q_OBJECT + Q_PROPERTY(qreal propC READ propC WRITE setPropC NOTIFY propCChanged) + Q_PROPERTY(qreal propD READ propD WRITE setPropD NOTIFY propDChanged REVISION 1) + +public: + MyRevisionedBaseClassUnregistered() : m_pc(1), m_pd(2) {} + + qreal propC() const { return m_pc; } + void setPropC(qreal p) { + if (p != m_pc) { + m_pc = p; + emit propCChanged(); + } + } + qreal propD() const { return m_pd; } + void setPropD(qreal p) { + if (p != m_pd) { + m_pd = p; + emit propDChanged(); + } + } + + Q_INVOKABLE void methodC() { } + Q_INVOKABLE Q_REVISION(1) void methodD() { } + +signals: + void propCChanged(); + void propDChanged(); + + void signalC(); + Q_REVISION(1) void signalD(); + +protected: + qreal m_pc; + qreal m_pd; +}; + +class MyRevisionedClass : public MyRevisionedBaseClassUnregistered +{ + Q_OBJECT + Q_PROPERTY(qreal prop1 READ prop1 WRITE setProp1 NOTIFY prop1Changed) + Q_PROPERTY(qreal prop2 READ prop2 WRITE setProp2 NOTIFY prop2Changed REVISION 1) + +public: + MyRevisionedClass() : m_p1(1), m_p2(2) {} + + qreal prop1() const { return m_p1; } + void setProp1(qreal p) { + if (p != m_p1) { + m_p1 = p; + emit prop1Changed(); + } + } + qreal prop2() const { return m_p2; } + void setProp2(qreal p) { + if (p != m_p2) { + m_p2 = p; + emit prop2Changed(); + } + } + + Q_INVOKABLE void method1() { } + Q_INVOKABLE Q_REVISION(1) void method2() { } + +signals: + void prop1Changed(); + void prop2Changed(); + + void signal1(); + Q_REVISION(1) void signal2(); + +protected: + qreal m_p1; + qreal m_p2; +}; + +class MyRevisionedSubclass : public MyRevisionedClass +{ + Q_OBJECT + Q_PROPERTY(qreal prop3 READ prop3 WRITE setProp3 NOTIFY prop3Changed) + Q_PROPERTY(qreal prop4 READ prop4 WRITE setProp4 NOTIFY prop4Changed REVISION 1) + +public: + MyRevisionedSubclass() : m_p3(3), m_p4(4) {} + + qreal prop3() const { return m_p3; } + void setProp3(qreal p) { + if (p != m_p3) { + m_p3 = p; + emit prop3Changed(); + } + } + qreal prop4() const { return m_p4; } + void setProp4(qreal p) { + if (p != m_p4) { + m_p4 = p; + emit prop4Changed(); + } + } + + Q_INVOKABLE void method3() { } + Q_INVOKABLE Q_REVISION(1) void method4() { } + +signals: + void prop3Changed(); + void prop4Changed(); + + void signal3(); + Q_REVISION(1) void signal4(); + +protected: + qreal m_p3; + qreal m_p4; +}; + +class MySubclass : public MyRevisionedClass +{ + Q_OBJECT + Q_PROPERTY(qreal prop5 READ prop5 WRITE setProp5 NOTIFY prop5Changed) + +public: + MySubclass() : m_p5(5) {} + + qreal prop5() const { return m_p5; } + void setProp5(qreal p) { + if (p != m_p5) { + m_p5 = p; + emit prop5Changed(); + } + } + + Q_INVOKABLE void method5() { } + +signals: + void prop5Changed(); + +protected: + qreal m_p5; +}; + +QML_DECLARE_TYPE(MyRevisionedBaseClassRegistered) +QML_DECLARE_TYPE(MyRevisionedBaseClassUnregistered) +QML_DECLARE_TYPE(MyRevisionedClass) +QML_DECLARE_TYPE(MyRevisionedSubclass) +QML_DECLARE_TYPE(MySubclass) + + + void registerTypes(); #endif // TESTTYPES_H diff --git a/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp b/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp index a3e8ce6..f3f41a9 100644 --- a/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp +++ b/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp @@ -153,6 +153,9 @@ private slots: void customOnProperty(); void variantNotify(); + void revisions(); + void revisionOverloads(); + // regression tests for crashes void crash1(); void crash2(); @@ -421,6 +424,10 @@ void tst_qdeclarativelanguage::errors_data() << "incorrectCase.errors.sensitive.txt" #endif << false; + + QTest::newRow("metaobjectRevision.1") << "metaobjectRevision.1.qml" << "metaobjectRevision.1.errors.txt" << false; + QTest::newRow("metaobjectRevision.2") << "metaobjectRevision.2.qml" << "metaobjectRevision.2.errors.txt" << false; + QTest::newRow("metaobjectRevision.3") << "metaobjectRevision.3.qml" << "metaobjectRevision.3.errors.txt" << false; } @@ -947,7 +954,7 @@ void tst_qdeclarativelanguage::aliasProperties() object->setProperty("value", QVariant(13)); QCOMPARE(object->property("valueAlias").toInt(), 13); - // Write throught alias + // Write through alias object->setProperty("valueAlias", QVariant(19)); QCOMPARE(object->property("valueAlias").toInt(), 19); QCOMPARE(object->property("value").toInt(), 19); @@ -1109,7 +1116,7 @@ void tst_qdeclarativelanguage::aliasProperties() object->setProperty("rectProperty", QVariant(QRect(33, 12, 99, 100))); QCOMPARE(object->property("valueAlias").toRect(), QRect(33, 12, 99, 100)); - // Write throught alias + // Write through alias object->setProperty("valueAlias", QVariant(QRect(3, 3, 4, 9))); QCOMPARE(object->property("valueAlias").toRect(), QRect(3, 3, 4, 9)); QCOMPARE(object->property("rectProperty").toRect(), QRect(3, 3, 4, 9)); @@ -1129,7 +1136,7 @@ void tst_qdeclarativelanguage::aliasProperties() object->setProperty("rectProperty", QVariant(QRect(33, 8, 102, 111))); QCOMPARE(object->property("aliasProperty").toInt(), 33); - // Write throught alias + // Write through alias object->setProperty("aliasProperty", QVariant(4)); QCOMPARE(object->property("aliasProperty").toInt(), 4); QCOMPARE(object->property("rectProperty").toRect(), QRect(4, 8, 102, 111)); @@ -1888,6 +1895,61 @@ void tst_qdeclarativelanguage::variantNotify() delete object; } +void tst_qdeclarativelanguage::revisions() +{ + { + QDeclarativeComponent component(&engine, TEST_FILE("revisions11.qml")); + + VERIFY_ERRORS(0); + MyRevisionedClass *object = qobject_cast<MyRevisionedClass*>(component.create()); + QVERIFY(object != 0); + + QCOMPARE(object->prop2(), 10.0); + + delete object; + } + { + QDeclarativeEngine myEngine; + QDeclarativeComponent component(&myEngine, TEST_FILE("revisionssub11.qml")); + + VERIFY_ERRORS(0); + MyRevisionedSubclass *object = qobject_cast<MyRevisionedSubclass*>(component.create()); + QVERIFY(object != 0); + + QCOMPARE(object->prop1(), 10.0); + QCOMPARE(object->prop2(), 10.0); + QCOMPARE(object->prop3(), 10.0); + QCOMPARE(object->prop4(), 10.0); + + delete object; + } + { + QDeclarativeComponent component(&engine, TEST_FILE("versionedbase.qml")); + VERIFY_ERRORS(0); + MySubclass *object = qobject_cast<MySubclass*>(component.create()); + QVERIFY(object != 0); + + QCOMPARE(object->prop1(), 10.0); + QCOMPARE(object->prop2(), 10.0); + + delete object; + } +} + +void tst_qdeclarativelanguage::revisionOverloads() +{ + { + QDeclarativeComponent component(&engine, TEST_FILE("allowedRevisionOverloads.qml")); + VERIFY_ERRORS(0); + } + { + QDeclarativeComponent component(&engine, TEST_FILE("disallowedRevisionOverloads.qml")); + QEXPECT_FAIL("", "QTBUG-13849", Abort); + QVERIFY(0); + VERIFY_ERRORS("disallowedRevisionOverloads.errors.txt"); + } +} + void tst_qdeclarativelanguage::initTestCase() { registerTypes(); diff --git a/tests/auto/declarative/qdeclarativelistmodel/data/setmodelcachelist.qml b/tests/auto/declarative/qdeclarativelistmodel/data/setmodelcachelist.qml new file mode 100644 index 0000000..ffe417a --- /dev/null +++ b/tests/auto/declarative/qdeclarativelistmodel/data/setmodelcachelist.qml @@ -0,0 +1,20 @@ +import QtQuick 1.0 + +ListModel { + id: model + property bool ok : false + + Component.onCompleted: { + model.append({"attrs": []}) + model.get(0) + model.set(0, {"attrs": [{'abc': 123, 'def': 456}] } ) + ok = ( model.get(0).attrs.get(0).abc == 123 + && model.get(0).attrs.get(0).def == 456 ) + + model.set(0, {"attrs": [{'abc': 789, 'def': 101}] } ) + ok = ( model.get(0).attrs.get(0).abc == 789 + && model.get(0).attrs.get(0).def == 101 ) + + } +} + diff --git a/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp b/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp index 5a88dd1..45072f3 100644 --- a/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp +++ b/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp @@ -59,6 +59,7 @@ #endif Q_DECLARE_METATYPE(QList<int>) +Q_DECLARE_METATYPE(QList<QVariantHash>) class tst_qdeclarativelistmodel : public QObject { @@ -100,6 +101,11 @@ private slots: void get_nested(); void get_nested_data(); void crash_model_with_multiple_roles(); + void set_model_cache(); + void property_changes(); + void property_changes_data(); + void property_changes_worker(); + void property_changes_worker_data(); }; int tst_qdeclarativelistmodel::roleFromName(const QDeclarativeListModel *model, const QString &roleName) { @@ -297,13 +303,10 @@ void tst_qdeclarativelistmodel::dynamic_data() QTest::newRow("nested-append3") << "{append({'foo':123,'bars':[{'a':1},{'a':2},{'a':3}]});get(0).bars.append({'a':4});get(0).bars.get(3).a}" << 4 << ""; QTest::newRow("nested-insert") << "{append({'foo':123});insert(0,{'bars':[{'a':1},{'b':2},{'c':3}]});get(0).bars.get(0).a}" << 1 << ""; - QTest::newRow("nested-set") << "{append({'foo':123});set(0,{'foo':[{'x':123}]});get(0).foo.get(0).x}" << 123 << ""; + QTest::newRow("nested-set") << "{append({'foo':[{'x':1}]});set(0,{'foo':[{'x':123}]});get(0).foo.get(0).x}" << 123 << ""; QTest::newRow("nested-count") << "{append({'foo':123,'bars':[{'a':1},{'a':2},{'a':3}]}); get(0).bars.count}" << 3 << ""; QTest::newRow("nested-clear") << "{append({'foo':123,'bars':[{'a':1},{'a':2},{'a':3}]}); get(0).bars.clear(); get(0).bars.count}" << 0 << ""; - - // XXX - //QTest::newRow("nested-setprop") << "{append({'foo':123});setProperty(0,'foo',[{'x':123}]);get(0).foo.get(0).x}" << 123 << ""; } void tst_qdeclarativelistmodel::dynamic() @@ -420,6 +423,9 @@ void tst_qdeclarativelistmodel::dynamic_worker_sync() if (QByteArray(QTest::currentDataTag()).startsWith("nested")) QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML ListModel: Cannot add list-type data when modifying or after modification from a worker script"); + if (QByteArray(QTest::currentDataTag()).startsWith("nested-set")) + QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML ListModel: Cannot add list-type data when modifying or after modification from a worker script"); + QVERIFY(QMetaObject::invokeMethod(item, "evalExpressionViaWorker", Q_ARG(QVariant, operations.mid(0, operations.length()-1)))); waitForWorker(item); @@ -928,6 +934,163 @@ void tst_qdeclarativelistmodel::crash_model_with_multiple_roles() model->setProperty(0, "black", true); } +//QTBUG-15190 +void tst_qdeclarativelistmodel::set_model_cache() +{ + QDeclarativeEngine eng; + QDeclarativeComponent component(&eng, QUrl::fromLocalFile(SRCDIR "/data/setmodelcachelist.qml")); + QObject *model = component.create(); + QVERIFY2(component.errorString().isEmpty(), QTest::toString(component.errorString())); + QVERIFY(model != 0); + QVERIFY(model->property("ok").toBool()); +} + +void tst_qdeclarativelistmodel::property_changes() +{ + QFETCH(QString, script_setup); + QFETCH(QString, script_change); + QFETCH(QString, roleName); + QFETCH(int, listIndex); + QFETCH(bool, itemsChanged); + QFETCH(QString, testExpression); + + QDeclarativeEngine engine; + QDeclarativeListModel model; + QDeclarativeEngine::setContextForObject(&model, engine.rootContext()); + engine.rootContext()->setContextObject(&model); + + QDeclarativeExpression expr(engine.rootContext(), &model, script_setup); + expr.evaluate(); + QVERIFY2(!expr.hasError(), QTest::toString(expr.error().toString())); + + QString signalHandler = "on" + QString(roleName[0].toUpper()) + roleName.mid(1, roleName.length()) + "Changed:"; + QString qml = "import QtQuick 1.0\n" + "Connections {\n" + "property bool gotSignal: false\n" + "target: model.get(0)\n" + + signalHandler + " gotSignal = true\n" + "}\n"; + QDeclarativeComponent component(&engine); + component.setData(qml.toUtf8(), QUrl::fromLocalFile("")); + engine.rootContext()->setContextProperty("model", &model); + QObject *connectionsObject = component.create(); + QVERIFY2(component.errorString().isEmpty(), QTest::toString(component.errorString())); + + QSignalSpy spyItemsChanged(&model, SIGNAL(itemsChanged(int, int, QList<int>))); + + expr.setExpression(script_change); + expr.evaluate(); + QVERIFY2(!expr.hasError(), QTest::toString(expr.error())); + + // test the object returned by get() emits the correct signals + QCOMPARE(connectionsObject->property("gotSignal").toBool(), itemsChanged); + + // test itemsChanged() is emitted correctly + if (itemsChanged) { + QCOMPARE(spyItemsChanged.count(), 1); + QCOMPARE(spyItemsChanged.at(0).at(0).toInt(), listIndex); + QCOMPARE(spyItemsChanged.at(0).at(1).toInt(), 1); + } else { + QCOMPARE(spyItemsChanged.count(), 0); + } + + expr.setExpression(testExpression); + QCOMPARE(expr.evaluate().toBool(), true); + + delete connectionsObject; +} + +void tst_qdeclarativelistmodel::property_changes_data() +{ + QTest::addColumn<QString>("script_setup"); + QTest::addColumn<QString>("script_change"); + QTest::addColumn<QString>("roleName"); + QTest::addColumn<int>("listIndex"); + QTest::addColumn<bool>("itemsChanged"); + QTest::addColumn<QString>("testExpression"); + + QTest::newRow("set: plain") << "append({'a':123, 'b':456, 'c':789});" << "set(0,{'b':123});" + << "b" << 0 << true << "get(0).b == 123"; + QTest::newRow("setProperty: plain") << "append({'a':123, 'b':456, 'c':789});" << "setProperty(0, 'b', 123);" + << "b" << 0 << true << "get(0).b == 123"; + + QTest::newRow("set: plain, no changes") << "append({'a':123, 'b':456, 'c':789});" << "set(0,{'b':456});" + << "b" << 0 << false << "get(0).b == 456"; + QTest::newRow("setProperty: plain, no changes") << "append({'a':123, 'b':456, 'c':789});" << "setProperty(0, 'b', 456);" + << "b" << 0 << false << "get(0).b == 456"; + + // Following tests only call set() since setProperty() only allows plain + // values, not lists, as the argument. + // Note that when a list is changed, itemsChanged() is currently always + // emitted regardless of whether it actually changed or not. + + QTest::newRow("nested-set: list, new size") << "append({'a':123, 'b':[{'a':1},{'a':2},{'a':3}], 'c':789});" << "set(0,{'b':[{'a':1},{'a':2}]});" + << "b" << 0 << true << "get(0).b.get(0).a == 1 && get(0).b.get(1).a == 2"; + + QTest::newRow("nested-set: list, empty -> non-empty") << "append({'a':123, 'b':[], 'c':789});" << "set(0,{'b':[{'a':1},{'a':2},{'a':3}]});" + << "b" << 0 << true << "get(0).b.get(0).a == 1 && get(0).b.get(1).a == 2 && get(0).b.get(2).a == 3"; + + QTest::newRow("nested-set: list, non-empty -> empty") << "append({'a':123, 'b':[{'a':1},{'a':2},{'a':3}], 'c':789});" << "set(0,{'b':[]});" + << "b" << 0 << true << "get(0).b.count == 0"; + + QTest::newRow("nested-set: list, same size, different values") << "append({'a':123, 'b':[{'a':1},{'a':2},{'a':3}], 'c':789});" << "set(0,{'b':[{'a':1},{'a':222},{'a':3}]});" + << "b" << 0 << true << "get(0).b.get(0).a == 1 && get(0).b.get(1).a == 222 && get(0).b.get(2).a == 3"; + + QTest::newRow("nested-set: list, no changes") << "append({'a':123, 'b':[{'a':1},{'a':2},{'a':3}], 'c':789});" << "set(0,{'b':[{'a':1},{'a':2},{'a':3}]});" + << "b" << 0 << true << "get(0).b.get(0).a == 1 && get(0).b.get(1).a == 2 && get(0).b.get(2).a == 3"; + + QTest::newRow("nested-set: list, no changes, empty") << "append({'a':123, 'b':[], 'c':789});" << "set(0,{'b':[]});" + << "b" << 0 << true << "get(0).b.count == 0"; +} + + +void tst_qdeclarativelistmodel::property_changes_worker() +{ + // nested models are not supported when WorkerScript is involved + if (QByteArray(QTest::currentDataTag()).startsWith("nested-")) + return; + + QFETCH(QString, script_setup); + QFETCH(QString, script_change); + QFETCH(QString, roleName); + QFETCH(int, listIndex); + QFETCH(bool, itemsChanged); + + QDeclarativeListModel model; + QDeclarativeEngine engine; + QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/model.qml")); + QVERIFY2(component.errorString().isEmpty(), component.errorString().toUtf8()); + QDeclarativeItem *item = createWorkerTest(&engine, &component, &model); + QVERIFY(item != 0); + + QDeclarativeExpression expr(engine.rootContext(), &model, script_setup); + expr.evaluate(); + QVERIFY2(!expr.hasError(), QTest::toString(expr.error().toString())); + + QSignalSpy spyItemsChanged(&model, SIGNAL(itemsChanged(int, int, QList<int>))); + + QVERIFY(QMetaObject::invokeMethod(item, "evalExpressionViaWorker", + Q_ARG(QVariant, QStringList(script_change)))); + waitForWorker(item); + + // test itemsChanged() is emitted correctly + if (itemsChanged) { + QCOMPARE(spyItemsChanged.count(), 1); + QCOMPARE(spyItemsChanged.at(0).at(0).toInt(), listIndex); + QCOMPARE(spyItemsChanged.at(0).at(1).toInt(), 1); + } else { + QCOMPARE(spyItemsChanged.count(), 0); + } + + delete item; + qApp->processEvents(); +} + +void tst_qdeclarativelistmodel::property_changes_worker_data() +{ + property_changes_data(); +} + QTEST_MAIN(tst_qdeclarativelistmodel) #include "tst_qdeclarativelistmodel.moc" diff --git a/tests/auto/declarative/qdeclarativelistview/data/footer.qml b/tests/auto/declarative/qdeclarativelistview/data/footer.qml index 4cbd33b..33e04f1 100644 --- a/tests/auto/declarative/qdeclarativelistview/data/footer.qml +++ b/tests/auto/declarative/qdeclarativelistview/data/footer.qml @@ -1,6 +1,9 @@ import QtQuick 1.0 Rectangle { + function changeFooter() { + list.footer = footer2 + } width: 240 height: 320 color: "#ffffff" @@ -27,4 +30,9 @@ Rectangle { delegate: myDelegate footer: Text { objectName: "footer"; text: "Footer"; height: 30 } } + + Component { + id: footer2 + Text { objectName: "footer2"; text: "Footer 2"; height: 20 } + } } diff --git a/tests/auto/declarative/qdeclarativelistview/data/header.qml b/tests/auto/declarative/qdeclarativelistview/data/header.qml index 6da996e..38cdd6e 100644 --- a/tests/auto/declarative/qdeclarativelistview/data/header.qml +++ b/tests/auto/declarative/qdeclarativelistview/data/header.qml @@ -1,6 +1,9 @@ import QtQuick 1.0 Rectangle { + function changeHeader() { + list.header = header2 + } width: 240 height: 320 color: "#ffffff" @@ -26,6 +29,10 @@ Rectangle { snapMode: ListView.SnapToItem model: testModel delegate: myDelegate - header: Text { objectName: "header"; text: "Header"; height: 10 } + header: Text { objectName: "header"; text: "Header"; height: 20 } + } + Component { + id: header2 + Text { objectName: "header2"; text: "Header 2"; height: 10 } } } diff --git a/tests/auto/declarative/qdeclarativelistview/data/listviewtest.qml b/tests/auto/declarative/qdeclarativelistview/data/listviewtest.qml index 534540f..3cd6f42 100644 --- a/tests/auto/declarative/qdeclarativelistview/data/listviewtest.qml +++ b/tests/auto/declarative/qdeclarativelistview/data/listviewtest.qml @@ -1,10 +1,13 @@ import QtQuick 1.0 Rectangle { + id: root width: 240 height: 320 color: "#ffffff" + property bool showHeader: false + property bool showFooter: false property real hr: list.visibleArea.heightRatio function heightRatio() { return list.visibleArea.heightRatio @@ -105,6 +108,10 @@ Rectangle { Component { id: invalidHl SmoothedAnimation {} + }, + Component { + id: headerFooter + Rectangle { height: 30; width: 240; color: "blue" } } ] ListView { @@ -119,5 +126,7 @@ Rectangle { highlightMoveSpeed: 1000 highlightResizeSpeed: 1000 cacheBuffer: testObject.cacheBuffer + header: root.showHeader ? headerFooter : null + footer: root.showFooter ? headerFooter : null } } diff --git a/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp b/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp index 9b6f04c..86b68ca 100644 --- a/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp +++ b/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp @@ -108,6 +108,8 @@ private slots: void QTBUG_16037(); void indexAt(); void incrementalModel(); + void testQtQuick11Attributes(); + void testQtQuick11Attributes_data(); private: template <class T> void items(); @@ -1383,6 +1385,24 @@ void tst_QDeclarativeListView::positionViewAtIndex() listview->positionViewAtIndex(20, QDeclarativeListView::Contain); QTRY_COMPARE(listview->contentY(), 100.); + // positionAtBeginnging + listview->positionViewAtBeginning(); + QTRY_COMPARE(listview->contentY(), 0.); + + listview->setContentY(80); + canvas->rootObject()->setProperty("showHeader", true); + listview->positionViewAtBeginning(); + QTRY_COMPARE(listview->contentY(), -30.); + + // positionAtEnd + listview->positionViewAtEnd(); + QTRY_COMPARE(listview->contentY(), 480.); // 40*20 - 320 + + listview->setContentY(80); + canvas->rootObject()->setProperty("showFooter", true); + listview->positionViewAtEnd(); + QTRY_COMPARE(listview->contentY(), 510.); + delete canvas; } @@ -1716,12 +1736,27 @@ void tst_QDeclarativeListView::header() QDeclarativeText *header = findItem<QDeclarativeText>(contentItem, "header"); QVERIFY(header); QCOMPARE(header->y(), 0.0); + QCOMPARE(header->height(), 20.0); QCOMPARE(listview->contentY(), 0.0); model.clear(); QTRY_COMPARE(header->y(), 0.0); + for (int i = 0; i < 30; i++) + model.addItem("Item" + QString::number(i), ""); + + QMetaObject::invokeMethod(canvas->rootObject(), "changeHeader"); + + header = findItem<QDeclarativeText>(contentItem, "header"); + QVERIFY(!header); + header = findItem<QDeclarativeText>(contentItem, "header2"); + QVERIFY(header); + + QCOMPARE(header->y(), 0.0); + QCOMPARE(header->height(), 10.0); + QCOMPARE(listview->contentY(), 0.0); + delete canvas; } { @@ -1776,6 +1811,7 @@ void tst_QDeclarativeListView::footer() QDeclarativeText *footer = findItem<QDeclarativeText>(contentItem, "footer"); QVERIFY(footer); QCOMPARE(footer->y(), 60.0); + QCOMPARE(footer->height(), 30.0); model.removeItem(1); QTRY_COMPARE(footer->y(), 40.0); @@ -1783,6 +1819,20 @@ void tst_QDeclarativeListView::footer() model.clear(); QTRY_COMPARE(footer->y(), 0.0); + for (int i = 0; i < 30; i++) + model.addItem("Item" + QString::number(i), ""); + + QMetaObject::invokeMethod(canvas->rootObject(), "changeFooter"); + + footer = findItem<QDeclarativeText>(contentItem, "footer"); + QVERIFY(!footer); + footer = findItem<QDeclarativeText>(contentItem, "footer2"); + QVERIFY(footer); + + QCOMPARE(footer->y(), 0.0); + QCOMPARE(footer->height(), 20.0); + QCOMPARE(listview->contentY(), 0.0); + delete canvas; } @@ -2039,6 +2089,45 @@ void tst_QDeclarativeListView::incrementalModel() delete canvas; } +void tst_QDeclarativeListView::testQtQuick11Attributes() +{ + QFETCH(QString, code); + QFETCH(QString, warning); + QFETCH(QString, error); + + QDeclarativeEngine engine; + QObject *obj; + + QDeclarativeComponent valid(&engine); + valid.setData("import QtQuick 1.1; ListView { " + code.toUtf8() + " }", QUrl("")); + obj = valid.create(); + QVERIFY(obj); + QVERIFY(valid.errorString().isEmpty()); + delete obj; + + QDeclarativeComponent invalid(&engine); + invalid.setData("import QtQuick 1.0; ListView { " + code.toUtf8() + " }", QUrl("")); + QTest::ignoreMessage(QtWarningMsg, warning.toUtf8()); + obj = invalid.create(); + QCOMPARE(invalid.errorString(), error); + delete obj; +} + +void tst_QDeclarativeListView::testQtQuick11Attributes_data() +{ + QTest::addColumn<QString>("code"); + QTest::addColumn<QString>("warning"); + QTest::addColumn<QString>("error"); + + QTest::newRow("positionViewAtBeginning") << "Component.onCompleted: positionViewAtBeginning()" + << "<Unknown File>:1: ReferenceError: Can't find variable: positionViewAtBeginning" + << ""; + + QTest::newRow("positionViewAtEnd") << "Component.onCompleted: positionViewAtEnd()" + << "<Unknown File>:1: ReferenceError: Can't find variable: positionViewAtEnd" + << ""; +} + void tst_QDeclarativeListView::qListModelInterface_items() { items<TestModel>(); diff --git a/tests/auto/declarative/qdeclarativeloader/data/QTBUG_16928.qml b/tests/auto/declarative/qdeclarativeloader/data/QTBUG_16928.qml new file mode 100644 index 0000000..9949e34 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeloader/data/QTBUG_16928.qml @@ -0,0 +1,23 @@ +import QtQuick 1.1 + +Rectangle { + color: "green" + width: loader.implicitWidth+50 + height: loader.implicitHeight+50 + + Loader { + id: loader + sourceComponent: Item { + anchors.centerIn: parent + + implicitWidth: 200 + implicitHeight: 200 + Rectangle { + color: "red" + anchors.fill: parent + } + } + anchors.fill: parent + anchors.margins: 15 + } +} diff --git a/tests/auto/declarative/qdeclarativeloader/data/QTBUG_17114.qml b/tests/auto/declarative/qdeclarativeloader/data/QTBUG_17114.qml new file mode 100644 index 0000000..8a49733 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeloader/data/QTBUG_17114.qml @@ -0,0 +1,18 @@ +import QtQuick 1.1 + +Rectangle { + property real loaderWidth: loader.width + property real loaderHeight: loader.height + width: 200 + height: 200 + + Loader { + id: loader + sourceComponent: Item { + property real iwidth: 32 + property real iheight: 32 + width: iwidth + height: iheight + } + } +} diff --git a/tests/auto/declarative/qdeclarativeloader/data/implicitSize.qml b/tests/auto/declarative/qdeclarativeloader/data/implicitSize.qml new file mode 100644 index 0000000..53aad97 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeloader/data/implicitSize.qml @@ -0,0 +1,28 @@ +import QtQuick 1.1 + +Rectangle { + property real implWidth: 0 + property real implHeight: 0 + color: "green" + width: loader.implicitWidth+50 + height: loader.implicitHeight+50 + + Loader { + id: loader + sourceComponent: Item { + anchors.centerIn: parent + + implicitWidth: 100 + implicitHeight: 100 + Rectangle { + color: "red" + anchors.fill: parent + } + } + + anchors.fill: parent + anchors.margins: 50 + onImplicitWidthChanged: implWidth = implicitWidth + onImplicitHeightChanged: implHeight = loader.implicitHeight + } +} diff --git a/tests/auto/declarative/qdeclarativeloader/tst_qdeclarativeloader.cpp b/tests/auto/declarative/qdeclarativeloader/tst_qdeclarativeloader.cpp index bfa81ed..f5218c7 100644 --- a/tests/auto/declarative/qdeclarativeloader/tst_qdeclarativeloader.cpp +++ b/tests/auto/declarative/qdeclarativeloader/tst_qdeclarativeloader.cpp @@ -69,9 +69,8 @@ public: tst_QDeclarativeLoader(); private slots: - void url(); - void invalidUrl(); - void component(); + void sourceOrComponent(); + void sourceOrComponent_data(); void clear(); void urlToComponent(); void componentToUrl(); @@ -90,6 +89,9 @@ private slots: void nonItem(); void vmeErrors(); void creationContext(); + void QTBUG_16928(); + void implicitSize(); + void QTBUG_17114(); private: QDeclarativeEngine engine; @@ -100,56 +102,71 @@ tst_QDeclarativeLoader::tst_QDeclarativeLoader() { } -void tst_QDeclarativeLoader::url() +void tst_QDeclarativeLoader::sourceOrComponent() { + QFETCH(QString, sourceDefinition); + QFETCH(QUrl, sourceUrl); + QFETCH(QString, errorString); + + bool error = !errorString.isEmpty(); + if (error) + QTest::ignoreMessage(QtWarningMsg, errorString.toUtf8().constData()); + QDeclarativeComponent component(&engine); - component.setData(QByteArray("import QtQuick 1.0\nLoader { property int did_load: 0; onLoaded: did_load=123; source: \"Rect120x60.qml\" }"), TEST_FILE("")); + component.setData(QByteArray( + "import QtQuick 1.0\n" + "Loader {\n" + " property int onItemChangedCount: 0\n" + " property int onSourceChangedCount: 0\n" + " property int onStatusChangedCount: 0\n" + " property int onProgressChangedCount: 0\n" + " property int onLoadedCount: 0\n") + + sourceDefinition.toUtf8() + + QByteArray( + " onItemChanged: onItemChangedCount += 1\n" + " onSourceChanged: onSourceChangedCount += 1\n" + " onStatusChanged: onStatusChangedCount += 1\n" + " onProgressChanged: onProgressChangedCount += 1\n" + " onLoaded: onLoadedCount += 1\n" + "}") + , TEST_FILE("")); + QDeclarativeLoader *loader = qobject_cast<QDeclarativeLoader*>(component.create()); QVERIFY(loader != 0); - QVERIFY(loader->item()); - QVERIFY(loader->source() == QUrl::fromLocalFile(SRCDIR "/data/Rect120x60.qml")); + QCOMPARE(loader->item() == 0, error); + QCOMPARE(loader->source(), sourceUrl); QCOMPARE(loader->progress(), 1.0); - QCOMPARE(loader->status(), QDeclarativeLoader::Ready); - QCOMPARE(loader->property("did_load").toInt(), 123); - QCOMPARE(static_cast<QGraphicsItem*>(loader)->children().count(), 1); - delete loader; -} + QCOMPARE(loader->status(), error ? QDeclarativeLoader::Error : QDeclarativeLoader::Ready); + QCOMPARE(static_cast<QGraphicsItem*>(loader)->children().count(), error ? 0: 1); -void tst_QDeclarativeLoader::component() -{ - QDeclarativeComponent component(&engine, TEST_FILE("/SetSourceComponent.qml")); - QDeclarativeItem *item = qobject_cast<QDeclarativeItem*>(component.create()); - QVERIFY(item); + if (!error) { + QDeclarativeComponent *c = qobject_cast<QDeclarativeComponent*>(loader->QGraphicsObject::children().at(0)); + QVERIFY(c); + QCOMPARE(loader->sourceComponent(), c); + } - QDeclarativeLoader *loader = qobject_cast<QDeclarativeLoader*>(item->QGraphicsObject::children().at(1)); - QVERIFY(loader); - QVERIFY(loader->item()); - QCOMPARE(loader->progress(), 1.0); - QCOMPARE(loader->status(), QDeclarativeLoader::Ready); - QCOMPARE(static_cast<QGraphicsItem*>(loader)->children().count(), 1); + QCOMPARE(loader->property("onSourceChangedCount").toInt(), 1); + QCOMPARE(loader->property("onStatusChangedCount").toInt(), 1); + QCOMPARE(loader->property("onProgressChangedCount").toInt(), 1); - QDeclarativeComponent *c = qobject_cast<QDeclarativeComponent*>(item->QGraphicsObject::children().at(0)); - QVERIFY(c); - QCOMPARE(loader->sourceComponent(), c); + QCOMPARE(loader->property("onItemChangedCount").toInt(), error ? 0 : 1); + QCOMPARE(loader->property("onLoadedCount").toInt(), error ? 0 : 1); - delete item; + delete loader; } -void tst_QDeclarativeLoader::invalidUrl() +void tst_QDeclarativeLoader::sourceOrComponent_data() { - QTest::ignoreMessage(QtWarningMsg, QString(QUrl::fromLocalFile(SRCDIR "/data/IDontExist.qml").toString() + ": File not found").toUtf8().constData()); + QTest::addColumn<QString>("sourceDefinition"); + QTest::addColumn<QUrl>("sourceUrl"); + QTest::addColumn<QString>("errorString"); - QDeclarativeComponent component(&engine); - component.setData(QByteArray("import QtQuick 1.0\nLoader { source: \"IDontExist.qml\" }"), TEST_FILE("")); - QDeclarativeLoader *loader = qobject_cast<QDeclarativeLoader*>(component.create()); - QVERIFY(loader != 0); - QVERIFY(loader->item() == 0); - QCOMPARE(loader->progress(), 1.0); - QCOMPARE(loader->status(), QDeclarativeLoader::Error); - QCOMPARE(static_cast<QGraphicsItem*>(loader)->children().count(), 0); + QTest::newRow("source") << "source: 'Rect120x60.qml'\n" << QUrl::fromLocalFile(SRCDIR "/data/Rect120x60.qml") << ""; + QTest::newRow("sourceComponent") << "Component { id: comp; Rectangle { width: 100; height: 50 } }\n sourceComponent: comp\n" << QUrl() << ""; - delete loader; + QTest::newRow("invalid source") << "source: 'IDontExist.qml'\n" << QUrl::fromLocalFile(SRCDIR "/data/IDontExist.qml") + << QString(QUrl::fromLocalFile(SRCDIR "/data/IDontExist.qml").toString() + ": File not found"); } void tst_QDeclarativeLoader::clear() @@ -446,7 +463,7 @@ void tst_QDeclarativeLoader::networkRequestUrl() server.serveDirectory(SRCDIR "/data"); QDeclarativeComponent component(&engine); - component.setData(QByteArray("import QtQuick 1.0\nLoader { property int did_load : 0; source: \"http://127.0.0.1:14450/Rect120x60.qml\"; onLoaded: did_load=123 }"), QUrl::fromLocalFile(SRCDIR "/dummy.qml")); + component.setData(QByteArray("import QtQuick 1.0\nLoader { property int signalCount : 0; source: \"http://127.0.0.1:14450/Rect120x60.qml\"; onLoaded: signalCount += 1 }"), QUrl::fromLocalFile(SRCDIR "/dummy.qml")); if (component.isError()) qDebug() << component.errors(); QDeclarativeLoader *loader = qobject_cast<QDeclarativeLoader*>(component.create()); @@ -456,7 +473,7 @@ void tst_QDeclarativeLoader::networkRequestUrl() QVERIFY(loader->item()); QCOMPARE(loader->progress(), 1.0); - QCOMPARE(loader->property("did_load").toInt(), 123); + QCOMPARE(loader->property("signalCount").toInt(), 1); QCOMPARE(static_cast<QGraphicsItem*>(loader)->children().count(), 1); delete loader; @@ -576,6 +593,45 @@ void tst_QDeclarativeLoader::creationContext() delete o; } +void tst_QDeclarativeLoader::QTBUG_16928() +{ + QDeclarativeComponent component(&engine, TEST_FILE("QTBUG_16928.qml")); + QDeclarativeItem *item = qobject_cast<QDeclarativeItem*>(component.create()); + QVERIFY(item); + + QCOMPARE(item->width(), 250.); + QCOMPARE(item->height(), 250.); + + delete item; +} + +void tst_QDeclarativeLoader::implicitSize() +{ + QDeclarativeComponent component(&engine, TEST_FILE("implicitSize.qml")); + QDeclarativeItem *item = qobject_cast<QDeclarativeItem*>(component.create()); + QVERIFY(item); + + QCOMPARE(item->width(), 150.); + QCOMPARE(item->height(), 150.); + + QCOMPARE(item->property("implHeight").toReal(), 100.); + QCOMPARE(item->property("implWidth").toReal(), 100.); + + delete item; +} + +void tst_QDeclarativeLoader::QTBUG_17114() +{ + QDeclarativeComponent component(&engine, TEST_FILE("QTBUG_17114.qml")); + QDeclarativeItem *item = qobject_cast<QDeclarativeItem*>(component.create()); + QVERIFY(item); + + QCOMPARE(item->property("loaderWidth").toReal(), 32.); + QCOMPARE(item->property("loaderHeight").toReal(), 32.); + + delete item; +} + QTEST_MAIN(tst_QDeclarativeLoader) #include "tst_qdeclarativeloader.moc" diff --git a/tests/auto/declarative/qdeclarativemousearea/data/pressedOrdering.qml b/tests/auto/declarative/qdeclarativemousearea/data/pressedOrdering.qml new file mode 100644 index 0000000..4a80e83 --- /dev/null +++ b/tests/auto/declarative/qdeclarativemousearea/data/pressedOrdering.qml @@ -0,0 +1,28 @@ +import QtQuick 1.0 + +Item { + id: root + property string value: "base" + + MouseArea { + id: mouseArea + width: 200; height: 200 + onClicked: toggleState.state = "toggled" + } + + StateGroup { + states: State { + name: "pressed" + when: mouseArea.pressed + PropertyChanges { target: root; value: "pressed" } + } + } + + StateGroup { + id: toggleState + states: State { + name: "toggled" + PropertyChanges { target: root; value: "toggled" } + } + } +} diff --git a/tests/auto/declarative/qdeclarativemousearea/tst_qdeclarativemousearea.cpp b/tests/auto/declarative/qdeclarativemousearea/tst_qdeclarativemousearea.cpp index 9d7cc05..845d6bb 100644 --- a/tests/auto/declarative/qdeclarativemousearea/tst_qdeclarativemousearea.cpp +++ b/tests/auto/declarative/qdeclarativemousearea/tst_qdeclarativemousearea.cpp @@ -64,6 +64,7 @@ private slots: void onMousePressRejected(); void doubleClick(); void clickTwice(); + void pressedOrdering(); private: QDeclarativeView *createView(); @@ -477,6 +478,40 @@ void tst_QDeclarativeMouseArea::clickTwice() QCOMPARE(canvas->rootObject()->property("clicked").toInt(), 2); } +void tst_QDeclarativeMouseArea::pressedOrdering() +{ + QDeclarativeView *canvas = createView(); + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/pressedOrdering.qml")); + canvas->show(); + canvas->setFocus(); + QVERIFY(canvas->rootObject() != 0); + + QCOMPARE(canvas->rootObject()->property("value").toString(), QLatin1String("base")); + + QGraphicsScene *scene = canvas->scene(); + QGraphicsSceneMouseEvent pressEvent(QEvent::GraphicsSceneMousePress); + pressEvent.setScenePos(QPointF(100, 100)); + pressEvent.setButton(Qt::LeftButton); + pressEvent.setButtons(Qt::LeftButton); + QApplication::sendEvent(scene, &pressEvent); + + QCOMPARE(canvas->rootObject()->property("value").toString(), QLatin1String("pressed")); + + QGraphicsSceneMouseEvent releaseEvent(QEvent::GraphicsSceneMouseRelease); + releaseEvent.setScenePos(QPointF(100, 100)); + releaseEvent.setButton(Qt::LeftButton); + releaseEvent.setButtons(Qt::LeftButton); + QApplication::sendEvent(scene, &releaseEvent); + + QCOMPARE(canvas->rootObject()->property("value").toString(), QLatin1String("toggled")); + + QApplication::sendEvent(scene, &pressEvent); + + QCOMPARE(canvas->rootObject()->property("value").toString(), QLatin1String("pressed")); + + delete canvas; +} + QTEST_MAIN(tst_QDeclarativeMouseArea) #include "tst_qdeclarativemousearea.moc" diff --git a/tests/auto/declarative/qdeclarativepincharea/data/pinchproperties.qml b/tests/auto/declarative/qdeclarativepincharea/data/pinchproperties.qml new file mode 100644 index 0000000..0b59d9d --- /dev/null +++ b/tests/auto/declarative/qdeclarativepincharea/data/pinchproperties.qml @@ -0,0 +1,46 @@ +import QtQuick 1.1 +Rectangle { + id: whiteRect + property variant center + property real scale + width: 240; height: 320 + color: "white" + Rectangle { + id: blackRect + objectName: "blackrect" + color: "black" + y: 50 + x: 50 + width: 100 + height: 100 + opacity: (whiteRect.width-blackRect.x+whiteRect.height-blackRect.y-199)/200 + Text { text: blackRect.opacity} + PinchArea { + id: pincharea + objectName: "pincharea" + anchors.fill: parent + pinch.target: blackRect + pinch.dragAxis: Drag.XandYAxis + pinch.minimumX: 0 + pinch.maximumX: whiteRect.width-blackRect.width + pinch.minimumY: 0 + pinch.maximumY: whiteRect.height-blackRect.height + pinch.minimumScale: 1.0 + pinch.maximumScale: 2.0 + pinch.minimumRotation: 0.0 + pinch.maximumRotation: 90.0 + onPinchStarted: { + whiteRect.center = pinch.center + whiteRect.scale = pinch.scale + } + onPinchUpdated: { + whiteRect.center = pinch.center + whiteRect.scale = pinch.scale + } + onPinchFinished: { + whiteRect.center = pinch.center + whiteRect.scale = pinch.scale + } + } + } + } diff --git a/tests/auto/declarative/qdeclarativepincharea/qdeclarativepincharea.pro b/tests/auto/declarative/qdeclarativepincharea/qdeclarativepincharea.pro new file mode 100644 index 0000000..2c13644 --- /dev/null +++ b/tests/auto/declarative/qdeclarativepincharea/qdeclarativepincharea.pro @@ -0,0 +1,16 @@ +load(qttest_p4) +contains(QT_CONFIG,declarative): QT += declarative gui +macx:CONFIG -= app_bundle + +SOURCES += tst_qdeclarativepincharea.cpp + +symbian: { + importFiles.sources = data + importFiles.path = . + DEPLOYMENT = importFiles +} else { + DEFINES += SRCDIR=\\\"$$PWD\\\" +} + +CONFIG += parallel_test + diff --git a/tests/auto/declarative/qdeclarativepincharea/tst_qdeclarativepincharea.cpp b/tests/auto/declarative/qdeclarativepincharea/tst_qdeclarativepincharea.cpp new file mode 100644 index 0000000..f175033 --- /dev/null +++ b/tests/auto/declarative/qdeclarativepincharea/tst_qdeclarativepincharea.cpp @@ -0,0 +1,315 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest/QtTest> +#include <QtTest/QSignalSpy> +#include <private/qdeclarativepincharea_p.h> +#include <private/qdeclarativerectangle_p.h> +#include <QtDeclarative/qdeclarativeview.h> +#include <QtDeclarative/qdeclarativecontext.h> + +#ifdef Q_OS_SYMBIAN +// In Symbian OS test data is located in applications private dir +#define SRCDIR "." +#endif + +class tst_QDeclarativePinchArea: public QObject +{ + Q_OBJECT +private slots: + void pinchProperties(); + void scale(); + void pan(); + +private: + QDeclarativeView *createView(); +}; + +void tst_QDeclarativePinchArea::pinchProperties() +{ + QDeclarativeView *canvas = createView(); + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/pinchproperties.qml")); + canvas->show(); + canvas->setFocus(); + QVERIFY(canvas->rootObject() != 0); + + QDeclarativePinchArea *pinchArea = canvas->rootObject()->findChild<QDeclarativePinchArea*>("pincharea"); + QDeclarativePinch *pinch = pinchArea->pinch(); + QVERIFY(pinchArea != 0); + QVERIFY(pinch != 0); + + // target + QDeclarativeItem *blackRect = canvas->rootObject()->findChild<QDeclarativeItem*>("blackrect"); + QVERIFY(blackRect != 0); + QVERIFY(blackRect == pinch->target()); + QDeclarativeItem *rootItem = qobject_cast<QDeclarativeItem*>(canvas->rootObject()); + QVERIFY(rootItem != 0); + QSignalSpy targetSpy(pinch, SIGNAL(targetChanged())); + pinch->setTarget(rootItem); + QCOMPARE(targetSpy.count(),1); + pinch->setTarget(rootItem); + QCOMPARE(targetSpy.count(),1); + + // axis + QCOMPARE(pinch->axis(), QDeclarativePinch::XandYAxis); + QSignalSpy axisSpy(pinch, SIGNAL(dragAxisChanged())); + pinch->setAxis(QDeclarativePinch::XAxis); + QCOMPARE(pinch->axis(), QDeclarativePinch::XAxis); + QCOMPARE(axisSpy.count(),1); + pinch->setAxis(QDeclarativePinch::XAxis); + QCOMPARE(axisSpy.count(),1); + + // minimum and maximum drag properties + QSignalSpy xminSpy(pinch, SIGNAL(minimumXChanged())); + QSignalSpy xmaxSpy(pinch, SIGNAL(maximumXChanged())); + QSignalSpy yminSpy(pinch, SIGNAL(minimumYChanged())); + QSignalSpy ymaxSpy(pinch, SIGNAL(maximumYChanged())); + + QCOMPARE(pinch->xmin(), 0.0); + QCOMPARE(pinch->xmax(), rootItem->width()-blackRect->width()); + QCOMPARE(pinch->ymin(), 0.0); + QCOMPARE(pinch->ymax(), rootItem->height()-blackRect->height()); + + pinch->setXmin(10); + pinch->setXmax(10); + pinch->setYmin(10); + pinch->setYmax(10); + + QCOMPARE(pinch->xmin(), 10.0); + QCOMPARE(pinch->xmax(), 10.0); + QCOMPARE(pinch->ymin(), 10.0); + QCOMPARE(pinch->ymax(), 10.0); + + QCOMPARE(xminSpy.count(),1); + QCOMPARE(xmaxSpy.count(),1); + QCOMPARE(yminSpy.count(),1); + QCOMPARE(ymaxSpy.count(),1); + + pinch->setXmin(10); + pinch->setXmax(10); + pinch->setYmin(10); + pinch->setYmax(10); + + QCOMPARE(xminSpy.count(),1); + QCOMPARE(xmaxSpy.count(),1); + QCOMPARE(yminSpy.count(),1); + QCOMPARE(ymaxSpy.count(),1); + + // minimum and maximum scale properties + QSignalSpy scaleMinSpy(pinch, SIGNAL(minimumScaleChanged())); + QSignalSpy scaleMaxSpy(pinch, SIGNAL(maximumScaleChanged())); + + QCOMPARE(pinch->minimumScale(), 1.0); + QCOMPARE(pinch->maximumScale(), 2.0); + + pinch->setMinimumScale(0.5); + pinch->setMaximumScale(1.5); + + QCOMPARE(pinch->minimumScale(), 0.5); + QCOMPARE(pinch->maximumScale(), 1.5); + + QCOMPARE(scaleMinSpy.count(),1); + QCOMPARE(scaleMaxSpy.count(),1); + + pinch->setMinimumScale(0.5); + pinch->setMaximumScale(1.5); + + QCOMPARE(scaleMinSpy.count(),1); + QCOMPARE(scaleMaxSpy.count(),1); + + // minimum and maximum rotation properties + QSignalSpy rotMinSpy(pinch, SIGNAL(minimumRotationChanged())); + QSignalSpy rotMaxSpy(pinch, SIGNAL(maximumRotationChanged())); + + QCOMPARE(pinch->minimumRotation(), 0.0); + QCOMPARE(pinch->maximumRotation(), 90.0); + + pinch->setMinimumRotation(-90.0); + pinch->setMaximumRotation(45.0); + + QCOMPARE(pinch->minimumRotation(), -90.0); + QCOMPARE(pinch->maximumRotation(), 45.0); + + QCOMPARE(rotMinSpy.count(),1); + QCOMPARE(rotMaxSpy.count(),1); + + pinch->setMinimumRotation(-90.0); + pinch->setMaximumRotation(45.0); + + QCOMPARE(rotMinSpy.count(),1); + QCOMPARE(rotMaxSpy.count(),1); + + delete canvas; +} + +QTouchEvent::TouchPoint makeTouchPoint(int id, QPoint p, QGraphicsView *v, QGraphicsItem *i) +{ + QTouchEvent::TouchPoint touchPoint(id); + touchPoint.setPos(i->mapFromScene(p)); + touchPoint.setScreenPos(v->mapToGlobal(p)); + touchPoint.setScenePos(p); + return touchPoint; +} + +void tst_QDeclarativePinchArea::scale() +{ + QDeclarativeView *canvas = createView(); + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/pinchproperties.qml")); + canvas->show(); + canvas->setFocus(); + QTest::qWaitForWindowShown(canvas); + QVERIFY(canvas->rootObject() != 0); + qApp->processEvents(); + + QDeclarativePinchArea *pinchArea = canvas->rootObject()->findChild<QDeclarativePinchArea*>("pincharea"); + QDeclarativePinch *pinch = pinchArea->pinch(); + QVERIFY(pinchArea != 0); + QVERIFY(pinch != 0); + + QDeclarativeItem *root = qobject_cast<QDeclarativeItem*>(canvas->rootObject()); + QVERIFY(root != 0); + + // target + QDeclarativeItem *blackRect = canvas->rootObject()->findChild<QDeclarativeItem*>("blackrect"); + QVERIFY(blackRect != 0); + + QWidget *vp = canvas->viewport(); + + QPoint p1(80, 80); + QPoint p2(100, 100); + + QTest::touchEvent(vp).press(0, p1); + QTest::touchEvent(vp).stationary(0).press(1, p2); + p1 -= QPoint(10,10); + p2 += QPoint(10,10); + QTest::touchEvent(vp).move(0, p1).move(1, p2); + + QCOMPARE(root->property("scale").toReal(), 1.0); + + p1 -= QPoint(10,10); + p2 += QPoint(10,10); + QTest::touchEvent(vp).move(0, p1).move(1, p2); + + QCOMPARE(root->property("scale").toReal(), 1.5); + QCOMPARE(root->property("center").toPointF(), QPointF(40, 40)); // blackrect is at 50,50 + QCOMPARE(blackRect->scale(), 1.5); + + // scale beyond bound + p1 -= QPoint(50,50); + p2 += QPoint(50,50); + QTest::touchEvent(vp).move(0, p1).move(1, p2); + + QCOMPARE(blackRect->scale(), 2.0); + + QTest::touchEvent(vp).release(0, p1).release(1, p2); + + delete canvas; +} + +void tst_QDeclarativePinchArea::pan() +{ + QDeclarativeView *canvas = createView(); + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/pinchproperties.qml")); + canvas->show(); + canvas->setFocus(); + QTest::qWaitForWindowShown(canvas); + QVERIFY(canvas->rootObject() != 0); + qApp->processEvents(); + + QDeclarativePinchArea *pinchArea = canvas->rootObject()->findChild<QDeclarativePinchArea*>("pincharea"); + QDeclarativePinch *pinch = pinchArea->pinch(); + QVERIFY(pinchArea != 0); + QVERIFY(pinch != 0); + + QDeclarativeItem *root = qobject_cast<QDeclarativeItem*>(canvas->rootObject()); + QVERIFY(root != 0); + + // target + QDeclarativeItem *blackRect = canvas->rootObject()->findChild<QDeclarativeItem*>("blackrect"); + QVERIFY(blackRect != 0); + + QWidget *vp = canvas->viewport(); + + QPoint p1(80, 80); + QPoint p2(100, 100); + + QTest::touchEvent(vp).press(0, p1); + QTest::touchEvent(vp).stationary(0).press(1, p2); + p1 += QPoint(10,10); + p2 += QPoint(10,10); + QTest::touchEvent(vp).move(0, p1).move(1, p2); + + QCOMPARE(root->property("scale").toReal(), 1.0); + + p1 += QPoint(10,10); + p2 += QPoint(10,10); + QTest::touchEvent(vp).move(0, p1).move(1, p2); + + QCOMPARE(root->property("center").toPointF(), QPointF(60, 60)); // blackrect is at 50,50 + + QCOMPARE(blackRect->x(), 60.0); + QCOMPARE(blackRect->y(), 60.0); + + // pan x beyond bound + p1 += QPoint(100,100); + p2 += QPoint(100,100); + QTest::touchEvent(vp).move(0, p1).move(1, p2); + + QCOMPARE(blackRect->x(), 140.0); + QCOMPARE(blackRect->y(), 160.0); + + QTest::touchEvent(vp).release(0, p1).release(1, p2); + + delete canvas; +} + +QDeclarativeView *tst_QDeclarativePinchArea::createView() +{ + QDeclarativeView *canvas = new QDeclarativeView(0); + canvas->viewport()->setAttribute(Qt::WA_AcceptTouchEvents); + canvas->setFixedSize(240,320); + + return canvas; +} + +QTEST_MAIN(tst_QDeclarativePinchArea) + +#include "tst_qdeclarativepincharea.moc" diff --git a/tests/auto/declarative/qdeclarativepixmapcache/tst_qdeclarativepixmapcache.cpp b/tests/auto/declarative/qdeclarativepixmapcache/tst_qdeclarativepixmapcache.cpp index 76fe2dc..11595a9 100644 --- a/tests/auto/declarative/qdeclarativepixmapcache/tst_qdeclarativepixmapcache.cpp +++ b/tests/auto/declarative/qdeclarativepixmapcache/tst_qdeclarativepixmapcache.cpp @@ -47,6 +47,11 @@ #include "testhttpserver.h" #include "../../../shared/util.h" +#ifndef QT_NO_CONCURRENT +#include <qtconcurrentrun.h> +#include <qfuture.h> +#endif + // These don't let normal people run tests! //#include "../network-settings.h" @@ -74,7 +79,10 @@ private slots: void massive(); void cancelcrash(); void shrinkcache(); +#ifndef QT_NO_CONCURRENT void networkCrash(); +#endif + private: QDeclarativeEngine engine; QUrl thisfile; @@ -354,6 +362,8 @@ void tst_qdeclarativepixmapcache::shrinkcache() } } +#ifndef QT_NO_CONCURRENT + void createNetworkServer() { QEventLoop eventLoop; @@ -378,6 +388,8 @@ void tst_qdeclarativepixmapcache::networkCrash() future.cancel(); } +#endif + QTEST_MAIN(tst_qdeclarativepixmapcache) #include "tst_qdeclarativepixmapcache.moc" diff --git a/tests/auto/declarative/qdeclarativepositioners/data/flow-testimplicitsize.qml b/tests/auto/declarative/qdeclarativepositioners/data/flow-testimplicitsize.qml index 51c8134..ee4e104 100644 --- a/tests/auto/declarative/qdeclarativepositioners/data/flow-testimplicitsize.qml +++ b/tests/auto/declarative/qdeclarativepositioners/data/flow-testimplicitsize.qml @@ -1,16 +1,19 @@ -import QtQuick 1.0 +import QtQuick 1.1 Rectangle { width: 300; height: 200; - property bool leftToRight: false + property int flowLayout: 1 Flow { objectName: "flow" - flow: leftToRight ? Flow.LeftToRight : Flow.TopToBottom + layoutDirection: (flowLayout == 2) ? Qt.RightToLeft : Qt.LeftToRight + flow: (flowLayout == 1) ? Flow.TopToBottom : Flow.LeftToRight; + spacing: 20 anchors.horizontalCenter: parent.horizontalCenter Rectangle { color: "red"; width: 100; height: 50 } Rectangle { color: "blue"; width: 100; height: 50 } } } + diff --git a/tests/auto/declarative/qdeclarativepositioners/data/flowtest-toptobottom.qml b/tests/auto/declarative/qdeclarativepositioners/data/flowtest-toptobottom.qml new file mode 100644 index 0000000..ec1d666 --- /dev/null +++ b/tests/auto/declarative/qdeclarativepositioners/data/flowtest-toptobottom.qml @@ -0,0 +1,44 @@ +import QtQuick 1.1 + +Item { + height: 90 + width: 480 + property bool testRightToLeft: false + + Flow { + objectName: "flow" + height: parent.height + layoutDirection: testRightToLeft ? Qt.RightToLeft : Qt.LeftToRight + flow: Flow.TopToBottom + Rectangle { + objectName: "one" + color: "red" + width: 50 + height: 50 + } + Rectangle { + objectName: "two" + color: "green" + width: 20 + height: 50 + } + Rectangle { + objectName: "three" + color: "blue" + width: 50 + height: 20 + } + Rectangle { + objectName: "four" + color: "cyan" + width: 50 + height: 50 + } + Rectangle { + objectName: "five" + color: "magenta" + width: 10 + height: 10 + } + } +} diff --git a/tests/auto/declarative/qdeclarativepositioners/data/flowtest.qml b/tests/auto/declarative/qdeclarativepositioners/data/flowtest.qml index 2810234..7c124a3 100644 --- a/tests/auto/declarative/qdeclarativepositioners/data/flowtest.qml +++ b/tests/auto/declarative/qdeclarativepositioners/data/flowtest.qml @@ -1,11 +1,14 @@ -import QtQuick 1.0 +import QtQuick 1.1 Item { width: 90 height: 480 + property bool testRightToLeft: false + Flow { objectName: "flow" width: parent.width + layoutDirection: testRightToLeft ? Qt.RightToLeft : Qt.LeftToRight Rectangle { objectName: "one" color: "red" diff --git a/tests/auto/declarative/qdeclarativepositioners/data/grid-animated.qml b/tests/auto/declarative/qdeclarativepositioners/data/grid-animated.qml index e13f078..3dcbed1 100644 --- a/tests/auto/declarative/qdeclarativepositioners/data/grid-animated.qml +++ b/tests/auto/declarative/qdeclarativepositioners/data/grid-animated.qml @@ -1,11 +1,14 @@ -import QtQuick 1.0 +import QtQuick 1.1 Item { width: 640 height: 480 + property bool testRightToLeft: true + Grid { objectName: "grid" columns: 3 + layoutDirection: testRightToLeft ? Qt.RightToLeft : Qt.LeftToRight add: Transition { NumberAnimation { properties: "x,y"; diff --git a/tests/auto/declarative/qdeclarativepositioners/data/grid-righttoleft.qml b/tests/auto/declarative/qdeclarativepositioners/data/grid-righttoleft.qml new file mode 100644 index 0000000..0ec1f37 --- /dev/null +++ b/tests/auto/declarative/qdeclarativepositioners/data/grid-righttoleft.qml @@ -0,0 +1,41 @@ +import QtQuick 1.1 + +Item { + width: 640 + height: 480 + Grid { + objectName: "grid" + columns: 3 + layoutDirection: Qt.RightToLeft + Rectangle { + objectName: "one" + color: "red" + width: 50 + height: 50 + } + Rectangle { + objectName: "two" + color: "green" + width: 20 + height: 50 + } + Rectangle { + objectName: "three" + color: "blue" + width: 50 + height: 20 + } + Rectangle { + objectName: "four" + color: "cyan" + width: 50 + height: 50 + } + Rectangle { + objectName: "five" + color: "magenta" + width: 10 + height: 10 + } + } +} diff --git a/tests/auto/declarative/qdeclarativepositioners/data/horizontal-animated.qml b/tests/auto/declarative/qdeclarativepositioners/data/horizontal-animated.qml index 5b064cd..3c95f53 100644 --- a/tests/auto/declarative/qdeclarativepositioners/data/horizontal-animated.qml +++ b/tests/auto/declarative/qdeclarativepositioners/data/horizontal-animated.qml @@ -1,10 +1,13 @@ -import QtQuick 1.0 +import QtQuick 1.1 Item { width: 640 height: 480 + property bool testRightToLeft: false + Row { objectName: "row" + layoutDirection: testRightToLeft ? Qt.RightToLeft : Qt.LeftToRight add: Transition { NumberAnimation { properties: "x"; diff --git a/tests/auto/declarative/qdeclarativepositioners/data/horizontal-spacing.qml b/tests/auto/declarative/qdeclarativepositioners/data/horizontal-spacing.qml index 2b46bca..64bedb0 100644 --- a/tests/auto/declarative/qdeclarativepositioners/data/horizontal-spacing.qml +++ b/tests/auto/declarative/qdeclarativepositioners/data/horizontal-spacing.qml @@ -1,11 +1,14 @@ -import QtQuick 1.0 +import QtQuick 1.1 Item { width: 640 height: 480 + property bool testRightToLeft: false + Row { objectName: "row" spacing: 10 + layoutDirection: testRightToLeft ? Qt.RightToLeft : Qt.LeftToRight Rectangle { objectName: "one" color: "red" diff --git a/tests/auto/declarative/qdeclarativepositioners/data/horizontal.qml b/tests/auto/declarative/qdeclarativepositioners/data/horizontal.qml index 919cecc..e1a9652 100644 --- a/tests/auto/declarative/qdeclarativepositioners/data/horizontal.qml +++ b/tests/auto/declarative/qdeclarativepositioners/data/horizontal.qml @@ -1,10 +1,13 @@ -import QtQuick 1.0 +import QtQuick 1.1 Item { width: 640 height: 480 + property bool testRightToLeft: false + Row { objectName: "row" + layoutDirection: testRightToLeft ? Qt.RightToLeft : Qt.LeftToRight Rectangle { objectName: "one" color: "red" diff --git a/tests/auto/declarative/qdeclarativepositioners/data/repeatertest.qml b/tests/auto/declarative/qdeclarativepositioners/data/repeatertest.qml index 1cba598..f93ce67 100644 --- a/tests/auto/declarative/qdeclarativepositioners/data/repeatertest.qml +++ b/tests/auto/declarative/qdeclarativepositioners/data/repeatertest.qml @@ -12,9 +12,27 @@ Item { height: 50 z: {if(index == 0){2;}else if(index == 1){1;} else{3;}} objectName: {if(index == 0){"one";}else if(index == 1){"two";} else{"three";}} - } } } } + + //This crashed once (QTBUG-16959) because the repeater ended up on the end of the list + //If this grid just instantiates without crashing, then it has not regressed. + Grid { + id: grid + rows: 2 + flow: Grid.TopToBottom + + Repeater { + model: 13 + Rectangle { + color: "goldenrod" + width: 100 + height: 100 + radius: 10 + border.width: 1 + } + } + } } diff --git a/tests/auto/declarative/qdeclarativepositioners/tst_qdeclarativepositioners.cpp b/tests/auto/declarative/qdeclarativepositioners/tst_qdeclarativepositioners.cpp index 93611cc..40e533d 100644 --- a/tests/auto/declarative/qdeclarativepositioners/tst_qdeclarativepositioners.cpp +++ b/tests/auto/declarative/qdeclarativepositioners/tst_qdeclarativepositioners.cpp @@ -62,23 +62,33 @@ public: private slots: void test_horizontal(); + void test_horizontal_rtl(); void test_horizontal_spacing(); + void test_horizontal_spacing_rightToLeft(); void test_horizontal_animated(); + void test_horizontal_animated_rightToLeft(); void test_vertical(); void test_vertical_spacing(); void test_vertical_animated(); void test_grid(); void test_grid_topToBottom(); + void test_grid_rightToLeft(); void test_grid_spacing(); void test_grid_animated(); + void test_grid_animated_rightToLeft(); void test_grid_zero_columns(); void test_propertychanges(); void test_repeater(); void test_flow(); + void test_flow_rightToLeft(); + void test_flow_topToBottom(); void test_flow_resize(); + void test_flow_resize_rightToLeft(); void test_flow_implicit_resize(); void test_conflictinganchors(); void test_vertical_qgraphicswidget(); + void testQtQuick11Attributes(); + void testQtQuick11Attributes_data(); private: QDeclarativeView *createView(const QString &filename); }; @@ -91,6 +101,8 @@ void tst_QDeclarativePositioners::test_horizontal() { QDeclarativeView *canvas = createView(SRCDIR "/data/horizontal.qml"); + canvas->rootObject()->setProperty("testRightToLeft", false); + QDeclarativeRectangle *one = canvas->rootObject()->findChild<QDeclarativeRectangle*>("one"); QVERIFY(one != 0); @@ -114,10 +126,41 @@ void tst_QDeclarativePositioners::test_horizontal() delete canvas; } +void tst_QDeclarativePositioners::test_horizontal_rtl() +{ + QDeclarativeView *canvas = createView(SRCDIR "/data/horizontal.qml"); + + canvas->rootObject()->setProperty("testRightToLeft", true); + + QDeclarativeRectangle *one = canvas->rootObject()->findChild<QDeclarativeRectangle*>("one"); + QVERIFY(one != 0); + + QDeclarativeRectangle *two = canvas->rootObject()->findChild<QDeclarativeRectangle*>("two"); + QVERIFY(two != 0); + + QDeclarativeRectangle *three = canvas->rootObject()->findChild<QDeclarativeRectangle*>("three"); + QVERIFY(three != 0); + + QCOMPARE(one->x(), 60.0); + QCOMPARE(one->y(), 0.0); + QCOMPARE(two->x(), 40.0); + QCOMPARE(two->y(), 0.0); + QCOMPARE(three->x(), 0.0); + QCOMPARE(three->y(), 0.0); + + QDeclarativeItem *row = canvas->rootObject()->findChild<QDeclarativeItem*>("row"); + QCOMPARE(row->width(), 110.0); + QCOMPARE(row->height(), 50.0); + + delete canvas; +} + void tst_QDeclarativePositioners::test_horizontal_spacing() { QDeclarativeView *canvas = createView(SRCDIR "/data/horizontal-spacing.qml"); + canvas->rootObject()->setProperty("testRightToLeft", false); + QDeclarativeRectangle *one = canvas->rootObject()->findChild<QDeclarativeRectangle*>("one"); QVERIFY(one != 0); @@ -141,10 +184,41 @@ void tst_QDeclarativePositioners::test_horizontal_spacing() delete canvas; } +void tst_QDeclarativePositioners::test_horizontal_spacing_rightToLeft() +{ + QDeclarativeView *canvas = createView(SRCDIR "/data/horizontal-spacing.qml"); + + canvas->rootObject()->setProperty("testRightToLeft", true); + + QDeclarativeRectangle *one = canvas->rootObject()->findChild<QDeclarativeRectangle*>("one"); + QVERIFY(one != 0); + + QDeclarativeRectangle *two = canvas->rootObject()->findChild<QDeclarativeRectangle*>("two"); + QVERIFY(two != 0); + + QDeclarativeRectangle *three = canvas->rootObject()->findChild<QDeclarativeRectangle*>("three"); + QVERIFY(three != 0); + + QCOMPARE(one->x(), 80.0); + QCOMPARE(one->y(), 0.0); + QCOMPARE(two->x(), 50.0); + QCOMPARE(two->y(), 0.0); + QCOMPARE(three->x(), 00.0); + QCOMPARE(three->y(), 0.0); + + QDeclarativeItem *row = canvas->rootObject()->findChild<QDeclarativeItem*>("row"); + QCOMPARE(row->width(), 130.0); + QCOMPARE(row->height(), 50.0); + + delete canvas; +} + void tst_QDeclarativePositioners::test_horizontal_animated() { QDeclarativeView *canvas = createView(SRCDIR "/data/horizontal-animated.qml"); + canvas->rootObject()->setProperty("testRightToLeft", false); + QDeclarativeRectangle *one = canvas->rootObject()->findChild<QDeclarativeRectangle*>("one"); QVERIFY(one != 0); @@ -193,6 +267,60 @@ void tst_QDeclarativePositioners::test_horizontal_animated() delete canvas; } +void tst_QDeclarativePositioners::test_horizontal_animated_rightToLeft() +{ + QDeclarativeView *canvas = createView(SRCDIR "/data/horizontal-animated.qml"); + + canvas->rootObject()->setProperty("testRightToLeft", true); + + QDeclarativeRectangle *one = canvas->rootObject()->findChild<QDeclarativeRectangle*>("one"); + QVERIFY(one != 0); + + QDeclarativeRectangle *two = canvas->rootObject()->findChild<QDeclarativeRectangle*>("two"); + QVERIFY(two != 0); + + QDeclarativeRectangle *three = canvas->rootObject()->findChild<QDeclarativeRectangle*>("three"); + QVERIFY(three != 0); + + //Note that they animate in + QCOMPARE(one->x(), -100.0); + QCOMPARE(two->x(), -100.0); + QCOMPARE(three->x(), -100.0); + + QDeclarativeItem *row = canvas->rootObject()->findChild<QDeclarativeItem*>("row"); + QVERIFY(row); + QCOMPARE(row->width(), 100.0); + QCOMPARE(row->height(), 50.0); + + //QTRY_COMPARE used instead of waiting for the expected time of animation completion + //Note that this means the duration of the animation is NOT tested + + QTRY_COMPARE(one->x(), 50.0); + QTRY_COMPARE(one->y(), 0.0); + QTRY_COMPARE(two->opacity(), 0.0); + QTRY_COMPARE(two->x(), -100.0);//Not 'in' yet + QTRY_COMPARE(two->y(), 0.0); + QTRY_COMPARE(three->x(), 0.0); + QTRY_COMPARE(three->y(), 0.0); + + //Add 'two' + two->setOpacity(1.0); + QCOMPARE(two->opacity(), 1.0); + + // New size should be immediate + QCOMPARE(row->width(), 150.0); + QCOMPARE(row->height(), 50.0); + + QTest::qWait(0);//Let the animation start + QCOMPARE(one->x(), 50.0); + QCOMPARE(two->x(), -100.0); + + QTRY_COMPARE(one->x(), 100.0); + QTRY_COMPARE(two->x(), 50.0); + + delete canvas; +} + void tst_QDeclarativePositioners::test_vertical() { QDeclarativeView *canvas = createView(SRCDIR "/data/vertical.qml"); @@ -364,6 +492,40 @@ void tst_QDeclarativePositioners::test_grid_topToBottom() delete canvas; } +void tst_QDeclarativePositioners::test_grid_rightToLeft() +{ + QDeclarativeView *canvas = createView(SRCDIR "/data/grid-righttoleft.qml"); + + QDeclarativeRectangle *one = canvas->rootObject()->findChild<QDeclarativeRectangle*>("one"); + QVERIFY(one != 0); + QDeclarativeRectangle *two = canvas->rootObject()->findChild<QDeclarativeRectangle*>("two"); + QVERIFY(two != 0); + QDeclarativeRectangle *three = canvas->rootObject()->findChild<QDeclarativeRectangle*>("three"); + QVERIFY(three != 0); + QDeclarativeRectangle *four = canvas->rootObject()->findChild<QDeclarativeRectangle*>("four"); + QVERIFY(four != 0); + QDeclarativeRectangle *five = canvas->rootObject()->findChild<QDeclarativeRectangle*>("five"); + QVERIFY(five != 0); + + QCOMPARE(one->x(), 70.0); + QCOMPARE(one->y(), 0.0); + QCOMPARE(two->x(), 50.0); + QCOMPARE(two->y(), 0.0); + QCOMPARE(three->x(), 0.0); + QCOMPARE(three->y(), 0.0); + QCOMPARE(four->x(), 70.0); + QCOMPARE(four->y(), 50.0); + QCOMPARE(five->x(), 60.0); + QCOMPARE(five->y(), 50.0); + + QDeclarativeGrid *grid = canvas->rootObject()->findChild<QDeclarativeGrid*>("grid"); + QCOMPARE(grid->layoutDirection(), Qt::RightToLeft); + QCOMPARE(grid->width(), 120.0); + QCOMPARE(grid->height(), 100.0); + + delete canvas; +} + void tst_QDeclarativePositioners::test_grid_spacing() { QDeclarativeView *canvas = createView(SRCDIR "/data/grid-spacing.qml"); @@ -401,6 +563,8 @@ void tst_QDeclarativePositioners::test_grid_animated() { QDeclarativeView *canvas = createView(SRCDIR "/data/grid-animated.qml"); + canvas->rootObject()->setProperty("testRightToLeft", false); + //Note that all animate in QDeclarativeRectangle *one = canvas->rootObject()->findChild<QDeclarativeRectangle*>("one"); QVERIFY(one != 0); @@ -478,6 +642,89 @@ void tst_QDeclarativePositioners::test_grid_animated() delete canvas; } +void tst_QDeclarativePositioners::test_grid_animated_rightToLeft() +{ + QDeclarativeView *canvas = createView(SRCDIR "/data/grid-animated.qml"); + + canvas->rootObject()->setProperty("testRightToLeft", true); + + //Note that all animate in + QDeclarativeRectangle *one = canvas->rootObject()->findChild<QDeclarativeRectangle*>("one"); + QVERIFY(one != 0); + QCOMPARE(one->x(), -100.0); + QCOMPARE(one->y(), -100.0); + + QDeclarativeRectangle *two = canvas->rootObject()->findChild<QDeclarativeRectangle*>("two"); + QVERIFY(two != 0); + QCOMPARE(two->x(), -100.0); + QCOMPARE(two->y(), -100.0); + + QDeclarativeRectangle *three = canvas->rootObject()->findChild<QDeclarativeRectangle*>("three"); + QVERIFY(three != 0); + QCOMPARE(three->x(), -100.0); + QCOMPARE(three->y(), -100.0); + + QDeclarativeRectangle *four = canvas->rootObject()->findChild<QDeclarativeRectangle*>("four"); + QVERIFY(four != 0); + QCOMPARE(four->x(), -100.0); + QCOMPARE(four->y(), -100.0); + + QDeclarativeRectangle *five = canvas->rootObject()->findChild<QDeclarativeRectangle*>("five"); + QVERIFY(five != 0); + QCOMPARE(five->x(), -100.0); + QCOMPARE(five->y(), -100.0); + + QDeclarativeItem *grid = canvas->rootObject()->findChild<QDeclarativeItem*>("grid"); + QVERIFY(grid); + QCOMPARE(grid->width(), 150.0); + QCOMPARE(grid->height(), 100.0); + + //QTRY_COMPARE used instead of waiting for the expected time of animation completion + //Note that this means the duration of the animation is NOT tested + + QTRY_COMPARE(one->y(), 0.0); + QTRY_COMPARE(one->x(), 100.0); + QTRY_COMPARE(two->opacity(), 0.0); + QTRY_COMPARE(two->y(), -100.0); + QTRY_COMPARE(two->x(), -100.0); + QTRY_COMPARE(three->y(), 0.0); + QTRY_COMPARE(three->x(), 50.0); + QTRY_COMPARE(four->y(), 0.0); + QTRY_COMPARE(four->x(), 0.0); + QTRY_COMPARE(five->y(), 50.0); + QTRY_COMPARE(five->x(), 100.0); + + //Add 'two' + two->setOpacity(1.0); + QCOMPARE(two->opacity(), 1.0); + QCOMPARE(grid->width(), 150.0); + QCOMPARE(grid->height(), 100.0); + QTest::qWait(0);//Let the animation start + QCOMPARE(two->x(), -100.0); + QCOMPARE(two->y(), -100.0); + QCOMPARE(one->x(), 100.0); + QCOMPARE(one->y(), 0.0); + QCOMPARE(three->x(), 50.0); + QCOMPARE(three->y(), 0.0); + QCOMPARE(four->x(), 0.0); + QCOMPARE(four->y(), 0.0); + QCOMPARE(five->x(), 100.0); + QCOMPARE(five->y(), 50.0); + //Let the animation complete + QTRY_COMPARE(two->x(), 50.0); + QTRY_COMPARE(two->y(), 0.0); + QTRY_COMPARE(one->x(), 100.0); + QTRY_COMPARE(one->y(), 0.0); + QTRY_COMPARE(three->x(), 0.0); + QTRY_COMPARE(three->y(), 0.0); + QTRY_COMPARE(four->x(), 100.0); + QTRY_COMPARE(four->y(), 50.0); + QTRY_COMPARE(five->x(), 50.0); + QTRY_COMPARE(five->y(), 50.0); + + delete canvas; +} + void tst_QDeclarativePositioners::test_grid_zero_columns() { QDeclarativeView *canvas = createView(SRCDIR "/data/gridzerocolumns.qml"); @@ -597,6 +844,8 @@ void tst_QDeclarativePositioners::test_flow() { QDeclarativeView *canvas = createView(SRCDIR "/data/flowtest.qml"); + canvas->rootObject()->setProperty("testRightToLeft", false); + QDeclarativeRectangle *one = canvas->rootObject()->findChild<QDeclarativeRectangle*>("one"); QVERIFY(one != 0); QDeclarativeRectangle *two = canvas->rootObject()->findChild<QDeclarativeRectangle*>("two"); @@ -627,6 +876,95 @@ void tst_QDeclarativePositioners::test_flow() delete canvas; } +void tst_QDeclarativePositioners::test_flow_rightToLeft() +{ + QDeclarativeView *canvas = createView(SRCDIR "/data/flowtest.qml"); + + canvas->rootObject()->setProperty("testRightToLeft", true); + + QDeclarativeRectangle *one = canvas->rootObject()->findChild<QDeclarativeRectangle*>("one"); + QVERIFY(one != 0); + QDeclarativeRectangle *two = canvas->rootObject()->findChild<QDeclarativeRectangle*>("two"); + QVERIFY(two != 0); + QDeclarativeRectangle *three = canvas->rootObject()->findChild<QDeclarativeRectangle*>("three"); + QVERIFY(three != 0); + QDeclarativeRectangle *four = canvas->rootObject()->findChild<QDeclarativeRectangle*>("four"); + QVERIFY(four != 0); + QDeclarativeRectangle *five = canvas->rootObject()->findChild<QDeclarativeRectangle*>("five"); + QVERIFY(five != 0); + + QCOMPARE(one->x(), 40.0); + QCOMPARE(one->y(), 0.0); + QCOMPARE(two->x(), 20.0); + QCOMPARE(two->y(), 0.0); + QCOMPARE(three->x(), 40.0); + QCOMPARE(three->y(), 50.0); + QCOMPARE(four->x(), 40.0); + QCOMPARE(four->y(), 70.0); + QCOMPARE(five->x(), 30.0); + QCOMPARE(five->y(), 70.0); + + QDeclarativeItem *flow = canvas->rootObject()->findChild<QDeclarativeItem*>("flow"); + QVERIFY(flow); + QCOMPARE(flow->width(), 90.0); + QCOMPARE(flow->height(), 120.0); + + delete canvas; +} + +void tst_QDeclarativePositioners::test_flow_topToBottom() +{ + QDeclarativeView *canvas = createView(SRCDIR "/data/flowtest-toptobottom.qml"); + + canvas->rootObject()->setProperty("testRightToLeft", false); + + QDeclarativeRectangle *one = canvas->rootObject()->findChild<QDeclarativeRectangle*>("one"); + QVERIFY(one != 0); + QDeclarativeRectangle *two = canvas->rootObject()->findChild<QDeclarativeRectangle*>("two"); + QVERIFY(two != 0); + QDeclarativeRectangle *three = canvas->rootObject()->findChild<QDeclarativeRectangle*>("three"); + QVERIFY(three != 0); + QDeclarativeRectangle *four = canvas->rootObject()->findChild<QDeclarativeRectangle*>("four"); + QVERIFY(four != 0); + QDeclarativeRectangle *five = canvas->rootObject()->findChild<QDeclarativeRectangle*>("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(), 50.0); + QCOMPARE(three->y(), 50.0); + QCOMPARE(four->x(), 100.0); + QCOMPARE(four->y(), 00.0); + QCOMPARE(five->x(), 100.0); + QCOMPARE(five->y(), 50.0); + + QDeclarativeItem *flow = canvas->rootObject()->findChild<QDeclarativeItem*>("flow"); + QVERIFY(flow); + QCOMPARE(flow->height(), 90.0); + QCOMPARE(flow->width(), 150.0); + + canvas->rootObject()->setProperty("testRightToLeft", true); + + QVERIFY(flow); + QCOMPARE(flow->height(), 90.0); + QCOMPARE(flow->width(), 150.0); + + QCOMPARE(one->x(), 100.0); + QCOMPARE(one->y(), 0.0); + QCOMPARE(two->x(), 80.0); + QCOMPARE(two->y(), 0.0); + QCOMPARE(three->x(), 50.0); + QCOMPARE(three->y(), 50.0); + QCOMPARE(four->x(), 0.0); + QCOMPARE(four->y(), 0.0); + QCOMPARE(five->x(), 40.0); + QCOMPARE(five->y(), 50.0); + + delete canvas; +} + void tst_QDeclarativePositioners::test_flow_resize() { QDeclarativeView *canvas = createView(SRCDIR "/data/flowtest.qml"); @@ -634,6 +972,7 @@ void tst_QDeclarativePositioners::test_flow_resize() QDeclarativeItem *root = qobject_cast<QDeclarativeItem*>(canvas->rootObject()); QVERIFY(root); root->setWidth(125); + root->setProperty("testRightToLeft", false); QDeclarativeRectangle *one = canvas->rootObject()->findChild<QDeclarativeRectangle*>("one"); QVERIFY(one != 0); @@ -660,6 +999,40 @@ void tst_QDeclarativePositioners::test_flow_resize() delete canvas; } +void tst_QDeclarativePositioners::test_flow_resize_rightToLeft() +{ + QDeclarativeView *canvas = createView(SRCDIR "/data/flowtest.qml"); + + QDeclarativeItem *root = qobject_cast<QDeclarativeItem*>(canvas->rootObject()); + QVERIFY(root); + root->setWidth(125); + root->setProperty("testRightToLeft", true); + + QDeclarativeRectangle *one = canvas->rootObject()->findChild<QDeclarativeRectangle*>("one"); + QVERIFY(one != 0); + QDeclarativeRectangle *two = canvas->rootObject()->findChild<QDeclarativeRectangle*>("two"); + QVERIFY(two != 0); + QDeclarativeRectangle *three = canvas->rootObject()->findChild<QDeclarativeRectangle*>("three"); + QVERIFY(three != 0); + QDeclarativeRectangle *four = canvas->rootObject()->findChild<QDeclarativeRectangle*>("four"); + QVERIFY(four != 0); + QDeclarativeRectangle *five = canvas->rootObject()->findChild<QDeclarativeRectangle*>("five"); + QVERIFY(five != 0); + + QCOMPARE(one->x(), 75.0); + QCOMPARE(one->y(), 0.0); + QCOMPARE(two->x(), 55.0); + QCOMPARE(two->y(), 0.0); + QCOMPARE(three->x(), 5.0); + QCOMPARE(three->y(), 0.0); + QCOMPARE(four->x(), 75.0); + QCOMPARE(four->y(), 50.0); + QCOMPARE(five->x(), 65.0); + QCOMPARE(five->y(), 50.0); + + delete canvas; +} + void tst_QDeclarativePositioners::test_flow_implicit_resize() { QDeclarativeView *canvas = createView(SRCDIR "/data/flow-testimplicitsize.qml"); @@ -671,16 +1044,21 @@ void tst_QDeclarativePositioners::test_flow_implicit_resize() QCOMPARE(flow->width(), 100.0); QCOMPARE(flow->height(), 120.0); - canvas->rootObject()->setProperty("leftToRight", true); + canvas->rootObject()->setProperty("flowLayout", 0); QCOMPARE(flow->flow(), QDeclarativeFlow::LeftToRight); QCOMPARE(flow->width(), 220.0); QCOMPARE(flow->height(), 50.0); - canvas->rootObject()->setProperty("leftToRight", false); + canvas->rootObject()->setProperty("flowLayout", 1); QCOMPARE(flow->flow(), QDeclarativeFlow::TopToBottom); QCOMPARE(flow->width(), 100.0); QCOMPARE(flow->height(), 120.0); + canvas->rootObject()->setProperty("flowLayout", 2); + QCOMPARE(flow->layoutDirection(), Qt::RightToLeft); + QCOMPARE(flow->width(), 220.0); + QCOMPARE(flow->height(), 50.0); + delete canvas; } @@ -694,7 +1072,7 @@ void interceptWarnings(QtMsgType type, const char *msg) void tst_QDeclarativePositioners::test_conflictinganchors() { - qInstallMsgHandler(interceptWarnings); + QtMsgHandler oldMsgHandler = qInstallMsgHandler(interceptWarnings); QDeclarativeEngine engine; QDeclarativeComponent component(&engine); @@ -775,6 +1153,7 @@ void tst_QDeclarativePositioners::test_conflictinganchors() item = qobject_cast<QDeclarativeItem*>(component.create()); QVERIFY(item); QCOMPARE(warningMessage, QString("file::2:1: QML Flow: Cannot specify anchors for items inside Flow")); + qInstallMsgHandler(oldMsgHandler); } void tst_QDeclarativePositioners::test_vertical_qgraphicswidget() @@ -819,6 +1198,49 @@ void tst_QDeclarativePositioners::test_vertical_qgraphicswidget() delete canvas; } +void tst_QDeclarativePositioners::testQtQuick11Attributes() +{ + QFETCH(QString, code); + QFETCH(QString, warning); + QFETCH(QString, error); + + QDeclarativeEngine engine; + QObject *obj; + + QDeclarativeComponent valid(&engine); + valid.setData("import QtQuick 1.1; " + code.toUtf8(), QUrl("")); + obj = valid.create(); + QVERIFY(obj); + QVERIFY(valid.errorString().isEmpty()); + delete obj; + + QDeclarativeComponent invalid(&engine); + invalid.setData("import QtQuick 1.0; " + code.toUtf8(), QUrl("")); + QTest::ignoreMessage(QtWarningMsg, warning.toUtf8()); + obj = invalid.create(); + QCOMPARE(invalid.errorString(), error); + delete obj; +} + +void tst_QDeclarativePositioners::testQtQuick11Attributes_data() +{ + QTest::addColumn<QString>("code"); + QTest::addColumn<QString>("warning"); + QTest::addColumn<QString>("error"); + + QTest::newRow("Flow.layoutDirection") << "Flow { layoutDirection: Qt.LeftToRight }" + << "QDeclarativeComponent: Component is not ready" + << ":1 \"Flow.layoutDirection\" is not available in QtQuick 1.0.\n"; + + QTest::newRow("Row.layoutDirection") << "Row { layoutDirection: Qt.LeftToRight }" + << "QDeclarativeComponent: Component is not ready" + << ":1 \"Row.layoutDirection\" is not available in QtQuick 1.0.\n"; + + QTest::newRow("Grid.layoutDirection") << "Grid { layoutDirection: Qt.LeftToRight }" + << "QDeclarativeComponent: Component is not ready" + << ":1 \"Grid.layoutDirection\" is not available in QtQuick 1.0.\n"; +} + QDeclarativeView *tst_QDeclarativePositioners::createView(const QString &filename) { QDeclarativeView *canvas = new QDeclarativeView(0); diff --git a/tests/auto/declarative/qdeclarativeqt/data/formatting.qml b/tests/auto/declarative/qdeclarativeqt/data/formatting.qml index 35c6a29..f520aeb 100644 --- a/tests/auto/declarative/qdeclarativeqt/data/formatting.qml +++ b/tests/auto/declarative/qdeclarativeqt/data/formatting.qml @@ -1,29 +1,44 @@ import QtQuick 1.0 QtObject { - property date date1: "2008-12-24" - property string test1: Qt.formatDate(date1) - property string test2: Qt.formatDate(date1, Qt.DefaultLocaleLongDate) - property string test3: Qt.formatDate(date1, "ddd MMMM d yy") + property date dateFromString: "2008-12-24" + property variant jsdate: new Date(2008,11,24,14,15,38,200) // months are 0-based - property variant time1: new Date(0,0,0,14,15,38,200) - property string test4: Qt.formatTime(time1) - property string test5: Qt.formatTime(time1, Qt.DefaultLocaleLongDate) - property string test6: Qt.formatTime(time1, "H:m:s a") - property string test7: Qt.formatTime(time1, "hh:mm:ss.zzz") + function formatDate(prop) { + var v = eval(prop) + return [ + Qt.formatDate(v), + Qt.formatDate(v, Qt.DefaultLocaleLongDate), + Qt.formatDate(v, "ddd MMMM d yy") + ] + } - property variant dateTime1: new Date(1978,2,4,9,13,54) - property string test8: Qt.formatDateTime(dateTime1) - property string test9: Qt.formatDateTime(dateTime1, Qt.DefaultLocaleLongDate) - property string test10: Qt.formatDateTime(dateTime1, "M/d/yy H:m:s a") + function formatTime(prop) { + var v = eval(prop) + return [ + Qt.formatTime(v), + Qt.formatTime(v, Qt.DefaultLocaleLongDate), + Qt.formatTime(v, "H:m:s a"), + Qt.formatTime(v, "hh:mm:ss.zzz") + ] + } + + function formatDateTime(prop) { + var v = eval(prop) + return [ + Qt.formatDateTime(v), + Qt.formatDateTime(v, Qt.DefaultLocaleLongDate), + Qt.formatDateTime(v, "M/d/yy H:m:s a") + ] + } // Error cases - property string test11: Qt.formatDate() - property string test12: Qt.formatDate(new Date, new Object) + property string err_date1: Qt.formatDate() + property string err_date2: Qt.formatDate(new Date, new Object) - property string test13: Qt.formatTime() - property string test14: Qt.formatTime(new Date, new Object) + property string err_time1: Qt.formatTime() + property string err_time2: Qt.formatTime(new Date, new Object) - property string test15: Qt.formatDateTime() - property string test16: Qt.formatDateTime(new Date, new Object) + property string err_dateTime1: Qt.formatDateTime() + property string err_dateTime2: Qt.formatDateTime(new Date, new Object) } diff --git a/tests/auto/declarative/qdeclarativeqt/qdeclarativeqt.pro b/tests/auto/declarative/qdeclarativeqt/qdeclarativeqt.pro index 6af6500..9e698fe 100644 --- a/tests/auto/declarative/qdeclarativeqt/qdeclarativeqt.pro +++ b/tests/auto/declarative/qdeclarativeqt/qdeclarativeqt.pro @@ -1,5 +1,5 @@ load(qttest_p4) -contains(QT_CONFIG,declarative): QT += declarative +contains(QT_CONFIG,declarative): QT += declarative script SOURCES += tst_qdeclarativeqt.cpp macx:CONFIG -= app_bundle diff --git a/tests/auto/declarative/qdeclarativeqt/tst_qdeclarativeqt.cpp b/tests/auto/declarative/qdeclarativeqt/tst_qdeclarativeqt.cpp index bd9d01f..80d9d93 100644 --- a/tests/auto/declarative/qdeclarativeqt/tst_qdeclarativeqt.cpp +++ b/tests/auto/declarative/qdeclarativeqt/tst_qdeclarativeqt.cpp @@ -38,6 +38,7 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ +#include <private/qdeclarativeengine_p.h> #include <qtest.h> #include <QDebug> @@ -81,7 +82,8 @@ private slots: void createComponent_pragmaLibrary(); void createQmlObject(); void consoleLog(); - void formatting(); + void dateTimeFormatting(); + void dateTimeFormatting_data(); void isQtObject(); void btoa(); void atob(); @@ -446,49 +448,88 @@ void tst_qdeclarativeqt::consoleLog() delete object; } -void tst_qdeclarativeqt::formatting() +void tst_qdeclarativeqt::dateTimeFormatting() { - QDeclarativeComponent component(&engine, TEST_FILE("formatting.qml")); + QFETCH(QString, method); + QFETCH(QStringList, inputProperties); + QFETCH(QStringList, expectedResults); - QString warning1 = component.url().toString() + ":22: Error: Qt.formatDate(): Invalid date format"; - QString warning2 = component.url().toString() + ":21: Error: Qt.formatDate(): Invalid arguments"; - QString warning3 = component.url().toString() + ":28: Error: Qt.formatDateTime(): Invalid datetime format"; - QString warning4 = component.url().toString() + ":27: Error: Qt.formatDateTime(): Invalid arguments"; - QString warning5 = component.url().toString() + ":25: Error: Qt.formatTime(): Invalid time format"; - QString warning6 = component.url().toString() + ":24: Error: Qt.formatTime(): Invalid arguments"; + QDate date(2008,12,24); + QTime time(14,15,38,200); + QDateTime dateTime(date, time); - 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)); - QTest::ignoreMessage(QtWarningMsg, qPrintable(warning6)); + QDeclarativeEngine eng; + + eng.rootContext()->setContextProperty("qdate", date); + eng.rootContext()->setContextProperty("qtime", time); + eng.rootContext()->setContextProperty("qdatetime", dateTime); + + QDeclarativeComponent component(&eng, TEST_FILE("formatting.qml")); + + QStringList warnings; + warnings << component.url().toString() + ":37: Error: Qt.formatDate(): Invalid date format" + << component.url().toString() + ":36: Error: Qt.formatDate(): Invalid arguments" + << component.url().toString() + ":40: Error: Qt.formatTime(): Invalid time format" + << component.url().toString() + ":39: Error: Qt.formatTime(): Invalid arguments" + << component.url().toString() + ":43: Error: Qt.formatDateTime(): Invalid datetime format" + << component.url().toString() + ":42: Error: Qt.formatDateTime(): Invalid arguments"; + + foreach (const QString &warning, warnings) + QTest::ignoreMessage(QtWarningMsg, qPrintable(warning)); QObject *object = component.create(); + QVERIFY2(component.errorString().isEmpty(), qPrintable(component.errorString())); QVERIFY(object != 0); - QDate date1(2008,12,24); - QCOMPARE(object->property("date1").toDate(), date1); - QCOMPARE(object->property("test1").toString(), date1.toString(Qt::DefaultLocaleShortDate)); - QCOMPARE(object->property("test2").toString(), date1.toString(Qt::DefaultLocaleLongDate)); - QCOMPARE(object->property("test3").toString(), date1.toString("ddd MMMM d yy")); - - QTime time1(14,15,38,200); - QCOMPARE(object->property("time1").toTime(), time1); - QCOMPARE(object->property("test4").toString(), time1.toString(Qt::DefaultLocaleShortDate)); - QCOMPARE(object->property("test5").toString(), time1.toString(Qt::DefaultLocaleLongDate)); - QCOMPARE(object->property("test6").toString(), time1.toString("H:m:s a")); - QCOMPARE(object->property("test7").toString(), time1.toString("hh:mm:ss.zzz")); - - QDateTime dateTime1(QDate(1978,03,04),QTime(9,13,54)); - QCOMPARE(object->property("dateTime1").toDateTime(),dateTime1); - QCOMPARE(object->property("test8").toString(), dateTime1.toString(Qt::DefaultLocaleShortDate)); - QCOMPARE(object->property("test9").toString(), dateTime1.toString(Qt::DefaultLocaleLongDate)); - QCOMPARE(object->property("test10").toString(), dateTime1.toString("M/d/yy H:m:s a")); + QVERIFY(inputProperties.count() > 0); + + QVariant result; + foreach(const QString &prop, inputProperties) { + QVERIFY(QMetaObject::invokeMethod(object, method.toUtf8().constData(), + Q_RETURN_ARG(QVariant, result), + Q_ARG(QVariant, prop))); + + QStringList output = result.toStringList(); + for (int i=0; i<output.count(); i++) + QCOMPARE(output[i], expectedResults[i]); + } delete object; } +void tst_qdeclarativeqt::dateTimeFormatting_data() +{ + QTest::addColumn<QString>("method"); + QTest::addColumn<QStringList>("inputProperties"); + QTest::addColumn<QStringList>("expectedResults"); + + QDate date(2008,12,24); + QTime time(14,15,38,200); + QDateTime dateTime(date, time); + + QTest::newRow("formatDate") + << "formatDate" + << (QStringList() << "dateFromString" << "jsdate" << "qdate" << "qdatetime") + << (QStringList() << date.toString(Qt::DefaultLocaleShortDate) + << date.toString(Qt::DefaultLocaleLongDate) + << date.toString("ddd MMMM d yy")); + + QTest::newRow("formatTime") + << "formatTime" + << (QStringList() << "jsdate" << "qtime" << "qdatetime") + << (QStringList() << time.toString(Qt::DefaultLocaleShortDate) + << time.toString(Qt::DefaultLocaleLongDate) + << time.toString("H:m:s a") + << time.toString("hh:mm:ss.zzz")); + + QTest::newRow("formatDateTime") + << "formatDateTime" + << (QStringList() << "jsdate" << "qdatetime") + << (QStringList() << dateTime.toString(Qt::DefaultLocaleShortDate) + << dateTime.toString(Qt::DefaultLocaleLongDate) + << dateTime.toString("M/d/yy H:m:s a")); +} + void tst_qdeclarativeqt::isQtObject() { QDeclarativeComponent component(&engine, TEST_FILE("isQtObject.qml")); diff --git a/tests/auto/declarative/qdeclarativerepeater/tst_qdeclarativerepeater.cpp b/tests/auto/declarative/qdeclarativerepeater/tst_qdeclarativerepeater.cpp index d849d73..6b840a3 100644 --- a/tests/auto/declarative/qdeclarativerepeater/tst_qdeclarativerepeater.cpp +++ b/tests/auto/declarative/qdeclarativerepeater/tst_qdeclarativerepeater.cpp @@ -69,9 +69,14 @@ private slots: void numberModel(); void objectList(); void stringList(); - void dataModel(); + void dataModel_adding(); + void dataModel_removing(); + void dataModel_changes(); void itemModel(); + void resetModel(); void properties(); + void testQtQuick11Attributes(); + void testQtQuick11Attributes_data(); private: QDeclarativeView *createView(); @@ -186,6 +191,11 @@ void tst_QDeclarativeRepeater::numberModel() QVERIFY(repeater != 0); QCOMPARE(repeater->parentItem()->childItems().count(), 5+1); + QVERIFY(!repeater->itemAt(-1)); + for (int i=0; i<repeater->count(); i++) + QCOMPARE(repeater->itemAt(i), repeater->parentItem()->childItems().at(i)); + QVERIFY(!repeater->itemAt(repeater->count())); + QMetaObject::invokeMethod(canvas->rootObject(), "checkProperties"); QVERIFY(testObject->error() == false); @@ -223,6 +233,17 @@ void tst_QDeclarativeRepeater::objectList() QCOMPARE(repeater->property("errors").toInt(), 0);//If this fails either they are out of order or can't find the object's data QCOMPARE(repeater->property("instantiated").toInt(), 100); + QVERIFY(!repeater->itemAt(-1)); + for (int i=0; i<data.count(); i++) + QCOMPARE(repeater->itemAt(i), repeater->parentItem()->childItems().at(i)); + QVERIFY(!repeater->itemAt(data.count())); + + QSignalSpy addedSpy(repeater, SIGNAL(itemAdded(int,QDeclarativeItem*))); + QSignalSpy removedSpy(repeater, SIGNAL(itemRemoved(int,QDeclarativeItem*))); + ctxt->setContextProperty("testData", QVariant::fromValue(data)); + QCOMPARE(addedSpy.count(), data.count()); + QCOMPARE(removedSpy.count(), data.count()); + qDeleteAll(data); delete canvas; } @@ -284,7 +305,69 @@ void tst_QDeclarativeRepeater::stringList() delete canvas; } -void tst_QDeclarativeRepeater::dataModel() +void tst_QDeclarativeRepeater::dataModel_adding() +{ + QDeclarativeView *canvas = createView(); + QDeclarativeContext *ctxt = canvas->rootContext(); + TestObject *testObject = new TestObject; + ctxt->setContextProperty("testObject", testObject); + + TestModel testModel; + ctxt->setContextProperty("testData", &testModel); + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/repeater2.qml")); + qApp->processEvents(); + + QDeclarativeRepeater *repeater = findItem<QDeclarativeRepeater>(canvas->rootObject(), "repeater"); + QVERIFY(repeater != 0); + QDeclarativeItem *container = findItem<QDeclarativeItem>(canvas->rootObject(), "container"); + QVERIFY(container != 0); + + QVERIFY(!repeater->itemAt(0)); + + QSignalSpy countSpy(repeater, SIGNAL(countChanged())); + QSignalSpy addedSpy(repeater, SIGNAL(itemAdded(int,QDeclarativeItem*))); + + // add to empty model + testModel.addItem("two", "2"); + QCOMPARE(repeater->itemAt(0), container->childItems().at(0)); + QCOMPARE(countSpy.count(), 1); countSpy.clear(); + QCOMPARE(addedSpy.count(), 1); + QCOMPARE(addedSpy.at(0).at(0).toInt(), 0); + QCOMPARE(addedSpy.at(0).at(1).value<QDeclarativeItem*>(), container->childItems().at(0)); + addedSpy.clear(); + + // insert at start + testModel.insertItem(0, "one", "1"); + QCOMPARE(repeater->itemAt(0), container->childItems().at(0)); + QCOMPARE(countSpy.count(), 1); countSpy.clear(); + QCOMPARE(addedSpy.count(), 1); + QCOMPARE(addedSpy.at(0).at(0).toInt(), 0); + QCOMPARE(addedSpy.at(0).at(1).value<QDeclarativeItem*>(), container->childItems().at(0)); + addedSpy.clear(); + + // insert at end + testModel.insertItem(2, "four", "4"); + QCOMPARE(repeater->itemAt(2), container->childItems().at(2)); + QCOMPARE(countSpy.count(), 1); countSpy.clear(); + QCOMPARE(addedSpy.count(), 1); + QCOMPARE(addedSpy.at(0).at(0).toInt(), 2); + QCOMPARE(addedSpy.at(0).at(1).value<QDeclarativeItem*>(), container->childItems().at(2)); + addedSpy.clear(); + + // insert in middle + testModel.insertItem(2, "three", "3"); + QCOMPARE(repeater->itemAt(2), container->childItems().at(2)); + QCOMPARE(countSpy.count(), 1); countSpy.clear(); + QCOMPARE(addedSpy.count(), 1); + QCOMPARE(addedSpy.at(0).at(0).toInt(), 2); + QCOMPARE(addedSpy.at(0).at(1).value<QDeclarativeItem*>(), container->childItems().at(2)); + addedSpy.clear(); + + delete testObject; + delete canvas; +} + +void tst_QDeclarativeRepeater::dataModel_removing() { QDeclarativeView *canvas = createView(); QDeclarativeContext *ctxt = canvas->rootContext(); @@ -295,28 +378,84 @@ void tst_QDeclarativeRepeater::dataModel() testModel.addItem("one", "1"); testModel.addItem("two", "2"); testModel.addItem("three", "3"); + testModel.addItem("four", "4"); + testModel.addItem("five", "5"); ctxt->setContextProperty("testData", &testModel); - canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/repeater2.qml")); qApp->processEvents(); QDeclarativeRepeater *repeater = findItem<QDeclarativeRepeater>(canvas->rootObject(), "repeater"); QVERIFY(repeater != 0); - QDeclarativeItem *container = findItem<QDeclarativeItem>(canvas->rootObject(), "container"); QVERIFY(container != 0); + QCOMPARE(container->childItems().count(), repeater->count()+1); + + QSignalSpy countSpy(repeater, SIGNAL(countChanged())); + QSignalSpy removedSpy(repeater, SIGNAL(itemRemoved(int,QDeclarativeItem*))); + + // remove at start + QDeclarativeItem *item = repeater->itemAt(0); + QCOMPARE(item, container->childItems().at(0)); + + testModel.removeItem(0); + QVERIFY(repeater->itemAt(0) != item); + QCOMPARE(countSpy.count(), 1); countSpy.clear(); + QCOMPARE(removedSpy.count(), 1); + QCOMPARE(removedSpy.at(0).at(0).toInt(), 0); + QCOMPARE(removedSpy.at(0).at(1).value<QDeclarativeItem*>(), item); + removedSpy.clear(); + + // remove at end + int lastIndex = testModel.count()-1; + item = repeater->itemAt(lastIndex); + QCOMPARE(item, container->childItems().at(lastIndex)); + + testModel.removeItem(lastIndex); + QVERIFY(repeater->itemAt(lastIndex) != item); + QCOMPARE(countSpy.count(), 1); countSpy.clear(); + QCOMPARE(removedSpy.count(), 1); + QCOMPARE(removedSpy.at(0).at(0).toInt(), lastIndex); + QCOMPARE(removedSpy.at(0).at(1).value<QDeclarativeItem*>(), item); + removedSpy.clear(); + + // remove from middle + item = repeater->itemAt(1); + QCOMPARE(item, container->childItems().at(1)); + + testModel.removeItem(1); + QVERIFY(repeater->itemAt(lastIndex) != item); + QCOMPARE(countSpy.count(), 1); countSpy.clear(); + QCOMPARE(removedSpy.count(), 1); + QCOMPARE(removedSpy.at(0).at(0).toInt(), 1); + QCOMPARE(removedSpy.at(0).at(1).value<QDeclarativeItem*>(), item); + removedSpy.clear(); - QCOMPARE(container->childItems().count(), 4); + delete testObject; + delete canvas; +} - QSignalSpy repeaterSpy(repeater, SIGNAL(countChanged())); - testModel.addItem("four", "4"); - QCOMPARE(container->childItems().count(), 5); - QCOMPARE(repeaterSpy.count(),1); +void tst_QDeclarativeRepeater::dataModel_changes() +{ + QDeclarativeView *canvas = createView(); + QDeclarativeContext *ctxt = canvas->rootContext(); + TestObject *testObject = new TestObject; + ctxt->setContextProperty("testObject", testObject); - testModel.removeItem(2); - QCOMPARE(container->childItems().count(), 4); - QCOMPARE(repeaterSpy.count(),2); + TestModel testModel; + testModel.addItem("one", "1"); + testModel.addItem("two", "2"); + testModel.addItem("three", "3"); + + ctxt->setContextProperty("testData", &testModel); + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/repeater2.qml")); + qApp->processEvents(); + + QDeclarativeRepeater *repeater = findItem<QDeclarativeRepeater>(canvas->rootObject(), "repeater"); + QVERIFY(repeater != 0); + QDeclarativeItem *container = findItem<QDeclarativeItem>(canvas->rootObject(), "container"); + QVERIFY(container != 0); + QCOMPARE(container->childItems().count(), repeater->count()+1); // Check that model changes are propagated QDeclarativeText *text = findItem<QDeclarativeText>(canvas->rootObject(), "myName", 1); @@ -377,6 +516,61 @@ void tst_QDeclarativeRepeater::itemModel() delete canvas; } +void tst_QDeclarativeRepeater::resetModel() +{ + QDeclarativeView *canvas = createView(); + + QStringList dataA; + for (int i=0; i<10; i++) + dataA << QString::number(i); + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testData", dataA); + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/repeater1.qml")); + qApp->processEvents(); + QDeclarativeRepeater *repeater = findItem<QDeclarativeRepeater>(canvas->rootObject(), "repeater"); + QVERIFY(repeater != 0); + QDeclarativeItem *container = findItem<QDeclarativeItem>(canvas->rootObject(), "container"); + QVERIFY(container != 0); + + QCOMPARE(repeater->count(), dataA.count()); + + QSignalSpy countSpy(repeater, SIGNAL(countChanged())); + QSignalSpy addedSpy(repeater, SIGNAL(itemAdded(int,QDeclarativeItem*))); + QSignalSpy removedSpy(repeater, SIGNAL(itemRemoved(int,QDeclarativeItem*))); + + QStringList dataB; + for (int i=0; i<20; i++) + dataB << QString::number(i); + + // reset context property + ctxt->setContextProperty("testData", dataB); + QCOMPARE(repeater->count(), dataB.count()); + + QCOMPARE(countSpy.count(), 1); + QCOMPARE(removedSpy.count(), dataA.count()); + QCOMPARE(addedSpy.count(), dataB.count()); + for (int i=0; i<dataB.count(); i++) { + QCOMPARE(addedSpy.at(i).at(0).toInt(), i); + QCOMPARE(addedSpy.at(i).at(1).value<QDeclarativeItem*>(), repeater->itemAt(i)); + } + countSpy.clear(); + removedSpy.clear(); + addedSpy.clear(); + + // reset via setModel() + repeater->setModel(dataA); + QCOMPARE(repeater->count(), dataA.count()); + + QCOMPARE(countSpy.count(), 1); + QCOMPARE(removedSpy.count(), dataB.count()); + QCOMPARE(addedSpy.count(), dataA.count()); + for (int i=0; i<dataA.count(); i++) { + QCOMPARE(addedSpy.at(i).at(0).toInt(), i); + QCOMPARE(addedSpy.at(i).at(1).value<QDeclarativeItem*>(), repeater->itemAt(i)); + } +} + void tst_QDeclarativeRepeater::properties() { QDeclarativeEngine engine; @@ -407,6 +601,50 @@ void tst_QDeclarativeRepeater::properties() delete rootObject; } +void tst_QDeclarativeRepeater::testQtQuick11Attributes() +{ + QFETCH(QString, code); + QFETCH(QString, warning); + QFETCH(QString, error); + + QDeclarativeEngine engine; + QObject *obj; + + QDeclarativeComponent invalid(&engine); + invalid.setData("import QtQuick 1.0; Repeater { " + code.toUtf8() + " }", QUrl("")); + QTest::ignoreMessage(QtWarningMsg, warning.toUtf8()); + obj = invalid.create(); + QCOMPARE(invalid.errorString(), error); + delete obj; + + QDeclarativeComponent valid(&engine); + valid.setData("import QtQuick 1.1; Repeater { " + code.toUtf8() + " }", QUrl("")); + obj = valid.create(); + QVERIFY(obj); + QVERIFY(valid.errorString().isEmpty()); + delete obj; +} + +void tst_QDeclarativeRepeater::testQtQuick11Attributes_data() +{ + QTest::addColumn<QString>("code"); + QTest::addColumn<QString>("warning"); + QTest::addColumn<QString>("error"); + + QTest::newRow("itemAdded") << "onItemAdded: count" + << "QDeclarativeComponent: Component is not ready" + << ":1 \"Repeater.onItemAdded\" is not available in QtQuick 1.0.\n"; + + QTest::newRow("itemRemoved") << "onItemRemoved: count" + << "QDeclarativeComponent: Component is not ready" + << ":1 \"Repeater.onItemRemoved\" is not available in QtQuick 1.0.\n"; + + QTest::newRow("itemAt") << "Component.onCompleted: itemAt(0)" + << "<Unknown File>:1: ReferenceError: Can't find variable: itemAt" + << ""; +} + + QDeclarativeView *tst_QDeclarativeRepeater::createView() { QDeclarativeView *canvas = new QDeclarativeView(0); diff --git a/tests/auto/declarative/qdeclarativetext/data/horizontalAlignment_RightToLeft.qml b/tests/auto/declarative/qdeclarativetext/data/horizontalAlignment_RightToLeft.qml new file mode 100644 index 0000000..4f58944 --- /dev/null +++ b/tests/auto/declarative/qdeclarativetext/data/horizontalAlignment_RightToLeft.qml @@ -0,0 +1,23 @@ +import QtQuick 1.0 + +Rectangle { + id: top + width: 200; height: 70; + + property alias horizontalAlignment: text.horizontalAlignment + property string text: "اختبا" + + Rectangle { + anchors.centerIn: parent + width: 180 + height: 20 + color: "green" + + Text { + id: text + objectName: "text" + anchors.fill: parent + text: top.text + } + } +} diff --git a/tests/auto/declarative/qdeclarativetext/data/lineCount.qml b/tests/auto/declarative/qdeclarativetext/data/lineCount.qml new file mode 100644 index 0000000..63817f6 --- /dev/null +++ b/tests/auto/declarative/qdeclarativetext/data/lineCount.qml @@ -0,0 +1,15 @@ +import QtQuick 1.1 + +Item { + width: 200 + height: 200 + + Text { + id: myText + objectName: "myText" + width: 200 + wrapMode: Text.WordWrap + maximumLineCount: undefined + text: "Testing that maximumLines, visibleLines, and totalLines works properly in the autotests. The quick brown fox jumped over the lazy anything with the letter 'g'." + } +} diff --git a/tests/auto/declarative/qdeclarativetext/data/lineHeight.qml b/tests/auto/declarative/qdeclarativetext/data/lineHeight.qml new file mode 100644 index 0000000..851d871 --- /dev/null +++ b/tests/auto/declarative/qdeclarativetext/data/lineHeight.qml @@ -0,0 +1,15 @@ +import QtQuick 1.1 + +Item { + width: 200 + height: 200 + + Text { + id: myText + objectName: "myText" + width: 200 + wrapMode: Text.WordWrap + font.pixelSize: 13 + text: "Lorem ipsum sit amet, consectetur adipiscing elit. Integer felis nisl, varius in pretium nec, venenatis non erat. Proin lobortis interdum dictum." + } +} diff --git a/tests/auto/declarative/qdeclarativetext/tst_qdeclarativetext.cpp b/tests/auto/declarative/qdeclarativetext/tst_qdeclarativetext.cpp index 480dba5..320a6e7 100644 --- a/tests/auto/declarative/qdeclarativetext/tst_qdeclarativetext.cpp +++ b/tests/auto/declarative/qdeclarativetext/tst_qdeclarativetext.cpp @@ -43,12 +43,14 @@ #include <QtDeclarative/qdeclarativeengine.h> #include <QtDeclarative/qdeclarativecomponent.h> #include <private/qdeclarativetext_p.h> +#include <private/qdeclarativetext_p_p.h> #include <private/qdeclarativevaluetype_p.h> #include <QFontMetrics> #include <QGraphicsSceneMouseEvent> #include <qmath.h> #include <QDeclarativeView> #include <private/qapplication_p.h> +#include <limits.h> #include "../../../shared/util.h" #include "testhttpserver.h" @@ -78,8 +80,12 @@ private slots: void embeddedImages_data(); void embeddedImages(); + void lineCount(); + void lineHeight(); + // ### these tests may be trivial void horizontalAlignment(); + void horizontalAlignment_RightToLeft(); void verticalAlignment(); void font(); void style(); @@ -98,6 +104,10 @@ private slots: void clickLink(); void QTBUG_12291(); + void implicitSize_data(); + void implicitSize(); + void testQtQuick11Attributes(); + void testQtQuick11Attributes_data(); private: QStringList standard; @@ -460,6 +470,8 @@ void tst_qdeclarativetext::alignments() QCOMPARE(actual,expect); } #endif + + delete canvas; } //the alignment tests may be trivial o.oa @@ -495,6 +507,32 @@ void tst_qdeclarativetext::horizontalAlignment() } +void tst_qdeclarativetext::horizontalAlignment_RightToLeft() +{ + QDeclarativeView *canvas = createView(SRCDIR "/data/horizontalAlignment_RightToLeft.qml"); + QDeclarativeText *text = canvas->rootObject()->findChild<QDeclarativeText*>("text"); + QVERIFY(text != 0); + canvas->show(); + + QDeclarativeTextPrivate *textPrivate = QDeclarativeTextPrivate::get(text); + QVERIFY(textPrivate != 0); + + QVERIFY(textPrivate->layout.lineAt(0).x() > canvas->width()/2); + + // "Right" aligned + text->setHAlign(QDeclarativeText::AlignRight); + QCOMPARE(text->hAlign(), QDeclarativeText::AlignRight); + QVERIFY(textPrivate->layout.lineAt(0).x() < canvas->width()/2); + + // Center aligned + text->setHAlign(QDeclarativeText::AlignHCenter); + QCOMPARE(text->hAlign(), QDeclarativeText::AlignHCenter); + QVERIFY(textPrivate->layout.lineAt(0).x() < canvas->width()/2); + QVERIFY(textPrivate->layout.lineAt(0).x() + textPrivate->layout.lineAt(0).width() > canvas->width()/2); + + delete canvas; +} + void tst_qdeclarativetext::verticalAlignment() { //test one align each, and then test if two align fails. @@ -926,6 +964,8 @@ void tst_qdeclarativetext::QTBUG_12291() QDeclarativeText *text = ob->findChild<QDeclarativeText*>("text"); QVERIFY(text); QVERIFY(text->boundingRect().isValid()); + + delete canvas; } class EventSender : public QGraphicsItem @@ -1018,6 +1058,148 @@ void tst_qdeclarativetext::embeddedImages() QCOMPARE(textObject->width(), 16.0); // default size of QTextDocument broken image icon QCOMPARE(textObject->height(), 16.0); } + + delete textObject; +} + +void tst_qdeclarativetext::lineCount() +{ + QDeclarativeView *canvas = createView(SRCDIR "/data/lineCount.qml"); + + QDeclarativeText *myText = canvas->rootObject()->findChild<QDeclarativeText*>("myText"); + QVERIFY(myText != 0); + + QVERIFY(myText->lineCount() > 1); + QVERIFY(!myText->truncated()); + QCOMPARE(myText->maximumLineCount(), INT_MAX); + + myText->setMaximumLineCount(2); + QCOMPARE(myText->lineCount(), 2); + QCOMPARE(myText->truncated(), true); + QCOMPARE(myText->maximumLineCount(), 2); + + myText->resetMaximumLineCount(); + QCOMPARE(myText->maximumLineCount(), INT_MAX); + QCOMPARE(myText->truncated(), false); + + myText->setElideMode(QDeclarativeText::ElideRight); + myText->setMaximumLineCount(2); + QCOMPARE(myText->lineCount(), 2); + QCOMPARE(myText->truncated(), true); + QCOMPARE(myText->maximumLineCount(), 2); + + delete canvas; +} + +void tst_qdeclarativetext::lineHeight() +{ + QDeclarativeView *canvas = createView(SRCDIR "/data/lineHeight.qml"); + + QDeclarativeText *myText = canvas->rootObject()->findChild<QDeclarativeText*>("myText"); + QVERIFY(myText != 0); + + QVERIFY(myText->lineHeight() == 1); + QVERIFY(myText->lineHeightMode() == QDeclarativeText::MultiplyHeight); + + qreal h = myText->height(); + myText->setLineHeight(1.5); + QVERIFY(myText->height() == h * 1.5); + + myText->setLineHeightMode(QDeclarativeText::PixelHeight); + myText->setLineHeight(20); + QCOMPARE(myText->height(), myText->lineCount() * 20.0); + + myText->setText("Lorem ipsum sit <b>amet</b>, consectetur adipiscing elit. Integer felis nisl, varius in pretium nec, venenatis non erat. Proin lobortis interdum dictum."); + myText->setLineHeightMode(QDeclarativeText::MultiplyHeight); + myText->setLineHeight(1); + + qreal h2 = myText->height(); + myText->setLineHeight(2.0); + QVERIFY(myText->height() == h2 * 2.0); + + myText->setLineHeightMode(QDeclarativeText::PixelHeight); + myText->setLineHeight(10); + QCOMPARE(myText->height(), myText->lineCount() * 10.0); + + delete canvas; +} + +void tst_qdeclarativetext::implicitSize_data() +{ + QTest::addColumn<QString>("text"); + QTest::addColumn<QString>("wrap"); + QTest::newRow("plain") << "The quick red fox jumped over the lazy brown dog" << "Text.NoWrap"; + QTest::newRow("richtext") << "<b>The quick red fox jumped over the lazy brown dog</b>" << "Text.NoWrap"; + QTest::newRow("plain_wrap") << "The quick red fox jumped over the lazy brown dog" << "Text.Wrap"; + QTest::newRow("richtext_wrap") << "<b>The quick red fox jumped over the lazy brown dog</b>" << "Text.Wrap"; +} + +void tst_qdeclarativetext::implicitSize() +{ + QFETCH(QString, text); + QFETCH(QString, wrap); + QString componentStr = "import QtQuick 1.1\nText { text: \"" + text + "\"; width: 50; wrapMode: " + wrap + " }"; + QDeclarativeComponent textComponent(&engine); + textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QDeclarativeText *textObject = qobject_cast<QDeclarativeText*>(textComponent.create()); + + QVERIFY(textObject->width() < textObject->implicitWidth()); + QVERIFY(textObject->height() == textObject->implicitHeight()); + + textObject->resetWidth(); + QVERIFY(textObject->width() == textObject->implicitWidth()); + QVERIFY(textObject->height() == textObject->implicitHeight()); +} + +void tst_qdeclarativetext::testQtQuick11Attributes() +{ + QFETCH(QString, code); + QFETCH(QString, warning); + QFETCH(QString, error); + + QDeclarativeEngine engine; + QObject *obj; + + QDeclarativeComponent valid(&engine); + valid.setData("import QtQuick 1.1; Text { " + code.toUtf8() + " }", QUrl("")); + obj = valid.create(); + QVERIFY(obj); + QVERIFY(valid.errorString().isEmpty()); + delete obj; + + QDeclarativeComponent invalid(&engine); + invalid.setData("import QtQuick 1.0; Text { " + code.toUtf8() + " }", QUrl("")); + QTest::ignoreMessage(QtWarningMsg, warning.toUtf8()); + obj = invalid.create(); + QCOMPARE(invalid.errorString(), error); + delete obj; +} + +void tst_qdeclarativetext::testQtQuick11Attributes_data() +{ + QTest::addColumn<QString>("code"); + QTest::addColumn<QString>("warning"); + QTest::addColumn<QString>("error"); + + QTest::newRow("maximumLineCount") << "maximumLineCount: 4" + << "QDeclarativeComponent: Component is not ready" + << ":1 \"Text.maximumLineCount\" is not available in QtQuick 1.0.\n"; + + QTest::newRow("lineHeight") << "lineHeight: 2" + << "QDeclarativeComponent: Component is not ready" + << ":1 \"Text.lineHeight\" is not available in QtQuick 1.0.\n"; + + QTest::newRow("lineHeightMode") << "lineHeightMode: Text.MultiplyHeight" + << "QDeclarativeComponent: Component is not ready" + << ":1 \"Text.lineHeightMode\" is not available in QtQuick 1.0.\n"; + + QTest::newRow("lineCount") << "property int foo: lineCount" + << "<Unknown File>:1: ReferenceError: Can't find variable: lineCount" + << ""; + + QTest::newRow("truncated") << "property bool foo: truncated" + << "<Unknown File>:1: ReferenceError: Can't find variable: truncated" + << ""; } QTEST_MAIN(tst_qdeclarativetext) diff --git a/tests/auto/declarative/qdeclarativetextedit/data/horizontalAlignment_RightToLeft.qml b/tests/auto/declarative/qdeclarativetextedit/data/horizontalAlignment_RightToLeft.qml new file mode 100644 index 0000000..43ea8d8 --- /dev/null +++ b/tests/auto/declarative/qdeclarativetextedit/data/horizontalAlignment_RightToLeft.qml @@ -0,0 +1,23 @@ +import QtQuick 1.0 + +Rectangle { + id: top + width: 200; height: 70; + + property alias horizontalAlignment: text.horizontalAlignment + property string text: "اختبا" + + Rectangle { + anchors.centerIn: parent + width: 200 + height: 20 + color: "green" + + TextEdit { + id: text + objectName: "text" + anchors.fill: parent + text: top.text + } + } +} diff --git a/tests/auto/declarative/qdeclarativetextedit/data/mouseselectionmode_characters.qml b/tests/auto/declarative/qdeclarativetextedit/data/mouseselectionmode_characters.qml new file mode 100644 index 0000000..5784e19 --- /dev/null +++ b/tests/auto/declarative/qdeclarativetextedit/data/mouseselectionmode_characters.qml @@ -0,0 +1,8 @@ +import QtQuick 1.1 + +TextEdit { + focus: true + text: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" + selectByMouse: true + mouseSelectionMode: TextEdit.SelectCharacters +} diff --git a/tests/auto/declarative/qdeclarativetextedit/data/mouseselectionmode_default.qml b/tests/auto/declarative/qdeclarativetextedit/data/mouseselectionmode_default.qml new file mode 100644 index 0000000..1e5f4aa --- /dev/null +++ b/tests/auto/declarative/qdeclarativetextedit/data/mouseselectionmode_default.qml @@ -0,0 +1,7 @@ +import QtQuick 1.1 + +TextEdit { + focus: true + text: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" + selectByMouse: true +} diff --git a/tests/auto/declarative/qdeclarativetextedit/data/mouseselectionmode_words.qml b/tests/auto/declarative/qdeclarativetextedit/data/mouseselectionmode_words.qml new file mode 100644 index 0000000..4b25f2f --- /dev/null +++ b/tests/auto/declarative/qdeclarativetextedit/data/mouseselectionmode_words.qml @@ -0,0 +1,8 @@ +import QtQuick 1.1 + +TextEdit { + focus: true + text: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" + selectByMouse: true + mouseSelectionMode: TextEdit.SelectWords +} diff --git a/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp b/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp index ba1a95f..7d5101c 100644 --- a/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp +++ b/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp @@ -66,6 +66,8 @@ #define SRCDIR "." #endif +Q_DECLARE_METATYPE(QDeclarativeTextEdit::SelectionMode) + QString createExpectedFileIfNotFound(const QString& filebasename, const QImage& actual) { // XXX This will be replaced by some clever persistent platform image store. @@ -100,6 +102,7 @@ private slots: // ### these tests may be trivial void hAlign(); + void hAlign_RightToLeft(); void vAlign(); void font(); void color(); @@ -107,8 +110,15 @@ private slots: void persistentSelection(); void focusOnPress(); void selection(); + void moveCursorSelection_data(); + void moveCursorSelection(); + void moveCursorSelectionSequence_data(); + void moveCursorSelectionSequence(); void mouseSelection_data(); void mouseSelection(); + void mouseSelectionMode_data(); + void mouseSelectionMode(); + void dragMouseSelection(); void inputMethodHints(); void cursorDelegate(); @@ -122,6 +132,10 @@ private slots: void openInputPanelOnFocus(); void geometrySignals(); void pastingRichText_QTBUG_14003(); + void implicitSize_data(); + void implicitSize(); + void testQtQuick11Attributes(); + void testQtQuick11Attributes_data(); private: void simulateKey(QDeclarativeView *, int key); @@ -144,7 +158,9 @@ private: tst_qdeclarativetextedit::tst_qdeclarativetextedit() { standard << "the quick brown fox jumped over the lazy dog" - << "the quick brown fox\n jumped over the lazy dog"; + << "the quick brown fox\n jumped over the lazy dog" + << "Hello, world!" + << "!dlrow ,olleH"; 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>"; @@ -413,6 +429,30 @@ void tst_qdeclarativetextedit::hAlign() } +void tst_qdeclarativetextedit::hAlign_RightToLeft() +{ + QDeclarativeView *canvas = createView(SRCDIR "/data/horizontalAlignment_RightToLeft.qml"); + QDeclarativeTextEdit *textEdit = canvas->rootObject()->findChild<QDeclarativeTextEdit*>("text"); + QVERIFY(textEdit != 0); + canvas->show(); + + QVERIFY(textEdit->positionToRectangle(0).x() > canvas->width()/2); + + // "Right" align + textEdit->setHAlign(QDeclarativeTextEdit::AlignRight); + QCOMPARE(textEdit->hAlign(), QDeclarativeTextEdit::AlignRight); + QVERIFY(textEdit->positionToRectangle(0).x() < canvas->width()/2); + + // Center align + // Note that position 0 is on the right-hand side + textEdit->setHAlign(QDeclarativeTextEdit::AlignHCenter); + QCOMPARE(textEdit->hAlign(), QDeclarativeTextEdit::AlignHCenter); + QVERIFY(textEdit->positionToRectangle(0).x() - textEdit->width() < canvas->width()/2); + QVERIFY(textEdit->positionToRectangle(0).x() > canvas->width()/2); + + delete canvas; +} + void tst_qdeclarativetextedit::vAlign() { //test one align each, and then test if two align fails. @@ -704,8 +744,351 @@ void tst_qdeclarativetextedit::selection() QVERIFY(textEditObject->selectedText().size() == 10); textEditObject->select(0,100); QVERIFY(textEditObject->selectedText().size() == 10); + + textEditObject->deselect(); + QVERIFY(textEditObject->selectedText().isNull()); + textEditObject->select(0,10); + QVERIFY(textEditObject->selectedText().size() == 10); + textEditObject->deselect(); + QVERIFY(textEditObject->selectedText().isNull()); +} + +void tst_qdeclarativetextedit::moveCursorSelection_data() +{ + QTest::addColumn<QString>("testStr"); + QTest::addColumn<int>("cursorPosition"); + QTest::addColumn<int>("movePosition"); + QTest::addColumn<QDeclarativeTextEdit::SelectionMode>("mode"); + QTest::addColumn<int>("selectionStart"); + QTest::addColumn<int>("selectionEnd"); + QTest::addColumn<bool>("reversible"); + + QTest::newRow("(t)he|characters") + << standard[0] << 0 << 1 << QDeclarativeTextEdit::SelectCharacters << 0 << 1 << true; + QTest::newRow("do(g)|characters") + << standard[0] << 43 << 44 << QDeclarativeTextEdit::SelectCharacters << 43 << 44 << true; + QTest::newRow("jum(p)ed|characters") + << standard[0] << 23 << 24 << QDeclarativeTextEdit::SelectCharacters << 23 << 24 << true; + QTest::newRow("jumped( )over|characters") + << standard[0] << 26 << 27 << QDeclarativeTextEdit::SelectCharacters << 26 << 27 << true; + QTest::newRow("(the )|characters") + << standard[0] << 0 << 4 << QDeclarativeTextEdit::SelectCharacters << 0 << 4 << true; + QTest::newRow("( dog)|characters") + << standard[0] << 40 << 44 << QDeclarativeTextEdit::SelectCharacters << 40 << 44 << true; + QTest::newRow("( jumped )|characters") + << standard[0] << 19 << 27 << QDeclarativeTextEdit::SelectCharacters << 19 << 27 << true; + QTest::newRow("th(e qu)ick|characters") + << standard[0] << 2 << 6 << QDeclarativeTextEdit::SelectCharacters << 2 << 6 << true; + QTest::newRow("la(zy d)og|characters") + << standard[0] << 38 << 42 << QDeclarativeTextEdit::SelectCharacters << 38 << 42 << true; + QTest::newRow("jum(ped ov)er|characters") + << standard[0] << 23 << 29 << QDeclarativeTextEdit::SelectCharacters << 23 << 29 << true; + QTest::newRow("()the|characters") + << standard[0] << 0 << 0 << QDeclarativeTextEdit::SelectCharacters << 0 << 0 << true; + QTest::newRow("dog()|characters") + << standard[0] << 44 << 44 << QDeclarativeTextEdit::SelectCharacters << 44 << 44 << true; + QTest::newRow("jum()ped|characters") + << standard[0] << 23 << 23 << QDeclarativeTextEdit::SelectCharacters << 23 << 23 << true; + + QTest::newRow("<(t)he>|words") + << standard[0] << 0 << 1 << QDeclarativeTextEdit::SelectWords << 0 << 3 << true; + QTest::newRow("<do(g)>|words") + << standard[0] << 43 << 44 << QDeclarativeTextEdit::SelectWords << 41 << 44 << true; + QTest::newRow("<jum(p)ed>|words") + << standard[0] << 23 << 24 << QDeclarativeTextEdit::SelectWords << 20 << 26 << true; + QTest::newRow("<jumped( )>over|words") + << standard[0] << 26 << 27 << QDeclarativeTextEdit::SelectWords << 20 << 27 << false; + QTest::newRow("jumped<( )over>|words,reversed") + << standard[0] << 27 << 26 << QDeclarativeTextEdit::SelectWords << 26 << 31 << false; + QTest::newRow("<(the )>quick|words") + << standard[0] << 0 << 4 << QDeclarativeTextEdit::SelectWords << 0 << 4 << false; + QTest::newRow("<(the )quick>|words,reversed") + << standard[0] << 4 << 0 << QDeclarativeTextEdit::SelectWords << 0 << 9 << false; + QTest::newRow("<lazy( dog)>|words") + << standard[0] << 40 << 44 << QDeclarativeTextEdit::SelectWords << 36 << 44 << false; + QTest::newRow("lazy<( dog)>|words,reversed") + << standard[0] << 44 << 40 << QDeclarativeTextEdit::SelectWords << 40 << 44 << false; + QTest::newRow("<fox( jumped )>over|words") + << standard[0] << 19 << 27 << QDeclarativeTextEdit::SelectWords << 16 << 27 << false; + QTest::newRow("fox<( jumped )over>|words,reversed") + << standard[0] << 27 << 19 << QDeclarativeTextEdit::SelectWords << 19 << 31 << false; + QTest::newRow("<th(e qu)ick>|words") + << standard[0] << 2 << 6 << QDeclarativeTextEdit::SelectWords << 0 << 9 << true; + QTest::newRow("<la(zy d)og|words>") + << standard[0] << 38 << 42 << QDeclarativeTextEdit::SelectWords << 36 << 44 << true; + QTest::newRow("<jum(ped ov)er>|words") + << standard[0] << 23 << 29 << QDeclarativeTextEdit::SelectWords << 20 << 31 << true; + QTest::newRow("<()>the|words") + << standard[0] << 0 << 0 << QDeclarativeTextEdit::SelectWords << 0 << 0 << true; + QTest::newRow("dog<()>|words") + << standard[0] << 44 << 44 << QDeclarativeTextEdit::SelectWords << 44 << 44 << true; + QTest::newRow("jum<()>ped|words") + << standard[0] << 23 << 23 << QDeclarativeTextEdit::SelectWords << 23 << 23 << true; + + QTest::newRow("Hello<(,)> |words") + << standard[2] << 5 << 6 << QDeclarativeTextEdit::SelectWords << 5 << 6 << true; + QTest::newRow("Hello<(, )>world|words") + << standard[2] << 5 << 7 << QDeclarativeTextEdit::SelectWords << 5 << 7 << false; + QTest::newRow("Hello<(, )world>|words,reversed") + << standard[2] << 7 << 5 << QDeclarativeTextEdit::SelectWords << 5 << 12 << false; + QTest::newRow("<Hel(lo, )>world|words") + << standard[2] << 3 << 7 << QDeclarativeTextEdit::SelectWords << 0 << 7 << false; + QTest::newRow("<Hel(lo, )world>|words,reversed") + << standard[2] << 7 << 3 << QDeclarativeTextEdit::SelectWords << 0 << 12 << false; + QTest::newRow("<Hel(lo)>,|words") + << standard[2] << 3 << 5 << QDeclarativeTextEdit::SelectWords << 0 << 5 << true; + QTest::newRow("Hello<()>,|words") + << standard[2] << 5 << 5 << QDeclarativeTextEdit::SelectWords << 5 << 5 << true; + QTest::newRow("Hello,<()>|words") + << standard[2] << 6 << 6 << QDeclarativeTextEdit::SelectWords << 6 << 6 << true; + QTest::newRow("Hello<,( )>world|words") + << standard[2] << 6 << 7 << QDeclarativeTextEdit::SelectWords << 5 << 7 << false; + QTest::newRow("Hello,<( )world>|words,reversed") + << standard[2] << 7 << 6 << QDeclarativeTextEdit::SelectWords << 6 << 12 << false; + QTest::newRow("Hello<,( world)>|words") + << standard[2] << 6 << 12 << QDeclarativeTextEdit::SelectWords << 5 << 12 << false; + QTest::newRow("Hello,<( world)>|words,reversed") + << standard[2] << 12 << 6 << QDeclarativeTextEdit::SelectWords << 6 << 12 << false; + QTest::newRow("Hello<,( world!)>|words") + << standard[2] << 6 << 13 << QDeclarativeTextEdit::SelectWords << 5 << 13 << false; + QTest::newRow("Hello,<( world!)>|words,reversed") + << standard[2] << 13 << 6 << QDeclarativeTextEdit::SelectWords << 6 << 13 << false; + QTest::newRow("Hello<(, world!)>|words") + << standard[2] << 5 << 13 << QDeclarativeTextEdit::SelectWords << 5 << 13 << true; + QTest::newRow("world<(!)>|words") + << standard[2] << 12 << 13 << QDeclarativeTextEdit::SelectWords << 12 << 13 << true; + QTest::newRow("world!<()>)|words") + << standard[2] << 13 << 13 << QDeclarativeTextEdit::SelectWords << 13 << 13 << true; + QTest::newRow("world<()>!)|words") + << standard[2] << 12 << 12 << QDeclarativeTextEdit::SelectWords << 12 << 12 << true; + + QTest::newRow("<(,)>olleH |words") + << standard[3] << 7 << 8 << QDeclarativeTextEdit::SelectWords << 7 << 8 << true; + QTest::newRow("<dlrow( ,)>olleH|words") + << standard[3] << 6 << 8 << QDeclarativeTextEdit::SelectWords << 1 << 8 << false; + QTest::newRow("dlrow<( ,)>olleH|words,reversed") + << standard[3] << 8 << 6 << QDeclarativeTextEdit::SelectWords << 6 << 8 << false; + QTest::newRow("<dlrow( ,ol)leH>|words") + << standard[3] << 6 << 10 << QDeclarativeTextEdit::SelectWords << 1 << 13 << false; + QTest::newRow("dlrow<( ,ol)leH>|words,reversed") + << standard[3] << 10 << 6 << QDeclarativeTextEdit::SelectWords << 6 << 13 << false; + QTest::newRow(",<(ol)leH>,|words") + << standard[3] << 8 << 10 << QDeclarativeTextEdit::SelectWords << 8 << 13 << true; + QTest::newRow(",<()>olleH|words") + << standard[3] << 8 << 8 << QDeclarativeTextEdit::SelectWords << 8 << 8 << true; + QTest::newRow("<()>,olleH|words") + << standard[3] << 7 << 7 << QDeclarativeTextEdit::SelectWords << 7 << 7 << true; + QTest::newRow("<dlrow( )>,olleH|words") + << standard[3] << 6 << 7 << QDeclarativeTextEdit::SelectWords << 1 << 7 << false; + QTest::newRow("dlrow<( ),>olleH|words,reversed") + << standard[3] << 7 << 6 << QDeclarativeTextEdit::SelectWords << 6 << 8 << false; + QTest::newRow("<(dlrow )>,olleH|words") + << standard[3] << 1 << 7 << QDeclarativeTextEdit::SelectWords << 1 << 7 << false; + QTest::newRow("<(dlrow ),>olleH|words,reversed") + << standard[3] << 7 << 1 << QDeclarativeTextEdit::SelectWords << 1 << 8 << false; + QTest::newRow("<(!dlrow )>,olleH|words") + << standard[3] << 0 << 7 << QDeclarativeTextEdit::SelectWords << 0 << 7 << false; + QTest::newRow("<(!dlrow ),>olleH|words,reversed") + << standard[3] << 7 << 0 << QDeclarativeTextEdit::SelectWords << 0 << 8 << false; + QTest::newRow("(!dlrow ,)olleH|words") + << standard[3] << 0 << 8 << QDeclarativeTextEdit::SelectWords << 0 << 8 << true; + QTest::newRow("<(!)>dlrow|words") + << standard[3] << 0 << 1 << QDeclarativeTextEdit::SelectWords << 0 << 1 << true; + QTest::newRow("<()>!dlrow|words") + << standard[3] << 0 << 0 << QDeclarativeTextEdit::SelectWords << 0 << 0 << true; + QTest::newRow("!<()>dlrow|words") + << standard[3] << 1 << 1 << QDeclarativeTextEdit::SelectWords << 1 << 1 << true; +} + +void tst_qdeclarativetextedit::moveCursorSelection() +{ + QFETCH(QString, testStr); + QFETCH(int, cursorPosition); + QFETCH(int, movePosition); + QFETCH(QDeclarativeTextEdit::SelectionMode, mode); + QFETCH(int, selectionStart); + QFETCH(int, selectionEnd); + QFETCH(bool, reversible); + + QString componentStr = "import QtQuick 1.1\nTextEdit { text: \""+ testStr +"\"; }"; + QDeclarativeComponent textinputComponent(&engine); + textinputComponent.setData(componentStr.toLatin1(), QUrl()); + QDeclarativeTextEdit *texteditObject = qobject_cast<QDeclarativeTextEdit*>(textinputComponent.create()); + QVERIFY(texteditObject != 0); + + texteditObject->setCursorPosition(cursorPosition); + texteditObject->moveCursorSelection(movePosition, mode); + + QCOMPARE(texteditObject->selectedText(), testStr.mid(selectionStart, selectionEnd - selectionStart)); + QCOMPARE(texteditObject->selectionStart(), selectionStart); + QCOMPARE(texteditObject->selectionEnd(), selectionEnd); + + if (reversible) { + texteditObject->setCursorPosition(movePosition); + texteditObject->moveCursorSelection(cursorPosition, mode); + + QCOMPARE(texteditObject->selectedText(), testStr.mid(selectionStart, selectionEnd - selectionStart)); + QCOMPARE(texteditObject->selectionStart(), selectionStart); + QCOMPARE(texteditObject->selectionEnd(), selectionEnd); + } +} + +void tst_qdeclarativetextedit::moveCursorSelectionSequence_data() +{ + QTest::addColumn<QString>("testStr"); + QTest::addColumn<int>("cursorPosition"); + QTest::addColumn<int>("movePosition1"); + QTest::addColumn<int>("movePosition2"); + QTest::addColumn<int>("selection1Start"); + QTest::addColumn<int>("selection1End"); + QTest::addColumn<int>("selection2Start"); + QTest::addColumn<int>("selection2End"); + + QTest::newRow("the {<quick( bro)wn> f^ox} jumped|ltr") + << standard[0] + << 9 << 13 << 17 + << 4 << 15 + << 4 << 19; + QTest::newRow("the quick<( {bro)wn> f^ox} jumped|rtl") + << standard[0] + << 13 << 9 << 17 + << 9 << 15 + << 10 << 19; + QTest::newRow("the {<quick( bro)wn> ^}fox jumped|ltr") + << standard[0] + << 9 << 13 << 16 + << 4 << 15 + << 4 << 16; + QTest::newRow("the quick<( {bro)wn> ^}fox jumped|rtl") + << standard[0] + << 13 << 9 << 16 + << 9 << 15 + << 10 << 16; + QTest::newRow("the {<quick( bro)wn^>} fox jumped|ltr") + << standard[0] + << 9 << 13 << 15 + << 4 << 15 + << 4 << 15; + QTest::newRow("the quick<( {bro)wn^>} f^ox jumped|rtl") + << standard[0] + << 13 << 9 << 15 + << 9 << 15 + << 10 << 15; + QTest::newRow("the {<quick() ^}bro)wn> fox|ltr") + << standard[0] + << 9 << 13 << 10 + << 4 << 15 + << 4 << 10; + QTest::newRow("the quick<(^ {^bro)wn>} fox|rtl") + << standard[0] + << 13 << 9 << 10 + << 9 << 15 + << 10 << 15; + QTest::newRow("the {<quick^}( bro)wn> fox|ltr") + << standard[0] + << 9 << 13 << 9 + << 4 << 15 + << 4 << 9; + QTest::newRow("the quick{<(^ bro)wn>} fox|rtl") + << standard[0] + << 13 << 9 << 9 + << 9 << 15 + << 9 << 15; + QTest::newRow("the {<qui^ck}( bro)wn> fox|ltr") + << standard[0] + << 9 << 13 << 7 + << 4 << 15 + << 4 << 9; + QTest::newRow("the {<qui^ck}( bro)wn> fox|rtl") + << standard[0] + << 13 << 9 << 7 + << 9 << 15 + << 4 << 15; + QTest::newRow("the {<^quick}( bro)wn> fox|ltr") + << standard[0] + << 9 << 13 << 4 + << 4 << 15 + << 4 << 9; + QTest::newRow("the {<^quick}( bro)wn> fox|rtl") + << standard[0] + << 13 << 9 << 4 + << 9 << 15 + << 4 << 15; + QTest::newRow("the{^ <quick}( bro)wn> fox|ltr") + << standard[0] + << 9 << 13 << 3 + << 4 << 15 + << 3 << 9; + QTest::newRow("the{^ <quick}( bro)wn> fox|rtl") + << standard[0] + << 13 << 9 << 3 + << 9 << 15 + << 3 << 15; + QTest::newRow("{t^he <quick}( bro)wn> fox|ltr") + << standard[0] + << 9 << 13 << 1 + << 4 << 15 + << 0 << 9; + QTest::newRow("{t^he <quick}( bro)wn> fox|rtl") + << standard[0] + << 13 << 9 << 1 + << 9 << 15 + << 0 << 15; + + QTest::newRow("{<He(ll)o>, w^orld}!|ltr") + << standard[2] + << 2 << 4 << 8 + << 0 << 5 + << 0 << 12; + QTest::newRow("{<He(ll)o>, w^orld}!|rtl") + << standard[2] + << 4 << 2 << 8 + << 0 << 5 + << 0 << 12; + + QTest::newRow("!{dlro^w ,<o(ll)eH>}|ltr") + << standard[3] + << 9 << 11 << 5 + << 8 << 13 + << 1 << 13; + QTest::newRow("!{dlro^w ,<o(ll)eH>}|rtl") + << standard[3] + << 11 << 9 << 5 + << 8 << 13 + << 1 << 13; +} + +void tst_qdeclarativetextedit::moveCursorSelectionSequence() +{ + QFETCH(QString, testStr); + QFETCH(int, cursorPosition); + QFETCH(int, movePosition1); + QFETCH(int, movePosition2); + QFETCH(int, selection1Start); + QFETCH(int, selection1End); + QFETCH(int, selection2Start); + QFETCH(int, selection2End); + + QString componentStr = "import QtQuick 1.1\nTextEdit { text: \""+ testStr +"\"; }"; + QDeclarativeComponent texteditComponent(&engine); + texteditComponent.setData(componentStr.toLatin1(), QUrl()); + QDeclarativeTextEdit *texteditObject = qobject_cast<QDeclarativeTextEdit*>(texteditComponent.create()); + QVERIFY(texteditObject != 0); + + texteditObject->setCursorPosition(cursorPosition); + + texteditObject->moveCursorSelection(movePosition1, QDeclarativeTextEdit::SelectWords); + QCOMPARE(texteditObject->selectedText(), testStr.mid(selection1Start, selection1End - selection1Start)); + QCOMPARE(texteditObject->selectionStart(), selection1Start); + QCOMPARE(texteditObject->selectionEnd(), selection1End); + + texteditObject->moveCursorSelection(movePosition2, QDeclarativeTextEdit::SelectWords); + QCOMPARE(texteditObject->selectedText(), testStr.mid(selection2Start, selection2End - selection2Start)); + QCOMPARE(texteditObject->selectionStart(), selection2Start); + QCOMPARE(texteditObject->selectionEnd(), selection2End); } + void tst_qdeclarativetextedit::mouseSelection_data() { QTest::addColumn<QString>("qmlfile"); @@ -751,6 +1134,100 @@ void tst_qdeclarativetextedit::mouseSelection() delete canvas; } +void tst_qdeclarativetextedit::dragMouseSelection() +{ + QString qmlfile = SRCDIR "/data/mouseselection_true.qml"; + + QDeclarativeView *canvas = createView(qmlfile); + + canvas->show(); + QApplication::setActiveWindow(canvas); + QTest::qWaitForWindowShown(canvas); + QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(canvas)); + + QVERIFY(canvas->rootObject() != 0); + QDeclarativeTextEdit *textEditObject = qobject_cast<QDeclarativeTextEdit *>(canvas->rootObject()); + QVERIFY(textEditObject != 0); + + textEditObject->setAcceptDrops(true); + + // press-and-drag-and-release from x1 to x2 + int x1 = 10; + int x2 = 70; + int y = textEditObject->height()/2; + QTest::mousePress(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(x1,y))); + { + QMouseEvent mv(QEvent::MouseMove, canvas->mapFromScene(QPoint(x2,y)), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); + QApplication::sendEvent(canvas->viewport(), &mv); + } + QTest::mouseRelease(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(x2,y))); + QString str1 = textEditObject->selectedText(); + QVERIFY(str1.length() > 3); + + // press and drag the current selection. + x1 = 40; + x2 = 100; + QTest::mousePress(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(x1,y))); + { + QMouseEvent mv(QEvent::MouseMove, canvas->mapFromScene(QPoint(x2,y)), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); + QApplication::sendEvent(canvas->viewport(), &mv); + } + QTest::mouseRelease(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(x2,y))); + QString str2 = textEditObject->selectedText(); + QVERIFY(str2.length() > 3); + + QVERIFY(str1 != str2); // Verify the second press and drag is a new selection and doesn't not the first moved. +} + +void tst_qdeclarativetextedit::mouseSelectionMode_data() +{ + QTest::addColumn<QString>("qmlfile"); + QTest::addColumn<bool>("selectWords"); + + // import installed + QTest::newRow("SelectWords") << SRCDIR "/data/mouseselectionmode_words.qml" << true; + QTest::newRow("SelectCharacters") << SRCDIR "/data/mouseselectionmode_characters.qml" << false; + QTest::newRow("default") << SRCDIR "/data/mouseselectionmode_default.qml" << false; +} + +void tst_qdeclarativetextedit::mouseSelectionMode() +{ + QFETCH(QString, qmlfile); + QFETCH(bool, selectWords); + + QString text = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + + QDeclarativeView *canvas = createView(qmlfile); + + canvas->show(); + QApplication::setActiveWindow(canvas); + QTest::qWaitForWindowShown(canvas); + QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(canvas)); + + QVERIFY(canvas->rootObject() != 0); + QDeclarativeTextEdit *textEditObject = qobject_cast<QDeclarativeTextEdit *>(canvas->rootObject()); + QVERIFY(textEditObject != 0); + + // press-and-drag-and-release from x1 to x2 + int x1 = 10; + int x2 = 70; + int y = textEditObject->height()/2; + QTest::mousePress(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(x1,y))); + //QTest::mouseMove(canvas->viewport(), canvas->mapFromScene(QPoint(x2,y))); // doesn't work + QMouseEvent mv(QEvent::MouseMove, canvas->mapFromScene(QPoint(x2,y)), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); + QApplication::sendEvent(canvas->viewport(), &mv); + QTest::mouseRelease(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(x2,y))); + QString str = textEditObject->selectedText(); + if (selectWords) { + QCOMPARE(str, text); + } else { + QVERIFY(str.length() > 3); + QVERIFY(str != text); + } + + delete canvas; +} + void tst_qdeclarativetextedit::inputMethodHints() { QDeclarativeView *canvas = createView(SRCDIR "/data/inputmethodhints.qml"); @@ -906,10 +1383,18 @@ void tst_qdeclarativetextedit::copyAndPaste() { QCOMPARE(textEdit->selectedText(), QString("Hello world!")); QCOMPARE(textEdit->selectedText().length(), 12); textEdit->setCursorPosition(0); + QVERIFY(textEdit->canPaste()); textEdit->paste(); QCOMPARE(textEdit->text(), QString("Hello world!Hello world!")); QCOMPARE(textEdit->text().length(), 24); + // canPaste + QVERIFY(textEdit->canPaste()); + textEdit->setReadOnly(true); + QVERIFY(!textEdit->canPaste()); + textEdit->setReadOnly(false); + QVERIFY(textEdit->canPaste()); + // QTBUG-12339 // test that document and internal text attribute are in sync QDeclarativeItemPrivate* pri = QDeclarativeItemPrivate::get(textEdit); @@ -1191,6 +1676,16 @@ void tst_qdeclarativetextedit::openInputPanelOnFocus() QApplication::processEvents(); QVERIFY(view.inputContext() == 0); QVERIFY(!view.testAttribute(Qt::WA_InputMethodEnabled)); + + // input method should not be enabled + // if TextEdit is read only. + edit.setReadOnly(true); + ic.openInputPanelReceived = false; + edit.setFocus(true); + QApplication::processEvents(); + QCOMPARE(ic.openInputPanelReceived, false); + QVERIFY(view.inputContext() == 0); + QVERIFY(!view.testAttribute(Qt::WA_InputMethodEnabled)); } void tst_qdeclarativetextedit::geometrySignals() @@ -1224,6 +1719,84 @@ void tst_qdeclarativetextedit::pastingRichText_QTBUG_14003() #endif } +void tst_qdeclarativetextedit::implicitSize_data() +{ + QTest::addColumn<QString>("text"); + QTest::addColumn<QString>("wrap"); + QTest::newRow("plain") << "The quick red fox jumped over the lazy brown dog" << "TextEdit.NoWrap"; + QTest::newRow("richtext") << "<b>The quick red fox jumped over the lazy brown dog</b>" << "TextEdit.NoWrap"; + QTest::newRow("plain_wrap") << "The quick red fox jumped over the lazy brown dog" << "TextEdit.Wrap"; + QTest::newRow("richtext_wrap") << "<b>The quick red fox jumped over the lazy brown dog</b>" << "TextEdit.Wrap"; +} + +void tst_qdeclarativetextedit::implicitSize() +{ + QFETCH(QString, text); + QFETCH(QString, wrap); + QString componentStr = "import QtQuick 1.1\nTextEdit { text: \"" + text + "\"; width: 50; wrapMode: " + wrap + " }"; + QDeclarativeComponent textComponent(&engine); + textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QDeclarativeTextEdit *textObject = qobject_cast<QDeclarativeTextEdit*>(textComponent.create()); + + QVERIFY(textObject->width() < textObject->implicitWidth()); + QVERIFY(textObject->height() == textObject->implicitHeight()); + + textObject->resetWidth(); + QVERIFY(textObject->width() == textObject->implicitWidth()); + QVERIFY(textObject->height() == textObject->implicitHeight()); +} + +void tst_qdeclarativetextedit::testQtQuick11Attributes() +{ + QFETCH(QString, code); + QFETCH(QString, warning); + QFETCH(QString, error); + + QDeclarativeEngine engine; + QObject *obj; + + QDeclarativeComponent valid(&engine); + valid.setData("import QtQuick 1.1; TextEdit { " + code.toUtf8() + " }", QUrl("")); + obj = valid.create(); + QVERIFY(obj); + QVERIFY(valid.errorString().isEmpty()); + delete obj; + + QDeclarativeComponent invalid(&engine); + invalid.setData("import QtQuick 1.0; TextEdit { " + code.toUtf8() + " }", QUrl("")); + QTest::ignoreMessage(QtWarningMsg, warning.toUtf8()); + obj = invalid.create(); + QCOMPARE(invalid.errorString(), error); + delete obj; +} + +void tst_qdeclarativetextedit::testQtQuick11Attributes_data() +{ + QTest::addColumn<QString>("code"); + QTest::addColumn<QString>("warning"); + QTest::addColumn<QString>("error"); + + QTest::newRow("canPaste") << "property bool foo: canPaste" + << "<Unknown File>:1: ReferenceError: Can't find variable: canPaste" + << ""; + + QTest::newRow("lineCount") << "property int foo: lineCount" + << "<Unknown File>:1: ReferenceError: Can't find variable: lineCount" + << ""; + + QTest::newRow("moveCursorSelection") << "Component.onCompleted: moveCursorSelection(0, TextEdit.SelectCharacters)" + << "<Unknown File>:1: ReferenceError: Can't find variable: moveCursorSelection" + << ""; + + QTest::newRow("deselect") << "Component.onCompleted: deselect()" + << "<Unknown File>:1: ReferenceError: Can't find variable: deselect" + << ""; + + QTest::newRow("onLinkActivated") << "onLinkActivated: {}" + << "QDeclarativeComponent: Component is not ready" + << ":1 \"TextEdit.onLinkActivated\" is not available in QtQuick 1.0.\n"; +} + QTEST_MAIN(tst_qdeclarativetextedit) #include "tst_qdeclarativetextedit.moc" diff --git a/tests/auto/declarative/qdeclarativetextinput/data/horizontalAlignment_RightToLeft.qml b/tests/auto/declarative/qdeclarativetextinput/data/horizontalAlignment_RightToLeft.qml new file mode 100644 index 0000000..b11535e --- /dev/null +++ b/tests/auto/declarative/qdeclarativetextinput/data/horizontalAlignment_RightToLeft.qml @@ -0,0 +1,23 @@ +import QtQuick 1.0 + +Rectangle { + id: top + width: 200; height: 70; + + property alias horizontalAlignment: text.horizontalAlignment + property string text: "اختبا" + + Rectangle { + anchors.centerIn: parent + width: 180 + height: 20 + color: "green" + + TextInput { + id: text + objectName: "text" + anchors.fill: parent + text: top.text + } + } +} diff --git a/tests/auto/declarative/qdeclarativetextinput/data/mouseselection_true.qml b/tests/auto/declarative/qdeclarativetextinput/data/mouseselection_true.qml new file mode 100644 index 0000000..8115ba0 --- /dev/null +++ b/tests/auto/declarative/qdeclarativetextinput/data/mouseselection_true.qml @@ -0,0 +1,7 @@ +import QtQuick 1.0 + +TextInput { + focus: true + text: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" + selectByMouse: true +} diff --git a/tests/auto/declarative/qdeclarativetextinput/data/mouseselectionmode_characters.qml b/tests/auto/declarative/qdeclarativetextinput/data/mouseselectionmode_characters.qml new file mode 100644 index 0000000..0ffc6ff --- /dev/null +++ b/tests/auto/declarative/qdeclarativetextinput/data/mouseselectionmode_characters.qml @@ -0,0 +1,8 @@ +import QtQuick 1.1 + +TextInput { + focus: true + text: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" + selectByMouse: true + mouseSelectionMode: TextInput.SelectCharacters +} diff --git a/tests/auto/declarative/qdeclarativetextinput/data/mouseselectionmode_default.qml b/tests/auto/declarative/qdeclarativetextinput/data/mouseselectionmode_default.qml new file mode 100644 index 0000000..87c174b --- /dev/null +++ b/tests/auto/declarative/qdeclarativetextinput/data/mouseselectionmode_default.qml @@ -0,0 +1,7 @@ +import QtQuick 1.1 + +TextInput { + focus: true + text: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" + selectByMouse: true +} diff --git a/tests/auto/declarative/qdeclarativetextinput/data/mouseselectionmode_words.qml b/tests/auto/declarative/qdeclarativetextinput/data/mouseselectionmode_words.qml new file mode 100644 index 0000000..df69a7d --- /dev/null +++ b/tests/auto/declarative/qdeclarativetextinput/data/mouseselectionmode_words.qml @@ -0,0 +1,8 @@ +import QtQuick 1.1 + +TextInput { + focus: true + text: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" + selectByMouse: true + mouseSelectionMode: TextInput.SelectWords +} diff --git a/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp b/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp index 4ad055c..42a0659 100644 --- a/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp +++ b/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp @@ -57,6 +57,8 @@ #define SRCDIR "." #endif +Q_DECLARE_METATYPE(QDeclarativeTextInput::SelectionMode) + QString createExpectedFileIfNotFound(const QString& filebasename, const QImage& actual) { // XXX This will be replaced by some clever persistent platform image store. @@ -87,9 +89,17 @@ private slots: void font(); void color(); void selection(); + void moveCursorSelection_data(); + void moveCursorSelection(); + void moveCursorSelectionSequence_data(); + void moveCursorSelectionSequence(); + void dragMouseSelection(); + void mouseSelectionMode_data(); + void mouseSelectionMode(); void horizontalAlignment_data(); void horizontalAlignment(); + void horizontalAlignment_RightToLeft(); void positionAt(); @@ -111,6 +121,9 @@ private slots: void echoMode(); void geometrySignals(); + void testQtQuick11Attributes(); + void testQtQuick11Attributes_data(); + private: void simulateKey(QDeclarativeView *, int key); QDeclarativeView *createView(const QString &filename); @@ -124,7 +137,8 @@ tst_qdeclarativetextinput::tst_qdeclarativetextinput() { standard << "the quick brown fox jumped over the lazy dog" << "It's supercalifragisiticexpialidocious!" - << "Hello, world!"; + << "Hello, world!" + << "!dlrow ,olleH"; colorStrings << "aliceblue" << "antiquewhite" @@ -405,9 +419,447 @@ void tst_qdeclarativetextinput::selection() textinputObject->select(0,100); QVERIFY(textinputObject->selectedText().size() == 10); + textinputObject->deselect(); + QVERIFY(textinputObject->selectedText().isNull()); + textinputObject->select(0,10); + QVERIFY(textinputObject->selectedText().size() == 10); + textinputObject->deselect(); + QVERIFY(textinputObject->selectedText().isNull()); + delete textinputObject; } +void tst_qdeclarativetextinput::moveCursorSelection_data() +{ + QTest::addColumn<QString>("testStr"); + QTest::addColumn<int>("cursorPosition"); + QTest::addColumn<int>("movePosition"); + QTest::addColumn<QDeclarativeTextInput::SelectionMode>("mode"); + QTest::addColumn<int>("selectionStart"); + QTest::addColumn<int>("selectionEnd"); + QTest::addColumn<bool>("reversible"); + + QTest::newRow("(t)he|characters") + << standard[0] << 0 << 1 << QDeclarativeTextInput::SelectCharacters << 0 << 1 << true; + QTest::newRow("do(g)|characters") + << standard[0] << 43 << 44 << QDeclarativeTextInput::SelectCharacters << 43 << 44 << true; + QTest::newRow("jum(p)ed|characters") + << standard[0] << 23 << 24 << QDeclarativeTextInput::SelectCharacters << 23 << 24 << true; + QTest::newRow("jumped( )over|characters") + << standard[0] << 26 << 27 << QDeclarativeTextInput::SelectCharacters << 26 << 27 << true; + QTest::newRow("(the )|characters") + << standard[0] << 0 << 4 << QDeclarativeTextInput::SelectCharacters << 0 << 4 << true; + QTest::newRow("( dog)|characters") + << standard[0] << 40 << 44 << QDeclarativeTextInput::SelectCharacters << 40 << 44 << true; + QTest::newRow("( jumped )|characters") + << standard[0] << 19 << 27 << QDeclarativeTextInput::SelectCharacters << 19 << 27 << true; + QTest::newRow("th(e qu)ick|characters") + << standard[0] << 2 << 6 << QDeclarativeTextInput::SelectCharacters << 2 << 6 << true; + QTest::newRow("la(zy d)og|characters") + << standard[0] << 38 << 42 << QDeclarativeTextInput::SelectCharacters << 38 << 42 << true; + QTest::newRow("jum(ped ov)er|characters") + << standard[0] << 23 << 29 << QDeclarativeTextInput::SelectCharacters << 23 << 29 << true; + QTest::newRow("()the|characters") + << standard[0] << 0 << 0 << QDeclarativeTextInput::SelectCharacters << 0 << 0 << true; + QTest::newRow("dog()|characters") + << standard[0] << 44 << 44 << QDeclarativeTextInput::SelectCharacters << 44 << 44 << true; + QTest::newRow("jum()ped|characters") + << standard[0] << 23 << 23 << QDeclarativeTextInput::SelectCharacters << 23 << 23 << true; + + QTest::newRow("<(t)he>|words") + << standard[0] << 0 << 1 << QDeclarativeTextInput::SelectWords << 0 << 3 << true; + QTest::newRow("<do(g)>|words") + << standard[0] << 43 << 44 << QDeclarativeTextInput::SelectWords << 41 << 44 << true; + QTest::newRow("<jum(p)ed>|words") + << standard[0] << 23 << 24 << QDeclarativeTextInput::SelectWords << 20 << 26 << true; + QTest::newRow("<jumped( )>over|words,ltr") + << standard[0] << 26 << 27 << QDeclarativeTextInput::SelectWords << 20 << 27 << false; + QTest::newRow("jumped<( )over>|words,rtl") + << standard[0] << 27 << 26 << QDeclarativeTextInput::SelectWords << 26 << 31 << false; + QTest::newRow("<(the )>quick|words,ltr") + << standard[0] << 0 << 4 << QDeclarativeTextInput::SelectWords << 0 << 4 << false; + QTest::newRow("<(the )quick>|words,rtl") + << standard[0] << 4 << 0 << QDeclarativeTextInput::SelectWords << 0 << 9 << false; + QTest::newRow("<lazy( dog)>|words,ltr") + << standard[0] << 40 << 44 << QDeclarativeTextInput::SelectWords << 36 << 44 << false; + QTest::newRow("lazy<( dog)>|words,rtl") + << standard[0] << 44 << 40 << QDeclarativeTextInput::SelectWords << 40 << 44 << false; + QTest::newRow("<fox( jumped )>over|words,ltr") + << standard[0] << 19 << 27 << QDeclarativeTextInput::SelectWords << 16 << 27 << false; + QTest::newRow("fox<( jumped )over>|words,rtl") + << standard[0] << 27 << 19 << QDeclarativeTextInput::SelectWords << 19 << 31 << false; + QTest::newRow("<th(e qu)ick>|words") + << standard[0] << 2 << 6 << QDeclarativeTextInput::SelectWords << 0 << 9 << true; + QTest::newRow("<la(zy d)og|words>") + << standard[0] << 38 << 42 << QDeclarativeTextInput::SelectWords << 36 << 44 << true; + QTest::newRow("<jum(ped ov)er>|words") + << standard[0] << 23 << 29 << QDeclarativeTextInput::SelectWords << 20 << 31 << true; + QTest::newRow("<()>the|words") + << standard[0] << 0 << 0 << QDeclarativeTextInput::SelectWords << 0 << 0 << true; + QTest::newRow("dog<()>|words") + << standard[0] << 44 << 44 << QDeclarativeTextInput::SelectWords << 44 << 44 << true; + QTest::newRow("jum<()>ped|words") + << standard[0] << 23 << 23 << QDeclarativeTextInput::SelectWords << 23 << 23 << true; + + QTest::newRow("Hello<(,)> |words") + << standard[2] << 5 << 6 << QDeclarativeTextInput::SelectWords << 5 << 6 << true; + QTest::newRow("Hello<(, )>world|words,ltr") + << standard[2] << 5 << 7 << QDeclarativeTextInput::SelectWords << 5 << 7 << false; + QTest::newRow("Hello<(, )world>|words,rtl") + << standard[2] << 7 << 5 << QDeclarativeTextInput::SelectWords << 5 << 12 << false; + QTest::newRow("<Hel(lo, )>world|words,ltr") + << standard[2] << 3 << 7 << QDeclarativeTextInput::SelectWords << 0 << 7 << false; + QTest::newRow("<Hel(lo, )world>|words,rtl") + << standard[2] << 7 << 3 << QDeclarativeTextInput::SelectWords << 0 << 12 << false; + QTest::newRow("<Hel(lo)>,|words") + << standard[2] << 3 << 5 << QDeclarativeTextInput::SelectWords << 0 << 5 << true; + QTest::newRow("Hello<()>,|words") + << standard[2] << 5 << 5 << QDeclarativeTextInput::SelectWords << 5 << 5 << true; + QTest::newRow("Hello,<()>|words") + << standard[2] << 6 << 6 << QDeclarativeTextInput::SelectWords << 6 << 6 << true; + QTest::newRow("Hello<,( )>world|words,ltr") + << standard[2] << 6 << 7 << QDeclarativeTextInput::SelectWords << 5 << 7 << false; + QTest::newRow("Hello,<( )world>|words,rtl") + << standard[2] << 7 << 6 << QDeclarativeTextInput::SelectWords << 6 << 12 << false; + QTest::newRow("Hello<,( world)>|words,ltr") + << standard[2] << 6 << 12 << QDeclarativeTextInput::SelectWords << 5 << 12 << false; + QTest::newRow("Hello,<( world)>|words,rtl") + << standard[2] << 12 << 6 << QDeclarativeTextInput::SelectWords << 6 << 12 << false; + QTest::newRow("Hello<,( world!)>|words,ltr") + << standard[2] << 6 << 13 << QDeclarativeTextInput::SelectWords << 5 << 13 << false; + QTest::newRow("Hello,<( world!)>|words,rtl") + << standard[2] << 13 << 6 << QDeclarativeTextInput::SelectWords << 6 << 13 << false; + QTest::newRow("Hello<(, world!)>|words") + << standard[2] << 5 << 13 << QDeclarativeTextInput::SelectWords << 5 << 13 << true; + // Fails due to an issue with QTextBoundaryFinder and punctuation at the end of strings. + // QTBUG-11365 + // QTest::newRow("world<(!)>|words") + // << standard[2] << 12 << 13 << QDeclarativeTextInput::SelectWords << 12 << 13 << true; + QTest::newRow("world!<()>)|words") + << standard[2] << 13 << 13 << QDeclarativeTextInput::SelectWords << 13 << 13 << true; + QTest::newRow("world<()>!)|words") + << standard[2] << 12 << 12 << QDeclarativeTextInput::SelectWords << 12 << 12 << true; + + QTest::newRow("<(,)>olleH |words") + << standard[3] << 7 << 8 << QDeclarativeTextInput::SelectWords << 7 << 8 << true; + QTest::newRow("<dlrow( ,)>olleH|words,ltr") + << standard[3] << 6 << 8 << QDeclarativeTextInput::SelectWords << 1 << 8 << false; + QTest::newRow("dlrow<( ,)>olleH|words,rtl") + << standard[3] << 8 << 6 << QDeclarativeTextInput::SelectWords << 6 << 8 << false; + QTest::newRow("<dlrow( ,ol)leH>|words,ltr") + << standard[3] << 6 << 10 << QDeclarativeTextInput::SelectWords << 1 << 13 << false; + QTest::newRow("dlrow<( ,ol)leH>|words,rtl") + << standard[3] << 10 << 6 << QDeclarativeTextInput::SelectWords << 6 << 13 << false; + QTest::newRow(",<(ol)leH>,|words") + << standard[3] << 8 << 10 << QDeclarativeTextInput::SelectWords << 8 << 13 << true; + QTest::newRow(",<()>olleH|words") + << standard[3] << 8 << 8 << QDeclarativeTextInput::SelectWords << 8 << 8 << true; + QTest::newRow("<()>,olleH|words") + << standard[3] << 7 << 7 << QDeclarativeTextInput::SelectWords << 7 << 7 << true; + QTest::newRow("<dlrow( )>,olleH|words,ltr") + << standard[3] << 6 << 7 << QDeclarativeTextInput::SelectWords << 1 << 7 << false; + QTest::newRow("dlrow<( ),>olleH|words,rtl") + << standard[3] << 7 << 6 << QDeclarativeTextInput::SelectWords << 6 << 8 << false; + QTest::newRow("<(dlrow )>,olleH|words,ltr") + << standard[3] << 1 << 7 << QDeclarativeTextInput::SelectWords << 1 << 7 << false; + QTest::newRow("<(dlrow ),>olleH|words,rtl") + << standard[3] << 7 << 1 << QDeclarativeTextInput::SelectWords << 1 << 8 << false; + QTest::newRow("<(!dlrow )>,olleH|words,ltr") + << standard[3] << 0 << 7 << QDeclarativeTextInput::SelectWords << 0 << 7 << false; + QTest::newRow("<(!dlrow ),>olleH|words,rtl") + << standard[3] << 7 << 0 << QDeclarativeTextInput::SelectWords << 0 << 8 << false; + QTest::newRow("(!dlrow ,)olleH|words") + << standard[3] << 0 << 8 << QDeclarativeTextInput::SelectWords << 0 << 8 << true; + QTest::newRow("<(!)>dlrow|words") + << standard[3] << 0 << 1 << QDeclarativeTextInput::SelectWords << 0 << 1 << true; + QTest::newRow("<()>!dlrow|words") + << standard[3] << 0 << 0 << QDeclarativeTextInput::SelectWords << 0 << 0 << true; + QTest::newRow("!<()>dlrow|words") + << standard[3] << 1 << 1 << QDeclarativeTextInput::SelectWords << 1 << 1 << true; +} + +void tst_qdeclarativetextinput::moveCursorSelection() +{ + QFETCH(QString, testStr); + QFETCH(int, cursorPosition); + QFETCH(int, movePosition); + QFETCH(QDeclarativeTextInput::SelectionMode, mode); + QFETCH(int, selectionStart); + QFETCH(int, selectionEnd); + QFETCH(bool, reversible); + + QString componentStr = "import QtQuick 1.1\nTextInput { text: \""+ testStr +"\"; }"; + QDeclarativeComponent textinputComponent(&engine); + textinputComponent.setData(componentStr.toLatin1(), QUrl()); + QDeclarativeTextInput *textinputObject = qobject_cast<QDeclarativeTextInput*>(textinputComponent.create()); + QVERIFY(textinputObject != 0); + + textinputObject->setCursorPosition(cursorPosition); + textinputObject->moveCursorSelection(movePosition, mode); + + QCOMPARE(textinputObject->selectedText(), testStr.mid(selectionStart, selectionEnd - selectionStart)); + QCOMPARE(textinputObject->selectionStart(), selectionStart); + QCOMPARE(textinputObject->selectionEnd(), selectionEnd); + + if (reversible) { + textinputObject->setCursorPosition(movePosition); + textinputObject->moveCursorSelection(cursorPosition, mode); + + QCOMPARE(textinputObject->selectedText(), testStr.mid(selectionStart, selectionEnd - selectionStart)); + QCOMPARE(textinputObject->selectionStart(), selectionStart); + QCOMPARE(textinputObject->selectionEnd(), selectionEnd); + } +} + +void tst_qdeclarativetextinput::moveCursorSelectionSequence_data() +{ + QTest::addColumn<QString>("testStr"); + QTest::addColumn<int>("cursorPosition"); + QTest::addColumn<int>("movePosition1"); + QTest::addColumn<int>("movePosition2"); + QTest::addColumn<int>("selection1Start"); + QTest::addColumn<int>("selection1End"); + QTest::addColumn<int>("selection2Start"); + QTest::addColumn<int>("selection2End"); + + QTest::newRow("the {<quick( bro)wn> f^ox} jumped|ltr") + << standard[0] + << 9 << 13 << 17 + << 4 << 15 + << 4 << 19; + QTest::newRow("the quick<( {bro)wn> f^ox} jumped|rtl") + << standard[0] + << 13 << 9 << 17 + << 9 << 15 + << 10 << 19; + QTest::newRow("the {<quick( bro)wn> ^}fox jumped|ltr") + << standard[0] + << 9 << 13 << 16 + << 4 << 15 + << 4 << 16; + QTest::newRow("the quick<( {bro)wn> ^}fox jumped|rtl") + << standard[0] + << 13 << 9 << 16 + << 9 << 15 + << 10 << 16; + QTest::newRow("the {<quick( bro)wn^>} fox jumped|ltr") + << standard[0] + << 9 << 13 << 15 + << 4 << 15 + << 4 << 15; + QTest::newRow("the quick<( {bro)wn^>} f^ox jumped|rtl") + << standard[0] + << 13 << 9 << 15 + << 9 << 15 + << 10 << 15; + QTest::newRow("the {<quick() ^}bro)wn> fox|ltr") + << standard[0] + << 9 << 13 << 10 + << 4 << 15 + << 4 << 10; + QTest::newRow("the quick<( {^bro)wn>} fox|rtl") + << standard[0] + << 13 << 9 << 10 + << 9 << 15 + << 10 << 15; + QTest::newRow("the {<quick^}( bro)wn> fox|ltr") + << standard[0] + << 9 << 13 << 9 + << 4 << 15 + << 4 << 9; + QTest::newRow("the quick{<(^ bro)wn>} fox|rtl") + << standard[0] + << 13 << 9 << 9 + << 9 << 15 + << 9 << 15; + QTest::newRow("the {<qui^ck}( bro)wn> fox|ltr") + << standard[0] + << 9 << 13 << 7 + << 4 << 15 + << 4 << 9; + QTest::newRow("the {<qui^ck}( bro)wn> fox|rtl") + << standard[0] + << 13 << 9 << 7 + << 9 << 15 + << 4 << 15; + QTest::newRow("the {<^quick}( bro)wn> fox|ltr") + << standard[0] + << 9 << 13 << 4 + << 4 << 15 + << 4 << 9; + QTest::newRow("the {<^quick}( bro)wn> fox|rtl") + << standard[0] + << 13 << 9 << 4 + << 9 << 15 + << 4 << 15; + QTest::newRow("the{^ <quick}( bro)wn> fox|ltr") + << standard[0] + << 9 << 13 << 3 + << 4 << 15 + << 3 << 9; + QTest::newRow("the{^ <quick}( bro)wn> fox|rtl") + << standard[0] + << 13 << 9 << 3 + << 9 << 15 + << 3 << 15; + QTest::newRow("{t^he <quick}( bro)wn> fox|ltr") + << standard[0] + << 9 << 13 << 1 + << 4 << 15 + << 0 << 9; + QTest::newRow("{t^he <quick}( bro)wn> fox|rtl") + << standard[0] + << 13 << 9 << 1 + << 9 << 15 + << 0 << 15; + + QTest::newRow("{<He(ll)o>, w^orld}!|ltr") + << standard[2] + << 2 << 4 << 8 + << 0 << 5 + << 0 << 12; + QTest::newRow("{<He(ll)o>, w^orld}!|rtl") + << standard[2] + << 4 << 2 << 8 + << 0 << 5 + << 0 << 12; + + QTest::newRow("!{dlro^w ,<o(ll)eH>}|ltr") + << standard[3] + << 9 << 11 << 5 + << 8 << 13 + << 1 << 13; + QTest::newRow("!{dlro^w ,<o(ll)eH>}|rtl") + << standard[3] + << 11 << 9 << 5 + << 8 << 13 + << 1 << 13; +} + +void tst_qdeclarativetextinput::moveCursorSelectionSequence() +{ + QFETCH(QString, testStr); + QFETCH(int, cursorPosition); + QFETCH(int, movePosition1); + QFETCH(int, movePosition2); + QFETCH(int, selection1Start); + QFETCH(int, selection1End); + QFETCH(int, selection2Start); + QFETCH(int, selection2End); + + QString componentStr = "import QtQuick 1.1\nTextInput { text: \""+ testStr +"\"; }"; + QDeclarativeComponent textinputComponent(&engine); + textinputComponent.setData(componentStr.toLatin1(), QUrl()); + QDeclarativeTextInput *textinputObject = qobject_cast<QDeclarativeTextInput*>(textinputComponent.create()); + QVERIFY(textinputObject != 0); + + textinputObject->setCursorPosition(cursorPosition); + + textinputObject->moveCursorSelection(movePosition1, QDeclarativeTextInput::SelectWords); + QCOMPARE(textinputObject->selectedText(), testStr.mid(selection1Start, selection1End - selection1Start)); + QCOMPARE(textinputObject->selectionStart(), selection1Start); + QCOMPARE(textinputObject->selectionEnd(), selection1End); + + textinputObject->moveCursorSelection(movePosition2, QDeclarativeTextInput::SelectWords); + QCOMPARE(textinputObject->selectedText(), testStr.mid(selection2Start, selection2End - selection2Start)); + QCOMPARE(textinputObject->selectionStart(), selection2Start); + QCOMPARE(textinputObject->selectionEnd(), selection2End); +} + +void tst_qdeclarativetextinput::dragMouseSelection() +{ + QString qmlfile = SRCDIR "/data/mouseselection_true.qml"; + + QDeclarativeView *canvas = createView(qmlfile); + + canvas->show(); + QApplication::setActiveWindow(canvas); + QTest::qWaitForWindowShown(canvas); + QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(canvas)); + + QVERIFY(canvas->rootObject() != 0); + QDeclarativeTextInput *textInputObject = qobject_cast<QDeclarativeTextInput *>(canvas->rootObject()); + QVERIFY(textInputObject != 0); + + // press-and-drag-and-release from x1 to x2 + int x1 = 10; + int x2 = 70; + int y = textInputObject->height()/2; + QTest::mousePress(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(x1,y))); + { + QMouseEvent mv(QEvent::MouseMove, canvas->mapFromScene(QPoint(x2,y)), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); + QApplication::sendEvent(canvas->viewport(), &mv); + } + QTest::mouseRelease(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(x2,y))); + + QString str1 = textInputObject->selectedText(); + QVERIFY(str1.length() > 3); + + // press and drag the current selection. + x1 = 40; + x2 = 100; + QTest::mousePress(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(x1,y))); + { + QMouseEvent mv(QEvent::MouseMove, canvas->mapFromScene(QPoint(x2,y)), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); + QApplication::sendEvent(canvas->viewport(), &mv); + } + QTest::mouseRelease(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(x2,y))); + QString str2 = textInputObject->selectedText(); + QVERIFY(str2.length() > 3); + + QVERIFY(str1 != str2); // Verify the second press and drag is a new selection and doesn't not the first moved. + delete canvas; +} + +void tst_qdeclarativetextinput::mouseSelectionMode_data() +{ + QTest::addColumn<QString>("qmlfile"); + QTest::addColumn<bool>("selectWords"); + + // import installed + QTest::newRow("SelectWords") << SRCDIR "/data/mouseselectionmode_words.qml" << true; + QTest::newRow("SelectCharacters") << SRCDIR "/data/mouseselectionmode_characters.qml" << false; + QTest::newRow("default") << SRCDIR "/data/mouseselectionmode_default.qml" << false; +} + +void tst_qdeclarativetextinput::mouseSelectionMode() +{ + QFETCH(QString, qmlfile); + QFETCH(bool, selectWords); + + QString text = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + + QDeclarativeView *canvas = createView(qmlfile); + + canvas->show(); + QApplication::setActiveWindow(canvas); + QTest::qWaitForWindowShown(canvas); + QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(canvas)); + + QVERIFY(canvas->rootObject() != 0); + QDeclarativeTextInput *textInputObject = qobject_cast<QDeclarativeTextInput *>(canvas->rootObject()); + QVERIFY(textInputObject != 0); + + // press-and-drag-and-release from x1 to x2 + int x1 = 10; + int x2 = 70; + int y = textInputObject->height()/2; + QTest::mousePress(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(x1,y))); + //QTest::mouseMove(canvas->viewport(), canvas->mapFromScene(QPoint(x2,y))); // doesn't work + QMouseEvent mv(QEvent::MouseMove, canvas->mapFromScene(QPoint(x2,y)), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); + QApplication::sendEvent(canvas->viewport(), &mv); + QTest::mouseRelease(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(x2,y))); + QString str = textInputObject->selectedText(); + if (selectWords) { + QCOMPARE(str, text); + } else { + QVERIFY(str.length() > 3); + QVERIFY(str != text); + } + + delete canvas; +} + void tst_qdeclarativetextinput::horizontalAlignment_data() { QTest::addColumn<int>("hAlign"); @@ -448,6 +900,31 @@ void tst_qdeclarativetextinput::horizontalAlignment() delete canvas; } +void tst_qdeclarativetextinput::horizontalAlignment_RightToLeft() +{ + QDeclarativeView *canvas = createView(SRCDIR "/data/horizontalAlignment_RightToLeft.qml"); + QDeclarativeTextInput *textInput = canvas->rootObject()->findChild<QDeclarativeTextInput*>("text"); + QVERIFY(textInput != 0); + canvas->show(); + + QDeclarativeTextInputPrivate *textInputPrivate = QDeclarativeTextInputPrivate::get(textInput); + QVERIFY(textInputPrivate != 0); + QVERIFY(-textInputPrivate->hscroll > canvas->width()/2); + + // "Right" Align + textInput->setHAlign(QDeclarativeTextInput::AlignRight); + QCOMPARE(textInput->hAlign(), QDeclarativeTextInput::AlignRight); + QVERIFY(-textInputPrivate->hscroll < canvas->width()/2); + + // Center Align + textInput->setHAlign(QDeclarativeTextInput::AlignHCenter); + QCOMPARE(textInput->hAlign(), QDeclarativeTextInput::AlignHCenter); + QVERIFY(-textInputPrivate->hscroll < canvas->width()/2); + QVERIFY(-textInputPrivate->hscroll + textInputPrivate->width() > canvas->width()/2); + + delete canvas; +} + void tst_qdeclarativetextinput::positionAt() { QDeclarativeView *canvas = createView(SRCDIR "/data/positionAt.qml"); @@ -739,10 +1216,18 @@ void tst_qdeclarativetextinput::copyAndPaste() { QCOMPARE(textInput->selectedText(), QString("Hello world!")); QCOMPARE(textInput->selectedText().length(), 12); textInput->setCursorPosition(0); + QVERIFY(textInput->canPaste()); textInput->paste(); QCOMPARE(textInput->text(), QString("Hello world!Hello world!")); QCOMPARE(textInput->text().length(), 24); + // can paste + QVERIFY(textInput->canPaste()); + textInput->setReadOnly(true); + QVERIFY(!textInput->canPaste()); + textInput->setReadOnly(false); + QVERIFY(textInput->canPaste()); + // select word textInput->setCursorPosition(0); textInput->selectWord(); @@ -760,6 +1245,7 @@ void tst_qdeclarativetextinput::copyAndPaste() { QClipboard *clipboard = QApplication::clipboard(); QVERIFY(clipboard); clipboard->clear(); + QVERIFY(!textInput->canPaste()); // test that copy functionality is disabled // when echo mode is set to hide text/password mode @@ -907,6 +1393,8 @@ void tst_qdeclarativetextinput::echoMode() input->setFocus(false); QVERIFY(input->hasActiveFocus() == false); QCOMPARE(input->displayText(), QLatin1String("Q")); + + delete canvas; } void tst_qdeclarativetextinput::simulateKey(QDeclarativeView *view, int key) @@ -1117,6 +1605,16 @@ void tst_qdeclarativetextinput::openInputPanelOnFocus() QApplication::processEvents(); QVERIFY(view.inputContext() == 0); QVERIFY(!view.testAttribute(Qt::WA_InputMethodEnabled)); + + // input method should not be enabled + // if TextEdit is read only. + input.setReadOnly(true); + ic.openInputPanelReceived = false; + input.setFocus(true); + QApplication::processEvents(); + QCOMPARE(ic.openInputPanelReceived, false); + QVERIFY(view.inputContext() == 0); + QVERIFY(!view.testAttribute(Qt::WA_InputMethodEnabled)); } class MyTextInput : public QDeclarativeTextInput @@ -1183,6 +1681,49 @@ void tst_qdeclarativetextinput::geometrySignals() delete o; } +void tst_qdeclarativetextinput::testQtQuick11Attributes() +{ + QFETCH(QString, code); + QFETCH(QString, warning); + QFETCH(QString, error); + + QDeclarativeEngine engine; + QObject *obj; + + QDeclarativeComponent valid(&engine); + valid.setData("import QtQuick 1.1; TextInput { " + code.toUtf8() + " }", QUrl("")); + obj = valid.create(); + QVERIFY(obj); + QVERIFY(valid.errorString().isEmpty()); + delete obj; + + QDeclarativeComponent invalid(&engine); + invalid.setData("import QtQuick 1.0; TextInput { " + code.toUtf8() + " }", QUrl("")); + QTest::ignoreMessage(QtWarningMsg, warning.toUtf8()); + obj = invalid.create(); + QCOMPARE(invalid.errorString(), error); + delete obj; +} + +void tst_qdeclarativetextinput::testQtQuick11Attributes_data() +{ + QTest::addColumn<QString>("code"); + QTest::addColumn<QString>("warning"); + QTest::addColumn<QString>("error"); + + QTest::newRow("canPaste") << "property bool foo: canPaste" + << "<Unknown File>:1: ReferenceError: Can't find variable: canPaste" + << ""; + + QTest::newRow("moveCursorSelection") << "Component.onCompleted: moveCursorSelection(0, TextEdit.SelectCharacters)" + << "<Unknown File>:1: ReferenceError: Can't find variable: moveCursorSelection" + << ""; + + QTest::newRow("deselect") << "Component.onCompleted: deselect()" + << "<Unknown File>:1: ReferenceError: Can't find variable: deselect" + << ""; +} + QTEST_MAIN(tst_qdeclarativetextinput) #include "tst_qdeclarativetextinput.moc" diff --git a/tests/auto/declarative/qdeclarativeview/tst_qdeclarativeview.cpp b/tests/auto/declarative/qdeclarativeview/tst_qdeclarativeview.cpp index 46c2a34..8385659 100644 --- a/tests/auto/declarative/qdeclarativeview/tst_qdeclarativeview.cpp +++ b/tests/auto/declarative/qdeclarativeview/tst_qdeclarativeview.cpp @@ -60,6 +60,7 @@ public: tst_QDeclarativeView(); private slots: + void scene(); void resizemodedeclarativeitem(); void resizemodegraphicswidget(); void errors(); @@ -74,6 +75,26 @@ tst_QDeclarativeView::tst_QDeclarativeView() { } +void tst_QDeclarativeView::scene() +{ + // QTBUG-14771 + QGraphicsScene scene; + scene.setItemIndexMethod(QGraphicsScene::NoIndex); + scene.setStickyFocus(true); + + QDeclarativeView *view = new QDeclarativeView(); + QVERIFY(view); + QVERIFY(view->scene()); + view->setScene(&scene); + QCOMPARE(view->scene(), &scene); + + view->setSource(QUrl::fromLocalFile(SRCDIR "/data/resizemodedeclarativeitem.qml")); + QDeclarativeItem* declarativeItem = qobject_cast<QDeclarativeItem*>(view->rootObject()); + QVERIFY(declarativeItem); + QVERIFY(scene.items().count() > 0); + QCOMPARE(scene.items().at(0), declarativeItem); +} + void tst_QDeclarativeView::resizemodedeclarativeitem() { QWidget window; diff --git a/tests/auto/declarative/qdeclarativexmllistmodel/data/model2.qml b/tests/auto/declarative/qdeclarativexmllistmodel/data/model2.qml deleted file mode 100644 index e56aafa..0000000 --- a/tests/auto/declarative/qdeclarativexmllistmodel/data/model2.qml +++ /dev/null @@ -1,11 +0,0 @@ -import QtQuick 1.0 - -XmlListModel { - source: "model.xml" - query: "/Pets/Pet" - XmlRole { name: "name"; query: "name/string()" } - XmlRole { name: "type"; query: "type/string()" } - XmlRole { name: "age"; query: "age/number()" } - XmlRole { name: "size"; query: "size/string()" } - XmlRole { name: "tricks"; query: "tricks/string()" } -} diff --git a/tests/auto/declarative/qdeclarativexmllistmodel/data/testtypes.qml b/tests/auto/declarative/qdeclarativexmllistmodel/data/testtypes.qml new file mode 100644 index 0000000..4dbcc02 --- /dev/null +++ b/tests/auto/declarative/qdeclarativexmllistmodel/data/testtypes.qml @@ -0,0 +1,8 @@ +import QtQuick 1.0 + +XmlListModel { + query: "/data" + XmlRole { name: "stringValue"; query: "a-string/string()" } + XmlRole { name: "numberValue"; query: "a-number/number()" } +} + diff --git a/tests/auto/declarative/qdeclarativexmllistmodel/tst_qdeclarativexmllistmodel.cpp b/tests/auto/declarative/qdeclarativexmllistmodel/tst_qdeclarativexmllistmodel.cpp index 41807bf..19d7967 100644 --- a/tests/auto/declarative/qdeclarativexmllistmodel/tst_qdeclarativexmllistmodel.cpp +++ b/tests/auto/declarative/qdeclarativexmllistmodel/tst_qdeclarativexmllistmodel.cpp @@ -40,6 +40,10 @@ ****************************************************************************/ #include <private/qdeclarativeengine_p.h> +#include <QtTest/QtTest> +#include <QtGlobal> +#include <math.h> + #include <qtest.h> #include <QtTest/qsignalspy.h> #include <QtDeclarative/qdeclarativenetworkaccessmanagerfactory.h> @@ -80,7 +84,8 @@ private slots: } void buildModel(); - void missingFields(); + void testTypes(); + void testTypes_data(); void cdata(); void attributes(); void roles(); @@ -202,27 +207,70 @@ void tst_qdeclarativexmllistmodel::buildModel() delete model; } -void tst_qdeclarativexmllistmodel::missingFields() +void tst_qdeclarativexmllistmodel::testTypes() { - QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/model2.qml")); + QFETCH(QString, xml); + QFETCH(QString, roleName); + QFETCH(QVariant, expectedValue); + + QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/testtypes.qml")); QDeclarativeXmlListModel *model = qobject_cast<QDeclarativeXmlListModel*>(component.create()); QVERIFY(model != 0); - QTRY_COMPARE(model->count(), 9); + model->setXml(xml.toUtf8()); + model->reload(); + QTRY_COMPARE(model->count(), 1); - QList<int> roles; - roles << Qt::UserRole << Qt::UserRole + 1 << Qt::UserRole + 2 << Qt::UserRole + 3 << Qt::UserRole + 4; - QHash<int, QVariant> data = model->data(5, roles); - QVERIFY(data.count() == 5); - QCOMPARE(data.value(Qt::UserRole+3).toString(), QLatin1String("")); - QCOMPARE(data.value(Qt::UserRole+4).toString(), QLatin1String("")); + int role = -1; + foreach (int i, model->roles()) { + if (model->toString(i) == roleName) { + role = i; + break; + } + } + QVERIFY(role >= 0); - data = model->data(7, roles); - QVERIFY(data.count() == 5); - QCOMPARE(data.value(Qt::UserRole+2).toString(), QLatin1String("")); + if (expectedValue.toString() == "nan") + QVERIFY(qIsNaN(model->data(0, role).toDouble())); + else + QCOMPARE(model->data(0, role), expectedValue); delete model; } +void tst_qdeclarativexmllistmodel::testTypes_data() +{ + QTest::addColumn<QString>("xml"); + QTest::addColumn<QString>("roleName"); + QTest::addColumn<QVariant>("expectedValue"); + + QTest::newRow("missing string field") << "<data></data>" + << "stringValue" << QVariant(""); + QTest::newRow("empty string") << "<data><a-string></a-string></data>" + << "stringValue" << QVariant(""); + QTest::newRow("1-char string") << "<data><a-string>5</a-string></data>" + << "stringValue" << QVariant("5"); + QTest::newRow("string ok") << "<data><a-string>abc def g</a-string></data>" + << "stringValue" << QVariant("abc def g"); + + QTest::newRow("missing number field") << "<data></data>" + << "numberValue" << QVariant(""); + double nan = qQNaN(); + QTest::newRow("empty number field") << "<data><a-number></a-number></data>" + << "numberValue" << QVariant(nan); + QTest::newRow("number field with string") << "<data><a-number>a string</a-number></data>" + << "numberValue" << QVariant(nan); + QTest::newRow("-1") << "<data><a-number>-1</a-number></data>" + << "numberValue" << QVariant("-1"); + QTest::newRow("-1.5") << "<data><a-number>-1.5</a-number></data>" + << "numberValue" << QVariant("-1.5"); + QTest::newRow("0") << "<data><a-number>0</a-number></data>" + << "numberValue" << QVariant("0"); + QTest::newRow("+1") << "<data><a-number>1</a-number></data>" + << "numberValue" << QVariant("1"); + QTest::newRow("+1.5") << "<data><a-number>1.5</a-number></data>" + << "numberValue" << QVariant("1.5"); +} + void tst_qdeclarativexmllistmodel::cdata() { QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/recipes.qml")); diff --git a/tests/auto/declarative/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp b/tests/auto/declarative/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp index 704fea0..06baed8 100644 --- a/tests/auto/declarative/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp +++ b/tests/auto/declarative/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp @@ -546,7 +546,6 @@ void tst_QMetaObjectBuilder::property() QVERIFY(!nullProp.isUser()); QVERIFY(!nullProp.hasStdCppSet()); QVERIFY(!nullProp.isEnumOrFlag()); - QVERIFY(!nullProp.isDynamic()); QCOMPARE(nullProp.index(), 0); // Add a property and check its attributes. @@ -564,7 +563,6 @@ void tst_QMetaObjectBuilder::property() QVERIFY(!prop1.isUser()); QVERIFY(!prop1.hasStdCppSet()); QVERIFY(!prop1.isEnumOrFlag()); - QVERIFY(!prop1.isDynamic()); QCOMPARE(prop1.index(), 0); QCOMPARE(builder.propertyCount(), 1); @@ -583,7 +581,6 @@ void tst_QMetaObjectBuilder::property() QVERIFY(!prop2.isUser()); QVERIFY(!prop2.hasStdCppSet()); QVERIFY(!prop2.isEnumOrFlag()); - QVERIFY(!prop2.isDynamic()); QCOMPARE(prop2.index(), 1); QCOMPARE(builder.propertyCount(), 2); @@ -605,7 +602,6 @@ void tst_QMetaObjectBuilder::property() prop1.setUser(true); prop1.setStdCppSet(true); prop1.setEnumOrFlag(true); - prop1.setDynamic(true); // Check that prop1 is changed, but prop2 is not. QCOMPARE(prop1.name(), QByteArray("foo")); @@ -620,7 +616,6 @@ void tst_QMetaObjectBuilder::property() QVERIFY(prop1.isUser()); QVERIFY(prop1.hasStdCppSet()); QVERIFY(prop1.isEnumOrFlag()); - QVERIFY(prop1.isDynamic()); QVERIFY(prop2.isReadable()); QVERIFY(prop2.isWritable()); QCOMPARE(prop2.name(), QByteArray("bar")); @@ -633,7 +628,6 @@ void tst_QMetaObjectBuilder::property() QVERIFY(!prop2.isUser()); QVERIFY(!prop2.hasStdCppSet()); QVERIFY(!prop2.isEnumOrFlag()); - QVERIFY(!prop2.isDynamic()); // Remove prop1 and check that prop2 becomes index 0. builder.removeProperty(0); @@ -649,7 +643,6 @@ void tst_QMetaObjectBuilder::property() QVERIFY(!prop2.isUser()); QVERIFY(!prop2.hasStdCppSet()); QVERIFY(!prop2.isEnumOrFlag()); - QVERIFY(!prop2.isDynamic()); QCOMPARE(prop2.index(), 0); // Perform index-based lookup again. @@ -673,7 +666,6 @@ void tst_QMetaObjectBuilder::property() prop2.setUser(false); \ prop2.setStdCppSet(false); \ prop2.setEnumOrFlag(false); \ - prop2.setDynamic(false); \ } while (0) #define COUNT_FLAGS() \ ((prop2.isReadable() ? 1 : 0) + \ @@ -685,8 +677,7 @@ void tst_QMetaObjectBuilder::property() (prop2.isEditable() ? 1 : 0) + \ (prop2.isUser() ? 1 : 0) + \ (prop2.hasStdCppSet() ? 1 : 0) + \ - (prop2.isEnumOrFlag() ? 1 : 0) + \ - (prop2.isDynamic() ? 1 : 0)) + (prop2.isEnumOrFlag() ? 1 : 0)) #define CHECK_FLAG(setFunc,isFunc) \ do { \ CLEAR_FLAGS(); \ @@ -705,7 +696,6 @@ void tst_QMetaObjectBuilder::property() CHECK_FLAG(setUser, isUser); CHECK_FLAG(setStdCppSet, hasStdCppSet); CHECK_FLAG(setEnumOrFlag, isEnumOrFlag); - CHECK_FLAG(setDynamic, isDynamic); // Check that nothing else changed. QVERIFY(checkForSideEffects(builder, QMetaObjectBuilder::Properties)); diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/align/data-MAC/justify.0.png b/tests/auto/declarative/qmlvisual/qdeclarativetext/align/data-MAC/justify.0.png Binary files differnew file mode 100644 index 0000000..74c6934 --- /dev/null +++ b/tests/auto/declarative/qmlvisual/qdeclarativetext/align/data-MAC/justify.0.png diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/align/data-MAC/justify.qml b/tests/auto/declarative/qmlvisual/qdeclarativetext/align/data-MAC/justify.qml new file mode 100644 index 0000000..e4dbeb1 --- /dev/null +++ b/tests/auto/declarative/qmlvisual/qdeclarativetext/align/data-MAC/justify.qml @@ -0,0 +1,11 @@ +import Qt.VisualTest 4.7 + +VisualTest { + Frame { + msec: 0 + } + Frame { + msec: 16 + image: "justify.0.png" + } +} diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/align/justify.qml b/tests/auto/declarative/qmlvisual/qdeclarativetext/align/justify.qml new file mode 100644 index 0000000..c3a7aaa --- /dev/null +++ b/tests/auto/declarative/qmlvisual/qdeclarativetext/align/justify.qml @@ -0,0 +1,22 @@ +import QtQuick 1.0 +import "../../shared" 1.0 + +Rectangle { + width: 450 + height: 250 + + TestText { + anchors.fill: parent + anchors { leftMargin: 10; rightMargin: 10; topMargin:10; bottomMargin: 10 } + wrapMode: Text.Wrap + horizontalAlignment: Text.AlignJustify + + text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin a aliquet massa. Integer id velit a nibh imperdiet sagittis. Cras fringilla enim non nulla porta bibendum. Integer risus urna, hendrerit non interdum ut, dapibus id velit. Nullam fermentum viverra pellentesque. In molestie scelerisque lorem molestie ultrices. Curabitur dolor arcu, tristique in sodales in, varius sed diam. Quisque magna velit, tincidunt sed ullamcorper sit amet, ornare adipiscing ligula. In hac habitasse platea dictumst. Ut tincidunt urna vel mauris fermentum ornare quis a ligula. Suspendisse cursus volutpat sapien eget cursus." + + Rectangle { + anchors.fill: parent + color: "transparent" + border.color: "red" + } + } +} diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/maximumLineCount/data-X11/newLines.0.png b/tests/auto/declarative/qmlvisual/qdeclarativetext/maximumLineCount/data-X11/newLines.0.png Binary files differnew file mode 100644 index 0000000..c24c7c6 --- /dev/null +++ b/tests/auto/declarative/qmlvisual/qdeclarativetext/maximumLineCount/data-X11/newLines.0.png diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/maximumLineCount/data-X11/newLines.qml b/tests/auto/declarative/qmlvisual/qdeclarativetext/maximumLineCount/data-X11/newLines.qml new file mode 100644 index 0000000..affd3a6 --- /dev/null +++ b/tests/auto/declarative/qmlvisual/qdeclarativetext/maximumLineCount/data-X11/newLines.qml @@ -0,0 +1,11 @@ +import Qt.VisualTest 4.7 + +VisualTest { + Frame { + msec: 0 + } + Frame { + msec: 16 + image: "newLines.0.png" + } +} diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/maximumLineCount/data-X11/newLines_wrap.0.png b/tests/auto/declarative/qmlvisual/qdeclarativetext/maximumLineCount/data-X11/newLines_wrap.0.png Binary files differnew file mode 100644 index 0000000..0ba68e5 --- /dev/null +++ b/tests/auto/declarative/qmlvisual/qdeclarativetext/maximumLineCount/data-X11/newLines_wrap.0.png diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/maximumLineCount/data-X11/newLines_wrap.qml b/tests/auto/declarative/qmlvisual/qdeclarativetext/maximumLineCount/data-X11/newLines_wrap.qml new file mode 100644 index 0000000..410b47d --- /dev/null +++ b/tests/auto/declarative/qmlvisual/qdeclarativetext/maximumLineCount/data-X11/newLines_wrap.qml @@ -0,0 +1,11 @@ +import Qt.VisualTest 4.7 + +VisualTest { + Frame { + msec: 0 + } + Frame { + msec: 16 + image: "newLines_wrap.0.png" + } +} diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/maximumLineCount/data-X11/newLines_wrap_elide.0.png b/tests/auto/declarative/qmlvisual/qdeclarativetext/maximumLineCount/data-X11/newLines_wrap_elide.0.png Binary files differnew file mode 100644 index 0000000..3f1144b --- /dev/null +++ b/tests/auto/declarative/qmlvisual/qdeclarativetext/maximumLineCount/data-X11/newLines_wrap_elide.0.png diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/maximumLineCount/data-X11/newLines_wrap_elide.qml b/tests/auto/declarative/qmlvisual/qdeclarativetext/maximumLineCount/data-X11/newLines_wrap_elide.qml new file mode 100644 index 0000000..94cf1d2 --- /dev/null +++ b/tests/auto/declarative/qmlvisual/qdeclarativetext/maximumLineCount/data-X11/newLines_wrap_elide.qml @@ -0,0 +1,11 @@ +import Qt.VisualTest 4.7 + +VisualTest { + Frame { + msec: 0 + } + Frame { + msec: 16 + image: "newLines_wrap_elide.0.png" + } +} diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/maximumLineCount/data-X11/wrap.0.png b/tests/auto/declarative/qmlvisual/qdeclarativetext/maximumLineCount/data-X11/wrap.0.png Binary files differnew file mode 100644 index 0000000..f0ad965 --- /dev/null +++ b/tests/auto/declarative/qmlvisual/qdeclarativetext/maximumLineCount/data-X11/wrap.0.png diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/maximumLineCount/data-X11/wrap.qml b/tests/auto/declarative/qmlvisual/qdeclarativetext/maximumLineCount/data-X11/wrap.qml new file mode 100644 index 0000000..4b55312 --- /dev/null +++ b/tests/auto/declarative/qmlvisual/qdeclarativetext/maximumLineCount/data-X11/wrap.qml @@ -0,0 +1,11 @@ +import Qt.VisualTest 4.7 + +VisualTest { + Frame { + msec: 0 + } + Frame { + msec: 16 + image: "wrap.0.png" + } +} diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/maximumLineCount/data-X11/wrap_elide.0.png b/tests/auto/declarative/qmlvisual/qdeclarativetext/maximumLineCount/data-X11/wrap_elide.0.png Binary files differnew file mode 100644 index 0000000..62274ce --- /dev/null +++ b/tests/auto/declarative/qmlvisual/qdeclarativetext/maximumLineCount/data-X11/wrap_elide.0.png diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/maximumLineCount/data-X11/wrap_elide.qml b/tests/auto/declarative/qmlvisual/qdeclarativetext/maximumLineCount/data-X11/wrap_elide.qml new file mode 100644 index 0000000..7d002ea --- /dev/null +++ b/tests/auto/declarative/qmlvisual/qdeclarativetext/maximumLineCount/data-X11/wrap_elide.qml @@ -0,0 +1,11 @@ +import Qt.VisualTest 4.7 + +VisualTest { + Frame { + msec: 0 + } + Frame { + msec: 16 + image: "wrap_elide.0.png" + } +} diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/maximumLineCount/data/newLines.0.png b/tests/auto/declarative/qmlvisual/qdeclarativetext/maximumLineCount/data/newLines.0.png Binary files differnew file mode 100644 index 0000000..c24c7c6 --- /dev/null +++ b/tests/auto/declarative/qmlvisual/qdeclarativetext/maximumLineCount/data/newLines.0.png diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/maximumLineCount/data/newLines.qml b/tests/auto/declarative/qmlvisual/qdeclarativetext/maximumLineCount/data/newLines.qml new file mode 100644 index 0000000..affd3a6 --- /dev/null +++ b/tests/auto/declarative/qmlvisual/qdeclarativetext/maximumLineCount/data/newLines.qml @@ -0,0 +1,11 @@ +import Qt.VisualTest 4.7 + +VisualTest { + Frame { + msec: 0 + } + Frame { + msec: 16 + image: "newLines.0.png" + } +} diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/maximumLineCount/data/newLines_wrap.0.png b/tests/auto/declarative/qmlvisual/qdeclarativetext/maximumLineCount/data/newLines_wrap.0.png Binary files differnew file mode 100644 index 0000000..0ba68e5 --- /dev/null +++ b/tests/auto/declarative/qmlvisual/qdeclarativetext/maximumLineCount/data/newLines_wrap.0.png diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/maximumLineCount/data/newLines_wrap.qml b/tests/auto/declarative/qmlvisual/qdeclarativetext/maximumLineCount/data/newLines_wrap.qml new file mode 100644 index 0000000..410b47d --- /dev/null +++ b/tests/auto/declarative/qmlvisual/qdeclarativetext/maximumLineCount/data/newLines_wrap.qml @@ -0,0 +1,11 @@ +import Qt.VisualTest 4.7 + +VisualTest { + Frame { + msec: 0 + } + Frame { + msec: 16 + image: "newLines_wrap.0.png" + } +} diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/maximumLineCount/data/newLines_wrap_elide.0.png b/tests/auto/declarative/qmlvisual/qdeclarativetext/maximumLineCount/data/newLines_wrap_elide.0.png Binary files differnew file mode 100644 index 0000000..3f1144b --- /dev/null +++ b/tests/auto/declarative/qmlvisual/qdeclarativetext/maximumLineCount/data/newLines_wrap_elide.0.png diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/maximumLineCount/data/newLines_wrap_elide.qml b/tests/auto/declarative/qmlvisual/qdeclarativetext/maximumLineCount/data/newLines_wrap_elide.qml new file mode 100644 index 0000000..94cf1d2 --- /dev/null +++ b/tests/auto/declarative/qmlvisual/qdeclarativetext/maximumLineCount/data/newLines_wrap_elide.qml @@ -0,0 +1,11 @@ +import Qt.VisualTest 4.7 + +VisualTest { + Frame { + msec: 0 + } + Frame { + msec: 16 + image: "newLines_wrap_elide.0.png" + } +} diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/maximumLineCount/data/wrap.0.png b/tests/auto/declarative/qmlvisual/qdeclarativetext/maximumLineCount/data/wrap.0.png Binary files differnew file mode 100644 index 0000000..f0ad965 --- /dev/null +++ b/tests/auto/declarative/qmlvisual/qdeclarativetext/maximumLineCount/data/wrap.0.png diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/maximumLineCount/data/wrap.qml b/tests/auto/declarative/qmlvisual/qdeclarativetext/maximumLineCount/data/wrap.qml new file mode 100644 index 0000000..4b55312 --- /dev/null +++ b/tests/auto/declarative/qmlvisual/qdeclarativetext/maximumLineCount/data/wrap.qml @@ -0,0 +1,11 @@ +import Qt.VisualTest 4.7 + +VisualTest { + Frame { + msec: 0 + } + Frame { + msec: 16 + image: "wrap.0.png" + } +} diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/maximumLineCount/data/wrap_elide.0.png b/tests/auto/declarative/qmlvisual/qdeclarativetext/maximumLineCount/data/wrap_elide.0.png Binary files differnew file mode 100644 index 0000000..62274ce --- /dev/null +++ b/tests/auto/declarative/qmlvisual/qdeclarativetext/maximumLineCount/data/wrap_elide.0.png diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/maximumLineCount/data/wrap_elide.qml b/tests/auto/declarative/qmlvisual/qdeclarativetext/maximumLineCount/data/wrap_elide.qml new file mode 100644 index 0000000..7d002ea --- /dev/null +++ b/tests/auto/declarative/qmlvisual/qdeclarativetext/maximumLineCount/data/wrap_elide.qml @@ -0,0 +1,11 @@ +import Qt.VisualTest 4.7 + +VisualTest { + Frame { + msec: 0 + } + Frame { + msec: 16 + image: "wrap_elide.0.png" + } +} diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/maximumLineCount/newLines.qml b/tests/auto/declarative/qmlvisual/qdeclarativetext/maximumLineCount/newLines.qml new file mode 100644 index 0000000..4e993c6 --- /dev/null +++ b/tests/auto/declarative/qmlvisual/qdeclarativetext/maximumLineCount/newLines.qml @@ -0,0 +1,13 @@ +import QtQuick 1.0 +import "../../shared" 1.0 + +Rectangle { + width: childrenRect.width + height: childrenRect.height + + TestText { + width: 80 + maximumLineCount: 2 + text: "Line1\nLine2\nLine3\nLine4" + } +} diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/maximumLineCount/newLines_wrap.qml b/tests/auto/declarative/qmlvisual/qdeclarativetext/maximumLineCount/newLines_wrap.qml new file mode 100644 index 0000000..5d8f50b --- /dev/null +++ b/tests/auto/declarative/qmlvisual/qdeclarativetext/maximumLineCount/newLines_wrap.qml @@ -0,0 +1,14 @@ +import QtQuick 1.0 +import "../../shared" 1.0 + +Rectangle { + width: childrenRect.width + height: childrenRect.height + + TestText { + width: 80 + maximumLineCount: 3 + wrapMode: Text.WordWrap + text: "Line1 has a more\nLine2\nLine3\nLine4" + } +} diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/maximumLineCount/newLines_wrap_elide.qml b/tests/auto/declarative/qmlvisual/qdeclarativetext/maximumLineCount/newLines_wrap_elide.qml new file mode 100644 index 0000000..ac7b5cb --- /dev/null +++ b/tests/auto/declarative/qmlvisual/qdeclarativetext/maximumLineCount/newLines_wrap_elide.qml @@ -0,0 +1,15 @@ +import QtQuick 1.0 +import "../../shared" 1.0 + +Rectangle { + width: childrenRect.width + height: childrenRect.height + + TestText { + width: 80 + maximumLineCount: 3 + wrapMode: Text.WordWrap + elide: Text.ElideRight + text: "Line1 has a more\nLine2\nLine3\nLine4" + } +} diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/maximumLineCount/wrap.qml b/tests/auto/declarative/qmlvisual/qdeclarativetext/maximumLineCount/wrap.qml new file mode 100644 index 0000000..6d72430 --- /dev/null +++ b/tests/auto/declarative/qmlvisual/qdeclarativetext/maximumLineCount/wrap.qml @@ -0,0 +1,14 @@ +import QtQuick 1.0 +import "../../shared" 1.0 + +Rectangle { + width: childrenRect.width + height: childrenRect.height + + TestText { + width: 80 + maximumLineCount: 3 + wrapMode: Text.WordWrap + text: "The quick brown fox jumped over the lazy dog" + } +} diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/maximumLineCount/wrap_elide.qml b/tests/auto/declarative/qmlvisual/qdeclarativetext/maximumLineCount/wrap_elide.qml new file mode 100644 index 0000000..785c5f5 --- /dev/null +++ b/tests/auto/declarative/qmlvisual/qdeclarativetext/maximumLineCount/wrap_elide.qml @@ -0,0 +1,15 @@ +import QtQuick 1.0 +import "../../shared" 1.0 + +Rectangle { + width: childrenRect.width + height: childrenRect.height + + TestText { + width: 80 + maximumLineCount: 3 + wrapMode: Text.WordWrap + elide: Text.ElideRight + text: "The quick brown fox jumped over the lazy dog" + } +} diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-MAC/justify.0.png b/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-MAC/justify.0.png Binary files differnew file mode 100644 index 0000000..74c6934 --- /dev/null +++ b/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-MAC/justify.0.png diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-MAC/justify.qml b/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-MAC/justify.qml new file mode 100644 index 0000000..e4dbeb1 --- /dev/null +++ b/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-MAC/justify.qml @@ -0,0 +1,11 @@ +import Qt.VisualTest 4.7 + +VisualTest { + Frame { + msec: 0 + } + Frame { + msec: 16 + image: "justify.0.png" + } +} diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/linkActivated.0.png b/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/linkActivated.0.png Binary files differnew file mode 100644 index 0000000..7d0d0ae --- /dev/null +++ b/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/linkActivated.0.png diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/linkActivated.1.png b/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/linkActivated.1.png Binary files differnew file mode 100644 index 0000000..7d612bf --- /dev/null +++ b/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/linkActivated.1.png diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/linkActivated.qml b/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/linkActivated.qml new file mode 100644 index 0000000..8c7e380 --- /dev/null +++ b/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-X11/linkActivated.qml @@ -0,0 +1,191 @@ +import Qt.VisualTest 4.7 + +VisualTest { + Frame { + msec: 0 + } + Frame { + msec: 16 + image: "linkActivated.0.png" + } + Frame { + msec: 32 + hash: "53d97d0966197ea41364511dea13752f" + } + Frame { + msec: 48 + hash: "53d97d0966197ea41364511dea13752f" + } + Frame { + msec: 64 + hash: "53d97d0966197ea41364511dea13752f" + } + Frame { + msec: 80 + hash: "53d97d0966197ea41364511dea13752f" + } + Frame { + msec: 96 + hash: "53d97d0966197ea41364511dea13752f" + } + Frame { + msec: 112 + hash: "53d97d0966197ea41364511dea13752f" + } + Frame { + msec: 128 + hash: "53d97d0966197ea41364511dea13752f" + } + Frame { + msec: 144 + hash: "53d97d0966197ea41364511dea13752f" + } + Frame { + msec: 160 + hash: "53d97d0966197ea41364511dea13752f" + } + Frame { + msec: 176 + hash: "53d97d0966197ea41364511dea13752f" + } + Frame { + msec: 192 + hash: "53d97d0966197ea41364511dea13752f" + } + Frame { + msec: 208 + hash: "53d97d0966197ea41364511dea13752f" + } + Frame { + msec: 224 + hash: "53d97d0966197ea41364511dea13752f" + } + Frame { + msec: 240 + hash: "53d97d0966197ea41364511dea13752f" + } + Frame { + msec: 256 + hash: "53d97d0966197ea41364511dea13752f" + } + Mouse { + type: 2 + button: 1 + buttons: 1 + x: 21; y: 13 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 272 + hash: "9482227cbc77e9083218c1452e8644d8" + } + Frame { + msec: 288 + hash: "9482227cbc77e9083218c1452e8644d8" + } + Frame { + msec: 304 + hash: "9482227cbc77e9083218c1452e8644d8" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 22; y: 11 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 320 + hash: "9482227cbc77e9083218c1452e8644d8" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 23; y: 10 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 3 + button: 1 + buttons: 0 + x: 23; y: 10 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 336 + hash: "29c47cec5d015e6cab0762c3db0fa714" + } + Frame { + msec: 352 + hash: "29c47cec5d015e6cab0762c3db0fa714" + } + Frame { + msec: 368 + hash: "29c47cec5d015e6cab0762c3db0fa714" + } + Frame { + msec: 384 + hash: "29c47cec5d015e6cab0762c3db0fa714" + } + Frame { + msec: 400 + hash: "29c47cec5d015e6cab0762c3db0fa714" + } + Frame { + msec: 416 + hash: "29c47cec5d015e6cab0762c3db0fa714" + } + Frame { + msec: 432 + hash: "29c47cec5d015e6cab0762c3db0fa714" + } + Frame { + msec: 448 + hash: "29c47cec5d015e6cab0762c3db0fa714" + } + Frame { + msec: 464 + hash: "29c47cec5d015e6cab0762c3db0fa714" + } + Frame { + msec: 480 + hash: "29c47cec5d015e6cab0762c3db0fa714" + } + Frame { + msec: 496 + hash: "29c47cec5d015e6cab0762c3db0fa714" + } + Frame { + msec: 512 + hash: "29c47cec5d015e6cab0762c3db0fa714" + } + Frame { + msec: 528 + hash: "29c47cec5d015e6cab0762c3db0fa714" + } + Frame { + msec: 544 + hash: "29c47cec5d015e6cab0762c3db0fa714" + } + Frame { + msec: 560 + hash: "29c47cec5d015e6cab0762c3db0fa714" + } + Frame { + msec: 576 + hash: "29c47cec5d015e6cab0762c3db0fa714" + } + Frame { + msec: 592 + hash: "29c47cec5d015e6cab0762c3db0fa714" + } + Frame { + msec: 608 + hash: "29c47cec5d015e6cab0762c3db0fa714" + } +} diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data/linkActivated.0.png b/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data/linkActivated.0.png Binary files differnew file mode 100644 index 0000000..7d0d0ae --- /dev/null +++ b/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data/linkActivated.0.png diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data/linkActivated.1.png b/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data/linkActivated.1.png Binary files differnew file mode 100644 index 0000000..7d612bf --- /dev/null +++ b/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data/linkActivated.1.png diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data/linkActivated.qml b/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data/linkActivated.qml new file mode 100644 index 0000000..8c7e380 --- /dev/null +++ b/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data/linkActivated.qml @@ -0,0 +1,191 @@ +import Qt.VisualTest 4.7 + +VisualTest { + Frame { + msec: 0 + } + Frame { + msec: 16 + image: "linkActivated.0.png" + } + Frame { + msec: 32 + hash: "53d97d0966197ea41364511dea13752f" + } + Frame { + msec: 48 + hash: "53d97d0966197ea41364511dea13752f" + } + Frame { + msec: 64 + hash: "53d97d0966197ea41364511dea13752f" + } + Frame { + msec: 80 + hash: "53d97d0966197ea41364511dea13752f" + } + Frame { + msec: 96 + hash: "53d97d0966197ea41364511dea13752f" + } + Frame { + msec: 112 + hash: "53d97d0966197ea41364511dea13752f" + } + Frame { + msec: 128 + hash: "53d97d0966197ea41364511dea13752f" + } + Frame { + msec: 144 + hash: "53d97d0966197ea41364511dea13752f" + } + Frame { + msec: 160 + hash: "53d97d0966197ea41364511dea13752f" + } + Frame { + msec: 176 + hash: "53d97d0966197ea41364511dea13752f" + } + Frame { + msec: 192 + hash: "53d97d0966197ea41364511dea13752f" + } + Frame { + msec: 208 + hash: "53d97d0966197ea41364511dea13752f" + } + Frame { + msec: 224 + hash: "53d97d0966197ea41364511dea13752f" + } + Frame { + msec: 240 + hash: "53d97d0966197ea41364511dea13752f" + } + Frame { + msec: 256 + hash: "53d97d0966197ea41364511dea13752f" + } + Mouse { + type: 2 + button: 1 + buttons: 1 + x: 21; y: 13 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 272 + hash: "9482227cbc77e9083218c1452e8644d8" + } + Frame { + msec: 288 + hash: "9482227cbc77e9083218c1452e8644d8" + } + Frame { + msec: 304 + hash: "9482227cbc77e9083218c1452e8644d8" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 22; y: 11 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 320 + hash: "9482227cbc77e9083218c1452e8644d8" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 23; y: 10 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 3 + button: 1 + buttons: 0 + x: 23; y: 10 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 336 + hash: "29c47cec5d015e6cab0762c3db0fa714" + } + Frame { + msec: 352 + hash: "29c47cec5d015e6cab0762c3db0fa714" + } + Frame { + msec: 368 + hash: "29c47cec5d015e6cab0762c3db0fa714" + } + Frame { + msec: 384 + hash: "29c47cec5d015e6cab0762c3db0fa714" + } + Frame { + msec: 400 + hash: "29c47cec5d015e6cab0762c3db0fa714" + } + Frame { + msec: 416 + hash: "29c47cec5d015e6cab0762c3db0fa714" + } + Frame { + msec: 432 + hash: "29c47cec5d015e6cab0762c3db0fa714" + } + Frame { + msec: 448 + hash: "29c47cec5d015e6cab0762c3db0fa714" + } + Frame { + msec: 464 + hash: "29c47cec5d015e6cab0762c3db0fa714" + } + Frame { + msec: 480 + hash: "29c47cec5d015e6cab0762c3db0fa714" + } + Frame { + msec: 496 + hash: "29c47cec5d015e6cab0762c3db0fa714" + } + Frame { + msec: 512 + hash: "29c47cec5d015e6cab0762c3db0fa714" + } + Frame { + msec: 528 + hash: "29c47cec5d015e6cab0762c3db0fa714" + } + Frame { + msec: 544 + hash: "29c47cec5d015e6cab0762c3db0fa714" + } + Frame { + msec: 560 + hash: "29c47cec5d015e6cab0762c3db0fa714" + } + Frame { + msec: 576 + hash: "29c47cec5d015e6cab0762c3db0fa714" + } + Frame { + msec: 592 + hash: "29c47cec5d015e6cab0762c3db0fa714" + } + Frame { + msec: 608 + hash: "29c47cec5d015e6cab0762c3db0fa714" + } +} diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetextedit/justify.qml b/tests/auto/declarative/qmlvisual/qdeclarativetextedit/justify.qml new file mode 100644 index 0000000..4aeb58c --- /dev/null +++ b/tests/auto/declarative/qmlvisual/qdeclarativetextedit/justify.qml @@ -0,0 +1,22 @@ +import QtQuick 1.0 +import "../shared" 1.0 + +Rectangle { + width: 450 + height: 250 + + TestTextEdit { + anchors.fill: parent + anchors { leftMargin: 10; rightMargin: 10; topMargin:10; bottomMargin: 10 } + wrapMode: Text.Wrap + horizontalAlignment: Text.AlignJustify + + text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin a aliquet massa. Integer id velit a nibh imperdiet sagittis. Cras fringilla enim non nulla porta bibendum. Integer risus urna, hendrerit non interdum ut, dapibus id velit. Nullam fermentum viverra pellentesque. In molestie scelerisque lorem molestie ultrices. Curabitur dolor arcu, tristique in sodales in, varius sed diam. Quisque magna velit, tincidunt sed ullamcorper sit amet, ornare adipiscing ligula. In hac habitasse platea dictumst. Ut tincidunt urna vel mauris fermentum ornare quis a ligula. Suspendisse cursus volutpat sapien eget cursus." + + Rectangle { + anchors.fill: parent + color: "transparent" + border.color: "red" + } + } +} diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetextedit/linkActivated.qml b/tests/auto/declarative/qmlvisual/qdeclarativetextedit/linkActivated.qml new file mode 100644 index 0000000..177d475 --- /dev/null +++ b/tests/auto/declarative/qmlvisual/qdeclarativetextedit/linkActivated.qml @@ -0,0 +1,15 @@ +import QtQuick 1.1 + +Rectangle{ + width: 100 + height: 100 + TextEdit{ + text: '<a href="clicked">Click Me</a> ' + onLinkActivated: txt.text=link; + } + Text{ + id: txt + y:50 + text: "unknown" + } +} diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-X11/qtbug-15818.0.png b/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-X11/qtbug-15818.0.png Binary files differnew file mode 100644 index 0000000..fc34b1a --- /dev/null +++ b/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-X11/qtbug-15818.0.png diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-X11/qtbug-15818.1.png b/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-X11/qtbug-15818.1.png Binary files differnew file mode 100644 index 0000000..fc34b1a --- /dev/null +++ b/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-X11/qtbug-15818.1.png diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-X11/qtbug-15818.2.png b/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-X11/qtbug-15818.2.png Binary files differnew file mode 100644 index 0000000..fc34b1a --- /dev/null +++ b/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-X11/qtbug-15818.2.png diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-X11/qtbug-15818.3.png b/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-X11/qtbug-15818.3.png Binary files differnew file mode 100644 index 0000000..fb2c90b --- /dev/null +++ b/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-X11/qtbug-15818.3.png diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-X11/qtbug-15818.4.png b/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-X11/qtbug-15818.4.png Binary files differnew file mode 100644 index 0000000..fb2c90b --- /dev/null +++ b/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-X11/qtbug-15818.4.png diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-X11/qtbug-15818.5.png b/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-X11/qtbug-15818.5.png Binary files differnew file mode 100644 index 0000000..e2231ff --- /dev/null +++ b/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-X11/qtbug-15818.5.png diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-X11/qtbug-15818.qml b/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-X11/qtbug-15818.qml new file mode 100644 index 0000000..790dffa --- /dev/null +++ b/tests/auto/declarative/qmlvisual/qdeclarativetextinput/data-X11/qtbug-15818.qml @@ -0,0 +1,1039 @@ +import Qt.VisualTest 4.7 + +VisualTest { + Frame { + msec: 0 + } + Frame { + msec: 16 + image: "qtbug-15818.0.png" + } + Frame { + msec: 32 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Frame { + msec: 48 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Frame { + msec: 64 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Frame { + msec: 80 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Frame { + msec: 96 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Frame { + msec: 112 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Frame { + msec: 128 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Frame { + msec: 144 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Frame { + msec: 160 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Frame { + msec: 176 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Frame { + msec: 192 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Frame { + msec: 208 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Frame { + msec: 224 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Frame { + msec: 240 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Frame { + msec: 256 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Frame { + msec: 272 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Frame { + msec: 288 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Frame { + msec: 304 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Frame { + msec: 320 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Frame { + msec: 336 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Frame { + msec: 352 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Frame { + msec: 368 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Frame { + msec: 384 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Frame { + msec: 400 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Frame { + msec: 416 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Frame { + msec: 432 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Frame { + msec: 448 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Frame { + msec: 464 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Frame { + msec: 480 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Frame { + msec: 496 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Frame { + msec: 512 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Frame { + msec: 528 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Frame { + msec: 544 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Frame { + msec: 560 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Frame { + msec: 576 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Frame { + msec: 592 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Frame { + msec: 608 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Frame { + msec: 624 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Frame { + msec: 640 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Frame { + msec: 656 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Frame { + msec: 672 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Frame { + msec: 688 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Frame { + msec: 704 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Frame { + msec: 720 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Frame { + msec: 736 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Frame { + msec: 752 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Frame { + msec: 768 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Frame { + msec: 784 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Frame { + msec: 800 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Frame { + msec: 816 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Frame { + msec: 832 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Frame { + msec: 848 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Frame { + msec: 864 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Frame { + msec: 880 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Mouse { + type: 2 + button: 1 + buttons: 1 + x: 26; y: 9 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 896 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Frame { + msec: 912 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Frame { + msec: 928 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 27; y: 9 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 3 + button: 1 + buttons: 0 + x: 27; y: 9 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 944 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Frame { + msec: 960 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Frame { + msec: 976 + image: "qtbug-15818.1.png" + } + Frame { + msec: 992 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Mouse { + type: 4 + button: 1 + buttons: 1 + x: 27; y: 9 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 1008 + hash: "8833dfac6aae78ce1309222cc4438e6f" + } + Frame { + msec: 1024 + hash: "8833dfac6aae78ce1309222cc4438e6f" + } + Frame { + msec: 1040 + hash: "8833dfac6aae78ce1309222cc4438e6f" + } + Frame { + msec: 1056 + hash: "8833dfac6aae78ce1309222cc4438e6f" + } + Frame { + msec: 1072 + hash: "8833dfac6aae78ce1309222cc4438e6f" + } + Frame { + msec: 1088 + hash: "8833dfac6aae78ce1309222cc4438e6f" + } + Frame { + msec: 1104 + hash: "8833dfac6aae78ce1309222cc4438e6f" + } + Mouse { + type: 3 + button: 1 + buttons: 0 + x: 27; y: 9 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 1120 + hash: "8833dfac6aae78ce1309222cc4438e6f" + } + Frame { + msec: 1136 + hash: "8833dfac6aae78ce1309222cc4438e6f" + } + Frame { + msec: 1152 + hash: "8833dfac6aae78ce1309222cc4438e6f" + } + Frame { + msec: 1168 + hash: "8833dfac6aae78ce1309222cc4438e6f" + } + Frame { + msec: 1184 + hash: "8833dfac6aae78ce1309222cc4438e6f" + } + Frame { + msec: 1200 + hash: "8833dfac6aae78ce1309222cc4438e6f" + } + Frame { + msec: 1216 + hash: "8833dfac6aae78ce1309222cc4438e6f" + } + Frame { + msec: 1232 + hash: "8833dfac6aae78ce1309222cc4438e6f" + } + Frame { + msec: 1248 + hash: "8833dfac6aae78ce1309222cc4438e6f" + } + Frame { + msec: 1264 + hash: "8833dfac6aae78ce1309222cc4438e6f" + } + Frame { + msec: 1280 + hash: "8833dfac6aae78ce1309222cc4438e6f" + } + Frame { + msec: 1296 + hash: "8833dfac6aae78ce1309222cc4438e6f" + } + Frame { + msec: 1312 + hash: "8833dfac6aae78ce1309222cc4438e6f" + } + Frame { + msec: 1328 + hash: "8833dfac6aae78ce1309222cc4438e6f" + } + Frame { + msec: 1344 + hash: "8833dfac6aae78ce1309222cc4438e6f" + } + Frame { + msec: 1360 + hash: "8833dfac6aae78ce1309222cc4438e6f" + } + Frame { + msec: 1376 + hash: "8833dfac6aae78ce1309222cc4438e6f" + } + Frame { + msec: 1392 + hash: "8833dfac6aae78ce1309222cc4438e6f" + } + Frame { + msec: 1408 + hash: "8833dfac6aae78ce1309222cc4438e6f" + } + Frame { + msec: 1424 + hash: "8833dfac6aae78ce1309222cc4438e6f" + } + Frame { + msec: 1440 + hash: "8833dfac6aae78ce1309222cc4438e6f" + } + Frame { + msec: 1456 + hash: "8833dfac6aae78ce1309222cc4438e6f" + } + Frame { + msec: 1472 + hash: "8833dfac6aae78ce1309222cc4438e6f" + } + Frame { + msec: 1488 + hash: "8833dfac6aae78ce1309222cc4438e6f" + } + Frame { + msec: 1504 + hash: "8833dfac6aae78ce1309222cc4438e6f" + } + Frame { + msec: 1520 + hash: "8833dfac6aae78ce1309222cc4438e6f" + } + Frame { + msec: 1536 + hash: "8833dfac6aae78ce1309222cc4438e6f" + } + Frame { + msec: 1552 + hash: "8833dfac6aae78ce1309222cc4438e6f" + } + Frame { + msec: 1568 + hash: "8833dfac6aae78ce1309222cc4438e6f" + } + Frame { + msec: 1584 + hash: "8833dfac6aae78ce1309222cc4438e6f" + } + Frame { + msec: 1600 + hash: "8833dfac6aae78ce1309222cc4438e6f" + } + Frame { + msec: 1616 + hash: "8833dfac6aae78ce1309222cc4438e6f" + } + Frame { + msec: 1632 + hash: "8833dfac6aae78ce1309222cc4438e6f" + } + Frame { + msec: 1648 + hash: "8833dfac6aae78ce1309222cc4438e6f" + } + Frame { + msec: 1664 + hash: "8833dfac6aae78ce1309222cc4438e6f" + } + Frame { + msec: 1680 + hash: "8833dfac6aae78ce1309222cc4438e6f" + } + Frame { + msec: 1696 + hash: "8833dfac6aae78ce1309222cc4438e6f" + } + Frame { + msec: 1712 + hash: "8833dfac6aae78ce1309222cc4438e6f" + } + Frame { + msec: 1728 + hash: "8833dfac6aae78ce1309222cc4438e6f" + } + Frame { + msec: 1744 + hash: "8833dfac6aae78ce1309222cc4438e6f" + } + Frame { + msec: 1760 + hash: "8833dfac6aae78ce1309222cc4438e6f" + } + Frame { + msec: 1776 + hash: "8833dfac6aae78ce1309222cc4438e6f" + } + Frame { + msec: 1792 + hash: "8833dfac6aae78ce1309222cc4438e6f" + } + Mouse { + type: 2 + button: 1 + buttons: 1 + x: 43; y: 9 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 1808 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Frame { + msec: 1824 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Frame { + msec: 1840 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Frame { + msec: 1856 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Frame { + msec: 1872 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Frame { + msec: 1888 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Mouse { + type: 3 + button: 1 + buttons: 0 + x: 43; y: 9 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 1904 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Frame { + msec: 1920 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Frame { + msec: 1936 + image: "qtbug-15818.2.png" + } + Frame { + msec: 1952 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Mouse { + type: 4 + button: 1 + buttons: 1 + x: 43; y: 9 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 1968 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 1984 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 2000 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 2016 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 2032 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 2048 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 2064 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Mouse { + type: 3 + button: 1 + buttons: 0 + x: 43; y: 9 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2080 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 2096 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 2112 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 2128 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 2144 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 2160 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 2176 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 2192 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 2208 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 2224 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 2240 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 2256 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 2272 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 2288 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 2304 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 2320 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 2336 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 2352 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 2368 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 2384 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 2400 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 2416 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 2432 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 2448 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 2464 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 2480 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 2496 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 2512 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 2528 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 2544 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 2560 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 2576 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 2592 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 2608 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 2624 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 2640 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 2656 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 2672 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 2688 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Mouse { + type: 2 + button: 1 + buttons: 1 + x: 54; y: 9 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2704 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Frame { + msec: 2720 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Frame { + msec: 2736 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Frame { + msec: 2752 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Frame { + msec: 2768 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Frame { + msec: 2784 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 55; y: 9 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 3 + button: 1 + buttons: 0 + x: 55; y: 9 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2800 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Frame { + msec: 2816 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Frame { + msec: 2832 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Frame { + msec: 2848 + hash: "0a63463fc1004efffd15f9524bcf3a29" + } + Mouse { + type: 4 + button: 1 + buttons: 1 + x: 55; y: 9 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2864 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 2880 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 2896 + image: "qtbug-15818.3.png" + } + Frame { + msec: 2912 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 2928 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 2944 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 2960 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 2976 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Mouse { + type: 3 + button: 1 + buttons: 0 + x: 55; y: 9 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2992 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 3008 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 3024 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 3040 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 3056 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 3072 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 3088 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 3104 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 3120 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 3136 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 3152 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 3168 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 3184 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 3200 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 3216 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 3232 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 3248 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 3264 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 3280 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 3296 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 3312 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 3328 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 3344 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 3360 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 3376 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 3392 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 3408 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 3424 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 3440 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 3456 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 3472 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 3488 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 3504 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 3520 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 3536 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 3552 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 3568 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 3584 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 3600 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 3616 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 3632 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 3648 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 3664 + hash: "270462ec02bce658757e0ea4fb2136b1" + } + Frame { + msec: 3680 + hash: "270462ec02bce658757e0ea4fb2136b1" + } +} diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetextinput/qtbug-15818.qml b/tests/auto/declarative/qmlvisual/qdeclarativetextinput/qtbug-15818.qml new file mode 100644 index 0000000..59710a4 --- /dev/null +++ b/tests/auto/declarative/qmlvisual/qdeclarativetextinput/qtbug-15818.qml @@ -0,0 +1,13 @@ +import QtQuick 1.1 +//Test that doubleclicking on the front of a word only selects that word, and not the word in front + +Item{ + width: 200 + height: 100 + TextInput{ + anchors.fill: parent + readOnly: true + selectByMouse: true + text: "abc a cba test" + } +} diff --git a/tests/auto/declarative/qmlvisual/qmlvisual.pro b/tests/auto/declarative/qmlvisual/qmlvisual.pro index cb7e5d7..b2c5b4f 100644 --- a/tests/auto/declarative/qmlvisual/qmlvisual.pro +++ b/tests/auto/declarative/qmlvisual/qmlvisual.pro @@ -19,7 +19,7 @@ symbian: { qdeclarativepathview \ qdeclarativepositioners \ qdeclarativesmoothedanimation \ - qdeclarativespringfollow \ + qdeclarativespringanimation \ qdeclarativetext \ qdeclarativetextedit \ qdeclarativetextinput \ diff --git a/tests/auto/declarative/qperformancetimer/qperformancetimer.pro b/tests/auto/declarative/qperformancetimer/qperformancetimer.pro new file mode 100644 index 0000000..656bf68 --- /dev/null +++ b/tests/auto/declarative/qperformancetimer/qperformancetimer.pro @@ -0,0 +1,7 @@ +load(qttest_p4) +contains(QT_CONFIG,declarative): QT += declarative +SOURCES += tst_qperformancetimer.cpp +macx:CONFIG -= app_bundle + +CONFIG += parallel_test + diff --git a/tests/auto/declarative/qperformancetimer/tst_qperformancetimer.cpp b/tests/auto/declarative/qperformancetimer/tst_qperformancetimer.cpp new file mode 100644 index 0000000..2029c8a --- /dev/null +++ b/tests/auto/declarative/qperformancetimer/tst_qperformancetimer.cpp @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <private/qperformancetimer_p.h> +#include <QObject> +#include <qtest.h> + +class tst_qperformancetimer : public QObject +{ + Q_OBJECT + +public: + tst_qperformancetimer() {} + +private slots: + void units(); +}; + +void tst_qperformancetimer::units() +{ + QPerformanceTimer timer; + timer.start(); + QTest::qWait(300); + qint64 elapsed = timer.elapsed(); + QVERIFY(elapsed > 300000000 && elapsed < 310000000); +} + +QTEST_MAIN(tst_qperformancetimer) + +#include "tst_qperformancetimer.moc" diff --git a/tests/auto/moc/tst_moc.cpp b/tests/auto/moc/tst_moc.cpp index 3e15bde..20fade1 100644 --- a/tests/auto/moc/tst_moc.cpp +++ b/tests/auto/moc/tst_moc.cpp @@ -493,6 +493,7 @@ private slots: void QTBUG5590_dummyProperty(); void QTBUG12260_defaultTemplate(); void notifyError(); + void revisions(); signals: void sigWithUnsignedArg(unsigned foo); void sigWithSignedArg(signed foo); @@ -507,6 +508,7 @@ private: bool user2() { return false; }; bool user3() { return false; }; bool userFunction(){ return false; }; + template <class T> void revisions_T(); private: QString qtIncludePath; @@ -1384,6 +1386,117 @@ void tst_Moc::notifyError() #endif } +// If changed, update VersionTestNotify below +class VersionTest : public QObject +{ + Q_OBJECT + Q_PROPERTY(int prop1 READ foo) + Q_PROPERTY(int prop2 READ foo REVISION 2) + Q_ENUMS(TestEnum); + +public: + int foo() const { return 0; } + + Q_INVOKABLE void method1() {} + Q_INVOKABLE Q_REVISION(4) void method2() {} + + enum TestEnum { One, Two }; + +public slots: + void slot1() {} + Q_REVISION(3) void slot2() {} + +signals: + void signal1(); + Q_REVISION(5) void signal2(); + +public slots Q_REVISION(6): + void slot3() {} + void slot4() {} + +signals Q_REVISION(7): + void signal3(); + void signal4(); +}; + +// If changed, update VersionTest above +class VersionTestNotify : public QObject +{ + Q_OBJECT + Q_PROPERTY(int prop1 READ foo NOTIFY fooChanged) + Q_PROPERTY(int prop2 READ foo REVISION 2) + Q_ENUMS(TestEnum); + +public: + int foo() const { return 0; } + + Q_INVOKABLE void method1() {} + Q_INVOKABLE Q_REVISION(4) void method2() {} + + enum TestEnum { One, Two }; + +public slots: + void slot1() {} + Q_REVISION(3) void slot2() {} + +signals: + void fooChanged(); + void signal1(); + Q_REVISION(5) void signal2(); + +public slots Q_REVISION(6): + void slot3() {} + void slot4() {} + +signals Q_REVISION(7): + void signal3(); + void signal4(); +}; + +template <class T> +void tst_Moc::revisions_T() +{ + int idx = T::staticMetaObject.indexOfProperty("prop1"); + QVERIFY(T::staticMetaObject.property(idx).revision() == 0); + idx = T::staticMetaObject.indexOfProperty("prop2"); + QVERIFY(T::staticMetaObject.property(idx).revision() == 2); + + idx = T::staticMetaObject.indexOfMethod("method1()"); + QVERIFY(T::staticMetaObject.method(idx).revision() == 0); + idx = T::staticMetaObject.indexOfMethod("method2()"); + QVERIFY(T::staticMetaObject.method(idx).revision() == 4); + + idx = T::staticMetaObject.indexOfSlot("slot1()"); + QVERIFY(T::staticMetaObject.method(idx).revision() == 0); + idx = T::staticMetaObject.indexOfSlot("slot2()"); + QVERIFY(T::staticMetaObject.method(idx).revision() == 3); + + idx = T::staticMetaObject.indexOfSlot("slot3()"); + QVERIFY(T::staticMetaObject.method(idx).revision() == 6); + idx = T::staticMetaObject.indexOfSlot("slot4()"); + QVERIFY(T::staticMetaObject.method(idx).revision() == 6); + + idx = T::staticMetaObject.indexOfSignal("signal1()"); + QVERIFY(T::staticMetaObject.method(idx).revision() == 0); + idx = T::staticMetaObject.indexOfSignal("signal2()"); + QVERIFY(T::staticMetaObject.method(idx).revision() == 5); + + idx = T::staticMetaObject.indexOfSignal("signal3()"); + QVERIFY(T::staticMetaObject.method(idx).revision() == 7); + idx = T::staticMetaObject.indexOfSignal("signal4()"); + QVERIFY(T::staticMetaObject.method(idx).revision() == 7); + + idx = T::staticMetaObject.indexOfEnumerator("TestEnum"); + QCOMPARE(T::staticMetaObject.enumerator(idx).keyCount(), 2); + QCOMPARE(T::staticMetaObject.enumerator(idx).key(0), "One"); +} + +// test using both class that has properties with and without NOTIFY signals +void tst_Moc::revisions() +{ + revisions_T<VersionTest>(); + revisions_T<VersionTestNotify>(); +} QTEST_APPLESS_MAIN(tst_Moc) #include "tst_moc.moc" diff --git a/tests/auto/qmutex/tst_qmutex.cpp b/tests/auto/qmutex/tst_qmutex.cpp index 3c4c767..ea983cb 100644 --- a/tests/auto/qmutex/tst_qmutex.cpp +++ b/tests/auto/qmutex/tst_qmutex.cpp @@ -67,6 +67,7 @@ private slots: void lock_unlock_locked_tryLock(); void stressTest(); void tryLockRace(); + void qtbug16115_trylock(); }; static const int iterations = 100; @@ -464,5 +465,42 @@ void tst_QMutex::tryLockRace() TryLockRaceThread::mutex.unlock(); } +static volatile int qtbug16115_trylock_counter; + +void tst_QMutex::qtbug16115_trylock() +{ + //Used to deadlock on unix + struct TrylockThread : QThread { + TrylockThread(QMutex &mut) : mut(mut) {} + QMutex &mut; + void run() { + for (int i = 0; i < 1000000; ++i) { + if (mut.tryLock(0)) { + Q_ASSERT((++qtbug16115_trylock_counter) == 1); + Q_ASSERT((--qtbug16115_trylock_counter) == 0); + mut.unlock(); + } + } + } + }; + QMutex mut; + TrylockThread t1(mut); + TrylockThread t2(mut); + TrylockThread t3(mut); + t1.start(); + t2.start(); + t3.start(); + + for (int i = 0; i < 1000000; ++i) { + mut.lock(); + Q_ASSERT((++qtbug16115_trylock_counter) == 1); + Q_ASSERT((--qtbug16115_trylock_counter) == 0); + mut.unlock(); + } + t1.wait(); + t2.wait(); + t3.wait(); +} + QTEST_MAIN(tst_QMutex) #include "tst_qmutex.moc" diff --git a/tests/auto/qthread/tst_qthread.cpp b/tests/auto/qthread/tst_qthread.cpp index c7036e4..e6bf9ce 100644 --- a/tests/auto/qthread/tst_qthread.cpp +++ b/tests/auto/qthread/tst_qthread.cpp @@ -86,7 +86,6 @@ private slots: void start(); void terminate(); void quit(); - void execAfterQuit(); void wait(); void started(); void finished(); @@ -266,34 +265,6 @@ public: } }; -class ExecAfterQuitThreadHelper: public QObject -{ - Q_OBJECT - QThread *thr; -public: - ExecAfterQuitThreadHelper(QThread *thr) : thr(thr) {} -public slots: - void doIt() { thr->exit(0); } -}; - -class ExecAfterQuitThread: public QThread -{ -public: - int returnValue; - void run() - { - ExecAfterQuitThreadHelper obj(this); - - QMetaObject::invokeMethod(&obj, "doIt", Qt::QueuedConnection); - exit(1); - - // returnValue will be either 0 or 1, depending on which of the two - // above take effect. The correct value is 0, since exit(1) before - // exec() should have no effect - returnValue = exec(); - } -}; - tst_QThread::tst_QThread() { @@ -453,52 +424,34 @@ void tst_QThread::stackSize() void tst_QThread::exit() { - { - Exit_Thread thread; - thread.object = new Exit_Object; - thread.object->moveToThread(&thread); - thread.code = 42; - thread.result = 0; - QVERIFY(!thread.isFinished()); - QVERIFY(!thread.isRunning()); - - QMutexLocker locker(&thread.mutex); - thread.start(); - QVERIFY(thread.isRunning()); - QVERIFY(!thread.isFinished()); - // but the thread is not running the event loop yet (the mutex is locked) - - // start the event loop - thread.cond.wait(locker.mutex()); - - // the Exit_Object above will cause the thread to exit - QVERIFY(thread.wait(five_minutes)); - QVERIFY(thread.isFinished()); - QVERIFY(!thread.isRunning()); - QCOMPARE(thread.result, thread.code); - delete thread.object; - } + Exit_Thread thread; + thread.object = new Exit_Object; + thread.object->moveToThread(&thread); + thread.code = 42; + thread.result = 0; + QVERIFY(!thread.isFinished()); + QVERIFY(!thread.isRunning()); + QMutexLocker locker(&thread.mutex); + thread.start(); + QVERIFY(thread.isRunning()); + QVERIFY(!thread.isFinished()); + thread.cond.wait(locker.mutex()); + QVERIFY(thread.wait(five_minutes)); + QVERIFY(thread.isFinished()); + QVERIFY(!thread.isRunning()); + QCOMPARE(thread.result, thread.code); + delete thread.object; - { - Exit_Thread thread2; - thread2.object = 0; - thread2.code = 53; - thread2.result = 0; - QMutexLocker locker2(&thread2.mutex); - thread2.start(); - - // the mutex is locked, so the thread has *not* started running the event loop yet - // this will do nothing: - thread2.exit(thread2.code); - - // the thread will now start running - thread2.cond.wait(locker2.mutex()); - - // this will cause it to exit now - thread2.exit(++thread2.code); - QVERIFY(thread2.wait(five_minutes)); - QCOMPARE(thread2.result, thread2.code); - } + Exit_Thread thread2; + thread2.object = 0; + thread2.code = 53; + thread2.result = 0; + QMutexLocker locker2(&thread2.mutex); + thread2.start(); + thread2.exit(thread2.code); + thread2.cond.wait(locker2.mutex()); + QVERIFY(thread2.wait(five_minutes)); + QCOMPARE(thread2.result, thread2.code); } void tst_QThread::start() @@ -545,59 +498,32 @@ void tst_QThread::terminate() void tst_QThread::quit() { - // very similar to exit() above - { - Quit_Thread thread; - thread.object = new Quit_Object; - thread.object->moveToThread(&thread); - thread.result = -1; - QVERIFY(!thread.isFinished()); - QVERIFY(!thread.isRunning()); - - // start the thread, but keep the event loop from starting - // (while the mutex is locked) - QMutexLocker locker(&thread.mutex); - thread.start(); - QVERIFY(thread.isRunning()); - QVERIFY(!thread.isFinished()); - - // unlock the mutex and let the event loop run - // the Quit_Object above will cause the thread to quit - thread.cond.wait(locker.mutex()); - QVERIFY(thread.wait(five_minutes)); - QVERIFY(thread.isFinished()); - QVERIFY(!thread.isRunning()); - QCOMPARE(thread.result, 0); - delete thread.object; - } - - { - Quit_Thread thread2; - thread2.object = 0; - thread2.result = -1; - - // start the thread, but keep the event loop from starting - // (while the mutex is locked) - QMutexLocker locker2(&thread2.mutex); - thread2.start(); - thread2.quit(); // does nothing, the event loop is not running! - - // unlock the mutex and let the event loop run - thread2.cond.wait(locker2.mutex()); - - // there's no Quit_Object so it won't quit on its own - thread2.quit(); - QVERIFY(thread2.wait(five_minutes)); - QCOMPARE(thread2.result, 0); - } -} - -void tst_QThread::execAfterQuit() -{ - ExecAfterQuitThread thread; + Quit_Thread thread; + thread.object = new Quit_Object; + thread.object->moveToThread(&thread); + thread.result = -1; + QVERIFY(!thread.isFinished()); + QVERIFY(!thread.isRunning()); + QMutexLocker locker(&thread.mutex); thread.start(); - QVERIFY(thread.wait()); - QCOMPARE(thread.returnValue, 0); + QVERIFY(thread.isRunning()); + QVERIFY(!thread.isFinished()); + thread.cond.wait(locker.mutex()); + QVERIFY(thread.wait(five_minutes)); + QVERIFY(thread.isFinished()); + QVERIFY(!thread.isRunning()); + QCOMPARE(thread.result, 0); + delete thread.object; + + Quit_Thread thread2; + thread2.object = 0; + thread2.result = -1; + QMutexLocker locker2(&thread2.mutex); + thread2.start(); + thread2.quit(); + thread2.cond.wait(locker2.mutex()); + QVERIFY(thread2.wait(five_minutes)); + QCOMPARE(thread2.result, 0); } void tst_QThread::wait() @@ -1068,17 +994,8 @@ void tst_QThread::QTBUG15378_exitAndExec() Thread thread; thread.value = 0; thread.start(); - thread.exit(42); // will do nothing, this value should not appear - thread.sem1.release(); //should enter the first loop - - Exit_Object *exit_object = new Exit_Object; - exit_object->code = 556; - exit_object->thread = &thread; - QMetaObject::invokeMethod(exit_object, "slot", Qt::QueuedConnection); - exit_object->deleteLater(); - exit_object->moveToThread(&thread); // should exit the first loop - exit_object = 0; - + thread.exit(556); + thread.sem1.release(); //should exit the first loop thread.sem2.acquire(); int v = thread.value; QCOMPARE(v, 556); |