From 8bf48260034e3ffe27f3b78c128123ef7b22faa5 Mon Sep 17 00:00:00 2001 From: Florian Geyer Date: Thu, 15 May 2014 23:48:54 +0200 Subject: [PATCH] Move search into separate class. --- src/CMakeLists.txt | 1 + src/core/EntrySearcher.cpp | 47 ++++++++++++ src/core/EntrySearcher.h | 35 +++++++++ src/core/Group.cpp | 27 ------- src/core/Group.h | 3 - src/gui/DatabaseWidget.cpp | 3 +- tests/CMakeLists.txt | 3 + tests/TestEntrySearcher.cpp | 141 ++++++++++++++++++++++++++++++++++++ tests/TestEntrySearcher.h | 35 +++++++++ tests/TestGroup.cpp | 96 ------------------------ tests/TestGroup.h | 2 - 11 files changed, 264 insertions(+), 129 deletions(-) create mode 100644 src/core/EntrySearcher.cpp create mode 100644 src/core/EntrySearcher.h create mode 100644 tests/TestEntrySearcher.cpp create mode 100644 tests/TestEntrySearcher.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d57153e5f..9af937ea3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -35,6 +35,7 @@ set(keepassx_SOURCES core/Entry.cpp core/EntryAttachments.cpp core/EntryAttributes.cpp + core/EntrySearcher.cpp core/FilePath.cpp core/Global.h core/Group.cpp diff --git a/src/core/EntrySearcher.cpp b/src/core/EntrySearcher.cpp new file mode 100644 index 000000000..60cfaea45 --- /dev/null +++ b/src/core/EntrySearcher.cpp @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2014 Florian Geyer + * + * 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 or (at your option) + * 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 "EntrySearcher.h" + +#include "core/Group.h" + +QList EntrySearcher::search(const QString &searchTerm, const Group* group, Qt::CaseSensitivity caseSensitivity) +{ + if (!group->resolveSearchingEnabled()) { + return QList(); + } + + return searchEntries(searchTerm, group, caseSensitivity); +} + +QList EntrySearcher::searchEntries(const QString &searchTerm, const Group* group, Qt::CaseSensitivity caseSensitivity) +{ + QList searchResult; + + Q_FOREACH (Entry* entry, group->entries()) { + if (entry->match(searchTerm, caseSensitivity)) { + searchResult.append(entry); + } + } + Q_FOREACH (Group* childGroup, group->children()) { + if (childGroup->searchingEnabled() != Group::Disable) { + searchResult.append(searchEntries(searchTerm, childGroup, caseSensitivity)); + } + } + + return searchResult; +} diff --git a/src/core/EntrySearcher.h b/src/core/EntrySearcher.h new file mode 100644 index 000000000..56ed7e4e5 --- /dev/null +++ b/src/core/EntrySearcher.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2014 Florian Geyer + * + * 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 or (at your option) + * 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 KEEPASSX_ENTRYSEARCHER_H +#define KEEPASSX_ENTRYSEARCHER_H + +#include + + +class Group; +class Entry; + +class EntrySearcher +{ +public: + QList search(const QString& searchTerm, const Group* group, Qt::CaseSensitivity caseSensitivity); +private: + QList searchEntries(const QString &searchTerm, const Group *group, Qt::CaseSensitivity caseSensitivity); +}; + +#endif // KEEPASSX_ENTRYSEARCHER_H diff --git a/src/core/Group.cpp b/src/core/Group.cpp index 4c04b4846..9ebf7bb86 100644 --- a/src/core/Group.cpp +++ b/src/core/Group.cpp @@ -612,33 +612,6 @@ void Group::recCreateDelObjects() } } -QList Group::search(const QString& searchTerm, Qt::CaseSensitivity caseSensitivity, - bool resolveInherit) -{ - QList searchResult; - bool search; - if (resolveInherit) { - search = resolveSearchingEnabled(); - } - else if (searchingEnabled() == Disable) { - search = false; - } - else { - search = true; - } - if (search) { - Q_FOREACH (Entry* entry, m_entries) { - if (entry->match(searchTerm, caseSensitivity)) { - searchResult.append(entry); - } - } - Q_FOREACH (Group* group, m_children) { - searchResult.append(group->search(searchTerm, caseSensitivity, false)); - } - } - return searchResult; -} - bool Group::resolveSearchingEnabled() const { switch (m_data.searchingEnabled) { diff --git a/src/core/Group.h b/src/core/Group.h index 4e08f5b3b..715403c03 100644 --- a/src/core/Group.h +++ b/src/core/Group.h @@ -113,9 +113,6 @@ public: void copyDataFrom(const Group* other); Database* exportToDb(); - QList search(const QString& searchTerm, Qt::CaseSensitivity caseSensitivity, - bool resolveInherit = true); - Q_SIGNALS: void dataChanged(Group* group); diff --git a/src/gui/DatabaseWidget.cpp b/src/gui/DatabaseWidget.cpp index ba7ca747c..fc533a3f3 100644 --- a/src/gui/DatabaseWidget.cpp +++ b/src/gui/DatabaseWidget.cpp @@ -28,6 +28,7 @@ #include "autotype/AutoType.h" #include "core/Config.h" +#include "core/EntrySearcher.h" #include "core/FilePath.h" #include "core/Group.h" #include "core/Metadata.h" @@ -754,8 +755,8 @@ void DatabaseWidget::search() else { sensitivity = Qt::CaseInsensitive; } - QList searchResult = searchGroup->search(m_searchUi->searchEdit->text(), sensitivity); + QList searchResult = EntrySearcher().search(m_searchUi->searchEdit->text(), searchGroup, sensitivity); m_entryView->setEntryList(searchResult); } diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 8df0050aa..be37a5def 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -165,6 +165,9 @@ add_unit_test(NAME testqcommandlineparser SOURCES TestQCommandLineParser.cpp MOC add_unit_test(NAME testrandom SOURCES TestRandom.cpp MOCS TestRandom.h LIBS ${TEST_LIBRARIES}) +add_unit_test(NAME testentrysearcher SOURCES TestEntrySearcher.cpp MOCS TestEntrySearcher.h + LIBS ${TEST_LIBRARIES}) + if(WITH_GUI_TESTS) add_subdirectory(gui) endif(WITH_GUI_TESTS) diff --git a/tests/TestEntrySearcher.cpp b/tests/TestEntrySearcher.cpp new file mode 100644 index 000000000..308a26e6d --- /dev/null +++ b/tests/TestEntrySearcher.cpp @@ -0,0 +1,141 @@ +/* + * Copyright (C) 2014 Florian Geyer + * + * 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 or (at your option) + * 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 "TestEntrySearcher.h" + +#include + +#include "tests.h" +#include "core/EntrySearcher.h" +#include "core/Group.h" + +QTEST_GUILESS_MAIN(TestEntrySearcher) + +void TestEntrySearcher::initTestCase() +{ + +} + +void TestEntrySearcher::testSearch() +{ + Group* groupRoot = new Group(); + Group* group1 = new Group(); + Group* group2 = new Group(); + Group* group3 = new Group(); + + group1->setParent(groupRoot); + group2->setParent(groupRoot); + group3->setParent(groupRoot); + + Group* group11 = new Group(); + + group11->setParent(group1); + + Group* group21 = new Group(); + Group* group211 = new Group(); + Group* group2111 = new Group(); + + group21->setParent(group2); + group211->setParent(group21); + group2111->setParent(group211); + + group1->setSearchingEnabled(Group::Disable); + group11->setSearchingEnabled(Group::Enable); + + Entry* eRoot = new Entry(); + eRoot->setNotes("test search term test"); + eRoot->setGroup(groupRoot); + + Entry* eRoot2 = new Entry(); + eRoot2->setNotes("test term test"); + eRoot2->setGroup(groupRoot); + + Entry* e1 = new Entry(); + e1->setNotes("test search term test"); + e1->setGroup(group1); + + Entry* e11 = new Entry(); + e11->setNotes("test search term test"); + e11->setGroup(group11); + + Entry* e2111 = new Entry(); + e2111->setNotes("test search term test"); + e2111->setGroup(group2111); + + Entry* e2111b = new Entry(); + e2111b->setNotes("test search test"); + e2111b->setGroup(group2111); + + Entry* e3 = new Entry(); + e3->setNotes("test search term test"); + e3->setGroup(group3); + + Entry* e3b = new Entry(); + e3b->setNotes("test search test"); + e3b->setGroup(group3); + + QList searchResult; + + EntrySearcher entrySearcher; + + searchResult = entrySearcher.search("search term", groupRoot, Qt::CaseInsensitive); + + QCOMPARE(searchResult.count(), 3); + + searchResult = entrySearcher.search("search term", group211, Qt::CaseInsensitive); + QCOMPARE(searchResult.count(), 1); + + searchResult = entrySearcher.search("search term", group11, Qt::CaseInsensitive); + QCOMPARE(searchResult.count(), 1); + + searchResult = entrySearcher.search("search term", group1, Qt::CaseInsensitive); + QCOMPARE(searchResult.count(), 0); + + delete groupRoot; +} + +void TestEntrySearcher::testAndConcatenationInSearch() +{ + Group* group = new Group(); + Entry* entry = new Entry(); + entry->setNotes("abc def ghi"); + entry->setTitle("jkl"); + entry->setGroup(group); + + EntrySearcher entrySearcher; + QList searchResult; + + searchResult = entrySearcher.search("", group, Qt::CaseInsensitive); + QCOMPARE(searchResult.count(), 1); + + searchResult = entrySearcher.search("def", group, Qt::CaseInsensitive); + QCOMPARE(searchResult.count(), 1); + + searchResult = entrySearcher.search(" abc ghi ", group, Qt::CaseInsensitive); + QCOMPARE(searchResult.count(), 1); + + searchResult = entrySearcher.search("ghi ef", group, Qt::CaseInsensitive); + QCOMPARE(searchResult.count(), 1); + + searchResult = entrySearcher.search("abc ef xyz", group, Qt::CaseInsensitive); + QCOMPARE(searchResult.count(), 0); + + searchResult = entrySearcher.search("abc kl", group, Qt::CaseInsensitive); + QCOMPARE(searchResult.count(), 1); + + delete group; +} diff --git a/tests/TestEntrySearcher.h b/tests/TestEntrySearcher.h new file mode 100644 index 000000000..d261d5dd6 --- /dev/null +++ b/tests/TestEntrySearcher.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2014 Florian Geyer + * + * 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 or (at your option) + * 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 KEEPASSX_TESTENTRYSEARCHER_H +#define KEEPASSX_TESTENTRYSEARCHER_H + +#include + +class TestEntrySearcher : public QObject +{ + Q_OBJECT + +private Q_SLOTS: + void initTestCase(); + + void testAndConcatenationInSearch(); + void testSearch(); +}; + +#endif // KEEPASSX_TESTENTRYSEARCHER_H diff --git a/tests/TestGroup.cpp b/tests/TestGroup.cpp index 86b55b706..816f7ce70 100644 --- a/tests/TestGroup.cpp +++ b/tests/TestGroup.cpp @@ -334,102 +334,6 @@ void TestGroup::testCopyCustomIcon() delete dbTarget; } -void TestGroup::testSearch() -{ - Group* groupRoot = new Group(); - Group* group1 = new Group(); - Group* group2 = new Group(); - Group* group3 = new Group(); - - group1->setParent(groupRoot); - group2->setParent(groupRoot); - group3->setParent(groupRoot); - - Group* group11 = new Group(); - - group11->setParent(group1); - - Group* group21 = new Group(); - Group* group211 = new Group(); - Group* group2111 = new Group(); - - group21->setParent(group2); - group211->setParent(group21); - group2111->setParent(group211); - - group1->setSearchingEnabled(Group::Disable); - group11->setSearchingEnabled(Group::Enable); - - Entry* eRoot = new Entry(); - eRoot->setNotes("test search term test"); - eRoot->setGroup(groupRoot); - - Entry* eRoot2 = new Entry(); - eRoot2->setNotes("test term test"); - eRoot2->setGroup(groupRoot); - - Entry* e1 = new Entry(); - e1->setNotes("test search term test"); - e1->setGroup(group1); - - Entry* e2111 = new Entry(); - e2111->setNotes("test search term test"); - e2111->setGroup(group2111); - - Entry* e2111b = new Entry(); - e2111b->setNotes("test search test"); - e2111b->setGroup(group2111); - - Entry* e3 = new Entry(); - e3->setNotes("test search term test"); - e3->setGroup(group3); - - Entry* e3b = new Entry(); - e3b->setNotes("test search test"); - e3b->setGroup(group3); - - QList searchResult; - - searchResult = groupRoot->search("search term", Qt::CaseInsensitive); - QCOMPARE(searchResult.count(), 3); - - searchResult = group211->search("search term", Qt::CaseInsensitive); - QCOMPARE(searchResult.count(), 1); - - delete groupRoot; -} - -void TestGroup::testAndConcatenationInSearch() -{ - Group* group = new Group(); - Entry* entry = new Entry(); - entry->setNotes("abc def ghi"); - entry->setTitle("jkl"); - entry->setGroup(group); - - QList searchResult; - - searchResult = group->search("", Qt::CaseInsensitive); - QCOMPARE(searchResult.count(), 1); - - searchResult = group->search("def", Qt::CaseInsensitive); - QCOMPARE(searchResult.count(), 1); - - searchResult = group->search(" abc ghi ", Qt::CaseInsensitive); - QCOMPARE(searchResult.count(), 1); - - searchResult = group->search("ghi ef", Qt::CaseInsensitive); - QCOMPARE(searchResult.count(), 1); - - searchResult = group->search("abc ef xyz", Qt::CaseInsensitive); - QCOMPARE(searchResult.count(), 0); - - searchResult = group->search("abc kl", Qt::CaseInsensitive); - QCOMPARE(searchResult.count(), 1); - - delete group; -} - void TestGroup::testClone() { Database* db = new Database(); diff --git a/tests/TestGroup.h b/tests/TestGroup.h index 895c2cc5a..2e4019901 100644 --- a/tests/TestGroup.h +++ b/tests/TestGroup.h @@ -31,8 +31,6 @@ private Q_SLOTS: void testEntries(); void testDeleteSignals(); void testCopyCustomIcon(); - void testSearch(); - void testAndConcatenationInSearch(); void testClone(); void testCopyCustomIcons(); void testExportToDb();