summaryrefslogtreecommitdiffstats
path: root/tests/auto/corelib/io/qurlquery/tst_qurlquery.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/corelib/io/qurlquery/tst_qurlquery.cpp')
-rw-r--r--tests/auto/corelib/io/qurlquery/tst_qurlquery.cpp695
1 files changed, 695 insertions, 0 deletions
diff --git a/tests/auto/corelib/io/qurlquery/tst_qurlquery.cpp b/tests/auto/corelib/io/qurlquery/tst_qurlquery.cpp
new file mode 100644
index 0000000000..4ce621c4ba
--- /dev/null
+++ b/tests/auto/corelib/io/qurlquery/tst_qurlquery.cpp
@@ -0,0 +1,695 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Intel Corporation.
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/QUrlQuery>
+#include <QtTest/QtTest>
+
+typedef QList<QPair<QString, QString> > QueryItems;
+Q_DECLARE_METATYPE(QueryItems)
+Q_DECLARE_METATYPE(QUrl::ComponentFormattingOptions)
+
+class tst_QUrlQuery : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_QUrlQuery()
+ {
+ qRegisterMetaType<QueryItems>();
+ }
+
+private Q_SLOTS:
+ void constructing();
+ void addRemove();
+ void multiAddRemove();
+ void multiplyAddSamePair();
+ void setQueryItems_data();
+ void setQueryItems();
+ void basicParsing_data();
+ void basicParsing();
+ void reconstructQuery_data();
+ void reconstructQuery();
+ void encodedSetQueryItems_data();
+ void encodedSetQueryItems();
+ void encodedParsing_data();
+ void encodedParsing();
+ void differentDelimiters();
+};
+
+static QString prettyElement(const QString &key, const QString &value)
+{
+ QString result;
+ if (key.isNull())
+ result += "null -> ";
+ else
+ result += '"' % key % "\" -> ";
+ if (value.isNull())
+ result += "null";
+ else
+ result += '"' % value % '"';
+ return result;
+}
+
+static QString prettyPair(QList<QPair<QString, QString> >::const_iterator it)
+{
+ return prettyElement(it->first, it->second);
+}
+
+template <typename T>
+static QByteArray prettyList(const T &items)
+{
+ QString result = "(";
+ bool first = true;
+ typename T::const_iterator it = items.constBegin();
+ for ( ; it != items.constEnd(); ++it) {
+ if (!first)
+ result += ", ";
+ first = false;
+ result += prettyPair(it);
+ }
+ result += ")";
+ return result.toLocal8Bit();
+}
+
+static bool compare(const QList<QPair<QString, QString> > &actual, const QueryItems &expected,
+ const char *actualStr, const char *expectedStr, const char *file, int line)
+{
+ return QTest::compare_helper(actual == expected, "Compared values are not the same",
+ qstrdup(prettyList(actual)), qstrdup(prettyList(expected).data()),
+ actualStr, expectedStr, file, line);
+}
+
+#define COMPARE_ITEMS(actual, expected) \
+ do { \
+ if (!compare(actual, expected, #actual, #expected, __FILE__, __LINE__)) \
+ return; \
+ } while (0)
+
+inline QueryItems operator+(QueryItems items, const QPair<QString, QString> &pair)
+{
+ // items is already a copy
+ items.append(pair);
+ return items;
+}
+
+inline QueryItems operator+(const QPair<QString, QString> &pair, QueryItems items)
+{
+ // items is already a copy
+ items.prepend(pair);
+ return items;
+}
+
+inline QPair<QString, QString> qItem(const QString &first, const QString &second)
+{
+ return qMakePair(first, second);
+}
+
+inline QPair<QString, QString> qItem(const char *first, const QString &second)
+{
+ return qMakePair(QString::fromUtf8(first), second);
+}
+
+inline QPair<QString, QString> qItem(const char *first, const char *second)
+{
+ return qMakePair(QString::fromUtf8(first), QString::fromUtf8(second));
+}
+
+inline QPair<QString, QString> qItem(const QString &first, const char *second)
+{
+ return qMakePair(first, QString::fromUtf8(second));
+}
+
+static QUrlQuery emptyQuery()
+{
+ return QUrlQuery();
+}
+
+void tst_QUrlQuery::constructing()
+{
+ QUrlQuery empty;
+ QVERIFY(empty.isEmpty());
+ QCOMPARE(empty.queryPairDelimiter(), QUrlQuery::defaultQueryPairDelimiter());
+ QCOMPARE(empty.queryValueDelimiter(), QUrlQuery::defaultQueryValueDelimiter());
+ // undefined whether it is detached, but don't crash
+ QVERIFY(empty.isDetached() || !empty.isDetached());
+
+ empty.clear();
+ QVERIFY(empty.isEmpty());
+
+ {
+ QUrlQuery copy(empty);
+ QVERIFY(copy.isEmpty());
+ QVERIFY(!copy.isDetached());
+ QVERIFY(copy == empty);
+ QVERIFY(!(copy != empty));
+
+ copy = empty;
+ QVERIFY(copy == empty);
+
+ copy = QUrlQuery();
+ QVERIFY(copy == empty);
+ }
+ {
+ QUrlQuery copy(emptyQuery());
+ QVERIFY(copy == empty);
+ }
+
+ QVERIFY(!empty.hasQueryItem("a"));
+ QVERIFY(empty.queryItemValue("a").isEmpty());
+ QVERIFY(empty.allQueryItemValues("a").isEmpty());
+
+ QVERIFY(!empty.hasQueryItem(""));
+ QVERIFY(empty.queryItemValue("").isEmpty());
+ QVERIFY(empty.allQueryItemValues("").isEmpty());
+
+ QVERIFY(!empty.hasQueryItem(QString()));
+ QVERIFY(empty.queryItemValue(QString()).isEmpty());
+ QVERIFY(empty.allQueryItemValues(QString()).isEmpty());
+
+ QVERIFY(empty.queryItems().isEmpty());
+
+ QUrlQuery other;
+ other.addQueryItem("a", "b");
+ QVERIFY(!other.isEmpty());
+ QVERIFY(other.isDetached());
+ QVERIFY(other != empty);
+ QVERIFY(!(other == empty));
+
+ QUrlQuery copy(other);
+ QVERIFY(copy == other);
+
+ copy.clear();
+ QVERIFY(copy.isEmpty());
+ QVERIFY(copy != other);
+
+ copy = other;
+ QVERIFY(!copy.isEmpty());
+ QVERIFY(copy == other);
+
+ copy = QUrlQuery();
+ QVERIFY(copy.isEmpty());
+
+ empty.setQueryDelimiters('(', ')');
+ QCOMPARE(empty.queryValueDelimiter(), QChar(QLatin1Char('(')));
+ QCOMPARE(empty.queryPairDelimiter(), QChar(QLatin1Char(')')));
+}
+
+void tst_QUrlQuery::addRemove()
+{
+ QUrlQuery query;
+
+ {
+ // one item
+ query.addQueryItem("a", "b");
+ QVERIFY(!query.isEmpty());
+ QVERIFY(query.hasQueryItem("a"));
+ QCOMPARE(query.queryItemValue("a"), QString("b"));
+ QCOMPARE(query.allQueryItemValues("a"), QStringList() << "b");
+
+ QList<QPair<QString, QString> > allItems = query.queryItems();
+ QCOMPARE(allItems.count(), 1);
+ QCOMPARE(allItems.at(0).first, QString("a"));
+ QCOMPARE(allItems.at(0).second, QString("b"));
+ }
+
+ QUrlQuery original = query;
+
+ {
+ // two items
+ query.addQueryItem("c", "d");
+ QVERIFY(query.hasQueryItem("a"));
+ QCOMPARE(query.queryItemValue("a"), QString("b"));
+ QCOMPARE(query.allQueryItemValues("a"), QStringList() << "b");
+ QVERIFY(query.hasQueryItem("c"));
+ QCOMPARE(query.queryItemValue("c"), QString("d"));
+ QCOMPARE(query.allQueryItemValues("c"), QStringList() << "d");
+
+ QList<QPair<QString, QString> > allItems = query.queryItems();
+ QCOMPARE(allItems.count(), 2);
+ QVERIFY(allItems.contains(qItem("a", "b")));
+ QVERIFY(allItems.contains(qItem("c", "d")));
+
+ QVERIFY(query != original);
+ QVERIFY(!(query == original));
+ }
+
+ {
+ // remove an item that isn't there
+ QUrlQuery copy = query;
+ query.removeQueryItem("e");
+ QCOMPARE(query, copy);
+ }
+
+ {
+ // remove an item
+ query.removeQueryItem("c");
+ QVERIFY(query.hasQueryItem("a"));
+ QCOMPARE(query.queryItemValue("a"), QString("b"));
+ QCOMPARE(query.allQueryItemValues("a"), QStringList() << "b");
+
+ QList<QPair<QString, QString> > allItems = query.queryItems();
+ QCOMPARE(allItems.count(), 1);
+ QCOMPARE(allItems.at(0).first, QString("a"));
+ QCOMPARE(allItems.at(0).second, QString("b"));
+
+ QVERIFY(query == original);
+ QVERIFY(!(query != original));
+ }
+
+ {
+ // add an item with en empty value
+ QString emptyButNotNull(0, Qt::Uninitialized);
+ QVERIFY(emptyButNotNull.isEmpty());
+ QVERIFY(!emptyButNotNull.isNull());
+
+ query.addQueryItem("e", "");
+ QVERIFY(query.hasQueryItem("a"));
+ QCOMPARE(query.queryItemValue("a"), QString("b"));
+ QCOMPARE(query.allQueryItemValues("a"), QStringList() << "b");
+ QVERIFY(query.hasQueryItem("e"));
+ QCOMPARE(query.queryItemValue("e"), emptyButNotNull);
+ QCOMPARE(query.allQueryItemValues("e"), QStringList() << emptyButNotNull);
+
+ QList<QPair<QString, QString> > allItems = query.queryItems();
+ QCOMPARE(allItems.count(), 2);
+ QVERIFY(allItems.contains(qItem("a", "b")));
+ QVERIFY(allItems.contains(qItem("e", emptyButNotNull)));
+
+ QVERIFY(query != original);
+ QVERIFY(!(query == original));
+ }
+
+ {
+ // remove the items
+ query.removeQueryItem("a");
+ query.removeQueryItem("e");
+ QVERIFY(query.isEmpty());
+ }
+}
+
+void tst_QUrlQuery::multiAddRemove()
+{
+ QUrlQuery query;
+
+ {
+ // one item, two values
+ query.addQueryItem("a", "b");
+ query.addQueryItem("a", "c");
+ QVERIFY(!query.isEmpty());
+ QVERIFY(query.hasQueryItem("a"));
+
+ // returns the first one
+ QVERIFY(query.queryItemValue("a") == "b");
+
+ // order is the order we set them in
+ QVERIFY(query.allQueryItemValues("a") == QStringList() << "b" << "c");
+ }
+
+ {
+ // add another item, two values
+ query.addQueryItem("A", "B");
+ query.addQueryItem("A", "C");
+ QVERIFY(query.hasQueryItem("A"));
+ QVERIFY(query.hasQueryItem("a"));
+
+ QVERIFY(query.queryItemValue("a") == "b");
+ QVERIFY(query.allQueryItemValues("a") == QStringList() << "b" << "c");
+ QVERIFY(query.queryItemValue("A") == "B");
+ QVERIFY(query.allQueryItemValues("A") == QStringList() << "B" << "C");
+ }
+
+ {
+ // remove one of the original items
+ query.removeQueryItem("a");
+ QVERIFY(query.hasQueryItem("a"));
+
+ // it must have removed the first one
+ QVERIFY(query.queryItemValue("a") == "c");
+ }
+
+ {
+ // remove the items we added later
+ query.removeAllQueryItems("A");
+ QVERIFY(!query.isEmpty());
+ QVERIFY(!query.hasQueryItem("A"));
+ }
+
+ {
+ // add one element to the current, then remove them
+ query.addQueryItem("a", "d");
+ query.removeAllQueryItems("a");
+ QVERIFY(!query.hasQueryItem("a"));
+ QVERIFY(query.isEmpty());
+ }
+}
+
+void tst_QUrlQuery::multiplyAddSamePair()
+{
+ QUrlQuery query;
+ query.addQueryItem("a", "a");
+ query.addQueryItem("a", "a");
+ QCOMPARE(query.allQueryItemValues("a"), QStringList() << "a" << "a");
+
+ query.addQueryItem("a", "a");
+ QCOMPARE(query.allQueryItemValues("a"), QStringList() << "a" << "a" << "a");
+
+ query.removeQueryItem("a");
+ QCOMPARE(query.allQueryItemValues("a"), QStringList() << "a" << "a");
+}
+
+void tst_QUrlQuery::setQueryItems_data()
+{
+ QTest::addColumn<QueryItems>("items");
+ QString emptyButNotNull(0, Qt::Uninitialized);
+
+ QTest::newRow("empty") << QueryItems();
+ QTest::newRow("1-novalue") << (QueryItems() << qItem("a", QString()));
+ QTest::newRow("1-emptyvalue") << (QueryItems() << qItem("a", emptyButNotNull));
+
+ QueryItems list;
+ list << qItem("a", "b");
+ QTest::newRow("1-value") << list;
+ QTest::newRow("1-multi") << (list + qItem("a", "c"));
+ QTest::newRow("1-duplicated") << (list + qItem("a", "b"));
+
+ list << qItem("c", "d");
+ QTest::newRow("2") << list;
+
+ list << qItem("c", "e");
+ QTest::newRow("2-multi") << list;
+}
+
+void tst_QUrlQuery::setQueryItems()
+{
+ QFETCH(QueryItems, items);
+ QUrlQuery query;
+
+ QueryItems::const_iterator it = items.constBegin();
+ for ( ; it != items.constEnd(); ++it)
+ query.addQueryItem(it->first, it->second);
+ COMPARE_ITEMS(query.queryItems(), items);
+
+ query.clear();
+
+ query.setQueryItems(items);
+ COMPARE_ITEMS(query.queryItems(), items);
+}
+
+void tst_QUrlQuery::basicParsing_data()
+{
+ QTest::addColumn<QString>("queryString");
+ QTest::addColumn<QueryItems>("items");
+ QString emptyButNotNull(0, Qt::Uninitialized);
+
+ QTest::newRow("null") << QString() << QueryItems();
+ QTest::newRow("empty") << "" << QueryItems();
+
+ QTest::newRow("1-novalue") << "a" << (QueryItems() << qItem("a", QString()));
+ QTest::newRow("1-emptyvalue") << "a=" << (QueryItems() << qItem("a", emptyButNotNull));
+ QTest::newRow("1-value") << "a=b" << (QueryItems() << qItem("a", "b"));
+
+ // some longer keys
+ QTest::newRow("1-longkey-novalue") << "thisisalongkey" << (QueryItems() << qItem("thisisalongkey", QString()));
+ QTest::newRow("1-longkey-emptyvalue") << "thisisalongkey=" << (QueryItems() << qItem("thisisalongkey", emptyButNotNull));
+ QTest::newRow("1-longkey-value") << "thisisalongkey=b" << (QueryItems() << qItem("thisisalongkey", "b"));
+
+ // longer values
+ QTest::newRow("1-longvalue-value") << "a=thisisalongreasonablyvalue"
+ << (QueryItems() << qItem("a", "thisisalongreasonablyvalue"));
+ QTest::newRow("1-longboth-value") << "thisisalongkey=thisisalongreasonablyvalue"
+ << (QueryItems() << qItem("thisisalongkey", "thisisalongreasonablyvalue"));
+
+ // two or more entries
+ QueryItems baselist;
+ baselist << qItem("a", "b") << qItem("c", "d");
+ QTest::newRow("2-ab-cd") << "a=b&c=d" << baselist;
+ QTest::newRow("2-cd-ab") << "c=d&a=b" << (QueryItems() << qItem("c", "d") << qItem("a", "b"));
+
+ // the same entry multiply defined
+ QTest::newRow("2-a-a") << "a&a" << (QueryItems() << qItem("a", QString()) << qItem("a", QString()));
+ QTest::newRow("2-ab-a") << "a=b&a" << (QueryItems() << qItem("a", "b") << qItem("a", QString()));
+ QTest::newRow("2-ab-ab") << "a=b&a=b" << (QueryItems() << qItem("a", "b") << qItem("a", "b"));
+ QTest::newRow("2-ab-ac") << "a=b&a=c" << (QueryItems() << qItem("a", "b") << qItem("a", "c"));
+
+ QPair<QString, QString> novalue = qItem("somekey", QString());
+ QueryItems list2 = baselist + novalue;
+ QTest::newRow("3-novalue-ab-cd") << "somekey&a=b&c=d" << (novalue + baselist);
+ QTest::newRow("3-ab-novalue-cd") << "a=b&somekey&c=d" << (QueryItems() << qItem("a", "b") << novalue << qItem("c", "d"));
+ QTest::newRow("3-ab-cd-novalue") << "a=b&c=d&somekey" << list2;
+
+ list2 << qItem("otherkeynovalue", QString());
+ QTest::newRow("4-ab-cd-novalue-novalue") << "a=b&c=d&somekey&otherkeynovalue" << list2;
+
+ QPair<QString, QString> emptyvalue = qItem("somekey", emptyButNotNull);
+ list2 = baselist + emptyvalue;
+ QTest::newRow("3-emptyvalue-ab-cd") << "somekey=&a=b&c=d" << (emptyvalue + baselist);
+ QTest::newRow("3-ab-emptyvalue-cd") << "a=b&somekey=&c=d" << (QueryItems() << qItem("a", "b") << emptyvalue << qItem("c", "d"));
+ QTest::newRow("3-ab-cd-emptyvalue") << "a=b&c=d&somekey=" << list2;
+}
+
+void tst_QUrlQuery::basicParsing()
+{
+ QFETCH(QString, queryString);
+ QFETCH(QueryItems, items);
+
+ QUrlQuery query(queryString);
+ QCOMPARE(query.isEmpty(), items.isEmpty());
+ COMPARE_ITEMS(query.queryItems(), items);
+}
+
+void tst_QUrlQuery::reconstructQuery_data()
+{
+ QTest::addColumn<QString>("queryString");
+ QTest::addColumn<QueryItems>("items");
+ QString emptyButNotNull(0, Qt::Uninitialized);
+
+ QTest::newRow("null") << QString() << QueryItems();
+ QTest::newRow("empty") << "" << QueryItems();
+
+ QTest::newRow("1-novalue") << "a" << (QueryItems() << qItem("a", QString()));
+ QTest::newRow("1-emptyvalue") << "a=" << (QueryItems() << qItem("a", emptyButNotNull));
+ QTest::newRow("1-value") << "a=b" << (QueryItems() << qItem("a", "b"));
+
+ // some longer keys
+ QTest::newRow("1-longkey-novalue") << "thisisalongkey" << (QueryItems() << qItem("thisisalongkey", QString()));
+ QTest::newRow("1-longkey-emptyvalue") << "thisisalongkey=" << (QueryItems() << qItem("thisisalongkey", emptyButNotNull));
+ QTest::newRow("1-longkey-value") << "thisisalongkey=b" << (QueryItems() << qItem("thisisalongkey", "b"));
+
+ // longer values
+ QTest::newRow("1-longvalue-value") << "a=thisisalongreasonablyvalue"
+ << (QueryItems() << qItem("a", "thisisalongreasonablyvalue"));
+ QTest::newRow("1-longboth-value") << "thisisalongkey=thisisalongreasonablyvalue"
+ << (QueryItems() << qItem("thisisalongkey", "thisisalongreasonablyvalue"));
+
+ // two or more entries
+ QueryItems baselist;
+ baselist << qItem("a", "b") << qItem("c", "d");
+ QTest::newRow("2-ab-cd") << "a=b&c=d" << baselist;
+
+ // the same entry multiply defined
+ QTest::newRow("2-a-a") << "a&a" << (QueryItems() << qItem("a", QString()) << qItem("a", QString()));
+ QTest::newRow("2-ab-ab") << "a=b&a=b" << (QueryItems() << qItem("a", "b") << qItem("a", "b"));
+ QTest::newRow("2-ab-ac") << "a=b&a=c" << (QueryItems() << qItem("a", "b") << qItem("a", "c"));
+ QTest::newRow("2-ac-ab") << "a=c&a=b" << (QueryItems() << qItem("a", "c") << qItem("a", "b"));
+ QTest::newRow("2-ab-cd") << "a=b&c=d" << (QueryItems() << qItem("a", "b") << qItem("c", "d"));
+ QTest::newRow("2-cd-ab") << "c=d&a=b" << (QueryItems() << qItem("c", "d") << qItem("a", "b"));
+
+ QueryItems list2 = baselist + qItem("somekey", QString());
+ QTest::newRow("3-ab-cd-novalue") << "a=b&c=d&somekey" << list2;
+
+ list2 << qItem("otherkeynovalue", QString());
+ QTest::newRow("4-ab-cd-novalue-novalue") << "a=b&c=d&somekey&otherkeynovalue" << list2;
+
+ list2 = baselist + qItem("somekey", emptyButNotNull);
+ QTest::newRow("3-ab-cd-emptyvalue") << "a=b&c=d&somekey=" << list2;
+}
+
+void tst_QUrlQuery::reconstructQuery()
+{
+ QFETCH(QString, queryString);
+ QFETCH(QueryItems, items);
+
+ QUrlQuery query;
+
+ // add the items
+ for (QueryItems::ConstIterator it = items.constBegin(); it != items.constEnd(); ++it) {
+ query.addQueryItem(it->first, it->second);
+ }
+ QCOMPARE(query.query(), queryString);
+}
+
+void tst_QUrlQuery::encodedSetQueryItems_data()
+{
+ QTest::addColumn<QString>("queryString");
+ QTest::addColumn<QString>("key");
+ QTest::addColumn<QString>("value");
+ QTest::addColumn<QUrl::ComponentFormattingOptions>("encoding");
+ QTest::addColumn<QString>("expectedQuery");
+ QTest::addColumn<QString>("expectedKey");
+ QTest::addColumn<QString>("expectedValue");
+ typedef QUrl::ComponentFormattingOptions F;
+
+ QTest::newRow("nul") << "f%00=bar%00" << "f%00" << "bar%00" << F(QUrl::PrettyDecoded)
+ << "f%00=bar%00" << "f%00" << "bar%00";
+ QTest::newRow("non-decodable-1") << "foo%01%7f=b%1ar" << "foo%01%7f" << "b%1ar" << F(QUrl::PrettyDecoded)
+ << "foo%01%7F=b%1Ar" << "foo%01%7F" << "b%1Ar";
+ QTest::newRow("non-decodable-2") << "foo\x01\x7f=b\x1ar" << "foo\x01\x7f" << "b\x1Ar" << F(QUrl::PrettyDecoded)
+ << "foo%01%7F=b%1Ar" << "foo%01%7F" << "b%1Ar";
+
+ QTest::newRow("space") << "%20=%20" << "%20" << "%20" << F(QUrl::PrettyDecoded)
+ << " = " << " " << " ";
+ QTest::newRow("encode-space") << " = " << " " << " " << F(QUrl::FullyEncoded)
+ << "%20=%20" << "%20" << "%20";
+
+ QTest::newRow("non-delimiters") << "%3C%5C%3E=%7B%7C%7D%5E%60" << "%3C%5C%3E" << "%7B%7C%7D%5E%60" << F(QUrl::PrettyDecoded)
+ << "<\\>={|}^`" << "<\\>" << "{|}^`";
+ QTest::newRow("encode-non-delimiters") << "<\\>={|}^`" << "<\\>" << "{|}^`" << F(QUrl::FullyEncoded)
+ << "%3C%5C%3E=%7B%7C%7D%5E%60" << "%3C%5C%3E" << "%7B%7C%7D%5E%60";
+
+ QTest::newRow("equals") << "%3D=%3D" << "%3D" << "%3D" << F(QUrl::PrettyDecoded)
+ << "%3D=%3D" << "=" << "=";
+ QTest::newRow("equals-2") << "%3D==" << "=" << "=" << F(QUrl::PrettyDecoded)
+ << "%3D=%3D" << "=" << "=";
+ QTest::newRow("ampersand") << "%26=%26" << "%26" << "%26" << F(QUrl::PrettyDecoded)
+ << "%26=%26" << "&" << "&";
+ QTest::newRow("hash") << "#=#" << "%23" << "%23" << F(QUrl::PrettyDecoded)
+ << "%23=%23" << "#" << "#";
+ QTest::newRow("decode-hash") << "%23=%23" << "%23" << "%23" << F(QUrl::DecodeAllDelimiters)
+ << "#=#" << "#" << "#";
+
+ QTest::newRow("percent") << "%25=%25" << "%25" << "%25" << F(QUrl::PrettyDecoded)
+ << "%25=%25" << "%25" << "%25";
+ QTest::newRow("bad-percent-1") << "%=%" << "%" << "%" << F(QUrl::PrettyDecoded)
+ << "%25=%25" << "%25" << "%25";
+ QTest::newRow("bad-percent-2") << "%2=%2" << "%2" << "%2" << F(QUrl::PrettyDecoded)
+ << "%252=%252" << "%252" << "%252";
+
+ QTest::newRow("plus") << "+=+" << "+" << "+" << F(QUrl::PrettyDecoded)
+ << "+=+" << "+" << "+";
+ QTest::newRow("2b") << "%2b=%2b" << "%2b" << "%2b" << F(QUrl::PrettyDecoded)
+ << "%2B=%2B" << "%2B" << "%2B";
+ // plus signs must not be touched
+ QTest::newRow("encode-plus") << "+=+" << "+" << "+" << F(QUrl::FullyEncoded)
+ << "+=+" << "+" << "+";
+ QTest::newRow("decode-2b") << "%2b=%2b" << "%2b" << "%2b" << F(QUrl::DecodeAllDelimiters)
+ << "%2B=%2B" << "%2B" << "%2B";
+
+
+ QTest::newRow("unicode") << "q=R%C3%a9sum%c3%A9" << "q" << "R%C3%a9sum%c3%A9" << F(QUrl::PrettyDecoded)
+ << QString::fromUtf8("q=R\xc3\xa9sum\xc3\xa9") << "q" << QString::fromUtf8("R\xc3\xa9sum\xc3\xa9");
+ QTest::newRow("encode-unicode") << QString::fromUtf8("q=R\xc3\xa9sum\xc3\xa9") << "q" << QString::fromUtf8("R\xc3\xa9sum\xc3\xa9")
+ << F(QUrl::FullyEncoded)
+ << "q=R%C3%A9sum%C3%A9" << "q" << "R%C3%A9sum%C3%A9";
+}
+
+void tst_QUrlQuery::encodedSetQueryItems()
+{
+ QFETCH(QString, key);
+ QFETCH(QString, value);
+ QFETCH(QString, expectedQuery);
+ QFETCH(QString, expectedKey);
+ QFETCH(QString, expectedValue);
+ QFETCH(QUrl::ComponentFormattingOptions, encoding);
+ QUrlQuery query;
+
+ query.addQueryItem(key, value);
+ COMPARE_ITEMS(query.queryItems(encoding), QueryItems() << qItem(expectedKey, expectedValue));
+ QCOMPARE(query.query(encoding), expectedQuery);
+}
+
+void tst_QUrlQuery::encodedParsing_data()
+{
+ encodedSetQueryItems_data();
+}
+
+void tst_QUrlQuery::encodedParsing()
+{
+ QFETCH(QString, queryString);
+ QFETCH(QString, expectedQuery);
+ QFETCH(QString, expectedKey);
+ QFETCH(QString, expectedValue);
+ QFETCH(QUrl::ComponentFormattingOptions, encoding);
+
+ QUrlQuery query(queryString);
+ COMPARE_ITEMS(query.queryItems(encoding), QueryItems() << qItem(expectedKey, expectedValue));
+ QCOMPARE(query.query(encoding), expectedQuery);
+}
+
+void tst_QUrlQuery::differentDelimiters()
+{
+ QUrlQuery query;
+ query.setQueryDelimiters('(', ')');
+
+ {
+ // parse:
+ query.setQuery("foo(bar)hello(world)");
+
+ QueryItems expected;
+ expected << qItem("foo", "bar") << qItem("hello", "world");
+ COMPARE_ITEMS(query.queryItems(), expected);
+ COMPARE_ITEMS(query.queryItems(QUrl::FullyEncoded), expected);
+ COMPARE_ITEMS(query.queryItems(QUrl::DecodeAllDelimiters), expected);
+ }
+
+ {
+ // reconstruct:
+ // note the final ')' is missing because there are no further items
+ QCOMPARE(query.query(), QString("foo(bar)hello(world"));
+ }
+
+ {
+ // set items containing the new delimiters and the old ones
+ query.clear();
+ query.addQueryItem("z(=)", "y(&)");
+ QCOMPARE(query.query(), QString("z%28=%29(y%28&%29"));
+
+ QUrlQuery copy = query;
+ QCOMPARE(query.query(), QString("z%28=%29(y%28&%29"));
+
+ copy.setQueryDelimiters(QUrlQuery::defaultQueryValueDelimiter(),
+ QUrlQuery::defaultQueryPairDelimiter());
+ QCOMPARE(copy.query(), QString("z(%3D)=y(%26)"));
+ }
+}
+
+QTEST_APPLESS_MAIN(tst_QUrlQuery)
+
+#include "tst_qurlquery.moc"