|
1 | 1 | :- module(reif_tests, []).
|
2 | 2 |
|
3 | 3 | :- use_module(library(reif)).
|
4 |
| - |
5 |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
6 |
| -% Unit tests |
7 |
| - |
8 |
| -% indexing_dif_* tests are just sanity checks – examples from the paper, to |
9 |
| -% make sure I haven't messed up. |
10 |
| -t(true, ( |
11 |
| - indexing_dif_p6_e1 :- |
12 |
| - findall(X-Fs, tfilter(=(X),[1,2,3,2,3,3],Fs), [1-[1], 2-[2,2], 3-[3,3,3], Y-[]]), |
13 |
| - maplist(dif(Y), [1,2,3]) |
| 4 | +:- use_module(library(lists)). |
| 5 | +:- use_module(library(dif)). |
| 6 | +:- use_module(library(loader)). |
| 7 | +:- use_module(test_framework). |
| 8 | + |
| 9 | +% Those tests are just sanity checks – examples from the paper, to make sure |
| 10 | +% I haven't messed up. |
| 11 | +test("indexing dif/2 p6#1", ( |
| 12 | + findall(X-Fs, tfilter(=(X),[1,2,3,2,3,3],Fs), [1-[1], 2-[2,2], 3-[3,3,3], Y-[]]), |
| 13 | + maplist(dif(Y), [1,2,3]) |
14 | 14 | )).
|
15 |
| -t(true, (indexing_dif_p6_e2 :- findall(X, duplicate(X,[1,2,3,2,3,3]), [2,3]))). |
16 |
| -t(true, (indexing_dif_p7_e1 :- firstduplicate(1, [1,2,3,1]))). |
17 |
| -t(true, (indexing_dif_p7_e2 :- firstduplicate(X, [1,2,3,1]), X == 1)). |
18 |
| -t(true, (indexing_dif_p7_e3 :- |
| 15 | +test("indexing dif/2 p6#2", findall(X, duplicate(X,[1,2,3,2,3,3]), [2,3])). |
| 16 | +test("indexing dif/2 p7#1", firstduplicate(1, [1,2,3,1])). |
| 17 | +test("indexing dif/2 p7#2",( |
| 18 | + firstduplicate(X, [1,2,3,1]), |
| 19 | + X == 1 |
| 20 | +)). |
| 21 | +test("indexing dif/2 p7#3", ( |
19 | 22 | findall(Y-A-B-C, firstduplicate(Y,[A,B,C]), [X-X-X-_, X-X-B1-X, X-A2-X-X]),
|
20 | 23 | dif(B1,X),
|
21 | 24 | dif(A2,X)
|
22 | 25 | )).
|
23 | 26 |
|
24 |
| -t(true, (doesnt_modify_free_variables :- user:goal_expanded(A,B), A == B, var(A))). |
25 |
| -t(true, (expands_call1 :- user:goal_expanded(call(a), a))). |
26 |
| -t(true, (expands_call1_for_modules :- user:goal_expanded(call(a:b(1)), a:b(1)))). |
27 |
| -t(true, (expands_call2_for_modules :- user:goal_expanded(call(a:b,c), a:b(c)))). |
28 |
| -t(true, (doesnt_expand_call2 :- user:goal_expanded(call(b,c), call(b,c)))). |
29 |
| -t(true, (doesnt_expand_cyclic_terms :- X=a(X), user:goal_expanded(call(X), Y), call(X) == Y)). |
30 |
| -t(true, (doesnt_expand_cyclic_call1 :- X=call(X), user:goal_expanded(X, Y), X == Y)). |
31 |
| -t(true, (doesnt_expand_higher_order_predicates :- X = maplist(=(1), _), user:goal_expanded(X, Y), X == Y)). |
| 27 | +test("doesnt modify free variables", (reif:goal_expanded(A,B), A == B, var(A))). |
| 28 | +test("expands call/1", reif:goal_expanded(call(a), a)). |
| 29 | +test("expands call/1 for modules", reif:goal_expanded(call(a:b(1)), a:b(1))). |
| 30 | +test("expands call/2 for modules", reif:goal_expanded(call(a:b,c), a:b(c))). |
| 31 | +test("doesn't expand call/2", reif:goal_expanded(call(b,c), call(b,c))). |
| 32 | +test("doesn't expand cyclic terms", ( |
| 33 | + X=a(X), |
| 34 | + reif:goal_expanded(call(X), Y), |
| 35 | + call(X) == Y |
| 36 | +)). |
| 37 | +test("doesn't expand cyclic call/1", ( |
| 38 | + X=call(X), |
| 39 | + reif:goal_expanded(X, Y), |
| 40 | + X == Y |
| 41 | +)). |
| 42 | +test("doesn't expand higher order predicates", ( |
| 43 | + X = maplist(=(1), _), |
| 44 | + reif:goal_expanded(X, Y), |
| 45 | + X == Y |
| 46 | +)). |
32 | 47 |
|
33 | 48 | % This test fails, and I don't know if goal_expanded/2 should be recursive or not,
|
34 | 49 | % and what properties it shall maintain (is idempotence even desirable?).
|
35 |
| -t(skip, (second_expansion_doesnt_modify_goal :- |
36 |
| - findall(G==Gxx, test_expand_goal_twice(G,Gxx), Goals), maplist(call, Goals) |
37 |
| -)). |
| 50 | +%test("second expansion doesnt modify goal", ( |
| 51 | +% findall(G==Gxx, test_expand_goal_twice(G,Gxx), Goals), |
| 52 | +% maplist(call, Goals) |
| 53 | +%)). |
38 | 54 |
|
39 |
| -t(true, (ge1(X) :- |
40 |
| - user:goal_expansion(if_(1=2,false,true), X))). |
| 55 | +test("ge1", ( |
| 56 | + loader:goal_expansion(if_(1=2,false,true), reif_tests, _) |
| 57 | +)). |
41 | 58 |
|
42 | 59 | test_expand_goal_twice(G, Gxx) :-
|
43 |
| - test_goal(G), goal_expanded(G,Gx), goal_expanded(Gx, Gxx). |
| 60 | + test_goal(G), |
| 61 | + reif:goal_expanded(G,Gx), |
| 62 | + reif:goal_expanded(Gx, Gxx). |
| 63 | + |
44 | 64 | test_goal(_).
|
45 | 65 | test_goal(call(a)).
|
46 | 66 | test_goal(call(a:b(1))).
|
47 | 67 | test_goal(call(a:b,c)).
|
48 | 68 | test_goal(call(call(a))).
|
49 | 69 | test_goal(call(call(a:b))).
|
50 | 70 |
|
51 |
| - |
52 |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
53 |
| -% Extras from the paper |
54 |
| - |
| 71 | +% Extra predicates from the paper |
55 | 72 | duplicate(X, Xs) :-
|
56 | 73 | tfilter(=(X), Xs, [_,_|_]).
|
57 | 74 |
|
|
67 | 84 | dif(E,F),
|
68 | 85 | tree_non_member(E, L),
|
69 | 86 | tree_non_member(E, R).
|
70 |
| - |
71 |
| - |
72 |
| -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
73 |
| -% Unit test support (probably should be moved to another module) |
74 |
| - |
75 |
| -:- use_module(library(iso_ext)). |
76 |
| -:- use_module(library(lists)). |
77 |
| - |
78 |
| -:- dynamic([t/2]). |
79 |
| - |
80 |
| -%% testall. |
81 |
| -% |
82 |
| -% Fails if at least one test doesn't pass, but still executes all of them no |
83 |
| -% matter what while printing report line for each unit test. |
84 |
| -% |
85 |
| -% Report looks like the following: |
86 |
| -% |
87 |
| -% ``` |
88 |
| -% true:[test_name,...] |
89 |
| -% false:test_name |
90 |
| -% skip:test_name |
91 |
| -% error(ErrorTerm):test_name |
92 |
| -% ``` |
93 |
| -% |
94 |
| -% Test succeeds if it perfroms according to its expected outcome. Test may |
95 |
| -% succeed multiple times. |
96 |
| -% |
97 |
| -% Test definition looks like this: |
98 |
| -% |
99 |
| -% ``` |
100 |
| -% t(ExpectedOutcome, (TestName :- TestBody)). |
101 |
| -% ``` |
102 |
| -% |
103 |
| -% Where: |
104 |
| -% `ExpectedOutcome` is either `true`, `false` or `error(ErrorTerm)` when an exception is expected. |
105 |
| -% `TestName` is a term describing the test (usually an atom) |
106 |
| -% `TestBody` is an actual test case |
107 |
| -% |
108 |
| -% TODO: Write tips for writting tests |
109 |
| -% FIXME: There some quirks when using inside modules, because of (:)/2. |
110 |
| -testall :- findall(C, testsingle(C), Cs), maplist(pass, Cs). |
111 |
| - |
112 |
| -pass(true). |
113 |
| -pass(skip). |
114 |
| - |
115 |
| -%% testsingle(-TestResult). |
116 |
| -% |
117 |
| -% Retrieves unit tests and executes it. Always succeeds. |
118 |
| -testsingle(C) :- |
119 |
| - gettest(D, G), |
120 |
| - asserta(D), |
121 |
| - call_cleanup(runtest(G,C), retract(D)). |
122 |
| - |
123 |
| -%% gettest(-TestPredicate, -TestQuery). |
124 |
| -% |
125 |
| -% Retrieves unit test from the datebase, fails if no tests were found or test |
126 |
| -% definition is incorrect. |
127 |
| -% |
128 |
| -% TODO: Throw exception, don't fail. |
129 |
| -% FIXME: Handle modules correctly |
130 |
| -gettest((H:-B), G) :- t(E, (H:-B)), expectation_goal(E, H, G). |
131 |
| -expectation_goal(true, H, H). |
132 |
| -expectation_goal(false, H, \+reif:H). |
133 |
| -expectation_goal(error(E), H, catch(reif:H, error(E, _), true)). |
134 |
| -expectation_goal(skip, H, true(H)). |
135 |
| -true(_). |
136 |
| - |
137 |
| -%% runtest(+Goal, -ResultCode). |
138 |
| -% |
139 |
| -% Try to collect all solutions and print predicate outcome no matter what. |
140 |
| -% Always succeeds. |
141 |
| -runtest(G, C) :- catch(findall(G,G,S), E, S = x(E)), what_to_print(S, G, C:R), write(C:R), nl. |
142 |
| -what_to_print([], G, false:G). |
143 |
| -what_to_print([true(H)|_], _, skip:H). |
144 |
| -what_to_print([H|T], _, true:[H|T]) :- H \= true(_). |
145 |
| -what_to_print(x(E), G, E:G). |
0 commit comments