summaryrefslogtreecommitdiff
path: root/test cases/frameworks
diff options
context:
space:
mode:
authorPierre Lamot <pierre@videolabs.io>2024-06-06 18:05:45 +0200
committerPierre Lamot <pierre@videolabs.io>2025-01-09 09:22:38 +0100
commita8bb13c2d228c74dd234fc07c79abdc4e7e05c55 (patch)
treec269d8e6b3203c9a14e697f075ccff69ce9809f1 /test cases/frameworks
parent4508622a34932d23e336392a8a3c71ed79af4e3f (diff)
downloadmeson-a8bb13c2d228c74dd234fc07c79abdc4e7e05c55.tar.gz
qt module: add qml module test
Diffstat (limited to 'test cases/frameworks')
-rw-r--r--test cases/frameworks/39 qt qml/Basic.qml5
-rw-r--r--test cases/frameworks/39 qt qml/Internal.qml5
-rw-r--r--test cases/frameworks/39 qt qml/Main.qml53
-rw-r--r--test cases/frameworks/39 qt qml/QmlCppExposed.hpp25
-rw-r--r--test cases/frameworks/39 qt qml/QmlCppOtherExposed.hpp25
-rw-r--r--test cases/frameworks/39 qt qml/QmlMain.cpp31
-rw-r--r--test cases/frameworks/39 qt qml/QmlSingleton.qml10
-rw-r--r--test cases/frameworks/39 qt qml/custom_qmldir4
-rw-r--r--test cases/frameworks/39 qt qml/custom_qmldir.qrc5
-rw-r--r--test cases/frameworks/39 qt qml/meson.build115
-rw-r--r--test cases/frameworks/39 qt qml/meson_options.txt1
-rw-r--r--test cases/frameworks/39 qt qml/subdir/SubdirHeader.hpp27
-rw-r--r--test cases/frameworks/39 qt qml/subdir/Thing.qml5
-rw-r--r--test cases/frameworks/39 qt qml/test.json22
14 files changed, 333 insertions, 0 deletions
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 000000000..33c0a28c7
--- /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 000000000..e8eee4723
--- /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 000000000..94b67186d
--- /dev/null
+++ b/test cases/frameworks/39 qt qml/Main.qml
@@ -0,0 +1,53 @@
+import QtQuick
+import My.Module1 as M1
+
+Item {
+ id: root
+
+ Component.onCompleted: {
+ function checkInstance(label, instance, value) {
+ if (!instance) {
+ console.log(label, "KO instance is null")
+ return false
+ } if (instance.ok !== value) {
+ console.log(label, "KO got", instance.ok, "expected", value)
+ return false
+ } else {
+ console.log(label, "OK")
+ return true
+ }
+ }
+
+ function checkClass(namespace, classname, value) {
+ let newObject = null;
+ try {
+ newObject = Qt.createQmlObject(
+ "import %1; %2 {}".arg(namespace).arg(classname),
+ root,
+ "some path"
+ )
+ } catch (e) {
+ console.log(namespace, classname, "KO failed to instanciate object")
+ return false
+ }
+ return checkInstance("%1 %2".arg(namespace).arg(classname), newObject, value)
+ }
+
+ let ret = true
+ ret &= checkClass("My.Module1", "Basic", 1);
+ ret &= checkClass("My.Module1", "Thing", 2);
+ ret &= checkClass("My.Module1", "QmlCppExposed", 3);
+ ret &= checkInstance("My.Module1 QmlSingleton", M1.QmlSingleton, 5)
+
+ ret &= checkClass("My.Module2", "Thing", 2);
+ ret &= checkClass("My.Module3", "Basic", 1);
+ ret &= checkClass("My.Module4", "BasicAliased", 1);
+ ret &= checkClass("My.Module5", "SubdirHeader", 6);
+ ret &= checkClass("My.Module6", "Basic", 1);
+
+ if (!ret)
+ Qt.exit(1)
+ else
+ 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 000000000..10568c8b7
--- /dev/null
+++ b/test cases/frameworks/39 qt qml/QmlCppExposed.hpp
@@ -0,0 +1,25 @@
+#pragma once
+#include <QObject>
+#include <QQmlEngine>
+
+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 000000000..784261635
--- /dev/null
+++ b/test cases/frameworks/39 qt qml/QmlCppOtherExposed.hpp
@@ -0,0 +1,25 @@
+#pragma once
+#include <QObject>
+#include <QQmlEngine>
+
+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 000000000..0cec6f3a3
--- /dev/null
+++ b/test cases/frameworks/39 qt qml/QmlMain.cpp
@@ -0,0 +1,31 @@
+#include <QGuiApplication>
+#include <QQmlApplicationEngine>
+#include <QDebug>
+
+//extern type registration
+extern void qml_register_types_My_Module6();
+
+int main(int argCount, char* argVector[])
+{
+ //register resources from static libraries
+ Q_INIT_RESOURCE(My_Module6);
+ Q_INIT_RESOURCE(qmlcache_My_Module6);
+ qml_register_types_My_Module6();
+
+ //don't require a grapical environment to run the test
+ qputenv("QT_QPA_PLATFORM", "offscreen");
+
+ 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 000000000..73ea95d11
--- /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 000000000..9d84db651
--- /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 000000000..bee52092c
--- /dev/null
+++ b/test cases/frameworks/39 qt qml/custom_qmldir.qrc
@@ -0,0 +1,5 @@
+<RCC>
+ <qresource prefix="/qt/qml/My/Module4">
+ <file alias="qmldir">custom_qmldir</file>
+ </qresource>
+</RCC>
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 000000000..060e044a5
--- /dev/null
+++ b/test cases/frameworks/39 qt qml/meson.build
@@ -0,0 +1,115 @@
+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')
+fs = import('fs')
+
+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: ['Basic.qml', 'subdir/Thing.qml'],
+ resources_prefix: '/test',
+ dependencies: [qtdep],
+)
+
+#test with generated targets
+basic_copy = fs.copyfile('Basic.qml')
+thing_copy = fs.copyfile('subdir/Thing.qml')
+
+#build without cachegen
+qmlmodule3 = qtmodule.qml_module(
+ 'My.Module3',
+ version: '1.10.42',
+ qml_sources: [basic_copy, thing_copy],
+ 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
+)
+
+#module as static library
+qmlmodule6 = qtmodule.qml_module(
+ 'My.Module6',
+ version: '1.0',
+ qml_sources: files('Basic.qml'),
+ moc_headers: files('subdir/SubdirHeader.hpp'),
+ cachegen: true,
+ dependencies: [qtdep],
+)
+
+qmlmodule6_static = static_library(
+ 'Qmlmodule6Lib',
+ sources: qmlmodule6,
+ include_directories: include_directories('subdir'),
+ dependencies: [qtdep],
+ override_options: 'unity=off',
+)
+
+#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
+ ],
+ link_with : qmlmodule6_static,
+ 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'),
+ #generated code doesn't support unity build
+ override_options: 'unity=off',
+)
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 000000000..bc1069ebc
--- /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 000000000..019a16923
--- /dev/null
+++ b/test cases/frameworks/39 qt qml/subdir/SubdirHeader.hpp
@@ -0,0 +1,27 @@
+#pragma once
+#include <QObject>
+#include <QQmlEngine>
+
+#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 000000000..5b015c35c
--- /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 000000000..d1f868400
--- /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", "bionic", "macos"]
+}