// Copyright (C) 2024 Intel Corporation. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only // Testing qtmochelpers.h is probably pointless... if there's a problem with it // then you most likely can't compile this test in the first place. #include #include "qtmocconstants.h" #include #include #include #include QT_BEGIN_NAMESPACE namespace QtMocHelpers { } QT_END_NAMESPACE class tst_MocHelpers : public QObject { Q_OBJECT private slots: void stringData(); // parts of the uint array void classinfoData(); void classinfoDataGroup(); void enumUintData(); void enumUintGroup(); void propertyUintData(); void propertyUintGroup(); void methodUintData(); void methodUintGroup(); void constructorUintData(); void constructorUintGroup(); void emptyUintArray(); void uintArrayNoMethods(); void uintArray(); }; template void verifyStringData(const QtMocHelpers::StringData &data, std::initializer_list strings) { QCOMPARE(std::size(strings), size_t(Count) / 2); ptrdiff_t i = 0; for (const char *str : strings) { uint offset = data.offsetsAndSizes[i++] - sizeof(data.offsetsAndSizes); uint len = data.offsetsAndSizes[i++]; QByteArrayView result(data.stringdata0 + offset, len); QCOMPARE(len, strlen(str)); QCOMPARE(result, str); } } void tst_MocHelpers::stringData() { #define CHECK(...) \ verifyStringData(QtMocHelpers::stringData(__VA_ARGS__), { __VA_ARGS__ }) QTest::setThrowOnFail(true); CHECK("Hello"); CHECK("Hello", "World"); CHECK("Hello", "", "World"); #undef CHECK } void tst_MocHelpers::classinfoData() { { auto result = QtMocHelpers::ClassInfos({{1, 2}}); QCOMPARE(result.headerSize(), 2U); QCOMPARE(result.header[0], 1U); QCOMPARE(result.header[1], 2U); } { auto result = QtMocHelpers::ClassInfos({{1, 2}, {3, 4}}); QCOMPARE(result.headerSize(), 4U); QCOMPARE(result.header[0], 1U); QCOMPARE(result.header[1], 2U); QCOMPARE(result.header[2], 3U); QCOMPARE(result.header[3], 4U); } } constexpr QtMocHelpers::StringRefStorage dummyStringData {"tst_QtMocHelpers"}; template static void checkClassInfos(const uint (&data)[N]) { QCOMPARE(data[2], 2U); QCOMPARE_GE(data[3], 14U); const uint *classinfos = data + data[3]; QCOMPARE(classinfos[0], 1U); QCOMPARE(classinfos[1], 2U); QCOMPARE(classinfos[2], 3U); QCOMPARE(classinfos[3], 4U); } void tst_MocHelpers::classinfoDataGroup() { constexpr auto data = QtMocHelpers::metaObjectData(0, dummyStringData, QtMocHelpers::UintData{}, QtMocHelpers::UintData{}, QtMocHelpers::UintData{}, QtMocHelpers::UintData{}, QtMocHelpers::ClassInfos({{1, 2}, {3, 4}})); checkClassInfos(data.staticData.data); } template constexpr auto getMetaTypes(MetaTypeHolder) { QtMocHelpers::MetaObjectContents<1, 1, 1, MetaTypeHolder::count()> r = {}; uint metatypeoffset = 0; MetaTypeHolder::template copyTo(r, metatypeoffset); std::array result; for (uint i = 0; i < result.size(); ++i) result[i] = QMetaType(r.relocatingData.metaTypes[i]); return result; } template void enumUintData_check(const E (&values)[N]) { using namespace QtMocHelpers; // make an array of dummy offsets typename EnumData::EnumEntry namesAndOffsets[N]; for (int i = 0; i < N; ++i) { namesAndOffsets[i].nameIndex = 2 * (i + 7); namesAndOffsets[i].value = values[i]; } auto result = EnumData(0, 0, 0).add(namesAndOffsets); for (uint i = 0; i < N; ++i) { QCOMPARE(result.payload[2 * i + 0], uint(namesAndOffsets[i].nameIndex)); QCOMPARE(result.payload[2 * i + 1], uint(values[i])); } if constexpr (sizeof(E) > sizeof(uint)) { using U = std::underlying_type_t; for (uint i = 0; i < N; ++i) QCOMPARE(result.payload[2 * N + i], uint(U(values[i]) >> 32)); } } enum E1 { AnEnumValue }; enum class E2 { V0 = INT_MAX, V1 = INT_MIN }; enum class E3 : qint64 { V = 0x1111'2222'3333'4444, V2 = -V }; void tst_MocHelpers::enumUintData() { using namespace QtMocHelpers; using namespace QtMocConstants; { auto result = QtMocHelpers::EnumData(1, 1, EnumFlags{}); QCOMPARE(result.header[0], 1U); QCOMPARE(result.header[1], 1U); QCOMPARE(result.header[2], EnumFlags{}); QCOMPARE(result.header[3], 0U); QCOMPARE(result.payloadSize(), 0U); } { auto result = QtMocHelpers::EnumData>(1, 2, EnumIsFlag); QCOMPARE(result.header[0], 1U); QCOMPARE(result.header[1], 2U); QCOMPARE(result.header[2], EnumIsFlag); QCOMPARE(result.header[3], 0U); QCOMPARE(result.payloadSize(), 0U); } { auto result = QtMocHelpers::EnumData(1, 1, EnumFlags{}).add({ { 1, E1::AnEnumValue } }); QCOMPARE(result.header[0], 1U); QCOMPARE(result.header[1], 1U); QCOMPARE(result.header[2], EnumFlags{}); QCOMPARE(result.header[3], 1U); QCOMPARE(result.payload[0], 1U); QCOMPARE(result.payload[1], uint(E1::AnEnumValue)); } { auto result = QtMocHelpers::EnumData>(1, 2, EnumFlags{}).add({ { 1, E1::AnEnumValue } }); QCOMPARE(result.header[0], 1U); QCOMPARE(result.header[1], 2U); QCOMPARE(result.header[2], uint(EnumIsFlag)); QCOMPARE(result.header[3], 1U); QCOMPARE(result.payload[0], 1U); QCOMPARE(result.payload[1], uint(E1::AnEnumValue)); } { constexpr auto result = QtMocHelpers::EnumData(1, 1, EnumIsScoped) .add({ { 2, E3::V }, {3, E3::V2 }, }); QCOMPARE(result.header[0], 1U); QCOMPARE(result.header[1], 1U); QCOMPARE(result.header[2], EnumIsScoped | EnumIs64Bit); QCOMPARE(result.header[3], 2U); QCOMPARE(result.payload[0], 2U); QCOMPARE(result.payload[1], uint(E3::V)); QCOMPARE(result.payload[2], 3U); QCOMPARE(result.payload[3], uint(E3::V2)); QCOMPARE(result.payload[4], uint(quint64(E3::V) >> 32)); QCOMPARE(result.payload[5], uint(quint64(E3::V2) >> 32)); } QTest::setThrowOnFail(true); { enum E { E0, E1 = -1, E2 = 123, E3 = INT_MIN }; enumUintData_check({E0, E1, E2, E3}); } { enum E : quint64 { E0, E1 = quint64(INT_MIN), E2 = 0x1'0000'0000, E3 = quint64(LLONG_MIN) }; enumUintData_check({E0, E1, E2, E3}); } } template void testUintData(const Data &data) { uint count = 0; size_t headerSize = 0; size_t payloadSize = 0; data.forEach([&](const auto &block) { ++count; headerSize += block.headerSize(); payloadSize += block.payloadSize(); }); QCOMPARE(data.count(), count); QCOMPARE(data.headerSize(), headerSize); QCOMPARE(data.payloadSize(), payloadSize); } static void checkEnums(const uint *data, const QtPrivate::QMetaTypeInterface *const *metaTypes) { using namespace QtMocConstants; QCOMPARE(data[8], 4U); QCOMPARE_NE(data[9], 0U); const uint *header = data + data[9]; metaTypes += data[6]; // property count // E1: QCOMPARE(header[0 + 0], 1U); QCOMPARE(header[0 + 1], 1U); QCOMPARE(header[0 + 2], 0U); QCOMPARE(header[0 + 3], 1U); QCOMPARE_GE(header[0 + 4], 14U); const uint *payload = data + header[0 + 4]; QCOMPARE(payload[0], 3U); QCOMPARE(payload[1], uint(E1::AnEnumValue)); QCOMPARE(QMetaType(metaTypes[0]), QMetaType::fromType()); // E3: QCOMPARE(header[5 + 0], 4U); QCOMPARE(header[5 + 1], 5U); QCOMPARE(header[5 + 2], EnumIsFlag | EnumIsScoped | EnumIs64Bit); QCOMPARE(header[5 + 3], 2U); QCOMPARE_GE(header[5 + 4], 14U); payload = data + header[5 + 4]; QCOMPARE(payload[0], 6U); QCOMPARE(payload[1], uint(E3::V)); QCOMPARE(payload[2], 8U); QCOMPARE(payload[3], uint(E3::V2)); QCOMPARE(payload[4], uint(quint64(E3::V) >> 32)); QCOMPARE(payload[5], uint(quint64(E3::V2) >> 32)); QCOMPARE(QMetaType(metaTypes[1]), QMetaType::fromType()); // E2: QCOMPARE(header[10 + 0], 7U); QCOMPARE(header[10 + 1], 6U); QCOMPARE(header[10 + 2], EnumIsFlag | EnumIsScoped); QCOMPARE(header[10 + 3], 2U); QCOMPARE_GE(header[10 + 4], 14U); payload = data + header[10 + 4]; QCOMPARE(payload[0], 7U); QCOMPARE(payload[1], uint(E2::V0)); QCOMPARE(payload[2], 10U); QCOMPARE(payload[3], uint(E2::V1)); QCOMPARE(QMetaType(metaTypes[2]), QMetaType::fromType()); // QFlags QCOMPARE(header[15 + 0], 11U); QCOMPARE(header[15 + 1], 1U); QCOMPARE(header[15 + 2], EnumIsFlag); QCOMPARE(header[15 + 3], 1U); QCOMPARE_GE(header[15 + 4], 14U); payload = data + header[15 + 4]; QCOMPARE(payload[0], 3U); QCOMPARE(payload[1], uint(E1::AnEnumValue)); QCOMPARE(QMetaType(metaTypes[3]), QMetaType::fromType>()); } void tst_MocHelpers::enumUintGroup() { using namespace QtMocConstants; QTest::setThrowOnFail(true); constexpr QtMocHelpers::UintData enums = { QtMocHelpers::EnumData(1, 1, 0x00).add({ { 3, E1::AnEnumValue } }), QtMocHelpers::EnumData(4, 5, EnumIsFlag | EnumIsScoped) .add({ { 6, E3::V }, { 8, E3::V2 }, }), QtMocHelpers::EnumData(7, 6, EnumIsFlag | EnumIsScoped) .add({ { 7, E2::V0 }, { 10, E2::V1 }, }), QtMocHelpers::EnumData>(11, 1, EnumIsFlag).add({ { 3, E1::AnEnumValue } }), }; testUintData(enums); constexpr auto data = QtMocHelpers::metaObjectData(0, dummyStringData, QtMocHelpers::UintData{}, QtMocHelpers::UintData{}, enums); checkEnums(data.staticData.data, data.relocatingData.metaTypes); } void tst_MocHelpers::propertyUintData() { using namespace QtMocHelpers; { auto result = PropertyData(3, QMetaType::Int, 0x3, 13, 0x101); QCOMPARE(result.payloadSize(), 0U); QCOMPARE(result.header[0], 3U); QCOMPARE(result.header[1], uint(QMetaType::Int)); QCOMPARE(result.header[2], 0x3U); QCOMPARE(result.header[3], 13U); QCOMPARE(result.header[4], 0x0101U); } { // check that QMetaType doesn't override if it's an alias using Dummy = QString; auto result = PropertyData(3, 0x80000000 | 4, 0x03); QCOMPARE(result.header[1], 0x80000000U | 4); } { // Or derived from struct Dummy : QString {}; auto result = PropertyData(3, 0x80000000 | 4, 0x03); QCOMPARE(result.header[1], 0x80000000U | 4); } } static void checkProperties(const uint *data, const QtPrivate::QMetaTypeInterface *const *metaTypes) { QCOMPARE(data[6], 3U); QCOMPARE_NE(data[7], 0U); const uint *header = data + data[7]; QCOMPARE(header[0 + 0], 3U); QCOMPARE(header[0 + 1], uint(QMetaType::Int)); QCOMPARE(header[0 + 2], 0x3U); QCOMPARE(header[0 + 3], 13U); QCOMPARE(header[0 + 4], 0x0101U); QCOMPARE(QMetaType(metaTypes[0]), QMetaType::fromType()); QCOMPARE(header[5 + 0], 4U); QCOMPARE(header[5 + 1], 0x80000000U | 5); QCOMPARE(header[5 + 2], 0x3U); QCOMPARE(header[5 + 3], uint(-1)); QCOMPARE(header[5 + 4], 0U); QCOMPARE(QMetaType(metaTypes[1]), QMetaType::fromType()); QCOMPARE(header[10 + 0], 6U); QCOMPARE(header[10 + 1], 0x80000000U | 7); QCOMPARE(header[10 + 2], 0x3U); QCOMPARE(header[10 + 3], uint(-1)); QCOMPARE(header[10 + 4], 0U); QCOMPARE(QMetaType(metaTypes[2]), QMetaType::fromType()); } void tst_MocHelpers::propertyUintGroup() { QTest::setThrowOnFail(true); constexpr QtMocHelpers::UintData properties = { QtMocHelpers::PropertyData(3, QMetaType::Int, 0x3, 13, 0x101), QtMocHelpers::PropertyData(4, 0x80000000 | 5, 0x03), QtMocHelpers::PropertyData(6, 0x80000000 | 7, 0x03) }; testUintData(properties); constexpr auto data = QtMocHelpers::metaObjectData(0, dummyStringData, QtMocHelpers::UintData{}, properties, QtMocHelpers::UintData{}); checkProperties(data.staticData.data, data.relocatingData.metaTypes); } void tst_MocHelpers::methodUintData() { using namespace QtMocHelpers; using namespace QtMocConstants; { auto result = SignalData(1, 2, AccessPublic, QMetaType::Void, {}); QCOMPARE(result.header[0], 1U); QCOMPARE(result.header[1], 0U); QCOMPARE(result.header[3], 2U); QCOMPARE(result.header[4], AccessPublic | MethodSignal); QCOMPARE(result.header[5], 0U); QCOMPARE(result.payload[0], uint(QMetaType::Void)); QCOMPARE(result.metaTypes().count(), 1); std::array mt = getMetaTypes(result.metaTypes()); QCOMPARE(mt[0], QMetaType::fromType()); } { auto result = SlotData(1, 2, AccessPublic, QMetaType::Void, { { { QMetaType::QString, 1000 } } }); QCOMPARE(result.header[0], 1U); QCOMPARE(result.header[1], 1U); QCOMPARE(result.header[3], 2U); QCOMPARE(result.header[4], AccessPublic | MethodSlot | MethodIsConst); QCOMPARE(result.header[5], 0U); QCOMPARE(result.payload[0], uint(QMetaType::Void)); QCOMPARE(result.payload[1], uint(QMetaType::QString)); QCOMPARE(result.payload[2], 1000U); QCOMPARE(result.metaTypes().count(), 2); std::array mt = getMetaTypes(result.metaTypes()); QCOMPARE(mt[0], QMetaType::fromType()); QCOMPARE(mt[1], QMetaType::fromType()); } { auto result = RevisionedSlotData(1, 2, AccessPublic, 0xff01, QMetaType::Void, { { { QMetaType::QString, 1000 } } }); QCOMPARE(result.header[0], 1U); QCOMPARE(result.header[1], 1U); QCOMPARE(result.header[3], 2U); QCOMPARE(result.header[4], AccessPublic | MethodSlot | MethodRevisioned); QCOMPARE(result.header[5], 0U); QCOMPARE(result.payload[0], 0xff01U); QCOMPARE(result.payload[1], uint(QMetaType::Void)); QCOMPARE(result.payload[2], uint(QMetaType::QString)); QCOMPARE(result.payload[3], 1000U); QCOMPARE(result.metaTypes().count(), 2); std::array mt = getMetaTypes(result.metaTypes()); QCOMPARE(mt[0], QMetaType::fromType()); QCOMPARE(mt[1], QMetaType::fromType()); } } static void checkMethods(const uint *data, const QtPrivate::QMetaTypeInterface *const *metaTypes) { using namespace QtMocConstants; QCOMPARE(data[4], 3U); QCOMPARE_NE(data[5], 0U); const uint *header = data + data[5]; uint initialMetaTypeOffset = data[6] + data[8] + 1; // propcount + enumcount + object // signals: void signal() QCOMPARE(header[0], 1U); QCOMPARE(header[1], 0U); QCOMPARE_NE(header[2], 0U); QCOMPARE(header[3], 2U); QCOMPARE(header[4], AccessPublic | MethodSignal | MethodRevisioned); QCOMPARE(header[5], initialMetaTypeOffset); const uint *payload = data + header[2]; QCOMPARE(payload[-1], 0x0509U); QCOMPARE(payload[0], uint(QMetaType::Void)); QCOMPARE(QMetaType(metaTypes[header[5]]), QMetaType::fromType()); // signals: void signal(E1, Dummy) [Dummy = QString] header += 6; QCOMPARE(header[0], 3U); QCOMPARE(header[1], 2U); QCOMPARE_NE(header[2], 0U); QCOMPARE(header[3], 2U); QCOMPARE(header[4], AccessPublic | MethodSignal); QCOMPARE(header[5], initialMetaTypeOffset + 1); payload = data + header[2]; QCOMPARE(payload[0], uint(QMetaType::Void)); QCOMPARE(payload[1], 0x80000000U | 4); // not a builtin type QCOMPARE(payload[2], 0x80000000U | 5); QCOMPARE(payload[3], 6U); QCOMPARE(payload[4], 7U); QCOMPARE(QMetaType(metaTypes[header[5] + 0]), QMetaType::fromType()); QCOMPARE(QMetaType(metaTypes[header[5] + 1]), QMetaType::fromType()); QCOMPARE(QMetaType(metaTypes[header[5] + 2]), QMetaType::fromType()); // public slots: bool slot(QString &) const header += 6; QCOMPARE(header[0], 8U); QCOMPARE(header[1], 1U); QCOMPARE_NE(header[2], 0U); QCOMPARE(header[3], 2U); QCOMPARE(header[4], AccessPublic | MethodSlot | MethodIsConst); QCOMPARE(header[5], initialMetaTypeOffset + 4); payload = data + header[2]; QCOMPARE(payload[0], uint(QMetaType::Bool)); QCOMPARE(payload[1], 0x80000000U | 10); // not a builtin type QCOMPARE(payload[2], 11U); QCOMPARE(QMetaType(metaTypes[header[5] + 0]), QMetaType::fromType()); QCOMPARE(metaTypes[header[5] + 1], nullptr); // is a reference } void tst_MocHelpers::methodUintGroup() { QTest::setThrowOnFail(true); using Dummy = QString; constexpr QtMocHelpers::UintData methods = { QtMocHelpers::RevisionedSignalData(1, 2, QtMocConstants::AccessPublic, 0x509, QMetaType::Void, {{ }} ), QtMocHelpers::SignalData(3, 2, QtMocConstants::AccessPublic, QMetaType::Void, {{ { 0x80000000 | 4, 6 }, { 0x80000000 | 5, 7 }} } ), QtMocHelpers::SlotData(8, 2, QtMocConstants::AccessPublic, QMetaType::Bool, {{ { 0x80000000 | 10, 11 } }} ) }; testUintData(methods); constexpr auto data = QtMocHelpers::metaObjectData(0, dummyStringData, methods, QtMocHelpers::UintData{}, QtMocHelpers::UintData{}); checkMethods(data.staticData.data, data.relocatingData.metaTypes); } void tst_MocHelpers::constructorUintData() { using namespace QtMocHelpers; using namespace QtMocConstants; { auto result = ConstructorData(2, AccessPublic, {}); QCOMPARE(result.header[0], 0U); QCOMPARE(result.header[1], 0U); QCOMPARE(result.header[3], 2U); QCOMPARE(result.header[4], AccessPublic | MethodConstructor); QCOMPARE(result.header[5], 0U); QCOMPARE(result.payload[0], uint(QMetaType::UnknownType)); QCOMPARE(result.metaTypes().count(), 0); } { auto result = ConstructorData(1, AccessPublic, {{ { QMetaType::QObjectStar, 2 } }}); QCOMPARE(result.header[0], 0U); QCOMPARE(result.header[1], 1U); QCOMPARE(result.header[3], 1U); QCOMPARE(result.header[4], AccessPublic | MethodConstructor); QCOMPARE(result.header[5], 0U); QCOMPARE(result.payload[0], uint(QMetaType::UnknownType)); QCOMPARE(result.payload[1], uint(QMetaType::QObjectStar)); QCOMPARE(result.payload[2], 2U); QCOMPARE(result.metaTypes().count(), 1); std::array mt = getMetaTypes(result.metaTypes()); QCOMPARE(mt[0], QMetaType::fromType()); } } static void checkConstructors(const uint *data, const QtPrivate::QMetaTypeInterface *const *metaTypes) { using namespace QtMocConstants; QCOMPARE(data[10], 3U); QCOMPARE_NE(data[11], 0U); const uint *header = data + data[11]; // Constructor(QObject *) QCOMPARE(header[0], 0U); QCOMPARE(header[1], 1U); QCOMPARE_NE(header[2], 0U); QCOMPARE(header[3], 1U); QCOMPARE(header[4], AccessPublic | MethodConstructor); QCOMPARE_GT(header[5], 0U); const uint *payload = data + header[2]; QCOMPARE(payload[0], uint(QMetaType::UnknownType)); QCOMPARE(payload[1], uint(QMetaType::QObjectStar)); QCOMPARE(QMetaType(metaTypes[header[5]]), QMetaType::fromType()); // Constructor() [cloned from the previous with a default argument] header += 6; QCOMPARE(header[0], 0U); QCOMPARE(header[1], 0U); QCOMPARE_NE(header[2], 0U); QCOMPARE(header[3], 1U); QCOMPARE(header[4], AccessPublic | MethodConstructor | MethodCloned); QCOMPARE_GT(header[5], 0U); payload = data + header[2]; QCOMPARE(payload[0], uint(QMetaType::UnknownType)); // no metatype stored for this constructor // Constructor(const QString &) header += 6; QCOMPARE(header[0], 0U); QCOMPARE(header[1], 1U); QCOMPARE_NE(header[2], 0U); QCOMPARE(header[3], 1U); QCOMPARE(header[4], AccessPublic | MethodConstructor); QCOMPARE_GT(header[5], 0U); payload = data + header[2]; QCOMPARE(payload[0], uint(QMetaType::UnknownType)); QCOMPARE(payload[1], uint(QMetaType::QString)); QCOMPARE(QMetaType(metaTypes[header[5]]), QMetaType::fromType()); } void tst_MocHelpers::constructorUintGroup() { using QtMocHelpers::NoType; QTest::setThrowOnFail(true); constexpr QtMocHelpers::UintData constructors = { QtMocHelpers::ConstructorData(1, QtMocConstants::AccessPublic, {{ { QMetaType::QObjectStar, 2 } }} ), QtMocHelpers::ConstructorData(1, QtMocConstants::AccessPublic | QtMocConstants::MethodCloned, {{ }} ), QtMocHelpers::ConstructorData(1, QtMocConstants::AccessPublic, {{ { QMetaType::QString, 3 }, }} ) }; testUintData(constructors); constexpr auto data = QtMocHelpers::metaObjectData(0, dummyStringData, QtMocHelpers::UintData{}, QtMocHelpers::UintData{}, QtMocHelpers::UintData{}, constructors); checkConstructors(data.staticData.data, data.relocatingData.metaTypes); } struct Gadget {}; template static void checkUintArrayGeneric(const uint (&data)[N], uint flags = 0) { using namespace QtMocConstants; QCOMPARE(data[0], uint(OutputRevision)); QCOMPARE(data[1], 0U); QCOMPARE(data[12], flags); QCOMPARE(data[N-1], 0U); // check the offsets are valid QCOMPARE_LT(data[2], N); // classinfos QCOMPARE_LT(data[4], N); // methods QCOMPARE_LT(data[6], N); // properties QCOMPARE_LT(data[8], N); // enums QCOMPARE_LT(data[10], N); // constructors } void tst_MocHelpers::emptyUintArray() { using namespace QtMocConstants; constexpr auto mo = QtMocHelpers::metaObjectData(MetaObjectFlag{}, dummyStringData, QtMocHelpers::UintData{}, QtMocHelpers::UintData{}, QtMocHelpers::UintData{}); QTest::setThrowOnFail(true); checkUintArrayGeneric(mo.staticData.data, MetaObjectFlag{}); QTest::setThrowOnFail(false); const uint *data = mo.staticData.data; auto &metaTypes = mo.relocatingData.metaTypes; // check it says nothing was added QCOMPARE(data[2], 0U); // classinfos QCOMPARE(data[4], 0U); // methods QCOMPARE(data[6], 0U); // properties QCOMPARE(data[8], 0U); // enums QCOMPARE(data[10], 0U); // constructors QCOMPARE(data[13], 0U); // signals QCOMPARE(std::size(metaTypes), 1U); QMetaType self(metaTypes[data[6] + data[8]]); QCOMPARE(self, QMetaType::fromType()); } void tst_MocHelpers::uintArrayNoMethods() { using namespace QtMocConstants; constexpr auto mo = QtMocHelpers::metaObjectData(PropertyAccessInStaticMetaCall, dummyStringData, QtMocHelpers::UintData{}, QtMocHelpers::UintData{ QtMocHelpers::PropertyData(3, QMetaType::Int, 0x3, 13, 0x101), QtMocHelpers::PropertyData(4, 0x80000000 | 5, 0x03), QtMocHelpers::PropertyData(6, 0x80000000 | 7, 0x03) }, QtMocHelpers::UintData{ QtMocHelpers::EnumData(1, 1, 0x00).add({ { 3, E1::AnEnumValue } }), QtMocHelpers::EnumData(4, 5, EnumIsFlag | EnumIsScoped) .add({ { 6, E3::V }, { 8, E3::V2 }, }), QtMocHelpers::EnumData(7, 6, EnumIsFlag | EnumIsScoped) .add({ { 7, E2::V0 }, { 10, E2::V1 }, }), QtMocHelpers::EnumData>(11, 1, EnumIsFlag).add({ { 3, E1::AnEnumValue } }), }, QtMocHelpers::UintData{}, QtMocHelpers::ClassInfos({{1, 2}, {3, 4}})); auto &data = mo.staticData.data; auto &metaTypes = mo.relocatingData.metaTypes; QTest::setThrowOnFail(true); checkUintArrayGeneric(data, PropertyAccessInStaticMetaCall); checkClassInfos(data); checkProperties(data, metaTypes); checkEnums(data, metaTypes); QTest::setThrowOnFail(false); QCOMPARE(data[4], 0U); // methods QCOMPARE(data[10], 0U); // constructors QCOMPARE(data[13], 0U); // signals QMetaType self(metaTypes[data[6] + data[8]]); QCOMPARE(self, QMetaType::fromType()); } void tst_MocHelpers::uintArray() { using Dummy = QString; using QtMocHelpers::NoType; using namespace QtMocConstants; constexpr auto mo = QtMocHelpers::metaObjectData(PropertyAccessInStaticMetaCall, dummyStringData, QtMocHelpers::UintData{ QtMocHelpers::RevisionedSignalData(1, 2, QtMocConstants::AccessPublic, 0x509, QMetaType::Void, {{ }} ), QtMocHelpers::SignalData(3, 2, QtMocConstants::AccessPublic, QMetaType::Void, {{ { 0x80000000 | 4, 6 }, { 0x80000000 | 5, 7 }} } ), QtMocHelpers::SlotData(8, 2, QtMocConstants::AccessPublic, QMetaType::Bool, {{ { 0x80000000 | 10, 11 } }} ) }, QtMocHelpers::UintData{ QtMocHelpers::PropertyData(3, QMetaType::Int, 0x3, 13, 0x101), QtMocHelpers::PropertyData(4, 0x80000000 | 5, 0x03), QtMocHelpers::PropertyData(6, 0x80000000 | 7, 0x03) }, QtMocHelpers::UintData{ QtMocHelpers::EnumData(1, 1, 0x00).add({ { 3, E1::AnEnumValue } }), QtMocHelpers::EnumData(4, 5, EnumIsFlag | EnumIsScoped) .add({ { 6, E3::V }, { 8, E3::V2 }, }), QtMocHelpers::EnumData(7, 6, EnumIsFlag | EnumIsScoped) .add({ { 7, E2::V0 }, { 10, E2::V1 }, }), QtMocHelpers::EnumData>(11, 1, EnumIsFlag).add({ { 3, E1::AnEnumValue } }), }, QtMocHelpers::UintData{ QtMocHelpers::ConstructorData(1, QtMocConstants::AccessPublic, {{ { QMetaType::QObjectStar, 2 } }} ), QtMocHelpers::ConstructorData(1, QtMocConstants::AccessPublic | QtMocConstants::MethodCloned, {{ }} ), QtMocHelpers::ConstructorData(1, QtMocConstants::AccessPublic, {{ { QMetaType::QString, 3 }, }} ) }, QtMocHelpers::ClassInfos({{1, 2}, {3, 4}})); auto &data = mo.staticData.data; auto &metaTypes = mo.relocatingData.metaTypes; QTest::setThrowOnFail(true); checkUintArrayGeneric(data, PropertyAccessInStaticMetaCall); checkClassInfos(data); checkProperties(data, metaTypes); checkEnums(data, metaTypes); checkMethods(data, metaTypes); checkConstructors(data, metaTypes); QMetaType self(metaTypes[data[6] + data[8]]); QCOMPARE(self, QMetaType::fromType()); } QTEST_MAIN(tst_MocHelpers) #include "tst_mochelpers.moc"