1 // krazy:excludeall=qclasses
2 /* This file is part of the KDE libraries
3     Copyright (c) 1999-2005 Waldo Bastian <bastian@kde.org>
4     Copyright (c) 2000-2005 David Faure <faure@kde.org>
5 
6     This library is free software; you can redistribute it and/or
7     modify it under the terms of the GNU Library General Public
8     License version 2 as published by the Free Software Foundation.
9 
10     This library is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13     Library General Public License for more details.
14 
15     You should have received a copy of the GNU Library General Public License
16     along with this library; see the file COPYING.LIB.  If not, write to
17     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18     Boston, MA 02110-1301, USA.
19 */
20 
21 #include "kurltest.h"
22 
23 #include <QTest>
24 
QTEST_MAIN(KUrlTest)25 QTEST_MAIN(KUrlTest)
26 
27 #include "kurl.h"
28 
29 #include "kuser.h"
30 
31 #include <QTextCodec>
32 #include <QDataStream>
33 #include <QMap>
34 #include <QDebug>
35 #include <unistd.h> // gethostname
36 
37 //QCOMPARE cannot be used to strictly check for empty or null QString as it treats QString("") == QString()
38 #define QSTREMPTY(_str) QVERIFY(!_str.isNull() && _str.isEmpty())
39 
40 void KUrlTest::testEmptyURL()
41 {
42     KUrl emptyURL;
43     QVERIFY(!emptyURL.isValid());
44     QVERIFY(emptyURL.isEmpty());
45     QVERIFY(emptyURL.prettyUrl().isEmpty());
46     QCOMPARE(emptyURL.url(), QString());
47     QVERIFY(emptyURL.url().isEmpty());
48     QVERIFY(!emptyURL.url().isNull());   // well, a null string would be correct too...
49     QVERIFY(!emptyURL.isLocalFile());
50 
51     KUrl emptyStringURL("");
52     QVERIFY(!emptyStringURL.isValid());
53     QVERIFY(emptyStringURL.isEmpty());
54     QVERIFY(emptyStringURL.url().isEmpty());
55     QVERIFY(!emptyStringURL.url().isNull());
56     QCOMPARE(emptyURL, emptyStringURL);
57 
58     // Roundtrip via .url()
59     KUrl emptyCopy(emptyURL.url());
60     QCOMPARE(emptyURL, emptyCopy);
61     KUrl emptyStringCopy = KUrl(emptyStringURL.url());
62     QCOMPARE(emptyStringURL, emptyCopy);
63 
64     KUrl fileURL("file:/");
65     QVERIFY(!fileURL.isEmpty());
66 
67     fileURL = "file:///";
68     QVERIFY(!fileURL.isEmpty());
69 
70     fileURL = QLatin1String("FILE:///");
71     QVERIFY(fileURL.isLocalFile());
72 
73     KUrl udir;
74     QCOMPARE(udir.url(), QString());
75     QVERIFY(udir.isEmpty());
76     QVERIFY(!udir.isValid());
77     udir = udir.upUrl();
78     QVERIFY(udir.upUrl().isEmpty());
79 }
80 
testIsValid()81 void KUrlTest::testIsValid()
82 {
83     KUrl url1("gg:www.kde.org");
84     QVERIFY(url1.isValid());
85 
86     url1 = "KDE";
87     QVERIFY(url1.isValid());   // KDE3 difference: was FALSE
88 
89     url1 = "$HOME/.kde/share/config";
90     QVERIFY(url1.isValid());   // KDE3 difference: was FALSE
91 }
92 
testSetQuery()93 void KUrlTest::testSetQuery()
94 {
95     KUrl url1 = KUrl(QByteArray("http://www.kde.org/foo.cgi?foo=bar"));
96     QCOMPARE(url1.query(), QString("?foo=bar"));
97     url1.setQuery("toto=titi&kde=rocks");
98     QCOMPARE(url1.query(), QString("?toto=titi&kde=rocks"));
99     url1.setQuery("?kde%20rocks&a=b");   // must be encoded already, as documented
100     QCOMPARE(url1.query(), QString("?kde%20rocks&a=b"));   // encoded, as documented
101     url1.setQuery("?");
102     QCOMPARE(url1.query(), QString("?"));
103     url1.setQuery("");
104     QCOMPARE(url1.query(), QString("?"));
105     url1.setQuery(QString());
106     QCOMPARE(url1.query(), QString());
107 
108     url1.setQuery("4=2+2");
109     QCOMPARE(url1.url(), QString("http://www.kde.org/foo.cgi?4=2+2"));
110     QCOMPARE(url1.query(), QString("?4=2+2"));
111     url1.setQuery("4=2%2B2");
112     QCOMPARE(url1.url(), QString("http://www.kde.org/foo.cgi?4=2%2B2"));  // %2B should not be decoded to +
113     QCOMPARE(url1.query(), QString("?4=2%2B2"));
114 }
115 
testEmptyNullReference()116 void KUrlTest::testEmptyNullReference()
117 {
118     KUrl url1 = KUrl("http://www.kde.org");
119     QVERIFY(!url1.hasRef());
120     QVERIFY(!url1.hasHTMLRef());
121     QVERIFY(url1.ref().isNull());
122     QVERIFY(url1.htmlRef().isNull());
123     QVERIFY(url1.encodedHtmlRef().isNull());
124 
125     url1 = "http://www.kde.org#";
126     QVERIFY(url1.hasRef());
127     QVERIFY(url1.hasHTMLRef());
128     QSTREMPTY(url1.ref());
129     QSTREMPTY(url1.htmlRef());
130     QSTREMPTY(url1.encodedHtmlRef());
131 }
132 
testSetRef()133 void KUrlTest::testSetRef()
134 {
135     KUrl url1 = KUrl(QByteArray("http://www.kde.org/foo.cgi#foo=bar"));
136     QCOMPARE(url1.ref(), QString("foo=bar"));    // KDE3: was foo=bar, KDE4 (until 4.11): foo%3Dbar, KF5 (Qt5.2): foo=bar
137 #if 0// ditto (TODO)
138     url1.setRef("toto=titi&kde=rocks");
139     QCOMPARE(url1.ref(), QString("toto=titi&kde=rocks"));
140     url1.setRef("kde=rocks&a=b");
141     QCOMPARE(url1.ref(), QString("kde=rocks&a=b"));
142     url1.setRef("#");
143     QCOMPARE(url1.ref(), QString("#"));
144 #endif
145     url1.setRef("");
146     QSTREMPTY(url1.ref());
147     QCOMPARE(url1.url(), QString("http://www.kde.org/foo.cgi#"));
148 
149     url1.setRef(QString());
150     QVERIFY(url1.ref().isNull());
151     QCOMPARE(url1.url(), QString("http://www.kde.org/foo.cgi"));
152 }
153 
testSetHTMLRef()154 void KUrlTest::testSetHTMLRef()
155 {
156     KUrl url1 = KUrl(QByteArray("http://www.kde.org/foo.cgi#foo=bar"));
157     QCOMPARE(url1.htmlRef(), QString("foo=bar"));
158     url1.setHTMLRef("toto=titi&kde=rocks");
159     QCOMPARE(url1.htmlRef(), QString("toto=titi&kde=rocks"));
160     url1.setHTMLRef("kde=rocks&a=b");
161     QCOMPARE(url1.htmlRef(), QString("kde=rocks&a=b"));
162     url1.setHTMLRef("#");
163     QCOMPARE(url1.htmlRef(), QString("#"));
164     QCOMPARE(url1.ref(), QString("%23"));   // it's encoded
165     url1.setHTMLRef("");
166     QSTREMPTY(url1.htmlRef());
167     QCOMPARE(url1.url(), QString("http://www.kde.org/foo.cgi#"));
168 
169     url1.setHTMLRef(QString());
170     QVERIFY(url1.htmlRef().isNull());
171     QCOMPARE(url1.url(), QString("http://www.kde.org/foo.cgi"));
172 }
173 
testQUrl()174 void KUrlTest::testQUrl()
175 {
176     QUrl url1("file:///home/dfaure/my#%2f");
177     // Qt 4.0 to 4.4: #/. Qt 4.5: %2f again.
178     // Qt 5.0 & 5.1: #/. Qt 5.2: %2F again (probably due to 2ff719de8fe7a in qtbase)
179     // See also testSimpleMethods below, for the KUrl history of it.
180     QCOMPARE(url1.toString(), QString("file:///home/dfaure/my#%2F"));
181 
182 #ifdef Q_OS_WIN
183     QUrl url2("file:///c:/home/dfaure/my#%2f");
184     QCOMPARE(url2.toString(), QString("file:///c:/home/dfaure/my#/"));
185 #endif
186 
187     // Show how toString() was confusing in Qt4, and fixed in Qt5
188     QUrl url3 = QUrl::fromLocalFile("/home/dfaure/hash#file");
189     QCOMPARE(url3.toString(), QString("file:///home/dfaure/hash%23file"));
190     QString url3Str = url3.toString();
191     QUrl url4(url3Str);
192     QCOMPARE(url4.toString(), url3Str);
193     QVERIFY(url3 == url4);
194 }
195 
testIsLocalFile()196 void KUrlTest::testIsLocalFile()
197 {
198     KUrl trash("trash:/");
199     QVERIFY(!trash.isLocalFile());
200 
201     KUrl local_file_1("file://localhost/my/file");
202     QVERIFY(local_file_1.isLocalFile());
203 
204     KUrl local_file_2("file://www.kde.org/my/file");
205     QVERIFY(!local_file_2.isLocalFile());
206 
207 #if 0
208     // exactly like in kurl.cpp, getenv("HOSTNAME") can be different...
209     char hostname[ 256 ];
210     hostname[ 0 ] = '\0';
211     if (!gethostname(hostname, 255)) {
212         hostname[sizeof(hostname) - 1] = '\0';
213     }
214 
215     for (char *p = hostname; *p; p++) {
216         *p = tolower(*p);
217     }
218 
219     KUrl local_file_3;
220     local_file_3.setHost(QString::fromLatin1(hostname));
221     local_file_3.setPath("/my/file");
222     qDebug("URL=%s", qPrintable(local_file_3.url()));
223     QVERIFY(local_file_3.isLocalFile());
224 #endif
225 
226     KUrl local_file_4("file:///my/file");
227     QVERIFY(local_file_4.isLocalFile());
228 
229 #ifdef Q_OS_WIN
230     KUrl local_file_4a("file:///c:/my/file");
231     QVERIFY(local_file_4a.isLocalFile());
232 #endif
233 
234     KUrl local_file_5;
235     local_file_5.setPath("/foo?bar");
236     QCOMPARE(local_file_5.url(), QString("file:///foo%3Fbar"));
237 
238 #ifdef Q_OS_WIN
239     KUrl local_file_5a;
240     local_file_5a.setPath("c:/foo?bar");
241     QCOMPARE(local_file_5a.url(), QString("file:///c:/foo%3Fbar"));
242 #endif
243 
244     KUrl scummos("inf://localhost/test.txt");
245     QVERIFY(!scummos.isLocalFile());
246 }
247 
testSimpleMethods()248 void KUrlTest::testSimpleMethods() // to test parsing, mostly
249 {
250     KUrl kde("http://www.kde.org");
251     QVERIFY(kde.isValid());
252     QCOMPARE(kde.port(), -1);   // KDE3 DIFFERENCE: was 0.
253 
254     KUrl mlc("http://mlc:80/");
255     QVERIFY(mlc.isValid());
256     QCOMPARE(mlc.port(), 80);
257     QCOMPARE(mlc.path(), QString("/"));
258 
259     KUrl ulong("https://swww.gad.de:443/servlet/CookieAccepted?MAIL=s@gad.de&VER=25901");
260     QCOMPARE(ulong.host(), QString("swww.gad.de"));
261     QCOMPARE(ulong.path(), QString("/servlet/CookieAccepted"));
262 
263     // RFC 3986 section 3.5 says:
264     // fragment = *( pchar / "/" / "?" )
265     // where:
266     // pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
267     //         unreserved  = ALPHA / DIGIT / "-" / "." / "_" / "~"
268     //         pct-encoded = "%" HEXDIG HEXDIG
269     //         sub-delims  = sub-delims  = "!" / "$" / "&" / "'" / "(" / ")" /  "*" / "+" / "," / ";" / "="
270     KUrl url0;
271     url0 = QString("http://www.kde.org#/?:@-._~!$&'()*+,;="); // These fragment's chars should not be %-encoded
272     QCOMPARE(url0.ref(),     QString("/?:@-._~!$&'()*+,;="));
273     QCOMPARE(url0.htmlRef(), QString("/?:@-._~!$&'()*+,;="));
274     QCOMPARE(url0.url(), QString("http://www.kde.org#/?:@-._~!$&'()*+,;="));
275 
276     url0 = QString("http://www.kde.org#/?:@-._~!$&'()*+,;=%A");
277     QCOMPARE(url0.ref(),     QString("/?:@-._~!$&'()*+,;=%25A"));
278     QCOMPARE(url0.htmlRef(), QString("/?:@-._~!$&'()*+,;=%A"));
279     QCOMPARE(url0.url(), QString("http://www.kde.org#/?:@-._~!$&'()*+,;=%25A"));
280 
281     url0 = "http://www.kde.org/foo.cgi?4=2+2";
282     QCOMPARE(url0.url(), QString("http://www.kde.org/foo.cgi?4=2+2"));
283     url0 = "http://www.kde.org/foo.cgi?4=2%2B2";
284     QCOMPARE(url0.url(), QString("http://www.kde.org/foo.cgi?4=2%2B2"));    // %2B should not be decoded to +
285 
286     KUrl fileURL("file:///home/dfaure/myfile");
287     QCOMPARE(fileURL.url(), QString("file:///home/dfaure/myfile"));
288     QCOMPARE(fileURL.path(), QString("/home/dfaure/myfile"));
289     QVERIFY(!fileURL.hasRef());
290 
291     QString u1 = "file:/home/dfaure/my#myref";
292     KUrl url1(u1);
293     // KDE3 difference: QUrl doesn't resolve file:/ into file:///
294     QCOMPARE(url1.url(), QString("file:///home/dfaure/my#myref"));
295     QVERIFY(url1.hasRef());
296     QVERIFY(url1.hasHTMLRef());
297     QVERIFY(!url1.hasSubUrl());
298     QCOMPARE(url1.htmlRef(), QString("myref"));
299     QCOMPARE(url1.upUrl().url(), QString("file:///home/dfaure/"));
300 
301 #if 0
302     QUrl qurl = QUrl::fromEncoded("file:///home/dfaure/my#%23");
303     printf("toString = %s\n", qurl.toString().toLatin1().constData());
304     printf("toEncoded = %s\n", qurl.toEncoded().data());
305     qurl = QUrl::fromEncoded("file:///home/dfaure/my#%2f");
306     printf("toString = %s\n", qurl.toString().toLatin1().constData());
307     printf("toEncoded = %s\n", qurl.toEncoded().data());
308     qurl = QUrl::fromEncoded("file:///home/dfaure/my#/");
309     printf("toString = %s\n", qurl.toString().toLatin1().constData());
310     printf("toEncoded = %s\n", qurl.toEncoded().data());
311 #endif
312 
313     u1 = "file:///home/dfaure/my#%2f";
314     url1 = u1;
315     // KDE3: was %2f, Qt-4.0 to 4.4: #/. 4.5: %2f again. 5.0 to 5.1: #/. 5.2: %2F.
316     // (see also testQUrl)
317     QCOMPARE(url1.url(), QString("file:///home/dfaure/my#%2F"));
318     QVERIFY(url1.hasRef());
319     QVERIFY(url1.hasHTMLRef());
320     QVERIFY(!url1.hasSubUrl());
321     QCOMPARE(url1.ref().toLower(), QString("%2f"));
322     QCOMPARE(url1.encodedHtmlRef().toLower(), QString("%2f"));
323     QCOMPARE(url1.htmlRef(), QString("/"));
324 
325     u1 = "file:///home/dfaure/my#%23";
326     url1 = u1;
327     QCOMPARE(url1.url(), QString("file:///home/dfaure/my#%23"));   // KDE4: #%23. Qt 5.0/5.1 had "##", fixed in c615dcc4416.
328     QVERIFY(url1.hasRef());
329     QVERIFY(url1.hasHTMLRef());
330     QVERIFY(!url1.hasSubUrl());
331     QCOMPARE(url1.ref(), QString("%23"));
332     QCOMPARE(url1.encodedHtmlRef(), QString("%23"));
333     QCOMPARE(url1.htmlRef(), QString("#"));
334 
335     url1 = KUrl(url1, "#%6a");
336     QCOMPARE(url1.url(), QString("file:///home/dfaure/my#j"));
337     QVERIFY(url1.hasRef());
338     QVERIFY(url1.hasHTMLRef());
339     QVERIFY(!url1.hasSubUrl());
340     QCOMPARE(url1.ref(), QString("j"));
341     QCOMPARE(url1.encodedHtmlRef(), QString("j"));
342     QCOMPARE(url1.htmlRef(), QString("j"));
343 
344     url1 = KUrl(url1, "#");
345     QCOMPARE(url1.url(), QString("file:///home/dfaure/my#"));
346     QVERIFY(url1.hasRef());
347     QVERIFY(url1.hasHTMLRef());
348     QVERIFY(!url1.hasSubUrl());
349     QSTREMPTY(url1.ref());
350     QSTREMPTY(url1.encodedHtmlRef());
351     QSTREMPTY(url1.htmlRef());
352 
353     u1 = "file:///home/dfaure/my#myref";
354     url1 = u1;
355     QCOMPARE(url1.url(), QString("file:///home/dfaure/my#myref"));
356     QVERIFY(url1.hasRef());
357     QVERIFY(url1.hasHTMLRef());
358     QVERIFY(!url1.hasSubUrl());
359     QCOMPARE(url1.htmlRef(), QString("myref"));
360     QCOMPARE(url1.upUrl().url(), QString("file:///home/dfaure/"));
361 
362     u1 = "file:/opt/kde2/qt2/doc/html/showimg-main-cpp.html#QObject::connect";
363     url1 = u1;
364     QCOMPARE(url1.url(), QString("file:///opt/kde2/qt2/doc/html/showimg-main-cpp.html#QObject::connect"));
365     QVERIFY(url1.hasRef());
366     QVERIFY(url1.hasHTMLRef());
367     QVERIFY(!url1.hasSubUrl());
368     QCOMPARE(url1.ref(), QString("QObject::connect"));   // used to be %3A%3A but there's not point in encoding that here.
369     QCOMPARE(url1.htmlRef(), QString("QObject::connect"));
370     QCOMPARE(url1.upUrl().url(), QString("file:///opt/kde2/qt2/doc/html/"));
371 
372     u1 = "file:///opt/kde2/qt2/doc/html/showimg-main-cpp.html#QObject::connect";
373     url1 = u1;
374     QCOMPARE(url1.url(), QString("file:///opt/kde2/qt2/doc/html/showimg-main-cpp.html#QObject::connect"));
375     QVERIFY(url1.hasRef());
376     QVERIFY(url1.hasHTMLRef());
377     QVERIFY(!url1.hasSubUrl());
378     QCOMPARE(url1.ref(), QString("QObject::connect"));   // see above
379     QCOMPARE(url1.htmlRef(), QString("QObject::connect"));
380     QCOMPARE(url1.upUrl().url(), QString("file:///opt/kde2/qt2/doc/html/"));
381 
382     u1 = "file:/opt/kde2/qt2/doc/html/showimg-main-cpp.html#QObject:connect";
383     url1 = u1;
384     QCOMPARE(url1.url(), QString("file:///opt/kde2/qt2/doc/html/showimg-main-cpp.html#QObject:connect"));
385     QVERIFY(url1.hasRef());
386     QVERIFY(url1.hasHTMLRef());
387     QVERIFY(!url1.hasSubUrl());
388     QCOMPARE(url1.ref(), QString("QObject:connect"));   // see above
389     QCOMPARE(url1.htmlRef(), QString("QObject:connect"));
390     QCOMPARE(url1.upUrl().url(), QString("file:///opt/kde2/qt2/doc/html/"));
391 
392     KUrl carsten;
393     carsten.setPath("/home/gis/src/kde/kdelibs/kfile/.#kfiledetailview.cpp.1.18");
394     QCOMPARE(carsten.path(), QString("/home/gis/src/kde/kdelibs/kfile/.#kfiledetailview.cpp.1.18"));
395 
396     KUrl longUserName("http://thisisaverylongusername@foobar.com/");
397     QCOMPARE(longUserName.prettyUrl(), QString("http://thisisaverylongusername@foobar.com/"));
398     QCOMPARE(KUrl(longUserName.prettyUrl()).url(), QString("http://thisisaverylongusername@foobar.com/"));
399     KUrl whitespaceInUser("http://www.google.com%20%20%20%20%20@foobar.com/");
400     QCOMPARE(whitespaceInUser.prettyUrl(), QString("http://www.google.com%20%20%20%20%20@foobar.com/"));
401     KUrl whitespaceInPath("http://www.google.com/foo%20bar/");
402     QCOMPARE(whitespaceInPath.prettyUrl(), QString("http://www.google.com/foo bar/"));
403     KUrl whitespaceInPath2("http://www.google.com/foo%20%20%20%20%20%20%20bar/");
404     QCOMPARE(whitespaceInPath2.prettyUrl(), QString("http://www.google.com/foo%20%20%20%20%20%20 bar/"));
405 
406     KUrl charles;
407     charles.setPath("/home/charles/foo%20moo");
408     QCOMPARE(charles.path(), QString("/home/charles/foo%20moo"));
409     KUrl charles2("file:/home/charles/foo%20moo");
410     QCOMPARE(charles2.path(), QString("/home/charles/foo moo"));
411 
412     //NOTE this test should be ran in UTF8 locale
413     KUrl percentEncodedQuery("http://mail.yandex.ru/message_part/%D0%9A%D1%80%D0%B8%D1%82%D0%B5%D1%80%D0%B8%D0%B8%20%D0%BE%D1%86%D0%B5%D0%BD%D0%B8%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F%20%D0%BE%D1%80%D0%BB%D0%BE%D0%B2%D0%BE%D0%B9.rar?hid=1.1&mid=391.56424458.99241672611486679803334485488&name=%D0%9A%D1%80%D0%B8%D1%82%D0%B5%D1%80%D0%B8%D0%B8%20%D0%BE%D1%86%D0%B5%D0%BD%D0%B8%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F%20%D0%BE%D1%80%D0%BB%D0%BE%D0%B2%D0%BE%D0%B9.rar");
414     QCOMPARE(percentEncodedQuery.prettyUrl(), QString::fromUtf8("http://mail.yandex.ru/message_part/Критерии оценивания орловой.rar?hid=1.1&mid=391.56424458.99241672611486679803334485488&name=%D0%9A%D1%80%D0%B8%D1%82%D0%B5%D1%80%D0%B8%D0%B8%20%D0%BE%D1%86%D0%B5%D0%BD%D0%B8%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F%20%D0%BE%D1%80%D0%BB%D0%BE%D0%B2%D0%BE%D0%B9.rar"));
415 
416 #ifdef Q_OS_WIN
417 #ifdef Q_CC_MSVC
418 #pragma message ("port KUser")
419 #else
420 #warning port KUser
421 #endif
422 #else
423     KUrl tilde;
424     KUser currentUser;
425     const QString userName = currentUser.loginName();
426     QVERIFY(!userName.isEmpty());
427     tilde.setPath(QString::fromUtf8("~%1/Matériel").arg(userName));
428     QString homeDir = currentUser.homeDir();
429     QEXPECT_FAIL("", "No more user-expansion in KUrl", Continue);
430     QCOMPARE(tilde.url(), QString("file://%1/Mat%C3%A9riel").arg(homeDir));
431 
432     QUrl httpTilde("http://foo.bar/index.html");
433     httpTilde.setPath("/~slajsjdlsjd/test.html");
434     QVERIFY2(httpTilde.isValid(), qPrintable(httpTilde.errorString()));
435     QCOMPARE(httpTilde.toString(), QString("http://foo.bar/~slajsjdlsjd/test.html"));
436 #endif
437 }
438 
testHostName()439 void KUrlTest::testHostName()
440 {
441     KUrl u1("http://www.Abc.de/FR");
442     QCOMPARE(u1.host(), QString("www.abc.de")); // lowercase
443     QCOMPARE(u1.path(), QString("/FR")); // lowercase
444     QCOMPARE(u1.url(), QString("http://www.abc.de/FR")); // hostname is lowercase
445     QCOMPARE(u1.prettyUrl(), QString("http://www.abc.de/FR")); // hostname is lowercase
446 
447     KUrl u2;
448     u2.setProtocol("http");
449     u2.setHost("www.Abc.de");
450     QCOMPARE(u2.host(), QString("www.abc.de")); // lowercase
451     QCOMPARE(u2.url(), QString("http://www.abc.de")); // lowercase
452 
453     KUrl u3("donkey://Abc/DE");
454     QCOMPARE(u3.host(), QString("abc")); // lowercase
455     QCOMPARE(u3.url(), QString("donkey://abc/DE")); // lowercase
456 }
457 
testEmptyQueryOrRef()458 void KUrlTest::testEmptyQueryOrRef()
459 {
460     QUrl url = QUrl::fromEncoded("http://www.kde.org");
461     QCOMPARE(url.toEncoded(), QByteArray("http://www.kde.org"));
462     QCOMPARE(url.encodedQuery(), QByteArray());
463     url = QUrl::fromEncoded("http://www.kde.org?");
464     QCOMPARE(url.toEncoded(), QByteArray("http://www.kde.org?"));
465     QCOMPARE(url.encodedQuery(), QByteArray());   // note that QByteArray() == QByteArray("")
466 
467     url = QUrl::fromEncoded("http://www.kde.org");
468     QVERIFY(url.encodedQuery().isEmpty());
469     QVERIFY(!url.hasQuery());
470     url = QUrl::fromEncoded("http://www.kde.org?");
471     QVERIFY(!url.encodedQuery().isNull());
472     QVERIFY(url.encodedQuery().isEmpty());
473     QVERIFY(url.hasQuery());
474 
475     KUrl noQuery("http://www.kde.org");
476     QCOMPARE(noQuery.query(), QString());   // query at all
477     QVERIFY(!noQuery.hasQuery());
478     QVERIFY(!noQuery.hasRef());
479     QVERIFY(noQuery.ref().isNull());
480 
481     // Empty queries should be preserved!
482     QUrl qurl = QUrl::fromEncoded("http://www.kde.org/cgi/test.cgi?", QUrl::TolerantMode);
483     QCOMPARE(qurl.toEncoded(), QByteArray("http://www.kde.org/cgi/test.cgi?"));
484 
485     KUrl waba1("http://www.kde.org/cgi/test.cgi?");
486     QCOMPARE(waba1.url(), QString("http://www.kde.org/cgi/test.cgi?"));
487     QCOMPARE(waba1.query(), QString("?"));     // empty query
488     QVERIFY(waba1.hasQuery());
489 
490     // Empty references should be preserved
491     waba1 = "http://www.kde.org/cgi/test.cgi#";
492     QCOMPARE(waba1.url(), QString("http://www.kde.org/cgi/test.cgi#"));
493     QVERIFY(waba1.hasRef());
494     QVERIFY(waba1.hasFragment());
495     QVERIFY(waba1.hasHTMLRef());
496     QSTREMPTY(waba1.encodedHtmlRef());
497     //qurl = QUrl::fromEncoded("http://www.kde.org/cgi/test.cgi#", QUrl::TolerantMode);
498     //QCOMPARE( qurl.toEncoded(), QByteArray("http://www.kde.org/cgi/test.cgi#") );
499 
500     KUrl tobi1("http://host.net/path/?#http://broken-adsfk-poij31-029mu-2890zupyc-*!*'O-+-0i");
501     QCOMPARE(tobi1.query(), QString("?")); // query is empty
502     QVERIFY(tobi1.hasQuery());
503 
504     tobi1 = "http://host.net/path/#no-query";
505     QCOMPARE(tobi1.query(), QString("")); // no query
506     QVERIFY(!tobi1.hasQuery());
507 }
508 
testParsingTolerance()509 void KUrlTest::testParsingTolerance()
510 {
511     // URLs who forgot to encode spaces in the query - the QUrl version first
512     QUrl incorrectEncoded = QUrl::fromEncoded("http://www.kde.org/cgi/qurl.cgi?hello=My Value");
513     QVERIFY(incorrectEncoded.isValid());
514     QVERIFY(!incorrectEncoded.toEncoded().isEmpty());
515     //qDebug( "%s", incorrectEncoded.toEncoded().data() );
516     QCOMPARE(incorrectEncoded.toEncoded(),
517              QByteArray("http://www.kde.org/cgi/qurl.cgi?hello=My%20Value"));
518 
519     // URLs who forgot to encode spaces in the query.
520     KUrl waba1("http://www.kde.org/cgi/test.cgi?hello=My Value");
521     //QVERIFY( waba1.isValid() );
522     QCOMPARE(waba1.url(), QString("http://www.kde.org/cgi/test.cgi?hello=My%20Value"));
523 
524     // URL with ':' in query (':' should NOT be encoded!)
525     waba1 = "http://www.kde.org/cgi/test.cgi?hello:My Value";
526     QCOMPARE(waba1.url(), QString("http://www.kde.org/cgi/test.cgi?hello:My%20Value"));
527     QCOMPARE(waba1.upUrl().url(), QString("http://www.kde.org/cgi/test.cgi"));
528 
529     // URLs who forgot to encode spaces in the query.
530     waba1 = "http://www.kde.org/cgi/test.cgi?hello=My Value+20";
531     QCOMPARE(waba1.url(), QString("http://www.kde.org/cgi/test.cgi?hello=My%20Value+20"));
532 }
533 
testNewLine()534 void KUrlTest::testNewLine()
535 {
536     QUrl qurl_newline_1 = QUrl::fromEncoded("http://www.foo.bar/foo/bar\ngnork", QUrl::TolerantMode);
537     QVERIFY(qurl_newline_1.isValid());
538     QCOMPARE(qurl_newline_1.toEncoded(), QByteArray("http://www.foo.bar/foo/bar%0Agnork"));
539 
540     KUrl url_newline_1("http://www.foo.bar/foo/bar\ngnork");
541     QCOMPARE(url_newline_1.url(), QLatin1String("http://www.foo.bar/foo/bar%0Agnork"));
542 
543     KUrl url_newline_2("http://www.foo.bar/foo?bar\ngnork");
544     QCOMPARE(url_newline_2.url(), QLatin1String("http://www.foo.bar/foo?bar%0Agnork"));
545 }
546 
testQueryParsing()547 void KUrlTest::testQueryParsing()
548 {
549     KUrl ldap("ldap://host.com:6666/o=University%20of%20Michigan,c=US??sub?(cn=Babs%20Jensen)");
550     QCOMPARE(ldap.host(), QString("host.com"));
551     QCOMPARE(ldap.port(), 6666);
552     QCOMPARE(ldap.path(), QString("/o=University of Michigan,c=US"));
553     QCOMPARE(ldap.query(), QString("??sub?(cn=Babs%20Jensen)"));
554     QCOMPARE(ldap.url(), QString("ldap://host.com:6666/o=University%20of%20Michigan,c=US??sub?(cn=Babs%20Jensen)"));
555     ldap.setQuery("??sub?(cn=Karl%20Marx)");
556     QCOMPARE(ldap.query(), QString("??sub?(cn=Karl%20Marx)"));
557     QCOMPARE(ldap.url(), QString("ldap://host.com:6666/o=University%20of%20Michigan,c=US??sub?(cn=Karl%20Marx)"));
558 }
559 
testURLsWithoutPath()560 void KUrlTest::testURLsWithoutPath()
561 {
562     // Urls without path (BR21387)
563     KUrl waba1("http://meine.db24.de?link=home_c_login_login");   // has query
564     QCOMPARE(waba1.url(), QString("http://meine.db24.de?link=home_c_login_login"));
565     QCOMPARE(waba1.path(), QString(""));
566     QCOMPARE(waba1.query(), QString("?link=home_c_login_login"));
567 
568     waba1 = "http://a:389?b=c"; // has port and query
569     QCOMPARE(waba1.url(), QString("http://a:389?b=c"));
570     QCOMPARE(waba1.host(), QString("a"));
571     QCOMPARE(waba1.port(), 389);
572     QCOMPARE(waba1.path(), QString(""));
573     QCOMPARE(waba1.query(), QString("?b=c"));
574 
575     // Urls without path (BR21387)
576     waba1 = "http://meine.db24.de#link=home_c_login_login"; // has fragment
577     QCOMPARE(waba1.url(), QString("http://meine.db24.de#link=home_c_login_login"));
578     QCOMPARE(waba1.path(), QString(""));
579 
580     waba1 = "http://a:389#b=c"; // has port and fragment
581     //qDebug( "%s", qPrintable( waba1.url() ) );
582     QCOMPARE(waba1.scheme(), QString("http"));
583     QCOMPARE(waba1.url(), QString("http://a:389#b=c"));
584     QCOMPARE(waba1.host(), QString("a"));
585     QCOMPARE(waba1.port(), 389);
586     QCOMPARE(waba1.path(), QString(""));
587     QCOMPARE(waba1.ref(), QString("b=c"));     // see testSetRef(), this changed over time
588     QCOMPARE(waba1.htmlRef(), QString("b=c"));
589     QCOMPARE(waba1.query(), QString());
590 
591     QUrl schemeOnly("ftp:");
592     QVERIFY(schemeOnly.isValid());
593     QCOMPARE(schemeOnly.scheme(), QString("ftp"));
594 }
595 
testPathAndQuery()596 void KUrlTest::testPathAndQuery()
597 {
598 #if 0
599     // this KDE3 test fails, but Tobias Anton didn't say where it came from, and Andreas Hanssen (TT) says:
600     // "I can't see any reason to support this; it looks like a junk artifact from older days.
601     // Everything after # is the fragment. Parsing what comes after # is broken; tolerant or not."
602     KUrl tobi0("http://some.host.net/path/to/file#fragmentPrecedes?theQuery");
603     QCOMPARE(tobi0.ref(), QString("fragmentPrecedes"));
604     QCOMPARE(tobi0.query(), QString("?theQuery"));
605 #else
606     // So we treat it as part of the fragment
607     KUrl tobi0("http://some.host.net/path/to/file#foo?bar");
608     QCOMPARE(tobi0.ref(), QString("foo?bar"));   // was foo%3Fbar until KDE 4.11, but no need to encode it (Qt 5.2)
609     QCOMPARE(tobi0.query(), QString());
610     QCOMPARE(tobi0.prettyUrl(), QString("http://some.host.net/path/to/file#foo?bar"));
611 #endif
612 
613     KUrl tobi1("http://host.net/path?myfirstquery#andsomeReference");
614     tobi1.setEncodedPathAndQuery("another/path/?another&query");
615     QCOMPARE(tobi1.query(), QString("?another&query"));
616     QCOMPARE(tobi1.path(), QString("another/path/"));   // with trailing slash
617     QCOMPARE(tobi1.encodedPathAndQuery(), QString("another/path/?another&query"));
618     tobi1.setEncodedPathAndQuery("another/path?another&query");
619     QCOMPARE(tobi1.query(), QString("?another&query"));
620     QCOMPARE(tobi1.path(), QString("another/path"));   // without trailing slash
621     QCOMPARE(tobi1.encodedPathAndQuery(), QString("another/path?another&query"));
622     tobi1.setEncodedPathAndQuery("and%20another%2Bpath%2E?bug=%2B258301&query%2Bword");
623     QCOMPARE(tobi1.query(), QString("?bug=%2B258301&query%2Bword"));   // encoded
624     QCOMPARE(tobi1.queryItem("bug"), QString("+258301"));   // decoded
625     QCOMPARE(tobi1.path(), QString("and another+path."));   // decoded
626     QCOMPARE(tobi1.encodedPath().constData(), "and%20another+path.");   // from QUrl. It only encodes the space.
627     QCOMPARE(tobi1.encodedPathAndQuery(), QString("and%20another+path.?bug=%2B258301&query%2Bword"));
628 
629     tobi1 = "http://host.net/path/#no-query";
630     QCOMPARE(tobi1.encodedPathAndQuery(), QString("/path/"));
631 
632     KUrl kde("http://www.kde.org");
633     QCOMPARE(kde.encodedPathAndQuery(), QString(""));
634     QCOMPARE(kde.encodedPathAndQuery(KUrl::LeaveTrailingSlash, KUrl::AvoidEmptyPath), QString("/"));
635 
636     KUrl theKow("http://www.google.de/search?q=frerich&hlx=xx&hl=de&empty=&lr=lang+de&test=%2B%20%3A%25");
637     QCOMPARE(theKow.encodedPathAndQuery(), QString("/search?q=frerich&hlx=xx&hl=de&empty=&lr=lang+de&test=%2B%20%3A%25"));
638 
639     KUrl uloc("file:///home/dfaure/konqtests/Mat%C3%A9riel");
640     QCOMPARE(uloc.encodedPathAndQuery(), QString("/home/dfaure/konqtests/Mat%C3%A9riel"));
641 
642     KUrl urlWithAccent("file:///home/dfaure/konqtests/Matériel");
643     QCOMPARE(urlWithAccent.encodedPathAndQuery(), QString("/home/dfaure/konqtests/Mat%C3%A9riel"));
644 
645     KUrl urlWithUnicodeChar(QString::fromUtf8("file:///home/dfaure/konqtests/Matériel"));
646     QCOMPARE(urlWithUnicodeChar.encodedPathAndQuery(), QString("/home/dfaure/konqtests/Mat%C3%A9riel"));
647 
648     KUrl maelcum(QString::fromUtf8("http://a.b.c/äöu"));
649     QCOMPARE(maelcum.encodedPathAndQuery(), QString("/%C3%A4%C3%B6u"));
650 
651     // This gives an encoded path in Qt5. TODO: find again where this came from (Gof, obviously, in 2009)
652     //KUrl gof("file:%2Ftmp%2Fkde-ogoffart%2Fkmail"); // weird URL, but well ;)
653     //QCOMPARE(gof.path(), QString("/tmp/kde-ogoffart/kmail"));
654 }
655 
testUpUrl()656 void KUrlTest::testUpUrl()
657 {
658     KUrl url1("ftp://user%40host.com@ftp.host.com/var/www/");
659     QCOMPARE(url1.user(), QString("user@host.com"));
660     QCOMPARE(url1.host(), QString("ftp.host.com"));
661     KUrl up = url1.upUrl();
662     QCOMPARE(up.url(), QString("ftp://user%40host.com@ftp.host.com/var/"));
663     up = up.upUrl();
664     QCOMPARE(up.url(), QString("ftp://user%40host.com@ftp.host.com/"));
665     up = up.upUrl();
666     QCOMPARE(up.url(), QString("ftp://user%40host.com@ftp.host.com/"));   // unchanged
667 
668     // Going up from a relative url is not supported (#170695)
669     KUrl invalid("tmp");
670     QVERIFY(invalid.isValid());
671     up = invalid.upUrl();
672     QVERIFY(!up.isValid());
673 }
674 
testSetFileName()675 void KUrlTest::testSetFileName() // and addPath
676 {
677     KUrl u2("file:/home/dfaure/my%20tar%20file.tgz#gzip:/#tar:/README");
678     //qDebug( "* URL is %s", qPrintable( u2.url() ) );
679 
680     u2.setFileName("myfile.txt");
681     QCOMPARE(u2.url(), QString("file:///home/dfaure/myfile.txt"));
682     u2.setFileName("myotherfile.txt");
683     QCOMPARE(u2.url(), QString("file:///home/dfaure/myotherfile.txt"));
684 
685     // more tricky, renaming a directory (kpropertiesdialog.cc)
686     QString tmpurl = "file:/home/dfaure/myolddir/";
687     if (tmpurl.at(tmpurl.length() - 1) == '/')
688         // It's a directory, so strip the trailing slash first
689     {
690         tmpurl.truncate(tmpurl.length() - 1);
691     }
692     KUrl newUrl(tmpurl);
693     newUrl.setFileName("mynewdir");
694     QCOMPARE(newUrl.url(), QString("file:///home/dfaure/mynewdir"));
695 
696     // addPath tests
697     newUrl.addPath("subdir");
698     QCOMPARE(newUrl.url(), QString("file:///home/dfaure/mynewdir/subdir"));
699     newUrl.addPath("/foo/");
700     QCOMPARE(newUrl.url(), QString("file:///home/dfaure/mynewdir/subdir/foo/"));
701     u2 = "http://www.kde.org"; // no path
702     u2.addPath("subdir");
703     QCOMPARE(u2.url(), QString("http://www.kde.org/subdir"));
704     u2.addPath("");
705     QCOMPARE(u2.url(), QString("http://www.kde.org/subdir"));   // unchanged
706 
707     QUrl qurl2 = QUrl::fromEncoded("print:/specials/Print%20To%20File%20(PDF%252FAcrobat)", QUrl::TolerantMode);
708     QCOMPARE(qurl2.path(), QString::fromLatin1("/specials/Print To File (PDF%2FAcrobat)"));
709     QCOMPARE(qurl2.path(QUrl::PrettyDecoded), QString::fromLatin1("/specials/Print To File (PDF%252FAcrobat)"));
710     QCOMPARE(qurl2.toString(), QString::fromLatin1("print:/specials/Print To File (PDF%252FAcrobat)"));
711     QCOMPARE(qurl2.toEncoded(), QByteArray("print:/specials/Print%20To%20File%20(PDF%252FAcrobat)"));
712 
713     // even more tricky
714     u2 = "print:/specials/Print%20To%20File%20(PDF%252FAcrobat)";
715     QCOMPARE(u2.path(), QString("/specials/Print To File (PDF%2FAcrobat)"));
716     QCOMPARE(u2.fileName(), QString("Print To File (PDF%2FAcrobat)"));
717     u2.setFileName("");
718     QCOMPARE(u2.url(), QString("print:/specials/"));
719 
720     u2 = "file:/specials/Print";
721     QCOMPARE(u2.path(), QString("/specials/Print"));
722     QCOMPARE(u2.fileName(), QString("Print"));
723     u2.setFileName("");
724     QCOMPARE(u2.url(), QString("file:///specials/"));
725 
726     const char *u3 = "ftp://host/dir1/dir2/myfile.txt";
727     QVERIFY(!KUrl(u3).hasSubUrl());
728 
729     KUrl::List lst = KUrl::split(KUrl(u3));
730     QCOMPARE(lst.count(), 1);
731     QCOMPARE(lst.first().url(), QString("ftp://host/dir1/dir2/myfile.txt"));
732 
733     // cdUp code
734     KUrl lastUrl = lst.last();
735     QString dir = lastUrl.directory();
736     QCOMPARE(dir, QString("/dir1/dir2"));
737 
738     // files without directories
739     KUrl singleFile("foo.txt");
740     QCOMPARE(singleFile.path(), QString("foo.txt"));
741     QCOMPARE(singleFile.pathOrUrl(), QString("foo.txt"));
742 
743     QString pre;
744 #ifdef Q_OS_WIN
745     // On Windows we explicitly prepend a slash, see KUrl::setPath
746     pre = '/';
747 #endif
748     singleFile.setFileName("bar.bin");
749     QCOMPARE(singleFile.path(), QString(pre + "bar.bin"));
750     QCOMPARE(singleFile.pathOrUrl(), QString(pre + "bar.bin"));
751 }
752 
testDirectory()753 void KUrlTest::testDirectory()
754 {
755     KUrl udir;
756     udir.setPath("/home/dfaure/file.txt");
757     //qDebug( "URL is %s", qPrintable( udir.url() ) );
758     QCOMPARE(udir.path(), QString("/home/dfaure/file.txt"));
759     QCOMPARE(udir.url(), QString("file:///home/dfaure/file.txt"));
760     QCOMPARE(udir.directory(KUrl::AppendTrailingSlash | KUrl::ObeyTrailingSlash), QString("/home/dfaure/"));
761     QCOMPARE(udir.directory(KUrl::ObeyTrailingSlash), QString("/home/dfaure"));
762 
763     KUrl u2(QByteArray("file:///home/dfaure/"));
764     // not ignoring trailing slash
765     QCOMPARE(u2.directory(KUrl::AppendTrailingSlash | KUrl::ObeyTrailingSlash), QString("/home/dfaure/"));
766     QCOMPARE(u2.directory(KUrl::ObeyTrailingSlash), QString("/home/dfaure"));
767     // ignoring trailing slash
768     QCOMPARE(u2.directory(KUrl::AppendTrailingSlash), QString("/home/"));
769     QCOMPARE(u2.directory(), QString("/home"));
770 
771     // cleanPath() tests (before cd() since cd uses that)
772     u2.cleanPath();
773     QCOMPARE(u2.url(), QString("file:///home/dfaure/"));
774     u2.addPath("/..//foo");
775     QCOMPARE(u2.url(), QString("file:///home/dfaure/..//foo"));
776     u2 = KUrl(QByteArray("file:///home/dfaure/..//foo"));
777     QCOMPARE(u2.url(), QString("file:///home/dfaure/..//foo"));
778     u2.cleanPath(KUrl::KeepDirSeparators);
779     QCOMPARE(u2.url(), QString("file:///home//foo"));
780     u2.cleanPath(KUrl::SimplifyDirSeparators);
781     QCOMPARE(u2.url(), QString("file:///home/foo"));
782 
783     // cd() tests
784     u2.cd("..");
785     QCOMPARE(u2.url(), QString("file:///home"));
786     u2.cd("thomas");
787     QCOMPARE(u2.url(), QString("file:///home/thomas"));
788     u2.cd("../");
789     QCOMPARE(u2.url(), QString("file:///home/"));
790     u2.cd("/opt/kde/bin/");
791     QCOMPARE(u2.url(), QString("file:///opt/kde/bin/"));
792     u2 = "ftp://ftp.kde.org/";
793     u2.cd("pub");
794     QCOMPARE(u2.url(), QString("ftp://ftp.kde.org/pub"));
795     u2 = u2.upUrl();
796     QCOMPARE(u2.url(), QString("ftp://ftp.kde.org/"));
797 }
798 
testPrettyURL()799 void KUrlTest::testPrettyURL()
800 {
801     KUrl tildeInPath("http://ferret.lmh.ox.ac.uk/%7Ekdecvs/");
802     QCOMPARE(tildeInPath.prettyUrl(), QString("http://ferret.lmh.ox.ac.uk/~kdecvs/"));
803     // Tilde should not be re-encoded, see end of 2.3 in rfc3986
804     QCOMPARE(KUrl(tildeInPath.prettyUrl()).url(), QString("http://ferret.lmh.ox.ac.uk/~kdecvs/"));
805 
806     KUrl spaceInPath("file:/home/test/directory%20with%20spaces");
807     QCOMPARE(spaceInPath.prettyUrl(), QString("file:///home/test/directory with spaces"));
808     QCOMPARE(KUrl(spaceInPath.prettyUrl()).url(), QString("file:///home/test/directory%20with%20spaces"));
809 
810     KUrl plusInPath("http://slashdot.org/~RAMMS%2BEIN/"); // #232008
811     QCOMPARE(plusInPath.prettyUrl(), QString::fromLatin1("http://slashdot.org/~RAMMS+EIN/"));
812     QCOMPARE(KUrl(plusInPath.prettyUrl()).url(), QString::fromLatin1("http://slashdot.org/~RAMMS+EIN/"));
813 
814     KUrl notPretty3("fish://foo/%23README%23");
815     QCOMPARE(notPretty3.path(), QString("/#README#"));
816     QCOMPARE(notPretty3.prettyUrl(), QString("fish://foo/%23README%23"));
817 
818     KUrl url15581("http://alain.knaff.linux.lu/bug-reports/kde/spaces in url.html");
819     QCOMPARE(url15581.prettyUrl(), QString("http://alain.knaff.linux.lu/bug-reports/kde/spaces in url.html"));
820     QCOMPARE(url15581.url(), QString("http://alain.knaff.linux.lu/bug-reports/kde/spaces%20in%20url.html"));
821 
822     KUrl newLineInQuery("http://localhost/?a=foo%0A%0Abar%20baz&b=foo%0Abar%21%3F");
823     QCOMPARE(newLineInQuery.prettyUrl(), QString("http://localhost/?a=foo%0A%0Abar%20baz&b=foo%0Abar%21%3F"));
824     KUrl nonUtf8Query("http://kde.org/?a=test%C2%A0foo%A0%A0%A0%A0bar");
825     QCOMPARE(nonUtf8Query.prettyUrl(), QString("http://kde.org/?a=test%C2%A0foo%A0%A0%A0%A0bar"));
826 
827     // KDE3 test was for parsing "percentage%in%url.html", but this is not supported; too broken.
828     KUrl url15581bis("http://alain.knaff.linux.lu/bug-reports/kde/percentage%25in%25url.html");
829     QCOMPARE(url15581bis.prettyUrl(), QString("http://alain.knaff.linux.lu/bug-reports/kde/percentage%25in%25url.html"));
830     QCOMPARE(url15581bis.url(), QString("http://alain.knaff.linux.lu/bug-reports/kde/percentage%25in%25url.html"));
831 
832     KUrl urlWithPass("ftp://user:password@ftp.kde.org/path");
833     QCOMPARE(urlWithPass.pass(), QString::fromLatin1("password"));
834     QCOMPARE(urlWithPass.prettyUrl(), QString::fromLatin1("ftp://user@ftp.kde.org/path"));
835 
836     KUrl urlWithPassAndNoUser("ftp://:password@ftp.kde.org/path");
837     QCOMPARE(urlWithPassAndNoUser.pass(), QString::fromLatin1("password"));
838     QCOMPARE(urlWithPassAndNoUser.prettyUrl(), QString::fromLatin1("ftp://ftp.kde.org/path"));
839 
840     KUrl xmppUri("xmpp:ogoffart@kde.org");
841     QCOMPARE(xmppUri.path(), QString::fromLatin1("ogoffart@kde.org"));
842     QCOMPARE(xmppUri.prettyUrl(), QString::fromLatin1("xmpp:ogoffart@kde.org"));
843 
844     QUrl offEagleqUrl;
845     offEagleqUrl.setEncodedUrl("http://www.sejlsport.dk/Pr%F8v%20noget%20nyt%20dokumenter.pdf", QUrl::TolerantMode);
846     const QString offEaglePath = offEagleqUrl.path();
847     QCOMPARE((int)offEaglePath.at(2).unicode(), (int)'r');
848 #if 0 // CURRENTLY BROKEN, PENDING PRETTYURL REWRITE AND QT-4.5 (in thiago's hands)
849     QCOMPARE((int)offEaglePath.at(3).unicode(), (int)0xf8);
850 
851     KUrl offEagle("http://www.sejlsport.dk/graphics/ds/DSUngdom/PDF/Pr%F8v%20noget%20nyt%20dokumenter/Invitation_Kerteminde_11.07.08.pdf");
852     QCOMPARE(offEagle.path(), QString::fromLatin1("/graphics/ds/DSUngdom/PDF/Pr%F8v noget nyt dokumenter/Invitation_Kerteminde_11.07.08.pdf"));
853     QCOMPARE(offEagle.url(), QString::fromLatin1("http://www.sejlsport.dk/graphics/ds/DSUngdom/PDF/Pr%F8v%20noget%20nyt%20dokumenter/Invitation_Kerteminde_11.07.08.pdf"));
854     QCOMPARE(offEagle.prettyUrl(), QString::fromLatin1("http://www.sejlsport.dk/graphics/ds/DSUngdom/PDF/Pr%F8v noget nyt dokumenter/Invitation_Kerteminde_11.07.08.pdf"));
855 #endif
856 
857     KUrl openWithUrl("kate --use %25U");
858     QCOMPARE(openWithUrl.url(), QString::fromLatin1("kate%20--use%20%25U"));
859     QCOMPARE(openWithUrl.prettyUrl(), QString::fromLatin1("kate --use %25U"));
860     QCOMPARE(openWithUrl.path(), QString::fromLatin1("kate --use %U"));
861     QCOMPARE(openWithUrl.pathOrUrl(), QString::fromLatin1("kate --use %25U")); // caused #153894; better not use KUrl for this.
862 
863     KUrl ipv6Address("http://[::ffff:129.144.52.38]:81/index.html");
864     QCOMPARE(ipv6Address.prettyUrl(), QString::fromLatin1("http://[::ffff:129.144.52.38]:81/index.html"));
865 }
866 
testIsRelative()867 void KUrlTest::testIsRelative()
868 {
869     QVERIFY(!KUrl::isRelativeUrl("man:mmap"));
870     QVERIFY(!KUrl::isRelativeUrl("javascript:doSomething()"));
871     QVERIFY(!KUrl::isRelativeUrl("file:///blah"));
872     // arguable, but necessary for KUrl( baseURL, "//www1.foo.bar" );
873     QVERIFY(KUrl::isRelativeUrl("/path"));
874     QVERIFY(KUrl::isRelativeUrl("something"));
875 
876     KUrl something("something");
877     QCOMPARE(something.url(), QString("something"));
878     QCOMPARE(something.protocol(), QString());
879     QVERIFY(!something.isLocalFile());
880 
881     // Now let's test QUrl::isRelative.
882     QVERIFY(!KUrl("file:///blah").isRelative());
883     QVERIFY(!KUrl("/blah").isRelative());
884     QVERIFY(KUrl("blah").isRelative());
885     QVERIFY(!KUrl("http://www.kde.org").isRelative());
886     QVERIFY(KUrl("foo/bar").isRelative());
887 }
888 
testRelativePath()889 void KUrlTest::testRelativePath()
890 {
891     QString basePath = "/home/bastian";
892 
893     QCOMPARE(KUrl::relativePath(basePath, "/home/bastian"), QString("./"));
894     bool b;
895     QCOMPARE(KUrl::relativePath(basePath, "/home/bastian/src/plugins", &b), QString("./src/plugins"));
896     QVERIFY(b);
897     QCOMPARE(KUrl::relativePath(basePath, "./src/plugins"), QString("./src/plugins"));
898     QCOMPARE(KUrl::relativePath(basePath, "/home/waba/src/plugins", &b), QString("../waba/src/plugins"));
899     QVERIFY(!b);
900     QCOMPARE(KUrl::relativePath(basePath, "/"), QString("../../"));
901 
902     QCOMPARE(KUrl::relativePath("/", "/"), QString("./"));
903     QCOMPARE(KUrl::relativePath("/", "/home/bastian"), QString("./home/bastian"));
904     QCOMPARE(KUrl::relativePath("", "/home/bastian"), QString("/home/bastian"));
905 }
906 
testRelativeURL()907 void KUrlTest::testRelativeURL()
908 {
909     KUrl baseURL("http://www.kde.org/index.html");
910     QCOMPARE(KUrl::relativeUrl(baseURL, KUrl("http://www.kde.org/index.html#help")), QString("#help"));
911     QCOMPARE(KUrl::relativeUrl(baseURL, KUrl("http://www.kde.org/index.html?help=true")), QString("index.html?help=true"));
912     QCOMPARE(KUrl::relativeUrl(baseURL, KUrl("http://www.kde.org/contact.html")), QString("contact.html"));
913     QCOMPARE(KUrl::relativeUrl(baseURL, KUrl("ftp://ftp.kde.org/pub/kde")), QString("ftp://ftp.kde.org/pub/kde"));
914     QCOMPARE(KUrl::relativeUrl(baseURL, KUrl("http://www.kde.org/index.html")), QString("./"));
915 
916     baseURL = "http://www.kde.org/info/index.html";
917     QCOMPARE(KUrl::relativeUrl(baseURL, KUrl("http://www.kde.org/bugs/contact.html")), QString("../bugs/contact.html"));
918 
919     baseURL = "ftp://ftp.kde.org/info/";
920     QCOMPARE(KUrl::relativeUrl(baseURL, KUrl("ftp://ftp.kde.org/info/contact.html")), QString("contact.html"));
921     QCOMPARE(KUrl::relativeUrl(baseURL, KUrl("ftp://ftp.kde.org/info/A%20%20B.txt")), QString("A%20%20B.txt"));
922 }
923 
testAdjustPath()924 void KUrlTest::testAdjustPath()
925 {
926     KUrl url0("file:///");
927     QCOMPARE(url0.url(KUrl::RemoveTrailingSlash), QString("file:///"));
928     url0.adjustPath(KUrl::RemoveTrailingSlash);
929     QCOMPARE(url0.url(), QString("file:///"));
930 
931     KUrl url1("file:///home/kde/");
932     url1.adjustPath(KUrl::LeaveTrailingSlash);
933     QCOMPARE(url1.path(), QString("/home/kde/"));
934     url1.adjustPath(KUrl::RemoveTrailingSlash);
935     QCOMPARE(url1.path(), QString("/home/kde"));
936     url1.adjustPath(KUrl::RemoveTrailingSlash);
937     QCOMPARE(url1.path(), QString("/home/kde"));
938     url1.adjustPath(KUrl::AddTrailingSlash);
939     QCOMPARE(url1.path(), QString("/home/kde/"));
940 
941     KUrl url2("file:///home/kde//");
942     url2.adjustPath(KUrl::LeaveTrailingSlash);
943     QCOMPARE(url2.path(), QString("/home/kde//"));
944     url2.adjustPath(KUrl::RemoveTrailingSlash);
945     QCOMPARE(url2.path(), QString("/home/kde"));
946     url2.adjustPath(KUrl::AddTrailingSlash);
947     QCOMPARE(url2.path(), QString("/home/kde/"));
948 
949     KUrl ftpurl1("ftp://ftp.kde.org/");
950     ftpurl1.adjustPath(KUrl::LeaveTrailingSlash);
951     QCOMPARE(ftpurl1.path(), QString("/"));
952     ftpurl1.adjustPath(KUrl::RemoveTrailingSlash);
953     QCOMPARE(ftpurl1.path(), QString("/"));
954 
955     KUrl ftpurlNoPath("ftp://ftp.kde.org"); // #312060
956     QCOMPARE(ftpurlNoPath.path(), QString());
957     ftpurlNoPath.adjustPath(KUrl::LeaveTrailingSlash);
958     QCOMPARE(ftpurlNoPath.path(), QString());
959     ftpurlNoPath.adjustPath(KUrl::AddTrailingSlash);
960     QCOMPARE(ftpurlNoPath.path(), QString());
961     ftpurlNoPath.adjustPath(KUrl::RemoveTrailingSlash);
962     QCOMPARE(ftpurlNoPath.path(), QString());
963 
964     KUrl ftpurl2("ftp://ftp.kde.org///");
965     ftpurl2.adjustPath(KUrl::LeaveTrailingSlash);
966     QCOMPARE(ftpurl2.path(), QString("///"));
967     ftpurl2.adjustPath(KUrl::RemoveTrailingSlash); // should remove all but trailing slash
968     QCOMPARE(ftpurl2.path(), QString("/"));
969     ftpurl2.adjustPath(KUrl::AddTrailingSlash);
970     QCOMPARE(ftpurl2.path(), QString("/"));
971 
972     // Equivalent tests written by the KDirLister maintainer :)
973 
974     KUrl u3(QByteArray("ftp://brade@ftp.kde.org///"));
975     u3.adjustPath(KUrl::RemoveTrailingSlash);
976     QCOMPARE(u3.url(), QString("ftp://brade@ftp.kde.org/"));
977 
978     KUrl u4(QByteArray("ftp://brade@ftp.kde.org/kde///"));
979     u4.adjustPath(KUrl::RemoveTrailingSlash);
980     QCOMPARE(u4.url(), QString("ftp://brade@ftp.kde.org/kde"));
981 
982     // applying adjustPath(KUrl::RemoveTrailingSlash) twice should not yield two different urls
983     // (follows from the above test)
984     KUrl u5 = u4;
985     u5.adjustPath(KUrl::RemoveTrailingSlash);
986     QCOMPARE(u5.url(), u4.url());
987 
988     {
989         KUrl remote("remote:/");
990         QCOMPARE(remote.url(KUrl::RemoveTrailingSlash), QString("remote:/"));
991         remote.adjustPath(KUrl::RemoveTrailingSlash);
992         QCOMPARE(remote.url(), QString("remote:/"));
993         remote.adjustPath(KUrl::RemoveTrailingSlash);
994         QCOMPARE(remote.url(), QString("remote:/"));
995     }
996 
997     {
998         KUrl remote2("remote://");
999         QCOMPARE(remote2.url(), QString("remote://"));
1000         QCOMPARE(remote2.url(KUrl::RemoveTrailingSlash), QString("remote://"));
1001         QCOMPARE(QUrl(remote2).toString(QUrl::StripTrailingSlash), QString("remote://"));
1002     }
1003 }
1004 
testIPV6()1005 void KUrlTest::testIPV6()
1006 {
1007     // IPV6
1008     KUrl waba1("http://[::FFFF:129.144.52.38]:81/index.html");
1009     QCOMPARE(waba1.host(), QString("::ffff:129.144.52.38"));
1010     QCOMPARE(waba1.port(), 81);
1011 
1012     // IPV6
1013     waba1 = "http://waba:pass@[::FFFF:129.144.52.38]:81/index.html";
1014     QCOMPARE(waba1.host(), QString("::ffff:129.144.52.38"));
1015     QCOMPARE(waba1.user(), QString("waba"));
1016     QCOMPARE(waba1.pass(), QString("pass"));
1017     QCOMPARE(waba1.port(), 81);
1018 
1019     // IPV6
1020     waba1 = "http://www.kde.org/cgi/test.cgi";
1021     waba1.setHost("::ffff:129.144.52.38");
1022     QCOMPARE(waba1.url(), QString("http://[::ffff:129.144.52.38]/cgi/test.cgi"));
1023     waba1 = "http://[::ffff:129.144.52.38]/cgi/test.cgi";
1024     QVERIFY(waba1.isValid());
1025 
1026     // IPV6 without path
1027     waba1 = "http://[::ffff:129.144.52.38]?query";
1028     QVERIFY(waba1.isValid());
1029     QCOMPARE(waba1.url(), QString("http://[::ffff:129.144.52.38]?query"));
1030     QCOMPARE(waba1.query(), QString("?query"));
1031     waba1 = "http://[::ffff:129.144.52.38]#ref";
1032     QVERIFY(waba1.isValid());
1033     QCOMPARE(waba1.url(), QString("http://[::ffff:129.144.52.38]#ref"));
1034     QCOMPARE(waba1.ref(), QString("ref"));
1035     // IPV6 without path but with a port
1036     waba1 = "http://[::ffff:129.144.52.38]:81?query";
1037     QVERIFY(waba1.isValid());
1038     QCOMPARE(waba1.url(), QString("http://[::ffff:129.144.52.38]:81?query"));
1039     QCOMPARE(waba1.port(), 81);
1040     QCOMPARE(waba1.query(), QString("?query"));
1041     waba1 = "http://[::ffff:129.144.52.38]:81#ref";
1042     QVERIFY(waba1.isValid());
1043     QCOMPARE(waba1.url(), QString("http://[::ffff:129.144.52.38]:81#ref"));
1044     QCOMPARE(waba1.port(), 81);
1045     QCOMPARE(waba1.ref(), QString("ref"));
1046 
1047     KUrl weird("http://[::fff:1:23]/");
1048     QVERIFY(weird.isValid());
1049     QCOMPARE(weird.host(), QString("::fff:1:23"));
1050 }
1051 
testBaseURL()1052 void KUrlTest::testBaseURL() // those are tests for the KUrl(base,relative) constructor
1053 {
1054     KUrl com1(KUrl("http://server.com/dir/"), ".");
1055     QCOMPARE(com1.url(), QString("http://server.com/dir/"));
1056 
1057     KUrl com2(KUrl("http://server.com/dir/blubb/"), "blah/");
1058     QCOMPARE(com2.url(), QString("http://server.com/dir/blubb/blah/"));
1059 
1060     KUrl baseURL("http://www.foo.bar:80");
1061     QVERIFY(baseURL.isValid());
1062     QCOMPARE(baseURL.protocol(), QString("http"));     // lowercase
1063     QCOMPARE(baseURL.port(), 80);
1064 
1065     QString relativeUrl = "//www1.foo.bar";
1066     QVERIFY(KUrl::isRelativeUrl(relativeUrl));
1067 
1068     // Mimick what KUrl(2 urls) does:
1069     QUrl qurl("http://www.foo.bar:80");
1070     QCOMPARE(QString::fromLatin1(qurl.toEncoded()), QString::fromLatin1("http://www.foo.bar:80"));
1071     QCOMPARE(qurl.port(), 80);
1072 
1073     qurl.setHost(QString());
1074     qurl.setPath(QString());
1075     QCOMPARE(qurl.port(), 80);
1076     QCOMPARE(QString(qurl.toEncoded()), QString("http:"));   // a port without a host isn't really useful
1077     qurl.setPort(-1);
1078     QCOMPARE(QString(qurl.toEncoded()), QString("http:"));   // hmm we have no '//' anymore
1079 
1080     KUrl url1(baseURL, relativeUrl);
1081     QCOMPARE(url1.url(), QString("http://www1.foo.bar"));
1082     QCOMPARE(url1.host(), QString("www1.foo.bar"));
1083 
1084     baseURL = "http://www.foo.bar";
1085     KUrl rel_url(baseURL, "/top//test/../test1/file.html");
1086     QCOMPARE(rel_url.url(), QString("http://www.foo.bar/top//test1/file.html"));
1087 
1088     baseURL = "http://www.foo.bar/top//test2/file2.html";
1089     QCOMPARE(baseURL.url(), QString("http://www.foo.bar/top//test2/file2.html"));
1090 
1091     baseURL = "file:/usr/local/src/kde2/////kdelibs/kio";
1092     QCOMPARE(baseURL.url(), QString("file:///usr/local/src/kde2/////kdelibs/kio"));
1093 
1094     baseURL = "http://www.foo.bar";
1095     KUrl rel_url2(baseURL, "mailto:bastian@kde.org");
1096     QCOMPARE(rel_url2.url(), QString("mailto:bastian@kde.org"));
1097 
1098     baseURL = "file:/usr/local/src/kde2/kdelibs/kio/";
1099     KUrl url2(baseURL, "../../////kdebase/konqueror");
1100     QCOMPARE( url2.url(), QString("file:///usr/local/src/kde2/////kdebase/konqueror" ));
1101 
1102 
1103     // WABA: The following tests are to test the handling of relative URLs as
1104     //       found on web-pages.
1105 
1106     KUrl waba1("http://www.website.com/directory/?hello#ref");
1107     {
1108         KUrl waba2(waba1, "relative.html");
1109         QCOMPARE(waba2.url(), QString("http://www.website.com/directory/relative.html"));
1110     }
1111     {
1112         KUrl waba2(waba1, "../relative.html");
1113         QCOMPARE(waba2.url(), QString("http://www.website.com/relative.html"));
1114     }
1115     {
1116         KUrl waba2(waba1, "down/relative.html");
1117         QCOMPARE(waba2.url(), QString("http://www.website.com/directory/down/relative.html"));
1118     }
1119     {
1120         KUrl waba2(waba1, "/down/relative.html");
1121         QCOMPARE(waba2.url(), QString("http://www.website.com/down/relative.html"));
1122     }
1123     {
1124         KUrl waba2(waba1, "//www.kde.org/relative.html");
1125         QCOMPARE(waba2.url(), QString("http://www.kde.org/relative.html"));
1126     }
1127     {
1128         KUrl waba2(waba1, "relative.html?query=test&name=harry");
1129         QCOMPARE(waba2.url(), QString("http://www.website.com/directory/relative.html?query=test&name=harry"));
1130         waba2.removeQueryItem("query");
1131         QCOMPARE(waba2.url(), QString("http://www.website.com/directory/relative.html?name=harry"));
1132         waba2.addQueryItem("age", "18");
1133         QCOMPARE(waba2.url(), QString("http://www.website.com/directory/relative.html?name=harry&age=18"));
1134         waba2.addQueryItem("age", "21");
1135         QCOMPARE(waba2.url(), QString("http://www.website.com/directory/relative.html?name=harry&age=18&age=21"));
1136         waba2.addQueryItem("fullname", "Harry Potter");
1137         QCOMPARE(waba2.url(), QString("http://www.website.com/directory/relative.html?name=harry&age=18&age=21&fullname=Harry%20Potter"));
1138     }
1139     {
1140         KUrl waba2(waba1, "?query=test&name=harry");
1141         QCOMPARE(waba2.url(), QString("http://www.website.com/directory/?query=test&name=harry"));
1142     }
1143     {
1144         KUrl waba2(waba1, "relative.html#with_reference");
1145         QCOMPARE(waba2.url(), QString("http://www.website.com/directory/relative.html#with_reference"));
1146     }
1147 
1148     {
1149         KUrl waba2(waba1, "#");
1150         QCOMPARE(waba2.url(), QString("http://www.website.com/directory/?hello#"));
1151     }
1152     {
1153         KUrl waba2(waba1, "");
1154         QCOMPARE(waba2.url(), QString("http://www.website.com/directory/?hello#ref"));
1155     }
1156     {
1157         KUrl waba2(waba1, "#%72%22method");  // #243217
1158         QCOMPARE(waba2.url(), QString("http://www.website.com/directory/?hello#r%22method"));
1159     }
1160     {
1161         KUrl base("http://faure@www.kde.org");   // no path
1162         KUrl waba2(base, "filename.html");
1163         QCOMPARE(waba2.url(), QString("http://faure@www.kde.org/filename.html"));
1164     }
1165     {
1166         KUrl base("http://faure:pass@www.kde.org:81?query");
1167         KUrl rel1(base, "http://www.kde.org/bleh/");  // same host
1168         QCOMPARE(rel1.url(), QString("http://faure:pass@www.kde.org/bleh/"));
1169         KUrl rel2(base, "http://www.yahoo.org");  // different host
1170         QCOMPARE(rel2.url(), QString("http://www.yahoo.org"));
1171     }
1172 
1173     waba1 = "http://www.website.com/directory/filename?bla#blub";
1174     {
1175         KUrl waba2(waba1, "relative.html");
1176         QCOMPARE(waba2.url(), QString("http://www.website.com/directory/relative.html"));
1177     }
1178     {
1179         KUrl waba2(waba1, "./relative.html");
1180         QCOMPARE(waba2.url(), QString("http://www.website.com/directory/relative.html"));
1181     }
1182     {
1183         KUrl waba2(waba1, "../relative.html");
1184         QCOMPARE(waba2.url(), QString("http://www.website.com/relative.html"));
1185     }
1186     {
1187         KUrl waba2(waba1, "down/relative.html");
1188         QCOMPARE(waba2.url(), QString("http://www.website.com/directory/down/relative.html"));
1189     }
1190     {
1191         KUrl waba2(waba1, "down/./relative.html");
1192         QCOMPARE(waba2.url(), QString("http://www.website.com/directory/down/relative.html"));
1193     }
1194     {
1195         KUrl waba2(waba1, "/down/relative.html");
1196         QCOMPARE(waba2.url(), QString("http://www.website.com/down/relative.html"));
1197     }
1198     {
1199         KUrl waba2(waba1, "relative.html?query=test&name=harry");
1200         QCOMPARE(waba2.url(), QString("http://www.website.com/directory/relative.html?query=test&name=harry"));
1201     }
1202     {
1203         KUrl waba2(waba1, "?query=test&name=harry");
1204         QCOMPARE(waba2.url(), QString("http://www.website.com/directory/filename?query=test&name=harry"));
1205     }
1206     {
1207         KUrl waba2(waba1, "relative.html#with_reference");
1208         QCOMPARE(waba2.url(), QString("http://www.website.com/directory/relative.html#with_reference"));
1209     }
1210     {
1211         KUrl waba2(waba1, "http:/relative.html");  // "rfc 1606 loophole"
1212         QCOMPARE(waba2.url(), QString("http://www.website.com/relative.html"));
1213     }
1214     waba1.setUser("waldo");
1215     QCOMPARE(waba1.url(), QString("http://waldo@www.website.com/directory/filename?bla#blub"));
1216     waba1.setUser("waldo/bastian");
1217     QCOMPARE(waba1.url(), QString("http://waldo%2Fbastian@www.website.com/directory/filename?bla#blub"));
1218     waba1.setRef(QString());
1219     waba1.setPass("pass");
1220     waba1.setDirectory("/foo");
1221     waba1.setProtocol("https");
1222     waba1.setHost("web.com");
1223     waba1.setPort(881);
1224     QCOMPARE(waba1.url(), QString("https://waldo%2Fbastian:pass@web.com:881/foo/?bla"));
1225     waba1.setDirectory("/foo/");
1226     QCOMPARE(waba1.url(), QString("https://waldo%2Fbastian:pass@web.com:881/foo/?bla"));
1227 
1228     QUrl sadEagleTest;
1229     sadEagleTest.setEncodedUrl("http://www.calorieking.com/foo.php?P0=[2006-3-8]", QUrl::TolerantMode);
1230     QVERIFY(sadEagleTest.isValid());
1231     KUrl sadEagleExpectedResult("http://www.calorieking.com/personal/diary/rpc.php?C=jsrs1&F=getDiaryDay&P0=[2006-3-8]&U=1141858921458");
1232     QVERIFY(sadEagleExpectedResult.isValid());
1233     KUrl sadEagleBase("http://www.calorieking.com/personal/diary/");
1234     QVERIFY(sadEagleBase.isValid());
1235     KUrl sadEagleCombined(sadEagleBase, "/personal/diary/rpc.php?C=jsrs1&F=getDiaryDay&P0=[2006-3-8]&U=1141858921458");
1236     QCOMPARE(sadEagleCombined.url(), sadEagleExpectedResult.url());
1237 
1238     KUrl dxOffEagle(KUrl("http://something/other.html"), "newpage.html?[{\"foo: bar\"}]");
1239     QVERIFY(dxOffEagle.isValid());
1240     QCOMPARE(dxOffEagle.url(), QString("http://something/newpage.html?[%7B%22foo:%20bar%22%7D]"));
1241     QCOMPARE(dxOffEagle.prettyUrl(), QString("http://something/newpage.html?[%7B%22foo:%20bar%22%7D]"));
1242 
1243     // QtSw issue 243557
1244     QByteArray tsdgeos("http://google.com/c?c=Translation+%C2%BB+trunk|");
1245     QUrl tsdgeosQUrl;
1246     tsdgeosQUrl.setEncodedUrl(tsdgeos, QUrl::TolerantMode);
1247     QVERIFY(tsdgeosQUrl.isValid()); // failed in Qt-4.4, works in Qt-4.5
1248     QByteArray tsdgeosExpected("http://google.com/c?c=Translation+%C2%BB+trunk%7C");
1249     //QCOMPARE(tsdgeosQUrl.toEncoded(), tsdgeosExpected); // unusable output from qtestlib...
1250     QCOMPARE(QString(tsdgeosQUrl.toEncoded()), QString(tsdgeosExpected));
1251 
1252     KUrl tsdgeosUrl(tsdgeos);
1253     QCOMPARE(tsdgeosUrl.url(), QString(tsdgeosExpected));
1254 
1255     QByteArray pipesAgain("http://translate.google.com/translate_t#en|uk|demo");
1256     QUrl pipesUrl;
1257     pipesUrl.setEncodedUrl(pipesAgain, QUrl::TolerantMode);
1258     QVERIFY(pipesUrl.isValid());
1259     QCOMPARE(QString(pipesUrl.toEncoded()), QString("http://translate.google.com/translate_t#en%7Cuk%7Cdemo"));
1260 
1261     // Shows up in nspluginviewer/flash
1262     QString flashRel = "javascript:window.location+\"__flashplugin_unique__\"";
1263     KUrl flashUrl(flashRel);
1264     QVERIFY(flashUrl.isValid());
1265     KUrl flashBase("http://www.youtube.com/?v=JvOSnRD5aNk");
1266     KUrl flashComposed(flashBase, flashRel);
1267     QCOMPARE(flashComposed.url(), QString("javascript:window.location+%22__flashplugin_unique__%22"));
1268 }
1269 
testSetEncodedFragment_data()1270 void KUrlTest::testSetEncodedFragment_data()
1271 {
1272     QTest::addColumn<QByteArray>("base");
1273     QTest::addColumn<QByteArray>("fragment");
1274     QTest::addColumn<QByteArray>("expected");
1275     typedef QByteArray BA;
1276     QTest::newRow("basic test") << BA("http://www.kde.org") << BA("abc") << BA("http://www.kde.org#abc");
1277     QTest::newRow("initial url has fragment") << BA("http://www.kde.org#old") << BA("new") << BA("http://www.kde.org#new");
1278     QTest::newRow("encoded fragment") << BA("http://www.kde.org") << BA("a%20c") << BA("http://www.kde.org#a%20c");
1279     QTest::newRow("with #") << BA("http://www.kde.org") << BA("a#b") << BA("http://www.kde.org#a%23b"); // see c615dcc4416 in qtbase
1280     QTest::newRow("empty") << BA("http://www.kde.org") << BA("") << BA("http://www.kde.org#");
1281 }
1282 
testSetEncodedFragment()1283 void KUrlTest::testSetEncodedFragment()
1284 {
1285     // Bug fixed in 4.5.1 by Thiago
1286 #if QT_VERSION < 0x040501
1287     QSKIP("Bug in Qt-4.4/4.5-rc1: setEncodedFragment doesn't work if the initial url has no fragment");
1288 #endif
1289 
1290     QFETCH(QByteArray, base);
1291     QFETCH(QByteArray, fragment);
1292     QFETCH(QByteArray, expected);
1293     QUrl u;
1294     u.setEncodedUrl(base, QUrl::TolerantMode);
1295     QVERIFY(u.isValid());
1296     u.setEncodedFragment(fragment);
1297     QVERIFY(u.isValid());
1298     QCOMPARE(QString::fromLatin1(u.toEncoded()), QString::fromLatin1(expected));
1299 }
1300 
testSubURL()1301 void KUrlTest::testSubURL()
1302 {
1303     QString u1 = "file:/home/dfaure/my%20tar%20file.tgz#gzip:/#tar:/#myref";
1304     KUrl url1(u1);
1305     // KDE3: was #,#,#, Qt-4.0 to 4.4: #,%23,%23 . 4.5, 5.0, 5.1: #,#,#
1306     // Qt 5.2: #, %23, %23, see c615dcc441 in qtbase for the reasoning. We don't use sub urls anymore anyway.
1307     QCOMPARE(url1.url(), QString("file:///home/dfaure/my%20tar%20file.tgz#gzip:/%23tar:/%23myref"));
1308     QVERIFY(url1.hasRef());
1309     QVERIFY(!url1.isLocalFile());    // Not strictly local!
1310     QVERIFY(url1.hasSubUrl());
1311     //QCOMPARE( url1.htmlRef(), QString("myref") );
1312     QCOMPARE(url1.upUrl().url(), QString("file:///home/dfaure/"));
1313 
1314     const KUrl::List splitList = KUrl::split(url1);
1315     QCOMPARE(splitList.count(), 3);
1316     //kDebug() << splitList.toStringList();
1317     QCOMPARE(splitList[0].url(), QString("file:///home/dfaure/my%20tar%20file.tgz#myref"));
1318     QCOMPARE(splitList[1].url(), QString("gzip:/#myref"));
1319     QCOMPARE(splitList[2].url(), QString("tar:/#myref"));
1320 
1321     KUrl rejoined = KUrl::join(splitList);
1322     QCOMPARE(rejoined.url(), url1.url());
1323 
1324     u1 = "error:/?error=14&errText=Unknown%20host%20asdfu.adgi.sdfgoi#http://asdfu.adgi.sdfgoi";
1325     url1 = u1;
1326     QCOMPARE(url1.url(), QString("error:/?error=14&errText=Unknown%20host%20asdfu.adgi.sdfgoi#http://asdfu.adgi.sdfgoi"));
1327     QVERIFY(url1.hasSubUrl());
1328     QVERIFY(url1.hasRef());
1329     QVERIFY(!url1.isLocalFile());
1330     QVERIFY(!url1.hasHTMLRef());
1331 
1332     u1 = "file:/home/dfaure/my%20tar%20file.tgz#gzip:/#tar:/";
1333     url1 = u1;
1334     QCOMPARE(url1.url(), QString("file:///home/dfaure/my%20tar%20file.tgz#gzip:/%23tar:/"));
1335     QVERIFY(url1.hasRef());
1336     QVERIFY(!url1.hasHTMLRef());
1337     QVERIFY(url1.hasSubUrl());
1338     QVERIFY(url1.htmlRef().isNull());
1339     QCOMPARE(url1.upUrl().url(), QString("file:///home/dfaure/"));
1340 
1341     u1 = "file:///home/dfaure/my%20tar%20file.tgz#gzip:/#tar:/";
1342     url1 = u1;
1343     QCOMPARE(url1.url(), QString("file:///home/dfaure/my%20tar%20file.tgz#gzip:/%23tar:/"));
1344     QVERIFY(url1.hasRef());
1345     QVERIFY(!url1.hasHTMLRef());
1346     QVERIFY(url1.hasSubUrl());
1347     QVERIFY(url1.htmlRef().isNull());
1348     QCOMPARE(url1.upUrl().url(), QString("file:///home/dfaure/"));
1349 
1350     u1 = "file:/home/dfaure/my%20tar%20file.tgz#gzip:/#tar:/README";
1351     url1 = u1;
1352     QCOMPARE(url1.url(), QString("file:///home/dfaure/my%20tar%20file.tgz#gzip:/%23tar:/README"));
1353     QVERIFY(url1.hasRef());
1354     QVERIFY(!url1.hasHTMLRef());
1355     QVERIFY(url1.hasSubUrl());
1356     QVERIFY(url1.htmlRef().isNull());
1357     const KUrl::List url1Splitted = KUrl::split(url1);
1358     QCOMPARE(url1Splitted.count(), 3);
1359     //kDebug() << url1Splitted.toStringList();
1360     QCOMPARE(url1Splitted[0].url(), QString("file:///home/dfaure/my%20tar%20file.tgz"));
1361     QCOMPARE(url1Splitted[1].url(), QString("gzip:/"));
1362     QCOMPARE(url1Splitted[2].url(), QString("tar:/README"));
1363     const KUrl url1Rejoined = KUrl::join(url1Splitted);
1364     QCOMPARE(url1Rejoined.url(), url1.url());
1365     QCOMPARE(url1.upUrl().url(), QString("file:///home/dfaure/my%20tar%20file.tgz#gzip:/%23tar:/"));
1366 
1367 }
1368 
testSetUser()1369 void KUrlTest::testSetUser()
1370 {
1371     // The KUrl equality test below works because in Qt4 null == empty.
1372     QString str1;
1373     QString str2 = "";
1374     QVERIFY(str1 == str2);
1375 
1376     KUrl emptyUserTest1("http://www.foobar.com/");
1377     QVERIFY(emptyUserTest1.user().isEmpty());
1378     QVERIFY(emptyUserTest1.user().isNull());   // Expected result. This was fixed in Qt-4.4
1379 
1380     KUrl emptyUserTest2("http://www.foobar.com/");
1381     emptyUserTest2.setUser("");
1382     //QVERIFY( emptyUserTest2.user().isNull() );
1383     // Qt 5 allows a "set but empty" username, as per the RFC.
1384     QCOMPARE(emptyUserTest2.url(), QString("http://@www.foobar.com/"));
1385     QVERIFY(emptyUserTest1 != emptyUserTest2);
1386 
1387     // Parsing back:
1388     QUrl u("http://@kde.org/");
1389     QVERIFY(u.userName().isEmpty());
1390     QVERIFY(!u.userName().isNull());
1391     QVERIFY(u.password().isNull());
1392     emptyUserTest2.setUser("foo");
1393     QCOMPARE(emptyUserTest2.user(), QString::fromLatin1("foo"));
1394     emptyUserTest2.setUser(QString());
1395     QVERIFY(emptyUserTest1 == emptyUserTest2);
1396 
1397     KUrl emptyUserTest3("http://www.foobar.com/");
1398     emptyUserTest3.setPass("");
1399     // empty password means empty user, fixed in Qt5
1400     QCOMPARE(emptyUserTest3.url(), QString("http://:@www.foobar.com/"));
1401     QVERIFY(emptyUserTest1 != emptyUserTest3);
1402 
1403     KUrl uga("ftp://ftp.kde.org");
1404     uga.setUser("foo@bar");
1405     QCOMPARE(uga.user(), QString::fromLatin1("foo@bar"));
1406     QCOMPARE(uga.url(), QString::fromLatin1("ftp://foo%40bar@ftp.kde.org"));
1407 }
1408 
testComparisons()1409 void KUrlTest::testComparisons()
1410 {
1411     /* QUrl version of urlcmp */
1412     QUrl u1("ftp://ftp.de.kde.org/dir");
1413     QUrl u2("ftp://ftp.de.kde.org/dir/");
1414     QUrl::FormattingOptions options = QUrl::None;
1415     options |= QUrl::StripTrailingSlash;
1416     QString str1 = u1.toString(options);
1417     QString str2 = u2.toString(options);
1418     QCOMPARE(str1, u1.toString());
1419     QCOMPARE(str2, u1.toString());
1420     bool same = str1 == str2;
1421     QVERIFY(same);
1422 
1423     QString ucmp1 = "ftp://ftp.de.kde.org/dir";
1424     QString ucmp2 = "ftp://ftp.de.kde.org/dir/";
1425 #ifndef KDELIBS4SUPPORT_NO_DEPRECATED
1426     QVERIFY(!urlcmp(ucmp1, ucmp2));
1427     QVERIFY(urlcmp(ucmp1, ucmp2, KUrl::CompareWithoutTrailingSlash)); //only slash difference, ignore_trailing
1428 #endif
1429 
1430     {
1431         KUrl u1(ucmp1);
1432         KUrl u2(ucmp2);
1433         QVERIFY(!u1.equals(u2));
1434         QVERIFY(u1.equals(u2, KUrl::CompareWithoutTrailingSlash));
1435         QVERIFY(u1.equals(u2, KUrl::CompareWithoutTrailingSlash | KUrl::AllowEmptyPath));
1436     }
1437 
1438     // Special case: no path vs '/'.
1439     {
1440         QString str1 = QString::fromLatin1("ftp://ftp.de.kde.org");
1441         QString str2 = QString::fromLatin1("ftp://ftp.de.kde.org/");
1442 #ifndef KDELIBS4SUPPORT_NO_DEPRECATED
1443         QVERIFY(!urlcmp(str1, str2));
1444         QVERIFY(!urlcmp(str1, str2, KUrl::CompareWithoutTrailingSlash)); // empty path != '/'
1445         QVERIFY(urlcmp(str1, str2, KUrl::CompareWithoutTrailingSlash | KUrl::AllowEmptyPath));
1446 #endif
1447         KUrl u1(str1);
1448         KUrl u2(str2);
1449         QVERIFY(!u1.equals(u2));
1450         QVERIFY(!u1.equals(u2, KUrl::CompareWithoutTrailingSlash));
1451         QVERIFY(u1.equals(u2, KUrl::CompareWithoutTrailingSlash | KUrl::AllowEmptyPath));
1452     }
1453 
1454     QString ucmp3 = "ftp://ftp.de.kde.org/dir/#";
1455 #ifndef KDELIBS4SUPPORT_NO_DEPRECATED
1456     QVERIFY(!urlcmp(ucmp2, ucmp3));  // (only hash difference)
1457     QVERIFY(urlcmp(ucmp2, ucmp3, KUrl::CompareWithoutFragment)); // (only hash difference, ignore_ref)
1458     QVERIFY(urlcmp(ucmp2, ucmp3, KUrl::CompareWithoutTrailingSlash | KUrl::CompareWithoutFragment)); // (slash and hash difference, ignore_trailing, ignore_ref)
1459     QVERIFY(urlcmp("", "", KUrl::CompareWithoutFragment)); // (empty, empty)
1460     QVERIFY(urlcmp("", ""));  // (empty, empty)
1461     QVERIFY(!urlcmp("", ucmp1));  // (empty, not empty)
1462     QVERIFY(!urlcmp("", ucmp1, KUrl::CompareWithoutFragment)); // (empty, not empty)
1463     QVERIFY(!urlcmp("file", ucmp1));  // (malformed, not empty)
1464     QVERIFY(!urlcmp("file", ucmp1, KUrl::CompareWithoutFragment)); // (malformed, not empty)
1465 #endif
1466 
1467     KUrl ftpUrl("ftp://ftp.de.kde.org");
1468     QCOMPARE(ftpUrl.path(), QString());
1469     ftpUrl = "ftp://ftp.de.kde.org/";
1470     QVERIFY(ftpUrl.isParentOf(KUrl("ftp://ftp.de.kde.org/host/subdir/")));
1471     ftpUrl = "ftp://ftp/host/subdir/";
1472     QVERIFY(ftpUrl.isParentOf(KUrl("ftp://ftp/host/subdir/")));
1473     QVERIFY(ftpUrl.isParentOf(KUrl("ftp://ftp/host/subdir")));
1474     QVERIFY(!ftpUrl.isParentOf(KUrl("ftp://ftp/host/subdi")));
1475     QVERIFY(ftpUrl.isParentOf(KUrl("ftp://ftp/host/subdir/blah/")));
1476     QVERIFY(!ftpUrl.isParentOf(KUrl("ftp://ftp/blah/subdir")));
1477     QVERIFY(!ftpUrl.isParentOf(KUrl("file:////ftp/host/subdir/")));
1478     QVERIFY(ftpUrl.isParentOf(KUrl("ftp://ftp/host/subdir/subsub")));
1479 }
1480 
testStreaming_data()1481 void KUrlTest::testStreaming_data()
1482 {
1483     QTest::addColumn<QString>("urlStr");
1484 
1485     QTest::newRow("origURL") << "http://www.website.com/directory/?#ref";
1486     QTest::newRow("urlWithPassAndNoUser") << "ftp://:password@ftp.kde.org/path";
1487     QTest::newRow("accentuated") << QString::fromUtf8("trash:/été");
1488     QTest::newRow("empty") << "";
1489     QVERIFY(!KUrl("ptal://mlc:usb").isValid());
1490     QTest::newRow("invalid") << "ptal://mlc:usb";
1491     QTest::newRow("ipv6") << "http://[::ffff:129.144.52.38]:81?query";
1492 }
1493 
testStreaming()1494 void KUrlTest::testStreaming()
1495 {
1496     QFETCH(QString, urlStr);
1497     KUrl url(urlStr);
1498 
1499     QByteArray buffer;
1500     QDataStream writeStream(&buffer, QIODevice::WriteOnly);
1501     writeStream << url;
1502 
1503     QDataStream stream(buffer);
1504     KUrl restored;
1505     stream >> restored; // streaming valid url
1506     QCOMPARE(restored.isValid(), url.isValid());
1507     if (url.isValid()) {
1508         QCOMPARE(restored.url(), url.url());
1509     }
1510 }
1511 
testBrokenStuff()1512 void KUrlTest::testBrokenStuff()
1513 {
1514     // Broken stuff
1515     KUrl waba1("file:a");
1516     QCOMPARE(waba1.path(), QString("a"));
1517     QCOMPARE(waba1.fileName(KUrl::ObeyTrailingSlash), QString("a"));
1518     QCOMPARE(waba1.fileName(), QString("a"));
1519     QCOMPARE(waba1.directory(KUrl::AppendTrailingSlash | KUrl::ObeyTrailingSlash), QString(""));
1520     QCOMPARE(waba1.directory(KUrl::ObeyTrailingSlash), QString(""));
1521     QCOMPARE(waba1.directory(), QString(""));
1522 
1523     waba1 = "file:a/";
1524     QCOMPARE(waba1.path(), QString("a/"));
1525     QCOMPARE(waba1.fileName(KUrl::ObeyTrailingSlash), QString(""));
1526     QCOMPARE(waba1.fileName(), QString("a"));
1527     QCOMPARE(waba1.directory(KUrl::ObeyTrailingSlash | KUrl::AppendTrailingSlash), QString("a/"));
1528     QCOMPARE(waba1.directory(KUrl::ObeyTrailingSlash), QString("a"));
1529     QCOMPARE(waba1.directory(), QString(""));
1530 
1531     waba1 = "file:";
1532     QVERIFY(!waba1.isEmpty());
1533     QVERIFY(waba1.isValid());   // KDE3: was invalid. Now it's qurl with scheme="file".
1534     QCOMPARE(waba1.path(), QString(""));
1535     QCOMPARE(waba1.fileName(KUrl::ObeyTrailingSlash), QString(""));
1536     QCOMPARE(waba1.fileName(), QString(""));
1537     QCOMPARE(waba1.directory(KUrl::ObeyTrailingSlash | KUrl::AppendTrailingSlash), QString(""));
1538     QCOMPARE(waba1.directory(KUrl::AppendTrailingSlash), QString(""));
1539     QCOMPARE(waba1.directory(), QString(""));
1540     KUrl broken;
1541     broken.setPath(QString());
1542     QVERIFY(!broken.isEmpty());
1543     // It's valid: because isValid refers to parsing, not to what happens afterwards.
1544     QVERIFY(broken.isValid());
1545     QCOMPARE(broken.path(), QString(""));
1546     broken = "file://"; // just because coolo wondered
1547     QVERIFY(!broken.isEmpty());
1548     QVERIFY(broken.isValid());   // KDE3: was invalid; same as above
1549     QCOMPARE(broken.path(), QString(""));
1550     broken = "file";
1551     QVERIFY(broken.isValid());   // KDE3: was invalid; now it's path="file"
1552 
1553 #if 0
1554     // KUrl has a Q_ASSERT on this now, so we can't test it.
1555     broken = "/";
1556     QVERIFY(broken.isValid());
1557     QCOMPARE(broken.path(), QString("/"));
1558     QCOMPARE(broken.url(), QString("/"));   // KDE3: was resolved to "file:///". QUrl supports urls without a protocol.
1559     QCOMPARE(broken.protocol(), QString(""));   // KDE3: was "file"
1560 #endif
1561 
1562     {
1563         QUrl url;
1564         url.setEncodedUrl("LABEL=USB_STICK", QUrl::TolerantMode);
1565         QVERIFY(url.isValid());
1566         QCOMPARE(url.path(), QString("LABEL=USB_STICK"));
1567         QVERIFY(!url.isEmpty());
1568     }
1569     {
1570         QUrl url;
1571         url.setEncodedUrl("LABEL=USB_STICK", QUrl::TolerantMode);
1572         QVERIFY(url.isValid());
1573         QVERIFY(!url.isEmpty());   // Qt-4.4-snapshot20080213 bug, reported to TT
1574         QCOMPARE(url.path(), QString("LABEL=USB_STICK"));
1575     }
1576 
1577     broken = "LABEL=USB_STICK"; // 71430, can we use KUrl for this?
1578     QVERIFY(broken.isValid());   // KDE3 difference: QUrl likes this one too
1579     QVERIFY(!broken.isEmpty());
1580     QCOMPARE(broken.path(), QString("LABEL=USB_STICK"));   // was "" in KDE3
1581 }
1582 
testMoreBrokenStuff()1583 void KUrlTest::testMoreBrokenStuff()
1584 {
1585 #if 0 // BROKEN?
1586     // UNC like names
1587     KUrl unc1("FILE://localhost/home/root");
1588     QCOMPARE(unc1.path(), QString("/home/root"));
1589     QCOMPARE(unc1.url(), QString("file:///home/root"));
1590 #endif
1591     KUrl unc2("file:///home/root"); // with empty host
1592     QCOMPARE(unc2.path(), QString("/home/root"));
1593     QCOMPARE(unc2.url(), QString("file:///home/root"));
1594 
1595     {
1596         KUrl unc3("FILE://remotehost/home/root");
1597 #if 0 // BROKEN?
1598         QCOMPARE(unc3.path(), QString("//remotehost/home/root"));
1599 #endif
1600         QCOMPARE(unc3.url(), QString("file://remotehost/home/root"));   // kde3, qt5: lowercase. kde4/qt4: uppercase.
1601         KUrl url2("file://atlas/dfaure");
1602         QCOMPARE(url2.host(), QString("atlas"));
1603         QCOMPARE(url2.path(), QString("/dfaure"));
1604         //QCOMPARE( url3.path(), QString("//atlas/dfaure")); // says Waba
1605         //KUrl url3("file:////atlas/dfaure");
1606         //QCOMPARE( url3.path(), QString("//atlas/dfaure")); // says Waba
1607 
1608         KUrl url4(url2, "//remotehost/home/root");
1609         QCOMPARE(url4.host(), QString("remotehost"));
1610         QCOMPARE(url4.path(), QString("/home/root"));
1611     }
1612 
1613     KUrl weird;
1614     weird = "http://strange<hostname>/";
1615     QVERIFY(!weird.isValid());
1616 
1617     weird = "http://strange<username>@strange<hostname>/";
1618     QVERIFY(!weird.isValid());
1619 
1620     {
1621         QUrl url;
1622         url.setUrl("http://strange<username>@hostname/", QUrl::TolerantMode);
1623         QVERIFY(url.isValid());
1624     }
1625     weird = "http://strange<username>@hostname/";
1626     QVERIFY(weird.isValid());   // KDE3: was valid. Fixed by _setEncodedUrl.
1627     QCOMPARE(weird.host(), QString("hostname"));
1628 
1629     weird = "http://strange;hostname/";
1630     QVERIFY(!weird.isValid());
1631 
1632     weird = "http://strange;username@strange;hostname/";
1633     QVERIFY(!weird.isValid());
1634 
1635     weird = "http://strange;username@hostname/";
1636     QVERIFY(weird.isValid());
1637     QCOMPARE(weird.host(), QString("hostname"));
1638 
1639     weird = "http://strange;username:password@strange;hostname/";
1640     QVERIFY(!weird.isValid());
1641 
1642     weird = "http://strange;username:password@hostname/";
1643     QVERIFY(weird.isValid());
1644     QCOMPARE(weird.host(), QString("hostname"));
1645 
1646     weird = "http://[strange;hostname]/";
1647     QVERIFY(!weird.isValid());
1648 
1649     weird = "ssh://user@machine?cmd='echo $HOSTNAME'";
1650     QVERIFY(weird.isValid());
1651     QCOMPARE(weird.host(), QString("machine"));
1652     //qDebug("%s",qPrintable( weird.query() ) );
1653     QCOMPARE(weird.queryItem("cmd"), QString("'echo $HOSTNAME'"));
1654 
1655     weird = ":pictures"; // for KFileDialog's startDir, long ago. Nowadays it uses a proper URL, kfiledialog:///pictures
1656     QVERIFY(!weird.isValid());
1657     QVERIFY(weird.protocol().isEmpty());
1658     QVERIFY(weird.host().isEmpty());
1659     QCOMPARE(weird.path(), QString(":pictures"));
1660     QCOMPARE(weird.url(), QString());
1661 
1662     weird = "::keyword"; // for KFileDialog's startDir, long ago.
1663     QVERIFY(!weird.isValid());
1664     QVERIFY(weird.protocol().isEmpty());
1665     QVERIFY(weird.host().isEmpty());
1666     QCOMPARE(weird.path(), QString("::keyword"));
1667     QCOMPARE(weird.url(), QString());
1668 
1669     KUrl broken;
1670     broken = "ptal://mlc:usb:PC_970";
1671     QVERIFY(!broken.isValid());
1672     QVERIFY(!broken.errorString().isEmpty());
1673     //QCOMPARE( broken.url(), QString("ptal://mlc:usb:PC_970") ); // QUrl doesn't provide the initial string if it's an invalid url
1674     QUrl brokenUrl("ptal://mlc:usb:PC_970");
1675     QVERIFY(!brokenUrl.isValid());
1676 
1677     QUrl dxOffEagle("http://something/newpage.html?[{\"foo: bar\"}]", QUrl::TolerantMode);
1678     QVERIFY(dxOffEagle.isValid());
1679     QCOMPARE(QString(dxOffEagle.toEncoded()), QString("http://something/newpage.html?[%7B%22foo:%20bar%22%7D]"));
1680     QUrl dxOffEagle2;
1681     dxOffEagle2.setUrl("http://something/newpage.html?[{\"foo: bar\"}]", QUrl::TolerantMode);
1682     QVERIFY(dxOffEagle2.isValid());
1683     QCOMPARE(dxOffEagle.toEncoded(), dxOffEagle2.toEncoded());
1684 
1685     QUrl dxOffEagle3;
1686     dxOffEagle3.setEncodedUrl("http://something/newpage.html?[{\"foo: bar\"}]", QUrl::TolerantMode);
1687 #if QT_VERSION < 0x040500
1688     QEXPECT_FAIL("", "Issue N183630, task ID 183874; works with setUrl so we do that in _setEncodedUrl now", Continue);
1689 #endif
1690     QVERIFY(dxOffEagle3.isValid());
1691     QCOMPARE(dxOffEagle.toEncoded(), dxOffEagle3.toEncoded());
1692 
1693     QUrl javascript;
1694     javascript.setUrl("javascript:window.location+\"__flashplugin_unique__\"", QUrl::TolerantMode);
1695     QVERIFY(javascript.isValid());
1696     javascript.setEncodedUrl("javascript:window.location+\"__flashplugin_unique__\"", QUrl::TolerantMode);
1697 #if QT_VERSION < 0x040500
1698     QEXPECT_FAIL("", "Issue N183630, task ID 183874", Continue);
1699 #endif
1700     QVERIFY(javascript.isValid());
1701 }
1702 
testMailto()1703 void KUrlTest::testMailto()
1704 {
1705     const QString faure = "faure@kde.org";
1706     const QString mailtoFaure = "mailto:" + faure;
1707     KUrl umail1(mailtoFaure);
1708     QCOMPARE(umail1.protocol(), QString("mailto"));
1709     QCOMPARE(umail1.path(), QString(faure));
1710     QVERIFY(!KUrl::isRelativeUrl(mailtoFaure));
1711 
1712 #if 0 // TODO in Qt
1713     // Make sure populateMimeData() works correct:
1714     // 1. the text/plain part of the mimedata should not contain the mailto: part
1715     // 2. the uri-list part of the mimedata should contain the mailto: part
1716     QMimeData md;
1717     umail1.populateMimeData(&md);
1718     QCOMPARE(md.text(), faure);
1719     KUrl::List uriList = KUrl::List::fromMimeData(&md);
1720     QCOMPARE(uriList.size(), 1);
1721     KUrl first = uriList.first();
1722     QCOMPARE(first.protocol(), QString("mailto"));
1723     QCOMPARE(first.path(), faure);
1724 #endif
1725 
1726     KUrl mailtoOnly("mailto:");
1727     QVERIFY(mailtoOnly.isValid());   // KDE3 said invalid, QUrl is more tolerant
1728 
1729     KUrl url1("mailto:user@host.com");
1730     QCOMPARE(url1.url(), QString("mailto:user@host.com"));
1731     QCOMPARE(url1.url(KUrl::LeaveTrailingSlash), QString("mailto:user@host.com"));
1732 
1733     KUrl mailtoUrl("mailto:null@kde.org?subject=hello");
1734     QCOMPARE(mailtoUrl.url(), QString("mailto:null@kde.org?subject=hello"));
1735 
1736     QUrl qurl("mailto:null@kde.org?subject=hello#world"); // #80165: is #world part of fragment or query? RFC-3986 says: fragment.
1737     QCOMPARE(QString::fromLatin1(qurl.encodedQuery()), QString("subject=hello"));
1738 
1739     {
1740         QUrl mailtoUrl;
1741         mailtoUrl.setScheme("mailto");
1742         mailtoUrl.setPath("a%b");
1743         QCOMPARE(mailtoUrl.path(), QString("a%b"));
1744         QCOMPARE(mailtoUrl.path(QUrl::FullyEncoded), QString("a%25b"));
1745         QCOMPARE(mailtoUrl.toString(), QString("mailto:a%25b"));
1746         QCOMPARE(QString::fromLatin1(mailtoUrl.toEncoded()), QString::fromLatin1("mailto:a%25b"));
1747     }
1748     {
1749         KUrl mailtoUrl;
1750         mailtoUrl.setScheme("mailto");
1751         mailtoUrl.setPath("a%b");
1752         QCOMPARE(mailtoUrl.url(), QString("mailto:a%25b")); // KUrl takes care of not changing behavior with Qt5.
1753     }
1754 
1755 #if 0
1756     // I wrote this test in the very first kurltest, but there's no proof that it's actually valid.
1757     // Andreas says this is broken, i.e. against rfc2368.
1758     // Let's see if the need ever comes up.
1759     KUrl umail2("mailto:Faure David <faure@kde.org>");
1760     QCOMPARE(umail2.protocol(), QString("mailto"));
1761     QCOMPARE(umail2.path(), QString("Faure David <faure@kde.org>"));
1762     QVERIFY(!KUrl::isRelativeUrl("mailto:faure@kde.org"));
1763 #endif
1764 
1765     KUrl url183433("mailto:test[at]gmail[dot]com");
1766     QCOMPARE(url183433.prettyUrl(), QString("mailto:test[at]gmail[dot]com"));
1767     QCOMPARE(url183433.url(), QString("mailto:test[at]gmail[dot]com"));
1768 }
1769 
testSmb()1770 void KUrlTest::testSmb()
1771 {
1772     KUrl smb("smb://domain;username:password@server/share");
1773     QVERIFY(smb.isValid());
1774     QCOMPARE(smb.user(), QString("domain;username"));
1775     smb = "smb:/";
1776     QVERIFY(smb.isValid());
1777     QCOMPARE(smb.url(), QString::fromLatin1("smb:/"));
1778     QCOMPARE(smb.prettyUrl(), QString::fromLatin1("smb:/"));
1779     smb = "smb://"; // KDE3: kurl.cpp rev 1.106 made it invalid. Valid again with QUrl.
1780     QVERIFY(smb.isValid());
1781     QCOMPARE(smb.prettyUrl(), QString::fromLatin1("smb://"));
1782     smb = "smb://host";
1783     QVERIFY(smb.isValid());
1784     QCOMPARE(smb.url(), QString::fromLatin1("smb://host"));
1785     QCOMPARE(smb.prettyUrl(), QString::fromLatin1("smb://host"));
1786     smb = "smb:///";
1787     QVERIFY(smb.isValid());
1788     QCOMPARE(smb.prettyUrl(), QString::fromLatin1("smb:/"));
1789 
1790     KUrl implicitSmb("file://host/path");
1791     QVERIFY(!implicitSmb.isLocalFile()); // -> kio_file will redirect to smb (by default)
1792     QCOMPARE(implicitSmb.host(), QString("host"));
1793 
1794     KUrl noImplicitSmb("//path1/path2");
1795     QVERIFY(noImplicitSmb.isLocalFile());
1796     QCOMPARE(noImplicitSmb.path(), QString("//path1/path2"));
1797 }
1798 
testOtherProtocols()1799 void KUrlTest::testOtherProtocols()
1800 {
1801     KUrl about("about:");
1802     QCOMPARE(about.path(), QString());
1803     QCOMPARE(about.protocol(), QString("about"));
1804 
1805     KUrl aboutKonqueror("about:konqueror");
1806     QCOMPARE(aboutKonqueror.path(), QString("konqueror"));
1807 
1808     KUrl leo("data:text/html,http://www.invalid/");
1809     QVERIFY(leo.isValid());
1810     QCOMPARE(leo.protocol(), QString("data"));
1811     QCOMPARE(leo.url(), QString("data:text/html,http://www.invalid/"));
1812     QCOMPARE(leo.path(), QString("text/html,http://www.invalid/"));
1813 
1814     KUrl testFrag("data:,test#foo");
1815     QVERIFY(testFrag.isValid());
1816     QCOMPARE(testFrag.protocol(), QString("data"));
1817     QCOMPARE(testFrag.url(), QString("data:,test#foo"));
1818     QCOMPARE(testFrag.path(), QString(",test"));
1819     QVERIFY(testFrag.hasFragment());
1820     QCOMPARE(testFrag.fragment(), QString("foo"));
1821 
1822     KUrl ptal("ptal://mlc:usb@PC_970");   // User=mlc, password=usb, host=PC_970
1823 #if QT_VERSION >= 0x040600 && QT_VERSION <= 0x040602 // Hostnames with underscores were invalid in 4.6.0 to 4.6.2, then allowed again in e301c82693c33c0f96c6a756d15fe35a9d877443
1824     QCOMPARE(ptal.url(), QString("ptal://mlc:usb@")); // The host "PC_970" is invalid according to STD3 validation
1825     KUrl ptalSimpler("ptal://mlc:usb@pc123");
1826     QCOMPARE(ptalSimpler.url(), QString("ptal://mlc:usb@pc123"));
1827 #else
1828     QUrl ptal_qurl;
1829     ptal_qurl.setUrl("ptal://mlc:usb@PC_970", QUrl::TolerantMode);
1830     QVERIFY(ptal_qurl.isValid());
1831     QCOMPARE(QString::fromLatin1(ptal_qurl.toEncoded()), QString::fromLatin1("ptal://mlc:usb@pc_970"));
1832     QCOMPARE(ptal_qurl.host(), QString("pc_970"));
1833 
1834     QVERIFY(ptal.isValid());
1835     QCOMPARE(ptal.host(), QString("pc_970"));
1836     QCOMPARE(ptal.user(), QString("mlc"));
1837     QCOMPARE(ptal.pass(), QString("usb"));
1838 #endif
1839 }
1840 
testUtf8()1841 void KUrlTest::testUtf8()
1842 {
1843     QTextCodec *codec = QTextCodec::codecForName("ISO-8859-1");
1844     QVERIFY(codec != nullptr);
1845     QTextCodec::setCodecForLocale(codec);
1846 
1847 #if 0
1848     {
1849         QUrl utest;
1850         utest.setScheme("file");
1851         utest.setPath(QString::fromUtf8("/home/dfaure/Matériel"));
1852         printf("utest.toString()=%s\n", utest.toString().toLatin1().constData());
1853         printf("utest.path()=%s\n", utest.path().toLatin1().constData());
1854         printf("utest.toEncoded()=%s\n", utest.toEncoded().data());
1855     }
1856 #endif
1857 
1858     // UTF8 tests
1859     KUrl uloc;
1860     uloc.setPath(QString::fromUtf8("/home/dfaure/Matériel"));
1861     QCOMPARE(uloc.url(), QString("file:///home/dfaure/Mat%C3%A9riel"));    // KDE3 would say %E9 here; but from now on URLs are always utf8 encoded.
1862     QCOMPARE(uloc.path(), QString::fromUtf8("/home/dfaure/Matériel"));
1863     QCOMPARE(uloc.prettyUrl(), QString::fromUtf8("file:///home/dfaure/Matériel"));
1864     QCOMPARE(uloc.pathOrUrl(), QString::fromUtf8("/home/dfaure/Matériel"));                // ... but that's why pathOrUrl is nicer.
1865     QCOMPARE(uloc.url(), QString("file:///home/dfaure/Mat%C3%A9riel"));
1866     uloc = KUrl("file:///home/dfaure/Mat%C3%A9riel");
1867     QCOMPARE(uloc.path(), QString::fromUtf8("/home/dfaure/Matériel"));
1868     QCOMPARE(uloc.url(), QString("file:///home/dfaure/Mat%C3%A9riel"));
1869 
1870     KUrl umlaut1("http://www.clever-tanken.de/liste.asp?ort=N%FCrnberg&typ=Diesel");
1871     QCOMPARE(umlaut1.url(), QString("http://www.clever-tanken.de/liste.asp?ort=N%FCrnberg&typ=Diesel"));
1872 
1873     KUrl umlaut2("http://www.clever-tanken.de/liste.asp?ort=N%FCrnberg&typ=Diesel"); // was ,106
1874     QCOMPARE(umlaut2.url(), QString("http://www.clever-tanken.de/liste.asp?ort=N%FCrnberg&typ=Diesel"));
1875 
1876     KUrl urlWithUnicodeChar(QString::fromUtf8("file:///home/dfaure/Matériel"));
1877     QCOMPARE(uloc.url(), QString("file:///home/dfaure/Mat%C3%A9riel"));
1878 
1879     KUrl wkai(QString::fromUtf8("/tmp/魔"));
1880     QCOMPARE(wkai.url(), QString("file:///tmp/%E9%AD%94"));
1881     QCOMPARE(wkai.prettyUrl(), QString::fromUtf8("file:///tmp/魔"));
1882 
1883     // Show that the character "fraction slash" (U+2044) cannot appear in url(),
1884     // so it's ok to use that to encode urls as filenames (e.g. in kio_http cache)
1885     KUrl fractionSlash(QString("http://kde.org/a") + QChar(0x2044) + "b");
1886     QCOMPARE(fractionSlash.url(), QString("http://kde.org/a%E2%81%84b"));
1887     QCOMPARE(fractionSlash.prettyUrl(), QString(QString("http://kde.org/a") + QChar(0x2044) + "b"));
1888 }
1889 
testOtherEncodings()1890 void KUrlTest::testOtherEncodings()
1891 {
1892     QTextCodec::setCodecForLocale(QTextCodec::codecForName("koi8-r"));
1893     KUrl baseURL("file:/home/coolo");
1894     KUrl russian = QUrl::fromLocalFile(baseURL.directory(KUrl::AppendTrailingSlash) + QString::fromUtf8("фгн7"));
1895     //QCOMPARE( russian.url(), QString("file:///home/%C6%C7%CE7" ) ); // KDE3: was not using utf8
1896     QCOMPARE(russian.url(), QString("file:///home/%D1%84%D0%B3%D0%BD7"));   // QUrl uses utf8
1897 
1898     KUrl utf8_1("audiocd:/By%20Name/15%20Geantra%C3%AE.wav");
1899     QCOMPARE(utf8_1.fileName(), QString::fromUtf8("15 Geantraî.wav"));
1900 
1901     // KDE3: url had %2F, and fileName had '/'. But this is wrong, %2F means '/',
1902     // and filenames have to use %2F, so the url needs to have %252F.
1903     // KIO::encodeFileName takes care of that.
1904     KUrl utf8_2("audiocd:/By%20Name/15%252FGeantra%C3%AE.wav");
1905     QCOMPARE(utf8_2.path(), QString::fromUtf8("/By Name/15%2FGeantraî.wav"));
1906     QCOMPARE(utf8_2.fileName(), QString::fromUtf8("15%2FGeantraî.wav"));
1907 }
1908 
testPathOrURL()1909 void KUrlTest::testPathOrURL()
1910 {
1911     QUrl quloc = QUrl::fromLocalFile("/home/dfaure/konqtests/Mat%C3%A9riel");
1912     QCOMPARE(quloc.toLocalFile(), QString("/home/dfaure/konqtests/Mat%C3%A9riel"));
1913 
1914     // passing path or url to the constructor: both work
1915     KUrl uloc("/home/dfaure/konqtests/Mat%C3%A9riel");
1916     QCOMPARE(uloc.url(), QString("file:///home/dfaure/konqtests/Mat%25C3%25A9riel"));
1917     QCOMPARE(uloc.toLocalFile(), QString("/home/dfaure/konqtests/Mat%C3%A9riel"));
1918     uloc = KUrl("http://www.kde.org");
1919     QCOMPARE(uloc.pathOrUrl(), uloc.url());
1920     QCOMPARE(uloc.pathOrUrl(KUrl::AddTrailingSlash), QString("http://www.kde.org/"));
1921     uloc = KUrl(QString("www.kde.org"));
1922     QVERIFY(uloc.isValid());   // KDE3: was invalid. But it's now a url with path="www.kde.org", ok.
1923     uloc = KUrl("index.html");
1924     QVERIFY(uloc.isValid());   // KDE3: was invalid; same as above
1925     uloc = KUrl("");
1926     QVERIFY(!uloc.isValid());
1927 #ifdef Q_OS_WIN
1928 #ifdef Q_CC_MSVC
1929 #pragma message ("port KUser")
1930 #else
1931 #warning port KUser
1932 #endif
1933 #else
1934     KUser currentUser;
1935     const QString userName = currentUser.loginName();
1936     QVERIFY(!userName.isEmpty());
1937     uloc = KUrl(QString::fromUtf8("~%1/konqtests/Matériel").arg(userName));
1938     QEXPECT_FAIL("", "No more user-expansion in KUrl", Continue);
1939     QCOMPARE(uloc.path(), QString::fromUtf8("%1/konqtests/Matériel").arg(currentUser.homeDir()));
1940 #endif
1941 
1942     // pathOrUrl tests
1943     uloc = KUrl("/home/dfaure/konqtests/Mat%C3%A9riel");
1944     QCOMPARE(uloc.pathOrUrl(), uloc.path());
1945     uloc = "http://www.kde.org";
1946     QCOMPARE(uloc.url(), QString("http://www.kde.org"));
1947     uloc = "file:///home/dfaure/konq%20tests/Mat%C3%A9riel#ref";
1948     QCOMPARE(uloc.pathOrUrl(), QString::fromUtf8("file:///home/dfaure/konq tests/Matériel#ref"));
1949     uloc = "file:///home/dfaure/konq%20tests/Mat%C3%A9riel?query";
1950     QCOMPARE(uloc.pathOrUrl(), QString::fromUtf8("file:///home/dfaure/konq tests/Matériel?query"));
1951     uloc = KUrl("/home/dfaure/file#with#hash");
1952     QCOMPARE(uloc.pathOrUrl(), QString("/home/dfaure/file#with#hash"));
1953 
1954     // test creation of url from pathOrUrl
1955     uloc = KUrl(QString::fromUtf8("http://www.kde.org/home/andreas/täst"));
1956     QCOMPARE(KUrl(uloc.pathOrUrl()), uloc);
1957     uloc = KUrl("http://www.kde.org/home/andreas/t%C3%A4st");
1958     QCOMPARE(KUrl(uloc.pathOrUrl()), uloc);
1959     uloc = KUrl(QString::fromUtf8("file:///home/andreas/täst"));
1960     QCOMPARE(KUrl(uloc.pathOrUrl()), uloc);
1961     uloc = KUrl("file:///home/andreas/t%C3%A4st");
1962     QCOMPARE(KUrl(uloc.pathOrUrl()), uloc);
1963     uloc = KUrl("http://www.kde.org/home/kde?foobar#test");
1964     QCOMPARE(KUrl(uloc.pathOrUrl()), uloc);
1965     uloc = KUrl("http://www.kde.org/home/%andreas");
1966     QCOMPARE(KUrl(uloc.pathOrUrl()), uloc);
1967 }
1968 
testAssignment()1969 void KUrlTest::testAssignment()
1970 {
1971     // passing path or url to the constructor: both work
1972     KUrl uloc;
1973     uloc = "/home/dfaure/konqtests/Mat%C3%A9riel";
1974     QCOMPARE(uloc.toLocalFile(), QString::fromUtf8("/home/dfaure/konqtests/Mat%C3%A9riel"));
1975     KUrl u2;
1976     u2 = uloc;
1977     QCOMPARE(u2.toLocalFile(), QString::fromUtf8("/home/dfaure/konqtests/Mat%C3%A9riel"));
1978     uloc = "http://www.kde.org";
1979     QCOMPARE(uloc.pathOrUrl(), uloc.url());
1980     uloc = QString("www.kde.org");
1981     QVERIFY(uloc.isValid());
1982     uloc = KUrl("index.html");
1983     QVERIFY(uloc.isValid());
1984     uloc = KUrl("");
1985     QVERIFY(!uloc.isValid());
1986 #ifdef Q_OS_WIN
1987 #ifdef Q_CC_MSVC
1988 #pragma message ("port KUser")
1989 #else
1990 #warning port KUser
1991 #endif
1992 #else
1993     KUser currentUser;
1994     const QString userName = currentUser.loginName();
1995     QVERIFY(!userName.isEmpty());
1996     uloc = QString::fromUtf8("~%1/konqtests/Matériel").arg(userName);
1997     QEXPECT_FAIL("", "No more user-expansion in KUrl", Continue);
1998     QCOMPARE(uloc.path(), QString::fromUtf8("%1/konqtests/Matériel").arg(currentUser.homeDir()));
1999     uloc = QByteArray('~' + userName.toUtf8() + "/konqtests/Matériel");
2000     QEXPECT_FAIL("", "No more user-expansion in KUrl", Continue);
2001     QCOMPARE(uloc.path(), QString::fromUtf8("%1/konqtests/Matériel").arg(currentUser.homeDir()));
2002 
2003     // Assigning a KUrl to a QUrl and back
2004     QUrl qurl = uloc;
2005     QCOMPARE(qurl.toEncoded(), uloc.toEncoded());
2006     uloc = KUrl(qurl);
2007     QCOMPARE(qurl.toEncoded(), uloc.toEncoded());
2008     QEXPECT_FAIL("", "No more user-expansion in KUrl", Continue);
2009     QCOMPARE(uloc.path(), QString::fromUtf8("%1/konqtests/Matériel").arg(currentUser.homeDir()));
2010 #endif
2011 }
2012 
testQueryItem()2013 void KUrlTest::testQueryItem()
2014 {
2015     KUrl theKow("http://www.google.de/search?q=frerich&hlx=xx&hl=de&empty=&lr=lang+de&test=%2B%20%3A%25");
2016     QCOMPARE(theKow.queryItem("q"), QString("frerich"));
2017     QCOMPARE(theKow.queryItem("hl"), QString("de"));
2018     QCOMPARE(theKow.queryItem("lr"), QString("lang de"));   // the '+' got decoded
2019     QCOMPARE(theKow.queryItem("InterstellarCounselor"), QString());
2020     QCOMPARE(theKow.queryItem("empty"), QString(""));
2021     QCOMPARE(theKow.queryItem("test"), QString("+ :%"));
2022     theKow.addQueryItem("a", "b+c");
2023     QCOMPARE(theKow.url(), QString("http://www.google.de/search?q=frerich&hlx=xx&hl=de&empty=&lr=lang+de&test=%2B%20%3A%25&a=b%2Bc"));   // KDE3 would use b%2Bc, but this is more correct
2024     QCOMPARE(theKow.queryItem("a"), QString("b+c"));   // note that the '+' remained
2025 
2026     // checks for queryItems(), which returns a QMap<QString,QString>:
2027     KUrl queryUrl("mailto:Marc%20Mutz%20%3cmutz@kde.org%3E?"
2028                   "Subject=subscribe+me&"
2029                   "body=subscribe+mutz%40kde.org&"
2030                   "Cc=majordomo%40lists.kde.org");
2031     QCOMPARE(QStringList(queryUrl.queryItems(KUrl::QueryItemsOptions()).keys()).join(", "),
2032              QString("Cc, Subject, body"));
2033     QCOMPARE(QStringList(queryUrl.queryItems(KUrl::CaseInsensitiveKeys).keys()).join(", "),
2034              QString("body, cc, subject"));
2035     QCOMPARE(QStringList(queryUrl.queryItems(KUrl::QueryItemsOptions()).values()).join(", "),
2036              QString("majordomo@lists.kde.org, subscribe me, subscribe mutz@kde.org"));
2037     QCOMPARE(QStringList(queryUrl.queryItems(KUrl::CaseInsensitiveKeys).values()).join(", "),
2038              QString("subscribe mutz@kde.org, majordomo@lists.kde.org, subscribe me"));
2039     // TODO check for QUrl::queryItems
2040 
2041 }
2042 
testEncodeString()2043 void KUrlTest::testEncodeString()
2044 {
2045     // Needed for #49616
2046     QCOMPARE(QUrl::toPercentEncoding("C++"), QByteArray("C%2B%2B"));
2047     QCOMPARE(QUrl::fromPercentEncoding("C%2B%2B"), QString("C++"));
2048     QCOMPARE(QUrl::toPercentEncoding("%"), QByteArray("%25"));
2049     QCOMPARE(QUrl::toPercentEncoding(":"), QByteArray("%3A"));
2050     QCOMPARE(QUrl::fromPercentEncoding("C%A"), QString("C%A"));     // % A is not percent-encoding  (pct-encoded = "%" HEXDIG HEXDIG)
2051 
2052     QString output = QUrl::fromPercentEncoding("C%00%0A");
2053     QString expected = QString::fromLatin1("C\0\n", 3); // no reason to stop at %00, in fact
2054     QCOMPARE(output.size(), expected.size());
2055     QCOMPARE(output, expected);
2056 }
2057 
testIdn()2058 void KUrlTest::testIdn()
2059 {
2060     //qDebug( "trying QUrl with fromPercentEncoding" );
2061     QUrl qurltest(QUrl::fromPercentEncoding("http://\303\244.de"));     // a+trema in utf8
2062     QVERIFY(qurltest.isValid());
2063 
2064     //qDebug( "trying QUrl with fromEncoded" );
2065     QUrl qurl = QUrl::fromEncoded("http://\303\244.de");   // a+trema in utf8
2066     QVERIFY(qurl.isValid());
2067     QCOMPARE(qurl.toEncoded(), QByteArray("http://xn--4ca.de"));
2068 
2069     //qDebug( "and now trying KUrl" );
2070     KUrl thiago(QString::fromUtf8("http://\303\244.de"));     // a+trema in utf8
2071     QVERIFY(thiago.isValid());
2072     QCOMPARE(thiago.url(), QString("http://xn--4ca.de"));     // Non-ascii is allowed in IDN domain names.
2073 
2074 #if 0
2075     // A broken test - not using utf8. and amantia forgot the real-world testcase.
2076     KUrl amantia("http://%E1.foo.de");
2077     QVERIFY(amantia.isValid());
2078     QCOMPARE(amantia.url(), QString("http://xn--80a.foo.de"));     // Non-ascii is allowed in IDN domain names.
2079 #endif
2080 
2081     // A more valid test for % in hostnames:
2082     KUrl uwp("http://%C3%A4.de");
2083     QVERIFY(uwp.isValid());
2084     QCOMPARE(thiago.url(), QString("http://xn--4ca.de"));   // as above
2085 }
2086 
testUriMode()2087 void KUrlTest::testUriMode()
2088 {
2089     KUrl url1;
2090 #if 0 // ###### TODO KUri
2091     url1 = "http://www.foobar.com/";
2092     QCOMPARE(url1.uriMode(), KUrl::URL);
2093     url1 = "mailto:user@host.com";
2094     QCOMPARE(url1.uriMode(), KUrl::Mailto);
2095 
2096     url1 = "data:text/plain,foobar?gazonk=flarp";
2097     QCOMPARE(url1.uriMode(), KUrl::RawURI);
2098 
2099     QCOMPARE(url1.path(), QString("text/plain,foobar?gazonk=flarp"));
2100 #endif
2101     url1 = "mailto:User@Host.COM?subject=Hello";
2102     QCOMPARE(url1.path(), QString("User@Host.COM"));   // KDE3: "User@host.com". Does it matter?
2103 }
2104 
testToLocalFile()2105 void KUrlTest::testToLocalFile()
2106 {
2107     const QString localFile("/tmp/print.pdf");
2108 
2109     const KUrl urlWithHost("file://localhost/tmp/print.pdf");
2110     const KUrl urlWithoutHost("file:///tmp/print.pdf");
2111 
2112     QCOMPARE(urlWithHost.toLocalFile(), localFile);
2113     QCOMPARE(urlWithoutHost.toLocalFile(), localFile);
2114 }
2115 
testUrl_data()2116 void KUrlTest::testUrl_data()
2117 {
2118     QTest::addColumn<KUrl>("url");
2119     QTest::addColumn<QString>("urlLTS");
2120     QTest::addColumn<QString>("urlRTS");
2121     QTest::addColumn<QString>("urlATS");
2122 
2123     QTest::newRow("local file 1")
2124             << KUrl("file:///")
2125             << QString::fromLatin1("file:///")
2126             << QString::fromLatin1("file:///")
2127             << QString::fromLatin1("file:///");
2128     QTest::newRow("local file 2")
2129             << KUrl("file:///home/kde/")
2130             << QString::fromLatin1("file:///home/kde/")
2131             << QString::fromLatin1("file:///home/kde")
2132             << QString::fromLatin1("file:///home/kde/");
2133     QTest::newRow("local file 3")
2134             << KUrl("file:///home/kde//")
2135             << QString::fromLatin1("file:///home/kde//")
2136             << QString::fromLatin1("file:///home/kde")
2137             << QString::fromLatin1("file:///home/kde//");
2138 
2139     QTest::newRow("ftp url")
2140             << KUrl("ftp://ftp.kde.org/")
2141             << QString::fromLatin1("ftp://ftp.kde.org/")
2142             << QString::fromLatin1("ftp://ftp.kde.org/")
2143             << QString::fromLatin1("ftp://ftp.kde.org/");
2144     QTest::newRow("ftp url - 3 trailing slashes")
2145             << KUrl("ftp://ftp.kde.org///")
2146             << QString::fromLatin1("ftp://ftp.kde.org///")
2147             << QString::fromLatin1("ftp://ftp.kde.org/")
2148             << QString::fromLatin1("ftp://ftp.kde.org///");
2149 }
2150 
testUrl()2151 void KUrlTest::testUrl()
2152 {
2153     QFETCH(KUrl, url);
2154     QFETCH(QString, urlLTS);
2155     QFETCH(QString, urlRTS);
2156     QFETCH(QString, urlATS);
2157 
2158     QCOMPARE(url.url(KUrl::LeaveTrailingSlash), urlLTS);
2159     QCOMPARE(url.url(KUrl::RemoveTrailingSlash), urlRTS);
2160     QCOMPARE(url.url(KUrl::AddTrailingSlash), urlATS);
2161 }
2162 
testToStringList()2163 void KUrlTest::testToStringList()
2164 {
2165     KUrl::List urls;
2166     urls << KUrl("file:///")
2167          << KUrl("file:///home/kde/")
2168          << KUrl("file:///home/kde//")
2169          << KUrl("ftp://ftp.kde.org/")
2170          << KUrl("ftp://ftp.kde.org///");
2171 
2172     //kDebug() << urls.toStringList(KUrl::LeaveTrailingSlash);
2173     QCOMPARE(urls.toStringList(KUrl::LeaveTrailingSlash),
2174              QStringList()
2175              << QLatin1String("file:///")
2176              << QLatin1String("file:///home/kde/")
2177              << QLatin1String("file:///home/kde//")
2178              << QLatin1String("ftp://ftp.kde.org/")
2179              << QLatin1String("ftp://ftp.kde.org///"));
2180 
2181     //kDebug() << urls.toStringList(KUrl::RemoveTrailingSlash);
2182     QCOMPARE(urls.toStringList(KUrl::RemoveTrailingSlash),
2183              QStringList()
2184              << QLatin1String("file:///")
2185              << QLatin1String("file:///home/kde")
2186              << QLatin1String("file:///home/kde")
2187              << QLatin1String("ftp://ftp.kde.org/")
2188              << QLatin1String("ftp://ftp.kde.org/"));
2189 
2190     //kDebug() << urls.toStringList(KUrl::AddTrailingSlash);
2191     QCOMPARE(urls.toStringList(KUrl::AddTrailingSlash),
2192              QStringList()
2193              << QLatin1String("file:///")
2194              << QLatin1String("file:///home/kde/")
2195              << QLatin1String("file:///home/kde//")
2196              << QLatin1String("ftp://ftp.kde.org/")
2197              << QLatin1String("ftp://ftp.kde.org///"));
2198 }
2199 
testHashing()2200 void KUrlTest::testHashing()
2201 {
2202     QHash<KUrl, QUrl> hash;
2203     hash.insert(KUrl("http://www.kde.org/foo%23bar"), QUrl("http://www.kde.org/foo%23bar"));
2204     hash.insert(KUrl("http://www.kde.org/foo#ref?query"), QUrl("http://www.kde.org/foo#ref?query"));
2205 
2206     QHashIterator<KUrl, QUrl> it(hash);
2207     while (it.hasNext()) {
2208         it.next();
2209         QCOMPARE(it.key().url(), it.value().toString());
2210     }
2211 }
2212