Refactor tst_qcomparehelpers

Previously the test consisted of just one cpp file. An attempt to add
more test cases to the file resulted in the minGW compiler complaining
about a too large object file:

 Fatal error: tst_qcomparehelpers.cpp.obj: file too big

This patch splits the implementation into a header and a cpp file.
This itself does not fix the issues, but now we can add the new test
cases in a separate cpp file. This patch also adds some comments
that advocate doing so.

Change-Id: I451987370fa4e18b7ad81dfc064ea016f1d0da47
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
(cherry picked from commit e26914fa0fe8b6bb2a045a8d37e1b73777a5e0ce)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Ivan Solovev 2024-02-08 11:22:51 +01:00 committed by Qt Cherry-pick Bot
parent 4483e81440
commit 62a8bb3477
4 changed files with 255 additions and 188 deletions

View File

@ -3,7 +3,8 @@
qt_internal_add_test(tst_qcomparehelpers
SOURCES
tst_qcomparehelpers.cpp
tst_qcomparehelpers.h tst_qcomparehelpers.cpp
wrappertypes.h
LIBRARIES
Qt::TestPrivate
)
@ -13,7 +14,8 @@ qt_internal_add_test(tst_qcomparehelpers
if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.20" AND NOT MACOS)
qt_internal_add_test(tst_qcomparehelpers_cpp23
SOURCES
tst_qcomparehelpers.cpp
tst_qcomparehelpers.h tst_qcomparehelpers.cpp
wrappertypes.h
DEFINES
tst_QCompareHelpers=tst_QCompareHelpersCpp23
LIBRARIES

View File

@ -1,198 +1,20 @@
// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QtCore/qcompare.h>
#include <QtTest/qtest.h>
#include <QtTest/private/qcomparisontesthelper_p.h>
#include "tst_qcomparehelpers.h"
#include "wrappertypes.h"
#if defined(__STDCPP_FLOAT16_T__) && __has_include(<stdfloat>)
#include <stdfloat>
#endif
class IntWrapper
{
public:
// implicit constructor and operator int() to simulate the case that
// triggers a bug on MSVC < 19.36.
IntWrapper(int val) : m_val(val) {}
operator int() const noexcept { return m_val; }
/*
NOTE: Do not add any other test cases to this cpp file!
minGW already complains about a too large tst_qcomparehelpers.cpp.obj
object file.
int value() const { return m_val; }
private:
friend bool comparesEqual(const IntWrapper &lhs, const IntWrapper &rhs) noexcept
{ return lhs.m_val == rhs.m_val; }
friend Qt::strong_ordering
compareThreeWay(const IntWrapper &lhs, const IntWrapper &rhs) noexcept
{
return Qt::compareThreeWay(lhs.m_val, rhs.m_val);
}
friend bool comparesEqual(const IntWrapper &lhs, int rhs) noexcept
{ return lhs.m_val == rhs; }
friend Qt::strong_ordering compareThreeWay(const IntWrapper &lhs, int rhs) noexcept
{ return compareThreeWay(lhs, IntWrapper(rhs)); }
Q_DECLARE_STRONGLY_ORDERED(IntWrapper)
Q_DECLARE_STRONGLY_ORDERED(IntWrapper, int)
int m_val = 0;
};
class DoubleWrapper
{
public:
explicit DoubleWrapper(double val) : m_val(val) {}
double value() const { return m_val; }
private:
friend bool comparesEqual(const DoubleWrapper &lhs, const DoubleWrapper &rhs) noexcept
{ return lhs.m_val == rhs.m_val; }
friend Qt::partial_ordering
compareThreeWay(const DoubleWrapper &lhs, const DoubleWrapper &rhs) noexcept
{
return Qt::compareThreeWay(lhs.m_val, rhs.m_val);
}
friend bool comparesEqual(const DoubleWrapper &lhs, const IntWrapper &rhs) noexcept
{ return comparesEqual(lhs, DoubleWrapper(rhs.value())); }
friend Qt::partial_ordering
compareThreeWay(const DoubleWrapper &lhs, const IntWrapper &rhs) noexcept
{ return compareThreeWay(lhs, DoubleWrapper(rhs.value())); }
friend bool comparesEqual(const DoubleWrapper &lhs, double rhs) noexcept
{ return lhs.m_val == rhs; }
friend Qt::partial_ordering compareThreeWay(const DoubleWrapper &lhs, double rhs) noexcept
{
return Qt::compareThreeWay(lhs.m_val, rhs);
}
Q_DECLARE_PARTIALLY_ORDERED(DoubleWrapper)
Q_DECLARE_PARTIALLY_ORDERED(DoubleWrapper, IntWrapper)
Q_DECLARE_PARTIALLY_ORDERED(DoubleWrapper, double)
double m_val = 0.0;
};
template <typename String>
class StringWrapper
{
public:
explicit StringWrapper(String val) : m_val(val) {}
String value() const { return m_val; }
private:
// Some of the helper functions are intentionally NOT marked as noexcept
// to test the conditional noexcept in the macros.
template <typename T>
friend bool comparesEqual(const StringWrapper<T> &, const StringWrapper<T> &) noexcept;
template <typename T>
friend Qt::weak_ordering
compareThreeWay(const StringWrapper<T> &, const StringWrapper<T> &) noexcept;
template <typename T>
friend bool comparesEqual(const StringWrapper<T> &, QAnyStringView);
template <typename T>
friend Qt::weak_ordering compareThreeWay(const StringWrapper<T> &, QAnyStringView);
Q_DECLARE_WEAKLY_ORDERED(StringWrapper)
Q_DECLARE_WEAKLY_ORDERED(StringWrapper, QAnyStringView)
String m_val;
};
// StringWrapper comparison helper functions
bool equalsHelper(QAnyStringView lhs, QAnyStringView rhs) noexcept
{
return QAnyStringView::compare(lhs, rhs, Qt::CaseInsensitive) == 0;
}
template <typename T>
bool comparesEqual(const StringWrapper<T> &lhs, const StringWrapper<T> &rhs) noexcept
{
return equalsHelper(lhs.m_val, rhs.m_val);
}
Qt::weak_ordering compareHelper(QAnyStringView lhs, QAnyStringView rhs) noexcept
{
const int res = QAnyStringView::compare(lhs, rhs, Qt::CaseInsensitive);
if (res < 0)
return Qt::weak_ordering::less;
else if (res > 0)
return Qt::weak_ordering::greater;
else
return Qt::weak_ordering::equivalent;
}
template <typename T>
Qt::weak_ordering compareThreeWay(const StringWrapper<T> &lhs, const StringWrapper<T> &rhs) noexcept
{
return compareHelper(lhs.m_val, rhs.m_val);
}
template <typename T>
bool comparesEqual(const StringWrapper<T> &lhs, QAnyStringView rhs)
{
return equalsHelper(lhs.m_val, rhs);
}
template <typename T>
Qt::weak_ordering compareThreeWay(const StringWrapper<T> &lhs, QAnyStringView rhs)
{
return compareHelper(lhs.m_val, rhs);
}
// Test class
class tst_QCompareHelpers : public QObject
{
Q_OBJECT
private:
template <typename LeftType, typename RightType, typename OrderingType>
void compareImpl();
template <typename LeftType, typename RightType>
void compareIntData();
template <typename LeftType, typename RightType>
void compareFloatData();
template <typename LeftType, typename RightType>
void compareStringData();
private slots:
void comparisonCompiles();
void compare_IntWrapper_data() { compareIntData<IntWrapper, IntWrapper>(); }
void compare_IntWrapper() { compareImpl<IntWrapper, IntWrapper, Qt::strong_ordering>(); }
void compare_IntWrapper_int_data() { compareIntData<IntWrapper, int>(); }
void compare_IntWrapper_int() { compareImpl<IntWrapper, int, Qt::strong_ordering>(); }
void compare_DoubleWrapper_data() { compareFloatData<DoubleWrapper, DoubleWrapper>(); }
void compare_DoubleWrapper()
{ compareImpl<DoubleWrapper, DoubleWrapper, Qt::partial_ordering>(); }
void compare_DoubleWrapper_double_data() { compareFloatData<DoubleWrapper, double>(); }
void compare_DoubleWrapper_double()
{ compareImpl<DoubleWrapper, double, Qt::partial_ordering>(); }
void compare_IntWrapper_DoubleWrapper_data();
void compare_IntWrapper_DoubleWrapper()
{ compareImpl<IntWrapper, DoubleWrapper, Qt::partial_ordering>(); }
void compare_StringWrapper_data()
{ compareStringData<StringWrapper<QString>, StringWrapper<QString>>(); }
void compare_StringWrapper()
{ compareImpl<StringWrapper<QString>, StringWrapper<QString>, Qt::weak_ordering>(); }
void compare_StringWrapper_AnyStringView_data()
{ compareStringData<StringWrapper<QString>, QAnyStringView>(); }
void compare_StringWrapper_AnyStringView()
{ compareImpl<StringWrapper<QString>, QAnyStringView, Qt::weak_ordering>(); }
void generatedClasses();
void builtinOrder();
};
Create a new cpp file and add new tests there.
*/
template<typename LeftType, typename RightType, typename OrderingType>
void tst_QCompareHelpers::compareImpl()
@ -315,6 +137,46 @@ void tst_QCompareHelpers::comparisonCompiles()
return;
}
void tst_QCompareHelpers::compare_IntWrapper_data()
{
compareIntData<IntWrapper, IntWrapper>();
}
void tst_QCompareHelpers::compare_IntWrapper()
{
compareImpl<IntWrapper, IntWrapper, Qt::strong_ordering>();
}
void tst_QCompareHelpers::compare_IntWrapper_int_data()
{
compareIntData<IntWrapper, int>();
}
void tst_QCompareHelpers::compare_IntWrapper_int()
{
compareImpl<IntWrapper, int, Qt::strong_ordering>();
}
void tst_QCompareHelpers::compare_DoubleWrapper_data()
{
compareFloatData<DoubleWrapper, DoubleWrapper>();
}
void tst_QCompareHelpers::compare_DoubleWrapper()
{
compareImpl<DoubleWrapper, DoubleWrapper, Qt::partial_ordering>();
}
void tst_QCompareHelpers::compare_DoubleWrapper_double_data()
{
compareFloatData<DoubleWrapper, double>();
}
void tst_QCompareHelpers::compare_DoubleWrapper_double()
{
compareImpl<DoubleWrapper, double, Qt::partial_ordering>();
}
void tst_QCompareHelpers::compare_IntWrapper_DoubleWrapper_data()
{
QTest::addColumn<IntWrapper>("lhs");
@ -347,6 +209,31 @@ void tst_QCompareHelpers::compare_IntWrapper_DoubleWrapper_data()
createRow(min, -inf, Qt::partial_ordering::greater);
}
void tst_QCompareHelpers::compare_IntWrapper_DoubleWrapper()
{
compareImpl<IntWrapper, DoubleWrapper, Qt::partial_ordering>();
}
void tst_QCompareHelpers::compare_StringWrapper_data()
{
compareStringData<StringWrapper<QString>, StringWrapper<QString>>();
}
void tst_QCompareHelpers::compare_StringWrapper()
{
compareImpl<StringWrapper<QString>, StringWrapper<QString>, Qt::weak_ordering>();
}
void tst_QCompareHelpers::compare_StringWrapper_AnyStringView_data()
{
compareStringData<StringWrapper<QString>, QAnyStringView>();
}
void tst_QCompareHelpers::compare_StringWrapper_AnyStringView()
{
compareImpl<StringWrapper<QString>, QAnyStringView, Qt::weak_ordering>();
}
#define DECLARE_TYPE(Name, Type, Attrs, RetType, Constexpr, Suffix) \
class Dummy ## Name \
{ \

View File

@ -0,0 +1,62 @@
// Copyright (C) 2024 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#ifndef TST_QCOMPAREHELPERS_H
#define TST_QCOMPAREHELPERS_H
#include <QtCore/qcompare.h>
#include <QtTest/qtest.h>
#include <QtTest/private/qcomparisontesthelper_p.h>
class tst_QCompareHelpers : public QObject
{
Q_OBJECT
private:
template <typename LeftType, typename RightType, typename OrderingType>
void compareImpl();
template <typename LeftType, typename RightType>
void compareIntData();
template <typename LeftType, typename RightType>
void compareFloatData();
template <typename LeftType, typename RightType>
void compareStringData();
private Q_SLOTS:
// tst_qcomparehelpers.cpp
void comparisonCompiles();
void compare_IntWrapper_data();
void compare_IntWrapper();
void compare_IntWrapper_int_data();
void compare_IntWrapper_int();
void compare_DoubleWrapper_data();
void compare_DoubleWrapper();
void compare_DoubleWrapper_double_data();
void compare_DoubleWrapper_double();
void compare_IntWrapper_DoubleWrapper_data();
void compare_IntWrapper_DoubleWrapper();
void compare_StringWrapper_data();
void compare_StringWrapper();
void compare_StringWrapper_AnyStringView_data();
void compare_StringWrapper_AnyStringView();
void generatedClasses();
void builtinOrder();
// Add new test cases to another cpp file, because minGW already complains
// about a too large tst_qcomparehelpers.cpp.obj object file
};
#endif // TST_QCOMPAREHELPERS_H

View File

@ -0,0 +1,116 @@
// Copyright (C) 2024 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#ifndef TST_QCOMPAREHELPERS_WRAPPERTYPES_H
#define TST_QCOMPAREHELPERS_WRAPPERTYPES_H
#include <QtCore/qanystringview.h>
#include <QtCore/qcompare.h>
class IntWrapper
{
public:
// implicit constructor and operator int() to simulate the case that
// triggers a bug on MSVC < 19.36.
IntWrapper(int val) : m_val(val) {}
operator int() const noexcept { return m_val; }
int value() const { return m_val; }
private:
friend bool comparesEqual(const IntWrapper &lhs, const IntWrapper &rhs) noexcept
{ return lhs.m_val == rhs.m_val; }
friend Qt::strong_ordering
compareThreeWay(const IntWrapper &lhs, const IntWrapper &rhs) noexcept
{
return Qt::compareThreeWay(lhs.m_val, rhs.m_val);
}
friend bool comparesEqual(const IntWrapper &lhs, int rhs) noexcept
{ return lhs.m_val == rhs; }
friend Qt::strong_ordering compareThreeWay(const IntWrapper &lhs, int rhs) noexcept
{ return compareThreeWay(lhs, IntWrapper(rhs)); }
Q_DECLARE_STRONGLY_ORDERED(IntWrapper)
Q_DECLARE_STRONGLY_ORDERED(IntWrapper, int)
int m_val = 0;
};
class DoubleWrapper
{
public:
explicit DoubleWrapper(double val) : m_val(val) {}
double value() const { return m_val; }
private:
friend bool comparesEqual(const DoubleWrapper &lhs, const DoubleWrapper &rhs) noexcept
{ return lhs.m_val == rhs.m_val; }
friend Qt::partial_ordering
compareThreeWay(const DoubleWrapper &lhs, const DoubleWrapper &rhs) noexcept
{
return Qt::compareThreeWay(lhs.m_val, rhs.m_val);
}
friend bool comparesEqual(const DoubleWrapper &lhs, const IntWrapper &rhs) noexcept
{ return comparesEqual(lhs, DoubleWrapper(rhs.value())); }
friend Qt::partial_ordering
compareThreeWay(const DoubleWrapper &lhs, const IntWrapper &rhs) noexcept
{ return compareThreeWay(lhs, DoubleWrapper(rhs.value())); }
friend bool comparesEqual(const DoubleWrapper &lhs, double rhs) noexcept
{ return lhs.m_val == rhs; }
friend Qt::partial_ordering compareThreeWay(const DoubleWrapper &lhs, double rhs) noexcept
{
return Qt::compareThreeWay(lhs.m_val, rhs);
}
Q_DECLARE_PARTIALLY_ORDERED(DoubleWrapper)
Q_DECLARE_PARTIALLY_ORDERED(DoubleWrapper, IntWrapper)
Q_DECLARE_PARTIALLY_ORDERED(DoubleWrapper, double)
double m_val = 0.0;
};
template <typename String>
class StringWrapper
{
public:
explicit StringWrapper(String val) : m_val(val) {}
String value() const { return m_val; }
private:
static bool equalsHelper(QAnyStringView lhs, QAnyStringView rhs) noexcept
{ return QAnyStringView::compare(lhs, rhs, Qt::CaseInsensitive) == 0; }
static Qt::weak_ordering compareHelper(QAnyStringView lhs, QAnyStringView rhs) noexcept
{
const int res = QAnyStringView::compare(lhs, rhs, Qt::CaseInsensitive);
if (res < 0)
return Qt::weak_ordering::less;
else if (res > 0)
return Qt::weak_ordering::greater;
else
return Qt::weak_ordering::equivalent;
}
// Some of the helper functions are intentionally NOT marked as noexcept
// to test the conditional noexcept in the macros.
template <typename T>
friend bool comparesEqual(const StringWrapper<T> &lhs, const StringWrapper<T> &rhs) noexcept
{ return StringWrapper<T>::equalsHelper(lhs.m_val, rhs.m_val); }
template <typename T>
friend Qt::weak_ordering
compareThreeWay(const StringWrapper<T> &lhs, const StringWrapper<T> &rhs) noexcept
{ return StringWrapper<T>::compareHelper(lhs.m_val, rhs.m_val); }
template <typename T>
friend bool comparesEqual(const StringWrapper<T> &lhs, QAnyStringView rhs)
{ return StringWrapper<T>::equalsHelper(lhs.m_val, rhs); }
template <typename T>
friend Qt::weak_ordering compareThreeWay(const StringWrapper<T> &lhs, QAnyStringView rhs)
{ return StringWrapper<T>::compareHelper(lhs.m_val, rhs); }
Q_DECLARE_WEAKLY_ORDERED(StringWrapper)
Q_DECLARE_WEAKLY_ORDERED(StringWrapper, QAnyStringView)
String m_val;
};
#endif // TST_QCOMPAREHELPERS_WRAPPERTYPES_H