diff --git a/Modules/about-distro/CMakeLists.txt b/Modules/about-distro/CMakeLists.txt --- a/Modules/about-distro/CMakeLists.txt +++ b/Modules/about-distro/CMakeLists.txt @@ -4,4 +4,8 @@ add_subdirectory(src) +if(BUILD_TESTING) + add_subdirectory(autotests) +endif() + feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES) diff --git a/Modules/about-distro/autotests/CMakeLists.txt b/Modules/about-distro/autotests/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/Modules/about-distro/autotests/CMakeLists.txt @@ -0,0 +1,23 @@ +remove_definitions(-DQT_NO_CAST_FROM_ASCII) + +include(ECMAddTests) + +find_package(Qt5Test ${REQUIRED_QT_VERSION} CONFIG REQUIRED) + +# Include src to get access to the OSRelease.h +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../src) + +add_library(about-distro-test STATIC ../src/OSRelease.cpp) +target_link_libraries(about-distro-test + PUBLIC + KF5::CoreAddons +) + +ecm_add_tests( + OSReleaseTest.cpp + LINK_LIBRARIES + Qt5::Test + about-distro-test +) + +ecm_mark_nongui_executable(OSReleaseTest) diff --git a/Modules/about-distro/autotests/OSReleaseTest.cpp b/Modules/about-distro/autotests/OSReleaseTest.cpp new file mode 100644 --- /dev/null +++ b/Modules/about-distro/autotests/OSReleaseTest.cpp @@ -0,0 +1,57 @@ +/* + Copyright (C) 2019 Harald Sitter + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License or (at your option) version 3 or any later version + accepted by the membership of KDE e.V. (or its successor approved + by the membership of KDE e.V.), which shall act as a proxy + defined in Section 14 of version 3 of the license. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include + +#include "OSRelease.h" + +class OSReleaseTest : public QObject +{ + Q_OBJECT +private Q_SLOTS: + void initTestCase() {} + + void testParse() + { + auto r = OSRelease(QFINDTESTDATA("data/os-release")); + QCOMPARE(r.name, "Name"); + QCOMPARE(r.version, "100.5"); + QCOMPARE(r.id, "theid"); + QCOMPARE(r.idLike, QStringList({"otherid", "otherotherid"})); + QCOMPARE(r.versionCodename, "versioncodename"); + QCOMPARE(r.versionId, "500.1"); + QCOMPARE(r.prettyName, "Pretty Name"); + QCOMPARE(r.ansiColor, "1;34"); + QCOMPARE(r.cpeName, "cpe:/o:foo:bar:100"); + QCOMPARE(r.homeUrl, "https://url.home"); + QCOMPARE(r.documentationUrl, "https://url.docs"); + QCOMPARE(r.supportUrl, "https://url.support"); + QCOMPARE(r.bugReportUrl, "https://url.bugs"); + QCOMPARE(r.privacyPolicyUrl, "https://url.privacy"); + QCOMPARE(r.buildId, "105.5"); + QCOMPARE(r.variant, "Test Edition"); + QCOMPARE(r.variantId, "test"); + QCOMPARE(r.logo, "start-here-test"); + } +}; + +QTEST_MAIN(OSReleaseTest) + +#include "OSReleaseTest.moc" diff --git a/Modules/about-distro/autotests/data/os-release b/Modules/about-distro/autotests/data/os-release new file mode 100644 --- /dev/null +++ b/Modules/about-distro/autotests/data/os-release @@ -0,0 +1,18 @@ +NAME="Name" +VERSION="100.5" +ID=theid +ID_LIKE="otherid otherotherid" +VERSION_CODENAME=versioncodename +VERSION_ID="500.1" +PRETTY_NAME="Pretty Name" +ANSI_COLOR="1;34" +CPE_NAME="cpe:/o:foo:bar:100" +HOME_URL="https://url.home" +DOCUMENTATION_URL="https://url.docs" +SUPPORT_URL="https://url.support" +BUG_REPORT_URL="https://url.bugs" +PRIVACY_POLICY_URL="https://url.privacy" +BUILD_ID="105.5" +VARIANT="Test Edition" +VARIANT_ID=test +LOGO=start-here-test diff --git a/Modules/about-distro/src/OSRelease.h b/Modules/about-distro/src/OSRelease.h --- a/Modules/about-distro/src/OSRelease.h +++ b/Modules/about-distro/src/OSRelease.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2014 Harald Sitter + Copyright (C) 2014-2019 Harald Sitter This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -27,21 +27,30 @@ class OSRelease { public: - OSRelease(); + OSRelease(const QString &filePath = defaultFilePath()); + + static QString defaultFilePath(); QString name; QString version; QString id; QStringList idLike; + QString versionCodename; QString versionId; QString prettyName; QString ansiColor; QString cpeName; // TODO: url struct or map? QString homeUrl; + QString documentationUrl; QString supportUrl; QString bugReportUrl; + QString privacyPolicyUrl; + QString buildId; + QString variant; + QString variantId; + QString logo; }; #endif // OSRELEASE_H diff --git a/Modules/about-distro/src/OSRelease.cpp b/Modules/about-distro/src/OSRelease.cpp --- a/Modules/about-distro/src/OSRelease.cpp +++ b/Modules/about-distro/src/OSRelease.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2014 Harald Sitter + Copyright (C) 2014-2019 Harald Sitter This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -23,7 +23,6 @@ #include #include -#include #include static void setVar(QString *var, const QString &value) @@ -61,25 +60,39 @@ *var = args; } -OSRelease::OSRelease() +OSRelease::OSRelease(const QString &filePath) { // Set default values for non-optional fields. name = QStringLiteral("Linux"); id = QStringLiteral("linux"); prettyName = QStringLiteral("Linux"); - QString fileName; - - if (QFile::exists(QStringLiteral("/etc/os-release"))) { - fileName = QStringLiteral("/etc/os-release"); - } else if (QFile::exists(QStringLiteral("/usr/lib/os-release"))) { - fileName = QStringLiteral("/usr/lib/os-release"); - } else { + if (filePath.isEmpty()) { return; } - - QFile file(fileName); + QHash stringHash = { + { QStringLiteral("NAME"), &name }, + { QStringLiteral("VERSION"), &version }, + { QStringLiteral("ID"), &id }, + // idLike is not a QString, special handling below! + { QStringLiteral("VERSION_CODENAME"), &versionCodename }, + { QStringLiteral("VERSION_ID"), &versionId }, + { QStringLiteral("PRETTY_NAME"), &prettyName }, + { QStringLiteral("ANSI_COLOR"), &ansiColor }, + { QStringLiteral("CPE_NAME"), &cpeName }, + { QStringLiteral("HOME_URL"), &homeUrl }, + { QStringLiteral("DOCUMENTATION_URL"), &documentationUrl }, + { QStringLiteral("SUPPORT_URL"), &supportUrl }, + { QStringLiteral("BUG_REPORT_URL"), &bugReportUrl }, + { QStringLiteral("PRIVACY_POLICY_URL"), &privacyPolicyUrl }, + { QStringLiteral("BUILD_ID"), &buildId }, + { QStringLiteral("VARIANT"), &variant }, + { QStringLiteral("VARIANT_ID"), &variantId }, + { QStringLiteral("LOGO"), &logo } + }; + + QFile file(filePath); // NOTE: The os-release specification defines default values for specific // fields which means that even if we can not read the os-release file // we have sort of expected default values to use. @@ -105,31 +118,28 @@ QString key = comps.at(0); QString value = comps.at(1).trimmed(); - if (key == QLatin1String("NAME")) - setVar(&name, value); - else if (key == QLatin1String("VERSION")) - setVar(&version, value); - else if (key == QLatin1String("ID")) - setVar(&id, value); - else if (key == QLatin1String("ID_LIKE")) + + if (QString *var = stringHash.value(key, nullptr)) { + setVar(var, value); + } + + // ID_LIKE is a list and parsed as such (rather than a QString). + if (key == QLatin1String("ID_LIKE")) { setVar(&idLike, value); - else if (key == QLatin1String("VERSION_ID")) - setVar(&versionId, value); - else if (key == QLatin1String("PRETTY_NAME")) - setVar(&prettyName, value); - else if (key == QLatin1String("ANSI_COLOR")) - setVar(&ansiColor, value); - else if (key == QLatin1String("CPE_NAME")) - setVar(&cpeName, value); - else if (key == QLatin1String("HOME_URL")) - setVar(&homeUrl, value); - else if (key == QLatin1String("SUPPORT_URL")) - setVar(&supportUrl, value); - else if (key == QLatin1String("BUG_REPORT_URL")) - setVar(&bugReportUrl, value); - else if (key == QLatin1String("BUILD_ID")) - setVar(&buildId, value); + } + // os-release explicitly allows for vendor specific aditions. We have no // interest in those right now. } } + +QString OSRelease::defaultFilePath() +{ + if (QFile::exists(QStringLiteral("/etc/os-release"))) { + return QStringLiteral("/etc/os-release"); + } else if (QFile::exists(QStringLiteral("/usr/lib/os-release"))) { + return QStringLiteral("/usr/lib/os-release"); + } else { + return QString(); + } +}