summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrandomdan <randomdan@localhost>2011-12-20 00:30:20 +0000
committerrandomdan <randomdan@localhost>2011-12-20 00:30:20 +0000
commit31b8a0fc5616d9c2f27e49e1c706a59c90d15a45 (patch)
treebd4191cdd1a2c84635c3c8a7d50fd2fd3723ffd6
parentImproved connection failure logging and instantiation (diff)
downloadproject2-31b8a0fc5616d9c2f27e49e1c706a59c90d15a45.tar.bz2
project2-31b8a0fc5616d9c2f27e49e1c706a59c90d15a45.tar.xz
project2-31b8a0fc5616d9c2f27e49e1c706a59c90d15a45.zip
Split check and test functionality... if and check now take tests as children, adds all, any, none and not as building blocks
-rw-r--r--project2/cgi/cgiAppEngine.h1
-rw-r--r--project2/common/check.cpp29
-rw-r--r--project2/common/check.h25
-rw-r--r--project2/common/checkHost.cpp6
-rw-r--r--project2/common/checkHost.h10
-rw-r--r--project2/common/if.cpp118
-rw-r--r--project2/common/if.h22
-rw-r--r--project2/common/paramChecker.cpp16
-rw-r--r--project2/common/paramChecker.h23
-rw-r--r--project2/common/presenter.h1
-rw-r--r--project2/common/test.cpp7
-rw-r--r--project2/common/test.h14
-rw-r--r--project2/common/validDateCheck.cpp15
-rw-r--r--project2/common/viewHost.h1
-rw-r--r--project2/console/consoleAppEngine.cpp6
-rw-r--r--project2/console/consoleAppEngine.h1
-rw-r--r--project2/regex/Jamfile.jam2
-rw-r--r--project2/regex/regexCheck.h19
-rw-r--r--project2/regex/regexTest.cpp (renamed from project2/regex/regexCheck.cpp)13
-rw-r--r--project2/regex/regexTest.h19
-rw-r--r--project2/sql/Jamfile.jam2
-rw-r--r--project2/sql/sqlTest.cpp (renamed from project2/sql/sqlCheck.cpp)15
-rw-r--r--project2/sql/sqlTest.h (renamed from project2/sql/sqlCheck.h)16
23 files changed, 225 insertions, 156 deletions
diff --git a/project2/cgi/cgiAppEngine.h b/project2/cgi/cgiAppEngine.h
index d4295de..e339576 100644
--- a/project2/cgi/cgiAppEngine.h
+++ b/project2/cgi/cgiAppEngine.h
@@ -3,7 +3,6 @@
#include "appEngine.h"
#include "task.h"
-#include "paramChecker.h"
#include "commonObjects.h"
#include "uuid.h"
#include "taskHost.h"
diff --git a/project2/common/check.cpp b/project2/common/check.cpp
new file mode 100644
index 0000000..c284c8d
--- /dev/null
+++ b/project2/common/check.cpp
@@ -0,0 +1,29 @@
+#include <pch.hpp>
+#include "check.h"
+#include "scriptLoader.h"
+
+DECLARE_LOADER("check", Check);
+StaticMessageException(NoTestsToPerform, "No tests to perform");
+
+Check::Check(ScriptNodePtr p) :
+ SourceObject(p),
+ message(p, "message", "Check failed"),
+ group(p, "group", "default"),
+ present(p, "present", "")
+{
+ p->script->loader.addLoadTarget(p, Storer::into<ElementLoader>(&test));
+}
+
+Check::~Check()
+{
+}
+
+bool
+Check::performCheck() const
+{
+ if (!test) {
+ throw NoTestsToPerform();
+ }
+ return test->passes();
+}
+
diff --git a/project2/common/check.h b/project2/common/check.h
new file mode 100644
index 0000000..e9f44b5
--- /dev/null
+++ b/project2/common/check.h
@@ -0,0 +1,25 @@
+#ifndef CHECK_H
+#define CHECK_H
+
+#include "sourceObject.h"
+#include "variables.h"
+#include "test.h"
+
+/// Base class for Project2 compoments that perform checks
+class Check : public SourceObject {
+ public:
+ Check(ScriptNodePtr p);
+ virtual ~Check();
+
+ bool performCheck() const;
+
+ const Variable message;
+ const Variable group;
+ const Variable present;
+ TestPtr test;
+};
+typedef boost::intrusive_ptr<const Check> CheckCPtr;
+
+#endif
+
+
diff --git a/project2/common/checkHost.cpp b/project2/common/checkHost.cpp
index 4f2ab44..be7b572 100644
--- a/project2/common/checkHost.cpp
+++ b/project2/common/checkHost.cpp
@@ -6,7 +6,7 @@
CheckHost::CheckHost(ScriptReaderPtr s) :
CommonObjects(s)
{
- s->loader.addLoadTarget(s->root(), Storer::into<ElementLoader>(&parameterChecks));
+ s->loader.addLoadTarget(s->root(), Storer::into<ElementLoader>(&checks));
}
CheckHost::~CheckHost()
@@ -17,7 +17,7 @@ void
CheckHost::runChecks() const
{
loadScriptComponents();
- BOOST_FOREACH(const ParamCheckers::value_type & pc, parameterChecks) {
+ BOOST_FOREACH(const Checks::value_type & pc, checks) {
if (!pc->performCheck()) {
ApplicationEngine::getCurrent()->logMessage(false, pc->group(), pc->message());
throw CheckFailure(pc);
@@ -25,7 +25,7 @@ CheckHost::runChecks() const
}
}
-CheckHost::CheckFailure::CheckFailure(ParamCheckerCPtr fc) : failedCheck(fc)
+CheckHost::CheckFailure::CheckFailure(CheckCPtr fc) : failedCheck(fc)
{
}
diff --git a/project2/common/checkHost.h b/project2/common/checkHost.h
index cc32ad4..0721ac5 100644
--- a/project2/common/checkHost.h
+++ b/project2/common/checkHost.h
@@ -1,7 +1,7 @@
#ifndef CHECKHOST_H
#define CHECKHOST_H
-#include "paramChecker.h"
+#include "check.h"
#include "scriptStorage.h"
#include <set>
#include <boost/function.hpp>
@@ -11,17 +11,17 @@ class CheckHost : virtual public CommonObjects {
public:
class CheckFailure : std::exception {
public:
- CheckFailure(ParamCheckerCPtr);
+ CheckFailure(CheckCPtr);
~CheckFailure() throw();
- const ParamCheckerCPtr failedCheck;
+ const CheckCPtr failedCheck;
};
CheckHost(ScriptReaderPtr script);
~CheckHost();
void runChecks() const;
- typedef ANONORDEREDSTORAGEOF(ParamChecker) ParamCheckers;
- ParamCheckers parameterChecks;
+ typedef ANONORDEREDSTORAGEOF(Check) Checks;
+ Checks checks;
};
#endif
diff --git a/project2/common/if.cpp b/project2/common/if.cpp
index 624feef..b9db1db 100644
--- a/project2/common/if.cpp
+++ b/project2/common/if.cpp
@@ -7,53 +7,39 @@
#include <algorithm>
DECLARE_LOADER("if", If);
+StaticMessageException(NoTestsToPerform, "No tests to perform");
-SimpleMessageException(IfModeIsNonsense);
-
-IfSet::IfSet(ScriptNodePtr e) :
- mode(e->value("mode", "and").as<Glib::ustring>() == "or" ? Or : And)
-{
- e->script->loader.addLoadTarget(e, Storer::into<ElementLoader>(&checks));
-}
-
-template <class Range, class Pred>
-bool all(const Range & c, const Pred & p)
+CompoundTest::CompoundTest(ScriptNodePtr s) :
+ SourceObject(s),
+ Test(s)
{
- return (std::find_if(c.begin(), c.end(), !p) == c.end());
-}
-template <class Range, class Pred>
-bool any(const Range & c, const Pred & p)
-{
- return (std::find_if(c.begin(), c.end(), p) != c.end());
-}
-
-bool
-IfSet::passes() const
-{
- if (mode == And) {
- return all(checks, boost::bind(&ParamChecker::performCheck, _1));
- }
- else if (mode == Or) {
- return ::any(checks, boost::bind(&ParamChecker::performCheck, _1));
- }
- throw IfModeIsNonsense(getName());
+ s->script->loader.addLoadTarget(s, Storer::into<ElementLoader>(&tests));
}
If::If(ScriptNodePtr e) :
SourceObject(e),
IHaveSubTasks(e),
- View(e),
- IfSet(e)
+ View(e)
{
e->script->loader.addLoadTarget(e, Storer::into<ElementLoader>(&normal));
e->script->loader.addLoadTarget(e, Storer::into<ElementLoader>(&subViews));
+ e->script->loader.addLoadTarget(e, Storer::into<ElementLoader>(&test));
+}
+
+bool
+If::passes() const
+{
+ if (!test) {
+ throw NoTestsToPerform();
+ }
+ return test->passes();
}
void
If::execute(const MultiRowSetPresenter * presenter) const
{
if (passes()) {
- Logger()->messagef(LOG_DEBUG, "IfSet passed %zu checks, showing %zu views", checks.size(), subViews.size());
+ Logger()->messagef(LOG_DEBUG, "Test passed; showing %zu views", subViews.size());
BOOST_FOREACH(const SubViews::value_type & sq, subViews) {
sq->execute(presenter);
}
@@ -64,14 +50,72 @@ void
If::execute() const
{
if (passes()) {
- Logger()->message(LOG_DEBUG, "IfSet passed");
+ Logger()->messagef(LOG_DEBUG, "Test passed; executing %zu tasks", normal.size());
run(normal);
}
}
-const std::string &
-If::getName() const
-{
- return name;
-}
+class All : public CompoundTest {
+ public:
+ All(ScriptNodePtr s) :
+ SourceObject(s),
+ CompoundTest(s) {
+ }
+ bool passes() const {
+ if (tests.empty()) {
+ throw NoTestsToPerform();
+ }
+ return (std::find_if(tests.begin(), tests.end(), !boost::bind(&Test::passes, _1)) == tests.end());
+ }
+};
+DECLARE_LOADER("all", All);
+
+class Any : public CompoundTest {
+ public:
+ Any(ScriptNodePtr s) :
+ SourceObject(s),
+ CompoundTest(s) {
+ }
+ bool passes() const {
+ if (tests.empty()) {
+ throw NoTestsToPerform();
+ }
+ return (std::find_if(tests.begin(), tests.end(), boost::bind(&Test::passes, _1)) != tests.end());
+ }
+};
+DECLARE_LOADER("any", Any);
+
+class None : public CompoundTest {
+ public:
+ None(ScriptNodePtr s) :
+ SourceObject(s),
+ CompoundTest(s) {
+ }
+ bool passes() const {
+ if (tests.empty()) {
+ throw NoTestsToPerform();
+ }
+ return (std::find_if(tests.begin(), tests.end(), boost::bind(&Test::passes, _1)) == tests.end());
+ }
+};
+DECLARE_LOADER("none", None);
+
+class Not : public Test {
+ public:
+ Not(ScriptNodePtr s) :
+ SourceObject(s),
+ Test(s)
+ {
+ s->script->loader.addLoadTarget(s, Storer::into<ElementLoader>(&test));
+ }
+ bool passes() const {
+ if (!test) {
+ throw NoTestsToPerform();
+ }
+ return !test->passes();
+ }
+ private:
+ TestPtr test;
+};
+DECLARE_LOADER("not", Not);
diff --git a/project2/common/if.h b/project2/common/if.h
index e27003d..bcf83cd 100644
--- a/project2/common/if.h
+++ b/project2/common/if.h
@@ -3,24 +3,19 @@
#include "iHaveSubTasks.h"
#include "view.h"
-#include "paramChecker.h"
+#include "test.h"
-class IfSet : public virtual IntrusivePtrBase {
+class CompoundTest : public Test {
public:
- IfSet(ScriptNodePtr);
- bool passes() const;
+ CompoundTest(ScriptNodePtr);
- private:
- virtual const std::string & getName() const = 0;
- enum Mode { And, Or };
- Mode mode;
- typedef ANONORDEREDSTORAGEOF(ParamChecker) ParamCheckers;
protected:
- ParamCheckers checks;
+ typedef ANONORDEREDSTORAGEOF(Test) Tests;
+ Tests tests;
};
/// Project2 component to conditionally execute its children
-class If : public IHaveSubTasks, public View, public IfSet {
+class If : public IHaveSubTasks, public View {
public:
If(ScriptNodePtr);
@@ -28,10 +23,11 @@ class If : public IHaveSubTasks, public View, public IfSet {
virtual void execute() const;
private:
+ bool passes() const;
+
typedef ANONSTORAGEOF(View) SubViews;
SubViews subViews;
-
- const std::string & getName() const;
+ TestPtr test;
};
#endif
diff --git a/project2/common/paramChecker.cpp b/project2/common/paramChecker.cpp
deleted file mode 100644
index 3d6b046..0000000
--- a/project2/common/paramChecker.cpp
+++ /dev/null
@@ -1,16 +0,0 @@
-#include <pch.hpp>
-#include "paramChecker.h"
-#include "scriptLoader.h"
-
-ParamChecker::ParamChecker(ScriptNodePtr p) :
- SourceObject(p),
- message(p, "message", "Check failed"),
- group(p, "group", "default"),
- present(p, "present", "")
-{
-}
-
-ParamChecker::~ParamChecker()
-{
-}
-
diff --git a/project2/common/paramChecker.h b/project2/common/paramChecker.h
deleted file mode 100644
index db3d8de..0000000
--- a/project2/common/paramChecker.h
+++ /dev/null
@@ -1,23 +0,0 @@
-#ifndef PARAMCHECKER_H
-#define PARAMCHECKER_H
-
-#include "sourceObject.h"
-#include "variables.h"
-
-/// Base class for Project2 compoments that perform tests/checks
-class ParamChecker : public SourceObject {
- public:
- ParamChecker(ScriptNodePtr p);
- virtual ~ParamChecker();
-
- virtual bool performCheck() const = 0;
-
- const Variable message;
- const Variable group;
- const Variable present;
-};
-typedef boost::intrusive_ptr<const ParamChecker> ParamCheckerCPtr;
-
-#endif
-
-
diff --git a/project2/common/presenter.h b/project2/common/presenter.h
index de233a3..eaba17f 100644
--- a/project2/common/presenter.h
+++ b/project2/common/presenter.h
@@ -6,7 +6,6 @@
#include <boost/function.hpp>
#include <glibmm/ustring.h>
#include "view.h"
-#include "paramChecker.h"
#include "scriptLoader.h"
class NameValuePairPresenter : public virtual IntrusivePtrBase {
diff --git a/project2/common/test.cpp b/project2/common/test.cpp
new file mode 100644
index 0000000..f4066af
--- /dev/null
+++ b/project2/common/test.cpp
@@ -0,0 +1,7 @@
+#include "test.h"
+
+Test::Test(ScriptNodePtr s) :
+ SourceObject(s)
+{
+}
+
diff --git a/project2/common/test.h b/project2/common/test.h
new file mode 100644
index 0000000..aa2709c
--- /dev/null
+++ b/project2/common/test.h
@@ -0,0 +1,14 @@
+#ifndef TEST_H
+#define TEST_H
+
+#include "sourceObject.h"
+#include "scripts.h"
+
+class Test : public virtual SourceObject {
+ public:
+ Test(ScriptNodePtr);
+ virtual bool passes() const = 0;
+};
+typedef boost::intrusive_ptr<const Test> TestPtr;
+
+#endif
diff --git a/project2/common/validDateCheck.cpp b/project2/common/validDateCheck.cpp
index d83fa1f..be983b4 100644
--- a/project2/common/validDateCheck.cpp
+++ b/project2/common/validDateCheck.cpp
@@ -2,26 +2,27 @@
#include "logger.h"
#include "scriptLoader.h"
#include "commonObjects.h"
-#include "paramChecker.h"
+#include "test.h"
#include "variables.h"
#include "scripts.h"
-class ValidDateCheck : public ParamChecker {
+class ValidDateTest : public Test {
public:
- ValidDateCheck(ScriptNodePtr p) :
- ParamChecker(p),
+ ValidDateTest(ScriptNodePtr p) :
+ SourceObject(p),
+ Test(p),
applyTo(p, "apply-to"),
format(p, "format"),
warnLev(p->value("warn", true).as<bool>() ? LOG_WARNING : LOG_INFO)
{
}
- ~ValidDateCheck()
+ ~ValidDateTest()
{
}
bool
- performCheck() const
+ passes() const
{
struct tm tm, ftm;
memset(&tm, 0, sizeof(struct tm));
@@ -61,5 +62,5 @@ class ValidDateCheck : public ParamChecker {
int warnLev;
};
-DECLARE_LOADER("validdatecheck", ValidDateCheck);
+DECLARE_LOADER("validdatetest", ValidDateTest);
diff --git a/project2/common/viewHost.h b/project2/common/viewHost.h
index 39849ec..a1468ed 100644
--- a/project2/common/viewHost.h
+++ b/project2/common/viewHost.h
@@ -1,7 +1,6 @@
#ifndef VIEWHOST_H
#define VIEWHOST_H
-#include "paramChecker.h"
#include "scriptStorage.h"
#include "presenter.h"
#include "checkHost.h"
diff --git a/project2/console/consoleAppEngine.cpp b/project2/console/consoleAppEngine.cpp
index cb8109f..7643cad 100644
--- a/project2/console/consoleAppEngine.cpp
+++ b/project2/console/consoleAppEngine.cpp
@@ -28,12 +28,6 @@ ConsoleApplicationEngine::~ConsoleApplicationEngine()
}
void
-onCheckFailureHelper(boost::intrusive_ptr<const ParamChecker> pc)
-{
- throw std::runtime_error(pc->message());
-}
-
-void
ConsoleApplicationEngine::process() const
{
try {
diff --git a/project2/console/consoleAppEngine.h b/project2/console/consoleAppEngine.h
index 9a9ce26..a0f72e5 100644
--- a/project2/console/consoleAppEngine.h
+++ b/project2/console/consoleAppEngine.h
@@ -3,7 +3,6 @@
#include "appEngine.h"
#include "task.h"
-#include "paramChecker.h"
#include "presenter.h"
#include "commonObjects.h"
#include "view.h"
diff --git a/project2/regex/Jamfile.jam b/project2/regex/Jamfile.jam
index 7bb9d16..1849b45 100644
--- a/project2/regex/Jamfile.jam
+++ b/project2/regex/Jamfile.jam
@@ -3,7 +3,7 @@ alias glibmm : : : :
<linkflags>"`pkg-config --libs glibmm-2.4`"
;
lib p2regex :
- regexCheck.cpp regexRows.cpp
+ [ glob *.cpp ]
:
<include>../../libmisc
<library>glibmm
diff --git a/project2/regex/regexCheck.h b/project2/regex/regexCheck.h
deleted file mode 100644
index 2ddc545..0000000
--- a/project2/regex/regexCheck.h
+++ /dev/null
@@ -1,19 +0,0 @@
-#ifndef REGEXCHECK_H
-#define REGEXCHECK_H
-
-#include "paramChecker.h"
-#include "variables.h"
-
-/// Project2 component to test the value of a variable against a regular expression
-class RegexCheck : public ParamChecker {
- public:
- RegexCheck(ScriptNodePtr p);
- virtual ~RegexCheck();
-
- bool performCheck() const;
-
- const Variable applyTo;
- const Variable regex;
-};
-
-#endif
diff --git a/project2/regex/regexCheck.cpp b/project2/regex/regexTest.cpp
index e7975bc..93ee2f7 100644
--- a/project2/regex/regexCheck.cpp
+++ b/project2/regex/regexTest.cpp
@@ -1,23 +1,24 @@
-#include "regexCheck.h"
+#include "regexTest.h"
#include "scriptLoader.h"
#include "commonObjects.h"
#include <glibmm/regex.h>
-DECLARE_LOADER("regexcheck", RegexCheck);
+DECLARE_LOADER("regextest", RegexTest);
-RegexCheck::RegexCheck(ScriptNodePtr p) :
- ParamChecker(p),
+RegexTest::RegexTest(ScriptNodePtr p) :
+ SourceObject(p),
+ Test(p),
applyTo(p, "apply-to"),
regex(p, "regex")
{
}
-RegexCheck::~RegexCheck()
+RegexTest::~RegexTest()
{
}
bool
-RegexCheck::performCheck() const
+RegexTest::passes() const
{
Glib::RefPtr<Glib::Regex> reg = Glib::Regex::create(regex());
return reg->match(applyTo());
diff --git a/project2/regex/regexTest.h b/project2/regex/regexTest.h
new file mode 100644
index 0000000..f3459bc
--- /dev/null
+++ b/project2/regex/regexTest.h
@@ -0,0 +1,19 @@
+#ifndef REGEXTEST_H
+#define REGEXTEST_H
+
+#include "test.h"
+#include "variables.h"
+
+/// Project2 component to test the value of a variable against a regular expression
+class RegexTest : public Test {
+ public:
+ RegexTest(ScriptNodePtr p);
+ virtual ~RegexTest();
+
+ bool passes() const;
+
+ const Variable applyTo;
+ const Variable regex;
+};
+
+#endif
diff --git a/project2/sql/Jamfile.jam b/project2/sql/Jamfile.jam
index 068394f..3e63abb 100644
--- a/project2/sql/Jamfile.jam
+++ b/project2/sql/Jamfile.jam
@@ -32,7 +32,7 @@ cpp-pch pch : pch.hpp :
;
lib p2sql :
pch
- sqlCheck.cpp sqlWriter.cpp sqlTask.cpp sqlMergeTask.cpp sqlRows.cpp sqlCache.cpp sqlVariableBinder.cpp tablepatch.cpp rdbmsDataSource.cpp
+ sqlTest.cpp sqlWriter.cpp sqlTask.cpp sqlMergeTask.cpp sqlRows.cpp sqlCache.cpp sqlVariableBinder.cpp tablepatch.cpp rdbmsDataSource.cpp
sqlHandleAsVariableType.cpp
../../libdbpp//dbpp
:
diff --git a/project2/sql/sqlCheck.cpp b/project2/sql/sqlTest.cpp
index b1d369c..3cf25b7 100644
--- a/project2/sql/sqlCheck.cpp
+++ b/project2/sql/sqlTest.cpp
@@ -1,5 +1,5 @@
#include <pch.hpp>
-#include "sqlCheck.h"
+#include "sqlTest.h"
#include "scriptLoader.h"
#include "selectcommand.h"
#include "column.h"
@@ -9,12 +9,13 @@
#include <boost/foreach.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
-DECLARE_LOADER("sqlcheck", SqlCheck);
+DECLARE_LOADER("sqltest", SqlTest);
class CantCompareNulls : public std::exception { };
-SqlCheck::SqlCheck(ScriptNodePtr p) :
- ParamChecker(p),
+SqlTest::SqlTest(ScriptNodePtr p) :
+ SourceObject(p),
+ Test(p),
dataSource(p, "datasource"),
filter(p, "filter", ""),
testOp(p, "testOp", "=="),
@@ -23,12 +24,12 @@ SqlCheck::SqlCheck(ScriptNodePtr p) :
{
}
-SqlCheck::~SqlCheck()
+SqlTest::~SqlTest()
{
}
void
-SqlCheck::loadComplete(const CommonObjects * co)
+SqlTest::loadComplete(const CommonObjects * co)
{
db = co->dataSource<RdbmsDataSource>(dataSource());
}
@@ -86,7 +87,7 @@ class HandleDoCompare : public DB::HandleField {
std::string testOp;
};
bool
-SqlCheck::performCheck() const
+SqlTest::passes() const
{
boost::shared_ptr<DB::SelectCommand> query = boost::shared_ptr<DB::SelectCommand>(
db->getWritable().newSelectCommand(sqlCommand.getSqlFor(filter())));
diff --git a/project2/sql/sqlCheck.h b/project2/sql/sqlTest.h
index 86492dc..f722424 100644
--- a/project2/sql/sqlCheck.h
+++ b/project2/sql/sqlTest.h
@@ -1,20 +1,20 @@
-#ifndef SQLCHECK_H
-#define SQLCHECK_H
+#ifndef SQLTEST_H
+#define SQLTEST_H
-#include "paramChecker.h"
+#include "test.h"
#include "sqlWriter.h"
namespace DB { class SelectCommand; }
class RdbmsDataSource;
-/// Project2 component to check the value of a variable against an RDBMS data source
-class SqlCheck : public ParamChecker {
+/// Project2 component to test the value of a variable against an RDBMS data source
+class SqlTest : public Test {
public:
- SqlCheck(ScriptNodePtr p);
- virtual ~SqlCheck();
+ SqlTest(ScriptNodePtr p);
+ virtual ~SqlTest();
virtual void loadComplete(const CommonObjects *);
- bool performCheck() const;
+ bool passes() const;
const Variable dataSource;
const Variable filter;