| 1 | /**************************************************************************** |
| 2 | ** |
| 3 | ** Copyright (C) 2013 BlackBerry Limited. All rights reserved. |
| 4 | ** Contact: https://www.qt.io/licensing/ |
| 5 | ** |
| 6 | ** This file is part of the test suite of the Qt Toolkit. |
| 7 | ** |
| 8 | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ |
| 9 | ** Commercial License Usage |
| 10 | ** Licensees holding valid commercial Qt licenses may use this file in |
| 11 | ** accordance with the commercial license agreement provided with the |
| 12 | ** Software or, alternatively, in accordance with the terms contained in |
| 13 | ** a written agreement between you and The Qt Company. For licensing terms |
| 14 | ** and conditions see https://www.qt.io/terms-conditions. For further |
| 15 | ** information use the contact form at https://www.qt.io/contact-us. |
| 16 | ** |
| 17 | ** GNU General Public License Usage |
| 18 | ** Alternatively, this file may be used under the terms of the GNU |
| 19 | ** General Public License version 3 as published by the Free Software |
| 20 | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT |
| 21 | ** included in the packaging of this file. Please review the following |
| 22 | ** information to ensure the GNU General Public License requirements will |
| 23 | ** be met: https://www.gnu.org/licenses/gpl-3.0.html. |
| 24 | ** |
| 25 | ** $QT_END_LICENSE$ |
| 26 | ** |
| 27 | ****************************************************************************/ |
| 28 | |
| 29 | #include <QtTest/QtTest> |
| 30 | #include <qplatformdefs.h> |
| 31 | |
| 32 | #include <QCoreApplication> |
| 33 | #include <QDebug> |
| 34 | #include <QDir> |
| 35 | #include <QFile> |
| 36 | #include <QFileInfo> |
| 37 | #include <QString> |
| 38 | |
| 39 | #include <private/qfileselector_p.h> |
| 40 | #include <private/qabstractfileengine_p.h> |
| 41 | #include <private/qfsfileengine_p.h> |
| 42 | #include <private/qfilesystemengine_p.h> |
| 43 | |
| 44 | const ushort selectorIndicator = '+'; |
| 45 | |
| 46 | class tst_QFileSelector : public QObject |
| 47 | { |
| 48 | Q_OBJECT |
| 49 | public: |
| 50 | tst_QFileSelector() {} |
| 51 | |
| 52 | private slots: |
| 53 | void basicTest_data(); |
| 54 | void basicTest(); |
| 55 | |
| 56 | void urlConvenience_data(); |
| 57 | void urlConvenience(); |
| 58 | |
| 59 | void addStatics(); |
| 60 | }; |
| 61 | |
| 62 | void tst_QFileSelector::basicTest_data() |
| 63 | { |
| 64 | /* Files existing for this test |
| 65 | * platform/test |
| 66 | * platform/+<platform>/test for all <platform> in QFileSelectorPrivate::platformSelectors() |
| 67 | * extras/test |
| 68 | * extras/test2 to test for when selector directories exist, but don't have the files |
| 69 | * extras/+custom1/test |
| 70 | * extras/+custom1/test3 to test for when base file doesn't exist |
| 71 | * extras/+custom2/test |
| 72 | * extras/+custom3/test |
| 73 | * extras/+custom3/+custom2/test |
| 74 | * extras/+custom3/+custom4/test |
| 75 | * extras/+custom3/+custom5/test |
| 76 | * extras/+custom5/+custom3/test |
| 77 | */ |
| 78 | QTest::addColumn<QString>(name: "testPath" ); |
| 79 | QTest::addColumn<QStringList>(name: "customSelectors" ); |
| 80 | QTest::addColumn<QString>(name: "expectedPath" ); |
| 81 | |
| 82 | QString test("/test" );// '/' is here so dir string can also be selector string |
| 83 | QString test2("/test2" ); |
| 84 | QString test3("/test3" ); |
| 85 | QString expectedPlatform1File(":/platforms" ); |
| 86 | QString expectedPlatform2File("" ); //Only the last selector |
| 87 | QString expectedPlatform3File; // Only the first selector (the family) |
| 88 | #if defined(Q_OS_UNIX) && !defined(Q_OS_ANDROID) && \ |
| 89 | !defined(Q_OS_DARWIN) && !defined(Q_OS_LINUX) && !defined(Q_OS_HAIKU) && !defined(Q_OS_QNX) |
| 90 | /* We are only aware of specific unixes, and do not have test files for any of the others. |
| 91 | However those unixes can get a selector added from the result of a uname call, so this will |
| 92 | lead to a case where we don't have that file so we can't expect the concatenation of platform |
| 93 | selectors to work. It should just find the +unix/test file.*/ |
| 94 | expectedPlatform1File = QString(":/platforms/" ) + QLatin1Char(selectorIndicator) |
| 95 | + QString("unix/test" ); |
| 96 | expectedPlatform2File = QString(":/platforms/test2" ); |
| 97 | #else |
| 98 | QString distributionName; |
| 99 | # if (defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID)) || defined(Q_OS_FREEBSD) || defined(Q_OS_WINRT) |
| 100 | distributionName = QSysInfo::productType(); |
| 101 | # endif |
| 102 | foreach (const QString &selector, QFileSelectorPrivate::platformSelectors()) { |
| 103 | // skip the Linux distribution name (if any) since we don't have files for them |
| 104 | if (selector == distributionName) |
| 105 | continue; |
| 106 | |
| 107 | expectedPlatform1File = expectedPlatform1File + QLatin1Char('/') + QLatin1Char(selectorIndicator) |
| 108 | + selector; |
| 109 | expectedPlatform2File = selector; |
| 110 | if (expectedPlatform3File.isNull()) |
| 111 | expectedPlatform3File = selector; |
| 112 | } |
| 113 | expectedPlatform1File += test; |
| 114 | expectedPlatform2File = QLatin1String(":/platforms/" ) + QLatin1Char(selectorIndicator) |
| 115 | + expectedPlatform2File + test2; |
| 116 | expectedPlatform3File = QLatin1String(":/platforms/" ) + QLatin1Char(selectorIndicator) |
| 117 | + expectedPlatform3File + test3; |
| 118 | #endif |
| 119 | |
| 120 | QTest::newRow(dataTag: "platform1" ) << QString(":/platforms/test" ) << QStringList() |
| 121 | << expectedPlatform1File; |
| 122 | |
| 123 | QTest::newRow(dataTag: "platform2" ) << QString(":/platforms/test2" ) << QStringList() |
| 124 | << expectedPlatform2File; |
| 125 | |
| 126 | QTest::newRow(dataTag: "platform3" ) << QString(":/platforms/test3" ) << QStringList() |
| 127 | << expectedPlatform3File; |
| 128 | |
| 129 | #ifdef Q_OS_MACOS |
| 130 | // special case for compatibility code |
| 131 | QTest::newRow("osx-compat" ) << QString(":/platforms/test4" ) << QStringList() |
| 132 | << ":/platforms/+osx/test4" ; |
| 133 | QTest::newRow("mac-compat" ) << QString(":/platforms/test5" ) << QStringList() |
| 134 | << ":/platforms/+mac/test5" ; |
| 135 | #endif |
| 136 | |
| 137 | QString resourceTestPath(":/extras/test" ); |
| 138 | QString custom1("custom1" ); |
| 139 | QTest::newRow(dataTag: "custom1-noselector" ) << resourceTestPath << QStringList() |
| 140 | << QString(":/extras" ) + test; |
| 141 | |
| 142 | QTest::newRow(dataTag: "custom1-withselector" ) << resourceTestPath << (QStringList() << custom1) |
| 143 | << QString(":/extras/" ) + QLatin1Char(selectorIndicator) + custom1 + test; |
| 144 | |
| 145 | QTest::newRow(dataTag: "customX-withselector-nofile" ) << QString(":/extras/test2" ) << (QStringList() << custom1) |
| 146 | << QString(":/extras/test2" ); |
| 147 | |
| 148 | QTest::newRow(dataTag: "custom1-withselector-nobasefile" ) << QString(":/extras/test3" ) << (QStringList() << custom1) |
| 149 | << QString(":/extras/+custom1/test3" ); |
| 150 | |
| 151 | QString custom2("custom2" ); |
| 152 | QString custom3("custom3" ); |
| 153 | QString custom4("custom4" ); |
| 154 | QString custom5("custom5" ); |
| 155 | QString slash("/" ); |
| 156 | QTest::newRow(dataTag: "custom12" ) << resourceTestPath << (QStringList() << custom1 << custom2) |
| 157 | << QString(":/extras/" ) + QLatin1Char(selectorIndicator) + custom1 + test; |
| 158 | |
| 159 | QTest::newRow(dataTag: "custom21" ) << resourceTestPath << (QStringList() << custom2 << custom1) |
| 160 | << QString(":/extras/" ) + QLatin1Char(selectorIndicator) + custom2 + test; |
| 161 | |
| 162 | QTest::newRow(dataTag: "custom213" ) << resourceTestPath << (QStringList() << custom2 << custom1 << custom3) |
| 163 | << QString(":/extras/" ) + QLatin1Char(selectorIndicator) + custom2 + test; |
| 164 | |
| 165 | QTest::newRow(dataTag: "custom23" ) << resourceTestPath << (QStringList() << custom2 << custom3) |
| 166 | << QString(":/extras/" ) + QLatin1Char(selectorIndicator) + custom2 + test; |
| 167 | |
| 168 | QTest::newRow(dataTag: "custom34nested" ) << resourceTestPath << (QStringList() << custom3 << custom4) |
| 169 | << QString(":/extras/" ) + QLatin1Char(selectorIndicator) + custom3 + slash |
| 170 | + QLatin1Char(selectorIndicator) + custom4 + test; |
| 171 | |
| 172 | QTest::newRow(dataTag: "custom43nested" ) << resourceTestPath << (QStringList() << custom4 << custom3) |
| 173 | << QString(":/extras/" ) + QLatin1Char(selectorIndicator) + custom3 + slash |
| 174 | + QLatin1Char(selectorIndicator) + custom4 + test; |
| 175 | |
| 176 | QTest::newRow(dataTag: "custom35conflict" ) << resourceTestPath << (QStringList() << custom3 << custom5) |
| 177 | << QString(":/extras/" ) + QLatin1Char(selectorIndicator) + custom3 + slash |
| 178 | + QLatin1Char(selectorIndicator) + custom5 + test; |
| 179 | |
| 180 | QTest::newRow(dataTag: "relativePaths" ) << QFINDTESTDATA("extras/test" ) << (QStringList() << custom1) |
| 181 | << QFINDTESTDATA(QString("extras/" ) + QLatin1Char(selectorIndicator) + custom1 |
| 182 | + QString("/test" )); |
| 183 | } |
| 184 | |
| 185 | void tst_QFileSelector::basicTest() |
| 186 | { |
| 187 | QFETCH(QString, testPath); |
| 188 | QFETCH(QStringList, customSelectors); |
| 189 | QFETCH(QString, expectedPath); |
| 190 | |
| 191 | QFileSelector fs; |
| 192 | fs.setExtraSelectors(customSelectors); |
| 193 | QCOMPARE(fs.select(testPath), expectedPath); |
| 194 | } |
| 195 | |
| 196 | void tst_QFileSelector::urlConvenience_data() |
| 197 | { |
| 198 | /* Files existing for this test |
| 199 | * extras/test |
| 200 | * extras/+custom1/test |
| 201 | */ |
| 202 | QTest::addColumn<QUrl>(name: "testUrl" ); |
| 203 | QTest::addColumn<QStringList>(name: "customSelectors" ); |
| 204 | QTest::addColumn<QUrl>(name: "expectedUrl" ); |
| 205 | |
| 206 | QString test("/test" );// '/' is here so dir string can also be selector string |
| 207 | QString custom1("custom1" ); |
| 208 | QString testWithQueryAndFragment("/test?query#Fragment" ); |
| 209 | |
| 210 | QTest::newRow(dataTag: "qrc" ) << QUrl("qrc:///extras/test" ) << (QStringList() << custom1) |
| 211 | << QUrl(QString("qrc:///extras/" ) + QLatin1Char(selectorIndicator) + custom1 + test); |
| 212 | QTest::newRow(dataTag: "qrc with query and fragment" ) << QUrl(QString::fromLatin1(str: "qrc:///extras%1" ).arg(a: testWithQueryAndFragment)) << (QStringList() << custom1) |
| 213 | << QUrl(QString("qrc:///extras/" ) + QLatin1Char(selectorIndicator) + custom1 + testWithQueryAndFragment); |
| 214 | |
| 215 | QString fileBasePath = QFINDTESTDATA("extras/test" ); |
| 216 | QString fileSelectedPath = QFINDTESTDATA(QString("extras/" ) + QLatin1Char(selectorIndicator) |
| 217 | + custom1 + QString("/test" )); |
| 218 | QTest::newRow(dataTag: "file" ) << QUrl::fromLocalFile(localfile: fileBasePath) << (QStringList() << custom1) |
| 219 | << QUrl::fromLocalFile(localfile: fileSelectedPath); |
| 220 | // do not strip off the query and fragment |
| 221 | QString strUrlWithFragment = QString("file://" ) + testWithQueryAndFragment; |
| 222 | QTest::newRow(dataTag: "file with query and fragment" ) << QUrl(strUrlWithFragment) << (QStringList()) << QUrl(strUrlWithFragment); |
| 223 | strUrlWithFragment = QString("file:" ) + testWithQueryAndFragment; |
| 224 | QTest::newRow(dataTag: "file with query and fragment too" ) << QUrl(strUrlWithFragment) << (QStringList()) << QUrl(strUrlWithFragment); |
| 225 | |
| 226 | // http://qt-project.org/images/qtdn/sprites-combined-latest.png is chosen as a representative real world URL |
| 227 | // But note that this test is checking that http urls are NOT selected so it shouldn't be checked |
| 228 | QUrl testHttpUrl("http://qt-project.org/images/sprites-combined-latest.png" ); |
| 229 | QTest::newRow(dataTag: "http" ) << testHttpUrl << (QStringList() << QString("qtdn" )) << testHttpUrl; |
| 230 | } |
| 231 | |
| 232 | void tst_QFileSelector::urlConvenience() |
| 233 | { |
| 234 | QFETCH(QUrl, testUrl); |
| 235 | QFETCH(QStringList, customSelectors); |
| 236 | QFETCH(QUrl, expectedUrl); |
| 237 | |
| 238 | QFileSelector fs; |
| 239 | //All rows of this test use only custom selectors, so should not select before the setExtra call |
| 240 | QCOMPARE(fs.select(testUrl), testUrl); |
| 241 | fs.setExtraSelectors(customSelectors); |
| 242 | QCOMPARE(fs.select(testUrl), expectedUrl); |
| 243 | } |
| 244 | |
| 245 | void tst_QFileSelector::addStatics() |
| 246 | { |
| 247 | QFileSelector fs; |
| 248 | QCOMPARE(fs.select(QStringLiteral(":/extras/test" )), QStringLiteral(":/extras/test" )); |
| 249 | |
| 250 | QFileSelectorPrivate::addStatics(QStringList() << QStringLiteral("custom1" )); |
| 251 | QCOMPARE(fs.select(QStringLiteral(":/extras/test" )), QStringLiteral(":/extras/+custom1/test" )); |
| 252 | } |
| 253 | |
| 254 | QTEST_MAIN(tst_QFileSelector) |
| 255 | #include "tst_qfileselector.moc" |
| 256 | |