diff options
author | Tasuku Suzuki <stasuku@gmail.com> | 2012-11-25 04:36:33 +0900 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2012-11-29 17:48:46 +0100 |
commit | e0cb13a510c0099784fee00d5b4b7c608dd42dd2 (patch) | |
tree | 8d61daaaa70df2fa7b26a0c989d748fc3718e15f /tests/auto/qml/qqmlconnections | |
parent | 55f6a109e99ea2eb3359fa941a1826d4b4e11bf8 (diff) |
Move no-Gui related QML types from QtQuick into QtQml
Task-number: QTBUG-26340
Change-Id: I9049128db2598bf3c7a9d677b774eaae53b54eb5
Reviewed-by: Alan Alpert <aalpert@rim.com>
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Reviewed-by: Gunnar Sletta <gunnar.sletta@digia.com>
Diffstat (limited to 'tests/auto/qml/qqmlconnections')
18 files changed, 489 insertions, 0 deletions
diff --git a/tests/auto/qml/qqmlconnections/data/connection-targetchange.qml b/tests/auto/qml/qqmlconnections/data/connection-targetchange.qml new file mode 100644 index 0000000000..154c309c9c --- /dev/null +++ b/tests/auto/qml/qqmlconnections/data/connection-targetchange.qml @@ -0,0 +1,25 @@ +import QtQuick 2.0 + +Item { + Component { + id: item1 + Item { + objectName: "item1" + } + } + Component { + id: item2 + Item { + objectName: "item2" + } + } + Loader { + id: loader + sourceComponent: item1 + } + Connections { + objectName: "connections" + target: loader.item + onWidthChanged: loader.sourceComponent = item2 + } +} diff --git a/tests/auto/qml/qqmlconnections/data/connection-unknownsignals-ignored.qml b/tests/auto/qml/qqmlconnections/data/connection-unknownsignals-ignored.qml new file mode 100644 index 0000000000..0780dd1509 --- /dev/null +++ b/tests/auto/qml/qqmlconnections/data/connection-unknownsignals-ignored.qml @@ -0,0 +1,8 @@ +import QtQml 2.0 + +QtObject { + id: root + + property Connections c1: Connections { target: root; onNotFooBar1: {} ignoreUnknownSignals: true } + property Connections c2: Connections { objectName: "connections"; onNotFooBar2: {} ignoreUnknownSignals: true } +} diff --git a/tests/auto/qml/qqmlconnections/data/connection-unknownsignals-notarget.qml b/tests/auto/qml/qqmlconnections/data/connection-unknownsignals-notarget.qml new file mode 100644 index 0000000000..3da3e0f5d1 --- /dev/null +++ b/tests/auto/qml/qqmlconnections/data/connection-unknownsignals-notarget.qml @@ -0,0 +1,5 @@ +import QtQml 2.0 + +QtObject { + property Connections c1: Connections { objectName: "connections"; target: null; onNotFooBar: {} } +} diff --git a/tests/auto/qml/qqmlconnections/data/connection-unknownsignals-parent.qml b/tests/auto/qml/qqmlconnections/data/connection-unknownsignals-parent.qml new file mode 100644 index 0000000000..2c55215579 --- /dev/null +++ b/tests/auto/qml/qqmlconnections/data/connection-unknownsignals-parent.qml @@ -0,0 +1,5 @@ +import QtQml 2.0 + +QtObject { + property Connections c1: Connections { objectName: "connections"; onFooBar: {} } +} diff --git a/tests/auto/qml/qqmlconnections/data/connection-unknownsignals.qml b/tests/auto/qml/qqmlconnections/data/connection-unknownsignals.qml new file mode 100644 index 0000000000..a351016b4a --- /dev/null +++ b/tests/auto/qml/qqmlconnections/data/connection-unknownsignals.qml @@ -0,0 +1,7 @@ +import QtQml 2.0 + +QtObject { + id: screen + + property Connections c1: Connections { objectName: "connections"; target: screen; onFooBar: {} } +} diff --git a/tests/auto/qml/qqmlconnections/data/error-object.qml b/tests/auto/qml/qqmlconnections/data/error-object.qml new file mode 100644 index 0000000000..8594811aa1 --- /dev/null +++ b/tests/auto/qml/qqmlconnections/data/error-object.qml @@ -0,0 +1,5 @@ +import QtQml 2.0 + +Connections { + onClicked: Timer {} +} diff --git a/tests/auto/qml/qqmlconnections/data/error-property.qml b/tests/auto/qml/qqmlconnections/data/error-property.qml new file mode 100644 index 0000000000..b08a4a504a --- /dev/null +++ b/tests/auto/qml/qqmlconnections/data/error-property.qml @@ -0,0 +1,3 @@ +import QtQml 2.0 + +Connections { fakeProperty: {} } diff --git a/tests/auto/qml/qqmlconnections/data/error-property2.qml b/tests/auto/qml/qqmlconnections/data/error-property2.qml new file mode 100644 index 0000000000..fcfbf5b412 --- /dev/null +++ b/tests/auto/qml/qqmlconnections/data/error-property2.qml @@ -0,0 +1,3 @@ +import QtQml 2.0 + +Connections { onfakeProperty: {} } diff --git a/tests/auto/qml/qqmlconnections/data/error-syntax.qml b/tests/auto/qml/qqmlconnections/data/error-syntax.qml new file mode 100644 index 0000000000..62c841bdb1 --- /dev/null +++ b/tests/auto/qml/qqmlconnections/data/error-syntax.qml @@ -0,0 +1,7 @@ +import QtQml 2.0 + +Connections { + onClicked { + onPressed: {} + } +} diff --git a/tests/auto/qml/qqmlconnections/data/rewriteError-global.qml b/tests/auto/qml/qqmlconnections/data/rewriteError-global.qml new file mode 100644 index 0000000000..1d0b557069 --- /dev/null +++ b/tests/auto/qml/qqmlconnections/data/rewriteError-global.qml @@ -0,0 +1,8 @@ +import QtQml 2.0 +import Test 1.0 + +TestObject { + property QtObject connection: Connections { + onSignalWithGlobalName: { ran = true } + } +} diff --git a/tests/auto/qml/qqmlconnections/data/rewriteError-unnamed.qml b/tests/auto/qml/qqmlconnections/data/rewriteError-unnamed.qml new file mode 100644 index 0000000000..a4849e994b --- /dev/null +++ b/tests/auto/qml/qqmlconnections/data/rewriteError-unnamed.qml @@ -0,0 +1,8 @@ +import QtQuick 2.0 +import Test 1.0 + +TestObject { + property QtObject connection: Connections { + onUnnamedArgumentSignal: { ran = true } + } +} diff --git a/tests/auto/qml/qqmlconnections/data/singletontype-target.qml b/tests/auto/qml/qqmlconnections/data/singletontype-target.qml new file mode 100644 index 0000000000..7de488c2dd --- /dev/null +++ b/tests/auto/qml/qqmlconnections/data/singletontype-target.qml @@ -0,0 +1,22 @@ +import QtQml 2.0 +import MyTestSingletonType 1.0 as MyTestSingletonType + +QtObject { + id: rootObject + objectName: "rootObject" + property int newIntPropValue: 12 + + property int moduleIntPropChangedCount: 0 + property int moduleOtherSignalCount: 0 + + function setModuleIntProp() { + MyTestSingletonType.Api.intProp = newIntPropValue; + newIntPropValue = newIntPropValue + 1; + } + + property Connections c: Connections { + target: MyTestSingletonType.Api + onIntPropChanged: moduleIntPropChangedCount = moduleIntPropChangedCount + 1; + onOtherSignal: moduleOtherSignalCount = moduleOtherSignalCount + 1; + } +} diff --git a/tests/auto/qml/qqmlconnections/data/test-connection.qml b/tests/auto/qml/qqmlconnections/data/test-connection.qml new file mode 100644 index 0000000000..ce851fc3db --- /dev/null +++ b/tests/auto/qml/qqmlconnections/data/test-connection.qml @@ -0,0 +1,10 @@ +import QtQuick 2.0 + +Item { + id: screen; width: 50 + + property bool tested: false + signal testMe + + Connections { target: screen; onWidthChanged: screen.tested = true } +} diff --git a/tests/auto/qml/qqmlconnections/data/test-connection2.qml b/tests/auto/qml/qqmlconnections/data/test-connection2.qml new file mode 100644 index 0000000000..a7e264c332 --- /dev/null +++ b/tests/auto/qml/qqmlconnections/data/test-connection2.qml @@ -0,0 +1,3 @@ +import QtQml 2.0 + +Connections { id: connection; target: connection; onTargetChanged: 1 == 1 } diff --git a/tests/auto/qml/qqmlconnections/data/test-connection3.qml b/tests/auto/qml/qqmlconnections/data/test-connection3.qml new file mode 100644 index 0000000000..9aaca2213a --- /dev/null +++ b/tests/auto/qml/qqmlconnections/data/test-connection3.qml @@ -0,0 +1,3 @@ +import QtQml 2.0 + +Connections {} diff --git a/tests/auto/qml/qqmlconnections/data/trimming.qml b/tests/auto/qml/qqmlconnections/data/trimming.qml new file mode 100644 index 0000000000..4c37eb22af --- /dev/null +++ b/tests/auto/qml/qqmlconnections/data/trimming.qml @@ -0,0 +1,10 @@ +import QtQml 2.0 + +QtObject { + id: root + + property string tested + signal testMe(int param1, string param2) + + property Connections c: Connections { target: root; onTestMe: root.tested = param2 + param1 } +} diff --git a/tests/auto/qml/qqmlconnections/qqmlconnections.pro b/tests/auto/qml/qqmlconnections/qqmlconnections.pro new file mode 100644 index 0000000000..52f85f6219 --- /dev/null +++ b/tests/auto/qml/qqmlconnections/qqmlconnections.pro @@ -0,0 +1,14 @@ +CONFIG += testcase +TARGET = tst_qqmlconnections +macx:CONFIG -= app_bundle + +SOURCES += tst_qqmlconnections.cpp + +include (../../shared/util.pri) + +TESTDATA = data/* + +CONFIG += parallel_test + +QT += core-private gui-private v8-private qml-private quick-private testlib +DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qml/qqmlconnections/tst_qqmlconnections.cpp b/tests/auto/qml/qqmlconnections/tst_qqmlconnections.cpp new file mode 100644 index 0000000000..b9e31d2216 --- /dev/null +++ b/tests/auto/qml/qqmlconnections/tst_qqmlconnections.cpp @@ -0,0 +1,343 @@ +/**************************************************************************** +** +** Copyright (C) 2012 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$ +** +****************************************************************************/ +#include <qtest.h> +#include <QtQml/qqmlengine.h> +#include <QtQml/qqmlcomponent.h> +#include <private/qqmlconnections_p.h> +#include <private/qquickitem_p.h> +#include "../../shared/util.h" +#include <QtQml/qqmlscriptstring.h> + +class tst_qqmlconnections : public QQmlDataTest +{ + Q_OBJECT +public: + tst_qqmlconnections(); + +private slots: + void defaultValues(); + void properties(); + void connection(); + void trimming(); + void targetChanged(); + void unknownSignals_data(); + void unknownSignals(); + void errors_data(); + void errors(); + void rewriteErrors(); + void singletonTypeTarget(); + +private: + QQmlEngine engine; +}; + +tst_qqmlconnections::tst_qqmlconnections() +{ +} + +void tst_qqmlconnections::defaultValues() +{ + QQmlEngine engine; + QQmlComponent c(&engine, testFileUrl("test-connection3.qml")); + QQmlConnections *item = qobject_cast<QQmlConnections*>(c.create()); + + QVERIFY(item != 0); + QVERIFY(item->target() == 0); + + delete item; +} + +void tst_qqmlconnections::properties() +{ + QQmlEngine engine; + QQmlComponent c(&engine, testFileUrl("test-connection2.qml")); + QQmlConnections *item = qobject_cast<QQmlConnections*>(c.create()); + + QVERIFY(item != 0); + + QVERIFY(item != 0); + QVERIFY(item->target() == item); + + delete item; +} + +void tst_qqmlconnections::connection() +{ + QQmlEngine engine; + QQmlComponent c(&engine, testFileUrl("test-connection.qml")); + QQuickItem *item = qobject_cast<QQuickItem*>(c.create()); + + QVERIFY(item != 0); + + QCOMPARE(item->property("tested").toBool(), false); + QCOMPARE(item->width(), 50.); + emit item->setWidth(100.); + QCOMPARE(item->width(), 100.); + QCOMPARE(item->property("tested").toBool(), true); + + delete item; +} + +void tst_qqmlconnections::trimming() +{ + QQmlEngine engine; + QQmlComponent c(&engine, testFileUrl("trimming.qml")); + QObject *object = c.create(); + + QVERIFY(object != 0); + + QCOMPARE(object->property("tested").toString(), QString("")); + int index = object->metaObject()->indexOfSignal("testMe(int,QString)"); + QMetaMethod method = object->metaObject()->method(index); + method.invoke(object, + Qt::DirectConnection, + Q_ARG(int, 5), + Q_ARG(QString, "worked")); + QCOMPARE(object->property("tested").toString(), QString("worked5")); + + delete object; +} + +// Confirm that target can be changed by one of our signal handlers +void tst_qqmlconnections::targetChanged() +{ + QQmlEngine engine; + QQmlComponent c(&engine, testFileUrl("connection-targetchange.qml")); + QQuickItem *item = qobject_cast<QQuickItem*>(c.create()); + QVERIFY(item != 0); + + QQmlConnections *connections = item->findChild<QQmlConnections*>("connections"); + QVERIFY(connections); + + QQuickItem *item1 = item->findChild<QQuickItem*>("item1"); + QVERIFY(item1); + + item1->setWidth(200); + + QQuickItem *item2 = item->findChild<QQuickItem*>("item2"); + QVERIFY(item2); + QVERIFY(connections->target() == item2); + + // If we don't crash then we're OK + + delete item; +} + +void tst_qqmlconnections::unknownSignals_data() +{ + QTest::addColumn<QString>("file"); + QTest::addColumn<QString>("error"); + + QTest::newRow("basic") << "connection-unknownsignals.qml" << ":6:30: QML Connections: Cannot assign to non-existent property \"onFooBar\""; + QTest::newRow("parent") << "connection-unknownsignals-parent.qml" << ":4:30: QML Connections: Cannot assign to non-existent property \"onFooBar\""; + QTest::newRow("ignored") << "connection-unknownsignals-ignored.qml" << ""; // should be NO error + QTest::newRow("notarget") << "connection-unknownsignals-notarget.qml" << ""; // should be NO error +} + +void tst_qqmlconnections::unknownSignals() +{ + QFETCH(QString, file); + QFETCH(QString, error); + + QUrl url = testFileUrl(file); + if (!error.isEmpty()) { + QTest::ignoreMessage(QtWarningMsg, (url.toString() + error).toLatin1()); + } else { + // QTest has no way to insist no message (i.e. fail) + } + + QQmlEngine engine; + QQmlComponent c(&engine, url); + QObject *object = c.create(); + QVERIFY(object != 0); + + // check that connection is created (they are all runtime errors) + QQmlConnections *connections = object->findChild<QQmlConnections*>("connections"); + QVERIFY(connections); + + if (file == "connection-unknownsignals-ignored.qml") + QVERIFY(connections->ignoreUnknownSignals()); + + delete object; +} + +void tst_qqmlconnections::errors_data() +{ + QTest::addColumn<QString>("file"); + QTest::addColumn<QString>("error"); + + QTest::newRow("no \"on\"") << "error-property.qml" << "Cannot assign to non-existent property \"fakeProperty\""; + QTest::newRow("3rd letter lowercase") << "error-property2.qml" << "Cannot assign to non-existent property \"onfakeProperty\""; + QTest::newRow("child object") << "error-object.qml" << "Connections: nested objects not allowed"; + QTest::newRow("grouped object") << "error-syntax.qml" << "Connections: syntax error"; +} + +void tst_qqmlconnections::errors() +{ + QFETCH(QString, file); + QFETCH(QString, error); + + QUrl url = testFileUrl(file); + + QQmlEngine engine; + QQmlComponent c(&engine, url); + QVERIFY(c.isError() == true); + QList<QQmlError> errors = c.errors(); + QVERIFY(errors.count() == 1); + QCOMPARE(errors.at(0).description(), error); +} + +class TestObject : public QObject +{ + Q_OBJECT + Q_PROPERTY(bool ran READ ran WRITE setRan) + +public: + TestObject(QObject *parent = 0) : m_ran(false) {} + ~TestObject() {} + + bool ran() const { return m_ran; } + void setRan(bool arg) { m_ran = arg; } + +signals: + void unnamedArgumentSignal(int a, qreal, QString c); + void signalWithGlobalName(int parseInt); + +private: + bool m_ran; +}; + +void tst_qqmlconnections::rewriteErrors() +{ + qmlRegisterType<TestObject>("Test", 1, 0, "TestObject"); + { + QQmlEngine engine; + QQmlComponent c(&engine, testFileUrl("rewriteError-unnamed.qml")); + TestObject *obj = qobject_cast<TestObject*>(c.create()); + QVERIFY(obj != 0); + + QTest::ignoreMessage(QtWarningMsg, (c.url().toString() + ":5:35: QML Connections: Signal uses unnamed parameter followed by named parameter.").toLatin1()); + obj->unnamedArgumentSignal(1, .5, "hello"); + QCOMPARE(obj->ran(), false); + + delete obj; + } + + { + QQmlEngine engine; + QQmlComponent c(&engine, testFileUrl("rewriteError-global.qml")); + TestObject *obj = qobject_cast<TestObject*>(c.create()); + QVERIFY(obj != 0); + + QTest::ignoreMessage(QtWarningMsg, (c.url().toString() + ":5:35: QML Connections: Signal parameter \"parseInt\" hides global variable.").toLatin1()); + obj->signalWithGlobalName(10); + QCOMPARE(obj->ran(), false); + + delete obj; + } +} + + +class MyTestSingletonType : public QObject +{ +Q_OBJECT +Q_PROPERTY(int intProp READ intProp WRITE setIntProp NOTIFY intPropChanged) + +public: + MyTestSingletonType(QObject *parent = 0) : QObject(parent), m_intProp(0), m_changeCount(0) {} + ~MyTestSingletonType() {} + + Q_INVOKABLE int otherMethod(int val) { return val + 4; } + + int intProp() const { return m_intProp; } + void setIntProp(int val) + { + if (++m_changeCount % 3 == 0) emit otherSignal(); + m_intProp = val; emit intPropChanged(); + } + +signals: + void intPropChanged(); + void otherSignal(); + +private: + int m_intProp; + int m_changeCount; +}; + +static QObject *module_api_factory(QQmlEngine *engine, QJSEngine *scriptEngine) +{ + Q_UNUSED(engine) + Q_UNUSED(scriptEngine) + MyTestSingletonType *api = new MyTestSingletonType(); + return api; +} + +// QTBUG-20937 +void tst_qqmlconnections::singletonTypeTarget() +{ + qmlRegisterSingletonType<MyTestSingletonType>("MyTestSingletonType", 1, 0, "Api", module_api_factory); + QQmlComponent component(&engine, testFileUrl("singletontype-target.qml")); + QObject *object = component.create(); + QVERIFY(object != 0); + + QCOMPARE(object->property("moduleIntPropChangedCount").toInt(), 0); + QCOMPARE(object->property("moduleOtherSignalCount").toInt(), 0); + + QMetaObject::invokeMethod(object, "setModuleIntProp"); + QCOMPARE(object->property("moduleIntPropChangedCount").toInt(), 1); + QCOMPARE(object->property("moduleOtherSignalCount").toInt(), 0); + + QMetaObject::invokeMethod(object, "setModuleIntProp"); + QCOMPARE(object->property("moduleIntPropChangedCount").toInt(), 2); + QCOMPARE(object->property("moduleOtherSignalCount").toInt(), 0); + + // the singleton Type emits otherSignal every 3 times the int property changes. + QMetaObject::invokeMethod(object, "setModuleIntProp"); + QCOMPARE(object->property("moduleIntPropChangedCount").toInt(), 3); + QCOMPARE(object->property("moduleOtherSignalCount").toInt(), 1); + + delete object; +} + +QTEST_MAIN(tst_qqmlconnections) + +#include "tst_qqmlconnections.moc" |