diff options
Diffstat (limited to 'tests/auto/corelib/io/qdebug/tst_qdebug.cpp')
-rw-r--r-- | tests/auto/corelib/io/qdebug/tst_qdebug.cpp | 501 |
1 files changed, 498 insertions, 3 deletions
diff --git a/tests/auto/corelib/io/qdebug/tst_qdebug.cpp b/tests/auto/corelib/io/qdebug/tst_qdebug.cpp index 400625ba7d..15da0758d0 100644 --- a/tests/auto/corelib/io/qdebug/tst_qdebug.cpp +++ b/tests/auto/corelib/io/qdebug/tst_qdebug.cpp @@ -1,6 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // Copyright (C) 2016 Intel Corporation. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QtCore/QCoreApplication> @@ -14,8 +14,23 @@ #include <QLine> #include <QMimeType> #include <QMimeDatabase> +#include <QMetaType> + +#include <q20chrono.h> + +#ifdef __cpp_lib_memory_resource +# include <memory_resource> +namespace pmr = std::pmr; +#else +namespace pmr = std; +#endif + +using namespace std::chrono; +using namespace q20::chrono; +using namespace Qt::StringLiterals; static_assert(QTypeTraits::has_ostream_operator_v<QDebug, int>); +static_assert(QTypeTraits::has_ostream_operator_v<QDebug, QMetaType>); static_assert(QTypeTraits::has_ostream_operator_v<QDebug, QList<int>>); static_assert(QTypeTraits::has_ostream_operator_v<QDebug, QMap<int, QString>>); struct NonStreamable {}; @@ -54,13 +69,27 @@ private slots: void stateSaver() const; void veryLongWarningMessage() const; void qDebugQChar() const; + void qDebugQMetaType() const; void qDebugQString() const; void qDebugQStringView() const; void qDebugQUtf8StringView() const; void qDebugQLatin1String() const; + void qDebugStdString() const; + void qDebugStdStringView() const; + void qDebugStdWString() const; + void qDebugStdWStringView() const; + void qDebugStdU8String() const; + void qDebugStdU8StringView() const; + void qDebugStdU16String() const; + void qDebugStdU16StringView() const; + void qDebugStdU32String() const; + void qDebugStdU32StringView() const; void qDebugQByteArray() const; void qDebugQByteArrayView() const; void qDebugQFlags() const; + void qDebugStdChrono_data() const; + void qDebugStdChrono() const; + void qDebugStdOptional() const; void textStreamModifiers() const; void resetFormat() const; void defaultMessagehandler() const; @@ -290,11 +319,17 @@ void tst_QDebug::debugNoQuotes() const MessageHandlerSetter mhs(myMessageHandler); { QDebug d = qDebug(); + QVERIFY(d.quoteStrings()); d << QStringLiteral("Hello"); + QVERIFY(d.quoteStrings()); d.noquote(); + QVERIFY(!d.quoteStrings()); d << QStringLiteral("Hello"); + QVERIFY(!d.quoteStrings()); d.quote(); + QVERIFY(d.quoteStrings()); d << QStringLiteral("Hello"); + QVERIFY(d.quoteStrings()); } QCOMPARE(s_msg, QString::fromLatin1("\"Hello\" Hello \"Hello\"")); @@ -303,7 +338,7 @@ void tst_QDebug::debugNoQuotes() const d << QChar('H'); d << QLatin1String("Hello"); d << QByteArray("Hello"); - d.noquote(); + d.setQuoteStrings(false); d << QChar('H'); d << QLatin1String("Hello"); d << QByteArray("Hello"); @@ -428,6 +463,25 @@ void tst_QDebug::qDebugQChar() const } +void tst_QDebug::qDebugQMetaType() const +{ + QString file, function; + int line = 0; + MessageHandlerSetter mhs(myMessageHandler); + { + QDebug d = qDebug(); + d << QMetaType::fromType<int>() << QMetaType::fromType<QString>(); + } +#ifndef QT_NO_MESSAGELOGCONTEXT + file = __FILE__; line = __LINE__ - 4; function = Q_FUNC_INFO; +#endif + QCOMPARE(s_msgType, QtDebugMsg); + QCOMPARE(s_msg, R"(QMetaType(int) QMetaType(QString))"_L1); + QCOMPARE(QString::fromLatin1(s_file), file); + QCOMPARE(s_line, line); + QCOMPARE(QString::fromLatin1(s_function), function); +} + void tst_QDebug::qDebugQString() const { /* Use a basic string. */ @@ -624,6 +678,324 @@ void tst_QDebug::qDebugQLatin1String() const QCOMPARE(s_msg, QString("\"\\nSm\\u00F8rg\\u00E5sbord\\\\\"")); } +void tst_QDebug::qDebugStdString() const +{ + QString file, function; + int line = 0; + MessageHandlerSetter mhs(myMessageHandler); + { + QDebug d = qDebug(); + d << pmr::string("foo") << std::string("") << std::string("barbaz", 3); + d.nospace().noquote() << std::string("baz"); + } +#ifndef QT_NO_MESSAGELOGCONTEXT + file = __FILE__; line = __LINE__ - 5; function = Q_FUNC_INFO; +#endif + QCOMPARE(s_msgType, QtDebugMsg); + QCOMPARE(s_msg, QString::fromLatin1("\"foo\" \"\" \"bar\" baz")); + QCOMPARE(QString::fromLatin1(s_file), file); + QCOMPARE(s_line, line); + QCOMPARE(QString::fromLatin1(s_function), function); + + /* simpler tests from now on */ + std::string string("\"Hello\""); + qDebug() << string; + QCOMPARE(s_msg, QString("\"\\\"Hello\\\"\"")); + + qDebug().noquote().nospace() << string; + QCOMPARE(s_msg, QString::fromStdString(string)); + + qDebug().noquote().nospace() << qSetFieldWidth(8) << string; + QCOMPARE(s_msg, " " + QString::fromStdString(string)); +} + +void tst_QDebug::qDebugStdStringView() const +{ + QString file, function; + int line = 0; + MessageHandlerSetter mhs(myMessageHandler); + { + QDebug d = qDebug(); + d << std::string_view("foo") << std::string_view("") << std::string_view("barbaz", 3); + d.nospace().noquote() << std::string_view("baz"); + } +#ifndef QT_NO_MESSAGELOGCONTEXT + file = __FILE__; line = __LINE__ - 5; function = Q_FUNC_INFO; +#endif + QCOMPARE(s_msgType, QtDebugMsg); + QCOMPARE(s_msg, QString::fromLatin1("\"foo\" \"\" \"bar\" baz")); + QCOMPARE(QString::fromLatin1(s_file), file); + QCOMPARE(s_line, line); + QCOMPARE(QString::fromLatin1(s_function), function); + + /* simpler tests from now on */ + std::string_view string("\"Hello\""); + qDebug() << string; + QCOMPARE(s_msg, QString("\"\\\"Hello\\\"\"")); + + qDebug().noquote().nospace() << string; + QCOMPARE(s_msg, QString::fromStdString(std::string(string))); + + qDebug().noquote().nospace() << qSetFieldWidth(8) << string; + QCOMPARE(s_msg, " " + QString::fromStdString(std::string(string))); +} + +void tst_QDebug::qDebugStdWString() const +{ + QString file, function; + int line = 0; + MessageHandlerSetter mhs(myMessageHandler); + { + QDebug d = qDebug(); + d << pmr::wstring(L"foo") << std::wstring(L"") << std::wstring(L"barbaz", 3); + d.nospace().noquote() << std::wstring(L"baz"); + } +#ifndef QT_NO_MESSAGELOGCONTEXT + file = __FILE__; line = __LINE__ - 5; function = Q_FUNC_INFO; +#endif + QCOMPARE(s_msgType, QtDebugMsg); + QCOMPARE(s_msg, QString::fromLatin1("\"foo\" \"\" \"bar\" baz")); + QCOMPARE(QString::fromLatin1(s_file), file); + QCOMPARE(s_line, line); + QCOMPARE(QString::fromLatin1(s_function), function); + + /* simpler tests from now on */ + std::wstring string(L"\"Hello\""); + qDebug() << string; + QCOMPARE(s_msg, QString("\"\\\"Hello\\\"\"")); + + qDebug().noquote().nospace() << string; + QCOMPARE(s_msg, QString::fromStdWString(string)); + + qDebug().noquote().nospace() << qSetFieldWidth(8) << string; + QCOMPARE(s_msg, " " + QString::fromStdWString(string)); +} + +void tst_QDebug::qDebugStdWStringView() const +{ + QString file, function; + int line = 0; + MessageHandlerSetter mhs(myMessageHandler); + { + QDebug d = qDebug(); + d << std::wstring_view(L"foo") << std::wstring_view(L"") << std::wstring_view(L"barbaz", 3); + d.nospace().noquote() << std::wstring_view(L"baz"); + } +#ifndef QT_NO_MESSAGELOGCONTEXT + file = __FILE__; line = __LINE__ - 5; function = Q_FUNC_INFO; +#endif + QCOMPARE(s_msgType, QtDebugMsg); + QCOMPARE(s_msg, QString::fromLatin1("\"foo\" \"\" \"bar\" baz")); + QCOMPARE(QString::fromLatin1(s_file), file); + QCOMPARE(s_line, line); + QCOMPARE(QString::fromLatin1(s_function), function); + + /* simpler tests from now on */ + std::wstring_view string(L"\"Hello\""); + qDebug() << string; + QCOMPARE(s_msg, QString("\"\\\"Hello\\\"\"")); + + qDebug().noquote().nospace() << string; + QCOMPARE(s_msg, QString::fromStdWString(std::wstring(string))); + + qDebug().noquote().nospace() << qSetFieldWidth(8) << string; + QCOMPARE(s_msg, " " + QString::fromStdWString(std::wstring(string))); +} + +void tst_QDebug::qDebugStdU8String() const +{ +#ifndef __cpp_lib_char8_t + QSKIP("This test requires C++20 char8_t support enabled in the compiler."); +#else + QString file, function; + int line = 0; + MessageHandlerSetter mhs(myMessageHandler); + { + QDebug d = qDebug(); + d << pmr::u8string(u8"foo") << std::u8string(u8"") << std::u8string(u8"barbaz", 3); + d.nospace().noquote() << std::u8string(u8"baz"); + } +#ifndef QT_NO_MESSAGELOGCONTEXT + file = __FILE__; line = __LINE__ - 5; function = Q_FUNC_INFO; +#endif + QCOMPARE(s_msgType, QtDebugMsg); + QCOMPARE(s_msg, QString::fromLatin1("\"foo\" \"\" \"bar\" baz")); + QCOMPARE(QString::fromLatin1(s_file), file); + QCOMPARE(s_line, line); + QCOMPARE(QString::fromLatin1(s_function), function); + + /* simpler tests from now on */ + std::u8string string(u8"\"Hello\""); + qDebug() << string; + QCOMPARE(s_msg, QString("\"\\\"Hello\\\"\"")); + + qDebug().noquote().nospace() << string; + QCOMPARE(s_msg, QUtf8StringView(string).toString()); + + qDebug().noquote().nospace() << qSetFieldWidth(8) << string; + QCOMPARE(s_msg, " " + QUtf8StringView(string).toString()); +#endif // __cpp_lib_char8_t +} + +void tst_QDebug::qDebugStdU8StringView() const +{ +#ifndef __cpp_lib_char8_t + QSKIP("This test requires C++20 char8_t support enabled in the compiler."); +#else + QString file, function; + int line = 0; + MessageHandlerSetter mhs(myMessageHandler); + { + QDebug d = qDebug(); + d << std::u16string_view(u"foo") << std::u16string_view(u"") << std::u16string_view(u"barbaz", 3); + d.nospace().noquote() << std::u16string_view(u"baz"); + } +#ifndef QT_NO_MESSAGELOGCONTEXT + file = __FILE__; line = __LINE__ - 5; function = Q_FUNC_INFO; +#endif + QCOMPARE(s_msgType, QtDebugMsg); + QCOMPARE(s_msg, QString::fromLatin1("\"foo\" \"\" \"bar\" baz")); + QCOMPARE(QString::fromLatin1(s_file), file); + QCOMPARE(s_line, line); + QCOMPARE(QString::fromLatin1(s_function), function); + + /* simpler tests from now on */ + std::u16string_view string(u"\"Hello\""); + qDebug() << string; + QCOMPARE(s_msg, QString("\"\\\"Hello\\\"\"")); + + qDebug().noquote().nospace() << string; + QCOMPARE(s_msg, QString::fromStdU16String(std::u16string(string))); + + qDebug().noquote().nospace() << qSetFieldWidth(8) << string; + QCOMPARE(s_msg, " " + QString::fromStdU16String(std::u16string(string))); +#endif // __cpp_lib_char8_t +} + +void tst_QDebug::qDebugStdU16String() const +{ + QString file, function; + int line = 0; + MessageHandlerSetter mhs(myMessageHandler); + { + QDebug d = qDebug(); + d << pmr::u16string(u"foo") << std::u16string(u"") << std::u16string(u"barbaz", 3); + d.nospace().noquote() << std::u16string(u"baz"); + } +#ifndef QT_NO_MESSAGELOGCONTEXT + file = __FILE__; line = __LINE__ - 5; function = Q_FUNC_INFO; +#endif + QCOMPARE(s_msgType, QtDebugMsg); + QCOMPARE(s_msg, QString::fromLatin1("\"foo\" \"\" \"bar\" baz")); + QCOMPARE(QString::fromLatin1(s_file), file); + QCOMPARE(s_line, line); + QCOMPARE(QString::fromLatin1(s_function), function); + + /* simpler tests from now on */ + std::u16string string(u"\"Hello\""); + qDebug() << string; + QCOMPARE(s_msg, QString("\"\\\"Hello\\\"\"")); + + qDebug().noquote().nospace() << string; + QCOMPARE(s_msg, QString::fromStdU16String(string)); + + qDebug().noquote().nospace() << qSetFieldWidth(8) << string; + QCOMPARE(s_msg, " " + QString::fromStdU16String(string)); +} + +void tst_QDebug::qDebugStdU16StringView() const +{ + QString file, function; + int line = 0; + MessageHandlerSetter mhs(myMessageHandler); + { + QDebug d = qDebug(); + d << std::u16string_view(u"foo") << std::u16string_view(u"") << std::u16string_view(u"barbaz", 3); + d.nospace().noquote() << std::u16string_view(u"baz"); + } +#ifndef QT_NO_MESSAGELOGCONTEXT + file = __FILE__; line = __LINE__ - 5; function = Q_FUNC_INFO; +#endif + QCOMPARE(s_msgType, QtDebugMsg); + QCOMPARE(s_msg, QString::fromLatin1("\"foo\" \"\" \"bar\" baz")); + QCOMPARE(QString::fromLatin1(s_file), file); + QCOMPARE(s_line, line); + QCOMPARE(QString::fromLatin1(s_function), function); + + /* simpler tests from now on */ + std::u16string_view string(u"\"Hello\""); + qDebug() << string; + QCOMPARE(s_msg, QString("\"\\\"Hello\\\"\"")); + + qDebug().noquote().nospace() << string; + QCOMPARE(s_msg, QString::fromStdU16String(std::u16string(string))); + + qDebug().noquote().nospace() << qSetFieldWidth(8) << string; + QCOMPARE(s_msg, " " + QString::fromStdU16String(std::u16string(string))); +} + +void tst_QDebug::qDebugStdU32String() const +{ + QString file, function; + int line = 0; + MessageHandlerSetter mhs(myMessageHandler); + { + QDebug d = qDebug(); + d << pmr::u32string(U"foo") << std::u32string(U"") << std::u32string(U"barbaz", 3); + d.nospace().noquote() << std::u32string(U"baz"); + } +#ifndef QT_NO_MESSAGELOGCONTEXT + file = __FILE__; line = __LINE__ - 5; function = Q_FUNC_INFO; +#endif + QCOMPARE(s_msgType, QtDebugMsg); + QCOMPARE(s_msg, QString::fromLatin1("\"foo\" \"\" \"bar\" baz")); + QCOMPARE(QString::fromLatin1(s_file), file); + QCOMPARE(s_line, line); + QCOMPARE(QString::fromLatin1(s_function), function); + + /* simpler tests from now on */ + std::u32string string(U"\"Hello\""); + qDebug() << string; + QCOMPARE(s_msg, QString("\"\\\"Hello\\\"\"")); + + qDebug().noquote().nospace() << string; + QCOMPARE(s_msg, QString::fromStdU32String(string)); + + qDebug().noquote().nospace() << qSetFieldWidth(8) << string; + QCOMPARE(s_msg, " " + QString::fromStdU32String(string)); +} + +void tst_QDebug::qDebugStdU32StringView() const +{ + QString file, function; + int line = 0; + MessageHandlerSetter mhs(myMessageHandler); + { + QDebug d = qDebug(); + d << std::u32string_view(U"foo") << std::u32string_view(U"") << std::u32string_view(U"barbaz", 3); + d.nospace().noquote() << std::u32string_view(U"baz"); + } +#ifndef QT_NO_MESSAGELOGCONTEXT + file = __FILE__; line = __LINE__ - 5; function = Q_FUNC_INFO; +#endif + QCOMPARE(s_msgType, QtDebugMsg); + QCOMPARE(s_msg, QString::fromLatin1("\"foo\" \"\" \"bar\" baz")); + QCOMPARE(QString::fromLatin1(s_file), file); + QCOMPARE(s_line, line); + QCOMPARE(QString::fromLatin1(s_function), function); + + /* simpler tests from now on */ + std::u32string_view string(U"\"Hello\""); + qDebug() << string; + QCOMPARE(s_msg, QString("\"\\\"Hello\\\"\"")); + + qDebug().noquote().nospace() << string; + QCOMPARE(s_msg, QString::fromStdU32String(std::u32string(string))); + + qDebug().noquote().nospace() << qSetFieldWidth(8) << string; + QCOMPARE(s_msg, " " + QString::fromStdU32String(std::u32string(string))); +} + void tst_QDebug::qDebugQByteArray() const { QString file, function; @@ -743,6 +1115,129 @@ void tst_QDebug::qDebugQFlags() const QCOMPARE(s_msg, QString::fromLatin1("QFlags<tst_QDebug::FlagType>(EnumFlag1)")); } +using ToStringFunction = std::function<QString()>; +void tst_QDebug::qDebugStdChrono_data() const +{ + using attoseconds = duration<int64_t, std::atto>; + using femtoseconds = duration<int64_t, std::femto>; + using picoseconds = duration<int64_t, std::pico>; + using centiseconds = duration<int64_t, std::centi>; + using deciseconds = duration<int64_t, std::deci>; + + using quadriennia = duration<int, std::ratio_multiply<std::ratio<4>, years::period>>; + using decades = duration<int, std::ratio_multiply<years::period, std::deca>>; // decayears + using centuries = duration<int16_t, std::ratio_multiply<years::period, std::hecto>>; // hectoyears + using millennia = duration<int16_t, std::ratio_multiply<years::period, std::kilo>>; // kiloyears + using gigayears = duration<int8_t, std::ratio_multiply<years::period, std::giga>>; + using fortnights = duration<int, std::ratio_multiply<days::period, std::ratio<14>>>; + using microfortnights = duration<int64_t, std::ratio_multiply<fortnights::period, std::micro>>; + using telecom = duration<int64_t, std::ratio<1, 8000>>; // 8 kHz + + using kiloseconds = duration<int64_t, std::kilo>; + using exaseconds = duration<int8_t, std::exa>; + using meter_per_light = duration<int64_t, std::ratio<1, 299'792'458>>; + using kilometer_per_light = duration<int64_t, std::ratio<1000, 299'792'458>>; + + QTest::addColumn<ToStringFunction>("fn"); + QTest::addColumn<QString>("expected"); + + auto addRow = [](const char *name, auto duration, const char *expected) { + auto toString = [duration]() { return QDebug::toString(duration); }; + QTest::newRow(name) << ToStringFunction(toString) << expected; + }; + + addRow("1as", attoseconds{1}, "1as"); + addRow("1fs", femtoseconds{1}, "1fs"); + addRow("1ps", picoseconds{1}, "1ps"); + addRow("0ns", 0ns, "0ns"); + addRow("1000ns", 1000ns, "1000ns"); + addRow("0us", 0us, "0us"); + addRow("0ms", 0ms, "0ms"); + addRow("1cs", centiseconds{1}, "1cs"); + addRow("2ds", deciseconds{2}, "2ds"); + addRow("-1s", -1s, "-1s"); + addRow("0s", 0s, "0s"); + addRow("1s", 1s, "1s"); + addRow("60s", 60s, "60s"); + addRow("1min", 1min, "1min"); + addRow("1h", 1h, "1h"); + addRow("1days", days{1}, "1d"); + addRow("365days", days{365}, "365d"); + addRow("1weeks", weeks{1}, "1wk"); + addRow("1years", years{1}, "1yr"); // 365.2425 days + addRow("42years", years{42}, "42yr"); + + addRow("1ks", kiloseconds{1}, "1[1000]s"); + addRow("2fortnights", fortnights{2}, "2[2]wk"); + addRow("1quadriennia", quadriennia{1}, "1[4]yr"); + addRow("1decades", decades{1}, "1[10]yr"); + addRow("1centuries", centuries{1}, "1[100]yr"); + addRow("1millennia", millennia{1}, "1[1000]yr"); +#if defined(Q_OS_LINUX) || defined(Q_OS_DARWIN) + // some OSes print the exponent differently + addRow("1Es", exaseconds{1}, "1[1e+18]s"); + addRow("13gigayears", gigayears{13}, "13[1e+09]yr"); +#endif + + // months are one twelfth of a Gregorian year, not 30 days + addRow("1months", months{1}, "1[2629746]s"); + + // weird units + addRow("2microfortnights", microfortnights{2}, "2[756/625]s"); + addRow("1telecom", telecom{1}, "1[1/8000]s"); + addRow("10m/c", meter_per_light{10}, "10[1/299792458]s"); + addRow("10km/c", kilometer_per_light{10}, "10[500/149896229]s"); + + // real floting point + using fpsec = duration<double>; + using fpmsec = duration<double, std::milli>; + using fpnsec = duration<double, std::nano>; + addRow("1.0s", fpsec{1}, "1s"); + addRow("1.5s", fpsec{1.5}, "1.5s"); + addRow("1.0ms", fpmsec{1}, "1ms"); + addRow("1.5ms", fpmsec{1.5}, "1.5ms"); + addRow("1.0ns", fpnsec{1}, "1ns"); + addRow("1.5ns", fpnsec{1.5}, "1.5ns"); + + // and some precision setting too + QTest::newRow("1.00000ns") + << ToStringFunction([]() { + QString buffer; + QDebug d(&buffer); + d.nospace() << qSetRealNumberPrecision(5) << Qt::fixed << fpnsec{1}; + return buffer; + }) << "1.00000ns"; +} + +void tst_QDebug::qDebugStdChrono() const +{ + QFETCH(ToStringFunction, fn); + QFETCH(QString, expected); + QCOMPARE(fn(), expected); +} + +void tst_QDebug::qDebugStdOptional() const +{ + QString file, function; + int line = 0; + MessageHandlerSetter mhs(myMessageHandler); + { + std::optional<QByteArray> notSet = std::nullopt; + std::optional<QByteArray> set("foo"); + auto no = std::nullopt; + QDebug d = qDebug(); + d << notSet << set << no; + } +#ifndef QT_NO_MESSAGELOGCONTEXT + file = __FILE__; line = __LINE__ - 4; function = Q_FUNC_INFO; +#endif + QCOMPARE(s_msgType, QtDebugMsg); + QCOMPARE(s_msg, QString::fromLatin1("nullopt std::optional(\"foo\") nullopt")); + QCOMPARE(QString::fromLatin1(s_file), file); + QCOMPARE(s_line, line); + QCOMPARE(QString::fromLatin1(s_function), function); +} + void tst_QDebug::textStreamModifiers() const { QString file, function; @@ -822,7 +1317,7 @@ void tst_QDebug::threadSafety() const s_sema.release(numThreads); sync.waitForFinished(); QMutexLocker lock(&s_mutex); - QCOMPARE(s_messages.count(), numThreads); + QCOMPARE(s_messages.size(), numThreads); for (int i = 0; i < numThreads; ++i) { QCOMPARE(s_messages.at(i), QStringLiteral("doDebug")); } |