QMetaType: add a test to confirm that types are equal across libraries
Because of the template shenanigans. This is just to make sure. Pick-to: 6.4 Change-Id: Id0fb9ab0089845ee8843fffd16f989e7d555894f Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
This commit is contained in:
parent
bbcdee2afa
commit
985e24dd5f
@ -10,6 +10,35 @@
|
||||
# Collect test data
|
||||
list(APPEND test_data "./typeFlags.bin")
|
||||
|
||||
qt_internal_add_cmake_library(qmetatype_lib1
|
||||
INSTALL_DIRECTORY "${INSTALL_TESTSDIR}/tst_qmetatype"
|
||||
SOURCES
|
||||
lib1.cpp
|
||||
PUBLIC_LIBRARIES
|
||||
Qt::Core
|
||||
)
|
||||
qt_internal_add_cmake_library(qmetatype_lib2
|
||||
INSTALL_DIRECTORY "${INSTALL_TESTSDIR}/tst_qmetatype"
|
||||
SOURCES
|
||||
lib2.cpp
|
||||
PUBLIC_LIBRARIES
|
||||
Qt::Core
|
||||
)
|
||||
set_target_properties(qmetatype_lib1 PROPERTIES
|
||||
VERSION 1.0.0
|
||||
SOVERSION 0
|
||||
C_VISIBILITY_PRESET "hidden"
|
||||
CXX_VISIBILITY_PRESET "hidden"
|
||||
VISIBILITY_INLINES_HIDDEN ON
|
||||
)
|
||||
set_target_properties(qmetatype_lib2 PROPERTIES
|
||||
VERSION 1.0.0
|
||||
SOVERSION 0
|
||||
C_VISIBILITY_PRESET "hidden"
|
||||
CXX_VISIBILITY_PRESET "hidden"
|
||||
VISIBILITY_INLINES_HIDDEN ON
|
||||
)
|
||||
|
||||
qt_internal_add_test(tst_qmetatype
|
||||
SOURCES
|
||||
tst_qmetatype.h tst_qmetatype.cpp tst_qmetatype2.cpp
|
||||
@ -21,6 +50,8 @@ qt_internal_add_test(tst_qmetatype
|
||||
LIBRARIES
|
||||
Qt::CorePrivate
|
||||
Qt::Gui
|
||||
qmetatype_lib1
|
||||
qmetatype_lib2
|
||||
TESTDATA ${test_data}
|
||||
)
|
||||
|
||||
@ -28,7 +59,3 @@ qt_internal_extend_target(tst_qmetatype CONDITION MSVC
|
||||
COMPILE_OPTIONS
|
||||
/bigobj
|
||||
)
|
||||
|
||||
#### Keys ignored in scope 3:.:.:qmetatype.pro:CLANG:
|
||||
# QMAKE_CFLAGS_RELEASE = "--O2" "--g"
|
||||
# QMAKE_CXXFLAGS_RELEASE = "--O2" "--g"
|
||||
|
5
tests/auto/corelib/kernel/qmetatype/lib1.cpp
Normal file
5
tests/auto/corelib/kernel/qmetatype/lib1.cpp
Normal file
@ -0,0 +1,5 @@
|
||||
// Copyright (C) 2022 Intel Corporation
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#define LIB_NAMESPACE Lib1
|
||||
#include "lib_common.cpp"
|
5
tests/auto/corelib/kernel/qmetatype/lib2.cpp
Normal file
5
tests/auto/corelib/kernel/qmetatype/lib2.cpp
Normal file
@ -0,0 +1,5 @@
|
||||
// Copyright (C) 2022 Intel Corporation
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#define LIB_NAMESPACE Lib2
|
||||
#include "lib_common.cpp"
|
13
tests/auto/corelib/kernel/qmetatype/lib_common.cpp
Normal file
13
tests/auto/corelib/kernel/qmetatype/lib_common.cpp
Normal file
@ -0,0 +1,13 @@
|
||||
// Copyright (C) 2022 Intel Corporation
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include <qcollator.h>
|
||||
#include "tst_qmetatype_libs.h"
|
||||
|
||||
#define DECLARE_FUNCTION(TYPE, ID) \
|
||||
Q_DECL_EXPORT QMetaType metatype_ ## TYPE() \
|
||||
{ return QMetaType::fromType<TYPE>(); }
|
||||
|
||||
namespace LIB_NAMESPACE {
|
||||
FOR_EACH_METATYPE_LIBS(DECLARE_FUNCTION)
|
||||
}
|
@ -108,6 +108,10 @@ private slots:
|
||||
void fromType();
|
||||
void operatorEq_data();
|
||||
void operatorEq();
|
||||
void operatorEq2_data();
|
||||
void operatorEq2();
|
||||
void operatorEqAcrossLibs_data();
|
||||
void operatorEqAcrossLibs();
|
||||
void typesWithInaccessibleDTors();
|
||||
void voidIsNotUnknown();
|
||||
void typeNameNormalization();
|
||||
|
@ -2,7 +2,7 @@
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "tst_qmetatype.h"
|
||||
#include "tst_qvariant_common.h"
|
||||
#include "tst_qmetatype_libs.h"
|
||||
|
||||
#include <QtCore/private/qmetaobjectbuilder_p.h>
|
||||
|
||||
@ -412,6 +412,116 @@ void tst_QMetaType::operatorEq()
|
||||
QCOMPARE(typeB == typeA, eq);
|
||||
QCOMPARE(typeA != typeB, !eq);
|
||||
QCOMPARE(typeB != typeA, !eq);
|
||||
|
||||
#if !defined(Q_OS_WIN) && !defined(Q_OS_INTEGRITY)
|
||||
// for built-in types or locally-defined types, this must also hold true
|
||||
if (eq)
|
||||
QCOMPARE(typeA.iface(), typeB.iface());
|
||||
#endif
|
||||
}
|
||||
|
||||
void tst_QMetaType::operatorEq2_data()
|
||||
{
|
||||
create_data();
|
||||
}
|
||||
|
||||
void tst_QMetaType::operatorEq2()
|
||||
{
|
||||
QFETCH(int, type);
|
||||
QMetaType fromType1, fromType2;
|
||||
QMetaType fromId1(type), fromId2(type);
|
||||
|
||||
switch (type) {
|
||||
case QMetaType::UnknownType:
|
||||
break;
|
||||
#define GET_METATYPE_FROM_TYPE(MetaTypeName, MetaTypeId, RealType) \
|
||||
case QMetaType::MetaTypeName: \
|
||||
fromType1 = QMetaType::fromType<RealType>(); \
|
||||
fromType2 = QMetaType::fromType<RealType>(); \
|
||||
break;
|
||||
FOR_EACH_CORE_METATYPE(GET_METATYPE_FROM_TYPE)
|
||||
#undef GET_METATYPE_FROM_TYPE
|
||||
}
|
||||
|
||||
// sanity check
|
||||
QCOMPARE(fromId1.id(), type);
|
||||
QCOMPARE(fromId2.id(), type);
|
||||
|
||||
// confirm that they're all equal
|
||||
QCOMPARE(fromId1, fromId2);
|
||||
QCOMPARE(fromType1, fromType2);
|
||||
QCOMPARE(fromType1, fromId1);
|
||||
QCOMPARE(fromType2, fromId2);
|
||||
|
||||
#if !defined(Q_OS_WIN) && !defined(Q_OS_INTEGRITY)
|
||||
// for built-in types (other than void), this must be true
|
||||
if (type != QMetaType::Void) {
|
||||
QCOMPARE(fromType1.iface(), fromId1.iface());
|
||||
QCOMPARE(fromType2.iface(), fromId1.iface());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#define DECLARE_LIB_FUNCTION(TYPE, ID) \
|
||||
Q_DECL_IMPORT QMetaType metatype_ ## TYPE();
|
||||
namespace Lib1 { FOR_EACH_METATYPE_LIBS(DECLARE_LIB_FUNCTION) }
|
||||
namespace Lib2 { FOR_EACH_METATYPE_LIBS(DECLARE_LIB_FUNCTION) }
|
||||
#undef DECLARE_LIB_FUNCTION
|
||||
|
||||
using LibMetatypeFunction = QMetaType (*)();
|
||||
void tst_QMetaType::operatorEqAcrossLibs_data()
|
||||
{
|
||||
QTest::addColumn<int>("builtinTypeId");
|
||||
QTest::addColumn<QMetaType>("localType");
|
||||
QTest::addColumn<LibMetatypeFunction>("lib1Function");
|
||||
QTest::addColumn<LibMetatypeFunction>("lib2Function");
|
||||
|
||||
#define ADD_ROW(TYPE, ID) \
|
||||
QTest::addRow(QT_STRINGIFY(TYPE)) << int(ID) \
|
||||
<< QMetaType::fromType<TYPE>() \
|
||||
<< &Lib1::metatype_ ## TYPE \
|
||||
<< &Lib2::metatype_ ## TYPE;
|
||||
FOR_EACH_METATYPE_LIBS(ADD_ROW)
|
||||
#undef ADD_ROW
|
||||
}
|
||||
|
||||
void tst_QMetaType::operatorEqAcrossLibs()
|
||||
{
|
||||
QFETCH(int, builtinTypeId);
|
||||
QFETCH(QMetaType, localType);
|
||||
QFETCH(LibMetatypeFunction, lib1Function);
|
||||
QFETCH(LibMetatypeFunction, lib2Function);
|
||||
|
||||
QMetaType lib1Type = lib1Function();
|
||||
QMetaType lib2Type = lib2Function();
|
||||
|
||||
const QtPrivate::QMetaTypeInterface *localIface = localType.iface();
|
||||
const QtPrivate::QMetaTypeInterface *lib1Iface = lib1Type.iface();
|
||||
const QtPrivate::QMetaTypeInterface *lib2Iface = lib2Type.iface();
|
||||
|
||||
// DO THIS FIRST:
|
||||
// if this isn't a built-in type, then the QMetaTypeInterface::typeId is
|
||||
// initially set to 0
|
||||
QCOMPARE(lib1Type, lib2Type);
|
||||
|
||||
int actualTypeId = localType.id();
|
||||
bool builtinTypeExpected = builtinTypeId != QMetaType::UnknownType;
|
||||
bool builtinTypeActually = actualTypeId < QMetaType::User;
|
||||
|
||||
qDebug() << "QMetaType for type" << QByteArray(localType.name())
|
||||
<< "(type ID" << (actualTypeId >= 0x1000 ? Qt::hex : Qt::dec) << actualTypeId << ')'
|
||||
<< (builtinTypeActually ? "IS" : "is NOT") << "a built-in type;"
|
||||
<< "local interface:" << static_cast<const void *>(localIface)
|
||||
<< "lib1 interface:" << static_cast<const void *>(lib1Iface)
|
||||
<< "lib2 interface:" << static_cast<const void *>(lib2Iface);
|
||||
|
||||
QCOMPARE(builtinTypeActually, builtinTypeExpected);
|
||||
QCOMPARE(lib1Type.id(), actualTypeId);
|
||||
QCOMPARE(lib2Type.id(), actualTypeId);
|
||||
QCOMPARE(QByteArray(lib1Type.name()), QByteArray(localType.name()));
|
||||
QCOMPARE(QByteArray(lib2Type.name()), QByteArray(localType.name()));
|
||||
QCOMPARE(lib1Type, localType);
|
||||
QCOMPARE(lib2Type, localType);
|
||||
}
|
||||
|
||||
class WithPrivateDTor {
|
||||
|
24
tests/auto/corelib/kernel/qmetatype/tst_qmetatype_libs.h
Normal file
24
tests/auto/corelib/kernel/qmetatype/tst_qmetatype_libs.h
Normal file
@ -0,0 +1,24 @@
|
||||
// Copyright (C) 2022 Intel Corporation
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#ifndef TST_QMETATYPE_LIBS_H
|
||||
#define TST_QMETATYPE_LIBS_H
|
||||
|
||||
#include <qmetatype.h>
|
||||
|
||||
#include <stdlib.h> // for div_t
|
||||
|
||||
// void: builtin metatype, special
|
||||
// int: builtin metatype, primitive type
|
||||
// QString: builtin metatype, class
|
||||
// QCollator: not builtin, class, Q_CORE_EXPORT
|
||||
// div_t: not builtin, class, no export
|
||||
#define FOR_EACH_METATYPE_LIBS(F) \
|
||||
F(void, QMetaType::Void) \
|
||||
F(int, QMetaType::Int) \
|
||||
F(QString, QMetaType::QString) \
|
||||
F(QCollator, QMetaType::UnknownType) \
|
||||
F(div_t, QMetaType::UnknownType) \
|
||||
/**/
|
||||
|
||||
#endif // TST_QMETATYPE_LIBS_H
|
Loading…
Reference in New Issue
Block a user