Revision control
+ // Copyright (C) 2026 The Qt Company Ltd.
+ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+ #include <QtTest/QSignalSpy>
+ #include <QtTest/QTest>
+
+ #include <QtQuick3DHelpers/private/capsulegeometry_p.h>
+ #include <QtQuick3DHelpers/private/conegeometry_p.h>
+ #include <QtQuick3DHelpers/private/cuboidgeometry_p.h>
+ #include <QtQuick3DHelpers/private/cylindergeometry_p.h>
+ #include <QtQuick3DHelpers/private/extrudedtextgeometry_p.h>
+ #include <QtQuick3DHelpers/private/planegeometry_p.h>
+ #include <QtQuick3DHelpers/private/spheregeometry_p.h>
+ #include <QtQuick3DHelpers/private/torusgeometry_p.h>
+
+ #include <functional>
+
+ using GeometryFactory = std::function<QQuick3DGeometry *()>;
+ Q_DECLARE_METATYPE(GeometryFactory)
+
+ class tst_ProceduralGeometry : public QObject
+ {
+ Q_OBJECT
+
+ private slots:
+ void regenerate_data();
+ void regenerate();
+ };
+
+ void tst_ProceduralGeometry::regenerate_data()
+ {
+ QTest::addColumn<GeometryFactory>("create");
+ QTest::addColumn<QByteArray>("property");
+ QTest::addColumn<QVariant>("value");
+ QTest::addColumn<bool>("asynchronous");
+
+ struct Row
+ {
+ const char *type;
+ GeometryFactory create;
+ const char *property;
+ QVariant value;
+ };
+ const Row rows[] = {
+ { "SphereGeometry", [] { return new SphereGeometry; }, "radius", 50.0f },
+ { "CuboidGeometry", [] { return new CuboidGeometry; }, "xExtent", 50.0f },
+ { "ConeGeometry", [] { return new ConeGeometry; }, "length", 50.0f },
+ { "CylinderGeometry", [] { return new CylinderGeometry; }, "radius", 20.0f },
+ { "TorusGeometry", [] { return new TorusGeometry; }, "radius", 50.0f },
+ { "PlaneGeometry", [] { return new PlaneGeometry; }, "width", 50.0f },
+ { "CapsuleGeometry", [] { return new CapsuleGeometry; }, "height", 50.0f },
+ { "ExtrudedTextGeometry",
+ [] {
+ auto *geometry = new ExtrudedTextGeometry;
+ geometry->setText(QStringLiteral("Qt"));
+ return geometry;
+ },
+ "depth",
+ 5.0f },
+ };
+
+ for (const Row &row : rows) {
+ for (bool async : { false, true }) {
+ QTest::addRow("%s-%s", row.type, async ? "async" : "sync")
+ << row.create << QByteArray(row.property) << row.value << async;
+ }
+ }
+ }
+
+ void tst_ProceduralGeometry::regenerate()
+ {
+ QFETCH(GeometryFactory, create);
+ QFETCH(QByteArray, property);
+ QFETCH(QVariant, value);
+ QFETCH(bool, asynchronous);
+
+ QScopedPointer<QQuick3DGeometry> geometry(create());
+ QVERIFY(geometry->setProperty("asynchronous", asynchronous));
+
+ QSignalSpy spy(geometry.data(), &QQuick3DGeometry::geometryChanged);
+ QTRY_COMPARE(spy.size(), 1);
+ const int attributeCount = geometry->attributeCount();
+ QVERIFY(attributeCount > 0);
+ QVERIFY(!geometry->vertexData().isEmpty());
+
+ for (int i = 0; i < 3; ++i) {
+ QVERIFY(geometry->setProperty(property.constData(), value.toFloat() * (i + 3)));
+ QTRY_COMPARE(spy.size(), i + 2);
+ QCOMPARE(geometry->attributeCount(), attributeCount);
+ QVERIFY(!geometry->vertexData().isEmpty());
+ }
+ }
+
+ QTEST_MAIN(tst_ProceduralGeometry)
+ #include "tst_proceduralgeometry.moc"