Current section
Files
Jump to
Current section
Files
examples/exploriak/deps/meck/src/meck_expect.erl
%%%============================================================================%%% Licensed under the Apache License, Version 2.0 (the "License");%%% you may not use this file except in compliance with the License.%%% You may obtain a copy of the License at%%%%%% http://www.apache.org/licenses/LICENSE-2.0%%%%%% Unless required by applicable law or agreed to in writing, software%%% distributed under the License is distributed on an "AS IS" BASIS,%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.%%% See the License for the specific language governing permissions and%%% limitations under the License.%%%============================================================================%%% @private%%% @doc Provides expectation processing functions.-module(meck_expect).%% API-export_type([func_ari/0]).-export_type([expect/0]).-export([new/2]).-export([new/3]).-export([new_passthrough/1]).-export([new_dummy/2]).-export([func_ari/1]).-export([fetch_result/2]).%%%============================================================================%%% Types%%%============================================================================-type func_clause_spec() :: {meck_args_matcher:args_spec(), meck_ret_spec:ret_spec()}.-type func_clause() :: {meck_args_matcher:args_matcher(), meck_ret_spec:ret_spec()}.-type func_ari() :: {Func::atom(), Ari::byte()}.-opaque expect() :: {func_ari(), [func_clause()]}.%%%============================================================================%%% API%%%============================================================================-spec new(Func::atom(), fun() | func_clause_spec()) -> expect().new(Func, StubFun) when is_function(StubFun) -> {arity, Arity} = erlang:fun_info(StubFun, arity), Clause = {meck_args_matcher:new(Arity), meck_ret_spec:exec(StubFun)}, {{Func, Arity}, [Clause]};new(Func, ClauseSpecs) when is_list(ClauseSpecs) -> {Arity, Clauses} = parse_clause_specs(ClauseSpecs), {{Func, Arity}, Clauses}.-spec new(Func::atom(), meck_args_matcher:args_spec(), meck_ret_spec:ret_spec()) -> expect().new(Func, ArgsSpec, RetSpec) -> {Ari, Clause} = parse_clause_spec({ArgsSpec, RetSpec}), {{Func, Ari}, [Clause]}.-spec new_passthrough(func_ari()) -> expect().new_passthrough({Func, Ari}) -> {{Func, Ari}, [{meck_args_matcher:new(Ari), meck_ret_spec:passthrough()}]}.-spec new_dummy(func_ari(), meck_ret_spec:ret_spec()) -> expect().new_dummy({Func, Ari}, RetSpec) -> {{Func, Ari}, [{meck_args_matcher:new(Ari), RetSpec}]}.-spec func_ari(expect()) -> func_ari().func_ari({FuncAri, _Clauses}) -> FuncAri.-spec fetch_result(Args::[any()], expect()) -> {undefined, unchanged} | {meck_ret_spec:result_spec(), unchanged} | {meck_ret_spec:result_spec(), NewExpect::expect()}.fetch_result(Args, {FuncAri, Clauses}) -> case find_matching_clause(Args, Clauses) of not_found -> {undefined, unchanged}; {ArgsMatcher, RetSpec} -> case meck_ret_spec:retrieve_result(RetSpec) of {ResultSpec, unchanged} -> {ResultSpec, unchanged}; {ResultSpec, NewRetSpec} -> NewClauses = lists:keyreplace(ArgsMatcher, 1, Clauses, {ArgsMatcher, NewRetSpec}), {ResultSpec, {FuncAri, NewClauses}} end end.%%%============================================================================%%% Internal functions%%%============================================================================-spec parse_clause_specs([func_clause_spec()]) -> {Ari::byte(), [func_clause()]}.parse_clause_specs([ClauseSpec | Rest]) -> {Ari, Clause} = parse_clause_spec(ClauseSpec), parse_clause_specs(Rest, Ari, [Clause]).-spec parse_clause_specs([func_clause_spec()], FirstClauseAri::byte(), Clauses::[func_clause()]) -> {Ari::byte(), [func_clause()]}.parse_clause_specs([ClauseSpec | Rest], FirstClauseAri, Clauses) -> {Ari, Clause} = parse_clause_spec(ClauseSpec), case Ari of FirstClauseAri -> parse_clause_specs(Rest, FirstClauseAri, [Clause | Clauses]); _ -> erlang:error({invalid_arity, {{expected, FirstClauseAri}, {actual, Ari}, {clause, ClauseSpec}}}) end;parse_clause_specs([], FirstClauseAri, Clauses) -> {FirstClauseAri, lists:reverse(Clauses)}.-spec parse_clause_spec(func_clause_spec()) -> {Ari::byte(), func_clause()}.parse_clause_spec({ArgsSpec, RetSpec}) -> ArgsMatcher = meck_args_matcher:new(ArgsSpec), Ari = meck_args_matcher:arity(ArgsMatcher), Clause = {ArgsMatcher, RetSpec}, {Ari, Clause}.-spec find_matching_clause(Args::[any()], Defined::[func_clause()]) -> Matching::func_clause() | not_found.find_matching_clause(Args, [{ArgsMatcher, RetSpec} | Rest]) -> case meck_args_matcher:match(Args, ArgsMatcher) of true -> {ArgsMatcher, RetSpec}; _Else -> find_matching_clause(Args, Rest) end;find_matching_clause(_Args, []) -> not_found.