aboutsummaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorStephen Kelly <stephen.kelly@kdab.com>2012-01-12 20:01:15 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-09-10 11:17:46 +0200
commit59ed8c355b99df0b949003a438ab850274261aa0 (patch)
tree7f019270e9e8457d385d94c6e8a9b1679b396fb2 /tests
parentf20d726766bf5e875f96fc5ce8885afe5c3fae4a (diff)
Make it possible to handle pointers to QObject derived in QML.
This way, properties of QObject derived types can be read in QML code for example: Q_PROPERTY(MyObject* obj READ obj CONSTANT) Previously, only QObject* types could be read by QML: Q_PROPERTY(QObject* obj READ obj CONSTANT) This meant that multiple properties and methods had to be created for classes which were relevant to both QML and non-QML code. This patch lifts that restriction. As a consequence, we can also remove a Q_EXPECT_FAIL from the qqmllanguage unit test. That test was introduced in commit 92562eacbc3c (Allow signal parameters which are custom QML object-types, 2012-07-13) to document knowledge of the limitation while fixing it as much as possible. Task-number: QTBUG-26662 Change-Id: Ic85fa73c6f3655189438ec509765bae2eab9993a Reviewed-by: Alan Alpert (Personal) <416365416c@gmail.com> Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Diffstat (limited to 'tests')
-rw-r--r--tests/auto/qml/qqmlcontext/tst_qqmlcontext.cpp21
-rw-r--r--tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp1
-rw-r--r--tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp58
3 files changed, 77 insertions, 3 deletions
diff --git a/tests/auto/qml/qqmlcontext/tst_qqmlcontext.cpp b/tests/auto/qml/qqmlcontext/tst_qqmlcontext.cpp
index e0c20307a8..4f21231184 100644
--- a/tests/auto/qml/qqmlcontext/tst_qqmlcontext.cpp
+++ b/tests/auto/qml/qqmlcontext/tst_qqmlcontext.cpp
@@ -72,6 +72,7 @@ private slots:
void qtbug_22535();
void evalAfterInvalidate();
+ void qobjectDerived();
private:
QQmlEngine engine;
@@ -659,6 +660,26 @@ void tst_qqmlcontext::evalAfterInvalidate()
QCoreApplication::processEvents();
}
+void tst_qqmlcontext::qobjectDerived()
+{
+ QQmlEngine engine;
+ QQmlComponent component(&engine, testFileUrl("refreshExpressions.qml"));
+
+ CountCommand command;
+ // This test is similar to refreshExpressions, but with the key difference that
+ // we use the QVariant overload of setContextProperty. That way, we test that
+ // QVariant knowledge that it contains a QObject derived pointer is used.
+ engine.rootContext()->setContextProperty("countCommand", QVariant::fromValue(&command));
+
+ // We use a fresh context here to bypass any root-context optimizations in
+ // the engine
+ QQmlContext context(engine.rootContext());
+
+ QObject *o1 = component.create(&context);
+
+ QCOMPARE(command.count, 2);
+}
+
QTEST_MAIN(tst_qqmlcontext)
#include "tst_qqmlcontext.moc"
diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
index 3e2493effe..acb623989a 100644
--- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
+++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
@@ -3016,7 +3016,6 @@ void tst_qqmllanguage::signalParameterTypes()
QQmlComponent component(&engine, testFileUrl("signalParameterTypes.2.qml"));
QObject *obj = component.create();
QVERIFY(obj != 0);
- QEXPECT_FAIL("", "Dynamic connections don't enforce type safety - QTBUG-26662", Abort);
QVERIFY(obj->property("success").toBool());
delete obj;
}
diff --git a/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp b/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp
index 418e2edf27..27c3fd985e 100644
--- a/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp
+++ b/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp
@@ -57,11 +57,24 @@ class MyQmlObject : public QObject
{
Q_OBJECT
public:
- MyQmlObject() {}
+ MyQmlObject(QObject *parent = 0) : QObject(parent) {}
};
QML_DECLARE_TYPE(MyQmlObject);
+class MyQObject : public QObject
+{
+ Q_OBJECT
+public:
+ MyQObject(QObject *parent = 0) : QObject(parent), m_i(0) {}
+
+ int inc() { return ++m_i; }
+
+private:
+ int m_i;
+};
+
+
class MyAttached : public QObject
{
Q_OBJECT
@@ -316,10 +329,11 @@ class PropertyObject : public QObject
Q_PROPERTY(int resettableProperty READ resettableProperty WRITE setResettableProperty RESET resetProperty)
Q_PROPERTY(int propertyWithNotify READ propertyWithNotify WRITE setPropertyWithNotify NOTIFY oddlyNamedNotifySignal)
Q_PROPERTY(MyQmlObject *qmlObject READ qmlObject)
+ Q_PROPERTY(MyQObject *qObject READ qObject WRITE setQObject NOTIFY qObjectChanged)
Q_CLASSINFO("DefaultProperty", "defaultProperty")
public:
- PropertyObject() : m_resetProperty(9) {}
+ PropertyObject() : m_resetProperty(9), m_qObject(0) {}
int defaultProperty() { return 10; }
QRect rectProperty() { return QRect(10, 10, 1, 209); }
@@ -342,9 +356,19 @@ public:
MyQmlObject *qmlObject() { return &m_qmlObject; }
+ MyQObject *qObject() { return m_qObject; }
+ void setQObject(MyQObject *object)
+ {
+ if (m_qObject != object) {
+ m_qObject = object;
+ emit qObjectChanged();
+ }
+ }
+
signals:
void clicked();
void oddlyNamedNotifySignal();
+ void qObjectChanged();
private:
int m_resetProperty;
@@ -353,6 +377,7 @@ private:
QVariantMap m_variantMap;
int m_propertyWithNotify;
MyQmlObject m_qmlObject;
+ MyQObject *m_qObject;
};
QML_DECLARE_TYPE(PropertyObject);
@@ -1130,6 +1155,18 @@ void tst_qqmlproperty::read()
QCOMPARE(p.read(), QVariant());
}
+ // Object property registered with Qt, but not registered with QML.
+ {
+ PropertyObject o;
+ QQmlProperty p(&o, "qObject");
+ QCOMPARE(p.propertyTypeCategory(), QQmlProperty::Object);
+
+ QCOMPARE(p.propertyType(), qMetaTypeId<MyQObject*>());
+ QVariant v = p.read();
+ QVERIFY(v.canConvert(QMetaType::QObjectStar));
+ QVERIFY(qvariant_cast<QObject *>(v) == o.qObject());
+ }
+
// Object property
{
PropertyObject o;
@@ -1387,6 +1424,23 @@ void tst_qqmlproperty::write()
QCOMPARE(p.read(), QVariant(99));
delete object;
}
+ // Writable pointer to QObject derived
+ {
+ PropertyObject o;
+ QQmlProperty p(&o, QString("qObject"));
+ QCOMPARE(o.qObject(), (QObject*)0);
+ QObject *newObject = new MyQObject(this);
+ QCOMPARE(p.write(QVariant::fromValue(newObject)), true);
+ QCOMPARE(o.qObject(), newObject);
+ QVariant data = p.read();
+ QCOMPARE(data.value<QObject*>(), newObject);
+ QCOMPARE(data.value<MyQObject*>(), newObject);
+ // Incompatible types can not be written.
+ QCOMPARE(p.write(QVariant::fromValue(new MyQmlObject(this))), false);
+ QVariant newData = p.read();
+ QCOMPARE(newData.value<QObject*>(), newObject);
+ QCOMPARE(newData.value<MyQObject*>(), newObject);
+ }
}
void tst_qqmlproperty::reset()