File indexing completed on 2024-05-26 05:39:40

0001 /*
0002     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0003     SPDX-FileCopyrightText: 2021 Alexander Lohnau <alexander.lonau@gmx.de>
0004 */
0005 
0006 #include <QSignalSpy>
0007 #include <QStandardPaths>
0008 #include <QTemporaryFile>
0009 #include <QTest>
0010 
0011 #include <KPluginMetaData>
0012 #include <KRunner/AbstractRunnerTest>
0013 #include <KShell>
0014 
0015 #include <clocale>
0016 
0017 class ShellRunnerTest : public KRunner::AbstractRunnerTest
0018 {
0019     Q_OBJECT
0020 
0021 private:
0022     QFileInfo createExecutableFile(const QString &fileName);
0023 
0024 private Q_SLOTS:
0025     void initTestCase();
0026     void testShellrunnerQueries_data();
0027     void testShellrunnerQueries();
0028 };
0029 
0030 void ShellRunnerTest::initTestCase()
0031 {
0032     initProperties();
0033 }
0034 
0035 void ShellRunnerTest::testShellrunnerQueries()
0036 {
0037     QFETCH(int, matchCount);
0038     QFETCH(QString, query);
0039     QFETCH(QString, expectedCommand);
0040     QFETCH(QStringList, expectedENVs);
0041 
0042     const auto matches = launchQuery(query);
0043     QCOMPARE(matches.count(), matchCount);
0044     if (matchCount == 1) {
0045         const QVariantList matchData = manager->matches().constFirst().data().toList();
0046         QCOMPARE(matchData.first().toString(), expectedCommand);
0047         QCOMPARE(matchData.at(1).toStringList(), expectedENVs);
0048     }
0049 }
0050 
0051 void ShellRunnerTest::testShellrunnerQueries_data()
0052 {
0053     QTest::addColumn<int>("matchCount");
0054     QTest::addColumn<QString>("query");
0055     QTest::addColumn<QString>("expectedCommand");
0056     QTest::addColumn<QStringList>("expectedENVs");
0057 
0058     // On The BSDs the path can differ, this will give us the absolute path
0059     const QString executablePath = QStandardPaths::findExecutable("true");
0060     QVERIFY(!executablePath.isEmpty());
0061     // clang-format off
0062     QTest::newRow("Should show result with full executable path")
0063         << 1 << executablePath << executablePath << QStringList{};
0064     QTest::newRow("Should show result with full executable path and args")
0065         << 1 << executablePath + " --help" << executablePath + " --help" << QStringList{};
0066     QTest::newRow("Should bot show result for non-existent path")
0067         << 0 << "/bin/trueeeeeee" << QString() << QStringList{};
0068     QTest::newRow("Should show result for executable name")
0069         << 1 << "true" << executablePath << QStringList{};
0070     QTest::newRow("Should show result for executable name and args")
0071         << 1 << "true --help" << executablePath + " --help" << QStringList{};
0072 
0073     QTest::newRow("Should show result for executable and ENV variables")
0074         << 1 << "LC_ALL=C true" << executablePath << QStringList{"LC_ALL=C"};
0075     QTest::newRow("Should show result for executable + args and ENV variables")
0076         << 1 << "LC_ALL=C true --help" << executablePath + " --help" << QStringList{"LC_ALL=C"};
0077     QTest::newRow("Should show result for executable and multiple ENV variables")
0078         << 1 << "LC_ALL=C TEST=1 true" << executablePath << QStringList{"LC_ALL=C", "TEST=1"};
0079     QTest::newRow("Should show no result for non-existent executable path and ENV variable")
0080         << 0 << "LC_ALL=C /bin/trueeeeeeeeeeee" << "" << QStringList{};
0081 
0082     // Some file we can access with a ~
0083     const QFileInfo testFile = createExecutableFile("test.sh");
0084     const QString testFilePath = testFile.absoluteFilePath();
0085     const QString tildePath = KShell::tildeCollapse(testFilePath);
0086 
0087     QTest::newRow("Should show result for full path with tilde")
0088         << 1 << tildePath << KShell::quoteArg(testFilePath) << QStringList{};
0089     QTest::newRow("Should show result for full path with tilde and envs")
0090         << 1 << "LC_ALL=C " + tildePath << KShell::quoteArg(testFilePath) << QStringList{"LC_ALL=C"};
0091     QTest::newRow("Should show result for full path with tilde + args and envs")
0092         << 1 << "LC_ALL=C " + tildePath + " --help" << KShell::quoteArg(testFilePath) + " --help" << QStringList{"LC_ALL=C"};
0093 
0094     // Some file we can access with a ~ and which has a space in its filename
0095     const QFileInfo testSpaceFile = createExecutableFile("test space.sh");
0096     const QString testSpaceFilePath = testSpaceFile.absoluteFilePath();
0097     const QString tildeSpacePath = KShell::tildeCollapse(testSpaceFile.absoluteFilePath());
0098 
0099     QTest::newRow("Should show no result for full path with tilde and unquoted space")
0100             << 0 << tildeSpacePath << QString() << QStringList{};
0101     QTest::newRow("Should show result for full path with tilde and quoted space")
0102             << 1 << KShell::quoteArg(tildeSpacePath) << KShell::quoteArg(testSpaceFilePath) << QStringList{};
0103     QTest::newRow("Should show result for full path with tilde, quoted space and args")
0104             << 1 << KShell::quoteArg(tildeSpacePath) + " --help"
0105             << KShell::joinArgs({testSpaceFilePath, "--help"}) << QStringList{};
0106     // clang-format on
0107 }
0108 
0109 QFileInfo ShellRunnerTest::createExecutableFile(const QString &fileName)
0110 {
0111     const QString tmpPath = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
0112     QDir(tmpPath).mkpath(".");
0113     QFile testFile(tmpPath + "/" + fileName);
0114     testFile.open(QIODevice::WriteOnly);
0115     testFile.setPermissions(QFile::ExeOwner);
0116     return QFileInfo(testFile);
0117 }
0118 
0119 QTEST_MAIN(ShellRunnerTest)
0120 
0121 #include "shellrunnertest.moc"