diff options
Diffstat (limited to 'tests/auto/corelib')
149 files changed, 3650 insertions, 877 deletions
diff --git a/tests/auto/corelib/animation/qpropertyanimation/tst_qpropertyanimation.cpp b/tests/auto/corelib/animation/qpropertyanimation/tst_qpropertyanimation.cpp index 03755fa7ab..3ebec35f12 100644 --- a/tests/auto/corelib/animation/qpropertyanimation/tst_qpropertyanimation.cpp +++ b/tests/auto/corelib/animation/qpropertyanimation/tst_qpropertyanimation.cpp @@ -7,6 +7,7 @@ #include <QAnimationGroup> #include <QSequentialAnimationGroup> #include <QtCore/qpropertyanimation.h> +#include <QtCore/qtimer.h> #include <QtCore/qvariantanimation.h> #include <private/qabstractanimation_p.h> #include <QtGui/qpointingdevice.h> diff --git a/tests/auto/corelib/global/CMakeLists.txt b/tests/auto/corelib/global/CMakeLists.txt index 7970116672..8adf9d7430 100644 --- a/tests/auto/corelib/global/CMakeLists.txt +++ b/tests/auto/corelib/global/CMakeLists.txt @@ -16,6 +16,9 @@ if(NOT INTEGRITY) add_subdirectory(qnativeinterface) endif() add_subdirectory(qrandomgenerator) +if (QT_FEATURE_settings) + add_subdirectory(qlibraryinfo) +endif() add_subdirectory(qlogging) add_subdirectory(qtendian) add_subdirectory(qglobalstatic) diff --git a/tests/auto/corelib/global/q20/CMakeLists.txt b/tests/auto/corelib/global/q20/CMakeLists.txt index bd28f8b999..141f94d9f7 100644 --- a/tests/auto/corelib/global/q20/CMakeLists.txt +++ b/tests/auto/corelib/global/q20/CMakeLists.txt @@ -1 +1,3 @@ +# Copyright (C) 2024 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause add_subdirectory(memory) diff --git a/tests/auto/corelib/global/qcompare/tst_qcompare.cpp b/tests/auto/corelib/global/qcompare/tst_qcompare.cpp index e36429e62b..556c8212b3 100644 --- a/tests/auto/corelib/global/qcompare/tst_qcompare.cpp +++ b/tests/auto/corelib/global/qcompare/tst_qcompare.cpp @@ -785,9 +785,10 @@ void tst_QCompare::compareThreeWay() static_assert(noexcept(qCompareThreeWay(std::declval<TestEnum>(), std::declval<TestEnum>()))); // pointers - static_assert(noexcept(qCompareThreeWay(std::declval<StringWrapper *>(), - std::declval<StringWrapper *>()))); - static_assert(noexcept(qCompareThreeWay(std::declval<StringWrapper *>(), nullptr))); + using StringWrapperPtr = Qt::totally_ordered_wrapper<StringWrapper *>; + static_assert(noexcept(qCompareThreeWay(std::declval<StringWrapperPtr>(), + std::declval<StringWrapperPtr>()))); + static_assert(noexcept(qCompareThreeWay(std::declval<StringWrapperPtr>(), nullptr))); // Test some actual comparison results @@ -832,8 +833,17 @@ void tst_QCompare::compareThreeWay() // pointers std::array<int, 2> arr{1, 0}; +#if QT_DEPRECATED_SINCE(6, 8) +QT_WARNING_PUSH +QT_WARNING_DISABLE_DEPRECATED QCOMPARE_EQ(qCompareThreeWay(&arr[1], &arr[0]), Qt::strong_ordering::greater); QCOMPARE_EQ(qCompareThreeWay(arr.data(), &arr[0]), Qt::strong_ordering::equivalent); +QT_WARNING_POP +#endif // QT_DEPRECATED_SINCE(6, 8) + const auto a0 = Qt::totally_ordered_wrapper(&arr[0]); + const auto a1 = Qt::totally_ordered_wrapper(&arr[1]); + QCOMPARE_EQ(qCompareThreeWay(a1, a0), Qt::strong_ordering::greater); + QCOMPARE_EQ(qCompareThreeWay(arr.data(), a0), Qt::strong_ordering::equivalent); } QTEST_MAIN(tst_QCompare) diff --git a/tests/auto/corelib/global/qcomparehelpers/CMakeLists.txt b/tests/auto/corelib/global/qcomparehelpers/CMakeLists.txt index 25b8812153..31d8bff0a5 100644 --- a/tests/auto/corelib/global/qcomparehelpers/CMakeLists.txt +++ b/tests/auto/corelib/global/qcomparehelpers/CMakeLists.txt @@ -17,7 +17,7 @@ qt_internal_add_test(tst_qcomparehelpers # CMake recognizes CXX_STANDARD=23 only starting from version 3.20 # macOS has some issues with concepts, see QTBUG-117765 -if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.20" AND NOT MACOS AND NOT VXWORKS) +if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.20" AND NOT MACOS AND NOT VXWORKS AND NOT (LINUX AND "${CMAKE_SYSTEM_PROCESSOR}" MATCHES "aarch64")) qt_internal_add_test(tst_qcomparehelpers_cpp23 SOURCES tst_qcomparehelpers.h tst_qcomparehelpers.cpp tst_qcomparehelpers1.cpp diff --git a/tests/auto/corelib/global/qcomparehelpers/tst_qcomparehelpers.cpp b/tests/auto/corelib/global/qcomparehelpers/tst_qcomparehelpers.cpp index f140c23ed0..466723a271 100644 --- a/tests/auto/corelib/global/qcomparehelpers/tst_qcomparehelpers.cpp +++ b/tests/auto/corelib/global/qcomparehelpers/tst_qcomparehelpers.cpp @@ -581,20 +581,46 @@ void tst_QCompareHelpers::builtinOrder() Qt::strong_ordering::equivalent); std::array<int, 2> arr{1, 0}; +#if QT_DEPRECATED_SINCE(6, 8) +QT_WARNING_PUSH +QT_WARNING_DISABLE_DEPRECATED QCOMPARE_EQ(Qt::compareThreeWay(&arr[0], &arr[1]), Qt::strong_ordering::less); QCOMPARE_EQ(Qt::compareThreeWay(arr.data(), &arr[0]), Qt::strong_ordering::equivalent); +QT_WARNING_POP +#endif // QT_DEPRECATED_SINCE(6, 8) class Base {}; class Derived : public Base {}; auto b = std::make_unique<Base>(); auto d = std::make_unique<Derived>(); +#if QT_DEPRECATED_SINCE(6, 8) +QT_WARNING_PUSH +QT_WARNING_DISABLE_DEPRECATED QCOMPARE_NE(Qt::compareThreeWay(b.get(), d.get()), Qt::strong_ordering::equivalent); QCOMPARE_EQ(Qt::compareThreeWay(b.get(), nullptr), Qt::strong_ordering::greater); QCOMPARE_EQ(Qt::compareThreeWay(nullptr, d.get()), Qt::strong_ordering::less); +QT_WARNING_POP +#endif // QT_DEPRECATED_SINCE(6, 8) + + // Check Qt::totally_ordered_wrapper + auto a0 = Qt::totally_ordered_wrapper(&arr[0]); + auto a1 = Qt::totally_ordered_wrapper(&arr[1]); + QCOMPARE_EQ(Qt::compareThreeWay(a0, a1), Qt::strong_ordering::less); + QCOMPARE_EQ(Qt::compareThreeWay(arr.data(), a0), Qt::strong_ordering::equivalent); + + auto bWrapper = Qt::totally_ordered_wrapper(b.get()); + auto dWrapper = Qt::totally_ordered_wrapper(d.get()); + QCOMPARE_NE(Qt::compareThreeWay(bWrapper, dWrapper), Qt::strong_ordering::equivalent); + QCOMPARE_NE(Qt::compareThreeWay(bWrapper, d.get()), Qt::strong_ordering::equivalent); + QCOMPARE_NE(Qt::compareThreeWay(b.get(), dWrapper), Qt::strong_ordering::equivalent); + QCOMPARE_EQ(Qt::compareThreeWay(bWrapper, nullptr), Qt::strong_ordering::greater); + QCOMPARE_EQ(Qt::compareThreeWay(nullptr, dWrapper), Qt::strong_ordering::less); + dWrapper.reset(nullptr); + QCOMPARE_EQ(Qt::compareThreeWay(nullptr, dWrapper), Qt::strong_ordering::equivalent); #undef TEST_BUILTIN } QTEST_MAIN(tst_QCompareHelpers) -#include "tst_qcomparehelpers.moc" +#include "moc_tst_qcomparehelpers.cpp" diff --git a/tests/auto/corelib/global/qcomparehelpers/tst_qcomparehelpers1.cpp b/tests/auto/corelib/global/qcomparehelpers/tst_qcomparehelpers1.cpp index a3b8200a63..16b2842de2 100644 --- a/tests/auto/corelib/global/qcomparehelpers/tst_qcomparehelpers1.cpp +++ b/tests/auto/corelib/global/qcomparehelpers/tst_qcomparehelpers1.cpp @@ -4,23 +4,26 @@ #include "tst_qcomparehelpers.h" #define DECLARE_TYPE(Name, Type, RetType, Constexpr, Suffix) \ -class Deprecated ## Name \ +class Templated ## Name \ { \ public: \ - Constexpr Deprecated ## Name () {} \ + Constexpr Templated ## Name () {} \ \ private: \ + template <typename X> \ friend Constexpr bool \ - comparesEqual(const Deprecated ## Name &lhs, int rhs) noexcept; \ + comparesEqual(const Templated ## Name &lhs, X rhs) noexcept; \ + template <typename X> \ friend Constexpr RetType \ - compareThreeWay(const Deprecated ## Name &lhs, int rhs) noexcept; \ - Q_DECLARE_ ## Type ## _ORDERED ## Suffix (Deprecated ## Name, int, \ - Q_DECL_DEPRECATED_X("This op is deprecated")) \ + compareThreeWay(const Templated ## Name &lhs, X rhs) noexcept; \ + Q_DECLARE_ ## Type ## _ORDERED ## Suffix (Templated ## Name, X, template <typename X>) \ }; \ \ -Constexpr bool comparesEqual(const Deprecated ## Name &lhs, int rhs) noexcept \ +template <typename X> \ +Constexpr bool comparesEqual(const Templated ## Name &lhs, X rhs) noexcept \ { Q_UNUSED(lhs); Q_UNUSED(rhs); return true; } \ -Constexpr RetType compareThreeWay(const Deprecated ## Name &lhs, int rhs) noexcept \ +template <typename X> \ +Constexpr RetType compareThreeWay(const Templated ## Name &lhs, X rhs) noexcept \ { Q_UNUSED(lhs); Q_UNUSED(rhs); return RetType::equivalent; } DECLARE_TYPE(PartialConst, PARTIALLY, Qt::partial_ordering, constexpr, _LITERAL_TYPE) @@ -34,10 +37,6 @@ DECLARE_TYPE(Strong, STRONGLY, Qt::strong_ordering, , ) void tst_QCompareHelpers::compareWithAttributes() { - // All these comparisons would trigger deprecation warnings. -QT_WARNING_PUSH -QT_WARNING_DISABLE_DEPRECATED - #define COMPARE(ClassName) \ do { \ ClassName c; \ @@ -46,14 +45,12 @@ QT_WARNING_DISABLE_DEPRECATED QCOMPARE_GE(0, c); \ } while (false) - COMPARE(DeprecatedPartialConst); - COMPARE(DeprecatedPartial); - COMPARE(DeprecatedWeakConst); - COMPARE(DeprecatedWeak); - COMPARE(DeprecatedStrongConst); - COMPARE(DeprecatedStrong); + COMPARE(TemplatedPartialConst); + COMPARE(TemplatedPartial); + COMPARE(TemplatedWeakConst); + COMPARE(TemplatedWeak); + COMPARE(TemplatedStrongConst); + COMPARE(TemplatedStrong); #undef COMPARE - -QT_WARNING_POP } diff --git a/tests/auto/corelib/global/qfloat16/tst_qfloat16.cpp b/tests/auto/corelib/global/qfloat16/tst_qfloat16.cpp index 7acf8c2cf6..5f1ff67316 100644 --- a/tests/auto/corelib/global/qfloat16/tst_qfloat16.cpp +++ b/tests/auto/corelib/global/qfloat16/tst_qfloat16.cpp @@ -155,6 +155,7 @@ void tst_qfloat16::ordering_data() row(2.0f, -inf); row(-2.0f, nan); row(-inf, -2.0f); + // testing with values outside qfloat16 range row(0.0f, 13e5f); // generateRow(inf, 13e5f); // fails qfloat16 vs qfloat16 and qfloat16 vs int (QTBUG-118193) @@ -187,11 +188,21 @@ void tst_qfloat16::ordering() #undef CHECK_FP + auto check_int = [=](auto rhs) { + // check that we're in range before converting, otherwise + // [conv.fpint]/1 says it would be UB + using RHS = decltype(rhs); + if (right > double(std::numeric_limits<RHS>::max())) + return; + if (auto min = std::numeric_limits<RHS>::min(); min != 0 && right < double(min)) + return; + rhs = RHS(right); + const auto expectedRes = Qt::compareThreeWay(left, rhs); + QTestPrivate::testAllComparisonOperators(lhs, rhs, expectedRes); + }; #define CHECK_INT(RHS) \ do { \ - const auto rhs = static_cast<RHS>(right); \ - const auto expectedRes = Qt::compareThreeWay(left, rhs); \ - QTestPrivate::testAllComparisonOperators(lhs, rhs, expectedRes); \ + check_int(static_cast<RHS>(0)); \ POSTCHECK("qfloat16 vs " #RHS " comparison failed") \ } while (false) \ /* END */ diff --git a/tests/auto/corelib/global/qkeycombination/CMakeLists.txt b/tests/auto/corelib/global/qkeycombination/CMakeLists.txt index 0b1d519e4f..911eef7289 100644 --- a/tests/auto/corelib/global/qkeycombination/CMakeLists.txt +++ b/tests/auto/corelib/global/qkeycombination/CMakeLists.txt @@ -14,4 +14,6 @@ endif() qt_internal_add_test(tst_qkeycombination SOURCES tst_qkeycombination.cpp + LIBRARIES + Qt::TestPrivate ) diff --git a/tests/auto/corelib/global/qkeycombination/tst_qkeycombination.cpp b/tests/auto/corelib/global/qkeycombination/tst_qkeycombination.cpp index 06da0d2444..9941f8e154 100644 --- a/tests/auto/corelib/global/qkeycombination/tst_qkeycombination.cpp +++ b/tests/auto/corelib/global/qkeycombination/tst_qkeycombination.cpp @@ -3,11 +3,13 @@ #include <QObject> #include <QTest> +#include <QtTest/private/qcomparisontesthelper_p.h> class tst_QKeyCombination : public QObject { Q_OBJECT private slots: + void compareCompiles(); void construction(); void operator_eq(); void operator_or(); @@ -24,6 +26,11 @@ constexpr auto bitwiseOr(T ... args) return (... | ((int)args)); } +void tst_QKeyCombination::compareCompiles() +{ + QTestPrivate::testEqualityOperatorsCompile<QKeyCombination>(); +} + void tst_QKeyCombination::construction() { { @@ -131,145 +138,125 @@ void tst_QKeyCombination::operator_eq() // default { QKeyCombination a, b; - QVERIFY(a == b); - QVERIFY(!(a != b)); + QT_TEST_EQUALITY_OPS(a, b, true); } // key only { QKeyCombination a; QKeyCombination b(Qt::Key_X); - QVERIFY(a != b); - QVERIFY(!(a == b)); + QT_TEST_EQUALITY_OPS(a, b, false); } { QKeyCombination a(Qt::Key_Y); QKeyCombination b; - QVERIFY(a != b); - QVERIFY(!(a == b)); + QT_TEST_EQUALITY_OPS(a, b, false); } { QKeyCombination a(Qt::Key_Y); QKeyCombination b(Qt::Key_X); - QVERIFY(a != b); - QVERIFY(!(a == b)); + QT_TEST_EQUALITY_OPS(a, b, false); } { QKeyCombination a(Qt::Key_F1); QKeyCombination b(Qt::Key_F1); - QVERIFY(a == b); - QVERIFY(!(a != b)); + QT_TEST_EQUALITY_OPS(a, b, true); } // modifier only { QKeyCombination a; QKeyCombination b(Qt::CTRL); - QVERIFY(a != b); - QVERIFY(!(a == b)); + QT_TEST_EQUALITY_OPS(a, b, false); } { QKeyCombination a(Qt::CTRL); QKeyCombination b; - QVERIFY(a != b); - QVERIFY(!(a == b)); + QT_TEST_EQUALITY_OPS(a, b, false); } { QKeyCombination a(Qt::CTRL); QKeyCombination b(Qt::SHIFT); - QVERIFY(a != b); - QVERIFY(!(a == b)); + QT_TEST_EQUALITY_OPS(a, b, false); } { QKeyCombination a(Qt::CTRL); QKeyCombination b(Qt::CTRL); - QVERIFY(a == b); - QVERIFY(!(a != b)); + QT_TEST_EQUALITY_OPS(a, b, true); } { QKeyCombination a(Qt::CTRL); QKeyCombination b(Qt::ControlModifier); - QVERIFY(a == b); - QVERIFY(!(a != b)); + QT_TEST_EQUALITY_OPS(a, b, true); } { QKeyCombination a(Qt::ControlModifier); QKeyCombination b(Qt::CTRL); - QVERIFY(a == b); - QVERIFY(!(a != b)); + QT_TEST_EQUALITY_OPS(a, b, true); } { QKeyCombination a(Qt::ControlModifier); QKeyCombination b(Qt::ControlModifier); - QVERIFY(a == b); - QVERIFY(!(a != b)); + QT_TEST_EQUALITY_OPS(a, b, true); } // key and modifier { QKeyCombination a(Qt::Key_A); QKeyCombination b(Qt::SHIFT, Qt::Key_A); - QVERIFY(a != b); - QVERIFY(!(a == b)); + QT_TEST_EQUALITY_OPS(a, b, false); } { QKeyCombination a(Qt::CTRL, Qt::Key_A); QKeyCombination b(Qt::SHIFT, Qt::Key_A); - QVERIFY(a != b); - QVERIFY(!(a == b)); + QT_TEST_EQUALITY_OPS(a, b, false); } { QKeyCombination a(Qt::SHIFT, Qt::Key_A); QKeyCombination b(Qt::SHIFT, Qt::Key_A); - QVERIFY(a == b); - QVERIFY(!(a != b)); + QT_TEST_EQUALITY_OPS(a, b, true); } { QKeyCombination a(Qt::SHIFT, Qt::Key_A); QKeyCombination b(Qt::SHIFT, Qt::Key_Escape); - QVERIFY(a != b); - QVERIFY(!(a == b)); + QT_TEST_EQUALITY_OPS(a, b, false); } { QKeyCombination a(Qt::SHIFT, Qt::Key_A); QKeyCombination b(Qt::ShiftModifier, Qt::Key_A); - QVERIFY(a == b); - QVERIFY(!(a != b)); + QT_TEST_EQUALITY_OPS(a, b, true); } { QKeyCombination a(Qt::SHIFT | Qt::CTRL, Qt::Key_A); QKeyCombination b(Qt::ControlModifier | Qt::ShiftModifier, Qt::Key_A); - QVERIFY(a == b); - QVERIFY(!(a != b)); + QT_TEST_EQUALITY_OPS(a, b, true); } // corner cases { QKeyCombination a(Qt::CTRL); QKeyCombination b(Qt::Key_Control); - QVERIFY(a != b); - QVERIFY(!(a == b)); + QT_TEST_EQUALITY_OPS(a, b, false); } { QKeyCombination a(Qt::ALT); QKeyCombination b(Qt::Key_Alt); - QVERIFY(a != b); - QVERIFY(!(a == b)); + QT_TEST_EQUALITY_OPS(a, b, false); } } diff --git a/tests/auto/corelib/global/qlibraryinfo/CMakeLists.txt b/tests/auto/corelib/global/qlibraryinfo/CMakeLists.txt new file mode 100644 index 0000000000..d72e871967 --- /dev/null +++ b/tests/auto/corelib/global/qlibraryinfo/CMakeLists.txt @@ -0,0 +1,24 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qlibraryinfo LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + + +qt_internal_add_test(tst_qlibraryinfo SOURCES tst_qlibraryinfo.cpp + LIBRARIES + Qt::CorePrivate + +) + +qt_add_resources(tst_qlibraryinfo "qtconffiles" + PREFIX "/" + FILES + empty.qt.conf + partial.qt.conf + list.qt.conf + merge.qt.conf +) diff --git a/tests/auto/corelib/global/qlibraryinfo/empty.qt.conf b/tests/auto/corelib/global/qlibraryinfo/empty.qt.conf new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/auto/corelib/global/qlibraryinfo/empty.qt.conf diff --git a/tests/auto/corelib/global/qlibraryinfo/list.qt.conf b/tests/auto/corelib/global/qlibraryinfo/list.qt.conf new file mode 100644 index 0000000000..9271b414ca --- /dev/null +++ b/tests/auto/corelib/global/qlibraryinfo/list.qt.conf @@ -0,0 +1,2 @@ +[Paths] +Documentation = "/path/to/mydoc","/path/to/anotherdoc","relativePath" diff --git a/tests/auto/corelib/global/qlibraryinfo/merge.qt.conf b/tests/auto/corelib/global/qlibraryinfo/merge.qt.conf new file mode 100644 index 0000000000..a687dc4d71 --- /dev/null +++ b/tests/auto/corelib/global/qlibraryinfo/merge.qt.conf @@ -0,0 +1,5 @@ +[Paths] +QmlImports = "/path/to/myqml" + +[Config] +MergeQtConf=true diff --git a/tests/auto/corelib/global/qlibraryinfo/partial.qt.conf b/tests/auto/corelib/global/qlibraryinfo/partial.qt.conf new file mode 100644 index 0000000000..bba214c2a6 --- /dev/null +++ b/tests/auto/corelib/global/qlibraryinfo/partial.qt.conf @@ -0,0 +1,2 @@ +[Paths] +QmlImports = "/path/to/myqml" diff --git a/tests/auto/corelib/global/qlibraryinfo/tst_qlibraryinfo.cpp b/tests/auto/corelib/global/qlibraryinfo/tst_qlibraryinfo.cpp new file mode 100644 index 0000000000..b7d79c05f5 --- /dev/null +++ b/tests/auto/corelib/global/qlibraryinfo/tst_qlibraryinfo.cpp @@ -0,0 +1,103 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#include <QTest> +#include <QtCore/qlibraryinfo.h> +#include <QtCore/qscopeguard.h> +#include <QtCore/private/qlibraryinfo_p.h> + + +class tst_QLibraryInfo : public QObject +{ + Q_OBJECT +private slots: + void initTestCase(); + void cleanup(); + void path_data(); + void path(); + void paths(); + void merge(); +}; + +void tst_QLibraryInfo::initTestCase() +{ +#if !QT_CONFIG(settings) + QSKIP("QSettings support is required for the test to run."); +#endif +} + +void tst_QLibraryInfo::cleanup() +{ + QLibraryInfoPrivate::setQtconfManualPath(nullptr); + QLibraryInfoPrivate::reload(); +} + +void tst_QLibraryInfo::path_data() +{ + QTest::addColumn<QString>("qtConfPath"); + QTest::addColumn<QLibraryInfo::LibraryPath>("path"); + QTest::addColumn<QString>("expected"); + + // TODO: deal with bundle on macOs? + QString baseDir = QCoreApplication::applicationDirPath(); + + // empty means we fall-back to default entries + QTest::addRow("empty_qmlimports") << ":/empty.qt.conf" << QLibraryInfo::QmlImportsPath << (baseDir + "/qml"); + QTest::addRow("empty_Data") << ":/empty.qt.conf" << QLibraryInfo::DataPath << baseDir; + + // partial override; use given entry if provided, otherwise default + QTest::addRow("partial_qmlimports") << ":/partial.qt.conf" << QLibraryInfo::QmlImportsPath << "/path/to/myqml"; + QTest::addRow("partial_Data") << ":/partial.qt.conf" << QLibraryInfo::DataPath << baseDir; +} + +void tst_QLibraryInfo::path() +{ + QFETCH(QString, qtConfPath); + QFETCH(QLibraryInfo::LibraryPath, path); + QFETCH(QString, expected); + + QLibraryInfoPrivate::setQtconfManualPath(&qtConfPath); + QLibraryInfoPrivate::reload(); + QString value = QLibraryInfo::path(path); + QCOMPARE(value, expected); + + // check consistency with paths + auto values = QLibraryInfo::paths(path); + QVERIFY(!values.isEmpty()); + QCOMPARE(values.first(), expected); +} + +void tst_QLibraryInfo::paths() +{ + QString qtConfPath(u":/list.qt.conf"); + QLibraryInfoPrivate::setQtconfManualPath(&qtConfPath); + QLibraryInfoPrivate::reload(); + + QList<QString> values = QLibraryInfo::paths(QLibraryInfo::DocumentationPath); + QCOMPARE(values.length(), 3); + QCOMPARE(values[0], "/path/to/mydoc"); + QCOMPARE(values[1], "/path/to/anotherdoc"); + QString baseDir = QCoreApplication::applicationDirPath(); + QCOMPARE(values[2], baseDir + "/relativePath"); +} + +void tst_QLibraryInfo::merge() +{ + QString qtConfPath(u":/merge.qt.conf"); + QLibraryInfoPrivate::setQtconfManualPath(&qtConfPath); + QLibraryInfoPrivate::reload(); + + QString baseDir = QCoreApplication::applicationDirPath(); + QString docPath = QLibraryInfo::path(QLibraryInfo::DocumentationPath); + // we can't know where exactly the doc path points, but it should not point to ${baseDir}/doc, + // which would be the behavior without merge_qt_conf + QCOMPARE_NE(docPath, baseDir + "/doc"); + + QList<QString> values = QLibraryInfo::paths(QLibraryInfo::QmlImportsPath); + QCOMPARE(values.size(), 2); // custom entry + Qt default entry + QCOMPARE(values[0], "/path/to/myqml"); +} + +QTEST_GUILESS_MAIN(tst_QLibraryInfo) + +#include "tst_qlibraryinfo.moc" diff --git a/tests/auto/corelib/global/qlogging/CMakeLists.txt b/tests/auto/corelib/global/qlogging/CMakeLists.txt index b3c66aeb2e..f35c9c4192 100644 --- a/tests/auto/corelib/global/qlogging/CMakeLists.txt +++ b/tests/auto/corelib/global/qlogging/CMakeLists.txt @@ -23,7 +23,6 @@ set_target_properties(qlogging_helper PROPERTIES CXX_VISIBILITY_PRESET default) qt_internal_add_test(tst_qlogging SOURCES tst_qlogging.cpp DEFINES QT_MESSAGELOGCONTEXT - HELPER_BINARY="${CMAKE_CURRENT_BINARY_DIR}/qlogging_helper" ) add_dependencies(tst_qlogging qlogging_helper) diff --git a/tests/auto/corelib/global/qlogging/tst_qlogging.cpp b/tests/auto/corelib/global/qlogging/tst_qlogging.cpp index 861e60e256..defe3ac421 100644 --- a/tests/auto/corelib/global/qlogging/tst_qlogging.cpp +++ b/tests/auto/corelib/global/qlogging/tst_qlogging.cpp @@ -986,11 +986,9 @@ QString tst_qmessagehandler::backtraceHelperPath() #ifdef Q_OS_ANDROID QString appExe(QCoreApplication::applicationDirPath() + QLatin1String("/lib" BACKTRACE_HELPER_NAME ".so")); -#elif defined(Q_OS_WEBOS) +#else QString appExe(QCoreApplication::applicationDirPath() + QLatin1String("/" BACKTRACE_HELPER_NAME)); -#else - QString appExe(QLatin1String(HELPER_BINARY)); #endif return appExe; } diff --git a/tests/auto/corelib/global/qxp/CMakeLists.txt b/tests/auto/corelib/global/qxp/CMakeLists.txt index 2178f446db..8292462d17 100644 --- a/tests/auto/corelib/global/qxp/CMakeLists.txt +++ b/tests/auto/corelib/global/qxp/CMakeLists.txt @@ -1,2 +1,4 @@ +# Copyright (C) 2024 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause add_subdirectory(function_ref) add_subdirectory(is_virtual_base_of) diff --git a/tests/auto/corelib/io/CMakeLists.txt b/tests/auto/corelib/io/CMakeLists.txt index 7fdf4b52b0..1e66aa8956 100644 --- a/tests/auto/corelib/io/CMakeLists.txt +++ b/tests/auto/corelib/io/CMakeLists.txt @@ -25,7 +25,7 @@ add_subdirectory(qloggingcategory) add_subdirectory(qnodebug) add_subdirectory(qsavefile) add_subdirectory(qstandardpaths) -if(NOT QNX) +if(NOT QNX AND NOT VXWORKS) add_subdirectory(qstorageinfo) endif() add_subdirectory(qtemporarydir) @@ -68,3 +68,9 @@ endif() if(QT_FEATURE_private_tests) add_subdirectory(qzip) endif() +if(NOT (MACOS AND "$ENV{QT_BUILD_ENVIRONMENT}" STREQUAL "ci")) + # On macOS the new features require at least macOS 13.3, + # but we also run the tests on older OS versions. + # So just skip macOS on CI for now. + add_subdirectory(qfloat16format) +endif() diff --git a/tests/auto/corelib/io/largefile/tst_largefile.cpp b/tests/auto/corelib/io/largefile/tst_largefile.cpp index 6fa3569c4f..f5af3bde63 100644 --- a/tests/auto/corelib/io/largefile/tst_largefile.cpp +++ b/tests/auto/corelib/io/largefile/tst_largefile.cpp @@ -46,6 +46,10 @@ public: // This means that files are limited to 2 GB − 1 bytes. // Limit max size to 256MB maxSizeBits = 28; // 256 MiB + #elif defined(Q_OS_VXWORKS) + // VxWorks doesn't support sparse files, also, default /tmp directory is a RAM-disk which + // limits its capacity. + maxSizeBits = 28; // 256 MiB #elif defined (Q_OS_WASM) maxSizeBits = 28; // 256 MiB #elif defined(QT_LARGEFILE_SUPPORT) @@ -494,6 +498,7 @@ void tst_LargeFile::mapFile() // 32-bit: limited to 44-bit offsets (when sizeof(off_t) == 8) //Windows: memory-mapping beyond EOF is not allowed //wasm: as for linux +//VxWorks: memory-mapping beyond EOF is not allowed void tst_LargeFile::mapOffsetOverflow() { enum { @@ -506,6 +511,9 @@ void tst_LargeFile::mapOffsetOverflow() #elif (defined(Q_OS_LINUX) || defined(Q_OS_ANDROID)) && (Q_PROCESSOR_WORDSIZE == 4) Succeeds = true, MaxOffset = sizeof(QT_OFF_T) > 4 ? 43 : 30 +#elif defined(Q_OS_VXWORKS) + Succeeds = false, + MaxOffset = 8 * sizeof(QT_OFF_T) - 1 #else Succeeds = true, MaxOffset = 8 * sizeof(QT_OFF_T) - 1 diff --git a/tests/auto/corelib/io/qabstractfileengine/tst_qabstractfileengine.cpp b/tests/auto/corelib/io/qabstractfileengine/tst_qabstractfileengine.cpp index 5b706961cc..cf00c1525c 100644 --- a/tests/auto/corelib/io/qabstractfileengine/tst_qabstractfileengine.cpp +++ b/tests/auto/corelib/io/qabstractfileengine/tst_qabstractfileengine.cpp @@ -490,6 +490,7 @@ QHash<QString, QSharedPointer<ReferenceFileEngine::File> > ReferenceFileEngine:: class FileEngineHandler : QAbstractFileEngineHandler { + Q_DISABLE_COPY_MOVE(FileEngineHandler) std::unique_ptr<QAbstractFileEngine> create(const QString &fileName) const override { if (fileName.endsWith(".tar") || fileName.contains(".tar/")) @@ -508,6 +509,8 @@ class FileEngineHandler return nullptr; } +public: + FileEngineHandler() = default; }; void tst_QAbstractFileEngine::initTestCase() @@ -618,12 +621,12 @@ void tst_QAbstractFileEngine::fileIO() * the original size + the '\r' characters added by autocrlf. */ QFile::OpenMode openMode = QIODevice::ReadOnly | QIODevice::Unbuffered; -#ifdef Q_OS_WIN +#if defined (Q_OS_WIN) || defined(Q_OS_WASM) openMode |= QIODevice::Text; #endif QVERIFY(file.open(openMode)); QVERIFY(file.isOpen()); -#ifdef Q_OS_WIN +#if defined(Q_OS_WIN) || defined(Q_OS_WASM) const qint64 convertedSize = fileSize + readContent.count('\n'); if (file.size() == convertedSize) fileSize = convertedSize; diff --git a/tests/auto/corelib/io/qdir/tst_qdir.cpp b/tests/auto/corelib/io/qdir/tst_qdir.cpp index b19f158746..06f0c3d178 100644 --- a/tests/auto/corelib/io/qdir/tst_qdir.cpp +++ b/tests/auto/corelib/io/qdir/tst_qdir.cpp @@ -2285,6 +2285,8 @@ void tst_QDir::equalityOperator_data() QString pathinroot("/system/.."); #elif defined(Q_OS_HAIKU) QString pathinroot("/boot/.."); +#elif defined(Q_OS_VXWORKS) + QString pathinroot("/tmp/.."); #else QString pathinroot("/usr/.."); #endif diff --git a/tests/auto/corelib/io/qdiriterator/tst_qdiriterator.cpp b/tests/auto/corelib/io/qdiriterator/tst_qdiriterator.cpp index 0215f863eb..a0a8917c27 100644 --- a/tests/auto/corelib/io/qdiriterator/tst_qdiriterator.cpp +++ b/tests/auto/corelib/io/qdiriterator/tst_qdiriterator.cpp @@ -443,7 +443,10 @@ public: class EngineWithNoIteratorHandler : public QAbstractFileEngineHandler { + Q_DISABLE_COPY_MOVE(EngineWithNoIteratorHandler) public: + EngineWithNoIteratorHandler() = default; + std::unique_ptr<QAbstractFileEngine> create(const QString &fileName) const override { return std::make_unique<EngineWithNoIterator>(fileName); @@ -462,7 +465,10 @@ void tst_QDirIterator::engineWithNoIterator() class CustomEngineHandler : public QAbstractFileEngineHandler { + Q_DISABLE_COPY_MOVE(CustomEngineHandler) public: + CustomEngineHandler() = default; + std::unique_ptr<QAbstractFileEngine> create(const QString &fileName) const override { // We want to test QFSFileEngine specifically, so force QDirIterator to use it diff --git a/tests/auto/corelib/io/qdirlisting/tst_qdirlisting.cpp b/tests/auto/corelib/io/qdirlisting/tst_qdirlisting.cpp index df541ee710..e2ac1858da 100644 --- a/tests/auto/corelib/io/qdirlisting/tst_qdirlisting.cpp +++ b/tests/auto/corelib/io/qdirlisting/tst_qdirlisting.cpp @@ -85,9 +85,12 @@ private slots: void uncPaths(); #endif #ifndef Q_OS_WIN - void hiddenDirs_hiddenFiles(); + void hiddenFiles(); + void hiddenDirs(); #endif + void withStdAlgorithms(); + private: QSharedPointer<QTemporaryDir> m_dataDir; }; @@ -173,10 +176,10 @@ void tst_QDirListing::initTestCase() createFile("hiddenDirs_hiddenFiles/normalDirectory/.hiddenFile"); createFile("hiddenDirs_hiddenFiles/.hiddenDirectory/normalFile"); createFile("hiddenDirs_hiddenFiles/.hiddenDirectory/.hiddenFile"); - createDirectory("hiddenDirs_hiddenFiles/normalDirectory/normalDirectory"); - createDirectory("hiddenDirs_hiddenFiles/normalDirectory/.hiddenDirectory"); - createDirectory("hiddenDirs_hiddenFiles/.hiddenDirectory/normalDirectory"); - createDirectory("hiddenDirs_hiddenFiles/.hiddenDirectory/.hiddenDirectory"); + createDirectory("hiddenDirs_hiddenFiles/normalDirectory/subdir"); + createDirectory("hiddenDirs_hiddenFiles/normalDirectory/.hidden-subdir"); + createDirectory("hiddenDirs_hiddenFiles/.hiddenDirectory/subdir"); + createDirectory("hiddenDirs_hiddenFiles/.hiddenDirectory/.hidden-subdir"); #endif } @@ -427,7 +430,10 @@ public: class EngineWithNoIteratorHandler : public QAbstractFileEngineHandler { + Q_DISABLE_COPY_MOVE(EngineWithNoIteratorHandler) public: + EngineWithNoIteratorHandler() = default; + std::unique_ptr<QAbstractFileEngine> create(const QString &fileName) const override { return std::make_unique<EngineWithNoIterator>(fileName); @@ -446,7 +452,10 @@ void tst_QDirListing::engineWithNoIterator() class CustomEngineHandler : public QAbstractFileEngineHandler { + Q_DISABLE_COPY_MOVE(CustomEngineHandler) public: + CustomEngineHandler() = default; + std::unique_ptr<QAbstractFileEngine> create(const QString &fileName) const override { // We want to test QFSFileEngine specifically, so force QDirListing to use it @@ -565,40 +574,77 @@ void tst_QDirListing::uncPaths() // In Unix it is easy to create hidden files, but in Windows it requires // a special call since hidden files need to be "marked" while in Unix // anything starting by a '.' is a hidden file. -// For that reason this test is not run in Windows. -void tst_QDirListing::hiddenDirs_hiddenFiles() +// For that reason these two tests aren't run on Windows. + +void tst_QDirListing::hiddenFiles() { - // Only files - { - int matches = 0; - int failures = 0; - constexpr auto filters = QDir::Files | QDir::Hidden | QDir::NoDotAndDotDot; - for (const auto &dirEntry : QDirListing(u"hiddenDirs_hiddenFiles"_s, filters, - ItFlag::Recursive)) { - ++matches; - if (dirEntry.isDir()) - ++failures; // search was only supposed to find files - } - QCOMPARE(matches, 6); - QCOMPARE(failures, 0); + QStringList expected = { + "hiddenDirs_hiddenFiles/normalFile"_L1, + "hiddenDirs_hiddenFiles/.hiddenFile"_L1, + "hiddenDirs_hiddenFiles/normalDirectory/normalFile"_L1, + "hiddenDirs_hiddenFiles/normalDirectory/.hiddenFile"_L1, + "hiddenDirs_hiddenFiles/.hiddenDirectory/normalFile"_L1, + "hiddenDirs_hiddenFiles/.hiddenDirectory/.hiddenFile"_L1, + }; + expected.sort(); + + constexpr auto filters = QDir::Files | QDir::Hidden | QDir::NoDotAndDotDot; + QStringList list; + list.reserve(expected.size()); + for (const auto &dirEntry : QDirListing(u"hiddenDirs_hiddenFiles"_s, filters, + ItFlag::Recursive)) { + QVERIFY(dirEntry.isFile()); + list.emplace_back(dirEntry.filePath()); } - // Only directories - { - int matches = 0; - int failures = 0; - constexpr auto filters = QDir::Dirs | QDir::Hidden | QDir::NoDotAndDotDot; - for (const auto &dirEntry : QDirListing(u"hiddenDirs_hiddenFiles"_s, filters, - ItFlag::Recursive)) { - ++matches; - if (!dirEntry.isDir()) - ++failures; // search was only supposed to find files - } - QCOMPARE(matches, 6); - QCOMPARE(failures, 0); + + list.sort(); + + QCOMPARE_EQ(list, expected); +} + +void tst_QDirListing::hiddenDirs() +{ + QStringList expected = { + "hiddenDirs_hiddenFiles/normalDirectory"_L1, + "hiddenDirs_hiddenFiles/normalDirectory/subdir"_L1, + "hiddenDirs_hiddenFiles/normalDirectory/.hidden-subdir"_L1, + "hiddenDirs_hiddenFiles/.hiddenDirectory"_L1, + "hiddenDirs_hiddenFiles/.hiddenDirectory/subdir"_L1, + "hiddenDirs_hiddenFiles/.hiddenDirectory/.hidden-subdir"_L1, + }; + expected.sort(); + + constexpr auto filters = QDir::Dirs | QDir::Hidden | QDir::NoDotAndDotDot; + QStringList list; + list.reserve(expected.size()); + for (const auto &dirEntry : QDirListing(u"hiddenDirs_hiddenFiles"_s, filters, + ItFlag::Recursive)) { + QVERIFY(dirEntry.isDir()); + list.emplace_back(dirEntry.filePath()); } + list.sort(); + + QCOMPARE_EQ(list, expected); } + #endif // Q_OS_WIN +void tst_QDirListing::withStdAlgorithms() +{ + QDirListing dirList(u"entrylist"_s, QDir::AllEntries | QDir::NoDotAndDotDot, ItFlag::Recursive); + + std::for_each(dirList.cbegin(), dirList.cend(), [](const auto &dirEntry) { + QVERIFY(dirEntry.absoluteFilePath().contains("entrylist")); + }); + + const auto fileName = "dummy"_L1; + auto it = std::find_if(dirList.cbegin(), dirList.cend(), [fileName](const auto &dirEntry) { + return dirEntry.fileName() == fileName; + }); + QVERIFY(it != dirList.cend()); + QCOMPARE(it->fileName(), fileName); +} + QTEST_MAIN(tst_QDirListing) #include "tst_qdirlisting.moc" diff --git a/tests/auto/corelib/io/qfile/stdinprocess/main.cpp b/tests/auto/corelib/io/qfile/stdinprocess/main.cpp index dbcd00bb0a..0f92ba2670 100644 --- a/tests/auto/corelib/io/qfile/stdinprocess/main.cpp +++ b/tests/auto/corelib/io/qfile/stdinprocess/main.cpp @@ -16,13 +16,16 @@ int main(int argc, char *argv[]) QFile file; if (strcmp(argv[1], "all") == 0) { - file.open(stdin, QFile::ReadWrite); + if (!file.open(stdin, QFile::ReadWrite)) + return 1; printf("%s", file.readAll().constData()); } else if (strcmp(argv[1], "line") == 0) { if (strcmp(argv[2], "0") == 0) { - file.open(stdin, QFile::ReadWrite); + if (!file.open(stdin, QFile::ReadWrite)) + return 1; } else { - file.open(0, QFile::ReadWrite); + if (!file.open(0, QFile::ReadWrite)) + return 1; } char line[1024]; diff --git a/tests/auto/corelib/io/qfile/tst_qfile.cpp b/tests/auto/corelib/io/qfile/tst_qfile.cpp index e75fdade95..d69cc167d6 100644 --- a/tests/auto/corelib/io/qfile/tst_qfile.cpp +++ b/tests/auto/corelib/io/qfile/tst_qfile.cpp @@ -202,6 +202,7 @@ private slots: void flush(); void bufferedRead(); #ifdef Q_OS_UNIX + void isSequential_data(); void isSequential(); #endif void decodeName_data(); @@ -232,7 +233,7 @@ private slots: void virtualFile_data(); void virtualFile(); #endif -#ifdef Q_OS_UNIX +#if defined(Q_OS_UNIX) && !defined(Q_OS_WASM) void unixPipe_data(); void unixPipe(); void unixFifo_data() { unixPipe_data(); } @@ -645,7 +646,7 @@ void tst_QFile::open() QFETCH( bool, ok ); -#if defined(Q_OS_UNIX) && !defined(Q_OS_VXWORKS) +#if defined(Q_OS_UNIX) && !defined(Q_OS_VXWORKS) && !defined(Q_OS_WASM) if (::getuid() == 0) // root and Chuck Norris don't care for file permissions. Skip. QSKIP("Running this test as root doesn't make sense"); @@ -1219,6 +1220,11 @@ static inline QChar invalidDriveLetter() void tst_QFile::invalidFile_data() { QTest::addColumn<QString>("fileName"); + +#if defined(Q_OS_WASM) + QSKIP("No invalid files on wasm"); +#endif + #if !defined(Q_OS_WIN) QTest::newRow( "x11" ) << QString( "qwe//" ); #else @@ -1233,7 +1239,6 @@ void tst_QFile::invalidFile_data() QTest::newRow( "pipe" ) << QString( "fail|invalid" ); #endif } - void tst_QFile::invalidFile() { QFETCH( QString, fileName ); @@ -1376,7 +1381,10 @@ void tst_QFile::permissions_data() QTest::addColumn<bool>("expected"); QTest::addColumn<bool>("create"); +#ifndef Q_OS_WASM + // Application path is empty on wasm QTest::newRow("data0") << QCoreApplication::instance()->applicationFilePath() << uint(QFile::ExeUser) << true << false; +#endif QTest::newRow("data1") << m_testSourceFile << uint(QFile::ReadUser) << true << false; QTest::newRow("readonly") << QString::fromLatin1("readonlyfile") << uint(QFile::WriteUser) << false << false; QTest::newRow("longfile") << QString::fromLatin1("longFileNamelongFileNamelongFileNamelongFileName" @@ -1407,7 +1415,7 @@ void tst_QFile::permissions() QFile::Permissions staticResult = QFile::permissions(file) & perms; if (create) { - QFile::remove(file); + QVERIFY(QFile::remove(file)); } #if defined(Q_OS_WIN) @@ -1911,20 +1919,26 @@ void tst_QFile::bufferedRead() } #ifdef Q_OS_UNIX -void tst_QFile::isSequential() +void tst_QFile::isSequential_data() { - QFile zero("/dev/zero"); - QVERIFY2(zero.open(QFile::ReadOnly), msgOpenFailed(zero).constData()); - QVERIFY(zero.isSequential()); + QTest::addColumn<QString>("deviceName"); + QTest::addColumn<bool>("acceptFailOpen"); + + QTest::newRow("/dev/null") << QString("/dev/null") << false; + QTest::newRow("/dev/tty") << QString("/dev/tty") << true; + QTest::newRow("/dev/zero") << QString("/dev/zero") << false; +} - QFile null("/dev/null"); - QVERIFY(null.open(QFile::ReadOnly)); - QVERIFY(null.isSequential()); +void tst_QFile::isSequential() +{ + QFETCH(QString, deviceName); + QFETCH(bool, acceptFailOpen); - // /dev/tty will fail to open if we don't have a controlling TTY - QFile tty("/dev/tty"); - if (tty.open(QFile::ReadOnly)) - QVERIFY(tty.isSequential()); + if (access(deviceName.toUtf8().data(), R_OK) == 0) { + QFile device(deviceName); + QVERIFY2(device.open(QFile::ReadOnly) || acceptFailOpen, msgOpenFailed(device).constData()); + QVERIFY(!device.isOpen() || device.isSequential()); + } } #endif @@ -2320,7 +2334,9 @@ private: class MyHandler : public QAbstractFileEngineHandler { + Q_DISABLE_COPY_MOVE(MyHandler) public: + MyHandler() = default; std::unique_ptr<QAbstractFileEngine> create(const QString &) const override { return std::make_unique<MyEngine>(1); @@ -2329,7 +2345,10 @@ public: class MyHandler2 : public QAbstractFileEngineHandler { + Q_DISABLE_COPY_MOVE(MyHandler2) public: + MyHandler2() = default; + std::unique_ptr<QAbstractFileEngine> create(const QString &) const override { return std::make_unique<MyEngine>(2); @@ -2360,7 +2379,10 @@ void tst_QFile::fileEngineHandler() #ifdef QT_BUILD_INTERNAL class MyRecursiveHandler : public QAbstractFileEngineHandler { + Q_DISABLE_COPY_MOVE(MyRecursiveHandler) public: + MyRecursiveHandler() = default; + std::unique_ptr<QAbstractFileEngine> create(const QString &fileName) const override { if (fileName.startsWith(":!")) { @@ -2720,7 +2742,13 @@ void tst_QFile::virtualFile() } #endif // defined(Q_OS_LINUX) || defined(Q_OS_AIX) || defined(Q_OS_FREEBSD) || defined(Q_OS_NETBSD) -#ifdef Q_OS_UNIX +#if defined (Q_OS_UNIX) && !defined(Q_OS_WASM) +// wasm does not have working fifo +// https://github.com/nodejs/node/issues/38344 +// wasm does not have blocking pipe I/O +// https://github.com/emscripten-core/emscripten/issues/13214 +// wasm does not, by default, have socketpair +// https://emscripten.org/docs/porting/networking.html static void unixPipe_helper(int pipes[2]) { // start a thread and wait for it to write a first byte @@ -2839,7 +2867,7 @@ void tst_QFile::socketPair() qt_safe_close(pipes[1]); #endif } -#endif +#endif /* UNIX && !WASM; */ void tst_QFile::textFile() { @@ -3949,7 +3977,7 @@ void tst_QFile::moveToTrash_data() if (!temp.open()) QSKIP("Failed to create temporary file!"); QTest::newRow("temporary file") << temp.fileName() << true << true; -#ifdef Q_OS_UNIX +#if defined(Q_OS_UNIX) && !defined(Q_OS_WASM) if (QDir::tempPath() == "/tmp") QTest::newRow("var-temporary file") << "/var" + temp.fileName() << true << true; #endif @@ -3962,7 +3990,7 @@ void tst_QFile::moveToTrash_data() QTest::newRow("temporary dir") << tempDir.path() + QLatin1Char('/') << true << true; -#ifdef Q_OS_UNIX +#if defined(Q_OS_UNIX) && !defined(Q_OS_WASM) if (QDir::tempPath() == "/tmp") QTest::newRow("var-temporary dir") << "/var" + tempDir.path() << true << true; #endif diff --git a/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp b/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp index f7d531f61f..563e4c2a83 100644 --- a/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp +++ b/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp @@ -1217,9 +1217,16 @@ void tst_QFileInfo::setFileTimes() QCOMPARE(file.write(data), data.size()); QCOMPARE(file.size(), data.size()); - const QDateTime before = QDateTime::currentDateTimeUtc().addMSecs(-5000); + QDateTime before = QDateTime::currentDateTimeUtc().addMSecs(-5000); + QVERIFY(file.setFileTime(before, QFile::FileModificationTime)); const QDateTime mtime = file.fileTime(QFile::FileModificationTime).toUTC(); + if (mtime.time().msec() == 0) + { + const QTime beforeTime = before.time(); + const QTime beforeTimeWithMSCutOff{beforeTime.hour(), beforeTime.minute(), beforeTime.second(), 0}; + before.setTime(beforeTimeWithMSCutOff); + } QCOMPARE(mtime, before); } diff --git a/tests/auto/corelib/io/qfileselector/CMakeLists.txt b/tests/auto/corelib/io/qfileselector/CMakeLists.txt index 0fdff55cd5..c27c4f4f96 100644 --- a/tests/auto/corelib/io/qfileselector/CMakeLists.txt +++ b/tests/auto/corelib/io/qfileselector/CMakeLists.txt @@ -32,10 +32,14 @@ set(qfileselector_resource_files "platforms/+ios/test2" "platforms/+linux/test" "platforms/+linux/test2" + "platforms/+wasm/test" + "platforms/+wasm/test2" "platforms/+macos/test" "platforms/+macos/test2" "platforms/+qnx/test" "platforms/+qnx/test2" + "platforms/+unix/+emscripten/+wasm/test" + "platforms/+unix/+emscripten/test" "platforms/+unix/+android/test" "platforms/+unix/+darwin/+ios/test" "platforms/+unix/+darwin/+macos/test" diff --git a/tests/auto/corelib/io/qfileselector/platforms/+unix/+emscripten/+wasm/test b/tests/auto/corelib/io/qfileselector/platforms/+unix/+emscripten/+wasm/test new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/auto/corelib/io/qfileselector/platforms/+unix/+emscripten/+wasm/test diff --git a/tests/auto/corelib/io/qfileselector/platforms/+unix/+emscripten/test b/tests/auto/corelib/io/qfileselector/platforms/+unix/+emscripten/test new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/auto/corelib/io/qfileselector/platforms/+unix/+emscripten/test diff --git a/tests/auto/corelib/io/qfileselector/platforms/+wasm/test b/tests/auto/corelib/io/qfileselector/platforms/+wasm/test new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/auto/corelib/io/qfileselector/platforms/+wasm/test diff --git a/tests/auto/corelib/io/qfileselector/platforms/+wasm/test2 b/tests/auto/corelib/io/qfileselector/platforms/+wasm/test2 new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/auto/corelib/io/qfileselector/platforms/+wasm/test2 diff --git a/tests/auto/corelib/io/qfileselector/tst_qfileselector.cpp b/tests/auto/corelib/io/qfileselector/tst_qfileselector.cpp index 7c038e9913..626166c8b8 100644 --- a/tests/auto/corelib/io/qfileselector/tst_qfileselector.cpp +++ b/tests/auto/corelib/io/qfileselector/tst_qfileselector.cpp @@ -60,7 +60,7 @@ void tst_QFileSelector::basicTest_data() QString expectedPlatform1File(":/platforms"); QString expectedPlatform2File(""); //Only the last selector QString expectedPlatform3File; // Only the first selector (the family) -#if defined(Q_OS_UNIX) && !defined(Q_OS_ANDROID) && \ +#if defined(Q_OS_UNIX) && !defined(Q_OS_ANDROID) && !defined(Q_OS_WASM) && \ !defined(Q_OS_DARWIN) && !defined(Q_OS_LINUX) && !defined(Q_OS_HAIKU) && !defined(Q_OS_QNX) /* We are only aware of specific unixes, and do not have test files for any of the others. However those unixes can get a selector added from the result of a uname call, so this will diff --git a/tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp b/tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp index a5b0087f9c..184eef3f15 100644 --- a/tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp +++ b/tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp @@ -26,14 +26,18 @@ using namespace std::chrono_literals; #if defined(Q_OS_QNX) -// Longer polling times on QNX, otherwise the tests fail on the CI +constexpr bool isQNX = true; +#else +constexpr bool isQNX = false; +#endif + +#if defined(Q_OS_QNX) || defined(Q_OS_VXWORKS) +// Longer polling times on QNX and VxWorks, otherwise the tests fail on the CI constexpr auto nativeEngineTimeout = 1s; constexpr auto pollingEngineTimeout = 1s; -constexpr bool isQNX = true; #else constexpr auto nativeEngineTimeout = 0ms; constexpr auto pollingEngineTimeout = 20ms; -constexpr bool isQNX = false; #endif /* All tests need to run in temporary directories not used diff --git a/tests/auto/corelib/io/qfloat16format/CMakeLists.txt b/tests/auto/corelib/io/qfloat16format/CMakeLists.txt new file mode 100644 index 0000000000..0980007f69 --- /dev/null +++ b/tests/auto/corelib/io/qfloat16format/CMakeLists.txt @@ -0,0 +1,21 @@ +# Copyright (C) 2024 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qfloat16format LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + +set(CMAKE_OSX_DEPLOYMENT_TARGET 13.3) + +qt_internal_add_test(tst_qfloat16format + SOURCES + tst_qfloat16format.cpp +) + +set_target_properties(tst_qfloat16format + PROPERTIES + CXX_STANDARD 20 + CXX_STANDARD_REQUIRED OFF +) diff --git a/tests/auto/corelib/io/qfloat16format/tst_qfloat16format.cpp b/tests/auto/corelib/io/qfloat16format/tst_qfloat16format.cpp new file mode 100644 index 0000000000..63a27d55f6 --- /dev/null +++ b/tests/auto/corelib/io/qfloat16format/tst_qfloat16format.cpp @@ -0,0 +1,168 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#include <QTest> + +#include <QtCore/qcompilerdetection.h> +#include <QtCore/qdebug.h> +#include <QtCore/qfloat16format.h> +#include <QtCore/qstring.h> + +using namespace Qt::StringLiterals; + +class tst_QFloat16Format : public QObject +{ + Q_OBJECT + +private slots: + void initTestCase(); + void formatCompileTime(); + void format_data(); + void format(); + void formatMultiArg(); +}; + +void tst_QFloat16Format::initTestCase() +{ +#ifndef QT_SUPPORTS_STD_FORMAT + QSKIP("This test requires std::format support!"); +#endif +} + +void tst_QFloat16Format::formatCompileTime() +{ +#ifdef QT_SUPPORTS_STD_FORMAT + // Starting from __cpp_lib_format == 202106L, + // std::format requires the format string to be evaluated at compile-time, + // so check it here. + + const qfloat16 val{1.234f}; + std::locale loc{"C"}; + + // char + std::string buffer; + std::format_to(std::back_inserter(buffer), "{}", val); + std::format_to(std::back_inserter(buffer), "{:*>15.7f}", val); + std::format_to(std::back_inserter(buffer), "{:*^+#15.7g}", val); + std::format_to(std::back_inserter(buffer), "{:*<-#15.7A}", val); + std::format_to(std::back_inserter(buffer), "{:*^ 15.7e}", val); + std::format_to(std::back_inserter(buffer), loc, "{:*^10.3Lf}", val); + std::format_to(std::back_inserter(buffer), loc, "{:*< 10.7LE}", val); + + // wchar_t + std::wstring wbuffer; + std::format_to(std::back_inserter(wbuffer), L"{}", val); + std::format_to(std::back_inserter(wbuffer), L"{:*>15.7f}", val); + std::format_to(std::back_inserter(wbuffer), L"{:*^+#15.7g}", val); + std::format_to(std::back_inserter(wbuffer), L"{:*<-#15.7A}", val); + std::format_to(std::back_inserter(wbuffer), L"{:*^ 15.7e}", val); + std::format_to(std::back_inserter(wbuffer), loc, L"{:*^10.3Lf}", val); + std::format_to(std::back_inserter(wbuffer), loc, L"{:*< 10.7LE}", val); +#endif // QT_SUPPORTS_STD_FORMAT +} + +void tst_QFloat16Format::format_data() +{ + QTest::addColumn<QString>("format"); + QTest::addColumn<qfloat16>("value"); + QTest::addColumn<QByteArray>("locName"); + QTest::addColumn<QString>("expectedString"); + + auto row = [](const QString &format, qfloat16 val, const QString &expected, + const QByteArray &loc = QByteArray()) + { + QString str; + QDebug dbg(&str); + dbg.nospace().noquote() << format; + if (!loc.isEmpty()) + dbg.nospace().noquote() << "_" << loc; + + QTest::newRow(qPrintable(str)) << format << val << loc << expected; + }; + + QByteArray loc; +#if defined(Q_CC_MSVC_ONLY) + loc = "de-DE"_ba; +#elif !defined(Q_CC_MINGW) // minGW has only C and POSIX locales + loc = "de_DE"_ba; +#endif + + row(u"{}"_s, qfloat16(1.f), u"1"_s); + row(u"{:#}"_s, qfloat16(1.f), u"1."_s); + row(u"{:f}"_s, qfloat16(1.f), u"1.000000"_s); + row(u"{:*>10.2a}"_s, qfloat16(-1.23f), u"**-1.3bp+0"_s); + if (!loc.isEmpty()) { + row(u"{:+Lf}"_s, qfloat16(1.f), u"+1,000000"_s, loc); + row(u"{:*^10.3LF}"_s, qfloat16(-0.1234f), u"**-0,123**"_s, loc); + row(u"{:*^#10.4Lg}"_s, qfloat16(-1.f), u"**-1,000**"_s, loc); + row(u"{:*<14.3LE}"_s, qfloat16(-0.1234f), u"-1,234E-01****"_s, loc); + } +} + +void tst_QFloat16Format::format() +{ +#ifdef QT_SUPPORTS_STD_FORMAT + QFETCH(const QString, format); + QFETCH(const qfloat16, value); + QFETCH(const QByteArray, locName); + QFETCH(const QString, expectedString); + + // char + { + std::string buffer; + const auto formatStr = format.toStdString(); + if (!locName.isEmpty()) { + std::locale loc(locName.constData()); + std::vformat_to(std::back_inserter(buffer), loc, formatStr, + std::make_format_args(value)); + } else { + std::vformat_to(std::back_inserter(buffer), formatStr, + std::make_format_args(value)); + } + const QString actualString = QString::fromStdString(buffer); + QCOMPARE_EQ(actualString, expectedString); + } + + // wchar_t + { + std::wstring buffer; + const auto formatStr = format.toStdWString(); + if (!locName.isEmpty()) { + std::locale loc(locName.constData()); + std::vformat_to(std::back_inserter(buffer), loc, formatStr, + std::make_wformat_args(value)); + } else { + std::vformat_to(std::back_inserter(buffer), formatStr, + std::make_wformat_args(value)); + } + const QString actualString = QString::fromStdWString(buffer); + QCOMPARE_EQ(actualString, expectedString); + } +#endif // QT_SUPPORTS_STD_FORMAT +} + +void tst_QFloat16Format::formatMultiArg() +{ +#ifdef QT_SUPPORTS_STD_FORMAT + const qfloat16 v1{-0.1234f}; + const qfloat16 v2{5.67f}; + + const QString expectedString = u"**+5.67**_*****-1.234E-01"_s; + // char + { + std::string buffer; + std::format_to(std::back_inserter(buffer), "{1:*^+9.2f}_{0:*>15.3E}", v1, v2); + QCOMPARE_EQ(QString::fromStdString(buffer), expectedString); + } + + // wchar_t + { + std::wstring buffer; + std::format_to(std::back_inserter(buffer), L"{1:*^+9.2f}_{0:*>15.3E}", v1, v2); + QCOMPARE_EQ(QString::fromStdWString(buffer), expectedString); + } +#endif // QT_SUPPORTS_STD_FORMAT +} + +QTEST_MAIN(tst_QFloat16Format) +#include "tst_qfloat16format.moc" diff --git a/tests/auto/corelib/io/qprocess/crasher.h b/tests/auto/corelib/io/qprocess/crasher.h index 7d55bf980f..f1ca82a86b 100644 --- a/tests/auto/corelib/io/qprocess/crasher.h +++ b/tests/auto/corelib/io/qprocess/crasher.h @@ -45,6 +45,8 @@ void crash() { #if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64)) __ud2(); +#elif defined(_MSC_VER) && defined(_M_ARM64) + __debugbreak(); #elif __has_builtin(__builtin_trap) __builtin_trap(); #elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) diff --git a/tests/auto/corelib/io/qprocess/fileWriterProcess/main.cpp b/tests/auto/corelib/io/qprocess/fileWriterProcess/main.cpp index 43b3f77188..0349a48067 100644 --- a/tests/auto/corelib/io/qprocess/fileWriterProcess/main.cpp +++ b/tests/auto/corelib/io/qprocess/fileWriterProcess/main.cpp @@ -9,7 +9,8 @@ int main(int argc, char **argv) { QCoreApplication ca(argc, argv); QFile f; - f.open(stdin, QIODevice::ReadOnly); + if (!f.open(stdin, QIODevice::ReadOnly)) + return 1; QByteArray input; char buf[1024]; qint64 len; diff --git a/tests/auto/corelib/io/qprocess/testBatFiles/simple.bat b/tests/auto/corelib/io/qprocess/testBatFiles/simple.bat index 900f7ae356..8567e16850 100755 --- a/tests/auto/corelib/io/qprocess/testBatFiles/simple.bat +++ b/tests/auto/corelib/io/qprocess/testBatFiles/simple.bat @@ -1,2 +1,4 @@ +:: Copyright (C) 2024 The Qt Company Ltd. +:: SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 @echo off -echo Hello
\ No newline at end of file +echo Hello diff --git a/tests/auto/corelib/io/qprocess/testBatFiles/with space.bat b/tests/auto/corelib/io/qprocess/testBatFiles/with space.bat index 900f7ae356..8567e16850 100755 --- a/tests/auto/corelib/io/qprocess/testBatFiles/with space.bat +++ b/tests/auto/corelib/io/qprocess/testBatFiles/with space.bat @@ -1,2 +1,4 @@ +:: Copyright (C) 2024 The Qt Company Ltd. +:: SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 @echo off -echo Hello
\ No newline at end of file +echo Hello diff --git a/tests/auto/corelib/io/qprocess/tst_qprocess.cpp b/tests/auto/corelib/io/qprocess/tst_qprocess.cpp index 1056eaa107..5f35732979 100644 --- a/tests/auto/corelib/io/qprocess/tst_qprocess.cpp +++ b/tests/auto/corelib/io/qprocess/tst_qprocess.cpp @@ -48,6 +48,7 @@ private slots: void constructing(); void simpleStart(); void startCommand(); + void startCommandEmptyString(); void startWithOpen(); void startWithOldOpen(); void execute(); @@ -299,6 +300,25 @@ void tst_QProcess::startCommand() QCOMPARE(actual, expected); } +void tst_QProcess::startCommandEmptyString() +{ + static const char warningMsg[] = + "QProcess::startCommand: empty or whitespace-only command was provided"; + QProcess process; + + QTest::ignoreMessage(QtWarningMsg, warningMsg); + process.startCommand(""); + QVERIFY(!process.waitForStarted()); + + QTest::ignoreMessage(QtWarningMsg, warningMsg); + process.startCommand(" "); + QVERIFY(!process.waitForStarted()); + + QTest::ignoreMessage(QtWarningMsg, warningMsg); + process.startCommand("\t\n"); + QVERIFY(!process.waitForStarted()); +} + void tst_QProcess::startWithOpen() { QProcess p; diff --git a/tests/auto/corelib/io/qprocessenvironment/tst_qprocessenvironment.cpp b/tests/auto/corelib/io/qprocessenvironment/tst_qprocessenvironment.cpp index 6a2a3daaa2..560d4196b2 100644 --- a/tests/auto/corelib/io/qprocessenvironment/tst_qprocessenvironment.cpp +++ b/tests/auto/corelib/io/qprocessenvironment/tst_qprocessenvironment.cpp @@ -257,6 +257,9 @@ void tst_QProcessEnvironment::caseSensitivity() void tst_QProcessEnvironment::systemEnvironment() { +#ifdef Q_OS_VXWORKS + QSKIP("VxWorks do not have PATH environment variable"); +#endif static const char envname[] = "THIS_ENVIRONMENT_VARIABLE_HOPEFULLY_DOESNT_EXIST"; QByteArray path = qgetenv("PATH"); QByteArray nonexistant = qgetenv(envname); diff --git a/tests/auto/corelib/io/qresourceengine/generateResources.sh b/tests/auto/corelib/io/qresourceengine/generateResources.sh index 9894f6bfb7..ab05f1c35a 100755 --- a/tests/auto/corelib/io/qresourceengine/generateResources.sh +++ b/tests/auto/corelib/io/qresourceengine/generateResources.sh @@ -1,4 +1,6 @@ #!/bin/sh +# Copyright (C) 2016 Intel Corporation. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 count=`awk '/ZERO_FILE_LEN/ { print $3 }' tst_qresourceengine.cpp` dd if=/dev/zero of=zero.txt bs=1 count=$count rcc --binary -o uncompressed.rcc --no-compress compressed.qrc diff --git a/tests/auto/corelib/io/qresourceengine/staticplugin/main.cpp b/tests/auto/corelib/io/qresourceengine/staticplugin/main.cpp index 39a3a1e012..c7b0fe7ea1 100644 --- a/tests/auto/corelib/io/qresourceengine/staticplugin/main.cpp +++ b/tests/auto/corelib/io/qresourceengine/staticplugin/main.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QObject> class PluginClass : public QObject diff --git a/tests/auto/corelib/io/qresourceengine/testqrc/test.qrc b/tests/auto/corelib/io/qresourceengine/testqrc/test.qrc index f5e8c849a6..56972ea764 100644 --- a/tests/auto/corelib/io/qresourceengine/testqrc/test.qrc +++ b/tests/auto/corelib/io/qresourceengine/testqrc/test.qrc @@ -9,10 +9,10 @@ <file>searchpath1/search_file.txt</file>
<file>searchpath2/search_file.txt</file>
<file>search_file.txt</file>
- </qresource>
- <qresource><file>test/testdir.txt</file>
+ <file>test/testdir.txt</file>
<file>otherdir/otherdir.txt</file>
<file alias="aliasdir/aliasdir.txt">test/testdir2.txt</file>
+ <file alias="uncompresseddir/uncompressed.txt" compression-algorithm="none">aliasdir/compressme.txt</file>
<file>test/test</file>
</qresource>
<qresource lang="ko">
@@ -21,7 +21,7 @@ <qresource lang="de_CH">
<file alias="aliasdir/aliasdir.txt" compress="9" threshold="30">aliasdir/compressme.txt</file>
</qresource>
- <qresource lang="de">
+ <qresource lang="de" compression-algorithm="none">
<file alias="aliasdir/aliasdir.txt">test/german.txt</file>
</qresource>
<qresource prefix="withoutslashes">
diff --git a/tests/auto/corelib/io/qresourceengine/tst_qresourceengine.cpp b/tests/auto/corelib/io/qresourceengine/tst_qresourceengine.cpp index fc9b9ee201..00a8cc4d72 100644 --- a/tests/auto/corelib/io/qresourceengine/tst_qresourceengine.cpp +++ b/tests/auto/corelib/io/qresourceengine/tst_qresourceengine.cpp @@ -45,6 +45,7 @@ private slots: private: const QString m_runtimeResourceRcc; + QByteArray m_runtimeResourceData; }; @@ -73,15 +74,27 @@ void tst_QResourceEngine::initTestCase() #endif QVERIFY(!m_runtimeResourceRcc.isEmpty()); + + QFile resourceFile(m_runtimeResourceRcc); + QVERIFY2(resourceFile.open(QIODevice::ReadOnly), qPrintable(resourceFile.errorString())); + + // register once with the file name, which will attempt to use mmap() + // (uses QDynamicFileResourceRoot) QVERIFY(QResource::registerResource(m_runtimeResourceRcc)); - QVERIFY(QResource::registerResource(m_runtimeResourceRcc, "/secondary_root/")); + + // and register a second time with a gifted memory block + // (uses QDynamicBufferResourceRoot) + m_runtimeResourceData = resourceFile.readAll(); + auto resourcePtr = reinterpret_cast<const uchar *>(m_runtimeResourceData.constData()); + QVERIFY(QResource::registerResource(resourcePtr, "/secondary_root/")); } void tst_QResourceEngine::cleanupTestCase() { // make sure we don't leak memory QVERIFY(QResource::unregisterResource(m_runtimeResourceRcc)); - QVERIFY(QResource::unregisterResource(m_runtimeResourceRcc, "/secondary_root/")); + auto resourcePtr = reinterpret_cast<const uchar *>(m_runtimeResourceData.constData()); + QVERIFY(QResource::unregisterResource(resourcePtr, "/secondary_root/")); } void tst_QResourceEngine::compressedResource_data() @@ -180,6 +193,7 @@ void tst_QResourceEngine::checkStructure_data() #if defined(BUILTIN_TESTDATA) << QLatin1String("testqrc") #endif + << QLatin1String("uncompresseddir") << QLatin1String("withoutslashes"); QTest::newRow("root dir") << QString(":/") @@ -187,7 +201,6 @@ void tst_QResourceEngine::checkStructure_data() << (QStringList() #if defined(BUILTIN_TESTDATA) << "parentdir.txt" - << "runtime_resource.rcc" #endif << "search_file.txt" #if defined(BUILTIN_TESTDATA) @@ -212,56 +225,56 @@ void tst_QResourceEngine::checkStructure_data() for(int i = 0; i < roots.size(); ++i) { const QString root = roots.at(i); - QTest::addRow("%s prefix dir", qPrintable(root)) << QString(root + "test/abc/123/+++") + QTest::addRow("prefix dir on %s", qPrintable(root)) << QString(root + "test/abc/123/+++") << QByteArray() << (QStringList() << QLatin1String("currentdir.txt") << QLatin1String("currentdir2.txt") << QLatin1String("parentdir.txt")) << (QStringList() << QLatin1String("subdir")) << QLocale::c() << qlonglong(0); - QTest::addRow("%s parent to prefix", qPrintable(root)) << QString(root + "test/abc/123") + QTest::addRow("parent to prefix on %s", qPrintable(root)) << QString(root + "test/abc/123") << QByteArray() << QStringList() << (QStringList() << QLatin1String("+++")) << QLocale::c() << qlonglong(0); - QTest::addRow("%s two parents prefix", qPrintable(root)) << QString(root + "test/abc") + QTest::addRow("two parents prefix on %s", qPrintable(root)) << QString(root + "test/abc") << QByteArray() << QStringList() << QStringList(QLatin1String("123")) << QLocale::c() << qlonglong(0); - QTest::addRow("%s test dir ", qPrintable(root)) << QString(root + "test") + QTest::addRow("test dir on %s", qPrintable(root)) << QString(root + "test") << QByteArray() << (QStringList() << QLatin1String("testdir.txt")) << (QStringList() << QLatin1String("abc") << QLatin1String("test")) << QLocale::c() << qlonglong(0); - QTest::addRow("%s prefix no slashes", qPrintable(root)) << QString(root + "withoutslashes") + QTest::addRow("prefix no slashes on %s", qPrintable(root)) << QString(root + "withoutslashes") << QByteArray() << QStringList("blahblah.txt") << QStringList() << QLocale::c() << qlonglong(0); - QTest::addRow("%s other dir", qPrintable(root)) << QString(root + "otherdir") + QTest::addRow("other dir on %s", qPrintable(root)) << QString(root + "otherdir") << QByteArray() << QStringList(QLatin1String("otherdir.txt")) << QStringList() << QLocale::c() << qlonglong(0); - QTest::addRow("%s alias dir", qPrintable(root)) << QString(root + "aliasdir") + QTest::addRow("alias dir on %s", qPrintable(root)) << QString(root + "aliasdir") << QByteArray() << QStringList(QLatin1String("aliasdir.txt")) << QStringList() << QLocale::c() << qlonglong(0); - QTest::addRow("%s second test dir", qPrintable(root)) << QString(root + "test/test") + QTest::addRow("second test dir on %s", qPrintable(root)) << QString(root + "test/test") << QByteArray() << (QStringList() << QLatin1String("test1.txt") << QLatin1String("test2.txt")) << QStringList() @@ -269,7 +282,7 @@ void tst_QResourceEngine::checkStructure_data() << qlonglong(0); info = QFileInfo(QFINDTESTDATA("testqrc/test/test/test1.txt")); - QTest::addRow("%s test1 text", qPrintable(root)) << QString(root + "test/test/test1.txt") + QTest::addRow("test1 text on %s", qPrintable(root)) << QString(root + "test/test/test1.txt") << QByteArray("abc\n") << QStringList() << QStringList() @@ -277,7 +290,7 @@ void tst_QResourceEngine::checkStructure_data() << qlonglong(info.size()); info = QFileInfo(QFINDTESTDATA("testqrc/blahblah.txt")); - QTest::addRow("%s text no slashes", qPrintable(root)) << QString(root + "withoutslashes/blahblah.txt") + QTest::addRow("text no slashes on %s", qPrintable(root)) << QString(root + "withoutslashes/blahblah.txt") << QByteArray("qwerty\n") << QStringList() << QStringList() @@ -286,7 +299,7 @@ void tst_QResourceEngine::checkStructure_data() info = QFileInfo(QFINDTESTDATA("testqrc/test/test/test2.txt")); - QTest::addRow("%s test2 text", qPrintable(root)) << QString(root + "test/test/test2.txt") + QTest::addRow("test2 text on %s", qPrintable(root)) << QString(root + "test/test/test2.txt") << QByteArray("def\n") << QStringList() << QStringList() @@ -294,7 +307,7 @@ void tst_QResourceEngine::checkStructure_data() << qlonglong(info.size()); info = QFileInfo(QFINDTESTDATA("testqrc/currentdir.txt")); - QTest::addRow("%s currentdir text", qPrintable(root)) << QString(root + "test/abc/123/+++/currentdir.txt") + QTest::addRow("currentdir text on %s", qPrintable(root)) << QString(root + "test/abc/123/+++/currentdir.txt") << QByteArray("\"This is the current dir\"\n") << QStringList() << QStringList() @@ -302,7 +315,7 @@ void tst_QResourceEngine::checkStructure_data() << qlonglong(info.size()); info = QFileInfo(QFINDTESTDATA("testqrc/currentdir2.txt")); - QTest::addRow("%s currentdir text2", qPrintable(root)) << QString(root + "test/abc/123/+++/currentdir2.txt") + QTest::addRow("currentdir text2 on %s", qPrintable(root)) << QString(root + "test/abc/123/+++/currentdir2.txt") << QByteArray("\"This is also the current dir\"\n") << QStringList() << QStringList() @@ -310,7 +323,7 @@ void tst_QResourceEngine::checkStructure_data() << qlonglong(info.size()); info = QFileInfo(QFINDTESTDATA("parentdir.txt")); - QTest::addRow("%s parentdir text", qPrintable(root)) << QString(root + "test/abc/123/+++/parentdir.txt") + QTest::addRow("parentdir text on %s", qPrintable(root)) << QString(root + "test/abc/123/+++/parentdir.txt") << QByteArray("abcdefgihklmnopqrstuvwxyz \n") << QStringList() << QStringList() @@ -318,7 +331,7 @@ void tst_QResourceEngine::checkStructure_data() << qlonglong(info.size()); info = QFileInfo(QFINDTESTDATA("testqrc/subdir/subdir.txt")); - QTest::addRow("%s subdir text", qPrintable(root)) << QString(root + "test/abc/123/+++/subdir/subdir.txt") + QTest::addRow("subdir text on %s", qPrintable(root)) << QString(root + "test/abc/123/+++/subdir/subdir.txt") << QByteArray("\"This is in the sub directory\"\n") << QStringList() << QStringList() @@ -326,7 +339,7 @@ void tst_QResourceEngine::checkStructure_data() << qlonglong(info.size()); info = QFileInfo(QFINDTESTDATA("testqrc/test/testdir.txt")); - QTest::addRow("%s testdir text", qPrintable(root)) << QString(root + "test/testdir.txt") + QTest::addRow("testdir text on %s", qPrintable(root)) << QString(root + "test/testdir.txt") << QByteArray("\"This is in the test directory\"\n") << QStringList() << QStringList() @@ -334,7 +347,7 @@ void tst_QResourceEngine::checkStructure_data() << qlonglong(info.size()); info = QFileInfo(QFINDTESTDATA("testqrc/otherdir/otherdir.txt")); - QTest::addRow("%s otherdir text", qPrintable(root)) << QString(root + "otherdir/otherdir.txt") + QTest::addRow("otherdir text on %s", qPrintable(root)) << QString(root + "otherdir/otherdir.txt") << QByteArray("\"This is the other dir\"\n") << QStringList() << QStringList() @@ -342,7 +355,7 @@ void tst_QResourceEngine::checkStructure_data() << qlonglong(info.size()); info = QFileInfo(QFINDTESTDATA("testqrc/test/testdir2.txt")); - QTest::addRow("%s alias text", qPrintable(root)) << QString(root + "aliasdir/aliasdir.txt") + QTest::addRow("alias text on %s", qPrintable(root)) << QString(root + "aliasdir/aliasdir.txt") << QByteArray("\"This is another file in this directory\"\n") << QStringList() << QStringList() @@ -350,7 +363,7 @@ void tst_QResourceEngine::checkStructure_data() << qlonglong(info.size()); info = QFileInfo(QFINDTESTDATA("testqrc/aliasdir/aliasdir.txt")); - QTest::addRow("%s korean text", qPrintable(root)) << QString(root + "aliasdir/aliasdir.txt") + QTest::addRow("korean text on %s", qPrintable(root)) << QString(root + "aliasdir/aliasdir.txt") << QByteArray("\"This is a korean text file\"\n") << QStringList() << QStringList() @@ -358,7 +371,7 @@ void tst_QResourceEngine::checkStructure_data() << qlonglong(info.size()); info = QFileInfo(QFINDTESTDATA("testqrc/aliasdir/aliasdir.txt")); - QTest::addRow("%s korean text 2", qPrintable(root)) << QString(root + "aliasdir/aliasdir.txt") + QTest::addRow("korean text 2 on %s", qPrintable(root)) << QString(root + "aliasdir/aliasdir.txt") << QByteArray("\"This is a korean text file\"\n") << QStringList() << QStringList() @@ -366,7 +379,7 @@ void tst_QResourceEngine::checkStructure_data() << qlonglong(info.size()); info = QFileInfo(QFINDTESTDATA("testqrc/test/german.txt")); - QTest::addRow("%s german text", qPrintable(root)) << QString(root + "aliasdir/aliasdir.txt") + QTest::addRow("german text on %s", qPrintable(root)) << QString(root + "aliasdir/aliasdir.txt") << QByteArray("Deutsch\n") << QStringList() << QStringList() @@ -374,7 +387,7 @@ void tst_QResourceEngine::checkStructure_data() << qlonglong(info.size()); info = QFileInfo(QFINDTESTDATA("testqrc/test/german.txt")); - QTest::addRow("%s german text 2", qPrintable(root)) << QString(root + "aliasdir/aliasdir.txt") + QTest::addRow("german text 2 on %s", qPrintable(root)) << QString(root + "aliasdir/aliasdir.txt") << QByteArray("Deutsch\n") << QStringList() << QStringList() @@ -384,8 +397,16 @@ void tst_QResourceEngine::checkStructure_data() QFile file(QFINDTESTDATA("testqrc/aliasdir/compressme.txt")); QVERIFY(file.open(QFile::ReadOnly)); info = QFileInfo(QFINDTESTDATA("testqrc/aliasdir/compressme.txt")); - QTest::addRow("%s compressed text", qPrintable(root)) << QString(root + "aliasdir/aliasdir.txt") - << file.readAll() + QByteArray compressmeContents = file.readAll(); + QTest::addRow("compressed text on %s", qPrintable(root)) << QString(root + "aliasdir/aliasdir.txt") + << compressmeContents + << QStringList() + << QStringList() + << QLocale("de_CH") + << qlonglong(info.size()); + + QTest::addRow("non-compressed text on %s", qPrintable(root)) << QString(root + "uncompresseddir/uncompressed.txt") + << compressmeContents << QStringList() << QStringList() << QLocale("de_CH") @@ -463,6 +484,18 @@ void tst_QResourceEngine::checkStructure() // check that it is still valid after closing the file file.close(); QCOMPARE(ba, contents); + + // memory should be writable because we used MapPrivateOption + *ptr = '\0'; + + // but shouldn't affect the actual file or a new mapping + QFile file2(pathName); + QVERIFY(file2.open(QFile::ReadOnly)); + QCOMPARE(file2.readAll(), contents); + ptr = file2.map(0, file.size(), QFile::MapPrivateOption); + QVERIFY2(ptr, qPrintable(file2.errorString())); + QByteArrayView bav(reinterpret_cast<const char *>(ptr), file.size()); + QCOMPARE(bav, contents); } QLocale::setDefault(QLocale::system()); } diff --git a/tests/auto/corelib/io/qsavefile/tst_qsavefile.cpp b/tests/auto/corelib/io/qsavefile/tst_qsavefile.cpp index fbb6a29f26..c027f8a3c1 100644 --- a/tests/auto/corelib/io/qsavefile/tst_qsavefile.cpp +++ b/tests/auto/corelib/io/qsavefile/tst_qsavefile.cpp @@ -5,6 +5,7 @@ #include <QSaveFile> #include <qcoreapplication.h> #include <qstring.h> +#include <qsystemdetection.h> #include <qtemporaryfile.h> #include <qfile.h> #include <qdir.h> @@ -89,17 +90,34 @@ void tst_QSaveFile::transactionalWrite() QCOMPARE(file.fileName(), targetFile); QVERIFY(!QFile::exists(targetFile)); - QCOMPARE(file.write("Hello"), Q_INT64_C(5)); + const char *data = "Hello"; + QCOMPARE(file.write(data), qint64(strlen(data))); QCOMPARE(file.error(), QFile::NoError); QVERIFY(!QFile::exists(targetFile)); + QVERIFY(file.fileTime(QFile::FileModificationTime).isValid()); QVERIFY(file.commit()); QVERIFY(QFile::exists(targetFile)); QCOMPARE(file.fileName(), targetFile); +#if defined(Q_OS_WIN) + // Without this delay, file.fileTime() and file.size() tests fail to + // pass on Windows in the CI. It passes locally in a VM, so it looks like + // it depends on how often different filesystems on different OSes, update + // their metadata. + // Interestingly, this delay is enough to fix similar tests in the rest + // of tst_QSaveFile's functions. + QTRY_VERIFY(file.fileTime(QFile::FileModificationTime).isValid()); +#else + QVERIFY(file.fileTime(QFile::FileModificationTime).isValid()); +#endif + + QCOMPARE(file.size(), qint64(strlen(data))); QFile reader(targetFile); QVERIFY(reader.open(QIODevice::ReadOnly)); - QCOMPARE(QString::fromLatin1(reader.readAll()), QString::fromLatin1("Hello")); + QCOMPARE(QString::fromLatin1(reader.readAll()), QString::fromLatin1(data)); + QCOMPARE(file.fileTime(QFile::FileModificationTime), + reader.fileTime(QFile::FileModificationTime)); // check that permissions are the same as for QFile const QString otherFile = dir.path() + QString::fromLatin1("/otherfile"); @@ -124,12 +142,13 @@ void tst_QSaveFile::retryTransactionalWrite() QTemporaryDir dir; QVERIFY2(dir.isValid(), qPrintable(dir.errorString())); + const char *data = "Hello"; QString targetFile = dir.path() + QLatin1String("/outfile"); const QString readOnlyName = targetFile + QLatin1String(".ro"); { QFile readOnlyFile(readOnlyName); QVERIFY2(readOnlyFile.open(QIODevice::WriteOnly), msgCannotOpen(readOnlyFile).constData()); - readOnlyFile.write("Hello"); + readOnlyFile.write(data); readOnlyFile.close(); auto permissions = readOnlyFile.permissions(); permissions &= ~(QFileDevice::WriteOwner | QFileDevice::WriteGroup | QFileDevice::WriteUser); @@ -142,13 +161,15 @@ void tst_QSaveFile::retryTransactionalWrite() file.setFileName(targetFile); QVERIFY2(file.open(QIODevice::WriteOnly), msgCannotOpen(file).constData()); QVERIFY(file.isOpen()); - QCOMPARE(file.write("Hello"), Q_INT64_C(5)); + QCOMPARE(file.write(data), qint64(strlen(data))); QCOMPARE(file.error(), QFile::NoError); QVERIFY(file.commit()); + QCOMPARE(file.size(), qint64(strlen(data))); } void tst_QSaveFile::saveTwice() { + const char *hello = "Hello"; // Check that we can reuse a QSaveFile object // (and test the case of an existing target file) QTemporaryDir dir; @@ -156,16 +177,19 @@ void tst_QSaveFile::saveTwice() const QString targetFile = dir.path() + QString::fromLatin1("/outfile"); QSaveFile file(targetFile); QVERIFY2(file.open(QIODevice::WriteOnly), msgCannotOpen(file).constData()); - QCOMPARE(file.write("Hello"), Q_INT64_C(5)); + QCOMPARE(file.write(hello), qint64(strlen(hello))); QVERIFY2(file.commit(), qPrintable(file.errorString())); + QCOMPARE(file.size(), qint64(strlen(hello))); + const char *world = "World"; QVERIFY2(file.open(QIODevice::WriteOnly), msgCannotOpen(file).constData()); - QCOMPARE(file.write("World"), Q_INT64_C(5)); + QCOMPARE(file.write(world), qint64(strlen(world))); QVERIFY2(file.commit(), qPrintable(file.errorString())); + QCOMPARE(file.size(), qint64(strlen(world))); QFile reader(targetFile); QVERIFY2(reader.open(QIODevice::ReadOnly), msgCannotOpen(reader).constData()); - QCOMPARE(QString::fromLatin1(reader.readAll()), QString::fromLatin1("World")); + QCOMPARE(QString::fromLatin1(reader.readAll()), QString::fromLatin1(world)); } void tst_QSaveFile::textStreamManualFlush() @@ -176,16 +200,18 @@ void tst_QSaveFile::textStreamManualFlush() QSaveFile file(targetFile); QVERIFY2(file.open(QIODevice::WriteOnly), msgCannotOpen(file).constData()); + const char *data = "Manual flush"; QTextStream ts(&file); - ts << "Manual flush"; + ts << data; ts.flush(); QCOMPARE(file.error(), QFile::NoError); QVERIFY(!QFile::exists(targetFile)); QVERIFY(file.commit()); + QCOMPARE(file.size(), qint64(strlen(data))); QFile reader(targetFile); QVERIFY(reader.open(QIODevice::ReadOnly)); - QCOMPARE(QString::fromLatin1(reader.readAll().constData()), QString::fromLatin1("Manual flush")); + QCOMPARE(QString::fromLatin1(reader.readAll().constData()), QString::fromLatin1(data)); QFile::remove(targetFile); } @@ -432,6 +458,7 @@ void tst_QSaveFile::symlink() QVERIFY(saveFile.open(QIODevice::WriteOnly)); QCOMPARE(saveFile.write(someData), someData.size()); saveFile.commit(); + QCOMPARE(saveFile.size(), someData.size()); QFile file(targetFile); QVERIFY2(file.open(QIODevice::ReadOnly), msgCannotOpen(file).constData()); @@ -461,6 +488,7 @@ void tst_QSaveFile::symlink() QVERIFY(saveFile.open(QIODevice::WriteOnly)); QCOMPARE(saveFile.write(someData), someData.size()); saveFile.commit(); + QCOMPARE(saveFile.size(), someData.size()); // the explicit file becomes a file instead of a link QVERIFY(!QFileInfo(cyclicLink + QLatin1Char('1')).isSymLink()); @@ -540,6 +568,7 @@ void tst_QSaveFile::alternateDataStream() QVERIFY2(file.open(QIODevice::WriteOnly), qPrintable(file.errorString())); file.write(newContent); QVERIFY2(file.commit(), qPrintable(file.errorString())); + QCOMPARE(file.size(), qint64(strlen(newContent))); // check the contents QFile targetFile(adsName); diff --git a/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp b/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp index 01f2ad7694..84d0a505a4 100644 --- a/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp +++ b/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp @@ -430,7 +430,7 @@ void tst_qstandardpaths::testAppConfigLocation() #endif } -#ifndef Q_OS_WIN +#if !defined(Q_OS_WIN) && !defined(Q_OS_WASM) // Find "sh" on Unix. // It may exist twice, in /bin/sh and /usr/bin/sh, in that case use the PATH order. static inline QFileInfo findSh() @@ -484,6 +484,7 @@ void tst_qstandardpaths::testFindExecutable_data() << QString() << logo << logoPath; } #else +# ifndef Q_OS_WASM const QFileInfo shFi = findSh(); Q_ASSERT(shFi.exists()); const QString shPath = shFi.absoluteFilePath(); @@ -493,6 +494,7 @@ void tst_qstandardpaths::testFindExecutable_data() << QString() << shPath << shPath; QTest::newRow("unix-sh-relativepath") << QString(shFi.absolutePath()) << QString::fromLatin1("./sh") << shPath; +#endif /* !WASM */ #endif QTest::newRow("idontexist") << QString() << QString::fromLatin1("idontexist") << QString(); @@ -524,6 +526,9 @@ void tst_qstandardpaths::testFindExecutable() void tst_qstandardpaths::testFindExecutableLinkToDirectory() { +#ifdef Q_OS_WASM + QSKIP("No applicationdir on wasm"); +#else // link to directory const QString target = QDir::tempPath() + QDir::separator() + QLatin1String("link.lnk"); QFile::remove(target); @@ -531,9 +536,10 @@ void tst_qstandardpaths::testFindExecutableLinkToDirectory() QVERIFY(appFile.link(target)); QVERIFY(QStandardPaths::findExecutable(target).isEmpty()); QFile::remove(target); +#endif } -using RuntimeDirSetup = QString (*)(QDir &); +using RuntimeDirSetup = std::optional<QString> (*)(QDir &); Q_DECLARE_METATYPE(RuntimeDirSetup); void tst_qstandardpaths::testRuntimeDirectory() @@ -593,18 +599,18 @@ void tst_qstandardpaths::testCustomRuntimeDirectory_data() QSKIP("Running this test as root doesn't make sense"); # endif - addRow("environment:non-existing", [](QDir &d) { + addRow("environment:non-existing", [](QDir &d) -> std::optional<QString> { return updateRuntimeDir(d.filePath("runtime")); }); - addRow("environment:existing", [](QDir &d) { + addRow("environment:existing", [](QDir &d) -> std::optional<QString> { QString p = d.filePath("runtime"); d.mkdir("runtime"); QFile::setPermissions(p, QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner); return updateRuntimeDir(p); }); - addRow("environment-to-existing-wrong-perm", [](QDir &d) { + addRow("environment-to-existing-wrong-perm", [](QDir &d) -> std::optional<QString> { QString p = d.filePath("runtime"); d.mkdir("runtime"); QFile::setPermissions(p, QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner | @@ -617,7 +623,7 @@ void tst_qstandardpaths::testCustomRuntimeDirectory_data() return fallbackXdgRuntimeDir(); }); - addRow("environment:wrong-owner", [](QDir &) { + addRow("environment:wrong-owner", [](QDir &) -> std::optional<QString> { QT_STATBUF st; QT_STAT("/", &st); @@ -632,10 +638,18 @@ void tst_qstandardpaths::testCustomRuntimeDirectory_data() return fallbackXdgRuntimeDir(); }); - addRow("environment:file", [](QDir &d) { + // static so that it can be used in RuntimeDirSetup callable without capturing + static auto failedToOpen = [](const QFile &f) { + qCritical("QFile::Open: failed to open '%s': %s", + qPrintable(f.fileName()), qPrintable(f.errorString())); + return std::nullopt; + }; + + addRow("environment:file", [](QDir &d) -> std::optional<QString> { QString p = d.filePath("file"); QFile f(p); - f.open(QIODevice::WriteOnly); + if (!f.open(QIODevice::WriteOnly)) + return failedToOpen(f); f.setPermissions(QFile::ReadOwner | QFile::WriteOwner); updateRuntimeDir(p); @@ -646,7 +660,7 @@ void tst_qstandardpaths::testCustomRuntimeDirectory_data() return fallbackXdgRuntimeDir(); }); - addRow("environment:broken-symlink", [](QDir &d) { + addRow("environment:broken-symlink", [](QDir &d) -> std::optional<QString> { QString p = d.filePath("link"); QFile::link(d.filePath("this-goes-nowhere"), p); updateRuntimeDir(p); @@ -657,7 +671,7 @@ void tst_qstandardpaths::testCustomRuntimeDirectory_data() return fallbackXdgRuntimeDir(); }); - addRow("environment:symlink-to-dir", [](QDir &d) { + addRow("environment:symlink-to-dir", [](QDir &d) -> std::optional<QString> { QString p = d.filePath("link"); d.mkdir("dir"); QFile::link(d.filePath("dir"), p); @@ -670,12 +684,12 @@ void tst_qstandardpaths::testCustomRuntimeDirectory_data() return fallbackXdgRuntimeDir(); }); - addRow("no-environment:non-existing", [](QDir &) { + addRow("no-environment:non-existing", [](QDir &) -> std::optional<QString> { clearRuntimeDir(); return fallbackXdgRuntimeDir(); }); - addRow("no-environment:existing", [](QDir &d) { + addRow("no-environment:existing", [](QDir &d) -> std::optional<QString> { clearRuntimeDir(); QString p = fallbackXdgRuntimeDir(); d.mkdir(p); // probably has wrong permissions @@ -683,10 +697,11 @@ void tst_qstandardpaths::testCustomRuntimeDirectory_data() return p; }); - addRow("no-environment:fallback-is-file", [](QDir &) { + addRow("no-environment:fallback-is-file", [](QDir &) -> std::optional<QString> { QString p = fallbackXdgRuntimeDir(); QFile f(p); - f.open(QIODevice::WriteOnly); + if (!f.open(QIODevice::WriteOnly)) + return failedToOpen(f); f.setPermissions(QFile::ReadOwner | QFile::WriteOwner); clearRuntimeDir(); @@ -697,10 +712,11 @@ void tst_qstandardpaths::testCustomRuntimeDirectory_data() return QString(); }); - addRow("environment-and-fallback-are-files", [](QDir &d) { + addRow("environment-and-fallback-are-files", [](QDir &d) -> std::optional<QString> { QString p = d.filePath("file1"); QFile f(p); - f.open(QIODevice::WriteOnly); + if (!f.open(QIODevice::WriteOnly)) + return failedToOpen(f); f.setPermissions(QFile::ReadOwner | QFile::WriteOwner | QFile::ReadGroup); updateRuntimeDir(p); QTest::ignoreMessage(QtWarningMsg, @@ -710,7 +726,8 @@ void tst_qstandardpaths::testCustomRuntimeDirectory_data() f.close(); f.setFileName(fallbackXdgRuntimeDir()); - f.open(QIODevice::WriteOnly); + if (!f.open(QIODevice::WriteOnly)) + return failedToOpen(f); f.setPermissions(QFile::ReadOwner | QFile::WriteOwner | QFile::ReadGroup); QTest::ignoreMessage(QtWarningMsg, QString("QStandardPaths: runtime directory '%1' is not a directory, " @@ -750,7 +767,9 @@ void tst_qstandardpaths::testCustomRuntimeDirectory() qputenv("TMPDIR", QFile::encodeName(tempDir.path())); QFETCH(RuntimeDirSetup, setup); - QString expected = setup(d); + std::optional<QString> opt = setup(d); + QVERIFY(opt); + QString expected = *opt; QString runtimeDir = QStandardPaths::writableLocation(QStandardPaths::RuntimeLocation); QCOMPARE(runtimeDir, expected); diff --git a/tests/auto/corelib/io/qstorageinfo/tst_qstorageinfo.cpp b/tests/auto/corelib/io/qstorageinfo/tst_qstorageinfo.cpp index 6a6339a8ec..f96cd48900 100644 --- a/tests/auto/corelib/io/qstorageinfo/tst_qstorageinfo.cpp +++ b/tests/auto/corelib/io/qstorageinfo/tst_qstorageinfo.cpp @@ -24,6 +24,8 @@ # include "../../../../../src/corelib/io/qstorageinfo_linux_p.h" #endif +using namespace Qt::StringLiterals; + class tst_QStorageInfo : public QObject { Q_OBJECT @@ -137,8 +139,10 @@ void tst_QStorageInfo::root() QVERIFY(storage.isReady()); QCOMPARE(storage.rootPath(), QDir::rootPath()); QVERIFY(storage.isRoot()); +#ifndef Q_OS_WASM QVERIFY(!storage.device().isEmpty()); QVERIFY(!storage.fileSystemType().isEmpty()); +#endif #ifndef Q_OS_HAIKU QCOMPARE_GE(storage.bytesTotal(), 0); QCOMPARE_GE(storage.bytesFree(), 0); @@ -149,6 +153,9 @@ void tst_QStorageInfo::root() void tst_QStorageInfo::currentStorage() { QString appPath = QCoreApplication::applicationFilePath(); + if (appPath.isEmpty()) + QSKIP("No applicationFilePath(), cannot test"); + QStorageInfo storage(appPath); QVERIFY(storage.isValid()); QVERIFY(storage.isReady()); @@ -262,7 +269,9 @@ void tst_QStorageInfo::freeSpaceUpdate() FlushFileBuffers(HANDLE(_get_osfhandle(file.handle()))); #elif _POSIX_VERSION >= 200112L fsync(file.handle()); +# ifndef Q_OS_VXWORKS sync(); +# endif // Q_OS_VXWORKS #endif }; @@ -306,7 +315,10 @@ void tst_QStorageInfo::freeSpaceUpdate() QCOMPARE(free, storage2.bytesFree()); storage2.refresh(); QCOMPARE(storage1, storage2); + +#ifndef Q_OS_WASM QCOMPARE_NE(free, storage2.bytesFree()); +#endif } #if defined(Q_OS_LINUX) && defined(QT_BUILD_INTERNAL) @@ -317,64 +329,64 @@ void tst_QStorageInfo::testParseMountInfo_data() QTest::newRow("tmpfs") << "17 25 0:18 / /dev rw,nosuid,relatime shared:2 - tmpfs tmpfs rw,seclabel,mode=755\n"_ba - << MountInfo{"/dev", "tmpfs", "tmpfs", "", makedev(0, 18)}; + << MountInfo{"/dev", "tmpfs", "tmpfs", "", makedev(0, 18), 17}; QTest::newRow("proc") << "23 66 0:21 / /proc rw,nosuid,nodev,noexec,relatime shared:12 - proc proc rw\n"_ba - << MountInfo{"/proc", "proc", "proc", "", makedev(0, 21)}; + << MountInfo{"/proc", "proc", "proc", "", makedev(0, 21), 23}; // E.g. on Android QTest::newRow("rootfs") << "618 618 0:1 / / ro,relatime master:1 - rootfs rootfs ro,seclabel\n"_ba - << MountInfo{"/", "rootfs", "rootfs", "", makedev(0, 1)}; + << MountInfo{"/", "rootfs", "rootfs", "", makedev(0, 1), 618}; QTest::newRow("ext4") << "47 66 8:3 / /home rw,relatime shared:50 - ext4 /dev/sda3 rw,stripe=32736\n"_ba - << MountInfo{"/home", "ext4", "/dev/sda3", "", makedev(8, 3)}; + << MountInfo{"/home", "ext4", "/dev/sda3", "", makedev(8, 3), 47}; QTest::newRow("empty-optional-field") << "23 25 0:22 / /apex rw,nosuid,nodev,noexec,relatime - tmpfs tmpfs rw,seclabel,mode=755\n"_ba - << MountInfo{"/apex", "tmpfs", "tmpfs", "", makedev(0, 22)}; + << MountInfo{"/apex", "tmpfs", "tmpfs", "", makedev(0, 22), 23}; QTest::newRow("one-optional-field") << "47 66 8:3 / /home rw,relatime shared:50 - ext4 /dev/sda3 rw,stripe=32736\n"_ba - << MountInfo{"/home", "ext4", "/dev/sda3", "", makedev(8, 3)}; + << MountInfo{"/home", "ext4", "/dev/sda3", "", makedev(8, 3), 47}; QTest::newRow("multiple-optional-fields") << "47 66 8:3 / /home rw,relatime shared:142 master:111 - ext4 /dev/sda3 rw,stripe=32736\n"_ba - << MountInfo{"/home", "ext4", "/dev/sda3", "", makedev(8, 3)}; + << MountInfo{"/home", "ext4", "/dev/sda3", "", makedev(8, 3), 47}; QTest::newRow("mountdir-with-utf8") << "129 66 8:51 / /mnt/lab\xC3\xA9l rw,relatime shared:234 - ext4 /dev/sdd3 rw\n"_ba - << MountInfo{"/mnt/labél", "ext4", "/dev/sdd3", "", makedev(8, 51)}; + << MountInfo{"/mnt/labél", "ext4", "/dev/sdd3", "", makedev(8, 51), 129}; QTest::newRow("mountdir-with-space") << "129 66 8:51 / /mnt/labe\\040l rw,relatime shared:234 - ext4 /dev/sdd3 rw\n"_ba - << MountInfo{"/mnt/labe l", "ext4", "/dev/sdd3", "", makedev(8, 51)}; + << MountInfo{"/mnt/labe l", "ext4", "/dev/sdd3", "", makedev(8, 51), 129}; QTest::newRow("mountdir-with-tab") << "129 66 8:51 / /mnt/labe\\011l rw,relatime shared:234 - ext4 /dev/sdd3 rw\n"_ba - << MountInfo{"/mnt/labe\tl", "ext4", "/dev/sdd3", "", makedev(8, 51)}; + << MountInfo{"/mnt/labe\tl", "ext4", "/dev/sdd3", "", makedev(8, 51), 129}; QTest::newRow("mountdir-with-backslash") << "129 66 8:51 / /mnt/labe\\134l rw,relatime shared:234 - ext4 /dev/sdd3 rw\n"_ba - << MountInfo{"/mnt/labe\\l", "ext4", "/dev/sdd3", "", makedev(8, 51)}; + << MountInfo{"/mnt/labe\\l", "ext4", "/dev/sdd3", "", makedev(8, 51), 129}; QTest::newRow("mountdir-with-newline") << "129 66 8:51 / /mnt/labe\\012l rw,relatime shared:234 - ext4 /dev/sdd3 rw\n"_ba - << MountInfo{"/mnt/labe\nl", "ext4", "/dev/sdd3", "", makedev(8, 51)}; + << MountInfo{"/mnt/labe\nl", "ext4", "/dev/sdd3", "", makedev(8, 51), 129}; QTest::newRow("btrfs-subvol") << "775 503 0:49 /foo/bar / rw,relatime shared:142 master:111 - btrfs " "/dev/mapper/vg0-stuff rw,ssd,discard,space_cache,subvolid=272,subvol=/foo/bar\n"_ba - << MountInfo{"/", "btrfs", "/dev/mapper/vg0-stuff", "/foo/bar", makedev(0, 49)}; + << MountInfo{"/", "btrfs", "/dev/mapper/vg0-stuff", "/foo/bar", makedev(0, 49), 775}; QTest::newRow("bind-mount") << "59 47 8:17 /rpmbuild /home/user/rpmbuild rw,relatime shared:48 - ext4 /dev/sdb1 rw\n"_ba - << MountInfo{"/home/user/rpmbuild", "ext4", "/dev/sdb1", "/rpmbuild", makedev(8, 17)}; + << MountInfo{"/home/user/rpmbuild", "ext4", "/dev/sdb1", "/rpmbuild", makedev(8, 17), 59}; QTest::newRow("space-dash-space") << "47 66 8:3 / /home\\040-\\040dir rw,relatime shared:50 - ext4 /dev/sda3 rw,stripe=32736\n"_ba - << MountInfo{"/home - dir", "ext4", "/dev/sda3", "", makedev(8, 3)}; + << MountInfo{"/home - dir", "ext4", "/dev/sda3", "", makedev(8, 3), 47}; QTest::newRow("btrfs-mount-bind-file") << "1799 1778 0:49 " @@ -383,7 +395,7 @@ void tst_QStorageInfo::testParseMountInfo_data() "rw,ssd,discard,space_cache,subvolid=1773,subvol=/var_lib_docker\n"_ba << MountInfo{"/etc/resolv.conf", "btrfs", "/dev/mapper/vg0-stuff", "/var_lib_docker/containers/81fde0fec3dd3d99765c3f7fd9cf1ab121b6ffcfd05d5d7ff434db933fe9d795/resolv.conf", - makedev(0, 49)}; + makedev(0, 49), 1799}; QTest::newRow("very-long-line-QTBUG-77059") << "727 26 0:52 / " @@ -400,13 +412,13 @@ void tst_QStorageInfo::testParseMountInfo_data() "workdir=/var/lib/docker/overlay2/f3fbad5eedef71145f00729f0826ea8c44defcfec8c92c58aee0aa2c5ea3fa3a/work," "index=off,xino=off\n"_ba << MountInfo{"/var/lib/docker/overlay2/f3fbad5eedef71145f00729f0826ea8c44defcfec8c92c58aee0aa2c5ea3fa3a/merged", - "overlay", "overlay", "", makedev(0, 52)}; + "overlay", "overlay", "", makedev(0, 52), 727}; QTest::newRow("sshfs-src-device-not-start-with-slash") << "128 92 0:64 / /mnt-point rw,nosuid,nodev,relatime shared:234 - " "fuse.sshfs admin@192.168.1.2:/storage/emulated/0 rw,user_id=1000,group_id=1000\n"_ba << MountInfo{"/mnt-point", "fuse.sshfs", - "admin@192.168.1.2:/storage/emulated/0", "", makedev(0, 64)}; + "admin@192.168.1.2:/storage/emulated/0", "", makedev(0, 64), 128}; } void tst_QStorageInfo::testParseMountInfo() @@ -422,6 +434,7 @@ void tst_QStorageInfo::testParseMountInfo() QCOMPARE(a.device, expected.device); QCOMPARE(a.fsRoot, expected.fsRoot); QCOMPARE(a.stDev, expected.stDev); + QCOMPARE(a.mntid, expected.mntid); } void tst_QStorageInfo::testParseMountInfo_filtered_data() diff --git a/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp b/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp index 579e6d5511..1419f06f86 100644 --- a/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp +++ b/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp @@ -592,7 +592,9 @@ void tst_QTemporaryFile::rename() void tst_QTemporaryFile::renameFdLeak() { #if defined(Q_OS_UNIX) && !defined(Q_OS_ANDROID) - const QByteArray sourceFile = QFile::encodeName(QFINDTESTDATA("CMakeLists.txt")); + QTemporaryFile file; + QVERIFY(file.open()); + const QByteArray sourceFile = QFile::encodeName(file.fileName()); QVERIFY(!sourceFile.isEmpty()); // Test this on Unix only diff --git a/tests/auto/corelib/io/qurl/tst_qurl.cpp b/tests/auto/corelib/io/qurl/tst_qurl.cpp index 81cd94e4ed..2024968435 100644 --- a/tests/auto/corelib/io/qurl/tst_qurl.cpp +++ b/tests/auto/corelib/io/qurl/tst_qurl.cpp @@ -3776,13 +3776,13 @@ void tst_QUrl::setComponents_data() << PrettyDecoded << QString() << "foo:/path"; QTest::newRow("host-empty") << QUrl("foo://example.com/path") << int(Host) << "" << Tolerant << true - << PrettyDecoded << QString() << "foo:///path"; + << PrettyDecoded << "" << "foo:///path"; QTest::newRow("authority-null") << QUrl("foo://example.com/path") << int(Authority) << QString() << Tolerant << true << PrettyDecoded << QString() << "foo:/path"; QTest::newRow("authority-empty") << QUrl("foo://example.com/path") << int(Authority) << "" << Tolerant << true - << PrettyDecoded << QString() << "foo:///path"; + << PrettyDecoded << "" << "foo:///path"; QTest::newRow("query-null") << QUrl("http://example.com/?q=foo") << int(Query) << QString() << Tolerant << true << PrettyDecoded << QString() << "http://example.com/"; @@ -3840,10 +3840,10 @@ void tst_QUrl::setComponents_data() << PrettyDecoded << QString() << QString(); QTest::newRow("invalid-authority-1") << QUrl("http://example.com") << int(Authority) << "-not-valid-" << Tolerant << false - << PrettyDecoded << QString() << QString(); + << PrettyDecoded << "" << QString(); QTest::newRow("invalid-authority-2") << QUrl("http://example.com") << int(Authority) << "%31%30.%30.%30.%31" << Strict << false - << PrettyDecoded << QString() << QString(); + << PrettyDecoded << "" << QString(); QTest::newRow("invalid-path-0") << QUrl("http://example.com") << int(Path) << "{}" << Strict << false @@ -4126,14 +4126,30 @@ void tst_QUrl::testThreadingHelper() void tst_QUrl::testThreading() { + enum { Count = 100 }; + if (QTestPrivate::isRunningArmOnX86()) QSKIP("This test fails in QEMU and looks like because of a data race, QTBUG-93176"); s_urlStorage = new UrlStorage; - QThreadPool::globalInstance()->setMaxThreadCount(100); - QFutureSynchronizer<void> sync; - for (int i = 0; i < 100; ++i) - sync.addFuture(QtConcurrent::run(&tst_QUrl::testThreadingHelper, this)); - sync.waitForFinished(); + QThreadPool::globalInstance()->setMaxThreadCount(Count); + + // Written this way because wasm need the eventloop + QList<QFuture<void>> futures; + futures.reserve(Count); + + for (int i = 0; i < Count; ++i) + futures.push_back(QtConcurrent::run(&tst_QUrl::testThreadingHelper, this)); + + QEventLoop loop; + std::atomic<int> remaining = Count; + for (int i = 0; i < Count; ++i) { + futures[i].then([&]() { + if (!--remaining) + loop.quit(); + }); + } + loop.exec(); + delete s_urlStorage; } diff --git a/tests/auto/corelib/io/qurlquery/tst_qurlquery.cpp b/tests/auto/corelib/io/qurlquery/tst_qurlquery.cpp index 8a799fbf94..8360bdbe28 100644 --- a/tests/auto/corelib/io/qurlquery/tst_qurlquery.cpp +++ b/tests/auto/corelib/io/qurlquery/tst_qurlquery.cpp @@ -73,9 +73,12 @@ static QByteArray prettyList(const QueryItems &items) static bool compare(const QueryItems &actual, const QueryItems &expected, const char *actualStr, const char *expectedStr, const char *file, int line) { + auto formatter = [](const void *val) -> const char * { + const QueryItems items = *static_cast<const QueryItems *>(val); + return qstrdup(prettyList(items).constData()); + }; return QTest::compare_helper(actual == expected, "Compared values are not the same", - [&actual] { return qstrdup(prettyList(actual).constData()); }, - [&expected] { return qstrdup(prettyList(expected).constData()); }, + &actual, &expected, formatter, formatter, actualStr, expectedStr, file, line); } diff --git a/tests/auto/corelib/ipc/qnativeipckey/CMakeLists.txt b/tests/auto/corelib/ipc/qnativeipckey/CMakeLists.txt index aba8946002..0cc6a7b18b 100644 --- a/tests/auto/corelib/ipc/qnativeipckey/CMakeLists.txt +++ b/tests/auto/corelib/ipc/qnativeipckey/CMakeLists.txt @@ -10,4 +10,6 @@ endif() qt_internal_add_test(tst_qnativeipckey SOURCES tst_qnativeipckey.cpp + LIBRARIES + Qt::TestPrivate ) diff --git a/tests/auto/corelib/ipc/qnativeipckey/tst_qnativeipckey.cpp b/tests/auto/corelib/ipc/qnativeipckey/tst_qnativeipckey.cpp index cd1a07a4d0..a01a108591 100644 --- a/tests/auto/corelib/ipc/qnativeipckey/tst_qnativeipckey.cpp +++ b/tests/auto/corelib/ipc/qnativeipckey/tst_qnativeipckey.cpp @@ -3,6 +3,7 @@ #include <QtCore/QNativeIpcKey> #include <QtTest/QTest> +#include <QtTest/private/qcomparisontesthelper_p.h> #include "../ipctestcommon.h" @@ -25,6 +26,7 @@ class tst_QNativeIpcKey : public QObject { Q_OBJECT private slots: + void compareCompiles(); void defaultTypes(); void construct(); void getSetCheck(); @@ -39,6 +41,11 @@ private slots: void legacyKeys(); }; +void tst_QNativeIpcKey::compareCompiles() +{ + QTestPrivate::testEqualityOperatorsCompile<QNativeIpcKey>(); +} + void tst_QNativeIpcKey::defaultTypes() { auto isKnown = [](QNativeIpcKey::Type t) { @@ -180,35 +187,43 @@ void tst_QNativeIpcKey::equality() QNativeIpcKey key1, key2; QCOMPARE(key1, key2); QVERIFY(!(key1 != key2)); + QT_TEST_EQUALITY_OPS(key1, key2, true); key1.setNativeKey("key1"); QCOMPARE_NE(key1, key2); QVERIFY(!(key1 == key2)); + QT_TEST_EQUALITY_OPS(key1, key2, false); key2.setType({}); QCOMPARE_NE(key1, key2); QVERIFY(!(key1 == key2)); + QT_TEST_EQUALITY_OPS(key1, key2, false); key2.setNativeKey(key1.nativeKey()); QCOMPARE_NE(key1, key2); QVERIFY(!(key1 == key2)); + QT_TEST_EQUALITY_OPS(key1, key2, false); key2.setType(QNativeIpcKey::DefaultTypeForOs); QCOMPARE(key1, key2); QVERIFY(!(key1 != key2)); + QT_TEST_EQUALITY_OPS(key1, key2, true); key1 = makeLegacyKey("key1", QNativeIpcKey::DefaultTypeForOs); QCOMPARE_NE(key1, key2); QVERIFY(!(key1 == key2)); + QT_TEST_EQUALITY_OPS(key1, key2, false); key2 = key1; QCOMPARE(key1, key2); QVERIFY(!(key1 != key2)); + QT_TEST_EQUALITY_OPS(key1, key2, true); // just setting the native key won't make them equal again! key2.setNativeKey(key1.nativeKey()); QCOMPARE_NE(key1, key2); QVERIFY(!(key1 == key2)); + QT_TEST_EQUALITY_OPS(key1, key2, false); } void tst_QNativeIpcKey::hash() @@ -410,6 +425,7 @@ void tst_QNativeIpcKey::legacyKeys() QString string = key.toString(); QNativeIpcKey key2 = QNativeIpcKey::fromString(string); QCOMPARE(key2, key); + QT_TEST_EQUALITY_OPS(key, key2, true); if (!legacyKey.isEmpty()) { // confirm it shows up in the encoded form diff --git a/tests/auto/corelib/itemmodels/CMakeLists.txt b/tests/auto/corelib/itemmodels/CMakeLists.txt index 90211669d9..c0cd04df12 100644 --- a/tests/auto/corelib/itemmodels/CMakeLists.txt +++ b/tests/auto/corelib/itemmodels/CMakeLists.txt @@ -4,15 +4,17 @@ add_subdirectory(qstringlistmodel) if(TARGET Qt::Gui) add_subdirectory(qabstractitemmodel) - add_subdirectory(qabstractproxymodel) - add_subdirectory(qconcatenatetablesproxymodel) - add_subdirectory(qidentityproxymodel) + if(QT_FEATURE_proxymodel) + add_subdirectory(qabstractproxymodel) + add_subdirectory(qconcatenatetablesproxymodel) + add_subdirectory(qidentityproxymodel) + add_subdirectory(qsortfilterproxymodel_recursive) + add_subdirectory(qsortfilterproxymodel_regularexpression) + add_subdirectory(qtransposeproxymodel) + endif() add_subdirectory(qitemselectionmodel) - add_subdirectory(qsortfilterproxymodel_recursive) - add_subdirectory(qsortfilterproxymodel_regularexpression) - add_subdirectory(qtransposeproxymodel) endif() -if(TARGET Qt::Widgets) +if(TARGET Qt::Widgets AND QT_FEATURE_proxymodel) add_subdirectory(qsortfilterproxymodel) endif() if(TARGET Qt::Sql AND TARGET Qt::Widgets) diff --git a/tests/auto/corelib/itemmodels/qabstractitemmodel/tst_qabstractitemmodel.cpp b/tests/auto/corelib/itemmodels/qabstractitemmodel/tst_qabstractitemmodel.cpp index 36eb9320a4..c48b79b260 100644 --- a/tests/auto/corelib/itemmodels/qabstractitemmodel/tst_qabstractitemmodel.cpp +++ b/tests/auto/corelib/itemmodels/qabstractitemmodel/tst_qabstractitemmodel.cpp @@ -6,7 +6,9 @@ #include <QtTest/private/qcomparisontesthelper_p.h> #include <QtCore/QCoreApplication> +#if QT_CONFIG(sortfilterproxymodel) #include <QtCore/QSortFilterProxyModel> +#endif #include <QtCore/QStringListModel> #include <QtGui/QStandardItemModel> @@ -80,9 +82,11 @@ private slots: void testMoveWithinOwnRange_data(); void testMoveWithinOwnRange(); +#if QT_CONFIG(sortfilterproxymodel) void testMoveThroughProxy(); void testReset(); +#endif void testDataChanged(); @@ -989,9 +993,9 @@ void tst_QAbstractItemModel::complexChangesWithPersistent() void tst_QAbstractItemModel::modelIndexComparisons() { - QTestPrivate::testEqualityOperatorsCompile<QModelIndex>(); - QTestPrivate::testEqualityOperatorsCompile<QPersistentModelIndex>(); - QTestPrivate::testEqualityOperatorsCompile<QPersistentModelIndex, QModelIndex>(); + QTestPrivate::testAllComparisonOperatorsCompile<QModelIndex>(); + QTestPrivate::testAllComparisonOperatorsCompile<QPersistentModelIndex>(); + QTestPrivate::testAllComparisonOperatorsCompile<QPersistentModelIndex, QModelIndex>(); QtTestModel model(3, 3); @@ -999,13 +1003,28 @@ void tst_QAbstractItemModel::modelIndexComparisons() QModelIndex mi22 = model.index(2, 2); QPersistentModelIndex pmi11 = mi11; QPersistentModelIndex pmi22 = mi22; + QPersistentModelIndex pmiU; QT_TEST_EQUALITY_OPS(mi11, mi11, true); QT_TEST_EQUALITY_OPS(mi11, mi22, false); + QT_TEST_ALL_COMPARISON_OPS(mi11, mi11, Qt::strong_ordering::equal); + QT_TEST_ALL_COMPARISON_OPS(mi11, mi22, Qt::strong_ordering::less); + QT_TEST_ALL_COMPARISON_OPS(mi22, mi11, Qt::strong_ordering::greater); QT_TEST_EQUALITY_OPS(pmi11, pmi11, true); QT_TEST_EQUALITY_OPS(pmi11, pmi22, false); QT_TEST_EQUALITY_OPS(pmi11, mi11, true); QT_TEST_EQUALITY_OPS(pmi11, mi22, false); + + QT_TEST_ALL_COMPARISON_OPS(pmi11, pmi11, Qt::strong_ordering::equal); + QT_TEST_ALL_COMPARISON_OPS(pmi11, pmi22, Qt::strong_ordering::less); + // Disengaged QPMIs are sorted randomly (based on address of their Private) + // So all we can check here is QPMIs with d == nullptr, which should reliably + // come before any others. + QT_TEST_ALL_COMPARISON_OPS(pmiU, pmiU, Qt::strong_ordering::equal); + QT_TEST_ALL_COMPARISON_OPS(pmi11, pmiU, Qt::strong_ordering::greater); + QT_TEST_ALL_COMPARISON_OPS(pmi11, mi11, Qt::strong_ordering::equal); + QT_TEST_ALL_COMPARISON_OPS(pmi11, mi22, Qt::strong_ordering::less); + QT_TEST_ALL_COMPARISON_OPS(pmiU, mi11, Qt::strong_ordering::less); } void tst_QAbstractItemModel::testMoveSameParentDown_data() @@ -1239,6 +1258,7 @@ void tst_QAbstractItemModel::testMoveSameParentUp() } } +#if QT_CONFIG(sortfilterproxymodel) void tst_QAbstractItemModel::testMoveThroughProxy() { QSortFilterProxyModel *proxy = new QSortFilterProxyModel(this); @@ -1257,6 +1277,7 @@ void tst_QAbstractItemModel::testMoveThroughProxy() moveCommand->setDestRow(0); moveCommand->doCommand(); } +#endif void tst_QAbstractItemModel::testMoveToGrandParent_data() { @@ -1804,6 +1825,7 @@ void tst_QAbstractItemModel::testMoveWithinOwnRange() QCOMPARE(afterSpy.size(), 0); } +#if QT_CONFIG(proxymodel) class ListenerObject : public QObject { Q_OBJECT @@ -1822,7 +1844,7 @@ private: QList<QPersistentModelIndex> m_persistentIndexes; QModelIndexList m_nonPersistentIndexes; }; - +#endif class ModelWithCustomRole : public QStringListModel { @@ -1836,6 +1858,7 @@ public: } }; +#if QT_CONFIG(proxymodel) ListenerObject::ListenerObject(QAbstractProxyModel *parent) : QObject(parent), m_model(parent) { @@ -1876,7 +1899,9 @@ void ListenerObject::slotReset() QVERIFY(!idx.isValid()); } } +#endif +#if QT_CONFIG(sortfilterproxymodel) void tst_QAbstractItemModel::testReset() { QSignalSpy beforeResetSpy(m_model, &DynamicTreeModel::modelAboutToBeReset); @@ -1931,6 +1956,7 @@ void tst_QAbstractItemModel::testReset() // After being reset the proxy must be queried again. QCOMPARE(nullProxy->roleNames().value(Qt::UserRole + 1), QByteArray()); } +#endif class CustomRoleModel : public QStringListModel { diff --git a/tests/auto/corelib/itemmodels/qitemselectionmodel/tst_qitemselectionmodel.cpp b/tests/auto/corelib/itemmodels/qitemselectionmodel/tst_qitemselectionmodel.cpp index 02e0f86ea7..08233a1f7b 100644 --- a/tests/auto/corelib/itemmodels/qitemselectionmodel/tst_qitemselectionmodel.cpp +++ b/tests/auto/corelib/itemmodels/qitemselectionmodel/tst_qitemselectionmodel.cpp @@ -2,6 +2,7 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QTest> +#include <QtTest/private/qcomparisontesthelper_p.h> #include <QtTest/private/qpropertytesthelper_p.h> #include <QSignalSpy> @@ -24,6 +25,7 @@ public slots: void cleanupTestCase(); void init(); private slots: + void compareCompiles(); void clear_data(); void clear(); void clearAndSelect(); @@ -55,8 +57,10 @@ private slots: void merge(); void isRowSelected(); void childrenDeselectionSignal(); +#if QT_CONFIG(proxymodel) void layoutChangedWithAllSelected1(); void layoutChangedWithAllSelected2(); +#endif void layoutChangedTreeSelection(); void deselectRemovedMiddleRange(); void setModel(); @@ -73,7 +77,9 @@ private slots: void QTBUG48402(); void QTBUG58851_data(); +#if QT_CONFIG(proxymodel) void QTBUG58851(); +#endif void QTBUG18001_data(); void QTBUG18001(); @@ -213,6 +219,11 @@ void tst_QItemSelectionModel::init() model->insertRow(0, QModelIndex()); } +void tst_QItemSelectionModel::compareCompiles() +{ + QTestPrivate::testEqualityOperatorsCompile<QItemSelectionRange>(); +} + void tst_QItemSelectionModel::clear_data() { QTest::addColumn<QModelIndexList>("indexList"); @@ -2253,6 +2264,7 @@ void tst_QItemSelectionModel::childrenDeselectionSignal() QVERIFY(selectionModel.selection().contains(sel2)); } +#if QT_CONFIG(proxymodel) void tst_QItemSelectionModel::layoutChangedWithAllSelected1() { QStringListModel model( QStringList() << "foo" << "bar" << "foo2"); @@ -2331,6 +2343,7 @@ void tst_QItemSelectionModel::layoutChangedWithAllSelected2() for (const auto &index : indexList) QVERIFY(selection.isSelected(index)); } +#endif // This test is a regression test for QTBUG-2804. void tst_QItemSelectionModel::layoutChangedTreeSelection() @@ -2714,6 +2727,9 @@ void tst_QItemSelectionModel::QTBUG48402() model.removeRows(removeTop, removeBottom - removeTop + 1); QCOMPARE(QItemSelectionRange(helper.tl, helper.br), QItemSelectionRange(dtl, dbr)); + QT_TEST_EQUALITY_OPS(QItemSelectionRange(helper.tl, helper.br), QItemSelectionRange(dtl, dbr), true); + QT_TEST_EQUALITY_OPS(QItemSelectionRange(), QItemSelectionRange(), true); + QT_TEST_EQUALITY_OPS(QItemSelectionRange(helper.tl, helper.br), QItemSelectionRange(), false); } void tst_QItemSelectionModel::QTBUG58851_data() @@ -2742,6 +2758,7 @@ void tst_QItemSelectionModel::QTBUG58851_data() << IntPair(2, 3)); } +#if QT_CONFIG(proxymodel) void tst_QItemSelectionModel::QTBUG58851() { using IntPair = std::pair<int, int>; @@ -2786,6 +2803,7 @@ void tst_QItemSelectionModel::QTBUG58851() QVERIFY(selections.isSelected(i)); } } +#endif void tst_QItemSelectionModel::QTBUG18001_data() { @@ -2963,7 +2981,7 @@ void tst_QItemSelectionModel::destroyModel() selectionModel->setCurrentIndex(itemModel->index(1, 0), QItemSelectionModel::Select); QVERIFY(selectionModel->currentIndex().isValid()); - QTest::failOnWarning(QRegularExpression(".*")); + QTest::failOnWarning(); itemModel.reset(); QVERIFY(!selectionModel->currentIndex().isValid()); QVERIFY(selectionModel->selection().isEmpty()); diff --git a/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp b/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp index 5a06a4a605..0e027461aa 100644 --- a/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp +++ b/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp @@ -247,13 +247,16 @@ void tst_QSortFilterProxyModel::sort() QCOMPARE(m_proxy->data(index, Qt::DisplayRole).toString(), expected.at(row)); } - // restore the unsorted order - m_proxy->sort(-1); + // restore the unsorted order in the given order + m_proxy->sort(-1, sortOrder); - // make sure the proxy is unsorted again + // make sure the proxy is sorted by source row in the given order + int sourceIndex = sortOrder == Qt::AscendingOrder ? 0 : initial.size() - 1; + int adjustmentValue = sortOrder == Qt::AscendingOrder ? 1 : -1; for (int row = 0; row < m_proxy->rowCount(QModelIndex()); ++row) { QModelIndex index = m_proxy->index(row, 0, QModelIndex()); - QCOMPARE(m_proxy->data(index, Qt::DisplayRole).toString(), initial.at(row)); + QCOMPARE(m_proxy->data(index, Qt::DisplayRole).toString(), initial.at(sourceIndex)); + sourceIndex += adjustmentValue; } } diff --git a/tests/auto/corelib/kernel/qchronotimer/tst_qchronotimer.cpp b/tests/auto/corelib/kernel/qchronotimer/tst_qchronotimer.cpp index 62c402ae24..4711853c88 100644 --- a/tests/auto/corelib/kernel/qchronotimer/tst_qchronotimer.cpp +++ b/tests/auto/corelib/kernel/qchronotimer/tst_qchronotimer.cpp @@ -20,6 +20,10 @@ #include <qelapsedtimer.h> #include <qproperty.h> +#if defined(Q_OS_WIN32) +#include <qt_windows.h> +#endif + #if defined Q_OS_UNIX #include <unistd.h> #endif @@ -57,6 +61,7 @@ private slots: void recurringTimer(); void deleteLaterOnQChronoTimer(); // long name, don't want to shadow QObject::deleteLater() void moveToThread(); + void newTimerFiresTooSoon(); void restartedTimerFiresTooSoon(); void timerFiresOnlyOncePerProcessEvents_data(); void timerFiresOnlyOncePerProcessEvents(); @@ -619,6 +624,51 @@ void tst_QChronoTimer::moveToThread() QVERIFY((ti3.id() & 0xffffff) != (timer1.id() & 0xffffff)); } +class TimerListener : public QObject +{ + Q_OBJECT +public: + void timerEvent(QTimerEvent *) override + { + m_timerElapsed = true; + } + + bool m_timerElapsed = false; +}; + +void tst_QChronoTimer::newTimerFiresTooSoon() +{ +#ifndef Q_OS_WIN32 + QSKIP("Only relevant on Windows"); +#else + // Arrange - Create timer and make sure it ticked + { + QTest::qWait(0 /*ms*/); // Clean up event queue from previous tests + + TimerListener listener; + const int timerId = listener.startTimer(50ms, Qt::CoarseTimer); + QThread::sleep(100ms); + + // Force WM_TIMER events on Windows event queue + MSG msg{}; + PeekMessage(&msg, nullptr, WM_TIMER, WM_TIMER, PM_NOREMOVE); + + listener.killTimer(timerId); + } + + // Act - Create new timer with long interval and make sure it does not immediately tick + TimerListener listener; + const int timerId = listener.startTimer(60s, Qt::CoarseTimer); + + QTest::qWait(0 /*ms*/); // Process event queue - Should not call timerEvent + listener.killTimer(timerId); + + // Assert + QEXPECT_FAIL("", "QTBUG-124496 - QObject::timerEvent may be called before the timer elapsed", Continue); + QVERIFY(!listener.m_timerElapsed); +#endif +} + class RestartedTimerFiresTooSoonObject : public QObject { Q_OBJECT diff --git a/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp b/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp index 1271f53e57..8f8ab33e64 100644 --- a/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp +++ b/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp @@ -1041,7 +1041,7 @@ void tst_QCoreApplication::addRemoveLibPaths() static bool theMainThreadIsSet() { // QCoreApplicationPrivate::mainThread() has a Q_ASSERT we'd trigger - return QCoreApplicationPrivate::theMainThread.loadRelaxed() != nullptr; + return QCoreApplicationPrivate::theMainThreadId.loadRelaxed() != nullptr; } static bool theMainThreadWasUnset = !theMainThreadIsSet(); // global static @@ -1053,8 +1053,8 @@ void tst_QCoreApplication::theMainThread() int argc = 1; char *argv[] = { const_cast<char*>(QTest::currentAppName()) }; TestApplication app(argc, argv); - QVERIFY(QCoreApplicationPrivate::theMainThread.loadRelaxed()); - QCOMPARE(QCoreApplicationPrivate::theMainThread.loadRelaxed(), thread()); + QVERIFY(QCoreApplicationPrivate::theMainThreadId.loadRelaxed()); + QVERIFY(QThread::isMainThread()); QCOMPARE(app.thread(), thread()); QCOMPARE(app.thread(), QThread::currentThread()); } @@ -1067,7 +1067,7 @@ static void createQObjectOnDestruction() #if !defined(QT_QGUIAPPLICATIONTEST) && !defined(Q_OS_WIN) // QCoreApplicationData's global static destructor has run and cleaned up - // the QAdoptedThrad. + // the QAdoptedThread. if (theMainThreadIsSet()) qFatal("theMainThreadIsSet() returned true; some QObject must have leaked"); #endif @@ -1108,6 +1108,57 @@ void tst_QCoreApplication::testDeleteLaterFromBeforeOutermostEventLoop() QVERIFY(!spyPointer); } +void tst_QCoreApplication::setIndividualAttributes_data() +{ + QTest::addColumn<Qt::ApplicationAttribute>("attribute"); + + const QMetaEnum &metaEnum = Qt::staticMetaObject.enumerator(Qt::staticMetaObject.indexOfEnumerator("ApplicationAttribute")); + // - 1 to avoid AA_AttributeCount. + for (int i = 0; i < metaEnum.keyCount(); ++i) { + const auto attribute = static_cast<Qt::ApplicationAttribute>(metaEnum.value(i)); + if (attribute == Qt::AA_AttributeCount) + continue; + + QTest::addRow("%s", metaEnum.key(i)) << attribute; + } +} + +void tst_QCoreApplication::setIndividualAttributes() +{ + QFETCH(Qt::ApplicationAttribute, attribute); + + const auto originalValue = QCoreApplication::testAttribute(attribute); + auto cleanup = qScopeGuard([=]() { + QCoreApplication::setAttribute(attribute, originalValue); + }); + + QCoreApplication::setAttribute(attribute, true); + QVERIFY(QCoreApplication::testAttribute(attribute)); + + QCoreApplication::setAttribute(attribute, false); + QVERIFY(!QCoreApplication::testAttribute(attribute)); +} + +void tst_QCoreApplication::setMultipleAttributes() +{ + const auto originalDontUseNativeMenuWindowsValue = QCoreApplication::testAttribute(Qt::AA_DontUseNativeMenuWindows); + const auto originalDisableSessionManagerValue = QCoreApplication::testAttribute(Qt::AA_DisableSessionManager); + auto cleanup = qScopeGuard([=]() { + QCoreApplication::setAttribute(Qt::AA_DontUseNativeMenuWindows, originalDontUseNativeMenuWindowsValue); + QCoreApplication::setAttribute(Qt::AA_DisableSessionManager, originalDisableSessionManagerValue); + }); + + QCoreApplication::setAttribute(Qt::AA_DontUseNativeMenuWindows, true); + QCoreApplication::setAttribute(Qt::AA_DisableSessionManager, true); + QVERIFY(QCoreApplication::testAttribute(Qt::AA_DontUseNativeMenuWindows)); + QVERIFY(QCoreApplication::testAttribute(Qt::AA_DisableSessionManager)); + + QCoreApplication::setAttribute(Qt::AA_DontUseNativeMenuWindows, false); + QCoreApplication::setAttribute(Qt::AA_DisableSessionManager, false); + QVERIFY(!QCoreApplication::testAttribute(Qt::AA_DontUseNativeMenuWindows)); + QVERIFY(!QCoreApplication::testAttribute(Qt::AA_DisableSessionManager)); +} + #ifndef QT_QGUIAPPLICATIONTEST QTEST_APPLESS_MAIN(tst_QCoreApplication) #endif diff --git a/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.h b/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.h index 269b5d5bdb..1c25f63534 100644 --- a/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.h +++ b/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.h @@ -46,6 +46,9 @@ private slots: #endif void theMainThread(); void testDeleteLaterFromBeforeOutermostEventLoop(); + void setIndividualAttributes_data(); + void setIndividualAttributes(); + void setMultipleAttributes(); }; #endif // TST_QCOREAPPLICATION_H diff --git a/tests/auto/corelib/kernel/qdeadlinetimer/CMakeLists.txt b/tests/auto/corelib/kernel/qdeadlinetimer/CMakeLists.txt index 0c70b1d1a7..2031cd9d48 100644 --- a/tests/auto/corelib/kernel/qdeadlinetimer/CMakeLists.txt +++ b/tests/auto/corelib/kernel/qdeadlinetimer/CMakeLists.txt @@ -14,4 +14,6 @@ endif() qt_internal_add_test(tst_qdeadlinetimer SOURCES tst_qdeadlinetimer.cpp + LIBRARIES + Qt::TestPrivate ) diff --git a/tests/auto/corelib/kernel/qdeadlinetimer/tst_qdeadlinetimer.cpp b/tests/auto/corelib/kernel/qdeadlinetimer/tst_qdeadlinetimer.cpp index 19bea741f3..79416faaf9 100644 --- a/tests/auto/corelib/kernel/qdeadlinetimer/tst_qdeadlinetimer.cpp +++ b/tests/auto/corelib/kernel/qdeadlinetimer/tst_qdeadlinetimer.cpp @@ -6,6 +6,7 @@ #include <QtCore/QDeadlineTimer> #include <QtCore/QElapsedTimer> #include <QTest> +#include <QtTest/private/qcomparisontesthelper_p.h> #include <QTimer> #include <chrono> @@ -35,6 +36,7 @@ class tst_QDeadlineTimer : public QObject Q_OBJECT private Q_SLOTS: + void compareCompiles(); void basics(); void foreverness(); void current(); @@ -47,6 +49,11 @@ private Q_SLOTS: static constexpr auto timerType = Qt::PreciseTimer; +void tst_QDeadlineTimer::compareCompiles() +{ + QTestPrivate::testAllComparisonOperatorsCompile<QDeadlineTimer>(); +} + void tst_QDeadlineTimer::basics() { QDeadlineTimer deadline; @@ -65,6 +72,9 @@ void tst_QDeadlineTimer::basics() QCOMPARE_LE(deadline, deadline); QCOMPARE_GE(deadline, deadline); QVERIFY(!(deadline > deadline)); + QT_TEST_ALL_COMPARISON_OPS(deadline, QDeadlineTimer(timerType), Qt::strong_ordering::equal); + QT_TEST_ALL_COMPARISON_OPS(deadline, QDeadlineTimer(), Qt::strong_ordering::equal); + QT_TEST_ALL_COMPARISON_OPS(QDeadlineTimer(), QDeadlineTimer(), Qt::strong_ordering::equal); // should have expired, but we may be running too early after boot QTRY_VERIFY_WITH_TIMEOUT(deadline.hasExpired(), 100); @@ -167,6 +177,7 @@ void tst_QDeadlineTimer::foreverness() QCOMPARE_LE(deadline, deadline); QCOMPARE_GE(deadline, deadline); QVERIFY(!(deadline > deadline)); + QT_TEST_ALL_COMPARISON_OPS(deadline, deadline, Qt::strong_ordering::equal); // adding to forever must still be forever QDeadlineTimer deadline2 = deadline + 1; @@ -184,6 +195,7 @@ void tst_QDeadlineTimer::foreverness() QCOMPARE_LE(deadline2, deadline); QCOMPARE_GE(deadline2, deadline); QVERIFY(!(deadline2 > deadline)); + QT_TEST_ALL_COMPARISON_OPS(deadline2, deadline, Qt::strong_ordering::equal); // subtracting from forever is *also* forever deadline2 = deadline - 1; @@ -201,6 +213,7 @@ void tst_QDeadlineTimer::foreverness() QCOMPARE_LE(deadline2, deadline); QCOMPARE_GE(deadline2, deadline); QVERIFY(!(deadline2 > deadline)); + QT_TEST_ALL_COMPARISON_OPS(deadline2, deadline, Qt::strong_ordering::equal); // compare and order against a default-constructed object QDeadlineTimer expired; @@ -210,6 +223,7 @@ void tst_QDeadlineTimer::foreverness() QVERIFY(!(deadline <= expired)); QCOMPARE_GE(deadline, expired); QCOMPARE_GT(deadline, expired); + QT_TEST_EQUALITY_OPS(deadline, expired, false); } void tst_QDeadlineTimer::current() @@ -245,6 +259,7 @@ void tst_QDeadlineTimer::current() QCOMPARE_LE(earlierDeadline, deadline); QVERIFY(!(earlierDeadline >= deadline)); QVERIFY(!(earlierDeadline > deadline)); + QT_TEST_ALL_COMPARISON_OPS(earlierDeadline, deadline, Qt::strong_ordering::less); } void tst_QDeadlineTimer::deadlines() @@ -323,6 +338,7 @@ void tst_QDeadlineTimer::deadlines() QVERIFY(!(laterDeadline <= deadline)); QCOMPARE_GE(laterDeadline, deadline); QCOMPARE_GT(laterDeadline, deadline); + QT_TEST_ALL_COMPARISON_OPS(laterDeadline, deadline, Qt::strong_ordering::greater); // compare and order against a default-constructed object QDeadlineTimer expired; @@ -332,9 +348,11 @@ void tst_QDeadlineTimer::deadlines() QVERIFY(!(deadline <= expired)); QCOMPARE_GE(deadline, expired); QCOMPARE_GT(deadline, expired); + QT_TEST_EQUALITY_OPS(deadline, expired, false); // compare and order against a forever deadline QDeadlineTimer forever_(QDeadlineTimer::Forever); + QT_TEST_EQUALITY_OPS(deadline, forever_, false); QVERIFY(!(deadline == forever_)); QCOMPARE_NE(deadline, forever_); QCOMPARE_LT(deadline, forever_); @@ -601,12 +619,14 @@ void tst_QDeadlineTimer::stdchrono() QCOMPARE_LT(diff.count(), 3 * minResolution / 2); QDeadlineTimer dt_after(steady_after, timerType); QCOMPARE_LT(now, dt_after); + QT_TEST_ALL_COMPARISON_OPS(now, dt_after, Qt::strong_ordering::less); diff = duration_cast<milliseconds>(steady_deadline - steady_before); QCOMPARE_GT(diff.count(), minResolution / 2); QCOMPARE_LT(diff.count(), 3 * minResolution / 2); QDeadlineTimer dt_before(steady_before, timerType); QCOMPARE_GT(now, dt_before); + QT_TEST_ALL_COMPARISON_OPS(now, dt_before, Qt::strong_ordering::greater); } { auto diff = duration_cast<milliseconds>(system_after - system_deadline); @@ -614,12 +634,14 @@ void tst_QDeadlineTimer::stdchrono() QCOMPARE_LT(diff.count(), 3 * minResolution / 2); QDeadlineTimer dt_after(system_after, timerType); QCOMPARE_LT(now, dt_after); + QT_TEST_ALL_COMPARISON_OPS(now, dt_after, Qt::strong_ordering::less); diff = duration_cast<milliseconds>(system_deadline - system_before); QCOMPARE_GT(diff.count(), minResolution / 2); QCOMPARE_LT(diff.count(), 3 * minResolution / 2); QDeadlineTimer dt_before(system_before, timerType); QCOMPARE_GT(now, dt_before); + QT_TEST_ALL_COMPARISON_OPS(now, dt_before, Qt::strong_ordering::greater); } // make it regular @@ -654,6 +676,14 @@ void tst_QDeadlineTimer::stdchrono() QCOMPARE_LT(deadline, 5000000ns * minResolution); QCOMPARE_GE(deadline, steady_clock::now()); QCOMPARE_GE(deadline, system_clock::now()); + QT_TEST_ALL_COMPARISON_OPS(deadline, now + 3ms * minResolution, Qt::strong_ordering::greater); + QT_TEST_ALL_COMPARISON_OPS(deadline, now + 5ms * minResolution, Qt::strong_ordering::less); + QT_TEST_ALL_COMPARISON_OPS(deadline, now + 3000000ns * minResolution, Qt::strong_ordering::greater); + QT_TEST_ALL_COMPARISON_OPS(deadline, now + 5000000ns * minResolution, Qt::strong_ordering::less); + QT_TEST_ALL_COMPARISON_OPS(deadline, 3ms * minResolution, Qt::strong_ordering::greater); + QT_TEST_ALL_COMPARISON_OPS(deadline, 5ms * minResolution, Qt::strong_ordering::less); + QT_TEST_ALL_COMPARISON_OPS(deadline, steady_clock::now(), Qt::strong_ordering::greater); + QT_TEST_ALL_COMPARISON_OPS(deadline, system_clock::now(), Qt::strong_ordering::greater); now = QDeadlineTimer::current(timerType); deadline = QDeadlineTimer(1s, timerType); diff --git a/tests/auto/corelib/kernel/qelapsedtimer/CMakeLists.txt b/tests/auto/corelib/kernel/qelapsedtimer/CMakeLists.txt index 9a40a2f905..eccde38df2 100644 --- a/tests/auto/corelib/kernel/qelapsedtimer/CMakeLists.txt +++ b/tests/auto/corelib/kernel/qelapsedtimer/CMakeLists.txt @@ -14,4 +14,6 @@ endif() qt_internal_add_test(tst_qelapsedtimer SOURCES tst_qelapsedtimer.cpp + LIBRARIES + Qt::TestPrivate ) diff --git a/tests/auto/corelib/kernel/qelapsedtimer/tst_qelapsedtimer.cpp b/tests/auto/corelib/kernel/qelapsedtimer/tst_qelapsedtimer.cpp index 7623fd2e43..7a2b12b2eb 100644 --- a/tests/auto/corelib/kernel/qelapsedtimer/tst_qelapsedtimer.cpp +++ b/tests/auto/corelib/kernel/qelapsedtimer/tst_qelapsedtimer.cpp @@ -5,6 +5,7 @@ #include <QtCore/QString> #include <QtCore/QElapsedTimer> #include <QTest> +#include <QtTest/private/qcomparisontesthelper_p.h> #include <QTimer> static const int minResolution = 100; // the minimum resolution for the tests @@ -22,6 +23,7 @@ class tst_QElapsedTimer : public QObject Q_OBJECT private Q_SLOTS: + void compareCompiles(); void statics(); void validity(); void basics(); @@ -29,6 +31,11 @@ private Q_SLOTS: void msecsTo(); }; +void tst_QElapsedTimer::compareCompiles() +{ + QTestPrivate::testAllComparisonOperatorsCompile<QElapsedTimer>(); +} + void tst_QElapsedTimer::statics() { // these have been required since Qt 6.6 @@ -77,6 +84,7 @@ void tst_QElapsedTimer::basics() QVERIFY(!(t1 < t1)); QCOMPARE(t1.msecsTo(t1), qint64(0)); QCOMPARE(t1.secsTo(t1), qint64(0)); + QT_TEST_ALL_COMPARISON_OPS(t1, t1, Qt::strong_ordering::equal); quint64 value1 = t1.msecsSinceReference(); qDebug() << "value1:" << value1 << "t1:" << t1; @@ -141,10 +149,16 @@ void tst_QElapsedTimer::msecsTo() QTest::qSleep(minResolution); QElapsedTimer t2; t2.start(); - - QVERIFY(t1 != t2); - QVERIFY(!(t1 == t2)); - QVERIFY(t1 < t2); + QTest::qSleep(minResolution); + QElapsedTimer t3; + t3.start(); + + QT_TEST_EQUALITY_OPS(t1, t2, false); + QT_TEST_EQUALITY_OPS(QElapsedTimer(), QElapsedTimer(), true); + QT_TEST_EQUALITY_OPS(QElapsedTimer(), t2, false); + QT_TEST_ALL_COMPARISON_OPS(t1, t2, Qt::strong_ordering::less); + QT_TEST_ALL_COMPARISON_OPS(t3, t2, Qt::strong_ordering::greater); + QT_TEST_ALL_COMPARISON_OPS(t3, QElapsedTimer(), Qt::strong_ordering::greater); auto diff = t1.msecsTo(t2); QVERIFY2(diff > 0, QString("difference t1 and t2 is %1").arg(diff).toLatin1()); diff --git a/tests/auto/corelib/kernel/qjniarray/tst_qjniarray.cpp b/tests/auto/corelib/kernel/qjniarray/tst_qjniarray.cpp index b7b1f95b39..20dfcfd4d7 100644 --- a/tests/auto/corelib/kernel/qjniarray/tst_qjniarray.cpp +++ b/tests/auto/corelib/kernel/qjniarray/tst_qjniarray.cpp @@ -81,6 +81,7 @@ VERIFY_RETURN_FOR_TYPE(QJniArray<List>, QJniArray<List>); void tst_QJniArray::construct() { + // explicit { QStringList strings; for (int i = 0; i < 10000; ++i) @@ -89,13 +90,36 @@ void tst_QJniArray::construct() QCOMPARE(list.size(), 10000); } { - QJniArray<jint> list{1, 2, 3}; + QJniArray bytes = QJniArrayBase::fromContainer(QByteArray("abc")); + static_assert(std::is_same_v<decltype(bytes)::value_type, jbyte>); + QCOMPARE(bytes.size(), 3); + } + { + QJniArray list{1, 2, 3}; + static_assert(std::is_same_v<decltype(list), QJniArray<int>>); QCOMPARE(list.size(), 3); + list = {4, 5}; + QCOMPARE(list.size(), 2); } { QJniArray<jint> list(QList<int>{1, 2, 3}); QCOMPARE(list.size(), 3); } + // CTAD with deduction guide + { + QJniArray list(QList<int>{1, 2, 3}); + QCOMPARE(list.size(), 3); + } + { + QJniArray bytes(QByteArray("abc")); + static_assert(std::is_same_v<decltype(bytes)::value_type, jbyte>); + QCOMPARE(bytes.size(), 3); + } + { + QStringList strings{"a", "b", "c"}; + QJniArray list(strings); + QCOMPARE(list.size(), 3); + } { QJniArray<jint> list{QList<int>{1, 2, 3}}; QCOMPARE(list.size(), 3); @@ -110,7 +134,7 @@ void tst_QJniArray::size() QList<int> intList; intList.resize(10); - auto intArray = QJniArrayBase::fromContainer(intList); + auto intArray = QJniArray(intList); QCOMPARE(intArray.size(), 10); } diff --git a/tests/auto/corelib/kernel/qjniobject/testdata/src/org/qtproject/qt/android/testdata/QtJniObjectTestClass.java b/tests/auto/corelib/kernel/qjniobject/testdata/src/org/qtproject/qt/android/testdata/QtJniObjectTestClass.java index faa33a6bac..07a94d1cac 100644 --- a/tests/auto/corelib/kernel/qjniobject/testdata/src/org/qtproject/qt/android/testdata/QtJniObjectTestClass.java +++ b/tests/auto/corelib/kernel/qjniobject/testdata/src/org/qtproject/qt/android/testdata/QtJniObjectTestClass.java @@ -334,4 +334,12 @@ public class QtJniObjectTestClass { return callbackWithStringList(value); } + + public Object callMethodThrowsException() throws Exception { + throw new Exception(); + } + + public static Object callStaticMethodThrowsException() throws Exception { + throw new Exception(); + } } diff --git a/tests/auto/corelib/kernel/qjniobject/tst_qjniobject.cpp b/tests/auto/corelib/kernel/qjniobject/tst_qjniobject.cpp index 0b01e4a10f..196874b6a5 100644 --- a/tests/auto/corelib/kernel/qjniobject/tst_qjniobject.cpp +++ b/tests/auto/corelib/kernel/qjniobject/tst_qjniobject.cpp @@ -40,10 +40,12 @@ private slots: void ctor(); void callMethodTest(); + void callMethodThrowsException(); void callObjectMethodTest(); void stringConvertionTest(); void compareOperatorTests(); void className(); + void callStaticMethodThrowsException(); void callStaticObjectMethodClassName(); void callStaticObjectMethod(); void callStaticObjectMethodById(); @@ -262,6 +264,15 @@ void tst_QJniObject::callMethodTest() } } +void tst_QJniObject::callMethodThrowsException() +{ + QtJniTypes::QtJniObjectTestClass instance; + QTest::ignoreMessage(QtWarningMsg, QRegularExpression("java.lang.Exception")); + auto res = instance.callMethod<jobject>("callMethodThrowsException"); + QVERIFY(!res.isValid()); + QVERIFY(!QJniEnvironment().checkAndClearExceptions()); +} + void tst_QJniObject::callObjectMethodTest() { const QString qString = QLatin1String("Hello, Java"); @@ -339,6 +350,15 @@ void tst_QJniObject::className() } } +void tst_QJniObject::callStaticMethodThrowsException() +{ + QTest::ignoreMessage(QtWarningMsg, QRegularExpression("java.lang.Exception")); + auto res = QtJniTypes::QtJniObjectTestClass::callStaticMethod<jobject>( + "callStaticMethodThrowsException"); + QVERIFY(!res.isValid()); + QVERIFY(!QJniEnvironment().checkAndClearExceptions()); +} + void tst_QJniObject::callStaticObjectMethodClassName() { QJniObject formatString = QJniObject::fromString(QLatin1String("test format")); @@ -1607,7 +1627,7 @@ void tst_QJniObject::templateApiCheck() QCOMPARE(array.size(), 3); QCOMPARE(array.toContainer(), "abc"); - QJniArray<jbyte> newArray = QJniArrayBase::fromContainer(QByteArray{"cba"}); + QJniArray newArray = QJniArray(QByteArray{"cba"}); QVERIFY(newArray.isValid()); const auto reverse = testClass.callMethod<jbyte[]>("reverseByteArray", newArray); QVERIFY(reverse.isValid()); diff --git a/tests/auto/corelib/kernel/qmetacontainer/CMakeLists.txt b/tests/auto/corelib/kernel/qmetacontainer/CMakeLists.txt index a9ebcdf72f..fb58aebe73 100644 --- a/tests/auto/corelib/kernel/qmetacontainer/CMakeLists.txt +++ b/tests/auto/corelib/kernel/qmetacontainer/CMakeLists.txt @@ -16,4 +16,5 @@ qt_internal_add_test(tst_qmetacontainer tst_qmetacontainer.cpp LIBRARIES Qt::CorePrivate + Qt::TestPrivate ) diff --git a/tests/auto/corelib/kernel/qmetacontainer/tst_qmetacontainer.cpp b/tests/auto/corelib/kernel/qmetacontainer/tst_qmetacontainer.cpp index dff2176a11..cc1d8baa8e 100644 --- a/tests/auto/corelib/kernel/qmetacontainer/tst_qmetacontainer.cpp +++ b/tests/auto/corelib/kernel/qmetacontainer/tst_qmetacontainer.cpp @@ -2,6 +2,7 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QtTest/qtest.h> +#include <QtTest/private/qcomparisontesthelper_p.h> #include <QtCore/qcontainerinfo.h> #include <QtCore/qmetacontainer.h> #include <QtCore/QMap> @@ -157,6 +158,7 @@ private: private slots: void init(); + void compareCompiles(); void testSequence_data(); void testSequence(); @@ -203,6 +205,12 @@ void tst_QMetaContainer::init() }; } +void tst_QMetaContainer::compareCompiles() +{ + QTestPrivate::testEqualityOperatorsCompile<QMetaSequence>(); + QTestPrivate::testEqualityOperatorsCompile<QMetaAssociation>(); +} + void tst_QMetaContainer::cleanup() { qvector.clear(); @@ -501,6 +509,9 @@ void tst_QMetaContainer::testSequence() QVERIFY(metaSequence.iface() != nullptr); QMetaSequence defaultConstructed; QVERIFY(defaultConstructed.iface() == nullptr); + QT_TEST_EQUALITY_OPS(QMetaSequence(), defaultConstructed, true); + QT_TEST_EQUALITY_OPS(QMetaSequence(), QMetaSequence(), true); + QT_TEST_EQUALITY_OPS(defaultConstructed, metaSequence, false); } void tst_QMetaContainer::testAssociation_data() @@ -728,8 +739,10 @@ void tst_QMetaContainer::testAssociation() metaAssociation.destroyConstIterator(constEnd); QVERIFY(metaAssociation.iface() != nullptr); - QMetaSequence defaultConstructed; + QMetaAssociation defaultConstructed; QVERIFY(defaultConstructed.iface() == nullptr); + QT_TEST_EQUALITY_OPS(QMetaAssociation(), QMetaAssociation(), true); + QT_TEST_EQUALITY_OPS(QMetaAssociation(), metaAssociation, false); } QTEST_MAIN(tst_QMetaContainer) diff --git a/tests/auto/corelib/kernel/qmetamethod/CMakeLists.txt b/tests/auto/corelib/kernel/qmetamethod/CMakeLists.txt index 29a6e3c64b..0d46aef8bd 100644 --- a/tests/auto/corelib/kernel/qmetamethod/CMakeLists.txt +++ b/tests/auto/corelib/kernel/qmetamethod/CMakeLists.txt @@ -14,4 +14,6 @@ endif() qt_internal_add_test(tst_qmetamethod SOURCES tst_qmetamethod.cpp + LIBRARIES + Qt::TestPrivate ) diff --git a/tests/auto/corelib/kernel/qmetamethod/tst_qmetamethod.cpp b/tests/auto/corelib/kernel/qmetamethod/tst_qmetamethod.cpp index 47012f9a28..59fb747524 100644 --- a/tests/auto/corelib/kernel/qmetamethod/tst_qmetamethod.cpp +++ b/tests/auto/corelib/kernel/qmetamethod/tst_qmetamethod.cpp @@ -4,6 +4,7 @@ #include <QTest> +#include <QtTest/private/qcomparisontesthelper_p.h> #include <QTypeRevision> #include <qobject.h> @@ -14,6 +15,7 @@ class tst_QMetaMethod : public QObject Q_OBJECT private slots: + void compareCompiles(); void method_data(); void method(); @@ -166,6 +168,11 @@ QVariant MethodTestObject::qvariantSlotBoolIntUIntLonglongULonglongDoubleLongSho } void MethodTestObject::voidSlotNoParameterNames(bool, int) {} +void tst_QMetaMethod::compareCompiles() +{ + QTestPrivate::testEqualityOperatorsCompile<QMetaMethod>(); +} + void tst_QMetaMethod::method_data() { QTest::addColumn<QByteArray>("signature"); @@ -647,6 +654,8 @@ void tst_QMetaMethod::method() // Bogus indexes QCOMPARE(method.parameterType(-1), 0); QCOMPARE(method.parameterType(parameterTypes.size()), 0); + QT_TEST_EQUALITY_OPS(method, QMetaMethod(), false); + QT_TEST_EQUALITY_OPS(QMetaMethod(), QMetaMethod(), true); } void tst_QMetaMethod::invalidMethod() @@ -659,6 +668,9 @@ void tst_QMetaMethod::invalidMethod() QMetaMethod method3 = staticMetaObject.method(-1); QVERIFY(!method3.isValid()); + QT_TEST_EQUALITY_OPS(method, method2, true); + QT_TEST_EQUALITY_OPS(method2, method3, true); + QT_TEST_EQUALITY_OPS(method, method3, true); } void tst_QMetaMethod::comparisonOperators() @@ -673,16 +685,9 @@ void tst_QMetaMethod::comparisonOperators() QMetaMethod other = x ? mo->constructor(j) : mo->method(j); bool expectedEqual = ((methodMo == other.enclosingMetaObject()) && (i == j)); - QCOMPARE(method == other, expectedEqual); - QCOMPARE(method != other, !expectedEqual); - QCOMPARE(other == method, expectedEqual); - QCOMPARE(other != method, !expectedEqual); + QT_TEST_EQUALITY_OPS(method, other, expectedEqual); } - - QVERIFY(method != QMetaMethod()); - QVERIFY(QMetaMethod() != method); - QVERIFY(!(method == QMetaMethod())); - QVERIFY(!(QMetaMethod() == method)); + QT_TEST_EQUALITY_OPS(method, QMetaMethod(), false); } } @@ -691,8 +696,7 @@ void tst_QMetaMethod::comparisonOperators() for (int i = 0; i < qMin(mo->methodCount(), mo->constructorCount()); ++i) { QMetaMethod method = mo->method(i); QMetaMethod constructor = mo->constructor(i); - QVERIFY(method != constructor); - QVERIFY(!(method == constructor)); + QT_TEST_EQUALITY_OPS(method, constructor, false); } } @@ -748,6 +752,7 @@ void tst_QMetaMethod::gadget() QMetaMethod getValueMethod = MyGadget::staticMetaObject.method(idx); QVERIFY(getValueMethod.isValid()); + QT_TEST_EQUALITY_OPS(setValueMethod, getValueMethod, false); { MyGadget gadget; QString string; diff --git a/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp b/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp index ee13c32353..182ec6daae 100644 --- a/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp +++ b/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp @@ -3,11 +3,15 @@ #include <QTest> #include <QSignalSpy> +#if QT_CONFIG(sortfilterproxymodel) #include <QSortFilterProxyModel> +#endif #include <qobject.h> #include <qmetaobject.h> +#if QT_CONFIG(proxymodel) #include <qabstractproxymodel.h> +#endif #include <private/qmetaobject_p.h> Q_DECLARE_METATYPE(const QMetaObject *) @@ -1906,6 +1910,7 @@ void tst_QMetaObject::invokeBlockingQueuedPointer() void tst_QMetaObject::qtMetaObjectInheritance() { QVERIFY(!QObject::staticMetaObject.superClass()); +#if QT_CONFIG(sortfilterproxymodel) QCOMPARE(QSortFilterProxyModel::staticMetaObject.indexOfEnumerator("Qt::CaseSensitivity"), -1); QCOMPARE(QSortFilterProxyModel::staticMetaObject.indexOfEnumerator("CaseSensitivity"), -1); int indexOfSortCaseSensitivity = QSortFilterProxyModel::staticMetaObject.indexOfProperty("sortCaseSensitivity"); @@ -1913,6 +1918,7 @@ void tst_QMetaObject::qtMetaObjectInheritance() QMetaProperty sortCaseSensitivity = QSortFilterProxyModel::staticMetaObject.property(indexOfSortCaseSensitivity); QVERIFY(sortCaseSensitivity.isValid()); QCOMPARE(sortCaseSensitivity.enumerator().name(), "CaseSensitivity"); +#endif } struct MyType @@ -2515,7 +2521,9 @@ void tst_QMetaObject::metaType() { QCOMPARE(QObject::staticMetaObject.metaType(), QMetaType::fromType<QObject>()); QCOMPARE(MyGadget::staticMetaObject.metaType(), QMetaType::fromType<MyGadget>()); +#if QT_CONFIG(proxymodel) QCOMPARE(QAbstractProxyModel::staticMetaObject.metaType(), QMetaType::fromType<QAbstractProxyModel>()); +#endif auto qtNameSpaceMetaType = Qt::staticMetaObject.metaType(); QVERIFY2(!qtNameSpaceMetaType.isValid(), qtNameSpaceMetaType.name()); } diff --git a/tests/auto/corelib/kernel/qmetaproperty/tst_qmetaproperty.cpp b/tests/auto/corelib/kernel/qmetaproperty/tst_qmetaproperty.cpp index c8053ca43a..3bf6211a53 100644 --- a/tests/auto/corelib/kernel/qmetaproperty/tst_qmetaproperty.cpp +++ b/tests/auto/corelib/kernel/qmetaproperty/tst_qmetaproperty.cpp @@ -170,11 +170,55 @@ public: {} }; +enum FreeEnum { + FreeEnumValue1, + FreeEnumValue2 +}; + +namespace MySpace { + enum NamespacedEnum { + NamespacedEnumValue1, + NamespacedEnumValue2 + }; +}; + +namespace MyQtSpace { + Q_NAMESPACE + enum NamespacedEnum { + NamespacedEnumValue1, + NamespacedEnumValue2 + }; + Q_DECLARE_FLAGS(NamespacedFlags, NamespacedEnum) + Q_FLAG_NS(NamespacedFlags) +}; + +namespace SeparateEnumNamespace { + Q_NAMESPACE + enum Enum { + Value1, + Value2 + }; + Q_ENUM_NS(Enum) +}; +namespace SeparateFlagsNamespace { + Q_NAMESPACE + Q_DECLARE_FLAGS(Flags, SeparateEnumNamespace::Enum) + Q_FLAG_NS(Flags) +} + class EnumFlagsTester : public QObject { Q_OBJECT Q_PROPERTY(TestEnum enumProperty READ enumProperty WRITE setEnumProperty) Q_PROPERTY(TestFlags flagProperty READ flagProperty WRITE setFlagProperty) + + Q_PROPERTY(FreeEnum freeEnumProperty READ freeEnumProperty WRITE setFreeEnumProperty) + Q_PROPERTY(MySpace::NamespacedEnum namespacedEnumProperty READ namespacedEnumProperty WRITE setNamespacedEnumProperty) + Q_PROPERTY(MyQtSpace::NamespacedEnum qtNamespacedEnumProperty READ qtNamespacedEnumProperty WRITE setQtNamespacedEnumProperty) + Q_PROPERTY(MyQtSpace::NamespacedFlags qtNamespacedFlagProperty READ qtNamespacedFlagProperty WRITE setQtNamespacedFlagProperty) + + Q_PROPERTY(SeparateEnumNamespace::Enum sepEnum READ sepEnum WRITE setSepEnum) + Q_PROPERTY(SeparateFlagsNamespace::Flags sepFlags READ sepFlags WRITE setSepFlags) public: enum TestEnum { e1, e2 }; Q_ENUM(TestEnum) @@ -190,9 +234,35 @@ public: TestFlags flagProperty() const { return m_flags; } void setFlagProperty(TestFlags f) { m_flags = f; } + FreeEnum freeEnumProperty() const { return m_freeEnum; } + void setFreeEnumProperty(FreeEnum e) { m_freeEnum = e; } + + MySpace::NamespacedEnum namespacedEnumProperty() const { return m_namespacedEnum; } + void setNamespacedEnumProperty(MySpace::NamespacedEnum e) { m_namespacedEnum = e; } + + MyQtSpace::NamespacedEnum qtNamespacedEnumProperty() const { return m_qtNamespaceEnum; } + void setQtNamespacedEnumProperty(MyQtSpace::NamespacedEnum e) { m_qtNamespaceEnum = e; } + + MyQtSpace::NamespacedFlags qtNamespacedFlagProperty() const { return m_qtNamespaceFlags; } + void setQtNamespacedFlagProperty(MyQtSpace::NamespacedFlags f) { m_qtNamespaceFlags = f; } + + SeparateEnumNamespace::Enum sepEnum() const { return m_sepEnum; } + void setSepEnum(SeparateEnumNamespace::Enum e) { m_sepEnum = e; } + + SeparateFlagsNamespace::Flags sepFlags() const { return m_sepFlags; } + void setSepFlags(SeparateFlagsNamespace::Flags f) { m_sepFlags = f; } + private: TestEnum m_enum = e1; TestFlags m_flags; + + FreeEnum m_freeEnum = FreeEnum::FreeEnumValue1; + MySpace::NamespacedEnum m_namespacedEnum = MySpace::NamespacedEnumValue1; + MyQtSpace::NamespacedEnum m_qtNamespaceEnum = MyQtSpace::NamespacedEnumValue1; + MyQtSpace::NamespacedFlags m_qtNamespaceFlags; + + SeparateEnumNamespace::Enum m_sepEnum = SeparateEnumNamespace::Value1; + SeparateFlagsNamespace::Flags m_sepFlags; }; Q_DECLARE_OPERATORS_FOR_FLAGS(EnumFlagsTester::TestFlags) @@ -265,7 +335,7 @@ void tst_QMetaProperty::conversion() void tst_QMetaProperty::enumsFlags() { // QTBUG-83689, verify that enumerations and flags can be assigned from int, - // which is important for Qt Designer. + // which is important for Qt Widgets Designer. EnumFlagsTester t; auto mo = t.metaObject(); @@ -276,6 +346,7 @@ void tst_QMetaProperty::enumsFlags() QVERIFY(enumProperty.metaType().flags().testFlag(QMetaType::IsEnumeration)); QVERIFY(enumProperty.write(&t, QVariant(int(EnumFlagsTester::e2)))); QCOMPARE(t.enumProperty(), EnumFlagsTester::e2); + QVERIFY(enumProperty.enumerator().isValid()); // OK: Q_ENUM const int flagsIndex = mo->indexOfProperty("flagProperty"); QVERIFY(flagsIndex >= 0); @@ -283,6 +354,55 @@ void tst_QMetaProperty::enumsFlags() QVERIFY(flagsProperty.metaType().flags().testFlag(QMetaType::IsEnumeration)); QVERIFY(flagsProperty.write(&t, QVariant(int(EnumFlagsTester::flag2)))); QCOMPARE(t.flagProperty(), EnumFlagsTester::flag2); + QVERIFY(!flagsProperty.enumerator().isValid()); // Not using Q_FLAG + + const int freeEnumIndex = mo->indexOfProperty("freeEnumProperty"); + QVERIFY(freeEnumIndex >= 0); + auto freeEnumProperty = mo->property(freeEnumIndex); + QVERIFY(freeEnumProperty.metaType().flags().testFlag(QMetaType::IsEnumeration)); + QVERIFY(freeEnumProperty.write(&t, QVariant(FreeEnumValue2))); + QCOMPARE(t.freeEnumProperty(), FreeEnumValue2); + QVERIFY(!freeEnumProperty.enumerator().isValid()); // Not using Q_ENUM + + const int namespacedEnumIndex = mo->indexOfProperty("namespacedEnumProperty"); + QVERIFY(namespacedEnumIndex >= 0); + auto namespacedEnumProperty = mo->property(namespacedEnumIndex); + QVERIFY(namespacedEnumProperty.metaType().flags().testFlag(QMetaType::IsEnumeration)); + QVERIFY(namespacedEnumProperty.write(&t, QVariant(MySpace::NamespacedEnumValue2))); + QCOMPARE(t.namespacedEnumProperty(), MySpace::NamespacedEnumValue2); + QVERIFY(!namespacedEnumProperty.enumerator().isValid()); // Not using Q_NAMESPACE/Q_ENUM_NS + + const int qtNamespacedEnumIndex = mo->indexOfProperty("qtNamespacedEnumProperty"); + QVERIFY(qtNamespacedEnumIndex >= 0); + auto qtNamespacedEnumProperty = mo->property(qtNamespacedEnumIndex); + QVERIFY(qtNamespacedEnumProperty.metaType().flags().testFlag(QMetaType::IsEnumeration)); + QVERIFY(qtNamespacedEnumProperty.write(&t, QVariant(MyQtSpace::NamespacedEnumValue2))); + QCOMPARE(t.qtNamespacedEnumProperty(), MyQtSpace::NamespacedEnumValue2); + QVERIFY(qtNamespacedEnumProperty.enumerator().isValid()); // OK: Q_ENUM_NS + + const int qtNamespacedFlagIndex = mo->indexOfProperty("qtNamespacedFlagProperty"); + QVERIFY(qtNamespacedFlagIndex >= 0); + auto qtNamespacedFlagProperty = mo->property(qtNamespacedFlagIndex); + QVERIFY(qtNamespacedFlagProperty.metaType().flags().testFlag(QMetaType::IsEnumeration)); + QVERIFY(qtNamespacedFlagProperty.write(&t, QVariant(MyQtSpace::NamespacedFlags(MyQtSpace::NamespacedEnumValue2)))); + QCOMPARE(t.qtNamespacedFlagProperty(), MyQtSpace::NamespacedFlags(MyQtSpace::NamespacedEnumValue2)); + QVERIFY(qtNamespacedFlagProperty.enumerator().isValid()); // OK: Q_FLAG + + const int sepEnumIndex = mo->indexOfProperty("sepEnum"); + QVERIFY(sepEnumIndex >= 0); + auto sepEnumProperty = mo->property(sepEnumIndex); + QVERIFY(sepEnumProperty.metaType().flags().testFlag(QMetaType::IsEnumeration)); + QVERIFY(sepEnumProperty.write(&t, QVariant(SeparateEnumNamespace::Value2))); + QCOMPARE(t.sepEnum(), SeparateEnumNamespace::Value2); + QVERIFY(sepEnumProperty.enumerator().isValid()); // OK: Q_ENUM_NS + + const int sepFlagsIndex = mo->indexOfProperty("sepFlags"); + QVERIFY(sepFlagsIndex >= 0); + auto sepFlagsProperty = mo->property(sepFlagsIndex); + QVERIFY(sepFlagsProperty.metaType().flags().testFlag(QMetaType::IsEnumeration)); + QVERIFY(sepFlagsProperty.write(&t, QVariant(SeparateEnumNamespace::Value1))); + QCOMPARE(t.sepFlags(), SeparateEnumNamespace::Value1); + QVERIFY(!sepFlagsProperty.enumerator().isValid()); // NOK: the meta object is empty } diff --git a/tests/auto/corelib/kernel/qmetatype/CMakeLists.txt b/tests/auto/corelib/kernel/qmetatype/CMakeLists.txt index b93d961109..65bec3e187 100644 --- a/tests/auto/corelib/kernel/qmetatype/CMakeLists.txt +++ b/tests/auto/corelib/kernel/qmetatype/CMakeLists.txt @@ -51,6 +51,7 @@ qt_internal_add_test(tst_qmetatype ../../../other/qvariant_common LIBRARIES Qt::CorePrivate + Qt::TestPrivate Qt::Gui qmetatype_lib1 qmetatype_lib2 diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.h b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.h index 1694e49491..bcd2fe2def 100644 --- a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.h +++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.h @@ -111,6 +111,7 @@ private slots: void customDebugStream(); void unknownType(); void fromType(); + void compareCompiles(); void operatorEq_data(); void operatorEq(); void operatorEq2_data(); diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype2.cpp b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype2.cpp index 68bcb53056..661c1f6072 100644 --- a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype2.cpp +++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype2.cpp @@ -5,6 +5,7 @@ #include "tst_qmetatype_libs.h" #include <QtCore/private/qmetaobjectbuilder_p.h> +#include <QtTest/private/qcomparisontesthelper_p.h> void tst_QMetaType::constRefs() { @@ -418,6 +419,11 @@ struct CharTemplate } y; }; +void tst_QMetaType::compareCompiles() +{ + QTestPrivate::testEqualityOperatorsCompile<QMetaType>(); +} + void tst_QMetaType::operatorEq_data() { QTest::addColumn<QMetaType>("typeA"); @@ -447,10 +453,7 @@ void tst_QMetaType::operatorEq() QFETCH(QMetaType, typeB); QFETCH(bool, eq); - QCOMPARE(typeA == typeB, eq); - QCOMPARE(typeB == typeA, eq); - QCOMPARE(typeA != typeB, !eq); - QCOMPARE(typeB != typeA, !eq); + QT_TEST_EQUALITY_OPS(typeA, typeB, eq); #if !defined(Q_OS_WIN) && !defined(Q_OS_INTEGRITY) // for built-in types or locally-defined types, this must also hold true @@ -487,10 +490,10 @@ FOR_EACH_CORE_METATYPE(GET_METATYPE_FROM_TYPE) QCOMPARE(fromId2.id(), type); // confirm that they're all equal - QCOMPARE(fromId1, fromId2); - QCOMPARE(fromType1, fromType2); - QCOMPARE(fromType1, fromId1); - QCOMPARE(fromType2, fromId2); + QT_TEST_EQUALITY_OPS(fromId1, fromId2, true); + QT_TEST_EQUALITY_OPS(fromType1, fromType2, true); + QT_TEST_EQUALITY_OPS(fromType1, fromId1, true); + QT_TEST_EQUALITY_OPS(fromType2, fromId2, true); #if !defined(Q_OS_WIN) && !defined(Q_OS_INTEGRITY) // for built-in types (other than void), this must be true @@ -541,7 +544,7 @@ void tst_QMetaType::operatorEqAcrossLibs() // DO THIS FIRST: // if this isn't a built-in type, then the QMetaTypeInterface::typeId is // initially set to 0 - QCOMPARE(lib1Type, lib2Type); + QT_TEST_EQUALITY_OPS(lib1Type, lib2Type, true); int actualTypeId = localType.id(); bool builtinTypeExpected = builtinTypeId != QMetaType::UnknownType; @@ -559,8 +562,8 @@ void tst_QMetaType::operatorEqAcrossLibs() QCOMPARE(lib2Type.id(), actualTypeId); QCOMPARE(QByteArray(lib1Type.name()), QByteArray(localType.name())); QCOMPARE(QByteArray(lib2Type.name()), QByteArray(localType.name())); - QCOMPARE(lib1Type, localType); - QCOMPARE(lib2Type, localType); + QT_TEST_EQUALITY_OPS(lib1Type, localType, true); + QT_TEST_EQUALITY_OPS(lib2Type, localType, true); #if !defined(Q_OS_WIN) && !defined(Q_OS_INTEGRITY) if (actualTypeId < QMetaType::FirstGuiType && actualTypeId != QMetaType::Void) { diff --git a/tests/auto/corelib/kernel/qmimedata/tst_qmimedata.cpp b/tests/auto/corelib/kernel/qmimedata/tst_qmimedata.cpp index c9c8734353..e28a2e98cc 100644 --- a/tests/auto/corelib/kernel/qmimedata/tst_qmimedata.cpp +++ b/tests/auto/corelib/kernel/qmimedata/tst_qmimedata.cpp @@ -85,6 +85,14 @@ void tst_QMimeData::data() const QCOMPARE(mimeData.data("text/markdown"), QByteArray("vikings")); QCOMPARE(mimeData.data("text/html"), QByteArray("ninjas")); QCOMPARE(mimeData.data("text/plain"), QByteArray("pirates")); + + // URI list + QByteArray list = "https://example.com/\r\nhttps://example.net/\r\nhttps://example.org/\r\n"; + mimeData.setData("text/uri-list", list); + QCOMPARE(mimeData.data("text/uri-list"), list); + + mimeData.setData("text/uri-list", list.chopped(2)); // without the ending CRLF + QCOMPARE(mimeData.data("text/uri-list"), list); } void tst_QMimeData::formats() const diff --git a/tests/auto/corelib/kernel/qpointer/CMakeLists.txt b/tests/auto/corelib/kernel/qpointer/CMakeLists.txt index b1570b8cef..0b2c4b7e45 100644 --- a/tests/auto/corelib/kernel/qpointer/CMakeLists.txt +++ b/tests/auto/corelib/kernel/qpointer/CMakeLists.txt @@ -20,6 +20,7 @@ qt_internal_add_test(tst_qpointer tst_qpointer.cpp LIBRARIES Qt::Gui + Qt::TestPrivate ) ## Scopes: diff --git a/tests/auto/corelib/kernel/qpointer/tst_qpointer.cpp b/tests/auto/corelib/kernel/qpointer/tst_qpointer.cpp index 7365fee819..b88f1b5b0f 100644 --- a/tests/auto/corelib/kernel/qpointer/tst_qpointer.cpp +++ b/tests/auto/corelib/kernel/qpointer/tst_qpointer.cpp @@ -2,6 +2,7 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QTest> +#include <QtTest/private/qcomparisontesthelper_p.h> #include <QRunnable> #include <QThreadPool> @@ -23,6 +24,7 @@ private slots: void conversion(); void destructor(); void assignment_operators(); + void compareCompiles(); void equality_operators(); void swap(); void isNull(); @@ -203,12 +205,21 @@ void tst_QPointer::assignment_operators() delete object; } +void tst_QPointer::compareCompiles() +{ + QTestPrivate::testEqualityOperatorsCompile<QPointer<QObject>>(); + QTestPrivate::testEqualityOperatorsCompile<QPointer<QObject>, QObject*>(); + QTestPrivate::testEqualityOperatorsCompile<QPointer<QObject>, QWidget*>(); + QTestPrivate::testEqualityOperatorsCompile<QPointer<QObject>, QPointer<QWidget>>(); + QTestPrivate::testEqualityOperatorsCompile<QPointer<QObject>, std::nullptr_t>(); +} + void tst_QPointer::equality_operators() { QPointer<QObject> p1; QPointer<QObject> p2; - QVERIFY(p1 == p2); + QT_TEST_EQUALITY_OPS(p1, p2, true); QObject *object = nullptr; #ifndef QT_NO_WIDGETS @@ -216,16 +227,15 @@ void tst_QPointer::equality_operators() #endif p1 = object; - QVERIFY(p1 == p2); - QVERIFY(p1 == object); + QT_TEST_EQUALITY_OPS(p1, p2, true); + QT_TEST_EQUALITY_OPS(p1, object, true); p2 = object; - QVERIFY(p2 == p1); - QVERIFY(p2 == object); - + QT_TEST_EQUALITY_OPS(p2, p1, true); + QT_TEST_EQUALITY_OPS(p2, object, true); p1 = this; - QVERIFY(p1 != p2); + QT_TEST_EQUALITY_OPS(p1, p2, false); p2 = p1; - QVERIFY(p1 == p2); + QT_TEST_EQUALITY_OPS(p1, p2, true); // compare to zero p1 = nullptr; @@ -233,19 +243,13 @@ void tst_QPointer::equality_operators() QVERIFY(0 == p1); QVERIFY(p2 != 0); QVERIFY(0 != p2); - QVERIFY(p1 == nullptr); - QVERIFY(nullptr == p1); - QVERIFY(p2 != nullptr); - QVERIFY(nullptr != p2); - QVERIFY(p1 == object); - QVERIFY(object == p1); - QVERIFY(p2 != object); - QVERIFY(object != p2); + QT_TEST_EQUALITY_OPS(p1, nullptr, true); + QT_TEST_EQUALITY_OPS(p2, nullptr, false); + QT_TEST_EQUALITY_OPS(p1, object, true); + QT_TEST_EQUALITY_OPS(p2, object, false); #ifndef QT_NO_WIDGETS - QVERIFY(p1 == widget); - QVERIFY(widget == p1); - QVERIFY(p2 != widget); - QVERIFY(widget != p2); + QT_TEST_EQUALITY_OPS(p1, widget, true); + QT_TEST_EQUALITY_OPS(p2, widget, false); #endif } diff --git a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp index 75907ec062..d79e0e82f8 100644 --- a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp +++ b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp @@ -5,6 +5,8 @@ #include <qvariant.h> +#include <QtCore/qttypetraits.h> + // don't assume <type_traits> template <typename T, typename U> constexpr inline bool my_is_same_v = false; @@ -544,6 +546,9 @@ void tst_QVariant::isNull() var3 = QVariant(QMetaType::fromType<QString>()); QVERIFY( var3.isNull() ); + var3.setValue(QString()); + QVERIFY( !var3.isNull() ); + QVariant var4( 0 ); QVERIFY( !var4.isNull() ); @@ -3005,9 +3010,11 @@ void tst_QVariant::compareNumerics_data() const QString::number(v.toULongLong()) : QString::number(v.toLongLong()); switch (v.typeId()) { - case QMetaType::Char: case QMetaType::Char16: + return QString::number(qvariant_cast<char16_t>(v)); case QMetaType::Char32: + return QString::number(qvariant_cast<char32_t>(v)); + case QMetaType::Char: case QMetaType::UChar: return QString::number(v.toUInt()); case QMetaType::SChar: @@ -3151,7 +3158,7 @@ QT_WARNING_POP addComparePair(LLONG_MIN, quint64(LLONG_MIN) + 1); addComparePair(LLONG_MIN + 1, quint64(LLONG_MIN) + 1); addComparePair(LLONG_MIN, LLONG_MAX - 1); - addComparePair(LLONG_MIN, LLONG_MAX); + // addComparePair(LLONG_MIN, LLONG_MAX); // already added by addSingleType() // floating point addComparePair(0.f, 0); @@ -3160,7 +3167,6 @@ QT_WARNING_POP addComparePair(0.f, Q_UINT64_C(0)); addComparePair(0.f, 0.); addComparePair(0.f, 1.); - addComparePair(0.f, 1.); addComparePair(float(1 << 24), 1 << 24); addComparePair(float(1 << 24) - 1, (1 << 24) - 1); addComparePair(-float(1 << 24), 1 << 24); @@ -3170,7 +3176,7 @@ QT_WARNING_POP addComparePair(qQNaN(), std::numeric_limits<float>::quiet_NaN()); if (sizeof(qreal) == sizeof(double)) { addComparePair(std::numeric_limits<float>::min(), std::numeric_limits<double>::min()); - addComparePair(std::numeric_limits<float>::min(), std::numeric_limits<double>::min()); + addComparePair(std::numeric_limits<float>::min(), std::numeric_limits<double>::max()); addComparePair(std::numeric_limits<float>::max(), std::numeric_limits<double>::min()); addComparePair(std::numeric_limits<float>::max(), std::numeric_limits<double>::max()); addComparePair(double(Q_INT64_C(1) << 53), Q_INT64_C(1) << 53); diff --git a/tests/auto/corelib/mimetypes/qmimetype/CMakeLists.txt b/tests/auto/corelib/mimetypes/qmimetype/CMakeLists.txt index e1781d450e..605cdccc3f 100644 --- a/tests/auto/corelib/mimetypes/qmimetype/CMakeLists.txt +++ b/tests/auto/corelib/mimetypes/qmimetype/CMakeLists.txt @@ -16,4 +16,5 @@ qt_internal_add_test(tst_qmimetype tst_qmimetype.cpp LIBRARIES Qt::CorePrivate + Qt::TestPrivate ) diff --git a/tests/auto/corelib/mimetypes/qmimetype/tst_qmimetype.cpp b/tests/auto/corelib/mimetypes/qmimetype/tst_qmimetype.cpp index 79304e4420..b96e8feffa 100644 --- a/tests/auto/corelib/mimetypes/qmimetype/tst_qmimetype.cpp +++ b/tests/auto/corelib/mimetypes/qmimetype/tst_qmimetype.cpp @@ -8,7 +8,7 @@ #include <QVariantMap> #include <QTest> - +#include <QtTest/private/qcomparisontesthelper_p.h> class tst_qmimetype : public QObject { @@ -17,7 +17,9 @@ class tst_qmimetype : public QObject private slots: void initTestCase(); + void compareCompiles(); void isValid(); + void compareQMimetypes(); void name(); void genericIconName(); void iconName(); @@ -41,6 +43,28 @@ static QString qMimeTypeName() // ------------------------------------------------------------------------------------------------ +void tst_qmimetype::compareCompiles() +{ + QTestPrivate::testEqualityOperatorsCompile<QMimeType>(); +} + +// ------------------------------------------------------------------------------------------------ + +void tst_qmimetype::compareQMimetypes() +{ + QMimeType instantiatedQMimeType{ QMimeTypePrivate(qMimeTypeName()) }; + QMimeType otherQMimeType (instantiatedQMimeType); + QMimeType defaultQMimeType; + + QVERIFY(!defaultQMimeType.isValid()); + QT_TEST_EQUALITY_OPS(defaultQMimeType, QMimeType(), true); + QT_TEST_EQUALITY_OPS(QMimeType(), QMimeType(), true); + QT_TEST_EQUALITY_OPS(instantiatedQMimeType, QMimeType(), false); + QT_TEST_EQUALITY_OPS(otherQMimeType, defaultQMimeType, false); +} + +// ------------------------------------------------------------------------------------------------ + void tst_qmimetype::isValid() { QMimeType instantiatedQMimeType{ QMimeTypePrivate(qMimeTypeName()) }; @@ -49,7 +73,7 @@ void tst_qmimetype::isValid() QMimeType otherQMimeType (instantiatedQMimeType); QVERIFY(otherQMimeType.isValid()); - QCOMPARE(instantiatedQMimeType, otherQMimeType); + QT_TEST_EQUALITY_OPS(instantiatedQMimeType, otherQMimeType, true); QMimeType defaultQMimeType; @@ -66,8 +90,7 @@ void tst_qmimetype::name() // Verify that the Name is part of the equality test: QCOMPARE(instantiatedQMimeType.name(), qMimeTypeName()); - QVERIFY(instantiatedQMimeType != otherQMimeType); - QVERIFY(!(instantiatedQMimeType == otherQMimeType)); + QT_TEST_EQUALITY_OPS(instantiatedQMimeType, otherQMimeType, false); } // ------------------------------------------------------------------------------------------------ diff --git a/tests/auto/corelib/platform/android/tst_android.cpp b/tests/auto/corelib/platform/android/tst_android.cpp index e03308a883..76811a31ad 100644 --- a/tests/auto/corelib/platform/android/tst_android.cpp +++ b/tests/auto/corelib/platform/android/tst_android.cpp @@ -312,11 +312,39 @@ void tst_Android::orientationChange_data() const QSize portraitSize = QGuiApplication::primaryScreen()->size(); const QSize landscapeSize = QSize(portraitSize.height(), portraitSize.width()); + // Rotations without 180 degree or inverted portrait, assuming that the device is in portrait + // position. These are ok for Android 6(API 23), 8 (API 27) and 14 (API 34) QTest::newRow("InvertedLandscape") << 8 << Qt::InvertedLandscapeOrientation << landscapeSize; - QTest::newRow("InvertedPortrait") << 9 << Qt::InvertedPortraitOrientation << portraitSize; - QTest::newRow("Landscape") << 0 << Qt::LandscapeOrientation << landscapeSize; - // Leave Portrait till the end QTest::newRow("Portrait") << 1 << Qt::PortraitOrientation << portraitSize; + QTest::newRow("Landscape") << 0 << Qt::LandscapeOrientation << landscapeSize; + QTest::newRow("Portrait2") << 1 << Qt::PortraitOrientation << portraitSize; + + // Rotations over inverted portrait doing only 90 degree turns. + QTest::newRow("InvertedLandscape2") << 8 << Qt::InvertedLandscapeOrientation << landscapeSize; + QTest::newRow("InvertedPortrait") << 9 << Qt::InvertedPortraitOrientation << portraitSize; + QTest::newRow("Landscape2") << 0 << Qt::LandscapeOrientation << landscapeSize; + QTest::newRow("InvertedPortrait2") << 9 << Qt::InvertedPortraitOrientation << portraitSize; + QTest::newRow("InvertedLandscape3") << 8 << Qt::InvertedLandscapeOrientation << landscapeSize; + + // Rotations with 180 degree turns. + // Android 6 (API23) Does not understand these transitions. + if (QNativeInterface::QAndroidApplication::sdkVersion() > __ANDROID_API_M__) { + QTest::newRow("Landscape3") << 0 << Qt::LandscapeOrientation << landscapeSize; + QTest::newRow("InvertedLandscape4") + << 8 << Qt::InvertedLandscapeOrientation << landscapeSize; + QTest::newRow("Portrait3") << 1 << Qt::PortraitOrientation << portraitSize; + } else { + qWarning() << "180 degree turn rotation test cases are not run on Android 6 (API 23) and " + "below."; + } + // Android 8 (API 27) does not understand portrait-'inverted portrait'-portrait transition. + if (QNativeInterface::QAndroidApplication::sdkVersion() > __ANDROID_API_O_MR1__) { + QTest::newRow("InvertedPortrait3") << 9 << Qt::InvertedPortraitOrientation << portraitSize; + QTest::newRow("Portrait4") << 1 << Qt::PortraitOrientation << portraitSize; + } else { + qWarning() << "Portrait-'Inverted portrait'-Portrait rotation test cases are not run on " + "Android 8 (API 27) and below."; + } } void tst_Android::orientationChange() @@ -325,15 +353,20 @@ void tst_Android::orientationChange() QFETCH(Qt::ScreenOrientation, expected); QFETCH(QSize, screenSize); + if (QNativeInterface::QAndroidApplication::sdkVersion() == __ANDROID_API_P__) + QSKIP("Android 9 orientation changes callbacks are buggy (QTBUG-124890)."); + // For QTBUG-94459 to check that the widget size are consistent after orientation changes QWidget widget; widget.show(); + QScreen *screen = QGuiApplication::primaryScreen(); + QSignalSpy orientationSpy(screen, SIGNAL(orientationChanged(Qt::ScreenOrientation))); + auto context = QNativeInterface::QAndroidApplication::context(); context.callMethod<void>("setRequestedOrientation", nativeOrientation); - QScreen *screen = QGuiApplication::primaryScreen(); - QSignalSpy orientationSpy(screen, SIGNAL(orientationChanged(Qt::ScreenOrientation))); + orientationSpy.wait(); QTRY_COMPARE(screen->orientation(), expected); QCOMPARE(orientationSpy.size(), 1); QCOMPARE(screen->size(), screenSize); diff --git a/tests/auto/corelib/platform/windows/qcomobject/tst_qcomobject.cpp b/tests/auto/corelib/platform/windows/qcomobject/tst_qcomobject.cpp index 5ad961ee66..3c609238fc 100644 --- a/tests/auto/corelib/platform/windows/qcomobject/tst_qcomobject.cpp +++ b/tests/auto/corelib/platform/windows/qcomobject/tst_qcomobject.cpp @@ -69,6 +69,7 @@ struct QComObjectTraits<IDirect> }; } // namespace QtPrivate +QT_END_NAMESPACE class tst_QComObject : public QObject { @@ -263,6 +264,4 @@ void tst_QComObject::Release_decrementsReferenceCountByOne() QTEST_MAIN(tst_QComObject) # include "tst_qcomobject.moc" -QT_END_NAMESPACE - #endif // Q_OS_WIN diff --git a/tests/auto/corelib/plugin/qpluginloader/machtest/CMakeLists.txt b/tests/auto/corelib/plugin/qpluginloader/machtest/CMakeLists.txt index 6cb69fc46d..daf922b42c 100644 --- a/tests/auto/corelib/plugin/qpluginloader/machtest/CMakeLists.txt +++ b/tests/auto/corelib/plugin/qpluginloader/machtest/CMakeLists.txt @@ -1,3 +1,5 @@ +# Copyright (C) 2024 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause set_directory_properties(PROPERTIES _qt_good_targets "" _qt_stub_targets "" diff --git a/tests/auto/corelib/plugin/qpluginloader/machtest/stub.cpp b/tests/auto/corelib/plugin/qpluginloader/machtest/stub.cpp index 24bac391fb..eed7228a29 100644 --- a/tests/auto/corelib/plugin/qpluginloader/machtest/stub.cpp +++ b/tests/auto/corelib/plugin/qpluginloader/machtest/stub.cpp @@ -1 +1,3 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only void dummy() {} diff --git a/tests/auto/corelib/plugin/quuid/test/CMakeLists.txt b/tests/auto/corelib/plugin/quuid/test/CMakeLists.txt index 1e1e820b14..ec6c1979f7 100644 --- a/tests/auto/corelib/plugin/quuid/test/CMakeLists.txt +++ b/tests/auto/corelib/plugin/quuid/test/CMakeLists.txt @@ -9,6 +9,8 @@ qt_internal_add_test(tst_quuid OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/../" SOURCES ../tst_quuid.cpp + LIBRARIES + Qt::TestPrivate ) ## Scopes: diff --git a/tests/auto/corelib/plugin/quuid/tst_quuid.cpp b/tests/auto/corelib/plugin/quuid/tst_quuid.cpp index c5ce490b61..08a5b826e9 100644 --- a/tests/auto/corelib/plugin/quuid/tst_quuid.cpp +++ b/tests/auto/corelib/plugin/quuid/tst_quuid.cpp @@ -3,6 +3,7 @@ #include <QTest> +#include <QtTest/private/qcomparisontesthelper_p.h> #if QT_CONFIG(process) #include <QProcess> #endif @@ -17,6 +18,7 @@ class tst_QUuid : public QObject private slots: void initTestCase(); + void compareCompiles(); void fromChar(); void toString(); void fromString_data(); @@ -89,20 +91,28 @@ void tst_QUuid::initTestCase() uuidD = QUuid(0x21f7f8de, 0x8051, 0x5b89, 0x86, 0x80, 0x01, 0x95, 0xef, 0x79, 0x8b, 0x6a); } +void tst_QUuid::compareCompiles() +{ + QTestPrivate::testAllComparisonOperatorsCompile<QUuid>(); +#if defined(Q_OS_WIN) + QTestPrivate::testEqualityOperatorsCompile<QUuid, GUID>(); +#endif +} + void tst_QUuid::fromChar() { - QCOMPARE(uuidA, QUuid("{fc69b59e-cc34-4436-a43c-ee95d128b8c5}")); - QCOMPARE(uuidA, QUuid("fc69b59e-cc34-4436-a43c-ee95d128b8c5}")); - QCOMPARE(uuidA, QUuid("{fc69b59e-cc34-4436-a43c-ee95d128b8c5")); - QCOMPARE(uuidA, QUuid("fc69b59e-cc34-4436-a43c-ee95d128b8c5")); - QCOMPARE(QUuid(), QUuid("{fc69b59e-cc34-4436-a43c-ee95d128b8c")); - QCOMPARE(QUuid(), QUuid("{fc69b59e-cc34")); - QCOMPARE(QUuid(), QUuid("fc69b59e-cc34-")); - QCOMPARE(QUuid(), QUuid("fc69b59e-cc34")); - QCOMPARE(QUuid(), QUuid("cc34")); - QCOMPARE(QUuid(), QUuid(nullptr)); - - QCOMPARE(uuidB, QUuid(QString("{1ab6e93a-b1cb-4a87-ba47-ec7e99039a7b}"))); + QT_TEST_EQUALITY_OPS(uuidA, QUuid("{fc69b59e-cc34-4436-a43c-ee95d128b8c5}"), true); + QT_TEST_EQUALITY_OPS(uuidA, QUuid("fc69b59e-cc34-4436-a43c-ee95d128b8c5}"), true); + QT_TEST_EQUALITY_OPS(uuidA, QUuid("{fc69b59e-cc34-4436-a43c-ee95d128b8c5"), true); + QT_TEST_EQUALITY_OPS(uuidA, QUuid("fc69b59e-cc34-4436-a43c-ee95d128b8c5"), true); + QT_TEST_EQUALITY_OPS(QUuid(), QUuid("{fc69b59e-cc34-4436-a43c-ee95d128b8c"), true); + QT_TEST_EQUALITY_OPS(QUuid(), QUuid("{fc69b59e-cc34"), true); + QT_TEST_EQUALITY_OPS(QUuid(), QUuid("fc69b59e-cc34-"), true); + QT_TEST_EQUALITY_OPS(QUuid(), QUuid("fc69b59e-cc34"), true); + QT_TEST_EQUALITY_OPS(QUuid(), QUuid("cc34"), true); + QT_TEST_EQUALITY_OPS(QUuid(), QUuid(nullptr), true); + + QT_TEST_EQUALITY_OPS(uuidB, QUuid(QString("{1ab6e93a-b1cb-4a87-ba47-ec7e99039a7b}")), true); } void tst_QUuid::toString() @@ -162,21 +172,21 @@ void tst_QUuid::fromString() const auto inputL1 = input.toLatin1(); const auto inputU8 = input.toUtf8(); - QCOMPARE(expected, QUuid(input)); - QCOMPARE(expected, QUuid(inputU8)); - QCOMPARE(expected, QUuid(inputL1)); + QT_TEST_EQUALITY_OPS(expected, QUuid(input), true); + QT_TEST_EQUALITY_OPS(expected, QUuid(inputU8), true); + QT_TEST_EQUALITY_OPS(expected, QUuid(inputL1), true); - QCOMPARE(expected, QUuid::fromString(input)); + QT_TEST_EQUALITY_OPS(expected, QUuid::fromString(input), true); // for QLatin1String, construct one whose data() is not NUL-terminated: const auto longerInputL1 = inputL1 + '5'; // the '5' makes the premature end check incorrectly succeed const auto inputL1S = QLatin1String(longerInputL1.data(), inputL1.size()); - QCOMPARE(expected, QUuid::fromString(inputL1S)); + QT_TEST_EQUALITY_OPS(expected, QUuid::fromString(inputL1S), true); // for QUtf8StringView, too: const auto longerInputU8 = inputU8 + '5'; // the '5' makes the premature end check incorrectly succeed const auto inputU8S = QUtf8StringView(longerInputU8.data(), inputU8.size()); - QCOMPARE(expected, QUuid::fromString(inputU8S)); + QT_TEST_EQUALITY_OPS(expected, QUuid::fromString(inputU8S), true); } void tst_QUuid::toByteArray() @@ -196,27 +206,30 @@ void tst_QUuid::toByteArray() void tst_QUuid::fromByteArray() { - QCOMPARE(uuidA, QUuid(QByteArray("{fc69b59e-cc34-4436-a43c-ee95d128b8c5}"))); - QCOMPARE(uuidA, QUuid(QByteArray("fc69b59e-cc34-4436-a43c-ee95d128b8c5}"))); - QCOMPARE(uuidA, QUuid(QByteArray("{fc69b59e-cc34-4436-a43c-ee95d128b8c5"))); - QCOMPARE(uuidA, QUuid(QByteArray("fc69b59e-cc34-4436-a43c-ee95d128b8c5"))); - QCOMPARE(QUuid(), QUuid(QByteArray("{fc69b59e-cc34-4436-a43c-ee95d128b8c"))); + QT_TEST_EQUALITY_OPS(uuidA, QUuid(QByteArray("{fc69b59e-cc34-4436-a43c-ee95d128b8c5}")), true); + QT_TEST_EQUALITY_OPS(uuidA, QUuid(QByteArray("fc69b59e-cc34-4436-a43c-ee95d128b8c5}")), true); + QT_TEST_EQUALITY_OPS(uuidA, QUuid(QByteArray("{fc69b59e-cc34-4436-a43c-ee95d128b8c5")), true); + QT_TEST_EQUALITY_OPS(uuidA, QUuid(QByteArray("fc69b59e-cc34-4436-a43c-ee95d128b8c5")), true); + QT_TEST_EQUALITY_OPS(QUuid(), QUuid(QByteArray("{fc69b59e-cc34-4436-a43c-ee95d128b8c")), true); - QCOMPARE(uuidB, QUuid(QByteArray("{1ab6e93a-b1cb-4a87-ba47-ec7e99039a7b}"))); + QT_TEST_EQUALITY_OPS(uuidB, QUuid(QByteArray("{1ab6e93a-b1cb-4a87-ba47-ec7e99039a7b}")), true); } void tst_QUuid::toRfc4122() { QCOMPARE(uuidA.toRfc4122(), QByteArray::fromHex("fc69b59ecc344436a43cee95d128b8c5")); - QCOMPARE(uuidB.toRfc4122(), QByteArray::fromHex("1ab6e93ab1cb4a87ba47ec7e99039a7b")); } void tst_QUuid::fromRfc4122() { - QCOMPARE(uuidA, QUuid::fromRfc4122(QByteArray::fromHex("fc69b59ecc344436a43cee95d128b8c5"))); + QT_TEST_EQUALITY_OPS( + uuidA, + QUuid::fromRfc4122(QByteArray::fromHex("fc69b59ecc344436a43cee95d128b8c5")), true); - QCOMPARE(uuidB, QUuid::fromRfc4122(QByteArray::fromHex("1ab6e93ab1cb4a87ba47ec7e99039a7b"))); + QT_TEST_EQUALITY_OPS( + uuidB, QUuid::fromRfc4122(QByteArray::fromHex("1ab6e93ab1cb4a87ba47ec7e99039a7b")), + true); } void tst_QUuid::id128() @@ -234,15 +247,15 @@ void tst_QUuid::id128() 0xba, 0x47, 0xec, 0x7e, 0x99, 0x03, 0x9a, 0x7b, } }; - QCOMPARE(QUuid(bytesA), uuidA); - QCOMPARE(QUuid(bytesB), uuidB); + QT_TEST_EQUALITY_OPS(QUuid(bytesA), uuidA, true); + QT_TEST_EQUALITY_OPS(QUuid(bytesB), uuidB, true); QVERIFY(memcmp(uuidA.toBytes().data, bytesA.data, sizeof(QUuid::Id128Bytes)) == 0); QVERIFY(memcmp(uuidB.toBytes().data, bytesB.data, sizeof(QUuid::Id128Bytes)) == 0); QUuid::Id128Bytes leBytesA = {}; for (int i = 0; i < 16; i++) leBytesA.data[15 - i] = bytesA.data[i]; - QCOMPARE(QUuid(leBytesA, QSysInfo::LittleEndian), uuidA); + QT_TEST_EQUALITY_OPS(QUuid(leBytesA, QSysInfo::LittleEndian), uuidA, true); QVERIFY(memcmp(uuidA.toBytes(QSysInfo::LittleEndian).data, leBytesA.data, sizeof(leBytesA)) == 0); // check the new q{To,From}{Big,Little}Endian() overloads @@ -271,16 +284,16 @@ void tst_QUuid::uint128() constexpr QUuid uuid = QUuid::fromUInt128(be); static_assert(uuid.toUInt128() == be, "Round-trip through QUuid failed"); - QCOMPARE(uuid, uuidA); + QT_TEST_EQUALITY_OPS(uuid, uuidA, true); QCOMPARE(uuid.toUInt128(), be); quint128 le = qFromBigEndian(be); QCOMPARE(uuid.toUInt128(QSysInfo::LittleEndian), le); - QCOMPARE(QUuid::fromUInt128(le, QSysInfo::LittleEndian), uuidA); + QT_TEST_EQUALITY_OPS(QUuid::fromUInt128(le, QSysInfo::LittleEndian), uuidA, true); QUuid::Id128Bytes bytes = { .data128 = { qToBigEndian(u) } }; QUuid uuid2(bytes); - QCOMPARE(uuid2, uuid); + QT_TEST_EQUALITY_OPS(uuid2, uuid, true); // verify that toBytes() and toUInt128() provide bytewise similar result constexpr quint128 val = uuid.toUInt128(); @@ -294,11 +307,11 @@ void tst_QUuid::uint128() void tst_QUuid::createUuidV3OrV5() { //"www.widgets.com" is also from RFC4122 - QCOMPARE(uuidC, QUuid::createUuidV3(uuidNS, QByteArray("www.widgets.com"))); - QCOMPARE(uuidC, QUuid::createUuidV3(uuidNS, QString("www.widgets.com"))); + QT_TEST_EQUALITY_OPS(uuidC, QUuid::createUuidV3(uuidNS, QByteArray("www.widgets.com")), true); + QT_TEST_EQUALITY_OPS(uuidC, QUuid::createUuidV3(uuidNS, QString("www.widgets.com")), true); - QCOMPARE(uuidD, QUuid::createUuidV5(uuidNS, QByteArray("www.widgets.com"))); - QCOMPARE(uuidD, QUuid::createUuidV5(uuidNS, QString("www.widgets.com"))); + QT_TEST_EQUALITY_OPS(uuidD, QUuid::createUuidV5(uuidNS, QByteArray("www.widgets.com")), true); + QT_TEST_EQUALITY_OPS(uuidD, QUuid::createUuidV5(uuidNS, QString("www.widgets.com")), true); } void tst_QUuid::check_QDataStream() @@ -314,7 +327,7 @@ void tst_QUuid::check_QDataStream() QDataStream in(&ar,QIODevice::ReadOnly); in.setByteOrder(QDataStream::BigEndian); in >> tmp; - QCOMPARE(uuidA, tmp); + QT_TEST_EQUALITY_OPS(uuidA, tmp, true); } { QDataStream out(&ar,QIODevice::WriteOnly); @@ -325,7 +338,7 @@ void tst_QUuid::check_QDataStream() QDataStream in(&ar,QIODevice::ReadOnly); in.setByteOrder(QDataStream::LittleEndian); in >> tmp; - QCOMPARE(uuidA, tmp); + QT_TEST_EQUALITY_OPS(uuidA, tmp, true); } } @@ -340,14 +353,14 @@ void tst_QUuid::isNull() void tst_QUuid::equal() { - QVERIFY( !(uuidA == uuidB) ); + QT_TEST_EQUALITY_OPS(uuidA, uuidB, false); QUuid copy(uuidA); - QCOMPARE(uuidA, copy); + QT_TEST_EQUALITY_OPS(uuidA, copy, true); QUuid assigned; assigned = uuidA; - QCOMPARE(uuidA, assigned); + QT_TEST_EQUALITY_OPS(uuidA, assigned, true); } @@ -384,10 +397,12 @@ void tst_QUuid::less() QVERIFY( uuidB <= uuidA); QVERIFY(!(uuidA < uuidB) ); QVERIFY(!(uuidA <= uuidB)); + QT_TEST_ALL_COMPARISON_OPS(uuidB, uuidA, Qt::strong_ordering::less); QUuid null_uuid; QVERIFY(null_uuid < uuidA); // Null uuid is always less than a valid one QVERIFY(null_uuid <= uuidA); + QT_TEST_ALL_COMPARISON_OPS(null_uuid, uuidA, Qt::strong_ordering::less); QVERIFY(null_uuid <= null_uuid); QVERIFY(uuidA <= uuidA); @@ -400,6 +415,7 @@ void tst_QUuid::more() QVERIFY( uuidA >= uuidB); QVERIFY(!(uuidB > uuidA)); QVERIFY(!(uuidB >= uuidA)); + QT_TEST_ALL_COMPARISON_OPS(uuidA, uuidB, Qt::strong_ordering::greater); QUuid null_uuid; QVERIFY(!(null_uuid > uuidA)); // Null uuid is always less than a valid one @@ -407,6 +423,7 @@ void tst_QUuid::more() QVERIFY(null_uuid >= null_uuid); QVERIFY(uuidA >= uuidA); + QT_TEST_ALL_COMPARISON_OPS(uuidA, uuidA, Qt::strong_ordering::equal); } @@ -512,7 +529,7 @@ void tst_QUuid::qvariant() QUuid uuid2 = v.value<QUuid>(); QVERIFY(!uuid2.isNull()); - QCOMPARE(uuid, uuid2); + QT_TEST_EQUALITY_OPS(uuid, uuid2, true); } void tst_QUuid::qvariant_conversion() @@ -544,7 +561,7 @@ void tst_QUuid::qvariant_conversion() QVariant sv = QVariant::fromValue(uuid.toByteArray()); QCOMPARE(sv.metaType(), QMetaType(QMetaType::QByteArray)); QVERIFY(sv.canConvert<QUuid>()); - QCOMPARE(sv.value<QUuid>(), uuid); + QT_TEST_EQUALITY_OPS(sv.value<QUuid>(), uuid, true); } } diff --git a/tests/auto/corelib/serialization/CMakeLists.txt b/tests/auto/corelib/serialization/CMakeLists.txt index 3792336255..45965114cc 100644 --- a/tests/auto/corelib/serialization/CMakeLists.txt +++ b/tests/auto/corelib/serialization/CMakeLists.txt @@ -3,7 +3,9 @@ add_subdirectory(json) add_subdirectory(qcborstreamreader) -add_subdirectory(qcborstreamwriter) +if(QT_FEATURE_cborstreamwriter) + add_subdirectory(qcborstreamwriter) +endif() if(NOT WASM) add_subdirectory(qcborvalue) endif() diff --git a/tests/auto/corelib/serialization/json/tst_qtjson.cpp b/tests/auto/corelib/serialization/json/tst_qtjson.cpp index 5046478547..54ef9be4f2 100644 --- a/tests/auto/corelib/serialization/json/tst_qtjson.cpp +++ b/tests/auto/corelib/serialization/json/tst_qtjson.cpp @@ -182,14 +182,20 @@ void tst_QtJson::compareCompiles() QJsonArray::const_iterator>(); QTestPrivate::testEqualityOperatorsCompile<QJsonDocument>(); QTestPrivate::testEqualityOperatorsCompile<QJsonObject>(); + QTestPrivate::testEqualityOperatorsCompile<QJsonObject::iterator>(); + QTestPrivate::testEqualityOperatorsCompile<QJsonObject::const_iterator>(); QTestPrivate::testEqualityOperatorsCompile<QJsonValue>(); QTestPrivate::testEqualityOperatorsCompile<QJsonValueConstRef>(); QTestPrivate::testEqualityOperatorsCompile<QJsonValueRef>(); QTestPrivate::testEqualityOperatorsCompile<QJsonArray, QJsonValue>(); QTestPrivate::testEqualityOperatorsCompile<QJsonObject, QJsonValue>(); + QTestPrivate::testEqualityOperatorsCompile<QJsonObject, QJsonValueConstRef>(); + QTestPrivate::testEqualityOperatorsCompile<QJsonObject, QJsonValueRef>(); QTestPrivate::testEqualityOperatorsCompile<QJsonValueConstRef, QJsonValue>(); QTestPrivate::testEqualityOperatorsCompile<QJsonValueRef, QJsonValue>(); QTestPrivate::testEqualityOperatorsCompile<QJsonValueRef, QJsonValueConstRef>(); + QTestPrivate::testEqualityOperatorsCompile<QJsonObject::iterator, + QJsonObject::const_iterator>(); } void tst_QtJson::testValueSimple() @@ -670,6 +676,7 @@ void tst_QtJson::testObjectInsertCopies() QCOMPARE(obj.size(), 2); QCOMPARE(obj.value("value"), "TEST"); QCOMPARE(obj.value("prop2"), "TEST"); + QT_TEST_EQUALITY_OPS(rv, obj["value"].toObject(), true); } { QJsonObject obj; @@ -1105,6 +1112,7 @@ void tst_QtJson::testObjectIteration() for (QJsonObject::iterator it = object.begin(); it != object.end(); ++it) { QJsonValue value = it.value(); QCOMPARE((double)it.key().toInt(), value.toDouble()); + QT_TEST_EQUALITY_OPS(it, QJsonObject::iterator(), false); } { @@ -1117,6 +1125,7 @@ void tst_QtJson::testObjectIteration() QCOMPARE(object.size(), 10); QCOMPARE(object2.size(), 9); QVERIFY(next == object2.begin()); + QT_TEST_EQUALITY_OPS(next, object2.begin(), true); double d = 1; // we erased the first item for (auto it = object2.constBegin(); it != object2.constEnd(); ++it, d += 1) { @@ -1175,6 +1184,7 @@ void tst_QtJson::testObjectIteration() { QJsonObject::Iterator it = object.begin(); it += 5; + QT_TEST_ALL_COMPARISON_OPS(it, object.begin(), Qt::strong_ordering::greater); QCOMPARE(QJsonValue(it.value()).toDouble(), 5.); it -= 3; QCOMPARE(QJsonValue(it.value()).toDouble(), 2.); @@ -1189,10 +1199,14 @@ void tst_QtJson::testObjectIteration() it += 5; QCOMPARE(QJsonValue(it.value()).toDouble(), 5.); it -= 3; + QT_TEST_ALL_COMPARISON_OPS(object.constBegin(), it, Qt::strong_ordering::less); QCOMPARE(QJsonValue(it.value()).toDouble(), 2.); QJsonObject::ConstIterator it2 = it + 5; + QT_TEST_EQUALITY_OPS(it, it2, false); QCOMPARE(QJsonValue(it2.value()).toDouble(), 7.); it2 = it - 1; + QT_TEST_ALL_COMPARISON_OPS(it2, it, Qt::strong_ordering::less); + QT_TEST_ALL_COMPARISON_OPS(it2, it - 2, Qt::strong_ordering::greater); QCOMPARE(QJsonValue(it2.value()).toDouble(), 1.); } @@ -1201,6 +1215,17 @@ void tst_QtJson::testObjectIteration() it = object.erase(it); QCOMPARE(object.size() , 0); QCOMPARE(it, object.end()); + QT_TEST_ALL_COMPARISON_OPS(it, object.end(), Qt::strong_ordering::equal); + QT_TEST_ALL_COMPARISON_OPS(it, object.constEnd(), Qt::strong_ordering::equal); + QT_TEST_ALL_COMPARISON_OPS(it, object.begin(), + Qt::strong_ordering::equal); // because object is empty + QT_TEST_ALL_COMPARISON_OPS(it, object.constBegin(), Qt::strong_ordering::equal); + QT_TEST_ALL_COMPARISON_OPS(QJsonObject::Iterator(), + QJsonObject::Iterator(), Qt::strong_ordering::equal); + QT_TEST_ALL_COMPARISON_OPS(QJsonObject::ConstIterator(), + QJsonObject::Iterator(), Qt::strong_ordering::equal); + QT_TEST_ALL_COMPARISON_OPS(QJsonObject::ConstIterator(), + QJsonObject::ConstIterator(), Qt::strong_ordering::equal); } void tst_QtJson::testArrayIteration() diff --git a/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp b/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp index 37f1569bbc..e480b033e1 100644 --- a/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp +++ b/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp @@ -7,7 +7,9 @@ #include <QBuffer> #include <QCborStreamReader> +#if QT_CONFIG(cborstreamwriter) #include <QCborStreamWriter> +#endif #include <QDateTime> #include <QtEndian> #include <QTimeZone> @@ -16,6 +18,8 @@ Q_DECLARE_METATYPE(QCborKnownTags) Q_DECLARE_METATYPE(QCborValue) Q_DECLARE_METATYPE(QCborValue::EncodingOptions) +using namespace Qt::StringLiterals; + class tst_QCborValue : public QObject { Q_OBJECT @@ -78,16 +82,17 @@ private slots: void mapComplexKeys(); void mapNested(); + void sorting_data(); void sorting(); - void comparison_data(); - void comparison(); void comparisonMap_data(); void comparisonMap(); void toCbor_data(); +#if QT_CONFIG(cborstreamwriter) void toCbor(); void toCborStreamWriter_data() { toCbor_data(); } void toCborStreamWriter(); +#endif void fromCbor_data(); void fromCbor(); void fromCborStreamReaderByteArray_data() { fromCbor_data(); } @@ -457,7 +462,11 @@ void tst_QCborValue::compareCompiles() QTestPrivate::testAllComparisonOperatorsCompile<QCborValueRef>(); QTestPrivate::testAllComparisonOperatorsCompile<QCborValueConstRef>(); QTestPrivate::testAllComparisonOperatorsCompile<QCborArray>(); + QTestPrivate::testAllComparisonOperatorsCompile<QCborArray::Iterator>(); + QTestPrivate::testAllComparisonOperatorsCompile<QCborArray::ConstIterator>(); QTestPrivate::testAllComparisonOperatorsCompile<QCborMap>(); + QTestPrivate::testAllComparisonOperatorsCompile<QCborMap::Iterator>(); + QTestPrivate::testAllComparisonOperatorsCompile<QCborMap::ConstIterator>(); // QCborValue, Ref and ConstRef QTestPrivate::testAllComparisonOperatorsCompile<QCborValueRef, QCborValueConstRef>(); @@ -471,6 +480,8 @@ void tst_QCborValue::compareCompiles() QTestPrivate::testAllComparisonOperatorsCompile<QCborMap, QCborValue>(); QTestPrivate::testAllComparisonOperatorsCompile<QCborMap, QCborValueRef>(); QTestPrivate::testAllComparisonOperatorsCompile<QCborMap, QCborValueConstRef>(); + QTestPrivate::testAllComparisonOperatorsCompile<QCborArray::Iterator, + QCborArray::ConstIterator>(); } void tst_QCborValue::extendedTypes() @@ -739,6 +750,13 @@ void tst_QCborValue::mapNonEmptyDetach() { QCborMap copy(m); auto it = m.find(QLatin1String("3")); QVERIFY(it == m.end()); } { QCborMap copy(m); auto it = m.find(QString("3")); QVERIFY(it == m.end()); } { QCborMap copy(m); auto it = m.find(QCborValue(3)); QVERIFY(it == m.end()); } + + QT_TEST_EQUALITY_OPS(m.constBegin(), m.constEnd(), false); + QT_TEST_EQUALITY_OPS(m.begin(), m.end(), false); + QT_TEST_EQUALITY_OPS(m.constFind(3), m.constEnd(), true); + QT_TEST_EQUALITY_OPS(m.find(3), m.end(), true); + QT_TEST_EQUALITY_OPS(m.find(3), m.constEnd(), true); + QT_TEST_EQUALITY_OPS(m.constFind(3), m.end(), true); } void tst_QCborValue::arrayInitializerList() @@ -785,12 +803,17 @@ void tst_QCborValue::arrayInitializerList() // iterators auto it = a.constBegin(); auto end = a.constEnd(); + QT_TEST_ALL_COMPARISON_OPS(it, end, Qt::strong_ordering::less); QCOMPARE(end - it, 7); QCOMPARE(it + 7, end); + QT_TEST_EQUALITY_OPS(it + 7, end, true); QVERIFY(it->isInteger()); QCOMPARE(*it, QCborValue(0)); QCOMPARE(it[1], QCborValue(-1)); QCOMPARE(*(it + 2), QCborValue(false)); + QT_TEST_EQUALITY_OPS(*it, QCborValue(0), true); + QT_TEST_EQUALITY_OPS(it[1], QCborValue(-1), true); + QT_TEST_EQUALITY_OPS(*(it + 2), QCborValue(false), true); it += 3; QCOMPARE(*it, QCborValue(true)); ++it; @@ -801,6 +824,24 @@ void tst_QCborValue::arrayInitializerList() QCOMPARE(*end, QCborValue(1.0)); end--; QCOMPARE(it, end); + QT_TEST_EQUALITY_OPS(it, end, true); + QT_TEST_EQUALITY_OPS(it, QCborArray::ConstIterator(), false); + QT_TEST_EQUALITY_OPS(QCborArray::ConstIterator(), end, false); + QT_TEST_EQUALITY_OPS(QCborArray::ConstIterator(), QCborArray::ConstIterator(), true); + QT_TEST_EQUALITY_OPS(QCborArray::ConstIterator(), QCborArray::Iterator(), true); + + { + auto it = a.begin(); + auto it1 = a.constBegin(); + auto end = a.end(); + QT_TEST_ALL_COMPARISON_OPS(it, end, Qt::strong_ordering::less); + QT_TEST_ALL_COMPARISON_OPS(it1, end, Qt::strong_ordering::less); + QT_TEST_EQUALITY_OPS(it + 7, end, true); + QT_TEST_EQUALITY_OPS(it1 + 7, end, true); + QT_TEST_EQUALITY_OPS(it, QCborArray::Iterator(), false); + QT_TEST_EQUALITY_OPS(QCborArray::Iterator(), end, false); + QT_TEST_EQUALITY_OPS(QCborArray::Iterator(), QCborArray::ConstIterator(), true); + } // range for int i = 0; @@ -1151,8 +1192,18 @@ void tst_QCborValue::mapMutation() m2 = m; auto it = m.begin(); // detaches again auto end = m.end(); + auto it1 = m.constBegin(); // detaches again + auto end2 = m.constEnd(); QCOMPARE(end - it, 2); + QT_TEST_ALL_COMPARISON_OPS(it, it + 1, Qt::strong_ordering::less); + QT_TEST_ALL_COMPARISON_OPS(it, it1 + 1, Qt::strong_ordering::less); + QT_TEST_ALL_COMPARISON_OPS(it, it - 1, Qt::strong_ordering::greater); + QT_TEST_ALL_COMPARISON_OPS(it, it1 - 1, Qt::strong_ordering::greater); + QT_TEST_EQUALITY_OPS(it, it1, true); QCOMPARE(it + 2, end); + QT_TEST_EQUALITY_OPS(it + 2, end, true); + QT_TEST_EQUALITY_OPS(it + 2, end2, true); + QT_TEST_EQUALITY_OPS(it1 + 2, end2, true); QT_TEST_EQUALITY_OPS(it.key(), QCborValue(42), true); QT_TEST_EQUALITY_OPS(it.value(), QCborValue(2.5), true); QT_TEST_EQUALITY_OPS((++it).value(), QCborValue(nullptr), true); @@ -1287,6 +1338,8 @@ void tst_QCborValue::arrayValueRef() QVERIFY(v == a.first()); QVERIFY(v == a.last()); QVERIFY(v == a[0]); + QT_TEST_EQUALITY_OPS(a.first(), v, true); + QT_TEST_EQUALITY_OPS(a.last(), v, true); auto iteratorCheck = [&v](auto it) { QT_TEST_EQUALITY_OPS(*it, v, true); @@ -1819,8 +1872,24 @@ void tst_QCborValue::mapNested() } } -void tst_QCborValue::sorting() +void tst_QCborValue::sorting_data() { + // CBOR data comparisons are done as if we were comparing their canonically + // (deterministic) encoded forms in the byte stream, including the Major + // Type. That has a few surprises noted below: + // 1) because the length of a string precedes it, effectively strings are + // sorted by their UTF-8 length before their contents + // 2) because negative integers are stored in negated form, they sort in + // descending order (i.e. by absolute value) + // 3) negative integers (Major Type 1) sort after all positive integers + // (Major Type 0) + // Effectively, this means integers are sorted as sign+magnitude. + // 4) floating point types (Major Type 7) sort after all integers + + QTest::addColumn<QCborValue>("lhs"); + QTest::addColumn<QCborValue>("rhs"); + QTest::addColumn<Qt::strong_ordering>("expectedOrdering"); + QCborValue vundef, vnull(nullptr); QCborValue vtrue(true), vfalse(false); QCborValue vint1(1), vint2(2); @@ -1839,97 +1908,213 @@ void tst_QCborValue::sorting() QCborValue vurl1(QUrl("https://example.net")), vurl2(QUrl("https://example.com/")); QCborValue vuuid1{QUuid()}, vuuid2(QUuid::createUuid()); QCborValue vsimple1(QCborSimpleType(1)), vsimple32(QCborSimpleType(32)), vsimple255(QCborSimpleType(255)); - QCborValue vdouble1(1.5), vdouble2(qInf()); + QCborValue vdouble1(1.5), vdouble2(qInf()), vdouble3(qQNaN()); QCborValue vndouble1(-1.5), vndouble2(-qInf()); + auto addRow = [](QCborValue lhs, QCborValue rhs, Qt::strong_ordering order) { + QTest::addRow("%s-cmp-%s", qPrintable(lhs.toDiagnosticNotation()), + qPrintable(rhs.toDiagnosticNotation())) + << lhs << rhs << order; + }; + auto addSelfCmp = [](QCborValue v) { + QTest::addRow("self-%s", qPrintable(v.toDiagnosticNotation())) + << v << v << Qt::strong_ordering::equal; + }; + + // self compares + addSelfCmp(vundef); + addSelfCmp(vnull); + addSelfCmp(vfalse); + addSelfCmp(vtrue); + addSelfCmp(vint1); + addSelfCmp(vint2); + addSelfCmp(vneg1); + addSelfCmp(vneg2); + addSelfCmp(vba1); + addSelfCmp(vba2); + addSelfCmp(vba3); + addSelfCmp(vs1); + addSelfCmp(vs2); + addSelfCmp(vs3); + addSelfCmp(va1); + addSelfCmp(va2); + addSelfCmp(va3); + addSelfCmp(vm1); + addSelfCmp(vm2); + addSelfCmp(vm3); + addSelfCmp(vdt1); + addSelfCmp(vdt2); + addSelfCmp(vtagged1); + addSelfCmp(vtagged2); + addSelfCmp(vtagged3); + addSelfCmp(vtagged4); + addSelfCmp(vtagged5); + addSelfCmp(vurl1); + addSelfCmp(vurl2); + addSelfCmp(vuuid1); + addSelfCmp(vuuid2); + addSelfCmp(vsimple1); + addSelfCmp(vsimple32); + addSelfCmp(vsimple255); + addSelfCmp(vdouble1); + addSelfCmp(vdouble2); + addSelfCmp(vdouble3); // surprise: NaNs do compare + addSelfCmp(vndouble1); + addSelfCmp(vndouble2); + // intra-type comparisons - QT_TEST_ALL_COMPARISON_OPS(vfalse, vtrue, Qt::strong_ordering::less); - QT_TEST_ALL_COMPARISON_OPS(vsimple1, vsimple32, Qt::strong_ordering::less); - QT_TEST_ALL_COMPARISON_OPS(vsimple32, vsimple255, Qt::strong_ordering::less); - QT_TEST_ALL_COMPARISON_OPS(vint1, vint2, Qt::strong_ordering::less); - QT_TEST_ALL_COMPARISON_OPS(vdouble1, vdouble2, Qt::strong_ordering::less); - QT_TEST_ALL_COMPARISON_OPS(vndouble1, vndouble2, Qt::strong_ordering::less); - // note: shorter length sorts first - QT_TEST_ALL_COMPARISON_OPS(vba1, vba2, Qt::strong_ordering::less); - QT_TEST_ALL_COMPARISON_OPS(vba2, vba3, Qt::strong_ordering::less); - QT_TEST_ALL_COMPARISON_OPS(vs1, vs2, Qt::strong_ordering::less); - QT_TEST_ALL_COMPARISON_OPS(vs2, vs3, Qt::strong_ordering::less); - QT_TEST_ALL_COMPARISON_OPS(va1, va2, Qt::strong_ordering::less); - QT_TEST_ALL_COMPARISON_OPS(va2, va3, Qt::strong_ordering::less); - QT_TEST_ALL_COMPARISON_OPS(vm1, vm2, Qt::strong_ordering::less); - QT_TEST_ALL_COMPARISON_OPS(vm2, vm3, Qt::strong_ordering::less); - QT_TEST_ALL_COMPARISON_OPS(vdt1, vdt2, Qt::strong_ordering::less); - QT_TEST_ALL_COMPARISON_OPS(vtagged1, vtagged2, Qt::strong_ordering::less); - QT_TEST_ALL_COMPARISON_OPS(vtagged2, vtagged3, Qt::strong_ordering::less); - QT_TEST_ALL_COMPARISON_OPS(vtagged3, vtagged4, Qt::strong_ordering::less); - QT_TEST_ALL_COMPARISON_OPS(vtagged4, vtagged5, Qt::strong_ordering::less); - QT_TEST_ALL_COMPARISON_OPS(vurl1, vurl2, Qt::strong_ordering::less); - QT_TEST_ALL_COMPARISON_OPS(vuuid1, vuuid2, Qt::strong_ordering::less); - - // surprise 1: CBOR sorts integrals by absolute value - QT_TEST_ALL_COMPARISON_OPS(vneg1, vneg2, Qt::strong_ordering::less); - - // surprise 2: CBOR sorts negatives after positives (sign+magnitude) - QT_TEST_ALL_COMPARISON_OPS(vint2, vneg1, Qt::strong_ordering::less); - QVERIFY(vint2.toInteger() > vneg1.toInteger()); - QT_TEST_ALL_COMPARISON_OPS(vdouble2, vndouble1, Qt::strong_ordering::less); - QVERIFY(vdouble2.toDouble() > vndouble1.toDouble()); + addRow(vfalse, vtrue, Qt::strong_ordering::less); + addRow(vsimple1, vsimple32, Qt::strong_ordering::less); + addRow(vsimple32, vsimple255, Qt::strong_ordering::less); + addRow(vint1, vint2, Qt::strong_ordering::less); + addRow(vdouble1, vdouble2, Qt::strong_ordering::less); + addRow(vdouble2, vdouble3, Qt::strong_ordering::less); // surprise: NaNs do compare + addRow(vndouble1, vndouble2, Qt::strong_ordering::less); // surprise: -1.5 < -inf + addRow(va1, va2, Qt::strong_ordering::less); + addRow(va2, va3, Qt::strong_ordering::less); + addRow(vm1, vm2, Qt::strong_ordering::less); + addRow(vm2, vm3, Qt::strong_ordering::less); + addRow(vdt1, vdt2, Qt::strong_ordering::less); + addRow(vtagged1, vtagged2, Qt::strong_ordering::less); + addRow(vtagged2, vtagged3, Qt::strong_ordering::less); + addRow(vtagged3, vtagged4, Qt::strong_ordering::less); + addRow(vtagged4, vtagged5, Qt::strong_ordering::less); + addRow(vurl1, vurl2, Qt::strong_ordering::less); + addRow(vuuid1, vuuid2, Qt::strong_ordering::less); + + // surprise 1: CBOR sorts strings by length first + addRow(vba1, vba2, Qt::strong_ordering::less); + addRow(vba2, vba3, Qt::strong_ordering::less); + addRow(vs1, vs2, Qt::strong_ordering::less); + addRow(vs2, vs3, Qt::strong_ordering::less); + + // surprise 2: CBOR sorts integrals by absolute value + addRow(vneg1, vneg2, Qt::strong_ordering::less); + + // surprise 3: CBOR sorts negatives after positives (sign+magnitude) + addRow(vint2, vneg1, Qt::strong_ordering::less); + addRow(vdouble2, vndouble1, Qt::strong_ordering::less); // inter-type comparisons - QT_TEST_ALL_COMPARISON_OPS(vneg2, vba1, Qt::strong_ordering::less); - QT_TEST_ALL_COMPARISON_OPS(vba3, vs1, Qt::strong_ordering::less); - QT_TEST_ALL_COMPARISON_OPS(vs3, va1, Qt::strong_ordering::less); - QT_TEST_ALL_COMPARISON_OPS(va2, vm1, Qt::strong_ordering::less); - QT_TEST_ALL_COMPARISON_OPS(vm2, vdt1, Qt::strong_ordering::less); - QT_TEST_ALL_COMPARISON_OPS(vdt2, vtagged1, Qt::strong_ordering::less); - QT_TEST_ALL_COMPARISON_OPS(vtagged2, vurl1, Qt::strong_ordering::less); - QT_TEST_ALL_COMPARISON_OPS(vurl1, vuuid1, Qt::strong_ordering::less); - QT_TEST_ALL_COMPARISON_OPS(vuuid2, vtagged3, Qt::strong_ordering::less); - QT_TEST_ALL_COMPARISON_OPS(vtagged4, vsimple1, Qt::strong_ordering::less); - QT_TEST_ALL_COMPARISON_OPS(vsimple1, vfalse, Qt::strong_ordering::less); - QT_TEST_ALL_COMPARISON_OPS(vtrue, vnull, Qt::strong_ordering::less); - QT_TEST_ALL_COMPARISON_OPS(vnull, vundef, Qt::strong_ordering::less); - QT_TEST_ALL_COMPARISON_OPS(vundef, vsimple32, Qt::strong_ordering::less); - QT_TEST_ALL_COMPARISON_OPS(vsimple255, vdouble1, Qt::strong_ordering::less); + addRow(vneg2, vba1, Qt::strong_ordering::less); + addRow(vba3, vs1, Qt::strong_ordering::less); + addRow(vs3, va1, Qt::strong_ordering::less); + addRow(va2, vm1, Qt::strong_ordering::less); + addRow(vm2, vdt1, Qt::strong_ordering::less); + addRow(vdt2, vtagged1, Qt::strong_ordering::less); + addRow(vtagged2, vurl1, Qt::strong_ordering::less); + addRow(vurl1, vuuid1, Qt::strong_ordering::less); + addRow(vuuid2, vtagged3, Qt::strong_ordering::less); + addRow(vtagged4, vsimple1, Qt::strong_ordering::less); + addRow(vsimple1, vfalse, Qt::strong_ordering::less); + addRow(vtrue, vnull, Qt::strong_ordering::less); + addRow(vnull, vundef, Qt::strong_ordering::less); + addRow(vundef, vsimple32, Qt::strong_ordering::less); + addRow(vsimple255, vdouble1, Qt::strong_ordering::less); // which shows all doubles sorted after integrals - QT_TEST_ALL_COMPARISON_OPS(vint2, vdouble1, Qt::strong_ordering::less); - QVERIFY(vint2.toInteger() > vdouble1.toDouble()); -} + addRow(vint2, vdouble1, Qt::strong_ordering::less); -void tst_QCborValue::comparison_data() -{ - QTest::addColumn<QCborValue>("lhs"); - QTest::addColumn<QCborValue>("rhs"); - QTest::addColumn<Qt::strong_ordering>("expectedOrdering"); + // Add some non-US-ASCII strings. In the current implementation, QCborValue + // can store a string as either US-ASCII, UTF-8, or UTF-16, so let's exercise + // those comparisons. - auto addRow = [](QCborValue lhs, QCborValue rhs, Qt::strong_ordering order) { - QTest::addRow("%s-cmp-%s", qPrintable(lhs.toDiagnosticNotation()), - qPrintable(rhs.toDiagnosticNotation())) - << lhs << rhs << order; + // we don't have a QUtf8StringView constructor, so work around it + auto utf8string = [](QByteArray str) { + Q_ASSERT(str.size() < 24); + str.prepend(char(QCborValue::String) + str.size()); + return QCborValue::fromCbor(str); }; - // typical, sorts as expected - addRow(0, 0, Qt::strong_ordering::equivalent); - addRow(1, 0, Qt::strong_ordering::greater); - addRow(0, 1, Qt::strong_ordering::less); - addRow(10.0, 10.0, Qt::strong_ordering::equivalent); - addRow(10.5, 10.8, Qt::strong_ordering::less); - addRow(-10.5, -10.8, Qt::strong_ordering::less); - addRow("Qt","Qt", Qt::strong_ordering::equivalent); - addRow("qt","Qt", Qt::strong_ordering::greater); - // atypical gotchas - addRow(0, -1, Qt::strong_ordering::less); - addRow(10, 10.0, Qt::strong_ordering::less); - addRow(0, "Qt", Qt::strong_ordering::less); + auto addStringCmp = [&](const char *prefix, const char *tag, QUtf8StringView lhs, + QUtf8StringView rhs) { + // CBOR orders strings by UTF-8 length + auto order = Qt::compareThreeWay(lhs.size(), rhs.size()); + if (is_eq(order)) + order = compareThreeWay(lhs, rhs); + Q_ASSERT(is_eq(order) || is_lt(order)); // please keep lhs <= rhs! + + QCborValue lhs_utf8 = utf8string(QByteArrayView(lhs).toByteArray()); + QCborValue rhs_utf8 = utf8string(QByteArrayView(rhs).toByteArray()); + QCborValue lhs_utf16 = QString::fromUtf8(lhs); + QCborValue rhs_utf16 = QString::fromUtf8(rhs); + + QTest::addRow("string-%s%s:utf8-utf8", prefix, tag) << lhs_utf8 << rhs_utf8 << order; + QTest::addRow("string-%s%s:utf8-utf16", prefix, tag) << lhs_utf8 << rhs_utf16 << order; + QTest::addRow("string-%s%s:utf16-utf8", prefix, tag) << lhs_utf16 << rhs_utf8 << order; + QTest::addRow("string-%s%s:utf16-utf16", prefix, tag) << lhs_utf16 << rhs_utf16 << order; + }; + auto addStringCmpSameLength = [&](const char *tag, QUtf8StringView lhs, QUtf8StringView rhs) { + Q_ASSERT(lhs.size() == rhs.size()); + addStringCmp("samelength-", tag, lhs, rhs); + }; + auto addStringCmpShorter = [&](const char *tag, QUtf8StringView lhs, QUtf8StringView rhs) { + Q_ASSERT(lhs.size() < rhs.size()); + addStringCmp("shorter-", tag, lhs, rhs); + }; + + // ascii-only is already tested + addStringCmp("equal-", "1continuation", "ab\u00A0c", "ab\u00A0c"); + addStringCmp("equal-", "2continuation", "ab\u0800", "ab\u0800"); + addStringCmp("equal-", "3continuation", "a\U00010000", "a\U00010000"); + + // these strings all have the same UTF-8 length (5 bytes) + addStringCmpSameLength("less-ascii", "abcde", "ab\u00A0c"); + addStringCmpSameLength("less-1continuation", "ab\u00A0c", "ab\u07FFc"); + addStringCmpSameLength("less-2continuation", "ab\u0800", "ab\uFFFC"); + addStringCmpSameLength("less-3continuation", "a\U00010000", "a\U0010FFFC"); + addStringCmpSameLength("less-0-vs-1continuation", "abcde", "ab\u00A0c"); + addStringCmpSameLength("less-0-vs-2continuation", "abcde", "ab\u0800"); + addStringCmpSameLength("less-0-vs-3continuation", "abcde", "a\U00010000"); + addStringCmpSameLength("less-1-vs-2continuation", "ab\u00A0c", "ab\uFFFC"); + addStringCmpSameLength("less-1-vs-3continuation", "ab\u00A0c", "a\U00010000"); + addStringCmpSameLength("less-2-vs-3continuation", "ab\u0800", "a\U00010000"); + addStringCmpSameLength("less-2-vs-3continuation_surrogate", "a\uFFFCz", "a\U00010000"); // even though U+D800 < U+FFFC + + // these strings have different lengths in UTF-8 + // (0continuation already tested) + addStringCmpShorter("1continuation", "ab\u00A0", "ab\u00A0c"); + addStringCmpShorter("2continuation", "ab\u0800", "ab\u0800c"); + addStringCmpShorter("3continuation", "ab\U00010000", "ab\U00010000c"); + // most of these have the same length in UTF-16! + addStringCmpShorter("0-vs-1continuation", "abc", "ab\u00A0"); + addStringCmpShorter("0-vs-2continuation", "abcd", "ab\u0800"); + addStringCmpShorter("0-vs-3continuation", "abcde", "ab\U00010000"); + addStringCmpShorter("1-vs-2continuation", "ab\u00A0", "ab\u0800"); + addStringCmpShorter("1-vs-3continuation", "abc\u00A0", "ab\U00010000"); + addStringCmpShorter("2-vs-3continuation", "ab\u0800", "ab\U00010000"); + + // lhs is 4xUTF-16 and 8xUTF-8; rhs is 3xUTF-16 but 9xUTF-8 + addStringCmpShorter("3x2-vs-2x3continuation", "\U00010000\U00010000", "\u0800\u0800\u0800"); + + // slight surprising because normally rhs would sort first ("aa" vs "ab" prefix) + // (0continuation_surprise already tested) + addStringCmpShorter("1continuation_surprise", "ab\u00A0", "aa\u00A0c"); + addStringCmpShorter("2continuation_surprise", "ab\u0800", "aa\u0800c"); + addStringCmpShorter("3continuation_surprise", "ab\U00010000", "aa\U00010000c"); + addStringCmpShorter("0-vs-1continuation_surprise", "abc", "aa\u00A0"); + addStringCmpShorter("0-vs-2continuation_surprise", "abcd", "aa\u0800"); + addStringCmpShorter("0-vs-3continuation_surprise", "abcde", "aa\U00010000"); + addStringCmpShorter("1-vs-2continuation_surprise", "ab\u00A0", "aa\u0800"); + addStringCmpShorter("1-vs-3continuation_surprise", "abc\u00A0", "aa\U00010000"); + addStringCmpShorter("2-vs-3continuation_surprise", "ab\u0800", "aa\U00010000"); } -void tst_QCborValue::comparison() +void tst_QCborValue::sorting() { QFETCH(QCborValue, lhs); QFETCH(QCborValue, rhs); QFETCH(Qt::strong_ordering, expectedOrdering); + // do a QCOMPARE first so we get a proper QTest error in case QCborValue is + // broken + if (expectedOrdering == Qt::strong_ordering::equal) + QCOMPARE_EQ(lhs, rhs); + else if (expectedOrdering == Qt::strong_ordering::less) + QCOMPARE_LT(lhs, rhs); + else if (expectedOrdering == Qt::strong_ordering::greater) + QCOMPARE_GT(lhs, rhs); + QCborArray array{lhs, rhs}; QCborValueConstRef lhsCRef = array.constBegin()[0]; @@ -1937,7 +2122,7 @@ void tst_QCborValue::comparison() QCborValueRef lhsRef = array[0]; QCborValueRef rhsRef = array[1]; - // QCborValue vs QCborValue + // QCborValue vs QCborValue QT_TEST_ALL_COMPARISON_OPS(lhs, rhs, expectedOrdering); // QCborValueConstRef vs QCborValueConstRef QT_TEST_ALL_COMPARISON_OPS(lhsCRef, rhsCRef, expectedOrdering); @@ -1951,7 +2136,6 @@ void tst_QCborValue::comparison() QT_TEST_ALL_COMPARISON_OPS(lhsCRef, rhsRef, expectedOrdering); } - void tst_QCborValue::comparisonMap_data() { QTest::addColumn<QCborMap>("left"); @@ -2131,6 +2315,7 @@ void tst_QCborValue::toCbor_data() QTest::newRow("UseInteger:-2^65") << QCborValue(-2 * 18446744073709551616.0) << raw("\xfb\xc4\0\0\0""\0\0\0\0") << QCborValue::EncodingOptions(QCborValue::UseIntegers); } +#if QT_CONFIG(cborstreamwriter) void tst_QCborValue::toCbor() { QFETCH(QCborValue, v); @@ -2170,6 +2355,7 @@ void tst_QCborValue::toCborStreamWriter() QCOMPARE(buffer.pos(), result.size()); QCOMPARE(output, result); } +#endif void tst_QCborValue::fromCbor_data() { @@ -2487,12 +2673,14 @@ void tst_QCborValue::extendedTypeValidation() QCOMPARE(error.offset, data.size()); QT_TEST_EQUALITY_OPS(decoded, expected, true); +#if QT_CONFIG(cborstreamwriter) QByteArray encoded = decoded.toCbor(); #if QT_VERSION < QT_VERSION_CHECK(6,0,0) // behavior change, see qdatetime.cpp:fromIsoTimeString QEXPECT_FAIL("DateTime:Null-at-19", "QDateTime parsing fixed, but only in 6.0", Abort); #endif QCOMPARE(encoded, data); +#endif } void tst_QCborValue::hugeDeviceValidation_data() @@ -2820,7 +3008,9 @@ template <typename ValueRef> static void cborValueRef_template() else QCOMPARE(ref.toVariant(), v.toVariant()); QCOMPARE(ref.toJsonValue(), v.toJsonValue()); +#if QT_CONFIG(cborstreamwriter) QCOMPARE(ref.toCbor(), v.toCbor()); +#endif QCOMPARE(ref.toDiagnosticNotation(), v.toDiagnosticNotation()); } @@ -2980,6 +3170,7 @@ void tst_QCborValue::datastreamSerialization_data() void tst_QCborValue::datastreamSerialization() { +#if QT_CONFIG(cborstreamwriter) QFETCH(QCborValue, v); QByteArray buffer; { @@ -3007,6 +3198,7 @@ void tst_QCborValue::datastreamSerialization() load >> output; QCOMPARE(output, map); } +#endif } void tst_QCborValue::streamVariantSerialization() diff --git a/tests/auto/corelib/serialization/qdatastream/tst_qdatastream.cpp b/tests/auto/corelib/serialization/qdatastream/tst_qdatastream.cpp index 77ca884897..9a227c782d 100644 --- a/tests/auto/corelib/serialization/qdatastream/tst_qdatastream.cpp +++ b/tests/auto/corelib/serialization/qdatastream/tst_qdatastream.cpp @@ -143,9 +143,11 @@ private slots: void stream_QJsonObject(); void stream_QJsonValue(); +#if QT_CONFIG(cborstreamwriter) void stream_QCborArray(); void stream_QCborMap(); void stream_QCborValue(); +#endif void setVersion_data(); void setVersion(); @@ -2326,6 +2328,7 @@ void tst_QDataStream::stream_QJsonValue() } } +#if QT_CONFIG(cborstreamwriter) void tst_QDataStream::stream_QCborArray() { QByteArray buffer; @@ -2361,6 +2364,7 @@ void tst_QDataStream::stream_QCborValue() load >> valueLoad; QCOMPARE(valueLoad, valueSave); } +#endif void tst_QDataStream::setVersion_data() { @@ -3254,11 +3258,13 @@ void tst_QDataStream::streamRealDataTypes() // Generate QPicture from pixmap. QPixmap pm(open_xpm); QVERIFY(!pm.isNull()); +#ifndef QT_NO_PICTURE QPicture picture; picture.setBoundingRect(QRect(QPoint(0, 0), pm.size())); QPainter painter(&picture); painter.drawPixmap(0, 0, pm); painter.end(); +#endif // Generate path QPainterPath path; @@ -3296,7 +3302,9 @@ void tst_QDataStream::streamRealDataTypes() stream << QPointF(3, 5) << QRectF(-1, -2, 3, 4) << (QPolygonF() << QPointF(0, 0) << QPointF(1, 2)); stream << QTransform().rotate(90).scale(2, 2).asAffineMatrix(); stream << path; +#ifndef QT_NO_PICTURE stream << picture; +#endif stream << QTextLength(QTextLength::VariableLength, 1.5); stream << color; stream << radialBrush << conicalBrush; @@ -3310,7 +3318,9 @@ void tst_QDataStream::streamRealDataTypes() QPolygonF polygon {{3, 4}, {5, 6}}; QTransform transform; QPainterPath p = otherPath; +#ifndef QT_NO_PICTURE QPicture pict; +#endif QTextLength textLength(QTextLength::FixedLength, 2.5); QColor col(128, 128, 127); QBrush rGrad(Qt::CrossPattern); @@ -3363,6 +3373,7 @@ void tst_QDataStream::streamRealDataTypes() QCOMPARE(transform, QTransform().rotate(90).scale(2, 2)); stream >> p; QCOMPARE(p, path); +#ifndef QT_NO_PICTURE if (i == 1) { stream >> pict; @@ -3376,6 +3387,7 @@ void tst_QDataStream::streamRealDataTypes() QCOMPARE(pictA, pictB); } +#endif stream >> textLength; QCOMPARE(textLength, QTextLength(QTextLength::VariableLength, 1.5)); stream >> col; diff --git a/tests/auto/corelib/serialization/qxmlstream/tst_qxmlstream.cpp b/tests/auto/corelib/serialization/qxmlstream/tst_qxmlstream.cpp index 0b7d9ab0ed..b90d05b0fa 100644 --- a/tests/auto/corelib/serialization/qxmlstream/tst_qxmlstream.cpp +++ b/tests/auto/corelib/serialization/qxmlstream/tst_qxmlstream.cpp @@ -95,8 +95,8 @@ static QByteArray makeCanonical(const QString &filename, bool testIncremental = false) { QFile file(filename); - file.open(QIODevice::ReadOnly); - + if (!file.open(QIODevice::ReadOnly)) + qFatal("Could not open file %s", qPrintable(filename)); QXmlStreamReader reader; QByteArray buffer; @@ -572,6 +572,14 @@ private slots: void hasAttribute() const; void writeWithUtf8Codec() const; void writeWithStandalone() const; + void writeCharacters_data() const; + void writeCharacters() const; + void writeAttribute_data() const; + void writeAttribute() const; + void writeBadCharactersUtf8_data() const; + void writeBadCharactersUtf8() const; + void writeBadCharactersUtf16_data() const; + void writeBadCharactersUtf16() const; void entitiesAndWhitespace_1() const; void entitiesAndWhitespace_2() const; void testFalsePrematureError() const; @@ -747,7 +755,8 @@ void tst_QXmlStream::reportSuccess_data() const QByteArray tst_QXmlStream::readFile(const QString &filename) { QFile file(filename); - file.open(QIODevice::ReadOnly); + if (!file.open(QIODevice::ReadOnly)) + qFatal("Could not open file %s", qPrintable(filename)); QXmlStreamReader reader; @@ -1406,6 +1415,143 @@ void tst_QXmlStream::writeWithStandalone() const } } +static void writeCharacters_data_common() +{ + QTest::addColumn<QString>("input"); + QTest::addColumn<QString>("output"); + + QTest::newRow("empty") << QString() << QString(); + + // invalid content + QTest::newRow("null-character") << u"\0"_s << QString(); + QTest::newRow("vertical-tab") << "\v" << QString(); + QTest::newRow("form-feed") << "\f" << QString(); + QTest::newRow("esc") << "\x1f" << QString(); + QTest::newRow("U+FFFE") << u"\xfffe"_s << QString(); + QTest::newRow("U+FFFF") << u"\xffff"_s << QString(); + + // simple strings + QTest::newRow("us-ascii") << "Hello, world" << "Hello, world"; + QTest::newRow("latin1") << "Bokmål" << "Bokmål"; + QTest::newRow("nonlatin1") << "Ελληνικά" << "Ελληνικά"; + QTest::newRow("nonbmp") << u"\U00010000"_s << u"\U00010000"_s; + + // escaped content + QTest::newRow("less-than") << "<" << "<"; + QTest::newRow("greater-than") << ">" << ">"; + QTest::newRow("ampersand") << "&" << "&"; + QTest::newRow("quote") << "\"" << """; +} + +template <typename Execute, typename Transform> +static void writeCharacters_common(Execute &&exec, Transform &&transform) +{ + QFETCH(QString, input); + QFETCH(QString, output); + QStringView utf16 = input; + QByteArray utf8ba = input.toUtf8(); + QUtf8StringView utf8(utf8ba); + + // may be invalid if input is not Latin1 + QByteArray l1ba = input.toLatin1(); + QLatin1StringView l1(l1ba); + if (l1 != input) + l1 = {}; + + auto write = [&](auto input) -> std::optional<QString> { + QString result; + QXmlStreamWriter writer(&result); + writer.writeStartElement("a"); + exec(writer, input); + writer.writeEndElement(); + if (writer.hasError()) + return std::nullopt; + return result; + }; + + if (input.isNull() != output.isNull()) { + // error + QCOMPARE(write(utf16), std::nullopt); + QCOMPARE(write(utf8), std::nullopt); + if (!l1.isEmpty()) + QCOMPARE(write(l1), std::nullopt); + } else { + output = transform(output); + QCOMPARE(write(utf16), output); + QCOMPARE(write(utf8), output); + if (!l1.isEmpty()) + QCOMPARE(write(l1), output); + } +} + +void tst_QXmlStream::writeCharacters_data() const +{ + writeCharacters_data_common(); + QTest::newRow("tab") << "\t" << "\t"; + QTest::newRow("newline") << "\n" << "\n"; + QTest::newRow("carriage-return") << "\r" << "\r"; +} + +void tst_QXmlStream::writeCharacters() const +{ + auto exec = [](QXmlStreamWriter &writer, auto input) { + writer.writeCharacters(input); + }; + auto transform = [](auto output) { return "<a>" + output + "</a>"; }; + writeCharacters_common(exec, transform); +} + +void tst_QXmlStream::writeAttribute_data() const +{ + writeCharacters_data_common(); + QTest::newRow("tab") << "\t" << "	"; + QTest::newRow("newline") << "\n" << " "; + QTest::newRow("carriage-return") << "\r" << " "; +} + +void tst_QXmlStream::writeAttribute() const +{ + auto exec = [](QXmlStreamWriter &writer, auto input) { + writer.writeAttribute("b", input); + }; + auto transform = [](auto output) { return "<a b=\"" + output + "\"/>"; }; + writeCharacters_common(exec, transform); +} + +#include "../../io/qurlinternal/utf8data.cpp" +void tst_QXmlStream::writeBadCharactersUtf8_data() const +{ + QTest::addColumn<QByteArray>("input"); + loadInvalidUtf8Rows(); +} + +void tst_QXmlStream::writeBadCharactersUtf8() const +{ + QFETCH(QByteArray, input); + QString target; + QXmlStreamWriter writer(&target); + writer.writeTextElement("a", QUtf8StringView(input)); + QVERIFY(writer.hasError()); +} + +void tst_QXmlStream::writeBadCharactersUtf16_data() const +{ + QTest::addColumn<QString>("input"); + QTest::addRow("low-surrogate") << u"\xdc00"_s; + QTest::addRow("high-surrogate") << u"\xd800"_s; + QTest::addRow("inverted-surrogate-pair") << u"\xdc00\xd800"_s; + QTest::addRow("high-surrogate+non-surrogate") << u"\xd800z"_s; +} + +void tst_QXmlStream::writeBadCharactersUtf16() const +{ + QFETCH(QString, input); + QString target; + QXmlStreamWriter writer(&target); + writer.writeTextElement("a", input); + QVERIFY(writer.hasError()); +} + void tst_QXmlStream::entitiesAndWhitespace_1() const { QXmlStreamReader reader(QLatin1String("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\"><test>&extEnt;</test>")); diff --git a/tests/auto/corelib/text/qanystringview/tst_qanystringview.cpp b/tests/auto/corelib/text/qanystringview/tst_qanystringview.cpp index 0eaadb870c..398be96530 100644 --- a/tests/auto/corelib/text/qanystringview/tst_qanystringview.cpp +++ b/tests/auto/corelib/text/qanystringview/tst_qanystringview.cpp @@ -356,6 +356,29 @@ private Q_SLOTS: fromLiteral(u8"Hello, World!"); // char[] in <= C++17, char8_t[] in >= C++20 } + void fromChar() const { fromCharacter('\xE4', 1); } + void fromUChar() const { fromCharacter(static_cast<unsigned char>('\xE4'), 1); } + void fromSChar() const { fromCharacter(static_cast<signed char>('\xE4'), 1); } + void fromChar16T() const { fromCharacter(u'ä', 1); } + void fromUShort() const { fromCharacter(ushort(0xE4), 1); } + void fromChar32T() const { + fromCharacter(U'ä', 1); + if (QTest::currentTestFailed()) + return; + fromCharacter(U'\x1F0A0', 2); // U+1F0A0: PLAYING CARD BACK + } + void fromWCharT() const { + ONLY_WIN(fromCharacter(L'ä', 1)); // should work on Unix, too (char32_t does) + } + void fromQChar() const { fromCharacter(QChar(u'ä'), 1); } + void fromQLatin1Char() const { fromCharacter(QLatin1Char('\xE4'), 1); } + void fromQCharSpecialCharacter() const { + fromCharacter(QChar::ReplacementCharacter, 1); + if (QTest::currentTestFailed()) + return; + fromCharacter(QChar::LastValidCodePoint, 1); + } + void fromChar16TStar() const { fromLiteral(u"Hello, World!"); } void fromWCharTStar() const { ONLY_WIN(fromLiteral(L"Hello, World!")); } @@ -393,6 +416,8 @@ private: template <typename Char> void fromLiteral(const Char *arg) const; template <typename Char> + void fromCharacter(Char arg, qsizetype expectedSize) const; + template <typename Char> void fromRange() const; template <typename Char, typename Container> void fromContainer() const; @@ -673,6 +698,44 @@ void tst_QAnyStringView::fromLiteral(const Char *arg) const conversion_tests(arg); } +template<typename Char> +void tst_QAnyStringView::fromCharacter(Char arg, qsizetype expectedSize) const +{ + // Need to re-create a new QASV(arg) each time, QASV(Char).data() dangles + // after the end of the Full Expression: + + static_assert(noexcept(QAnyStringView(arg)), + "If this fails, we may be creating a temporary QString/QByteArray"); + + QCOMPARE(QAnyStringView(arg).size(), expectedSize); + + // QCOMPARE(QAnyStringView(arg), arg); // not all pairs compile, so do it manually: + + // Check implicit conversion: + const QChar chars[] = { + [](QAnyStringView v) { return v.front(); }(arg), + [](QAnyStringView v) { return v.back(); }(arg), + }; + + switch (expectedSize) { + case 1: + if constexpr (std::is_same_v<Char, signed char>) // QChar doesn't have a ctor for this + QCOMPARE(chars[0], QChar(uchar(arg))); + else + QCOMPARE(chars[0], QChar(arg)); + break; + case 2: + QCOMPARE_EQ(QAnyStringView(arg), QStringView::fromArray(chars)); + if constexpr (std::is_convertible_v<Char, char32_t>) + QCOMPARE_EQ(QAnyStringView(arg), QStringView(QChar::fromUcs4(arg))); + break; + default: + QFAIL("Don't know how to compare this type to QAnyStringView"); + } + + // conversion_tests() would produce dangling references +} + template <typename Char> void tst_QAnyStringView::fromRange() const { diff --git a/tests/auto/corelib/text/qbytearrayview/CMakeLists.txt b/tests/auto/corelib/text/qbytearrayview/CMakeLists.txt index c78a81c7bd..8922ae2267 100644 --- a/tests/auto/corelib/text/qbytearrayview/CMakeLists.txt +++ b/tests/auto/corelib/text/qbytearrayview/CMakeLists.txt @@ -15,3 +15,10 @@ qt_internal_add_test(tst_qbytearrayview SOURCES tst_qbytearrayview.cpp ) + +if(QT_FEATURE_sanitize_undefined) + qt_internal_extend_target(tst_qbytearrayview + DEFINES + QT_SANITIZE_UNDEFINED # GCC (in)famously doesn't provide a predefined macro for this + ) +endif() diff --git a/tests/auto/corelib/text/qbytearrayview/tst_qbytearrayview.cpp b/tests/auto/corelib/text/qbytearrayview/tst_qbytearrayview.cpp index 894f0430dd..702e1840da 100644 --- a/tests/auto/corelib/text/qbytearrayview/tst_qbytearrayview.cpp +++ b/tests/auto/corelib/text/qbytearrayview/tst_qbytearrayview.cpp @@ -262,10 +262,9 @@ void tst_QByteArrayView::constExpr() const static_assert(!bv2.empty()); static_assert(bv2.size() == 5); } -#if !defined(Q_CC_GNU) || defined(Q_CC_CLANG) +#if !defined(Q_CC_GNU_ONLY) || !defined(QT_SANITIZE_UNDEFINED) // Below checks are disabled because of a compilation issue with GCC and // -fsanitize=undefined. See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71962. - // Note: Q_CC_GNU is also defined for Clang, so we need to check that too. { static constexpr char hello[] = "Hello"; constexpr QByteArrayView bv(hello); @@ -307,6 +306,9 @@ void tst_QByteArrayView::constExpr() const static_assert(bv.back() == 'o'); static_assert(bv.last() == 'o'); + constexpr auto bv2 = QByteArrayView::fromArray(hello); + QCOMPARE_EQ(bv, bv2); + constexpr std::string_view sv = bv; static_assert(bv.size() == sv.size()); #ifdef AMBIGUOUS_CALL // QTBUG-108805 @@ -416,7 +418,7 @@ void tst_QByteArrayView::fromArray() const { static constexpr char hello[] = "Hello\0abc\0\0."; - constexpr QByteArrayView bv = QByteArrayView::fromArray(hello); + const QByteArrayView bv = QByteArrayView::fromArray(hello); QCOMPARE(bv.size(), 13); QVERIFY(!bv.empty()); QVERIFY(!bv.isEmpty()); diff --git a/tests/auto/corelib/text/qlatin1stringmatcher/tst_qlatin1stringmatcher.cpp b/tests/auto/corelib/text/qlatin1stringmatcher/tst_qlatin1stringmatcher.cpp index 82e12bdfca..ba098fd23c 100644 --- a/tests/auto/corelib/text/qlatin1stringmatcher/tst_qlatin1stringmatcher.cpp +++ b/tests/auto/corelib/text/qlatin1stringmatcher/tst_qlatin1stringmatcher.cpp @@ -25,6 +25,7 @@ class tst_QLatin1StringMatcher : public QObject private slots: void overloads(); void staticOverloads(); + void staticOverloads_QStringViewHaystack(); void interface(); void indexIn(); void haystacksWithMoreThan4GiBWork(); @@ -44,6 +45,12 @@ void tst_QLatin1StringMatcher::overloads() QCOMPARE(m.indexIn("Hellohello"_L1), 5); QCOMPARE(m.indexIn("helloHello"_L1), 0); QCOMPARE(m.indexIn("helloHello"_L1, 1), -1); + + QCOMPARE(m.indexIn(u"hello"), 0); + QCOMPARE(m.indexIn(u"Hello"), -1); + QCOMPARE(m.indexIn(u"Hellohello"), 5); + QCOMPARE(m.indexIn(u"helloHello"), 0); + QCOMPARE(m.indexIn(u"helloHello", 1), -1); } { QLatin1StringMatcher m("Hello"_L1, Qt::CaseSensitive); @@ -53,6 +60,12 @@ void tst_QLatin1StringMatcher::overloads() QCOMPARE(m.indexIn("Hellohello"_L1), 0); QCOMPARE(m.indexIn("helloHello"_L1), 5); QCOMPARE(m.indexIn("helloHello"_L1, 6), -1); + + QCOMPARE(m.indexIn(u"hello"), -1); + QCOMPARE(m.indexIn(u"Hello"), 0); + QCOMPARE(m.indexIn(u"Hellohello"), 0); + QCOMPARE(m.indexIn(u"helloHello"), 5); + QCOMPARE(m.indexIn(u"helloHello", 6), -1); } { QLatin1StringMatcher m("hello"_L1, Qt::CaseInsensitive); @@ -63,6 +76,13 @@ void tst_QLatin1StringMatcher::overloads() QCOMPARE(m.indexIn("helloHello"_L1), 0); QCOMPARE(m.indexIn("helloHello"_L1, 1), 5); QCOMPARE(m.indexIn("helloHello"_L1, 6), -1); + + QCOMPARE(m.indexIn(u"hello"), 0); + QCOMPARE(m.indexIn(u"Hello"), 0); + QCOMPARE(m.indexIn(u"Hellohello"), 0); + QCOMPARE(m.indexIn(u"helloHello"), 0); + QCOMPARE(m.indexIn(u"helloHello", 1), 5); + QCOMPARE(m.indexIn(u"helloHello", 6), -1); } { QLatin1StringMatcher m("Hello"_L1, Qt::CaseInsensitive); @@ -73,6 +93,13 @@ void tst_QLatin1StringMatcher::overloads() QCOMPARE(m.indexIn("helloHello"_L1), 0); QCOMPARE(m.indexIn("helloHello"_L1, 1), 5); QCOMPARE(m.indexIn("helloHello"_L1, 6), -1); + + QCOMPARE(m.indexIn(u"hello"), 0); + QCOMPARE(m.indexIn(u"Hello"), 0); + QCOMPARE(m.indexIn(u"Hellohello"), 0); + QCOMPARE(m.indexIn(u"helloHello"), 0); + QCOMPARE(m.indexIn(u"helloHello", 1), 5); + QCOMPARE(m.indexIn(u"helloHello", 6), -1); } { QLatin1StringMatcher m(hello, Qt::CaseSensitive); @@ -81,6 +108,11 @@ void tst_QLatin1StringMatcher::overloads() QCOMPARE(m.indexIn(hello, 1), -1); QCOMPARE(m.indexIn(hello2, 1), hello.size()); QCOMPARE(m.indexIn(hello2, 6), -1); + + QCOMPARE(m.indexIn(QString::fromLatin1(hello)), 0); + QCOMPARE(m.indexIn(QString::fromLatin1(hello), 1), -1); + QCOMPARE(m.indexIn(QString::fromLatin1(hello2), 1), hello.size()); + QCOMPARE(m.indexIn(QString::fromLatin1(hello2), 6), -1); } } @@ -206,6 +238,129 @@ void tst_QLatin1StringMatcher::staticOverloads() #endif } +void tst_QLatin1StringMatcher::staticOverloads_QStringViewHaystack() +{ +#ifdef QT_STATIC_BOYER_MOORE_NOT_SUPPORTED + QSKIP("Test is only valid on an OS that supports static latin1 string matcher"); +#else + constexpr QStringView hello = u"hello"; + QString hello2B = QStringView(hello).toString().repeated(2); + hello2B += QStringView(u"🍉"); + QStringView hello2(hello2B); + { + static constexpr auto m = qMakeStaticCaseSensitiveLatin1StringMatcher("hel"); + QCOMPARE(m.indexIn(QStringView(u"hello🍉")), 0); + QCOMPARE(m.indexIn(QStringView(u"Hello🍉")), -1); + QCOMPARE(m.indexIn(QStringView(u"Hellohello🍉")), 5); + QCOMPARE(m.indexIn(QStringView(u"helloHello🍉")), 0); + QCOMPARE(m.indexIn(QStringView(u"he🍉")), -1); + QCOMPARE(m.indexIn(QStringView(u"hel🍉")), 0); + QCOMPARE(m.indexIn(hello), 0); + QCOMPARE(m.indexIn(hello, 1), -1); // from is 1 + QCOMPARE(m.indexIn(hello2, 2), hello.size()); // from is 2 + QCOMPARE(m.indexIn(hello2, 3), hello.size()); // from is 3 + QCOMPARE(m.indexIn(hello2, 6), -1); // from is 6 + static_assert(m.indexIn(QStringView(u"hello🍉")) == 0); + static_assert(m.indexIn(QStringView(u"Hello🍉")) == -1); + static_assert(m.indexIn(QStringView(u"Hellohello🍉")) == 5); + static_assert(m.indexIn(QStringView(u"helloHello🍉")) == 0); + static_assert(m.indexIn(QStringView(u"he🍉")) == -1); + static_assert(m.indexIn(QStringView(u"hel🍉")) == 0); + static_assert(m.indexIn(QStringView(u"hellohello🍉"), 2) == 5); // from is 2 + static_assert(m.indexIn(QStringView(u"hellohello🍉"), 3) == 5); // from is 3 + static_assert(m.indexIn(QStringView(u"hellohello🍉"), 6) == -1); // from is 6 + } + { + static constexpr auto m = qMakeStaticCaseSensitiveLatin1StringMatcher("Hel"); + QCOMPARE(m.indexIn(QStringView(u"hello🍉")), -1); + QCOMPARE(m.indexIn(QStringView(u"Hello🍉")), 0); + QCOMPARE(m.indexIn(QStringView(u"Hellohello🍉")), 0); + QCOMPARE(m.indexIn(QStringView(u"helloHello🍉")), 5); + QCOMPARE(m.indexIn(QStringView(u"helloHello🍉"), 6), -1); + QCOMPARE(m.indexIn(QStringView(u"He🍉")), -1); + QCOMPARE(m.indexIn(QStringView(u"Hel🍉")), 0); + QCOMPARE(m.indexIn(hello), -1); + QCOMPARE(m.indexIn(hello2, 2), -1); // from is 2 + QCOMPARE(m.indexIn(hello2, 6), -1); // from is 6 + static_assert(m.indexIn(QStringView(u"hello🍉")) == -1); + static_assert(m.indexIn(QStringView(u"Hello🍉")) == 0); + static_assert(m.indexIn(QStringView(u"Hellohello🍉")) == 0); + static_assert(m.indexIn(QStringView(u"helloHello🍉")) == 5); + static_assert(m.indexIn(QStringView(u"helloHello🍉"), 6) == -1); + static_assert(m.indexIn(QStringView(u"He🍉")) == -1); + static_assert(m.indexIn(QStringView(u"Hel🍉")) == 0); + static_assert(m.indexIn(QStringView(u"hellohello🍉"), 2) == -1); // from is 2 + static_assert(m.indexIn(QStringView(u"hellohello🍉"), 6) == -1); // from is 6 + } + { + static constexpr auto m = qMakeStaticCaseInsensitiveLatin1StringMatcher("hel"); + QCOMPARE(m.indexIn(QStringView(u"hello🍉")), 0); + QCOMPARE(m.indexIn(QStringView(u"Hello🍉")), 0); + QCOMPARE(m.indexIn(QStringView(u"Hellohello🍉")), 0); + QCOMPARE(m.indexIn(QStringView(u"helloHello🍉")), 0); + QCOMPARE(m.indexIn(QStringView(u"he🍉")), -1); + QCOMPARE(m.indexIn(QStringView(u"hel🍉")), 0); + QCOMPARE(m.indexIn(hello), 0); + QCOMPARE(m.indexIn(hello, 1), -1); + QCOMPARE(m.indexIn(hello2, 2), hello.size()); // from is 2 + QCOMPARE(m.indexIn(hello2, 3), hello.size()); // from is 3 + QCOMPARE(m.indexIn(hello2, 6), -1); // from is 6 + static_assert(m.indexIn(QStringView(u"hello🍉")) == 0); + static_assert(m.indexIn(QStringView(u"Hello🍉")) == 0); + static_assert(m.indexIn(QStringView(u"Hellohello🍉")) == 0); + static_assert(m.indexIn(QStringView(u"helloHello🍉")) == 0); + static_assert(m.indexIn(QStringView(u"he🍉")) == -1); + static_assert(m.indexIn(QStringView(u"hel🍉")) == 0); + static_assert(m.indexIn(QStringView(u"hellohello🍉"), 2) == 5); // from is 2 + static_assert(m.indexIn(QStringView(u"hellohello🍉"), 3) == 5); // from is 3 + static_assert(m.indexIn(QStringView(u"hellohello🍉"), 6) == -1); // from is 6 + } + { + static constexpr auto m = qMakeStaticCaseInsensitiveLatin1StringMatcher("Hel"); + QCOMPARE(m.indexIn(QStringView(u"hello🍉")), 0); + QCOMPARE(m.indexIn(QStringView(u"Hello🍉")), 0); + QCOMPARE(m.indexIn(QStringView(u"Hellohello🍉")), 0); + QCOMPARE(m.indexIn(QStringView(u"helloHello🍉")), 0); + QCOMPARE(m.indexIn(QStringView(u"he🍉")), -1); + QCOMPARE(m.indexIn(QStringView(u"hel🍉")), 0); + QCOMPARE(m.indexIn(hello), 0); + QCOMPARE(m.indexIn(hello, 1), -1); + QCOMPARE(m.indexIn(hello2, 2), hello.size()); // from is 2 + QCOMPARE(m.indexIn(hello2, 3), hello.size()); // from is 3 + QCOMPARE(m.indexIn(hello2, 6), -1); // from is 6 + static_assert(m.indexIn(QStringView(u"hello🍉")) == 0); + static_assert(m.indexIn(QStringView(u"Hello🍉")) == 0); + static_assert(m.indexIn(QStringView(u"Hellohello🍉")) == 0); + static_assert(m.indexIn(QStringView(u"helloHello🍉")) == 0); + static_assert(m.indexIn(QStringView(u"he🍉")) == -1); + static_assert(m.indexIn(QStringView(u"hel🍉")) == 0); + static_assert(m.indexIn(QStringView(u"hellohello🍉"), 2) == 5); // from is 2 + static_assert(m.indexIn(QStringView(u"hellohello🍉"), 3) == 5); // from is 3 + static_assert(m.indexIn(QStringView(u"hellohello🍉"), 6) == -1); // from is 6 + } + { + static constexpr auto m = qMakeStaticCaseInsensitiveLatin1StringMatcher("b\xF8"); + QCOMPARE(m.indexIn(QStringView(u"B\xD8")), 0); + QCOMPARE(m.indexIn(QStringView(u"B\xF8")), 0); + QCOMPARE(m.indexIn(QStringView(u"b\xD8")), 0); + QCOMPARE(m.indexIn(QStringView(u"b\xF8")), 0); + QCOMPARE(m.indexIn(QStringView(u"b\xF8lle")), 0); + QCOMPARE(m.indexIn(QStringView(u"m\xF8lle")), -1); + QCOMPARE(m.indexIn(QStringView(u"Si b\xF8")), 3); + } + { + static constexpr auto m = qMakeStaticCaseSensitiveLatin1StringMatcher("b\xF8"); + QCOMPARE(m.indexIn(QStringView(u"B\xD8")), -1); + QCOMPARE(m.indexIn(QStringView(u"B\xF8")), -1); + QCOMPARE(m.indexIn(QStringView(u"b\xD8")), -1); + QCOMPARE(m.indexIn(QStringView(u"b\xF8")), 0); + QCOMPARE(m.indexIn(QStringView(u"b\xF8lle")), 0); + QCOMPARE(m.indexIn(QStringView(u"m\xF8lle")), -1); + QCOMPARE(m.indexIn(QStringView(u"Si b\xF8")), 3); + } +#endif +} + void tst_QLatin1StringMatcher::interface() { QLatin1StringView needle = "abc123"_L1; @@ -387,25 +542,35 @@ void tst_QLatin1StringMatcher::haystacksWithMoreThan4GiBWork() QCOMPARE(large.size(), BaseSize + needle.size()); qDebug("created dataset in %lld ms", timer.elapsed()); - using MaybeThread = std::thread; - - // - // WHEN: trying to match an occurrence past the 4GiB mark - // - - qsizetype dynamicResult; - - auto t = MaybeThread{ [&] { - QLatin1StringMatcher m(QLatin1StringView(needle), Qt::CaseSensitive); - dynamicResult = m.indexIn(QLatin1StringView(large)); - } }; - t.join(); + { + // + // WHEN: trying to match an occurrence past the 4GiB mark + // + qsizetype dynamicResult; + auto t = std::thread{ [&] { + QLatin1StringMatcher m(QLatin1StringView(needle), Qt::CaseSensitive); + dynamicResult = m.indexIn(QLatin1StringView(large)); + } }; + t.join(); + + // + // THEN: the result index is not truncated + // + + QCOMPARE(dynamicResult, qsizetype(BaseSize)); + } - // - // THEN: the result index is not trucated - // + { + qsizetype dynamicResult; + auto t = std::thread{ [&] { + QLatin1StringMatcher m(QLatin1StringView(needle), Qt::CaseSensitive); + dynamicResult = m.indexIn(QStringView(QString::fromLatin1(large))); + } }; + t.join(); + + QCOMPARE(dynamicResult, qsizetype(BaseSize)); + } - QCOMPARE(dynamicResult, qsizetype(BaseSize)); #else QSKIP("This test is 64-bit only."); #endif diff --git a/tests/auto/corelib/text/qlocale/CMakeLists.txt b/tests/auto/corelib/text/qlocale/CMakeLists.txt index 3e6693d12b..a91dd44ea5 100644 --- a/tests/auto/corelib/text/qlocale/CMakeLists.txt +++ b/tests/auto/corelib/text/qlocale/CMakeLists.txt @@ -8,4 +8,6 @@ if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) endif() add_subdirectory(test) -add_subdirectory(syslocaleapp) +if(QT_FEATURE_jalalicalendar) + add_subdirectory(syslocaleapp) +endif() diff --git a/tests/auto/corelib/text/qlocale/test/CMakeLists.txt b/tests/auto/corelib/text/qlocale/test/CMakeLists.txt index 54ab71ea81..fc3e1488cd 100644 --- a/tests/auto/corelib/text/qlocale/test/CMakeLists.txt +++ b/tests/auto/corelib/text/qlocale/test/CMakeLists.txt @@ -11,6 +11,7 @@ qt_internal_add_test(tst_qlocale ../tst_qlocale.cpp LIBRARIES Qt::CorePrivate + Qt::TestPrivate ) ## Scopes: diff --git a/tests/auto/corelib/text/qlocale/tst_qlocale.cpp b/tests/auto/corelib/text/qlocale/tst_qlocale.cpp index 8cc7f9af6e..eb2d73b9b2 100644 --- a/tests/auto/corelib/text/qlocale/tst_qlocale.cpp +++ b/tests/auto/corelib/text/qlocale/tst_qlocale.cpp @@ -2,6 +2,7 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QTest> +#include <QtTest/private/qcomparisontesthelper_p.h> #include <QLocale> #include <QDateTime> @@ -40,6 +41,7 @@ public: private slots: void initTestCase(); + void compareCompiles(); #if defined(Q_OS_WIN) void windowsDefaultLocale(); #endif @@ -189,6 +191,11 @@ tst_QLocale::tst_QLocale() qRegisterMetaType<QLocale::FormatType>("QLocale::FormatType"); } +void tst_QLocale::compareCompiles() +{ + QTestPrivate::testEqualityOperatorsCompile<QLocale>(); +} + void tst_QLocale::initTestCase() { #ifdef Q_OS_ANDROID @@ -741,8 +748,8 @@ void tst_QLocale::legacyNames() void tst_QLocale::consistentC() { const QLocale c(QLocale::C); - QCOMPARE(c, QLocale::c()); - QCOMPARE(c, QLocale(QLocale::C, QLocale::AnyScript, QLocale::AnyTerritory)); + QT_TEST_EQUALITY_OPS(c, QLocale::c(), true); + QT_TEST_EQUALITY_OPS(c, QLocale(QLocale::C, QLocale::AnyScript, QLocale::AnyTerritory), true); QVERIFY(QLocale::matchingLocales(QLocale::AnyLanguage, QLocale::AnyScript, QLocale::AnyTerritory).contains(c)); } @@ -751,6 +758,7 @@ void tst_QLocale::matchingLocales() { const QLocale c(QLocale::C); const QLocale ru_RU(QLocale::Russian, QLocale::Russia); + QT_TEST_EQUALITY_OPS(c, ru_RU, false); QList<QLocale> locales = QLocale::matchingLocales(QLocale::C, QLocale::AnyScript, QLocale::AnyTerritory); QCOMPARE(locales.size(), 1); @@ -1618,6 +1626,11 @@ void tst_QLocale::infNaN() { // TODO: QTBUG-95460 -- could support localized forms of inf/NaN const QLocale c(QLocale::C); + + QT_TEST_EQUALITY_OPS(QLocale(), QLocale(QLocale::C), false); + QT_TEST_EQUALITY_OPS(QLocale(), QLocale(), true); + QT_TEST_EQUALITY_OPS(QLocale(QLocale::C), c, true); + QCOMPARE(c.toString(qQNaN()), u"nan"); QCOMPARE(c.toString(qQNaN(), 'e'), u"nan"); QCOMPARE(c.toString(qQNaN(), 'f'), u"nan"); @@ -2966,6 +2979,7 @@ void tst_QLocale::numberOptions() QVERIFY(ok); locale.toDouble(QString("12.400"), &ok); QVERIFY(!ok); + QT_TEST_EQUALITY_OPS(locale, locale2, false); } void tst_QLocale::negativeNumbers() @@ -3030,6 +3044,7 @@ void tst_QLocale::negativeNumbers() i = farsi.toInt(u"\u200e+\u06f4\u06f0\u06f3"_s, &ok); QVERIFY(ok); QCOMPARE(i, 403); + QT_TEST_EQUALITY_OPS(egypt, farsi, false); } #include <private/qlocale_p.h> @@ -3288,6 +3303,11 @@ void tst_QLocale::dateFormat() const QLocale ir("ga_IE"); QCOMPARE(ir.dateFormat(QLocale::ShortFormat), QLatin1String("dd/MM/yyyy")); + QT_TEST_EQUALITY_OPS(c, no, false); + QT_TEST_EQUALITY_OPS(ca, ja, false); + QT_TEST_EQUALITY_OPS(ca, ir, false); + QT_TEST_EQUALITY_OPS(ir, ja, false); + const auto sys = QLocale::system(); // QTBUG-92018, ru_RU on MS const QDate date(2021, 3, 17); QCOMPARE(sys.toString(date, sys.dateFormat(QLocale::LongFormat)), sys.toString(date)); @@ -3327,19 +3347,29 @@ void tst_QLocale::timeFormat() const QLocale no("no_NO"); QCOMPARE(no.timeFormat(QLocale::NarrowFormat), QLatin1String("HH:mm")); QCOMPARE(no.timeFormat(QLocale::ShortFormat), QLatin1String("HH:mm")); - QCOMPARE(no.timeFormat(QLocale::LongFormat), QLatin1String("HH:mm:ss t")); + QCOMPARE(no.timeFormat(QLocale::LongFormat), "HH:mm:ss tttt"_L1); const QLocale id("id_ID"); QCOMPARE(id.timeFormat(QLocale::ShortFormat), QLatin1String("HH.mm")); - QCOMPARE(id.timeFormat(QLocale::LongFormat), QLatin1String("HH.mm.ss t")); + QCOMPARE(id.timeFormat(QLocale::LongFormat), "HH.mm.ss tttt"_L1); const QLocale cat("ca_ES"); QCOMPARE(cat.timeFormat(QLocale::ShortFormat), QLatin1String("H:mm")); - QCOMPARE(cat.timeFormat(QLocale::LongFormat), QLatin1String("H:mm:ss (t)")); + QCOMPARE(cat.timeFormat(QLocale::LongFormat), "H:mm:ss (tttt)"_L1); const QLocale bra("pt_BR"); QCOMPARE(bra.timeFormat(QLocale::ShortFormat), QLatin1String("HH:mm")); - QCOMPARE(bra.timeFormat(QLocale::LongFormat), QLatin1String("HH:mm:ss t")); + QCOMPARE(bra.timeFormat(QLocale::LongFormat), "HH:mm:ss tttt"_L1); + + // QTBUG-123872 - we kludge CLDR's B to Ap: + const QLocale tw("zh_TW"); + QCOMPARE(tw.timeFormat(QLocale::ShortFormat), "Aph:mm"_L1); + QCOMPARE(tw.timeFormat(QLocale::LongFormat), "Aph:mm:ss [tttt]"_L1); + + QT_TEST_EQUALITY_OPS(c, no, false); + QT_TEST_EQUALITY_OPS(id, no, false); + QT_TEST_EQUALITY_OPS(c, cat, false); + QT_TEST_EQUALITY_OPS(bra, no, false); } void tst_QLocale::dateTimeFormat() @@ -3351,7 +3381,9 @@ void tst_QLocale::dateTimeFormat() const QLocale no("no_NO"); QCOMPARE(no.dateTimeFormat(QLocale::NarrowFormat), QLatin1String("dd.MM.yyyy HH:mm")); QCOMPARE(no.dateTimeFormat(QLocale::ShortFormat), QLatin1String("dd.MM.yyyy HH:mm")); - QCOMPARE(no.dateTimeFormat(QLocale::LongFormat), QLatin1String("dddd d. MMMM yyyy HH:mm:ss t")); + QCOMPARE(no.dateTimeFormat(QLocale::LongFormat), "dddd d. MMMM yyyy HH:mm:ss tttt"_L1); + + QT_TEST_EQUALITY_OPS(c, no, false); } void tst_QLocale::monthName() @@ -3611,6 +3643,7 @@ void tst_QLocale::currency() const QLocale system = QLocale::system(); QVERIFY(system.toCurrencyString(1, QLatin1String("FOO")).contains(QLatin1String("FOO"))); + QT_TEST_EQUALITY_OPS(system, es_CR, false); } void tst_QLocale::quoteString() @@ -3625,6 +3658,7 @@ void tst_QLocale::quoteString() QCOMPARE(de_CH.quoteString(someText), QString::fromUtf8("\xe2\x80\x9e" "text" "\xe2\x80\x9c")); QCOMPARE(de_CH.quoteString(someText, QLocale::AlternateQuotation), QString::fromUtf8("\xe2\x80\x9a" "text" "\xe2\x80\x98")); + QT_TEST_EQUALITY_OPS(de_CH, c, false); } void tst_QLocale::uiLanguages_data() @@ -4006,19 +4040,21 @@ void tst_QLocale::bcp47Name() QTest::ignoreMessage(QtWarningMsg, "QLocale::bcp47Name(): " "Using non-ASCII separator '\u00ff' (ff) is unsupported"); QCOMPARE(locale.bcp47Name(QLocale::TagSeparator{'\xff'}), QString()); + QT_TEST_EQUALITY_OPS(locale, QLocale(QLatin1String(QTest::currentDataTag())), true); } #ifndef QT_NO_SYSTEMLOCALE # ifdef QT_BUILD_INTERNAL class MySystemLocale : public QSystemLocale { + Q_DISABLE_COPY_MOVE(MySystemLocale) public: MySystemLocale(const QString &locale) : m_name(locale), m_id(QLocaleId::fromName(locale)), m_locale(locale) { } - QVariant query(QueryType type, QVariant /*in*/) const override + QVariant query(QueryType type, QVariant &&/*in*/) const override { switch (type) { case UILanguages: @@ -4142,12 +4178,14 @@ void tst_QLocale::mySystemLocale() qDebug("\n\t%s", qPrintable(QLocale::system().uiLanguages().join(u"\n\t"))); }); QCOMPARE(QLocale::system().uiLanguages(), uiLanguages); + QCOMPARE(QLocale::system().uiLanguages(QLocale::TagSeparator::Underscore), + uiLanguages.replaceInStrings(u"-", u"_")); reporter.dismiss(); } // Verify MySystemLocale tidy-up restored prior state: - QCOMPARE(QLocale(), originalLocale); - QCOMPARE(QLocale::system(), originalSystemLocale); + QT_TEST_EQUALITY_OPS(QLocale(), originalLocale, true); + QT_TEST_EQUALITY_OPS(QLocale::system(), originalSystemLocale, true); } # endif // QT_BUILD_INTERNAL diff --git a/tests/auto/corelib/text/qregularexpression/CMakeLists.txt b/tests/auto/corelib/text/qregularexpression/CMakeLists.txt index b1d3ed0a8d..a7a7fe298f 100644 --- a/tests/auto/corelib/text/qregularexpression/CMakeLists.txt +++ b/tests/auto/corelib/text/qregularexpression/CMakeLists.txt @@ -14,4 +14,6 @@ endif() qt_internal_add_test(tst_qregularexpression SOURCES tst_qregularexpression.cpp + LIBRARIES + Qt::TestPrivate ) diff --git a/tests/auto/corelib/text/qregularexpression/tst_qregularexpression.cpp b/tests/auto/corelib/text/qregularexpression/tst_qregularexpression.cpp index ad41ae331e..d0ce414095 100644 --- a/tests/auto/corelib/text/qregularexpression/tst_qregularexpression.cpp +++ b/tests/auto/corelib/text/qregularexpression/tst_qregularexpression.cpp @@ -3,6 +3,7 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QTest> +#include <QtTest/private/qcomparisontesthelper_p.h> #include <qstring.h> #include <qlist.h> #include <qstringlist.h> @@ -27,6 +28,7 @@ public: static void initMain(); private slots: + void compareCompiles(); void defaultConstructors(); void moveSemantics(); void moveSemanticsMatch(); @@ -460,6 +462,11 @@ void tst_QRegularExpression::initMain() } } +void tst_QRegularExpression::compareCompiles() +{ + QTestPrivate::testEqualityOperatorsCompile<QRegularExpression>(); +} + void tst_QRegularExpression::defaultConstructors() { QRegularExpression re; @@ -564,12 +571,12 @@ void tst_QRegularExpression::moveSemanticsMatchIterator() QRegularExpressionMatchIterator it1 = re.globalMatch("some test"); QVERIFY(it1.isValid()); QVERIFY(it1.hasNext()); - QCOMPARE(it1.regularExpression(), re); + QT_TEST_EQUALITY_OPS(it1.regularExpression(), re, true); QRegularExpressionMatchIterator it2(std::move(it1)); QVERIFY(it2.isValid()); QVERIFY(it2.hasNext()); - QCOMPARE(it2.regularExpression(), re); + QT_TEST_EQUALITY_OPS(it2.regularExpression(), re, true); consistencyCheck(it2); if (QTest::currentTestFailed()) return; @@ -578,13 +585,13 @@ void tst_QRegularExpression::moveSemanticsMatchIterator() QRegularExpressionMatchIterator it3 = re2.globalMatch("123test456"); QVERIFY(it3.isValid()); QVERIFY(it3.hasNext()); - QCOMPARE(it3.regularExpression(), re2); + QT_TEST_EQUALITY_OPS(it3.regularExpression(), re2, true); // check that (move)assigning to the moved-from object is ok it1 = std::move(it3); QVERIFY(it1.isValid()); QVERIFY(it1.hasNext()); - QCOMPARE(it1.regularExpression(), re2); + QT_TEST_EQUALITY_OPS(it1.regularExpression(), re2, true); consistencyCheck(it1); if (QTest::currentTestFailed()) return; @@ -1680,38 +1687,23 @@ void tst_QRegularExpression::serialize() static void verifyEquality(const QRegularExpression &re1, const QRegularExpression &re2) { - QVERIFY(re1 == re2); - QVERIFY(re2 == re1); + QT_TEST_EQUALITY_OPS(re1, re2, true); QCOMPARE(qHash(re1), qHash(re2)); - QVERIFY(!(re1 != re2)); - QVERIFY(!(re2 != re1)); QRegularExpression re3(re1); - QVERIFY(re1 == re3); - QVERIFY(re3 == re1); QCOMPARE(qHash(re1), qHash(re3)); - QVERIFY(!(re1 != re3)); - QVERIFY(!(re3 != re1)); + QT_TEST_EQUALITY_OPS(re1, re3, true); - QVERIFY(re2 == re3); - QVERIFY(re3 == re2); QCOMPARE(qHash(re2), qHash(re3)); - QVERIFY(!(re2 != re3)); - QVERIFY(!(re3 != re2)); + QT_TEST_EQUALITY_OPS(re2, re3, true); re3 = re2; - QVERIFY(re1 == re3); - QVERIFY(re3 == re1); QCOMPARE(qHash(re1), qHash(re3)); - QVERIFY(!(re1 != re3)); - QVERIFY(!(re3 != re1)); + QT_TEST_EQUALITY_OPS(re1, re3, true); - QVERIFY(re2 == re3); - QVERIFY(re3 == re2); QCOMPARE(qHash(re2), qHash(re3)); - QVERIFY(!(re2 != re3)); - QVERIFY(!(re3 != re2)); + QT_TEST_EQUALITY_OPS(re2, re3, true); } void tst_QRegularExpression::operatoreq_data() @@ -1874,12 +1866,14 @@ void tst_QRegularExpression::captureNamesNul() QString captureName("name"); QCOMPARE(m.captured(captureName), "456"); QCOMPARE(m.captured(QStringView(captureName)), "456"); + QCOMPARE(m.captured(QAnyStringView(captureName)), "456"); QCOMPARE(m.captured(qToStringViewIgnoringNull(captureName)), "456"); QCOMPARE(m.captured(u"name"), "456"); captureName = "anotherName"; QCOMPARE(m.captured(captureName), "789"); QCOMPARE(m.captured(QStringView(captureName)), "789"); + QCOMPARE(m.captured(QAnyStringView(captureName)), "789"); QCOMPARE(m.captured(qToStringViewIgnoringNull(captureName)), "789"); QCOMPARE(m.captured(u"anotherName"), "789"); } diff --git a/tests/auto/corelib/text/qstring/tst_qstring.cpp b/tests/auto/corelib/text/qstring/tst_qstring.cpp index 35bddf16a4..92ea5b013d 100644 --- a/tests/auto/corelib/text/qstring/tst_qstring.cpp +++ b/tests/auto/corelib/text/qstring/tst_qstring.cpp @@ -6647,9 +6647,41 @@ void tst_QString::arg() // number overloads QCOMPARE( s4.arg(0), QLatin1String("[0]") ); QCOMPARE( s4.arg(-1), QLatin1String("[-1]") ); + QCOMPARE( s4.arg(0U), QLatin1String("[0]")); + QCOMPARE( s4.arg(qint8(-128)), QLatin1String("[-128]")); // signed char + QCOMPARE( s4.arg(quint8(255)), QLatin1String("[255]")); // unsigned char + QCOMPARE( s4.arg(short(-4200)), QLatin1String("[-4200]")); + QCOMPARE( s4.arg(ushort(42000)), QLatin1String("[42000]")); QCOMPARE( s4.arg(4294967295UL), QLatin1String("[4294967295]") ); // ULONG_MAX 32 QCOMPARE( s4.arg(Q_INT64_C(9223372036854775807)), // LLONG_MAX QLatin1String("[9223372036854775807]") ); + QCOMPARE( s4.arg(Q_UINT64_C(9223372036854775808)), // LLONG_MAX + 1 + QLatin1String("[9223372036854775808]") ); + + // FP overloads + QCOMPARE(s4.arg(2.25), QLatin1String("[2.25]")); + QCOMPARE(s4.arg(3.75f), QLatin1String("[3.75]")); +#if !QFLOAT16_IS_NATIVE // QTBUG-126055 + QCOMPARE(s4.arg(qfloat16{4.125f}), QLatin1String("[4.125]")); +#endif + + // char-ish overloads + QCOMPARE(s4.arg('\xE4'), QStringView(u"[ä]")); + QEXPECT_FAIL("", "QTBUG-125588", Continue); + QCOMPARE(s4.arg(u'ø'), QStringView(u"[ø]")); +#ifdef Q_OS_WIN + QCOMPARE(QLatin1String("[%1]").arg(L'ø'), QStringView(u"[ø]")); +#endif + QEXPECT_FAIL("", "QTBUG-126054", Continue); + QCOMPARE(s4.arg(L'ø'), QStringView(u"[ø]")); +#ifndef __cpp_char8_t +#ifndef QT_NO_CAST_FROM_ASCII + QCOMPARE(QLatin1String("[%1]").arg(u8'a'), QLatin1String("[a]")); +#endif +#else + QEXPECT_FAIL("", "QTBUG-126053", Continue); +#endif + QCOMPARE(s4.arg(u8'a'), QLatin1String("[a]")); QTest::ignoreMessage(QtWarningMsg, "QString::arg: Argument missing: , foo"); QCOMPARE(QString().arg(foo), QString()); @@ -6721,9 +6753,15 @@ void tst_QString::arg() str = str.arg(u"ahoy"_s, u"there"_s); QCOMPARE(str, "one 2 3 4 5 6 7 8 9 foo ahoy there bar"_L1); - QString str2(u"%123 %234 %345 %456 %567 %999 %1000 %1230"_s); - str2 = str2.arg(u"A"_s, u"B"_s, u"C"_s, u"D"_s, u"E"_s, u"F"_s); - QCOMPARE(str2, QLatin1String("A B C D E F %1000 %1230")); + // Make sure the single- and multi-arg expand the same sequences: at most + // two digits. The sequence below has four replacements: %01, %10 (twice), + // %11, and %12. + QString str2 = u"%100 %101 %110 %12 %0100"_s; + QLatin1StringView str2expected = "B0 B1 C0 D A00"_L1; + QCOMPARE(str2.arg(QChar(u'A')).arg(QChar(u'B')).arg(QChar(u'C')).arg(QChar(u'D')), str2expected); + QCOMPARE(str2.arg(QChar(u'A'), QChar(u'B')).arg(QChar(u'C')).arg(QChar(u'D')), str2expected); + QCOMPARE(str2.arg(QChar(u'A'), QChar(u'B'), QChar(u'C')).arg(QChar(u'D')), str2expected); + QCOMPARE(str2.arg(QChar(u'A'), QChar(u'B'), QChar(u'C'), QChar(u'D')), str2expected); QCOMPARE(u"%1"_s.arg(-1, 3, 10, QChar(u'0')), "-01"_L1); QCOMPARE(u"%1"_s.arg(-100, 3, 10, QChar(u'0')), "-100"_L1); diff --git a/tests/auto/corelib/text/qstringapisymmetry/tst_qstringapisymmetry.cpp b/tests/auto/corelib/text/qstringapisymmetry/tst_qstringapisymmetry.cpp index 35a734cf02..06ef1aede0 100644 --- a/tests/auto/corelib/text/qstringapisymmetry/tst_qstringapisymmetry.cpp +++ b/tests/auto/corelib/text/qstringapisymmetry/tst_qstringapisymmetry.cpp @@ -545,6 +545,93 @@ private Q_SLOTS: void endsWith_QLatin1String_QLatin1Char() { endsWith_impl<QLatin1String, QLatin1Char>(); } private: + void arg1_data(bool argHasVariableLength = true) const; + template <typename Format, typename Argument> void arg1_impl() const; + +private Q_SLOTS: + // let Formats = {QString, QStringView, QLatin1String} + // let Arguments = Formats ∪ {QByteArray, const char*, const char8_t*. const char16_t*, std::u16string, char, QChar, QLatin1Char, char16_t} + // test Formats × Arguments: + void arg1_QString_QString_data() { arg1_data(); } + void arg1_QString_QString() { arg1_impl<QString, QString>(); } + void arg1_QString_QStringView_data() { arg1_data(); } + void arg1_QString_QStringView() { arg1_impl<QString, QStringView>(); } + void arg1_QString_QLatin1StringView_data() { arg1_data(); } + void arg1_QString_QLatin1StringView() { arg1_impl<QString, QLatin1StringView>(); } + void arg1_QString_QByteArray_data() { arg1_data(); } + void arg1_QString_QByteArray() { arg1_impl<QString, QByteArray>(); } + void arg1_QString_const_char_star_data() { arg1_data(); } + void arg1_QString_const_char_star() { arg1_impl<QString, const char*>(); } + void arg1_QString_const_char8_t_star_data() { arg1_data(); } + void arg1_QString_const_char8_t_star() { IF_CHAR8T((arg1_impl<QString, const char8_t*>())); } + void arg1_QString_const_char16_t_star_data() { arg1_data(); } + void arg1_QString_const_char16_t_star() { arg1_impl<QString, const char16_t*>(); } + void arg1_QString_stdu16string_data() { arg1_data(); } + void arg1_QString_stdu16string() { arg1_impl<QString, std::u16string>(); } + void arg1_QString_char_data() { arg1_data(false); } + void arg1_QString_char() { arg1_impl<QString, char>(); } + void arg1_QString_QChar_data() { arg1_data(false); } + void arg1_QString_QChar() { arg1_impl<QString, QChar>(); } + void arg1_QString_QLatin1Char_data() { arg1_data(false); } + void arg1_QString_QLatin1Char() { arg1_impl<QString, QLatin1Char>(); } + void arg1_QString_char16_t_data() { arg1_data(false); } + void arg1_QString_char16_t() { + QEXPECT_FAIL("%1/a", "QTBUG-125588", Continue); + QEXPECT_FAIL("%1/ä", "QTBUG-125588", Continue); + arg1_impl<QString, char16_t>(); + } + + void arg1_QStringView_QString_data() { arg1_data(); } + void arg1_QStringView_QString() { arg1_impl<QStringView, QString>(); } + void arg1_QStringView_QStringView_data() { arg1_data(); } + void arg1_QStringView_QStringView() { arg1_impl<QStringView, QStringView>(); } + void arg1_QStringView_QLatin1StringView_data() { arg1_data(); } + void arg1_QStringView_QLatin1StringView() { arg1_impl<QStringView, QLatin1StringView>(); } + void arg1_QStringView_QByteArray_data() { arg1_data(); } + void arg1_QStringView_QByteArray() { arg1_impl<QStringView, QByteArray>(); } + void arg1_QStringView_const_char_star_data() { arg1_data(); } + void arg1_QStringView_const_char_star() { arg1_impl<QStringView, const char*>(); } + void arg1_QStringView_const_char8_t_star_data() { arg1_data(); } + void arg1_QStringView_const_char8_t_star() { IF_CHAR8T((arg1_impl<QStringView, const char8_t*>())); } + void arg1_QStringView_const_char16_t_star_data() { arg1_data(); } + void arg1_QStringView_const_char16_t_star() { arg1_impl<QStringView, const char16_t*>(); } + void arg1_QStringView_stdu16string_data() { arg1_data(); } + void arg1_QStringView_stdu16string() { arg1_impl<QStringView, std::u16string>(); } + void arg1_QStringView_char_data() { arg1_data(false); } + void arg1_QStringView_char() { arg1_impl<QStringView, char>(); } + void arg1_QStringView_QChar_data() { arg1_data(false); } + void arg1_QStringView_QChar() { arg1_impl<QStringView, QChar>(); } + void arg1_QStringView_QLatin1Char_data() { arg1_data(false); } + void arg1_QStringView_QLatin1Char() { arg1_impl<QStringView, QLatin1Char>(); } + void arg1_QStringView_char16_t_data() { arg1_data(false); } + void arg1_QStringView_char16_t() { arg1_impl<QStringView, char16_t>(); } + + void arg1_QLatin1StringView_QString_data() { arg1_data(); } + void arg1_QLatin1StringView_QString() { arg1_impl<QLatin1StringView, QString>(); } + void arg1_QLatin1StringView_QStringView_data() { arg1_data(); } + void arg1_QLatin1StringView_QStringView() { arg1_impl<QLatin1StringView, QStringView>(); } + void arg1_QLatin1StringView_QLatin1StringView_data() { arg1_data(); } + void arg1_QLatin1StringView_QLatin1StringView() { arg1_impl<QLatin1StringView, QLatin1StringView>(); } + void arg1_QLatin1StringView_QByteArray_data() { arg1_data(); } + void arg1_QLatin1StringView_QByteArray() { arg1_impl<QLatin1StringView, QByteArray>(); } + void arg1_QLatin1StringView_const_char_star_data() { arg1_data(); } + void arg1_QLatin1StringView_const_char_star() { arg1_impl<QLatin1StringView, const char*>(); } + void arg1_QLatin1StringView_const_char8_t_star_data() { arg1_data(); } + void arg1_QLatin1StringView_const_char8_t_star() { IF_CHAR8T((arg1_impl<QLatin1StringView, const char8_t*>())); } + void arg1_QLatin1StringView_const_char16_t_star_data() { arg1_data(); } + void arg1_QLatin1StringView_const_char16_t_star() { arg1_impl<QLatin1StringView, const char16_t*>(); } + void arg1_QLatin1StringView_stdu16string_data() { arg1_data(); } + void arg1_QLatin1StringView_stdu16string() { arg1_impl<QLatin1StringView, std::u16string>(); } + void arg1_QLatin1StringView_char_data() { arg1_data(false); } + void arg1_QLatin1StringView_char() { arg1_impl<QLatin1StringView, char>(); } + void arg1_QLatin1StringView_QChar_data() { arg1_data(false); } + void arg1_QLatin1StringView_QChar() { arg1_impl<QLatin1StringView, QChar>(); } + void arg1_QLatin1StringView_QLatin1Char_data() { arg1_data(false); } + void arg1_QLatin1StringView_QLatin1Char() { arg1_impl<QLatin1StringView, QLatin1Char>(); } + void arg1_QLatin1StringView_char16_t_data() { arg1_data(false); } + void arg1_QLatin1StringView_char16_t() { arg1_impl<QLatin1StringView, char16_t>(); } + +private: void split_data(bool rhsHasVariableLength = true); template <typename Haystack, typename Needle> void split_impl() const; @@ -1112,6 +1199,10 @@ auto overload_s_v(QStringView s) { return s; } auto overload_sr_v(QString &&s) { return std::move(s); } auto overload_sr_v(QStringView s) { return s; } +Q_WEAK_OVERLOAD +auto overload_s_bav(const QString &s) { return s; } +auto overload_s_bav(QByteArrayView s) { return s; } + } // unnamed namespace template<typename T> @@ -1174,6 +1265,15 @@ void tst_QStringApiSymmetry::overload() overload_sr_v(CT()); } } + + if constexpr (std::is_convertible_v<T, QString> || std::is_convertible_v<T, QByteArrayView>) { + overload_s_bav(t); + overload_s_bav(ct); + if constexpr (!std::is_array_v<T>) { + overload_s_bav(T()); + overload_s_bav(CT()); + } + } QT_WARNING_POP } @@ -1290,6 +1390,7 @@ template <class Str> Str make(QStringView sf, QLatin1String l1, const QByteArra [[maybe_unused]] const QByteArray &u8) \ /*end*/ MAKE(QChar) { return sv.isEmpty() ? QChar() : sv.at(0); } +MAKE(char) { return sv.isEmpty() ? char() : char(sv.at(0).unicode()); } MAKE(char16_t) { return sv.isEmpty() ? char16_t() : char16_t{sv.at(0).unicode()}; } MAKE(QLatin1Char) { return l1.isEmpty() ? QLatin1Char('\0') : l1.at(0); } MAKE(QString) { return sv.toString(); } @@ -1298,6 +1399,9 @@ MAKE(QLatin1String) { return l1; } MAKE(QByteArray) { return u8; } MAKE(QByteArrayView) { return u8; } MAKE(const char *) { return u8.data(); } +#ifdef __cpp_char8_t +MAKE(const char8_t *) { return q_has_char8_t::QUtf8StringView(u8).data(); } +#endif MAKE(const char16_t *) { return sv.utf16(); } // assumes `sv` doesn't represent a substring MAKE(std::u16string) { return sv.toString().toStdU16String(); } MAKE(QUtf8StringView) { return u8; } @@ -1926,6 +2030,69 @@ void tst_QStringApiSymmetry::endsWith_impl() const QCOMPARE_EQ(haystack.endsWith(needle, Qt::CaseInsensitive), resultCIS); } +void tst_QStringApiSymmetry::arg1_data(bool argHasVariableLength) const +{ + QTest::addColumn<QString>("formatU16"); + QTest::addColumn<QString>("argumentU16"); + QTest::addColumn<QString>("expected"); + + const char *null = nullptr; + const char *empty = ""; + + auto row = [](const char *fmt, const char *arg, const char *res) { + auto protect = [](const char *s) { return s ? *s ? s : "<empty>" : "<null>"; }; + QTest::addRow("%s/%s", protect(fmt), protect(arg)) + << QString::fromUtf8(fmt) << QString::fromUtf8(arg) << QString::fromUtf8(res); + }; + + for (auto fmt : {null, empty}) { + if (argHasVariableLength) { + for (auto arg : {null, empty}) + row(fmt, arg, ""); + } + for (auto arg : {"a", "ä"}) + row(fmt, arg, ""); + if (argHasVariableLength) { + for (auto arg : {"äá", "Øåß"}) + row(fmt, arg, ""); + } + } + + for (auto fmt : {"%1"}) { + if (argHasVariableLength) { + for (auto arg : {null, empty}) + row(fmt, arg, arg); + } + for (auto arg : {"a", "ä"}) + row(fmt, arg, arg); + if (argHasVariableLength) { + for (auto arg : {"äá", "Øåß"}) + row(fmt, arg, arg); + } + } +} + +template <typename Format, typename Argument> +void tst_QStringApiSymmetry::arg1_impl() const +{ + QFETCH(const QString, formatU16); + QFETCH(const QString, argumentU16); + QFETCH(const QString, expected); + + const auto formatL1Pinned = formatU16.toLatin1(); + const auto formatL1 = QLatin1StringView{formatL1Pinned}; + const auto formatU8 = formatU16.toUtf8(); + + const auto argumentL1Pinned = argumentU16.toLatin1(); + const auto argumentL1= QLatin1StringView{argumentL1Pinned}; + const auto argumentU8 = argumentU16.toUtf8(); + + const auto format = make<Format>(formatU16, formatL1, formatU8); + const auto argument = make<Argument>(argumentU16, argumentL1, argumentU8); + + QCOMPARE(format.arg(argument), expected); +} + void tst_QStringApiSymmetry::split_data(bool rhsHasVariableLength) { QTest::addColumn<QStringView>("haystackU16"); diff --git a/tests/auto/corelib/text/qstringbuilder/qstringbuilder1/stringbuilder.cpp b/tests/auto/corelib/text/qstringbuilder/qstringbuilder1/stringbuilder.cpp index 59362d010a..7931363b4b 100644 --- a/tests/auto/corelib/text/qstringbuilder/qstringbuilder1/stringbuilder.cpp +++ b/tests/auto/corelib/text/qstringbuilder/qstringbuilder1/stringbuilder.cpp @@ -377,6 +377,8 @@ void runScenario() char chararray[3] = { 'H', 'i', '\0' }; const char constchararray[3] = { 'H', 'i', '\0' }; char achar = 'a'; + char embedded_NULs[16] = { 'H', 'i' }; + const char const_embedded_NULs[16] = { 'H', 'i' }; CHECK(P, bytearray, bytearray); CHECK(P, QByteArray(bytearray), bytearray); @@ -400,6 +402,33 @@ void runScenario() CHECK(P, bytearray, achar); CHECK(Q, bytearray, constchararray); CHECK(Q, bytearray, achar); + CHECK(Q, bytearray, embedded_NULs); + CHECK(Q, bytearray, const_embedded_NULs); + + CHECK(Q, baview, bytearray); + CHECK(Q, baview, charstar); + CHECK(Q, baview, chararray); + CHECK(Q, baview, constchararray); + CHECK(Q, baview, achar); + CHECK(Q, baview, embedded_NULs); + CHECK(Q, baview, const_embedded_NULs); + + // Check QString/QByteArray consistency when appending const char[] with embedded NULs: + { + const QByteArray ba = baview Q embedded_NULs; + QEXPECT_FAIL("", "QTBUG-117321", Continue); + QCOMPARE(ba.size(), baview.size() + q20::ssize(embedded_NULs) - 1); + +#ifndef QT_NO_CAST_FROM_ASCII + const auto l1s = QLatin1StringView{baview}; // l1string != baview + + const QString s = l1s Q embedded_NULs; + QCOMPARE(s.size(), l1s.size() + q20::ssize(embedded_NULs) - 1); + + QEXPECT_FAIL("", "QTBUG-117321", Continue); + QCOMPARE(s, ba); +#endif + } //CHECK(Q, charstar, charstar); // BUILTIN <-> BUILTIN cat't be overloaded //CHECK(Q, charstar, chararray); diff --git a/tests/auto/corelib/text/qstringbuilder/qstringbuilder1/tst_qstringbuilder1.cpp b/tests/auto/corelib/text/qstringbuilder/qstringbuilder1/tst_qstringbuilder1.cpp index 394372c398..e8365f500b 100644 --- a/tests/auto/corelib/text/qstringbuilder/qstringbuilder1/tst_qstringbuilder1.cpp +++ b/tests/auto/corelib/text/qstringbuilder/qstringbuilder1/tst_qstringbuilder1.cpp @@ -15,6 +15,8 @@ #include <QtCore/QStringBuilder> #include <QtTest/QTest> +#include <QtCore/q20iterator.h> + #define LITERAL "some literal" namespace { diff --git a/tests/auto/corelib/text/qstringbuilder/qstringbuilder2/tst_qstringbuilder2.cpp b/tests/auto/corelib/text/qstringbuilder/qstringbuilder2/tst_qstringbuilder2.cpp index dc590304f5..1aaee114a3 100644 --- a/tests/auto/corelib/text/qstringbuilder/qstringbuilder2/tst_qstringbuilder2.cpp +++ b/tests/auto/corelib/text/qstringbuilder/qstringbuilder2/tst_qstringbuilder2.cpp @@ -16,6 +16,8 @@ #include <QtCore/QStringBuilder> #include <QtTest/QTest> +#include <QtCore/q20iterator.h> + #define LITERAL "some literal" namespace { diff --git a/tests/auto/corelib/text/qstringbuilder/qstringbuilder3/tst_qstringbuilder3.cpp b/tests/auto/corelib/text/qstringbuilder/qstringbuilder3/tst_qstringbuilder3.cpp index 3222b52713..aaa14a5d1a 100644 --- a/tests/auto/corelib/text/qstringbuilder/qstringbuilder3/tst_qstringbuilder3.cpp +++ b/tests/auto/corelib/text/qstringbuilder/qstringbuilder3/tst_qstringbuilder3.cpp @@ -15,6 +15,8 @@ #include <QtCore/QStringBuilder> #include <QtTest/QTest> +#include <QtCore/q20iterator.h> + #define LITERAL "some literal" namespace { diff --git a/tests/auto/corelib/text/qstringbuilder/qstringbuilder4/tst_qstringbuilder4.cpp b/tests/auto/corelib/text/qstringbuilder/qstringbuilder4/tst_qstringbuilder4.cpp index 442c5275d2..319708fd4b 100644 --- a/tests/auto/corelib/text/qstringbuilder/qstringbuilder4/tst_qstringbuilder4.cpp +++ b/tests/auto/corelib/text/qstringbuilder/qstringbuilder4/tst_qstringbuilder4.cpp @@ -16,6 +16,8 @@ #include <QtCore/QStringBuilder> #include <QtTest/QTest> +#include <QtCore/q20iterator.h> + #define LITERAL "some literal" namespace { diff --git a/tests/auto/corelib/text/qstringconverter/tst_qstringconverter.cpp b/tests/auto/corelib/text/qstringconverter/tst_qstringconverter.cpp index 7c0235998f..342c343a42 100644 --- a/tests/auto/corelib/text/qstringconverter/tst_qstringconverter.cpp +++ b/tests/auto/corelib/text/qstringconverter/tst_qstringconverter.cpp @@ -257,7 +257,7 @@ void tst_QStringConverter::invalidConverter() QVERIFY(!encoder.hasError()); char buffer[100]; char *position = encoder.appendToBuffer(buffer, u"Even more"); - QCOMPARE(position, buffer); + QCOMPARE(position - buffer, 0); QVERIFY(encoder.hasError()); } @@ -283,7 +283,7 @@ void tst_QStringConverter::invalidConverter() QVERIFY(!decoder.hasError()); char16_t buffer[100]; char16_t *position = decoder.appendToBuffer(buffer, "Even more"); - QCOMPARE(position, buffer); + QCOMPARE(position - buffer, 0); QVERIFY(decoder.hasError()); } } @@ -571,11 +571,10 @@ void tst_QStringConverter::charByCharConsistency_data() void tst_QStringConverter::charByCharConsistency() { - QFETCH(QStringView, source); - QFETCH(QByteArray, codec); + QFETCH(const QStringView, source); + QFETCH(const QByteArray, codec); - { - QStringEncoder encoder(codec); + const auto check = [&](QStringEncoder encoder){ if (!encoder.isValid()) QSKIP("Unsupported codec"); @@ -586,19 +585,28 @@ void tst_QStringConverter::charByCharConsistency() stepByStepConverted += encoder.encode(codeUnit); } QCOMPARE(stepByStepConverted, fullyConverted); - } + }; + + check(QStringEncoder(codec)); + if (QTest::currentTestResolved()) return; + + check(QStringEncoder(codec, QStringConverter::Flag::ConvertInvalidToNull)); + if (QTest::currentTestResolved()) return; + + // moved codecs also work: { - QStringEncoder encoder(codec, QStringConverter::Flag::ConvertInvalidToNull); + QStringEncoder dec(codec); + check(std::move(dec)); + } + if (QTest::currentTestResolved()) return; - QByteArray fullyConverted = encoder.encode(source); - encoder.resetState(); - QByteArray stepByStepConverted; - for (const auto& codeUnit: source) { - stepByStepConverted += encoder.encode(codeUnit); - } - QCOMPARE(stepByStepConverted, fullyConverted); + { + QStringEncoder dec(codec, QStringConverter::Flag::ConvertInvalidToNull); + check(std::move(dec)); } + if (QTest::currentTestResolved()) return; + } void tst_QStringConverter::byteByByteConsistency_data() @@ -615,11 +623,10 @@ void tst_QStringConverter::byteByByteConsistency_data() void tst_QStringConverter::byteByByteConsistency() { - QFETCH(QByteArray, source); - QFETCH(QByteArray, codec); + QFETCH(const QByteArray, source); + QFETCH(const QByteArray, codec); - { - QStringDecoder decoder(codec); + const auto check = [&](QStringDecoder decoder) { if (!decoder.isValid()) QSKIP("Unsupported codec"); @@ -632,23 +639,28 @@ void tst_QStringConverter::byteByByteConsistency() stepByStepConverted += decoder.decode(singleChar); } QCOMPARE(stepByStepConverted, fullyConverted); - } + }; + + check(QStringDecoder(codec)); + if (QTest::currentTestResolved()) return; + + check(QStringDecoder(codec, QStringConverter::Flag::ConvertInvalidToNull)); + if (QTest::currentTestResolved()) return; + + // moved codecs also work: { - QStringDecoder decoder(codec, QStringConverter::Flag::ConvertInvalidToNull); - if (!decoder.isValid()) - QSKIP("Unsupported codec"); + QStringDecoder dec(codec); + check(std::move(dec)); + } + if (QTest::currentTestResolved()) return; - QString fullyConverted = decoder.decode(source); - decoder.resetState(); - QString stepByStepConverted; - for (const auto& byte: source) { - QByteArray singleChar; - singleChar.append(byte); - stepByStepConverted += decoder.decode(singleChar); - } - QCOMPARE(stepByStepConverted, fullyConverted); + { + QStringDecoder dec(codec, QStringConverter::Flag::ConvertInvalidToNull); + check(std::move(dec)); } + if (QTest::currentTestResolved()) return; + } void tst_QStringConverter::statefulPieceWise() diff --git a/tests/auto/corelib/text/qstringview/CMakeLists.txt b/tests/auto/corelib/text/qstringview/CMakeLists.txt index ba5f540838..b541cdd0ed 100644 --- a/tests/auto/corelib/text/qstringview/CMakeLists.txt +++ b/tests/auto/corelib/text/qstringview/CMakeLists.txt @@ -18,5 +18,12 @@ qt_internal_add_test(tst_qstringview Qt::CorePrivate ) +if(QT_FEATURE_sanitize_undefined) + qt_internal_extend_target(tst_qstringview + DEFINES + QT_SANITIZE_UNDEFINED # GCC (in)famously doesn't provide a predefined macro for this + ) +endif() + ## Scopes: ##################################################################### diff --git a/tests/auto/corelib/text/qstringview/tst_qstringview.cpp b/tests/auto/corelib/text/qstringview/tst_qstringview.cpp index df3ef94371..3f87ffc9fc 100644 --- a/tests/auto/corelib/text/qstringview/tst_qstringview.cpp +++ b/tests/auto/corelib/text/qstringview/tst_qstringview.cpp @@ -359,6 +359,30 @@ void tst_QStringView::constExpr() const static_assert(sv3.isEmpty()); static_assert(sv3.size() == 0); } +#if !defined(Q_CC_GNU_ONLY) || !defined(QT_SANITIZE_UNDEFINED) + // Below checks are disabled because of a compilation issue with GCC and + // -fsanitize=undefined. See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71962. + { + static constexpr char16_t hello[] = u"Hello"; + constexpr QStringView sv(hello); + static_assert(sv.size() == 5); + static_assert(!sv.empty()); + static_assert(!sv.isEmpty()); + static_assert(!sv.isNull()); + static_assert(*sv.utf16() == 'H'); + static_assert(sv[0] == QLatin1Char('H')); + static_assert(sv.at(0) == QLatin1Char('H')); + static_assert(sv.front() == QLatin1Char('H')); + static_assert(sv.first() == QLatin1Char('H')); + static_assert(sv[4] == QLatin1Char('o')); + static_assert(sv.at(4) == QLatin1Char('o')); + static_assert(sv.back() == QLatin1Char('o')); + static_assert(sv.last() == QLatin1Char('o')); + + constexpr auto sv2 = QStringView::fromArray(hello); + QCOMPARE_EQ(sv, sv2.chopped(1)); + } +#endif // -fsanitize=undefined } void tst_QStringView::basics() const @@ -430,7 +454,7 @@ void tst_QStringView::fromArray() const { static constexpr char16_t hello[] = u"Hello\0abc\0\0."; - constexpr QStringView sv = QStringView::fromArray(hello); + const QStringView sv = QStringView::fromArray(hello); QCOMPARE(sv.size(), 13); QVERIFY(!sv.empty()); QVERIFY(!sv.isEmpty()); diff --git a/tests/auto/corelib/thread/CMakeLists.txt b/tests/auto/corelib/thread/CMakeLists.txt index 5889f4249f..d25d0205f5 100644 --- a/tests/auto/corelib/thread/CMakeLists.txt +++ b/tests/auto/corelib/thread/CMakeLists.txt @@ -1,7 +1,7 @@ # Copyright (C) 2022 The Qt Company Ltd. # SPDX-License-Identifier: BSD-3-Clause -if(WASM) # not all tests currently work in WebAssembly +if(QT_BUILD_WASM_BATCHED_TESTS) # not all tests currently work in WebAssembly add_subdirectory(qatomicint) add_subdirectory(qatomicinteger) add_subdirectory(qatomicpointer) @@ -17,11 +17,20 @@ if(QT_FEATURE_thread) add_subdirectory(qatomicint) add_subdirectory(qatomicinteger) add_subdirectory(qatomicpointer) - add_subdirectory(qresultstore) - if(QT_FEATURE_concurrent AND NOT INTEGRITY) - add_subdirectory(qfuture) + if(QT_FEATURE_future) + if(QT_FEATURE_concurrent AND NOT INTEGRITY) + add_subdirectory(qfuture) + endif() + add_subdirectory(qresultstore) + add_subdirectory(qfuturesynchronizer) + if(NOT INTEGRITY) + add_subdirectory(qpromise) + endif() + # QTBUG-87431 + if(TARGET Qt::Concurrent AND NOT INTEGRITY) + add_subdirectory(qfuturewatcher) + endif() endif() - add_subdirectory(qfuturesynchronizer) add_subdirectory(qmutex) add_subdirectory(qmutexlocker) add_subdirectory(qreadlocker) @@ -36,12 +45,5 @@ if(QT_FEATURE_thread) add_subdirectory(qthreadstorage) add_subdirectory(qwaitcondition) add_subdirectory(qwritelocker) - if(NOT INTEGRITY) - add_subdirectory(qpromise) - endif() endif() -# QTBUG-87431 -if(TARGET Qt::Concurrent AND NOT INTEGRITY) - add_subdirectory(qfuturewatcher) -endif() diff --git a/tests/auto/corelib/thread/qfuture/CMakeLists.txt b/tests/auto/corelib/thread/qfuture/CMakeLists.txt index aa989f3df1..ba5730d5cf 100644 --- a/tests/auto/corelib/thread/qfuture/CMakeLists.txt +++ b/tests/auto/corelib/thread/qfuture/CMakeLists.txt @@ -16,6 +16,7 @@ qt_internal_add_test(tst_qfuture tst_qfuture.cpp LIBRARIES Qt::CorePrivate + Qt::TestPrivate ) qt_internal_extend_target(tst_qfuture CONDITION MSVC diff --git a/tests/auto/corelib/thread/qfuture/tst_qfuture.cpp b/tests/auto/corelib/thread/qfuture/tst_qfuture.cpp index 3fc796514d..4cb29c514a 100644 --- a/tests/auto/corelib/thread/qfuture/tst_qfuture.cpp +++ b/tests/auto/corelib/thread/qfuture/tst_qfuture.cpp @@ -17,6 +17,7 @@ #include <private/qobject_p.h> #include <QTest> +#include <QtTest/private/qcomparisontesthelper_p.h> #include <qfuture.h> #include <qfuturewatcher.h> #include <qresultstore.h> @@ -161,6 +162,7 @@ class tst_QFuture: public QObject { Q_OBJECT private slots: + void compareCompiles(); void resultStore(); void future(); void futureToVoid(); @@ -273,6 +275,12 @@ private: QtPrivate::ResultStoreBase &store; }; +void tst_QFuture::compareCompiles() +{ + QTestPrivate::testEqualityOperatorsCompile<QFuture<int>::const_iterator>(); + QTestPrivate::testEqualityOperatorsCompile<QFuture<QString>::const_iterator>(); +} + void tst_QFuture::resultStore() { int int0 = 0; @@ -1359,16 +1367,16 @@ void tst_QFuture::iterators() QFuture<int>::const_iterator i1 = f.begin(), i2 = i1 + 1; QFuture<int>::const_iterator c1 = i1, c2 = c1 + 1; - QCOMPARE(i1, i1); - QCOMPARE(i1, c1); - QCOMPARE(c1, i1); - QCOMPARE(c1, c1); - QCOMPARE(i2, i2); - QCOMPARE(i2, c2); - QCOMPARE(c2, i2); - QCOMPARE(c2, c2); - QCOMPARE(1 + i1, i1 + 1); - QCOMPARE(1 + c1, c1 + 1); + QT_TEST_EQUALITY_OPS(i1, i1, true); + QT_TEST_EQUALITY_OPS(i1, c1, true); + QT_TEST_EQUALITY_OPS(c1, i1, true); + QT_TEST_EQUALITY_OPS(c1, c1, true); + QT_TEST_EQUALITY_OPS(i2, i2, true); + QT_TEST_EQUALITY_OPS(i2, c2, true); + QT_TEST_EQUALITY_OPS(c2, i2, true); + QT_TEST_EQUALITY_OPS(c2, c2, true); + QT_TEST_EQUALITY_OPS(1 + i1, i1 + 1, true); + QT_TEST_EQUALITY_OPS(1 + c1, c1 + 1, true); QVERIFY(i1 != i2); QVERIFY(i1 != c2); diff --git a/tests/auto/corelib/thread/qresultstore/CMakeLists.txt b/tests/auto/corelib/thread/qresultstore/CMakeLists.txt index 0f9d8d9e52..5abfc14ac6 100644 --- a/tests/auto/corelib/thread/qresultstore/CMakeLists.txt +++ b/tests/auto/corelib/thread/qresultstore/CMakeLists.txt @@ -16,4 +16,5 @@ qt_internal_add_test(tst_qresultstore tst_qresultstore.cpp LIBRARIES Qt::CorePrivate + Qt::TestPrivate ) diff --git a/tests/auto/corelib/thread/qresultstore/tst_qresultstore.cpp b/tests/auto/corelib/thread/qresultstore/tst_qresultstore.cpp index 265b2cd1f6..722184a72a 100644 --- a/tests/auto/corelib/thread/qresultstore/tst_qresultstore.cpp +++ b/tests/auto/corelib/thread/qresultstore/tst_qresultstore.cpp @@ -2,7 +2,7 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QTest> - +#include <QtTest/private/qcomparisontesthelper_p.h> #include <qresultstore.h> using namespace QtPrivate; @@ -23,6 +23,7 @@ class tst_QtConcurrentResultStore : public QObject public slots: void init(); private slots: + void compareCompiles(); void construction(); void iterators(); void addResult(); @@ -52,6 +53,11 @@ void tst_QtConcurrentResultStore::init() vec1 = QList<int> { 4, 5 }; } +void tst_QtConcurrentResultStore::compareCompiles() +{ + QTestPrivate::testEqualityOperatorsCompile<ResultIteratorBase>(); +} + void tst_QtConcurrentResultStore::construction() { ResultStoreBase store; @@ -74,17 +80,20 @@ void tst_QtConcurrentResultStore::iterators() storebase.addResult(1, &int1); // ResultStoreBase does not take ownership, only ResultStore<> does. ResultIteratorBase it = storebase.begin(); QCOMPARE(it.resultIndex(), 0); - QCOMPARE(it, storebase.begin()); + QT_TEST_EQUALITY_OPS(it, storebase.begin(), true); QVERIFY(it != storebase.end()); ++it; QCOMPARE(it.resultIndex(), 1); QVERIFY(it != storebase.begin()); QVERIFY(it != storebase.end()); + QT_TEST_EQUALITY_OPS(it, storebase.begin(), false); + QT_TEST_EQUALITY_OPS(it, storebase.end(), false); ++it; QVERIFY(it != storebase.begin()); QCOMPARE(it, storebase.end()); + QT_TEST_EQUALITY_OPS(it, storebase.end(), true); } } @@ -147,8 +156,8 @@ void tst_QtConcurrentResultStore::addResults() store.addResults(-1, &vec1); ResultIteratorBase it = store.begin(); QCOMPARE(it.resultIndex(), 0); - QCOMPARE(it, store.begin()); - QVERIFY(it != store.end()); + QT_TEST_EQUALITY_OPS(it, store.begin(), true); + QT_TEST_EQUALITY_OPS(it, store.end(), false); ++it; QCOMPARE(it.resultIndex(), 1); @@ -162,7 +171,7 @@ void tst_QtConcurrentResultStore::addResults() QCOMPARE(it.resultIndex(), 3); ++it; - QCOMPARE(it, store.end()); + QT_TEST_EQUALITY_OPS(it, store.end(), true); QList<int> empty; const auto countBefore = store.count(); @@ -184,22 +193,22 @@ void tst_QtConcurrentResultStore::resultIndex() ResultIteratorBase it = store.begin(); QCOMPARE(it.resultIndex(), 0); - QVERIFY(it == store.begin()); - QVERIFY(it != store.end()); + QT_TEST_EQUALITY_OPS(it, store.begin(), true); + QT_TEST_EQUALITY_OPS(it, store.end(), false); ++it; QCOMPARE(it.resultIndex(), 1); - QVERIFY(it != store.begin()); - QVERIFY(it != store.end()); + QT_TEST_EQUALITY_OPS(it, store.begin(), false); + QT_TEST_EQUALITY_OPS(it, store.end(), false); ++it; QCOMPARE(it.resultIndex(), 2); - QVERIFY(it != store.end()); + QT_TEST_EQUALITY_OPS(it, store.end(), false); ++it; QCOMPARE(it.resultIndex(), 3); - QVERIFY(it != store.end()); + QT_TEST_EQUALITY_OPS(it, store.end(), false); ++it; - QVERIFY(it == store.end()); + QT_TEST_EQUALITY_OPS(it, store.end(), true); QCOMPARE(store.resultAt(0).value<int>(), int0); QCOMPARE(store.resultAt(1).value<int>(), vec0[0]); diff --git a/tests/auto/corelib/thread/qthread/tst_qthread.cpp b/tests/auto/corelib/thread/qthread/tst_qthread.cpp index a7194d4442..18c8d5fbd5 100644 --- a/tests/auto/corelib/thread/qthread/tst_qthread.cpp +++ b/tests/auto/corelib/thread/qthread/tst_qthread.cpp @@ -53,6 +53,7 @@ private slots: void setStackSize(); void exit(); void start(); + void startSlotUsedInStringBasedLookups(); void terminate(); void quit(); void started(); @@ -136,11 +137,13 @@ class Current_Thread : public QThread public: Qt::HANDLE id; QThread *thread; + bool runCalledInCurrentThread = false; void run() override { id = QThread::currentThreadId(); thread = QThread::currentThread(); + runCalledInCurrentThread = thread->isCurrentThread(); } }; @@ -275,6 +278,11 @@ void tst_QThread::currentThreadId() QVERIFY(thread.wait(five_minutes)); QVERIFY(thread.id != nullptr); QVERIFY(thread.id != QThread::currentThreadId()); + QVERIFY(!thread.isCurrentThread()); + QVERIFY(!thread.thread->isCurrentThread()); + QVERIFY(thread.QThread::thread()->isCurrentThread()); + QVERIFY(thread.runCalledInCurrentThread); + QVERIFY(qApp->thread()->isCurrentThread()); } void tst_QThread::currentThread() @@ -466,6 +474,56 @@ void tst_QThread::start() } } +class QThreadStarter : public QObject +{ + Q_OBJECT +public: + using QObject::QObject; +Q_SIGNALS: + void start(QThread::Priority); +}; + +class QThreadSelfStarter : public QThread +{ + Q_OBJECT +public: + using QThread::QThread; + + void check() + { + QVERIFY(connect(this, SIGNAL(starting(Priority)), + this, SLOT(start(Priority)))); + QVERIFY(QMetaObject::invokeMethod(this, "start", Q_ARG(Priority, IdlePriority))); + } + +Q_SIGNALS: + void starting(Priority); +}; + +void tst_QThread::startSlotUsedInStringBasedLookups() +{ + // QTBUG-124723 + + QThread thread; + { + QThreadStarter starter; + QVERIFY(QObject::connect(&starter, SIGNAL(start(QThread::Priority)), + &thread, SLOT(start(QThread::Priority)))); + } + { + QThreadSelfStarter selfStarter; + selfStarter.check(); + if (QTest::currentTestFailed()) + return; + selfStarter.exit(); + selfStarter.wait(30s); + } + QVERIFY(QMetaObject::invokeMethod(&thread, "start", + Q_ARG(QThread::Priority, QThread::IdlePriority))); + thread.exit(); + thread.wait(30s); +} + void tst_QThread::terminate() { #if defined(Q_OS_ANDROID) @@ -1241,8 +1299,16 @@ public: } void registerSocketNotifier(QSocketNotifier *) override {} void unregisterSocketNotifier(QSocketNotifier *) override {} - void registerTimer(Qt::TimerId, Duration, Qt::TimerType, QObject *) override {} - bool unregisterTimer(Qt::TimerId) override { return false; } + void registerTimer(Qt::TimerId id, Duration, Qt::TimerType, QObject *) override + { + if (registeredTimerId <= Qt::TimerId::Invalid) + registeredTimerId = id; + } + bool unregisterTimer(Qt::TimerId id) override + { + Qt::TimerId oldId = std::exchange(registeredTimerId, Qt::TimerId::Invalid); + return id == oldId; + } bool unregisterTimers(QObject *) override { return false; } QList<TimerInfoV2> timersForObject(QObject *) const override { return {}; } Duration remainingTime(Qt::TimerId) const override { return 0s; } @@ -1255,25 +1321,47 @@ public: #endif QBasicAtomicInt visited; // bool + Qt::TimerId registeredTimerId = Qt::TimerId::Invalid; }; -class ThreadObj : public QObject +struct ThreadLocalContent { - Q_OBJECT -public slots: - void visit() { - emit visited(); + static inline const QMetaObject *atStart; + static inline const QMetaObject *atEnd; + QSemaphore *sem; + QBasicTimer timer; + + ThreadLocalContent(QObject *obj, QSemaphore *sem) + : sem(sem) + { + ensureEventDispatcher(); + atStart = QAbstractEventDispatcher::instance()->metaObject(); + timer.start(10s, obj); + } + ~ThreadLocalContent() + { + ensureEventDispatcher(); + atEnd = QAbstractEventDispatcher::instance()->metaObject(); + timer.stop(); + sem->release(); + } + + void ensureEventDispatcher() + { + // QEventLoop's constructor has a call to QThreadData::ensureEventDispatcher() + QEventLoop dummy; } -signals: - void visited(); }; void tst_QThread::customEventDispatcher() { + ThreadLocalContent::atStart = ThreadLocalContent::atEnd = nullptr; + QThread thr; // there should be no ED yet QVERIFY(!thr.eventDispatcher()); DummyEventDispatcher *ed = new DummyEventDispatcher; + QPointer<DummyEventDispatcher> weak_ed(ed); thr.setEventDispatcher(ed); // the new ED should be set QCOMPARE(thr.eventDispatcher(), ed); @@ -1282,25 +1370,39 @@ void tst_QThread::customEventDispatcher() thr.start(); // start() should not overwrite the ED QCOMPARE(thr.eventDispatcher(), ed); + QVERIFY(!weak_ed.isNull()); - ThreadObj obj; + QObject obj; obj.moveToThread(&thr); // move was successful? QCOMPARE(obj.thread(), &thr); - QEventLoop loop; - connect(&obj, SIGNAL(visited()), &loop, SLOT(quit()), Qt::QueuedConnection); - QMetaObject::invokeMethod(&obj, "visit", Qt::QueuedConnection); - loop.exec(); + + QSemaphore threadLocalSemaphore; + QMetaObject::invokeMethod(&obj, [&]() { +#ifndef Q_OS_WIN + // On Windows, the thread_locals are unsequenced between DLLs, so this + // could run after QThreadPrivate::finish() + static thread_local +#endif + ThreadLocalContent d(&obj, &threadLocalSemaphore); + }, Qt::BlockingQueuedConnection); + // test that the ED has really been used QVERIFY(ed->visited.loadRelaxed()); + // and it's ours + QCOMPARE(ThreadLocalContent::atStart->className(), "DummyEventDispatcher"); - QPointer<DummyEventDispatcher> weak_ed(ed); QVERIFY(!weak_ed.isNull()); thr.quit(); + // wait for thread to be stopped QVERIFY(thr.wait(30000)); + QVERIFY(threadLocalSemaphore.tryAcquire(1, 30s)); + // test that ED has been deleted QVERIFY(weak_ed.isNull()); + // test that ED was ours + QCOMPARE(ThreadLocalContent::atEnd->className(), "DummyEventDispatcher"); } class Job : public QObject diff --git a/tests/auto/corelib/time/CMakeLists.txt b/tests/auto/corelib/time/CMakeLists.txt index b593cc54d6..1fb95e9245 100644 --- a/tests/auto/corelib/time/CMakeLists.txt +++ b/tests/auto/corelib/time/CMakeLists.txt @@ -4,7 +4,9 @@ add_subdirectory(qcalendar) add_subdirectory(qdate) add_subdirectory(qdatetime) -add_subdirectory(qdatetimeparser) +if(QT_FEATURE_datetimeparser) + add_subdirectory(qdatetimeparser) +endif() add_subdirectory(qtime) if(QT_FEATURE_timezone) add_subdirectory(qtimezone) diff --git a/tests/auto/corelib/time/qdate/tst_qdate.cpp b/tests/auto/corelib/time/qdate/tst_qdate.cpp index 66d7571550..5b715e8c55 100644 --- a/tests/auto/corelib/time/qdate/tst_qdate.cpp +++ b/tests/auto/corelib/time/qdate/tst_qdate.cpp @@ -1179,7 +1179,7 @@ void tst_QDate::operator_insert_extract() QCOMPARE(deserialised, date); } -#if QT_CONFIG(datetimeparser) +#if QT_CONFIG(datestring) void tst_QDate::fromStringDateFormat_data() { QTest::addColumn<QString>("dateStr"); @@ -1303,6 +1303,7 @@ void tst_QDate::fromStringDateFormat() QCOMPARE(QDate::fromString(dateStr, dateFormat), expectedDate); } +# if QT_CONFIG(datetimeparser) void tst_QDate::fromStringFormat_data() { QTest::addColumn<QString>("string"); @@ -1334,7 +1335,7 @@ void tst_QDate::fromStringFormat_data() QTest::newRow("year-match-1999") << u"1999:99"_s << u"yyyy:yy"_s << 1900 << QDate(1999, 1, 1); QTest::newRow("year-match-2099") << u"2099:99"_s << u"yyyy:yy"_s << 1900 << QDate(2099, 1, 1); QTest::newRow("year-match-2001") << u"2001:01"_s << u"yyyy:yy"_s << 1900 << QDate(2001, 1, 1); - QTest::newRow("year-match-1999") << u"99"_s << u"yy"_s << 1900 << QDate(1999, 1, 1); + QTest::newRow("just-yy-1999") << u"99"_s << u"yy"_s << 1900 << QDate(1999, 1, 1); QTest::newRow("just-yy-1901") << u"01"_s << u"yy"_s << 1900 << QDate(1901, 1, 1); QTest::newRow("just-yy-2001") << u"01"_s << u"yy"_s << 1970 << QDate(2001, 1, 1); @@ -1490,7 +1491,6 @@ void tst_QDate::fromStringFormat() } #endif // datetimeparser -#if QT_CONFIG(datestring) void tst_QDate::toStringFormat_data() { QTest::addColumn<QDate>("t"); diff --git a/tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp b/tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp index 6c0733686d..f9c6afc795 100644 --- a/tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp +++ b/tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp @@ -3117,6 +3117,9 @@ void tst_QDateTime::fromStringStringFormat_data() << u"Thu January 2004"_s << u"ddd MMMM yyyy"_s << 1900 << QDate(2004, 1, 1).startOfDay(); } + QTest::newRow("yy=24/Mar/20") // QTBUG-123579 + << u"Wed, 20 Mar 24 16:17:00"_s << u"ddd, dd MMM yy HH:mm:ss"_s << 1900 + << QDateTime(QDate(2024, 3, 20), QTime(16, 17)); QTest::newRow("secs-conflict") << u"1020"_s << u"sss"_s << 1900 << QDateTime(); QTest::newRow("secs-split-conflict") << u"10hello20"_s << u"ss'hello'ss"_s << 1900 << QDateTime(); diff --git a/tests/auto/corelib/time/qtimezone/tst_qtimezone.cpp b/tests/auto/corelib/time/qtimezone/tst_qtimezone.cpp index a350ffeb04..e71f32a3ca 100644 --- a/tests/auto/corelib/time/qtimezone/tst_qtimezone.cpp +++ b/tests/auto/corelib/time/qtimezone/tst_qtimezone.cpp @@ -7,6 +7,7 @@ #include <private/qcomparisontesthelper_p.h> #include <qlocale.h> +#include <qscopeguard.h> #if defined(Q_OS_WIN) #include <QOperatingSystemVersion> @@ -16,6 +17,8 @@ # define USING_WIN_TZ #endif +using namespace Qt::StringLiterals; + class tst_QTimeZone : public QObject { Q_OBJECT @@ -38,6 +41,8 @@ private Q_SLOTS: void availableTimeZoneIds(); void utcOffsetId_data(); void utcOffsetId(); + void aliasMatches_data(); + void aliasMatches(); void specificTransition_data(); void specificTransition(); void transitionEachZone_data(); @@ -558,9 +563,12 @@ void tst_QTimeZone::isTimeZoneIdAvailable() const QList<QByteArray> available = QTimeZone::availableTimeZoneIds(); for (const QByteArray &id : available) { QVERIFY2(QTimeZone::isTimeZoneIdAvailable(id), id); - QVERIFY2(QTimeZone(id).isValid(), id); - QCOMPARE(QTimeZone(id).id(), id); + const QTimeZone zone(id); + QVERIFY2(zone.isValid(), id); + QVERIFY2(zone.aliasMatches(id), zone.id() + " != " + id); } + // availableTimeZoneIds() doesn't list all possible offset IDs, but + // isTimeZoneIdAvailable() should accept them. for (qint32 offset = QTimeZone::MinUtcOffsetSecs; offset <= QTimeZone::MinUtcOffsetSecs; ++offset) { const QByteArray id = QTimeZone(offset).id(); @@ -584,7 +592,7 @@ void tst_QTimeZone::utcOffsetId_data() #define ROW(name, valid, offset) \ QTest::newRow(name) << QByteArray(name) << valid << offset - // See qtbase/util/locale_database/cldr2qtimezone.py for source + // See qtbase/util/locale_database/zonedata.py for source // CLDR v35.1 IDs: ROW("UTC", true, 0); ROW("UTC-14:00", true, -50400); @@ -700,6 +708,58 @@ void tst_QTimeZone::utcOffsetId() } } +void tst_QTimeZone::aliasMatches_data() +{ + QTest::addColumn<QByteArray>("iana"); + QTest::addColumn<QByteArray>("alias"); + + QTest::newRow("Montreal=Toronto") << "America/Toronto"_ba << "America/Montreal"_ba; + QTest::newRow("Asmera=Asmara") << "Africa/Asmara"_ba << "Africa/Asmera"_ba; + QTest::newRow("Argentina/Catamarca") + << "America/Argentina/Catamarca"_ba << "America/Catamarca"_ba; + QTest::newRow("Godthab=Nuuk") << "America/Nuuk"_ba << "America/Godthab"_ba; + QTest::newRow("Indiana/Indianapolis") + << "America/Indiana/Indianapolis"_ba << "America/Indianapolis"_ba; + QTest::newRow("Kentucky/Louisville") + << "America/Kentucky/Louisville"_ba << "America/Louisville"_ba; + QTest::newRow("Calcutta=Kolkata") << "Asia/Kolkata"_ba << "Asia/Calcutta"_ba; + QTest::newRow("Katmandu=Kathmandu") << "Asia/Kathmandu"_ba << "Asia/Katmandu"_ba; + QTest::newRow("Rangoon=Yangon") << "Asia/Yangon"_ba << "Asia/Rangoon"_ba; + QTest::newRow("Saigon=Ho_Chi_Minh") << "Asia/Ho_Chi_Minh"_ba << "Asia/Saigon"_ba; + QTest::newRow("Faeroe=Faroe") << "Atlantic/Faroe"_ba << "Atlantic/Faeroe"_ba; + QTest::newRow("Currie=Hobart") << "Australia/Hobart"_ba << "Australia/Currie"_ba; + QTest::newRow("Kiev=Kyiv") << "Europe/Kyiv"_ba << "Europe/Kiev"_ba; + QTest::newRow("Uzhgorod=Kyiv") << "Europe/Kyiv"_ba << "Europe/Uzhgorod"_ba; + QTest::newRow("Zaporozhye=Kyiv") << "Europe/Kyiv"_ba << "Europe/Zaporozhye"_ba; + QTest::newRow("Fiji=Fiji") << "Pacific/Fiji"_ba << "Pacific/Fiji"_ba; + QTest::newRow("Enderbury=Enderbury") << "Pacific/Enderbury"_ba << "Pacific/Enderbury"_ba; +} + +void tst_QTimeZone::aliasMatches() +{ + QFETCH(const QByteArray, iana); + QFETCH(const QByteArray, alias); + const QTimeZone zone(iana); + const QTimeZone peer(alias); + if (!zone.isValid()) + QSKIP("Backend doesn't support IANA ID"); + + auto report = qScopeGuard([zone, peer]() { + const QByteArray zid = zone.id(), pid = peer.id(); + qDebug("Using %s and %s", zid.constData(), pid.constData()); + }); + QVERIFY2(peer.isValid(), "Construction should have fallen back on IANA ID"); + QVERIFY(zone.aliasMatches(zone.id())); + QVERIFY(zone.aliasMatches(iana)); + QVERIFY(peer.aliasMatches(peer.id())); + QVERIFY(peer.aliasMatches(alias)); + QVERIFY(zone.aliasMatches(peer.id())); + QVERIFY(zone.aliasMatches(alias)); + QVERIFY(peer.aliasMatches(zone.id())); + QVERIFY(peer.aliasMatches(iana)); + report.dismiss(); +} + void tst_QTimeZone::specificTransition_data() { QTest::addColumn<QByteArray>("zone"); @@ -924,7 +984,7 @@ void tst_QTimeZone::stressTest() for (const QByteArray &id : idList) { QTimeZone testZone = QTimeZone(id); QCOMPARE(testZone.isValid(), true); - QCOMPARE(testZone.id(), id); + QVERIFY2(testZone.aliasMatches(id), testZone.id() + " != " + id); QDateTime testDate = QDateTime(QDate(2015, 1, 1), QTime(0, 0), UTC); testZone.territory(); testZone.comment(); @@ -972,7 +1032,7 @@ void tst_QTimeZone::windowsId() Current Windows zones for "Central Standard Time": Region IANA Id(s) Default "America/Chicago" - Canada "America/Winnipeg America/Rainy_River America/Rankin_Inlet America/Resolute" + Canada "America/Winnipeg America/Rankin_Inlet America/Resolute" Mexico "America/Matamoros" USA "America/Chicago America/Indiana/Knox America/Indiana/Tell_City America/Menominee" "America/North_Dakota/Beulah America/North_Dakota/Center" @@ -1004,8 +1064,8 @@ void tst_QTimeZone::windowsId() "America/Chicago", "America/Indiana/Knox", "America/Indiana/Tell_City", "America/Matamoros", "America/Menominee", "America/North_Dakota/Beulah", "America/North_Dakota/Center", "America/North_Dakota/New_Salem", - "America/Ojinaga", "America/Rainy_River", "America/Rankin_Inlet", - "America/Resolute", "America/Winnipeg", "CST6CDT" + "America/Ojinaga", "America/Rankin_Inlet", "America/Resolute", + "America/Winnipeg", "CST6CDT" }; QCOMPARE(QTimeZone::windowsIdToIanaIds("Central Standard Time"), list); } @@ -1018,7 +1078,7 @@ void tst_QTimeZone::windowsId() { // Check valid country returns list in preference order const QList<QByteArray> list = { - "America/Winnipeg", "America/Rainy_River", "America/Rankin_Inlet", "America/Resolute" + "America/Winnipeg", "America/Rankin_Inlet", "America/Resolute" }; QCOMPARE(QTimeZone::windowsIdToIanaIds("Central Standard Time", QLocale::Canada), list); } @@ -1280,7 +1340,7 @@ void tst_QTimeZone::utcTest() void tst_QTimeZone::icuTest() { -#if defined(QT_BUILD_INTERNAL) && QT_CONFIG(icu) +#if defined(QT_BUILD_INTERNAL) && QT_CONFIG(icu) && !defined(Q_OS_UNIX) // Known datetimes qint64 std = QDateTime(QDate(2012, 1, 1), QTime(0, 0), QTimeZone::UTC).toMSecsSinceEpoch(); qint64 dst = QDateTime(QDate(2012, 6, 1), QTime(0, 0), QTimeZone::UTC).toMSecsSinceEpoch(); @@ -1323,7 +1383,7 @@ void tst_QTimeZone::icuTest() if (QTest::currentTestFailed()) return; testEpochTranPrivate(QIcuTimeZonePrivate("America/Toronto")); -#endif // icu +#endif // ICU not on Unix } void tst_QTimeZone::tzTest() @@ -1527,7 +1587,7 @@ void tst_QTimeZone::tzTest() QDateTime dt(QDate(2016, 3, 28), QTime(0, 0), UTC); QCOMPARE(tzBarnaul.data(dt.toMSecsSinceEpoch()).abbreviation, QString("+07")); } -#endif // QT_BUILD_INTERNAL && Q_OS_UNIX && !Q_OS_DARWIN +#endif // QT_BUILD_INTERNAL && Q_OS_UNIX && !Q_OS_DARWIN && !Q_OS_ANDROID } void tst_QTimeZone::macTest() @@ -1685,6 +1745,8 @@ void tst_QTimeZone::localeSpecificDisplayName() QVERIFY(zone.isValid()); const QString localeName = zone.displayName(timeType, QTimeZone::LongName, locale); + if (localeName.isEmpty()) // Backend doesn't know how to localize this zone's name + QEXPECT_FAIL("", "QTBUG-115158 zone name localization unknown", Continue); QCOMPARE(localeName, expectedName); } @@ -1857,18 +1919,10 @@ void tst_QTimeZone::stdCompatibility() QFETCH(const std::chrono::time_zone *, timeZone); QByteArrayView zoneName = QByteArrayView(timeZone->name()); QTimeZone tz = QTimeZone::fromStdTimeZonePtr(timeZone); - if (tz.isValid()) { - QCOMPARE(tz.id(), zoneName); - } else { - // QTBUG-102187: a few timezones reported by tzdb might not be - // recognized by QTimeZone. This happens for instance on Windows, where - // tzdb is using ICU, whose database does not match QTimeZone's. - const bool isKnownUnknown = - !zoneName.contains('/') - || zoneName == "Antarctica/Troll" - || zoneName.startsWith("SystemV/"); - QVERIFY(isKnownUnknown); - } + if (tz.isValid()) + QVERIFY2(tz.aliasMatches(zoneName), tz.id().constData()); + else + QVERIFY(!QTimeZone::isTimeZoneIdAvailable(zoneName.toByteArray())); #else QSKIP("This test requires C++20's <chrono>."); #endif diff --git a/tests/auto/corelib/time/qtimezone/tst_qtimezone_darwin.mm b/tests/auto/corelib/time/qtimezone/tst_qtimezone_darwin.mm index 6102fd8a60..f4ef15036d 100644 --- a/tests/auto/corelib/time/qtimezone/tst_qtimezone_darwin.mm +++ b/tests/auto/corelib/time/qtimezone/tst_qtimezone_darwin.mm @@ -9,7 +9,7 @@ void tst_QTimeZone_darwinTypes() { -#if !defined(QT_NO_SYSTEMLOCALE) +#if QT_CONFIG(timezone) // QTimeZone <-> CFTimeZone { QTimeZone qtTimeZone("America/Los_Angeles"); @@ -39,5 +39,5 @@ void tst_QTimeZone_darwinTypes() QVERIFY([qtTimeZone.toNSTimeZone() isEqual:nsTimeZone]); [autoreleasepool release]; } -#endif +#endif // feature timezone } diff --git a/tests/auto/corelib/tools/qbitarray/CMakeLists.txt b/tests/auto/corelib/tools/qbitarray/CMakeLists.txt index 802d647abb..ac3bd24bd5 100644 --- a/tests/auto/corelib/tools/qbitarray/CMakeLists.txt +++ b/tests/auto/corelib/tools/qbitarray/CMakeLists.txt @@ -14,4 +14,6 @@ endif() qt_internal_add_test(tst_qbitarray SOURCES tst_qbitarray.cpp + LIBRARIES + Qt::TestPrivate ) diff --git a/tests/auto/corelib/tools/qbitarray/tst_qbitarray.cpp b/tests/auto/corelib/tools/qbitarray/tst_qbitarray.cpp index 5fcf444485..f52a368aa9 100644 --- a/tests/auto/corelib/tools/qbitarray/tst_qbitarray.cpp +++ b/tests/auto/corelib/tools/qbitarray/tst_qbitarray.cpp @@ -2,6 +2,7 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QTest> +#include <QtTest/private/qcomparisontesthelper_p.h> #include <QtCore/QBuffer> #include <QtCore/QDataStream> @@ -39,6 +40,7 @@ class tst_QBitArray : public QObject { Q_OBJECT private slots: + void compareCompiles(); void canHandleIntMaxBits(); void size_data(); void size(); @@ -85,6 +87,11 @@ private slots: void toUInt32(); }; +void tst_QBitArray::compareCompiles() +{ + QTestPrivate::testEqualityOperatorsCompile<QBitArray>(); +} + void tst_QBitArray::canHandleIntMaxBits() { QElapsedTimer timer; @@ -126,7 +133,7 @@ void tst_QBitArray::canHandleIntMaxBits() QBitArray ba2; ds >> ba2; QCOMPARE(ds.status(), QDataStream::Status::Ok); - QCOMPARE(ba, ba2); + QT_TEST_EQUALITY_OPS(ba, ba2, true); } } catch (const std::bad_alloc &) { QSKIP("Failed to allocate sufficient memory"); @@ -266,14 +273,20 @@ void tst_QBitArray::isEmpty() QVERIFY(!a1.isEmpty()); QVERIFY(!a1.isNull()); QVERIFY(a1.size() == 2); + + QT_TEST_EQUALITY_OPS(a1, a2, false); + QT_TEST_EQUALITY_OPS(a2, a3, false); + QT_TEST_EQUALITY_OPS(QBitArray(), QBitArray(), true); + a3 = a2; + QT_TEST_EQUALITY_OPS(a2, a3, true); } void tst_QBitArray::swap() { QBitArray b1 = QStringToQBitArray("1"), b2 = QStringToQBitArray("10"); b1.swap(b2); - QCOMPARE(b1,QStringToQBitArray("10")); - QCOMPARE(b2,QStringToQBitArray("1")); + QT_TEST_EQUALITY_OPS(b1,QStringToQBitArray("10"), true); + QT_TEST_EQUALITY_OPS(b2,QStringToQBitArray("1"), true); } void tst_QBitArray::fill() @@ -323,7 +336,7 @@ void tst_QBitArray::toggleBit() input.toggleBit(index); - QCOMPARE(input, res); + QT_TEST_EQUALITY_OPS(input, res, true); } void tst_QBitArray::operator_andeq_data() @@ -370,32 +383,32 @@ void tst_QBitArray::operator_andeq() QBitArray result = input1; result &= input2; - QCOMPARE(result, res); + QT_TEST_EQUALITY_OPS(result, res, true); result = input1; result &= std::move(input2); - QCOMPARE(result, res); + QT_TEST_EQUALITY_OPS(result, res, true); result = input1; result &= detached(input2); - QCOMPARE(result, res); + QT_TEST_EQUALITY_OPS(result, res, true); // operation is commutative result = input2; result &= input1; - QCOMPARE(result, res); + QT_TEST_EQUALITY_OPS(result, res, true); result = input2; result &= std::move(input1); - QCOMPARE(result, res); + QT_TEST_EQUALITY_OPS(result, res, true); result = input2; result &= detached(input1); - QCOMPARE(result, res); + QT_TEST_EQUALITY_OPS(result, res, true); // operation is idempotent result &= result; - QCOMPARE(result, res); + QT_TEST_EQUALITY_OPS(result, res, true); result &= std::move(result); - QCOMPARE(result, res); + QT_TEST_EQUALITY_OPS(result, res, true); result &= detached(result); - QCOMPARE(result, res); + QT_TEST_EQUALITY_OPS(result, res, true); } void tst_QBitArray::operator_and() @@ -405,27 +418,27 @@ void tst_QBitArray::operator_and() QFETCH(QBitArray, res); QBitArray result = input1 & input2; - QCOMPARE(result, res); + QT_TEST_EQUALITY_OPS(result, res, true); result = input1 & QBitArray(input2); - QCOMPARE(result, res); + QT_TEST_EQUALITY_OPS(result, res, true); result = input1 & detached(input2); - QCOMPARE(result, res); + QT_TEST_EQUALITY_OPS(result, res, true); // operation is commutative result = input2 & input1; - QCOMPARE(result, res); + QT_TEST_EQUALITY_OPS(result, res, true); result = input2 & QBitArray(input1); - QCOMPARE(result, res); + QT_TEST_EQUALITY_OPS(result, res, true); result = input2 & detached(input1); - QCOMPARE(result, res); + QT_TEST_EQUALITY_OPS(result, res, true); // operation is idempotent result = result & result; - QCOMPARE(result, res); + QT_TEST_EQUALITY_OPS(result, res, true); result = result & QBitArray(result); - QCOMPARE(result, res); + QT_TEST_EQUALITY_OPS(result, res, true); result = result & detached(result); - QCOMPARE(result, res); + QT_TEST_EQUALITY_OPS(result, res, true); } void tst_QBitArray::operator_oreq_data() @@ -476,32 +489,32 @@ void tst_QBitArray::operator_oreq() QBitArray result = input1; result |= input2; - QCOMPARE(result, res); + QT_TEST_EQUALITY_OPS(result, res, true); result = input1; result |= QBitArray(input2); - QCOMPARE(result, res); + QT_TEST_EQUALITY_OPS(result, res, true); result = input1; result |= detached(input2); - QCOMPARE(result, res); + QT_TEST_EQUALITY_OPS(result, res, true); // operation is commutative result = input2; result |= input1; - QCOMPARE(result, res); + QT_TEST_EQUALITY_OPS(result, res, true); result = input2; result |= QBitArray(input1); - QCOMPARE(result, res); + QT_TEST_EQUALITY_OPS(result, res, true); result = input2; result |= detached(input1); - QCOMPARE(result, res); + QT_TEST_EQUALITY_OPS(result, res, true); // operation is idempotent result |= result; - QCOMPARE(result, res); + QT_TEST_EQUALITY_OPS(result, res, true); result |= QBitArray(result); - QCOMPARE(result, res); + QT_TEST_EQUALITY_OPS(result, res, true); result |= detached(result); - QCOMPARE(result, res); + QT_TEST_EQUALITY_OPS(result, res, true); } void tst_QBitArray::operator_or() @@ -511,27 +524,27 @@ void tst_QBitArray::operator_or() QFETCH(QBitArray, res); QBitArray result = input1 | input2; - QCOMPARE(result, res); + QT_TEST_EQUALITY_OPS(result, res, true); result = input1 | QBitArray(input2); - QCOMPARE(result, res); + QT_TEST_EQUALITY_OPS(result, res, true); result = input1 | detached(input2); - QCOMPARE(result, res); + QT_TEST_EQUALITY_OPS(result, res, true); // operation is commutative result = input2 | input1; - QCOMPARE(result, res); + QT_TEST_EQUALITY_OPS(result, res, true); result = input2 | QBitArray(input1); - QCOMPARE(result, res); + QT_TEST_EQUALITY_OPS(result, res, true); result = input2 | detached(input1); - QCOMPARE(result, res); + QT_TEST_EQUALITY_OPS(result, res, true); // operation is idempotent result = result | result; - QCOMPARE(result, res); + QT_TEST_EQUALITY_OPS(result, res, true); result = result | QBitArray(result); - QCOMPARE(result, res); + QT_TEST_EQUALITY_OPS(result, res, true); result = result | detached(result); - QCOMPARE(result, res); + QT_TEST_EQUALITY_OPS(result, res, true); } void tst_QBitArray::operator_xoreq_data() @@ -580,55 +593,55 @@ void tst_QBitArray::operator_xoreq() QBitArray result = input1; result ^= input2; - QCOMPARE(result, res); + QT_TEST_EQUALITY_OPS(result, res, true); result = input1; result ^= QBitArray(input2); - QCOMPARE(result, res); + QT_TEST_EQUALITY_OPS(result, res, true); result = input1; result ^= detached(input2); - QCOMPARE(result, res); + QT_TEST_EQUALITY_OPS(result, res, true); // operation is commutative result = input2; result ^= input1; - QCOMPARE(result, res); + QT_TEST_EQUALITY_OPS(result, res, true); result = input2; result ^= QBitArray(input1); - QCOMPARE(result, res); + QT_TEST_EQUALITY_OPS(result, res, true); result = input2; result ^= detached(input1); - QCOMPARE(result, res); + QT_TEST_EQUALITY_OPS(result, res, true); // XORing with oneself is nilpotent result = input1; result ^= input1; - QCOMPARE(result, QBitArray(input1.size())); + QT_TEST_EQUALITY_OPS(result, QBitArray(input1.size()), true); result = input1; result ^= QBitArray(result); - QCOMPARE(result, QBitArray(input1.size())); + QT_TEST_EQUALITY_OPS(result, QBitArray(input1.size()), true); result = input1; result ^= detached(result); - QCOMPARE(result, QBitArray(input1.size())); + QT_TEST_EQUALITY_OPS(result, QBitArray(input1.size()), true); result = input2; result ^= input2; - QCOMPARE(result, QBitArray(input2.size())); + QT_TEST_EQUALITY_OPS(result, QBitArray(input2.size()), true); result = input2; result ^= QBitArray(input2); - QCOMPARE(result, QBitArray(input2.size())); + QT_TEST_EQUALITY_OPS(result, QBitArray(input2.size()), true); result = input2; result ^= detached(input2); - QCOMPARE(result, QBitArray(input2.size())); + QT_TEST_EQUALITY_OPS(result, QBitArray(input2.size()), true); result = res; result ^= res; - QCOMPARE(result, QBitArray(res.size())); + QT_TEST_EQUALITY_OPS(result, QBitArray(res.size()), true); result = res; result ^= QBitArray(res); - QCOMPARE(result, QBitArray(res.size())); + QT_TEST_EQUALITY_OPS(result, QBitArray(res.size()), true); result = res; result ^= detached(res); - QCOMPARE(result, QBitArray(res.size())); + QT_TEST_EQUALITY_OPS(result, QBitArray(res.size()), true); } void tst_QBitArray::operator_xor() @@ -638,41 +651,41 @@ void tst_QBitArray::operator_xor() QFETCH(QBitArray, res); QBitArray result = input1 ^ input2; - QCOMPARE(result, res); + QT_TEST_EQUALITY_OPS(result, res, true); result = input1 ^ QBitArray(input2); - QCOMPARE(result, res); + QT_TEST_EQUALITY_OPS(result, res, true); result = input1 ^ detached(input2); - QCOMPARE(result, res); + QT_TEST_EQUALITY_OPS(result, res, true); // operation is commutative result = input2 ^ input1; - QCOMPARE(result, res); + QT_TEST_EQUALITY_OPS(result, res, true); result = input2 ^ QBitArray(input1); - QCOMPARE(result, res); + QT_TEST_EQUALITY_OPS(result, res, true); result = input2 ^ detached(input1); - QCOMPARE(result, res); + QT_TEST_EQUALITY_OPS(result, res, true); // XORing with oneself is nilpotent result = input1 ^ input1; - QCOMPARE(result, QBitArray(input1.size())); + QT_TEST_EQUALITY_OPS(result, QBitArray(input1.size()), true); result = input1 ^ QBitArray(input1); - QCOMPARE(result, QBitArray(input1.size())); + QT_TEST_EQUALITY_OPS(result, QBitArray(input1.size()), true); result = input1 ^ detached(input1); - QCOMPARE(result, QBitArray(input1.size())); + QT_TEST_EQUALITY_OPS(result, QBitArray(input1.size()), true); result = input2 ^ input2; - QCOMPARE(result, QBitArray(input2.size())); + QT_TEST_EQUALITY_OPS(result, QBitArray(input2.size()), true); result = input2 ^ QBitArray(input2); - QCOMPARE(result, QBitArray(input2.size())); + QT_TEST_EQUALITY_OPS(result, QBitArray(input2.size()), true); result = input2 ^ detached(input2); - QCOMPARE(result, QBitArray(input2.size())); + QT_TEST_EQUALITY_OPS(result, QBitArray(input2.size()), true); result = res ^ res; - QCOMPARE(result, QBitArray(res.size())); + QT_TEST_EQUALITY_OPS(result, QBitArray(res.size()), true); result = res ^ QBitArray(res); - QCOMPARE(result, QBitArray(res.size())); + QT_TEST_EQUALITY_OPS(result, QBitArray(res.size()), true); result = res ^ detached(res); - QCOMPARE(result, QBitArray(res.size())); + QT_TEST_EQUALITY_OPS(result, QBitArray(res.size()), true); } void tst_QBitArray::operator_neg_data() @@ -721,8 +734,8 @@ void tst_QBitArray::operator_neg() input = ~input; - QCOMPARE(input, res); - QCOMPARE(~~input, res); // performs two in-place negations + QT_TEST_EQUALITY_OPS(input, res, true); + QT_TEST_EQUALITY_OPS(~~input, res, true); // performs two in-place negations } void tst_QBitArray::datastream_data() @@ -782,15 +795,15 @@ void tst_QBitArray::datastream() QCOMPARE(array1.count(true), onBits); QCOMPARE(array1.count(false), numBits - onBits); - QCOMPARE(array1, bits); - QCOMPARE(array2, bits); - QCOMPARE(array3, bits); + QT_TEST_EQUALITY_OPS(array1, bits, true); + QT_TEST_EQUALITY_OPS(array2, bits, true); + QT_TEST_EQUALITY_OPS(array3, bits, true); } void tst_QBitArray::invertOnNull() const { QBitArray a; - QCOMPARE(a = ~a, QBitArray()); + QT_TEST_EQUALITY_OPS(a = ~a, QBitArray(), true); } void tst_QBitArray::operator_noteq_data() @@ -831,7 +844,7 @@ void tst_QBitArray::operator_noteq() QFETCH(bool, res); bool b = input1 != input2; - QCOMPARE(b, res); + QT_TEST_EQUALITY_OPS(b, res, true); } void tst_QBitArray::resize() @@ -840,22 +853,22 @@ void tst_QBitArray::resize() QBitArray a = QStringToQBitArray(QString("11")); a.resize(10); QVERIFY(a.size() == 10); - QCOMPARE( a, QStringToQBitArray(QString("1100000000")) ); + QT_TEST_EQUALITY_OPS( a, QStringToQBitArray(QString("1100000000")), true); a.setBit(9); a.resize(9); // now the bit in a should have been gone: - QCOMPARE( a, QStringToQBitArray(QString("110000000")) ); + QT_TEST_EQUALITY_OPS( a, QStringToQBitArray(QString("110000000")), true); // grow the array back and check the new bit a.resize(10); - QCOMPARE( a, QStringToQBitArray(QString("1100000000")) ); + QT_TEST_EQUALITY_OPS( a, QStringToQBitArray(QString("1100000000")), true); // other test with and a.resize(9); QBitArray b = QStringToQBitArray(QString("1111111111")); b &= a; - QCOMPARE( b, QStringToQBitArray(QString("1100000000")) ); + QT_TEST_EQUALITY_OPS( b, QStringToQBitArray(QString("1100000000")), true); } @@ -909,9 +922,9 @@ void tst_QBitArray::fromBits() QFETCH(QBitArray, expected); QBitArray fromBits = QBitArray::fromBits(data, size); - QCOMPARE(fromBits, expected); + QT_TEST_EQUALITY_OPS(fromBits, expected, true); - QCOMPARE(QBitArray::fromBits(fromBits.bits(), fromBits.size()), expected); + QT_TEST_EQUALITY_OPS(QBitArray::fromBits(fromBits.bits(), fromBits.size()), expected, true); } void tst_QBitArray::toUInt32_data() diff --git a/tests/auto/corelib/tools/qcryptographichash/tst_qcryptographichash.cpp b/tests/auto/corelib/tools/qcryptographichash/tst_qcryptographichash.cpp index c08afd67c4..47e0ead270 100644 --- a/tests/auto/corelib/tools/qcryptographichash/tst_qcryptographichash.cpp +++ b/tests/auto/corelib/tools/qcryptographichash/tst_qcryptographichash.cpp @@ -20,6 +20,8 @@ private slots: void repeated_result(); void intermediary_result_data(); void intermediary_result(); + void static_hash_data() { intermediary_result_data(); } + void static_hash(); void sha1(); void sha3_data(); void sha3(); @@ -29,9 +31,9 @@ private slots: void blake2(); void files_data(); void files(); - void hashLength_data(); + void hashLength_data() { all_methods(true); } void hashLength(); - void addDataAcceptsNullByteArrayView_data() { hashLength_data(); } + void addDataAcceptsNullByteArrayView_data() { all_methods(false); } void addDataAcceptsNullByteArrayView(); void move(); void swap(); @@ -40,6 +42,7 @@ private slots: void moreThan4GiBOfData(); void keccakBufferOverflow(); private: + void all_methods(bool includingNumAlgorithms) const; void ensureLargeData(); std::vector<char> large; }; @@ -197,6 +200,20 @@ void tst_QCryptographicHash::intermediary_result() hash.reset(); } +void tst_QCryptographicHash::static_hash() +{ + QFETCH(const int, algo); + QFETCH(const QByteArray, first); + QFETCH(const QByteArray, hash_first); + + const auto _algo = QCryptographicHash::Algorithm(algo); + + QCOMPARE(QCryptographicHash::hash(first, _algo), hash_first); + + std::byte buffer[1024]; + QCOMPARE(QCryptographicHash::hashInto(buffer, first, _algo), hash_first); +} + void tst_QCryptographicHash::sha1() { @@ -474,12 +491,14 @@ void tst_QCryptographicHash::files() } } -void tst_QCryptographicHash::hashLength_data() +void tst_QCryptographicHash::all_methods(bool inclNumAlgos) const { QTest::addColumn<QCryptographicHash::Algorithm>("algorithm"); auto metaEnum = QMetaEnum::fromType<QCryptographicHash::Algorithm>(); for (int i = 0, value = metaEnum.value(i); value != -1; value = metaEnum.value(++i)) { auto algorithm = QCryptographicHash::Algorithm(value); + if (!inclNumAlgos && algorithm == QCryptographicHash::Algorithm::NumAlgorithms) + continue; QTest::addRow("%s", metaEnum.key(i)) << algorithm; } } @@ -495,6 +514,9 @@ void tst_QCryptographicHash::hashLength() expectedSize = 0; } else { expectedSize = QCryptographicHash::hash("test", algorithm).size(); + + std::byte buffer[1024]; + QCOMPARE(QCryptographicHash::hashInto(buffer, "foo", algorithm).size(), expectedSize); } QCOMPARE(QCryptographicHash::hashLength(algorithm), expectedSize); } diff --git a/tests/auto/corelib/tools/qeasingcurve/CMakeLists.txt b/tests/auto/corelib/tools/qeasingcurve/CMakeLists.txt index 3f76f8a38f..2569e0c7a9 100644 --- a/tests/auto/corelib/tools/qeasingcurve/CMakeLists.txt +++ b/tests/auto/corelib/tools/qeasingcurve/CMakeLists.txt @@ -14,4 +14,6 @@ endif() qt_internal_add_test(tst_qeasingcurve SOURCES tst_qeasingcurve.cpp + LIBRARIES + Qt::TestPrivate ) diff --git a/tests/auto/corelib/tools/qeasingcurve/tst_qeasingcurve.cpp b/tests/auto/corelib/tools/qeasingcurve/tst_qeasingcurve.cpp index fc8c1a3e5c..0a933a1e2b 100644 --- a/tests/auto/corelib/tools/qeasingcurve/tst_qeasingcurve.cpp +++ b/tests/auto/corelib/tools/qeasingcurve/tst_qeasingcurve.cpp @@ -2,6 +2,7 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QTest> +#include <private/qcomparisontesthelper_p.h> #include <qeasingcurve.h> @@ -16,6 +17,7 @@ private slots: void valueForProgress_data(); void valueForProgress(); void setCustomType(); + void comparisonCompiles(); void operators(); void properties(); void metaTypes(); @@ -420,6 +422,11 @@ void tst_QEasingCurve::setCustomType() QCOMPARE(curve.valueForProgress(0.99), 0.99); } +void tst_QEasingCurve::comparisonCompiles() +{ + QTestPrivate::testEqualityOperatorsCompile<QEasingCurve>(); +} + void tst_QEasingCurve::operators() { { // member-swap() @@ -447,28 +454,28 @@ void tst_QEasingCurve::operators() curve2 = curve; curve2.setOvershoot(qreal(1.70158)); QCOMPARE(curve.overshoot(), curve2.overshoot()); - QVERIFY(curve2 == curve); + QT_TEST_EQUALITY_OPS(curve2, curve, true); curve.setOvershoot(3.0); - QVERIFY(curve2 != curve); + QT_TEST_EQUALITY_OPS(curve2, curve, false); curve2.setOvershoot(3.0); - QVERIFY(curve2 == curve); + QT_TEST_EQUALITY_OPS(curve2, curve, true); curve2.setType(QEasingCurve::Linear); QCOMPARE(curve.overshoot(), curve2.overshoot()); - QVERIFY(curve2 != curve); + QT_TEST_EQUALITY_OPS(curve2, curve, false); curve2.setType(QEasingCurve::InBack); QCOMPARE(curve.overshoot(), curve2.overshoot()); - QVERIFY(curve2 == curve); + QT_TEST_EQUALITY_OPS(curve2, curve, true); QEasingCurve curve3; QEasingCurve curve4; curve4.setAmplitude(curve4.amplitude()); QEasingCurve curve5; curve5.setAmplitude(0.12345); - QVERIFY(curve3 == curve4); // default value and not assigned - QVERIFY(curve3 != curve5); // unassinged and other value - QVERIFY(curve4 != curve5); + QT_TEST_EQUALITY_OPS(curve3, curve4, true); // default value and not assigned + QT_TEST_EQUALITY_OPS(curve3, curve5, false); // unassinged and other value + QT_TEST_EQUALITY_OPS(curve4, curve5, false); } class tst_QEasingProperties : public QObject @@ -890,7 +897,7 @@ void tst_QEasingCurve::streamInOut() dsw << orig; dsr >> copy; - QCOMPARE(copy == orig, equality); + QT_TEST_EQUALITY_OPS(copy, orig, equality); } QTEST_MAIN(tst_QEasingCurve) diff --git a/tests/auto/corelib/tools/qhashseed/tst_qhashseed.cpp b/tests/auto/corelib/tools/qhashseed/tst_qhashseed.cpp index 99fc7c5772..e004a560a2 100644 --- a/tests/auto/corelib/tools/qhashseed/tst_qhashseed.cpp +++ b/tests/auto/corelib/tools/qhashseed/tst_qhashseed.cpp @@ -21,7 +21,7 @@ private Q_SLOTS: void deterministicSeed(); void reseeding(); void quality(); -#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0) +#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0) && QT_DEPRECATED_SINCE(6,6) void compatibilityApi(); void deterministicSeed_compat(); #endif @@ -157,7 +157,7 @@ void tst_QHashSeed::quality() "seedsToMinus1 = " + QByteArray::number(seedsToMinus1)); } -#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0) +#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0) && QT_DEPRECATED_SINCE(6,6) QT_WARNING_DISABLE_DEPRECATED void tst_QHashSeed::compatibilityApi() { diff --git a/tests/auto/corelib/tools/qline/CMakeLists.txt b/tests/auto/corelib/tools/qline/CMakeLists.txt index 17a3a1bcef..7d9fdf51a9 100644 --- a/tests/auto/corelib/tools/qline/CMakeLists.txt +++ b/tests/auto/corelib/tools/qline/CMakeLists.txt @@ -14,6 +14,8 @@ endif() qt_internal_add_test(tst_qline SOURCES tst_qline.cpp + LIBRARIES + Qt::TestPrivate ) ## Scopes: diff --git a/tests/auto/corelib/tools/qline/tst_qline.cpp b/tests/auto/corelib/tools/qline/tst_qline.cpp index 51f1f8ac79..10069e821b 100644 --- a/tests/auto/corelib/tools/qline/tst_qline.cpp +++ b/tests/auto/corelib/tools/qline/tst_qline.cpp @@ -4,6 +4,7 @@ #include <QTest> #include <qline.h> #include <qmath.h> +#include <private/qcomparisontesthelper_p.h> #include <array> @@ -11,6 +12,16 @@ class tst_QLine : public QObject { Q_OBJECT private slots: + void testComparisonCompiles(); + void testComparison_data(); + void testComparison(); + + void testFuzzyCompare_data(); + void testFuzzyCompare(); + + void testIsNull_data(); + void testIsNull(); + void testIntersection(); void testIntersection_data(); @@ -41,6 +52,120 @@ private slots: }; const qreal epsilon = sizeof(qreal) == sizeof(double) ? 1e-8 : 1e-4; +constexpr static qreal qreal_min = std::numeric_limits<qreal>::min(); + +void tst_QLine::testComparisonCompiles() +{ + QTestPrivate::testEqualityOperatorsCompile<QLine>(); + QTestPrivate::testEqualityOperatorsCompile<QLineF>(); + QTestPrivate::testEqualityOperatorsCompile<QLineF, QLine>(); +} + +void tst_QLine::testComparison_data() +{ + QTest::addColumn<double>("xa1"); + QTest::addColumn<double>("ya1"); + QTest::addColumn<double>("xa2"); + QTest::addColumn<double>("ya2"); + QTest::addColumn<double>("xb1"); + QTest::addColumn<double>("yb1"); + QTest::addColumn<double>("xb2"); + QTest::addColumn<double>("yb2"); + QTest::addColumn<bool>("result"); + QTest::addColumn<bool>("floatResult"); + QTest::addColumn<bool>("mixedResult"); + + auto row = [&](double xa1, double ya1, double xa2, double ya2, + double xb1, double yb1, double xb2, double yb2, + bool result, bool floatResult, bool mixedResult) + { + QString str; + QDebug dbg(&str); + dbg.nospace() << "[(" << xa1 << ", " << ya1 << "); (" << xa2 << ", " << ya2 << ")] vs [(" + << xb1 << ", " << yb1 << "); (" << xb2 << ", " << yb2 << ")]"; + QTest::addRow("%s", str.toLatin1().constData()) + << xa1 << ya1 << xa2 << ya2 << xb1 << yb1 << xb2 << yb2 + << result << floatResult << mixedResult; + }; + + row(-1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, true, true, true); + row(-1.1, -0.9, 1.1, 0.9, -1.0, -1.0, 1.0, 1.0, true, false, false); + row(-1.0, -1.0, 1.0, 1.0, -0.9, -1.1, 0.9, 1.1, true, false, true); + row(-qreal_min, -1.0, 1.0, qreal_min, 0.0, -1.1, 0.9, 0.0, true, false, true); +} + +void tst_QLine::testComparison() +{ + QFETCH(double, xa1); + QFETCH(double, ya1); + QFETCH(double, xa2); + QFETCH(double, ya2); + QFETCH(double, xb1); + QFETCH(double, yb1); + QFETCH(double, xb2); + QFETCH(double, yb2); + QFETCH(bool, result); + QFETCH(bool, floatResult); + QFETCH(bool, mixedResult); + + const QLineF l1f(xa1, ya1, xa2, ya2); + const QLine l1 = l1f.toLine(); + + const QLineF l2f(xb1, yb1, xb2, yb2); + const QLine l2 = l2f.toLine(); + + QT_TEST_EQUALITY_OPS(l1, l2, result); + QT_TEST_EQUALITY_OPS(l1f, l2f, floatResult); + QT_TEST_EQUALITY_OPS(l1f, l2, mixedResult); +} + +void tst_QLine::testFuzzyCompare_data() +{ + testComparison_data(); +} + +void tst_QLine::testFuzzyCompare() +{ + QFETCH(double, xa1); + QFETCH(double, ya1); + QFETCH(double, xa2); + QFETCH(double, ya2); + QFETCH(double, xb1); + QFETCH(double, yb1); + QFETCH(double, xb2); + QFETCH(double, yb2); + QFETCH(bool, floatResult); + + const QLineF l1f(xa1, ya1, xa2, ya2); + const QLineF l2f(xb1, yb1, xb2, yb2); + + QCOMPARE_EQ(qFuzzyCompare(l1f, l2f), floatResult); +} + +void tst_QLine::testIsNull_data() +{ + QTest::addColumn<QLineF>("lineF"); + QTest::addColumn<bool>("result"); + QTest::addColumn<bool>("floatResult"); + + QTest::newRow("non-null") << QLineF(1.0, 1.0, 2.0, 2.0) << false << false; + QTest::newRow("null") << QLineF(1.0, 1.0, 1.0, 1.0) << true << true; + QTest::newRow("null_int_non-null_float") << QLineF(1.0, 1.0, 1.1, 1.1) << true << false; + QTest::newRow("with_qreal_min") << QLineF(-qreal_min, qreal_min, 0.0, 0.0) << true << true; +} + +void tst_QLine::testIsNull() +{ + QFETCH(QLineF, lineF); + QFETCH(bool, result); + QFETCH(bool, floatResult); + + const QLine line = lineF.toLine(); + + QCOMPARE_EQ(line.isNull(), result); + QCOMPARE_EQ(lineF.isNull(), floatResult); + QCOMPARE_EQ(qFuzzyIsNull(lineF), floatResult); +} void tst_QLine::testSet() { diff --git a/tests/auto/corelib/tools/qmargins/CMakeLists.txt b/tests/auto/corelib/tools/qmargins/CMakeLists.txt index 2e0ea797ff..b0adf63f40 100644 --- a/tests/auto/corelib/tools/qmargins/CMakeLists.txt +++ b/tests/auto/corelib/tools/qmargins/CMakeLists.txt @@ -14,4 +14,6 @@ endif() qt_internal_add_test(tst_qmargins SOURCES tst_qmargins.cpp + LIBRARIES + Qt::TestPrivate ) diff --git a/tests/auto/corelib/tools/qmargins/tst_qmargins.cpp b/tests/auto/corelib/tools/qmargins/tst_qmargins.cpp index 2611f62f01..dc0b0e4085 100644 --- a/tests/auto/corelib/tools/qmargins/tst_qmargins.cpp +++ b/tests/auto/corelib/tools/qmargins/tst_qmargins.cpp @@ -32,15 +32,28 @@ CHECK(const &&); #include <QTest> #include <qmargins.h> +#include <private/qcomparisontesthelper_p.h> #include <array> Q_DECLARE_METATYPE(QMargins) +constexpr static qreal qreal_min = std::numeric_limits<qreal>::min(); + class tst_QMargins : public QObject { Q_OBJECT private slots: + void comparisonCompiles(); + void comparison_data(); + void comparison(); + + void fuzzyComparison_data(); + void fuzzyComparison(); + + void isNull_data(); + void isNull(); + void getSetCheck(); #ifndef QT_NO_DATASTREAM void dataStreamCheck(); @@ -65,6 +78,92 @@ private slots: void toMarginsF(); }; +void tst_QMargins::comparisonCompiles() +{ + QTestPrivate::testEqualityOperatorsCompile<QMargins>(); + QTestPrivate::testEqualityOperatorsCompile<QMarginsF>(); + QTestPrivate::testEqualityOperatorsCompile<QMarginsF, QMargins>(); +} + +void tst_QMargins::comparison_data() +{ + QTest::addColumn<QMarginsF>("lhs"); + QTest::addColumn<QMarginsF>("rhs"); + QTest::addColumn<bool>("result"); + QTest::addColumn<bool>("floatResult"); + QTest::addColumn<bool>("mixedResult"); + + auto row = [](const QMarginsF &lhs, const QMarginsF &rhs, bool res, bool fRes, bool mRes) { + QString str; + QDebug dbg(&str); + dbg.nospace() << "(" << lhs.left() << ", " << lhs.top() << ", " << lhs.right() << ", " + << lhs.bottom() << ") vs (" << rhs.left() << ", " << rhs.top() << ", " + << rhs.right() << ", " << rhs.bottom() << ")"; + QTest::addRow("%s", str.toLatin1().constData()) << lhs << rhs << res << fRes << mRes; + }; + + row(QMarginsF(0.0, 0.0, 0.0, 0.0), QMarginsF(0.0, 0.0, 0.0, 0.0), true, true, true); + row(QMarginsF(qreal_min, -qreal_min, -qreal_min, qreal_min), QMarginsF(0.0, 0.0, 0.0, 0.0), true, true, true); + row(QMarginsF(1.0, 2.0, 3.0, 4.0), QMarginsF(1.1, 2.1, 2.9, 3.9), true, false, true); + row(QMarginsF(1.5, 2.5, 3.0, 4.0), QMarginsF(1.1, 2.1, 2.9, 3.9), false, false, false); +} + +void tst_QMargins::comparison() +{ + QFETCH(const QMarginsF, lhs); + QFETCH(const QMarginsF, rhs); + QFETCH(const bool, result); + QFETCH(const bool, floatResult); + QFETCH(const bool, mixedResult); + + QT_TEST_EQUALITY_OPS(lhs, rhs, floatResult); + + const QMargins lhsInt = lhs.toMargins(); + const QMargins rhsInt = rhs.toMargins(); + QT_TEST_EQUALITY_OPS(lhsInt, rhsInt, result); + + QT_TEST_EQUALITY_OPS(lhs, rhsInt, mixedResult); +} + +void tst_QMargins::fuzzyComparison_data() +{ + comparison_data(); +} + +void tst_QMargins::fuzzyComparison() +{ + QFETCH(const QMarginsF, lhs); + QFETCH(const QMarginsF, rhs); + QFETCH(const bool, floatResult); + + QCOMPARE_EQ(qFuzzyCompare(lhs, rhs), floatResult); +} + +void tst_QMargins::isNull_data() +{ + QTest::addColumn<QMarginsF>("margins"); + QTest::addColumn<bool>("result"); + + QTest::newRow("null") << QMarginsF(0.0, 0.0, 0.0, 0.0) << true; + QTest::newRow("non_null_left") << QMarginsF(1.0, 0.0, 0.0, 0.0) << false; + QTest::newRow("non_null_top") << QMarginsF(0.0, 0.5, 0.0, 0.0) << false; + QTest::newRow("non_null_right") << QMarginsF(0.0, 0.0, -2.0, 0.0) << false; + QTest::newRow("non_null_bottom") << QMarginsF(0.0, 0.0, 0.0, -0.6) << false; + QTest::newRow("almost_null") << QMarginsF(qreal_min, -qreal_min, qreal_min, -qreal_min) << true; +} + +void tst_QMargins::isNull() +{ + QFETCH(const QMarginsF, margins); + QFETCH(const bool, result); + + QCOMPARE_EQ(margins.isNull(), result); + QCOMPARE_EQ(qFuzzyIsNull(margins), result); + + const QMargins marginsInt = margins.toMargins(); + QCOMPARE_EQ(marginsInt.isNull(), result); +} + // Testing get/set functions void tst_QMargins::getSetCheck() { diff --git a/tests/auto/corelib/tools/qpoint/CMakeLists.txt b/tests/auto/corelib/tools/qpoint/CMakeLists.txt index f1402d8815..82ece1fc15 100644 --- a/tests/auto/corelib/tools/qpoint/CMakeLists.txt +++ b/tests/auto/corelib/tools/qpoint/CMakeLists.txt @@ -14,4 +14,6 @@ endif() qt_internal_add_test(tst_qpoint SOURCES tst_qpoint.cpp + LIBRARIES + Qt::TestPrivate ) diff --git a/tests/auto/corelib/tools/qpoint/tst_qpoint.cpp b/tests/auto/corelib/tools/qpoint/tst_qpoint.cpp index 7fea787131..4763c1bf07 100644 --- a/tests/auto/corelib/tools/qpoint/tst_qpoint.cpp +++ b/tests/auto/corelib/tools/qpoint/tst_qpoint.cpp @@ -5,6 +5,7 @@ #ifdef QVARIANT_H # error "This test requires qpoint.h to not include qvariant.h" #endif +#include <private/qcomparisontesthelper_p.h> // don't assume <type_traits> template <typename T, typename U> @@ -71,6 +72,7 @@ private slots: void operator_unary_minus_data(); void operator_unary_minus(); + void operatorsCompile(); void operator_eq_data(); void operator_eq(); @@ -155,6 +157,8 @@ void tst_QPoint::toPointF() QFETCH(const QPointF, result); QCOMPARE(input.toPointF(), result); + // test also mixed-type comparison + QT_TEST_EQUALITY_OPS(input, result, true); } void tst_QPoint::transposed() @@ -350,6 +354,12 @@ void tst_QPoint::operator_unary_minus() QCOMPARE(-point, expected); } +void tst_QPoint::operatorsCompile() +{ + // Mixed-type comparison is tested in tst_QPointF. + QTestPrivate::testEqualityOperatorsCompile<QPoint>(); +} + void tst_QPoint::operator_eq_data() { QTest::addColumn<QPoint>("point1"); @@ -371,12 +381,9 @@ void tst_QPoint::operator_eq() QFETCH(QPoint, point2); QFETCH(bool, expectEqual); - bool equal = point1 == point2; - QCOMPARE(equal, expectEqual); - bool notEqual = point1 != point2; - QCOMPARE(notEqual, !expectEqual); + QT_TEST_EQUALITY_OPS(point1, point2, expectEqual); - if (equal) + if (expectEqual) QCOMPARE(qHash(point1), qHash(point2)); } diff --git a/tests/auto/corelib/tools/qpointf/CMakeLists.txt b/tests/auto/corelib/tools/qpointf/CMakeLists.txt index 16e5a9036a..28cbe185b2 100644 --- a/tests/auto/corelib/tools/qpointf/CMakeLists.txt +++ b/tests/auto/corelib/tools/qpointf/CMakeLists.txt @@ -14,4 +14,6 @@ endif() qt_internal_add_test(tst_qpointf SOURCES tst_qpointf.cpp + LIBRARIES + Qt::TestPrivate ) diff --git a/tests/auto/corelib/tools/qpointf/tst_qpointf.cpp b/tests/auto/corelib/tools/qpointf/tst_qpointf.cpp index 392c22c70a..ebbac4ec7c 100644 --- a/tests/auto/corelib/tools/qpointf/tst_qpointf.cpp +++ b/tests/auto/corelib/tools/qpointf/tst_qpointf.cpp @@ -5,6 +5,7 @@ #ifdef QVARIANT_H # error "This test requires qpoint.h to not include qvariant.h" #endif +#include <private/qcomparisontesthelper_p.h> // don't assume <type_traits> template <typename T, typename U> @@ -71,9 +72,13 @@ private slots: void operator_unary_minus_data(); void operator_unary_minus(); + void operatorsCompile(); void operator_eq_data(); void operator_eq(); + void fuzzyCompare_data(); + void fuzzyCompare(); + void toPoint_data(); void toPoint(); @@ -101,15 +106,19 @@ void tst_QPointF::isNull() { QPointF point(0, 0); QVERIFY(point.isNull()); + QVERIFY(qFuzzyIsNull(point)); ++point.rx(); QVERIFY(!point.isNull()); + QVERIFY(!qFuzzyIsNull(point)); point.rx() -= 2; QVERIFY(!point.isNull()); + QVERIFY(!qFuzzyIsNull(point)); QPointF nullNegativeZero(qreal(-0.0), qreal(-0.0)); QCOMPARE(nullNegativeZero.x(), (qreal)-0.0f); QCOMPARE(nullNegativeZero.y(), (qreal)-0.0f); QVERIFY(nullNegativeZero.isNull()); + QVERIFY(qFuzzyIsNull(nullNegativeZero)); } void tst_QPointF::manhattanLength_data() @@ -345,21 +354,29 @@ void tst_QPointF::operator_unary_minus() QCOMPARE(-point, expected); } +void tst_QPointF::operatorsCompile() +{ + QTestPrivate::testEqualityOperatorsCompile<QPointF>(); + QTestPrivate::testEqualityOperatorsCompile<QPointF, QPoint>(); +} + void tst_QPointF::operator_eq_data() { QTest::addColumn<QPointF>("point1"); QTest::addColumn<QPointF>("point2"); QTest::addColumn<bool>("expectEqual"); - - QTest::newRow("(0, 0) == (0, 0)") << QPointF(0, 0) << QPointF(0, 0) << true; - QTest::newRow("(-1, 0) == (-1, 0)") << QPointF(-1, 0) << QPointF(-1, 0) << true; - QTest::newRow("(-1, 0) != (0, 0)") << QPointF(-1, 0) << QPointF(0, 0) << false; - QTest::newRow("(-1, 0) != (0, -1)") << QPointF(-1, 0) << QPointF(0, -1) << false; - QTest::newRow("(-1.125, 0.25) == (-1.125, 0.25)") << QPointF(-1.125, 0.25) << QPointF(-1.125, 0.25) << true; + QTest::addColumn<bool>("expectIntEqual"); + + QTest::newRow("(0, 0) == (0, 0)") << QPointF(0, 0) << QPointF(0, 0) << true << true; + QTest::newRow("(-1, 0) == (-1, 0)") << QPointF(-1, 0) << QPointF(-1, 0) << true << true; + QTest::newRow("(-1, 0) != (0, 0)") << QPointF(-1, 0) << QPointF(0, 0) << false << false; + QTest::newRow("(-1, 0) != (0, -1)") << QPointF(-1, 0) << QPointF(0, -1) << false << false; + QTest::newRow("(-1.125, 0.25) == (-1.125, 0.25)") + << QPointF(-1.125, 0.25) << QPointF(-1.125, 0.25) << true << false; QTest::newRow("(QREAL_MIN, QREAL_MIN) == (QREAL_MIN, QREAL_MIN)") - << QPointF(QREAL_MIN, QREAL_MIN) << QPointF(QREAL_MIN, QREAL_MIN) << true; + << QPointF(QREAL_MIN, QREAL_MIN) << QPointF(QREAL_MIN, QREAL_MIN) << true << true; QTest::newRow("(QREAL_MAX, QREAL_MAX) == (QREAL_MAX, QREAL_MAX)") - << QPointF(QREAL_MAX, QREAL_MAX) << QPointF(QREAL_MAX, QREAL_MAX) << true; + << QPointF(QREAL_MAX, QREAL_MAX) << QPointF(QREAL_MAX, QREAL_MAX) << true << false; } void tst_QPointF::operator_eq() @@ -367,11 +384,26 @@ void tst_QPointF::operator_eq() QFETCH(QPointF, point1); QFETCH(QPointF, point2); QFETCH(bool, expectEqual); + QFETCH(bool, expectIntEqual); + + QT_TEST_EQUALITY_OPS(point1, point2, expectEqual); + + const QPoint intPoint2 = point2.toPoint(); + QT_TEST_EQUALITY_OPS(point1, intPoint2, expectIntEqual); +} + +void tst_QPointF::fuzzyCompare_data() +{ + operator_eq_data(); +} + +void tst_QPointF::fuzzyCompare() +{ + QFETCH(QPointF, point1); + QFETCH(QPointF, point2); + QFETCH(bool, expectEqual); - bool equal = point1 == point2; - QCOMPARE(equal, expectEqual); - bool notEqual = point1 != point2; - QCOMPARE(notEqual, !expectEqual); + QCOMPARE_EQ(qFuzzyCompare(point1, point2), expectEqual); } void tst_QPointF::toPoint_data() diff --git a/tests/auto/corelib/tools/qrect/CMakeLists.txt b/tests/auto/corelib/tools/qrect/CMakeLists.txt index a02e1c33a5..c98c836379 100644 --- a/tests/auto/corelib/tools/qrect/CMakeLists.txt +++ b/tests/auto/corelib/tools/qrect/CMakeLists.txt @@ -14,4 +14,6 @@ endif() qt_internal_add_test(tst_qrect SOURCES tst_qrect.cpp + LIBRARIES + Qt::TestPrivate ) diff --git a/tests/auto/corelib/tools/qrect/tst_qrect.cpp b/tests/auto/corelib/tools/qrect/tst_qrect.cpp index 0f3dd1a0ef..c7c8b3a560 100644 --- a/tests/auto/corelib/tools/qrect/tst_qrect.cpp +++ b/tests/auto/corelib/tools/qrect/tst_qrect.cpp @@ -7,6 +7,8 @@ #include <limits.h> #include <qdebug.h> +#include <private/qcomparisontesthelper_p.h> + #include <array> class tst_QRect : public QObject @@ -33,8 +35,14 @@ public: static QPoint getQPointCase( QPointCases p ); private slots: + void comparisonCompiles(); + void comparison_data(); + void comparison(); + void fuzzyComparison_data(); + void fuzzyComparison(); void isNull_data(); void isNull(); + void fuzzyIsNull(); void newIsEmpty_data(); void newIsEmpty(); void newIsValid_data(); @@ -160,6 +168,8 @@ private slots: #define LARGE 1000000000 static bool isLarge(int x) { return x > LARGE || x < -LARGE; } +static constexpr qreal qreal_min = std::numeric_limits<qreal>::min(); + QRect tst_QRect::getQRectCase( QRectCases c ) { // Should return the best variety of possible QRects, if a @@ -242,6 +252,80 @@ QPoint tst_QRect::getQPointCase( QPointCases p ) } } +void tst_QRect::comparisonCompiles() +{ + QTestPrivate::testEqualityOperatorsCompile<QRect>(); + QTestPrivate::testEqualityOperatorsCompile<QRectF>(); + QTestPrivate::testEqualityOperatorsCompile<QRectF, QRect>(); +} + +void tst_QRect::comparison_data() +{ + QTest::addColumn<QRectF>("lhsF"); + QTest::addColumn<QRectF>("rhsF"); + QTest::addColumn<bool>("result"); + QTest::addColumn<bool>("floatResult"); + QTest::addColumn<bool>("mixedResult"); + + QTest::newRow("Invalid_vs_Invalid") << getQRectCase(InvalidQRect).toRectF() + << getQRectCase(InvalidQRect).toRectF() + << true << true << true; + + QTest::newRow("Null_vs_Null") << getQRectCase(NullQRect).toRectF() + << getQRectCase(NullQRect).toRectF() + << true << true << true; + + QTest::newRow("Empty_vs_Empty") << getQRectCase(EmptyQRect).toRectF() + << getQRectCase(EmptyQRect).toRectF() + << true << true << true; + + QTest::newRow("NegativeSize_vs_NegativeSize") << getQRectCase(NegativeSizeQRect).toRectF() + << getQRectCase(NegativeSizeQRect).toRectF() + << true << true << true; + + QTest::newRow("Invalid_vs_Null") << getQRectCase(InvalidQRect).toRectF() + << getQRectCase(NullQRect).toRectF() + << false << false << false; + + QTest::newRow("NearlySimilar") << QRectF(QPointF(1.1, 9.9), QPointF(9.9, 1.1)) + << QRectF(QPointF(1., 10.), QPointF(10., 1.)) + << true << false << true; + + QTest::newRow("WithQREAL_MIN") << QRectF(QPointF(0., -10.), QPointF(-1., 0.)) + << QRectF(QPointF(-qreal_min, -10.), QPointF(-1., qreal_min)) + << true << true << true; +} + +void tst_QRect::comparison() +{ + QFETCH(const QRectF, lhsF); + QFETCH(const QRectF, rhsF); + QFETCH(const bool, result); + QFETCH(const bool, floatResult); + QFETCH(const bool, mixedResult); + + const QRect lhs = lhsF.toRect(); + const QRect rhs = rhsF.toRect(); + + QT_TEST_EQUALITY_OPS(lhs, rhs, result); + QT_TEST_EQUALITY_OPS(lhsF, rhsF, floatResult); + QT_TEST_EQUALITY_OPS(lhs, rhsF, mixedResult); +} + +void tst_QRect::fuzzyComparison_data() +{ + comparison_data(); +} + +void tst_QRect::fuzzyComparison() +{ + QFETCH(const QRectF, lhsF); + QFETCH(const QRectF, rhsF); + QFETCH(const bool, floatResult); + + QCOMPARE_EQ(qFuzzyCompare(lhsF, rhsF), floatResult); +} + void tst_QRect::isNull_data() { QTest::addColumn<QRect>("r"); @@ -271,6 +355,14 @@ void tst_QRect::isNull() QVERIFY( rf.isNull() == isNull ); } +void tst_QRect::fuzzyIsNull() +{ + QRectF rf(QPointF(-qreal_min, qreal_min), QPointF(qreal_min, -qreal_min)); + + QVERIFY(!rf.isNull()); // QRectF::isNull() does strict comparison + QVERIFY(qFuzzyIsNull(rf)); +} + void tst_QRect::newIsEmpty_data() { QTest::addColumn<QRect>("r"); diff --git a/tests/auto/corelib/tools/qsize/CMakeLists.txt b/tests/auto/corelib/tools/qsize/CMakeLists.txt index 91de696ddd..4a4c96b52c 100644 --- a/tests/auto/corelib/tools/qsize/CMakeLists.txt +++ b/tests/auto/corelib/tools/qsize/CMakeLists.txt @@ -14,4 +14,6 @@ endif() qt_internal_add_test(tst_qsize SOURCES tst_qsize.cpp + LIBRARIES + Qt::TestPrivate ) diff --git a/tests/auto/corelib/tools/qsize/tst_qsize.cpp b/tests/auto/corelib/tools/qsize/tst_qsize.cpp index c9699c5e76..d379275dd8 100644 --- a/tests/auto/corelib/tools/qsize/tst_qsize.cpp +++ b/tests/auto/corelib/tools/qsize/tst_qsize.cpp @@ -24,6 +24,7 @@ CHECK(const &&); #undef CHECK #include <QTest> +#include <QtTest/private/qcomparisontesthelper_p.h> #include <qsize.h> #include <array> @@ -34,6 +35,10 @@ class tst_QSize : public QObject { Q_OBJECT private slots: + void compareCompiles(); + void compare_data(); + void compare(); + void getSetCheck(); void scale(); @@ -55,6 +60,38 @@ private slots: void structuredBinding(); }; +void tst_QSize::compareCompiles() +{ + QTestPrivate::testEqualityOperatorsCompile<QSize>(); +} + +void tst_QSize::compare_data() +{ + QTest::addColumn<QSize>("lhs"); + QTest::addColumn<QSize>("rhs"); + QTest::addColumn<bool>("result"); + + auto row = [](QSize lhs, QSize rhs, bool res) { + QTest::addRow("(%d, %d) vs (%d, %d)", lhs.width(), lhs.height(), rhs.width(), rhs.height()) + << lhs << rhs << res; + }; + + row(QSize(0, 0), QSize(0, 0), true); + row(QSize(1, 0), QSize(0, 1), false); + row(QSize(-1, -1), QSize(-1, -1), true); + row(QSize(-1, -1), QSize(1, 1), false); + row(QSize(INT_MIN, INT_MAX), QSize(INT_MAX, INT_MIN), false); +} + +void tst_QSize::compare() +{ + QFETCH(QSize, lhs); + QFETCH(QSize, rhs); + QFETCH(bool, result); + + QT_TEST_EQUALITY_OPS(lhs, rhs, result); +} + // Testing get/set functions void tst_QSize::getSetCheck() { diff --git a/tests/auto/corelib/tools/qsizef/CMakeLists.txt b/tests/auto/corelib/tools/qsizef/CMakeLists.txt index 9adaafe2ea..d8a1c7f46e 100644 --- a/tests/auto/corelib/tools/qsizef/CMakeLists.txt +++ b/tests/auto/corelib/tools/qsizef/CMakeLists.txt @@ -14,4 +14,6 @@ endif() qt_internal_add_test(tst_qsizef SOURCES tst_qsizef.cpp + LIBRARIES + Qt::TestPrivate ) diff --git a/tests/auto/corelib/tools/qsizef/tst_qsizef.cpp b/tests/auto/corelib/tools/qsizef/tst_qsizef.cpp index ee33fa13b6..bb087e89de 100644 --- a/tests/auto/corelib/tools/qsizef/tst_qsizef.cpp +++ b/tests/auto/corelib/tools/qsizef/tst_qsizef.cpp @@ -24,17 +24,30 @@ CHECK(const &&); #undef CHECK #include <QTest> +#include <QtTest/private/qcomparisontesthelper_p.h> #include <qsize.h> Q_DECLARE_METATYPE(QMarginsF) +static constexpr qreal qreal_min = std::numeric_limits<qreal>::min(); + class tst_QSizeF : public QObject { Q_OBJECT private slots: + void compareCompiles(); + void compare_data(); + void compare(); + + void fuzzyCompare_data(); + void fuzzyCompare(); + void isNull_data(); void isNull(); + void fuzzyIsNull_data(); + void fuzzyIsNull(); + void scale(); void expandedTo(); @@ -52,6 +65,61 @@ private slots: void structuredBinding(); }; +void tst_QSizeF::compareCompiles() +{ + QTestPrivate::testEqualityOperatorsCompile<QSizeF>(); + QTestPrivate::testEqualityOperatorsCompile<QSizeF, QSize>(); +} + +void tst_QSizeF::compare_data() +{ + QTest::addColumn<QSizeF>("lhs"); + QTest::addColumn<QSizeF>("rhs"); + QTest::addColumn<bool>("result"); + QTest::addColumn<bool>("mixedResult"); + + auto row = [&](QSizeF lhs, QSizeF rhs, bool res, bool mixedRes) { + QString str; + QDebug dbg(&str); + dbg.nospace() << "(" << lhs.width() << ", " << lhs.height() << ") vs " + << "(" << rhs.width() << ", " << rhs.height() << ")"; + QTest::addRow("%s", str.toLatin1().constData()) << lhs << rhs << res << mixedRes; + }; + + row(QSizeF(0.0, 0.0), QSizeF(0.0, 0.0), true, true); + row(QSizeF(1.0, 2.0), QSizeF(1.0, 2.0), true, true); + row(QSizeF(1.0, -1.0), QSizeF(-1.0, 1.0), false, false); + row(QSizeF(0.1, 1.1), QSizeF(0.1, 1.1), true, false); + row(QSizeF(qreal_min, 0.0), QSizeF(0.0, -qreal_min), true, true); +} + +void tst_QSizeF::compare() +{ + QFETCH(QSizeF, lhs); + QFETCH(QSizeF, rhs); + QFETCH(bool, result); + QFETCH(bool, mixedResult); + + QT_TEST_EQUALITY_OPS(lhs, rhs, result); + + const QSize rhsFixed = rhs.toSize(); + QT_TEST_EQUALITY_OPS(lhs, rhsFixed, mixedResult); +} + +void tst_QSizeF::fuzzyCompare_data() +{ + compare_data(); +} + +void tst_QSizeF::fuzzyCompare() +{ + QFETCH(QSizeF, lhs); + QFETCH(QSizeF, rhs); + QFETCH(bool, result); + + QCOMPARE_EQ(qFuzzyCompare(lhs, rhs), result); +} + void tst_QSizeF::isNull_data() { QTest::addColumn<qreal>("width"); @@ -66,6 +134,7 @@ void tst_QSizeF::isNull_data() QTest::newRow("0, -0.1") << qreal(0) << qreal(-0.1) << false; QTest::newRow("0.1, 0") << qreal(0.1) << qreal(0) << false; QTest::newRow("0, 0.1") << qreal(0) << qreal(0.1) << false; + QTest::newRow("qreal_min, -qreal_min") << qreal_min << -qreal_min << false; } void tst_QSizeF::isNull() @@ -80,6 +149,33 @@ void tst_QSizeF::isNull() QCOMPARE(size.isNull(), isNull); } +void tst_QSizeF::fuzzyIsNull_data() +{ + QTest::addColumn<qreal>("width"); + QTest::addColumn<qreal>("height"); + QTest::addColumn<bool>("fuzzyNull"); + + QTest::newRow("0, 0") << qreal(0.0) << qreal(0.0) << true; + QTest::newRow("-0, -0") << qreal(-0.0) << qreal(-0.0) << true; + QTest::newRow("0, -0") << qreal(0) << qreal(-0.0) << true; + QTest::newRow("-0, 0") << qreal(-0.0) << qreal(0) << true; + QTest::newRow("-0.1, 0") << qreal(-0.1) << qreal(0) << false; + QTest::newRow("0, -0.1") << qreal(0) << qreal(-0.1) << false; + QTest::newRow("0.1, 0") << qreal(0.1) << qreal(0) << false; + QTest::newRow("0, 0.1") << qreal(0) << qreal(0.1) << false; + QTest::newRow("qreal_min, -qreal_min") << qreal_min << -qreal_min << true; +} + +void tst_QSizeF::fuzzyIsNull() +{ + QFETCH(qreal, width); + QFETCH(qreal, height); + QFETCH(bool, fuzzyNull); + + QSizeF size(width, height); + QCOMPARE(qFuzzyIsNull(size), fuzzyNull); +} + void tst_QSizeF::scale() { QSizeF t1(10.4, 12.8); t1.scale(60.6, 60.6, Qt::IgnoreAspectRatio); diff --git a/tests/auto/corelib/tools/qspan/tst_qspan.cpp b/tests/auto/corelib/tools/qspan/tst_qspan.cpp index 91d2ecf739..c7456ac7f2 100644 --- a/tests/auto/corelib/tools/qspan/tst_qspan.cpp +++ b/tests/auto/corelib/tools/qspan/tst_qspan.cpp @@ -141,6 +141,9 @@ private: void from_variable_size_container_impl(C &&c) const; }; +template <typename T> +const void *as_const_void(T *p) noexcept { return static_cast<const void *>(p); } + #define RETURN_IF_FAILED() \ do { if (QTest::currentTestFailed()) return; } while (false) @@ -149,7 +152,7 @@ void tst_QSpan::onlyZeroExtentSpansHaveDefaultCtors() const static_assert(std::is_nothrow_default_constructible_v<QSpan<int, 0>>); static_assert(std::is_nothrow_default_constructible_v<QSpan<const int, 0>>); static_assert(std::is_nothrow_default_constructible_v<QSpan<int>>); - static_assert(std::is_nothrow_default_constructible_v<QSpan<const int, 0>>); + static_assert(std::is_nothrow_default_constructible_v<QSpan<const int>>); QSpan<int, 0> si; check_null_span(si); @@ -173,7 +176,7 @@ void tst_QSpan::onlyZeroExtentSpansHaveDefaultCtors() const void tst_QSpan::zeroExtentSpansMaintainADataPointer() const { - int i; + int i = 0; QSpan<int, 0> si{&i, 0}; QCOMPARE(si.data(), &i); check_empty_span_incl_subspans(si); @@ -334,6 +337,8 @@ void tst_QSpan::from_container_impl(C &&c) const const auto c_data = QSpanPrivate::adl_data(c); using V = std::remove_reference_t<QSpanPrivate::range_reference_t<C>>; + constexpr auto ExpectedBytesExtent + = ExpectedExtent == q20::dynamic_extent ? q20::dynamic_extent : ExpectedExtent * sizeof(V); { QSpan si = c; // CTAD static_assert(std::is_same_v<decltype(si), QSpan<V, ExpectedExtent>>); @@ -344,6 +349,20 @@ void tst_QSpan::from_container_impl(C &&c) const check_nonempty_span(si, c_size); RETURN_IF_FAILED(); + auto bi = as_bytes(si); + static_assert(std::is_same_v<decltype(bi), QSpan<const std::byte, ExpectedBytesExtent>>); + QCOMPARE_EQ(bi.size(), si.size_bytes()); + QCOMPARE_EQ(as_const_void(bi.data()), + as_const_void(si.data())); + + if constexpr (!std::is_const_v<V>) { // e.g. std::initializer_list<int> + auto wbi = as_writable_bytes(si); + static_assert(std::is_same_v<decltype(wbi), QSpan<std::byte, ExpectedBytesExtent>>); + QCOMPARE_EQ(wbi.size(), si.size_bytes()); + QCOMPARE_EQ(as_const_void(wbi.data()), + as_const_void(si.data())); + } + QSpan<const int> sci = c; QCOMPARE_EQ(sci.size(), c_size); @@ -351,6 +370,12 @@ void tst_QSpan::from_container_impl(C &&c) const check_nonempty_span(sci, c_size); RETURN_IF_FAILED(); + + auto bci = as_bytes(sci); + static_assert(std::is_same_v<decltype(bci), QSpan<const std::byte>>); + QCOMPARE_EQ(bci.size(), sci.size_bytes()); + QCOMPARE_EQ(as_const_void(bci.data()), + as_const_void(sci.data())); } { QSpan sci = std::as_const(c); // CTAD @@ -361,6 +386,12 @@ void tst_QSpan::from_container_impl(C &&c) const check_nonempty_span(sci, c_size); RETURN_IF_FAILED(); + + auto bci = as_bytes(sci); + static_assert(std::is_same_v<decltype(bci), QSpan<const std::byte, ExpectedBytesExtent>>); + QCOMPARE_EQ(bci.size(), sci.size_bytes()); + QCOMPARE_EQ(as_const_void(bci.data()), + as_const_void(sci.data())); } } diff --git a/tests/auto/corelib/tools/quniquehandle/tst_quniquehandle.cpp b/tests/auto/corelib/tools/quniquehandle/tst_quniquehandle.cpp index 4ec60e166a..ed46999e73 100644 --- a/tests/auto/corelib/tools/quniquehandle/tst_quniquehandle.cpp +++ b/tests/auto/corelib/tools/quniquehandle/tst_quniquehandle.cpp @@ -248,7 +248,7 @@ private slots: { using Type = int; - static bool close(Type handle) + static bool close(Type) { return true; } diff --git a/tests/auto/corelib/tools/qversionnumber/CMakeLists.txt b/tests/auto/corelib/tools/qversionnumber/CMakeLists.txt index 8f6ed66841..5b9fa60c64 100644 --- a/tests/auto/corelib/tools/qversionnumber/CMakeLists.txt +++ b/tests/auto/corelib/tools/qversionnumber/CMakeLists.txt @@ -14,6 +14,8 @@ endif() qt_internal_add_test(tst_qversionnumber SOURCES tst_qversionnumber.cpp + LIBRARIES + Qt::TestPrivate ) ## Scopes: diff --git a/tests/auto/corelib/tools/qversionnumber/tst_qversionnumber.cpp b/tests/auto/corelib/tools/qversionnumber/tst_qversionnumber.cpp index da9dcc9366..5ccf56c1d1 100644 --- a/tests/auto/corelib/tools/qversionnumber/tst_qversionnumber.cpp +++ b/tests/auto/corelib/tools/qversionnumber/tst_qversionnumber.cpp @@ -3,6 +3,7 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QTest> +#include <QtTest/private/qcomparisontesthelper_p.h> #include <QtCore/qversionnumber.h> #include <QtCore/qlibraryinfo.h> @@ -16,24 +17,15 @@ private: private slots: void initTestCase(); + void compareCompiles(); void constructorDefault(); void constructorVersioned_data(); void constructorVersioned(); void constructorExplicit(); void constructorCopy_data(); void constructorCopy(); - void compareGreater_data(); - void compareGreater(); - void compareGreaterEqual_data(); - void compareGreaterEqual(); - void compareLess_data(); - void compareLess(); - void compareLessEqual_data(); - void compareLessEqual(); - void compareEqual_data(); - void compareEqual(); - void compareNotEqual_data(); - void compareNotEqual(); + void comparisonOperators_data(); + void comparisonOperators(); void compare_data(); void compare(); void isPrefixOf_data(); @@ -121,74 +113,69 @@ void tst_QVersionNumber::comparisonData() { QTest::addColumn<QVersionNumber>("lhs"); QTest::addColumn<QVersionNumber>("rhs"); - QTest::addColumn<bool>("equal"); - QTest::addColumn<bool>("notEqual"); - QTest::addColumn<bool>("lessThan"); - QTest::addColumn<bool>("lessThanOrEqual"); - QTest::addColumn<bool>("greaterThan"); - QTest::addColumn<bool>("greaterThanOrEqual"); + QTest::addColumn<Qt::strong_ordering>("ordering"); QTest::addColumn<int>("compareResult"); QTest::addColumn<bool>("isPrefix"); QTest::addColumn<QVersionNumber>("common"); - // LHS RHS == != < <= > >= compareResult isPrefixOf commonPrefix - QTest::newRow("null, null") << QVersionNumber() << QVersionNumber() << true << false << false << true << false << true << 0 << true << QVersionNumber(); - QTest::newRow("null, 0") << QVersionNumber() << QVersionNumber(0) << false << true << true << true << false << false << -1 << true << QVersionNumber(); - QTest::newRow("0, null") << QVersionNumber(0) << QVersionNumber() << false << true << false << false << true << true << 1 << false << QVersionNumber(); - QTest::newRow("0, 0") << QVersionNumber(0) << QVersionNumber(0) << true << false << false << true << false << true << 0 << true << QVersionNumber(0); - QTest::newRow("1.0, 1.0") << QVersionNumber(1, 0) << QVersionNumber(1, 0) << true << false << false << true << false << true << 0 << true << QVersionNumber(1, 0); - QTest::newRow("1, 1.0") << QVersionNumber(1) << QVersionNumber(1, 0) << false << true << true << true << false << false << -1 << true << QVersionNumber(1); - QTest::newRow("1.0, 1") << QVersionNumber(1, 0) << QVersionNumber(1) << false << true << false << false << true << true << 1 << false << QVersionNumber(1); - - QTest::newRow("0.1.2, 0.1") << QVersionNumber(0, 1, 2) << QVersionNumber(0, 1) << false << true << false << false << true << true << 2 << false << QVersionNumber(0, 1); - QTest::newRow("0.1, 0.1.2") << QVersionNumber(0, 1) << QVersionNumber(0, 1, 2) << false << true << true << true << false << false << -2 << true << QVersionNumber(0, 1); - QTest::newRow("0.1.2, 0.1.2") << QVersionNumber(0, 1, 2) << QVersionNumber(0, 1, 2) << true << false << false << true << false << true << 0 << true << QVersionNumber(0, 1, 2); - QTest::newRow("0.1.2, 1.1.2") << QVersionNumber(0, 1, 2) << QVersionNumber(1, 1, 2) << false << true << true << true << false << false << -1 << false << QVersionNumber(); - QTest::newRow("1.1.2, 0.1.2") << QVersionNumber(1, 1, 2) << QVersionNumber(0, 1, 2) << false << true << false << false << true << true << 1 << false << QVersionNumber(); - QTest::newRow("1, -1") << QVersionNumber(1) << QVersionNumber(-1) << false << true << false << false << true << true << 2 << false << QVersionNumber(); - QTest::newRow("-1, 1") << QVersionNumber(-1) << QVersionNumber(1) << false << true << true << true << false << false << -2 << false << QVersionNumber(); - QTest::newRow("0.1, 0.-1") << QVersionNumber(0, 1) << QVersionNumber(0, -1) << false << true << false << false << true << true << 2 << false << QVersionNumber(0); - QTest::newRow("0.-1, 0.1") << QVersionNumber(0, -1) << QVersionNumber(0, 1) << false << true << true << true << false << false << -2 << false << QVersionNumber(0); - QTest::newRow("0.-1, 0") << QVersionNumber(0, -1) << QVersionNumber(0) << false << true << true << true << false << false << -1 << false << QVersionNumber(0); - QTest::newRow("0, 0.-1") << QVersionNumber(0) << QVersionNumber(0, -1) << false << true << false << false << true << true << 1 << true << QVersionNumber(0); - - QTest::newRow("0.127.2, 0.127") << QVersionNumber(0, 127, 2) << QVersionNumber(0, 127) << false << true << false << false << true << true << 2 << false << QVersionNumber(0, 127); - QTest::newRow("0.127, 0.127.2") << QVersionNumber(0, 127) << QVersionNumber(0, 127, 2) << false << true << true << true << false << false << -2 << true << QVersionNumber(0, 127); - QTest::newRow("0.127.2, 0.127.2") << QVersionNumber(0, 127, 2) << QVersionNumber(0, 127, 2) << true << false << false << true << false << true << 0 << true << QVersionNumber(0, 127, 2); - QTest::newRow("0.127.2, 127.127.2") << QVersionNumber(0, 127, 2) << QVersionNumber(127, 127, 2) << false << true << true << true << false << false << -127 << false << QVersionNumber(); - QTest::newRow("127.127.2, 0.127.2") << QVersionNumber(127, 127, 2) << QVersionNumber(0, 127, 2) << false << true << false << false << true << true << 127 << false << QVersionNumber(); - QTest::newRow("127, -128") << QVersionNumber(127) << QVersionNumber(-128) << false << true << false << false << true << true << 255 << false << QVersionNumber(); - QTest::newRow("-128, 127") << QVersionNumber(-128) << QVersionNumber(127) << false << true << true << true << false << false << -255 << false << QVersionNumber(); - QTest::newRow("0.127, 0.-128") << QVersionNumber(0, 127) << QVersionNumber(0, -128) << false << true << false << false << true << true << 255 << false << QVersionNumber(0); - QTest::newRow("0.-128, 0.127") << QVersionNumber(0, -128) << QVersionNumber(0, 127) << false << true << true << true << false << false << -255 << false << QVersionNumber(0); - QTest::newRow("0.-128, 0") << QVersionNumber(0, -128) << QVersionNumber(0) << false << true << true << true << false << false << -128 << false << QVersionNumber(0); - QTest::newRow("0, 0.-128") << QVersionNumber(0) << QVersionNumber(0, -128) << false << true << false << false << true << true << 128 << true << QVersionNumber(0); - - QTest::newRow("0.128.2, 0.128") << QVersionNumber(0, 128, 2) << QVersionNumber(0, 128) << false << true << false << false << true << true << 2 << false << QVersionNumber(0, 128); - QTest::newRow("0.128, 0.128.2") << QVersionNumber(0, 128) << QVersionNumber(0, 128, 2) << false << true << true << true << false << false << -2 << true << QVersionNumber(0, 128); - QTest::newRow("0.128.2, 0.128.2") << QVersionNumber(0, 128, 2) << QVersionNumber(0, 128, 2) << true << false << false << true << false << true << 0 << true << QVersionNumber(0, 128, 2); - QTest::newRow("0.128.2, 128.128.2") << QVersionNumber(0, 128, 2) << QVersionNumber(128, 128, 2) << false << true << true << true << false << false << -128 << false << QVersionNumber(); - QTest::newRow("128.128.2, 0.128.2") << QVersionNumber(128, 128, 2) << QVersionNumber(0, 128, 2) << false << true << false << false << true << true << 128 << false << QVersionNumber(); - QTest::newRow("128, -129") << QVersionNumber(128) << QVersionNumber(-129) << false << true << false << false << true << true << 257 << false << QVersionNumber(); - QTest::newRow("-129, 128") << QVersionNumber(-129) << QVersionNumber(128) << false << true << true << true << false << false << -257 << false << QVersionNumber(); - QTest::newRow("0.128, 0.-129") << QVersionNumber(0, 128) << QVersionNumber(0, -129) << false << true << false << false << true << true << 257 << false << QVersionNumber(0); - QTest::newRow("0.-129, 0.128") << QVersionNumber(0, -129) << QVersionNumber(0, 128) << false << true << true << true << false << false << -257 << false << QVersionNumber(0); - QTest::newRow("0.-129, 0") << QVersionNumber(0, -129) << QVersionNumber(0) << false << true << true << true << false << false << -129 << false << QVersionNumber(0); - QTest::newRow("0, 0.-129") << QVersionNumber(0) << QVersionNumber(0, -129) << false << true << false << false << true << true << 129 << true << QVersionNumber(0); + // LHS RHS ordering compareResult isPrefixOf commonPrefix + QTest::newRow("null, null") << QVersionNumber() << QVersionNumber() << Qt::strong_ordering::equal << 0 << true << QVersionNumber(); + QTest::newRow("null, 0") << QVersionNumber() << QVersionNumber(0) << Qt::strong_ordering::less << -1 << true << QVersionNumber(); + QTest::newRow("0, null") << QVersionNumber(0) << QVersionNumber() << Qt::strong_ordering::greater << 1 << false << QVersionNumber(); + QTest::newRow("0, 0") << QVersionNumber(0) << QVersionNumber(0) << Qt::strong_ordering::equal << 0 << true << QVersionNumber(0); + QTest::newRow("1.0, 1.0") << QVersionNumber(1, 0) << QVersionNumber(1, 0) << Qt::strong_ordering::equal << 0 << true << QVersionNumber(1, 0); + QTest::newRow("1, 1.0") << QVersionNumber(1) << QVersionNumber(1, 0) << Qt::strong_ordering::less << -1 << true << QVersionNumber(1); + QTest::newRow("1.0, 1") << QVersionNumber(1, 0) << QVersionNumber(1) << Qt::strong_ordering::greater << 1 << false << QVersionNumber(1); + + QTest::newRow("0.1.2, 0.1") << QVersionNumber(0, 1, 2) << QVersionNumber(0, 1) << Qt::strong_ordering::greater << 2 << false << QVersionNumber(0, 1); + QTest::newRow("0.1, 0.1.2") << QVersionNumber(0, 1) << QVersionNumber(0, 1, 2) << Qt::strong_ordering::less << -2 << true << QVersionNumber(0, 1); + QTest::newRow("0.1.2, 0.1.2") << QVersionNumber(0, 1, 2) << QVersionNumber(0, 1, 2) << Qt::strong_ordering::equal << 0 << true << QVersionNumber(0, 1, 2); + QTest::newRow("0.1.2, 1.1.2") << QVersionNumber(0, 1, 2) << QVersionNumber(1, 1, 2) << Qt::strong_ordering::less << -1 << false << QVersionNumber(); + QTest::newRow("1.1.2, 0.1.2") << QVersionNumber(1, 1, 2) << QVersionNumber(0, 1, 2) << Qt::strong_ordering::greater << 1 << false << QVersionNumber(); + QTest::newRow("1, -1") << QVersionNumber(1) << QVersionNumber(-1) << Qt::strong_ordering::greater << 2 << false << QVersionNumber(); + QTest::newRow("-1, 1") << QVersionNumber(-1) << QVersionNumber(1) << Qt::strong_ordering::less << -2 << false << QVersionNumber(); + QTest::newRow("0.1, 0.-1") << QVersionNumber(0, 1) << QVersionNumber(0, -1) << Qt::strong_ordering::greater << 2 << false << QVersionNumber(0); + QTest::newRow("0.-1, 0.1") << QVersionNumber(0, -1) << QVersionNumber(0, 1) << Qt::strong_ordering::less << -2 << false << QVersionNumber(0); + QTest::newRow("0.-1, 0") << QVersionNumber(0, -1) << QVersionNumber(0) << Qt::strong_ordering::less << -1 << false << QVersionNumber(0); + QTest::newRow("0, 0.-1") << QVersionNumber(0) << QVersionNumber(0, -1) << Qt::strong_ordering::greater << 1 << true << QVersionNumber(0); + + QTest::newRow("0.127.2, 0.127") << QVersionNumber(0, 127, 2) << QVersionNumber(0, 127) << Qt::strong_ordering::greater << 2 << false << QVersionNumber(0, 127); + QTest::newRow("0.127, 0.127.2") << QVersionNumber(0, 127) << QVersionNumber(0, 127, 2) << Qt::strong_ordering::less << -2 << true << QVersionNumber(0, 127); + QTest::newRow("0.127.2, 0.127.2") << QVersionNumber(0, 127, 2) << QVersionNumber(0, 127, 2) << Qt::strong_ordering::equal << 0 << true << QVersionNumber(0, 127, 2); + QTest::newRow("0.127.2, 127.127.2") << QVersionNumber(0, 127, 2) << QVersionNumber(127, 127, 2) << Qt::strong_ordering::less << -127 << false << QVersionNumber(); + QTest::newRow("127.127.2, 0.127.2") << QVersionNumber(127, 127, 2) << QVersionNumber(0, 127, 2) << Qt::strong_ordering::greater << 127 << false << QVersionNumber(); + QTest::newRow("127, -128") << QVersionNumber(127) << QVersionNumber(-128) << Qt::strong_ordering::greater << 255 << false << QVersionNumber(); + QTest::newRow("-128, 127") << QVersionNumber(-128) << QVersionNumber(127) << Qt::strong_ordering::less << -255 << false << QVersionNumber(); + QTest::newRow("0.127, 0.-128") << QVersionNumber(0, 127) << QVersionNumber(0, -128) << Qt::strong_ordering::greater << 255 << false << QVersionNumber(0); + QTest::newRow("0.-128, 0.127") << QVersionNumber(0, -128) << QVersionNumber(0, 127) << Qt::strong_ordering::less << -255 << false << QVersionNumber(0); + QTest::newRow("0.-128, 0") << QVersionNumber(0, -128) << QVersionNumber(0) << Qt::strong_ordering::less << -128 << false << QVersionNumber(0); + QTest::newRow("0, 0.-128") << QVersionNumber(0) << QVersionNumber(0, -128) << Qt::strong_ordering::greater << 128 << true << QVersionNumber(0); + + QTest::newRow("0.128.2, 0.128") << QVersionNumber(0, 128, 2) << QVersionNumber(0, 128) << Qt::strong_ordering::greater << 2 << false << QVersionNumber(0, 128); + QTest::newRow("0.128, 0.128.2") << QVersionNumber(0, 128) << QVersionNumber(0, 128, 2) << Qt::strong_ordering::less << -2 << true << QVersionNumber(0, 128); + QTest::newRow("0.128.2, 0.128.2") << QVersionNumber(0, 128, 2) << QVersionNumber(0, 128, 2) << Qt::strong_ordering::equal << 0 << true << QVersionNumber(0, 128, 2); + QTest::newRow("0.128.2, 128.128.2") << QVersionNumber(0, 128, 2) << QVersionNumber(128, 128, 2) << Qt::strong_ordering::less << -128 << false << QVersionNumber(); + QTest::newRow("128.128.2, 0.128.2") << QVersionNumber(128, 128, 2) << QVersionNumber(0, 128, 2) << Qt::strong_ordering::greater << 128 << false << QVersionNumber(); + QTest::newRow("128, -129") << QVersionNumber(128) << QVersionNumber(-129) << Qt::strong_ordering::greater << 257 << false << QVersionNumber(); + QTest::newRow("-129, 128") << QVersionNumber(-129) << QVersionNumber(128) << Qt::strong_ordering::less << -257 << false << QVersionNumber(); + QTest::newRow("0.128, 0.-129") << QVersionNumber(0, 128) << QVersionNumber(0, -129) << Qt::strong_ordering::greater << 257 << false << QVersionNumber(0); + QTest::newRow("0.-129, 0.128") << QVersionNumber(0, -129) << QVersionNumber(0, 128) << Qt::strong_ordering::less << -257 << false << QVersionNumber(0); + QTest::newRow("0.-129, 0") << QVersionNumber(0, -129) << QVersionNumber(0) << Qt::strong_ordering::less << -129 << false << QVersionNumber(0); + QTest::newRow("0, 0.-129") << QVersionNumber(0) << QVersionNumber(0, -129) << Qt::strong_ordering::greater << 129 << true << QVersionNumber(0); const QList<int> common = QList<int>({ 0, 1, 2, 3, 4, 5, 6 }); using namespace UglyOperator; - QTest::newRow("0.1.2.3.4.5.6.0.1.2, 0.1.2.3.4.5.6.0.1") << QVersionNumber(common + 0 + 1 + 2) << QVersionNumber(common + 0 + 1) << false << true << false << false << true << true << 2 << false << QVersionNumber(common + 0 + 1); - QTest::newRow("0.1.2.3.4.5.6.0.1, 0.1.2.3.4.5.6.0.1.2") << QVersionNumber(common + 0 + 1) << QVersionNumber(common + 0 + 1 + 2) << false << true << true << true << false << false << -2 << true << QVersionNumber(common + 0 + 1); - QTest::newRow("0.1.2.3.4.5.6.0.1.2, 0.1.2.3.4.5.6.0.1.2") << QVersionNumber(common + 0 + 1 + 2) << QVersionNumber(common + 0 + 1 + 2) << true << false << false << true << false << true << 0 << true << QVersionNumber(common + 0 + 1 + 2); - QTest::newRow("0.1.2.3.4.5.6.0.1.2, 0.1.2.3.4.5.6.1.1.2") << QVersionNumber(common + 0 + 1 + 2) << QVersionNumber(common + 1 + 1 + 2) << false << true << true << true << false << false << -1 << false << QVersionNumber(common); - QTest::newRow("0.1.2.3.4.5.6.1.1.2, 0.1.2.3.4.5.6.0.1.2") << QVersionNumber(common + 1 + 1 + 2) << QVersionNumber(common + 0 + 1 + 2) << false << true << false << false << true << true << 1 << false << QVersionNumber(common); - QTest::newRow("0.1.2.3.4.5.6.1, 0.1.2.3.4.5.6.-1") << QVersionNumber(common + 1) << QVersionNumber(common + -1) << false << true << false << false << true << true << 2 << false << QVersionNumber(common); - QTest::newRow("0.1.2.3.4.5.6.-1, 0.1.2.3.4.5.6.1") << QVersionNumber(common + -1) << QVersionNumber(common + 1) << false << true << true << true << false << false << -2 << false << QVersionNumber(common); - QTest::newRow("0.1.2.3.4.5.6.0.1, 0.1.2.3.4.5.6.0.-1") << QVersionNumber(common + 0 + 1) << QVersionNumber(common + 0 + -1) << false << true << false << false << true << true << 2 << false << QVersionNumber(common + 0); - QTest::newRow("0.1.2.3.4.5.6.0.-1, 0.1.2.3.4.5.6.0.1") << QVersionNumber(common + 0 + -1) << QVersionNumber(common + 0 + 1) << false << true << true << true << false << false << -2 << false << QVersionNumber(common + 0); - QTest::newRow("0.1.2.3.4.5.6.0.-1, 0.1.2.3.4.5.6.0") << QVersionNumber(common + 0 + -1) << QVersionNumber(common + 0) << false << true << true << true << false << false << -1 << false << QVersionNumber(common + 0); - QTest::newRow("0.1.2.3.4.5.6.0, 0.1.2.3.4.5.6.0.-1") << QVersionNumber(common + 0) << QVersionNumber(common + 0 + -1) << false << true << false << false << true << true << 1 << true << QVersionNumber(common + 0); + QTest::newRow("0.1.2.3.4.5.6.0.1.2, 0.1.2.3.4.5.6.0.1") << QVersionNumber(common + 0 + 1 + 2) << QVersionNumber(common + 0 + 1) << Qt::strong_ordering::greater << 2 << false << QVersionNumber(common + 0 + 1); + QTest::newRow("0.1.2.3.4.5.6.0.1, 0.1.2.3.4.5.6.0.1.2") << QVersionNumber(common + 0 + 1) << QVersionNumber(common + 0 + 1 + 2) << Qt::strong_ordering::less << -2 << true << QVersionNumber(common + 0 + 1); + QTest::newRow("0.1.2.3.4.5.6.0.1.2, 0.1.2.3.4.5.6.0.1.2") << QVersionNumber(common + 0 + 1 + 2) << QVersionNumber(common + 0 + 1 + 2) << Qt::strong_ordering::equal << 0 << true << QVersionNumber(common + 0 + 1 + 2); + QTest::newRow("0.1.2.3.4.5.6.0.1.2, 0.1.2.3.4.5.6.1.1.2") << QVersionNumber(common + 0 + 1 + 2) << QVersionNumber(common + 1 + 1 + 2) << Qt::strong_ordering::less << -1 << false << QVersionNumber(common); + QTest::newRow("0.1.2.3.4.5.6.1.1.2, 0.1.2.3.4.5.6.0.1.2") << QVersionNumber(common + 1 + 1 + 2) << QVersionNumber(common + 0 + 1 + 2) << Qt::strong_ordering::greater << 1 << false << QVersionNumber(common); + QTest::newRow("0.1.2.3.4.5.6.1, 0.1.2.3.4.5.6.-1") << QVersionNumber(common + 1) << QVersionNumber(common + -1) << Qt::strong_ordering::greater << 2 << false << QVersionNumber(common); + QTest::newRow("0.1.2.3.4.5.6.-1, 0.1.2.3.4.5.6.1") << QVersionNumber(common + -1) << QVersionNumber(common + 1) << Qt::strong_ordering::less << -2 << false << QVersionNumber(common); + QTest::newRow("0.1.2.3.4.5.6.0.1, 0.1.2.3.4.5.6.0.-1") << QVersionNumber(common + 0 + 1) << QVersionNumber(common + 0 + -1) << Qt::strong_ordering::greater << 2 << false << QVersionNumber(common + 0); + QTest::newRow("0.1.2.3.4.5.6.0.-1, 0.1.2.3.4.5.6.0.1") << QVersionNumber(common + 0 + -1) << QVersionNumber(common + 0 + 1) << Qt::strong_ordering::less << -2 << false << QVersionNumber(common + 0); + QTest::newRow("0.1.2.3.4.5.6.0.-1, 0.1.2.3.4.5.6.0") << QVersionNumber(common + 0 + -1) << QVersionNumber(common + 0) << Qt::strong_ordering::less << -1 << false << QVersionNumber(common + 0); + QTest::newRow("0.1.2.3.4.5.6.0, 0.1.2.3.4.5.6.0.-1") << QVersionNumber(common + 0) << QVersionNumber(common + 0 + -1) << Qt::strong_ordering::greater << 1 << true << QVersionNumber(common + 0); } void tst_QVersionNumber::initTestCase() @@ -196,6 +183,11 @@ void tst_QVersionNumber::initTestCase() qRegisterMetaType<QList<int>>(); } +void tst_QVersionNumber::compareCompiles() +{ + QTestPrivate::testAllComparisonOperatorsCompile<QVersionNumber>(); +} + void tst_QVersionNumber::constructorDefault() { QVersionNumber version; @@ -270,88 +262,18 @@ void tst_QVersionNumber::constructorCopy() QCOMPARE(version.segments(), expectedVersion.segments()); } -void tst_QVersionNumber::compareGreater_data() -{ - comparisonData(); -} - -void tst_QVersionNumber::compareGreater() -{ - QFETCH(QVersionNumber, lhs); - QFETCH(QVersionNumber, rhs); - QFETCH(bool, greaterThan); - - QCOMPARE(lhs > rhs, greaterThan); -} - -void tst_QVersionNumber::compareGreaterEqual_data() -{ - comparisonData(); -} - -void tst_QVersionNumber::compareGreaterEqual() -{ - QFETCH(QVersionNumber, lhs); - QFETCH(QVersionNumber, rhs); - QFETCH(bool, greaterThanOrEqual); - - QCOMPARE(lhs >= rhs, greaterThanOrEqual); -} - -void tst_QVersionNumber::compareLess_data() -{ - comparisonData(); -} - -void tst_QVersionNumber::compareLess() -{ - QFETCH(QVersionNumber, lhs); - QFETCH(QVersionNumber, rhs); - QFETCH(bool, lessThan); - - QCOMPARE(lhs < rhs, lessThan); -} - -void tst_QVersionNumber::compareLessEqual_data() -{ - comparisonData(); -} - -void tst_QVersionNumber::compareLessEqual() -{ - QFETCH(QVersionNumber, lhs); - QFETCH(QVersionNumber, rhs); - QFETCH(bool, lessThanOrEqual); - - QCOMPARE(lhs <= rhs, lessThanOrEqual); -} - -void tst_QVersionNumber::compareEqual_data() -{ - comparisonData(); -} - -void tst_QVersionNumber::compareEqual() -{ - QFETCH(QVersionNumber, lhs); - QFETCH(QVersionNumber, rhs); - QFETCH(bool, equal); - - QCOMPARE(lhs == rhs, equal); -} - -void tst_QVersionNumber::compareNotEqual_data() +void tst_QVersionNumber::comparisonOperators_data() { comparisonData(); } -void tst_QVersionNumber::compareNotEqual() +void tst_QVersionNumber::comparisonOperators() { QFETCH(QVersionNumber, lhs); QFETCH(QVersionNumber, rhs); - QFETCH(bool, notEqual); + QFETCH(Qt::strong_ordering, ordering); - QCOMPARE(lhs != rhs, notEqual); + QT_TEST_ALL_COMPARISON_OPS(lhs, rhs, ordering); } void tst_QVersionNumber::compare_data() @@ -394,7 +316,7 @@ void tst_QVersionNumber::commonPrefix() QFETCH(QVersionNumber, common); QVersionNumber calculatedPrefix = QVersionNumber::commonPrefix(lhs, rhs); - QCOMPARE(calculatedPrefix, common); + QT_TEST_EQUALITY_OPS(calculatedPrefix, common, true); QCOMPARE(calculatedPrefix.segments(), common.segments()); } @@ -530,18 +452,18 @@ void tst_QVersionNumber::fromString_extra() // when passing explicit nullptr: { auto v = QVersionNumber::fromString("1.2.3-rc1", nullptr); - QCOMPARE(v, QVersionNumber({1, 2, 3})); + QT_TEST_EQUALITY_OPS(v, QVersionNumber({1, 2, 3}), true); } { auto v = QVersionNumber::fromString("1.2.3-rc1", 0); - QCOMPARE(v, QVersionNumber({1, 2, 3})); + QT_TEST_EQUALITY_OPS(v, QVersionNumber({1, 2, 3}), true); } // check the UTF16->L1 conversion isn't doing something weird { qsizetype i = -1; auto v = QVersionNumber::fromString(u"1.0ı", &i); // LATIN SMALL LETTER DOTLESS I - QCOMPARE(v, QVersionNumber(1, 0)); + QT_TEST_EQUALITY_OPS(v, QVersionNumber(1, 0), true); QCOMPARE(i, 3); } } @@ -652,14 +574,14 @@ void tst_QVersionNumber::moveSemantics() { QVersionNumber v1(1, 2, 3); QVersionNumber v2 = std::move(v1); - QCOMPARE(v2, QVersionNumber(1, 2, 3)); + QT_TEST_EQUALITY_OPS(v2, QVersionNumber(1, 2, 3), true); } // QVersionNumber &operator=(QVersionNumber &&) { QVersionNumber v1(1, 2, 3); QVersionNumber v2; v2 = std::move(v1); - QCOMPARE(v2, QVersionNumber(1, 2, 3)); + QT_TEST_EQUALITY_OPS(v2, QVersionNumber(1, 2, 3), true); } // QVersionNumber(QList<int> &&) { @@ -668,7 +590,7 @@ void tst_QVersionNumber::moveSemantics() QVersionNumber v2(std::move(segments)); QVERIFY(!v1.isNull()); QVERIFY(!v2.isNull()); - QCOMPARE(v1, v2); + QT_TEST_EQUALITY_OPS(v1, v2, true); } #ifdef Q_COMPILER_REF_QUALIFIERS // normalized() |