diff options
Diffstat (limited to 'tests')
114 files changed, 7999 insertions, 183 deletions
diff --git a/tests/arthur/common/paintcommands.cpp b/tests/arthur/common/paintcommands.cpp index 70d419e..c4f09a4 100644 --- a/tests/arthur/common/paintcommands.cpp +++ b/tests/arthur/common/paintcommands.cpp @@ -713,7 +713,7 @@ void PaintCommands::runCommands() QPainter pt(&pm); pt.fillRect(0, 0, 10, 10, QColor::fromRgba(0xffdfdfdf)); pt.fillRect(10, 10, 10, 10, QColor::fromRgba(0xffdfdfdf)); - + pt.end(); m_painter->drawTiledPixmap(0, 0, width, height, pm); } else { m_painter->fillRect(0, 0, width, height, Qt::white); diff --git a/tests/auto/declarative/qdeclarativebehaviors/data/qtbug12295.qml b/tests/auto/declarative/qdeclarativebehaviors/data/qtbug12295.qml index 804559c..d41add3 100644 --- a/tests/auto/declarative/qdeclarativebehaviors/data/qtbug12295.qml +++ b/tests/auto/declarative/qdeclarativebehaviors/data/qtbug12295.qml @@ -11,7 +11,7 @@ Rectangle { width: 100 height: 100 Behavior on x { - NumberAnimation {} + NumberAnimation { duration: 500 } } } } diff --git a/tests/auto/declarative/qdeclarativedom/tst_qdeclarativedom.cpp b/tests/auto/declarative/qdeclarativedom/tst_qdeclarativedom.cpp index 5028ba1..dca5205 100644 --- a/tests/auto/declarative/qdeclarativedom/tst_qdeclarativedom.cpp +++ b/tests/auto/declarative/qdeclarativedom/tst_qdeclarativedom.cpp @@ -480,7 +480,7 @@ void tst_qdeclarativedom::loadDynamicProperty() DP_TEST(0, a, QVariant::Int, 25, 14, "int"); DP_TEST(1, b, QVariant::Bool, 44, 15, "bool"); - DP_TEST(2, c, QVariant::Double, 64, 17, "double"); + DP_TEST(2, c, QMetaType::QReal, 64, 17, "double"); DP_TEST(3, d, QMetaType::QReal, 86, 15, "real"); DP_TEST(4, e, QVariant::String, 106, 17, "string"); DP_TEST(5, f, QVariant::Url, 128, 14, "url"); diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/deleteLater.qml b/tests/auto/declarative/qdeclarativeecmascript/data/deleteLater.qml new file mode 100644 index 0000000..6d23e5f7 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/deleteLater.qml @@ -0,0 +1,14 @@ +import Qt 4.7 + +QtObject { + id: root + property bool test: false + + Component.onCompleted: { + try { + root.deleteLater() + } catch(e) { + test = true; + } + } +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/in.qml b/tests/auto/declarative/qdeclarativeecmascript/data/in.qml new file mode 100644 index 0000000..0b5b0ba --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/in.qml @@ -0,0 +1,7 @@ +import Qt 4.7 + +Item { + id: root + property bool test1: "x" in root + property bool test2: !("foo" in root) +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/invokableObjectArg.qml b/tests/auto/declarative/qdeclarativeecmascript/data/invokableObjectArg.qml new file mode 100644 index 0000000..d5d3329 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/invokableObjectArg.qml @@ -0,0 +1,9 @@ +import Qt.test 1.0 +import Qt 4.7 + +MyQmlObject { + id: root + Component.onCompleted: { + root.myinvokable(root); + } +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/invokableObjectRet.qml b/tests/auto/declarative/qdeclarativeecmascript/data/invokableObjectRet.qml new file mode 100644 index 0000000..29d7d01 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/invokableObjectRet.qml @@ -0,0 +1,11 @@ +import Qt.test 1.0 +import Qt 4.7 + +MyQmlObject { + id: root + property bool test: false + Component.onCompleted: { + test = (root.returnme() == root) + } +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/nonscriptable.qml b/tests/auto/declarative/qdeclarativeecmascript/data/nonscriptable.qml new file mode 100644 index 0000000..024d82e --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/nonscriptable.qml @@ -0,0 +1,19 @@ +import Qt.test 1.0 +import Qt 4.7 + +MyQmlObject { + id: root + + property bool readOk: false; + property bool writeOk: false + + Component.onCompleted: { + readOk = (root.nonscriptable == undefined); + + try { + root.nonscriptable = 10 + } catch (e) { + writeOk = true; + } + } +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/testtypes.h b/tests/auto/declarative/qdeclarativeecmascript/testtypes.h index 37d6dbd..220318d 100644 --- a/tests/auto/declarative/qdeclarativeecmascript/testtypes.h +++ b/tests/auto/declarative/qdeclarativeecmascript/testtypes.h @@ -92,9 +92,10 @@ class MyQmlObject : public QObject Q_PROPERTY(QDeclarativeListProperty<QObject> objectListProperty READ objectListProperty CONSTANT) Q_PROPERTY(int resettableProperty READ resettableProperty WRITE setResettableProperty RESET resetProperty) Q_PROPERTY(QRegExp regExp READ regExp WRITE setRegExp) + Q_PROPERTY(int nonscriptable READ nonscriptable WRITE setNonscriptable SCRIPTABLE false); public: - MyQmlObject(): m_methodCalled(false), m_methodIntCalled(false), m_object(0), m_value(0), m_resetProperty(13) {} + MyQmlObject(): myinvokableObject(0), m_methodCalled(false), m_methodIntCalled(false), m_object(0), m_value(0), m_resetProperty(13) {} enum MyEnum { EnumValue1 = 0, EnumValue2 = 1 }; enum MyEnum2 { EnumValue3 = 2, EnumValue4 = 3 }; @@ -144,6 +145,13 @@ public: void setRegExp(const QRegExp ®Exp) { m_regExp = regExp; } int console() const { return 11; } + + int nonscriptable() const { return 0; } + void setNonscriptable(int) {} + + MyQmlObject *myinvokableObject; + Q_INVOKABLE MyQmlObject *returnme() { return this; } + signals: void basicSignal(); void argumentSignal(int a, QString b, qreal c); @@ -157,6 +165,7 @@ public slots: void methodNoArgs() { m_methodCalled = true; } void method(int a) { if(a == 163) m_methodIntCalled = true; } void setString(const QString &s) { m_string = s; } + void myinvokable(MyQmlObject *o) { myinvokableObject = o; } private: friend class tst_qdeclarativeecmascript; diff --git a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp index a6d2dac..33bf7ea 100644 --- a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp +++ b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp @@ -157,10 +157,15 @@ private slots: void qtbug_10696(); void qtbug_11606(); void qtbug_11600(); + void nonscriptable(); + void deleteLater(); + void in(); void include(); void callQtInvokables(); + void invokableObjectArg(); + void invokableObjectRet(); private: QDeclarativeEngine engine; }; @@ -1730,6 +1735,31 @@ void tst_qdeclarativeecmascript::callQtInvokables() QCOMPARE(o.actuals().at(0), QVariant(9)); } +// QTBUG-13047 (check that you can pass registered object types as args) +void tst_qdeclarativeecmascript::invokableObjectArg() +{ + QDeclarativeComponent component(&engine, TEST_FILE("invokableObjectArg.qml")); + + QObject *o = component.create(); + QVERIFY(o); + MyQmlObject *qmlobject = qobject_cast<MyQmlObject *>(o); + QVERIFY(qmlobject); + QCOMPARE(qmlobject->myinvokableObject, qmlobject); + + delete o; +} + +// QTBUG-13047 (check that you can return registered object types from methods) +void tst_qdeclarativeecmascript::invokableObjectRet() +{ + QDeclarativeComponent component(&engine, TEST_FILE("invokableObjectRet.qml")); + + QObject *o = component.create(); + QVERIFY(o); + QCOMPARE(o->property("test").toBool(), true); + delete o; +} + // QTBUG-5675 void tst_qdeclarativeecmascript::listToVariant() { @@ -2530,6 +2560,36 @@ void tst_qdeclarativeecmascript::qtbug_11600() delete o; } +// Reading and writing non-scriptable properties should fail +void tst_qdeclarativeecmascript::nonscriptable() +{ + QDeclarativeComponent component(&engine, TEST_FILE("nonscriptable.qml")); + QObject *o = component.create(); + QVERIFY(o != 0); + QCOMPARE(o->property("readOk").toBool(), true); + QCOMPARE(o->property("writeOk").toBool(), true); + delete o; +} + +// deleteLater() should not be callable from QML +void tst_qdeclarativeecmascript::deleteLater() +{ + QDeclarativeComponent component(&engine, TEST_FILE("deleteLater.qml")); + QObject *o = component.create(); + QVERIFY(o != 0); + QCOMPARE(o->property("test").toBool(), true); + delete o; +} + +void tst_qdeclarativeecmascript::in() +{ + QDeclarativeComponent component(&engine, TEST_FILE("in.qml")); + QObject *o = component.create(); + QVERIFY(o != 0); + QCOMPARE(o->property("test1").toBool(), true); + QCOMPARE(o->property("test2").toBool(), true); + delete o; +} QTEST_MAIN(tst_qdeclarativeecmascript) diff --git a/tests/auto/declarative/qdeclarativegridview/tst_qdeclarativegridview.cpp b/tests/auto/declarative/qdeclarativegridview/tst_qdeclarativegridview.cpp index 1a28b71..d4d8bf6 100644 --- a/tests/auto/declarative/qdeclarativegridview/tst_qdeclarativegridview.cpp +++ b/tests/auto/declarative/qdeclarativegridview/tst_qdeclarativegridview.cpp @@ -590,7 +590,7 @@ void tst_QDeclarativeGridView::currentIndex() QCOMPARE(gridview->currentIndex(), 35); QCOMPARE(gridview->currentItem(), findItem<QDeclarativeItem>(contentItem, "wrapper", 35)); QCOMPARE(gridview->currentItem()->y(), gridview->highlightItem()->y()); - QCOMPARE(gridview->contentY(), 399.0); + QCOMPARE(gridview->contentY(), 400.0); gridview->moveCurrentIndexRight(); QCOMPARE(gridview->currentIndex(), 36); @@ -629,7 +629,7 @@ void tst_QDeclarativeGridView::currentIndex() gridview->moveCurrentIndexLeft(); QCOMPARE(gridview->currentIndex(), model.count()-1); - QTRY_COMPARE(gridview->contentY(), 879.0); + QTRY_COMPARE(gridview->contentY(), 880.0); gridview->moveCurrentIndexRight(); QCOMPARE(gridview->currentIndex(), 0); @@ -655,6 +655,15 @@ void tst_QDeclarativeGridView::currentIndex() gridview->setFlow(QDeclarativeGridView::TopToBottom); + qApp->setActiveWindow(canvas); +#ifdef Q_WS_X11 + // to be safe and avoid failing setFocus with window managers + qt_x11_wait_for_window_manager(canvas); +#endif + QTRY_VERIFY(canvas->hasFocus()); + QTRY_VERIFY(canvas->scene()->hasFocus()); + qApp->processEvents(); + QTest::keyClick(canvas, Qt::Key_Right); QCOMPARE(gridview->currentIndex(), 5); diff --git a/tests/auto/declarative/qdeclarativeimage/tst_qdeclarativeimage.cpp b/tests/auto/declarative/qdeclarativeimage/tst_qdeclarativeimage.cpp index 8cfb487..2686127 100644 --- a/tests/auto/declarative/qdeclarativeimage/tst_qdeclarativeimage.cpp +++ b/tests/auto/declarative/qdeclarativeimage/tst_qdeclarativeimage.cpp @@ -52,7 +52,9 @@ #include <private/qdeclarativeloader_p.h> #include <QtDeclarative/qdeclarativecontext.h> #include <QtDeclarative/qdeclarativeexpression.h> +#include <QtTest/QSignalSpy> +#include "../../../shared/util.h" #include "../shared/testhttpserver.h" #ifdef Q_OS_SYMBIAN @@ -63,18 +65,7 @@ #define SERVER_PORT 14451 #define SERVER_ADDR "http://127.0.0.1:14451" -#define TRY_WAIT(expr) \ - do { \ - for (int ii = 0; ii < 60; ++ii) { \ - if ((expr)) break; \ - QTest::qWait(50); \ - } \ - QVERIFY((expr)); \ - } while (false) - - class tst_qdeclarativeimage : public QObject - { Q_OBJECT public: @@ -91,6 +82,7 @@ private slots: void svg(); void big(); void tiling_QTBUG_6716(); + void noLoading(); private: template<typename T> @@ -173,18 +165,18 @@ void tst_qdeclarativeimage::imageSource() QVERIFY(obj->asynchronous() == true); if (remote || async) - TRY_WAIT(obj->status() == QDeclarativeImage::Loading); + QTRY_VERIFY(obj->status() == QDeclarativeImage::Loading); QCOMPARE(obj->source(), remote ? source : QUrl(source)); if (error.isEmpty()) { - TRY_WAIT(obj->status() == QDeclarativeImage::Ready); + QTRY_VERIFY(obj->status() == QDeclarativeImage::Ready); QCOMPARE(obj->width(), qreal(width)); QCOMPARE(obj->height(), qreal(height)); QCOMPARE(obj->fillMode(), QDeclarativeImage::Stretch); QCOMPARE(obj->progress(), 1.0); } else { - TRY_WAIT(obj->status() == QDeclarativeImage::Error); + QTRY_VERIFY(obj->status() == QDeclarativeImage::Error); } delete obj; @@ -355,6 +347,54 @@ void tst_qdeclarativeimage::tiling_QTBUG_6716() } } +void tst_qdeclarativeimage::noLoading() +{ + TestHTTPServer server(SERVER_PORT); + QVERIFY(server.isValid()); + server.serveDirectory(SRCDIR "/data"); + server.addRedirect("oldcolors.png", SERVER_ADDR "/colors.png"); + + QString componentStr = "import Qt 4.7\nImage { source: srcImage }"; + QDeclarativeContext *ctxt = engine.rootContext(); + ctxt->setContextProperty("srcImage", QUrl::fromLocalFile(SRCDIR "/data/heart.png")); + QDeclarativeComponent component(&engine); + component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QDeclarativeImage *obj = qobject_cast<QDeclarativeImage*>(component.create()); + QVERIFY(obj != 0); + QVERIFY(obj->status() == QDeclarativeImage::Ready); + + QSignalSpy sourceSpy(obj, SIGNAL(sourceChanged(const QUrl &))); + QSignalSpy progressSpy(obj, SIGNAL(progressChanged(qreal))); + QSignalSpy statusSpy(obj, SIGNAL(statusChanged(QDeclarativeImageBase::Status))); + + // Loading local file + ctxt->setContextProperty("srcImage", QUrl::fromLocalFile(SRCDIR "/data/colors.png")); + QTRY_VERIFY(obj->status() == QDeclarativeImage::Ready); + QTRY_VERIFY(obj->progress() == 1.0); + QTRY_COMPARE(sourceSpy.count(), 1); + QTRY_COMPARE(progressSpy.count(), 0); + QTRY_COMPARE(statusSpy.count(), 0); + + // Loading remote file + ctxt->setContextProperty("srcImage", QString(SERVER_ADDR) + "/oldcolors.png"); + QTRY_VERIFY(obj->status() == QDeclarativeImage::Loading); + QTRY_VERIFY(obj->progress() == 0.0); + QTRY_VERIFY(obj->status() == QDeclarativeImage::Ready); + QTRY_VERIFY(obj->progress() == 1.0); + QTRY_COMPARE(sourceSpy.count(), 2); + QTRY_COMPARE(progressSpy.count(), 2); + QTRY_COMPARE(statusSpy.count(), 2); + + // Loading remote file again - should not go through 'Loading' state. + ctxt->setContextProperty("srcImage", QUrl::fromLocalFile(SRCDIR "/data/colors.png")); + ctxt->setContextProperty("srcImage", QString(SERVER_ADDR) + "/oldcolors.png"); + QTRY_VERIFY(obj->status() == QDeclarativeImage::Ready); + QTRY_VERIFY(obj->progress() == 1.0); + QTRY_COMPARE(sourceSpy.count(), 4); + QTRY_COMPARE(progressSpy.count(), 2); + QTRY_COMPARE(statusSpy.count(), 2); +} + /* Find an item with the specified objectName. If index is supplied then the item must also evaluate the {index} expression equal to index diff --git a/tests/auto/declarative/qdeclarativeimageprovider/qdeclarativeimageprovider.pro b/tests/auto/declarative/qdeclarativeimageprovider/qdeclarativeimageprovider.pro index bdb6423..3bf0ea1 100644 --- a/tests/auto/declarative/qdeclarativeimageprovider/qdeclarativeimageprovider.pro +++ b/tests/auto/declarative/qdeclarativeimageprovider/qdeclarativeimageprovider.pro @@ -8,11 +8,7 @@ SOURCES += tst_qdeclarativeimageprovider.cpp # QMAKE_CXXFLAGS = -fprofile-arcs -ftest-coverage # LIBS += -lgcov -symbian: { - importFiles.sources = data - importFiles.path = . - DEPLOYMENT = importFiles -} else { +!symbian: { DEFINES += SRCDIR=\\\"$$PWD\\\" } diff --git a/tests/auto/declarative/qdeclarativeimageprovider/tst_qdeclarativeimageprovider.cpp b/tests/auto/declarative/qdeclarativeimageprovider/tst_qdeclarativeimageprovider.cpp index 6d5a357..d0afc8a 100644 --- a/tests/auto/declarative/qdeclarativeimageprovider/tst_qdeclarativeimageprovider.cpp +++ b/tests/auto/declarative/qdeclarativeimageprovider/tst_qdeclarativeimageprovider.cpp @@ -389,6 +389,7 @@ void tst_qdeclarativeimageprovider::threadTest() } provider->ok = true; provider->cond.wakeAll(); + QTest::qWait(250); foreach(QDeclarativeImage *img, images) { TRY_WAIT(img->status() == QDeclarativeImage::Ready); } diff --git a/tests/auto/declarative/qdeclarativelanguage/data/DontDoubleCallClassBeginItem.qml b/tests/auto/declarative/qdeclarativelanguage/data/DontDoubleCallClassBeginItem.qml new file mode 100644 index 0000000..1f8eac8 --- /dev/null +++ b/tests/auto/declarative/qdeclarativelanguage/data/DontDoubleCallClassBeginItem.qml @@ -0,0 +1,4 @@ +import Test 1.0 + +MyParserStatus { +} diff --git a/tests/auto/declarative/qdeclarativelanguage/data/aliasPropertiesAndSignals.qml b/tests/auto/declarative/qdeclarativelanguage/data/aliasPropertiesAndSignals.qml new file mode 100644 index 0000000..59afe58 --- /dev/null +++ b/tests/auto/declarative/qdeclarativelanguage/data/aliasPropertiesAndSignals.qml @@ -0,0 +1,14 @@ +import Qt 4.7 + +QtObject { + id: root + + property bool test: false + property alias myalias: root.objectName + signal go + onGo: test = true + + Component.onCompleted: { + root.go(); + } +} diff --git a/tests/auto/declarative/qdeclarativelanguage/data/dontDoubleCallClassBegin.qml b/tests/auto/declarative/qdeclarativelanguage/data/dontDoubleCallClassBegin.qml new file mode 100644 index 0000000..df048cc --- /dev/null +++ b/tests/auto/declarative/qdeclarativelanguage/data/dontDoubleCallClassBegin.qml @@ -0,0 +1,5 @@ +import Qt 4.7 + +Item { + property QtObject object: DontDoubleCallClassBeginItem {} +} diff --git a/tests/auto/declarative/qdeclarativelanguage/data/invalidAlias.7.errors.txt b/tests/auto/declarative/qdeclarativelanguage/data/invalidAlias.7.errors.txt new file mode 100644 index 0000000..93652a7 --- /dev/null +++ b/tests/auto/declarative/qdeclarativelanguage/data/invalidAlias.7.errors.txt @@ -0,0 +1 @@ +5:23:Invalid alias location diff --git a/tests/auto/declarative/qdeclarativelanguage/data/invalidAlias.7.qml b/tests/auto/declarative/qdeclarativelanguage/data/invalidAlias.7.qml new file mode 100644 index 0000000..2a09648 --- /dev/null +++ b/tests/auto/declarative/qdeclarativelanguage/data/invalidAlias.7.qml @@ -0,0 +1,6 @@ +import Test 1.0 + +MyTypeObject { + id: root + property alias a: root.nonScriptable +} diff --git a/tests/auto/declarative/qdeclarativelanguage/data/nestedErrors.errors.txt b/tests/auto/declarative/qdeclarativelanguage/data/nestedErrors.errors.txt index 6e11786..53e752b 100644 --- a/tests/auto/declarative/qdeclarativelanguage/data/nestedErrors.errors.txt +++ b/tests/auto/declarative/qdeclarativelanguage/data/nestedErrors.errors.txt @@ -1,2 +1,2 @@ -4:5:Unable to create type NestedErrorsType +4:5:Type NestedErrorsType unavailable 4:8:Invalid property assignment: number expected diff --git a/tests/auto/declarative/qdeclarativelanguage/data/nonScriptableProperty.errors.txt b/tests/auto/declarative/qdeclarativelanguage/data/nonScriptableProperty.errors.txt new file mode 100644 index 0000000..cdfa4b2 --- /dev/null +++ b/tests/auto/declarative/qdeclarativelanguage/data/nonScriptableProperty.errors.txt @@ -0,0 +1 @@ +4:5:Cannot assign to non-existent property "nonScriptable" diff --git a/tests/auto/declarative/qdeclarativelanguage/data/nonScriptableProperty.qml b/tests/auto/declarative/qdeclarativelanguage/data/nonScriptableProperty.qml new file mode 100644 index 0000000..bd59bc8 --- /dev/null +++ b/tests/auto/declarative/qdeclarativelanguage/data/nonScriptableProperty.qml @@ -0,0 +1,5 @@ +import Test 1.0 + +MyQmlObject { + nonScriptable: 11 +} diff --git a/tests/auto/declarative/qdeclarativelanguage/data/variantNotify.qml b/tests/auto/declarative/qdeclarativelanguage/data/variantNotify.qml new file mode 100644 index 0000000..e7aaf16 --- /dev/null +++ b/tests/auto/declarative/qdeclarativelanguage/data/variantNotify.qml @@ -0,0 +1,13 @@ +import Qt 4.7 + +QtObject { + property int notifyCount: 0 + + property variant foo + onFooChanged: notifyCount++ + + Component.onCompleted: { + foo = 1; + foo = 1; + } +} diff --git a/tests/auto/declarative/qdeclarativelanguage/testtypes.cpp b/tests/auto/declarative/qdeclarativelanguage/testtypes.cpp index 5d87404..20cd976 100644 --- a/tests/auto/declarative/qdeclarativelanguage/testtypes.cpp +++ b/tests/auto/declarative/qdeclarativelanguage/testtypes.cpp @@ -50,6 +50,7 @@ void registerTypes() qmlRegisterType<MyDotPropertyObject>("Test",1,0,"MyDotPropertyObject"); qmlRegisterType<MyNamespace::MyNamespacedType>("Test",1,0,"MyNamespacedType"); qmlRegisterType<MyNamespace::MySecondNamespacedType>("Test",1,0,"MySecondNamespacedType"); + qmlRegisterType<MyParserStatus>("Test",1,0,"MyParserStatus"); qmlRegisterType<MyGroupedObject>(); qmlRegisterCustomType<MyCustomParserType>("Test", 1, 0, "MyCustomParserType", new MyCustomParserTypeParser); diff --git a/tests/auto/declarative/qdeclarativelanguage/testtypes.h b/tests/auto/declarative/qdeclarativelanguage/testtypes.h index acbe219..ac55bae 100644 --- a/tests/auto/declarative/qdeclarativelanguage/testtypes.h +++ b/tests/auto/declarative/qdeclarativelanguage/testtypes.h @@ -112,6 +112,7 @@ class MyQmlObject : public QObject, public MyInterface Q_PROPERTY(MyCustomVariantType customType READ customType WRITE setCustomType) Q_PROPERTY(MyQmlObject *qmlobjectProperty READ qmlobject WRITE setQmlobject) Q_PROPERTY(int propertyWithNotify READ propertyWithNotify WRITE setPropertyWithNotify NOTIFY oddlyNamedNotifySignal) + Q_PROPERTY(int nonScriptable READ nonScriptable WRITE setNonScriptable SCRIPTABLE false); Q_INTERFACES(MyInterface) public: @@ -150,6 +151,9 @@ public: int propertyWithNotify() const { return m_propertyWithNotify; } void setPropertyWithNotify(int i) { m_propertyWithNotify = i; emit oddlyNamedNotifySignal(); } + + int nonScriptable() const { return 0; } + void setNonScriptable(int) {} public slots: void basicSlot() { qWarning("MyQmlObject::basicSlot"); } void basicSlotWithArgs(int v) { qWarning("MyQmlObject::basicSlotWithArgs(%d)", v); } @@ -170,7 +174,6 @@ private: QML_DECLARE_TYPE(MyQmlObject) QML_DECLARE_TYPEINFO(MyQmlObject, QML_HAS_ATTACHED_PROPERTIES) - class MyGroupedObject : public QObject { Q_OBJECT @@ -576,6 +579,22 @@ public: void setCustomData(QObject *, const QByteArray &) {} }; +class MyParserStatus : public QObject, public QDeclarativeParserStatus +{ + Q_OBJECT +public: + MyParserStatus() : m_cbc(0), m_ccc(0) {} + + int classBeginCount() const { return m_cbc; } + int componentCompleteCount() const { return m_ccc; } + + virtual void classBegin() { m_cbc++; } + virtual void componentComplete() { m_ccc++; } +private: + int m_cbc; + int m_ccc; +}; + void registerTypes(); #endif // TESTTYPES_H diff --git a/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp b/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp index fcdf926..1825991 100644 --- a/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp +++ b/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp @@ -118,6 +118,7 @@ private slots: void valueTypes(); void cppnamespace(); void aliasProperties(); + void aliasPropertiesAndSignals(); void componentCompositeType(); void i18n(); void i18n_data(); @@ -126,6 +127,7 @@ private slots: void scriptString(); void defaultPropertyListOrder(); void declaredPropertyValues(); + void dontDoubleCallClassBegin(); void basicRemote_data(); void basicRemote(); @@ -141,8 +143,8 @@ private slots: void importsOrder(); void qmlAttachedPropertiesObjectMethod(); - void customOnProperty(); + void variantNotify(); // regression tests for crashes void crash1(); @@ -342,6 +344,7 @@ void tst_qdeclarativelanguage::errors_data() QTest::newRow("invalidAlias.4") << "invalidAlias.4.qml" << "invalidAlias.4.errors.txt" << false; QTest::newRow("invalidAlias.5") << "invalidAlias.5.qml" << "invalidAlias.5.errors.txt" << false; QTest::newRow("invalidAlias.6") << "invalidAlias.6.qml" << "invalidAlias.6.errors.txt" << false; + QTest::newRow("invalidAlias.7") << "invalidAlias.7.qml" << "invalidAlias.7.errors.txt" << false; QTest::newRow("invalidAttachedProperty.1") << "invalidAttachedProperty.1.qml" << "invalidAttachedProperty.1.errors.txt" << false; QTest::newRow("invalidAttachedProperty.2") << "invalidAttachedProperty.2.qml" << "invalidAttachedProperty.2.errors.txt" << false; @@ -372,6 +375,7 @@ void tst_qdeclarativelanguage::errors_data() QTest::newRow("assignToNamespace") << "assignToNamespace.qml" << "assignToNamespace.errors.txt" << false; QTest::newRow("invalidOn") << "invalidOn.qml" << "invalidOn.errors.txt" << false; QTest::newRow("invalidProperty") << "invalidProperty.qml" << "invalidProperty.errors.txt" << false; + QTest::newRow("nonScriptableProperty") << "nonScriptableProperty.qml" << "nonScriptableProperty.errors.txt" << false; } @@ -1048,6 +1052,17 @@ void tst_qdeclarativelanguage::aliasProperties() } } +// QTBUG-13374 Test that alias properties and signals can coexist +void tst_qdeclarativelanguage::aliasPropertiesAndSignals() +{ + QDeclarativeComponent component(&engine, TEST_FILE("aliasPropertiesAndSignals.qml")); + VERIFY_ERRORS(0); + QObject *o = component.create(); + QVERIFY(o); + QCOMPARE(o->property("test").toBool(), true); + delete o; +} + // Test that the root element in a composite type can be a Component void tst_qdeclarativelanguage::componentCompositeType() { @@ -1192,6 +1207,20 @@ void tst_qdeclarativelanguage::declaredPropertyValues() VERIFY_ERRORS(0); } +void tst_qdeclarativelanguage::dontDoubleCallClassBegin() +{ + QDeclarativeComponent component(&engine, TEST_FILE("dontDoubleCallClassBegin.qml")); + QObject *o = component.create(); + QVERIFY(o); + + MyParserStatus *o2 = qobject_cast<MyParserStatus *>(qvariant_cast<QObject *>(o->property("object"))); + QVERIFY(o2); + QCOMPARE(o2->classBeginCount(), 1); + QCOMPARE(o2->componentCompleteCount(), 1); + + delete o; +} + // Check that first child of qml is of given type. Empty type insists on error. void tst_qdeclarativelanguage::testType(const QString& qml, const QString& type, const QString& expectederror) { @@ -1668,6 +1697,20 @@ void tst_qdeclarativelanguage::customOnProperty() delete object; } +// QTBUG-12601 +void tst_qdeclarativelanguage::variantNotify() +{ + QDeclarativeComponent component(&engine, TEST_FILE("variantNotify.qml")); + + VERIFY_ERRORS(0); + QObject *object = component.create(); + QVERIFY(object != 0); + + QCOMPARE(object->property("notifyCount").toInt(), 1); + + delete object; +} + void tst_qdeclarativelanguage::initTestCase() { registerTypes(); diff --git a/tests/auto/declarative/qdeclarativelistview/data/itemlist.qml b/tests/auto/declarative/qdeclarativelistview/data/itemlist.qml index 66728d6..9ea5953 100644 --- a/tests/auto/declarative/qdeclarativelistview/data/itemlist.qml +++ b/tests/auto/declarative/qdeclarativelistview/data/itemlist.qml @@ -13,17 +13,17 @@ Rectangle { objectName: "itemModel" Rectangle { objectName: "item1" - height: view.height; width: view.width; color: "#FFFEF0" + height: ListView.view.height; width: view.width; color: "#FFFEF0" Text { objectName: "text1"; text: "index: " + parent.VisualItemModel.index; font.bold: true; anchors.centerIn: parent } } Rectangle { objectName: "item2" - height: view.height; width: view.width; color: "#F0FFF7" + height: ListView.view.height; width: view.width; color: "#F0FFF7" Text { objectName: "text2"; text: "index: " + parent.VisualItemModel.index; font.bold: true; anchors.centerIn: parent } } Rectangle { objectName: "item3" - height: view.height; width: view.width; color: "#F4F0FF" + height: ListView.view.height; width: view.width; color: "#F4F0FF" Text { objectName: "text3"; text: "index: " + parent.VisualItemModel.index; font.bold: true; anchors.centerIn: parent } } } diff --git a/tests/auto/declarative/qdeclarativelistview/data/listviewtest.qml b/tests/auto/declarative/qdeclarativelistview/data/listviewtest.qml index 3b2db5e..d5d3365 100644 --- a/tests/auto/declarative/qdeclarativelistview/data/listviewtest.qml +++ b/tests/auto/declarative/qdeclarativelistview/data/listviewtest.qml @@ -4,6 +4,12 @@ Rectangle { width: 240 height: 320 color: "#ffffff" + + property real hr: list.visibleArea.heightRatio + function heightRatio() { + return list.visibleArea.heightRatio + } + function checkProperties() { testObject.error = false; if (list.model != testModel) { diff --git a/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp b/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp index 9c24e03..e4b59a7 100644 --- a/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp +++ b/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp @@ -98,6 +98,7 @@ private slots: void manualHighlight(); void QTBUG_11105(); void footer(); + void resizeView(); private: template <class T> void items(); @@ -223,6 +224,13 @@ public: emit itemsRemoved(index, 1); } + void removeItems(int index, int count) { + int c = count; + while (c--) + list.removeAt(index); + emit itemsRemoved(index, count); + } + void moveItem(int from, int to) { list.move(from, to); emit itemsMoved(from, to, 1); @@ -289,6 +297,13 @@ public: emit endRemoveRows(); } + void removeItems(int index, int count) { + emit beginRemoveRows(QModelIndex(), index, index+count-1); + while (count--) + list.removeAt(index); + emit endRemoveRows(); + } + void moveItem(int from, int to) { emit beginMoveRows(QModelIndex(), from, from, QModelIndex(), to); list.move(from, to); @@ -519,7 +534,7 @@ void tst_QDeclarativeListView::removed(bool animated) QDeclarativeView *canvas = createView(); T model; - for (int i = 0; i < 30; i++) + for (int i = 0; i < 50; i++) model.addItem("Item" + QString::number(i), ""); QDeclarativeContext *ctxt = canvas->rootContext(); @@ -642,6 +657,21 @@ void tst_QDeclarativeListView::removed(bool animated) QTRY_COMPARE(listview->currentIndex(), 7); QTRY_VERIFY(listview->currentItem() == oldCurrent); + listview->setContentY(80); + QTest::qWait(300); + + model.removeItems(1, 17); + QTest::qWait(300); + + // Confirm items positioned correctly + itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count(); + for (int i = 0; i < model.count() && i < itemCount-1; ++i) { + QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i+2); + if (!item) qWarning() << "Item" << i+2 << "not found"; + QTRY_VERIFY(item); + QTRY_COMPARE(item->y(),80+i*20.0); + } + delete canvas; } @@ -979,7 +1009,7 @@ void tst_QDeclarativeListView::currentIndex() // current item should be 20th item at startup // and current item should be in view QCOMPARE(listview->currentIndex(), 20); - QCOMPARE(listview->contentY(), 99.0); + QCOMPARE(listview->contentY(), 100.0); QCOMPARE(listview->currentItem(), findItem<QDeclarativeItem>(contentItem, "wrapper", 20)); QCOMPARE(listview->highlightItem()->y(), listview->currentItem()->y()); @@ -1002,7 +1032,7 @@ void tst_QDeclarativeListView::currentIndex() listview->decrementCurrentIndex(); QCOMPARE(listview->currentIndex(), model.count()-1); - QTRY_COMPARE(listview->contentY(), 279.0); + QTRY_COMPARE(listview->contentY(), 280.0); listview->incrementCurrentIndex(); QCOMPARE(listview->currentIndex(), 0); @@ -1066,6 +1096,7 @@ void tst_QDeclarativeListView::itemList() QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "item1"); QTRY_VERIFY(item); QTRY_COMPARE(item->x(), 0.0); + QCOMPARE(item->height(), listview->height()); QDeclarativeText *text = findItem<QDeclarativeText>(contentItem, "text1"); QTRY_VERIFY(text); @@ -1590,6 +1621,48 @@ void tst_QDeclarativeListView::footer() QTRY_COMPARE(footer->y(), 0.0); } +void tst_QDeclarativeListView::resizeView() +{ + QDeclarativeView *canvas = createView(); + + TestModel model; + for (int i = 0; i < 40; i++) + model.addItem("Item" + QString::number(i), ""); + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + + TestObject *testObject = new TestObject; + ctxt->setContextProperty("testObject", testObject); + + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listviewtest.qml")); + qApp->processEvents(); + + QDeclarativeListView *listview = findItem<QDeclarativeListView>(canvas->rootObject(), "list"); + QTRY_VERIFY(listview != 0); + + QDeclarativeItem *contentItem = listview->contentItem(); + QTRY_VERIFY(contentItem != 0); + + // Confirm items positioned correctly + int itemCount = findItems<QDeclarativeItem>(contentItem, "wrapper").count(); + for (int i = 0; i < model.count() && i < itemCount; ++i) { + QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i); + if (!item) qWarning() << "Item" << i << "not found"; + QTRY_VERIFY(item); + QTRY_COMPARE(item->y(), i*20.); + } + + QVariant heightRatio; + QMetaObject::invokeMethod(canvas->rootObject(), "heightRatio", Q_RETURN_ARG(QVariant, heightRatio)); + QCOMPARE(heightRatio.toReal(), 0.4); + + listview->setHeight(200); + + QMetaObject::invokeMethod(canvas->rootObject(), "heightRatio", Q_RETURN_ARG(QVariant, heightRatio)); + QCOMPARE(heightRatio.toReal(), 0.25); +} + void tst_QDeclarativeListView::qListModelInterface_items() { items<TestModel>(); diff --git a/tests/auto/declarative/qdeclarativeloader/tst_qdeclarativeloader.cpp b/tests/auto/declarative/qdeclarativeloader/tst_qdeclarativeloader.cpp index b0b7a3b..3baf848 100644 --- a/tests/auto/declarative/qdeclarativeloader/tst_qdeclarativeloader.cpp +++ b/tests/auto/declarative/qdeclarativeloader/tst_qdeclarativeloader.cpp @@ -146,7 +146,7 @@ void tst_QDeclarativeLoader::component() void tst_QDeclarativeLoader::invalidUrl() { - QTest::ignoreMessage(QtWarningMsg, QString("<Unknown File>: File error for URL " + QUrl::fromLocalFile(SRCDIR "/data/IDontExist.qml").toString()).toUtf8().constData()); + QTest::ignoreMessage(QtWarningMsg, QString(QUrl::fromLocalFile(SRCDIR "/data/IDontExist.qml").toString() + ": File not found").toUtf8().constData()); QDeclarativeComponent component(&engine); component.setData(QByteArray("import Qt 4.7\nLoader { source: \"IDontExist.qml\" }"), TEST_FILE("")); @@ -508,7 +508,7 @@ void tst_QDeclarativeLoader::failNetworkRequest() QVERIFY(server.isValid()); server.serveDirectory(SRCDIR "/data"); - QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: Network error for URL http://127.0.0.1:14450/IDontExist.qml"); + QTest::ignoreMessage(QtWarningMsg, "http://127.0.0.1:14450/IDontExist.qml: File not found"); QDeclarativeComponent component(&engine); component.setData(QByteArray("import Qt 4.7\nLoader { property int did_load: 123; source: \"http://127.0.0.1:14450/IDontExist.qml\"; onLoaded: did_load=456 }"), QUrl::fromLocalFile("http://127.0.0.1:14450/dummy.qml")); diff --git a/tests/auto/declarative/qdeclarativepathview/tst_qdeclarativepathview.cpp b/tests/auto/declarative/qdeclarativepathview/tst_qdeclarativepathview.cpp index e2ccfd2..74d2f0a 100644 --- a/tests/auto/declarative/qdeclarativepathview/tst_qdeclarativepathview.cpp +++ b/tests/auto/declarative/qdeclarativepathview/tst_qdeclarativepathview.cpp @@ -367,9 +367,11 @@ void tst_QDeclarativePathView::dataModel() QCOMPARE(item->y(), 10.0); model.insertItem(4, "orange", "10"); + QTest::qWait(100); - int itemCount = findItems<QDeclarativeItem>(pathview, "wrapper").count(); - QCOMPARE(itemCount, 10); + QTRY_COMPARE(findItems<QDeclarativeItem>(pathview, "wrapper").count(), 10); + + QVERIFY(pathview->currentIndex() == 0); QDeclarativeText *text = findItem<QDeclarativeText>(pathview, "myText", 4); QVERIFY(text); @@ -384,26 +386,27 @@ void tst_QDeclarativePathView::dataModel() QMetaObject::invokeMethod(canvas->rootObject(), "checkProperties"); QVERIFY(testObject->error() == false); - itemCount = findItems<QDeclarativeItem>(pathview, "wrapper").count(); - QCOMPARE(itemCount, 5); + QTRY_COMPARE(findItems<QDeclarativeItem>(pathview, "wrapper").count(), 5); QDeclarativeRectangle *testItem = findItem<QDeclarativeRectangle>(pathview, "wrapper", 4); QVERIFY(testItem != 0); testItem = findItem<QDeclarativeRectangle>(pathview, "wrapper", 5); QVERIFY(testItem == 0); + pathview->setCurrentIndex(1); + model.insertItem(2, "pink", "2"); + QTest::qWait(100); - itemCount = findItems<QDeclarativeItem>(pathview, "wrapper").count(); - QCOMPARE(itemCount, 5); + QTRY_COMPARE(findItems<QDeclarativeItem>(pathview, "wrapper").count(), 5); + QVERIFY(pathview->currentIndex() == 1); text = findItem<QDeclarativeText>(pathview, "myText", 2); QVERIFY(text); QCOMPARE(text->text(), model.name(2)); model.removeItem(3); - itemCount = findItems<QDeclarativeItem>(pathview, "wrapper").count(); - QCOMPARE(itemCount, 5); + QTRY_COMPARE(findItems<QDeclarativeItem>(pathview, "wrapper").count(), 5); text = findItem<QDeclarativeText>(pathview, "myText", 3); QVERIFY(text); QCOMPARE(text->text(), model.name(3)); diff --git a/tests/auto/declarative/qdeclarativepixmapcache/tst_qdeclarativepixmapcache.cpp b/tests/auto/declarative/qdeclarativepixmapcache/tst_qdeclarativepixmapcache.cpp index 6b36224..b20d8ec 100644 --- a/tests/auto/declarative/qdeclarativepixmapcache/tst_qdeclarativepixmapcache.cpp +++ b/tests/auto/declarative/qdeclarativepixmapcache/tst_qdeclarativepixmapcache.cpp @@ -42,6 +42,7 @@ #include <QtTest/QtTest> #include <private/qdeclarativepixmapcache_p.h> #include <QtDeclarative/qdeclarativeengine.h> +#include <QtDeclarative/qdeclarativeimageprovider.h> #include <QNetworkReply> #include "testhttpserver.h" #include "../../../shared/util.h" @@ -72,6 +73,7 @@ private slots: void parallel_data(); void massive(); void cancelcrash(); + void shrinkcache(); private: QDeclarativeEngine engine; @@ -326,6 +328,31 @@ void tst_qdeclarativepixmapcache::cancelcrash() } } +class MyPixmapProvider : public QDeclarativeImageProvider +{ +public: + MyPixmapProvider() + : QDeclarativeImageProvider(Pixmap) {} + + virtual QPixmap requestPixmap(const QString &d, QSize *, const QSize &) { + QPixmap pix(800, 600); + pix.fill(Qt::red); + return pix; + } +}; + +// QTBUG-13345 +void tst_qdeclarativepixmapcache::shrinkcache() +{ + QDeclarativeEngine engine; + engine.addImageProvider(QLatin1String("mypixmaps"), new MyPixmapProvider); + + for (int ii = 0; ii < 4000; ++ii) { + QUrl url("image://mypixmaps/" + QString::number(ii)); + QDeclarativePixmap p(&engine, url); + } +} + QTEST_MAIN(tst_qdeclarativepixmapcache) #include "tst_qdeclarativepixmapcache.moc" diff --git a/tests/auto/declarative/qdeclarativetext/tst_qdeclarativetext.cpp b/tests/auto/declarative/qdeclarativetext/tst_qdeclarativetext.cpp index 658f381..f683d98 100644 --- a/tests/auto/declarative/qdeclarativetext/tst_qdeclarativetext.cpp +++ b/tests/auto/declarative/qdeclarativetext/tst_qdeclarativetext.cpp @@ -608,6 +608,17 @@ void tst_qdeclarativetext::style() QCOMPARE((int)textObject->style(), (int)styles.at(i)); QCOMPARE(textObject->styleColor(), QColor("white")); } + QString componentStr = "import Qt 4.7\nText { text: \"Hello World\" }"; + QDeclarativeComponent textComponent(&engine); + textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QDeclarativeText *textObject = qobject_cast<QDeclarativeText*>(textComponent.create()); + + QRectF brPre = textObject->boundingRect(); + textObject->setStyle(QDeclarativeText::Outline); + QRectF brPost = textObject->boundingRect(); + + QVERIFY(brPre.width() < brPost.width()); + QVERIFY(brPre.height() < brPost.height()); } void tst_qdeclarativetext::color() diff --git a/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp b/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp index 56a3121..84f4230 100644 --- a/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp +++ b/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp @@ -777,7 +777,7 @@ void tst_qdeclarativetextedit::delegateLoading_data() // import installed QTest::newRow("pass") << "cursorHttpTestPass.qml" << ""; - QTest::newRow("fail1") << "cursorHttpTestFail1.qml" << "<Unknown File>: Network error for URL http://localhost:42332/FailItem.qml "; + QTest::newRow("fail1") << "cursorHttpTestFail1.qml" << "http://localhost:42332/FailItem.qml: Remote host closed the connection "; QTest::newRow("fail2") << "cursorHttpTestFail2.qml" << "http://localhost:42332/ErrItem.qml:4:5: Fungus is not a type "; } diff --git a/tests/auto/declarative/qdeclarativevisualdatamodel/data/datalist.qml b/tests/auto/declarative/qdeclarativevisualdatamodel/data/datalist.qml new file mode 100644 index 0000000..c5e945a --- /dev/null +++ b/tests/auto/declarative/qdeclarativevisualdatamodel/data/datalist.qml @@ -0,0 +1,19 @@ +import Qt 4.7 + +ListView { + width: 100 + height: 100 + anchors.fill: parent + model: VisualDataModel { + id: visualModel + objectName: "visualModel" + model: myModel + delegate: Component { + Rectangle { + height: 25 + width: 100 + Text { objectName: "display"; text: display } + } + } + } +} diff --git a/tests/auto/declarative/qdeclarativevisualdatamodel/tst_qdeclarativevisualdatamodel.cpp b/tests/auto/declarative/qdeclarativevisualdatamodel/tst_qdeclarativevisualdatamodel.cpp index e0f32ea..95ef4fc 100644 --- a/tests/auto/declarative/qdeclarativevisualdatamodel/tst_qdeclarativevisualdatamodel.cpp +++ b/tests/auto/declarative/qdeclarativevisualdatamodel/tst_qdeclarativevisualdatamodel.cpp @@ -83,6 +83,8 @@ public: private slots: void rootIndex(); + void updateLayout(); + void childChanged(); void objectListModel(); private: @@ -155,6 +157,100 @@ void tst_qdeclarativevisualdatamodel::rootIndex() delete obj; } +void tst_qdeclarativevisualdatamodel::updateLayout() +{ + QDeclarativeView view; + + QStandardItemModel model; + initStandardTreeModel(&model); + + view.rootContext()->setContextProperty("myModel", &model); + + view.setSource(QUrl::fromLocalFile(SRCDIR "/data/datalist.qml")); + + QDeclarativeListView *listview = qobject_cast<QDeclarativeListView*>(view.rootObject()); + QVERIFY(listview != 0); + + QDeclarativeItem *contentItem = listview->contentItem(); + QVERIFY(contentItem != 0); + + QDeclarativeText *name = findItem<QDeclarativeText>(contentItem, "display", 0); + QVERIFY(name); + QCOMPARE(name->text(), QString("Row 1 Item")); + name = findItem<QDeclarativeText>(contentItem, "display", 1); + QVERIFY(name); + QCOMPARE(name->text(), QString("Row 2 Item")); + name = findItem<QDeclarativeText>(contentItem, "display", 2); + QVERIFY(name); + QCOMPARE(name->text(), QString("Row 3 Item")); + + model.invisibleRootItem()->sortChildren(0, Qt::DescendingOrder); + + name = findItem<QDeclarativeText>(contentItem, "display", 0); + QVERIFY(name); + QCOMPARE(name->text(), QString("Row 3 Item")); + name = findItem<QDeclarativeText>(contentItem, "display", 1); + QVERIFY(name); + QCOMPARE(name->text(), QString("Row 2 Item")); + name = findItem<QDeclarativeText>(contentItem, "display", 2); + QVERIFY(name); + QCOMPARE(name->text(), QString("Row 1 Item")); +} + +void tst_qdeclarativevisualdatamodel::childChanged() +{ + QDeclarativeView view; + + QStandardItemModel model; + initStandardTreeModel(&model); + + view.rootContext()->setContextProperty("myModel", &model); + + view.setSource(QUrl::fromLocalFile(SRCDIR "/data/datalist.qml")); + + QDeclarativeListView *listview = qobject_cast<QDeclarativeListView*>(view.rootObject()); + QVERIFY(listview != 0); + + QDeclarativeItem *contentItem = listview->contentItem(); + QVERIFY(contentItem != 0); + + QDeclarativeVisualDataModel *vdm = listview->findChild<QDeclarativeVisualDataModel*>("visualModel"); + vdm->setRootIndex(QVariant::fromValue(model.indexFromItem(model.item(1,0)))); + + QDeclarativeText *name = findItem<QDeclarativeText>(contentItem, "display", 0); + QVERIFY(name); + QCOMPARE(name->text(), QString("Row 2 Child Item")); + + model.item(1,0)->child(0,0)->setText("Row 2 updated child"); + + name = findItem<QDeclarativeText>(contentItem, "display", 0); + QVERIFY(name); + QCOMPARE(name->text(), QString("Row 2 updated child")); + + model.item(1,0)->appendRow(new QStandardItem(QLatin1String("Row 2 Child Item 2"))); + QTest::qWait(300); + + name = findItem<QDeclarativeText>(contentItem, "display", 1); + QVERIFY(name != 0); + QCOMPARE(name->text(), QString("Row 2 Child Item 2")); + + model.item(1,0)->takeRow(1); + name = findItem<QDeclarativeText>(contentItem, "display", 1); + QVERIFY(name == 0); + + vdm->setRootIndex(QVariant::fromValue(QModelIndex())); + QTest::qWait(300); + name = findItem<QDeclarativeText>(contentItem, "display", 0); + QVERIFY(name); + QCOMPARE(name->text(), QString("Row 1 Item")); + name = findItem<QDeclarativeText>(contentItem, "display", 1); + QVERIFY(name); + QCOMPARE(name->text(), QString("Row 2 Item")); + name = findItem<QDeclarativeText>(contentItem, "display", 2); + QVERIFY(name); + QCOMPARE(name->text(), QString("Row 3 Item")); +} + void tst_qdeclarativevisualdatamodel::objectListModel() { QDeclarativeView view; diff --git a/tests/auto/declarative/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp b/tests/auto/declarative/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp index 8ba9d45..0f6d531 100644 --- a/tests/auto/declarative/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp +++ b/tests/auto/declarative/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp @@ -558,7 +558,7 @@ void tst_QMetaObjectBuilder::property() QVERIFY(prop1.isWritable()); QVERIFY(!prop1.isResettable()); QVERIFY(!prop1.isDesignable()); - QVERIFY(!prop1.isScriptable()); + QVERIFY(prop1.isScriptable()); QVERIFY(!prop1.isStored()); QVERIFY(!prop1.isEditable()); QVERIFY(!prop1.isUser()); @@ -577,7 +577,7 @@ void tst_QMetaObjectBuilder::property() QVERIFY(prop2.isWritable()); QVERIFY(!prop2.isResettable()); QVERIFY(!prop2.isDesignable()); - QVERIFY(!prop2.isScriptable()); + QVERIFY(prop2.isScriptable()); QVERIFY(!prop2.isStored()); QVERIFY(!prop2.isEditable()); QVERIFY(!prop2.isUser()); @@ -599,7 +599,7 @@ void tst_QMetaObjectBuilder::property() prop1.setWritable(false); prop1.setResettable(true); prop1.setDesignable(true); - prop1.setScriptable(true); + prop1.setScriptable(false); prop1.setStored(true); prop1.setEditable(true); prop1.setUser(true); @@ -614,7 +614,7 @@ void tst_QMetaObjectBuilder::property() QVERIFY(!prop1.isWritable()); QVERIFY(prop1.isResettable()); QVERIFY(prop1.isDesignable()); - QVERIFY(prop1.isScriptable()); + QVERIFY(!prop1.isScriptable()); QVERIFY(prop1.isStored()); QVERIFY(prop1.isEditable()); QVERIFY(prop1.isUser()); @@ -627,7 +627,7 @@ void tst_QMetaObjectBuilder::property() QCOMPARE(prop2.type(), QByteArray("int")); QVERIFY(!prop2.isResettable()); QVERIFY(!prop2.isDesignable()); - QVERIFY(!prop2.isScriptable()); + QVERIFY(prop2.isScriptable()); QVERIFY(!prop2.isStored()); QVERIFY(!prop2.isEditable()); QVERIFY(!prop2.isUser()); @@ -643,7 +643,7 @@ void tst_QMetaObjectBuilder::property() QCOMPARE(prop2.type(), QByteArray("int")); QVERIFY(!prop2.isResettable()); QVERIFY(!prop2.isDesignable()); - QVERIFY(!prop2.isScriptable()); + QVERIFY(prop2.isScriptable()); QVERIFY(!prop2.isStored()); QVERIFY(!prop2.isEditable()); QVERIFY(!prop2.isUser()); diff --git a/tests/auto/declarative/qmlvisual/animation/qtbug13398/data/qtbug13398.0.png b/tests/auto/declarative/qmlvisual/animation/qtbug13398/data/qtbug13398.0.png Binary files differnew file mode 100644 index 0000000..16adc51 --- /dev/null +++ b/tests/auto/declarative/qmlvisual/animation/qtbug13398/data/qtbug13398.0.png diff --git a/tests/auto/declarative/qmlvisual/animation/qtbug13398/data/qtbug13398.qml b/tests/auto/declarative/qmlvisual/animation/qtbug13398/data/qtbug13398.qml new file mode 100644 index 0000000..0cc98ce --- /dev/null +++ b/tests/auto/declarative/qmlvisual/animation/qtbug13398/data/qtbug13398.qml @@ -0,0 +1,447 @@ +import Qt.VisualTest 4.7 + +VisualTest { + Frame { + msec: 0 + } + Frame { + msec: 16 + hash: "2452007928bf86b9c42e666c7a7afc89" + } + Frame { + msec: 32 + hash: "2452007928bf86b9c42e666c7a7afc89" + } + Frame { + msec: 48 + hash: "2452007928bf86b9c42e666c7a7afc89" + } + Frame { + msec: 64 + hash: "2452007928bf86b9c42e666c7a7afc89" + } + Frame { + msec: 80 + hash: "2452007928bf86b9c42e666c7a7afc89" + } + Frame { + msec: 96 + hash: "2452007928bf86b9c42e666c7a7afc89" + } + Frame { + msec: 112 + hash: "2452007928bf86b9c42e666c7a7afc89" + } + Frame { + msec: 128 + hash: "2452007928bf86b9c42e666c7a7afc89" + } + Frame { + msec: 144 + hash: "2452007928bf86b9c42e666c7a7afc89" + } + Frame { + msec: 160 + hash: "2452007928bf86b9c42e666c7a7afc89" + } + Frame { + msec: 176 + hash: "2452007928bf86b9c42e666c7a7afc89" + } + Frame { + msec: 192 + hash: "2452007928bf86b9c42e666c7a7afc89" + } + Frame { + msec: 208 + hash: "2452007928bf86b9c42e666c7a7afc89" + } + Frame { + msec: 224 + hash: "2452007928bf86b9c42e666c7a7afc89" + } + Frame { + msec: 240 + hash: "2452007928bf86b9c42e666c7a7afc89" + } + Frame { + msec: 256 + hash: "2452007928bf86b9c42e666c7a7afc89" + } + Frame { + msec: 272 + hash: "2452007928bf86b9c42e666c7a7afc89" + } + Frame { + msec: 288 + hash: "2452007928bf86b9c42e666c7a7afc89" + } + Frame { + msec: 304 + hash: "2452007928bf86b9c42e666c7a7afc89" + } + Frame { + msec: 320 + hash: "2452007928bf86b9c42e666c7a7afc89" + } + Frame { + msec: 336 + hash: "2452007928bf86b9c42e666c7a7afc89" + } + Frame { + msec: 352 + hash: "2452007928bf86b9c42e666c7a7afc89" + } + Frame { + msec: 368 + hash: "2452007928bf86b9c42e666c7a7afc89" + } + Frame { + msec: 384 + hash: "2452007928bf86b9c42e666c7a7afc89" + } + Frame { + msec: 400 + hash: "2452007928bf86b9c42e666c7a7afc89" + } + Frame { + msec: 416 + hash: "2452007928bf86b9c42e666c7a7afc89" + } + Frame { + msec: 432 + hash: "2452007928bf86b9c42e666c7a7afc89" + } + Frame { + msec: 448 + hash: "2452007928bf86b9c42e666c7a7afc89" + } + Frame { + msec: 464 + hash: "2452007928bf86b9c42e666c7a7afc89" + } + Frame { + msec: 480 + hash: "2452007928bf86b9c42e666c7a7afc89" + } + Frame { + msec: 496 + hash: "2452007928bf86b9c42e666c7a7afc89" + } + Mouse { + type: 2 + button: 1 + buttons: 1 + x: 220; y: 270 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 512 + hash: "2452007928bf86b9c42e666c7a7afc89" + } + Frame { + msec: 528 + hash: "2452007928bf86b9c42e666c7a7afc89" + } + Frame { + msec: 544 + hash: "2452007928bf86b9c42e666c7a7afc89" + } + Frame { + msec: 560 + hash: "2452007928bf86b9c42e666c7a7afc89" + } + Frame { + msec: 576 + hash: "2452007928bf86b9c42e666c7a7afc89" + } + Mouse { + type: 5 + button: 0 + buttons: 1 + x: 220; y: 271 + modifiers: 0 + sendToViewport: true + } + Mouse { + type: 3 + button: 1 + buttons: 0 + x: 220; y: 271 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 592 + hash: "2452007928bf86b9c42e666c7a7afc89" + } + Frame { + msec: 608 + hash: "96e8e81d61bffe02b8f41f47a4a7e8fc" + } + Frame { + msec: 624 + hash: "75881a2779bd7d7f683f87c4a7393769" + } + Frame { + msec: 640 + hash: "2ef628328d2a6393095e78db80b0513f" + } + Frame { + msec: 656 + hash: "390926f2c2c27dfa10c9b393ee466ce6" + } + Frame { + msec: 672 + hash: "ea07d93e7d8a53f56cff19d9d3b282a4" + } + Frame { + msec: 688 + hash: "8aa6be919b1ef4b7e102a319a453707e" + } + Frame { + msec: 704 + hash: "6ebc518fb53ffe42fca20b9f16a21b36" + } + Frame { + msec: 720 + hash: "ee7a93b157e24e22efa84604e7e44fe6" + } + Frame { + msec: 736 + hash: "de3bf8f67e51b036db4976fd3b4b6c3c" + } + Frame { + msec: 752 + hash: "648be4298ebe3bbc7e5c4a4c9c46f193" + } + Frame { + msec: 768 + hash: "1ccf3b73e22a4b98ce1df098af9466f2" + } + Frame { + msec: 784 + hash: "73a2fb047728b2b8e613f0fb8dfe429d" + } + Frame { + msec: 800 + hash: "bbb4cabec4b98ea8ca94dff91a0d8c99" + } + Frame { + msec: 816 + hash: "3337e86bd9fcfbce939389928fb1fb72" + } + Frame { + msec: 832 + hash: "cb4a2a330e8470c61de9e9b6d2dc4597" + } + Frame { + msec: 848 + hash: "e09a359578935b988ac1cc8c40b25547" + } + Frame { + msec: 864 + hash: "e09a359578935b988ac1cc8c40b25547" + } + Frame { + msec: 880 + hash: "e09a359578935b988ac1cc8c40b25547" + } + Frame { + msec: 896 + hash: "e09a359578935b988ac1cc8c40b25547" + } + Frame { + msec: 912 + hash: "e09a359578935b988ac1cc8c40b25547" + } + Frame { + msec: 928 + hash: "e09a359578935b988ac1cc8c40b25547" + } + Frame { + msec: 944 + hash: "e09a359578935b988ac1cc8c40b25547" + } + Frame { + msec: 960 + image: "qtbug13398.0.png" + } + Frame { + msec: 976 + hash: "e09a359578935b988ac1cc8c40b25547" + } + Frame { + msec: 992 + hash: "e09a359578935b988ac1cc8c40b25547" + } + Frame { + msec: 1008 + hash: "e09a359578935b988ac1cc8c40b25547" + } + Frame { + msec: 1024 + hash: "e09a359578935b988ac1cc8c40b25547" + } + Frame { + msec: 1040 + hash: "e09a359578935b988ac1cc8c40b25547" + } + Frame { + msec: 1056 + hash: "e09a359578935b988ac1cc8c40b25547" + } + Frame { + msec: 1072 + hash: "e09a359578935b988ac1cc8c40b25547" + } + Frame { + msec: 1088 + hash: "e09a359578935b988ac1cc8c40b25547" + } + Frame { + msec: 1104 + hash: "e09a359578935b988ac1cc8c40b25547" + } + Frame { + msec: 1120 + hash: "e09a359578935b988ac1cc8c40b25547" + } + Frame { + msec: 1136 + hash: "e09a359578935b988ac1cc8c40b25547" + } + Frame { + msec: 1152 + hash: "e09a359578935b988ac1cc8c40b25547" + } + Frame { + msec: 1168 + hash: "e09a359578935b988ac1cc8c40b25547" + } + Frame { + msec: 1184 + hash: "e09a359578935b988ac1cc8c40b25547" + } + Frame { + msec: 1200 + hash: "e09a359578935b988ac1cc8c40b25547" + } + Frame { + msec: 1216 + hash: "e09a359578935b988ac1cc8c40b25547" + } + Frame { + msec: 1232 + hash: "e09a359578935b988ac1cc8c40b25547" + } + Mouse { + type: 2 + button: 1 + buttons: 1 + x: 220; y: 271 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 1248 + hash: "e09a359578935b988ac1cc8c40b25547" + } + Frame { + msec: 1264 + hash: "e09a359578935b988ac1cc8c40b25547" + } + Frame { + msec: 1280 + hash: "e09a359578935b988ac1cc8c40b25547" + } + Frame { + msec: 1296 + hash: "e09a359578935b988ac1cc8c40b25547" + } + Frame { + msec: 1312 + hash: "e09a359578935b988ac1cc8c40b25547" + } + Frame { + msec: 1328 + hash: "e09a359578935b988ac1cc8c40b25547" + } + Mouse { + type: 3 + button: 1 + buttons: 0 + x: 220; y: 271 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 1344 + hash: "e09a359578935b988ac1cc8c40b25547" + } + Frame { + msec: 1360 + hash: "697a4fd182ff90cd557f224174bad43a" + } + Frame { + msec: 1376 + hash: "99e5ca9a77df1acfed628f31b9050179" + } + Frame { + msec: 1392 + hash: "1f0dc00d3e3536b40a6becf775b31cee" + } + Frame { + msec: 1408 + hash: "5b81ddd35d74be222bc8a40d2573884b" + } + Frame { + msec: 1424 + hash: "4e236f5de69048e87add0e4380f2c3e6" + } + Frame { + msec: 1440 + hash: "a901c9c0c77e03d98a2b95267cca8514" + } + Frame { + msec: 1456 + hash: "78bbdf6781c2968c67982ffdb747dbbe" + } + Frame { + msec: 1472 + hash: "a245ca593649f60980be982eb8fda57e" + } + Frame { + msec: 1488 + hash: "c27fddc147749da24eaeb92aeaf61738" + } + Frame { + msec: 1504 + hash: "b9674af46b618dc1eedabd4f18253b11" + } + Frame { + msec: 1520 + hash: "8ae3c0cc0888fd0a607bc5b537a9ce0a" + } + Frame { + msec: 1536 + hash: "f1981bd3fb08233622a4078e2f717011" + } + Frame { + msec: 1552 + hash: "4dce834c9e3988fe535391fedc942add" + } + Frame { + msec: 1568 + hash: "ca7356dee61e156d04b0b46ea033498e" + } + Frame { + msec: 1584 + hash: "97499f6e04cbe690bc12458aef4b66a5" + } + Frame { + msec: 1600 + hash: "2452007928bf86b9c42e666c7a7afc89" + } +} diff --git a/tests/auto/declarative/qmlvisual/animation/qtbug13398/qtbug13398.qml b/tests/auto/declarative/qmlvisual/animation/qtbug13398/qtbug13398.qml new file mode 100644 index 0000000..8f388bc --- /dev/null +++ b/tests/auto/declarative/qmlvisual/animation/qtbug13398/qtbug13398.qml @@ -0,0 +1,68 @@ +import Qt 4.7 + +Item { + width: 300 + height: 400 + + Rectangle { + id: root + color: "darkkhaki" + + x: 50 + y: 50 + + width: 200 + height: 300 + + Rectangle { + id: statusbar + color: "chocolate" + + height: 30 + + anchors.top: root.top + anchors.left: root.left + anchors.right: root.right + } + + Rectangle { + id: titlebar + color: "crimson" + + height: 60 + + anchors.top: statusbar.bottom + anchors.left: root.left + anchors.right: root.right + } + + MouseArea { + anchors.fill: parent + onClicked: { + root.state = root.state ? "" : "fullscreen"; + } + } + + states: [ + State { + name: "fullscreen" + AnchorChanges { + target: statusbar + anchors.top: undefined + anchors.bottom: titlebar.top + } + AnchorChanges { + target: titlebar + anchors.top: undefined + anchors.bottom: root.top + } + } + ] + + transitions: [ + Transition { + AnchorAnimation { } + } + ] + } +} diff --git a/tests/auto/declarative/qmlvisual/qdeclarativesmoothedanimation/data/smoothedfollow.0.png b/tests/auto/declarative/qmlvisual/qdeclarativesmoothedanimation/data/smoothedfollow.0.png Binary files differnew file mode 100644 index 0000000..bf02e1a --- /dev/null +++ b/tests/auto/declarative/qmlvisual/qdeclarativesmoothedanimation/data/smoothedfollow.0.png diff --git a/tests/auto/declarative/qmlvisual/qdeclarativesmoothedanimation/data/smoothedfollow.1.png b/tests/auto/declarative/qmlvisual/qdeclarativesmoothedanimation/data/smoothedfollow.1.png Binary files differnew file mode 100644 index 0000000..ae71dc8 --- /dev/null +++ b/tests/auto/declarative/qmlvisual/qdeclarativesmoothedanimation/data/smoothedfollow.1.png diff --git a/tests/auto/declarative/qmlvisual/qdeclarativesmoothedanimation/data/smoothedfollow.2.png b/tests/auto/declarative/qmlvisual/qdeclarativesmoothedanimation/data/smoothedfollow.2.png Binary files differnew file mode 100644 index 0000000..6f631b0 --- /dev/null +++ b/tests/auto/declarative/qmlvisual/qdeclarativesmoothedanimation/data/smoothedfollow.2.png diff --git a/tests/auto/declarative/qmlvisual/qdeclarativesmoothedanimation/data/smoothedfollow.qml b/tests/auto/declarative/qmlvisual/qdeclarativesmoothedanimation/data/smoothedfollow.qml new file mode 100644 index 0000000..3124973 --- /dev/null +++ b/tests/auto/declarative/qmlvisual/qdeclarativesmoothedanimation/data/smoothedfollow.qml @@ -0,0 +1,795 @@ +import Qt.VisualTest 4.7 + +VisualTest { + Frame { + msec: 0 + } + Frame { + msec: 16 + hash: "2c6600b50a18c415032fa95fe5089da6" + } + Frame { + msec: 32 + hash: "aefd5a2570cc0252be102644ec1e49e3" + } + Frame { + msec: 48 + hash: "6183d0554a8b812bee02719dc4df21d1" + } + Frame { + msec: 64 + hash: "e1b3a94d033626338de0e04dba7b6df9" + } + Frame { + msec: 80 + hash: "7d1a5a265fb20ac4d741d76ab7b3a41f" + } + Frame { + msec: 96 + hash: "0ce7d2acda3e5ccb7b2364e2a7b409a4" + } + Frame { + msec: 112 + hash: "21f3a66ee80fcb2dd4dce0d1666aa4dd" + } + Frame { + msec: 128 + hash: "ea5b81ff2805210111cb388ab9be0d8f" + } + Frame { + msec: 144 + hash: "a8a54a3c524dcf6777b71d99ae2d50bd" + } + Frame { + msec: 160 + hash: "6b658c468af8a88e4a282d57fdcbc3b0" + } + Frame { + msec: 176 + hash: "986121c9d928cc9ceb912a975f75760a" + } + Frame { + msec: 192 + hash: "4bf3593d0edc4347cf77670a48ba4440" + } + Frame { + msec: 208 + hash: "ea00f25295fb019f949930fb7109ceb4" + } + Frame { + msec: 224 + hash: "ad6cc7563e2720c405842317d0ce731a" + } + Frame { + msec: 240 + hash: "8a03a1207cdb5bd92f5227b25a7b638e" + } + Frame { + msec: 256 + hash: "f355321aa47d18e8b6dde503565d0e97" + } + Frame { + msec: 272 + hash: "e18f671cac8e68948f32a468bf2630cf" + } + Frame { + msec: 288 + hash: "264bca92fba53f25439d240afef62880" + } + Frame { + msec: 304 + hash: "a1a226c73fb97d5302ce683f901ee5c4" + } + Frame { + msec: 320 + hash: "05578552476372fc58e463e84a147ddd" + } + Frame { + msec: 336 + hash: "0a3e0a651f9eb3e6a44a55a6786e60ff" + } + Frame { + msec: 352 + hash: "4ca362f079f96a01360ee8062fbb8238" + } + Frame { + msec: 368 + hash: "ba512c117d97ce16ff92d03ce2b08056" + } + Frame { + msec: 384 + hash: "8688355f0f97afe000d02f71c841d5dc" + } + Frame { + msec: 400 + hash: "a2ea6ad008da95a67d3bc70e11e3811d" + } + Frame { + msec: 416 + hash: "83bc9c444ab8618438dc2b8b14716f7b" + } + Frame { + msec: 432 + hash: "fafbba34fc8f9d33b559e6fcd0c5f1c6" + } + Frame { + msec: 448 + hash: "92d245951b759f74182602a7a337cb0f" + } + Frame { + msec: 464 + hash: "e0634d25088a6855df8d86d84fe37cd7" + } + Frame { + msec: 480 + hash: "7f4d05f4c3b1a365732e448f2c751740" + } + Frame { + msec: 496 + hash: "fcd6f55929f753f77b1617c0984b8690" + } + Frame { + msec: 512 + hash: "7e88f100a7012d739cd3c97c4e7f4b45" + } + Frame { + msec: 528 + hash: "8f9d029b3850ee2f11cdf6630d100682" + } + Frame { + msec: 544 + hash: "b915f712b24f187ee759b3337fb0df7a" + } + Frame { + msec: 560 + hash: "eae400a0c72d38156f7ae0f16ab9ee66" + } + Frame { + msec: 576 + hash: "e913a1e317cca355b06a393f44cc0243" + } + Frame { + msec: 592 + hash: "abf075ea63a6f5cce43c38e20dbcdbb2" + } + Frame { + msec: 608 + hash: "a6e85caa1eb933343a4605bc434e2841" + } + Frame { + msec: 624 + hash: "8e33e2582dd127d3f04017bf493b0ac6" + } + Frame { + msec: 640 + hash: "959e4062262bcc759abfc7b0bf3e10b6" + } + Frame { + msec: 656 + hash: "9529e2241df0d90ea640fdb3752b0837" + } + Frame { + msec: 672 + hash: "5595b64495996ce66b5f6892e9457456" + } + Frame { + msec: 688 + hash: "532259c3577553622093eba907ae82d3" + } + Frame { + msec: 704 + hash: "85c4332100b6f5256702b594c83f4eff" + } + Frame { + msec: 720 + hash: "b96292d85b12fa8e68c5de3deb29b980" + } + Frame { + msec: 736 + hash: "64febec9c8b58e2b93249f19c57b7aba" + } + Frame { + msec: 752 + hash: "88e588af29131cf942e02b1080e564e5" + } + Frame { + msec: 768 + hash: "07f911478be2f36d0c1b9cb878f4fe47" + } + Frame { + msec: 784 + hash: "8ffbf2381efefcbca413f6e3455018fb" + } + Frame { + msec: 800 + hash: "6e456af680e40799d3f38bdde29a85f9" + } + Frame { + msec: 816 + hash: "48a8dbc64d7823164c992f55b270115d" + } + Frame { + msec: 832 + hash: "a6d28eb1d0aafd387e35ca7b362bec53" + } + Frame { + msec: 848 + hash: "2e9f2b2ebf1b24f01fc986ded320d7c9" + } + Frame { + msec: 864 + hash: "d0cafd9be3263193c207c39eeb051bb8" + } + Frame { + msec: 880 + hash: "8dee1a5365fa3ccd7036c8afa6a805cc" + } + Frame { + msec: 896 + hash: "42f893afb80633f0ffb82f1725bb097f" + } + Frame { + msec: 912 + hash: "f466a404940abcd4c8f3180696da1a29" + } + Frame { + msec: 928 + hash: "e5746e33b3eb155a354bc5900b7593ee" + } + Frame { + msec: 944 + hash: "a1c2eb7048356f4ebc803d9d5439db24" + } + Frame { + msec: 960 + image: "smoothedfollow.0.png" + } + Frame { + msec: 976 + hash: "338aec0e679a8f2e79f6a5503dfbd6c3" + } + Frame { + msec: 992 + hash: "59321f1eb26c379e9e2a37b6890d922d" + } + Frame { + msec: 1008 + hash: "f37a821b9cf9f67fd011c6790a2757f0" + } + Frame { + msec: 1024 + hash: "c3f1b8722c616ecd55d8496e76a9bf06" + } + Frame { + msec: 1040 + hash: "ca6aff9addda2e3ac51e5e2013393365" + } + Frame { + msec: 1056 + hash: "17d1aa7821ce8169a3100a3cd3a0df2b" + } + Frame { + msec: 1072 + hash: "d85dd272f35868d6832316e862db4ec1" + } + Frame { + msec: 1088 + hash: "8bce5bdadfa974655dc7e020ad43edeb" + } + Frame { + msec: 1104 + hash: "b97f71587a5187d5175e5d9f1409c00a" + } + Frame { + msec: 1120 + hash: "53d438e601c25aebfd2ecb0064cdf5cc" + } + Frame { + msec: 1136 + hash: "18c43dd35b3e0d8f9ab5c8de3e48886a" + } + Frame { + msec: 1152 + hash: "e4ab585684d083de118b7862ef5cbd63" + } + Frame { + msec: 1168 + hash: "48ab046a2e2ca1a1225574b94925482e" + } + Frame { + msec: 1184 + hash: "c4bd06a5c329ef6975a60453f588bce7" + } + Frame { + msec: 1200 + hash: "864393a984dce3e9dd2daec56ddb3fe7" + } + Frame { + msec: 1216 + hash: "fcdf4cfcd8a6d8667868ba9633475fe0" + } + Frame { + msec: 1232 + hash: "5ac2b96158045c9b9eb35f1cbabe5b1f" + } + Frame { + msec: 1248 + hash: "83c409e5d3e6fe9e953d9ce14d731b3b" + } + Frame { + msec: 1264 + hash: "01805526b04e17b89238e7b929be48dd" + } + Frame { + msec: 1280 + hash: "4708345219b3732f9aaf8b40645f65d2" + } + Frame { + msec: 1296 + hash: "12716f84b6f648df2cbe08cfea58764c" + } + Frame { + msec: 1312 + hash: "6cce1e6354bd338f364bcca84a5fd081" + } + Frame { + msec: 1328 + hash: "c5da6f6b00402e0de00490792b963cdf" + } + Frame { + msec: 1344 + hash: "0eacadf69c0818e818abaf3aaf823aff" + } + Frame { + msec: 1360 + hash: "c68cd79bf0d329a3c672896b9ce2044d" + } + Frame { + msec: 1376 + hash: "26786f921ddddd9d2f975e1193943d2d" + } + Frame { + msec: 1392 + hash: "68c7c1779bb19ee5cd9370b5c06f4ce7" + } + Frame { + msec: 1408 + hash: "5e87c3e00ef7fab01c17d9e89c661aab" + } + Frame { + msec: 1424 + hash: "0b459122be303c38d3564dd7fea53fc1" + } + Frame { + msec: 1440 + hash: "3b13101a45b470fd04fa02f34548984b" + } + Frame { + msec: 1456 + hash: "6308fa1ed015bb698251af0d1b9be084" + } + Frame { + msec: 1472 + hash: "f219427d8fdf826f33351ba64db55d33" + } + Frame { + msec: 1488 + hash: "0c9ad8c5224d3cdefb8ac793cac3ca79" + } + Frame { + msec: 1504 + hash: "38438307162bceef76afb043c82b6a82" + } + Frame { + msec: 1520 + hash: "78b367e6bab0463fe08f5e634cfbced2" + } + Frame { + msec: 1536 + hash: "81e56f9d3bb9b360a07dc85697a59340" + } + Frame { + msec: 1552 + hash: "cef4fdb8c12485d3590e598090312297" + } + Frame { + msec: 1568 + hash: "8ea0c90a100c583558f92843030543cc" + } + Frame { + msec: 1584 + hash: "0037f0f17a50bdfe3bf0de810ff837f1" + } + Frame { + msec: 1600 + hash: "2b060ac0dfa045b916d3fd5ff6f84bfb" + } + Frame { + msec: 1616 + hash: "b20705dcc6176efd83cff6927991ff0a" + } + Frame { + msec: 1632 + hash: "0af69e490bdc54f27d3e50c1fdfd12a8" + } + Frame { + msec: 1648 + hash: "8e4cceadc01de5b51082889efabcbb7e" + } + Frame { + msec: 1664 + hash: "b64958786a7007686fb1734783d553f5" + } + Frame { + msec: 1680 + hash: "e0b9d98bb3a596fd235d58b6a761a0e0" + } + Frame { + msec: 1696 + hash: "1a5d7dc4dfd3ee86a36978d4effd299c" + } + Frame { + msec: 1712 + hash: "4946561f008635599651bf24b9aa0594" + } + Frame { + msec: 1728 + hash: "8427d33046af64c6e63939238c101e86" + } + Frame { + msec: 1744 + hash: "cdcfab5cea86c33f276c3613d76067c4" + } + Frame { + msec: 1760 + hash: "966005d62bd69b53d77459e5ab65116c" + } + Frame { + msec: 1776 + hash: "8a3c4ff083a973325c4ab09e09027ef6" + } + Frame { + msec: 1792 + hash: "737ffd6f52fa3d812ecaf835a30495af" + } + Frame { + msec: 1808 + hash: "6731007c97ba3ba60e73ab50803868e5" + } + Frame { + msec: 1824 + hash: "caa4ea08c5c330e77a7445cc1adf1666" + } + Frame { + msec: 1840 + hash: "73778bfbae55a81557a128acb4a197c8" + } + Frame { + msec: 1856 + hash: "7d8609f1336ddf4e25b505e54142114e" + } + Frame { + msec: 1872 + hash: "d8b4514d2bd77dbe67e27d400dc1a2f3" + } + Frame { + msec: 1888 + hash: "ac3e7040f1e9fc680f52f46d25eb3faa" + } + Frame { + msec: 1904 + hash: "509c21774f0fca9dde0657133a1cc363" + } + Frame { + msec: 1920 + image: "smoothedfollow.1.png" + } + Frame { + msec: 1936 + hash: "545bcb0c362a083ee698a5c8cd225014" + } + Frame { + msec: 1952 + hash: "77370c9b2880c55fecf07457dd0d455b" + } + Frame { + msec: 1968 + hash: "6c44209f31f5f010f1b3e05490468821" + } + Frame { + msec: 1984 + hash: "2dffac0c44e52f2984525d3d3700e6ed" + } + Frame { + msec: 2000 + hash: "d70f2db1b166b2de3bef74bc4bf94a80" + } + Frame { + msec: 2016 + hash: "50e4f6a82f498066fc9b6588762f59f9" + } + Frame { + msec: 2032 + hash: "956a7d7db9aef1b7abefac1a69622f02" + } + Frame { + msec: 2048 + hash: "13f19d5baefb6c8c9f71c16163663a27" + } + Frame { + msec: 2064 + hash: "076ff84405ddb29a12ed30d27cee558b" + } + Frame { + msec: 2080 + hash: "6af0261639f809da8f7e4831559596d3" + } + Frame { + msec: 2096 + hash: "a0500b18e99bfe3a48d52cc62b4a946b" + } + Frame { + msec: 2112 + hash: "bb0ea576c9136fb70720d4540731d2ca" + } + Frame { + msec: 2128 + hash: "d9b12ad9bf54d7db0ef1b36297a6dd6c" + } + Frame { + msec: 2144 + hash: "2de77e082872f072a849ba9ea93e3aec" + } + Frame { + msec: 2160 + hash: "69e186c3e8e6b2c75da2ca87043129da" + } + Frame { + msec: 2176 + hash: "0c2f23b0cbedb45a68f0cbe6132b4820" + } + Frame { + msec: 2192 + hash: "533bad00e5624611ea8a15d5fa98f0f2" + } + Frame { + msec: 2208 + hash: "d9c60bc821205aa4ea38d846e5b00f3a" + } + Frame { + msec: 2224 + hash: "d4de041edf15c6b6806d7f5992146711" + } + Frame { + msec: 2240 + hash: "100145df5271efaaee1d619bd50b69fc" + } + Frame { + msec: 2256 + hash: "22905b794fee24f3a25e4944d5505e96" + } + Frame { + msec: 2272 + hash: "aeed7adea08fe6e8b60310082cf87b6c" + } + Frame { + msec: 2288 + hash: "82bf8d40b6ed8aae9d6172eae76d1859" + } + Frame { + msec: 2304 + hash: "b1881778936744db3df0898638e4b0df" + } + Frame { + msec: 2320 + hash: "87195016996f8786a8a2430c54f13494" + } + Frame { + msec: 2336 + hash: "56f99b14320662b90eb10e77845bba30" + } + Frame { + msec: 2352 + hash: "69a84022d8d2b3cdb1d7eae6ce5ccef2" + } + Frame { + msec: 2368 + hash: "578ca8c66da6aa64392b253ab6cccbc0" + } + Frame { + msec: 2384 + hash: "4c2058e4708001f82f3bcb8110d6a54f" + } + Frame { + msec: 2400 + hash: "a838be752168bc6feb3151327147bb23" + } + Frame { + msec: 2416 + hash: "bf6cde06f0ee814cd4a23f3d43e7d270" + } + Frame { + msec: 2432 + hash: "9162ec43bc84261c0eb9ea2425da0b8a" + } + Frame { + msec: 2448 + hash: "7be19df0ee54f9bb31ebee2d786addc8" + } + Frame { + msec: 2464 + hash: "542a4c004f5b1b8efa7588b27cc2ba43" + } + Frame { + msec: 2480 + hash: "f9e2edd343be212a9679f1e2ad0e73b3" + } + Frame { + msec: 2496 + hash: "b6d4e9169fc4446cdbd3a36f485b943b" + } + Frame { + msec: 2512 + hash: "0d3b7a652a94162b71e88ed213559af4" + } + Frame { + msec: 2528 + hash: "9d4a2383a4d43ac94ff0a344f217b22d" + } + Frame { + msec: 2544 + hash: "719d402379c40de5cd6d4c8fa92f5472" + } + Frame { + msec: 2560 + hash: "78fb55f5b9c2033a91e41100229e4465" + } + Frame { + msec: 2576 + hash: "0a9ec91eee6c7c770ce2e414fa881229" + } + Frame { + msec: 2592 + hash: "5d9f81f1becf486a09f086e15a64d1f0" + } + Frame { + msec: 2608 + hash: "0f5e18af1eac31e6993ea2df51a143f0" + } + Frame { + msec: 2624 + hash: "08a292373756b06c3a624b8f3bf06236" + } + Frame { + msec: 2640 + hash: "f3c8101429753ce8f0ee094fe0db98ac" + } + Frame { + msec: 2656 + hash: "1603ad220d68ae0a2f613687533c2ebc" + } + Frame { + msec: 2672 + hash: "e2b8049d18fd36fff0180bd4bc199732" + } + Frame { + msec: 2688 + hash: "d1bfeadaa9046ec5013734938a8f4af1" + } + Frame { + msec: 2704 + hash: "3cb3a0e9dc73e76101288395ffeb2b7b" + } + Frame { + msec: 2720 + hash: "104a10e6bd48dacfedf5c98cf641ae93" + } + Frame { + msec: 2736 + hash: "f04a2985e7c203dd6fce46b60fcb23fc" + } + Frame { + msec: 2752 + hash: "30cb747f4604c208d7dc697d5fe2af6b" + } + Frame { + msec: 2768 + hash: "b9eca6ee8fe29351cadeb9a2caf36fa6" + } + Frame { + msec: 2784 + hash: "7bc56e712d713a00a684e07cf3d09907" + } + Frame { + msec: 2800 + hash: "0d7a5e2ff588b71e77abb72723c763b2" + } + Frame { + msec: 2816 + hash: "0d961843e54cbe5ba76c11bcd634bc39" + } + Frame { + msec: 2832 + hash: "6328b52965a002944c501d9888928caa" + } + Frame { + msec: 2848 + hash: "63e668a7688167b604b641929843d0cf" + } + Frame { + msec: 2864 + hash: "7f5e71332268be68de9dcb25f173d2e0" + } + Frame { + msec: 2880 + image: "smoothedfollow.2.png" + } + Frame { + msec: 2896 + hash: "dc6e83fcc5a403913a94c498f1571098" + } + Frame { + msec: 2912 + hash: "8deb275bd08df9b3abdcf3e2796a0601" + } + Frame { + msec: 2928 + hash: "6c08a25a442b97a8cb359792b6a01641" + } + Frame { + msec: 2944 + hash: "5f7ccd5706c77f0b0ddced41ed6352d8" + } + Frame { + msec: 2960 + hash: "6668d1936524f0fdc490720a962a3698" + } + Frame { + msec: 2976 + hash: "e36f901fb4b8ad754592642a7575e4ee" + } + Frame { + msec: 2992 + hash: "7453182980e458d827f3ff83aa3f2c88" + } + Frame { + msec: 3008 + hash: "0e15d75b2a7f2e4a39906093b930d6a8" + } + Frame { + msec: 3024 + hash: "822ccc6c629eabf38fd5ac56abb638f5" + } + Frame { + msec: 3040 + hash: "331ef5b3e3dd5642f8532d337fd22def" + } + Frame { + msec: 3056 + hash: "3c29aae83f28239f31125ef02f523d02" + } + Frame { + msec: 3072 + hash: "56ed674bf2d345861eb235a4239078e2" + } + Frame { + msec: 3088 + hash: "5412b9ad01a6780b67bc59b80a274cd5" + } + Frame { + msec: 3104 + hash: "a6f9ae09a7386f06a84c251083660dd6" + } + Frame { + msec: 3120 + hash: "83f07277c9bec7419dd6a4d40d8accf7" + } + Frame { + msec: 3136 + hash: "e6cb74961dfef68a32f255176e0ebff3" + } + Frame { + msec: 3152 + hash: "9e6c3ac0190beaf30754155a5d64b81c" + } +} diff --git a/tests/auto/declarative/qmlvisual/qdeclarativesmoothedanimation/smoothedfollow.qml b/tests/auto/declarative/qmlvisual/qdeclarativesmoothedanimation/smoothedfollow.qml index 0df727b..63dba47 100644 --- a/tests/auto/declarative/qmlvisual/qdeclarativesmoothedanimation/smoothedfollow.qml +++ b/tests/auto/declarative/qmlvisual/qdeclarativesmoothedanimation/smoothedfollow.qml @@ -1,15 +1,15 @@ import Qt 4.7 Rectangle { - width: 800; height: 240; color: "gray" + width: 800; height: 720; color: "gray" Rectangle { id: rect width: 50; height: 20; y: 30; color: "black" SequentialAnimation on x { loops: Animation.Infinite - NumberAnimation { from: 50; to: 700; duration: 2000 } - NumberAnimation { from: 700; to: 50; duration: 2000 } + NumberAnimation { from: 50; to: 700; duration: 1000 } + NumberAnimation { from: 700; to: 50; duration: 1000 } } } @@ -25,16 +25,104 @@ Rectangle { Rectangle { width: 50; height: 20; x: rect.x; y: 120; color: "green" - Behavior on x { SmoothedAnimation { reversingMode: SmoothedAnimation.Sync } } + Behavior on x { SmoothedAnimation { velocity: 200; reversingMode: SmoothedAnimation.Sync } } } Rectangle { width: 50; height: 20; x: rect.x; y: 150; color: "purple" - Behavior on x { SmoothedAnimation { maximumEasingTime: 200 } } + Behavior on x { SmoothedAnimation { velocity: 200; maximumEasingTime: 100 } } } Rectangle { width: 50; height: 20; x: rect.x; y: 180; color: "blue" - Behavior on x { SmoothedAnimation { duration: 300 } } + Behavior on x { SmoothedAnimation { velocity: -1; duration: 300 } } + } + + //rect2 has jerky movement, but the rects following it should be smooth + Rectangle { + id: rect2 + property int dir: 1 + width: 50; height: 20; x:50; y: 240; color: "black" + function advance(){ + if(x >= 700) + dir = -1; + if(x <= 50) + dir = 1; + x += 130.0 * dir; + } + } + Timer{ + interval: 200 + running: true + repeat: true + onTriggered: rect2.advance(); + } + + Rectangle { + width: 50; height: 20; x: rect2.x; y: 270; color: "red" + Behavior on x { SmoothedAnimation { velocity: 400 } } + } + + Rectangle { + width: 50; height: 20; x: rect2.x; y: 300; color: "yellow" + Behavior on x { SmoothedAnimation { velocity: 300; reversingMode: SmoothedAnimation.Immediate } } + } + + Rectangle { + width: 50; height: 20; x: rect2.x; y: 330; color: "green" + Behavior on x { SmoothedAnimation { velocity: 200; reversingMode: SmoothedAnimation.Sync } } + } + + Rectangle { + width: 50; height: 20; x: rect2.x; y: 360; color: "purple" + Behavior on x { SmoothedAnimation { velocity: 200; maximumEasingTime: 100 } } + } + + Rectangle { + width: 50; height: 20; x: rect2.x; y: 390; color: "blue" + Behavior on x { SmoothedAnimation { velocity: -1; duration: 300 } } + } + + //rect3 just jumps , but the rects following it should be smooth + Rectangle { + id: rect3 + width: 50; height: 20; x:50; y: 480; color: "black" + function advance(){ + if(x == 50) + x = 700; + else + x = 50; + } + } + Timer{ + interval: 1000 + running: true + repeat: true + onTriggered: rect3.advance(); + } + + Rectangle { + width: 50; height: 20; x: rect3.x; y: 510; color: "red" + Behavior on x { SmoothedAnimation { velocity: 400 } } + } + + Rectangle { + width: 50; height: 20; x: rect3.x; y: 540; color: "yellow" + Behavior on x { SmoothedAnimation { velocity: 300; reversingMode: SmoothedAnimation.Immediate } } + } + + Rectangle { + width: 50; height: 20; x: rect3.x; y: 570; color: "green" + Behavior on x { SmoothedAnimation { velocity: 200; reversingMode: SmoothedAnimation.Sync } } + } + + Rectangle { + width: 50; height: 20; x: rect3.x; y: 600; color: "purple" + Behavior on x { SmoothedAnimation { velocity: 200; maximumEasingTime: 100 } } + } + + Rectangle { + width: 50; height: 20; x: rect3.x; y: 630; color: "blue" + Behavior on x { SmoothedAnimation { velocity: -1; duration: 300 } } } } diff --git a/tests/auto/gestures/tst_gestures.cpp b/tests/auto/gestures/tst_gestures.cpp index a968520..ddc3939 100644 --- a/tests/auto/gestures/tst_gestures.cpp +++ b/tests/auto/gestures/tst_gestures.cpp @@ -395,7 +395,12 @@ void tst_Gestures::customGesture() { GestureWidget widget; widget.grabGesture(CustomGesture::GestureType, Qt::DontStartGestureOnChildren); + widget.show(); + QTest::qWaitForWindowShown(&widget); + CustomEvent event; + event.hotSpot = widget.mapToGlobal(QPoint(5,5)); + event.hasHotSpot = true; sendCustomGesture(&event, &widget); static const int TotalGestureEventsCount = CustomGesture::SerialFinishedThreshold - CustomGesture::SerialStartedThreshold + 1; diff --git a/tests/auto/headers/tst_headers.cpp b/tests/auto/headers/tst_headers.cpp index 06c70f9..7ccf058 100644 --- a/tests/auto/headers/tst_headers.cpp +++ b/tests/auto/headers/tst_headers.cpp @@ -213,7 +213,8 @@ void tst_Headers::licenseCheck() return; if (content.first().contains("generated")) { - content.takeFirst(); + // don't scan generated files + return; } if (sourceFile.endsWith("/tests/auto/linguist/lupdate/testdata/good/merge_ordering/foo.cpp") diff --git a/tests/auto/linguist/lconvert/data/test-refs.po b/tests/auto/linguist/lconvert/data/test-refs.po new file mode 100644 index 0000000..e149a38 --- /dev/null +++ b/tests/auto/linguist/lconvert/data/test-refs.po @@ -0,0 +1,23 @@ +msgid "" +msgstr "" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Language: de_DE\n" + +#: themer/kdmlabel.cpp:285 +#, no-c-format +msgctxt "date format" +msgid "%a %d %B" +msgstr "%a %d %B" + +#: foo.bar.baz +#, no-c-format +msgid "full java class name" +msgstr "" + +#: foo.car:123 monks:here file/gar.c:17:19 no:monks:here +#, no-c-format +msgid "some excessive locations" +msgstr "" diff --git a/tests/auto/linguist/lconvert/data/test20.ts b/tests/auto/linguist/lconvert/data/test20.ts index f042edf..0e38b4b 100644 --- a/tests/auto/linguist/lconvert/data/test20.ts +++ b/tests/auto/linguist/lconvert/data/test20.ts @@ -158,5 +158,14 @@ <comment>comment with | and ~ and so~</comment> <translation type="unfinished"></translation> </message> + <message> + <source>just something obsolete</source> + <translation type="obsolete">translated obsoletion</translation> + </message> + <message> + <source>something else obsolete</source> + <comment>comment with | and ~ and so~</comment> + <translation type="obsolete">another translated obsoletion</translation> + </message> </context> </TS> diff --git a/tests/auto/linguist/lconvert/tst_lconvert.cpp b/tests/auto/linguist/lconvert/tst_lconvert.cpp index 998f588..a3c29d8 100644 --- a/tests/auto/linguist/lconvert/tst_lconvert.cpp +++ b/tests/auto/linguist/lconvert/tst_lconvert.cpp @@ -317,6 +317,8 @@ void tst_lconvert::roundtrips_data() QTest::newRow("po-xliff-po (plural-2)") << "plural-2.po" << poXlfPo << noArgs; QTest::newRow("po-xliff-po (plural-3)") << "plural-3.po" << poXlfPo << noArgs; + QTest::newRow("po-ts-po (references)") << "test-refs.po" << poTsPo << noArgs; + QTest::newRow("ts20-ts11-ts20 (utf8)") << "codec-utf8.ts" << tsTs11Ts << noArgs; QTest::newRow("ts20-ts11-ts20 (cp1252)") << "codec-cp1252.ts" << tsTs11Ts << noArgs; QTest::newRow("ts20-ts11-ts20 (dual-encoding)") << "dual-encoding.ts" << tsTs11Ts << noArgs; diff --git a/tests/auto/linguist/lupdate/testdata/good/parsejs/main.js b/tests/auto/linguist/lupdate/testdata/good/parsejs/main.js new file mode 100644 index 0000000..9f61cea --- /dev/null +++ b/tests/auto/linguist/lupdate/testdata/good/parsejs/main.js @@ -0,0 +1,91 @@ +qsTr("One"); +qsTranslate("FooContext", "Two"); + +var greeting_strings = [ + QT_TR_NOOP("Hello"), + QT_TRANSLATE_NOOP("FooContext", "Goodbye") +]; + +qsTr("One", "not the same one"); + +//: My first comment. +qsTr("See comment"); + +//: My second comment. +qsTranslate("BarContext", "See other comment"); + +//: My third comment +//: spans two lines. +qsTr("The comment explains it all"); + +//: My fourth comment +//: spans a whopping +//: three lines. +qsTranslate("BazContext", "It should be clear by now"); + +/*: C-style comment. */ +qsTr("I love C++"); + +/*: Another C-style comment. */ +qsTranslate("FooContext", "I really love C++"); + +/*: C-style comment, followed by */ +/*: another one. */ +qsTr("Qt is the best"); + +/*: Another C-style comment, followed by */ +/*: yet another one. */ +qsTranslate("BarContext", "Qt is the very best"); + +// This comment doesn't have any effect. +qsTr("The comment had no effect"); + +// This comment doesn't have any effect either. +qsTranslate("BazContext", "The comment had no effect, really"); + +/* This C-style comment doesn't have any effect. */ +qsTr("No comment to your comment"); + +/* This C-style comment doesn't have any effect either. */ +qsTranslate("FooContext", "I refuse to comment on that"); + +//= id_foo +qsTr("This string has an identifier"); + +//= id_bar +qsTranslate("BarContext", "This string also has an identifier"); + +//~ loc-blank False +qsTr("This string has meta-data"); + +//~ loc-layout_id foo_dialog +qsTranslate("BazContext", "This string also has meta-data"); + +// This comment is to be ignored. +//: This is a comment for the translator. +//= id_baz +//~ foo 123 +//~ magic-stuff This means something special. +qsTr("This string has a lot of information"); + +// This comment is also to be ignored. +//: This is another comment for the translator. +//= id_babar +//~ foo-bar Important stuff +//~ needle-in-haystack Found +//~ overflow True +qsTranslate("FooContext", "This string has even more information"); + +qsTr("This string has disambiguation", "Disambiguation"); + +qsTranslate("BarContext", "This string also has disambiguation", "Another disambiguation"); + +qsTr("This string contains plurals", "", 10); + +qsTrId("qtn_foo_bar"); + +var more_greeting_strings = [ QT_TRID_NOOP("qtn_needle"), QT_TRID_NOOP("qtn_haystack") ]; + +//: qsTrId() with comment, meta-data and plurals. +//~ well-tested True +qsTrId("qtn_bar_baz", 10); diff --git a/tests/auto/linguist/lupdate/testdata/good/parsejs/project.pro b/tests/auto/linguist/lupdate/testdata/good/parsejs/project.pro new file mode 100644 index 0000000..d549039 --- /dev/null +++ b/tests/auto/linguist/lupdate/testdata/good/parsejs/project.pro @@ -0,0 +1,3 @@ +SOURCES += main.js + +TRANSLATIONS = project.ts diff --git a/tests/auto/linguist/lupdate/testdata/good/parsejs/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/parsejs/project.ts.result new file mode 100644 index 0000000..d03c713 --- /dev/null +++ b/tests/auto/linguist/lupdate/testdata/good/parsejs/project.ts.result @@ -0,0 +1,195 @@ +<?xml version="1.0" encoding="utf-8"?> +<!DOCTYPE TS> +<TS version="2.0"> +<context> + <name></name> + <message id="qtn_foo_bar"> + <location filename="main.js" line="85"/> + <source></source> + <translation type="unfinished"></translation> + </message> + <message id="qtn_needle"> + <location filename="main.js" line="87"/> + <source></source> + <translation type="unfinished"></translation> + </message> + <message id="qtn_haystack"> + <location filename="main.js" line="87"/> + <source></source> + <translation type="unfinished"></translation> + </message> + <message id="qtn_bar_baz" numerus="yes"> + <location filename="main.js" line="91"/> + <source></source> + <extracomment>qsTrId() with comment, meta-data and plurals.</extracomment> + <translation type="unfinished"> + <numerusform></numerusform> + </translation> + <extra-well-tested>True</extra-well-tested> + </message> +</context> +<context> + <name>BarContext</name> + <message> + <location filename="main.js" line="15"/> + <source>See other comment</source> + <extracomment>My second comment.</extracomment> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.js" line="38"/> + <source>Qt is the very best</source> + <extracomment>Another C-style comment, followed by yet another one.</extracomment> + <translation type="unfinished"></translation> + </message> + <message id="id_bar"> + <location filename="main.js" line="56"/> + <source>This string also has an identifier</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.js" line="81"/> + <source>This string also has disambiguation</source> + <comment>Another disambiguation</comment> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>BazContext</name> + <message> + <location filename="main.js" line="24"/> + <source>It should be clear by now</source> + <extracomment>My fourth comment spans a whopping three lines.</extracomment> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.js" line="44"/> + <source>The comment had no effect, really</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.js" line="62"/> + <source>This string also has meta-data</source> + <translation type="unfinished"></translation> + <extra-loc-layout_id>foo_dialog</extra-loc-layout_id> + </message> +</context> +<context> + <name>FooContext</name> + <message> + <location filename="main.js" line="2"/> + <source>Two</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.js" line="6"/> + <source>Goodbye</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.js" line="30"/> + <source>I really love C++</source> + <extracomment>Another C-style comment.</extracomment> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.js" line="50"/> + <source>I refuse to comment on that</source> + <translation type="unfinished"></translation> + </message> + <message id="id_babar"> + <location filename="main.js" line="77"/> + <source>This string has even more information</source> + <extracomment>This is another comment for the translator.</extracomment> + <translation type="unfinished"></translation> + <extra-needle-in-haystack>Found</extra-needle-in-haystack> + <extra-overflow>True</extra-overflow> + <extra-foo-bar>Important stuff</extra-foo-bar> + </message> +</context> +<context> + <name>main</name> + <message> + <location filename="main.js" line="1"/> + <source>One</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.js" line="5"/> + <source>Hello</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.js" line="9"/> + <source>One</source> + <comment>not the same one</comment> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.js" line="12"/> + <source>See comment</source> + <extracomment>My first comment.</extracomment> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.js" line="19"/> + <source>The comment explains it all</source> + <extracomment>My third comment spans two lines.</extracomment> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.js" line="27"/> + <source>I love C++</source> + <extracomment>C-style comment.</extracomment> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.js" line="34"/> + <source>Qt is the best</source> + <extracomment>C-style comment, followed by another one.</extracomment> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.js" line="41"/> + <source>The comment had no effect</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.js" line="47"/> + <source>No comment to your comment</source> + <translation type="unfinished"></translation> + </message> + <message id="id_foo"> + <location filename="main.js" line="53"/> + <source>This string has an identifier</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.js" line="59"/> + <source>This string has meta-data</source> + <translation type="unfinished"></translation> + <extra-loc-blank>False</extra-loc-blank> + </message> + <message id="id_baz"> + <location filename="main.js" line="69"/> + <source>This string has a lot of information</source> + <extracomment>This is a comment for the translator.</extracomment> + <translation type="unfinished"></translation> + <extra-foo>123</extra-foo> + <extra-magic-stuff>This means something special.</extra-magic-stuff> + </message> + <message> + <location filename="main.js" line="79"/> + <source>This string has disambiguation</source> + <comment>Disambiguation</comment> + <translation type="unfinished"></translation> + </message> + <message numerus="yes"> + <location filename="main.js" line="83"/> + <source>This string contains plurals</source> + <translation type="unfinished"> + <numerusform></numerusform> + </translation> + </message> +</context> +</TS> diff --git a/tests/auto/linguist/lupdate/testdata/good/parsejs2/expectedoutput.txt b/tests/auto/linguist/lupdate/testdata/good/parsejs2/expectedoutput.txt new file mode 100644 index 0000000..d6c977f --- /dev/null +++ b/tests/auto/linguist/lupdate/testdata/good/parsejs2/expectedoutput.txt @@ -0,0 +1,29 @@ +.*/lupdate/testdata/good/parsejs2/main.js:3: qsTranslate\(\) requires at least two arguments. +.*/lupdate/testdata/good/parsejs2/main.js:4: qsTranslate\(\) requires at least two arguments. +.*/lupdate/testdata/good/parsejs2/main.js:5: qsTranslate\(\): both arguments must be literal strings. +.*/lupdate/testdata/good/parsejs2/main.js:6: qsTranslate\(\): both arguments must be literal strings. +.*/lupdate/testdata/good/parsejs2/main.js:7: qsTranslate\(\): both arguments must be literal strings. +.*/lupdate/testdata/good/parsejs2/main.js:9: QT_TRANSLATE_NOOP\(\) requires at least two arguments. +.*/lupdate/testdata/good/parsejs2/main.js:10: QT_TRANSLATE_NOOP\(\) requires at least two arguments. +.*/lupdate/testdata/good/parsejs2/main.js:11: QT_TRANSLATE_NOOP\(\): both arguments must be literal strings. +.*/lupdate/testdata/good/parsejs2/main.js:12: QT_TRANSLATE_NOOP\(\): both arguments must be literal strings. +.*/lupdate/testdata/good/parsejs2/main.js:13: QT_TRANSLATE_NOOP\(\): both arguments must be literal strings. +.*/lupdate/testdata/good/parsejs2/main.js:15: qsTr\(\) requires at least one argument. +.*/lupdate/testdata/good/parsejs2/main.js:16: qsTr\(\): text to translate must be a literal string. +.*/lupdate/testdata/good/parsejs2/main.js:18: QT_TR_NOOP\(\) requires at least one argument. +.*/lupdate/testdata/good/parsejs2/main.js:19: QT_TR_NOOP\(\): text to translate must be a literal string. +.*/lupdate/testdata/good/parsejs2/main.js:21: qsTrId\(\) requires at least one argument. +.*/lupdate/testdata/good/parsejs2/main.js:22: qsTrId\(\): identifier must be a literal string. +.*/lupdate/testdata/good/parsejs2/main.js:24: QT_TRID_NOOP\(\) requires at least one argument. +.*/lupdate/testdata/good/parsejs2/main.js:25: QT_TRID_NOOP\(\): identifier must be a literal string. +.*/lupdate/testdata/good/parsejs2/main.js:27: Unexpected character in meta string +.*/lupdate/testdata/good/parsejs2/main.js:28: Unexpected character in meta string +.*/lupdate/testdata/good/parsejs2/main.js:29: Unterminated meta string +.*/lupdate/testdata/good/parsejs2/main.js:30: Unterminated meta string +.*/lupdate/testdata/good/parsejs2/main.js:33: //% cannot be used with qsTranslate\(\). Ignoring +.*/lupdate/testdata/good/parsejs2/main.js:35: //% cannot be used with QT_TRANSLATE_NOOP\(\). Ignoring +.*/lupdate/testdata/good/parsejs2/main.js:37: //% cannot be used with qsTr\(\). Ignoring +.*/lupdate/testdata/good/parsejs2/main.js:39: //% cannot be used with QT_TR_NOOP\(\). Ignoring +.*/lupdate/testdata/good/parsejs2/main.js:42: Discarding unconsumed meta data +.*/lupdate/testdata/good/parsejs2/main.js:44: Discarding unconsumed meta data +.*/lupdate/testdata/good/parsejs2/main.js:46: Discarding unconsumed meta data diff --git a/tests/auto/linguist/lupdate/testdata/good/parsejs2/main.js b/tests/auto/linguist/lupdate/testdata/good/parsejs2/main.js new file mode 100644 index 0000000..ea02957 --- /dev/null +++ b/tests/auto/linguist/lupdate/testdata/good/parsejs2/main.js @@ -0,0 +1,56 @@ +// This script exercises lupdate errors and warnings. + +qsTranslate(); +qsTranslate(10); +qsTranslate(10, 20); +qsTranslate("10", 20); +qsTranslate(10, "20"); + +QT_TRANSLATE_NOOP(); +QT_TRANSLATE_NOOP(10); +QT_TRANSLATE_NOOP(10, 20); +QT_TRANSLATE_NOOP("10", 20); +QT_TRANSLATE_NOOP(10, "20"); + +qsTr(); +qsTr(10); + +QT_TR_NOOP(); +QT_TR_NOOP(10); + +qsTrId(); +qsTrId(10); + +QT_TRID_NOOP(); +QT_TRID_NOOP(10); + +//% This is wrong +//% "This is not wrong" This is wrong +//% "I forgot to close the meta string +//% "Being evil \ + +//% "Should cause a warning" +qsTranslate("FooContext", "Hello"); +//% "Should cause a warning" +QT_TRANSLATE_NOOP("FooContext", "World"); +//% "Should cause a warning" +qsTr("Hello"); +//% "Should cause a warning" +QT_TR_NOOP("World"); + +//: This comment will be discarded. +Math.sin(1); +//= id_foobar +Math.cos(2); +//~ underflow False +Math.tan(3); + +/* +Not tested for now, because these should perhaps not cause +translation entries to be generated at all; see QTBUG-11843. + +//= qtn_foo +qsTrId("qtn_foo"); +//= qtn_bar +QT_TRID_NOOP("qtn_bar"); +*/ diff --git a/tests/auto/linguist/lupdate/testdata/good/parsejs2/project.pro b/tests/auto/linguist/lupdate/testdata/good/parsejs2/project.pro new file mode 100644 index 0000000..d549039 --- /dev/null +++ b/tests/auto/linguist/lupdate/testdata/good/parsejs2/project.pro @@ -0,0 +1,3 @@ +SOURCES += main.js + +TRANSLATIONS = project.ts diff --git a/tests/auto/linguist/lupdate/testdata/good/parsejs2/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/parsejs2/project.ts.result new file mode 100644 index 0000000..bfa1b3d --- /dev/null +++ b/tests/auto/linguist/lupdate/testdata/good/parsejs2/project.ts.result @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8"?> +<!DOCTYPE TS> +<TS version="2.0"> +<context> + <name>FooContext</name> + <message> + <location filename="main.js" line="33"/> + <source>Hello</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.js" line="35"/> + <source>World</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>main</name> + <message> + <location filename="main.js" line="37"/> + <source>Hello</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.js" line="39"/> + <source>World</source> + <translation type="unfinished"></translation> + </message> +</context> +</TS> diff --git a/tests/auto/linguist/lupdate/testdata/good/parseqml/main.qml b/tests/auto/linguist/lupdate/testdata/good/parseqml/main.qml new file mode 100644 index 0000000..172bd65 --- /dev/null +++ b/tests/auto/linguist/lupdate/testdata/good/parseqml/main.qml @@ -0,0 +1,97 @@ +import Qt 4.7 + +QtObject { + function translate() { + qsTr("One"); + qsTranslate("FooContext", "Two"); + + var greeting_strings = [ + QT_TR_NOOP("Hello"), + QT_TRANSLATE_NOOP("FooContext", "Goodbye") + ]; + + qsTr("One", "not the same one"); + + //: My first comment. + qsTr("See comment"); + + //: My second comment. + qsTranslate("BarContext", "See other comment"); + + //: My third comment + //: spans two lines. + qsTr("The comment explains it all"); + + //: My fourth comment + //: spans a whopping + //: three lines. + qsTranslate("BazContext", "It should be clear by now"); + + /*: C-style comment. */ + qsTr("I love C++"); + + /*: Another C-style comment. */ + qsTranslate("FooContext", "I really love C++"); + + /*: C-style comment, followed by */ + /*: another one. */ + qsTr("Qt is the best"); + + /*: Another C-style comment, followed by */ + /*: yet another one. */ + qsTranslate("BarContext", "Qt is the very best"); + + // This comment doesn't have any effect. + qsTr("The comment had no effect"); + + // This comment doesn't have any effect either. + qsTranslate("BazContext", "The comment had no effect, really"); + + /* This C-style comment doesn't have any effect. */ + qsTr("No comment to your comment"); + + /* This C-style comment doesn't have any effect either. */ + qsTranslate("FooContext", "I refuse to comment on that"); + + //= id_foo + qsTr("This string has an identifier"); + + //= id_bar + qsTranslate("BarContext", "This string also has an identifier"); + + //~ loc-blank False + qsTr("This string has meta-data"); + + //~ loc-layout_id foo_dialog + qsTranslate("BazContext", "This string also has meta-data"); + + // This comment is to be ignored. + //: This is a comment for the translator. + //= id_baz + //~ foo 123 + //~ magic-stuff This means something special. + qsTr("This string has a lot of information"); + + // This comment is also to be ignored. + //: This is another comment for the translator. + //= id_babar + //~ foo-bar Important stuff + //~ needle-in-haystack Found + //~ overflow True + qsTranslate("FooContext", "This string has even more information"); + + qsTr("This string has disambiguation", "Disambiguation"); + + qsTranslate("BarContext", "This string also has disambiguation", "Another disambiguation"); + + qsTr("This string contains plurals", "", 10); + + qsTrId("qtn_foo_bar"); + + var more_greeting_strings = [ QT_TRID_NOOP("qtn_needle"), QT_TRID_NOOP("qtn_haystack") ]; + + //: qsTrId() with comment, meta-data and plurals. + //~ well-tested True + qsTrId("qtn_bar_baz", 10); + } +} diff --git a/tests/auto/linguist/lupdate/testdata/good/parseqml/project.pro b/tests/auto/linguist/lupdate/testdata/good/parseqml/project.pro new file mode 100644 index 0000000..1040e22 --- /dev/null +++ b/tests/auto/linguist/lupdate/testdata/good/parseqml/project.pro @@ -0,0 +1,3 @@ +SOURCES += main.qml + +TRANSLATIONS = project.ts diff --git a/tests/auto/linguist/lupdate/testdata/good/parseqml/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/parseqml/project.ts.result new file mode 100644 index 0000000..7dac8cb --- /dev/null +++ b/tests/auto/linguist/lupdate/testdata/good/parseqml/project.ts.result @@ -0,0 +1,195 @@ +<?xml version="1.0" encoding="utf-8"?> +<!DOCTYPE TS> +<TS version="2.0"> +<context> + <name></name> + <message id="qtn_foo_bar"> + <location filename="main.qml" line="89"/> + <source></source> + <translation type="unfinished"></translation> + </message> + <message id="qtn_needle"> + <location filename="main.qml" line="91"/> + <source></source> + <translation type="unfinished"></translation> + </message> + <message id="qtn_haystack"> + <location filename="main.qml" line="91"/> + <source></source> + <translation type="unfinished"></translation> + </message> + <message id="qtn_bar_baz" numerus="yes"> + <location filename="main.qml" line="95"/> + <source></source> + <extracomment>qsTrId() with comment, meta-data and plurals.</extracomment> + <translation type="unfinished"> + <numerusform></numerusform> + </translation> + <extra-well-tested>True</extra-well-tested> + </message> +</context> +<context> + <name>BarContext</name> + <message> + <location filename="main.qml" line="19"/> + <source>See other comment</source> + <extracomment>My second comment.</extracomment> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.qml" line="42"/> + <source>Qt is the very best</source> + <extracomment>Another C-style comment, followed by yet another one.</extracomment> + <translation type="unfinished"></translation> + </message> + <message id="id_bar"> + <location filename="main.qml" line="60"/> + <source>This string also has an identifier</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.qml" line="85"/> + <source>This string also has disambiguation</source> + <comment>Another disambiguation</comment> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>BazContext</name> + <message> + <location filename="main.qml" line="28"/> + <source>It should be clear by now</source> + <extracomment>My fourth comment spans a whopping three lines.</extracomment> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.qml" line="48"/> + <source>The comment had no effect, really</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.qml" line="66"/> + <source>This string also has meta-data</source> + <translation type="unfinished"></translation> + <extra-loc-layout_id>foo_dialog</extra-loc-layout_id> + </message> +</context> +<context> + <name>FooContext</name> + <message> + <location filename="main.qml" line="6"/> + <source>Two</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.qml" line="10"/> + <source>Goodbye</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.qml" line="34"/> + <source>I really love C++</source> + <extracomment>Another C-style comment.</extracomment> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.qml" line="54"/> + <source>I refuse to comment on that</source> + <translation type="unfinished"></translation> + </message> + <message id="id_babar"> + <location filename="main.qml" line="81"/> + <source>This string has even more information</source> + <extracomment>This is another comment for the translator.</extracomment> + <translation type="unfinished"></translation> + <extra-needle-in-haystack>Found</extra-needle-in-haystack> + <extra-overflow>True</extra-overflow> + <extra-foo-bar>Important stuff</extra-foo-bar> + </message> +</context> +<context> + <name>main</name> + <message> + <location filename="main.qml" line="5"/> + <source>One</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.qml" line="9"/> + <source>Hello</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.qml" line="13"/> + <source>One</source> + <comment>not the same one</comment> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.qml" line="16"/> + <source>See comment</source> + <extracomment>My first comment.</extracomment> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.qml" line="23"/> + <source>The comment explains it all</source> + <extracomment>My third comment spans two lines.</extracomment> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.qml" line="31"/> + <source>I love C++</source> + <extracomment>C-style comment.</extracomment> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.qml" line="38"/> + <source>Qt is the best</source> + <extracomment>C-style comment, followed by another one.</extracomment> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.qml" line="45"/> + <source>The comment had no effect</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.qml" line="51"/> + <source>No comment to your comment</source> + <translation type="unfinished"></translation> + </message> + <message id="id_foo"> + <location filename="main.qml" line="57"/> + <source>This string has an identifier</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.qml" line="63"/> + <source>This string has meta-data</source> + <translation type="unfinished"></translation> + <extra-loc-blank>False</extra-loc-blank> + </message> + <message id="id_baz"> + <location filename="main.qml" line="73"/> + <source>This string has a lot of information</source> + <extracomment>This is a comment for the translator.</extracomment> + <translation type="unfinished"></translation> + <extra-foo>123</extra-foo> + <extra-magic-stuff>This means something special.</extra-magic-stuff> + </message> + <message> + <location filename="main.qml" line="83"/> + <source>This string has disambiguation</source> + <comment>Disambiguation</comment> + <translation type="unfinished"></translation> + </message> + <message numerus="yes"> + <location filename="main.qml" line="87"/> + <source>This string contains plurals</source> + <translation type="unfinished"> + <numerusform></numerusform> + </translation> + </message> +</context> +</TS> diff --git a/tests/auto/qabstractitemmodel/tst_qabstractitemmodel.cpp b/tests/auto/qabstractitemmodel/tst_qabstractitemmodel.cpp index 6f158f0..dbcccc9 100644 --- a/tests/auto/qabstractitemmodel/tst_qabstractitemmodel.cpp +++ b/tests/auto/qabstractitemmodel/tst_qabstractitemmodel.cpp @@ -1208,6 +1208,7 @@ void tst_QAbstractItemModel::testMoveToGrandParent() QSignalSpy beforeSpy(m_model, SIGNAL(rowsAboutToBeMoved(const QModelIndex &, int, int, const QModelIndex &, int))); QSignalSpy afterSpy(m_model, SIGNAL(rowsMoved(const QModelIndex &, int, int, const QModelIndex &, int))); + QPersistentModelIndex persistentSource = sourceIndex; ModelMoveCommand *moveCommand = new ModelMoveCommand(m_model, this); moveCommand->setAncestorRowNumbers(QList<int>() << 5); @@ -1228,7 +1229,7 @@ void tst_QAbstractItemModel::testMoveToGrandParent() QCOMPARE(beforeSignal.at(4).toInt(), destRow); QCOMPARE(afterSignal.size(), 5); - QCOMPARE(afterSignal.at(0).value<QModelIndex>(), sourceIndex); + QCOMPARE(afterSignal.at(0).value<QModelIndex>(), static_cast<QModelIndex>(persistentSource)); QCOMPARE(afterSignal.at(1).toInt(), startRow); QCOMPARE(afterSignal.at(2).toInt(), endRow); QCOMPARE(afterSignal.at(3).value<QModelIndex>(), QModelIndex()); @@ -1351,6 +1352,7 @@ void tst_QAbstractItemModel::testMoveToSibling() QSignalSpy beforeSpy(m_model, SIGNAL(rowsAboutToBeMoved(const QModelIndex &, int, int, const QModelIndex &, int))); QSignalSpy afterSpy(m_model, SIGNAL(rowsMoved(const QModelIndex &, int, int, const QModelIndex &, int))); + QPersistentModelIndex persistentDest = destIndex; ModelMoveCommand *moveCommand = new ModelMoveCommand(m_model, this); moveCommand->setNumCols(4); @@ -1374,7 +1376,7 @@ void tst_QAbstractItemModel::testMoveToSibling() QCOMPARE(afterSignal.at(0).value<QModelIndex>(), sourceIndex); QCOMPARE(afterSignal.at(1).toInt(), startRow); QCOMPARE(afterSignal.at(2).toInt(), endRow); - QCOMPARE(afterSignal.at(3).value<QModelIndex>(), destIndex); + QCOMPARE(afterSignal.at(3).value<QModelIndex>(), static_cast<QModelIndex>(persistentDest)); QCOMPARE(afterSignal.at(4).toInt(), destRow); for (int i = 0; i < indexList.size(); i++) diff --git a/tests/auto/qdbusthreading/tst_qdbusthreading.cpp b/tests/auto/qdbusthreading/tst_qdbusthreading.cpp index 94771a8..9d96ad8 100644 --- a/tests/auto/qdbusthreading/tst_qdbusthreading.cpp +++ b/tests/auto/qdbusthreading/tst_qdbusthreading.cpp @@ -70,7 +70,12 @@ public: QSemaphore sem1, sem2; volatile bool success; QEventLoop *loop; - const char *functionSpy; + enum FunctionSpy { + NoMethod = 0, + Adaptor_method, + Object_method + } functionSpy; + QThread *threadSpy; int signalSpy; @@ -127,7 +132,7 @@ public: public Q_SLOTS: void method() { - tst_QDBusThreading::self()->functionSpy = Q_FUNC_INFO; + tst_QDBusThreading::self()->functionSpy = tst_QDBusThreading::Adaptor_method; tst_QDBusThreading::self()->threadSpy = QThread::currentThread(); emit signal(); } @@ -155,7 +160,7 @@ public: public Q_SLOTS: void method() { - tst_QDBusThreading::self()->functionSpy = Q_FUNC_INFO; + tst_QDBusThreading::self()->functionSpy = tst_QDBusThreading::Object_method; tst_QDBusThreading::self()->threadSpy = QThread::currentThread(); emit signal(); deleteLater(); @@ -198,7 +203,7 @@ void Thread::run() static const char myConnectionName[] = "connection"; tst_QDBusThreading::tst_QDBusThreading() - : loop(0), functionSpy(0), threadSpy(0) + : loop(0), functionSpy(NoMethod), threadSpy(0) { _self = this; QCoreApplication::instance()->thread()->setObjectName("Main thread"); @@ -420,22 +425,22 @@ void tst_QDBusThreading::registerObjectInOtherThread() QTest::qWait(100); QCOMPARE(signalSpy, 0); - functionSpy = 0; + functionSpy = NoMethod; threadSpy = 0; QDBusReply<void> reply = iface.call("method"); QVERIFY(reply.isValid()); - QCOMPARE(functionSpy, "void Object::method()"); + QCOMPARE(functionSpy, Object_method); QCOMPARE(threadSpy, th); QTest::qWait(100); QCOMPARE(signalSpy, 1); sem2.acquire(); // the object is gone - functionSpy = 0; + functionSpy = NoMethod; threadSpy = 0; reply = iface.call("method"); QVERIFY(!reply.isValid()); - QCOMPARE(functionSpy, (const char*)0); + QCOMPARE(functionSpy, NoMethod); QCOMPARE(threadSpy, (QThread*)0); } @@ -468,36 +473,36 @@ void tst_QDBusThreading::registerAdaptorInOtherThread() connect(&adaptor, SIGNAL(signal()), SLOT(signalSpySlot())); QCOMPARE(signalSpy, 0); - functionSpy = 0; + functionSpy = NoMethod; threadSpy = 0; QDBusReply<void> reply = adaptor.call("method"); QVERIFY(reply.isValid()); - QCOMPARE(functionSpy, "void Adaptor::method()"); + QCOMPARE(functionSpy, Adaptor_method); QCOMPARE(threadSpy, th); QTest::qWait(100); QCOMPARE(signalSpy, 1); - functionSpy = 0; + functionSpy = NoMethod; threadSpy = 0; reply = object.call("method"); QVERIFY(reply.isValid()); - QCOMPARE(functionSpy, "void Object::method()"); + QCOMPARE(functionSpy, Object_method); QCOMPARE(threadSpy, th); QTest::qWait(100); QCOMPARE(signalSpy, 1); sem2.acquire(); // the object is gone - functionSpy = 0; + functionSpy = NoMethod; threadSpy = 0; reply = adaptor.call("method"); QVERIFY(!reply.isValid()); - QCOMPARE(functionSpy, (const char*)0); + QCOMPARE(functionSpy, NoMethod); QCOMPARE(threadSpy, (QThread*)0); reply = object.call("method"); QVERIFY(!reply.isValid()); - QCOMPARE(functionSpy, (const char*)0); + QCOMPARE(functionSpy, NoMethod); QCOMPARE(threadSpy, (QThread*)0); } diff --git a/tests/auto/qdir/tst_qdir.cpp b/tests/auto/qdir/tst_qdir.cpp index 661a4c7..9678868 100644 --- a/tests/auto/qdir/tst_qdir.cpp +++ b/tests/auto/qdir/tst_qdir.cpp @@ -173,6 +173,8 @@ private slots: void updateFileLists(); + void detachingOperations(); + #if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) void isRoot_data(); void isRoot(); @@ -1561,6 +1563,103 @@ void tst_QDir::updateFileLists() QCOMPARE(dir.entryList(), QStringList() << "sub-dir1" << "sub-dir2" << "file1.txt"); } +void tst_QDir::detachingOperations() +{ + QString const defaultPath("."); + QStringList const defaultNameFilters = QStringList("*"); + QDir::SortFlags const defaultSorting = QDir::Name | QDir::IgnoreCase; + QDir::Filters const defaultFilter = QDir::AllEntries; + + QString const path1(".."); + QString const path2("./foo"); + QStringList const nameFilters = QStringList(QString("*.txt")); + QDir::SortFlags const sorting = QDir::Name | QDir::DirsLast | QDir::Reversed; + QDir::Filters const filter = QDir::Writable; + + QDir dir1; + + QCOMPARE(dir1.path(), defaultPath); + QCOMPARE(dir1.filter(), defaultFilter); + QCOMPARE(dir1.nameFilters(), defaultNameFilters); + QCOMPARE(dir1.sorting(), defaultSorting); + + dir1.setPath(path1); + QCOMPARE(dir1.path(), path1); + QCOMPARE(dir1.filter(), defaultFilter); + QCOMPARE(dir1.nameFilters(), defaultNameFilters); + QCOMPARE(dir1.sorting(), defaultSorting); + + dir1.setFilter(filter); + QCOMPARE(dir1.path(), path1); + QCOMPARE(dir1.filter(), filter); + QCOMPARE(dir1.nameFilters(), defaultNameFilters); + QCOMPARE(dir1.sorting(), defaultSorting); + + dir1.setNameFilters(nameFilters); + QCOMPARE(dir1.path(), path1); + QCOMPARE(dir1.filter(), filter); + QCOMPARE(dir1.nameFilters(), nameFilters); + QCOMPARE(dir1.sorting(), defaultSorting); + + dir1.setSorting(sorting); + QCOMPARE(dir1.path(), path1); + QCOMPARE(dir1.filter(), filter); + QCOMPARE(dir1.nameFilters(), nameFilters); + QCOMPARE(dir1.sorting(), sorting); + + dir1.setPath(path2); + QCOMPARE(dir1.path(), path2); + QCOMPARE(dir1.filter(), filter); + QCOMPARE(dir1.nameFilters(), nameFilters); + QCOMPARE(dir1.sorting(), sorting); + + { + QDir dir2(dir1); + QCOMPARE(dir2.path(), path2); + QCOMPARE(dir2.filter(), filter); + QCOMPARE(dir2.nameFilters(), nameFilters); + QCOMPARE(dir2.sorting(), sorting); + } + + { + QDir dir2; + QCOMPARE(dir2.path(), defaultPath); + QCOMPARE(dir2.filter(), defaultFilter); + QCOMPARE(dir2.nameFilters(), defaultNameFilters); + QCOMPARE(dir2.sorting(), defaultSorting); + + dir2 = dir1; + QCOMPARE(dir2.path(), path2); + QCOMPARE(dir2.filter(), filter); + QCOMPARE(dir2.nameFilters(), nameFilters); + QCOMPARE(dir2.sorting(), sorting); + + dir2 = path1; + QCOMPARE(dir2.path(), path1); + QCOMPARE(dir2.filter(), filter); + QCOMPARE(dir2.nameFilters(), nameFilters); + QCOMPARE(dir2.sorting(), sorting); + } + + dir1.refresh(); + QCOMPARE(dir1.path(), path2); + QCOMPARE(dir1.filter(), filter); + QCOMPARE(dir1.nameFilters(), nameFilters); + QCOMPARE(dir1.sorting(), sorting); + + QString const currentPath = QDir::currentPath(); + QVERIFY(dir1.cd(currentPath)); + QCOMPARE(dir1.path(), currentPath); + QCOMPARE(dir1.filter(), filter); + QCOMPARE(dir1.nameFilters(), nameFilters); + QCOMPARE(dir1.sorting(), sorting); + + QVERIFY(dir1.cdUp()); + QCOMPARE(dir1.filter(), filter); + QCOMPARE(dir1.nameFilters(), nameFilters); + QCOMPARE(dir1.sorting(), sorting); +} + #if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) void tst_QDir::isRoot_data() { diff --git a/tests/auto/qeasingcurve/tst_qeasingcurve.cpp b/tests/auto/qeasingcurve/tst_qeasingcurve.cpp index 124f900..2411ab6 100644 --- a/tests/auto/qeasingcurve/tst_qeasingcurve.cpp +++ b/tests/auto/qeasingcurve/tst_qeasingcurve.cpp @@ -153,19 +153,19 @@ void tst_QEasingCurve::propertyDefaults() QEasingCurve curve(QEasingCurve::InElastic); QCOMPARE(curve.period(), 0.3); QCOMPARE(curve.amplitude(), 1.0); - QCOMPARE(curve.overshoot(), qreal(1.70158f)); + QCOMPARE(curve.overshoot(), qreal(1.70158)); curve.setType(QEasingCurve::InBounce); QCOMPARE(curve.period(), 0.3); QCOMPARE(curve.amplitude(), 1.0); - QCOMPARE(curve.overshoot(), qreal(1.70158f)); + QCOMPARE(curve.overshoot(), qreal(1.70158)); curve.setType(QEasingCurve::Linear); QCOMPARE(curve.period(), 0.3); QCOMPARE(curve.amplitude(), 1.0); - QCOMPARE(curve.overshoot(), qreal(1.70158f)); + QCOMPARE(curve.overshoot(), qreal(1.70158)); curve.setType(QEasingCurve::InElastic); QCOMPARE(curve.period(), 0.3); QCOMPARE(curve.amplitude(), 1.0); - QCOMPARE(curve.overshoot(), qreal(1.70158f)); + QCOMPARE(curve.overshoot(), qreal(1.70158)); curve.setPeriod(0.4); curve.setAmplitude(0.6); curve.setOvershoot(1.0); @@ -490,7 +490,7 @@ void tst_QEasingCurve::operators() // operator== curve.setType(QEasingCurve::InBack); curve2 = curve; - curve2.setOvershoot(qreal(1.70158f)); + curve2.setOvershoot(qreal(1.70158)); QCOMPARE(curve.overshoot(), curve2.overshoot()); QVERIFY(curve2 == curve); @@ -505,6 +505,15 @@ void tst_QEasingCurve::operators() curve2.setType(QEasingCurve::InBack); QCOMPARE(curve.overshoot(), curve2.overshoot()); QVERIFY(curve2 == curve); + + QEasingCurve curve3; + QEasingCurve curve4; + curve4.setAmplitude(curve4.amplitude()); + QEasingCurve curve5; + curve5.setAmplitude(0.12345); + QVERIFY(curve3 == curve4); // default value and not assigned + QVERIFY(curve3 != curve5); // unassinged and other value + QVERIFY(curve4 != curve5); } class tst_QEasingProperties : public QObject @@ -527,7 +536,7 @@ void tst_QEasingCurve::properties() tst_QEasingProperties obj; QEasingCurve inOutBack(QEasingCurve::InOutBack); - qreal overshoot = 1.5f; + qreal overshoot = 1.5; inOutBack.setOvershoot(overshoot); qreal amplitude = inOutBack.amplitude(); qreal period = inOutBack.period(); diff --git a/tests/auto/qfileinfo/tst_qfileinfo.cpp b/tests/auto/qfileinfo/tst_qfileinfo.cpp index a074f4b..7659a75 100644 --- a/tests/auto/qfileinfo/tst_qfileinfo.cpp +++ b/tests/auto/qfileinfo/tst_qfileinfo.cpp @@ -181,6 +181,8 @@ private slots: void equalOperator() const; void equalOperatorWithDifferentSlashes() const; void notEqualOperator() const; + + void detachingOperations(); }; tst_QFileInfo::tst_QFileInfo() @@ -247,13 +249,13 @@ void tst_QFileInfo::copy() QFileInfo info2(info); QFileInfoPrivate *privateInfo = getPrivate(info); QFileInfoPrivate *privateInfo2 = getPrivate(info2); - QCOMPARE(privateInfo->data, privateInfo2->data); + QCOMPARE(privateInfo, privateInfo2); //operator = QFileInfo info3 = info; QFileInfoPrivate *privateInfo3 = getPrivate(info3); - QCOMPARE(privateInfo->data, privateInfo3->data); - QCOMPARE(privateInfo2->data, privateInfo3->data); + QCOMPARE(privateInfo, privateInfo3); + QCOMPARE(privateInfo2, privateInfo3); //refreshing info3 will detach it QFile file(info.absoluteFilePath()); @@ -275,9 +277,10 @@ void tst_QFileInfo::copy() QTest::qWait(5000); #endif info3.refresh(); - QVERIFY(privateInfo->data != privateInfo3->data); - QVERIFY(privateInfo2->data != privateInfo3->data); - QCOMPARE(privateInfo->data, privateInfo2->data); + privateInfo3 = getPrivate(info3); + QVERIFY(privateInfo != privateInfo3); + QVERIFY(privateInfo2 != privateInfo3); + QCOMPARE(privateInfo, privateInfo2); } void tst_QFileInfo::isFile_data() @@ -1241,8 +1244,8 @@ void tst_QFileInfo::isLocalFs() QFileInfo info(path); QFileInfoPrivate *privateInfo = getPrivate(info); - QVERIFY(privateInfo->data->fileEngine); - QCOMPARE(bool(privateInfo->data->fileEngine->fileFlags(QAbstractFileEngine::LocalDiskFlag) + QVERIFY(privateInfo->fileEngine); + QCOMPARE(bool(privateInfo->fileEngine->fileFlags(QAbstractFileEngine::LocalDiskFlag) & QAbstractFileEngine::LocalDiskFlag), isLocalFs); } @@ -1544,5 +1547,51 @@ void tst_QFileInfo::notEqualOperator() const QVERIFY(QFileInfo() != QFileInfo()); } +void tst_QFileInfo::detachingOperations() +{ + QFileInfo info1; + QVERIFY(info1.caching()); + info1.setCaching(false); + + { + QFileInfo info2 = info1; + + QVERIFY(!info1.caching()); + QVERIFY(!info2.caching()); + + info2.setCaching(true); + QVERIFY(info2.caching()); + + info1.setFile("foo"); + QVERIFY(!info1.caching()); + } + + { + QFile file("foo"); + info1.setFile(file); + QVERIFY(!info1.caching()); + } + + info1.setFile(QDir(), "foo"); + QVERIFY(!info1.caching()); + + { + QFileInfo info3; + QVERIFY(info3.caching()); + + info3 = info1; + QVERIFY(!info3.caching()); + } + + info1.refresh(); + QVERIFY(!info1.caching()); + + QVERIFY(info1.makeAbsolute()); + QVERIFY(!info1.caching()); + + info1.detach(); + QVERIFY(!info1.caching()); +} + QTEST_MAIN(tst_QFileInfo) #include "tst_qfileinfo.moc" diff --git a/tests/auto/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp b/tests/auto/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp index 7346f07..82af71f 100644 --- a/tests/auto/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp +++ b/tests/auto/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp @@ -109,6 +109,7 @@ private slots: void styleInfoLeak(); void task236367_maxSizeHint(); void heightForWidth(); + void widthForHeight(); }; class RectWidget : public QGraphicsWidget @@ -225,9 +226,10 @@ struct ItemDesc return (*this); } - ItemDesc &heightForWidth(QSizeF (*fnConstraint)(Qt::SizeHint, const QSizeF &)) { + ItemDesc &dynamicConstraint(QSizeF (*fnConstraint)(Qt::SizeHint, const QSizeF &), + Qt::Orientation orientation) { m_fnConstraint = fnConstraint; - m_constraintOrientation = Qt::Vertical; + m_constraintOrientation = orientation; return (*this); } @@ -235,7 +237,7 @@ struct ItemDesc QSizePolicy sp = m_sizePolicy; if (m_fnConstraint) { sp.setHeightForWidth(m_constraintOrientation == Qt::Vertical); - //sp.setWidthForHeight(m_constraintOrientation == Qt::Horizontal); + sp.setWidthForHeight(m_constraintOrientation == Qt::Horizontal); } item->setSizePolicy(sp); @@ -2174,10 +2176,50 @@ void tst_QGraphicsGridLayout::alignment2() static QSizeF hfw1(Qt::SizeHint, const QSizeF &constraint) { QSizeF result(constraint); - if (constraint.width() < 0 && constraint.height() < 0) { + const qreal ch = constraint.height(); + const qreal cw = constraint.width(); + if (cw < 0 && ch < 0) { return QSizeF(50, 400); - } else if (constraint.width() >= 0) { - result.setHeight(20000./constraint.width()); + } else if (cw > 0) { + result.setHeight(20000./cw); + } + return result; +} + +static QSizeF wfh1(Qt::SizeHint, const QSizeF &constraint) +{ + QSizeF result(constraint); + const qreal ch = constraint.height(); + const qreal cw = constraint.width(); + if (cw < 0 && ch < 0) { + return QSizeF(400, 50); + } else if (ch > 0) { + result.setWidth(20000./ch); + } + return result; +} + +static QSizeF wfh2(Qt::SizeHint, const QSizeF &constraint) +{ + QSizeF result(constraint); + const qreal ch = constraint.height(); + const qreal cw = constraint.width(); + if (ch < 0 && cw < 0) + return QSizeF(50, 50); + if (ch >= 0) + result.setWidth(ch); + return result; +} + +static QSizeF hfw3(Qt::SizeHint, const QSizeF &constraint) +{ + QSizeF result(constraint); + const qreal ch = constraint.height(); + const qreal cw = constraint.width(); + if (cw < 0 && ch < 0) { + return QSizeF(10, 10); + } else if (cw > 0) { + result.setHeight(100./cw); } return result; } @@ -2212,7 +2254,7 @@ void tst_QGraphicsGridLayout::geometries_data() ); // change layout height and verify - QTest::newRow("hfw-h401") << (ItemList() + QTest::newRow("hfw-100x401") << (ItemList() << ItemDesc(0,0) .minSize(QSizeF(1,1)) .preferredSize(QSizeF(50,10)) @@ -2229,7 +2271,7 @@ void tst_QGraphicsGridLayout::geometries_data() .minSize(QSizeF(40,40)) .preferredSize(QSizeF(50,400)) .maxSize(QSizeF(500, 500)) - .heightForWidth(hfw1) + .dynamicConstraint(hfw1, Qt::Vertical) ) << QSizeF(100, 401) << (RectList() @@ -2238,7 +2280,7 @@ void tst_QGraphicsGridLayout::geometries_data() ); - QTest::newRow("hfw-h408") << (ItemList() + QTest::newRow("hfw-100x408") << (ItemList() << ItemDesc(0,0) .minSize(QSizeF(1,1)) .preferredSize(QSizeF(50,10)) @@ -2255,7 +2297,7 @@ void tst_QGraphicsGridLayout::geometries_data() .minSize(QSizeF(40,40)) .preferredSize(QSizeF(50,400)) .maxSize(QSizeF(500, 500)) - .heightForWidth(hfw1) + .dynamicConstraint(hfw1, Qt::Vertical) ) << QSizeF(100, 408) << (RectList() @@ -2280,7 +2322,7 @@ void tst_QGraphicsGridLayout::geometries_data() .minSize(QSizeF(40,40)) .preferredSize(QSizeF(50,400)) .maxSize(QSizeF(500, 500)) - .heightForWidth(hfw1) + .dynamicConstraint(hfw1, Qt::Vertical) ) << QSizeF(100, 410) << (RectList() @@ -2288,7 +2330,7 @@ void tst_QGraphicsGridLayout::geometries_data() << QRectF(0, 10, 50,100) << QRectF(50, 10, 50,400) ); - QTest::newRow("hfw-h470") << (ItemList() + QTest::newRow("hfw-100x470") << (ItemList() << ItemDesc(0,0) .minSize(QSizeF(1,1)) .preferredSize(QSizeF(50,10)) @@ -2305,7 +2347,7 @@ void tst_QGraphicsGridLayout::geometries_data() .minSize(QSizeF(40,40)) .preferredSize(QSizeF(50,400)) .maxSize(QSizeF(500, 500)) - .heightForWidth(hfw1) + .dynamicConstraint(hfw1, Qt::Vertical) ) << QSizeF(100, 470) << (RectList() @@ -2315,7 +2357,7 @@ void tst_QGraphicsGridLayout::geometries_data() // change layout width and verify - QTest::newRow("hfw-w100") << (ItemList() + QTest::newRow("hfw-100x401") << (ItemList() << ItemDesc(0,0) .minSize(QSizeF(1,1)) .preferredSize(QSizeF(50,10)) @@ -2332,7 +2374,7 @@ void tst_QGraphicsGridLayout::geometries_data() .minSize(QSizeF(40,40)) .preferredSize(QSizeF(50,400)) .maxSize(QSizeF(5000, 5000)) - .heightForWidth(hfw1) + .dynamicConstraint(hfw1, Qt::Vertical) ) << QSizeF(100, 401) << (RectList() @@ -2340,7 +2382,7 @@ void tst_QGraphicsGridLayout::geometries_data() << QRectF( 0, 1, 50, 100) << QRectF( 50, 1, 50, 400) ); - QTest::newRow("hfw-w160") << (ItemList() + QTest::newRow("hfw-160x400") << (ItemList() << ItemDesc(0,0) .minSize(QSizeF(1,1)) .preferredSize(QSizeF(50,10)) @@ -2357,16 +2399,16 @@ void tst_QGraphicsGridLayout::geometries_data() .minSize(QSizeF(40,40)) .preferredSize(QSizeF(50,400)) .maxSize(QSizeF(5000, 5000)) - .heightForWidth(hfw1) + .dynamicConstraint(hfw1, Qt::Vertical) ) - << QSizeF(160, 401) + << QSizeF(160, 400) << (RectList() << QRectF( 0, 0, 80, 100) << QRectF( 80, 0, 80, 100) << QRectF( 0, 100, 80, 100) << QRectF( 80, 100, 80, 250) ); - QTest::newRow("hfw-w500") << (ItemList() + QTest::newRow("hfw-160x300") << (ItemList() << ItemDesc(0,0) .minSize(QSizeF(1,1)) .preferredSize(QSizeF(50,10)) @@ -2383,12 +2425,145 @@ void tst_QGraphicsGridLayout::geometries_data() .minSize(QSizeF(40,40)) .preferredSize(QSizeF(50,400)) .maxSize(QSizeF(5000, 5000)) - .heightForWidth(hfw1) + .dynamicConstraint(hfw1, Qt::Vertical) + ) + << QSizeF(160, 300) + << (RectList() + << QRectF( 0, 0, 80, 50) << QRectF( 80, 0, 80, 50) + << QRectF( 0, 50, 80, 100) << QRectF( 80, 50, 80, 250) + ); + + QTest::newRow("hfw-20x40") << (ItemList() + << ItemDesc(0,0) + .minSize(QSizeF(1,1)) + .preferredSize(QSizeF(50,50)) + .maxSize(QSizeF(100, 100)) + << ItemDesc(0,1) + .minSize(QSizeF(1,10)) + .preferredSize(QSizeF(50,50)) + .maxSize(QSizeF(100, 100)) + << ItemDesc(1,0) + .minSize(QSizeF(1,1)) + .preferredSize(QSizeF(50,50)) + .maxSize(QSizeF(100, 100)) + << ItemDesc(1,1) + .minSize(QSizeF(1,1)) + .preferredSize(QSizeF(50,50)) + .maxSize(QSizeF(100, 100)) + .dynamicConstraint(hfw3, Qt::Vertical) + ) + << QSizeF(20, 40) + << (RectList() + << QRectF(0, 0, 10, 20) << QRectF(10, 0, 10, 20) + << QRectF(0, 20, 10, 20) << QRectF(10, 20, 10, 10) + ); + + QTest::newRow("wfh-300x160") << (ItemList() + << ItemDesc(0,0) + .minSize(QSizeF(1,1)) + .preferredSize(QSizeF(10,50)) + .maxSize(QSizeF(100, 100)) + << ItemDesc(0,1) + .minSize(QSizeF(1,1)) + .preferredSize(QSizeF(10,50)) + .maxSize(QSizeF(100, 100)) + << ItemDesc(1,0) + .minSize(QSizeF(1,1)) + .preferredSize(QSizeF(10,50)) + .maxSize(QSizeF(100, 100)) + << ItemDesc(1,1) + .minSize(QSizeF(10,10)) + .preferredSize(QSizeF(400,50)) + .maxSize(QSizeF(5000, 5000)) + .dynamicConstraint(wfh1, Qt::Horizontal) + ) + << QSizeF(300, 160) + << (RectList() + << QRectF( 0, 0, 50, 80) << QRectF( 50, 0, 100, 80) + << QRectF( 0, 80, 50, 80) << QRectF( 50, 80, 250, 80) + ); + + QTest::newRow("wfh-40x20") << (ItemList() + << ItemDesc(0,0) + .minSize(QSizeF(1,1)) + .preferredSize(QSizeF(50,50)) + .maxSize(QSizeF(100, 100)) + << ItemDesc(0,1) + .minSize(QSizeF(1,1)) + .preferredSize(QSizeF(50,50)) + .maxSize(QSizeF(100, 100)) + << ItemDesc(1,0) + // Note, must be 10 in order to match stretching of wfh item + // below (the same stretch makes it easier to test) + .minSize(QSizeF(10,1)) + .preferredSize(QSizeF(50,50)) + .maxSize(QSizeF(100, 100)) + << ItemDesc(1,1) + .minSize(QSizeF(1,1)) + .preferredSize(QSizeF(50,50)) + .maxSize(QSizeF(100, 100)) + .dynamicConstraint(wfh2, Qt::Horizontal) ) - << QSizeF(500, 401) + << QSizeF(40, 20) << (RectList() - << QRectF( 0, 0, 100, 100) << QRectF(100, 0, 100, 100) - << QRectF( 0, 100, 100, 100) << QRectF(100, 100, 400, 50) + << QRectF(0, 0, 20, 10) << QRectF(20, 0, 20, 10) + << QRectF(0, 10, 20, 10) << QRectF(20, 10, 10, 10) + ); + + QTest::newRow("wfh-400x160") << (ItemList() + << ItemDesc(0,0) + .minSize(QSizeF(1,1)) + .preferredSize(QSizeF(50,50)) + .maxSize(QSizeF(100, 100)) + << ItemDesc(0,1) + .minSize(QSizeF(1,1)) + .preferredSize(QSizeF(50,50)) + .maxSize(QSizeF(100, 100)) + << ItemDesc(1,0) + .minSize(QSizeF(1,1)) + .preferredSize(QSizeF(50,50)) + .maxSize(QSizeF(100, 100)) + << ItemDesc(1,1) + .minSize(QSizeF(1,1)) + .preferredSize(QSizeF(50,50)) + .maxSize(QSizeF(100, 100)) + .dynamicConstraint(wfh2, Qt::Horizontal) + ) + + << QSizeF(400, 160) + << (RectList() + << QRectF(0, 0, 100, 80) << QRectF(100, 0, 100, 80) + << QRectF(0, 80, 100, 80) << QRectF(100, 80, 80, 80) + ); + + QTest::newRow("wfh-160x100") << (ItemList() + << ItemDesc(0,0) + .minSize(QSizeF(1,1)) + // Note, preferred width must be 50 in order to match + // preferred width of wfh item below. + // (The same preferred size makes the stretch the same, and + // makes it easier to test) (The stretch algorithm is a + // blackbox) + .preferredSize(QSizeF(50,50)) + .maxSize(QSizeF(100, 100)) + << ItemDesc(0,1) + .minSize(QSizeF(1,1)) + .preferredSize(QSizeF(10,50)) + .maxSize(QSizeF(100, 100)) + << ItemDesc(1,0) + .minSize(QSizeF(1,1)) + .preferredSize(QSizeF(10,50)) + .maxSize(QSizeF(100, 100)) + << ItemDesc(1,1) + .minSize(QSizeF(1,1)) + .preferredSize(QSizeF(10,50)) + .maxSize(QSizeF(500, 500)) + .dynamicConstraint(wfh2, Qt::Horizontal) + ) + << QSizeF(160, 100) + << (RectList() + << QRectF(0, 0, 80, 50) << QRectF( 80, 0, 80, 50) + << QRectF(0, 50, 80, 50) << QRectF( 80, 50, 50, 50) ); } @@ -2461,14 +2636,6 @@ void tst_QGraphicsGridLayout::task236367_maxSizeHint() QCOMPARE(widget->size(), QSizeF(w, h)); } -/* -static qreal hfw(qreal w) -{ - if (w == 0) - return 20000; - return 20000/w; -} -*/ static QSizeF hfw(Qt::SizeHint /*which*/, const QSizeF &constraint) { QSizeF result(constraint); @@ -2485,7 +2652,16 @@ static QSizeF hfw(Qt::SizeHint /*which*/, const QSizeF &constraint) } else if (ch == 0) { result.setWidth(20000); } + return result; +} +static QSizeF wfh(Qt::SizeHint /*which*/, const QSizeF &constraint) +{ + QSizeF result(constraint); + const qreal ch = constraint.height(); + if (ch >= 0) { + result.setWidth(ch); + } return result; } @@ -2536,24 +2712,25 @@ void tst_QGraphicsGridLayout::heightForWidth() layout->setSpacing(0); RectWidget *w00 = new RectWidget; w00->setSizeHint(Qt::MinimumSize, QSizeF(1,1)); - w00->setSizeHint(Qt::PreferredSize, QSizeF(10,10)); + w00->setSizeHint(Qt::PreferredSize, QSizeF(50,50)); w00->setSizeHint(Qt::MaximumSize, QSizeF(100,100)); layout->addItem(w00, 0, 0); RectWidget *w01 = new RectWidget; w01->setSizeHint(Qt::MinimumSize, QSizeF(1,1)); - w01->setSizeHint(Qt::PreferredSize, QSizeF(10,10)); + w01->setSizeHint(Qt::PreferredSize, QSizeF(50,50)); w01->setSizeHint(Qt::MaximumSize, QSizeF(100,100)); layout->addItem(w01, 0, 1); RectWidget *w10 = new RectWidget; w10->setSizeHint(Qt::MinimumSize, QSizeF(1,1)); - w10->setSizeHint(Qt::PreferredSize, QSizeF(10,10)); + w10->setSizeHint(Qt::PreferredSize, QSizeF(50,50)); w10->setSizeHint(Qt::MaximumSize, QSizeF(100,100)); layout->addItem(w10, 1, 0); RectWidget *w11 = new RectWidget; w11->setSizeHint(Qt::MinimumSize, QSizeF(1,1)); + w11->setSizeHint(Qt::PreferredSize, QSizeF(50,400)); w11->setSizeHint(Qt::MaximumSize, QSizeF(30000,30000)); w11->setConstraintFunction(hfw); QSizePolicy sp(QSizePolicy::Preferred, QSizePolicy::Preferred); @@ -2562,42 +2739,104 @@ void tst_QGraphicsGridLayout::heightForWidth() layout->addItem(w11, 1, 1); QSizeF prefSize = layout->effectiveSizeHint(Qt::PreferredSize, QSizeF(-1, -1)); - QCOMPARE(prefSize, QSizeF(10+200, 10+100)); + QCOMPARE(prefSize, QSizeF(50+50, 50+400)); QCOMPARE(layout->effectiveSizeHint(Qt::MinimumSize, QSizeF(2, -1)), QSizeF(2, 20001)); - QCOMPARE(layout->effectiveSizeHint(Qt::PreferredSize, QSizeF(2, -1)), QSizeF(2, 20010)); + QCOMPARE(layout->effectiveSizeHint(Qt::PreferredSize, QSizeF(2, -1)), QSizeF(2, 20050)); QCOMPARE(layout->effectiveSizeHint(Qt::MaximumSize, QSizeF(2, -1)), QSizeF(2, 20100)); - qreal width1; - qreal width2; - expectedWidth(1, 10, 1, 200, 20, &width1, &width2); - QSizeF expectedSize = hfw(Qt::MinimumSize, QSizeF(width2, -1)) + QSizeF(width1, 1); - QCOMPARE(layout->effectiveSizeHint(Qt::MinimumSize, QSizeF(20, -1)), expectedSize); - expectedSize.rheight()+=9; - QCOMPARE(layout->effectiveSizeHint(Qt::PreferredSize, QSizeF(20, -1)), expectedSize); - expectedSize.rheight()+=90; - QCOMPARE(layout->effectiveSizeHint(Qt::MaximumSize, QSizeF(20, -1)), expectedSize); - - expectedWidth(1, 10, 1, 200, 300, &width1, &width2); - expectedSize = hfw(Qt::MinimumSize, QSizeF(width2, -1)) + QSizeF(width1, 1); - QCOMPARE(layout->effectiveSizeHint(Qt::MinimumSize, QSizeF(300, -1)), expectedSize); - expectedSize.rheight()+=9; - QCOMPARE(layout->effectiveSizeHint(Qt::PreferredSize, QSizeF(300, -1)), expectedSize); - // the height of the hfw widget is shorter than the one to the left, which is 100, so - // the total height of the last row is 100 (which leaves the layout height to be 200) - QCOMPARE(layout->effectiveSizeHint(Qt::MaximumSize, QSizeF(300, -1)), QSizeF(300, 200)); - - // the hfw item is shorter than the item to the left - expectedWidth(1, 10, 1, 200, 500, &width1, &width2); - expectedSize = hfw(Qt::MinimumSize, QSizeF(width2, -1)) + QSizeF(width1, 1); - QCOMPARE(layout->effectiveSizeHint(Qt::MinimumSize, QSizeF(500, -1)), expectedSize); - expectedSize.rheight()+=9; - QCOMPARE(layout->effectiveSizeHint(Qt::PreferredSize, QSizeF(500, -1)), expectedSize); + + QCOMPARE(layout->effectiveSizeHint(Qt::MinimumSize, QSizeF(20, -1)), QSizeF(20, 1 + 2000)); + QCOMPARE(layout->effectiveSizeHint(Qt::PreferredSize, QSizeF(20, -1)), QSizeF(20, 50 + 2000)); + QCOMPARE(layout->effectiveSizeHint(Qt::MaximumSize, QSizeF(20, -1)), QSizeF(20, 100 + 2000)); + + QCOMPARE(layout->effectiveSizeHint(Qt::MinimumSize, QSizeF(300, -1)), QSizeF(300, 1 + 100)); + QCOMPARE(layout->effectiveSizeHint(Qt::PreferredSize, QSizeF(300, -1)), QSizeF(300, 50 + 100)); + QCOMPARE(layout->effectiveSizeHint(Qt::MaximumSize, QSizeF(300, -1)), QSizeF(300, 100 + 100)); + // the height of the hfw widget is shorter than the one to the left, which is 100, so // the total height of the last row is 100 (which leaves the layout height to be 200) - QCOMPARE(layout->effectiveSizeHint(Qt::MaximumSize, QSizeF(500, -1)), QSizeF(500, 200)); + QCOMPARE(layout->effectiveSizeHint(Qt::MaximumSize, QSizeF(500, -1)), QSizeF(500, 100 + 100)); + + // hfw item size: (500, 40) -> preferred size is maxed up to preferred size of item w10 (50) + QCOMPARE(layout->effectiveSizeHint(Qt::PreferredSize, QSizeF(600, -1)), QSizeF(600, 50 + 50)); } +void tst_QGraphicsGridLayout::widthForHeight() +{ + QGraphicsWidget *widget = new QGraphicsWidget; + QGraphicsGridLayout *layout = new QGraphicsGridLayout; + widget->setLayout(layout); + layout->setContentsMargins(0, 0, 0, 0); + layout->setSpacing(0); + RectWidget *w00 = new RectWidget; + w00->setMinimumSize(1, 1); + w00->setPreferredSize(50, 50); + w00->setMaximumSize(100, 100); + + layout->addItem(w00, 0, 0); + + RectWidget *w01 = new RectWidget; + w01->setMinimumSize(1,1); + w01->setPreferredSize(50,50); + w01->setMaximumSize(100,100); + layout->addItem(w01, 0, 1); + + RectWidget *w10 = new RectWidget; + w10->setMinimumSize(1,1); + w10->setPreferredSize(50,50); + w10->setMaximumSize(100,100); + layout->addItem(w10, 1, 0); + + RectWidget *w11 = new RectWidget; + w11->setMinimumSize(1,1); + w11->setPreferredSize(50, 50); + w11->setMaximumSize(30000,30000); + // This will make sure its always square. + w11->setConstraintFunction(wfh); + QSizePolicy sp(QSizePolicy::Preferred, QSizePolicy::Preferred); + sp.setWidthForHeight(true); + w11->setSizePolicy(sp); + layout->addItem(w11, 1, 1); + + /* + | 1, 50, 100 | 1, 50, 100 | + -----+--------------+--------------+ + 1| | | + 50| | | + 100| | | + -----|--------------+--------------+ + 1| | | + 50| | WFH | + 100| | | + -----------------------------------+ + */ + + + QSizeF prefSize = layout->effectiveSizeHint(Qt::PreferredSize, QSizeF(-1, -1)); + QCOMPARE(prefSize, QSizeF(50+50, 50+50)); + + // wfh(1): = 1 + QCOMPARE(layout->effectiveSizeHint(Qt::MinimumSize, QSizeF(-1, 2)), QSizeF(1 + 1, 2)); + QCOMPARE(layout->effectiveSizeHint(Qt::PreferredSize, QSizeF(-1, 2)), QSizeF(50 + 50, 2)); + QCOMPARE(layout->effectiveSizeHint(Qt::MaximumSize, QSizeF(-1, 2)), QSizeF(100 + 100, 2)); + + // wfh(40) = 40 + QCOMPARE(layout->effectiveSizeHint(Qt::MinimumSize, QSizeF(-1, 80)), QSizeF(1 + 40, 80)); + QCOMPARE(layout->effectiveSizeHint(Qt::PreferredSize, QSizeF(-1, 80)), QSizeF(50 + 50, 80)); + QCOMPARE(layout->effectiveSizeHint(Qt::MaximumSize, QSizeF(-1, 80)), QSizeF(100 + 100, 80)); + + // wfh(80) = 80 + QCOMPARE(layout->effectiveSizeHint(Qt::MinimumSize, QSizeF(-1, 160)), QSizeF(1 + 80, 160)); + QCOMPARE(layout->effectiveSizeHint(Qt::PreferredSize, QSizeF(-1, 160)), QSizeF(50 + 80, 160)); + QCOMPARE(layout->effectiveSizeHint(Qt::MaximumSize, QSizeF(-1, 160)), QSizeF(100 + 100, 160)); + + // wfh(200) = 200 + QCOMPARE(layout->effectiveSizeHint(Qt::MinimumSize, QSizeF(-1, 300)), QSizeF(1 + 200, 300)); + QCOMPARE(layout->effectiveSizeHint(Qt::PreferredSize, QSizeF(-1, 300)), QSizeF(50 + 200, 300)); + QCOMPARE(layout->effectiveSizeHint(Qt::MaximumSize, QSizeF(-1, 300)), QSizeF(100 + 200, 300)); + +} QTEST_MAIN(tst_QGraphicsGridLayout) #include "tst_qgraphicsgridlayout.moc" diff --git a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp index 3634ce9..4476084 100644 --- a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp @@ -4578,7 +4578,7 @@ void tst_QGraphicsItem::itemChange() QCOMPARE(tester.changes.at(tester.changes.size() - 1), QGraphicsItem::ItemFlagsHaveChanged); QVariant expectedFlags = qVariantFromValue<quint32>(QGraphicsItem::GraphicsItemFlags(QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemSendsGeometryChanges)); QCOMPARE(tester.values.at(tester.values.size() - 2), expectedFlags); - QCOMPARE(tester.values.at(tester.values.size() - 1), qVariantFromValue<quint32>(QGraphicsItem::ItemIsSelectable)); + QCOMPARE(tester.values.at(tester.values.size() - 1), qVariantFromValue<quint32>((quint32)QGraphicsItem::ItemIsSelectable)); } { // ItemSelectedChange diff --git a/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp b/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp index e5628d1..ddc4f73 100644 --- a/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp +++ b/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp @@ -172,6 +172,12 @@ private slots: void itemChangeEvents(); void itemSendGeometryPosChangesDeactivated(); + void fontPropagatesResolveToChildren(); + void fontPropagatesResolveToGrandChildren(); + void fontPropagatesResolveInParentChange(); + void fontPropagatesResolveViaNonWidget(); + void fontPropagatesResolveFromScene(); + // Task fixes void task236127_bspTreeIndexFails(); void task243004_setStyleCrash(); @@ -622,6 +628,192 @@ void tst_QGraphicsWidget::font() QCOMPARE(widget.font().family(), font.family()); } +void tst_QGraphicsWidget::fontPropagatesResolveToChildren() +{ + QGraphicsWidget *root = new QGraphicsWidget(); + QGraphicsWidget *child1 = new QGraphicsWidget(root); + + QGraphicsScene scene; + scene.addItem(root); + + QFont font; + font.setItalic(true); + root->setFont(font); + + QGraphicsWidget *child2 = new QGraphicsWidget(root); + QGraphicsWidget *child3 = new QGraphicsWidget(); + child3->setParentItem(root); + + QGraphicsView view; + view.setScene(&scene); + view.show(); + QTest::qWaitForWindowShown(&view); + + QCOMPARE(font.resolve(), uint(QFont::StyleResolved)); + QCOMPARE(root->font().resolve(), uint(QFont::StyleResolved)); + QCOMPARE(child1->font().resolve(), uint(QFont::StyleResolved)); + QCOMPARE(child2->font().resolve(), uint(QFont::StyleResolved)); + QCOMPARE(child3->font().resolve(), uint(QFont::StyleResolved)); +} + +void tst_QGraphicsWidget::fontPropagatesResolveToGrandChildren() +{ + QGraphicsWidget *root = new QGraphicsWidget(); + QGraphicsWidget *child1 = new QGraphicsWidget(root); + QGraphicsWidget *grandChild1 = new QGraphicsWidget(child1); + + QGraphicsScene scene; + scene.addItem(root); + + QFont font; + font.setItalic(true); + root->setFont(font); + + QGraphicsWidget *child2 = new QGraphicsWidget(root); + QGraphicsWidget *grandChild2 = new QGraphicsWidget(child2); + QGraphicsWidget *grandChild3 = new QGraphicsWidget(child2); + + QGraphicsWidget *child3 = new QGraphicsWidget(); + QGraphicsWidget *grandChild4 = new QGraphicsWidget(child3); + QGraphicsWidget *grandChild5 = new QGraphicsWidget(child3); + child3->setParentItem(root); + grandChild5->setParentItem(child3); + + QGraphicsView view; + view.setScene(&scene); + view.show(); + QTest::qWaitForWindowShown(&view); + + QCOMPARE(font.resolve(), uint(QFont::StyleResolved)); + QCOMPARE(grandChild1->font().resolve(), uint(QFont::StyleResolved)); + QCOMPARE(grandChild2->font().resolve(), uint(QFont::StyleResolved)); + QCOMPARE(grandChild3->font().resolve(), uint(QFont::StyleResolved)); + QCOMPARE(grandChild4->font().resolve(), uint(QFont::StyleResolved)); + QCOMPARE(grandChild5->font().resolve(), uint(QFont::StyleResolved)); +} + +void tst_QGraphicsWidget::fontPropagatesResolveViaNonWidget() +{ + QGraphicsWidget *root = new QGraphicsWidget(); + QGraphicsPixmapItem *child1 = new QGraphicsPixmapItem(root); + QGraphicsWidget *grandChild1 = new QGraphicsWidget(child1); + + QGraphicsScene scene; + scene.addItem(root); + + QFont font; + font.setItalic(true); + root->setFont(font); + + QGraphicsPixmapItem *child2 = new QGraphicsPixmapItem(root); + QGraphicsWidget *grandChild2 = new QGraphicsWidget(child2); + QGraphicsWidget *grandChild3 = new QGraphicsWidget(child2); + + QGraphicsPixmapItem *child3 = new QGraphicsPixmapItem(); + QGraphicsWidget *grandChild4 = new QGraphicsWidget(child3); + QGraphicsWidget *grandChild5 = new QGraphicsWidget(child3); + child3->setParentItem(root); + grandChild5->setParentItem(child3); + + QGraphicsView view; + view.setScene(&scene); + view.show(); + QTest::qWaitForWindowShown(&view); + + QCOMPARE(font.resolve(), uint(QFont::StyleResolved)); + QCOMPARE(grandChild1->font().resolve(), uint(QFont::StyleResolved)); + QCOMPARE(grandChild2->font().resolve(), uint(QFont::StyleResolved)); + QCOMPARE(grandChild3->font().resolve(), uint(QFont::StyleResolved)); + QCOMPARE(grandChild4->font().resolve(), uint(QFont::StyleResolved)); + QCOMPARE(grandChild5->font().resolve(), uint(QFont::StyleResolved)); +} + +void tst_QGraphicsWidget::fontPropagatesResolveFromScene() +{ + QGraphicsWidget *root = new QGraphicsWidget(); + QGraphicsWidget *child1 = new QGraphicsWidget(root); + QGraphicsWidget *grandChild1 = new QGraphicsWidget(child1); + + QGraphicsScene scene; + scene.addItem(root); + + QFont font; + font.setItalic(true); + scene.setFont(font); + + QGraphicsWidget *child2 = new QGraphicsWidget(root); + QGraphicsWidget *grandChild2 = new QGraphicsWidget(child2); + QGraphicsWidget *grandChild3 = new QGraphicsWidget(child2); + + QGraphicsWidget *child3 = new QGraphicsWidget(); + QGraphicsWidget *grandChild4 = new QGraphicsWidget(child3); + QGraphicsWidget *grandChild5 = new QGraphicsWidget(child3); + child3->setParentItem(root); + grandChild5->setParentItem(child3); + + QGraphicsView view; + view.setScene(&scene); + view.show(); + QTest::qWaitForWindowShown(&view); + + QCOMPARE(font.resolve(), uint(QFont::StyleResolved)); + QCOMPARE(root->font().resolve(), uint(QFont::StyleResolved)); + QCOMPARE(child1->font().resolve(), uint(QFont::StyleResolved)); + QCOMPARE(child2->font().resolve(), uint(QFont::StyleResolved)); + QCOMPARE(child3->font().resolve(), uint(QFont::StyleResolved)); + QCOMPARE(grandChild1->font().resolve(), uint(QFont::StyleResolved)); + QCOMPARE(grandChild2->font().resolve(), uint(QFont::StyleResolved)); + QCOMPARE(grandChild3->font().resolve(), uint(QFont::StyleResolved)); + QCOMPARE(grandChild4->font().resolve(), uint(QFont::StyleResolved)); + QCOMPARE(grandChild5->font().resolve(), uint(QFont::StyleResolved)); +} + +void tst_QGraphicsWidget::fontPropagatesResolveInParentChange() +{ + QGraphicsWidget *root = new QGraphicsWidget(); + + QGraphicsWidget *child1 = new QGraphicsWidget(root); + QGraphicsWidget *grandChild1 = new QGraphicsWidget(child1); + + QGraphicsWidget *child2 = new QGraphicsWidget(root); + QGraphicsWidget *grandChild2 = new QGraphicsWidget(child2); + + QGraphicsScene scene; + scene.addItem(root); + + QFont italicFont; + italicFont.setItalic(true); + child1->setFont(italicFont); + + QFont boldFont; + boldFont.setBold(true); + child2->setFont(boldFont); + + QVERIFY(grandChild1->font().italic()); + QVERIFY(!grandChild1->font().bold()); + QVERIFY(!grandChild2->font().italic()); + QVERIFY(grandChild2->font().bold()); + + QCOMPARE(grandChild1->font().resolve(), uint(QFont::StyleResolved)); + QCOMPARE(grandChild2->font().resolve(), uint(QFont::WeightResolved)); + + grandChild2->setParentItem(child1); + + QGraphicsView view; + view.setScene(&scene); + view.show(); + QTest::qWaitForWindowShown(&view); + + QVERIFY(grandChild1->font().italic()); + QVERIFY(!grandChild1->font().bold()); + QVERIFY(grandChild2->font().italic()); + QVERIFY(!grandChild2->font().bold()); + + QCOMPARE(grandChild1->font().resolve(), uint(QFont::StyleResolved)); + QCOMPARE(grandChild2->font().resolve(), uint(QFont::StyleResolved)); + +} + void tst_QGraphicsWidget::fontPropagation() { QGraphicsWidget *root = new QGraphicsWidget; @@ -728,11 +920,12 @@ void tst_QGraphicsWidget::fontPropagationWidgetItemWidget() widget->setFont(font); QCOMPARE(widget2->font().pointSize(), 43); - QCOMPARE(widget2->font().resolve(), QFont().resolve()); + QCOMPARE(widget2->font().resolve(), uint(QFont::SizeResolved)); widget->setFont(QFont()); QCOMPARE(widget2->font().pointSize(), qApp->font().pointSize()); + QCOMPARE(widget2->font().resolve(), QFont().resolve()); } void tst_QGraphicsWidget::fontPropagationSceneChange() diff --git a/tests/auto/qimage/tst_qimage.cpp b/tests/auto/qimage/tst_qimage.cpp index 46bc6e7..6b8028c 100644 --- a/tests/auto/qimage/tst_qimage.cpp +++ b/tests/auto/qimage/tst_qimage.cpp @@ -162,14 +162,14 @@ void tst_QImage::create() { bool cr = true; #if !defined(Q_WS_QWS) && !defined(Q_OS_WINCE) - try { + QT_TRY { #endif //QImage image(7000000, 7000000, 8, 256, QImage::IgnoreEndian); QImage image(7000000, 7000000, QImage::Format_Indexed8); image.setColorCount(256); cr = !image.isNull(); #if !defined(Q_WS_QWS) && !defined(Q_OS_WINCE) - } catch (...) { + } QT_CATCH (...) { } #endif QVERIFY( !cr ); diff --git a/tests/auto/qinputcontext/qinputcontext.pro b/tests/auto/qinputcontext/qinputcontext.pro index b3ea8c2..ec6831e 100644 --- a/tests/auto/qinputcontext/qinputcontext.pro +++ b/tests/auto/qinputcontext/qinputcontext.pro @@ -1,2 +1,6 @@ load(qttest_p4) SOURCES += tst_qinputcontext.cpp + +symbian { + LIBS += -lws32 -lcone +} diff --git a/tests/auto/qinputcontext/tst_qinputcontext.cpp b/tests/auto/qinputcontext/tst_qinputcontext.cpp index 644b463..d077bc1 100644 --- a/tests/auto/qinputcontext/tst_qinputcontext.cpp +++ b/tests/auto/qinputcontext/tst_qinputcontext.cpp @@ -48,17 +48,27 @@ #include <qlayout.h> #include <qradiobutton.h> #include <qwindowsstyle.h> +#include <qdesktopwidget.h> +#include <qpushbutton.h> + +#ifdef Q_OS_SYMBIAN +#include <private/qt_s60_p.h> +#include <private/qcoefepinputcontext_p.h> + +#include <w32std.h> +#include <coecntrl.h> +#endif class tst_QInputContext : public QObject { Q_OBJECT public: - tst_QInputContext() {} + tst_QInputContext() : m_phoneIsQwerty(false) {} virtual ~tst_QInputContext() {} public slots: - void initTestCase() {} + void initTestCase(); void cleanupTestCase() {} void init() {} void cleanup() {} @@ -69,8 +79,178 @@ private slots: void closeSoftwareInputPanel(); void selections(); void focusProxy(); + void symbianTestCoeFepInputContext_data(); + void symbianTestCoeFepInputContext(); + void symbianTestCoeFepAutoCommit_data(); + void symbianTestCoeFepAutoCommit(); + +private: + bool m_phoneIsQwerty; +}; + +#ifdef Q_OS_SYMBIAN +class KeyEvent : public TWsEvent +{ +public: + KeyEvent(QWidget *w, TInt type, TInt scanCode, TUint code, TUint modifiers, TInt repeats) { + iHandle = w->effectiveWinId()->DrawableWindow()->WindowGroupId(); + iType = type; + SetTimeNow(); + TKeyEvent *keyEvent = reinterpret_cast<TKeyEvent *>(iEventData); + keyEvent->iScanCode = scanCode; + keyEvent->iCode = code; + keyEvent->iModifiers = modifiers; + keyEvent->iRepeats = repeats; + } +}; + +class FepReplayEvent +{ +public: + enum Type { + Pause, + Key, + CompleteKey + }; + + FepReplayEvent(int msecsToPause) + : m_type(Pause) + , m_msecsToPause(msecsToPause) + { + } + + FepReplayEvent(TInt keyType, TInt scanCode, TUint code, TUint modifiers, TInt repeats) + : m_type(Key) + , m_keyType(keyType) + , m_scanCode(scanCode) + , m_code(code) + , m_modifiers(modifiers) + , m_repeats(repeats) + { + } + + FepReplayEvent(TInt scanCode, TUint code, TUint modifiers, TInt repeats) + : m_type(CompleteKey) + , m_scanCode(scanCode) + , m_code(code) + , m_modifiers(modifiers) + , m_repeats(repeats) + { + } + + void sendEvent(QWidget *w, TInt type, TInt scanCode, TUint code, TUint modifiers, TInt repeats) + { + KeyEvent event(w, type, scanCode, code, modifiers, repeats); + S60->wsSession().SendEventToWindowGroup(w->effectiveWinId()->DrawableWindow()->WindowGroupId(), event); + } + + void pause(int msecs) + { + // Don't use qWait here. The polling nature of that function screws up the test. + QTimer timer; + QEventLoop loop; + QObject::connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit())); + timer.setSingleShot(true); + timer.start(msecs); + loop.exec(); + } + + // For some reason, the test fails if using processEvents instead of an event loop + // with a zero timer to quit it, so use the timer. +#define KEY_WAIT 0 + + void replay(QWidget *w) + { + if (m_type == Pause) { + pause(m_msecsToPause); + } else if (m_type == Key) { + sendEvent(w, m_keyType, m_scanCode, m_code, m_modifiers, m_repeats); + if (m_keyType != EEventKeyDown) + // EEventKeyDown events should have no pause before the EEventKey event. + pause(KEY_WAIT); + } else if (m_type == CompleteKey) { + sendEvent(w, EEventKeyDown, m_scanCode, 0, m_modifiers, m_repeats); + // EEventKeyDown events should have no pause before the EEventKey event. + sendEvent(w, EEventKey, m_scanCode, m_code, m_modifiers, m_repeats); + pause(KEY_WAIT); + sendEvent(w, EEventKeyUp, m_scanCode, 0, m_modifiers, m_repeats); + pause(KEY_WAIT); + } + } + +private: + Type m_type; + int m_msecsToPause; + TInt m_keyType; + TInt m_scanCode; + TUint m_code; + TUint m_modifiers; + TInt m_repeats; }; +Q_DECLARE_METATYPE(QList<FepReplayEvent>) +Q_DECLARE_METATYPE(Qt::InputMethodHints) +Q_DECLARE_METATYPE(QLineEdit::EchoMode); + +#endif // Q_OS_SYMBIAN + +void tst_QInputContext::initTestCase() +{ +#ifdef Q_OS_SYMBIAN + // Sanity test. Checks FEP for: + // - T9 mode is default (it will attempt to fix this) + // - Language is English (it cannot fix this; bail out if not correct) + QWidget w; + QLayout *layout = new QVBoxLayout; + w.setLayout(layout); + QLineEdit *lineedit = new QLineEdit; + layout->addWidget(lineedit); + lineedit->setFocus(); +#ifdef QT_KEYPAD_NAVIGATION + lineedit->setEditFocus(true); +#endif + w.show(); + + QDesktopWidget desktop; + QRect screenSize = desktop.screenGeometry(&w); + if (screenSize.width() > screenSize.height()) { + // Crude way of finding out we are running on a qwerty phone. + m_phoneIsQwerty = true; + return; + } + + for (int iterations = 0; iterations < 16; iterations++) { + QTest::qWait(500); + + QList<FepReplayEvent> keyEvents; + + keyEvents << FepReplayEvent('9', '9', 0, 0); + keyEvents << FepReplayEvent('6', '6', 0, 0); + keyEvents << FepReplayEvent('8', '8', 0, 0); + keyEvents << FepReplayEvent(EStdKeyRightArrow, EKeyRightArrow, 0, 0); + + foreach(FepReplayEvent event, keyEvents) { + event.replay(lineedit); + } + + QApplication::processEvents(); + + if (lineedit->text().endsWith("you", Qt::CaseInsensitive)) { + // Success! + return; + } + + // Try changing modes. + // After 8 iterations, try to press the mode switch twice before typing. + for (int c = 0; c <= iterations / 8; c++) { + FepReplayEvent(EStdKeyHash, '#', 0, 0).replay(lineedit); + } + } + + QFAIL("FEP sanity test failed. Either the phone is not set to English, or the test was unable to enable T9"); +#endif +} + void tst_QInputContext::maximumTextLength() { QLineEdit le; @@ -271,7 +451,6 @@ void tst_QInputContext::focusProxy() QInputContext *gic = qApp->inputContext(); QVERIFY(gic); - qDebug() << gic->focusWidget() << &proxy; QCOMPARE(gic->focusWidget(), &proxy); // then change the focus proxy and check that input context is valid @@ -285,5 +464,622 @@ void tst_QInputContext::focusProxy() QCOMPARE(gic->focusWidget(), &proxy); } +void tst_QInputContext::symbianTestCoeFepInputContext_data() +{ +#ifdef Q_OS_SYMBIAN + QTest::addColumn<bool> ("inputMethodEnabled"); + QTest::addColumn<Qt::InputMethodHints> ("inputMethodHints"); + QTest::addColumn<int> ("maxLength"); // Zero for no limit + QTest::addColumn<QLineEdit::EchoMode> ("echoMode"); + QTest::addColumn<QList<FepReplayEvent> > ("keyEvents"); + QTest::addColumn<QString> ("finalString"); + QTest::addColumn<QString> ("preeditString"); + QList<FepReplayEvent> events; + + events << FepReplayEvent(EStdKeyBackspace, EKeyBackspace, 0, 0); + events << FepReplayEvent(EStdKeyBackspace, EKeyBackspace, 0, 0); + events << FepReplayEvent('5', '5', 0, 0); + events << FepReplayEvent('4', '4', 0, 0); + events << FepReplayEvent('6', '6', 0, 0); + events << FepReplayEvent(EStdKeyBackspace, EKeyBackspace, 0, 0); + events << FepReplayEvent(EStdKeyBackspace, EKeyBackspace, 0, 0); + events << FepReplayEvent('1', '1', 0, 0); + events << FepReplayEvent(EStdKeyBackspace, EKeyBackspace, 0, 0); + events << FepReplayEvent('2', '2', 0, 0); + events << FepReplayEvent('1', '1', 0, 0); + QTest::newRow("Numbers (no FEP)") + << false + << Qt::InputMethodHints(Qt::ImhNone) + << 0 + << QLineEdit::Normal + << events + << QString("521") + << QString(""); + QTest::newRow("Numbers and password mode (no FEP)") + << false + << Qt::InputMethodHints(Qt::ImhNone) + << 0 + << QLineEdit::Password + << events + << QString("521") + << QString(""); + QTest::newRow("Numbers") + << true + << Qt::InputMethodHints(Qt::ImhDigitsOnly) + << 0 + << QLineEdit::Normal + << events + << QString("521") + << QString(""); + QTest::newRow("Numbers max length (no FEP)") + << false + << Qt::InputMethodHints(Qt::ImhNone) + << 2 + << QLineEdit::Normal + << events + << QString("21") + << QString(""); + QTest::newRow("Numbers max length") + << true + << Qt::InputMethodHints(Qt::ImhDigitsOnly) + << 2 + << QLineEdit::Normal + << events + << QString("21") + << QString(""); + events.clear(); + + events << FepReplayEvent(EEventKeyDown, '5', 0, 0, 0); + events << FepReplayEvent(EEventKey, '5', '5', 0, 0); + events << FepReplayEvent(EEventKey, '5', '5', 0, 1); + events << FepReplayEvent(EEventKey, '5', '5', 0, 1); + events << FepReplayEvent(EEventKeyUp, '5', 0, 0, 0); + QTest::newRow("Numbers and autorepeat (no FEP)") + << false + << Qt::InputMethodHints(Qt::ImhNone) + << 0 + << QLineEdit::Normal + << events + << QString("555") + << QString(""); + events.clear(); + + events << FepReplayEvent(EStdKeyBackspace, EKeyBackspace, 0, 0); + events << FepReplayEvent('2', '2', 0, 0); + events << FepReplayEvent('3', '3', 0, 0); + events << FepReplayEvent('4', '4', 0, 0); + events << FepReplayEvent('4', '4', 0, 0); + events << FepReplayEvent('5', '5', 0, 0); + events << FepReplayEvent('5', '5', 0, 0); + events << FepReplayEvent(EStdKeyBackspace, EKeyBackspace, 0, 0); + QTest::newRow("Multitap") + << true + << Qt::InputMethodHints(Qt::ImhNoPredictiveText) + << 0 + << QLineEdit::Normal + << events + << QString("Adh") + << QString(""); + QTest::newRow("Multitap with no auto uppercase") + << true + << Qt::InputMethodHints(Qt::ImhNoPredictiveText | Qt::ImhNoAutoUppercase) + << 0 + << QLineEdit::Normal + << events + << QString("adh") + << QString(""); + QTest::newRow("Multitap with uppercase") + << true + << Qt::InputMethodHints(Qt::ImhNoPredictiveText | Qt::ImhPreferUppercase) + << 0 + << QLineEdit::Normal + << events + << QString("ADH") + << QString(""); + QTest::newRow("Multitap with lowercase") + << true + << Qt::InputMethodHints(Qt::ImhNoPredictiveText | Qt::ImhPreferLowercase) + << 0 + << QLineEdit::Normal + << events + << QString("adh") + << QString(""); + QTest::newRow("Multitap with forced uppercase") + << true + << Qt::InputMethodHints(Qt::ImhNoPredictiveText | Qt::ImhUppercaseOnly) + << 0 + << QLineEdit::Normal + << events + << QString("ADH") + << QString(""); + QTest::newRow("Multitap with forced lowercase") + << true + << Qt::InputMethodHints(Qt::ImhNoPredictiveText | Qt::ImhLowercaseOnly) + << 0 + << QLineEdit::Normal + << events + << QString("adh") + << QString(""); + events.clear(); + + events << FepReplayEvent(EStdKeyHash, '#', 0, 0); + events << FepReplayEvent('2', '2', 0, 0); + events << FepReplayEvent('2', '2', 0, 0); + events << FepReplayEvent('3', '3', 0, 0); + events << FepReplayEvent('4', '4', 0, 0); + events << FepReplayEvent('4', '4', 0, 0); + events << FepReplayEvent('5', '5', 0, 0); + events << FepReplayEvent('5', '5', 0, 0); + events << FepReplayEvent(EStdKeyBackspace, EKeyBackspace, 0, 0); + QTest::newRow("Multitap with mode switch") + << true + << Qt::InputMethodHints(Qt::ImhNoPredictiveText) + << 0 + << QLineEdit::Normal + << events + << QString("bdh") + << QString(""); + events.clear(); + + events << FepReplayEvent('7', '7', 0, 0); + events << FepReplayEvent('7', '7', 0, 0); + events << FepReplayEvent('8', '8', 0, 0); + events << FepReplayEvent('9', '9', 0, 0); + events << FepReplayEvent('9', '9', 0, 0); + QTest::newRow("Multitap with unfinished text") + << true + << Qt::InputMethodHints(Qt::ImhNoPredictiveText) + << 0 + << QLineEdit::Normal + << events + << QString("Qt") + << QString("x"); + events << FepReplayEvent(2000); + QTest::newRow("Multitap with committed text") + << true + << Qt::InputMethodHints(Qt::ImhNoPredictiveText) + << 0 + << QLineEdit::Normal + << events + << QString("Qtx") + << QString(""); + events.clear(); + + events << FepReplayEvent('4', '4', 0, 0); + events << FepReplayEvent('4', '4', 0, 0); + // Simulate holding down hash key. + events << FepReplayEvent(EEventKeyDown, EStdKeyHash, 0, 0, 0); + events << FepReplayEvent(EEventKey, EStdKeyHash, '#', 0, 0); + events << FepReplayEvent(500); + events << FepReplayEvent(EEventKey, EStdKeyHash, '#', 0, 1); + events << FepReplayEvent(EEventKey, EStdKeyHash, '#', 0, 1); + events << FepReplayEvent(EEventKey, EStdKeyHash, '#', 0, 1); + events << FepReplayEvent(EEventKeyUp, EStdKeyHash, 0, 0, 0); + events << FepReplayEvent('7', '7', 0, 0); + events << FepReplayEvent('7', '7', 0, 0); + events << FepReplayEvent('8', '8', 0, 0); + // QTBUG-9867: Switch back as well to make sure we don't get extra symbols + events << FepReplayEvent(EEventKeyDown, EStdKeyHash, 0, 0, 0); + events << FepReplayEvent(EEventKey, EStdKeyHash, '#', 0, 0); + events << FepReplayEvent(500); + events << FepReplayEvent(EEventKey, EStdKeyHash, '#', 0, 1); + events << FepReplayEvent(EEventKey, EStdKeyHash, '#', 0, 1); + events << FepReplayEvent(EEventKey, EStdKeyHash, '#', 0, 1); + events << FepReplayEvent(EEventKeyUp, EStdKeyHash, 0, 0, 0); + events << FepReplayEvent('9', '9', 0, 0); + events << FepReplayEvent('6', '6', 0, 0); + events << FepReplayEvent('8', '8', 0, 0); + events << FepReplayEvent(2000); + events << FepReplayEvent(EStdKeyDevice3, EKeyDevice3, 0, 0); // Select key + QTest::newRow("Multitap and numbers") + << true + << Qt::InputMethodHints(Qt::ImhNoPredictiveText) + << 0 + << QLineEdit::Normal + << events + << QString("H778wmt") + << QString(""); + QTest::newRow("T9 and numbers") + << true + << Qt::InputMethodHints(Qt::ImhPreferLowercase) + << 0 + << QLineEdit::Normal + << events + << QString("hi778you") + << QString(""); + events.clear(); + + events << FepReplayEvent('4', '4', 0, 0); + events << FepReplayEvent('4', '4', 0, 0); + events << FepReplayEvent(EStdKeyDevice3, EKeyDevice3, 0, 0); // Select key + QTest::newRow("T9") + << true + << Qt::InputMethodHints(Qt::ImhPreferLowercase) + << 0 + << QLineEdit::Normal + << events + << QString("hi") + << QString(""); + QTest::newRow("T9 with uppercase") + << true + << Qt::InputMethodHints(Qt::ImhPreferUppercase) + << 0 + << QLineEdit::Normal + << events + << QString("HI") + << QString(""); + QTest::newRow("T9 with forced lowercase") + << true + << Qt::InputMethodHints(Qt::ImhLowercaseOnly) + << 0 + << QLineEdit::Normal + << events + << QString("hi") + << QString(""); + QTest::newRow("T9 with forced uppercase") + << true + << Qt::InputMethodHints(Qt::ImhUppercaseOnly) + << 0 + << QLineEdit::Normal + << events + << QString("HI") + << QString(""); + QTest::newRow("T9 with maxlength") + << true + << Qt::InputMethodHints(Qt::ImhLowercaseOnly) + << 1 + << QLineEdit::Normal + << events + << QString("i") + << QString(""); + events.clear(); + + events << FepReplayEvent('4', '4', 0, 0); + events << FepReplayEvent('4', '4', 0, 0); + events << FepReplayEvent(EStdKeyLeftArrow, EKeyLeftArrow, 0, 0); + events << FepReplayEvent(EStdKeyLeftArrow, EKeyLeftArrow, 0, 0); + events << FepReplayEvent('9', '9', 0, 0); + events << FepReplayEvent('6', '6', 0, 0); + events << FepReplayEvent('8', '8', 0, 0); + events << FepReplayEvent('0', '0', 0, 0); + events << FepReplayEvent(EStdKeyRightArrow, EKeyRightArrow, 0, 0); + events << FepReplayEvent(EStdKeyRightArrow, EKeyRightArrow, 0, 0); + events << FepReplayEvent('8', '8', 0, 0); + events << FepReplayEvent('8', '8', 0, 0); + QTest::newRow("T9 with movement and unfinished text") + << true + << Qt::InputMethodHints(Qt::ImhPreferLowercase) + << 0 + << QLineEdit::Normal + << events + << QString("you hi") + << QString("tv"); + QTest::newRow("T9 with movement, password and unfinished text") + << true + << Qt::InputMethodHints(Qt::ImhPreferLowercase) + << 0 + << QLineEdit::Password + << events + << QString("wmt h") + << QString("u"); + QTest::newRow("T9 with movement, maxlength, password and unfinished text") + << true + << Qt::InputMethodHints(Qt::ImhPreferLowercase) + << 2 + << QLineEdit::Password + << events + << QString("wh") + << QString(""); + QTest::newRow("T9 with movement, maxlength and unfinished text") + << true + << Qt::InputMethodHints(Qt::ImhPreferLowercase) + << 2 + << QLineEdit::Normal + << events + << QString("hi") + << QString(""); + QTest::newRow("Multitap with movement and unfinished text") + << true + << Qt::InputMethodHints(Qt::ImhNoPredictiveText | Qt::ImhPreferLowercase) + << 0 + << QLineEdit::Normal + << events + << QString("wmt h") + << QString("u"); + QTest::newRow("Multitap with movement, maxlength and unfinished text") + << true + << Qt::InputMethodHints(Qt::ImhNoPredictiveText | Qt::ImhPreferLowercase) + << 2 + << QLineEdit::Normal + << events + << QString("wh") + << QString(""); + QTest::newRow("Numbers with movement") + << true + << Qt::InputMethodHints(Qt::ImhDigitsOnly) + << 0 + << QLineEdit::Normal + << events + << QString("96804488") + << QString(""); + QTest::newRow("Numbers with movement and maxlength") + << true + << Qt::InputMethodHints(Qt::ImhDigitsOnly) + << 2 + << QLineEdit::Normal + << events + << QString("44") + << QString(""); + QTest::newRow("Numbers with movement, password and unfinished text") + << true + << Qt::InputMethodHints(Qt::ImhDigitsOnly) + << 0 + << QLineEdit::Password + << events + << QString("9680448") + << QString("8"); + QTest::newRow("Numbers with movement, maxlength, password and unfinished text") + << true + << Qt::InputMethodHints(Qt::ImhDigitsOnly) + << 2 + << QLineEdit::Password + << events + << QString("44") + << QString(""); + events << FepReplayEvent(EStdKeyRightArrow, EKeyRightArrow, 0, 0); + QTest::newRow("T9 with movement") + << true + << Qt::InputMethodHints(Qt::ImhPreferLowercase) + << 0 + << QLineEdit::Normal + << events + << QString("you htvi") + << QString(""); + QTest::newRow("T9 with movement and password") + << true + << Qt::InputMethodHints(Qt::ImhPreferLowercase) + << 0 + << QLineEdit::Password + << events + << QString("wmt hu") + << QString(""); + QTest::newRow("T9 with movement, maxlength and password") + << true + << Qt::InputMethodHints(Qt::ImhPreferLowercase) + << 2 + << QLineEdit::Password + << events + << QString("wh") + << QString(""); + QTest::newRow("Multitap with movement") + << true + << Qt::InputMethodHints(Qt::ImhNoPredictiveText | Qt::ImhPreferLowercase) + << 0 + << QLineEdit::Normal + << events + << QString("wmt hu") + << QString(""); + QTest::newRow("Multitap with movement and maxlength") + << true + << Qt::InputMethodHints(Qt::ImhNoPredictiveText | Qt::ImhPreferLowercase) + << 2 + << QLineEdit::Normal + << events + << QString("wh") + << QString(""); + QTest::newRow("Numbers with movement and password") + << true + << Qt::InputMethodHints(Qt::ImhDigitsOnly) + << 0 + << QLineEdit::Password + << events + << QString("96804488") + << QString(""); + QTest::newRow("Numbers with movement, maxlength and password") + << true + << Qt::InputMethodHints(Qt::ImhDigitsOnly) + << 2 + << QLineEdit::Password + << events + << QString("44") + << QString(""); + events.clear(); + + // Test that the symbol key successfully does nothing when in number-only mode. + events << FepReplayEvent(EEventKeyDown, EStdKeyLeftFunc, 0, 0, 0); + events << FepReplayEvent(EEventKeyUp, EStdKeyLeftFunc, 0, 0, 0); + QTest::newRow("Dead symbols key") + << true + << Qt::InputMethodHints(Qt::ImhDigitsOnly) + << 0 + << QLineEdit::Normal + << events + << QString("") + << QString(""); + QTest::newRow("Dead symbols key and password") + << true + << Qt::InputMethodHints(Qt::ImhDigitsOnly) + << 0 + << QLineEdit::Password + << events + << QString("") + << QString(""); + events.clear(); +#endif +} + +void tst_QInputContext::symbianTestCoeFepInputContext() +{ +#ifndef Q_OS_SYMBIAN + QSKIP("This is a Symbian-only test", SkipAll); +#else + QCoeFepInputContext *ic = qobject_cast<QCoeFepInputContext *>(qApp->inputContext()); + if (!ic) { + QSKIP("coefep is not the active input context; skipping test", SkipAll); + } + + QFETCH(bool, inputMethodEnabled); + QFETCH(Qt::InputMethodHints, inputMethodHints); + QFETCH(int, maxLength); + QFETCH(QLineEdit::EchoMode, echoMode); + QFETCH(QList<FepReplayEvent>, keyEvents); + QFETCH(QString, finalString); + QFETCH(QString, preeditString); + + if (inputMethodEnabled && m_phoneIsQwerty) { + QSKIP("Skipping advanced input method tests on QWERTY phones", SkipSingle); + } + + QWidget w; + QLayout *layout = new QVBoxLayout; + w.setLayout(layout); + QLineEdit *lineedit = new QLineEdit; + layout->addWidget(lineedit); + lineedit->setFocus(); +#ifdef QT_KEYPAD_NAVIGATION + lineedit->setEditFocus(true); +#endif + w.show(); + + lineedit->setAttribute(Qt::WA_InputMethodEnabled, inputMethodEnabled); + lineedit->setInputMethodHints(inputMethodHints); + if (maxLength > 0) + lineedit->setMaxLength(maxLength); + lineedit->setEchoMode(echoMode); + + QTest::qWait(200); + + foreach(FepReplayEvent event, keyEvents) { + event.replay(lineedit); + } + + QApplication::processEvents(); + + QCOMPARE(lineedit->text(), finalString); + QCOMPARE(ic->m_preeditString, preeditString); +#endif +} + +void tst_QInputContext::symbianTestCoeFepAutoCommit_data() +{ +#ifdef Q_OS_SYMBIAN + QTest::addColumn<Qt::InputMethodHints> ("inputMethodHints"); + QTest::addColumn<QLineEdit::EchoMode> ("echoMode"); + QTest::addColumn<QList<FepReplayEvent> > ("keyEvents"); + QTest::addColumn<QString> ("finalString"); + + QList<FepReplayEvent> events; + + events << FepReplayEvent('4', '4', 0, 0); + events << FepReplayEvent('4', '4', 0, 0); + events << FepReplayEvent('0', '0', 0, 0); + events << FepReplayEvent('9', '9', 0, 0); + events << FepReplayEvent('6', '6', 0, 0); + events << FepReplayEvent('8', '8', 0, 0); + QTest::newRow("Numbers") + << Qt::InputMethodHints(Qt::ImhDigitsOnly) + << QLineEdit::Normal + << events + << QString("440968"); + QTest::newRow("Numbers and password") + << Qt::InputMethodHints(Qt::ImhDigitsOnly) + << QLineEdit::Password + << events + << QString("440968"); + QTest::newRow("Multitap") + << Qt::InputMethodHints(Qt::ImhPreferLowercase | Qt::ImhNoPredictiveText) + << QLineEdit::Normal + << events + << QString("h wmt"); + QTest::newRow("T9") + << Qt::InputMethodHints(Qt::ImhPreferLowercase) + << QLineEdit::Normal + << events + << QString("hi you"); + QTest::newRow("Multitap with password") + << Qt::InputMethodHints(Qt::ImhPreferLowercase | Qt::ImhNoPredictiveText) + << QLineEdit::Password + << events + << QString("h wmt"); + QTest::newRow("T9 with password") + << Qt::InputMethodHints(Qt::ImhPreferLowercase) + << QLineEdit::Password + << events + << QString("h wmt"); +#endif +} + +void tst_QInputContext::symbianTestCoeFepAutoCommit() +{ +#ifndef Q_OS_SYMBIAN + QSKIP("This is a Symbian-only test", SkipAll); +#else + QCoeFepInputContext *ic = qobject_cast<QCoeFepInputContext *>(qApp->inputContext()); + if (!ic) { + QSKIP("coefep is not the active input context; skipping test", SkipAll); + } + + QFETCH(Qt::InputMethodHints, inputMethodHints); + QFETCH(QLineEdit::EchoMode, echoMode); + QFETCH(QList<FepReplayEvent>, keyEvents); + QFETCH(QString, finalString); + + if (m_phoneIsQwerty) { + QSKIP("Skipping advanced input method tests on QWERTY phones", SkipSingle); + } + + QWidget w; + QLayout *layout = new QVBoxLayout; + w.setLayout(layout); + QLineEdit *lineedit = new QLineEdit; + layout->addWidget(lineedit); + lineedit->setFocus(); +#ifdef QT_KEYPAD_NAVIGATION + lineedit->setEditFocus(true); +#endif + QPushButton *pushButton = new QPushButton("Done"); + layout->addWidget(pushButton); + QAction softkey("Done", &w); + softkey.setSoftKeyRole(QAction::PositiveSoftKey); + w.addAction(&softkey); + w.show(); + + lineedit->setInputMethodHints(inputMethodHints); + lineedit->setEchoMode(echoMode); + + QTest::qWait(200); + foreach(FepReplayEvent event, keyEvents) { + event.replay(lineedit); + } + QApplication::processEvents(); + + QTest::mouseClick(pushButton, Qt::LeftButton); + + QCOMPARE(lineedit->text(), finalString); + QVERIFY(ic->m_preeditString.isEmpty()); + +#ifdef Q_WS_S60 + lineedit->inputContext()->reset(); + lineedit->clear(); + lineedit->setFocus(); +#ifdef QT_KEYPAD_NAVIGATION + lineedit->setEditFocus(true); +#endif + + QTest::qWait(200); + foreach(FepReplayEvent event, keyEvents) { + event.replay(lineedit); + } + QApplication::processEvents(); + + FepReplayEvent(EStdKeyDevice0, EKeyDevice0, 0, 0).replay(lineedit); // Left softkey + + QCOMPARE(lineedit->text(), finalString); + QVERIFY(ic->m_preeditString.isEmpty()); + +#endif // Q_WS_S60 +#endif // Q_OS_SYMBIAN +} + QTEST_MAIN(tst_QInputContext) #include "tst_qinputcontext.moc" diff --git a/tests/auto/qkeysequence/tst_qkeysequence.cpp b/tests/auto/qkeysequence/tst_qkeysequence.cpp index 1faae6a..60f022f 100644 --- a/tests/auto/qkeysequence/tst_qkeysequence.cpp +++ b/tests/auto/qkeysequence/tst_qkeysequence.cpp @@ -532,20 +532,20 @@ void tst_QKeySequence::translated_data() QTest::addColumn<QString>("transKey"); QTest::addColumn<QString>("compKey"); - QTest::newRow("Shift++") << QString(tr("Shift++")) << QString("Umschalt++"); - QTest::newRow("Ctrl++") << QString(tr("Ctrl++")) << QString("Strg++"); - QTest::newRow("Alt++") << QString(tr("Alt++")) << QString("Alt++"); - QTest::newRow("Meta++") << QString(tr("Meta++")) << QString("Meta++"); - - QTest::newRow("Shift+,, Shift++") << QString(tr("Shift+,, Shift++")) << QString("Umschalt+,, Umschalt++"); - QTest::newRow("Shift+,, Ctrl++") << QString(tr("Shift+,, Ctrl++")) << QString("Umschalt+,, Strg++"); - QTest::newRow("Shift+,, Alt++") << QString(tr("Shift+,, Alt++")) << QString("Umschalt+,, Alt++"); - QTest::newRow("Shift+,, Meta++") << QString(tr("Shift+,, Meta++")) << QString("Umschalt+,, Meta++"); - - QTest::newRow("Ctrl+,, Shift++") << QString(tr("Ctrl+,, Shift++")) << QString("Strg+,, Umschalt++"); - QTest::newRow("Ctrl+,, Ctrl++") << QString(tr("Ctrl+,, Ctrl++")) << QString("Strg+,, Strg++"); - QTest::newRow("Ctrl+,, Alt++") << QString(tr("Ctrl+,, Alt++")) << QString("Strg+,, Alt++"); - QTest::newRow("Ctrl+,, Meta++") << QString(tr("Ctrl+,, Meta++")) << QString("Strg+,, Meta++"); + QTest::newRow("Shift++") << tr("Shift++") << QString("Umschalt++"); + QTest::newRow("Ctrl++") << tr("Ctrl++") << QString("Strg++"); + QTest::newRow("Alt++") << tr("Alt++") << QString("Alt++"); + QTest::newRow("Meta++") << tr("Meta++") << QString("Meta++"); + + QTest::newRow("Shift+,, Shift++") << tr("Shift+,, Shift++") << QString("Umschalt+,, Umschalt++"); + QTest::newRow("Shift+,, Ctrl++") << tr("Shift+,, Ctrl++") << QString("Umschalt+,, Strg++"); + QTest::newRow("Shift+,, Alt++") << tr("Shift+,, Alt++") << QString("Umschalt+,, Alt++"); + QTest::newRow("Shift+,, Meta++") << tr("Shift+,, Meta++") << QString("Umschalt+,, Meta++"); + + QTest::newRow("Ctrl+,, Shift++") << tr("Ctrl+,, Shift++") << QString("Strg+,, Umschalt++"); + QTest::newRow("Ctrl+,, Ctrl++") << tr("Ctrl+,, Ctrl++") << QString("Strg+,, Strg++"); + QTest::newRow("Ctrl+,, Alt++") << tr("Ctrl+,, Alt++") << QString("Strg+,, Alt++"); + QTest::newRow("Ctrl+,, Meta++") << tr("Ctrl+,, Meta++") << QString("Strg+,, Meta++"); qApp->removeTranslator(ourTranslator); qApp->removeTranslator(qtTranslator); diff --git a/tests/auto/qlineedit/tst_qlineedit.cpp b/tests/auto/qlineedit/tst_qlineedit.cpp index 717b32d..bfa9406 100644 --- a/tests/auto/qlineedit/tst_qlineedit.cpp +++ b/tests/auto/qlineedit/tst_qlineedit.cpp @@ -275,6 +275,7 @@ private slots: #endif void taskQTBUG_7395_readOnlyShortcut(); void QTBUG697_paletteCurrentColorGroup(); + void QTBUG13520_textNotVisible(); #ifdef QT3_SUPPORT void validateAndSet_data(); @@ -3034,6 +3035,8 @@ public: }; State state; + + friend class tst_QLineEdit; }; Q_DECLARE_METATYPE(LineEdit::State); @@ -3741,5 +3744,21 @@ void tst_QLineEdit::QTBUG697_paletteCurrentColorGroup() QCOMPARE(img.pixel(10, le.height()/2), QColor(Qt::red).rgb()); } +void tst_QLineEdit::QTBUG13520_textNotVisible() +{ + LineEdit le; + le.setAlignment( Qt::AlignRight | Qt::AlignVCenter);
+ le.show();
+ QTest::qWaitForWindowShown(&le);
+ le.setText("01-ST16-01SIL-MPL001wfgsdfgsdgsdfgsdfgsdfgsdfgsdfg");
+ le.setCursorPosition(0);
+ QTest::qWait(100); //just make sure we get he lineedit correcly painted
+
+ QVERIFY(le.cursorRect().center().x() < le.width() / 2);
+
+ +} + + QTEST_MAIN(tst_QLineEdit) #include "tst_qlineedit.moc" diff --git a/tests/auto/qlist/tst_qlist.cpp b/tests/auto/qlist/tst_qlist.cpp index ba8aefa..9f6b4a5 100644 --- a/tests/auto/qlist/tst_qlist.cpp +++ b/tests/auto/qlist/tst_qlist.cpp @@ -89,6 +89,8 @@ private slots: void testSTLIterators() const; void testOperators() const; + + void initializeList() const; }; void tst_QList::length() const @@ -662,5 +664,19 @@ void tst_QList::testSTLIterators() const QCOMPARE(*it, QLatin1String("foo")); } +void tst_QList::initializeList() const +{ +#ifdef QT_CXX0X_INITIALIZERLIST + QList<int> v1{2,3,4}; + QCOMPARE(v1, QList<int>() << 2 << 3 << 4); + QCOMPARE(v1, (QList<int>{2,3,4})); + + QList<QList<int>> v2{ v1, {1}, QList<int>(), {2,3,4} }; + QList<QList<int>> v3; + v3 << v1 << (QList<int>() << 1) << QList<int>() << v1; + QCOMPARE(v3, v2); +#endif +} + QTEST_APPLESS_MAIN(tst_QList) #include "tst_qlist.moc" diff --git a/tests/auto/qmake/qmake.pro b/tests/auto/qmake/qmake.pro index 8cae6be..d0faa87 100644 --- a/tests/auto/qmake/qmake.pro +++ b/tests/auto/qmake/qmake.pro @@ -1,6 +1,7 @@ load(qttest_p4) HEADERS += testcompiler.h SOURCES += tst_qmake.cpp testcompiler.cpp +QT -= gui cross_compile: DEFINES += QMAKE_CROSS_COMPILED diff --git a/tests/auto/qmake/testdata/substitutes/test.pro b/tests/auto/qmake/testdata/substitutes/test.pro index ddad93f..26b0272 100644 --- a/tests/auto/qmake/testdata/substitutes/test.pro +++ b/tests/auto/qmake/testdata/substitutes/test.pro @@ -1 +1,5 @@ -QMAKE_SUBSTITUTES += test.in sub/test2.in +QMAKE_SUBSTITUTES += test.in sub/test2.in indirect + +indirect.input = $$PWD/test3.txt +indirect.output = $$OUT_PWD/sub/indirect_test.txt + diff --git a/tests/auto/qmake/testdata/substitutes/test3.txt b/tests/auto/qmake/testdata/substitutes/test3.txt new file mode 100644 index 0000000..ce01362 --- /dev/null +++ b/tests/auto/qmake/testdata/substitutes/test3.txt @@ -0,0 +1 @@ +hello diff --git a/tests/auto/qmake/tst_qmake.cpp b/tests/auto/qmake/tst_qmake.cpp index 060fa01..1d3e128 100644 --- a/tests/auto/qmake/tst_qmake.cpp +++ b/tests/auto/qmake/tst_qmake.cpp @@ -99,7 +99,8 @@ private: tst_qmake::tst_qmake() { - QString cmd = QString("qmake \"QT_VERSION=%1\"").arg(QT_VERSION); + QString binpath = QLibraryInfo::location(QLibraryInfo::BinariesPath); + QString cmd = QString("%2/qmake \"QT_VERSION=%1\"").arg(QT_VERSION).arg(binpath); #ifdef Q_CC_MSVC test_compiler.setBaseCommands( "nmake", cmd ); #elif defined(Q_CC_MINGW) @@ -484,12 +485,14 @@ void tst_qmake::substitutes() QVERIFY( test_compiler.qmake( workDir, "test" )); QVERIFY( test_compiler.exists( workDir, "test", Plain, "" )); QVERIFY( test_compiler.exists( workDir, "sub/test2", Plain, "" )); + QVERIFY( test_compiler.exists( workDir, "sub/indirect_test.txt", Plain, "" )); QVERIFY( test_compiler.makeDistClean( workDir )); QString buildDir = base_path + "/testdata/substitutes_build"; QVERIFY( test_compiler.qmake( workDir, "test", buildDir )); QVERIFY( test_compiler.exists( buildDir, "test", Plain, "" )); QVERIFY( test_compiler.exists( buildDir, "sub/test2", Plain, "" )); + QVERIFY( test_compiler.exists( buildDir, "sub/indirect_test.txt", Plain, "" )); QVERIFY( test_compiler.makeDistClean( buildDir )); } diff --git a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp index bb91965..2ad4060 100644 --- a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp @@ -296,6 +296,7 @@ private Q_SLOTS: void ioGetFromHttpWithoutContentLength(); void ioGetFromHttpBrokenChunkedEncoding(); + void qtbug12908compressedHttpReply(); // NOTE: This test must be last! void parentingRepliesToTheApp(); @@ -4375,6 +4376,30 @@ void tst_QNetworkReply::ioGetFromHttpBrokenChunkedEncoding() QCOMPARE(reply->error(), QNetworkReply::NoError); } +// TODO: +// Prepare a gzip that has one chunk that expands to the size mentioned in the bugreport. +// Then have a custom HTTP server that waits after this chunk so the returning gets +// triggered. +void tst_QNetworkReply::qtbug12908compressedHttpReply() +{ + QString header("HTTP/1.0 200 OK\r\nContent-Encoding: gzip\r\nContent-Length: 63\r\n\r\n"); + + // dd if=/dev/zero of=qtbug-12908 bs=16384 count=1 && gzip qtbug-12908 && base64 -w 0 qtbug-12908.gz + QString encodedFile("H4sICDdDaUwAA3F0YnVnLTEyOTA4AO3BMQEAAADCoPVPbQwfoAAAAAAAAAAAAAAAAAAAAIC3AYbSVKsAQAAA"); + QByteArray decodedFile = QByteArray::fromBase64(encodedFile.toAscii()); + + MiniHttpServer server(header.toAscii() + decodedFile); + server.doClose = true; + + QNetworkRequest request(QUrl("http://localhost:" + QString::number(server.serverPort()))); + QNetworkReplyPtr reply = manager.get(request); + + connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); + QTestEventLoop::instance().enterLoop(10); + QVERIFY(!QTestEventLoop::instance().timeout()); + + QCOMPARE(reply->error(), QNetworkReply::NoError); +} // NOTE: This test must be last testcase in tst_qnetworkreply! void tst_QNetworkReply::parentingRepliesToTheApp() diff --git a/tests/auto/qpen/tst_qpen.cpp b/tests/auto/qpen/tst_qpen.cpp index 149f462..b0c2cad 100644 --- a/tests/auto/qpen/tst_qpen.cpp +++ b/tests/auto/qpen/tst_qpen.cpp @@ -213,6 +213,5 @@ void tst_QPen::stream() QCOMPARE(pen, cmp); } - QTEST_APPLESS_MAIN(tst_QPen) #include "tst_qpen.moc" diff --git a/tests/auto/qpluginloader/elftest/.gitattributes b/tests/auto/qpluginloader/elftest/.gitattributes new file mode 100644 index 0000000..891192c --- /dev/null +++ b/tests/auto/qpluginloader/elftest/.gitattributes @@ -0,0 +1,10 @@ +corrupt1.elf64.so set -crlf -diff +corrupt2.elf64.so set -crlf -diff +corrupt3.elf64.so set -crlf -diff +debugobj.so set -crlf -diff +garbage1.so set -crlf -diff +garbage2.so set -crlf -diff +garbage3.so set -crlf -diff +garbage4.so set -crlf -diff +garbage5.so set -crlf -diff + diff --git a/tests/auto/qpluginloader/elftest/corrupt1.elf64.so b/tests/auto/qpluginloader/elftest/corrupt1.elf64.so Binary files differnew file mode 100755 index 0000000..12ce736 --- /dev/null +++ b/tests/auto/qpluginloader/elftest/corrupt1.elf64.so diff --git a/tests/auto/qpluginloader/elftest/corrupt2.elf64.so b/tests/auto/qpluginloader/elftest/corrupt2.elf64.so Binary files differnew file mode 100755 index 0000000..11fdc2c --- /dev/null +++ b/tests/auto/qpluginloader/elftest/corrupt2.elf64.so diff --git a/tests/auto/qpluginloader/elftest/corrupt3.elf64.so b/tests/auto/qpluginloader/elftest/corrupt3.elf64.so Binary files differnew file mode 100755 index 0000000..94a2bc3 --- /dev/null +++ b/tests/auto/qpluginloader/elftest/corrupt3.elf64.so diff --git a/tests/auto/qpluginloader/elftest/debugobj.so b/tests/auto/qpluginloader/elftest/debugobj.so Binary files differnew file mode 100644 index 0000000..f0ee056 --- /dev/null +++ b/tests/auto/qpluginloader/elftest/debugobj.so diff --git a/tests/auto/qpluginloader/elftest/garbage1.so b/tests/auto/qpluginloader/elftest/garbage1.so new file mode 100644 index 0000000..0c74530 --- /dev/null +++ b/tests/auto/qpluginloader/elftest/garbage1.so @@ -0,0 +1,4 @@ +p¶¤Ðã¨ø±ÕÛcdL+ôúæî&‘¿&÷ýeü¥=კ² +•o°Ã’ÊŽI›§ÙÏmgƒ]!ÀZ +L'Ž)t± +ÙN»¸(e©×P)Y8öG ˆ6ß-yÈÏÀñŸ§÷—“"ô–ZÖÿ›kõ4â?Ë^náÁÇß5$ž’ôY=£ð#y
\ No newline at end of file diff --git a/tests/auto/qpluginloader/elftest/garbage2.so b/tests/auto/qpluginloader/elftest/garbage2.so new file mode 100644 index 0000000..c06338e --- /dev/null +++ b/tests/auto/qpluginloader/elftest/garbage2.so @@ -0,0 +1 @@ +£Çv.³Y‹¨tKëW3
\ No newline at end of file diff --git a/tests/auto/qpluginloader/elftest/garbage3.so b/tests/auto/qpluginloader/elftest/garbage3.so new file mode 100644 index 0000000..a24c523 --- /dev/null +++ b/tests/auto/qpluginloader/elftest/garbage3.so @@ -0,0 +1 @@ +£ÝÈÈ‚åžT-õ«´ÊôÚ¥ Àä¸ï¨ì¾œÀi8¼_ñxÓõª¾I±Ð×®ÝxÎ=úØ4@þñ[¨—úBàKS$ú
\ No newline at end of file diff --git a/tests/auto/qpluginloader/elftest/garbage4.so b/tests/auto/qpluginloader/elftest/garbage4.so new file mode 100644 index 0000000..4f45cf5 --- /dev/null +++ b/tests/auto/qpluginloader/elftest/garbage4.so @@ -0,0 +1 @@ +¶!¦\~çUu³†:9©ˆ œ§T+91ˆQ¬EøåÇšx¨ng5Óã—zhŒ–…ÿÆ^t™ŠµŽ¦'ÆÎmm*ˈdXH;vw+ªG“²ÃàØ
¨9Lƒ0!
\ No newline at end of file diff --git a/tests/auto/qpluginloader/elftest/garbage5.so b/tests/auto/qpluginloader/elftest/garbage5.so new file mode 100644 index 0000000..f8c0a1d --- /dev/null +++ b/tests/auto/qpluginloader/elftest/garbage5.so @@ -0,0 +1,2 @@ +ïÌô’Q² +ãµ-¢9Ò
\ No newline at end of file diff --git a/tests/auto/qpluginloader/tst/tst.pro b/tests/auto/qpluginloader/tst/tst.pro index 2d757e7..e270120 100644 --- a/tests/auto/qpluginloader/tst/tst.pro +++ b/tests/auto/qpluginloader/tst/tst.pro @@ -27,3 +27,5 @@ symbian: { DEPLOYMENT += libDep pluginDep } + +DEFINES += SRCDIR=\\\"$$PWD/../\\\" diff --git a/tests/auto/qpluginloader/tst_qpluginloader.cpp b/tests/auto/qpluginloader/tst_qpluginloader.cpp index 1e382b8..46fce5e 100644 --- a/tests/auto/qpluginloader/tst_qpluginloader.cpp +++ b/tests/auto/qpluginloader/tst_qpluginloader.cpp @@ -123,6 +123,9 @@ private slots: void loadHints(); void deleteinstanceOnUnload(); void checkingStubsFromDifferentDrives(); + void loadDebugObj(); + void loadCorruptElf(); + void loadGarbage(); }; tst_QPluginLoader::tst_QPluginLoader() @@ -350,5 +353,54 @@ void tst_QPluginLoader::checkingStubsFromDifferentDrives() #endif//Q_OS_SYMBIAN } +void tst_QPluginLoader::loadDebugObj() +{ +#if defined (__ELF__) + QVERIFY(QFile::exists(SRCDIR "elftest/debugobj.so")); + QPluginLoader lib1(SRCDIR "elftest/debugobj.so"); + QCOMPARE(lib1.load(), false); +#endif +} + +void tst_QPluginLoader::loadCorruptElf() +{ +#if defined (__ELF__) +if (sizeof(void*) == 8) { + QVERIFY(QFile::exists(SRCDIR "elftest/corrupt1.elf64.so")); + + QPluginLoader lib1(SRCDIR "elftest/corrupt1.elf64.so"); + QCOMPARE(lib1.load(), false); + QVERIFY(lib1.errorString().contains("not an ELF object")); + + QPluginLoader lib2(SRCDIR "elftest/corrupt2.elf64.so"); + QCOMPARE(lib2.load(), false); + QVERIFY(lib2.errorString().contains("invalid")); + + QPluginLoader lib3(SRCDIR "elftest/corrupt3.elf64.so"); + QCOMPARE(lib3.load(), false); + QVERIFY(lib3.errorString().contains("invalid")); +} else if (sizeof(void*) == 4) { + QPluginLoader libW(SRCDIR "elftest/corrupt3.elf64.so"); + QCOMPARE(libW.load(), false); + QVERIFY(libW.errorString().contains("architecture")); +} else { + QFAIL("Please port QElfParser to this platform or blacklist this test."); +} +#endif +} + +void tst_QPluginLoader::loadGarbage() +{ +#if defined (Q_OS_UNIX) && !defined(Q_OS_SYMBIAN) + for (int i=0; i<5; i++) { + QPluginLoader lib(QString(SRCDIR "elftest/garbage%1.so").arg(i)); + QCOMPARE(lib.load(), false); +#ifdef SHOW_ERRORS + qDebug() << lib.errorString(); +#endif + } +#endif +} + QTEST_APPLESS_MAIN(tst_QPluginLoader) #include "tst_qpluginloader.moc" diff --git a/tests/auto/qscriptengine/idtranslatable.js b/tests/auto/qscriptengine/idtranslatable.js new file mode 100644 index 0000000..554ca88 --- /dev/null +++ b/tests/auto/qscriptengine/idtranslatable.js @@ -0,0 +1,5 @@ +qsTrId("qtn_foo_bar"); + +var more_greeting_strings = [ QT_TRID_NOOP("qtn_needle"), QT_TRID_NOOP("qtn_haystack") ]; + +qsTrId("qtn_bar_baz", 10); diff --git a/tests/auto/qscriptengine/qscriptengine.qrc b/tests/auto/qscriptengine/qscriptengine.qrc index b87f985..fa55a5b 100644 --- a/tests/auto/qscriptengine/qscriptengine.qrc +++ b/tests/auto/qscriptengine/qscriptengine.qrc @@ -1,5 +1,6 @@ <!DOCTYPE RCC><RCC version="1.0"> <qresource> <file>translations/translatable_la.qm</file> + <file>translations/idtranslatable_la.qm</file> </qresource> </RCC> diff --git a/tests/auto/qscriptengine/translations/idtranslatable_la.qm b/tests/auto/qscriptengine/translations/idtranslatable_la.qm Binary files differnew file mode 100644 index 0000000..c8c0b72 --- /dev/null +++ b/tests/auto/qscriptengine/translations/idtranslatable_la.qm diff --git a/tests/auto/qscriptengine/translations/idtranslatable_la.ts b/tests/auto/qscriptengine/translations/idtranslatable_la.ts new file mode 100644 index 0000000..b6d7053 --- /dev/null +++ b/tests/auto/qscriptengine/translations/idtranslatable_la.ts @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8"?> +<!DOCTYPE TS> +<TS version="2.0" language="nb_NO"> +<context> + <name></name> + <message id="qtn_foo_bar"> + <location filename="idtranslatable.js" line="1"/> + <source></source> + <translation>First string</translation> + </message> + <message id="qtn_needle"> + <location filename="idtranslatable.js" line="3"/> + <source></source> + <translation>Second string</translation> + </message> + <message id="qtn_haystack"> + <location filename="idtranslatable.js" line="3"/> + <source></source> + <translation>Third string</translation> + </message> + <message id="qtn_bar_baz" numerus="yes"> + <location filename="idtranslatable.js" line="5"/> + <source></source> + <translation> + <numerusform>Fourth string</numerusform> + <numerusform>%n fooish bar(s) found</numerusform> + </translation> + </message> +</context> +</TS> diff --git a/tests/auto/qscriptengine/tst_qscriptengine.cpp b/tests/auto/qscriptengine/tst_qscriptengine.cpp index 04b2627..b035492 100644 --- a/tests/auto/qscriptengine/tst_qscriptengine.cpp +++ b/tests/auto/qscriptengine/tst_qscriptengine.cpp @@ -162,6 +162,7 @@ private slots: void translateWithInvalidArgs(); void translationContext_data(); void translationContext(); + void translateScriptIdBased(); void functionScopes(); void nativeFunctionScopes(); void evaluateProgram(); @@ -173,6 +174,10 @@ private slots: void reentrency(); void newFixedStaticScopeObject(); void newGrowingStaticScopeObject(); + void dateRoundtripJSQtJS(); + void dateRoundtripQtJSQt(); + void dateConversionJSQt(); + void dateConversionQtJS(); }; tst_QScriptEngine::tst_QScriptEngine() @@ -4416,6 +4421,8 @@ void tst_QScriptEngine::installTranslatorFunctions() QVERIFY(!global.property("QT_TRANSLATE_NOOP").isValid()); QVERIFY(!global.property("qsTr").isValid()); QVERIFY(!global.property("QT_TR_NOOP").isValid()); + QVERIFY(!global.property("qsTrId").isValid()); + QVERIFY(!global.property("QT_TRID_NOOP").isValid()); QVERIFY(!globalOrig.property("String").property("prototype").property("arg").isValid()); eng.installTranslatorFunctions(); @@ -4423,6 +4430,8 @@ void tst_QScriptEngine::installTranslatorFunctions() QVERIFY(global.property("QT_TRANSLATE_NOOP").isFunction()); QVERIFY(global.property("qsTr").isFunction()); QVERIFY(global.property("QT_TR_NOOP").isFunction()); + QVERIFY(global.property("qsTrId").isFunction()); + QVERIFY(global.property("QT_TRID_NOOP").isFunction()); QVERIFY(globalOrig.property("String").property("prototype").property("arg").isFunction()); if (useCustomGlobalObject) { @@ -4430,6 +4439,8 @@ void tst_QScriptEngine::installTranslatorFunctions() QVERIFY(!globalOrig.property("QT_TRANSLATE_NOOP").isValid()); QVERIFY(!globalOrig.property("qsTr").isValid()); QVERIFY(!globalOrig.property("QT_TR_NOOP").isValid()); + QVERIFY(!globalOrig.property("qsTrId").isValid()); + QVERIFY(!globalOrig.property("QT_TRID_NOOP").isValid()); } { @@ -4457,6 +4468,17 @@ void tst_QScriptEngine::installTranslatorFunctions() QVERIFY(ret.isString()); QCOMPARE(ret.toString(), QString::fromLatin1("foobar")); } + + { + QScriptValue ret = eng.evaluate("qsTrId('foo')"); + QVERIFY(ret.isString()); + QCOMPARE(ret.toString(), QString::fromLatin1("foo")); + } + { + QScriptValue ret = eng.evaluate("QT_TRID_NOOP('foo')"); + QVERIFY(ret.isString()); + QCOMPARE(ret.toString(), QString::fromLatin1("foo")); + } } static QScriptValue callQsTr(QScriptContext *ctx, QScriptEngine *eng) @@ -4567,6 +4589,10 @@ void tst_QScriptEngine::translateWithInvalidArgs_data() QTest::newRow("qsTranslate('foo', 'bar', 'baz', 123)") << "qsTranslate('foo', 'bar', 'baz', 123)" << "Error: qsTranslate(): fourth argument (encoding) must be a string"; QTest::newRow("qsTranslate('foo', 'bar', 'baz', 'zab', 'rab')") << "qsTranslate('foo', 'bar', 'baz', 'zab', 'rab')" << "Error: qsTranslate(): fifth argument (n) must be a number"; QTest::newRow("qsTranslate('foo', 'bar', 'baz', 'zab', 123)") << "qsTranslate('foo', 'bar', 'baz', 'zab', 123)" << "Error: qsTranslate(): invalid encoding 'zab'"; + + QTest::newRow("qsTrId()") << "qsTrId()" << "Error: qsTrId() requires at least one argument"; + QTest::newRow("qsTrId(123)") << "qsTrId(123)" << "TypeError: qsTrId(): first argument (id) must be a string"; + QTest::newRow("qsTrId('foo', 'bar')") << "qsTrId('foo', 'bar')" << "TypeError: qsTrId(): second argument (n) must be a number"; } void tst_QScriptEngine::translateWithInvalidArgs() @@ -4628,6 +4654,53 @@ void tst_QScriptEngine::translationContext() QCoreApplication::instance()->removeTranslator(&translator); } +void tst_QScriptEngine::translateScriptIdBased() +{ + QScriptEngine engine; + + QTranslator translator; + translator.load(":/translations/idtranslatable_la"); + QCoreApplication::instance()->installTranslator(&translator); + engine.installTranslatorFunctions(); + + QString fileName = QString::fromLatin1("idtranslatable.js"); + + QHash<QString, QString> expectedTranslations; + expectedTranslations["qtn_foo_bar"] = "First string"; + expectedTranslations["qtn_needle"] = "Second string"; + expectedTranslations["qtn_haystack"] = "Third string"; + expectedTranslations["qtn_bar_baz"] = "Fourth string"; + + QHash<QString, QString>::const_iterator it; + for (it = expectedTranslations.constBegin(); it != expectedTranslations.constEnd(); ++it) { + for (int x = 0; x < 2; ++x) { + QString fn; + if (x) + fn = fileName; + // Top-level + QCOMPARE(engine.evaluate(QString::fromLatin1("qsTrId('%0')") + .arg(it.key()), fn).toString(), + it.value()); + QCOMPARE(engine.evaluate(QString::fromLatin1("QT_TRID_NOOP('%0')") + .arg(it.key()), fn).toString(), + it.key()); + // From function + QCOMPARE(engine.evaluate(QString::fromLatin1("(function() { return qsTrId('%0'); })()") + .arg(it.key()), fn).toString(), + it.value()); + QCOMPARE(engine.evaluate(QString::fromLatin1("(function() { return QT_TRID_NOOP('%0'); })()") + .arg(it.key()), fn).toString(), + it.key()); + } + } + + // Plural form + QCOMPARE(engine.evaluate("qsTrId('qtn_bar_baz', 10)").toString(), + QString::fromLatin1("10 fooish bar(s) found")); + QCOMPARE(engine.evaluate("qsTrId('qtn_foo_bar', 10)").toString(), + QString::fromLatin1("qtn_foo_bar")); // Doesn't have plural +} + void tst_QScriptEngine::functionScopes() { QScriptEngine eng; @@ -4998,6 +5071,68 @@ void tst_QScriptEngine::qRegExpInport() } } +// QScriptValue::toDateTime() returns a local time, whereas JS dates +// are always stored as UTC. QtScript must respect the current time +// zone, and correctly adjust for daylight saving time that may be in +// effect at a given date (QTBUG-9770). +void tst_QScriptEngine::dateRoundtripJSQtJS() +{ + uint secs = QDateTime(QDate(2009, 1, 1)).toUTC().toTime_t(); + QScriptEngine eng; + for (int i = 0; i < 8000; ++i) { + QScriptValue jsDate = eng.evaluate(QString::fromLatin1("new Date(%0)").arg(secs * 1000.0)); + QDateTime qtDate = jsDate.toDateTime(); + QScriptValue jsDate2 = eng.newDate(qtDate); + if (jsDate2.toNumber() != jsDate.toNumber()) + QFAIL(qPrintable(jsDate.toString())); + secs += 2*60*60; + } +} + +void tst_QScriptEngine::dateRoundtripQtJSQt() +{ + QDateTime qtDate = QDateTime(QDate(2009, 1, 1)); + QScriptEngine eng; + for (int i = 0; i < 8000; ++i) { + QScriptValue jsDate = eng.newDate(qtDate); + QDateTime qtDate2 = jsDate.toDateTime(); + if (qtDate2 != qtDate) + QFAIL(qPrintable(qtDate.toString())); + qtDate = qtDate.addSecs(2*60*60); + } +} + +void tst_QScriptEngine::dateConversionJSQt() +{ + uint secs = QDateTime(QDate(2009, 1, 1)).toUTC().toTime_t(); + QScriptEngine eng; + for (int i = 0; i < 8000; ++i) { + QScriptValue jsDate = eng.evaluate(QString::fromLatin1("new Date(%0)").arg(secs * 1000.0)); + QDateTime qtDate = jsDate.toDateTime(); + QString qtUTCDateStr = qtDate.toUTC().toString(Qt::ISODate); + QString jsUTCDateStr = jsDate.property("toISOString").call(jsDate).toString(); + jsUTCDateStr.chop(5); // get rid of milliseconds (".000Z") + if (qtUTCDateStr != jsUTCDateStr) + QFAIL(qPrintable(jsDate.toString())); + secs += 2*60*60; + } +} + +void tst_QScriptEngine::dateConversionQtJS() +{ + QDateTime qtDate = QDateTime(QDate(2009, 1, 1)); + QScriptEngine eng; + for (int i = 0; i < 8000; ++i) { + QScriptValue jsDate = eng.newDate(qtDate); + QString jsUTCDateStr = jsDate.property("toISOString").call(jsDate).toString(); + jsUTCDateStr.chop(5); // get rid of milliseconds (".000Z") + QString qtUTCDateStr = qtDate.toUTC().toString(Qt::ISODate); + if (jsUTCDateStr != qtUTCDateStr) + QFAIL(qPrintable(qtDate.toString())); + qtDate = qtDate.addSecs(2*60*60); + } +} + static QScriptValue createAnotherEngine(QScriptContext *, QScriptEngine *) { QScriptEngine eng; diff --git a/tests/auto/qsslsocket/tst_qsslsocket.cpp b/tests/auto/qsslsocket/tst_qsslsocket.cpp index 6c1dd8f..d6a7a01 100644 --- a/tests/auto/qsslsocket/tst_qsslsocket.cpp +++ b/tests/auto/qsslsocket/tst_qsslsocket.cpp @@ -183,6 +183,7 @@ private slots: void ignoreSslErrorsListWithSlot(); void readFromClosedSocket(); void writeBigChunk(); + void setEmptyDefaultConfiguration(); static void exitLoop() { @@ -1835,6 +1836,21 @@ void tst_QSslSocket::writeBigChunk() socket->close(); } +void tst_QSslSocket::setEmptyDefaultConfiguration() +{ + // used to produce a crash in QSslConfigurationPrivate::deepCopyDefaultConfiguration, QTBUG-13265 + + if (!QSslSocket::supportsSsl()) + return; + + QSslConfiguration emptyConf; + QSslConfiguration::setDefaultConfiguration(emptyConf); + + QSslSocketPtr socket = newSocket(); + socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 443); + +} + #endif // QT_NO_OPENSSL QTEST_MAIN(tst_QSslSocket) diff --git a/tests/auto/qstatictext/tst_qstatictext.cpp b/tests/auto/qstatictext/tst_qstatictext.cpp index 6498ae4..49d6633 100644 --- a/tests/auto/qstatictext/tst_qstatictext.cpp +++ b/tests/auto/qstatictext/tst_qstatictext.cpp @@ -73,6 +73,8 @@ private slots: void prepareToCorrectData(); void prepareToWrongData(); + void copyConstructor(); + void translatedPainter(); void rotatedPainter(); void scaledPainter(); @@ -107,6 +109,31 @@ void tst_QStaticText::constructionAndDestruction() QStaticText text("My text"); } +void tst_QStaticText::copyConstructor() +{ + QStaticText text(QLatin1String("My text")); + + QTextOption textOption(Qt::AlignRight); + text.setTextOption(textOption); + + text.setPerformanceHint(QStaticText::AggressiveCaching); + text.setTextWidth(123.456); + text.setTextFormat(Qt::PlainText); + + QStaticText copiedText(text); + copiedText.setText(QLatin1String("Other text")); + + QCOMPARE(copiedText.textOption().alignment(), Qt::AlignRight); + QCOMPARE(copiedText.performanceHint(), QStaticText::AggressiveCaching); + QCOMPARE(copiedText.textWidth(), 123.456); + QCOMPARE(copiedText.textFormat(), Qt::PlainText); + + QStaticText otherCopiedText(copiedText); + otherCopiedText.setTextWidth(789); + + QCOMPARE(otherCopiedText.text(), QString::fromLatin1("Other text")); +} + Q_DECLARE_METATYPE(QStaticText::PerformanceHint) void tst_QStaticText::drawToPoint_data() { diff --git a/tests/auto/qstylesheetstyle/tst_qstylesheetstyle.cpp b/tests/auto/qstylesheetstyle/tst_qstylesheetstyle.cpp index e370309..04b1e79 100644 --- a/tests/auto/qstylesheetstyle/tst_qstylesheetstyle.cpp +++ b/tests/auto/qstylesheetstyle/tst_qstylesheetstyle.cpp @@ -698,20 +698,25 @@ void tst_QStyleSheetStyle::fontPrecedence() QCOMPARE(FONTSIZE(edit2), 26); } -static bool testForColors(const QImage& image, const QColor& color) +// Ensure primary will only return true if the color covers more than 50% of pixels +static bool testForColors(const QImage& image, const QColor& color, bool ensurePrimary=false) { int count = 0; QRgb rgb = color.rgba(); + int totalCount = image.height()*image.width(); for (int y = 0; y < image.height(); ++y) { for (int x = 0; x < image.width(); ++x) { // Because of antialiasing we allow a certain range of errors here. QRgb pixel = image.pixel(x, y); + if (qAbs((int)(pixel & 0xff) - (int)(rgb & 0xff)) + qAbs((int)((pixel & 0xff00) >> 8) - (int)((rgb & 0xff00) >> 8)) + qAbs((int)((pixel & 0xff0000) >> 16) - (int)((rgb & 0xff0000) >> 16)) <= 50) { - if (++count >= 10) { + count++; + if (!ensurePrimary && count >=10 ) + return true; + else if (count > totalCount/2) return true; - } } } } @@ -1528,6 +1533,15 @@ void tst_QStyleSheetStyle::task188195_baseBackground() tree.render(&image); QVERIFY(testForColors(image, tree.palette().base().color())); QVERIFY(!testForColors(image, QColor(0xab, 0x12, 0x51))); + + QTableWidget table(12, 12); + table.setItem(0, 0, new QTableWidgetItem()); + table.setStyleSheet( "QTableView {background-color: #ff0000}" ); + table.show(); + QTest::qWait(20); + image = QImage(table.width(), table.height(), QImage::Format_ARGB32); + table.render(&image); + QVERIFY(testForColors(image, Qt::red, true)); } void tst_QStyleSheetStyle::task232085_spinBoxLineEditBg() diff --git a/tests/auto/qtextlist/tst_qtextlist.cpp b/tests/auto/qtextlist/tst_qtextlist.cpp index 3e92836..8ad0898 100644 --- a/tests/auto/qtextlist/tst_qtextlist.cpp +++ b/tests/auto/qtextlist/tst_qtextlist.cpp @@ -67,6 +67,9 @@ private slots: void item(); void autoNumbering(); void autoNumberingRTL(); + void autoNumberingPrefixAndSuffix(); + void autoNumberingPrefixAndSuffixRTL(); + void autoNumberingPrefixAndSuffixHtmlExportImport(); void romanNumbering(); void romanNumberingLimit(); void formatChange(); @@ -128,6 +131,76 @@ void tst_QTextList::autoNumbering() QVERIFY(cursor.currentList()->itemText(cursor.block()) == "ab."); } +void tst_QTextList::autoNumberingPrefixAndSuffix() +{ + QTextListFormat fmt; + fmt.setStyle(QTextListFormat::ListLowerAlpha); + fmt.setNumberPrefix("-"); + fmt.setNumberSuffix(")"); + QTextList *list = cursor.createList(fmt); + QVERIFY(list); + + for (int i = 0; i < 27; ++i) + cursor.insertBlock(); + + QVERIFY(list->count() == 28); + + QVERIFY(cursor.currentList()); + QVERIFY(cursor.currentList()->itemNumber(cursor.block()) == 27); + QVERIFY(cursor.currentList()->itemText(cursor.block()) == "-ab)"); +} + +void tst_QTextList::autoNumberingPrefixAndSuffixRTL() +{ + QTextBlockFormat bfmt; + bfmt.setLayoutDirection(Qt::RightToLeft); + cursor.setBlockFormat(bfmt); + + QTextListFormat fmt; + fmt.setStyle(QTextListFormat::ListUpperAlpha); + fmt.setNumberPrefix("-"); + fmt.setNumberSuffix("*"); + QTextList *list = cursor.createList(fmt); + QVERIFY(list); + + cursor.insertBlock(); + + QVERIFY(list->count() == 2); + + QVERIFY(cursor.currentList()->itemText(cursor.block()) == "*B-"); +} + +void tst_QTextList::autoNumberingPrefixAndSuffixHtmlExportImport() +{ + QTextListFormat fmt; + fmt.setStyle(QTextListFormat::ListLowerAlpha); + fmt.setNumberPrefix("\""); + fmt.setNumberSuffix("#"); + fmt.setIndent(10); + // FIXME: Would like to test "'" but there's a problem in the css parser (Scanner::preprocess + // is called before the values are being parsed), so the quoting does not work. + QTextList *list = cursor.createList(fmt); + QVERIFY(list); + + for (int i = 0; i < 27; ++i) + cursor.insertBlock(); + + QVERIFY(list->count() == 28); + + QString htmlExport = doc->toHtml(); + QTextDocument importDoc; + importDoc.setHtml(htmlExport); + + QTextCursor importCursor(&importDoc); + for (int i = 0; i < 27; ++i) + importCursor.movePosition(QTextCursor::NextBlock); + + QVERIFY(importCursor.currentList()); + QVERIFY(importCursor.currentList()->itemNumber(importCursor.block()) == 27); + QVERIFY(importCursor.currentList()->itemText(importCursor.block()) == "\"ab#"); + QVERIFY(importCursor.currentList()->format().indent() == 10); +} + void tst_QTextList::autoNumberingRTL() { QTextBlockFormat bfmt; diff --git a/tests/auto/qtimer/tst_qtimer.cpp b/tests/auto/qtimer/tst_qtimer.cpp index 8d213ed..b651187 100644 --- a/tests/auto/qtimer/tst_qtimer.cpp +++ b/tests/auto/qtimer/tst_qtimer.cpp @@ -161,8 +161,9 @@ void tst_QTimer::singleShotTimeout() QCOMPARE(helper.count, 1); } -#if defined(Q_OS_SYMBIAN) && defined(Q_CC_NOKIAX86) -// Increase wait as emulator startup can cause unexpected delays +#if defined(Q_OS_SYMBIAN) +// Increase wait as emulator startup can cause unexpected delays, and +// on hardware there are sometimes spikes right after process startup. #define TIMEOUT_TIMEOUT 2000 #else #define TIMEOUT_TIMEOUT 200 diff --git a/tests/auto/qtouchevent/tst_qtouchevent.cpp b/tests/auto/qtouchevent/tst_qtouchevent.cpp index bb80fde..4219ef4 100644 --- a/tests/auto/qtouchevent/tst_qtouchevent.cpp +++ b/tests/auto/qtouchevent/tst_qtouchevent.cpp @@ -109,6 +109,7 @@ class tst_QTouchEventGraphicsItem : public QGraphicsItem public: QList<QTouchEvent::TouchPoint> touchBeginPoints, touchUpdatePoints, touchEndPoints; bool seenTouchBegin, seenTouchUpdate, seenTouchEnd; + int touchBeginCounter, touchUpdateCounter, touchEndCounter; bool acceptTouchBegin, acceptTouchUpdate, acceptTouchEnd; bool deleteInTouchBegin, deleteInTouchUpdate, deleteInTouchEnd; tst_QTouchEventGraphicsItem **weakpointer; @@ -131,6 +132,7 @@ public: touchUpdatePoints.clear(); touchEndPoints.clear(); seenTouchBegin = seenTouchUpdate = seenTouchEnd = false; + touchBeginCounter = touchUpdateCounter = touchEndCounter = 0; acceptTouchBegin = acceptTouchUpdate = acceptTouchEnd = true; deleteInTouchBegin = deleteInTouchUpdate = deleteInTouchEnd = false; } @@ -146,6 +148,7 @@ public: if (seenTouchUpdate) qWarning("TouchBegin: TouchUpdate cannot happen before TouchBegin"); if (seenTouchEnd) qWarning("TouchBegin: TouchEnd cannot happen before TouchBegin"); seenTouchBegin = !seenTouchBegin && !seenTouchUpdate && !seenTouchEnd; + ++touchBeginCounter; touchBeginPoints = static_cast<QTouchEvent *>(event)->touchPoints(); event->setAccepted(acceptTouchBegin); if (deleteInTouchBegin) @@ -155,6 +158,7 @@ public: if (!seenTouchBegin) qWarning("TouchUpdate: have not seen TouchBegin"); if (seenTouchEnd) qWarning("TouchUpdate: TouchEnd cannot happen before TouchUpdate"); seenTouchUpdate = seenTouchBegin && !seenTouchEnd; + ++touchUpdateCounter; touchUpdatePoints = static_cast<QTouchEvent *>(event)->touchPoints(); event->setAccepted(acceptTouchUpdate); if (deleteInTouchUpdate) @@ -164,6 +168,7 @@ public: if (!seenTouchBegin) qWarning("TouchEnd: have not seen TouchBegin"); if (seenTouchEnd) qWarning("TouchEnd: already seen a TouchEnd"); seenTouchEnd = seenTouchBegin && !seenTouchEnd; + ++touchEndCounter; touchEndPoints = static_cast<QTouchEvent *>(event)->touchPoints(); event->setAccepted(acceptTouchEnd); if (deleteInTouchEnd) @@ -194,6 +199,7 @@ private slots: void deleteInEventHandler(); void deleteInRawEventTranslation(); void crashInQGraphicsSceneAfterNotHandlingTouchBegin(); + void touchBeginWithGraphicsWidget(); }; void tst_QTouchEvent::touchDisabledByDefault() @@ -1334,6 +1340,59 @@ void tst_QTouchEvent::crashInQGraphicsSceneAfterNotHandlingTouchBegin() QTest::touchEvent(view.viewport()).release(0, view.mapFromScene(QPoint(10, 10))); } +void tst_QTouchEvent::touchBeginWithGraphicsWidget() +{ + QGraphicsScene scene; + QGraphicsView view(&scene); + tst_QTouchEventGraphicsItem *root; + root = new tst_QTouchEventGraphicsItem; + root->setAcceptTouchEvents(true); + scene.addItem(root); + + QGraphicsWidget *glassWidget = new QGraphicsWidget; + glassWidget->setMinimumSize(100, 100); + scene.addItem(glassWidget); + + view.resize(200, 200); + view.show(); + QTest::qWaitForWindowShown(&view); + view.fitInView(scene.sceneRect()); + + QTest::touchEvent() + .press(0, view.mapFromScene(root->mapToScene(3,3)), view.viewport()); + QTest::touchEvent() + .stationary(0) + .press(1, view.mapFromScene(root->mapToScene(6,6)), view.viewport()); + QTest::touchEvent() + .release(0, view.mapFromScene(root->mapToScene(3,3)), view.viewport()) + .release(1, view.mapFromScene(root->mapToScene(6,6)), view.viewport()); + + QCOMPARE(root->touchBeginCounter, 1); + QCOMPARE(root->touchUpdateCounter, 1); + QCOMPARE(root->touchEndCounter, 1); + QCOMPARE(root->touchUpdatePoints.size(), 2); + + root->reset(); + glassWidget->setWindowFlags(Qt::Window); // make the glassWidget a panel + + QTest::touchEvent() + .press(0, view.mapFromScene(root->mapToScene(3,3)), view.viewport()); + QTest::touchEvent() + .stationary(0) + .press(1, view.mapFromScene(root->mapToScene(6,6)), view.viewport()); + QTest::touchEvent() + .release(0, view.mapFromScene(root->mapToScene(3,3)), view.viewport()) + .release(1, view.mapFromScene(root->mapToScene(6,6)), view.viewport()); + + QCOMPARE(root->touchBeginCounter, 0); + QCOMPARE(root->touchUpdateCounter, 0); + QCOMPARE(root->touchEndCounter, 0); + + + delete root; + delete glassWidget; +} + QTEST_MAIN(tst_QTouchEvent) #include "tst_qtouchevent.moc" diff --git a/tests/auto/qudpsocket/tst_qudpsocket.cpp b/tests/auto/qudpsocket/tst_qudpsocket.cpp index abed55c..32fab6b 100644 --- a/tests/auto/qudpsocket/tst_qudpsocket.cpp +++ b/tests/auto/qudpsocket/tst_qudpsocket.cpp @@ -50,11 +50,13 @@ #include <qhostinfo.h> #include <qmap.h> #include <QNetworkProxy> +#include <QNetworkInterface> #include <qstringlist.h> #include "../network-settings.h" Q_DECLARE_METATYPE(QHostAddress) +Q_DECLARE_METATYPE(QNetworkInterface) //TESTED_CLASS= //TESTED_FILES= @@ -94,6 +96,18 @@ private slots: void outOfProcessConnectedClientServerTest(); void outOfProcessUnconnectedClientServerTest(); void zeroLengthDatagram(); + void multicastTtlOption_data(); + void multicastTtlOption(); + void multicastLoopbackOption_data(); + void multicastLoopbackOption(); + void multicastJoinBeforeBind_data(); + void multicastJoinBeforeBind(); + void multicastLeaveAfterClose_data(); + void multicastLeaveAfterClose(); + void setMulticastInterface_data(); + void setMulticastInterface(); + void multicast_data(); + void multicast(); protected slots: void empty_readyReadSlot(); @@ -844,5 +858,242 @@ void tst_QUdpSocket::zeroLengthDatagram() QCOMPARE(receiver.readDatagram(&buf, 1), qint64(0)); } +void tst_QUdpSocket::multicastTtlOption_data() +{ + QTest::addColumn<QHostAddress>("bindAddress"); + QTest::addColumn<int>("ttl"); + QTest::addColumn<int>("expected"); + + QList<QHostAddress> addresses; + addresses += QHostAddress(QHostAddress::Any); + addresses += QHostAddress(QHostAddress::AnyIPv6); + + foreach (const QHostAddress &address, addresses) { + QTest::newRow(QString("%1 0").arg(address.toString()).toAscii()) << address << 0 << 0; + QTest::newRow(QString("%1 1").arg(address.toString()).toAscii()) << address << 1 << 1; + QTest::newRow(QString("%1 2").arg(address.toString()).toAscii()) << address << 2 << 2; + QTest::newRow(QString("%1 128").arg(address.toString()).toAscii()) << address << 128 << 128; + QTest::newRow(QString("%1 255").arg(address.toString()).toAscii()) << address << 255 << 255; + QTest::newRow(QString("%1 1024").arg(address.toString()).toAscii()) << address << 1024 << 1; + } +} + +void tst_QUdpSocket::multicastTtlOption() +{ + QFETCH_GLOBAL(bool, setProxy); + QFETCH(QHostAddress, bindAddress); + QFETCH(int, ttl); + QFETCH(int, expected); + if (setProxy) { + // UDP multicast does not work with proxies + expected = 0; + } + + QUdpSocket udpSocket; + // bind, but ignore the result, we are only interested in initializing the socket + (void) udpSocket.bind(bindAddress, 0); + udpSocket.setSocketOption(QUdpSocket::MulticastTtlOption, ttl); + QCOMPARE(udpSocket.socketOption(QUdpSocket::MulticastTtlOption).toInt(), expected); +} + +void tst_QUdpSocket::multicastLoopbackOption_data() +{ + QTest::addColumn<QHostAddress>("bindAddress"); + QTest::addColumn<int>("loopback"); + QTest::addColumn<int>("expected"); + + QList<QHostAddress> addresses; + addresses += QHostAddress(QHostAddress::Any); + addresses += QHostAddress(QHostAddress::AnyIPv6); + + foreach (const QHostAddress &address, addresses) { + QTest::newRow(QString("%1 0").arg(address.toString()).toAscii()) << address << 0 << 0; + QTest::newRow(QString("%1 1").arg(address.toString()).toAscii()) << address << 1 << 1; + QTest::newRow(QString("%1 2").arg(address.toString()).toAscii()) << address << 2 << 1; + QTest::newRow(QString("%1 0 again").arg(address.toString()).toAscii()) << address << 0 << 0; + QTest::newRow(QString("%1 2 again").arg(address.toString()).toAscii()) << address << 2 << 1; + QTest::newRow(QString("%1 0 last time").arg(address.toString()).toAscii()) << address << 0 << 0; + QTest::newRow(QString("%1 1 again").arg(address.toString()).toAscii()) << address << 1 << 1; + } +} + +void tst_QUdpSocket::multicastLoopbackOption() +{ + QFETCH_GLOBAL(bool, setProxy); + QFETCH(QHostAddress, bindAddress); + QFETCH(int, loopback); + QFETCH(int, expected); + if (setProxy) { + // UDP multicast does not work with proxies + expected = 0; + } + + QUdpSocket udpSocket; + // bind, but ignore the result, we are only interested in initializing the socket + (void) udpSocket.bind(bindAddress, 0); + udpSocket.setSocketOption(QUdpSocket::MulticastLoopbackOption, loopback); + QCOMPARE(udpSocket.socketOption(QUdpSocket::MulticastLoopbackOption).toInt(), expected); +} + +void tst_QUdpSocket::multicastJoinBeforeBind_data() +{ + QTest::addColumn<QHostAddress>("groupAddress"); + QTest::newRow("valid ipv4 group address") << QHostAddress("239.255.118.62"); + QTest::newRow("invalid ipv4 group address") << QHostAddress(QHostAddress::Broadcast); + QTest::newRow("valid ipv6 group address") << QHostAddress("FF01::114"); + QTest::newRow("invalid ipv6 group address") << QHostAddress(QHostAddress::AnyIPv6); +} + +void tst_QUdpSocket::multicastJoinBeforeBind() +{ + QFETCH(QHostAddress, groupAddress); + + QUdpSocket udpSocket; + // cannot join group before binding + QTest::ignoreMessage(QtWarningMsg, "QUdpSocket::joinMulticastGroup() called on a QUdpSocket when not in QUdpSocket::BoundState"); + QVERIFY(!udpSocket.joinMulticastGroup(groupAddress)); +} + +void tst_QUdpSocket::multicastLeaveAfterClose_data() +{ + QTest::addColumn<QHostAddress>("groupAddress"); + QTest::newRow("valid ipv4 group address") << QHostAddress("239.255.118.62"); + QTest::newRow("valid ipv6 group address") << QHostAddress("FF01::114"); +} + +void tst_QUdpSocket::multicastLeaveAfterClose() +{ + QFETCH_GLOBAL(bool, setProxy); + QFETCH(QHostAddress, groupAddress); + if (setProxy) { + QSKIP("UDP Multicast does not work with proxies", SkipAll); + } + + QUdpSocket udpSocket; + QVERIFY2(udpSocket.bind(groupAddress, 0), + qPrintable(udpSocket.errorString())); + QVERIFY2(udpSocket.joinMulticastGroup(groupAddress), + qPrintable(udpSocket.errorString())); + udpSocket.close(); + QTest::ignoreMessage(QtWarningMsg, "QUdpSocket::leaveMulticastGroup() called on a QUdpSocket when not in QUdpSocket::BoundState"); + QVERIFY(!udpSocket.leaveMulticastGroup(groupAddress)); +} + +void tst_QUdpSocket::setMulticastInterface_data() +{ + QTest::addColumn<QNetworkInterface>("iface"); + QTest::addColumn<QHostAddress>("address"); + QList<QNetworkInterface> interfaces = QNetworkInterface::allInterfaces(); + foreach (const QNetworkInterface &iface, interfaces) { + foreach (const QNetworkAddressEntry &entry, iface.addressEntries()) { + QTest::newRow(QString("%1:%2").arg(iface.name()).arg(entry.ip().toString()).toAscii()) + << iface + << entry.ip(); + } + } +} + +void tst_QUdpSocket::setMulticastInterface() +{ + QFETCH_GLOBAL(bool, setProxy); + QFETCH(QNetworkInterface, iface); + QFETCH(QHostAddress, address); + + QUdpSocket udpSocket; + // bind initializes the socket + bool bound = udpSocket.bind((address.protocol() == QAbstractSocket::IPv6Protocol + ? QHostAddress(QHostAddress::AnyIPv6) + : QHostAddress(QHostAddress::Any)), + 0); + if (!bound) + QTest::ignoreMessage(QtWarningMsg, "QUdpSocket::setMulticastInterface() called on a QUdpSocket when not in QUdpSocket::BoundState"); + udpSocket.setMulticastInterface(iface); + if (!bound) + QTest::ignoreMessage(QtWarningMsg, "QUdpSocket::multicastInterface() called on a QUdpSocket when not in QUdpSocket::BoundState"); + QNetworkInterface iface2 = udpSocket.multicastInterface(); + if (!setProxy) { + QVERIFY(iface2.isValid()); + QCOMPARE(iface.name(), iface2.name()); + } else { + QVERIFY(!iface2.isValid()); + } +} + +void tst_QUdpSocket::multicast_data() +{ + QHostAddress anyAddress = QHostAddress(QHostAddress::Any); + QHostAddress groupAddress = QHostAddress("239.255.118.62"); + QHostAddress any6Address = QHostAddress(QHostAddress::AnyIPv6); + QHostAddress group6Address = QHostAddress("FF01::114"); + + QTest::addColumn<QHostAddress>("bindAddress"); + QTest::addColumn<bool>("bindResult"); + QTest::addColumn<QHostAddress>("groupAddress"); + QTest::addColumn<bool>("joinResult"); + QTest::newRow("valid bind, group ipv4 address") << anyAddress << true << groupAddress << true; + QTest::newRow("valid bind, invalid group ipv4 address") << anyAddress << true << anyAddress << false; + QTest::newRow("same bind, group ipv4 address") << groupAddress << true << groupAddress << true; + QTest::newRow("valid bind, group ipv6 address") << any6Address << true << group6Address << true; + QTest::newRow("valid bind, invalid group ipv6 address") << any6Address << true << any6Address << false; + QTest::newRow("same bind, group ipv6 address") << group6Address << true << group6Address << true; +} + +void tst_QUdpSocket::multicast() +{ + QFETCH_GLOBAL(bool, setProxy); + QFETCH(QHostAddress, bindAddress); + QFETCH(bool, bindResult); + QFETCH(QHostAddress, groupAddress); + QFETCH(bool, joinResult); + if (setProxy) { + // UDP multicast does not work with proxies + if ((bindAddress.protocol() == QAbstractSocket::IPv4Protocol && (bindAddress.toIPv4Address() & 0xffff0000) == 0xefff0000) + || bindAddress.protocol() == QAbstractSocket::IPv6Protocol) { + // proxy cannot bind to IPv6 or multicast addresses + bindResult = false; + } + joinResult = false; + } + + QUdpSocket receiver; + + // bind first, then verify that we can join the multicast group + QVERIFY2(receiver.bind(bindAddress, 0) == bindResult, + qPrintable(receiver.errorString())); + if (!bindResult) + return; + + QVERIFY2(receiver.joinMulticastGroup(groupAddress) == joinResult, + qPrintable(receiver.errorString())); + if (!joinResult) + return; + + QList<QByteArray> datagrams = QList<QByteArray>() + << QByteArray("0123") + << QByteArray("4567") + << QByteArray("89ab") + << QByteArray("cdef"); + + QUdpSocket sender; + foreach (const QByteArray &datagram, datagrams) { + QCOMPARE(int(sender.writeDatagram(datagram, groupAddress, receiver.localPort())), + int(datagram.size())); + } + + QVERIFY2(receiver.waitForReadyRead(), + qPrintable(receiver.errorString())); + QVERIFY(receiver.hasPendingDatagrams()); + QList<QByteArray> receivedDatagrams; + while (receiver.hasPendingDatagrams()) { + QByteArray datagram; + datagram.resize(receiver.pendingDatagramSize()); + receiver.readDatagram(datagram.data(), datagram.size(), 0, 0); + receivedDatagrams << datagram; + } + QCOMPARE(receivedDatagrams, datagrams); + + QVERIFY2(receiver.leaveMulticastGroup(groupAddress), qPrintable(receiver.errorString())); +} + QTEST_MAIN(tst_QUdpSocket) #include "tst_qudpsocket.moc" diff --git a/tests/auto/qurl/tst_qurl.cpp b/tests/auto/qurl/tst_qurl.cpp index b2b28bd..8091607 100644 --- a/tests/auto/qurl/tst_qurl.cpp +++ b/tests/auto/qurl/tst_qurl.cpp @@ -196,6 +196,7 @@ private slots: void task_199967(); void task_240612(); void taskQTBUG_6962(); + void taskQTBUG_8701(); #ifdef QT3_SUPPORT void dirPath(); @@ -2276,7 +2277,9 @@ void tst_QUrl::ipv6() QCOMPARE(url.isValid(), isValid); if (url.isValid()) { - QCOMPARE(url.toString(), ipv6Auth); + QCOMPARE(url.toString(), ipv6Auth); + url.setHost(url.host()); + QCOMPARE(url.toString(), ipv6Auth); } }; @@ -2300,6 +2303,8 @@ void tst_QUrl::ipv6_2() QUrl url(input); QCOMPARE(url.toString(), output); + url.setHost(url.host()); + QCOMPARE(url.toString(), output); } void tst_QUrl::moreIpv6() @@ -3961,5 +3966,17 @@ void tst_QUrl::taskQTBUG_6962() QCOMPARE(url.authority(), QString()); } +void tst_QUrl::taskQTBUG_8701() +{ + //bug 8701: foo:///bar mangled to foo:/bar + QString foo_triple_bar("foo:///bar"), foo_uni_bar("foo:/bar"); + + QCOMPARE(foo_triple_bar, QUrl(foo_triple_bar).toString()); + QCOMPARE(foo_uni_bar, QUrl(foo_uni_bar).toString()); + + QCOMPARE(foo_triple_bar, QUrl(foo_triple_bar, QUrl::StrictMode).toString()); // fails + QCOMPARE(foo_uni_bar, QUrl(foo_uni_bar, QUrl::StrictMode).toString()); +} + QTEST_MAIN(tst_QUrl) #include "tst_qurl.moc" diff --git a/tests/auto/qvector/tst_qvector.cpp b/tests/auto/qvector/tst_qvector.cpp index 2bc8d15..d8dfacf 100644 --- a/tests/auto/qvector/tst_qvector.cpp +++ b/tests/auto/qvector/tst_qvector.cpp @@ -88,6 +88,7 @@ private slots: void outOfMemory(); void QTBUG6416_reserve(); + void initializeList(); }; void tst_QVector::constructors() const @@ -834,5 +835,19 @@ void tst_QVector::QTBUG6416_reserve() QCOMPARE(fooCtor, fooDtor); } +void tst_QVector::initializeList() +{ +#ifdef QT_CXX0X_INITIALIZERLIST + QVector<int> v1{2,3,4}; + QCOMPARE(v1, QVector<int>() << 2 << 3 << 4); + QCOMPARE(v1, (QVector<int>{2,3,4})); + + QVector<QVector<int>> v2{ v1, {1}, QVector<int>(), {2,3,4} }; + QVector<QVector<int>> v3; + v3 << v1 << (QVector<int>() << 1) << QVector<int>() << v1; + QCOMPARE(v3, v2); +#endif +} + QTEST_APPLESS_MAIN(tst_QVector) #include "tst_qvector.moc" diff --git a/tests/auto/qwidget/tst_qwidget.cpp b/tests/auto/qwidget/tst_qwidget.cpp index fc22058..cdd0d80 100644 --- a/tests/auto/qwidget/tst_qwidget.cpp +++ b/tests/auto/qwidget/tst_qwidget.cpp @@ -402,6 +402,8 @@ private slots: #endif // QT_MAC_USE_COCOA #endif + void nativeChildFocus(); + private: bool ensureScreenSize(int width, int height); QWidget *testWidget; @@ -10521,5 +10523,28 @@ void tst_QWidget::taskQTBUG_11373() #endif // QT_MAC_USE_COCOA #endif +void tst_QWidget::nativeChildFocus() +{ + QWidget w; + QLayout *layout = new QVBoxLayout; + w.setLayout(layout); + QLineEdit *p1 = new QLineEdit; + QLineEdit *p2 = new QLineEdit; + layout->addWidget(p1); + layout->addWidget(p2); + p1->setObjectName("p1"); + p2->setObjectName("p2"); + w.show(); + w.activateWindow(); + p1->setFocus(); + p1->setAttribute(Qt::WA_NativeWindow); + p2->setAttribute(Qt::WA_NativeWindow); + QApplication::processEvents(); + QTest::qWaitForWindowShown(&w); + + QCOMPARE(QApplication::activeWindow(), &w); + QCOMPARE(QApplication::focusWidget(), p1); +} + QTEST_MAIN(tst_QWidget) #include "tst_qwidget.moc" diff --git a/tests/auto/uic/baseline/icontheme.ui b/tests/auto/uic/baseline/icontheme.ui new file mode 100644 index 0000000..a214635 --- /dev/null +++ b/tests/auto/uic/baseline/icontheme.ui @@ -0,0 +1,55 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>Form</class> + <widget class="QWidget" name="Form"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>122</width> + <height>117</height> + </rect> + </property> + <property name="windowTitle"> + <string>Form</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QPushButton" name="fileicon"> + <property name="text"> + <string>fileicon</string> + </property> + <property name="icon"> + <iconset> + <normaloff>image1.png</normaloff>image1.png</iconset> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="fileandthemeicon"> + <property name="text"> + <string>PushButton</string> + </property> + <property name="icon"> + <iconset theme="edit-copy"> + <normaloff>image7.png</normaloff>image7.png</iconset> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="themeicon"> + <property name="text"> + <string>PushButton</string> + </property> + <property name="icon"> + <iconset theme="edit-copy"> + <normaloff/> + </iconset> + </property> + </widget> + </item> + </layout> + </widget> + <resources/> + <connections/> +</ui> diff --git a/tests/auto/uic/baseline/icontheme.ui.h b/tests/auto/uic/baseline/icontheme.ui.h new file mode 100644 index 0000000..946fff9 --- /dev/null +++ b/tests/auto/uic/baseline/icontheme.ui.h @@ -0,0 +1,95 @@ +/******************************************************************************** +** Form generated from reading UI file 'icontheme.ui' +** +** Created: Thu Sep 2 10:28:19 2010 +** by: Qt User Interface Compiler version 4.8.0 +** +** WARNING! All changes made in this file will be lost when recompiling UI file! +********************************************************************************/ + +#ifndef ICONTHEME_H +#define ICONTHEME_H + +#include <QtCore/QVariant> +#include <QtGui/QAction> +#include <QtGui/QApplication> +#include <QtGui/QButtonGroup> +#include <QtGui/QHeaderView> +#include <QtGui/QPushButton> +#include <QtGui/QVBoxLayout> +#include <QtGui/QWidget> + +QT_BEGIN_NAMESPACE + +class Ui_Form +{ +public: + QVBoxLayout *verticalLayout; + QPushButton *fileicon; + QPushButton *fileandthemeicon; + QPushButton *themeicon; + + void setupUi(QWidget *Form) + { + if (Form->objectName().isEmpty()) + Form->setObjectName(QString::fromUtf8("Form")); + Form->resize(122, 117); + verticalLayout = new QVBoxLayout(Form); + verticalLayout->setObjectName(QString::fromUtf8("verticalLayout")); + fileicon = new QPushButton(Form); + fileicon->setObjectName(QString::fromUtf8("fileicon")); + QIcon icon; + icon.addFile(QString::fromUtf8("image1.png"), QSize(), QIcon::Normal, QIcon::Off); + fileicon->setIcon(icon); + + verticalLayout->addWidget(fileicon); + + fileandthemeicon = new QPushButton(Form); + fileandthemeicon->setObjectName(QString::fromUtf8("fileandthemeicon")); + QIcon icon1; + QString iconThemeName = QString::fromUtf8("edit-copy"); + if (QIcon::hasThemeIcon(iconThemeName)) { + icon1 = QIcon::fromTheme(iconThemeName); + } else { + icon1.addFile(QString::fromUtf8("image7.png"), QSize(), QIcon::Normal, QIcon::Off); + } + fileandthemeicon->setIcon(icon1); + + verticalLayout->addWidget(fileandthemeicon); + + themeicon = new QPushButton(Form); + themeicon->setObjectName(QString::fromUtf8("themeicon")); + QIcon icon2; + iconThemeName = QString::fromUtf8("edit-copy"); + if (QIcon::hasThemeIcon(iconThemeName)) { + icon2 = QIcon::fromTheme(iconThemeName); + } else { + icon2.addFile(QString::fromUtf8(""), QSize(), QIcon::Normal, QIcon::Off); + } + themeicon->setIcon(icon2); + + verticalLayout->addWidget(themeicon); + + + retranslateUi(Form); + + QMetaObject::connectSlotsByName(Form); + } // setupUi + + void retranslateUi(QWidget *Form) + { + Form->setWindowTitle(QApplication::translate("Form", "Form", 0, QApplication::UnicodeUTF8)); + fileicon->setText(QApplication::translate("Form", "fileicon", 0, QApplication::UnicodeUTF8)); + fileandthemeicon->setText(QApplication::translate("Form", "PushButton", 0, QApplication::UnicodeUTF8)); + themeicon->setText(QApplication::translate("Form", "PushButton", 0, QApplication::UnicodeUTF8)); + } // retranslateUi + +}; + +namespace Ui { + class Form: public Ui_Form {}; +} // namespace Ui + +QT_END_NAMESPACE + +#endif // ICONTHEME_H diff --git a/tests/benchmarks/corelib/tools/qstring/data.cpp b/tests/benchmarks/corelib/tools/qstring/data.cpp new file mode 100644 index 0000000..6d1a069 --- /dev/null +++ b/tests/benchmarks/corelib/tools/qstring/data.cpp @@ -0,0 +1,1284 @@ +// This is a generated file - DO NOT EDIT +static const ushort stringCollectionData[] __attribute__((aligned(16))) = { + // #0 + 65535, + 99, 111, 109, 112, 105, 108, 101, 114, 32, 118, 101, 114, 115, 105, 111, 110, 115, 47, + 65535,65534,65533,65532,65531, // 24 + 65535,65534,65533,65532,65531, + 99, 111, 109, 112, 105, 108, 101, 114, 32, 118, 101, 114, 115, 105, 111, 110, 115, 47, + 65535, // 48 + + // #1 + 65535,65534,65533,65532,65531, + 99, 111, 109, 112, 105, 108, 101, 114, 32, 118, 101, 114, 115, 105, 111, 110, 115, 47, + 65535, // 72 + 65535,65534,65533,65532,65531, + 67, 111, 109, 112, 105, 108, 101, 114, 32, 86, 101, 114, 115, 105, 111, 110, 115, 47, + 65535, // 96 + + // #2 + 65535, + 99, 111, 109, 112, 105, 108, 101, 114, 32, 116, 105, 109, 101, 115, 116, 97, 109, 112, 115, 47, + 65535,65534,65533, // 120 + 65535,65534,65533,65532,65531, + 99, 111, 109, 112, 105, 108, 101, 114, 32, 116, 105, 109, 101, 115, 116, 97, 109, 112, 115, 47, + 65535,65534,65533,65532,65531,65530,65529, // 152 + + // #3 + 65535,65534,65533,65532,65531, + 99, 111, 109, 112, 105, 108, 101, 114, 32, 116, 105, 109, 101, 115, 116, 97, 109, 112, 115, 47, + 65535,65534,65533,65532,65531,65530,65529, // 184 + 65535, + 67, 111, 109, 112, 105, 108, 101, 114, 32, 84, 105, 109, 101, 115, 116, 97, 109, 112, 115, 47, + 65535,65534,65533, // 208 + + // #4 + 65535,65534,65533,65532,65531,65530,65529,65528,65527,65526,65525,65524,65523,65522,65521,65520,65519, + 47, 118, 97, 114, 47, 116, 109, 112, 47, 116, 101, 97, 109, 98, 117, 105, 108, 100, 101, 114, 45, 116, 109, 97, 99, 105, 101, 105, 114, 47, 99, 108, 105, 101, 110, 116, 47, 99, 111, 109, 112, 105, 108, 101, 114, 115, 46, 99, 111, 110, 102, + 65535,65534,65533,65532, // 280+ + + + // #5 + 65535,65534,65533,65532,65531,65530,65529,65528,65527,65526,65525,65524,65523, + 47, 118, 97, 114, 47, 116, 109, 112, 47, 116, 101, 97, 109, 98, 117, 105, 108, 100, 101, 114, 45, 116, 109, 97, 99, 105, 101, 105, 114, 47, 99, 108, 105, 101, 110, 116, 47, 99, 111, 109, 112, 105, 108, 101, 114, 115, 46, 99, 111, 110, 102, + 65535,65534,65533,65532,65531,65530,65529,65528, // 352+ + 65535, + 47, 118, 97, 114, 47, 116, 109, 112, 47, 116, 101, 97, 109, 98, 117, 105, 108, 100, 101, 114, 45, 116, 109, 97, 99, 105, 101, 105, 114, 47, 99, 108, 105, 101, 110, 116, 47, 99, 111, 109, 112, 105, 108, 101, 114, 115, 46, 99, 111, 110, 102, + 65535,65534,65533,65532, // 408+ + + // #6 + 65535,65534,65533,65532,65531,65530,65529,65528,65527, + 47, 118, 97, 114, 47, 116, 109, 112, 47, 116, 101, 97, 109, 98, 117, 105, 108, 100, 101, 114, 45, 116, 109, 97, 99, 105, 101, 105, 114, 47, 99, 108, 105, 101, 110, 116, 47, 99, 111, 109, 112, 105, 108, 101, 114, 115, 46, 99, 111, 110, 102, + 65535,65534,65533,65532, // 472+ + + + // #7 + 65535, + 97, 114, 99, 104, 105, 118, 101, 100, 32, 99, 111, 109, 112, 105, 108, 101, 114, 115, 47, + 65535,65534,65533,65532, // 496 + 65535,65534,65533,65532,65531, + 97, 114, 99, 104, 105, 118, 101, 100, 32, 99, 111, 109, 112, 105, 108, 101, 114, 115, 47, + 65535,65534,65533,65532,65531,65530,65529,65528, // 528 + + // #8 + 65535,65534,65533,65532,65531, + 97, 114, 99, 104, 105, 118, 101, 100, 32, 99, 111, 109, 112, 105, 108, 101, 114, 115, 47, + 65535,65534,65533,65532,65531,65530,65529,65528, // 560 + 65535,65534,65533,65532,65531, + 65, 114, 99, 104, 105, 118, 101, 100, 32, 67, 111, 109, 112, 105, 108, 101, 114, 115, 47, + 65535,65534,65533,65532,65531,65530,65529,65528, // 592 + + // #9 + 65535,65534,65533,65532,65531,65530,65529,65528,65527,65526,65525,65524,65523,65522,65521,65520,65519, + 47, 118, 97, 114, 47, 116, 109, 112, 47, 116, 101, 97, 109, 98, 117, 105, 108, 100, 101, 114, 45, 116, 109, 97, 99, 105, 101, 105, 114, 47, 99, 108, 105, 101, 110, 116, 47, 99, 111, 109, 112, 105, 108, 101, 114, 115, 46, 99, 111, 110, 102, + 65535,65534,65533,65532, // 664+ + 65535,65534,65533,65532,65531,65530,65529,65528,65527,65526,65525,65524,65523, + 47, 118, 97, 114, 47, 116, 109, 112, 47, 116, 101, 97, 109, 98, 117, 105, 108, 100, 101, 114, 45, 116, 109, 97, 99, 105, 101, 105, 114, 47, 99, 108, 105, 101, 110, 116, 47, 99, 111, 109, 112, 105, 108, 101, 114, 115, 46, 99, 111, 110, 102, + 65535,65534,65533,65532,65531,65530,65529,65528, // 736+ + + // #10 + 65535,65534,65533,65532,65531, + 76, 105, 110, 117, 120, + 65535,65534,65533,65532,65531,65530, // 752 + 65535, + 76, 105, 110, 117, 120, + 65535,65534, // 760 + + // #11 + 65535,65534,65533,65532,65531, + 105, 51, 56, 54, + 65535,65534,65533,65532,65531,65530,65529, // 776 + 65535,65534,65533,65532,65531, + 105, 51, 56, 54, + 65535,65534,65533,65532,65531,65530,65529, // 792 + + // #12 + 65535, + 105, 99, 99, + 65535,65534,65533,65532, // 800 + 65535,65534,65533,65532,65531, + 103, 43, 43, + 65535,65534,65533,65532,65531,65530,65529,65528, // 816 + + // #13 + 65535, + 76, 105, 110, 117, 120, + 65535,65534, // 824 + 65535, + 76, 105, 110, 117, 120, + 65535,65534, // 832 + + // #14 + 65535, + 105, 51, 56, 54, + 65535,65534,65533, // 840 + 65535,65534,65533,65532,65531, + 105, 51, 56, 54, + 65535,65534,65533,65532,65531,65530,65529, // 856 + + // #15 + 65535, + 76, 105, 110, 117, 120, + 65535,65534, // 864 + 65535, + 76, 105, 110, 117, 120, + 65535,65534, // 872 + + // #16 + 65535, + 105, 51, 56, 54, + 65535,65534,65533, // 880 + 65535,65534,65533,65532,65531, + 105, 51, 56, 54, + 65535,65534,65533,65532,65531,65530,65529, // 896 + + // #17 + 65535, + 103, 99, 99, + 65535,65534,65533,65532, // 904 + 65535,65534,65533,65532,65531, + 103, 43, 43, + 65535,65534,65533,65532,65531,65530,65529,65528, // 920 + + // #18 + 65535,65534,65533,65532,65531, + 76, 105, 110, 117, 120, + 65535,65534,65533,65532,65531,65530, // 936 + 65535, + 76, 105, 110, 117, 120, + 65535,65534, // 944 + + // #19 + 65535,65534,65533,65532,65531, + 105, 51, 56, 54, + 65535,65534,65533,65532,65531,65530,65529, // 960 + 65535,65534,65533,65532,65531, + 105, 51, 56, 54, + 65535,65534,65533,65532,65531,65530,65529, // 976 + + // #20 + 65535, + 103, 43, 43, + 65535,65534,65533,65532, // 984 + 65535,65534,65533,65532,65531, + 103, 43, 43, + 65535,65534,65533,65532,65531,65530,65529,65528, // 1000 + + // #21 + 65535,65534,65533,65532,65531, + 52, 46, 52, 46, 51, + 65535,65534,65533,65532,65531,65530, // 1016 + 65535,65534,65533,65532,65531, + 52, 46, 52, 46, 51, + 65535,65534,65533,65532,65531,65530, // 1032 + + // #22 + 65535, + 76, 105, 110, 117, 120, + 65535,65534, // 1040 + 65535, + 76, 105, 110, 117, 120, + 65535,65534, // 1048 + + // #23 + 65535,65534,65533,65532,65531, + 105, 51, 56, 54, + 65535,65534,65533,65532,65531,65530,65529, // 1064 + 65535,65534,65533,65532,65531, + 105, 51, 56, 54, + 65535,65534,65533,65532,65531,65530,65529, // 1080 + + // #24 + 65535, + 47, 117, 115, 114, 47, 98, 105, 110, 47, 103, 43, 43, + 65535,65534,65533, // 1096 + 65535, + 47, 117, 115, 114, 47, 98, 105, 110, 47, 103, 43, 43, + 65535,65534,65533, // 1112 + + // #25 + 65535, + 76, 105, 110, 117, 120, + 65535,65534, // 1120 + 65535, + 76, 105, 110, 117, 120, + 65535,65534, // 1128 + + // #26 + 65535, + 105, 51, 56, 54, + 65535,65534,65533, // 1136 + 65535,65534,65533,65532,65531, + 105, 51, 56, 54, + 65535,65534,65533,65532,65531,65530,65529, // 1152 + + // #27 + 65535, + 105, 99, 99, + 65535,65534,65533,65532, // 1160 + 65535,65534,65533,65532,65531, + 103, 43, 43, + 65535,65534,65533,65532,65531,65530,65529,65528, // 1176 + + // #28 + 65535, + 76, 105, 110, 117, 120, + 65535,65534, // 1184 + 65535, + 76, 105, 110, 117, 120, + 65535,65534, // 1192 + + // #29 + 65535, + 105, 51, 56, 54, + 65535,65534,65533, // 1200 + 65535,65534,65533,65532,65531, + 105, 51, 56, 54, + 65535,65534,65533,65532,65531,65530,65529, // 1216 + + // #30 + 65535,65534,65533,65532,65531, + 76, 105, 110, 117, 120, + 65535,65534,65533,65532,65531,65530, // 1232 + 65535, + 76, 105, 110, 117, 120, + 65535,65534, // 1240 + + // #31 + 65535,65534,65533,65532,65531, + 105, 51, 56, 54, + 65535,65534,65533,65532,65531,65530,65529, // 1256 + 65535,65534,65533,65532,65531, + 105, 51, 56, 54, + 65535,65534,65533,65532,65531,65530,65529, // 1272 + + // #32 + 65535,65534,65533,65532,65531, + 76, 105, 110, 117, 120, + 65535,65534,65533,65532,65531,65530, // 1288 + 65535, + 76, 105, 110, 117, 120, + 65535,65534, // 1296 + + // #33 + 65535,65534,65533,65532,65531, + 105, 51, 56, 54, + 65535,65534,65533,65532,65531,65530,65529, // 1312 + 65535,65534,65533,65532,65531, + 105, 51, 56, 54, + 65535,65534,65533,65532,65531,65530,65529, // 1328 + + // #34 + 65535, + 45, 109, 97, 114, 99, 104, 61, 99, 111, 114, 101, 50, + 65535,65534,65533, // 1344 + 65535, + 116, 98, 51, 54, 57, 54, 56, 95, 50, 46, 105, 105, + 65535,65534,65533, // 1360 + + // #35 + 65535,65534,65533,65532,65531, + 45, 102, 108, 111, 111, 112, 45, 98, 108, 111, 99, 107, + 65535,65534,65533,65532,65531,65530,65529, // 1384 + 65535, + 116, 98, 51, 54, 57, 54, 56, 95, 50, 46, 105, 105, + 65535,65534,65533, // 1400 + + // #36 + 65535,65534,65533,65532,65531, + 116, 98, 51, 54, 57, 54, 56, 95, 50, 46, 105, 105, + 65535,65534,65533,65532,65531,65530,65529, // 1424 + 65535, + 116, 98, 51, 54, 57, 54, 56, 95, 50, 46, 105, 105, + 65535,65534,65533, // 1440 + + // #37 + 65535,65534,65533,65532,65531, + 45, 109, 115, 115, 101, 52, + 65535,65534,65533,65532,65531, // 1456 + 65535,65534,65533,65532,65531, + 108, 101, 110, 103, 116, 104, + 65535,65534,65533,65532,65531, // 1472 + + // #38 + 65535,65534,65533,65532,65531, + 116, 98, 51, 54, 57, 54, 56, 95, 49, 46, 111, + 65535,65534,65533,65532,65531,65530,65529,65528, // 1496 + 65535,65534,65533,65532,65531, + 116, 98, 51, 54, 57, 54, 56, 95, 49, 46, 111, + 65535,65534,65533,65532,65531,65530,65529,65528, // 1520 + + // #39 + 65535,65534,65533,65532,65531, + 68, 69, 83, 75, 84, 79, 80, 95, 83, 69, 83, 83, + 65535,65534,65533,65532,65531,65530,65529, // 1544 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 1560 + + // #40 + 65535,65534,65533,65532,65531, + 76, 67, 95, 83, 79, 85, 82, 67, 69, 68, 61, 49, + 65535,65534,65533,65532,65531,65530,65529, // 1584 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 1600 + + // #41 + 65535,65534,65533,65532,65531, + 81, 84, 68, 73, 82, 61, 47, 104, 111, 109, 101, 47, + 65535,65534,65533,65532,65531,65530,65529, // 1624 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 1640 + + // #42 + 65535, + 76, 67, 95, 67, 84, 89, 80, 69, 61, 112, 116, 95, + 65535,65534,65533, // 1656 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 1672 + + // #43 + 65535, + 71, 84, 75, 95, 82, 67, 95, 70, 73, 76, 69, 83, + 65535,65534,65533, // 1688 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 1704 + + // #44 + 65535, + 88, 77, 79, 68, 73, 70, 73, 69, 82, 83, 61, 64, + 65535,65534,65533, // 1720 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 1736 + + // #45 + 65535, + 83, 72, 69, 76, 76, 61, 47, 98, 105, 110, 47, 122, + 65535,65534,65533, // 1752 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 1768 + + // #46 + 65535,65534,65533,65532,65531, + 85, 61, 64, 123, 117, 112, 115, 116, 114, 101, 97, 109, + 65535,65534,65533,65532,65531,65530,65529, // 1792 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 1808 + + // #47 + 65535, + 95, 61, 47, 117, 115, 114, 47, 98, 105, 110, 47, 105, + 65535,65534,65533, // 1824 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 1840 + + // #48 + 65535, + 88, 68, 71, 95, 67, 79, 78, 70, 73, 71, 95, 68, + 65535,65534,65533, // 1856 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 1872 + + // #49 + 65535,65534,65533,65532,65531, + 83, 65, 86, 69, 72, 73, 83, 84, 61, 49, 48, 48, + 65535,65534,65533,65532,65531,65530,65529, // 1896 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 1912 + + // #50 + 65535, + 75, 68, 69, 95, 77, 85, 76, 84, 73, 72, 69, 65, + 65535,65534,65533, // 1928 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 1944 + + // #51 + 65535,65534,65533,65532,65531, + 77, 65, 76, 76, 79, 67, 95, 67, 72, 69, 67, 75, + 65535,65534,65533,65532,65531,65530,65529, // 1968 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 1984 + + // #52 + 65535,65534,65533,65532,65531, + 72, 73, 83, 84, 67, 79, 78, 84, 82, 79, 76, 61, + 65535,65534,65533,65532,65531,65530,65529, // 2008 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 2024 + + // #53 + 65535,65534,65533,65532,65531, + 88, 68, 71, 95, 68, 65, 84, 65, 95, 68, 73, 82, + 65535,65534,65533,65532,65531,65530,65529, // 2048 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 2064 + + // #54 + 65535,65534,65533,65532,65531, + 88, 68, 77, 95, 77, 65, 78, 65, 71, 69, 68, 61, + 65535,65534,65533,65532,65531,65530,65529, // 2088 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 2104 + + // #55 + 65535, + 76, 67, 95, 67, 79, 76, 76, 65, 84, 69, 61, 112, + 65535,65534,65533, // 2120 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 2136 + + // #56 + 65535, + 81, 84, 95, 80, 76, 85, 71, 73, 78, 95, 80, 65, + 65535,65534,65533, // 2152 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 2168 + + // #57 + 65535, + 83, 67, 82, 69, 69, 78, 68, 73, 82, 61, 47, 104, + 65535,65534,65533, // 2184 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 2200 + + // #58 + 65535,65534,65533,65532,65531, + 76, 69, 83, 83, 79, 80, 69, 78, 61, 124, 47, 117, + 65535,65534,65533,65532,65531,65530,65529, // 2224 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 2240 + + // #59 + 65535, + 76, 67, 95, 78, 65, 77, 69, 61, 110, 98, 95, 78, + 65535,65534,65533, // 2256 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 2272 + + // #60 + 65535,65534,65533,65532,65531, + 80, 52, 67, 76, 73, 69, 78, 84, 61, 116, 109, 97, + 65535,65534,65533,65532,65531,65530,65529, // 2296 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 2312 + + // #61 + 65535, + 80, 65, 84, 72, 61, 47, 104, 111, 109, 101, 47, 116, + 65535,65534,65533, // 2328 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 2344 + + // #62 + 65535,65534,65533,65532,65531, + 71, 80, 71, 95, 65, 71, 69, 78, 84, 95, 73, 78, + 65535,65534,65533,65532,65531,65530,65529, // 2368 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 2384 + + // #63 + 65535,65534,65533,65532,65531, + 88, 67, 85, 82, 83, 79, 82, 95, 84, 72, 69, 77, + 65535,65534,65533,65532,65531,65530,65529, // 2408 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 2424 + + // #64 + 65535,65534,65533,65532,65531, + 83, 69, 83, 83, 73, 79, 78, 95, 77, 65, 78, 65, + 65535,65534,65533,65532,65531,65530,65529, // 2448 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 2464 + + // #65 + 65535, + 81, 84, 83, 82, 67, 68, 73, 82, 61, 47, 104, 111, + 65535,65534,65533, // 2480 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 2496 + + // #66 + 65535,65534,65533,65532,65531, + 87, 73, 78, 68, 79, 87, 73, 68, 61, 52, 54, 49, + 65535,65534,65533,65532,65531,65530,65529, // 2520 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 2536 + + // #67 + 65535,65534,65533,65532,65531, + 76, 67, 95, 77, 69, 83, 83, 65, 71, 69, 83, 61, + 65535,65534,65533,65532,65531,65530,65529, // 2560 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 2576 + + // #68 + 65535, + 76, 67, 95, 78, 85, 77, 69, 82, 73, 67, 61, 110, + 65535,65534,65533, // 2592 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 2608 + + // #69 + 65535, + 71, 84, 75, 50, 95, 82, 67, 95, 70, 73, 76, 69, + 65535,65534,65533, // 2624 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 2640 + + // #70 + 65535, + 80, 82, 79, 70, 73, 76, 69, 72, 79, 77, 69, 61, + 65535,65534,65533, // 2656 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 2672 + + // #71 + 65535,65534,65533,65532,65531, + 68, 77, 95, 67, 79, 78, 84, 82, 79, 76, 61, 47, + 65535,65534,65533,65532,65531,65530,65529, // 2696 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 2712 + + // #72 + 65535, + 76, 83, 95, 67, 79, 76, 79, 82, 83, 61, 114, 115, + 65535,65534,65533, // 2728 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 2744 + + // #73 + 65535,65534,65533,65532,65531, + 83, 83, 72, 95, 65, 85, 84, 72, 95, 83, 79, 67, + 65535,65534,65533,65532,65531,65530,65529, // 2768 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 2784 + + // #74 + 65535,65534,65533,65532,65531, + 75, 68, 69, 68, 73, 82, 83, 61, 47, 104, 111, 109, + 65535,65534,65533,65532,65531,65530,65529, // 2808 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 2824 + + // #75 + 65535,65534,65533,65532,65531, + 76, 68, 95, 80, 82, 69, 76, 79, 65, 68, 61, 47, + 65535,65534,65533,65532,65531,65530,65529, // 2848 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 2864 + + // #76 + 65535,65534,65533,65532,65531, + 88, 67, 85, 82, 83, 79, 82, 95, 80, 65, 84, 72, + 65535,65534,65533,65532,65531,65530,65529, // 2888 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 2904 + + // #77 + 65535, + 115, 114, 99, 100, 105, 114, 61, 47, 104, 111, 109, 101, + 65535,65534,65533, // 2920 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 2936 + + // #78 + 65535,65534,65533,65532,65531, + 72, 79, 77, 69, 61, 47, 104, 111, 109, 101, 47, 116, + 65535,65534,65533,65532,65531,65530,65529, // 2960 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 2976 + + // #79 + 65535, + 81, 84, 52, 68, 79, 67, 68, 73, 82, 61, 47, 117, + 65535,65534,65533, // 2992 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 3008 + + // #80 + 65535,65534,65533,65532,65531, + 80, 87, 68, 61, 47, 104, 111, 109, 101, 47, 116, 109, + 65535,65534,65533,65532,65531,65530,65529, // 3032 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 3048 + + // #81 + 65535,65534,65533,65532,65531, + 75, 68, 69, 95, 83, 69, 83, 83, 73, 79, 78, 95, + 65535,65534,65533,65532,65531,65530,65529, // 3072 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 3088 + + // #82 + 65535, + 73, 78, 83, 73, 68, 69, 95, 83, 80, 69, 67, 73, + 65535,65534,65533, // 3104 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 3120 + + // #83 + 65535, + 83, 83, 72, 95, 65, 71, 69, 78, 84, 95, 80, 73, + 65535,65534,65533, // 3136 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 3152 + + // #84 + 65535, + 80, 75, 71, 95, 67, 79, 78, 70, 73, 71, 95, 80, + 65535,65534,65533, // 3168 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 3184 + + // #85 + 65535,65534,65533,65532,65531, + 68, 66, 85, 83, 95, 83, 69, 83, 83, 73, 79, 78, + 65535,65534,65533,65532,65531,65530,65529, // 3208 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 3224 + + // #86 + 65535, + 76, 68, 95, 76, 73, 66, 82, 65, 82, 89, 95, 80, + 65535,65534,65533, // 3240 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 3256 + + // #87 + 65535,65534,65533,65532,65531, + 80, 52, 85, 83, 69, 82, 61, 116, 106, 109, 97, 99, + 65535,65534,65533,65532,65531,65530,65529, // 3280 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 3296 + + // #88 + 65535,65534,65533,65532,65531, + 81, 84, 69, 83, 84, 95, 67, 79, 76, 79, 82, 69, + 65535,65534,65533,65532,65531,65530,65529, // 3320 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 3336 + + // #89 + 65535,65534,65533,65532,65531, + 88, 68, 71, 95, 83, 69, 83, 83, 73, 79, 78, 95, + 65535,65534,65533,65532,65531,65530,65529, // 3360 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 3376 + + // #90 + 65535,65534,65533,65532,65531, + 76, 69, 83, 83, 75, 69, 89, 61, 47, 101, 116, 99, + 65535,65534,65533,65532,65531,65530,65529, // 3400 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 3416 + + // #91 + 65535, + 76, 79, 71, 78, 65, 77, 69, 61, 116, 109, 97, 99, + 65535,65534,65533, // 3432 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 3448 + + // #92 + 65535, + 71, 95, 70, 73, 76, 69, 78, 65, 77, 69, 95, 69, + 65535,65534,65533, // 3464 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 3480 + + // #93 + 65535, + 75, 68, 69, 95, 70, 85, 76, 76, 95, 83, 69, 83, + 65535,65534,65533, // 3496 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 3512 + + // #94 + 65535,65534,65533,65532,65531, + 72, 79, 83, 84, 78, 65, 77, 69, 61, 108, 111, 116, + 65535,65534,65533,65532,65531,65530,65529, // 3536 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 3552 + + // #95 + 65535,65534,65533,65532,65531, + 76, 67, 95, 84, 73, 77, 69, 61, 112, 116, 95, 66, + 65535,65534,65533,65532,65531,65530,65529, // 3576 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 3592 + + // #96 + 65535, + 83, 83, 72, 95, 65, 83, 75, 80, 65, 83, 83, 61, + 65535,65534,65533, // 3608 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 3624 + + // #97 + 65535,65534,65533,65532,65531, + 72, 73, 83, 84, 70, 73, 76, 69, 61, 47, 104, 111, + 65535,65534,65533,65532,65531,65530,65529, // 3648 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 3664 + + // #98 + 65535, + 75, 79, 78, 83, 79, 76, 69, 95, 68, 66, 85, 83, + 65535,65534,65533, // 3680 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 3696 + + // #99 + 65535, + 77, 65, 75, 69, 61, 47, 117, 115, 114, 47, 98, 105, + 65535,65534,65533, // 3712 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 3728 + + // #100 + 65535, + 67, 65, 78, 66, 69, 82, 82, 65, 95, 68, 82, 73, + 65535,65534,65533, // 3744 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 3760 + + // #101 + 65535, + 71, 67, 79, 78, 70, 95, 84, 77, 80, 68, 73, 82, + 65535,65534,65533, // 3776 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 3792 + + // #102 + 65535,65534,65533,65532,65531, + 85, 83, 69, 82, 61, 116, 109, 97, 99, 105, 101, 105, + 65535,65534,65533,65532,65531,65530,65529, // 3816 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 3832 + + // #103 + 65535, + 111, 98, 106, 100, 105, 114, 61, 47, 104, 111, 109, 101, + 65535,65534,65533, // 3848 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 3864 + + // #104 + 65535,65534,65533,65532,65531, + 76, 67, 95, 77, 79, 78, 69, 84, 65, 82, 89, 61, + 65535,65534,65533,65532,65531,65530,65529, // 3888 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 3904 + + // #105 + 65535,65534,65533,65532,65531, + 81, 84, 76, 73, 66, 61, 47, 117, 115, 114, 47, 108, + 65535,65534,65533,65532,65531,65530,65529, // 3928 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 3944 + + // #106 + 65535,65534,65533,65532,65531, + 76, 67, 95, 84, 69, 76, 69, 80, 72, 79, 78, 69, + 65535,65534,65533,65532,65531,65530,65529, // 3968 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 3984 + + // #107 + 65535, + 80, 89, 84, 72, 79, 78, 68, 79, 78, 84, 87, 82, + 65535,65534,65533, // 4000 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 4016 + + // #108 + 65535,65534,65533,65532,65531, + 84, 77, 80, 68, 73, 82, 61, 47, 116, 109, 112, 47, + 65535,65534,65533,65532,65531,65530,65529, // 4040 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 4056 + + // #109 + 65535,65534,65533,65532,65531, + 65, 82, 77, 76, 77, 68, 95, 76, 73, 67, 69, 78, + 65535,65534,65533,65532,65531,65530,65529, // 4080 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 4096 + + // #110 + 65535, + 80, 89, 84, 72, 79, 78, 80, 65, 84, 72, 61, 47, + 65535,65534,65533, // 4112 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 4128 + + // #111 + 65535,65534,65533,65532,65531, + 77, 65, 75, 69, 70, 76, 65, 71, 83, 61, 119, 32, + 65535,65534,65533,65532,65531,65530,65529, // 4152 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 4168 + + // #112 + 65535, + 77, 70, 76, 65, 71, 83, 61, 45, 119, 32, 45, 45, + 65535,65534,65533, // 4184 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 4200 + + // #113 + 65535, + 77, 65, 73, 76, 61, 47, 118, 97, 114, 47, 115, 112, + 65535,65534,65533, // 4216 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 4232 + + // #114 + 65535,65534,65533,65532,65531, + 83, 72, 69, 76, 76, 95, 83, 69, 83, 83, 73, 79, + 65535,65534,65533,65532,65531,65530,65529, // 4256 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 4272 + + // #115 + 65535, + 75, 68, 69, 68, 73, 82, 61, 47, 104, 111, 109, 101, + 65535,65534,65533, // 4288 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 4304 + + // #116 + 65535,65534,65533,65532,65531, + 76, 69, 83, 83, 67, 72, 65, 82, 83, 69, 84, 61, + 65535,65534,65533,65532,65531,65530,65529, // 4328 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 4344 + + // #117 + 65535,65534,65533,65532,65531, + 76, 67, 95, 80, 65, 80, 69, 82, 61, 110, 98, 95, + 65535,65534,65533,65532,65531,65530,65529, // 4368 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 4384 + + // #118 + 65535, + 66, 82, 79, 87, 83, 69, 82, 61, 47, 117, 115, 114, + 65535,65534,65533, // 4400 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 4416 + + // #119 + 65535, + 77, 69, 84, 65, 95, 67, 76, 65, 83, 83, 61, 100, + 65535,65534,65533, // 4432 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 4448 + + // #120 + 65535,65534,65533,65532,65531, + 77, 68, 86, 95, 77, 69, 78, 85, 95, 83, 84, 89, + 65535,65534,65533,65532,65531,65530,65529, // 4472 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 4488 + + // #121 + 65535,65534,65533,65532,65531, + 67, 79, 76, 79, 82, 70, 71, 66, 71, 61, 49, 53, + 65535,65534,65533,65532,65531,65530,65529, // 4512 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 4528 + + // #122 + 65535,65534,65533,65532,65531, + 80, 89, 84, 72, 79, 78, 83, 84, 65, 82, 84, 85, + 65535,65534,65533,65532,65531,65530,65529, // 4552 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 4568 + + // #123 + 65535, + 76, 67, 95, 77, 69, 65, 83, 85, 82, 69, 77, 69, + 65535,65534,65533, // 4584 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 4600 + + // #124 + 65535,65534,65533,65532,65531, + 69, 68, 73, 84, 79, 82, 61, 47, 117, 115, 114, 47, + 65535,65534,65533,65532,65531,65530,65529, // 4624 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 4640 + + // #125 + 65535,65534,65533,65532,65531, + 69, 78, 95, 84, 66, 61, 109, 111, 99, 58, 117, 105, + 65535,65534,65533,65532,65531,65530,65529, // 4664 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 4680 + + // #126 + 65535, + 72, 73, 83, 84, 83, 73, 90, 69, 61, 49, 48, 48, + 65535,65534,65533, // 4696 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 4712 + + // #127 + 65535,65534,65533,65532,65531, + 71, 83, 95, 76, 73, 66, 61, 47, 104, 111, 109, 101, + 65535,65534,65533,65532,65531,65530,65529, // 4736 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 4752 + + // #128 + 65535,65534,65533,65532,65531, + 78, 76, 83, 80, 65, 84, 72, 61, 47, 117, 115, 114, + 65535,65534,65533,65532,65531,65530,65529, // 4776 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 4792 + + // #129 + 65535,65534,65533,65532,65531, + 87, 73, 78, 68, 79, 87, 80, 65, 84, 72, 61, 55, + 65535,65534,65533,65532,65531,65530,65529, // 4816 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 4832 + + // #130 + 65535,65534,65533,65532,65531, + 75, 79, 78, 83, 79, 76, 69, 95, 68, 66, 85, 83, + 65535,65534,65533,65532,65531,65530,65529, // 4856 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 4872 + + // #131 + 65535, + 76, 67, 95, 73, 68, 69, 78, 84, 73, 70, 73, 67, + 65535,65534,65533, // 4888 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 4904 + + // #132 + 65535, + 73, 78, 80, 85, 84, 82, 67, 61, 47, 101, 116, 99, + 65535,65534,65533, // 4920 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 4936 + + // #133 + 65535,65534,65533,65532,65531, + 81, 84, 73, 78, 67, 61, 47, 117, 115, 114, 47, 108, + 65535,65534,65533,65532,65531,65530,65529, // 4960 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 4976 + + // #134 + 65535, + 76, 67, 95, 65, 68, 68, 82, 69, 83, 83, 61, 110, + 65535,65534,65533, // 4992 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 5008 + + // #135 + 65535,65534,65533,65532,65531, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 95, + 65535,65534,65533,65532,65531,65530,65529, // 5032 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 5048 + + // #136 + 65535, + 76, 65, 78, 71, 61, 112, 116, 95, 66, 82, 46, 85, + 65535,65534,65533, // 5064 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 5080 + + // #137 + 65535, + 80, 52, 80, 79, 82, 84, 61, 112, 52, 46, 116, 114, + 65535,65534,65533, // 5096 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 5112 + + // #138 + 65535,65534,65533,65532,65531, + 80, 73, 76, 79, 84, 80, 79, 82, 84, 61, 117, 115, + 65535,65534,65533,65532,65531,65530,65529, // 5136 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 5152 + + // #139 + 65535, + 75, 68, 69, 95, 83, 69, 83, 83, 73, 79, 78, 95, + 65535,65534,65533, // 5168 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 5184 + + // #140 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 5200 + 65535, + 84, 69, 65, 77, 66, 85, 73, 76, 68, 69, 82, 61, + 65535,65534,65533, // 5216 + + +}; +static struct StringCollection +{ + int len; + int offset1, offset2; + ushort align1, align2; +} stringCollection[] = { + {18, 1, 29, 3666, 106}, // #0 + {18, 53, 77, 106, 1978}, // #1 + {20, 97, 125, 2850, 3210}, // #2 + {20, 157, 185, 3210, 3138}, // #3 + {51, 225, 225, 3362, 3362}, // #4 + {51, 293, 353, 1434, 3362}, // #5 + {51, 417, 417, 3362, 3362}, // #6 + {19, 473, 501, 2850, 10}, // #7 + {19, 533, 565, 10, 442}, // #8 + {51, 609, 677, 3362, 1434}, // #9 + {5, 741, 753, 2666, 2066}, // #10 + {4, 765, 781, 2362, 3930}, // #11 + {3, 793, 805, 3330, 2138}, // #12 + {5, 817, 825, 738, 2066}, // #13 + {4, 833, 845, 434, 3930}, // #14 + {5, 857, 865, 3842, 2066}, // #15 + {4, 873, 885, 3538, 3930}, // #16 + {3, 897, 909, 3330, 2138}, // #17 + {5, 925, 937, 1898, 2066}, // #18 + {4, 949, 965, 1594, 3930}, // #19 + {3, 977, 989, 3330, 2138}, // #20 + {5, 1005, 1021, 2218, 762}, // #21 + {5, 1033, 1041, 3346, 2066}, // #22 + {4, 1053, 1069, 3082, 3930}, // #23 + {12, 1081, 1097, 2082, 962}, // #24 + {5, 1113, 1121, 3362, 2066}, // #25 + {4, 1129, 1141, 322, 3930}, // #26 + {3, 1153, 1165, 2050, 2138}, // #27 + {5, 1177, 1185, 1538, 2066}, // #28 + {4, 1193, 1205, 1234, 3930}, // #29 + {5, 1221, 1233, 554, 2066}, // #30 + {4, 1245, 1261, 250, 3930}, // #31 + {5, 1277, 1289, 2858, 2066}, // #32 + {4, 1301, 1317, 2554, 3930}, // #33 + {12, 1329, 1345, 2194, 1762}, // #34 + {12, 1365, 1385, 2170, 1762}, // #35 + {12, 1405, 1425, 2314, 1762}, // #36 + {6, 1445, 1461, 3626, 666}, // #37 + {11, 1477, 1501, 3882, 842}, // #38 + {12, 1525, 1545, 1722, 2930}, // #39 + {12, 1565, 1585, 1914, 2930}, // #40 + {12, 1605, 1625, 442, 2930}, // #41 + {12, 1641, 1657, 626, 2930}, // #42 + {12, 1673, 1689, 946, 2930}, // #43 + {12, 1705, 1721, 738, 2930}, // #44 + {12, 1737, 1753, 2066, 2930}, // #45 + {12, 1773, 1793, 1210, 2930}, // #46 + {12, 1809, 1825, 1426, 2930}, // #47 + {12, 1841, 1857, 1650, 2930}, // #48 + {12, 1877, 1897, 1530, 2930}, // #49 + {12, 1913, 1929, 1858, 2930}, // #50 + {12, 1949, 1969, 2106, 2930}, // #51 + {12, 1989, 2009, 2202, 2930}, // #52 + {12, 2029, 2049, 2490, 2930}, // #53 + {12, 2069, 2089, 2794, 2930}, // #54 + {12, 2105, 2121, 2322, 2930}, // #55 + {12, 2137, 2153, 2834, 2930}, // #56 + {12, 2169, 2185, 1266, 2930}, // #57 + {12, 2205, 2225, 2538, 2930}, // #58 + {12, 2241, 2257, 2706, 2930}, // #59 + {12, 2277, 2297, 3402, 2930}, // #60 + {12, 2313, 2329, 146, 2930}, // #61 + {12, 2349, 2369, 3690, 2930}, // #62 + {12, 2389, 2409, 810, 2930}, // #63 + {12, 2429, 2449, 1178, 2930}, // #64 + {12, 2465, 2481, 1442, 2930}, // #65 + {12, 2501, 2521, 3546, 2930}, // #66 + {12, 2541, 2561, 1930, 2930}, // #67 + {12, 2577, 2593, 1634, 2930}, // #68 + {12, 2609, 2625, 1986, 2930}, // #69 + {12, 2641, 2657, 1970, 2930}, // #70 + {12, 2677, 2697, 1834, 2930}, // #71 + {12, 2713, 2729, 1474, 2930}, // #72 + {12, 2749, 2769, 2250, 2930}, // #73 + {12, 2789, 2809, 2458, 2930}, // #74 + {12, 2829, 2849, 2618, 2930}, // #75 + {12, 2869, 2889, 3066, 2930}, // #76 + {12, 2905, 2921, 3330, 2930}, // #77 + {12, 2941, 2961, 1706, 2930}, // #78 + {12, 2977, 2993, 2802, 2930}, // #79 + {12, 3013, 3033, 3770, 2930}, // #80 + {12, 3053, 3073, 3594, 2930}, // #81 + {12, 3089, 3105, 2, 2930}, // #82 + {12, 3121, 3137, 2962, 2930}, // #83 + {12, 3153, 3169, 290, 2930}, // #84 + {12, 3189, 3209, 794, 2930}, // #85 + {12, 3225, 3241, 1058, 2930}, // #86 + {12, 3261, 3281, 2394, 2930}, // #87 + {12, 3301, 3321, 138, 2930}, // #88 + {12, 3341, 3361, 1482, 2930}, // #89 + {12, 3381, 3401, 570, 2930}, // #90 + {12, 3417, 3433, 674, 2930}, // #91 + {12, 3449, 3465, 1282, 2930}, // #92 + {12, 3481, 3497, 1746, 2930}, // #93 + {12, 3517, 3537, 1866, 2930}, // #94 + {12, 3557, 3577, 1978, 2930}, // #95 + {12, 3593, 3609, 3954, 2930}, // #96 + {12, 3629, 3649, 2570, 2930}, // #97 + {12, 3665, 3681, 2754, 2930}, // #98 + {12, 3697, 3713, 3666, 2930}, // #99 + {12, 3729, 3745, 34, 2930}, // #100 + {12, 3761, 3777, 2914, 2930}, // #101 + {12, 3797, 3817, 1194, 2930}, // #102 + {12, 3833, 3849, 3202, 2930}, // #103 + {12, 3869, 3889, 3018, 2930}, // #104 + {12, 3909, 3929, 202, 2930}, // #105 + {12, 3949, 3969, 3546, 2930}, // #106 + {12, 3985, 4001, 3682, 2930}, // #107 + {12, 4021, 4041, 3466, 2930}, // #108 + {12, 4061, 4081, 4074, 2930}, // #109 + {12, 4097, 4113, 306, 2930}, // #110 + {12, 4133, 4153, 634, 2930}, // #111 + {12, 4169, 4185, 802, 2930}, // #112 + {12, 4201, 4217, 962, 2930}, // #113 + {12, 4237, 4257, 1114, 2930}, // #114 + {12, 4273, 4289, 1250, 2930}, // #115 + {12, 4309, 4329, 3898, 2930}, // #116 + {12, 4349, 4369, 1386, 2930}, // #117 + {12, 4385, 4401, 1586, 2930}, // #118 + {12, 4417, 4433, 1730, 2930}, // #119 + {12, 4453, 4473, 1914, 2930}, // #120 + {12, 4493, 4513, 1498, 2930}, // #121 + {12, 4533, 4553, 2138, 2930}, // #122 + {12, 4569, 4585, 2290, 2930}, // #123 + {12, 4605, 4625, 2426, 2930}, // #124 + {12, 4645, 4665, 2666, 2930}, // #125 + {12, 4681, 4697, 2050, 2930}, // #126 + {12, 4717, 4737, 2874, 2930}, // #127 + {12, 4757, 4777, 3018, 2930}, // #128 + {12, 4797, 4817, 1834, 2930}, // #129 + {12, 4837, 4857, 3178, 2930}, // #130 + {12, 4873, 4889, 3314, 2930}, // #131 + {12, 4905, 4921, 2546, 2930}, // #132 + {12, 4941, 4961, 3546, 2930}, // #133 + {12, 4977, 4993, 3682, 2930}, // #134 + {12, 5013, 5033, 3802, 2930}, // #135 + {12, 5049, 5065, 3922, 2930}, // #136 + {12, 5081, 5097, 4018, 2930}, // #137 + {12, 5117, 5137, 42, 2930}, // #138 + {12, 5153, 5169, 130, 2930}, // #139 + {12, 5185, 5201, 242, 2930}, // #140 +}; +static const int stringCollectionCount = 141; +static const int stringCollectionMaxLen = 51; +// average comparison length: 12.0922 +// cache-line crosses: 6 (2.1%) +// alignment histogram: +// 0xXXX2 = 188 (66.7%) strings, 57 (30.3%) of which same-aligned +// 0xXXXa = 94 (33.3%) strings, 10 (10.6%) of which same-aligned +// total = 282 (100%) strings, 67 (23.8%) of which same-aligned diff --git a/tests/benchmarks/corelib/tools/qstring/data.h b/tests/benchmarks/corelib/tools/qstring/data.h new file mode 100644 index 0000000..c7a7467 --- /dev/null +++ b/tests/benchmarks/corelib/tools/qstring/data.h @@ -0,0 +1,53 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <qglobal.h> + +struct StringCollection +{ + int len; + int offset1, offset2; + ushort align1, align2; +}; + +extern const ushort stringCollectionData[]; +extern StringCollection stringCollection[]; +extern const int stringCollectionCount; diff --git a/tests/benchmarks/corelib/tools/qstring/generatelist.pl b/tests/benchmarks/corelib/tools/qstring/generatelist.pl new file mode 100644 index 0000000..d027adb --- /dev/null +++ b/tests/benchmarks/corelib/tools/qstring/generatelist.pl @@ -0,0 +1,198 @@ +#!/usr/bin/perl +## Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +## All rights reserved. +## Contact: Nokia Corporation (qt-info@nokia.com) +## +## This file is part of the QtCore module of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:LGPL$ +## No Commercial Usage +## This file contains pre-release code and may not be distributed. +## You may use this file in accordance with the terms and conditions +## contained in the Technology Preview License Agreement accompanying +## this package. +## +## GNU Lesser General Public License Usage +## Alternatively, this file may be used under the terms of the GNU Lesser +## General Public License version 2.1 as published by the Free Software +## Foundation and appearing in the file LICENSE.LGPL included in the +## packaging of this file. Please review the following information to +## ensure the GNU Lesser General Public License version 2.1 requirements +## will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +## +## In addition, as a special exception, Nokia gives you certain additional +## rights. These rights are described in the Nokia Qt LGPL Exception +## version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +## +## If you have questions regarding the use of this file, please contact +## Nokia at qt-info@nokia.com. +## +## +## +## +## +## +## +## +## $QT_END_LICENSE$ +# +# Parses a file (passed as argument) that contains a dump of pairs of +# strings and generates C source code including said data. +# +# The format of the file is: +# LEN = <len> <keyword> <align1> <align2>\n<data1><data2>\n +# where: +# LEN the literal string "LEN" +# <len> the length of the data, in 16-bit words +# <keyword> the literal string "SAME" or "DIFF" +# <align1> the alignment or pointer value of the first data +# <align2> the alignment or pointer value of the second data +# <data1> the first data +# <data2> the second data +# \n newline +# +# The code to write this data would be: +# fprintf(out, "LEN = %d %s %d %d\n", len, +# (p1 == p2) ? "SAME" : "DIFF", +# uint(quintptr(p1)) & 0xfff, uint(quintptr(p2)) & 0xfff); +# fwrite(p1, 2, len, out); +# fwrite(p2, 2, len, out); +# fwrite("\n", 1, 1, out); + +sub printUshortArray($$$) { + $str = $_[0]; + $align = $_[1] & 0x1f; + $offset = $_[2]; + + die if ($align & 1) != 0; + $align /= 2; + + $len = (length $str) / 2; + $headpadding = $align & 0x7; + $tailpadding = 8 - (($len + $headpadding) & 0x7); + $multiplecachelines = ($align + $len) > 0x20; + + if ($multiplecachelines) { + # if this string crosses into a new cacheline, then + # replicate the result + $headpadding |= ($offset & ~0x1f); + $headpadding += 0x20 + if ($headpadding < $offset); + $headpadding -= $offset; + ++$cachelinecrosses; + } + for $i (1..$headpadding) { + print 65536-$i,","; + } + print "\n " if ($headpadding > 0); + print " " if ($headpadding == 0); + + for ($i = 0; $i < $len * 2; $i += 2) { + print " ", ord(substr($str, $i, 1)) + + ord(substr($str, $i + 1, 1)) * 256, + ","; + } + print "\n " if ($tailpadding > 0); + + for $i (1..$tailpadding) { + print 65536-$i, ","; + } + print " // ", $offset + $headpadding + $len + $tailpadding; + print "+" if $multiplecachelines; + + return ($offset + $headpadding, $offset + $headpadding + $len + $tailpadding); +} + +print "#include \"data.h\"\n\n"; + +print "// This is a generated file - DO NOT EDIT\n"; +print "const ushort stringCollectionData[] __attribute__((aligned(64))) = {\n"; +$count = 0; +$offset = 0; +$totalsize = 0; +$maxlen = 0; +$cachelinecrosses = 0; + +open IN, "<" . $ARGV[0]; +while (1) { + $line = readline(*IN); + last unless defined($line); + $line =~ /LEN = (\d+) (\w+) (\d+) (\d+)/; + $len = $1; + $data[$count]->{len} = $len; + $sameptr = $2; + $data[$count]->{align1} = $3 - 0; + $data[$count]->{align2} = $4 - 0; + + # statistics + $alignhistogram{$3 & 0xf}++; + $alignhistogram{$4 & 0xf}++; + $samealignments{$3 & 0xf}++ if ($3 & 0xf) == ($4 & 0xf); + + read IN, $a, $len * 2; + read IN, $b, $len * 2; + + <IN>; # Eat the newline + + if ($len == 0) { + $data[$count]->{offset1} = $offset; + $data[$count]->{offset2} = $data[$count]->{offset1}; + ++$data[$count]->{offset2} if ($sameptr eq "DIFF"); + } else { + print " // #$count\n"; + print " "; + ($data[$count]->{offset1}, $offset) = + printUshortArray($a, $data[$count]->{align1}, $offset); + print "\n "; + die if ($offset & 0x7) != 0; + + if ($sameptr eq "DIFF") { + ($data[$count]->{offset2}, $offset) = + printUshortArray($b, $data[$count]->{align2}, $offset); + print "\n\n"; + } else { + $data[$count]->{offset2} = $data[$count]->{offset1}; + print "\n\n"; + } + } + ++$count; + + $totalsize += $len; + $maxlen = $len if $len > $maxlen; +} +print "\n};\n"; +close IN; + +print "struct StringCollection stringCollection[] = {\n"; + +for $i (0..$count-1) { + print " {", + $data[$i]->{len}, ", ", + $data[$i]->{offset1}, ", ", + $data[$i]->{offset2}, ", ", + $data[$i]->{align1}, ", ", + $data[$i]->{align2}, + "}, // #$i\n"; + next if $data[$i]->{len} == 0; + die if (($data[$i]->{offset1} & 0x7) != ($data[$i]->{align1} & 0xf)/2); + die if (($data[$i]->{offset2} & 0x7) != ($data[$i]->{align2} & 0xf)/2); +} +print "};\n"; + +print "const int stringCollectionCount = $count;\n"; +print "const int stringCollectionMaxLen = $maxlen;\n"; +printf "// average comparison length: %.4f\n", ($totalsize * 1.0 / $count); +printf "// cache-line crosses: %d (%.1f%%)\n", + $cachelinecrosses, ($cachelinecrosses * 100.0 / $count / 2); + +print "// alignment histogram:\n"; +for $key (sort { $a <=> $b } keys(%alignhistogram)) { + $value = $alignhistogram{$key}; + $samealigned = $samealignments{$key}; + printf "// 0xXXX%x = %d (%.1f%%) strings, %d (%.1f%%) of which same-aligned\n", + $key, $value, $value * 100.0 / ($count*2), + $samealigned, $samealigned * 100.0 / $value; + $samealignedtotal += $samealigned; +} +printf "// total = %d (100%) strings, %d (%.1f%%) of which same-aligned\n", + $count * 2, $samealignedtotal, $samealignedtotal * 100 / $count / 2; diff --git a/tests/benchmarks/corelib/tools/qstring/main.cpp b/tests/benchmarks/corelib/tools/qstring/main.cpp index 12826eb..9616052 100644 --- a/tests/benchmarks/corelib/tools/qstring/main.cpp +++ b/tests/benchmarks/corelib/tools/qstring/main.cpp @@ -40,7 +40,7 @@ ****************************************************************************/ #include <QStringList> #include <QFile> -#include <qtest.h> +#include <QtTest/QtTest> #ifdef Q_OS_SYMBIAN // In Symbian OS test data is located in applications private dir @@ -48,12 +48,27 @@ #define SRCDIR "" #endif +#ifdef Q_OS_UNIX +#include <sys/mman.h> +#include <unistd.h> +#endif + +#include <private/qsimd_p.h> + +#include "data.h" + class tst_QString: public QObject { Q_OBJECT +public: + tst_QString(); private slots: void equals() const; void equals_data() const; + void equals2_data() const; + void equals2() const; + void ucstrncmp_data() const; + void ucstrncmp() const; void fromUtf8() const; }; @@ -67,6 +82,10 @@ void tst_QString::equals() const } } +tst_QString::tst_QString() +{ +} + void tst_QString::equals_data() const { static const struct { @@ -126,6 +145,1247 @@ void tst_QString::equals_data() const << QString::fromRawData(ptr + 1, 58) << QString::fromRawData(ptr + 3, 58); } +static bool equals2_memcmp_call(const ushort *p1, const ushort *p2, int len) +{ + return memcmp(p1, p2, len * 2) == 0; +} + +static bool equals2_bytewise(const ushort *p1, const ushort *p2, int len) +{ + if (p1 == p2 || !len) + return true; + uchar *b1 = (uchar *)p1; + uchar *b2 = (uchar *)p2; + len *= 2; + while (len--) + if (*b1++ != *b2++) + return false; + return true; +} + +static bool equals2_shortwise(const ushort *p1, const ushort *p2, int len) +{ + if (p1 == p2 || !len) + return true; +// for (register int counter; counter < len; ++counter) +// if (p1[counter] != p2[counter]) +// return false; + while (len--) { + if (p1[len] != p2[len]) + return false; + } + return true; +} + +static bool equals2_intwise(const ushort *p1, const ushort *p2, int length) +{ + if (p1 == p2 || !length) + return true; + register union { + const quint16 *w; + const quint32 *d; + quintptr value; + } sa, sb; + sa.w = p1; + sb.w = p2; + + // check alignment + if ((sa.value & 2) == (sb.value & 2)) { + // both addresses have the same alignment + if (sa.value & 2) { + // both addresses are not aligned to 4-bytes boundaries + // compare the first character + if (*sa.w != *sb.w) + return false; + --length; + ++sa.w; + ++sb.w; + + // now both addresses are 4-bytes aligned + } + + // both addresses are 4-bytes aligned + // do a fast 32-bit comparison + register const quint32 *e = sa.d + (length >> 1); + for ( ; sa.d != e; ++sa.d, ++sb.d) { + if (*sa.d != *sb.d) + return false; + } + + // do we have a tail? + return (length & 1) ? *sa.w == *sb.w : true; + } else { + // one of the addresses isn't 4-byte aligned but the other is + register const quint16 *e = sa.w + length; + for ( ; sa.w != e; ++sa.w, ++sb.w) { + if (*sa.w != *sb.w) + return false; + } + } + return true; +} + +static inline bool equals2_short_tail(const ushort *p1, const ushort *p2, int len) +{ + if (len) { + if (*p1 != *p2) + return false; + if (--len) { + if (p1[1] != p2[1]) + return false; + if (--len) { + if (p1[2] != p2[2]) + return false; + if (--len) { + if (p1[3] != p2[3]) + return false; + if (--len) { + if (p1[4] != p2[4]) + return false; + if (--len) { + if (p1[5] != p2[5]) + return false; + if (--len) { + if (p1[6] != p2[6]) + return false; + return p1[7] == p2[7]; + } + } + } + } + } + } + } + return true; +} + +//#pragma GCC optimize("no-unroll-loops") +#ifdef __SSE2__ +static bool equals2_sse2_aligned(const ushort *p1, const ushort *p2, int len) +{ + if (len >= 8) { + qptrdiff counter = 0; + while (len > 8) { + __m128i q1 = _mm_load_si128((__m128i *)(p1 + counter)); + __m128i q2 = _mm_load_si128((__m128i *)(p2 + counter)); + __m128i cmp = _mm_cmpeq_epi16(q1, q2); + if (ushort(_mm_movemask_epi8(cmp)) != ushort(0xffff)) + return false; + + len -= 8; + counter += 8; + } + p1 += counter; + p2 += counter; + } + + return equals2_short_tail(p1, p2, len); +} + +static bool __attribute__((optimize("no-unroll-loops"))) equals2_sse2(const ushort *p1, const ushort *p2, int len) +{ + if (p1 == p2 || !len) + return true; + + if (len >= 8) { + qptrdiff counter = 0; + while (len >= 8) { + __m128i q1 = _mm_loadu_si128((__m128i *)(p1 + counter)); + __m128i q2 = _mm_loadu_si128((__m128i *)(p2 + counter)); + __m128i cmp = _mm_cmpeq_epi16(q1, q2); + if (ushort(_mm_movemask_epi8(cmp)) != 0xffff) + return false; + + len -= 8; + counter += 8; + } + p1 += counter; + p2 += counter; + } + + return equals2_short_tail(p1, p2, len); +} + +//static bool equals2_sse2(const ushort *p1, const ushort *p2, int len) +//{ +// register int val1 = quintptr(p1) & 0xf; +// register int val2 = quintptr(p2) & 0xf; +// if (false && val1 + val2 == 0) +// return equals2_sse2_aligned(p1, p2, len); +// else +// return equals2_sse2_unaligned(p1, p2, len); +//} + +static bool equals2_sse2_aligning(const ushort *p1, const ushort *p2, int len) +{ + if (len < 8) + return equals2_short_tail(p1, p2, len); + + qptrdiff counter = 0; + + // which one is easier to align, p1 or p2 ? + register int val1 = quintptr(p1) & 0xf; + register int val2 = quintptr(p2) & 0xf; + if (val1 && val2) { +#if 0 + // we'll align the one which requires the least number of steps + if (val1 > val2) { + qSwap(p1, p2); + val1 = val2; + } + + // val1 contains the number of bytes past the 16-aligned mark + // we must read 16-val1 bytes to align + val1 = 16 - val1; + if (val1 & 0x2) { + if (*p1 != *p2) + return false; + --len; + ++counter; + } + while (val1 & 12) { + if (*(uint*)p1 != *(uint*)p2) + return false; + --len; + counter += 2; + val1 -= 4; + } +#else + // we'll align the one closest to the 16-byte mark + if (val1 > val2) { + qSwap(p1, p2); + val1 = val2; + } + + // we're reading val1 bytes too many + __m128i q2 = _mm_loadu_si128((__m128i *)(p2 - val1/2)); + __m128i cmp = _mm_cmpeq_epi16(*(__m128i *)(p1 - val1/2), q2); + if (short(_mm_movemask_epi8(cmp)) >> val1 != short(-1)) + return false; + + counter = 8 - val1/2; + len -= 8 - val1/2; +#endif + } else if (!val2) { + // p2 is already aligned + qSwap(p1, p2); + } + + // p1 is aligned + + while (len >= 8) { + __m128i q1 = _mm_load_si128((__m128i *)(p1 + counter)); + __m128i q2 = _mm_loadu_si128((__m128i *)(p2 + counter)); + __m128i cmp = _mm_cmpeq_epi16(q1, q2); + if (ushort(_mm_movemask_epi8(cmp)) != ushort(0xffff)) + return false; + + len -= 8; + counter += 8; + } + + // tail + return equals2_short_tail(p1 + counter, p2 + counter, len); +} + +#ifdef __SSE3__ +static bool __attribute__((optimize("no-unroll-loops"))) equals2_sse3(const ushort *p1, const ushort *p2, int len) +{ + if (p1 == p2 || !len) + return true; + + if (len >= 8) { + qptrdiff counter = 0; + while (len >= 8) { + __m128i q1 = _mm_lddqu_si128((__m128i *)(p1 + counter)); + __m128i q2 = _mm_lddqu_si128((__m128i *)(p2 + counter)); + __m128i cmp = _mm_cmpeq_epi16(q1, q2); + if (ushort(_mm_movemask_epi8(cmp)) != 0xffff) + return false; + + len -= 8; + counter += 8; + } + p1 += counter; + p2 += counter; + } + + return equals2_short_tail(p1, p2, len); +} + +#ifdef __SSSE3__ +template<int N> static __attribute__((optimize("unroll-loops"))) inline bool equals2_ssse3_alignr(__m128i *m1, __m128i *m2, int len) +{ + __m128i lower = _mm_load_si128(m1); + while (len >= 8) { + __m128i upper = _mm_load_si128(m1 + 1); + __m128i correct; + correct = _mm_alignr_epi8(upper, lower, N); + + __m128i q2 = _mm_lddqu_si128(m2); + __m128i cmp = _mm_cmpeq_epi16(correct, q2); + if (ushort(_mm_movemask_epi8(cmp)) != 0xffff) + return false; + + len -= 8; + ++m2; + ++m1; + lower = upper; + } + + // tail + return len == 0 || equals2_short_tail((const ushort *)m1 + N / 2, (const ushort*)m2, len); +} + +static inline __attribute__((optimize("unroll-loops"))) bool equals2_ssse3_aligned(__m128i *m1, __m128i *m2, int len) +{ + while (len >= 8) { + __m128i q2 = _mm_lddqu_si128(m2); + __m128i cmp = _mm_cmpeq_epi16(*m1, q2); + if (ushort(_mm_movemask_epi8(cmp)) != 0xffff) + return false; + + len -= 8; + ++m1; + ++m2; + } + return len == 0 || equals2_short_tail((const ushort *)m1, (const ushort *)m2, len); +} + +static bool equals2_ssse3(const ushort *p1, const ushort *p2, int len) +{ + // p1 & 0xf can be: + // 0, 2, 4, 6, 8, 10, 12, 14 + // If it's 0, we're aligned + // If it's not, then we're interested in the 16 - (p1 & 0xf) bytes only + + if (len >= 8) { + // find the last aligned position below the p1 memory + __m128i *m1 = (__m128i *)(quintptr(p1) & ~0xf); + __m128i *m2 = (__m128i *)p2; + qptrdiff diff = quintptr(p1) - quintptr(m1); + + // diff contains the number of extra bytes + if (diff == 10) + return equals2_ssse3_alignr<10>(m1, m2, len); + else if (diff == 2) + return equals2_ssse3_alignr<2>(m1, m2, len); + if (diff < 8) { + if (diff < 4) { + return equals2_ssse3_aligned(m1, m2, len); + } else { + if (diff == 4) + return equals2_ssse3_alignr<4>(m1, m2, len); + else // diff == 6 + return equals2_ssse3_alignr<6>(m1, m2, len); + } + } else { + if (diff < 12) { + return equals2_ssse3_alignr<8>(m1, m2, len); + } else { + if (diff == 12) + return equals2_ssse3_alignr<12>(m1, m2, len); + else // diff == 14 + return equals2_ssse3_alignr<14>(m1, m2, len); + } + } + } + + // tail + return equals2_short_tail(p1, p2, len); +} + +template<int N> static inline bool equals2_ssse3_aligning_alignr(__m128i *m1, __m128i *m2, int len) +{ + __m128i lower = _mm_load_si128(m1); + while (len >= 8) { + __m128i upper = _mm_load_si128(m1 + 1); + __m128i correct; + correct = _mm_alignr_epi8(upper, lower, N); + + __m128i cmp = _mm_cmpeq_epi16(correct, *m2); + if (ushort(_mm_movemask_epi8(cmp)) != 0xffff) + return false; + + len -= 8; + ++m2; + ++m1; + lower = upper; + } + + // tail + return len == 0 || equals2_short_tail((const ushort *)m1 + N / 2, (const ushort*)m2, len); +} + +static bool equals2_ssse3_aligning(const ushort *p1, const ushort *p2, int len) +{ + if (len < 8) + return equals2_short_tail(p1, p2, len); + qptrdiff counter = 0; + + // which one is easier to align, p1 or p2 ? + { + register int val1 = quintptr(p1) & 0xf; + register int val2 = quintptr(p2) & 0xf; + if (val1 && val2) { + // we'll align the one closest to the 16-byte mark + if (val1 < val2) { + qSwap(p1, p2); + val2 = val1; + } + + // we're reading val1 bytes too many + __m128i q1 = _mm_lddqu_si128((__m128i *)(p1 - val2/2)); + __m128i cmp = _mm_cmpeq_epi16(q1, *(__m128i *)(p2 - val2/2)); + if (short(_mm_movemask_epi8(cmp)) >> val1 != short(-1)) + return false; + + counter = 8 - val2/2; + len -= 8 - val2/2; + } else if (!val1) { + // p1 is already aligned + qSwap(p1, p2); + } + } + + // p2 is aligned now + // we want to use palignr in the mis-alignment of p1 + __m128i *m1 = (__m128i *)(quintptr(p1 + counter) & ~0xf); + __m128i *m2 = (__m128i *)(p2 + counter); + register int val1 = quintptr(p1 + counter) - quintptr(m1); + + // val1 contains the number of extra bytes + if (val1 == 8) + return equals2_ssse3_aligning_alignr<8>(m1, m2, len); + if (val1 == 0) + return equals2_sse2_aligned(p1 + counter, p2 + counter, len); + if (val1 < 8) { + if (val1 < 4) { + return equals2_ssse3_aligning_alignr<2>(m1, m2, len); + } else { + if (val1 == 4) + return equals2_ssse3_aligning_alignr<4>(m1, m2, len); + else // diff == 6 + return equals2_ssse3_aligning_alignr<6>(m1, m2, len); + } + } else { + if (val1 < 12) { + return equals2_ssse3_aligning_alignr<10>(m1, m2, len); + } else { + if (val1 == 12) + return equals2_ssse3_aligning_alignr<12>(m1, m2, len); + else // diff == 14 + return equals2_ssse3_aligning_alignr<14>(m1, m2, len); + } + } +} + +#ifdef __SSE4_1__ +static bool equals2_sse4(const ushort *p1, const ushort *p2, int len) +{ + // We use the pcmpestrm instruction searching for differences (negative polarity) + // it will reset CF if it's all equal + // it will reset OF if the first char is equal + // it will set ZF & SF if the length is less than 8 (which means we've done the last operation) + // the three possible conditions are: + // difference found: CF = 1 + // all equal, not finished: CF = ZF = SF = 0 + // all equal, finished: CF = 0, ZF = SF = 1 + // We use the JA instruction that jumps if ZF = 0 and CF = 0 + if (p1 == p2 || !len) + return true; + + // This function may read some bytes past the end of p1 or p2 + // It is safe to do that, as long as those extra bytes (beyond p1+len and p2+len) + // are on the same page as the last valid byte. + // If len is a multiple of 8, we'll never load invalid bytes. + if (len & 7) { + // The last load would load (len & ~7) valid bytes and (8 - (len & ~7)) invalid bytes. + // So we can't do the last load if any of those bytes is in a different + // page. That is, if: + // pX + len is on a different page from pX + (len & ~7) + 8 + // + // that is, if second-to-last load ended up less than 16 bytes from the page end: + // pX + (len & ~7) is the last ushort read in the second-to-last load + if (len < 8) + return equals2_short_tail(p1, p2, len); + if ((quintptr(p1 + (len & ~7)) & 0xfff) > 0xff0 || + (quintptr(p2 + (len & ~7)) & 0xfff) > 0xff0) { + + // yes, so we mustn't do the final 128-bit load + bool result; + asm ( + "sub %[p1], %[p2]\n\t" + "sub $16, %[p1]\n\t" + "add $8, %[len]\n\t" + + // main loop: + "0:\n\t" + "add $16, %[p1]\n\t" + "sub $8, %[len]\n\t" + "jz 1f\n\t" + "lddqu (%[p1]), %%xmm0\n\t" + "mov %[len], %%edx\n\t" + "pcmpestri %[mode], (%[p2],%[p1]), %%xmm0\n\t" + + "jna 1f\n\t" + "add $16, %[p1]\n\t" + "sub $8, %[len]\n\t" + "jz 1f\n\t" + "lddqu (%[p1]), %%xmm0\n\t" + "mov %[len], %%edx\n\t" + "pcmpestri %[mode], (%[p2],%[p1]), %%xmm0\n\t" + + "ja 0b\n\t" + "1:\n\t" + "setnc %[result]\n\t" + : [result] "=a" (result), + [p1] "+r" (p1), + [p2] "+r" (p2) + : [len] "0" (len & ~7), + [mode] "i" (_SIDD_UWORD_OPS | _SIDD_CMP_EQUAL_EACH | _SIDD_NEGATIVE_POLARITY) + : "%edx", "%ecx", "%xmm0" + ); + return result && equals2_short_tail(p1, (const ushort *)(quintptr(p1) + quintptr(p2)), len & 7); + } + } + +// const qptrdiff disp = p2 - p1; +// p1 -= 8; +// len += 8; +// while (true) { +// enum { Mode = _SIDD_UWORD_OPS | _SIDD_CMP_EQUAL_EACH | _SIDD_NEGATIVE_POLARITY }; + +// p1 += 8; +// len -= 8; +// if (!len) +// return true; + +// __m128i q1 = _mm_lddqu_si128((__m128i *)(p1 + disp)); +// __m128i *m2 = (__m128i *)p1; + +// bool cmp_a = _mm_cmpestra(q1, len, *m2, len, Mode); +// if (cmp_a) +// continue; +// return !_mm_cmpestrc(q1, len, *m2, len, Mode); +// } +// return true; + bool result; + asm ( + "sub %[p1], %[p2]\n\t" + "sub $16, %[p1]\n\t" + "add $8, %[len]\n\t" + + "0:\n\t" + "add $16, %[p1]\n\t" + "sub $8, %[len]\n\t" + "jz 1f\n\t" + "lddqu (%[p2],%[p1]), %%xmm0\n\t" + "mov %[len], %%edx\n\t" + "pcmpestri %[mode], (%[p1]), %%xmm0\n\t" + + "jna 1f\n\t" + "add $16, %[p1]\n\t" + "sub $8, %[len]\n\t" + "jz 1f\n\t" + "lddqu (%[p2],%[p1]), %%xmm0\n\t" + "mov %[len], %%edx\n\t" + "pcmpestri %[mode], (%[p1]), %%xmm0\n\t" + + "ja 0b\n\t" + + "1:\n\t" + "setnc %[result]\n\t" + : [result] "=a" (result) + : [len] "0" (len), + [p1] "r" (p1), + [p2] "r" (p2), + [mode] "i" (_SIDD_UWORD_OPS | _SIDD_CMP_EQUAL_EACH | _SIDD_NEGATIVE_POLARITY) + : "%edx", "%ecx", "%xmm0" + ); + return result; +} + +#endif +#endif +#endif +#endif + +typedef bool (* FuncPtr)(const ushort *, const ushort *, int); +static const FuncPtr func[] = { + equals2_memcmp_call, // 0 + equals2_bytewise, // 1 + equals2_shortwise, // 1 + equals2_intwise, // 3 +#ifdef __SSE2__ + equals2_sse2, // 4 + equals2_sse2_aligning, // 5 +#ifdef __SSE3__ + equals2_sse3, // 6 +#ifdef __SSSE3__ + equals2_ssse3, // 7 + equals2_ssse3, // 8 +#ifdef __SSE4_1__ + equals2_sse4, // 9 +#endif +#endif +#endif +#endif + 0 +}; +static const int functionCount = sizeof(func)/sizeof(func[0]) - 1; + +void tst_QString::equals2_data() const +{ + QTest::addColumn<int>("algorithm"); + QTest::newRow("selftest") << -1; + QTest::newRow("memcmp_call") << 0; + QTest::newRow("bytewise") << 1; + QTest::newRow("shortwise") << 2; + QTest::newRow("intwise") << 3; +#ifdef __SSE2__ + QTest::newRow("sse2") << 4; + QTest::newRow("sse2_aligning") << 5; +#ifdef __SSE3__ + QTest::newRow("sse3") << 6; +#ifdef __SSSE3__ + QTest::newRow("ssse3") << 7; + QTest::newRow("ssse3_aligning") << 8; +#ifdef __SSE4_1__ + QTest::newRow("sse4.2") << 9; +#endif +#endif +#endif +#endif +} + +static void __attribute__((noinline)) equals2_selftest() +{ +#ifdef Q_OS_UNIX + const long pagesize = sysconf(_SC_PAGESIZE); + void *page1, *page3; + ushort *page2; + page1 = mmap(0, pagesize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + page2 = (ushort *)mmap(0, pagesize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_POPULATE, -1, 0); + page3 = mmap(0, pagesize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + + Q_ASSERT(quintptr(page2) == quintptr(page1) + pagesize || quintptr(page2) == quintptr(page1) - pagesize); + Q_ASSERT(quintptr(page3) == quintptr(page2) + pagesize || quintptr(page3) == quintptr(page2) - pagesize); + munmap(page1, pagesize); + munmap(page3, pagesize); + + // populate our page + for (uint i = 0; i < pagesize / sizeof(long long); ++i) + ((long long *)page2)[i] = Q_INT64_C(0x0041004100410041); + + // the following should crash: + //page2[-1] = 0xdead; + //page2[pagesize / sizeof(ushort) + 1] = 0xbeef; + + static const ushort needle[] = { + 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, + 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, + 0x41 + }; + + for (int algo = 0; algo < functionCount; ++algo) { + // boundary condition test: + for (int i = 0; i < 8; ++i) { + (func[algo])(page2 + i, needle, sizeof needle / 2); + (func[algo])(page2 - i - 1 - sizeof(needle)/2 + pagesize/2, needle, sizeof needle/2); + } + } + + munmap(page2, pagesize); +#endif + + for (int algo = 0; algo < functionCount; ++algo) { + for (int i = 0; i < stringCollectionCount; ++i) { + const ushort *p1 = stringCollectionData + stringCollection[i].offset1; + const ushort *p2 = stringCollectionData + stringCollection[i].offset2; + bool expected = memcmp(p1, p2, stringCollection[i].len * 2) == 0; + + bool result = (func[algo])(p1, p2, stringCollection[i].len); + if (expected != result) + qWarning().nospace() + << "algo=" << algo + << " i=" << i + << " failed (" << result << "!=" << expected + << "); strings were " + << QByteArray((char*)p1, stringCollection[i].len).toHex() + << " and " + << QByteArray((char*)p2, stringCollection[i].len).toHex(); + } + } +} + +void tst_QString::equals2() const +{ + QFETCH(int, algorithm); + if (algorithm == -1) { + equals2_selftest(); + return; + } + + QBENCHMARK { + for (int i = 0; i < stringCollectionCount; ++i) { + const ushort *p1 = stringCollectionData + stringCollection[i].offset1; + const ushort *p2 = stringCollectionData + stringCollection[i].offset2; + bool result = (func[algorithm])(p1, p2, stringCollection[i].len); + Q_UNUSED(result); + } + } +} + +static int ucstrncmp_shortwise(const ushort *a, const ushort *b, int l) +{ + while (l-- && *a == *b) + a++,b++; + if (l==-1) + return 0; + return *a - *b; +} + +static int ucstrncmp_intwise(const ushort *a, const ushort *b, int len) +{ + // do both strings have the same alignment? + if ((quintptr(a) & 2) == (quintptr(b) & 2)) { + // are we aligned to 4 bytes? + if (quintptr(a) & 2) { + if (*a != *b) + return *a - *b; + ++a; + ++b; + --len; + } + + const uint *p1 = (const uint *)a; + const uint *p2 = (const uint *)b; + quintptr counter = 0; + for ( ; len > 1 ; len -= 2, ++counter) { + if (p1[counter] != p2[counter]) { + // which ushort isn't equal? + int diff = a[2*counter] - b[2*counter]; + return diff ? diff : a[2*counter + 1] - b[2*counter + 1]; + } + } + + return len ? a[2*counter] - b[2*counter] : 0; + } else { + while (len-- && *a == *b) + a++,b++; + if (len==-1) + return 0; + return *a - *b; + } +} + +#ifdef __SSE2__ +static inline int ucstrncmp_short_tail(const ushort *p1, const ushort *p2, int len) +{ + if (len) { + if (*p1 != *p2) + return *p1 - *p2; + if (--len) { + if (p1[1] != p2[1]) + return p1[1] - p2[1]; + if (--len) { + if (p1[2] != p2[2]) + return p1[2] - p2[2]; + if (--len) { + if (p1[3] != p2[3]) + return p1[3] - p2[3]; + if (--len) { + if (p1[4] != p2[4]) + return p1[4] - p2[4]; + if (--len) { + if (p1[5] != p2[5]) + return p1[5] - p2[5]; + if (--len) { + if (p1[6] != p2[6]) + return p1[6] - p2[6]; + return p1[7] - p2[7]; + } + } + } + } + } + } + } + return 0; +} + +static inline int bsf_nonzero(register long val) +{ + int result; +# ifdef Q_CC_GNU + // returns the first non-zero bit on a non-zero reg + asm ("bsf %1, %0" : "=r" (result) : "r" (val)); + return result; +# elif defined(Q_CC_MSVC) + _BitScanForward(&result, val); + return result; +# endif +} + +static __attribute__((optimize("no-unroll-loops"))) int ucstrncmp_sse2(const ushort *a, const ushort *b, int len) +{ + qptrdiff counter = 0; + while (len >= 8) { + __m128i m1 = _mm_loadu_si128((__m128i *)(a + counter)); + __m128i m2 = _mm_loadu_si128((__m128i *)(b + counter)); + __m128i cmp = _mm_cmpeq_epi16(m1, m2); + ushort mask = ~uint(_mm_movemask_epi8(cmp)); + if (mask) { + // which ushort isn't equal? + counter += bsf_nonzero(mask)/2; + return a[counter] - b[counter]; + } + + counter += 8; + len -= 8; + } + return ucstrncmp_short_tail(a + counter, b + counter, len); +} + +static __attribute__((optimize("no-unroll-loops"))) int ucstrncmp_sse2_aligning(const ushort *a, const ushort *b, int len) +{ + if (len >= 8) { + __m128i m1 = _mm_loadu_si128((__m128i *)a); + __m128i m2 = _mm_loadu_si128((__m128i *)b); + __m128i cmp = _mm_cmpeq_epi16(m1, m2); + ushort mask = ~uint(_mm_movemask_epi8(cmp)); + if (mask) { + // which ushort isn't equal? + int counter = bsf_nonzero(mask)/2; + return a[counter] - b[counter]; + } + + + // now align to do 16-byte loads + int diff = 8 - (quintptr(a) & 0xf)/2; + len -= diff; + a += diff; + b += diff; + } + + qptrdiff counter = 0; + while (len >= 8) { + __m128i m1 = _mm_load_si128((__m128i *)(a + counter)); + __m128i m2 = _mm_loadu_si128((__m128i *)(b + counter)); + __m128i cmp = _mm_cmpeq_epi16(m1, m2); + ushort mask = ~uint(_mm_movemask_epi8(cmp)); + if (mask) { + // which ushort isn't equal? + counter += bsf_nonzero(mask)/2; + return a[counter] - b[counter]; + } + + counter += 8; + len -= 8; + } + return ucstrncmp_short_tail(a + counter, b + counter, len); +} + +static inline __attribute__((optimize("no-unroll-loops"))) int ucstrncmp_sse2_aligned(const ushort *a, const ushort *b, int len) +{ + quintptr counter = 0; + while (len >= 8) { + __m128i m1 = _mm_load_si128((__m128i *)(a + counter)); + __m128i m2 = _mm_load_si128((__m128i *)(b + counter)); + __m128i cmp = _mm_cmpeq_epi16(m1, m2); + ushort mask = ~uint(_mm_movemask_epi8(cmp)); + if (mask) { + // which ushort isn't equal? + counter += bsf_nonzero(mask)/2; + return a[counter] - b[counter]; + } + + counter += 8; + len -= 8; + } + return ucstrncmp_short_tail(a + counter, b + counter, len); +} + +static inline __attribute__((optimize("no-unroll-loops"))) int ucstrncmp_ssse3_alignr_aligned(const ushort *a, const ushort *b, int len) +{ + quintptr counter = 0; + while (len >= 8) { + __m128i m1 = _mm_load_si128((__m128i *)(a + counter)); + __m128i m2 = _mm_lddqu_si128((__m128i *)(b + counter)); + __m128i cmp = _mm_cmpeq_epi16(m1, m2); + ushort mask = ~uint(_mm_movemask_epi8(cmp)); + if (mask) { + // which ushort isn't equal? + counter += bsf_nonzero(mask)/2; + return a[counter] - b[counter]; + } + + counter += 8; + len -= 8; + } + return ucstrncmp_short_tail(a + counter, b + counter, len); +} + + +typedef __m128i (* MMLoadFunction)(const __m128i *); +template<int N, MMLoadFunction LoadFunction> +static inline __attribute__((optimize("no-unroll-loops"))) int ucstrncmp_ssse3_alignr(const ushort *a, const ushort *b, int len) +{ + qptrdiff counter = 0; + __m128i lower, upper; + upper = _mm_load_si128((__m128i *)a); + + do { + lower = upper; + upper = _mm_load_si128((__m128i *)(a + counter) + 1); + __m128i merged = _mm_alignr_epi8(upper, lower, N); + + __m128i m2 = LoadFunction((__m128i *)(b + counter)); + __m128i cmp = _mm_cmpeq_epi16(merged, m2); + ushort mask = ~uint(_mm_movemask_epi8(cmp)); + if (mask) { + // which ushort isn't equal? + counter += bsf_nonzero(mask)/2; + return a[counter + N/2] - b[counter]; + } + + counter += 8; + len -= 8; + } while (len >= 8); + + return ucstrncmp_short_tail(a + counter + N/2, b + counter, len); +} + +static int ucstrncmp_ssse3(const ushort *a, const ushort *b, int len) +{ + if (len >= 8) { + int val = quintptr(a) & 0xf; + a -= val/2; + + if (val == 10) + return ucstrncmp_ssse3_alignr<10, _mm_lddqu_si128>(a, b, len); + else if (val == 2) + return ucstrncmp_ssse3_alignr<2, _mm_lddqu_si128>(a, b, len); + if (val < 8) { + if (val < 4) + return ucstrncmp_ssse3_alignr_aligned(a, b, len); + else if (val == 4) + return ucstrncmp_ssse3_alignr<4, _mm_lddqu_si128>(a, b, len); + else + return ucstrncmp_ssse3_alignr<6, _mm_lddqu_si128>(a, b, len); + } else { + if (val < 12) + return ucstrncmp_ssse3_alignr<8, _mm_lddqu_si128>(a, b, len); + else if (val == 12) + return ucstrncmp_ssse3_alignr<12, _mm_lddqu_si128>(a, b, len); + else + return ucstrncmp_ssse3_alignr<14, _mm_lddqu_si128>(a, b, len); + } + } + return ucstrncmp_short_tail(a, b, len); +} + +static int ucstrncmp_ssse3_aligning(const ushort *a, const ushort *b, int len) +{ + if (len >= 8) { + __m128i m1 = _mm_loadu_si128((__m128i *)a); + __m128i m2 = _mm_loadu_si128((__m128i *)b); + __m128i cmp = _mm_cmpeq_epi16(m1, m2); + ushort mask = ~uint(_mm_movemask_epi8(cmp)); + if (mask) { + // which ushort isn't equal? + int counter = bsf_nonzero(mask)/2; + return a[counter] - b[counter]; + } + + + // now 'b' align to do 16-byte loads + int diff = 8 - (quintptr(b) & 0xf)/2; + len -= diff; + a += diff; + b += diff; + } + + if (len < 8) + return ucstrncmp_short_tail(a, b, len); + + // 'b' is aligned + int val = quintptr(a) & 0xf; + a -= val/2; + + if (val == 8) + return ucstrncmp_ssse3_alignr<8, _mm_load_si128>(a, b, len); + else if (val == 0) + return ucstrncmp_sse2_aligned(a, b, len); + if (val < 8) { + if (val < 4) + return ucstrncmp_ssse3_alignr<2, _mm_load_si128>(a, b, len); + else if (val == 4) + return ucstrncmp_ssse3_alignr<4, _mm_load_si128>(a, b, len); + else + return ucstrncmp_ssse3_alignr<6, _mm_load_si128>(a, b, len); + } else { + if (val < 12) + return ucstrncmp_ssse3_alignr<10, _mm_load_si128>(a, b, len); + else if (val == 12) + return ucstrncmp_ssse3_alignr<12, _mm_load_si128>(a, b, len); + else + return ucstrncmp_ssse3_alignr<14, _mm_load_si128>(a, b, len); + } +} + +static inline __attribute__((optimize("no-unroll-loops"))) +int ucstrncmp_ssse3_aligning2_aligned(const ushort *a, const ushort *b, int len, int garbage) +{ + // len >= 8 + __m128i m1 = _mm_load_si128((const __m128i *)a); + __m128i m2 = _mm_load_si128((const __m128i *)b); + __m128i cmp = _mm_cmpeq_epi16(m1, m2); + int mask = short(_mm_movemask_epi8(cmp)); // force sign extension + mask >>= garbage; + if (~mask) { + // which ushort isn't equal? + uint counter = (garbage + bsf_nonzero(~mask)); + return a[counter/2] - b[counter/2]; + } + + // the first 16-garbage bytes (8-garbage/2 ushorts) were equal + len -= 8 - garbage/2; + return ucstrncmp_sse2_aligned(a + 8, b + 8, len); +} + +template<int N> static inline __attribute__((optimize("no-unroll-loops"),always_inline)) +int ucstrncmp_ssse3_aligning2_alignr(const ushort *a, const ushort *b, int len, int garbage) +{ + // len >= 8 + __m128i lower, upper, merged; + lower = _mm_load_si128((const __m128i*)a); + upper = _mm_load_si128((const __m128i*)(a + 8)); + merged = _mm_alignr_epi8(upper, lower, N); + + __m128i m2 = _mm_load_si128((const __m128i*)b); + __m128i cmp = _mm_cmpeq_epi16(merged, m2); + int mask = short(_mm_movemask_epi8(cmp)); // force sign extension + mask >>= garbage; + if (~mask) { + // which ushort isn't equal? + uint counter = (garbage + bsf_nonzero(~mask)); + return a[counter/2 + N/2] - b[counter/2]; + } + + // the first 16-garbage bytes (8-garbage/2 ushorts) were equal + quintptr counter = 8; + len -= 8 - garbage/2; + while (len >= 8) { + lower = upper; + upper = _mm_load_si128((__m128i *)(a + counter) + 1); + merged = _mm_alignr_epi8(upper, lower, N); + + m2 = _mm_load_si128((__m128i *)(b + counter)); + cmp = _mm_cmpeq_epi16(merged, m2); + ushort mask = ~uint(_mm_movemask_epi8(cmp)); + if (mask) { + // which ushort isn't equal? + counter += bsf_nonzero(mask)/2; + return a[counter + N/2] - b[counter]; + } + + counter += 8; + len -= 8; + } + + return ucstrncmp_short_tail(a + counter + N/2, b + counter, len); +} + +static inline int conditional_invert(int result, bool invert) +{ + if (invert) + return -result; + return result; +} + +static int ucstrncmp_ssse3_aligning2(const ushort *a, const ushort *b, int len) +{ + // Different strategy from above: instead of doing two unaligned loads + // when trying to align, we'll only do aligned loads and round down the + // addresses of a and b. This means the first load will contain garbage + // in the beginning of the string, which we'll shift out of the way + // (after _mm_movemask_epi8) + + if (len < 8) + return ucstrncmp_intwise(a, b, len); + + // both a and b are misaligned + // we'll call the alignr function with the alignment *difference* between the two + int offset = (quintptr(a) & 0xf) - (quintptr(b) & 0xf); + if (offset >= 0) { + // from this point on, b has the shortest alignment + // and align(a) = align(b) + offset + // round down the alignment so align(b) == align(a) == 0 + int garbage = (quintptr(b) & 0xf); + a = (const ushort*)(quintptr(a) & ~0xf); + b = (const ushort*)(quintptr(b) & ~0xf); + + // now the first load of b will load 'garbage' extra bytes + // and the first load of a will load 'garbage + offset' extra bytes + if (offset == 8) + return ucstrncmp_ssse3_aligning2_alignr<8>(a, b, len, garbage); + if (offset == 0) + return ucstrncmp_ssse3_aligning2_aligned(a, b, len, garbage); + if (offset < 8) { + if (offset < 4) + return ucstrncmp_ssse3_aligning2_alignr<2>(a, b, len, garbage); + else if (offset == 4) + return ucstrncmp_ssse3_aligning2_alignr<4>(a, b, len, garbage); + else + return ucstrncmp_ssse3_aligning2_alignr<6>(a, b, len, garbage); + } else { + if (offset < 12) + return ucstrncmp_ssse3_aligning2_alignr<10>(a, b, len, garbage); + else if (offset == 12) + return ucstrncmp_ssse3_aligning2_alignr<12>(a, b, len, garbage); + else + return ucstrncmp_ssse3_aligning2_alignr<14>(a, b, len, garbage); + } + } else { + // same as above but inverted + int garbage = (quintptr(a) & 0xf); + a = (const ushort*)(quintptr(a) & ~0xf); + b = (const ushort*)(quintptr(b) & ~0xf); + + offset = -offset; + if (offset == 8) + return -ucstrncmp_ssse3_aligning2_alignr<8>(b, a, len, garbage); + if (offset < 8) { + if (offset < 4) + return -ucstrncmp_ssse3_aligning2_alignr<2>(b, a, len, garbage); + else if (offset == 4) + return -ucstrncmp_ssse3_aligning2_alignr<4>(b, a, len, garbage); + else + return -ucstrncmp_ssse3_aligning2_alignr<6>(b, a, len, garbage); + } else { + if (offset < 12) + return -ucstrncmp_ssse3_aligning2_alignr<10>(b, a, len, garbage); + else if (offset == 12) + return -ucstrncmp_ssse3_aligning2_alignr<12>(b, a, len, garbage); + else + return -ucstrncmp_ssse3_aligning2_alignr<14>(b, a, len, garbage); + } + } +} + +#endif + +typedef int (* UcstrncmpFunction)(const ushort *, const ushort *, int); +Q_DECLARE_METATYPE(UcstrncmpFunction) + +void tst_QString::ucstrncmp_data() const +{ + QTest::addColumn<UcstrncmpFunction>("function"); + QTest::newRow("selftest") << UcstrncmpFunction(0); + QTest::newRow("shortwise") << &ucstrncmp_shortwise; + QTest::newRow("intwise") << &ucstrncmp_intwise; +#ifdef __SSE2__ + QTest::newRow("sse2") << &ucstrncmp_sse2; + QTest::newRow("sse2_aligning") << &ucstrncmp_sse2_aligning; +#ifdef __SSSE3__ + QTest::newRow("ssse3") << &ucstrncmp_ssse3; + QTest::newRow("ssse3_aligning") << &ucstrncmp_ssse3_aligning; + QTest::newRow("ssse3_aligning2") << &ucstrncmp_ssse3_aligning2; +#endif +#endif +} + +void tst_QString::ucstrncmp() const +{ + QFETCH(UcstrncmpFunction, function); + if (!function) { + static const UcstrncmpFunction func[] = { + &ucstrncmp_shortwise, + &ucstrncmp_intwise, +#ifdef __SSE2__ + &ucstrncmp_sse2, + &ucstrncmp_sse2_aligning, +#ifdef __SSSE3__ + &ucstrncmp_ssse3, + &ucstrncmp_ssse3_aligning, + &ucstrncmp_ssse3_aligning2 +#endif +#endif + }; + static const int functionCount = sizeof func / sizeof func[0]; + +#ifdef Q_OS_UNIX + const long pagesize = sysconf(_SC_PAGESIZE); + void *page1, *page3; + ushort *page2; + page1 = mmap(0, pagesize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + page2 = (ushort *)mmap(0, pagesize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_POPULATE, -1, 0); + page3 = mmap(0, pagesize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + + Q_ASSERT(quintptr(page2) == quintptr(page1) + pagesize || quintptr(page2) == quintptr(page1) - pagesize); + Q_ASSERT(quintptr(page3) == quintptr(page2) + pagesize || quintptr(page3) == quintptr(page2) - pagesize); + munmap(page1, pagesize); + munmap(page3, pagesize); + + // populate our page + for (uint i = 0; i < pagesize / sizeof(long long); ++i) + ((long long *)page2)[i] = Q_INT64_C(0x0041004100410041); + + // the following should crash: + //page2[-1] = 0xdead; + //page2[pagesize / sizeof(ushort) + 1] = 0xbeef; + + static const ushort needle[] = { + 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, + 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, + 0x41 + }; + + for (int algo = 0; algo < functionCount; ++algo) { + // boundary condition test: + for (int i = 0; i < 8; ++i) { + (func[algo])(page2 + i, needle, sizeof needle / 2); + (func[algo])(page2 - i - 1 - sizeof(needle)/2 + pagesize/2, needle, sizeof needle/2); + } + } + + munmap(page2, pagesize); +#endif + + for (int algo = 0; algo < functionCount; ++algo) { + for (int i = 0; i < stringCollectionCount; ++i) { + const ushort *p1 = stringCollectionData + stringCollection[i].offset1; + const ushort *p2 = stringCollectionData + stringCollection[i].offset2; + int expected = ucstrncmp_shortwise(p1, p2, stringCollection[i].len); + expected = qBound(-1, expected, 1); + + int result = (func[algo])(p1, p2, stringCollection[i].len); + result = qBound(-1, result, 1); + if (expected != result) + qWarning().nospace() + << "algo=" << algo + << " i=" << i + << " failed (" << result << "!=" << expected + << "); strings were " + << QByteArray((char*)p1, stringCollection[i].len).toHex() + << " and " + << QByteArray((char*)p2, stringCollection[i].len).toHex(); + } + } + return; + } + + QBENCHMARK { + for (int i = 0; i < stringCollectionCount; ++i) { + const ushort *p1 = stringCollectionData + stringCollection[i].offset1; + const ushort *p2 = stringCollectionData + stringCollection[i].offset2; + (function)(p1, p2, stringCollection[i].len); + } + } +} + void tst_QString::fromUtf8() const { QFile file(SRCDIR "utf-8.txt"); diff --git a/tests/benchmarks/corelib/tools/qstring/qstring.pro b/tests/benchmarks/corelib/tools/qstring/qstring.pro index fa4310e..e8720e1 100644 --- a/tests/benchmarks/corelib/tools/qstring/qstring.pro +++ b/tests/benchmarks/corelib/tools/qstring/qstring.pro @@ -1,7 +1,7 @@ load(qttest_p4) TARGET = tst_bench_qstring QT -= gui -SOURCES += main.cpp +SOURCES += main.cpp data.cpp wince*:{ DEFINES += SRCDIR=\\\"\\\" @@ -14,3 +14,6 @@ wince*:{ DEFINES += SRCDIR=\\\"$$PWD/\\\" } +sse4:QMAKE_CXXFLAGS += -msse4 +else:ssse3:QMAKE_FLAGS += -mssse3 +else:sse2:QMAKE_CXXFLAGS += -msse2 |