diff options
author | Simon Hausmann <simon.hausmann@theqtcompany.com> | 2015-08-24 21:13:41 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@theqtcompany.com> | 2015-08-24 21:14:07 +0200 |
commit | 922ca8c3a839ccbf3407bfe7e449bfceec5ecd23 (patch) | |
tree | f18c3702e1692c17ebe710530aba931c8a4554f6 /tests/auto | |
parent | 9c9fca5e27bd91da1ea07bebd7569049493c5ccf (diff) | |
parent | 9dd496c069154ac655be9b85b72a6eb409bfa223 (diff) |
Merge remote-tracking branch 'origin/5.6' into dev
Change-Id: Ic5aad89b014527d3dfd7ad9b1837e3c3065c5f4c
Diffstat (limited to 'tests/auto')
26 files changed, 732 insertions, 41 deletions
diff --git a/tests/auto/qml/qml.pro b/tests/auto/qml/qml.pro index 2ca3e42991..b61eca730f 100644 --- a/tests/auto/qml/qml.pro +++ b/tests/auto/qml/qml.pro @@ -25,7 +25,8 @@ PUBLICTESTS += \ qtqmlmodules \ qquickfolderlistmodel \ qqmlapplicationengine \ - qqmlsettings + qqmlsettings \ + qqmlstatemachine PRIVATETESTS += \ animation \ diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp index 8bb9ddc07e..222e594d1a 100644 --- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp +++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp @@ -3941,12 +3941,12 @@ void tst_qqmlecmascript::verifyContextLifetime(QQmlContextData *ctxt) { QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine); QV4::Scope scope(v4); QV4::ScopedArrayObject scripts(scope, ctxt->importedScripts.value()); - QV4::ScopedValue qml(scope); + QV4::Scoped<QV4::QmlContextWrapper> qml(scope); for (quint32 i = 0; i < scripts->getLength(); ++i) { QQmlContextData *scriptContext, *newContext; qml = scripts->getIndexed(i); - scriptContext = QV4::QmlContextWrapper::getContext(qml); + scriptContext = qml ? qml->getContext() : 0; qml = QV4::Encode::undefined(); { @@ -3957,7 +3957,7 @@ void tst_qqmlecmascript::verifyContextLifetime(QQmlContextData *ctxt) { ctxt->engine->collectGarbage(); qml = scripts->getIndexed(i); - newContext = QV4::QmlContextWrapper::getContext(qml); + newContext = qml ? qml->getContext() : 0; QCOMPARE(scriptContext, newContext); } } @@ -5007,6 +5007,12 @@ void tst_qqmlecmascript::propertyVarCircular() QObject *object = component.create(); QVERIFY(object != 0); QMetaObject::invokeMethod(object, "assignCircular"); // cause assignment and gc + { + QCOMPARE(object->property("canaryInt"), QVariant(5)); + QVariant canaryResourceVariant = object->property("canaryResource"); + QVERIFY(canaryResourceVariant.isValid()); + } + QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); // process deleteLater() events from QV8QObjectWrapper. QCoreApplication::processEvents(); QCOMPARE(object->property("canaryInt"), QVariant(5)); @@ -5703,9 +5709,10 @@ void tst_qqmlecmascript::deletedEngine() delete engine; - QCOMPARE(object->property("a").toInt(), 117); + QCOMPARE(object->property("a").toInt(), 0); object->setProperty("b", QVariant(10)); - QCOMPARE(object->property("a").toInt(), 117); + object->setProperty("b", QVariant()); + QCOMPARE(object->property("a").toInt(), 0); delete object; } diff --git a/tests/auto/qml/qqmllanguage/data/assignSignalFunctionExpression.qml b/tests/auto/qml/qqmllanguage/data/assignSignalFunctionExpression.qml new file mode 100644 index 0000000000..bf8f8556c1 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/assignSignalFunctionExpression.qml @@ -0,0 +1,5 @@ +import Test 1.0 +MyQmlObject { + onBasicSignal: function() { basicSlot() } + onBasicParameterizedSignal: function(param) { basicSlotWithArgs(param) } +} diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp index 152b7510d2..97501118dd 100644 --- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp +++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp @@ -117,6 +117,7 @@ private slots: void idProperty(); void autoNotifyConnection(); void assignSignal(); + void assignSignalFunctionExpression(); void overrideSignal_data(); void overrideSignal(); void dynamicProperties(); @@ -1263,6 +1264,17 @@ void tst_qqmllanguage::assignSignal() emit object->basicParameterizedSignal(9); } +void tst_qqmllanguage::assignSignalFunctionExpression() +{ + QQmlComponent component(&engine, testFileUrl("assignSignalFunctionExpression.qml")); + VERIFY_ERRORS(0); + MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create()); + QVERIFY(object != 0); + QTest::ignoreMessage(QtWarningMsg, "MyQmlObject::basicSlot"); + emit object->basicSignal(); + QTest::ignoreMessage(QtWarningMsg, "MyQmlObject::basicSlotWithArgs(9)"); + emit object->basicParameterizedSignal(9); +} void tst_qqmllanguage::overrideSignal_data() { diff --git a/tests/auto/qml/qqmlnotifier/tst_qqmlnotifier.cpp b/tests/auto/qml/qqmlnotifier/tst_qqmlnotifier.cpp index 81215f7a18..4f1c9ae53e 100644 --- a/tests/auto/qml/qqmlnotifier/tst_qqmlnotifier.cpp +++ b/tests/auto/qml/qqmlnotifier/tst_qqmlnotifier.cpp @@ -165,6 +165,7 @@ private slots: void readProperty(); void propertyChange(); void disconnectOnDestroy(); + void lotsOfBindings(); private: void createObjects(); @@ -312,6 +313,39 @@ void tst_qqmlnotifier::disconnectOnDestroy() exportedObject->verifyReceiverCount(); } +class TestObject : public QObject +{ + Q_OBJECT + Q_PROPERTY(int a READ a NOTIFY aChanged) + +public: + int a() const { return 0; } + +signals: + void aChanged(); +}; + +void tst_qqmlnotifier::lotsOfBindings() +{ + TestObject o; + QQmlEngine *e = new QQmlEngine; + + e->rootContext()->setContextProperty(QStringLiteral("test"), &o); + + QList<QQmlComponent *> components; + for (int i = 0; i < 20000; ++i) { + QQmlComponent *component = new QQmlComponent(e); + component->setData("import QtQuick 2.0; Item { width: test.a; }", QUrl()); + component->create(e->rootContext()); + components.append(component); + } + + o.aChanged(); + + qDeleteAll(components); + delete e; +} + QTEST_MAIN(tst_qqmlnotifier) #include "tst_qqmlnotifier.moc" diff --git a/tests/auto/qml/qqmlproperty/data/readonlyPrimitiveVsVar.qml b/tests/auto/qml/qqmlproperty/data/readonlyPrimitiveVsVar.qml new file mode 100644 index 0000000000..253d61d1da --- /dev/null +++ b/tests/auto/qml/qqmlproperty/data/readonlyPrimitiveVsVar.qml @@ -0,0 +1,8 @@ +import QtQuick 2.0 + +QtObject { + readonly property var r_var: 1; + readonly property int r_int: 1; + property var w_var: 1; + property int w_int: 1; +} diff --git a/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp b/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp index 1d6c2d87ff..d6b1c86b88 100644 --- a/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp +++ b/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp @@ -146,6 +146,7 @@ private slots: void warnOnInvalidBinding(); void registeredCompositeTypeProperty(); void deeplyNestedObject(); + void readOnlyDynamicProperties(); void copy(); private: @@ -2039,6 +2040,20 @@ void tst_qqmlproperty::deeplyNestedObject() QCOMPARE(p.read(), QVariant(14)); } +void tst_qqmlproperty::readOnlyDynamicProperties() +{ + QQmlComponent comp(&engine, testFileUrl("readonlyPrimitiveVsVar.qml")); + QObject *obj = comp.create(); + QVERIFY(obj != 0); + + QVERIFY(!obj->metaObject()->property(obj->metaObject()->indexOfProperty("r_var")).isWritable()); + QVERIFY(!obj->metaObject()->property(obj->metaObject()->indexOfProperty("r_int")).isWritable()); + QVERIFY(obj->metaObject()->property(obj->metaObject()->indexOfProperty("w_var")).isWritable()); + QVERIFY(obj->metaObject()->property(obj->metaObject()->indexOfProperty("w_int")).isWritable()); + + delete obj; +} + void tst_qqmlproperty::initTestCase() { QQmlDataTest::initTestCase(); diff --git a/tests/auto/qml/qqmlpropertycache/tst_qqmlpropertycache.cpp b/tests/auto/qml/qqmlpropertycache/tst_qqmlpropertycache.cpp index ce2aab49c3..a5ae27d446 100644 --- a/tests/auto/qml/qqmlpropertycache/tst_qqmlpropertycache.cpp +++ b/tests/auto/qml/qqmlpropertycache/tst_qqmlpropertycache.cpp @@ -34,6 +34,7 @@ #include <qtest.h> #include <private/qqmlpropertycache_p.h> #include <QtQml/qqmlengine.h> +#include <private/qv8engine_p.h> #include "../../shared/util.h" class tst_qqmlpropertycache : public QObject @@ -102,10 +103,11 @@ QQmlPropertyData *cacheProperty(QQmlPropertyCache *cache, const char *name) void tst_qqmlpropertycache::properties() { QQmlEngine engine; + QV4::ExecutionEngine *v4 = QV8Engine::getV4(&engine); DerivedObject object; const QMetaObject *metaObject = object.metaObject(); - QQmlRefPointer<QQmlPropertyCache> cache(new QQmlPropertyCache(&engine, metaObject)); + QQmlRefPointer<QQmlPropertyCache> cache(new QQmlPropertyCache(v4, metaObject)); QQmlPropertyData *data; QVERIFY(data = cacheProperty(cache, "propertyA")); @@ -124,10 +126,11 @@ void tst_qqmlpropertycache::properties() void tst_qqmlpropertycache::propertiesDerived() { QQmlEngine engine; + QV4::ExecutionEngine *v4 = QV8Engine::getV4(&engine); DerivedObject object; const QMetaObject *metaObject = object.metaObject(); - QQmlRefPointer<QQmlPropertyCache> parentCache(new QQmlPropertyCache(&engine, &BaseObject::staticMetaObject)); + QQmlRefPointer<QQmlPropertyCache> parentCache(new QQmlPropertyCache(v4, &BaseObject::staticMetaObject)); QQmlRefPointer<QQmlPropertyCache> cache(parentCache->copyAndAppend(object.metaObject())); QQmlPropertyData *data; @@ -147,10 +150,11 @@ void tst_qqmlpropertycache::propertiesDerived() void tst_qqmlpropertycache::methods() { QQmlEngine engine; + QV4::ExecutionEngine *v4 = QV8Engine::getV4(&engine); DerivedObject object; const QMetaObject *metaObject = object.metaObject(); - QQmlRefPointer<QQmlPropertyCache> cache(new QQmlPropertyCache(&engine, metaObject)); + QQmlRefPointer<QQmlPropertyCache> cache(new QQmlPropertyCache(v4, metaObject)); QQmlPropertyData *data; QVERIFY(data = cacheProperty(cache, "slotA")); @@ -181,10 +185,11 @@ void tst_qqmlpropertycache::methods() void tst_qqmlpropertycache::methodsDerived() { QQmlEngine engine; + QV4::ExecutionEngine *v4 = QV8Engine::getV4(&engine); DerivedObject object; const QMetaObject *metaObject = object.metaObject(); - QQmlRefPointer<QQmlPropertyCache> parentCache(new QQmlPropertyCache(&engine, &BaseObject::staticMetaObject)); + QQmlRefPointer<QQmlPropertyCache> parentCache(new QQmlPropertyCache(v4, &BaseObject::staticMetaObject)); QQmlRefPointer<QQmlPropertyCache> cache(parentCache->copyAndAppend(object.metaObject())); QQmlPropertyData *data; @@ -216,10 +221,11 @@ void tst_qqmlpropertycache::methodsDerived() void tst_qqmlpropertycache::signalHandlers() { QQmlEngine engine; + QV4::ExecutionEngine *v4 = QV8Engine::getV4(&engine); DerivedObject object; const QMetaObject *metaObject = object.metaObject(); - QQmlRefPointer<QQmlPropertyCache> cache(new QQmlPropertyCache(&engine, metaObject)); + QQmlRefPointer<QQmlPropertyCache> cache(new QQmlPropertyCache(v4, metaObject)); QQmlPropertyData *data; QVERIFY(data = cacheProperty(cache, "onSignalA")); @@ -244,10 +250,11 @@ void tst_qqmlpropertycache::signalHandlers() void tst_qqmlpropertycache::signalHandlersDerived() { QQmlEngine engine; + QV4::ExecutionEngine *v4 = QV8Engine::getV4(&engine); DerivedObject object; const QMetaObject *metaObject = object.metaObject(); - QQmlRefPointer<QQmlPropertyCache> parentCache(new QQmlPropertyCache(&engine, &BaseObject::staticMetaObject)); + QQmlRefPointer<QQmlPropertyCache> parentCache(new QQmlPropertyCache(v4, &BaseObject::staticMetaObject)); QQmlRefPointer<QQmlPropertyCache> cache(parentCache->copyAndAppend(object.metaObject())); QQmlPropertyData *data; diff --git a/tests/auto/qml/qqmlstatemachine/data/cppsignal.qml b/tests/auto/qml/qqmlstatemachine/data/cppsignal.qml new file mode 100644 index 0000000000..3d06d823e2 --- /dev/null +++ b/tests/auto/qml/qqmlstatemachine/data/cppsignal.qml @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 2015 Ford Motor Company +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** 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 The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQml 2.0 + +import QtQml.StateMachine 1.0 + +import CppObjectEnum 1.0 + +StateMachine { + id: stateMachine + initialState: state0 + + State { + id: state0 + SignalTransition { + targetState: state1 + signal: _cppObject.mySignal + // signalState is mySignal's parameter + guard: signalState === CppObject.State1 + } + } + + State { + id: state1 + SignalTransition { + targetState: state2 + signal: _cppObject.mySignal + // signalState is mySignal's parameter + guard: signalState === CppObject.State2 + } + onEntered: _cppObject.objectState = CppObject.State1 + } + + FinalState { + id: state2 + onEntered: _cppObject.objectState = CppObject.State2 + } + Component.onCompleted: stateMachine.running = true +} diff --git a/tests/auto/qml/qqmlstatemachine/qqmlstatemachine.pro b/tests/auto/qml/qqmlstatemachine/qqmlstatemachine.pro new file mode 100644 index 0000000000..002af1d707 --- /dev/null +++ b/tests/auto/qml/qqmlstatemachine/qqmlstatemachine.pro @@ -0,0 +1,11 @@ +CONFIG += testcase +TARGET = tst_qqmlstatemachine +osx:CONFIG -= app_bundle + +SOURCES += tst_qqmlstatemachine.cpp + +include (../../shared/util.pri) + +CONFIG += parallel_test +QT += core-private gui-private qml-private quick-private gui testlib +DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/qqmlstatemachine/tst_qqmlstatemachine.cpp b/tests/auto/qml/qqmlstatemachine/tst_qqmlstatemachine.cpp new file mode 100644 index 0000000000..0d36b66e3f --- /dev/null +++ b/tests/auto/qml/qqmlstatemachine/tst_qqmlstatemachine.cpp @@ -0,0 +1,118 @@ +/**************************************************************************** +** +** Copyright (C) 2015 Ford Motor Company +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** 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 The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include <QQmlComponent> +#include <QQmlContext> +#include <QQmlEngine> +#include <QTest> +#include "../../shared/util.h" + +class tst_qqmlstatemachine : public QQmlDataTest +{ + Q_OBJECT +public: + tst_qqmlstatemachine(); + +private slots: + void tst_cppObjectSignal(); +}; + + +class CppObject : public QObject +{ + Q_OBJECT + Q_PROPERTY(ObjectState objectState READ objectState WRITE setObjectState NOTIFY objectStateChanged) + Q_ENUMS(ObjectState) +public: + enum ObjectState { + State0, + State1, + State2 + }; + +public: + CppObject() + : QObject() + , m_objectState(State0) + {} + + ObjectState objectState() const { return m_objectState; } + void setObjectState(ObjectState objectState) { m_objectState = objectState; emit objectStateChanged();} + +signals: + void objectStateChanged(); + void mySignal(int signalState); + +private: + ObjectState m_objectState; +}; + +tst_qqmlstatemachine::tst_qqmlstatemachine() +{ + QVERIFY(-1 != qmlRegisterUncreatableType<CppObject>("CppObjectEnum", 1, 0, "CppObject", QString())); +} + +void tst_qqmlstatemachine::tst_cppObjectSignal() +{ + CppObject cppObject; + QQmlEngine engine; + QQmlComponent component(&engine, testFileUrl("cppsignal.qml")); + QVERIFY(!component.isError()); + + QQmlContext *ctxt = engine.rootContext(); + ctxt->setContextProperty("_cppObject", &cppObject); + QScopedPointer<QObject> rootObject(component.create()); + QVERIFY(rootObject != 0); + + // wait for state machine to start + QTRY_VERIFY(rootObject->property("running").toBool()); + + // emit signal from cpp + emit cppObject.mySignal(CppObject::State1); + + // check if the signal was propagated + QTRY_COMPARE(cppObject.objectState(), CppObject::State1); + + // emit signal from cpp + emit cppObject.mySignal(CppObject::State2); + + // check if the signal was propagated + QTRY_COMPARE(cppObject.objectState(), CppObject::State2); + + // wait for state machine to finish + QTRY_VERIFY(!rootObject->property("running").toBool()); +} + + +QTEST_MAIN(tst_qqmlstatemachine) + +#include "tst_qqmlstatemachine.moc" diff --git a/tests/auto/qml/qv4debugger/tst_qv4debugger.cpp b/tests/auto/qml/qv4debugger/tst_qv4debugger.cpp index ca308a4f49..7772d16234 100644 --- a/tests/auto/qml/qv4debugger/tst_qv4debugger.cpp +++ b/tests/auto/qml/qv4debugger/tst_qv4debugger.cpp @@ -564,10 +564,8 @@ void tst_qv4debugger::readObject() QVERIFY(b_props.at(0).isObject()); QJsonObject b_head = b_props.at(0).toObject(); QCOMPARE(b_head.value("name").toString(), QStringLiteral("head")); - QVERIFY(b_head.contains("ref")); - QJsonObject b_head_value = frame0.collector->lookupRef(b_head.value("ref").toInt()); - QCOMPARE(b_head_value.value("type").toString(), QStringLiteral("number")); - QCOMPARE(b_head_value.value("value").toDouble(), 1.0); + QCOMPARE(b_head.value("type").toString(), QStringLiteral("number")); + QCOMPARE(b_head.value("value").toDouble(), 1.0); QVERIFY(b_props.at(1).isObject()); QJsonObject b_tail = b_props.at(1).toObject(); QCOMPARE(b_tail.value("name").toString(), QStringLiteral("tail")); @@ -580,16 +578,12 @@ void tst_qv4debugger::readObject() QCOMPARE(b_tail_props.size(), 2); QJsonObject b_tail_head = b_tail_props.at(0).toObject(); QCOMPARE(b_tail_head.value("name").toString(), QStringLiteral("head")); - QVERIFY(b_tail_head.contains("ref")); - QJsonObject b_tail_head_value = frame0.collector->lookupRef(b_tail_head.value("ref").toInt()); - QCOMPARE(b_tail_head_value.value("type").toString(), QStringLiteral("string")); - QCOMPARE(b_tail_head_value.value("value").toString(), QStringLiteral("asdf")); + QCOMPARE(b_tail_head.value("type").toString(), QStringLiteral("string")); + QCOMPARE(b_tail_head.value("value").toString(), QStringLiteral("asdf")); QJsonObject b_tail_tail = b_tail_props.at(1).toObject(); QCOMPARE(b_tail_tail.value("name").toString(), QStringLiteral("tail")); - QVERIFY(b_tail_tail.contains("ref")); - - QJsonObject b_tail_tail_value = frame0.collector->lookupRef(b_tail_tail.value("ref").toInt()); - QCOMPARE(b_tail_tail_value.value("type").toString(), QStringLiteral("null")); + QCOMPARE(b_tail_tail.value("type").toString(), QStringLiteral("null")); + QVERIFY(b_tail_tail.value("value").isNull()); } void tst_qv4debugger::readContextInAllFrames() diff --git a/tests/auto/quick/examples/examples.pro b/tests/auto/quick/examples/examples.pro index 6543aa1b2b..3d821fc13d 100644 --- a/tests/auto/quick/examples/examples.pro +++ b/tests/auto/quick/examples/examples.pro @@ -10,3 +10,5 @@ CONFIG += parallel_test #temporary QT += core-private gui-private qml-private quick-private testlib DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 +!qtHaveModule(xmlpatterns): DEFINES += QT_NO_XMLPATTERNS + diff --git a/tests/auto/quick/examples/tst_examples.cpp b/tests/auto/quick/examples/tst_examples.cpp index 175955d663..90c78ec942 100644 --- a/tests/auto/quick/examples/tst_examples.cpp +++ b/tests/auto/quick/examples/tst_examples.cpp @@ -104,7 +104,9 @@ tst_examples::tst_examples() excludedDirs << "demos/twitter"; excludedDirs << "demos/flickr"; excludedDirs << "demos/photoviewer"; - excludedDirs << "snippets/qml/xmlrole.qml"; + excludedFiles << "snippets/qml/xmlrole.qml"; + excludedFiles << "particles/itemparticle/particleview.qml"; + excludedFiles << "views/visualdatamodel/slideshow.qml"; #endif } diff --git a/tests/auto/quick/nodes/tst_nodestest.cpp b/tests/auto/quick/nodes/tst_nodestest.cpp index b49ce34951..c49f01d5a7 100644 --- a/tests/auto/quick/nodes/tst_nodestest.cpp +++ b/tests/auto/quick/nodes/tst_nodestest.cpp @@ -283,7 +283,7 @@ void NodesTest::textureNodeTextureOwnership() QVERIFY(!texture.isNull()); } - { // Check that it is deleted when we so desire + { // Check that it is deleted on destruction when we so desire QPointer<QSGTexture> texture(new QSGPlainTexture()); QSGSimpleTextureNode *tn = new QSGSimpleTextureNode(); @@ -294,6 +294,25 @@ void NodesTest::textureNodeTextureOwnership() delete tn; QVERIFY(texture.isNull()); } + + { // Check that it is deleted on update when we so desire + QPointer<QSGTexture> oldTexture(new QSGPlainTexture()); + QPointer<QSGTexture> newTexture(new QSGPlainTexture()); + + QSGSimpleTextureNode *tn = new QSGSimpleTextureNode(); + tn->setOwnsTexture(true); + QVERIFY(tn->ownsTexture()); + + tn->setTexture(oldTexture); + QVERIFY(!oldTexture.isNull()); + QVERIFY(!newTexture.isNull()); + + tn->setTexture(newTexture); + QVERIFY(oldTexture.isNull()); + QVERIFY(!newTexture.isNull()); + + delete tn; + } } void NodesTest::textureNodeRect() diff --git a/tests/auto/quick/qquickanimationcontroller/data/tst_parallelanimation.qml b/tests/auto/quick/qquickanimationcontroller/data/tst_parallelanimation.qml index 87cba880af..cd0f95bc7a 100644 --- a/tests/auto/quick/qquickanimationcontroller/data/tst_parallelanimation.qml +++ b/tests/auto/quick/qquickanimationcontroller/data/tst_parallelanimation.qml @@ -24,7 +24,7 @@ Rectangle { name:"AnimationController" when:windowShown function test_parallelAnimation_data() { - //FIXME:the commented lines fail on MAC OS X + //FIXME:the commented lines fail on OS X return [ {tag:"0.1",progress:0.1, x:5, y:10, color:"#e50019", width:14, height:14}, //{tag:"0.2",progress:0.2, x:10, y:20, color:"#cb0033", width:18, height:18}, diff --git a/tests/auto/quick/qquickcanvasitem/data/tst_canvas.qml b/tests/auto/quick/qquickcanvasitem/data/tst_canvas.qml index 5960e53557..93f85107a7 100644 --- a/tests/auto/quick/qquickcanvasitem/data/tst_canvas.qml +++ b/tests/auto/quick/qquickcanvasitem/data/tst_canvas.qml @@ -677,5 +677,27 @@ CanvasTestCase { waitForRendering(implicitlySizedItem); comparePixel(implicitlySizedItem.canvas.context, xCenter, yCenter, 0, 0, 0, 255); } + + Component { + id: simpleTextureNodeUsageComponent + + Canvas { + id: canvas + anchors.fill: parent + + onPaint: { + var ctx = canvas.getContext("2d"); + ctx.clearRect(0, 0, 200, 200); + } + } + } + + function test_simpleTextureNodeUsage() { + var canvas = simpleTextureNodeUsageComponent.createObject(container); + verify(canvas); + wait(0); + // Shouldn't crash. + canvas.requestPaint(); + } } } diff --git a/tests/auto/quick/qquickitem2/data/tabFence.qml b/tests/auto/quick/qquickitem2/data/tabFence.qml new file mode 100644 index 0000000000..fcf69b418b --- /dev/null +++ b/tests/auto/quick/qquickitem2/data/tabFence.qml @@ -0,0 +1,49 @@ +import QtQuick 2.1 +import Test 1.0 + +Item { + objectName: "root" + focus: true + width: 800 + height: 600 + + TabFence { + objectName: "fence1" + + TextInput { + objectName: "input11" + activeFocusOnTab: true + } + TextInput { + objectName: "input12" + activeFocusOnTab: true + } + TextInput { + objectName: "input13" + activeFocusOnTab: true + } + } + + TextInput { + objectName: "input1" + activeFocusOnTab: true + } + + TextInput { + objectName: "input2" + activeFocusOnTab: true + } + + TabFence { + objectName: "fence2" + } + + TextInput { + objectName: "input3" + activeFocusOnTab: true + } + + TabFence { + objectName: "fence3" + } +} diff --git a/tests/auto/quick/qquickitem2/tst_qquickitem.cpp b/tests/auto/quick/qquickitem2/tst_qquickitem.cpp index 396f183860..9f3de8292f 100644 --- a/tests/auto/quick/qquickitem2/tst_qquickitem.cpp +++ b/tests/auto/quick/qquickitem2/tst_qquickitem.cpp @@ -73,6 +73,8 @@ private slots: void nextItemInFocusChain2(); void nextItemInFocusChain3(); + void tabFence(); + void keys(); void standardKeys_data(); void standardKeys(); @@ -289,6 +291,20 @@ private: QML_DECLARE_TYPE(HollowTestItem); +class TabFenceItem : public QQuickItem +{ + Q_OBJECT + +public: + TabFenceItem(QQuickItem *parent = Q_NULLPTR) + : QQuickItem(parent) + { + QQuickItemPrivate *d = QQuickItemPrivate::get(this); + d->isTabFence = true; + } +}; + +QML_DECLARE_TYPE(TabFenceItem); tst_QQuickItem::tst_QQuickItem() { @@ -299,6 +315,7 @@ void tst_QQuickItem::initTestCase() QQmlDataTest::initTestCase(); qmlRegisterType<KeyTestItem>("Test",1,0,"KeyTestItem"); qmlRegisterType<HollowTestItem>("Test", 1, 0, "HollowTestItem"); + qmlRegisterType<TabFenceItem>("Test", 1, 0, "TabFence"); } void tst_QQuickItem::cleanup() @@ -1120,6 +1137,61 @@ void tst_QQuickItem::nextItemInFocusChain3() QCOMPARE(QGuiApplication::focusWindow(), window); } +void verifyTabFocusChain(QQuickView *window, const char **focusChain, bool forward) +{ + int idx = 0; + for (const char **objectName = focusChain; *objectName; ++objectName, ++idx) { + const QString &descrStr = QString("idx=%1 objectName=\"%2\"").arg(idx).arg(*objectName); + const char *descr = descrStr.toLocal8Bit().data(); + QKeyEvent key(QEvent::KeyPress, Qt::Key_Tab, forward ? Qt::NoModifier : Qt::ShiftModifier); + QGuiApplication::sendEvent(window, &key); + QVERIFY2(key.isAccepted(), descr); + + QQuickItem *item = findItem<QQuickItem>(window->rootObject(), *objectName); + QVERIFY2(item, descr); + QVERIFY2(item->hasActiveFocus(), descr); + } +} + +void tst_QQuickItem::tabFence() +{ + QQuickView *window = new QQuickView(0); + window->setBaseSize(QSize(800,600)); + + window->setSource(testFileUrl("tabFence.qml")); + window->show(); + window->requestActivate(); + QVERIFY(QTest::qWaitForWindowActive(window)); + QVERIFY(QGuiApplication::focusWindow() == window); + QVERIFY(window->rootObject()->hasActiveFocus()); + + const char *rootTabFocusChain[] = { + "input1", "input2", "input3", "input1", Q_NULLPTR + }; + verifyTabFocusChain(window, rootTabFocusChain, true /* forward */); + + const char *rootBacktabFocusChain[] = { + "input3", "input2", "input1", "input3", Q_NULLPTR + }; + verifyTabFocusChain(window, rootBacktabFocusChain, false /* forward */); + + // Give focus to input11 in fence1 + QQuickItem *item = findItem<QQuickItem>(window->rootObject(), "input11"); + item->setFocus(true); + QVERIFY(item); + QVERIFY(item->hasActiveFocus()); + + const char *fence1TabFocusChain[] = { + "input12", "input13", "input11", "input12", Q_NULLPTR + }; + verifyTabFocusChain(window, fence1TabFocusChain, true /* forward */); + + const char *fence1BacktabFocusChain[] = { + "input11", "input13", "input12", "input11", Q_NULLPTR + }; + verifyTabFocusChain(window, fence1BacktabFocusChain, false /* forward */); +} + void tst_QQuickItem::keys() { QQuickView *window = new QQuickView(0); diff --git a/tests/auto/quick/qquickitemlayer/data/TextureMirroring.qml b/tests/auto/quick/qquickitemlayer/data/TextureMirroring.qml new file mode 100644 index 0000000000..2827960153 --- /dev/null +++ b/tests/auto/quick/qquickitemlayer/data/TextureMirroring.qml @@ -0,0 +1,159 @@ +import QtQuick 2.6 + +Item +{ + width: 250 + height: 50 + + property int mirroring: 0 + + // Layered box without effect. Mirroring should not affect how it looks. + Rectangle { + x: 0 + y: 0 + width: 50 + height: 50 + layer.enabled: true + layer.textureMirroring: mirroring + Rectangle { + x: 0 + y: 0 + width: 25 + height: 25 + color: "#000000" + } + Rectangle { + x: 25 + y: 0 + width: 25 + height: 25 + color: "#ff0000" + } + Rectangle { + x: 0 + y: 25 + width: 25 + height: 25 + color: "#00ff00" + } + Rectangle { + x: 25 + y: 25 + width: 25 + height: 25 + color: "#0000ff" + } + } + + // Layered box with effect. Mirroring should affect how it looks. + Rectangle { + id: layeredEffectBox + x: 50 + y: 0 + width: 50 + height: 50 + layer.enabled: true + layer.textureMirroring: mirroring + layer.samplerName: "source" + layer.effect: ShaderEffect { + property variant source: layeredEffectBox + fragmentShader: " + uniform lowp sampler2D source; + varying highp vec2 qt_TexCoord0; + void main() { + gl_FragColor = texture2D(source, qt_TexCoord0); + }" + + } + + Rectangle { + x: 0 + y: 0 + width: 25 + height: 25 + color: "#000000" + } + Rectangle { + x: 25 + y: 0 + width: 25 + height: 25 + color: "#ff0000" + } + Rectangle { + x: 0 + y: 25 + width: 25 + height: 25 + color: "#00ff00" + } + Rectangle { + x: 25 + y: 25 + width: 25 + height: 25 + color: "#0000ff" + } + } + + // Non-layered source item for ShaderEffectSource. Mirroring should not affect how it looks. + Rectangle { + id: box2 + x: 100 + y: 0 + width: 50 + height: 50 + Rectangle { + x: 0 + y: 0 + width: 25 + height: 25 + color: "#000000" + } + Rectangle { + x: 25 + y: 0 + width: 25 + height: 25 + color: "#ff0000" + } + Rectangle { + x: 0 + y: 25 + width: 25 + height: 25 + color: "#00ff00" + } + Rectangle { + x: 25 + y: 25 + width: 25 + height: 25 + color: "#0000ff" + } + } + // ShaderEffectSource item. Mirroring should not affect how it looks. + ShaderEffectSource { + id: theSource + x: 150 + y: 0 + width: 50 + height: 50 + sourceItem: box2 + textureMirroring: mirroring + } + // ShaderEffect item. Mirroring should affect how it looks. + ShaderEffect { + x: 200 + y: 0 + width: 50 + height: 50 + property variant source: theSource + fragmentShader: " + uniform lowp sampler2D source; + varying highp vec2 qt_TexCoord0; + void main() { + gl_FragColor = texture2D(source, qt_TexCoord0); + }" + } +} diff --git a/tests/auto/quick/qquickitemlayer/qquickitemlayer.pro b/tests/auto/quick/qquickitemlayer/qquickitemlayer.pro index 999f0cf23d..a087948f6d 100644 --- a/tests/auto/quick/qquickitemlayer/qquickitemlayer.pro +++ b/tests/auto/quick/qquickitemlayer/qquickitemlayer.pro @@ -25,5 +25,6 @@ OTHER_FILES += \ data/DisableLayer.qml \ data/SamplerNameChange.qml \ data/ItemEffect.qml \ - data/RectangleEffect.qml + data/RectangleEffect.qml \ + data/TextureMirroring.qml DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/quick/qquickitemlayer/tst_qquickitemlayer.cpp b/tests/auto/quick/qquickitemlayer/tst_qquickitemlayer.cpp index 25a75c0580..094b69c07f 100644 --- a/tests/auto/quick/qquickitemlayer/tst_qquickitemlayer.cpp +++ b/tests/auto/quick/qquickitemlayer/tst_qquickitemlayer.cpp @@ -87,7 +87,12 @@ private slots: void itemEffect(); void rectangleEffect(); + void textureMirroring_data(); + void textureMirroring(); + private: + void mirroringCheck(int mirroring, int x, bool shouldMirror, const QImage &fb); + bool m_isMesaSoftwareRasterizer; int m_mesaVersion; }; @@ -434,6 +439,94 @@ void tst_QQuickItemLayer::rectangleEffect() QCOMPARE(fb.pixel(0, 100), qRgb(0, 0, 0xff)); } +void tst_QQuickItemLayer::textureMirroring_data() +{ + QTest::addColumn<int>("mirroring"); + + QTest::newRow("no mirroring") << 0; + QTest::newRow("horizontal") << 1; + QTest::newRow("vertical") << 2; + QTest::newRow("horizontal | vertical") << 3; +} + +void tst_QQuickItemLayer::textureMirroring() +{ + QFETCH(int, mirroring); + + QQuickView view; + view.setSource(testFileUrl("TextureMirroring.qml")); + + QQuickItem *child = view.contentItem()->childItems().at(0); + child->setProperty("mirroring", mirroring); + + view.show(); + + QTest::qWaitForWindowExposed(&view); + + QImage fb = view.grabWindow(); + + // Mirroring should have no visual effect on layered item without shader effect + mirroringCheck(mirroring, 0, false, fb); + + // Mirroring should have visual effect on layered item with shader effect + mirroringCheck(mirroring, 50, true, fb); + + // Mirroring should have no visual effect on source item for ShaderEffectSource + mirroringCheck(mirroring, 100, false, fb); + + // Mirroring should have no visual effect on ShaderEffectSource item + mirroringCheck(mirroring, 150, false, fb); + + // Mirroring should have visual effect on ShaderEffect item itself + mirroringCheck(mirroring, 200, true, fb); +} + +void tst_QQuickItemLayer::mirroringCheck(int mirroring, int x, bool shouldMirror, const QImage &fb) +{ + int offset = 10; + int spacing = 25; + + if (shouldMirror) { + switch (mirroring) { + case 0: { // No mirroring -> Visually Y gets swapped, X is default + QCOMPARE(fb.pixel(x + offset, offset), qRgb(0, 0xff, 0)); + QCOMPARE(fb.pixel(x + offset + spacing, offset), qRgb(0, 0, 0xff)); + QCOMPARE(fb.pixel(x + offset, offset + spacing), qRgb(0, 0, 0)); + QCOMPARE(fb.pixel(x + offset + spacing, offset + spacing), qRgb(0xff, 0, 0)); + break; + } + case 1: { // Horizontal mirroring -> Visually both X and Y get swapped, as neither is default + QCOMPARE(fb.pixel(x + offset, offset), qRgb(0, 0, 0xff)); + QCOMPARE(fb.pixel(x + offset + spacing, offset), qRgb(0, 0xff, 0)); + QCOMPARE(fb.pixel(x + offset, offset + spacing), qRgb(0xff, 0, 0)); + QCOMPARE(fb.pixel(x + offset + spacing, offset + spacing), qRgb(0, 0, 0)); + break; + } + case 2: { // Vertical mirroring -> The default case, nothing gets swapped + QCOMPARE(fb.pixel(x + offset, offset), qRgb(0, 0, 0)); + QCOMPARE(fb.pixel(x + offset + spacing, offset), qRgb(0xff, 0, 0)); + QCOMPARE(fb.pixel(x + offset, offset + spacing), qRgb(0, 0xff, 0)); + QCOMPARE(fb.pixel(x + offset + spacing, offset + spacing), qRgb(0, 0, 0xff)); + break; + } + case 3: { // Both axes mirrored -> Visually X gets swapped, Y is default + QCOMPARE(fb.pixel(x + offset, offset), qRgb(0xff, 0, 0)); + QCOMPARE(fb.pixel(x + offset + spacing, offset), qRgb(0, 0, 0)); + QCOMPARE(fb.pixel(x + offset, offset + spacing), qRgb(0, 0, 0xff)); + QCOMPARE(fb.pixel(x + offset + spacing, offset + spacing), qRgb(0, 0xff, 0)); + break; + } + default: + qWarning() << "Invalid case!"; + break; + } + } else { + QCOMPARE(fb.pixel(x + offset, offset), qRgb(0, 0, 0)); + QCOMPARE(fb.pixel(x + offset + spacing, offset), qRgb(0xff, 0, 0)); + QCOMPARE(fb.pixel(x + offset, offset + spacing), qRgb(0, 0xff, 0)); + QCOMPARE(fb.pixel(x + offset + spacing, offset + spacing), qRgb(0, 0, 0xff)); + } +} QTEST_MAIN(tst_QQuickItemLayer) diff --git a/tests/auto/quick/qquickstyledtext/tst_qquickstyledtext.cpp b/tests/auto/quick/qquickstyledtext/tst_qquickstyledtext.cpp index 95e495a74e..4678f5fbb9 100644 --- a/tests/auto/quick/qquickstyledtext/tst_qquickstyledtext.cpp +++ b/tests/auto/quick/qquickstyledtext/tst_qquickstyledtext.cpp @@ -153,6 +153,8 @@ void tst_qquickstyledtext::textOutput_data() QTest::newRow("space trailing bold") << "this is <b>bold </b>" << "this is bold " << (FormatList() << Format(Format::Bold, 8, 5)) << false; QTest::newRow("img") << "a<img src=\"blah.png\"/>b" << "a b" << FormatList() << false; QTest::newRow("tag mix") << "<f6>ds<b></img><pro>gfh</b><w><w>ghj</stron><ql><sl><pl>dfg</j6><img><bol><r><prp>dfg<bkj></b><up><string>ewrq</al><bl>jklhj<zl>" << "dsgfhghjdfgdfgewrqjklhj" << (FormatList() << Format(Format::Bold, 2, 3)) << false; + QTest::newRow("named html entities") << "> < & " " << QLatin1String("> < & \" ") + QChar(QChar::Nbsp) << FormatList() << false; + QTest::newRow("invalid html entities") << "a &hello & a &goodbye;" << "a &hello & a " << FormatList() << false; } void tst_qquickstyledtext::textOutput() diff --git a/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp b/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp index 9682070162..079f73ae34 100644 --- a/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp +++ b/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp @@ -2419,7 +2419,7 @@ void tst_qquicktextinput::navigation() simulateKey(&window, Qt::Key_Left); QVERIFY(input->hasActiveFocus()); - // Up and Down should NOT do Home/End, even on Mac OS X (QTBUG-10438). + // Up and Down should NOT do Home/End, even on OS X (QTBUG-10438). input->setCursorPosition(2); QCOMPARE(input->cursorPosition(),2); simulateKey(&window, Qt::Key_Up); diff --git a/tests/auto/quick/qquickwindow/BLACKLIST b/tests/auto/quick/qquickwindow/BLACKLIST deleted file mode 100644 index 8a19a679a3..0000000000 --- a/tests/auto/quick/qquickwindow/BLACKLIST +++ /dev/null @@ -1,4 +0,0 @@ -[cursor] -* -[testWindowVisibilityOrder] -osx diff --git a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp index 2c7a3c933b..e1ea068a62 100644 --- a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp +++ b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp @@ -1753,14 +1753,6 @@ void tst_qquickwindow::testWindowVisibilityOrder() QTest::qWaitForWindowExposed(window5); QVERIFY(window4->isVisible()); QVERIFY(window5->isVisible()); - window4->hide(); - window5->hide(); - - window3->hide(); - QTRY_COMPARE(window2, QGuiApplication::focusWindow()); - - window2->hide(); - QTRY_COMPARE(window1.data(), QGuiApplication::focusWindow()); } void tst_qquickwindow::blockClosing() |