| /**************************************************************************** |
| ** |
| ** Copyright (C) 2016 The Qt Company Ltd. |
| ** Contact: https://www.qt.io/licensing/ |
| ** |
| ** This file is part of the test suite of the Qt Toolkit. |
| ** |
| ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ |
| ** Commercial License Usage |
| ** Licensees holding valid commercial Qt licenses may use this file in |
| ** accordance with the commercial license agreement provided with the |
| ** Software or, alternatively, in accordance with the terms contained in |
| ** a written agreement between you and The Qt Company. For licensing terms |
| ** and conditions see https://www.qt.io/terms-conditions. For further |
| ** information use the contact form at https://www.qt.io/contact-us. |
| ** |
| ** GNU General Public License Usage |
| ** Alternatively, this file may be used under the terms of the GNU |
| ** General Public License version 3 as published by the Free Software |
| ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT |
| ** included in the packaging of this file. Please review the following |
| ** information to ensure the GNU General Public License requirements will |
| ** be met: https://www.gnu.org/licenses/gpl-3.0.html. |
| ** |
| ** $QT_END_LICENSE$ |
| ** |
| ****************************************************************************/ |
| |
| #include "tst_qmakelib.h" |
| |
| #include <ioutils.h> |
| |
| using namespace QMakeInternal; |
| |
| void tst_qmakelib::initTestCase() |
| { |
| m_indir = QFINDTESTDATA("testdata"); |
| m_outdir = m_indir + QLatin1String("_build"); |
| m_env.insert(QStringLiteral("E1"), QStringLiteral("env var")); |
| #ifdef Q_OS_WIN |
| m_env.insert(QStringLiteral("COMSPEC"), qgetenv("COMSPEC")); |
| #endif |
| m_prop.insert(ProKey("P1"), ProString("prop val")); |
| m_prop.insert(ProKey("QT_HOST_DATA/get"), ProString(m_indir)); |
| m_prop.insert(ProKey("QT_HOST_DATA/src"), ProString(m_indir)); |
| |
| QVERIFY(!m_indir.isEmpty()); |
| QVERIFY(QDir(m_outdir).removeRecursively()); |
| QVERIFY(QDir().mkpath(m_outdir)); |
| } |
| |
| void tst_qmakelib::cleanupTestCase() |
| { |
| QVERIFY(QDir(m_outdir).removeRecursively()); |
| } |
| |
| void tst_qmakelib::proString() |
| { |
| QString qs1(QStringLiteral("this is a string")); |
| |
| ProString s1(qs1); |
| QCOMPARE(s1.toQString(), QStringLiteral("this is a string")); |
| |
| ProString s2(qs1, 5, 8); |
| QCOMPARE(s2.toQString(), QStringLiteral("is a str")); |
| |
| QCOMPARE(s2.hash(), 0x80000000); |
| qHash(s2); |
| QCOMPARE(s2.hash(), 90404018U); |
| |
| QCOMPARE(s2.mid(0, 10).toQString(), QStringLiteral("is a str")); |
| QCOMPARE(s2.mid(1, 5).toQString(), QStringLiteral("s a s")); |
| QCOMPARE(s2.mid(10, 3).toQString(), QStringLiteral("")); |
| |
| QString qs2(QStringLiteral(" spacy string ")); |
| QCOMPARE(ProString(qs2, 3, 13).trimmed().toQString(), QStringLiteral("spacy string")); |
| QCOMPARE(ProString(qs2, 1, 17).trimmed().toQString(), QStringLiteral("spacy string")); |
| |
| QVERIFY(s2.toQStringRef().string()->isSharedWith(qs1)); |
| s2.prepend(ProString("there ")); |
| QCOMPARE(s2.toQString(), QStringLiteral("there is a str")); |
| QVERIFY(!s2.toQStringRef().string()->isSharedWith(qs1)); |
| |
| ProString s3("this is a longish string with bells and whistles"); |
| s3 = s3.mid(18, 17); |
| // Prepend to detached string with lots of spare space in it. |
| s3.prepend(ProString("another ")); |
| QCOMPARE(s3.toQString(), QStringLiteral("another string with bells")); |
| |
| // Note: The string still has plenty of spare space. |
| s3.append(QLatin1Char('.')); |
| QCOMPARE(s3.toQString(), QStringLiteral("another string with bells.")); |
| s3.append(QLatin1String(" eh?")); |
| QCOMPARE(s3.toQString(), QStringLiteral("another string with bells. eh?")); |
| |
| s3.append(ProString(" yeah!")); |
| QCOMPARE(s3.toQString(), QStringLiteral("another string with bells. eh? yeah!")); |
| |
| bool pending = false; // Not in string, but joining => add space |
| s3.append(ProString("..."), &pending); |
| QCOMPARE(s3.toQString(), QStringLiteral("another string with bells. eh? yeah! ...")); |
| QVERIFY(pending); |
| |
| ProStringList sl1; |
| sl1 << ProString("") << ProString("foo") << ProString("barbaz"); |
| ProString s4a("hallo"); |
| s4a.append(sl1); |
| QCOMPARE(s4a.toQString(), QStringLiteral("hallo foo barbaz")); |
| ProString s4b("hallo"); |
| pending = false; |
| s4b.append(sl1, &pending); |
| QCOMPARE(s4b.toQString(), QStringLiteral("hallo foo barbaz")); |
| ProString s4c; |
| pending = false; |
| s4c.append(sl1, &pending); |
| QCOMPARE(s4c.toQString(), QStringLiteral(" foo barbaz")); |
| // bizarreness |
| ProString s4d("hallo"); |
| pending = false; |
| s4d.append(sl1, &pending, true); |
| QCOMPARE(s4d.toQString(), QStringLiteral("hallo foo barbaz")); |
| ProString s4e; |
| pending = false; |
| s4e.append(sl1, &pending, true); |
| QCOMPARE(s4e.toQString(), QStringLiteral("foo barbaz")); |
| |
| ProStringList sl2; |
| sl2 << ProString("foo"); |
| ProString s5; |
| s5.append(sl2); |
| QCOMPARE(s5.toQString(), QStringLiteral("foo")); |
| QVERIFY(s5.toQStringRef().string()->isSharedWith(*sl2.first().toQStringRef().string())); |
| |
| QCOMPARE(ProString("one") + ProString(" more"), QStringLiteral("one more")); |
| } |
| |
| void tst_qmakelib::proStringList() |
| { |
| ProStringList sl1; |
| sl1 << ProString("qt") << ProString(QLatin1String("is")) |
| << ProString(QStringLiteral("uncool")).mid(2); |
| |
| QCOMPARE(sl1.toQStringList(), QStringList() << "qt" << "is" << "cool"); |
| QCOMPARE(sl1.join(QStringLiteral("~~")), QStringLiteral("qt~~is~~cool")); |
| |
| ProStringList sl2; |
| sl2 << ProString("mostly") << ProString("...") << ProString("is") << ProString("..."); |
| sl1.insertUnique(sl2); |
| QCOMPARE(sl1.toQStringList(), QStringList() << "qt" << "is" << "cool" << "mostly" << "..."); |
| |
| QVERIFY(sl1.contains("cool")); |
| QVERIFY(!sl1.contains("COOL")); |
| QVERIFY(sl1.contains("COOL", Qt::CaseInsensitive)); |
| } |
| |
| void tst_qmakelib::quoteArgUnix_data() |
| { |
| QTest::addColumn<QString>("in"); |
| QTest::addColumn<QString>("out"); |
| |
| static const struct { |
| const char * const in; |
| const char * const out; |
| } vals[] = { |
| { "", "''" }, |
| { "hallo", "hallo" }, |
| { "hallo du", "'hallo du'" }, |
| { "ha'llo", "'ha'\\''llo'" }, |
| }; |
| |
| for (unsigned i = 0; i < sizeof(vals)/sizeof(vals[0]); i++) |
| QTest::newRow(vals[i].in) << QString::fromLatin1(vals[i].in) |
| << QString::fromLatin1(vals[i].out); |
| } |
| |
| void tst_qmakelib::quoteArgUnix() |
| { |
| QFETCH(QString, in); |
| QFETCH(QString, out); |
| |
| QCOMPARE(IoUtils::shellQuoteUnix(in), out); |
| } |
| |
| void tst_qmakelib::quoteArgWin_data() |
| { |
| QTest::addColumn<QString>("in"); |
| QTest::addColumn<QString>("out"); |
| |
| static const struct { |
| const char * const in; |
| const char * const out; |
| } vals[] = { |
| { "", "\"\"" }, |
| { "hallo", "hallo" }, |
| { "hallo du", "\"hallo du\"" }, |
| { "hallo\\", "hallo\\" }, |
| { "hallo du\\", "\"hallo du\\\\\"" }, |
| { "ha\"llo", "\"ha\\\"llo^\"" }, |
| { "ha\\\"llo", "\"ha\\\\\\\"llo^\"" }, |
| }; |
| |
| for (unsigned i = 0; i < sizeof(vals)/sizeof(vals[0]); i++) |
| QTest::newRow(vals[i].in) << QString::fromLatin1(vals[i].in) |
| << QString::fromLatin1(vals[i].out); |
| } |
| |
| void tst_qmakelib::quoteArgWin() |
| { |
| QFETCH(QString, in); |
| QFETCH(QString, out); |
| |
| QCOMPARE(IoUtils::shellQuoteWin(in), out); |
| } |
| |
| void tst_qmakelib::pathUtils() |
| { |
| QString afp = QCoreApplication::applicationFilePath(); |
| QVERIFY(IoUtils::exists(afp)); |
| QVERIFY(!IoUtils::exists(afp + "-tehfail")); |
| QCOMPARE(IoUtils::fileType(afp), IoUtils::FileIsRegular); |
| QString adp = QCoreApplication::applicationDirPath(); |
| QCOMPARE(IoUtils::fileType(adp), IoUtils::FileIsDir); |
| |
| QString fn0 = "file/path"; |
| QVERIFY(IoUtils::isRelativePath(fn0)); |
| |
| QString fn1 = "/a/unix/file/path"; |
| QCOMPARE(IoUtils::pathName(fn1).toString(), QStringLiteral("/a/unix/file/")); |
| QCOMPARE(IoUtils::fileName(fn1).toString(), QStringLiteral("path")); |
| } |
| |
| void tst_qmakelib::ioUtilRelativity_data() |
| { |
| QTest::addColumn<QString>("path"); |
| QTest::addColumn<bool>("relative"); |
| |
| static const struct { |
| const char *name; |
| const char *path; |
| bool relative; |
| } rows[] = { |
| { "resource", ":/resource", |
| #ifdef QMAKE_BUILTIN_PRFS |
| false |
| #else |
| true |
| #endif |
| }, |
| #ifdef Q_OS_WIN // all the complications: |
| // (except UNC: unsupported) |
| { "drive-abs", "c:/path/to/file", false }, |
| { "drive-abs-bs", "c:\\path\\to\\file", false }, |
| { "drive-path", "c:path/to/file.txt", true }, |
| { "drive-path-bs", "c:path\\to\\file.txt", true }, |
| { "rooted", "/Users/qt/bin/true", true }, |
| { "rooted-bs", "\\Users\\qt\\bin\\true", true }, |
| { "drive-rel", "c:file.txt", true }, |
| { "subdir-bs", "path\\to\\file", true }, |
| #else |
| { "rooted", "/usr/bin/false", false }, |
| #endif // Q_OS_WIN |
| { "subdir", "path/to/file", true }, |
| { "simple", "file.name", true }, |
| { "empty", "", true } |
| }; |
| |
| for (unsigned int i = sizeof(rows) / sizeof(rows[0]); i-- > 0; ) |
| QTest::newRow(rows[i].name) << QString::fromLatin1(rows[i].path) |
| << rows[i].relative; |
| } |
| |
| void tst_qmakelib::ioUtilRelativity() |
| { |
| QFETCH(QString, path); |
| QFETCH(bool, relative); |
| |
| QCOMPARE(IoUtils::isRelativePath(path), relative); |
| } |
| |
| void tst_qmakelib::ioUtilResolve_data() |
| { |
| QTest::addColumn<QString>("base"); |
| QTest::addColumn<QString>("path"); |
| QTest::addColumn<QString>("expect"); |
| |
| static const struct { |
| const char *name; |
| const char *base; |
| const char *path; |
| const char *expect; |
| } data[] = { |
| #ifdef Q_OS_WIN // all the complications: |
| { "drive-drive", "a:/ms/dir", "z:/root/file", "z:/root/file" }, |
| { "drive-drive-bs", "a:\\ms\\dir", "z:\\root\\file", "z:/root/file" }, |
| { "drive-root", "a:/ms/dir", "/root/file", "a:/root/file" }, |
| { "drive-root-bs", "a:\\ms\\dir", "\\root\\file", "a:/root/file" }, |
| { "drive-sub", "a:/ms/dir", "sub/file", "a:/ms/dir/sub/file" }, |
| { "drive-sub-bs", "a:\\ms\\dir", "sub\\file", "a:/ms/dir/sub/file" }, |
| { "drive-rel", "a:/ms/dir", "file.txt", "a:/ms/dir/file.txt" }, |
| { "drive-rel-bs", "a:\\ms\\dir", "file.txt", "a:/ms/dir/file.txt" }, |
| #else |
| { "abs-abs", "/a/unix/dir", "/root/file", "/root/file" }, |
| { "abs-sub", "/a/unix/dir", "sub/file", "/a/unix/dir/sub/file" }, |
| { "abs-rel", "/a/unix/dir", "file.txt", "/a/unix/dir/file.txt" }, |
| #endif // Q_OS_WIN |
| }; |
| |
| for (unsigned i = sizeof(data) / sizeof(data[0]); i-- > 0; ) |
| QTest::newRow(data[i].name) << QString::fromLatin1(data[i].base) |
| << QString::fromLatin1(data[i].path) |
| << QString::fromLatin1(data[i].expect); |
| } |
| |
| void tst_qmakelib::ioUtilResolve() |
| { |
| QFETCH(QString, base); |
| QFETCH(QString, path); |
| QFETCH(QString, expect); |
| |
| QCOMPARE(IoUtils::resolvePath(base, path), expect); |
| } |
| |
| void QMakeTestHandler::print(const QString &fileName, int lineNo, int type, const QString &msg) |
| { |
| QString pfx = ((type & QMakeParserHandler::CategoryMask) == QMakeParserHandler::WarningMessage) |
| ? QString::fromLatin1("WARNING: ") : QString(); |
| if (lineNo) |
| doPrint(QStringLiteral("%1%2:%3: %4").arg(pfx, fileName, QString::number(lineNo), msg)); |
| else |
| doPrint(QStringLiteral("%1%2").arg(pfx, msg)); |
| } |
| |
| void QMakeTestHandler::doPrint(const QString &msg) |
| { |
| if (!expected.isEmpty() && expected.first() == msg) { |
| expected.removeAt(0); |
| } else { |
| qWarning("%s", qPrintable(msg)); |
| printed = true; |
| } |
| } |
| |
| QTEST_MAIN(tst_qmakelib) |