aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp')
-rw-r--r--tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp298
1 files changed, 240 insertions, 58 deletions
diff --git a/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp b/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp
index 02399fdcdf..04c2a5bfdb 100644
--- a/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp
+++ b/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <qstandardpaths.h>
#include <qtest.h>
@@ -36,13 +11,16 @@
#include <private/qqmlmetatype_p.h>
#include <private/qqmlpropertyvalueinterceptor_p.h>
#include <private/qqmlengine_p.h>
-#include "../../shared/util.h"
+#include <private/qqmlanybinding_p.h>
+#include <QtQuickTestUtils/private/qmlutils_p.h>
+
+using namespace Qt::StringLiterals;
class tst_qqmlmetatype : public QQmlDataTest
{
Q_OBJECT
public:
- tst_qqmlmetatype() {}
+ tst_qqmlmetatype() : QQmlDataTest(QT_QMLTEST_DATADIR) {}
private slots:
void initTestCase() override;
@@ -57,6 +35,8 @@ private slots:
void compositeType();
void externalEnums();
+ void interceptorAPI();
+
void isList();
void defaultObject();
@@ -69,6 +49,11 @@ private slots:
void enumsInRecursiveImport_data();
void enumsInRecursiveImport();
+
+ void revertValueTypeAnimation();
+
+ void clearPropertyCaches();
+ void builtins();
};
class TestType : public QObject
@@ -116,8 +101,8 @@ QObject *testTypeProvider(QQmlEngine *engine, QJSEngine *scriptEngine)
class ParserStatusTestType : public QObject, public QQmlParserStatus
{
Q_OBJECT
- void classBegin(){}
- void componentComplete(){}
+ void classBegin() override {}
+ void componentComplete() override {}
Q_CLASSINFO("DefaultProperty", "foo") // Missing default property
Q_INTERFACES(QQmlParserStatus)
};
@@ -128,7 +113,7 @@ class ValueSourceTestType : public QObject, public QQmlPropertyValueSource
Q_OBJECT
Q_INTERFACES(QQmlPropertyValueSource)
public:
- virtual void setTarget(const QQmlProperty &) {}
+ void setTarget(const QQmlProperty &) override {}
};
QML_DECLARE_TYPE(ValueSourceTestType);
@@ -137,8 +122,8 @@ class ValueInterceptorTestType : public QObject, public QQmlPropertyValueInterce
Q_OBJECT
Q_INTERFACES(QQmlPropertyValueInterceptor)
public:
- virtual void setTarget(const QQmlProperty &) {}
- virtual void write(const QVariant &) {}
+ void setTarget(const QQmlProperty &) override {}
+ void write(const QVariant &) override {}
};
QML_DECLARE_TYPE(ValueInterceptorTestType);
@@ -157,14 +142,14 @@ void tst_qqmlmetatype::initTestCase()
void tst_qqmlmetatype::qmlParserStatusCast()
{
- QVERIFY(!QQmlMetaType::qmlType(QMetaType::Int).isValid());
- QVERIFY(QQmlMetaType::qmlType(qMetaTypeId<TestType *>()).isValid());
- QCOMPARE(QQmlMetaType::qmlType(qMetaTypeId<TestType *>()).parserStatusCast(), -1);
- QVERIFY(QQmlMetaType::qmlType(qMetaTypeId<ValueSourceTestType *>()).isValid());
- QCOMPARE(QQmlMetaType::qmlType(qMetaTypeId<ValueSourceTestType *>()).parserStatusCast(), -1);
+ QVERIFY(!QQmlMetaType::qmlType(QMetaType::fromType<int>()).isValid());
+ QVERIFY(QQmlMetaType::qmlType(QMetaType::fromType<TestType *>()).isValid());
+ QCOMPARE(QQmlMetaType::qmlType(QMetaType::fromType<TestType *>()).parserStatusCast(), -1);
+ QVERIFY(QQmlMetaType::qmlType(QMetaType::fromType<ValueSourceTestType *>()).isValid());
+ QCOMPARE(QQmlMetaType::qmlType(QMetaType::fromType<ValueSourceTestType *>()).parserStatusCast(), -1);
- QVERIFY(QQmlMetaType::qmlType(qMetaTypeId<ParserStatusTestType *>()).isValid());
- int cast = QQmlMetaType::qmlType(qMetaTypeId<ParserStatusTestType *>()).parserStatusCast();
+ QVERIFY(QQmlMetaType::qmlType(QMetaType::fromType<ParserStatusTestType *>()).isValid());
+ int cast = QQmlMetaType::qmlType(QMetaType::fromType<ParserStatusTestType *>()).parserStatusCast();
QVERIFY(cast != -1);
QVERIFY(cast != 0);
@@ -177,14 +162,14 @@ void tst_qqmlmetatype::qmlParserStatusCast()
void tst_qqmlmetatype::qmlPropertyValueSourceCast()
{
- QVERIFY(!QQmlMetaType::qmlType(QMetaType::Int).isValid());
- QVERIFY(QQmlMetaType::qmlType(qMetaTypeId<TestType *>()).isValid());
- QCOMPARE(QQmlMetaType::qmlType(qMetaTypeId<TestType *>()).propertyValueSourceCast(), -1);
- QVERIFY(QQmlMetaType::qmlType(qMetaTypeId<ParserStatusTestType *>()).isValid());
- QCOMPARE(QQmlMetaType::qmlType(qMetaTypeId<ParserStatusTestType *>()).propertyValueSourceCast(), -1);
+ QVERIFY(!QQmlMetaType::qmlType(QMetaType::fromType<int>()).isValid());
+ QVERIFY(QQmlMetaType::qmlType(QMetaType::fromType<TestType *>()).isValid());
+ QCOMPARE(QQmlMetaType::qmlType(QMetaType::fromType<TestType *>()).propertyValueSourceCast(), -1);
+ QVERIFY(QQmlMetaType::qmlType(QMetaType::fromType<ParserStatusTestType *>()).isValid());
+ QCOMPARE(QQmlMetaType::qmlType(QMetaType::fromType<ParserStatusTestType *>()).propertyValueSourceCast(), -1);
- QVERIFY(QQmlMetaType::qmlType(qMetaTypeId<ValueSourceTestType *>()).isValid());
- int cast = QQmlMetaType::qmlType(qMetaTypeId<ValueSourceTestType *>()).propertyValueSourceCast();
+ QVERIFY(QQmlMetaType::qmlType(QMetaType::fromType<ValueSourceTestType *>()).isValid());
+ int cast = QQmlMetaType::qmlType(QMetaType::fromType<ValueSourceTestType *>()).propertyValueSourceCast();
QVERIFY(cast != -1);
QVERIFY(cast != 0);
@@ -197,14 +182,14 @@ void tst_qqmlmetatype::qmlPropertyValueSourceCast()
void tst_qqmlmetatype::qmlPropertyValueInterceptorCast()
{
- QVERIFY(!QQmlMetaType::qmlType(QMetaType::Int).isValid());
- QVERIFY(QQmlMetaType::qmlType(qMetaTypeId<TestType *>()).isValid());
- QCOMPARE(QQmlMetaType::qmlType(qMetaTypeId<TestType *>()).propertyValueInterceptorCast(), -1);
- QVERIFY(QQmlMetaType::qmlType(qMetaTypeId<ParserStatusTestType *>()).isValid());
- QCOMPARE(QQmlMetaType::qmlType(qMetaTypeId<ParserStatusTestType *>()).propertyValueInterceptorCast(), -1);
+ QVERIFY(!QQmlMetaType::qmlType(QMetaType::fromType<int>()).isValid());
+ QVERIFY(QQmlMetaType::qmlType(QMetaType::fromType<TestType *>()).isValid());
+ QCOMPARE(QQmlMetaType::qmlType(QMetaType::fromType<TestType *>()).propertyValueInterceptorCast(), -1);
+ QVERIFY(QQmlMetaType::qmlType(QMetaType::fromType<ParserStatusTestType *>()).isValid());
+ QCOMPARE(QQmlMetaType::qmlType(QMetaType::fromType<ParserStatusTestType *>()).propertyValueInterceptorCast(), -1);
- QVERIFY(QQmlMetaType::qmlType(qMetaTypeId<ValueInterceptorTestType *>()).isValid());
- int cast = QQmlMetaType::qmlType(qMetaTypeId<ValueInterceptorTestType *>()).propertyValueInterceptorCast();
+ QVERIFY(QQmlMetaType::qmlType(QMetaType::fromType<ValueInterceptorTestType *>()).isValid());
+ int cast = QQmlMetaType::qmlType(QMetaType::fromType<ValueInterceptorTestType *>()).propertyValueInterceptorCast();
QVERIFY(cast != -1);
QVERIFY(cast != 0);
@@ -257,9 +242,9 @@ void tst_qqmlmetatype::prettyTypeName()
void tst_qqmlmetatype::isList()
{
- QCOMPARE(QQmlMetaType::isList(QMetaType::UnknownType), false);
- QCOMPARE(QQmlMetaType::isList(QMetaType::Int), false);
- QCOMPARE(QQmlMetaType::isList(qMetaTypeId<QQmlListProperty<TestType> >()), true);
+ QCOMPARE(QQmlMetaType::isList(QMetaType {}), false);
+ QCOMPARE(QQmlMetaType::isList(QMetaType::fromType<int>()), false);
+ QCOMPARE(QQmlMetaType::isList(QMetaType::fromType<QQmlListProperty<TestType> >()), true);
}
void tst_qqmlmetatype::defaultObject()
@@ -337,6 +322,60 @@ void tst_qqmlmetatype::externalEnums()
}
+class ForwardAndLogInterceptor : public QObject, public QQmlPropertyValueInterceptor {
+ Q_OBJECT
+ Q_INTERFACES(QQmlPropertyValueInterceptor)
+public:
+
+ // QQmlPropertyValueInterceptor interface
+ void setTarget(const QQmlProperty &property) override
+ {
+ m_property = property;
+ }
+ void write(const QVariant &value) override
+ {
+ interceptedWrite = true;
+ QQmlPropertyPrivate::write(m_property, value, QQmlPropertyData::BypassInterceptor);
+ }
+ bool bindable(QUntypedBindable *bindable, QUntypedBindable target) override
+ {
+ interceptedBindable = true;
+ *bindable = target;
+ return true;
+ }
+
+ QQmlProperty m_property;
+ bool interceptedBindable = false;
+ bool interceptedWrite = false;
+};
+
+void tst_qqmlmetatype::interceptorAPI()
+{
+ qmlRegisterType<ForwardAndLogInterceptor>("test", 1, 0, "Interceptor");
+ QQmlEngine engine;
+ QQmlComponent component(&engine, testFileUrl("interceptorApi.qml"));
+ QScopedPointer<QObject> obj(component.create());
+ QVERIFY2(obj, qPrintable(component.errorString()));
+
+ auto interceptor = obj->property("i").value<ForwardAndLogInterceptor *>();
+ QVERIFY(interceptor->interceptedBindable);
+ QVERIFY(interceptor->interceptedWrite);
+
+ QQmlProperty objectName(obj.get(), "objectName");
+ QProperty<QString> hello(u"Hello, World!"_s);
+ QQmlAnyBinding binding;
+ binding = Qt::makePropertyBinding(hello);
+ interceptor->interceptedBindable = false;
+ binding.installOn(objectName, QQmlAnyBinding::RespectInterceptors);
+ QVERIFY(interceptor->interceptedBindable);
+ binding = QQmlAnyBinding::takeFrom(objectName);
+ objectName.write("bar");
+ interceptor->interceptedBindable = false;
+ binding.installOn(objectName, QQmlAnyBinding::IgnoreInterceptors);
+ QVERIFY(!interceptor->interceptedBindable);
+ QCOMPARE(objectName.read().toString(), hello.value());
+}
+
class Controller1 : public QObject
{
Q_OBJECT
@@ -573,6 +612,7 @@ class Grouped : public QObject
{
Q_OBJECT
Q_PROPERTY(int prop READ prop WRITE setProp NOTIFY propChanged REVISION 1)
+ Q_PROPERTY(int prop2 READ prop WRITE setProp NOTIFY prop2Changed REVISION 2)
public:
int prop() const { return m_prop; }
void setProp(int prop)
@@ -580,11 +620,13 @@ public:
if (prop != m_prop) {
m_prop = prop;
emit propChanged(prop);
+ emit prop2Changed(prop);
}
}
signals:
Q_REVISION(1) void propChanged(int prop);
+ Q_REVISION(2) void prop2Changed(int prop);
private:
int m_prop = 0;
@@ -602,13 +644,24 @@ private:
QScopedPointer<Grouped> m_grouped;
};
+class MyRevisioned : public MyItem
+{
+ Q_OBJECT
+ Q_PROPERTY(int revisioned READ revisioned CONSTANT REVISION 1)
+public:
+ int revisioned() const { return 12; }
+};
+
void tst_qqmlmetatype::revisionedGroupedProperties()
{
qmlClearTypeRegistrations();
qmlRegisterType<MyItem>("GroupedTest", 1, 0, "MyItem");
qmlRegisterType<MyItem, 1>("GroupedTest", 1, 1, "MyItem");
+ qmlRegisterType<MyRevisioned>("GroupedTest", 1, 0, "MyRevisioned");
+ qmlRegisterType<MyRevisioned, 1>("GroupedTest", 1, 1, "MyRevisioned");
qmlRegisterUncreatableType<Grouped>("GroupedTest", 1, 0, "Grouped", "Grouped");
qmlRegisterUncreatableType<Grouped, 1>("GroupedTest", 1, 1, "Grouped", "Grouped");
+ qmlRegisterUncreatableType<Grouped, 2>("GroupedTest", 1, 2, "Grouped", "Grouped");
{
QQmlEngine engine;
@@ -623,6 +676,15 @@ void tst_qqmlmetatype::revisionedGroupedProperties()
QQmlComponent invalid(&engine, testFileUrl("revisionedGroupedPropertiesInvalid.qml"));
QVERIFY(invalid.isError());
}
+
+ {
+ QQmlEngine engine;
+ QQmlComponent unversioned(
+ &engine, testFileUrl("revisionedGroupedPropertiesUnversioned.qml"));
+ QVERIFY2(unversioned.isReady(), qPrintable(unversioned.errorString()));
+ QScopedPointer<QObject> obj(unversioned.create());
+ QVERIFY(!obj.isNull());
+ }
}
void tst_qqmlmetatype::enumsInRecursiveImport_data()
@@ -654,6 +716,126 @@ void tst_qqmlmetatype::enumsInRecursiveImport()
QTRY_COMPARE(obj->property("color").toString(), QString("green"));
}
+void tst_qqmlmetatype::revertValueTypeAnimation()
+{
+ QQmlEngine engine;
+ QQmlComponent c(&engine, testFileUrl("animationOnValueType.qml"));
+ QVERIFY2(c.isReady(), qPrintable(c.errorString()));
+
+ QScopedPointer<QObject> o(c.create());
+ QTRY_COMPARE(o->property("letterSpacing").toDouble(), 24.0);
+ QCOMPARE(o->property("pointSize").toDouble(), 12.0);
+}
+
+void tst_qqmlmetatype::clearPropertyCaches()
+{
+ qmlClearTypeRegistrations();
+ qmlRegisterType<TestType>("ClearPropertyCaches", 1, 0, "A");
+ QQmlPropertyCache::ConstPtr oldCache = QQmlMetaType::propertyCache(&TestType::staticMetaObject);
+ QVERIFY(oldCache);
+ qmlClearTypeRegistrations();
+ qmlRegisterType<TestType>("ClearPropertyCaches", 1, 0, "B");
+ QQmlPropertyCache::ConstPtr newCache = QQmlMetaType::propertyCache(&TestType::staticMetaObject);
+ QVERIFY(oldCache.data() != newCache.data());
+}
+
+template<typename T>
+void checkBuiltinBaseType()
+{
+ const QQmlType type = QQmlMetaType::qmlType(QMetaType::fromType<T>());
+ QVERIFY(type.isValid());
+ QCOMPARE(type.typeId(), QMetaType::fromType<T>());
+ QCOMPARE(type.qListTypeId(), QMetaType::fromType<QList<T>>());
+}
+
+template<typename T>
+void checkBuiltinListType()
+{
+ const QQmlType listType = QQmlMetaType::qmlListType(QMetaType::fromType<QList<T>>());
+ QVERIFY(listType.isValid());
+ QVERIFY(listType.isSequentialContainer());
+ QCOMPARE(listType.typeId(), QMetaType::fromType<T>());
+ QCOMPARE(listType.qListTypeId(), QMetaType::fromType<QList<T>>());
+ QCOMPARE(listType.listMetaSequence().valueMetaType(), QMetaType::fromType<T>());
+}
+
+template<typename... T>
+void checkBuiltinTypes()
+{
+ (checkBuiltinBaseType<T>(), ...);
+ (checkBuiltinListType<T>(), ...);
+}
+
+template<typename T>
+void checkNamedBuiltin(const QString &name)
+{
+ const QQmlType expected = QQmlMetaType::qmlType(QMetaType::fromType<T>());
+ const QQmlType actual = QQmlMetaType::qmlType("QML/" + name, QTypeRevision::fromVersion(1, 0));
+ if (actual != expected) {
+ qWarning() << Q_FUNC_INFO << "looking for" << name;
+ qWarning() << "found" << actual.module() << actual.elementName() << actual.version()
+ << actual.typeId();
+ qWarning() << "expected" << expected.module() << expected.elementName()
+ << expected.version() << expected.typeId();
+ QFAIL("mismatch");
+ }
+}
+
+template<typename T>
+void checkObjectBuiltin(const QString &name)
+{
+ const QQmlType objectType = QQmlMetaType::qmlType(QMetaType::fromType<T *>());
+ QVERIFY(objectType.isValid());
+ QCOMPARE(objectType.typeId(), QMetaType::fromType<T *>());
+ QCOMPARE(objectType.qListTypeId(), QMetaType::fromType<QQmlListProperty<T>>());
+
+ const QQmlType listType = QQmlMetaType::qmlListType(QMetaType::fromType<QQmlListProperty<T>>());
+ QVERIFY(listType.isValid());
+ QCOMPARE(listType.typeId(), QMetaType::fromType<T *>());
+ QCOMPARE(listType.qListTypeId(), QMetaType::fromType<QQmlListProperty<T>>());
+
+ checkNamedBuiltin<T *>(name);
+}
+
+void tst_qqmlmetatype::builtins()
+{
+ qmlClearTypeRegistrations();
+ QQmlEngine engine; // registers the builtins
+
+ checkBuiltinTypes<
+ QVariant, QJSValue, qint8, quint8, short, ushort, int, uint, qlonglong, qulonglong, float,
+ double, QChar, QString, bool, QDateTime, QDate, QTime, QUrl, QByteArray>();
+
+ checkNamedBuiltin<QVariant>("var");
+ checkNamedBuiltin<QVariant>("variant");
+ checkNamedBuiltin<int>("int");
+ checkNamedBuiltin<double>("double");
+ checkNamedBuiltin<double>("real");
+ checkNamedBuiltin<QString>("string");
+ checkNamedBuiltin<bool>("bool");
+ checkNamedBuiltin<QDateTime>("date");
+ checkNamedBuiltin<QUrl>("url");
+
+#if QT_CONFIG(regularexpression)
+ checkBuiltinBaseType<QRegularExpression>();
+ checkBuiltinListType<QRegularExpression>();
+ checkNamedBuiltin<QRegularExpression>("regexp");
+#endif
+
+ // Can't retrieve this one by metatype
+ const QQmlType voidType = QQmlMetaType::qmlType("QML/void", QTypeRevision::fromVersion(1, 0));
+ QVERIFY(voidType.isValid());
+ QCOMPARE(voidType.typeId(), QMetaType());
+ QCOMPARE(voidType.qListTypeId(), QMetaType());
+
+ // No separate list types
+ checkBuiltinBaseType<std::nullptr_t>();
+ checkBuiltinBaseType<QVariantMap>();
+
+ checkObjectBuiltin<QObject>("QtObject");
+ checkObjectBuiltin<QQmlComponent>("Component");
+}
+
QTEST_MAIN(tst_qqmlmetatype)
#include "tst_qqmlmetatype.moc"