Commit e77951ff authored by Siebers, Michael's avatar Siebers, Michael
Browse files

Harmonized type_error tests; restructured testing files

parent 6ef2ee73
:- use_module(web_api).
/***************************************
* *
* Helpers generating erroneous values *
* *
***************************************/
type_not_atom(Value) :- member(Value, [1, "test", 7.3, some(term)]).
type_not_dict(Value) :- member(Value, [
1,
test,
"test",
7.3,
some(term),
[key=value],
[key: value]
]).
type_not_integer(Value) :- member(Value, [
an_atom,
"test",
1.0,
7.3,
some(term),
["test"]
]).
type_not_list(Value) :- type_not_term('[|]'/2, Value).
type_not_text(Value) :- member(Value, [1, 7.3, some(term), ["test"]]).
type_not_term(_,Value) :- member(Value, [1, "test", test, 7.3]).
type_not_term(P/A, ["test"]) :- P/A \= '[|]'/2.
type_not_term(P/A, some(term)) :- P/A \= some/1.
type_not_term(P/A, Value) :-
succ(TooFew, A),
between(1,TooFew,N),
functor(Value,P,N),
numbervars(Value,0,_).
type_not_term(P/A, Value) :-
succ(A,TooMany),
functor(Value,P,TooMany),
numbervars(Value,0,_).
:- prolog_load_context(directory, Dir),
path_segments_atom(Dir/web_api/'*.plt',WebApiFiles),
load_files(WebApiFiles,[expand(true)]).
:- begin_tests(web_api_expl_integration).
:- use_module(web_api).
/***************************
* *
* web_api -> explanations *
* *
***************************/
:- dynamic user:irrelevant/1.
:- dynamic explanations:explain/4.
%%
%% irrelevance mocks
%%
setup_irrelevance_mocks :-
assertz(user:irrelevant('some_path')),
assertz(user:irrelevant('/yet/another/pa.th')).
cleanup_irrelevance_mocks :-
retractall(user:irrelevant('some_path')),
retractall(user:irrelevant('/yet/another/pa.th')).
setup_irrelevance_throws(Error) :-
asserta((user:irrelevant(_) :- throw(Error))).
:- begin_tests('web_api -> explanations').
cleanup_irrelevance_throws :-
retractall(user:irrelevant(_)).
%%
%% explain mocks
%%
/*********
* mocks *
*********/
explain_mock('some_path', 1,
["this ", "is ", "a ", reference("test",0)],
[
......@@ -81,149 +69,11 @@ setup_explain_throws(Error) :-
cleanup_explain_throws :-
retractall(explanations:explain(_,_,_,_)).
%%
%% do_handle_irrelevant_file/2
%%
% do_handle_irrelevant_file(Dict, Path) succeeds with correct path
% if Dict contains only the key abs_path with the Path of an
% irrelevant file as atom.
test(do_handle_irrelevant_file_happy,
[
forall(member(Path,['some_path', '/yet/another/pa.th'])),
setup(setup_irrelevance_mocks),
cleanup(cleanup_irrelevance_mocks)
]) :-
web_api:do_handle_irrelevant_file(_{abs_path:Path},Path).
% do_handle_irrelevant_file(Dict, Path) fails if Dict contains only
% the key abs_path with the Path of a relevant file as atom.
test(do_handle_irrelevant_file_fail,
[
forall(member(Path,['another_path', '/some/other/path'])),
fail
]) :-
web_api:do_handle_irrelevant_file(_{abs_path:Path},_).
% do_handle_irrelevant_file(Dict, Path) throws error(type_error(dict, Dict),_)
% if Dict is no dict. Takes precedence over other errors.
test(do_handle_irrelevant_file_nodict,
[
forall(member(OtherTypeValue, [1, "test", 7.3, some(term)])),
error(type_error(dict, OtherTypeValue))
]) :-
web_api:do_handle_irrelevant_file(OtherTypeValue,_).
test(do_handle_irrelevant_file_type,
[
forall(member(OtherTypeValue, [1, "test", 7.3, some(term)])),
error(type_error(dict, OtherTypeValue)),
setup(setup_irrelevance_throws(some_error)),
cleanup(cleanup_irrelevance_throws)
]) :-
web_api:do_handle_irrelevant_file(OtherTypeValue,_).
% do_handle_irrelevant_file(Dict, Path) throws
% error(existence_error(key, abs_path, Dict),_) if Dict does not
% contain the key abs_path. Takes precendence over unknown_key
% and implementation_error.
test(do_handle_irrelevant_file_missingkey,
[
forall(member(Dict,[t{},t{another_key:some_atom}])),
error(existence_error(key, abs_path, Dict))
]) :-
web_api:do_handle_irrelevant_file(Dict,_).
test(do_handle_irrelevant_file_missingkey,
[
forall(member(Dict,[t{},t{another_key:some_atom}])),
setup(setup_irrelevance_throws(some_error)),
cleanup(cleanup_irrelevance_throws),
error(existence_error(key, abs_path, Dict))
]) :-
web_api:do_handle_irrelevant_file(Dict,_).
% do_handle_irrelevant_file(Dict, Path) throws error(instantiation_error,_)
% if the dict value under abs_path is unbound. Takes precedence over type_error,
% unknown_key, and implementation_error.
test(do_handle_irrelevant_file_instantiation,
[
forall(member(Dict,[t{abs_path:_},t{abs_path:_,another_key:some_atom}])),
error(instantiation_error)
]) :-
web_api:do_handle_irrelevant_file(Dict,_).
test(do_handle_irrelevant_file_instantiation,
[
forall(member(Dict,[t{abs_path:_},t{abs_path:_,another_key:some_atom}])),
setup(setup_irrelevance_throws(some_error)),
cleanup(cleanup_irrelevance_throws),
error(instantiation_error)
]) :-
web_api:do_handle_irrelevant_file(Dict,_).
% do_handle_irrelevant_file(Dict, Path) throws error(type_error(atom, AbsPath),_)
% if the dict value under abs_path is not an atom. Takes precedence over
% unknown_key and implementation_error.
test(do_handle_irrelevant_file_type,
[
forall(
(
member(OtherTypeValue, [1, "test", 7.3, some(term)]),
(Dict=t{abs_path:OtherTypeValue}; Dict=t{abs_path:OtherTypeValue,another_key:some_atom})
)
),
error(type_error(atom, OtherTypeValue))
]) :-
web_api:do_handle_irrelevant_file(Dict,_).
test(do_handle_irrelevant_file_type,
[
forall(
(
member(OtherTypeValue, [1, "test", 7.3, some(term)]),
(Dict=t{abs_path:OtherTypeValue}; Dict=t{abs_path:OtherTypeValue,another_key:some_atom})
)
),
setup(setup_irrelevance_throws(some_error)),
cleanup(cleanup_irrelevance_throws),
error(type_error(atom, OtherTypeValue))
]) :-
web_api:do_handle_irrelevant_file(Dict,_).
% do_handle_irrelevant_file(Dict, Path) throws error(unknown_key(KeyName, Dict),_)
% if the dict contains any other key than abs_path. Takes precedence over implementation_error.
test(do_handle_irrelevant_file_unknown,
[
error(unknown_key(another_key, t{abs_path:some_atom,another_key:another_atom}))
]) :-
web_api:do_handle_irrelevant_file(t{abs_path:some_atom,another_key:another_atom},_).
test(do_handle_irrelevant_file_unknown,
[
error(unknown_key(another_key, t{abs_path:some_atom,another_key:another_atom})),
setup(setup_irrelevance_throws(some_error)),
cleanup(cleanup_irrelevance_throws)
]) :-
web_api:do_handle_irrelevant_file(t{abs_path:some_atom,another_key:another_atom},_).
% do_handle_irrelevant_file(Dict, Path) throws error(implementation_error(Cause),_)
% if checking the irrelevance itself throws Cause.
test(do_handle_irrelevant_file_implementation,
[ forall(member(Error,[some_error,"error text",a(describing,term)])),
error(implementation_error(Error)),
setup(setup_irrelevance_throws(Error)),
cleanup(cleanup_irrelevance_throws)
]) :-
web_api:do_handle_irrelevant_file(t{abs_path:some_atom},_).
%%
%% do_handle_explain/3
%%
/***********************
* do_handle_explain/3 *
***********************/
% do_handle_explain(Dict, Result, More) succeeds with correct result
% if Dict contains the key abs_path with the Path of an irrelevant file
......@@ -282,8 +132,7 @@ test(do_handle_explain_notirrelevant,
% if Dict is no dict. Takes precedence over other errors.
test(do_handle_explain_nodict,
[
forall(member(OtherTypeValue,
[1, "test", 7.3, some(term), [abs_path='some_path']])),
forall(type_not_dict(OtherTypeValue)),
setup(setup_explain_throws(some_error)),
cleanup(cleanup_explain_throws),
error(type_error(dict, OtherTypeValue))
......@@ -340,7 +189,7 @@ test(do_handle_explain_type,
[
forall(
(
member(OtherTypeValue, [1, "test", 7.3, some(term)]),
type_not_atom(OtherTypeValue),
(Parameters=t{abs_path:OtherTypeValue};
Parameters=t{abs_path:OtherTypeValue, limit:1};
Parameters=t{abs_path:OtherTypeValue, limit:1,
......@@ -356,7 +205,7 @@ test(do_handle_explain_type,
[
forall(
(
member(OtherTypeValue, [an_atom, "test", 7.3, some(term)]),
type_not_integer(OtherTypeValue),
(Parameters=t{abs_path:'some_path', limit:OtherTypeValue}; Parameters=t{abs_path:'some_path', limit:OtherTypeValue,
another_key:some_atom})
)
......@@ -398,11 +247,11 @@ test(do_handle_explain_implemention,
web_api:do_handle_explain(t{abs_path:'some_path'},_Result,_More).
%%
%% explain_message_to_json/2
%%
/*****************************
* explain_message_to_json/2 *
*****************************/
% explain_message_to_json(Message, JSON) succeeds with
% explain_message_to_json(Message, JSON) succeeds with
% correct result given a valid input.
test(explain_message_to_json_happy_simple, % simple
[
......@@ -456,20 +305,20 @@ test(explain_message_to_json_message_type_list, % message no list
test(explain_message_to_json_message_type_text, % text no text
[
forall(member(OtherTypeValue, [1, 7.3, some(term), ["test"]])),
forall(type_not_text(OtherTypeValue)),
error(type_error(text,OtherTypeValue))
]) :-
web_api:explain_message_to_json([OtherTypeValue], _ActualJSON).
test(explain_message_to_json_message_type_referencetext, % reference text no text
[
forall(member(OtherTypeValue, [1, 7.3, some(term), ["test"]])),
forall(type_not_text(OtherTypeValue)),
error(type_error(text,OtherTypeValue))
]) :-
web_api:explain_message_to_json([reference(OtherTypeValue,0)], _ActualJSON).
test(explain_message_to_json_message_type_referenceid, % reference id no integer
[
forall(member(OtherTypeValue, ["ref", a, 1.0, 7.3, some(term), ["test"]])),
forall(type_not_integer(OtherTypeValue)),
error(type_error(integer,OtherTypeValue))
]) :-
web_api:explain_message_to_json([reference("text",OtherTypeValue)],
......@@ -485,9 +334,9 @@ test(explain_message_to_json_uninstantiaton,
web_api:explain_message_to_json(["some text"], BoundJSON).
%%
%% explain_references_to_json/2
%%
/********************************
* explain_references_to_json/2 *
********************************/
% explain_references_to_json(References, JSON) succeeds with
% correct result given a valid input.
......@@ -573,16 +422,14 @@ test(explain_reference_to_json_instantiation,
% if References or any part of it is of the wrong type.
test(explain_reference_to_json_message_type_list, % References no list
[
forall(member(References, [1, "test", test, 7.3, some(term)])),
forall(type_not_list(References)),
error(type_error(list,References))
]) :-
web_api:explain_reference_to_json(References, _ActualJSON).
test(explain_reference_to_json_message_type_reference, % reference no ref(_,_)
[
forall(member(OtherTypeValue, ["ref", a, 1.0, 7.3, some(term),
["test"], ref(too_few_args),
ref(too, many, args)])),
forall(type_not_term(ref/2,OtherTypeValue)),
error(type_error(ref(_,_),OtherTypeValue))
]) :-
References = [OtherTypeValue],
......@@ -590,7 +437,7 @@ test(explain_reference_to_json_message_type_reference, % reference no ref(_,_)
test(explain_reference_to_json_message_type_id, % id no integer
[
forall(member(OtherTypeValue, ["ref", a, 1.0, 7.3, some(term), ["test"]])),
forall(type_not_integer(OtherTypeValue)),
error(type_error(integer,OtherTypeValue))
]) :-
References = [ref(OtherTypeValue,[entity("some_path","name")])],
......@@ -598,23 +445,21 @@ test(explain_reference_to_json_message_type_id, % id no integer
test(explain_reference_to_json_message_type_entities, % entities no list
[
forall(member(OtherTypeValue, [1, "test", test, 7.3, some(term)])),
forall(type_not_list(OtherTypeValue)),
error(type_error(list,OtherTypeValue))
]) :-
References = [ref(0,OtherTypeValue)],
web_api:explain_reference_to_json(References, _ActualJSON).
test(explain_reference_to_json_message_type_entity, % entity is not entity(_,_)
[
forall(member(OtherTypeValue, [1, 7.3, some(binary,term),
["test"], entity(too_few_args),
entity(too,many, args)])),
forall(type_not_term(entity/2,OtherTypeValue)),
error(type_error(entity(_,_),OtherTypeValue))
]) :-
References = [ref(0,[OtherTypeValue])],
web_api:explain_reference_to_json(References, _ActualJSON).
test(explain_reference_to_json_message_type_entitypath, % entity path not text
[
forall(member(OtherTypeValue, [1, 7.3, some(term), ["test"]])),
forall(type_not_text(OtherTypeValue)),
error(type_error(text,OtherTypeValue))
]) :-
References = [ref(0,[entity(OtherTypeValue,"name")])],
......@@ -622,7 +467,7 @@ test(explain_reference_to_json_message_type_entitypath, % entity path not text
test(explain_reference_to_json_message_type_entityproperty, % entity property not text
[
forall(member(OtherTypeValue, [1, 7.3, some(term), ["test"]])),
forall(type_not_text(OtherTypeValue)),
error(type_error(text,OtherTypeValue))
]) :-
References = [ref(0,[entity("some_path",OtherTypeValue)])],
......@@ -651,9 +496,9 @@ test(explain_reference_to_json_uninstantiaton,
%%
%% explain_explanation_to_json/2
%%
/*********************************
* explain_explanation_to_json/2 *
*********************************/
% explain_explanation_to_json(Explanation, JSON) succedes deterministically with
% correct results given valid message input.
......@@ -711,12 +556,7 @@ test(explain_explanation_to_json_instantiation,
% expected type.
test(explain_explanation_to_json_type,
[
forall(member(OtherTypeValue, [1, 7.3, some(binary,term),
["test"],
explanation(one_arg),
explanation(two,args),
explanation(only,three,args),
explanation(way,too,many,arguments,given)])),
forall(type_not_term(explanation/4,OtherTypeValue)),
error(type_error(explanation(_,_,_,_),OtherTypeValue)) ]) :-
web_api:explain_explanation_to_json(OtherTypeValue, _ActualJSON).
......@@ -744,7 +584,7 @@ test(explain_explanation_to_json_abspath_instantiation,
% no text type.
test(explain_explanation_to_json_abspath_type,
[
forall(member(OtherTypeValue, [1, 7.3, some(term), ["test"]])),
forall(type_not_text(OtherTypeValue)),
error(type_error(text,OtherTypeValue))
]) :-
Message = [ "some arbitrary", reference("message",0) ],
......@@ -764,7 +604,7 @@ test(explain_explanation_to_json_abspath_type,
% type_error(list,Details) if the detail messages of the explanation is no list.
test(explain_explanation_to_json_details_type,
[
forall(member(OtherTypeValue, [1, "test", test, 7.3, some(term)])),
forall(type_not_list(OtherTypeValue)),
error(type_error(list,OtherTypeValue))
]) :-
AbsPath = "some_path",
......@@ -904,4 +744,4 @@ test(explain_explanation_to_json_bound,
% no further tests are required.
test(explain_explanation_to_json_further_errors) :- true.
:- end_tests(web_api_expl_integration).
:- end_tests('web_api -> explanations').
:- begin_tests(web_api_helpers).
:- use_module(web_api).
%%
%% text_so_string/2
%%
/**************************************
* *
* web_api -> irrelevance integration *
* *
**************************************/
:- begin_tests('web_api -> helpers').
/********************
* text_so_string/2 *
********************/
% text_to_string(Text, String) succeeds with correct
% result if Text is a string
......@@ -83,4 +90,4 @@ test(text_to_string_type,
]) :-
web_api:text_to_string(Text,_String).
:- end_tests(web_api_helpers).
:- end_tests('web_api -> helpers').
/**************************************
* *
* web_api -> irrelevance integration *
* *
**************************************/
:- dynamic user:irrelevant/1.
:- begin_tests('web_api -> irrelevance').
/*********
* mocks *
*********/
setup_irrelevance_mocks :-
assertz(user:irrelevant('some_path')),
assertz(user:irrelevant('/yet/another/pa.th')).
cleanup_irrelevance_mocks :-
retractall(user:irrelevant('some_path')),
retractall(user:irrelevant('/yet/another/pa.th')).
setup_irrelevance_throws(Error) :-
asserta((user:irrelevant(_) :- throw(Error))).
cleanup_irrelevance_throws :-
retractall(user:irrelevant(_)).
/*******************************
* do_handle_irrelevant_file/2 *
*******************************/
% do_handle_irrelevant_file(Dict, Path) succeeds with correct path
% if Dict contains only the key abs_path with the Path of an
% irrelevant file as atom.
test(do_handle_irrelevant_file_happy,
[
forall(member(Path,['some_path', '/yet/another/pa.th'])),
setup(setup_irrelevance_mocks),
cleanup(cleanup_irrelevance_mocks)
]) :-
web_api:do_handle_irrelevant_file(_{abs_path:Path},Path).
% do_handle_irrelevant_file(Dict, Path) fails if Dict contains only
% the key abs_path with the Path of a relevant file as atom.
test(do_handle_irrelevant_file_fail,
[
forall(member(Path,['another_path', '/some/other/path'])),
fail
]) :-
web_api:do_handle_irrelevant_file(_{abs_path:Path},_).
% do_handle_irrelevant_file(Dict, Path) throws error(type_error(dict, Dict),_)
% if Dict is no dict. Takes precedence over other errors.
test(do_handle_irrelevant_file_nodict,
[
forall(type_not_dict(OtherTypeValue)),
error(type_error(dict, OtherTypeValue))
]) :-
web_api:do_handle_irrelevant_file(OtherTypeValue,_).
test(do_handle_irrelevant_file_type,
[
forall(type_not_dict(OtherTypeValue)),
error(type_error(dict, OtherTypeValue)),
setup(setup_irrelevance_throws(some_error)),
cleanup(cleanup_irrelevance_throws)
]) :-
web_api:do_handle_irrelevant_file(OtherTypeValue,_).
% do_handle_irrelevant_file(Dict, Path) throws
% error(existence_error(key, abs_path, Dict),_) if Dict does not
% contain the key abs_path. Takes precendence over unknown_key
% and implementation_error.
test(do_handle_irrelevant_file_missingkey,
[
forall(member(Dict,[t{},t{another_key:some_atom}])),
error(existence_error(key, abs_path, Dict))
]) :-
web_api:do_handle_irrelevant_file(Dict,_).
test(do_handle_irrelevant_file_missingkey,
[
forall(member(Dict,[t{},t{another_key:some_atom}])),
setup(setup_irrelevance_throws(some_error)),
cleanup(cleanup_irrelevance_throws),
error(existence_error(key, abs_path, Dict))
]) :-
web_api:do_handle_irrelevant_file(Dict,_).
% do_handle_irrelevant_file(Dict, Path) throws error(instantiation_error,_)
% if the dict value under abs_path is unbound. Takes precedence over type_error,
% unknown_key, and implementation_error.
test(do_handle_irrelevant_file_instantiation,
[
forall(member(Dict,[t{abs_path:_},t{abs_path:_,another_key:some_atom}])),
error(instantiation_error)
]) :-
web_api:do_handle_irrelevant_file(Dict,_).
test(do_handle_irrelevant_file_instantiation,
[
forall(member(Dict,[t{abs_path:_},t{abs_path:_,another_key:some_atom}])),
setup(setup_irrelevance_throws(some_error)),
cleanup(cleanup_irrelevance_throws),
error(instantiation_error)
]) :-
web_api:do_handle_irrelevant_file(Dict,_).
% do_handle_irrelevant_file(Dict, Path) throws error(type_error(atom, AbsPath),_)
% if the dict value under abs_path is not an atom. Takes precedence over
% unknown_key and implementation_error.
test(do_handle_irrelevant_file_type,
[
forall(
(
type_not_atom(OtherTypeValue),
(Dict=t{abs_path:OtherTypeValue}; Dict=t{abs_path:OtherTypeValue,another_key:some_atom})
)
),
error(type_error(atom, OtherTypeValue))
]) :-
web_api:do_handle_irrelevant_file(Dict,_).
test(do_handle_irrelevant_file_type,
[
forall(
(
member(OtherTypeValue, [1, "test", 7.3, some(term)]),
(Dict=t{abs_path:OtherTypeValue}; Dict=t{abs_path:OtherTypeValue,another_key:some_atom})
)
),
setup(setup_irrelevance_throws(some_error)),
cleanup(cleanup_irrelevance_throws),
error(type_error(atom, OtherTypeValue))
]) :-
web_api:do_handle_irrelevant_file(Dict,_).
% do_handle_irrelevant_file(Dict, Path) throws error(unknown_key(KeyName, Dict),_)
% if the dict contains any other key than abs_path. Takes precedence over implementation_error.
test(do_handle_irrelevant_file_unknown,
[
error(unknown_key(another_key, t{abs_path:some_atom,another_key:another_atom}))
]) :-
web_api:do_handle_irrelevant_file(t{abs_path:some_atom,another_key:another_atom},_).
test(do_handle_irrelevant_file_unknown,
[
error(unknown_key(another_key, t{abs_path:some_atom,another_key:another_atom})),
setup(setup_irrelevance_throws(some_error)),
cleanup(cleanup_irrelevance_throws)
]) :-
web_api:do_handle_irrelevant_file(t{abs_path:some_atom,another_key:another_atom},_).
% do_handle_irrelevant_file(Dict, Path) throws error(implementation_error(Cause),_)
% if checking the irrelevance itself throws Cause.
test(do_handle_irrelevant_file_implementation,
[ forall(member(Error,[some_error,"error text",a(describing,term)])),
error(implementation_error(Error)),
setup(setup_irrelevance_throws(Error)),
cleanup(cleanup_irrelevance_throws)
]) :-
web_api:do_handle_irrelevant_file(t{abs_path:some_atom},_).
:- end_tests('web_api -> irrelevance').
......@@ -267,8 +267,9 @@ explain_entity_to_json(Entity,JSON) :-
% @error implementation_error(Cause) if generating the explanation itself throws
% an exception
do_handle_explain(Parameters, Result, More) :-
AbsPath = Parameters.abs_path, % extract absolute path; might throw
% type_error(dict, Parameters) or
must_be(dict, Parameters), % might throw type_error(dict, Parameters)
% or instantiation_error
AbsPath = Parameters.abs_path, % extract absolute path; or
% existence_error(key, abs_path, Parameters)
must_be(atom, AbsPath), % might throw instantiation_error or
% type_error(atom, AbsPath)
......@@ -362,6 +363,8 @@ handle_irrelevant(file,Req) :-
% @error unknown_key(KeyName, Dict) if the dict contains any KeyName which is not abs_path
% @error implementation_error(Cause) if checking the irrelevance itself throws an error (Cause)
do_handle_irrelevant_file(Parameters,AbsPath) :-
must_be(dict,Parameters), % might throw type_error(dict, Parameters)
% or instantiation_error
AbsPath = Parameters.abs_path,
must_be(atom,AbsPath),
( (get_dict(Key,Parameters,_), Key\= abs_path )
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment