diff options
author | Liang Qi <liang.qi@theqtcompany.com> | 2015-09-25 20:56:51 +0200 |
---|---|---|
committer | Liang Qi <liang.qi@theqtcompany.com> | 2015-09-25 20:56:51 +0200 |
commit | f9ef039ad955db67dc3ab6e9056afc4a325aa9a3 (patch) | |
tree | 4928ff85fb630639e306ea4eb7137a2064a80c8b /tests | |
parent | 0238c739f81911f0963cf2c40b27dcfc8e3d38b7 (diff) | |
parent | 52fb4685e95e5b44e54d2d0f8ea27dea866c75e9 (diff) |
Merge remote-tracking branch 'origin/5.6' into dev
Conflicts:
src/qml/debugger/qqmldebug.cpp
Change-Id: I93de5a81b18cdece475870cf7cfba1b9baef2304
Diffstat (limited to 'tests')
25 files changed, 549 insertions, 123 deletions
diff --git a/tests/auto/qml/qqmlbinding/data/readonlyProperty.qml b/tests/auto/qml/qqmlbinding/data/readonlyProperty.qml new file mode 100644 index 0000000000..fa8d93d355 --- /dev/null +++ b/tests/auto/qml/qqmlbinding/data/readonlyProperty.qml @@ -0,0 +1,13 @@ +import QtQuick 2.0 + +Item { + id: root + + readonly property string name: "John" + + Binding { + target: root + property: "name" + value: "Doe" + } +} diff --git a/tests/auto/qml/qqmlbinding/data/unknownProperty.qml b/tests/auto/qml/qqmlbinding/data/unknownProperty.qml new file mode 100644 index 0000000000..36157bb4e7 --- /dev/null +++ b/tests/auto/qml/qqmlbinding/data/unknownProperty.qml @@ -0,0 +1,11 @@ +import QtQuick 2.0 + +Item { + id: root + + Binding { + target: root + property: "unknown" + value: 42 + } +} diff --git a/tests/auto/qml/qqmlbinding/tst_qqmlbinding.cpp b/tests/auto/qml/qqmlbinding/tst_qqmlbinding.cpp index 2d267cc668..3e49f3b3c4 100644 --- a/tests/auto/qml/qqmlbinding/tst_qqmlbinding.cpp +++ b/tests/auto/qml/qqmlbinding/tst_qqmlbinding.cpp @@ -50,6 +50,8 @@ private slots: void restoreBindingWithLoop(); void restoreBindingWithoutCrash(); void deletedObject(); + void warningOnUnknownProperty(); + void warningOnReadOnlyProperty(); private: QQmlEngine engine; @@ -224,6 +226,38 @@ void tst_qqmlbinding::deletedObject() delete rect; } +void tst_qqmlbinding::warningOnUnknownProperty() +{ + QQmlTestMessageHandler messageHandler; + + QQmlEngine engine; + QQmlComponent c(&engine, testFileUrl("unknownProperty.qml")); + QQuickItem *item = qobject_cast<QQuickItem*>(c.create()); + QVERIFY(item); + delete item; + + QCOMPARE(messageHandler.messages().count(), 1); + + const QString expectedMessage = c.url().toString() + QLatin1String(":6:5: QML Binding: Property 'unknown' does not exist on Item."); + QCOMPARE(messageHandler.messages().first(), expectedMessage); +} + +void tst_qqmlbinding::warningOnReadOnlyProperty() +{ + QQmlTestMessageHandler messageHandler; + + QQmlEngine engine; + QQmlComponent c(&engine, testFileUrl("readonlyProperty.qml")); + QQuickItem *item = qobject_cast<QQuickItem*>(c.create()); + QVERIFY(item); + delete item; + + QCOMPARE(messageHandler.messages().count(), 1); + + const QString expectedMessage = c.url().toString() + QLatin1String(":8:5: QML Binding: Property 'name' on Item is read-only."); + QCOMPARE(messageHandler.messages().first(), expectedMessage); +} + QTEST_MAIN(tst_qqmlbinding) #include "tst_qqmlbinding.moc" diff --git a/tests/auto/qml/qqmlecmascript/data/qtbug_46022.js b/tests/auto/qml/qqmlecmascript/data/qtbug_46022.js new file mode 100644 index 0000000000..385d7f9e97 --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/qtbug_46022.js @@ -0,0 +1,21 @@ +var obj = {} +obj[5289] = 0 +obj[5290] = 0 +obj[5288] = 0 +obj[5287] = 0 +delete obj[5288] + +var a = Object.getOwnPropertyNames(obj) +var test1 = a.every(function(key) { + return obj.hasOwnProperty(key) +}) + +obj = {} +obj[8187] = 0 +obj[8188] = 0 +delete obj[8187] + +var b = Object.getOwnPropertyNames(obj) +var test2 = b.every(function(key) { + return obj.hasOwnProperty(key) +}) diff --git a/tests/auto/qml/qqmlecmascript/data/qtbug_46022.qml b/tests/auto/qml/qqmlecmascript/data/qtbug_46022.qml new file mode 100644 index 0000000000..2d2375de3e --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/qtbug_46022.qml @@ -0,0 +1,7 @@ +import "qtbug_46022.js" as Test +import QtQuick 2.0 + +QtObject { + property bool test1: Test.test1 + property bool test2: Test.test2 +} diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp index a1038b0f52..e186c364c3 100644 --- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp +++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp @@ -326,6 +326,7 @@ private slots: void readUnregisteredQObjectProperty(); void writeUnregisteredQObjectProperty(); void switchExpression(); + void qtbug_46022(); private: // static void propertyVarWeakRefCallback(v8::Persistent<v8::Value> object, void* parameter); @@ -7876,6 +7877,16 @@ void tst_qqmlecmascript::switchExpression() QCOMPARE(v.toBool(), true); } +void tst_qqmlecmascript::qtbug_46022() +{ + QQmlComponent component(&engine, testFileUrl("qtbug_46022.qml")); + + QScopedPointer<QObject> obj(component.create()); + QVERIFY(obj != 0); + QCOMPARE(obj->property("test1").toBool(), true); + QCOMPARE(obj->property("test2").toBool(), true); +} + QTEST_MAIN(tst_qqmlecmascript) #include "tst_qqmlecmascript.moc" diff --git a/tests/auto/qml/qqmllanguage/data/CompositeTypeWithEnum.qml b/tests/auto/qml/qqmllanguage/data/CompositeTypeWithEnum.qml new file mode 100644 index 0000000000..6a14e72a31 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/CompositeTypeWithEnum.qml @@ -0,0 +1,4 @@ +import Test 1.0 + +MyCompositeBaseType { +} diff --git a/tests/auto/qml/qqmllanguage/data/registeredCompositeTypeWithEnum.qml b/tests/auto/qml/qqmllanguage/data/registeredCompositeTypeWithEnum.qml new file mode 100644 index 0000000000..5f8c11e5f6 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/registeredCompositeTypeWithEnum.qml @@ -0,0 +1,6 @@ +import Test 1.0 + +RegisteredCompositeTypeWithEnum { + property int enumValue0: RegisteredCompositeTypeWithEnum.EnumValue0 + property int enumValue42: RegisteredCompositeTypeWithEnum.EnumValue42 +} diff --git a/tests/auto/qml/qqmllanguage/testtypes.cpp b/tests/auto/qml/qqmllanguage/testtypes.cpp index 6fc4bae438..95a98788c3 100644 --- a/tests/auto/qml/qqmllanguage/testtypes.cpp +++ b/tests/auto/qml/qqmllanguage/testtypes.cpp @@ -91,6 +91,8 @@ void registerTypes() qmlRegisterCustomExtendedType<SimpleObjectWithCustomParser, SimpleObjectExtension>("Test", 1, 0, "SimpleExtendedObjectWithCustomParser", new SimpleObjectCustomParser); qmlRegisterType<RootObjectInCreationTester>("Test", 1, 0, "RootObjectInCreationTester"); + + qmlRegisterType<MyCompositeBaseType>("Test", 1, 0, "MyCompositeBaseType"); } QVariant myCustomVariantTypeConverter(const QString &data) @@ -121,7 +123,7 @@ void CustomBinding::componentComplete() QQmlContextData *context = QQmlContextData::get(qmlContext(this)); QV4::Scope scope(QQmlEnginePrivate::getV4Engine(qmlEngine(this))); - QV4::ScopedValue function(scope, QV4::QmlBindingWrapper::createQmlCallableForFunction(context, m_target, cdata->compilationUnit->runtimeFunctions[bindingId])); + QV4::ScopedValue function(scope, QV4::FunctionObject::createQmlFunction(context, m_target, cdata->compilationUnit->runtimeFunctions[bindingId])); QQmlBinding *qmlBinding = new QQmlBinding(function, m_target, context); QQmlProperty property(m_target, name, qmlContext(this)); diff --git a/tests/auto/qml/qqmllanguage/testtypes.h b/tests/auto/qml/qqmllanguage/testtypes.h index b8792a892f..985acc2539 100644 --- a/tests/auto/qml/qqmllanguage/testtypes.h +++ b/tests/auto/qml/qqmllanguage/testtypes.h @@ -1079,9 +1079,19 @@ class MyEnumDerivedClass : public MyEnum2Class Q_OBJECT }; +class MyCompositeBaseType : public QObject +{ + Q_OBJECT + Q_ENUMS(CompositeEnum) + +public: + enum CompositeEnum { EnumValue0, EnumValue42 = 42 }; +}; + Q_DECLARE_METATYPE(MyEnum2Class::EnumB) Q_DECLARE_METATYPE(MyEnum1Class::EnumA) Q_DECLARE_METATYPE(Qt::TextFormat) +Q_DECLARE_METATYPE(MyCompositeBaseType::CompositeEnum) QML_DECLARE_TYPE(MyRevisionedBaseClassRegistered) QML_DECLARE_TYPE(MyRevisionedBaseClassUnregistered) @@ -1089,6 +1099,7 @@ QML_DECLARE_TYPE(MyRevisionedClass) QML_DECLARE_TYPE(MyRevisionedSubclass) QML_DECLARE_TYPE(MySubclass) QML_DECLARE_TYPE(MyReceiversTestObject) +QML_DECLARE_TYPE(MyCompositeBaseType) class CustomBinding : public QObject, public QQmlParserStatus { diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp index 7893114500..6b6d52ca34 100644 --- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp +++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp @@ -159,6 +159,7 @@ private slots: void readonlyObjectProperties(); void receivers(); void registeredCompositeType(); + void registeredCompositeTypeWithEnum(); void implicitImportsLast(); void basicRemote_data(); @@ -3172,6 +3173,7 @@ void tst_qqmllanguage::initTestCase() qmlRegisterType(testFileUrl("CompositeType.qml"), "Test", 1, 0, "RegisteredCompositeType"); qmlRegisterType(testFileUrl("CompositeType.DoesNotExist.qml"), "Test", 1, 0, "RegisteredCompositeType2"); qmlRegisterType(testFileUrl("invalidRoot.1.qml"), "Test", 1, 0, "RegisteredCompositeType3"); + qmlRegisterType(testFileUrl("CompositeTypeWithEnum.qml"), "Test", 1, 0, "RegisteredCompositeTypeWithEnum"); // Registering the TestType class in other modules should have no adverse effects qmlRegisterType<TestType>("org.qtproject.TestPre", 1, 0, "Test"); @@ -3348,6 +3350,21 @@ void tst_qqmllanguage::registeredCompositeType() delete o; } +// QTBUG-43582 +void tst_qqmllanguage::registeredCompositeTypeWithEnum() +{ + QQmlComponent component(&engine, testFileUrl("registeredCompositeTypeWithEnum.qml")); + + VERIFY_ERRORS(0); + QObject *o = component.create(); + QVERIFY(o != 0); + + QCOMPARE(o->property("enumValue0").toInt(), static_cast<int>(MyCompositeBaseType::EnumValue0)); + QCOMPARE(o->property("enumValue42").toInt(), static_cast<int>(MyCompositeBaseType::EnumValue42)); + + delete o; +} + // QTBUG-18268 void tst_qqmllanguage::remoteLoadCrash() { diff --git a/tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp b/tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp index 5c252013ea..519ee7ac26 100644 --- a/tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp +++ b/tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp @@ -125,6 +125,7 @@ private slots: void datetime(); void datetime_data(); void about_to_be_signals(); + void modify_through_delegate(); }; bool tst_qqmllistmodel::compareVariantList(const QVariantList &testList, QVariant object) @@ -1427,6 +1428,36 @@ void tst_qqmllistmodel::about_to_be_signals() QCOMPARE(tester.rowsRemovedCount, 0); } +void tst_qqmllistmodel::modify_through_delegate() +{ + QQmlEngine engine; + QQmlComponent component(&engine); + component.setData( + "import QtQuick 2.0\n" + "Item {\n" + " ListModel {\n" + " id: testModel\n" + " objectName: \"testModel\"\n" + " ListElement { name: \"Joe\"; age: 22 }\n" + " ListElement { name: \"Doe\"; age: 33 }\n" + " }\n" + " ListView {\n" + " model: testModel\n" + " delegate: Item {\n" + " Component.onCompleted: model.age = 18;\n" + " }\n" + " }\n" + "}\n", QUrl()); + + QObject *scene = component.create(); + QQmlListModel *model = scene->findChild<QQmlListModel*>("testModel"); + + const QHash<int, QByteArray> roleNames = model->roleNames(); + + QCOMPARE(model->data(model->index(0, 0, QModelIndex()), roleNames.key("age")).toInt(), 18); + QCOMPARE(model->data(model->index(1, 0, QModelIndex()), roleNames.key("age")).toInt(), 18); +} + QTEST_MAIN(tst_qqmllistmodel) #include "tst_qqmllistmodel.moc" diff --git a/tests/auto/qml/qqmlproperty/data/floatToStringPrecision.qml b/tests/auto/qml/qqmlproperty/data/floatToStringPrecision.qml new file mode 100644 index 0000000000..a0429e0cc8 --- /dev/null +++ b/tests/auto/qml/qqmlproperty/data/floatToStringPrecision.qml @@ -0,0 +1,10 @@ +import QtQuick 2.0 + +QtObject { + property double a: 3.4 + property string b: a + + property double c: 0.035003945 + property string d: c +} + diff --git a/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp b/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp index d6b1c86b88..6ada14ce79 100644 --- a/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp +++ b/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp @@ -147,6 +147,7 @@ private slots: void registeredCompositeTypeProperty(); void deeplyNestedObject(); void readOnlyDynamicProperties(); + void floatToStringPrecision(); void copy(); private: @@ -2054,6 +2055,27 @@ void tst_qqmlproperty::readOnlyDynamicProperties() delete obj; } +void tst_qqmlproperty::floatToStringPrecision() +{ + QQmlComponent comp(&engine, testFileUrl("floatToStringPrecision.qml")); + QObject *obj = comp.create(); + QVERIFY(obj != 0); + + QCOMPARE(obj->property("a").toDouble(), 3.4); + QEXPECT_FAIL("", "QVariant's double-to-string conversion is worse than V4's.", Continue); + QCOMPARE(obj->property("a").toString(), QLatin1String("3.4")); + QCOMPARE(obj->property("b").toDouble(), 3.4); + QCOMPARE(obj->property("b").toString(), QLatin1String("3.4")); + + QCOMPARE(obj->property("c").toDouble(), 0.035003945); + QEXPECT_FAIL("", "QVariant's double-to-string conversion is worse than V4's.", Continue); + QCOMPARE(obj->property("c").toString(), QLatin1String("0.035003945")); + QCOMPARE(obj->property("d").toDouble(), 0.035003945); + QCOMPARE(obj->property("d").toString(), QLatin1String("0.035003945")); + + delete obj; +} + void tst_qqmlproperty::initTestCase() { QQmlDataTest::initTestCase(); diff --git a/tests/auto/quick/qquicklistview/data/qtbug48044.qml b/tests/auto/quick/qquicklistview/data/qtbug48044.qml new file mode 100644 index 0000000000..d318643c1c --- /dev/null +++ b/tests/auto/quick/qquicklistview/data/qtbug48044.qml @@ -0,0 +1,144 @@ +import QtQuick 2.0 + +Item { + width: 200 + height: 442 + + ListModel { + id: listModel + ListElement { + name: "h1" + txt: "Header 1" + header: true + collapsed: true + } + ListElement { + name: "h2" + txt: "Header 2" + header: true + collapsed: true + } + ListElement { + name: "h3" + txt: "Header 3" + header: true + collapsed: true + } + + function indexFromName(name) { + for (var i = 0; i < count; i++) + if (get(i).name === name) + return i + + console.warn("Did not find index for name " + name) + return -1 + } + } + + function populateModel(prefix, index, n) { + for (var k = 1; k <= n; k++) { + var name = prefix + k + var data = { + "collapsed": false, + "name": name, + "txt": name, + "header": false + } + listModel.insert(index + k, data) + } + } + + function h2(open) { + var i = listModel.indexFromName("h2") + if (listModel.get(i).collapsed === !open) + return + + listModel.setProperty(i, "collapsed", !open) + + var n = 15 + if (open) { + h3(false) + populateModel("c2_", listModel.indexFromName("h2"), n) + } else { + listModel.remove(i + 1, n) + } + + } + + function h3(open) { + var i = listModel.indexFromName("h3") + if (listModel.get(i).collapsed === !open) + return + + listModel.setProperty(i, "collapsed", !open) + + var n = 6 + if (open) { + h2(false) + populateModel("c3_", listModel.indexFromName("h3"), n) + } else { + listModel.remove(i + 1, n) + } + } + + ListView { + id: listView + width: parent.width + height: parent.height + cacheBuffer: 0 + model: listModel + + property bool transitionsDone: false + property int runningTransitions: 0 + onRunningTransitionsChanged: { + if (runningTransitions === 0) + transitionsDone = true + } + + displaced: Transition { + id: dispTrans + SequentialAnimation { + ScriptAction { + script: listView.runningTransitions++ + } + NumberAnimation { + property: "y"; + duration: 250 + } + ScriptAction { + script: listView.runningTransitions-- + } + } + } + + delegate: Rectangle { + id: rect + color: header ? "yellow" : "cyan" + border.color: "black" + height: 50 + width: parent.width + + Text { + anchors.centerIn: parent + font.pixelSize: 20 + text: txt + } + + MouseArea { + anchors.fill: parent + onClicked: { + listView.currentIndex = index + var i = listModel.indexFromName("h3") + if (i === -1) + return; + var isCollapsed = listModel.get(i).collapsed + if (name === "h2") + h2(isCollapsed) + else if (name === "h3") + h3(isCollapsed) + } + } + } + } +} + diff --git a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp index 8e7f93849c..e02c053208 100644 --- a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp +++ b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp @@ -247,6 +247,8 @@ private slots: void contentHeightWithDelayRemove(); void contentHeightWithDelayRemove_data(); + void QTBUG_48044_currentItemNotVisibleAfterTransition(); + private: template <class T> void items(const QUrl &source); template <class T> void changed(const QUrl &source); @@ -8231,6 +8233,41 @@ void tst_QQuickListView::contentHeightWithDelayRemove() delete window; } +void tst_QQuickListView::QTBUG_48044_currentItemNotVisibleAfterTransition() +{ + QQuickView *window = createView(); + window->setSource(testFileUrl("qtbug48044.qml")); + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QQuickListView *listview = window->rootObject()->findChild<QQuickListView*>(); + QTRY_VERIFY(listview != 0); + + // Expand 2nd header + listview->setProperty("transitionsDone", QVariant(false)); + QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() / 2, 75)); + QTRY_VERIFY(listview->property("transitionsDone").toBool()); + + // Flick listview to the bottom + flick(window, QPoint(window->width() / 2, 400), QPoint(window->width() / 2, 0), 100); + QTRY_VERIFY(!listview->isMoving()); + + // Expand 3rd header + listview->setProperty("transitionsDone", QVariant(false)); + QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() / 2, window->height() - 25)); + QTRY_VERIFY(listview->property("transitionsDone").toBool()); + + // Check current item is what we expect + QCOMPARE(listview->currentIndex(), 2); + QQuickItem *currentItem = listview->currentItem(); + QVERIFY(currentItem); + QVERIFY(currentItem->isVisible()); + + // This is the actual test + QQuickItemPrivate *currentPriv = QQuickItemPrivate::get(currentItem); + QVERIFY(!currentPriv->culled); +} + QTEST_MAIN(tst_QQuickListView) #include "tst_qquicklistview.moc" diff --git a/tests/auto/quick/qquicktext/data/fontSizeMode.qml b/tests/auto/quick/qquicktext/data/fontSizeMode.qml index 84f7ce8d50..48e7c7b6d0 100644 --- a/tests/auto/quick/qquicktext/data/fontSizeMode.qml +++ b/tests/auto/quick/qquicktext/data/fontSizeMode.qml @@ -13,10 +13,10 @@ Item { id: myText objectName: "myText" width: 250 - height: 41 + height: 35 minimumPointSize: 8 minimumPixelSize: 8 - font.pixelSize: 30 + font.pixelSize: 25 font.family: "Helvetica" } } diff --git a/tests/auto/quick/qquicktext/data/hAlignImplicitWidth.qml b/tests/auto/quick/qquicktext/data/hAlignImplicitWidth.qml index 9c9318d3cc..45255691fb 100644 --- a/tests/auto/quick/qquicktext/data/hAlignImplicitWidth.qml +++ b/tests/auto/quick/qquicktext/data/hAlignImplicitWidth.qml @@ -1,7 +1,7 @@ import QtQuick 2.0 Rectangle { - width: 200 + width: 220 height: 100 Text { diff --git a/tests/auto/quick/qquicktext/tst_qquicktext.cpp b/tests/auto/quick/qquicktext/tst_qquicktext.cpp index c1f10f9788..6042c08891 100644 --- a/tests/auto/quick/qquicktext/tst_qquicktext.cpp +++ b/tests/auto/quick/qquicktext/tst_qquicktext.cpp @@ -913,7 +913,7 @@ void tst_qquicktext::hAlignImplicitWidth() // Try to check whether alignment works by checking the number of black // pixels in the thirds of the grabbed image. - const int windowWidth = 200; + const int windowWidth = 220; const int textWidth = qCeil(text->implicitWidth()); QVERIFY2(textWidth < windowWidth, "System font too large."); const int sectionWidth = textWidth / 3; @@ -3756,8 +3756,8 @@ void tst_qquicktext::baselineOffset_data() << "<b>hello world</b>" << "<b>hello<br/>world</b>" << QByteArray("height: 200") - << &expectedBaselineTop - << &expectedBaselineBold; + << &expectedBaselineBold + << &expectedBaselineTop; QTest::newRow("richText") << "<b>hello world</b>" @@ -3852,8 +3852,8 @@ void tst_qquicktext::baselineOffset_data() << "<b>hello world</b>" << "<b>hello<br/>world</b>" << QByteArray("height: 200; topPadding: 10; bottomPadding: 20") - << &expectedBaselineTop - << &expectedBaselineBold; + << &expectedBaselineBold + << &expectedBaselineTop; QTest::newRow("richText with padding") << "<b>hello world</b>" diff --git a/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp b/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp index 5ec8fa2e83..eda3be5c1d 100644 --- a/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp +++ b/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp @@ -201,6 +201,7 @@ private slots: void emptytags_QTBUG_22058(); void cursorRectangle_QTBUG_38947(); void textCached_QTBUG_41583(); + void doubleSelect_QTBUG_38704(); void padding(); @@ -4044,7 +4045,7 @@ void tst_qquicktextedit::append_data() << QString("Hello") << standard.at(0) + QString("\nHello") << 18 << standard.at(0).length() + 6 << standard.at(0).length() + 6 - << false << true; + << true << true; QTest::newRow("reversed selection kept intact") << standard.at(0) << QQuickTextEdit::PlainText @@ -4126,11 +4127,8 @@ void tst_qquicktextedit::append() if (selectionStart > selectionEnd) qSwap(selectionStart, selectionEnd); - QEXPECT_FAIL("into selection", "selectedTextChanged signal isn't emitted on edits within selection", Continue); - QEXPECT_FAIL("into reversed selection", "selectedTextChanged signal isn't emitted on edits within selection", Continue); QCOMPARE(selectionSpy.count() > 0, selectionChanged); QCOMPARE(selectionStartSpy.count() > 0, selectionStart != expectedSelectionStart); - QEXPECT_FAIL("into reversed selection", "selectionEndChanged signal not emitted", Continue); QCOMPARE(selectionEndSpy.count() > 0, selectionEnd != expectedSelectionEnd); QCOMPARE(textSpy.count() > 0, text != expectedText); QCOMPARE(cursorPositionSpy.count() > 0, cursorPositionChanged); @@ -4213,7 +4211,7 @@ void tst_qquicktextedit::insert_data() << QString("Hello") << QString("Hello") + standard.at(0) << 19 << 24 << 24 - << false << true; + << true << true; QTest::newRow("before reversed selection") << standard.at(0) << QQuickTextEdit::PlainText @@ -4221,7 +4219,7 @@ void tst_qquicktextedit::insert_data() << QString("Hello") << QString("Hello") + standard.at(0) << 19 << 24 << 19 - << false << true; + << true << true; QTest::newRow("after selection") << standard.at(0) << QQuickTextEdit::PlainText @@ -4344,11 +4342,8 @@ void tst_qquicktextedit::insert() if (selectionStart > selectionEnd) qSwap(selectionStart, selectionEnd); - QEXPECT_FAIL("into selection", "selectedTextChanged signal isn't emitted on edits within selection", Continue); - QEXPECT_FAIL("into reversed selection", "selectedTextChanged signal isn't emitted on edits within selection", Continue); QCOMPARE(selectionSpy.count() > 0, selectionChanged); QCOMPARE(selectionStartSpy.count() > 0, selectionStart != expectedSelectionStart); - QEXPECT_FAIL("into reversed selection", "selectionEndChanged signal not emitted", Continue); QCOMPARE(selectionEndSpy.count() > 0, selectionEnd != expectedSelectionEnd); QCOMPARE(textSpy.count() > 0, text != expectedText); QCOMPARE(cursorPositionSpy.count() > 0, cursorPositionChanged); @@ -4458,7 +4453,7 @@ void tst_qquicktextedit::remove_data() << 0 << 5 << standard.at(0).mid(5) << 9 << 14 << 14 - << false << true; + << true << true; QTest::newRow("before reversed selection") << standard.at(0) << QQuickTextEdit::PlainText @@ -4466,7 +4461,7 @@ void tst_qquicktextedit::remove_data() << 0 << 5 << standard.at(0).mid(5) << 9 << 14 << 9 - << false << true; + << true << true; QTest::newRow("after selection") << standard.at(0) << QQuickTextEdit::PlainText @@ -4588,11 +4583,8 @@ void tst_qquicktextedit::remove() QCOMPARE(textEdit->selectionEnd(), expectedSelectionEnd); QCOMPARE(textEdit->cursorPosition(), expectedCursorPosition); - QEXPECT_FAIL("from selection", "selectedTextChanged signal isn't emitted on edits within selection", Continue); - QEXPECT_FAIL("from reversed selection", "selectedTextChanged signal isn't emitted on edits within selection", Continue); QCOMPARE(selectionSpy.count() > 0, selectionChanged); QCOMPARE(selectionStartSpy.count() > 0, selectionStart != expectedSelectionStart); - QEXPECT_FAIL("from reversed selection", "selectionEndChanged signal not emitted", Continue); QCOMPARE(selectionEndSpy.count() > 0, selectionEnd != expectedSelectionEnd); QCOMPARE(textSpy.count() > 0, text != expectedText); @@ -5374,6 +5366,26 @@ void tst_qquicktextedit::textCached_QTBUG_41583() QVERIFY(!textedit->property("empty").toBool()); } +void tst_qquicktextedit::doubleSelect_QTBUG_38704() +{ + QString componentStr = "import QtQuick 2.2\nTextEdit { text: \"TextEdit\" }"; + QQmlComponent textEditComponent(&engine); + textEditComponent.setData(componentStr.toLatin1(), QUrl()); + QQuickTextEdit *textEdit = qobject_cast<QQuickTextEdit*>(textEditComponent.create()); + QVERIFY(textEdit != 0); + + QSignalSpy selectionSpy(textEdit, SIGNAL(selectedTextChanged())); + + textEdit->select(0,1); //Select some text initially + QCOMPARE(selectionSpy.count(), 1); + textEdit->select(0,1); //No change to selection start/end + QCOMPARE(selectionSpy.count(), 1); + textEdit->select(0,2); //Change selection end + QCOMPARE(selectionSpy.count(), 2); + textEdit->select(1,2); //Change selection start + QCOMPARE(selectionSpy.count(), 3); +} + void tst_qquicktextedit::padding() { QScopedPointer<QQuickView> window(new QQuickView); diff --git a/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp b/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp index 079f73ae34..85123c6f92 100644 --- a/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp +++ b/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp @@ -3092,14 +3092,16 @@ void tst_qquicktextinput::cursorRectangle() } else { QCOMPARE(r.left(), input.width()); } - QVERIFY(r.top() >= line.height() - 1); + // we can't be exact here, as the space character can have a different ascent/descent from the arabic chars + // this then leads to different line heights between the wrapped and non wrapped texts + QVERIFY(r.top() >= line.height() - 5); COMPARE_INPUT_METHOD_QUERY(QRectF, (&input), Qt::ImCursorRectangle, toRectF, r); QCOMPARE(input.positionToRectangle(11), r); for (int i = wrapPosition + 1; i < text.length(); ++i) { input.setCursorPosition(i); r = input.cursorRectangle(); - QVERIFY(r.top() >= line.height() - 1); + QVERIFY(r.top() >= line.height() - 5); COMPARE_INPUT_METHOD_QUERY(QRectF, (&input), Qt::ImCursorRectangle, toRectF, r); QCOMPARE(input.positionToRectangle(i), r); } diff --git a/tests/auto/shared/testhttpserver.cpp b/tests/auto/shared/testhttpserver.cpp index 7235246fc0..6c466293b6 100644 --- a/tests/auto/shared/testhttpserver.cpp +++ b/tests/auto/shared/testhttpserver.cpp @@ -81,15 +81,14 @@ The following request urls will then result in the appropriate action: \endtable */ TestHTTPServer::TestHTTPServer() -: m_state(AwaitingHeader) + : m_state(AwaitingHeader) { - QObject::connect(&server, SIGNAL(newConnection()), this, SLOT(newConnection())); - + QObject::connect(&m_server, &QTcpServer::newConnection, this, &TestHTTPServer::newConnection); } bool TestHTTPServer::listen() { - return server.listen(QHostAddress::LocalHost, 0); + return m_server.listen(QHostAddress::LocalHost, 0); } QUrl TestHTTPServer::baseUrl() const @@ -97,7 +96,7 @@ QUrl TestHTTPServer::baseUrl() const QUrl url; url.setScheme(QStringLiteral("http")); url.setHost(QStringLiteral("127.0.0.1")); - url.setPort(server.serverPort()); + url.setPort(m_server.serverPort()); return url; } @@ -113,12 +112,12 @@ QString TestHTTPServer::urlString(const QString &documentPath) const QString TestHTTPServer::errorString() const { - return server.errorString(); + return m_server.errorString(); } bool TestHTTPServer::serveDirectory(const QString &dir, Mode mode) { - dirs.append(qMakePair(dir, mode)); + m_directories.append(qMakePair(dir, mode)); return true; } @@ -128,17 +127,17 @@ bool TestHTTPServer::serveDirectory(const QString &dir, Mode mode) */ void TestHTTPServer::addAlias(const QString &filename, const QString &alias) { - aliases.insert(filename, alias); + m_aliases.insert(filename, alias); } void TestHTTPServer::addRedirect(const QString &filename, const QString &redirectName) { - redirects.insert(filename, redirectName); + m_redirects.insert(filename, redirectName); } void TestHTTPServer::registerFileNameForContentSubstitution(const QString &fileName) { - contentSubstitutedFileNames.insert(fileName); + m_contentSubstitutedFileNames.insert(fileName); } bool TestHTTPServer::wait(const QUrl &expect, const QUrl &reply, const QUrl &body) @@ -147,19 +146,23 @@ bool TestHTTPServer::wait(const QUrl &expect, const QUrl &reply, const QUrl &bod m_data.clear(); QFile expectFile(expect.toLocalFile()); - if (!expectFile.open(QIODevice::ReadOnly)) return false; + if (!expectFile.open(QIODevice::ReadOnly)) + return false; QFile replyFile(reply.toLocalFile()); - if (!replyFile.open(QIODevice::ReadOnly)) return false; + if (!replyFile.open(QIODevice::ReadOnly)) + return false; - bodyData = QByteArray(); + m_bodyData = QByteArray(); if (body.isValid()) { QFile bodyFile(body.toLocalFile()); - if (!bodyFile.open(QIODevice::ReadOnly)) return false; - bodyData = bodyFile.readAll(); + if (!bodyFile.open(QIODevice::ReadOnly)) + return false; + m_bodyData = bodyFile.readAll(); } - const QByteArray serverHostUrl = QByteArrayLiteral("127.0.0.1:") + QByteArray::number(server.serverPort()); + const QByteArray serverHostUrl + = QByteArrayLiteral("127.0.0.1:")+ QByteArray::number(m_server.serverPort()); QByteArray line; bool headers_done = false; @@ -170,10 +173,10 @@ bool TestHTTPServer::wait(const QUrl &expect, const QUrl &reply, const QUrl &bod continue; } if (headers_done) { - waitData.body.append(line); + m_waitData.body.append(line); } else { line.replace("{{ServerHostUrl}}", serverHostUrl); - waitData.headers.append(line); + m_waitData.headers.append(line); } } /* @@ -181,20 +184,21 @@ bool TestHTTPServer::wait(const QUrl &expect, const QUrl &reply, const QUrl &bod waitData = waitData.left(waitData.count() - 1); */ - replyData = replyFile.readAll(); + m_replyData = replyFile.readAll(); - if (!replyData.endsWith('\n')) - replyData.append("\n"); - replyData.append("Content-length: " + QByteArray::number(bodyData.length())); - replyData .append("\n\n"); + if (!m_replyData.endsWith('\n')) + m_replyData.append('\n'); + m_replyData.append("Content-length: "); + m_replyData.append(QByteArray::number(m_bodyData.length())); + m_replyData.append("\n\n"); - for (int ii = 0; ii < replyData.count(); ++ii) { - if (replyData.at(ii) == '\n' && (!ii || replyData.at(ii - 1) != '\r')) { - replyData.insert(ii, '\r'); + for (int ii = 0; ii < m_replyData.count(); ++ii) { + if (m_replyData.at(ii) == '\n' && (!ii || m_replyData.at(ii - 1) != '\r')) { + m_replyData.insert(ii, '\r'); ++ii; } } - replyData.append(bodyData); + m_replyData.append(m_bodyData); return true; } @@ -206,25 +210,27 @@ bool TestHTTPServer::hasFailed() const void TestHTTPServer::newConnection() { - QTcpSocket *socket = server.nextPendingConnection(); - if (!socket) return; + QTcpSocket *socket = m_server.nextPendingConnection(); + if (!socket) + return; - if (!dirs.isEmpty()) - dataCache.insert(socket, QByteArray()); + if (!m_directories.isEmpty()) + m_dataCache.insert(socket, QByteArray()); - QObject::connect(socket, SIGNAL(disconnected()), this, SLOT(disconnected())); - QObject::connect(socket, SIGNAL(readyRead()), this, SLOT(readyRead())); + QObject::connect(socket, &QAbstractSocket::disconnected, this, &TestHTTPServer::disconnected); + QObject::connect(socket, &QIODevice::readyRead, this, &TestHTTPServer::readyRead); } void TestHTTPServer::disconnected() { QTcpSocket *socket = qobject_cast<QTcpSocket *>(sender()); - if (!socket) return; + if (!socket) + return; - dataCache.remove(socket); - for (int ii = 0; ii < toSend.count(); ++ii) { - if (toSend.at(ii).first == socket) { - toSend.removeAt(ii); + m_dataCache.remove(socket); + for (int ii = 0; ii < m_toSend.count(); ++ii) { + if (m_toSend.at(ii).first == socket) { + m_toSend.removeAt(ii); --ii; } } @@ -235,14 +241,15 @@ void TestHTTPServer::disconnected() void TestHTTPServer::readyRead() { QTcpSocket *socket = qobject_cast<QTcpSocket *>(sender()); - if (!socket || socket->state() == QTcpSocket::ClosingState) return; + if (!socket || socket->state() == QTcpSocket::ClosingState) + return; - if (!dirs.isEmpty()) { + if (!m_directories.isEmpty()) { serveGET(socket, socket->readAll()); return; } - if (m_state == Failed || (waitData.body.isEmpty() && waitData.headers.count() == 0)) { + if (m_state == Failed || (m_waitData.body.isEmpty() && m_waitData.headers.count() == 0)) { qWarning() << "TestHTTPServer: Unexpected data" << socket->readAll(); return; } @@ -256,8 +263,9 @@ void TestHTTPServer::readyRead() m_data += socket->readAll(); break; } else { - if (!waitData.headers.contains(line)) { - qWarning() << "TestHTTPServer: Unexpected header:" << line << "\nExpected headers: " << waitData.headers; + if (!m_waitData.headers.contains(line)) { + qWarning() << "TestHTTPServer: Unexpected header:" << line + << "\nExpected headers: " << m_waitData.headers; m_state = Failed; socket->disconnectFromHost(); return; @@ -268,34 +276,38 @@ void TestHTTPServer::readyRead() m_data += socket->readAll(); } - if (!m_data.isEmpty() || waitData.body.isEmpty()) { - if (waitData.body != m_data) { - qWarning() << "TestHTTPServer: Unexpected data" << m_data << "\nExpected: " << waitData.body; + if (!m_data.isEmpty() || m_waitData.body.isEmpty()) { + if (m_waitData.body != m_data) { + qWarning() << "TestHTTPServer: Unexpected data" << m_data << "\nExpected: " << m_waitData.body; m_state = Failed; } else { - socket->write(replyData); + socket->write(m_replyData); } socket->disconnectFromHost(); } } -bool TestHTTPServer::reply(QTcpSocket *socket, const QByteArray &fileName) +bool TestHTTPServer::reply(QTcpSocket *socket, const QByteArray &fileNameIn) { - if (redirects.contains(fileName)) { - QByteArray response = "HTTP/1.1 302 Found\r\nContent-length: 0\r\nContent-type: text/html; charset=UTF-8\r\nLocation: " + redirects[fileName].toUtf8() + "\r\n\r\n"; + const QString fileName = QLatin1String(fileNameIn); + if (m_redirects.contains(fileName)) { + const QByteArray response + = "HTTP/1.1 302 Found\r\nContent-length: 0\r\nContent-type: text/html; charset=UTF-8\r\nLocation: " + + m_redirects.value(fileName).toUtf8() + "\r\n\r\n"; socket->write(response); return true; } - for (int ii = 0; ii < dirs.count(); ++ii) { - QString dir = dirs.at(ii).first; - Mode mode = dirs.at(ii).second; + for (int ii = 0; ii < m_directories.count(); ++ii) { + const QString &dir = m_directories.at(ii).first; + const Mode mode = m_directories.at(ii).second; - QString dirFile = dir + QLatin1String("/") + QLatin1String(fileName); + QString dirFile = dir + QLatin1Char('/') + fileName; if (!QFile::exists(dirFile)) { - if (aliases.contains(fileName)) - dirFile = dir + QLatin1String("/") + aliases.value(fileName); + const QHash<QString, QString>::const_iterator it = m_aliases.constFind(fileName); + if (it != m_aliases.constEnd()) + dirFile = dir + QLatin1Char('/') + it.value(); } QFile file(dirFile); @@ -305,18 +317,18 @@ bool TestHTTPServer::reply(QTcpSocket *socket, const QByteArray &fileName) return true; QByteArray data = file.readAll(); - if (contentSubstitutedFileNames.contains("/" + fileName)) { + if (m_contentSubstitutedFileNames.contains(QLatin1Char('/') + fileName)) data.replace(QByteArrayLiteral("{{ServerBaseUrl}}"), baseUrl().toString().toUtf8()); - } - QByteArray response = "HTTP/1.0 200 OK\r\nContent-type: text/html; charset=UTF-8\r\nContent-length: "; + QByteArray response + = "HTTP/1.0 200 OK\r\nContent-type: text/html; charset=UTF-8\r\nContent-length: "; response += QByteArray::number(data.count()); response += "\r\n\r\n"; response += data; if (mode == Delay) { - toSend.append(qMakePair(socket, response)); - QTimer::singleShot(500, this, SLOT(sendOne())); + m_toSend.append(qMakePair(socket, response)); + QTimer::singleShot(500, this, &TestHTTPServer::sendOne); return false; } else { socket->write(response); @@ -325,9 +337,7 @@ bool TestHTTPServer::reply(QTcpSocket *socket, const QByteArray &fileName) } } - - QByteArray response = "HTTP/1.0 404 Not found\r\nContent-type: text/html; charset=UTF-8\r\n\r\n"; - socket->write(response); + socket->write("HTTP/1.0 404 Not found\r\nContent-type: text/html; charset=UTF-8\r\n\r\n"); return true; } @@ -339,39 +349,31 @@ void TestHTTPServer::sendDelayedItem() void TestHTTPServer::sendOne() { - if (!toSend.isEmpty()) { - toSend.first().first->write(toSend.first().second); - toSend.first().first->close(); - toSend.removeFirst(); + if (!m_toSend.isEmpty()) { + m_toSend.first().first->write(m_toSend.first().second); + m_toSend.first().first->close(); + m_toSend.removeFirst(); } } void TestHTTPServer::serveGET(QTcpSocket *socket, const QByteArray &data) { - if (!dataCache.contains(socket)) + const QHash<QTcpSocket *, QByteArray>::iterator it = m_dataCache.find(socket); + if (it == m_dataCache.end()) return; - QByteArray total = dataCache[socket] + data; - dataCache[socket] = total; + QByteArray &total = it.value(); + total.append(data); if (total.contains("\n\r\n")) { - bool close = true; - if (total.startsWith("GET /")) { - - int space = total.indexOf(' ', 4); - if (space != -1) { - - QByteArray req = total.mid(5, space - 5); - close = reply(socket, req); - - } + const int space = total.indexOf(' ', 4); + if (space != -1) + close = reply(socket, total.mid(5, space - 5)); } - dataCache.remove(socket); - + m_dataCache.erase(it); if (close) socket->disconnectFromHost(); } } - diff --git a/tests/auto/shared/testhttpserver.h b/tests/auto/shared/testhttpserver.h index 0c0e799d8e..0fc8e4a79c 100644 --- a/tests/auto/shared/testhttpserver.h +++ b/tests/auto/shared/testhttpserver.h @@ -34,7 +34,6 @@ #ifndef TESTHTTPSERVER_H #define TESTHTTPSERVER_H -#include <QObject> #include <QTcpServer> #include <QUrl> #include <QPair> @@ -81,24 +80,24 @@ private: void serveGET(QTcpSocket *, const QByteArray &); bool reply(QTcpSocket *, const QByteArray &); - QList<QPair<QString, Mode> > dirs; - QHash<QTcpSocket *, QByteArray> dataCache; - QList<QPair<QTcpSocket *, QByteArray> > toSend; - QSet<QString> contentSubstitutedFileNames; + QList<QPair<QString, Mode> > m_directories; + QHash<QTcpSocket *, QByteArray> m_dataCache; + QList<QPair<QTcpSocket *, QByteArray> > m_toSend; + QSet<QString> m_contentSubstitutedFileNames; struct WaitData { QList <QByteArray>headers; QByteArray body; - } waitData; - QByteArray replyData; - QByteArray bodyData; + } m_waitData; + QByteArray m_replyData; + QByteArray m_bodyData; QByteArray m_data; State m_state; - QHash<QString,QString> aliases; - QHash<QString,QString> redirects; + QHash<QString, QString> m_aliases; + QHash<QString, QString> m_redirects; - QTcpServer server; + QTcpServer m_server; }; #endif // TESTHTTPSERVER_H diff --git a/tests/manual/v4/crypto.js b/tests/manual/v4/crypto.js index cd48bdb019..7c24b08439 100644 --- a/tests/manual/v4/crypto.js +++ b/tests/manual/v4/crypto.js @@ -1710,3 +1710,4 @@ if (typeof(print) === "undefined") print = console.log; print("done in", new Date - d1) +gc() diff --git a/tests/manual/v4/typedarrays.js b/tests/manual/v4/typedarrays.js index d52fd6bab0..8cf2b8c75a 100644 --- a/tests/manual/v4/typedarrays.js +++ b/tests/manual/v4/typedarrays.js @@ -51,11 +51,13 @@ function assertTrue(b) { throw "assertTrue failed:" + b } -function assertEquals(a, b) { +function assertEquals(a, b, delta) { if (isNaN(a) && isNaN(b)) return - if (a !== b) + if (!delta && a !== b) throw "assertEquals failed:" + a + "!==" + b + else if (Math.abs(a - b) > delta) + throw "assertEquals failed: Math.abs(" + a + " - " + b + ") > " + delta } function assertArrayEquals(a, b) @@ -700,9 +702,36 @@ function TestDataViewPropertyTypeChecks() { CheckProperty("byteLength"); } - TestDataViewPropertyTypeChecks(); +function TestDataGetterSetters() { + var a = new DataView(new ArrayBuffer(16)); + function TestGetterSetter(size, name, value0, value1, delta1, delta2) { + var getter = 'get' + name; + var setter = 'set' + name; + a[setter](0, value0); + a[setter](size, value1); + assertEquals(value0, a[getter](0), delta1); + assertEquals(value1, a[getter](size), delta2); + } + + TestGetterSetter(1, 'Int8', 111, -100); + TestGetterSetter(2, 'Int16', 31111, -30000); + TestGetterSetter(4, 'Int32', 2111111111, -2000000000); + TestGetterSetter(1, 'Uint8', 111, 200); + TestGetterSetter(2, 'Uint16', 31111, 60000); + TestGetterSetter(4, 'Uint32', 2111111111, 4000000000); + TestGetterSetter(4, 'Float32', Math.pow(10, 38), Math.pow(10, -38), Math.pow(10, 31), Math.pow(10, -45)); + TestGetterSetter(8, 'Float64', Math.pow(10, 308), Math.pow(10, -293), Math.pow(10, 293), Math.pow(10, -308)); + + // Backword compatibility + TestGetterSetter(1, 'UInt8', 111, 200); + TestGetterSetter(2, 'UInt16', 31111, 60000); + TestGetterSetter(4, 'UInt32', 2111111111, 4000000000); +} + +TestDataGetterSetters(); + // General tests for properties // Test property attribute [[Enumerable]] |