From 4f78c32461a332e44e49ff95d44b71e7026c2f6c Mon Sep 17 00:00:00 2001 From: Florian Geyer Date: Sun, 22 Jul 2012 14:04:50 +0200 Subject: [PATCH] Add custom wildcard matcher. --- src/CMakeLists.txt | 2 + src/autotype/WildcardMatcher.cpp | 96 +++++++++++++++++++++++ src/autotype/WildcardMatcher.h | 49 ++++++++++++ tests/CMakeLists.txt | 3 + tests/TestWildcardMatcher.cpp | 129 +++++++++++++++++++++++++++++++ tests/TestWildcardMatcher.h | 54 +++++++++++++ 6 files changed, 333 insertions(+) create mode 100644 src/autotype/WildcardMatcher.cpp create mode 100644 src/autotype/WildcardMatcher.h create mode 100644 tests/TestWildcardMatcher.cpp create mode 100644 tests/TestWildcardMatcher.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 860b21575..7c6625ae0 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -23,6 +23,7 @@ set(keepassx_SOURCES autotype/AutoTypeSelectDialog.cpp autotype/AutoTypeSelectView.cpp autotype/ShortcutWidget.cpp + autotype/WildcardMatcher.cpp autotype/WindowSelectComboBox.cpp core/AutoTypeAssociations.cpp core/Config.cpp @@ -104,6 +105,7 @@ set(keepassx_MOC autotype/AutoTypeSelectDialog.h autotype/AutoTypeSelectView.h autotype/ShortcutWidget.h + autotype/WildcardMatcher.h autotype/WindowSelectComboBox.h core/AutoTypeAssociations.h core/Config.h diff --git a/src/autotype/WildcardMatcher.cpp b/src/autotype/WildcardMatcher.cpp new file mode 100644 index 000000000..ce6fbfe11 --- /dev/null +++ b/src/autotype/WildcardMatcher.cpp @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2012 Felix 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 "WildcardMatcher.h" + +#include + +const QString WildcardMatcher::Wildcard = "*"; + +WildcardMatcher::WildcardMatcher(QString text, QObject* parent) : + QObject(parent) +{ + m_text = text; +} + +bool WildcardMatcher::match(QString pattern) +{ + m_pattern = pattern; + + if (patternContainsWildcard()) { + return matchWithWildcards(); + } + else { + return patternEqualsText(); + } +} + +bool WildcardMatcher::patternContainsWildcard() +{ + return m_pattern.contains(Wildcard); +} + +bool WildcardMatcher::patternEqualsText() +{ + return m_text.compare(m_pattern) == 0; +} + +bool WildcardMatcher::matchWithWildcards() +{ + QStringList parts = m_pattern.split(Wildcard, QString::KeepEmptyParts); + Q_ASSERT(parts.size() >= 2); + + if (startOrEndDoesNotMatch(parts)) { + return false; + } + + return partsMatch(parts); +} + +bool WildcardMatcher::startOrEndDoesNotMatch(QStringList parts) +{ + return !m_text.startsWith(parts.first()) || !m_text.endsWith(parts.last()); +} + +bool WildcardMatcher::partsMatch(QStringList parts) +{ + int index = 0; + Q_FOREACH (QString part, parts) { + int matchIndex = getMatchIndex(part, index); + if (noMatchFound(matchIndex)) { + return false; + } + index = calculateNewIndex(matchIndex, part.length()); + } + + return true; +} + +int WildcardMatcher::getMatchIndex(QString part, int startIndex) +{ + return m_text.indexOf(part, startIndex); +} + +bool WildcardMatcher::noMatchFound(int index) +{ + return index < 0; +} + +int WildcardMatcher::calculateNewIndex(int matchIndex, int partLength) +{ + return matchIndex + partLength; +} diff --git a/src/autotype/WildcardMatcher.h b/src/autotype/WildcardMatcher.h new file mode 100644 index 000000000..fdf623822 --- /dev/null +++ b/src/autotype/WildcardMatcher.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2012 Felix 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_WILDCARDMATCHER_H +#define KEEPASSX_WILDCARDMATCHER_H + +#include + +#include "core/Global.h" + +class WildcardMatcher : public QObject +{ + Q_OBJECT + +public: + explicit WildcardMatcher(QString text, QObject* parent = Q_NULLPTR); + + static const QString Wildcard; + + bool match(QString pattern); + +private: + QString m_text; + QString m_pattern; + bool patternEqualsText(); + bool patternContainsWildcard(); + bool matchWithWildcards(); + bool startOrEndDoesNotMatch(QStringList parts); + bool partsMatch(QStringList parts); + int getMatchIndex(QString part, int startIndex); + bool noMatchFound(int index); + int calculateNewIndex(int matchIndex, int partLength); +}; + +#endif // KEEPASSX_WILDCARDMATCHER_H diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index c422c5adb..8d9c5bdd1 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -149,6 +149,9 @@ add_unit_test(NAME testkeepass1reader SOURCES TestKeePass1Reader.cpp MOCS TestKe add_unit_test(NAME testqsavefile SOURCES TestQSaveFile.cpp MOCS TestQSaveFile.h LIBS ${TEST_LIBRARIES}) +add_unit_test(NAME testwildcardmatcher SOURCES TestWildcardMatcher.cpp MOCS TestWildcardMatcher.h + LIBS ${TEST_LIBRARIES}) + if(WITH_GUI_TESTS) add_subdirectory(gui) endif(WITH_GUI_TESTS) diff --git a/tests/TestWildcardMatcher.cpp b/tests/TestWildcardMatcher.cpp new file mode 100644 index 000000000..e8febe9e4 --- /dev/null +++ b/tests/TestWildcardMatcher.cpp @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2012 Felix 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 "TestWildcardMatcher.h" + +#include + +#include "tests.h" +#include "autotype/WildcardMatcher.h" + +const QString TestWildcardMatcher::DefaultText = QString("some text"); +const QString TestWildcardMatcher::AlternativeText = QString("some other text"); + +void TestWildcardMatcher::testMatchWithoutWildcard() +{ + initMatcher(DefaultText); + QString pattern = DefaultText; + verifyMatch(pattern); +} + +void TestWildcardMatcher::testNoMatchWithoutWildcard() +{ + initMatcher(DefaultText); + QString pattern = QString("no match text"); + verifyNoMatch(pattern); +} + +void TestWildcardMatcher::testMatchWithOneWildcardInTheMiddle() +{ + initMatcher(AlternativeText); + QString pattern("some*text"); + verifyMatch(pattern); +} + +void TestWildcardMatcher::testNoMatchWithOneWildcardInTheMiddle() +{ + initMatcher(AlternativeText); + QString pattern("differen*text"); + verifyNoMatch(pattern); +} + +void TestWildcardMatcher::testMatchWithOneWildcardAtBegin() +{ + initMatcher(DefaultText); + QString pattern("*text"); + verifyMatch(pattern); +} + +void TestWildcardMatcher::testNoMatchWithOneWildcardAtBegin() +{ + initMatcher(DefaultText); + QString pattern("*text something else"); + verifyNoMatch(pattern); +} + +void TestWildcardMatcher::testMatchWithOneWildcardAtEnd() +{ + initMatcher(DefaultText); + QString pattern("some*"); + verifyMatch(pattern); +} + +void TestWildcardMatcher::testNoMatchWithOneWildcardAtEnd() +{ + initMatcher(DefaultText); + QString pattern("some other*"); + verifyNoMatch(pattern); +} + +void TestWildcardMatcher::testMatchWithMultipleWildcards() +{ + initMatcher(AlternativeText); + QString pattern("some*th*text"); + verifyMatch(pattern); +} + +void TestWildcardMatcher::testNoMatchWithMultipleWildcards() +{ + initMatcher(AlternativeText); + QString pattern("some*abc*text"); + verifyNoMatch(pattern); +} + +void TestWildcardMatcher::testMatchJustWildcard() +{ + initMatcher(AlternativeText); + QString pattern("*"); + verifyMatch(pattern); +} + +void TestWildcardMatcher::testMatchFollowingWildcards() +{ + initMatcher(DefaultText); + QString pattern("some t**t"); + verifyMatch(pattern); +} + +void TestWildcardMatcher::initMatcher(QString text) +{ + m_matcher = new WildcardMatcher(text); +} + +void TestWildcardMatcher::verifyMatch(QString pattern) +{ + bool matchResult = m_matcher->match(pattern); + QVERIFY(matchResult); +} + +void TestWildcardMatcher::verifyNoMatch(QString pattern) +{ + bool matchResult = m_matcher->match(pattern); + QVERIFY(!matchResult); +} + +KEEPASSX_QTEST_CORE_MAIN(TestWildcardMatcher) diff --git a/tests/TestWildcardMatcher.h b/tests/TestWildcardMatcher.h new file mode 100644 index 000000000..2ee1c34ee --- /dev/null +++ b/tests/TestWildcardMatcher.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2012 Felix 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_TESTWILDCARDMATCHER_H +#define KEEPASSX_TESTWILDCARDMATCHER_H + +#include + +class WildcardMatcher; + +class TestWildcardMatcher : public QObject +{ + Q_OBJECT + +private Q_SLOTS: + void testMatchWithoutWildcard(); + void testNoMatchWithoutWildcard(); + void testMatchWithOneWildcardInTheMiddle(); + void testNoMatchWithOneWildcardInTheMiddle(); + void testNoMatchWithOneWildcardAtBegin(); + void testMatchWithOneWildcardAtBegin(); + void testNoMatchWithOneWildcardAtEnd(); + void testMatchWithOneWildcardAtEnd(); + void testMatchWithMultipleWildcards(); + void testNoMatchWithMultipleWildcards(); + void testMatchJustWildcard(); + void testMatchFollowingWildcards(); + +private: + static const QString DefaultText; + static const QString AlternativeText; + + void initMatcher(QString text); + void verifyMatch(QString pattern); + void verifyNoMatch(QString pattern); + + WildcardMatcher* m_matcher; +}; + +#endif // KEEPASSX_TESTWILDCARDMATCHER_H