Browse Source

Merge 9f64d69a4d into 879c69874a

pull/1/merge
Max Treskin 11 years ago
parent
commit
023e20d066
5 changed files with 142 additions and 142 deletions
  1. +10
    -10
      src/gr_e.erl
  2. +66
    -66
      src/gr_lc.erl
  3. +9
    -9
      src/gr_lc_code.erl
  4. +53
    -53
      src/gr_lc_lib.erl
  5. +4
    -4
      src/gr_lc_ops.erl

src/gre.erl → src/gr_e.erl View File

@ -13,7 +13,7 @@
%% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
%% @doc Accessor function for goldrush event terms.
-module(gre).
-module(gr_e).
-export([
make/2,
@ -81,15 +81,15 @@ pairs({list, List}) ->
-ifdef(TEST).
-include_lib("eunit/include/eunit.hrl").
gre_test_() ->
[?_assert(gre:has(a, gre:make([{a,1}], [list]))),
?_assertNot(gre:has(b, gre:make([{a,1}], [list]))),
?_assertEqual(1, gre:fetch(a, gre:make([{a,1}], [list]))),
?_assertError(badarg, gre:fetch(a, gre:make([], [list]))),
?_assertEqual([], gre:keys(gre:make([], [list]))),
?_assertEqual([a], gre:keys(gre:make([{a,1}], [list]))),
?_assertEqual([a,b], gre:keys(gre:make([{a,1},{b,2}], [list]))),
?_assertEqual([{a,1},{b,2}], gre:pairs(gre:make([{b,2},{a,1}], [list])))
gr_e_test_() ->
[?_assert(gr_e:has(a, gr_e:make([{a,1}], [list]))),
?_assertNot(gr_e:has(b, gr_e:make([{a,1}], [list]))),
?_assertEqual(1, gr_e:fetch(a, gr_e:make([{a,1}], [list]))),
?_assertError(badarg, gr_e:fetch(a, gr_e:make([], [list]))),
?_assertEqual([], gr_e:keys(gr_e:make([], [list]))),
?_assertEqual([a], gr_e:keys(gr_e:make([{a,1}], [list]))),
?_assertEqual([a,b], gr_e:keys(gr_e:make([{a,1},{b,2}], [list]))),
?_assertEqual([{a,1},{b,2}], gr_e:pairs(gr_e:make([{b,2},{a,1}], [list])))
].
-endif.

src/glc.erl → src/gr_lc.erl View File

@ -24,27 +24,27 @@
%%
%% === Examples of built in filters ===
%% ```
%% %% Select all events where 'a' exists and is greater than 0.
%% glc:gt(a, 0).
%% %% Select all events where 'a' exists and is gr_eater than 0.
%% gr_lc:gt(a, 0).
%% %% Select all events where 'a' exists and is equal to 0.
%% glc:eq(a, 0).
%% gr_lc:eq(a, 0).
%% %% Select all events where 'a' exists and is less than 0.
%% glc:lt(a, 0).
%% gr_lc:lt(a, 0).
%% %% Select all events where 'a' exists and is anything.
%% glc:wc(a).
%% gr_lc:wc(a).
%%
%% %% Select no input events. Used as black hole query.
%% glc:null(false).
%% gr_lc:null(false).
%% %% Select all input events. Used as passthrough query.
%% glc:null(true).
%% gr_lc:null(true).
%% '''
%%
%% === Examples of combining filters ===
%% ```
%% %% Select all events where both 'a' and 'b' exists and are greater than 0.
%% glc:all([glc:gt(a, 0), glc:gt(b, 0)]).
%% %% Select all events where 'a' or 'b' exists and are greater than 0.
%% glc:any([glc:get(a, 0), glc:gt(b, 0)]).
%% %% Select all events where both 'a' and 'b' exists and are gr_eater than 0.
%% gr_lc:all([gr_lc:gt(a, 0), gr_lc:gt(b, 0)]).
%% %% Select all events where 'a' or 'b' exists and are gr_eater than 0.
%% gr_lc:any([gr_lc:get(a, 0), gr_lc:gt(b, 0)]).
%% '''
%%
%% === Handling output events ===
@ -55,11 +55,11 @@
%%
%% ```
%% %% Write all input events as info reports to the error logger.
%% glc:with(glc:null(true), fun(E) ->
%% error_logger:info_report(gre:pairs(E)) end).
%% gr_lc:with(gr_lc:null(true), fun(E) ->
%% error_logger:info_report(gr_e:pairs(E)) end).
%% '''
%%
-module(glc).
-module(gr_lc).
-export([
compile/2,
@ -91,21 +91,21 @@
qtree :: term()
}).
-spec lt(atom(), term()) -> glc_ops:op().
-spec lt(atom(), term()) -> gr_lc_ops:op().
lt(Key, Term) ->
glc_ops:lt(Key, Term).
gr_lc_ops:lt(Key, Term).
-spec eq(atom(), term()) -> glc_ops:op().
-spec eq(atom(), term()) -> gr_lc_ops:op().
eq(Key, Term) ->
glc_ops:eq(Key, Term).
gr_lc_ops:eq(Key, Term).
-spec gt(atom(), term()) -> glc_ops:op().
-spec gt(atom(), term()) -> gr_lc_ops:op().
gt(Key, Term) ->
glc_ops:gt(Key, Term).
gr_lc_ops:gt(Key, Term).
-spec wc(atom()) -> glc_ops:op().
-spec wc(atom()) -> gr_lc_ops:op().
wc(Key) ->
glc_ops:wc(Key).
gr_lc_ops:wc(Key).
%% @doc Filter the input using multiple filters.
%%
@ -113,9 +113,9 @@ wc(Key) ->
%% in the list must hold for the input event. The list is expected to
%% be a non-empty list. If the list of filters is an empty list a `badarg'
%% error will be thrown.
-spec all([glc_ops:op()]) -> glc_ops:op().
-spec all([gr_lc_ops:op()]) -> gr_lc_ops:op().
all(Filters) ->
glc_ops:all(Filters).
gr_lc_ops:all(Filters).
%% @doc Filter the input using one of multiple filters.
@ -124,15 +124,15 @@ all(Filters) ->
%% in the list must hold for the input event. The list is expected to be
%% a non-empty list. If the list of filters is an empty list a `badarg'
%% error will be thrown.
-spec any([glc_ops:op()]) -> glc_ops:op().
-spec any([gr_lc_ops:op()]) -> gr_lc_ops:op().
any(Filters) ->
glc_ops:any(Filters).
gr_lc_ops:any(Filters).
%% @doc Always return `true' or `false'.
-spec null(boolean()) -> glc_ops:op().
-spec null(boolean()) -> gr_lc_ops:op().
null(Result) ->
glc_ops:null(Result).
gr_lc_ops:null(Result).
%% @doc Apply a function to each output of a query.
@ -140,9 +140,9 @@ null(Result) ->
%% Updating the output action of a query finalizes it. Attempting
%% to use a finalized query to construct a new query will result
%% in a `badarg' error.
-spec with(glc_ops:op(), fun((gre:event()) -> term())) -> glc_ops:op().
-spec with(gr_lc_ops:op(), fun((gr_e:event()) -> term())) -> gr_lc_ops:op().
with(Query, Action) ->
glc_ops:with(Query, Action).
gr_lc_ops:with(Query, Action).
%% @doc Return a union of multiple queries.
@ -155,9 +155,9 @@ with(Query, Action) ->
%% All queries are expected to be valid and have an output action other
%% than the default which is `output'. If these expectations don't hold
%% a `badarg' error will be thrown.
-spec union([glc_ops:op()]) -> glc_ops:op().
-spec union([gr_lc_ops:op()]) -> gr_lc_ops:op().
union(Queries) ->
glc_ops:union(Queries).
gr_lc_ops:union(Queries).
%% @doc Compile a query to a module.
@ -168,15 +168,15 @@ union(Queries) ->
-spec compile(atom(), list()) -> {ok, atom()}.
compile(Module, Query) ->
{ok, ModuleData} = module_data(Query),
case glc_code:compile(Module, ModuleData) of
case gr_lc_code:compile(Module, ModuleData) of
{ok, Module} ->
{ok, Module}
end.
%% @doc Handle an event using a compiled query.
%%
%% The input event is expected to have been returned from {@link gre:make/2}.
-spec handle(atom(), gre:event()) -> ok.
%% The input event is expected to have been returned from {@link gr_e:make/2}.
-spec handle(atom(), gr_e:event()) -> ok.
handle(Module, Event) ->
Module:handle(Event).
@ -206,7 +206,7 @@ module_data(Query) ->
%% tables are referred to by name in the generated code. the table/1
%% function maps names to tids.
Tables = [{params,Params}, {counters,Counters}],
Query2 = glc_lib:reduce(Query),
Query2 = gr_lc_lib:reduce(Query),
{ok, #module{'query'=Query, tables=Tables, qtree=Query2}}.
@ -247,30 +247,30 @@ setup_query(Module, Query) ->
{compiled, Module}.
nullquery_compiles_test() ->
{compiled, Mod} = setup_query(testmod1, glc:null(false)),
{compiled, Mod} = setup_query(testmod1, gr_lc:null(false)),
?assertError(badarg, Mod:table(noexists)).
params_table_exists_test() ->
{compiled, Mod} = setup_query(testmod2, glc:null(false)),
{compiled, Mod} = setup_query(testmod2, gr_lc:null(false)),
?assert(is_integer(Mod:table(params))),
?assertMatch([_|_], ets:info(Mod:table(params))).
nullquery_exists_test() ->
{compiled, Mod} = setup_query(testmod3, glc:null(false)),
{compiled, Mod} = setup_query(testmod3, gr_lc:null(false)),
?assert(erlang:function_exported(Mod, info, 1)),
?assertError(badarg, Mod:info(invalid)),
?assertEqual({null, false}, Mod:info('query')).
init_counters_test() ->
{compiled, Mod} = setup_query(testmod4, glc:null(false)),
{compiled, Mod} = setup_query(testmod4, gr_lc:null(false)),
?assertEqual(0, Mod:info(input)),
?assertEqual(0, Mod:info(filter)),
?assertEqual(0, Mod:info(output)).
filtered_event_test() ->
%% If no selection condition is specified no inputs can match.
{compiled, Mod} = setup_query(testmod5, glc:null(false)),
glc:handle(Mod, gre:make([], [list])),
{compiled, Mod} = setup_query(testmod5, gr_lc:null(false)),
gr_lc:handle(Mod, gr_e:make([], [list])),
?assertEqual(1, Mod:info(input)),
?assertEqual(1, Mod:info(filter)),
?assertEqual(0, Mod:info(output)).
@ -279,8 +279,8 @@ nomatch_event_test() ->
%% If a selection condition but no body is specified the event
%% is expected to count as filtered out if the condition does
%% not hold.
{compiled, Mod} = setup_query(testmod6, glc:eq('$n', 'noexists@nohost')),
glc:handle(Mod, gre:make([{'$n', 'noexists2@nohost'}], [list])),
{compiled, Mod} = setup_query(testmod6, gr_lc:eq('$n', 'noexists@nohost')),
gr_lc:handle(Mod, gr_e:make([{'$n', 'noexists2@nohost'}], [list])),
?assertEqual(1, Mod:info(input)),
?assertEqual(1, Mod:info(filter)),
?assertEqual(0, Mod:info(output)).
@ -288,8 +288,8 @@ nomatch_event_test() ->
opfilter_eq_test() ->
%% If a selection condition but no body is specified the event
%% counts as input to the query, but not as filtered out.
{compiled, Mod} = setup_query(testmod7, glc:eq('$n', 'noexists@nohost')),
glc:handle(Mod, gre:make([{'$n', 'noexists@nohost'}], [list])),
{compiled, Mod} = setup_query(testmod7, gr_lc:eq('$n', 'noexists@nohost')),
gr_lc:handle(Mod, gr_e:make([{'$n', 'noexists@nohost'}], [list])),
?assertEqual(1, Mod:info(input)),
?assertEqual(0, Mod:info(filter)),
?assertEqual(1, Mod:info(output)),
@ -297,23 +297,23 @@ opfilter_eq_test() ->
opfilter_gt_test() ->
{compiled, Mod} = setup_query(testmod8, glc:gt(a, 1)),
glc:handle(Mod, gre:make([{'a', 2}], [list])),
{compiled, Mod} = setup_query(testmod8, gr_lc:gt(a, 1)),
gr_lc:handle(Mod, gr_e:make([{'a', 2}], [list])),
?assertEqual(1, Mod:info(input)),
?assertEqual(0, Mod:info(filter)),
glc:handle(Mod, gre:make([{'a', 0}], [list])),
gr_lc:handle(Mod, gr_e:make([{'a', 0}], [list])),
?assertEqual(2, Mod:info(input)),
?assertEqual(1, Mod:info(filter)),
?assertEqual(1, Mod:info(output)),
done.
opfilter_lt_test() ->
{compiled, Mod} = setup_query(testmod9, glc:lt(a, 1)),
glc:handle(Mod, gre:make([{'a', 0}], [list])),
{compiled, Mod} = setup_query(testmod9, gr_lc:lt(a, 1)),
gr_lc:handle(Mod, gr_e:make([{'a', 0}], [list])),
?assertEqual(1, Mod:info(input)),
?assertEqual(0, Mod:info(filter)),
?assertEqual(1, Mod:info(output)),
glc:handle(Mod, gre:make([{'a', 2}], [list])),
gr_lc:handle(Mod, gr_e:make([{'a', 2}], [list])),
?assertEqual(2, Mod:info(input)),
?assertEqual(1, Mod:info(filter)),
?assertEqual(1, Mod:info(output)),
@ -321,16 +321,16 @@ opfilter_lt_test() ->
allholds_op_test() ->
{compiled, Mod} = setup_query(testmod10,
glc:all([glc:eq(a, 1), glc:eq(b, 2)])),
glc:handle(Mod, gre:make([{'a', 1}], [list])),
glc:handle(Mod, gre:make([{'a', 2}], [list])),
gr_lc:all([gr_lc:eq(a, 1), gr_lc:eq(b, 2)])),
gr_lc:handle(Mod, gr_e:make([{'a', 1}], [list])),
gr_lc:handle(Mod, gr_e:make([{'a', 2}], [list])),
?assertEqual(2, Mod:info(input)),
?assertEqual(2, Mod:info(filter)),
glc:handle(Mod, gre:make([{'b', 1}], [list])),
glc:handle(Mod, gre:make([{'b', 2}], [list])),
gr_lc:handle(Mod, gr_e:make([{'b', 1}], [list])),
gr_lc:handle(Mod, gr_e:make([{'b', 2}], [list])),
?assertEqual(4, Mod:info(input)),
?assertEqual(4, Mod:info(filter)),
glc:handle(Mod, gre:make([{'a', 1},{'b', 2}], [list])),
gr_lc:handle(Mod, gr_e:make([{'a', 1},{'b', 2}], [list])),
?assertEqual(5, Mod:info(input)),
?assertEqual(4, Mod:info(filter)),
?assertEqual(1, Mod:info(output)),
@ -338,13 +338,13 @@ allholds_op_test() ->
anyholds_op_test() ->
{compiled, Mod} = setup_query(testmod11,
glc:any([glc:eq(a, 1), glc:eq(b, 2)])),
glc:handle(Mod, gre:make([{'a', 2}], [list])),
glc:handle(Mod, gre:make([{'b', 1}], [list])),
gr_lc:any([gr_lc:eq(a, 1), gr_lc:eq(b, 2)])),
gr_lc:handle(Mod, gr_e:make([{'a', 2}], [list])),
gr_lc:handle(Mod, gr_e:make([{'b', 1}], [list])),
?assertEqual(2, Mod:info(input)),
?assertEqual(2, Mod:info(filter)),
glc:handle(Mod, gre:make([{'a', 1}], [list])),
glc:handle(Mod, gre:make([{'b', 2}], [list])),
gr_lc:handle(Mod, gr_e:make([{'a', 1}], [list])),
gr_lc:handle(Mod, gr_e:make([{'b', 2}], [list])),
?assertEqual(4, Mod:info(input)),
?assertEqual(2, Mod:info(filter)),
done.
@ -352,14 +352,14 @@ anyholds_op_test() ->
with_function_test() ->
Self = self(),
{compiled, Mod} = setup_query(testmod12,
glc:with(glc:eq(a, 1), fun(Event) -> Self ! gre:fetch(a, Event) end)),
glc:handle(Mod, gre:make([{a,1}], [list])),
gr_lc:with(gr_lc:eq(a, 1), fun(Event) -> Self ! gr_e:fetch(a, Event) end)),
gr_lc:handle(Mod, gr_e:make([{a,1}], [list])),
?assertEqual(1, Mod:info(output)),
?assertEqual(1, receive Msg -> Msg after 0 -> notcalled end),
done.
union_error_test() ->
?assertError(badarg, glc:union([glc:eq(a, 1)])),
?assertError(badarg, gr_lc:union([gr_lc:eq(a, 1)])),
done.
-endif.

src/glc_code.erl → src/gr_lc_code.erl View File

@ -1,5 +1,5 @@
%% @doc Code generation functions.
-module(glc_code).
-module(gr_lc_code).
-export([
compile/2
@ -128,7 +128,7 @@ abstract_query(Query) ->
%% @private Return a list of expressions to apply a filter.
%% @todo Allow mulitple functions to be specified using `with/2'.
-spec abstract_filter(glc_ops:op(), #state{}) -> [syntaxTree()].
-spec abstract_filter(gr_lc_ops:op(), #state{}) -> [syntaxTree()].
abstract_filter({with, Cond, Fun}, State) ->
abstract_filter_(Cond,
_OnMatch=fun(State2) ->
@ -144,7 +144,7 @@ abstract_filter(Cond, State) ->
%% to apply when the filter matches or fails to match. The state passed to the
%% functions will be contain all variable bindings to previously accessed
%% fields and parameters.
-spec abstract_filter_(glc_ops:op(), nextFun(), nextFun(), #state{}) ->
-spec abstract_filter_(gr_lc_ops:op(), nextFun(), nextFun(), #state{}) ->
syntaxTree().
abstract_filter_({null, true}, OnMatch, _OnNomatch, State) ->
OnMatch(State);
@ -185,7 +185,7 @@ abstract_opfilter(Key, Opname, Value, OnMatch, OnNomatch, State) ->
%% any of the conditions does not hold the evaluation is short circuted at that
%% point. This means that the `OnNomatch' branch is executed once for each
%% condition. The `OnMatch' branch is only executed once.
-spec abstract_all([glc_ops:op()], nextFun(), nextFun(), #state{}) ->
-spec abstract_all([gr_lc_ops:op()], nextFun(), nextFun(), #state{}) ->
[syntaxTree()].
abstract_all([H|T], OnMatch, OnNomatch, State) ->
abstract_filter_(H,
@ -195,7 +195,7 @@ abstract_all([], OnMatch, _OnNomatch, State) ->
OnMatch(State).
%% @private
-spec abstract_any([glc_ops:op()], nextFun(), nextFun(), #state{}) ->
-spec abstract_any([gr_lc_ops:op()], nextFun(), nextFun(), #state{}) ->
[syntaxTree()].
abstract_any([H|T], OnMatch, OnNomatch, State) ->
abstract_filter_(H, OnMatch,
@ -205,7 +205,7 @@ abstract_any([], _OnMatch, OnNomatch, State) ->
OnNomatch(State).
%% @private
-spec abstract_with(fun((gre:event()) -> term()), #state{}) -> [syntaxTree()].
-spec abstract_with(fun((gr_e:event()) -> term()), #state{}) -> [syntaxTree()].
abstract_with(Fun, State) when is_function(Fun, 1) ->
abstract_getparam(Fun, fun(#state{event=Event, paramvars=Params}) ->
{_, Fun2} = lists:keyfind(Fun, 1, Params),
@ -231,7 +231,7 @@ abstract_getkey(Key, OnMatch, OnNomatch, #state{fields=Fields}=State) ->
abstract_getkey_(Key, OnMatch, OnNomatch, #state{
event=Event, fields=Fields}=State) ->
[?erl:case_expr(
abstract_apply(gre, find, [?erl:atom(Key), Event]),
abstract_apply(gr_e, find, [?erl:atom(Key), Event]),
[?erl:clause([
?erl:tuple([
?erl:atom(true),
@ -302,11 +302,11 @@ param_variable(Key) ->
%% @private Generate a list of field variable names.
%% Walk the query tree and generate a safe variable name string for each field
%% that is accessed by the conditions in the query. Only allow alpha-numeric.
%%-spec field_variables(glc_ops:op()) -> [{atom(), string()}].
%%-spec field_variables(gr_lc_ops:op()) -> [{atom(), string()}].
%%field_variables(Query) ->
%% lists:usort(field_variables_(Query)).
%%-spec field_variables(glc_ops:op()) -> [{atom(), string()}].
%%-spec field_variables(gr_lc_ops:op()) -> [{atom(), string()}].
%%field_variables_({Key, '=', _Term}) ->
%% [{Key, field_variable(Key)}].

src/glc_lib.erl → src/gr_lc_lib.erl View File

@ -13,7 +13,7 @@
%% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
%% @doc Query processing functions.
-module(glc_lib).
-module(gr_lc_lib).
-export([
reduce/1,
@ -56,22 +56,22 @@ matches({all, Conds}, Event) ->
matches({null, Const}, _Event) ->
Const;
matches({Key, '<', Term}, Event) ->
case gre:find(Key, Event) of
case gr_e:find(Key, Event) of
{true, Term2} -> Term2 < Term;
false -> false
end;
matches({Key, '=', Term}, Event) ->
case gre:find(Key, Event) of
case gr_e:find(Key, Event) of
{true, Term2} -> Term2 =:= Term;
false -> false
end;
matches({Key, '>', Term}, Event) ->
case gre:find(Key, Event) of
case gr_e:find(Key, Event) of
{true, Term2} -> Term2 > Term;
false -> false
end;
matches({Key, '*'}, Event) ->
case gre:find(Key, Event) of
case gr_e:find(Key, Event) of
{true, _} -> true;
false -> false
end.
@ -265,111 +265,111 @@ valid(Term) ->
-include_lib("eunit/include/eunit.hrl").
all_one_test() ->
?assertEqual(glc:eq(a, 1),
glc_lib:reduce(glc:all([glc:eq(a, 1)]))
?assertEqual(gr_lc:eq(a, 1),
gr_lc_lib:reduce(gr_lc:all([gr_lc:eq(a, 1)]))
).
all_sort_test() ->
?assertEqual(glc:all([glc:eq(a, 1), glc:eq(b, 2)]),
glc_lib:reduce(glc:all([glc:eq(b, 2), glc:eq(a, 1)]))
?assertEqual(gr_lc:all([gr_lc:eq(a, 1), gr_lc:eq(b, 2)]),
gr_lc_lib:reduce(gr_lc:all([gr_lc:eq(b, 2), gr_lc:eq(a, 1)]))
).
any_one_test() ->
?assertEqual(glc:eq(a, 1),
glc_lib:reduce(glc:any([glc:eq(a, 1)]))
?assertEqual(gr_lc:eq(a, 1),
gr_lc_lib:reduce(gr_lc:any([gr_lc:eq(a, 1)]))
).
any_sort_test() ->
?assertEqual(glc:any([glc:eq(a, 1), glc:eq(b, 2)]),
glc_lib:reduce(glc:any([glc:eq(b, 2), glc:eq(a, 1)]))
?assertEqual(gr_lc:any([gr_lc:eq(a, 1), gr_lc:eq(b, 2)]),
gr_lc_lib:reduce(gr_lc:any([gr_lc:eq(b, 2), gr_lc:eq(a, 1)]))
).
all_nest_test() ->
?assertEqual(glc:all([glc:eq(a, 1), glc:eq(b, 2)]),
glc_lib:reduce(glc:all([glc:eq(a, 1), glc:all([glc:eq(b, 2)])]))
?assertEqual(gr_lc:all([gr_lc:eq(a, 1), gr_lc:eq(b, 2)]),
gr_lc_lib:reduce(gr_lc:all([gr_lc:eq(a, 1), gr_lc:all([gr_lc:eq(b, 2)])]))
),
?assertEqual(glc:all([glc:eq(a, 1), glc:eq(b, 2), glc:eq(c, 3)]),
glc_lib:reduce(glc:all([glc:eq(c, 3),
glc:all([glc:eq(a, 1),
glc:all([glc:eq(b, 2)])])]))
?assertEqual(gr_lc:all([gr_lc:eq(a, 1), gr_lc:eq(b, 2), gr_lc:eq(c, 3)]),
gr_lc_lib:reduce(gr_lc:all([gr_lc:eq(c, 3),
gr_lc:all([gr_lc:eq(a, 1),
gr_lc:all([gr_lc:eq(b, 2)])])]))
).
any_nest_test() ->
?assertEqual(glc:any([glc:eq(a, 1), glc:eq(b, 2)]),
glc_lib:reduce(glc:any([glc:eq(a, 1), glc:any([glc:eq(b, 2)])]))
?assertEqual(gr_lc:any([gr_lc:eq(a, 1), gr_lc:eq(b, 2)]),
gr_lc_lib:reduce(gr_lc:any([gr_lc:eq(a, 1), gr_lc:any([gr_lc:eq(b, 2)])]))
),
?assertEqual(glc:any([glc:eq(a, 1), glc:eq(b, 2), glc:eq(c, 3)]),
glc_lib:reduce(glc:any([glc:eq(c, 3),
glc:any([glc:eq(a, 1),
glc:any([glc:eq(b, 2)])])]))
?assertEqual(gr_lc:any([gr_lc:eq(a, 1), gr_lc:eq(b, 2), gr_lc:eq(c, 3)]),
gr_lc_lib:reduce(gr_lc:any([gr_lc:eq(c, 3),
gr_lc:any([gr_lc:eq(a, 1),
gr_lc:any([gr_lc:eq(b, 2)])])]))
).
all_equiv_test() ->
?assertEqual(glc:eq(a, 1),
glc_lib:reduce(glc:all([glc:eq(a, 1), glc:eq(a, 1)]))
?assertEqual(gr_lc:eq(a, 1),
gr_lc_lib:reduce(gr_lc:all([gr_lc:eq(a, 1), gr_lc:eq(a, 1)]))
).
any_equiv_test() ->
?assertEqual(glc:eq(a, 1),
glc_lib:reduce(glc:any([glc:eq(a, 1), glc:eq(a, 1)]))
?assertEqual(gr_lc:eq(a, 1),
gr_lc_lib:reduce(gr_lc:any([gr_lc:eq(a, 1), gr_lc:eq(a, 1)]))
).
any_required_test() ->
?assertEqual(
glc:all([
glc:any([glc:eq(b, 2), glc:eq(c, 3)]),
glc:eq(a, 1)
gr_lc:all([
gr_lc:any([gr_lc:eq(b, 2), gr_lc:eq(c, 3)]),
gr_lc:eq(a, 1)
]),
glc_lib:reduce(
glc:any([
glc:all([glc:eq(a, 1), glc:eq(b, 2)]),
glc:all([glc:eq(a, 1), glc:eq(c, 3)])]))
gr_lc_lib:reduce(
gr_lc:any([
gr_lc:all([gr_lc:eq(a, 1), gr_lc:eq(b, 2)]),
gr_lc:all([gr_lc:eq(a, 1), gr_lc:eq(c, 3)])]))
).
all_common_test() ->
?assertEqual(
glc:all([glc:eq(a, 1), glc:eq(b, 2), glc:eq(c, 3)]),
glc_lib:reduce(
glc:all([
glc:any([glc:eq(a, 1), glc:eq(b, 2)]),
glc:any([glc:eq(a, 1), glc:eq(c, 3)])]))
gr_lc:all([gr_lc:eq(a, 1), gr_lc:eq(b, 2), gr_lc:eq(c, 3)]),
gr_lc_lib:reduce(
gr_lc:all([
gr_lc:any([gr_lc:eq(a, 1), gr_lc:eq(b, 2)]),
gr_lc:any([gr_lc:eq(a, 1), gr_lc:eq(c, 3)])]))
).
delete_from_all_test() ->
?assertEqual(
glc:all([glc:eq(b,2)]),
gr_lc:all([gr_lc:eq(b,2)]),
deleteall(
glc:all([glc:eq(a, 1),glc:eq(b,2)]), [glc:eq(a, 1)])
gr_lc:all([gr_lc:eq(a, 1),gr_lc:eq(b,2)]), [gr_lc:eq(a, 1)])
).
delete_from_any_test() ->
?assertEqual(
glc:any([glc:eq(b,2)]),
gr_lc:any([gr_lc:eq(b,2)]),
deleteall(
glc:any([glc:eq(a, 1),glc:eq(b,2)]), [glc:eq(a, 1)])
gr_lc:any([gr_lc:eq(a, 1),gr_lc:eq(b,2)]), [gr_lc:eq(a, 1)])
).
default_is_output_test_() ->
[?_assertEqual(output, glc_lib:onoutput(glc:lt(a, 1))),
?_assertEqual(output, glc_lib:onoutput(glc:eq(a, 1))),
?_assertEqual(output, glc_lib:onoutput(glc:gt(a, 1))),
?_assertEqual(output, glc_lib:onoutput(glc:wc(a)))
[?_assertEqual(output, gr_lc_lib:onoutput(gr_lc:lt(a, 1))),
?_assertEqual(output, gr_lc_lib:onoutput(gr_lc:eq(a, 1))),
?_assertEqual(output, gr_lc_lib:onoutput(gr_lc:gt(a, 1))),
?_assertEqual(output, gr_lc_lib:onoutput(gr_lc:wc(a)))
].
-ifdef(PROPER).
prop_reduce_returns() ->
?FORALL(Query, glc_ops:op(),
returns(fun() -> glc_lib:reduce(Query) end)).
?FORALL(Query, gr_lc_ops:op(),
returns(fun() -> gr_lc_lib:reduce(Query) end)).
reduce_returns_test() ->
?assert(proper:quickcheck(prop_reduce_returns())).
prop_matches_returns_boolean() ->
?FORALL({Query, Event}, {glc_ops:op(), [{atom(), term()}]},
is_boolean(glc_lib:matches(Query, gre:make(Event, [list])))).
?FORALL({Query, Event}, {gr_lc_ops:op(), [{atom(), term()}]},
is_boolean(gr_lc_lib:matches(Query, gr_e:make(Event, [list])))).
matches_returns_boolean_test() ->
?assert(proper:quickcheck(prop_matches_returns_boolean())).

src/glc_ops.erl → src/gr_lc_ops.erl View File

@ -1,5 +1,5 @@
%% @doc Built in operators.
-module(glc_ops).
-module(gr_lc_ops).
-export([
lt/2,
@ -44,7 +44,7 @@ eq(Key, Term) when is_atom(Key) ->
eq(Key, Term) ->
erlang:error(badarg, [Key, Term]).
%% @doc Test that a field value is greater than a term.
%% @doc Test that a field value is gr_eater than a term.
-spec gt(atom(), term()) -> op().
gt(Key, Term) when is_atom(Key) ->
{Key, '>', Term};
@ -95,7 +95,7 @@ null(Result) ->
%% Updating the output action of a query finalizes it. Attempting
%% to use a finalized query to construct a new query will result
%% in a `badarg' error.
-spec with(op(), fun((gre:event()) -> term())) -> op().
-spec with(op(), fun((gr_e:event()) -> term())) -> op().
with(Query, Fun) when is_function(Fun, 1) ->
{with, Query, Fun};
with(Query, Fun) ->
@ -113,7 +113,7 @@ with(Query, Fun) ->
%% a `badarg' error will be thrown.
-spec union([op()]) -> op().
union(Queries) ->
case [Query || Query <- Queries, glc_lib:onoutput(Query) =:= output] of
case [Query || Query <- Queries, gr_lc_lib:onoutput(Query) =:= output] of
[] -> {union, Queries};
[_|_] -> erlang:error(badarg, [Queries])
end.

Loading…
Cancel
Save