summaryrefslogtreecommitdiff
path: root/test/stub.erl
diff options
context:
space:
mode:
Diffstat (limited to 'test/stub.erl')
-rw-r--r--test/stub.erl168
1 files changed, 0 insertions, 168 deletions
diff --git a/test/stub.erl b/test/stub.erl
deleted file mode 100644
index 2a6173b5..00000000
--- a/test/stub.erl
+++ /dev/null
@@ -1,168 +0,0 @@
-%%%-------------------------------------------------------------------
-%%% File: stub.erl
-%%% @author Cliff Moon <> []
-%%% @copyright 2009 Cliff Moon
-%%% @doc
-%%%
-%%% @end
-%%%
-%%% @since 2009-05-10 by Cliff Moon
-%%%-------------------------------------------------------------------
--module(stub).
--author('cliff@powerset.com').
-
--behaviour(gen_server).
-
-%% API
--export([stub/3, stub/4, proxy_call/3]).
-
-%% gen_server callbacks
--export([init/1, handle_call/3, handle_cast/2, handle_info/2,
- terminate/2, code_change/3]).
-
--include_lib("eunit/include/eunit.hrl").
--include("../include/common.hrl").
-
--record(state, {old_code, module, stub, times}).
-
-%%====================================================================
-%% API
-%%====================================================================
-
-stub(Module, Function, Fun) ->
- stub(Module, Function, Fun, 1).
-
-stub(Module, Function, Fun, Times) when is_function(Fun) ->
- gen_server:start({local, name(Module, Function)}, ?MODULE, [Module, Function, Fun, Times], []).
-
-proxy_call(_, Name, Args) ->
- {Times, Reply} = gen_server:call(Name, {proxy_call, Args}),
- if
- Times =< 0 -> gen_server:cast(Name, stop);
- true -> ok
- end,
- Reply.
-
-%%====================================================================
-%% gen_server callbacks
-%%====================================================================
-
-%%--------------------------------------------------------------------
-%% @spec init(Args) -> {ok, State} |
-%% {ok, State, Timeout} |
-%% ignore |
-%% {stop, Reason}
-%% @doc Initiates the server
-%% @end
-%%--------------------------------------------------------------------
-init([Module, Function, Fun, Times]) ->
- case code:get_object_code(Module) of
- {Module, Bin, Filename} ->
- ?debugMsg("stubbing"),
- stub_function(Module, Function, arity(Fun)),
- {ok, #state{module=Module,old_code={Module,Bin,Filename},times=Times,stub=Fun}};
- error -> {stop, ?fmt("Could not get object code for module ~p", [Module])}
- end.
-
-%%--------------------------------------------------------------------
-%% @spec
-%% handle_call(Request, From, State) -> {reply, Reply, State} |
-%% {reply, Reply, State, Timeout} |
-%% {noreply, State} |
-%% {noreply, State, Timeout} |
-%% {stop, Reason, Reply, State} |
-%% {stop, Reason, State}
-%% @doc Handling call messages
-%% @end
-%%--------------------------------------------------------------------
-handle_call({proxy_call, Args}, _From, State = #state{stub=Fun, times=Times}) ->
- Reply = apply(Fun, tuple_to_list(Args)),
- {reply, {Times-1, Reply}, State#state{times=Times-1}}.
-
-%%--------------------------------------------------------------------
-%% @spec handle_cast(Msg, State) -> {noreply, State} |
-%% {noreply, State, Timeout} |
-%% {stop, Reason, State}
-%% @doc Handling cast messages
-%% @end
-%%--------------------------------------------------------------------
-handle_cast(stop, State) ->
- sleep:timer(10),
- {stop, normal, State}.
-
-%%--------------------------------------------------------------------
-%% @spec handle_info(Info, State) -> {noreply, State} |
-%% {noreply, State, Timeout} |
-%% {stop, Reason, State}
-%% @doc Handling all non call/cast messages
-%% @end
-%%--------------------------------------------------------------------
-handle_info(_Info, State) ->
- {noreply, State}.
-
-%%--------------------------------------------------------------------
-%% @spec terminate(Reason, State) -> void()
-%% @doc This function is called by a gen_server when it is about to
-%% terminate. It should be the opposite of Module:init/1 and do any necessary
-%% cleaning up. When it returns, the gen_server terminates with Reason.
-%% The return value is ignored.
-%% @end
-%%--------------------------------------------------------------------
-terminate(_Reason, #state{old_code={_Module,_Bin,_Filename}}) ->
- ok.
-
-%%--------------------------------------------------------------------
-%% @spec code_change(OldVsn, State, Extra) -> {ok, NewState}
-%% @doc Convert process state when code is changed
-%% @end
-%%--------------------------------------------------------------------
-code_change(_OldVsn, State, _Extra) ->
- {ok, State}.
-
-%%--------------------------------------------------------------------
-%%% Internal functions
-%%--------------------------------------------------------------------
-name(Module, Function) ->
- list_to_atom(lists:concat([Module, Function, "stub"])).
-
-stub_function(Module, Function, Arity) ->
- {_, Bin, _} = code:get_object_code(Module),
- {ok, {Module,[{abstract_code,{raw_abstract_v1,Forms}}]}} = beam_lib:chunks(Bin, [abstract_code]),
- ?debugMsg("replacing function"),
- StubbedForms = replace_function(Module, Function, Arity, Forms),
- case compile:forms(StubbedForms, [binary]) of
- {ok, Module, Binary} -> code:load_binary(Module, atom_to_list(Module) ++ ".erl", Binary);
- Other -> Other
- end.
-
-arity(Fun) when is_function(Fun) ->
- Props = erlang:fun_info(Fun),
- proplists:get_value(arity, Props).
-
-replace_function(Module, Function, Arity, Forms) ->
- replace_function(Module, Function, Arity, Forms, []).
-
-replace_function(_Module, _Function, _Arity, [], Acc) ->
- lists:reverse(Acc);
-replace_function(Module, Function, Arity, [{function, Line, Function, Arity, _Clauses}|Forms], Acc) ->
- lists:reverse(Acc) ++ [{function, Line, Function, Arity, [
- {clause,
- Line,
- generate_variables(Arity),
- [],
- generate_expression(stub,proxy_call,Module,name(Module,Function),Arity)}]}] ++ Forms;
-replace_function(Module, Function, Arity, [Form|Forms], Acc) ->
- replace_function(Module, Function, Arity, Forms, [Form|Acc]).
-
-generate_variables(0) -> [];
-generate_variables(Arity) ->
- lists:map(fun(N) ->
- {var, 1, list_to_atom(lists:concat(['Arg', N]))}
- end, lists:seq(1, Arity)).
-
-generate_expression(M, F, Module, Name, 0) ->
- [{call,1,{remote,1,{atom,1,M},{atom,1,F}}, [{atom,1,Module}, {atom,1,Name}]}];
-generate_expression(M, F, Module, Name, Arity) ->
- [{call,1,{remote,1,{atom,1,M},{atom,1,F}}, [{atom,1,Module}, {atom,1,Name}, {tuple,1,lists:map(fun(N) ->
- {var, 1, list_to_atom(lists:concat(['Arg', N]))}
- end, lists:seq(1, Arity))}]}].