diff options
Diffstat (limited to 'tests/auto/corelib/io/qurluts46/tst_qurluts46.cpp')
-rw-r--r-- | tests/auto/corelib/io/qurluts46/tst_qurluts46.cpp | 60 |
1 files changed, 44 insertions, 16 deletions
diff --git a/tests/auto/corelib/io/qurluts46/tst_qurluts46.cpp b/tests/auto/corelib/io/qurluts46/tst_qurluts46.cpp index e36642974a..d163ed19bf 100644 --- a/tests/auto/corelib/io/qurluts46/tst_qurluts46.cpp +++ b/tests/auto/corelib/io/qurluts46/tst_qurluts46.cpp @@ -1,5 +1,5 @@ // Copyright (C) 2021 The Qt Company Ltd. -// 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/QUrl> #include <QtCore/QFile> @@ -16,11 +16,11 @@ private Q_SLOTS: void idnaTestV2(); private: - // All error codes: - // A3, A4_1, A4_2, + // All error codes in UTR #46 revision 31 (Unicode 15.1): + // A4_1, A4_2, // B1, B2, B3, B4, B5, B6, // C1, C2, - // P1, P4, + // P4, // V1, V2, V3, V5, V6, // X4_2 // @@ -28,7 +28,38 @@ private: static const QSet<QByteArray> fatalErrors; }; -const QSet<QByteArray> tst_QUrlUts46::fatalErrors = { "A3", "A4_2", "P1", "X4_2" }; +const QSet<QByteArray> tst_QUrlUts46::fatalErrors = { + "A4_2", // Empty ASCII label +}; + +/** + * Replace \uXXXX escapes in test case fields. + */ +static QString unescapeField(const QString &field) +{ + static const QRegularExpression re(R"(\\u([[:xdigit:]]{4}))"); + + QString result; + qsizetype lastIdx = 0; + + for (const auto &match : re.globalMatch(field)) { + // Add stuff before the match + result.append(field.mid(lastIdx, match.capturedStart() - lastIdx)); + bool ok = false; + auto c = match.captured(1).toUInt(&ok, 16); + if (!ok) { + qFatal("Failed to parse a Unicode escape: %s", qPrintable(match.captured(1))); + } + + result.append(QChar(c)); + lastIdx = match.capturedEnd(); + } + + // Append the unescaped end + result.append(field.mid(lastIdx)); + + return result; +} void tst_QUrlUts46::idnaTestV2_data() { @@ -50,7 +81,7 @@ void tst_QUrlUts46::idnaTestV2_data() Q_ASSERT(s.startsWith('[') && s.endsWith(']')); - const auto errors = s.sliced(1, s.length() - 2).split(','); + const auto errors = s.sliced(1, s.size() - 2).split(','); // NOTE: empty string is not in fatalErrors and it's ok return std::all_of(errors.begin(), errors.end(), [](auto &e) { return !fatalErrors.contains(e.trimmed()); }); @@ -69,7 +100,7 @@ void tst_QUrlUts46::idnaTestV2_data() Q_ASSERT(fields.size() == 7); for (auto &field : fields) - field = field.trimmed(); + field = unescapeField(field.trimmed()).toUtf8(); const QString &source = fields[0]; QString toUnicode = fields[1].isEmpty() ? source : fields[1]; @@ -95,22 +126,19 @@ void tst_QUrlUts46::idnaTestV2() QFETCH(QString, toAsciiT); QFETCH(bool, toAsciiTOk); - auto dashesOk = [](const QString &domain) { - const auto labels = domain.split(u'.'); - return std::all_of(labels.begin(), labels.end(), [](const QString &label) { - return label.isEmpty() || !(label.startsWith(u'-') || label.endsWith(u'-')); - }); - }; - QString toAceN = QUrl::toAce(source); - if (toAsciiNOk && dashesOk(toAsciiN)) + if (toUnicodeOk && toAsciiNOk) QCOMPARE(toAceN, toAsciiN); + else if (toAsciiNOk) + QVERIFY(toAceN.isEmpty() || toAceN == toAsciiN); else QCOMPARE(toAceN, QString()); QString toAceT = QUrl::toAce(source, QUrl::AceTransitionalProcessing); - if (toAsciiTOk && dashesOk(toAsciiT)) + if (toUnicodeOk && toAsciiTOk) QCOMPARE(toAceT, toAsciiT); + else if (toAsciiTOk) + QVERIFY(toAceT.isEmpty() || toAceT == toAsciiT); else QCOMPARE(toAceT, QString()); |