1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.collections4.comparators;
18
19 import static org.junit.jupiter.api.Assertions.assertEquals;
20 import static org.junit.jupiter.api.Assertions.assertFalse;
21 import static org.junit.jupiter.api.Assertions.assertThrows;
22 import static org.junit.jupiter.api.Assertions.assertTrue;
23
24 import java.util.Arrays;
25 import java.util.Comparator;
26 import java.util.LinkedList;
27 import java.util.List;
28 import java.util.Random;
29
30 import org.apache.commons.lang3.ArrayUtils;
31 import org.junit.jupiter.api.Nested;
32 import org.junit.jupiter.api.Test;
33
34
35
36
37 public class FixedOrderComparatorTest extends AbstractComparatorTest<String> {
38
39 @Nested
40 class Equals {
41
42 @Test
43 void expectFalseWhenBothComparatorsWithDifferentItems() {
44 final FixedOrderComparator<Integer> comparator1 = new FixedOrderComparator<>(1, 2, 3);
45 final FixedOrderComparator<Integer> comparator2 = new FixedOrderComparator<>(2, 3, 4);
46 assertFalse(comparator1.equals(comparator2));
47 }
48
49 @Test
50 void expectFalseWhenBothComparatorsWithDifferentUnknownObjectBehavior() {
51 final FixedOrderComparator<Integer> comparator1 = new FixedOrderComparator<>();
52 comparator1.setUnknownObjectBehavior(FixedOrderComparator.UnknownObjectBehavior.BEFORE);
53 final FixedOrderComparator<Integer> comparator2 = new FixedOrderComparator<>();
54 comparator2.setUnknownObjectBehavior(FixedOrderComparator.UnknownObjectBehavior.AFTER);
55 assertFalse(comparator1.equals(comparator2));
56 }
57
58 @Test
59 void expectFalseWhenFixedOrderComparatorIsComparedWithNull() {
60 final FixedOrderComparator<Integer> comparator = new FixedOrderComparator<>();
61 assertFalse(comparator.equals(null));
62 }
63
64 @Test
65 void expectFalseWhenFixedOrderComparatorIsComparedWithOtherObject() {
66 final FixedOrderComparator<Integer> comparator = new FixedOrderComparator<>();
67 assertFalse(comparator.equals(new Object()));
68 }
69
70 @Test
71 void expectFalseWhenOneComparatorIsLocked() {
72 final FixedOrderComparator<Integer> comparator1 = new FixedOrderComparator<>(1, 2, 3);
73 final FixedOrderComparator<Integer> comparator2 = new FixedOrderComparator<>(1, 2, 3);
74 comparator2.compare(1, 2);
75 assertFalse(comparator1.equals(comparator2));
76 }
77
78 @Test
79 void expectFalseWhenOneComparatorsWithDuplicateItems() {
80 final FixedOrderComparator<Integer> comparator1 = new FixedOrderComparator<>(1, 2, 3);
81 final FixedOrderComparator<Integer> comparator2 = new FixedOrderComparator<>(1, 2, 3, 3);
82 assertFalse(comparator1.equals(comparator2));
83 }
84
85 @Test
86 void expectTrueWhenBothComparatorsAreLocked() {
87 final FixedOrderComparator<Integer> comparator1 = new FixedOrderComparator<>(1, 2, 3);
88 final FixedOrderComparator<Integer> comparator2 = new FixedOrderComparator<>(1, 2, 3);
89 comparator1.compare(1, 2);
90 comparator2.compare(1, 2);
91 assertTrue(comparator1.equals(comparator2));
92 }
93
94 @Test
95 void expectTrueWhenBothComparatorsWithoutAnyItems() {
96 final FixedOrderComparator<Integer> comparator1 = new FixedOrderComparator<>();
97 final FixedOrderComparator<Integer> comparator2 = new FixedOrderComparator<>();
98 assertTrue(comparator1.equals(comparator2));
99 }
100
101 @Test
102 void expectTrueWhenBothObjectsAreSame() {
103 final FixedOrderComparator<Integer> comparator = new FixedOrderComparator<>();
104 assertTrue(comparator.equals(comparator));
105 }
106 }
107
108
109
110
111
112
113
114
115 private static final String[] topCities = {
116 "Tokyo",
117 "Mexico City",
118 "Mumbai",
119 "Sao Paulo",
120 "New York",
121 "Shanghai",
122 "Lagos",
123 "Los Angeles",
124 "Calcutta",
125 "Buenos Aires"
126 };
127
128
129
130
131 private void assertComparatorYieldsOrder(final String[] orderedObjects, final Comparator<String> comparator) {
132 final String[] keys = orderedObjects.clone();
133
134
135
136
137 boolean isInNewOrder = false;
138 final Random rand = new Random();
139 while (keys.length > 1 && !isInNewOrder) {
140
141 for (int i = keys.length - 1; i > 0; i--) {
142 final String swap = keys[i];
143 final int j = rand.nextInt(i + 1);
144 keys[i] = keys[j];
145 keys[j] = swap;
146 }
147
148
149 for (int i = 0; i < keys.length; i++) {
150 if (!orderedObjects[i].equals(keys[i])) {
151 isInNewOrder = true;
152 break;
153 }
154 }
155 }
156
157
158
159 Arrays.sort(keys, comparator);
160
161 for (int i = 0; i < orderedObjects.length; i++) {
162 assertEquals(orderedObjects[i], keys[i]);
163 }
164 }
165
166 @Override
167 public List<String> getComparableObjectsOrdered() {
168 return Arrays.asList(topCities);
169 }
170
171
172
173
174
175
176
177
178
179 @Override
180 public String getCompatibilityVersion() {
181 return "4";
182 }
183
184 @Override
185 public Comparator<String> makeObject() {
186 return new FixedOrderComparator<>(topCities);
187 }
188
189
190
191
192 @Test
193 public void testAddAsEqual() {
194 final FixedOrderComparator<String> comparator = new FixedOrderComparator<>(topCities);
195 comparator.addAsEqual("New York", "Minneapolis");
196 assertEquals(0, comparator.compare("New York", "Minneapolis"));
197 assertEquals(-1, comparator.compare("Tokyo", "Minneapolis"));
198 assertEquals(1, comparator.compare("Shanghai", "Minneapolis"));
199 }
200
201
202
203
204 @Test
205 public void testArrayConstructor() {
206 final String[] keys = topCities.clone();
207 final String[] topCitiesForTest = topCities.clone();
208 final FixedOrderComparator<String> comparator = new FixedOrderComparator<>(topCitiesForTest);
209 assertComparatorYieldsOrder(keys, comparator);
210
211 topCitiesForTest[0] = "Brighton";
212 assertComparatorYieldsOrder(keys, comparator);
213 }
214
215
216
217
218 @Test
219 public void testConstructorPlusAdd() {
220 final FixedOrderComparator<String> comparator = new FixedOrderComparator<>();
221 for (final String topCity : topCities) {
222 comparator.add(topCity);
223 }
224 final String[] keys = topCities.clone();
225 assertComparatorYieldsOrder(keys, comparator);
226 }
227
228
229
230
231 @Test
232 public void testListConstructor() {
233 final String[] keys = topCities.clone();
234 final List<String> topCitiesForTest = new LinkedList<>(Arrays.asList(topCities));
235 final FixedOrderComparator<String> comparator = new FixedOrderComparator<>(topCitiesForTest);
236 assertComparatorYieldsOrder(keys, comparator);
237
238 topCitiesForTest.set(0, "Brighton");
239 assertComparatorYieldsOrder(keys, comparator);
240 }
241
242
243
244
245
246
247
248
249 @Test
250 public void testLock() {
251 final FixedOrderComparator<String> comparator = new FixedOrderComparator<>(topCities);
252 assertFalse(comparator.isLocked());
253 comparator.compare("New York", "Tokyo");
254 assertTrue(comparator.isLocked());
255
256 assertThrows(UnsupportedOperationException.class, () -> comparator.add("Minneapolis"),
257 "Should have thrown an UnsupportedOperationException");
258
259 assertThrows(UnsupportedOperationException.class, () -> comparator.addAsEqual("New York", "Minneapolis"),
260 "Should have thrown an UnsupportedOperationException");
261 }
262
263 @Test
264 public void testUnknownObjectBehavior() {
265 FixedOrderComparator<String> comparator = new FixedOrderComparator<>(topCities);
266
267 final FixedOrderComparator<String> finalComparator = comparator;
268 assertThrows(IllegalArgumentException.class, () -> finalComparator.compare("New York", "Minneapolis"),
269 "Should have thrown a IllegalArgumentException");
270
271 assertThrows(IllegalArgumentException.class, () -> finalComparator.compare("Minneapolis", "New York"),
272 "Should have thrown a IllegalArgumentException");
273
274 assertEquals(FixedOrderComparator.UnknownObjectBehavior.EXCEPTION, comparator.getUnknownObjectBehavior());
275
276 comparator = new FixedOrderComparator<>(topCities);
277 comparator.setUnknownObjectBehavior(FixedOrderComparator.UnknownObjectBehavior.BEFORE);
278 assertEquals(FixedOrderComparator.UnknownObjectBehavior.BEFORE, comparator.getUnknownObjectBehavior());
279 LinkedList<String> keys = new LinkedList<>(Arrays.asList(topCities));
280 keys.addFirst("Minneapolis");
281 assertComparatorYieldsOrder(keys.toArray(ArrayUtils.EMPTY_STRING_ARRAY), comparator);
282
283 assertEquals(-1, comparator.compare("Minneapolis", "New York"));
284 assertEquals(1, comparator.compare("New York", "Minneapolis"));
285 assertEquals(0, comparator.compare("Minneapolis", "St Paul"));
286
287 comparator = new FixedOrderComparator<>(topCities);
288 comparator.setUnknownObjectBehavior(FixedOrderComparator.UnknownObjectBehavior.AFTER);
289 keys = new LinkedList<>(Arrays.asList(topCities));
290 keys.add("Minneapolis");
291 assertComparatorYieldsOrder(keys.toArray(ArrayUtils.EMPTY_STRING_ARRAY), comparator);
292
293 assertEquals(1, comparator.compare("Minneapolis", "New York"));
294 assertEquals(-1, comparator.compare("New York", "Minneapolis"));
295 assertEquals(0, comparator.compare("Minneapolis", "St Paul"));
296 }
297 }