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 user:irrelevant/1.
:- dynamic explanations:explain/4. :- dynamic explanations:explain/4.
%%
%% irrelevance mocks
%%
setup_irrelevance_mocks :-
assertz(user:irrelevant('some_path')),
assertz(user:irrelevant('/yet/another/pa.th')).
cleanup_irrelevance_mocks :- :- begin_tests('web_api -> explanations').
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(_)).
%% /*********
%% explain mocks * mocks *
%% *********/
explain_mock('some_path', 1, explain_mock('some_path', 1,
["this ", "is ", "a ", reference("test",0)], ["this ", "is ", "a ", reference("test",0)],
[ [
...@@ -81,149 +69,11 @@ setup_explain_throws(Error) :- ...@@ -81,149 +69,11 @@ setup_explain_throws(Error) :-
cleanup_explain_throws :- cleanup_explain_throws :-
retractall(explanations:explain(_,_,_,_)). retractall(explanations:explain(_,_,_,_)).
%%
%% do_handle_irrelevant_file/2 /***********************
%% * do_handle_explain/3 *
***********************/
% 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(Dict, Result, More) succeeds with correct result % do_handle_explain(Dict, Result, More) succeeds with correct result
% if Dict contains the key abs_path with the Path of an irrelevant file % if Dict contains the key abs_path with the Path of an irrelevant file
...@@ -282,8 +132,7 @@ test(do_handle_explain_notirrelevant, ...@@ -282,8 +132,7 @@ test(do_handle_explain_notirrelevant,
% if Dict is no dict. Takes precedence over other errors. % if Dict is no dict. Takes precedence over other errors.
test(do_handle_explain_nodict, test(do_handle_explain_nodict,
[ [
forall(member(OtherTypeValue, forall(type_not_dict(OtherTypeValue)),
[1, "test", 7.3, some(term), [abs_path='some_path']])),
setup(setup_explain_throws(some_error)), setup(setup_explain_throws(some_error)),
cleanup(cleanup_explain_throws), cleanup(cleanup_explain_throws),
error(type_error(dict, OtherTypeValue)) error(type_error(dict, OtherTypeValue))
...@@ -340,7 +189,7 @@ test(do_handle_explain_type, ...@@ -340,7 +189,7 @@ test(do_handle_explain_type,
[ [
forall( forall(
( (
member(OtherTypeValue, [1, "test", 7.3, some(term)]), type_not_atom(OtherTypeValue),
(Parameters=t{abs_path:OtherTypeValue}; (Parameters=t{abs_path:OtherTypeValue};
Parameters=t{abs_path:OtherTypeValue, limit:1}; Parameters=t{abs_path:OtherTypeValue, limit:1};
Parameters=t{abs_path:OtherTypeValue, limit:1, Parameters=t{abs_path:OtherTypeValue, limit:1,
...@@ -356,7 +205,7 @@ test(do_handle_explain_type, ...@@ -356,7 +205,7 @@ test(do_handle_explain_type,
[ [
forall( 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, (Parameters=t{abs_path:'some_path', limit:OtherTypeValue}; Parameters=t{abs_path:'some_path', limit:OtherTypeValue,
another_key:some_atom}) another_key:some_atom})
) )
...@@ -398,11 +247,11 @@ test(do_handle_explain_implemention, ...@@ -398,11 +247,11 @@ test(do_handle_explain_implemention,
web_api:do_handle_explain(t{abs_path:'some_path'},_Result,_More). 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. % correct result given a valid input.
test(explain_message_to_json_happy_simple, % simple test(explain_message_to_json_happy_simple, % simple
[ [
...@@ -456,20 +305,20 @@ test(explain_message_to_json_message_type_list, % message no list ...@@ -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 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)) error(type_error(text,OtherTypeValue))
]) :- ]) :-
web_api:explain_message_to_json([OtherTypeValue], _ActualJSON). web_api:explain_message_to_json([OtherTypeValue], _ActualJSON).
test(explain_message_to_json_message_type_referencetext, % reference text no text 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)) error(type_error(text,OtherTypeValue))
]) :- ]) :-
web_api:explain_message_to_json([reference(OtherTypeValue,0)], _ActualJSON). web_api:explain_message_to_json([reference(OtherTypeValue,0)], _ActualJSON).
test(explain_message_to_json_message_type_referenceid, % reference id no integer 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)) error(type_error(integer,OtherTypeValue))
]) :- ]) :-
web_api:explain_message_to_json([reference("text",OtherTypeValue)], web_api:explain_message_to_json([reference("text",OtherTypeValue)],
...@@ -485,9 +334,9 @@ test(explain_message_to_json_uninstantiaton, ...@@ -485,9 +334,9 @@ test(explain_message_to_json_uninstantiaton,
web_api:explain_message_to_json(["some text"], BoundJSON). 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 % explain_references_to_json(References, JSON) succeeds with
% correct result given a valid input. % correct result given a valid input.
...@@ -573,16 +422,14 @@ test(explain_reference_to_json_instantiation, ...@@ -573,16 +422,14 @@ test(explain_reference_to_json_instantiation,
% if References or any part of it is of the wrong type. % if References or any part of it is of the wrong type.
test(explain_reference_to_json_message_type_list, % References no list 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)) error(type_error(list,References))
]) :- ]) :-
web_api:explain_reference_to_json(References, _ActualJSON). web_api:explain_reference_to_json(References, _ActualJSON).
test(explain_reference_to_json_message_type_reference, % reference no ref(_,_) test(explain_reference_to_json_message_type_reference, % reference no ref(_,_)
[ [
forall(member(OtherTypeValue, ["ref", a, 1.0, 7.3, some(term), forall(type_not_term(ref/2,OtherTypeValue)),
["test"], ref(too_few_args),
ref(too, many, args)])),
error(type_error(ref(_,_),OtherTypeValue)) error(type_error(ref(_,_),OtherTypeValue))
]) :- ]) :-
References = [OtherTypeValue], References = [OtherTypeValue],
...@@ -590,7 +437,7 @@ test(explain_reference_to_json_message_type_reference, % reference no ref(_,_) ...@@ -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 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)) error(type_error(integer,OtherTypeValue))
]) :- ]) :-
References = [ref(OtherTypeValue,[entity("some_path","name")])], References = [ref(OtherTypeValue,[entity("some_path","name")])],
...@@ -598,23 +445,21 @@ test(explain_reference_to_json_message_type_id, % id no integer ...@@ -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 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)) error(type_error(list,OtherTypeValue))
]) :- ]) :-
References = [ref(0,OtherTypeValue)], References = [ref(0,OtherTypeValue)],
web_api:explain_reference_to_json(References, _ActualJSON). web_api:explain_reference_to_json(References, _ActualJSON).
test(explain_reference_to_json_message_type_entity, % entity is not entity(_,_) test(explain_reference_to_json_message_type_entity, % entity is not entity(_,_)
[ [
forall(member(OtherTypeValue, [1, 7.3, some(binary,term), forall(type_not_term(entity/2,OtherTypeValue)),
["test"], entity(too_few_args),
entity(too,many, args)])),
error(type_error(entity(_,_),OtherTypeValue)) error(type_error(entity(_,_),OtherTypeValue))
]) :- ]) :-
References = [ref(0,[OtherTypeValue])], References = [ref(0,[OtherTypeValue])],
web_api:explain_reference_to_json(References, _ActualJSON). web_api:explain_reference_to_json(References, _ActualJSON).
test(explain_reference_to_json_message_type_entitypath, % entity path not text 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)) error(type_error(text,OtherTypeValue))
]) :- ]) :-
References = [ref(0,[entity(OtherTypeValue,"name")])], References = [ref(0,[entity(OtherTypeValue,"name")])],
...@@ -622,7 +467,7 @@ test(explain_reference_to_json_message_type_entitypath, % entity path not text ...@@ -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 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)) error(type_error(text,OtherTypeValue))
]) :- ]) :-
References = [ref(0,[entity("some_path",OtherTypeValue)])], References = [ref(0,[entity("some_path",OtherTypeValue)])],
...@@ -651,9 +496,9 @@ test(explain_reference_to_json_uninstantiaton, ...@@ -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 % explain_explanation_to_json(Explanation, JSON) succedes deterministically with
% correct results given valid message input. % correct results given valid message input.
...@@ -711,12 +556,7 @@ test(explain_explanation_to_json_instantiation, ...@@ -711,12 +556,7 @@ test(explain_explanation_to_json_instantiation,
% expected type. % expected type.
test(explain_explanation_to_json_type, test(explain_explanation_to_json_type,
[ [
forall(member(OtherTypeValue, [1, 7.3, some(binary,term), forall(type_not_term(explanation/4,OtherTypeValue)),
["test"],
explanation(one_arg),
explanation(two,args),
explanation(only,three,args),
explanation(way,too,many,arguments,given)])),
error(type_error(explanation(_,_,_,_),OtherTypeValue)) ]) :- error(type_error(explanation(_,_,_,_),OtherTypeValue)) ]) :-
web_api:explain_explanation_to_json(OtherTypeValue, _ActualJSON). web_api:explain_explanation_to_json(OtherTypeValue, _ActualJSON).
...@@ -744,7 +584,7 @@ test(explain_explanation_to_json_abspath_instantiation, ...@@ -744,7 +584,7 @@ test(explain_explanation_to_json_abspath_instantiation,
% no text type. % no text type.
test(explain_explanation_to_json_abspath_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)) error(type_error(text,OtherTypeValue))
]) :- ]) :-
Message = [ "some arbitrary", reference("message",0) ], Message = [ "some arbitrary", reference("message",0) ],
...@@ -764,7 +604,7 @@ test(explain_explanation_to_json_abspath_type, ...@@ -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. % type_error(list,Details) if the detail messages of the explanation is no list.
test(explain_explanation_to_json_details_type, 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)) error(type_error(list,OtherTypeValue))
]) :- ]) :-
AbsPath = "some_path", AbsPath = "some_path",
...@@ -904,4 +744,4 @@ test(explain_explanation_to_json_bound, ...@@ -904,4 +744,4 @@ test(explain_explanation_to_json_bound,
% no further tests are required. % no further tests are required.
test(explain_explanation_to_json_further_errors) :- true. 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). :- 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 % text_to_string(Text, String) succeeds with correct
% result if Text is a string % result if Text is a string
...@@ -83,4 +90,4 @@ test(text_to_string_type, ...@@ -83,4 +90,4 @@ test(text_to_string_type,
]) :- ]) :-
web_api:text_to_string(Text,_String). 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.