aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAqua-sama <aqua@iserlohn-fortress.net>2018-12-19 16:27:41 +0100
committerAqua-sama <aqua@iserlohn-fortress.net>2018-12-19 16:27:41 +0100
commit9100d9bb0fc30df1046e58064e0293b13dbeda89 (patch)
tree074d35fbb0c278d26b3f2d0177558173f47fdbcd
parentAdd subwindow list to Window menu (diff)
downloadsmolbote-9100d9bb0fc30df1046e58064e0293b13dbeda89.tar.xz
Add ContentsMatcher class
-rw-r--r--lib/urlfilter/formats/adblockrule.cpp1
-rw-r--r--lib/urlfilter/formats/adblockrule.h58
-rw-r--r--lib/urlfilter/formats/adblockrule_parse.cpp2
-rw-r--r--lib/urlfilter/formats/adblockrule_parse.h4
-rw-r--r--meson.build4
-rw-r--r--meson_options.txt2
-rw-r--r--test/adblock/adblocktest.cpp124
-rw-r--r--test/adblock/adblocktest.h15
-rw-r--r--test/meson.build6
9 files changed, 142 insertions, 74 deletions
diff --git a/lib/urlfilter/formats/adblockrule.cpp b/lib/urlfilter/formats/adblockrule.cpp
index db1c3c5..60e817f 100644
--- a/lib/urlfilter/formats/adblockrule.cpp
+++ b/lib/urlfilter/formats/adblockrule.cpp
@@ -45,6 +45,7 @@ bool AdBlockRule::match(const QUrl &requestUrl, QWebEngineUrlRequestInfo::Resour
case FilterLeaf::RegularExpressionMatch:
return (regExp->indexIn(requestUrl.toString()) != -1);
default:
+ qWarning("Match type not implemented, returning false!");
return false;
}
}
diff --git a/lib/urlfilter/formats/adblockrule.h b/lib/urlfilter/formats/adblockrule.h
index 9c89dac..3331cac 100644
--- a/lib/urlfilter/formats/adblockrule.h
+++ b/lib/urlfilter/formats/adblockrule.h
@@ -11,6 +11,64 @@
#include "../filterleaf.h"
#include <optional>
+#include <QRegularExpression>
+#include <QStringMatcher>
+
+template <typename T>
+class ContentsMatcher
+{
+public:
+ ContentsMatcher(const QString &pattern, FilterLeaf::UrlMatchType matchType)
+ {
+ this->matchType = matchType;
+ patternLength = pattern.length();
+ matcher.setPattern(pattern);
+
+ if constexpr(std::is_same_v<T, QRegularExpression>) {
+ matcher.setPatternOptions(matcher.patternOptions() | QRegularExpression::CaseInsensitiveOption);
+ } else if constexpr(std::is_same_v<T, QStringMatcher>) {
+ matcher.setCaseSensitivity(Qt::CaseInsensitive);
+ }
+ }
+
+ bool hasMatch(const QString &where) const
+ {
+ if constexpr(std::is_same_v<T, QStringMatcher>) {
+ switch (matchType) {
+ case FilterLeaf::InvalidMatch:
+ case FilterLeaf::RegularExpressionMatch:
+ case FilterLeaf::DomainMatch:
+ qWarning("ContentsMatcher is a String Matcher, but not doing string matching!");
+ return false;
+
+ case FilterLeaf::StringContains:
+ return (matcher.indexIn(where) != -1);
+
+ case FilterLeaf::StringStartsWith:
+ return (matcher.indexIn(where) == 0);
+
+ case FilterLeaf::StringEndsWith:
+ return (matcher.indexIn(where) == where.length() - patternLength);
+
+ case FilterLeaf::StringEquals:
+ return (matcher.indexIn(where) == 0) && (patternLength == where.length());
+ }
+
+ } else if constexpr(std::is_same_v<T, QRegularExpression>) {
+ if(matchType != FilterLeaf::RegularExpressionMatch)
+ qWarning("ContentsMatcher is a regular expression, but not doing a regular expression match!");
+ return matcher.match(where).hasMatch();
+ } else {
+ qWarning("Matcher has no backend, returning false");
+ return false;
+ }
+ }
+
+private:
+ int patternLength;
+ T matcher;
+ FilterLeaf::UrlMatchType matchType;
+};
class AdBlockRule : public FilterLeaf
{
diff --git a/lib/urlfilter/formats/adblockrule_parse.cpp b/lib/urlfilter/formats/adblockrule_parse.cpp
index 0e5bf05..927a6a3 100644
--- a/lib/urlfilter/formats/adblockrule_parse.cpp
+++ b/lib/urlfilter/formats/adblockrule_parse.cpp
@@ -16,7 +16,7 @@
// QString::chop(len) - Removes n characters from the end of the string.
// QString::remove(pos, len) - Removes n characters from the string, starting at the given position index.
-AdBlockRule *loadRule(const QString &filter)
+AdBlockRule *parseRule_adblock(const QString &filter)
{
QString parsedLine = filter.trimmed();
diff --git a/lib/urlfilter/formats/adblockrule_parse.h b/lib/urlfilter/formats/adblockrule_parse.h
index 7d380a8..01255ca 100644
--- a/lib/urlfilter/formats/adblockrule_parse.h
+++ b/lib/urlfilter/formats/adblockrule_parse.h
@@ -11,7 +11,7 @@
class AdBlockRule;
-AdBlockRule *loadRule(const QString &filter);
+AdBlockRule *parseRule_adblock(const QString &filter);
std::optional<QPair<QWebEngineUrlRequestInfo::ResourceType, bool>> parseOption(const QString &option);
-#endif // ADBLOCKRULE_PARSE_H \ No newline at end of file
+#endif // ADBLOCKRULE_PARSE_H
diff --git a/meson.build b/meson.build
index 9c2f0d3..5452574 100644
--- a/meson.build
+++ b/meson.build
@@ -76,5 +76,7 @@ subdir('doc')
subdir('plugins/ConfigurationEditor')
subdir('plugins/ProfileEditor')
-subdir('test')
+if get_option('testing').enabled()
+ subdir('test')
+endif
diff --git a/meson_options.txt b/meson_options.txt
index ee219a7..5362f95 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -9,3 +9,5 @@ option('translations', description: 'Generate and install translations', type: '
# Feature options
option('Breakpad', description: 'Enable breakpad crash reporting', type: 'feature', value: 'auto')
option('Plasma', description: 'Enable KDE plasma integration', type: 'feature', value: 'auto')
+option('testing', description: 'Build tests (requires gtest)', type: 'feature', value: 'auto')
+
diff --git a/test/adblock/adblocktest.cpp b/test/adblock/adblocktest.cpp
index 871b7ca..bbcaf0e 100644
--- a/test/adblock/adblocktest.cpp
+++ b/test/adblock/adblocktest.cpp
@@ -1,65 +1,83 @@
-#include "adblocktest.h"
-#include <QtTest/QtTest>
#include "formats/adblockrule.h"
#include "formats/adblockrule_parse.h"
+#include <gtest/gtest.h>
-void AdBlockTest::parseRule()
-{
- auto *rule = loadRule("/spamdomain/$domain=spamdomain.com,image");
- QCOMPARE(rule != nullptr, true);
- QCOMPARE(rule->match(QUrl::fromUserInput("subdomain.spamdomain.com")), true);
- QCOMPARE(rule->action().first == FilterLeaf::Block, true);
- QCOMPARE(rule->option(QWebEngineUrlRequestInfo::ResourceTypeImage).value(), true);
+TEST(Matcher, StringContains) {
+ ContentsMatcher<QStringMatcher> matcher("spam-pattern", FilterLeaf::StringContains);
+ EXPECT_TRUE(matcher.hasMatch("this string contains a spam-pattern"));
+ EXPECT_FALSE(matcher.hasMatch("this string does not contain the pattern"));
}
-/*void AdBlockTest::parseList()
-{
- std::vector<AdBlockRule> rules;
+TEST(Matcher, StringStartsWith) {
+ ContentsMatcher<QStringMatcher> matcher("beginning", FilterLeaf::StringStartsWith);
+ EXPECT_TRUE(matcher.hasMatch("beginning this string is the pattern"));
+ EXPECT_FALSE(matcher.hasMatch("ending this string is the pattern, the word beginning"));
+ EXPECT_FALSE(matcher.hasMatch("this would be a string where the pattern cannot be found"));
+}
+
+TEST(Matcher, StringEndsWith) {
+ ContentsMatcher<QStringMatcher> matcher("ending", FilterLeaf::StringEndsWith);
+ EXPECT_TRUE(matcher.hasMatch("this string has the proper ending"));
+ EXPECT_FALSE(matcher.hasMatch("and this string doesn't"));
+}
+
+TEST(Matcher, StringEquals) {
+ ContentsMatcher<QStringMatcher> matcher("string-to-match", FilterLeaf::StringEquals);
+ EXPECT_TRUE(matcher.hasMatch("string-to-match"));
+ EXPECT_FALSE(matcher.hasMatch("same-len-string"));
+ EXPECT_FALSE(matcher.hasMatch("not the string-to-match"));
+}
+
+TEST(Matcher, RegularExpression) {
+ ContentsMatcher<QRegularExpression> matcher("banner\\d+", FilterLeaf::RegularExpressionMatch);
+ EXPECT_TRUE(matcher.hasMatch("http://another.com/banner123"));
+ EXPECT_TRUE(matcher.hasMatch("http://another.com/banner321"));
+ EXPECT_FALSE(matcher.hasMatch("http://another.com/banners"));
+
+}
- QFile list("adblock.txt");
- int ruleCount = 0;
- QCOMPARE(list.open(QIODevice::ReadOnly | QIODevice::Text), true);
- {
- QTextStream l(&list);
- QString line;
- while(l.readLineInto(&line)) {
- AdBlockRule rule(line);
- if(rule.isEnabled()) {
- rules.emplace_back(std::move(rule));
- ruleCount++;
- qDebug("added rule: %s", qUtf8Printable(line));
- }
- }
- }
- list.close();
+TEST(AdBlockRule, SimpleRule) {
+ AdBlockRule *rule = parseRule_adblock("/spamdomain/$domain=spamdomain.com,image");
+ EXPECT_TRUE(rule->match(QUrl("subdomain.spamdomain.com")));
+// QCOMPARE(rule->action().first == FilterLeaf::Block, true);
+// QCOMPARE(rule->option(QWebEngineUrlRequestInfo::ResourceTypeImage).value(), true);
+}
- // there should be 3 rules
- QCOMPARE(rules.size(), ruleCount);
+TEST(AdBlockRule, AddressPart) {
+ AdBlockRule *rule = parseRule_adblock("/banner/*/img^");
+ EXPECT_TRUE(rule->match(QUrl("http://example.com/banner/foo/img")));
+ EXPECT_TRUE(rule->match(QUrl("http://example.com/banner/foo/bar/img?param")));
+ EXPECT_TRUE(rule->match(QUrl("http://example.com/banner//img/foo")));
+ EXPECT_FALSE(rule->match(QUrl("http://example.com/banner/img")));
+ EXPECT_FALSE(rule->match(QUrl("http://example.com/banner/foo/imgraph")));
+ EXPECT_FALSE(rule->match(QUrl("http://example.com/banner/foo/img.gif")));
+}
- // block by address part
- QCOMPARE(check(rules, QUrl("http://example.com/banner/foo/img")), true);
- QCOMPARE(check(rules, QUrl("http://example.com/banner/foo/bar/img?param")), true);
- QCOMPARE(check(rules, QUrl("http://example.com/banner//img/foo")), true);
- QCOMPARE(check(rules, QUrl("http://example.com/banner/img")), false);
- QCOMPARE(check(rules, QUrl("http://example.com/banner/foo/imgraph")), false);
- QCOMPARE(check(rules, QUrl("http://example.com/banner/foo/img.gif")), false);
+TEST(AdBlockRule, Domain){
+ AdBlockRule *rule = parseRule_adblock("||ads.example.com^");
+ EXPECT_TRUE(rule->match(QUrl("http://ads.example.com/foo.gif")));
+ EXPECT_TRUE(rule->match(QUrl("http://server1.ads.example.com/foo.gif")));
+ EXPECT_TRUE(rule->match(QUrl("https://ads.example.com:8000/")));
+ EXPECT_FALSE(rule->match(QUrl("http://ads.example.com.ua/foo.gif")));
+ EXPECT_FALSE(rule->match(QUrl("http://example.com/redirect/http://ads.example.com/")));
+}
- // block by domain
- QCOMPARE(check(rules, QUrl("http://ads.example.com/foo.gif")), true);
- QCOMPARE(check(rules, QUrl("http://server1.ads.example.com/foo.gif")), true);
- QCOMPARE(check(rules, QUrl("https://ads.example.com:8000/")), true);
- QCOMPARE(check(rules, QUrl("http://ads.example.com.ua/foo.gif")), false);
- QCOMPARE(check(rules, QUrl("http://example.com/redirect/http://ads.example.com/")), false);
- // block exact address
- QCOMPARE(check(rules, QUrl("http://example.com/")), true);
- QCOMPARE(check(rules, QUrl("http://example.com/foo.gif")), false);
- QCOMPARE(check(rules, QUrl("http://example.info/redirect/http://example.com/")), false);
+TEST(AdBlockRule, ExactAddress){
+ AdBlockRule *rule = parseRule_adblock("|http://example.com/|");
+ EXPECT_TRUE(rule->match(QUrl("http://example.com/")));
+ EXPECT_FALSE(rule->match(QUrl("http://example.com/foo.gif")));
+ EXPECT_FALSE(rule->match(QUrl("http://example.info/redirect/http://example.com/")));
+}
- // regular expression
- QCOMPARE(check(rules, QUrl("http://another.com/banner123")), true);
- QCOMPARE(check(rules, QUrl("http://another.com/banner321")), true);
- QCOMPARE(check(rules, QUrl("http://another.com/banners")), false);
-}*/
+TEST(AdBlockRule, RegularExpression) {
+ AdBlockRule *rule = parseRule_adblock("/banner\\d+/");
+ EXPECT_TRUE(rule->match(QUrl("http://another.com/banner123")));
+ EXPECT_TRUE(rule->match(QUrl("http://another.com/banner321")));
+ EXPECT_FALSE(rule->match(QUrl("http://another.com/banners")));
+}
-QTEST_GUILESS_MAIN(AdBlockTest)
+int main(int argc, char **argv) {
+ testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
diff --git a/test/adblock/adblocktest.h b/test/adblock/adblocktest.h
deleted file mode 100644
index 7e58197..0000000
--- a/test/adblock/adblocktest.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#ifndef ADBLOCKTEST_H
-#define ADBLOCKTEST_H
-
-#include <QObject>
-
-class AdBlockTest : public QObject
-{
- Q_OBJECT
-
-private slots:
- void parseRule();
- //void parseList();
-};
-
-#endif // ADBLOCKTEST_H
diff --git a/test/meson.build b/test/meson.build
index df6a9c9..e2e25f6 100644
--- a/test/meson.build
+++ b/test/meson.build
@@ -1,7 +1,9 @@
+dep_gtest = dependency('gtest')
+
# Adblock parsing test
adblock = executable('AdblockTest',
- dependencies: [dep_qt5, dep_urlfilter],
- sources: ['adblock/adblocktest.cpp', qt5.preprocess(moc_headers: 'adblock/adblocktest.h', dependencies: dep_qt5)]
+ dependencies: [dep_gtest, dep_qt5, dep_urlfilter],
+ sources: ['adblock/adblocktest.cpp']
)
test('urlfilter-adblock', adblock, workdir: meson.current_source_dir())