File indexing completed on 2022-11-29 18:25:19

0001 // krazy:excludeall=qclasses
0002 /* This file is part of the KDE libraries
0003     Copyright (c) 1999-2005 Waldo Bastian <bastian@kde.org>
0004     Copyright (c) 2000-2005 David Faure <faure@kde.org>
0005 
0006     This library is free software; you can redistribute it and/or
0007     modify it under the terms of the GNU Library General Public
0008     License version 2 as published by the Free Software Foundation.
0009 
0010     This library is distributed in the hope that it will be useful,
0011     but WITHOUT ANY WARRANTY; without even the implied warranty of
0012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0013     Library General Public License for more details.
0014 
0015     You should have received a copy of the GNU Library General Public License
0016     along with this library; see the file COPYING.LIB.  If not, write to
0017     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0018     Boston, MA 02110-1301, USA.
0019 */
0020 
0021 #include "kurltest.h"
0022 
0023 #include <QTest>
0024 
0025 QTEST_MAIN(KUrlTest)
0026 
0027 #include "kurl.h"
0028 
0029 #include "kuser.h"
0030 
0031 #include <QTextCodec>
0032 #include <QDataStream>
0033 #include <QMap>
0034 #include <QDebug>
0035 #include <unistd.h> // gethostname
0036 
0037 //QCOMPARE cannot be used to strictly check for empty or null QString as it treats QString("") == QString()
0038 #define QSTREMPTY(_str) QVERIFY(!_str.isNull() && _str.isEmpty())
0039 
0040 void KUrlTest::testEmptyURL()
0041 {
0042     KUrl emptyURL;
0043     QVERIFY(!emptyURL.isValid());
0044     QVERIFY(emptyURL.isEmpty());
0045     QVERIFY(emptyURL.prettyUrl().isEmpty());
0046     QCOMPARE(emptyURL.url(), QString());
0047     QVERIFY(emptyURL.url().isEmpty());
0048     QVERIFY(!emptyURL.url().isNull());   // well, a null string would be correct too...
0049     QVERIFY(!emptyURL.isLocalFile());
0050 
0051     KUrl emptyStringURL("");
0052     QVERIFY(!emptyStringURL.isValid());
0053     QVERIFY(emptyStringURL.isEmpty());
0054     QVERIFY(emptyStringURL.url().isEmpty());
0055     QVERIFY(!emptyStringURL.url().isNull());
0056     QCOMPARE(emptyURL, emptyStringURL);
0057 
0058     // Roundtrip via .url()
0059     KUrl emptyCopy(emptyURL.url());
0060     QCOMPARE(emptyURL, emptyCopy);
0061     KUrl emptyStringCopy = KUrl(emptyStringURL.url());
0062     QCOMPARE(emptyStringURL, emptyCopy);
0063 
0064     KUrl fileURL("file:/");
0065     QVERIFY(!fileURL.isEmpty());
0066 
0067     fileURL = "file:///";
0068     QVERIFY(!fileURL.isEmpty());
0069 
0070     fileURL = QLatin1String("FILE:///");
0071     QVERIFY(fileURL.isLocalFile());
0072 
0073     KUrl udir;
0074     QCOMPARE(udir.url(), QString());
0075     QVERIFY(udir.isEmpty());
0076     QVERIFY(!udir.isValid());
0077     udir = udir.upUrl();
0078     QVERIFY(udir.upUrl().isEmpty());
0079 }
0080 
0081 void KUrlTest::testIsValid()
0082 {
0083     KUrl url1("gg:www.kde.org");
0084     QVERIFY(url1.isValid());
0085 
0086     url1 = "KDE";
0087     QVERIFY(url1.isValid());   // KDE3 difference: was FALSE
0088 
0089     url1 = "$HOME/.kde/share/config";
0090     QVERIFY(url1.isValid());   // KDE3 difference: was FALSE
0091 }
0092 
0093 void KUrlTest::testSetQuery()
0094 {
0095     KUrl url1 = KUrl(QByteArray("http://www.kde.org/foo.cgi?foo=bar"));
0096     QCOMPARE(url1.query(), QString("?foo=bar"));
0097     url1.setQuery("toto=titi&kde=rocks");
0098     QCOMPARE(url1.query(), QString("?toto=titi&kde=rocks"));
0099     url1.setQuery("?kde%20rocks&a=b");   // must be encoded already, as documented
0100     QCOMPARE(url1.query(), QString("?kde%20rocks&a=b"));   // encoded, as documented
0101     url1.setQuery("?");
0102     QCOMPARE(url1.query(), QString("?"));
0103     url1.setQuery("");
0104     QCOMPARE(url1.query(), QString("?"));
0105     url1.setQuery(QString());
0106     QCOMPARE(url1.query(), QString());
0107 
0108     url1.setQuery("4=2+2");
0109     QCOMPARE(url1.url(), QString("http://www.kde.org/foo.cgi?4=2+2"));
0110     QCOMPARE(url1.query(), QString("?4=2+2"));
0111     url1.setQuery("4=2%2B2");
0112     QCOMPARE(url1.url(), QString("http://www.kde.org/foo.cgi?4=2%2B2"));  // %2B should not be decoded to +
0113     QCOMPARE(url1.query(), QString("?4=2%2B2"));
0114 }
0115 
0116 void KUrlTest::testEmptyNullReference()
0117 {
0118     KUrl url1 = KUrl("http://www.kde.org");
0119     QVERIFY(!url1.hasRef());
0120     QVERIFY(!url1.hasHTMLRef());
0121     QVERIFY(url1.ref().isNull());
0122     QVERIFY(url1.htmlRef().isNull());
0123     QVERIFY(url1.encodedHtmlRef().isNull());
0124 
0125     url1 = "http://www.kde.org#";
0126     QVERIFY(url1.hasRef());
0127     QVERIFY(url1.hasHTMLRef());
0128     QSTREMPTY(url1.ref());
0129     QSTREMPTY(url1.htmlRef());
0130     QSTREMPTY(url1.encodedHtmlRef());
0131 }
0132 
0133 void KUrlTest::testSetRef()
0134 {
0135     KUrl url1 = KUrl(QByteArray("http://www.kde.org/foo.cgi#foo=bar"));
0136     QCOMPARE(url1.ref(), QString("foo=bar"));    // KDE3: was foo=bar, KDE4 (until 4.11): foo%3Dbar, KF5 (Qt5.2): foo=bar
0137 #if 0// ditto (TODO)
0138     url1.setRef("toto=titi&kde=rocks");
0139     QCOMPARE(url1.ref(), QString("toto=titi&kde=rocks"));
0140     url1.setRef("kde=rocks&a=b");
0141     QCOMPARE(url1.ref(), QString("kde=rocks&a=b"));
0142     url1.setRef("#");
0143     QCOMPARE(url1.ref(), QString("#"));
0144 #endif
0145     url1.setRef("");
0146     QSTREMPTY(url1.ref());
0147     QCOMPARE(url1.url(), QString("http://www.kde.org/foo.cgi#"));
0148 
0149     url1.setRef(QString());
0150     QVERIFY(url1.ref().isNull());
0151     QCOMPARE(url1.url(), QString("http://www.kde.org/foo.cgi"));
0152 }
0153 
0154 void KUrlTest::testSetHTMLRef()
0155 {
0156     KUrl url1 = KUrl(QByteArray("http://www.kde.org/foo.cgi#foo=bar"));
0157     QCOMPARE(url1.htmlRef(), QString("foo=bar"));
0158     url1.setHTMLRef("toto=titi&kde=rocks");
0159     QCOMPARE(url1.htmlRef(), QString("toto=titi&kde=rocks"));
0160     url1.setHTMLRef("kde=rocks&a=b");
0161     QCOMPARE(url1.htmlRef(), QString("kde=rocks&a=b"));
0162     url1.setHTMLRef("#");
0163     QCOMPARE(url1.htmlRef(), QString("#"));
0164     QCOMPARE(url1.ref(), QString("%23"));   // it's encoded
0165     url1.setHTMLRef("");
0166     QSTREMPTY(url1.htmlRef());
0167     QCOMPARE(url1.url(), QString("http://www.kde.org/foo.cgi#"));
0168 
0169     url1.setHTMLRef(QString());
0170     QVERIFY(url1.htmlRef().isNull());
0171     QCOMPARE(url1.url(), QString("http://www.kde.org/foo.cgi"));
0172 }
0173 
0174 void KUrlTest::testQUrl()
0175 {
0176     QUrl url1("file:///home/dfaure/my#%2f");
0177     // Qt 4.0 to 4.4: #/. Qt 4.5: %2f again.
0178     // Qt 5.0 & 5.1: #/. Qt 5.2: %2F again (probably due to 2ff719de8fe7a in qtbase)
0179     // See also testSimpleMethods below, for the KUrl history of it.
0180     QCOMPARE(url1.toString(), QString("file:///home/dfaure/my#%2F"));
0181 
0182 #ifdef Q_OS_WIN
0183     QUrl url2("file:///c:/home/dfaure/my#%2f");
0184     QCOMPARE(url2.toString(), QString("file:///c:/home/dfaure/my#/"));
0185 #endif
0186 
0187     // Show how toString() was confusing in Qt4, and fixed in Qt5
0188     QUrl url3 = QUrl::fromLocalFile("/home/dfaure/hash#file");
0189     QCOMPARE(url3.toString(), QString("file:///home/dfaure/hash%23file"));
0190     QString url3Str = url3.toString();
0191     QUrl url4(url3Str);
0192     QCOMPARE(url4.toString(), url3Str);
0193     QVERIFY(url3 == url4);
0194 }
0195 
0196 void KUrlTest::testIsLocalFile()
0197 {
0198     KUrl trash("trash:/");
0199     QVERIFY(!trash.isLocalFile());
0200 
0201     KUrl local_file_1("file://localhost/my/file");
0202     QVERIFY(local_file_1.isLocalFile());
0203 
0204     KUrl local_file_2("file://www.kde.org/my/file");
0205     QVERIFY(!local_file_2.isLocalFile());
0206 
0207 #if 0
0208     // exactly like in kurl.cpp, getenv("HOSTNAME") can be different...
0209     char hostname[ 256 ];
0210     hostname[ 0 ] = '\0';
0211     if (!gethostname(hostname, 255)) {
0212         hostname[sizeof(hostname) - 1] = '\0';
0213     }
0214 
0215     for (char *p = hostname; *p; p++) {
0216         *p = tolower(*p);
0217     }
0218 
0219     KUrl local_file_3;
0220     local_file_3.setHost(QString::fromLatin1(hostname));
0221     local_file_3.setPath("/my/file");
0222     qDebug("URL=%s", qPrintable(local_file_3.url()));
0223     QVERIFY(local_file_3.isLocalFile());
0224 #endif
0225 
0226     KUrl local_file_4("file:///my/file");
0227     QVERIFY(local_file_4.isLocalFile());
0228 
0229 #ifdef Q_OS_WIN
0230     KUrl local_file_4a("file:///c:/my/file");
0231     QVERIFY(local_file_4a.isLocalFile());
0232 #endif
0233 
0234     KUrl local_file_5;
0235     local_file_5.setPath("/foo?bar");
0236     QCOMPARE(local_file_5.url(), QString("file:///foo%3Fbar"));
0237 
0238 #ifdef Q_OS_WIN
0239     KUrl local_file_5a;
0240     local_file_5a.setPath("c:/foo?bar");
0241     QCOMPARE(local_file_5a.url(), QString("file:///c:/foo%3Fbar"));
0242 #endif
0243 
0244     KUrl scummos("inf://localhost/test.txt");
0245     QVERIFY(!scummos.isLocalFile());
0246 }
0247 
0248 void KUrlTest::testSimpleMethods() // to test parsing, mostly
0249 {
0250     KUrl kde("http://www.kde.org");
0251     QVERIFY(kde.isValid());
0252     QCOMPARE(kde.port(), -1);   // KDE3 DIFFERENCE: was 0.
0253 
0254     KUrl mlc("http://mlc:80/");
0255     QVERIFY(mlc.isValid());
0256     QCOMPARE(mlc.port(), 80);
0257     QCOMPARE(mlc.path(), QString("/"));
0258 
0259     KUrl ulong("https://swww.gad.de:443/servlet/CookieAccepted?MAIL=s@gad.de&VER=25901");
0260     QCOMPARE(ulong.host(), QString("swww.gad.de"));
0261     QCOMPARE(ulong.path(), QString("/servlet/CookieAccepted"));
0262 
0263     // RFC 3986 section 3.5 says:
0264     // fragment = *( pchar / "/" / "?" )
0265     // where:
0266     // pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
0267     //         unreserved  = ALPHA / DIGIT / "-" / "." / "_" / "~"
0268     //         pct-encoded = "%" HEXDIG HEXDIG
0269     //         sub-delims  = sub-delims  = "!" / "$" / "&" / "'" / "(" / ")" /  "*" / "+" / "," / ";" / "="
0270     KUrl url0;
0271     url0 = QString("http://www.kde.org#/?:@-._~!$&'()*+,;="); // These fragment's chars should not be %-encoded
0272     QCOMPARE(url0.ref(),     QString("/?:@-._~!$&'()*+,;="));
0273     QCOMPARE(url0.htmlRef(), QString("/?:@-._~!$&'()*+,;="));
0274     QCOMPARE(url0.url(), QString("http://www.kde.org#/?:@-._~!$&'()*+,;="));
0275 
0276     url0 = QString("http://www.kde.org#/?:@-._~!$&'()*+,;=%A");
0277     QCOMPARE(url0.ref(),     QString("/?:@-._~!$&'()*+,;=%25A"));
0278     QCOMPARE(url0.htmlRef(), QString("/?:@-._~!$&'()*+,;=%A"));
0279     QCOMPARE(url0.url(), QString("http://www.kde.org#/?:@-._~!$&'()*+,;=%25A"));
0280 
0281     url0 = "http://www.kde.org/foo.cgi?4=2+2";
0282     QCOMPARE(url0.url(), QString("http://www.kde.org/foo.cgi?4=2+2"));
0283     url0 = "http://www.kde.org/foo.cgi?4=2%2B2";
0284     QCOMPARE(url0.url(), QString("http://www.kde.org/foo.cgi?4=2%2B2"));    // %2B should not be decoded to +
0285 
0286     KUrl fileURL("file:///home/dfaure/myfile");
0287     QCOMPARE(fileURL.url(), QString("file:///home/dfaure/myfile"));
0288     QCOMPARE(fileURL.path(), QString("/home/dfaure/myfile"));
0289     QVERIFY(!fileURL.hasRef());
0290 
0291     QString u1 = "file:/home/dfaure/my#myref";
0292     KUrl url1(u1);
0293     // KDE3 difference: QUrl doesn't resolve file:/ into file:///
0294     QCOMPARE(url1.url(), QString("file:///home/dfaure/my#myref"));
0295     QVERIFY(url1.hasRef());
0296     QVERIFY(url1.hasHTMLRef());
0297     QVERIFY(!url1.hasSubUrl());
0298     QCOMPARE(url1.htmlRef(), QString("myref"));
0299     QCOMPARE(url1.upUrl().url(), QString("file:///home/dfaure/"));
0300 
0301 #if 0
0302     QUrl qurl = QUrl::fromEncoded("file:///home/dfaure/my#%23");
0303     printf("toString = %s\n", qurl.toString().toLatin1().constData());
0304     printf("toEncoded = %s\n", qurl.toEncoded().data());
0305     qurl = QUrl::fromEncoded("file:///home/dfaure/my#%2f");
0306     printf("toString = %s\n", qurl.toString().toLatin1().constData());
0307     printf("toEncoded = %s\n", qurl.toEncoded().data());
0308     qurl = QUrl::fromEncoded("file:///home/dfaure/my#/");
0309     printf("toString = %s\n", qurl.toString().toLatin1().constData());
0310     printf("toEncoded = %s\n", qurl.toEncoded().data());
0311 #endif
0312 
0313     u1 = "file:///home/dfaure/my#%2f";
0314     url1 = u1;
0315     // KDE3: was %2f, Qt-4.0 to 4.4: #/. 4.5: %2f again. 5.0 to 5.1: #/. 5.2: %2F.
0316     // (see also testQUrl)
0317     QCOMPARE(url1.url(), QString("file:///home/dfaure/my#%2F"));
0318     QVERIFY(url1.hasRef());
0319     QVERIFY(url1.hasHTMLRef());
0320     QVERIFY(!url1.hasSubUrl());
0321     QCOMPARE(url1.ref().toLower(), QString("%2f"));
0322     QCOMPARE(url1.encodedHtmlRef().toLower(), QString("%2f"));
0323     QCOMPARE(url1.htmlRef(), QString("/"));
0324 
0325     u1 = "file:///home/dfaure/my#%23";
0326     url1 = u1;
0327     QCOMPARE(url1.url(), QString("file:///home/dfaure/my#%23"));   // KDE4: #%23. Qt 5.0/5.1 had "##", fixed in c615dcc4416.
0328     QVERIFY(url1.hasRef());
0329     QVERIFY(url1.hasHTMLRef());
0330     QVERIFY(!url1.hasSubUrl());
0331     QCOMPARE(url1.ref(), QString("%23"));
0332     QCOMPARE(url1.encodedHtmlRef(), QString("%23"));
0333     QCOMPARE(url1.htmlRef(), QString("#"));
0334 
0335     url1 = KUrl(url1, "#%6a");
0336     QCOMPARE(url1.url(), QString("file:///home/dfaure/my#j"));
0337     QVERIFY(url1.hasRef());
0338     QVERIFY(url1.hasHTMLRef());
0339     QVERIFY(!url1.hasSubUrl());
0340     QCOMPARE(url1.ref(), QString("j"));
0341     QCOMPARE(url1.encodedHtmlRef(), QString("j"));
0342     QCOMPARE(url1.htmlRef(), QString("j"));
0343 
0344     url1 = KUrl(url1, "#");
0345     QCOMPARE(url1.url(), QString("file:///home/dfaure/my#"));
0346     QVERIFY(url1.hasRef());
0347     QVERIFY(url1.hasHTMLRef());
0348     QVERIFY(!url1.hasSubUrl());
0349     QSTREMPTY(url1.ref());
0350     QSTREMPTY(url1.encodedHtmlRef());
0351     QSTREMPTY(url1.htmlRef());
0352 
0353     u1 = "file:///home/dfaure/my#myref";
0354     url1 = u1;
0355     QCOMPARE(url1.url(), QString("file:///home/dfaure/my#myref"));
0356     QVERIFY(url1.hasRef());
0357     QVERIFY(url1.hasHTMLRef());
0358     QVERIFY(!url1.hasSubUrl());
0359     QCOMPARE(url1.htmlRef(), QString("myref"));
0360     QCOMPARE(url1.upUrl().url(), QString("file:///home/dfaure/"));
0361 
0362     u1 = "file:/opt/kde2/qt2/doc/html/showimg-main-cpp.html#QObject::connect";
0363     url1 = u1;
0364     QCOMPARE(url1.url(), QString("file:///opt/kde2/qt2/doc/html/showimg-main-cpp.html#QObject::connect"));
0365     QVERIFY(url1.hasRef());
0366     QVERIFY(url1.hasHTMLRef());
0367     QVERIFY(!url1.hasSubUrl());
0368     QCOMPARE(url1.ref(), QString("QObject::connect"));   // used to be %3A%3A but there's not point in encoding that here.
0369     QCOMPARE(url1.htmlRef(), QString("QObject::connect"));
0370     QCOMPARE(url1.upUrl().url(), QString("file:///opt/kde2/qt2/doc/html/"));
0371 
0372     u1 = "file:///opt/kde2/qt2/doc/html/showimg-main-cpp.html#QObject::connect";
0373     url1 = u1;
0374     QCOMPARE(url1.url(), QString("file:///opt/kde2/qt2/doc/html/showimg-main-cpp.html#QObject::connect"));
0375     QVERIFY(url1.hasRef());
0376     QVERIFY(url1.hasHTMLRef());
0377     QVERIFY(!url1.hasSubUrl());
0378     QCOMPARE(url1.ref(), QString("QObject::connect"));   // see above
0379     QCOMPARE(url1.htmlRef(), QString("QObject::connect"));
0380     QCOMPARE(url1.upUrl().url(), QString("file:///opt/kde2/qt2/doc/html/"));
0381 
0382     u1 = "file:/opt/kde2/qt2/doc/html/showimg-main-cpp.html#QObject:connect";
0383     url1 = u1;
0384     QCOMPARE(url1.url(), QString("file:///opt/kde2/qt2/doc/html/showimg-main-cpp.html#QObject:connect"));
0385     QVERIFY(url1.hasRef());
0386     QVERIFY(url1.hasHTMLRef());
0387     QVERIFY(!url1.hasSubUrl());
0388     QCOMPARE(url1.ref(), QString("QObject:connect"));   // see above
0389     QCOMPARE(url1.htmlRef(), QString("QObject:connect"));
0390     QCOMPARE(url1.upUrl().url(), QString("file:///opt/kde2/qt2/doc/html/"));
0391 
0392     KUrl carsten;
0393     carsten.setPath("/home/gis/src/kde/kdelibs/kfile/.#kfiledetailview.cpp.1.18");
0394     QCOMPARE(carsten.path(), QString("/home/gis/src/kde/kdelibs/kfile/.#kfiledetailview.cpp.1.18"));
0395 
0396     KUrl longUserName("http://thisisaverylongusername@foobar.com/");
0397     QCOMPARE(longUserName.prettyUrl(), QString("http://thisisaverylongusername@foobar.com/"));
0398     QCOMPARE(KUrl(longUserName.prettyUrl()).url(), QString("http://thisisaverylongusername@foobar.com/"));
0399     KUrl whitespaceInUser("http://www.google.com%20%20%20%20%20@foobar.com/");
0400     QCOMPARE(whitespaceInUser.prettyUrl(), QString("http://www.google.com%20%20%20%20%20@foobar.com/"));
0401     KUrl whitespaceInPath("http://www.google.com/foo%20bar/");
0402     QCOMPARE(whitespaceInPath.prettyUrl(), QString("http://www.google.com/foo bar/"));
0403     KUrl whitespaceInPath2("http://www.google.com/foo%20%20%20%20%20%20%20bar/");
0404     QCOMPARE(whitespaceInPath2.prettyUrl(), QString("http://www.google.com/foo%20%20%20%20%20%20 bar/"));
0405 
0406     KUrl charles;
0407     charles.setPath("/home/charles/foo%20moo");
0408     QCOMPARE(charles.path(), QString("/home/charles/foo%20moo"));
0409     KUrl charles2("file:/home/charles/foo%20moo");
0410     QCOMPARE(charles2.path(), QString("/home/charles/foo moo"));
0411 
0412     //NOTE this test should be ran in UTF8 locale
0413     KUrl percentEncodedQuery("http://mail.yandex.ru/message_part/%D0%9A%D1%80%D0%B8%D1%82%D0%B5%D1%80%D0%B8%D0%B8%20%D0%BE%D1%86%D0%B5%D0%BD%D0%B8%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F%20%D0%BE%D1%80%D0%BB%D0%BE%D0%B2%D0%BE%D0%B9.rar?hid=1.1&mid=391.56424458.99241672611486679803334485488&name=%D0%9A%D1%80%D0%B8%D1%82%D0%B5%D1%80%D0%B8%D0%B8%20%D0%BE%D1%86%D0%B5%D0%BD%D0%B8%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F%20%D0%BE%D1%80%D0%BB%D0%BE%D0%B2%D0%BE%D0%B9.rar");
0414     QCOMPARE(percentEncodedQuery.prettyUrl(), QString::fromUtf8("http://mail.yandex.ru/message_part/Критерии оценивания орловой.rar?hid=1.1&mid=391.56424458.99241672611486679803334485488&name=%D0%9A%D1%80%D0%B8%D1%82%D0%B5%D1%80%D0%B8%D0%B8%20%D0%BE%D1%86%D0%B5%D0%BD%D0%B8%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F%20%D0%BE%D1%80%D0%BB%D0%BE%D0%B2%D0%BE%D0%B9.rar"));
0415 
0416 #ifdef Q_OS_WIN
0417 #ifdef Q_CC_MSVC
0418 #pragma message ("port KUser")
0419 #else
0420 #warning port KUser
0421 #endif
0422 #else
0423     KUrl tilde;
0424     KUser currentUser;
0425     const QString userName = currentUser.loginName();
0426     QVERIFY(!userName.isEmpty());
0427     tilde.setPath(QString::fromUtf8("~%1/Matériel").arg(userName));
0428     QString homeDir = currentUser.homeDir();
0429     QEXPECT_FAIL("", "No more user-expansion in KUrl", Continue);
0430     QCOMPARE(tilde.url(), QString("file://%1/Mat%C3%A9riel").arg(homeDir));
0431 
0432     QUrl httpTilde("http://foo.bar/index.html");
0433     httpTilde.setPath("/~slajsjdlsjd/test.html");
0434     QVERIFY2(httpTilde.isValid(), qPrintable(httpTilde.errorString()));
0435     QCOMPARE(httpTilde.toString(), QString("http://foo.bar/~slajsjdlsjd/test.html"));
0436 #endif
0437 }
0438 
0439 void KUrlTest::testHostName()
0440 {
0441     KUrl u1("http://www.Abc.de/FR");
0442     QCOMPARE(u1.host(), QString("www.abc.de")); // lowercase
0443     QCOMPARE(u1.path(), QString("/FR")); // lowercase
0444     QCOMPARE(u1.url(), QString("http://www.abc.de/FR")); // hostname is lowercase
0445     QCOMPARE(u1.prettyUrl(), QString("http://www.abc.de/FR")); // hostname is lowercase
0446 
0447     KUrl u2;
0448     u2.setProtocol("http");
0449     u2.setHost("www.Abc.de");
0450     QCOMPARE(u2.host(), QString("www.abc.de")); // lowercase
0451     QCOMPARE(u2.url(), QString("http://www.abc.de")); // lowercase
0452 
0453     KUrl u3("donkey://Abc/DE");
0454     QCOMPARE(u3.host(), QString("abc")); // lowercase
0455     QCOMPARE(u3.url(), QString("donkey://abc/DE")); // lowercase
0456 }
0457 
0458 void KUrlTest::testEmptyQueryOrRef()
0459 {
0460     QUrl url = QUrl::fromEncoded("http://www.kde.org");
0461     QCOMPARE(url.toEncoded(), QByteArray("http://www.kde.org"));
0462     QCOMPARE(url.encodedQuery(), QByteArray());
0463     url = QUrl::fromEncoded("http://www.kde.org?");
0464     QCOMPARE(url.toEncoded(), QByteArray("http://www.kde.org?"));
0465     QCOMPARE(url.encodedQuery(), QByteArray());   // note that QByteArray() == QByteArray("")
0466 
0467     url = QUrl::fromEncoded("http://www.kde.org");
0468     QVERIFY(url.encodedQuery().isEmpty());
0469     QVERIFY(!url.hasQuery());
0470     url = QUrl::fromEncoded("http://www.kde.org?");
0471     QVERIFY(!url.encodedQuery().isNull());
0472     QVERIFY(url.encodedQuery().isEmpty());
0473     QVERIFY(url.hasQuery());
0474 
0475     KUrl noQuery("http://www.kde.org");
0476     QCOMPARE(noQuery.query(), QString());   // query at all
0477     QVERIFY(!noQuery.hasQuery());
0478     QVERIFY(!noQuery.hasRef());
0479     QVERIFY(noQuery.ref().isNull());
0480 
0481     // Empty queries should be preserved!
0482     QUrl qurl = QUrl::fromEncoded("http://www.kde.org/cgi/test.cgi?", QUrl::TolerantMode);
0483     QCOMPARE(qurl.toEncoded(), QByteArray("http://www.kde.org/cgi/test.cgi?"));
0484 
0485     KUrl waba1("http://www.kde.org/cgi/test.cgi?");
0486     QCOMPARE(waba1.url(), QString("http://www.kde.org/cgi/test.cgi?"));
0487     QCOMPARE(waba1.query(), QString("?"));     // empty query
0488     QVERIFY(waba1.hasQuery());
0489 
0490     // Empty references should be preserved
0491     waba1 = "http://www.kde.org/cgi/test.cgi#";
0492     QCOMPARE(waba1.url(), QString("http://www.kde.org/cgi/test.cgi#"));
0493     QVERIFY(waba1.hasRef());
0494     QVERIFY(waba1.hasFragment());
0495     QVERIFY(waba1.hasHTMLRef());
0496     QSTREMPTY(waba1.encodedHtmlRef());
0497     //qurl = QUrl::fromEncoded("http://www.kde.org/cgi/test.cgi#", QUrl::TolerantMode);
0498     //QCOMPARE( qurl.toEncoded(), QByteArray("http://www.kde.org/cgi/test.cgi#") );
0499 
0500     KUrl tobi1("http://host.net/path/?#http://broken-adsfk-poij31-029mu-2890zupyc-*!*'O-+-0i");
0501     QCOMPARE(tobi1.query(), QString("?")); // query is empty
0502     QVERIFY(tobi1.hasQuery());
0503 
0504     tobi1 = "http://host.net/path/#no-query";
0505     QCOMPARE(tobi1.query(), QString("")); // no query
0506     QVERIFY(!tobi1.hasQuery());
0507 }
0508 
0509 void KUrlTest::testParsingTolerance()
0510 {
0511     // URLs who forgot to encode spaces in the query - the QUrl version first
0512     QUrl incorrectEncoded = QUrl::fromEncoded("http://www.kde.org/cgi/qurl.cgi?hello=My Value");
0513     QVERIFY(incorrectEncoded.isValid());
0514     QVERIFY(!incorrectEncoded.toEncoded().isEmpty());
0515     //qDebug( "%s", incorrectEncoded.toEncoded().data() );
0516     QCOMPARE(incorrectEncoded.toEncoded(),
0517              QByteArray("http://www.kde.org/cgi/qurl.cgi?hello=My%20Value"));
0518 
0519     // URLs who forgot to encode spaces in the query.
0520     KUrl waba1("http://www.kde.org/cgi/test.cgi?hello=My Value");
0521     //QVERIFY( waba1.isValid() );
0522     QCOMPARE(waba1.url(), QString("http://www.kde.org/cgi/test.cgi?hello=My%20Value"));
0523 
0524     // URL with ':' in query (':' should NOT be encoded!)
0525     waba1 = "http://www.kde.org/cgi/test.cgi?hello:My Value";
0526     QCOMPARE(waba1.url(), QString("http://www.kde.org/cgi/test.cgi?hello:My%20Value"));
0527     QCOMPARE(waba1.upUrl().url(), QString("http://www.kde.org/cgi/test.cgi"));
0528 
0529     // URLs who forgot to encode spaces in the query.
0530     waba1 = "http://www.kde.org/cgi/test.cgi?hello=My Value+20";
0531     QCOMPARE(waba1.url(), QString("http://www.kde.org/cgi/test.cgi?hello=My%20Value+20"));
0532 }
0533 
0534 void KUrlTest::testNewLine()
0535 {
0536     QUrl qurl_newline_1 = QUrl::fromEncoded("http://www.foo.bar/foo/bar\ngnork", QUrl::TolerantMode);
0537     QVERIFY(qurl_newline_1.isValid());
0538     QCOMPARE(qurl_newline_1.toEncoded(), QByteArray("http://www.foo.bar/foo/bar%0Agnork"));
0539 
0540     KUrl url_newline_1("http://www.foo.bar/foo/bar\ngnork");
0541     QCOMPARE(url_newline_1.url(), QLatin1String("http://www.foo.bar/foo/bar%0Agnork"));
0542 
0543     KUrl url_newline_2("http://www.foo.bar/foo?bar\ngnork");
0544     QCOMPARE(url_newline_2.url(), QLatin1String("http://www.foo.bar/foo?bar%0Agnork"));
0545 }
0546 
0547 void KUrlTest::testQueryParsing()
0548 {
0549     KUrl ldap("ldap://host.com:6666/o=University%20of%20Michigan,c=US??sub?(cn=Babs%20Jensen)");
0550     QCOMPARE(ldap.host(), QString("host.com"));
0551     QCOMPARE(ldap.port(), 6666);
0552     QCOMPARE(ldap.path(), QString("/o=University of Michigan,c=US"));
0553     QCOMPARE(ldap.query(), QString("??sub?(cn=Babs%20Jensen)"));
0554     QCOMPARE(ldap.url(), QString("ldap://host.com:6666/o=University%20of%20Michigan,c=US??sub?(cn=Babs%20Jensen)"));
0555     ldap.setQuery("??sub?(cn=Karl%20Marx)");
0556     QCOMPARE(ldap.query(), QString("??sub?(cn=Karl%20Marx)"));
0557     QCOMPARE(ldap.url(), QString("ldap://host.com:6666/o=University%20of%20Michigan,c=US??sub?(cn=Karl%20Marx)"));
0558 }
0559 
0560 void KUrlTest::testURLsWithoutPath()
0561 {
0562     // Urls without path (BR21387)
0563     KUrl waba1("http://meine.db24.de?link=home_c_login_login");   // has query
0564     QCOMPARE(waba1.url(), QString("http://meine.db24.de?link=home_c_login_login"));
0565     QCOMPARE(waba1.path(), QString(""));
0566     QCOMPARE(waba1.query(), QString("?link=home_c_login_login"));
0567 
0568     waba1 = "http://a:389?b=c"; // has port and query
0569     QCOMPARE(waba1.url(), QString("http://a:389?b=c"));
0570     QCOMPARE(waba1.host(), QString("a"));
0571     QCOMPARE(waba1.port(), 389);
0572     QCOMPARE(waba1.path(), QString(""));
0573     QCOMPARE(waba1.query(), QString("?b=c"));
0574 
0575     // Urls without path (BR21387)
0576     waba1 = "http://meine.db24.de#link=home_c_login_login"; // has fragment
0577     QCOMPARE(waba1.url(), QString("http://meine.db24.de#link=home_c_login_login"));
0578     QCOMPARE(waba1.path(), QString(""));
0579 
0580     waba1 = "http://a:389#b=c"; // has port and fragment
0581     //qDebug( "%s", qPrintable( waba1.url() ) );
0582     QCOMPARE(waba1.scheme(), QString("http"));
0583     QCOMPARE(waba1.url(), QString("http://a:389#b=c"));
0584     QCOMPARE(waba1.host(), QString("a"));
0585     QCOMPARE(waba1.port(), 389);
0586     QCOMPARE(waba1.path(), QString(""));
0587     QCOMPARE(waba1.ref(), QString("b=c"));     // see testSetRef(), this changed over time
0588     QCOMPARE(waba1.htmlRef(), QString("b=c"));
0589     QCOMPARE(waba1.query(), QString());
0590 
0591     QUrl schemeOnly("ftp:");
0592     QVERIFY(schemeOnly.isValid());
0593     QCOMPARE(schemeOnly.scheme(), QString("ftp"));
0594 }
0595 
0596 void KUrlTest::testPathAndQuery()
0597 {
0598 #if 0
0599     // this KDE3 test fails, but Tobias Anton didn't say where it came from, and Andreas Hanssen (TT) says:
0600     // "I can't see any reason to support this; it looks like a junk artifact from older days.
0601     // Everything after # is the fragment. Parsing what comes after # is broken; tolerant or not."
0602     KUrl tobi0("http://some.host.net/path/to/file#fragmentPrecedes?theQuery");
0603     QCOMPARE(tobi0.ref(), QString("fragmentPrecedes"));
0604     QCOMPARE(tobi0.query(), QString("?theQuery"));
0605 #else
0606     // So we treat it as part of the fragment
0607     KUrl tobi0("http://some.host.net/path/to/file#foo?bar");
0608     QCOMPARE(tobi0.ref(), QString("foo?bar"));   // was foo%3Fbar until KDE 4.11, but no need to encode it (Qt 5.2)
0609     QCOMPARE(tobi0.query(), QString());
0610     QCOMPARE(tobi0.prettyUrl(), QString("http://some.host.net/path/to/file#foo?bar"));
0611 #endif
0612 
0613     KUrl tobi1("http://host.net/path?myfirstquery#andsomeReference");
0614     tobi1.setEncodedPathAndQuery("another/path/?another&query");
0615     QCOMPARE(tobi1.query(), QString("?another&query"));
0616     QCOMPARE(tobi1.path(), QString("another/path/"));   // with trailing slash
0617     QCOMPARE(tobi1.encodedPathAndQuery(), QString("another/path/?another&query"));
0618     tobi1.setEncodedPathAndQuery("another/path?another&query");
0619     QCOMPARE(tobi1.query(), QString("?another&query"));
0620     QCOMPARE(tobi1.path(), QString("another/path"));   // without trailing slash
0621     QCOMPARE(tobi1.encodedPathAndQuery(), QString("another/path?another&query"));
0622     tobi1.setEncodedPathAndQuery("and%20another%2Bpath%2E?bug=%2B258301&query%2Bword");
0623     QCOMPARE(tobi1.query(), QString("?bug=%2B258301&query%2Bword"));   // encoded
0624     QCOMPARE(tobi1.queryItem("bug"), QString("+258301"));   // decoded
0625     QCOMPARE(tobi1.path(), QString("and another+path."));   // decoded
0626     QCOMPARE(tobi1.encodedPath().constData(), "and%20another+path.");   // from QUrl. It only encodes the space.
0627     QCOMPARE(tobi1.encodedPathAndQuery(), QString("and%20another+path.?bug=%2B258301&query%2Bword"));
0628 
0629     tobi1 = "http://host.net/path/#no-query";
0630     QCOMPARE(tobi1.encodedPathAndQuery(), QString("/path/"));
0631 
0632     KUrl kde("http://www.kde.org");
0633     QCOMPARE(kde.encodedPathAndQuery(), QString(""));
0634     QCOMPARE(kde.encodedPathAndQuery(KUrl::LeaveTrailingSlash, KUrl::AvoidEmptyPath), QString("/"));
0635 
0636     KUrl theKow("http://www.google.de/search?q=frerich&hlx=xx&hl=de&empty=&lr=lang+de&test=%2B%20%3A%25");
0637     QCOMPARE(theKow.encodedPathAndQuery(), QString("/search?q=frerich&hlx=xx&hl=de&empty=&lr=lang+de&test=%2B%20%3A%25"));
0638 
0639     KUrl uloc("file:///home/dfaure/konqtests/Mat%C3%A9riel");
0640     QCOMPARE(uloc.encodedPathAndQuery(), QString("/home/dfaure/konqtests/Mat%C3%A9riel"));
0641 
0642     KUrl urlWithAccent("file:///home/dfaure/konqtests/Matériel");
0643     QCOMPARE(urlWithAccent.encodedPathAndQuery(), QString("/home/dfaure/konqtests/Mat%C3%A9riel"));
0644 
0645     KUrl urlWithUnicodeChar(QString::fromUtf8("file:///home/dfaure/konqtests/Matériel"));
0646     QCOMPARE(urlWithUnicodeChar.encodedPathAndQuery(), QString("/home/dfaure/konqtests/Mat%C3%A9riel"));
0647 
0648     KUrl maelcum(QString::fromUtf8("http://a.b.c/äöu"));
0649     QCOMPARE(maelcum.encodedPathAndQuery(), QString("/%C3%A4%C3%B6u"));
0650 
0651     // This gives an encoded path in Qt5. TODO: find again where this came from (Gof, obviously, in 2009)
0652     //KUrl gof("file:%2Ftmp%2Fkde-ogoffart%2Fkmail"); // weird URL, but well ;)
0653     //QCOMPARE(gof.path(), QString("/tmp/kde-ogoffart/kmail"));
0654 }
0655 
0656 void KUrlTest::testUpUrl()
0657 {
0658     KUrl url1("ftp://user%40host.com@ftp.host.com/var/www/");
0659     QCOMPARE(url1.user(), QString("user@host.com"));
0660     QCOMPARE(url1.host(), QString("ftp.host.com"));
0661     KUrl up = url1.upUrl();
0662     QCOMPARE(up.url(), QString("ftp://user%40host.com@ftp.host.com/var/"));
0663     up = up.upUrl();
0664     QCOMPARE(up.url(), QString("ftp://user%40host.com@ftp.host.com/"));
0665     up = up.upUrl();
0666     QCOMPARE(up.url(), QString("ftp://user%40host.com@ftp.host.com/"));   // unchanged
0667 
0668     // Going up from a relative url is not supported (#170695)
0669     KUrl invalid("tmp");
0670     QVERIFY(invalid.isValid());
0671     up = invalid.upUrl();
0672     QVERIFY(!up.isValid());
0673 }
0674 
0675 void KUrlTest::testSetFileName() // and addPath
0676 {
0677     KUrl u2("file:/home/dfaure/my%20tar%20file.tgz#gzip:/#tar:/README");
0678     //qDebug( "* URL is %s", qPrintable( u2.url() ) );
0679 
0680     u2.setFileName("myfile.txt");
0681     QCOMPARE(u2.url(), QString("file:///home/dfaure/myfile.txt"));
0682     u2.setFileName("myotherfile.txt");
0683     QCOMPARE(u2.url(), QString("file:///home/dfaure/myotherfile.txt"));
0684 
0685     // more tricky, renaming a directory (kpropertiesdialog.cc)
0686     QString tmpurl = "file:/home/dfaure/myolddir/";
0687     if (tmpurl.at(tmpurl.length() - 1) == '/')
0688         // It's a directory, so strip the trailing slash first
0689     {
0690         tmpurl.truncate(tmpurl.length() - 1);
0691     }
0692     KUrl newUrl(tmpurl);
0693     newUrl.setFileName("mynewdir");
0694     QCOMPARE(newUrl.url(), QString("file:///home/dfaure/mynewdir"));
0695 
0696     // addPath tests
0697     newUrl.addPath("subdir");
0698     QCOMPARE(newUrl.url(), QString("file:///home/dfaure/mynewdir/subdir"));
0699     newUrl.addPath("/foo/");
0700     QCOMPARE(newUrl.url(), QString("file:///home/dfaure/mynewdir/subdir/foo/"));
0701     u2 = "http://www.kde.org"; // no path
0702     u2.addPath("subdir");
0703     QCOMPARE(u2.url(), QString("http://www.kde.org/subdir"));
0704     u2.addPath("");
0705     QCOMPARE(u2.url(), QString("http://www.kde.org/subdir"));   // unchanged
0706 
0707     QUrl qurl2 = QUrl::fromEncoded("print:/specials/Print%20To%20File%20(PDF%252FAcrobat)", QUrl::TolerantMode);
0708     QCOMPARE(qurl2.path(), QString::fromLatin1("/specials/Print To File (PDF%2FAcrobat)"));
0709     QCOMPARE(qurl2.path(QUrl::PrettyDecoded), QString::fromLatin1("/specials/Print To File (PDF%252FAcrobat)"));
0710     QCOMPARE(qurl2.toString(), QString::fromLatin1("print:/specials/Print To File (PDF%252FAcrobat)"));
0711     QCOMPARE(qurl2.toEncoded(), QByteArray("print:/specials/Print%20To%20File%20(PDF%252FAcrobat)"));
0712 
0713     // even more tricky
0714     u2 = "print:/specials/Print%20To%20File%20(PDF%252FAcrobat)";
0715     QCOMPARE(u2.path(), QString("/specials/Print To File (PDF%2FAcrobat)"));
0716     QCOMPARE(u2.fileName(), QString("Print To File (PDF%2FAcrobat)"));
0717     u2.setFileName("");
0718     QCOMPARE(u2.url(), QString("print:/specials/"));
0719 
0720     u2 = "file:/specials/Print";
0721     QCOMPARE(u2.path(), QString("/specials/Print"));
0722     QCOMPARE(u2.fileName(), QString("Print"));
0723     u2.setFileName("");
0724     QCOMPARE(u2.url(), QString("file:///specials/"));
0725 
0726     const char *u3 = "ftp://host/dir1/dir2/myfile.txt";
0727     QVERIFY(!KUrl(u3).hasSubUrl());
0728 
0729     KUrl::List lst = KUrl::split(KUrl(u3));
0730     QCOMPARE(lst.count(), 1);
0731     QCOMPARE(lst.first().url(), QString("ftp://host/dir1/dir2/myfile.txt"));
0732 
0733     // cdUp code
0734     KUrl lastUrl = lst.last();
0735     QString dir = lastUrl.directory();
0736     QCOMPARE(dir, QString("/dir1/dir2"));
0737 
0738     // files without directories
0739     KUrl singleFile("foo.txt");
0740     QCOMPARE(singleFile.path(), QString("foo.txt"));
0741     QCOMPARE(singleFile.pathOrUrl(), QString("foo.txt"));
0742 
0743     QString pre;
0744 #ifdef Q_OS_WIN
0745     // On Windows we explicitly prepend a slash, see KUrl::setPath
0746     pre = '/';
0747 #endif
0748     singleFile.setFileName("bar.bin");
0749     QCOMPARE(singleFile.path(), QString(pre + "bar.bin"));
0750     QCOMPARE(singleFile.pathOrUrl(), QString(pre + "bar.bin"));
0751 }
0752 
0753 void KUrlTest::testDirectory()
0754 {
0755     KUrl udir;
0756     udir.setPath("/home/dfaure/file.txt");
0757     //qDebug( "URL is %s", qPrintable( udir.url() ) );
0758     QCOMPARE(udir.path(), QString("/home/dfaure/file.txt"));
0759     QCOMPARE(udir.url(), QString("file:///home/dfaure/file.txt"));
0760     QCOMPARE(udir.directory(KUrl::AppendTrailingSlash | KUrl::ObeyTrailingSlash), QString("/home/dfaure/"));
0761     QCOMPARE(udir.directory(KUrl::ObeyTrailingSlash), QString("/home/dfaure"));
0762 
0763     KUrl u2(QByteArray("file:///home/dfaure/"));
0764     // not ignoring trailing slash
0765     QCOMPARE(u2.directory(KUrl::AppendTrailingSlash | KUrl::ObeyTrailingSlash), QString("/home/dfaure/"));
0766     QCOMPARE(u2.directory(KUrl::ObeyTrailingSlash), QString("/home/dfaure"));
0767     // ignoring trailing slash
0768     QCOMPARE(u2.directory(KUrl::AppendTrailingSlash), QString("/home/"));
0769     QCOMPARE(u2.directory(), QString("/home"));
0770 
0771     // cleanPath() tests (before cd() since cd uses that)
0772     u2.cleanPath();
0773     QCOMPARE(u2.url(), QString("file:///home/dfaure/"));
0774     u2.addPath("/..//foo");
0775     QCOMPARE(u2.url(), QString("file:///home/dfaure/..//foo"));
0776     u2 = KUrl(QByteArray("file:///home/dfaure/..//foo"));
0777     QCOMPARE(u2.url(), QString("file:///home/dfaure/..//foo"));
0778     u2.cleanPath(KUrl::KeepDirSeparators);
0779     QCOMPARE(u2.url(), QString("file:///home//foo"));
0780     u2.cleanPath(KUrl::SimplifyDirSeparators);
0781     QCOMPARE(u2.url(), QString("file:///home/foo"));
0782 
0783     // cd() tests
0784     u2.cd("..");
0785     QCOMPARE(u2.url(), QString("file:///home"));
0786     u2.cd("thomas");
0787     QCOMPARE(u2.url(), QString("file:///home/thomas"));
0788     u2.cd("../");
0789     QCOMPARE(u2.url(), QString("file:///home/"));
0790     u2.cd("/opt/kde/bin/");
0791     QCOMPARE(u2.url(), QString("file:///opt/kde/bin/"));
0792     u2 = "ftp://ftp.kde.org/";
0793     u2.cd("pub");
0794     QCOMPARE(u2.url(), QString("ftp://ftp.kde.org/pub"));
0795     u2 = u2.upUrl();
0796     QCOMPARE(u2.url(), QString("ftp://ftp.kde.org/"));
0797 }
0798 
0799 void KUrlTest::testPrettyURL()
0800 {
0801     KUrl tildeInPath("http://ferret.lmh.ox.ac.uk/%7Ekdecvs/");
0802     QCOMPARE(tildeInPath.prettyUrl(), QString("http://ferret.lmh.ox.ac.uk/~kdecvs/"));
0803     // Tilde should not be re-encoded, see end of 2.3 in rfc3986
0804     QCOMPARE(KUrl(tildeInPath.prettyUrl()).url(), QString("http://ferret.lmh.ox.ac.uk/~kdecvs/"));
0805 
0806     KUrl spaceInPath("file:/home/test/directory%20with%20spaces");
0807     QCOMPARE(spaceInPath.prettyUrl(), QString("file:///home/test/directory with spaces"));
0808     QCOMPARE(KUrl(spaceInPath.prettyUrl()).url(), QString("file:///home/test/directory%20with%20spaces"));
0809 
0810     KUrl plusInPath("http://slashdot.org/~RAMMS%2BEIN/"); // #232008
0811     QCOMPARE(plusInPath.prettyUrl(), QString::fromLatin1("http://slashdot.org/~RAMMS+EIN/"));
0812     QCOMPARE(KUrl(plusInPath.prettyUrl()).url(), QString::fromLatin1("http://slashdot.org/~RAMMS+EIN/"));
0813 
0814     KUrl notPretty3("fish://foo/%23README%23");
0815     QCOMPARE(notPretty3.path(), QString("/#README#"));
0816     QCOMPARE(notPretty3.prettyUrl(), QString("fish://foo/%23README%23"));
0817 
0818     KUrl url15581("http://alain.knaff.linux.lu/bug-reports/kde/spaces in url.html");
0819     QCOMPARE(url15581.prettyUrl(), QString("http://alain.knaff.linux.lu/bug-reports/kde/spaces in url.html"));
0820     QCOMPARE(url15581.url(), QString("http://alain.knaff.linux.lu/bug-reports/kde/spaces%20in%20url.html"));
0821 
0822     KUrl newLineInQuery("http://localhost/?a=foo%0A%0Abar%20baz&b=foo%0Abar%21%3F");
0823     QCOMPARE(newLineInQuery.prettyUrl(), QString("http://localhost/?a=foo%0A%0Abar%20baz&b=foo%0Abar%21%3F"));
0824     KUrl nonUtf8Query("http://kde.org/?a=test%C2%A0foo%A0%A0%A0%A0bar");
0825     QCOMPARE(nonUtf8Query.prettyUrl(), QString("http://kde.org/?a=test%C2%A0foo%A0%A0%A0%A0bar"));
0826 
0827     // KDE3 test was for parsing "percentage%in%url.html", but this is not supported; too broken.
0828     KUrl url15581bis("http://alain.knaff.linux.lu/bug-reports/kde/percentage%25in%25url.html");
0829     QCOMPARE(url15581bis.prettyUrl(), QString("http://alain.knaff.linux.lu/bug-reports/kde/percentage%25in%25url.html"));
0830     QCOMPARE(url15581bis.url(), QString("http://alain.knaff.linux.lu/bug-reports/kde/percentage%25in%25url.html"));
0831 
0832     KUrl urlWithPass("ftp://user:password@ftp.kde.org/path");
0833     QCOMPARE(urlWithPass.pass(), QString::fromLatin1("password"));
0834     QCOMPARE(urlWithPass.prettyUrl(), QString::fromLatin1("ftp://user@ftp.kde.org/path"));
0835 
0836     KUrl urlWithPassAndNoUser("ftp://:password@ftp.kde.org/path");
0837     QCOMPARE(urlWithPassAndNoUser.pass(), QString::fromLatin1("password"));
0838     QCOMPARE(urlWithPassAndNoUser.prettyUrl(), QString::fromLatin1("ftp://ftp.kde.org/path"));
0839 
0840     KUrl xmppUri("xmpp:ogoffart@kde.org");
0841     QCOMPARE(xmppUri.path(), QString::fromLatin1("ogoffart@kde.org"));
0842     QCOMPARE(xmppUri.prettyUrl(), QString::fromLatin1("xmpp:ogoffart@kde.org"));
0843 
0844     QUrl offEagleqUrl;
0845     offEagleqUrl.setEncodedUrl("http://www.sejlsport.dk/Pr%F8v%20noget%20nyt%20dokumenter.pdf", QUrl::TolerantMode);
0846     const QString offEaglePath = offEagleqUrl.path();
0847     QCOMPARE((int)offEaglePath.at(2).unicode(), (int)'r');
0848 #if 0 // CURRENTLY BROKEN, PENDING PRETTYURL REWRITE AND QT-4.5 (in thiago's hands)
0849     QCOMPARE((int)offEaglePath.at(3).unicode(), (int)0xf8);
0850 
0851     KUrl offEagle("http://www.sejlsport.dk/graphics/ds/DSUngdom/PDF/Pr%F8v%20noget%20nyt%20dokumenter/Invitation_Kerteminde_11.07.08.pdf");
0852     QCOMPARE(offEagle.path(), QString::fromLatin1("/graphics/ds/DSUngdom/PDF/Pr%F8v noget nyt dokumenter/Invitation_Kerteminde_11.07.08.pdf"));
0853     QCOMPARE(offEagle.url(), QString::fromLatin1("http://www.sejlsport.dk/graphics/ds/DSUngdom/PDF/Pr%F8v%20noget%20nyt%20dokumenter/Invitation_Kerteminde_11.07.08.pdf"));
0854     QCOMPARE(offEagle.prettyUrl(), QString::fromLatin1("http://www.sejlsport.dk/graphics/ds/DSUngdom/PDF/Pr%F8v noget nyt dokumenter/Invitation_Kerteminde_11.07.08.pdf"));
0855 #endif
0856 
0857     KUrl openWithUrl("kate --use %25U");
0858     QCOMPARE(openWithUrl.url(), QString::fromLatin1("kate%20--use%20%25U"));
0859     QCOMPARE(openWithUrl.prettyUrl(), QString::fromLatin1("kate --use %25U"));
0860     QCOMPARE(openWithUrl.path(), QString::fromLatin1("kate --use %U"));
0861     QCOMPARE(openWithUrl.pathOrUrl(), QString::fromLatin1("kate --use %25U")); // caused #153894; better not use KUrl for this.
0862 
0863     KUrl ipv6Address("http://[::ffff:129.144.52.38]:81/index.html");
0864     QCOMPARE(ipv6Address.prettyUrl(), QString::fromLatin1("http://[::ffff:129.144.52.38]:81/index.html"));
0865 }
0866 
0867 void KUrlTest::testIsRelative()
0868 {
0869     QVERIFY(!KUrl::isRelativeUrl("man:mmap"));
0870     QVERIFY(!KUrl::isRelativeUrl("javascript:doSomething()"));
0871     QVERIFY(!KUrl::isRelativeUrl("file:///blah"));
0872     // arguable, but necessary for KUrl( baseURL, "//www1.foo.bar" );
0873     QVERIFY(KUrl::isRelativeUrl("/path"));
0874     QVERIFY(KUrl::isRelativeUrl("something"));
0875 
0876     KUrl something("something");
0877     QCOMPARE(something.url(), QString("something"));
0878     QCOMPARE(something.protocol(), QString());
0879     QVERIFY(!something.isLocalFile());
0880 
0881     // Now let's test QUrl::isRelative.
0882     QVERIFY(!KUrl("file:///blah").isRelative());
0883     QVERIFY(!KUrl("/blah").isRelative());
0884     QVERIFY(KUrl("blah").isRelative());
0885     QVERIFY(!KUrl("http://www.kde.org").isRelative());
0886     QVERIFY(KUrl("foo/bar").isRelative());
0887 }
0888 
0889 void KUrlTest::testRelativePath()
0890 {
0891     QString basePath = "/home/bastian";
0892 
0893     QCOMPARE(KUrl::relativePath(basePath, "/home/bastian"), QString("./"));
0894     bool b;
0895     QCOMPARE(KUrl::relativePath(basePath, "/home/bastian/src/plugins", &b), QString("./src/plugins"));
0896     QVERIFY(b);
0897     QCOMPARE(KUrl::relativePath(basePath, "./src/plugins"), QString("./src/plugins"));
0898     QCOMPARE(KUrl::relativePath(basePath, "/home/waba/src/plugins", &b), QString("../waba/src/plugins"));
0899     QVERIFY(!b);
0900     QCOMPARE(KUrl::relativePath(basePath, "/"), QString("../../"));
0901 
0902     QCOMPARE(KUrl::relativePath("/", "/"), QString("./"));
0903     QCOMPARE(KUrl::relativePath("/", "/home/bastian"), QString("./home/bastian"));
0904     QCOMPARE(KUrl::relativePath("", "/home/bastian"), QString("/home/bastian"));
0905 }
0906 
0907 void KUrlTest::testRelativeURL()
0908 {
0909     KUrl baseURL("http://www.kde.org/index.html");
0910     QCOMPARE(KUrl::relativeUrl(baseURL, KUrl("http://www.kde.org/index.html#help")), QString("#help"));
0911     QCOMPARE(KUrl::relativeUrl(baseURL, KUrl("http://www.kde.org/index.html?help=true")), QString("index.html?help=true"));
0912     QCOMPARE(KUrl::relativeUrl(baseURL, KUrl("http://www.kde.org/contact.html")), QString("contact.html"));
0913     QCOMPARE(KUrl::relativeUrl(baseURL, KUrl("ftp://ftp.kde.org/pub/kde")), QString("ftp://ftp.kde.org/pub/kde"));
0914     QCOMPARE(KUrl::relativeUrl(baseURL, KUrl("http://www.kde.org/index.html")), QString("./"));
0915 
0916     baseURL = "http://www.kde.org/info/index.html";
0917     QCOMPARE(KUrl::relativeUrl(baseURL, KUrl("http://www.kde.org/bugs/contact.html")), QString("../bugs/contact.html"));
0918 
0919     baseURL = "ftp://ftp.kde.org/info/";
0920     QCOMPARE(KUrl::relativeUrl(baseURL, KUrl("ftp://ftp.kde.org/info/contact.html")), QString("contact.html"));
0921     QCOMPARE(KUrl::relativeUrl(baseURL, KUrl("ftp://ftp.kde.org/info/A%20%20B.txt")), QString("A%20%20B.txt"));
0922 }
0923 
0924 void KUrlTest::testAdjustPath()
0925 {
0926     KUrl url0("file:///");
0927     QCOMPARE(url0.url(KUrl::RemoveTrailingSlash), QString("file:///"));
0928     url0.adjustPath(KUrl::RemoveTrailingSlash);
0929     QCOMPARE(url0.url(), QString("file:///"));
0930 
0931     KUrl url1("file:///home/kde/");
0932     url1.adjustPath(KUrl::LeaveTrailingSlash);
0933     QCOMPARE(url1.path(), QString("/home/kde/"));
0934     url1.adjustPath(KUrl::RemoveTrailingSlash);
0935     QCOMPARE(url1.path(), QString("/home/kde"));
0936     url1.adjustPath(KUrl::RemoveTrailingSlash);
0937     QCOMPARE(url1.path(), QString("/home/kde"));
0938     url1.adjustPath(KUrl::AddTrailingSlash);
0939     QCOMPARE(url1.path(), QString("/home/kde/"));
0940 
0941     KUrl url2("file:///home/kde//");
0942     url2.adjustPath(KUrl::LeaveTrailingSlash);
0943     QCOMPARE(url2.path(), QString("/home/kde//"));
0944     url2.adjustPath(KUrl::RemoveTrailingSlash);
0945     QCOMPARE(url2.path(), QString("/home/kde"));
0946     url2.adjustPath(KUrl::AddTrailingSlash);
0947     QCOMPARE(url2.path(), QString("/home/kde/"));
0948 
0949     KUrl ftpurl1("ftp://ftp.kde.org/");
0950     ftpurl1.adjustPath(KUrl::LeaveTrailingSlash);
0951     QCOMPARE(ftpurl1.path(), QString("/"));
0952     ftpurl1.adjustPath(KUrl::RemoveTrailingSlash);
0953     QCOMPARE(ftpurl1.path(), QString("/"));
0954 
0955     KUrl ftpurlNoPath("ftp://ftp.kde.org"); // #312060
0956     QCOMPARE(ftpurlNoPath.path(), QString());
0957     ftpurlNoPath.adjustPath(KUrl::LeaveTrailingSlash);
0958     QCOMPARE(ftpurlNoPath.path(), QString());
0959     ftpurlNoPath.adjustPath(KUrl::AddTrailingSlash);
0960     QCOMPARE(ftpurlNoPath.path(), QString());
0961     ftpurlNoPath.adjustPath(KUrl::RemoveTrailingSlash);
0962     QCOMPARE(ftpurlNoPath.path(), QString());
0963 
0964     KUrl ftpurl2("ftp://ftp.kde.org///");
0965     ftpurl2.adjustPath(KUrl::LeaveTrailingSlash);
0966     QCOMPARE(ftpurl2.path(), QString("///"));
0967     ftpurl2.adjustPath(KUrl::RemoveTrailingSlash); // should remove all but trailing slash
0968     QCOMPARE(ftpurl2.path(), QString("/"));
0969     ftpurl2.adjustPath(KUrl::AddTrailingSlash);
0970     QCOMPARE(ftpurl2.path(), QString("/"));
0971 
0972     // Equivalent tests written by the KDirLister maintainer :)
0973 
0974     KUrl u3(QByteArray("ftp://brade@ftp.kde.org///"));
0975     u3.adjustPath(KUrl::RemoveTrailingSlash);
0976     QCOMPARE(u3.url(), QString("ftp://brade@ftp.kde.org/"));
0977 
0978     KUrl u4(QByteArray("ftp://brade@ftp.kde.org/kde///"));
0979     u4.adjustPath(KUrl::RemoveTrailingSlash);
0980     QCOMPARE(u4.url(), QString("ftp://brade@ftp.kde.org/kde"));
0981 
0982     // applying adjustPath(KUrl::RemoveTrailingSlash) twice should not yield two different urls
0983     // (follows from the above test)
0984     KUrl u5 = u4;
0985     u5.adjustPath(KUrl::RemoveTrailingSlash);
0986     QCOMPARE(u5.url(), u4.url());
0987 
0988     {
0989         KUrl remote("remote:/");
0990         QCOMPARE(remote.url(KUrl::RemoveTrailingSlash), QString("remote:/"));
0991         remote.adjustPath(KUrl::RemoveTrailingSlash);
0992         QCOMPARE(remote.url(), QString("remote:/"));
0993         remote.adjustPath(KUrl::RemoveTrailingSlash);
0994         QCOMPARE(remote.url(), QString("remote:/"));
0995     }
0996 
0997     {
0998         KUrl remote2("remote://");
0999         QCOMPARE(remote2.url(), QString("remote://"));
1000         QCOMPARE(remote2.url(KUrl::RemoveTrailingSlash), QString("remote://"));
1001         QCOMPARE(QUrl(remote2).toString(QUrl::StripTrailingSlash), QString("remote://"));
1002     }
1003 }
1004 
1005 void KUrlTest::testIPV6()
1006 {
1007     // IPV6
1008     KUrl waba1("http://[::FFFF:129.144.52.38]:81/index.html");
1009     QCOMPARE(waba1.host(), QString("::ffff:129.144.52.38"));
1010     QCOMPARE(waba1.port(), 81);
1011 
1012     // IPV6
1013     waba1 = "http://waba:pass@[::FFFF:129.144.52.38]:81/index.html";
1014     QCOMPARE(waba1.host(), QString("::ffff:129.144.52.38"));
1015     QCOMPARE(waba1.user(), QString("waba"));
1016     QCOMPARE(waba1.pass(), QString("pass"));
1017     QCOMPARE(waba1.port(), 81);
1018 
1019     // IPV6
1020     waba1 = "http://www.kde.org/cgi/test.cgi";
1021     waba1.setHost("::ffff:129.144.52.38");
1022     QCOMPARE(waba1.url(), QString("http://[::ffff:129.144.52.38]/cgi/test.cgi"));
1023     waba1 = "http://[::ffff:129.144.52.38]/cgi/test.cgi";
1024     QVERIFY(waba1.isValid());
1025 
1026     // IPV6 without path
1027     waba1 = "http://[::ffff:129.144.52.38]?query";
1028     QVERIFY(waba1.isValid());
1029     QCOMPARE(waba1.url(), QString("http://[::ffff:129.144.52.38]?query"));
1030     QCOMPARE(waba1.query(), QString("?query"));
1031     waba1 = "http://[::ffff:129.144.52.38]#ref";
1032     QVERIFY(waba1.isValid());
1033     QCOMPARE(waba1.url(), QString("http://[::ffff:129.144.52.38]#ref"));
1034     QCOMPARE(waba1.ref(), QString("ref"));
1035     // IPV6 without path but with a port
1036     waba1 = "http://[::ffff:129.144.52.38]:81?query";
1037     QVERIFY(waba1.isValid());
1038     QCOMPARE(waba1.url(), QString("http://[::ffff:129.144.52.38]:81?query"));
1039     QCOMPARE(waba1.port(), 81);
1040     QCOMPARE(waba1.query(), QString("?query"));
1041     waba1 = "http://[::ffff:129.144.52.38]:81#ref";
1042     QVERIFY(waba1.isValid());
1043     QCOMPARE(waba1.url(), QString("http://[::ffff:129.144.52.38]:81#ref"));
1044     QCOMPARE(waba1.port(), 81);
1045     QCOMPARE(waba1.ref(), QString("ref"));
1046 
1047     KUrl weird("http://[::fff:1:23]/");
1048     QVERIFY(weird.isValid());
1049     QCOMPARE(weird.host(), QString("::fff:1:23"));
1050 }
1051 
1052 void KUrlTest::testBaseURL() // those are tests for the KUrl(base,relative) constructor
1053 {
1054     KUrl com1(KUrl("http://server.com/dir/"), ".");
1055     QCOMPARE(com1.url(), QString("http://server.com/dir/"));
1056 
1057     KUrl com2(KUrl("http://server.com/dir/blubb/"), "blah/");
1058     QCOMPARE(com2.url(), QString("http://server.com/dir/blubb/blah/"));
1059 
1060     KUrl baseURL("http://www.foo.bar:80");
1061     QVERIFY(baseURL.isValid());
1062     QCOMPARE(baseURL.protocol(), QString("http"));     // lowercase
1063     QCOMPARE(baseURL.port(), 80);
1064 
1065     QString relativeUrl = "//www1.foo.bar";
1066     QVERIFY(KUrl::isRelativeUrl(relativeUrl));
1067 
1068     // Mimick what KUrl(2 urls) does:
1069     QUrl qurl("http://www.foo.bar:80");
1070     QCOMPARE(QString::fromLatin1(qurl.toEncoded()), QString::fromLatin1("http://www.foo.bar:80"));
1071     QCOMPARE(qurl.port(), 80);
1072 
1073     qurl.setHost(QString());
1074     qurl.setPath(QString());
1075     QCOMPARE(qurl.port(), 80);
1076     QCOMPARE(QString(qurl.toEncoded()), QString("http:"));   // a port without a host isn't really useful
1077     qurl.setPort(-1);
1078     QCOMPARE(QString(qurl.toEncoded()), QString("http:"));   // hmm we have no '//' anymore
1079 
1080     KUrl url1(baseURL, relativeUrl);
1081     QCOMPARE(url1.url(), QString("http://www1.foo.bar"));
1082     QCOMPARE(url1.host(), QString("www1.foo.bar"));
1083 
1084     baseURL = "http://www.foo.bar";
1085     KUrl rel_url(baseURL, "/top//test/../test1/file.html");
1086     QCOMPARE(rel_url.url(), QString("http://www.foo.bar/top//test1/file.html"));
1087 
1088     baseURL = "http://www.foo.bar/top//test2/file2.html";
1089     QCOMPARE(baseURL.url(), QString("http://www.foo.bar/top//test2/file2.html"));
1090 
1091     baseURL = "file:/usr/local/src/kde2/////kdelibs/kio";
1092     QCOMPARE(baseURL.url(), QString("file:///usr/local/src/kde2/////kdelibs/kio"));
1093 
1094     baseURL = "http://www.foo.bar";
1095     KUrl rel_url2(baseURL, "mailto:bastian@kde.org");
1096     QCOMPARE(rel_url2.url(), QString("mailto:bastian@kde.org"));
1097 
1098     baseURL = "file:/usr/local/src/kde2/kdelibs/kio/";
1099     KUrl url2(baseURL, "../../////kdebase/konqueror");
1100     QCOMPARE( url2.url(), QString("file:///usr/local/src/kde2/////kdebase/konqueror" ));
1101 
1102 
1103     // WABA: The following tests are to test the handling of relative URLs as
1104     //       found on web-pages.
1105 
1106     KUrl waba1("http://www.website.com/directory/?hello#ref");
1107     {
1108         KUrl waba2(waba1, "relative.html");
1109         QCOMPARE(waba2.url(), QString("http://www.website.com/directory/relative.html"));
1110     }
1111     {
1112         KUrl waba2(waba1, "../relative.html");
1113         QCOMPARE(waba2.url(), QString("http://www.website.com/relative.html"));
1114     }
1115     {
1116         KUrl waba2(waba1, "down/relative.html");
1117         QCOMPARE(waba2.url(), QString("http://www.website.com/directory/down/relative.html"));
1118     }
1119     {
1120         KUrl waba2(waba1, "/down/relative.html");
1121         QCOMPARE(waba2.url(), QString("http://www.website.com/down/relative.html"));
1122     }
1123     {
1124         KUrl waba2(waba1, "//www.kde.org/relative.html");
1125         QCOMPARE(waba2.url(), QString("http://www.kde.org/relative.html"));
1126     }
1127     {
1128         KUrl waba2(waba1, "relative.html?query=test&name=harry");
1129         QCOMPARE(waba2.url(), QString("http://www.website.com/directory/relative.html?query=test&name=harry"));
1130         waba2.removeQueryItem("query");
1131         QCOMPARE(waba2.url(), QString("http://www.website.com/directory/relative.html?name=harry"));
1132         waba2.addQueryItem("age", "18");
1133         QCOMPARE(waba2.url(), QString("http://www.website.com/directory/relative.html?name=harry&age=18"));
1134         waba2.addQueryItem("age", "21");
1135         QCOMPARE(waba2.url(), QString("http://www.website.com/directory/relative.html?name=harry&age=18&age=21"));
1136         waba2.addQueryItem("fullname", "Harry Potter");
1137         QCOMPARE(waba2.url(), QString("http://www.website.com/directory/relative.html?name=harry&age=18&age=21&fullname=Harry%20Potter"));
1138     }
1139     {
1140         KUrl waba2(waba1, "?query=test&name=harry");
1141         QCOMPARE(waba2.url(), QString("http://www.website.com/directory/?query=test&name=harry"));
1142     }
1143     {
1144         KUrl waba2(waba1, "relative.html#with_reference");
1145         QCOMPARE(waba2.url(), QString("http://www.website.com/directory/relative.html#with_reference"));
1146     }
1147 
1148     {
1149         KUrl waba2(waba1, "#");
1150         QCOMPARE(waba2.url(), QString("http://www.website.com/directory/?hello#"));
1151     }
1152     {
1153         KUrl waba2(waba1, "");
1154         QCOMPARE(waba2.url(), QString("http://www.website.com/directory/?hello#ref"));
1155     }
1156     {
1157         KUrl waba2(waba1, "#%72%22method");  // #243217
1158         QCOMPARE(waba2.url(), QString("http://www.website.com/directory/?hello#r%22method"));
1159     }
1160     {
1161         KUrl base("http://faure@www.kde.org");   // no path
1162         KUrl waba2(base, "filename.html");
1163         QCOMPARE(waba2.url(), QString("http://faure@www.kde.org/filename.html"));
1164     }
1165     {
1166         KUrl base("http://faure:pass@www.kde.org:81?query");
1167         KUrl rel1(base, "http://www.kde.org/bleh/");  // same host
1168         QCOMPARE(rel1.url(), QString("http://faure:pass@www.kde.org/bleh/"));
1169         KUrl rel2(base, "http://www.yahoo.org");  // different host
1170         QCOMPARE(rel2.url(), QString("http://www.yahoo.org"));
1171     }
1172 
1173     waba1 = "http://www.website.com/directory/filename?bla#blub";
1174     {
1175         KUrl waba2(waba1, "relative.html");
1176         QCOMPARE(waba2.url(), QString("http://www.website.com/directory/relative.html"));
1177     }
1178     {
1179         KUrl waba2(waba1, "./relative.html");
1180         QCOMPARE(waba2.url(), QString("http://www.website.com/directory/relative.html"));
1181     }
1182     {
1183         KUrl waba2(waba1, "../relative.html");
1184         QCOMPARE(waba2.url(), QString("http://www.website.com/relative.html"));
1185     }
1186     {
1187         KUrl waba2(waba1, "down/relative.html");
1188         QCOMPARE(waba2.url(), QString("http://www.website.com/directory/down/relative.html"));
1189     }
1190     {
1191         KUrl waba2(waba1, "down/./relative.html");
1192         QCOMPARE(waba2.url(), QString("http://www.website.com/directory/down/relative.html"));
1193     }
1194     {
1195         KUrl waba2(waba1, "/down/relative.html");
1196         QCOMPARE(waba2.url(), QString("http://www.website.com/down/relative.html"));
1197     }
1198     {
1199         KUrl waba2(waba1, "relative.html?query=test&name=harry");
1200         QCOMPARE(waba2.url(), QString("http://www.website.com/directory/relative.html?query=test&name=harry"));
1201     }
1202     {
1203         KUrl waba2(waba1, "?query=test&name=harry");
1204         QCOMPARE(waba2.url(), QString("http://www.website.com/directory/filename?query=test&name=harry"));
1205     }
1206     {
1207         KUrl waba2(waba1, "relative.html#with_reference");
1208         QCOMPARE(waba2.url(), QString("http://www.website.com/directory/relative.html#with_reference"));
1209     }
1210     {
1211         KUrl waba2(waba1, "http:/relative.html");  // "rfc 1606 loophole"
1212         QCOMPARE(waba2.url(), QString("http://www.website.com/relative.html"));
1213     }
1214     waba1.setUser("waldo");
1215     QCOMPARE(waba1.url(), QString("http://waldo@www.website.com/directory/filename?bla#blub"));
1216     waba1.setUser("waldo/bastian");
1217     QCOMPARE(waba1.url(), QString("http://waldo%2Fbastian@www.website.com/directory/filename?bla#blub"));
1218     waba1.setRef(QString());
1219     waba1.setPass("pass");
1220     waba1.setDirectory("/foo");
1221     waba1.setProtocol("https");
1222     waba1.setHost("web.com");
1223     waba1.setPort(881);
1224     QCOMPARE(waba1.url(), QString("https://waldo%2Fbastian:pass@web.com:881/foo/?bla"));
1225     waba1.setDirectory("/foo/");
1226     QCOMPARE(waba1.url(), QString("https://waldo%2Fbastian:pass@web.com:881/foo/?bla"));
1227 
1228     QUrl sadEagleTest;
1229     sadEagleTest.setEncodedUrl("http://www.calorieking.com/foo.php?P0=[2006-3-8]", QUrl::TolerantMode);
1230     QVERIFY(sadEagleTest.isValid());
1231     KUrl sadEagleExpectedResult("http://www.calorieking.com/personal/diary/rpc.php?C=jsrs1&F=getDiaryDay&P0=[2006-3-8]&U=1141858921458");
1232     QVERIFY(sadEagleExpectedResult.isValid());
1233     KUrl sadEagleBase("http://www.calorieking.com/personal/diary/");
1234     QVERIFY(sadEagleBase.isValid());
1235     KUrl sadEagleCombined(sadEagleBase, "/personal/diary/rpc.php?C=jsrs1&F=getDiaryDay&P0=[2006-3-8]&U=1141858921458");
1236     QCOMPARE(sadEagleCombined.url(), sadEagleExpectedResult.url());
1237 
1238     KUrl dxOffEagle(KUrl("http://something/other.html"), "newpage.html?[{\"foo: bar\"}]");
1239     QVERIFY(dxOffEagle.isValid());
1240     QCOMPARE(dxOffEagle.url(), QString("http://something/newpage.html?[%7B%22foo:%20bar%22%7D]"));
1241     QCOMPARE(dxOffEagle.prettyUrl(), QString("http://something/newpage.html?[%7B%22foo:%20bar%22%7D]"));
1242 
1243     // QtSw issue 243557
1244     QByteArray tsdgeos("http://google.com/c?c=Translation+%C2%BB+trunk|");
1245     QUrl tsdgeosQUrl;
1246     tsdgeosQUrl.setEncodedUrl(tsdgeos, QUrl::TolerantMode);
1247     QVERIFY(tsdgeosQUrl.isValid()); // failed in Qt-4.4, works in Qt-4.5
1248     QByteArray tsdgeosExpected("http://google.com/c?c=Translation+%C2%BB+trunk%7C");
1249     //QCOMPARE(tsdgeosQUrl.toEncoded(), tsdgeosExpected); // unusable output from qtestlib...
1250     QCOMPARE(QString(tsdgeosQUrl.toEncoded()), QString(tsdgeosExpected));
1251 
1252     KUrl tsdgeosUrl(tsdgeos);
1253     QCOMPARE(tsdgeosUrl.url(), QString(tsdgeosExpected));
1254 
1255     QByteArray pipesAgain("http://translate.google.com/translate_t#en|uk|demo");
1256     QUrl pipesUrl;
1257     pipesUrl.setEncodedUrl(pipesAgain, QUrl::TolerantMode);
1258     QVERIFY(pipesUrl.isValid());
1259     QCOMPARE(QString(pipesUrl.toEncoded()), QString("http://translate.google.com/translate_t#en%7Cuk%7Cdemo"));
1260 
1261     // Shows up in nspluginviewer/flash
1262     QString flashRel = "javascript:window.location+\"__flashplugin_unique__\"";
1263     KUrl flashUrl(flashRel);
1264     QVERIFY(flashUrl.isValid());
1265     KUrl flashBase("http://www.youtube.com/?v=JvOSnRD5aNk");
1266     KUrl flashComposed(flashBase, flashRel);
1267     QCOMPARE(flashComposed.url(), QString("javascript:window.location+%22__flashplugin_unique__%22"));
1268 }
1269 
1270 void KUrlTest::testSetEncodedFragment_data()
1271 {
1272     QTest::addColumn<QByteArray>("base");
1273     QTest::addColumn<QByteArray>("fragment");
1274     QTest::addColumn<QByteArray>("expected");
1275     typedef QByteArray BA;
1276     QTest::newRow("basic test") << BA("http://www.kde.org") << BA("abc") << BA("http://www.kde.org#abc");
1277     QTest::newRow("initial url has fragment") << BA("http://www.kde.org#old") << BA("new") << BA("http://www.kde.org#new");
1278     QTest::newRow("encoded fragment") << BA("http://www.kde.org") << BA("a%20c") << BA("http://www.kde.org#a%20c");
1279     QTest::newRow("with #") << BA("http://www.kde.org") << BA("a#b") << BA("http://www.kde.org#a%23b"); // see c615dcc4416 in qtbase
1280     QTest::newRow("empty") << BA("http://www.kde.org") << BA("") << BA("http://www.kde.org#");
1281 }
1282 
1283 void KUrlTest::testSetEncodedFragment()
1284 {
1285     // Bug fixed in 4.5.1 by Thiago
1286 #if QT_VERSION < 0x040501
1287     QSKIP("Bug in Qt-4.4/4.5-rc1: setEncodedFragment doesn't work if the initial url has no fragment");
1288 #endif
1289 
1290     QFETCH(QByteArray, base);
1291     QFETCH(QByteArray, fragment);
1292     QFETCH(QByteArray, expected);
1293     QUrl u;
1294     u.setEncodedUrl(base, QUrl::TolerantMode);
1295     QVERIFY(u.isValid());
1296     u.setEncodedFragment(fragment);
1297     QVERIFY(u.isValid());
1298     QCOMPARE(QString::fromLatin1(u.toEncoded()), QString::fromLatin1(expected));
1299 }
1300 
1301 void KUrlTest::testSubURL()
1302 {
1303     QString u1 = "file:/home/dfaure/my%20tar%20file.tgz#gzip:/#tar:/#myref";
1304     KUrl url1(u1);
1305     // KDE3: was #,#,#, Qt-4.0 to 4.4: #,%23,%23 . 4.5, 5.0, 5.1: #,#,#
1306     // Qt 5.2: #, %23, %23, see c615dcc441 in qtbase for the reasoning. We don't use sub urls anymore anyway.
1307     QCOMPARE(url1.url(), QString("file:///home/dfaure/my%20tar%20file.tgz#gzip:/%23tar:/%23myref"));
1308     QVERIFY(url1.hasRef());
1309     QVERIFY(!url1.isLocalFile());    // Not strictly local!
1310     QVERIFY(url1.hasSubUrl());
1311     //QCOMPARE( url1.htmlRef(), QString("myref") );
1312     QCOMPARE(url1.upUrl().url(), QString("file:///home/dfaure/"));
1313 
1314     const KUrl::List splitList = KUrl::split(url1);
1315     QCOMPARE(splitList.count(), 3);
1316     //kDebug() << splitList.toStringList();
1317     QCOMPARE(splitList[0].url(), QString("file:///home/dfaure/my%20tar%20file.tgz#myref"));
1318     QCOMPARE(splitList[1].url(), QString("gzip:/#myref"));
1319     QCOMPARE(splitList[2].url(), QString("tar:/#myref"));
1320 
1321     KUrl rejoined = KUrl::join(splitList);
1322     QCOMPARE(rejoined.url(), url1.url());
1323 
1324     u1 = "error:/?error=14&errText=Unknown%20host%20asdfu.adgi.sdfgoi#http://asdfu.adgi.sdfgoi";
1325     url1 = u1;
1326     QCOMPARE(url1.url(), QString("error:/?error=14&errText=Unknown%20host%20asdfu.adgi.sdfgoi#http://asdfu.adgi.sdfgoi"));
1327     QVERIFY(url1.hasSubUrl());
1328     QVERIFY(url1.hasRef());
1329     QVERIFY(!url1.isLocalFile());
1330     QVERIFY(!url1.hasHTMLRef());
1331 
1332     u1 = "file:/home/dfaure/my%20tar%20file.tgz#gzip:/#tar:/";
1333     url1 = u1;
1334     QCOMPARE(url1.url(), QString("file:///home/dfaure/my%20tar%20file.tgz#gzip:/%23tar:/"));
1335     QVERIFY(url1.hasRef());
1336     QVERIFY(!url1.hasHTMLRef());
1337     QVERIFY(url1.hasSubUrl());
1338     QVERIFY(url1.htmlRef().isNull());
1339     QCOMPARE(url1.upUrl().url(), QString("file:///home/dfaure/"));
1340 
1341     u1 = "file:///home/dfaure/my%20tar%20file.tgz#gzip:/#tar:/";
1342     url1 = u1;
1343     QCOMPARE(url1.url(), QString("file:///home/dfaure/my%20tar%20file.tgz#gzip:/%23tar:/"));
1344     QVERIFY(url1.hasRef());
1345     QVERIFY(!url1.hasHTMLRef());
1346     QVERIFY(url1.hasSubUrl());
1347     QVERIFY(url1.htmlRef().isNull());
1348     QCOMPARE(url1.upUrl().url(), QString("file:///home/dfaure/"));
1349 
1350     u1 = "file:/home/dfaure/my%20tar%20file.tgz#gzip:/#tar:/README";
1351     url1 = u1;
1352     QCOMPARE(url1.url(), QString("file:///home/dfaure/my%20tar%20file.tgz#gzip:/%23tar:/README"));
1353     QVERIFY(url1.hasRef());
1354     QVERIFY(!url1.hasHTMLRef());
1355     QVERIFY(url1.hasSubUrl());
1356     QVERIFY(url1.htmlRef().isNull());
1357     const KUrl::List url1Splitted = KUrl::split(url1);
1358     QCOMPARE(url1Splitted.count(), 3);
1359     //kDebug() << url1Splitted.toStringList();
1360     QCOMPARE(url1Splitted[0].url(), QString("file:///home/dfaure/my%20tar%20file.tgz"));
1361     QCOMPARE(url1Splitted[1].url(), QString("gzip:/"));
1362     QCOMPARE(url1Splitted[2].url(), QString("tar:/README"));
1363     const KUrl url1Rejoined = KUrl::join(url1Splitted);
1364     QCOMPARE(url1Rejoined.url(), url1.url());
1365     QCOMPARE(url1.upUrl().url(), QString("file:///home/dfaure/my%20tar%20file.tgz#gzip:/%23tar:/"));
1366 
1367 }
1368 
1369 void KUrlTest::testSetUser()
1370 {
1371     // The KUrl equality test below works because in Qt4 null == empty.
1372     QString str1;
1373     QString str2 = "";
1374     QVERIFY(str1 == str2);
1375 
1376     KUrl emptyUserTest1("http://www.foobar.com/");
1377     QVERIFY(emptyUserTest1.user().isEmpty());
1378     QVERIFY(emptyUserTest1.user().isNull());   // Expected result. This was fixed in Qt-4.4
1379 
1380     KUrl emptyUserTest2("http://www.foobar.com/");
1381     emptyUserTest2.setUser("");
1382     //QVERIFY( emptyUserTest2.user().isNull() );
1383     // Qt 5 allows a "set but empty" username, as per the RFC.
1384     QCOMPARE(emptyUserTest2.url(), QString("http://@www.foobar.com/"));
1385     QVERIFY(emptyUserTest1 != emptyUserTest2);
1386 
1387     // Parsing back:
1388     QUrl u("http://@kde.org/");
1389     QVERIFY(u.userName().isEmpty());
1390     QVERIFY(!u.userName().isNull());
1391     QVERIFY(u.password().isNull());
1392     emptyUserTest2.setUser("foo");
1393     QCOMPARE(emptyUserTest2.user(), QString::fromLatin1("foo"));
1394     emptyUserTest2.setUser(QString());
1395     QVERIFY(emptyUserTest1 == emptyUserTest2);
1396 
1397     KUrl emptyUserTest3("http://www.foobar.com/");
1398     emptyUserTest3.setPass("");
1399     // empty password means empty user, fixed in Qt5
1400     QCOMPARE(emptyUserTest3.url(), QString("http://:@www.foobar.com/"));
1401     QVERIFY(emptyUserTest1 != emptyUserTest3);
1402 
1403     KUrl uga("ftp://ftp.kde.org");
1404     uga.setUser("foo@bar");
1405     QCOMPARE(uga.user(), QString::fromLatin1("foo@bar"));
1406     QCOMPARE(uga.url(), QString::fromLatin1("ftp://foo%40bar@ftp.kde.org"));
1407 }
1408 
1409 void KUrlTest::testComparisons()
1410 {
1411     /* QUrl version of urlcmp */
1412     QUrl u1("ftp://ftp.de.kde.org/dir");
1413     QUrl u2("ftp://ftp.de.kde.org/dir/");
1414     QUrl::FormattingOptions options = QUrl::None;
1415     options |= QUrl::StripTrailingSlash;
1416     QString str1 = u1.toString(options);
1417     QString str2 = u2.toString(options);
1418     QCOMPARE(str1, u1.toString());
1419     QCOMPARE(str2, u1.toString());
1420     bool same = str1 == str2;
1421     QVERIFY(same);
1422 
1423     QString ucmp1 = "ftp://ftp.de.kde.org/dir";
1424     QString ucmp2 = "ftp://ftp.de.kde.org/dir/";
1425 #ifndef KDELIBS4SUPPORT_NO_DEPRECATED
1426     QVERIFY(!urlcmp(ucmp1, ucmp2));
1427     QVERIFY(urlcmp(ucmp1, ucmp2, KUrl::CompareWithoutTrailingSlash)); //only slash difference, ignore_trailing
1428 #endif
1429 
1430     {
1431         KUrl u1(ucmp1);
1432         KUrl u2(ucmp2);
1433         QVERIFY(!u1.equals(u2));
1434         QVERIFY(u1.equals(u2, KUrl::CompareWithoutTrailingSlash));
1435         QVERIFY(u1.equals(u2, KUrl::CompareWithoutTrailingSlash | KUrl::AllowEmptyPath));
1436     }
1437 
1438     // Special case: no path vs '/'.
1439     {
1440         QString str1 = QString::fromLatin1("ftp://ftp.de.kde.org");
1441         QString str2 = QString::fromLatin1("ftp://ftp.de.kde.org/");
1442 #ifndef KDELIBS4SUPPORT_NO_DEPRECATED
1443         QVERIFY(!urlcmp(str1, str2));
1444         QVERIFY(!urlcmp(str1, str2, KUrl::CompareWithoutTrailingSlash)); // empty path != '/'
1445         QVERIFY(urlcmp(str1, str2, KUrl::CompareWithoutTrailingSlash | KUrl::AllowEmptyPath));
1446 #endif
1447         KUrl u1(str1);
1448         KUrl u2(str2);
1449         QVERIFY(!u1.equals(u2));
1450         QVERIFY(!u1.equals(u2, KUrl::CompareWithoutTrailingSlash));
1451         QVERIFY(u1.equals(u2, KUrl::CompareWithoutTrailingSlash | KUrl::AllowEmptyPath));
1452     }
1453 
1454     QString ucmp3 = "ftp://ftp.de.kde.org/dir/#";
1455 #ifndef KDELIBS4SUPPORT_NO_DEPRECATED
1456     QVERIFY(!urlcmp(ucmp2, ucmp3));  // (only hash difference)
1457     QVERIFY(urlcmp(ucmp2, ucmp3, KUrl::CompareWithoutFragment)); // (only hash difference, ignore_ref)
1458     QVERIFY(urlcmp(ucmp2, ucmp3, KUrl::CompareWithoutTrailingSlash | KUrl::CompareWithoutFragment)); // (slash and hash difference, ignore_trailing, ignore_ref)
1459     QVERIFY(urlcmp("", "", KUrl::CompareWithoutFragment)); // (empty, empty)
1460     QVERIFY(urlcmp("", ""));  // (empty, empty)
1461     QVERIFY(!urlcmp("", ucmp1));  // (empty, not empty)
1462     QVERIFY(!urlcmp("", ucmp1, KUrl::CompareWithoutFragment)); // (empty, not empty)
1463     QVERIFY(!urlcmp("file", ucmp1));  // (malformed, not empty)
1464     QVERIFY(!urlcmp("file", ucmp1, KUrl::CompareWithoutFragment)); // (malformed, not empty)
1465 #endif
1466 
1467     KUrl ftpUrl("ftp://ftp.de.kde.org");
1468     QCOMPARE(ftpUrl.path(), QString());
1469     ftpUrl = "ftp://ftp.de.kde.org/";
1470     QVERIFY(ftpUrl.isParentOf(KUrl("ftp://ftp.de.kde.org/host/subdir/")));
1471     ftpUrl = "ftp://ftp/host/subdir/";
1472     QVERIFY(ftpUrl.isParentOf(KUrl("ftp://ftp/host/subdir/")));
1473     QVERIFY(ftpUrl.isParentOf(KUrl("ftp://ftp/host/subdir")));
1474     QVERIFY(!ftpUrl.isParentOf(KUrl("ftp://ftp/host/subdi")));
1475     QVERIFY(ftpUrl.isParentOf(KUrl("ftp://ftp/host/subdir/blah/")));
1476     QVERIFY(!ftpUrl.isParentOf(KUrl("ftp://ftp/blah/subdir")));
1477     QVERIFY(!ftpUrl.isParentOf(KUrl("file:////ftp/host/subdir/")));
1478     QVERIFY(ftpUrl.isParentOf(KUrl("ftp://ftp/host/subdir/subsub")));
1479 }
1480 
1481 void KUrlTest::testStreaming_data()
1482 {
1483     QTest::addColumn<QString>("urlStr");
1484 
1485     QTest::newRow("origURL") << "http://www.website.com/directory/?#ref";
1486     QTest::newRow("urlWithPassAndNoUser") << "ftp://:password@ftp.kde.org/path";
1487     QTest::newRow("accentuated") << QString::fromUtf8("trash:/été");
1488     QTest::newRow("empty") << "";
1489     QVERIFY(!KUrl("ptal://mlc:usb").isValid());
1490     QTest::newRow("invalid") << "ptal://mlc:usb";
1491     QTest::newRow("ipv6") << "http://[::ffff:129.144.52.38]:81?query";
1492 }
1493 
1494 void KUrlTest::testStreaming()
1495 {
1496     QFETCH(QString, urlStr);
1497     KUrl url(urlStr);
1498 
1499     QByteArray buffer;
1500     QDataStream writeStream(&buffer, QIODevice::WriteOnly);
1501     writeStream << url;
1502 
1503     QDataStream stream(buffer);
1504     KUrl restored;
1505     stream >> restored; // streaming valid url
1506     QCOMPARE(restored.isValid(), url.isValid());
1507     if (url.isValid()) {
1508         QCOMPARE(restored.url(), url.url());
1509     }
1510 }
1511 
1512 void KUrlTest::testBrokenStuff()
1513 {
1514     // Broken stuff
1515     KUrl waba1("file:a");
1516     QCOMPARE(waba1.path(), QString("a"));
1517     QCOMPARE(waba1.fileName(KUrl::ObeyTrailingSlash), QString("a"));
1518     QCOMPARE(waba1.fileName(), QString("a"));
1519     QCOMPARE(waba1.directory(KUrl::AppendTrailingSlash | KUrl::ObeyTrailingSlash), QString(""));
1520     QCOMPARE(waba1.directory(KUrl::ObeyTrailingSlash), QString(""));
1521     QCOMPARE(waba1.directory(), QString(""));
1522 
1523     waba1 = "file:a/";
1524     QCOMPARE(waba1.path(), QString("a/"));
1525     QCOMPARE(waba1.fileName(KUrl::ObeyTrailingSlash), QString(""));
1526     QCOMPARE(waba1.fileName(), QString("a"));
1527     QCOMPARE(waba1.directory(KUrl::ObeyTrailingSlash | KUrl::AppendTrailingSlash), QString("a/"));
1528     QCOMPARE(waba1.directory(KUrl::ObeyTrailingSlash), QString("a"));
1529     QCOMPARE(waba1.directory(), QString(""));
1530 
1531     waba1 = "file:";
1532     QVERIFY(!waba1.isEmpty());
1533     QVERIFY(waba1.isValid());   // KDE3: was invalid. Now it's qurl with scheme="file".
1534     QCOMPARE(waba1.path(), QString(""));
1535     QCOMPARE(waba1.fileName(KUrl::ObeyTrailingSlash), QString(""));
1536     QCOMPARE(waba1.fileName(), QString(""));
1537     QCOMPARE(waba1.directory(KUrl::ObeyTrailingSlash | KUrl::AppendTrailingSlash), QString(""));
1538     QCOMPARE(waba1.directory(KUrl::AppendTrailingSlash), QString(""));
1539     QCOMPARE(waba1.directory(), QString(""));
1540     KUrl broken;
1541     broken.setPath(QString());
1542     QVERIFY(!broken.isEmpty());
1543     // It's valid: because isValid refers to parsing, not to what happens afterwards.
1544     QVERIFY(broken.isValid());
1545     QCOMPARE(broken.path(), QString(""));
1546     broken = "file://"; // just because coolo wondered
1547     QVERIFY(!broken.isEmpty());
1548     QVERIFY(broken.isValid());   // KDE3: was invalid; same as above
1549     QCOMPARE(broken.path(), QString(""));
1550     broken = "file";
1551     QVERIFY(broken.isValid());   // KDE3: was invalid; now it's path="file"
1552 
1553 #if 0
1554     // KUrl has a Q_ASSERT on this now, so we can't test it.
1555     broken = "/";
1556     QVERIFY(broken.isValid());
1557     QCOMPARE(broken.path(), QString("/"));
1558     QCOMPARE(broken.url(), QString("/"));   // KDE3: was resolved to "file:///". QUrl supports urls without a protocol.
1559     QCOMPARE(broken.protocol(), QString(""));   // KDE3: was "file"
1560 #endif
1561 
1562     {
1563         QUrl url;
1564         url.setEncodedUrl("LABEL=USB_STICK", QUrl::TolerantMode);
1565         QVERIFY(url.isValid());
1566         QCOMPARE(url.path(), QString("LABEL=USB_STICK"));
1567         QVERIFY(!url.isEmpty());
1568     }
1569     {
1570         QUrl url;
1571         url.setEncodedUrl("LABEL=USB_STICK", QUrl::TolerantMode);
1572         QVERIFY(url.isValid());
1573         QVERIFY(!url.isEmpty());   // Qt-4.4-snapshot20080213 bug, reported to TT
1574         QCOMPARE(url.path(), QString("LABEL=USB_STICK"));
1575     }
1576 
1577     broken = "LABEL=USB_STICK"; // 71430, can we use KUrl for this?
1578     QVERIFY(broken.isValid());   // KDE3 difference: QUrl likes this one too
1579     QVERIFY(!broken.isEmpty());
1580     QCOMPARE(broken.path(), QString("LABEL=USB_STICK"));   // was "" in KDE3
1581 }
1582 
1583 void KUrlTest::testMoreBrokenStuff()
1584 {
1585 #if 0 // BROKEN?
1586     // UNC like names
1587     KUrl unc1("FILE://localhost/home/root");
1588     QCOMPARE(unc1.path(), QString("/home/root"));
1589     QCOMPARE(unc1.url(), QString("file:///home/root"));
1590 #endif
1591     KUrl unc2("file:///home/root"); // with empty host
1592     QCOMPARE(unc2.path(), QString("/home/root"));
1593     QCOMPARE(unc2.url(), QString("file:///home/root"));
1594 
1595     {
1596         KUrl unc3("FILE://remotehost/home/root");
1597 #if 0 // BROKEN?
1598         QCOMPARE(unc3.path(), QString("//remotehost/home/root"));
1599 #endif
1600         QCOMPARE(unc3.url(), QString("file://remotehost/home/root"));   // kde3, qt5: lowercase. kde4/qt4: uppercase.
1601         KUrl url2("file://atlas/dfaure");
1602         QCOMPARE(url2.host(), QString("atlas"));
1603         QCOMPARE(url2.path(), QString("/dfaure"));
1604         //QCOMPARE( url3.path(), QString("//atlas/dfaure")); // says Waba
1605         //KUrl url3("file:////atlas/dfaure");
1606         //QCOMPARE( url3.path(), QString("//atlas/dfaure")); // says Waba
1607 
1608         KUrl url4(url2, "//remotehost/home/root");
1609         QCOMPARE(url4.host(), QString("remotehost"));
1610         QCOMPARE(url4.path(), QString("/home/root"));
1611     }
1612 
1613     KUrl weird;
1614     weird = "http://strange<hostname>/";
1615     QVERIFY(!weird.isValid());
1616 
1617     weird = "http://strange<username>@strange<hostname>/";
1618     QVERIFY(!weird.isValid());
1619 
1620     {
1621         QUrl url;
1622         url.setUrl("http://strange<username>@hostname/", QUrl::TolerantMode);
1623         QVERIFY(url.isValid());
1624     }
1625     weird = "http://strange<username>@hostname/";
1626     QVERIFY(weird.isValid());   // KDE3: was valid. Fixed by _setEncodedUrl.
1627     QCOMPARE(weird.host(), QString("hostname"));
1628 
1629     weird = "http://strange;hostname/";
1630     QVERIFY(!weird.isValid());
1631 
1632     weird = "http://strange;username@strange;hostname/";
1633     QVERIFY(!weird.isValid());
1634 
1635     weird = "http://strange;username@hostname/";
1636     QVERIFY(weird.isValid());
1637     QCOMPARE(weird.host(), QString("hostname"));
1638 
1639     weird = "http://strange;username:password@strange;hostname/";
1640     QVERIFY(!weird.isValid());
1641 
1642     weird = "http://strange;username:password@hostname/";
1643     QVERIFY(weird.isValid());
1644     QCOMPARE(weird.host(), QString("hostname"));
1645 
1646     weird = "http://[strange;hostname]/";
1647     QVERIFY(!weird.isValid());
1648 
1649     weird = "ssh://user@machine?cmd='echo $HOSTNAME'";
1650     QVERIFY(weird.isValid());
1651     QCOMPARE(weird.host(), QString("machine"));
1652     //qDebug("%s",qPrintable( weird.query() ) );
1653     QCOMPARE(weird.queryItem("cmd"), QString("'echo $HOSTNAME'"));
1654 
1655     weird = ":pictures"; // for KFileDialog's startDir, long ago. Nowadays it uses a proper URL, kfiledialog:///pictures
1656     QVERIFY(!weird.isValid());
1657     QVERIFY(weird.protocol().isEmpty());
1658     QVERIFY(weird.host().isEmpty());
1659     QCOMPARE(weird.path(), QString(":pictures"));
1660     QCOMPARE(weird.url(), QString());
1661 
1662     weird = "::keyword"; // for KFileDialog's startDir, long ago.
1663     QVERIFY(!weird.isValid());
1664     QVERIFY(weird.protocol().isEmpty());
1665     QVERIFY(weird.host().isEmpty());
1666     QCOMPARE(weird.path(), QString("::keyword"));
1667     QCOMPARE(weird.url(), QString());
1668 
1669     KUrl broken;
1670     broken = "ptal://mlc:usb:PC_970";
1671     QVERIFY(!broken.isValid());
1672     QVERIFY(!broken.errorString().isEmpty());
1673     //QCOMPARE( broken.url(), QString("ptal://mlc:usb:PC_970") ); // QUrl doesn't provide the initial string if it's an invalid url
1674     QUrl brokenUrl("ptal://mlc:usb:PC_970");
1675     QVERIFY(!brokenUrl.isValid());
1676 
1677     QUrl dxOffEagle("http://something/newpage.html?[{\"foo: bar\"}]", QUrl::TolerantMode);
1678     QVERIFY(dxOffEagle.isValid());
1679     QCOMPARE(QString(dxOffEagle.toEncoded()), QString("http://something/newpage.html?[%7B%22foo:%20bar%22%7D]"));
1680     QUrl dxOffEagle2;
1681     dxOffEagle2.setUrl("http://something/newpage.html?[{\"foo: bar\"}]", QUrl::TolerantMode);
1682     QVERIFY(dxOffEagle2.isValid());
1683     QCOMPARE(dxOffEagle.toEncoded(), dxOffEagle2.toEncoded());
1684 
1685     QUrl dxOffEagle3;
1686     dxOffEagle3.setEncodedUrl("http://something/newpage.html?[{\"foo: bar\"}]", QUrl::TolerantMode);
1687 #if QT_VERSION < 0x040500
1688     QEXPECT_FAIL("", "Issue N183630, task ID 183874; works with setUrl so we do that in _setEncodedUrl now", Continue);
1689 #endif
1690     QVERIFY(dxOffEagle3.isValid());
1691     QCOMPARE(dxOffEagle.toEncoded(), dxOffEagle3.toEncoded());
1692 
1693     QUrl javascript;
1694     javascript.setUrl("javascript:window.location+\"__flashplugin_unique__\"", QUrl::TolerantMode);
1695     QVERIFY(javascript.isValid());
1696     javascript.setEncodedUrl("javascript:window.location+\"__flashplugin_unique__\"", QUrl::TolerantMode);
1697 #if QT_VERSION < 0x040500
1698     QEXPECT_FAIL("", "Issue N183630, task ID 183874", Continue);
1699 #endif
1700     QVERIFY(javascript.isValid());
1701 }
1702 
1703 void KUrlTest::testMailto()
1704 {
1705     const QString faure = "faure@kde.org";
1706     const QString mailtoFaure = "mailto:" + faure;
1707     KUrl umail1(mailtoFaure);
1708     QCOMPARE(umail1.protocol(), QString("mailto"));
1709     QCOMPARE(umail1.path(), QString(faure));
1710     QVERIFY(!KUrl::isRelativeUrl(mailtoFaure));
1711 
1712 #if 0 // TODO in Qt
1713     // Make sure populateMimeData() works correct:
1714     // 1. the text/plain part of the mimedata should not contain the mailto: part
1715     // 2. the uri-list part of the mimedata should contain the mailto: part
1716     QMimeData md;
1717     umail1.populateMimeData(&md);
1718     QCOMPARE(md.text(), faure);
1719     KUrl::List uriList = KUrl::List::fromMimeData(&md);
1720     QCOMPARE(uriList.size(), 1);
1721     KUrl first = uriList.first();
1722     QCOMPARE(first.protocol(), QString("mailto"));
1723     QCOMPARE(first.path(), faure);
1724 #endif
1725 
1726     KUrl mailtoOnly("mailto:");
1727     QVERIFY(mailtoOnly.isValid());   // KDE3 said invalid, QUrl is more tolerant
1728 
1729     KUrl url1("mailto:user@host.com");
1730     QCOMPARE(url1.url(), QString("mailto:user@host.com"));
1731     QCOMPARE(url1.url(KUrl::LeaveTrailingSlash), QString("mailto:user@host.com"));
1732 
1733     KUrl mailtoUrl("mailto:null@kde.org?subject=hello");
1734     QCOMPARE(mailtoUrl.url(), QString("mailto:null@kde.org?subject=hello"));
1735 
1736     QUrl qurl("mailto:null@kde.org?subject=hello#world"); // #80165: is #world part of fragment or query? RFC-3986 says: fragment.
1737     QCOMPARE(QString::fromLatin1(qurl.encodedQuery()), QString("subject=hello"));
1738 
1739     {
1740         QUrl mailtoUrl;
1741         mailtoUrl.setScheme("mailto");
1742         mailtoUrl.setPath("a%b");
1743         QCOMPARE(mailtoUrl.path(), QString("a%b"));
1744         QCOMPARE(mailtoUrl.path(QUrl::FullyEncoded), QString("a%25b"));
1745         QCOMPARE(mailtoUrl.toString(), QString("mailto:a%25b"));
1746         QCOMPARE(QString::fromLatin1(mailtoUrl.toEncoded()), QString::fromLatin1("mailto:a%25b"));
1747     }
1748     {
1749         KUrl mailtoUrl;
1750         mailtoUrl.setScheme("mailto");
1751         mailtoUrl.setPath("a%b");
1752         QCOMPARE(mailtoUrl.url(), QString("mailto:a%25b")); // KUrl takes care of not changing behavior with Qt5.
1753     }
1754 
1755 #if 0
1756     // I wrote this test in the very first kurltest, but there's no proof that it's actually valid.
1757     // Andreas says this is broken, i.e. against rfc2368.
1758     // Let's see if the need ever comes up.
1759     KUrl umail2("mailto:Faure David <faure@kde.org>");
1760     QCOMPARE(umail2.protocol(), QString("mailto"));
1761     QCOMPARE(umail2.path(), QString("Faure David <faure@kde.org>"));
1762     QVERIFY(!KUrl::isRelativeUrl("mailto:faure@kde.org"));
1763 #endif
1764 
1765     KUrl url183433("mailto:test[at]gmail[dot]com");
1766     QCOMPARE(url183433.prettyUrl(), QString("mailto:test[at]gmail[dot]com"));
1767     QCOMPARE(url183433.url(), QString("mailto:test[at]gmail[dot]com"));
1768 }
1769 
1770 void KUrlTest::testSmb()
1771 {
1772     KUrl smb("smb://domain;username:password@server/share");
1773     QVERIFY(smb.isValid());
1774     QCOMPARE(smb.user(), QString("domain;username"));
1775     smb = "smb:/";
1776     QVERIFY(smb.isValid());
1777     QCOMPARE(smb.url(), QString::fromLatin1("smb:/"));
1778     QCOMPARE(smb.prettyUrl(), QString::fromLatin1("smb:/"));
1779     smb = "smb://"; // KDE3: kurl.cpp rev 1.106 made it invalid. Valid again with QUrl.
1780     QVERIFY(smb.isValid());
1781     QCOMPARE(smb.prettyUrl(), QString::fromLatin1("smb://"));
1782     smb = "smb://host";
1783     QVERIFY(smb.isValid());
1784     QCOMPARE(smb.url(), QString::fromLatin1("smb://host"));
1785     QCOMPARE(smb.prettyUrl(), QString::fromLatin1("smb://host"));
1786     smb = "smb:///";
1787     QVERIFY(smb.isValid());
1788     QCOMPARE(smb.prettyUrl(), QString::fromLatin1("smb:/"));
1789 
1790     KUrl implicitSmb("file://host/path");
1791     QVERIFY(!implicitSmb.isLocalFile()); // -> kio_file will redirect to smb (by default)
1792     QCOMPARE(implicitSmb.host(), QString("host"));
1793 
1794     KUrl noImplicitSmb("//path1/path2");
1795     QVERIFY(noImplicitSmb.isLocalFile());
1796     QCOMPARE(noImplicitSmb.path(), QString("//path1/path2"));
1797 }
1798 
1799 void KUrlTest::testOtherProtocols()
1800 {
1801     KUrl about("about:");
1802     QCOMPARE(about.path(), QString());
1803     QCOMPARE(about.protocol(), QString("about"));
1804 
1805     KUrl aboutKonqueror("about:konqueror");
1806     QCOMPARE(aboutKonqueror.path(), QString("konqueror"));
1807 
1808     KUrl leo("data:text/html,http://www.invalid/");
1809     QVERIFY(leo.isValid());
1810     QCOMPARE(leo.protocol(), QString("data"));
1811     QCOMPARE(leo.url(), QString("data:text/html,http://www.invalid/"));
1812     QCOMPARE(leo.path(), QString("text/html,http://www.invalid/"));
1813 
1814     KUrl testFrag("data:,test#foo");
1815     QVERIFY(testFrag.isValid());
1816     QCOMPARE(testFrag.protocol(), QString("data"));
1817     QCOMPARE(testFrag.url(), QString("data:,test#foo"));
1818     QCOMPARE(testFrag.path(), QString(",test"));
1819     QVERIFY(testFrag.hasFragment());
1820     QCOMPARE(testFrag.fragment(), QString("foo"));
1821 
1822     KUrl ptal("ptal://mlc:usb@PC_970");   // User=mlc, password=usb, host=PC_970
1823 #if QT_VERSION >= 0x040600 && QT_VERSION <= 0x040602 // Hostnames with underscores were invalid in 4.6.0 to 4.6.2, then allowed again in e301c82693c33c0f96c6a756d15fe35a9d877443
1824     QCOMPARE(ptal.url(), QString("ptal://mlc:usb@")); // The host "PC_970" is invalid according to STD3 validation
1825     KUrl ptalSimpler("ptal://mlc:usb@pc123");
1826     QCOMPARE(ptalSimpler.url(), QString("ptal://mlc:usb@pc123"));
1827 #else
1828     QUrl ptal_qurl;
1829     ptal_qurl.setUrl("ptal://mlc:usb@PC_970", QUrl::TolerantMode);
1830     QVERIFY(ptal_qurl.isValid());
1831     QCOMPARE(QString::fromLatin1(ptal_qurl.toEncoded()), QString::fromLatin1("ptal://mlc:usb@pc_970"));
1832     QCOMPARE(ptal_qurl.host(), QString("pc_970"));
1833 
1834     QVERIFY(ptal.isValid());
1835     QCOMPARE(ptal.host(), QString("pc_970"));
1836     QCOMPARE(ptal.user(), QString("mlc"));
1837     QCOMPARE(ptal.pass(), QString("usb"));
1838 #endif
1839 }
1840 
1841 void KUrlTest::testUtf8()
1842 {
1843     QTextCodec *codec = QTextCodec::codecForName("ISO-8859-1");
1844     QVERIFY(codec != nullptr);
1845     QTextCodec::setCodecForLocale(codec);
1846 
1847 #if 0
1848     {
1849         QUrl utest;
1850         utest.setScheme("file");
1851         utest.setPath(QString::fromUtf8("/home/dfaure/Matériel"));
1852         printf("utest.toString()=%s\n", utest.toString().toLatin1().constData());
1853         printf("utest.path()=%s\n", utest.path().toLatin1().constData());
1854         printf("utest.toEncoded()=%s\n", utest.toEncoded().data());
1855     }
1856 #endif
1857 
1858     // UTF8 tests
1859     KUrl uloc;
1860     uloc.setPath(QString::fromUtf8("/home/dfaure/Matériel"));
1861     QCOMPARE(uloc.url(), QString("file:///home/dfaure/Mat%C3%A9riel"));    // KDE3 would say %E9 here; but from now on URLs are always utf8 encoded.
1862     QCOMPARE(uloc.path(), QString::fromUtf8("/home/dfaure/Matériel"));
1863     QCOMPARE(uloc.prettyUrl(), QString::fromUtf8("file:///home/dfaure/Matériel"));
1864     QCOMPARE(uloc.pathOrUrl(), QString::fromUtf8("/home/dfaure/Matériel"));                // ... but that's why pathOrUrl is nicer.
1865     QCOMPARE(uloc.url(), QString("file:///home/dfaure/Mat%C3%A9riel"));
1866     uloc = KUrl("file:///home/dfaure/Mat%C3%A9riel");
1867     QCOMPARE(uloc.path(), QString::fromUtf8("/home/dfaure/Matériel"));
1868     QCOMPARE(uloc.url(), QString("file:///home/dfaure/Mat%C3%A9riel"));
1869 
1870     KUrl umlaut1("http://www.clever-tanken.de/liste.asp?ort=N%FCrnberg&typ=Diesel");
1871     QCOMPARE(umlaut1.url(), QString("http://www.clever-tanken.de/liste.asp?ort=N%FCrnberg&typ=Diesel"));
1872 
1873     KUrl umlaut2("http://www.clever-tanken.de/liste.asp?ort=N%FCrnberg&typ=Diesel"); // was ,106
1874     QCOMPARE(umlaut2.url(), QString("http://www.clever-tanken.de/liste.asp?ort=N%FCrnberg&typ=Diesel"));
1875 
1876     KUrl urlWithUnicodeChar(QString::fromUtf8("file:///home/dfaure/Matériel"));
1877     QCOMPARE(uloc.url(), QString("file:///home/dfaure/Mat%C3%A9riel"));
1878 
1879     KUrl wkai(QString::fromUtf8("/tmp/魔"));
1880     QCOMPARE(wkai.url(), QString("file:///tmp/%E9%AD%94"));
1881     QCOMPARE(wkai.prettyUrl(), QString::fromUtf8("file:///tmp/魔"));
1882 
1883     // Show that the character "fraction slash" (U+2044) cannot appear in url(),
1884     // so it's ok to use that to encode urls as filenames (e.g. in kio_http cache)
1885     KUrl fractionSlash(QString("http://kde.org/a") + QChar(0x2044) + "b");
1886     QCOMPARE(fractionSlash.url(), QString("http://kde.org/a%E2%81%84b"));
1887     QCOMPARE(fractionSlash.prettyUrl(), QString(QString("http://kde.org/a") + QChar(0x2044) + "b"));
1888 }
1889 
1890 void KUrlTest::testOtherEncodings()
1891 {
1892     QTextCodec::setCodecForLocale(QTextCodec::codecForName("koi8-r"));
1893     KUrl baseURL("file:/home/coolo");
1894     KUrl russian = QUrl::fromLocalFile(baseURL.directory(KUrl::AppendTrailingSlash) + QString::fromUtf8("фгн7"));
1895     //QCOMPARE( russian.url(), QString("file:///home/%C6%C7%CE7" ) ); // KDE3: was not using utf8
1896     QCOMPARE(russian.url(), QString("file:///home/%D1%84%D0%B3%D0%BD7"));   // QUrl uses utf8
1897 
1898     KUrl utf8_1("audiocd:/By%20Name/15%20Geantra%C3%AE.wav");
1899     QCOMPARE(utf8_1.fileName(), QString::fromUtf8("15 Geantraî.wav"));
1900 
1901     // KDE3: url had %2F, and fileName had '/'. But this is wrong, %2F means '/',
1902     // and filenames have to use %2F, so the url needs to have %252F.
1903     // KIO::encodeFileName takes care of that.
1904     KUrl utf8_2("audiocd:/By%20Name/15%252FGeantra%C3%AE.wav");
1905     QCOMPARE(utf8_2.path(), QString::fromUtf8("/By Name/15%2FGeantraî.wav"));
1906     QCOMPARE(utf8_2.fileName(), QString::fromUtf8("15%2FGeantraî.wav"));
1907 }
1908 
1909 void KUrlTest::testPathOrURL()
1910 {
1911     QUrl quloc = QUrl::fromLocalFile("/home/dfaure/konqtests/Mat%C3%A9riel");
1912     QCOMPARE(quloc.toLocalFile(), QString("/home/dfaure/konqtests/Mat%C3%A9riel"));
1913 
1914     // passing path or url to the constructor: both work
1915     KUrl uloc("/home/dfaure/konqtests/Mat%C3%A9riel");
1916     QCOMPARE(uloc.url(), QString("file:///home/dfaure/konqtests/Mat%25C3%25A9riel"));
1917     QCOMPARE(uloc.toLocalFile(), QString("/home/dfaure/konqtests/Mat%C3%A9riel"));
1918     uloc = KUrl("http://www.kde.org");
1919     QCOMPARE(uloc.pathOrUrl(), uloc.url());
1920     QCOMPARE(uloc.pathOrUrl(KUrl::AddTrailingSlash), QString("http://www.kde.org/"));
1921     uloc = KUrl(QString("www.kde.org"));
1922     QVERIFY(uloc.isValid());   // KDE3: was invalid. But it's now a url with path="www.kde.org", ok.
1923     uloc = KUrl("index.html");
1924     QVERIFY(uloc.isValid());   // KDE3: was invalid; same as above
1925     uloc = KUrl("");
1926     QVERIFY(!uloc.isValid());
1927 #ifdef Q_OS_WIN
1928 #ifdef Q_CC_MSVC
1929 #pragma message ("port KUser")
1930 #else
1931 #warning port KUser
1932 #endif
1933 #else
1934     KUser currentUser;
1935     const QString userName = currentUser.loginName();
1936     QVERIFY(!userName.isEmpty());
1937     uloc = KUrl(QString::fromUtf8("~%1/konqtests/Matériel").arg(userName));
1938     QEXPECT_FAIL("", "No more user-expansion in KUrl", Continue);
1939     QCOMPARE(uloc.path(), QString::fromUtf8("%1/konqtests/Matériel").arg(currentUser.homeDir()));
1940 #endif
1941 
1942     // pathOrUrl tests
1943     uloc = KUrl("/home/dfaure/konqtests/Mat%C3%A9riel");
1944     QCOMPARE(uloc.pathOrUrl(), uloc.path());
1945     uloc = "http://www.kde.org";
1946     QCOMPARE(uloc.url(), QString("http://www.kde.org"));
1947     uloc = "file:///home/dfaure/konq%20tests/Mat%C3%A9riel#ref";
1948     QCOMPARE(uloc.pathOrUrl(), QString::fromUtf8("file:///home/dfaure/konq tests/Matériel#ref"));
1949     uloc = "file:///home/dfaure/konq%20tests/Mat%C3%A9riel?query";
1950     QCOMPARE(uloc.pathOrUrl(), QString::fromUtf8("file:///home/dfaure/konq tests/Matériel?query"));
1951     uloc = KUrl("/home/dfaure/file#with#hash");
1952     QCOMPARE(uloc.pathOrUrl(), QString("/home/dfaure/file#with#hash"));
1953 
1954     // test creation of url from pathOrUrl
1955     uloc = KUrl(QString::fromUtf8("http://www.kde.org/home/andreas/täst"));
1956     QCOMPARE(KUrl(uloc.pathOrUrl()), uloc);
1957     uloc = KUrl("http://www.kde.org/home/andreas/t%C3%A4st");
1958     QCOMPARE(KUrl(uloc.pathOrUrl()), uloc);
1959     uloc = KUrl(QString::fromUtf8("file:///home/andreas/täst"));
1960     QCOMPARE(KUrl(uloc.pathOrUrl()), uloc);
1961     uloc = KUrl("file:///home/andreas/t%C3%A4st");
1962     QCOMPARE(KUrl(uloc.pathOrUrl()), uloc);
1963     uloc = KUrl("http://www.kde.org/home/kde?foobar#test");
1964     QCOMPARE(KUrl(uloc.pathOrUrl()), uloc);
1965     uloc = KUrl("http://www.kde.org/home/%andreas");
1966     QCOMPARE(KUrl(uloc.pathOrUrl()), uloc);
1967 }
1968 
1969 void KUrlTest::testAssignment()
1970 {
1971     // passing path or url to the constructor: both work
1972     KUrl uloc;
1973     uloc = "/home/dfaure/konqtests/Mat%C3%A9riel";
1974     QCOMPARE(uloc.toLocalFile(), QString::fromUtf8("/home/dfaure/konqtests/Mat%C3%A9riel"));
1975     KUrl u2;
1976     u2 = uloc;
1977     QCOMPARE(u2.toLocalFile(), QString::fromUtf8("/home/dfaure/konqtests/Mat%C3%A9riel"));
1978     uloc = "http://www.kde.org";
1979     QCOMPARE(uloc.pathOrUrl(), uloc.url());
1980     uloc = QString("www.kde.org");
1981     QVERIFY(uloc.isValid());
1982     uloc = KUrl("index.html");
1983     QVERIFY(uloc.isValid());
1984     uloc = KUrl("");
1985     QVERIFY(!uloc.isValid());
1986 #ifdef Q_OS_WIN
1987 #ifdef Q_CC_MSVC
1988 #pragma message ("port KUser")
1989 #else
1990 #warning port KUser
1991 #endif
1992 #else
1993     KUser currentUser;
1994     const QString userName = currentUser.loginName();
1995     QVERIFY(!userName.isEmpty());
1996     uloc = QString::fromUtf8("~%1/konqtests/Matériel").arg(userName);
1997     QEXPECT_FAIL("", "No more user-expansion in KUrl", Continue);
1998     QCOMPARE(uloc.path(), QString::fromUtf8("%1/konqtests/Matériel").arg(currentUser.homeDir()));
1999     uloc = QByteArray('~' + userName.toUtf8() + "/konqtests/Matériel");
2000     QEXPECT_FAIL("", "No more user-expansion in KUrl", Continue);
2001     QCOMPARE(uloc.path(), QString::fromUtf8("%1/konqtests/Matériel").arg(currentUser.homeDir()));
2002 
2003     // Assigning a KUrl to a QUrl and back
2004     QUrl qurl = uloc;
2005     QCOMPARE(qurl.toEncoded(), uloc.toEncoded());
2006     uloc = KUrl(qurl);
2007     QCOMPARE(qurl.toEncoded(), uloc.toEncoded());
2008     QEXPECT_FAIL("", "No more user-expansion in KUrl", Continue);
2009     QCOMPARE(uloc.path(), QString::fromUtf8("%1/konqtests/Matériel").arg(currentUser.homeDir()));
2010 #endif
2011 }
2012 
2013 void KUrlTest::testQueryItem()
2014 {
2015     KUrl theKow("http://www.google.de/search?q=frerich&hlx=xx&hl=de&empty=&lr=lang+de&test=%2B%20%3A%25");
2016     QCOMPARE(theKow.queryItem("q"), QString("frerich"));
2017     QCOMPARE(theKow.queryItem("hl"), QString("de"));
2018     QCOMPARE(theKow.queryItem("lr"), QString("lang de"));   // the '+' got decoded
2019     QCOMPARE(theKow.queryItem("InterstellarCounselor"), QString());
2020     QCOMPARE(theKow.queryItem("empty"), QString(""));
2021     QCOMPARE(theKow.queryItem("test"), QString("+ :%"));
2022     theKow.addQueryItem("a", "b+c");
2023     QCOMPARE(theKow.url(), QString("http://www.google.de/search?q=frerich&hlx=xx&hl=de&empty=&lr=lang+de&test=%2B%20%3A%25&a=b%2Bc"));   // KDE3 would use b%2Bc, but this is more correct
2024     QCOMPARE(theKow.queryItem("a"), QString("b+c"));   // note that the '+' remained
2025 
2026     // checks for queryItems(), which returns a QMap<QString,QString>:
2027     KUrl queryUrl("mailto:Marc%20Mutz%20%3cmutz@kde.org%3E?"
2028                   "Subject=subscribe+me&"
2029                   "body=subscribe+mutz%40kde.org&"
2030                   "Cc=majordomo%40lists.kde.org");
2031     QCOMPARE(QStringList(queryUrl.queryItems(KUrl::QueryItemsOptions()).keys()).join(", "),
2032              QString("Cc, Subject, body"));
2033     QCOMPARE(QStringList(queryUrl.queryItems(KUrl::CaseInsensitiveKeys).keys()).join(", "),
2034              QString("body, cc, subject"));
2035     QCOMPARE(QStringList(queryUrl.queryItems(KUrl::QueryItemsOptions()).values()).join(", "),
2036              QString("majordomo@lists.kde.org, subscribe me, subscribe mutz@kde.org"));
2037     QCOMPARE(QStringList(queryUrl.queryItems(KUrl::CaseInsensitiveKeys).values()).join(", "),
2038              QString("subscribe mutz@kde.org, majordomo@lists.kde.org, subscribe me"));
2039     // TODO check for QUrl::queryItems
2040 
2041 }
2042 
2043 void KUrlTest::testEncodeString()
2044 {
2045     // Needed for #49616
2046     QCOMPARE(QUrl::toPercentEncoding("C++"), QByteArray("C%2B%2B"));
2047     QCOMPARE(QUrl::fromPercentEncoding("C%2B%2B"), QString("C++"));
2048     QCOMPARE(QUrl::toPercentEncoding("%"), QByteArray("%25"));
2049     QCOMPARE(QUrl::toPercentEncoding(":"), QByteArray("%3A"));
2050     QCOMPARE(QUrl::fromPercentEncoding("C%A"), QString("C%A"));     // % A is not percent-encoding  (pct-encoded = "%" HEXDIG HEXDIG)
2051 
2052     QString output = QUrl::fromPercentEncoding("C%00%0A");
2053     QString expected = QString::fromLatin1("C\0\n", 3); // no reason to stop at %00, in fact
2054     QCOMPARE(output.size(), expected.size());
2055     QCOMPARE(output, expected);
2056 }
2057 
2058 void KUrlTest::testIdn()
2059 {
2060     //qDebug( "trying QUrl with fromPercentEncoding" );
2061     QUrl qurltest(QUrl::fromPercentEncoding("http://\303\244.de"));     // a+trema in utf8
2062     QVERIFY(qurltest.isValid());
2063 
2064     //qDebug( "trying QUrl with fromEncoded" );
2065     QUrl qurl = QUrl::fromEncoded("http://\303\244.de");   // a+trema in utf8
2066     QVERIFY(qurl.isValid());
2067     QCOMPARE(qurl.toEncoded(), QByteArray("http://xn--4ca.de"));
2068 
2069     //qDebug( "and now trying KUrl" );
2070     KUrl thiago(QString::fromUtf8("http://\303\244.de"));     // a+trema in utf8
2071     QVERIFY(thiago.isValid());
2072     QCOMPARE(thiago.url(), QString("http://xn--4ca.de"));     // Non-ascii is allowed in IDN domain names.
2073 
2074 #if 0
2075     // A broken test - not using utf8. and amantia forgot the real-world testcase.
2076     KUrl amantia("http://%E1.foo.de");
2077     QVERIFY(amantia.isValid());
2078     QCOMPARE(amantia.url(), QString("http://xn--80a.foo.de"));     // Non-ascii is allowed in IDN domain names.
2079 #endif
2080 
2081     // A more valid test for % in hostnames:
2082     KUrl uwp("http://%C3%A4.de");
2083     QVERIFY(uwp.isValid());
2084     QCOMPARE(thiago.url(), QString("http://xn--4ca.de"));   // as above
2085 }
2086 
2087 void KUrlTest::testUriMode()
2088 {
2089     KUrl url1;
2090 #if 0 // ###### TODO KUri
2091     url1 = "http://www.foobar.com/";
2092     QCOMPARE(url1.uriMode(), KUrl::URL);
2093     url1 = "mailto:user@host.com";
2094     QCOMPARE(url1.uriMode(), KUrl::Mailto);
2095 
2096     url1 = "data:text/plain,foobar?gazonk=flarp";
2097     QCOMPARE(url1.uriMode(), KUrl::RawURI);
2098 
2099     QCOMPARE(url1.path(), QString("text/plain,foobar?gazonk=flarp"));
2100 #endif
2101     url1 = "mailto:User@Host.COM?subject=Hello";
2102     QCOMPARE(url1.path(), QString("User@Host.COM"));   // KDE3: "User@host.com". Does it matter?
2103 }
2104 
2105 void KUrlTest::testToLocalFile()
2106 {
2107     const QString localFile("/tmp/print.pdf");
2108 
2109     const KUrl urlWithHost("file://localhost/tmp/print.pdf");
2110     const KUrl urlWithoutHost("file:///tmp/print.pdf");
2111 
2112     QCOMPARE(urlWithHost.toLocalFile(), localFile);
2113     QCOMPARE(urlWithoutHost.toLocalFile(), localFile);
2114 }
2115 
2116 void KUrlTest::testUrl_data()
2117 {
2118     QTest::addColumn<KUrl>("url");
2119     QTest::addColumn<QString>("urlLTS");
2120     QTest::addColumn<QString>("urlRTS");
2121     QTest::addColumn<QString>("urlATS");
2122 
2123     QTest::newRow("local file 1")
2124             << KUrl("file:///")
2125             << QString::fromLatin1("file:///")
2126             << QString::fromLatin1("file:///")
2127             << QString::fromLatin1("file:///");
2128     QTest::newRow("local file 2")
2129             << KUrl("file:///home/kde/")
2130             << QString::fromLatin1("file:///home/kde/")
2131             << QString::fromLatin1("file:///home/kde")
2132             << QString::fromLatin1("file:///home/kde/");
2133     QTest::newRow("local file 3")
2134             << KUrl("file:///home/kde//")
2135             << QString::fromLatin1("file:///home/kde//")
2136             << QString::fromLatin1("file:///home/kde")
2137             << QString::fromLatin1("file:///home/kde//");
2138 
2139     QTest::newRow("ftp url")
2140             << KUrl("ftp://ftp.kde.org/")
2141             << QString::fromLatin1("ftp://ftp.kde.org/")
2142             << QString::fromLatin1("ftp://ftp.kde.org/")
2143             << QString::fromLatin1("ftp://ftp.kde.org/");
2144     QTest::newRow("ftp url - 3 trailing slashes")
2145             << KUrl("ftp://ftp.kde.org///")
2146             << QString::fromLatin1("ftp://ftp.kde.org///")
2147             << QString::fromLatin1("ftp://ftp.kde.org/")
2148             << QString::fromLatin1("ftp://ftp.kde.org///");
2149 }
2150 
2151 void KUrlTest::testUrl()
2152 {
2153     QFETCH(KUrl, url);
2154     QFETCH(QString, urlLTS);
2155     QFETCH(QString, urlRTS);
2156     QFETCH(QString, urlATS);
2157 
2158     QCOMPARE(url.url(KUrl::LeaveTrailingSlash), urlLTS);
2159     QCOMPARE(url.url(KUrl::RemoveTrailingSlash), urlRTS);
2160     QCOMPARE(url.url(KUrl::AddTrailingSlash), urlATS);
2161 }
2162 
2163 void KUrlTest::testToStringList()
2164 {
2165     KUrl::List urls;
2166     urls << KUrl("file:///")
2167          << KUrl("file:///home/kde/")
2168          << KUrl("file:///home/kde//")
2169          << KUrl("ftp://ftp.kde.org/")
2170          << KUrl("ftp://ftp.kde.org///");
2171 
2172     //kDebug() << urls.toStringList(KUrl::LeaveTrailingSlash);
2173     QCOMPARE(urls.toStringList(KUrl::LeaveTrailingSlash),
2174              QStringList()
2175              << QLatin1String("file:///")
2176              << QLatin1String("file:///home/kde/")
2177              << QLatin1String("file:///home/kde//")
2178              << QLatin1String("ftp://ftp.kde.org/")
2179              << QLatin1String("ftp://ftp.kde.org///"));
2180 
2181     //kDebug() << urls.toStringList(KUrl::RemoveTrailingSlash);
2182     QCOMPARE(urls.toStringList(KUrl::RemoveTrailingSlash),
2183              QStringList()
2184              << QLatin1String("file:///")
2185              << QLatin1String("file:///home/kde")
2186              << QLatin1String("file:///home/kde")
2187              << QLatin1String("ftp://ftp.kde.org/")
2188              << QLatin1String("ftp://ftp.kde.org/"));
2189 
2190     //kDebug() << urls.toStringList(KUrl::AddTrailingSlash);
2191     QCOMPARE(urls.toStringList(KUrl::AddTrailingSlash),
2192              QStringList()
2193              << QLatin1String("file:///")
2194              << QLatin1String("file:///home/kde/")
2195              << QLatin1String("file:///home/kde//")
2196              << QLatin1String("ftp://ftp.kde.org/")
2197              << QLatin1String("ftp://ftp.kde.org///"));
2198 }
2199 
2200 void KUrlTest::testHashing()
2201 {
2202     QHash<KUrl, QUrl> hash;
2203     hash.insert(KUrl("http://www.kde.org/foo%23bar"), QUrl("http://www.kde.org/foo%23bar"));
2204     hash.insert(KUrl("http://www.kde.org/foo#ref?query"), QUrl("http://www.kde.org/foo#ref?query"));
2205 
2206     QHashIterator<KUrl, QUrl> it(hash);
2207     while (it.hasNext()) {
2208         it.next();
2209         QCOMPARE(it.key().url(), it.value().toString());
2210     }
2211 }