3
0
mirror of https://github.com/Qortal/Brooklyn.git synced 2025-02-23 15:45:53 +00:00
2022-04-02 18:24:21 +05:00

291 lines
9.9 KiB
C++

/*
SPDX-FileCopyrightText: 2016-2021 Harald Sitter <sitter@kde.org>
SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
#include <QDebug>
#include <QDir>
#include <QFile>
#include <QObject>
#include <QStandardPaths>
#include <QTest>
#include <QThread>
#include <KSycoca>
#include "../servicerunner.h"
#include <clocale>
#include <optional>
#include <sys/types.h>
#include <unistd.h>
class ServiceRunnerTest : public QObject
{
Q_OBJECT
private Q_SLOTS:
void initTestCase();
void cleanupTestCase();
void testExcutableExactMatch();
void testChromeAppsRelevance();
void testKonsoleVsYakuakeComment();
void testSystemSettings();
void testSystemSettings2();
void testCategories();
void testJumpListActions();
void testINotifyUsage();
};
void ServiceRunnerTest::initTestCase()
{
QStandardPaths::setTestModeEnabled(true);
auto appsPath = QStandardPaths::writableLocation(QStandardPaths::ApplicationsLocation);
QDir(appsPath).removeRecursively();
QVERIFY(QDir().mkpath(appsPath));
auto fixtureDir = QDir(QFINDTESTDATA("fixtures"));
const auto infoList = fixtureDir.entryInfoList(QDir::Files);
for (const auto &fileInfo : infoList) {
auto source = fileInfo.absoluteFilePath();
auto target = appsPath + QDir::separator() + fileInfo.fileName();
QVERIFY2(QFile::copy(fileInfo.absoluteFilePath(), target), qPrintable(QStringLiteral("can't copy %1 => %2").arg(source, target)));
}
setlocale(LC_ALL, "C.utf8");
KSycoca::self()->ensureCacheValid();
// Make sure noDisplay behaves consistently WRT OnlyShowIn etc.
QVERIFY(setenv("XDG_CURRENT_DESKTOP", "KDE", 1) == 0);
// NOTE: noDisplay also includes X-KDE-OnlyShowOnQtPlatforms which is a bit harder to fake
// and not currently under testing anyway.
}
void ServiceRunnerTest::cleanupTestCase()
{
}
void ServiceRunnerTest::testExcutableExactMatch()
{
ServiceRunner runner(this, KPluginMetaData(), QVariantList());
Plasma::RunnerContext context;
context.setQuery(QStringLiteral("Virtual Machine Manager ServiceRunnerTest")); // virt-manager.desktop
runner.match(context);
auto matches = context.matches();
QVERIFY(std::any_of(matches.cbegin(), matches.cend(), [](const Plasma::QueryMatch &match) {
return match.text() == QLatin1String("Virtual Machine Manager ServiceRunnerTest") && match.relevance() == 1;
}));
}
void ServiceRunnerTest::testChromeAppsRelevance()
{
ServiceRunner runner(this, KPluginMetaData(), QVariantList());
Plasma::RunnerContext context;
context.setQuery(QStringLiteral("chrome"));
runner.match(context);
bool chromeFound = false;
bool signalFound = false;
const auto matches = context.matches();
for (const auto &match : matches) {
qDebug() << "matched" << match.text();
if (!match.text().contains(QLatin1String("ServiceRunnerTest"))) {
continue;
}
if (match.text() == QLatin1String("Google Chrome ServiceRunnerTest")) {
QCOMPARE(match.relevance(), 0.8);
chromeFound = true;
} else if (match.text() == QLatin1String("Signal ServiceRunnerTest")) {
// Rates lower because it doesn't have it in the name.
QCOMPARE(match.relevance(), 0.7);
signalFound = true;
}
}
QVERIFY(chromeFound);
QVERIFY(signalFound);
}
void ServiceRunnerTest::testKonsoleVsYakuakeComment()
{
// Yakuake has konsole mentioned in comment, should be rated lower.
ServiceRunner runner(this, KPluginMetaData(), QVariantList());
Plasma::RunnerContext context;
context.setQuery(QStringLiteral("kons"));
runner.match(context);
bool konsoleFound = false;
bool yakuakeFound = false;
const auto matches = context.matches();
for (const auto &match : matches) {
qDebug() << "matched" << match.text();
if (!match.text().contains(QLatin1String("ServiceRunnerTest"))) {
continue;
}
if (match.text() == QLatin1String("Konsole ServiceRunnerTest")) {
QCOMPARE(match.relevance(), 0.99);
konsoleFound = true;
} else if (match.text() == QLatin1String("Yakuake ServiceRunnerTest")) {
// Rates lower because it doesn't have it in the name.
QCOMPARE(match.relevance(), 0.59);
yakuakeFound = true;
}
}
QVERIFY(konsoleFound);
QVERIFY(yakuakeFound);
}
void ServiceRunnerTest::testSystemSettings()
{
// In 5.9.0 'System Settings' suddenly didn't come back as a match for 'settings' anymore.
// System Settings has a noKDE version and a KDE version, if the noKDE version is encountered
// first it will be added to the seen cache, however disqualification of already seen items
// may then also disqualify the KDE version of system settings on account of having already
// seen it. This test makes sure we find the right version.
ServiceRunner runner(this, KPluginMetaData(), QVariantList());
Plasma::RunnerContext context;
context.setQuery(QStringLiteral("settings"));
runner.match(context);
bool systemSettingsFound = false;
bool foreignSystemSettingsFound = false;
const auto matches = context.matches();
for (const auto &match : matches) {
qDebug() << "matched" << match.text();
if (match.text() == QLatin1String("System Settings ServiceRunnerTest")) {
systemSettingsFound = true;
}
if (match.text() == QLatin1String("KDE System Settings ServiceRunnerTest")) {
foreignSystemSettingsFound = true;
}
}
QVERIFY(systemSettingsFound);
QVERIFY(!foreignSystemSettingsFound);
}
void ServiceRunnerTest::testSystemSettings2()
{
ServiceRunner runner(this, KPluginMetaData(), QVariantList());
Plasma::RunnerContext context;
context.setQuery(QStringLiteral("sy"));
runner.match(context);
bool systemSettingsFound = false;
bool foreignSystemSettingsFound = false;
const auto matches = context.matches();
for (const auto &match : matches) {
qDebug() << "matched" << match.text();
if (match.text() == QLatin1String("System Settings ServiceRunnerTest")) {
systemSettingsFound = true;
}
if (match.text() == QLatin1String("KDE System Settings ServiceRunnerTest")) {
foreignSystemSettingsFound = true;
}
}
QVERIFY(systemSettingsFound);
QVERIFY(!foreignSystemSettingsFound);
}
void ServiceRunnerTest::testCategories()
{
ServiceRunner runner(this, KPluginMetaData(), QVariantList());
Plasma::RunnerContext context;
context.setQuery(QStringLiteral("System"));
runner.match(context);
auto matches = context.matches();
QVERIFY(std::any_of(matches.cbegin(), matches.cend(), [](const Plasma::QueryMatch &match) {
return match.text() == QLatin1String("Konsole ServiceRunnerTest") && match.relevance() == 0.64;
}));
// Multiple categories
context.setQuery(QStringLiteral("System KDE TerminalEmulator"));
runner.match(context);
matches = context.matches();
QVERIFY(std::any_of(matches.cbegin(), matches.cend(), [](const Plasma::QueryMatch &match) {
return match.text() == QLatin1String("Konsole ServiceRunnerTest") && match.relevance() == 0.64;
}));
// Multiple categories but at least one doesn't match
context.setQuery(QStringLiteral("System KDE Office"));
runner.match(context);
matches = context.matches();
QVERIFY(std::none_of(matches.cbegin(), matches.cend(), [](const Plasma::QueryMatch &match) {
return match.text() == QLatin1String("Konsole ServiceRunnerTest");
}));
}
void ServiceRunnerTest::testJumpListActions()
{
ServiceRunner runner(this, KPluginMetaData(), QVariantList());
Plasma::RunnerContext context;
context.setQuery(QStringLiteral("open a new window")); // org.kde.konsole.desktop
runner.match(context);
auto matches = context.matches();
QVERIFY(std::any_of(matches.cbegin(), matches.cend(), [](const Plasma::QueryMatch &match) {
return match.text() == QLatin1String("Open a New Window - Konsole ServiceRunnerTest") && match.relevance() == 0.55;
}));
context.setQuery(QStringLiteral("new window"));
runner.match(context);
matches = context.matches();
QVERIFY(std::any_of(matches.cbegin(), matches.cend(), [](const Plasma::QueryMatch &match) {
return match.text() == QLatin1String("Open a New Window - Konsole ServiceRunnerTest") && match.relevance() == 0.5;
}));
context.setQuery(QStringLiteral("new windows"));
runner.match(context);
matches = context.matches();
QVERIFY(std::none_of(matches.cbegin(), matches.cend(), [](const Plasma::QueryMatch &match) {
return match.text() == QLatin1String("Open a New Window - Konsole ServiceRunnerTest");
}));
}
void ServiceRunnerTest::testINotifyUsage()
{
auto inotifyCount = []() -> uint {
uint count = 0;
const QDir procDir(QStringLiteral("/proc/%1/fd").arg(getpid()));
for (const auto &fileInfo : procDir.entryInfoList()) {
if (fileInfo.symLinkTarget().endsWith(QStringLiteral("anon_inode:inotify"))) {
++count;
}
}
return count;
};
const uint originalCount = inotifyCount();
// We'll run this in a new thread so KDirWatch would be led to create a new thread-local watch instance.
// The expectation here is that this KDW instance is not persistently claiming an inotify instance.
bool inotifyCountCool = false;
auto thread = QThread::create([&] {
ServiceRunner runner(nullptr, KPluginMetaData(), QVariantList());
Plasma::RunnerContext context;
context.setQuery(QStringLiteral("settings"));
runner.match(context);
QCOMPARE(inotifyCount(), originalCount);
inotifyCountCool = true;
});
thread->start();
thread->wait();
thread->deleteLater();
QVERIFY(inotifyCountCool);
}
QTEST_MAIN(ServiceRunnerTest)
#include "servicerunnertest.moc"