From 86db843bc53a93dbf566b24df1462a22fccb619a Mon Sep 17 00:00:00 2001 From: aqua Date: Sat, 27 Aug 2022 22:09:16 +0300 Subject: Add parseCommandLine tests - use PluginLoader in plugin tests --- CMakeLists.txt | 1 + src/CMakeLists.txt | 8 ++++ src/application.cpp | 1 + src/application.hpp | 8 ++-- src/application_instance.cpp | 4 +- src/plugins/CMakeLists.txt | 2 +- src/plugins/pluginloader.h | 1 + src/plugins/test/pluginloader.cpp | 23 +++++------ src/rekonq_defines.h | 8 +++- src/taskmanager.cpp | 3 +- src/test/application_mock.hpp | 17 +++++++++ src/test/test_application.cpp | 80 +++++++++++++++++++++++++++++++++++++++ 12 files changed, 136 insertions(+), 20 deletions(-) create mode 100644 src/test/application_mock.hpp create mode 100644 src/test/test_application.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 154e39ba..0c0b707a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -92,6 +92,7 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config-version.h.cmake config-version # ================================================================================== # includes for all targets include_directories(include) +include_directories(${CMAKE_CURRENT_BINARY_DIR}) # ================================================================================== # Log messages diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6bf47516..1877a108 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -102,6 +102,14 @@ IF(HAVE_QCA2 AND HAVE_QTOAUTH) ) ENDIF(HAVE_QCA2 AND HAVE_QTOAUTH) +# tests +if(${CMAKE_BUILD_TYPE} STREQUAL "Debug") + add_executable(test_application test/test_application.cpp test/application_mock.hpp + application_instance.cpp application.hpp) + target_compile_definitions(test_application PRIVATE REKONQ_TEST) + target_link_libraries(test_application GTest::gtest GTest::gmock GTest::gtest_main SingleApplication::SingleApplication) + gtest_discover_tests(test_application) +endif() ### ------------ INSTALL FILES... diff --git a/src/application.cpp b/src/application.cpp index be4bb4fc..69279734 100644 --- a/src/application.cpp +++ b/src/application.cpp @@ -12,6 +12,7 @@ #include "application.hpp" #include "plugins/pluginloader.h" #include "plugins/rplugininterface.hpp" +#include "rekonqwindow.h" #include // --------------------------------------------------------------------------------------------------------------- diff --git a/src/application.hpp b/src/application.hpp index 7d75af3a..9d98b5a0 100644 --- a/src/application.hpp +++ b/src/application.hpp @@ -12,7 +12,6 @@ #pragma once #include "rekonq.hpp" -#include "rekonqwindow.h" #include #include #include @@ -20,6 +19,7 @@ // Forward Declarations class RekonqView; +class RekonqWindow; class PluginLoader; // class WebTab; @@ -41,7 +41,7 @@ public: Application(int &argc, char *argv[]); ~Application() override; - bool registerPlugin(const QString &path); + REKONQ_TEST_VIRTUAL bool registerPlugin(const QString &path) REKONQ_TEST_PURE; [[nodiscard]] auto pluginList() const { return m_plugins; }; // int newInstance(); @@ -94,8 +94,8 @@ public slots: // RekonqWindow *newWindow(bool withTab = true, bool PrivateBrowsingMode = false); // RekonqWindow *newWindow(WebPage *pg); - RekonqWindow *newWindow(); - RekonqView *newView(const QUrl &url = QUrl(), RekonqWindow *window = nullptr); + REKONQ_TEST_VIRTUAL RekonqWindow *newWindow() REKONQ_TEST_PURE; + REKONQ_TEST_VIRTUAL RekonqView *newView(const QUrl &url = QUrl(), RekonqWindow *window = nullptr) REKONQ_TEST_PURE; // void createWebAppShortcut(const QString & urlString = QString(), const QString & titleString = QString()); diff --git a/src/application_instance.cpp b/src/application_instance.cpp index 53dd9885..8c744d10 100644 --- a/src/application_instance.cpp +++ b/src/application_instance.cpp @@ -49,6 +49,8 @@ void Application::parseCommandLine(quint32 instanceId, const QByteArray &message else { // create main window auto *window = newWindow(); - for (const auto &url : positionalArguments) newView(QUrl::fromUserInput(url), window); + if (positionalArguments.isEmpty()) newView(QUrl(), window); + else + for (const auto &url : positionalArguments) newView(QUrl::fromUserInput(url), window); } } diff --git a/src/plugins/CMakeLists.txt b/src/plugins/CMakeLists.txt index ab4d8950..a978542f 100644 --- a/src/plugins/CMakeLists.txt +++ b/src/plugins/CMakeLists.txt @@ -3,5 +3,5 @@ target_link_libraries(pluginloader PUBLIC Qt6::Core Qt6::Widgets) if(${CMAKE_BUILD_TYPE} STREQUAL "Debug") add_executable(load_plugin test/pluginloader.cpp) - target_link_libraries(load_plugin GTest::gtest GTest::gtest_main Qt6::Core) + target_link_libraries(load_plugin GTest::gtest GTest::gtest_main pluginloader) endif() diff --git a/src/plugins/pluginloader.h b/src/plugins/pluginloader.h index 319e985a..23c884b1 100644 --- a/src/plugins/pluginloader.h +++ b/src/plugins/pluginloader.h @@ -16,6 +16,7 @@ class PluginLoader : public QPluginLoader { public: explicit PluginLoader(const QString &path, QObject *parent = nullptr); + ~PluginLoader() override = default; [[nodiscard]] auto schemes() const { return m_schemes; } [[nodiscard]] bool hasScheme(const QString &scheme) const { return m_schemes.contains(scheme); } diff --git a/src/plugins/test/pluginloader.cpp b/src/plugins/test/pluginloader.cpp index 83b30c40..7c2791a4 100644 --- a/src/plugins/test/pluginloader.cpp +++ b/src/plugins/test/pluginloader.cpp @@ -1,24 +1,23 @@ #include -#include #include -#include + +#include "../pluginloader.h" char *pluginPath; class PluginLoaderTest : public ::testing::Test { protected: - void SetUp() override { loader = new QPluginLoader; } + void SetUp() override { loader = new PluginLoader(pluginPath); } void TearDown() override { delete loader; } - QPluginLoader *loader = nullptr; + PluginLoader *loader = nullptr; }; TEST_F(PluginLoaderTest, InterfaceTest) { // Ensure plugin loads - loader->setFileName(pluginPath); - EXPECT_TRUE(loader->load()) << "For plugin: " << pluginPath << '\n' << qUtf8Printable(loader->errorString()); + EXPECT_TRUE(loader->load()) << "plugin: " << pluginPath << '\n' << qUtf8Printable(loader->errorString()); // Ensure plugin has metadata const auto metadata = loader->metaData()["MetaData"].toObject(); @@ -26,15 +25,17 @@ TEST_F(PluginLoaderTest, InterfaceTest) EXPECT_FALSE(metadata["name"].toString().isEmpty()); EXPECT_TRUE(metadata.contains("schemes")); EXPECT_FALSE(metadata["schemes"].toArray().isEmpty()); + + // check available schemes + EXPECT_FALSE(loader->schemes().isEmpty()); + + // check interface cast + EXPECT_FALSE(loader->interface() == nullptr); } int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); - if (argc != 2) { - std::cerr << "Usage: " << argv[0] << " [path to plugin]" << std::endl; - return -1; - } - pluginPath = argv[1]; + pluginPath = argv[argc - 1]; return RUN_ALL_TESTS(); } diff --git a/src/rekonq_defines.h b/src/rekonq_defines.h index 629d59bc..f56cb5fa 100644 --- a/src/rekonq_defines.h +++ b/src/rekonq_defines.h @@ -14,8 +14,12 @@ // ---------------------------------------------------------------------------------------------------- // UNIT TESTS NEED -#ifndef REKONQ_TEST_EXPORT -#define REKONQ_TEST_EXPORT __attribute__((visibility("hidden"))) +#ifdef REKONQ_TEST +#define REKONQ_TEST_VIRTUAL virtual +#define REKONQ_TEST_PURE = 0 +#else +#define REKONQ_TEST_VIRTUAL +#define REKONQ_TEST_PURE #endif // ---------------------------------------------------------------------------------------------------- diff --git a/src/taskmanager.cpp b/src/taskmanager.cpp index 9025f461..b69b30b8 100644 --- a/src/taskmanager.cpp +++ b/src/taskmanager.cpp @@ -10,6 +10,7 @@ #include "taskmanager.h" #include "application.hpp" #include "plugins/pluginloader.h" +#include "rekonqwindow.h" #include "ui_taskmanager.h" TaskManager::TaskManager(QWidget *parent) : QDialog(parent), ui(new Ui::TaskManager) @@ -59,4 +60,4 @@ void TaskManager::showPluginDetails(QListWidgetItem *item) ui->pluginState->setChecked(plugin->isLoaded()); ui->pluginError->setText(plugin->errorString()); ui->pluginSchemes->setText(plugin->schemes().join(' ')); -} \ No newline at end of file +} diff --git a/src/test/application_mock.hpp b/src/test/application_mock.hpp new file mode 100644 index 00000000..edfaf0bc --- /dev/null +++ b/src/test/application_mock.hpp @@ -0,0 +1,17 @@ +#pragma once + +#include "../application.hpp" +#include + +class FakeApplication : public Application { + Q_OBJECT + +public: + explicit FakeApplication(int &argc, char *argv[]) : Application(argc, argv) {} + ~FakeApplication() override = default; + + MOCK_METHOD(bool, registerPlugin, (const QString &), (override)); + + MOCK_METHOD(RekonqWindow *, newWindow, (), (override)); + MOCK_METHOD(RekonqView *, newView, (const QUrl &, RekonqWindow *), (override)); +}; diff --git a/src/test/test_application.cpp b/src/test/test_application.cpp new file mode 100644 index 00000000..63963cd1 --- /dev/null +++ b/src/test/test_application.cpp @@ -0,0 +1,80 @@ +#include "test/application_mock.hpp" +#include + +// NOLINTNEXTLINE(modernize-avoid-c-arrays) +Application::Application(int &argc, char *argv[]) : SingleApplication(argc, argv) {} +Application::~Application() = default; + +using ::testing::_; // NOLINT(bugprone-reserved-identifier) + +MATCHER_P(QStringEq, a, "") +{ + *result_listener << "where the arg is " << qUtf8Printable(arg); + return arg.compare(a) == 0; +} + +MATCHER_P(QUrlEq, a, "") +{ + *result_listener << "where the arg is " << qUtf8Printable(arg.toString()); + return arg.toString().compare(a) == 0; +} + +TEST(Application, parseCommandLine_url) +{ + int argc = 2; + // NOLINTNEXTLINE(modernize-avoid-c-arrays) + char *argv[]{(char *)"FakeApplication", (char *)"about:blank"}; + + FakeApplication app(argc, argv); + EXPECT_CALL(app, registerPlugin).Times(0); + EXPECT_CALL(app, newView(QUrlEq("about:blank"), nullptr)).Times(1); + EXPECT_CALL(app, newWindow).Times(1); + + ASSERT_TRUE(Application::instance() != nullptr); + + EXPECT_TRUE(app.pluginList().isEmpty()); + EXPECT_TRUE(app.windowList().isEmpty()); + EXPECT_TRUE(app.viewList().isEmpty()); + + app.parseCommandLine(app.instanceId(), {}); +} + +TEST(Application, parseCommandLine_webapp) +{ + int argc = 3; + // NOLINTNEXTLINE(modernize-avoid-c-arrays) + char *argv[]{(char *)"FakeApplication", (char *)"--webapp", (char *)"about:blank"}; + + FakeApplication app(argc, argv); + EXPECT_CALL(app, registerPlugin).Times(0); + EXPECT_CALL(app, newView(QUrlEq("about:blank"), nullptr)).Times(1); + EXPECT_CALL(app, newWindow).Times(0); + + ASSERT_TRUE(Application::instance() != nullptr); + + EXPECT_TRUE(app.pluginList().isEmpty()); + EXPECT_TRUE(app.windowList().isEmpty()); + EXPECT_TRUE(app.viewList().isEmpty()); + + app.parseCommandLine(app.instanceId(), {}); +} + +TEST(Application, parseCommandLine_load) +{ + int argc = 3; + // NOLINTNEXTLINE(modernize-avoid-c-arrays) + char *argv[]{(char *)"FakeApplication", (char *)"--load", (char *)"libPlugin.so"}; + + FakeApplication app(argc, argv); + EXPECT_CALL(app, registerPlugin(QStringEq("libPlugin.so"))).Times(1); + EXPECT_CALL(app, newView).Times(1); + EXPECT_CALL(app, newWindow).Times(1); + + ASSERT_TRUE(Application::instance() != nullptr); + + EXPECT_TRUE(app.pluginList().isEmpty()); + EXPECT_TRUE(app.windowList().isEmpty()); + EXPECT_TRUE(app.viewList().isEmpty()); + + app.parseCommandLine(app.instanceId(), {}); +} -- cgit v1.2.1