aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto
diff options
context:
space:
mode:
authorFrederik Gladhorn <frederik.gladhorn@digia.com>2013-12-16 17:05:21 +0100
committerFrederik Gladhorn <frederik.gladhorn@digia.com>2013-12-16 17:05:21 +0100
commit13e88fe2b9b1680cb161a249289c3ba998f08c0c (patch)
tree496a9d88c69b441e8c88aa0416b327faca3a1532 /tests/auto
parenta2dad3ddee9c4bf274a7c6469342e4104605ceeb (diff)
parent470ba767663e4ad9d3183fb56ee89361354dfefb (diff)
Merge remote-tracking branch 'origin/stable' into dev
Conflicts: src/quick/items/qquickitem.cpp src/quick/items/qquicktext.cpp tests/auto/quick/qquicklistview/tst_qquicklistview.cpp Change-Id: I0bc5786098193c2c40b6fd8905de75d90f6ed0cf
Diffstat (limited to 'tests/auto')
-rw-r--r--tests/auto/particles/qquicktrailemitter/tst_qquicktrailemitter.cpp2
-rw-r--r--tests/auto/qml/qjsengine/tst_qjsengine.cpp8
-rw-r--r--tests/auto/qml/qqmlecmascript/data/misctypetest.qml4
-rw-r--r--tests/auto/qml/qqmlecmascript/data/noCaptureWhenWritingProperty.qml14
-rw-r--r--tests/auto/qml/qqmlecmascript/data/sequenceConversion.array.qml16
-rw-r--r--tests/auto/qml/qqmlecmascript/testtypes.cpp2
-rw-r--r--tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp15
-rw-r--r--tests/auto/qml/qqmlengine/tst_qqmlengine.cpp2
-rw-r--r--tests/auto/qml/qqmllanguage/data/customParserBindingScopes.qml19
-rw-r--r--tests/auto/qml/qqmllanguage/testtypes.cpp60
-rw-r--r--tests/auto/qml/qqmllanguage/testtypes.h23
-rw-r--r--tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp13
-rw-r--r--tests/auto/qml/qqmlpropertymap/tst_qqmlpropertymap.cpp81
-rw-r--r--tests/auto/qml/qqmltranslation/data/jstranslation.qml20
-rw-r--r--tests/auto/qml/qqmltranslation/data/translation.js98
-rw-r--r--tests/auto/qml/qqmltranslation/tst_qqmltranslation.cpp47
-rw-r--r--tests/auto/quick/qquickapplication/tst_qquickapplication.cpp1
-rw-r--r--tests/auto/quick/qquickflickable/data/stopAtBounds.qml22
-rw-r--r--tests/auto/quick/qquickflickable/qquickflickable.pro1
-rw-r--r--tests/auto/quick/qquickflickable/tst_qquickflickable.cpp110
-rw-r--r--tests/auto/quick/qquickitem/tst_qquickitem.cpp15
-rw-r--r--tests/auto/quick/qquicklistview/data/HighlightResize.qml23
-rw-r--r--tests/auto/quick/qquicklistview/data/listview-sections.qml25
-rw-r--r--tests/auto/quick/qquicklistview/tst_qquicklistview.cpp23
-rw-r--r--tests/auto/quick/qquickloader/data/SimpleTestComponent.qml2
-rw-r--r--tests/auto/quick/qquickloader/data/sourceComponentGarbageCollection.qml8
-rw-r--r--tests/auto/quick/qquickloader/tst_qquickloader.cpp22
-rw-r--r--tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp52
-rw-r--r--tests/auto/quick/qquickwindow/data/focus.qml4
-rw-r--r--tests/auto/quick/qquickwindow/tst_qquickwindow.cpp35
-rw-r--r--tests/auto/quick/scenegraph/data/simple.qml60
-rw-r--r--tests/auto/quick/scenegraph/scenegraph.pro3
-rw-r--r--tests/auto/quick/scenegraph/tst_scenegraph.cpp36
-rw-r--r--tests/auto/quick/touchmouse/tst_touchmouse.cpp100
34 files changed, 904 insertions, 62 deletions
diff --git a/tests/auto/particles/qquicktrailemitter/tst_qquicktrailemitter.cpp b/tests/auto/particles/qquicktrailemitter/tst_qquicktrailemitter.cpp
index 98209e218c..43600e226e 100644
--- a/tests/auto/particles/qquicktrailemitter/tst_qquicktrailemitter.cpp
+++ b/tests/auto/particles/qquicktrailemitter/tst_qquicktrailemitter.cpp
@@ -86,7 +86,7 @@ void tst_qquicktrailemitter::test_basic()
QVERIFY(myFuzzyLEQ(d->t, ((qreal)system->timeInt/1000.0)));
}
- QCOMPARE(system->groupData[1]->size(), 500);
+ QVERIFY(extremelyFuzzyCompare(system->groupData[1]->size(), 500, 10));
foreach (QQuickParticleData *d, system->groupData[1]->data) {
if (d->t == -1)
continue; //Particle data unused
diff --git a/tests/auto/qml/qjsengine/tst_qjsengine.cpp b/tests/auto/qml/qjsengine/tst_qjsengine.cpp
index 39086d75ac..726f8636b6 100644
--- a/tests/auto/qml/qjsengine/tst_qjsengine.cpp
+++ b/tests/auto/qml/qjsengine/tst_qjsengine.cpp
@@ -134,6 +134,7 @@ private slots:
void reentrancy_Array();
void reentrancy_objectCreation();
void jsIncDecNonObjectProperty();
+ void JSONparse();
void qRegExpInport_data();
void qRegExpInport();
@@ -2500,6 +2501,13 @@ void tst_QJSEngine::jsIncDecNonObjectProperty()
}
}
+void tst_QJSEngine::JSONparse()
+{
+ QJSEngine eng;
+ QJSValue ret = eng.evaluate("var json=\"{\\\"1\\\": null}\"; JSON.parse(json);");
+ QVERIFY(ret.isObject());
+}
+
static QRegExp minimal(QRegExp r) { r.setMinimal(true); return r; }
void tst_QJSEngine::qRegExpInport_data()
diff --git a/tests/auto/qml/qqmlecmascript/data/misctypetest.qml b/tests/auto/qml/qqmlecmascript/data/misctypetest.qml
index 60ff53a2b4..088ede67ec 100644
--- a/tests/auto/qml/qqmlecmascript/data/misctypetest.qml
+++ b/tests/auto/qml/qqmlecmascript/data/misctypetest.qml
@@ -11,7 +11,7 @@ Item {
return mtt.invalidUrl() == mtt.invalidUrl();
}
- function test_invalid_url_refequal()
+ function test_invalid_url_strictequal()
{
return mtt.invalidUrl() === mtt.invalidUrl();
}
@@ -21,7 +21,7 @@ Item {
return mtt.validUrl() == mtt.validUrl();
}
- function test_valid_url_refequal()
+ function test_valid_url_strictequal()
{
return mtt.validUrl() === mtt.validUrl();
}
diff --git a/tests/auto/qml/qqmlecmascript/data/noCaptureWhenWritingProperty.qml b/tests/auto/qml/qqmlecmascript/data/noCaptureWhenWritingProperty.qml
new file mode 100644
index 0000000000..8b8601692d
--- /dev/null
+++ b/tests/auto/qml/qqmlecmascript/data/noCaptureWhenWritingProperty.qml
@@ -0,0 +1,14 @@
+import QtQml 2.0
+QtObject {
+ property bool somePropertyEvaluated: false;
+
+ property int someProperty: {
+ // It's sort of evil to set the property here, but that doesn't mean that
+ // this expression should get re-evaluated when unrelatedProperty changes later.
+ somePropertyEvaluated = true
+ return 20;
+ }
+ Component.onCompleted: {
+ somePropertyEvaluated = false
+ }
+}
diff --git a/tests/auto/qml/qqmlecmascript/data/sequenceConversion.array.qml b/tests/auto/qml/qqmlecmascript/data/sequenceConversion.array.qml
index 52abda1e55..8d08cc5559 100644
--- a/tests/auto/qml/qqmlecmascript/data/sequenceConversion.array.qml
+++ b/tests/auto/qml/qqmlecmascript/data/sequenceConversion.array.qml
@@ -140,6 +140,22 @@ Item {
if (msco.intListProperty.toString() != expected.toString()) success = false;
expected = 7;
if (poppedVal != expected) success = false;
+
+ // concat
+ msco.stringListProperty = [ "one", "two" ]
+ stringList = [ "hello", "world" ]
+ stringList = stringList.concat(msco.stringListProperty)
+ expected = [ "hello", "world", "one", "two" ]
+ if (stringList.length != expected.length) {
+ success = false;
+ } else {
+ for (var i = 0; i < stringList.length; ++i) {
+ if (stringList[i] != expected[i]) {
+ success = false;
+ break;
+ }
+ }
+ }
}
property variant variantList: [ 1, 2, 3, 4, 5 ];
diff --git a/tests/auto/qml/qqmlecmascript/testtypes.cpp b/tests/auto/qml/qqmlecmascript/testtypes.cpp
index 41fa3672bd..22fac2013e 100644
--- a/tests/auto/qml/qqmlecmascript/testtypes.cpp
+++ b/tests/auto/qml/qqmlecmascript/testtypes.cpp
@@ -106,7 +106,7 @@ public:
void MyQmlObject::v8function(QQmlV4Function *function)
{
- QV8Engine::getV4(function->engine())->current->throwError(QStringLiteral("Exception thrown from within QObject slot"));
+ QV8Engine::getV4(function->engine())->currentContext()->throwError(QStringLiteral("Exception thrown from within QObject slot"));
}
static QJSValue script_api(QQmlEngine *engine, QJSEngine *scriptEngine)
diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
index 660be13f71..7b89709923 100644
--- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
+++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
@@ -319,6 +319,7 @@ private slots:
void stackLimits();
void idsAsLValues();
void qtbug_34792();
+ void noCaptureWhenWritingProperty();
private:
// static void propertyVarWeakRefCallback(v8::Persistent<v8::Value> object, void* parameter);
@@ -2267,7 +2268,7 @@ static inline bool evaluate_error(QV8Engine *engine, const QV4::ValueRef o, cons
QV4::Script program(QV8Engine::getV4(engine)->rootContext, functionSource);
program.inheritContext = true;
- QV4::ExecutionContext *ctx = QV8Engine::getV4(engine)->current;
+ QV4::ExecutionContext *ctx = QV8Engine::getV4(engine)->currentContext();
QV4::Scope scope(ctx);
QV4::Scoped<QV4::FunctionObject> function(scope, program.run());
@@ -2295,7 +2296,7 @@ static inline bool evaluate_value(QV8Engine *engine, const QV4::ValueRef o,
QV4::Script program(QV8Engine::getV4(engine)->rootContext, functionSource);
program.inheritContext = true;
- QV4::ExecutionContext *ctx = QV8Engine::getV4(engine)->current;
+ QV4::ExecutionContext *ctx = QV8Engine::getV4(engine)->currentContext();
QV4::Scope scope(ctx);
QV4::Scoped<QV4::FunctionObject> function(scope, program.run());
@@ -2324,7 +2325,7 @@ static inline QV4::ReturnedValue evaluate(QV8Engine *engine, const QV4::ValueRef
QString functionSource = QLatin1String("(function(object) { return ") +
QLatin1String(source) + QLatin1String(" })");
- QV4::ExecutionContext *ctx = QV8Engine::getV4(engine)->current;
+ QV4::ExecutionContext *ctx = QV8Engine::getV4(engine)->currentContext();
QV4::Scope scope(ctx);
QV4::Script program(QV8Engine::getV4(engine)->rootContext, functionSource);
@@ -7498,6 +7499,14 @@ void tst_qqmlecmascript::qtbug_34792()
delete object;
}
+void tst_qqmlecmascript::noCaptureWhenWritingProperty()
+{
+ QQmlComponent component(&engine, testFileUrl("noCaptureWhenWritingProperty.qml"));
+ QScopedPointer<QObject> obj(component.create());
+ QVERIFY(!obj.isNull());
+ QCOMPARE(obj->property("somePropertyEvaluated").toBool(), false);
+}
+
QTEST_MAIN(tst_qqmlecmascript)
#include "tst_qqmlecmascript.moc"
diff --git a/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp b/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp
index 382bfe4b73..004514d39c 100644
--- a/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp
+++ b/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp
@@ -54,7 +54,7 @@
#include <QQmlExpression>
#include <QQmlIncubationController>
#include <private/qqmlengine_p.h>
-#include <private/qqmlabstracturlinterceptor_p.h>
+#include <QQmlAbstractUrlInterceptor>
class tst_qqmlengine : public QQmlDataTest
{
diff --git a/tests/auto/qml/qqmllanguage/data/customParserBindingScopes.qml b/tests/auto/qml/qqmllanguage/data/customParserBindingScopes.qml
new file mode 100644
index 0000000000..2efc199f32
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/customParserBindingScopes.qml
@@ -0,0 +1,19 @@
+import Test 1.0
+import QtQml 2.0
+QtObject {
+ id: root
+
+ property int otherProperty: 10
+
+ property QtObject child: QtObject {
+ id: child
+
+ property int testProperty;
+ property int otherProperty: 41
+
+ property QtObject customBinder: CustomBinding {
+ target: child
+ testProperty: otherProperty + 1
+ }
+ }
+}
diff --git a/tests/auto/qml/qqmllanguage/testtypes.cpp b/tests/auto/qml/qqmllanguage/testtypes.cpp
index 3957f9d872..4a4ab3b81a 100644
--- a/tests/auto/qml/qqmllanguage/testtypes.cpp
+++ b/tests/auto/qml/qqmllanguage/testtypes.cpp
@@ -89,6 +89,8 @@ void registerTypes()
qmlRegisterUncreatableType<MyUncreateableBaseClass,1>("Test", 1, 1, "MyUncreateableBaseClass", "Cannot create MyUncreateableBaseClass");
qmlRegisterType<MyCreateableDerivedClass,1>("Test", 1, 1, "MyCreateableDerivedClass");
+
+ qmlRegisterCustomType<CustomBinding>("Test", 1, 0, "CustomBinding", new CustomBindingParser);
}
QVariant myCustomVariantTypeConverter(const QString &data)
@@ -97,3 +99,61 @@ QVariant myCustomVariantTypeConverter(const QString &data)
rv.a = data.toInt();
return QVariant::fromValue(rv);
}
+
+
+QByteArray CustomBindingParser::compile(const QList<QQmlCustomParserProperty> &properties)
+{
+ QByteArray result;
+ QDataStream ds(&result, QIODevice::WriteOnly);
+
+ ds << properties.count();
+ for (int i = 0; i < properties.count(); ++i) {
+ const QQmlCustomParserProperty &prop = properties.at(i);
+ ds << prop.name();
+
+ Q_ASSERT(prop.assignedValues().count() == 1);
+ QVariant value = prop.assignedValues().first();
+
+ Q_ASSERT(value.userType() == qMetaTypeId<QQmlScript::Variant>());
+ QQmlScript::Variant v = qvariant_cast<QQmlScript::Variant>(value);
+ Q_ASSERT(v.type() == QQmlScript::Variant::Script);
+ int bindingId = bindingIdentifier(v, prop.name());
+ ds << bindingId;
+
+ ds << prop.location().line;
+ }
+
+ return result;
+}
+
+void CustomBindingParser::setCustomData(QObject *object, const QByteArray &data)
+{
+ CustomBinding *customBinding = qobject_cast<CustomBinding*>(object);
+ Q_ASSERT(customBinding);
+ customBinding->m_bindingData = data;
+}
+
+void CustomBinding::componentComplete()
+{
+ Q_ASSERT(m_target);
+
+ QDataStream ds(m_bindingData);
+ int count;
+ ds >> count;
+ for (int i = 0; i < count; ++i) {
+ QString name;
+ ds >> name;
+
+ int bindingId;
+ ds >> bindingId;
+
+ int line;
+ ds >> line;
+
+ QQmlBinding *binding = QQmlBinding::createBinding(QQmlBinding::Identifier(bindingId), m_target, qmlContext(this), QString(), line);
+
+ QQmlProperty property(m_target, name, qmlContext(this));
+ binding->setTarget(property);
+ QQmlPropertyPrivate::setBinding(property, binding);
+ }
+}
diff --git a/tests/auto/qml/qqmllanguage/testtypes.h b/tests/auto/qml/qqmllanguage/testtypes.h
index 703b26a73c..a968d9a25a 100644
--- a/tests/auto/qml/qqmllanguage/testtypes.h
+++ b/tests/auto/qml/qqmllanguage/testtypes.h
@@ -1070,6 +1070,29 @@ QML_DECLARE_TYPE(MyRevisionedSubclass)
QML_DECLARE_TYPE(MySubclass)
QML_DECLARE_TYPE(MyReceiversTestObject)
+class CustomBinding : public QObject, public QQmlParserStatus
+{
+ Q_OBJECT
+ Q_INTERFACES(QQmlParserStatus)
+ Q_PROPERTY(QObject* target READ target WRITE setTarget)
+public:
+
+ virtual void classBegin() {}
+ virtual void componentComplete();
+
+ QObject *target() const { return m_target; }
+ void setTarget(QObject *newTarget) { m_target = newTarget; }
+
+ QPointer<QObject> m_target;
+ QByteArray m_bindingData;
+};
+
+class CustomBindingParser : public QQmlCustomParser
+{
+ virtual QByteArray compile(const QList<QQmlCustomParserProperty> &properties);
+ virtual void setCustomData(QObject *object, const QByteArray &data);
+};
+
void registerTypes();
#endif // TESTTYPES_H
diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
index 621061ab6a..6a577ec91c 100644
--- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
+++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
@@ -214,6 +214,8 @@ private slots:
void compositeSingletonSelectors();
void compositeSingletonRegistered();
+ void customParserBindingScopes();
+
private:
QQmlEngine engine;
QStringList defaultImportPathList;
@@ -3534,6 +3536,17 @@ void tst_qqmllanguage::compositeSingletonRegistered()
verifyCompositeSingletonPropertyValues(o, "value1", 925, "value2", 755);
}
+void tst_qqmllanguage::customParserBindingScopes()
+{
+ QQmlComponent component(&engine, testFile("customParserBindingScopes.qml"));
+ VERIFY_ERRORS(0);
+ QScopedPointer<QObject> o(component.create());
+ QVERIFY(!o.isNull());
+ QPointer<QObject> child = qvariant_cast<QObject*>(o->property("child"));
+ QVERIFY(!child.isNull());
+ QCOMPARE(child->property("testProperty").toInt(), 42);
+}
+
QTEST_MAIN(tst_qqmllanguage)
#include "tst_qqmllanguage.moc"
diff --git a/tests/auto/qml/qqmlpropertymap/tst_qqmlpropertymap.cpp b/tests/auto/qml/qqmlpropertymap/tst_qqmlpropertymap.cpp
index d76c11b833..28a9bce98d 100644
--- a/tests/auto/qml/qqmlpropertymap/tst_qqmlpropertymap.cpp
+++ b/tests/auto/qml/qqmlpropertymap/tst_qqmlpropertymap.cpp
@@ -55,6 +55,8 @@ public:
tst_QQmlPropertyMap() {}
private slots:
+ void initTestCase();
+
void insert();
void operatorInsert();
void operatorValue();
@@ -68,8 +70,39 @@ private slots:
void metaObjectAccessibility();
void QTBUG_31226();
void QTBUG_29836();
+ void QTBUG_35233();
+ void disallowExtending();
+};
+
+class LazyPropertyMap : public QQmlPropertyMap, public QQmlParserStatus
+{
+ Q_OBJECT
+ Q_INTERFACES(QQmlParserStatus)
+
+ Q_PROPERTY(int someFixedProperty READ someFixedProperty WRITE setSomeFixedProperty)
+public:
+ LazyPropertyMap()
+ : QQmlPropertyMap(this, /*parent*/0)
+ , value(0)
+ {}
+
+ virtual void classBegin() {}
+ virtual void componentComplete() {
+ insert(QStringLiteral("lateProperty"), QStringLiteral("lateValue"));
+ }
+
+ int someFixedProperty() const { return value; }
+ void setSomeFixedProperty(int v) { value = v; }
+
+private:
+ int value;
};
+void tst_QQmlPropertyMap::initTestCase()
+{
+ qmlRegisterType<LazyPropertyMap>("QTBUG_35233", 1, 0, "LazyPropertyMap");
+}
+
void tst_QQmlPropertyMap::insert()
{
QQmlPropertyMap map;
@@ -369,6 +402,54 @@ void tst_QQmlPropertyMap::QTBUG_29836()
}
+void tst_QQmlPropertyMap::QTBUG_35233()
+{
+ QQmlEngine engine;
+ QQmlComponent component(&engine);
+ component.setData("import QtQml 2.0\n"
+ "import QTBUG_35233 1.0\n"
+ "QtObject {\n"
+ " property QtObject testMap: LazyPropertyMap {\n"
+ " id: map\n"
+ " }\n"
+ " property QtObject sibling: QtObject {\n"
+ " objectName: \"sibling\"\n"
+ " property string testValue: map.lateProperty\n"
+ " }\n"
+ "}", QUrl());
+ QScopedPointer<QObject> obj(component.create());
+ QVERIFY(!obj.isNull());
+
+ QObject *sibling = obj->findChild<QObject*>("sibling");
+ QVERIFY(sibling);
+ QCOMPARE(sibling->property("testValue").toString(), QString("lateValue"));
+}
+
+void tst_QQmlPropertyMap::disallowExtending()
+{
+ QQmlEngine engine;
+ QQmlComponent component(&engine);
+ component.setData("import QtQml 2.0\n"
+ "import QTBUG_35233 1.0\n"
+ "LazyPropertyMap {\n"
+ " id: blah\n"
+ " someFixedProperty: 42\n"
+ "}\n", QUrl());
+ QScopedPointer<QObject> obj(component.create());
+ QVERIFY(!obj.isNull());
+
+ component.setData("import QtQml 2.0\n"
+ "import QTBUG_35233 1.0\n"
+ "LazyPropertyMap {\n"
+ " id: blah\n"
+ " property int someNewProperty;\n"
+ "}\n", QUrl());
+ obj.reset(component.create());
+ QVERIFY(obj.isNull());
+ QCOMPARE(component.errors().count(), 1);
+ QCOMPARE(component.errors().at(0).toString(), QStringLiteral("<Unknown File>: Fully dynamic types cannot declare new properties."));
+}
+
QTEST_MAIN(tst_QQmlPropertyMap)
#include "tst_qqmlpropertymap.moc"
diff --git a/tests/auto/qml/qqmltranslation/data/jstranslation.qml b/tests/auto/qml/qqmltranslation/data/jstranslation.qml
new file mode 100644
index 0000000000..7adde019fa
--- /dev/null
+++ b/tests/auto/qml/qqmltranslation/data/jstranslation.qml
@@ -0,0 +1,20 @@
+import QtQuick 2.0
+import "translation.js" as Js
+
+QtObject {
+ property string basic: Js.basic()
+ property string basic2: Js.basic2()
+ property string basic3: Js.basic3()
+
+ property string disambiguation: Js.disambiguation()
+ property string disambiguation2: Js.disambiguation2()
+ property string disambiguation3: Js.disambiguation3()
+
+ property string noop: Js.noop()
+ property string noop2: Js.noop2()
+
+ property string singular: Js.singular()
+ property string singular2: Js.singular2()
+ property string plural: Js.plural()
+ property string plural2: Js.plural2()
+}
diff --git a/tests/auto/qml/qqmltranslation/data/translation.js b/tests/auto/qml/qqmltranslation/data/translation.js
new file mode 100644
index 0000000000..c1e25dcd2f
--- /dev/null
+++ b/tests/auto/qml/qqmltranslation/data/translation.js
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+function basic() {
+ return qsTr("hello")
+}
+
+function basic2() {
+ return qsTranslate("CustomContext", "goodbye")
+}
+
+function basic3() {
+ if (1)
+ return qsTr("hello")
+ return "";
+}
+
+function disambiguation() {
+ return qsTr("hi", "informal 'hello'")
+}
+
+function disambiguation2() {
+ return qsTranslate("CustomContext", "see ya", "informal 'goodbye'")
+}
+
+function disambiguation3() {
+ if (1)
+ return qsTr("hi", "informal 'hello'")
+ return "";
+}
+
+function noop() {
+ var _noop = QT_TR_NOOP("hello")
+ return qsTr(_noop)
+}
+
+function noop2() {
+ var _noop2 = QT_TRANSLATE_NOOP("CustomContext", "goodbye")
+ return qsTranslate("CustomContext", _noop2)
+}
+
+function singular() {
+ return qsTr("%n duck(s)", "", 1)
+}
+
+function singular2() {
+ if (1)
+ return qsTr("%n duck(s)", "", 1)
+ return "";
+}
+
+function plural() {
+ return qsTr("%n duck(s)", "", 2)
+}
+
+function plural2() {
+ if (1)
+ return qsTr("%n duck(s)", "", 2)
+ return "";
+}
diff --git a/tests/auto/qml/qqmltranslation/tst_qqmltranslation.cpp b/tests/auto/qml/qqmltranslation/tst_qqmltranslation.cpp
index 0e22d3cfca..01e1cf85fb 100644
--- a/tests/auto/qml/qqmltranslation/tst_qqmltranslation.cpp
+++ b/tests/auto/qml/qqmltranslation/tst_qqmltranslation.cpp
@@ -52,19 +52,32 @@ public:
tst_qqmltranslation() {}
private slots:
+ void translation_data();
void translation();
void idTranslation();
- void translationInQrc();
};
+void tst_qqmltranslation::translation_data()
+{
+ QTest::addColumn<QString>("translation");
+ QTest::addColumn<QUrl>("testFile");
+
+ QTest::newRow("qml") << QStringLiteral("qml_fr") << testFileUrl("translation.qml");
+ QTest::newRow("qrc") << QStringLiteral(":/qml_fr.qm") << QUrl("qrc:/translation.qml");
+ QTest::newRow("js") << QStringLiteral("qml_fr") << testFileUrl("jstranslation.qml");
+}
+
void tst_qqmltranslation::translation()
{
+ QFETCH(QString, translation);
+ QFETCH(QUrl, testFile);
+
QTranslator translator;
- translator.load(QLatin1String("qml_fr"), dataDirectory());
+ translator.load(translation, dataDirectory());
QCoreApplication::installTranslator(&translator);
QQmlEngine engine;
- QQmlComponent component(&engine, testFileUrl("translation.qml"));
+ QQmlComponent component(&engine, testFile);
QObject *object = component.create();
QVERIFY(object != 0);
@@ -104,34 +117,6 @@ void tst_qqmltranslation::idTranslation()
delete object;
}
-void tst_qqmltranslation::translationInQrc()
-{
- QTranslator translator;
- translator.load(":/qml_fr.qm");
- QCoreApplication::installTranslator(&translator);
-
- QQmlEngine engine;
- QQmlComponent component(&engine, QUrl("qrc:/translation.qml"));
- QObject *object = component.create();
- QVERIFY(object != 0);
-
- QCOMPARE(object->property("basic").toString(), QLatin1String("bonjour"));
- QCOMPARE(object->property("basic2").toString(), QLatin1String("au revoir"));
- QCOMPARE(object->property("basic3").toString(), QLatin1String("bonjour"));
- QCOMPARE(object->property("disambiguation").toString(), QLatin1String("salut"));
- QCOMPARE(object->property("disambiguation2").toString(), QString::fromUtf8("\xc3\xa0 plus tard"));
- QCOMPARE(object->property("disambiguation3").toString(), QLatin1String("salut"));
- QCOMPARE(object->property("noop").toString(), QLatin1String("bonjour"));
- QCOMPARE(object->property("noop2").toString(), QLatin1String("au revoir"));
- QCOMPARE(object->property("singular").toString(), QLatin1String("1 canard"));
- QCOMPARE(object->property("singular2").toString(), QLatin1String("1 canard"));
- QCOMPARE(object->property("plural").toString(), QLatin1String("2 canards"));
- QCOMPARE(object->property("plural2").toString(), QLatin1String("2 canards"));
-
- QCoreApplication::removeTranslator(&translator);
- delete object;
-}
-
QTEST_MAIN(tst_qqmltranslation)
#include "tst_qqmltranslation.moc"
diff --git a/tests/auto/quick/qquickapplication/tst_qquickapplication.cpp b/tests/auto/quick/qquickapplication/tst_qquickapplication.cpp
index ef27445920..dfcef43a7e 100644
--- a/tests/auto/quick/qquickapplication/tst_qquickapplication.cpp
+++ b/tests/auto/quick/qquickapplication/tst_qquickapplication.cpp
@@ -184,7 +184,6 @@ void tst_qquickapplication::layoutDirection()
// mirrored
QGuiApplication::setLayoutDirection(Qt::RightToLeft);
- QEXPECT_FAIL("", "QTBUG-21573", Abort);
QCOMPARE(Qt::LayoutDirection(item->property("layoutDirection").toInt()), Qt::RightToLeft);
// not mirrored again
diff --git a/tests/auto/quick/qquickflickable/data/stopAtBounds.qml b/tests/auto/quick/qquickflickable/data/stopAtBounds.qml
new file mode 100644
index 0000000000..d8661f3e45
--- /dev/null
+++ b/tests/auto/quick/qquickflickable/data/stopAtBounds.qml
@@ -0,0 +1,22 @@
+import QtQuick 2.0
+
+Flickable {
+ id: outer
+ objectName: "flickable"
+ width: 400
+ height: 400
+ contentX: 50
+ contentY: 50
+ contentWidth: 500
+ contentHeight: 500
+ boundsBehavior: Flickable.StopAtBounds
+
+ Rectangle {
+ x: 100
+ y: 100
+ width: 300
+ height: 300
+
+ color: "yellow"
+ }
+}
diff --git a/tests/auto/quick/qquickflickable/qquickflickable.pro b/tests/auto/quick/qquickflickable/qquickflickable.pro
index dfc8d7541b..88dc2fbc2a 100644
--- a/tests/auto/quick/qquickflickable/qquickflickable.pro
+++ b/tests/auto/quick/qquickflickable/qquickflickable.pro
@@ -11,4 +11,3 @@ TESTDATA = data/*
QT += core-private gui-private qml-private quick-private testlib
DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
-CONFIG+=insignificant_test
diff --git a/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp b/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp
index 3c518c509b..794f9a8af6 100644
--- a/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp
+++ b/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp
@@ -94,6 +94,8 @@ private slots:
void flickTwiceUsingTouches();
void nestedStopAtBounds();
void nestedStopAtBounds_data();
+ void stopAtBounds();
+ void stopAtBounds_data();
void nestedMouseAreaUsingTouch();
private:
@@ -285,11 +287,6 @@ void tst_qquickflickable::rebound()
window->rootObject()->setProperty("transitionsStarted", 0);
window->rootObject()->setProperty("transitionsFinished", 0);
-#ifdef Q_OS_MAC
- QSKIP("QTBUG-26696 - sometimes fails on Mac");
- return;
-#endif
-
// flick and trigger the transition multiple times
// (moving signals are emitted as soon as the first transition starts)
flick(window.data(), QPoint(20,20), QPoint(120,120), 200); // both x and y will bounce back
@@ -425,8 +422,7 @@ void tst_qquickflickable::pressDelay()
// As we moved pass the drag threshold, we should never receive the press
QVERIFY(mouseArea->property("pressed").toBool() == false);
- QTest::qWait(200);
- QVERIFY(mouseArea->property("pressed").toBool() == false);
+ QTRY_VERIFY(mouseArea->property("pressed").toBool() == false);
// On release the clicked signal should *not* be emitted
QTest::mouseRelease(window.data(), Qt::LeftButton, 0, QPoint(150, 190));
@@ -1180,8 +1176,7 @@ void tst_qquickflickable::margins()
// position to the far right, including margin
obj->setContentX(1600 + 50 - obj->width());
obj->returnToBounds();
- QTest::qWait(200);
- QCOMPARE(obj->contentX(), 1600. + 50. - obj->width());
+ QTRY_COMPARE(obj->contentX(), 1600. + 50. - obj->width());
// position beyond the far right, including margin
obj->setContentX(1600 + 50 - obj->width() + 1.);
@@ -1196,8 +1191,7 @@ void tst_qquickflickable::margins()
// position to the far bottom, including margin
obj->setContentY(600 + 30 - obj->height());
obj->returnToBounds();
- QTest::qWait(200);
- QCOMPARE(obj->contentY(), 600. + 30. - obj->height());
+ QTRY_COMPARE(obj->contentY(), 600. + 30. - obj->height());
// position beyond the far bottom, including margin
obj->setContentY(600 + 30 - obj->height() + 1.);
@@ -1266,14 +1260,12 @@ void tst_qquickflickable::clickAndDragWhenTransformed()
// click outside child rect
QTest::mousePress(view.data(), Qt::LeftButton, 0, QPoint(190, 190));
- QTest::qWait(10);
- QCOMPARE(flickable->property("itemPressed").toBool(), false);
+ QTRY_COMPARE(flickable->property("itemPressed").toBool(), false);
QTest::mouseRelease(view.data(), Qt::LeftButton, 0, QPoint(190, 190));
// click inside child rect
QTest::mousePress(view.data(), Qt::LeftButton, 0, QPoint(200, 200));
- QTest::qWait(10);
- QCOMPARE(flickable->property("itemPressed").toBool(), true);
+ QTRY_COMPARE(flickable->property("itemPressed").toBool(), true);
QTest::mouseRelease(view.data(), Qt::LeftButton, 0, QPoint(200, 200));
const int threshold = qApp->styleHints()->startDragDistance();
@@ -1322,13 +1314,15 @@ void tst_qquickflickable::flickTwiceUsingTouches()
qreal contentYAfterFirstFlick = flickable->contentY();
qDebug() << "contentYAfterFirstFlick " << contentYAfterFirstFlick;
QVERIFY(contentYAfterFirstFlick > 50.0f);
+ // Wait until view stops moving
+ QTRY_VERIFY(!flickable->isMoving());
flickWithTouch(window.data(), touchDevice, QPoint(100, 400), QPoint(100, 240));
// In the original bug, that second flick would cause Flickable to halt immediately
qreal contentYAfterSecondFlick = flickable->contentY();
qDebug() << "contentYAfterSecondFlick " << contentYAfterSecondFlick;
- QVERIFY(contentYAfterSecondFlick > (contentYAfterFirstFlick + 80.0f));
+ QTRY_VERIFY(contentYAfterSecondFlick > (contentYAfterFirstFlick + 80.0f));
}
void tst_qquickflickable::flickWithTouch(QWindow *window, QTouchDevice *touchDevice, const QPoint &from, const QPoint &to)
@@ -1419,6 +1413,90 @@ void tst_qquickflickable::nestedStopAtBounds()
QTRY_VERIFY(!outer->isMoving());
}
+void tst_qquickflickable::stopAtBounds_data()
+{
+ QTest::addColumn<bool>("transpose");
+ QTest::addColumn<bool>("invert");
+
+ QTest::newRow("left") << false << false;
+ QTest::newRow("right") << false << true;
+ QTest::newRow("top") << true << false;
+ QTest::newRow("bottom") << true << true;
+}
+
+void tst_qquickflickable::stopAtBounds()
+{
+ QFETCH(bool, transpose);
+ QFETCH(bool, invert);
+
+ QQuickView view;
+ view.setSource(testFileUrl("stopAtBounds.qml"));
+ QTRY_COMPARE(view.status(), QQuickView::Ready);
+ QQuickViewTestUtil::centerOnScreen(&view);
+ QQuickViewTestUtil::moveMouseAway(&view);
+ view.show();
+ view.requestActivate();
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
+ QVERIFY(view.rootObject());
+
+ QQuickFlickable *flickable = qobject_cast<QQuickFlickable*>(view.rootObject());
+ QVERIFY(flickable);
+
+ if (transpose)
+ flickable->setContentY(invert ? 100 : 0);
+ else
+ flickable->setContentX(invert ? 100 : 0);
+
+ const int threshold = qApp->styleHints()->startDragDistance();
+
+ QPoint position(200, 200);
+ int &axis = transpose ? position.ry() : position.rx();
+
+ // drag away from the aligned boundary. View should not move
+ QTest::mousePress(&view, Qt::LeftButton, 0, position);
+ QTest::qWait(10);
+ for (int i = 0; i < 3; ++i) {
+ axis += invert ? -threshold : threshold;
+ QTest::mouseMove(&view, position);
+ }
+ QCOMPARE(flickable->isDragging(), false);
+ if (invert)
+ QCOMPARE(transpose ? flickable->isAtYEnd() : flickable->isAtXEnd(), true);
+ else
+ QCOMPARE(transpose ? flickable->isAtYBeginning() : flickable->isAtXBeginning(), true);
+
+ // drag back towards boundary
+ for (int i = 0; i < 24; ++i) {
+ axis += invert ? threshold / 3 : -threshold / 3;
+ QTest::mouseMove(&view, position);
+ }
+ QTRY_COMPARE(flickable->isDragging(), true);
+ if (invert)
+ QCOMPARE(transpose ? flickable->isAtYEnd() : flickable->isAtXEnd(), false);
+ else
+ QCOMPARE(transpose ? flickable->isAtYBeginning() : flickable->isAtXBeginning(), false);
+
+ // Drag away from the aligned boundary again.
+ // None of the mouse movements will position the view at the boundary exactly,
+ // but the view should end up aligned on the boundary
+ for (int i = 0; i < 5; ++i) {
+ axis += invert ? -threshold * 2 : threshold * 2;
+ QTest::mouseMove(&view, position);
+ }
+ QCOMPARE(flickable->isDragging(), true);
+
+ // we should have hit the boundary and stopped
+ if (invert) {
+ QCOMPARE(transpose ? flickable->isAtYEnd() : flickable->isAtXEnd(), true);
+ QCOMPARE(transpose ? flickable->contentY() : flickable->contentX(), 100.0);
+ } else {
+ QCOMPARE(transpose ? flickable->isAtYBeginning() : flickable->isAtXBeginning(), true);
+ QCOMPARE(transpose ? flickable->contentY() : flickable->contentX(), 0.0);
+ }
+
+ QTest::mouseRelease(&view, Qt::LeftButton, 0, position);
+}
+
void tst_qquickflickable::nestedMouseAreaUsingTouch()
{
QTouchDevice *touchDevice = new QTouchDevice;
diff --git a/tests/auto/quick/qquickitem/tst_qquickitem.cpp b/tests/auto/quick/qquickitem/tst_qquickitem.cpp
index 2c6dcd72ba..ad3c4fc208 100644
--- a/tests/auto/quick/qquickitem/tst_qquickitem.cpp
+++ b/tests/auto/quick/qquickitem/tst_qquickitem.cpp
@@ -1310,7 +1310,10 @@ void tst_qquickitem::touchEventAcceptIgnore()
bool accepted = window.event(&event);
QVERIFY(item->touchEventReached);
- QCOMPARE(accepted && event.isAccepted(), itemSupportsTouch);
+
+ // always true because QtQuick always eats touch events so as to not
+ // allow QtGui to synthesise them for us.
+ QCOMPARE(accepted && event.isAccepted(), true);
}
{
QTouchEvent::TouchPoint point;
@@ -1330,7 +1333,10 @@ void tst_qquickitem::touchEventAcceptIgnore()
bool accepted = window.event(&event);
QCOMPARE(item->touchEventReached, itemSupportsTouch);
- QCOMPARE(accepted && event.isAccepted(), itemSupportsTouch);
+
+ // always true because QtQuick always eats touch events so as to not
+ // allow QtGui to synthesise them for us.
+ QCOMPARE(accepted && event.isAccepted(), true);
}
{
QTouchEvent::TouchPoint point;
@@ -1350,7 +1356,10 @@ void tst_qquickitem::touchEventAcceptIgnore()
bool accepted = window.event(&event);
QCOMPARE(item->touchEventReached, itemSupportsTouch);
- QCOMPARE(accepted && event.isAccepted(), itemSupportsTouch);
+
+ // always true because QtQuick always eats touch events so as to not
+ // allow QtGui to synthesise them for us.
+ QCOMPARE(accepted && event.isAccepted(), true);
}
}
diff --git a/tests/auto/quick/qquicklistview/data/HighlightResize.qml b/tests/auto/quick/qquicklistview/data/HighlightResize.qml
new file mode 100644
index 0000000000..2b07b39d20
--- /dev/null
+++ b/tests/auto/quick/qquicklistview/data/HighlightResize.qml
@@ -0,0 +1,23 @@
+import QtQuick 2.0
+
+ListView {
+ id: view
+
+ width: 400
+ height: 400
+ model: 5
+
+ highlight: Rectangle {
+ color: "skyblue"
+ }
+
+ delegate: Item {
+ width: 100 + index * 20
+ height: 100 + index * 10
+
+ Text {
+ anchors.centerIn: parent
+ text: model.index
+ }
+ }
+}
diff --git a/tests/auto/quick/qquicklistview/data/listview-sections.qml b/tests/auto/quick/qquicklistview/data/listview-sections.qml
index d5b8a4400d..e9fb83910a 100644
--- a/tests/auto/quick/qquicklistview/data/listview-sections.qml
+++ b/tests/auto/quick/qquicklistview/data/listview-sections.qml
@@ -1,6 +1,7 @@
import QtQuick 2.0
Rectangle {
+ property bool sectionsInvalidOnCompletion
width: 240
height: 320
color: "#ffffff"
@@ -9,6 +10,26 @@ Rectangle {
id: myDelegate
Item {
id: wrapper
+
+ function validateInitialSections() {
+ var invalid = false
+ if (index == 0) {
+ invalid |= wrapper.ListView.previousSection != ""
+ }
+ if (index == model.count - 1) {
+ invalid |= wrapper.ListView.nextSection != ""
+ }
+ if (index % 5 == 0 && index > 0) {
+ invalid |= wrapper.ListView.previousSection != Number(wrapper.ListView.section) - 1
+ } else if ((index + 1) % 5 == 0 && index < model.count - 1) {
+ invalid |= wrapper.ListView.nextSection != Number(wrapper.ListView.section) + 1
+ } else if (index > 0 && index < model.count - 1) {
+ invalid |= wrapper.ListView.previousSection != wrapper.ListView.section
+ invalid |= wrapper.ListView.nextSection != wrapper.ListView.section
+ }
+ sectionsInvalidOnCompletion |= invalid
+ }
+
objectName: "wrapper"
height: ListView.previousSection != ListView.section ? 40 : 20;
width: 240
@@ -49,6 +70,10 @@ Rectangle {
visible: wrapper.ListView.previousSection != wrapper.ListView.section ? true : false
Text { text: wrapper.ListView.section }
}
+ ListView.onPreviousSectionChanged: validateInitialSections()
+ ListView.onNextSectionChanged: validateInitialSections()
+ ListView.onSectionChanged: validateInitialSections()
+ Component.onCompleted: validateInitialSections()
}
}
]
diff --git a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp
index c3a5c64ba1..c3f42d393e 100644
--- a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp
+++ b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp
@@ -217,6 +217,8 @@ private slots:
void typedModel();
void displayMargin();
+ void highlightItemGeometryChanges();
+
private:
template <class T> void items(const QUrl &source);
template <class T> void changed(const QUrl &source);
@@ -1957,6 +1959,8 @@ void tst_QQuickListView::sections(const QUrl &source)
QCOMPARE(next->text().toInt(), (i+1)/5);
}
+ QVERIFY(!listview->property("sectionsInvalidOnCompletion").toBool());
+
QSignalSpy currentSectionChangedSpy(listview, SIGNAL(currentSectionChanged()));
// Remove section boundary
@@ -7048,6 +7052,25 @@ void tst_QQuickListView::displayMargin()
delete window;
}
+void tst_QQuickListView::highlightItemGeometryChanges()
+{
+ QQmlEngine engine;
+ QQmlComponent component(&engine, testFileUrl("HighlightResize.qml"));
+
+ QScopedPointer<QObject> object(component.create());
+
+ QQuickListView *listview = qobject_cast<QQuickListView *>(object.data());
+ QVERIFY(listview);
+
+ QCOMPARE(listview->count(), 5);
+
+ for (int i = 0; i < listview->count(); ++i) {
+ listview->setCurrentIndex(i);
+ QTRY_COMPARE(listview->highlightItem()->width(), qreal(100 + i * 20));
+ QTRY_COMPARE(listview->highlightItem()->height(), qreal(100 + i * 10));
+ }
+}
+
QTEST_MAIN(tst_QQuickListView)
#include "tst_qquicklistview.moc"
diff --git a/tests/auto/quick/qquickloader/data/SimpleTestComponent.qml b/tests/auto/quick/qquickloader/data/SimpleTestComponent.qml
new file mode 100644
index 0000000000..0e69012662
--- /dev/null
+++ b/tests/auto/quick/qquickloader/data/SimpleTestComponent.qml
@@ -0,0 +1,2 @@
+import QtQml 2.0
+QtObject {}
diff --git a/tests/auto/quick/qquickloader/data/sourceComponentGarbageCollection.qml b/tests/auto/quick/qquickloader/data/sourceComponentGarbageCollection.qml
new file mode 100644
index 0000000000..ab86883af5
--- /dev/null
+++ b/tests/auto/quick/qquickloader/data/sourceComponentGarbageCollection.qml
@@ -0,0 +1,8 @@
+import QtQuick 2.0
+
+Loader {
+ active: false
+ function setSourceComponent() {
+ sourceComponent = Qt.createComponent("SimpleTestComponent.qml");
+ }
+}
diff --git a/tests/auto/quick/qquickloader/tst_qquickloader.cpp b/tests/auto/quick/qquickloader/tst_qquickloader.cpp
index 50ded4d95a..1e23d689ff 100644
--- a/tests/auto/quick/qquickloader/tst_qquickloader.cpp
+++ b/tests/auto/quick/qquickloader/tst_qquickloader.cpp
@@ -128,6 +128,8 @@ private slots:
void sizeBound();
void QTBUG_30183();
+ void sourceComponentGarbageCollection();
+
private:
QQmlEngine engine;
};
@@ -1144,6 +1146,26 @@ void tst_QQuickLoader::QTBUG_30183()
delete loader;
}
+void tst_QQuickLoader::sourceComponentGarbageCollection()
+{
+ QQmlComponent component(&engine, testFileUrl("sourceComponentGarbageCollection.qml"));
+ QScopedPointer<QObject> obj(component.create());
+ QVERIFY(!obj.isNull());
+
+ QMetaObject::invokeMethod(obj.data(), "setSourceComponent");
+ engine.collectGarbage();
+ QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
+
+ QSignalSpy spy(obj.data(), SIGNAL(loaded()));
+
+ obj->setProperty("active", true);
+
+ if (spy.isEmpty())
+ QVERIFY(spy.wait());
+
+ QCOMPARE(spy.count(), 1);
+}
+
QTEST_MAIN(tst_QQuickLoader)
#include "tst_qquickloader.moc"
diff --git a/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp b/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp
index 72639556ec..31b323af5d 100644
--- a/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp
+++ b/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp
@@ -89,6 +89,7 @@ private slots:
void dragThreshold();
void invalidDrag_data() { rejectedButton_data(); }
void invalidDrag();
+ void cancelDragging();
void setDragOnPressed();
void updateMouseAreaPosOnClick();
void updateMouseAreaPosOnResize();
@@ -440,6 +441,57 @@ void tst_QQuickMouseArea::invalidDrag()
QCOMPARE(blackRect->y(), 50.0);
}
+void tst_QQuickMouseArea::cancelDragging()
+{
+ QQuickView window;
+ QByteArray errorMessage;
+ QVERIFY2(initView(window, testFileUrl("dragging.qml"), true, &errorMessage), errorMessage.constData());
+
+ window.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&window));
+ QVERIFY(window.rootObject() != 0);
+
+ QQuickMouseArea *mouseRegion = window.rootObject()->findChild<QQuickMouseArea*>("mouseregion");
+ QQuickDrag *drag = mouseRegion->drag();
+ QVERIFY(mouseRegion != 0);
+ QVERIFY(drag != 0);
+
+ mouseRegion->setAcceptedButtons(Qt::LeftButton);
+
+ // target
+ QQuickItem *blackRect = window.rootObject()->findChild<QQuickItem*>("blackrect");
+ QVERIFY(blackRect != 0);
+ QVERIFY(blackRect == drag->target());
+
+ QVERIFY(!drag->active());
+
+ QTest::mousePress(&window, Qt::LeftButton, 0, QPoint(100,100));
+
+ QVERIFY(!drag->active());
+ QCOMPARE(blackRect->x(), 50.0);
+ QCOMPARE(blackRect->y(), 50.0);
+
+ QTest::mouseMove(&window, QPoint(111,111), 50);
+ QTest::mouseMove(&window, QPoint(116,116), 50);
+ QTest::mouseMove(&window, QPoint(122,122), 50);
+
+ QTRY_VERIFY(drag->active());
+ QTRY_COMPARE(blackRect->x(), 61.0);
+ QCOMPARE(blackRect->y(), 61.0);
+
+ mouseRegion->QQuickItem::ungrabMouse();
+ QTRY_VERIFY(!drag->active());
+ QCOMPARE(blackRect->x(), 61.0);
+ QCOMPARE(blackRect->y(), 61.0);
+
+ QTest::mouseMove(&window, QPoint(132,132), 50);
+ QTRY_VERIFY(!drag->active());
+ QCOMPARE(blackRect->x(), 61.0);
+ QCOMPARE(blackRect->y(), 61.0);
+
+ QTest::mouseRelease(&window, Qt::LeftButton, 0, QPoint(122,122));
+}
+
void tst_QQuickMouseArea::setDragOnPressed()
{
QQuickView window;
diff --git a/tests/auto/quick/qquickwindow/data/focus.qml b/tests/auto/quick/qquickwindow/data/focus.qml
index 899b999cdc..fa8ae9dc69 100644
--- a/tests/auto/quick/qquickwindow/data/focus.qml
+++ b/tests/auto/quick/qquickwindow/data/focus.qml
@@ -12,4 +12,8 @@ Window.Window {
Item {
objectName: "item2"
}
+
+ FocusScope {
+ Item { objectName: "item3" }
+ }
}
diff --git a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
index 1d9beedbab..bdd70f6a6e 100644
--- a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
+++ b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
@@ -316,6 +316,7 @@ private slots:
void qmlCreation();
void clearColor();
+ void defaultState();
void grab_data();
void grab();
@@ -974,6 +975,25 @@ void tst_qquickwindow::clearColor()
QCOMPARE(window->color(), QColor(Qt::blue));
}
+void tst_qquickwindow::defaultState()
+{
+ QQmlEngine engine;
+ QQmlComponent component(&engine);
+ component.setData("import QtQuick 2.0; import QtQuick.Window 2.1; Window { }", QUrl());
+ QObject *created = component.create();
+ QScopedPointer<QObject> cleanup(created);
+ QVERIFY(created);
+
+ QQuickWindow *qmlWindow = qobject_cast<QQuickWindow*>(created);
+ QVERIFY(qmlWindow);
+
+ QQuickWindow cppWindow;
+ cppWindow.show();
+ QTest::qWaitForWindowExposed(&cppWindow);
+
+ QCOMPARE(qmlWindow->windowState(), cppWindow.windowState());
+}
+
void tst_qquickwindow::grab_data()
{
QTest::addColumn<bool>("visible");
@@ -1144,20 +1164,35 @@ void tst_qquickwindow::focusObject()
QQuickWindow *window = qobject_cast<QQuickWindow*>(created);
QVERIFY(window);
+ QSignalSpy focusObjectSpy(window, SIGNAL(focusObjectChanged(QObject*)));
+
window->show();
QVERIFY(QTest::qWaitForWindowExposed(window));
window->requestActivate();
QVERIFY(QTest::qWaitForWindowActive(window));
+ QCOMPARE(window->contentItem(), window->focusObject());
+ QCOMPARE(focusObjectSpy.count(), 1);
+
QQuickItem *item1 = window->findChild<QQuickItem*>("item1");
QVERIFY(item1);
item1->setFocus(true);
QCOMPARE(item1, window->focusObject());
+ QCOMPARE(focusObjectSpy.count(), 2);
QQuickItem *item2 = window->findChild<QQuickItem*>("item2");
QVERIFY(item2);
item2->setFocus(true);
QCOMPARE(item2, window->focusObject());
+ QCOMPARE(focusObjectSpy.count(), 3);
+
+ // set focus for item in non-focused focus scope and
+ // ensure focusObject does not change and signal is not emitted
+ QQuickItem *item3 = window->findChild<QQuickItem*>("item3");
+ QVERIFY(item3);
+ item3->setFocus(true);
+ QCOMPARE(item2, window->focusObject());
+ QCOMPARE(focusObjectSpy.count(), 3);
}
void tst_qquickwindow::ignoreUnhandledMouseEvents()
diff --git a/tests/auto/quick/scenegraph/data/simple.qml b/tests/auto/quick/scenegraph/data/simple.qml
new file mode 100644
index 0000000000..b2924f135e
--- /dev/null
+++ b/tests/auto/quick/scenegraph/data/simple.qml
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.2
+
+Rectangle {
+ width: 200
+ height: 200
+ color: "steelblue"
+ Rectangle {
+ width: 150
+ height: 150
+ anchors.centerIn: parent
+ color: "palegreen"
+ rotation: 45
+ Text {
+ rotation: -45
+ text: "Simple QML.."
+ anchors.centerIn: parent
+ }
+ }
+}
diff --git a/tests/auto/quick/scenegraph/scenegraph.pro b/tests/auto/quick/scenegraph/scenegraph.pro
index 105221b7f4..1aa73ca60a 100644
--- a/tests/auto/quick/scenegraph/scenegraph.pro
+++ b/tests/auto/quick/scenegraph/scenegraph.pro
@@ -11,4 +11,5 @@ QT += core-private gui-private qml-private quick-private testlib
DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
OTHER_FILES += \
- data/render_OutOfFloatRange.qml
+ data/render_OutOfFloatRange.qml \
+ data/simple.qml
diff --git a/tests/auto/quick/scenegraph/tst_scenegraph.cpp b/tests/auto/quick/scenegraph/tst_scenegraph.cpp
index 3b79f01f12..780d5a97db 100644
--- a/tests/auto/quick/scenegraph/tst_scenegraph.cpp
+++ b/tests/auto/quick/scenegraph/tst_scenegraph.cpp
@@ -58,6 +58,8 @@ private slots:
void render_data();
void render();
+
+ void hideWithOtherContext();
};
template <typename T> class ScopedList : public QList<T> {
@@ -401,6 +403,40 @@ void tst_SceneGraph::render()
}
}
+// Testcase for QTBUG-34898. We make another context current on another surface
+// in the GUI thread and hide the QQuickWindow while the other context is
+// current on the other window.
+void tst_SceneGraph::hideWithOtherContext()
+{
+ QWindow window;
+ window.setSurfaceType(QWindow::OpenGLSurface);
+ window.resize(100, 100);
+ window.create();
+ QOpenGLContext context;
+ context.create();
+ bool renderingOnMainThread = false;
+
+ {
+ QQuickView view;
+ view.setSource(QUrl::fromLocalFile("data/simple.qml"));
+ view.setResizeMode(QQuickView::SizeViewToRootObject);
+ view.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
+
+ renderingOnMainThread = view.openglContext()->thread() == QGuiApplication::instance()->thread();
+
+ // Make the local context current on the local window...
+ context.makeCurrent(&window);
+ }
+
+ // The local context should no longer be the current one. It is not
+ // rebound because all well behaving Qt/OpenGL applications are
+ // required to makeCurrent their context again before making any
+ // GL calls to a new frame (see QOpenGLContext docs).
+ QVERIFY(!renderingOnMainThread || QOpenGLContext::currentContext() != &context);
+}
+
+
#include "tst_scenegraph.moc"
QTEST_MAIN(tst_SceneGraph)
diff --git a/tests/auto/quick/touchmouse/tst_touchmouse.cpp b/tests/auto/quick/touchmouse/tst_touchmouse.cpp
index 6cf0aa4749..5b4ad0ffa3 100644
--- a/tests/auto/quick/touchmouse/tst_touchmouse.cpp
+++ b/tests/auto/quick/touchmouse/tst_touchmouse.cpp
@@ -154,6 +154,7 @@ private slots:
void mouseOverTouch();
void buttonOnFlickable();
+ void buttonOnDelayedPressFlickable();
void buttonOnTouch();
void pinchOnFlickable();
@@ -162,9 +163,22 @@ private slots:
void tapOnDismissiveTopMouseAreaClicksBottomOne();
+protected:
+ bool eventFilter(QObject *, QEvent *event)
+ {
+ if (event->type() == QEvent::MouseButtonPress ||
+ event->type() == QEvent::MouseMove ||
+ event->type() == QEvent::MouseButtonRelease) {
+ QMouseEvent *me = static_cast<QMouseEvent*>(event);
+ filteredEventList.append(Event(me->type(), me->pos(), me->globalPos()));
+ }
+ return false;
+ }
+
private:
QQuickView *createView();
QTouchDevice *device;
+ QList<Event> filteredEventList;
};
QQuickView *tst_TouchMouse::createView()
@@ -496,7 +510,7 @@ void tst_TouchMouse::buttonOnFlickable()
QCOMPARE(eventItem1->eventList.size(), 0);
QPoint p1 = QPoint(20, 130);
QTest::touchEvent(window, device).press(0, p1, window);
- QCOMPARE(eventItem1->eventList.size(), 2);
+ QTRY_COMPARE(eventItem1->eventList.size(), 2);
QCOMPARE(eventItem1->eventList.at(0).type, QEvent::TouchBegin);
QCOMPARE(eventItem1->eventList.at(1).type, QEvent::MouseButtonPress);
QTest::touchEvent(window, device).release(0, p1, window);
@@ -559,12 +573,96 @@ void tst_TouchMouse::buttonOnFlickable()
QCOMPARE(eventItem1->eventList.at(3).type, QEvent::MouseMove);
QCOMPARE(windowPriv->mouseGrabberItem, flickable);
+ QCOMPARE(windowPriv->touchMouseId, 0);
+ QCOMPARE(windowPriv->itemForTouchPointId[0], flickable);
QVERIFY(flickable->isMovingVertically());
QTest::touchEvent(window, device).release(0, p3, window);
delete window;
}
+void tst_TouchMouse::buttonOnDelayedPressFlickable()
+{
+ // flickable - height 500 / 1000
+ // - eventItem1 y: 100, height 100
+ // - eventItem2 y: 300, height 100
+
+ qApp->setAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents, true);
+ filteredEventList.clear();
+
+ QQuickView *window = createView();
+
+ window->setSource(testFileUrl("buttononflickable.qml"));
+ window->show();
+ QVERIFY(QTest::qWaitForWindowExposed(window));
+ window->requestActivate();
+ QVERIFY(QTest::qWaitForWindowActive(window));
+ QVERIFY(window->rootObject() != 0);
+
+ QQuickFlickable *flickable = window->rootObject()->findChild<QQuickFlickable*>("flickable");
+ QVERIFY(flickable);
+
+ window->installEventFilter(this);
+
+ flickable->setPressDelay(60);
+
+ // should a mouse area button be clickable on top of flickable? yes :)
+ EventItem *eventItem1 = window->rootObject()->findChild<EventItem*>("eventItem1");
+ QVERIFY(eventItem1);
+ eventItem1->setAcceptedMouseButtons(Qt::LeftButton);
+ eventItem1->acceptMouse = true;
+
+ // should a touch button be touchable on top of flickable? yes :)
+ EventItem *eventItem2 = window->rootObject()->findChild<EventItem*>("eventItem2");
+ QVERIFY(eventItem2);
+ QCOMPARE(eventItem2->eventList.size(), 0);
+ eventItem2->acceptTouch = true;
+
+ // wait to avoid getting a double click event
+ QTest::qWait(qApp->styleHints()->mouseDoubleClickInterval() + 10);
+
+ // check that flickable moves - mouse button
+ QCOMPARE(eventItem1->eventList.size(), 0);
+ QPoint p1 = QPoint(10, 110);
+ QTest::touchEvent(window, device).press(0, p1, window);
+ // Flickable initially steals events
+ QCOMPARE(eventItem1->eventList.size(), 0);
+ // but we'll get the delayed mouse press after a delay
+ QTRY_COMPARE(eventItem1->eventList.size(), 1);
+ QCOMPARE(eventItem1->eventList.at(0).type, QEvent::MouseButtonPress);
+
+ // eventItem1 should have the mouse grab, and have moved the itemForTouchPointId
+ // for the touchMouseId to the new grabber.
+ QQuickWindowPrivate *windowPriv = QQuickWindowPrivate::get(window);
+ QCOMPARE(windowPriv->touchMouseId, 0);
+ QCOMPARE(windowPriv->itemForTouchPointId[0], eventItem1);
+ QCOMPARE(windowPriv->mouseGrabberItem, eventItem1);
+
+ p1 += QPoint(0, -10);
+ QPoint p2 = p1 + QPoint(0, -10);
+ QPoint p3 = p2 + QPoint(0, -10);
+ QTest::qWait(10);
+ QTest::touchEvent(window, device).move(0, p1, window);
+ QTest::qWait(10);
+ QTest::touchEvent(window, device).move(0, p2, window);
+ QTest::qWait(10);
+ QTest::touchEvent(window, device).move(0, p3, window);
+ QVERIFY(flickable->isMovingVertically());
+
+ // flickable should have the mouse grab, and have moved the itemForTouchPointId
+ // for the touchMouseId to the new grabber.
+ QCOMPARE(windowPriv->mouseGrabberItem, flickable);
+ QCOMPARE(windowPriv->touchMouseId, 0);
+ QCOMPARE(windowPriv->itemForTouchPointId[0], flickable);
+
+ QTest::touchEvent(window, device).release(0, p3, window);
+
+ // We should not have received any synthesised mouse events from Qt gui.
+ QCOMPARE(filteredEventList.count(), 0);
+
+ delete window;
+}
+
void tst_TouchMouse::buttonOnTouch()
{
// 400x800