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