1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.commons.lang3;
20
21 import static org.apache.commons.lang3.LangAssertions.assertNullPointerException;
22 import static org.junit.jupiter.api.Assertions.assertEquals;
23 import static org.junit.jupiter.api.Assertions.assertFalse;
24 import static org.junit.jupiter.api.Assertions.assertNotEquals;
25 import static org.junit.jupiter.api.Assertions.assertNotNull;
26 import static org.junit.jupiter.api.Assertions.assertThrows;
27 import static org.junit.jupiter.api.Assertions.assertTrue;
28
29 import java.lang.reflect.Modifier;
30 import java.util.Iterator;
31 import java.util.NoSuchElementException;
32
33 import org.junit.jupiter.api.Test;
34
35
36
37
38 class CharRangeTest extends AbstractLangTest {
39
40 @Test
41 void testClass() {
42
43 assertFalse(Modifier.isPublic(CharRange.class.getModifiers()));
44 assertTrue(Modifier.isFinal(CharRange.class.getModifiers()));
45 }
46
47 @Test
48 void testConstructorAccessors_is() {
49 final CharRange rangea = CharRange.is('a');
50 assertEquals('a', rangea.getStart());
51 assertEquals('a', rangea.getEnd());
52 assertFalse(rangea.isNegated());
53 assertEquals("a", rangea.toString());
54 }
55
56 @Test
57 void testConstructorAccessors_isIn_Normal() {
58 final CharRange rangea = CharRange.isIn('a', 'e');
59 assertEquals('a', rangea.getStart());
60 assertEquals('e', rangea.getEnd());
61 assertFalse(rangea.isNegated());
62 assertEquals("a-e", rangea.toString());
63 }
64
65 @Test
66 void testConstructorAccessors_isIn_Reversed() {
67 final CharRange rangea = CharRange.isIn('e', 'a');
68 assertEquals('a', rangea.getStart());
69 assertEquals('e', rangea.getEnd());
70 assertFalse(rangea.isNegated());
71 assertEquals("a-e", rangea.toString());
72 }
73
74 @Test
75 void testConstructorAccessors_isIn_Same() {
76 final CharRange rangea = CharRange.isIn('a', 'a');
77 assertEquals('a', rangea.getStart());
78 assertEquals('a', rangea.getEnd());
79 assertFalse(rangea.isNegated());
80 assertEquals("a", rangea.toString());
81 }
82
83 @Test
84 void testConstructorAccessors_isNot() {
85 final CharRange rangea = CharRange.isNot('a');
86 assertEquals('a', rangea.getStart());
87 assertEquals('a', rangea.getEnd());
88 assertTrue(rangea.isNegated());
89 assertEquals("^a", rangea.toString());
90 }
91
92 @Test
93 void testConstructorAccessors_isNotIn_Normal() {
94 final CharRange rangea = CharRange.isNotIn('a', 'e');
95 assertEquals('a', rangea.getStart());
96 assertEquals('e', rangea.getEnd());
97 assertTrue(rangea.isNegated());
98 assertEquals("^a-e", rangea.toString());
99 }
100
101 @Test
102 void testConstructorAccessors_isNotIn_Reversed() {
103 final CharRange rangea = CharRange.isNotIn('e', 'a');
104 assertEquals('a', rangea.getStart());
105 assertEquals('e', rangea.getEnd());
106 assertTrue(rangea.isNegated());
107 assertEquals("^a-e", rangea.toString());
108 }
109
110 @Test
111 void testConstructorAccessors_isNotIn_Same() {
112 final CharRange rangea = CharRange.isNotIn('a', 'a');
113 assertEquals('a', rangea.getStart());
114 assertEquals('a', rangea.getEnd());
115 assertTrue(rangea.isNegated());
116 assertEquals("^a", rangea.toString());
117 }
118
119 @Test
120 void testContains_Char() {
121 CharRange range = CharRange.is('c');
122 assertFalse(range.contains('b'));
123 assertTrue(range.contains('c'));
124 assertFalse(range.contains('d'));
125 assertFalse(range.contains('e'));
126
127 range = CharRange.isIn('c', 'd');
128 assertFalse(range.contains('b'));
129 assertTrue(range.contains('c'));
130 assertTrue(range.contains('d'));
131 assertFalse(range.contains('e'));
132
133 range = CharRange.isIn('d', 'c');
134 assertFalse(range.contains('b'));
135 assertTrue(range.contains('c'));
136 assertTrue(range.contains('d'));
137 assertFalse(range.contains('e'));
138
139 range = CharRange.isNotIn('c', 'd');
140 assertTrue(range.contains('b'));
141 assertFalse(range.contains('c'));
142 assertFalse(range.contains('d'));
143 assertTrue(range.contains('e'));
144 assertTrue(range.contains((char) 0));
145 assertTrue(range.contains(Character.MAX_VALUE));
146 }
147
148 @Test
149 void testContains_Charrange() {
150 final CharRange a = CharRange.is('a');
151 final CharRange b = CharRange.is('b');
152 final CharRange c = CharRange.is('c');
153 final CharRange c2 = CharRange.is('c');
154 final CharRange d = CharRange.is('d');
155 final CharRange e = CharRange.is('e');
156 final CharRange cd = CharRange.isIn('c', 'd');
157 final CharRange bd = CharRange.isIn('b', 'd');
158 final CharRange bc = CharRange.isIn('b', 'c');
159 final CharRange ab = CharRange.isIn('a', 'b');
160 final CharRange de = CharRange.isIn('d', 'e');
161 final CharRange ef = CharRange.isIn('e', 'f');
162 final CharRange ae = CharRange.isIn('a', 'e');
163
164
165 assertFalse(c.contains(b));
166 assertTrue(c.contains(c));
167 assertTrue(c.contains(c2));
168 assertFalse(c.contains(d));
169
170 assertFalse(c.contains(cd));
171 assertFalse(c.contains(bd));
172 assertFalse(c.contains(bc));
173 assertFalse(c.contains(ab));
174 assertFalse(c.contains(de));
175
176 assertTrue(cd.contains(c));
177 assertTrue(bd.contains(c));
178 assertTrue(bc.contains(c));
179 assertFalse(ab.contains(c));
180 assertFalse(de.contains(c));
181
182 assertTrue(ae.contains(b));
183 assertTrue(ae.contains(ab));
184 assertTrue(ae.contains(bc));
185 assertTrue(ae.contains(cd));
186 assertTrue(ae.contains(de));
187
188 final CharRange notb = CharRange.isNot('b');
189 final CharRange notc = CharRange.isNot('c');
190 final CharRange notd = CharRange.isNot('d');
191 final CharRange notab = CharRange.isNotIn('a', 'b');
192 final CharRange notbc = CharRange.isNotIn('b', 'c');
193 final CharRange notbd = CharRange.isNotIn('b', 'd');
194 final CharRange notcd = CharRange.isNotIn('c', 'd');
195 final CharRange notde = CharRange.isNotIn('d', 'e');
196 final CharRange notae = CharRange.isNotIn('a', 'e');
197 final CharRange all = CharRange.isIn((char) 0, Character.MAX_VALUE);
198 final CharRange allbutfirst = CharRange.isIn((char) 1, Character.MAX_VALUE);
199
200
201 assertFalse(c.contains(notc));
202 assertFalse(c.contains(notbd));
203 assertTrue(all.contains(notc));
204 assertTrue(all.contains(notbd));
205 assertFalse(allbutfirst.contains(notc));
206 assertFalse(allbutfirst.contains(notbd));
207
208
209 assertTrue(notc.contains(a));
210 assertTrue(notc.contains(b));
211 assertFalse(notc.contains(c));
212 assertTrue(notc.contains(d));
213 assertTrue(notc.contains(e));
214
215 assertTrue(notc.contains(ab));
216 assertFalse(notc.contains(bc));
217 assertFalse(notc.contains(bd));
218 assertFalse(notc.contains(cd));
219 assertTrue(notc.contains(de));
220 assertFalse(notc.contains(ae));
221 assertFalse(notc.contains(all));
222 assertFalse(notc.contains(allbutfirst));
223
224 assertTrue(notbd.contains(a));
225 assertFalse(notbd.contains(b));
226 assertFalse(notbd.contains(c));
227 assertFalse(notbd.contains(d));
228 assertTrue(notbd.contains(e));
229
230 assertTrue(notcd.contains(ab));
231 assertFalse(notcd.contains(bc));
232 assertFalse(notcd.contains(bd));
233 assertFalse(notcd.contains(cd));
234 assertFalse(notcd.contains(de));
235 assertFalse(notcd.contains(ae));
236 assertTrue(notcd.contains(ef));
237 assertFalse(notcd.contains(all));
238 assertFalse(notcd.contains(allbutfirst));
239
240
241 assertFalse(notc.contains(notb));
242 assertTrue(notc.contains(notc));
243 assertFalse(notc.contains(notd));
244
245 assertFalse(notc.contains(notab));
246 assertTrue(notc.contains(notbc));
247 assertTrue(notc.contains(notbd));
248 assertTrue(notc.contains(notcd));
249 assertFalse(notc.contains(notde));
250
251 assertFalse(notbd.contains(notb));
252 assertFalse(notbd.contains(notc));
253 assertFalse(notbd.contains(notd));
254
255 assertFalse(notbd.contains(notab));
256 assertFalse(notbd.contains(notbc));
257 assertTrue(notbd.contains(notbd));
258 assertFalse(notbd.contains(notcd));
259 assertFalse(notbd.contains(notde));
260 assertTrue(notbd.contains(notae));
261 }
262
263 @Test
264 void testContainsNullArg() {
265 final CharRange range = CharRange.is('a');
266 final NullPointerException e = assertNullPointerException(() -> range.contains(null));
267 assertEquals("range", e.getMessage());
268 }
269
270 @Test
271 void testEquals_Object() {
272 final CharRange rangea = CharRange.is('a');
273 final CharRange rangeae = CharRange.isIn('a', 'e');
274 final CharRange rangenotbf = CharRange.isIn('b', 'f');
275
276 assertNotEquals(null, rangea);
277
278 assertEquals(rangea, rangea);
279 assertEquals(rangea, CharRange.is('a'));
280 assertEquals(rangeae, rangeae);
281 assertEquals(rangeae, CharRange.isIn('a', 'e'));
282 assertEquals(rangenotbf, rangenotbf);
283 assertEquals(rangenotbf, CharRange.isIn('b', 'f'));
284
285 assertNotEquals(rangea, rangeae);
286 assertNotEquals(rangea, rangenotbf);
287 assertNotEquals(rangeae, rangea);
288 assertNotEquals(rangeae, rangenotbf);
289 assertNotEquals(rangenotbf, rangea);
290 assertNotEquals(rangenotbf, rangeae);
291 }
292
293 @Test
294 void testHashCode() {
295 final CharRange rangea = CharRange.is('a');
296 final CharRange rangeae = CharRange.isIn('a', 'e');
297 final CharRange rangenotbf = CharRange.isIn('b', 'f');
298
299 assertEquals(rangea.hashCode(), rangea.hashCode());
300 assertEquals(rangea.hashCode(), CharRange.is('a').hashCode());
301 assertEquals(rangeae.hashCode(), rangeae.hashCode());
302 assertEquals(rangeae.hashCode(), CharRange.isIn('a', 'e').hashCode());
303 assertEquals(rangenotbf.hashCode(), rangenotbf.hashCode());
304 assertEquals(rangenotbf.hashCode(), CharRange.isIn('b', 'f').hashCode());
305
306 assertNotEquals(rangea.hashCode(), rangeae.hashCode());
307 assertNotEquals(rangea.hashCode(), rangenotbf.hashCode());
308 assertNotEquals(rangeae.hashCode(), rangea.hashCode());
309 assertNotEquals(rangeae.hashCode(), rangenotbf.hashCode());
310 assertNotEquals(rangenotbf.hashCode(), rangea.hashCode());
311 assertNotEquals(rangenotbf.hashCode(), rangeae.hashCode());
312 }
313
314
315
316
317 @Test
318 void testHashCodeLang1802() {
319
320 final CharRange range1 = CharRange.is('a');
321 final CharRange range2 = CharRange.is('b');
322 final CharRange range3 = CharRange.isIn('a', 'z');
323 final CharRange range4 = CharRange.isIn('b', 'z');
324 final CharRange range5 = CharRange.isNot('a');
325 final CharRange range6 = CharRange.isNotIn('a', 'z');
326 final CharRange range7 = CharRange.isNotIn('b', 'z');
327 final CharRange range8 = CharRange.isIn((char) 1, (char) 2);
328 final CharRange range9 = CharRange.isNotIn((char) 1, (char) 2);
329
330 final CharRange a1 = CharRange.isNotIn((char) 1, (char) 2);
331 final CharRange a2 = CharRange.isIn((char) 2, (char) 2);
332 assertNotEquals(a1, a2, "Different ranges should not be equal");
333 assertNotEquals(a1.hashCode(), a2.hashCode(), "Different ranges should have different hash codes");
334 final CharRange b1 = CharRange.isIn((char) 5, (char) 5);
335 final CharRange b2 = CharRange.isNotIn((char) 4, (char) 5);
336 assertNotEquals(b1, b2, "Different ranges should not be equal");
337 assertNotEquals(b1.hashCode(), b2.hashCode(), "Different ranges should have different hash codes");
338
339 final CharRange normal = CharRange.isIn('x', 'y');
340 final CharRange negated = CharRange.isNotIn('x', 'y');
341 assertNotEquals(normal, negated, "Negated and normal ranges should not be equal");
342 assertNotEquals(normal.hashCode(), negated.hashCode(), "Negated and normal ranges should have different hash codes");
343
344 assertNotEquals(range1.hashCode(), range2.hashCode(), "is('a') vs is('b')");
345 assertNotEquals(range1.hashCode(), range3.hashCode(), "is('a') vs isIn('a', 'z')");
346 assertNotEquals(range3.hashCode(), range4.hashCode(), "isIn('a', 'z') vs isIn('b', 'z')");
347 assertNotEquals(range1.hashCode(), range5.hashCode(), "is('a') vs isNot('a')");
348 assertNotEquals(range3.hashCode(), range6.hashCode(), "isIn('a', 'z') vs isNotIn('a', 'z')");
349 assertNotEquals(range6.hashCode(), range7.hashCode(), "isNotIn('a', 'z') vs isNotIn('b', 'z')");
350 assertNotEquals(range8.hashCode(), range9.hashCode(), "isIn(1, 2) vs isNotIn(1, 2)");
351
352 final CharRange sameAsRange1 = CharRange.is('a');
353 assertEquals(range1, sameAsRange1, "Equal ranges should be equal");
354 assertEquals(range1.hashCode(), sameAsRange1.hashCode(), "Equal ranges should have equal hash codes");
355 }
356
357 @Test
358 void testIterator() {
359 final CharRange a = CharRange.is('a');
360 final CharRange ad = CharRange.isIn('a', 'd');
361 final CharRange nota = CharRange.isNot('a');
362 final CharRange emptySet = CharRange.isNotIn((char) 0, Character.MAX_VALUE);
363 final CharRange notFirst = CharRange.isNotIn((char) 1, Character.MAX_VALUE);
364 final CharRange notLast = CharRange.isNotIn((char) 0, (char) (Character.MAX_VALUE - 1));
365
366 final Iterator<Character> aIt = a.iterator();
367 assertNotNull(aIt);
368 assertTrue(aIt.hasNext());
369 assertEquals(Character.valueOf('a'), aIt.next());
370 assertFalse(aIt.hasNext());
371
372 final Iterator<Character> adIt = ad.iterator();
373 assertNotNull(adIt);
374 assertTrue(adIt.hasNext());
375 assertEquals(Character.valueOf('a'), adIt.next());
376 assertEquals(Character.valueOf('b'), adIt.next());
377 assertEquals(Character.valueOf('c'), adIt.next());
378 assertEquals(Character.valueOf('d'), adIt.next());
379 assertFalse(adIt.hasNext());
380
381 final Iterator<Character> notaIt = nota.iterator();
382 assertNotNull(notaIt);
383 assertTrue(notaIt.hasNext());
384 while (notaIt.hasNext()) {
385 final Character c = notaIt.next();
386 assertNotEquals('a', c.charValue());
387 }
388
389 final Iterator<Character> emptySetIt = emptySet.iterator();
390 assertNotNull(emptySetIt);
391 assertFalse(emptySetIt.hasNext());
392 assertThrows(NoSuchElementException.class, emptySetIt::next);
393
394 final Iterator<Character> notFirstIt = notFirst.iterator();
395 assertNotNull(notFirstIt);
396 assertTrue(notFirstIt.hasNext());
397 assertEquals(Character.valueOf((char) 0), notFirstIt.next());
398 assertFalse(notFirstIt.hasNext());
399 assertThrows(NoSuchElementException.class, notFirstIt::next);
400
401 final Iterator<Character> notLastIt = notLast.iterator();
402 assertNotNull(notLastIt);
403 assertTrue(notLastIt.hasNext());
404 assertEquals(Character.valueOf(Character.MAX_VALUE), notLastIt.next());
405 assertFalse(notLastIt.hasNext());
406 assertThrows(NoSuchElementException.class, notLastIt::next);
407 }
408
409 @Test
410 void testIteratorRemove() {
411 final CharRange a = CharRange.is('a');
412 final Iterator<Character> aIt = a.iterator();
413 assertThrows(UnsupportedOperationException.class, aIt::remove);
414 }
415
416 @Test
417 void testSerialization() {
418 CharRange range = CharRange.is('a');
419 assertEquals(range, SerializationUtils.clone(range));
420 range = CharRange.isIn('a', 'e');
421 assertEquals(range, SerializationUtils.clone(range));
422 range = CharRange.isNotIn('a', 'e');
423 assertEquals(range, SerializationUtils.clone(range));
424 }
425 }