Packages

Erlang grab bag of useful functions. It should have been called swiss army knife but katanas are deadlier

Current section

Files

Jump to
katana src ktn_test_utils.erl
Raw

src/ktn_test_utils.erl

-module(ktn_test_utils).
-export(
[ assert_response/4
, test_response/4
]).
-type test_subject() :: status | headers | body.
-type match_type() :: exact | partial.
-type response() :: #{status => term(), headers => term(), body => term()}.
-spec assert_response(test_subject(), match_type(), term(), response()) -> ok.
assert_response(Test, MatchType, Params, Response) ->
ok = test_response(Test, MatchType, Params, Response).
-spec test_response(test_subject(), match_type(), term(), term()) ->
ok | {error, term()}.
test_response(status, partial, [C, $?, $?], Response) ->
Pattern = [C] ++ "[0-9][0-9]",
test_response(status, partial, Pattern, Response);
test_response(status, partial, [C1, C2, $?], Response) ->
Pattern = [C1, C2] ++ "[0-9]",
test_response(status, partial, Pattern, Response);
test_response(status, partial, Pattern, Response) ->
#{status := Status} = Response,
ResStatus = ktn_strings:to_string(Status),
case re:compile(Pattern) of
{ok, MP} ->
case re:run(ResStatus, MP, [global]) of
match -> ok;
{match, [[{0, 3}]]} -> ok;
nomatch -> {error, {nomatch, Pattern, ResStatus}}
end;
{error, Error} ->
{error, {regex_compile_fail, Error}}
end;
test_response(status, exact, Status, Response) ->
#{status := ResStatus} = Response,
StatusStr = ktn_strings:to_string(Status),
ResStatusStr = ktn_strings:to_string(ResStatus),
case ResStatusStr of
StatusStr -> ok;
_Other -> {error, {nomatch, StatusStr, ResStatusStr}}
end;
test_response(headers, partial, Headers, Response) ->
#{headers := ResHeaders} = Response,
HeadersNorm =
[{string:to_lower(X), string:to_lower(Y)} || {X, Y} <- Headers],
ResHeadersNorm =
[{string:to_lower(X), string:to_lower(Y)} || {X, Y} <- ResHeaders],
case HeadersNorm -- ResHeadersNorm of
[] -> ok;
MissingHeaders -> {error, {missing_headers, MissingHeaders, ResHeadersNorm}}
end;
test_response(headers, exact, Headers, Response) ->
#{headers := ResHeaders} = Response,
HeadersNorm =
[{string:to_lower(X), string:to_lower(Y)} || {X, Y} <- Headers],
ResHeadersNorm =
[{string:to_lower(X), string:to_lower(Y)} || {X, Y} <- ResHeaders],
case {HeadersNorm -- ResHeadersNorm, ResHeadersNorm -- HeadersNorm} of
{[], []} -> ok;
_ -> {error, {nomatch, HeadersNorm, ResHeadersNorm}}
end;
test_response(body, partial, Pattern, Response) ->
#{body := ResBody} = Response,
ResBodyStr = ktn_strings:to_string(ResBody),
case re:compile(Pattern) of
{ok, MP} ->
case re:run(ResBodyStr, MP) of
{match, _} -> ok;
nomatch -> {error, {nomatch, Pattern, ResBodyStr}}
end;
{error, Error} ->
{error, {regex_compile_fail, Error}}
end;
test_response(body, exact, Text, Response) ->
#{body := ResBody} = Response,
ResBodyStr = ktn_strings:to_string(ResBody),
Body = ktn_strings:to_string(Text),
case ResBodyStr of
Body -> ok;
_ -> {error, {nomatch, ResBodyStr, Body}}
end.