diff options
Diffstat (limited to 'tests/auto/qml/qmltyperegistrar')
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; |