aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto/qml/qmltyperegistrar
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/qml/qmltyperegistrar')
-rw-r--r--tests/auto/qml/qmltyperegistrar/CMakeLists.txt28
-rw-r--r--tests/auto/qml/qmltyperegistrar/UnregisteredTypes/CMakeLists.txt4
-rw-r--r--tests/auto/qml/qmltyperegistrar/UnregisteredTypes/uncreatable.h51
-rw-r--r--tests/auto/qml/qmltyperegistrar/VersionZero/version_zero_type.h2
-rw-r--r--tests/auto/qml/qmltyperegistrar/duplicatedExports.h2
-rw-r--r--tests/auto/qml/qmltyperegistrar/enum.cpp5
-rw-r--r--tests/auto/qml/qmltyperegistrar/enum.h40
-rw-r--r--tests/auto/qml/qmltyperegistrar/foo.cpp2
-rw-r--r--tests/auto/qml/qmltyperegistrar/foo.h2
-rw-r--r--tests/auto/qml/qmltyperegistrar/foreign/CMakeLists.txt3
-rw-r--r--tests/auto/qml/qmltyperegistrar/foreign/foreign.cpp2
-rw-r--r--tests/auto/qml/qmltyperegistrar/foreign/foreign.h2
-rw-r--r--tests/auto/qml/qmltyperegistrar/foreign/private/foreign_p.h (renamed from tests/auto/qml/qmltyperegistrar/foreign/foreign_p.h)3
-rw-r--r--tests/auto/qml/qmltyperegistrar/hppheader.hpp2
-rw-r--r--tests/auto/qml/qmltyperegistrar/missingTypes.json167
-rw-r--r--tests/auto/qml/qmltyperegistrar/noextheader2
-rw-r--r--tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.cpp651
-rw-r--r--tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.h388
18 files changed, 1272 insertions, 84 deletions
diff --git a/tests/auto/qml/qmltyperegistrar/CMakeLists.txt b/tests/auto/qml/qmltyperegistrar/CMakeLists.txt
index 039f1647db..45669769e4 100644
--- a/tests/auto/qml/qmltyperegistrar/CMakeLists.txt
+++ b/tests/auto/qml/qmltyperegistrar/CMakeLists.txt
@@ -7,12 +7,18 @@
## tst_qmltyperegistrar Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qmltyperegistrar LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
add_subdirectory(VersionZero)
add_subdirectory(UnregisteredTypes)
add_subdirectory(foreign)
qt_manual_moc(moc_files OUTPUT_MOC_JSON_FILES json_list noextheader
- INCLUDE_DIRECTORY_TARGETS Qt::Qml)
+ TARGETS Qt6::Qml)
# Dummy target to pass --private-includes to qmltyperegistrar for tst_qmltyperegistrar.
# We want to test that it expects files named foo_p.h appearing in foreign metatypes
@@ -76,9 +82,11 @@ qt_add_library(tst-qmltyperegistrar-with-dashes)
qt_autogen_tools_initial_setup(tst-qmltyperegistrar-with-dashes)
target_link_libraries(tst-qmltyperegistrar-with-dashes PRIVATE Qt::Core Qt::Qml)
qt_enable_autogen_tool(tst-qmltyperegistrar-with-dashes "moc" ON)
+
+qt_policy(SET QTP0001 NEW)
+
qt_add_qml_module(tst-qmltyperegistrar-with-dashes
URI Module-With-Dashes
- AUTO_RESOURCE_PREFIX
SOURCES
foo.cpp foo.h
OUTPUT_DIRECTORY Module-With-Dashes
@@ -90,4 +98,20 @@ qt_internal_add_resource(tst_qmltyperegistrar "resources"
"/"
FILES
duplicatedExports.json
+ missingTypes.json
)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+qt_add_library(tst-qmltyperegistrar-enum-foreign STATIC enum.cpp)
+qt_autogen_tools_initial_setup(tst-qmltyperegistrar-enum-foreign)
+qt_enable_autogen_tool(tst-qmltyperegistrar-enum-foreign "moc" ON)
+target_link_libraries(tst-qmltyperegistrar-enum-foreign PRIVATE Qt::QmlIntegration)
+
+qt_add_library(tst-qmltyperegistrar-enum STATIC)
+qt_autogen_tools_initial_setup(tst-qmltyperegistrar-enum)
+qt_enable_autogen_tool(tst-qmltyperegistrar-enum "moc" ON)
+target_link_libraries(tst-qmltyperegistrar-enum PRIVATE Qt::Qml tst-qmltyperegistrar-enum-foreign)
+
+qt_add_qml_module(tst-qmltyperegistrar-enum URI TstEnum OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/TstEnum)
+qt_autogen_tools_initial_setup(tst-qmltyperegistrar-enumplugin)
+qt_generate_foreign_qml_types(tst-qmltyperegistrar-enum-foreign tst-qmltyperegistrar-enum)
diff --git a/tests/auto/qml/qmltyperegistrar/UnregisteredTypes/CMakeLists.txt b/tests/auto/qml/qmltyperegistrar/UnregisteredTypes/CMakeLists.txt
index cb020e95e0..d469f1e97f 100644
--- a/tests/auto/qml/qmltyperegistrar/UnregisteredTypes/CMakeLists.txt
+++ b/tests/auto/qml/qmltyperegistrar/UnregisteredTypes/CMakeLists.txt
@@ -2,13 +2,15 @@
# SPDX-License-Identifier: BSD-3-Clause
# Use NO_GENERATE_QMLTYPES to avoid static asserts during compilation of the types to be tested, same for NO_PLUGIN
+
+qt_policy(SET QTP0001 NEW)
+
qt_add_qml_module(UnregisteredTypes
STATIC
URI UnregisteredTypes
NO_GENERATE_QMLTYPES
NO_PLUGIN
SOURCES uncreatable.h
- AUTO_RESOURCE_PREFIX
)
qt_enable_autogen_tool(UnregisteredTypes "moc" ON)
diff --git a/tests/auto/qml/qmltyperegistrar/UnregisteredTypes/uncreatable.h b/tests/auto/qml/qmltyperegistrar/UnregisteredTypes/uncreatable.h
index 9726f4683c..2274f87e3d 100644
--- a/tests/auto/qml/qmltyperegistrar/UnregisteredTypes/uncreatable.h
+++ b/tests/auto/qml/qmltyperegistrar/UnregisteredTypes/uncreatable.h
@@ -1,5 +1,5 @@
// Copyright (C) 2021 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#ifndef UNCREATABLE_H
#define UNCREATABLE_H
@@ -39,6 +39,39 @@ public:
static SingletonCreatable3 *create(QQmlEngine *, QJSEngine *) { return nullptr; }
};
+class SingletonForeign : public QObject
+{
+ Q_OBJECT
+ SingletonForeign() = delete;
+};
+
+class SingletonLocalCreatable
+{
+ Q_GADGET
+ QML_FOREIGN(SingletonForeign)
+ QML_ELEMENT
+ QML_SINGLETON
+public:
+ static SingletonForeign *create(QQmlEngine *, QJSEngine *) { return nullptr; }
+};
+
+class SingletonLocalUncreatable1
+{
+ Q_GADGET
+ QML_FOREIGN(SingletonForeign)
+ QML_ELEMENT
+ QML_SINGLETON
+ static SingletonForeign *create(QQmlEngine *, QJSEngine *) { return nullptr; }
+};
+
+class SingletonLocalUncreatable2
+{
+ Q_GADGET
+ QML_FOREIGN(SingletonForeign)
+ QML_ELEMENT
+ QML_SINGLETON
+};
+
class SingletonIncreatable : public QObject
{
Q_OBJECT
@@ -184,4 +217,20 @@ class FixingBadUncreatable
QML_FOREIGN(BadUncreatable)
QML_UNCREATABLE("")
};
+
+class SingletonVesion0 : public QObject
+{
+ Q_OBJECT
+ QML_ELEMENT
+ QML_SINGLETON
+ // is default constructible
+};
+
+class SingletonVesion1 : public QObject
+{
+ Q_OBJECT
+ QML_ELEMENT
+ QML_SINGLETON
+ // is default constructible
+};
#endif // UNCREATABLE_H
diff --git a/tests/auto/qml/qmltyperegistrar/VersionZero/version_zero_type.h b/tests/auto/qml/qmltyperegistrar/VersionZero/version_zero_type.h
index a3277e6ab3..0ad477c3cb 100644
--- a/tests/auto/qml/qmltyperegistrar/VersionZero/version_zero_type.h
+++ b/tests/auto/qml/qmltyperegistrar/VersionZero/version_zero_type.h
@@ -1,5 +1,5 @@
// Copyright (C) 2022 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#ifndef VERSION_ZERO_TYPE_H
#define VERSION_ZERO_TYPE_H
diff --git a/tests/auto/qml/qmltyperegistrar/duplicatedExports.h b/tests/auto/qml/qmltyperegistrar/duplicatedExports.h
index 5ae2e77551..e72a2f19c9 100644
--- a/tests/auto/qml/qmltyperegistrar/duplicatedExports.h
+++ b/tests/auto/qml/qmltyperegistrar/duplicatedExports.h
@@ -1,5 +1,5 @@
// Copyright (C) 2021 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#ifndef DUPLICATEDEXPORTS_H
#define DUPLICATEDEXPORTS_H
diff --git a/tests/auto/qml/qmltyperegistrar/enum.cpp b/tests/auto/qml/qmltyperegistrar/enum.cpp
new file mode 100644
index 0000000000..34d2e00ffa
--- /dev/null
+++ b/tests/auto/qml/qmltyperegistrar/enum.cpp
@@ -0,0 +1,5 @@
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include "enum.h"
+#include "moc_enum.cpp"
diff --git a/tests/auto/qml/qmltyperegistrar/enum.h b/tests/auto/qml/qmltyperegistrar/enum.h
new file mode 100644
index 0000000000..653c48c79f
--- /dev/null
+++ b/tests/auto/qml/qmltyperegistrar/enum.h
@@ -0,0 +1,40 @@
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#ifndef ENUM_NS_HELLO_H
+#define ENUM_NS_HELLO_H
+
+#include <QObject>
+#include <QtQmlIntegration/qqmlintegration.h>
+
+namespace Hello {
+ Q_NAMESPACE
+ QML_NAMED_ELEMENT(World)
+ enum class World {
+ Europe = 2024,
+ };
+ Q_ENUM_NS(World)
+}
+
+namespace Universe {
+ namespace Galaxy {
+ Q_NAMESPACE
+ QML_NAMED_ELEMENT(Solar)
+ enum class Solar {
+ Earth,
+ };
+ Q_ENUM_NS(Solar)
+ }
+
+ class Blackhole {
+ Q_GADGET
+ QML_ELEMENT
+ public:
+ enum SagittariusA {
+ Singularity
+ };
+ Q_ENUM(SagittariusA)
+ };
+}
+
+#endif // ENUM_NS_HELLO_H
diff --git a/tests/auto/qml/qmltyperegistrar/foo.cpp b/tests/auto/qml/qmltyperegistrar/foo.cpp
index ba95235bd6..c5ef8313dc 100644
--- a/tests/auto/qml/qmltyperegistrar/foo.cpp
+++ b/tests/auto/qml/qmltyperegistrar/foo.cpp
@@ -1,5 +1,5 @@
// Copyright (C) 2021 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include "foo.h"
#include <QDebug>
diff --git a/tests/auto/qml/qmltyperegistrar/foo.h b/tests/auto/qml/qmltyperegistrar/foo.h
index 7872c35c17..5af2e11eaa 100644
--- a/tests/auto/qml/qmltyperegistrar/foo.h
+++ b/tests/auto/qml/qmltyperegistrar/foo.h
@@ -1,5 +1,5 @@
// Copyright (C) 2021 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#ifndef FOO_H
#define FOO_H
diff --git a/tests/auto/qml/qmltyperegistrar/foreign/CMakeLists.txt b/tests/auto/qml/qmltyperegistrar/foreign/CMakeLists.txt
index 5334225692..68223ae6a5 100644
--- a/tests/auto/qml/qmltyperegistrar/foreign/CMakeLists.txt
+++ b/tests/auto/qml/qmltyperegistrar/foreign/CMakeLists.txt
@@ -10,7 +10,8 @@
qt_internal_add_cmake_library(foreign
STATIC
SOURCES
- foreign.cpp foreign.h foreign_p.h
+ foreign.cpp foreign.h
+ private/foreign_p.h
PUBLIC_LIBRARIES
Qt::Core
)
diff --git a/tests/auto/qml/qmltyperegistrar/foreign/foreign.cpp b/tests/auto/qml/qmltyperegistrar/foreign/foreign.cpp
index f78dd47237..1691f5396a 100644
--- a/tests/auto/qml/qmltyperegistrar/foreign/foreign.cpp
+++ b/tests/auto/qml/qmltyperegistrar/foreign/foreign.cpp
@@ -1,5 +1,5 @@
// Copyright (C) 2020 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include "foreign.h"
diff --git a/tests/auto/qml/qmltyperegistrar/foreign/foreign.h b/tests/auto/qml/qmltyperegistrar/foreign/foreign.h
index ea78a58432..79ac8074cf 100644
--- a/tests/auto/qml/qmltyperegistrar/foreign/foreign.h
+++ b/tests/auto/qml/qmltyperegistrar/foreign/foreign.h
@@ -1,5 +1,5 @@
// Copyright (C) 2020 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#ifndef FOREIGN_H
#define FOREIGN_H
diff --git a/tests/auto/qml/qmltyperegistrar/foreign/foreign_p.h b/tests/auto/qml/qmltyperegistrar/foreign/private/foreign_p.h
index fe7986471f..ed23d78284 100644
--- a/tests/auto/qml/qmltyperegistrar/foreign/foreign_p.h
+++ b/tests/auto/qml/qmltyperegistrar/foreign/private/foreign_p.h
@@ -1,5 +1,5 @@
// Copyright (C) 2021 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#ifndef FOREIGN_P_H
#define FOREIGN_P_H
@@ -7,7 +7,6 @@
#include <QtCore/qobject.h>
// qmltyperegistrar will assume this file is reachable under <private/foreign_p.h>
-// It's not true, but this is how it works on actual private headers in Qt.
// See the trick in tst_qmltyperegistrar's CMakeLists.txt to turn on the --private-includes option.
class ForeignPrivate : public QObject
{
diff --git a/tests/auto/qml/qmltyperegistrar/hppheader.hpp b/tests/auto/qml/qmltyperegistrar/hppheader.hpp
index dc82fc8530..4278601a9e 100644
--- a/tests/auto/qml/qmltyperegistrar/hppheader.hpp
+++ b/tests/auto/qml/qmltyperegistrar/hppheader.hpp
@@ -1,5 +1,5 @@
// Copyright (C) 2021 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#ifndef HPPHEADER_HPP
#define HPPHEADER_HPP
diff --git a/tests/auto/qml/qmltyperegistrar/missingTypes.json b/tests/auto/qml/qmltyperegistrar/missingTypes.json
new file mode 100644
index 0000000000..dacec11c4c
--- /dev/null
+++ b/tests/auto/qml/qmltyperegistrar/missingTypes.json
@@ -0,0 +1,167 @@
+[
+ {
+ "classes": [
+ {
+ "classInfos": [
+ {
+ "name": "QML.Element",
+ "value": "int"
+ },
+ {
+ "name": "QML.Extended",
+ "value": "QQmlIntForeign"
+ },
+ {
+ "name": "QML.Foreign",
+ "value": "int"
+ }
+ ],
+ "className": "QQmlIntForeign",
+ "gadget": true,
+ "qualifiedClassName": "QQmlIntForeign"
+ },
+ {
+ "classInfos": [
+ {
+ "name": "QML.Element",
+ "value": "auto"
+ }
+ ],
+ "className": "ExcessiveVersion",
+ "object": true,
+ "properties": [
+ {
+ "constant": false,
+ "designable": true,
+ "final": false,
+ "index": 0,
+ "name": "palette",
+ "notify": "paletteChanged",
+ "read": "palette",
+ "required": false,
+ "revision": 1536,
+ "scriptable": true,
+ "stored": true,
+ "type": "int",
+ "user": false,
+ "write": "setPalette"
+ }
+ ],
+ "enums": [
+ {
+ "isClass": false,
+ "isFlag": false,
+ "name": "RestorationMode",
+ "type": "NotAnUnderlyingType",
+ "values": [
+ "RestoreNone",
+ "RestoreBinding",
+ "RestoreValue",
+ "RestoreBindingOrValue"
+ ]
+ }
+ ],
+ "qualifiedClassName": "ExcessiveVersion",
+ "signals": [
+ {
+ "access": "public",
+ "name": "paletteChanged",
+ "returnType": "void",
+ "revision": 1536
+ }
+ ],
+ "superClasses": [
+ {
+ "access": "public",
+ "name": "NotQObject"
+ }
+ ]
+ },
+ {
+ "classInfos": [
+ {
+ "name": "QML.Element",
+ "value": "Versioned"
+ },
+ {
+ "name": "QML.AddedInVersion",
+ "value": "264"
+ }
+ ],
+ "className": "AddedInLateVersion",
+ "object": true,
+ "properties": [
+ {
+ "constant": true,
+ "designable": true,
+ "final": false,
+ "index": 0,
+ "name": "revisioned",
+ "read": "revisioned",
+ "required": false,
+ "revision": 260,
+ "scriptable": true,
+ "stored": true,
+ "type": "NotAPropertyType",
+ "user": false
+ }
+ ],
+ "methods": [
+ {
+ "access": "public",
+ "arguments": [
+ {
+ "type": "NotAnArgumentType"
+ }
+ ],
+ "name": "createAThing",
+ "returnType": "NotAReturnType"
+ }
+ ],
+ "qualifiedClassName": "AddedInLateVersion",
+ "superClasses": [
+ {
+ "access": "public",
+ "name": "NotQObject"
+ }
+ ]
+ },
+ {
+ "classInfos": [
+ {
+ "name": "QML.Foreign",
+ "value": "Invisible"
+ },
+ {
+ "name": "QML.Element",
+ "value": "Invisible"
+ }
+ ],
+ "className": "InvisibleForeign",
+ "gadget": true,
+ "qualifiedClassName": "InvisibleForeign"
+ },
+ {
+ "classInfos": [
+ {
+ "name": "QML.Element",
+ "value": "anonymous"
+ },
+ {
+ "name": "QML.Sequence",
+ "value": "NotQByteArray"
+ },
+ {
+ "name": "QML.Foreign",
+ "value": "std::vector<NotQByteArray>"
+ }
+ ],
+ "className": "NotQByteArrayStdVectorForeign",
+ "gadget": true,
+ "qualifiedClassName": "NotQByteArrayStdVectorForeign"
+ }
+ ],
+ "inputFile": "tst_qmltyperegistrar.h",
+ "outputRevision": 68
+ }
+]
diff --git a/tests/auto/qml/qmltyperegistrar/noextheader b/tests/auto/qml/qmltyperegistrar/noextheader
index 1bad168044..2b3579a34b 100644
--- a/tests/auto/qml/qmltyperegistrar/noextheader
+++ b/tests/auto/qml/qmltyperegistrar/noextheader
@@ -1,5 +1,5 @@
// Copyright (C) 2020 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#ifndef NOEXTHEADER
#define NOEXTHEADER
diff --git a/tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.cpp b/tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.cpp
index a0f9a92b5c..e79e9b84b6 100644
--- a/tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.cpp
+++ b/tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.cpp
@@ -1,5 +1,5 @@
// Copyright (C) 2021 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include "tst_qmltyperegistrar.h"
#include <QtTest/qtest.h>
@@ -116,8 +116,8 @@ void tst_qmltyperegistrar::pastMajorVersions()
void tst_qmltyperegistrar::implementsInterfaces()
{
- QVERIFY(qmltypesData.contains("interfaces: [\"Interface\"]"));
- QVERIFY(qmltypesData.contains("interfaces: [\"Interface\", \"Interface2\"]"));
+ QVERIFY(qmltypesData.contains("interfaces: [\"Interface1\"]"));
+ QVERIFY(qmltypesData.contains("interfaces: [\"Interface1\", \"Interface2\"]"));
}
void tst_qmltyperegistrar::namespacedElement()
@@ -145,9 +145,9 @@ void tst_qmltyperegistrar::metaTypesRegistered()
auto verifyMetaType = [](const char *name, const char *className) {
const auto foundMetaType = QMetaType::fromName(name);
- QVERIFY(foundMetaType.isValid());
+ QVERIFY2(foundMetaType.isValid(), name);
QCOMPARE(foundMetaType.name(), name);
- QVERIFY(foundMetaType.metaObject());
+ QVERIFY2(foundMetaType.metaObject(), name);
QCOMPARE(foundMetaType.metaObject()->className(), className);
};
@@ -356,6 +356,12 @@ void tst_qmltyperegistrar::addRemoveVersion()
QCOMPARE(o->property("thing").toInt(), thingAccessible ? 24 : 0);
}
+void tst_qmltyperegistrar::addInMinorVersion()
+{
+ QVERIFY(qmltypesData.contains("exports: [\"QmlTypeRegistrarTest/MinorVersioned 1.5\"]"));
+ QVERIFY(qmltypesData.contains("exports: [\"QmlTypeRegistrarTest/MinorVersioned 1.2\"]"));
+}
+
#ifdef QT_QUICK_LIB
void tst_qmltyperegistrar::foreignRevisionedProperty()
{
@@ -398,23 +404,83 @@ void tst_qmltyperegistrar::duplicateExportWarnings()
MetaTypesJsonProcessor processor(true);
QVERIFY(processor.processTypes({ ":/duplicatedExports.json" }));
processor.postProcessTypes();
- QVector<QJsonObject> types = processor.types();
- QVector<QJsonObject> typesforeign = processor.foreignTypes();
+ QVector<MetaType> types = processor.types();
+ QVector<MetaType> typesforeign = processor.foreignTypes();
r.setTypes(types, typesforeign);
- auto expectWarning = [](QString message) {
- QTest::ignoreMessage(QtWarningMsg, qPrintable(message));
+ const auto expectWarning = [](const char *message) {
+ QTest::ignoreMessage(QtWarningMsg, message);
};
- expectWarning("Warning: ExportedQmlElement was registered multiple times by following Cpp "
- "classes: ExportedQmlElement, ExportedQmlElement2 (added in 1.2), "
- "ExportedQmlElementDifferentVersion (added in 1.0) (removed in 1.7)");
- expectWarning("Warning: SameNameSameExport was registered multiple times by following Cpp "
- "classes: SameNameSameExport, SameNameSameExport2 (added in 1.2), "
- "SameNameSameExportDifferentVersion (added in 1.0)");
+ expectWarning("Warning: duplicatedExports.h:: ExportedQmlElement is registered multiple times "
+ "by the following C++ classes: ExportedQmlElement, ExportedQmlElement2 "
+ "(added in 1.2), ExportedQmlElementDifferentVersion (added in 1.0) "
+ "(removed in 1.7)");
+ expectWarning("Warning: duplicatedExports.h:: SameNameSameExport is registered multiple times "
+ "by the following C++ classes: SameNameSameExport, SameNameSameExport2 "
+ "(added in 1.2), SameNameSameExportDifferentVersion (added in 1.0)");
QString outputData;
QTextStream output(&outputData, QIODeviceBase::ReadWrite);
- r.write(output);
+ r.write(output, "tst_qmltyperegistrar_qmltyperegistrations.cpp");
+}
+
+void tst_qmltyperegistrar::consistencyWarnings()
+{
+ QmlTypeRegistrar r;
+ r.setModuleVersions(QTypeRevision::fromVersion(1, 1), {}, false);
+ QString moduleName = "tstmodule";
+ QString targetNamespace = "tstnamespace";
+ r.setModuleNameAndNamespace(moduleName, targetNamespace);
+
+ MetaTypesJsonProcessor processor(true);
+
+ QVERIFY(processor.processTypes({ ":/missingTypes.json" }));
+ processor.postProcessTypes();
+
+ const auto expectWarning = [](const char *message) {
+ QTest::ignoreMessage(QtWarningMsg, message);
+ };
+
+ expectWarning("Warning: tst_qmltyperegistrar.h:: "
+ "NotQObject is used as base type but cannot be found.");
+ expectWarning("Warning: tst_qmltyperegistrar.h:: NotQObject is used as base type "
+ "but cannot be found.");
+ expectWarning("Warning: tst_qmltyperegistrar.h:: Invisible is declared as foreign type, "
+ "but cannot be found.");
+ expectWarning("Warning: tst_qmltyperegistrar.h:: NotQByteArray is used as sequence value type "
+ "but cannot be found.");
+ expectWarning("Warning: tst_qmltyperegistrar.h:: NotAPropertyType is used as property type "
+ "but cannot be found.");
+ expectWarning("Warning: tst_qmltyperegistrar.h:: NotAnArgumentType is used as argument type "
+ "but cannot be found.");
+ expectWarning("Warning: tst_qmltyperegistrar.h:: NotAReturnType is used as return type "
+ "but cannot be found.");
+ expectWarning("Warning: tst_qmltyperegistrar.h:: NotAnUnderlyingType is used as enum type "
+ "but cannot be found.");
+
+ processor.postProcessForeignTypes();
+
+ QVector<MetaType> types = processor.types();
+ QVector<MetaType> typesforeign = processor.foreignTypes();
+ r.setTypes(types, typesforeign);
+
+ QString outputData;
+ QTextStream output(&outputData, QIODeviceBase::ReadWrite);
+
+ expectWarning("Warning: tst_qmltyperegistrar.h:: AddedInLateVersion is trying to register "
+ "property revisioned with future version 1.4 when module version is only 1.1");
+ expectWarning("Warning: tst_qmltyperegistrar.h:: ExcessiveVersion is trying to register "
+ "property palette with future version 6.0 when module version is only 1.1");
+
+ r.write(output, "tst_qmltyperegistrar_qmltyperegistrations.cpp");
+
+ QTemporaryFile pluginTypes;
+ QVERIFY(pluginTypes.open());
+
+ expectWarning("Warning: tst_qmltyperegistrar.h:: Refusing to generate non-lowercase name "
+ "Invisible for unknown foreign type");
+
+ r.generatePluginTypes(pluginTypes.fileName());
}
void tst_qmltyperegistrar::clonedSignal()
@@ -432,17 +498,17 @@ void tst_qmltyperegistrar::hasIsConstantInParameters()
QVERIFY(qmltypesData.contains(R"( Signal {
name: "mySignal"
Parameter { name: "myObject"; type: "QObject"; isPointer: true }
- Parameter { name: "myConstObject"; type: "QObject"; isPointer: true; isConstant: true }
- Parameter { name: "myConstObject2"; type: "QObject"; isPointer: true; isConstant: true }
+ Parameter { name: "myConstObject"; type: "QObject"; isPointer: true; isTypeConstant: true }
+ Parameter { name: "myConstObject2"; type: "QObject"; isPointer: true; isTypeConstant: true }
Parameter { name: "myObject2"; type: "QObject"; isPointer: true }
- Parameter { name: "myConstObject3"; type: "QObject"; isPointer: true; isConstant: true }
+ Parameter { name: "myConstObject3"; type: "QObject"; isPointer: true; isTypeConstant: true }
}
)"));
QVERIFY(qmltypesData.contains(R"(Signal {
name: "myVolatileSignal"
- Parameter { name: "a"; type: "volatile QObject"; isPointer: true; isConstant: true }
- Parameter { name: "b"; type: "volatile QObject"; isPointer: true; isConstant: true }
+ Parameter { name: "a"; type: "volatile QObject"; isPointer: true; isTypeConstant: true }
+ Parameter { name: "b"; type: "volatile QObject"; isPointer: true; isTypeConstant: true }
Parameter { name: "nonConst"; type: "volatile QObject"; isPointer: true }
}
)"));
@@ -450,70 +516,101 @@ void tst_qmltyperegistrar::hasIsConstantInParameters()
void tst_qmltyperegistrar::uncreatable()
{
+ using namespace QQmlPrivate;
+
// "normal" constructible types
- QVERIFY(QQmlPrivate::QmlMetaType<Creatable>::hasAcceptableCtors());
- QVERIFY(QQmlPrivate::QmlMetaType<Creatable2>::hasAcceptableCtors());
+ QVERIFY(QmlMetaType<Creatable>::hasAcceptableCtors());
+ QVERIFY(QmlMetaType<Creatable2>::hasAcceptableCtors());
// good singletons
- QVERIFY(QQmlPrivate::QmlMetaType<SingletonCreatable>::hasAcceptableSingletonCtors());
- QVERIFY(QQmlPrivate::QmlMetaType<SingletonCreatable2>::hasAcceptableSingletonCtors());
- QVERIFY(QQmlPrivate::QmlMetaType<SingletonCreatable3>::hasAcceptableSingletonCtors());
+ QCOMPARE((singletonConstructionMode<SingletonCreatable, SingletonCreatable>()),
+ SingletonConstructionMode::Factory);
+ QCOMPARE((singletonConstructionMode<SingletonCreatable2, SingletonCreatable2>()),
+ SingletonConstructionMode::Constructor);
+ QCOMPARE((singletonConstructionMode<SingletonCreatable2, SingletonCreatable2>()),
+ SingletonConstructionMode::Constructor);
+ QCOMPARE((singletonConstructionMode<SingletonForeign, SingletonLocalCreatable>()),
+ SingletonConstructionMode::FactoryWrapper);
// bad singletons
- QVERIFY(!QQmlPrivate::QmlMetaType<SingletonIncreatable>::hasAcceptableSingletonCtors());
- QVERIFY(!QQmlPrivate::QmlMetaType<SingletonIncreatable2>::hasAcceptableSingletonCtors());
- QVERIFY(!QQmlPrivate::QmlMetaType<SingletonIncreatable3>::hasAcceptableSingletonCtors());
- QVERIFY(!QQmlPrivate::QmlMetaType<SingletonIncreatable4>::hasAcceptableSingletonCtors());
- QVERIFY(!QQmlPrivate::QmlMetaType<SingletonIncreatableExtended>::hasAcceptableSingletonCtors());
+ QCOMPARE((singletonConstructionMode<SingletonIncreatable, SingletonIncreatable>()),
+ SingletonConstructionMode::None);
+ QCOMPARE((singletonConstructionMode<SingletonIncreatable2, SingletonIncreatable2>()),
+ SingletonConstructionMode::None);
+ QCOMPARE((singletonConstructionMode<SingletonIncreatable3, SingletonIncreatable3>()),
+ SingletonConstructionMode::None);
+ QCOMPARE((singletonConstructionMode<SingletonIncreatable4, SingletonIncreatable4>()),
+ SingletonConstructionMode::None);
+ QCOMPARE((singletonConstructionMode<SingletonIncreatableExtended,
+ SingletonIncreatableExtended>()),
+ SingletonConstructionMode::None);
+ QCOMPARE((singletonConstructionMode<SingletonForeign, SingletonLocalUncreatable1>()),
+ SingletonConstructionMode::None);
+ QCOMPARE((singletonConstructionMode<SingletonForeign, SingletonLocalUncreatable2>()),
+ SingletonConstructionMode::None);
#if QT_DEPRECATED_SINCE(6, 4)
QTest::ignoreMessage(
QtWarningMsg,
- "Singleton SingletonIncreatable needs either a default constructor or, "
- "when adding a default constructor is infeasible, a public static "
- "create(QQmlEngine *, QJSEngine *) method.");
+ "Singleton SingletonIncreatable needs to be a concrete class with either a "
+ "default constructor or, when adding a default constructor is infeasible, "
+ "a public static create(QQmlEngine *, QJSEngine *) method.");
qmlRegisterTypesAndRevisions<SingletonIncreatable>("A", 1);
QTest::ignoreMessage(
QtWarningMsg,
- "Singleton SingletonIncreatable2 needs either a default constructor or, "
- "when adding a default constructor is infeasible, a public static "
- "create(QQmlEngine *, QJSEngine *) method.");
+ "Singleton SingletonIncreatable2 needs to be a concrete class with either a "
+ "default constructor or, when adding a default constructor is infeasible, "
+ "a public static create(QQmlEngine *, QJSEngine *) method.");
qmlRegisterTypesAndRevisions<SingletonIncreatable2>("A", 1);
QTest::ignoreMessage(
QtWarningMsg,
- "Singleton SingletonIncreatable3 needs either a default constructor or, "
- "when adding a default constructor is infeasible, a public static "
- "create(QQmlEngine *, QJSEngine *) method.");
+ "Singleton SingletonIncreatable3 needs to be a concrete class with either a "
+ "default constructor or, when adding a default constructor is infeasible, "
+ "a public static create(QQmlEngine *, QJSEngine *) method.");
qmlRegisterTypesAndRevisions<SingletonIncreatable3>("A", 1);
QTest::ignoreMessage(
QtWarningMsg,
- "Singleton SingletonIncreatable4 needs either a default constructor or, "
- "when adding a default constructor is infeasible, a public static "
- "create(QQmlEngine *, QJSEngine *) method.");
+ "Singleton SingletonIncreatable4 needs to be a concrete class with either a "
+ "default constructor or, when adding a default constructor is infeasible, "
+ "a public static create(QQmlEngine *, QJSEngine *) method.");
qmlRegisterTypesAndRevisions<SingletonIncreatable4>("A", 1);
QTest::ignoreMessage(
QtWarningMsg,
- "Singleton SingletonIncreatableExtended needs either a default constructor or, "
- "when adding a default constructor is infeasible, a public static "
- "create(QQmlEngine *, QJSEngine *) method.");
+ "Singleton SingletonIncreatableExtended needs to be a concrete class with either a "
+ "default constructor or, when adding a default constructor is infeasible, "
+ "a public static create(QQmlEngine *, QJSEngine *) method.");
qmlRegisterTypesAndRevisions<SingletonIncreatableExtended>("A", 1);
+ QTest::ignoreMessage(
+ QtWarningMsg,
+ "Singleton SingletonForeign needs to be a concrete class with either a "
+ "default constructor or, when adding a default constructor is infeasible, "
+ "a public static create(QQmlEngine *, QJSEngine *) method.");
+ qmlRegisterTypesAndRevisions<SingletonLocalUncreatable1>("A", 1);
+ QTest::ignoreMessage(
+ QtWarningMsg,
+ "Singleton SingletonForeign needs to be a concrete class with either a "
+ "default constructor or, when adding a default constructor is infeasible, "
+ "a public static create(QQmlEngine *, QJSEngine *) method.");
+ qmlRegisterTypesAndRevisions<SingletonLocalUncreatable2>("A", 1);
#endif
// QML_UNCREATABLE types
- QVERIFY(!QQmlPrivate::QmlMetaType<BadUncreatable>::hasAcceptableCtors());
- QVERIFY(!QQmlPrivate::QmlMetaType<BadUncreatableExtended>::hasAcceptableCtors());
- QVERIFY(!QQmlPrivate::QmlMetaType<GoodUncreatable>::hasAcceptableCtors());
- QVERIFY(!QQmlPrivate::QmlMetaType<UncreatableNeedsForeign>::hasAcceptableCtors());
- QVERIFY(!QQmlPrivate::QmlMetaType<GoodUncreatableExtended>::hasAcceptableCtors());
+ QVERIFY(!QmlMetaType<BadUncreatable>::hasAcceptableCtors());
+ QVERIFY(!QmlMetaType<BadUncreatableExtended>::hasAcceptableCtors());
+ QVERIFY(!QmlMetaType<GoodUncreatable>::hasAcceptableCtors());
+ QVERIFY(!QmlMetaType<UncreatableNeedsForeign>::hasAcceptableCtors());
+ QVERIFY(!QmlMetaType<GoodUncreatableExtended>::hasAcceptableCtors());
#if QT_DEPRECATED_SINCE(6, 4)
QTest::ignoreMessage(
QtWarningMsg,
- "BadUncreatable is neither a QObject, nor default- and copy-constructible, "
- "nor uncreatable. You should not use it as a QML type.");
+ "BadUncreatable is neither a default constructible QObject, nor a default- "
+ "and copy-constructible Q_GADGET, nor marked as uncreatable.\n"
+ "You should not use it as a QML type.");
qmlRegisterTypesAndRevisions<BadUncreatable>("A", 1);
QTest::ignoreMessage(
QtWarningMsg,
- "BadUncreatableExtended is neither a QObject, nor default- and copy-constructible, "
- "nor uncreatable. You should not use it as a QML type.");
+ "BadUncreatableExtended is neither a default constructible QObject, nor a default- "
+ "and copy-constructible Q_GADGET, nor marked as uncreatable.\n"
+ "You should not use it as a QML type.");
qmlRegisterTypesAndRevisions<BadUncreatableExtended>("A", 1);
#endif
@@ -537,6 +634,26 @@ void tst_qmltyperegistrar::uncreatable()
qmlRegisterTypesAndRevisions<GoodUncreatableExtended>("A", 1);
}
+void tst_qmltyperegistrar::singletonVersions()
+{
+ QQmlEngine engine;
+ qmlRegisterTypesAndRevisions<SingletonVesion0>("A", 0);
+ qmlRegisterTypesAndRevisions<SingletonVesion1>("B", 1);
+
+ QQmlComponent c(&engine);
+ c.setData("import QtQuick\n"
+ "import A\n"
+ "import B\n"
+ "QtObject {\n"
+ " property QtObject v0: SingletonVesion0\n"
+ " property QtObject v1: SingletonVesion1\n"
+ "}", QUrl());
+ QVERIFY2(c.isReady(), qPrintable(c.errorString()));
+ QScopedPointer<QObject> obj(c.create());
+ QVERIFY2(!obj->property("v0").isNull(), "Singleton version 0 is not registered");
+ QVERIFY2(!obj->property("v1").isNull(), "Singleton version 1 is not registered");
+}
+
void tst_qmltyperegistrar::baseVersionInQmltypes()
{
// Since it has no QML_ADDED_IN_VERSION, WithMethod was added in .0 of the current version.
@@ -544,4 +661,428 @@ void tst_qmltyperegistrar::baseVersionInQmltypes()
QVERIFY(qmltypesData.contains("exports: [\"QmlTypeRegistrarTest/WithMethod 1.0\"]"));
}
+void tst_qmltyperegistrar::unconstructibleValueType()
+{
+ QVERIFY(qmltypesData.contains(
+ R"(Component {
+ file: "tst_qmltyperegistrar.h"
+ name: "Unconstructible"
+ accessSemantics: "value"
+ exports: ["QmlTypeRegistrarTest/unconstructible 1.0"]
+ isCreatable: false
+ exportMetaObjectRevisions: [256]
+ })"));
+}
+
+void tst_qmltyperegistrar::constructibleValueType()
+{
+ QVERIFY(qmltypesData.contains(
+ R"(Component {
+ file: "tst_qmltyperegistrar.h"
+ name: "Constructible"
+ accessSemantics: "value"
+ exports: ["QmlTypeRegistrarTest/constructible 1.0"]
+ exportMetaObjectRevisions: [256]
+ Method {
+ name: "Constructible"
+ isConstructor: true
+ Parameter { name: "i"; type: "int" }
+ }
+ Method { name: "Constructible"; isCloned: true; isConstructor: true }
+ })"));
+}
+
+void tst_qmltyperegistrar::structuredValueType()
+{
+ QVERIFY(qmltypesData.contains(
+ R"(Component {
+ file: "tst_qmltyperegistrar.h"
+ name: "Structured"
+ accessSemantics: "value"
+ exports: ["QmlTypeRegistrarTest/structured 1.0"]
+ isStructured: true
+ exportMetaObjectRevisions: [256]
+ Property { name: "i"; type: "int"; index: 0; isFinal: true }
+ })"));
+}
+
+void tst_qmltyperegistrar::anonymousAndUncreatable()
+{
+ QVERIFY(qmltypesData.contains(
+ R"(Component {
+ file: "tst_qmltyperegistrar.h"
+ name: "AnonymousAndUncreatable"
+ accessSemantics: "reference"
+ prototype: "QObject"
+ })"));
+}
+
+void tst_qmltyperegistrar::omitInvisible()
+{
+ // If it cannot resolve the type a QML_FOREIGN refers to, it should not generate anything.
+ QVERIFY(qmltypesData.contains(
+ R"(Component { file: "tst_qmltyperegistrar.h"; name: "Invisible"; accessSemantics: "none" })"));
+}
+
+void tst_qmltyperegistrar::typedEnum()
+{
+ QVERIFY(qmltypesData.contains(
+ R"(Component {
+ file: "tst_qmltyperegistrar.h"
+ name: "TypedEnum"
+ accessSemantics: "reference"
+ prototype: "QObject"
+ exports: ["QmlTypeRegistrarTest/TypedEnum 1.0"]
+ exportMetaObjectRevisions: [256]
+ Enum {
+ name: "UChar"
+ type: "quint8"
+ values: ["V0"]
+ }
+ Enum {
+ name: "Int8_T"
+ type: "qint8"
+ values: ["V1"]
+ }
+ Enum {
+ name: "UInt8_T"
+ type: "quint8"
+ values: ["V2"]
+ }
+ Enum {
+ name: "Int16_T"
+ type: "short"
+ values: ["V3"]
+ }
+ Enum {
+ name: "UInt16_T"
+ type: "ushort"
+ values: ["V4"]
+ }
+ Enum {
+ name: "Int32_T"
+ type: "int"
+ values: ["V5"]
+ }
+ Enum {
+ name: "UInt32_T"
+ type: "uint"
+ values: ["V6"]
+ }
+ Enum {
+ name: "S"
+ type: "short"
+ values: ["A", "B", "C"]
+ }
+ Enum {
+ name: "T"
+ type: "ushort"
+ values: ["D", "E", "F"]
+ }
+ Enum {
+ name: "U"
+ type: "qint8"
+ values: ["G", "H", "I"]
+ }
+ Enum {
+ name: "V"
+ type: "quint8"
+ values: ["J", "K", "L"]
+ }
+ })"));
+}
+
+void tst_qmltyperegistrar::listSignal()
+{
+ QVERIFY(qmltypesData.contains(
+ R"(Component {
+ file: "tst_qmltyperegistrar.h"
+ name: "ListSignal"
+ accessSemantics: "reference"
+ prototype: "QObject"
+ Signal {
+ name: "objectListHappened"
+ Parameter { type: "QObjectList" }
+ }
+ })"));
+}
+
+void tst_qmltyperegistrar::withNamespace()
+{
+ QVERIFY(qmltypesData.contains(R"(Component {
+ file: "tst_qmltyperegistrar.h"
+ name: "Bar"
+ accessSemantics: "reference"
+ prototype: "QObject"
+ Property {
+ name: "outerBarProp"
+ type: "int"
+ read: "bar"
+ index: 0
+ isReadonly: true
+ isPropertyConstant: true
+ }
+ })"));
+
+ QVERIFY(qmltypesData.contains(R"(Component {
+ file: "tst_qmltyperegistrar.h"
+ name: "Testing::Bar"
+ accessSemantics: "reference"
+ prototype: "Testing::Foo"
+ exports: ["QmlTypeRegistrarTest/Bar 1.0"]
+ exportMetaObjectRevisions: [256]
+ Property {
+ name: "barProp"
+ type: "int"
+ read: "bar"
+ index: 0
+ isReadonly: true
+ isPropertyConstant: true
+ }
+ })"));
+
+ QVERIFY(qmltypesData.contains(R"(Component {
+ file: "tst_qmltyperegistrar.h"
+ name: "Testing::Foo"
+ accessSemantics: "reference"
+ prototype: "QObject"
+ Property {
+ name: "fooProp"
+ type: "int"
+ read: "foo"
+ index: 0
+ isReadonly: true
+ isPropertyConstant: true
+ }
+ })"));
+
+ QVERIFY(qmltypesData.contains(R"(Component {
+ file: "tst_qmltyperegistrar.h"
+ name: "Testing::Inner::Baz"
+ accessSemantics: "reference"
+ prototype: "Testing::Bar"
+ extension: "Bar"
+ exports: ["QmlTypeRegistrarTest/Baz 1.0"]
+ exportMetaObjectRevisions: [256]
+ attachedType: "Testing::Foo"
+ })"));
+}
+
+void tst_qmltyperegistrar::sequenceRegistration()
+{
+ QVERIFY(qmltypesData.contains(R"(Component {
+ file: "tst_qmltyperegistrar.h"
+ name: "std::vector<QByteArray>"
+ accessSemantics: "sequence"
+ valueType: "QByteArray"
+ })"));
+}
+
+void tst_qmltyperegistrar::valueTypeSelfReference()
+{
+ QVERIFY(qmltypesData.contains(R"(Component {
+ file: "tst_qmltyperegistrar.h"
+ name: "QPersistentModelIndex"
+ accessSemantics: "value"
+ extension: "QPersistentModelIndexValueType"
+ })"));
+ QVERIFY(qmltypesData.contains(R"(Component {
+ file: "tst_qmltyperegistrar.h"
+ name: "QPersistentModelIndexValueType"
+ accessSemantics: "value"
+ Property { name: "row"; type: "int"; read: "row"; index: 0; isReadonly: true; isFinal: true }
+ })"));
+}
+
+void tst_qmltyperegistrar::foreignNamespaceFromGadget()
+{
+ QQmlEngine engine;
+ {
+ QQmlComponent c(&engine);
+ c.setData(QStringLiteral(R"(
+ import QtQml
+ import QmlTypeRegistrarTest
+ QtObject {
+ objectName: 'b' + NetworkManager.B
+ }
+ )").toUtf8(), QUrl("foreignNamespaceFromGadget.qml"));
+ QVERIFY2(c.isReady(), qPrintable(c.errorString()));
+ QScopedPointer<QObject> o(c.create());
+ QCOMPARE(o->objectName(), QStringLiteral("b1"));
+ }
+
+ {
+ QQmlComponent c(&engine);
+ c.setData(QStringLiteral(R"(
+ import QtQml
+ import QmlTypeRegistrarTest
+ QtObject {
+ objectName: 'b' + NotNamespaceForeign.B
+ }
+ )").toUtf8(), QUrl("foreignNamespaceFromGadget2.qml"));
+ QVERIFY2(c.isReady(), qPrintable(c.errorString()));
+ QScopedPointer<QObject> o(c.create());
+ QCOMPARE(o->objectName(), QStringLiteral("b1"));
+ }
+}
+
+void tst_qmltyperegistrar::nameExplosion_data()
+{
+ QTest::addColumn<QByteArray>("qml");
+ QTest::addRow("Name1") << QByteArray("import QmlTypeRegistrarTest\nName1{}");
+ QTest::addRow("Name2") << QByteArray("import QmlTypeRegistrarTest\nName2{}");
+ QTest::addRow("NameExplosion") << QByteArray("import QmlTypeRegistrarTest\nNameExplosion{}");
+}
+
+void tst_qmltyperegistrar::nameExplosion()
+{
+ QVERIFY(qmltypesData.contains(R"(Component {
+ file: "tst_qmltyperegistrar.h"
+ name: "NameExplosion"
+ accessSemantics: "reference"
+ prototype: "QObject"
+ exports: [
+ "QmlTypeRegistrarTest/Name1 1.0",
+ "QmlTypeRegistrarTest/Name2 1.0",
+ "QmlTypeRegistrarTest/NameExplosion 1.0"
+ ]
+ exportMetaObjectRevisions: [256]
+ })"));
+
+ QFETCH(QByteArray, qml);
+
+ QQmlEngine engine;
+ QQmlComponent c(&engine);
+
+ c.setData(qml, QUrl());
+ QVERIFY2(c.isReady(), qPrintable(c.errorString()));
+ QScopedPointer<QObject> o(c.create());
+ QVERIFY(!o.isNull());
+}
+
+void tst_qmltyperegistrar::javaScriptExtension()
+{
+ QVERIFY(qmltypesData.contains(R"(Component {
+ file: "tst_qmltyperegistrar.h"
+ name: "JavaScriptExtension"
+ accessSemantics: "reference"
+ prototype: "QObject"
+ extension: "SymbolPrototype"
+ extensionIsJavaScript: true
+ exports: ["QmlTypeRegistrarTest/JavaScriptExtension 1.0"]
+ exportMetaObjectRevisions: [256]
+ })"));
+}
+
+void tst_qmltyperegistrar::relatedAddedInVersion()
+{
+ QVERIFY(qmltypesData.contains(R"(Component {
+ file: "tst_qmltyperegistrar.h"
+ name: "AddedIn1_0"
+ accessSemantics: "reference"
+ prototype: "AddedIn1_5"
+ exports: [
+ "QmlTypeRegistrarTest/AddedIn1_0 1.0",
+ "QmlTypeRegistrarTest/AddedIn1_0 1.5"
+ ]
+ exportMetaObjectRevisions: [256, 261]
+ })"));
+}
+
+void tst_qmltyperegistrar::longNumberTypes()
+{
+ QVERIFY(qmltypesData.contains(R"(Component {
+ file: "tst_qmltyperegistrar.h"
+ name: "LongNumberTypes"
+ accessSemantics: "reference"
+ prototype: "QObject"
+ exports: ["QmlTypeRegistrarTest/LongNumberTypes 1.0"]
+ exportMetaObjectRevisions: [256]
+ Property { name: "a"; type: "qlonglong"; index: 0 }
+ Property { name: "b"; type: "qlonglong"; index: 1 }
+ Property { name: "c"; type: "qulonglong"; index: 2 }
+ Property { name: "d"; type: "qulonglong"; index: 3 }
+ })"));
+}
+
+void tst_qmltyperegistrar::enumList() {
+ QVERIFY(qmltypesData.contains(R"(Component {
+ file: "tst_qmltyperegistrar.h"
+ name: "QList<NetworkManager::NM>"
+ accessSemantics: "sequence"
+ valueType: "NetworkManager::NM"
+ })"));
+}
+
+void tst_qmltyperegistrar::constReturnType()
+{
+ QVERIFY(qmltypesData.contains(R"(Component {
+ file: "tst_qmltyperegistrar.h"
+ name: "ConstInvokable"
+ accessSemantics: "reference"
+ prototype: "QObject"
+ exports: ["QmlTypeRegistrarTest/ConstInvokable 1.0"]
+ exportMetaObjectRevisions: [256]
+ Method { name: "getObject"; type: "QObject"; isPointer: true; isTypeConstant: true }
+ })"));
+}
+
+void tst_qmltyperegistrar::usingDeclaration()
+{
+ QVERIFY(qmltypesData.contains(R"(Component {
+ file: "tst_qmltyperegistrar.h"
+ name: "WithMyInt"
+ accessSemantics: "reference"
+ prototype: "QObject"
+ exports: ["QmlTypeRegistrarTest/WithMyInt 1.0"]
+ exportMetaObjectRevisions: [256]
+ Property { name: "a"; type: "int"; read: "a"; index: 0; isReadonly: true; isPropertyConstant: true }
+ })"));
+}
+
+void tst_qmltyperegistrar::enumsRegistered()
+{
+ QCOMPARE(QMetaType::fromName("SizeEnums::Unit"), QMetaType::fromType<SizeEnums::Unit>());
+ QCOMPARE(QMetaType::fromName("Local::Flag"), QMetaType::fromType<Local::Flag>());
+ QCOMPARE(QMetaType::fromName("Local::Flags"), QMetaType::fromType<Local::Flags>());
+ QCOMPARE(QMetaType::fromName("ValueTypeWithEnum1::Quality"),
+ QMetaType::fromType<ValueTypeWithEnum1::Quality>());
+ QCOMPARE(QMetaType::fromName("ValueTypeWithEnum2::Quality"),
+ QMetaType::fromType<ValueTypeWithEnum2::Quality>());
+ QCOMPARE(QMetaType::fromName("BaseNamespace::BBB"), QMetaType::fromType<BaseNamespace::BBB>());
+ QCOMPARE(QMetaType::fromName("ExtensionValueType::EEE"),
+ QMetaType::fromType<ExtensionValueType::EEE>());
+ QCOMPARE(QMetaType::fromName("TypedEnum::UChar"), QMetaType::fromType<TypedEnum::UChar>());
+ QCOMPARE(QMetaType::fromName("TypedEnum::Int8_T"), QMetaType::fromType<TypedEnum::Int8_T>());
+ QCOMPARE(QMetaType::fromName("TypedEnum::UInt8_T"), QMetaType::fromType<TypedEnum::UInt8_T>());
+ QCOMPARE(QMetaType::fromName("TypedEnum::Int16_T"), QMetaType::fromType<TypedEnum::Int16_T>());
+ QCOMPARE(QMetaType::fromName("TypedEnum::UInt16_T"), QMetaType::fromType<TypedEnum::UInt16_T>());
+ QCOMPARE(QMetaType::fromName("TypedEnum::Int32_T"), QMetaType::fromType<TypedEnum::Int32_T>());
+ QCOMPARE(QMetaType::fromName("TypedEnum::UInt32_T"), QMetaType::fromType<TypedEnum::UInt32_T>());
+ QCOMPARE(QMetaType::fromName("TypedEnum::S"), QMetaType::fromType<TypedEnum::S>());
+ QCOMPARE(QMetaType::fromName("TypedEnum::T"), QMetaType::fromType<TypedEnum::T>());
+ QCOMPARE(QMetaType::fromName("TypedEnum::U"), QMetaType::fromType<TypedEnum::U>());
+ QCOMPARE(QMetaType::fromName("TypedEnum::V"), QMetaType::fromType<TypedEnum::V>());
+ QCOMPARE(QMetaType::fromName("NetworkManager::NM"), QMetaType::fromType<NetworkManager::NM>());
+ QCOMPARE(QMetaType::fromName("NotNamespace::Abc"), QMetaType::fromType<NotNamespace::Abc>());
+}
+
+void tst_qmltyperegistrar::doNotDuplicateQtNamespace()
+{
+ QVERIFY(!qmltypesData.contains(R"(file: "qnamespace.h")"));
+}
+
+void tst_qmltyperegistrar::slotsBeforeInvokables()
+{
+ QVERIFY(qmltypesData.contains(R"(Component {
+ file: "tst_qmltyperegistrar.h"
+ name: "SlotsBeforeInvokables"
+ accessSemantics: "reference"
+ prototype: "QObject"
+ Method { name: "bar" }
+ Method { name: "foo" }
+ Method { name: "baz" }
+ })"));
+}
+
QTEST_MAIN(tst_qmltyperegistrar)
diff --git a/tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.h b/tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.h
index df755472d7..1eff2af024 100644
--- a/tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.h
+++ b/tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.h
@@ -1,46 +1,50 @@
// Copyright (C) 2020 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#ifndef TST_QMLTYPEREGISTRAR_H
#define TST_QMLTYPEREGISTRAR_H
#include "foreign.h"
-#include "foreign_p.h"
+#include "private/foreign_p.h"
-#include <QtQml/qqml.h>
-#include <QtQml/qqmlcomponent.h>
-#include <QtCore/qproperty.h>
-#include <QtCore/qtimeline.h>
-#include <QtCore/qrect.h>
#include <QtQmlTypeRegistrar/private/qqmltyperegistrar_p.h>
-#include <QtCore/qtemporaryfile.h>
#ifdef QT_QUICK_LIB
# include <QtQuick/qquickitem.h>
#endif
-class Interface {};
+#include <QtQml/qqml.h>
+#include <QtQml/qqmlcomponent.h>
+
+#include <QtCore/qabstractitemmodel.h>
+#include <QtCore/qnamespace.h>
+#include <QtCore/qproperty.h>
+#include <QtCore/qrect.h>
+#include <QtCore/qtemporaryfile.h>
+#include <QtCore/qtimeline.h>
+
+class Interface1 {};
class Interface2 {};
class Interface3 {};
QT_BEGIN_NAMESPACE
-Q_DECLARE_INTERFACE(Interface, "io.qt.bugreports.Interface");
+Q_DECLARE_INTERFACE(Interface1, "io.qt.bugreports.Interface1");
Q_DECLARE_INTERFACE(Interface2, "io.qt.bugreports.Interface2");
Q_DECLARE_INTERFACE(Interface3, "io.qt.bugreports.Interface3");
QT_END_NAMESPACE
-class ImplementsInterfaces : public QObject, public Interface
+class ImplementsInterfaces : public QObject, public Interface1
{
Q_OBJECT
QML_ELEMENT
- QML_IMPLEMENTS_INTERFACES(Interface)
+ QML_IMPLEMENTS_INTERFACES(Interface1)
};
-class ImplementsInterfaces2 : public QObject, public Interface, public Interface2
+class ImplementsInterfaces2 : public QObject, public Interface1, public Interface2
{
Q_OBJECT
QML_ELEMENT
- QML_IMPLEMENTS_INTERFACES(Interface Interface2)
+ QML_IMPLEMENTS_INTERFACES(Interface1 Interface2)
};
class ExcessiveVersion : public QObject
@@ -458,6 +462,29 @@ public:
int revisioned() const { return 24; }
};
+class AddedInLateMinorVersion : public QObject
+{
+ Q_OBJECT
+ QML_ADDED_IN_VERSION(1, 5)
+ Q_PROPERTY(int revisioned READ revisioned CONSTANT)
+ QML_NAMED_ELEMENT(MinorVersioned)
+public:
+ AddedInLateMinorVersion(QObject *parent = nullptr) : QObject(parent) {}
+ int revisioned() const { return 123; }
+};
+
+class RemovedInLateMinorVersion : public QObject
+{
+ Q_OBJECT
+ QML_ADDED_IN_VERSION(1, 2)
+ QML_REMOVED_IN_VERSION(1, 4)
+ Q_PROPERTY(int revisioned READ revisioned CONSTANT)
+ QML_NAMED_ELEMENT(MinorVersioned)
+public:
+ RemovedInLateMinorVersion(QObject *parent = nullptr) : QObject(parent) { }
+ int revisioned() const { return 456; }
+};
+
class RemovedInEarlyVersion : public AddedInLateVersion
{
Q_OBJECT
@@ -468,6 +495,23 @@ public:
RemovedInEarlyVersion(QObject *parent = nullptr) : AddedInLateVersion(parent) {}
};
+class AddedIn1_5 : public QObject
+{
+ Q_OBJECT
+ QML_ELEMENT
+ QML_ADDED_IN_VERSION(1, 5)
+};
+
+// Slightly absurd. The reason for such a thing may be a change in the versioning
+// scheme of the base class. We still have to retain all of the version information
+// so that you can at least use version 1.5.
+class AddedIn1_0 : public AddedIn1_5
+{
+ Q_OBJECT
+ QML_ELEMENT
+ QML_ADDED_IN_VERSION(1, 0)
+};
+
class HasResettableProperty : public QObject
{
Q_OBJECT
@@ -501,6 +545,293 @@ signals:
void clonedSignal(int i = 7);
};
+class Unconstructible
+{
+ Q_GADGET
+ QML_VALUE_TYPE(unconstructible)
+ int m_i = 11;
+};
+
+class Constructible
+{
+ Q_GADGET
+ QML_VALUE_TYPE(constructible)
+ QML_CONSTRUCTIBLE_VALUE
+public:
+ Q_INVOKABLE Constructible(int i = 12) : m_i(i) {}
+
+private:
+ int m_i;
+};
+
+class Structured
+{
+ Q_GADGET
+ QML_VALUE_TYPE(structured)
+ QML_STRUCTURED_VALUE
+ Q_PROPERTY(int i MEMBER m_i FINAL)
+
+private:
+ int m_i;
+};
+
+class AnonymousAndUncreatable : public QObject
+{
+ Q_OBJECT
+ QML_ANONYMOUS
+ QML_UNCREATABLE("Pointless uncreatable message")
+};
+
+class Invisible : public QObject
+{
+};
+
+struct InvisibleForeign
+{
+ Q_GADGET
+ QML_FOREIGN(Invisible)
+ QML_NAMED_ELEMENT(Invisible)
+};
+
+class TypedEnum : public QObject
+{
+ Q_OBJECT
+ QML_ELEMENT
+public:
+ enum UChar: uchar { V0 = 41 };
+ Q_ENUM(UChar)
+ enum Int8_T: int8_t { V1 = 42 };
+ Q_ENUM(Int8_T)
+ enum UInt8_T: uint8_t { V2 = 43 };
+ Q_ENUM(UInt8_T)
+ enum Int16_T: int16_t { V3 = 44 };
+ Q_ENUM(Int16_T)
+ enum UInt16_T: uint16_t { V4 = 45 };
+ Q_ENUM(UInt16_T)
+ enum Int32_T: int32_t { V5 = 46 };
+ Q_ENUM(Int32_T)
+ enum UInt32_T: uint32_t { V6 = 47 };
+ Q_ENUM(UInt32_T)
+
+ // TODO: We cannot handle 64bit numbers as underlying types for enums.
+ // Luckily, moc generates bad code for those. So we don't have to, for now.
+
+ enum S: qint16 {
+ A, B, C
+ };
+ Q_ENUM(S)
+
+ enum T: quint16 {
+ D, E, F
+ };
+ Q_ENUM(T)
+
+ enum U: qint8 {
+ G, H, I
+ };
+ Q_ENUM(U)
+
+ enum V: quint8 {
+ J, K, L
+ };
+ Q_ENUM(V)
+};
+
+class ListSignal : public QObject
+{
+ Q_OBJECT
+ QML_ANONYMOUS
+
+Q_SIGNALS:
+ void objectListHappened(const QList<QObject *> &);
+};
+
+class Bar : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(int outerBarProp READ bar CONSTANT)
+public:
+ Bar(QObject *parent = nullptr) : QObject(parent) {}
+ int bar() const { return 44; }
+};
+
+namespace Testing {
+
+class Foo : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(int fooProp READ foo CONSTANT)
+
+public:
+ int foo() const { return 42; }
+};
+
+class Bar : public Foo
+{
+ Q_OBJECT
+ QML_ELEMENT
+ Q_PROPERTY(int barProp READ bar CONSTANT)
+
+public:
+ int bar() const { return 43; }
+};
+
+namespace Inner {
+
+class Baz : public Bar
+{
+ Q_OBJECT
+ QML_ELEMENT
+
+ QML_EXTENDED(::Bar)
+ QML_ATTACHED(Foo)
+
+public:
+ static Foo *qmlAttachedProperties(QObject *) { return new Foo; }
+};
+
+} // namespace Inner
+} // namespace Testing
+
+struct QByteArrayStdVectorForeign
+{
+ Q_GADGET
+ QML_ANONYMOUS
+ QML_SEQUENTIAL_CONTAINER(QByteArray)
+ QML_FOREIGN(std::vector<QByteArray>)
+};
+
+// Anonymous value type for an unknown foreign type
+struct QPersistentModelIndexValueType
+{
+ QPersistentModelIndex v;
+ Q_PROPERTY(int row READ row FINAL)
+ Q_GADGET
+ QML_ANONYMOUS
+ QML_EXTENDED(QPersistentModelIndexValueType)
+ QML_FOREIGN(QPersistentModelIndex)
+
+public:
+ inline int row() const { return v.row(); }
+};
+
+
+namespace NetworkManager {
+Q_NAMESPACE
+
+enum NM { A, B, C};
+Q_ENUM_NS(NM)
+}
+
+struct NMForeign
+{
+ Q_GADGET
+ QML_NAMED_ELEMENT(NetworkManager)
+ QML_FOREIGN_NAMESPACE(NetworkManager)
+};
+
+struct NotNamespace {
+ Q_GADGET
+public:
+ enum Abc {
+ A, B, C, D
+ };
+ Q_ENUM(Abc);
+};
+
+struct NotNamespaceForeign {
+ Q_GADGET
+ QML_FOREIGN_NAMESPACE(NotNamespace)
+ QML_ELEMENT
+};
+
+class NameExplosion : public QObject
+{
+ Q_OBJECT
+ QML_NAMED_ELEMENT(Name1)
+ QML_NAMED_ELEMENT(Name2)
+ QML_ELEMENT
+ QML_ANONYMOUS
+};
+
+class JavaScriptExtension : public QObject
+{
+ Q_OBJECT
+ QML_ELEMENT
+ Q_CLASSINFO("QML.Extended", "SymbolPrototype")
+ Q_CLASSINFO("QML.ExtensionIsJavaScript", "true")
+};
+
+class LongNumberTypes : public QObject
+{
+ Q_OBJECT
+ QML_ELEMENT
+ Q_PROPERTY(qint64 a MEMBER m_a)
+ Q_PROPERTY(int64_t b MEMBER m_b)
+ Q_PROPERTY(quint64 c MEMBER m_c)
+ Q_PROPERTY(uint64_t d MEMBER m_d)
+
+ qint64 m_a = 1;
+ int64_t m_b = 2;
+ quint64 m_c = 3;
+ uint64_t m_d = 4;
+};
+
+struct EnumList
+{
+ Q_GADGET
+ QML_ANONYMOUS
+ QML_FOREIGN(QList<NetworkManager::NM>)
+ QML_SEQUENTIAL_CONTAINER(NetworkManager::NM)
+};
+
+class ConstInvokable : public QObject
+{
+ Q_OBJECT
+ QML_ELEMENT
+public:
+ Q_INVOKABLE const QObject *getObject() { return nullptr; }
+};
+
+using myint = int;
+
+struct IntAlias
+{
+ Q_GADGET
+ QML_FOREIGN(myint)
+ QML_USING(int);
+};
+
+class WithMyInt : public QObject
+{
+ Q_OBJECT
+ QML_ELEMENT
+ Q_PROPERTY(myint a READ a CONSTANT)
+public:
+ myint a() const { return 10; }
+};
+
+class UsesQtNamespace : public QObject
+{
+ Q_OBJECT
+ QML_ANONYMOUS
+ Q_PROPERTY(Qt::Key key READ key CONSTANT)
+public:
+ Qt::Key key() const { return Qt::Key_Escape; }
+};
+
+class SlotsBeforeInvokables : public QObject
+{
+ Q_OBJECT
+ QML_ANONYMOUS
+public:
+ Q_INVOKABLE void foo() {}
+public Q_SLOTS:
+ void bar() {}
+public:
+ Q_INVOKABLE void baz() {}
+};
+
class tst_qmltyperegistrar : public QObject
{
Q_OBJECT
@@ -537,6 +868,7 @@ private slots:
void methodReturnType();
void hasIsConstantInParameters();
void uncreatable();
+ void singletonVersions();
#ifdef QT_QUICK_LIB
void foreignRevisionedProperty();
@@ -544,11 +876,39 @@ private slots:
void addRemoveVersion_data();
void addRemoveVersion();
+ void addInMinorVersion();
void typeInModuleMajorVersionZero();
void resettableProperty();
void duplicateExportWarnings();
void clonedSignal();
void baseVersionInQmltypes();
+ void unconstructibleValueType();
+ void constructibleValueType();
+ void structuredValueType();
+ void anonymousAndUncreatable();
+ void omitInvisible();
+ void typedEnum();
+ void listSignal();
+ void withNamespace();
+ void sequenceRegistration();
+ void valueTypeSelfReference();
+ void foreignNamespaceFromGadget();
+
+ void nameExplosion_data();
+ void nameExplosion();
+
+ void javaScriptExtension();
+
+ void consistencyWarnings();
+ void relatedAddedInVersion();
+ void longNumberTypes();
+ void enumList();
+ void constReturnType();
+
+ void usingDeclaration();
+ void enumsRegistered();
+ void doNotDuplicateQtNamespace();
+ void slotsBeforeInvokables();
private:
QByteArray qmltypesData;