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/.prev_CMakeLists.txt39
-rw-r--r--tests/auto/qml/qmltyperegistrar/BLACKLIST3
-rw-r--r--tests/auto/qml/qmltyperegistrar/CMakeLists.txt89
-rw-r--r--tests/auto/qml/qmltyperegistrar/UnregisteredTypes/CMakeLists.txt16
-rw-r--r--tests/auto/qml/qmltyperegistrar/UnregisteredTypes/uncreatable.h236
-rw-r--r--tests/auto/qml/qmltyperegistrar/VersionZero/CMakeLists.txt24
-rw-r--r--tests/auto/qml/qmltyperegistrar/VersionZero/version_zero_type.h17
-rw-r--r--tests/auto/qml/qmltyperegistrar/dummy.cpp2
-rw-r--r--tests/auto/qml/qmltyperegistrar/dummy_p.h2
-rw-r--r--tests/auto/qml/qmltyperegistrar/duplicatedExports.h95
-rw-r--r--tests/auto/qml/qmltyperegistrar/duplicatedExports.json218
-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.cpp29
-rw-r--r--tests/auto/qml/qmltyperegistrar/foo.h35
-rw-r--r--tests/auto/qml/qmltyperegistrar/foreign/.prev_CMakeLists.txt19
-rw-r--r--tests/auto/qml/qmltyperegistrar/foreign/CMakeLists.txt4
-rw-r--r--tests/auto/qml/qmltyperegistrar/foreign/foreign.cpp29
-rw-r--r--tests/auto/qml/qmltyperegistrar/foreign/foreign.h29
-rw-r--r--tests/auto/qml/qmltyperegistrar/foreign/private/foreign_p.h18
-rw-r--r--tests/auto/qml/qmltyperegistrar/hppheader.hpp37
-rw-r--r--tests/auto/qml/qmltyperegistrar/missingTypes.json167
-rw-r--r--tests/auto/qml/qmltyperegistrar/noextheader29
-rw-r--r--tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.cpp902
-rw-r--r--tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.h673
25 files changed, 2452 insertions, 305 deletions
diff --git a/tests/auto/qml/qmltyperegistrar/.prev_CMakeLists.txt b/tests/auto/qml/qmltyperegistrar/.prev_CMakeLists.txt
deleted file mode 100644
index adbe3c2c9e..0000000000
--- a/tests/auto/qml/qmltyperegistrar/.prev_CMakeLists.txt
+++ /dev/null
@@ -1,39 +0,0 @@
-# Generated from qmltyperegistrar.pro.
-
-#####################################################################
-## tst_qmltyperegistrar Test:
-#####################################################################
-
-qt_internal_add_test(tst_qmltyperegistrar
- SOURCES
- hppheader.hpp
- noextheader
- tst_qmltyperegistrar.cpp tst_qmltyperegistrar.h
- INCLUDE_DIRECTORIES
- foreign
- PUBLIC_LIBRARIES
- # Remove: Lforeign
- Qt::Qml
- foreign
-)
-
-#### Keys ignored in scope 2:.:.:tst_qmltyperegistrar.pro:<TRUE>:
-# QMLTYPES_FILENAME = "tst_qmltyperegistrar.qmltypes"
-# QML_FOREIGN_METATYPES = "foreign/foreign_metatypes.json"
-# QML_IMPORT_NAME = "QmlTypeRegistrarTest"
-# QML_IMPORT_VERSION = "1.0"
-# QML_PAST_MAJOR_VERSIONS = "0"
-# TEMPLATE = "app"
-
-## Scopes:
-#####################################################################
-
-set_target_properties(tst_qmltyperegistrar PROPERTIES
- QT_QML_MODULE_VERSION 1.0
- QT_QML_PAST_MAJOR_VERSIONS 0
- QT_QML_MODULE_URI QmlTypeRegistrarTest
- QT_QMLTYPES_FILENAME tst_qmltyperegistrar.qmltypes
-)
-
-qt6_qml_type_registration(tst_qmltyperegistrar)
-add_subdirectory(foreign)
diff --git a/tests/auto/qml/qmltyperegistrar/BLACKLIST b/tests/auto/qml/qmltyperegistrar/BLACKLIST
deleted file mode 100644
index 6563288d0c..0000000000
--- a/tests/auto/qml/qmltyperegistrar/BLACKLIST
+++ /dev/null
@@ -1,3 +0,0 @@
-[pastMajorVersions]
-windows # QTBUG-88381
-
diff --git a/tests/auto/qml/qmltyperegistrar/CMakeLists.txt b/tests/auto/qml/qmltyperegistrar/CMakeLists.txt
index 674dc08056..45669769e4 100644
--- a/tests/auto/qml/qmltyperegistrar/CMakeLists.txt
+++ b/tests/auto/qml/qmltyperegistrar/CMakeLists.txt
@@ -1,27 +1,59 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
# Generated from qmltyperegistrar.pro.
#####################################################################
## 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
+# to be in a private/ subdirectory. In particular, we have a foreign_p.h to exercise this.
+# TODO: There should be more fine grained control over this.
+qt_add_library(tst_qmltyperegistrarPrivate STATIC
+ dummy.cpp dummy_p.h
+)
+
+target_link_libraries(tst_qmltyperegistrarPrivate PRIVATE Qt::Core)
qt_internal_add_test(tst_qmltyperegistrar
SOURCES
hppheader.hpp
# noextheader special case
tst_qmltyperegistrar.cpp tst_qmltyperegistrar.h
- foo.cpp foo.h
+ foo.cpp foo.h duplicatedExports.h
${moc_files}
INCLUDE_DIRECTORIES
foreign
- PUBLIC_LIBRARIES
+ LIBRARIES
# Remove: Lforeign
Qt::Qml
foreign
+ tst_qmltyperegistrarPrivate
+ Qt::QmlTypeRegistrarPrivate
+ tst_qmltyperegistrar_major_version_zero
+ UnregisteredTypes
)
+qt_internal_extend_target(tst_qmltyperegistrar CONDITION TARGET Qt::Quick
+ LIBRARIES
+ Qt::Quick
+ )
+
#### Keys ignored in scope 2:.:.:tst_qmltyperegistrar.pro:<TRUE>:
# QMLTYPES_FILENAME = "tst_qmltyperegistrar.qmltypes"
# QML_FOREIGN_METATYPES = "foreign/foreign_metatypes.json"
@@ -33,12 +65,53 @@ qt_internal_add_test(tst_qmltyperegistrar
## Scopes:
#####################################################################
+# Simulate conditions that qt6_add_qml_module() would normally set up for us
set_target_properties(tst_qmltyperegistrar PROPERTIES
- QT_QML_MODULE_VERSION 1.0
- QT_QML_PAST_MAJOR_VERSIONS 0
+ QT_QML_MODULE_VERSION 1.1
+ QT_QML_MODULE_PAST_MAJOR_VERSIONS 0
QT_QML_MODULE_URI QmlTypeRegistrarTest
- QT_QMLTYPES_FILENAME tst_qmltyperegistrar.qmltypes
+ QT_QML_MODULE_TYPEINFO tst_qmltyperegistrar.qmltypes
+ QT_QML_MODULE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
)
-qt6_qml_type_registration(tst_qmltyperegistrar MANUAL_MOC_JSON_FILES ${json_list}) # special case
-add_subdirectory(foreign)
+# qt6_add_qml_module() doesn't allow us to pass through MANUAL_MOC_JSON_FILES
+# yet, so we have to call it directly to test that code path for now.
+_qt_internal_qml_type_registration(tst_qmltyperegistrar MANUAL_MOC_JSON_FILES ${json_list})
+
+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
+ SOURCES
+ foo.cpp foo.h
+ OUTPUT_DIRECTORY Module-With-Dashes
+)
+qt_autogen_tools_initial_setup(tst-qmltyperegistrar-with-dashesplugin)
+
+qt_internal_add_resource(tst_qmltyperegistrar "resources"
+ PREFIX
+ "/"
+ 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
new file mode 100644
index 0000000000..d469f1e97f
--- /dev/null
+++ b/tests/auto/qml/qmltyperegistrar/UnregisteredTypes/CMakeLists.txt
@@ -0,0 +1,16 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# 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
+)
+
+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
new file mode 100644
index 0000000000..2274f87e3d
--- /dev/null
+++ b/tests/auto/qml/qmltyperegistrar/UnregisteredTypes/uncreatable.h
@@ -0,0 +1,236 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#ifndef UNCREATABLE_H
+#define UNCREATABLE_H
+
+#include <QtCore/qobject.h>
+#include <QtCore/qproperty.h>
+#include <QtQml/qqmlregistration.h>
+#include <QtQml/qqmlengine.h>
+
+class SingletonCreatable : public QObject
+{
+ Q_OBJECT
+ QML_ELEMENT
+ QML_SINGLETON
+public:
+ SingletonCreatable() = delete;
+ // not default constructible but has the static create method
+public:
+ static SingletonCreatable *create(QQmlEngine *, QJSEngine *) { return nullptr; }
+};
+
+class SingletonCreatable2 : public QObject
+{
+ Q_OBJECT
+ QML_ELEMENT
+ QML_SINGLETON
+ // is default constructible
+};
+
+class SingletonCreatable3 : public QObject
+{
+ Q_OBJECT
+ QML_ELEMENT
+ QML_SINGLETON
+public:
+ // is default constructible and has the create method
+ 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
+ QML_ELEMENT
+ QML_SINGLETON
+ SingletonIncreatable() = delete;
+
+public:
+ static SingletonCreatable *create(QQmlEngine *, QJSEngine *)
+ {
+ return nullptr;
+ } // wrong return type
+};
+
+class SingletonIncreatable2 : public QObject
+{
+ Q_OBJECT
+ QML_ELEMENT
+ QML_SINGLETON
+ SingletonIncreatable2() = delete;
+
+public:
+ static SingletonCreatable2 *create(QQmlEngine *) { return nullptr; } // wrong argument type
+};
+
+class SingletonIncreatable3 : public QObject
+{
+ Q_OBJECT
+ QML_ELEMENT
+ QML_SINGLETON
+ SingletonIncreatable3() = delete;
+
+public:
+ SingletonCreatable3 *create(QQmlEngine *, QJSEngine *) { return nullptr; } // should be static
+};
+
+class SingletonIncreatable4 : public QObject
+{
+ Q_OBJECT
+ QML_ELEMENT
+ QML_SINGLETON
+ SingletonIncreatable4() = delete;
+ static SingletonIncreatable4 *create(QQmlEngine *, QJSEngine *)
+ {
+ return nullptr;
+ } // should be public
+};
+
+class BadUncreatable : public QObject
+{
+ Q_OBJECT
+ QML_ELEMENT
+
+ BadUncreatable() = delete;
+};
+
+class GoodUncreatable : public QObject
+{
+ Q_OBJECT
+ QML_ELEMENT
+ QML_UNCREATABLE("")
+ GoodUncreatable() = delete;
+};
+
+class UncreatableNeedsForeign : public QObject
+{
+ Q_OBJECT
+
+ virtual void f() = 0;
+};
+
+class GoodUncreatable2
+{
+ Q_GADGET
+ QML_FOREIGN(UncreatableNeedsForeign)
+ QML_ELEMENT
+ QML_UNCREATABLE("")
+};
+
+class Creatable : public QObject
+{
+ Q_OBJECT
+ QML_ELEMENT
+public:
+ Creatable(QObject *parent = nullptr) { Q_UNUSED(parent); }; // default constructor in disguise
+};
+
+class Extension : public QObject
+{
+ Q_OBJECT
+
+public:
+ Extension(QObject *parent = nullptr) : QObject(parent) {}
+
+ enum HelloWorld { Hello, Hallo, Bonjour };
+ Q_ENUM(HelloWorld)
+};
+
+class Creatable2 : public QObject
+{
+ Q_OBJECT
+ QML_ELEMENT
+ QML_EXTENDED(Extension)
+public:
+ Creatable2(QObject *parent = nullptr) { Q_UNUSED(parent); }; // default constructor in disguise
+};
+
+class SingletonIncreatableExtended : public QObject
+{
+ Q_OBJECT
+ QML_ELEMENT
+ QML_SINGLETON
+ QML_EXTENDED(Extension)
+ SingletonIncreatableExtended() = delete;
+ static SingletonIncreatableExtended *create(QQmlEngine *, QJSEngine *)
+ {
+ return nullptr;
+ } // should be public
+};
+
+class BadUncreatableExtended : public QObject
+{
+ Q_OBJECT
+ QML_ELEMENT
+ QML_EXTENDED(Extension)
+
+ BadUncreatableExtended() = delete;
+};
+
+class GoodUncreatableExtended : public QObject
+{
+ Q_OBJECT
+ QML_ELEMENT
+ QML_UNCREATABLE("")
+ QML_EXTENDED(Extension)
+
+ GoodUncreatableExtended() = delete;
+};
+
+class FixingBadUncreatable
+{
+ Q_GADGET
+ 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/CMakeLists.txt b/tests/auto/qml/qmltyperegistrar/VersionZero/CMakeLists.txt
new file mode 100644
index 0000000000..0fc5968870
--- /dev/null
+++ b/tests/auto/qml/qmltyperegistrar/VersionZero/CMakeLists.txt
@@ -0,0 +1,24 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+qt_add_library(tst_qmltyperegistrar_major_version_zero)
+qt_autogen_tools_initial_setup(tst_qmltyperegistrar_major_version_zero)
+target_link_libraries(tst_qmltyperegistrar_major_version_zero PRIVATE Qt::Core Qt::Qml)
+qt_enable_autogen_tool(tst_qmltyperegistrar_major_version_zero "moc" ON)
+qt_add_qml_module(tst_qmltyperegistrar_major_version_zero
+ URI VersionZero
+ VERSION 0.1
+ SOURCES
+ version_zero_type.h
+ RESOURCE_PREFIX "/"
+)
+qt_autogen_tools_initial_setup(tst_qmltyperegistrar_major_version_zeroplugin)
+
+# Make sure the backing library is found on Windows next to the executable
+set_target_properties(
+ tst_qmltyperegistrar_major_version_zero
+ PROPERTIES
+ RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/..
+ LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/..
+ ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/..
+)
diff --git a/tests/auto/qml/qmltyperegistrar/VersionZero/version_zero_type.h b/tests/auto/qml/qmltyperegistrar/VersionZero/version_zero_type.h
new file mode 100644
index 0000000000..0ad477c3cb
--- /dev/null
+++ b/tests/auto/qml/qmltyperegistrar/VersionZero/version_zero_type.h
@@ -0,0 +1,17 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#ifndef VERSION_ZERO_TYPE_H
+#define VERSION_ZERO_TYPE_H
+
+#include <QtQml/qqml.h>
+
+class TypeInModuleMajorVersionZero : public QObject
+{
+ Q_OBJECT
+ QML_ELEMENT
+public:
+ TypeInModuleMajorVersionZero(QObject *parent = nullptr) : QObject(parent) {}
+};
+
+#endif // VERSION_ZERO_TYPE_H
diff --git a/tests/auto/qml/qmltyperegistrar/dummy.cpp b/tests/auto/qml/qmltyperegistrar/dummy.cpp
new file mode 100644
index 0000000000..1959bc3816
--- /dev/null
+++ b/tests/auto/qml/qmltyperegistrar/dummy.cpp
@@ -0,0 +1,2 @@
+#include "dummy_p.h"
+int foo() { return 1; }
diff --git a/tests/auto/qml/qmltyperegistrar/dummy_p.h b/tests/auto/qml/qmltyperegistrar/dummy_p.h
new file mode 100644
index 0000000000..e564d3b549
--- /dev/null
+++ b/tests/auto/qml/qmltyperegistrar/dummy_p.h
@@ -0,0 +1,2 @@
+#include <QtCore/qglobal.h>
+Q_DECL_EXPORT int foo();
diff --git a/tests/auto/qml/qmltyperegistrar/duplicatedExports.h b/tests/auto/qml/qmltyperegistrar/duplicatedExports.h
new file mode 100644
index 0000000000..e72a2f19c9
--- /dev/null
+++ b/tests/auto/qml/qmltyperegistrar/duplicatedExports.h
@@ -0,0 +1,95 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#ifndef DUPLICATEDEXPORTS_H
+#define DUPLICATEDEXPORTS_H
+
+#include <QtCore/qobject.h>
+#include <qqml.h>
+
+class Exported : public QObject
+{
+ Q_OBJECT
+public:
+ Exported(QObject *parent = nullptr) : QObject(parent) { }
+};
+
+class ExportedQmlElement : public QObject
+{
+ Q_OBJECT
+ QML_ELEMENT
+ QML_ADDED_IN_VERSION(1, 2)
+public:
+ ExportedQmlElement(QObject *parent = nullptr) : QObject(parent) { }
+};
+
+class ExportedQmlElement2 : public QObject
+{
+ Q_OBJECT
+ QML_NAMED_ELEMENT(ExportedQmlElement)
+ QML_ADDED_IN_VERSION(1, 2)
+public:
+ ExportedQmlElement2(QObject *parent = nullptr) : QObject(parent) { }
+};
+
+class ExportedQmlElementDifferentVersion : public QObject
+{
+ Q_OBJECT
+ QML_NAMED_ELEMENT(ExportedQmlElement)
+ QML_ADDED_IN_VERSION(1, 0)
+ QML_REMOVED_IN_VERSION(1, 7)
+public:
+ ExportedQmlElementDifferentVersion(QObject *parent = nullptr) : QObject(parent) { }
+};
+
+class SameNameSameExport : public QObject
+{
+ Q_OBJECT
+ QML_NAMED_ELEMENT(SameNameSameExport)
+ QML_FOREIGN(Exported)
+ QML_ADDED_IN_VERSION(1, 2)
+public:
+ SameNameSameExport(QObject *parent = nullptr) : QObject(parent) { }
+};
+class SameNameSameExport2 : public QObject
+{
+ Q_OBJECT
+ QML_NAMED_ELEMENT(SameNameSameExport)
+ QML_FOREIGN(Exported)
+ QML_ADDED_IN_VERSION(1, 2)
+public:
+ SameNameSameExport2(QObject *parent = nullptr) : QObject(parent) { }
+};
+class SameNameSameExportDifferentVersion : public QObject
+{
+ Q_OBJECT
+ QML_NAMED_ELEMENT(SameNameSameExport)
+ QML_FOREIGN(Exported)
+ QML_ADDED_IN_VERSION(1, 0)
+public:
+ SameNameSameExportDifferentVersion(QObject *parent = nullptr) : QObject(parent) { }
+};
+
+struct SameName
+{
+ Q_GADGET
+ QML_ELEMENT
+ QML_FOREIGN(Exported);
+ QML_ADDED_IN_VERSION(1, 2)
+};
+struct SameName2
+{
+ Q_GADGET
+ QML_ELEMENT
+ QML_FOREIGN(Exported);
+ QML_ADDED_IN_VERSION(1, 2)
+};
+struct SameNameDifferentVersion
+{
+ Q_GADGET
+ QML_ELEMENT
+ QML_FOREIGN(Exported);
+ QML_ADDED_IN_VERSION(1, 0)
+};
+
+#endif // DUPLICATEDEXPORTS_H
diff --git a/tests/auto/qml/qmltyperegistrar/duplicatedExports.json b/tests/auto/qml/qmltyperegistrar/duplicatedExports.json
new file mode 100644
index 0000000000..0cc5d899f4
--- /dev/null
+++ b/tests/auto/qml/qmltyperegistrar/duplicatedExports.json
@@ -0,0 +1,218 @@
+[
+ {
+ "classes": [
+ {
+ "className": "Exported",
+ "object": true,
+ "qualifiedClassName": "Exported",
+ "superClasses": [
+ {
+ "access": "public",
+ "name": "QObject"
+ }
+ ]
+ },
+ {
+ "classInfos": [
+ {
+ "name": "QML.Element",
+ "value": "auto"
+ },
+ {
+ "name": "QML.AddedInVersion",
+ "value": "258"
+ }
+ ],
+ "className": "ExportedQmlElement",
+ "object": true,
+ "qualifiedClassName": "ExportedQmlElement",
+ "superClasses": [
+ {
+ "access": "public",
+ "name": "QObject"
+ }
+ ]
+ },
+ {
+ "classInfos": [
+ {
+ "name": "QML.Element",
+ "value": "ExportedQmlElement"
+ },
+ {
+ "name": "QML.AddedInVersion",
+ "value": "258"
+ }
+ ],
+ "className": "ExportedQmlElement2",
+ "object": true,
+ "qualifiedClassName": "ExportedQmlElement2",
+ "superClasses": [
+ {
+ "access": "public",
+ "name": "QObject"
+ }
+ ]
+ },
+ {
+ "classInfos": [
+ {
+ "name": "QML.Element",
+ "value": "ExportedQmlElement"
+ },
+ {
+ "name": "QML.AddedInVersion",
+ "value": "256"
+ },
+ {
+ "name": "QML.RemovedInVersion",
+ "value": "263"
+ }
+ ],
+ "className": "ExportedQmlElementDifferentVersion",
+ "object": true,
+ "qualifiedClassName": "ExportedQmlElementDifferentVersion",
+ "superClasses": [
+ {
+ "access": "public",
+ "name": "QObject"
+ }
+ ]
+ },
+ {
+ "classInfos": [
+ {
+ "name": "QML.Element",
+ "value": "SameNameSameExport"
+ },
+ {
+ "name": "QML.Foreign",
+ "value": "Exported"
+ },
+ {
+ "name": "QML.AddedInVersion",
+ "value": "258"
+ }
+ ],
+ "className": "SameNameSameExport",
+ "object": true,
+ "qualifiedClassName": "SameNameSameExport",
+ "superClasses": [
+ {
+ "access": "public",
+ "name": "QObject"
+ }
+ ]
+ },
+ {
+ "classInfos": [
+ {
+ "name": "QML.Element",
+ "value": "SameNameSameExport"
+ },
+ {
+ "name": "QML.Foreign",
+ "value": "Exported"
+ },
+ {
+ "name": "QML.AddedInVersion",
+ "value": "258"
+ }
+ ],
+ "className": "SameNameSameExport2",
+ "object": true,
+ "qualifiedClassName": "SameNameSameExport2",
+ "superClasses": [
+ {
+ "access": "public",
+ "name": "QObject"
+ }
+ ]
+ },
+ {
+ "classInfos": [
+ {
+ "name": "QML.Element",
+ "value": "SameNameSameExport"
+ },
+ {
+ "name": "QML.Foreign",
+ "value": "Exported"
+ },
+ {
+ "name": "QML.AddedInVersion",
+ "value": "256"
+ }
+ ],
+ "className": "SameNameSameExportDifferentVersion",
+ "object": true,
+ "qualifiedClassName": "SameNameSameExportDifferentVersion",
+ "superClasses": [
+ {
+ "access": "public",
+ "name": "QObject"
+ }
+ ]
+ },
+ {
+ "classInfos": [
+ {
+ "name": "QML.Element",
+ "value": "auto"
+ },
+ {
+ "name": "QML.Foreign",
+ "value": "Exported"
+ },
+ {
+ "name": "QML.AddedInVersion",
+ "value": "258"
+ }
+ ],
+ "className": "SameName",
+ "gadget": true,
+ "qualifiedClassName": "SameName"
+ },
+ {
+ "classInfos": [
+ {
+ "name": "QML.Element",
+ "value": "auto"
+ },
+ {
+ "name": "QML.Foreign",
+ "value": "Exported"
+ },
+ {
+ "name": "QML.AddedInVersion",
+ "value": "258"
+ }
+ ],
+ "className": "SameName2",
+ "gadget": true,
+ "qualifiedClassName": "SameName2"
+ },
+ {
+ "classInfos": [
+ {
+ "name": "QML.Element",
+ "value": "auto"
+ },
+ {
+ "name": "QML.Foreign",
+ "value": "Exported"
+ },
+ {
+ "name": "QML.AddedInVersion",
+ "value": "256"
+ }
+ ],
+ "className": "SameNameDifferentVersion",
+ "gadget": true,
+ "qualifiedClassName": "SameNameDifferentVersion"
+ }
+ ],
+ "inputFile": "duplicatedExports.h",
+ "outputRevision": 68
+ }
+]
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 25aed2d8f0..c5ef8313dc 100644
--- a/tests/auto/qml/qmltyperegistrar/foo.cpp
+++ b/tests/auto/qml/qmltyperegistrar/foo.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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) 2021 The Qt Company Ltd.
+// 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 2da5b92fc5..5af2e11eaa 100644
--- a/tests/auto/qml/qmltyperegistrar/foo.h
+++ b/tests/auto/qml/qmltyperegistrar/foo.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#ifndef FOO_H
#define FOO_H
@@ -37,6 +12,12 @@ class Bbb : public QObject
Q_OBJECT
public:
Bbb(QObject *parent = nullptr) : QObject(parent) {}
+
+Q_SIGNALS:
+ void mySignal(QObject *myObject, const QObject *myConstObject, QObject const *myConstObject2,
+ QObject *const myObject2, const QObject *const myConstObject3);
+ void myVolatileSignal(volatile const QObject *a, const volatile QObject *b,
+ volatile QObject *nonConst);
};
class Ccc : public QObject
diff --git a/tests/auto/qml/qmltyperegistrar/foreign/.prev_CMakeLists.txt b/tests/auto/qml/qmltyperegistrar/foreign/.prev_CMakeLists.txt
deleted file mode 100644
index 0dcbd16e43..0000000000
--- a/tests/auto/qml/qmltyperegistrar/foreign/.prev_CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-# Generated from foreign.pro.
-
-#####################################################################
-## foreign Generic Library:
-#####################################################################
-
-qt_internal_add_cmake_library(foreign
- STATIC
- SOURCES
- foreign.cpp foreign.h
- PUBLIC_LIBRARIES
- Qt::Core
-)
-
-#### Keys ignored in scope 1:.:.:foreign.pro:<TRUE>:
-# TEMPLATE = "lib"
-
-## Scopes:
-#####################################################################
diff --git a/tests/auto/qml/qmltyperegistrar/foreign/CMakeLists.txt b/tests/auto/qml/qmltyperegistrar/foreign/CMakeLists.txt
index ad967cdbf0..68223ae6a5 100644
--- a/tests/auto/qml/qmltyperegistrar/foreign/CMakeLists.txt
+++ b/tests/auto/qml/qmltyperegistrar/foreign/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
# Generated from foreign.pro.
#####################################################################
@@ -8,6 +11,7 @@ qt_internal_add_cmake_library(foreign
STATIC
SOURCES
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 db080a5cad..1691f5396a 100644
--- a/tests/auto/qml/qmltyperegistrar/foreign/foreign.cpp
+++ b/tests/auto/qml/qmltyperegistrar/foreign/foreign.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 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) 2020 The Qt Company Ltd.
+// 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 dc9fbc84a8..79ac8074cf 100644
--- a/tests/auto/qml/qmltyperegistrar/foreign/foreign.h
+++ b/tests/auto/qml/qmltyperegistrar/foreign/foreign.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 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) 2020 The Qt Company Ltd.
+// 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/private/foreign_p.h b/tests/auto/qml/qmltyperegistrar/foreign/private/foreign_p.h
new file mode 100644
index 0000000000..ed23d78284
--- /dev/null
+++ b/tests/auto/qml/qmltyperegistrar/foreign/private/foreign_p.h
@@ -0,0 +1,18 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#ifndef FOREIGN_P_H
+#define FOREIGN_P_H
+
+#include <QtCore/qobject.h>
+
+// qmltyperegistrar will assume this file is reachable under <private/foreign_p.h>
+// See the trick in tst_qmltyperegistrar's CMakeLists.txt to turn on the --private-includes option.
+class ForeignPrivate : public QObject
+{
+ Q_OBJECT
+Q_SIGNALS:
+ void happens();
+};
+
+#endif // FOREIGN_P_H
diff --git a/tests/auto/qml/qmltyperegistrar/hppheader.hpp b/tests/auto/qml/qmltyperegistrar/hppheader.hpp
index f5fc881b77..4278601a9e 100644
--- a/tests/auto/qml/qmltyperegistrar/hppheader.hpp
+++ b/tests/auto/qml/qmltyperegistrar/hppheader.hpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 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) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#ifndef HPPHEADER_HPP
#define HPPHEADER_HPP
@@ -37,12 +12,11 @@ class HppClass : public QObject
Q_OBJECT
QML_ELEMENT
Q_PROPERTY(int eieiei READ eieiei WRITE setEieiei NOTIFY eieieiChanged)
+ Q_PROPERTY(int eieiei2 READ eieiei2)
public:
- int eieiei() const
- {
- return m_eieiei;
- }
+ int eieiei() const { return m_eieiei; }
+ int eieiei2() const { return m_eieiei2; }
public slots:
void setEieiei(int eieiei)
@@ -59,6 +33,7 @@ signals:
private:
int m_eieiei;
+ int m_eieiei2;
};
#endif // 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 3b6cb6d72c..2b3579a34b 100644
--- a/tests/auto/qml/qmltyperegistrar/noextheader
+++ b/tests/auto/qml/qmltyperegistrar/noextheader
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 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) 2020 The Qt Company Ltd.
+// 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 798aab03b1..7ea5dcb51c 100644
--- a/tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.cpp
+++ b/tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 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) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include "tst_qmltyperegistrar.h"
#include <QtTest/qtest.h>
@@ -32,6 +7,10 @@
#include <QtCore/qfile.h>
#include <QtQml/QQmlEngine>
#include <QtQml/QQmlComponent>
+#include <QtQml/qqmlprivate.h>
+
+#include "hppheader.hpp"
+#include "UnregisteredTypes/uncreatable.h"
void tst_qmltyperegistrar::initTestCase()
{
@@ -60,6 +39,30 @@ void tst_qmltyperegistrar::qmltypesHasReadAndWrite()
QVERIFY(qmltypesData.contains(R"(write: "setEieiei")"));
}
+void tst_qmltyperegistrar::qmltypesHasNotify()
+{
+ QVERIFY(qmltypesData.contains(R"(notify: "eieieiChanged")"));
+}
+
+void tst_qmltyperegistrar::qmltypesHasPropertyIndex()
+{
+ qsizetype start = qmltypesData.indexOf("notify: \"eieieiChanged\"");
+ qsizetype end = qmltypesData.indexOf("}", start);
+ // [start, end) - range in which index information of eieiei should exist
+ QVERIFY(qmltypesData.indexOf("index: 0", start) < end); // belongs to eieiei
+
+ start = qmltypesData.indexOf("read: \"eieiei2\"");
+ end = qmltypesData.indexOf("}", start);
+ QVERIFY(qmltypesData.indexOf("index: 1", start) < end); // belongs to eieiei2
+
+ HppClass eieieiClass;
+ const QMetaObject *mo = eieieiClass.metaObject();
+ QVERIFY(mo);
+ // NB: add 0 and 1 as relative indices "parsed" from qmltypesData
+ QCOMPARE(mo->indexOfProperty("eieiei"), mo->propertyOffset() + 0);
+ QCOMPARE(mo->indexOfProperty("eieiei2"), mo->propertyOffset() + 1);
+}
+
void tst_qmltyperegistrar::qmltypesHasFileNames()
{
QVERIFY(qmltypesData.contains("file: \"hppheader.hpp\""));
@@ -79,8 +82,8 @@ void tst_qmltyperegistrar::superAndForeignTypes()
QVERIFY(qmltypesData.contains("values: [\"Pixel\", \"Centimeter\", \"Inch\", \"Point\"]"));
QVERIFY(qmltypesData.contains("name: \"SizeGadget\""));
QVERIFY(qmltypesData.contains("prototype: \"SizeEnums\""));
- QVERIFY(qmltypesData.contains("Property { name: \"height\"; type: \"int\"; read: \"height\"; write: \"setHeight\" }"));
- QVERIFY(qmltypesData.contains("Property { name: \"width\"; type: \"int\"; read: \"width\"; write: \"setWidth\" }"));
+ QVERIFY(qmltypesData.contains("Property { name: \"height\"; type: \"int\"; read: \"height\"; write: \"setHeight\"; index: 0; isFinal: true }"));
+ QVERIFY(qmltypesData.contains("Property { name: \"width\"; type: \"int\"; read: \"width\"; write: \"setWidth\"; index: 0; isFinal: true }"));
QVERIFY(qmltypesData.contains("Method { name: \"sizeToString\"; type: \"QString\" }"));
QCOMPARE(qmltypesData.count("extension: \"SizeValueType\""), 1);
}
@@ -93,8 +96,7 @@ void tst_qmltyperegistrar::accessSemantics()
void tst_qmltyperegistrar::isBindable()
{
- // TODO: readonly?
- QVERIFY(qmltypesData.contains(R"(Property { name: "someProperty"; bindable: "bindableSomeProperty"; type: "int"; isReadonly: true)"));
+ QVERIFY(qmltypesData.contains(R"(Property { name: "someProperty"; type: "int"; bindable: "bindableSomeProperty"; index: 0 })"));
}
void tst_qmltyperegistrar::restrictToImportVersion()
@@ -114,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()
@@ -143,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);
};
@@ -153,6 +155,7 @@ void tst_qmltyperegistrar::metaTypesRegistered()
verifyMetaType("Ooo*", "Ooo");
verifyMetaType("Bbb*", "Bbb");
verifyMetaType("Ccc*", "Ccc");
+ verifyMetaType("SelfExtensionHack", "SelfExtensionHack");
}
void tst_qmltyperegistrar::multiExtensions()
@@ -205,4 +208,833 @@ void tst_qmltyperegistrar::requiredProperty()
QCOMPARE(qmltypesData.count("isRequired: true"), 1);
}
+void tst_qmltyperegistrar::hiddenAccessor()
+{
+ const auto start = qmltypesData.indexOf("name: \"hiddenRead\""); // rely on name being 1st field
+ QVERIFY(start != -1);
+ const auto end = qmltypesData.indexOf("}", start); // enclosing '}' of hiddenRead property
+ QVERIFY(end != -1);
+ QVERIFY(start < end);
+
+ const auto hiddenReadData = QByteArrayView(qmltypesData).sliced(start, end - start);
+ // QVERIFY(hiddenReadData.contains("name: \"hiddenRead\"")); // tested above by start != -1
+ QVERIFY(hiddenReadData.contains("type: \"QString\""));
+ QVERIFY(hiddenReadData.contains("read: \"hiddenRead\""));
+ QVERIFY(hiddenReadData.contains("privateClass: \"HiddenAccessorsPrivate\""));
+ QVERIFY(hiddenReadData.contains("isReadonly: true"));
+}
+
+void tst_qmltyperegistrar::finalProperty()
+{
+ QCOMPARE(qmltypesData.count("name: \"FinalProperty\""), 1);
+ QCOMPARE(qmltypesData.count(
+ "Property { name: \"fff\"; type: \"int\"; index: 0; isFinal: true }"),
+ 1);
+}
+
+void tst_qmltyperegistrar::parentProperty()
+{
+ QCOMPARE(qmltypesData.count("parentProperty: \"ppp\""), 1);
+}
+
+void tst_qmltyperegistrar::namespacesAndValueTypes()
+{
+ QQmlEngine engine;
+ QQmlComponent c(&engine);
+ c.setData("import QmlTypeRegistrarTest\nLocal {}", QUrl());
+ QVERIFY2(c.isReady(), qPrintable(c.errorString()));
+ QScopedPointer o(c.create());
+ QVERIFY(!o.isNull());
+
+ auto check = [&](QMetaType m1, QMetaType m2) {
+ QVERIFY(m1.isValid());
+ QVERIFY(m2.isValid());
+
+ // Does not actually help if we have two types with equal IDs. It only compares the IDs.
+ QVERIFY(m1 == m2);
+ QCOMPARE(m1.id(), m2.id());
+
+ // If we had a bogus namespace value type, it wouldn't be able to create the type.
+ void *v1 = m1.create();
+ QVERIFY(v1 != nullptr);
+ m1.destroy(v1);
+
+ void *v2 = m2.create();
+ QVERIFY(v2 != nullptr);
+ m2.destroy(v2);
+
+ QMetaType m3(m1.id());
+ QVERIFY(m3.isValid());
+ void *v3 = m3.create();
+ QVERIFY(v3 != nullptr);
+ m3.destroy(v3);
+ };
+
+ check(QMetaType::fromName("ValueTypeWithEnum1"), QMetaType::fromType<ValueTypeWithEnum1>());
+ check(QMetaType::fromName("ValueTypeWithEnum2"), QMetaType::fromType<ValueTypeWithEnum2>());
+}
+
+void tst_qmltyperegistrar::namespaceExtendedNamespace()
+{
+ QQmlEngine engine;
+ QQmlComponent c(&engine);
+ c.setData("import QtQml\n"
+ "import QmlTypeRegistrarTest\n"
+ "QtObject {\n"
+ " property int b: ForeignNamespace.B\n"
+ " property int f: ForeignNamespace.F\n"
+ "}", QUrl());
+ QVERIFY2(c.isReady(), qPrintable(c.errorString()));
+ QScopedPointer o(c.create());
+ QVERIFY(!o.isNull());
+
+ QCOMPARE(o->property("b").toInt(), int(ExtensionValueType::B));
+ QCOMPARE(o->property("f").toInt(), int(BaseNamespace::F));
+}
+
+void tst_qmltyperegistrar::deferredNames()
+{
+ QVERIFY(qmltypesData.contains("deferredNames: [\"\"]"));
+ QVERIFY(qmltypesData.contains("deferredNames: [\"A\", \"B\", \"C\"]"));
+}
+
+void tst_qmltyperegistrar::immediateNames()
+{
+ QVERIFY(qmltypesData.contains("immediateNames: [\"\"]"));
+ QVERIFY(qmltypesData.contains("immediateNames: [\"A\", \"B\", \"C\"]"));
+}
+
+void tst_qmltyperegistrar::derivedFromForeignPrivate()
+{
+ QVERIFY(qmltypesData.contains("file: \"private/foreign_p.h\""));
+}
+
+void tst_qmltyperegistrar::methodReturnType()
+{
+ QVERIFY(qmltypesData.contains("createAThing"));
+ QVERIFY(!qmltypesData.contains("QQmlComponent*"));
+ QVERIFY(qmltypesData.contains("type: \"QQmlComponent\""));
+}
+
+void tst_qmltyperegistrar::addRemoveVersion_data()
+{
+ QTest::addColumn<QTypeRevision>("importVersion");
+ for (int i = 0; i < 20; ++i)
+ QTest::addRow("v1.%d.qml", i) << QTypeRevision::fromVersion(1, i);
+}
+
+void tst_qmltyperegistrar::addRemoveVersion()
+{
+ QFETCH(QTypeRevision, importVersion);
+
+ const bool creatable
+ = importVersion > QTypeRevision::fromVersion(1, 2)
+ && importVersion < QTypeRevision::fromVersion(1, 18);
+ const bool thingAccessible = importVersion > QTypeRevision::fromVersion(1, 3);
+
+ QQmlEngine engine;
+ QQmlComponent c(&engine);
+ c.setData(QStringLiteral("import QmlTypeRegistrarTest %1.%2\n"
+ "Versioned {\n"
+ " property int thing: revisioned\n"
+ "}")
+ .arg(importVersion.majorVersion()).arg(importVersion.minorVersion()).toUtf8(),
+ QUrl(QTest::currentDataTag()));
+ if (!creatable) {
+ QVERIFY(c.isError());
+ return;
+ }
+ QVERIFY2(c.isReady(), qPrintable(c.errorString()));
+ if (!thingAccessible) {
+ QTest::ignoreMessage(
+ QtWarningMsg,
+ qPrintable(QStringLiteral("%1:3: ReferenceError: revisioned is not defined")
+ .arg(QTest::currentDataTag())));
+ }
+ QScopedPointer o(c.create());
+ QVERIFY(!o.isNull());
+ 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()
+{
+ QQmlEngine engine;
+ QQmlComponent c(&engine);
+ c.setData("import QmlTypeRegistrarTest\n"
+ "ForeignRevisionedProperty {\n"
+ " activeFocusOnTab: true\n"
+ "}",
+ QUrl());
+
+ QVERIFY2(c.isReady(), qPrintable(c.errorString()));
+ QScopedPointer o(c.create());
+ QVERIFY(!o.isNull());
+}
+#endif
+
+void tst_qmltyperegistrar::typeInModuleMajorVersionZero()
+{
+ QQmlEngine engine;
+ QQmlComponent c(&engine);
+ c.setData(QStringLiteral("import VersionZero\n"
+ "TypeInModuleMajorVersionZero {}\n").toUtf8(),
+ QUrl(QTest::currentDataTag()));
+ QVERIFY2(c.isReady(), qPrintable(c.errorString()));
+}
+
+void tst_qmltyperegistrar::resettableProperty()
+{
+ QVERIFY(qmltypesData.contains(R"(reset: "resetFoo")"));
+}
+
+void tst_qmltyperegistrar::duplicateExportWarnings()
+{
+ QmlTypeRegistrar r;
+ QString moduleName = "tstmodule";
+ QString targetNamespace = "tstnamespace";
+ r.setModuleNameAndNamespace(moduleName, targetNamespace);
+
+ MetaTypesJsonProcessor processor(true);
+ QVERIFY(processor.processTypes({ ":/duplicatedExports.json" }));
+ processor.postProcessTypes();
+ QVector<MetaType> types = processor.types();
+ QVector<MetaType> typesforeign = processor.foreignTypes();
+ r.setTypes(types, typesforeign);
+
+ const auto expectWarning = [](const char *message) {
+ QTest::ignoreMessage(QtWarningMsg, message);
+ };
+ 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, "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()
+{
+ QVERIFY(qmltypesData.contains(R"(Signal {
+ name: "clonedSignal"
+ Parameter { name: "i"; type: "int" }
+ })"));
+
+ QVERIFY(qmltypesData.contains(R"(Signal { name: "clonedSignal"; isCloned: true })"));
+}
+
+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: "myObject2"; type: "QObject"; isPointer: true }
+ Parameter { name: "myConstObject3"; type: "QObject"; isPointer: true; isConstant: 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: "nonConst"; type: "volatile QObject"; isPointer: true }
+ }
+)"));
+}
+
+void tst_qmltyperegistrar::uncreatable()
+{
+ using namespace QQmlPrivate;
+
+ // "normal" constructible types
+ QVERIFY(QmlMetaType<Creatable>::hasAcceptableCtors());
+ QVERIFY(QmlMetaType<Creatable2>::hasAcceptableCtors());
+
+ // good singletons
+ 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
+ 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 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 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 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 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 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(!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 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 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
+
+ const auto oldHandler = qInstallMessageHandler(
+ [](QtMsgType, const QMessageLogContext &, const QString &message) {
+ QFAIL(qPrintable(message));
+ });
+ const auto guard = qScopeGuard([oldHandler](){qInstallMessageHandler(oldHandler); });
+
+ // These should not print any messages.
+
+ qmlRegisterTypesAndRevisions<Creatable>("A", 1);
+ qmlRegisterTypesAndRevisions<Creatable2>("A", 1);
+
+ qmlRegisterTypesAndRevisions<SingletonCreatable>("A", 1);
+ qmlRegisterTypesAndRevisions<SingletonCreatable2>("A", 1);
+ qmlRegisterTypesAndRevisions<SingletonCreatable3>("A", 1);
+
+ qmlRegisterTypesAndRevisions<GoodUncreatable>("A", 1);
+ qmlRegisterTypesAndRevisions<GoodUncreatable2>("A", 1);
+ 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.
+ // The current version is 1.1, so it's 1.0.
+ 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"]
+ isCreatable: true
+ 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"]
+ isCreatable: true
+ 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"]
+ isCreatable: true
+ exportMetaObjectRevisions: [256]
+ Enum {
+ name: "UChar"
+ type: "uchar"
+ values: ["V0"]
+ }
+ Enum {
+ name: "Int8_T"
+ type: "int8_t"
+ values: ["V1"]
+ }
+ Enum {
+ name: "UInt8_T"
+ type: "uint8_t"
+ values: ["V2"]
+ }
+ Enum {
+ name: "Int16_T"
+ type: "int16_t"
+ values: ["V3"]
+ }
+ Enum {
+ name: "UInt16_T"
+ type: "uint16_t"
+ values: ["V4"]
+ }
+ Enum {
+ name: "Int32_T"
+ type: "int32_t"
+ values: ["V5"]
+ }
+ Enum {
+ name: "UInt32_T"
+ type: "uint32_t"
+ values: ["V6"]
+ }
+ Enum {
+ name: "S"
+ type: "qint16"
+ values: ["A", "B", "C"]
+ }
+ Enum {
+ name: "T"
+ type: "quint16"
+ 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: "QList<QObject*>" }
+ }
+ })"));
+}
+
+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
+ isConstant: true
+ }
+ })"));
+
+ QVERIFY(qmltypesData.contains(R"(Component {
+ file: "tst_qmltyperegistrar.h"
+ name: "Testing::Bar"
+ accessSemantics: "reference"
+ prototype: "Testing::Foo"
+ exports: ["QmlTypeRegistrarTest/Bar 1.0"]
+ isCreatable: true
+ exportMetaObjectRevisions: [256]
+ Property { name: "barProp"; type: "int"; read: "bar"; index: 0; isReadonly: true; isConstant: 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; isConstant: 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"]
+ isCreatable: true
+ 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"
+ ]
+ isCreatable: true
+ 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"]
+ isCreatable: true
+ 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"
+ ]
+ isCreatable: true
+ 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"]
+ isCreatable: true
+ exportMetaObjectRevisions: [256]
+ Property { name: "a"; type: "qint64"; index: 0 }
+ Property { name: "b"; type: "int64_t"; index: 1 }
+ Property { name: "c"; type: "quint64"; index: 2 }
+ Property { name: "d"; type: "uint64_t"; 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"]
+ isCreatable: true
+ exportMetaObjectRevisions: [256]
+ Method { name: "getObject"; type: "QObject"; isPointer: true; isConstant: 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"]
+ isCreatable: true
+ exportMetaObjectRevisions: [256]
+ Property { name: "a"; type: "int"; read: "a"; index: 0; isReadonly: true; isConstant: true }
+ })"));
+}
+
QTEST_MAIN(tst_qmltyperegistrar)
diff --git a/tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.h b/tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.h
index 8d934d4996..efb40fd426 100644
--- a/tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.h
+++ b/tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.h
@@ -1,63 +1,49 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 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) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#ifndef TST_QMLTYPEREGISTRAR_H
#define TST_QMLTYPEREGISTRAR_H
#include "foreign.h"
+#include "private/foreign_p.h"
+
+#include <QtQmlTypeRegistrar/private/qqmltyperegistrar_p.h>
+
+#ifdef QT_QUICK_LIB
+# include <QtQuick/qquickitem.h>
+#endif
#include <QtQml/qqml.h>
+#include <QtQml/qqmlcomponent.h>
+
+#include <QtCore/qabstractitemmodel.h>
#include <QtCore/qproperty.h>
+#include <QtCore/qrect.h>
+#include <QtCore/qtemporaryfile.h>
#include <QtCore/qtimeline.h>
-class Interface {};
+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
@@ -199,7 +185,7 @@ class DerivedFromForeign : public QTimeLine
Q_OBJECT
QML_ELEMENT
public:
- DerivedFromForeign(QObject *parent) : QTimeLine(1000, parent) {}
+ DerivedFromForeign(QObject *parent = nullptr) : QTimeLine(1000, parent) { }
};
class ExtensionA : public QObject
@@ -247,6 +233,15 @@ private:
int m_foo;
};
+class FinalProperty : public QObject
+{
+ Q_OBJECT
+ QML_ELEMENT
+ Q_PROPERTY(int fff MEMBER fff FINAL)
+public:
+ int fff = 0;
+};
+
class MultiExtension : public MultiExtensionParent
{
Q_OBJECT
@@ -258,6 +253,563 @@ public:
int e() const { return 'e'; }
};
+class HiddenAccessorsPrivate
+{
+public:
+ QString hiddenRead() const { return QStringLiteral("bar"); }
+};
+
+class HiddenAccessors : public QObject
+{
+ Q_OBJECT
+ Q_PRIVATE_PROPERTY(HiddenAccessors::d_func(), QString hiddenRead READ hiddenRead CONSTANT)
+ QML_ELEMENT
+ Q_DECLARE_PRIVATE(HiddenAccessors)
+};
+
+struct SelfExtensionHack
+{
+ QRectF rect;
+ Q_GADGET
+ QML_EXTENDED(SelfExtensionHack)
+ QML_FOREIGN(QRectF)
+ QML_VALUE_TYPE(recterei)
+};
+
+class ParentProperty : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QObject *ppp READ ppp BINDABLE pppBindable)
+ QML_ELEMENT
+ Q_CLASSINFO("ParentProperty", "ppp")
+public:
+
+ QObject *ppp() const { return m_parent.value(); }
+ QBindable<QObject *> pppBindable() { return QBindable<QObject *>(&m_parent); }
+
+private:
+ QProperty<QObject *> m_parent;
+};
+
+
+class ValueTypeWithEnum1
+{
+ Q_GADGET
+ Q_PROPERTY(ValueTypeWithEnum1::Quality quality READ quality WRITE setQuality)
+public:
+ enum Quality
+ {
+ VeryLowQuality,
+ LowQuality,
+ NormalQuality,
+ HighQuality,
+ VeryHighQuality
+ };
+ Q_ENUM(Quality)
+
+ Quality quality() const { return m_quality; }
+ void setQuality(Quality quality) { m_quality = quality; }
+
+private:
+ Quality m_quality = HighQuality;
+};
+
+// value type alphabetically first
+struct AValueTypeWithEnumForeign1
+{
+ Q_GADGET
+ QML_FOREIGN(ValueTypeWithEnum1)
+ QML_NAMED_ELEMENT(valueTypeWithEnum1)
+};
+
+// namespace alphabetically second
+namespace BValueTypeWithEnumForeignNamespace1
+{
+ Q_NAMESPACE
+ QML_FOREIGN_NAMESPACE(ValueTypeWithEnum1)
+ QML_NAMED_ELEMENT(ValueTypeWithEnum1)
+};
+
+class ValueTypeWithEnum2
+{
+ Q_GADGET
+ Q_PROPERTY(ValueTypeWithEnum2::Quality quality READ quality WRITE setQuality)
+public:
+ enum Quality
+ {
+ VeryLowQuality,
+ LowQuality,
+ NormalQuality,
+ HighQuality,
+ VeryHighQuality
+ };
+ Q_ENUM(Quality)
+
+ Quality quality() const { return m_quality; }
+ void setQuality(Quality quality) { m_quality = quality; }
+
+private:
+ Quality m_quality = HighQuality;
+};
+
+// namespace alphabetically first
+namespace AValueTypeWithEnumForeignNamespace2
+{
+ Q_NAMESPACE
+ QML_FOREIGN_NAMESPACE(ValueTypeWithEnum2)
+ QML_NAMED_ELEMENT(ValueTypeWithEnum2)
+};
+
+// value type alphabetically second
+struct BValueTypeWithEnumForeign2
+{
+ Q_GADGET
+ QML_FOREIGN(ValueTypeWithEnum2)
+ QML_NAMED_ELEMENT(valueTypeWithEnum2)
+};
+
+
+namespace BaseNamespace
+{
+Q_NAMESPACE
+enum BBB {
+ D, E, F
+};
+Q_ENUM_NS(BBB)
+}
+
+struct ExtensionValueType
+{
+ Q_GADGET
+public:
+ enum EEE {
+ A, B, C
+ };
+ Q_ENUM(EEE)
+};
+
+struct DeferredPropertyNamesEmpty : public QObject
+{
+ Q_OBJECT
+ QML_ELEMENT
+ Q_CLASSINFO("DeferredPropertyNames", "")
+};
+
+struct DeferredPropertyNames : public QObject
+{
+ Q_OBJECT
+ QML_ELEMENT
+ Q_CLASSINFO("DeferredPropertyNames", "A,B,C")
+};
+
+struct ImmediatePropertyNamesEmpty : public QObject
+{
+ Q_OBJECT
+ QML_ELEMENT
+ Q_CLASSINFO("ImmediatePropertyNames", "")
+};
+
+struct ImmediatePropertyNames : public QObject
+{
+ Q_OBJECT
+ QML_ELEMENT
+ Q_CLASSINFO("ImmediatePropertyNames", "A,B,C")
+};
+
+namespace ForeignNamespace
+{
+Q_NAMESPACE
+QML_FOREIGN_NAMESPACE(BaseNamespace)
+QML_NAMESPACE_EXTENDED(ExtensionValueType)
+QML_ELEMENT
+}
+
+class DerivedFromForeignPrivate : public ForeignPrivate
+{
+ Q_OBJECT
+ QML_ELEMENT
+};
+
+class WithMethod : public QObject
+{
+ Q_OBJECT
+ QML_ELEMENT
+public:
+ Q_INVOKABLE QQmlComponent *createAThing(int) { return nullptr; }
+};
+
+#ifdef QT_QUICK_LIB
+class ForeignRevisionedProperty : public QQuickItem
+{
+ Q_OBJECT
+ QML_ELEMENT
+
+public:
+ explicit ForeignRevisionedProperty(QQuickItem *parent = nullptr) : QQuickItem(parent) {};
+};
+#endif
+
+class AddedInLateVersion : public QObject
+{
+ Q_OBJECT
+ QML_NAMED_ELEMENT(Versioned)
+ QML_ADDED_IN_VERSION(1, 8)
+ Q_PROPERTY(int revisioned READ revisioned CONSTANT REVISION(1, 4))
+ Q_PROPERTY(int insane READ revisioned CONSTANT REVISION 17)
+public:
+ AddedInLateVersion(QObject *parent = nullptr) : QObject(parent) {}
+ 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
+ QML_NAMED_ELEMENT(Versioned)
+ QML_ADDED_IN_VERSION(1, 3)
+ QML_REMOVED_IN_VERSION(1, 8)
+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
+ QML_ELEMENT
+ Q_PROPERTY(int foo READ foo WRITE setFoo RESET resetFoo NOTIFY fooChanged)
+public:
+ HasResettableProperty(QObject *parent = nullptr) : QObject(parent) {}
+
+ int foo() const { return m_foo; }
+ void setFoo(int newFoo)
+ {
+ if (m_foo == newFoo)
+ return;
+ m_foo = newFoo;
+ emit fooChanged();
+ }
+ void resetFoo() { setFoo(12); }
+
+signals:
+ void fooChanged();
+
+private:
+ int m_foo = 12;
+};
+
+class ClonedSignal : public QObject
+{
+ Q_OBJECT
+ QML_ELEMENT
+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 tst_qmltyperegistrar : public QObject
{
Q_OBJECT
@@ -267,6 +819,8 @@ private slots:
void qmltypesHasForeign();
void qmltypesHasHppClassAndNoext();
void qmltypesHasReadAndWrite();
+ void qmltypesHasNotify();
+ void qmltypesHasPropertyIndex();
void qmltypesHasFileNames();
void qmltypesHasFlags();
void superAndForeignTypes();
@@ -281,6 +835,55 @@ private slots:
void multiExtensions();
void localDefault();
void requiredProperty();
+ void hiddenAccessor();
+ void finalProperty();
+ void parentProperty();
+ void namespacesAndValueTypes();
+ void namespaceExtendedNamespace();
+ void deferredNames();
+ void immediateNames();
+ void derivedFromForeignPrivate();
+ void methodReturnType();
+ void hasIsConstantInParameters();
+ void uncreatable();
+ void singletonVersions();
+
+#ifdef QT_QUICK_LIB
+ void foreignRevisionedProperty();
+#endif
+
+ 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();
private:
QByteArray qmltypesData;