From b10895dd611057bf09c8142d9ebb55263db4faf0 Mon Sep 17 00:00:00 2001 From: aqua Date: Fri, 9 Sep 2022 10:08:01 +0300 Subject: Rework SearchEngine --- src/CMakeLists.txt | 8 ++ src/rekonq.hpp | 1 + src/rekonq_defines.h | 10 --- src/rekonq_test.hpp | 27 ++++++ src/searchengine.cpp | 190 ++++++++++------------------------------- src/searchengine.h | 60 ------------- src/searchengine.hpp | 42 +++++++++ src/test/test_searchengine.cpp | 43 ++++++++++ 8 files changed, 165 insertions(+), 216 deletions(-) create mode 100644 src/rekonq_test.hpp delete mode 100644 src/searchengine.h create mode 100644 src/searchengine.hpp create mode 100644 src/test/test_searchengine.cpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a4193a16..a991b1b1 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -13,6 +13,8 @@ set(rekonqwindow_SRCS ) set(rekonqwindow_IFACES ${PROJECT_SOURCE_DIR}/include/rview.hpp) +set(searchengine_SRCS searchengine.cpp searchengine.hpp) + # rekonq set(rekonq_SRCS #---------------------------------------- @@ -127,6 +129,12 @@ if(${CMAKE_BUILD_TYPE} STREQUAL "Debug") target_compile_definitions(test_rekonqwindow PRIVATE REKONQ_TEST) target_link_libraries(test_rekonqwindow GTest::gtest GTest::gmock settings) gtest_discover_tests(test_rekonqwindow) + + # searchengine test + add_executable(test_searchengine test/test_searchengine.cpp test/settings_mock.hpp ${searchengine_SRCS}) + target_compile_definitions(test_searchengine PRIVATE REKONQ_TEST) + target_link_libraries(test_searchengine GTest::gtest GTest::gtest_main GTest::gmock settings) + gtest_discover_tests(test_searchengine) endif() ### ------------ INSTALL FILES... diff --git a/src/rekonq.hpp b/src/rekonq.hpp index 4a9bf10d..49bda0fa 100644 --- a/src/rekonq.hpp +++ b/src/rekonq.hpp @@ -14,3 +14,4 @@ // Defines #include "rekonq_defines.h" +#include "rekonq_test.hpp" diff --git a/src/rekonq_defines.h b/src/rekonq_defines.h index 088478bd..01294aba 100644 --- a/src/rekonq_defines.h +++ b/src/rekonq_defines.h @@ -12,16 +12,6 @@ #pragma once -// ------------------------------------------------------------ -// UNIT TESTS NEED -#ifdef REKONQ_TEST -#define REKONQ_TEST_VIRTUAL virtual -#define REKONQ_TEST_PURE = 0 -#else -#define REKONQ_TEST_VIRTUAL -#define REKONQ_TEST_PURE -#endif - // ------------------------------------------------------------ // Defines diff --git a/src/rekonq_test.hpp b/src/rekonq_test.hpp new file mode 100644 index 00000000..ff30b8cf --- /dev/null +++ b/src/rekonq_test.hpp @@ -0,0 +1,27 @@ +/* ============================================================ + * The rekonq project + * ============================================================ + * SPDX-License-Identifier: GPL-3.0-only + * Copyright (C) 2022 aqua + * ============================================================ + * Description: rekonq test definitions + * ============================================================ */ + +#pragma once + +// GTest and GMock +#include + +// ------------------------------------------------------------ +// UNIT TESTS NEED + +#ifdef REKONQ_TEST +#define REKONQ_TEST_VIRTUAL virtual +#define REKONQ_TEST_PURE = 0 +#else +#define REKONQ_TEST_VIRTUAL +#define REKONQ_TEST_PURE +#endif + +// ------------------------------------------------------------ +// GTest Matchers diff --git a/src/searchengine.cpp b/src/searchengine.cpp index dd01f703..342065c4 100644 --- a/src/searchengine.cpp +++ b/src/searchengine.cpp @@ -1,166 +1,64 @@ /* ============================================================ -* -* This file is a part of the rekonq project -* -* Copyright (C) 2008-2012 by Andrea Diamantini -* Copyright (C) 2009-2011 by Lionel Chauvin -* -* -* 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 . -* -* ============================================================ */ - + * The rekonq project + * ============================================================ + * SPDX-License-Identifier: GPL-2.0-or-later + * Copyright (C) 2008-2012 by Andrea Diamantini + * Copyright (C) 2009-2011 by Lionel Chauvin + * SPDX-License-Identifier: GPL-3.0-only + * Copyright (C) 2022 aqua + * ============================================================ */ // local includes -#include "searchengine.h" - -//KDE includes -#include -#include -#include - -#include - - -struct SearchEnginePrivate -{ - SearchEnginePrivate() : isLoaded(false) {} - bool isLoaded; - bool isEnabled; - bool usePreferredOnly; - QString delimiter; - KService::List favorites; - KService::Ptr defaultEngine; +#include "searchengine.hpp" + +struct SearchEnginePrivate { + SearchEnginePrivate() = default; + ~SearchEnginePrivate() noexcept + { + for (auto *i : engines) delete i; + } + bool isLoaded = false; + QList engines; + SearchEngine *defaultEngine = nullptr; }; +Q_GLOBAL_STATIC(SearchEnginePrivate, d) -K_GLOBAL_STATIC(SearchEnginePrivate, d) - - - -void SearchEngine::reload() -{ - KConfig config("kuriikwsfilterrc"); //Shared with konqueror - KConfigGroup cg = config.group("General"); - - d->isEnabled = cg.readEntry("EnableWebShortcuts", true); - d->usePreferredOnly = cg.readEntry("UsePreferredWebShortcutsOnly", false); - - //load delimiter - d->delimiter = cg.readEntry("KeywordDelimiter", ":"); - - // load favorite engines - QStringList favoriteEngines; - favoriteEngines = cg.readEntry("PreferredWebShortcuts", favoriteEngines); - - KService::List favorites; - KService::Ptr service; - Q_FOREACH(const QString & engine, favoriteEngines) - { - service = KService::serviceByDesktopPath(QString("searchproviders/%1.desktop").arg(engine)); - if (service) - { - favorites << service; - } - } - d->favorites = favorites; - - // load default engine - QString dse; - dse = cg.readEntry("DefaultWebShortcut"); - - d->defaultEngine = KService::serviceByDesktopPath(QString("searchproviders/%1.desktop").arg(dse)); - - d->isLoaded = true; -} - - -QString SearchEngine::delimiter() -{ - if (!d->isLoaded) - reload(); - - return d->delimiter; -} - - -KService::List SearchEngine::favorites() +SearchEngine *SearchEngine::defaultEngine() { - if (!d->isLoaded) - reload(); - - return d->favorites; + Q_ASSERT(d->isLoaded); + return d->defaultEngine; } - -KService::Ptr SearchEngine::defaultEngine() +QList SearchEngine::engines() { - if (!d->isLoaded) - reload(); - - return d->defaultEngine; + Q_ASSERT(d->isLoaded); + return d->engines; } - -KService::Ptr SearchEngine::fromString(const QString &text) +void SearchEngine::reload(RekonqSettings *settings) { - KService::Ptr service; - - // first, the easy part... - if (!d->isEnabled) - return service; + Q_CHECK_PTR(settings); - KService::List providers = (d->usePreferredOnly) - ? SearchEngine::favorites() - : KServiceTypeTrader::self()->query("SearchProvider"); + settings->beginGroup("SearchEngines"); + const auto defaultId = settings->value("default").toString(); + const auto list = settings->value("engines").toStringList(); - int i = 0; - bool found = false; - while (!found && i < providers.size()) - { - QStringList list = providers.at(i)->property("Keys").toStringList(); - Q_FOREACH(const QString & key, list) - { - const QString searchPrefix = key + delimiter(); - if (text.startsWith(searchPrefix)) - { - service = providers.at(i); - found = true; - break; - } - } - i++; - } + for (const auto &id : list) { + auto *e = new SearchEngine(id, settings); + d->engines.append(e); + if (id == defaultId) d->defaultEngine = e; + } - return service; + settings->endGroup(); + d->isLoaded = true; } - -QString SearchEngine::buildQuery(KService::Ptr engine, const QString &text) +SearchEngine::SearchEngine(const QString &id, RekonqSettings *settings) : m_id(id) { - if (!engine) - return QString(); - - QString shortcut = engine->property("Keys").toStringList().at(0); - QString query = shortcut + delimiter() + text; - - QStringList filters; - filters << QL1S("kurisearchfilter"); - KUriFilter::self()->filterUri(query, filters); - - return query; + settings->beginGroup("SearchEngines." + id); + m_name = settings->value("name").toString(); + m_url = settings->value("url").toString(); + m_enabled = settings->value("enabled").toBool(); + settings->endGroup(); } diff --git a/src/searchengine.h b/src/searchengine.h deleted file mode 100644 index 38808ae3..00000000 --- a/src/searchengine.h +++ /dev/null @@ -1,60 +0,0 @@ -/* ============================================================ -* -* This file is a part of the rekonq project -* -* Copyright (C) 2008-2012 by Andrea Diamantini -* Copyright (C) 2009-2011 by Lionel Chauvin -* -* -* 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 . -* -* ============================================================ */ - - -#ifndef SEARCHENGINE_H -#define SEARCHENGINE_H - - -// Rekonq Includes -#include "rekonq_defines.h" - -// KDE Includes -#include - -//Qt Includes -#include - - -namespace SearchEngine -{ -void reload(); - -QString delimiter(); - -KService::Ptr defaultEngine(); - -KService::List favorites(); - -KService::Ptr fromString(const QString &text); - -QString buildQuery(KService::Ptr engine, const QString &text); - -QString extractQuery(const QString &text); - -} - -#endif diff --git a/src/searchengine.hpp b/src/searchengine.hpp new file mode 100644 index 00000000..3eff4b58 --- /dev/null +++ b/src/searchengine.hpp @@ -0,0 +1,42 @@ +/* ============================================================ + * The rekonq project + * ============================================================ + * SPDX-License-Identifier: GPL-2.0-or-later + * Copyright (C) 2008-2012 by Andrea Diamantini + * Copyright (C) 2009-2011 by Lionel Chauvin + * SPDX-License-Identifier: GPL-3.0-only + * Copyright (C) 2022 aqua + * ============================================================ + * Description: Search engine manager + * ============================================================ */ + +#pragma once + +#include +#include +#include +#include + +class SearchEngine { +public: + static void reload(RekonqSettings *settings); + static SearchEngine *defaultEngine(); + static QList engines(); + + SearchEngine(const QString &id, RekonqSettings *settings); + + [[nodiscard]] auto id() const { return m_id; } + [[nodiscard]] auto icon() const { return m_icon; } + [[nodiscard]] auto name() const { return m_name; } + void setName(const QString &name) { m_name = name; } + [[nodiscard]] bool isEnabled() const { return m_enabled; } + + [[nodiscard]] QString query(const QString &text) const { return m_url.arg(text); } + +private: + const QString m_id; + QIcon m_icon; + QString m_name; + QString m_url; + bool m_enabled; +}; diff --git a/src/test/test_searchengine.cpp b/src/test/test_searchengine.cpp new file mode 100644 index 00000000..6efe6cdc --- /dev/null +++ b/src/test/test_searchengine.cpp @@ -0,0 +1,43 @@ +/* ============================================================ + * The rekonq project + * ============================================================ + * SPDX-License-Identifier: GPL-3.0-only + * Copyright (C) 2022 aqua + * ============================================================ */ + +#include "../searchengine.hpp" +#include "settings_mock.hpp" +#include + +using ::testing::_; // NOLINT(bugprone-reserved-identifier) +using ::testing::Matcher; +using ::testing::Return; + +MATCHER_P(QStringEq, a, "") +{ + *result_listener << "where the arg is " << qUtf8Printable(arg); + return arg.compare(a) == 0; +} + +TEST(SearchEngine, reload) +{ + MockSettings settings; + EXPECT_CALL(settings, beginGroup(QStringEq("SearchEngines"))).Times(1); + EXPECT_CALL(settings, beginGroup(QStringEq("SearchEngines.ddg"))).Times(1); + EXPECT_CALL(settings, endGroup).Times(2); + EXPECT_CALL(settings, value(QStringEq("engines"))).Times(1).WillOnce(Return(QVariant{"ddg"})); + EXPECT_CALL(settings, value(QStringEq("default"))).Times(1).WillOnce(Return(QVariant{"ddg"})); + EXPECT_CALL(settings, value(QStringEq("name"))).Times(1).WillOnce(Return(QVariant{"DuckDuckGo"})); + EXPECT_CALL(settings, value(QStringEq("url"))).Times(1).WillOnce(Return(QVariant{"https://dd.go/&q=%1"})); + EXPECT_CALL(settings, value(QString("enabled"))).Times(1).WillOnce(Return(QVariant{true})); + + SearchEngine::reload(&settings); + const auto engines = SearchEngine::engines(); + EXPECT_EQ(engines.count(), 1); + + const auto *e = SearchEngine::defaultEngine(); + ASSERT_NE(e, nullptr); + EXPECT_THAT(e->name(), QStringEq("DuckDuckGo")); + EXPECT_THAT(e->query("cats"), QStringEq("https://dd.go/&q=cats")); + EXPECT_TRUE(e->isEnabled()); +} -- cgit v1.2.1