From 0e8a2788d84c814b698848b699af8a2c8ba3179f Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 5 Oct 2012 12:13:54 +0200 Subject: Fix Windows: QStandardPath::findExecutable() to check suffixes. Append the Windows executables suffixes from the PATHEXT environment variable. The previous code had a bug since the 'break' statement bailed out of the inner loop only. Factor search code out into a separate functions, avoiding repeated invocations of list.constEnd() and variable assignments in the old code. Add a static function that is called on Unix and on Windows for executable names with a suffix. Call another function applying a candidate list of suffixes in case an executable name without a suffix is passed. Lower case the extensions from PATHEXT, streamline code. Split up the test, add a _data() slot for clarity. Task-number: QTBUG-27457 Change-Id: I2bf34de52aeadddd3b937ad1e22191c3c850fd26 Reviewed-by: Joerg Bornemann --- .../io/qstandardpaths/tst_qstandardpaths.cpp | 105 ++++++++++++++++----- 1 file changed, 79 insertions(+), 26 deletions(-) (limited to 'tests/auto/corelib/io') diff --git a/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp b/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp index cec98450c9..ede029af28 100644 --- a/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp +++ b/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp @@ -43,6 +43,8 @@ #include #include #include +#include +#include #ifdef Q_OS_UNIX #include @@ -63,7 +65,9 @@ private slots: void enableTestMode(); void testLocateAll(); void testDataLocation(); + void testFindExecutable_data(); void testFindExecutable(); + void testFindExecutableLinkToDirectory(); void testRuntimeDirectory(); void testCustomRuntimeDirectory(); void testAllWritableLocations_data(); @@ -264,30 +268,90 @@ void tst_qstandardpaths::testDataLocation() #endif } -void tst_qstandardpaths::testFindExecutable() +#ifndef Q_OS_WIN +// Find "sh" on Unix. +static inline QFileInfo findSh() { - // Search for 'sh' on unix and 'cmd.exe' on Windows -#ifdef Q_OS_WIN - const QString exeName = "cmd.exe"; -#else - const QString exeName = "sh"; + const char *shPaths[] = {"/bin/sh", "/usr/bin/sh", 0}; + for (const char **shPath = shPaths; *shPath; ++shPath) { + const QFileInfo fi = QFileInfo(QLatin1String(*shPath)); + if (fi.exists()) + return fi; + } + return QFileInfo(); +} #endif - const QString result = QStandardPaths::findExecutable(exeName); - QVERIFY(!result.isEmpty()); +void tst_qstandardpaths::testFindExecutable_data() +{ + QTest::addColumn("directory"); + QTest::addColumn("needle"); + QTest::addColumn("expected"); #ifdef Q_OS_WIN - QVERIFY(result.endsWith("/cmd.exe")); + const QFileInfo cmdFi = QFileInfo(QDir::cleanPath(QString::fromLocal8Bit(qgetenv("COMSPEC")))); + const QString cmdPath = cmdFi.absoluteFilePath(); + + Q_ASSERT(cmdFi.exists()); + QTest::newRow("win-cmd") + << QString() << QString::fromLatin1("cmd.eXe") << cmdPath; + QTest::newRow("win-full-path") + << QString() << cmdPath << cmdPath; + QTest::newRow("win-relative-path") + << cmdFi.absolutePath() << QString::fromLatin1("./cmd.exe") << cmdPath; + QTest::newRow("win-cmd-nosuffix") + << QString() << QString::fromLatin1("cmd") << cmdPath; + + if (QSysInfo::windowsVersion() >= QSysInfo::WV_WINDOWS8) { + // The logo executable on Windows 8 is perfectly suited for testing that the + // suffix mechanism is not thrown off by dots in the name. + const QString logo = QLatin1String("microsoft.windows.softwarelogo.showdesktop"); + const QString logoPath = cmdFi.absolutePath() + QLatin1Char('/') + logo + QLatin1String(".exe"); + QTest::newRow("win8-logo") + << QString() << (logo + QLatin1String(".exe")) << logoPath; + QTest::newRow("win8-logo-nosuffix") + << QString() << logo << logoPath; + } #else - QVERIFY(result.endsWith("/bin/sh")); + const QFileInfo shFi = findSh(); + Q_ASSERT(shFi.exists()); + const QString shPath = shFi.absoluteFilePath(); + QTest::newRow("unix-sh") + << QString() << QString::fromLatin1("sh") << shPath; + QTest::newRow("unix-sh-fullpath") + << QString() << shPath << shPath; + QTest::newRow("unix-sh-relativepath") + << QString(shFi.absolutePath()) << QString::fromLatin1("./sh") << shPath; #endif + QTest::newRow("idontexist") + << QString() << QString::fromLatin1("idontexist") << QString(); + QTest::newRow("empty") + << QString() << QString() << QString(); +} - // full path as argument - QCOMPARE(QStandardPaths::findExecutable(result), result); +void tst_qstandardpaths::testFindExecutable() +{ + QFETCH(QString, directory); + QFETCH(QString, needle); + QFETCH(QString, expected); + const bool changeDirectory = !directory.isEmpty(); + const QString currentDirectory = QDir::currentPath(); + if (changeDirectory) + QVERIFY(QDir::setCurrent(directory)); + const QString result = QStandardPaths::findExecutable(needle); + if (changeDirectory) + QVERIFY(QDir::setCurrent(currentDirectory)); - // exe no found - QVERIFY(QStandardPaths::findExecutable("idontexist").isEmpty()); - QVERIFY(QStandardPaths::findExecutable("").isEmpty()); +#ifdef Q_OS_WIN + const Qt::CaseSensitivity sensitivity = Qt::CaseInsensitive; +#else + const Qt::CaseSensitivity sensitivity = Qt::CaseSensitive; +#endif + QVERIFY2(!result.compare(expected, sensitivity), + qPrintable(QString::fromLatin1("Actual: '%1', Expected: '%2'").arg(result, expected))); +} +void tst_qstandardpaths::testFindExecutableLinkToDirectory() +{ // link to directory const QString target = QDir::tempPath() + QDir::separator() + QLatin1String("link.lnk"); QFile::remove(target); @@ -295,17 +359,6 @@ void tst_qstandardpaths::testFindExecutable() QVERIFY(appFile.link(target)); QVERIFY(QStandardPaths::findExecutable(target).isEmpty()); QFile::remove(target); - - // findExecutable with a relative path -#ifdef Q_OS_UNIX - const QString pwd = QDir::currentPath(); - QDir::setCurrent("/bin"); - QStringList possibleResults; - possibleResults << QString::fromLatin1("/bin/sh") << QString::fromLatin1("/usr/bin/sh"); - const QString sh = QStandardPaths::findExecutable("./sh"); - QVERIFY2(possibleResults.contains(sh), qPrintable(sh)); - QDir::setCurrent(pwd); -#endif } void tst_qstandardpaths::testRuntimeDirectory() -- cgit v1.2.3