OSDN Git Service

a126104a32a0a79ed8d2bb41d0691d4ff24a6351
[transunit/transunit.git] / transunit.compare_test.m
1 % Copyright (C) 2019 Alaskan Emily, Transnat Games.
2 %
3 % This software is provided 'as-is', without any express or implied warranty.
4 % In no event will the authors be held liable for any damages arising from
5 % the use of this software.
6 %
7 % Permission is granted to anyone to use this software for any purpose,
8 % including commercial applications, and to alter it and redistribute it
9 % freely, subject to the following restrictions:
10 %
11 %   1. The origin of this software must not be misrepresented; you must not
12 %      claim that you wrote the original software. If you use this software
13 %      in a product, an acknowledgment in the product documentation would be
14 %      appreciated but is not required.
15 %
16 %   2. Altered source versions must be plainly marked as such, and must not
17 %      be misrepresented as being the original software.
18 %
19 %   3. This notice may not be removed or altered from any source distribution.
20 %
21
22 :- module transunit.compare_test.
23
24 %=============================================================================%
25 % Implements test preds where the result is compared to an expected result.
26 :- interface.
27 %=============================================================================%
28
29 :- use_module maybe.
30 :- use_module io.
31
32 %-----------------------------------------------------------------------------%
33 % NOTE: this runner does NOT catch exceptions!
34 :- pred run_test(pred(A, B), A, B, maybe.maybe_error)
35     <= compare(B).
36 :- mode run_test(pred(in, out) is det, in, in, out) is det.
37 :- mode run_test(pred(di, out) is det, di, in, out) is det.
38 :- mode run_test(pred(in, out) is cc_multi, in, in, out) is det.
39 :- mode run_test(pred(di, out) is cc_multi, di, in, out) is det.
40 :- mode run_test(pred(in, out) is semidet, in, in, out) is det.
41 :- mode run_test(pred(mdi, out) is semidet, mdi, in, out) is det.
42 :- mode run_test(pred(in, out) is cc_nondet, in, in, out) is det.
43 :- mode run_test(pred(mdi, out) is cc_nondet, mdi, in, out) is det.
44
45 %-----------------------------------------------------------------------------%
46
47 :- pred run_test(pred(A, B, State, State), A, B, maybe.maybe_error, State, State)
48     <= compare(B).
49 :- mode run_test(pred(in, out, di, uo) is det, in, in, out, di, uo) is det.
50 :- mode run_test(pred(in, out, in, out) is det, in, in, out, in, out) is det.
51 :- mode run_test(pred(di, out, di, uo) is det, di, in, out, di, uo) is det.
52 :- mode run_test(pred(di, out, in, out) is det, di, in, out, in, out) is det.
53 :- mode run_test(pred(in, out, di, uo) is cc_multi, in, in, out, di, uo) is det.
54 :- mode run_test(pred(in, out, in, out) is cc_multi, in, in, out, in, out) is det.
55 :- mode run_test(pred(di, out, di, uo) is cc_multi, di, in, out, di, uo) is det.
56 :- mode run_test(pred(di, out, in, out) is cc_multi, di, in, out, in, out) is det.
57
58 %-----------------------------------------------------------------------------%
59
60 :- pred run_test(pred(T, State, State), T, maybe.maybe_error, State, State)
61     <= compare(T).
62 :- mode run_test(pred(out, di, uo) is det, in, out, di, uo) is det.
63 :- mode run_test(pred(out, in, out) is det, in, out, in, out) is det.
64 :- mode run_test(pred(out, di, uo) is cc_multi, in, out, di, uo) is det.
65 :- mode run_test(pred(out, in, out) is cc_multi, in, out, in, out) is det.
66
67 %-----------------------------------------------------------------------------%
68 % Tests a pred that results in an io.res. If the result is io.error, then that
69 % error is transformed into the maybe_error result using io.error_message.
70 % If the result is io.ok, the value is tested against the expected result as
71 % usual. 
72 :- pred run_io_test(pred(A, io.res(B), State, State), A, B, maybe.maybe_error, State, State)
73     <= compare(B).
74 :- mode run_io_test(pred(in, out, di, uo) is det, in, in, out, di, uo) is det.
75 :- mode run_io_test(pred(di, out, di, uo) is det, di, in, out, di, uo) is det.
76
77 %-----------------------------------------------------------------------------%
78 % Similar to run_test/6, but supports semidet inputs.
79 :- pred run_backtrack_test(pred(A, B, State, State), A, B, maybe.maybe_error, State, State)
80     <= compare(B).
81 :- mode run_backtrack_test(pred(in, out, in, out) is semidet, in, in, out, in, out) is det.
82 :- mode run_backtrack_test(pred(in, out, mdi, muo) is semidet, in, in, out, mdi, muo) is det.
83 :- mode run_backtrack_test(pred(mdi, out, in, out) is semidet, mdi, in, out, in, out) is det.
84 :- mode run_backtrack_test(pred(mdi, out, mdi, muo) is semidet, mdi, in, out, mdi, muo) is det.
85 :- mode run_backtrack_test(pred(in, out, in, out) is cc_nondet, in, in, out, in, out) is det.
86 :- mode run_backtrack_test(pred(in, out, mdi, muo) is cc_nondet, in, in, out, mdi, muo) is det.
87 :- mode run_backtrack_test(pred(mdi, out, in, out) is cc_nondet, mdi, in, out, in, out) is det.
88 :- mode run_backtrack_test(pred(mdi, out, mdi, muo) is cc_nondet, mdi, in, out, mdi, muo) is det.
89
90 :- pred run_backtrack_test(pred(T, State, State), T, maybe.maybe_error, State, State)
91     <= compare(T).
92 :- mode run_backtrack_test(pred(out, in, out) is semidet, in, out, in, out) is det.
93 :- mode run_backtrack_test(pred(out, mdi, muo) is semidet, in, out, mdi, muo) is det.
94 :- mode run_backtrack_test(pred(out, in, out) is cc_nondet, in, out, in, out) is det.
95 :- mode run_backtrack_test(pred(out, mdi, muo) is cc_nondet, in, out, mdi, muo) is det.
96
97 %=============================================================================%
98 :- implementation.
99 %=============================================================================%
100
101 %-----------------------------------------------------------------------------%
102
103 run_test(Pred, In, Out, Result) :-
104     ( if
105         promise_equivalent_solutions [Mid] (
106             Pred(In, Mid)
107         )
108     then
109         compare(Mid, Out) = Result
110     else
111         Result = maybe.error("Pred failed")
112     ).
113
114 %-----------------------------------------------------------------------------%
115
116 run_test(Pred, In, Out, compare(Mid, Out), !State) :-
117     promise_equivalent_solutions [!:State, Mid] (
118         Pred(In, Mid, !State)
119     ).
120
121 %-----------------------------------------------------------------------------%
122
123 run_test(Pred, Out, compare(Mid, Out), !State) :-
124     promise_equivalent_solutions [!:State, Mid] (
125         Pred(Mid, !State)
126     ).
127
128 %-----------------------------------------------------------------------------%
129
130 run_io_test(Pred, In, Out, Result, !IO) :-
131     Pred(In, MidResult, !IO),
132     (
133         MidResult = io.error(E),
134         Result = maybe.error(io.error_message(E))
135     ;
136         MidResult = io.ok(Mid),
137         Result = compare(Mid, Out)
138     ).
139
140 %-----------------------------------------------------------------------------%
141
142 run_backtrack_test(Pred, In, Out, Result, StateIn, StateOut) :-
143     ( if
144         promise_equivalent_solutions [Mid, StateMid] (
145             Pred(In, Mid, StateIn, StateMid)
146         )
147     then
148         StateOut = StateMid,
149         compare(Mid, Out) = Result
150     else
151         StateOut = StateIn,
152         Result = maybe.error("Pred failed")
153     ).
154
155 %-----------------------------------------------------------------------------%
156
157 run_backtrack_test(Pred, Out, Result, StateIn, StateOut) :-
158     ( if
159         promise_equivalent_solutions [Mid, StateMid] (
160             Pred(Mid, StateIn, StateMid)
161         )
162     then
163         StateOut = StateMid,
164         compare(Mid, Out) = Result
165     else
166         StateOut = StateIn,
167         Result = maybe.error("Pred failed")
168     ).
169