Index: test/BaseJsTest.h |
diff --git a/test/BaseJsTest.h b/test/BaseJsTest.h |
index dc83a3785fa511e0c06546d08f78b06b62f16f87..b02745fcb848662139b7ce2a0f9f081db736a492 100644 |
--- a/test/BaseJsTest.h |
+++ b/test/BaseJsTest.h |
@@ -22,6 +22,37 @@ |
#include <gtest/gtest.h> |
#include "../src/Thread.h" |
+// Strictly speaking in each test there should be a special implementation of |
+// an interface, which is merely referenced by a wrapper and the latter should |
+// be injected into JsEngine or what ever. However the everthing a test often |
+// actually needs is the access to pending tasks. Therefore instantiation of |
+// implemenation of an interface, creation of shared tasks and sharing them |
+// with tasks in test is located in this class. |
+// |
+// Task is passed as an additional template parameter instead of using traits |
+// (CRTP does not work with types in derived class) merely to simplify the code |
+// by minimization. |
+template<typename T, typename TTask, typename Interface> |
+class DelayedMixin : public Interface |
+{ |
+public: |
+ typedef TTask Task; |
+ typedef std::shared_ptr<std::list<Task>> SharedTasks; |
+ static std::unique_ptr<Interface> New(SharedTasks& tasks) |
+ { |
+ std::unique_ptr<T> result(new T()); |
+ tasks = result->tasks; |
+ return std::move(result); |
+ } |
+protected: |
+ DelayedMixin() |
+ : tasks(std::make_shared<std::list<Task>>()) |
+ { |
+ } |
+ |
+ SharedTasks tasks; |
+}; |
+ |
class ThrowingTimer : public AdblockPlus::ITimer |
{ |
void SetTimer(const std::chrono::milliseconds& timeout, const TimerCallback& timerCallback) override |
@@ -37,6 +68,30 @@ class NoopTimer : public AdblockPlus::ITimer |
} |
}; |
+struct DelayedTimerTask |
+{ |
+ std::chrono::milliseconds timeout; |
+ AdblockPlus::ITimer::TimerCallback callback; |
+}; |
+ |
+class DelayedTimer : public DelayedMixin<DelayedTimer, DelayedTimerTask, AdblockPlus::ITimer> |
+{ |
+public: |
+ void SetTimer(const std::chrono::milliseconds& timeout, const TimerCallback& timerCallback) override |
+ { |
+ Task task = { timeout, timerCallback }; |
+ tasks->emplace_back(task); |
+ } |
+ |
+ // JS part often schedules download requests using Utils.runAsync which calls |
+ // setTimeout(callback, 0). So, we need to firstly process those timers |
+ // to actually schedule web requests and afterwards we may inspect pending |
+ // web requests. |
+ // non-immeditate timers are not touched |
+ static void ProcessImmediateTimers(DelayedTimer::SharedTasks& timerTasks); |
+}; |
+ |
+ |
class ThrowingLogSystem : public AdblockPlus::LogSystem |
{ |
public: |
@@ -156,6 +211,23 @@ public: |
} |
}; |
+struct DelayedWebRequestTask |
+{ |
+ std::string url; |
+ AdblockPlus::HeaderList headers; |
+ AdblockPlus::IWebRequest::GetCallback getCallback; |
+}; |
+ |
+class DelayedWebRequest : public DelayedMixin<DelayedWebRequest, DelayedWebRequestTask, AdblockPlus::IWebRequest> |
+{ |
+public: |
+ void GET(const std::string& url, const AdblockPlus::HeaderList& requestHeaders, const GetCallback& callback) override |
+ { |
+ Task task = { url, requestHeaders, callback }; |
+ tasks->emplace_back(task); |
+ } |
+}; |
+ |
class LazyLogSystem : public AdblockPlus::LogSystem |
{ |
public: |