From c74367d82c1c7bec393548d2e5014c794333822f Mon Sep 17 00:00:00 2001 From: Aqua-sama Date: Tue, 16 Oct 2018 17:25:40 +0200 Subject: urlfilter: Add FilterTree class FilterTree is a class that holds filter rules, sorted by the domain they are to be applied on. The rules are to follow FilterLeaf as interface. - Add a hostlist rule format to FilterTree. - Add a test for hostlist format. --- test/CMakeLists.txt | 15 ++++++++-- test/adblock/adblocktest.cpp | 65 ++++++++++++++++++++++++++++++++++++++++++ test/adblock/adblocktest.h | 13 +++++++++ test/hostlist.txt | 6 ++++ test/hostlist/hostlisttest.cpp | 42 +++++++++++++++++++++++++++ test/hostlist/hostlisttest.h | 19 ++++++++++++ test/urlfilter/adblocktest.cpp | 65 ------------------------------------------ test/urlfilter/adblocktest.h | 13 --------- 8 files changed, 157 insertions(+), 81 deletions(-) create mode 100644 test/adblock/adblocktest.cpp create mode 100644 test/adblock/adblocktest.h create mode 100644 test/hostlist.txt create mode 100644 test/hostlist/hostlisttest.cpp create mode 100644 test/hostlist/hostlisttest.h delete mode 100644 test/urlfilter/adblocktest.cpp delete mode 100644 test/urlfilter/adblocktest.h (limited to 'test') diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 4302ab2..6b740d7 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -3,10 +3,19 @@ set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) add_executable(AdBlockTest - urlfilter/adblocktest.cpp - urlfilter/adblocktest.h + adblock/adblocktest.cpp + adblock/adblocktest.h ) target_include_directories(AdBlockTest PRIVATE ../lib/urlfilter) - target_link_libraries(AdBlockTest Qt5::Test urlfilter) + +add_executable(HostlistTest + hostlist/hostlisttest.cpp + hostlist/hostlisttest.h +) +target_include_directories(HostlistTest PRIVATE ../lib/urlfilter/) +target_link_libraries(HostlistTest Qt5::Test urlfilter) + +add_test(NAME urlfilter-adblock COMMAND AdBlockTest WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}) +add_test(NAME urlfilter-hostlist COMMAND HostlistTest WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}) diff --git a/test/adblock/adblocktest.cpp b/test/adblock/adblocktest.cpp new file mode 100644 index 0000000..b31d965 --- /dev/null +++ b/test/adblock/adblocktest.cpp @@ -0,0 +1,65 @@ +#include "adblocktest.h" +#include +#include "filterrule.h" +#include "formats/adblockrule.h" + +inline bool check(const std::vector rules, const QUrl &url) +{ + for(const AdBlockRule &rule : rules) { + if(rule.matchesDomain(qHash(url.host())) && rule.matchesUrl(url)) + return true; + } + return false; +} + +void AdBlockTest::parseList() +{ + std::vector rules; + + 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(); + + // there should be 3 rules + QCOMPARE(rules.size(), ruleCount); + + // 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); + + // 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); + + // 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); +} + +QTEST_GUILESS_MAIN(AdBlockTest) diff --git a/test/adblock/adblocktest.h b/test/adblock/adblocktest.h new file mode 100644 index 0000000..95cb7e2 --- /dev/null +++ b/test/adblock/adblocktest.h @@ -0,0 +1,13 @@ +#ifndef ADBLOCKTEST_H +#define ADBLOCKTEST_H + +#include +class AdBlockTest : public QObject +{ + Q_OBJECT + +private slots: + void parseList(); +}; + +#endif // ADBLOCKTEST_H diff --git a/test/hostlist.txt b/test/hostlist.txt new file mode 100644 index 0000000..a0b4e5c --- /dev/null +++ b/test/hostlist.txt @@ -0,0 +1,6 @@ +# This is a comment, and after it comes a blank line + +127.0.0.1 localhost.localdomain + +0.0.0.0 blockeddomain.com +0.0.0.0 blockeddomain.first blockeddomain.second diff --git a/test/hostlist/hostlisttest.cpp b/test/hostlist/hostlisttest.cpp new file mode 100644 index 0000000..46f6a85 --- /dev/null +++ b/test/hostlist/hostlisttest.cpp @@ -0,0 +1,42 @@ +#include "hostlisttest.h" +#include + +void HostlistTest::parseList() +{ + //FilterTree tree; + + // load filters + QFile hostlist("hostlist.txt"); + QCOMPARE(hostlist.open(QIODevice::ReadOnly | QIODevice::Text), true); + QCOMPARE(loadHostlist(hostlist, &tree), true); + + QCOMPARE(tree.branches().length(), 1); +} + +void HostlistTest::checkRules() +{ + // test block + QVector block = tree.match(QString(), "blockeddomain.com"); + QCOMPARE(block.length(), 1); + QCOMPARE(block.constFirst()->action(), FilterLeaf::Block); + + // test redirect + QVector redirectResult = tree.match(QString(), "localhost.localdomain"); + QCOMPARE(redirectResult.length(), 1); + QCOMPARE(redirectResult.at(0)->action(), FilterLeaf::Redirect); + QCOMPARE(redirectResult.at(0)->redirect(), "127.0.0.1"); + + // two domains on one line + QVector blockFirst = tree.match(QString(), "blockeddomain.first"); + QCOMPARE(blockFirst.length(), 1); + QCOMPARE(blockFirst.constFirst()->action(), FilterLeaf::Block); + QVector blockSecond = tree.match(QString(), "blockeddomain.second"); + QCOMPARE(blockSecond.length(), 1); + QCOMPARE(blockSecond.constFirst()->action(), FilterLeaf::Block); + + // domain not on list + QVector missing = tree.match(QString(), "other.domain"); + QCOMPARE(missing.length(), 0); +} + +QTEST_GUILESS_MAIN(HostlistTest) diff --git a/test/hostlist/hostlisttest.h b/test/hostlist/hostlisttest.h new file mode 100644 index 0000000..9a87e0d --- /dev/null +++ b/test/hostlist/hostlisttest.h @@ -0,0 +1,19 @@ +#ifndef HOSTLIST_TEST +#define HOSTLIST_TEST + +#include +#include "filtertree.h" + +class HostlistTest : public QObject +{ + Q_OBJECT + +private slots: + void parseList(); + void checkRules(); + +private: + FilterTree tree; +}; + +#endif diff --git a/test/urlfilter/adblocktest.cpp b/test/urlfilter/adblocktest.cpp deleted file mode 100644 index b31d965..0000000 --- a/test/urlfilter/adblocktest.cpp +++ /dev/null @@ -1,65 +0,0 @@ -#include "adblocktest.h" -#include -#include "filterrule.h" -#include "formats/adblockrule.h" - -inline bool check(const std::vector rules, const QUrl &url) -{ - for(const AdBlockRule &rule : rules) { - if(rule.matchesDomain(qHash(url.host())) && rule.matchesUrl(url)) - return true; - } - return false; -} - -void AdBlockTest::parseList() -{ - std::vector rules; - - 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(); - - // there should be 3 rules - QCOMPARE(rules.size(), ruleCount); - - // 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); - - // 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); - - // 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); -} - -QTEST_GUILESS_MAIN(AdBlockTest) diff --git a/test/urlfilter/adblocktest.h b/test/urlfilter/adblocktest.h deleted file mode 100644 index 95cb7e2..0000000 --- a/test/urlfilter/adblocktest.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef ADBLOCKTEST_H -#define ADBLOCKTEST_H - -#include -class AdBlockTest : public QObject -{ - Q_OBJECT - -private slots: - void parseList(); -}; - -#endif // ADBLOCKTEST_H -- cgit v1.2.1