Commits

Anonymous committed 9a1d9de

async_publish support and a bunch more test cases (some just to placate cover). Currently at 94.42% coverage.

Comments (0)

Files changed (2)

 -include_lib("gen_bunny.hrl").
 
 -export([start_link/4, stop/1]).
--export([publish/3, publish/4, get/2, ack/2]).
+-export([publish/3,
+         publish/4,
+         async_publish/3,
+         async_publish/4,
+         get/2,
+         ack/2]).
 
 -export([init/1,
          handle_call/3,
 %% API
 %%
 publish(Name, Key, Message) ->
-    gen_server:call(Name, {publish, Key, Message, []}).
+    publish(Name, Key, Message, []).
+
 publish(Name, Key, Message, Opts) ->
     gen_server:call(Name, {publish, Key, Message, Opts}).
 
 
+async_publish(Name, Key, Message) ->
+    async_publish(Name, Key, Message, []).
+
+async_publish(Name, Key, Message, Opts) ->
+    gen_server:cast(Name, {publish, Key, Message, Opts}).
+
+
 get(Name, NoAck) ->
     gen_server:call(Name, {get, NoAck}).
 
             State = #state{channel=Channel, exchange=Exchange})
   when is_binary(Key), is_binary(Message) orelse ?is_message(Message),
        is_list(Opts) ->
-    Resp = internal_publish(Channel, Exchange, Key, Message, Opts),
+    Resp = internal_publish(fun amqp_channel:call/3,
+                            Channel, Exchange, Key, Message, Opts),
     {reply, Resp, State};
 
 handle_call({get, NoAck}, _From,
     lib_amqp:close_connection(Connection),
     {stop, normal, ok, State}.
 
+handle_cast({publish, Key, Message, Opts},
+            State = #state{channel=Channel, exchange=Exchange})
+  when is_binary(Key), is_binary(Message) orelse ?is_message(Message),
+       is_list(Opts) ->
+    internal_publish(fun amqp_channel:cast/3,
+                     Channel, Exchange, Key, Message, Opts),
+    {noreply, State};
 
 handle_cast(_Request, State) ->
     {noreply, State}.
 %%
 %% Internal
 %%
-internal_publish(Channel, Exchange, Key, Message, Opts)
+internal_publish(Fun, Channel, Exchange, Key, Message, Opts)
   when ?is_message(Message) ->
     Mandatory = proplists:get_value(mandatory, Opts, false),
 
       routing_key = Key,
       mandatory = Mandatory},
 
-    amqp_channel:call(Channel, BasicPublish, Message),
-    ok;
-internal_publish(Channel, Exchange, Key, Message, Opts)
+    Fun(Channel, BasicPublish, Message);
+internal_publish(Fun, Channel, Exchange, Key, Message, Opts)
   when is_binary(Message) ->
-    internal_publish(Channel, Exchange, Key,
+    internal_publish(Fun, Channel, Exchange, Key,
                      bunny_util:new_message(Message), Opts).
 
 
          end])}.
 
 
+async_publish_test_() ->
+    {setup, fun normal_setup/0, fun normal_stop/1,
+     ?_test(
+        [begin
+             mock:expects(
+               amqp_channel, cast,
+               fun({dummy_channel, #'basic.publish'{
+                      exchange = <<"bunnyc.test">>,
+                      routing_key = <<"bunnyc.test">>},
+                    Message}) when ?is_message(Message) ->
+                       bunny_util:get_payload(Message) =:= <<"HELLO GOODBYE">>
+               end,
+               ok),
+
+             ?assertEqual(ok, bunnyc:async_publish(
+                                bunnyc_test,
+                                <<"bunnyc.test">>,
+                                <<"HELLO GOODBYE">>))
+         end])}.
+
+
 publish_message_test_() ->
     {setup, fun normal_setup/0, fun normal_stop/1,
      ?_test(
          end])}.
 
 
