Packages

KATT (Klarna API Testing Tool) is an HTTP-based API testing tool for Erlang.

Current section

Files

Jump to
katt src katt_cli.erl
Raw

src/katt_cli.erl

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Copyright 2014- AUTHORS
%%%
%%% 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.
%%%
%%% @copyright 2014- AUTHORS
%%%
%%% @doc Klarna API Testing Tool
%%%
%%% CLI.
%%% @end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%_* Module declaration =======================================================
-module(katt_cli).
%%%_* Exports ==================================================================
%% API
-export([main/1]).
%%%_* API ======================================================================
-ifdef(BARE_MODE).
main(_) ->
{error, katt_bare_mode}.
-else.
main([]) ->
main(["--help"]);
main(["-h"]) ->
main(["--help"]);
main(["--help"]) ->
io:fwrite( "Usage: ~s [--json] [--all] [param=string] [param:=non_string] -- "
"file.katt [file.katt] ~n"
, [escript:script_name()]
),
katt_har_cli:help();
main(Options) ->
main(Options, [], [], []).
main(["from-har"|Rest], [], [], []) ->
katt_har_cli:main(Rest);
main(["--json"|Rest], Options, [], []) ->
main(Rest, [{json, true}|Options], [], []);
main(["--all"|Rest], Options, [], []) ->
main(Rest, [{all, true}|Options], [], []);
main([], _, _, _) ->
throw({error, missing_scenario_filenames});
main(["--"|ScenarioFilenames], Options, Params0, []) ->
Params = parse_params(Params0),
run(Options, Params, ScenarioFilenames);
main([Param|Rest], Options, Params, []) ->
main(Rest, Options, [Param|Params], []).
%%%_* Internal =================================================================
run(_Options, _Params, []) ->
ok;
run(Options, Params0, [ScenarioFilename|ScenarioFilenames]) ->
KattResult0 = katt_run(ScenarioFilename, Params0),
KattResult = case {proplists:get_value('all', Options, false), KattResult0} of
{false, { PassOrFail
, ScenarioFilename
, Params
, FinalParams
, TransactionResults0
}} ->
{ PassOrFail
, ScenarioFilename
, Params
, FinalParams
, [lists:last(TransactionResults0)]
};
_ ->
KattResult0
end,
case proplists:get_value(json, Options) of
undefined ->
io:fwrite("~p\n\n", [KattResult]);
true ->
JsonResult = katt_util:run_result_to_jsx(KattResult),
Result = jsx:encode(JsonResult),
io:fwrite("~s\n\n", [Result])
end,
case KattResult of
{pass, _, _, NewParams , _} ->
run(Options, NewParams, ScenarioFilenames);
_ ->
%% init:stop not setting status code correctly
%% init:stop(1)
halt(1)
end.
katt_run(ScenarioFilename, Params) ->
%% Don't use application:ensure_all_started(katt)
%% nor application:ensure_started(_)
%% in order to maintain compatibility with R16B01 and lower
ok = ensure_started(crypto),
ok = ensure_started(asn1),
ok = ensure_started(public_key),
ok = ensure_started(ssl),
ok = ensure_started(jsx),
ok = ensure_started(unicode_util_compat),
ok = ensure_started(idna),
ok = ensure_started(mimerl),
ok = ensure_started(certifi),
ok = ensure_started(metrics),
ok = ensure_started(syntax_tools),
ok = ensure_started(parse_trans),
ok = ensure_started(ssl_verify_fun),
ok = ensure_started(hackney),
ok = ensure_started(tdiff),
ok = ensure_started(katt),
katt:run( ScenarioFilename
, Params
, [{ progress
, fun(Step, Detail) ->
io:fwrite( standard_error
, "\n== PROGRESS REPORT ~p ==\n~p\n\n~p\n\n"
, [Step, erlang:localtime(), Detail])
end
}]).
parse_params(Params) ->
parse_params(Params, []).
parse_params([], Acc) ->
lists:reverse(Acc);
parse_params([Param|Params], Acc) ->
{Key, Value} = parse_param(Param),
parse_params(Params, [{Key, Value}|Acc]).
parse_param(Param) ->
parse_param(Param, []).
parse_param(":=" ++ _Value, []) ->
throw({error, invalid_key});
parse_param("=" ++ _Value, []) ->
throw({error, invalid_key});
parse_param(":=" ++ Value, Key) ->
{lists:reverse(Key), convert(Value)};
parse_param("=" ++ Value, Key) ->
{lists:reverse(Key), Value};
parse_param([Char|Rest], Key) ->
parse_param(Rest, [Char|Key]).
convert(Value) ->
try_to_convert_to([null, integer, float, boolean], Value).
try_to_convert_to([], _Value) ->
throw({error, unknown_param_type});
try_to_convert_to([null|Rest], Value0) ->
Value = string:to_lower(Value0),
case Value of
"null" ->
null;
_ ->
try_to_convert_to(Rest, Value)
end;
try_to_convert_to([integer|Rest], Value) ->
case string:to_integer(Value) of
{error, _} ->
try_to_convert_to(Rest, Value);
{IntValue, []} ->
IntValue;
_ ->
try_to_convert_to(Rest, Value)
end;
try_to_convert_to([float|Rest], Value) ->
case string:to_float(Value) of
{error, _} ->
try_to_convert_to(Rest, Value);
{FloatValue, []} ->
FloatValue;
_ ->
try_to_convert_to(Rest, Value)
end;
try_to_convert_to([boolean|Rest], Value0) ->
Value = string:to_lower(Value0),
case Value of
"true" ->
true;
"false" ->
false;
_ ->
try_to_convert_to(Rest, Value0)
end.
ensure_started(App) ->
case application:start(App) of
ok ->
ok;
{error, {already_started, App}} ->
ok
end.
-endif.