| 1 | /**************************************************************************** |
| 2 | ** |
| 3 | ** Copyright (C) 2016 The Qt Company Ltd. |
| 4 | ** Copyright (C) 2016 Intel Corporation. |
| 5 | ** Contact: https://www.qt.io/licensing/ |
| 6 | ** |
| 7 | ** This file is part of the test suite of the Qt Toolkit. |
| 8 | ** |
| 9 | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ |
| 10 | ** Commercial License Usage |
| 11 | ** Licensees holding valid commercial Qt licenses may use this file in |
| 12 | ** accordance with the commercial license agreement provided with the |
| 13 | ** Software or, alternatively, in accordance with the terms contained in |
| 14 | ** a written agreement between you and The Qt Company. For licensing terms |
| 15 | ** and conditions see https://www.qt.io/terms-conditions. For further |
| 16 | ** information use the contact form at https://www.qt.io/contact-us. |
| 17 | ** |
| 18 | ** GNU General Public License Usage |
| 19 | ** Alternatively, this file may be used under the terms of the GNU |
| 20 | ** General Public License version 3 as published by the Free Software |
| 21 | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT |
| 22 | ** included in the packaging of this file. Please review the following |
| 23 | ** information to ensure the GNU General Public License requirements will |
| 24 | ** be met: https://www.gnu.org/licenses/gpl-3.0.html. |
| 25 | ** |
| 26 | ** $QT_END_LICENSE$ |
| 27 | ** |
| 28 | ****************************************************************************/ |
| 29 | |
| 30 | #define QT_DEPRECATED |
| 31 | #define QT_DISABLE_DEPRECATED_BEFORE 0 |
| 32 | #include <qurl.h> |
| 33 | #include <QtTest/QtTest> |
| 34 | #include <QtCore/QDebug> |
| 35 | |
| 36 | #include <qcoreapplication.h> |
| 37 | |
| 38 | #include <qfileinfo.h> |
| 39 | #include <qtextcodec.h> |
| 40 | #include <qmap.h> |
| 41 | |
| 42 | Q_DECLARE_METATYPE(QUrl::FormattingOptions) |
| 43 | |
| 44 | class tst_QUrl : public QObject |
| 45 | { |
| 46 | Q_OBJECT |
| 47 | |
| 48 | private slots: |
| 49 | void initTestCase(); |
| 50 | void cleanupTestCase(); |
| 51 | void effectiveTLDs_data(); |
| 52 | void effectiveTLDs(); |
| 53 | void getSetCheck(); |
| 54 | void constructing(); |
| 55 | void hashInPath(); |
| 56 | void unc(); |
| 57 | void assignment(); |
| 58 | void comparison(); |
| 59 | void comparison2_data(); |
| 60 | void comparison2(); |
| 61 | void copying(); |
| 62 | void setUrl(); |
| 63 | void i18n_data(); |
| 64 | void i18n(); |
| 65 | void resolving_data(); |
| 66 | void resolving(); |
| 67 | void toString_data(); |
| 68 | void toString(); |
| 69 | void toString_PreferLocalFile_data(); |
| 70 | void toString_PreferLocalFile(); |
| 71 | void toString_constructed_data(); |
| 72 | void toString_constructed(); |
| 73 | void toDisplayString_PreferLocalFile_data(); |
| 74 | void toDisplayString_PreferLocalFile(); |
| 75 | void toAndFromStringList_data(); |
| 76 | void toAndFromStringList(); |
| 77 | void isParentOf_data(); |
| 78 | void isParentOf(); |
| 79 | void toLocalFile_data(); |
| 80 | void toLocalFile(); |
| 81 | void fromLocalFile_data(); |
| 82 | void fromLocalFile(); |
| 83 | void fromLocalFileNormalize_data(); |
| 84 | void fromLocalFileNormalize(); |
| 85 | void macTypes(); |
| 86 | void relative(); |
| 87 | void compat_legacy(); |
| 88 | void compat_constructor_01_data(); |
| 89 | void compat_constructor_01(); |
| 90 | void compat_constructor_02_data(); |
| 91 | void compat_constructor_02(); |
| 92 | void compat_constructor_03_data(); |
| 93 | void compat_constructor_03(); |
| 94 | void compat_isValid_01_data(); |
| 95 | void compat_isValid_01(); |
| 96 | void compat_isValid_02_data(); |
| 97 | void compat_isValid_02(); |
| 98 | void compat_path_data(); |
| 99 | void compat_path(); |
| 100 | void compat_fileName_data(); |
| 101 | void compat_fileName(); |
| 102 | void compat_decode_data(); |
| 103 | void compat_decode(); |
| 104 | void compat_encode_data(); |
| 105 | void compat_encode(); |
| 106 | void percentEncoding_data(); |
| 107 | void percentEncoding(); |
| 108 | void swap(); |
| 109 | void symmetry(); |
| 110 | void ipvfuture_data(); |
| 111 | void ipvfuture(); |
| 112 | void ipv6_data(); |
| 113 | void ipv6(); |
| 114 | void ipv6_2_data(); |
| 115 | void ipv6_2(); |
| 116 | void moreIpv6(); |
| 117 | void toPercentEncoding_data(); |
| 118 | void toPercentEncoding(); |
| 119 | void isRelative_data(); |
| 120 | void isRelative(); |
| 121 | void hasQuery_data(); |
| 122 | void hasQuery(); |
| 123 | void nameprep(); |
| 124 | void isValid(); |
| 125 | void schemeValidator_data(); |
| 126 | void schemeValidator(); |
| 127 | void setScheme_data(); |
| 128 | void setScheme(); |
| 129 | void strictParser_data(); |
| 130 | void strictParser(); |
| 131 | void tolerantParser(); |
| 132 | void correctEncodedMistakes_data(); |
| 133 | void correctEncodedMistakes(); |
| 134 | void correctDecodedMistakes_data(); |
| 135 | void correctDecodedMistakes(); |
| 136 | void tldRestrictions_data(); |
| 137 | void tldRestrictions(); |
| 138 | void emptyQueryOrFragment(); |
| 139 | void hasFragment_data(); |
| 140 | void hasFragment(); |
| 141 | void setFragment_data(); |
| 142 | void setFragment(); |
| 143 | void fromEncoded(); |
| 144 | void stripTrailingSlash_data(); |
| 145 | void stripTrailingSlash(); |
| 146 | void hosts_data(); |
| 147 | void hosts(); |
| 148 | void hostFlags_data(); |
| 149 | void hostFlags(); |
| 150 | void setPort(); |
| 151 | void port_data(); |
| 152 | void port(); |
| 153 | void toEncoded_data(); |
| 154 | void toEncoded(); |
| 155 | void setAuthority_data(); |
| 156 | void setAuthority(); |
| 157 | void setEmptyAuthority_data(); |
| 158 | void setEmptyAuthority(); |
| 159 | void clear(); |
| 160 | void resolvedWithAbsoluteSchemes() const; |
| 161 | void resolvedWithAbsoluteSchemes_data() const; |
| 162 | void binaryData_data(); |
| 163 | void binaryData(); |
| 164 | void fromUserInput_data(); |
| 165 | void fromUserInput(); |
| 166 | void fromUserInputWithCwd_data(); |
| 167 | void fromUserInputWithCwd(); |
| 168 | void fileName_data(); |
| 169 | void fileName(); |
| 170 | void isEmptyForEncodedUrl(); |
| 171 | void toEncodedNotUsingUninitializedPath(); |
| 172 | void emptyAuthorityRemovesExistingAuthority_data(); |
| 173 | void emptyAuthorityRemovesExistingAuthority(); |
| 174 | void acceptEmptyAuthoritySegments(); |
| 175 | void lowercasesScheme(); |
| 176 | void componentEncodings_data(); |
| 177 | void componentEncodings(); |
| 178 | void setComponents_data(); |
| 179 | void setComponents(); |
| 180 | void streaming_data(); |
| 181 | void streaming(); |
| 182 | void detach(); |
| 183 | void testThreading(); |
| 184 | void matches_data(); |
| 185 | void matches(); |
| 186 | void ipv6_zoneId_data(); |
| 187 | void ipv6_zoneId(); |
| 188 | void normalizeRemotePaths_data(); |
| 189 | void normalizeRemotePaths(); |
| 190 | |
| 191 | private: |
| 192 | void testThreadingHelper(); |
| 193 | |
| 194 | const QString m_currentPath = QDir::currentPath(); |
| 195 | QTemporaryDir m_tempDir; |
| 196 | }; |
| 197 | |
| 198 | void tst_QUrl::initTestCase() |
| 199 | { |
| 200 | QVERIFY2(m_tempDir.isValid(), qPrintable(m_tempDir.errorString())); |
| 201 | } |
| 202 | |
| 203 | void tst_QUrl::cleanupTestCase() |
| 204 | { |
| 205 | // Restore working directory changed in fromUserInputWithCwd() |
| 206 | QDir::setCurrent(m_currentPath); |
| 207 | } |
| 208 | |
| 209 | // Testing get/set functions |
| 210 | void tst_QUrl::getSetCheck() |
| 211 | { |
| 212 | QUrl obj1; |
| 213 | // int QUrl::port() |
| 214 | // void QUrl::setPort(int) |
| 215 | obj1.setPort(0); |
| 216 | QCOMPARE(0, obj1.port()); |
| 217 | |
| 218 | obj1.setPort(INT_MIN); |
| 219 | QCOMPARE(-1, obj1.port()); // Out of range, -1 |
| 220 | |
| 221 | obj1.setPort(INT_MAX); |
| 222 | QCOMPARE(-1, obj1.port()); // Out of range, -1 |
| 223 | |
| 224 | obj1.setPort(1234); |
| 225 | QCOMPARE(1234, obj1.port()); |
| 226 | |
| 227 | // static QStringList QUrl::idnWhitelist() |
| 228 | // static void QUrl::setIdnWhitelist(QStringList) |
| 229 | QStringList original = QUrl::idnWhitelist(); // save for later |
| 230 | |
| 231 | QUrl::setIdnWhitelist(QStringList()); |
| 232 | QCOMPARE(QUrl::idnWhitelist(), QStringList()); |
| 233 | |
| 234 | QStringList norway; norway << "no" ; |
| 235 | QUrl::setIdnWhitelist(norway); |
| 236 | QCOMPARE(QUrl::idnWhitelist(), norway); |
| 237 | |
| 238 | QStringList modified = original; |
| 239 | modified << "foo" ; |
| 240 | QUrl::setIdnWhitelist(modified); |
| 241 | QCOMPARE(QUrl::idnWhitelist(), modified); |
| 242 | |
| 243 | // reset to the original |
| 244 | QUrl::setIdnWhitelist(original); |
| 245 | QCOMPARE(QUrl::idnWhitelist(), original); |
| 246 | } |
| 247 | |
| 248 | void tst_QUrl::constructing() |
| 249 | { |
| 250 | QUrl url; |
| 251 | QVERIFY(!url.isValid()); |
| 252 | QVERIFY(url.isEmpty()); |
| 253 | QCOMPARE(url.port(), -1); |
| 254 | QCOMPARE(url.toString(), QString()); |
| 255 | QCOMPARE(url, url); |
| 256 | QVERIFY(!(url < url)); |
| 257 | |
| 258 | QUrl fromLocal = QUrl::fromLocalFile(localfile: QString()); |
| 259 | QVERIFY(!fromLocal.isValid()); |
| 260 | QVERIFY(fromLocal.isEmpty()); |
| 261 | QCOMPARE(fromLocal.toString(), QString()); |
| 262 | |
| 263 | QUrl justHost("qt-project.org" ); |
| 264 | QVERIFY(!justHost.isEmpty()); |
| 265 | QVERIFY(justHost.host().isEmpty()); |
| 266 | QCOMPARE(justHost.path(), QString::fromLatin1("qt-project.org" )); |
| 267 | |
| 268 | QUrl hostWithSlashes("//qt-project.org" ); |
| 269 | QVERIFY(hostWithSlashes.path().isEmpty()); |
| 270 | QCOMPARE(hostWithSlashes.host(), QString::fromLatin1("qt-project.org" )); |
| 271 | } |
| 272 | |
| 273 | void tst_QUrl::hashInPath() |
| 274 | { |
| 275 | QUrl withHashInPath; |
| 276 | withHashInPath.setPath(path: QString::fromLatin1(str: "hi#mum.txt" )); |
| 277 | QCOMPARE(withHashInPath.path(), QString::fromLatin1("hi#mum.txt" )); |
| 278 | QCOMPARE(withHashInPath.toEncoded(), QByteArray("hi%23mum.txt" )); |
| 279 | QCOMPARE(withHashInPath.toString(), QString("hi%23mum.txt" )); |
| 280 | QCOMPARE(withHashInPath.toDisplayString(QUrl::PreferLocalFile), QString("hi%23mum.txt" )); |
| 281 | |
| 282 | QUrl fromHashInPath = QUrl::fromEncoded(url: withHashInPath.toEncoded()); |
| 283 | QCOMPARE(withHashInPath, fromHashInPath); |
| 284 | |
| 285 | const QUrl localWithHash = QUrl::fromLocalFile(localfile: "/hi#mum.txt" ); |
| 286 | QCOMPARE(localWithHash.path(), QString::fromLatin1("/hi#mum.txt" )); |
| 287 | QCOMPARE(localWithHash.toEncoded(), QByteArray("file:///hi%23mum.txt" )); |
| 288 | QCOMPARE(localWithHash.toString(), QString("file:///hi%23mum.txt" )); |
| 289 | QCOMPARE(localWithHash.path(), QString::fromLatin1("/hi#mum.txt" )); |
| 290 | QCOMPARE(localWithHash.toString(QUrl::PreferLocalFile), QString("/hi#mum.txt" )); |
| 291 | QCOMPARE(localWithHash.toDisplayString(QUrl::PreferLocalFile), QString("/hi#mum.txt" )); |
| 292 | } |
| 293 | |
| 294 | void tst_QUrl::unc() |
| 295 | { |
| 296 | QUrl buildUNC; |
| 297 | buildUNC.setScheme(QString::fromLatin1(str: "file" )); |
| 298 | buildUNC.setHost(host: QString::fromLatin1(str: "somehost" )); |
| 299 | buildUNC.setPath(path: QString::fromLatin1(str: "somepath" )); |
| 300 | QCOMPARE(buildUNC.toLocalFile(), QString::fromLatin1("//somehost/somepath" )); |
| 301 | buildUNC.toEncoded(); |
| 302 | QVERIFY(!buildUNC.isEmpty()); |
| 303 | } |
| 304 | |
| 305 | void tst_QUrl::assignment() |
| 306 | { |
| 307 | QUrl url("http://qt-project.org/" ); |
| 308 | QVERIFY(url.isValid()); |
| 309 | |
| 310 | QUrl copy; |
| 311 | copy = url; |
| 312 | |
| 313 | QCOMPARE(url, copy); |
| 314 | } |
| 315 | |
| 316 | void tst_QUrl::comparison() |
| 317 | { |
| 318 | QUrl url1("http://qt-project.org/" ); |
| 319 | QVERIFY(url1.isValid()); |
| 320 | |
| 321 | QUrl url2("http://qt-project.org/" ); |
| 322 | QVERIFY(url2.isValid()); |
| 323 | |
| 324 | QCOMPARE(url1, url2); |
| 325 | QVERIFY(!(url1 < url2)); |
| 326 | QVERIFY(!(url2 < url1)); |
| 327 | QVERIFY(url1.matches(url2, QUrl::None)); |
| 328 | QVERIFY(url1.matches(url2, QUrl::StripTrailingSlash)); |
| 329 | |
| 330 | // 6.2.2 Syntax-based Normalization |
| 331 | QUrl url3 = QUrl::fromEncoded(url: "example://a/b/c/%7Bfoo%7D" ); |
| 332 | QUrl url4 = QUrl::fromEncoded(url: "eXAMPLE://a/./b/../b/%63/%7bfoo%7d" ); |
| 333 | QEXPECT_FAIL("" , "Normalization not implemented, will probably not be implemented like this" , Continue); |
| 334 | QCOMPARE(url3, url4); |
| 335 | |
| 336 | QUrl url3bis = QUrl::fromEncoded(url: "example://a/b/c/%7Bfoo%7D/" ); |
| 337 | QUrl url3bisNoSlash = QUrl::fromEncoded(url: "example://a/b/c/%7Bfoo%7D" ); |
| 338 | QUrl url4bis = QUrl::fromEncoded(url: "example://a/./b/../b/c/%7Bfoo%7D/" ); |
| 339 | QCOMPARE(url4bis.adjusted(QUrl::NormalizePathSegments), url3bis); |
| 340 | QCOMPARE(url4bis.adjusted(QUrl::NormalizePathSegments | QUrl::StripTrailingSlash), url3bisNoSlash); |
| 341 | QVERIFY(url3bis.matches(url4bis, QUrl::NormalizePathSegments)); |
| 342 | QVERIFY(!url3bisNoSlash.matches(url4bis, QUrl::NormalizePathSegments)); |
| 343 | QVERIFY(url3bisNoSlash.matches(url4bis, QUrl::NormalizePathSegments | QUrl::StripTrailingSlash)); |
| 344 | |
| 345 | QUrl url4EncodedDots = QUrl("example://a/.//b/%2E%2E%2F/b/c/" ); |
| 346 | QCOMPARE(url4EncodedDots.path(QUrl::PrettyDecoded), QString("/.//b/..%2F/b/c/" )); |
| 347 | QCOMPARE(url4EncodedDots.path(QUrl::FullyDecoded), QString("/.//b/..//b/c/" )); |
| 348 | QCOMPARE(QString::fromLatin1(url4EncodedDots.toEncoded()), QString::fromLatin1("example://a/.//b/..%2F/b/c/" )); |
| 349 | QCOMPARE(url4EncodedDots.toString(), QString("example://a/.//b/..%2F/b/c/" )); |
| 350 | QCOMPARE(url4EncodedDots.adjusted(QUrl::NormalizePathSegments).toString(), QString("example://a//b/..%2F/b/c/" )); |
| 351 | |
| 352 | // 6.2.2.1 Make sure hexdecimal characters in percent encoding are |
| 353 | // treated case-insensitively |
| 354 | QUrl url5; |
| 355 | url5.setQuery(query: QLatin1String("a=%2a" )); |
| 356 | QUrl url6; |
| 357 | url6.setQuery(query: QLatin1String("a=%2A" )); |
| 358 | QCOMPARE(url5, url6); |
| 359 | |
| 360 | QUrl url7; |
| 361 | url7.setQuery(query: QLatin1String("a=C" )); |
| 362 | QUrl url8; |
| 363 | url8.setQuery(query: QLatin1String("a=c" )); |
| 364 | QVERIFY(url7 != url8); |
| 365 | QVERIFY(url7 < url8); |
| 366 | |
| 367 | // Trailing slash difference |
| 368 | QUrl url9("http://qt-project.org/path/" ); |
| 369 | QUrl url9NoSlash("http://qt-project.org/path" ); |
| 370 | QVERIFY(!(url9 == url9NoSlash)); |
| 371 | QVERIFY(!url9.matches(url9NoSlash, QUrl::None)); |
| 372 | QVERIFY(url9.matches(url9NoSlash, QUrl::StripTrailingSlash)); |
| 373 | |
| 374 | // RemoveFilename |
| 375 | QUrl url10("http://qt-project.org/file" ); |
| 376 | QUrl url10bis("http://qt-project.org/otherfile" ); |
| 377 | QVERIFY(!(url10 == url10bis)); |
| 378 | QVERIFY(!url10.matches(url10bis, QUrl::None)); |
| 379 | QVERIFY(!url10.matches(url10bis, QUrl::StripTrailingSlash)); |
| 380 | QVERIFY(url10.matches(url10bis, QUrl::RemoveFilename)); |
| 381 | |
| 382 | // RemoveAuthority |
| 383 | QUrl authUrl1("x://host/a/b" ); |
| 384 | QUrl authUrl2("x://host/a/" ); |
| 385 | QUrl authUrl3("x:/a/b" ); |
| 386 | QVERIFY(authUrl1.matches(authUrl2, QUrl::RemoveFilename)); |
| 387 | QCOMPARE(authUrl1.adjusted(QUrl::RemoveAuthority), authUrl3.adjusted(QUrl::RemoveAuthority)); |
| 388 | QVERIFY(authUrl1.matches(authUrl3, QUrl::RemoveAuthority)); |
| 389 | QCOMPARE(authUrl2.adjusted(QUrl::RemoveAuthority | QUrl::RemoveFilename), authUrl3.adjusted(QUrl::RemoveAuthority | QUrl::RemoveFilename)); |
| 390 | QVERIFY(authUrl2.matches(authUrl3, QUrl::RemoveAuthority | QUrl::RemoveFilename)); |
| 391 | QVERIFY(authUrl3.matches(authUrl2, QUrl::RemoveAuthority | QUrl::RemoveFilename)); |
| 392 | |
| 393 | QUrl hostUrl1("file:/foo" ); |
| 394 | QUrl hostUrl2("file:///foo" ); |
| 395 | QCOMPARE(hostUrl1, hostUrl2); |
| 396 | QVERIFY(hostUrl1.matches(hostUrl2, QUrl::None)); |
| 397 | QVERIFY(hostUrl1.matches(hostUrl2, QUrl::RemoveAuthority)); |
| 398 | |
| 399 | // RemovePassword |
| 400 | QUrl passUrl1("http://user:pass@host/" ); |
| 401 | QUrl passUrl2("http://user:PASS@host/" ); |
| 402 | QVERIFY(!(passUrl1 == passUrl2)); |
| 403 | QVERIFY(passUrl1 != passUrl2); |
| 404 | QVERIFY(!passUrl1.matches(passUrl2, QUrl::None)); |
| 405 | QVERIFY(passUrl1.matches(passUrl2, QUrl::RemovePassword)); |
| 406 | |
| 407 | // RemovePassword, null vs empty |
| 408 | QUrl emptyPassUrl1("http://user:@host/" ); |
| 409 | QUrl emptyPassUrl2("http://user@host/" ); |
| 410 | QVERIFY(!(emptyPassUrl1 == emptyPassUrl2)); |
| 411 | QVERIFY(emptyPassUrl1 != emptyPassUrl2); |
| 412 | QVERIFY(!emptyPassUrl1.matches(emptyPassUrl2, QUrl::None)); |
| 413 | QVERIFY(emptyPassUrl1.matches(emptyPassUrl2, QUrl::RemovePassword)); |
| 414 | |
| 415 | // RemoveQuery, RemoveFragment |
| 416 | QUrl queryFragUrl1("http://host/file?query#fragment" ); |
| 417 | QUrl queryFragUrl2("http://host/file?q2#f2" ); |
| 418 | QUrl queryFragUrl3("http://host/file" ); |
| 419 | QVERIFY(!(queryFragUrl1 == queryFragUrl2)); |
| 420 | QVERIFY(queryFragUrl1 != queryFragUrl2); |
| 421 | QVERIFY(!queryFragUrl1.matches(queryFragUrl2, QUrl::None)); |
| 422 | QVERIFY(!queryFragUrl1.matches(queryFragUrl2, QUrl::RemoveQuery)); |
| 423 | QVERIFY(!queryFragUrl1.matches(queryFragUrl2, QUrl::RemoveFragment)); |
| 424 | QVERIFY(queryFragUrl1.matches(queryFragUrl2, QUrl::RemoveQuery | QUrl::RemoveFragment)); |
| 425 | QVERIFY(queryFragUrl1.matches(queryFragUrl3, QUrl::RemoveQuery | QUrl::RemoveFragment)); |
| 426 | QVERIFY(queryFragUrl3.matches(queryFragUrl1, QUrl::RemoveQuery | QUrl::RemoveFragment)); |
| 427 | } |
| 428 | |
| 429 | void tst_QUrl::comparison2_data() |
| 430 | { |
| 431 | QTest::addColumn<QUrl>(name: "url1" ); |
| 432 | QTest::addColumn<QUrl>(name: "url2" ); |
| 433 | QTest::addColumn<int>(name: "ordering" ); // like strcmp |
| 434 | |
| 435 | QTest::newRow(dataTag: "null-null" ) << QUrl() << QUrl() << 0; |
| 436 | |
| 437 | QUrl empty; |
| 438 | empty.setPath(path: "/hello" ); // ensure it has detached |
| 439 | empty.setPath(path: QString()); |
| 440 | QTest::newRow(dataTag: "null-empty" ) << QUrl() << empty << 0; |
| 441 | |
| 442 | QTest::newRow(dataTag: "scheme-null" ) << QUrl("x:" ) << QUrl() << 1; |
| 443 | QTest::newRow(dataTag: "samescheme" ) << QUrl("x:" ) << QUrl("x:" ) << 0; |
| 444 | QTest::newRow(dataTag: "no-fragment-empty-fragment" ) << QUrl("http://kde.org/dir/" ) << QUrl("http://kde.org/dir/#" ) << -1; |
| 445 | QTest::newRow(dataTag: "no-query-empty-query" ) << QUrl("http://kde.org/dir/" ) << QUrl("http://kde.org/dir/?" ) << -1; |
| 446 | QTest::newRow(dataTag: "simple-file-url" ) << QUrl("file:///home/dfaure/file" ) << QUrl("file:///home/dfaure/file" ) << 0; |
| 447 | QTest::newRow(dataTag: "fromLocalFile-vs-ctor" ) << QUrl::fromLocalFile(localfile: "/home/dfaure/file" ) << QUrl("file:///home/dfaure/file" ) << 0; |
| 448 | |
| 449 | // the following three are by choice |
| 450 | // the order could be the opposite and it would still be correct |
| 451 | QTest::newRow(dataTag: "scheme-path" ) << QUrl("x:" ) << QUrl("/tmp" ) << +1; |
| 452 | QTest::newRow(dataTag: "fragment-path" ) << QUrl("#foo" ) << QUrl("/tmp" ) << -1; |
| 453 | QTest::newRow(dataTag: "fragment-scheme" ) << QUrl("#foo" ) << QUrl("x:" ) << -1; |
| 454 | |
| 455 | QTest::newRow(dataTag: "noport-zeroport" ) << QUrl("http://example.com" ) << QUrl("http://example.com:0" ) << -1; |
| 456 | } |
| 457 | |
| 458 | void tst_QUrl::comparison2() |
| 459 | { |
| 460 | QFETCH(QUrl, url1); |
| 461 | QFETCH(QUrl, url2); |
| 462 | QFETCH(int, ordering); |
| 463 | |
| 464 | QCOMPARE(url1.toString() == url2.toString(), ordering == 0); |
| 465 | QCOMPARE(url1 == url2, ordering == 0); |
| 466 | QCOMPARE(url1 != url2, ordering != 0); |
| 467 | if (ordering == 0) |
| 468 | QCOMPARE(qHash(url1), qHash(url2)); |
| 469 | |
| 470 | QCOMPARE(url1 < url2, ordering < 0); |
| 471 | QCOMPARE(!(url1 < url2), ordering >= 0); |
| 472 | |
| 473 | QCOMPARE(url2 < url1, ordering > 0); |
| 474 | QCOMPARE(!(url2 < url1), ordering <= 0); |
| 475 | |
| 476 | // redundant checks (the above should catch these) |
| 477 | QCOMPARE(url1 < url2 || url2 < url1, ordering != 0); |
| 478 | QVERIFY(!(url1 < url2 && url2 < url1)); |
| 479 | QVERIFY(url1 < url2 || url1 == url2 || url2 < url1); |
| 480 | } |
| 481 | |
| 482 | void tst_QUrl::copying() |
| 483 | { |
| 484 | QUrl url("http://qt-project.org/" ); |
| 485 | QVERIFY(url.isValid()); |
| 486 | |
| 487 | QUrl copy(url); |
| 488 | |
| 489 | QCOMPARE(url, copy); |
| 490 | } |
| 491 | |
| 492 | void tst_QUrl::setUrl() |
| 493 | { |
| 494 | { |
| 495 | QUrl url("http://0.foo.com" ); |
| 496 | QVERIFY(url.isValid()); |
| 497 | QCOMPARE(url.scheme(), QString::fromLatin1("http" )); |
| 498 | QCOMPARE(url.path(), QString()); |
| 499 | QCOMPARE(url.host(), QString::fromLatin1("0.foo.com" )); |
| 500 | } |
| 501 | |
| 502 | { |
| 503 | QUrl url("file:/" ); |
| 504 | QVERIFY(url.isValid()); |
| 505 | QCOMPARE(url.scheme(), QString::fromLatin1("file" )); |
| 506 | QCOMPARE(url.path(), QString::fromLatin1("/" )); |
| 507 | QVERIFY(url.query().isEmpty()); |
| 508 | QVERIFY(url.userInfo().isEmpty()); |
| 509 | QVERIFY(url.authority().isEmpty()); |
| 510 | QVERIFY(url.fragment().isEmpty()); |
| 511 | QCOMPARE(url.port(), -1); |
| 512 | QCOMPARE(url.toString(), QString::fromLatin1("file:///" )); |
| 513 | QCOMPARE(url.toDisplayString(), QString::fromLatin1("file:///" )); |
| 514 | QCOMPARE(url.toDisplayString(QUrl::PreferLocalFile), QString::fromLatin1("/" )); |
| 515 | } |
| 516 | |
| 517 | { |
| 518 | QUrl url("hTTp://www.foo.bar:80" ); |
| 519 | QVERIFY(url.isValid()); |
| 520 | QCOMPARE(url.scheme(), QString::fromLatin1("http" )); |
| 521 | QCOMPARE(url.path(), QString()); |
| 522 | QVERIFY(url.query().isEmpty()); |
| 523 | QVERIFY(url.userInfo().isEmpty()); |
| 524 | QVERIFY(url.fragment().isEmpty()); |
| 525 | QCOMPARE(url.host(), QString::fromLatin1("www.foo.bar" )); |
| 526 | QCOMPARE(url.authority(), QString::fromLatin1("www.foo.bar:80" )); |
| 527 | QCOMPARE(url.port(), 80); |
| 528 | QCOMPARE(url.toString(), QString::fromLatin1("http://www.foo.bar:80" )); |
| 529 | QCOMPARE(url.toDisplayString(), QString::fromLatin1("http://www.foo.bar:80" )); |
| 530 | QCOMPARE(url.toDisplayString(QUrl::PreferLocalFile), QString::fromLatin1("http://www.foo.bar:80" )); |
| 531 | |
| 532 | QUrl url2("//www1.foo.bar" ); |
| 533 | QCOMPARE(url.resolved(url2).toString(), QString::fromLatin1("http://www1.foo.bar" )); |
| 534 | } |
| 535 | |
| 536 | { |
| 537 | QUrl url("http://user%3A:pass%40@[56::56:56:56:127.0.0.1]:99" ); |
| 538 | QVERIFY(url.isValid()); |
| 539 | QCOMPARE(url.scheme(), QString::fromLatin1("http" )); |
| 540 | QCOMPARE(url.path(), QString()); |
| 541 | QVERIFY(url.query().isEmpty()); |
| 542 | QCOMPARE(url.userName(), QString::fromLatin1("user:" )); |
| 543 | QCOMPARE(url.password(), QString::fromLatin1("pass@" )); |
| 544 | QCOMPARE(url.userInfo(), QString::fromLatin1("user%3A:pass@" )); |
| 545 | QVERIFY(url.fragment().isEmpty()); |
| 546 | QCOMPARE(url.host(), QString::fromLatin1("56::56:56:56:7f00:1" )); |
| 547 | QCOMPARE(url.authority(), QString::fromLatin1("user%3A:pass%40@[56::56:56:56:7f00:1]:99" )); |
| 548 | QCOMPARE(url.port(), 99); |
| 549 | QCOMPARE(url.url(), QString::fromLatin1("http://user%3A:pass%40@[56::56:56:56:7f00:1]:99" )); |
| 550 | QCOMPARE(url.toDisplayString(), QString::fromLatin1("http://user%3A@[56::56:56:56:7f00:1]:99" )); |
| 551 | } |
| 552 | |
| 553 | { |
| 554 | QUrl url("http://user@localhost:8000/xmlhttprequest/resources/basic-auth-nouserpass/basic-auth-nouserpass.php" ); |
| 555 | QVERIFY(url.isValid()); |
| 556 | QCOMPARE(url.scheme(), QString::fromLatin1("http" )); |
| 557 | QCOMPARE(url.userName(), QString::fromLatin1("user" )); |
| 558 | QCOMPARE(url.password(), QString()); |
| 559 | QCOMPARE(url.userInfo(), QString::fromLatin1("user" )); |
| 560 | QCOMPARE(url.port(), 8000); |
| 561 | } |
| 562 | |
| 563 | { |
| 564 | QUrl url("http://www.foo.bar" ); |
| 565 | QVERIFY(url.isValid()); |
| 566 | |
| 567 | QUrl url2("/top//test/../test1/file.html" ); |
| 568 | QCOMPARE(url.resolved(url2).toString(), QString::fromLatin1("http://www.foo.bar/top//test1/file.html" )); |
| 569 | } |
| 570 | |
| 571 | { |
| 572 | QUrl url("http://www.foo.bar" ); |
| 573 | QVERIFY(url.isValid()); |
| 574 | |
| 575 | QUrl url2("/top//test/../test1/file.html" ); |
| 576 | QCOMPARE(url.resolved(url2).toString(), QString::fromLatin1("http://www.foo.bar/top//test1/file.html" )); |
| 577 | } |
| 578 | |
| 579 | { |
| 580 | QUrl url("http://www.foo.bar/top//test2/file2.html" ); |
| 581 | QVERIFY(url.isValid()); |
| 582 | |
| 583 | QCOMPARE(url.toString(), QString::fromLatin1("http://www.foo.bar/top//test2/file2.html" )); |
| 584 | } |
| 585 | |
| 586 | { |
| 587 | QUrl url("http://www.foo.bar/top//test2/file2.html" ); |
| 588 | QVERIFY(url.isValid()); |
| 589 | |
| 590 | QCOMPARE(url.toString(), QString::fromLatin1("http://www.foo.bar/top//test2/file2.html" )); |
| 591 | } |
| 592 | |
| 593 | { |
| 594 | QUrl url("file:/usr/local/src/kde2/////kdelibs/kio" ); |
| 595 | QVERIFY(url.isValid()); |
| 596 | QCOMPARE(url.toString(), QString::fromLatin1("file:///usr/local/src/kde2/////kdelibs/kio" )); |
| 597 | } |
| 598 | |
| 599 | { |
| 600 | QUrl url("http://www.foo.bar" ); |
| 601 | QVERIFY(url.isValid()); |
| 602 | |
| 603 | QUrl url2("mailto:bastian@kde.org" ); |
| 604 | QVERIFY(url2.isValid()); |
| 605 | QCOMPARE(url.resolved(url2).toString(), QString::fromLatin1("mailto:bastian@kde.org" )); |
| 606 | } |
| 607 | |
| 608 | { |
| 609 | QUrl url("mailto:bastian@kde.org?subject=hello" ); |
| 610 | QCOMPARE(url.toString(), QString::fromLatin1("mailto:bastian@kde.org?subject=hello" )); |
| 611 | } |
| 612 | |
| 613 | { |
| 614 | QUrl url("file:/usr/local/src/kde2/kdelibs/kio/" ); |
| 615 | QVERIFY(url.isValid()); |
| 616 | |
| 617 | QUrl url2("../../////kdebase/konqueror" ); |
| 618 | QCOMPARE(url.resolved(url2).toString(), |
| 619 | QString::fromLatin1("file:///usr/local/src/kde2/////kdebase/konqueror" )); |
| 620 | } |
| 621 | |
| 622 | { |
| 623 | QString u1 = "file:/home/dfaure/my#myref" ; |
| 624 | QUrl url = u1; |
| 625 | QVERIFY(url.isValid()); |
| 626 | QCOMPARE(url.toString(), QString::fromLatin1("file:///home/dfaure/my#myref" )); |
| 627 | QCOMPARE(url.toString(QUrl::PreferLocalFile), QString::fromLatin1("file:///home/dfaure/my#myref" )); |
| 628 | QCOMPARE(url.fragment(), QString::fromLatin1("myref" )); |
| 629 | } |
| 630 | |
| 631 | { |
| 632 | QUrl url("gg:www.kde.org" ); |
| 633 | QVERIFY(url.isValid()); |
| 634 | QCOMPARE(url.scheme(), QString::fromLatin1("gg" )); |
| 635 | QVERIFY(url.host().isEmpty()); |
| 636 | QCOMPARE(url.path(), QString::fromLatin1("www.kde.org" )); |
| 637 | } |
| 638 | |
| 639 | { |
| 640 | QUrl url("KDE" ); |
| 641 | QVERIFY(url.isValid()); |
| 642 | QCOMPARE(url.path(), QString::fromLatin1("KDE" )); |
| 643 | QVERIFY(url.scheme().isEmpty()); |
| 644 | } |
| 645 | |
| 646 | { |
| 647 | QUrl url("$HOME/.kde/share/config" ); |
| 648 | QVERIFY(url.isValid()); |
| 649 | QCOMPARE(url.path(), QString::fromLatin1("$HOME/.kde/share/config" )); |
| 650 | QVERIFY(url.scheme().isEmpty()); |
| 651 | } |
| 652 | |
| 653 | { |
| 654 | QUrl url("file:/opt/kde2/qt2/doc/html/showimg-main-cpp.html#QObject::connect" ); |
| 655 | QVERIFY(url.isValid()); |
| 656 | QCOMPARE(url.fragment(), QString::fromLatin1("QObject::connect" )); |
| 657 | } |
| 658 | |
| 659 | { |
| 660 | QUrl url("file:/opt/kde2/qt2/doc/html/showimg-main-cpp.html#QObject:connect" ); |
| 661 | QVERIFY(url.isValid()); |
| 662 | QCOMPARE(url.fragment(), QString::fromLatin1("QObject:connect" )); |
| 663 | } |
| 664 | |
| 665 | { |
| 666 | // suburls |
| 667 | QUrl url("file:/home/dfaure/my%20tar%20file.tgz#gzip:/#tar:/#myref" ); |
| 668 | QVERIFY(url.isValid()); |
| 669 | |
| 670 | // or simply 'myref?' |
| 671 | QCOMPARE(url.fragment(), QString::fromLatin1("gzip:/#tar:/#myref" )); |
| 672 | } |
| 673 | |
| 674 | { |
| 675 | QUrl url("error:/?error=14&errText=Unknown%20host%20asdfu.adgi.sdfgoi#http://asdfu.adgi.sdfgoi" ); |
| 676 | QVERIFY(url.isValid()); |
| 677 | QCOMPARE(url.fragment(), QString::fromLatin1("http://asdfu.adgi.sdfgoi" )); |
| 678 | } |
| 679 | |
| 680 | { |
| 681 | // suburls |
| 682 | QUrl url("file:/home/dfaure/my%20tar%20file.tgz#gzip:/#tar:/" ); |
| 683 | QVERIFY(url.isValid()); |
| 684 | } |
| 685 | |
| 686 | { |
| 687 | QUrl url("file:/home/dfaure/cdrdao-1.1.5/dao/#CdrDriver.cc#" ); |
| 688 | QVERIFY(url.isValid()); |
| 689 | } |
| 690 | |
| 691 | { |
| 692 | QUrl url("file:/home/dfaure/my%20tar%20file.tgz#gzip:/#tar:/README" ); |
| 693 | QVERIFY(url.isValid()); |
| 694 | QCOMPARE(url.toString(), QString::fromLatin1("file:///home/dfaure/my tar file.tgz#gzip:/#tar:/README" )); |
| 695 | } |
| 696 | |
| 697 | { |
| 698 | QUrl notPretty("http://ferret.lmh.ox.ac.uk/%7Ekdecvs/" ); |
| 699 | QVERIFY(notPretty.isValid()); |
| 700 | QCOMPARE(notPretty.toString(), QString::fromLatin1("http://ferret.lmh.ox.ac.uk/~kdecvs/" )); |
| 701 | |
| 702 | QUrl notPretty2("file:/home/test/directory%20with%20spaces" ); |
| 703 | QVERIFY(notPretty2.isValid()); |
| 704 | QCOMPARE(notPretty2.toString(), QString::fromLatin1("file:///home/test/directory with spaces" )); |
| 705 | |
| 706 | QUrl notPretty3("fish://foo/%23README%23" ); |
| 707 | QVERIFY(notPretty3.isValid()); |
| 708 | QCOMPARE(notPretty3.toString(), QString::fromLatin1("fish://foo/%23README%23" )); |
| 709 | |
| 710 | QUrl url15581; |
| 711 | url15581.setUrl(url: "http://alain.knaff.linux.lu/bug-reports/kde/spaces in url.html" ); |
| 712 | QCOMPARE(url15581.toString(), QString::fromLatin1("http://alain.knaff.linux.lu/bug-reports/kde/spaces in url.html" )); |
| 713 | QCOMPARE(url15581.toEncoded().constData(), QByteArray("http://alain.knaff.linux.lu/bug-reports/kde/spaces%20in%20url.html" ).constData()); |
| 714 | |
| 715 | QUrl url15582("http://alain.knaff.linux.lu/bug-reports/kde/percentage%in%url.html" ); |
| 716 | QCOMPARE(url15582.toString(), QString::fromLatin1("http://alain.knaff.linux.lu/bug-reports/kde/percentage%25in%25url.html" )); |
| 717 | QCOMPARE(url15582.toEncoded(), QByteArray("http://alain.knaff.linux.lu/bug-reports/kde/percentage%25in%25url.html" )); |
| 718 | QCOMPARE(url15582.toString(QUrl::FullyEncoded), QString("http://alain.knaff.linux.lu/bug-reports/kde/percentage%25in%25url.html" )); |
| 719 | } |
| 720 | |
| 721 | { |
| 722 | QUrl carsten; |
| 723 | carsten.setPath(path: "/home/gis/src/kde/kdelibs/kfile/.#kfiledetailview.cpp.1.18" ); |
| 724 | QCOMPARE(carsten.path(), QString::fromLatin1("/home/gis/src/kde/kdelibs/kfile/.#kfiledetailview.cpp.1.18" )); |
| 725 | |
| 726 | QUrl charles; |
| 727 | charles.setPath(path: "/home/charles/foo%20moo" ); |
| 728 | QCOMPARE(charles.path(), QString::fromLatin1("/home/charles/foo%20moo" )); |
| 729 | QCOMPARE(charles.path(QUrl::FullyEncoded), QString::fromLatin1("/home/charles/foo%2520moo" )); |
| 730 | |
| 731 | QUrl charles2("file:/home/charles/foo%20moo" ); |
| 732 | QCOMPARE(charles2.path(), QString::fromLatin1("/home/charles/foo moo" )); |
| 733 | QCOMPARE(charles2.path(QUrl::FullyEncoded), QString::fromLatin1("/home/charles/foo%20moo" )); |
| 734 | } |
| 735 | |
| 736 | { |
| 737 | QUrl udir; |
| 738 | QCOMPARE(udir.toEncoded(), QByteArray()); |
| 739 | QCOMPARE(udir.toString(QUrl::FullyEncoded), QString()); |
| 740 | QVERIFY(!udir.isValid()); |
| 741 | |
| 742 | udir = QUrl::fromLocalFile(localfile: "/home/dfaure/file.txt" ); |
| 743 | QCOMPARE(udir.path(), QString::fromLatin1("/home/dfaure/file.txt" )); |
| 744 | QCOMPARE(udir.toEncoded(), QByteArray("file:///home/dfaure/file.txt" )); |
| 745 | QCOMPARE(udir.toString(QUrl::FullyEncoded), QString("file:///home/dfaure/file.txt" )); |
| 746 | } |
| 747 | |
| 748 | { |
| 749 | QUrl url; |
| 750 | url.setUrl(url: "hello.com#?" ); |
| 751 | QVERIFY(url.isValid()); |
| 752 | url.setUrl(url: "hello.com" ); |
| 753 | QVERIFY(!url.toString().contains(QLatin1Char('#'))); |
| 754 | QVERIFY(!url.toString().contains(QLatin1Char('?'))); |
| 755 | } |
| 756 | |
| 757 | { |
| 758 | QUrl url; |
| 759 | url.setUrl(url: "http://1.2.3.4.example.com" ); |
| 760 | QVERIFY(url.isValid()); |
| 761 | QCOMPARE(url.scheme(), QString("http" )); |
| 762 | QCOMPARE(url.host(), QString("1.2.3.4.example.com" )); |
| 763 | } |
| 764 | |
| 765 | { |
| 766 | QUrl url; |
| 767 | url.setUrl(url: "http://1.2.3.4" ); |
| 768 | QVERIFY(url.isValid()); |
| 769 | QCOMPARE(url.scheme(), QString("http" )); |
| 770 | QCOMPARE(url.host(), QString("1.2.3.4" )); |
| 771 | } |
| 772 | { |
| 773 | QUrl url; |
| 774 | url.setUrl(url: "http://1.2.3.4/" ); |
| 775 | QVERIFY(url.isValid()); |
| 776 | QCOMPARE(url.scheme(), QString("http" )); |
| 777 | QCOMPARE(url.host(), QString("1.2.3.4" )); |
| 778 | QCOMPARE(url.path(), QString("/" )); |
| 779 | } |
| 780 | { |
| 781 | QUrl url; |
| 782 | url.setUrl(url: "http://1.2.3.4?foo" ); |
| 783 | QVERIFY(url.isValid()); |
| 784 | QCOMPARE(url.scheme(), QString("http" )); |
| 785 | QCOMPARE(url.host(), QString("1.2.3.4" )); |
| 786 | QCOMPARE(url.query(QUrl::FullyEncoded), QLatin1String("foo" )); |
| 787 | } |
| 788 | { |
| 789 | QUrl url; |
| 790 | url.setUrl(url: "http://1.2.3.4#bar" ); |
| 791 | QVERIFY(url.isValid()); |
| 792 | QCOMPARE(url.scheme(), QString("http" )); |
| 793 | QCOMPARE(url.host(), QString("1.2.3.4" )); |
| 794 | QCOMPARE(url.fragment(), QString("bar" )); |
| 795 | } |
| 796 | |
| 797 | { |
| 798 | QUrl url("data:text/javascript,d5%20%3D%20'five\\u0027s'%3B" ); |
| 799 | QVERIFY(url.isValid()); |
| 800 | QCOMPARE(url.scheme(), QString("data" )); |
| 801 | QCOMPARE(url.host(), QString()); |
| 802 | QCOMPARE(url.path(), QString("text/javascript,d5 = 'five\\u0027s';" )); |
| 803 | QCOMPARE(url.path(QUrl::FullyEncoded), QLatin1String("text/javascript,d5%20%3D%20'five%5Cu0027s'%3B" )); |
| 804 | } |
| 805 | |
| 806 | { |
| 807 | // invalid port number |
| 808 | QUrl url; |
| 809 | url.setUrl(url: QLatin1String("foo://tel:2147483648" ), mode: QUrl::StrictMode); |
| 810 | QVERIFY(!url.isValid()); |
| 811 | } |
| 812 | |
| 813 | { //check it calls detach |
| 814 | QUrl u1("http://aaa.com" ); |
| 815 | QUrl u2 = u1; |
| 816 | u2.setUrl(url: "http://bbb.com" ); |
| 817 | QCOMPARE(u1.host(), QString::fromLatin1("aaa.com" )); |
| 818 | QCOMPARE(u2.host(), QString::fromLatin1("bbb.com" )); |
| 819 | } |
| 820 | } |
| 821 | |
| 822 | void tst_QUrl::i18n_data() |
| 823 | { |
| 824 | QTest::addColumn<QString>(name: "input" ); |
| 825 | QTest::addColumn<QByteArray>(name: "punyOutput" ); |
| 826 | |
| 827 | QTest::newRow(dataTag: "øl" ) << QString::fromUtf8(str: "http://ole:passord@www.øl.no/index.html?ole=æsemann&ilder gud=hei#top" ) |
| 828 | << QByteArray("http://ole:passord@www.xn--l-4ga.no/index.html?ole=%C3%A6semann&ilder%20gud=hei#top" ); |
| 829 | QTest::newRow(dataTag: "räksmörgås" ) << QString::fromUtf8(str: "http://www.räksmörgås.no/" ) |
| 830 | << QByteArray("http://www.xn--rksmrgs-5wao1o.no/" ); |
| 831 | QTest::newRow(dataTag: "bühler" ) << QString::fromUtf8(str: "http://www.bühler.no/" ) |
| 832 | << QByteArray("http://www.xn--bhler-kva.no/" ); |
| 833 | QTest::newRow(dataTag: "non-latin1" ) |
| 834 | << QString::fromUtf8(str: "http://www.\316\261\316\270\316\256\316\275\316\261.info" ) |
| 835 | << QByteArray("http://www.xn--jxafb0a0a.info" ); |
| 836 | } |
| 837 | |
| 838 | void tst_QUrl::i18n() |
| 839 | { |
| 840 | QFETCH(QString, input); |
| 841 | QFETCH(QByteArray, punyOutput); |
| 842 | |
| 843 | QUrl url(input); |
| 844 | QVERIFY(url.isValid()); |
| 845 | |
| 846 | QCOMPARE(url.toEncoded().constData(), punyOutput.constData()); |
| 847 | QCOMPARE(QUrl::fromEncoded(punyOutput), url); |
| 848 | QCOMPARE(QUrl::fromEncoded(punyOutput).toString(), input); |
| 849 | } |
| 850 | |
| 851 | |
| 852 | void tst_QUrl::resolving_data() |
| 853 | { |
| 854 | QTest::addColumn<QString>(name: "baseUrl" ); |
| 855 | QTest::addColumn<QString>(name: "relativeUrl" ); |
| 856 | QTest::addColumn<QString>(name: "resolvedUrl" ); |
| 857 | |
| 858 | // 5.4.1 Normal Examples (http://www.ietf.org/rfc/rfc3986.txt) |
| 859 | QTest::newRow(dataTag: "g:h" ) << QString::fromLatin1(str: "http://a/b/c/d;p?q" ) << QString::fromLatin1(str: "g:h" ) << QString::fromLatin1(str: "g:h" ); |
| 860 | QTest::newRow(dataTag: "g" ) << QString::fromLatin1(str: "http://a/b/c/d;p?q" ) << QString::fromLatin1(str: "g" ) << QString::fromLatin1(str: "http://a/b/c/g" ); |
| 861 | QTest::newRow(dataTag: "./g" ) << QString::fromLatin1(str: "http://a/b/c/d;p?q" ) << QString::fromLatin1(str: "./g" ) << QString::fromLatin1(str: "http://a/b/c/g" ); |
| 862 | QTest::newRow(dataTag: "g/" ) << QString::fromLatin1(str: "http://a/b/c/d;p?q" ) << QString::fromLatin1(str: "g/" ) << QString::fromLatin1(str: "http://a/b/c/g/" ); |
| 863 | QTest::newRow(dataTag: "/g" ) << QString::fromLatin1(str: "http://a/b/c/d;p?q" ) << QString::fromLatin1(str: "/g" ) << QString::fromLatin1(str: "http://a/g" ); |
| 864 | QTest::newRow(dataTag: "//g" ) << QString::fromLatin1(str: "http://a/b/c/d;p?q" ) << QString::fromLatin1(str: "//g" ) << QString::fromLatin1(str: "http://g" ); |
| 865 | QTest::newRow(dataTag: "?y" ) << QString::fromLatin1(str: "http://a/b/c/d;p?q" ) << QString::fromLatin1(str: "?y" ) << QString::fromLatin1(str: "http://a/b/c/d;p?y" ); |
| 866 | QTest::newRow(dataTag: "g?y" ) << QString::fromLatin1(str: "http://a/b/c/d;p?q" ) << QString::fromLatin1(str: "g?y" ) << QString::fromLatin1(str: "http://a/b/c/g?y" ); |
| 867 | QTest::newRow(dataTag: "#s" ) << QString::fromLatin1(str: "http://a/b/c/d;p?q" ) << QString::fromLatin1(str: "#s" ) << QString::fromLatin1(str: "http://a/b/c/d;p?q#s" ); |
| 868 | QTest::newRow(dataTag: "g#s" ) << QString::fromLatin1(str: "http://a/b/c/d;p?q" ) << QString::fromLatin1(str: "g#s" ) << QString::fromLatin1(str: "http://a/b/c/g#s" ); |
| 869 | QTest::newRow(dataTag: "g?y#s" ) << QString::fromLatin1(str: "http://a/b/c/d;p?q" ) << QString::fromLatin1(str: "g?y#s" ) << QString::fromLatin1(str: "http://a/b/c/g?y#s" ); |
| 870 | QTest::newRow(dataTag: ";x" ) << QString::fromLatin1(str: "http://a/b/c/d;p?q" ) << QString::fromLatin1(str: ";x" ) << QString::fromLatin1(str: "http://a/b/c/;x" ); |
| 871 | QTest::newRow(dataTag: "g;x" ) << QString::fromLatin1(str: "http://a/b/c/d;p?q" ) << QString::fromLatin1(str: "g;x" ) << QString::fromLatin1(str: "http://a/b/c/g;x" ); |
| 872 | QTest::newRow(dataTag: "g;x?y#s" ) << QString::fromLatin1(str: "http://a/b/c/d;p?q" ) << QString::fromLatin1(str: "g;x?y#s" ) << QString::fromLatin1(str: "http://a/b/c/g;x?y#s" ); |
| 873 | QTest::newRow(dataTag: "[empty]" ) << QString::fromLatin1(str: "http://a/b/c/d;p?q" ) << QString::fromLatin1(str: "" ) << QString::fromLatin1(str: "http://a/b/c/d;p?q" ); |
| 874 | QTest::newRow(dataTag: "." ) << QString::fromLatin1(str: "http://a/b/c/d;p?q" ) << QString::fromLatin1(str: "." ) << QString::fromLatin1(str: "http://a/b/c/" ); |
| 875 | QTest::newRow(dataTag: "./" ) << QString::fromLatin1(str: "http://a/b/c/d;p?q" ) << QString::fromLatin1(str: "./" ) << QString::fromLatin1(str: "http://a/b/c/" ); |
| 876 | QTest::newRow(dataTag: ".." ) << QString::fromLatin1(str: "http://a/b/c/d;p?q" ) << QString::fromLatin1(str: ".." ) << QString::fromLatin1(str: "http://a/b/" ); |
| 877 | QTest::newRow(dataTag: "../" ) << QString::fromLatin1(str: "http://a/b/c/d;p?q" ) << QString::fromLatin1(str: "../" ) << QString::fromLatin1(str: "http://a/b/" ); |
| 878 | QTest::newRow(dataTag: "../g" ) << QString::fromLatin1(str: "http://a/b/c/d;p?q" ) << QString::fromLatin1(str: "../g" ) << QString::fromLatin1(str: "http://a/b/g" ); |
| 879 | QTest::newRow(dataTag: "../.." ) << QString::fromLatin1(str: "http://a/b/c/d;p?q" ) << QString::fromLatin1(str: "../.." ) << QString::fromLatin1(str: "http://a/" ); |
| 880 | QTest::newRow(dataTag: "../../" ) << QString::fromLatin1(str: "http://a/b/c/d;p?q" ) << QString::fromLatin1(str: "../../" ) << QString::fromLatin1(str: "http://a/" ); |
| 881 | QTest::newRow(dataTag: "../../g" ) << QString::fromLatin1(str: "http://a/b/c/d;p?q" ) << QString::fromLatin1(str: "../../g" ) << QString::fromLatin1(str: "http://a/g" ); |
| 882 | |
| 883 | // 5.4.2 Abnormal Examples (http://www.ietf.org/rfc/rfc3986.txt) |
| 884 | |
| 885 | // Parsers must be careful in handling cases where there are more |
| 886 | // relative path ".." segments than there are hierarchical levels in the |
| 887 | // base URI's path. Note that the ".." syntax cannot be used to change |
| 888 | // the authority component of a URI. |
| 889 | QTest::newRow(dataTag: "../../../g" ) << QString::fromLatin1(str: "http://a/b/c/d;p?q" ) << QString::fromLatin1(str: "../../../g" ) << QString::fromLatin1(str: "http://a/g" ); |
| 890 | QTest::newRow(dataTag: "../../../../g" ) << QString::fromLatin1(str: "http://a/b/c/d;p?q" ) << QString::fromLatin1(str: "../../../../g" ) << QString::fromLatin1(str: "http://a/g" ); |
| 891 | |
| 892 | // Similarly, parsers must remove the dot-segments "." and ".." when |
| 893 | // they are complete components of a path, but not when they are only |
| 894 | // part of a segment. |
| 895 | QTest::newRow(dataTag: "/./g" ) << QString::fromLatin1(str: "http://a/b/c/d;p?q" ) << QString::fromLatin1(str: "/./g" ) << QString::fromLatin1(str: "http://a/g" ); |
| 896 | QTest::newRow(dataTag: "/../g" ) << QString::fromLatin1(str: "http://a/b/c/d;p?q" ) << QString::fromLatin1(str: "/../g" ) << QString::fromLatin1(str: "http://a/g" ); |
| 897 | QTest::newRow(dataTag: "g." ) << QString::fromLatin1(str: "http://a/b/c/d;p?q" ) << QString::fromLatin1(str: "g." ) << QString::fromLatin1(str: "http://a/b/c/g." ); |
| 898 | QTest::newRow(dataTag: ".g" ) << QString::fromLatin1(str: "http://a/b/c/d;p?q" ) << QString::fromLatin1(str: ".g" ) << QString::fromLatin1(str: "http://a/b/c/.g" ); |
| 899 | QTest::newRow(dataTag: "g.." ) << QString::fromLatin1(str: "http://a/b/c/d;p?q" ) << QString::fromLatin1(str: "g.." ) << QString::fromLatin1(str: "http://a/b/c/g.." ); |
| 900 | QTest::newRow(dataTag: "..g" ) << QString::fromLatin1(str: "http://a/b/c/d;p?q" ) << QString::fromLatin1(str: "..g" ) << QString::fromLatin1(str: "http://a/b/c/..g" ); |
| 901 | |
| 902 | // Less likely are cases where the relative URI reference uses |
| 903 | // unnecessary or nonsensical forms of the "." and ".." complete path |
| 904 | // segments. |
| 905 | QTest::newRow(dataTag: "./../g" ) << QString::fromLatin1(str: "http://a/b/c/d;p?q" ) << QString::fromLatin1(str: "./../g" ) << QString::fromLatin1(str: "http://a/b/g" ); |
| 906 | QTest::newRow(dataTag: "./g/." ) << QString::fromLatin1(str: "http://a/b/c/d;p?q" ) << QString::fromLatin1(str: "./g/." ) << QString::fromLatin1(str: "http://a/b/c/g/" ); |
| 907 | QTest::newRow(dataTag: "g/./h" ) << QString::fromLatin1(str: "http://a/b/c/d;p?q" ) << QString::fromLatin1(str: "g/./h" ) << QString::fromLatin1(str: "http://a/b/c/g/h" ); |
| 908 | QTest::newRow(dataTag: "g/../h" ) << QString::fromLatin1(str: "http://a/b/c/d;p?q" ) << QString::fromLatin1(str: "g/../h" ) << QString::fromLatin1(str: "http://a/b/c/h" ); |
| 909 | QTest::newRow(dataTag: "g;x=1/./y" ) << QString::fromLatin1(str: "http://a/b/c/d;p?q" ) << QString::fromLatin1(str: "g;x=1/./y" ) << QString::fromLatin1(str: "http://a/b/c/g;x=1/y" ); |
| 910 | QTest::newRow(dataTag: "g;x=1/../y" ) << QString::fromLatin1(str: "http://a/b/c/d;p?q" ) << QString::fromLatin1(str: "g;x=1/../y" ) << QString::fromLatin1(str: "http://a/b/c/y" ); |
| 911 | |
| 912 | // Some applications fail to separate the reference's query and/or |
| 913 | // fragment components from a relative path before merging it with the |
| 914 | // base path and removing dot-segments. This error is rarely noticed, |
| 915 | // since typical usage of a fragment never includes the hierarchy ("/") |
| 916 | // character, and the query component is not normally used within |
| 917 | // relative references. |
| 918 | QTest::newRow(dataTag: "g?y/./x" ) << QString::fromLatin1(str: "http://a/b/c/d;p?q" ) << QString::fromLatin1(str: "g?y/./x" ) << QString::fromLatin1(str: "http://a/b/c/g?y/./x" ); |
| 919 | QTest::newRow(dataTag: "g?y/../x" ) << QString::fromLatin1(str: "http://a/b/c/d;p?q" ) << QString::fromLatin1(str: "g?y/../x" ) << QString::fromLatin1(str: "http://a/b/c/g?y/../x" ); |
| 920 | QTest::newRow(dataTag: "g#s/./x" ) << QString::fromLatin1(str: "http://a/b/c/d;p?q" ) << QString::fromLatin1(str: "g#s/./x" ) << QString::fromLatin1(str: "http://a/b/c/g#s/./x" ); |
| 921 | QTest::newRow(dataTag: "g#s/../x" ) << QString::fromLatin1(str: "http://a/b/c/d;p?q" ) << QString::fromLatin1(str: "g#s/../x" ) << QString::fromLatin1(str: "http://a/b/c/g#s/../x" ); |
| 922 | |
| 923 | // Some parsers allow the scheme name to be present in a relative URI |
| 924 | // reference if it is the same as the base URI scheme. This is |
| 925 | // considered to be a loophole in prior specifications of partial URI [RFC1630], |
| 926 | //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"); |
| 927 | // However we don't do that anymore, as per RFC3986, in order for the data:subpage testcase below to work. |
| 928 | QTest::newRow(dataTag: "http:g" ) << QString::fromLatin1(str: "http://a/b/c/d;p?q" ) << QString::fromLatin1(str: "http:g" ) << QString::fromLatin1(str: "http:g" ); |
| 929 | QTest::newRow(dataTag: "data:subpage" ) << QString::fromLatin1(str: "data:text/plain, main page" ) << QString::fromLatin1(str: "data:text/plain, subpage" ) << QString::fromLatin1(str: "data:text/plain, subpage" ); |
| 930 | |
| 931 | // Resolve relative with relative |
| 932 | QTest::newRow(dataTag: "../a (1)" ) << QString::fromLatin1(str: "b" ) << QString::fromLatin1(str: "../a" ) << QString::fromLatin1(str: "a" ); |
| 933 | QTest::newRow(dataTag: "../a (2)" ) << QString::fromLatin1(str: "b/a" ) << QString::fromLatin1(str: "../a" ) << QString::fromLatin1(str: "a" ); |
| 934 | QTest::newRow(dataTag: "../a (3)" ) << QString::fromLatin1(str: "b/c/a" ) << QString::fromLatin1(str: "../a" ) << QString::fromLatin1(str: "b/a" ); |
| 935 | QTest::newRow(dataTag: "../a (4)" ) << QString::fromLatin1(str: "b" ) << QString::fromLatin1(str: "/a" ) << QString::fromLatin1(str: "/a" ); |
| 936 | |
| 937 | QTest::newRow(dataTag: "../a (5)" ) << QString::fromLatin1(str: "/b" ) << QString::fromLatin1(str: "../a" ) << QString::fromLatin1(str: "/a" ); |
| 938 | QTest::newRow(dataTag: "../a (6)" ) << QString::fromLatin1(str: "/b/a" ) << QString::fromLatin1(str: "../a" ) << QString::fromLatin1(str: "/a" ); |
| 939 | QTest::newRow(dataTag: "../a (7)" ) << QString::fromLatin1(str: "/b/c/a" ) << QString::fromLatin1(str: "../a" ) << QString::fromLatin1(str: "/b/a" ); |
| 940 | QTest::newRow(dataTag: "../a (8)" ) << QString::fromLatin1(str: "/b" ) << QString::fromLatin1(str: "/a" ) << QString::fromLatin1(str: "/a" ); |
| 941 | |
| 942 | // More tests from KDE |
| 943 | QTest::newRow(dataTag: "brackets" ) << QString::fromLatin1(str: "http://www.calorieking.com/personal/diary/" ) << QString::fromLatin1(str: "/personal/diary/rpc.php?C=jsrs1&F=getDiaryDay&P0=[2006-3-8]&U=1141858921458" ) << QString::fromLatin1(str: "http://www.calorieking.com/personal/diary/rpc.php?C=jsrs1&F=getDiaryDay&P0=[2006-3-8]&U=1141858921458" ); |
| 944 | QTest::newRow(dataTag: "javascript" )<< QString::fromLatin1(str: "http://www.youtube.com/?v=JvOSnRD5aNk" ) << QString::fromLatin1(str: "javascript:window.location+\"__flashplugin_unique__\"" ) << QString::fromLatin1(str: "javascript:window.location+%22__flashplugin_unique__%22" ); |
| 945 | } |
| 946 | |
| 947 | void tst_QUrl::resolving() |
| 948 | { |
| 949 | QFETCH(QString, baseUrl); |
| 950 | QFETCH(QString, relativeUrl); |
| 951 | QFETCH(QString, resolvedUrl); |
| 952 | |
| 953 | QUrl url(baseUrl); |
| 954 | QCOMPARE(url.resolved(relativeUrl).toString(), resolvedUrl); |
| 955 | } |
| 956 | |
| 957 | void tst_QUrl::toString_data() |
| 958 | { |
| 959 | QTest::addColumn<QString>(name: "urlString" ); |
| 960 | QTest::addColumn<uint>(name: "options" ); |
| 961 | QTest::addColumn<QString>(name: "string" ); |
| 962 | |
| 963 | QTest::newRow(dataTag: "data0" ) << QString::fromLatin1(str: "http://ole:password@www.troll.no:9090/index.html?ole=semann&gud=hei#top" ) |
| 964 | << uint(QUrl::RemoveScheme) |
| 965 | << QString::fromLatin1(str: "//ole:password@www.troll.no:9090/index.html?ole=semann&gud=hei#top" ); |
| 966 | |
| 967 | QTest::newRow(dataTag: "data2" ) << QString::fromLatin1(str: "http://ole:password@www.troll.no:9090/index.html?ole=semann&gud=hei#top" ) |
| 968 | << uint(QUrl::RemovePassword) |
| 969 | << QString::fromLatin1(str: "http://ole@www.troll.no:9090/index.html?ole=semann&gud=hei#top" ); |
| 970 | |
| 971 | // show that QUrl keeps the empty-but-present username if you remove the password |
| 972 | // see data3-bis for another case |
| 973 | QTest::newRow(dataTag: "data2-bis" ) << QString::fromLatin1(str: "http://:password@www.troll.no:9090/index.html?ole=semann&gud=hei#top" ) |
| 974 | << uint(QUrl::RemovePassword) |
| 975 | << QString::fromLatin1(str: "http://@www.troll.no:9090/index.html?ole=semann&gud=hei#top" ); |
| 976 | |
| 977 | QTest::newRow(dataTag: "data3" ) << QString::fromLatin1(str: "http://ole:password@www.troll.no:9090/index.html?ole=semann&gud=hei#top" ) |
| 978 | << uint(QUrl::RemoveUserInfo) |
| 979 | << QString::fromLatin1(str: "http://www.troll.no:9090/index.html?ole=semann&gud=hei#top" ); |
| 980 | |
| 981 | // show that QUrl keeps the empty-but-preset hostname if you remove the userinfo |
| 982 | QTest::newRow(dataTag: "data3-bis" ) << QString::fromLatin1(str: "http://ole:password@/index.html?ole=semann&gud=hei#top" ) |
| 983 | << uint(QUrl::RemoveUserInfo) |
| 984 | << QString::fromLatin1(str: "http:///index.html?ole=semann&gud=hei#top" ); |
| 985 | |
| 986 | QTest::newRow(dataTag: "data4" ) << QString::fromLatin1(str: "http://ole:password@www.troll.no:9090/index.html?ole=semann&gud=hei#top" ) |
| 987 | << uint(QUrl::RemovePort) |
| 988 | << QString::fromLatin1(str: "http://ole:password@www.troll.no/index.html?ole=semann&gud=hei#top" ); |
| 989 | |
| 990 | QTest::newRow(dataTag: "data5" ) << QString::fromLatin1(str: "http://ole:password@www.troll.no:9090/index.html?ole=semann&gud=hei#top" ) |
| 991 | << uint(QUrl::RemoveAuthority) |
| 992 | << QString::fromLatin1(str: "http:/index.html?ole=semann&gud=hei#top" ); |
| 993 | |
| 994 | QTest::newRow(dataTag: "data6" ) << QString::fromLatin1(str: "http://ole:password@www.troll.no:9090/index.html?ole=semann&gud=hei#top" ) |
| 995 | << uint(QUrl::RemovePath) |
| 996 | << QString::fromLatin1(str: "http://ole:password@www.troll.no:9090?ole=semann&gud=hei#top" ); |
| 997 | |
| 998 | QTest::newRow(dataTag: "data7" ) << QString::fromLatin1(str: "http://ole:password@www.troll.no:9090/index.html?ole=semann&gud=hei#top" ) |
| 999 | << uint(QUrl::RemoveQuery) |
| 1000 | << QString::fromLatin1(str: "http://ole:password@www.troll.no:9090/index.html#top" ); |
| 1001 | |
| 1002 | QTest::newRow(dataTag: "data8" ) << QString::fromLatin1(str: "http://ole:password@www.troll.no:9090/index.html?ole=semann&gud=hei#top" ) |
| 1003 | << uint(QUrl::RemoveFragment) |
| 1004 | << QString::fromLatin1(str: "http://ole:password@www.troll.no:9090/index.html?ole=semann&gud=hei" ); |
| 1005 | |
| 1006 | QTest::newRow(dataTag: "data9" ) << QString::fromLatin1(str: "http://ole:password@www.troll.no:9090/index.html?ole=semann&gud=hei#top" ) |
| 1007 | << uint(QUrl::RemoveScheme | QUrl::RemovePassword) |
| 1008 | << QString::fromLatin1(str: "//ole@www.troll.no:9090/index.html?ole=semann&gud=hei#top" ); |
| 1009 | |
| 1010 | QTest::newRow(dataTag: "data10" ) << QString::fromLatin1(str: "http://ole:password@www.troll.no:9090/index.html?ole=semann&gud=hei#top" ) |
| 1011 | << uint(QUrl::RemoveScheme | QUrl::RemoveUserInfo) |
| 1012 | << QString::fromLatin1(str: "//www.troll.no:9090/index.html?ole=semann&gud=hei#top" ); |
| 1013 | |
| 1014 | QTest::newRow(dataTag: "data11" ) << QString::fromLatin1(str: "http://ole:password@www.troll.no:9090/index.html?ole=semann&gud=hei#top" ) |
| 1015 | << uint(QUrl::RemoveScheme | QUrl::RemovePort) |
| 1016 | << QString::fromLatin1(str: "//ole:password@www.troll.no/index.html?ole=semann&gud=hei#top" ); |
| 1017 | |
| 1018 | QTest::newRow(dataTag: "data12" ) << QString::fromLatin1(str: "http://ole:password@www.troll.no:9090/index.html?ole=semann&gud=hei#top" ) |
| 1019 | << uint(QUrl::RemoveScheme | QUrl::RemoveAuthority) |
| 1020 | << QString::fromLatin1(str: "/index.html?ole=semann&gud=hei#top" ); |
| 1021 | |
| 1022 | QTest::newRow(dataTag: "data13" ) << QString::fromLatin1(str: "http://ole:password@www.troll.no:9090/index.html?ole=semann&gud=hei#top" ) |
| 1023 | << uint(QUrl::RemoveScheme | QUrl::RemovePath) |
| 1024 | << QString::fromLatin1(str: "//ole:password@www.troll.no:9090?ole=semann&gud=hei#top" ); |
| 1025 | |
| 1026 | QTest::newRow(dataTag: "data14" ) << QString::fromLatin1(str: "http://ole:password@www.troll.no:9090/index.html?ole=semann&gud=hei#top" ) |
| 1027 | << uint(QUrl::RemoveScheme | QUrl::RemoveAuthority | QUrl::RemoveFragment) |
| 1028 | << QString::fromLatin1(str: "/index.html?ole=semann&gud=hei" ); |
| 1029 | |
| 1030 | QTest::newRow(dataTag: "data15" ) << QString::fromLatin1(str: "http://ole:password@www.troll.no:9090/index.html?ole=semann&gud=hei#top" ) |
| 1031 | << uint(QUrl::RemoveAuthority | QUrl::RemoveQuery) |
| 1032 | << QString::fromLatin1(str: "http:/index.html#top" ); |
| 1033 | |
| 1034 | QTest::newRow(dataTag: "data16" ) << QString::fromLatin1(str: "http://ole:password@www.troll.no:9090/index.html?ole=semann&gud=hei#top" ) |
| 1035 | << uint(QUrl::RemovePassword | QUrl::RemovePort |
| 1036 | | QUrl::RemovePath | QUrl::RemoveQuery |
| 1037 | | QUrl::RemoveFragment) |
| 1038 | << QString::fromLatin1(str: "http://ole@www.troll.no" ); |
| 1039 | |
| 1040 | QTest::newRow(dataTag: "data17" ) << QString::fromLatin1(str: "http://ole:password@www.troll.no:9090/index.html?ole=semann&gud=hei#top" ) |
| 1041 | << uint(QUrl::RemoveScheme | QUrl::RemovePassword |
| 1042 | | QUrl::RemovePort | QUrl::RemovePath |
| 1043 | | QUrl::RemoveQuery | QUrl::RemoveFragment) |
| 1044 | << QString::fromLatin1(str: "//ole@www.troll.no" ); |
| 1045 | |
| 1046 | QTest::newRow(dataTag: "data18" ) << QString::fromLatin1(str: "http://andreas:hemmelig@www.vg.no/?my=query&your=query#yougotfragged" ) |
| 1047 | << uint(QUrl::None) |
| 1048 | << QString::fromLatin1(str: "http://andreas:hemmelig@www.vg.no/?my=query&your=query#yougotfragged" ); |
| 1049 | |
| 1050 | QTest::newRow(dataTag: "nopath" ) << QString::fromLatin1(str: "host://protocol" ) |
| 1051 | << uint(QUrl::None) |
| 1052 | << QString::fromLatin1(str: "host://protocol" ); |
| 1053 | |
| 1054 | QTest::newRow(dataTag: "underscore" ) << QString::fromLatin1(str: "http://foo_bar.host.com/rss.php" ) |
| 1055 | << uint(QUrl::None) |
| 1056 | << QString::fromLatin1(str: "http://foo_bar.host.com/rss.php" ); |
| 1057 | |
| 1058 | QTest::newRow(dataTag: "mailto-brackets" ) << QString::fromLatin1(str: "mailto:test[at]gmail[dot]com" ) |
| 1059 | << uint(QUrl::PrettyDecoded) |
| 1060 | << QString::fromLatin1(str: "mailto:test[at]gmail[dot]com" ); |
| 1061 | QTest::newRow(dataTag: "mailto-query" ) << QString::fromLatin1(str: "mailto:?to=test@example.com" ) |
| 1062 | << uint(QUrl::PrettyDecoded) |
| 1063 | << QString::fromLatin1(str: "mailto:?to=test@example.com" ); |
| 1064 | } |
| 1065 | |
| 1066 | void tst_QUrl::toString() |
| 1067 | { |
| 1068 | QFETCH(QString, urlString); |
| 1069 | QFETCH(uint, options); |
| 1070 | QFETCH(QString, string); |
| 1071 | |
| 1072 | QUrl::FormattingOptions opt(options); |
| 1073 | |
| 1074 | QUrl url(urlString); |
| 1075 | QCOMPARE(url.toString(opt), string); |
| 1076 | |
| 1077 | QCOMPARE(url.adjusted(opt).toString(), string); |
| 1078 | } |
| 1079 | void tst_QUrl::toString_PreferLocalFile_data() |
| 1080 | { |
| 1081 | QTest::addColumn<QUrl>(name: "url" ); |
| 1082 | QTest::addColumn<QString>(name: "string" ); |
| 1083 | |
| 1084 | #ifdef Q_OS_WIN |
| 1085 | QTest::newRow("win-drive" ) << QUrl(QString::fromLatin1("file:///c:/windows/regedit.exe" )) |
| 1086 | << QString::fromLatin1("c:/windows/regedit.exe" ); |
| 1087 | QTest::newRow("win-share" ) << QUrl(QString::fromLatin1("//Anarki/homes" )) |
| 1088 | << QString::fromLatin1("//anarki/homes" ); |
| 1089 | #else |
| 1090 | QTest::newRow(dataTag: "unix-path" ) << QUrl(QString::fromLatin1(str: "file:///tmp" )) |
| 1091 | << QString::fromLatin1(str: "/tmp" ); |
| 1092 | #endif |
| 1093 | } |
| 1094 | |
| 1095 | void tst_QUrl::toString_PreferLocalFile() |
| 1096 | { |
| 1097 | QFETCH(QUrl, url); |
| 1098 | QFETCH(QString, string); |
| 1099 | |
| 1100 | QCOMPARE(url.toString(QUrl::PreferLocalFile), string); |
| 1101 | } |
| 1102 | |
| 1103 | void tst_QUrl::toAndFromStringList_data() |
| 1104 | { |
| 1105 | QTest::addColumn<QStringList>(name: "strings" ); |
| 1106 | |
| 1107 | QTest::newRow(dataTag: "empty" ) << QStringList(); |
| 1108 | QTest::newRow(dataTag: "local" ) << (QStringList() << "file:///tmp" << "file:///" ); |
| 1109 | QTest::newRow(dataTag: "remote" ) << (QStringList() << "http://qt-project.org" ); |
| 1110 | } |
| 1111 | |
| 1112 | void tst_QUrl::toAndFromStringList() |
| 1113 | { |
| 1114 | QFETCH(QStringList, strings); |
| 1115 | |
| 1116 | const QList<QUrl> urls = QUrl::fromStringList(uris: strings); |
| 1117 | QCOMPARE(urls.count(), strings.count()); |
| 1118 | const QStringList converted = QUrl::toStringList(uris: urls); |
| 1119 | QCOMPARE(converted, strings); |
| 1120 | } |
| 1121 | |
| 1122 | //### more tests ... what do we expect ... |
| 1123 | void tst_QUrl::isParentOf_data() |
| 1124 | { |
| 1125 | QTest::addColumn<QString>(name: "parent" ); |
| 1126 | QTest::addColumn<QString>(name: "child" ); |
| 1127 | QTest::addColumn<bool>(name: "trueFalse" ); |
| 1128 | |
| 1129 | QTest::newRow(dataTag: "data0" ) << QString::fromLatin1(str: "http://a.b.c/d" ) |
| 1130 | << QString::fromLatin1(str: "http://a.b.c/d/e?f" ) << true; |
| 1131 | QTest::newRow(dataTag: "data1" ) << QString::fromLatin1(str: "http://a.b.c/d" ) |
| 1132 | << QString::fromLatin1(str: "http://a.b.c/d" ) << false; |
| 1133 | QTest::newRow(dataTag: "data2" ) << QString::fromLatin1(str: "http://a.b.c/d" ) |
| 1134 | << QString::fromLatin1(str: "http://a.b.c/de" ) << false; |
| 1135 | QTest::newRow(dataTag: "data3" ) << QString::fromLatin1(str: "http://a.b.c/d/" ) |
| 1136 | << QString::fromLatin1(str: "http://a.b.c/de" ) << false; |
| 1137 | QTest::newRow(dataTag: "data4" ) << QString::fromLatin1(str: "http://a.b.c/d/" ) |
| 1138 | << QString::fromLatin1(str: "http://a.b.c/d/e" ) << true; |
| 1139 | } |
| 1140 | |
| 1141 | void tst_QUrl::toString_constructed_data() |
| 1142 | { |
| 1143 | QTest::addColumn<QString>(name: "scheme" ); |
| 1144 | QTest::addColumn<QString>(name: "userName" ); |
| 1145 | QTest::addColumn<QString>(name: "password" ); |
| 1146 | QTest::addColumn<QString>(name: "host" ); |
| 1147 | QTest::addColumn<int>(name: "port" ); |
| 1148 | QTest::addColumn<QString>(name: "path" ); |
| 1149 | QTest::addColumn<QString>(name: "query" ); |
| 1150 | QTest::addColumn<QString>(name: "fragment" ); |
| 1151 | QTest::addColumn<QString>(name: "asString" ); |
| 1152 | QTest::addColumn<QByteArray>(name: "asEncoded" ); |
| 1153 | QTest::addColumn<uint>(name: "options" ); |
| 1154 | |
| 1155 | QString n("" ); |
| 1156 | |
| 1157 | QTest::newRow(dataTag: "data1" ) << n << n << n << QString::fromLatin1(str: "qt-project.org" ) << -1 << QString::fromLatin1(str: "/index.html" ) |
| 1158 | << QString() << n << QString::fromLatin1(str: "//qt-project.org/index.html" ) |
| 1159 | << QByteArray("//qt-project.org/index.html" ) << 0u; |
| 1160 | QTest::newRow(dataTag: "data2" ) << QString::fromLatin1(str: "file" ) << n << n << n << -1 << QString::fromLatin1(str: "/root" ) << QString() |
| 1161 | << n << QString::fromLatin1(str: "file:///root" ) << QByteArray("file:///root" ) << 0u; |
| 1162 | QTest::newRow(dataTag: "userAndPass" ) << QString::fromLatin1(str: "http" ) << QString::fromLatin1(str: "dfaure" ) << QString::fromLatin1(str: "kde" ) |
| 1163 | << "kde.org" << 443 << QString::fromLatin1(str: "/" ) << QString() << n |
| 1164 | << QString::fromLatin1(str: "http://dfaure:kde@kde.org:443/" ) << QByteArray("http://dfaure:kde@kde.org:443/" ) |
| 1165 | << 0u; |
| 1166 | QTest::newRow(dataTag: "PassWithoutUser" ) << QString::fromLatin1(str: "http" ) << n << QString::fromLatin1(str: "kde" ) |
| 1167 | << "kde.org" << 443 << QString::fromLatin1(str: "/" ) << QString() << n |
| 1168 | << QString::fromLatin1(str: "http://:kde@kde.org:443/" ) << QByteArray("http://:kde@kde.org:443/" ) << 0u; |
| 1169 | QTest::newRow(dataTag: "PassWithoutUser-RemovePassword" ) << QString::fromLatin1(str: "http" ) << n << QString::fromLatin1(str: "kde" ) |
| 1170 | << "kde.org" << 443 << QString::fromLatin1(str: "/" ) << QString() << n |
| 1171 | << QString::fromLatin1(str: "http://kde.org:443/" ) << QByteArray("http://kde.org:443/" ) |
| 1172 | << uint(QUrl::RemovePassword); |
| 1173 | } |
| 1174 | |
| 1175 | void tst_QUrl::toString_constructed() |
| 1176 | { |
| 1177 | QFETCH(QString, scheme); |
| 1178 | QFETCH(QString, userName); |
| 1179 | QFETCH(QString, password); |
| 1180 | QFETCH(QString, host); |
| 1181 | QFETCH(int, port); |
| 1182 | QFETCH(QString, path); |
| 1183 | QFETCH(QString, query); |
| 1184 | QFETCH(QString, fragment); |
| 1185 | QFETCH(QString, asString); |
| 1186 | QFETCH(QByteArray, asEncoded); |
| 1187 | QFETCH(uint, options); |
| 1188 | |
| 1189 | QUrl url; |
| 1190 | if (!scheme.isEmpty()) |
| 1191 | url.setScheme(scheme); |
| 1192 | if (!userName.isEmpty()) |
| 1193 | url.setUserName(userName); |
| 1194 | if (!password.isEmpty()) |
| 1195 | url.setPassword(password); |
| 1196 | if (!host.isEmpty()) |
| 1197 | url.setHost(host); |
| 1198 | if (port != -1) |
| 1199 | url.setPort(port); |
| 1200 | if (!path.isEmpty()) |
| 1201 | url.setPath(path); |
| 1202 | if (!query.isEmpty()) |
| 1203 | url.setQuery(query, mode: QUrl::StrictMode); |
| 1204 | if (!fragment.isEmpty()) |
| 1205 | url.setFragment(fragment); |
| 1206 | |
| 1207 | QVERIFY(url.isValid()); |
| 1208 | |
| 1209 | QUrl::FormattingOptions formattingOptions(options); |
| 1210 | QCOMPARE(url.toString(formattingOptions), asString); |
| 1211 | QCOMPARE(QString::fromLatin1(url.toEncoded(formattingOptions)), QString::fromLatin1(asEncoded)); // readable in case of differences |
| 1212 | QCOMPARE(url.toEncoded(formattingOptions), asEncoded); |
| 1213 | } |
| 1214 | |
| 1215 | void tst_QUrl::toDisplayString_PreferLocalFile_data() |
| 1216 | { |
| 1217 | QTest::addColumn<QUrl>(name: "url" ); |
| 1218 | QTest::addColumn<QString>(name: "string" ); |
| 1219 | |
| 1220 | QTest::newRow(dataTag: "basic" ) << QUrl::fromLocalFile(localfile: "/home/charles/foomoo" ) |
| 1221 | << QString::fromLatin1(str: "/home/charles/foomoo" ); |
| 1222 | QTest::newRow(dataTag: "with%" ) << QUrl::fromLocalFile(localfile: "/home/charles/foo%20moo" ) |
| 1223 | << QString::fromLatin1(str: "/home/charles/foo%20moo" ); |
| 1224 | QTest::newRow(dataTag: "non-local" ) << QUrl("file://host/foo" ) |
| 1225 | << QString::fromLatin1(str: "//host/foo" ); |
| 1226 | QTest::newRow(dataTag: "query-and-fragment" ) << QUrl("file://user:pass@example.org/a?b=c%20d%23e#frag%23ment" ) |
| 1227 | << QString::fromLatin1(str: "file://user@example.org/a?b=c d%23e#frag%23ment" ); |
| 1228 | QTest::newRow(dataTag: "http" ) << QUrl("http://user:pass@example.org/a?b=c%20d%23e#frag%23ment" ) |
| 1229 | << QString::fromLatin1(str: "http://user@example.org/a?b=c d%23e#frag%23ment" ); |
| 1230 | } |
| 1231 | |
| 1232 | void tst_QUrl::toDisplayString_PreferLocalFile() |
| 1233 | { |
| 1234 | QFETCH(QUrl, url); |
| 1235 | QFETCH(QString, string); |
| 1236 | |
| 1237 | if (url.isLocalFile() && url.query().isEmpty() && url.fragment().isEmpty()) |
| 1238 | QCOMPARE(url.toLocalFile(), string); |
| 1239 | QCOMPARE(url.toDisplayString(QUrl::PreferLocalFile), string); |
| 1240 | } |
| 1241 | |
| 1242 | void tst_QUrl::isParentOf() |
| 1243 | { |
| 1244 | QFETCH(QString, parent); |
| 1245 | QFETCH(QString, child); |
| 1246 | QFETCH(bool, trueFalse); |
| 1247 | |
| 1248 | QUrl url(parent); |
| 1249 | QCOMPARE(url.isParentOf(QUrl(child)), trueFalse); |
| 1250 | } |
| 1251 | |
| 1252 | void tst_QUrl::toLocalFile_data() |
| 1253 | { |
| 1254 | QTest::addColumn<QString>(name: "theUrl" ); |
| 1255 | QTest::addColumn<QString>(name: "theFile" ); |
| 1256 | |
| 1257 | QTest::newRow(dataTag: "file:/" ) << QString::fromLatin1(str: "file:/a.txt" ) << QString::fromLatin1(str: "/a.txt" ); |
| 1258 | QTest::newRow(dataTag: "file:///" ) << QString::fromLatin1(str: "file:///a.txt" ) << QString::fromLatin1(str: "/a.txt" ); |
| 1259 | QTest::newRow(dataTag: "file:////" ) << QString::fromLatin1(str: "file:////somehost/somedir/somefile" ) << QString::fromLatin1(str: "//somehost/somedir/somefile" ); |
| 1260 | QTest::newRow(dataTag: "FILE:/" ) << QString::fromLatin1(str: "FILE:/a.txt" ) << QString::fromLatin1(str: "/a.txt" ); |
| 1261 | |
| 1262 | QTest::newRow(dataTag: "path-delimiter" ) << QString::fromLatin1(str: "file:///Mambo <%235>.mp3" ) << QString::fromLatin1(str: "/Mambo <#5>.mp3" ); |
| 1263 | QTest::newRow(dataTag: "path-percent" ) << QString::fromLatin1(str: "file:///a%25.txt" ) << QString::fromLatin1(str: "/a%.txt" ); |
| 1264 | QTest::newRow(dataTag: "path-percent-percent" ) << QString::fromLatin1(str: "file:///a%25%25.txt" ) << QString::fromLatin1(str: "/a%%.txt" ); |
| 1265 | QTest::newRow(dataTag: "path-percent-a-percent" ) << QString::fromLatin1(str: "file:///a%25a%25.txt" ) << QString::fromLatin1(str: "/a%a%.txt" ); |
| 1266 | QTest::newRow(dataTag: "path-control-char" ) << QString::fromLatin1(str: "file:///a%1f.txt" ) << QString::fromLatin1(str: "/a\x1f.txt" ); |
| 1267 | QTest::newRow(dataTag: "path-percent-hex-hex" ) << QString::fromLatin1(str: "file:///%2580.txt" ) << QString::fromLatin1(str: "/%80.txt" ); |
| 1268 | |
| 1269 | QTest::newRow(dataTag: "webdavs" ) << QString::fromLatin1(str: "webdavs://somewebdavhost/somedir/somefile" ) |
| 1270 | #ifdef Q_OS_WIN // QTBUG-42346, WebDAV is visible as local file on Windows only. |
| 1271 | << QString::fromLatin1("//somewebdavhost@SSL/somedir/somefile" ); |
| 1272 | #else |
| 1273 | << QString(); |
| 1274 | #endif |
| 1275 | #ifdef Q_OS_WIN |
| 1276 | QTest::newRow("windows-drive-absolute" ) << QString::fromLatin1("file:///c:/a.txt" ) << QString::fromLatin1("c:/a.txt" ); |
| 1277 | #else |
| 1278 | QTest::newRow(dataTag: "windows-drive-absolute" ) << QString::fromLatin1(str: "file:///c:/a.txt" ) << QString::fromLatin1(str: "/c:/a.txt" ); |
| 1279 | #endif |
| 1280 | QTest::newRow(dataTag: "windows-unc-path" ) << QString::fromLatin1(str: "file://somehost/somedir/somefile" ) << QString::fromLatin1(str: "//somehost/somedir/somefile" ); |
| 1281 | QTest::newRow(dataTag: "windows-unc-root" ) << QString::fromLatin1(str: "file://somehost/" ) << QString::fromLatin1(str: "//somehost/" ); |
| 1282 | QTest::newRow(dataTag: "windows-unc-nopath" ) << QString::fromLatin1(str: "file://somehost" ) << QString::fromLatin1(str: "//somehost" ); |
| 1283 | QTest::newRow(dataTag: "windows-extlen-path" ) << QString::fromLatin1(str: "file:////%3F/somedir/somefile" ) << QString::fromLatin1(str: "//?/somedir/somefile" ); |
| 1284 | QTest::newRow(dataTag: "windows-wsl-path" ) << QString::fromLatin1(str: "file:////wsl$/somedir/somefile" ) << QString::fromLatin1(str: "//wsl$/somedir/somefile" ); |
| 1285 | QTest::newRow(dataTag: "windows-device-path" ) << QString::fromLatin1(str: "file:////./somedir/somefile" ) << QString::fromLatin1(str: "//./somedir/somefile" ); |
| 1286 | |
| 1287 | // and some that result in empty (i.e., not local) |
| 1288 | QTest::newRow(dataTag: "noscheme-absolute" ) << QString::fromLatin1(str: "/a.txt" ) << QString(); |
| 1289 | QTest::newRow(dataTag: "noscheme-host" ) << QString::fromLatin1(str: "//a.txt" ) << QString(); |
| 1290 | QTest::newRow(dataTag: "noscheme-host-path" ) << QString::fromLatin1(str: "///a.txt" ) << QString(); |
| 1291 | QTest::newRow(dataTag: "fooscheme-absolute" ) << QString::fromLatin1(str: "foo:/a.txt" ) << QString(); |
| 1292 | QTest::newRow(dataTag: "fooscheme-host" ) << QString::fromLatin1(str: "foo://a.txt" ) << QString(); |
| 1293 | QTest::newRow(dataTag: "fooscheme-host-path" ) << QString::fromLatin1(str: "foo:///a.txt" ) << QString(); |
| 1294 | } |
| 1295 | |
| 1296 | void tst_QUrl::toLocalFile() |
| 1297 | { |
| 1298 | QFETCH(QString, theUrl); |
| 1299 | QFETCH(QString, theFile); |
| 1300 | |
| 1301 | QUrl url(theUrl); |
| 1302 | QCOMPARE(url.toLocalFile(), theFile); |
| 1303 | QCOMPARE(url.isLocalFile(), !theFile.isEmpty()); |
| 1304 | } |
| 1305 | |
| 1306 | void tst_QUrl::fromLocalFile_data() |
| 1307 | { |
| 1308 | QTest::addColumn<QString>(name: "theFile" ); |
| 1309 | QTest::addColumn<QString>(name: "theUrl" ); |
| 1310 | QTest::addColumn<QString>(name: "thePath" ); |
| 1311 | |
| 1312 | QTest::newRow(dataTag: "absolute-path" ) << QString::fromLatin1(str: "/a.txt" ) << QString::fromLatin1(str: "file:///a.txt" ) << QString::fromLatin1(str: "/a.txt" ); |
| 1313 | QTest::newRow(dataTag: "relative-path" ) << QString::fromLatin1(str: "a.txt" ) << QString::fromLatin1(str: "file:a.txt" ) << QString::fromLatin1(str: "a.txt" ); |
| 1314 | QTest::newRow(dataTag: "absolute-two-path" ) << QString::fromLatin1(str: "/a/b.txt" ) << QString::fromLatin1(str: "file:///a/b.txt" ) << QString::fromLatin1(str: "/a/b.txt" ); |
| 1315 | QTest::newRow(dataTag: "path-delimiters" ) << QString::fromLatin1(str: "/Mambo <#5>.mp3" ) << QString::fromLatin1(str: "file:///Mambo <%235>.mp3" ) |
| 1316 | << QString::fromLatin1(str: "/Mambo <#5>.mp3" ); |
| 1317 | |
| 1318 | // Windows absolute details |
| 1319 | QTest::newRow(dataTag: "windows-drive" ) << QString::fromLatin1(str: "c:/a.txt" ) << QString::fromLatin1(str: "file:///c:/a.txt" ) << QString::fromLatin1(str: "/c:/a.txt" ); |
| 1320 | |
| 1321 | // Windows UNC paths |
| 1322 | for (const char *suffix : { "" , "/" , "/somedir/somefile" }) { |
| 1323 | const char *pathDescription = |
| 1324 | strlen(s: suffix) == 0 ? "nopath" : |
| 1325 | strlen(s: suffix) > 1 ? "path" : "root" ; |
| 1326 | |
| 1327 | QTest::addRow(format: "windows-unc-%s" , pathDescription) |
| 1328 | << QString("//somehost" ) + suffix |
| 1329 | << QString("file://somehost" ) + suffix |
| 1330 | << QString(suffix); |
| 1331 | #ifdef Q_OS_WIN32 |
| 1332 | // debackslashification only happens on Windows |
| 1333 | QTest::addRow("windows-backslash-unc-%s" , pathDescription) |
| 1334 | << QString(QString("//somehost" ) + suffix).replace('/', '\\') |
| 1335 | << QString("file://somehost" ) + suffix |
| 1336 | << QString(suffix); |
| 1337 | QTest::addRow("windows-backslash-extlen-%s" , pathDescription) |
| 1338 | << QString(QString("//?" ) + suffix).replace('/', '\\') |
| 1339 | << QString("file:////%3F" ) + suffix |
| 1340 | << QString("//?" ) + suffix; |
| 1341 | #endif |
| 1342 | QTest::addRow(format: "windows-extlen-%s" , pathDescription) |
| 1343 | << QString("//?" ) + suffix |
| 1344 | << QString("file:////%3F" ) + suffix |
| 1345 | << QString("//?" ) + suffix; |
| 1346 | QTest::addRow(format: "windows-wsl-%s" , pathDescription) |
| 1347 | << QString("//wsl$" ) + suffix |
| 1348 | << QString("file:////wsl$" ) + suffix |
| 1349 | << QString("//wsl$" ) + suffix; |
| 1350 | QTest::addRow(format: "windows-device--%s" , pathDescription) |
| 1351 | << QString("//." ) + suffix |
| 1352 | << QString("file:////." ) + suffix |
| 1353 | << QString("//." ) + suffix; |
| 1354 | } |
| 1355 | |
| 1356 | QTest::newRow(dataTag: "windows-webdav" ) |
| 1357 | << QString::fromLatin1(str: "//somewebdavhost@SSL/somedir/somefile" ) |
| 1358 | << QString::fromLatin1(str: "webdavs://somewebdavhost/somedir/somefile" ) |
| 1359 | << QString::fromLatin1(str: "/somedir/somefile" ); |
| 1360 | } |
| 1361 | |
| 1362 | void tst_QUrl::fromLocalFile() |
| 1363 | { |
| 1364 | QFETCH(QString, theFile); |
| 1365 | QFETCH(QString, theUrl); |
| 1366 | QFETCH(QString, thePath); |
| 1367 | |
| 1368 | QUrl url = QUrl::fromLocalFile(localfile: theFile); |
| 1369 | |
| 1370 | QCOMPARE(url.toString(QUrl::DecodeReserved), theUrl); |
| 1371 | QCOMPARE(url.path(), thePath); |
| 1372 | } |
| 1373 | |
| 1374 | void tst_QUrl::fromLocalFileNormalize_data() |
| 1375 | { |
| 1376 | QTest::addColumn<QString>(name: "theFile" ); // should support the fromLocalFile/toLocalFile roundtrip (so no //host or windows path) |
| 1377 | QTest::addColumn<QString>(name: "theUrl" ); |
| 1378 | QTest::addColumn<QString>(name: "urlWithNormalizedPath" ); |
| 1379 | |
| 1380 | QTest::newRow(dataTag: "absolute-path" ) << QString::fromLatin1(str: "/a.txt" ) << QString::fromLatin1(str: "file:///a.txt" ) << QString::fromLatin1(str: "file:///a.txt" ); |
| 1381 | QTest::newRow(dataTag: "relative-path" ) << QString::fromLatin1(str: "a.txt" ) << QString::fromLatin1(str: "file:a.txt" ) << QString::fromLatin1(str: "file:a.txt" ); |
| 1382 | QTest::newRow(dataTag: "percent" ) << QString::fromLatin1(str: "/a%.txt" ) << QString::fromLatin1(str: "file:///a%25.txt" ) |
| 1383 | << QString::fromLatin1(str: "file:///a%25.txt" ); |
| 1384 | QTest::newRow(dataTag: "percent25" ) << QString::fromLatin1(str: "/a%25.txt" ) << QString::fromLatin1(str: "file:///a%2525.txt" ) |
| 1385 | << QString::fromLatin1(str: "file:///a%2525.txt" ); |
| 1386 | QTest::newRow(dataTag: "percent80" ) << QString::fromLatin1(str: "/%80.txt" ) << QString::fromLatin1(str: "file:///%2580.txt" ) |
| 1387 | << QString::fromLatin1(str: "file:///%2580.txt" ); |
| 1388 | QTest::newRow(dataTag: "relative-dot" ) << QString::fromLatin1(str: "./a.txt" ) << QString::fromLatin1(str: "file:./a.txt" ) << QString::fromLatin1(str: "file:a.txt" ); |
| 1389 | QTest::newRow(dataTag: "relative-dot-dot" ) << QString::fromLatin1(str: "././a.txt" ) << QString::fromLatin1(str: "file:././a.txt" ) << QString::fromLatin1(str: "file:a.txt" ); |
| 1390 | QTest::newRow(dataTag: "relative-path-dotdot" ) << QString::fromLatin1(str: "b/../a.txt" ) << QString::fromLatin1(str: "file:b/../a.txt" ) << QString::fromLatin1(str: "file:a.txt" ); |
| 1391 | QTest::newRow(dataTag: "absolute-path-dotdot" ) << QString::fromLatin1(str: "/b/../a.txt" ) << QString::fromLatin1(str: "file:///b/../a.txt" ) << QString::fromLatin1(str: "file:///a.txt" ); |
| 1392 | QTest::newRow(dataTag: "absolute-path-dot" ) << QString::fromLatin1(str: "/b/." ) << QString::fromLatin1(str: "file:///b/." ) << QString::fromLatin1(str: "file:///b" ); |
| 1393 | } |
| 1394 | |
| 1395 | void tst_QUrl::fromLocalFileNormalize() |
| 1396 | { |
| 1397 | QFETCH(QString, theFile); |
| 1398 | QFETCH(QString, theUrl); |
| 1399 | QFETCH(QString, urlWithNormalizedPath); |
| 1400 | |
| 1401 | QUrl url = QUrl::fromLocalFile(localfile: theFile); |
| 1402 | |
| 1403 | QCOMPARE(url.toString(QUrl::DecodeReserved), theUrl); |
| 1404 | QCOMPARE(url.toLocalFile(), theFile); // roundtrip |
| 1405 | QCOMPARE(url.path(), theFile); // works as well as long as we don't test windows paths |
| 1406 | QCOMPARE(url.toString(QUrl::NormalizePathSegments), urlWithNormalizedPath); |
| 1407 | } |
| 1408 | |
| 1409 | void tst_QUrl::macTypes() |
| 1410 | { |
| 1411 | #ifndef Q_OS_MAC |
| 1412 | QSKIP("This is a Mac-only test" ); |
| 1413 | #else |
| 1414 | extern void tst_QUrl_mactypes(); // in tst_qurl_mac.mm |
| 1415 | void tst_QUrl_mactypes(); |
| 1416 | #endif |
| 1417 | } |
| 1418 | |
| 1419 | void tst_QUrl::compat_legacy() |
| 1420 | { |
| 1421 | { |
| 1422 | QUrl u( "file:bar" ); |
| 1423 | QCOMPARE( u.toString(QUrl::RemoveScheme), QString("bar" ) ); |
| 1424 | } |
| 1425 | |
| 1426 | /* others |
| 1427 | */ |
| 1428 | { |
| 1429 | QUrl u( "http://qt-project.org/images/ban/pgs_front.jpg" ); |
| 1430 | QCOMPARE( u.path(), QString("/images/ban/pgs_front.jpg" ) ); |
| 1431 | } |
| 1432 | { |
| 1433 | QUrl tmp( "http://qt-project.org/images/ban/" ); |
| 1434 | QUrl u = tmp.resolved(relative: QString("pgs_front.jpg" )); |
| 1435 | QCOMPARE( u.path(), QString("/images/ban/pgs_front.jpg" ) ); |
| 1436 | } |
| 1437 | { |
| 1438 | QUrl tmp; |
| 1439 | QUrl u = tmp.resolved(relative: QString("http://qt-project.org/images/ban/pgs_front.jpg" )); |
| 1440 | QCOMPARE( u.path(), QString("/images/ban/pgs_front.jpg" ) ); |
| 1441 | } |
| 1442 | { |
| 1443 | QUrl tmp; |
| 1444 | QUrl u = tmp.resolved(relative: QString("http://qt-project.org/images/ban/pgs_front.jpg" )); |
| 1445 | QFileInfo fi(u.path()); |
| 1446 | u.setPath(path: fi.path()); |
| 1447 | QCOMPARE( u.path(), QString("/images/ban" ) ); |
| 1448 | } |
| 1449 | } |
| 1450 | |
| 1451 | void tst_QUrl::compat_constructor_01_data() |
| 1452 | { |
| 1453 | QTest::addColumn<QString>(name: "urlStr" ); |
| 1454 | QTest::addColumn<QString>(name: "res" ); |
| 1455 | |
| 1456 | //next we fill it with data |
| 1457 | QTest::newRow( dataTag: "data0" ) << QString("Makefile" ) << QString("Makefile" ); // nolonger add file by default |
| 1458 | QTest::newRow( dataTag: "data1" ) << QString("Makefile" ) << QString("Makefile" ); |
| 1459 | QTest::newRow( dataTag: "data2" ) << QString("ftp://ftp.qt-project.org/qt/INSTALL" ) << QString("ftp://ftp.qt-project.org/qt/INSTALL" ); |
| 1460 | QTest::newRow( dataTag: "data3" ) << QString("ftp://ftp.qt-project.org/qt/INSTALL" ) << QString("ftp://ftp.qt-project.org/qt/INSTALL" ); |
| 1461 | } |
| 1462 | |
| 1463 | void tst_QUrl::compat_constructor_01() |
| 1464 | { |
| 1465 | QFETCH( QString, urlStr ); |
| 1466 | |
| 1467 | { |
| 1468 | QUrl empty; |
| 1469 | QUrl u = empty.resolved(relative: urlStr); |
| 1470 | |
| 1471 | QTEST( u.toString(), "res" ); |
| 1472 | } |
| 1473 | { |
| 1474 | QUrl empty; |
| 1475 | QUrl u = empty.resolved(relative: urlStr); |
| 1476 | |
| 1477 | QTEST( u.toString(), "res" ); |
| 1478 | } |
| 1479 | } |
| 1480 | |
| 1481 | void tst_QUrl::compat_constructor_02_data() |
| 1482 | { |
| 1483 | QTest::addColumn<QString>(name: "urlStr" ); |
| 1484 | QTest::addColumn<QString>(name: "fileName" ); |
| 1485 | QTest::addColumn<QString>(name: "res" ); |
| 1486 | |
| 1487 | //next we fill it with data |
| 1488 | QTest::newRow( dataTag: "data0" ) << QString("ftp://ftp.qt-project.org/qt" ) << QString("INSTALL" ) << QString("ftp://ftp.qt-project.org/INSTALL" ); |
| 1489 | QTest::newRow( dataTag: "data1" ) << QString("ftp://ftp.qt-project.org/qt/" ) << QString("INSTALL" ) << QString("ftp://ftp.qt-project.org/qt/INSTALL" ); |
| 1490 | } |
| 1491 | |
| 1492 | void tst_QUrl::compat_constructor_02() |
| 1493 | { |
| 1494 | QFETCH( QString, urlStr ); |
| 1495 | QFETCH( QString, fileName ); |
| 1496 | |
| 1497 | QUrl tmp( urlStr ); |
| 1498 | QUrl u = tmp.resolved(relative: fileName); |
| 1499 | |
| 1500 | QTEST( u.toString(), "res" ); |
| 1501 | } |
| 1502 | |
| 1503 | void tst_QUrl::compat_constructor_03_data() |
| 1504 | { |
| 1505 | QTest::addColumn<QString>(name: "urlStr" ); |
| 1506 | QTest::addColumn<QString>(name: "res" ); |
| 1507 | |
| 1508 | //next we fill it with data |
| 1509 | QTest::newRow( dataTag: "protocol00" ) << QString( "http://qt-project.org/index.html" ) << QString( "http://qt-project.org/index.html" ); |
| 1510 | QTest::newRow( dataTag: "protocol01" ) << QString( "http://qt-project.org" ) << QString( "http://qt-project.org" ); |
| 1511 | QTest::newRow( dataTag: "protocol02" ) << QString( "http://qt-project.org/" ) << QString( "http://qt-project.org/" ); |
| 1512 | QTest::newRow( dataTag: "protocol03" ) << QString( "http://qt-project.org/foo" ) << QString( "http://qt-project.org/foo" ); |
| 1513 | QTest::newRow( dataTag: "protocol04" ) << QString( "http://qt-project.org/foo/" ) << QString( "http://qt-project.org/foo/" ); |
| 1514 | QTest::newRow( dataTag: "protocol05" ) << QString( "ftp://ftp.qt-project.org/foo/index.txt" ) << QString( "ftp://ftp.qt-project.org/foo/index.txt" ); |
| 1515 | |
| 1516 | QTest::newRow( dataTag: "local00" ) << QString( "/foo" ) << QString( "/foo" ); |
| 1517 | QTest::newRow( dataTag: "local01" ) << QString( "/foo/" ) << QString( "/foo/" ); |
| 1518 | QTest::newRow( dataTag: "local02" ) << QString( "/foo/bar" ) << QString( "/foo/bar" ); |
| 1519 | QTest::newRow( dataTag: "local03" ) << QString( "/foo/bar/" ) << QString( "/foo/bar/" ); |
| 1520 | QTest::newRow( dataTag: "local04" ) << QString( "foo" ) << QString( "foo" ); |
| 1521 | QTest::newRow( dataTag: "local05" ) << QString( "foo/" ) << QString( "foo/" ); |
| 1522 | QTest::newRow( dataTag: "local06" ) << QString( "foo/bar" ) << QString( "foo/bar" ); |
| 1523 | QTest::newRow( dataTag: "local07" ) << QString( "foo/bar/" ) << QString( "foo/bar/" ); |
| 1524 | QTest::newRow( dataTag: "local09" ) << QString( "" ) << QString( "" ); |
| 1525 | |
| 1526 | QTest::newRow( dataTag: "file00" ) << QString( "file:/foo" ) << QString( "file:///foo" ); |
| 1527 | QTest::newRow( dataTag: "file01" ) << QString( "file:/foo/" ) << QString( "file:///foo/" ); |
| 1528 | QTest::newRow( dataTag: "file02" ) << QString( "file:/foo/bar" ) << QString( "file:///foo/bar" ); |
| 1529 | QTest::newRow( dataTag: "file03" ) << QString( "file:/foo/bar/" ) << QString( "file:///foo/bar/" ); |
| 1530 | QTest::newRow( dataTag: "relProtocol00" ) << QString( "foo:bar" ) << QString( "foo:bar" ); |
| 1531 | QTest::newRow( dataTag: "relProtocol01" ) << QString( "foo:/bar" ) << QString( "foo:/bar" ); |
| 1532 | |
| 1533 | QTest::newRow( dataTag: "windowsDrive00" ) << QString( "c:/" ) << QString( "c:/" ); |
| 1534 | QTest::newRow( dataTag: "windowsDrive01" ) << QString( "c:" ) << QString( "c:" ); |
| 1535 | QTest::newRow( dataTag: "windowsDrive02" ) << QString( "c:/WinNT/" ) << QString( "c:/WinNT/" ); |
| 1536 | QTest::newRow( dataTag: "windowsDrive03" ) << QString( "c:/autoexec.bat" ) << QString( "c:/autoexec.bat" ); |
| 1537 | QTest::newRow( dataTag: "windowsDrive04" ) << QString( "c:WinNT/" ) << QString( "c:WinNT/" ); |
| 1538 | QTest::newRow( dataTag: "windowsDrive05" ) << QString( "c:autoexec.bat" ) << QString( "c:autoexec.bat" ); |
| 1539 | |
| 1540 | QTest::newRow(dataTag: "nopath" ) << QString("protocol://host" ) << QString("protocol://host" ); |
| 1541 | } |
| 1542 | |
| 1543 | void tst_QUrl::compat_constructor_03() |
| 1544 | { |
| 1545 | QFETCH( QString, urlStr ); |
| 1546 | |
| 1547 | QUrl u( urlStr ); |
| 1548 | QTEST( u.toString(), "res" ); |
| 1549 | } |
| 1550 | |
| 1551 | void tst_QUrl::compat_isValid_01_data() |
| 1552 | { |
| 1553 | QTest::addColumn<QString>(name: "urlStr" ); |
| 1554 | QTest::addColumn<bool>(name: "res" ); |
| 1555 | |
| 1556 | QTest::newRow( dataTag: "ok_01" ) << QString("ftp://ftp.qt-project.org/qt/INSTALL" ) << (bool)true; |
| 1557 | QTest::newRow( dataTag: "ok_02" ) << QString( "file:/foo" ) << (bool)true; |
| 1558 | QTest::newRow( dataTag: "ok_03" ) << QString( "file:foo" ) << (bool)true; |
| 1559 | |
| 1560 | QTest::newRow( dataTag: "err_01" ) << QString("#ftp://ftp.qt-project.org/qt/INSTALL" ) << (bool)true; |
| 1561 | QTest::newRow( dataTag: "err_02" ) << QString( "file:/::foo" ) << (bool)true; |
| 1562 | } |
| 1563 | |
| 1564 | void tst_QUrl::compat_isValid_01() |
| 1565 | { |
| 1566 | QFETCH( QString, urlStr ); |
| 1567 | QFETCH( bool, res ); |
| 1568 | |
| 1569 | QUrl url( urlStr ); |
| 1570 | QCOMPARE( url.isValid(), res ); |
| 1571 | if (!res) |
| 1572 | QVERIFY(url.toString().isEmpty()); |
| 1573 | } |
| 1574 | |
| 1575 | void tst_QUrl::compat_isValid_02_data() |
| 1576 | { |
| 1577 | QTest::addColumn<QString>(name: "protocol" ); |
| 1578 | QTest::addColumn<QString>(name: "user" ); |
| 1579 | QTest::addColumn<QString>(name: "password" ); |
| 1580 | QTest::addColumn<QString>(name: "host" ); |
| 1581 | QTest::addColumn<int>(name: "port" ); |
| 1582 | QTest::addColumn<QString>(name: "path" ); |
| 1583 | QTest::addColumn<bool>(name: "res" ); |
| 1584 | |
| 1585 | QString n = "" ; |
| 1586 | |
| 1587 | QTest::newRow( dataTag: "ok_01" ) << n << n << n << n << -1 << QString("path" ) << (bool)true; |
| 1588 | QTest::newRow( dataTag: "ok_02" ) << QString("ftp" ) << n << n << QString("ftp.qt-project.org" ) << -1 << n << (bool)true; |
| 1589 | QTest::newRow( dataTag: "ok_03" ) << QString("ftp" ) << QString("foo" ) << n << QString("ftp.qt-project.org" ) << -1 << n << (bool)true; |
| 1590 | QTest::newRow( dataTag: "ok_04" ) << QString("ftp" ) << QString("foo" ) << QString("bar" ) << QString("ftp.qt-project.org" ) << -1 << n << (bool)true; |
| 1591 | QTest::newRow( dataTag: "ok_05" ) << QString("ftp" ) << n << n << QString("ftp.qt-project.org" ) << -1 << QString("/path" )<< (bool)true; |
| 1592 | QTest::newRow( dataTag: "ok_06" ) << QString("ftp" ) << QString("foo" ) << n << QString("ftp.qt-project.org" ) << -1 << QString("/path" ) << (bool)true; |
| 1593 | QTest::newRow( dataTag: "ok_07" ) << QString("ftp" ) << QString("foo" ) << QString("bar" ) << QString("ftp.qt-project.org" ) << -1 << QString("/path" )<< (bool)true; |
| 1594 | |
| 1595 | QTest::newRow( dataTag: "err_01" ) << n << n << n << n << -1 << n << (bool)false; |
| 1596 | QTest::newRow( dataTag: "err_02" ) << QString("ftp" ) << n << n << n << -1 << n << (bool)true; |
| 1597 | QTest::newRow( dataTag: "err_03" ) << n << QString("foo" ) << n << n << -1 << n << (bool)true; |
| 1598 | QTest::newRow( dataTag: "err_04" ) << n << n << QString("bar" ) << n << -1 << n << (bool)true; |
| 1599 | QTest::newRow( dataTag: "err_05" ) << n << n << n << QString("ftp.qt-project.org" ) << -1 << n << (bool)true; |
| 1600 | QTest::newRow( dataTag: "err_06" ) << n << n << n << n << 80 << n << (bool)true; |
| 1601 | QTest::newRow( dataTag: "err_07" ) << QString("ftp" ) << QString("foo" ) << n << n << -1 << n << (bool)true; |
| 1602 | QTest::newRow( dataTag: "err_08" ) << QString("ftp" ) << n << QString("bar" ) << n << -1 << n << (bool)true; |
| 1603 | QTest::newRow( dataTag: "err_09" ) << QString("ftp" ) << QString("foo" ) << QString("bar" ) << n << -1 << n << (bool)true; |
| 1604 | } |
| 1605 | |
| 1606 | void tst_QUrl::compat_isValid_02() |
| 1607 | { |
| 1608 | QFETCH( QString, protocol ); |
| 1609 | QFETCH( QString, user ); |
| 1610 | QFETCH( QString, password ); |
| 1611 | QFETCH( QString, host ); |
| 1612 | QFETCH( int, port ); |
| 1613 | QFETCH( QString, path ); |
| 1614 | QFETCH( bool, res ); |
| 1615 | |
| 1616 | QUrl url; |
| 1617 | if ( !protocol.isEmpty() ) |
| 1618 | url.setScheme( protocol ); |
| 1619 | if ( !user.isEmpty() ) |
| 1620 | url.setUserName( userName: user ); |
| 1621 | if ( !password.isEmpty() ) |
| 1622 | url.setPassword( password ); |
| 1623 | if ( !host.isEmpty() ) |
| 1624 | url.setHost( host ); |
| 1625 | if ( port != -1 ) |
| 1626 | url.setPort( port ); |
| 1627 | if ( !path.isEmpty() ) |
| 1628 | url.setPath( path ); |
| 1629 | |
| 1630 | QCOMPARE( url.isValid(), res ); |
| 1631 | if (!res) |
| 1632 | QVERIFY(url.toString().isEmpty()); |
| 1633 | } |
| 1634 | |
| 1635 | void tst_QUrl::compat_path_data() |
| 1636 | { |
| 1637 | QTest::addColumn<QString>(name: "url" ); |
| 1638 | QTest::addColumn<QString>(name: "res" ); |
| 1639 | |
| 1640 | QTest::newRow( dataTag: "protocol00" ) << "http://qt-project.org/images/ban/pgs_front.jpg" << "/images/ban/pgs_front.jpg" ; |
| 1641 | |
| 1642 | #if defined( Q_OS_WIN32 ) |
| 1643 | QTest::newRow( "winShare00" ) << "//Anarki/homes" << "/homes" ; |
| 1644 | #endif |
| 1645 | } |
| 1646 | |
| 1647 | void tst_QUrl::compat_path() |
| 1648 | { |
| 1649 | QFETCH( QString, url ); |
| 1650 | |
| 1651 | QUrl u( url ); |
| 1652 | QTEST( u.path(), "res" ); |
| 1653 | } |
| 1654 | |
| 1655 | void tst_QUrl::compat_fileName_data() |
| 1656 | { |
| 1657 | QTest::addColumn<QString>(name: "url" ); |
| 1658 | QTest::addColumn<QString>(name: "fileName" ); |
| 1659 | |
| 1660 | #ifdef Q_OS_WIN32 |
| 1661 | QTest::newRow( "Windows - DrivePathFileName - \\" ) << QString("c:\\windows\\tmp\\filename.txt" )<< QString("filename.txt" ); |
| 1662 | QTest::newRow( "Windows - DrivePathFileName - /" ) << QString("c:/windows/tmp/filename.txt" ) << QString("filename.txt" ); |
| 1663 | QTest::newRow( "Windows - DrivePathWithSlash - \\" ) << QString("c:\\windows\\tmp\\" ) << QString(); |
| 1664 | QTest::newRow( "Windows - DrivePathWithSlash - /" ) << QString("c:/windows/tmp/" ) << QString(); |
| 1665 | QTest::newRow( "Windows - DrivePathWithoutSlash - \\" ) << QString("c:/windows/tmp" ) << QString("tmp" ); |
| 1666 | QTest::newRow( "Windows - DrivePathWithoutSlash - /" ) << QString("c:/windows/tmp" ) << QString("tmp" ); |
| 1667 | #endif |
| 1668 | QTest::newRow( dataTag: "Path00" ) << QString("/" ) << QString(); |
| 1669 | QTest::newRow( dataTag: "Path01" ) << QString("/home/dev/test/" ) << QString(); |
| 1670 | QTest::newRow( dataTag: "PathFileName00" ) << QString("/home/dev/test" ) << QString("test" ); |
| 1671 | } |
| 1672 | |
| 1673 | void tst_QUrl::compat_fileName() |
| 1674 | { |
| 1675 | QFETCH( QString, url ); |
| 1676 | QFETCH( QString, fileName ); |
| 1677 | QUrl fileUrl = QUrl::fromLocalFile(localfile: url); |
| 1678 | QFileInfo fi(fileUrl.toLocalFile()); |
| 1679 | QCOMPARE( fi.fileName(), fileName ); |
| 1680 | } |
| 1681 | |
| 1682 | void tst_QUrl::compat_decode_data() |
| 1683 | { |
| 1684 | QTest::addColumn<QByteArray>(name: "encodedString" ); |
| 1685 | QTest::addColumn<QString>(name: "decodedString" ); |
| 1686 | |
| 1687 | QTest::newRow(dataTag: "NormalString" ) << QByteArray("filename" ) << QString("filename" ); |
| 1688 | QTest::newRow(dataTag: "NormalStringEncoded" ) << QByteArray("file%20name" ) << QString("file name" ); |
| 1689 | QTest::newRow(dataTag: "JustEncoded" ) << QByteArray("%20" ) << QString(" " ); |
| 1690 | QTest::newRow(dataTag: "HTTPUrl" ) << QByteArray("http://qt-project.org" ) << QString("http://qt-project.org" ); |
| 1691 | QTest::newRow(dataTag: "HTTPUrlEncoded" ) << QByteArray("http://qt-project%20org" ) << QString("http://qt-project org" ); |
| 1692 | QTest::newRow(dataTag: "EmptyString" ) << QByteArray("" ) << QString("" ); |
| 1693 | QTest::newRow(dataTag: "NulByte" ) << QByteArray("C%00%0A" ) << QString::fromLatin1(str: "C\0\n" , size: 3); |
| 1694 | QTest::newRow(dataTag: "Task27166" ) << QByteArray("Fran%C3%A7aise" ) << QString::fromUtf8(str: "Française" ); |
| 1695 | } |
| 1696 | |
| 1697 | void tst_QUrl::compat_decode() |
| 1698 | { |
| 1699 | QFETCH(QByteArray, encodedString); |
| 1700 | QFETCH(QString, decodedString); |
| 1701 | |
| 1702 | QCOMPARE(QUrl::fromPercentEncoding(encodedString), decodedString); |
| 1703 | } |
| 1704 | |
| 1705 | void tst_QUrl::compat_encode_data() |
| 1706 | { |
| 1707 | QTest::addColumn<QString>(name: "decodedString" ); |
| 1708 | QTest::addColumn<QByteArray>(name: "encodedString" ); |
| 1709 | |
| 1710 | QTest::newRow(dataTag: "NormalString" ) << QString("filename" ) << QByteArray("filename" ); |
| 1711 | QTest::newRow(dataTag: "NormalStringEncoded" ) << QString("file name" ) << QByteArray("file%20name" ); |
| 1712 | QTest::newRow(dataTag: "JustEncoded" ) << QString(" " ) << QByteArray("%20" ); |
| 1713 | QTest::newRow(dataTag: "HTTPUrl" ) << QString("http://qt-project.org" ) << QByteArray("http%3A//qt-project.org" ); |
| 1714 | QTest::newRow(dataTag: "HTTPUrlEncoded" ) << QString("http://qt-project org" ) << QByteArray("http%3A//qt-project%20org" ); |
| 1715 | QTest::newRow(dataTag: "EmptyString" ) << QString("" ) << QByteArray("" ); |
| 1716 | QTest::newRow(dataTag: "NulByte" ) << QString::fromLatin1(str: "C\0\n" , size: 3) << QByteArray("C%00%0A" ); |
| 1717 | QTest::newRow(dataTag: "Task27166" ) << QString::fromUtf8(str: "Française" ) << QByteArray("Fran%C3%A7aise" ); |
| 1718 | } |
| 1719 | |
| 1720 | void tst_QUrl::compat_encode() |
| 1721 | { |
| 1722 | QFETCH(QString, decodedString); |
| 1723 | QFETCH(QByteArray, encodedString); |
| 1724 | |
| 1725 | QCOMPARE(QUrl::toPercentEncoding(decodedString, "/." ), encodedString); |
| 1726 | } |
| 1727 | |
| 1728 | |
| 1729 | void tst_QUrl::relative() |
| 1730 | { |
| 1731 | QUrl url("../ole" ); |
| 1732 | QCOMPARE(url.path(), QString::fromLatin1("../ole" )); |
| 1733 | |
| 1734 | QUrl url2("./" ); |
| 1735 | QCOMPARE(url2.path(), QString::fromLatin1("./" )); |
| 1736 | |
| 1737 | QUrl url3(".." ); |
| 1738 | QCOMPARE(url3.path(), QString::fromLatin1(".." )); |
| 1739 | |
| 1740 | QUrl url4("../.." ); |
| 1741 | QCOMPARE(url4.path(), QString::fromLatin1("../.." )); |
| 1742 | } |
| 1743 | |
| 1744 | void tst_QUrl::percentEncoding_data() |
| 1745 | { |
| 1746 | // This test is limited. It's superseded by componentEncodings below |
| 1747 | QTest::addColumn<QString>(name: "original" ); |
| 1748 | QTest::addColumn<QByteArray>(name: "encoded" ); |
| 1749 | |
| 1750 | QTest::newRow(dataTag: "test_01" ) << QString::fromLatin1(str: "sdfsdf" ) << QByteArray("sdfsdf" ); |
| 1751 | QTest::newRow(dataTag: "test_02" ) << QString::fromUtf8(str: "æss" ) << QByteArray("%C3%A6ss" ); |
| 1752 | } |
| 1753 | |
| 1754 | void tst_QUrl::percentEncoding() |
| 1755 | { |
| 1756 | // This test is limited. It's superseded by componentEncodings below |
| 1757 | QFETCH(QString, original); |
| 1758 | QFETCH(QByteArray, encoded); |
| 1759 | |
| 1760 | QCOMPARE(QUrl(original).toEncoded().constData(), encoded.constData()); |
| 1761 | QCOMPARE(QUrl::fromEncoded(QUrl(original).toEncoded()), QUrl(original)); |
| 1762 | QCOMPARE(QUrl::fromEncoded(QUrl(original).toEncoded()).toString(), original); |
| 1763 | QCOMPARE(QUrl::fromEncoded(encoded), QUrl(original)); |
| 1764 | QCOMPARE(QUrl(QUrl(original).toString()).toString(), original); |
| 1765 | } |
| 1766 | |
| 1767 | void tst_QUrl::toPercentEncoding_data() |
| 1768 | { |
| 1769 | QTest::addColumn<QString>(name: "original" ); |
| 1770 | QTest::addColumn<QByteArray>(name: "encoded" ); |
| 1771 | QTest::addColumn<QByteArray>(name: "excludeInEncoding" ); |
| 1772 | QTest::addColumn<QByteArray>(name: "includeInEncoding" ); |
| 1773 | |
| 1774 | QTest::newRow(dataTag: "test_01" ) << QString::fromLatin1(str: "abcdevghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678-._~" ) |
| 1775 | << QByteArray("abcdevghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678-._~" ) |
| 1776 | << QByteArray("" ) |
| 1777 | << QByteArray("" ); |
| 1778 | QTest::newRow(dataTag: "test_02" ) << QString::fromLatin1(str: "{\t\n\r^\"abc}" ) |
| 1779 | << QByteArray("%7B%09%0A%0D%5E%22abc%7D" ) |
| 1780 | << QByteArray("" ) |
| 1781 | << QByteArray("" ); |
| 1782 | QTest::newRow(dataTag: "test_03" ) << QString::fromLatin1(str: "://?#[]@!$&'()*+,;=" ) |
| 1783 | << QByteArray("%3A%2F%2F%3F%23%5B%5D%40%21%24%26%27%28%29%2A%2B%2C%3B%3D" ) |
| 1784 | << QByteArray("" ) |
| 1785 | << QByteArray("" ); |
| 1786 | QTest::newRow(dataTag: "test_04" ) << QString::fromLatin1(str: "://?#[]@!$&'()*+,;=" ) |
| 1787 | << QByteArray("%3A%2F%2F%3F%23%5B%5D%40!$&'()*+,;=" ) |
| 1788 | << QByteArray("!$&'()*+,;=" ) |
| 1789 | << QByteArray("" ); |
| 1790 | QTest::newRow(dataTag: "test_05" ) << QString::fromLatin1(str: "abcd" ) |
| 1791 | << QByteArray("a%62%63d" ) |
| 1792 | << QByteArray("" ) |
| 1793 | << QByteArray("bc" ); |
| 1794 | } |
| 1795 | |
| 1796 | void tst_QUrl::toPercentEncoding() |
| 1797 | { |
| 1798 | QFETCH(QString, original); |
| 1799 | QFETCH(QByteArray, encoded); |
| 1800 | QFETCH(QByteArray, excludeInEncoding); |
| 1801 | QFETCH(QByteArray, includeInEncoding); |
| 1802 | |
| 1803 | QByteArray encodedUrl = QUrl::toPercentEncoding(original, exclude: excludeInEncoding, include: includeInEncoding); |
| 1804 | QCOMPARE(encodedUrl.constData(), encoded.constData()); |
| 1805 | QCOMPARE(original, QUrl::fromPercentEncoding(encodedUrl)); |
| 1806 | } |
| 1807 | |
| 1808 | void tst_QUrl::swap() |
| 1809 | { |
| 1810 | QUrl u1(QLatin1String("http://qt-project.org" )), u2(QLatin1String("http://www.kdab.com" )); |
| 1811 | u1.swap(other&: u2); |
| 1812 | QCOMPARE(u2.host(),QLatin1String("qt-project.org" )); |
| 1813 | QCOMPARE(u1.host(),QLatin1String("www.kdab.com" )); |
| 1814 | } |
| 1815 | |
| 1816 | void tst_QUrl::symmetry() |
| 1817 | { |
| 1818 | QUrl url(QString::fromUtf8(str: "http://www.räksmörgås.se/pub?a=b&a=dø&a=f#vræl" )); |
| 1819 | QCOMPARE(url.scheme(), QString::fromLatin1("http" )); |
| 1820 | QCOMPARE(url.host(), QString::fromUtf8("www.räksmörgås.se" )); |
| 1821 | QCOMPARE(url.host(QUrl::EncodeSpaces), QString::fromUtf8("www.räksmörgås.se" )); |
| 1822 | QCOMPARE(url.host(QUrl::EncodeUnicode), QString::fromUtf8("www.xn--rksmrgs-5wao1o.se" )); |
| 1823 | QCOMPARE(url.host(QUrl::EncodeUnicode | QUrl::EncodeSpaces), QString::fromUtf8("www.xn--rksmrgs-5wao1o.se" )); |
| 1824 | QCOMPARE(url.path(), QString::fromLatin1("/pub" )); |
| 1825 | // this will be encoded ... |
| 1826 | QCOMPARE(url.query(QUrl::FullyEncoded), QLatin1String("a=b&a=d%C3%B8&a=f" )); |
| 1827 | QCOMPARE(url.fragment(), QString::fromUtf8("vræl" )); |
| 1828 | |
| 1829 | QUrl onlyHost("//qt-project.org" ); |
| 1830 | QCOMPARE(onlyHost.toString(), QString::fromLatin1("//qt-project.org" )); |
| 1831 | |
| 1832 | { |
| 1833 | QString urlString = QString::fromLatin1(str: "http://desktop:33326/upnp/{32f525a6-6f31-426e-91ca-01c2e6c2c57e}" ); |
| 1834 | QString encodedUrlString = QString("http://desktop:33326/upnp/%7B32f525a6-6f31-426e-91ca-01c2e6c2c57e%7D" ); |
| 1835 | QUrl urlPreviewList(urlString); |
| 1836 | QCOMPARE(urlPreviewList.toString(), encodedUrlString); |
| 1837 | QByteArray b = urlPreviewList.toEncoded(); |
| 1838 | QCOMPARE(b.constData(), encodedUrlString.toLatin1().constData()); |
| 1839 | QCOMPARE(QUrl::fromEncoded(b).toString(), encodedUrlString); |
| 1840 | QCOMPARE(QUrl(b).toString(), encodedUrlString); |
| 1841 | } |
| 1842 | { |
| 1843 | QString urlString = QString::fromLatin1(str: "http://desktop:53423/deviceDescription?uuid={7977c17b-00bf-4af9-894e-fed28573c3a9}" ); |
| 1844 | QString encodedUrlString = QString("http://desktop:53423/deviceDescription?uuid=%7B7977c17b-00bf-4af9-894e-fed28573c3a9%7D" ); |
| 1845 | QUrl urlPreviewList(urlString); |
| 1846 | QCOMPARE(urlPreviewList.toString(), encodedUrlString); |
| 1847 | QByteArray b = urlPreviewList.toEncoded(); |
| 1848 | QCOMPARE(b.constData(), encodedUrlString.toLatin1().constData()); |
| 1849 | QCOMPARE(QUrl::fromEncoded(b).toString(), encodedUrlString); |
| 1850 | QCOMPARE(QUrl(b).toString(), encodedUrlString); |
| 1851 | } |
| 1852 | } |
| 1853 | |
| 1854 | void tst_QUrl::ipvfuture_data() |
| 1855 | { |
| 1856 | QTest::addColumn<QString>(name: "input" ); |
| 1857 | QTest::addColumn<bool>(name: "isValid" ); |
| 1858 | QTest::addColumn<QString>(name: "output" ); |
| 1859 | |
| 1860 | // No one uses IPvFuture yet, so we have no clue what it might contain |
| 1861 | // We're just testing that it can hold what the RFC says it should hold: |
| 1862 | // IPvFuture = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" ) |
| 1863 | QTest::newRow(dataTag: "missing-version-dot" ) << "x://[v]" << false; |
| 1864 | QTest::newRow(dataTag: "missing-version" ) << "x://[v.]" << false; |
| 1865 | QTest::newRow(dataTag: "missing-version-2" ) << "x://[v.1234]" << false; |
| 1866 | QTest::newRow(dataTag: "missing-dot" ) << "x://[v7]" << false; |
| 1867 | QTest::newRow(dataTag: "missing-dot-2" ) << "x://[v71234]" << false; |
| 1868 | QTest::newRow(dataTag: "missing-data" ) << "x://[v7.]" << false; |
| 1869 | QTest::newRow(dataTag: "non-hex-version" ) << "x://[vz.1234]" << false; |
| 1870 | |
| 1871 | QTest::newRow(dataTag: "digit-ver" ) << "x://[v7.1]" << true << "x://[v7.1]" ; |
| 1872 | QTest::newRow(dataTag: "lowercase-hex-ver" ) << "x://[va.1]" << true << "x://[vA.1]" ; |
| 1873 | QTest::newRow(dataTag: "lowercase-hex-ver" ) << "x://[vA.1]" << true << "x://[vA.1]" ; |
| 1874 | |
| 1875 | QTest::newRow(dataTag: "data-digits" ) << "x://[v7.1234]" << true << "x://[v7.1234]" ; |
| 1876 | QTest::newRow(dataTag: "data-unreserved" ) << "x://[v7.hello~-WORLD_.com]" << true << "x://[v7.hello~-WORLD_.com]" ; |
| 1877 | QTest::newRow(dataTag: "data-sub-delims-colon" ) << "x://[v7.!$&'()*+,;=:]" << true << "x://[v7.!$&'()*+,;=:]" ; |
| 1878 | |
| 1879 | // we're using the tolerant parser |
| 1880 | QTest::newRow(dataTag: "data-encoded-digits" ) << "x://[v7.%31%32%33%34]" << true << "x://[v7.1234]" ; |
| 1881 | QTest::newRow(dataTag: "data-encoded-unreserved" ) << "x://[v7.%7E%2D%54%5f%2E]" << true << "x://[v7.~-T_.]" ; |
| 1882 | QTest::newRow(dataTag: "data-encoded-sub-delims-colon" ) << "x://[v7.%21%24%26%27%28%29%2A%2B%2C%3B%3D%3A]" << true << "x://[v7.!$&'()*+,;=:]" ; |
| 1883 | |
| 1884 | // should we test "[%76%37%2ex]" -> "[v7.x]" ? |
| 1885 | |
| 1886 | QTest::newRow(dataTag: "data-invalid-space" ) << "x://[v7.%20]" << false; |
| 1887 | QTest::newRow(dataTag: "data-invalid-control" ) << "x://[v7.\x7f]" << false; |
| 1888 | QTest::newRow(dataTag: "data-invalid-other-1" ) << "x://[v7.{1234}]" << false; |
| 1889 | QTest::newRow(dataTag: "data-invalid-other-2" ) << "x://[v7.<hello>]" << false; |
| 1890 | QTest::newRow(dataTag: "data-invalid-unicode" ) << "x://[v7.æøå]" << false; |
| 1891 | QTest::newRow(dataTag: "data-invalid-percent" ) << "x://[v7.%]" << false; |
| 1892 | QTest::newRow(dataTag: "data-invalid-percent-percent" ) << "x://[v7.%25]" << false; |
| 1893 | } |
| 1894 | |
| 1895 | void tst_QUrl::ipvfuture() |
| 1896 | { |
| 1897 | QFETCH(QString, input); |
| 1898 | QFETCH(bool, isValid); |
| 1899 | |
| 1900 | QUrl url(input); |
| 1901 | if (isValid) { |
| 1902 | QVERIFY2(url.isValid(), qPrintable(url.errorString())); |
| 1903 | |
| 1904 | QFETCH(QString, output); |
| 1905 | QCOMPARE(url.toString(), output); |
| 1906 | |
| 1907 | QUrl url2(output); |
| 1908 | QCOMPARE(url2, url); |
| 1909 | } else { |
| 1910 | QVERIFY(!url.isValid()); |
| 1911 | } |
| 1912 | } |
| 1913 | |
| 1914 | |
| 1915 | void tst_QUrl::ipv6_data() |
| 1916 | { |
| 1917 | QTest::addColumn<QString>(name: "ipv6Auth" ); |
| 1918 | QTest::addColumn<bool>(name: "isValid" ); |
| 1919 | QTest::addColumn<QString>(name: "output" ); |
| 1920 | |
| 1921 | QTest::newRow(dataTag: "empty" ) << "//[]" << false << "" ; |
| 1922 | |
| 1923 | QTest::newRow(dataTag: "case 1" ) << QString::fromLatin1(str: "//[56:56:56:56:56:56:56:56]" ) << true |
| 1924 | << "//[56:56:56:56:56:56:56:56]" ; |
| 1925 | QTest::newRow(dataTag: "case 2" ) << QString::fromLatin1(str: "//[::56:56:56:56:56:56:56]" ) << true |
| 1926 | << "//[0:56:56:56:56:56:56:56]" ; |
| 1927 | QTest::newRow(dataTag: "case 3" ) << QString::fromLatin1(str: "//[56::56:56:56:56:56:56]" ) << true |
| 1928 | << "//[56:0:56:56:56:56:56:56]" ; |
| 1929 | QTest::newRow(dataTag: "case 4" ) << QString::fromLatin1(str: "//[56:56::56:56:56:56:56]" ) << true |
| 1930 | << "//[56:56:0:56:56:56:56:56]" ; |
| 1931 | QTest::newRow(dataTag: "case 5" ) << QString::fromLatin1(str: "//[56:56:56::56:56:56:56]" ) << true |
| 1932 | << "//[56:56:56:0:56:56:56:56]" ; |
| 1933 | QTest::newRow(dataTag: "case 6" ) << QString::fromLatin1(str: "//[56:56:56:56::56:56:56]" ) << true |
| 1934 | << "//[56:56:56:56:0:56:56:56]" ; |
| 1935 | QTest::newRow(dataTag: "case 7" ) << QString::fromLatin1(str: "//[56:56:56:56:56::56:56]" ) << true |
| 1936 | << "//[56:56:56:56:56:0:56:56]" ; |
| 1937 | QTest::newRow(dataTag: "case 8" ) << QString::fromLatin1(str: "//[56:56:56:56:56:56::56]" ) << true |
| 1938 | << "//[56:56:56:56:56:56:0:56]" ; |
| 1939 | QTest::newRow(dataTag: "case 9" ) << QString::fromLatin1(str: "//[56:56:56:56:56:56:56::]" ) << true |
| 1940 | << "//[56:56:56:56:56:56:56:0]" ; |
| 1941 | QTest::newRow(dataTag: "case 4 with one less" ) << QString::fromLatin1(str: "//[56::56:56:56:56:56]" ) << true |
| 1942 | << "//[56::56:56:56:56:56]" ; |
| 1943 | QTest::newRow(dataTag: "case 4 with less and ip4" ) << QString::fromLatin1(str: "//[56::56:56:56:127.0.0.1]" ) << true |
| 1944 | << "//[56::56:56:56:7f00:1]" ; |
| 1945 | QTest::newRow(dataTag: "case 7 with one and ip4" ) << QString::fromLatin1(str: "//[56::255.0.0.0]" ) << true |
| 1946 | << "//[56::ff00:0]" ; |
| 1947 | QTest::newRow(dataTag: "case 2 with ip4" ) << QString::fromLatin1(str: "//[::56:56:56:56:56:0.0.0.255]" ) << true |
| 1948 | << "//[0:56:56:56:56:56:0:ff]" ; |
| 1949 | QTest::newRow(dataTag: "case 2 with half ip4" ) << QString::fromLatin1(str: "//[::56:56:56:56:56:56:0.255]" ) << false << "" ; |
| 1950 | QTest::newRow(dataTag: "case 4 with less and ip4 and port and useinfo" ) |
| 1951 | << QString::fromLatin1(str: "//user:pass@[56::56:56:56:127.0.0.1]:99" ) << true |
| 1952 | << "//user:pass@[56::56:56:56:7f00:1]:99" ; |
| 1953 | QTest::newRow(dataTag: "case :," ) << QString::fromLatin1(str: "//[:,]" ) << false << "" ; |
| 1954 | QTest::newRow(dataTag: "case ::bla" ) << QString::fromLatin1(str: "//[::bla]" ) << false << "" ; |
| 1955 | QTest::newRow(dataTag: "case v4-mapped" ) << "//[0:0:0:0:0:ffff:7f00:1]" << true << "//[::ffff:127.0.0.1]" ; |
| 1956 | |
| 1957 | QTest::newRow(dataTag: "encoded-digit" ) << "//[::%31]" << true << "//[::1]" ; |
| 1958 | QTest::newRow(dataTag: "encoded-colon" ) << "//[%3A%3A]" << true << "//[::]" ; |
| 1959 | |
| 1960 | QTest::newRow(dataTag: "full ipv6 with zone id (decoded %)" ) << QString::fromLatin1(str: "//[56:56:56:56:56:56:56:56%eth0]" ) << true |
| 1961 | << "//[56:56:56:56:56:56:56:56%25eth0]" ; |
| 1962 | |
| 1963 | QTest::newRow(dataTag: "full ipv6 with zone id (encoded %)" ) << QString::fromLatin1(str: "//[56:56:56:56:56:56:56:56%25eth0]" ) << true |
| 1964 | << "//[56:56:56:56:56:56:56:56%25eth0]" ; |
| 1965 | |
| 1966 | QTest::newRow(dataTag: "full ipv6 with invalid zone id" ) << QString::fromLatin1(str: "//[56:56:56:56:56:56:56:56%]" ) << false << "" ; |
| 1967 | |
| 1968 | QTest::newRow(dataTag: "full ipv6 with invalid zone id (encoded)" ) << QString::fromLatin1(str: "//[56:56:56:56:56:56:56:56%25]" ) << false << "" ; |
| 1969 | |
| 1970 | QTest::newRow(dataTag: "full ipv6 with zone id 25 (encoded)" ) << QString::fromLatin1(str: "//[56:56:56:56:56:56:56:56%2525]" ) << true << "//[56:56:56:56:56:56:56:56%2525]" ; |
| 1971 | |
| 1972 | QTest::newRow(dataTag: "case 4 with less and ip4 and port and useinfo and zone id" ) |
| 1973 | << QString::fromLatin1(str: "//user:pass@[56::56:56:56:127.0.0.1%ethernet_1]:99" ) << true |
| 1974 | << "//user:pass@[56::56:56:56:7f00:1%25ethernet_1]:99" ; |
| 1975 | |
| 1976 | QTest::newRow(dataTag: "encoded-digit including zone id" ) << "//[::%31%25eth0]" << true << "//[::1%25eth0]" ; |
| 1977 | } |
| 1978 | |
| 1979 | void tst_QUrl::ipv6() |
| 1980 | { |
| 1981 | QFETCH(QString, ipv6Auth); |
| 1982 | QFETCH(bool, isValid); |
| 1983 | QFETCH(QString, output); |
| 1984 | |
| 1985 | QUrl url(ipv6Auth); |
| 1986 | |
| 1987 | QCOMPARE(url.isValid(), isValid); |
| 1988 | QCOMPARE(url.toString().isEmpty(), !isValid); |
| 1989 | if (url.isValid()) { |
| 1990 | QCOMPARE(url.toString(), output); |
| 1991 | url.setHost(host: url.host()); |
| 1992 | QVERIFY(url.isValid()); |
| 1993 | QCOMPARE(url.toString(), output); |
| 1994 | } |
| 1995 | } |
| 1996 | |
| 1997 | void tst_QUrl::ipv6_2_data() |
| 1998 | { |
| 1999 | QTest::addColumn<QString>(name: "input" ); |
| 2000 | QTest::addColumn<QString>(name: "output" ); |
| 2001 | |
| 2002 | QTest::newRow(dataTag: "[::ffff:129.144.52.38]" ) |
| 2003 | << QString("http://[::ffff:129.144.52.38]/cgi/test.cgi" ) |
| 2004 | << QString("http://[::ffff:129.144.52.38]/cgi/test.cgi" ); |
| 2005 | QTest::newRow(dataTag: "[::FFFF:129.144.52.38]" ) |
| 2006 | << QString("http://[::FFFF:129.144.52.38]/cgi/test.cgi" ) |
| 2007 | << QString("http://[::ffff:129.144.52.38]/cgi/test.cgi" ); |
| 2008 | } |
| 2009 | |
| 2010 | void tst_QUrl::ipv6_2() |
| 2011 | { |
| 2012 | QFETCH(QString, input); |
| 2013 | QFETCH(QString, output); |
| 2014 | |
| 2015 | QUrl url(input); |
| 2016 | QCOMPARE(url.toString(), output); |
| 2017 | url.setHost(host: url.host()); |
| 2018 | QCOMPARE(url.toString(), output); |
| 2019 | } |
| 2020 | |
| 2021 | void tst_QUrl::moreIpv6() |
| 2022 | { |
| 2023 | QUrl waba1("http://www.kde.org/cgi/test.cgi" ); |
| 2024 | waba1.setHost(host: "::ffff:129.144.52.38" ); |
| 2025 | QCOMPARE(QString::fromLatin1(waba1.toEncoded()), QString::fromLatin1("http://[::ffff:129.144.52.38]/cgi/test.cgi" )); |
| 2026 | } |
| 2027 | |
| 2028 | void tst_QUrl::isRelative_data() |
| 2029 | { |
| 2030 | QTest::addColumn<QString>(name: "url" ); |
| 2031 | QTest::addColumn<bool>(name: "trueFalse" ); |
| 2032 | |
| 2033 | QTest::newRow(dataTag: "not" ) << QString::fromLatin1(str: "http://qt-project.org" ) << false; |
| 2034 | QTest::newRow(dataTag: "55288" ) << QString::fromLatin1(str: "node64.html#fig:form:ana" ) << true; |
| 2035 | |
| 2036 | // kde |
| 2037 | QTest::newRow(dataTag: "mailto: URL, is relative" ) << "mailto:faure@kde.org" << false; |
| 2038 | QTest::newRow(dataTag: "man: URL, is relative" ) << "man:mmap" << false; |
| 2039 | QTest::newRow(dataTag: "javascript: URL, is relative" ) << "javascript:doSomething()" << false; |
| 2040 | QTest::newRow(dataTag: "file: URL, is relative" ) << "file:/blah" << false; |
| 2041 | QTest::newRow(dataTag: "/path, is relative" ) << "/path" << true; |
| 2042 | QTest::newRow(dataTag: "something, is relative" ) << "something" << true; |
| 2043 | // end kde |
| 2044 | } |
| 2045 | |
| 2046 | void tst_QUrl::isRelative() |
| 2047 | { |
| 2048 | QFETCH(QString, url); |
| 2049 | QFETCH(bool, trueFalse); |
| 2050 | |
| 2051 | QCOMPARE(QUrl(url).isRelative(), trueFalse); |
| 2052 | } |
| 2053 | |
| 2054 | void tst_QUrl::hasQuery_data() |
| 2055 | { |
| 2056 | QTest::addColumn<QString>(name: "url" ); |
| 2057 | QTest::addColumn<bool>(name: "trueFalse" ); |
| 2058 | |
| 2059 | QTest::newRow(dataTag: "no query items" ) << "http://www.foo.bar" << false; |
| 2060 | |
| 2061 | QTest::newRow(dataTag: "empty query" ) << "http://www.foo.bar?" << true; |
| 2062 | QTest::newRow(dataTag: "empty query 2" ) << "http://www.foo.bar/?" << true; |
| 2063 | |
| 2064 | QTest::newRow(dataTag: "query" ) << "http://www.foo.bar?query" << true; |
| 2065 | QTest::newRow(dataTag: "query=" ) << "http://www.foo.bar?query=" << true; |
| 2066 | QTest::newRow(dataTag: "query=value" ) << "http://www.foo.bar?query=value" << true; |
| 2067 | |
| 2068 | QTest::newRow(dataTag: "%3f" ) << "http://www.foo.bar/file%3f" << false; |
| 2069 | QTest::newRow(dataTag: "%3f-query" ) << "http://www.foo.bar/file%3fquery" << false; |
| 2070 | QTest::newRow(dataTag: "%3f-query=value" ) << "http://www.foo.bar/file%3fquery=value" << false; |
| 2071 | } |
| 2072 | |
| 2073 | void tst_QUrl::hasQuery() |
| 2074 | { |
| 2075 | QFETCH(QString, url); |
| 2076 | QFETCH(bool, trueFalse); |
| 2077 | |
| 2078 | QUrl qurl(url); |
| 2079 | QCOMPARE(qurl.hasQuery(), trueFalse); |
| 2080 | QCOMPARE(qurl.query().isNull(), !trueFalse); |
| 2081 | } |
| 2082 | |
| 2083 | void tst_QUrl::nameprep() |
| 2084 | { |
| 2085 | QUrl url(QString::fromUtf8(str: "http://www.fu" "\xc3" "\x9f" "ball.de/" )); |
| 2086 | QCOMPARE(url.toString(), QString::fromLatin1("http://www.fussball.de/" )); |
| 2087 | } |
| 2088 | |
| 2089 | void tst_QUrl::isValid() |
| 2090 | { |
| 2091 | { |
| 2092 | QUrl url(QString("A=B" )); |
| 2093 | QVERIFY(url.isValid()); |
| 2094 | QVERIFY(!url.toString().isEmpty()); |
| 2095 | QCOMPARE(url.path(), QString("A=B" )); |
| 2096 | } |
| 2097 | { |
| 2098 | QUrl url = QUrl::fromEncoded(url: "http://strange<username>@ok-hostname/" , mode: QUrl::StrictMode); |
| 2099 | QVERIFY(!url.isValid()); |
| 2100 | QVERIFY(url.toString().isEmpty()); |
| 2101 | // < and > are not allowed in userinfo in strict mode |
| 2102 | url.setUserName(userName: "normal_username" ); |
| 2103 | QVERIFY(url.isValid()); |
| 2104 | } |
| 2105 | { |
| 2106 | QUrl url = QUrl::fromEncoded(url: "http://strange<username>@ok-hostname/" ); |
| 2107 | QVERIFY(url.isValid()); |
| 2108 | QVERIFY(!url.toString().isEmpty()); |
| 2109 | // < and > are allowed in tolerant mode |
| 2110 | QCOMPARE(url.toEncoded(), QByteArray("http://strange%3Cusername%3E@ok-hostname/" )); |
| 2111 | } |
| 2112 | { |
| 2113 | QUrl url = QUrl::fromEncoded(url: "http://strange;hostname/here" ); |
| 2114 | QVERIFY(!url.isValid()); |
| 2115 | QVERIFY(url.toString().isEmpty()); |
| 2116 | QCOMPARE(url.path(), QString("/here" )); |
| 2117 | url.setAuthority(authority: "strange;hostname" ); |
| 2118 | QVERIFY(!url.isValid()); |
| 2119 | QVERIFY(url.toString().isEmpty()); |
| 2120 | url.setAuthority(authority: "foobar@bar" ); |
| 2121 | QVERIFY(url.isValid()); |
| 2122 | QVERIFY(!url.toString().isEmpty()); |
| 2123 | url.setAuthority(authority: "strange;hostname" ); |
| 2124 | QVERIFY(!url.isValid()); |
| 2125 | QVERIFY(url.toString().isEmpty()); |
| 2126 | QVERIFY2(url.errorString().contains("Invalid hostname" ), |
| 2127 | qPrintable(url.errorString())); |
| 2128 | } |
| 2129 | |
| 2130 | { |
| 2131 | QUrl url = QUrl::fromEncoded(url: "foo://stuff;1/g" ); |
| 2132 | QVERIFY(!url.isValid()); |
| 2133 | QVERIFY(url.toString().isEmpty()); |
| 2134 | QCOMPARE(url.path(), QString("/g" )); |
| 2135 | url.setHost(host: "stuff;1" ); |
| 2136 | QVERIFY(!url.isValid()); |
| 2137 | QVERIFY(url.toString().isEmpty()); |
| 2138 | url.setHost(host: "stuff-1" ); |
| 2139 | QVERIFY(url.isValid()); |
| 2140 | QVERIFY(!url.toString().isEmpty()); |
| 2141 | url.setHost(host: "stuff;1" ); |
| 2142 | QVERIFY(!url.isValid()); |
| 2143 | QVERIFY(url.toString().isEmpty()); |
| 2144 | QVERIFY2(url.errorString().contains("Invalid hostname" ), |
| 2145 | qPrintable(url.errorString())); |
| 2146 | } |
| 2147 | |
| 2148 | { |
| 2149 | QUrl url = QUrl::fromEncoded(url: "foo://%f0%9f%93%99.example.la/g" ); |
| 2150 | QVERIFY(!url.isValid()); |
| 2151 | QVERIFY(url.toString().isEmpty()); |
| 2152 | QCOMPARE(url.path(), QString("/g" )); |
| 2153 | url.setHost(host: "%f0%9f%93%99.example.la/" ); |
| 2154 | QVERIFY(!url.isValid()); |
| 2155 | QVERIFY(url.toString().isEmpty()); |
| 2156 | url.setHost(host: "\xf0\x9f\x93\x99.example.la/" ); |
| 2157 | QVERIFY(!url.isValid()); |
| 2158 | QVERIFY(url.toString().isEmpty()); |
| 2159 | QVERIFY2(url.errorString().contains("Invalid hostname" ), |
| 2160 | qPrintable(url.errorString())); |
| 2161 | } |
| 2162 | |
| 2163 | { |
| 2164 | QUrl url("http://example.com" ); |
| 2165 | QVERIFY(url.isValid()); |
| 2166 | QVERIFY(!url.toString().isEmpty()); |
| 2167 | url.setPath(path: "relative" ); |
| 2168 | QVERIFY(!url.isValid()); |
| 2169 | QVERIFY(url.toString().isEmpty()); |
| 2170 | QVERIFY(url.errorString().contains("Path component is relative and authority is present" )); |
| 2171 | } |
| 2172 | |
| 2173 | { |
| 2174 | QUrl url("http:" ); |
| 2175 | url.setPath(path: "//example.com" ); |
| 2176 | QVERIFY(!url.isValid()); |
| 2177 | QVERIFY(url.toString().isEmpty()); |
| 2178 | QVERIFY(url.errorString().contains("Path component starts with '//' and authority is absent" )); |
| 2179 | |
| 2180 | // should disappear if we set a port |
| 2181 | url.setPort(80); |
| 2182 | QVERIFY(url.isValid()); |
| 2183 | QCOMPARE(url.toString(), QString("http://:80//example.com" )); |
| 2184 | } |
| 2185 | |
| 2186 | { |
| 2187 | QUrl url; |
| 2188 | url.setPath(path: "http://example.com" ); |
| 2189 | QVERIFY(!url.isValid()); |
| 2190 | QVERIFY(url.toString().isEmpty()); |
| 2191 | QVERIFY(url.errorString().contains("':' before any '/'" )); |
| 2192 | |
| 2193 | // this specific error disappears if we set anything in the authority, |
| 2194 | // but then we run into another error |
| 2195 | url.setPort(80); |
| 2196 | QVERIFY(!url.isValid()); |
| 2197 | QVERIFY(url.toString().isEmpty()); |
| 2198 | QVERIFY(url.errorString().contains("Path component is relative and authority is present" )); |
| 2199 | } |
| 2200 | |
| 2201 | { |
| 2202 | QUrl url("file://./localfile.html" ); |
| 2203 | QVERIFY(!url.isValid()); |
| 2204 | } |
| 2205 | } |
| 2206 | |
| 2207 | void tst_QUrl::schemeValidator_data() |
| 2208 | { |
| 2209 | QTest::addColumn<QString>(name: "input" ); |
| 2210 | QTest::addColumn<bool>(name: "result" ); |
| 2211 | QTest::addColumn<QString>(name: "scheme" ); |
| 2212 | |
| 2213 | // scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) |
| 2214 | |
| 2215 | QTest::newRow(dataTag: "empty" ) << QString() << false << QString(); |
| 2216 | |
| 2217 | // uncontroversial ones |
| 2218 | QTest::newRow(dataTag: "ftp" ) << "ftp://ftp.example.com/" << true << "ftp" ; |
| 2219 | QTest::newRow(dataTag: "http" ) << "http://www.example.com/" << true << "http" ; |
| 2220 | QTest::newRow(dataTag: "mailto" ) << "mailto:smith@example.com" << true << "mailto" ; |
| 2221 | QTest::newRow(dataTag: "file-1slash" ) << "file:/etc/passwd" << true << "file" ; |
| 2222 | QTest::newRow(dataTag: "file-2slashes" ) << "file://server/etc/passwd" << true << "file" ; |
| 2223 | QTest::newRow(dataTag: "file-3slashes" ) << "file:///etc/passwd" << true << "file" ; |
| 2224 | |
| 2225 | QTest::newRow(dataTag: "mailto+subject" ) << "mailto:smith@example.com?subject=Hello%20World" << true << "mailto" ; |
| 2226 | QTest::newRow(dataTag: "mailto+host" ) << "mailto://smtp.example.com/smith@example.com" << true << "mailto" ; |
| 2227 | |
| 2228 | // valid, but unexpected |
| 2229 | QTest::newRow(dataTag: "ftp-nohost" ) << "ftp:/etc/passwd" << true << "ftp" ; |
| 2230 | QTest::newRow(dataTag: "http-nohost" ) << "http:/etc/passwd" << true << "http" ; |
| 2231 | QTest::newRow(dataTag: "mailto-nomail" ) << "mailto://smtp.example.com" << true << "mailto" ; |
| 2232 | |
| 2233 | // schemes with numbers |
| 2234 | QTest::newRow(dataTag: "digits" ) << "proto2://" << true << "proto2" ; |
| 2235 | |
| 2236 | // schemes with dots, dashes, and pluses |
| 2237 | QTest::newRow(dataTag: "svn+ssh" ) << "svn+ssh://svn.example.com" << true << "svn+ssh" ; |
| 2238 | QTest::newRow(dataTag: "withdash" ) << "svn-ssh://svn.example.com" << true << "svn-ssh" ; |
| 2239 | QTest::newRow(dataTag: "withdots" ) << "org.qt-project://qt-project.org" << true << "org.qt-project" ; |
| 2240 | |
| 2241 | // lowercasing |
| 2242 | QTest::newRow(dataTag: "FTP" ) << "FTP://ftp.example.com/" << true << "ftp" ; |
| 2243 | QTest::newRow(dataTag: "HTTP" ) << "HTTP://www.example.com/" << true << "http" ; |
| 2244 | QTest::newRow(dataTag: "MAILTO" ) << "MAILTO:smith@example.com" << true << "mailto" ; |
| 2245 | QTest::newRow(dataTag: "FILE" ) << "FILE:/etc/passwd" << true << "file" ; |
| 2246 | QTest::newRow(dataTag: "SVN+SSH" ) << "SVN+SSH://svn.example.com" << true << "svn+ssh" ; |
| 2247 | QTest::newRow(dataTag: "WITHDASH" ) << "SVN-SSH://svn.example.com" << true << "svn-ssh" ; |
| 2248 | QTest::newRow(dataTag: "WITHDOTS" ) << "ORG.QT-PROJECT://qt-project.org" << true << "org.qt-project" ; |
| 2249 | |
| 2250 | // invalid entries |
| 2251 | QTest::newRow(dataTag: "start-digit" ) << "1http://example.com" << false << "1http" ; |
| 2252 | QTest::newRow(dataTag: "start-plus" ) << "+ssh://user@example.com" << false << "+ssh" ; |
| 2253 | QTest::newRow(dataTag: "start-dot" ) << ".org.example:///" << false << ".org.example" ; |
| 2254 | QTest::newRow(dataTag: "with-space" ) << "a b://" << false << "a b" ; |
| 2255 | QTest::newRow(dataTag: "with-non-ascii" ) << "\304\245\305\243\305\245\321\200://example.com" << false << "\304\245\305\243\305\245\321\200" ; |
| 2256 | QTest::newRow(dataTag: "with-control1" ) << "http\1://example.com" << false << "http\1" ; |
| 2257 | QTest::newRow(dataTag: "with-control127" ) << "http\177://example.com" << false << "http\177" ; |
| 2258 | QTest::newRow(dataTag: "with-null" ) << QString::fromLatin1(str: "http\0://example.com" , size: 19) << false << QString::fromLatin1(str: "http\0" , size: 5); |
| 2259 | |
| 2260 | QTest::newRow(dataTag: "percent-encoded" ) << "%68%74%%74%70://example.com" << false << "%68%74%%74%70" ; |
| 2261 | |
| 2262 | static const char controls[] = "!\"$&'()*,;<=>[\\]^_`{|}~" ; |
| 2263 | for (char control : controls) { |
| 2264 | const QString scheme = QLatin1String("pre" ) + QLatin1Char(control) + QLatin1String("post" ); |
| 2265 | QTest::newRow(dataTag: (QByteArrayLiteral("with-" ) + control).constData()) |
| 2266 | << (scheme + QLatin1String("://example.com/" )) |
| 2267 | << false << scheme; |
| 2268 | } |
| 2269 | } |
| 2270 | |
| 2271 | void tst_QUrl::schemeValidator() |
| 2272 | { |
| 2273 | QFETCH(QString, input); |
| 2274 | QFETCH(bool, result); |
| 2275 | |
| 2276 | QUrl url(input); |
| 2277 | QCOMPARE(url.isValid(), result); |
| 2278 | if (result) { |
| 2279 | QFETCH(QString, scheme); |
| 2280 | QCOMPARE(url.scheme(), scheme); |
| 2281 | |
| 2282 | // reconstruct with just the scheme: |
| 2283 | url.setUrl(url: scheme + ':'); |
| 2284 | QVERIFY(url.isValid()); |
| 2285 | QCOMPARE(url.scheme(), scheme); |
| 2286 | } else { |
| 2287 | QVERIFY(url.toString().isEmpty()); |
| 2288 | } |
| 2289 | } |
| 2290 | |
| 2291 | void tst_QUrl::setScheme_data() |
| 2292 | { |
| 2293 | schemeValidator_data(); |
| 2294 | |
| 2295 | // a couple more which wouldn't work in parsing a full URL |
| 2296 | QTest::newRow(dataTag: "with-slash" ) << QString() << false << "http/" ; |
| 2297 | QTest::newRow(dataTag: "with-question" ) << QString() << false << "http?" ; |
| 2298 | QTest::newRow(dataTag: "with-hash" ) << QString() << false << "http#" ; |
| 2299 | } |
| 2300 | |
| 2301 | void tst_QUrl::setScheme() |
| 2302 | { |
| 2303 | QFETCH(QString, scheme); |
| 2304 | QFETCH(bool, result); |
| 2305 | QString expectedScheme; |
| 2306 | if (result) |
| 2307 | expectedScheme = scheme; |
| 2308 | |
| 2309 | QUrl url; |
| 2310 | url.setScheme(scheme); |
| 2311 | QCOMPARE(url.isValid(), result); |
| 2312 | QCOMPARE(url.scheme(), expectedScheme); |
| 2313 | |
| 2314 | url.setScheme(scheme.toUpper()); |
| 2315 | QCOMPARE(url.isValid(), result); |
| 2316 | QCOMPARE(url.scheme(), expectedScheme); |
| 2317 | } |
| 2318 | |
| 2319 | void tst_QUrl::strictParser_data() |
| 2320 | { |
| 2321 | QTest::addColumn<QString>(name: "input" ); |
| 2322 | QTest::addColumn<QString>(name: "needle" ); |
| 2323 | |
| 2324 | // QUrl doesn't detect an error in the scheme when parsing because |
| 2325 | // it falls back to parsing as a path. So, these errors are path errors |
| 2326 | QTest::newRow(dataTag: "invalid-scheme" ) << "ht%://example.com" << "character '%' not permitted" ; |
| 2327 | QTest::newRow(dataTag: "empty-scheme" ) << ":/" << "':' before any '/'" ; |
| 2328 | |
| 2329 | QTest::newRow(dataTag: "invalid-user1" ) << "http://bad<user_name>@ok-hostname" << "Invalid user name (character '<' not permitted)" ; |
| 2330 | QTest::newRow(dataTag: "invalid-user2" ) << "http://bad%@ok-hostname" << "Invalid user name (character '%' not permitted)" ; |
| 2331 | |
| 2332 | QTest::newRow(dataTag: "invalid-password" ) << "http://user:pass\x7F@ok-hostname" << "Invalid password (character '\x7F' not permitted)" ; |
| 2333 | |
| 2334 | QTest::newRow(dataTag: "invalid-regname" ) << "http://bad<hostname>" << "Invalid hostname (contains invalid characters)" ; |
| 2335 | QTest::newRow(dataTag: "invalid-regname-2" ) << "http://b%61d" << "Invalid hostname (contains invalid characters)" ; |
| 2336 | QTest::newRow(dataTag: "invalid-ipv6" ) << "http://[:::]" << "Invalid IPv6 address" ; |
| 2337 | QTest::newRow(dataTag: "invalid-ipv6-char1" ) << "http://[::g]" << "Invalid IPv6 address (character 'g' not permitted)" ; |
| 2338 | QTest::newRow(dataTag: "invalid-ipv6-char2" ) << "http://[z::]" << "Invalid IPv6 address (character 'z' not permitted)" ; |
| 2339 | QTest::newRow(dataTag: "invalid-ipvfuture-1" ) << "http://[v7]" << "Invalid IPvFuture address" ; |
| 2340 | QTest::newRow(dataTag: "invalid-ipvfuture-2" ) << "http://[v7.]" << "Invalid IPvFuture address" ; |
| 2341 | QTest::newRow(dataTag: "invalid-ipvfuture-3" ) << "http://[v789]" << "Invalid IPvFuture address" ; |
| 2342 | QTest::newRow(dataTag: "invalid-ipvfuture-char1" ) << "http://[v7.^]" << "Invalid IPvFuture address" ; |
| 2343 | QTest::newRow(dataTag: "invalid-encoded-ipv6" ) << "x://[%3a%3a%31]" << "Invalid IPv6 address" ; |
| 2344 | QTest::newRow(dataTag: "invalid-encoded-ipvfuture" ) << "x://[v7.%7E%2D%54%5f%2E]" << "Invalid IPvFuture address" ; |
| 2345 | QTest::newRow(dataTag: "unbalanced-brackets" ) << "http://[ff02::1" << "Expected ']' to match '[' in hostname" ; |
| 2346 | |
| 2347 | // invalid hostnames happen in TolerantMode too |
| 2348 | QTest::newRow(dataTag: "invalid-hostname-leading-dot" ) << "http://.co.uk" << "Invalid hostname (contains invalid characters)" ; |
| 2349 | QTest::newRow(dataTag: "invalid-hostname-double-dot" ) << "http://co..uk" << "Invalid hostname (contains invalid characters)" ; |
| 2350 | QTest::newRow(dataTag: "invalid-hostname-non-LDH" ) << "http://foo,bar.example.com" << "Invalid hostname (contains invalid characters)" ; |
| 2351 | QTest::newRow(dataTag: "idn-prohibited-char-space" ) << "http:// " << "Invalid hostname (contains invalid characters)" ; |
| 2352 | QTest::newRow(dataTag: "idn-prohibited-char-nbsp" ) << "http://\xc2\xa0" << "Invalid hostname (contains invalid characters)" ; |
| 2353 | QTest::newRow(dataTag: "idn-prohibited-char-control-1f" ) << "http://\x1f" << "Invalid hostname (contains invalid characters)" ; |
| 2354 | QTest::newRow(dataTag: "idn-prohibited-char-control-7f" ) << "http://\x7f" << "Invalid hostname (contains invalid characters)" ; |
| 2355 | QTest::newRow(dataTag: "idn-prohibited-char-control-80" ) << "http://\xc2\x80" << "Invalid hostname (contains invalid characters)" ; |
| 2356 | QTest::newRow(dataTag: "idn-prohibited-char-private-bmp" ) << "http://\xee\x80\x80" << "Invalid hostname (contains invalid characters)" ; |
| 2357 | QTest::newRow(dataTag: "idn-prohibited-char-private-plane15" ) << "http://\xf3\xb0\x80\x80" << "Invalid hostname (contains invalid characters)" ; |
| 2358 | QTest::newRow(dataTag: "idn-prohibited-char-private-plane16" ) << "http://\xf4\x80\x80\x80" << "Invalid hostname (contains invalid characters)" ; |
| 2359 | QTest::newRow(dataTag: "idn-prohibited-char-ffff" ) << "http://\xef\xbf\xbf" << "Invalid hostname (contains invalid characters)" ; |
| 2360 | QTest::newRow(dataTag: "idn-prohibited-char-surrogate-1" ) << "http://" + QString(QChar(0xD800)) << "Invalid hostname (contains invalid characters)" ; |
| 2361 | QTest::newRow(dataTag: "idn-prohibited-char-surrogate-2" ) << "http://" + QString(QChar(0xDC00)) << "Invalid hostname (contains invalid characters)" ; |
| 2362 | QTest::newRow(dataTag: "idn-prohibited-char-surrogate-3" ) << "http://" + QString(QChar(0xD800)) + "a" << "Invalid hostname (contains invalid characters)" ; |
| 2363 | // FIXME: add some tests for prohibited BiDi (RFC 3454 section 6) |
| 2364 | |
| 2365 | // port errors happen in TolerantMode too |
| 2366 | QTest::newRow(dataTag: "invalid-port-1" ) << "http://example.com:-1" << "Invalid port" ; |
| 2367 | QTest::newRow(dataTag: "invalid-port-2" ) << "http://example.com:abc" << "Invalid port" ; |
| 2368 | QTest::newRow(dataTag: "invalid-port-3" ) << "http://example.com:9a" << "Invalid port" ; |
| 2369 | QTest::newRow(dataTag: "port-range" ) << "http://example.com:65536" << "out of range" ; |
| 2370 | |
| 2371 | QTest::newRow(dataTag: "invalid-path" ) << "foo:/path%\x1F" << "Invalid path (character '%' not permitted)" ; |
| 2372 | |
| 2373 | QTest::newRow(dataTag: "invalid-query" ) << "foo:?\\#" << "Invalid query (character '\\' not permitted)" ; |
| 2374 | |
| 2375 | QTest::newRow(dataTag: "invalid-fragment" ) << "#{}" << "Invalid fragment (character '{' not permitted)" ; |
| 2376 | } |
| 2377 | |
| 2378 | void tst_QUrl::strictParser() |
| 2379 | { |
| 2380 | QFETCH(QString, input); |
| 2381 | QFETCH(QString, needle); |
| 2382 | |
| 2383 | QUrl url(input, QUrl::StrictMode); |
| 2384 | QVERIFY(!url.isValid()); |
| 2385 | QVERIFY(url.toString().isEmpty()); |
| 2386 | QVERIFY(!url.errorString().isEmpty()); |
| 2387 | QVERIFY2(url.errorString().contains(input), |
| 2388 | "Error string does not contain the original input (\"" + |
| 2389 | input.toLatin1() + "\"): " + url.errorString().toLatin1()); |
| 2390 | |
| 2391 | // Note: if the following fails due to changes in the parser, simply update the test data |
| 2392 | QVERIFY2(url.errorString().contains(needle), |
| 2393 | "Error string changed and does not contain \"" + |
| 2394 | needle.toLatin1() + "\" anymore: " + url.errorString().toLatin1()); |
| 2395 | } |
| 2396 | |
| 2397 | void tst_QUrl::tolerantParser() |
| 2398 | { |
| 2399 | { |
| 2400 | QUrl url("http://www.example.com/path%20with spaces.html" ); |
| 2401 | QVERIFY(url.isValid()); |
| 2402 | QVERIFY(!url.toString().isEmpty()); |
| 2403 | QCOMPARE(url.path(), QString("/path with spaces.html" )); |
| 2404 | QCOMPARE(url.toEncoded(), QByteArray("http://www.example.com/path%20with%20spaces.html" )); |
| 2405 | QCOMPARE(url.toString(QUrl::FullyEncoded), QString("http://www.example.com/path%20with%20spaces.html" )); |
| 2406 | url.setUrl(url: "http://www.example.com/path%20with spaces.html" , mode: QUrl::StrictMode); |
| 2407 | QVERIFY(!url.isValid()); |
| 2408 | QVERIFY(url.toString().isEmpty()); |
| 2409 | } |
| 2410 | { |
| 2411 | QUrl url = QUrl::fromEncoded(url: "http://www.example.com/path%20with spaces.html" ); |
| 2412 | QVERIFY(url.isValid()); |
| 2413 | QVERIFY(!url.toString().isEmpty()); |
| 2414 | QCOMPARE(url.path(), QString("/path with spaces.html" )); |
| 2415 | url.setUrl(url: QLatin1String("http://www.example.com/path%20with spaces.html" ), mode: QUrl::StrictMode); |
| 2416 | QVERIFY(!url.isValid()); |
| 2417 | QVERIFY(url.toString().isEmpty()); |
| 2418 | } |
| 2419 | |
| 2420 | { |
| 2421 | QUrl url15581("http://alain.knaff.linux.lu/bug-reports/kde/percentage%in%url.htm>" ); |
| 2422 | QVERIFY(url15581.isValid()); |
| 2423 | QCOMPARE(url15581.toEncoded().constData(), "http://alain.knaff.linux.lu/bug-reports/kde/percentage%25in%25url.htm%3E" ); |
| 2424 | } |
| 2425 | |
| 2426 | { |
| 2427 | QUrl webkit22616 = |
| 2428 | QUrl::fromEncoded(url: "http://example.com/testya.php?browser-info=s:1400x1050x24:f:9.0%20r152:t:%u0442%u0435%u0441%u0442" ); |
| 2429 | QVERIFY(webkit22616.isValid()); |
| 2430 | |
| 2431 | // Qt 5 behaviour change: one broken % means all % are considered broken |
| 2432 | // QCOMPARE(webkit22616.toEncoded().constData(), |
| 2433 | // "http://example.com/testya.php?browser-info=s:1400x1050x24:f:9.0%20r152:t:%25u0442%25u0435%25u0441%25u0442"); |
| 2434 | QCOMPARE(webkit22616.toEncoded().constData(), |
| 2435 | "http://example.com/testya.php?browser-info=s:1400x1050x24:f:9.0%2520r152:t:%25u0442%25u0435%25u0441%25u0442" ); |
| 2436 | } |
| 2437 | |
| 2438 | { |
| 2439 | QUrl url; |
| 2440 | url.setUrl(url: "http://foo.bar/[image][1].jpg" ); |
| 2441 | QVERIFY(url.isValid()); |
| 2442 | QVERIFY(!url.toString().isEmpty()); |
| 2443 | QCOMPARE(url.toString(QUrl::FullyEncoded), QString("http://foo.bar/[image][1].jpg" )); |
| 2444 | QCOMPARE(url.toEncoded(), QByteArray("http://foo.bar/[image][1].jpg" )); |
| 2445 | QCOMPARE(url.toString(), QString("http://foo.bar/[image][1].jpg" )); |
| 2446 | |
| 2447 | url.setUrl(url: "http://foo.bar/%5Bimage%5D%5B1%5D.jpg" ); |
| 2448 | QVERIFY(url.isValid()); |
| 2449 | QVERIFY(!url.toString().isEmpty()); |
| 2450 | QCOMPARE(url.toString(QUrl::FullyEncoded), QString("http://foo.bar/%5Bimage%5D%5B1%5D.jpg" )); |
| 2451 | QCOMPARE(url.toEncoded(), QByteArray("http://foo.bar/%5Bimage%5D%5B1%5D.jpg" )); |
| 2452 | QCOMPARE(url.toString(), QString("http://foo.bar/%5Bimage%5D%5B1%5D.jpg" )); |
| 2453 | |
| 2454 | url.setUrl(url: "//[::56:56:56:56:56:56:56]" ); |
| 2455 | QCOMPARE(url.toString(QUrl::FullyEncoded), QString("//[0:56:56:56:56:56:56:56]" )); |
| 2456 | QCOMPARE(url.toEncoded(), QByteArray("//[0:56:56:56:56:56:56:56]" )); |
| 2457 | QCOMPARE(url.toString(), QString("//[0:56:56:56:56:56:56:56]" )); |
| 2458 | |
| 2459 | // invoke the tolerant parser's error correction |
| 2460 | url.setUrl(url: "%hello.com/f%" ); |
| 2461 | QCOMPARE(url.toString(QUrl::FullyEncoded), QString("%25hello.com/f%25" )); |
| 2462 | QCOMPARE(url.toEncoded(), QByteArray("%25hello.com/f%25" )); |
| 2463 | QCOMPARE(url.toString(), QString("%25hello.com/f%25" )); |
| 2464 | |
| 2465 | url.setUrl(url: QLatin1String("http://www.host.com/foo.php?P0=[2006-3-8]" ), mode: QUrl::StrictMode); |
| 2466 | QVERIFY(url.isValid()); |
| 2467 | QVERIFY(!url.toString().isEmpty()); |
| 2468 | |
| 2469 | url.setUrl(url: QLatin1String("http://foo.bar/[image][1].jpg" ), mode: QUrl::StrictMode); |
| 2470 | QVERIFY(url.isValid()); |
| 2471 | QCOMPARE(url.toString(QUrl::FullyEncoded), QString("http://foo.bar/[image][1].jpg" )); |
| 2472 | QCOMPARE(url.toEncoded(), QByteArray("http://foo.bar/[image][1].jpg" )); |
| 2473 | QCOMPARE(url.toString(), QString("http://foo.bar/[image][1].jpg" )); |
| 2474 | |
| 2475 | url.setUrl(url: QLatin1String("http://foo.bar/%5Bimage%5D%5B1%5D.jpg" ), mode: QUrl::StrictMode); |
| 2476 | QVERIFY(url.isValid()); |
| 2477 | QCOMPARE(url.toString(QUrl::FullyEncoded), QString("http://foo.bar/%5Bimage%5D%5B1%5D.jpg" )); |
| 2478 | QCOMPARE(url.toEncoded(), QByteArray("http://foo.bar/%5Bimage%5D%5B1%5D.jpg" )); |
| 2479 | QCOMPARE(url.toString(), QString("http://foo.bar/%5Bimage%5D%5B1%5D.jpg" )); |
| 2480 | |
| 2481 | url.setUrl(url: QLatin1String("//[::56:56:56:56:56:56:56]" ), mode: QUrl::StrictMode); |
| 2482 | QCOMPARE(url.toString(QUrl::FullyEncoded), QString("//[0:56:56:56:56:56:56:56]" )); |
| 2483 | QCOMPARE(url.toEncoded(), QByteArray("//[0:56:56:56:56:56:56:56]" )); |
| 2484 | |
| 2485 | url.setUrl(url: QLatin1String("data:text/css,div%20{%20border-right:%20solid;%20}" ), mode: QUrl::TolerantMode); |
| 2486 | QCOMPARE(url.toString(QUrl::FullyEncoded), QString("data:text/css,div%20%7B%20border-right:%20solid;%20%7D" )); |
| 2487 | QCOMPARE(url.toEncoded(), QByteArray("data:text/css,div%20%7B%20border-right:%20solid;%20%7D" )); |
| 2488 | QCOMPARE(url.toString(), QString("data:text/css,div %7B border-right: solid; %7D" )); |
| 2489 | } |
| 2490 | |
| 2491 | { |
| 2492 | const QString tsdgeos = QLatin1String("http://google.com/c?c=Translation+%C2%BB+trunk|" ); |
| 2493 | QUrl tsdgeosQUrl; |
| 2494 | tsdgeosQUrl.setUrl(url: tsdgeos, mode: QUrl::TolerantMode); |
| 2495 | QVERIFY(tsdgeosQUrl.isValid()); // failed in Qt-4.4, works in Qt-4.5 |
| 2496 | QByteArray tsdgeosExpected("http://google.com/c?c=Translation+%C2%BB+trunk%7C" ); |
| 2497 | QCOMPARE(QString(tsdgeosQUrl.toEncoded()), QString(tsdgeosExpected)); |
| 2498 | } |
| 2499 | |
| 2500 | { |
| 2501 | QUrl url; |
| 2502 | url.setUrl(url: "http://strange<username>@hostname/" , mode: QUrl::TolerantMode); |
| 2503 | QVERIFY(url.isValid()); |
| 2504 | QCOMPARE(QString(url.toEncoded()), QString("http://strange%3Cusername%3E@hostname/" )); |
| 2505 | } |
| 2506 | |
| 2507 | { |
| 2508 | QUrl url; |
| 2509 | url.setUrl(url: "http://en%63o%64%65%64.hostname/" , mode: QUrl::TolerantMode); |
| 2510 | QVERIFY(url.isValid()); |
| 2511 | QCOMPARE(url.toString(), QString("http://encoded.hostname/" )); |
| 2512 | } |
| 2513 | } |
| 2514 | |
| 2515 | void tst_QUrl::correctEncodedMistakes_data() |
| 2516 | { |
| 2517 | QTest::addColumn<QByteArray>(name: "encodedUrl" ); |
| 2518 | QTest::addColumn<bool>(name: "result" ); |
| 2519 | QTest::addColumn<QString>(name: "toDecoded" ); |
| 2520 | |
| 2521 | QTest::newRow(dataTag: "%" ) << QByteArray("%" ) << true << QString("%25" ); |
| 2522 | QTest::newRow(dataTag: "3%" ) << QByteArray("3%" ) << true << QString("3%25" ); |
| 2523 | QTest::newRow(dataTag: "13%" ) << QByteArray("13%" ) << true << QString("13%25" ); |
| 2524 | QTest::newRow(dataTag: "13%!" ) << QByteArray("13%!" ) << true << QString("13%25!" ); |
| 2525 | QTest::newRow(dataTag: "13%!!" ) << QByteArray("13%!!" ) << true << QString("13%25!!" ); |
| 2526 | QTest::newRow(dataTag: "13%a" ) << QByteArray("13%a" ) << true << QString("13%25a" ); |
| 2527 | QTest::newRow(dataTag: "13%az" ) << QByteArray("13%az" ) << true << QString("13%25az" ); |
| 2528 | QTest::newRow(dataTag: "13%25" ) << QByteArray("13%25" ) << true << QString("13%25" ); |
| 2529 | } |
| 2530 | |
| 2531 | void tst_QUrl::correctEncodedMistakes() |
| 2532 | { |
| 2533 | QFETCH(QByteArray, encodedUrl); |
| 2534 | QFETCH(bool, result); |
| 2535 | QFETCH(QString, toDecoded); |
| 2536 | |
| 2537 | QUrl url = QUrl::fromEncoded(url: encodedUrl); |
| 2538 | QCOMPARE(url.isValid(), result); |
| 2539 | if (url.isValid()) { |
| 2540 | QCOMPARE(url.toString(), toDecoded); |
| 2541 | } else { |
| 2542 | QVERIFY(url.toString().isEmpty()); |
| 2543 | } |
| 2544 | } |
| 2545 | |
| 2546 | void tst_QUrl::correctDecodedMistakes_data() |
| 2547 | { |
| 2548 | QTest::addColumn<QString>(name: "decodedUrl" ); |
| 2549 | QTest::addColumn<bool>(name: "result" ); |
| 2550 | QTest::addColumn<QString>(name: "toDecoded" ); |
| 2551 | |
| 2552 | QTest::newRow(dataTag: "%" ) << QString("%" ) << true << QString("%25" ); |
| 2553 | QTest::newRow(dataTag: "3%" ) << QString("3%" ) << true << QString("3%25" ); |
| 2554 | QTest::newRow(dataTag: "13%" ) << QString("13%" ) << true << QString("13%25" ); |
| 2555 | QTest::newRow(dataTag: "13%!" ) << QString("13%!" ) << true << QString("13%25!" ); |
| 2556 | QTest::newRow(dataTag: "13%!!" ) << QString("13%!!" ) << true << QString("13%25!!" ); |
| 2557 | QTest::newRow(dataTag: "13%a" ) << QString("13%a" ) << true << QString("13%25a" ); |
| 2558 | QTest::newRow(dataTag: "13%az" ) << QString("13%az" ) << true << QString("13%25az" ); |
| 2559 | } |
| 2560 | |
| 2561 | void tst_QUrl::correctDecodedMistakes() |
| 2562 | { |
| 2563 | QFETCH(QString, decodedUrl); |
| 2564 | QFETCH(bool, result); |
| 2565 | QFETCH(QString, toDecoded); |
| 2566 | |
| 2567 | QUrl url(decodedUrl); |
| 2568 | QCOMPARE(url.isValid(), result); |
| 2569 | if (url.isValid()) { |
| 2570 | QCOMPARE(url.toString(), toDecoded); |
| 2571 | } else { |
| 2572 | QVERIFY(url.toString().isEmpty()); |
| 2573 | } |
| 2574 | } |
| 2575 | |
| 2576 | void tst_QUrl::tldRestrictions_data() |
| 2577 | { |
| 2578 | QTest::addColumn<QString>(name: "tld" ); |
| 2579 | QTest::addColumn<bool>(name: "encode" ); |
| 2580 | |
| 2581 | // current whitelist |
| 2582 | QTest::newRow(dataTag: "ac" ) << QString("ac" ) << true; |
| 2583 | QTest::newRow(dataTag: "ar" ) << QString("ar" ) << true; |
| 2584 | QTest::newRow(dataTag: "asia" ) << QString("asia" ) << true; |
| 2585 | QTest::newRow(dataTag: "at" ) << QString("at" ) << true; |
| 2586 | QTest::newRow(dataTag: "biz" ) << QString("biz" ) << true; |
| 2587 | QTest::newRow(dataTag: "br" ) << QString("br" ) << true; |
| 2588 | QTest::newRow(dataTag: "cat" ) << QString("cat" ) << true; |
| 2589 | QTest::newRow(dataTag: "ch" ) << QString("ch" ) << true; |
| 2590 | QTest::newRow(dataTag: "cl" ) << QString("cl" ) << true; |
| 2591 | QTest::newRow(dataTag: "cn" ) << QString("cn" ) << true; |
| 2592 | QTest::newRow(dataTag: "com" ) << QString("com" ) << true; |
| 2593 | QTest::newRow(dataTag: "de" ) << QString("de" ) << true; |
| 2594 | QTest::newRow(dataTag: "dk" ) << QString("dk" ) << true; |
| 2595 | QTest::newRow(dataTag: "es" ) << QString("es" ) << true; |
| 2596 | QTest::newRow(dataTag: "fi" ) << QString("fi" ) << true; |
| 2597 | QTest::newRow(dataTag: "gr" ) << QString("gr" ) << true; |
| 2598 | QTest::newRow(dataTag: "hu" ) << QString("hu" ) << true; |
| 2599 | QTest::newRow(dataTag: "il" ) << QString("il" ) << true; |
| 2600 | QTest::newRow(dataTag: "info" ) << QString("info" ) << true; |
| 2601 | QTest::newRow(dataTag: "io" ) << QString("io" ) << true; |
| 2602 | QTest::newRow(dataTag: "is" ) << QString("is" ) << true; |
| 2603 | QTest::newRow(dataTag: "ir" ) << QString("ir" ) << true; |
| 2604 | QTest::newRow(dataTag: "jp" ) << QString("jp" ) << true; |
| 2605 | QTest::newRow(dataTag: "kr" ) << QString("kr" ) << true; |
| 2606 | QTest::newRow(dataTag: "li" ) << QString("li" ) << true; |
| 2607 | QTest::newRow(dataTag: "lt" ) << QString("lt" ) << true; |
| 2608 | QTest::newRow(dataTag: "lu" ) << QString("lu" ) << true; |
| 2609 | QTest::newRow(dataTag: "lv" ) << QString("lv" ) << true; |
| 2610 | QTest::newRow(dataTag: "museum" ) << QString("museum" ) << true; |
| 2611 | QTest::newRow(dataTag: "name" ) << QString("name" ) << true; |
| 2612 | QTest::newRow(dataTag: "net" ) << QString("name" ) << true; |
| 2613 | QTest::newRow(dataTag: "no" ) << QString("no" ) << true; |
| 2614 | QTest::newRow(dataTag: "nu" ) << QString("nu" ) << true; |
| 2615 | QTest::newRow(dataTag: "nz" ) << QString("nz" ) << true; |
| 2616 | QTest::newRow(dataTag: "org" ) << QString("org" ) << true; |
| 2617 | QTest::newRow(dataTag: "pl" ) << QString("pl" ) << true; |
| 2618 | QTest::newRow(dataTag: "pr" ) << QString("pr" ) << true; |
| 2619 | QTest::newRow(dataTag: "se" ) << QString("se" ) << true; |
| 2620 | QTest::newRow(dataTag: "sh" ) << QString("sh" ) << true; |
| 2621 | QTest::newRow(dataTag: "tel" ) << QString("tel" ) << true; |
| 2622 | QTest::newRow(dataTag: "th" ) << QString("th" ) << true; |
| 2623 | QTest::newRow(dataTag: "tm" ) << QString("tm" ) << true; |
| 2624 | QTest::newRow(dataTag: "tw" ) << QString("tw" ) << true; |
| 2625 | QTest::newRow(dataTag: "ua" ) << QString("ua" ) << true; |
| 2626 | QTest::newRow(dataTag: "vn" ) << QString("vn" ) << true; |
| 2627 | |
| 2628 | // known blacklists: |
| 2629 | QTest::newRow(dataTag: "foo" ) << QString("foo" ) << false; |
| 2630 | } |
| 2631 | |
| 2632 | void tst_QUrl::tldRestrictions() |
| 2633 | { |
| 2634 | QFETCH(QString, tld); |
| 2635 | |
| 2636 | // www.brød.tld |
| 2637 | QByteArray ascii = "www.xn--brd-1na." + tld.toLatin1(); |
| 2638 | QString unicode = QLatin1String("www.br\370d." ) + tld; |
| 2639 | QString encoded = QUrl::fromAce(ascii); |
| 2640 | QTEST(!encoded.contains(".xn--" ), "encode" ); |
| 2641 | QTEST(encoded == unicode, "encode" ); |
| 2642 | |
| 2643 | QUrl url = QUrl::fromEncoded(url: "http://www.xn--brd-1na." + tld.toLatin1()); |
| 2644 | QTEST(!url.host().contains(".xn--" ), "encode" ); |
| 2645 | QTEST(url.host() == unicode, "encode" ); |
| 2646 | |
| 2647 | url.setUrl(url: QLatin1String("http://www.xn--brd-1na." ) + tld); |
| 2648 | QTEST(!url.host().contains(".xn--" ), "encode" ); |
| 2649 | QTEST(url.host() == unicode, "encode" ); |
| 2650 | |
| 2651 | url.setUrl(url: QLatin1String("http://www.br\370d." ) + tld); |
| 2652 | QTEST(!url.host().contains(".xn--" ), "encode" ); |
| 2653 | QTEST(url.host() == unicode, "encode" ); |
| 2654 | |
| 2655 | url = QUrl::fromEncoded(url: "http://www.br%C3%B8d." + tld.toLatin1()); |
| 2656 | QTEST(!url.host().contains(".xn--" ), "encode" ); |
| 2657 | QTEST(url.host() == unicode, "encode" ); |
| 2658 | } |
| 2659 | |
| 2660 | void tst_QUrl::emptyQueryOrFragment() |
| 2661 | { |
| 2662 | QUrl qurl = QUrl::fromEncoded(url: "http://www.kde.org/cgi/test.cgi?" , mode: QUrl::TolerantMode); |
| 2663 | QCOMPARE(qurl.toEncoded().constData(), "http://www.kde.org/cgi/test.cgi?" ); // Empty refs should be preserved |
| 2664 | QCOMPARE(qurl.toString(), QString("http://www.kde.org/cgi/test.cgi?" )); |
| 2665 | qurl = QUrl::fromEncoded(url: "http://www.kde.org/cgi/test.cgi#" , mode: QUrl::TolerantMode); |
| 2666 | QCOMPARE(qurl.toEncoded().constData(), "http://www.kde.org/cgi/test.cgi#" ); |
| 2667 | QCOMPARE(qurl.toString(), QString("http://www.kde.org/cgi/test.cgi#" )); |
| 2668 | |
| 2669 | { |
| 2670 | // start with an empty one |
| 2671 | QUrl url("http://www.foo.bar/baz" ); |
| 2672 | QVERIFY(!url.hasFragment()); |
| 2673 | QVERIFY(url.fragment().isNull()); |
| 2674 | |
| 2675 | // add fragment |
| 2676 | url.setFragment(fragment: QLatin1String("abc" )); |
| 2677 | QVERIFY(url.hasFragment()); |
| 2678 | QCOMPARE(url.fragment(), QString(QLatin1String("abc" ))); |
| 2679 | QCOMPARE(url.toString(), QString(QLatin1String("http://www.foo.bar/baz#abc" ))); |
| 2680 | |
| 2681 | // remove fragment |
| 2682 | url.setFragment(fragment: QString()); |
| 2683 | QVERIFY(!url.hasFragment()); |
| 2684 | QVERIFY(url.fragment().isNull()); |
| 2685 | QCOMPARE(url.toString(), QString(QLatin1String("http://www.foo.bar/baz" ))); |
| 2686 | |
| 2687 | // add empty fragment |
| 2688 | url.setFragment(fragment: QLatin1String("" )); |
| 2689 | QVERIFY(url.hasFragment()); |
| 2690 | QVERIFY(url.fragment().isEmpty()); |
| 2691 | QVERIFY(!url.fragment().isNull()); |
| 2692 | QCOMPARE(url.toString(), QString(QLatin1String("http://www.foo.bar/baz#" ))); |
| 2693 | } |
| 2694 | |
| 2695 | { |
| 2696 | // start with an empty one |
| 2697 | QUrl url("http://www.foo.bar/baz" ); |
| 2698 | QVERIFY(!url.hasQuery()); |
| 2699 | QVERIFY(url.query().isNull()); |
| 2700 | |
| 2701 | // add encodedQuery |
| 2702 | url.setQuery(query: "abc=def" ); |
| 2703 | QVERIFY(url.hasQuery()); |
| 2704 | QCOMPARE(url.query(), QString(QLatin1String("abc=def" ))); |
| 2705 | QCOMPARE(url.toString(), QString(QLatin1String("http://www.foo.bar/baz?abc=def" ))); |
| 2706 | url.setQuery(query: QLatin1String("abc=def" )); |
| 2707 | QCOMPARE(url.toString(), QString(QLatin1String("http://www.foo.bar/baz?abc=def" ))); |
| 2708 | |
| 2709 | // remove encodedQuery |
| 2710 | url.setQuery(query: QString()); |
| 2711 | QVERIFY(!url.hasQuery()); |
| 2712 | QVERIFY(url.query().isNull()); |
| 2713 | QCOMPARE(url.toString(), QString(QLatin1String("http://www.foo.bar/baz" ))); |
| 2714 | url.setQuery(query: QString()); |
| 2715 | QCOMPARE(url.toString(), QString(QLatin1String("http://www.foo.bar/baz" ))); |
| 2716 | |
| 2717 | // add empty encodedQuery |
| 2718 | url.setQuery(query: "" ); |
| 2719 | QVERIFY(url.hasQuery()); |
| 2720 | QVERIFY(url.query().isEmpty()); |
| 2721 | QVERIFY(!url.query().isNull()); |
| 2722 | QCOMPARE(url.toString(), QString(QLatin1String("http://www.foo.bar/baz?" ))); |
| 2723 | url.setQuery(query: QLatin1String("" )); |
| 2724 | QCOMPARE(url.toString(), QString(QLatin1String("http://www.foo.bar/baz?" ))); |
| 2725 | } |
| 2726 | } |
| 2727 | |
| 2728 | void tst_QUrl::hasFragment_data() |
| 2729 | { |
| 2730 | QTest::addColumn<QString>(name: "url" ); |
| 2731 | QTest::addColumn<bool>(name: "trueFalse" ); |
| 2732 | |
| 2733 | QTest::newRow(dataTag: "no fragment" ) << "http://www.foo.bar" << false; |
| 2734 | |
| 2735 | QTest::newRow(dataTag: "empty fragment" ) << "http://www.foo.bar#" << true; |
| 2736 | QTest::newRow(dataTag: "empty fragment 2" ) << "http://www.foo.bar/#" << true; |
| 2737 | |
| 2738 | QTest::newRow(dataTag: "fragment" ) << "http://www.foo.bar#baz" << true; |
| 2739 | QTest::newRow(dataTag: "fragment2" ) << "http://www.foo.bar/#baz" << true; |
| 2740 | |
| 2741 | QTest::newRow(dataTag: "%23" ) << "http://www.foo.bar/%23" << false; |
| 2742 | QTest::newRow(dataTag: "%23-and-something" ) << "http://www.foo.bar/%23baz" << false; |
| 2743 | } |
| 2744 | |
| 2745 | void tst_QUrl::hasFragment() |
| 2746 | { |
| 2747 | QFETCH(QString, url); |
| 2748 | QFETCH(bool, trueFalse); |
| 2749 | |
| 2750 | QUrl qurl(url); |
| 2751 | QCOMPARE(qurl.hasFragment(), trueFalse); |
| 2752 | QCOMPARE(qurl.fragment().isNull(), !trueFalse); |
| 2753 | } |
| 2754 | |
| 2755 | void tst_QUrl::setFragment_data() |
| 2756 | { |
| 2757 | QTest::addColumn<QString>(name: "base" ); |
| 2758 | QTest::addColumn<QString>(name: "fragment" ); |
| 2759 | QTest::addColumn<QString>(name: "expected" ); |
| 2760 | |
| 2761 | QTest::newRow(dataTag: "null" ) << QString::fromLatin1(str: "http://www.kde.org" ) << QString() << QString::fromLatin1(str: "http://www.kde.org" ); |
| 2762 | QTest::newRow(dataTag: "empty" ) << QString::fromLatin1(str: "http://www.kde.org" ) << QString::fromLatin1(str: "" ) << QString::fromLatin1(str: "http://www.kde.org#" ); |
| 2763 | QTest::newRow(dataTag: "basic test" ) << QString::fromLatin1(str: "http://www.kde.org" ) << QString::fromLatin1(str: "abc" ) << QString::fromLatin1(str: "http://www.kde.org#abc" ); |
| 2764 | QTest::newRow(dataTag: "initial url has fragment" ) << QString::fromLatin1(str: "http://www.kde.org#old" ) << QString::fromLatin1(str: "new" ) << QString::fromLatin1(str: "http://www.kde.org#new" ); |
| 2765 | QTest::newRow(dataTag: "encoded fragment" ) << QString::fromLatin1(str: "http://www.kde.org" ) << QString::fromLatin1(str: "a%20c" ) << QString::fromLatin1(str: "http://www.kde.org#a%20c" ); |
| 2766 | QTest::newRow(dataTag: "with #" ) << QString::fromLatin1(str: "http://www.kde.org" ) << QString::fromLatin1(str: "a#b" ) << QString::fromLatin1(str: "http://www.kde.org#a%23b" ); // toString uses "a#b" |
| 2767 | QTest::newRow(dataTag: "unicode" ) << QString::fromLatin1(str: "http://www.kde.org" ) << QString::fromUtf8(str: "\xc3\xa9" ) << QString::fromLatin1(str: "http://www.kde.org#%C3%A9" ); |
| 2768 | } |
| 2769 | |
| 2770 | void tst_QUrl::setFragment() |
| 2771 | { |
| 2772 | QFETCH(QString, base); |
| 2773 | QFETCH(QString, fragment); |
| 2774 | QFETCH(QString, expected); |
| 2775 | QUrl u; |
| 2776 | u.setUrl(url: base, mode: QUrl::TolerantMode); |
| 2777 | QVERIFY(u.isValid()); |
| 2778 | u.setFragment(fragment); |
| 2779 | QVERIFY(u.isValid()); |
| 2780 | QCOMPARE(!fragment.isNull(), u.hasFragment()); |
| 2781 | QCOMPARE(QString::fromUtf8(u.toEncoded()), expected); |
| 2782 | } |
| 2783 | |
| 2784 | void tst_QUrl::fromEncoded() |
| 2785 | { |
| 2786 | QUrl qurl2 = QUrl::fromEncoded(url: "print:/specials/Print%20To%20File%20(PDF%252FAcrobat)" , mode: QUrl::TolerantMode); |
| 2787 | QCOMPARE(qurl2.path(), QString::fromLatin1("/specials/Print To File (PDF%2FAcrobat)" )); |
| 2788 | QCOMPARE(QFileInfo(qurl2.path()).fileName(), QString::fromLatin1("Print To File (PDF%2FAcrobat)" )); |
| 2789 | QCOMPARE(qurl2.fileName(), QString::fromLatin1("Print To File (PDF%2FAcrobat)" )); |
| 2790 | QCOMPARE(qurl2.toEncoded().constData(), "print:/specials/Print%20To%20File%20(PDF%252FAcrobat)" ); |
| 2791 | |
| 2792 | QUrl qurl = QUrl::fromEncoded(url: "http://\303\244.de" ); |
| 2793 | QVERIFY(qurl.isValid()); |
| 2794 | QCOMPARE(qurl.toEncoded().constData(), "http://xn--4ca.de" ); |
| 2795 | |
| 2796 | QUrl qurltest(QUrl::fromPercentEncoding("http://\303\244.de" )); |
| 2797 | QVERIFY(qurltest.isValid()); |
| 2798 | |
| 2799 | QUrl qurl_newline_1 = QUrl::fromEncoded(url: "http://www.foo.bar/foo/bar\ngnork" , mode: QUrl::TolerantMode); |
| 2800 | QVERIFY(qurl_newline_1.isValid()); |
| 2801 | QCOMPARE(qurl_newline_1.toEncoded().constData(), "http://www.foo.bar/foo/bar%0Agnork" ); |
| 2802 | } |
| 2803 | |
| 2804 | void tst_QUrl::stripTrailingSlash_data() |
| 2805 | { |
| 2806 | QTest::addColumn<QString>(name: "url" ); |
| 2807 | QTest::addColumn<QString>(name: "expectedStrip" ); // toString(Strip) |
| 2808 | QTest::addColumn<QString>(name: "expectedDir" ); // toString(RemoveFilename) |
| 2809 | QTest::addColumn<QString>(name: "expectedDirStrip" ); // toString(RemoveFilename|Strip) |
| 2810 | |
| 2811 | QTest::newRow(dataTag: "subdir no slash" ) << "ftp://kde.org/dir/subdir" << "ftp://kde.org/dir/subdir" << "ftp://kde.org/dir/" << "ftp://kde.org/dir" ; |
| 2812 | QTest::newRow(dataTag: "ftp no slash" ) << "ftp://kde.org/dir" << "ftp://kde.org/dir" << "ftp://kde.org/" << "ftp://kde.org/" ; |
| 2813 | QTest::newRow(dataTag: "ftp slash" ) << "ftp://kde.org/dir/" << "ftp://kde.org/dir" << "ftp://kde.org/dir/" << "ftp://kde.org/dir" ; |
| 2814 | QTest::newRow(dataTag: "ftp_two_slashes" ) << "ftp://kde.org/dir//" << "ftp://kde.org/dir" << "ftp://kde.org/dir//" << "ftp://kde.org/dir" ; |
| 2815 | QTest::newRow(dataTag: "file slash" ) << "file:///dir/" << "file:///dir" << "file:///dir/" << "file:///dir" ; |
| 2816 | QTest::newRow(dataTag: "file no slash" ) << "file:///dir" << "file:///dir" << "file:///" << "file:///" ; |
| 2817 | QTest::newRow(dataTag: "file root" ) << "file:///" << "file:///" << "file:///" << "file:///" ; |
| 2818 | QTest::newRow(dataTag: "file_root_manyslashes" ) << "file://///" << "file:///" << "file://///" << "file:///" ; |
| 2819 | QTest::newRow(dataTag: "no path" ) << "remote://" << "remote://" << "remote://" << "remote://" ; |
| 2820 | } |
| 2821 | |
| 2822 | void tst_QUrl::stripTrailingSlash() |
| 2823 | { |
| 2824 | QFETCH(QString, url); |
| 2825 | QFETCH(QString, expectedStrip); |
| 2826 | QFETCH(QString, expectedDir); |
| 2827 | QFETCH(QString, expectedDirStrip); |
| 2828 | |
| 2829 | QUrl u(url); |
| 2830 | QCOMPARE(u.toString(QUrl::StripTrailingSlash), expectedStrip); |
| 2831 | QCOMPARE(u.toString(QUrl::RemoveFilename), expectedDir); |
| 2832 | QCOMPARE(u.toString(QUrl::RemoveFilename | QUrl::StripTrailingSlash), expectedDirStrip); |
| 2833 | |
| 2834 | // Same thing, using QUrl::adjusted() |
| 2835 | QCOMPARE(u.adjusted(QUrl::StripTrailingSlash).toString(), expectedStrip); |
| 2836 | QCOMPARE(u.adjusted(QUrl::RemoveFilename).toString(), expectedDir); |
| 2837 | QCOMPARE(u.adjusted(QUrl::RemoveFilename | QUrl::StripTrailingSlash).toString(), expectedDirStrip); |
| 2838 | } |
| 2839 | |
| 2840 | void tst_QUrl::hosts_data() |
| 2841 | { |
| 2842 | QTest::addColumn<QString>(name: "url" ); |
| 2843 | QTest::addColumn<QString>(name: "host" ); |
| 2844 | |
| 2845 | QTest::newRow(dataTag: "empty" ) << QString("" ) << QString("" ); |
| 2846 | QTest::newRow(dataTag: "empty1" ) << QString("file:///file" ) << QString("" ); |
| 2847 | QTest::newRow(dataTag: "empty2" ) << QString("file:/file" ) << QString("" ); |
| 2848 | QTest::newRow(dataTag: "empty3" ) << QString("http:///file" ) << QString("" ); |
| 2849 | QTest::newRow(dataTag: "empty4" ) << QString("http:/file" ) << QString("" ); |
| 2850 | |
| 2851 | // numeric hostnames -> decoded as IPv4 as per inet_aton(3) |
| 2852 | QTest::newRow(dataTag: "http://123/" ) << QString("http://123/" ) << QString("0.0.0.123" ); |
| 2853 | QTest::newRow(dataTag: "http://456/" ) << QString("http://456/" ) << QString("0.0.1.200" ); |
| 2854 | QTest::newRow(dataTag: "http://1000/" ) << QString("http://1000/" ) << QString("0.0.3.232" ); |
| 2855 | |
| 2856 | // IP literals |
| 2857 | QTest::newRow(dataTag: "normal-ip-literal" ) << QString("http://1.2.3.4" ) << QString("1.2.3.4" ); |
| 2858 | QTest::newRow(dataTag: "normal-ip-literal-with-port" ) << QString("http://1.2.3.4:80" ) |
| 2859 | << QString("1.2.3.4" ); |
| 2860 | QTest::newRow(dataTag: "ipv6-literal" ) << QString("http://[::1]" ) << QString("::1" ); |
| 2861 | QTest::newRow(dataTag: "ipv6-literal-with-port" ) << QString("http://[::1]:80" ) << QString("::1" ); |
| 2862 | QTest::newRow(dataTag: "long-ipv6-literal" ) << QString("http://[2001:200:0:8002:203:47ff:fea5:3085]" ) |
| 2863 | << QString("2001:200:0:8002:203:47ff:fea5:3085" ); |
| 2864 | QTest::newRow(dataTag: "long-ipv6-literal-with-port" ) << QString("http://[2001:200:0:8002:203:47ff:fea5:3085]:80" ) |
| 2865 | << QString("2001:200:0:8002:203:47ff:fea5:3085" ); |
| 2866 | QTest::newRow(dataTag: "ipv6-literal-v4compat" ) << QString("http://[::255.254.253.252]" ) |
| 2867 | << QString("::255.254.253.252" ); |
| 2868 | QTest::newRow(dataTag: "ipv6-literal-v4mapped" ) << QString("http://[::ffff:255.254.253.252]" ) |
| 2869 | << QString("::ffff:255.254.253.252" ); |
| 2870 | QTest::newRow(dataTag: "ipv6-literal-v4mapped-2" ) << QString("http://[::ffff:fffe:fdfc]" ) |
| 2871 | << QString("::ffff:255.254.253.252" ); |
| 2872 | |
| 2873 | // no embedded v4 unless the cases above |
| 2874 | QTest::newRow(dataTag: "ipv6-literal-v4decoded" ) << QString("http://[1000::ffff:127.128.129.1]" ) |
| 2875 | << QString("1000::ffff:7f80:8101" ); |
| 2876 | QTest::newRow(dataTag: "long-ipv6-literal-v4decoded" ) << QString("http://[fec0:8000::8002:1000:ffff:200.100.50.250]" ) |
| 2877 | << QString("fec0:8000:0:8002:1000:ffff:c864:32fa" ); |
| 2878 | QTest::newRow(dataTag: "longer-ipv6-literal-v4decoded" ) << QString("http://[fec0:8000:4000:8002:1000:ffff:200.100.50.250]" ) |
| 2879 | << QString("fec0:8000:4000:8002:1000:ffff:c864:32fa" ); |
| 2880 | |
| 2881 | // normal hostnames |
| 2882 | QTest::newRow(dataTag: "normal" ) << QString("http://intern" ) << QString("intern" ); |
| 2883 | QTest::newRow(dataTag: "normal2" ) << QString("http://qt-project.org" ) << QString("qt-project.org" ); |
| 2884 | |
| 2885 | // IDN hostnames |
| 2886 | QTest::newRow(dataTag: "idn" ) << QString(QLatin1String("http://\345r.no" )) << QString(QLatin1String("\345r.no" )); |
| 2887 | QTest::newRow(dataTag: "idn-ace" ) << QString("http://xn--r-1fa.no" ) << QString(QLatin1String("\345r.no" )); |
| 2888 | } |
| 2889 | |
| 2890 | void tst_QUrl::hosts() |
| 2891 | { |
| 2892 | QFETCH(QString, url); |
| 2893 | |
| 2894 | QUrl u(url); |
| 2895 | QTEST(u.host(), "host" ); |
| 2896 | QVERIFY(u.isEmpty() || u.isValid()); |
| 2897 | } |
| 2898 | |
| 2899 | void tst_QUrl::hostFlags_data() |
| 2900 | { |
| 2901 | QTest::addColumn<QString>(name: "urlStr" ); |
| 2902 | QTest::addColumn<QUrl::FormattingOptions>(name: "options" ); |
| 2903 | QTest::addColumn<QString>(name: "expectedHost" ); |
| 2904 | |
| 2905 | QString swedish = QString::fromUtf8(str: "http://www.räksmörgås.se/pub?a=b&a=dø&a=f#vræl" ); |
| 2906 | QTest::newRow(dataTag: "se_fullydecoded" ) << swedish << QUrl::FormattingOptions(QUrl::FullyDecoded) << QString::fromUtf8(str: "www.räksmörgås.se" ); |
| 2907 | QTest::newRow(dataTag: "se_fullyencoded" ) << swedish << QUrl::FormattingOptions(QUrl::FullyEncoded) << QString::fromUtf8(str: "www.xn--rksmrgs-5wao1o.se" ); |
| 2908 | QTest::newRow(dataTag: "se_prettydecoded" ) << swedish << QUrl::FormattingOptions(QUrl::PrettyDecoded) << QString::fromUtf8(str: "www.räksmörgås.se" ); |
| 2909 | QTest::newRow(dataTag: "se_encodespaces" ) << swedish << QUrl::FormattingOptions(QUrl::EncodeSpaces) << QString::fromUtf8(str: "www.räksmörgås.se" ); |
| 2910 | } |
| 2911 | |
| 2912 | void tst_QUrl::hostFlags() |
| 2913 | { |
| 2914 | QFETCH(QString, urlStr); |
| 2915 | QFETCH(QUrl::FormattingOptions, options); |
| 2916 | QFETCH(QString, expectedHost); |
| 2917 | |
| 2918 | QUrl url(urlStr); |
| 2919 | QCOMPARE(url.host(options), expectedHost); |
| 2920 | } |
| 2921 | |
| 2922 | void tst_QUrl::setPort() |
| 2923 | { |
| 2924 | { |
| 2925 | QUrl url; |
| 2926 | QVERIFY(url.toString().isEmpty()); |
| 2927 | url.setHost(host: "a" ); |
| 2928 | url.setPort(80); |
| 2929 | QCOMPARE(url.port(), 80); |
| 2930 | QCOMPARE(url.toString(), QString::fromLatin1("//a:80" )); |
| 2931 | url.setPort(-1); |
| 2932 | url.setHost(host: QString()); |
| 2933 | QCOMPARE(url.port(), -1); |
| 2934 | QCOMPARE(url.toString(), QString()); |
| 2935 | url.setPort(80); |
| 2936 | url.setPort(65536); |
| 2937 | QCOMPARE(url.port(), -1); |
| 2938 | QVERIFY(url.errorString().contains("out of range" )); |
| 2939 | } |
| 2940 | |
| 2941 | { |
| 2942 | QUrl reference("//:80" ); |
| 2943 | QUrl piecewise; |
| 2944 | piecewise.setPort(80); |
| 2945 | QCOMPARE(piecewise, reference); |
| 2946 | } |
| 2947 | |
| 2948 | { |
| 2949 | // setAuthority must clear the port |
| 2950 | QUrl url("http://example.com:80" ); |
| 2951 | url.setAuthority(authority: "example.org" ); |
| 2952 | QCOMPARE(url.port(), -1); |
| 2953 | QCOMPARE(url.toString(), QString("http://example.org" )); |
| 2954 | } |
| 2955 | |
| 2956 | { |
| 2957 | // setAuthority must clear the port |
| 2958 | QUrl url("http://example.com:80" ); |
| 2959 | url.setAuthority(authority: QString()); |
| 2960 | QCOMPARE(url.port(), -1); |
| 2961 | QCOMPARE(url.toString(), QString("http:" )); |
| 2962 | } |
| 2963 | } |
| 2964 | |
| 2965 | void tst_QUrl::port_data() |
| 2966 | { |
| 2967 | QTest::addColumn<QString>(name: "input" ); |
| 2968 | QTest::addColumn<int>(name: "port" ); |
| 2969 | |
| 2970 | QTest::newRow(dataTag: "no-port-1" ) << "http://example.com" << -1; |
| 2971 | QTest::newRow(dataTag: "no-port-2" ) << "http://example.com/" << -1; |
| 2972 | QTest::newRow(dataTag: "empty-port-1" ) << "http://example.com:" << -1; |
| 2973 | QTest::newRow(dataTag: "empty-port-2" ) << "http://example.com:/" << -1; |
| 2974 | QTest::newRow(dataTag: "zero-port-1" ) << "http://example.com:0" << 0; |
| 2975 | QTest::newRow(dataTag: "zero-port-2" ) << "http://example.com:0/" << 0; |
| 2976 | QTest::newRow(dataTag: "set-port-1" ) << "http://example.com:80" << 80; |
| 2977 | QTest::newRow(dataTag: "set-port-2" ) << "http://example.com:80/" << 80; |
| 2978 | } |
| 2979 | |
| 2980 | void tst_QUrl::port() |
| 2981 | { |
| 2982 | QFETCH(QString, input); |
| 2983 | QFETCH(int, port); |
| 2984 | |
| 2985 | QUrl url(input); |
| 2986 | QVERIFY(url.isValid()); |
| 2987 | QCOMPARE(url.port(), port); |
| 2988 | } |
| 2989 | |
| 2990 | void tst_QUrl::toEncoded_data() |
| 2991 | { |
| 2992 | QTest::addColumn<QByteArray>(name: "url" ); |
| 2993 | QTest::addColumn<QUrl::FormattingOptions>(name: "options" ); |
| 2994 | QTest::addColumn<QByteArray>(name: "encoded" ); |
| 2995 | QTest::newRow(dataTag: "file:///dir/" ) << QByteArray("file:///dir/" ) |
| 2996 | << QUrl::FormattingOptions(QUrl::StripTrailingSlash) |
| 2997 | << QByteArray("file:///dir" ); |
| 2998 | } |
| 2999 | |
| 3000 | void tst_QUrl::toEncoded() |
| 3001 | { |
| 3002 | QFETCH(QByteArray, url); |
| 3003 | QFETCH(QUrl::FormattingOptions, options); |
| 3004 | QFETCH(QByteArray, encoded); |
| 3005 | |
| 3006 | QCOMPARE(QUrl::fromEncoded(url).toEncoded(options), encoded); |
| 3007 | } |
| 3008 | |
| 3009 | void tst_QUrl::setAuthority_data() |
| 3010 | { |
| 3011 | QTest::addColumn<QString>(name: "authority" ); |
| 3012 | QTest::addColumn<QString>(name: "url" ); |
| 3013 | QTest::newRow(dataTag: "Plain auth" ) << QString("62.70.27.22:21" ) << QString("//62.70.27.22:21" ); |
| 3014 | QTest::newRow(dataTag: "Yet another plain auth" ) << QString("192.168.1.1:21" ) << QString("//192.168.1.1:21" ); |
| 3015 | QTest::newRow(dataTag: "Auth without port" ) << QString("192.168.1.1" ) << QString("//192.168.1.1" ); |
| 3016 | QTest::newRow(dataTag: "Auth w/full hostname without port" ) << QString("shusaku.troll.no" ) << QString("//shusaku.troll.no" ); |
| 3017 | QTest::newRow(dataTag: "Auth w/hostname without port" ) << QString("shusaku" ) << QString("//shusaku" ); |
| 3018 | QTest::newRow(dataTag: "Auth w/full hostname that ends with number, without port" ) << QString("shusaku.troll.no.2" ) << QString("//shusaku.troll.no.2" ); |
| 3019 | QTest::newRow(dataTag: "Auth w/hostname that ends with number, without port" ) << QString("shusaku2" ) << QString("//shusaku2" ); |
| 3020 | QTest::newRow(dataTag: "Empty auth" ) << QString() << QString(); |
| 3021 | } |
| 3022 | |
| 3023 | void tst_QUrl::setAuthority() |
| 3024 | { |
| 3025 | QUrl u; |
| 3026 | QFETCH(QString, authority); |
| 3027 | QFETCH(QString, url); |
| 3028 | u.setAuthority(authority); |
| 3029 | QCOMPARE(u.toString(), url); |
| 3030 | } |
| 3031 | |
| 3032 | void tst_QUrl::setEmptyAuthority_data() |
| 3033 | { |
| 3034 | QTest::addColumn<QString>(name: "host" ); |
| 3035 | QTest::addColumn<QString>(name: "authority" ); |
| 3036 | QTest::addColumn<QString>(name: "expectedUrlString" ); |
| 3037 | |
| 3038 | QTest::newRow(dataTag: "null host and authority" ) << QString() << QString() << QString("" ); |
| 3039 | QTest::newRow(dataTag: "empty host and authority" ) << QString("" ) << QString("" ) << QString("//" ); |
| 3040 | } |
| 3041 | |
| 3042 | void tst_QUrl::setEmptyAuthority() |
| 3043 | { |
| 3044 | QFETCH(QString, host); |
| 3045 | QFETCH(QString, authority); |
| 3046 | QFETCH(QString, expectedUrlString); |
| 3047 | QUrl u; |
| 3048 | u.setHost(host); |
| 3049 | QCOMPARE(u.toString(), expectedUrlString); |
| 3050 | u.setAuthority(authority); |
| 3051 | QCOMPARE(u.toString(), expectedUrlString); |
| 3052 | } |
| 3053 | |
| 3054 | void tst_QUrl::clear() |
| 3055 | { |
| 3056 | QUrl url("a" ); |
| 3057 | QUrl url2("a" ); |
| 3058 | QCOMPARE(url, url2); |
| 3059 | url.clear(); |
| 3060 | QVERIFY(url != url2); |
| 3061 | } |
| 3062 | |
| 3063 | void tst_QUrl::binaryData_data() |
| 3064 | { |
| 3065 | QTest::addColumn<QString>(name: "url" ); |
| 3066 | QTest::newRow(dataTag: "username" ) << "http://%01%0D%0A%7F@foo/" ; |
| 3067 | QTest::newRow(dataTag: "username-at" ) << "http://abc%40_def@foo/" ; |
| 3068 | QTest::newRow(dataTag: "username-nul" ) << "http://abc%00_def@foo/" ; |
| 3069 | QTest::newRow(dataTag: "username-colon" ) << "http://abc%3A_def@foo/" ; |
| 3070 | QTest::newRow(dataTag: "username-nonutf8" ) << "http://abc%E1_def@foo/" ; |
| 3071 | |
| 3072 | QTest::newRow(dataTag: "password" ) << "http://user:%01%0D%0A%7F@foo/" ; |
| 3073 | QTest::newRow(dataTag: "password-at" ) << "http://user:abc%40_def@foo/" ; |
| 3074 | QTest::newRow(dataTag: "password-nul" ) << "http://user:abc%00_def@foo/" ; |
| 3075 | QTest::newRow(dataTag: "password-nonutf8" ) << "http://user:abc%E1_def@foo/" ; |
| 3076 | |
| 3077 | QTest::newRow(dataTag: "file" ) << "http://foo/%01%0D%0A%7F" ; |
| 3078 | QTest::newRow(dataTag: "file-nul" ) << "http://foo/abc%00_def" ; |
| 3079 | QTest::newRow(dataTag: "file-hash" ) << "http://foo/abc%23_def" ; |
| 3080 | QTest::newRow(dataTag: "file-question" ) << "http://foo/abc%3F_def" ; |
| 3081 | QTest::newRow(dataTag: "file-nonutf8" ) << "http://foo/abc%E1_def" ; |
| 3082 | QTest::newRow(dataTag: "file-slash" ) << "http://foo/abc%2F_def" ; |
| 3083 | |
| 3084 | QTest::newRow(dataTag: "ref" ) << "http://foo/file#a%01%0D%0A%7F" ; |
| 3085 | QTest::newRow(dataTag: "ref-nul" ) << "http://foo/file#abc%00_def" ; |
| 3086 | QTest::newRow(dataTag: "ref-question" ) << "http://foo/file#abc?_def" ; |
| 3087 | QTest::newRow(dataTag: "ref-nonutf8" ) << "http://foo/file#abc%E1_def" ; |
| 3088 | |
| 3089 | QTest::newRow(dataTag: "query-value" ) << "http://foo/query?foo=%01%0D%0A%7F" ; |
| 3090 | QTest::newRow(dataTag: "query-value-nul" ) << "http://foo/query?foo=abc%00_def" ; |
| 3091 | QTest::newRow(dataTag: "query-value-nonutf8" ) << "http://foo/query?foo=abc%E1_def" ; |
| 3092 | |
| 3093 | QTest::newRow(dataTag: "query-name" ) << "http://foo/query/a%01%0D%0A%7Fz=foo" ; |
| 3094 | QTest::newRow(dataTag: "query-name-nul" ) << "http://foo/query/abc%00_def=foo" ; |
| 3095 | QTest::newRow(dataTag: "query-name-nonutf8" ) << "http://foo/query/abc%E1_def=foo" ; |
| 3096 | } |
| 3097 | |
| 3098 | void tst_QUrl::binaryData() |
| 3099 | { |
| 3100 | QFETCH(QString, url); |
| 3101 | QUrl u = QUrl::fromEncoded(url: url.toUtf8()); |
| 3102 | |
| 3103 | QVERIFY(u.isValid()); |
| 3104 | QVERIFY(!u.isEmpty()); |
| 3105 | |
| 3106 | QString url2 = QString::fromUtf8(str: u.toEncoded()); |
| 3107 | //QCOMPARE(url2.length(), url.length()); |
| 3108 | QCOMPARE(url2, url); |
| 3109 | } |
| 3110 | |
| 3111 | void tst_QUrl::fromUserInput_data() |
| 3112 | { |
| 3113 | // |
| 3114 | // most of this test is: |
| 3115 | // Copyright (C) Research In Motion Limited 2009. All rights reserved. |
| 3116 | // Distributed under the BSD license. |
| 3117 | // See qurl.cpp |
| 3118 | // |
| 3119 | |
| 3120 | QTest::addColumn<QString>(name: "string" ); |
| 3121 | QTest::addColumn<QUrl>(name: "guessUrlFromString" ); |
| 3122 | |
| 3123 | // Null |
| 3124 | QTest::newRow(dataTag: "null" ) << QString() << QUrl(); |
| 3125 | |
| 3126 | // File |
| 3127 | QDirIterator it(QDir::homePath()); |
| 3128 | int c = 0; |
| 3129 | while (it.hasNext()) { |
| 3130 | it.next(); |
| 3131 | QTest::newRow(dataTag: ("file-" + QByteArray::number(c++)).constData()) |
| 3132 | << it.filePath() << QUrl::fromLocalFile(localfile: it.filePath()); |
| 3133 | } |
| 3134 | |
| 3135 | // basic latin1 |
| 3136 | QTest::newRow(dataTag: "unicode-0" ) << QString::fromUtf8(str: "\xc3\xa5.com/" ) << QUrl::fromEncoded(url: QString::fromUtf8(str: "http://\xc3\xa5.com/" ).toUtf8(), mode: QUrl::TolerantMode); |
| 3137 | QTest::newRow(dataTag: "unicode-0b" ) << QString::fromUtf8(str: "\xc3\xa5.com/" ) << QUrl::fromEncoded(url: "http://%C3%A5.com/" , mode: QUrl::TolerantMode); |
| 3138 | QTest::newRow(dataTag: "unicode-0c" ) << QString::fromUtf8(str: "\xc3\xa5.com/" ) << QUrl::fromEncoded(url: "http://xn--5ca.com/" , mode: QUrl::TolerantMode); |
| 3139 | // unicode |
| 3140 | QTest::newRow(dataTag: "unicode-1" ) << QString::fromUtf8(str: "\xce\xbb.com/" ) << QUrl::fromEncoded(url: QString::fromUtf8(str: "http://\xce\xbb.com/" ).toUtf8(), mode: QUrl::TolerantMode); |
| 3141 | QTest::newRow(dataTag: "unicode-1b" ) << QString::fromUtf8(str: "\xce\xbb.com/" ) << QUrl::fromEncoded(url: "http://%CE%BB.com/" , mode: QUrl::TolerantMode); |
| 3142 | QTest::newRow(dataTag: "unicode-1c" ) << QString::fromUtf8(str: "\xce\xbb.com/" ) << QUrl::fromEncoded(url: "http://xn--wxa.com/" , mode: QUrl::TolerantMode); |
| 3143 | |
| 3144 | // no scheme |
| 3145 | QTest::newRow(dataTag: "add scheme-0" ) << "example.org" << QUrl("http://example.org" ); |
| 3146 | QTest::newRow(dataTag: "add scheme-1" ) << "www.example.org" << QUrl("http://www.example.org" ); |
| 3147 | QTest::newRow(dataTag: "add scheme-2" ) << "ftp.example.org" << QUrl("ftp://ftp.example.org" ); |
| 3148 | QTest::newRow(dataTag: "add scheme-3" ) << "hostname" << QUrl("http://hostname" ); |
| 3149 | QTest::newRow(dataTag: "ipv4-1" ) << "127.0.0.1" << QUrl("http://127.0.0.1" ); |
| 3150 | QTest::newRow(dataTag: "ipv6-0" ) << "::" << QUrl("http://[::]" ); |
| 3151 | QTest::newRow(dataTag: "ipv6-1" ) << "::1" << QUrl("http://[::1]" ); |
| 3152 | QTest::newRow(dataTag: "ipv6-2" ) << "1::1" << QUrl("http://[1::1]" ); |
| 3153 | QTest::newRow(dataTag: "ipv6-3" ) << "1::" << QUrl("http://[1::]" ); |
| 3154 | QTest::newRow(dataTag: "ipv6-4" ) << "c::" << QUrl("http://[c::]" ); |
| 3155 | QTest::newRow(dataTag: "ipv6-5" ) << "c:f00:ba4::" << QUrl("http://[c:f00:ba4::]" ); |
| 3156 | |
| 3157 | // no host |
| 3158 | QTest::newRow(dataTag: "nohost-1" ) << "http://" << QUrl("http://" ); |
| 3159 | QTest::newRow(dataTag: "nohost-2" ) << "smb:" << QUrl("smb:" ); |
| 3160 | |
| 3161 | // QUrl's tolerant parser should already handle this |
| 3162 | QTest::newRow(dataTag: "not-encoded-0" ) << "http://example.org/test page.html" << QUrl::fromEncoded(url: "http://example.org/test%20page.html" ); |
| 3163 | |
| 3164 | // Make sure the :80, i.e. port doesn't screw anything up |
| 3165 | QUrl portUrl("http://example.org" ); |
| 3166 | portUrl.setPort(80); |
| 3167 | QTest::newRow(dataTag: "port-0" ) << "example.org:80" << portUrl; |
| 3168 | QTest::newRow(dataTag: "port-1" ) << "http://example.org:80" << portUrl; |
| 3169 | portUrl.setPath(path: "/path" ); |
| 3170 | QTest::newRow(dataTag: "port-2" ) << "example.org:80/path" << portUrl; |
| 3171 | QTest::newRow(dataTag: "port-3" ) << "http://example.org:80/path" << portUrl; |
| 3172 | |
| 3173 | // mailto doesn't have a ://, but is valid |
| 3174 | QUrl mailto("ben@example.net" ); |
| 3175 | mailto.setScheme("mailto" ); |
| 3176 | QTest::newRow(dataTag: "mailto" ) << "mailto:ben@example.net" << mailto; |
| 3177 | |
| 3178 | // misc |
| 3179 | QTest::newRow(dataTag: "localhost-1" ) << "localhost:80" << QUrl("http://localhost:80" ); |
| 3180 | QTest::newRow(dataTag: "spaces-0" ) << " http://example.org/test page.html " << QUrl("http://example.org/test%20page.html" ); |
| 3181 | QTest::newRow(dataTag: "trash-0" ) << "example.org/test?someData=42%&someOtherData=abcde#anchor" << QUrl::fromEncoded(url: "http://example.org/test?someData=42%25&someOtherData=abcde#anchor" ); |
| 3182 | QTest::newRow(dataTag: "other-scheme-0" ) << "spotify:track:0hO542doVbfGDAGQULMORT" << QUrl("spotify:track:0hO542doVbfGDAGQULMORT" ); |
| 3183 | QTest::newRow(dataTag: "other-scheme-1" ) << "weirdscheme:80:otherstuff" << QUrl("weirdscheme:80:otherstuff" ); |
| 3184 | QTest::newRow(dataTag: "number-path-0" ) << "tel:2147483648" << QUrl("tel:2147483648" ); |
| 3185 | |
| 3186 | // FYI: The scheme in the resulting url user |
| 3187 | QUrl authUrl("user:pass@domain.com" ); |
| 3188 | QTest::newRow(dataTag: "misc-1" ) << "user:pass@domain.com" << authUrl; |
| 3189 | |
| 3190 | // FTP with double slashes in path |
| 3191 | QTest::newRow(dataTag: "ftp-double-slash-1" ) << "ftp.example.com//path" << QUrl("ftp://ftp.example.com/%2Fpath" ); |
| 3192 | QTest::newRow(dataTag: "ftp-double-slash-1" ) << "ftp://ftp.example.com//path" << QUrl("ftp://ftp.example.com/%2Fpath" ); |
| 3193 | } |
| 3194 | |
| 3195 | void tst_QUrl::fromUserInput() |
| 3196 | { |
| 3197 | QFETCH(QString, string); |
| 3198 | QFETCH(QUrl, guessUrlFromString); |
| 3199 | |
| 3200 | QUrl url = QUrl::fromUserInput(userInput: string); |
| 3201 | QCOMPARE(url, guessUrlFromString); |
| 3202 | } |
| 3203 | |
| 3204 | void tst_QUrl::fromUserInputWithCwd_data() |
| 3205 | { |
| 3206 | QTest::addColumn<QString>(name: "string" ); |
| 3207 | QTest::addColumn<QString>(name: "directory" ); |
| 3208 | QTest::addColumn<QUrl>(name: "guessedUrlDefault" ); |
| 3209 | QTest::addColumn<QUrl>(name: "guessedUrlAssumeLocalFile" ); |
| 3210 | |
| 3211 | // Null |
| 3212 | QTest::newRow(dataTag: "null" ) << QString() << QString() << QUrl() << QUrl(); |
| 3213 | |
| 3214 | // Use a tempdir with files, for testing specific file names |
| 3215 | // We use canonicalPath() on the dir path because ::getcwd() canonicalizes, |
| 3216 | // so we get a canonical base path for URLs with "." as working directory. |
| 3217 | const QString base = QDir(m_tempDir.path()).canonicalPath(); |
| 3218 | QDir::setCurrent(base); // for the tests that use "." as working dir |
| 3219 | |
| 3220 | // "." |
| 3221 | { |
| 3222 | const QUrl url = QUrl::fromLocalFile(localfile: base); // fromUserInput cleans the path |
| 3223 | QTest::newRow(dataTag: "dot-in-path" ) << "." << base << url << url; |
| 3224 | QTest::newRow(dataTag: "dot-in-dot" ) << "." << QStringLiteral("." ) << url << url; |
| 3225 | } |
| 3226 | |
| 3227 | // Existing files |
| 3228 | for (const char *fileName : {"file.txt" , "file#a.txt" , "file .txt" , "file.txt " |
| 3229 | #ifndef Q_OS_WIN |
| 3230 | , "file:colon.txt" |
| 3231 | #endif |
| 3232 | }) { |
| 3233 | const QString filePath = base + '/' + fileName; |
| 3234 | QFile file(filePath); |
| 3235 | QVERIFY2(file.open(QIODevice::WriteOnly), qPrintable(filePath)); |
| 3236 | file.write(data: "Hello world\n" ); |
| 3237 | |
| 3238 | const QUrl url = QUrl::fromLocalFile(localfile: filePath); |
| 3239 | QTest::newRow(dataTag: fileName) << fileName << base << url << url; |
| 3240 | QTest::newRow(dataTag: QByteArray(fileName) + "-in-dot" ) << fileName << QStringLiteral("." ) << url << url; |
| 3241 | } |
| 3242 | |
| 3243 | #ifndef Q_OS_WINRT // WinRT cannot cd outside current / sandbox |
| 3244 | QDir parent(base); |
| 3245 | QVERIFY(parent.cdUp()); |
| 3246 | QUrl parentUrl = QUrl::fromLocalFile(localfile: parent.path()); |
| 3247 | QTest::newRow(dataTag: "dotdot" ) << ".." << base << parentUrl << parentUrl; |
| 3248 | #endif |
| 3249 | |
| 3250 | QTest::newRow(dataTag: "nonexisting" ) << "nonexisting" << base << QUrl("http://nonexisting" ) << QUrl::fromLocalFile(localfile: base + "/nonexisting" ); |
| 3251 | QTest::newRow(dataTag: "short-url" ) << "example.org" << base << QUrl("http://example.org" ) << QUrl::fromLocalFile(localfile: base + "/example.org" ); |
| 3252 | QTest::newRow(dataTag: "full-url" ) << "http://example.org" << base << QUrl("http://example.org" ) << QUrl("http://example.org" ); |
| 3253 | QTest::newRow(dataTag: "absolute" ) << "/doesnotexist.txt" << base << QUrl("file:///doesnotexist.txt" ) << QUrl("file:///doesnotexist.txt" ); |
| 3254 | #ifdef Q_OS_WIN |
| 3255 | QTest::newRow("windows-absolute" ) << "c:/doesnotexist.txt" << base << QUrl("file:///c:/doesnotexist.txt" ) << QUrl("file:///c:/doesnotexist.txt" ); |
| 3256 | #endif |
| 3257 | |
| 3258 | // IPv4 & IPv6 |
| 3259 | // same as fromUserInput, but needs retesting |
| 3260 | QTest::newRow(dataTag: "ipv4-1" ) << "127.0.0.1" << base << QUrl("http://127.0.0.1" ) << QUrl::fromLocalFile(localfile: base + "/127.0.0.1" ); |
| 3261 | QTest::newRow(dataTag: "ipv6-0" ) << "::" << base << QUrl("http://[::]" ) << QUrl("http://[::]" ); |
| 3262 | QTest::newRow(dataTag: "ipv6-1" ) << "::1" << base << QUrl("http://[::1]" ) << QUrl("http://[::1]" ); |
| 3263 | QTest::newRow(dataTag: "ipv6-2" ) << "1::1" << base << QUrl("http://[1::1]" ) << QUrl("http://[1::1]" ); |
| 3264 | QTest::newRow(dataTag: "ipv6-3" ) << "1::" << base << QUrl("http://[1::]" ) << QUrl("http://[1::]" ); |
| 3265 | QTest::newRow(dataTag: "ipv6-4" ) << "c::" << base << QUrl("http://[c::]" ) << QUrl("http://[c::]" ); |
| 3266 | QTest::newRow(dataTag: "ipv6-5" ) << "c:f00:ba4::" << base << QUrl("http://[c:f00:ba4::]" ) << QUrl("http://[c:f00:ba4::]" ); |
| 3267 | } |
| 3268 | |
| 3269 | void tst_QUrl::fromUserInputWithCwd() |
| 3270 | { |
| 3271 | QFETCH(QString, string); |
| 3272 | QFETCH(QString, directory); |
| 3273 | QFETCH(QUrl, guessedUrlDefault); |
| 3274 | QFETCH(QUrl, guessedUrlAssumeLocalFile); |
| 3275 | |
| 3276 | QUrl url = QUrl::fromUserInput(userInput: string, workingDirectory: directory); |
| 3277 | QCOMPARE(url, guessedUrlDefault); |
| 3278 | |
| 3279 | url = QUrl::fromUserInput(userInput: string, workingDirectory: directory, options: QUrl::AssumeLocalFile); |
| 3280 | QCOMPARE(url, guessedUrlAssumeLocalFile); |
| 3281 | } |
| 3282 | |
| 3283 | void tst_QUrl::fileName_data() |
| 3284 | { |
| 3285 | QTest::addColumn<QString>(name: "urlStr" ); |
| 3286 | QTest::addColumn<QString>(name: "expectedDirPath" ); |
| 3287 | QTest::addColumn<QString>(name: "expectedPrettyDecodedFileName" ); |
| 3288 | QTest::addColumn<QString>(name: "expectedFullyDecodedFileName" ); |
| 3289 | |
| 3290 | QTest::newRow(dataTag: "fromDocu" ) << "http://qt-project.org/support/file.html" |
| 3291 | << "/support/" << "file.html" << "file.html" ; |
| 3292 | QTest::newRow(dataTag: "absoluteFile" ) << "file:///temp/tmp.txt" |
| 3293 | << "/temp/" << "tmp.txt" << "tmp.txt" ; |
| 3294 | QTest::newRow(dataTag: "absoluteDir" ) << "file:///temp/" |
| 3295 | << "/temp/" << QString() << QString(); |
| 3296 | QTest::newRow(dataTag: "absoluteInRoot" ) << "file:///temp" |
| 3297 | << "/" << "temp" << "temp" ; |
| 3298 | QTest::newRow(dataTag: "relative" ) << "temp/tmp.txt" |
| 3299 | << "temp/" << "tmp.txt" << "tmp.txt" ; |
| 3300 | QTest::newRow(dataTag: "relativeNoSlash" ) << "tmp.txt" |
| 3301 | << QString() << "tmp.txt" << "tmp.txt" ; |
| 3302 | QTest::newRow(dataTag: "encoded" ) << "print:/specials/Print%20To%20File%20(PDF%252FAcrobat)" |
| 3303 | << "/specials/" << "Print To File (PDF%252FAcrobat)" << "Print To File (PDF%2FAcrobat)" ; |
| 3304 | QTest::newRow(dataTag: "endsWithDot" ) << "file:///temp/." |
| 3305 | << "/temp/" << "." << "." ; |
| 3306 | } |
| 3307 | |
| 3308 | void tst_QUrl::fileName() |
| 3309 | { |
| 3310 | QFETCH(QString, urlStr); |
| 3311 | QFETCH(QString, expectedDirPath); |
| 3312 | QFETCH(QString, expectedPrettyDecodedFileName); |
| 3313 | QFETCH(QString, expectedFullyDecodedFileName); |
| 3314 | |
| 3315 | QUrl url(urlStr); |
| 3316 | QVERIFY(url.isValid()); |
| 3317 | QCOMPARE(url.adjusted(QUrl::RemoveFilename).path(), expectedDirPath); |
| 3318 | QCOMPARE(url.fileName(QUrl::PrettyDecoded), expectedPrettyDecodedFileName); |
| 3319 | QCOMPARE(url.fileName(QUrl::FullyDecoded), expectedFullyDecodedFileName); |
| 3320 | } |
| 3321 | |
| 3322 | // This is a regression test for a previously fixed bug where isEmpty didn't |
| 3323 | // work for an encoded URL that was yet to be decoded. The test checks that |
| 3324 | // isEmpty works for an encoded URL both after and before decoding. |
| 3325 | void tst_QUrl::isEmptyForEncodedUrl() |
| 3326 | { |
| 3327 | { |
| 3328 | QUrl url; |
| 3329 | url.setUrl(url: QLatin1String("LABEL=USB_STICK" ), mode: QUrl::TolerantMode); |
| 3330 | QVERIFY( url.isValid() ); |
| 3331 | QCOMPARE( url.path(), QString("LABEL=USB_STICK" ) ); |
| 3332 | QVERIFY( !url.isEmpty() ); |
| 3333 | } |
| 3334 | { |
| 3335 | QUrl url; |
| 3336 | url.setUrl(url: QLatin1String("LABEL=USB_STICK" ), mode: QUrl::TolerantMode); |
| 3337 | QVERIFY( url.isValid() ); |
| 3338 | QVERIFY( !url.isEmpty() ); |
| 3339 | QCOMPARE( url.path(), QString("LABEL=USB_STICK" ) ); |
| 3340 | } |
| 3341 | } |
| 3342 | |
| 3343 | // This test verifies that the QUrl::toEncoded() does not rely on the |
| 3344 | // potentially uninitialized unencoded path. |
| 3345 | void tst_QUrl::toEncodedNotUsingUninitializedPath() |
| 3346 | { |
| 3347 | QUrl url; |
| 3348 | url.setPath(path: QLatin1String("/test.txt" )); |
| 3349 | url.setHost(host: "example.com" ); |
| 3350 | |
| 3351 | QCOMPARE(url.toEncoded().constData(), "//example.com/test.txt" ); |
| 3352 | |
| 3353 | url.path(); |
| 3354 | QCOMPARE(url.toEncoded().constData(), "//example.com/test.txt" ); |
| 3355 | } |
| 3356 | |
| 3357 | void tst_QUrl::resolvedWithAbsoluteSchemes() const |
| 3358 | { |
| 3359 | QFETCH(QUrl, base); |
| 3360 | QFETCH(QUrl, relative); |
| 3361 | QFETCH(QUrl, expected); |
| 3362 | |
| 3363 | /* Check our input. */ |
| 3364 | QVERIFY(relative.isValid()); |
| 3365 | QVERIFY(base.isValid()); |
| 3366 | QVERIFY(expected.isValid()); |
| 3367 | |
| 3368 | const QUrl result(base.resolved(relative)); |
| 3369 | |
| 3370 | QVERIFY(result.isValid()); |
| 3371 | QCOMPARE(result, expected); |
| 3372 | } |
| 3373 | |
| 3374 | void tst_QUrl::resolvedWithAbsoluteSchemes_data() const |
| 3375 | { |
| 3376 | QTest::addColumn<QUrl>(name: "base" ); |
| 3377 | QTest::addColumn<QUrl>(name: "relative" ); |
| 3378 | QTest::addColumn<QUrl>(name: "expected" ); |
| 3379 | |
| 3380 | QTest::newRow(dataTag: "Absolute file:/// against absolute FTP." ) |
| 3381 | << QUrl::fromEncoded(url: "file:///foo/" ) |
| 3382 | << QUrl::fromEncoded(url: "ftp://example.com/" ) |
| 3383 | << QUrl::fromEncoded(url: "ftp://example.com/" ); |
| 3384 | |
| 3385 | QTest::newRow(dataTag: "Absolute file:/// against absolute HTTP." ) |
| 3386 | << QUrl::fromEncoded(url: "file:///foo/" ) |
| 3387 | << QUrl::fromEncoded(url: "http://example.com/" ) |
| 3388 | << QUrl::fromEncoded(url: "http://example.com/" ); |
| 3389 | |
| 3390 | QTest::newRow(dataTag: "Absolute file:/// against data scheme." ) |
| 3391 | << QUrl::fromEncoded(url: "file:///foo/" ) |
| 3392 | << QUrl::fromEncoded(url: "data:application/xml,%3Ce%2F%3E" ) |
| 3393 | << QUrl::fromEncoded(url: "data:application/xml,%3Ce%2F%3E" ); |
| 3394 | |
| 3395 | QTest::newRow(dataTag: "Resolve with base url and port." ) |
| 3396 | << QUrl::fromEncoded(url: "http://www.foo.com:8080/" ) |
| 3397 | << QUrl::fromEncoded(url: "newfile.html" ) |
| 3398 | << QUrl::fromEncoded(url: "http://www.foo.com:8080/newfile.html" ); |
| 3399 | |
| 3400 | QTest::newRow(dataTag: "Resolve with relative path" ) |
| 3401 | << QUrl::fromEncoded(url: "http://example.com/" ) |
| 3402 | << QUrl::fromEncoded(url: "http://andreas:hemmelig@www.vg.no/a/../?my=query&your=query#yougotfragged" ) |
| 3403 | << QUrl::fromEncoded(url: "http://andreas:hemmelig@www.vg.no/?my=query&your=query#yougotfragged" ); |
| 3404 | } |
| 3405 | |
| 3406 | void tst_QUrl::emptyAuthorityRemovesExistingAuthority_data() |
| 3407 | { |
| 3408 | QTest::addColumn<QString>(name: "input" ); |
| 3409 | QTest::addColumn<QString>(name: "expected" ); |
| 3410 | QTest::newRow(dataTag: "regular" ) << "foo://example.com/something" << "foo:/something" ; |
| 3411 | QTest::newRow(dataTag: "empty" ) << "foo:///something" << "foo:/something" ; |
| 3412 | } |
| 3413 | |
| 3414 | void tst_QUrl::emptyAuthorityRemovesExistingAuthority() |
| 3415 | { |
| 3416 | QFETCH(QString, input); |
| 3417 | QFETCH(QString, expected); |
| 3418 | QUrl url(input); |
| 3419 | QUrl orig = url; |
| 3420 | |
| 3421 | url.setAuthority(authority: QString()); |
| 3422 | QCOMPARE(url.authority(), QString()); |
| 3423 | QVERIFY(url != orig); |
| 3424 | QCOMPARE(url.toString(), expected); |
| 3425 | QCOMPARE(url, QUrl(expected)); |
| 3426 | } |
| 3427 | |
| 3428 | void tst_QUrl::acceptEmptyAuthoritySegments() |
| 3429 | { |
| 3430 | QCOMPARE(QUrl("remote://" ).toString(), QString::fromLatin1("remote://" )); |
| 3431 | |
| 3432 | // Verify that foo:///bar is not mangled to foo:/bar nor vice-versa |
| 3433 | QString foo_triple_bar("foo:///bar" ), foo_uni_bar("foo:/bar" ); |
| 3434 | |
| 3435 | QVERIFY(QUrl(foo_triple_bar) != QUrl(foo_uni_bar)); |
| 3436 | |
| 3437 | QCOMPARE(QUrl(foo_triple_bar).toString(), foo_triple_bar); |
| 3438 | QCOMPARE(QUrl(foo_triple_bar).toEncoded(), foo_triple_bar.toLatin1()); |
| 3439 | |
| 3440 | QCOMPARE(QUrl(foo_uni_bar).toString(), foo_uni_bar); |
| 3441 | QCOMPARE(QUrl(foo_uni_bar).toEncoded(), foo_uni_bar.toLatin1()); |
| 3442 | |
| 3443 | QCOMPARE(QUrl(foo_triple_bar, QUrl::StrictMode).toString(), foo_triple_bar); |
| 3444 | QCOMPARE(QUrl(foo_triple_bar, QUrl::StrictMode).toEncoded(), foo_triple_bar.toLatin1()); |
| 3445 | |
| 3446 | QCOMPARE(QUrl(foo_uni_bar, QUrl::StrictMode).toString(), foo_uni_bar); |
| 3447 | QCOMPARE(QUrl(foo_uni_bar, QUrl::StrictMode).toEncoded(), foo_uni_bar.toLatin1()); |
| 3448 | |
| 3449 | // However, file:/bar is the same as file:///bar |
| 3450 | QString file_triple_bar("file:///bar" ), file_uni_bar("file:/bar" ); |
| 3451 | |
| 3452 | QCOMPARE(QUrl(file_triple_bar), QUrl(file_uni_bar)); |
| 3453 | |
| 3454 | QCOMPARE(QUrl(file_uni_bar).toString(), file_triple_bar); |
| 3455 | QCOMPARE(QUrl(file_uni_bar, QUrl::StrictMode).toString(), file_triple_bar); |
| 3456 | } |
| 3457 | |
| 3458 | void tst_QUrl::effectiveTLDs_data() |
| 3459 | { |
| 3460 | // See also: tst_QNetworkCookieJar::setCookiesFromUrl(). |
| 3461 | // in tests/auto/network/access/qnetworkcookiejar/tst_qnetworkcookiejar.cpp |
| 3462 | QTest::addColumn<QUrl>(name: "domain" ); |
| 3463 | QTest::addColumn<QString>(name: "TLD" ); |
| 3464 | // TODO: autogenerate test-cases from: |
| 3465 | // https://raw.githubusercontent.com/publicsuffix/list/master/tests/test_psl.txt |
| 3466 | // checkPublicSuffix(domain, tail) appears in the list if |
| 3467 | // either tail is null and domain is public or |
| 3468 | // tail is the "registrable" part of domain; i.e. its minimal non-public tail. |
| 3469 | |
| 3470 | QTest::newRow(dataTag: "yes0" ) << QUrl::fromEncoded(url: "http://test.co.uk" ) << ".co.uk" ; |
| 3471 | QTest::newRow(dataTag: "yes1" ) << QUrl::fromEncoded(url: "http://test.com" ) << ".com" ; |
| 3472 | QTest::newRow(dataTag: "yes2" ) << QUrl::fromEncoded(url: "http://www.test.de" ) << ".de" ; |
| 3473 | QTest::newRow(dataTag: "yes3" ) << QUrl::fromEncoded(url: "http://test.ulm.museum" ) << ".ulm.museum" ; |
| 3474 | QTest::newRow(dataTag: "yes4" ) << QUrl::fromEncoded(url: "http://www.com.krodsherad.no" ) << ".krodsherad.no" ; |
| 3475 | QTest::newRow(dataTag: "yes5" ) << QUrl::fromEncoded(url: "http://www.co.uk.1.bg" ) << ".1.bg" ; |
| 3476 | QTest::newRow(dataTag: "yes6" ) << QUrl::fromEncoded(url: "http://www.com.com.cn" ) << ".com.cn" ; |
| 3477 | QTest::newRow(dataTag: "yes7" ) << QUrl::fromEncoded(url: "http://www.test.org.ws" ) << ".org.ws" ; |
| 3478 | QTest::newRow(dataTag: "yes9" ) << QUrl::fromEncoded(url: "http://www.com.co.uk.wallonie.museum" ) << ".wallonie.museum" ; |
| 3479 | QTest::newRow(dataTag: "yes10" ) << QUrl::fromEncoded(url: "http://www.com.evje-og-hornnes.no" ) << ".evje-og-hornnes.no" ; |
| 3480 | QTest::newRow(dataTag: "yes11" ) << QUrl::fromEncoded(url: "http://www.bla.kamijima.ehime.jp" ) << ".kamijima.ehime.jp" ; |
| 3481 | QTest::newRow(dataTag: "yes12" ) << QUrl::fromEncoded(url: "http://www.bla.kakuda.miyagi.jp" ) << ".kakuda.miyagi.jp" ; |
| 3482 | QTest::newRow(dataTag: "yes13" ) << QUrl::fromEncoded(url: "http://mypage.betainabox.com" ) << ".betainabox.com" ; |
| 3483 | QTest::newRow(dataTag: "yes14" ) << QUrl::fromEncoded(url: "http://mypage.rhcloud.com" ) << ".rhcloud.com" ; |
| 3484 | QTest::newRow(dataTag: "yes15" ) << QUrl::fromEncoded(url: "http://mypage.int.az" ) << ".int.az" ; |
| 3485 | QTest::newRow(dataTag: "yes16" ) << QUrl::fromEncoded(url: "http://anything.pagespeedmobilizer.com" ) << ".pagespeedmobilizer.com" ; |
| 3486 | QTest::newRow(dataTag: "yes17" ) << QUrl::fromEncoded(url: "http://anything.eu-central-1.compute.amazonaws.com" ) << ".eu-central-1.compute.amazonaws.com" ; |
| 3487 | QTest::newRow(dataTag: "yes18" ) << QUrl::fromEncoded(url: "http://anything.ltd.hk" ) << ".ltd.hk" ; |
| 3488 | QTest::newRow(dataTag: "trentino.it" ) |
| 3489 | << QUrl::fromEncoded(url: "http://any.thing.trentino.it" ) << ".trentino.it" ; |
| 3490 | QTest::newRow(dataTag: "net.ni" ) << QUrl::fromEncoded(url: "http://test.net.ni" ) << ".net.ni" ; |
| 3491 | QTest::newRow(dataTag: "dyn.cosidns.de" ) |
| 3492 | << QUrl::fromEncoded(url: "http://test.dyn.cosidns.de" ) << ".dyn.cosidns.de" ; |
| 3493 | QTest::newRow(dataTag: "freeddns.org" ) |
| 3494 | << QUrl::fromEncoded(url: "http://test.freeddns.org" ) << ".freeddns.org" ; |
| 3495 | QTest::newRow(dataTag: "app.os.stg.fedoraproject.org" ) |
| 3496 | << QUrl::fromEncoded(url: "http://test.app.os.stg.fedoraproject.org" ) |
| 3497 | << ".app.os.stg.fedoraproject.org" ; |
| 3498 | QTest::newRow(dataTag: "development.run" ) << QUrl::fromEncoded(url: "http://test.development.run" ) << ".development.run" ; |
| 3499 | QTest::newRow(dataTag: "crafting.xyz" ) << QUrl::fromEncoded(url: "http://test.crafting.xyz" ) << ".crafting.xyz" ; |
| 3500 | QTest::newRow(dataTag: "nym.ie" ) << QUrl::fromEncoded(url: "http://shamus.nym.ie" ) << ".ie" ; |
| 3501 | QTest::newRow(dataTag: "vapor.cloud" ) << QUrl::fromEncoded(url: "http://test.vapor.cloud" ) << ".vapor.cloud" ; |
| 3502 | QTest::newRow(dataTag: "official.academy" ) << QUrl::fromEncoded(url: "http://acredited.official.academy" ) << ".official.academy" ; |
| 3503 | } |
| 3504 | |
| 3505 | void tst_QUrl::effectiveTLDs() |
| 3506 | { |
| 3507 | QFETCH(QUrl, domain); |
| 3508 | QFETCH(QString, TLD); |
| 3509 | QCOMPARE(domain.topLevelDomain(QUrl::PrettyDecoded), TLD); |
| 3510 | QCOMPARE(domain.topLevelDomain(QUrl::FullyDecoded), TLD); |
| 3511 | } |
| 3512 | |
| 3513 | void tst_QUrl::lowercasesScheme() |
| 3514 | { |
| 3515 | QUrl url; |
| 3516 | url.setScheme("HELLO" ); |
| 3517 | QCOMPARE(url.scheme(), QString("hello" )); |
| 3518 | } |
| 3519 | |
| 3520 | void tst_QUrl::componentEncodings_data() |
| 3521 | { |
| 3522 | QTest::addColumn<QUrl>(name: "url" ); |
| 3523 | QTest::addColumn<int>(name: "encoding" ); |
| 3524 | QTest::addColumn<QString>(name: "userName" ); |
| 3525 | QTest::addColumn<QString>(name: "password" ); |
| 3526 | QTest::addColumn<QString>(name: "userInfo" ); |
| 3527 | QTest::addColumn<QString>(name: "host" ); |
| 3528 | QTest::addColumn<QString>(name: "authority" ); |
| 3529 | QTest::addColumn<QString>(name: "path" ); |
| 3530 | QTest::addColumn<QString>(name: "query" ); |
| 3531 | QTest::addColumn<QString>(name: "fragment" ); |
| 3532 | QTest::addColumn<QString>(name: "toString" ); |
| 3533 | |
| 3534 | const int MostDecoded = QUrl::DecodeReserved; // the most decoded mode without being fully decoded |
| 3535 | |
| 3536 | QTest::newRow(dataTag: "empty" ) << QUrl() << int(QUrl::FullyEncoded) |
| 3537 | << QString() << QString() << QString() |
| 3538 | << QString() << QString() |
| 3539 | << QString() << QString() << QString() << QString(); |
| 3540 | |
| 3541 | // hostname cannot contain spaces |
| 3542 | QTest::newRow(dataTag: "encoded-space" ) << QUrl("x://user name:pass word@host/path name?query value#fragment value" ) |
| 3543 | << int(QUrl::EncodeSpaces) |
| 3544 | << "user%20name" << "pass%20word" << "user%20name:pass%20word" |
| 3545 | << "host" << "user%20name:pass%20word@host" |
| 3546 | << "/path%20name" << "query%20value" << "fragment%20value" |
| 3547 | << "x://user%20name:pass%20word@host/path%20name?query%20value#fragment%20value" ; |
| 3548 | |
| 3549 | QTest::newRow(dataTag: "decoded-space" ) << QUrl("x://user%20name:pass%20word@host/path%20name?query%20value#fragment%20value" ) |
| 3550 | << MostDecoded |
| 3551 | << "user name" << "pass word" << "user name:pass word" |
| 3552 | << "host" << "user name:pass word@host" |
| 3553 | << "/path name" << "query value" << "fragment value" |
| 3554 | << "x://user name:pass word@host/path name?query value#fragment value" ; |
| 3555 | |
| 3556 | // binary data is always encoded |
| 3557 | // this is also testing non-UTF8 data |
| 3558 | QTest::newRow(dataTag: "binary" ) << QUrl("x://%c0%00:%c1%01@host/%c2%02?%c3%03#%d4%04" ) |
| 3559 | << MostDecoded |
| 3560 | << "%C0%00" << "%C1%01" << "%C0%00:%C1%01" |
| 3561 | << "host" << "%C0%00:%C1%01@host" |
| 3562 | << "/%C2%02" << "%C3%03" << "%D4%04" |
| 3563 | << "x://%C0%00:%C1%01@host/%C2%02?%C3%03#%D4%04" ; |
| 3564 | |
| 3565 | // unicode tests |
| 3566 | // hostnames can participate in this test, but we need a top-level domain that accepts Unicode |
| 3567 | QTest::newRow(dataTag: "encoded-unicode" ) << QUrl(QString::fromUtf8(str: "x://\xc2\x80:\xc3\x90@smørbrød.example.no/\xe0\xa0\x80?\xf0\x90\x80\x80#é" )) |
| 3568 | << int(QUrl::EncodeUnicode) |
| 3569 | << "%C2%80" << "%C3%90" << "%C2%80:%C3%90" |
| 3570 | << "xn--smrbrd-cyad.example.no" << "%C2%80:%C3%90@xn--smrbrd-cyad.example.no" |
| 3571 | << "/%E0%A0%80" << "%F0%90%80%80" << "%C3%A9" |
| 3572 | << "x://%C2%80:%C3%90@xn--smrbrd-cyad.example.no/%E0%A0%80?%F0%90%80%80#%C3%A9" ; |
| 3573 | QTest::newRow(dataTag: "decoded-unicode" ) << QUrl("x://%C2%80:%C3%90@XN--SMRBRD-cyad.example.NO/%E0%A0%80?%F0%90%80%80#%C3%A9" ) |
| 3574 | << MostDecoded |
| 3575 | << QString::fromUtf8(str: "\xc2\x80" ) << QString::fromUtf8(str: "\xc3\x90" ) |
| 3576 | << QString::fromUtf8(str: "\xc2\x80:\xc3\x90" ) |
| 3577 | << QString::fromUtf8(str: "smørbrød.example.no" ) |
| 3578 | << QString::fromUtf8(str: "\xc2\x80:\xc3\x90@smørbrød.example.no" ) |
| 3579 | << QString::fromUtf8(str: "/\xe0\xa0\x80" ) |
| 3580 | << QString::fromUtf8(str: "\xf0\x90\x80\x80" ) << QString::fromUtf8(str: "é" ) |
| 3581 | << QString::fromUtf8(str: "x://\xc2\x80:\xc3\x90@smørbrød.example.no/\xe0\xa0\x80?\xf0\x90\x80\x80#é" ); |
| 3582 | |
| 3583 | // unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" |
| 3584 | // these are always decoded |
| 3585 | QTest::newRow(dataTag: "decoded-unreserved" ) << QUrl("x://%61:%71@%41%30%2eexample%2ecom/%7e?%5f#%51" ) |
| 3586 | << int(QUrl::FullyEncoded) |
| 3587 | << "a" << "q" << "a:q" |
| 3588 | << "a0.example.com" << "a:q@a0.example.com" |
| 3589 | << "/~" << "_" << "Q" |
| 3590 | << "x://a:q@a0.example.com/~?_#Q" ; |
| 3591 | |
| 3592 | // sub-delims = "!" / "$" / "&" / "'" / "(" / ")" |
| 3593 | // / "*" / "+" / "," / ";" / "=" |
| 3594 | // these are always left alone |
| 3595 | QTest::newRow(dataTag: "decoded-subdelims" ) << QUrl("x://!$&:'()@host/*+,?$=(+)#;=" ) |
| 3596 | << int(QUrl::FullyEncoded) |
| 3597 | << "!$&" << "'()" << "!$&:'()" |
| 3598 | << "host" << "!$&:'()@host" |
| 3599 | << "/*+," << "$=(+)" << ";=" |
| 3600 | << "x://!$&:'()@host/*+,?$=(+)#;=" ; |
| 3601 | QTest::newRow(dataTag: "encoded-subdelims" ) << QUrl("x://%21%24%26:%27%28%29@host/%2a%2b%2c?%26=%26&%3d=%3d#%3b%3d" ) |
| 3602 | << MostDecoded |
| 3603 | << "%21%24%26" << "%27%28%29" << "%21%24%26:%27%28%29" |
| 3604 | << "host" << "%21%24%26:%27%28%29@host" |
| 3605 | << "/%2A%2B%2C" << "%26=%26&%3D=%3D" << "%3B%3D" |
| 3606 | << "x://%21%24%26:%27%28%29@host/%2A%2B%2C?%26=%26&%3D=%3D#%3B%3D" ; |
| 3607 | |
| 3608 | // gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@" |
| 3609 | // these are the separators between fields |
| 3610 | // they must appear encoded in certain positions in the full URL, no exceptions |
| 3611 | // when in those positions, they appear decoded in the isolated parts |
| 3612 | // in other positions and the other delimiters are always left untransformed |
| 3613 | // 1) test the delimiters that must appear encoded |
| 3614 | // (if they were decoded, they'd would change the URL parsing) |
| 3615 | QTest::newRow(dataTag: "encoded-gendelims-changing" ) << QUrl("x://%5b%3a%2f%3f%23%40%5d:%5b%2f%3f%23%40%5d@host/%2f%3f%23?%23" ) |
| 3616 | << MostDecoded |
| 3617 | << "[:/?#@]" << "[/?#@]" << "[%3A/?#@]:[/?#@]" |
| 3618 | << "host" << "%5B%3A/?#%40%5D:%5B/?#%40%5D@host" |
| 3619 | << "/%2F?#" << "#" << "" |
| 3620 | << "x://%5B%3A%2F%3F%23%40%5D:%5B%2F%3F%23%40%5D@host/%2F%3F%23?%23" ; |
| 3621 | |
| 3622 | // 2) test that the other delimiters remain decoded |
| 3623 | QTest::newRow(dataTag: "decoded-gendelims-unchanging" ) << QUrl("x://::@host/:@/[]?:/?@[]?#:/?@[]" ) |
| 3624 | << int(QUrl::FullyEncoded) |
| 3625 | << "" << ":" << "::" |
| 3626 | << "host" << "::@host" |
| 3627 | << "/:@/[]" << ":/?@[]?" << ":/?@[]" |
| 3628 | << "x://::@host/:@/[]?:/?@[]?#:/?@[]" ; |
| 3629 | |
| 3630 | // 3) and test that the same encoded sequences remain encoded |
| 3631 | QTest::newRow(dataTag: "encoded-gendelims-unchanging" ) << QUrl("x://:%3A@host/%3A%40%5B%5D?%3A%2F%3F%40%5B%5D#%23%3A%2F%3F%40%5B%5D" ) |
| 3632 | << MostDecoded |
| 3633 | << "" << "%3A" << ":%3A" |
| 3634 | << "host" << ":%3A@host" |
| 3635 | << "/%3A%40%5B%5D" << "%3A%2F%3F%40%5B%5D" << "%23%3A%2F%3F%40%5B%5D" |
| 3636 | << "x://:%3A@host/%3A%40%5B%5D?%3A%2F%3F%40%5B%5D#%23%3A%2F%3F%40%5B%5D" ; |
| 3637 | |
| 3638 | // test the query |
| 3639 | // since QUrl doesn't know what chars the user wants to use for the pair and value delimiters, |
| 3640 | // it keeps the delimiters alone except for "#", which must always be encoded. |
| 3641 | // In the following test, all delimiter characters appear both as encoded and as decoded (except for "#") |
| 3642 | QTest::newRow(dataTag: "unencoded-delims-query" ) << QUrl("?!$()*+,;=:/?[]@%21%24%26%27%28%29%2a%2b%2c%2f%3a%3b%3d%3f%40%5b%5d" ) |
| 3643 | << int(QUrl::FullyEncoded) |
| 3644 | << QString() << QString() << QString() |
| 3645 | << QString() << QString() |
| 3646 | << QString() << "!$()*+,;=:/?[]@%21%24%26%27%28%29%2A%2B%2C%2F%3A%3B%3D%3F%40%5B%5D" << QString() |
| 3647 | << "?!$()*+,;=:/?[]@%21%24%26%27%28%29%2A%2B%2C%2F%3A%3B%3D%3F%40%5B%5D" ; |
| 3648 | QTest::newRow(dataTag: "undecoded-delims-query" ) << QUrl("?!$()*+,;=:/?[]@%21%24%26%27%28%29%2a%2b%2c%2f%3a%3b%3d%3f%40%5b%5d" ) |
| 3649 | << MostDecoded |
| 3650 | << QString() << QString() << QString() |
| 3651 | << QString() << QString() |
| 3652 | << QString() << "!$()*+,;=:/?[]@%21%24%26%27%28%29%2A%2B%2C%2F%3A%3B%3D%3F%40%5B%5D" << QString() |
| 3653 | << "?!$()*+,;=:/?[]@%21%24%26%27%28%29%2A%2B%2C%2F%3A%3B%3D%3F%40%5B%5D" ; |
| 3654 | |
| 3655 | // reserved characters: '"' / "<" / ">" / "^" / "\" / "{" / "|" "}" |
| 3656 | // the RFC does not allow them undecoded anywhere, but we do |
| 3657 | QTest::newRow(dataTag: "encoded-reserved" ) << QUrl("x://\"<>^\\{|}:\"<>^\\{|}@host/\"<>^\\{|}?\"<>^\\{|}#\"<>^\\{|}" ) |
| 3658 | << int(QUrl::FullyEncoded) |
| 3659 | << "%22%3C%3E%5E%5C%7B%7C%7D" << "%22%3C%3E%5E%5C%7B%7C%7D" |
| 3660 | << "%22%3C%3E%5E%5C%7B%7C%7D:%22%3C%3E%5E%5C%7B%7C%7D" |
| 3661 | << "host" << "%22%3C%3E%5E%5C%7B%7C%7D:%22%3C%3E%5E%5C%7B%7C%7D@host" |
| 3662 | << "/%22%3C%3E%5E%5C%7B%7C%7D" << "%22%3C%3E%5E%5C%7B%7C%7D" |
| 3663 | << "%22%3C%3E%5E%5C%7B%7C%7D" |
| 3664 | << "x://%22%3C%3E%5E%5C%7B%7C%7D:%22%3C%3E%5E%5C%7B%7C%7D@host/%22%3C%3E%5E%5C%7B%7C%7D" |
| 3665 | "?%22%3C%3E%5E%5C%7B%7C%7D#%22%3C%3E%5E%5C%7B%7C%7D" ; |
| 3666 | QTest::newRow(dataTag: "decoded-reserved" ) << QUrl("x://%22%3C%3E%5E%5C%7B%7C%7D:%22%3C%3E%5E%5C%7B%7C%7D@host" |
| 3667 | "/%22%3C%3E%5E%5C%7B%7C%7D?%22%3C%3E%5E%5C%7B%7C%7D#%22%3C%3E%5E%5C%7B%7C%7D" ) |
| 3668 | << int(QUrl::DecodeReserved) |
| 3669 | << "\"<>^\\{|}" << "\"<>^\\{|}" << "\"<>^\\{|}:\"<>^\\{|}" |
| 3670 | << "host" << "\"<>^\\{|}:\"<>^\\{|}@host" |
| 3671 | << "/\"<>^\\{|}" << "\"<>^\\{|}" << "\"<>^\\{|}" |
| 3672 | << "x://\"<>^\\{|}:\"<>^\\{|}@host/\"<>^\\{|}?\"<>^\\{|}#\"<>^\\{|}" ; |
| 3673 | |
| 3674 | |
| 3675 | // Beauty is in the eye of the beholder |
| 3676 | // Test PrettyDecoder against our expectations |
| 3677 | |
| 3678 | // spaces and unicode are considered pretty and are decoded |
| 3679 | // this includes hostnames |
| 3680 | QTest::newRow(dataTag: "pretty-spaces-unicode" ) << QUrl("x://%20%c3%a9:%c3%a9%20@XN--SMRBRD-cyad.example.NO/%c3%a9%20?%20%c3%a9#%c3%a9%20" ) |
| 3681 | << int(QUrl::PrettyDecoded) |
| 3682 | << QString::fromUtf8(str: " é" ) << QString::fromUtf8(str: "é " ) |
| 3683 | << QString::fromUtf8(str: " é:é " ) |
| 3684 | << QString::fromUtf8(str: "smørbrød.example.no" ) |
| 3685 | << QString::fromUtf8(str: " é:é @smørbrød.example.no" ) |
| 3686 | << QString::fromUtf8(str: "/é " ) << QString::fromUtf8(str: " é" ) |
| 3687 | << QString::fromUtf8(str: "é " ) |
| 3688 | << QString::fromUtf8(str: "x:// é:é @smørbrød.example.no/é ? é#é " ); |
| 3689 | |
| 3690 | // the pretty form decodes all unambiguous gen-delims in the individual parts |
| 3691 | QTest::newRow(dataTag: "pretty-gendelims" ) << QUrl("x://%5b%3a%40%2f%3f%23%5d:%5b%40%2f%3f%23%5d@host/%3f%23?%23" ) |
| 3692 | << int(QUrl::PrettyDecoded) |
| 3693 | << "[:@/?#]" << "[@/?#]" << "[%3A@/?#]:[@/?#]" |
| 3694 | << "host" << "%5B%3A%40/?#%5D:%5B%40/?#%5D@host" |
| 3695 | << "/?#" << "#" << "" |
| 3696 | << "x://%5B%3A%40%2F%3F%23%5D:%5B%40%2F%3F%23%5D@host/%3F%23?%23" ; |
| 3697 | |
| 3698 | // the pretty form keeps the other characters decoded everywhere |
| 3699 | // except when rebuilding the full URL, when we only allow "{}" to remain decoded |
| 3700 | QTest::newRow(dataTag: "pretty-reserved" ) << QUrl("x://\"<>^\\{|}:\"<>^\\{|}@host/\"<>^\\{|}?\"<>^\\{|}#\"<>^\\{|}" ) |
| 3701 | << int(QUrl::PrettyDecoded) |
| 3702 | << "\"<>^\\{|}" << "\"<>^\\{|}" << "\"<>^\\{|}:\"<>^\\{|}" |
| 3703 | << "host" << "\"<>^\\{|}:\"<>^\\{|}@host" |
| 3704 | << "/\"<>^\\{|}" << "\"<>^\\{|}" << "\"<>^\\{|}" |
| 3705 | << "x://%22%3C%3E%5E%5C%7B%7C%7D:%22%3C%3E%5E%5C%7B%7C%7D@host/%22%3C%3E%5E%5C%7B%7C%7D" |
| 3706 | "?%22%3C%3E%5E%5C%7B%7C%7D#%22%3C%3E%5E%5C%7B%7C%7D" ; |
| 3707 | } |
| 3708 | |
| 3709 | void tst_QUrl::componentEncodings() |
| 3710 | { |
| 3711 | QFETCH(QUrl, url); |
| 3712 | QFETCH(int, encoding); |
| 3713 | QFETCH(QString, userName); |
| 3714 | QFETCH(QString, password); |
| 3715 | QFETCH(QString, userInfo); |
| 3716 | QFETCH(QString, host); |
| 3717 | QFETCH(QString, authority); |
| 3718 | QFETCH(QString, path); |
| 3719 | QFETCH(QString, query); |
| 3720 | QFETCH(QString, fragment); |
| 3721 | QFETCH(QString, toString); |
| 3722 | |
| 3723 | QUrl::ComponentFormattingOptions formatting(encoding); |
| 3724 | QCOMPARE(url.userName(formatting), userName); |
| 3725 | QCOMPARE(url.password(formatting), password); |
| 3726 | QCOMPARE(url.userInfo(formatting), userInfo); |
| 3727 | QCOMPARE(url.host(formatting), host); |
| 3728 | QCOMPARE(url.authority(formatting), authority); |
| 3729 | QCOMPARE(url.path(formatting), path); |
| 3730 | QCOMPARE(url.query(formatting), query); |
| 3731 | QCOMPARE(url.fragment(formatting), fragment); |
| 3732 | QCOMPARE(url.toString(formatting), |
| 3733 | (((QString(toString ))))); // the weird () and space is to align the output |
| 3734 | |
| 3735 | // repeat with the URL we got from toString |
| 3736 | QUrl url2(toString); |
| 3737 | QCOMPARE(url2.userName(formatting), userName); |
| 3738 | QCOMPARE(url2.password(formatting), password); |
| 3739 | QCOMPARE(url2.userInfo(formatting), userInfo); |
| 3740 | QCOMPARE(url2.host(formatting), host); |
| 3741 | QCOMPARE(url2.authority(formatting), authority); |
| 3742 | QCOMPARE(url2.path(formatting), path); |
| 3743 | QCOMPARE(url2.query(formatting), query); |
| 3744 | QCOMPARE(url2.fragment(formatting), fragment); |
| 3745 | QCOMPARE(url2.toString(formatting), toString); |
| 3746 | |
| 3747 | // and use the comparison operator |
| 3748 | QCOMPARE(url2, url); |
| 3749 | } |
| 3750 | |
| 3751 | enum Component { |
| 3752 | Scheme = 0x01, |
| 3753 | UserName = 0x02, |
| 3754 | Password = 0x04, |
| 3755 | UserInfo = UserName | Password, |
| 3756 | Host = 0x08, |
| 3757 | Port = 0x10, |
| 3758 | Authority = UserInfo | Host | Port, |
| 3759 | Path = 0x20, |
| 3760 | Hierarchy = Authority | Path, |
| 3761 | Query = 0x40, |
| 3762 | Fragment = 0x80, |
| 3763 | FullUrl = 0xff |
| 3764 | }; |
| 3765 | |
| 3766 | void tst_QUrl::setComponents_data() |
| 3767 | { |
| 3768 | QTest::addColumn<QUrl>(name: "original" ); |
| 3769 | QTest::addColumn<int>(name: "component" ); |
| 3770 | QTest::addColumn<QString>(name: "newValue" ); |
| 3771 | QTest::addColumn<int>(name: "parsingMode" ); |
| 3772 | QTest::addColumn<bool>(name: "isValid" ); |
| 3773 | QTest::addColumn<int>(name: "encoding" ); |
| 3774 | QTest::addColumn<QString>(name: "output" ); |
| 3775 | QTest::addColumn<QString>(name: "toString" ); |
| 3776 | |
| 3777 | const int Tolerant = QUrl::TolerantMode; |
| 3778 | const int Strict = QUrl::StrictMode; |
| 3779 | const int Decoded = QUrl::DecodedMode; |
| 3780 | const int PrettyDecoded = QUrl::PrettyDecoded; |
| 3781 | const int FullyDecoded = QUrl::FullyDecoded; |
| 3782 | |
| 3783 | // -- test empty vs null -- |
| 3784 | // there's no empty-but-present scheme or path |
| 3785 | // a URL with an empty scheme is a "URI reference" |
| 3786 | // and the path is always non-empty if it's present |
| 3787 | QTest::newRow(dataTag: "scheme-null" ) << QUrl("http://example.com" ) |
| 3788 | << int(Scheme) << QString() << Tolerant << true |
| 3789 | << PrettyDecoded << QString() << "//example.com" ; |
| 3790 | QTest::newRow(dataTag: "scheme-empty" ) << QUrl("http://example.com" ) |
| 3791 | << int(Scheme) << "" << Tolerant << true |
| 3792 | << PrettyDecoded << "" << "//example.com" ; |
| 3793 | QTest::newRow(dataTag: "path-null" ) << QUrl("http://example.com/path" ) |
| 3794 | << int(Path) << QString() << Tolerant << true |
| 3795 | << PrettyDecoded << QString() << "http://example.com" ; |
| 3796 | QTest::newRow(dataTag: "path-empty" ) << QUrl("http://example.com/path" ) |
| 3797 | << int(Path) << "" << Tolerant << true |
| 3798 | << PrettyDecoded << "" << "http://example.com" ; |
| 3799 | // If the %3A gets decoded to ":", the URL becomes invalid; |
| 3800 | // see test path-invalid-1 below |
| 3801 | QTest::newRow(dataTag: "path-%3A-before-slash" ) << QUrl() |
| 3802 | << int(Path) << "c%3A/" << Tolerant << true |
| 3803 | << PrettyDecoded << "c%3A/" << "c%3A/" ; |
| 3804 | QTest::newRow(dataTag: "path-doubleslash" ) << QUrl("http://example.com" ) |
| 3805 | << int(Path) << "//path" << Tolerant << true |
| 3806 | << PrettyDecoded << "//path" << "http://example.com//path" ; |
| 3807 | QTest::newRow(dataTag: "path-withdotdot" ) << QUrl("file:///tmp" ) |
| 3808 | << int(Path) << "//tmp/..///root/." << Tolerant << true |
| 3809 | << PrettyDecoded << "//tmp/..///root/." << "file:////tmp/..///root/." ; |
| 3810 | |
| 3811 | // the other fields can be present and be empty |
| 3812 | // that is, their delimiters would be present, but there would be nothing to one side |
| 3813 | QTest::newRow(dataTag: "userinfo-null" ) << QUrl("http://user:pass@example.com" ) |
| 3814 | << int(UserInfo) << QString() << Tolerant << true |
| 3815 | << PrettyDecoded << QString() << "http://example.com" ; |
| 3816 | QTest::newRow(dataTag: "userinfo-empty" ) << QUrl("http://user:pass@example.com" ) |
| 3817 | << int(UserInfo) << "" << Tolerant << true |
| 3818 | << PrettyDecoded << "" << "http://@example.com" ; |
| 3819 | QTest::newRow(dataTag: "userinfo-colon" ) << QUrl("http://user@example.com" ) |
| 3820 | << int(UserInfo) << ":" << Tolerant << true |
| 3821 | << PrettyDecoded << ":" << "http://:@example.com" ; |
| 3822 | QTest::newRow(dataTag: "username-null" ) << QUrl("http://user@example.com" ) |
| 3823 | << int(UserName) << QString() << Tolerant << true |
| 3824 | << PrettyDecoded << QString() << "http://example.com" ; |
| 3825 | QTest::newRow(dataTag: "username-empty" ) << QUrl("http://user@example.com" ) |
| 3826 | << int(UserName) << "" << Tolerant << true |
| 3827 | << PrettyDecoded << "" << "http://@example.com" ; |
| 3828 | QTest::newRow(dataTag: "username-empty-password-nonempty" ) << QUrl("http://user:pass@example.com" ) |
| 3829 | << int(UserName) << "" << Tolerant << true |
| 3830 | << PrettyDecoded << "" << "http://:pass@example.com" ; |
| 3831 | QTest::newRow(dataTag: "username-empty-password-empty" ) << QUrl("http://user:@example.com" ) |
| 3832 | << int(UserName) << "" << Tolerant << true |
| 3833 | << PrettyDecoded << "" << "http://:@example.com" ; |
| 3834 | QTest::newRow(dataTag: "password-null" ) << QUrl("http://user:pass@example.com" ) |
| 3835 | << int(Password) << QString() << Tolerant << true |
| 3836 | << PrettyDecoded << QString() << "http://user@example.com" ; |
| 3837 | QTest::newRow(dataTag: "password-empty" ) << QUrl("http://user:pass@example.com" ) |
| 3838 | << int(Password) << "" << Tolerant << true |
| 3839 | << PrettyDecoded << "" << "http://user:@example.com" ; |
| 3840 | QTest::newRow(dataTag: "host-null" ) << QUrl("foo://example.com/path" ) |
| 3841 | << int(Host) << QString() << Tolerant << true |
| 3842 | << PrettyDecoded << QString() << "foo:/path" ; |
| 3843 | QTest::newRow(dataTag: "host-empty" ) << QUrl("foo://example.com/path" ) |
| 3844 | << int(Host) << "" << Tolerant << true |
| 3845 | << PrettyDecoded << QString() << "foo:///path" ; |
| 3846 | QTest::newRow(dataTag: "authority-null" ) << QUrl("foo://example.com/path" ) |
| 3847 | << int(Authority) << QString() << Tolerant << true |
| 3848 | << PrettyDecoded << QString() << "foo:/path" ; |
| 3849 | QTest::newRow(dataTag: "authority-empty" ) << QUrl("foo://example.com/path" ) |
| 3850 | << int(Authority) << "" << Tolerant << true |
| 3851 | << PrettyDecoded << QString() << "foo:///path" ; |
| 3852 | QTest::newRow(dataTag: "query-null" ) << QUrl("http://example.com/?q=foo" ) |
| 3853 | << int(Query) << QString() << Tolerant << true |
| 3854 | << PrettyDecoded << QString() << "http://example.com/" ; |
| 3855 | QTest::newRow(dataTag: "query-empty" ) << QUrl("http://example.com/?q=foo" ) |
| 3856 | << int(Query) << "" << Tolerant << true |
| 3857 | << PrettyDecoded << QString() << "http://example.com/?" ; |
| 3858 | QTest::newRow(dataTag: "fragment-null" ) << QUrl("http://example.com/#bar" ) |
| 3859 | << int(Fragment) << QString() << Tolerant << true |
| 3860 | << PrettyDecoded << QString() << "http://example.com/" ; |
| 3861 | QTest::newRow(dataTag: "fragment-empty" ) << QUrl("http://example.com/#bar" ) |
| 3862 | << int(Fragment) << "" << Tolerant << true |
| 3863 | << PrettyDecoded << "" << "http://example.com/#" ; |
| 3864 | |
| 3865 | // -- test some non-valid components -- |
| 3866 | QTest::newRow(dataTag: "invalid-scheme-1" ) << QUrl("http://example.com" ) |
| 3867 | << int(Scheme) << "1http" << Tolerant << false |
| 3868 | << PrettyDecoded << "" << "" ; |
| 3869 | QTest::newRow(dataTag: "invalid-scheme-2" ) << QUrl("http://example.com" ) |
| 3870 | << int(Scheme) << "http%40" << Tolerant << false |
| 3871 | << PrettyDecoded << "" << "" ; |
| 3872 | QTest::newRow(dataTag: "invalid-scheme-3" ) << QUrl("http://example.com" ) |
| 3873 | << int(Scheme) << "http%61" << Strict << false |
| 3874 | << PrettyDecoded << "" << "" ; |
| 3875 | |
| 3876 | QTest::newRow(dataTag: "invalid-username-1" ) << QUrl("http://example.com" ) |
| 3877 | << int(UserName) << "{}" << Strict << false |
| 3878 | << PrettyDecoded << "" << "" ; |
| 3879 | QTest::newRow(dataTag: "invalid-username-2" ) << QUrl("http://example.com" ) |
| 3880 | << int(UserName) << "foo/bar" << Strict << false |
| 3881 | << PrettyDecoded << "" << "" ; |
| 3882 | QTest::newRow(dataTag: "invalid-username-3" ) << QUrl("http://example.com" ) |
| 3883 | << int(UserName) << "foo:bar" << Strict << false |
| 3884 | << PrettyDecoded << "" << "" ; |
| 3885 | QTest::newRow(dataTag: "invalid-password-1" ) << QUrl("http://example.com" ) |
| 3886 | << int(Password) << "{}" << Strict << false |
| 3887 | << PrettyDecoded << "" << "" ; |
| 3888 | QTest::newRow(dataTag: "invalid-password-2" ) << QUrl("http://example.com" ) |
| 3889 | << int(Password) << "foo/bar" << Strict << false |
| 3890 | << PrettyDecoded << "" << "" ; |
| 3891 | QTest::newRow(dataTag: "invalid-password-3" ) << QUrl("http://example.com" ) |
| 3892 | << int(Password) << "foo:bar" << Strict << false |
| 3893 | << PrettyDecoded << "" << "" ; |
| 3894 | QTest::newRow(dataTag: "invalid-userinfo-1" ) << QUrl("http://example.com" ) |
| 3895 | << int(UserInfo) << "{}" << Strict << false |
| 3896 | << PrettyDecoded << "" << "" ; |
| 3897 | QTest::newRow(dataTag: "invalid-userinfo-2" ) << QUrl("http://example.com" ) |
| 3898 | << int(UserInfo) << "foo/bar" << Strict << false |
| 3899 | << PrettyDecoded << "" << "" ; |
| 3900 | |
| 3901 | QTest::newRow(dataTag: "invalid-host-1" ) << QUrl("http://example.com" ) |
| 3902 | << int(Host) << "-not-valid-" << Tolerant << false |
| 3903 | << PrettyDecoded << "" << "" ; |
| 3904 | QTest::newRow(dataTag: "invalid-host-2" ) << QUrl("http://example.com" ) |
| 3905 | << int(Host) << "%31%30.%30.%30.%31" << Strict << false |
| 3906 | << PrettyDecoded << "" << "" ; |
| 3907 | QTest::newRow(dataTag: "invalid-authority-1" ) << QUrl("http://example.com" ) |
| 3908 | << int(Authority) << "-not-valid-" << Tolerant << false |
| 3909 | << PrettyDecoded << "" << "" ; |
| 3910 | QTest::newRow(dataTag: "invalid-authority-2" ) << QUrl("http://example.com" ) |
| 3911 | << int(Authority) << "%31%30.%30.%30.%31" << Strict << false |
| 3912 | << PrettyDecoded << "" << "" ; |
| 3913 | |
| 3914 | QTest::newRow(dataTag: "invalid-path-0" ) << QUrl("http://example.com" ) |
| 3915 | << int(Path) << "{}" << Strict << false |
| 3916 | << PrettyDecoded << "" << "" ; |
| 3917 | QTest::newRow(dataTag: "invalid-query-1" ) << QUrl("http://example.com" ) |
| 3918 | << int(Query) << "{}" << Strict << false |
| 3919 | << PrettyDecoded << "" << "" ; |
| 3920 | QTest::newRow(dataTag: "invalid-fragment-1" ) << QUrl("http://example.com" ) |
| 3921 | << int(Fragment) << "{}" << Strict << false |
| 3922 | << PrettyDecoded << "" << "" ; |
| 3923 | |
| 3924 | // these test cases are "compound invalid": |
| 3925 | // they produces isValid == false, but the original is still available |
| 3926 | QTest::newRow(dataTag: "invalid-path-1" ) << QUrl("/relative" ) |
| 3927 | << int(Path) << "c:/" << Strict << false |
| 3928 | << PrettyDecoded << "c:/" << "" ; |
| 3929 | QTest::newRow(dataTag: "invalid-path-2" ) << QUrl("http://example.com" ) |
| 3930 | << int(Path) << "relative" << Strict << false |
| 3931 | << PrettyDecoded << "relative" << "" ; |
| 3932 | QTest::newRow(dataTag: "invalid-path-3" ) << QUrl("trash:/" ) |
| 3933 | << int(Path) << "//path" << Tolerant << false |
| 3934 | << PrettyDecoded << "//path" << "" ; |
| 3935 | |
| 3936 | // -- test bad percent encoding -- |
| 3937 | // unnecessary to test the scheme, since percent-decoding is not performed in it; |
| 3938 | // see tests above |
| 3939 | QTest::newRow(dataTag: "bad-percent-username" ) << QUrl("http://example.com" ) |
| 3940 | << int(UserName) << "bar%foo" << Strict << false |
| 3941 | << PrettyDecoded << "" << "" ; |
| 3942 | QTest::newRow(dataTag: "bad-percent-password" ) << QUrl("http://user@example.com" ) |
| 3943 | << int(Password) << "bar%foo" << Strict << false |
| 3944 | << PrettyDecoded << "" << "" ; |
| 3945 | QTest::newRow(dataTag: "bad-percent-userinfo-1" ) << QUrl("http://example.com" ) |
| 3946 | << int(UserInfo) << "bar%foo" << Strict << false |
| 3947 | << PrettyDecoded << "" << "" ; |
| 3948 | QTest::newRow(dataTag: "bad-percent-userinfo-2" ) << QUrl("http://example.com" ) |
| 3949 | << int(UserInfo) << "bar%:foo" << Strict << false |
| 3950 | << PrettyDecoded << "" << "" ; |
| 3951 | QTest::newRow(dataTag: "bad-percent-userinfo-3" ) << QUrl("http://example.com" ) |
| 3952 | << int(UserInfo) << "bar:%foo" << Strict << false |
| 3953 | << PrettyDecoded << "" << "" ; |
| 3954 | QTest::newRow(dataTag: "bad-percent-authority-1" ) << QUrl("http://example.com" ) |
| 3955 | << int(Authority) << "bar%foo@example.org" << Strict << false |
| 3956 | << PrettyDecoded << "" << "" ; |
| 3957 | QTest::newRow(dataTag: "bad-percent-authority-2" ) << QUrl("http://example.com" ) |
| 3958 | << int(Authority) << "bar%:foo@example.org" << Strict << false |
| 3959 | << PrettyDecoded << "" << "" ; |
| 3960 | QTest::newRow(dataTag: "bad-percent-authority-3" ) << QUrl("http://example.com" ) |
| 3961 | << int(Authority) << "bar:%foo@example.org" << Strict << false |
| 3962 | << PrettyDecoded << "" << "" ; |
| 3963 | QTest::newRow(dataTag: "bad-percent-authority-4" ) << QUrl("http://example.com" ) |
| 3964 | << int(Authority) << "bar:foo@bar%foo" << Strict << false |
| 3965 | << PrettyDecoded << "" << "" ; |
| 3966 | QTest::newRow(dataTag: "bad-percent-host" ) << QUrl("http://example.com" ) |
| 3967 | << int(Host) << "bar%foo" << Strict << false |
| 3968 | << PrettyDecoded << "" << "" ; |
| 3969 | QTest::newRow(dataTag: "bad-percent-path" ) << QUrl("http://example.com" ) |
| 3970 | << int(Path) << "/bar%foo" << Strict << false |
| 3971 | << PrettyDecoded << "" << "" ; |
| 3972 | QTest::newRow(dataTag: "bad-percent-query" ) << QUrl("http://example.com" ) |
| 3973 | << int(Query) << "bar%foo" << Strict << false |
| 3974 | << PrettyDecoded << "" << "" ; |
| 3975 | QTest::newRow(dataTag: "bad-percent-fragment" ) << QUrl("http://example.com" ) |
| 3976 | << int(Fragment) << "bar%foo" << Strict << false |
| 3977 | << PrettyDecoded << "" << "" ; |
| 3978 | |
| 3979 | // -- test decoded behaviour -- |
| 3980 | // '%' characters are not permitted in the scheme, this tests that it fails to set anything |
| 3981 | QTest::newRow(dataTag: "invalid-scheme-encode" ) << QUrl("http://example.com" ) |
| 3982 | << int(Scheme) << "http%61" << Decoded << false |
| 3983 | << PrettyDecoded << "" << "" ; |
| 3984 | QTest::newRow(dataTag: "username-encode" ) << QUrl("http://example.com" ) |
| 3985 | << int(UserName) << "h%61llo:world" << Decoded << true |
| 3986 | << PrettyDecoded << "h%2561llo:world" << "http://h%2561llo%3Aworld@example.com" ; |
| 3987 | QTest::newRow(dataTag: "password-encode" ) << QUrl("http://example.com" ) |
| 3988 | << int(Password) << "h%61llo:world@" << Decoded << true |
| 3989 | << PrettyDecoded << "h%2561llo:world@" << "http://:h%2561llo:world%40@example.com" ; |
| 3990 | // '%' characters are not permitted in the hostname, these test that it fails to set anything |
| 3991 | QTest::newRow(dataTag: "invalid-host-encode" ) << QUrl("http://example.com" ) |
| 3992 | << int(Host) << "ex%61mple.com" << Decoded << false |
| 3993 | << PrettyDecoded << "" << "" ; |
| 3994 | QTest::newRow(dataTag: "path-encode" ) << QUrl("http://example.com/foo" ) |
| 3995 | << int(Path) << "/bar%23" << Decoded << true |
| 3996 | << PrettyDecoded << "/bar%2523" << "http://example.com/bar%2523" ; |
| 3997 | QTest::newRow(dataTag: "query-encode" ) << QUrl("http://example.com/foo?q" ) |
| 3998 | << int(Query) << "bar%23" << Decoded << true |
| 3999 | << PrettyDecoded << "bar%2523" << "http://example.com/foo?bar%2523" ; |
| 4000 | QTest::newRow(dataTag: "fragment-encode" ) << QUrl("http://example.com/foo#z" ) |
| 4001 | << int(Fragment) << "bar%23" << Decoded << true |
| 4002 | << PrettyDecoded << "bar%2523" << "http://example.com/foo#bar%2523" ; |
| 4003 | // force decoding |
| 4004 | QTest::newRow(dataTag: "username-decode" ) << QUrl("http://example.com" ) |
| 4005 | << int(UserName) << "hello%3Aworld%25" << Tolerant << true |
| 4006 | << FullyDecoded << "hello:world%" << "http://hello%3Aworld%25@example.com" ; |
| 4007 | QTest::newRow(dataTag: "password-decode" ) << QUrl("http://example.com" ) |
| 4008 | << int(Password) << "}}>b9o%25kR(" << Tolerant << true |
| 4009 | << FullyDecoded << "}}>b9o%kR(" << "http://:%7D%7D%3Eb9o%25kR(@example.com" ; |
| 4010 | QTest::newRow(dataTag: "path-decode" ) << QUrl("http://example.com/" ) |
| 4011 | << int(Path) << "/bar%25foo" << Tolerant << true |
| 4012 | << FullyDecoded << "/bar%foo" << "http://example.com/bar%25foo" ; |
| 4013 | QTest::newRow(dataTag: "query-decode" ) << QUrl("http://example.com/foo?qq" ) |
| 4014 | << int(Query) << "bar%25foo" << Tolerant << true |
| 4015 | << FullyDecoded << "bar%foo" << "http://example.com/foo?bar%25foo" ; |
| 4016 | QTest::newRow(dataTag: "fragment-decode" ) << QUrl("http://example.com/foo#qq" ) |
| 4017 | << int(Fragment) << "bar%25foo" << Tolerant << true |
| 4018 | << FullyDecoded << "bar%foo" << "http://example.com/foo#bar%25foo" ; |
| 4019 | } |
| 4020 | |
| 4021 | void tst_QUrl::setComponents() |
| 4022 | { |
| 4023 | QFETCH(QUrl, original); |
| 4024 | QUrl copy(original); |
| 4025 | |
| 4026 | QFETCH(int, component); |
| 4027 | QFETCH(int, parsingMode); |
| 4028 | QFETCH(QString, newValue); |
| 4029 | QFETCH(int, encoding); |
| 4030 | QFETCH(QString, output); |
| 4031 | |
| 4032 | switch (component) { |
| 4033 | case Scheme: |
| 4034 | // scheme is only parsed in strict mode |
| 4035 | copy.setScheme(newValue); |
| 4036 | QCOMPARE(copy.scheme(), output); |
| 4037 | break; |
| 4038 | |
| 4039 | case Path: |
| 4040 | copy.setPath(path: newValue, mode: QUrl::ParsingMode(parsingMode)); |
| 4041 | QCOMPARE(copy.path(QUrl::ComponentFormattingOptions(encoding)), output); |
| 4042 | break; |
| 4043 | |
| 4044 | case UserInfo: |
| 4045 | copy.setUserInfo(userInfo: newValue, mode: QUrl::ParsingMode(parsingMode)); |
| 4046 | QCOMPARE(copy.userInfo(QUrl::ComponentFormattingOptions(encoding)), output); |
| 4047 | break; |
| 4048 | |
| 4049 | case UserName: |
| 4050 | copy.setUserName(userName: newValue, mode: QUrl::ParsingMode(parsingMode)); |
| 4051 | QCOMPARE(copy.userName(QUrl::ComponentFormattingOptions(encoding)), output); |
| 4052 | break; |
| 4053 | |
| 4054 | case Password: |
| 4055 | copy.setPassword(password: newValue, mode: QUrl::ParsingMode(parsingMode)); |
| 4056 | QCOMPARE(copy.password(QUrl::ComponentFormattingOptions(encoding)), output); |
| 4057 | break; |
| 4058 | |
| 4059 | case Host: |
| 4060 | copy.setHost(host: newValue, mode: QUrl::ParsingMode(parsingMode)); |
| 4061 | QCOMPARE(copy.host(QUrl::ComponentFormattingOptions(encoding)), output); |
| 4062 | break; |
| 4063 | |
| 4064 | case Authority: |
| 4065 | copy.setAuthority(authority: newValue, mode: QUrl::ParsingMode(parsingMode)); |
| 4066 | QCOMPARE(copy.authority(QUrl::ComponentFormattingOptions(encoding)), output); |
| 4067 | break; |
| 4068 | |
| 4069 | case Query: |
| 4070 | copy.setQuery(query: newValue, mode: QUrl::ParsingMode(parsingMode)); |
| 4071 | QCOMPARE(copy.hasQuery(), !newValue.isNull()); |
| 4072 | QCOMPARE(copy.query(QUrl::ComponentFormattingOptions(encoding)), output); |
| 4073 | break; |
| 4074 | |
| 4075 | case Fragment: |
| 4076 | copy.setFragment(fragment: newValue, mode: QUrl::ParsingMode(parsingMode)); |
| 4077 | QCOMPARE(copy.hasFragment(), !newValue.isNull()); |
| 4078 | QCOMPARE(copy.fragment(QUrl::ComponentFormattingOptions(encoding)), output); |
| 4079 | break; |
| 4080 | } |
| 4081 | |
| 4082 | QFETCH(bool, isValid); |
| 4083 | QCOMPARE(copy.isValid(), isValid); |
| 4084 | |
| 4085 | if (isValid) { |
| 4086 | QFETCH(QString, toString); |
| 4087 | QCOMPARE(copy.toString(), toString); |
| 4088 | // Check round-tripping |
| 4089 | QCOMPARE(QUrl(copy.toString()).toString(), toString); |
| 4090 | } else { |
| 4091 | QVERIFY(copy.toString().isEmpty()); |
| 4092 | } |
| 4093 | } |
| 4094 | |
| 4095 | void tst_QUrl::streaming_data() |
| 4096 | { |
| 4097 | QTest::addColumn<QString>(name: "urlStr" ); |
| 4098 | |
| 4099 | QTest::newRow(dataTag: "origURL" ) << "http://www.website.com/directory/?#ref" ; |
| 4100 | QTest::newRow(dataTag: "urlWithPassAndNoUser" ) << "ftp://:password@ftp.kde.org/path" ; |
| 4101 | QTest::newRow(dataTag: "accentuated" ) << QString::fromUtf8(str: "trash:/été" ); |
| 4102 | QTest::newRow(dataTag: "withPercents" ) << "http://host/path%25path?%3Fque%25ry#%23ref%25" ; |
| 4103 | QTest::newRow(dataTag: "empty" ) << "" ; |
| 4104 | QVERIFY(!QUrl("ptal://mlc:usb" ).isValid()); |
| 4105 | QTest::newRow(dataTag: "invalid" ) << "ptal://mlc:usb" ; |
| 4106 | QTest::newRow(dataTag: "ipv6" ) << "http://[::ffff:129.144.52.38]:81?query" ; |
| 4107 | } |
| 4108 | |
| 4109 | void tst_QUrl::streaming() |
| 4110 | { |
| 4111 | QFETCH(QString, urlStr); |
| 4112 | QUrl url(urlStr); |
| 4113 | |
| 4114 | QByteArray buffer; |
| 4115 | QDataStream writeStream( &buffer, QIODevice::WriteOnly ); |
| 4116 | writeStream << url; |
| 4117 | |
| 4118 | QDataStream stream( buffer ); |
| 4119 | QUrl restored; |
| 4120 | stream >> restored; |
| 4121 | if (url.isValid()) |
| 4122 | QCOMPARE(restored.url(), url.url()); |
| 4123 | else |
| 4124 | QVERIFY(!restored.isValid()); |
| 4125 | } |
| 4126 | |
| 4127 | void tst_QUrl::detach() |
| 4128 | { |
| 4129 | QUrl empty; |
| 4130 | empty.detach(); |
| 4131 | |
| 4132 | QUrl foo("http://www.kde.org" ); |
| 4133 | QUrl foo2 = foo; |
| 4134 | foo2.detach(); // not that it's needed, given that setHost detaches, of course. But this increases coverage :) |
| 4135 | foo2.setHost(host: "www.gnome.org" ); |
| 4136 | QCOMPARE(foo2.host(), QString("www.gnome.org" )); |
| 4137 | QCOMPARE(foo.host(), QString("www.kde.org" )); |
| 4138 | } |
| 4139 | |
| 4140 | // Test accessing the same QUrl from multiple threads concurrently |
| 4141 | // To maximize the chances of a race (and of a report from helgrind), we actually use |
| 4142 | // 10 urls rather than one. |
| 4143 | class UrlStorage |
| 4144 | { |
| 4145 | public: |
| 4146 | UrlStorage() { |
| 4147 | m_urls.resize(asize: 10); |
| 4148 | for (int i = 0 ; i < m_urls.size(); ++i) |
| 4149 | m_urls[i] = QUrl::fromEncoded(url: "http://www.kde.org" , mode: QUrl::StrictMode); |
| 4150 | } |
| 4151 | QVector<QUrl> m_urls; |
| 4152 | }; |
| 4153 | |
| 4154 | static const UrlStorage * s_urlStorage = nullptr; |
| 4155 | |
| 4156 | void tst_QUrl::testThreadingHelper() |
| 4157 | { |
| 4158 | const UrlStorage* storage = s_urlStorage; |
| 4159 | for (const auto &u : storage->m_urls) { |
| 4160 | // QVERIFY/QCOMPARE trigger race conditions in helgrind |
| 4161 | if (!u.isValid()) |
| 4162 | qFatal(msg: "invalid url" ); |
| 4163 | if (u.scheme() != QLatin1String("http" )) |
| 4164 | qFatal(msg: "invalid scheme" ); |
| 4165 | if (!u.toString().startsWith(c: 'h')) |
| 4166 | qFatal(msg: "invalid toString" ); |
| 4167 | QUrl copy(u); |
| 4168 | copy.setHost(host: "www.new-host.com" ); |
| 4169 | QUrl copy2(u); |
| 4170 | copy2.setUserName(userName: "dfaure" ); |
| 4171 | QUrl copy3(u); |
| 4172 | copy3.setUrl(url: "http://www.new-host.com" ); |
| 4173 | QUrl copy4(u); |
| 4174 | copy4.detach(); |
| 4175 | QUrl copy5(u); |
| 4176 | QUrl resolved1 = u.resolved(relative: QUrl("index.html" )); |
| 4177 | Q_UNUSED(resolved1); |
| 4178 | QUrl resolved2 = QUrl("http://www.kde.org" ).resolved(relative: u); |
| 4179 | Q_UNUSED(resolved2); |
| 4180 | QString local = u.toLocalFile(); |
| 4181 | Q_UNUSED(local); |
| 4182 | QTest::qWait(ms: 10); // give time for the other threads to start |
| 4183 | } |
| 4184 | } |
| 4185 | |
| 4186 | #include <QThreadPool> |
| 4187 | #include <QtConcurrent> |
| 4188 | |
| 4189 | void tst_QUrl::testThreading() |
| 4190 | { |
| 4191 | s_urlStorage = new UrlStorage; |
| 4192 | QThreadPool::globalInstance()->setMaxThreadCount(100); |
| 4193 | QFutureSynchronizer<void> sync; |
| 4194 | for (int i = 0; i < 100; ++i) |
| 4195 | sync.addFuture(future: QtConcurrent::run(object: this, fn: &tst_QUrl::testThreadingHelper)); |
| 4196 | sync.waitForFinished(); |
| 4197 | delete s_urlStorage; |
| 4198 | } |
| 4199 | |
| 4200 | void tst_QUrl::matches_data() |
| 4201 | { |
| 4202 | QTest::addColumn<QString>(name: "urlStrOne" ); |
| 4203 | QTest::addColumn<QString>(name: "urlStrTwo" ); |
| 4204 | QTest::addColumn<uint>(name: "options" ); |
| 4205 | QTest::addColumn<bool>(name: "matches" ); |
| 4206 | |
| 4207 | QTest::newRow(dataTag: "matchingString-none" ) << "http://www.website.com/directory/?#ref" |
| 4208 | << "http://www.website.com/directory/?#ref" |
| 4209 | << uint(QUrl::None) << true; |
| 4210 | QTest::newRow(dataTag: "nonMatchingString-none" ) << "http://www.website.com/directory/?#ref" |
| 4211 | << "http://www.nomatch.com/directory/?#ref" |
| 4212 | << uint(QUrl::None) << false; |
| 4213 | QTest::newRow(dataTag: "matchingHost-removePath" ) << "http://www.website.com/directory" |
| 4214 | << "http://www.website.com/differentdir" |
| 4215 | << uint(QUrl::RemovePath) << true; |
| 4216 | QTest::newRow(dataTag: "nonMatchingHost-removePath" ) << "http://www.website.com/directory" |
| 4217 | << "http://www.different.com/differentdir" |
| 4218 | << uint(QUrl::RemovePath) << false; |
| 4219 | QTest::newRow(dataTag: "matchingHost-removePathAuthority" ) << "http://user:pass@www.website.com/directory" |
| 4220 | << "http://www.website.com/differentdir" |
| 4221 | << uint(QUrl::RemovePath | QUrl::RemoveAuthority) |
| 4222 | << true; |
| 4223 | QTest::newRow(dataTag: "nonMatchingHost-removePathAuthority" ) << "http://user:pass@www.website.com/directory" |
| 4224 | << "http://user:pass@www.different.com/differentdir" |
| 4225 | << uint(QUrl::RemovePath | QUrl::RemoveAuthority) |
| 4226 | << true; |
| 4227 | QTest::newRow(dataTag: "matchingHostAuthority-removePathAuthority" ) |
| 4228 | << "http://user:pass@www.website.com/directory" << "http://www.website.com/differentdir" |
| 4229 | << uint(QUrl::RemovePath | QUrl::RemoveAuthority) << true; |
| 4230 | QTest::newRow(dataTag: "nonMatchingAuthority-removePathAuthority" ) |
| 4231 | << "http://user:pass@www.website.com/directory" |
| 4232 | << "http://otheruser:otherpass@www.website.com/directory" |
| 4233 | << uint(QUrl::RemovePath | QUrl::RemoveAuthority) << true; |
| 4234 | QTest::newRow(dataTag: "matchingHost-removePort" ) << "http://example.com" << "http://example.com" |
| 4235 | << uint(QUrl::RemovePort) << true; |
| 4236 | QTest::newRow(dataTag: "nonMatchingHost-removePort" ) << "http://example.com" << "http://example.net" |
| 4237 | << uint(QUrl::RemovePort) << false; |
| 4238 | QTest::newRow(dataTag: "matchingHost-removePassword" ) << "http://example.com" << "http://example.com" |
| 4239 | << uint(QUrl::RemovePassword) << true; |
| 4240 | QTest::newRow(dataTag: "nonMatchingHost-removePassword" ) << "http://example.com" << "http://example.net" |
| 4241 | << uint(QUrl::RemovePassword) << false; |
| 4242 | QTest::newRow(dataTag: "matchingUserName-removePassword" ) << "http://user@example.com" << "http://user@example.com" |
| 4243 | << uint(QUrl::RemovePassword) << true; |
| 4244 | QTest::newRow(dataTag: "nonMatchingUserName-removePassword" ) << "http://user@example.com" << "http://user2@example.com" |
| 4245 | << uint(QUrl::RemovePassword) << false; |
| 4246 | } |
| 4247 | |
| 4248 | void tst_QUrl::matches() |
| 4249 | { |
| 4250 | QFETCH(QString, urlStrOne); |
| 4251 | QFETCH(QString, urlStrTwo); |
| 4252 | QFETCH(uint, options); |
| 4253 | QFETCH(bool, matches); |
| 4254 | |
| 4255 | QUrl urlOne(urlStrOne); |
| 4256 | QUrl urlTwo(urlStrTwo); |
| 4257 | QCOMPARE(urlOne.matches(urlTwo, QUrl::FormattingOptions(options)), matches); |
| 4258 | } |
| 4259 | |
| 4260 | void tst_QUrl::ipv6_zoneId_data() |
| 4261 | { |
| 4262 | QTest::addColumn<QUrl>(name: "url" ); |
| 4263 | QTest::addColumn<QString>(name: "decodedHost" ); |
| 4264 | QTest::addColumn<QString>(name: "prettyHost" ); |
| 4265 | QTest::addColumn<QString>(name: "encodedHost" ); |
| 4266 | |
| 4267 | QTest::newRow(dataTag: "digit" ) << QUrl("x://[::%251]" ) << "::%1" << "::%251" << "::%251" ; |
| 4268 | QTest::newRow(dataTag: "eth0" ) << QUrl("x://[::%25eth0]" ) << "::%eth0" << "::%25eth0" << "::%25eth0" ; |
| 4269 | QTest::newRow(dataTag: "space" ) << QUrl("x://[::%25%20]" ) << "::% " << "::%25 " << "::%25%20" ; |
| 4270 | QTest::newRow(dataTag: "subdelims" ) << QUrl("x://[::%25eth%2B]" ) << "::%eth+" << "::%25eth%2B" << "::%25eth%2B" ; |
| 4271 | QTest::newRow(dataTag: "other" ) << QUrl("x://[::%25^]" ) << "::%^" << "::%25%5E" << "::%25%5E" ; |
| 4272 | QTest::newRow(dataTag: "control" ) << QUrl("x://[::%25%7F]" ) << "::%\x7f" << "::%25%7F" << "::%25%7F" ; |
| 4273 | QTest::newRow(dataTag: "unicode" ) << QUrl("x://[::%25wlán0]" ) << "::%wlán0" << "::%25wlán0" << "::%25wl%C3%A1n0" ; |
| 4274 | QTest::newRow(dataTag: "non-utf8" ) << QUrl("x://[::%25%80]" ) << QString("::%" ) + QChar(QChar::ReplacementCharacter) << "::%25%80" << "::%25%80" ; |
| 4275 | } |
| 4276 | |
| 4277 | void tst_QUrl::ipv6_zoneId() |
| 4278 | { |
| 4279 | QFETCH(QUrl, url); |
| 4280 | QFETCH(QString, decodedHost); |
| 4281 | QFETCH(QString, prettyHost); |
| 4282 | QFETCH(QString, encodedHost); |
| 4283 | |
| 4284 | QVERIFY2(url.isValid(), qPrintable(url.errorString())); |
| 4285 | QCOMPARE(url.host(QUrl::FullyDecoded), decodedHost); |
| 4286 | QCOMPARE(url.host(), decodedHost); |
| 4287 | QCOMPARE(url.host(QUrl::FullyEncoded), encodedHost); |
| 4288 | QCOMPARE(url.toString(), "x://[" + prettyHost + "]" ); |
| 4289 | QCOMPARE(url.toString(QUrl::FullyEncoded), "x://[" + encodedHost + "]" ); |
| 4290 | } |
| 4291 | |
| 4292 | void tst_QUrl::normalizeRemotePaths_data() |
| 4293 | { |
| 4294 | QTest::addColumn<QUrl>(name: "url" ); |
| 4295 | QTest::addColumn<QString>(name: "expected" ); |
| 4296 | |
| 4297 | QTest::newRow(dataTag: "dotdot-slashslash" ) << QUrl("http://qt-project.org/some/long/..//path" ) << "http://qt-project.org/some//path" ; |
| 4298 | QTest::newRow(dataTag: "slashslash-dotdot" ) << QUrl("http://qt-project.org/some//../path" ) << "http://qt-project.org/some/path" ; |
| 4299 | QTest::newRow(dataTag: "slashslash-dotdot2" ) << QUrl("http://qt-project.org/some//path/../" ) << "http://qt-project.org/some//" ; |
| 4300 | QTest::newRow(dataTag: "dot-slash" ) << QUrl("http://qt-project.org/some/./path" ) << "http://qt-project.org/some/path" ; |
| 4301 | QTest::newRow(dataTag: "slashslash-dot-slashslash" ) << QUrl("http://qt-project.org/some//.//path" ) << "http://qt-project.org/some///path" ; |
| 4302 | QTest::newRow(dataTag: "dot-slashslash" ) << QUrl("http://qt-project.org/some/.//path" ) << "http://qt-project.org/some//path" ; |
| 4303 | QTest::newRow(dataTag: "multiple-slashes" ) << QUrl("http://qt-project.org/some//path" ) << "http://qt-project.org/some//path" ; |
| 4304 | QTest::newRow(dataTag: "multiple-slashes4" ) << QUrl("http://qt-project.org/some////path" ) << "http://qt-project.org/some////path" ; |
| 4305 | QTest::newRow(dataTag: "slashes-at-end" ) << QUrl("http://qt-project.org/some//" ) << "http://qt-project.org/some//" ; |
| 4306 | QTest::newRow(dataTag: "dot-dotdot" ) << QUrl("http://qt-project.org/path/./../" ) << "http://qt-project.org/" ; |
| 4307 | QTest::newRow(dataTag: "slash-dot-slash-dot-slash" ) << QUrl("http://qt-project.org/path//.//.//" ) << "http://qt-project.org/path////" ; |
| 4308 | QTest::newRow(dataTag: "dotdot" ) << QUrl("http://qt-project.org/../" ) << "http://qt-project.org/" ; |
| 4309 | QTest::newRow(dataTag: "dotdot-dotdot" ) << QUrl("http://qt-project.org/path/../../" ) << "http://qt-project.org/" ; |
| 4310 | QTest::newRow(dataTag: "dot-dotdot-tail" ) << QUrl("http://qt-project.org/stem/path/./../tail" ) << "http://qt-project.org/stem/tail" ; |
| 4311 | QTest::newRow(dataTag: "slash-dotdot-slash-tail" ) << QUrl("http://qt-project.org/stem/path//..//tail" ) << "http://qt-project.org/stem/path//tail" ; |
| 4312 | } |
| 4313 | |
| 4314 | void tst_QUrl::normalizeRemotePaths() |
| 4315 | { |
| 4316 | QFETCH(QUrl, url); |
| 4317 | QFETCH(QString, expected); |
| 4318 | |
| 4319 | QCOMPARE(url.adjusted(QUrl::NormalizePathSegments).toString(), expected); |
| 4320 | } |
| 4321 | |
| 4322 | QTEST_MAIN(tst_QUrl) |
| 4323 | |
| 4324 | #include "tst_qurl.moc" |
| 4325 | |