diff options
author | Matthew Vogt <matthew.vogt@nokia.com> | 2012-03-05 11:39:24 +1000 |
---|---|---|
committer | Matthew Vogt <matthew.vogt@nokia.com> | 2012-03-05 11:39:54 +1000 |
commit | 0284817d6cd7e17afa8da26ee6e9199100754446 (patch) | |
tree | c351d55d5a606c81c72e481f846b9b9e2603c883 /tests/auto | |
parent | 377eb94eb19dafeca20d12bc6b624f1779fae514 (diff) | |
parent | 36bd7f616f37f5f60e59bce1f0d8970248d627de (diff) |
Merge master <-> api_changes
Change-Id: Iad2f07b989b25349fd2d4fff010e24dcd5a1688f
Diffstat (limited to 'tests/auto')
96 files changed, 3451 insertions, 539 deletions
diff --git a/tests/auto/host.pro b/tests/auto/host.pro index 6bc8753fb0..0a96ef0413 100644 --- a/tests/auto/host.pro +++ b/tests/auto/host.pro @@ -1,4 +1,9 @@ TEMPLATE=subdirs -SUBDIRS=\ - headersclean \ + +# FIXME +# This test is crrently broken: +#SUBDIRS=\ + #headersclean \ + +SUBDIRS= diff --git a/tests/auto/qml/debugger/qqmlprofilerservice/qqmlprofilerservice.pro b/tests/auto/qml/debugger/qqmlprofilerservice/qqmlprofilerservice.pro index 0d11213cb4..81fe3d5943 100644 --- a/tests/auto/qml/debugger/qqmlprofilerservice/qqmlprofilerservice.pro +++ b/tests/auto/qml/debugger/qqmlprofilerservice/qqmlprofilerservice.pro @@ -12,4 +12,4 @@ include (../../../shared/util.pri) CONFIG += parallel_test declarative_debug -QT += qml-private testlib +QT += core-private v8-private qml-private testlib diff --git a/tests/auto/qml/debugger/qv8profilerservice/tst_qv8profilerservice.cpp b/tests/auto/qml/debugger/qv8profilerservice/tst_qv8profilerservice.cpp index a2cac08a21..c5992a4403 100644 --- a/tests/auto/qml/debugger/qv8profilerservice/tst_qv8profilerservice.cpp +++ b/tests/auto/qml/debugger/qv8profilerservice/tst_qv8profilerservice.cpp @@ -91,6 +91,7 @@ public: QList<QByteArray> snapshotMessages; signals: + void started(); void complete(); void snapshot(); @@ -158,6 +159,9 @@ void QV8ProfilerClient::messageReceived(const QByteArray &message) case QV8ProfilerService::V8SnapshotComplete: emit snapshot(); break; + case QV8ProfilerService::V8Started: + emit started(); + break; default: QString failMessage = QString("Unknown message type: %1").arg(messageType); QFAIL(qPrintable(failMessage)); @@ -208,6 +212,8 @@ void tst_QV8ProfilerService::blockingConnectWithTraceEnabled() QTRY_COMPARE(m_client->state(), QQmlDebugClient::Enabled); m_client->startProfiling(""); + QVERIFY2(QQmlDebugTest::waitForSignal(m_client, SIGNAL(started())), + "No start signal received in time."); m_client->stopProfiling(""); QVERIFY2(QQmlDebugTest::waitForSignal(m_client, SIGNAL(complete())), "No trace received in time."); @@ -225,6 +231,8 @@ void tst_QV8ProfilerService::blockingConnectWithTraceDisabled() QFAIL(qPrintable(failMsg)); } m_client->startProfiling(""); + QVERIFY2(QQmlDebugTest::waitForSignal(m_client, SIGNAL(started())), + "No start signal received in time."); m_client->stopProfiling(""); QVERIFY2(QQmlDebugTest::waitForSignal(m_client, SIGNAL(complete())), "No trace received in time."); @@ -236,6 +244,8 @@ void tst_QV8ProfilerService::nonBlockingConnect() QTRY_COMPARE(m_client->state(), QQmlDebugClient::Enabled); m_client->startProfiling(""); + QVERIFY2(QQmlDebugTest::waitForSignal(m_client, SIGNAL(started())), + "No start signal received in time."); m_client->stopProfiling(""); QVERIFY2(QQmlDebugTest::waitForSignal(m_client, SIGNAL(complete())), "No trace received in time."); @@ -257,6 +267,8 @@ void tst_QV8ProfilerService::profileOnExit() QTRY_COMPARE(m_client->state(), QQmlDebugClient::Enabled); m_client->startProfiling(""); + QVERIFY2(QQmlDebugTest::waitForSignal(m_client, SIGNAL(started())), + "No start signal received in time."); QVERIFY2(QQmlDebugTest::waitForSignal(m_client, SIGNAL(complete())), "No trace received in time."); @@ -270,6 +282,8 @@ void tst_QV8ProfilerService::console() m_client->stopProfiling(""); + QVERIFY2(QQmlDebugTest::waitForSignal(m_client, SIGNAL(started())), + "No start signal received in time."); QVERIFY2(QQmlDebugTest::waitForSignal(m_client, SIGNAL(complete())), "No trace received in time."); QVERIFY(!m_client->traceMessages.isEmpty()); diff --git a/tests/auto/qml/qml.pro b/tests/auto/qml/qml.pro index 7a62a71df1..bcfbcbdbf0 100644 --- a/tests/auto/qml/qml.pro +++ b/tests/auto/qml/qml.pro @@ -19,6 +19,7 @@ PUBLICTESTS += \ qqmlinfo \ qqmllistreference \ qqmllocale \ + qqmlmetaobject \ qqmlmoduleplugin \ qqmlqt \ qqmltranslation \ diff --git a/tests/auto/qml/qmlmin/tst_qmlmin.cpp b/tests/auto/qml/qmlmin/tst_qmlmin.cpp index 2d764317c5..dfc88fb78c 100644 --- a/tests/auto/qml/qmlmin/tst_qmlmin.cpp +++ b/tests/auto/qml/qmlmin/tst_qmlmin.cpp @@ -96,10 +96,11 @@ void tst_qmlmin::initTestCase() // Add invalid files (i.e. files with syntax errors) invalidFiles << "tests/auto/quick/qquickloader/data/InvalidSourceComponent.qml"; invalidFiles << "tests/auto/qml/qqmllanguage/data/dynamicObjectProperties.2.qml"; + invalidFiles << "tests/auto/qml/qqmllanguage/data/signal.2.qml"; invalidFiles << "tests/auto/qml/qqmllanguage/data/signal.3.qml"; + invalidFiles << "tests/auto/qml/qqmllanguage/data/signal.5.qml"; invalidFiles << "tests/auto/qml/qqmllanguage/data/property.4.qml"; invalidFiles << "tests/auto/qml/qqmllanguage/data/empty.qml"; - invalidFiles << "tests/auto/qml/qqmllanguage/data/signal.2.qml"; invalidFiles << "tests/auto/qml/qqmllanguage/data/missingObject.qml"; invalidFiles << "tests/auto/qml/qqmllanguage/data/insertedSemicolon.1.qml"; invalidFiles << "tests/auto/qml/qqmllanguage/data/nonexistantProperty.5.qml"; diff --git a/tests/auto/qml/qqmlcomponent/data/createParentReference.qml b/tests/auto/qml/qqmlcomponent/data/createParentReference.qml new file mode 100644 index 0000000000..daa5d3c167 --- /dev/null +++ b/tests/auto/qml/qqmlcomponent/data/createParentReference.qml @@ -0,0 +1,12 @@ +import QtQuick 2.0 + +Item { + id: root + width: 100 + height: 100 + + function createChild() { + Qt.createQmlObject("import QtQuick 2.0;" + + "Item { width: parent.width; }", root); + } +} diff --git a/tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp b/tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp index d277952f22..603c091a03 100644 --- a/tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp +++ b/tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp @@ -71,6 +71,7 @@ private slots: void qmlCreateObject(); void qmlCreateObjectWithProperties(); void qmlIncubateObject(); + void qmlCreateParentReference(); private: QQmlEngine engine; @@ -181,6 +182,37 @@ void tst_qqmlcomponent::qmlCreateObjectWithProperties() delete testBindingThisObj; } +static QStringList warnings; +static void msgHandler(QtMsgType, const char *warning) +{ + warnings << QString::fromUtf8(warning); +} + +void tst_qqmlcomponent::qmlCreateParentReference() +{ + QQmlEngine engine; + + QCOMPARE(engine.outputWarningsToStandardError(), true); + + warnings.clear(); + QtMsgHandler old = qInstallMsgHandler(msgHandler); + + QQmlComponent component(&engine, testFileUrl("createParentReference.qml")); + QVERIFY2(component.errorString().isEmpty(), component.errorString().toUtf8()); + QObject *object = component.create(); + QVERIFY(object != 0); + + QVERIFY(QMetaObject::invokeMethod(object, "createChild")); + delete object; + + qInstallMsgHandler(old); + + engine.setOutputWarningsToStandardError(false); + QCOMPARE(engine.outputWarningsToStandardError(), false); + + QCOMPARE(warnings.count(), 0); +} + QTEST_MAIN(tst_qqmlcomponent) #include "tst_qqmlcomponent.moc" diff --git a/tests/auto/qml/qqmlecmascript/data/jsimport/importModuleApi.js b/tests/auto/qml/qqmlecmascript/data/jsimport/importModuleApi.js new file mode 100644 index 0000000000..7a4f434665 --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/jsimport/importModuleApi.js @@ -0,0 +1,5 @@ +.import Qt.test 1.0 as QObjectModuleApi + +function testFunc() { + return QObjectModuleApi.qobjectTestProperty +} diff --git a/tests/auto/qml/qqmlecmascript/data/jsimport/testImportModuleApi.qml b/tests/auto/qml/qqmlecmascript/data/jsimport/testImportModuleApi.qml new file mode 100644 index 0000000000..b3e545dd7c --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/jsimport/testImportModuleApi.qml @@ -0,0 +1,10 @@ +import QtQuick 2.0 +import "importModuleApi.js" as Script + +Item { + property variant testValue: 5 + + Component.onCompleted: { + testValue = Script.testFunc(); + } +} diff --git a/tests/auto/qml/qqmlecmascript/data/rewriteMultiLineStrings_crlf.1.qml b/tests/auto/qml/qqmlecmascript/data/rewriteMultiLineStrings_crlf.1.qml new file mode 100644 index 0000000000..f84ba8c722 --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/rewriteMultiLineStrings_crlf.1.qml @@ -0,0 +1,13 @@ +import QtQuick 2.0 + +Rectangle { + id: root + + Component.onCompleted: { + var o = Qt.createQmlObject("import QtQuick 2.0; \ + \ + Item { \ + property bool b: true; \ + }", root, "Instance") + } +} diff --git a/tests/auto/qml/qqmlecmascript/data/signalAssignment.3.qml b/tests/auto/qml/qqmlecmascript/data/signalAssignment.3.qml new file mode 100644 index 0000000000..690b7cf216 --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/signalAssignment.3.qml @@ -0,0 +1,5 @@ +import Qt.test 1.0 + +MyQmlObject { + onUnnamedArgumentSignal: setString('pass ' + a + ' ' + c) +} diff --git a/tests/auto/qml/qqmlecmascript/data/signalAssignment.4.qml b/tests/auto/qml/qqmlecmascript/data/signalAssignment.4.qml new file mode 100644 index 0000000000..0e1e728a86 --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/signalAssignment.4.qml @@ -0,0 +1,6 @@ +import Qt.test 1.0 + + +MyQmlObject { + onSignalWithGlobalName: setString('pass ' + parseInt("5")) +} diff --git a/tests/auto/qml/qqmlecmascript/testtypes.h b/tests/auto/qml/qqmlecmascript/testtypes.h index 154e6f019c..1d68e8ae13 100644 --- a/tests/auto/qml/qqmlecmascript/testtypes.h +++ b/tests/auto/qml/qqmlecmascript/testtypes.h @@ -180,6 +180,7 @@ public: signals: void basicSignal(); void argumentSignal(int a, QString b, qreal c, MyEnum2 d, Qt::MouseButtons e); + void unnamedArgumentSignal(int a, qreal, QString c); void stringChanged(); void urlChanged(); void objectChanged(); @@ -188,6 +189,7 @@ signals: void signalWithUnknownType(const MyQmlObject::MyType &arg); void signalWithVariant(const QVariant &arg); void signalWithQJSValue(const QJSValue &arg); + void signalWithGlobalName(int parseInt); void intChanged(); public slots: diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp index af219c8826..676557a81c 100644 --- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp +++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp @@ -376,6 +376,27 @@ void tst_qqmlecmascript::signalAssignment() QCOMPARE(object->string(), QString("pass 19 Hello world! 10.25 3 2")); delete object; } + + { + QQmlComponent component(&engine, testFileUrl("signalAssignment.3.qml")); + MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create()); + QVERIFY(object != 0); + QCOMPARE(object->string(), QString()); + emit object->unnamedArgumentSignal(19, 10.25, "Hello world!"); + QEXPECT_FAIL("", "QTBUG-24481", Continue); + QCOMPARE(object->string(), QString("pass 19 Hello world!")); + delete object; + } + + { + QQmlComponent component(&engine, testFileUrl("signalAssignment.4.qml")); + MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create()); + QVERIFY(object != 0); + QCOMPARE(object->string(), QString()); + emit object->signalWithGlobalName(19); + QCOMPARE(object->string(), QString("pass 5")); + delete object; + } } void tst_qqmlecmascript::methods() @@ -1570,8 +1591,6 @@ void tst_qqmlecmascript::compileInvalidBinding() { // QTBUG-23387: ensure that invalid bindings don't cause a crash. QQmlComponent component(&engine, testFileUrl("v8bindingException.qml")); - QString warning = component.url().toString() + ":16: SyntaxError: Unexpected token ILLEGAL"; - QTest::ignoreMessage(QtWarningMsg, warning.toLatin1().constData()); QObject *object = component.create(); QVERIFY(object != 0); delete object; @@ -3248,6 +3267,13 @@ void tst_qqmlecmascript::importScripts_data() << QStringList() << (QStringList() << QLatin1String("testValue")) << (QVariantList() << QVariant(18)); + + QTest::newRow("import module api into js import") + << testFileUrl("jsimport/testImportModuleApi.qml") + << QString() + << QStringList() + << (QStringList() << QLatin1String("testValue")) + << (QVariantList() << QVariant(20)); } void tst_qqmlecmascript::importScripts() @@ -5287,12 +5313,21 @@ void tst_qqmlecmascript::qtbug_21864() void tst_qqmlecmascript::rewriteMultiLineStrings() { - // QTBUG-23387 - QQmlComponent component(&engine, testFileUrl("rewriteMultiLineStrings.qml")); - QObject *o = component.create(); - QVERIFY(o != 0); - QTRY_COMPARE(o->property("test").toBool(), true); - delete o; + { + // QTBUG-23387 + QQmlComponent component(&engine, testFileUrl("rewriteMultiLineStrings.qml")); + QObject *o = component.create(); + QVERIFY(o != 0); + QTRY_COMPARE(o->property("test").toBool(), true); + delete o; + } + + { + QQmlComponent component(&engine, testFileUrl("rewriteMultiLineStrings_crlf.1.qml")); + QObject *o = component.create(); + QVERIFY(o != 0); + delete o; + } } void tst_qqmlecmascript::qobjectConnectionListExceptionHandling() diff --git a/tests/auto/qml/qqmlinstruction/tst_qqmlinstruction.cpp b/tests/auto/qml/qqmlinstruction/tst_qqmlinstruction.cpp index 07b89af0a3..d076f038d3 100644 --- a/tests/auto/qml/qqmlinstruction/tst_qqmlinstruction.cpp +++ b/tests/auto/qml/qqmlinstruction/tst_qqmlinstruction.cpp @@ -499,9 +499,9 @@ void tst_qqmlinstruction::dump() << "24\t\tSTORE_OBJECT\t\t21" << "25\t\tSTORE_VARIANT_OBJECT\t22" << "26\t\tSTORE_INTERFACE\t\t23" - << "27\t\tSTORE_SIGNAL\t\t2\t3\t\t\"console.log(1921)\"" + << "27\t\tSTORE_SIGNAL\t\t2\t3" << "28\t\tSTORE_SCRIPT_STRING\t24\t3\t1\t4" - << "29\t\tASSIGN_SIGNAL_OBJECT\t4\t\t\t\"mySignal\"" + << "29\t\tASSIGN_SIGNAL_OBJECT\t4" << "30\t\tASSIGN_CUSTOMTYPE\t25\t6\t9" << "31\t\tSTORE_BINDING\t26\t3\t2" << "32\t\tSTORE_COMPILED_BINDING\t27\t2\t4" diff --git a/tests/auto/qml/qqmllanguage/data/signal.5.errors.txt b/tests/auto/qml/qqmllanguage/data/signal.5.errors.txt new file mode 100644 index 0000000000..cf772e881e --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/signal.5.errors.txt @@ -0,0 +1 @@ +4:27:Expected token `identifier' diff --git a/tests/auto/qml/qqmllanguage/data/signal.5.qml b/tests/auto/qml/qqmllanguage/data/signal.5.qml new file mode 100644 index 0000000000..63921cb2ca --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/signal.5.qml @@ -0,0 +1,6 @@ +import QtQuick 2.0 + +QtObject { + signal mySignal(string) +} + diff --git a/tests/auto/qml/qqmllanguage/testtypes.h b/tests/auto/qml/qqmllanguage/testtypes.h index e9898bd039..e7294f090c 100644 --- a/tests/auto/qml/qqmllanguage/testtypes.h +++ b/tests/auto/qml/qqmllanguage/testtypes.h @@ -67,7 +67,8 @@ public: }; QT_BEGIN_NAMESPACE -Q_DECLARE_INTERFACE(MyInterface, "com.trolltech.Qt.Test.MyInterface"); +#define MyInterface_iid "org.qt-project.Qt.Test.MyInterface" +Q_DECLARE_INTERFACE(MyInterface, MyInterface_iid); QT_END_NAMESPACE QML_DECLARE_INTERFACE(MyInterface); diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp index 379c32d4b8..266cd2a52d 100644 --- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp +++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp @@ -354,6 +354,7 @@ void tst_qqmllanguage::errors_data() QTest::newRow("signal.2") << "signal.2.qml" << "signal.2.errors.txt" << false; QTest::newRow("signal.3") << "signal.3.qml" << "signal.3.errors.txt" << false; QTest::newRow("signal.4") << "signal.4.qml" << "signal.4.errors.txt" << false; + QTest::newRow("signal.5") << "signal.5.qml" << "signal.5.errors.txt" << false; QTest::newRow("method.1") << "method.1.qml" << "method.1.errors.txt" << false; diff --git a/tests/auto/qml/qqmllocale/tst_qqmllocale.cpp b/tests/auto/qml/qqmllocale/tst_qqmllocale.cpp index af1a81847b..46435fb8fc 100644 --- a/tests/auto/qml/qqmllocale/tst_qqmllocale.cpp +++ b/tests/auto/qml/qqmllocale/tst_qqmllocale.cpp @@ -68,6 +68,8 @@ private slots: void dayName(); void standaloneDayName_data(); void standaloneDayName(); + void firstDayOfWeek_data(); + void firstDayOfWeek(); void weekDays_data(); void weekDays(); void uiLanguages_data(); @@ -154,7 +156,6 @@ void tst_qqmllocale::addPropertyData(const QString &l) LOCALE_PROP(QString,negativeSign), LOCALE_PROP(QString,positiveSign), LOCALE_PROP(QString,exponential), - LOCALE_PROP(int,firstDayOfWeek), LOCALE_PROP(int,measurementSystem), LOCALE_PROP(int,textDirection), { 0, QVariant() } @@ -426,6 +427,41 @@ void tst_qqmllocale::standaloneDayName() delete obj; } +void tst_qqmllocale::firstDayOfWeek_data() +{ + QTest::addColumn<QString>("locale"); + + QTest::newRow("en_US") << "en_US"; + QTest::newRow("de_DE") << "de_DE"; + QTest::newRow("ar_SA") << "ar_SA"; + QTest::newRow("hi_IN") << "hi_IN"; + QTest::newRow("zh_CN") << "zh_CN"; + QTest::newRow("th_TH") << "th_TH"; +} + +void tst_qqmllocale::firstDayOfWeek() +{ + QFETCH(QString, locale); + + QQmlComponent c(&engine, testFileUrl("properties.qml")); + + QObject *obj = c.create(); + QVERIFY(obj); + + QMetaObject::invokeMethod(obj, "setLocale", Qt::DirectConnection, + Q_ARG(QVariant, QVariant(locale))); + + QVariant val = obj->property("firstDayOfWeek"); + QVERIFY(val.type() == QVariant::Int); + + int day = int(QLocale(locale).firstDayOfWeek()); + if (day == 7) // JS Date days in range 0(Sunday) to 6(Saturday) + day = 0; + QCOMPARE(day, val.toInt()); + + delete obj; +} + void tst_qqmllocale::weekDays_data() { QTest::addColumn<QString>("locale"); diff --git a/tests/auto/qml/qqmlmetaobject/data/method.1.qml b/tests/auto/qml/qqmlmetaobject/data/method.1.qml new file mode 100644 index 0000000000..a021881743 --- /dev/null +++ b/tests/auto/qml/qqmlmetaobject/data/method.1.qml @@ -0,0 +1,5 @@ +import QtQuick 2.0 + +QtObject { + function testFunction() { return 19; } +} diff --git a/tests/auto/qml/qqmlmetaobject/data/method.2.qml b/tests/auto/qml/qqmlmetaobject/data/method.2.qml new file mode 100644 index 0000000000..d514955f47 --- /dev/null +++ b/tests/auto/qml/qqmlmetaobject/data/method.2.qml @@ -0,0 +1,5 @@ +import QtQuick 2.0 + +QtObject { + function testFunction(foo) { return 19; } +} diff --git a/tests/auto/qml/qqmlmetaobject/data/method.3.qml b/tests/auto/qml/qqmlmetaobject/data/method.3.qml new file mode 100644 index 0000000000..d6d19758c9 --- /dev/null +++ b/tests/auto/qml/qqmlmetaobject/data/method.3.qml @@ -0,0 +1,5 @@ +import QtQuick 2.0 + +QtObject { + function testFunction(foo, bar, baz) { return 19; } +} diff --git a/tests/auto/qml/qqmlmetaobject/data/property.MyQmlObject.qml b/tests/auto/qml/qqmlmetaobject/data/property.MyQmlObject.qml new file mode 100644 index 0000000000..8903bbb3e9 --- /dev/null +++ b/tests/auto/qml/qqmlmetaobject/data/property.MyQmlObject.qml @@ -0,0 +1,6 @@ +import Qt.test 1.0 +import QtQuick 2.0 + +QtObject { + property MyQmlObject test: MyQmlObject {} +} diff --git a/tests/auto/qml/qqmlmetaobject/data/property.QtObject.qml b/tests/auto/qml/qqmlmetaobject/data/property.QtObject.qml new file mode 100644 index 0000000000..20c42b5851 --- /dev/null +++ b/tests/auto/qml/qqmlmetaobject/data/property.QtObject.qml @@ -0,0 +1,5 @@ +import QtQuick 2.0 + +QtObject { + property QtObject test: QtObject {} +} diff --git a/tests/auto/qml/qqmlmetaobject/data/property.alias.2.qml b/tests/auto/qml/qqmlmetaobject/data/property.alias.2.qml new file mode 100644 index 0000000000..cae1ae6696 --- /dev/null +++ b/tests/auto/qml/qqmlmetaobject/data/property.alias.2.qml @@ -0,0 +1,6 @@ +import QtQuick 2.0 + +QtObject { + id: me + property alias test: me +} diff --git a/tests/auto/qml/qqmlmetaobject/data/property.alias.3.qml b/tests/auto/qml/qqmlmetaobject/data/property.alias.3.qml new file mode 100644 index 0000000000..86422ae367 --- /dev/null +++ b/tests/auto/qml/qqmlmetaobject/data/property.alias.3.qml @@ -0,0 +1,7 @@ +import QtQuick 2.0 + +Text { + id: me + font.family: "Arial" + property alias test: me.font.family +} diff --git a/tests/auto/qml/qqmlmetaobject/data/property.alias.qml b/tests/auto/qml/qqmlmetaobject/data/property.alias.qml new file mode 100644 index 0000000000..33a4a1c5b0 --- /dev/null +++ b/tests/auto/qml/qqmlmetaobject/data/property.alias.qml @@ -0,0 +1,7 @@ +import QtQuick 2.0 + +QtObject { + objectName: "Joe" + id: me + property alias test: me.objectName +} diff --git a/tests/auto/qml/qqmlmetaobject/data/property.bool.qml b/tests/auto/qml/qqmlmetaobject/data/property.bool.qml new file mode 100644 index 0000000000..9459cb6394 --- /dev/null +++ b/tests/auto/qml/qqmlmetaobject/data/property.bool.qml @@ -0,0 +1,5 @@ +import QtQuick 2.0 + +QtObject { + default property bool test: true +} diff --git a/tests/auto/qml/qqmlmetaobject/data/property.color.qml b/tests/auto/qml/qqmlmetaobject/data/property.color.qml new file mode 100644 index 0000000000..7451a27101 --- /dev/null +++ b/tests/auto/qml/qqmlmetaobject/data/property.color.qml @@ -0,0 +1,5 @@ +import QtQuick 2.0 + +QtObject { + default property color test: "#ff0000" +} diff --git a/tests/auto/qml/qqmlmetaobject/data/property.date.qml b/tests/auto/qml/qqmlmetaobject/data/property.date.qml new file mode 100644 index 0000000000..05fcb2516c --- /dev/null +++ b/tests/auto/qml/qqmlmetaobject/data/property.date.qml @@ -0,0 +1,5 @@ +import QtQuick 2.0 + +QtObject { + property date test: "2012-02-07" +} diff --git a/tests/auto/qml/qqmlmetaobject/data/property.int.qml b/tests/auto/qml/qqmlmetaobject/data/property.int.qml new file mode 100644 index 0000000000..ae419d08cb --- /dev/null +++ b/tests/auto/qml/qqmlmetaobject/data/property.int.qml @@ -0,0 +1,5 @@ +import QtQuick 2.0 + +QtObject { + property int test: 19 +} diff --git a/tests/auto/qml/qqmlmetaobject/data/property.list.MyQmlObject.qml b/tests/auto/qml/qqmlmetaobject/data/property.list.MyQmlObject.qml new file mode 100644 index 0000000000..602762cba2 --- /dev/null +++ b/tests/auto/qml/qqmlmetaobject/data/property.list.MyQmlObject.qml @@ -0,0 +1,6 @@ +import Qt.test 1.0 +import QtQuick 2.0 + +QtObject { + property list<MyQmlObject> test: [ MyQmlObject {} ] +} diff --git a/tests/auto/qml/qqmlmetaobject/data/property.list.QtObject.qml b/tests/auto/qml/qqmlmetaobject/data/property.list.QtObject.qml new file mode 100644 index 0000000000..e774d70b42 --- /dev/null +++ b/tests/auto/qml/qqmlmetaobject/data/property.list.QtObject.qml @@ -0,0 +1,5 @@ +import QtQuick 2.0 + +QtObject { + property list<QtObject> test: [ QtObject {} ] +} diff --git a/tests/auto/qml/qqmlmetaobject/data/property.real.qml b/tests/auto/qml/qqmlmetaobject/data/property.real.qml new file mode 100644 index 0000000000..de2baf5be2 --- /dev/null +++ b/tests/auto/qml/qqmlmetaobject/data/property.real.qml @@ -0,0 +1,5 @@ +import QtQuick 2.0 + +QtObject { + property real test: 21 +} diff --git a/tests/auto/qml/qqmlmetaobject/data/property.string.qml b/tests/auto/qml/qqmlmetaobject/data/property.string.qml new file mode 100644 index 0000000000..2a625c4fe4 --- /dev/null +++ b/tests/auto/qml/qqmlmetaobject/data/property.string.qml @@ -0,0 +1,5 @@ +import QtQuick 2.0 + +QtObject { + default property string test: "dog" +} diff --git a/tests/auto/qml/qqmlmetaobject/data/property.url.qml b/tests/auto/qml/qqmlmetaobject/data/property.url.qml new file mode 100644 index 0000000000..c820c82515 --- /dev/null +++ b/tests/auto/qml/qqmlmetaobject/data/property.url.qml @@ -0,0 +1,5 @@ +import QtQuick 2.0 + +QtObject { + property url test: "http://foo.bar" +} diff --git a/tests/auto/qml/qqmlmetaobject/data/property.var.qml b/tests/auto/qml/qqmlmetaobject/data/property.var.qml new file mode 100644 index 0000000000..9ea9245317 --- /dev/null +++ b/tests/auto/qml/qqmlmetaobject/data/property.var.qml @@ -0,0 +1,5 @@ +import QtQuick 2.0 + +QtObject { + property var test: [5, true, "ciao"] +} diff --git a/tests/auto/qml/qqmlmetaobject/data/property.variant.qml b/tests/auto/qml/qqmlmetaobject/data/property.variant.qml new file mode 100644 index 0000000000..edffa173c4 --- /dev/null +++ b/tests/auto/qml/qqmlmetaobject/data/property.variant.qml @@ -0,0 +1,5 @@ +import QtQuick 2.0 + +QtObject { + default property variant test: "12,34" +} diff --git a/tests/auto/qml/qqmlmetaobject/data/signal.1.qml b/tests/auto/qml/qqmlmetaobject/data/signal.1.qml new file mode 100644 index 0000000000..113130f3cc --- /dev/null +++ b/tests/auto/qml/qqmlmetaobject/data/signal.1.qml @@ -0,0 +1,5 @@ +import QtQuick 2.0 + +QtObject { + signal testSignal +} diff --git a/tests/auto/qml/qqmlmetaobject/data/signal.2.qml b/tests/auto/qml/qqmlmetaobject/data/signal.2.qml new file mode 100644 index 0000000000..db860cc7cd --- /dev/null +++ b/tests/auto/qml/qqmlmetaobject/data/signal.2.qml @@ -0,0 +1,5 @@ +import QtQuick 2.0 + +QtObject { + signal testSignal(string foo) +} diff --git a/tests/auto/qml/qqmlmetaobject/data/signal.3.qml b/tests/auto/qml/qqmlmetaobject/data/signal.3.qml new file mode 100644 index 0000000000..4d04041f8f --- /dev/null +++ b/tests/auto/qml/qqmlmetaobject/data/signal.3.qml @@ -0,0 +1,5 @@ +import QtQuick 2.0 + +QtObject { + signal testSignal(int foo, bool bar, real baz) +} diff --git a/tests/auto/qml/qqmlmetaobject/data/signal.4.qml b/tests/auto/qml/qqmlmetaobject/data/signal.4.qml new file mode 100644 index 0000000000..ad9b002176 --- /dev/null +++ b/tests/auto/qml/qqmlmetaobject/data/signal.4.qml @@ -0,0 +1,5 @@ +import QtQuick 2.0 + +QtObject { + signal testSignal(variant foo, var bar) +} diff --git a/tests/auto/qml/qqmlmetaobject/data/signal.5.qml b/tests/auto/qml/qqmlmetaobject/data/signal.5.qml new file mode 100644 index 0000000000..b848bb5cb5 --- /dev/null +++ b/tests/auto/qml/qqmlmetaobject/data/signal.5.qml @@ -0,0 +1,5 @@ +import QtQuick 2.0 + +QtObject { + signal testSignal(color foo, date bar, url baz) +} diff --git a/tests/auto/qml/qqmlmetaobject/qqmlmetaobject.pro b/tests/auto/qml/qqmlmetaobject/qqmlmetaobject.pro new file mode 100644 index 0000000000..b87a7cd8bd --- /dev/null +++ b/tests/auto/qml/qqmlmetaobject/qqmlmetaobject.pro @@ -0,0 +1,14 @@ +CONFIG += testcase +TARGET = tst_qqmlmetaobject +macx:CONFIG -= app_bundle + +SOURCES += tst_qqmlmetaobject.cpp + +include (../../shared/util.pri) + +testDataFiles.files = data +testDataFiles.path = . +DEPLOYMENT += testDataFiles + +CONFIG += parallel_test +QT += qml testlib diff --git a/tests/auto/qml/qqmlmetaobject/tst_qqmlmetaobject.cpp b/tests/auto/qml/qqmlmetaobject/tst_qqmlmetaobject.cpp new file mode 100644 index 0000000000..6cadc3524b --- /dev/null +++ b/tests/auto/qml/qqmlmetaobject/tst_qqmlmetaobject.cpp @@ -0,0 +1,364 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest/QtTest> +#include <QtQml/qqmlcomponent.h> +#include <QtQml/qqmlengine.h> +#include "../../shared/util.h" + +Q_DECLARE_METATYPE(QMetaMethod::MethodType) + +class MyQmlObject : public QObject +{ + Q_OBJECT +}; +QML_DECLARE_TYPE(MyQmlObject) + +class tst_QQmlMetaObject : public QQmlDataTest +{ + Q_OBJECT +private slots: + void initTestCase(); + + void property_data(); + void property(); + void method_data(); + void method(); + +private: + MyQmlObject myQmlObject; +}; + +void tst_QQmlMetaObject::initTestCase() +{ + QQmlDataTest::initTestCase(); + + qmlRegisterType<MyQmlObject>("Qt.test", 1,0, "MyQmlObject"); +} + +void tst_QQmlMetaObject::property_data() +{ + QTest::addColumn<QString>("testFile"); + QTest::addColumn<QByteArray>("cppTypeName"); + QTest::addColumn<int>("cppType"); + QTest::addColumn<bool>("isDefault"); + QTest::addColumn<QVariant>("expectedValue"); + QTest::addColumn<bool>("isWritable"); + QTest::addColumn<QVariant>("newValue"); + + QTest::newRow("int") << "property.int.qml" + << QByteArray("int") << int(QMetaType::Int) + << false // default + << QVariant(19) << true << QVariant(42); + QTest::newRow("bool") << "property.bool.qml" + << QByteArray("bool") << int(QMetaType::Bool) + << true // default + << QVariant(true) << true << QVariant(false); + QTest::newRow("real") << "property.real.qml" + << QByteArray("double") << int(QMetaType::Double) + << false // default + << QVariant(double(21)) + << true // writable + << QVariant(double(37)); + QTest::newRow("string") << "property.string.qml" + << QByteArray("QString") << int(QMetaType::QString) + << true // default + << QVariant(QString::fromLatin1("dog")) + << true // writable + << QVariant(QString::fromLatin1("food")); + QTest::newRow("url") << "property.url.qml" + << QByteArray("QUrl") << int(QMetaType::QUrl) + << false // default + << QVariant(QUrl("http://foo.bar")) + << true //writable + << QVariant(QUrl("http://bar.baz")); + QTest::newRow("color") << "property.color.qml" + << QByteArray("QColor") << int(QMetaType::QColor) + << true // default + << QVariant(QColor("#ff0000")) + << true // writable + << QVariant(QColor("#00ff00")); + QTest::newRow("date") << "property.date.qml" + << QByteArray("QDateTime") << int(QMetaType::QDateTime) + << false // default + << QVariant(QDateTime(QDate(2012, 2, 7))) + << true // writable + << QVariant(QDateTime(QDate(2010, 7, 2))); + QTest::newRow("variant") << "property.variant.qml" + << QByteArray("QVariant") << int(QMetaType::QVariant) + << true // default + << QVariant(QPointF(12, 34)) + << true // writable + << QVariant(QSizeF(45, 67)); + QTest::newRow("var") << "property.var.qml" + << QByteArray("QVariant") << int(QMetaType::QVariant) + << false // default + << QVariant(QVariantList() << 5 << true << "ciao") + << true // writable + << QVariant(QVariantList() << 17.0); + QTest::newRow("QtObject") << "property.QtObject.qml" + << QByteArray("QObject*") << int(QMetaType::QObjectStar) + << false // default + << QVariant() + << true // writable + << QVariant::fromValue(static_cast<QObject*>(this)); + QTest::newRow("list<QtObject>") << "property.list.QtObject.qml" + << QByteArray("QQmlListProperty<QObject>") + << qMetaTypeId<QQmlListProperty<QObject> >() + << false // default + << QVariant() + << false // writable + << QVariant(); + QTest::newRow("MyQmlObject") << "property.MyQmlObject.qml" + << QByteArray("MyQmlObject*") << qMetaTypeId<MyQmlObject*>() + << false // default + << QVariant() + << true // writable + << QVariant::fromValue(&myQmlObject); + QTest::newRow("list<MyQmlObject>") << "property.list.MyQmlObject.qml" + << QByteArray("QQmlListProperty<MyQmlObject>") + << qMetaTypeId<QQmlListProperty<MyQmlObject> >() + << false // default + << QVariant() + << false // writable + << QVariant(); + QTest::newRow("alias") << "property.alias.qml" + << QByteArray("QString") << int(QMetaType::QString) + << false // default + << QVariant(QString::fromLatin1("Joe")) + << true // writable + << QVariant(QString::fromLatin1("Bob")); + QTest::newRow("alias-2") << "property.alias.2.qml" + << QByteArray("QObject*") << int(QMetaType::QObjectStar) + << false // default + << QVariant() + << false // writable + << QVariant(); + QTest::newRow("alias-3") << "property.alias.3.qml" + << QByteArray("QString") << int(QMetaType::QString) + << false // default + << QVariant(QString::fromLatin1("Arial")) + << true // writable + << QVariant(QString::fromLatin1("Helvetica")); +} + +void tst_QQmlMetaObject::property() +{ + QFETCH(QString, testFile); + QFETCH(QByteArray, cppTypeName); + QFETCH(int, cppType); + QFETCH(bool, isDefault); + QFETCH(QVariant, expectedValue); + QFETCH(bool, isWritable); + QFETCH(QVariant, newValue); + + QQmlEngine engine; + QQmlComponent component(&engine, testFileUrl(testFile)); + QObject *object = component.create(); + QVERIFY(object != 0); + + const QMetaObject *mo = object->metaObject(); + QVERIFY(mo->superClass() != 0); + QVERIFY(QByteArray(mo->className()).contains("_QML_")); + QCOMPARE(mo->propertyOffset(), mo->superClass()->propertyCount()); + QCOMPARE(mo->propertyCount(), mo->superClass()->propertyCount() + 1); + + QMetaProperty prop = mo->property(mo->propertyOffset()); + QCOMPARE(prop.name(), "test"); + + QCOMPARE(QByteArray(prop.typeName()), cppTypeName); + QEXPECT_FAIL("QtObject", "prop.type() returns UserType for QtObject properties", Continue); + QEXPECT_FAIL("alias-2", "prop.type() returns UserType for QtObject properties", Continue); + if (prop.userType() < QMetaType::User) + QCOMPARE(prop.type(), QVariant::Type(cppType)); + QCOMPARE(prop.userType(), cppType); + + QVERIFY(!prop.isConstant()); + QVERIFY(!prop.isDesignable()); + QVERIFY(!prop.isEnumType()); + QVERIFY(!prop.isFinal()); + QVERIFY(!prop.isFlagType()); + QVERIFY(prop.isReadable()); + QVERIFY(!prop.isResettable()); + QVERIFY(prop.isScriptable()); + QVERIFY(!prop.isStored()); + QVERIFY(!prop.isUser()); + QVERIFY(prop.isValid()); + QCOMPARE(prop.isWritable(), isWritable); + + QCOMPARE(mo->classInfoOffset(), mo->superClass()->classInfoCount()); + QCOMPARE(mo->classInfoCount(), mo->superClass()->classInfoCount() + (isDefault ? 1 : 0)); + if (isDefault) { + QMetaClassInfo info = mo->classInfo(mo->classInfoOffset()); + QCOMPARE(info.name(), "DefaultProperty"); + QCOMPARE(info.value(), "test"); + } + + QCOMPARE(mo->methodOffset(), mo->superClass()->methodCount()); + QCOMPARE(mo->methodCount(), mo->superClass()->methodCount() + 1); // the signal + + QVERIFY(prop.notifySignalIndex() != -1); + QMetaMethod signal = prop.notifySignal(); + QCOMPARE(signal.methodType(), QMetaMethod::Signal); + QCOMPARE(signal.signature(), "testChanged()"); + QCOMPARE(signal.access(), QMetaMethod::Protected); + QCOMPARE(signal.parameterTypes(), QList<QByteArray>()); + QCOMPARE(signal.parameterNames(), QList<QByteArray>()); + QCOMPARE(signal.tag(), ""); + QCOMPARE(signal.typeName(), ""); + + QSignalSpy changedSpy(object, SIGNAL(testChanged())); + QObject::connect(object, SIGNAL(testChanged()), object, SLOT(deleteLater())); + + if (expectedValue.isValid()) + QCOMPARE(prop.read(object), expectedValue); + else + QVERIFY(prop.read(object).isValid()); + QCOMPARE(changedSpy.count(), 0); + + if (isWritable) { + QVERIFY(prop.write(object, newValue)); + QCOMPARE(changedSpy.count(), 1); + QCOMPARE(prop.read(object), newValue); + } else { + QVERIFY(!prop.write(object, prop.read(object))); + QCOMPARE(changedSpy.count(), 0); + } + + delete object; +} + +void tst_QQmlMetaObject::method_data() +{ + QTest::addColumn<QString>("testFile"); + QTest::addColumn<QString>("signature"); + QTest::addColumn<QMetaMethod::MethodType>("methodType"); + QTest::addColumn<QString>("returnTypeName"); + QTest::addColumn<QList<QByteArray> >("parameterTypeNames"); + QTest::addColumn<QList<QByteArray> >("parameterNames"); + + QTest::newRow("testFunction()") << "method.1.qml" + << "testFunction()" + << QMetaMethod::Slot + << "QVariant" + << QList<QByteArray>() + << QList<QByteArray>(); + QTest::newRow("testFunction(foo)") << "method.2.qml" + << "testFunction(QVariant)" + << QMetaMethod::Slot + << "QVariant" + << (QList<QByteArray>() << "QVariant") + << (QList<QByteArray>() << "foo"); + QTest::newRow("testFunction(foo, bar, baz)") << "method.3.qml" + << "testFunction(QVariant,QVariant,QVariant)" + << QMetaMethod::Slot + << "QVariant" + << (QList<QByteArray>() << "QVariant" << "QVariant" << "QVariant") + << (QList<QByteArray>() << "foo" << "bar" << "baz"); + QTest::newRow("testSignal") << "signal.1.qml" + << "testSignal()" + << QMetaMethod::Signal + << "" + << QList<QByteArray>() + << QList<QByteArray>(); + QTest::newRow("testSignal(string foo)") << "signal.2.qml" + << "testSignal(QString)" + << QMetaMethod::Signal + << "" + << (QList<QByteArray>() << "QString") + << (QList<QByteArray>() << "foo"); + QTest::newRow("testSignal(int foo, bool bar, real baz)") << "signal.3.qml" + << "testSignal(int,bool,qreal)" + << QMetaMethod::Signal + << "" + << (QList<QByteArray>() << "int" << "bool" << "qreal") + << (QList<QByteArray>() << "foo" << "bar" << "baz"); + QTest::newRow("testSignal(variant foo, var bar)") << "signal.4.qml" + << "testSignal(QVariant,QVariant)" + << QMetaMethod::Signal + << "" + << (QList<QByteArray>() << "QVariant" << "QVariant") + << (QList<QByteArray>() << "foo" << "bar"); + QTest::newRow("testSignal(color foo, date bar, url baz)") << "signal.5.qml" + << "testSignal(QColor,QDateTime,QUrl)" + << QMetaMethod::Signal + << "" + << (QList<QByteArray>() << "QColor" << "QDateTime" << "QUrl") + << (QList<QByteArray>() << "foo" << "bar" << "baz"); +} + +void tst_QQmlMetaObject::method() +{ + QFETCH(QString, testFile); + QFETCH(QString, signature); + QFETCH(QMetaMethod::MethodType, methodType); + QFETCH(QString, returnTypeName); + QFETCH(QList<QByteArray>, parameterTypeNames); + QFETCH(QList<QByteArray>, parameterNames); + + QCOMPARE(parameterTypeNames.size(), parameterNames.size()); + + QQmlEngine engine; + QQmlComponent component(&engine, testFileUrl(testFile)); + QObject *object = component.create(); + QVERIFY(object != 0); + + const QMetaObject *mo = object->metaObject(); + QVERIFY(mo->superClass() != 0); + QVERIFY(QByteArray(mo->className()).contains("_QML_")); + QCOMPARE(mo->methodOffset(), mo->superClass()->methodCount()); + QCOMPARE(mo->methodCount(), mo->superClass()->methodCount() + 1); + + QMetaMethod method = mo->method(mo->methodOffset()); + QCOMPARE(method.methodType(), methodType); + QCOMPARE(QString::fromUtf8(method.signature()), signature); + QCOMPARE(method.access(), QMetaMethod::Protected); + QCOMPARE(method.parameterTypes(), parameterTypeNames); + QCOMPARE(method.parameterNames(), parameterNames); + QCOMPARE(method.tag(), ""); + QCOMPARE(QString::fromUtf8(method.typeName()), returnTypeName); + + delete object; +} + +QTEST_MAIN(tst_QQmlMetaObject) + +#include "tst_qqmlmetaobject.moc" diff --git a/tests/auto/qml/qqmlmoduleplugin/empty.json b/tests/auto/qml/qqmlmoduleplugin/empty.json new file mode 100644 index 0000000000..0967ef424b --- /dev/null +++ b/tests/auto/qml/qqmlmoduleplugin/empty.json @@ -0,0 +1 @@ +{} diff --git a/tests/auto/qml/qqmlmoduleplugin/plugin.2.1/plugin.cpp b/tests/auto/qml/qqmlmoduleplugin/plugin.2.1/plugin.cpp index 53696b3598..03065b2f27 100644 --- a/tests/auto/qml/qqmlmoduleplugin/plugin.2.1/plugin.cpp +++ b/tests/auto/qml/qqmlmoduleplugin/plugin.2.1/plugin.cpp @@ -66,6 +66,8 @@ private: class MyPlugin : public QQmlExtensionPlugin { Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface" FILE "../empty.json") + public: MyPlugin() { @@ -80,5 +82,3 @@ public: }; #include "plugin.moc" - -Q_EXPORT_PLUGIN2(plugin, MyPlugin); diff --git a/tests/auto/qml/qqmlmoduleplugin/plugin.2/plugin.cpp b/tests/auto/qml/qqmlmoduleplugin/plugin.2/plugin.cpp index f62b8addd4..e2ff43dffe 100644 --- a/tests/auto/qml/qqmlmoduleplugin/plugin.2/plugin.cpp +++ b/tests/auto/qml/qqmlmoduleplugin/plugin.2/plugin.cpp @@ -66,6 +66,8 @@ private: class MyPlugin : public QQmlExtensionPlugin { Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface" FILE "../empty.json") + public: MyPlugin() { @@ -80,5 +82,3 @@ public: }; #include "plugin.moc" - -Q_EXPORT_PLUGIN2(plugin, MyPlugin); diff --git a/tests/auto/qml/qqmlmoduleplugin/plugin/plugin.cpp b/tests/auto/qml/qqmlmoduleplugin/plugin/plugin.cpp index 470aa7a37c..5a91852d22 100644 --- a/tests/auto/qml/qqmlmoduleplugin/plugin/plugin.cpp +++ b/tests/auto/qml/qqmlmoduleplugin/plugin/plugin.cpp @@ -65,6 +65,8 @@ private: class MyPlugin : public QQmlExtensionPlugin { Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface" FILE "../empty.json") + public: MyPlugin() { @@ -79,5 +81,3 @@ public: }; #include "plugin.moc" - -Q_EXPORT_PLUGIN2(plugin, MyPlugin); diff --git a/tests/auto/qml/qqmlmoduleplugin/pluginMixed/plugin.cpp b/tests/auto/qml/qqmlmoduleplugin/pluginMixed/plugin.cpp index eec8e3f3af..66c59fde81 100644 --- a/tests/auto/qml/qqmlmoduleplugin/pluginMixed/plugin.cpp +++ b/tests/auto/qml/qqmlmoduleplugin/pluginMixed/plugin.cpp @@ -56,6 +56,8 @@ public: class MyMixedPlugin : public QQmlExtensionPlugin { Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface" FILE "../empty.json") + public: MyMixedPlugin() { @@ -69,5 +71,3 @@ public: }; #include "plugin.moc" - -Q_EXPORT_PLUGIN2(plugin, MyMixedPlugin); diff --git a/tests/auto/qml/qqmlmoduleplugin/pluginVersion/plugin.cpp b/tests/auto/qml/qqmlmoduleplugin/pluginVersion/plugin.cpp index 8645028317..a3142ef9b3 100644 --- a/tests/auto/qml/qqmlmoduleplugin/pluginVersion/plugin.cpp +++ b/tests/auto/qml/qqmlmoduleplugin/pluginVersion/plugin.cpp @@ -56,6 +56,8 @@ public: class MyMixedPlugin : public QQmlExtensionPlugin { Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface" FILE "../empty.json") + public: MyMixedPlugin() { @@ -69,5 +71,3 @@ public: }; #include "plugin.moc" - -Q_EXPORT_PLUGIN2(plugin, MyMixedPlugin); diff --git a/tests/auto/qml/qqmlmoduleplugin/pluginWithQmlFile/plugin.cpp b/tests/auto/qml/qqmlmoduleplugin/pluginWithQmlFile/plugin.cpp index 1217df4d0e..a2262f15d6 100644 --- a/tests/auto/qml/qqmlmoduleplugin/pluginWithQmlFile/plugin.cpp +++ b/tests/auto/qml/qqmlmoduleplugin/pluginWithQmlFile/plugin.cpp @@ -46,6 +46,8 @@ class MyPlugin : public QQmlExtensionPlugin { Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface" FILE "../empty.json") + public: void registerTypes(const char *uri) { @@ -54,5 +56,3 @@ public: }; #include "plugin.moc" - -Q_EXPORT_PLUGIN2(plugin, MyPlugin); diff --git a/tests/auto/qml/qqmlmoduleplugin/pluginWrongCase/plugin.cpp b/tests/auto/qml/qqmlmoduleplugin/pluginWrongCase/plugin.cpp index e0257fe249..a5fc6c1d37 100644 --- a/tests/auto/qml/qqmlmoduleplugin/pluginWrongCase/plugin.cpp +++ b/tests/auto/qml/qqmlmoduleplugin/pluginWrongCase/plugin.cpp @@ -65,6 +65,8 @@ private: class MyPlugin : public QQmlExtensionPlugin { Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface" FILE "../empty.json") + public: MyPlugin() { @@ -79,5 +81,3 @@ public: }; #include "plugin.moc" - -Q_EXPORT_PLUGIN2(plugin, MyPlugin); diff --git a/tests/auto/qml/qqmlvaluetypes/data/nonValueTypeComparison.qml b/tests/auto/qml/qqmlvaluetypes/data/nonValueTypeComparison.qml new file mode 100644 index 0000000000..0ffa5eb666 --- /dev/null +++ b/tests/auto/qml/qqmlvaluetypes/data/nonValueTypeComparison.qml @@ -0,0 +1,10 @@ +import QtQuick 2.0 + +Item { + property variant somepoint: Qt.point(1,2) + property variant randomjsobj: {"some": 1, "thing": 2} + property bool test1: somepoint != randomjsobj + + property variant similar: {"x":1, "y":2} + property bool test2: somepoint != similar +} diff --git a/tests/auto/qml/qqmlvaluetypes/tst_qqmlvaluetypes.cpp b/tests/auto/qml/qqmlvaluetypes/tst_qqmlvaluetypes.cpp index 695dbe4147..0aa223e733 100644 --- a/tests/auto/qml/qqmlvaluetypes/tst_qqmlvaluetypes.cpp +++ b/tests/auto/qml/qqmlvaluetypes/tst_qqmlvaluetypes.cpp @@ -93,6 +93,7 @@ private slots: void returnValues(); void varAssignment(); void bindingsSpliceCorrectly(); + void nonValueTypeComparison(); private: QQmlEngine engine; @@ -950,7 +951,6 @@ void tst_qqmlvaluetypes::autoBindingRemoval() delete object; } - /* { QQmlComponent component(&engine, testFileUrl("autoBindingRemoval.2.qml")); MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create()); @@ -975,6 +975,8 @@ void tst_qqmlvaluetypes::autoBindingRemoval() { QQmlComponent component(&engine, testFileUrl("autoBindingRemoval.3.qml")); + QString warning = component.url().toString() + ":6: Unable to assign [undefined] to QRect"; + QTest::ignoreMessage(QtWarningMsg, qPrintable(warning)); MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create()); QVERIFY(object != 0); @@ -992,7 +994,6 @@ void tst_qqmlvaluetypes::autoBindingRemoval() delete object; } -*/ } // Test that property value sources assign to value types @@ -1301,6 +1302,18 @@ void tst_qqmlvaluetypes::bindingsSpliceCorrectly() } } +void tst_qqmlvaluetypes::nonValueTypeComparison() +{ + QQmlComponent component(&engine, testFileUrl("nonValueTypeComparison.qml")); + QObject *object = component.create(); + QVERIFY(object != 0); + + QCOMPARE(object->property("test1").toBool(), true); + QCOMPARE(object->property("test2").toBool(), true); + + delete object; +} + QTEST_MAIN(tst_qqmlvaluetypes) #include "tst_qqmlvaluetypes.moc" diff --git a/tests/auto/qml/qquickfolderlistmodel/tst_qquickfolderlistmodel.cpp b/tests/auto/qml/qquickfolderlistmodel/tst_qquickfolderlistmodel.cpp index a6d90cf688..3761929362 100644 --- a/tests/auto/qml/qquickfolderlistmodel/tst_qquickfolderlistmodel.cpp +++ b/tests/auto/qml/qquickfolderlistmodel/tst_qquickfolderlistmodel.cpp @@ -170,8 +170,8 @@ void tst_qquickfolderlistmodel::refresh() flm->setProperty("sortReversed", true); - QCOMPARE(removeStart, 0); - QCOMPARE(removeEnd, count-1); + QTRY_COMPARE(removeStart, 0); + QTRY_COMPARE(removeEnd, count-1); // wait for refresh } QTEST_MAIN(tst_qquickfolderlistmodel) diff --git a/tests/auto/qml/v4/data/colorType.qml b/tests/auto/qml/v4/data/colorType.qml new file mode 100644 index 0000000000..f6a98a4a3e --- /dev/null +++ b/tests/auto/qml/v4/data/colorType.qml @@ -0,0 +1,18 @@ +import QtQuick 2.0 + +QtObject { + property bool useMyColor: true + property color myColor: "red" + property color myOtherColor: "green" + + property color test1: useMyColor ? myColor : myOtherColor + property color test2: useMyColor ? "red" : "green" + property color test3: useMyColor ? myColor : "green" + + property bool test4: !myColor ? false : true + + property bool test5: myColor != "red" + property bool test6: myColor == "#ff0000" + property bool test7: myColor != "#00ff00" +} + diff --git a/tests/auto/qml/v4/tst_v4.cpp b/tests/auto/qml/v4/tst_v4.cpp index 559abf7388..4e3e71f717 100644 --- a/tests/auto/qml/v4/tst_v4.cpp +++ b/tests/auto/qml/v4/tst_v4.cpp @@ -45,6 +45,7 @@ #include <QtQml/qqmlengine.h> #include <QtQml/qqmlcomponent.h> #include <QtCore/qdebug.h> +#include <QtGui/qcolor.h> #include <private/qv4compiler_p.h> @@ -73,6 +74,7 @@ private slots: void stringComparison(); void unaryMinus(); void unaryPlus(); + void colorType(); private: QQmlEngine engine; @@ -348,6 +350,22 @@ void tst_v4::unaryPlus() delete o; } +void tst_v4::colorType() +{ + QQmlComponent component(&engine, testFileUrl("colorType.qml")); + + QObject *o = component.create(); + QVERIFY(o != 0); + QCOMPARE(o->property("test1").value<QColor>(), QColor("red")); + QCOMPARE(o->property("test2").value<QColor>(), QColor("red")); + QCOMPARE(o->property("test3").value<QColor>(), QColor("red")); + QCOMPARE(o->property("test4").toBool(), true); + QCOMPARE(o->property("test5").toBool(), true); + QCOMPARE(o->property("test6").toBool(), true); + QCOMPARE(o->property("test7").toBool(), true); + delete o; +} + QTEST_MAIN(tst_v4) #include "tst_v4.moc" diff --git a/tests/auto/quick/examples/tst_examples.cpp b/tests/auto/quick/examples/tst_examples.cpp index 24a60cb08a..482053e158 100644 --- a/tests/auto/quick/examples/tst_examples.cpp +++ b/tests/auto/quick/examples/tst_examples.cpp @@ -88,33 +88,27 @@ tst_examples::tst_examples() // Add files to exclude here excludedFiles << "doc/src/snippets/qml/listmodel.qml"; //Just a ListModel, no root QQuickItem - // Add directories you want excluded here - excludedDirs << "examples/qml/text/fonts"; // QTBUG-21415 + // Add directories you want excluded here (don't add examples/, because they install to examples/qtdeclarative/) + excludedDirs << "shared"; //Not an example + excludedDirs << "qtquick/text/fonts"; // QTBUG-21415 excludedDirs << "doc/src/snippets/qml/path"; //No root QQuickItem - - // Not run in QQuickView - excludedDirs << "examples/qml/qtquick1"; + excludedDirs << "tutorials/gettingStartedQml"; //C++ example, but no cpp files in root dir // These snippets are not expected to run on their own. excludedDirs << "doc/src/snippets/qml/visualdatamodel_rootindex"; excludedDirs << "doc/src/snippets/qml/qtbinding"; excludedDirs << "doc/src/snippets/qml/imports"; - excludedDirs << "doc/src/snippets/qtquick1/visualdatamodel_rootindex"; - excludedDirs << "doc/src/snippets/qtquick1/qtbinding"; - excludedDirs << "doc/src/snippets/qtquick1/imports"; #ifdef QT_NO_WEBKIT - excludedDirs << "examples/qml/modelviews/webview"; - excludedDirs << "examples/qml/webbrowser"; + excludedDirs << "qtquick/modelviews/webview"; + excludedDirs << "demos/webbrowser"; excludedDirs << "doc/src/snippets/qml/webview"; - excludedDirs << "doc/src/snippets/qtquick1/webview"; #endif #ifdef QT_NO_XMLPATTERNS - excludedDirs << "examples/qml/xml/xmldata"; - excludedDirs << "examples/qml/twitter"; - excludedDirs << "examples/qml/flickr"; - excludedDirs << "examples/qml/photoviewer"; + excludedDirs << "demos/twitter"; + excludedDirs << "demos/flickr"; + excludedDirs << "demos/photoviewer"; #endif } @@ -230,12 +224,10 @@ void tst_examples::sgexamples_data() { QTest::addColumn<QString>("file"); - QString examples = QLatin1String(SRCDIR) + "/../../../../examples/qml/"; - QString tutorials = QLatin1String(SRCDIR) + "/../../../../examples/tutorials/"; //Only qml tutorials since modularization + QString examples = QLatin1String(SRCDIR) + "/../../../../examples/"; QStringList files; files << findQmlFiles(QDir(examples)); - files << findQmlFiles(QDir(tutorials)); foreach (const QString &file, files) QTest::newRow(qPrintable(file)) << file; diff --git a/tests/auto/quick/qquickanchors/data/stretch.qml b/tests/auto/quick/qquickanchors/data/stretch.qml new file mode 100644 index 0000000000..64e23e30b5 --- /dev/null +++ b/tests/auto/quick/qquickanchors/data/stretch.qml @@ -0,0 +1,39 @@ +import QtQuick 2.0 + +Rectangle { + width: 400; height: 400 + + Rectangle { + id: rect1 + x: 20; y: 20; + height: 360; width: 360; + + Rectangle { + id: rect2; objectName: "stretcher" + anchors.verticalCenter: rect1.verticalCenter + anchors.bottom: rect3.top + anchors.horizontalCenter: rect1.horizontalCenter + anchors.left: rect3.left + } + + Rectangle { + id: rect3 + x: 160; y: 230 + width: 10 + height: 10 + } + + Rectangle { + id: rect4; objectName: "stretcher2" + anchors.verticalCenter: rect1.verticalCenter + anchors.top: rect5.top + } + + Rectangle { + id: rect5 + x: 160; y: 130 + width: 10 + height: 10 + } + } +} diff --git a/tests/auto/quick/qquickanchors/tst_qquickanchors.cpp b/tests/auto/quick/qquickanchors/tst_qquickanchors.cpp index 749b11f919..dd1f9f77ae 100644 --- a/tests/auto/quick/qquickanchors/tst_qquickanchors.cpp +++ b/tests/auto/quick/qquickanchors/tst_qquickanchors.cpp @@ -83,6 +83,7 @@ private slots: void fillRTL(); void margins(); void marginsRTL(); + void stretch(); }; void tst_qquickanchors::basicAnchors() @@ -472,6 +473,10 @@ void tst_qquickanchors::fill() qApp->processEvents(); QQuickRectangle* rect = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("filler")); QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); + QCOMPARE(rectPrivate->anchors()->leftMargin(), 10.0); + QCOMPARE(rectPrivate->anchors()->topMargin(), 30.0); + QCOMPARE(rectPrivate->anchors()->rightMargin(), 20.0); + QCOMPARE(rectPrivate->anchors()->bottomMargin(), 40.0); QCOMPARE(rect->x(), 0.0 + 10.0); QCOMPARE(rect->y(), 0.0 + 30.0); QCOMPARE(rect->width(), 200.0 - 10.0 - 20.0); @@ -481,6 +486,10 @@ void tst_qquickanchors::fill() rectPrivate->anchors()->setRightMargin(0.0); rectPrivate->anchors()->setBottomMargin(0.0); rectPrivate->anchors()->setTopMargin(10.0); + QCOMPARE(rectPrivate->anchors()->leftMargin(), 20.0); + QCOMPARE(rectPrivate->anchors()->topMargin(), 10.0); + QCOMPARE(rectPrivate->anchors()->rightMargin(), 0.0); + QCOMPARE(rectPrivate->anchors()->bottomMargin(), 0.0); QCOMPARE(rect->x(), 0.0 + 20.0); QCOMPARE(rect->y(), 0.0 + 10.0); QCOMPARE(rect->width(), 200.0 - 20.0); @@ -523,11 +532,15 @@ void tst_qquickanchors::centerIn() QQuickRectangle* rect = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("centered")); QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); + QCOMPARE(rectPrivate->anchors()->horizontalCenterOffset(), 10.0); + QCOMPARE(rectPrivate->anchors()->verticalCenterOffset(), 30.0); QCOMPARE(rect->x(), 75.0 + 10); QCOMPARE(rect->y(), 75.0 + 30); //Alter Offsets (tests QTBUG-6631) rectPrivate->anchors()->setHorizontalCenterOffset(-20.0); rectPrivate->anchors()->setVerticalCenterOffset(-10.0); + QCOMPARE(rectPrivate->anchors()->horizontalCenterOffset(), -20.0); + QCOMPARE(rectPrivate->anchors()->verticalCenterOffset(), -10.0); QCOMPARE(rect->x(), 75.0 - 20.0); QCOMPARE(rect->y(), 75.0 - 10.0); @@ -623,6 +636,11 @@ void tst_qquickanchors::margins() qApp->processEvents(); QQuickRectangle* rect = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("filler")); QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); + QCOMPARE(rectPrivate->anchors()->margins(), 10.0); + QCOMPARE(rectPrivate->anchors()->topMargin(), 6.0); + QCOMPARE(rectPrivate->anchors()->leftMargin(), 5.0); + QCOMPARE(rectPrivate->anchors()->bottomMargin(), 10.0); + QCOMPARE(rectPrivate->anchors()->rightMargin(), 10.0); QCOMPARE(rect->x(), 5.0); QCOMPARE(rect->y(), 6.0); QCOMPARE(rect->width(), 200.0 - 5.0 - 10.0); @@ -631,6 +649,12 @@ void tst_qquickanchors::margins() rectPrivate->anchors()->setTopMargin(0.0); rectPrivate->anchors()->setMargins(20.0); + QCOMPARE(rectPrivate->anchors()->margins(), 20.0); + QEXPECT_FAIL("","QTBUG-24515", Continue); + QCOMPARE(rectPrivate->anchors()->topMargin(), 0.0); + QCOMPARE(rectPrivate->anchors()->leftMargin(), 5.0); + QCOMPARE(rectPrivate->anchors()->bottomMargin(), 20.0); + QCOMPARE(rectPrivate->anchors()->rightMargin(), 20.0); QCOMPARE(rect->x(), 5.0); QCOMPARE(rect->y(), 20.0); QCOMPARE(rect->width(), 200.0 - 5.0 - 20.0); @@ -663,6 +687,23 @@ void tst_qquickanchors::marginsRTL() delete view; } +void tst_qquickanchors::stretch() +{ + QQuickView *view = new QQuickView(testFileUrl("stretch.qml")); + + qApp->processEvents(); + QQuickRectangle* rect = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("stretcher")); + QCOMPARE(rect->x(), 160.0); + QCOMPARE(rect->y(), 130.0); + QCOMPARE(rect->width(), 40.0); + QCOMPARE(rect->height(), 100.0); + + QQuickRectangle* rect2 = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("stretcher2")); + QCOMPARE(rect2->y(), 130.0); + QCOMPARE(rect2->height(), 100.0); + + delete view; +} QTEST_MAIN(tst_qquickanchors) diff --git a/tests/auto/quick/qquickanimatedsprite/data/basic.qml b/tests/auto/quick/qquickanimatedsprite/data/basic.qml new file mode 100644 index 0000000000..2dd20630d9 --- /dev/null +++ b/tests/auto/quick/qquickanimatedsprite/data/basic.qml @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +Rectangle { + color: "black" + width: 320 + height: 320 + + AnimatedSprite { + objectName: "sprite" + loops: 3 + source: "squarefacesprite.png" + frameCount: 6 + frameDuration: 120 + width: 160 + height: 160 + } +} diff --git a/tests/auto/quick/qquickanimatedsprite/data/squarefacesprite.png b/tests/auto/quick/qquickanimatedsprite/data/squarefacesprite.png Binary files differnew file mode 100644 index 0000000000..f9a5d5fcce --- /dev/null +++ b/tests/auto/quick/qquickanimatedsprite/data/squarefacesprite.png diff --git a/tests/auto/quick/qquickanimatedsprite/qquickanimatedsprite.pro b/tests/auto/quick/qquickanimatedsprite/qquickanimatedsprite.pro new file mode 100644 index 0000000000..3c20ccea66 --- /dev/null +++ b/tests/auto/quick/qquickanimatedsprite/qquickanimatedsprite.pro @@ -0,0 +1,15 @@ +CONFIG += testcase +TARGET = tst_qquickanimatedsprite +SOURCES += tst_qquickanimatedsprite.cpp + +include (../../shared/util.pri) + +macx:CONFIG -= app_bundle + +testDataFiles.files = data +testDataFiles.path = . +DEPLOYMENT += testDataFiles + +CONFIG += parallel_test + +QT += core-private gui-private qml-private quick-private network testlib diff --git a/tests/auto/quick/qquickanimatedsprite/tst_qquickanimatedsprite.cpp b/tests/auto/quick/qquickanimatedsprite/tst_qquickanimatedsprite.cpp new file mode 100644 index 0000000000..37625cfed6 --- /dev/null +++ b/tests/auto/quick/qquickanimatedsprite/tst_qquickanimatedsprite.cpp @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include <QtTest/QtTest> +#include "../../shared/util.h" +#include <QtQuick/qquickview.h> +#include <private/qquickanimatedsprite_p.h> + +class tst_qquickanimatedsprite : public QQmlDataTest +{ + Q_OBJECT +public: + tst_qquickanimatedsprite(){} + +private slots: + void test_properties(); +}; + +void tst_qquickanimatedsprite::test_properties() +{ + QQuickView *canvas = new QQuickView(0); + + canvas->setSource(testFileUrl("basic.qml")); + canvas->show(); + QTest::qWaitForWindowShown(canvas); + + QVERIFY(canvas->rootObject()); + QQuickAnimatedSprite* sprite = canvas->rootObject()->findChild<QQuickAnimatedSprite*>("sprite"); + QVERIFY(sprite); + + QVERIFY(sprite->running()); + QVERIFY(!sprite->paused()); + QVERIFY(sprite->interpolate()); + QCOMPARE(sprite->loops(), 3); + + sprite->setRunning(false); + QVERIFY(!sprite->running()); + sprite->setInterpolate(false); + QVERIFY(!sprite->interpolate()); + + delete canvas; +} + +QTEST_MAIN(tst_qquickanimatedsprite) + +#include "tst_qquickanimatedsprite.moc" diff --git a/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp b/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp index 108bce64f9..dd010999b4 100644 --- a/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp +++ b/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp @@ -44,9 +44,10 @@ #include <QtQuick/qquickview.h> #include <QtQml/private/qanimationgroupjob_p.h> #include <QtQuick/private/qquickrectangle_p.h> -#include <QtQuick/private/qquickanimation_p.h> -#include <QtQuick/private/qquicktransition_p.h> #include <QtQuick/private/qquickitemanimation_p.h> +#include <QtQuick/private/qquickitemanimation_p_p.h> +#include <QtQuick/private/qquicktransition_p.h> +#include <QtQuick/private/qquickanimation_p.h> #include <QtQuick/private/qquickpathinterpolator_p.h> #include <QtQuick/private/qquickitem_p.h> #include <QEasingCurve> @@ -105,6 +106,7 @@ private slots: void pauseBindingBug(); void pauseBug(); void loopingBug(); + void anchorBug(); }; #define QTIMED_COMPARE(lhs, rhs) do { \ @@ -1314,6 +1316,19 @@ void tst_qquickanimations::loopingBug() delete obj; } +//QTBUG-24532 +void tst_qquickanimations::anchorBug() +{ + QQuickAnchorAnimation animation; + animation.setDuration(5000); + animation.setEasing(QEasingCurve(QEasingCurve::InOutBack)); + animation.start(); + animation.pause(); + + QCOMPARE(animation.qtAnimation()->duration(), 5000); + QCOMPARE(static_cast<QQuickBulkValueAnimator*>(animation.qtAnimation())->easingCurve(), QEasingCurve(QEasingCurve::InOutBack)); +} + QTEST_MAIN(tst_qquickanimations) #include "tst_qquickanimations.moc" diff --git a/tests/auto/quick/qquickdroparea/qquickdroparea.pro b/tests/auto/quick/qquickdroparea/qquickdroparea.pro index 5ae8d222c4..41bcaacf79 100644 --- a/tests/auto/quick/qquickdroparea/qquickdroparea.pro +++ b/tests/auto/quick/qquickdroparea/qquickdroparea.pro @@ -7,3 +7,5 @@ SOURCES += tst_qquickdroparea.cpp CONFIG += parallel_test QT += core-private gui-private qml-private quick-private network testlib + +mac: CONFIG += insignificant_test # QTBUG-24588 diff --git a/tests/auto/quick/qquickdroparea/tst_qquickdroparea.cpp b/tests/auto/quick/qquickdroparea/tst_qquickdroparea.cpp index ed7a0aa0fa..38fb02d085 100644 --- a/tests/auto/quick/qquickdroparea/tst_qquickdroparea.cpp +++ b/tests/auto/quick/qquickdroparea/tst_qquickdroparea.cpp @@ -48,6 +48,7 @@ #include <QtQml/qqmlexpression.h> #include <QtGui/qwindowsysteminterface_qpa.h> +#include <QtGui/qplatformdrag_qpa.h> template <typename T> static T evaluate(QObject *scope, const QString &expression) { @@ -193,14 +194,14 @@ void tst_QQuickDropArea::containsDrag_external() QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), false); QCOMPARE(evaluate<bool>(dropArea, "hasDrag"), false); - QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50)); + QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50), Qt::CopyAction); QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), true); QCOMPARE(evaluate<bool>(dropArea, "hasDrag"), true); QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 1); QCOMPARE(evaluate<int>(dropArea, "exitEvents"), 0); evaluate<void>(dropArea, "{ enterEvents = 0; exitEvents = 0 }"); - QWindowSystemInterface::handleDrag(&alternateCanvas, &data, QPoint(50, 50)); + QWindowSystemInterface::handleDrag(&alternateCanvas, &data, QPoint(50, 50), Qt::CopyAction); QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), false); QCOMPARE(evaluate<bool>(dropArea, "hasDrag"), false); QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 0); @@ -208,13 +209,13 @@ void tst_QQuickDropArea::containsDrag_external() evaluate<void>(dropArea, "{ enterEvents = 0; exitEvents = 0 }"); - QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(150, 50)); + QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(150, 50), Qt::CopyAction); QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), false); QCOMPARE(evaluate<bool>(dropArea, "hasDrag"), false); QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 0); QCOMPARE(evaluate<int>(dropArea, "exitEvents"), 0); - QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50)); + QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50), Qt::CopyAction); QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), true); QCOMPARE(evaluate<bool>(dropArea, "hasDrag"), true); QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 1); @@ -222,13 +223,13 @@ void tst_QQuickDropArea::containsDrag_external() evaluate<void>(dropArea, "{ enterEvents = 0; exitEvents = 0 }"); - QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(150, 50)); + QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(150, 50), Qt::CopyAction); QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), false); QCOMPARE(evaluate<bool>(dropArea, "hasDrag"), false); QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 0); QCOMPARE(evaluate<int>(dropArea, "exitEvents"), 1); - QWindowSystemInterface::handleDrop(&canvas, &data, QPoint(150, 50)); + QWindowSystemInterface::handleDrop(&canvas, &data, QPoint(150, 50), Qt::CopyAction); } void tst_QQuickDropArea::keys_internal() @@ -363,80 +364,80 @@ void tst_QQuickDropArea::keys_external() QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), false); - QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50)); + QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50), Qt::CopyAction); QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), true); QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 1); QCOMPARE(dropArea->property("dragKeys").toStringList(), QStringList() << "text/x-red" << "text/x-blue"); - QWindowSystemInterface::handleDrag(&alternateCanvas, &data, QPoint(50, 50)); + QWindowSystemInterface::handleDrag(&alternateCanvas, &data, QPoint(50, 50), Qt::CopyAction); evaluate<void>(dropArea, "keys = \"text/x-blue\""); QCOMPARE(dropArea->property("keys").toStringList(), QStringList() << "text/x-blue"); QCOMPARE(dropArea->property("dropKeys").toStringList(), QStringList() << "text/x-blue"); evaluate<void>(dropArea, "{ enterEvents = 0; dragKeys = undefined }"); - QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50)); + QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50), Qt::CopyAction); QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), true); QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 1); QCOMPARE(dropArea->property("dragKeys").toStringList(), QStringList() << "text/x-red" << "text/x-blue"); - QWindowSystemInterface::handleDrag(&alternateCanvas, &data, QPoint(50, 50)); + QWindowSystemInterface::handleDrag(&alternateCanvas, &data, QPoint(50, 50), Qt::CopyAction); evaluate<void>(dropArea, "keys = \"text/x-red\""); QCOMPARE(dropArea->property("keys").toStringList(), QStringList() << "text/x-red"); QCOMPARE(dropArea->property("dropKeys").toStringList(), QStringList() << "text/x-red"); evaluate<void>(dropArea, "{ enterEvents = 0; dragKeys = undefined }"); - QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50)); + QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50), Qt::CopyAction); QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), true); QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 1); QCOMPARE(dropArea->property("dragKeys").toStringList(), QStringList() << "text/x-red" << "text/x-blue"); - QWindowSystemInterface::handleDrag(&alternateCanvas, &data, QPoint(50, 50)); + QWindowSystemInterface::handleDrag(&alternateCanvas, &data, QPoint(50, 50), Qt::CopyAction); evaluate<void>(dropArea, "keys = \"text/x-green\""); QCOMPARE(dropArea->property("keys").toStringList(), QStringList() << "text/x-green"); QCOMPARE(dropArea->property("dropKeys").toStringList(), QStringList() << "text/x-green"); evaluate<void>(dropArea, "{ enterEvents = 0; dragKeys = undefined }"); - QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50)); + QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50), Qt::CopyAction); QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), false); QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 0); - QWindowSystemInterface::handleDrag(&alternateCanvas, &data, QPoint(50, 50)); + QWindowSystemInterface::handleDrag(&alternateCanvas, &data, QPoint(50, 50), Qt::CopyAction); evaluate<void>(dropArea, "keys = [\"text/x-red\", \"text/x-green\"]"); QCOMPARE(dropArea->property("keys").toStringList(), QStringList() << "text/x-red" << "text/x-green"); QCOMPARE(dropArea->property("dropKeys").toStringList(), QStringList() << "text/x-red" << "text/x-green"); evaluate<void>(dropArea, "{ enterEvents = 0; dragKeys = undefined }"); - QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50)); + QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50), Qt::CopyAction); QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), true); QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 1); QCOMPARE(dropArea->property("dragKeys").toStringList(), QStringList() << "text/x-red" << "text/x-blue"); - QWindowSystemInterface::handleDrag(&alternateCanvas, &data, QPoint(50, 50)); + QWindowSystemInterface::handleDrag(&alternateCanvas, &data, QPoint(50, 50), Qt::CopyAction); data.removeFormat("text/x-red"); data.removeFormat("text/x-blue"); evaluate<void>(dropArea, "{ enterEvents = 0; dragKeys = undefined }"); - QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50)); + QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50), Qt::CopyAction); QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), false); QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 0); - QWindowSystemInterface::handleDrag(&alternateCanvas, &data, QPoint(50, 50)); + QWindowSystemInterface::handleDrag(&alternateCanvas, &data, QPoint(50, 50), Qt::CopyAction); evaluate<void>(dropArea, "keys = []"); QCOMPARE(dropArea->property("keys").toStringList(), QStringList()); QCOMPARE(dropArea->property("dropKeys").toStringList(), QStringList()); evaluate<void>(dropArea, "{ enterEvents = 0; dragKeys = undefined }"); - QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50)); + QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50), Qt::CopyAction); QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), true); QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 1); QCOMPARE(dropArea->property("dragKeys").toStringList(), QStringList()); - QWindowSystemInterface::handleDrag(&alternateCanvas, &data, QPoint(50, 50)); + QWindowSystemInterface::handleDrag(&alternateCanvas, &data, QPoint(50, 50), Qt::CopyAction); data.setData("text/x-red", "red"); data.setData("text/x-blue", "blue"); QCOMPARE(dropArea->property("keys").toStringList(), QStringList()); QCOMPARE(dropArea->property("dropKeys").toStringList(), QStringList()); evaluate<void>(dropArea, "{ enterEvents = 0; dragKeys = undefined }"); - QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50)); + QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50), Qt::CopyAction); QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), true); QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 1); QCOMPARE(dropArea->property("dragKeys").toStringList(), QStringList() << "text/x-red" << "text/x-blue"); - QWindowSystemInterface::handleDrop(&canvas, &data, QPoint(50, 50)); + QWindowSystemInterface::handleDrop(&canvas, &data, QPoint(50, 50), Qt::CopyAction); } void tst_QQuickDropArea::source_internal() @@ -589,7 +590,7 @@ void tst_QQuickDropArea::position_external() QMimeData data; - QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50)); + QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50), Qt::CopyAction); QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 1); QCOMPARE(evaluate<int>(dropArea, "moveEvents"), 1); QCOMPARE(evaluate<qreal>(dropArea, "drag.x"), qreal(50)); @@ -600,7 +601,7 @@ void tst_QQuickDropArea::position_external() QCOMPARE(evaluate<qreal>(dropArea, "eventY"), qreal(50)); evaluate<void>(dropArea, "{ enterEvents = 0; moveEvents = 0; eventX = -1; eventY = -1 }"); - QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(40, 50)); + QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(40, 50), Qt::CopyAction); QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 0); QCOMPARE(evaluate<int>(dropArea, "moveEvents"), 1); QCOMPARE(evaluate<qreal>(dropArea, "drag.x"), qreal(40)); @@ -611,7 +612,7 @@ void tst_QQuickDropArea::position_external() QCOMPARE(evaluate<qreal>(dropArea, "eventY"), qreal(50)); evaluate<void>(dropArea, "{ enterEvents = 0; moveEvents = 0; eventX = -1; eventY = -1 }"); - QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(75, 25)); + QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(75, 25), Qt::CopyAction); QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 0); QCOMPARE(evaluate<int>(dropArea, "moveEvents"), 1); QCOMPARE(evaluate<qreal>(dropArea, "drag.x"), qreal(75)); @@ -621,7 +622,7 @@ void tst_QQuickDropArea::position_external() QCOMPARE(evaluate<qreal>(dropArea, "eventX"), qreal(75)); QCOMPARE(evaluate<qreal>(dropArea, "eventY"), qreal(25)); - QWindowSystemInterface::handleDrop(&canvas, &data, QPoint(75, 25)); + QWindowSystemInterface::handleDrop(&canvas, &data, QPoint(75, 25), Qt::CopyAction); } void tst_QQuickDropArea::drop_internal() @@ -886,7 +887,7 @@ void tst_QQuickDropArea::simultaneousDrags() evaluate<void>(dropArea1, "{ enterEvents = 0; exitEvents = 0 }"); evaluate<void>(dropArea2, "{ enterEvents = 0; exitEvents = 0 }"); - QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50)); + QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50), Qt::CopyAction); QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true); QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0); QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0); @@ -894,7 +895,7 @@ void tst_QQuickDropArea::simultaneousDrags() QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0); QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0); - QWindowSystemInterface::handleDrag(&alternateCanvas, &data, QPoint(50, 50)); + QWindowSystemInterface::handleDrag(&alternateCanvas, &data, QPoint(50, 50), Qt::CopyAction); QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true); QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0); QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0); @@ -902,7 +903,7 @@ void tst_QQuickDropArea::simultaneousDrags() QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0); QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0); - QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50)); + QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50), Qt::CopyAction); QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true); QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0); QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0); @@ -920,7 +921,7 @@ void tst_QQuickDropArea::simultaneousDrags() evaluate<void>(dropArea1, "{ enterEvents = 0; exitEvents = 0 }"); evaluate<void>(dropArea2, "{ enterEvents = 0; exitEvents = 0 }"); - QWindowSystemInterface::handleDrag(&alternateCanvas, &data, QPoint(50, 50)); + QWindowSystemInterface::handleDrag(&alternateCanvas, &data, QPoint(50, 50), Qt::CopyAction); QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), false); QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0); QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0); @@ -931,7 +932,7 @@ void tst_QQuickDropArea::simultaneousDrags() // external then internal. evaluate<void>(dropArea1, "{ enterEvents = 0; exitEvents = 0 }"); evaluate<void>(dropArea2, "{ enterEvents = 0; exitEvents = 0 }"); - QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50)); + QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50), Qt::CopyAction); QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true); QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 1); QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0); @@ -965,7 +966,7 @@ void tst_QQuickDropArea::simultaneousDrags() QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0); QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0); - QWindowSystemInterface::handleDrag(&alternateCanvas, &data, QPoint(50, 50)); + QWindowSystemInterface::handleDrag(&alternateCanvas, &data, QPoint(50, 50), Qt::CopyAction); QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), false); QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0); QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 1); @@ -1061,7 +1062,7 @@ void tst_QQuickDropArea::simultaneousDrags() evaluate<void>(dropArea1, "{ enterEvents = 0; exitEvents = 0 }"); evaluate<void>(dropArea2, "{ enterEvents = 0; exitEvents = 0 }"); - QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50)); + QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50), Qt::CopyAction); QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true); QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0); QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0); @@ -1071,7 +1072,7 @@ void tst_QQuickDropArea::simultaneousDrags() evaluate<void>(dropArea1, "{ enterEvents = 0; exitEvents = 0 }"); evaluate<void>(dropArea2, "{ enterEvents = 0; exitEvents = 0 }"); - QWindowSystemInterface::handleDrag(&alternateCanvas, &data, QPoint(50, 50)); + QWindowSystemInterface::handleDrag(&alternateCanvas, &data, QPoint(50, 50), Qt::CopyAction); QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true); QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0); QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0); @@ -1081,7 +1082,7 @@ void tst_QQuickDropArea::simultaneousDrags() evaluate<void>(dropArea1, "{ enterEvents = 0; exitEvents = 0 }"); evaluate<void>(dropArea2, "{ enterEvents = 0; exitEvents = 0 }"); - QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50)); + QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50), Qt::CopyAction); QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true); QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0); QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0); @@ -1101,7 +1102,7 @@ void tst_QQuickDropArea::simultaneousDrags() evaluate<void>(dropArea1, "{ enterEvents = 0; exitEvents = 0 }"); evaluate<void>(dropArea2, "{ enterEvents = 0; exitEvents = 0 }"); - QWindowSystemInterface::handleDrag(&alternateCanvas, &data, QPoint(50, 50)); + QWindowSystemInterface::handleDrag(&alternateCanvas, &data, QPoint(50, 50), Qt::CopyAction); QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), false); QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0); QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0); @@ -1109,7 +1110,7 @@ void tst_QQuickDropArea::simultaneousDrags() QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0); QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 1); - QWindowSystemInterface::handleDrop(&alternateCanvas, &data, QPoint(50, 50)); + QWindowSystemInterface::handleDrop(&alternateCanvas, &data, QPoint(50, 50), Qt::CopyAction); } QTEST_MAIN(tst_QQuickDropArea) diff --git a/tests/auto/quick/qquickgridview/data/displacedTransitions.qml b/tests/auto/quick/qquickgridview/data/displacedTransitions.qml new file mode 100644 index 0000000000..d9353c0639 --- /dev/null +++ b/tests/auto/quick/qquickgridview/data/displacedTransitions.qml @@ -0,0 +1,138 @@ +import QtQuick 2.0 + +Rectangle { + id: root + width: 500 + height: 600 + + property int duration: 10 + property int count: grid.count + + Component { + id: myDelegate + Rectangle { + id: wrapper + + property string nameData: name + + objectName: "wrapper" + width: 80 + height: 60 + Text { + text: index + } + Text { + x: 40 + text: wrapper.x + ", " + wrapper.y + } + Text { + y: 20 + id: textName + objectName: "textName" + text: name + } + Text { + y: 40 + id: textNumber + objectName: "textNumber" + text: number + } + color: GridView.isCurrentItem ? "lightsteelblue" : "white" + + onXChanged: checkPos() + onYChanged: checkPos() + + function checkPos() { + if (Qt.point(x, y) == displaced_transitionVia) + model_displaced_transitionVia.addItem(name, "") + if (Qt.point(x, y) == addDisplaced_transitionVia) + model_addDisplaced_transitionVia.addItem(name, "") + if (Qt.point(x, y) == moveDisplaced_transitionVia) + model_moveDisplaced_transitionVia.addItem(name, "") + if (Qt.point(x, y) == removeDisplaced_transitionVia) + model_removeDisplaced_transitionVia.addItem(name, "") + } + } + } + + GridView { + id: grid + + property int targetTransitionsDone + property int displaceTransitionsDone + + objectName: "grid" + focus: true + anchors.centerIn: parent + width: 240 + height: 320 + cellWidth: 80 + cellHeight: 60 + model: testModel + delegate: myDelegate + + displaced: useDisplaced ? displaced : null + addDisplaced: useAddDisplaced ? addDisplaced : null + moveDisplaced: useMoveDisplaced ? moveDisplaced : null + removeDisplaced: useRemoveDisplaced ? removeDisplaced : null + + Transition { + id: displaced + enabled: displacedEnabled + SequentialAnimation { + ParallelAnimation { + NumberAnimation { properties: "x"; to: displaced_transitionVia.x; duration: root.duration } + NumberAnimation { properties: "y"; to: displaced_transitionVia.y; duration: root.duration } + } + NumberAnimation { properties: "x,y"; duration: root.duration } + PropertyAction { target: grid; property: "displaceTransitionsDone"; value: true } + } + } + + Transition { + id: addDisplaced + enabled: addDisplacedEnabled + SequentialAnimation { + ParallelAnimation { + NumberAnimation { properties: "x"; to: addDisplaced_transitionVia.x; duration: root.duration } + NumberAnimation { properties: "y"; to: addDisplaced_transitionVia.y; duration: root.duration } + } + NumberAnimation { properties: "x,y"; duration: root.duration } + PropertyAction { target: grid; property: "displaceTransitionsDone"; value: true } + } + } + + Transition { + id: moveDisplaced + enabled: moveDisplacedEnabled + SequentialAnimation { + ParallelAnimation { + NumberAnimation { properties: "x"; to: moveDisplaced_transitionVia.x; duration: root.duration } + NumberAnimation { properties: "y"; to: moveDisplaced_transitionVia.y; duration: root.duration } + } + NumberAnimation { properties: "x,y"; duration: root.duration } + PropertyAction { target: grid; property: "displaceTransitionsDone"; value: true } + } + } + + Transition { + id: removeDisplaced + enabled: removeDisplacedEnabled + SequentialAnimation { + ParallelAnimation { + NumberAnimation { properties: "x"; to: removeDisplaced_transitionVia.x; duration: root.duration } + NumberAnimation { properties: "y"; to: removeDisplaced_transitionVia.y; duration: root.duration } + } + NumberAnimation { properties: "x,y"; duration: root.duration } + PropertyAction { target: grid; property: "displaceTransitionsDone"; value: true } + } + } + } + + Rectangle { + anchors.fill: grid + color: "lightsteelblue" + opacity: 0.2 + } +} + diff --git a/tests/auto/quick/qquickgridview/data/multipleTransitions.qml b/tests/auto/quick/qquickgridview/data/multipleTransitions.qml index 45b86e22cf..909ec3a0b7 100644 --- a/tests/auto/quick/qquickgridview/data/multipleTransitions.qml +++ b/tests/auto/quick/qquickgridview/data/multipleTransitions.qml @@ -10,7 +10,7 @@ Rectangle { // interrupting transitions will still produce the correct result) property int timeBetweenActions: duration / 2 - property int duration: 100 + property int duration: 300 property int count: grid.count @@ -46,6 +46,8 @@ Rectangle { property bool runningAddDisplaced: false property bool runningMoveTargets: false property bool runningMoveDisplaced: false + property bool runningRemoveTargets: false + property bool runningRemoveDisplaced: false objectName: "grid" width: 240 @@ -103,6 +105,30 @@ Rectangle { ScriptAction { script: grid.runningMoveDisplaced = false } } } + + remove: Transition { + id: removeTargets + SequentialAnimation { + ScriptAction { script: grid.runningRemoveTargets = true } + ParallelAnimation { + NumberAnimation { properties: "x"; to: removeTargets_transitionTo.x; duration: root.duration } + NumberAnimation { properties: "y"; to: removeTargets_transitionTo.y; duration: root.duration } + } + ScriptAction { script: grid.runningRemoveTargets = false } + } + } + + removeDisplaced: Transition { + id: removeDisplaced + SequentialAnimation { + ScriptAction { script: grid.runningRemoveDisplaced = true } + ParallelAnimation { + NumberAnimation { properties: "x"; from: removeDisplaced_transitionFrom.x; duration: root.duration } + NumberAnimation { properties: "y"; from: removeDisplaced_transitionFrom.y; duration: root.duration } + } + ScriptAction { script: grid.runningRemoveDisplaced = false } + } + } } Rectangle { diff --git a/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp b/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp index d156ed0957..c0f2b02a7e 100644 --- a/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp +++ b/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp @@ -138,6 +138,8 @@ private slots: void moveTransitions_data(); void removeTransitions(); void removeTransitions_data(); + void displacedTransitions(); + void displacedTransitions_data(); void multipleTransitions(); void multipleTransitions_data(); @@ -1272,6 +1274,8 @@ void tst_QQuickGridView::moved_data() void tst_QQuickGridView::multipleChanges() { + QSKIP("QTBUG-24523"); + QFETCH(int, startCount); QFETCH(QList<ListChange>, changes); QFETCH(int, newCount); @@ -2037,10 +2041,10 @@ void tst_QQuickGridView::componentChanges() QTRY_VERIFY(gridView); QQmlComponent component(canvas->engine()); - component.setData("import QtQuick 2.0; Rectangle { color: \"blue\"; }", QUrl::fromLocalFile("")); + component.setData("import QtQuick 1.0; Rectangle { color: \"blue\"; }", QUrl::fromLocalFile("")); QQmlComponent delegateComponent(canvas->engine()); - delegateComponent.setData("import QtQuick 2.0; Text { text: '<b>Name:</b> ' + name }", QUrl::fromLocalFile("")); + delegateComponent.setData("import QtQuick 1.0; Text { text: '<b>Name:</b> ' + name }", QUrl::fromLocalFile("")); QSignalSpy highlightSpy(gridView, SIGNAL(highlightChanged())); QSignalSpy delegateSpy(gridView, SIGNAL(delegateChanged())); @@ -4555,6 +4559,215 @@ void tst_QQuickGridView::removeTransitions_data() << 18 << 3 << ListRange(); } +void tst_QQuickGridView::displacedTransitions() +{ + QFETCH(bool, useDisplaced); + QFETCH(bool, displacedEnabled); + QFETCH(bool, useAddDisplaced); + QFETCH(bool, addDisplacedEnabled); + QFETCH(bool, useMoveDisplaced); + QFETCH(bool, moveDisplacedEnabled); + QFETCH(bool, useRemoveDisplaced); + QFETCH(bool, removeDisplacedEnabled); + QFETCH(ListChange, change); + QFETCH(ListRange, expectedDisplacedIndexes); + + QaimModel model; + for (int i = 0; i < 30; i++) + model.addItem("Original item" + QString::number(i), ""); + QaimModel model_displaced_transitionVia; + QaimModel model_addDisplaced_transitionVia; + QaimModel model_moveDisplaced_transitionVia; + QaimModel model_removeDisplaced_transitionVia; + + QPointF displaced_transitionVia(-50, -100); + QPointF addDisplaced_transitionVia(-150, 100); + QPointF moveDisplaced_transitionVia(50, -100); + QPointF removeDisplaced_transitionVia(150, 100); + + QQuickView *canvas = createView(); + QQmlContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + ctxt->setContextProperty("model_displaced_transitionVia", &model_displaced_transitionVia); + ctxt->setContextProperty("model_addDisplaced_transitionVia", &model_addDisplaced_transitionVia); + ctxt->setContextProperty("model_moveDisplaced_transitionVia", &model_moveDisplaced_transitionVia); + ctxt->setContextProperty("model_removeDisplaced_transitionVia", &model_removeDisplaced_transitionVia); + ctxt->setContextProperty("displaced_transitionVia", displaced_transitionVia); + ctxt->setContextProperty("addDisplaced_transitionVia", addDisplaced_transitionVia); + ctxt->setContextProperty("moveDisplaced_transitionVia", moveDisplaced_transitionVia); + ctxt->setContextProperty("removeDisplaced_transitionVia", removeDisplaced_transitionVia); + ctxt->setContextProperty("useDisplaced", useDisplaced); + ctxt->setContextProperty("displacedEnabled", displacedEnabled); + ctxt->setContextProperty("useAddDisplaced", useAddDisplaced); + ctxt->setContextProperty("addDisplacedEnabled", addDisplacedEnabled); + ctxt->setContextProperty("useMoveDisplaced", useMoveDisplaced); + ctxt->setContextProperty("moveDisplacedEnabled", moveDisplacedEnabled); + ctxt->setContextProperty("useRemoveDisplaced", useRemoveDisplaced); + ctxt->setContextProperty("removeDisplacedEnabled", removeDisplacedEnabled); + canvas->setSource(testFileUrl("displacedTransitions.qml")); + canvas->show(); + qApp->processEvents(); + + QQuickGridView *gridview = findItem<QQuickGridView>(canvas->rootObject(), "grid"); + QTRY_VERIFY(gridview != 0); + QQuickItem *contentItem = gridview->contentItem(); + QVERIFY(contentItem != 0); + QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); + + QList<QPair<QString,QString> > expectedDisplacedValues = expectedDisplacedIndexes.getModelDataValues(model); + gridview->setProperty("displaceTransitionsDone", false); + + switch (change.type) { + case ListChange::Inserted: + { + QList<QPair<QString, QString> > targetItemData; + for (int i=change.index; i<change.index + change.count; ++i) + targetItemData << qMakePair(QString("new item %1").arg(i), QString::number(i)); + model.insertItems(change.index, targetItemData); + QTRY_COMPARE(model.count(), gridview->count()); + break; + } + case ListChange::Removed: + model.removeItems(change.index, change.count); + QTRY_COMPARE(model.count(), gridview->count()); + break; + case ListChange::Moved: + model.moveItems(change.index, change.to, change.count); + QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); + break; + case ListChange::SetCurrent: + case ListChange::SetContentY: + break; + } + if ((useDisplaced && displacedEnabled) + || (useAddDisplaced && addDisplacedEnabled) + || (useMoveDisplaced && moveDisplacedEnabled) + || (useRemoveDisplaced && removeDisplacedEnabled)) { + QTRY_VERIFY(gridview->property("displaceTransitionsDone").toBool()); + } + + if (change.type == ListChange::Inserted && useAddDisplaced && addDisplacedEnabled) + model_addDisplaced_transitionVia.matchAgainst(expectedDisplacedValues, "wasn't animated with add displaced", "shouldn't have been animated with add displaced"); + else + QCOMPARE(model_addDisplaced_transitionVia.count(), 0); + if (change.type == ListChange::Moved && useMoveDisplaced && moveDisplacedEnabled) + model_moveDisplaced_transitionVia.matchAgainst(expectedDisplacedValues, "wasn't animated with move displaced", "shouldn't have been animated with move displaced"); + else + QCOMPARE(model_moveDisplaced_transitionVia.count(), 0); + if (change.type == ListChange::Removed && useRemoveDisplaced && removeDisplacedEnabled) + model_removeDisplaced_transitionVia.matchAgainst(expectedDisplacedValues, "wasn't animated with remove displaced", "shouldn't have been animated with remove displaced"); + else + QCOMPARE(model_removeDisplaced_transitionVia.count(), 0); + + if (useDisplaced && displacedEnabled + && ( (change.type == ListChange::Inserted && (!useAddDisplaced || !addDisplacedEnabled)) + || (change.type == ListChange::Moved && (!useMoveDisplaced || !moveDisplacedEnabled)) + || (change.type == ListChange::Removed && (!useRemoveDisplaced || !removeDisplacedEnabled))) ) { + model_displaced_transitionVia.matchAgainst(expectedDisplacedValues, "wasn't animated with generic displaced", "shouldn't have been animated with generic displaced"); + } else { + QCOMPARE(model_displaced_transitionVia.count(), 0); + } + + // verify all items moved to the correct final positions + QList<QQuickItem*> items = findItems<QQuickItem>(contentItem, "wrapper"); + for (int i=0; i < model.count() && i < items.count(); ++i) { + QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i); + QVERIFY2(item, QTest::toString(QString("Item %1 not found").arg(i))); + QCOMPARE(item->x(), (i%3)*80.0); + QCOMPARE(item->y(), (i/3)*60.0); + QQuickText *name = findItem<QQuickText>(contentItem, "textName", i); + QVERIFY(name != 0); + QTRY_COMPARE(name->text(), model.name(i)); + } + + delete canvas; +} + +void tst_QQuickGridView::displacedTransitions_data() +{ + QTest::addColumn<bool>("useDisplaced"); + QTest::addColumn<bool>("displacedEnabled"); + QTest::addColumn<bool>("useAddDisplaced"); + QTest::addColumn<bool>("addDisplacedEnabled"); + QTest::addColumn<bool>("useMoveDisplaced"); + QTest::addColumn<bool>("moveDisplacedEnabled"); + QTest::addColumn<bool>("useRemoveDisplaced"); + QTest::addColumn<bool>("removeDisplacedEnabled"); + QTest::addColumn<ListChange>("change"); + QTest::addColumn<ListRange>("expectedDisplacedIndexes"); + + QTest::newRow("no displaced transitions at all") + << false << false + << false << false + << false << false + << false << false + << ListChange::insert(0, 1) << ListRange(0, 17); + + QTest::newRow("just displaced") + << true << true + << false << false + << false << false + << false << false + << ListChange::insert(0, 1) << ListRange(0, 17); + + QTest::newRow("just displaced (not enabled)") + << true << false + << false << false + << false << false + << false << false + << ListChange::insert(0, 1) << ListRange(0, 17); + + QTest::newRow("displaced + addDisplaced") + << true << true + << true << true + << false << false + << false << false + << ListChange::insert(0, 1) << ListRange(0, 17); + + QTest::newRow("displaced + addDisplaced (not enabled)") + << true << true + << true << false + << false << false + << false << false + << ListChange::insert(0, 1) << ListRange(0, 17); + + QTest::newRow("displaced + moveDisplaced") + << true << true + << false << false + << true << true + << false << false + << ListChange::move(0, 10, 1) << ListRange(1, 10); + + QTest::newRow("displaced + moveDisplaced (not enabled)") + << true << true + << false << false + << true << false + << false << false + << ListChange::move(0, 10, 1) << ListRange(1, 10); + + QTest::newRow("displaced + removeDisplaced") + << true << true + << false << false + << false << false + << true << true + << ListChange::remove(0, 1) << ListRange(1, 18); + + QTest::newRow("displaced + removeDisplaced (not enabled)") + << true << true + << false << false + << false << false + << true << false + << ListChange::remove(0, 1) << ListRange(1, 18); + + + QTest::newRow("displaced + add, should use generic displaced for a remove") + << true << true + << true << true + << false << false + << true << false + << ListChange::remove(0, 1) << ListRange(1, 18); +} + void tst_QQuickGridView::multipleTransitions() { // Tests that if you interrupt a transition in progress with another action that @@ -4563,12 +4776,15 @@ void tst_QQuickGridView::multipleTransitions() QFETCH(int, initialCount); QFETCH(qreal, contentY); QFETCH(QList<ListChange>, changes); + QFETCH(bool, rippleAddDisplaced); // add transitions on the left, moves on the right QPointF addTargets_transitionFrom(-50, -50); QPointF addDisplaced_transitionFrom(-50, 50); QPointF moveTargets_transitionFrom(50, -50); QPointF moveDisplaced_transitionFrom(50, 50); + QPointF removeTargets_transitionTo(-100, 300); + QPointF removeDisplaced_transitionFrom(100, 300); QmlListModel model; for (int i = 0; i < initialCount; i++) @@ -4581,8 +4797,12 @@ void tst_QQuickGridView::multipleTransitions() ctxt->setContextProperty("addDisplaced_transitionFrom", addDisplaced_transitionFrom); ctxt->setContextProperty("moveTargets_transitionFrom", moveTargets_transitionFrom); ctxt->setContextProperty("moveDisplaced_transitionFrom", moveDisplaced_transitionFrom); + ctxt->setContextProperty("removeTargets_transitionTo", removeTargets_transitionTo); + ctxt->setContextProperty("removeDisplaced_transitionFrom", removeDisplaced_transitionFrom); + ctxt->setContextProperty("rippleAddDisplaced", rippleAddDisplaced); canvas->setSource(testFileUrl("multipleTransitions.qml")); canvas->show(); + QTest::qWaitForWindowShown(canvas); QQuickGridView *gridview = findItem<QQuickGridView>(canvas->rootObject(), "grid"); QTRY_VERIFY(gridview != 0); @@ -4590,6 +4810,11 @@ void tst_QQuickGridView::multipleTransitions() QVERIFY(contentItem != 0); QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); + if (contentY != 0) { + gridview->setContentY(contentY); + QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false); + } + int timeBetweenActions = canvas->rootObject()->property("timeBetweenActions").toInt(); QList<QPair<QString, QString> > targetItems; @@ -4681,18 +4906,21 @@ void tst_QQuickGridView::multipleTransitions_data() QTest::addColumn<int>("initialCount"); QTest::addColumn<qreal>("contentY"); QTest::addColumn<QList<ListChange> >("changes"); + QTest::addColumn<bool>("rippleAddDisplaced"); // the added item and displaced items should move to final dest correctly QTest::newRow("add item, then move it immediately") << 10 << 0.0 << (QList<ListChange>() - << ListChange::insert(0, 1) - << ListChange::move(0, 3, 1) - ); + << ListChange::insert(0, 1) + << ListChange::move(0, 3, 1) + ) + << false; // items affected by the add should change from move to add transition QTest::newRow("move, then insert item before the moved item") << 20 << 0.0 << (QList<ListChange>() << ListChange::move(1, 10, 3) << ListChange::insert(0, 1) - ); + ) + << false; // items should be placed correctly if you trigger a transition then refill for that index QTest::newRow("add at 0, flick down, flick back to top and add at 0 again") << 20 << 0.0 << (QList<ListChange>() @@ -4700,7 +4928,14 @@ void tst_QQuickGridView::multipleTransitions_data() << ListChange::setContentY(160.0) << ListChange::setContentY(0.0) << ListChange::insert(0, 1) - ); + ) + << false; + + QTest::newRow("insert then remove same index, with ripple effect on add displaced") << 20 << 0.0 << (QList<ListChange>() + << ListChange::insert(1, 1) + << ListChange::remove(1, 1) + ) + << true; } void tst_QQuickGridView::cacheBuffer() diff --git a/tests/auto/quick/qquicklistview/data/displacedTransitions.qml b/tests/auto/quick/qquicklistview/data/displacedTransitions.qml new file mode 100644 index 0000000000..cc7892e930 --- /dev/null +++ b/tests/auto/quick/qquicklistview/data/displacedTransitions.qml @@ -0,0 +1,128 @@ +import QtQuick 2.0 + +Rectangle { + id: root + width: 500 + height: 600 + + property int duration: 10 + property int count: list.count + + Component { + id: myDelegate + Rectangle { + id: wrapper + + property string nameData: name + + objectName: "wrapper" + height: 20 + width: 240 + Text { text: index } + Text { + x: 30 + id: textName + objectName: "textName" + text: name + } + Text { + x: 200 + text: wrapper.y + } + color: ListView.isCurrentItem ? "lightsteelblue" : "white" + + onXChanged: checkPos() + onYChanged: checkPos() + + function checkPos() { + if (Qt.point(x, y) == displaced_transitionVia) + model_displaced_transitionVia.addItem(name, "") + if (Qt.point(x, y) == addDisplaced_transitionVia) + model_addDisplaced_transitionVia.addItem(name, "") + if (Qt.point(x, y) == moveDisplaced_transitionVia) + model_moveDisplaced_transitionVia.addItem(name, "") + if (Qt.point(x, y) == removeDisplaced_transitionVia) + model_removeDisplaced_transitionVia.addItem(name, "") + } + } + } + + ListView { + id: list + + property int targetTransitionsDone + property int displaceTransitionsDone + + objectName: "list" + focus: true + anchors.centerIn: parent + width: 240 + height: 320 + model: testModel + delegate: myDelegate + + displaced: useDisplaced ? displaced : null + addDisplaced: useAddDisplaced ? addDisplaced : null + moveDisplaced: useMoveDisplaced ? moveDisplaced : null + removeDisplaced: useRemoveDisplaced ? removeDisplaced : null + + Transition { + id: displaced + enabled: displacedEnabled + SequentialAnimation { + ParallelAnimation { + NumberAnimation { properties: "x"; to: displaced_transitionVia.x; duration: root.duration } + NumberAnimation { properties: "y"; to: displaced_transitionVia.y; duration: root.duration } + } + NumberAnimation { properties: "x,y"; duration: root.duration } + PropertyAction { target: list; property: "displaceTransitionsDone"; value: true } + } + } + + Transition { + id: addDisplaced + enabled: addDisplacedEnabled + SequentialAnimation { + ParallelAnimation { + NumberAnimation { properties: "x"; to: addDisplaced_transitionVia.x; duration: root.duration } + NumberAnimation { properties: "y"; to: addDisplaced_transitionVia.y; duration: root.duration } + } + NumberAnimation { properties: "x,y"; duration: root.duration } + PropertyAction { target: list; property: "displaceTransitionsDone"; value: true } + } + } + + Transition { + id: moveDisplaced + enabled: moveDisplacedEnabled + SequentialAnimation { + ParallelAnimation { + NumberAnimation { properties: "x"; to: moveDisplaced_transitionVia.x; duration: root.duration } + NumberAnimation { properties: "y"; to: moveDisplaced_transitionVia.y; duration: root.duration } + } + NumberAnimation { properties: "x,y"; duration: root.duration } + PropertyAction { target: list; property: "displaceTransitionsDone"; value: true } + } + } + + Transition { + id: removeDisplaced + enabled: removeDisplacedEnabled + SequentialAnimation { + ParallelAnimation { + NumberAnimation { properties: "x"; to: removeDisplaced_transitionVia.x; duration: root.duration } + NumberAnimation { properties: "y"; to: removeDisplaced_transitionVia.y; duration: root.duration } + } + NumberAnimation { properties: "x,y"; duration: root.duration } + PropertyAction { target: list; property: "displaceTransitionsDone"; value: true } + } + } + } + + Rectangle { + anchors.fill: list + color: "lightsteelblue" + opacity: 0.2 + } +} + diff --git a/tests/auto/quick/qquicklistview/data/multipleTransitions.qml b/tests/auto/quick/qquicklistview/data/multipleTransitions.qml index 50ffbc53c3..8264b42b64 100644 --- a/tests/auto/quick/qquicklistview/data/multipleTransitions.qml +++ b/tests/auto/quick/qquicklistview/data/multipleTransitions.qml @@ -10,7 +10,7 @@ Rectangle { // interrupting transitions will still produce the correct result) property int timeBetweenActions: duration / 2 - property int duration: 100 + property int duration: 300 property int count: list.count @@ -45,6 +45,8 @@ Rectangle { property bool runningAddDisplaced: false property bool runningMoveTargets: false property bool runningMoveDisplaced: false + property bool runningRemoveTargets: false + property bool runningRemoveDisplaced: false objectName: "list" focus: true @@ -70,6 +72,7 @@ Rectangle { id: addDisplaced SequentialAnimation { ScriptAction { script: list.runningAddDisplaced = true } + PauseAnimation { duration: rippleAddDisplaced ? addDisplaced.ViewTransition.index * root.duration/10 : 0 } ParallelAnimation { NumberAnimation { properties: "x"; from: addDisplaced_transitionFrom.x; duration: root.duration } NumberAnimation { properties: "y"; from: addDisplaced_transitionFrom.y; duration: root.duration } @@ -101,6 +104,30 @@ Rectangle { ScriptAction { script: list.runningMoveDisplaced = false } } } + + remove: Transition { + id: removeTargets + SequentialAnimation { + ScriptAction { script: list.runningRemoveTargets = true } + ParallelAnimation { + NumberAnimation { properties: "x"; to: removeTargets_transitionTo.x; duration: root.duration } + NumberAnimation { properties: "y"; to: removeTargets_transitionTo.y; duration: root.duration } + } + ScriptAction { script: list.runningRemoveTargets = false } + } + } + + removeDisplaced: Transition { + id: removeDisplaced + SequentialAnimation { + ScriptAction { script: list.runningRemoveDisplaced = true } + ParallelAnimation { + NumberAnimation { properties: "x"; from: removeDisplaced_transitionFrom.x; duration: root.duration } + NumberAnimation { properties: "y"; from: removeDisplaced_transitionFrom.y; duration: root.duration } + } + ScriptAction { script: list.runningRemoveDisplaced = false } + } + } } Rectangle { diff --git a/tests/auto/quick/qquicklistview/data/sectionpropertychange.qml b/tests/auto/quick/qquicklistview/data/sectionpropertychange.qml new file mode 100644 index 0000000000..f4679b5af0 --- /dev/null +++ b/tests/auto/quick/qquicklistview/data/sectionpropertychange.qml @@ -0,0 +1,92 @@ +import QtQuick 2.0 + +Rectangle { + width: 320; height: 480 + + Rectangle { + id: groupButtons + width: 300; height: 30 + color: "yellow" + border.width: 1 + Text { + anchors.centerIn: parent + text: "swap" + } + anchors { + top: parent.top + horizontalCenter: parent.horizontalCenter + } + MouseArea { + anchors.fill: parent + onClicked: switchGroups() + } + } + + function switchGroups() { + if ("title" === myListView.groupBy) + myListView.groupBy = "genre" + else + myListView.groupBy = "title" + } + + Component.onCompleted: { + myListView.model = generateModel(myListView) + } + + ListView { + id: myListView + objectName: "list" + + clip: true + property string groupBy: "title" + + anchors { + top: groupButtons.bottom + left: parent.left + right: parent.right + bottom: parent.bottom + } + + delegate: Item { + objectName: "wrapper" + height: 50 + width: 320 + Text { id: t; text: model.title } + Text { text: model.author; font.pixelSize: 10; anchors.top: t.bottom } + Text { text: parent.y; anchors.right: parent.right } + } + + onGroupByChanged: { + model.move(0,1,1) + section.property = groupBy + } + + section { + criteria: ViewSection.FullString + delegate: Rectangle { width: 320; height: 25; color: "lightblue" + objectName: "sect" + Text {text: section } + Text { text: parent.y; anchors.right: parent.right } + } + property: "title" + } + } + + function generateModel(theParent) + { + var books = [ + { "author": "Billy Bob", "genre": "Anarchism", "title": "Frogs and Love" }, + { "author": "Lefty Smith", "genre": "Horror", "title": "Chainsaws for Noobs" } + ]; + + var model = Qt.createQmlObject("import QtQuick 2.0; ListModel {}", theParent); + + for (var i = 0; i < books.length; ++i) { + var book = books[i]; + model.append(book); + } + return model; + } + +} + diff --git a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp index bcac5917d6..9195aab632 100644 --- a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp +++ b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp @@ -51,7 +51,6 @@ #include <QtQuick/private/qquicktext_p.h> #include <QtQuick/private/qquickvisualitemmodel_p.h> #include <QtQml/private/qquicklistmodel_p.h> -#include <QtQuick/private/qquickchangeset_p.h> #include "../../shared/util.h" #include "../shared/viewtestutil.h" #include "../shared/visualtestutil.h" @@ -126,6 +125,7 @@ private slots: void qAbstractItemModel_sections(); void sectionsPositioning(); void sectionsDelegate(); + void sectionPropertyChange(); void cacheBuffer(); void positionViewAtIndex(); void resetModel(); @@ -179,6 +179,8 @@ private slots: void moveTransitions_data(); void removeTransitions(); void removeTransitions_data(); + void displacedTransitions(); + void displacedTransitions_data(); void multipleTransitions(); void multipleTransitions_data(); @@ -491,6 +493,7 @@ void tst_QQuickListView::inserted_more() canvas->setSource(testFileUrl("listviewtest.qml")); canvas->show(); qApp->processEvents(); + QTest::qWaitForWindowShown(canvas); QQuickListView *listview = findItem<QQuickListView>(canvas->rootObject(), "list"); QTRY_VERIFY(listview != 0); @@ -644,6 +647,7 @@ void tst_QQuickListView::insertBeforeVisible() canvas->setSource(testFileUrl("listviewtest.qml")); canvas->show(); qApp->processEvents(); + QTest::qWaitForWindowShown(canvas); QQuickListView *listview = findItem<QQuickListView>(canvas->rootObject(), "list"); QTRY_VERIFY(listview != 0); @@ -734,6 +738,7 @@ void tst_QQuickListView::removed(const QUrl &source, bool /* animated */) canvas->setSource(source); canvas->show(); qApp->processEvents(); + QTest::qWaitForWindowShown(canvas); QQuickListView *listview = findItem<QQuickListView>(canvas->rootObject(), "list"); QTRY_VERIFY(listview != 0); @@ -923,6 +928,7 @@ void tst_QQuickListView::removed_more(const QUrl &source) canvas->setSource(source); canvas->show(); qApp->processEvents(); + QTest::qWaitForWindowShown(canvas); QQuickListView *listview = findItem<QQuickListView>(canvas->rootObject(), "list"); QTRY_VERIFY(listview != 0); @@ -1144,6 +1150,7 @@ void tst_QQuickListView::moved(const QUrl &source) canvas->setSource(source); canvas->show(); qApp->processEvents(); + QTest::qWaitForWindowShown(canvas); QQuickListView *listview = findItem<QQuickListView>(canvas->rootObject(), "list"); QTRY_VERIFY(listview != 0); @@ -1370,6 +1377,7 @@ void tst_QQuickListView::multipleChanges() canvas->setSource(testFileUrl("listviewtest.qml")); canvas->show(); qApp->processEvents(); + QTest::qWaitForWindowShown(canvas); QQuickListView *listview = findItem<QQuickListView>(canvas->rootObject(), "list"); QTRY_VERIFY(listview != 0); @@ -2090,9 +2098,9 @@ void tst_QQuickListView::sectionsPositioning() QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); model.removeItem(5); QTRY_COMPARE(listview->count(), model.count()); - for (int i = 0; i < 3; ++i) { - QQuickItem *item = findItem<QQuickItem>(contentItem, - "sect_" + (i == 0 ? QString("aaa") : QString::number(i))); + for (int i = 1; i < 3; ++i) { + QQuickItem *item = findVisibleChild(contentItem, + "sect_" + QString::number(i)); QVERIFY(item); QTRY_COMPARE(item->y(), qreal(i*20*6)); } @@ -2130,6 +2138,52 @@ void tst_QQuickListView::sectionsPositioning() delete canvas; } +void tst_QQuickListView::sectionPropertyChange() +{ + QQuickView *canvas = createView(); + + canvas->setSource(testFileUrl("sectionpropertychange.qml")); + canvas->show(); + qApp->processEvents(); + + QQuickListView *listview = findItem<QQuickListView>(canvas->rootObject(), "list"); + QTRY_VERIFY(listview != 0); + + QQuickItem *contentItem = listview->contentItem(); + QTRY_VERIFY(contentItem != 0); + + QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + + // Confirm items positioned correctly + for (int i = 0; i < 2; ++i) { + QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i); + QTRY_VERIFY(item); + QTRY_COMPARE(item->y(), qreal(25. + i*75.)); + } + + QMetaObject::invokeMethod(canvas->rootObject(), "switchGroups"); + QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + + // Confirm items positioned correctly + for (int i = 0; i < 2; ++i) { + QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i); + QTRY_VERIFY(item); + QTRY_COMPARE(item->y(), qreal(25. + i*75.)); + } + + QMetaObject::invokeMethod(canvas->rootObject(), "switchGroups"); + QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + + // Confirm items positioned correctly + for (int i = 0; i < 2; ++i) { + QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i); + QTRY_VERIFY(item); + QTRY_COMPARE(item->y(), qreal(25. + i*75.)); + } + + delete canvas; +} + void tst_QQuickListView::currentIndex_delayedItemCreation() { QFETCH(bool, setCurrentToZero); @@ -4814,6 +4868,7 @@ void tst_QQuickListView::populateTransitions() canvas->rootContext()->setContextProperty("model_transitionVia", &model_transitionVia); canvas->setSource(testFileUrl("populateTransitions.qml")); canvas->show(); + QTest::qWaitForWindowShown(canvas); QQuickListView *listview = findItem<QQuickListView>(canvas->rootObject(), "list"); QVERIFY(listview); @@ -4951,6 +5006,7 @@ void tst_QQuickListView::addTransitions() ctxt->setContextProperty("testObject", testObject); canvas->setSource(testFileUrl("addTransitions.qml")); canvas->show(); + QTest::qWaitForWindowShown(canvas); QQuickListView *listview = findItem<QQuickListView>(canvas->rootObject(), "list"); QTRY_VERIFY(listview != 0); @@ -5145,6 +5201,7 @@ void tst_QQuickListView::moveTransitions() ctxt->setContextProperty("testObject", testObject); canvas->setSource(testFileUrl("moveTransitions.qml")); canvas->show(); + QTest::qWaitForWindowShown(canvas); QQuickListView *listview = findItem<QQuickListView>(canvas->rootObject(), "list"); QTRY_VERIFY(listview != 0); @@ -5347,6 +5404,7 @@ void tst_QQuickListView::removeTransitions() ctxt->setContextProperty("testObject", testObject); canvas->setSource(testFileUrl("removeTransitions.qml")); canvas->show(); + QTest::qWaitForWindowShown(canvas); QQuickListView *listview = findItem<QQuickListView>(canvas->rootObject(), "list"); QTRY_VERIFY(listview != 0); @@ -5508,20 +5566,235 @@ void tst_QQuickListView::removeTransitions_data() << 17 << 3 << ListRange(); } +void tst_QQuickListView::displacedTransitions() +{ + QFETCH(bool, useDisplaced); + QFETCH(bool, displacedEnabled); + QFETCH(bool, useAddDisplaced); + QFETCH(bool, addDisplacedEnabled); + QFETCH(bool, useMoveDisplaced); + QFETCH(bool, moveDisplacedEnabled); + QFETCH(bool, useRemoveDisplaced); + QFETCH(bool, removeDisplacedEnabled); + QFETCH(ListChange, change); + QFETCH(ListRange, expectedDisplacedIndexes); + + QaimModel model; + for (int i = 0; i < 30; i++) + model.addItem("Original item" + QString::number(i), ""); + QaimModel model_displaced_transitionVia; + QaimModel model_addDisplaced_transitionVia; + QaimModel model_moveDisplaced_transitionVia; + QaimModel model_removeDisplaced_transitionVia; + + QPointF displaced_transitionVia(-50, -100); + QPointF addDisplaced_transitionVia(-150, 100); + QPointF moveDisplaced_transitionVia(50, -100); + QPointF removeDisplaced_transitionVia(150, 100); + + QQuickView *canvas = createView(); + QQmlContext *ctxt = canvas->rootContext(); + TestObject *testObject = new TestObject(canvas); + ctxt->setContextProperty("testModel", &model); + ctxt->setContextProperty("testObject", testObject); + ctxt->setContextProperty("model_displaced_transitionVia", &model_displaced_transitionVia); + ctxt->setContextProperty("model_addDisplaced_transitionVia", &model_addDisplaced_transitionVia); + ctxt->setContextProperty("model_moveDisplaced_transitionVia", &model_moveDisplaced_transitionVia); + ctxt->setContextProperty("model_removeDisplaced_transitionVia", &model_removeDisplaced_transitionVia); + ctxt->setContextProperty("displaced_transitionVia", displaced_transitionVia); + ctxt->setContextProperty("addDisplaced_transitionVia", addDisplaced_transitionVia); + ctxt->setContextProperty("moveDisplaced_transitionVia", moveDisplaced_transitionVia); + ctxt->setContextProperty("removeDisplaced_transitionVia", removeDisplaced_transitionVia); + ctxt->setContextProperty("useDisplaced", useDisplaced); + ctxt->setContextProperty("displacedEnabled", displacedEnabled); + ctxt->setContextProperty("useAddDisplaced", useAddDisplaced); + ctxt->setContextProperty("addDisplacedEnabled", addDisplacedEnabled); + ctxt->setContextProperty("useMoveDisplaced", useMoveDisplaced); + ctxt->setContextProperty("moveDisplacedEnabled", moveDisplacedEnabled); + ctxt->setContextProperty("useRemoveDisplaced", useRemoveDisplaced); + ctxt->setContextProperty("removeDisplacedEnabled", removeDisplacedEnabled); + canvas->setSource(testFileUrl("displacedTransitions.qml")); + canvas->show(); + qApp->processEvents(); + + QQuickListView *listview = findItem<QQuickListView>(canvas->rootObject(), "list"); + QTRY_VERIFY(listview != 0); + QQuickItem *contentItem = listview->contentItem(); + QVERIFY(contentItem != 0); + QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + + QList<QPair<QString,QString> > expectedDisplacedValues = expectedDisplacedIndexes.getModelDataValues(model); + listview->setProperty("displaceTransitionsDone", false); + + switch (change.type) { + case ListChange::Inserted: + { + QList<QPair<QString, QString> > targetItemData; + for (int i=change.index; i<change.index + change.count; ++i) + targetItemData << qMakePair(QString("new item %1").arg(i), QString::number(i)); + model.insertItems(change.index, targetItemData); + QTRY_COMPARE(model.count(), listview->count()); + break; + } + case ListChange::Removed: + model.removeItems(change.index, change.count); + QTRY_COMPARE(model.count(), listview->count()); + break; + case ListChange::Moved: + model.moveItems(change.index, change.to, change.count); + QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + break; + case ListChange::SetCurrent: + case ListChange::SetContentY: + break; + } + if ((useDisplaced && displacedEnabled) + || (useAddDisplaced && addDisplacedEnabled) + || (useMoveDisplaced && moveDisplacedEnabled) + || (useRemoveDisplaced && removeDisplacedEnabled)) { + QTRY_VERIFY(listview->property("displaceTransitionsDone").toBool()); + } + + if (change.type == ListChange::Inserted && useAddDisplaced && addDisplacedEnabled) + model_addDisplaced_transitionVia.matchAgainst(expectedDisplacedValues, "wasn't animated with add displaced", "shouldn't have been animated with add displaced"); + else + QCOMPARE(model_addDisplaced_transitionVia.count(), 0); + if (change.type == ListChange::Moved && useMoveDisplaced && moveDisplacedEnabled) + model_moveDisplaced_transitionVia.matchAgainst(expectedDisplacedValues, "wasn't animated with move displaced", "shouldn't have been animated with move displaced"); + else + QCOMPARE(model_moveDisplaced_transitionVia.count(), 0); + if (change.type == ListChange::Removed && useRemoveDisplaced && removeDisplacedEnabled) + model_removeDisplaced_transitionVia.matchAgainst(expectedDisplacedValues, "wasn't animated with remove displaced", "shouldn't have been animated with remove displaced"); + else + QCOMPARE(model_removeDisplaced_transitionVia.count(), 0); + + if (useDisplaced && displacedEnabled + && ( (change.type == ListChange::Inserted && (!useAddDisplaced || !addDisplacedEnabled)) + || (change.type == ListChange::Moved && (!useMoveDisplaced || !moveDisplacedEnabled)) + || (change.type == ListChange::Removed && (!useRemoveDisplaced || !removeDisplacedEnabled))) ) { + model_displaced_transitionVia.matchAgainst(expectedDisplacedValues, "wasn't animated with generic displaced", "shouldn't have been animated with generic displaced"); + } else { + QCOMPARE(model_displaced_transitionVia.count(), 0); + } + + // verify all items moved to the correct final positions + QList<QQuickItem*> items = findItems<QQuickItem>(contentItem, "wrapper"); + for (int i=0; i < model.count() && i < items.count(); ++i) { + QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i); + QVERIFY2(item, QTest::toString(QString("Item %1 not found").arg(i))); + QCOMPARE(item->x(), 0.0); + QCOMPARE(item->y(), i * 20.0); + QQuickText *name = findItem<QQuickText>(contentItem, "textName", i); + QVERIFY(name != 0); + QTRY_COMPARE(name->text(), model.name(i)); + } + + delete canvas; +} + +void tst_QQuickListView::displacedTransitions_data() +{ + QTest::addColumn<bool>("useDisplaced"); + QTest::addColumn<bool>("displacedEnabled"); + QTest::addColumn<bool>("useAddDisplaced"); + QTest::addColumn<bool>("addDisplacedEnabled"); + QTest::addColumn<bool>("useMoveDisplaced"); + QTest::addColumn<bool>("moveDisplacedEnabled"); + QTest::addColumn<bool>("useRemoveDisplaced"); + QTest::addColumn<bool>("removeDisplacedEnabled"); + QTest::addColumn<ListChange>("change"); + QTest::addColumn<ListRange>("expectedDisplacedIndexes"); + + QTest::newRow("no displaced transitions at all") + << false << false + << false << false + << false << false + << false << false + << ListChange::insert(0, 1) << ListRange(0, 15); + + QTest::newRow("just displaced") + << true << true + << false << false + << false << false + << false << false + << ListChange::insert(0, 1) << ListRange(0, 15); + + QTest::newRow("just displaced (not enabled)") + << true << false + << false << false + << false << false + << false << false + << ListChange::insert(0, 1) << ListRange(0, 15); + + QTest::newRow("displaced + addDisplaced") + << true << true + << true << true + << false << false + << false << false + << ListChange::insert(0, 1) << ListRange(0, 15); + + QTest::newRow("displaced + addDisplaced (not enabled)") + << true << true + << true << false + << false << false + << false << false + << ListChange::insert(0, 1) << ListRange(0, 15); + + QTest::newRow("displaced + moveDisplaced") + << true << true + << false << false + << true << true + << false << false + << ListChange::move(0, 10, 1) << ListRange(1, 10); + + QTest::newRow("displaced + moveDisplaced (not enabled)") + << true << true + << false << false + << true << false + << false << false + << ListChange::move(0, 10, 1) << ListRange(1, 10); + + QTest::newRow("displaced + removeDisplaced") + << true << true + << false << false + << false << false + << true << true + << ListChange::remove(0, 1) << ListRange(1, 16); + + QTest::newRow("displaced + removeDisplaced (not enabled)") + << true << true + << false << false + << false << false + << true << false + << ListChange::remove(0, 1) << ListRange(1, 16); + + + QTest::newRow("displaced + add, should use generic displaced for a remove") + << true << true + << true << true + << false << false + << true << false + << ListChange::remove(0, 1) << ListRange(1, 16); +} + void tst_QQuickListView::multipleTransitions() { + QSKIP("QTBUG-24523"); + // Tests that if you interrupt a transition in progress with another action that // cancels the previous transition, the resulting items are still placed correctly. QFETCH(int, initialCount); QFETCH(qreal, contentY); QFETCH(QList<ListChange>, changes); + QFETCH(bool, rippleAddDisplaced); - // add transitions on the left, moves on the right QPointF addTargets_transitionFrom(-50, -50); QPointF addDisplaced_transitionFrom(-50, 50); QPointF moveTargets_transitionFrom(50, -50); QPointF moveDisplaced_transitionFrom(50, 50); + QPointF removeTargets_transitionTo(-100, 300); + QPointF removeDisplaced_transitionFrom(100, 300); QmlListModel model; for (int i = 0; i < initialCount; i++) @@ -5536,8 +5809,12 @@ void tst_QQuickListView::multipleTransitions() ctxt->setContextProperty("addDisplaced_transitionFrom", addDisplaced_transitionFrom); ctxt->setContextProperty("moveTargets_transitionFrom", moveTargets_transitionFrom); ctxt->setContextProperty("moveDisplaced_transitionFrom", moveDisplaced_transitionFrom); + ctxt->setContextProperty("removeTargets_transitionTo", removeTargets_transitionTo); + ctxt->setContextProperty("removeDisplaced_transitionFrom", removeDisplaced_transitionFrom); + ctxt->setContextProperty("rippleAddDisplaced", rippleAddDisplaced); canvas->setSource(testFileUrl("multipleTransitions.qml")); canvas->show(); + QTest::qWaitForWindowShown(canvas); QQuickListView *listview = findItem<QQuickListView>(canvas->rootObject(), "list"); QTRY_VERIFY(listview != 0); @@ -5545,6 +5822,11 @@ void tst_QQuickListView::multipleTransitions() QVERIFY(contentItem != 0); QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + if (contentY != 0) { + listview->setContentY(contentY); + QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + } + int timeBetweenActions = canvas->rootObject()->property("timeBetweenActions").toInt(); QList<QPair<QString, QString> > targetItems; @@ -5604,20 +5886,9 @@ void tst_QQuickListView::multipleTransitions() } QCOMPARE(listview->count(), model.count()); - QList<QQuickItem*> items = findItems<QQuickItem>(contentItem, "wrapper"); - int firstVisibleIndex = -1; - for (int i=0; i<items.count(); i++) { - if (items[i]->y() >= contentY) { - QQmlExpression e(qmlContext(items[i]), items[i], "index"); - firstVisibleIndex = e.evaluate().toInt(); - break; - } - } - QVERIFY2(firstVisibleIndex >= 0, QTest::toString(firstVisibleIndex)); - // verify all items moved to the correct final positions - int itemCount = findItems<QQuickItem>(contentItem, "wrapper").count(); - for (int i=firstVisibleIndex; i < model.count() && i < itemCount; ++i) { + QList<QQuickItem*> items = findItems<QQuickItem>(contentItem, "wrapper"); + for (int i=0; i < model.count() && i < items.count(); ++i) { QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i); QVERIFY2(item, QTest::toString(QString("Item %1 not found").arg(i))); QTRY_COMPARE(item->x(), 0.0); @@ -5636,18 +5907,21 @@ void tst_QQuickListView::multipleTransitions_data() QTest::addColumn<int>("initialCount"); QTest::addColumn<qreal>("contentY"); QTest::addColumn<QList<ListChange> >("changes"); + QTest::addColumn<bool>("rippleAddDisplaced"); // the added item and displaced items should move to final dest correctly QTest::newRow("add item, then move it immediately") << 10 << 0.0 << (QList<ListChange>() << ListChange::insert(0, 1) << ListChange::move(0, 3, 1) - ); + ) + << false; // items affected by the add should change from move to add transition QTest::newRow("move, then insert item before the moved item") << 20 << 0.0 << (QList<ListChange>() << ListChange::move(1, 10, 3) << ListChange::insert(0, 1) - ); + ) + << false; // items should be placed correctly if you trigger a transition then refill for that index QTest::newRow("add at 0, flick down, flick back to top and add at 0 again") << 20 << 0.0 << (QList<ListChange>() @@ -5655,7 +5929,14 @@ void tst_QQuickListView::multipleTransitions_data() << ListChange::setContentY(80.0) << ListChange::setContentY(0.0) << ListChange::insert(0, 1) - ); + ) + << false; + + QTest::newRow("insert then remove same index, with ripple effect on add displaced") << 20 << 0.0 << (QList<ListChange>() + << ListChange::insert(1, 1) + << ListChange::remove(1, 1) + ) + << true; } QList<int> tst_QQuickListView::toIntList(const QVariantList &list) diff --git a/tests/auto/quick/qquickpositioners/data/transitions.qml b/tests/auto/quick/qquickpositioners/data/transitions.qml new file mode 100644 index 0000000000..54f5705c68 --- /dev/null +++ b/tests/auto/quick/qquickpositioners/data/transitions.qml @@ -0,0 +1,196 @@ +import QtQuick 2.0 + +Rectangle { + id: root + width: 500 + height: 500 + + property int duration: 50 + + property int targetTransitionsDone + property int displaceTransitionsDone + + property var targetTrans_items: new Object() + property var targetTrans_targetIndexes: new Array() + property var targetTrans_targetItems: new Array() + + property var displacedTrans_items: new Object() + property var displacedTrans_targetIndexes: new Array() + property var displacedTrans_targetItems: new Array() + + // for QQmlListProperty types + function copyList(propList) { + var temp = new Array() + for (var i=0; i<propList.length; i++) + temp.push(propList[i]) + return temp + } + + function checkPos(x, y, name) { + if (Qt.point(x, y) == targetItems_transitionFrom) + model_targetItems_transitionFrom.addItem(name, "") + if (Qt.point(x, y) == displacedItems_transitionVia) + model_displacedItems_transitionVia.addItem(name, "") + } + + Transition { + id: targetTransition + enabled: enableAddTransition + + SequentialAnimation { + ScriptAction { + script: { + root.targetTrans_items[targetTransition.ViewTransition.item.nameData] = targetTransition.ViewTransition.index + root.targetTrans_targetIndexes.push(targetTransition.ViewTransition.targetIndexes) + root.targetTrans_targetItems.push(root.copyList(targetTransition.ViewTransition.targetItems)) + } + } + ParallelAnimation { + NumberAnimation { properties: "x"; from: targetItems_transitionFrom.x; duration: root.duration } + NumberAnimation { properties: "y"; from: targetItems_transitionFrom.y; duration: root.duration } + } + + ScriptAction { script: root.targetTransitionsDone += 1 } + } + } + + Transition { + id: displaced + + SequentialAnimation { + ScriptAction { + script: { + root.displacedTrans_items[displaced.ViewTransition.item.nameData] = displaced.ViewTransition.index + root.displacedTrans_targetIndexes.push(displaced.ViewTransition.targetIndexes) + root.displacedTrans_targetItems.push(root.copyList(displaced.ViewTransition.targetItems)) + } + } + ParallelAnimation { + NumberAnimation { properties: "x"; duration: root.duration; to: displacedItems_transitionVia.x } + NumberAnimation { properties: "y"; duration: root.duration; to: displacedItems_transitionVia.y } + } + NumberAnimation { properties: "x,y"; duration: root.duration } + + ScriptAction { script: root.displaceTransitionsDone += 1 } + } + + } + + Row { + objectName: "row" + + property int count: children.length - 1 // omit Repeater + + x: 50; y: 50 + width: 400; height: 400 + Repeater { + objectName: "repeater" + Rectangle { + property string nameData: name + objectName: "wrapper" + width: 30 + index*5 + height: 30 + index*5 + border.width: 1 + Column { + Text { text: index } + Text { objectName: "name"; text: name } + Text { text: parent.parent.y } + } + onXChanged: root.checkPos(x, y, name) + onYChanged: root.checkPos(x, y, name) + } + } + + add: targetTransition + move: displaced + } + + Column { + objectName: "column" + + property int count: children.length - 1 // omit Repeater + + x: 50; y: 50 + width: 400; height: 400 + Repeater { + objectName: "repeater" + Rectangle { + property string nameData: name + objectName: "wrapper" + width: 30 + index*5 + height: 30 + index*5 + border.width: 1 + Column { + Text { text: index } + Text { objectName: "name"; text: name } + Text { text: parent.parent.y } + } + onXChanged: root.checkPos(x, y, name) + onYChanged: root.checkPos(x, y, name) + } + } + + add: targetTransition + move: displaced + } + + Grid { + objectName: "grid" + + property int count: children.length - 1 // omit Repeater + + x: 50; y: 50 + width: 400; height: 400 + Repeater { + objectName: "repeater" + Rectangle { + property string nameData: name + objectName: "wrapper" + width: 30 + index*5 + height: 30 + index*5 + border.width: 1 + Column { + Text { text: index } + Text { objectName: "name"; text: name } + Text { text: parent.parent.y } + } + + onXChanged: root.checkPos(x, y, name) + onYChanged: root.checkPos(x, y, name) + } + } + + add: targetTransition + move: displaced + } + + Flow { + objectName: "flow" + + property int count: children.length - 1 // omit Repeater + + x: 50; y: 50 + width: 400; height: 400 + Repeater { + objectName: "repeater" + Rectangle { + property string nameData: name + objectName: "wrapper" + width: 30 + index*5 + height: 30 + index*5 + border.width: 1 + Column { + Text { text: index } + Text { objectName: "name"; text: name } + Text { text: parent.parent.x + " " + parent.parent.y } + } + onXChanged: root.checkPos(x, y, name) + onYChanged: root.checkPos(x, y, name) + } + } + + add: targetTransition + move: displaced + } +} + diff --git a/tests/auto/quick/qquickpositioners/qquickpositioners.pro b/tests/auto/quick/qquickpositioners/qquickpositioners.pro index 56fe465901..563379652b 100644 --- a/tests/auto/quick/qquickpositioners/qquickpositioners.pro +++ b/tests/auto/quick/qquickpositioners/qquickpositioners.pro @@ -2,6 +2,7 @@ CONFIG += testcase TARGET = tst_qquickpositioners SOURCES += tst_qquickpositioners.cpp +include (../shared/util.pri) include (../../shared/util.pri) macx:CONFIG -= app_bundle diff --git a/tests/auto/quick/qquickpositioners/tst_qquickpositioners.cpp b/tests/auto/quick/qquickpositioners/tst_qquickpositioners.cpp index ecc4c80b2a..8f517a4fe3 100644 --- a/tests/auto/quick/qquickpositioners/tst_qquickpositioners.cpp +++ b/tests/auto/quick/qquickpositioners/tst_qquickpositioners.cpp @@ -47,8 +47,13 @@ #include <QtQuick/private/qquicktransition_p.h> #include <private/qquickitem_p.h> #include <qqmlexpression.h> +#include "../shared/viewtestutil.h" +#include "../shared/visualtestutil.h" #include "../../shared/util.h" +using namespace QQuickViewTestUtil; +using namespace QQuickVisualTestUtil; + class tst_qquickpositioners : public QQmlDataTest { Q_OBJECT @@ -88,11 +93,145 @@ private slots: void test_attachedproperties(); void test_attachedproperties_data(); void test_attachedproperties_dynamic(); + void addTransitions_row(); + void addTransitions_row_data(); + void addTransitions_column(); + void addTransitions_column_data(); + void addTransitions_grid(); + void addTransitions_grid_data(); + void addTransitions_flow(); + void addTransitions_flow_data(); + void moveTransitions_row(); + void moveTransitions_row_data(); + void moveTransitions_column(); + void moveTransitions_column_data(); + void moveTransitions_grid(); + void moveTransitions_grid_data(); + void moveTransitions_flow(); + void moveTransitions_flow_data(); private: QQuickView *createView(const QString &filename, bool wait=true); + + void addTransitions(const QString &positionerObjectName); + void addTransitions_data(); + void moveTransitions(const QString &positionerObjectName); + void moveTransitions_data(); + void matchIndexLists(const QVariantList &indexLists, const QList<int> &expectedIndexes); + void matchItemsAndIndexes(const QVariantMap &items, const QaimModel &model, const QList<int> &expectedIndexes); + void matchItemLists(const QVariantList &itemLists, const QList<QQuickItem *> &expectedItems); + void checkItemPositions(QQuickItem *positioner, QaimModel *model, qreal incrementalSize); }; +void tst_qquickpositioners::addTransitions_row() +{ + addTransitions("row"); +} + +void tst_qquickpositioners::addTransitions_row_data() +{ + addTransitions_data(); +} + +void tst_qquickpositioners::addTransitions_column() +{ + addTransitions("column"); +} + +void tst_qquickpositioners::addTransitions_column_data() +{ + addTransitions_data(); +} + +void tst_qquickpositioners::addTransitions_grid() +{ + addTransitions("grid"); +} + +void tst_qquickpositioners::addTransitions_grid_data() +{ + // don't use addTransitions_data() because grid displaces items differently + // (adding items further down the grid can cause displace transitions at + // previous indexes, since grid is auto-resized to tightly fit all of its items) + + QTest::addColumn<int>("initialItemCount"); + QTest::addColumn<int>("insertionIndex"); + QTest::addColumn<int>("insertionCount"); + QTest::addColumn<ListRange>("expectedDisplacedIndexes"); + + QTest::newRow("add one @ start") << 10 << 0 << 1 << ListRange(0, 9); + QTest::newRow("add one @ middle") << 10 << 5 << 1 << ListRange(3, 3) + ListRange(5, 9); + QTest::newRow("add one @ end") << 10 << 10 << 1 << ListRange(3, 3) + ListRange(7, 7); + + QTest::newRow("add multiple @ start") << 10 << 0 << 3 << ListRange(0, 9); + QTest::newRow("add multiple @ middle") << 10 << 5 << 3 << ListRange(1, 3) + ListRange(5, 9); + QTest::newRow("add multiple @ end") << 10 << 10 << 3 << ListRange(1, 3) + ListRange(5, 7) + ListRange(9, 9); +} + +void tst_qquickpositioners::addTransitions_flow() +{ + addTransitions("flow"); +} + +void tst_qquickpositioners::addTransitions_flow_data() +{ + addTransitions_data(); +} + +void tst_qquickpositioners::moveTransitions_row() +{ + moveTransitions("row"); +} + +void tst_qquickpositioners::moveTransitions_row_data() +{ + moveTransitions_data(); +} + +void tst_qquickpositioners::moveTransitions_column() +{ + moveTransitions("column"); +} + +void tst_qquickpositioners::moveTransitions_column_data() +{ + moveTransitions_data(); +} + +void tst_qquickpositioners::moveTransitions_grid() +{ + moveTransitions("grid"); +} + +void tst_qquickpositioners::moveTransitions_grid_data() +{ + // don't use moveTransitions_data() because grid displaces items differently + // (removing items further down the grid can cause displace transitions at + // previous indexes, since grid is auto-resized to tightly fit all of its items) + + QTest::addColumn<int>("initialItemCount"); + QTest::addColumn<ListChange>("change"); + QTest::addColumn<ListRange>("expectedDisplacedIndexes"); + + QTest::newRow("remove one @ start") << 10 << ListChange::remove(0, 1) << ListRange(1, 9); + QTest::newRow("remove one @ middle") << 10 << ListChange::remove(4, 1) << ListRange(2, 3) + ListRange(5, 9); + QTest::newRow("remove one @ end") << 10 << ListChange::remove(9, 1) << ListRange(2, 3) + ListRange(6, 7); + + QTest::newRow("remove multiple @ start") << 10 << ListChange::remove(0, 3) << ListRange(3, 9); + QTest::newRow("remove multiple @ middle") << 10 << ListChange::remove(4, 3) << ListRange(1, 3) + ListRange(7, 9); + QTest::newRow("remove multiple @ end") << 10 << ListChange::remove(7, 3) << ListRange(1, 3) + ListRange(5, 6); +} + +void tst_qquickpositioners::moveTransitions_flow() +{ + moveTransitions("flow"); +} + +void tst_qquickpositioners::moveTransitions_flow_data() +{ + moveTransitions_data(); +} + tst_qquickpositioners::tst_qquickpositioners() { } @@ -370,6 +509,285 @@ void tst_qquickpositioners::test_horizontal_animated_disabled() delete canvas; } +void tst_qquickpositioners::addTransitions(const QString &positionerObjectName) +{ + QFETCH(int, initialItemCount); + QFETCH(int, insertionIndex); + QFETCH(int, insertionCount); + QFETCH(ListRange, expectedDisplacedIndexes); + + QPointF targetItems_transitionFrom(-50, -50); + QPointF displacedItems_transitionVia(100, 100); + + QaimModel model; + for (int i = 0; i < initialItemCount; i++) + model.addItem("Original item" + QString::number(i), ""); + QaimModel model_targetItems_transitionFrom; + QaimModel model_displacedItems_transitionVia; + + QQuickView *canvas = QQuickViewTestUtil::createView(); + QQmlContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("enableAddTransition", true); + ctxt->setContextProperty("model_targetItems_transitionFrom", &model_targetItems_transitionFrom); + ctxt->setContextProperty("model_displacedItems_transitionVia", &model_displacedItems_transitionVia); + ctxt->setContextProperty("targetItems_transitionFrom", targetItems_transitionFrom); + ctxt->setContextProperty("displacedItems_transitionVia", displacedItems_transitionVia); + canvas->setSource(testFile("transitions.qml")); + canvas->show(); + qApp->processEvents(); + + QList<QPair<QString,QString> > expectedDisplacedValues = expectedDisplacedIndexes.getModelDataValues(model); + + QQuickItem *positioner = canvas->rootObject()->findChild<QQuickItem*>(positionerObjectName); + QVERIFY(positioner); + positioner->findChild<QQuickItem*>("repeater")->setProperty("model", QVariant::fromValue(&model)); + + QList<QPair<QString, QString> > targetData; + QList<int> targetIndexes; + for (int i=0; i<model.count(); i++) { + targetData << qMakePair(model.name(i), model.number(i)); + targetIndexes << i; + } + QList<QQuickItem *> targetItems = findItems<QQuickItem>(positioner, "wrapper", targetIndexes); + + // check initial add transition + // (positioners run the add transition on all items that are initially created for the view) + QTRY_COMPARE(canvas->rootObject()->property("targetTransitionsDone").toInt(), initialItemCount); + QTRY_COMPARE(canvas->rootObject()->property("displaceTransitionsDone").toInt(), 0); + model_targetItems_transitionFrom.matchAgainst(targetData, "wasn't animated from target 'from' pos", "shouldn't have been animated from target 'from' pos"); + matchItemsAndIndexes(canvas->rootObject()->property("targetTrans_items").toMap(), model, targetIndexes); + matchIndexLists(canvas->rootObject()->property("targetTrans_targetIndexes").toList(), targetIndexes); + matchItemLists(canvas->rootObject()->property("targetTrans_targetItems").toList(), targetItems); + + model_targetItems_transitionFrom.clear(); + canvas->rootObject()->setProperty("targetTransitionsDone", 0); + canvas->rootObject()->setProperty("targetTrans_items", QVariantMap()); + canvas->rootObject()->setProperty("targetTrans_targetIndexes", QVariantList()); + canvas->rootObject()->setProperty("targetTrans_targetItems", QVariantList()); + + // do insertion + targetData.clear(); + targetIndexes.clear(); + for (int i=insertionIndex; i<insertionIndex+insertionCount; i++) { + targetData << qMakePair(QString("New item %1").arg(i), QString("")); + targetIndexes << i; + } + model.insertItems(insertionIndex, targetData); + QTRY_COMPARE(model.count(), positioner->property("count").toInt()); + + targetItems = findItems<QQuickItem>(positioner, "wrapper", targetIndexes); + + QTRY_COMPARE(canvas->rootObject()->property("targetTransitionsDone").toInt(), targetData.count()); + QTRY_COMPARE(canvas->rootObject()->property("displaceTransitionsDone").toInt(), expectedDisplacedIndexes.count()); + + // check the target and displaced items were animated + model_targetItems_transitionFrom.matchAgainst(targetData, "wasn't animated from target 'from' pos", "shouldn't have been animated from target 'from' pos"); + model_displacedItems_transitionVia.matchAgainst(expectedDisplacedValues, "wasn't animated with displaced anim", "shouldn't have been animated with displaced anim"); + + // check attached properties + matchItemsAndIndexes(canvas->rootObject()->property("targetTrans_items").toMap(), model, targetIndexes); + matchIndexLists(canvas->rootObject()->property("targetTrans_targetIndexes").toList(), targetIndexes); + matchItemLists(canvas->rootObject()->property("targetTrans_targetItems").toList(), targetItems); + if (expectedDisplacedIndexes.isValid()) { + // adjust expectedDisplacedIndexes to their final values after the move + QList<int> displacedIndexes = adjustIndexesForAddDisplaced(expectedDisplacedIndexes.indexes, insertionIndex, insertionCount); + matchItemsAndIndexes(canvas->rootObject()->property("displacedTrans_items").toMap(), model, displacedIndexes); + matchIndexLists(canvas->rootObject()->property("displacedTrans_targetIndexes").toList(), targetIndexes); + matchItemLists(canvas->rootObject()->property("displacedTrans_targetItems").toList(), targetItems); + } + + checkItemPositions(positioner, &model, 5.0); // XXX fetch from qml? + + delete canvas; +} + +void tst_qquickpositioners::addTransitions_data() +{ + // If this data changes, update addTransitions_grid_data() also + + QTest::addColumn<int>("initialItemCount"); + QTest::addColumn<int>("insertionIndex"); + QTest::addColumn<int>("insertionCount"); + QTest::addColumn<ListRange>("expectedDisplacedIndexes"); + + QTest::newRow("add one @ start") << 10 << 0 << 1 << ListRange(0, 9); + QTest::newRow("add one @ middle") << 10 << 5 << 1 << ListRange(5, 9); + QTest::newRow("add one @ end") << 10 << 10 << 1 << ListRange(); + + QTest::newRow("add multiple @ start") << 10 << 0 << 3 << ListRange(0, 9); + QTest::newRow("add multiple @ middle") << 10 << 5 << 3 << ListRange(5, 9); + QTest::newRow("add multiple @ end") << 10 << 10 << 3 << ListRange(); +} + +void tst_qquickpositioners::moveTransitions(const QString &positionerObjectName) +{ + QFETCH(int, initialItemCount); + QFETCH(ListChange, change); + QFETCH(ListRange, expectedDisplacedIndexes); + + QPointF targetItems_transitionFrom(-50, -50); + QPointF displacedItems_transitionVia(100, 100); + + QaimModel model; + for (int i = 0; i < initialItemCount; i++) + model.addItem("Item" + QString::number(i), ""); + QaimModel model_targetItems_transitionFrom; + QaimModel model_displacedItems_transitionVia; + + QQuickView *canvas = QQuickViewTestUtil::createView(); + QQmlContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("enableAddTransition", false); + ctxt->setContextProperty("model_targetItems_transitionFrom", &model_targetItems_transitionFrom); + ctxt->setContextProperty("model_displacedItems_transitionVia", &model_displacedItems_transitionVia); + ctxt->setContextProperty("targetItems_transitionFrom", targetItems_transitionFrom); + ctxt->setContextProperty("displacedItems_transitionVia", displacedItems_transitionVia); + canvas->setSource(testFile("transitions.qml")); + canvas->show(); + qApp->processEvents(); + + QList<QPair<QString,QString> > expectedDisplacedValues = expectedDisplacedIndexes.getModelDataValues(model); + + QQuickItem *positioner = canvas->rootObject()->findChild<QQuickItem*>(positionerObjectName); + QVERIFY(positioner); + positioner->findChild<QQuickItem*>("repeater")->setProperty("model", QVariant::fromValue(&model)); + QTRY_COMPARE(QQuickItemPrivate::get(positioner)->polishScheduled, false); + + switch (change.type) { + case ListChange::Removed: + model.removeItems(change.index, change.count); + QTRY_COMPARE(model.count(), positioner->property("count").toInt()); + break; + case ListChange::Moved: + model.moveItems(change.index, change.to, change.count); + QTRY_COMPARE(QQuickItemPrivate::get(positioner)->polishScheduled, false); + break; + case ListChange::Inserted: + case ListChange::SetCurrent: + case ListChange::SetContentY: + QVERIFY(false); + break; + } + + QTRY_COMPARE(canvas->rootObject()->property("displaceTransitionsDone").toInt(), expectedDisplacedIndexes.count()); + QCOMPARE(canvas->rootObject()->property("targetTransitionsDone").toInt(), 0); + + // check the target and displaced items were animated + QCOMPARE(model_targetItems_transitionFrom.count(), 0); + model_displacedItems_transitionVia.matchAgainst(expectedDisplacedValues, "wasn't animated with displaced anim", "shouldn't have been animated with displaced anim"); + + // check attached properties + QCOMPARE(canvas->rootObject()->property("targetTrans_items").toMap().count(), 0); + QCOMPARE(canvas->rootObject()->property("targetTrans_targetIndexes").toList().count(), 0); + QCOMPARE(canvas->rootObject()->property("targetTrans_targetItems").toList().count(), 0); + if (expectedDisplacedIndexes.isValid()) { + // adjust expectedDisplacedIndexes to their final values after the move + QList<int> displacedIndexes; + if (change.type == ListChange::Inserted) + displacedIndexes = adjustIndexesForAddDisplaced(expectedDisplacedIndexes.indexes, change.index, change.count); + else if (change.type == ListChange::Moved) + displacedIndexes = adjustIndexesForMove(expectedDisplacedIndexes.indexes, change.index, change.to, change.count); + else if (change.type == ListChange::Removed) + displacedIndexes = adjustIndexesForRemoveDisplaced(expectedDisplacedIndexes.indexes, change.index, change.count); + else + QVERIFY(false); + matchItemsAndIndexes(canvas->rootObject()->property("displacedTrans_items").toMap(), model, displacedIndexes); + + QVariantList listOfEmptyIntLists; + for (int i=0; i<displacedIndexes.count(); i++) + listOfEmptyIntLists << QVariant::fromValue(QList<int>()); + QCOMPARE(canvas->rootObject()->property("displacedTrans_targetIndexes").toList(), listOfEmptyIntLists); + QVariantList listOfEmptyObjectLists; + for (int i=0; i<displacedIndexes.count(); i++) + listOfEmptyObjectLists.insert(listOfEmptyObjectLists.count(), QVariantList()); + QCOMPARE(canvas->rootObject()->property("displacedTrans_targetItems").toList(), listOfEmptyObjectLists); + } + + checkItemPositions(positioner, &model, 5.0); + + delete canvas; +} + +void tst_qquickpositioners::moveTransitions_data() +{ + // If this data changes, update moveTransitions_grid_data() also + + QTest::addColumn<int>("initialItemCount"); + QTest::addColumn<ListChange>("change"); + QTest::addColumn<ListRange>("expectedDisplacedIndexes"); + + QTest::newRow("remove one @ start") << 10 << ListChange::remove(0, 1) << ListRange(1, 9); + QTest::newRow("remove one @ middle") << 10 << ListChange::remove(4, 1) << ListRange(5, 9); + QTest::newRow("remove one @ end") << 10 << ListChange::remove(9, 1) << ListRange(); + + QTest::newRow("remove multiple @ start") << 10 << ListChange::remove(0, 3) << ListRange(3, 9); + QTest::newRow("remove multiple @ middle") << 10 << ListChange::remove(4, 3) << ListRange(7, 9); + QTest::newRow("remove multiple @ end") << 10 << ListChange::remove(7, 3) << ListRange(); +} + + +void tst_qquickpositioners::checkItemPositions(QQuickItem *positioner, QaimModel *model, qreal incrementalSize) +{ + QVERIFY(model->count() > 0); + qreal padding = 0; + qreal currentSize = 30; + qreal rowX = 0; + qreal rowY = 0; + + for (int i=0; i<model->count(); ++i) { + QQuickItem *item = findItem<QQuickItem>(positioner, "wrapper", i); + QVERIFY2(item, QTest::toString(QString("Item %1 not found").arg(i))); + + QCOMPARE(item->width(), currentSize); + QCOMPARE(item->height(), currentSize); + + if (qobject_cast<QQuickRow*>(positioner)) { + QCOMPARE(item->x(), (i * 30.0) + padding); + QCOMPARE(item->y(), 0.0); + } else if (qobject_cast<QQuickColumn*>(positioner)) { + QCOMPARE(item->x(), 0.0); + QCOMPARE(item->y(), (i * 30.0) + padding); + } else if (qobject_cast<QQuickGrid*>(positioner)) { + int columns = 4; + int rows = qCeil(model->count() / qreal(columns)); + int lastMatchingRowIndex = (rows * columns) - (columns - i%columns); + if (lastMatchingRowIndex >= model->count()) + lastMatchingRowIndex -= columns; + if (i % columns > 0) { + QQuickItem *finalAlignedRowItem = findItem<QQuickItem>(positioner, "wrapper", lastMatchingRowIndex); + QVERIFY(finalAlignedRowItem); + QCOMPARE(item->x(), finalAlignedRowItem->x()); + } else { + QCOMPARE(item->x(), 0.0); + } + if (i / columns > 0) { + QQuickItem *prevRowLastItem = findItem<QQuickItem>(positioner, "wrapper", (i/columns * columns) - 1); + QVERIFY(prevRowLastItem); + QCOMPARE(item->y(), prevRowLastItem->y() + prevRowLastItem->height()); + } else { + QCOMPARE(item->y(), 0.0); + } + } else if (qobject_cast<QQuickFlow*>(positioner)) { + if (rowX + item->width() > positioner->width()) { + QQuickItem *prevItem = findItem<QQuickItem>(positioner, "wrapper", i-1); + QVERIFY(prevItem); + rowX = 0; + rowY = prevItem->y() + prevItem->height(); + } + QCOMPARE(item->x(), rowX); + QCOMPARE(item->y(), rowY); + rowX += item->width(); + } else { + QVERIFY2(false, "Unknown positioner type"); + } + QQuickText *name = findItem<QQuickText>(positioner, "name", i); + QVERIFY(name != 0); + QTRY_COMPARE(name->text(), model->name(i)); + + padding += i * incrementalSize; + currentSize += incrementalSize; + } +} + void tst_qquickpositioners::test_vertical() { QQuickView *canvas = createView(testFile("vertical.qml")); @@ -1466,6 +1884,43 @@ QQuickView *tst_qquickpositioners::createView(const QString &filename, bool wait return canvas; } +void tst_qquickpositioners::matchIndexLists(const QVariantList &indexLists, const QList<int> &expectedIndexes) +{ + for (int i=0; i<indexLists.count(); i++) { + QSet<int> current = indexLists[i].value<QList<int> >().toSet(); + if (current != expectedIndexes.toSet()) + qDebug() << "Cannot match actual targets" << current << "with expected" << expectedIndexes; + QCOMPARE(current, expectedIndexes.toSet()); + } +} + +void tst_qquickpositioners::matchItemsAndIndexes(const QVariantMap &items, const QaimModel &model, const QList<int> &expectedIndexes) +{ + for (QVariantMap::const_iterator it = items.begin(); it != items.end(); ++it) { + QVERIFY(it.value().type() == QVariant::Int); + QString name = it.key(); + int itemIndex = it.value().toInt(); + QVERIFY2(expectedIndexes.contains(itemIndex), QTest::toString(QString("Index %1 not found in expectedIndexes").arg(itemIndex))); + if (model.name(itemIndex) != name) + qDebug() << itemIndex; + QCOMPARE(model.name(itemIndex), name); + } + QCOMPARE(items.count(), expectedIndexes.count()); +} + +void tst_qquickpositioners::matchItemLists(const QVariantList &itemLists, const QList<QQuickItem *> &expectedItems) +{ + for (int i=0; i<itemLists.count(); i++) { + QVERIFY(itemLists[i].type() == QVariant::List); + QVariantList current = itemLists[i].toList(); + for (int j=0; j<current.count(); j++) { + QQuickItem *o = qobject_cast<QQuickItem*>(current[j].value<QObject*>()); + QVERIFY2(o, QTest::toString(QString("Invalid actual item at %1").arg(j))); + QVERIFY2(expectedItems.contains(o), QTest::toString(QString("Cannot match item %1").arg(j))); + } + QCOMPARE(current.count(), expectedItems.count()); + } +} QTEST_MAIN(tst_qquickpositioners) diff --git a/tests/auto/quick/qquickspritesequence/data/advance.qml b/tests/auto/quick/qquickspritesequence/data/advance.qml new file mode 100644 index 0000000000..5866dcbfac --- /dev/null +++ b/tests/auto/quick/qquickspritesequence/data/advance.qml @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +Rectangle { + color: "black" + width: 320 + height: 320 + + SpriteSequence { + objectName: "sprite" + sprites: [Sprite { + name: "firstState" + source: "squarefacesprite.png" + frameCount: 3 + frameSync: true + to: {"secondState":1} + }, Sprite { + name: "secondState" + source: "squarefacesprite.png" + frameCount: 6 + frameSync: true + } ] + width: 160 + height: 160 + } +} diff --git a/tests/auto/quick/qquickspritesequence/data/basic.qml b/tests/auto/quick/qquickspritesequence/data/basic.qml new file mode 100644 index 0000000000..5eb7475f11 --- /dev/null +++ b/tests/auto/quick/qquickspritesequence/data/basic.qml @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +Rectangle { + color: "black" + width: 320 + height: 320 + + SpriteSequence { + objectName: "sprite" + sprites: Sprite { + name: "happy" + source: "squarefacesprite.png" + frameCount: 6 + frameDuration: 120 + } + width: 160 + height: 160 + } +} diff --git a/tests/auto/quick/qquickspritesequence/data/squarefacesprite.png b/tests/auto/quick/qquickspritesequence/data/squarefacesprite.png Binary files differnew file mode 100644 index 0000000000..f9a5d5fcce --- /dev/null +++ b/tests/auto/quick/qquickspritesequence/data/squarefacesprite.png diff --git a/tests/auto/quick/qquickspritesequence/qquickspritesequence.pro b/tests/auto/quick/qquickspritesequence/qquickspritesequence.pro new file mode 100644 index 0000000000..3dabd065a0 --- /dev/null +++ b/tests/auto/quick/qquickspritesequence/qquickspritesequence.pro @@ -0,0 +1,15 @@ +CONFIG += testcase +TARGET = tst_qquickspritesequence +SOURCES += tst_qquickspritesequence.cpp + +include (../../shared/util.pri) + +macx:CONFIG -= app_bundle + +testDataFiles.files = data +testDataFiles.path = . +DEPLOYMENT += testDataFiles + +CONFIG += parallel_test + +QT += core-private gui-private qml-private quick-private network testlib diff --git a/tests/auto/quick/qquickspritesequence/tst_qquickspritesequence.cpp b/tests/auto/quick/qquickspritesequence/tst_qquickspritesequence.cpp new file mode 100644 index 0000000000..8469a949c6 --- /dev/null +++ b/tests/auto/quick/qquickspritesequence/tst_qquickspritesequence.cpp @@ -0,0 +1,98 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include <QtTest/QtTest> +#include "../../shared/util.h" +#include <QtQuick/qquickview.h> +#include <private/qquickspritesequence_p.h> + +class tst_qquickspritesequence : public QQmlDataTest +{ + Q_OBJECT +public: + tst_qquickspritesequence(){} + +private slots: + void test_properties(); + void test_framerateAdvance();//Separate codepath for QQuickSpriteEngine +}; + +void tst_qquickspritesequence::test_properties() +{ + QQuickView *canvas = new QQuickView(0); + + canvas->setSource(testFileUrl("basic.qml")); + canvas->show(); + QTest::qWaitForWindowShown(canvas); + + QVERIFY(canvas->rootObject()); + QQuickSpriteSequence* sprite = canvas->rootObject()->findChild<QQuickSpriteSequence*>("sprite"); + QVERIFY(sprite); + + QVERIFY(sprite->running()); + QVERIFY(sprite->interpolate()); + + sprite->setRunning(false); + QVERIFY(!sprite->running()); + sprite->setInterpolate(false); + QVERIFY(!sprite->interpolate()); + + delete canvas; +} + +void tst_qquickspritesequence::test_framerateAdvance() +{ + QQuickView *canvas = new QQuickView(0); + + canvas->setSource(testFileUrl("advance.qml")); + canvas->show(); + QTest::qWaitForWindowShown(canvas); + + QVERIFY(canvas->rootObject()); + QQuickSpriteSequence* sprite = canvas->rootObject()->findChild<QQuickSpriteSequence*>("sprite"); + QVERIFY(sprite); + + QTRY_COMPARE(sprite->currentSprite(), QLatin1String("secondState")); + delete canvas; +} + +QTEST_MAIN(tst_qquickspritesequence) + +#include "tst_qquickspritesequence.moc" diff --git a/tests/auto/quick/qquickstyledtext/tst_qquickstyledtext.cpp b/tests/auto/quick/qquickstyledtext/tst_qquickstyledtext.cpp index 86874b84fd..35ce724a64 100644 --- a/tests/auto/quick/qquickstyledtext/tst_qquickstyledtext.cpp +++ b/tests/auto/quick/qquickstyledtext/tst_qquickstyledtext.cpp @@ -88,68 +88,69 @@ void tst_qquickstyledtext::textOutput_data() QTest::addColumn<QString>("input"); QTest::addColumn<QString>("output"); QTest::addColumn<FormatList>("formats"); - - QTest::newRow("bold") << "<b>bold</b>" << "bold" << (FormatList() << Format(Format::Bold, 0, 4)); - QTest::newRow("italic") << "<i>italic</i>" << "italic" << (FormatList() << Format(Format::Italic, 0, 6)); - QTest::newRow("underline") << "<u>underline</u>" << "underline" << (FormatList() << Format(Format::Underline, 0, 9)); - QTest::newRow("strong") << "<strong>strong</strong>" << "strong" << (FormatList() << Format(Format::Bold, 0, 6)); - QTest::newRow("underline") << "<u>underline</u>" << "underline" << (FormatList() << Format(Format::Underline, 0, 9)); - QTest::newRow("missing >") << "<b>text</b" << "text" << (FormatList() << Format(Format::Bold, 0, 4)); - QTest::newRow("missing b>") << "<b>text</" << "text" << (FormatList() << Format(Format::Bold, 0, 4)); - QTest::newRow("missing /b>") << "<b>text<" << "text" << (FormatList() << Format(Format::Bold, 0, 4)); - QTest::newRow("missing </b>") << "<b>text" << "text" << (FormatList() << Format(Format::Bold, 0, 4)); - QTest::newRow("nested") << "<b>text <i>italic</i> bold</b>" << "text italic bold" << (FormatList() << Format(Format::Bold, 0, 5) << Format(Format::Bold | Format::Italic, 5, 6) << Format(Format::Bold, 11, 5)); - QTest::newRow("bad nest") << "<b>text <i>italic</b></i>" << "text italic" << (FormatList() << Format(Format::Bold, 0, 5) << Format(Format::Bold | Format::Italic, 5, 6)); - QTest::newRow("font color") << "<font color=\"red\">red text</font>" << "red text" << (FormatList() << Format(0, 0, 8)); - QTest::newRow("font color: single quote") << "<font color='red'>red text</font>" << "red text" << (FormatList() << Format(0, 0, 8)); - QTest::newRow("font size") << "<font size=\"1\">text</font>" << "text" << (FormatList() << Format(0, 0, 4)); - QTest::newRow("font empty") << "<font>text</font>" << "text" << FormatList(); - QTest::newRow("font bad 1") << "<font ezis=\"blah\">text</font>" << "text" << FormatList(); - QTest::newRow("font bad 2") << "<font size=\"1>text</font>" << "" << FormatList(); - QTest::newRow("extra close") << "<b>text</b></b>" << "text" << (FormatList() << Format(Format::Bold, 0, 4)); - QTest::newRow("extra space") << "<b >text</b>" << "text" << (FormatList() << Format(Format::Bold, 0, 4)); - QTest::newRow("entities") << "<b>this & that</b>" << "<b>this & that</b>" << FormatList(); - QTest::newRow("newline") << "text<br>more text" << QLatin1String("text") + QChar(QChar::LineSeparator) + QLatin1String("more text") << FormatList(); - QTest::newRow("paragraph") << "text<p>more text" << QLatin1String("text") + QChar(QChar::LineSeparator) + QLatin1String("more text") << FormatList(); - QTest::newRow("paragraph closed") << "text<p>more text</p>more text" << QLatin1String("text") + QChar(QChar::LineSeparator) + QLatin1String("more text") + QChar(QChar::LineSeparator) + QLatin1String("more text") << FormatList(); - QTest::newRow("paragraph closed bold") << "<b>text<p>more text</p>more text</b>" << QLatin1String("text") + QChar(QChar::LineSeparator) + QLatin1String("more text") + QChar(QChar::LineSeparator) + QLatin1String("more text") << (FormatList() << Format(Format::Bold, 0, 24)); - QTest::newRow("self-closing newline") << "text<br/>more text" << QLatin1String("text") + QChar(QChar::LineSeparator) + QLatin1String("more text") << FormatList(); - QTest::newRow("empty") << "" << "" << FormatList(); - QTest::newRow("unknown tag") << "<a href='#'><foo>underline</foo></a> not" << "underline not" << (FormatList() << Format(Format::Underline, 0, 9)); - QTest::newRow("ordered list") << "<ol><li>one<li>two" << QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + QLatin1String("1.") + QString(2, QChar::Nbsp) + QLatin1String("one") + QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + QLatin1String("2.") + QString(2, QChar::Nbsp) + QLatin1String("two") << FormatList(); - QTest::newRow("ordered list closed") << "<ol><li>one</li><li>two</li></ol>" << QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + QLatin1String("1.") + QString(2, QChar::Nbsp) + QLatin1String("one") + QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + QLatin1String("2.") + QString(2, QChar::Nbsp) + QLatin1String("two") + QChar(QChar::LineSeparator) << FormatList(); - QTest::newRow("ordered list alpha") << "<ol type=\"a\"><li>one</li><li>two</li></ol>" << QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + QLatin1String("a.") + QString(2, QChar::Nbsp) + QLatin1String("one") + QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + QLatin1String("b.") + QString(2, QChar::Nbsp) + QLatin1String("two") + QChar(QChar::LineSeparator) << FormatList(); - QTest::newRow("ordered list upper alpha") << "<ol type=\"A\"><li>one</li><li>two</li></ol>" << QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + QLatin1String("A.") + QString(2, QChar::Nbsp) + QLatin1String("one") + QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + QLatin1String("B.") + QString(2, QChar::Nbsp) + QLatin1String("two") + QChar(QChar::LineSeparator) << FormatList(); - QTest::newRow("ordered list roman") << "<ol type=\"i\"><li>one</li><li>two</li></ol>" << QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + QLatin1String("i.") + QString(2, QChar::Nbsp) + QLatin1String("one") + QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + QLatin1String("ii.") + QString(2, QChar::Nbsp) + QLatin1String("two") + QChar(QChar::LineSeparator) << FormatList(); - QTest::newRow("ordered list upper roman") << "<ol type=\"I\"><li>one</li><li>two</li></ol>" << QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + QLatin1String("I.") + QString(2, QChar::Nbsp) + QLatin1String("one") + QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + QLatin1String("II.") + QString(2, QChar::Nbsp) + QLatin1String("two") + QChar(QChar::LineSeparator) << FormatList(); - QTest::newRow("ordered list bad") << "<ol type=\"z\"><li>one</li><li>two</li></ol>" << QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + QLatin1String("1.") + QString(2, QChar::Nbsp) + QLatin1String("one") + QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + QLatin1String("2.") + QString(2, QChar::Nbsp) + QLatin1String("two") + QChar(QChar::LineSeparator) << FormatList(); - QTest::newRow("unordered list") << "<ul><li>one<li>two" << QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + bullet + QString(2, QChar::Nbsp) + QLatin1String("one") + QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + bullet + QString(2, QChar::Nbsp) + QLatin1String("two") << FormatList(); - QTest::newRow("unordered list closed") << "<ul><li>one</li><li>two</li></ul>" << QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + bullet + QString(2, QChar::Nbsp) + QLatin1String("one") + QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + bullet + QString(2, QChar::Nbsp) + QLatin1String("two") + QChar(QChar::LineSeparator) << FormatList(); - QTest::newRow("unordered list disc") << "<ul type=\"disc\"><li>one</li><li>two</li></ul>" << QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + disc + QString(2, QChar::Nbsp) + QLatin1String("one") + QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + disc + QString(2, QChar::Nbsp) + QLatin1String("two") + QChar(QChar::LineSeparator) << FormatList(); - QTest::newRow("unordered list square") << "<ul type=\"square\"><li>one</li><li>two</li></ul>" << QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + square + QString(2, QChar::Nbsp) + QLatin1String("one") + QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + square + QString(2, QChar::Nbsp) + QLatin1String("two") + QChar(QChar::LineSeparator) << FormatList(); - QTest::newRow("unordered list bad") << "<ul type=\"bad\"><li>one</li><li>two</li></ul>" << QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + bullet + QString(2, QChar::Nbsp) + QLatin1String("one") + QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + bullet + QString(2, QChar::Nbsp) + QLatin1String("two") + QChar(QChar::LineSeparator) << FormatList(); - QTest::newRow("header close") << "<h1>head</h1>more" << QChar(QChar::LineSeparator) + QLatin1String("head") + QChar(QChar::LineSeparator) + QLatin1String("more") << (FormatList() << Format(Format::Bold, 0, 5)); - QTest::newRow("h0") << "<h0>head" << "head" << FormatList(); - QTest::newRow("h1") << "<h1>head" << QChar(QChar::LineSeparator) + QLatin1String("head") << (FormatList() << Format(Format::Bold, 0, 5)); - QTest::newRow("h2") << "<h2>head" << QChar(QChar::LineSeparator) + QLatin1String("head") << (FormatList() << Format(Format::Bold, 0, 5)); - QTest::newRow("h3") << "<h3>head" << QChar(QChar::LineSeparator) + QLatin1String("head") << (FormatList() << Format(Format::Bold, 0, 5)); - QTest::newRow("h4") << "<h4>head" << QChar(QChar::LineSeparator) + QLatin1String("head") << (FormatList() << Format(Format::Bold, 0, 5)); - QTest::newRow("h5") << "<h5>head" << QChar(QChar::LineSeparator) + QLatin1String("head") << (FormatList() << Format(Format::Bold, 0, 5)); - QTest::newRow("h6") << "<h6>head" << QChar(QChar::LineSeparator) + QLatin1String("head") << (FormatList() << Format(Format::Bold, 0, 5)); - QTest::newRow("h7") << "<h7>head" << "head" << FormatList(); - QTest::newRow("pre") << "normal<pre>pre text</pre>normal" << QLatin1String("normal") + QChar(QChar::LineSeparator) + QLatin1String("pre") + QChar(QChar::Nbsp) + QLatin1String("text") + QChar(QChar::LineSeparator) + QLatin1String("normal") << (FormatList() << Format(0, 6, 9)); - QTest::newRow("pre lb") << "normal<pre>pre\n text</pre>normal" << QLatin1String("normal") + QChar(QChar::LineSeparator) + QLatin1String("pre") + QChar(QChar::LineSeparator) + QChar(QChar::Nbsp) + QLatin1String("text") + QChar(QChar::LineSeparator) + QLatin1String("normal") << (FormatList() << Format(0, 6, 10)); - QTest::newRow("line feed") << "line\nfeed" << "line feed" << FormatList(); - QTest::newRow("leading whitespace") << " leading whitespace" << "leading whitespace" << FormatList(); - QTest::newRow("trailing whitespace") << "trailing whitespace " << "trailing whitespace" << FormatList(); - QTest::newRow("consecutive whitespace") << " consecutive \t \n whitespace" << "consecutive whitespace" << FormatList(); - QTest::newRow("space after newline") << "text<br/> more text" << QLatin1String("text") + QChar(QChar::LineSeparator) + QLatin1String("more text") << FormatList(); - QTest::newRow("space after paragraph") << "text<p> more text</p> more text" << QLatin1String("text") + QChar(QChar::LineSeparator) + QLatin1String("more text") + QChar(QChar::LineSeparator) + QLatin1String("more text") << FormatList(); - QTest::newRow("space in header") << "<h1> head</h1> " << QChar(QChar::LineSeparator) + QLatin1String("head") + QChar(QChar::LineSeparator) << (FormatList() << Format(Format::Bold, 0, 5)); - QTest::newRow("space before bold") << "this is <b>bold</b>" << "this is bold" << (FormatList() << Format(Format::Bold, 8, 4)); - QTest::newRow("space leading bold") << "this is<b> bold</b>" << "this is bold" << (FormatList() << Format(Format::Bold, 7, 5)); - QTest::newRow("space trailing bold") << "this is <b>bold </b>" << "this is bold " << (FormatList() << Format(Format::Bold, 8, 5)); - QTest::newRow("img") << "a<img src=\"blah.png\"/>b" << "a b" << FormatList(); + QTest::addColumn<bool>("modifiesFontSize"); + + QTest::newRow("bold") << "<b>bold</b>" << "bold" << (FormatList() << Format(Format::Bold, 0, 4)) << false; + QTest::newRow("italic") << "<i>italic</i>" << "italic" << (FormatList() << Format(Format::Italic, 0, 6)) << false; + QTest::newRow("underline") << "<u>underline</u>" << "underline" << (FormatList() << Format(Format::Underline, 0, 9)) << false; + QTest::newRow("strong") << "<strong>strong</strong>" << "strong" << (FormatList() << Format(Format::Bold, 0, 6)) << false; + QTest::newRow("underline") << "<u>underline</u>" << "underline" << (FormatList() << Format(Format::Underline, 0, 9)) << false; + QTest::newRow("missing >") << "<b>text</b" << "text" << (FormatList() << Format(Format::Bold, 0, 4)) << false; + QTest::newRow("missing b>") << "<b>text</" << "text" << (FormatList() << Format(Format::Bold, 0, 4)) << false; + QTest::newRow("missing /b>") << "<b>text<" << "text" << (FormatList() << Format(Format::Bold, 0, 4)) << false; + QTest::newRow("missing </b>") << "<b>text" << "text" << (FormatList() << Format(Format::Bold, 0, 4)) << false; + QTest::newRow("nested") << "<b>text <i>italic</i> bold</b>" << "text italic bold" << (FormatList() << Format(Format::Bold, 0, 5) << Format(Format::Bold | Format::Italic, 5, 6) << Format(Format::Bold, 11, 5)) << false; + QTest::newRow("bad nest") << "<b>text <i>italic</b></i>" << "text italic" << (FormatList() << Format(Format::Bold, 0, 5) << Format(Format::Bold | Format::Italic, 5, 6)) << false; + QTest::newRow("font color") << "<font color=\"red\">red text</font>" << "red text" << (FormatList() << Format(0, 0, 8)) << false; + QTest::newRow("font color: single quote") << "<font color='red'>red text</font>" << "red text" << (FormatList() << Format(0, 0, 8)) << false; + QTest::newRow("font size") << "<font size=\"1\">text</font>" << "text" << (FormatList() << Format(0, 0, 4)) << true; + QTest::newRow("font empty") << "<font>text</font>" << "text" << FormatList() << false; + QTest::newRow("font bad 1") << "<font ezis=\"blah\">text</font>" << "text" << FormatList() << false; + QTest::newRow("font bad 2") << "<font size=\"1>text</font>" << "" << FormatList() << false; + QTest::newRow("extra close") << "<b>text</b></b>" << "text" << (FormatList() << Format(Format::Bold, 0, 4)) << false; + QTest::newRow("extra space") << "<b >text</b>" << "text" << (FormatList() << Format(Format::Bold, 0, 4)) << false; + QTest::newRow("entities") << "<b>this & that</b>" << "<b>this & that</b>" << FormatList() << false; + QTest::newRow("newline") << "text<br>more text" << QLatin1String("text") + QChar(QChar::LineSeparator) + QLatin1String("more text") << FormatList() << false; + QTest::newRow("paragraph") << "text<p>more text" << QLatin1String("text") + QChar(QChar::LineSeparator) + QLatin1String("more text") << FormatList() << false; + QTest::newRow("paragraph closed") << "text<p>more text</p>more text" << QLatin1String("text") + QChar(QChar::LineSeparator) + QLatin1String("more text") + QChar(QChar::LineSeparator) + QLatin1String("more text") << FormatList() << false; + QTest::newRow("paragraph closed bold") << "<b>text<p>more text</p>more text</b>" << QLatin1String("text") + QChar(QChar::LineSeparator) + QLatin1String("more text") + QChar(QChar::LineSeparator) + QLatin1String("more text") << (FormatList() << Format(Format::Bold, 0, 24)) << false; + QTest::newRow("self-closing newline") << "text<br/>more text" << QLatin1String("text") + QChar(QChar::LineSeparator) + QLatin1String("more text") << FormatList() << false; + QTest::newRow("empty") << "" << "" << FormatList() << false; + QTest::newRow("unknown tag") << "<a href='#'><foo>underline</foo></a> not" << "underline not" << (FormatList() << Format(Format::Underline, 0, 9)) << false; + QTest::newRow("ordered list") << "<ol><li>one<li>two" << QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + QLatin1String("1.") + QString(2, QChar::Nbsp) + QLatin1String("one") + QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + QLatin1String("2.") + QString(2, QChar::Nbsp) + QLatin1String("two") << FormatList() << false; + QTest::newRow("ordered list closed") << "<ol><li>one</li><li>two</li></ol>" << QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + QLatin1String("1.") + QString(2, QChar::Nbsp) + QLatin1String("one") + QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + QLatin1String("2.") + QString(2, QChar::Nbsp) + QLatin1String("two") + QChar(QChar::LineSeparator) << FormatList() << false; + QTest::newRow("ordered list alpha") << "<ol type=\"a\"><li>one</li><li>two</li></ol>" << QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + QLatin1String("a.") + QString(2, QChar::Nbsp) + QLatin1String("one") + QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + QLatin1String("b.") + QString(2, QChar::Nbsp) + QLatin1String("two") + QChar(QChar::LineSeparator) << FormatList() << false; + QTest::newRow("ordered list upper alpha") << "<ol type=\"A\"><li>one</li><li>two</li></ol>" << QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + QLatin1String("A.") + QString(2, QChar::Nbsp) + QLatin1String("one") + QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + QLatin1String("B.") + QString(2, QChar::Nbsp) + QLatin1String("two") + QChar(QChar::LineSeparator) << FormatList() << false; + QTest::newRow("ordered list roman") << "<ol type=\"i\"><li>one</li><li>two</li></ol>" << QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + QLatin1String("i.") + QString(2, QChar::Nbsp) + QLatin1String("one") + QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + QLatin1String("ii.") + QString(2, QChar::Nbsp) + QLatin1String("two") + QChar(QChar::LineSeparator) << FormatList() << false; + QTest::newRow("ordered list upper roman") << "<ol type=\"I\"><li>one</li><li>two</li></ol>" << QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + QLatin1String("I.") + QString(2, QChar::Nbsp) + QLatin1String("one") + QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + QLatin1String("II.") + QString(2, QChar::Nbsp) + QLatin1String("two") + QChar(QChar::LineSeparator) << FormatList() << false; + QTest::newRow("ordered list bad") << "<ol type=\"z\"><li>one</li><li>two</li></ol>" << QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + QLatin1String("1.") + QString(2, QChar::Nbsp) + QLatin1String("one") + QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + QLatin1String("2.") + QString(2, QChar::Nbsp) + QLatin1String("two") + QChar(QChar::LineSeparator) << FormatList() << false; + QTest::newRow("unordered list") << "<ul><li>one<li>two" << QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + bullet + QString(2, QChar::Nbsp) + QLatin1String("one") + QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + bullet + QString(2, QChar::Nbsp) + QLatin1String("two") << FormatList() << false; + QTest::newRow("unordered list closed") << "<ul><li>one</li><li>two</li></ul>" << QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + bullet + QString(2, QChar::Nbsp) + QLatin1String("one") + QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + bullet + QString(2, QChar::Nbsp) + QLatin1String("two") + QChar(QChar::LineSeparator) << FormatList() << false; + QTest::newRow("unordered list disc") << "<ul type=\"disc\"><li>one</li><li>two</li></ul>" << QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + disc + QString(2, QChar::Nbsp) + QLatin1String("one") + QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + disc + QString(2, QChar::Nbsp) + QLatin1String("two") + QChar(QChar::LineSeparator) << FormatList() << false; + QTest::newRow("unordered list square") << "<ul type=\"square\"><li>one</li><li>two</li></ul>" << QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + square + QString(2, QChar::Nbsp) + QLatin1String("one") + QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + square + QString(2, QChar::Nbsp) + QLatin1String("two") + QChar(QChar::LineSeparator) << FormatList() << false; + QTest::newRow("unordered list bad") << "<ul type=\"bad\"><li>one</li><li>two</li></ul>" << QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + bullet + QString(2, QChar::Nbsp) + QLatin1String("one") + QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + bullet + QString(2, QChar::Nbsp) + QLatin1String("two") + QChar(QChar::LineSeparator) << FormatList() << false; + QTest::newRow("header close") << "<h1>head</h1>more" << QChar(QChar::LineSeparator) + QLatin1String("head") + QChar(QChar::LineSeparator) + QLatin1String("more") << (FormatList() << Format(Format::Bold, 0, 5)) << true; + QTest::newRow("h0") << "<h0>head" << "head" << FormatList() << false; + QTest::newRow("h1") << "<h1>head" << QChar(QChar::LineSeparator) + QLatin1String("head") << (FormatList() << Format(Format::Bold, 0, 5)) << true; + QTest::newRow("h2") << "<h2>head" << QChar(QChar::LineSeparator) + QLatin1String("head") << (FormatList() << Format(Format::Bold, 0, 5)) << true; + QTest::newRow("h3") << "<h3>head" << QChar(QChar::LineSeparator) + QLatin1String("head") << (FormatList() << Format(Format::Bold, 0, 5)) << true; + QTest::newRow("h4") << "<h4>head" << QChar(QChar::LineSeparator) + QLatin1String("head") << (FormatList() << Format(Format::Bold, 0, 5)) << true; + QTest::newRow("h5") << "<h5>head" << QChar(QChar::LineSeparator) + QLatin1String("head") << (FormatList() << Format(Format::Bold, 0, 5)) << true; + QTest::newRow("h6") << "<h6>head" << QChar(QChar::LineSeparator) + QLatin1String("head") << (FormatList() << Format(Format::Bold, 0, 5)) << true; + QTest::newRow("h7") << "<h7>head" << "head" << FormatList() << false; + QTest::newRow("pre") << "normal<pre>pre text</pre>normal" << QLatin1String("normal") + QChar(QChar::LineSeparator) + QLatin1String("pre") + QChar(QChar::Nbsp) + QLatin1String("text") + QChar(QChar::LineSeparator) + QLatin1String("normal") << (FormatList() << Format(0, 6, 9)) << false; + QTest::newRow("pre lb") << "normal<pre>pre\n text</pre>normal" << QLatin1String("normal") + QChar(QChar::LineSeparator) + QLatin1String("pre") + QChar(QChar::LineSeparator) + QChar(QChar::Nbsp) + QLatin1String("text") + QChar(QChar::LineSeparator) + QLatin1String("normal") << (FormatList() << Format(0, 6, 10)) << false; + QTest::newRow("line feed") << "line\nfeed" << "line feed" << FormatList() << false; + QTest::newRow("leading whitespace") << " leading whitespace" << "leading whitespace" << FormatList() << false; + QTest::newRow("trailing whitespace") << "trailing whitespace " << "trailing whitespace" << FormatList() << false; + QTest::newRow("consecutive whitespace") << " consecutive \t \n whitespace" << "consecutive whitespace" << FormatList() << false; + QTest::newRow("space after newline") << "text<br/> more text" << QLatin1String("text") + QChar(QChar::LineSeparator) + QLatin1String("more text") << FormatList() << false; + QTest::newRow("space after paragraph") << "text<p> more text</p> more text" << QLatin1String("text") + QChar(QChar::LineSeparator) + QLatin1String("more text") + QChar(QChar::LineSeparator) + QLatin1String("more text") << FormatList() << false; + QTest::newRow("space in header") << "<h1> head</h1> " << QChar(QChar::LineSeparator) + QLatin1String("head") + QChar(QChar::LineSeparator) << (FormatList() << Format(Format::Bold, 0, 5)) << true; + QTest::newRow("space before bold") << "this is <b>bold</b>" << "this is bold" << (FormatList() << Format(Format::Bold, 8, 4)) << false; + QTest::newRow("space leading bold") << "this is<b> bold</b>" << "this is bold" << (FormatList() << Format(Format::Bold, 7, 5)) << false; + QTest::newRow("space trailing bold") << "this is <b>bold </b>" << "this is bold " << (FormatList() << Format(Format::Bold, 8, 5)) << false; + QTest::newRow("img") << "a<img src=\"blah.png\"/>b" << "a b" << FormatList() << false; } void tst_qquickstyledtext::textOutput() @@ -157,10 +158,12 @@ void tst_qquickstyledtext::textOutput() QFETCH(QString, input); QFETCH(QString, output); QFETCH(FormatList, formats); + QFETCH(bool, modifiesFontSize); QTextLayout layout; QList<QQuickStyledTextImgTag*> imgTags; - QQuickStyledText::parse(input, layout, imgTags, QUrl(), 0, false); + bool fontSizeModified = false; + QQuickStyledText::parse(input, layout, imgTags, QUrl(), 0, false, &fontSizeModified); QCOMPARE(layout.text(), output); @@ -177,6 +180,7 @@ void tst_qquickstyledtext::textOutput() QVERIFY(layoutFormats.at(i).format.fontItalic() == bool(formats.at(i).type & Format::Italic)); QVERIFY(layoutFormats.at(i).format.fontUnderline() == bool(formats.at(i).type & Format::Underline)); } + QCOMPARE(fontSizeModified, modifiesFontSize); } diff --git a/tests/auto/quick/qquicktext/data/fontSizeMode.qml b/tests/auto/quick/qquicktext/data/fontSizeMode.qml index 20f7535365..84f7ce8d50 100644 --- a/tests/auto/quick/qquicktext/data/fontSizeMode.qml +++ b/tests/auto/quick/qquicktext/data/fontSizeMode.qml @@ -19,6 +19,4 @@ Item { font.pixelSize: 30 font.family: "Helvetica" } - - TextInput { focus: true; objectName: "input" } } diff --git a/tests/auto/quick/qquicktext/data/multilengthStrings.qml b/tests/auto/quick/qquicktext/data/multilengthStrings.qml index d26576eacd..6b9dc71fbc 100644 --- a/tests/auto/quick/qquicktext/data/multilengthStrings.qml +++ b/tests/auto/quick/qquicktext/data/multilengthStrings.qml @@ -7,7 +7,7 @@ Item { Text { id: myText objectName: "myText" - width: 100 + width: 60 font.pixelSize: 15 font.family: "Helvetica" } diff --git a/tests/auto/quick/qquicktext/data/multilengthStringsWrapped.qml b/tests/auto/quick/qquicktext/data/multilengthStringsWrapped.qml index 0da9bc353a..21f1b20619 100644 --- a/tests/auto/quick/qquicktext/data/multilengthStringsWrapped.qml +++ b/tests/auto/quick/qquicktext/data/multilengthStringsWrapped.qml @@ -7,7 +7,7 @@ Item { Text { id: myText objectName: "myText" - width: 100 + width: 60 height: 36 font.pixelSize: 15 font.family: "Helvetica" diff --git a/tests/auto/quick/qquicktext/data/multilineelide.qml b/tests/auto/quick/qquicktext/data/multilineelide.qml index f3bb65775b..ffca0d638a 100644 --- a/tests/auto/quick/qquicktext/data/multilineelide.qml +++ b/tests/auto/quick/qquicktext/data/multilineelide.qml @@ -1,7 +1,7 @@ import QtQuick 2.0 Text { - width: 200; height: 200 + width: 200 wrapMode: Text.WordWrap elide: Text.ElideRight maximumLineCount: 3 diff --git a/tests/auto/quick/qquicktext/data/pixelFontSizes.qml b/tests/auto/quick/qquicktext/data/pixelFontSizes.qml new file mode 100644 index 0000000000..e3d81b682e --- /dev/null +++ b/tests/auto/quick/qquicktext/data/pixelFontSizes.qml @@ -0,0 +1,21 @@ +import QtQuick 2.0 + +Rectangle { + width: 400 + height: 200 + + property variant pixelSize: 6 + + Text { + objectName: "text" + font.pixelSize: parent.pixelSize + text: "This is<br/>a font<br/> size test." + } + + Text { + x: 200 + objectName: "textWithTag" + font.pixelSize: parent.pixelSize + text: "This is <h4>a font</h4> size test." + } +} diff --git a/tests/auto/quick/qquicktext/data/pointFontSizes.qml b/tests/auto/quick/qquicktext/data/pointFontSizes.qml new file mode 100644 index 0000000000..6feb8fecf8 --- /dev/null +++ b/tests/auto/quick/qquicktext/data/pointFontSizes.qml @@ -0,0 +1,21 @@ +import QtQuick 2.0 + +Rectangle { + width: 400 + height: 200 + + property variant pointSize: 6 + + Text { + objectName: "text" + font.pointSize: parent.pointSize + text: "This is<br/>a font<br/> size test." + } + + Text { + x: 200 + objectName: "textWithTag" + font.pointSize: parent.pointSize + text: "This is <h4>a font</h4> size test." + } +} diff --git a/tests/auto/quick/qquicktext/tst_qquicktext.cpp b/tests/auto/quick/qquicktext/tst_qquicktext.cpp index 754395dba1..54b5a04466 100644 --- a/tests/auto/quick/qquicktext/tst_qquicktext.cpp +++ b/tests/auto/quick/qquicktext/tst_qquicktext.cpp @@ -58,6 +58,8 @@ DEFINE_BOOL_CONFIG_OPTION(qmlDisableDistanceField, QML_DISABLE_DISTANCEFIELD) +Q_DECLARE_METATYPE(QQuickText::TextFormat) + class tst_qquicktext : public QQmlDataTest { Q_OBJECT @@ -69,6 +71,7 @@ private slots: void width(); void wrap(); void elide(); + void multilineElide_data(); void multilineElide(); void textFormat(); @@ -122,6 +125,8 @@ private slots: void fontSizeModeMultiline(); void multilengthStrings_data(); void multilengthStrings(); + void fontFormatSizes_data(); + void fontFormatSizes(); private: QStringList standard; @@ -293,11 +298,10 @@ void tst_qquicktext::width() layout.endLayout(); - metricWidth = qCeil(layout.boundingRect().width()); + metricWidth = layout.boundingRect().width(); } else { QFontMetricsF fm(f); - qreal metricWidth = fm.size(Qt::TextExpandTabs && Qt::TextShowMnemonic, standard.at(i)).width(); - metricWidth = qCeil(metricWidth); + metricWidth = fm.size(Qt::TextExpandTabs && Qt::TextShowMnemonic, standard.at(i)).width(); } QString componentStr = "import QtQuick 2.0\nText { text: \"" + standard.at(i) + "\" }"; @@ -325,8 +329,9 @@ void tst_qquicktext::width() QQuickTextPrivate *textPrivate = QQuickTextPrivate::get(textObject); QVERIFY(textPrivate != 0); + QVERIFY(textPrivate->extra.isAllocated()); - QTextDocument *doc = textPrivate->textDocument(); + QTextDocument *doc = textPrivate->extra->doc; QVERIFY(doc != 0); QCOMPARE(int(textObject->width()), int(doc->idealWidth())); @@ -438,10 +443,12 @@ void tst_qquicktext::elide() QCOMPARE(textObject->elideMode(), m); QCOMPARE(textObject->width(), 100.); + if (m != QQuickText::ElideNone && !standard.at(i).contains('\n')) + QVERIFY(textObject->contentWidth() <= textObject->width()); + delete textObject; } - // richtext - does nothing for (int i = 0; i < richText.size(); i++) { QString componentStr = "import QtQuick 2.0\nText { "+elide+" width: 100; text: \"" + richText.at(i) + "\" }"; @@ -452,23 +459,41 @@ void tst_qquicktext::elide() QCOMPARE(textObject->elideMode(), m); QCOMPARE(textObject->width(), 100.); + if (m != QQuickText::ElideNone && standard.at(i).contains("<br>")) + QVERIFY(textObject->contentWidth() <= textObject->width()); + delete textObject; } } } +void tst_qquicktext::multilineElide_data() +{ + QTest::addColumn<QQuickText::TextFormat>("format"); + QTest::newRow("plain") << QQuickText::PlainText; + QTest::newRow("styled") << QQuickText::StyledText; +} + void tst_qquicktext::multilineElide() { + QFETCH(QQuickText::TextFormat, format); QQuickView *canvas = createView(testFile("multilineelide.qml")); QQuickText *myText = qobject_cast<QQuickText*>(canvas->rootObject()); QVERIFY(myText != 0); + myText->setTextFormat(format); QCOMPARE(myText->lineCount(), 3); QCOMPARE(myText->truncated(), true); qreal lineHeight = myText->contentHeight() / 3.; + // Set a valid height greater than the truncated content height and ensure the line count is + // unchanged. + myText->setHeight(200); + QCOMPARE(myText->lineCount(), 3); + QCOMPARE(myText->truncated(), true); + // reduce size and ensure fewer lines are drawn myText->setHeight(lineHeight * 2); QCOMPARE(myText->lineCount(), 2); @@ -670,19 +695,20 @@ void tst_qquicktext::horizontalAlignment_RightToLeft() // implicitly aligned rich text should follow the reading direction of text QCOMPARE(text->hAlign(), QQuickText::AlignRight); QCOMPARE(text->effectiveHAlign(), text->hAlign()); - QVERIFY(textPrivate->textDocument()->defaultTextOption().alignment() & Qt::AlignLeft); + QVERIFY(textPrivate->extra.isAllocated()); + QVERIFY(textPrivate->extra->doc->defaultTextOption().alignment() & Qt::AlignLeft); // explicitly left aligned rich text text->setHAlign(QQuickText::AlignLeft); QCOMPARE(text->hAlign(), QQuickText::AlignLeft); QCOMPARE(text->effectiveHAlign(), text->hAlign()); - QVERIFY(textPrivate->textDocument()->defaultTextOption().alignment() & Qt::AlignRight); + QVERIFY(textPrivate->extra->doc->defaultTextOption().alignment() & Qt::AlignRight); // explicitly right aligned rich text text->setHAlign(QQuickText::AlignRight); QCOMPARE(text->hAlign(), QQuickText::AlignRight); QCOMPARE(text->effectiveHAlign(), text->hAlign()); - QVERIFY(textPrivate->textDocument()->defaultTextOption().alignment() & Qt::AlignLeft); + QVERIFY(textPrivate->extra->doc->defaultTextOption().alignment() & Qt::AlignLeft); text->setText(textString); text->setTextFormat(QQuickText::PlainText); @@ -1616,8 +1642,7 @@ void tst_qquicktext::lineLaidOut() QQuickTextPrivate *textPrivate = QQuickTextPrivate::get(myText); QVERIFY(textPrivate != 0); - QTextDocument *doc = textPrivate->textDocument(); - QVERIFY(doc == 0); + QVERIFY(!textPrivate->extra.isAllocated()); #if defined(Q_OS_MAC) QVERIFY(myText->lineCount() == textPrivate->linesRects.count()); @@ -1835,17 +1860,15 @@ void tst_qquicktext::imgTagsError() void tst_qquicktext::fontSizeMode_data() { QTest::addColumn<QString>("text"); - QTest::addColumn<bool>("canElide"); - QTest::newRow("plain") << "The quick red fox jumped over the lazy brown dog" << true; - QTest::newRow("richtext") << "<b>The quick red fox jumped over the lazy brown dog</b>" << false; + QTest::newRow("plain") << "The quick red fox jumped over the lazy brown dog"; + QTest::newRow("styled") << "<b>The quick red fox jumped over the lazy brown dog</b>"; } void tst_qquicktext::fontSizeMode() { QFETCH(QString, text); - QFETCH(bool, canElide); - QQuickView *canvas = createView(testFile("fontSizeMode.qml")); + QScopedPointer<QQuickView> canvas(createView(testFile("fontSizeMode.qml"))); canvas->show(); QQuickText *myText = canvas->rootObject()->findChild<QQuickText*>("myText"); @@ -1873,29 +1896,27 @@ void tst_qquicktext::fontSizeMode() QVERIFY(horizontalFitWidth <= myText->width() + 2); // rounding QVERIFY(horizontalFitHeight <= myText->height() + 2); - if (canElide) { - // Elide won't affect the size with HorizontalFit. - myText->setElideMode(QQuickText::ElideRight); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); - QVERIFY(!myText->truncated()); - QCOMPARE(myText->contentWidth(), horizontalFitWidth); - QCOMPARE(myText->contentHeight(), horizontalFitHeight); - - myText->setElideMode(QQuickText::ElideLeft); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); - QVERIFY(!myText->truncated()); - QCOMPARE(myText->contentWidth(), horizontalFitWidth); - QCOMPARE(myText->contentHeight(), horizontalFitHeight); - - myText->setElideMode(QQuickText::ElideMiddle); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); - QVERIFY(!myText->truncated()); - QCOMPARE(myText->contentWidth(), horizontalFitWidth); - QCOMPARE(myText->contentHeight(), horizontalFitHeight); - - myText->setElideMode(QQuickText::ElideNone); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); - } + // Elide won't affect the size with HorizontalFit. + myText->setElideMode(QQuickText::ElideRight); + QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(!myText->truncated()); + QCOMPARE(myText->contentWidth(), horizontalFitWidth); + QCOMPARE(myText->contentHeight(), horizontalFitHeight); + + myText->setElideMode(QQuickText::ElideLeft); + QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(!myText->truncated()); + QCOMPARE(myText->contentWidth(), horizontalFitWidth); + QCOMPARE(myText->contentHeight(), horizontalFitHeight); + + myText->setElideMode(QQuickText::ElideMiddle); + QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(!myText->truncated()); + QCOMPARE(myText->contentWidth(), horizontalFitWidth); + QCOMPARE(myText->contentHeight(), horizontalFitHeight); + + myText->setElideMode(QQuickText::ElideNone); + QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); myText->setFontSizeMode(QQuickText::VerticalFit); QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); @@ -1905,29 +1926,27 @@ void tst_qquicktext::fontSizeMode() QVERIFY(verticalFitHeight <= myText->height() + 2); QVERIFY(verticalFitHeight > originalHeight); - if (canElide) { - // Elide won't affect the height of a single line with VerticalFit but will crop the width. - myText->setElideMode(QQuickText::ElideRight); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); - QVERIFY(myText->truncated()); - QVERIFY(myText->contentWidth() <= myText->width() + 2); - QCOMPARE(myText->contentHeight(), verticalFitHeight); - - myText->setElideMode(QQuickText::ElideLeft); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); - QVERIFY(myText->truncated()); - QVERIFY(myText->contentWidth() <= myText->width() + 2); - QCOMPARE(myText->contentHeight(), verticalFitHeight); - - myText->setElideMode(QQuickText::ElideMiddle); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); - QVERIFY(myText->truncated()); - QVERIFY(myText->contentWidth() <= myText->width() + 2); - QCOMPARE(myText->contentHeight(), verticalFitHeight); - - myText->setElideMode(QQuickText::ElideNone); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); - } + // Elide won't affect the height of a single line with VerticalFit but will crop the width. + myText->setElideMode(QQuickText::ElideRight); + QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(myText->truncated()); + QVERIFY(myText->contentWidth() <= myText->width() + 2); + QCOMPARE(myText->contentHeight(), verticalFitHeight); + + myText->setElideMode(QQuickText::ElideLeft); + QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(myText->truncated()); + QVERIFY(myText->contentWidth() <= myText->width() + 2); + QCOMPARE(myText->contentHeight(), verticalFitHeight); + + myText->setElideMode(QQuickText::ElideMiddle); + QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(myText->truncated()); + QVERIFY(myText->contentWidth() <= myText->width() + 2); + QCOMPARE(myText->contentHeight(), verticalFitHeight); + + myText->setElideMode(QQuickText::ElideNone); + QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); myText->setFontSizeMode(QQuickText::Fit); QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); @@ -1935,29 +1954,27 @@ void tst_qquicktext::fontSizeMode() QCOMPARE(myText->contentWidth(), horizontalFitWidth); QCOMPARE(myText->contentHeight(), horizontalFitHeight); - if (canElide) { - // Elide won't affect the size with Fit. - myText->setElideMode(QQuickText::ElideRight); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); - QVERIFY(!myText->truncated()); - QCOMPARE(myText->contentWidth(), horizontalFitWidth); - QCOMPARE(myText->contentHeight(), horizontalFitHeight); - - myText->setElideMode(QQuickText::ElideLeft); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); - QVERIFY(!myText->truncated()); - QCOMPARE(myText->contentWidth(), horizontalFitWidth); - QCOMPARE(myText->contentHeight(), horizontalFitHeight); - - myText->setElideMode(QQuickText::ElideMiddle); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); - QVERIFY(!myText->truncated()); - QCOMPARE(myText->contentWidth(), horizontalFitWidth); - QCOMPARE(myText->contentHeight(), horizontalFitHeight); - - myText->setElideMode(QQuickText::ElideNone); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); - } + // Elide won't affect the size with Fit. + myText->setElideMode(QQuickText::ElideRight); + QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(!myText->truncated()); + QCOMPARE(myText->contentWidth(), horizontalFitWidth); + QCOMPARE(myText->contentHeight(), horizontalFitHeight); + + myText->setElideMode(QQuickText::ElideLeft); + QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(!myText->truncated()); + QCOMPARE(myText->contentWidth(), horizontalFitWidth); + QCOMPARE(myText->contentHeight(), horizontalFitHeight); + + myText->setElideMode(QQuickText::ElideMiddle); + QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(!myText->truncated()); + QCOMPARE(myText->contentWidth(), horizontalFitWidth); + QCOMPARE(myText->contentHeight(), horizontalFitHeight); + + myText->setElideMode(QQuickText::ElideNone); + QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); myText->setFontSizeMode(QQuickText::FixedSize); myText->setWrapMode(QQuickText::Wrap); @@ -1977,17 +1994,15 @@ void tst_qquicktext::fontSizeMode() QCOMPARE(myText->contentWidth(), horizontalFitWidth); QCOMPARE(myText->contentHeight(), horizontalFitHeight); - if (canElide) { - // Elide won't affect the size with HorizontalFit. - myText->setElideMode(QQuickText::ElideRight); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); - QVERIFY(!myText->truncated()); - QCOMPARE(myText->contentWidth(), horizontalFitWidth); - QCOMPARE(myText->contentHeight(), horizontalFitHeight); + // Elide won't affect the size with HorizontalFit. + myText->setElideMode(QQuickText::ElideRight); + QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(!myText->truncated()); + QCOMPARE(myText->contentWidth(), horizontalFitWidth); + QCOMPARE(myText->contentHeight(), horizontalFitHeight); - myText->setElideMode(QQuickText::ElideNone); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); - } + myText->setElideMode(QQuickText::ElideNone); + QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); myText->setFontSizeMode(QQuickText::VerticalFit); QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); @@ -1998,17 +2013,15 @@ void tst_qquicktext::fontSizeMode() QVERIFY(verticalFitHeight <= myText->height() + 2); QVERIFY(verticalFitHeight < originalHeight); - if (canElide) { - // Elide won't affect the height or width of a wrapped text with VerticalFit. - myText->setElideMode(QQuickText::ElideRight); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); - QVERIFY(!myText->truncated()); - QCOMPARE(myText->contentWidth(), verticalFitWidth); - QCOMPARE(myText->contentHeight(), verticalFitHeight); + // Elide won't affect the height or width of a wrapped text with VerticalFit. + myText->setElideMode(QQuickText::ElideRight); + QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(!myText->truncated()); + QCOMPARE(myText->contentWidth(), verticalFitWidth); + QCOMPARE(myText->contentHeight(), verticalFitHeight); - myText->setElideMode(QQuickText::ElideNone); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); - } + myText->setElideMode(QQuickText::ElideNone); + QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); myText->setFontSizeMode(QQuickText::Fit); QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); @@ -2016,17 +2029,15 @@ void tst_qquicktext::fontSizeMode() QCOMPARE(myText->contentWidth(), verticalFitWidth); QCOMPARE(myText->contentHeight(), verticalFitHeight); - if (canElide) { - // Elide won't affect the size with Fit. - myText->setElideMode(QQuickText::ElideRight); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); - QVERIFY(!myText->truncated()); - QCOMPARE(myText->contentWidth(), verticalFitWidth); - QCOMPARE(myText->contentHeight(), verticalFitHeight); + // Elide won't affect the size with Fit. + myText->setElideMode(QQuickText::ElideRight); + QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(!myText->truncated()); + QCOMPARE(myText->contentWidth(), verticalFitWidth); + QCOMPARE(myText->contentHeight(), verticalFitHeight); - myText->setElideMode(QQuickText::ElideNone); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); - } + myText->setElideMode(QQuickText::ElideNone); + QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); myText->setFontSizeMode(QQuickText::FixedSize); myText->setMaximumLineCount(2); @@ -2043,17 +2054,15 @@ void tst_qquicktext::fontSizeMode() QCOMPARE(myText->contentWidth(), horizontalFitWidth); QCOMPARE(myText->contentHeight(), horizontalFitHeight); - if (canElide) { - // Elide won't affect the size with HorizontalFit. - myText->setElideMode(QQuickText::ElideRight); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); - QVERIFY(!myText->truncated()); - QCOMPARE(myText->contentWidth(), horizontalFitWidth); - QCOMPARE(myText->contentHeight(), horizontalFitHeight); + // Elide won't affect the size with HorizontalFit. + myText->setElideMode(QQuickText::ElideRight); + QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(!myText->truncated()); + QCOMPARE(myText->contentWidth(), horizontalFitWidth); + QCOMPARE(myText->contentHeight(), horizontalFitHeight); - myText->setElideMode(QQuickText::ElideNone); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); - } + myText->setElideMode(QQuickText::ElideNone); + QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); myText->setFontSizeMode(QQuickText::VerticalFit); QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); @@ -2064,17 +2073,15 @@ void tst_qquicktext::fontSizeMode() QVERIFY(verticalFitHeight <= myText->height() + 2); QVERIFY(verticalFitHeight < originalHeight); - if (canElide) { - // Elide won't affect the height or width of a wrapped text with VerticalFit. - myText->setElideMode(QQuickText::ElideRight); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); - QVERIFY(!myText->truncated()); - QCOMPARE(myText->contentWidth(), verticalFitWidth); - QCOMPARE(myText->contentHeight(), verticalFitHeight); + // Elide won't affect the height or width of a wrapped text with VerticalFit. + myText->setElideMode(QQuickText::ElideRight); + QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(!myText->truncated()); + QCOMPARE(myText->contentWidth(), verticalFitWidth); + QCOMPARE(myText->contentHeight(), verticalFitHeight); - myText->setElideMode(QQuickText::ElideNone); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); - } + myText->setElideMode(QQuickText::ElideNone); + QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); myText->setFontSizeMode(QQuickText::Fit); QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); @@ -2082,33 +2089,29 @@ void tst_qquicktext::fontSizeMode() QCOMPARE(myText->contentWidth(), verticalFitWidth); QCOMPARE(myText->contentHeight(), verticalFitHeight); - if (canElide) { - // Elide won't affect the size with Fit. - myText->setElideMode(QQuickText::ElideRight); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); - QVERIFY(!myText->truncated()); - QCOMPARE(myText->contentWidth(), verticalFitWidth); - QCOMPARE(myText->contentHeight(), verticalFitHeight); + // Elide won't affect the size with Fit. + myText->setElideMode(QQuickText::ElideRight); + QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(!myText->truncated()); + QCOMPARE(myText->contentWidth(), verticalFitWidth); + QCOMPARE(myText->contentHeight(), verticalFitHeight); - myText->setElideMode(QQuickText::ElideNone); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); - } + myText->setElideMode(QQuickText::ElideNone); + QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); } void tst_qquicktext::fontSizeModeMultiline_data() { QTest::addColumn<QString>("text"); - QTest::addColumn<bool>("canElide"); - QTest::newRow("plain") << "The quick red fox jumped\n over the lazy brown dog" << true; - QTest::newRow("richtext") << "<b>The quick red fox jumped<br/> over the lazy brown dog</b>" << false; + QTest::newRow("plain") << "The quick red fox jumped\n over the lazy brown dog"; + QTest::newRow("styledtext") << "<b>The quick red fox jumped<br/> over the lazy brown dog</b>"; } void tst_qquicktext::fontSizeModeMultiline() { QFETCH(QString, text); - QFETCH(bool, canElide); - QQuickView *canvas = createView(testFile("fontSizeMode.qml")); + QScopedPointer<QQuickView> canvas(createView(testFile("fontSizeMode.qml"))); canvas->show(); QQuickText *myText = canvas->rootObject()->findChild<QQuickText*>("myText"); @@ -2138,31 +2141,29 @@ void tst_qquicktext::fontSizeModeMultiline() QVERIFY(horizontalFitWidth <= myText->width() + 2); // rounding QVERIFY(horizontalFitHeight > myText->height()); - if (canElide) { - // Right eliding will remove the last line - myText->setElideMode(QQuickText::ElideRight); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); - QVERIFY(myText->truncated()); - QCOMPARE(myText->lineCount(), 1); - QVERIFY(myText->contentWidth() <= myText->width() + 2); - QVERIFY(myText->contentHeight() <= myText->height() + 2); - - // Left or middle eliding wont have any effect. - myText->setElideMode(QQuickText::ElideLeft); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); - QVERIFY(!myText->truncated()); - QCOMPARE(myText->contentWidth(), horizontalFitWidth); - QCOMPARE(myText->contentHeight(), horizontalFitHeight); - - myText->setElideMode(QQuickText::ElideMiddle); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); - QVERIFY(!myText->truncated()); - QCOMPARE(myText->contentWidth(), horizontalFitWidth); - QCOMPARE(myText->contentHeight(), horizontalFitHeight); - - myText->setElideMode(QQuickText::ElideNone); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); - } + // Right eliding will remove the last line + myText->setElideMode(QQuickText::ElideRight); + QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(myText->truncated()); + QCOMPARE(myText->lineCount(), 1); + QVERIFY(myText->contentWidth() <= myText->width() + 2); + QVERIFY(myText->contentHeight() <= myText->height() + 2); + + // Left or middle eliding wont have any effect. + myText->setElideMode(QQuickText::ElideLeft); + QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(!myText->truncated()); + QCOMPARE(myText->contentWidth(), horizontalFitWidth); + QCOMPARE(myText->contentHeight(), horizontalFitHeight); + + myText->setElideMode(QQuickText::ElideMiddle); + QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(!myText->truncated()); + QCOMPARE(myText->contentWidth(), horizontalFitWidth); + QCOMPARE(myText->contentHeight(), horizontalFitHeight); + + myText->setElideMode(QQuickText::ElideNone); + QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); myText->setFontSizeMode(QQuickText::VerticalFit); QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); @@ -2172,30 +2173,28 @@ void tst_qquicktext::fontSizeModeMultiline() QVERIFY(verticalFitWidth <= myText->width() + 2); QVERIFY(verticalFitHeight <= myText->height() + 2); - if (canElide) { - // Elide will have no effect. - myText->setElideMode(QQuickText::ElideRight); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); - QVERIFY(!myText->truncated()); - QVERIFY(myText->contentWidth() <= myText->width() + 2); - QCOMPARE(myText->contentWidth(), verticalFitWidth); - QCOMPARE(myText->contentHeight(), verticalFitHeight); - - myText->setElideMode(QQuickText::ElideLeft); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); - QVERIFY(!myText->truncated()); - QCOMPARE(myText->contentWidth(), verticalFitWidth); - QCOMPARE(myText->contentHeight(), verticalFitHeight); - - myText->setElideMode(QQuickText::ElideMiddle); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); - QVERIFY(!myText->truncated()); - QCOMPARE(myText->contentWidth(), verticalFitWidth); - QCOMPARE(myText->contentHeight(), verticalFitHeight); - - myText->setElideMode(QQuickText::ElideNone); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); - } + // Elide will have no effect. + myText->setElideMode(QQuickText::ElideRight); + QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(!myText->truncated()); + QVERIFY(myText->contentWidth() <= myText->width() + 2); + QCOMPARE(myText->contentWidth(), verticalFitWidth); + QCOMPARE(myText->contentHeight(), verticalFitHeight); + + myText->setElideMode(QQuickText::ElideLeft); + QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(!myText->truncated()); + QCOMPARE(myText->contentWidth(), verticalFitWidth); + QCOMPARE(myText->contentHeight(), verticalFitHeight); + + myText->setElideMode(QQuickText::ElideMiddle); + QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(!myText->truncated()); + QCOMPARE(myText->contentWidth(), verticalFitWidth); + QCOMPARE(myText->contentHeight(), verticalFitHeight); + + myText->setElideMode(QQuickText::ElideNone); + QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); myText->setFontSizeMode(QQuickText::Fit); QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); @@ -2203,29 +2202,27 @@ void tst_qquicktext::fontSizeModeMultiline() QCOMPARE(myText->contentWidth(), verticalFitWidth); QCOMPARE(myText->contentHeight(), verticalFitHeight); - if (canElide) { - // Elide won't affect the size with Fit. - myText->setElideMode(QQuickText::ElideRight); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); - QVERIFY(!myText->truncated()); - QCOMPARE(myText->contentWidth(), verticalFitWidth); - QCOMPARE(myText->contentHeight(), verticalFitHeight); - - myText->setElideMode(QQuickText::ElideLeft); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); - QVERIFY(!myText->truncated()); - QCOMPARE(myText->contentWidth(), verticalFitWidth); - QCOMPARE(myText->contentHeight(), verticalFitHeight); - - myText->setElideMode(QQuickText::ElideMiddle); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); - QVERIFY(!myText->truncated()); - QCOMPARE(myText->contentWidth(), verticalFitWidth); - QCOMPARE(myText->contentHeight(), verticalFitHeight); - - myText->setElideMode(QQuickText::ElideNone); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); - } + // Elide won't affect the size with Fit. + myText->setElideMode(QQuickText::ElideRight); + QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(!myText->truncated()); + QCOMPARE(myText->contentWidth(), verticalFitWidth); + QCOMPARE(myText->contentHeight(), verticalFitHeight); + + myText->setElideMode(QQuickText::ElideLeft); + QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(!myText->truncated()); + QCOMPARE(myText->contentWidth(), verticalFitWidth); + QCOMPARE(myText->contentHeight(), verticalFitHeight); + + myText->setElideMode(QQuickText::ElideMiddle); + QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(!myText->truncated()); + QCOMPARE(myText->contentWidth(), verticalFitWidth); + QCOMPARE(myText->contentHeight(), verticalFitHeight); + + myText->setElideMode(QQuickText::ElideNone); + QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); myText->setFontSizeMode(QQuickText::FixedSize); myText->setWrapMode(QQuickText::Wrap); @@ -2245,17 +2242,15 @@ void tst_qquicktext::fontSizeModeMultiline() QCOMPARE(myText->contentWidth(), horizontalFitWidth); QCOMPARE(myText->contentHeight(), horizontalFitHeight); - if (canElide) { - // Text will be elided vertically with HorizontalFit - myText->setElideMode(QQuickText::ElideRight); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); - QVERIFY(myText->truncated()); - QVERIFY(myText->contentWidth() <= myText->width() + 2); - QVERIFY(myText->contentHeight() <= myText->height() + 2); + // Text will be elided vertically with HorizontalFit + myText->setElideMode(QQuickText::ElideRight); + QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(myText->truncated()); + QVERIFY(myText->contentWidth() <= myText->width() + 2); + QVERIFY(myText->contentHeight() <= myText->height() + 2); - myText->setElideMode(QQuickText::ElideNone); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); - } + myText->setElideMode(QQuickText::ElideNone); + QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); myText->setFontSizeMode(QQuickText::VerticalFit); QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); @@ -2266,17 +2261,15 @@ void tst_qquicktext::fontSizeModeMultiline() QVERIFY(verticalFitHeight <= myText->height() + 2); QVERIFY(verticalFitHeight < originalHeight); - if (canElide) { - // Elide won't affect the height or width of a wrapped text with VerticalFit. - myText->setElideMode(QQuickText::ElideRight); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); - QVERIFY(!myText->truncated()); - QCOMPARE(myText->contentWidth(), verticalFitWidth); - QCOMPARE(myText->contentHeight(), verticalFitHeight); + // Elide won't affect the height or width of a wrapped text with VerticalFit. + myText->setElideMode(QQuickText::ElideRight); + QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(!myText->truncated()); + QCOMPARE(myText->contentWidth(), verticalFitWidth); + QCOMPARE(myText->contentHeight(), verticalFitHeight); - myText->setElideMode(QQuickText::ElideNone); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); - } + myText->setElideMode(QQuickText::ElideNone); + QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); myText->setFontSizeMode(QQuickText::Fit); QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); @@ -2284,17 +2277,15 @@ void tst_qquicktext::fontSizeModeMultiline() QCOMPARE(myText->contentWidth(), verticalFitWidth); QCOMPARE(myText->contentHeight(), verticalFitHeight); - if (canElide) { - // Elide won't affect the size with Fit. - myText->setElideMode(QQuickText::ElideRight); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); - QVERIFY(!myText->truncated()); - QCOMPARE(myText->contentWidth(), verticalFitWidth); - QCOMPARE(myText->contentHeight(), verticalFitHeight); + // Elide won't affect the size with Fit. + myText->setElideMode(QQuickText::ElideRight); + QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(!myText->truncated()); + QCOMPARE(myText->contentWidth(), verticalFitWidth); + QCOMPARE(myText->contentHeight(), verticalFitHeight); - myText->setElideMode(QQuickText::ElideNone); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); - } + myText->setElideMode(QQuickText::ElideNone); + QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); myText->setFontSizeMode(QQuickText::FixedSize); myText->setMaximumLineCount(2); @@ -2311,17 +2302,15 @@ void tst_qquicktext::fontSizeModeMultiline() QCOMPARE(myText->contentWidth(), horizontalFitWidth); QCOMPARE(myText->contentHeight(), horizontalFitHeight); - if (canElide) { - // Elide won't affect the size with HorizontalFit. - myText->setElideMode(QQuickText::ElideRight); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); - QVERIFY(myText->truncated()); - QVERIFY(myText->contentWidth() <= myText->width() + 2); - QVERIFY(myText->contentHeight() <= myText->height() + 2); + // Elide won't affect the size with HorizontalFit. + myText->setElideMode(QQuickText::ElideRight); + QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(myText->truncated()); + QVERIFY(myText->contentWidth() <= myText->width() + 2); + QVERIFY(myText->contentHeight() <= myText->height() + 2); - myText->setElideMode(QQuickText::ElideNone); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); - } + myText->setElideMode(QQuickText::ElideNone); + QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); myText->setFontSizeMode(QQuickText::VerticalFit); QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); @@ -2332,17 +2321,15 @@ void tst_qquicktext::fontSizeModeMultiline() QVERIFY(verticalFitHeight <= myText->height() + 2); QVERIFY(verticalFitHeight < originalHeight); - if (canElide) { - // Elide won't affect the height or width of a wrapped text with VerticalFit. - myText->setElideMode(QQuickText::ElideRight); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); - QVERIFY(!myText->truncated()); - QCOMPARE(myText->contentWidth(), verticalFitWidth); - QCOMPARE(myText->contentHeight(), verticalFitHeight); + // Elide won't affect the height or width of a wrapped text with VerticalFit. + myText->setElideMode(QQuickText::ElideRight); + QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(!myText->truncated()); + QCOMPARE(myText->contentWidth(), verticalFitWidth); + QCOMPARE(myText->contentHeight(), verticalFitHeight); - myText->setElideMode(QQuickText::ElideNone); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); - } + myText->setElideMode(QQuickText::ElideNone); + QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); myText->setFontSizeMode(QQuickText::Fit); QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); @@ -2350,17 +2337,15 @@ void tst_qquicktext::fontSizeModeMultiline() QCOMPARE(myText->contentWidth(), verticalFitWidth); QCOMPARE(myText->contentHeight(), verticalFitHeight); - if (canElide) { - // Elide won't affect the size with Fit. - myText->setElideMode(QQuickText::ElideRight); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); - QVERIFY(!myText->truncated()); - QCOMPARE(myText->contentWidth(), verticalFitWidth); - QCOMPARE(myText->contentHeight(), verticalFitHeight); + // Elide won't affect the size with Fit. + myText->setElideMode(QQuickText::ElideRight); + QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); + QVERIFY(!myText->truncated()); + QCOMPARE(myText->contentWidth(), verticalFitWidth); + QCOMPARE(myText->contentHeight(), verticalFitHeight); - myText->setElideMode(QQuickText::ElideNone); - QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); - } + myText->setElideMode(QQuickText::ElideNone); + QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false); } void tst_qquicktext::multilengthStrings_data() @@ -2414,9 +2399,6 @@ void tst_qquicktext::multilengthStrings() QCOMPARE(myText->contentWidth(), mediumWidth); QCOMPARE(myText->contentHeight(), mediumHeight); -#ifdef Q_OS_MAC - QEXPECT_FAIL("Wrap", "QTBUG-24310", Continue); -#endif QCOMPARE(myText->truncated(), true); myText->setSize(QSizeF(shortWidth, shortHeight)); @@ -2427,6 +2409,76 @@ void tst_qquicktext::multilengthStrings() QCOMPARE(myText->truncated(), true); } +void tst_qquicktext::fontFormatSizes_data() +{ + QTest::addColumn<QString>("text"); + QTest::addColumn<QString>("textWithTag"); + QTest::addColumn<bool>("fontIsBigger"); + + QTest::newRow("fs1") << "Hello world!" << "Hello <font size=\"1\">world</font>!" << false; + QTest::newRow("fs2") << "Hello world!" << "Hello <font size=\"2\">world</font>!" << false; + QTest::newRow("fs3") << "Hello world!" << "Hello <font size=\"3\">world</font>!" << false; + QTest::newRow("fs4") << "Hello world!" << "Hello <font size=\"4\">world</font>!" << true; + QTest::newRow("fs5") << "Hello world!" << "Hello <font size=\"5\">world</font>!" << true; + QTest::newRow("fs6") << "Hello world!" << "Hello <font size=\"6\">world</font>!" << true; + QTest::newRow("fs7") << "Hello world!" << "Hello <font size=\"7\">world</font>!" << true; + QTest::newRow("h1") << "This is<br/>a font<br/> size test." << "This is <h1>a font</h1> size test." << true; + QTest::newRow("h2") << "This is<br/>a font<br/> size test." << "This is <h2>a font</h2> size test." << true; + QTest::newRow("h3") << "This is<br/>a font<br/> size test." << "This is <h3>a font</h3> size test." << true; + QTest::newRow("h4") << "This is<br/>a font<br/> size test." << "This is <h4>a font</h4> size test." << true; + QTest::newRow("h5") << "This is<br/>a font<br/> size test." << "This is <h5>a font</h5> size test." << false; + QTest::newRow("h6") << "This is<br/>a font<br/> size test." << "This is <h6>a font</h6> size test." << false; +} + +void tst_qquicktext::fontFormatSizes() +{ + QFETCH(QString, text); + QFETCH(QString, textWithTag); + QFETCH(bool, fontIsBigger); + + QQuickView *view = new QQuickView; + { + view->setSource(testFileUrl("pointFontSizes.qml")); + view->show(); + + QQuickText *qtext = view->rootObject()->findChild<QQuickText*>("text"); + QQuickText *qtextWithTag = view->rootObject()->findChild<QQuickText*>("textWithTag"); + QVERIFY(qtext != 0); + QVERIFY(qtextWithTag != 0); + + qtext->setText(text); + qtextWithTag->setText(textWithTag); + + for (int size = 6; size < 100; size += 4) { + view->rootObject()->setProperty("pointSize", size); + if (fontIsBigger) + QVERIFY(qtext->height() <= qtextWithTag->height()); + else + QVERIFY(qtext->height() >= qtextWithTag->height()); + } + } + + { + view->setSource(testFileUrl("pixelFontSizes.qml")); + QQuickText *qtext = view->rootObject()->findChild<QQuickText*>("text"); + QQuickText *qtextWithTag = view->rootObject()->findChild<QQuickText*>("textWithTag"); + QVERIFY(qtext != 0); + QVERIFY(qtextWithTag != 0); + + qtext->setText(text); + qtextWithTag->setText(textWithTag); + + for (int size = 6; size < 100; size += 4) { + view->rootObject()->setProperty("pixelSize", size); + if (fontIsBigger) + QVERIFY(qtext->height() <= qtextWithTag->height()); + else + QVERIFY(qtext->height() >= qtextWithTag->height()); + } + } + delete view; +} + QTEST_MAIN(tst_qquicktext) #include "tst_qquicktext.moc" diff --git a/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp b/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp index 314a523602..85a9033dd7 100644 --- a/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp +++ b/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp @@ -461,10 +461,10 @@ void tst_qquicktextedit::width() layout.endLayout(); - qreal metricWidth = ceil(layout.boundingRect().width()); + qreal metricWidth = layout.boundingRect().width(); QVERIFY(textEditObject != 0); - QCOMPARE(textEditObject->width(), qreal(metricWidth)); + QCOMPARE(textEditObject->width(), metricWidth); } for (int i = 0; i < richText.size(); i++) @@ -475,7 +475,7 @@ void tst_qquicktextedit::width() if (requiresUnhintedMetrics) document.setUseDesignMetrics(true); - int documentWidth = ceil(document.idealWidth()); + qreal documentWidth = document.idealWidth(); QString componentStr = "import QtQuick 2.0\nTextEdit { textFormat: TextEdit.RichText; text: \"" + richText.at(i) + "\" }"; QQmlComponent texteditComponent(&engine); @@ -483,7 +483,7 @@ void tst_qquicktextedit::width() QQuickTextEdit *textEditObject = qobject_cast<QQuickTextEdit*>(texteditComponent.create()); QVERIFY(textEditObject != 0); - QCOMPARE(textEditObject->width(), qreal(documentWidth)); + QCOMPARE(textEditObject->width(), documentWidth); } } @@ -903,10 +903,7 @@ void tst_qquicktextedit::color() QVERIFY(textEditObject); QVERIFY(textEditPrivate); QVERIFY(textEditPrivate->control); - - QPalette pal = textEditPrivate->control->palette(); QCOMPARE(textEditPrivate->color, QColor("black")); - QCOMPARE(textEditPrivate->color, pal.color(QPalette::Text)); } //test normal for (int i = 0; i < colorStrings.size(); i++) @@ -1846,8 +1843,8 @@ void tst_qquicktextedit::cursorDelegate() //Test Delegate gets moved for (int i=0; i<= textEditObject->text().length(); i++) { textEditObject->setCursorPosition(i); - QCOMPARE(textEditObject->cursorRectangle().x(), qRound(delegateObject->x())); - QCOMPARE(textEditObject->cursorRectangle().y(), qRound(delegateObject->y())); + QCOMPARE(textEditObject->cursorRectangle().x(), delegateObject->x()); + QCOMPARE(textEditObject->cursorRectangle().y(), delegateObject->y()); } // Clear preedit text; QInputMethodEvent event; @@ -1861,8 +1858,8 @@ void tst_qquicktextedit::cursorDelegate() QTest::mouseClick(&view, Qt::LeftButton, 0, point1); QTest::qWait(50); QTRY_VERIFY(textEditObject->cursorPosition() != 0); - QCOMPARE(textEditObject->cursorRectangle().x(), qRound(delegateObject->x())); - QCOMPARE(textEditObject->cursorRectangle().y(), qRound(delegateObject->y())); + QCOMPARE(textEditObject->cursorRectangle().x(), delegateObject->x()); + QCOMPARE(textEditObject->cursorRectangle().y(), delegateObject->y()); // Test delegate gets moved on mouse drag textEditObject->setCursorPosition(0); @@ -1872,27 +1869,27 @@ void tst_qquicktextedit::cursorDelegate() QGuiApplication::sendEvent(&view, &mv); QTest::mouseRelease(&view, Qt::LeftButton, 0, point2); QTest::qWait(50); - QTRY_COMPARE(textEditObject->cursorRectangle().x(), qRound(delegateObject->x())); - QCOMPARE(textEditObject->cursorRectangle().y(), qRound(delegateObject->y())); + QTRY_COMPARE(textEditObject->cursorRectangle().x(), delegateObject->x()); + QCOMPARE(textEditObject->cursorRectangle().y(), delegateObject->y()); textEditObject->setReadOnly(true); textEditObject->setCursorPosition(0); QTest::mouseClick(&view, Qt::LeftButton, 0, textEditObject->positionToRectangle(5).center().toPoint()); QTest::qWait(50); QTRY_VERIFY(textEditObject->cursorPosition() != 0); - QCOMPARE(textEditObject->cursorRectangle().x(), qRound(delegateObject->x())); - QCOMPARE(textEditObject->cursorRectangle().y(), qRound(delegateObject->y())); + QCOMPARE(textEditObject->cursorRectangle().x(), delegateObject->x()); + QCOMPARE(textEditObject->cursorRectangle().y(), delegateObject->y()); textEditObject->setCursorPosition(0); QTest::mouseClick(&view, Qt::LeftButton, 0, textEditObject->positionToRectangle(5).center().toPoint()); QTest::qWait(50); QTRY_VERIFY(textEditObject->cursorPosition() != 0); - QCOMPARE(textEditObject->cursorRectangle().x(), qRound(delegateObject->x())); - QCOMPARE(textEditObject->cursorRectangle().y(), qRound(delegateObject->y())); + QCOMPARE(textEditObject->cursorRectangle().x(), delegateObject->x()); + QCOMPARE(textEditObject->cursorRectangle().y(), delegateObject->y()); textEditObject->setCursorPosition(0); - QCOMPARE(textEditObject->cursorRectangle().x(), qRound(delegateObject->x())); - QCOMPARE(textEditObject->cursorRectangle().y(), qRound(delegateObject->y())); + QCOMPARE(textEditObject->cursorRectangle().x(), delegateObject->x()); + QCOMPARE(textEditObject->cursorRectangle().y(), delegateObject->y()); //Test Delegate gets deleted textEditObject->setCursorDelegate(0); QVERIFY(!textEditObject->findChild<QQuickItem*>("cursorInstance")); @@ -2585,14 +2582,14 @@ void tst_qquicktextedit::cursorRectangleSize() qApp->sendEvent(qApp->focusObject(), &event); QRectF cursorRectFromQuery = event.value(Qt::ImCursorRectangle).toRectF(); - QRect cursorRectFromItem = textEdit->cursorRectangle(); + QRectF cursorRectFromItem = textEdit->cursorRectangle(); QRectF cursorRectFromPositionToRectangle = textEdit->positionToRectangle(textEdit->cursorPosition()); // item and input query cursor rectangles match - QCOMPARE(cursorRectFromItem, cursorRectFromQuery.toRect()); + QCOMPARE(cursorRectFromItem, cursorRectFromQuery); // item cursor rectangle and positionToRectangle calculations match - QCOMPARE(cursorRectFromItem, cursorRectFromPositionToRectangle.toRect()); + QCOMPARE(cursorRectFromItem, cursorRectFromPositionToRectangle); // item-canvas transform and input item transform match QCOMPARE(QQuickItemPrivate::get(textEdit)->itemToCanvasTransform(), qApp->inputMethod()->inputItemTransform()); diff --git a/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp b/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp index 4141fea26f..bdd18d620e 100644 --- a/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp +++ b/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp @@ -2341,12 +2341,12 @@ void tst_qquicktextinput::cursorDelegate() //Test Delegate gets moved for (int i=0; i<= textInputObject->text().length(); i++) { textInputObject->setCursorPosition(i); - QCOMPARE(textInputObject->cursorRectangle().x(), qRound(delegateObject->x())); - QCOMPARE(textInputObject->cursorRectangle().y(), qRound(delegateObject->y())); + QCOMPARE(textInputObject->cursorRectangle().x(), delegateObject->x()); + QCOMPARE(textInputObject->cursorRectangle().y(), delegateObject->y()); } textInputObject->setCursorPosition(0); - QCOMPARE(textInputObject->cursorRectangle().x(), qRound(delegateObject->x())); - QCOMPARE(textInputObject->cursorRectangle().y(), qRound(delegateObject->y())); + QCOMPARE(textInputObject->cursorRectangle().x(), delegateObject->x()); + QCOMPARE(textInputObject->cursorRectangle().y(), delegateObject->y()); //Test Delegate gets deleted textInputObject->setCursorDelegate(0); QVERIFY(!textInputObject->findChild<QQuickItem*>("cursorInstance")); @@ -2404,9 +2404,6 @@ void tst_qquicktextinput::cursorVisible() QCOMPARE(spy.count(), 7); } -static QRect round(const QRectF &r) { - return QRect(qRound(r.left()), qRound(r.top()), qCeil(r.width()), qCeil(r.height())); } - void tst_qquicktextinput::cursorRectangle() { @@ -2430,7 +2427,7 @@ void tst_qquicktextinput::cursorRectangle() input.setWidth(line.cursorToX(5, QTextLine::Leading)); input.setHeight(qCeil(line.height() * 3 / 2)); - QRect r; + QRectF r; // some tolerance for different fonts. #ifdef Q_OS_LINUX @@ -2445,28 +2442,28 @@ void tst_qquicktextinput::cursorRectangle() QVERIFY(r.left() < qCeil(line.cursorToX(i, QTextLine::Trailing))); QVERIFY(r.right() >= qFloor(line.cursorToX(i , QTextLine::Leading))); - QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRect(), r); - QCOMPARE(round(input.positionToRectangle(i)), r); + QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRectF(), r); + QCOMPARE(input.positionToRectangle(i), r); } // Check the cursor rectangle remains within the input bounding rect when auto scrolling. - QVERIFY(r.left() < input.width()); + QVERIFY(r.left() < input.width() + error); QVERIFY(r.right() >= input.width() - error); for (int i = 6; i < text.length(); ++i) { input.setCursorPosition(i); QCOMPARE(r, input.cursorRectangle()); - QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRect(), r); - QCOMPARE(round(input.positionToRectangle(i)), r); + QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRectF(), r); + QCOMPARE(input.positionToRectangle(i), r); } for (int i = text.length() - 2; i >= 0; --i) { input.setCursorPosition(i); r = input.cursorRectangle(); - QCOMPARE(r.top(), 0); + QCOMPARE(r.top(), 0.); QVERIFY(r.right() >= 0); - QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRect(), r); - QCOMPARE(round(input.positionToRectangle(i)), r); + QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRectF(), r); + QCOMPARE(input.positionToRectangle(i), r); } // Check position with word wrap. @@ -2478,24 +2475,24 @@ void tst_qquicktextinput::cursorRectangle() QVERIFY(r.left() < qCeil(line.cursorToX(i, QTextLine::Trailing))); QVERIFY(r.right() >= qFloor(line.cursorToX(i , QTextLine::Leading))); - QCOMPARE(r.top(), 0); - QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRect(), r); - QCOMPARE(round(input.positionToRectangle(i)), r); + QCOMPARE(r.top(), 0.); + QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRectF(), r); + QCOMPARE(input.positionToRectangle(i), r); } input.setCursorPosition(6); r = input.cursorRectangle(); - QCOMPARE(r.left(), 0); + QCOMPARE(r.left(), 0.); QVERIFY(r.top() > line.height() - error); - QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRect(), r); - QCOMPARE(round(input.positionToRectangle(6)), r); + QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRectF(), r); + QCOMPARE(input.positionToRectangle(6), r); for (int i = 7; i < text.length(); ++i) { input.setCursorPosition(i); r = input.cursorRectangle(); QVERIFY(r.top() > line.height() - error); - QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRect(), r); - QCOMPARE(round(input.positionToRectangle(i)), r); + QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRectF(), r); + QCOMPARE(input.positionToRectangle(i), r); } // Check vertical scrolling with word wrap. @@ -2506,40 +2503,40 @@ void tst_qquicktextinput::cursorRectangle() QVERIFY(r.left() < qCeil(line.cursorToX(i, QTextLine::Trailing))); QVERIFY(r.right() >= qFloor(line.cursorToX(i , QTextLine::Leading))); - QCOMPARE(r.top(), 0); - QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRect(), r); - QCOMPARE(round(round(input.positionToRectangle(i))), r); + QCOMPARE(r.top(), 0.); + QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRectF(), r); + QCOMPARE(input.positionToRectangle(i), r); } input.setCursorPosition(6); r = input.cursorRectangle(); - QCOMPARE(r.left(), 0); + QCOMPARE(r.left(), 0.); QVERIFY(r.bottom() >= input.height() - error); - QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRect(), r); - QCOMPARE(round(input.positionToRectangle(6)), r); + QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRectF(), r); + QCOMPARE(input.positionToRectangle(6), r); for (int i = 7; i < text.length(); ++i) { input.setCursorPosition(i); r = input.cursorRectangle(); QVERIFY(r.bottom() >= input.height() - error); - QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRect(), r); - QCOMPARE(round(input.positionToRectangle(i)), r); + QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRectF(), r); + QCOMPARE(input.positionToRectangle(i), r); } for (int i = text.length() - 2; i >= 6; --i) { input.setCursorPosition(i); r = input.cursorRectangle(); QVERIFY(r.bottom() >= input.height() - error); - QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRect(), r); - QCOMPARE(round(input.positionToRectangle(i)), r); + QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRectF(), r); + QCOMPARE(input.positionToRectangle(i), r); } for (int i = 5; i >= 0; --i) { input.setCursorPosition(i); r = input.cursorRectangle(); - QCOMPARE(r.top(), 0); - QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRect(), r); - QCOMPARE(round(input.positionToRectangle(i)), r); + QCOMPARE(r.top(), 0.); + QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRectF(), r); + QCOMPARE(input.positionToRectangle(i), r); } input.setText("Hi!"); @@ -3228,14 +3225,14 @@ void tst_qquicktextinput::cursorRectangleSize() qApp->sendEvent(qApp->focusObject(), &event); QRectF cursorRectFromQuery = event.value(Qt::ImCursorRectangle).toRectF(); - QRect cursorRectFromItem = textInput->cursorRectangle(); + QRectF cursorRectFromItem = textInput->cursorRectangle(); QRectF cursorRectFromPositionToRectangle = textInput->positionToRectangle(textInput->cursorPosition()); // item and input query cursor rectangles match - QCOMPARE(cursorRectFromItem, cursorRectFromQuery.toRect()); + QCOMPARE(cursorRectFromItem, cursorRectFromQuery); // item cursor rectangle and positionToRectangle calculations match - QCOMPARE(cursorRectFromItem, cursorRectFromPositionToRectangle.toRect()); + QCOMPARE(cursorRectFromItem, cursorRectFromPositionToRectangle); // item-canvas transform and input item transform match QCOMPARE(QQuickItemPrivate::get(textInput)->itemToCanvasTransform(), qApp->inputMethod()->inputItemTransform()); diff --git a/tests/auto/quick/quick.pro b/tests/auto/quick/quick.pro index 6fba193790..4065dbf508 100644 --- a/tests/auto/quick/quick.pro +++ b/tests/auto/quick/quick.pro @@ -8,7 +8,7 @@ PUBLICTESTS += \ qquickpixmapcache # This test requires the qtconcurrent module -!contains(QT_CONFIG, concurrent):PUBLICTESTS -= qqmlpixmapcache +!contains(QT_CONFIG, concurrent):PUBLICTESTS -= qquickpixmapcache PRIVATETESTS += \ qquickanimations \ @@ -25,16 +25,21 @@ PRIVATETESTS += \ qquickxmllistmodel # This test requires the xmlpatterns module -!contains(QT_CONFIG,xmlpatterns):PRIVATETESTS -= qqmlxmllistmodel +!contains(QT_CONFIG,xmlpatterns):PRIVATETESTS -= qquickxmllistmodel + +# FIXME +# qquickdroparea is disabled because it depends on changes that +# have not been merged from qtbase/master to qtbase/api_changes yet: + #qquickdroparea \ QUICKTESTS = \ qquickaccessible \ qquickanchors \ qquickanimatedimage \ + qquickanimatedsprite \ qquickborderimage \ qquickcanvas \ qquickdrag \ - qquickdroparea \ qquickflickable \ qquickflipable \ qquickfocusscope \ @@ -52,7 +57,7 @@ QUICKTESTS = \ qquickpositioners \ qquickrepeater \ qquickshadereffect \ - qquickspriteimage \ + qquickspritesequence \ qquicktext \ qquicktextedit \ qquicktextinput \ diff --git a/tests/auto/quick/shared/viewtestutil.h b/tests/auto/quick/shared/viewtestutil.h index e940727789..6ab754cff6 100644 --- a/tests/auto/quick/shared/viewtestutil.h +++ b/tests/auto/quick/shared/viewtestutil.h @@ -174,6 +174,8 @@ namespace QQuickViewTestUtil }; } +Q_DECLARE_METATYPE(QQuickViewTestUtil::QaimModel*) +Q_DECLARE_METATYPE(QQuickViewTestUtil::ListChange) Q_DECLARE_METATYPE(QList<QQuickViewTestUtil::ListChange>) Q_DECLARE_METATYPE(QQuickViewTestUtil::ListRange) |