+async_publish_message_test_() ->
+    {setup, fun normal_setup/0, fun normal_stop/1,
+     ?_test(
+        [begin
+             ExpectedMessage = bunny_util:set_delivery_mode(
+                                 bunny_util:new_message(<<"HELLO">>),
+                                 2),
+
+             mock:expects(
+               amqp_channel, cast,
+               fun({dummy_channel, #'basic.publish'{exchange=Exchange,
+                                                    routing_key=Key},
+                    Message}) when ?is_message(Message) ->
+                       Exchange =:= <<"bunnyc.test">>
+                           andalso Key =:= <<"bunnyc.test">>
+                           andalso ExpectedMessage =:= Message
+               end,
+               ok),
+             ?assertEqual(ok, bunnyc:async_publish(
+                                bunnyc_test,
+                                <<"bunnyc.test">>,
+                                ExpectedMessage))
+         end])}.
+
+
 publish_mandatory_test_() ->
     {setup, fun normal_setup/0, fun normal_stop/1,
      ?_test(
          end])}.
 
 
+async_publish_mandatory_test_() ->
+    {setup, fun normal_setup/0, fun normal_stop/1,
+     ?_test(
+        [begin
+             mock:expects(
+               amqp_channel, cast,
+               fun({dummy_channel, #'basic.publish'{
+                      exchange = <<"bunnyc.test">>,
+                      routing_key = <<"bunnyc.test">>,
+                      mandatory = true},
+                    Message}) when ?is_message(Message) ->
+                       bunny_util:get_payload(Message) =:= <<"HELLO GOODBYE">>
+               end,
+               ok),
+
+             ?assertEqual(ok, bunnyc:async_publish(
+                                bunnyc_test,
+                                <<"bunnyc.test">>,
+                                <<"HELLO GOODBYE">>, [{mandatory, true}]))
+         end])}.
+
+
 get_test_() ->
     {setup, fun normal_setup/0, fun normal_stop/1,
      ?_test(
                           ok),
              ?assertEqual(ok, bunnyc:ack(bunnyc_test, <<"sometag">>))
          end])}.
+
+
+%% These are mostly to placate cover.
+
+unknown_cast_test() ->
+    ?assertEqual({noreply, #state{}},
+                 bunnyc:handle_cast(unknown_cast, #state{})).
+
+
+unknown_info_test() ->
+    ?assertEqual({noreply, #state{}},
+                 bunnyc:handle_info(unknown_info, #state{})).
+
+
+code_change_test() ->
+    ?assertEqual({ok, #state{}}, bunnyc:code_change(ign, #state{}, ign)).

src/gen_bunny.erl

             end
     end.
 
-get_opt(Opt, Proplist) ->
-    get_opt(Opt, Proplist, undefined).
-
 get_opt(Opt, Proplist, Default) ->
     {proplists:get_value(Opt, Proplist, Default),
      proplists:delete(Opt, Proplist)}.
         [begin
              ?assertEqual(
                 {blah, "You suck"},
-                connect_declare_subscribe(ConnectFun, fun() -> ok end,
+                connect_declare_subscribe(ConnectFun, noop,
                                           direct, <<"cds.test">>, true))
          end])}.
 
                      ?assertEqual([info_test], test_gb:get_infos(Pid))
                  end])
      end}.
+
+
+%% These are mostly to placate cover.
+
+behaviour_info_test() ->
+    ?assertEqual(lists:sort([{init, 1},
+                             {handle_message, 2},
+                             {handle_call, 3},
+                             {handle_cast, 2},
+                             {handle_info, 2},
+                             {terminate, 2}]),
+                 lists:sort(gen_bunny:behaviour_info(callbacks))),
+    ?assertEqual(undefined, gen_bunny:behaviour_info(ign)).
+
+
+code_change_test() ->
+    ?assertEqual({ok, #state{}}, gen_bunny:code_change(ign, #state{}, ign)).