diff options
Diffstat (limited to 'tests')
17 files changed, 534 insertions, 99 deletions
diff --git a/tests/auto/corelib/serialization/json/tst_qtjson.cpp b/tests/auto/corelib/serialization/json/tst_qtjson.cpp index 3f242ba2a0..fbf0eacbd5 100644 --- a/tests/auto/corelib/serialization/json/tst_qtjson.cpp +++ b/tests/auto/corelib/serialization/json/tst_qtjson.cpp @@ -732,15 +732,20 @@ void tst_QtJson::testValueObject() void tst_QtJson::testValueArray() { QJsonArray array; + QJsonArray otherArray = {"wrong value"}; + QJsonValue value(array); + QCOMPARE(value.toArray(), array); + QCOMPARE(value.toArray(otherArray), array); + array.append(999.); array.append(QLatin1String("test")); array.append(true); - - QJsonValue value(array); + value = array; // if we don't modify the original JsonArray, toArray() // on the JsonValue should return the same object (non-detached). QCOMPARE(value.toArray(), array); + QCOMPARE(value.toArray(otherArray), array); // if we modify the original array, it should detach array.append(QLatin1String("test")); @@ -750,14 +755,23 @@ void tst_QtJson::testValueArray() void tst_QtJson::testObjectNested() { QJsonObject inner, outer; + QJsonObject otherObject = {{"wrong key", "wrong value"}}; + QJsonValue v = inner; + QCOMPARE(v.toObject(), inner); + QCOMPARE(v.toObject(otherObject), inner); + inner.insert("number", 999.); outer.insert("nested", inner); // if we don't modify the original JsonObject, value() // should return the same object (non-detached). QJsonObject value = outer.value("nested").toObject(); + v = value; QCOMPARE(value, inner); QCOMPARE(value.value("number").toDouble(), 999.); + QCOMPARE(v.toObject(), inner); + QCOMPARE(v.toObject(otherObject), inner); + QCOMPARE(v["number"].toDouble(), 999.); // if we modify the original object, it should detach and not // affect the nested object diff --git a/tests/auto/corelib/text/qlocale/tst_qlocale.cpp b/tests/auto/corelib/text/qlocale/tst_qlocale.cpp index 84901f8f75..4ee6c6df75 100644 --- a/tests/auto/corelib/text/qlocale/tst_qlocale.cpp +++ b/tests/auto/corelib/text/qlocale/tst_qlocale.cpp @@ -3012,7 +3012,12 @@ public: QVariant query(QueryType type, QVariant /*in*/) const override { - return type == UILanguages ? QVariant(QStringList{m_name}) : QVariant(); + if (type == UILanguages) { + if (m_name == u"en-DE") // QTBUG-104930: simulate macOS's list not including m_name. + return QVariant(QStringList{QStringLiteral("en-GB"), QStringLiteral("de-DE")}); + return QVariant(QStringList{m_name}); + } + return QVariant(); } QLocale fallbackUiLocale() const override @@ -3038,6 +3043,12 @@ void tst_QLocale::systemLocale_data() QTest::addRow("ukrainian") << QString("uk") << QLocale::Ukrainian << QStringList{QStringLiteral("uk"), QStringLiteral("uk-UA"), QStringLiteral("uk-Cyrl-UA")}; + QTest::addRow("english-germany") + << QString("en-DE") << QLocale::English + // First two were missed out before fix to QTBUG-104930: + << QStringList{QStringLiteral("en-DE"), QStringLiteral("en-Latn-DE"), + QStringLiteral("en-GB"), QStringLiteral("en-Latn-GB"), + QStringLiteral("de-DE"), QStringLiteral("de"), QStringLiteral("de-Latn-DE")}; QTest::addRow("german") << QString("de") << QLocale::German << QStringList{QStringLiteral("de"), QStringLiteral("de-DE"), QStringLiteral("de-Latn-DE")}; @@ -3062,7 +3073,11 @@ void tst_QLocale::systemLocale() MySystemLocale sLocale(name); QCOMPARE(QLocale().language(), language); QCOMPARE(QLocale::system().language(), language); + auto reporter = qScopeGuard([]() { + qDebug("\n\t%s", qPrintable(QLocale::system().uiLanguages().join(u"\n\t"))); + }); QCOMPARE(QLocale::system().uiLanguages(), uiLanguages); + reporter.dismiss(); } QCOMPARE(QLocale(), originalLocale); diff --git a/tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp b/tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp index b60d67fd89..96eb792cb2 100644 --- a/tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp +++ b/tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp @@ -1041,7 +1041,10 @@ void tst_QDateTime::toString_enumformat() QString str2 = dt1.toString(Qt::ISODate); QCOMPARE(str2, QString("1995-05-20T12:34:56")); +#if QT_DEPRECATED_SINCE(5, 15) + QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED QString str3 = dt1.toString(Qt::LocalDate); + QT_WARNING_POP QVERIFY(!str3.isEmpty()); //check for date/time components in any order //year may be 2 or 4 digits @@ -1050,6 +1053,7 @@ void tst_QDateTime::toString_enumformat() QVERIFY(str3.contains("12")); QVERIFY(str3.contains("34")); //seconds may be absent +#endif // 5.15 deprecations } void tst_QDateTime::addDays() diff --git a/tests/auto/corelib/tools/qbitarray/tst_qbitarray.cpp b/tests/auto/corelib/tools/qbitarray/tst_qbitarray.cpp index 9a7c099228..056fce881d 100644 --- a/tests/auto/corelib/tools/qbitarray/tst_qbitarray.cpp +++ b/tests/auto/corelib/tools/qbitarray/tst_qbitarray.cpp @@ -165,6 +165,7 @@ void tst_QBitArray::countBits() bits.setBit(i); } + QCOMPARE(bits.size(), numBits); QCOMPARE(bits.count(), numBits); QCOMPARE(bits.count(true), onBits); QCOMPARE(bits.count(false), numBits - onBits); diff --git a/tests/auto/corelib/tools/qcontiguouscache/tst_qcontiguouscache.cpp b/tests/auto/corelib/tools/qcontiguouscache/tst_qcontiguouscache.cpp index f305d63d46..9910c9c329 100644 --- a/tests/auto/corelib/tools/qcontiguouscache/tst_qcontiguouscache.cpp +++ b/tests/auto/corelib/tools/qcontiguouscache/tst_qcontiguouscache.cpp @@ -75,10 +75,12 @@ void tst_QContiguousCache::empty() { QContiguousCache<int> c(10); QCOMPARE(c.capacity(), 10); + QCOMPARE(c.size(), 0); QCOMPARE(c.count(), 0); QVERIFY(c.isEmpty()); c.append(1); QCOMPARE(c.count(), 1); + QCOMPARE(c.size(), 1); QVERIFY(!c.isEmpty()); c.clear(); QCOMPARE(c.capacity(), 10); diff --git a/tests/auto/gui/kernel/qguitimer/BLACKLIST b/tests/auto/gui/kernel/qguitimer/BLACKLIST new file mode 100644 index 0000000000..c6f1e9c892 --- /dev/null +++ b/tests/auto/gui/kernel/qguitimer/BLACKLIST @@ -0,0 +1,3 @@ +# See qtbase/src/testlib/qtestblacklist.cpp for format +[zeroTimer] +ci ubuntu-20.04 # QTBUG-108556 diff --git a/tests/auto/network/access/qftp/BLACKLIST b/tests/auto/network/access/qftp/BLACKLIST index 0a99f3eb00..59ed606207 100644 --- a/tests/auto/network/access/qftp/BLACKLIST +++ b/tests/auto/network/access/qftp/BLACKLIST @@ -14,3 +14,5 @@ ubuntu osx [list:epsvNotSupported] * +[initTestCase] +ci ubuntu-20.04 # QTBUG-109022 diff --git a/tests/auto/network/kernel/qhostaddress/tst_qhostaddress.cpp b/tests/auto/network/kernel/qhostaddress/tst_qhostaddress.cpp index 48f05a4604..454b00eea4 100644 --- a/tests/auto/network/kernel/qhostaddress/tst_qhostaddress.cpp +++ b/tests/auto/network/kernel/qhostaddress/tst_qhostaddress.cpp @@ -354,6 +354,12 @@ void tst_QHostAddress::isEqual_data() QTest::newRow("anyv6-anyv4-local") << QHostAddress(QHostAddress::AnyIPv6) << QHostAddress(QHostAddress::AnyIPv4) << (int)QHostAddress::ConvertLocalHost << false; QTest::newRow("any-anyv4-local") << QHostAddress(QHostAddress::Any) << QHostAddress(QHostAddress::AnyIPv4) << (int)QHostAddress::ConvertLocalHost << false; QTest::newRow("any-anyv6-local") << QHostAddress(QHostAddress::Any) << QHostAddress(QHostAddress::AnyIPv6) << (int)QHostAddress::ConvertLocalHost << false; + QTest::newRow("localhostv6-any-tolerant") << QHostAddress(QHostAddress::LocalHostIPv6) << QHostAddress(QHostAddress::Any) << (int)QHostAddress::TolerantConversion << false; + QTest::newRow("localhostv4-any-tolerant") << QHostAddress(QHostAddress::LocalHost) << QHostAddress(QHostAddress::Any) << (int)QHostAddress::TolerantConversion << false; + QTest::newRow("localhostv6-anyv6-tolerant") << QHostAddress(QHostAddress::LocalHostIPv6) << QHostAddress(QHostAddress::AnyIPv6) << (int)QHostAddress::TolerantConversion << false; + QTest::newRow("localhostv4-anyv6-tolerant") << QHostAddress(QHostAddress::LocalHost) << QHostAddress(QHostAddress::AnyIPv6) << (int)QHostAddress::TolerantConversion << false; + QTest::newRow("localhostv6-anyv4-tolerant") << QHostAddress(QHostAddress::LocalHostIPv6) << QHostAddress(QHostAddress::AnyIPv4) << (int)QHostAddress::TolerantConversion << false; + QTest::newRow("localhostv4-anyv4-tolerant") << QHostAddress(QHostAddress::LocalHost) << QHostAddress(QHostAddress::AnyIPv4) << (int)QHostAddress::TolerantConversion << false; } void tst_QHostAddress::isEqual() diff --git a/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp b/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp index 4c4113d9d4..15c74f1319 100644 --- a/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp +++ b/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp @@ -646,7 +646,7 @@ void tst_QUdpSocket::dualStack() QCOMPARE(dgram.senderAddress(), makeNonAny(v4Sock.localAddress(), QHostAddress::Null)); if (dgram.destinationPort() != -1) { QCOMPARE(dgram.destinationPort(), int(dualSock.localPort())); - QVERIFY(dgram.destinationAddress().isEqual(dualSock.localAddress())); + QVERIFY(dgram.destinationAddress().isEqual(makeNonAny(dualSock.localAddress(), QHostAddress::LocalHost))); } else { qInfo("Getting IPv4 destination address failed."); } diff --git a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp index 010cc5d45c..5dd5f66eba 100644 --- a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp +++ b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp @@ -238,9 +238,6 @@ private slots: void writeBigChunk(); void blacklistedCertificates(); void versionAccessors(); -#ifndef QT_NO_OPENSSL - void sslOptions(); -#endif void encryptWithoutConnecting(); void resume_data(); void resume(); @@ -1202,7 +1199,7 @@ public: config(QSslConfiguration::defaultConfiguration()), ignoreSslErrors(true), peerVerifyMode(QSslSocket::AutoVerifyPeer), - protocol(QSsl::TlsV1_0), + protocol(QSsl::TlsV1_2), m_keyFile(keyFile), m_certFile(certFile), m_interFile(interFile) @@ -2837,60 +2834,6 @@ void tst_QSslSocket::versionAccessors() qDebug() << QString::number(QSslSocket::sslLibraryVersionNumber(), 16); } -#ifndef QT_NO_OPENSSL -void tst_QSslSocket::sslOptions() -{ - if (!QSslSocket::supportsSsl()) - return; - -#ifdef SSL_OP_NO_COMPRESSION - QCOMPARE(QSslSocketBackendPrivate::setupOpenSslOptions(QSsl::SecureProtocols, - QSslConfigurationPrivate::defaultSslOptions), - long(SSL_OP_ALL|SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3|SSL_OP_NO_COMPRESSION|SSL_OP_CIPHER_SERVER_PREFERENCE)); -#else - QCOMPARE(QSslSocketBackendPrivate::setupOpenSslOptions(QSsl::SecureProtocols, - QSslConfigurationPrivate::defaultSslOptions), - long(SSL_OP_ALL|SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3|SSL_OP_CIPHER_SERVER_PREFERENCE)); -#endif - - QCOMPARE(QSslSocketBackendPrivate::setupOpenSslOptions(QSsl::SecureProtocols, - QSsl::SslOptionDisableEmptyFragments - |QSsl::SslOptionDisableLegacyRenegotiation), - long(SSL_OP_ALL|SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3|SSL_OP_CIPHER_SERVER_PREFERENCE)); - -#ifdef SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION - QCOMPARE(QSslSocketBackendPrivate::setupOpenSslOptions(QSsl::SecureProtocols, - QSsl::SslOptionDisableEmptyFragments), - long((SSL_OP_ALL|SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3|SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION|SSL_OP_CIPHER_SERVER_PREFERENCE))); -#endif - -#ifdef SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS - QCOMPARE(QSslSocketBackendPrivate::setupOpenSslOptions(QSsl::SecureProtocols, - QSsl::SslOptionDisableLegacyRenegotiation), - long((SSL_OP_ALL|SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3|SSL_OP_CIPHER_SERVER_PREFERENCE) & ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS)); -#endif - -#ifdef SSL_OP_NO_TICKET - QCOMPARE(QSslSocketBackendPrivate::setupOpenSslOptions(QSsl::SecureProtocols, - QSsl::SslOptionDisableEmptyFragments - |QSsl::SslOptionDisableLegacyRenegotiation - |QSsl::SslOptionDisableSessionTickets), - long((SSL_OP_ALL|SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3|SSL_OP_NO_TICKET|SSL_OP_CIPHER_SERVER_PREFERENCE))); -#endif - -#ifdef SSL_OP_NO_TICKET -#ifdef SSL_OP_NO_COMPRESSION - QCOMPARE(QSslSocketBackendPrivate::setupOpenSslOptions(QSsl::SecureProtocols, - QSsl::SslOptionDisableEmptyFragments - |QSsl::SslOptionDisableLegacyRenegotiation - |QSsl::SslOptionDisableSessionTickets - |QSsl::SslOptionDisableCompression), - long((SSL_OP_ALL|SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3|SSL_OP_NO_TICKET|SSL_OP_NO_COMPRESSION|SSL_OP_CIPHER_SERVER_PREFERENCE))); -#endif -#endif -} -#endif - void tst_QSslSocket::encryptWithoutConnecting() { if (!QSslSocket::supportsSsl()) diff --git a/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp b/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp index 6d6d65b791..1b760e87ba 100644 --- a/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp +++ b/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp @@ -251,6 +251,9 @@ private slots: void sqlite_real_data() { generic_data("QSQLITE"); } void sqlite_real(); + void prepared_query_json_row_data() { generic_data(); } + void prepared_query_json_row(); + void aggregateFunctionTypes_data() { generic_data(); } void aggregateFunctionTypes(); @@ -4308,6 +4311,43 @@ void tst_QSqlQuery::sqlite_real() QCOMPARE(q.value(0).toDouble(), 5.6); } +void tst_QSqlQuery::prepared_query_json_row() +{ + QFETCH(QString, dbName); + QSqlDatabase db = QSqlDatabase::database(dbName); + CHECK_DATABASE(db); + if (tst_Databases::getDatabaseType(db) != QSqlDriver::MySqlServer && + tst_Databases::getDatabaseType(db) != QSqlDriver::PostgreSQL) { + QSKIP("PostgreSQL / MySQL specific test"); + } + + const QString tableName(qTableName("tableWithJsonRow", __FILE__, db)); + tst_Databases::safeDropTable(db, tableName); + + QSqlQuery q(db); + const QLatin1String vals[] = {QLatin1String("{\"certificateNumber\": \"CERT-001\"}"), + QLatin1String("{\"certificateNumber\": \"CERT-002\"}")}; + QVERIFY_SQL(q, exec(QLatin1String("CREATE TABLE %1 (id INTEGER, value JSON)").arg(tableName))); + for (const QLatin1String &json : vals) { + QVERIFY_SQL(q, exec(QLatin1String("INSERT INTO %1 (id, value) VALUES (1, '%2')") + .arg(tableName, json))); + } + + QVERIFY_SQL(q, prepare(QLatin1String("SELECT id, value FROM %1 WHERE id = ?").arg(tableName))); + q.addBindValue(1); + QVERIFY_SQL(q, exec()); + + size_t iCount = 0; + while (q.next()) { + QVERIFY(iCount < sizeof(vals)); + const int id = q.value(0).toInt(); + const QByteArray json = q.value(1).toByteArray(); + QCOMPARE(id, 1); + QCOMPARE(json, vals[iCount].data()); + ++iCount; + } +} + void tst_QSqlQuery::aggregateFunctionTypes() { QFETCH(QString, dbName); diff --git a/tests/auto/widgets/kernel/qapplication/BLACKLIST b/tests/auto/widgets/kernel/qapplication/BLACKLIST index 364a2abe4f..7f4dd88261 100644 --- a/tests/auto/widgets/kernel/qapplication/BLACKLIST +++ b/tests/auto/widgets/kernel/qapplication/BLACKLIST @@ -1,6 +1,7 @@ [sendEventsOnProcessEvents] ubuntu-20.04 ubuntu-22.04 +rhel-9.0 [touchEventPropagation] # QTBUG-66745 opensuse-leap diff --git a/tests/auto/widgets/kernel/qwidget/BLACKLIST b/tests/auto/widgets/kernel/qwidget/BLACKLIST index 1f1e3804fc..16e8dc717d 100644 --- a/tests/auto/widgets/kernel/qwidget/BLACKLIST +++ b/tests/auto/widgets/kernel/qwidget/BLACKLIST @@ -8,11 +8,6 @@ b2qt opensuse-42.3 [restoreVersion1Geometry] ubuntu-16.04 -[focusProxyAndInputMethods] -rhel-7.6 -opensuse-leap -ubuntu -sles [raise] opensuse-leap # QTBUG-68175 diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp index 2b11aec902..30e828369c 100644 --- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp +++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp @@ -379,7 +379,6 @@ private slots: void openModal_taskQTBUG_5804(); void focusProxy(); - void focusProxyAndInputMethods(); #ifdef QT_BUILD_INTERNAL void scrollWithoutBackingStore(); #endif @@ -10488,34 +10487,6 @@ void tst_QWidget::focusProxy() QCOMPARE(container2->focusOutCount, 1); } -void tst_QWidget::focusProxyAndInputMethods() -{ - if (!QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::WindowActivation)) - QSKIP("Window activation is not supported."); - QScopedPointer<QWidget> toplevel(new QWidget(nullptr, Qt::X11BypassWindowManagerHint)); - toplevel->setWindowTitle(QLatin1String(QTest::currentTestFunction())); - toplevel->resize(200, 200); - toplevel->setAttribute(Qt::WA_InputMethodEnabled, true); - - QWidget *child = new QWidget(toplevel.data()); - child->setFocusProxy(toplevel.data()); - child->setAttribute(Qt::WA_InputMethodEnabled, true); - - toplevel->setFocusPolicy(Qt::WheelFocus); - child->setFocusPolicy(Qt::WheelFocus); - - QVERIFY(!child->hasFocus()); - QVERIFY(!toplevel->hasFocus()); - - toplevel->show(); - QVERIFY(QTest::qWaitForWindowExposed(toplevel.data())); - QApplication::setActiveWindow(toplevel.data()); - QVERIFY(QTest::qWaitForWindowActive(toplevel.data())); - QVERIFY(toplevel->hasFocus()); - QVERIFY(child->hasFocus()); - QCOMPARE(qApp->focusObject(), toplevel.data()); -} - #ifdef QT_BUILD_INTERNAL class scrollWidgetWBS : public QWidget { diff --git a/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp b/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp index 45b3b879b7..a527d7c0fc 100644 --- a/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp +++ b/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp @@ -2258,11 +2258,19 @@ void tst_QStyleSheetStyle::placeholderColor() QLineEdit le2; le2.setEnabled(false); le1.ensurePolished(); - QCOMPARE(le1.palette().placeholderText(), red); + QColor phColor = le1.palette().placeholderText().color(); + QCOMPARE(phColor.rgb(), red.rgb()); + QVERIFY(phColor.alpha() < red.alpha()); + le2.ensurePolished(); - QCOMPARE(le2.palette().placeholderText(), red); + phColor = le2.palette().placeholderText().color(); + QCOMPARE(phColor.rgb(), red.rgb()); + QVERIFY(phColor.alpha() < red.alpha()); + le2.setEnabled(true); - QCOMPARE(le2.palette().placeholderText(), red); + phColor = le2.palette().placeholderText().color(); + QCOMPARE(phColor.rgb(), red.rgb()); + QVERIFY(phColor.alpha() < red.alpha()); } void tst_QStyleSheetStyle::enumPropertySelector_data() diff --git a/tests/benchmarks/corelib/text/qlocale/main.cpp b/tests/benchmarks/corelib/text/qlocale/main.cpp index 38d94af143..c7bd37a2d3 100644 --- a/tests/benchmarks/corelib/text/qlocale/main.cpp +++ b/tests/benchmarks/corelib/text/qlocale/main.cpp @@ -28,6 +28,7 @@ #include <QLocale> #include <QTest> +#include <limits> class tst_QLocale : public QObject { @@ -37,6 +38,12 @@ private Q_SLOTS: void toUpper_QLocale_1(); void toUpper_QLocale_2(); void toUpper_QString(); + void toLongLong_data(); + void toLongLong(); + void toULongLong_data(); + void toULongLong(); + void toDouble_data(); + void toDouble(); }; static QString data() @@ -65,6 +72,271 @@ void tst_QLocale::toUpper_QString() QBENCHMARK { LOOP(s.toUpper()) } } +template <typename Integer> +void toWholeCommon_data() +{ + QTest::addColumn<QString>("text"); + QTest::addColumn<QString>("locale"); + QTest::addColumn<bool>("good"); + QTest::addColumn<Integer>("expected"); + + QTest::newRow("C: empty") + << QStringLiteral("") << QStringLiteral("C") << false << Integer(0ull); + QTest::newRow("C: 0") << QStringLiteral("0") << QStringLiteral("C") << true << Integer(0ull); + QTest::newRow("C: 1234") + << QStringLiteral("1234") << QStringLiteral("C") << true << Integer(1234ull); + // C locale omits grouping, but doesn't reject it. + QTest::newRow("C: 1,234") + << QStringLiteral("1,234") << QStringLiteral("C") << true << Integer(1234ull); + QTest::newRow("C: 123456789") + << QStringLiteral("123456789") << QStringLiteral("C") << true << Integer(123456789ull); + QTest::newRow("C: 123,456,789") + << QStringLiteral("123,456,789") + << QStringLiteral("C") << true << Integer(123456789ull); + + QTest::newRow("en: empty") + << QStringLiteral("") << QStringLiteral("en") << false << Integer(0ull); + QTest::newRow("en: 0") + << QStringLiteral("0") << QStringLiteral("en") << true << Integer(0ull); + QTest::newRow("en: 1234") + << QStringLiteral("1234") << QStringLiteral("en") << true << Integer(1234ull); + QTest::newRow("en: 1,234") + << QStringLiteral("1,234") << QStringLiteral("en") << true << Integer(1234ull); + QTest::newRow("en: 123,456,789") + << QStringLiteral("123,456,789") + << QStringLiteral("en") << true << Integer(123456789ull); + QTest::newRow("en: 123456789") + << QStringLiteral("123456789") << QStringLiteral("en") << true << Integer(123456789ull); + + QTest::newRow("de: empty") + << QStringLiteral("") << QStringLiteral("de") << false << Integer(0ull); + QTest::newRow("de: 0") << QStringLiteral("0") << QStringLiteral("de") << true << Integer(0ull); + QTest::newRow("de: 1234") + << QStringLiteral("1234") << QStringLiteral("de") << true << Integer(1234ull); + QTest::newRow("de: 1.234") + << QStringLiteral("1.234") << QStringLiteral("de") << true << Integer(1234ull); + QTest::newRow("de: 123.456.789") + << QStringLiteral("123.456.789") + << QStringLiteral("de") << true << Integer(123456789ull); + QTest::newRow("de: 123456789") + << QStringLiteral("123456789") << QStringLiteral("de") << true << Integer(123456789ull); + + // Locales with non-single-character signs: + QTest::newRow("ar_EG: +403") // Arabic, Egypt + << QStringLiteral("\u061c+\u0664\u0660\u0663") + << QStringLiteral("ar_EG") << true << Integer(403ull); + QTest::newRow("ar_EG: !403") // Only first character of the sign + << QStringLiteral("\u061c\u0664\u0660\u0663") + << QStringLiteral("ar_EG") << false << Integer(0ull); + QTest::newRow("fa_IR: +403") // Farsi, Iran + << QStringLiteral("\u200e+\u06f4\u06f0\u06f3") + << QStringLiteral("fa_IR") << true << Integer(403ull); + QTest::newRow("fa_IR: !403") // Only first character of sign + << QStringLiteral("\u200e\u06f4\u06f0\u06f3") + << QStringLiteral("fa_IR") << false << Integer(0ull); +} + +void tst_QLocale::toLongLong_data() +{ + toWholeCommon_data<qlonglong>(); + + QTest::newRow("C: -1234") << QStringLiteral("-1234") << QStringLiteral("C") << true << -1234ll; + QTest::newRow("C: -123456789") + << QStringLiteral("-123456789") << QStringLiteral("C") << true << -123456789ll; + QTest::newRow("C: qlonglong-max") + << QStringLiteral("9223372036854775807") << QStringLiteral("C") << true + << std::numeric_limits<qlonglong>::max(); + QTest::newRow("C: qlonglong-min") + << QStringLiteral("-9223372036854775808") << QStringLiteral("C") << true + << std::numeric_limits<qlonglong>::min(); + + // Locales with multi-character signs: + QTest::newRow("ar_EG: -403") // Arabic, Egypt + << QStringLiteral("\u061c-\u0664\u0660\u0663") + << QStringLiteral("ar_EG") << true << -403ll; + QTest::newRow("fa_IR: -403") // Farsi, Iran + << QStringLiteral("\u200e\u2212\u06f4\u06f0\u06f3") + << QStringLiteral("fa_IR") << true << -403ll; +} + +void tst_QLocale::toLongLong() +{ + QFETCH(QString, text); + QFETCH(QString, locale); + QFETCH(bool, good); + QFETCH(qlonglong, expected); + + const QLocale loc(locale); + qlonglong actual = expected; + bool ok = false; + QBENCHMARK { + actual = loc.toLongLong(text, &ok); + } + QEXPECT_FAIL("ar_EG: +403", "Code wrongly assumes single character, QTBUG-107801", Abort); + QEXPECT_FAIL("ar_EG: -403", "Code wrongly assumes single character, QTBUG-107801", Abort); + QEXPECT_FAIL("fa_IR: +403", "Code wrongly assumes single character, QTBUG-107801", Abort); + QEXPECT_FAIL("fa_IR: -403", "Code wrongly assumes single character, QTBUG-107801", Abort); + QCOMPARE(ok, good); + QCOMPARE(actual, expected); +} + +void tst_QLocale::toULongLong_data() +{ + toWholeCommon_data<qulonglong>(); + + QTest::newRow("C: qlonglong-max + 1") + << QStringLiteral("9223372036854775808") << QStringLiteral("C") << true + << (qulonglong(std::numeric_limits<qlonglong>::max()) + 1); + QTest::newRow("C: qulonglong-max") + << QStringLiteral("18446744073709551615") << QStringLiteral("C") << true + << std::numeric_limits<qulonglong>::max(); +} + +void tst_QLocale::toULongLong() +{ + QFETCH(QString, text); + QFETCH(QString, locale); + QFETCH(bool, good); + QFETCH(qulonglong, expected); + + const QLocale loc(locale); + qulonglong actual = expected; + bool ok = false; + QBENCHMARK { + actual = loc.toULongLong(text, &ok); + } + QEXPECT_FAIL("ar_EG: +403", "Code wrongly assumes single character, QTBUG-107801", Abort); + QEXPECT_FAIL("fa_IR: +403", "Code wrongly assumes single character, QTBUG-107801", Abort); + QCOMPARE(ok, good); + QCOMPARE(actual, expected); +} + + +void tst_QLocale::toDouble_data() +{ + QTest::addColumn<QString>("text"); + QTest::addColumn<QString>("locale"); + QTest::addColumn<bool>("good"); + QTest::addColumn<double>("expected"); + + QTest::newRow("C: empty") << QStringLiteral("") << QStringLiteral("C") << false << 0.0; + QTest::newRow("C: 0") << QStringLiteral("0") << QStringLiteral("C") << true << 0.0; + QTest::newRow("C: 0.12340") + << QStringLiteral("0.12340") << QStringLiteral("C") << true << 0.12340; + QTest::newRow("C: -0.12340") + << QStringLiteral("-0.12340") << QStringLiteral("C") << true << -0.12340; + QTest::newRow("C: −0.12340") + << QStringLiteral("\u2212" "0.12340") << QStringLiteral("C") << true << -0.12340; + QTest::newRow("C: 1.0e-4") << QStringLiteral("1.0e-4") << QStringLiteral("C") << true << 1.0e-4; + QTest::newRow("C: 1.0e−4") + << QStringLiteral("1.0e\u2212" "4") << QStringLiteral("C") << true << 1.0e-4; + QTest::newRow("C: 1.0e+4") << QStringLiteral("1.0e+4") << QStringLiteral("C") << true << 1.0e+4; + QTest::newRow("C: 10.e+3") << QStringLiteral("10.e+3") << QStringLiteral("C") << true << 1.0e+4; + QTest::newRow("C: 10e+3.") + << QStringLiteral("10e+3.") << QStringLiteral("C") << false << 0.0; // exp...dot + QTest::newRow("C: 1e4") << QStringLiteral("1e4") << QStringLiteral("C") << true << 1.0e+4; + + // NaN and infinity: + QTest::newRow("C: nan") << QStringLiteral("nan") << QStringLiteral("C") << true << qQNaN(); + QTest::newRow("C: NaN") << QStringLiteral("NaN") << QStringLiteral("C") << true << qQNaN(); + QTest::newRow("C: -nan") << QStringLiteral("-nan") << QStringLiteral("C") << false << 0.0; + QTest::newRow("C: +nan") << QStringLiteral("+nan") << QStringLiteral("C") << false << 0.0; + QTest::newRow("C: inf") << QStringLiteral("inf") << QStringLiteral("C") << true << qInf(); + QTest::newRow("C: Inf") << QStringLiteral("Inf") << QStringLiteral("C") << true << qInf(); + QTest::newRow("C: +inf") << QStringLiteral("+inf") << QStringLiteral("C") << true << qInf(); + QTest::newRow("C: -inf") << QStringLiteral("-inf") << QStringLiteral("C") << true << -qInf(); + + // Wantonly long-form representations, with trailing and leading zeros: + QTest::newRow("C: 1e-64 long-form") + << (QStringLiteral("0.") + QString(63, u'0') + u'1' + QString(962, u'0')) + << QStringLiteral("C") << true << 1e-64; + QTest::newRow("C: 1e+64 long-form") + << (QString(961, u'0') + u'1' + QString(64, u'0') + QStringLiteral(".0")) + << QStringLiteral("C") << true << 1e+64; + QTest::newRow("C: long-form 1 via e+64") + << (QStringLiteral("0.") + QString(63, u'0') + u'1' + QString(962, u'0') + + QStringLiteral("e+64")) + << QStringLiteral("C") << true << 1.0; + QTest::newRow("C: long-form 1 via e-64") + << (QString(961, u'0') + u'1' + QString(64, u'0') + QStringLiteral(".0e-64")) + << QStringLiteral("C") << true << 1.0; + QTest::newRow("C: 12345678.9") + << QStringLiteral("12345678.9") << QStringLiteral("C") << true << 12345678.9; + + // With and without grouping, en vs de for flipped separators: + QTest::newRow("en: 12345678.9") + << QStringLiteral("12345678.9") << QStringLiteral("en") << true << 12345678.9; + QTest::newRow("en: 12,345,678.9") + << QStringLiteral("12,345,678.9") << QStringLiteral("en") << true << 12345678.9; + QTest::newRow("de: 12345678,9") + << QStringLiteral("12345678,9") << QStringLiteral("de") << true << 12345678.9; + QTest::newRow("de: 12.345.678,9") + << QStringLiteral("12.345.678,9") << QStringLiteral("de") << true << 12345678.9; + + // NaN and infinity are locale-independent (for now - QTBUG-95460) + QTest::newRow("cy: nan") << QStringLiteral("nan") << QStringLiteral("cy") << true << qQNaN(); + QTest::newRow("cy: NaN") << QStringLiteral("NaN") << QStringLiteral("cy") << true << qQNaN(); + QTest::newRow("cy: -nan") << QStringLiteral("-nan") << QStringLiteral("cy") << false << 0.0; + QTest::newRow("cy: +nan") << QStringLiteral("+nan") << QStringLiteral("cy") << false << 0.0; + QTest::newRow("cy: inf") << QStringLiteral("inf") << QStringLiteral("cy") << true << qInf(); + QTest::newRow("cy: Inf") << QStringLiteral("Inf") << QStringLiteral("cy") << true << qInf(); + QTest::newRow("cy: +inf") << QStringLiteral("+inf") << QStringLiteral("cy") << true << qInf(); + QTest::newRow("cy: -inf") << QStringLiteral("-inf") << QStringLiteral("cy") << true << -qInf(); + // Samples ready for QTBUG-95460: + QTest::newRow("en: ∞") + << QStringLiteral("\u221e") << QStringLiteral("en") << true << qInf(); + QTest::newRow("ga: Nuimh") + << QStringLiteral("Nuimh") << QStringLiteral("ga") << true << qQNaN(); + + // Locales with multi-character exponents: + QTest::newRow("sv_SE: 4e-3") // Swedish, Sweden + << QStringLiteral("4\u00d7" "10^\u2212" "03") + << QStringLiteral("sv_SE") << true << 4e-3; + QTest::newRow("sv_SE: 4x-3") // Only first character of exponent + << QStringLiteral("4\u00d7\u2212" "03") + << QStringLiteral("sv_SE") << false << 0.0; + QTest::newRow("se_NO: 4e-3") // Northern Sami, Norway + << QStringLiteral("4\u00b7" "10^\u2212" "03") + << QStringLiteral("se_NO") << true << 4e-3; + QTest::newRow("se_NO: 4x-3") // Only first character of exponent + << QStringLiteral("4\u00b7\u2212" "03") + << QStringLiteral("se_NO") << false << 0.0; + QTest::newRow("ar_EG: 4e-3") // Arabic, Egypt + << QStringLiteral("\u0664\u0627\u0633\u061c-\u0660\u0663") + << QStringLiteral("ar_EG") << true << 4e-3; + QTest::newRow("ar_EG: 4x-3") // Only first character of exponent + << QStringLiteral("\u0664\u0627\u061c-\u0660\u0663") + << QStringLiteral("ar_EG") << false << 0.0; + QTest::newRow("ar_EG: 4e!3") // Only first character of sign + << QStringLiteral("\u0664\u0627\u0633\u061c\u0660\u0663") + << QStringLiteral("ar_EG") << false << 0.0; + QTest::newRow("ar_EG: 4x!3") // Only first character of sign and exponent + << QStringLiteral("\u0664\u0627\u061c\u0660\u0663") + << QStringLiteral("ar_EG") << false << 0.0; +} + +void tst_QLocale::toDouble() +{ + QFETCH(QString, text); + QFETCH(QString, locale); + QFETCH(bool, good); + QFETCH(double, expected); + + const QLocale loc(locale); + double actual = expected; + bool ok = false; + QBENCHMARK { + actual = loc.toDouble(text, &ok); + } + QEXPECT_FAIL("sv_SE: 4e-3", "Code wrongly assumes single character, QTBUG-107801", Abort); + QEXPECT_FAIL("se_NO: 4e-3", "Code wrongly assumes single character, QTBUG-107801", Abort); + QEXPECT_FAIL("ar_EG: 4e-3", "Code wrongly assumes single character, QTBUG-107801", Abort); + QEXPECT_FAIL("en: ∞", "Localized infinity support missing: QTBUG-95460", Abort); + QEXPECT_FAIL("ga: Nuimh", "Localized NaN support missing: QTBUG-95460", Abort); + QCOMPARE(ok, good); + QCOMPARE(actual, expected); +} + QTEST_MAIN(tst_QLocale) #include "main.moc" diff --git a/tests/benchmarks/corelib/text/qstring/main.cpp b/tests/benchmarks/corelib/text/qstring/main.cpp index 826a843c10..1c7c3d690e 100644 --- a/tests/benchmarks/corelib/text/qstring/main.cpp +++ b/tests/benchmarks/corelib/text/qstring/main.cpp @@ -28,6 +28,7 @@ #include <QStringList> #include <QFile> #include <QtTest/QtTest> +#include <limits> class tst_QString: public QObject { @@ -49,6 +50,14 @@ private slots: void toCaseFolded_data(); void toCaseFolded(); + // Parsing: + void toLongLong_data(); + void toLongLong(); + void toULongLong_data(); + void toULongLong(); + void toDouble_data(); + void toDouble(); + private: void section_data_impl(bool includeRegExOnly = true); template <typename RX> void section_impl(); @@ -188,6 +197,155 @@ void tst_QString::toCaseFolded() } } +template <typename Integer> +void toWholeCommon_data() +{ + QTest::addColumn<QString>("text"); + QTest::addColumn<int>("base"); + QTest::addColumn<bool>("good"); + QTest::addColumn<Integer>("expected"); + + QTest::newRow("empty") << QStringLiteral("") << 10 << false << Integer(0ull); + QTest::newRow("0") << QStringLiteral("0") << 10 << true << Integer(0ull); + QTest::newRow("1234") << QStringLiteral("1234") << 10 << true << Integer(1234ull); + QTest::newRow("1,234") << QStringLiteral("1,234") << 10 << false << Integer(0ull); + QTest::newRow("123456789") + << QStringLiteral("123456789") << 10 << true << Integer(123456789ull); + QTest::newRow("bad1dea, base 16") + << QStringLiteral("bad1dea") << 16 << true << Integer(0xBAD1DEAull); + QTest::newRow("bad1dea, base 10") << QStringLiteral("bad1dea") << 10 << false << Integer(0ull); + QTest::newRow("42, base 13") << QStringLiteral("42") << 13 << true << Integer(6ull * 9ull); + QTest::newRow("242, base 8") << QStringLiteral("242") << 8 << true << Integer(0242ull); + QTest::newRow("495, base 8") << QStringLiteral("495") << 8 << false << Integer(0ull); + QTest::newRow("101101, base 2") + << QStringLiteral("101101") << 2 << true << Integer(0b101101ull); + QTest::newRow("ad, base 30") << QStringLiteral("ad") << 30 << true << Integer(313ull); +} + +void tst_QString::toLongLong_data() +{ + toWholeCommon_data<qlonglong>(); + + QTest::newRow("-1234") << QStringLiteral("-1234") << 10 << true << -1234ll; + QTest::newRow("-123456789") << QStringLiteral("-123456789") << 10 << true << -123456789ll; + QTest::newRow("-bad1dea, base 16") << QStringLiteral("-bad1dea") << 16 << true << -0xBAD1DEAll; + QTest::newRow("-242, base 8") << QStringLiteral("-242") << 8 << true << -0242ll; + QTest::newRow("-101101, base 2") << QStringLiteral("-101101") << 2 << true << -0b101101ll; + QTest::newRow("-ad, base 30") << QStringLiteral("-ad") << 30 << true << -313ll; + + QTest::newRow("qlonglong-max") + << QStringLiteral("9223372036854775807") << 10 << true + << std::numeric_limits<qlonglong>::max(); + QTest::newRow("qlonglong-min") + << QStringLiteral("-9223372036854775808") << 10 << true + << std::numeric_limits<qlonglong>::min(); + QTest::newRow("qlonglong-max, base 2") + << QString(63, u'1') << 2 << true << std::numeric_limits<qlonglong>::max(); + QTest::newRow("qlonglong-min, base 2") + << (QStringLiteral("-1") + QString(63, u'0')) << 2 << true + << std::numeric_limits<qlonglong>::min(); + QTest::newRow("qlonglong-max, base 16") + << (QChar(u'7') + QString(15, u'f')) << 16 << true + << std::numeric_limits<qlonglong>::max(); + QTest::newRow("qlonglong-min, base 16") + << (QStringLiteral("-8") + QString(15, u'0')) << 16 << true + << std::numeric_limits<qlonglong>::min(); +} + +void tst_QString::toLongLong() +{ + QFETCH(QString, text); + QFETCH(int, base); + QFETCH(bool, good); + QFETCH(qlonglong, expected); + + qlonglong actual = expected; + bool ok = false; + QBENCHMARK { + actual = text.toLongLong(&ok, base); + } + QCOMPARE(ok, good); + QCOMPARE(actual, expected); +} + +void tst_QString::toULongLong_data() +{ + toWholeCommon_data<qulonglong>(); + + QTest::newRow("qlonglong-max + 1") + << QStringLiteral("9223372036854775808") << 10 << true + << (qulonglong(std::numeric_limits<qlonglong>::max()) + 1); + QTest::newRow("qulonglong-max") + << QStringLiteral("18446744073709551615") << 10 << true + << std::numeric_limits<qulonglong>::max(); + QTest::newRow("qulonglong-max, base 2") + << QString(64, u'1') << 2 << true << std::numeric_limits<qulonglong>::max(); + QTest::newRow("qulonglong-max, base 16") + << QString(16, u'f') << 16 << true << std::numeric_limits<qulonglong>::max(); +} + +void tst_QString::toULongLong() +{ + QFETCH(QString, text); + QFETCH(int, base); + QFETCH(bool, good); + QFETCH(qulonglong, expected); + + qulonglong actual = expected; + bool ok = false; + QBENCHMARK { + actual = text.toULongLong(&ok, base); + } + QCOMPARE(ok, good); + QCOMPARE(actual, expected); +} + +void tst_QString::toDouble_data() +{ + QTest::addColumn<QString>("text"); + QTest::addColumn<bool>("good"); + QTest::addColumn<double>("expected"); + + QTest::newRow("empty") << QStringLiteral("") << false << 0.0; + QTest::newRow("0") << QStringLiteral("0") << true << 0.0; + QTest::newRow("0.12340") << QStringLiteral("0.12340") << true << 0.12340; + QTest::newRow("-0.12340") << QStringLiteral("-0.12340") << true << -0.12340; + QTest::newRow("epsilon") + << QStringLiteral("2.220446049e-16") << true << std::numeric_limits<double>::epsilon(); + QTest::newRow("1.0e-4") << QStringLiteral("1.0e-4") << true << 1.0e-4; + QTest::newRow("1.0e+4") << QStringLiteral("1.0e+4") << true << 1.0e+4; + QTest::newRow("10.e+3") << QStringLiteral("10.e+3") << true << 1.0e+4; + QTest::newRow("10e+3.") << QStringLiteral("10e+3.") << false << 0.0; + QTest::newRow("1e4") << QStringLiteral("1e4") << true << 1.0e+4; + QTest::newRow("1.0e-8") << QStringLiteral("1.0e-8") << true << 1.0e-8; + QTest::newRow("1.0e+8") << QStringLiteral("1.0e+8") << true << 1.0e+8; + + // NaN and infinity: + QTest::newRow("nan") << QStringLiteral("nan") << true << qQNaN(); + QTest::newRow("NaN") << QStringLiteral("NaN") << true << qQNaN(); + QTest::newRow("-nan") << QStringLiteral("-nan") << false << 0.0; + QTest::newRow("+nan") << QStringLiteral("+nan") << false << 0.0; + QTest::newRow("inf") << QStringLiteral("inf") << true << qInf(); + QTest::newRow("Inf") << QStringLiteral("Inf") << true << qInf(); + QTest::newRow("+inf") << QStringLiteral("+inf") << true << qInf(); + QTest::newRow("-inf") << QStringLiteral("-inf") << true << -qInf(); +} + +void tst_QString::toDouble() +{ + QFETCH(QString, text); + QFETCH(bool, good); + QFETCH(double, expected); + + double actual = expected; + bool ok = false; + QBENCHMARK { + actual = text.toDouble(&ok); + } + QCOMPARE(ok, good); + QCOMPARE(actual, expected); +} + QTEST_APPLESS_MAIN(tst_QString) #include "main.moc" |