Skip to content

Commit

Permalink
Merge pull request #275 from esl/missing_specs
Browse files Browse the repository at this point in the history
Add missing specs
  • Loading branch information
DenysGonchar authored Jan 20, 2025
2 parents 160e4cc + 662a480 commit 3b71af1
Show file tree
Hide file tree
Showing 24 changed files with 235 additions and 46 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,4 @@ jobs:
- run: make test
- run: make ct
- run: make dialyzer
if: ${{ matrix.otp == '27' }}
if: ${{ matrix.otp_vsn == '27' }}
1 change: 1 addition & 0 deletions src/escalus.app.src
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
{applications, [
kernel,
stdlib,
public_key,
ssl,
exml,
gun,
Expand Down
14 changes: 14 additions & 0 deletions src/escalus.erl
Original file line number Diff line number Diff line change
Expand Up @@ -136,46 +136,60 @@ story(Config, ResourceCounts, Story) ->

%% Assertions

-spec assert(atom(), term()) -> ok | no_return().
assert(PredSpec, Arg) ->
escalus_new_assert:assert(PredSpec, Arg).

-spec assert(atom(), [term()], term()) -> ok | no_return().
assert(PredSpec, Params, Arg) ->
escalus_new_assert:assert(PredSpec, Params, Arg).

-spec assert_many([atom()], [exml:element()]) -> ok | no_return().
assert_many(Predicates, Stanzas) ->
escalus_new_assert:assert_many(Predicates, Stanzas).

%% Client API

-spec send(client(), exml:element()) -> ok.
send(Client, Packet) ->
escalus_client:send(Client, Packet).

-spec send_and_wait(client(), exml:element()) -> exml:element().
send_and_wait(Client, Packet) ->
escalus_client:send_and_wait(Client, Packet).

-spec wait_for_stanza(client()) -> exml:element().
wait_for_stanza(Client) ->
escalus_client:wait_for_stanza(Client).

-spec wait_for_stanza(client(), timeout()) -> exml:element().
wait_for_stanza(Client, Timeout) ->
escalus_client:wait_for_stanza(Client, Timeout).

-spec wait_for_stanzas(client(), non_neg_integer()) -> [exml:element()].
wait_for_stanzas(Client, Count) ->
escalus_client:wait_for_stanzas(Client, Count).

-spec wait_for_stanzas(client(), non_neg_integer(), timeout()) -> [exml:element()].
wait_for_stanzas(Client, Count, Timeout) ->
escalus_client:wait_for_stanzas(Client, Count, Timeout).

-spec peek_stanzas(client()) -> [exml:element()].
peek_stanzas(Client) ->
escalus_client:peek_stanzas(Client).

-spec send_iq_and_wait_for_result(client(), exml:element()) -> exml:element() | no_return().
send_iq_and_wait_for_result(Client, Iq) ->
escalus_client:send_iq_and_wait_for_result(Client, Iq).

-spec send_iq_and_wait_for_result(client(), exml:element(), timeout()) ->
exml:element() | no_return().
send_iq_and_wait_for_result(Client, Iq, Timeout) ->
escalus_client:send_iq_and_wait_for_result(Client, Iq, Timeout).

%% Other functions

-spec override(config(), atom(), {atom(), atom()}) -> config().
override(Config, OverrideName, NewValue) ->
escalus_overridables:override(Config, OverrideName, NewValue).

1 change: 1 addition & 0 deletions src/escalus_assert.erl
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
%%==============================================================================

-module(escalus_assert).
-compile(nowarn_missing_spec).

-export([is_chat_message/2,
has_no_stanzas/1,
Expand Down
4 changes: 2 additions & 2 deletions src/escalus_bosh.erl
Original file line number Diff line number Diff line change
Expand Up @@ -412,8 +412,8 @@ handle_info({http_reply, Ref, Body, _Transport} = HttpReply,
{_, true} ->
S1 = handle_http_reply(Ref, XmlBody, S0, Timestamp),
S1#state{ pending_replies = [] };
{{value, {Ref, _Rid, _Pid}}, _} ->
{{value, {Ref, _Rid, _Pid}}, NewRequests} = queue:out(S0#state.requests),
{{value, {Ref, Rid, Pid}}, _} ->
{{value, {Ref, Rid, Pid}}, NewRequests} = queue:out(S0#state.requests),
S1 = handle_http_reply(Ref, XmlBody, S0#state{ requests = NewRequests }, Timestamp),
lists:foreach(fun(PendingReply) -> self() ! PendingReply end,
S1#state.pending_replies),
Expand Down
14 changes: 9 additions & 5 deletions src/escalus_bosh_gun.erl
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@
handle_call/3,
handle_cast/2,
handle_info/2,
terminate/2,
code_change/3]).
terminate/2]).

-record(state, {destination,
options,
Expand All @@ -28,9 +27,11 @@
start_link(Args) ->
gen_server:start_link(?MODULE, [Args], []).

-spec stop(pid()) -> ok.
stop(Pool) ->
gen_server:cast(Pool, stop).

-spec request(pid(), iodata(), gun:req_headers(), iodata()) -> term().
request(Pool, Path, Hdrs, Body) ->
case get_client(Pool) of
{error, _} = Error ->
Expand Down Expand Up @@ -62,6 +63,8 @@ init([Args]) ->
queue = queue:new()
}, 0}.

-spec handle_call(get_client, gen_server:from(), state()) ->
{reply, term(), state()} | {noreply, state()}.
handle_call(get_client, _From, State = #state{free = [Client | Free],
busy = Busy}) ->
{reply, Client, State#state{free = Free,
Expand All @@ -83,6 +86,8 @@ handle_call(get_client, From, State = #state{free = [],
when M == T ->
{noreply, State#state{queue = queue:in(From, Queue)}}.

-spec handle_cast({free_client, pid()} | stop, state()) ->
{noreply, state()} | {stop, term(), state()}.
handle_cast({free_client, Pid}, State = #state{free = Free,
busy = Busy,
queue = Queue}) ->
Expand All @@ -98,6 +103,7 @@ handle_cast({free_client, Pid}, State = #state{free = Free,
handle_cast(stop, State) ->
{stop, normal, State}.

-spec handle_info(term(), state()) -> {noreply, state()}.
handle_info({'EXIT', From, _Reason}, State = #state{free = Free,
busy = Busy,
total = Total}) ->
Expand All @@ -113,14 +119,12 @@ handle_info(_Info, State) ->
ct:pal("Unknown Info in bosh_gun: ~p", [_Info]),
{noreply, State}.

-spec terminate(term(), state()) -> ok.
terminate(_Reason, #state{free = Free, busy = Busy}) ->
[gun:close(F) || F <- Free],
[gun:close(B) || B <- Busy],
ok.

code_change(_OldVsn, State, _Extra) ->
{ok, State}.

connect({Host, Port}, Options) ->
{ok, Pid} = gun:open(Host, Port, Options#{protocols => [http]}),
{ok, http} = gun:await_up(Pid),
Expand Down
5 changes: 5 additions & 0 deletions src/escalus_compat.erl
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
%% Public API
%%--------------------------------------------------------------------

-spec bin(binary() | string() | atom() | integer()) -> binary() | no_return().
bin(Arg) when is_binary(Arg) ->
Arg;
bin(Arg) when is_list(Arg) ->
Expand All @@ -46,17 +47,21 @@ bin(Other) ->
type_complain("???", Other),
error(badarg, [Other]).

-spec deprecated(atom(), atom(), T) -> T.
deprecated(Old, New, Result) ->
error_logger:info_msg("calling deprecated function ~p, use ~p instead~n~p~n",
[Old, New, backtrace(1)]),
Result.

-spec unimplemented() -> no_return().
unimplemented() ->
throw({unimplemented, backtrace(1)}).

-spec complain(term()) -> ok.
complain(What) ->
error_logger:info_msg("~s at ~p~n", [What, backtrace(1)]).

-spec backtrace(non_neg_integer()) -> list().
backtrace(N) ->
{current_stacktrace, Stacktrace} = erlang:process_info(self(), current_stacktrace),
lists:nthtail(N + 1, Stacktrace).
Expand Down
1 change: 1 addition & 0 deletions src/escalus_component.erl
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ handle_info(Info, #component_state{module = M, client = C, user_state = S} = Sta
{noreply, NewState, ?WAIT_AFTER_STANZA}.


-spec terminate(atom(), state()) -> any().
terminate(Reason, #component_state{client = C, module = M, user_state = S}) ->
catch escalus_connection:stop(C),
case erlang:function_exported(M, terminate, 2) of
Expand Down
3 changes: 3 additions & 0 deletions src/escalus_connection.erl
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,7 @@ upgrade_to_tls(#client{module = Mod, rcv_pid = Pid, props = Props}) ->
SSLOpts = proplists:get_value(ssl_opts, Props, DefSslOpts),
Mod:upgrade_to_tls(Pid, SSLOpts).

-spec wait_for_close(client()) -> boolean().
wait_for_close(Client) ->
wait_for_close(Client, default_timeout()).

Expand Down Expand Up @@ -476,6 +477,8 @@ maybe_forward_to_owner(_, State, Stanzas, Fun, Timestamp) ->
stanza_msg(Stanza, Metadata) ->
{stanza, self(), Stanza, Metadata}.

-spec separate_ack_requests({boolean(), non_neg_integer(), term()}, [exml_stream:element()]) ->
{{boolean(), non_neg_integer(), term()}, [exml_stream:element()], [exml_stream:element()]}.
separate_ack_requests({false, H0, A}, Stanzas) ->
%% Don't keep track of H
{{false, H0, A}, [], Stanzas};
Expand Down
1 change: 1 addition & 0 deletions src/escalus_ct.erl
Original file line number Diff line number Diff line change
Expand Up @@ -163,5 +163,6 @@ ct_log_timestamp({MS, S, US}) ->
"~2.10.0B:~2.10.0B:~2.10.0B.~3.10.0B",
[Year, Month, Day, Hour, Min, Sec, MilliSec])).

-spec log_error(term(), [any()]) -> ok.
log_error(Format, Args) ->
ct:pal(error, Format, Args).
35 changes: 29 additions & 6 deletions src/escalus_ejabberd.erl
Original file line number Diff line number Diff line change
Expand Up @@ -53,21 +53,26 @@
%%% Business API
%%%

-spec rpc(atom(), atom(), [any()], timeout()) -> any().
rpc(M, F, A, Timeout) ->
Node = escalus_ct:get_config(ejabberd_node),
Cookie = escalus_ct:get_config(ejabberd_cookie),
escalus_rpc:call(Node, M, F, A, Timeout, Cookie).

-spec rpc(atom(), atom(), [any()]) -> any().
rpc(M, F, A) ->
rpc(M, F, A, 3000).

-spec remote_display(string()) -> true.
remote_display(String) ->
Line = [$\n, [$- || _ <- String], $\n],
remote_format("~s~s~s", [Line, String, Line]).

-spec remote_format(string()) -> true.
remote_format(Format) ->
remote_format(Format, []).

-spec remote_format(string(), [any()]) -> true.
remote_format(Format, Args) ->
group_leader(rpc(erlang, whereis, [user]), self()),
io:format(Format, Args),
Expand Down Expand Up @@ -106,14 +111,17 @@ with_local_option(Option, Value, Fun) ->
end, lists:zip(Hosts, OldValues))
end.

get_c2s_status(#client{jid=Jid}) ->
-spec get_c2s_status(escalus:client()) -> term().
get_c2s_status(#client{jid = Jid}) ->
{match, USR} = re:run(Jid, <<"([^@]*)@([^/]*)/(.*)">>, [{capture, all_but_first, list}]),
Pid = rpc(ejabberd_sm, get_session_pid, USR),
rpc(sys, get_status, [Pid]).

-spec wait_for_session_count(escalus:config(), non_neg_integer()) -> ok | no_return().
wait_for_session_count(Config, Count) ->
wait_for_session_count(Config, Count, 0).

-spec get_remote_sessions(escalus:config()) -> term().
get_remote_sessions(Config) ->
escalus_overridables:do(Config, get_remote_sessions, [],
{?MODULE, default_get_remote_sessions}).
Expand Down Expand Up @@ -203,8 +211,13 @@ reset_option({Option, _, Set, _}, Config) ->
%% escalus_user_db callbacks
%%--------------------------------------------------------------------

start(_) -> ok.
stop(_) -> ok.
-spec start(_) -> ok.
start(_) ->
ok.

-spec stop(_) -> ok.
stop(_) ->
ok.

-spec create_users(escalus:config(), [escalus_users:named_user()]) -> escalus:config().
create_users(Config, Users) ->
Expand All @@ -220,11 +233,17 @@ delete_users(Config, Users) ->
%% escalus_server callbacks
%%--------------------------------------------------------------------

pre_story(Config) -> Config.
-spec pre_story(escalus:config()) -> escalus:config().
pre_story(Config) ->
Config.

post_story(Config) -> Config.
-spec post_story(escalus:config()) -> escalus:config().
post_story(Config) ->
Config.

name() -> ?MODULE.
-spec name() -> atom().
name() ->
?MODULE.

%%--------------------------------------------------------------------
%% Helpers
Expand All @@ -245,16 +264,20 @@ unregister_user(Config, {_UserName, UserSpec}) ->
[U, S, _P] = USP,
rpc(ejabberd_admin, unregister, [U, S], 30000).

-spec default_get_remote_sessions() -> any().
default_get_remote_sessions() ->
rpc(ejabberd_sm, get_full_session_list, []).

-spec legacy_get_remote_sessions() -> any().
legacy_get_remote_sessions() ->
rpc(ejabberd_sm, dirty_get_sessions_list, []).

-spec unify_str_arg(any()) -> any().
unify_str_arg(Arg) ->
StrFormat = escalus_ct:get_config(ejabberd_string_format),
unify_str_arg(Arg, StrFormat).

-spec unify_str_arg(any(), str | string()) -> any().
unify_str_arg(Arg, str) when is_binary(Arg) ->
binary_to_list(Arg);
unify_str_arg(Arg, _) ->
Expand Down
15 changes: 10 additions & 5 deletions src/escalus_event.erl
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@

-include_lib("exml/include/exml.hrl").

-type config() :: escalus_config:config().
-type event_client() :: list({atom(), any()}).
-type manager() :: pid().
-type resource() :: binary().
Expand All @@ -41,40 +40,47 @@ add_handler(Mgr, Handler, Args) ->
delete_handler(Mgr, Handler, Args) ->
gen_event:delete_handler(Mgr, Handler, Args).

-spec incoming_stanza(event_client(), exml_stream:element()) -> ok.
incoming_stanza(Client, Stanza) ->
notify_stanza(Client, incoming_stanza, Stanza).

-spec pop_incoming_stanza(event_client(), exml_stream:element()) -> ok.
pop_incoming_stanza(Client, Stanza) ->
notify_stanza(Client, pop_incoming_stanza, Stanza).

-spec outgoing_stanza(event_client(), exml_stream:element()) -> ok.
outgoing_stanza(Client, Stanza) ->
notify_stanza(Client, outgoing_stanza, Stanza).

-spec story_start(escalus_config:config()) -> ok.
story_start(Config) ->
gen_event:notify(manager(Config), story_start).

-spec story_end(escalus_config:config()) -> ok.
story_end(Config) ->
gen_event:notify(manager(Config), story_end).


%% ====================================================================

%% @doc Start the event manager
%% @end
-spec start(escalus_config:config()) -> escalus_config:config().
start(Config) ->
{ok, Mgr} = gen_event:start_link(),
add_handler(Mgr, escalus_history_h, []),
[{escalus_event_mgr, Mgr} | Config].

%% @doc Stop the event manager
%% @end
-spec stop(escalus_config:config()) -> escalus_config:config().
stop(Config) ->
gen_event:stop(manager(Config)),
Config.

-spec get_history(escalus_config:config()) -> [term()].
get_history(Config) ->
escalus_history_h:get_history(manager(Config)).

-spec print_history(escalus_config:config()) -> ok.
print_history(Config) ->
CaseName = proplists:get_value(tc_name, Config),
PrivDir = proplists:get_value(priv_dir, Config),
Expand Down Expand Up @@ -179,7 +185,7 @@ manager(Config) ->

%% @doc Create a new event emitter.
-spec new_client(Config, User, MaybeResource) -> undefined | EventClient when
Config :: config(),
Config :: escalus_config:config(),
User :: escalus_users:user_name() | escalus_users:user_spec(),
MaybeResource :: undefined | resource(),
EventClient :: event_client().
Expand All @@ -206,7 +212,6 @@ new_client_1(Mgr, UserSpec, Resource) ->

%% @doc Notify the event system of an event
%% <p>The system accepts any term as the event.</p>
%% @end
notify_stanza(undefined, _, _) ->
ok;
notify_stanza(Client, EventName, Stanza) ->
Expand Down
Loading

0 comments on commit 3b71af1

Please sign in to comment.