1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package de.smartics.util.test.theories;
17
18 import static org.hamcrest.CoreMatchers.equalTo;
19 import static org.hamcrest.CoreMatchers.is;
20 import static org.hamcrest.CoreMatchers.not;
21 import static org.junit.Assert.assertThat;
22 import static org.junit.Assume.assumeThat;
23
24 import org.junit.Assert;
25 import org.junit.experimental.theories.Theories;
26 import org.junit.experimental.theories.Theory;
27 import org.junit.runner.RunWith;
28
29
30
31
32
33
34
35
36
37 @RunWith(Theories.class)
38 public abstract class CompareToTheory<T extends Comparable<T>>
39
40 {
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55 private static void assumeThatValueIsNotNull(final Object uut)
56 {
57 assumeThat(uut, is(not(equalTo(null))));
58 }
59
60
61
62
63
64
65
66
67
68
69
70
71 protected boolean checkConsistentWithEquals()
72 {
73 return true;
74 }
75
76
77
78 private static <T extends Comparable<T>> String thrownMessage(
79 final String prefix, final TestAtom<T> atom1, final TestAtom<T> atom2)
80 {
81 final StringBuilder buffer = new StringBuilder(64);
82 buffer.append(prefix).append(" did not throw an exception, while ");
83 appendMessage(buffer, atom1.label, atom1.e);
84 buffer.append(" and");
85 appendMessage(buffer, atom2.label, atom2.e);
86 return buffer.toString();
87 }
88
89 private static void appendMessage(final StringBuilder buffer,
90 final String label, final Exception thrownException)
91 {
92 buffer.append(label).append(" did ")
93 .append(thrownException == null ? "not " : "");
94 }
95
96 private static boolean noExceptionThrown(final TestAtom<?>... atoms)
97 {
98 for (final TestAtom<?> e : atoms)
99 {
100 if (e.isExceptionThrown())
101 {
102 return false;
103 }
104 }
105 return true;
106 }
107
108
109
110
111
112
113
114 private static final class TestAtom<T extends Comparable<T>>
115 {
116
117
118
119 private final String label;
120
121
122
123
124 private int value;
125
126
127
128
129 private Exception e;
130
131 private TestAtom(final String label, final T uutX, final T uutY)
132 {
133 this.label = label;
134 try
135 {
136 this.value = uutX.compareTo(uutY);
137 }
138 catch (final Exception e)
139 {
140 this.e = e;
141 }
142 }
143
144 private boolean isExceptionThrown()
145 {
146 return e != null;
147 }
148 }
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168 @Theory
169 public void compareToIsSymmetric(final T uutX, final T uutY)
170
171 {
172 assumeThatValueIsNotNull(uutX);
173 assumeThatValueIsNotNull(uutY);
174
175 final TestAtom<T> xToY = new TestAtom<T>("X", uutX, uutY);
176 final TestAtom<T> yToX = new TestAtom<T>("Y", uutY, uutX);
177
178 if (noExceptionThrown(xToY, yToX))
179 {
180 assertThat(xToY.value == -yToX.value, is(true));
181 }
182 else if (xToY.e != null)
183 {
184 assertThat("Only X threw an exception.", yToX.e, is(not(equalTo(null))));
185 }
186 else
187 {
188 Assert.fail("Only Y threw an exception.");
189 }
190 }
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215 @Theory
216 public final void compareToIsTransitive(final T uutX, final T uutY,
217 final T uutZ)
218 {
219 assumeThatValueIsNotNull(uutX);
220 assumeThatValueIsNotNull(uutY);
221
222 final TestAtom<T> xToY = new TestAtom<T>("X", uutX, uutY);
223 final TestAtom<T> yToZ = new TestAtom<T>("Y", uutY, uutZ);
224 final TestAtom<T> xToZ = new TestAtom<T>("Z", uutX, uutZ);
225
226 if (noExceptionThrown(xToY, yToZ, xToZ))
227 {
228 assumeThat(xToY.value > 0 && yToZ.value > 0, is(equalTo(true)));
229 assertThat(xToZ.value > 0, is(equalTo(true)));
230 }
231 else
232 {
233 assertThat(thrownMessage("X", yToZ, xToZ), xToY, is(not(equalTo(null))));
234 assertThat(thrownMessage("Y", xToY, xToZ), yToZ, is(not(equalTo(null))));
235 assertThat(thrownMessage("Z", xToY, yToZ), xToZ, is(not(equalTo(null))));
236 }
237 }
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257 @Theory
258 public final void compareToIsConsistentToEquals(final T uutX, final T uutY)
259 {
260 if (checkConsistentWithEquals())
261 {
262 assumeThatValueIsNotNull(uutX);
263
264 final TestAtom<T> xToY = new TestAtom<T>("X", uutX, uutY);
265
266 assumeThat(xToY.isExceptionThrown(), is(equalTo(false)));
267 assumeThat(xToY.value, is(equalTo(0)));
268
269 assertThat(uutX.equals(uutY), is(equalTo(true)));
270 }
271 }
272 }