From d39f324d79f76c4d1656b4bd6a0b768138d8fc8f Mon Sep 17 00:00:00 2001 From: Pierre Lamot Date: Thu, 6 Jun 2024 18:05:45 +0200 Subject: [PATCH] qt module: add qml module test --- test cases/frameworks/39 qt qml/Basic.qml | 5 ++ test cases/frameworks/39 qt qml/Internal.qml | 5 ++ test cases/frameworks/39 qt qml/Main.qml | 47 ++++++++++ .../frameworks/39 qt qml/QmlCppExposed.hpp | 25 ++++++ .../39 qt qml/QmlCppOtherExposed.hpp | 25 ++++++ test cases/frameworks/39 qt qml/QmlMain.cpp | 19 ++++ .../frameworks/39 qt qml/QmlSingleton.qml | 10 +++ test cases/frameworks/39 qt qml/custom_qmldir | 4 + .../frameworks/39 qt qml/custom_qmldir.qrc | 5 ++ test cases/frameworks/39 qt qml/meson.build | 89 +++++++++++++++++++ .../frameworks/39 qt qml/meson_options.txt | 1 + .../39 qt qml/subdir/SubdirHeader.hpp | 27 ++++++ .../frameworks/39 qt qml/subdir/Thing.qml | 5 ++ test cases/frameworks/39 qt qml/test.json | 22 +++++ 14 files changed, 289 insertions(+) create mode 100644 test cases/frameworks/39 qt qml/Basic.qml create mode 100644 test cases/frameworks/39 qt qml/Internal.qml create mode 100644 test cases/frameworks/39 qt qml/Main.qml create mode 100644 test cases/frameworks/39 qt qml/QmlCppExposed.hpp create mode 100644 test cases/frameworks/39 qt qml/QmlCppOtherExposed.hpp create mode 100644 test cases/frameworks/39 qt qml/QmlMain.cpp create mode 100644 test cases/frameworks/39 qt qml/QmlSingleton.qml create mode 100644 test cases/frameworks/39 qt qml/custom_qmldir create mode 100644 test cases/frameworks/39 qt qml/custom_qmldir.qrc create mode 100644 test cases/frameworks/39 qt qml/meson.build create mode 100644 test cases/frameworks/39 qt qml/meson_options.txt create mode 100644 test cases/frameworks/39 qt qml/subdir/SubdirHeader.hpp create mode 100644 test cases/frameworks/39 qt qml/subdir/Thing.qml create mode 100644 test cases/frameworks/39 qt qml/test.json diff --git a/test cases/frameworks/39 qt qml/Basic.qml b/test cases/frameworks/39 qt qml/Basic.qml new file mode 100644 index 000000000000..33c0a28c70b0 --- /dev/null +++ b/test cases/frameworks/39 qt qml/Basic.qml @@ -0,0 +1,5 @@ +import QtQuick 2.0 + +Item { + property int ok: 1 +} diff --git a/test cases/frameworks/39 qt qml/Internal.qml b/test cases/frameworks/39 qt qml/Internal.qml new file mode 100644 index 000000000000..e8eee472379b --- /dev/null +++ b/test cases/frameworks/39 qt qml/Internal.qml @@ -0,0 +1,5 @@ +import QtQuick + +Item { + property int ok: 5 +} diff --git a/test cases/frameworks/39 qt qml/Main.qml b/test cases/frameworks/39 qt qml/Main.qml new file mode 100644 index 000000000000..5e9dcf45c08c --- /dev/null +++ b/test cases/frameworks/39 qt qml/Main.qml @@ -0,0 +1,47 @@ +import QtQuick +import My.Module1 as M1 +import My.Module2 as M2 +import My.Module3 as M3 +import My.Module4 as M4 +import My.Module5 as M5 + +Item { + + M1.Basic { id: b1 } + M1.Thing { id: t1 } + M1.QmlCppExposed { id: c1 } + + M2.Thing { id: t2 } + + M3.Basic { id: b3 } + + M4.BasicAliased { id: b4 } + + M5.SubdirHeader { id: s5 } + + Component.onCompleted: { + function checkClass(display, id, value) { + if (id.ok !== value) { + console.log(display, "KO got", id.ok, "expected", value) + Qt.exit(-1) + } + else + console.log(display, "OK") + } + + checkClass("M1.Basic", b1, 1); + checkClass("M1.Thing", t1, 2); + checkClass("M1.QmlCppExposed", c1, 3); + checkClass("M1.QmlSingleton", M1.QmlSingleton, 5); + + checkClass("M2.Thing", t2, 2); + + checkClass("M3.Basic", b3, 1); + + checkClass("M4.BasicAliased", b4, 1); + + checkClass("M5.SubdirHeader", s5, 6); + + Qt.quit() + } +} diff --git a/test cases/frameworks/39 qt qml/QmlCppExposed.hpp b/test cases/frameworks/39 qt qml/QmlCppExposed.hpp new file mode 100644 index 000000000000..10568c8b717e --- /dev/null +++ b/test cases/frameworks/39 qt qml/QmlCppExposed.hpp @@ -0,0 +1,25 @@ +#pragma once +#include +#include + +class QmlCppExposed : public QObject +{ + Q_OBJECT + QML_ELEMENT + Q_PROPERTY(int ok READ getOk WRITE setOk NOTIFY okChanged) + +public: + inline int getOk() const { return m_ok; } + inline void setOk(int value) { + if (value == m_ok) + return; + m_ok = value; + emit okChanged(); + } + +signals: + void okChanged(); + +private: + int m_ok = 3; +}; diff --git a/test cases/frameworks/39 qt qml/QmlCppOtherExposed.hpp b/test cases/frameworks/39 qt qml/QmlCppOtherExposed.hpp new file mode 100644 index 000000000000..78426163566f --- /dev/null +++ b/test cases/frameworks/39 qt qml/QmlCppOtherExposed.hpp @@ -0,0 +1,25 @@ +#pragma once +#include +#include + +class QmlCppOtherExposed : public QObject +{ + Q_OBJECT + QML_ELEMENT + Q_PROPERTY(int ok READ getOk WRITE setOk NOTIFY okChanged) + +public: + inline int getOk() const { return m_ok; } + inline void setOk(int value) { + if (value == m_ok) + return; + m_ok = value; + emit okChanged(); + } + +signals: + void okChanged(); + +private: + int m_ok = 42; +}; diff --git a/test cases/frameworks/39 qt qml/QmlMain.cpp b/test cases/frameworks/39 qt qml/QmlMain.cpp new file mode 100644 index 000000000000..003731dfa348 --- /dev/null +++ b/test cases/frameworks/39 qt qml/QmlMain.cpp @@ -0,0 +1,19 @@ +#include +#include +#include + +int main(int argCount, char* argVector[]) +{ + QGuiApplication app(argCount, argVector); + QQmlApplicationEngine engine; + QObject::connect(&engine, &QQmlApplicationEngine::objectCreated, [](QObject *object, const QUrl &url){ + if (object == nullptr) { + qFatal("unable to load scene"); + } + }); + + engine.addImportPath("qrc:///qt/qml"); + engine.addImportPath("qrc:///test"); + engine.load("qrc:///qt/qml/My/Module0/Main.qml"); + return app.exec(); +} diff --git a/test cases/frameworks/39 qt qml/QmlSingleton.qml b/test cases/frameworks/39 qt qml/QmlSingleton.qml new file mode 100644 index 000000000000..73ea95d11bf6 --- /dev/null +++ b/test cases/frameworks/39 qt qml/QmlSingleton.qml @@ -0,0 +1,10 @@ +pragma Singleton +import QtQuick + +Item { + property alias ok: sub.ok + + Internal { + id: sub + } +} diff --git a/test cases/frameworks/39 qt qml/custom_qmldir b/test cases/frameworks/39 qt qml/custom_qmldir new file mode 100644 index 000000000000..9d84db651401 --- /dev/null +++ b/test cases/frameworks/39 qt qml/custom_qmldir @@ -0,0 +1,4 @@ +module My.Module4 +prefer :/qt/qml/My/Module4/ +BasicAliased 1.0 Basic.qml +Thing 1.0 Thing.qml diff --git a/test cases/frameworks/39 qt qml/custom_qmldir.qrc b/test cases/frameworks/39 qt qml/custom_qmldir.qrc new file mode 100644 index 000000000000..bee52092c587 --- /dev/null +++ b/test cases/frameworks/39 qt qml/custom_qmldir.qrc @@ -0,0 +1,5 @@ + + + custom_qmldir + + diff --git a/test cases/frameworks/39 qt qml/meson.build b/test cases/frameworks/39 qt qml/meson.build new file mode 100644 index 000000000000..0aa25fe52b48 --- /dev/null +++ b/test cases/frameworks/39 qt qml/meson.build @@ -0,0 +1,89 @@ +project('qt6 qml build test', 'cpp', + meson_version: '>= 1.7.0', + # Qt6 requires C++ 17 support + default_options : ['cpp_std=c++17'] +) + +qt_modules = ['Core', 'Gui', 'Qml'] + +qtdep = dependency('qt6', modules : qt_modules, main : true, private_headers: true, required : false, method : get_option('method')) +if not qtdep.found() + error('MESON_SKIP_TEST qt6 not found.') +endif + +qtmodule = import('qt6') + +qmlmodule1 = qtmodule.qml_module( + 'My.Module1', + version: '1.0', + qml_sources: files('Basic.qml', 'subdir/Thing.qml'), + qml_singletons: files('QmlSingleton.qml'), + qml_internals: files('Internal.qml'), + moc_headers: files('QmlCppExposed.hpp', 'QmlCppOtherExposed.hpp'), + designer_supported: true, + dependencies: [qtdep], + install: true +) + +#with a different resource prefix +qmlmodule2 = qtmodule.qml_module( + 'My.Module2', + version: '1.0', + qml_sources: files('Basic.qml', 'subdir/Thing.qml'), + resources_prefix: '/test', + dependencies: [qtdep], +) + +#build without cachegen +qmlmodule3 = qtmodule.qml_module( + 'My.Module3', + version: '1.10.42', + qml_sources: files('Basic.qml', 'subdir/Thing.qml'), + cachegen: false, + dependencies: [qtdep], +) + +#build without cachegen +qmlmodule4 = qtmodule.qml_module( + 'My.Module4', + qml_sources: files('Basic.qml', 'subdir/Thing.qml'), + generate_qmldir: false, + dependencies: [qtdep], +) + +qmlmodule4_res = qtmodule.compile_resources( + name : 'qmlmodule4_resource', + sources : files(['custom_qmldir.qrc']), + method : get_option('method') +) + +#a module with only C++ classes +cpponly_module = qtmodule.qml_module( + 'My.Module5', + version: '1.0', + moc_headers: files('subdir/SubdirHeader.hpp'), + dependencies: [qtdep], + install: true +) + +#qml entry point and qmldir dependecies +qmlmodule0 = qtmodule.qml_module( + 'My.Module0', + version: '1.0', + qml_sources: files('Main.qml'), + imports: ['QtQuick/2.0', 'My.Module1'], + optional_imports: ['My.Module2/auto'], + dependencies: [qtdep], +) + +qmltest = executable( + 'qmlmodule', + sources : [ + 'QmlMain.cpp', qmlmodule0, qmlmodule1, qmlmodule2, + qmlmodule3, qmlmodule4, qmlmodule4_res, cpponly_module + ], + dependencies : qtdep, + # headers in subdirectory needs to have their include path explicitly + # added for the code generated by by qmltyperegistrar. see QTBUG-87221 + include_directories: include_directories('subdir'), +) diff --git a/test cases/frameworks/39 qt qml/meson_options.txt b/test cases/frameworks/39 qt qml/meson_options.txt new file mode 100644 index 000000000000..bc1069ebc881 --- /dev/null +++ b/test cases/frameworks/39 qt qml/meson_options.txt @@ -0,0 +1 @@ +option('method', type : 'string', value : 'auto', description : 'The method to use to find Qt') diff --git a/test cases/frameworks/39 qt qml/subdir/SubdirHeader.hpp b/test cases/frameworks/39 qt qml/subdir/SubdirHeader.hpp new file mode 100644 index 000000000000..019a1692335d --- /dev/null +++ b/test cases/frameworks/39 qt qml/subdir/SubdirHeader.hpp @@ -0,0 +1,27 @@ +#pragma once +#include +#include + +#include "QmlCppExposed.hpp" + +class SubdirHeader : public QObject +{ + Q_OBJECT + QML_ELEMENT + Q_PROPERTY(int ok READ getOk WRITE setOk NOTIFY okChanged) + +public: + inline int getOk() const { return m_ok; } + inline void setOk(int value) { + if (value == m_ok) + return; + m_ok = value; + emit okChanged(); + } + +signals: + void okChanged(); + +private: + int m_ok = 6; +}; diff --git a/test cases/frameworks/39 qt qml/subdir/Thing.qml b/test cases/frameworks/39 qt qml/subdir/Thing.qml new file mode 100644 index 000000000000..5b015c35ca01 --- /dev/null +++ b/test cases/frameworks/39 qt qml/subdir/Thing.qml @@ -0,0 +1,5 @@ +import QtQuick 2.0 + +Item { + property int ok: 2 +} diff --git a/test cases/frameworks/39 qt qml/test.json b/test cases/frameworks/39 qt qml/test.json new file mode 100644 index 000000000000..54d6e90d92bc --- /dev/null +++ b/test cases/frameworks/39 qt qml/test.json @@ -0,0 +1,22 @@ +{ + "matrix": { + "options": { + "method": [ + { "val": "config-tool" }, + { "val": "qmake" }, + { "val": "pkg-config" } + ] + } + }, + "installed": [ + {"type": "file", "file": "usr/qml/My/Module1/QmlSingleton.qml"}, + {"type": "file", "file": "usr/qml/My/Module1/qmldir"}, + {"type": "file", "file": "usr/qml/My/Module1/Basic.qml"}, + {"type": "file", "file": "usr/qml/My/Module1/Internal.qml"}, + {"type": "file", "file": "usr/qml/My/Module1/Thing.qml"}, + {"type": "file", "file": "usr/qml/My/Module1/My_Module1.qmltypes"}, + {"type": "file", "file": "usr/qml/My/Module5/qmldir"}, + {"type": "file", "file": "usr/qml/My/Module5/My_Module5.qmltypes"} + ], + "expect_skip_on_jobname": ["cygwin", "msys2", "azure"] +}