Filter and FilterGroup
These are the core abstractions involved in running the action filter.
Filter is the class that represents each modular filter, with requirements and functionality.
FilterGroup's purpose is to make it easy for
Filters to rely on persistent data when going through each action, rather than creating them anew each time they must be run.
Filter
abstract class Filter
{
private List<Func<IUITestActionStack, bool>> requirements =
new List<Func<IUITestActionStack, bool>>();
public Filter()
{
Require(stack => stack.Count > 0);
Require(stack => stack.Peek().UIElement != null);
}
protected void Require(Func<IUITestActionStack, bool> requirement)
{
requirements.Add(requirement);
}
The first part of the
Filter are some convenience definitions allowing for individual requirements. These make it easier and more clear to define what triggers the use of a specific
Filter. A couple of requirements are in place for all filters, though if necessary these can be avoided by using the
UnconditionalRun function.
protected virtual void UnconditionalRun(IUITestActionStack stack) { }
protected abstract void Run(IUITestActionStack stack);
public static void Run(IUITestActionStack stack, params Filter[] filters)
{
foreach(var filter in filters)
{
filter.UnconditionalRun(stack);
bool requirementsSatisfied = true;
foreach(var requirement in filter.requirements)
{
requirementsSatisfied = requirementsSatisfied && requirement(stack);
}
if(requirementsSatisfied)
{
filter.Run(stack);
}
}
}
}
These are the functions involved in actually running the filters.
UnconditionalRun is run first. The requirements are then gone through in the order added. If any fail, then
Filter's
Run is not run, and the next
Filter is executed the same way, until all
Filters have been processed.
The static
Run function is used to manage this processing.
FilterGroup
The
FilterGroup is simply to convenience persisting
Filters. It holds a list of
Filters, and defers the
Run function to the static function of the same name in
Filter.