util/tests/auto/qurl/tst_qurl.cpp
changeset 7 f7bc934e204c
equal deleted inserted replaced
3:41300fa6a67c 7:f7bc934e204c
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the test suite of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 
       
    43 #include <QtTest/QtTest>
       
    44 #include <QtCore/QDebug>
       
    45 
       
    46 #include <qcoreapplication.h>
       
    47 
       
    48 #include <qfileinfo.h>
       
    49 #include <qurl.h>
       
    50 #include <qtextcodec.h>
       
    51 #include <qmap.h>
       
    52 
       
    53 // For testsuites
       
    54 #define IDNA_ACE_PREFIX "xn--"
       
    55 #define IDNA_SUCCESS 1
       
    56 #define STRINGPREP_NO_UNASSIGNED 1
       
    57 #define STRINGPREP_CONTAINS_UNASSIGNED 2
       
    58 #define STRINGPREP_CONTAINS_PROHIBITED 3
       
    59 #define STRINGPREP_BIDI_BOTH_L_AND_RAL 4
       
    60 #define STRINGPREP_BIDI_LEADTRAIL_NOT_RAL 5
       
    61 
       
    62 struct ushortarray {
       
    63     ushortarray(unsigned short *array = 0)
       
    64     {
       
    65         if (array)
       
    66             memcpy(points, array, sizeof(points));
       
    67     }
       
    68 
       
    69     unsigned short points[100];
       
    70 };
       
    71 
       
    72 Q_DECLARE_METATYPE(ushortarray)
       
    73 Q_DECLARE_METATYPE(QUrl::FormattingOptions)
       
    74 
       
    75 //TESTED_CLASS=
       
    76 //TESTED_FILES=
       
    77 
       
    78 class tst_QUrl : public QObject
       
    79 {
       
    80     Q_OBJECT
       
    81 
       
    82 public:
       
    83     tst_QUrl();
       
    84     virtual ~tst_QUrl();
       
    85 
       
    86 
       
    87 public slots:
       
    88     void init();
       
    89     void cleanup();
       
    90 private slots:
       
    91     void getSetCheck();
       
    92     void constructing();
       
    93     void assignment();
       
    94     void comparison();
       
    95     void copying();
       
    96     void setUrl();
       
    97     void i18n_data();
       
    98     void i18n();
       
    99     void punycode_data();
       
   100     void punycode();
       
   101     void resolving_data();
       
   102     void resolving();
       
   103     void toString_data();
       
   104     void toString();
       
   105     void toString_constructed_data();
       
   106     void toString_constructed();
       
   107     void isParentOf_data();
       
   108     void isParentOf();
       
   109     void toLocalFile_data();
       
   110     void toLocalFile();
       
   111     void fromLocalFile_data();
       
   112     void fromLocalFile();
       
   113     void relative();
       
   114     void compat_legacy();
       
   115     void compat_constructor_01_data();
       
   116     void compat_constructor_01();
       
   117     void compat_constructor_02_data();
       
   118     void compat_constructor_02();
       
   119     void compat_constructor_03_data();
       
   120     void compat_constructor_03();
       
   121     void compat_isValid_01_data();
       
   122     void compat_isValid_01();
       
   123     void compat_isValid_02_data();
       
   124     void compat_isValid_02();
       
   125     void compat_path_data();
       
   126     void compat_path();
       
   127     void compat_fileName_data();
       
   128     void compat_fileName();
       
   129     void compat_decode_data();
       
   130     void compat_decode();
       
   131     void compat_encode_data();
       
   132     void compat_encode();
       
   133     void percentEncoding_data();
       
   134     void percentEncoding();
       
   135     void symmetry();
       
   136     void ipv6_data();
       
   137     void ipv6();
       
   138     void ipv6_2_data();
       
   139     void ipv6_2();
       
   140     void moreIpv6();
       
   141     void toPercentEncoding_data();
       
   142     void toPercentEncoding();
       
   143     void isRelative_data();
       
   144     void isRelative();
       
   145     void queryItems();
       
   146     void hasQuery_data();
       
   147     void hasQuery();
       
   148     void hasQueryItem_data();
       
   149     void hasQueryItem();
       
   150     void nameprep();
       
   151     void isValid();
       
   152     void schemeValidator_data();
       
   153     void schemeValidator();
       
   154     void invalidSchemeValidator();
       
   155     void tolerantParser();
       
   156     void correctEncodedMistakes_data();
       
   157     void correctEncodedMistakes();
       
   158     void correctDecodedMistakes_data();
       
   159     void correctDecodedMistakes();
       
   160     void idna_testsuite_data();
       
   161     void idna_testsuite();
       
   162     void nameprep_testsuite_data();
       
   163     void nameprep_testsuite();
       
   164     void ace_testsuite_data();
       
   165     void ace_testsuite();
       
   166     void std3violations_data();
       
   167     void std3violations();
       
   168     void std3deviations_data();
       
   169     void std3deviations();
       
   170     void tldRestrictions_data();
       
   171     void tldRestrictions();
       
   172     void emptyQueryOrFragment();
       
   173     void hasFragment_data();
       
   174     void hasFragment();
       
   175     void setEncodedFragment_data();
       
   176     void setEncodedFragment();
       
   177     void fromEncoded();
       
   178     void stripTrailingSlash();
       
   179     void hosts_data();
       
   180     void hosts();
       
   181     void setPort();
       
   182     void toEncoded_data();
       
   183     void toEncoded();
       
   184     void setAuthority_data();
       
   185     void setAuthority();
       
   186     void errorString();
       
   187     void clear();
       
   188     void resolvedWithAbsoluteSchemes() const;
       
   189     void resolvedWithAbsoluteSchemes_data() const;
       
   190     void binaryData_data();
       
   191     void binaryData();
       
   192     void fromUserInput_data();
       
   193     void fromUserInput();
       
   194     void task_199967();
       
   195     void task_240612();
       
   196 
       
   197 #ifdef QT3_SUPPORT
       
   198     void dirPath();
       
   199 #endif
       
   200 };
       
   201 
       
   202 // Testing get/set functions
       
   203 void tst_QUrl::getSetCheck()
       
   204 {
       
   205     QUrl obj1;
       
   206     // int QUrl::port()
       
   207     // void QUrl::setPort(int)
       
   208     obj1.setPort(0);
       
   209     QCOMPARE(0, obj1.port());
       
   210 
       
   211     QTest::ignoreMessage(QtWarningMsg, "QUrl::setPort: Out of range");
       
   212     obj1.setPort(INT_MIN);
       
   213     QCOMPARE(-1, obj1.port()); // Out of range, -1
       
   214 
       
   215     QTest::ignoreMessage(QtWarningMsg, "QUrl::setPort: Out of range");
       
   216     obj1.setPort(INT_MAX);
       
   217     QCOMPARE(-1, obj1.port()); // Out of range, -1
       
   218 
       
   219     obj1.setPort(1234);
       
   220     QCOMPARE(1234, obj1.port());
       
   221 
       
   222     // static QStringList QUrl::idnWhitelist()
       
   223     // static void QUrl::setIdnWhitelist(QStringList)
       
   224     QStringList original = QUrl::idnWhitelist(); // save for later
       
   225 
       
   226     QUrl::setIdnWhitelist(QStringList());
       
   227     QCOMPARE(QUrl::idnWhitelist(), QStringList());
       
   228 
       
   229     QStringList norway; norway << "no";
       
   230     QUrl::setIdnWhitelist(norway);
       
   231     QCOMPARE(QUrl::idnWhitelist(), norway);
       
   232 
       
   233     QStringList modified = original;
       
   234     modified << "foo";
       
   235     QUrl::setIdnWhitelist(modified);
       
   236     QCOMPARE(QUrl::idnWhitelist(), modified);
       
   237 
       
   238     // reset to the original
       
   239     QUrl::setIdnWhitelist(original);
       
   240     QCOMPARE(QUrl::idnWhitelist(), original);
       
   241 }
       
   242 
       
   243 tst_QUrl::tst_QUrl()
       
   244 {
       
   245 }
       
   246 
       
   247 tst_QUrl::~tst_QUrl()
       
   248 {
       
   249 
       
   250 }
       
   251 
       
   252 void tst_QUrl::init()
       
   253 {
       
   254 }
       
   255 
       
   256 void tst_QUrl::cleanup()
       
   257 {
       
   258 }
       
   259 
       
   260 void tst_QUrl::constructing()
       
   261 {
       
   262     QUrl url;
       
   263     QVERIFY(!url.isValid());
       
   264     QVERIFY(url.isEmpty());
       
   265     QCOMPARE(url.port(), -1);
       
   266     QCOMPARE(url.toString(), QString());
       
   267 
       
   268     QList<QPair<QString, QString> > query;
       
   269     query += qMakePair(QString("type"), QString("login"));
       
   270     query += qMakePair(QString("name"), QString("åge nissemannsen"));
       
   271     query += qMakePair(QString("ole&du"), QString("anne+jørgen=sant"));
       
   272     query += qMakePair(QString("prosent"), QString("%"));
       
   273     url.setQueryItems(query);
       
   274     QVERIFY(!url.isEmpty());
       
   275 
       
   276     QCOMPARE(url.encodedQuery().constData(),
       
   277             QByteArray("type=login&name=%C3%A5ge%20nissemannsen&ole%26du="
       
   278                        "anne+j%C3%B8rgen%3Dsant&prosent=%25").constData());
       
   279 
       
   280     url.setQueryDelimiters('>', '/');
       
   281     url.setQueryItems(query);
       
   282 
       
   283     QCOMPARE(url.encodedQuery(),
       
   284             QByteArray("type>login/name>%C3%A5ge%20nissemannsen/ole&du>"
       
   285                        "anne+j%C3%B8rgen=sant/prosent>%25"));
       
   286 
       
   287     url.setFragment(QString::fromLatin1("top"));
       
   288     QCOMPARE(url.fragment(), QString::fromLatin1("top"));
       
   289 
       
   290     url.setScheme("http");
       
   291     url.setHost("qt.nokia.com");
       
   292 
       
   293     QCOMPARE(url.toString(),
       
   294             QString::fromLatin1("http://qt.nokia.com?type>login/name>åge nissemannsen"
       
   295                           "/ole&du>anne+jørgen=sant/prosent>%#top"));
       
   296 
       
   297     QUrl justHost("qt.nokia.com");
       
   298     QVERIFY(!justHost.isEmpty());
       
   299     QVERIFY(justHost.host().isEmpty());
       
   300     QCOMPARE(justHost.path(), QString::fromLatin1("qt.nokia.com"));
       
   301 
       
   302     QUrl hostWithSlashes("//qt.nokia.com");
       
   303     QVERIFY(hostWithSlashes.path().isEmpty());
       
   304     QCOMPARE(hostWithSlashes.host(), QString::fromLatin1("qt.nokia.com"));
       
   305 
       
   306 
       
   307     QUrl withHashInPath;
       
   308     withHashInPath.setPath(QString::fromLatin1("hi#mum.txt"));
       
   309     QCOMPARE(withHashInPath.path(), QString::fromLatin1("hi#mum.txt"));
       
   310     QCOMPARE(withHashInPath.toEncoded(), QByteArray("hi%23mum.txt"));
       
   311     QUrl fromHashInPath = QUrl::fromEncoded(withHashInPath.toEncoded());
       
   312     QVERIFY(withHashInPath == fromHashInPath);
       
   313 
       
   314 
       
   315     QUrl buildUNC;
       
   316     buildUNC.setHost(QString::fromLatin1("somehost"));
       
   317     buildUNC.setPath(QString::fromLatin1("somepath"));
       
   318     QCOMPARE(buildUNC.toLocalFile(), QString::fromLatin1("//somehost/somepath"));
       
   319     buildUNC.toEncoded();
       
   320     QVERIFY(!buildUNC.isEmpty());
       
   321 }
       
   322 
       
   323 void tst_QUrl::assignment()
       
   324 {
       
   325     QUrl url("http://qt.nokia.com/");
       
   326     QVERIFY(url.isValid());
       
   327 
       
   328     QUrl copy;
       
   329     copy = url;
       
   330 
       
   331     QVERIFY(url == copy);
       
   332 }
       
   333 
       
   334 void tst_QUrl::comparison()
       
   335 {
       
   336     QUrl url1("http://qt.nokia.com/");
       
   337     QVERIFY(url1.isValid());
       
   338 
       
   339     QUrl url2("http://qt.nokia.com/");
       
   340     QVERIFY(url2.isValid());
       
   341 
       
   342     QVERIFY(url1 == url2);
       
   343 
       
   344     // 6.2.2 Syntax-based Normalization
       
   345     QUrl url3 = QUrl::fromEncoded("example://a/b/c/%7Bfoo%7D");
       
   346     QUrl url4 = QUrl::fromEncoded("eXAMPLE://a/./b/../b/%63/%7bfoo%7d");
       
   347     QVERIFY(url3 == url4);
       
   348 
       
   349     // 6.2.2.1 Make sure hexdecimal characters in percent encoding are
       
   350     // treated case-insensitively
       
   351     QUrl url5;
       
   352     url5.setEncodedQuery("a=%2a");
       
   353     QUrl url6;
       
   354     url6.setEncodedQuery("a=%2A");
       
   355     QVERIFY(url5 == url6);
       
   356 
       
   357     // ensure that encoded characters in the query do not match
       
   358     QUrl url7;
       
   359     url7.setEncodedQuery("a=%63");
       
   360     QUrl url8;
       
   361     url8.setEncodedQuery("a=c");
       
   362     QVERIFY(url7 != url8);
       
   363 }
       
   364 
       
   365 void tst_QUrl::copying()
       
   366 {
       
   367     QUrl url("http://qt.nokia.com/");
       
   368     QVERIFY(url.isValid());
       
   369 
       
   370     QUrl copy(url);
       
   371 
       
   372     QVERIFY(url == copy);
       
   373 }
       
   374 
       
   375 void tst_QUrl::setUrl()
       
   376 {
       
   377     {
       
   378         QUrl url("http://0.foo.com");
       
   379         QVERIFY(url.isValid());
       
   380         QCOMPARE(url.scheme(), QString::fromLatin1("http"));
       
   381         QCOMPARE(url.path(), QString());
       
   382         QCOMPARE(url.host(), QString::fromLatin1("0.foo.com"));
       
   383     }
       
   384 
       
   385     {
       
   386         QUrl url("file:/");
       
   387         QVERIFY(url.isValid());
       
   388         QCOMPARE(url.scheme(), QString::fromLatin1("file"));
       
   389         QCOMPARE(url.path(), QString::fromLatin1("/"));
       
   390         QVERIFY(url.encodedQuery().isEmpty());
       
   391         QVERIFY(url.userInfo().isEmpty());
       
   392         QVERIFY(url.authority().isEmpty());
       
   393         QVERIFY(url.fragment().isEmpty());
       
   394         QCOMPARE(url.port(), -1);
       
   395     }
       
   396 
       
   397     {
       
   398         QUrl url("hTTp://www.foo.bar:80");
       
   399         QVERIFY(url.isValid());
       
   400         QCOMPARE(url.scheme(), QString::fromLatin1("hTTp"));
       
   401         QCOMPARE(url.path(), QString());
       
   402         QVERIFY(url.encodedQuery().isEmpty());
       
   403         QVERIFY(url.userInfo().isEmpty());
       
   404         QVERIFY(url.fragment().isEmpty());
       
   405         QCOMPARE(url.host(), QString::fromLatin1("www.foo.bar"));
       
   406         QCOMPARE(url.authority(), QString::fromLatin1("www.foo.bar:80"));
       
   407         QCOMPARE(url.port(), 80);
       
   408 
       
   409         QUrl url2("//www1.foo.bar");
       
   410         QCOMPARE(url.resolved(url2).toString(), QString::fromLatin1("hTTp://www1.foo.bar"));
       
   411     }
       
   412 
       
   413     {
       
   414         QUrl url("http://user:pass@[56::56:56:56:127.0.0.1]:99");
       
   415         QVERIFY(url.isValid());
       
   416         QCOMPARE(url.scheme(), QString::fromLatin1("http"));
       
   417         QCOMPARE(url.path(), QString());
       
   418         QVERIFY(url.encodedQuery().isEmpty());
       
   419         QCOMPARE(url.userInfo(), QString::fromLatin1("user:pass"));
       
   420         QVERIFY(url.fragment().isEmpty());
       
   421         QCOMPARE(url.host(), QString::fromLatin1("56::56:56:56:127.0.0.1"));
       
   422         QCOMPARE(url.authority(), QString::fromLatin1("user:pass@[56::56:56:56:127.0.0.1]:99"));
       
   423         QCOMPARE(url.port(), 99);
       
   424     }
       
   425 
       
   426     {
       
   427         QUrl url("http://www.foo.bar");
       
   428         QVERIFY(url.isValid());
       
   429 
       
   430         QUrl url2("/top//test/../test1/file.html");
       
   431         QCOMPARE(url.resolved(url2).toString(), QString::fromLatin1("http://www.foo.bar/top//test1/file.html"));
       
   432     }
       
   433 
       
   434     {
       
   435         QUrl url("http://www.foo.bar");
       
   436         QVERIFY(url.isValid());
       
   437 
       
   438         QUrl url2("/top//test/../test1/file.html");
       
   439         QCOMPARE(url.resolved(url2).toString(), QString::fromLatin1("http://www.foo.bar/top//test1/file.html"));
       
   440     }
       
   441 
       
   442     {
       
   443         QUrl url("http://www.foo.bar/top//test2/file2.html");
       
   444         QVERIFY(url.isValid());
       
   445 
       
   446         QCOMPARE(url.toString(), QString::fromLatin1("http://www.foo.bar/top//test2/file2.html"));
       
   447     }
       
   448 
       
   449     {
       
   450         QUrl url("http://www.foo.bar/top//test2/file2.html");
       
   451         QVERIFY(url.isValid());
       
   452 
       
   453         QCOMPARE(url.toString(), QString::fromLatin1("http://www.foo.bar/top//test2/file2.html"));
       
   454     }
       
   455 
       
   456     {
       
   457         QUrl url("file:/usr/local/src/kde2/////kdelibs/kio");
       
   458         QVERIFY(url.isValid());
       
   459         QCOMPARE(url.toString(), QString::fromLatin1("file:///usr/local/src/kde2/////kdelibs/kio"));
       
   460     }
       
   461 
       
   462     {
       
   463         QUrl url("http://www.foo.bar");
       
   464         QVERIFY(url.isValid());
       
   465 
       
   466         QUrl url2("mailto:bastian@kde.org");
       
   467         QVERIFY(url2.isValid());
       
   468         QCOMPARE(url.resolved(url2).toString(), QString::fromLatin1("mailto:bastian@kde.org"));
       
   469     }
       
   470 
       
   471     {
       
   472         QUrl url("mailto:bastian@kde.org?subject=hello");
       
   473         QCOMPARE(url.toString(), QString::fromLatin1("mailto:bastian@kde.org?subject=hello"));
       
   474     }
       
   475 
       
   476     {
       
   477         QUrl url("file:/usr/local/src/kde2/kdelibs/kio/");
       
   478         QVERIFY(url.isValid());
       
   479 
       
   480         QUrl url2("../../////kdebase/konqueror");
       
   481         QCOMPARE(url.resolved(url2).toString(),
       
   482                 QString::fromLatin1("file:///usr/local/src/kde2/////kdebase/konqueror"));
       
   483     }
       
   484 
       
   485     {
       
   486         QString u1 = "file:/home/dfaure/my#myref";
       
   487         QUrl url = u1;
       
   488         QVERIFY(url.isValid());
       
   489         QCOMPARE(url.toString(), QString::fromLatin1("file:///home/dfaure/my#myref"));
       
   490         QCOMPARE(url.fragment(), QString::fromLatin1("myref"));
       
   491     }
       
   492 
       
   493     {
       
   494         QString u1 = "file:/home/dfaure/my#myref";
       
   495         QUrl url = u1;
       
   496         QVERIFY(url.isValid());
       
   497 
       
   498         QCOMPARE(url.toString(), QString::fromLatin1("file:///home/dfaure/my#myref"));
       
   499         QCOMPARE(url.fragment(), QString::fromLatin1("myref"));
       
   500     }
       
   501 
       
   502     {
       
   503         QUrl url("gg:www.kde.org");
       
   504         QVERIFY(url.isValid());
       
   505         QCOMPARE(url.scheme(), QString::fromLatin1("gg"));
       
   506         QVERIFY(url.host().isEmpty());
       
   507         QCOMPARE(url.path(), QString::fromLatin1("www.kde.org"));
       
   508     }
       
   509 
       
   510     {
       
   511         QUrl url("KDE");
       
   512         QVERIFY(url.isValid());
       
   513         QCOMPARE(url.path(), QString::fromLatin1("KDE"));
       
   514         QVERIFY(url.scheme().isEmpty());
       
   515     }
       
   516 
       
   517     {
       
   518         QUrl url("$HOME/.kde/share/config");
       
   519         QVERIFY(url.isValid());
       
   520         QCOMPARE(url.path(), QString::fromLatin1("$HOME/.kde/share/config"));
       
   521         QVERIFY(url.scheme().isEmpty());
       
   522     }
       
   523 
       
   524     {
       
   525         QUrl url("file:/opt/kde2/qt2/doc/html/showimg-main-cpp.html#QObject::connect");
       
   526         QVERIFY(url.isValid());
       
   527         QCOMPARE(url.fragment(), QString::fromLatin1("QObject::connect"));
       
   528     }
       
   529 
       
   530     {
       
   531         QUrl url("file:/opt/kde2/qt2/doc/html/showimg-main-cpp.html#QObject:connect");
       
   532         QVERIFY(url.isValid());
       
   533         QCOMPARE(url.fragment(), QString::fromLatin1("QObject:connect"));
       
   534     }
       
   535 
       
   536     {
       
   537         // suburls
       
   538         QUrl url("file:/home/dfaure/my%20tar%20file.tgz#gzip:/#tar:/#myref");
       
   539         QVERIFY(url.isValid());
       
   540 
       
   541         // or simply 'myref?'
       
   542         QCOMPARE(url.fragment(), QString::fromLatin1("gzip:/#tar:/#myref"));
       
   543     }
       
   544 
       
   545     {
       
   546         QUrl url("error:/?error=14&errText=Unknown%20host%20asdfu.adgi.sdfgoi#http://asdfu.adgi.sdfgoi");
       
   547         QVERIFY(url.isValid());
       
   548         QCOMPARE(url.fragment(), QString::fromLatin1("http://asdfu.adgi.sdfgoi"));
       
   549     }
       
   550 
       
   551     {
       
   552         // suburls
       
   553         QUrl url("file:/home/dfaure/my%20tar%20file.tgz#gzip:/#tar:/");
       
   554         QVERIFY(url.isValid());
       
   555     }
       
   556 
       
   557     {
       
   558         QUrl url("file:/home/dfaure/cdrdao-1.1.5/dao/#CdrDriver.cc#");
       
   559         QVERIFY(url.isValid());
       
   560     }
       
   561 
       
   562     {
       
   563         QUrl url("file:/home/dfaure/my%20tar%20file.tgz#gzip:/#tar:/README");
       
   564         QVERIFY(url.isValid());
       
   565         QCOMPARE(url.toString(), QString::fromLatin1("file:///home/dfaure/my tar file.tgz#gzip:/#tar:/README"));
       
   566     }
       
   567 
       
   568     {
       
   569         QUrl notPretty;
       
   570         notPretty.setEncodedUrl("http://ferret.lmh.ox.ac.uk/%7Ekdecvs/");
       
   571         QVERIFY(notPretty.isValid());
       
   572         QCOMPARE(notPretty.toString(), QString::fromLatin1("http://ferret.lmh.ox.ac.uk/~kdecvs/"));
       
   573 
       
   574         QUrl notPretty2;
       
   575         notPretty2.setEncodedUrl("file:/home/test/directory%20with%20spaces");
       
   576         QVERIFY(notPretty2.isValid());
       
   577         QCOMPARE(notPretty2.toString(), QString::fromLatin1("file:///home/test/directory with spaces"));
       
   578 
       
   579         QUrl notPretty3("fish://foo/%23README%23");
       
   580         QVERIFY(notPretty3.isValid());
       
   581         QCOMPARE(notPretty3.toString(), QString::fromLatin1("fish://foo/%23README%23"));
       
   582 
       
   583         QUrl url15581;
       
   584         url15581.setUrl("http://alain.knaff.linux.lu/bug-reports/kde/spaces in url.html");
       
   585         QCOMPARE(url15581.toString(), QString::fromLatin1("http://alain.knaff.linux.lu/bug-reports/kde/spaces in url.html"));
       
   586         QCOMPARE(url15581.toEncoded().constData(), QByteArray("http://alain.knaff.linux.lu/bug-reports/kde/spaces%20in%20url.html").constData());
       
   587 
       
   588         QUrl url15582("http://alain.knaff.linux.lu/bug-reports/kde/percentage%in%url.html");
       
   589         QCOMPARE(url15582.toString(), QString::fromLatin1("http://alain.knaff.linux.lu/bug-reports/kde/percentage%in%url.html"));
       
   590         QCOMPARE(url15582.toEncoded(), QByteArray("http://alain.knaff.linux.lu/bug-reports/kde/percentage%25in%25url.html"));
       
   591     }
       
   592 
       
   593     {
       
   594         QUrl carsten;
       
   595         carsten.setPath("/home/gis/src/kde/kdelibs/kfile/.#kfiledetailview.cpp.1.18");
       
   596         QCOMPARE(carsten.path(), QString::fromLatin1("/home/gis/src/kde/kdelibs/kfile/.#kfiledetailview.cpp.1.18"));
       
   597 
       
   598         QUrl charles;
       
   599         charles.setPath("/home/charles/foo%20moo");
       
   600         QCOMPARE(charles.path(), QString::fromLatin1("/home/charles/foo%20moo"));
       
   601 
       
   602         QUrl charles2;
       
   603         charles2.setEncodedUrl("file:/home/charles/foo%20moo");
       
   604         QCOMPARE(charles2.path(), QString::fromLatin1("/home/charles/foo moo"));
       
   605     }
       
   606 
       
   607     {
       
   608         QUrl udir;
       
   609         QCOMPARE(udir.toEncoded(), QByteArray());
       
   610         QVERIFY(!udir.isValid());
       
   611 
       
   612         udir = QUrl::fromLocalFile("/home/dfaure/file.txt");
       
   613         QCOMPARE(udir.path(), QString::fromLatin1("/home/dfaure/file.txt"));
       
   614         QCOMPARE(udir.toEncoded(), QByteArray("file:///home/dfaure/file.txt"));
       
   615     }
       
   616 
       
   617     {
       
   618         QUrl url;
       
   619         url.setUrl("hello.com#?");
       
   620         QVERIFY(url.isValid());
       
   621         url.setUrl("hello.com");
       
   622         QVERIFY(!url.toString().contains(QLatin1Char('#')));
       
   623         QVERIFY(!url.toString().contains(QLatin1Char('?')));
       
   624     }
       
   625 
       
   626     {
       
   627         QUrl url;
       
   628         url.setUrl("http://1.2.3.4.example.com");
       
   629         QVERIFY(url.isValid());
       
   630         QCOMPARE(url.scheme(), QString("http"));
       
   631         QCOMPARE(url.host(), QString("1.2.3.4.example.com"));
       
   632     }
       
   633 
       
   634     {
       
   635         QUrl url;
       
   636         url.setUrl("http://1.2.3.4");
       
   637         QVERIFY(url.isValid());
       
   638         QCOMPARE(url.scheme(), QString("http"));
       
   639         QCOMPARE(url.host(), QString("1.2.3.4"));
       
   640     }
       
   641     {
       
   642         QUrl url;
       
   643         url.setUrl("http://1.2.3.4/");
       
   644         QVERIFY(url.isValid());
       
   645         QCOMPARE(url.scheme(), QString("http"));
       
   646         QCOMPARE(url.host(), QString("1.2.3.4"));
       
   647         QCOMPARE(url.path(), QString("/"));
       
   648     }
       
   649     {
       
   650         QUrl url;
       
   651         url.setUrl("http://1.2.3.4?foo");
       
   652         QVERIFY(url.isValid());
       
   653         QCOMPARE(url.scheme(), QString("http"));
       
   654         QCOMPARE(url.host(), QString("1.2.3.4"));
       
   655         QCOMPARE(url.encodedQuery(), QByteArray("foo"));
       
   656     }
       
   657     {
       
   658         QUrl url;
       
   659         url.setUrl("http://1.2.3.4#bar");
       
   660         QVERIFY(url.isValid());
       
   661         QCOMPARE(url.scheme(), QString("http"));
       
   662         QCOMPARE(url.host(), QString("1.2.3.4"));
       
   663         QCOMPARE(url.fragment(), QString("bar"));
       
   664     }
       
   665 
       
   666     {
       
   667         QUrl url;
       
   668         url.setEncodedUrl("data:text/javascript,d5%20%3D%20'five\\u0027s'%3B");
       
   669         QVERIFY(url.isValid());
       
   670         QCOMPARE(url.scheme(), QString("data"));
       
   671         QCOMPARE(url.host(), QString());
       
   672         QCOMPARE(url.path(), QString("text/javascript,d5 = 'five\\u0027s';"));
       
   673         QCOMPARE(url.encodedPath().constData(), "text/javascript,d5%20%3D%20'five%5Cu0027s'%3B");
       
   674     }
       
   675 
       
   676 /*
       
   677    The tests below are copied from kdelibs/kdecore/tests/kurltest.cpp (an old version of)
       
   678 
       
   679     Copyright (c) 1999-2005 Waldo Bastian <bastian@kde.org>
       
   680     Copyright (c) 2000-2005 David Faure <faure@kde.org>
       
   681 
       
   682     This library is free software; you can redistribute it and/or
       
   683     modify it under the terms of the GNU Library General Public
       
   684     License version 2 as published by the Free Software Foundation.
       
   685 
       
   686     This library is distributed in the hope that it will be useful,
       
   687     but WITHOUT ANY WARRANTY; without even the implied warranty of
       
   688     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       
   689     Library General Public License for more details.
       
   690 
       
   691     You should have received a copy of the GNU Library General Public License
       
   692     along with this library; see the file COPYING.LIB.  If not, write to
       
   693     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
       
   694     Boston, MA 02110-1301, USA.
       
   695  */
       
   696 /*
       
   697     ### File / directory specifics
       
   698 
       
   699     KURL u2( QCString("/home/dfaure/") );
       
   700     printf("\n* URL is %s\n",u2.url().ascii());
       
   701 // not ignoring trailing slash
       
   702     check("KURL::directory(false,false)", u2.directory(false,false), "/home/dfaure/");
       
   703     check("KURL::directory(true,false)", u2.directory(true,false), "/home/dfaure");
       
   704 // ignoring trailing slash
       
   705     check("KURL::directory(false,true)", u2.directory(false,true), "/home/");
       
   706     check("KURL::directory(true,true)", u2.directory(true,true), "/home");
       
   707     u2.cd("..");
       
   708     check("KURL::cd(\"..\")", u2.url(), "file:/home");
       
   709     u2.cd("thomas");
       
   710     check("KURL::cd(\"thomas\")", u2.url(), "file:/home/thomas");
       
   711     u2.cd("/opt/kde/bin/");
       
   712     check("KURL::cd(\"/opt/kde/bin/\")", u2.url(), "file:/opt/kde/bin/");
       
   713     u2 = "ftp://ftp.kde.org/";
       
   714     printf("\n* URL is %s\n",u2.url().ascii());
       
   715     u2.cd("pub");
       
   716     check("KURL::cd(\"pub\")", u2.url(), "ftp://ftp.kde.org/pub");
       
   717     u2 = u2.upURL();
       
   718     check("KURL::upURL()", u2.url(), "ftp://ftp.kde.org/");
       
   719     u2 = u1;
       
   720     printf("\n* URL is %s\n",u2.url().ascii());
       
   721 // setFileName
       
   722     u2.setFileName( "myfile.txt" );
       
   723     check("KURL::setFileName()", u2.url(), "file:/home/dfaure/myfile.txt");
       
   724     u2.setFileName( "myotherfile.txt" );
       
   725     check("KURL::setFileName()", u2.url(), "file:/home/dfaure/myotherfile.txt");
       
   726 // more tricky, renaming a directory (kpropsdlg.cc, line ~ 238)
       
   727     QString tmpurl = "file:/home/dfaure/myolddir/";
       
   728     if ( tmpurl.at(tmpurl.length() - 1) == '/')
       
   729 // It's a directory, so strip the trailing slash first
       
   730         tmpurl.truncate( tmpurl.length() - 1);
       
   731     KURL newUrl = tmpurl;
       
   732     newUrl.setFileName( "mynewdir" );
       
   733     check("KURL::setFileName() special", newUrl.url(), "file:/home/dfaure/mynewdir");
       
   734 // addPath tests
       
   735     newUrl.addPath( "subdir" );
       
   736     check("KURL::addPath(\"subdir\")", newUrl.url(), "file:/home/dfaure/mynewdir/subdir");
       
   737     newUrl.addPath( "/foo/" );
       
   738     check("KURL::addPath(\"/foo/\")", newUrl.url(), "file:/home/dfaure/mynewdir/subdir/foo/");
       
   739     u2 = "http://www.kde.org"; // no path
       
   740     u2.addPath( "subdir" );
       
   741     check("KURL::addPath(\"subdir\")", u2.url(), "http://www.kde.org/subdir");
       
   742     u2.addPath( "" );
       
   743     check("KURL::addPath(\"subdir\")", u2.url(), "http://www.kde.org/subdir"); // unchanged
       
   744 
       
   745 // even more tricky
       
   746     u2 = "print:/specials/Print%20To%20File%20(PDF%2FAcrobat)";
       
   747     printf("\n* URL is %s\n",u2.url().ascii());
       
   748     check("KURL::path()", u2.path(), "/specials/Print To File (PDF/Acrobat)");
       
   749     check("KURL::fileName()", u2.fileName(), "Print To File (PDF/Acrobat)");
       
   750     u2.setFileName( "" );
       
   751     check("KURL::setFileName()", u2.url(), "print:/specials/");
       
   752 
       
   753     u2 = "file:/specials/Print";
       
   754     printf("\n* URL is %s\n",u2.url().ascii());
       
   755     check("KURL::path()", u2.path(), "/specials/Print");
       
   756     check("KURL::fileName()", u2.fileName(), "Print");
       
   757     u2.setFileName( "" );
       
   758     check("KURL::setFileName()", u2.url(), "file:/specials/");
       
   759 
       
   760     const char * u3 = "ftp://host/dir1/dir2/myfile.txt";
       
   761     printf("\n* URL is %s\n",u3);
       
   762     check("KURL::hasSubURL()", KURL(u3).hasSubURL() ? "yes" : "no", "no");
       
   763     lst.clear();
       
   764     lst = KURL::split( KURL(u3) );
       
   765     check("KURL::split()", lst.count()==1 ? "1" : "error", "1");
       
   766     check("KURL::split()", lst.first().url(), "ftp://host/dir1/dir2/myfile.txt");
       
   767 // cdUp code
       
   768     KURL lastUrl = lst.last();
       
   769     QString dir = lastUrl.directory( true, true );
       
   770     check( "KURL::directory(true,true)", dir, "/dir1/dir2");
       
   771 */
       
   772 
       
   773     {
       
   774         // !!! FAILS
       
   775 //        QString ucmp1 = "ftp://ftp.de.kde.org/dir";
       
   776 //        QString ucmp2 = "ftp://ftp.de.kde.org/dir/";
       
   777 //        QVERIFY(QUrl(ucmp1) == QUrl(ucmp2));
       
   778     }
       
   779 
       
   780 
       
   781     /*
       
   782 /// Comparisons
       
   783     QString ucmp1 = "ftp://ftp.de.kde.org/dir";
       
   784     QString ucmp2 = "ftp://ftp.de.kde.org/dir/";
       
   785     check("urlcmp(only slash difference)", urlcmp(ucmp1,ucmp2)?"ko":"ok","ok");
       
   786     check("urlcmp(only slash difference, ignore_trailing)", urlcmp(ucmp1,ucmp2,true,false)?"ok":"ko","ok");
       
   787     QString ucmp3 = "ftp://ftp.de.kde.org/dir/#";
       
   788     check("urlcmp(only hash difference)", urlcmp(ucmp2,ucmp3)?"ko":"ok","ok");
       
   789     check("urlcmp(only hash difference, ignore_ref)", urlcmp(ucmp2,ucmp3,false,true)?"ok":"ko","ok");
       
   790     check("urlcmp(slash and hash difference, ignore_trailing, ignore_ref)", urlcmp(ucmp2,ucmp3,true,true)?"ok":"ko","ok");
       
   791     check("urlcmp(empty, empty)", urlcmp("","",false,true)?"ok":"ko","ok");
       
   792     check("urlcmp(empty, empty)", urlcmp("","")?"ok":"ko","ok");
       
   793     check("urlcmp(empty, not empty)", urlcmp("",ucmp1)?"ok":"ko","ko");
       
   794     check("urlcmp(empty, not empty)", urlcmp("",ucmp1,false,true)?"ok":"ko","ko");
       
   795     check("urlcmp(malformed, not empty)", urlcmp("file",ucmp1)?"ok":"ko","ko");
       
   796     check("urlcmp(malformed, not empty)", urlcmp("file",ucmp1,false,true)?"ok":"ko","ko");
       
   797 
       
   798     KURL ftpUrl ( "ftp://ftp.de.kde.org" );
       
   799     printf("\n* URL is %s\n",ftpUrl.url().latin1());
       
   800     check("KURL::path()", ftpUrl.path(), QString());
       
   801     ftpUrl = "ftp://ftp.de.kde.org/";
       
   802     check("KURL::isParentOf()", ftpUrl.isParentOf( "ftp://ftp.de.kde.org/host/subdir/") ? "yes" : "no", "yes");
       
   803     ftpUrl = "ftp://ftp/host/subdir/";
       
   804     check("KURL::isParentOf()", ftpUrl.isParentOf( "ftp://ftp/host/subdir/") ? "yes" : "no", "yes");
       
   805     check("KURL::isParentOf()", ftpUrl.isParentOf( "ftp://ftp/host/subdir") ? "yes" : "no", "yes");
       
   806     check("KURL::isParentOf()", ftpUrl.isParentOf( "ftp://ftp/host/subdi") ? "yes" : "no", "no");
       
   807     check("KURL::isParentOf()", ftpUrl.isParentOf( "ftp://ftp/host/subdir/blah/") ? "yes" : "no", "yes");
       
   808     check("KURL::isParentOf()", ftpUrl.isParentOf( "ftp://ftp/blah/subdir") ? "yes" : "no", "no");
       
   809     check("KURL::isParentOf()", ftpUrl.isParentOf( "file://ftp/host/subdir/") ? "yes" : "no", "no");
       
   810     check("KURL::isParentOf()", ftpUrl.isParentOf( "ftp://ftp/host/subdir/subsub") ? "yes" : "no", "yes");
       
   811 
       
   812 // WABA: The following tests are to test the handling of relative URLs as
       
   813 //       found on web-pages.
       
   814 
       
   815     KURL waba1( "http://www.website.com/directory/?hello#ref" );
       
   816     {
       
   817         KURL waba2( waba1, "relative.html");
       
   818         check("http: Relative URL, single file", waba2.url(), "http://www.website.com/directory/relative.html");
       
   819     }
       
   820     {
       
   821         KURL waba2( waba1, "../relative.html");
       
   822         check("http: Relative URL, single file, directory up", waba2.url(), "http://www.website.com/relative.html");
       
   823     }
       
   824     {
       
   825         KURL waba2( waba1, "down/relative.html");
       
   826         check("http: Relative URL, single file, directory down", waba2.url(), "http://www.website.com/directory/down/relative.html");
       
   827     }
       
   828     {
       
   829         KURL waba2( waba1, "/down/relative.html");
       
   830         check("http: Relative URL, full path", waba2.url(), "http://www.website.com/down/relative.html");
       
   831     }
       
   832     {
       
   833         KURL waba2( waba1, "//www.kde.org/relative.html");
       
   834         check("http: Relative URL, with host", waba2.url(), "http://www.kde.org/relative.html");
       
   835     }
       
   836     {
       
   837         KURL waba2( waba1, "relative.html?query=test&name=harry");
       
   838         check("http: Relative URL, with query", waba2.url(), "http://www.website.com/directory/relative.html?query=test&name=harry");
       
   839         waba2.removeQueryItem("query");
       
   840         check("http: Removing query item", waba2.url(), "http://www.website.com/directory/relative.html?name=harry");
       
   841         waba2.addQueryItem("age", "18");
       
   842         check("http: Adding query item", waba2.url(), "http://www.website.com/directory/relative.html?name=harry&age=18");
       
   843         waba2.addQueryItem("age", "21");
       
   844         check("http: Adding query item", waba2.url(), "http://www.website.com/directory/relative.html?name=harry&age=18&age=21");
       
   845         waba2.addQueryItem("fullname", "Harry Potter");
       
   846         check("http: Adding query item", waba2.url(), "http://www.website.com/directory/relative.html?name=harry&age=18&age=21&fullname=Harry%20Potter");
       
   847     }
       
   848     {
       
   849         KURL waba2( waba1, "?query=test&name=harry");
       
   850         check("http: Relative URL, with query and no filename", waba2.url(), "http://www.website.com/directory/?query=test&name=harry");
       
   851     }
       
   852     {
       
   853         KURL waba2( waba1, "relative.html#with_reference");
       
   854         check("http: Relative URL, with reference", waba2.url(), "http://www.website.com/directory/relative.html#with_reference");
       
   855     }
       
   856     {
       
   857         KURL waba2( waba1, "#");
       
   858         check("http: Relative URL, with empty reference", waba2.url(), "http://www.website.com/directory/?hello#");
       
   859     }
       
   860     {
       
   861         KURL waba2( waba1, "");
       
   862         check("http: Empty relative URL", waba2.url(), "http://www.website.com/directory/?hello#ref");
       
   863     }
       
   864     {
       
   865         KURL base( "http://faure@www.kde.org" ); // no path
       
   866         KURL waba2( base, "filename.html");
       
   867         check("http: Relative URL, orig URL had no path", waba2.url(), "http://faure@www.kde.org/filename.html");
       
   868     }
       
   869     {
       
   870         KURL base( "http://faure:pass@www.kde.org:81?query" );
       
   871         KURL rel1( base, "http://www.kde.org/bleh/"); // same host
       
   872         check("http: Relative URL, orig URL had username", rel1.url(), "http://faure:pass@www.kde.org/bleh/");
       
   873         KURL rel2( base, "http://www.yahoo.org"); // different host
       
   874         check("http: Relative URL, orig URL had username", rel2.url(), "http://www.yahoo.org");
       
   875     }
       
   876 
       
   877     waba1 = "http://www.website.com/directory/filename?bla#blub";
       
   878     {
       
   879         KURL waba2( waba1, "relative.html");
       
   880         check("http: Relative URL, single file", waba2.url(), "http://www.website.com/directory/relative.html");
       
   881     }
       
   882     {
       
   883         KURL waba2( waba1, "../relative.html");
       
   884         check("http: Relative URL, single file, directory up", waba2.url(), "http://www.website.com/relative.html");
       
   885     }
       
   886     {
       
   887         KURL waba2( waba1, "down/relative.html");
       
   888         check("http: Relative URL, single file, directory down", waba2.url(), "http://www.website.com/directory/down/relative.html");
       
   889     }
       
   890     {
       
   891         KURL waba2( waba1, "/down/relative.html");
       
   892         check("http: Relative URL, full path", waba2.url(), "http://www.website.com/down/relative.html");
       
   893     }
       
   894     {
       
   895         KURL waba2( waba1, "relative.html?query=test&name=harry");
       
   896         check("http: Relative URL, with query", waba2.url(), "http://www.website.com/directory/relative.html?query=test&name=harry");
       
   897     }
       
   898     {
       
   899         KURL waba2( waba1, "?query=test&name=harry");
       
   900         check("http: Relative URL, with query and no filename", waba2.url(), "http://www.website.com/directory/filename?query=test&name=harry");
       
   901     }
       
   902     {
       
   903         KURL waba2( waba1, "relative.html#with_reference");
       
   904         check("http: Relative URL, with reference", waba2.url(), "http://www.website.com/directory/relative.html#with_reference");
       
   905     }
       
   906     {
       
   907         KURL waba2( waba1, "http:/relative.html"); // "rfc 1606 loophole"
       
   908         check("http: Strange relative URL", waba2.url(), "http://www.website.com/relative.html");
       
   909     }
       
   910     waba1.setUser("waldo");
       
   911     check("http: Set user", waba1.url(), "http://waldo@www.website.com/directory/filename?bla#blub");
       
   912     waba1.setUser("waldo/bastian");
       
   913     check("http: Set user with slash in it", waba1.url(), "http://waldo%2Fbastian@www.website.com/directory/filename?bla#blub");
       
   914     waba1.setRef( QString() );
       
   915     waba1.setPass( "pass" );
       
   916     waba1.setDirectory( "/foo" );
       
   917     waba1.setProtocol( "https" );
       
   918     waba1.setHost( "web.com" );
       
   919     waba1.setPort( 881 );
       
   920     check("http: setRef/setPass/setDirectory/setHost/setPort", waba1.url(), "https://waldo%2Fbastian:pass@web.com:881/foo/?bla");
       
   921     waba1.setDirectory( "/foo/" );
       
   922     check("http: setDirectory #2", waba1.url(), "https://waldo%2Fbastian:pass@web.com:881/foo/?bla");
       
   923 
       
   924 // Empty queries should be preserved!
       
   925     waba1 = "http://www.kde.org/cgi/test.cgi?";
       
   926     check("http: URL with empty query string", waba1.url(),
       
   927           "http://www.kde.org/cgi/test.cgi?");
       
   928 
       
   929 // Empty references should be preserved
       
   930     waba1 = "http://www.kde.org/cgi/test.cgi#";
       
   931     check("http: URL with empty reference string", waba1.url(),
       
   932           "http://www.kde.org/cgi/test.cgi#");
       
   933     check("hasRef()", waba1.hasRef()?"true":"false","true");
       
   934     check("hasHTMLRef()", waba1.hasHTMLRef()?"true":"false","true");
       
   935     check("encodedHtmlRef()", waba1.encodedHtmlRef(),QString());
       
   936 
       
   937 // URLs who forgot to encode spaces in the query.
       
   938     waba1 = "http://www.kde.org/cgi/test.cgi?hello=My Value";
       
   939     check("http: URL with incorrect encoded query", waba1.url(),
       
   940           "http://www.kde.org/cgi/test.cgi?hello=My%20Value");
       
   941 
       
   942 // URL with ':' in query (':' should NOT be encoded!)
       
   943     waba1.setQuery("hello:My Value");
       
   944     check("http: URL with ':' in query", waba1.url(),
       
   945           "http://www.kde.org/cgi/test.cgi?hello:My%20Value");
       
   946     check("upURL() removes query", waba1.upURL().url(),
       
   947           "http://www.kde.org/cgi/test.cgi");
       
   948 
       
   949 // URLs who forgot to encode spaces in the query.
       
   950     waba1 = "http://www.kde.org/cgi/test.cgi?hello=My Value+20";
       
   951     check("http: URL with incorrect encoded query", waba1.url(),
       
   952           "http://www.kde.org/cgi/test.cgi?hello=My%20Value+20");
       
   953 
       
   954 // Urls without path (BR21387)
       
   955     waba1 = "http://meine.db24.de?link=home_c_login_login";
       
   956     check("http: URL with empty path string", waba1.url(),
       
   957           "http://meine.db24.de?link=home_c_login_login");
       
   958     check("http: URL with empty path string path", waba1.path(),
       
   959           "");
       
   960     check("http: URL with empty path string query", waba1.query(),
       
   961           "?link=home_c_login_login");
       
   962 
       
   963     waba1 = "http://a:389?b=c";
       
   964     check( "http: URL with port, query, and empty path; url", waba1.url(), "http://a:389?b=c" );
       
   965     check( "http: URL with port, query, and empty path; host", waba1.host(), "a" );
       
   966     check( "http: URL with port, query, and empty path; port", QString::number( waba1.port() ), "389" );
       
   967     check( "http: URL with port, query, and empty path; path", waba1.path(), "" );
       
   968     check( "http: URL with port, query, and empty path; query", waba1.query(), "?b=c" );
       
   969 
       
   970 // Urls without path (BR21387)
       
   971     waba1 = "http://meine.db24.de#link=home_c_login_login";
       
   972     check("http: URL with empty path string", waba1.url(),
       
   973           "http://meine.db24.de#link=home_c_login_login");
       
   974     check("http: URL with empty path string path", waba1.path(),
       
   975           "");
       
   976 
       
   977     waba1 = "http://a:389#b=c";
       
   978     check( "http: URL with port, ref, and empty path; url", waba1.url(), "http://a:389#b=c" );
       
   979     check( "http: URL with port, ref, and empty path; host", waba1.host(), "a" );
       
   980     check( "http: URL with port, ref, and empty path; port", QString::number( waba1.port() ), "389" );
       
   981     check( "http: URL with port, ref, and empty path; path", waba1.path(), "" );
       
   982     check( "http: URL with port, ref, and empty path; ref", waba1.ref(), "b=c" );
       
   983     check( "http: URL with port, ref, and empty path; query", waba1.query(), "" );
       
   984 
       
   985 // IPV6
       
   986     waba1 = "http://[::FFFF:129.144.52.38]:81/index.html";
       
   987     check("http: IPV6 host", waba1.host(),
       
   988           "::ffff:129.144.52.38");
       
   989     check("http: IPV6 port", QString("%1").arg(waba1.port()),
       
   990           "81");
       
   991 
       
   992 // IPV6
       
   993     waba1 = "http://waba:pass@[::FFFF:129.144.52.38]:81/index.html";
       
   994     check("http: IPV6 host", waba1.host(),
       
   995           "::ffff:129.144.52.38");
       
   996     check("http: IPV6 host", waba1.user(),
       
   997           "waba");
       
   998     check("http: IPV6 host", waba1.pass(),
       
   999           "pass");
       
  1000     check("http: IPV6 port", QString("%1").arg(waba1.port()),
       
  1001           "81");
       
  1002 
       
  1003 // IPV6
       
  1004     waba1 = "http://www.kde.org/cgi/test.cgi";
       
  1005     waba1.setHost("::ffff:129.144.52.38");
       
  1006     check("http: IPV6 host", waba1.url(),
       
  1007           "http://[::ffff:129.144.52.38]/cgi/test.cgi");
       
  1008     waba1 = "http://[::ffff:129.144.52.38]/cgi/test.cgi";
       
  1009     assert( waba1.isValid() );
       
  1010 
       
  1011 // IPV6 without path
       
  1012     waba1 = "http://[::ffff:129.144.52.38]?query";
       
  1013     assert( waba1.isValid() );
       
  1014     check("http: IPV6 without path", waba1.url(),
       
  1015           "http://[::ffff:129.144.52.38]?query");
       
  1016     check("http: IPV6 without path; query", waba1.query(),
       
  1017           "?query");
       
  1018     waba1 = "http://[::ffff:129.144.52.38]#ref";
       
  1019     assert( waba1.isValid() );
       
  1020     check("http: IPV6 without path", waba1.url(),
       
  1021           "http://[::ffff:129.144.52.38]#ref");
       
  1022     check("http: IPV6 without path; ref", waba1.ref(),
       
  1023           "ref");
       
  1024 // IPV6 without path but with a port
       
  1025     waba1 = "http://[::ffff:129.144.52.38]:81?query";
       
  1026     assert( waba1.isValid() );
       
  1027     check("http: IPV6 without path", waba1.url(),
       
  1028           "http://[::ffff:129.144.52.38]:81?query");
       
  1029     check("http: IPV6 without path; port", QString::number( waba1.port() ), "81" );
       
  1030     check("http: IPV6 without path; query", waba1.query(), "?query");
       
  1031     waba1 = "http://[::ffff:129.144.52.38]:81#ref";
       
  1032     assert( waba1.isValid() );
       
  1033     check("http: IPV6 without path", waba1.url(),
       
  1034           "http://[::ffff:129.144.52.38]:81#ref");
       
  1035     check("http: IPV6 without path; port", QString::number( waba1.port() ), "81" );
       
  1036     check("http: IPV6 without path; ref", waba1.ref(), "ref");
       
  1037 
       
  1038 // Streaming operators
       
  1039     KURL origURL( "http://www.website.com/directory/?#ref" );
       
  1040     waba1 = "http://[::ffff:129.144.52.38]:81?query";
       
  1041     QByteArray buffer;
       
  1042     {
       
  1043         QDataStream stream( buffer, QIODevice::WriteOnly );
       
  1044         stream << origURL
       
  1045                << KURL( "file:" ) // an invalid one
       
  1046                << waba1; // the IPv6 one
       
  1047     }
       
  1048     {
       
  1049         QDataStream stream( buffer, QIODevice::ReadOnly );
       
  1050         KURL restoredURL;
       
  1051         stream >> restoredURL;
       
  1052         check( "Streaming valid URL", origURL.url(), restoredURL.url() );
       
  1053         stream >> restoredURL;
       
  1054         check( "Streaming invalid URL", restoredURL.isValid()?"valid":"malformed", "malformed" );
       
  1055         check( "Streaming invalid URL", restoredURL.url(), "file:" );
       
  1056         stream >> restoredURL;
       
  1057         check( "Streaming ipv6 URL with query", restoredURL.url(), waba1.url() );
       
  1058     }
       
  1059 
       
  1060 // Broken stuff
       
  1061     waba1 = "file:a";
       
  1062     check("Broken stuff #1 path", waba1.path(), "a");
       
  1063     check("Broken stuff #1 fileName(false)", waba1.fileName(false), "a");
       
  1064     check("Broken stuff #1 fileName(true)", waba1.fileName(true), "a");
       
  1065     check("Broken stuff #1 directory(false, false)", waba1.directory(false, false), "");
       
  1066     check("Broken stuff #1 directory(true, false)", waba1.directory(true, false), "");
       
  1067     check("Broken stuff #1 directory(false, true)", waba1.directory(true, true), "");
       
  1068 
       
  1069     waba1 = "file:a/";
       
  1070     check("Broken stuff #2 path", waba1.path(), "a/");
       
  1071     check("Broken stuff #2 fileName(false)", waba1.fileName(false), "");
       
  1072     check("Broken stuff #2 fileName(true)", waba1.fileName(true), "a");
       
  1073     check("Broken stuff #2 directory(false, false)", waba1.directory(false, false), "a/");
       
  1074     check("Broken stuff #2 directory(true, false)", waba1.directory(true, false), "a");
       
  1075     check("Broken stuff #2 directory(false, true)", waba1.directory(true, true), "");
       
  1076 
       
  1077     waba1 = "file:";
       
  1078     check("Broken stuff #3 empty", waba1.isEmpty()?"EMPTY":"NOT", "NOT");
       
  1079     check("Broken stuff #3 valid", waba1.isValid()?"VALID":"MALFORMED", "MALFORMED");
       
  1080     check("Broken stuff #3 path", waba1.path(), "");
       
  1081     check("Broken stuff #3 fileName(false)", waba1.fileName(false), "");
       
  1082     check("Broken stuff #3 fileName(true)", waba1.fileName(true), "");
       
  1083     check("Broken stuff #3 directory(false, false)", waba1.directory(false, false), "");
       
  1084     check("Broken stuff #3 directory(true, false)", waba1.directory(true, false), "");
       
  1085     check("Broken stuff #3 directory(false, true)", waba1.directory(true, true), "");
       
  1086     KURL broken;
       
  1087     broken.setPath( QString() );
       
  1088     check("Broken stuff #4 empty", broken.isEmpty()?"EMPTY":"NOT", "NOT");
       
  1089 // It's valid: because isValid refers to parsing, not to what happens afterwards.
       
  1090     check("Broken stuff #4 valid", broken.isValid()?"VALID":"MALFORMED", "VALID");
       
  1091     check("Broken stuff #4 path", broken.path(), "");
       
  1092     broken = "file://"; // just because coolo wondered
       
  1093     check("Broken stuff #5 empty", broken.isEmpty()?"EMPTY":"NOT", "NOT");
       
  1094     check("Broken stuff #5 valid", broken.isValid()?"VALID":"MALFORMED", "MALFORMED");
       
  1095     check("Broken stuff #5 path", broken.path(), "");
       
  1096     broken = "file";
       
  1097     check("Broken stuff #6 valid", broken.isValid()?"VALID":"MALFORMED", "MALFORMED");
       
  1098 
       
  1099 #if 0 // BROKEN?
       
  1100 // UNC like names
       
  1101     KURL unc1("FILE://localhost/home/root");
       
  1102     check("UNC, with localhost", unc1.path(), "/home/root");
       
  1103     check("UNC, with localhost", unc1.url(), "file:/home/root");
       
  1104 #endif
       
  1105     KURL unc2("file:///home/root");
       
  1106     check("UNC, with empty host", unc2.path(), "/home/root");
       
  1107     check("UNC, with empty host", unc2.url(), "file:/home/root");
       
  1108 
       
  1109     {
       
  1110         KURL unc3("FILE://remotehost/home/root");
       
  1111 #if 0 // BROKEN?
       
  1112         check("UNC, with remote host", unc3.path(), "//remotehost/home/root");
       
  1113 #endif
       
  1114         check("UNC, with remote host", unc3.url(), "file://remotehost/home/root");
       
  1115         KURL url2("file://atlas/dfaure");
       
  1116         check("KURL::host()", url2.host(), "atlas");
       
  1117         check("KURL::path()", url2.path(), "/dfaure");
       
  1118         //check("KURL::path()", url3.path(), "//atlas/dfaure"); // says Waba
       
  1119         //KURL url3("file:////atlas/dfaure");
       
  1120         //check("KURL::path()", url3.path(), "//atlas/dfaure"); // says Waba
       
  1121     }
       
  1122 
       
  1123     KURL umail1 ( "mailto:faure@kde.org" );
       
  1124     check("mailto: URL, general form", umail1.protocol(), "mailto");
       
  1125     check("mailto: URL, general form", umail1.path(), "faure@kde.org");
       
  1126     check("mailto: URL, is relative", KURL::isRelativeURL("mailto:faure@kde.org") ? "true" : "false", "false");
       
  1127     KURL umail2 ( "mailto:Faure David <faure@kde.org>" );
       
  1128     check("mailto: URL, general form", umail2.protocol(), "mailto");
       
  1129     check("mailto: URL, general form", umail2.path(), "Faure David <faure@kde.org>");
       
  1130     check("isRelativeURL(\"mailto:faure@kde.org\")", KURL::isRelativeURL("mailto:faure@kde.org") ? "yes" : "no", "no");
       
  1131     KURL umail3 ( "mailto:" );
       
  1132     check("mailto: invalid URL", umail3.isValid()?"valid":"malformed", "malformed");
       
  1133 
       
  1134     check("man: URL, is relative", KURL::isRelativeURL("man:mmap") ? "true" : "false", "false");
       
  1135     check("javascript: URL, is relative", KURL::isRelativeURL("javascript:doSomething()") ? "true" : "false", "false");
       
  1136 // more isRelative
       
  1137     check("file: URL, is relative", KURL::isRelativeURL("file:/blah") ? "true" : "false", "false");
       
  1138     check("/path, is relative", KURL::isRelativeURL("/path") ? "true" : "false", "true"); // arguable
       
  1139     check("something, is relative", KURL::isRelativeURL("something") ? "true" : "false", "true");
       
  1140     KURL about("about:konqueror");
       
  1141     check("about:",about.path(),"konqueror");
       
  1142 
       
  1143     KURL ulong("https://swww.gad.de:443/servlet/CookieAccepted?MAIL=s@gad.de&VER=25901");
       
  1144     check("host",ulong.host(),"swww.gad.de");
       
  1145     check("path",ulong.path(),"/servlet/CookieAccepted");
       
  1146 
       
  1147     QTextCodec::setCodecForLocale( KGlobal::charsets()->codecForName( "iso-8859-1" ) );
       
  1148 // UTF8 tests
       
  1149     KURL uloc("/home/dfaure/konqtests/Matériel");
       
  1150     check("locale8bit",uloc.url().latin1(),"file:/home/dfaure/konqtests/Mat%E9riel"); // escaping the letter would be correct too
       
  1151     check("pretty",uloc.prettyURL(),"file:/home/dfaure/konqtests/Matériel"); // escaping the letter would be correct too
       
  1152 // 106 is MIB for UTF-8
       
  1153     check("UTF8",uloc.url(0, 106),"file:/home/dfaure/konqtests/Mat%C3%A9riel");
       
  1154     uloc = KURL("file:/home/dfaure/konqtests/Mat%C3%A9riel", 106);
       
  1155     check("UTF8 path", uloc.path(), "/home/dfaure/konqtests/Matériel");
       
  1156 
       
  1157 // fromPathOrURL tests
       
  1158     uloc = KURL::fromPathOrURL( "/home/dfaure/konqtests/Mat%E9riel" );
       
  1159     check("fromPathOrURL path", uloc.path(), "/home/dfaure/konqtests/Mat%E9riel");
       
  1160     uloc = KURL::fromPathOrURL( "http://www.kde.org" );
       
  1161     check("fromPathOrURL url", uloc.url(), "http://www.kde.org");
       
  1162     uloc = KURL::fromPathOrURL( "www.kde.org" );
       
  1163     check("fromPathOrURL url", uloc.isValid()?"valid":"malformed", "malformed");
       
  1164     uloc = KURL::fromPathOrURL( "index.html" );
       
  1165     check("fromPathOrURL url", uloc.isValid()?"valid":"malformed", "malformed");
       
  1166     uloc = KURL::fromPathOrURL( "" );
       
  1167     check("fromPathOrURL url", uloc.isValid()?"valid":"malformed", "malformed");
       
  1168 
       
  1169     QTextCodec::setCodecForLocale( KGlobal::charsets()->codecForName( "koi8-r" ) );
       
  1170     baseURL = "file:/home/coolo";
       
  1171     KURL russian = baseURL.directory(false, true) + QString::fromLocal8Bit( "ÆÇÎ7" );
       
  1172     check( "russian", russian.url(), "file:/home/%C6%C7%CE7" );
       
  1173 
       
  1174     KURL tobi1("http://some.host.net/path/to/file#fragmentPrecedes?theQuery");
       
  1175     check("wrong order of query and hypertext reference #1", tobi1.ref(), "fragmentPrecedes");
       
  1176     check("wrong order of query and hypertext reference #2", tobi1.query(), "?theQuery");
       
  1177 
       
  1178     tobi1 = "http://host.net/path/?#http://brokenäadsfküpoij31ü029muß2890zupycÜ*!*'O´+ß0i";
       
  1179     check("zero-length query",tobi1.query(),"?");
       
  1180 
       
  1181     tobi1 = "http://host.net/path/#no-query";
       
  1182     check("no query", tobi1.query(),"");
       
  1183 
       
  1184     tobi1 = "http://host.net/path?myfirstquery#andsomeReference";
       
  1185     tobi1.setEncodedPathAndQuery("another/path/?another&query");
       
  1186     check("setEncodedPathAndQuery test#1", tobi1.query(), "?another&query");
       
  1187     check("setEncodedPathAndQuery test#2", tobi1.path(), "another/path/");
       
  1188     tobi1.setEncodedPathAndQuery("another/path?another&query");
       
  1189     check("setEncodedPathAndQuery test#1", tobi1.query(), "?another&query");
       
  1190     check("setEncodedPathAndQuery test#2", tobi1.path(), "another/path");
       
  1191 
       
  1192     KURL theKow = "http://www.google.de/search?q=frerich&hlx=xx&hl=de&empty=&lr=lang+de&test=%2B%20%3A%25";
       
  1193     check("queryItem (first item)", theKow.queryItem("q"), "frerich");
       
  1194     check("queryItem (middle item)", theKow.queryItem("hl"), "de");
       
  1195     check("queryItem (last item)", theKow.queryItem("lr"), "lang de");
       
  1196     check("queryItem (invalid item)", theKow.queryItem("InterstellarCounselor"), QString());
       
  1197     check("queryItem (empty item)", theKow.queryItem("empty"), "");
       
  1198     check("queryItem (item with encoded chars)", theKow.queryItem("test"), "+ :%");
       
  1199 
       
  1200 // checks for queryItems(), which returns a QMap<QString,QString>:
       
  1201     KURL queryUrl( "mailto:Marc%20Mutz%20%3cmutz@kde.org%3E?"
       
  1202                    "Subject=subscribe+me&"
       
  1203                    "body=subscribe+mutz%40kde.org&"
       
  1204                    "Cc=majordomo%40lists.kde.org" );
       
  1205     check("queryItems (c.s. keys)",
       
  1206           QStringList(queryUrl.queryItems().keys()).join(", "),
       
  1207           "Cc, Subject, body" );
       
  1208     check("queryItems (c.i.s. keys)",
       
  1209           QStringList(queryUrl.queryItems(KURL::CaseInsensitiveKeys).keys()).join(", "),
       
  1210           "body, cc, subject" );
       
  1211     check("queryItems (values; c.s. keys)",
       
  1212           QStringList(queryUrl.queryItems().values()).join(", "),
       
  1213           "majordomo@lists.kde.org, subscribe me, subscribe mutz@kde.org" );
       
  1214     check("queryItems (values; c.i.s. keys)",
       
  1215           QStringList(queryUrl.queryItems(KURL::CaseInsensitiveKeys).values()).join(", "),
       
  1216           "subscribe mutz@kde.org, majordomo@lists.kde.org, subscribe me" );
       
  1217 
       
  1218     KURL umlaut1("http://www.clever-tanken.de/liste.asp?ort=N%FCrnberg&typ=Diesel");
       
  1219     check("umlaut1.url()", umlaut1.url(), "http://www.clever-tanken.de/liste.asp?ort=N%FCrnberg&typ=Diesel");
       
  1220 
       
  1221     KURL umlaut2("http://www.clever-tanken.de/liste.asp?ort=N%FCrnberg&typ=Diesel", 106);
       
  1222     check("umlaut2.url()", umlaut2.url(), "http://www.clever-tanken.de/liste.asp?ort=N%FCrnberg&typ=Diesel");
       
  1223 
       
  1224 // Needed for #49616
       
  1225     check( "encode_string('C++')", KURL::encode_string( "C++" ), "C%2B%2B" );
       
  1226     check( "decode_string('C%2B%2B')", KURL::decode_string( "C%2B%2B" ), "C++" );
       
  1227     check( "decode_string('C%00A')", KURL::decode_string( "C%00%A" ), "C" ); // we stop at %00
       
  1228 
       
  1229     check( "encode_string('%')", KURL::encode_string( "%" ), "%25" );
       
  1230     check( "encode_string(':')", KURL::encode_string( ":" ), "%3A" );
       
  1231 
       
  1232     KURL amantia( "http://%E1.foo" );
       
  1233     check("amantia.isValid()", amantia.isValid() ? "true" : "false", "true");
       
  1234 #ifdef HAVE_IDNA_H
       
  1235     check("amantia.url()", amantia.url(), "http://xn--80a.foo");   // Non-ascii is allowed in IDN domain names.
       
  1236 #else
       
  1237     check("amantia.url()", amantia.url(), "http://?.foo"); // why not
       
  1238 #endif
       
  1239 
       
  1240     KURL smb("smb://domain;username:password@server/share");
       
  1241     check("smb.isValid()", smb.isValid() ? "true" : "false", "true");
       
  1242     check("smb.user()", smb.user(), "domain;username");
       
  1243     smb = "smb:/";
       
  1244     check("smb:/", smb.isValid()?"VALID":"MALFORMED", "VALID");
       
  1245     smb = "smb://"; // kurl.cpp rev 1.106
       
  1246     check("smb://", smb.isValid()?"VALID":"MALFORMED", "MALFORMED");
       
  1247     smb = "smb://host";
       
  1248     check("smb://host", smb.isValid()?"VALID":"MALFORMED", "VALID");
       
  1249     smb = "smb:///";
       
  1250     check("smb:///", smb.isValid()?"VALID":"MALFORMED", "VALID");
       
  1251 
       
  1252     KURL weird;
       
  1253     weird = "http://strange<hostname>/";
       
  1254     check("weird.isValid()", weird.isValid() ? "true" : "false", "false");
       
  1255 
       
  1256     weird = "http://strange<username>@strange<hostname>/";
       
  1257     check("weird.isValid()", weird.isValid() ? "true" : "false", "false");
       
  1258 
       
  1259     weird = "http://strange<username>@ok_hostname/";
       
  1260     check("weird.isValid()", weird.isValid() ? "true" : "false", "true");
       
  1261     check("weird.host()", weird.host(), "ok_hostname");
       
  1262 
       
  1263     weird = "http://strange;hostname/";
       
  1264     check("weird.isValid()", weird.isValid() ? "true" : "false", "false");
       
  1265 
       
  1266     weird = "http://strange;username@strange;hostname/";
       
  1267     check("weird.isValid()", weird.isValid() ? "true" : "false", "false");
       
  1268 
       
  1269     weird = "http://strange;username@ok_hostname/";
       
  1270     check("weird.isValid()", weird.isValid() ? "true" : "false", "true");
       
  1271     check("weird.host()", weird.host(), "ok_hostname");
       
  1272 
       
  1273     weird = "http://strange;username:password@strange;hostname/";
       
  1274     check("weird.isValid()", weird.isValid() ? "true" : "false", "false");
       
  1275 
       
  1276     weird = "http://strange;username:password@ok_hostname/";
       
  1277     check("weird.isValid()", weird.isValid() ? "true" : "false", "true");
       
  1278     check("weird.host()", weird.host(), "ok_hostname");
       
  1279 
       
  1280     weird = "http://[strange;hostname]/";
       
  1281     check("weird.isValid()", weird.isValid() ? "true" : "false", "false");
       
  1282 
       
  1283     weird = "http://[::fff:1:23]/";
       
  1284     check("weird.isValid()", weird.isValid() ? "true" : "false", "true");
       
  1285     check("weird.host()", weird.host(), "::fff:1:23");
       
  1286 
       
  1287     KURL com1("http://server.com/dir/", ".");
       
  1288     check("com1.url()", com1.url(), "http://server.com/dir/");
       
  1289 
       
  1290     KURL com2("http://server.com/dir/blubb/", "blah/");
       
  1291     check("com2.url()", com2.url(), "http://server.com/dir/blubb/blah/");
       
  1292 
       
  1293     KURL utf8_1("audiocd:/By%20Name/15%20Geantra%C3%AE.wav", 106);
       
  1294     check("utf8_1.fileName()", utf8_1.fileName(), QString::fromLatin1("15 Geantraî.wav"));
       
  1295 
       
  1296     KURL utf8_2("audiocd:/By%20Name/15%2fGeantra%C3%AE.wav", 106);
       
  1297     check("utf8_2.fileName()", utf8_2.fileName(), QString::fromLatin1("15/Geantraî.wav"));
       
  1298 
       
  1299     KURL url_newline_1("http://www.foo.bar/foo/bar\ngnork");
       
  1300     check("url_newline_1.url()", url_newline_1.url(), QString::fromLatin1("http://www.foo.bar/foo/bar%0Agnork"));
       
  1301 
       
  1302     KURL url_newline_2("http://www.foo.bar/foo?bar\ngnork");
       
  1303     check("url_newline_2.url()", url_newline_2.url(), QString::fromLatin1("http://www.foo.bar/foo?bar%0Agnork"));
       
  1304 
       
  1305     KURL local_file_1("file://localhost/my/file");
       
  1306     check("local_file_1.isLocalFile()", local_file_1.isLocalFile() ? "true" : "false", "true");
       
  1307 
       
  1308     KURL local_file_2("file://www.kde.org/my/file");
       
  1309     check("local_file_2.isLocalFile()", local_file_2.isLocalFile() ? "true" : "false", "false");
       
  1310 
       
  1311     KURL local_file_3;
       
  1312     local_file_3.setHost(getenv("HOSTNAME"));
       
  1313     local_file_3.setPath("/my/file");
       
  1314     printf("\nURL=%s\n", local_file_3.url().latin1());
       
  1315     check("local_file_3.isLocalFile()", local_file_3.isLocalFile() ? "true" : "false", "true");
       
  1316 
       
  1317     KURL local_file_4("file:///my/file");
       
  1318     check("local_file_4.isLocalFile()", local_file_4.isLocalFile() ? "true" : "false", "true");
       
  1319 
       
  1320     KURL local_file_5;
       
  1321     local_file_5.setPath("/foo?bar");
       
  1322     check("local_file_5.url()", local_file_5.url(), "file:/foo%3Fbar");
       
  1323 
       
  1324     QString basePath = "/home/bastian";
       
  1325 
       
  1326     check("relativePath(\"/home/bastian\", \"/home/bastian\")", KURL::relativePath(basePath, "/home/bastian"), "./");
       
  1327     bool b;
       
  1328     check("relativePath(\"/home/bastian\", \"/home/bastian/src/plugins\")", KURL::relativePath(basePath, "/home/bastian/src/plugins", &b), "./src/plugins");
       
  1329     check("Is a subdirectory?", b ? "true" : "false", "true");
       
  1330     check("relativePath(\"/home/bastian\", \"./src/plugins\")", KURL::relativePath(basePath, "./src/plugins"), "./src/plugins");
       
  1331     check("relativePath(\"/home/bastian\", \"/home/waba/src/plugins\")", KURL::relativePath(basePath, "/home/waba/src/plugins", &b), "../waba/src/plugins");
       
  1332     check("Is a subdirectory?", b ? "true" : "false", "false");
       
  1333     check("relativePath(\"/home/bastian\", \"/\")", KURL::relativePath(basePath, "/"), "../../");
       
  1334 
       
  1335     check("relativePath(\"/\", \"/\")", KURL::relativePath("/", "/"), "./");
       
  1336     check("relativePath(\"/\", \"/home/bastian\")", KURL::relativePath("/", "/home/bastian"), "./home/bastian");
       
  1337     check("relativePath(\"\", \"/home/bastian\")", KURL::relativePath("", "/home/bastian"), "/home/bastian");
       
  1338 
       
  1339     baseURL = "http://www.kde.org/index.html";
       
  1340     check("relativeURL(\"http://www.kde.org/index.html\", \"http://www.kde.org/index.html#help\")", KURL::relativeURL(baseURL, "http://www.kde.org/index.html#help"), "#help");
       
  1341     check("relativeURL(\"http://www.kde.org/index.html\", \"http://www.kde.org/index.html?help=true\")", KURL::relativeURL(baseURL, "http://www.kde.org/index.html?help=true"), "index.html?help=true");
       
  1342     check("relativeURL(\"http://www.kde.org/index.html\", \"http://www.kde.org/contact.html\")", KURL::relativeURL(baseURL, "http://www.kde.org/contact.html"), "contact.html");
       
  1343     check("relativeURL(\"http://www.kde.org/index.html\", \"ftp://ftp.kde.org/pub/kde\")", KURL::relativeURL(baseURL, "ftp://ftp.kde.org/pub/kde"), "ftp://ftp.kde.org/pub/kde");
       
  1344     check("relativeURL(\"http://www.kde.org/index.html\", \"http://www.kde.org/index.html\")", KURL::relativeURL(baseURL, "http://www.kde.org/index.html"), "./");
       
  1345 
       
  1346     baseURL = "http://www.kde.org/info/index.html";
       
  1347     check("relativeURL(\"http://www.kde.org/info/index.html\", \"http://www.kde.org/bugs/contact.html\")", KURL::relativeURL(baseURL, "http://www.kde.org/bugs/contact.html"), "../bugs/contact.html");
       
  1348 
       
  1349     baseURL = "ptal://mlc:usb:PC_970";
       
  1350     check("isValid()?", baseURL.isValid() ? "true" : "false", "false");
       
  1351     check("url()", baseURL.url(), "ptal://mlc:usb:PC_970");
       
  1352 
       
  1353     baseURL = "http://mlc:80/";
       
  1354     check("isValid()?", baseURL.isValid() ? "true" : "false", "true");
       
  1355     check("port()?", QString::number(baseURL.port()), "80");
       
  1356     check("path()?", baseURL.path(), "/");
       
  1357 
       
  1358     baseURL = "ptal://mlc:usb@PC_970"; // User=mlc, password=usb, host=PC_970
       
  1359     check("isValid()?", baseURL.isValid() ? "true" : "false", "true");
       
  1360     check("host()?", baseURL.host(), "pc_970");
       
  1361     check("user()?", baseURL.user(), "mlc");
       
  1362     check("pass()?", baseURL.pass(), "usb");
       
  1363 
       
  1364     weird = "ftp://user%40host.com@ftp.host.com/var/www/";
       
  1365     check("user()?", weird.user(), "user@host.com" );
       
  1366     check("host()?", weird.host(), "ftp.host.com" );
       
  1367     KURL up = weird.upURL();
       
  1368     check("KURL::upURL()", up.url(), "ftp://user%40host.com@ftp.host.com/var/");
       
  1369     up = up.upURL();
       
  1370     check("KURL::upURL()", up.url(), "ftp://user%40host.com@ftp.host.com/");
       
  1371     up = up.upURL();
       
  1372     check("KURL::upURL()", up.url(), "ftp://user%40host.com@ftp.host.com/"); // unchanged
       
  1373 
       
  1374     KURL ldap = "ldap://host.com:6666/o=University%20of%20Michigan,c=US??sub?(cn=Babs%20Jensen)";
       
  1375     check("host()?", ldap.host(), "host.com");
       
  1376     check("port()?", QString("%1").arg(ldap.port()), "6666");
       
  1377     check("path()?", ldap.path(), "/o=University of Michigan,c=US");
       
  1378     check("query()?", ldap.query(), "??sub?(cn=Babs%20Jensen)");
       
  1379     check("url()?", ldap.url(), "ldap://host.com:6666/o=University%20of%20Michigan,c=US??sub?(cn=Babs%20Jensen)");
       
  1380     ldap.setQuery("??sub?(cn=Karl%20Marx)");
       
  1381     check("query()?", ldap.query(), "??sub?(cn=Karl%20Marx)");
       
  1382     check("url()?", ldap.url(), "ldap://host.com:6666/o=University%20of%20Michigan,c=US??sub?(cn=Karl%20Marx)");
       
  1383 
       
  1384     KURL leo = "data:text/html,http://www.invalid/";
       
  1385     check("data URL: isValid", leo.isValid()?"valid":"malformed", "valid" );
       
  1386     check("data URL: protocol", leo.protocol(), "data" );
       
  1387     check("data URL: url", leo.url(), "data:text/html,http://www.invalid/" );
       
  1388     check("data URL: path", leo.path(), "text/html,http://www.invalid/" );
       
  1389 
       
  1390 // URI Mode tests
       
  1391     url1 = "http://www.foobar.com/";
       
  1392     check("KURL(\"http://www.foobar.com/\").uriMode()", QString::number(url1.uriMode()), QString::number(KURL::URL));
       
  1393     url1 = "mailto:user@host.com";
       
  1394     check("KURL(\"mailto:user@host.com\").uriMode()", QString::number(url1.uriMode()), QString::number(KURL::Mailto));
       
  1395     check("KURL(\"mailto:user@host.com\").url()", url1.url(), "mailto:user@host.com");
       
  1396     check("KURL(\"mailto:user@host.com\").url(0, 106)", url1.url(0, 106), "mailto:user@host.com");
       
  1397     url1 = "data:text/plain,foobar?gazonk=flarp";
       
  1398     check("KURL(\"data:text/plain,foobar?gazonk=flarp\").uriMode()", QString::number(url1.uriMode()), QString::number(KURL::RawURI));
       
  1399     check("KURL(\"data:text/plain,foobar?gazonk=flarp\").path()", url1.path(), "text/plain,foobar?gazonk=flarp");
       
  1400     url1 = "mailto:User@Host.COM?subject=Hello";
       
  1401     check("KURL(\"mailto:User@Host.COM?subject=Hello\").path()", url1.path(), "User@host.com");
       
  1402 
       
  1403     printf("\nTest OK !\n");
       
  1404     */
       
  1405 
       
  1406 
       
  1407         }
       
  1408 
       
  1409 void tst_QUrl::i18n_data()
       
  1410 {
       
  1411     QTest::addColumn<QString>("input");
       
  1412     QTest::addColumn<QByteArray>("punyOutput"); 
       
  1413 
       
  1414     QTest::newRow("øl") << QString::fromLatin1("http://ole:passord@www.øl.no/index.html?ole=æsemann&ilder gud=hei#top")
       
  1415                      <<          QByteArray("http://ole:passord@www.xn--l-4ga.no/index.html?ole=%C3%A6semann&ilder%20gud=hei#top");
       
  1416     QTest::newRow("räksmörgås") << QString::fromLatin1("http://www.räksmörgås.no/")
       
  1417                              << QByteArray("http://www.xn--rksmrgs-5wao1o.no/");
       
  1418     QTest::newRow("bühler") << QString::fromLatin1("http://www.bühler.no/")
       
  1419                          << QByteArray("http://www.xn--bhler-kva.no/");
       
  1420     QTest::newRow("non-latin1")
       
  1421         << QString::fromUtf8("http://www.\316\261\316\270\316\256\316\275\316\261.info")
       
  1422         << QByteArray("http://www.xn--jxafb0a0a.info");
       
  1423 }
       
  1424 
       
  1425 void tst_QUrl::i18n()
       
  1426 {
       
  1427     QFETCH(QString, input);
       
  1428     QFETCH(QByteArray, punyOutput);
       
  1429 
       
  1430     QUrl url(input);
       
  1431     QVERIFY(url.isValid());
       
  1432 
       
  1433     QCOMPARE(url.toEncoded().constData(), punyOutput.constData());
       
  1434     QCOMPARE(QUrl::fromEncoded(punyOutput), url);
       
  1435     QCOMPARE(QUrl::fromEncoded(punyOutput).toString(), input);
       
  1436 }
       
  1437 
       
  1438 
       
  1439 void tst_QUrl::resolving_data()
       
  1440 {
       
  1441     QTest::addColumn<QString>("baseUrl");
       
  1442     QTest::addColumn<QString>("relativeUrl");
       
  1443     QTest::addColumn<QString>("relsolvedUrl");
       
  1444 
       
  1445     // 5.4.1 Normal Examples (http://www.ietf.org/rfc/rfc3986.txt)
       
  1446     QTest::newRow("g:h")       << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("g:h")      << QString::fromLatin1("g:h");
       
  1447     QTest::newRow("g")         << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("g")        << QString::fromLatin1("http://a/b/c/g");
       
  1448     QTest::newRow("./g")       << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("./g")      << QString::fromLatin1("http://a/b/c/g");
       
  1449     QTest::newRow("g/")        << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("g/")       << QString::fromLatin1("http://a/b/c/g/");
       
  1450     QTest::newRow("/g")        << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("/g")       << QString::fromLatin1("http://a/g");
       
  1451     QTest::newRow("//g")       << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("//g")      << QString::fromLatin1("http://g");
       
  1452     QTest::newRow("?y")        << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("?y")       << QString::fromLatin1("http://a/b/c/d;p?y");
       
  1453     QTest::newRow("g?y")       << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("g?y")      << QString::fromLatin1("http://a/b/c/g?y");
       
  1454     QTest::newRow("#s")        << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("#s")       << QString::fromLatin1("http://a/b/c/d;p?q#s");
       
  1455     QTest::newRow("g#s")       << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("g#s")      << QString::fromLatin1("http://a/b/c/g#s");
       
  1456     QTest::newRow("g?y#s")     << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("g?y#s")    << QString::fromLatin1("http://a/b/c/g?y#s");
       
  1457     QTest::newRow(";x")        << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1(";x")       << QString::fromLatin1("http://a/b/c/;x");
       
  1458     QTest::newRow("g;x")       << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("g;x")      << QString::fromLatin1("http://a/b/c/g;x");
       
  1459     QTest::newRow("g;x?y#s")   << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("g;x?y#s")  << QString::fromLatin1("http://a/b/c/g;x?y#s");
       
  1460     QTest::newRow("[empty]")   << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("")         << QString::fromLatin1("http://a/b/c/d;p?q");
       
  1461     QTest::newRow(".")         << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1(".")        << QString::fromLatin1("http://a/b/c/");
       
  1462     QTest::newRow("./")        << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("./")       << QString::fromLatin1("http://a/b/c/");
       
  1463     QTest::newRow("..")        << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("..")       << QString::fromLatin1("http://a/b/");
       
  1464     QTest::newRow("../")       << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("../")      << QString::fromLatin1("http://a/b/");
       
  1465     QTest::newRow("../g")      << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("../g")     << QString::fromLatin1("http://a/b/g");
       
  1466     QTest::newRow("../..")     << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("../..")    << QString::fromLatin1("http://a/");
       
  1467     QTest::newRow("../../")    << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("../../")   << QString::fromLatin1("http://a/");
       
  1468     QTest::newRow("../../g")   << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("../../g")  << QString::fromLatin1("http://a/g");
       
  1469 
       
  1470     // 5.4.2  Abnormal Examples (http://www.ietf.org/rfc/rfc3986.txt)
       
  1471 
       
  1472     // Parsers must be careful in handling cases where there are more
       
  1473     // relative path ".." segments than there are hierarchical levels in the
       
  1474     // base URI's path.  Note that the ".." syntax cannot be used to change
       
  1475     // the authority component of a URI.
       
  1476     QTest::newRow("../../../g")    << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("../../../g")     << QString::fromLatin1("http://a/g");
       
  1477     QTest::newRow("../../../../g") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("../../../../g")  << QString::fromLatin1("http://a/g");
       
  1478 
       
  1479     // Similarly, parsers must remove the dot-segments "." and ".." when
       
  1480     // they are complete components of a path, but not when they are only
       
  1481     // part of a segment.
       
  1482     QTest::newRow("/./g")  << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("/./g")  << QString::fromLatin1("http://a/g");
       
  1483     QTest::newRow("/../g") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("/../g") << QString::fromLatin1("http://a/g");
       
  1484     QTest::newRow("g.")    << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("g.")    << QString::fromLatin1("http://a/b/c/g.");
       
  1485     QTest::newRow(".g")    << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1(".g")    << QString::fromLatin1("http://a/b/c/.g");
       
  1486     QTest::newRow("g..")   << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("g..")   << QString::fromLatin1("http://a/b/c/g..");
       
  1487     QTest::newRow("..g")   << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("..g")   << QString::fromLatin1("http://a/b/c/..g");
       
  1488 
       
  1489     // Less likely are cases where the relative URI reference uses
       
  1490     // unnecessary or nonsensical forms of the "." and ".." complete path
       
  1491     // segments.
       
  1492     QTest::newRow("./../g")     << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("./../g")     << QString::fromLatin1("http://a/b/g");
       
  1493     QTest::newRow("./g/.")      << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("./g/.")      << QString::fromLatin1("http://a/b/c/g/");
       
  1494     QTest::newRow("g/./h")      << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("g/./h")      << QString::fromLatin1("http://a/b/c/g/h");
       
  1495     QTest::newRow("g/../h")     << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("g/../h")     << QString::fromLatin1("http://a/b/c/h");
       
  1496     QTest::newRow("g;x=1/./y")  << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("g;x=1/./y")  << QString::fromLatin1("http://a/b/c/g;x=1/y");
       
  1497     QTest::newRow("g;x=1/../y") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("g;x=1/../y") << QString::fromLatin1("http://a/b/c/y");
       
  1498 
       
  1499     // Some applications fail to separate the reference's query and/or
       
  1500     // fragment components from a relative path before merging it with the
       
  1501     // base path and removing dot-segments.  This error is rarely noticed,
       
  1502     // since typical usage of a fragment never includes the hierarchy ("/")
       
  1503     // character, and the query component is not normally used within
       
  1504     // relative references.
       
  1505     QTest::newRow("g?y/./x")  << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("g?y/./x")  << QString::fromLatin1("http://a/b/c/g?y/./x");
       
  1506     QTest::newRow("g?y/../x") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("g?y/../x") << QString::fromLatin1("http://a/b/c/g?y/../x");
       
  1507     QTest::newRow("g#s/./x")  << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("g#s/./x")  << QString::fromLatin1("http://a/b/c/g#s/./x");
       
  1508     QTest::newRow("g#s/../x") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("g#s/../x") << QString::fromLatin1("http://a/b/c/g#s/../x");
       
  1509 
       
  1510     // Some parsers allow the scheme name to be present in a relative URI
       
  1511     // reference if it is the same as the base URI scheme.  This is
       
  1512     // considered to be a loophole in prior specifications of partial URI
       
  1513     // [RFC1630]. Its use should be avoided, but is allowed for backward
       
  1514     // compatibility.
       
  1515     // For strict parsers :
       
  1516 //    QTest::newRow("http:g [for strict parsers]")         << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("http:g") << QString::fromLatin1("http:g");
       
  1517     // For backward compatibility :
       
  1518     QTest::newRow("http:g [for backward compatibility]") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("http:g") << QString::fromLatin1("http://a/b/c/g");
       
  1519 
       
  1520     // Resolve relative with relative
       
  1521     QTest::newRow("../a (1)")  << QString::fromLatin1("b") << QString::fromLatin1("../a")  << QString::fromLatin1("a");
       
  1522     QTest::newRow("../a (2)")  << QString::fromLatin1("b/a") << QString::fromLatin1("../a")  << QString::fromLatin1("a");
       
  1523     QTest::newRow("../a (3)")  << QString::fromLatin1("b/c/a") << QString::fromLatin1("../a")  << QString::fromLatin1("b/a");
       
  1524     QTest::newRow("../a (4)")  << QString::fromLatin1("b") << QString::fromLatin1("/a")  << QString::fromLatin1("/a");
       
  1525 
       
  1526     QTest::newRow("../a (5)")  << QString::fromLatin1("/b") << QString::fromLatin1("../a")  << QString::fromLatin1("/a");
       
  1527     QTest::newRow("../a (6)")  << QString::fromLatin1("/b/a") << QString::fromLatin1("../a")  << QString::fromLatin1("/a");
       
  1528     QTest::newRow("../a (7)")  << QString::fromLatin1("/b/c/a") << QString::fromLatin1("../a")  << QString::fromLatin1("/b/a");
       
  1529     QTest::newRow("../a (8)")  << QString::fromLatin1("/b") << QString::fromLatin1("/a")  << QString::fromLatin1("/a");
       
  1530 }
       
  1531 
       
  1532 void tst_QUrl::resolving()
       
  1533 {
       
  1534     QFETCH(QString, baseUrl);
       
  1535     QFETCH(QString, relativeUrl);
       
  1536     QFETCH(QString, relsolvedUrl);
       
  1537 
       
  1538     QUrl url(baseUrl);
       
  1539     QCOMPARE(url.resolved(relativeUrl).toString(), relsolvedUrl);
       
  1540 }
       
  1541 
       
  1542 
       
  1543 void tst_QUrl::toString_data()
       
  1544 {
       
  1545     QTest::addColumn<QString>("urlString");
       
  1546     QTest::addColumn<uint>("options");
       
  1547     QTest::addColumn<QString>("string");
       
  1548 
       
  1549     QTest::newRow("data0")	<< QString::fromLatin1("http://ole:password@www.troll.no:9090/index.html?ole=semann&gud=hei#top")
       
  1550 			<< uint(QUrl::RemoveScheme)
       
  1551 			<< QString::fromLatin1("//ole:password@www.troll.no:9090/index.html?ole=semann&gud=hei#top");
       
  1552 
       
  1553     QTest::newRow("data2")	<< QString::fromLatin1("http://ole:password@www.troll.no:9090/index.html?ole=semann&gud=hei#top")
       
  1554 			<< uint(QUrl::RemovePassword)
       
  1555 			<< QString::fromLatin1("http://ole@www.troll.no:9090/index.html?ole=semann&gud=hei#top");
       
  1556 
       
  1557     QTest::newRow("data3")	<< QString::fromLatin1("http://ole:password@www.troll.no:9090/index.html?ole=semann&gud=hei#top")
       
  1558 			<< uint(QUrl::RemoveUserInfo)
       
  1559 			<< QString::fromLatin1("http://www.troll.no:9090/index.html?ole=semann&gud=hei#top");
       
  1560 
       
  1561     QTest::newRow("data4")	<< QString::fromLatin1("http://ole:password@www.troll.no:9090/index.html?ole=semann&gud=hei#top")
       
  1562 			<< uint(QUrl::RemovePort)
       
  1563 			<< QString::fromLatin1("http://ole:password@www.troll.no/index.html?ole=semann&gud=hei#top");
       
  1564 
       
  1565     QTest::newRow("data5")	<< QString::fromLatin1("http://ole:password@www.troll.no:9090/index.html?ole=semann&gud=hei#top")
       
  1566 			<< uint(QUrl::RemoveAuthority)
       
  1567 			<< QString::fromLatin1("http:/index.html?ole=semann&gud=hei#top");
       
  1568 
       
  1569     QTest::newRow("data6")	<< QString::fromLatin1("http://ole:password@www.troll.no:9090/index.html?ole=semann&gud=hei#top")
       
  1570 			<< uint(QUrl::RemovePath)
       
  1571 			<< QString::fromLatin1("http://ole:password@www.troll.no:9090?ole=semann&gud=hei#top");
       
  1572 
       
  1573     QTest::newRow("data7")	<< QString::fromLatin1("http://ole:password@www.troll.no:9090/index.html?ole=semann&gud=hei#top")
       
  1574 			<< uint(QUrl::RemoveQuery)
       
  1575 			<< QString::fromLatin1("http://ole:password@www.troll.no:9090/index.html#top");
       
  1576 
       
  1577     QTest::newRow("data8")	<< QString::fromLatin1("http://ole:password@www.troll.no:9090/index.html?ole=semann&gud=hei#top")
       
  1578 			<< uint(QUrl::RemoveFragment)
       
  1579 			<< QString::fromLatin1("http://ole:password@www.troll.no:9090/index.html?ole=semann&gud=hei");
       
  1580 
       
  1581     QTest::newRow("data9")	<< QString::fromLatin1("http://ole:password@www.troll.no:9090/index.html?ole=semann&gud=hei#top")
       
  1582 			<< uint(QUrl::RemoveScheme | QUrl::RemovePassword)
       
  1583 			<< QString::fromLatin1("//ole@www.troll.no:9090/index.html?ole=semann&gud=hei#top");
       
  1584 
       
  1585     QTest::newRow("data10") << QString::fromLatin1("http://ole:password@www.troll.no:9090/index.html?ole=semann&gud=hei#top")
       
  1586 			 << uint(QUrl::RemoveScheme | QUrl::RemoveUserInfo)
       
  1587 			 << QString::fromLatin1("//www.troll.no:9090/index.html?ole=semann&gud=hei#top");
       
  1588 
       
  1589     QTest::newRow("data11") << QString::fromLatin1("http://ole:password@www.troll.no:9090/index.html?ole=semann&gud=hei#top")
       
  1590 			 << uint(QUrl::RemoveScheme | QUrl::RemovePort)
       
  1591 			 << QString::fromLatin1("//ole:password@www.troll.no/index.html?ole=semann&gud=hei#top");
       
  1592 
       
  1593     QTest::newRow("data12") << QString::fromLatin1("http://ole:password@www.troll.no:9090/index.html?ole=semann&gud=hei#top")
       
  1594 			 << uint(QUrl::RemoveScheme | QUrl::RemoveAuthority)
       
  1595 			 << QString::fromLatin1("/index.html?ole=semann&gud=hei#top");
       
  1596 
       
  1597     QTest::newRow("data13") << QString::fromLatin1("http://ole:password@www.troll.no:9090/index.html?ole=semann&gud=hei#top")
       
  1598 			 << uint(QUrl::RemoveScheme | QUrl::RemovePath)
       
  1599 			 << QString::fromLatin1("//ole:password@www.troll.no:9090?ole=semann&gud=hei#top");
       
  1600 
       
  1601     QTest::newRow("data14") << QString::fromLatin1("http://ole:password@www.troll.no:9090/index.html?ole=semann&gud=hei#top")
       
  1602 			 << uint(QUrl::RemoveScheme | QUrl::RemoveAuthority | QUrl::RemoveFragment)
       
  1603 			 << QString::fromLatin1("/index.html?ole=semann&gud=hei");
       
  1604 
       
  1605     QTest::newRow("data15") << QString::fromLatin1("http://ole:password@www.troll.no:9090/index.html?ole=semann&gud=hei#top")
       
  1606 			 << uint(QUrl::RemoveAuthority | QUrl::RemoveQuery)
       
  1607 			 << QString::fromLatin1("http:/index.html#top");
       
  1608 
       
  1609     QTest::newRow("data16") << QString::fromLatin1("http://ole:password@www.troll.no:9090/index.html?ole=semann&gud=hei#top")
       
  1610 			 << uint(QUrl::RemovePassword | QUrl::RemovePort
       
  1611 			    | QUrl::RemovePath | QUrl::RemoveQuery
       
  1612 			    | QUrl::RemoveFragment)
       
  1613 			 << QString::fromLatin1("http://ole@www.troll.no");
       
  1614 
       
  1615     QTest::newRow("data17") << QString::fromLatin1("http://ole:password@www.troll.no:9090/index.html?ole=semann&gud=hei#top")
       
  1616 			 << uint(QUrl::RemoveScheme | QUrl::RemovePassword
       
  1617 			    | QUrl::RemovePort | QUrl::RemovePath
       
  1618 			    | QUrl::RemoveQuery | QUrl::RemoveFragment)
       
  1619 			 << QString::fromLatin1("//ole@www.troll.no");
       
  1620 
       
  1621     QTest::newRow("data18") << QString::fromLatin1("http://andreas:hemmelig@www.vg.no/?my=query&your=query#yougotfragged")
       
  1622                          << uint(QUrl::None)
       
  1623                          << QString::fromLatin1("http://andreas:hemmelig@www.vg.no/?my=query&your=query#yougotfragged");
       
  1624 
       
  1625     /*
       
  1626     QTest::newRow("data19") << QString::fromLatin1("http://andreas:hemmelig@www.vg.no/a/../?my=query&your=query#yougotfragged")
       
  1627                          << uint(QUrl::None)
       
  1628                          << QString::fromLatin1("http://andreas:hemmelig@www.vg.no/?my=query&your=query#yougotfragged");
       
  1629     */
       
  1630 
       
  1631     QTest::newRow("nopath_task31320") << QString::fromLatin1("host://protocol")
       
  1632                                    << uint(QUrl::None)
       
  1633                                    << QString::fromLatin1("host://protocol");
       
  1634 }
       
  1635 
       
  1636 void tst_QUrl::toString()
       
  1637 {
       
  1638     QFETCH(QString, urlString);
       
  1639     QFETCH(uint, options);
       
  1640     QFETCH(QString, string);
       
  1641 
       
  1642     QUrl url(urlString);
       
  1643     QCOMPARE(url.toString(QUrl::FormattingOptions(options)), string);
       
  1644 }
       
  1645 
       
  1646 //### more tests ... what do we expect ...
       
  1647 void tst_QUrl::isParentOf_data()
       
  1648 {
       
  1649     QTest::addColumn<QString>("parent");
       
  1650     QTest::addColumn<QString>("child");
       
  1651     QTest::addColumn<bool>("trueFalse");
       
  1652 
       
  1653     QTest::newRow("data0")	<< QString::fromLatin1("http://a.b.c/d")
       
  1654 			<< QString::fromLatin1("http://a.b.c/d/e?f") << true;
       
  1655     QTest::newRow("data1")	<< QString::fromLatin1("http://a.b.c/d")
       
  1656 			<< QString::fromLatin1("http://a.b.c/d") << false;
       
  1657     QTest::newRow("data2")	<< QString::fromLatin1("http://a.b.c/d")
       
  1658 			<< QString::fromLatin1("http://a.b.c/de") << false;
       
  1659     QTest::newRow("data3")	<< QString::fromLatin1("http://a.b.c/d/")
       
  1660 			<< QString::fromLatin1("http://a.b.c/de") << false;
       
  1661     QTest::newRow("data4")	<< QString::fromLatin1("http://a.b.c/d/")
       
  1662 			<< QString::fromLatin1("http://a.b.c/d/e") << true;
       
  1663 
       
  1664 
       
  1665 }
       
  1666 
       
  1667 void tst_QUrl::toString_constructed_data()
       
  1668 {
       
  1669     QTest::addColumn<QString>("scheme");
       
  1670     QTest::addColumn<QString>("userName");
       
  1671     QTest::addColumn<QString>("password");
       
  1672     QTest::addColumn<QString>("host");
       
  1673     QTest::addColumn<int>("port");
       
  1674     QTest::addColumn<QString>("path");
       
  1675     QTest::addColumn<QByteArray>("query");
       
  1676     QTest::addColumn<QString>("fragment");
       
  1677     QTest::addColumn<QString>("asString");
       
  1678     QTest::addColumn<QByteArray>("asEncoded");
       
  1679 
       
  1680     QString n("");
       
  1681 
       
  1682     QTest::newRow("data1") << n << n << n << QString::fromLatin1("qt.nokia.com") << -1 << QString::fromLatin1("index.html")
       
  1683 	                << QByteArray() << n << QString::fromLatin1("//qt.nokia.com/index.html")
       
  1684 			<< QByteArray("//qt.nokia.com/index.html");
       
  1685     QTest::newRow("data2") << QString::fromLatin1("file") << n << n << n << -1 << QString::fromLatin1("/root") << QByteArray()
       
  1686                         << n << QString::fromLatin1("file:///root") << QByteArray("file:///root");
       
  1687     QTest::newRow("userAndPass") << QString::fromLatin1("http") << QString::fromLatin1("dfaure") << QString::fromLatin1("kde")
       
  1688                                  << "kde.org" << 443 << QString::fromLatin1("/") << QByteArray() << n
       
  1689                                  << QString::fromLatin1("http://dfaure:kde@kde.org:443/") << QByteArray("http://dfaure:kde@kde.org:443/");
       
  1690     QTest::newRow("PassWithoutUser") << QString::fromLatin1("http") << n << QString::fromLatin1("kde")
       
  1691                                      << "kde.org" << 443 << QString::fromLatin1("/") << QByteArray() << n
       
  1692                                      << QString::fromLatin1("http://:kde@kde.org:443/") << QByteArray("http://:kde@kde.org:443/");
       
  1693 }
       
  1694 
       
  1695 void tst_QUrl::toString_constructed()
       
  1696 {
       
  1697     QFETCH(QString, scheme);
       
  1698     QFETCH(QString, userName);
       
  1699     QFETCH(QString, password);
       
  1700     QFETCH(QString, host);
       
  1701     QFETCH(int, port);
       
  1702     QFETCH(QString, path);
       
  1703     QFETCH(QByteArray, query);
       
  1704     QFETCH(QString, fragment);
       
  1705     QFETCH(QString, asString);
       
  1706     QFETCH(QByteArray, asEncoded);
       
  1707 
       
  1708     QUrl url;
       
  1709     if (!scheme.isEmpty())
       
  1710 	url.setScheme(scheme);
       
  1711     if (!userName.isEmpty())
       
  1712 	url.setUserName(userName);
       
  1713     if (!password.isEmpty())
       
  1714 	url.setPassword(password);
       
  1715     if (!host.isEmpty())
       
  1716 	url.setHost(host);
       
  1717     if (port != -1)
       
  1718 	url.setPort(port);
       
  1719     if (!path.isEmpty())
       
  1720 	url.setPath(path);
       
  1721     if (!query.isEmpty())
       
  1722 	url.setEncodedQuery(query);
       
  1723     if (!fragment.isEmpty())
       
  1724 	url.setFragment(fragment);
       
  1725 
       
  1726     QVERIFY(url.isValid());
       
  1727     QCOMPARE(url.toString(), asString);
       
  1728     QCOMPARE(QString::fromLatin1(url.toEncoded()), QString::fromLatin1(asEncoded)); // readable in case of differences
       
  1729     QCOMPARE(url.toEncoded(), asEncoded);
       
  1730 }
       
  1731 
       
  1732 
       
  1733 void tst_QUrl::isParentOf()
       
  1734 {
       
  1735     QFETCH(QString, parent);
       
  1736     QFETCH(QString, child);
       
  1737     QFETCH(bool, trueFalse);
       
  1738 
       
  1739     QUrl url(parent);
       
  1740     QCOMPARE(url.isParentOf(QUrl(child)), trueFalse);
       
  1741 }
       
  1742 
       
  1743 void tst_QUrl::toLocalFile_data()
       
  1744 {
       
  1745     QTest::addColumn<QString>("theUrl");
       
  1746     QTest::addColumn<QString>("theFile");
       
  1747 
       
  1748     QTest::newRow("data0")	<< QString::fromLatin1("file:/a.txt") << QString::fromLatin1("/a.txt");
       
  1749     QTest::newRow("data4")	<< QString::fromLatin1("file:///a.txt") << QString::fromLatin1("/a.txt");
       
  1750     QTest::newRow("data5")	<< QString::fromLatin1("file:///c:/a.txt") << QString::fromLatin1("c:/a.txt");
       
  1751     QTest::newRow("data6")	<< QString::fromLatin1("file://somehost/somedir/somefile") << QString::fromLatin1("//somehost/somedir/somefile");
       
  1752     QTest::newRow("data7")	<< QString::fromLatin1("file://somehost/") << QString::fromLatin1("//somehost/");
       
  1753     QTest::newRow("data8")	<< QString::fromLatin1("file://somehost") << QString::fromLatin1("//somehost");
       
  1754     QTest::newRow("data9")	<< QString::fromLatin1("file:////somehost/somedir/somefile") << QString::fromLatin1("//somehost/somedir/somefile");
       
  1755 
       
  1756 }
       
  1757 
       
  1758 void tst_QUrl::toLocalFile()
       
  1759 {
       
  1760     QFETCH(QString, theUrl);
       
  1761     QFETCH(QString, theFile);
       
  1762 
       
  1763     QUrl url(theUrl);
       
  1764     QCOMPARE(url.toLocalFile(), theFile);
       
  1765 }
       
  1766 
       
  1767 void tst_QUrl::fromLocalFile_data()
       
  1768 {
       
  1769     QTest::addColumn<QString>("theFile");
       
  1770     QTest::addColumn<QString>("theUrl");
       
  1771     QTest::addColumn<QString>("thePath");
       
  1772 
       
  1773     QTest::newRow("data0")	<< QString::fromLatin1("/a.txt") << QString::fromLatin1("file:///a.txt") << QString::fromLatin1("/a.txt");
       
  1774     QTest::newRow("data1")	<< QString::fromLatin1("a.txt") << QString::fromLatin1("file:a.txt") << QString::fromLatin1("a.txt");
       
  1775     QTest::newRow("data2")	<< QString::fromLatin1("/a/b.txt") << QString::fromLatin1("file:///a/b.txt") << QString::fromLatin1("/a/b.txt");
       
  1776     QTest::newRow("data3")	<< QString::fromLatin1("c:/a.txt") << QString::fromLatin1("file:///c:/a.txt") << QString::fromLatin1("/c:/a.txt");
       
  1777     QTest::newRow("data4")	<< QString::fromLatin1("//somehost/somedir/somefile") << QString::fromLatin1("file://somehost/somedir/somefile")
       
  1778 	                << QString::fromLatin1("/somedir/somefile");
       
  1779     QTest::newRow("data5")	<< QString::fromLatin1("//somehost") << QString::fromLatin1("file://somehost")
       
  1780 	                << QString::fromLatin1("");
       
  1781     QTest::newRow("data6")	<< QString::fromLatin1("//somehost/") << QString::fromLatin1("file://somehost/")
       
  1782 	                << QString::fromLatin1("/");
       
  1783 }
       
  1784 
       
  1785 void tst_QUrl::fromLocalFile()
       
  1786 {
       
  1787     QFETCH(QString, theFile);
       
  1788     QFETCH(QString, theUrl);
       
  1789     QFETCH(QString, thePath);
       
  1790 
       
  1791     QUrl url = QUrl::fromLocalFile(theFile);
       
  1792 
       
  1793     QCOMPARE(url.toString(), theUrl);
       
  1794     QCOMPARE(url.path(), thePath);
       
  1795 }
       
  1796 
       
  1797 void tst_QUrl::compat_legacy()
       
  1798 {
       
  1799     {
       
  1800 	QUrl u( "file:bar" );
       
  1801 	QCOMPARE( u.toString(QUrl::RemoveScheme), QString("bar") );
       
  1802     }
       
  1803 
       
  1804     /* others
       
  1805      */
       
  1806     {
       
  1807 	QUrl u( "http://qt.nokia.com/images/ban/pgs_front.jpg" );
       
  1808 	QCOMPARE( u.path(), QString("/images/ban/pgs_front.jpg") );
       
  1809     }
       
  1810     {
       
  1811 	QUrl tmp( "http://qt.nokia.com/images/ban/" );
       
  1812 	QUrl u = tmp.resolved(QString("pgs_front.jpg"));
       
  1813 	QCOMPARE( u.path(), QString("/images/ban/pgs_front.jpg") );
       
  1814     }
       
  1815     {
       
  1816 	QUrl tmp;
       
  1817 	QUrl u = tmp.resolved(QString("http://qt.nokia.com/images/ban/pgs_front.jpg"));
       
  1818 	QCOMPARE( u.path(), QString("/images/ban/pgs_front.jpg") );
       
  1819     }
       
  1820     {
       
  1821 	QUrl tmp;
       
  1822 	QUrl u = tmp.resolved(QString("http://qt.nokia.com/images/ban/pgs_front.jpg"));
       
  1823 	QFileInfo fi(u.path());
       
  1824 	u.setPath(fi.path());
       
  1825 	QCOMPARE( u.path(), QString("/images/ban") );
       
  1826     }
       
  1827 }
       
  1828 
       
  1829 void tst_QUrl::compat_constructor_01_data()
       
  1830 {
       
  1831     QTest::addColumn<QString>("urlStr");
       
  1832     QTest::addColumn<QString>("res");
       
  1833 
       
  1834     //next we fill it with data
       
  1835     QTest::newRow( "data0" )  << QString("Makefile") << QString("Makefile"); // nolonger add file by default
       
  1836     QTest::newRow( "data1" )  << QString("Makefile") << QString("Makefile");
       
  1837     QTest::newRow( "data2" )  << QString("ftp://ftp.qt.nokia.com/qt/INSTALL") << QString("ftp://ftp.qt.nokia.com/qt/INSTALL");
       
  1838     QTest::newRow( "data3" )  << QString("ftp://ftp.qt.nokia.com/qt/INSTALL") << QString("ftp://ftp.qt.nokia.com/qt/INSTALL");
       
  1839 }
       
  1840 
       
  1841 void tst_QUrl::compat_constructor_01()
       
  1842 {
       
  1843     /* The following should work as expected:
       
  1844      *
       
  1845      * QUrlOperator op;
       
  1846      * op.copy( QString( "Makefile" ),
       
  1847      *          QString("ftp://rms:grmpf12@nibbler/home/rms/tmp"),
       
  1848      *          false );
       
  1849      *
       
  1850      * as well as the following:
       
  1851      *
       
  1852      * QUrlOperator op;
       
  1853      * op.copy(QString("ftp://ftp.qt.nokia.com/qt/INSTALL"), ".");
       
  1854      */
       
  1855     QFETCH( QString, urlStr );
       
  1856 
       
  1857     {
       
  1858 	QUrl empty;
       
  1859 	QUrl u = empty.resolved(urlStr);
       
  1860 
       
  1861 	QTEST( u.toString(), "res" );
       
  1862     }
       
  1863     {
       
  1864 	QUrl empty;
       
  1865 	QUrl u = empty.resolved(urlStr);
       
  1866 
       
  1867 	QTEST( u.toString(), "res" );
       
  1868     }
       
  1869 }
       
  1870 
       
  1871 void tst_QUrl::compat_constructor_02_data()
       
  1872 {
       
  1873     QTest::addColumn<QString>("urlStr");
       
  1874     QTest::addColumn<QString>("fileName");
       
  1875     QTest::addColumn<QString>("res");
       
  1876 
       
  1877     //next we fill it with data
       
  1878     QTest::newRow( "data0" )  << QString("ftp://ftp.qt.nokia.com/qt") << QString("INSTALL") << QString("ftp://ftp.qt.nokia.com/INSTALL");
       
  1879     QTest::newRow( "data1" )  << QString("ftp://ftp.qt.nokia.com/qt/") << QString("INSTALL") << QString("ftp://ftp.qt.nokia.com/qt/INSTALL");
       
  1880 }
       
  1881 
       
  1882 void tst_QUrl::compat_constructor_02()
       
  1883 {
       
  1884     /* The following should work as expected:
       
  1885      *
       
  1886      * QUrlOperator op( "ftp://ftp.qt.nokia.com/qt" );
       
  1887      * op.copy(QString("INSTALL"), ".");
       
  1888      */
       
  1889     QFETCH( QString, urlStr );
       
  1890     QFETCH( QString, fileName );
       
  1891 
       
  1892     QUrl tmp( urlStr );
       
  1893     QUrl u = tmp.resolved(fileName);
       
  1894 
       
  1895     QTEST( u.toString(), "res" );
       
  1896 }
       
  1897 
       
  1898 void tst_QUrl::compat_constructor_03_data()
       
  1899 {
       
  1900     QTest::addColumn<QString>("urlStr");
       
  1901     QTest::addColumn<QString>("res");
       
  1902 
       
  1903     //next we fill it with data
       
  1904     QTest::newRow( "protocol00" )  << QString( "http://qt.nokia.com/index.html" ) << QString( "http://qt.nokia.com/index.html" );
       
  1905     QTest::newRow( "protocol01" )  << QString( "http://qt.nokia.com" ) << QString( "http://qt.nokia.com" );
       
  1906     QTest::newRow( "protocol02" )  << QString( "http://qt.nokia.com/" ) << QString( "http://qt.nokia.com/" );
       
  1907     QTest::newRow( "protocol03" )  << QString( "http://qt.nokia.com/foo" ) << QString( "http://qt.nokia.com/foo" );
       
  1908     QTest::newRow( "protocol04" )  << QString( "http://qt.nokia.com/foo/" ) << QString( "http://qt.nokia.com/foo/" );
       
  1909     QTest::newRow( "protocol05" )  << QString( "ftp://ftp.qt.nokia.com/foo/index.txt" ) << QString( "ftp://ftp.qt.nokia.com/foo/index.txt" );
       
  1910 
       
  1911     QTest::newRow( "local00" )  << QString( "/foo" ) << QString( "/foo" );
       
  1912     QTest::newRow( "local01" )  << QString( "/foo/" ) << QString( "/foo/" );
       
  1913     QTest::newRow( "local02" )  << QString( "/foo/bar" ) << QString( "/foo/bar" );
       
  1914     QTest::newRow( "local03" )  << QString( "/foo/bar/" ) << QString( "/foo/bar/" );
       
  1915     QTest::newRow( "local04" )  << QString( "foo" ) << QString( "foo" );
       
  1916     QTest::newRow( "local05" )  << QString( "foo/" ) << QString( "foo/" );
       
  1917     QTest::newRow( "local06" )  << QString( "foo/bar" ) << QString( "foo/bar" );
       
  1918     QTest::newRow( "local07" )  << QString( "foo/bar/" ) << QString( "foo/bar/" );
       
  1919     QTest::newRow( "local09" )  << QString( "" ) << QString( "" );
       
  1920 
       
  1921     QTest::newRow( "file00" )  << QString( "file:/foo" ) << QString( "file:///foo" );
       
  1922     QTest::newRow( "file01" )  << QString( "file:/foo/" ) << QString( "file:///foo/" );
       
  1923     QTest::newRow( "file02" )  << QString( "file:/foo/bar" ) << QString( "file:///foo/bar" );
       
  1924     QTest::newRow( "file03" )  << QString( "file:/foo/bar/" ) << QString( "file:///foo/bar/" );
       
  1925     QTest::newRow( "relProtocol00" )  << QString( "foo:bar" ) << QString( "foo:bar" );
       
  1926     QTest::newRow( "relProtocol01" )  << QString( "foo:/bar" ) << QString( "foo:/bar" );
       
  1927 
       
  1928     QTest::newRow( "windowsDrive00" )  << QString( "c:/" ) << QString( "c:/" );
       
  1929     QTest::newRow( "windowsDrive01" )  << QString( "c:" ) << QString( "c:" );
       
  1930     QTest::newRow( "windowsDrive02" )  << QString( "c:/WinNT/" ) << QString( "c:/WinNT/" );
       
  1931     QTest::newRow( "windowsDrive03" )  << QString( "c:/autoexec.bat" ) << QString( "c:/autoexec.bat" );
       
  1932     QTest::newRow( "windowsDrive04" )  << QString( "c:WinNT/" ) << QString( "c:WinNT/" );
       
  1933     QTest::newRow( "windowsDrive05" )  << QString( "c:autoexec.bat" ) << QString( "c:autoexec.bat" );
       
  1934 
       
  1935     QTest::newRow("task31280") << QString("protocol://host") << QString("protocol://host");
       
  1936 }
       
  1937 
       
  1938 void tst_QUrl::compat_constructor_03()
       
  1939 {
       
  1940     QFETCH( QString, urlStr );
       
  1941 
       
  1942     QUrl u( urlStr );
       
  1943     QTEST( u.toString(), "res" );
       
  1944 }
       
  1945 
       
  1946 void tst_QUrl::compat_isValid_01_data()
       
  1947 {
       
  1948     QTest::addColumn<QString>("urlStr");
       
  1949     QTest::addColumn<bool>("res");
       
  1950 
       
  1951     QTest::newRow( "ok_01" ) << QString("ftp://ftp.qt.nokia.com/qt/INSTALL") << (bool)true;
       
  1952     QTest::newRow( "ok_02" ) << QString( "file:/foo") << (bool)true;
       
  1953     QTest::newRow( "ok_03" ) << QString( "file:foo") << (bool)true;
       
  1954 
       
  1955     QTest::newRow( "err_01" ) << QString("#ftp://ftp.qt.nokia.com/qt/INSTALL") << (bool)true;
       
  1956     QTest::newRow( "err_02" ) << QString( "file:/::foo") << (bool)true;
       
  1957 }
       
  1958 
       
  1959 void tst_QUrl::compat_isValid_01()
       
  1960 {
       
  1961     QFETCH( QString, urlStr );
       
  1962     QFETCH( bool, res );
       
  1963 
       
  1964     QUrl url( urlStr );
       
  1965     QVERIFY( url.isValid() == res );
       
  1966 }
       
  1967 
       
  1968 void tst_QUrl::compat_isValid_02_data()
       
  1969 {
       
  1970     QTest::addColumn<QString>("protocol");
       
  1971     QTest::addColumn<QString>("user");
       
  1972     QTest::addColumn<QString>("password");
       
  1973     QTest::addColumn<QString>("host");
       
  1974     QTest::addColumn<int>("port");
       
  1975     QTest::addColumn<QString>("path");
       
  1976     QTest::addColumn<bool>("res");
       
  1977 
       
  1978     QString n = "";
       
  1979 
       
  1980     QTest::newRow( "ok_01" ) << n     << n     << n     << n                   << -1 << QString("path") << (bool)true;
       
  1981     QTest::newRow( "ok_02" ) << QString("ftp") << n     << n     << QString("ftp.qt.nokia.com") << -1 << n      << (bool)true;
       
  1982     QTest::newRow( "ok_03" ) << QString("ftp") << QString("foo") << n     << QString("ftp.qt.nokia.com") << -1 << n      << (bool)true;
       
  1983     QTest::newRow( "ok_04" ) << QString("ftp") << QString("foo") << QString("bar") << QString("ftp.qt.nokia.com") << -1 << n      << (bool)true;
       
  1984     QTest::newRow( "ok_05" ) << QString("ftp") << n     << n     << QString("ftp.qt.nokia.com") << -1 << QString("path")<< (bool)true;
       
  1985     QTest::newRow( "ok_06" ) << QString("ftp") << QString("foo") << n     << QString("ftp.qt.nokia.com") << -1 << QString("path") << (bool)true;
       
  1986     QTest::newRow( "ok_07" ) << QString("ftp") << QString("foo") << QString("bar") << QString("ftp.qt.nokia.com") << -1 << QString("path")<< (bool)true;
       
  1987 
       
  1988     QTest::newRow( "err_01" ) << n     << n     << n     << n                   << -1 << n << (bool)false;
       
  1989     QTest::newRow( "err_02" ) << QString("ftp") << n     << n     << n                   << -1 << n << (bool)true;
       
  1990     QTest::newRow( "err_03" ) << n     << QString("foo") << n     << n                   << -1 << n << (bool)true;
       
  1991     QTest::newRow( "err_04" ) << n     << n     << QString("bar") << n                   << -1 << n << (bool)true;
       
  1992     QTest::newRow( "err_05" ) << n     << n     << n     << QString("ftp.qt.nokia.com") << -1 << n << (bool)true;
       
  1993     QTest::newRow( "err_06" ) << n     << n     << n     << n                   << 80 << n << (bool)true;
       
  1994     QTest::newRow( "err_07" ) << QString("ftp") << QString("foo") << n     << n                   << -1 << n << (bool)true;
       
  1995     QTest::newRow( "err_08" ) << QString("ftp") << n     << QString("bar") << n                   << -1 << n << (bool)true;
       
  1996     QTest::newRow( "err_09" ) << QString("ftp") << QString("foo") << QString("bar") << n                   << -1 << n << (bool)true;
       
  1997 }
       
  1998 
       
  1999 void tst_QUrl::compat_isValid_02()
       
  2000 {
       
  2001     QFETCH( QString, protocol );
       
  2002     QFETCH( QString, user );
       
  2003     QFETCH( QString, password );
       
  2004     QFETCH( QString, host );
       
  2005     QFETCH( int, port );
       
  2006     QFETCH( QString, path );
       
  2007     QFETCH( bool, res );
       
  2008 
       
  2009     QUrl url;
       
  2010     if ( !protocol.isEmpty() )
       
  2011 	url.setScheme( protocol );
       
  2012     if ( !user.isEmpty() )
       
  2013 	url.setUserName( user );
       
  2014     if ( !password.isEmpty() )
       
  2015 	url.setPassword( password );
       
  2016     if ( !host.isEmpty() )
       
  2017 	url.setHost( host );
       
  2018     if ( port != -1 )
       
  2019 	url.setPort( port );
       
  2020     if ( !path.isEmpty() )
       
  2021 	url.setPath( path );
       
  2022 
       
  2023     QVERIFY( url.isValid() == res );
       
  2024 }
       
  2025 
       
  2026 void tst_QUrl::compat_path_data()
       
  2027 {
       
  2028     QTest::addColumn<QString>("url");
       
  2029     QTest::addColumn<QString>("res");
       
  2030 
       
  2031     QTest::newRow( "protocol00" ) << "http://qt.nokia.com/images/ban/pgs_front.jpg" << "/images/ban/pgs_front.jpg";
       
  2032 
       
  2033 #if defined( Q_OS_WIN32 )
       
  2034     QTest::newRow( "winShare00" ) << "//Anarki/homes" << "/homes";
       
  2035 #endif
       
  2036 }
       
  2037 
       
  2038 void tst_QUrl::compat_path()
       
  2039 {
       
  2040     QFETCH( QString, url );
       
  2041 
       
  2042     QUrl u( url );
       
  2043     QTEST( u.path(), "res" );
       
  2044 }
       
  2045 
       
  2046 void tst_QUrl::compat_fileName_data()
       
  2047 {
       
  2048     QTest::addColumn<QString>("url");
       
  2049     QTest::addColumn<QString>("fileName");
       
  2050 
       
  2051 #ifdef Q_OS_WIN32
       
  2052     QTest::newRow( "Windows - DrivePathFileName - \\" ) << QString("c:\\windows\\tmp\\filename.txt")<< QString("filename.txt");
       
  2053     QTest::newRow( "Windows - DrivePathFileName - /" ) << QString("c:/windows/tmp/filename.txt") << QString("filename.txt");
       
  2054     QTest::newRow( "Windows - DrivePathWithSlash - \\" ) << QString("c:\\windows\\tmp\\") << QString();
       
  2055     QTest::newRow( "Windows - DrivePathWithSlash - /" ) << QString("c:/windows/tmp/") << QString();
       
  2056     QTest::newRow( "Windows - DrivePathWithoutSlash - \\" ) << QString("c:/windows/tmp") << QString("tmp");
       
  2057     QTest::newRow( "Windows - DrivePathWithoutSlash - /" ) << QString("c:/windows/tmp") << QString("tmp");
       
  2058 #endif
       
  2059     QTest::newRow( "Path00" ) << QString("/") << QString();
       
  2060     QTest::newRow( "Path01" ) << QString("/home/dev/test/") << QString();
       
  2061     QTest::newRow( "PathFileName00" ) << QString("/home/dev/test") << QString("test");
       
  2062 }
       
  2063 
       
  2064 void tst_QUrl::compat_fileName()
       
  2065 {
       
  2066     QFETCH( QString, url );
       
  2067     QFETCH( QString, fileName );
       
  2068     QUrl fileUrl = QUrl::fromLocalFile(url);
       
  2069     QFileInfo fi(fileUrl.toLocalFile());
       
  2070     QCOMPARE( fi.fileName(), fileName );
       
  2071 }
       
  2072 
       
  2073 void tst_QUrl::compat_decode_data()
       
  2074 {
       
  2075     QTest::addColumn<QByteArray>("encodedString");
       
  2076     QTest::addColumn<QString>("decodedString");
       
  2077 
       
  2078     QTest::newRow("NormalString") << QByteArray("filename") << QString("filename");
       
  2079     QTest::newRow("NormalStringEncoded") << QByteArray("file%20name") << QString("file name");
       
  2080     QTest::newRow("JustEncoded") << QByteArray("%20") << QString(" ");
       
  2081     QTest::newRow("HTTPUrl") << QByteArray("http://qt.nokia.com") << QString("http://qt.nokia.com");
       
  2082     QTest::newRow("HTTPUrlEncoded") << QByteArray("http://qt%20nokia%20com") << QString("http://qt nokia com");
       
  2083     QTest::newRow("EmptyString") << QByteArray("") << QString("");
       
  2084     QTest::newRow("Task27166") << QByteArray("Fran%C3%A7aise") << QString("Française");
       
  2085 }
       
  2086 
       
  2087 void tst_QUrl::compat_decode()
       
  2088 {
       
  2089     QFETCH(QByteArray, encodedString);
       
  2090     QFETCH(QString, decodedString);
       
  2091 
       
  2092     QCOMPARE(QUrl::fromPercentEncoding(encodedString), decodedString);
       
  2093 }
       
  2094 
       
  2095 void tst_QUrl::compat_encode_data()
       
  2096 {
       
  2097     QTest::addColumn<QString>("decodedString");
       
  2098     QTest::addColumn<QByteArray>("encodedString");
       
  2099 
       
  2100     QTest::newRow("NormalString") << QString("filename") << QByteArray("filename");
       
  2101     QTest::newRow("NormalStringEncoded") << QString("file name") << QByteArray("file%20name");
       
  2102     QTest::newRow("JustEncoded") << QString(" ") << QByteArray("%20");
       
  2103     QTest::newRow("HTTPUrl") << QString("http://qt.nokia.com") << QByteArray("http%3A//qt.nokia.com");
       
  2104     QTest::newRow("HTTPUrlEncoded") << QString("http://qt nokia com") << QByteArray("http%3A//qt%20nokia%20com");
       
  2105     QTest::newRow("EmptyString") << QString("") << QByteArray("");
       
  2106     QTest::newRow("Task27166") << QString::fromLatin1("Française") << QByteArray("Fran%C3%A7aise");
       
  2107 }
       
  2108 
       
  2109 void tst_QUrl::compat_encode()
       
  2110 {
       
  2111     QFETCH(QString, decodedString);
       
  2112     QFETCH(QByteArray, encodedString);
       
  2113 
       
  2114     QCOMPARE(QUrl::toPercentEncoding(decodedString, "/.").constData(), encodedString.constData());
       
  2115 }
       
  2116 
       
  2117 
       
  2118 void tst_QUrl::relative()
       
  2119 {
       
  2120     QUrl url("../ole");
       
  2121     QCOMPARE(url.path(), QString::fromLatin1("../ole"));
       
  2122 
       
  2123     QUrl url2("./");
       
  2124     QCOMPARE(url2.path(), QString::fromLatin1("./"));
       
  2125 
       
  2126     QUrl url3("..");
       
  2127     QCOMPARE(url3.path(), QString::fromLatin1(".."));
       
  2128 
       
  2129     QUrl url4("../..");
       
  2130     QCOMPARE(url4.path(), QString::fromLatin1("../.."));
       
  2131 }
       
  2132 
       
  2133 void tst_QUrl::percentEncoding_data()
       
  2134 {
       
  2135     QTest::addColumn<QString>("original");
       
  2136     QTest::addColumn<QByteArray>("encoded");
       
  2137 
       
  2138     QTest::newRow("test_01") << QString::fromLatin1("sdfsdf") << QByteArray("sdfsdf");
       
  2139     QTest::newRow("test_02") << QString::fromLatin1("æss") << QByteArray("%C3%A6ss");
       
  2140     // not unreserved or reserved
       
  2141     QTest::newRow("test_03") << QString::fromLatin1("{}") << QByteArray("%7B%7D");
       
  2142 }
       
  2143 
       
  2144 void tst_QUrl::percentEncoding()
       
  2145 {
       
  2146     QFETCH(QString, original);
       
  2147     QFETCH(QByteArray, encoded);
       
  2148 
       
  2149     QCOMPARE(QUrl(original).toEncoded().constData(), encoded.constData());
       
  2150     QVERIFY(QUrl::fromEncoded(QUrl(original).toEncoded()) == QUrl(original));
       
  2151     QCOMPARE(QUrl::fromEncoded(QUrl(original).toEncoded()).toString(), original);
       
  2152     QVERIFY(QUrl::fromEncoded(encoded) == QUrl(original));
       
  2153 }
       
  2154 
       
  2155 void tst_QUrl::toPercentEncoding_data()
       
  2156 {
       
  2157     QTest::addColumn<QString>("original");
       
  2158     QTest::addColumn<QByteArray>("encoded");
       
  2159     QTest::addColumn<QByteArray>("excludeInEncoding");
       
  2160     QTest::addColumn<QByteArray>("includeInEncoding");
       
  2161 
       
  2162     QTest::newRow("test_01") << QString::fromLatin1("abcdevghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678-._~")
       
  2163                           << QByteArray("abcdevghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678-._~") 
       
  2164                           << QByteArray("")
       
  2165                           << QByteArray("");
       
  2166     QTest::newRow("test_02") << QString::fromLatin1("{\t\n\r^\"abc}")
       
  2167                           << QByteArray("%7B%09%0A%0D%5E%22abc%7D") 
       
  2168                           << QByteArray("")
       
  2169                           << QByteArray("");
       
  2170     QTest::newRow("test_03") << QString::fromLatin1("://?#[]@!$&'()*+,;=")
       
  2171                           << QByteArray("%3A%2F%2F%3F%23%5B%5D%40%21%24%26%27%28%29%2A%2B%2C%3B%3D") 
       
  2172                           << QByteArray("")
       
  2173                           << QByteArray("");
       
  2174     QTest::newRow("test_04") << QString::fromLatin1("://?#[]@!$&'()*+,;=")
       
  2175                           << QByteArray("%3A%2F%2F%3F%23%5B%5D%40!$&'()*+,;=") 
       
  2176                           << QByteArray("!$&'()*+,;=")
       
  2177                           << QByteArray("");
       
  2178     QTest::newRow("test_05") << QString::fromLatin1("abcd")
       
  2179                           << QByteArray("a%62%63d")
       
  2180                           << QByteArray("")
       
  2181                           << QByteArray("bc");                          
       
  2182 }
       
  2183 
       
  2184 void tst_QUrl::toPercentEncoding()
       
  2185 {
       
  2186     QFETCH(QString, original);
       
  2187     QFETCH(QByteArray, encoded);
       
  2188     QFETCH(QByteArray, excludeInEncoding);
       
  2189     QFETCH(QByteArray, includeInEncoding);
       
  2190 
       
  2191     QByteArray encodedUrl = QUrl::toPercentEncoding(original, excludeInEncoding, includeInEncoding); 
       
  2192     QCOMPARE(encodedUrl.constData(), encoded.constData());
       
  2193     QCOMPARE(original, QUrl::fromPercentEncoding(encodedUrl));
       
  2194 }
       
  2195 
       
  2196 void tst_QUrl::symmetry()
       
  2197 {
       
  2198     QUrl url(QString::fromLatin1("http://www.räksmörgås.se/pub?a=b&a=dø&a=f#vræl"));
       
  2199     QCOMPARE(url.scheme(), QString::fromLatin1("http"));
       
  2200     QCOMPARE(url.host(), QString::fromLatin1("www.räksmörgås.se"));
       
  2201     QCOMPARE(url.path(), QString::fromLatin1("/pub"));
       
  2202     // this will be encoded ...
       
  2203     QCOMPARE(url.encodedQuery().constData(), QString::fromLatin1("a=b&a=d%C3%B8&a=f").toLatin1().constData());
       
  2204     // unencoded
       
  2205     QCOMPARE(url.allQueryItemValues("a").join("").toLatin1().constData(), "bdøf");
       
  2206     QCOMPARE(url.fragment(), QString::fromLatin1("vræl"));
       
  2207 
       
  2208     QUrl onlyHost("//qt.nokia.com");
       
  2209     QCOMPARE(onlyHost.toString(), QString::fromLatin1("//qt.nokia.com"));
       
  2210 
       
  2211     {
       
  2212         QString urlString = QString::fromLatin1("http://desktop:33326/upnp/{32f525a6-6f31-426e-91ca-01c2e6c2c57e}");
       
  2213         QUrl urlPreviewList(urlString);
       
  2214         QCOMPARE(urlPreviewList.toString(), urlString);
       
  2215         QByteArray b = urlPreviewList.toEncoded();
       
  2216         QCOMPARE(b.constData(), "http://desktop:33326/upnp/%7B32f525a6-6f31-426e-91ca-01c2e6c2c57e%7D");
       
  2217         QCOMPARE(QUrl::fromEncoded(b).toString(), urlString);
       
  2218 
       
  2219     }{
       
  2220         QString urlString = QString::fromLatin1("http://desktop:53423/deviceDescription?uuid={7977c17b-00bf-4af9-894e-fed28573c3a9}");
       
  2221         QUrl urlPreviewList(urlString);
       
  2222         QCOMPARE(urlPreviewList.toString(), urlString);
       
  2223         QByteArray b = urlPreviewList.toEncoded();
       
  2224         QCOMPARE(b.constData(), "http://desktop:53423/deviceDescription?uuid=%7B7977c17b-00bf-4af9-894e-fed28573c3a9%7D");
       
  2225         QCOMPARE(QUrl::fromEncoded(b).toString(), urlString);
       
  2226     }
       
  2227 }
       
  2228 
       
  2229 
       
  2230 void tst_QUrl::ipv6_data()
       
  2231 {
       
  2232     QTest::addColumn<QString>("ipv6Auth");
       
  2233     QTest::addColumn<bool>("isValid");
       
  2234 
       
  2235     QTest::newRow("case 1") << QString::fromLatin1("//[56:56:56:56:56:56:56:56]") << true;
       
  2236     QTest::newRow("case 2") << QString::fromLatin1("//[::56:56:56:56:56:56:56]") << true;
       
  2237     QTest::newRow("case 3") << QString::fromLatin1("//[56::56:56:56:56:56:56]") << true;
       
  2238     QTest::newRow("case 4") << QString::fromLatin1("//[56:56::56:56:56:56:56]") << true;
       
  2239     QTest::newRow("case 5") << QString::fromLatin1("//[56:56:56::56:56:56:56]") << true;
       
  2240     QTest::newRow("case 6") << QString::fromLatin1("//[56:56:56:56::56:56:56]") << true;
       
  2241     QTest::newRow("case 7") << QString::fromLatin1("//[56:56:56:56:56::56:56]") << true;
       
  2242     QTest::newRow("case 8") << QString::fromLatin1("//[56:56:56:56:56:56::56]") << true;
       
  2243     QTest::newRow("case 9") << QString::fromLatin1("//[56:56:56:56:56:56:56::]") << true;
       
  2244     QTest::newRow("case 4 with one less") << QString::fromLatin1("//[56::56:56:56:56:56]") << true;
       
  2245     QTest::newRow("case 4 with less and ip4") << QString::fromLatin1("//[56::56:56:56:127.0.0.1]") << true;
       
  2246     QTest::newRow("case 7 with one and ip4") << QString::fromLatin1("//[56::255.0.0.0]") << true;
       
  2247     QTest::newRow("case 2 with ip4") << QString::fromLatin1("//[::56:56:56:56:56:0.0.0.255]") << true;
       
  2248     QTest::newRow("case 2 with half ip4") << QString::fromLatin1("//[::56:56:56:56:56:56:0.255]") << false;
       
  2249     QTest::newRow("case 4 with less and ip4 and port and useinfo") << QString::fromLatin1("//user:pass@[56::56:56:56:127.0.0.1]:99") << true;
       
  2250     QTest::newRow("case :,") << QString::fromLatin1("//[:,]") << false;
       
  2251     QTest::newRow("case ::bla") << QString::fromLatin1("//[::bla]") << false;
       
  2252 }
       
  2253 
       
  2254 void tst_QUrl::ipv6()
       
  2255 {
       
  2256     QFETCH(QString, ipv6Auth);
       
  2257     QFETCH(bool, isValid);
       
  2258 
       
  2259     QUrl url(ipv6Auth);
       
  2260 
       
  2261     QCOMPARE(url.isValid(), isValid);
       
  2262     if (url.isValid()) {
       
  2263 	QCOMPARE(url.toString(), ipv6Auth);
       
  2264     }
       
  2265 };
       
  2266 
       
  2267 void tst_QUrl::ipv6_2_data()
       
  2268 {
       
  2269     QTest::addColumn<QString>("input");
       
  2270     QTest::addColumn<QString>("output");
       
  2271 
       
  2272     QTest::newRow("[::ffff:129.144.52.38]")
       
  2273         << QString("http://[::ffff:129.144.52.38]/cgi/test.cgi")
       
  2274         << QString("http://[::ffff:129.144.52.38]/cgi/test.cgi");
       
  2275     QTest::newRow("[::FFFF:129.144.52.38]")
       
  2276         << QString("http://[::FFFF:129.144.52.38]/cgi/test.cgi")
       
  2277         << QString("http://[::ffff:129.144.52.38]/cgi/test.cgi");
       
  2278 }
       
  2279 
       
  2280 void tst_QUrl::ipv6_2()
       
  2281 {
       
  2282     QFETCH(QString, input);
       
  2283     QFETCH(QString, output);
       
  2284 
       
  2285     QUrl url(input);
       
  2286     QCOMPARE(url.toString(), output);
       
  2287 }
       
  2288 
       
  2289 void tst_QUrl::moreIpv6()
       
  2290 {
       
  2291     QUrl waba1("http://www.kde.org/cgi/test.cgi");
       
  2292     waba1.setHost("::ffff:129.144.52.38");
       
  2293     QCOMPARE(QString::fromLatin1(waba1.toEncoded()), QString::fromLatin1("http://[::ffff:129.144.52.38]/cgi/test.cgi"));
       
  2294 }
       
  2295 
       
  2296 void tst_QUrl::punycode_data()
       
  2297 {
       
  2298     QTest::addColumn<QString>("original");
       
  2299     QTest::addColumn<QByteArray>("encoded");
       
  2300 
       
  2301     QTest::newRow("øl") << QString::fromLatin1("øl") << QByteArray("xn--l-4ga");
       
  2302     QTest::newRow("Bühler") << QString::fromLatin1("Bühler") << QByteArray("xn--Bhler-kva");
       
  2303     QTest::newRow("räksmörgås") << QString::fromLatin1("räksmörgås") << QByteArray("xn--rksmrgs-5wao1o");
       
  2304 }
       
  2305 
       
  2306 void tst_QUrl::punycode()
       
  2307 {
       
  2308     QFETCH(QString, original);
       
  2309     QFETCH(QByteArray, encoded);
       
  2310 
       
  2311     QCOMPARE(QUrl::fromPunycode(encoded), original);
       
  2312     QCOMPARE(QUrl::fromPunycode(QUrl::toPunycode(original)), original);
       
  2313     QCOMPARE(QUrl::toPunycode(original).constData(), encoded.constData());
       
  2314 }
       
  2315 
       
  2316 void tst_QUrl::isRelative_data()
       
  2317 {
       
  2318     QTest::addColumn<QString>("url");
       
  2319     QTest::addColumn<bool>("trueFalse");
       
  2320 
       
  2321     QTest::newRow("not") << QString::fromLatin1("http://qt.nokia.com") << false;
       
  2322     QTest::newRow("55288") << QString::fromLatin1("node64.html#fig:form:ana") << true;
       
  2323 
       
  2324     // kde
       
  2325     QTest::newRow("mailto: URL, is relative") << "mailto:faure@kde.org" << false;
       
  2326     QTest::newRow("man: URL, is relative") << "man:mmap" << false;
       
  2327     QTest::newRow("javascript: URL, is relative") << "javascript:doSomething()" << false;
       
  2328     QTest::newRow("file: URL, is relative") << "file:/blah" << false;
       
  2329     QTest::newRow("/path, is relative") << "/path" << true;
       
  2330     QTest::newRow("something, is relative") << "something" << true;
       
  2331     // end kde
       
  2332 }
       
  2333 
       
  2334 void tst_QUrl::isRelative()
       
  2335 {
       
  2336     QFETCH(QString, url);
       
  2337     QFETCH(bool, trueFalse);
       
  2338 
       
  2339     QCOMPARE(QUrl(url).isRelative(), trueFalse);
       
  2340 }
       
  2341 
       
  2342 void tst_QUrl::queryItems()
       
  2343 {
       
  2344     QUrl url;
       
  2345     QVERIFY(!url.hasQuery());
       
  2346 
       
  2347     QList<QPair<QString, QString> > newItems;
       
  2348     newItems += qMakePair(QString("2"), QString("b"));
       
  2349     newItems += qMakePair(QString("1"), QString("a"));
       
  2350     newItems += qMakePair(QString("3"), QString("c"));
       
  2351     newItems += qMakePair(QString("4"), QString("a b"));
       
  2352     newItems += qMakePair(QString("5"), QString("&"));
       
  2353     newItems += qMakePair(QString("foo bar"), QString("hello world"));
       
  2354     newItems += qMakePair(QString("foo+bar"), QString("hello+world"));
       
  2355     newItems += qMakePair(QString("tex"), QString("a + b = c"));
       
  2356     url.setQueryItems(newItems);
       
  2357     QVERIFY(url.hasQuery());
       
  2358 
       
  2359     QList<QPair<QString, QString> > setItems = url.queryItems();
       
  2360     QVERIFY(newItems == setItems);
       
  2361 
       
  2362     url.addQueryItem("1", "z");
       
  2363 
       
  2364     QVERIFY(url.hasQueryItem("1"));
       
  2365     QCOMPARE(url.queryItemValue("1").toLatin1().constData(), "a");
       
  2366 
       
  2367     url.addQueryItem("1", "zz");
       
  2368 
       
  2369     QStringList expected;
       
  2370     expected += "a";
       
  2371     expected += "z";
       
  2372     expected += "zz";
       
  2373     QCOMPARE(expected, url.allQueryItemValues("1"));
       
  2374 
       
  2375     url.removeQueryItem("1");
       
  2376     QCOMPARE(url.allQueryItemValues("1").size(), 2);
       
  2377     QCOMPARE(url.queryItemValue("1").toLatin1().constData(), "z");
       
  2378 
       
  2379     url.removeAllQueryItems("1");
       
  2380     QVERIFY(!url.hasQueryItem("1"));
       
  2381 
       
  2382     QCOMPARE(url.queryItemValue("4").toLatin1().constData(), "a b");
       
  2383     QCOMPARE(url.queryItemValue("5").toLatin1().constData(), "&");
       
  2384     QCOMPARE(url.queryItemValue("tex").toLatin1().constData(), "a + b = c");
       
  2385     QCOMPARE(url.queryItemValue("foo bar").toLatin1().constData(), "hello world");
       
  2386     url.setUrl("http://www.google.com/search?q=a+b");
       
  2387     QCOMPARE(url.queryItemValue("q"), QString("a+b"));
       
  2388     url.setUrl("http://www.google.com/search?q=a=b"); // invalid, but should be tolerated
       
  2389     QCOMPARE(url.queryItemValue("q"), QString("a=b"));
       
  2390 }
       
  2391 
       
  2392 void tst_QUrl::hasQuery_data()
       
  2393 {
       
  2394     QTest::addColumn<QString>("url");
       
  2395     QTest::addColumn<bool>("trueFalse");
       
  2396 
       
  2397     QTest::newRow("no query items") << "http://www.foo.bar" << false;
       
  2398 
       
  2399     QTest::newRow("empty query") << "http://www.foo.bar?" << true;
       
  2400     QTest::newRow("empty query 2") << "http://www.foo.bar/?" << true;
       
  2401 
       
  2402     QTest::newRow("query") << "http://www.foo.bar?query" << true;
       
  2403     QTest::newRow("query=") << "http://www.foo.bar?query=" << true;
       
  2404     QTest::newRow("query=value") << "http://www.foo.bar?query=value" << true;
       
  2405 
       
  2406     QTest::newRow("%3f") << "http://www.foo.bar/file%3f" << false;
       
  2407     QTest::newRow("%3f-query") << "http://www.foo.bar/file%3fquery" << false;
       
  2408     QTest::newRow("%3f-query=value") << "http://www.foo.bar/file%3fquery=value" << false;
       
  2409 }
       
  2410 
       
  2411 void tst_QUrl::hasQuery()
       
  2412 {
       
  2413     QFETCH(QString, url);
       
  2414     QFETCH(bool, trueFalse);
       
  2415 
       
  2416     QUrl qurl(url);
       
  2417     QCOMPARE(qurl.hasQuery(), trueFalse);
       
  2418     QCOMPARE(qurl.encodedQuery().isNull(), !trueFalse);
       
  2419 }
       
  2420 
       
  2421 void tst_QUrl::hasQueryItem_data()
       
  2422 {
       
  2423     QTest::addColumn<QString>("url");
       
  2424     QTest::addColumn<QString>("item");
       
  2425     QTest::addColumn<bool>("trueFalse");
       
  2426 
       
  2427     QTest::newRow("no query items") << "http://www.foo.bar" << "baz" << false;
       
  2428     QTest::newRow("query item: hello") << "http://www.foo.bar?hello=world" << "hello" << true;
       
  2429     QTest::newRow("no query item: world") << "http://www.foo.bar?hello=world" << "world" << false;
       
  2430     QTest::newRow("query item: qt") << "http://www.foo.bar?hello=world&qt=rocks" << "qt" << true;
       
  2431 }
       
  2432 
       
  2433 void tst_QUrl::hasQueryItem()
       
  2434 {
       
  2435     QFETCH(QString, url);
       
  2436     QFETCH(QString, item);
       
  2437     QFETCH(bool, trueFalse);
       
  2438 
       
  2439     QCOMPARE(QUrl(url).hasQueryItem(item), trueFalse);
       
  2440 }
       
  2441 
       
  2442 void tst_QUrl::nameprep()
       
  2443 {
       
  2444     QUrl url(QString::fromUtf8("http://www.fu""\xc3""\x9f""ball.de/"));
       
  2445     QCOMPARE(url.toString(), QString::fromLatin1("http://www.fussball.de/"));
       
  2446 }
       
  2447 
       
  2448 void tst_QUrl::isValid()
       
  2449 {
       
  2450     {
       
  2451         QUrl url(QString("A=B"));
       
  2452         QVERIFY(url.isValid());
       
  2453         QCOMPARE(url.path(), QString("A=B"));
       
  2454     }
       
  2455     {
       
  2456         QUrl url = QUrl::fromEncoded("http://strange<username>@ok-hostname/", QUrl::StrictMode);
       
  2457         QVERIFY(!url.isValid());
       
  2458         // < and > are not allowed in userinfo in strict mode
       
  2459     }
       
  2460     {
       
  2461         QUrl url = QUrl::fromEncoded("http://strange<username>@ok-hostname/");
       
  2462         QVERIFY(url.isValid());
       
  2463         // < and > are allowed in tolerant mode
       
  2464     }
       
  2465     {
       
  2466         QUrl url = QUrl::fromEncoded("http://strange;hostname/here");
       
  2467         QVERIFY(!url.isValid());
       
  2468         QCOMPARE(url.path(), QString("/here"));
       
  2469     }
       
  2470 }
       
  2471 
       
  2472 void tst_QUrl::schemeValidator_data()
       
  2473 {
       
  2474     QTest::addColumn<QByteArray>("encodedUrl");
       
  2475     QTest::addColumn<bool>("result");
       
  2476     QTest::addColumn<QString>("toString");
       
  2477 
       
  2478     QTest::newRow("empty") << QByteArray() << false << QString();
       
  2479 
       
  2480     // ftp
       
  2481     QTest::newRow("ftp:") << QByteArray("ftp:") << true << QString("ftp:");
       
  2482     QTest::newRow("ftp://ftp.qt.nokia.com")
       
  2483         << QByteArray("ftp://ftp.qt.nokia.com")
       
  2484         << true << QString("ftp://ftp.qt.nokia.com");
       
  2485     QTest::newRow("ftp://ftp.qt.nokia.com/")
       
  2486         << QByteArray("ftp://ftp.qt.nokia.com/")
       
  2487         << true << QString("ftp://ftp.qt.nokia.com/");
       
  2488     QTest::newRow("ftp:/index.html")
       
  2489         << QByteArray("ftp:/index.html")
       
  2490         << false << QString();
       
  2491 
       
  2492     // mailto
       
  2493     QTest::newRow("mailto:") << QByteArray("mailto:") << true << QString("mailto:");
       
  2494     QTest::newRow("mailto://smtp.trolltech.com/ole@bull.name")
       
  2495         << QByteArray("mailto://smtp.trolltech.com/ole@bull.name") << false << QString();
       
  2496     QTest::newRow("mailto:") << QByteArray("mailto:") << true << QString("mailto:");
       
  2497     QTest::newRow("mailto:ole@bull.name")
       
  2498         << QByteArray("mailto:ole@bull.name") << true << QString("mailto:ole@bull.name");
       
  2499 
       
  2500     // file
       
  2501     QTest::newRow("file:") << QByteArray("file:/etc/passwd") << true << QString("file:///etc/passwd");
       
  2502 }
       
  2503 
       
  2504 void tst_QUrl::schemeValidator()
       
  2505 {
       
  2506     QFETCH(QByteArray, encodedUrl);
       
  2507     QFETCH(bool, result);
       
  2508     QFETCH(QString, toString);
       
  2509 
       
  2510     QUrl url = QUrl::fromEncoded(encodedUrl);
       
  2511     QCOMPARE(url.isValid(), result);
       
  2512 }
       
  2513 
       
  2514 void tst_QUrl::invalidSchemeValidator()
       
  2515 {
       
  2516     // test that if scheme does not start with an ALPHA, QUrl::isValid() returns false
       
  2517     {
       
  2518         QUrl url("1http://qt.nokia.com", QUrl::StrictMode);
       
  2519         QCOMPARE(url.isValid(), false);
       
  2520     }
       
  2521     {
       
  2522         QUrl url("http://qt.nokia.com");
       
  2523         url.setScheme("111http://qt.nokia.com");
       
  2524         QCOMPARE(url.isValid(), false);
       
  2525     }
       
  2526     {
       
  2527         QUrl url = QUrl::fromEncoded("1http://qt.nokia.com", QUrl::StrictMode);
       
  2528         QCOMPARE(url.isValid(), false);
       
  2529     }
       
  2530 
       
  2531     // non-ALPHA character at other positions in the scheme are ok
       
  2532     {
       
  2533         QUrl url("ht111tp://qt.nokia.com", QUrl::StrictMode);
       
  2534         QVERIFY(url.isValid());
       
  2535     }
       
  2536     {
       
  2537         QUrl url("http://qt.nokia.com");
       
  2538         url.setScheme("ht123tp://qt.nokia.com");
       
  2539         QVERIFY(url.isValid());
       
  2540     }
       
  2541     {
       
  2542         QUrl url = QUrl::fromEncoded("ht321tp://qt.nokia.com", QUrl::StrictMode);
       
  2543         QVERIFY(url.isValid());
       
  2544     }
       
  2545 }
       
  2546 
       
  2547 void tst_QUrl::tolerantParser()
       
  2548 {
       
  2549     {
       
  2550         QUrl url("http://www.example.com/path%20with spaces.html");
       
  2551         QVERIFY(url.isValid());
       
  2552         QCOMPARE(url.path(), QString("/path with spaces.html"));
       
  2553         QCOMPARE(url.toEncoded(), QByteArray("http://www.example.com/path%20with%20spaces.html"));
       
  2554         url.setUrl("http://www.example.com/path%20with spaces.html", QUrl::StrictMode);
       
  2555         QVERIFY(url.isValid());
       
  2556         QCOMPARE(url.toEncoded(), QByteArray("http://www.example.com/path%2520with%20spaces.html"));
       
  2557     }
       
  2558     {
       
  2559         QUrl url = QUrl::fromEncoded("http://www.example.com/path%20with spaces.html");
       
  2560         QVERIFY(url.isValid());
       
  2561         QCOMPARE(url.path(), QString("/path with spaces.html"));
       
  2562         url.setEncodedUrl("http://www.example.com/path%20with spaces.html", QUrl::StrictMode);
       
  2563         QVERIFY(!url.isValid());
       
  2564     }
       
  2565 
       
  2566     {
       
  2567         QUrl url15581("http://alain.knaff.linux.lu/bug-reports/kde/percentage%in%url.htm>");
       
  2568         QVERIFY(url15581.isValid());
       
  2569         QCOMPARE(url15581.toEncoded().constData(), "http://alain.knaff.linux.lu/bug-reports/kde/percentage%25in%25url.htm%3E");
       
  2570     }
       
  2571 
       
  2572     {
       
  2573         QUrl webkit22616 =
       
  2574             QUrl::fromEncoded("http://example.com/testya.php?browser-info=s:1400x1050x24:f:9.0%20r152:t:%u0442%u0435%u0441%u0442");
       
  2575         QVERIFY(webkit22616.isValid());
       
  2576         QCOMPARE(webkit22616.toEncoded().constData(),
       
  2577                  "http://example.com/testya.php?browser-info=s:1400x1050x24:f:9.0%20r152:t:%25u0442%25u0435%25u0441%25u0442");
       
  2578     }
       
  2579 
       
  2580     {
       
  2581         QUrl url;
       
  2582         url.setUrl("http://foo.bar/[image][1].jpg");
       
  2583         QVERIFY(url.isValid());
       
  2584         QCOMPARE(url.toEncoded(), QByteArray("http://foo.bar/%5Bimage%5D%5B1%5D.jpg"));
       
  2585 
       
  2586         url.setUrl("[].jpg");
       
  2587         QCOMPARE(url.toEncoded(), QByteArray("%5B%5D.jpg"));
       
  2588 
       
  2589         url.setUrl("/some/[path]/[]");
       
  2590         QCOMPARE(url.toEncoded(), QByteArray("/some/%5Bpath%5D/%5B%5D"));
       
  2591 
       
  2592         url.setUrl("//[::56:56:56:56:56:56:56]");
       
  2593         QCOMPARE(url.toEncoded(), QByteArray("//[::56:56:56:56:56:56:56]"));
       
  2594 
       
  2595         url.setUrl("//[::56:56:56:56:56:56:56]#[]");
       
  2596         QCOMPARE(url.toEncoded(), QByteArray("//[::56:56:56:56:56:56:56]#%5B%5D"));
       
  2597 
       
  2598         url.setUrl("//[::56:56:56:56:56:56:56]?[]");
       
  2599         QCOMPARE(url.toEncoded(), QByteArray("//[::56:56:56:56:56:56:56]?%5B%5D"));
       
  2600 
       
  2601         url.setUrl("%hello.com/f%");
       
  2602         QCOMPARE(url.toEncoded(), QByteArray("%25hello.com/f%25"));
       
  2603 
       
  2604         url.setEncodedUrl("http://www.host.com/foo.php?P0=[2006-3-8]");
       
  2605         QVERIFY(url.isValid());
       
  2606 
       
  2607         url.setEncodedUrl("http://foo.bar/[image][1].jpg");
       
  2608         QVERIFY(url.isValid());
       
  2609         QCOMPARE(url.toEncoded(), QByteArray("http://foo.bar/%5Bimage%5D%5B1%5D.jpg"));
       
  2610 
       
  2611         url.setEncodedUrl("[].jpg");
       
  2612         QCOMPARE(url.toEncoded(), QByteArray("%5B%5D.jpg"));
       
  2613 
       
  2614         url.setEncodedUrl("/some/[path]/[]");
       
  2615         QCOMPARE(url.toEncoded(), QByteArray("/some/%5Bpath%5D/%5B%5D"));
       
  2616 
       
  2617         url.setEncodedUrl("//[::56:56:56:56:56:56:56]");
       
  2618         QCOMPARE(url.toEncoded(), QByteArray("//[::56:56:56:56:56:56:56]"));
       
  2619 
       
  2620         url.setEncodedUrl("//[::56:56:56:56:56:56:56]#[]");
       
  2621         QCOMPARE(url.toEncoded(), QByteArray("//[::56:56:56:56:56:56:56]#%5B%5D"));
       
  2622 
       
  2623         url.setEncodedUrl("//[::56:56:56:56:56:56:56]?[]");
       
  2624         QCOMPARE(url.toEncoded(), QByteArray("//[::56:56:56:56:56:56:56]?%5B%5D"));
       
  2625 
       
  2626         url.setEncodedUrl("data:text/css,div%20{%20border-right:%20solid;%20}");
       
  2627         QCOMPARE(url.toEncoded(), QByteArray("data:text/css,div%20%7B%20border-right:%20solid;%20%7D"));
       
  2628     }
       
  2629 
       
  2630     {
       
  2631         // task 243557
       
  2632         QByteArray tsdgeos("http://google.com/c?c=Translation+%C2%BB+trunk|");
       
  2633         QUrl tsdgeosQUrl;
       
  2634         tsdgeosQUrl.setEncodedUrl(tsdgeos, QUrl::TolerantMode);
       
  2635         QVERIFY(tsdgeosQUrl.isValid()); // failed in Qt-4.4, works in Qt-4.5
       
  2636         QByteArray tsdgeosExpected("http://google.com/c?c=Translation+%C2%BB+trunk%7C");
       
  2637         //QCOMPARE(tsdgeosQUrl.toEncoded(), tsdgeosExpected); // unusable output from qtestlib...
       
  2638         QCOMPARE(QString(tsdgeosQUrl.toEncoded()), QString(tsdgeosExpected));
       
  2639     }
       
  2640 
       
  2641     {
       
  2642         QUrl url;
       
  2643         url.setUrl("http://strange<username>@hostname/", QUrl::TolerantMode);
       
  2644         QVERIFY(url.isValid());
       
  2645         QCOMPARE(QString(url.toEncoded()), QString("http://strange%3Cusername%3E@hostname/"));
       
  2646     }
       
  2647 }
       
  2648 
       
  2649 void tst_QUrl::correctEncodedMistakes_data()
       
  2650 {
       
  2651     QTest::addColumn<QByteArray>("encodedUrl");
       
  2652     QTest::addColumn<bool>("result");
       
  2653     QTest::addColumn<QString>("toString");
       
  2654     QTest::addColumn<QByteArray>("toEncoded");
       
  2655 
       
  2656     QTest::newRow("%") << QByteArray("%") << true << QString("%") << QByteArray("%25");
       
  2657     QTest::newRow("3%") << QByteArray("3%") << true << QString("3%") << QByteArray("3%25");
       
  2658     QTest::newRow("13%") << QByteArray("13%") << true << QString("13%") << QByteArray("13%25");
       
  2659     QTest::newRow("13%!") << QByteArray("13%!") << true << QString("13%!") << QByteArray("13%25!");
       
  2660     QTest::newRow("13%!!") << QByteArray("13%!!") << true << QString("13%!!") << QByteArray("13%25!!");
       
  2661     QTest::newRow("13%a") << QByteArray("13%a") << true << QString("13%a") << QByteArray("13%25a");
       
  2662     QTest::newRow("13%az") << QByteArray("13%az") << true << QString("13%az") << QByteArray("13%25az");
       
  2663     QTest::newRow("13%25") << QByteArray("13%25") << true << QString("13%") << QByteArray("13%25");
       
  2664 }
       
  2665 
       
  2666 void tst_QUrl::correctEncodedMistakes()
       
  2667 {
       
  2668     QFETCH(QByteArray, encodedUrl);
       
  2669     QFETCH(bool, result);
       
  2670     QFETCH(QString, toString);
       
  2671     QFETCH(QByteArray, toEncoded);
       
  2672 
       
  2673     QUrl url = QUrl::fromEncoded(encodedUrl);
       
  2674     QCOMPARE(url.isValid(), result);
       
  2675     if (url.isValid()) {
       
  2676         QCOMPARE(url.toString(), toString);
       
  2677         QCOMPARE(url.toEncoded(), toEncoded);
       
  2678     }
       
  2679 }
       
  2680 
       
  2681 void tst_QUrl::correctDecodedMistakes_data()
       
  2682 {
       
  2683     QTest::addColumn<QString>("decodedUrl");
       
  2684     QTest::addColumn<bool>("result");
       
  2685     QTest::addColumn<QString>("toString");
       
  2686     QTest::addColumn<QByteArray>("toEncoded");
       
  2687 
       
  2688     QTest::newRow("%") << QString("%") << true << QString("%") << QByteArray("%25");
       
  2689     QTest::newRow("3%") << QString("3%") << true << QString("3%") << QByteArray("3%25");
       
  2690     QTest::newRow("13%") << QString("13%") << true << QString("13%") << QByteArray("13%25");
       
  2691     QTest::newRow("13%!") << QString("13%!") << true << QString("13%!") << QByteArray("13%25!");
       
  2692     QTest::newRow("13%!!") << QString("13%!!") << true << QString("13%!!") << QByteArray("13%25!!");
       
  2693     QTest::newRow("13%a") << QString("13%a") << true << QString("13%a") << QByteArray("13%25a");
       
  2694     QTest::newRow("13%az") << QString("13%az") << true << QString("13%az") << QByteArray("13%25az");
       
  2695     QTest::newRow("13%25") << QString("13%25") << true << QString("13%25") << QByteArray("13%2525");
       
  2696 }
       
  2697 
       
  2698 void tst_QUrl::correctDecodedMistakes()
       
  2699 {
       
  2700     QFETCH(QString, decodedUrl);
       
  2701     QFETCH(bool, result);
       
  2702     QFETCH(QString, toString);
       
  2703     QFETCH(QByteArray, toEncoded);
       
  2704 
       
  2705     QUrl url(decodedUrl);
       
  2706     QCOMPARE(url.isValid(), result);
       
  2707     if (url.isValid()) {
       
  2708         QCOMPARE(url.toString(), toString);
       
  2709         QCOMPARE(url.toEncoded(), toEncoded);
       
  2710     }
       
  2711 }
       
  2712 
       
  2713 void tst_QUrl::idna_testsuite_data()
       
  2714 {
       
  2715     QTest::addColumn<int>("numchars");
       
  2716     QTest::addColumn<ushortarray>("unicode");
       
  2717     QTest::addColumn<QByteArray>("punycode");
       
  2718     QTest::addColumn<int>("allowunassigned");
       
  2719     QTest::addColumn<int>("usestd3asciirules");
       
  2720     QTest::addColumn<int>("toasciirc");
       
  2721     QTest::addColumn<int>("tounicoderc");
       
  2722 
       
  2723     unsigned short d1[] = { 0x0644, 0x064A, 0x0647, 0x0645, 0x0627, 0x0628, 0x062A, 0x0643,
       
  2724                             0x0644, 0x0645, 0x0648, 0x0634, 0x0639, 0x0631, 0x0628, 0x064A,
       
  2725                             0x061F };
       
  2726     QTest::newRow("Arabic (Egyptian)") << 17 << ushortarray(d1)
       
  2727                                     << QByteArray(IDNA_ACE_PREFIX "egbpdaj6bu4bxfgehfvwxn")
       
  2728                                     << 0 << 0 << IDNA_SUCCESS << IDNA_SUCCESS;
       
  2729 
       
  2730     unsigned short d2[] = { 0x4ED6, 0x4EEC, 0x4E3A, 0x4EC0, 0x4E48, 0x4E0D, 0x8BF4, 0x4E2D,
       
  2731                             0x6587 };
       
  2732     QTest::newRow("Chinese (simplified)") << 9 << ushortarray(d2)
       
  2733                                        << QByteArray(IDNA_ACE_PREFIX "ihqwcrb4cv8a8dqg056pqjye")
       
  2734                                        << 0 << 0 << IDNA_SUCCESS << IDNA_SUCCESS;
       
  2735 
       
  2736     unsigned short d3[] = { 0x4ED6, 0x5011, 0x7232, 0x4EC0, 0x9EBD, 0x4E0D, 0x8AAA, 0x4E2D,
       
  2737                             0x6587 };
       
  2738     QTest::newRow("Chinese (traditional)") << 9 << ushortarray(d3)
       
  2739                                         << QByteArray(IDNA_ACE_PREFIX "ihqwctvzc91f659drss3x8bo0yb")
       
  2740                                         << 0 << 0 << IDNA_SUCCESS << IDNA_SUCCESS;
       
  2741 
       
  2742     unsigned short d4[] = { 0x0050, 0x0072, 0x006F, 0x010D, 0x0070, 0x0072, 0x006F, 0x0073,
       
  2743                             0x0074, 0x011B, 0x006E, 0x0065, 0x006D, 0x006C, 0x0075, 0x0076,
       
  2744                             0x00ED, 0x010D, 0x0065, 0x0073, 0x006B, 0x0079 };
       
  2745     QTest::newRow("Czech") << 22 << ushortarray(d4)
       
  2746                         << QByteArray(IDNA_ACE_PREFIX "Proprostnemluvesky-uyb24dma41a")
       
  2747                         << 0 << 0 << IDNA_SUCCESS << IDNA_SUCCESS;
       
  2748 
       
  2749     unsigned short d5[] = { 0x05DC, 0x05DE, 0x05D4, 0x05D4, 0x05DD, 0x05E4, 0x05E9, 0x05D5,
       
  2750                             0x05D8, 0x05DC, 0x05D0, 0x05DE, 0x05D3, 0x05D1, 0x05E8, 0x05D9,
       
  2751                             0x05DD, 0x05E2, 0x05D1, 0x05E8, 0x05D9, 0x05EA };
       
  2752     QTest::newRow("Hebrew") << 22 << ushortarray(d5)
       
  2753                          << QByteArray(IDNA_ACE_PREFIX "4dbcagdahymbxekheh6e0a7fei0b")
       
  2754                          << 0 << 0 << IDNA_SUCCESS << IDNA_SUCCESS;
       
  2755 
       
  2756     unsigned short d6[] = { 0x092F, 0x0939, 0x0932, 0x094B, 0x0917, 0x0939, 0x093F, 0x0928,
       
  2757                             0x094D, 0x0926, 0x0940, 0x0915, 0x094D, 0x092F, 0x094B, 0x0902,
       
  2758                             0x0928, 0x0939, 0x0940, 0x0902, 0x092C, 0x094B, 0x0932, 0x0938,
       
  2759                             0x0915, 0x0924, 0x0947, 0x0939, 0x0948, 0x0902 };
       
  2760     QTest::newRow("Hindi (Devanagari)") << 30 << ushortarray(d6)
       
  2761                                      << QByteArray(IDNA_ACE_PREFIX "i1baa7eci9glrd9b2ae1bj0hfcgg6iyaf8o0a1dig0cd")
       
  2762                                      << 0 << 0 << IDNA_SUCCESS;
       
  2763 
       
  2764     unsigned short d7[] = { 0x306A, 0x305C, 0x307F, 0x3093, 0x306A, 0x65E5, 0x672C, 0x8A9E,
       
  2765                             0x3092, 0x8A71, 0x3057, 0x3066, 0x304F, 0x308C, 0x306A, 0x3044,
       
  2766                             0x306E, 0x304B };
       
  2767     QTest::newRow("Japanese (kanji and hiragana)") << 18 << ushortarray(d7)
       
  2768                                                 << QByteArray(IDNA_ACE_PREFIX "n8jok5ay5dzabd5bym9f0cm5685rrjetr6pdxa")
       
  2769                                                 << 0 << 0 << IDNA_SUCCESS;
       
  2770 
       
  2771     unsigned short d8[] = { 0x043F, 0x043E, 0x0447, 0x0435, 0x043C, 0x0443, 0x0436, 0x0435,
       
  2772                             0x043E, 0x043D, 0x0438, 0x043D, 0x0435, 0x0433, 0x043E, 0x0432,
       
  2773                             0x043E, 0x0440, 0x044F, 0x0442, 0x043F, 0x043E, 0x0440, 0x0443,
       
  2774                             0x0441, 0x0441, 0x043A, 0x0438 };
       
  2775     QTest::newRow("Russian (Cyrillic)") << 28 << ushortarray(d8)
       
  2776                                      << QByteArray(IDNA_ACE_PREFIX "b1abfaaepdrnnbgefbadotcwatmq2g4l")
       
  2777                                      << 0 << 0 << IDNA_SUCCESS << IDNA_SUCCESS;
       
  2778 
       
  2779     unsigned short d9[] = { 0x0050, 0x006F, 0x0072, 0x0071, 0x0075, 0x00E9, 0x006E, 0x006F,
       
  2780                             0x0070, 0x0075, 0x0065, 0x0064, 0x0065, 0x006E, 0x0073, 0x0069,
       
  2781                             0x006D, 0x0070, 0x006C, 0x0065, 0x006D, 0x0065, 0x006E, 0x0074,
       
  2782                             0x0065, 0x0068, 0x0061, 0x0062, 0x006C, 0x0061, 0x0072, 0x0065,
       
  2783                             0x006E, 0x0045, 0x0073, 0x0070, 0x0061, 0x00F1, 0x006F, 0x006C };
       
  2784     QTest::newRow("Spanish") << 40 << ushortarray(d9)
       
  2785                           << QByteArray(IDNA_ACE_PREFIX "PorqunopuedensimplementehablarenEspaol-fmd56a")
       
  2786                           << 0 << 0 << IDNA_SUCCESS;
       
  2787 
       
  2788     unsigned short d10[] = { 0x0054, 0x1EA1, 0x0069, 0x0073, 0x0061, 0x006F, 0x0068, 0x1ECD,
       
  2789                              0x006B, 0x0068, 0x00F4, 0x006E, 0x0067, 0x0074, 0x0068, 0x1EC3,
       
  2790                              0x0063, 0x0068, 0x1EC9, 0x006E, 0x00F3, 0x0069, 0x0074, 0x0069,
       
  2791                              0x1EBF, 0x006E, 0x0067, 0x0056, 0x0069, 0x1EC7, 0x0074 };
       
  2792     QTest::newRow("Vietnamese") << 31 << ushortarray(d10)
       
  2793                              << QByteArray(IDNA_ACE_PREFIX "TisaohkhngthchnitingVit-kjcr8268qyxafd2f1b9g")
       
  2794                              << 0 << 0 << IDNA_SUCCESS;
       
  2795 
       
  2796     unsigned short d11[] = { 0x0033, 0x5E74, 0x0042, 0x7D44, 0x91D1, 0x516B, 0x5148, 0x751F };
       
  2797     QTest::newRow("Japanese") << 8 << ushortarray(d11)
       
  2798                            << QByteArray(IDNA_ACE_PREFIX "3B-ww4c5e180e575a65lsy2b")
       
  2799                            << 0 << 0 << IDNA_SUCCESS << IDNA_SUCCESS;
       
  2800 
       
  2801     unsigned short d12[] = { 0x5B89, 0x5BA4, 0x5948, 0x7F8E, 0x6075, 0x002D, 0x0077, 0x0069,
       
  2802                              0x0074, 0x0068, 0x002D, 0x0053, 0x0055, 0x0050, 0x0045, 0x0052,
       
  2803                              0x002D, 0x004D, 0x004F, 0x004E, 0x004B, 0x0045, 0x0059, 0x0053 };
       
  2804     QTest::newRow("Japanese2") << 24 << ushortarray(d12)
       
  2805                             << QByteArray(IDNA_ACE_PREFIX "-with-SUPER-MONKEYS-pc58ag80a8qai00g7n9n")
       
  2806                             << 0 << 0 << IDNA_SUCCESS;
       
  2807 
       
  2808     unsigned short d13[] = { 0x0048, 0x0065, 0x006C, 0x006C, 0x006F, 0x002D, 0x0041, 0x006E,
       
  2809                              0x006F, 0x0074, 0x0068, 0x0065, 0x0072, 0x002D, 0x0057, 0x0061,
       
  2810                              0x0079, 0x002D, 0x305D, 0x308C, 0x305E, 0x308C, 0x306E, 0x5834,
       
  2811                              0x6240 };
       
  2812     QTest::newRow("Japanese3") << 25 << ushortarray(d13)
       
  2813                             << QByteArray(IDNA_ACE_PREFIX "Hello-Another-Way--fc4qua05auwb3674vfr0b")
       
  2814                             << 0 << 0 << IDNA_SUCCESS;
       
  2815 
       
  2816     unsigned short d14[] = { 0x3072, 0x3068, 0x3064, 0x5C4B, 0x6839, 0x306E, 0x4E0B, 0x0032 };
       
  2817     QTest::newRow("Japanese4") << 8 << ushortarray(d14)
       
  2818                             << QByteArray(IDNA_ACE_PREFIX "2-u9tlzr9756bt3uc0v")
       
  2819                             << 0 << 0 << IDNA_SUCCESS << IDNA_SUCCESS;
       
  2820 
       
  2821     unsigned short d15[] = { 0x004D, 0x0061, 0x006A, 0x0069, 0x3067, 0x004B, 0x006F, 0x0069,
       
  2822                              0x3059, 0x308B, 0x0035, 0x79D2, 0x524D };
       
  2823     QTest::newRow("Japanese5") << 13 << ushortarray(d15)
       
  2824                             << QByteArray(IDNA_ACE_PREFIX "MajiKoi5-783gue6qz075azm5e")
       
  2825                             << 0 << 0 << IDNA_SUCCESS << IDNA_SUCCESS;
       
  2826 
       
  2827     unsigned short d16[] = { 0x30D1, 0x30D5, 0x30A3, 0x30FC, 0x0064, 0x0065, 0x30EB, 0x30F3, 0x30D0 };
       
  2828     QTest::newRow("Japanese6") << 9 << ushortarray(d16)
       
  2829                             << QByteArray(IDNA_ACE_PREFIX "de-jg4avhby1noc0d")
       
  2830                             << 0 << 0 << IDNA_SUCCESS << IDNA_SUCCESS;
       
  2831 
       
  2832     unsigned short d17[] = { 0x305D, 0x306E, 0x30B9, 0x30D4, 0x30FC, 0x30C9, 0x3067 };
       
  2833     QTest::newRow("Japanese7") << 7 << ushortarray(d17)
       
  2834                             << QByteArray(IDNA_ACE_PREFIX "d9juau41awczczp")
       
  2835                             << 0 << 0 << IDNA_SUCCESS << IDNA_SUCCESS;
       
  2836 
       
  2837     unsigned short d18[] = { 0x03b5, 0x03bb, 0x03bb, 0x03b7, 0x03bd, 0x03b9, 0x03ba, 0x03ac };
       
  2838     QTest::newRow("Greek") << 8 << ushortarray(d18)
       
  2839                         << QByteArray(IDNA_ACE_PREFIX "hxargifdar")
       
  2840                         << 0 << 0 << IDNA_SUCCESS << IDNA_SUCCESS;
       
  2841 
       
  2842     unsigned short d19[] = { 0x0062, 0x006f, 0x006e, 0x0121, 0x0075, 0x0073, 0x0061, 0x0127,
       
  2843                              0x0127, 0x0061 };
       
  2844     QTest::newRow("Maltese (Malti)") << 10 << ushortarray(d19)
       
  2845                                   << QByteArray(IDNA_ACE_PREFIX "bonusaa-5bb1da")
       
  2846                                   << 0 << 0 << IDNA_SUCCESS << IDNA_SUCCESS;
       
  2847 
       
  2848     unsigned short d20[] = {0x043f, 0x043e, 0x0447, 0x0435, 0x043c, 0x0443, 0x0436, 0x0435,
       
  2849                             0x043e, 0x043d, 0x0438, 0x043d, 0x0435, 0x0433, 0x043e, 0x0432,
       
  2850                             0x043e, 0x0440, 0x044f, 0x0442, 0x043f, 0x043e, 0x0440, 0x0443,
       
  2851                             0x0441, 0x0441, 0x043a, 0x0438 };
       
  2852     QTest::newRow("Russian (Cyrillic)") << 28 << ushortarray(d20)
       
  2853                                      << QByteArray(IDNA_ACE_PREFIX "b1abfaaepdrnnbgefbadotcwatmq2g4l")
       
  2854                                      << 0 << 0 << IDNA_SUCCESS << IDNA_SUCCESS;
       
  2855 }
       
  2856 
       
  2857 void tst_QUrl::idna_testsuite()
       
  2858 {
       
  2859     QFETCH(int, numchars);
       
  2860     QFETCH(ushortarray, unicode);
       
  2861     QFETCH(QByteArray, punycode);
       
  2862 
       
  2863     QString s = QString::fromUtf16(unicode.points, numchars);
       
  2864     QCOMPARE(punycode, QUrl::toPunycode(s));
       
  2865 }
       
  2866 
       
  2867 void tst_QUrl::nameprep_testsuite_data()
       
  2868 {
       
  2869     QTest::addColumn<QString>("in");
       
  2870     QTest::addColumn<QString>("out");
       
  2871     QTest::addColumn<QString>("profile");
       
  2872     QTest::addColumn<int>("flags");
       
  2873     QTest::addColumn<int>("rc");
       
  2874 
       
  2875     QTest::newRow("Map to nothing")
       
  2876         << QString::fromUtf8("foo\xC2\xAD\xCD\x8F\xE1\xA0\x86\xE1\xA0\x8B"
       
  2877                              "bar""\xE2\x80\x8B\xE2\x81\xA0""baz\xEF\xB8\x80\xEF\xB8\x88"
       
  2878                              "\xEF\xB8\x8F\xEF\xBB\xBF")
       
  2879         << QString::fromUtf8("foobarbaz")
       
  2880         << QString() << 0 << 0;
       
  2881 
       
  2882     QTest::newRow("Case folding ASCII U+0043 U+0041 U+0046 U+0045")
       
  2883         << QString::fromUtf8("CAFE")
       
  2884         << QString::fromUtf8("cafe")
       
  2885         << QString() << 0 << 0;
       
  2886 
       
  2887     QTest::newRow("Case folding 8bit U+00DF (german sharp s)")
       
  2888 //        << QString::fromUtf8("\xC3\xDF") ### typo in the original testsuite
       
  2889         << QString::fromUtf8("\xC3\x9F")
       
  2890         << QString("ss")
       
  2891         << QString() << 0 << 0;
       
  2892 
       
  2893     QTest::newRow("Case folding U+0130 (turkish capital I with dot)")
       
  2894         << QString::fromUtf8("\xC4\xB0")
       
  2895         << QString::fromUtf8("i\xcc\x87")
       
  2896         << QString() << 0 << 0;
       
  2897 
       
  2898     QTest::newRow("Case folding multibyte U+0143 U+037A")
       
  2899         << QString::fromUtf8("\xC5\x83\xCD\xBA")
       
  2900         << QString::fromUtf8("\xC5\x84 \xCE\xB9")
       
  2901         << QString() << 0 << 0;
       
  2902 
       
  2903     QTest::newRow("Case folding U+2121 U+33C6 U+1D7BB")
       
  2904         << QString::fromUtf8("\xE2\x84\xA1\xE3\x8F\x86\xF0\x9D\x9E\xBB")
       
  2905         << QString::fromUtf8("telc\xE2\x88\x95""kg\xCF\x83")
       
  2906         << QString() << 0 << 0;
       
  2907 
       
  2908     QTest::newRow("Normalization of U+006a U+030c U+00A0 U+00AA")
       
  2909         << QString::fromUtf8("\x6A\xCC\x8C\xC2\xA0\xC2\xAA")
       
  2910         << QString::fromUtf8("\xC7\xB0 a")
       
  2911         << QString() << 0 << 0;
       
  2912 
       
  2913     QTest::newRow("Case folding U+1FB7 and normalization")
       
  2914         << QString::fromUtf8("\xE1\xBE\xB7")
       
  2915         << QString::fromUtf8("\xE1\xBE\xB6\xCE\xB9")
       
  2916         << QString() << 0 << 0;
       
  2917 
       
  2918     QTest::newRow("Self-reverting case folding U+01F0 and normalization")
       
  2919         << QString::fromUtf8("\xC7\xF0")
       
  2920         << QString::fromUtf8("\xC7\xB0")
       
  2921         << QString() << 0 << 0;
       
  2922 
       
  2923     QTest::newRow("Self-reverting case folding U+0390 and normalization")
       
  2924         << QString::fromUtf8("\xCE\x90")
       
  2925         << QString::fromUtf8("\xCE\x90")
       
  2926         << QString() << 0 << 0;
       
  2927 
       
  2928     QTest::newRow("Self-reverting case folding U+03B0 and normalization")
       
  2929         << QString::fromUtf8("\xCE\xB0")
       
  2930         << QString::fromUtf8("\xCE\xB0")
       
  2931         << QString() << 0 << 0;
       
  2932 
       
  2933     QTest::newRow("Self-reverting case folding U+1E96 and normalization")
       
  2934         << QString::fromUtf8("\xE1\xBA\x96")
       
  2935         << QString::fromUtf8("\xE1\xBA\x96")
       
  2936         << QString() << 0 << 0;
       
  2937 
       
  2938     QTest::newRow("Self-reverting case folding U+1F56 and normalization")
       
  2939         << QString::fromUtf8("\xE1\xBD\x96")
       
  2940         << QString::fromUtf8("\xE1\xBD\x96")
       
  2941         << QString() << 0 << 0;
       
  2942 
       
  2943     QTest::newRow("ASCII space character U+0020")
       
  2944         << QString::fromUtf8("\x20")
       
  2945         << QString::fromUtf8("\x20")
       
  2946         << QString() << 0 << 0;
       
  2947 
       
  2948     QTest::newRow("Non-ASCII 8bit space character U+00A0")
       
  2949         << QString::fromUtf8("\xC2\xA0")
       
  2950         << QString::fromUtf8("\x20")
       
  2951         << QString() << 0 << 0;
       
  2952 
       
  2953     QTest::newRow("Non-ASCII multibyte space character U+1680")
       
  2954         << QString::fromUtf8("\xE1\x9A\x80")
       
  2955         << QString()
       
  2956         << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED;
       
  2957 
       
  2958     QTest::newRow("Non-ASCII multibyte space character U+2000")
       
  2959         << QString::fromUtf8("\xE2\x80\x80")
       
  2960         << QString::fromUtf8("\x20")
       
  2961         << QString() << 0 << 0;
       
  2962 
       
  2963     QTest::newRow("Zero Width Space U+200b")
       
  2964         << QString::fromUtf8("\xE2\x80\x8b")
       
  2965         << QString()
       
  2966         << QString() << 0 << 0;
       
  2967 
       
  2968     QTest::newRow("Non-ASCII multibyte space character U+3000")
       
  2969         << QString::fromUtf8("\xE3\x80\x80")
       
  2970         << QString::fromUtf8("\x20")
       
  2971         << QString() << 0 << 0;
       
  2972 
       
  2973     QTest::newRow("ASCII control characters U+0010 U+007F")
       
  2974         << QString::fromUtf8("\x10\x7F")
       
  2975         << QString::fromUtf8("\x10\x7F")
       
  2976         << QString() << 0 << 0;
       
  2977 
       
  2978     QTest::newRow("Non-ASCII 8bit control character U+0085")
       
  2979         << QString::fromUtf8("\xC2\x85")
       
  2980         << QString()
       
  2981         << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED;
       
  2982 
       
  2983     QTest::newRow("Non-ASCII multibyte control character U+180E")
       
  2984         << QString::fromUtf8("\xE1\xA0\x8E")
       
  2985         << QString()
       
  2986         << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED;
       
  2987 
       
  2988     QTest::newRow("Zero Width No-Break Space U+FEFF")
       
  2989         << QString::fromUtf8("\xEF\xBB\xBF")
       
  2990         << QString()
       
  2991         << QString() << 0 << 0;
       
  2992 
       
  2993     QTest::newRow("Non-ASCII control character U+1D175")
       
  2994         << QString::fromUtf8("\xF0\x9D\x85\xB5")
       
  2995         << QString()
       
  2996         << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED;
       
  2997 
       
  2998     QTest::newRow("Plane 0 private use character U+F123")
       
  2999         << QString::fromUtf8("\xEF\x84\xA3")
       
  3000         << QString()
       
  3001         << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED;
       
  3002 
       
  3003     QTest::newRow("Plane 15 private use character U+F1234")
       
  3004         << QString::fromUtf8("\xF3\xB1\x88\xB4")
       
  3005         << QString()
       
  3006         << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED;
       
  3007 
       
  3008     QTest::newRow("Plane 16 private use character U+10F234")
       
  3009         << QString::fromUtf8("\xF4\x8F\x88\xB4")
       
  3010         << QString()
       
  3011         << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED;
       
  3012 
       
  3013     QTest::newRow("Non-character code point U+8FFFE")
       
  3014         << QString::fromUtf8("\xF2\x8F\xBF\xBE")
       
  3015         << QString()
       
  3016         << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED;
       
  3017 
       
  3018     QTest::newRow("Non-character code point U+10FFFF")
       
  3019         << QString::fromUtf8("\xF4\x8F\xBF\xBF")
       
  3020         << QString()
       
  3021         << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED;
       
  3022 
       
  3023     QTest::newRow("Surrogate code U+DF42")
       
  3024         << QString::fromUtf8("\xED\xBD\x82")
       
  3025         << QString()
       
  3026         << QString("Nameprep") << 0 <<  STRINGPREP_CONTAINS_PROHIBITED;
       
  3027 
       
  3028     QTest::newRow("Non-plain text character U+FFFD")
       
  3029         << QString::fromUtf8("\xEF\xBF\xBD")
       
  3030         << QString()
       
  3031         << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED;
       
  3032 
       
  3033     QTest::newRow("Ideographic description character U+2FF5")
       
  3034         << QString::fromUtf8("\xE2\xBF\xB5")
       
  3035         << QString()
       
  3036         << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED;
       
  3037 
       
  3038     QTest::newRow("Display property character U+0341")
       
  3039         << QString::fromUtf8("\xCD\x81")
       
  3040         << QString::fromUtf8("\xCC\x81")
       
  3041         << QString() << 0 << 0;
       
  3042 
       
  3043     QTest::newRow("Left-to-right mark U+200E")
       
  3044         << QString::fromUtf8("\xE2\x80\x8E")
       
  3045         << QString::fromUtf8("\xCC\x81")
       
  3046         << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED;
       
  3047 
       
  3048     QTest::newRow("Deprecated U+202A")
       
  3049         << QString::fromUtf8("\xE2\x80\xAA")
       
  3050         << QString::fromUtf8("\xCC\x81")
       
  3051         << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED;
       
  3052 
       
  3053     QTest::newRow("Language tagging character U+E0001")
       
  3054         << QString::fromUtf8("\xF3\xA0\x80\x81")
       
  3055         << QString::fromUtf8("\xCC\x81")
       
  3056         << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED;
       
  3057 
       
  3058     QTest::newRow("Language tagging character U+E0042")
       
  3059         << QString::fromUtf8("\xF3\xA0\x81\x82")
       
  3060         << QString()
       
  3061         << QString("Nameprep") << 0 << STRINGPREP_CONTAINS_PROHIBITED;
       
  3062 
       
  3063     QTest::newRow("Bidi: RandALCat character U+05BE and LCat characters")
       
  3064         << QString::fromUtf8("foo\xD6\xBE""bar")
       
  3065         << QString()
       
  3066         << QString("Nameprep") << 0 << STRINGPREP_BIDI_BOTH_L_AND_RAL;
       
  3067 
       
  3068     QTest::newRow("Bidi: RandALCat character U+FD50 and LCat characters")
       
  3069         << QString::fromUtf8("foo\xEF\xB5\x90""bar")
       
  3070         << QString()
       
  3071         << QString("Nameprep") << 0 << STRINGPREP_BIDI_BOTH_L_AND_RAL;
       
  3072 
       
  3073     QTest::newRow("Bidi: RandALCat character U+FB38 and LCat characters")
       
  3074         << QString::fromUtf8("foo\xEF\xB9\xB6""bar")
       
  3075         << QString::fromUtf8("foo \xd9\x8e""bar")
       
  3076         << QString() << 0 << 0;
       
  3077 
       
  3078     QTest::newRow("Bidi: RandALCat without trailing RandALCat U+0627 U+0031")
       
  3079         << QString::fromUtf8("\xD8\xA7\x31")
       
  3080         << QString()
       
  3081         << QString("Nameprep") << 0 << STRINGPREP_BIDI_LEADTRAIL_NOT_RAL;
       
  3082 
       
  3083     QTest::newRow("Bidi: RandALCat character U+0627 U+0031 U+0628")
       
  3084         << QString::fromUtf8("\xD8\xA7\x31\xD8\xA8")
       
  3085         << QString::fromUtf8("\xD8\xA7\x31\xD8\xA8")
       
  3086         << QString() << 0 << 0;
       
  3087 
       
  3088     QTest::newRow("Unassigned code point U+E0002")
       
  3089         << QString::fromUtf8("\xF3\xA0\x80\x82")
       
  3090         << QString()
       
  3091         << QString("Nameprep") << STRINGPREP_NO_UNASSIGNED << STRINGPREP_CONTAINS_UNASSIGNED;
       
  3092 
       
  3093     QTest::newRow("Larger test (shrinking)")
       
  3094         << QString::fromUtf8("X\xC2\xAD\xC3\xDF\xC4\xB0\xE2\x84\xA1\x6a\xcc\x8c\xc2\xa0\xc2"
       
  3095                              "\xaa\xce\xb0\xe2\x80\x80")
       
  3096         << QString::fromUtf8("xssi\xcc\x87""tel\xc7\xb0 a\xce\xb0 ")
       
  3097         << QString("Nameprep") << 0 << 0;
       
  3098 
       
  3099     QTest::newRow("Larger test (expanding)")
       
  3100         << QString::fromUtf8("X\xC3\xDF\xe3\x8c\x96\xC4\xB0\xE2\x84\xA1\xE2\x92\x9F\xE3\x8c\x80")
       
  3101         << QString::fromUtf8("xss\xe3\x82\xad\xe3\x83\xad\xe3\x83\xa1\xe3\x83\xbc\xe3\x83\x88"
       
  3102                              "\xe3\x83\xab""i\xcc\x87""tel\x28""d\x29\xe3\x82\xa2\xe3\x83\x91"
       
  3103                              "\xe3\x83\xbc\xe3\x83\x88")
       
  3104         << QString() << 0 << 0;
       
  3105 }
       
  3106 
       
  3107 #ifdef QT_BUILD_INTERNAL
       
  3108 QT_BEGIN_NAMESPACE
       
  3109 extern void qt_nameprep(QString *source, int from);
       
  3110 extern bool qt_check_std3rules(const QChar *, int);
       
  3111 QT_END_NAMESPACE
       
  3112 #endif
       
  3113 
       
  3114 void tst_QUrl::nameprep_testsuite()
       
  3115 {
       
  3116 #ifdef QT_BUILD_INTERNAL
       
  3117     QFETCH(QString, in);
       
  3118     QFETCH(QString, out);
       
  3119     QFETCH(QString, profile);
       
  3120 
       
  3121     QEXPECT_FAIL("Case folding U+2121 U+33C6 U+1D7BB",
       
  3122                  ">0xffff unicode points are not supported", Continue);
       
  3123     QEXPECT_FAIL("Self-reverting case folding U+01F0 and normalization",
       
  3124                  "Investigate further", Continue);
       
  3125     QEXPECT_FAIL("Left-to-right mark U+200E",
       
  3126                  "Investigate further", Continue);
       
  3127     QEXPECT_FAIL("Deprecated U+202A",
       
  3128                  "Investigate further", Continue);
       
  3129     QEXPECT_FAIL("Language tagging character U+E0001",
       
  3130                  "Investigate further", Continue);
       
  3131     QEXPECT_FAIL("Larger test (shrinking)",
       
  3132                  "Investigate further", Continue);
       
  3133     QEXPECT_FAIL("Larger test (expanding)",
       
  3134                  "Investigate further", Continue);
       
  3135     qt_nameprep(&in, 0);
       
  3136     QCOMPARE(in, out);
       
  3137 #endif
       
  3138 }
       
  3139 
       
  3140 void tst_QUrl::ace_testsuite_data()
       
  3141 {
       
  3142     QTest::addColumn<QString>("in");
       
  3143     QTest::addColumn<QString>("toace");
       
  3144     QTest::addColumn<QString>("fromace");
       
  3145     QTest::addColumn<QString>("unicode");
       
  3146 
       
  3147     QTest::newRow("ascii-lower") << "fluke" << "fluke" << "fluke" << "fluke";
       
  3148     QTest::newRow("ascii-mixed") << "FLuke" << "fluke" << "fluke" << "fluke";
       
  3149     QTest::newRow("ascii-upper") << "FLUKE" << "fluke" << "fluke" << "fluke";
       
  3150 
       
  3151     QTest::newRow("asciifolded") << QString::fromLatin1("stra\337e") << "strasse" << "." << "strasse";
       
  3152     QTest::newRow("asciifolded-dotcom") << QString::fromLatin1("stra\337e.example.com") << "strasse.example.com" << "." << "strasse.example.com";
       
  3153     QTest::newRow("greek-mu") << QString::fromLatin1("\265V")
       
  3154                               <<"xn--v-lmb"
       
  3155                               << "."
       
  3156                               << QString::fromUtf8("\316\274v");
       
  3157 
       
  3158     QTest::newRow("non-ascii-lower") << QString::fromLatin1("alqualond\353")
       
  3159                                      << "xn--alqualond-34a"
       
  3160                                      << "."
       
  3161                                      << QString::fromLatin1("alqualond\353");
       
  3162     QTest::newRow("non-ascii-mixed") << QString::fromLatin1("Alqualond\353")
       
  3163                                      << "xn--alqualond-34a"
       
  3164                                      << "."
       
  3165                                      << QString::fromLatin1("alqualond\353");
       
  3166     QTest::newRow("non-ascii-upper") << QString::fromLatin1("ALQUALOND\313")
       
  3167                                      << "xn--alqualond-34a"
       
  3168                                      << "."
       
  3169                                      << QString::fromLatin1("alqualond\353");
       
  3170 
       
  3171     QTest::newRow("idn-lower") << "xn--alqualond-34a" << "xn--alqualond-34a"
       
  3172                                << QString::fromLatin1("alqualond\353")
       
  3173                                << QString::fromLatin1("alqualond\353");
       
  3174     QTest::newRow("idn-mixed") << "Xn--alqualond-34a" << "xn--alqualond-34a"
       
  3175                                << QString::fromLatin1("alqualond\353")
       
  3176                                << QString::fromLatin1("alqualond\353");
       
  3177     QTest::newRow("idn-mixed2") << "XN--alqualond-34a" << "xn--alqualond-34a"
       
  3178                                 << QString::fromLatin1("alqualond\353")
       
  3179                                 << QString::fromLatin1("alqualond\353");
       
  3180     QTest::newRow("idn-mixed3") << "xn--ALQUALOND-34a" << "xn--alqualond-34a"
       
  3181                                 << QString::fromLatin1("alqualond\353")
       
  3182                                 << QString::fromLatin1("alqualond\353");
       
  3183     QTest::newRow("idn-mixed4") << "xn--alqualond-34A" << "xn--alqualond-34a"
       
  3184                                 << QString::fromLatin1("alqualond\353")
       
  3185                                 << QString::fromLatin1("alqualond\353");
       
  3186     QTest::newRow("idn-upper") << "XN--ALQUALOND-34A" << "xn--alqualond-34a"
       
  3187                                << QString::fromLatin1("alqualond\353")
       
  3188                                << QString::fromLatin1("alqualond\353");
       
  3189 
       
  3190     QTest::newRow("separator-3002") << QString::fromUtf8("example\343\200\202com")
       
  3191                                     << "example.com" << "." << "example.com";
       
  3192 }
       
  3193 
       
  3194 void tst_QUrl::ace_testsuite()
       
  3195 {
       
  3196     static const char canonsuffix[] = ".troll.no";
       
  3197     QFETCH(QString, in);
       
  3198     QFETCH(QString, toace);
       
  3199     QFETCH(QString, fromace);
       
  3200     QFETCH(QString, unicode);
       
  3201 
       
  3202     const char *suffix = canonsuffix;
       
  3203     if (toace.contains('.'))
       
  3204         suffix = 0;
       
  3205 
       
  3206     QString domain = in + suffix;
       
  3207     QCOMPARE(QString::fromLatin1(QUrl::toAce(domain)), toace + suffix);
       
  3208     if (fromace != ".")
       
  3209         QCOMPARE(QUrl::fromAce(domain.toLatin1()), fromace + suffix);
       
  3210     QCOMPARE(QUrl::fromAce(QUrl::toAce(domain)), unicode + suffix);
       
  3211 
       
  3212     domain = in + (suffix ? ".troll.No" : "");
       
  3213     QCOMPARE(QString::fromLatin1(QUrl::toAce(domain)), toace + suffix);
       
  3214     if (fromace != ".")
       
  3215         QCOMPARE(QUrl::fromAce(domain.toLatin1()), fromace + suffix);
       
  3216     QCOMPARE(QUrl::fromAce(QUrl::toAce(domain)), unicode + suffix);
       
  3217 
       
  3218     domain = in + (suffix ? ".troll.NO" : "");
       
  3219     QCOMPARE(QString::fromLatin1(QUrl::toAce(domain)), toace + suffix);
       
  3220     if (fromace != ".")
       
  3221         QCOMPARE(QUrl::fromAce(domain.toLatin1()), fromace + suffix);
       
  3222     QCOMPARE(QUrl::fromAce(QUrl::toAce(domain)), unicode + suffix);
       
  3223 }
       
  3224 
       
  3225 void tst_QUrl::std3violations_data()
       
  3226 {
       
  3227     QTest::addColumn<QString>("source");
       
  3228     QTest::addColumn<bool>("validUrl");
       
  3229 
       
  3230     QTest::newRow("too-long") << "this-domain-is-far-too-long-for-its-own-good-and-should-have-been-limited-to-63-chars" << false;
       
  3231     QTest::newRow("dash-begin") << "-x-foo" << false;
       
  3232     QTest::newRow("dash-end") << "x-foo-" << false;
       
  3233     QTest::newRow("dash-begin-end") << "-foo-" << false;
       
  3234 
       
  3235     QTest::newRow("control") << "\033foo" << false;
       
  3236     QTest::newRow("bang") << "foo!" << false;
       
  3237     QTest::newRow("plus") << "foo+bar" << false;
       
  3238     QTest::newRow("dot") << "foo.bar";
       
  3239     QTest::newRow("startingdot") << ".bar" << false;
       
  3240     QTest::newRow("startingdot2") << ".example.com" << false;
       
  3241     QTest::newRow("slash") << "foo/bar" << true;
       
  3242     QTest::newRow("colon") << "foo:80" << true;
       
  3243     QTest::newRow("question") << "foo?bar" << true;
       
  3244     QTest::newRow("at") << "foo@bar" << true;
       
  3245     QTest::newRow("backslash") << "foo\\bar" << false;
       
  3246     QTest::newRow("underline") << "foo_bar" << false;
       
  3247 
       
  3248     // these characters are transformed by NFKC to non-LDH characters
       
  3249     QTest::newRow("dot-like") << QString::fromUtf8("foo\342\200\244bar") << false;  // U+2024 ONE DOT LEADER
       
  3250     QTest::newRow("slash-like") << QString::fromUtf8("foo\357\274\217bar") << false;    // U+FF0F FULLWIDTH SOLIDUS
       
  3251 
       
  3252     // The following should be invalid but isn't
       
  3253     // the DIVISON SLASH doesn't case-fold to a slash
       
  3254     // is this a problem with RFC 3490?
       
  3255     //QTest::newRow("slash-like2") << QString::fromUtf8("foo\342\210\225bar") << false; // U+2215 DIVISION SLASH
       
  3256 }
       
  3257 
       
  3258 void tst_QUrl::std3violations()
       
  3259 {
       
  3260     QFETCH(QString, source);
       
  3261 
       
  3262 #ifdef QT_BUILD_INTERNAL
       
  3263     {
       
  3264         QString prepped = source;
       
  3265         qt_nameprep(&prepped, 0);
       
  3266         QVERIFY(!qt_check_std3rules(prepped.constData(), prepped.length()));
       
  3267     }
       
  3268 #endif
       
  3269 
       
  3270     if (source.contains('.'))
       
  3271         return; // this test ends here
       
  3272 
       
  3273     QUrl url;
       
  3274     url.setHost(source);
       
  3275     QVERIFY(url.host().isEmpty());
       
  3276 
       
  3277     QFETCH(bool, validUrl);
       
  3278     if (validUrl)
       
  3279         return;  // test ends here for these cases
       
  3280 
       
  3281     url = QUrl("http://" + source + "/some/path");
       
  3282     QVERIFY(!url.isValid());
       
  3283 }
       
  3284 
       
  3285 void tst_QUrl::std3deviations_data()
       
  3286 {
       
  3287     QTest::addColumn<QString>("source");
       
  3288 
       
  3289     QTest::newRow("ending-dot") << "example.com.";
       
  3290     QTest::newRow("ending-dot3002") << QString("example.com") + QChar(0x3002);
       
  3291 }
       
  3292 
       
  3293 void tst_QUrl::std3deviations()
       
  3294 {
       
  3295     QFETCH(QString, source);
       
  3296     QVERIFY(!QUrl::toAce(source).isEmpty());
       
  3297 
       
  3298     QUrl url;
       
  3299     url.setHost(source);
       
  3300     QVERIFY(!url.host().isEmpty());
       
  3301 }
       
  3302 
       
  3303 void tst_QUrl::tldRestrictions_data()
       
  3304 {
       
  3305     QTest::addColumn<QString>("tld");
       
  3306     QTest::addColumn<bool>("encode");
       
  3307 
       
  3308     // current whitelist
       
  3309     QTest::newRow("ac")  << QString("ac")  << true;
       
  3310     QTest::newRow("at") << QString("at") << true;
       
  3311     QTest::newRow("br") << QString("br") << true;
       
  3312     QTest::newRow("cat")  << QString("cat")  << true;
       
  3313     QTest::newRow("ch")  << QString("ch")  << true;
       
  3314     QTest::newRow("cl")  << QString("cl")  << true;
       
  3315     QTest::newRow("cn") << QString("cn") << true;
       
  3316     QTest::newRow("de")  << QString("de")  << true;
       
  3317     QTest::newRow("dk") << QString("dk") << true;
       
  3318     QTest::newRow("fi") << QString("fi") << true;
       
  3319     QTest::newRow("hu") << QString("hu") << true;
       
  3320     QTest::newRow("info")  << QString("info")  << true;
       
  3321     QTest::newRow("io") << QString("io") << true;
       
  3322     QTest::newRow("jp") << QString("jp") << true;
       
  3323     QTest::newRow("kr") << QString("kr") << true;
       
  3324     QTest::newRow("li")  << QString("li")  << true;
       
  3325     QTest::newRow("lt") << QString("lt") << true;
       
  3326     QTest::newRow("museum") << QString("museum") << true;
       
  3327     QTest::newRow("no") << QString("no") << true;
       
  3328     QTest::newRow("se")  << QString("se")  << true;
       
  3329     QTest::newRow("sh") << QString("sh") << true;
       
  3330     QTest::newRow("th")  << QString("th")  << true;
       
  3331     QTest::newRow("tm")  << QString("tm")  << true;
       
  3332     QTest::newRow("tw") << QString("tw") << true;
       
  3333     QTest::newRow("vn") << QString("vn") << true;
       
  3334 
       
  3335     // known blacklists:
       
  3336     QTest::newRow("com") << QString("com") << false;
       
  3337     QTest::newRow("foo") << QString("foo") << false;
       
  3338 }
       
  3339 
       
  3340 void tst_QUrl::tldRestrictions()
       
  3341 {
       
  3342     QFETCH(QString, tld);
       
  3343 
       
  3344     // www.brød.tld
       
  3345     QByteArray ascii = "www.xn--brd-1na." + tld.toLatin1();
       
  3346     QString unicode = QLatin1String("www.br\370d.") + tld;
       
  3347     QString encoded = QUrl::fromAce(ascii);
       
  3348     QTEST(!encoded.contains(".xn--"), "encode");
       
  3349     QTEST(encoded == unicode, "encode");
       
  3350 
       
  3351     QUrl url = QUrl::fromEncoded("http://www.xn--brd-1na." + tld.toLatin1());
       
  3352     QTEST(!url.host().contains(".xn--"), "encode");
       
  3353     QTEST(url.host() == unicode, "encode");
       
  3354 
       
  3355     url.setUrl(QLatin1String("http://www.xn--brd-1na.") + tld);
       
  3356     QTEST(!url.host().contains(".xn--"), "encode");
       
  3357     QTEST(url.host() == unicode, "encode");
       
  3358 
       
  3359     url.setUrl(QLatin1String("http://www.br\370d.") + tld);
       
  3360     QTEST(!url.host().contains(".xn--"), "encode");
       
  3361     QTEST(url.host() == unicode, "encode");
       
  3362 
       
  3363     url = QUrl::fromEncoded("http://www.br%C3%B8d." + tld.toLatin1());
       
  3364     QTEST(!url.host().contains(".xn--"), "encode");
       
  3365     QTEST(url.host() == unicode, "encode");
       
  3366 }
       
  3367 
       
  3368 void tst_QUrl::emptyQueryOrFragment()
       
  3369 {
       
  3370     QUrl qurl = QUrl::fromEncoded("http://www.kde.org/cgi/test.cgi?", QUrl::TolerantMode);
       
  3371     QCOMPARE(qurl.toEncoded().constData(), "http://www.kde.org/cgi/test.cgi?"); // Empty refs should be preserved
       
  3372     QCOMPARE(qurl.toString(), QString("http://www.kde.org/cgi/test.cgi?"));
       
  3373     qurl = QUrl::fromEncoded("http://www.kde.org/cgi/test.cgi#", QUrl::TolerantMode);
       
  3374     QCOMPARE(qurl.toEncoded().constData(), "http://www.kde.org/cgi/test.cgi#");
       
  3375     QCOMPARE(qurl.toString(), QString("http://www.kde.org/cgi/test.cgi#"));
       
  3376 
       
  3377     {
       
  3378         // start with an empty one
       
  3379         QUrl url("http://www.foo.bar/baz");
       
  3380         QVERIFY(!url.hasFragment());
       
  3381         QVERIFY(url.fragment().isNull());
       
  3382 
       
  3383         // add fragment
       
  3384         url.setFragment(QLatin1String("abc"));
       
  3385         QVERIFY(url.hasFragment());
       
  3386         QCOMPARE(url.fragment(), QString(QLatin1String("abc")));
       
  3387         QCOMPARE(url.toString(), QString(QLatin1String("http://www.foo.bar/baz#abc")));
       
  3388 
       
  3389         // remove fragment
       
  3390         url.setFragment(QString());
       
  3391         QVERIFY(!url.hasFragment());
       
  3392         QVERIFY(url.fragment().isNull());
       
  3393         QCOMPARE(url.toString(), QString(QLatin1String("http://www.foo.bar/baz")));
       
  3394 
       
  3395         // add empty fragment
       
  3396         url.setFragment(QLatin1String(""));
       
  3397         QVERIFY(url.hasFragment());
       
  3398         QVERIFY(url.fragment().isEmpty());
       
  3399         QVERIFY(!url.fragment().isNull());
       
  3400         QCOMPARE(url.toString(), QString(QLatin1String("http://www.foo.bar/baz#")));
       
  3401     }
       
  3402 
       
  3403     {
       
  3404         // start with an empty one
       
  3405         QUrl url("http://www.foo.bar/baz");
       
  3406         QVERIFY(!url.hasQuery());
       
  3407         QVERIFY(url.encodedQuery().isNull());
       
  3408 
       
  3409         // add encodedQuery
       
  3410         url.setEncodedQuery("abc=def");
       
  3411         QVERIFY(url.hasQuery());
       
  3412         QCOMPARE(QString(url.encodedQuery()), QString(QLatin1String("abc=def")));
       
  3413         QCOMPARE(url.toString(), QString(QLatin1String("http://www.foo.bar/baz?abc=def")));
       
  3414 
       
  3415         // remove encodedQuery
       
  3416         url.setEncodedQuery(0);
       
  3417         QVERIFY(!url.hasQuery());
       
  3418         QVERIFY(url.encodedQuery().isNull());
       
  3419         QCOMPARE(url.toString(), QString(QLatin1String("http://www.foo.bar/baz")));
       
  3420 
       
  3421         // add empty encodedQuery
       
  3422         url.setEncodedQuery("");
       
  3423         QVERIFY(url.hasQuery());
       
  3424         QVERIFY(url.encodedQuery().isEmpty());
       
  3425         QVERIFY(!url.encodedQuery().isNull());
       
  3426         QCOMPARE(url.toString(), QString(QLatin1String("http://www.foo.bar/baz?")));
       
  3427     }
       
  3428 }
       
  3429 
       
  3430 void tst_QUrl::hasFragment_data()
       
  3431 {
       
  3432     QTest::addColumn<QString>("url");
       
  3433     QTest::addColumn<bool>("trueFalse");
       
  3434 
       
  3435     QTest::newRow("no fragment") << "http://www.foo.bar" << false;
       
  3436 
       
  3437     QTest::newRow("empty fragment") << "http://www.foo.bar#" << true;
       
  3438     QTest::newRow("empty fragment 2") << "http://www.foo.bar/#" << true;
       
  3439 
       
  3440     QTest::newRow("fragment") << "http://www.foo.bar#baz" << true;
       
  3441     QTest::newRow("fragment2") << "http://www.foo.bar/#baz" << true;
       
  3442 
       
  3443     QTest::newRow("%23") << "http://www.foo.bar/%23" << false;
       
  3444     QTest::newRow("%23-and-something") << "http://www.foo.bar/%23baz" << false;
       
  3445 }
       
  3446 
       
  3447 void tst_QUrl::hasFragment()
       
  3448 {
       
  3449     QFETCH(QString, url);
       
  3450     QFETCH(bool, trueFalse);
       
  3451 
       
  3452     QUrl qurl(url);
       
  3453     QCOMPARE(qurl.hasFragment(), trueFalse);
       
  3454     QCOMPARE(qurl.fragment().isNull(), !trueFalse);
       
  3455 }
       
  3456 
       
  3457 void tst_QUrl::setEncodedFragment_data()
       
  3458 {
       
  3459     QTest::addColumn<QByteArray>("base");
       
  3460     QTest::addColumn<QByteArray>("fragment");
       
  3461     QTest::addColumn<QByteArray>("expected");
       
  3462 
       
  3463     typedef QByteArray BA;
       
  3464     QTest::newRow("empty") << BA("http://www.kde.org") << BA("") << BA("http://www.kde.org#");
       
  3465     QTest::newRow("basic test") << BA("http://www.kde.org") << BA("abc") << BA("http://www.kde.org#abc");
       
  3466     QTest::newRow("initial url has fragment") << BA("http://www.kde.org#old") << BA("new") << BA("http://www.kde.org#new");
       
  3467     QTest::newRow("encoded fragment") << BA("http://www.kde.org") << BA("a%20c") << BA("http://www.kde.org#a%20c");
       
  3468     QTest::newRow("with #") << BA("http://www.kde.org") << BA("a#b") << BA("http://www.kde.org#a#b");
       
  3469 }
       
  3470 
       
  3471 void tst_QUrl::setEncodedFragment()
       
  3472 {
       
  3473     QFETCH(QByteArray, base);
       
  3474     QFETCH(QByteArray, fragment);
       
  3475     QFETCH(QByteArray, expected);
       
  3476     QUrl u;
       
  3477     u.setEncodedUrl(base, QUrl::TolerantMode);
       
  3478     QVERIFY(u.isValid());
       
  3479     u.setEncodedFragment(fragment);
       
  3480     QVERIFY(u.isValid());
       
  3481     QVERIFY(u.hasFragment());
       
  3482     QCOMPARE(QString::fromLatin1(u.toEncoded()), QString::fromLatin1(expected));
       
  3483 }
       
  3484 
       
  3485 void tst_QUrl::fromEncoded()
       
  3486 {
       
  3487     QUrl qurl2 = QUrl::fromEncoded("print:/specials/Print%20To%20File%20(PDF%252FAcrobat)", QUrl::TolerantMode);
       
  3488     QCOMPARE(qurl2.path(), QString::fromLatin1("/specials/Print To File (PDF%2FAcrobat)"));
       
  3489     QCOMPARE(QFileInfo(qurl2.path()).fileName(), QString::fromLatin1("Print To File (PDF%2FAcrobat)"));
       
  3490     QCOMPARE(qurl2.toEncoded().constData(), "print:/specials/Print%20To%20File%20(PDF%252FAcrobat)");
       
  3491 
       
  3492     QUrl qurl = QUrl::fromEncoded("http://\303\244.de");
       
  3493     QVERIFY(qurl.isValid());
       
  3494     QCOMPARE(qurl.toEncoded().constData(), "http://xn--4ca.de");
       
  3495 
       
  3496     QUrl qurltest(QUrl::fromPercentEncoding("http://\303\244.de"));
       
  3497     QVERIFY(qurltest.isValid());
       
  3498 
       
  3499     QUrl qurl_newline_1 = QUrl::fromEncoded("http://www.foo.bar/foo/bar\ngnork", QUrl::TolerantMode);
       
  3500     QVERIFY(qurl_newline_1.isValid());
       
  3501     QCOMPARE(qurl_newline_1.toEncoded().constData(), "http://www.foo.bar/foo/bar%0Agnork");
       
  3502 }
       
  3503 
       
  3504 void tst_QUrl::stripTrailingSlash()
       
  3505 {
       
  3506     QUrl u1( "ftp://ftp.de.kde.org/dir" );
       
  3507     QUrl u2( "ftp://ftp.de.kde.org/dir/" );
       
  3508     QUrl::FormattingOptions options = QUrl::None;
       
  3509     options |= QUrl::StripTrailingSlash;
       
  3510     QString str1 = u1.toString(options);
       
  3511     QString str2 = u2.toString(options);
       
  3512     QCOMPARE( str1, u1.toString() );
       
  3513     QCOMPARE( str2, u1.toString() );
       
  3514     bool same = str1 == str2;
       
  3515     QVERIFY( same );
       
  3516 }
       
  3517 
       
  3518 void tst_QUrl::hosts_data()
       
  3519 {
       
  3520     QTest::addColumn<QString>("url");
       
  3521     QTest::addColumn<QString>("host");
       
  3522 
       
  3523     QTest::newRow("empty") << QString("") << QString("");
       
  3524     QTest::newRow("empty1") << QString("file:///file") << QString("");
       
  3525     QTest::newRow("empty2") << QString("file:/file") << QString("");
       
  3526     QTest::newRow("empty3") << QString("http:///file") << QString("");
       
  3527     QTest::newRow("empty4") << QString("http:/file") << QString("");
       
  3528 
       
  3529     // numeric hostnames
       
  3530     QTest::newRow("http://123/") << QString("http://123/") << QString("123");
       
  3531     QTest::newRow("http://456/") << QString("http://456/") << QString("456");
       
  3532     QTest::newRow("http://1000/") << QString("http://1000/") << QString("1000");
       
  3533 
       
  3534     // IP literals
       
  3535     QTest::newRow("normal-ip-literal") << QString("http://1.2.3.4") << QString("1.2.3.4");
       
  3536     QTest::newRow("normal-ip-literal-with-port") << QString("http://1.2.3.4:80")
       
  3537                                                  << QString("1.2.3.4");
       
  3538     QTest::newRow("ipv6-literal") << QString("http://[::1]") << QString("::1");
       
  3539     QTest::newRow("ipv6-literal-with-port") << QString("http://[::1]:80") << QString("::1");
       
  3540     QTest::newRow("long-ipv6-literal") << QString("http://[2001:200:0:8002:203:47ff:fea5:3085]")
       
  3541                                        << QString("2001:200:0:8002:203:47ff:fea5:3085");
       
  3542     QTest::newRow("long-ipv6-literal-with-port") << QString("http://[2001:200:0:8002:203:47ff:fea5:3085]:80")
       
  3543                                                  << QString("2001:200:0:8002:203:47ff:fea5:3085");
       
  3544     QTest::newRow("ipv6-literal-v4compat") << QString("http://[::255.254.253.252]")
       
  3545                                            << QString("::255.254.253.252");
       
  3546     QTest::newRow("ipv6-literal-v4compat-2") << QString("http://[1000::ffff:127.128.129.1]")
       
  3547                                              << QString("1000::ffff:127.128.129.1");
       
  3548     QTest::newRow("long-ipv6-literal-v4compat") << QString("http://[fec0:8000::8002:1000:ffff:200.100.50.250]")
       
  3549                                                 << QString("fec0:8000::8002:1000:ffff:200.100.50.250");
       
  3550     QTest::newRow("longer-ipv6-literal-v4compat") << QString("http://[fec0:8000:4000:8002:1000:ffff:200.100.50.250]")
       
  3551                                                   << QString("fec0:8000:4000:8002:1000:ffff:200.100.50.250");
       
  3552 
       
  3553 #if 0
       
  3554     // this is actually invalid
       
  3555     QTest::newRow("mac-literal") << QString("obex://[00:30:1b:b7:21:fb]")
       
  3556                                  << QString("00:30:1b:b7:21:fb");
       
  3557 #endif
       
  3558 
       
  3559     // normal hostnames
       
  3560     QTest::newRow("normal") << QString("http://intern") << QString("intern");
       
  3561     QTest::newRow("normal2") << QString("http://qt.nokia.com") << QString("qt.nokia.com");
       
  3562 
       
  3563     // IDN hostnames
       
  3564     QTest::newRow("idn") << QString(QLatin1String("http://\345r.no")) << QString(QLatin1String("\345r.no"));
       
  3565     QTest::newRow("idn-ace") << QString("http://xn--r-1fa.no") << QString(QLatin1String("\345r.no"));
       
  3566 }
       
  3567 
       
  3568 void tst_QUrl::hosts()
       
  3569 {
       
  3570     QFETCH(QString, url);
       
  3571 
       
  3572     QTEST(QUrl(url).host(), "host");
       
  3573 }
       
  3574 
       
  3575 void tst_QUrl::setPort()
       
  3576 {
       
  3577     {
       
  3578         QUrl url;
       
  3579         QVERIFY(url.toString().isEmpty());
       
  3580         url.setPort(80);
       
  3581         QCOMPARE(url.port(), 80);
       
  3582         QCOMPARE(url.toString(), QString::fromLatin1("//:80"));
       
  3583         url.setPort(-1);
       
  3584         QCOMPARE(url.port(), -1);
       
  3585         QVERIFY(url.toString().isEmpty());
       
  3586         url.setPort(80);
       
  3587         QTest::ignoreMessage(QtWarningMsg, "QUrl::setPort: Out of range");
       
  3588         url.setPort(65536);
       
  3589         QCOMPARE(url.port(), -1);
       
  3590     }
       
  3591 }
       
  3592 
       
  3593 void tst_QUrl::toEncoded_data()
       
  3594 {
       
  3595     QTest::addColumn<QByteArray>("url");
       
  3596     QTest::addColumn<QUrl::FormattingOptions>("options");
       
  3597     QTest::addColumn<QByteArray>("encoded");
       
  3598     QTest::newRow("file:///dir/") << QByteArray("file:///dir/")
       
  3599                                   << QUrl::FormattingOptions(QUrl::StripTrailingSlash)
       
  3600                                   << QByteArray("file:///dir");
       
  3601 }
       
  3602 
       
  3603 void tst_QUrl::toEncoded()
       
  3604 {
       
  3605     QFETCH(QByteArray, url);
       
  3606     QFETCH(QUrl::FormattingOptions, options);
       
  3607     QFETCH(QByteArray, encoded);
       
  3608 
       
  3609     QCOMPARE(QUrl::fromEncoded(url).toEncoded(options), encoded);
       
  3610 }
       
  3611 
       
  3612 void tst_QUrl::setAuthority_data()
       
  3613 {
       
  3614     QTest::addColumn<QString>("authority");
       
  3615     QTest::addColumn<QString>("url");
       
  3616     QTest::newRow("Plain auth") << QString("62.70.27.22:21") << QString("//62.70.27.22:21");
       
  3617     QTest::newRow("Yet another plain auth") << QString("192.168.1.1:21") << QString("//192.168.1.1:21");
       
  3618     QTest::newRow("Auth without port") << QString("192.168.1.1") << QString("//192.168.1.1");
       
  3619     QTest::newRow("Auth w/full hostname without port") << QString("shusaku.troll.no") << QString("//shusaku.troll.no");
       
  3620     QTest::newRow("Auth w/hostname without port") << QString("shusaku") << QString("//shusaku");
       
  3621     QTest::newRow("Auth w/full hostname that ends with number, without port") << QString("shusaku.troll.no.2") << QString("//shusaku.troll.no.2");
       
  3622     QTest::newRow("Auth w/hostname that ends with number, without port") << QString("shusaku2") << QString("//shusaku2");
       
  3623     QTest::newRow("Empty auth") << QString() << QString();
       
  3624 }
       
  3625 
       
  3626 void tst_QUrl::setAuthority()
       
  3627 {
       
  3628     QUrl u;
       
  3629     QFETCH(QString, authority);
       
  3630     QFETCH(QString, url);
       
  3631     u.setAuthority(authority);
       
  3632     QCOMPARE(u.toString(), url);
       
  3633 }
       
  3634 
       
  3635 void tst_QUrl::errorString()
       
  3636 {
       
  3637     QUrl u = QUrl::fromEncoded("http://strange<username>@bad_hostname/", QUrl::StrictMode);
       
  3638     QVERIFY(!u.isValid());
       
  3639     QString errorString = "Invalid URL \"http://strange<username>@bad_hostname/\": "
       
  3640                           "error at position 14: expected end of URL, but found '<'";
       
  3641     QCOMPARE(u.errorString(), errorString);
       
  3642 
       
  3643     QUrl v;
       
  3644     errorString = "Invalid URL \"\": ";
       
  3645     QCOMPARE(v.errorString(), errorString);
       
  3646 }
       
  3647 
       
  3648 void tst_QUrl::clear()
       
  3649 {
       
  3650     QUrl url("a");
       
  3651     QUrl url2("a");
       
  3652     QCOMPARE(url, url2);
       
  3653     url.clear();
       
  3654     QVERIFY(url != url2);
       
  3655 }
       
  3656 
       
  3657 void tst_QUrl::binaryData_data()
       
  3658 {
       
  3659     QTest::addColumn<QString>("url");
       
  3660     QTest::newRow("username") << "http://%01%0D%0A%7F@foo/";
       
  3661     QTest::newRow("username-at") << "http://abc%40_def@foo/";
       
  3662     QTest::newRow("username-nul") << "http://abc%00_def@foo/";
       
  3663     QTest::newRow("username-colon") << "http://abc%3A_def@foo/";
       
  3664     QTest::newRow("username-nonutf8") << "http://abc%E1_def@foo/";
       
  3665 
       
  3666     QTest::newRow("password") << "http://user:%01%0D%0A%7F@foo/";
       
  3667     QTest::newRow("password-at") << "http://user:abc%40_def@foo/";
       
  3668     QTest::newRow("password-nul") << "http://user:abc%00_def@foo/";
       
  3669     QTest::newRow("password-nonutf8") << "http://user:abc%E1_def@foo/";
       
  3670 
       
  3671     QTest::newRow("file") << "http://foo/%01%0D%0A%7F";
       
  3672     QTest::newRow("file-nul") << "http://foo/abc%00_def";
       
  3673     QTest::newRow("file-hash") << "http://foo/abc%23_def";
       
  3674     QTest::newRow("file-question") << "http://foo/abc%3F_def";
       
  3675     QTest::newRow("file-nonutf8") << "http://foo/abc%E1_def";
       
  3676     QTest::newRow("file-slash") << "http://foo/abc%2f_def";
       
  3677 
       
  3678     QTest::newRow("ref") << "http://foo/file#a%01%0D%0A%7F";
       
  3679     QTest::newRow("ref-nul") << "http://foo/file#abc%00_def";
       
  3680     QTest::newRow("ref-question") << "http://foo/file#abc?_def";
       
  3681     QTest::newRow("ref-nonutf8") << "http://foo/file#abc%E1_def";
       
  3682 
       
  3683     QTest::newRow("query-value") << "http://foo/query?foo=%01%0D%0A%7F";
       
  3684     QTest::newRow("query-value-nul") << "http://foo/query?foo=abc%00_def";
       
  3685     QTest::newRow("query-value-nonutf8") << "http://foo/query?foo=abc%E1_def";
       
  3686 
       
  3687     QTest::newRow("query-name") << "http://foo/query/a%01%0D%0A%7Fz=foo";
       
  3688     QTest::newRow("query-name-nul") << "http://foo/query/abc%00_def=foo";
       
  3689     QTest::newRow("query-name-nonutf8") << "http://foo/query/abc%E1_def=foo";
       
  3690 }
       
  3691 
       
  3692 void tst_QUrl::binaryData()
       
  3693 {
       
  3694     QFETCH(QString, url);
       
  3695     QUrl u = QUrl::fromEncoded(url.toUtf8());
       
  3696 
       
  3697     QVERIFY(u.isValid());
       
  3698     QVERIFY(!u.isEmpty());
       
  3699 
       
  3700     QString url2 = QString::fromUtf8(u.toEncoded());
       
  3701     //QCOMPARE(url2.length(), url.length());
       
  3702     QCOMPARE(url2, url);
       
  3703 }
       
  3704 
       
  3705 void tst_QUrl::fromUserInput_data()
       
  3706 {
       
  3707     //
       
  3708     // most of this test is:
       
  3709     //  Copyright (C) Research In Motion Limited 2009. All rights reserved.
       
  3710     // Distributed under the BSD license.
       
  3711     // See qurl.cpp
       
  3712     //
       
  3713 
       
  3714     QTest::addColumn<QString>("string");
       
  3715     QTest::addColumn<QUrl>("guessUrlFromString");
       
  3716 
       
  3717     // Null
       
  3718     QTest::newRow("null") << QString() << QUrl();
       
  3719 
       
  3720     // File
       
  3721     QDirIterator it(QDir::homePath());
       
  3722     int c = 0;
       
  3723     while (it.hasNext()) {
       
  3724         it.next();
       
  3725         QTest::newRow(QString("file-%1").arg(c++).toLatin1()) << it.filePath() << QUrl::fromLocalFile(it.filePath());
       
  3726     }
       
  3727 
       
  3728     // basic latin1
       
  3729     QTest::newRow("unicode-0") << QString::fromUtf8("\xc3\xa5.com/") << QUrl::fromEncoded(QString::fromUtf8("http://\xc3\xa5.com/").toUtf8(), QUrl::TolerantMode);
       
  3730     QTest::newRow("unicode-0b") << QString::fromUtf8("\xc3\xa5.com/") << QUrl::fromEncoded("http://%C3%A5.com/", QUrl::TolerantMode);
       
  3731     QTest::newRow("unicode-0c") << QString::fromUtf8("\xc3\xa5.com/") << QUrl::fromEncoded("http://xn--5ca.com/", QUrl::TolerantMode);
       
  3732     // unicode
       
  3733     QTest::newRow("unicode-1") << QString::fromUtf8("\xce\xbb.com/") << QUrl::fromEncoded(QString::fromUtf8("http://\xce\xbb.com/").toUtf8(), QUrl::TolerantMode);
       
  3734     QTest::newRow("unicode-1b") << QString::fromUtf8("\xce\xbb.com/") << QUrl::fromEncoded("http://%CE%BB.com/", QUrl::TolerantMode);
       
  3735     QTest::newRow("unicode-1c") << QString::fromUtf8("\xce\xbb.com/") << QUrl::fromEncoded("http://xn--wxa.com/", QUrl::TolerantMode);
       
  3736 
       
  3737     // no scheme
       
  3738     QTest::newRow("add scheme-0") << "example.org" << QUrl("http://example.org");
       
  3739     QTest::newRow("add scheme-1") << "www.example.org" << QUrl("http://www.example.org");
       
  3740     QTest::newRow("add scheme-2") << "ftp.example.org" << QUrl("ftp://ftp.example.org");
       
  3741     QTest::newRow("add scheme-3") << "hostname" << QUrl("http://hostname");
       
  3742 
       
  3743     // QUrl's tolerant parser should already handle this
       
  3744     QTest::newRow("not-encoded-0") << "http://example.org/test page.html" << QUrl::fromEncoded("http://example.org/test%20page.html");
       
  3745 
       
  3746     // Make sure the :80, i.e. port doesn't screw anything up
       
  3747     QUrl portUrl("http://example.org");
       
  3748     portUrl.setPort(80);
       
  3749     QTest::newRow("port-0") << "example.org:80" << portUrl;
       
  3750     QTest::newRow("port-1") << "http://example.org:80" << portUrl;
       
  3751     portUrl.setPath("path");
       
  3752     QTest::newRow("port-1") << "example.org:80/path" << portUrl;
       
  3753     QTest::newRow("port-1") << "http://example.org:80/path" << portUrl;
       
  3754 
       
  3755     // mailto doesn't have a ://, but is valid
       
  3756     QUrl mailto("ben@example.net");
       
  3757     mailto.setScheme("mailto");
       
  3758     QTest::newRow("mailto") << "mailto:ben@example.net" << mailto;
       
  3759 
       
  3760     // misc
       
  3761     QTest::newRow("localhost-1") << "localhost:80" << QUrl("http://localhost:80");
       
  3762     QTest::newRow("spaces-0") << "  http://example.org/test page.html " << QUrl("http://example.org/test%20page.html");
       
  3763     QTest::newRow("trash-0") << "example.org/test?someData=42%&someOtherData=abcde#anchor" << QUrl::fromEncoded("http://example.org/test?someData=42%25&someOtherData=abcde#anchor");
       
  3764     QTest::newRow("other-scheme-0") << "spotify:track:0hO542doVbfGDAGQULMORT" << QUrl("spotify:track:0hO542doVbfGDAGQULMORT");
       
  3765     QTest::newRow("other-scheme-1") << "weirdscheme:80:otherstuff" << QUrl("weirdscheme:80:otherstuff");
       
  3766 
       
  3767     // FYI: The scheme in the resulting url user
       
  3768     QUrl authUrl("user:pass@domain.com");
       
  3769     QTest::newRow("misc-1") << "user:pass@domain.com" << authUrl;
       
  3770 }
       
  3771 
       
  3772 void tst_QUrl::fromUserInput()
       
  3773 {
       
  3774     QFETCH(QString, string);
       
  3775     QFETCH(QUrl, guessUrlFromString);
       
  3776 
       
  3777     QUrl url = QUrl::fromUserInput(string);
       
  3778     QCOMPARE(url, guessUrlFromString);
       
  3779 }
       
  3780 
       
  3781 void tst_QUrl::task_199967()
       
  3782 {
       
  3783     {
       
  3784         QUrl url;
       
  3785         url.setEncodedUrl("LABEL=USB_STICK", QUrl::TolerantMode);
       
  3786         QVERIFY( url.isValid() );
       
  3787         QCOMPARE( url.path(), QString("LABEL=USB_STICK") );
       
  3788         QVERIFY( !url.isEmpty() );
       
  3789     }
       
  3790     {
       
  3791         QUrl url;
       
  3792         url.setEncodedUrl("LABEL=USB_STICK", QUrl::TolerantMode);
       
  3793         QVERIFY( url.isValid() );
       
  3794         QVERIFY( !url.isEmpty() );
       
  3795         QCOMPARE( url.path(), QString("LABEL=USB_STICK") );
       
  3796     }
       
  3797 }
       
  3798 
       
  3799 void tst_QUrl::task_240612()
       
  3800 {
       
  3801     QUrl url;
       
  3802     url.setEncodedPath("test.txt");
       
  3803     url.setHost("example.com");
       
  3804 
       
  3805     QCOMPARE(url.toEncoded().constData(), "//example.com/test.txt");
       
  3806 
       
  3807     url.path();
       
  3808     QCOMPARE(url.toEncoded().constData(), "//example.com/test.txt");
       
  3809 }
       
  3810 
       
  3811 #ifdef QT3_SUPPORT
       
  3812 void tst_QUrl::dirPath()
       
  3813 {
       
  3814     QCOMPARE(QUrl("http://www.vg.no/test/file.txt").dirPath(), QString("/test"));
       
  3815 }
       
  3816 #endif
       
  3817 
       
  3818 void tst_QUrl::resolvedWithAbsoluteSchemes() const
       
  3819 {
       
  3820     QFETCH(QUrl, base);
       
  3821     QFETCH(QUrl, relative);
       
  3822     QFETCH(QUrl, expected);
       
  3823 
       
  3824     /* Check our input. */
       
  3825     QVERIFY(relative.isValid());
       
  3826     QVERIFY(base.isValid());
       
  3827     QVERIFY(expected.isValid());
       
  3828 
       
  3829     const QUrl result(base.resolved(relative));
       
  3830 
       
  3831     QVERIFY(result.isValid());
       
  3832     QCOMPARE(result, expected);
       
  3833 }
       
  3834 
       
  3835 void tst_QUrl::resolvedWithAbsoluteSchemes_data() const
       
  3836 {
       
  3837     QTest::addColumn<QUrl>("base");
       
  3838     QTest::addColumn<QUrl>("relative");
       
  3839     QTest::addColumn<QUrl>("expected");
       
  3840 
       
  3841     QTest::newRow("Absolute file:/// against absolute FTP.")
       
  3842         << QUrl::fromEncoded("file:///foo/")
       
  3843         << QUrl::fromEncoded("ftp://example.com/")
       
  3844         << QUrl::fromEncoded("ftp://example.com/");
       
  3845 
       
  3846     QTest::newRow("Absolute file:/// against absolute HTTP.")
       
  3847         << QUrl::fromEncoded("file:///foo/")
       
  3848         << QUrl::fromEncoded("http://example.com/")
       
  3849         << QUrl::fromEncoded("http://example.com/");
       
  3850 
       
  3851 
       
  3852     QTest::newRow("Absolute file:/// against data scheme.")
       
  3853         << QUrl::fromEncoded("file:///foo/")
       
  3854         << QUrl::fromEncoded("data:application/xml,%3Ce%2F%3E")
       
  3855         << QUrl::fromEncoded("data:application/xml,%3Ce%2F%3E");
       
  3856 
       
  3857     QTest::newRow("Resolve with base url and port.")
       
  3858         << QUrl::fromEncoded("http://www.foo.com:8080/")
       
  3859         << QUrl::fromEncoded("newfile.html")
       
  3860         << QUrl::fromEncoded("http://www.foo.com:8080/newfile.html");
       
  3861 }
       
  3862 
       
  3863 QTEST_MAIN(tst_QUrl)
       
  3864 #include "tst_qurl.moc"