View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.commons.lang3;
19  
20  import static org.junit.jupiter.api.Assertions.assertEquals;
21  import static org.junit.jupiter.api.Assertions.assertFalse;
22  import static org.junit.jupiter.api.Assertions.assertNotEquals;
23  import static org.junit.jupiter.api.Assertions.assertNotNull;
24  import static org.junit.jupiter.api.Assertions.assertSame;
25  import static org.junit.jupiter.api.Assertions.assertThrows;
26  import static org.junit.jupiter.api.Assertions.assertTrue;
27  
28  import java.util.Comparator;
29  
30  import org.junit.jupiter.api.BeforeEach;
31  import org.junit.jupiter.api.Test;
32  
33  /**
34   * Tests {@link Range}.
35   */
36  @SuppressWarnings("boxing")
37  public class RangeTest extends AbstractLangTest {
38  
39      abstract static class AbstractComparable implements Comparable<AbstractComparable> {
40          @Override
41          public int compareTo(final AbstractComparable o) {
42              return 0;
43          }
44      }
45      static final class DerivedComparableA extends AbstractComparable {
46          // empty
47      }
48      static final class DerivedComparableB extends AbstractComparable {
49          // empty
50      }
51  
52      private Range<Byte> byteRange;
53      private Range<Byte> byteRange2;
54      private Range<Byte> byteRange3;
55      private Range<Double> doubleRange;
56      private Range<Float> floatRange;
57      private Range<Integer> intRange;
58      private Range<Long> longRange;
59  
60      @BeforeEach
61      public void setUp() {
62          byteRange = Range.of((byte) 0, (byte) 5);
63          byteRange2 = Range.of((byte) 0, (byte) 5);
64          byteRange3 = Range.of((byte) 0, (byte) 10);
65  
66          intRange = Range.of(10, 20);
67          longRange = Range.of(10L, 20L);
68          floatRange = Range.of((float) 10, (float) 20);
69          doubleRange = Range.of((double) 10, (double) 20);
70      }
71  
72      @Test
73      public void testBetweenWithCompare() {
74          // all integers are equal
75          final Comparator<Integer> c = (o1, o2) -> 0;
76          final Comparator<String> lengthComp = Comparator.comparingInt(String::length);
77          Range<Integer> rb = Range.between(-10, 20);
78          assertFalse(rb.contains(null), "should not contain null");
79          assertTrue(rb.contains(10), "should contain 10");
80          assertTrue(rb.contains(-10), "should contain -10");
81          assertFalse(rb.contains(21), "should not contain 21");
82          assertFalse(rb.contains(-11), "should not contain -11");
83          rb = Range.between(-10, 20, c);
84          assertFalse(rb.contains(null), "should not contain null");
85          assertTrue(rb.contains(10), "should contain 10");
86          assertTrue(rb.contains(-10), "should contain -10");
87          assertTrue(rb.contains(21), "should contain 21");
88          assertTrue(rb.contains(-11), "should contain -11");
89          Range<String> rbstr = Range.between("house", "i");
90          assertFalse(rbstr.contains(null), "should not contain null");
91          assertTrue(rbstr.contains("house"), "should contain house");
92          assertTrue(rbstr.contains("i"), "should contain i");
93          assertFalse(rbstr.contains("hose"), "should not contain hose");
94          assertFalse(rbstr.contains("ice"), "should not contain ice");
95          rbstr = Range.between("house", "i", lengthComp);
96          assertFalse(rbstr.contains(null), "should not contain null");
97          assertTrue(rbstr.contains("house"), "should contain house");
98          assertTrue(rbstr.contains("i"), "should contain i");
99          assertFalse(rbstr.contains("houses"), "should not contain houses");
100         assertFalse(rbstr.contains(""), "should not contain ''");
101 
102         assertThrows(NullPointerException.class, () -> Range.between(null, null, lengthComp));
103     }
104 
105     @SuppressWarnings({"rawtypes", "unchecked"})
106     @Test
107     public void testComparableConstructors() {
108         final Comparable c = other -> 1;
109         final Range r1 = Range.is(c);
110         final Range r2 = Range.between(c, c);
111         assertTrue(r1.isNaturalOrdering());
112         assertTrue(r2.isNaturalOrdering());
113     }
114 
115     @Test
116     public void testConstructorSignatureWithAbstractComparableClasses() {
117         final DerivedComparableA derivedComparableA = new DerivedComparableA();
118         final DerivedComparableB derivedComparableB = new DerivedComparableB();
119 
120         final Range<AbstractComparable> mixed = Range.between(derivedComparableA, derivedComparableB, null);
121         assertTrue(mixed.contains(derivedComparableA));
122 
123         final Range<AbstractComparable> same = Range.between(derivedComparableA, derivedComparableA, null);
124         assertTrue(same.contains(derivedComparableA));
125 
126         final Range<DerivedComparableA> rangeA = Range.between(derivedComparableA, derivedComparableA, null);
127         assertTrue(rangeA.contains(derivedComparableA));
128 
129         final Range<DerivedComparableB> rangeB = Range.is(derivedComparableB, null);
130         assertTrue(rangeB.contains(derivedComparableB));
131     }
132 
133     @Test
134     public void testContains() {
135         assertFalse(intRange.contains(null));
136 
137         assertFalse(intRange.contains(5));
138         assertTrue(intRange.contains(10));
139         assertTrue(intRange.contains(15));
140         assertTrue(intRange.contains(20));
141         assertFalse(intRange.contains(25));
142     }
143 
144     @Test
145     public void testContainsRange() {
146 
147         // null handling
148         assertFalse(intRange.containsRange(null));
149 
150         // easy inside range
151         assertTrue(intRange.containsRange(Range.between(12, 18)));
152 
153         // outside range on each side
154         assertFalse(intRange.containsRange(Range.between(32, 45)));
155         assertFalse(intRange.containsRange(Range.between(2, 8)));
156 
157         // equals range
158         assertTrue(intRange.containsRange(Range.between(10, 20)));
159 
160         // overlaps
161         assertFalse(intRange.containsRange(Range.between(9, 14)));
162         assertFalse(intRange.containsRange(Range.between(16, 21)));
163 
164         // touches lower boundary
165         assertTrue(intRange.containsRange(Range.between(10, 19)));
166         assertFalse(intRange.containsRange(Range.between(10, 21)));
167 
168         // touches upper boundary
169         assertTrue(intRange.containsRange(Range.between(11, 20)));
170         assertFalse(intRange.containsRange(Range.between(9, 20)));
171 
172         // negative
173         assertFalse(intRange.containsRange(Range.between(-11, -18)));
174     }
175 
176     @Test
177     public void testElementCompareTo() {
178         assertThrows(NullPointerException.class, () -> intRange.elementCompareTo(null));
179 
180         assertEquals(-1, intRange.elementCompareTo(5));
181         assertEquals(0, intRange.elementCompareTo(10));
182         assertEquals(0, intRange.elementCompareTo(15));
183         assertEquals(0, intRange.elementCompareTo(20));
184         assertEquals(1, intRange.elementCompareTo(25));
185     }
186 
187     @Test
188     public void testEqualsObject() {
189         assertEquals(byteRange, byteRange);
190         assertEquals(byteRange, byteRange2);
191         assertEquals(byteRange2, byteRange2);
192         assertEquals(byteRange, byteRange);
193         assertEquals(byteRange2, byteRange2);
194         assertEquals(byteRange3, byteRange3);
195         assertNotEquals(byteRange2, byteRange3);
196         assertNotEquals(null, byteRange2);
197         assertNotEquals("Ni!", byteRange2);
198     }
199 
200     @Test
201     public void testFit() {
202         assertEquals(intRange.getMinimum(), intRange.fit(Integer.MIN_VALUE));
203         assertEquals(intRange.getMinimum(), intRange.fit(intRange.getMinimum()));
204         assertEquals(intRange.getMaximum(), intRange.fit(Integer.MAX_VALUE));
205         assertEquals(intRange.getMaximum(), intRange.fit(intRange.getMaximum()));
206         assertEquals(15, intRange.fit(15));
207     }
208 
209     @Test
210     public void testFitNull() {
211         assertThrows(NullPointerException.class, () -> {
212             intRange.fit(null);
213         });
214     }
215 
216     @Test
217     public void testGetMaximum() {
218         assertEquals(20, (int) intRange.getMaximum());
219         assertEquals(20L, (long) longRange.getMaximum());
220         assertEquals(20f, floatRange.getMaximum(), 0.00001f);
221         assertEquals(20d, doubleRange.getMaximum(), 0.00001d);
222     }
223 
224     @Test
225     public void testGetMinimum() {
226         assertEquals(10, (int) intRange.getMinimum());
227         assertEquals(10L, (long) longRange.getMinimum());
228         assertEquals(10f, floatRange.getMinimum(), 0.00001f);
229         assertEquals(10d, doubleRange.getMinimum(), 0.00001d);
230     }
231 
232     @Test
233     public void testHashCode() {
234         assertEquals(byteRange.hashCode(), byteRange2.hashCode());
235         assertNotEquals(byteRange.hashCode(), byteRange3.hashCode());
236 
237         assertEquals(intRange.hashCode(), intRange.hashCode());
238         assertTrue(intRange.hashCode() != 0);
239     }
240 
241     @Test
242     public void testIntersectionWith() {
243         assertSame(intRange, intRange.intersectionWith(intRange));
244         assertSame(byteRange, byteRange.intersectionWith(byteRange));
245         assertSame(longRange, longRange.intersectionWith(longRange));
246         assertSame(floatRange, floatRange.intersectionWith(floatRange));
247         assertSame(doubleRange, doubleRange.intersectionWith(doubleRange));
248 
249         assertEquals(Range.between(10, 15), intRange.intersectionWith(Range.between(5, 15)));
250     }
251 
252     @Test
253     public void testIntersectionWithNonOverlapping() {
254         assertThrows(IllegalArgumentException.class, () -> intRange.intersectionWith(Range.between(0, 9)));
255     }
256 
257     @Test
258     public void testIntersectionWithNull() {
259         assertThrows(IllegalArgumentException.class, () -> intRange.intersectionWith(null));
260     }
261 
262     @Test
263     public void testIsAfter() {
264         assertFalse(intRange.isAfter(null));
265 
266         assertTrue(intRange.isAfter(5));
267         assertFalse(intRange.isAfter(10));
268         assertFalse(intRange.isAfter(15));
269         assertFalse(intRange.isAfter(20));
270         assertFalse(intRange.isAfter(25));
271     }
272 
273     @Test
274     public void testIsAfterRange() {
275         assertFalse(intRange.isAfterRange(null));
276 
277         assertTrue(intRange.isAfterRange(Range.between(5, 9)));
278 
279         assertFalse(intRange.isAfterRange(Range.between(5, 10)));
280         assertFalse(intRange.isAfterRange(Range.between(5, 20)));
281         assertFalse(intRange.isAfterRange(Range.between(5, 25)));
282         assertFalse(intRange.isAfterRange(Range.between(15, 25)));
283 
284         assertFalse(intRange.isAfterRange(Range.between(21, 25)));
285 
286         assertFalse(intRange.isAfterRange(Range.between(10, 20)));
287     }
288 
289     @Test
290     public void testIsBefore() {
291         assertFalse(intRange.isBefore(null));
292 
293         assertFalse(intRange.isBefore(5));
294         assertFalse(intRange.isBefore(10));
295         assertFalse(intRange.isBefore(15));
296         assertFalse(intRange.isBefore(20));
297         assertTrue(intRange.isBefore(25));
298     }
299 
300     @Test
301     public void testIsBeforeRange() {
302         assertFalse(intRange.isBeforeRange(null));
303 
304         assertFalse(intRange.isBeforeRange(Range.between(5, 9)));
305 
306         assertFalse(intRange.isBeforeRange(Range.between(5, 10)));
307         assertFalse(intRange.isBeforeRange(Range.between(5, 20)));
308         assertFalse(intRange.isBeforeRange(Range.between(5, 25)));
309         assertFalse(intRange.isBeforeRange(Range.between(15, 25)));
310 
311         assertTrue(intRange.isBeforeRange(Range.between(21, 25)));
312 
313         assertFalse(intRange.isBeforeRange(Range.between(10, 20)));
314     }
315 
316     @Test
317     public void testIsEndedBy() {
318         assertFalse(intRange.isEndedBy(null));
319 
320         assertFalse(intRange.isEndedBy(5));
321         assertFalse(intRange.isEndedBy(10));
322         assertFalse(intRange.isEndedBy(15));
323         assertTrue(intRange.isEndedBy(20));
324         assertFalse(intRange.isEndedBy(25));
325     }
326 
327     @Test
328     public void testIsOverlappedBy() {
329 
330         // null handling
331         assertFalse(intRange.isOverlappedBy(null));
332 
333         // easy inside range
334         assertTrue(intRange.isOverlappedBy(Range.between(12, 18)));
335 
336         // outside range on each side
337         assertFalse(intRange.isOverlappedBy(Range.between(32, 45)));
338         assertFalse(intRange.isOverlappedBy(Range.between(2, 8)));
339 
340         // equals range
341         assertTrue(intRange.isOverlappedBy(Range.between(10, 20)));
342 
343         // overlaps
344         assertTrue(intRange.isOverlappedBy(Range.between(9, 14)));
345         assertTrue(intRange.isOverlappedBy(Range.between(16, 21)));
346 
347         // touches lower boundary
348         assertTrue(intRange.isOverlappedBy(Range.between(10, 19)));
349         assertTrue(intRange.isOverlappedBy(Range.between(10, 21)));
350 
351         // touches upper boundary
352         assertTrue(intRange.isOverlappedBy(Range.between(11, 20)));
353         assertTrue(intRange.isOverlappedBy(Range.between(9, 20)));
354 
355         // negative
356         assertFalse(intRange.isOverlappedBy(Range.between(-11, -18)));
357 
358         // outside range whole range
359         assertTrue(intRange.isOverlappedBy(Range.between(9, 21)));
360 }
361 
362     @Test
363     public void testIsStartedBy() {
364         assertFalse(intRange.isStartedBy(null));
365 
366         assertFalse(intRange.isStartedBy(5));
367         assertTrue(intRange.isStartedBy(10));
368         assertFalse(intRange.isStartedBy(15));
369         assertFalse(intRange.isStartedBy(20));
370         assertFalse(intRange.isStartedBy(25));
371     }
372 
373     @Test
374     public void testIsWithCompare() {
375         // all integers are equal
376         final Comparator<Integer> c = (o1, o2) -> 0;
377         Range<Integer> ri = Range.is(10);
378         assertFalse(ri.contains(null), "should not contain null");
379         assertTrue(ri.contains(10), "should contain 10");
380         assertFalse(ri.contains(11), "should not contain 11");
381         ri = Range.is(10, c);
382         assertFalse(ri.contains(null), "should not contain null");
383         assertTrue(ri.contains(10), "should contain 10");
384         assertTrue(ri.contains(11), "should contain 11");
385     }
386 
387     @Test
388     public void testOfWithCompare() {
389         // all integers are equal
390         final Comparator<Integer> c = (o1, o2) -> 0;
391         final Comparator<String> lengthComp = Comparator.comparingInt(String::length);
392         Range<Integer> rb = Range.of(-10, 20);
393         assertFalse(rb.contains(null), "should not contain null");
394         assertTrue(rb.contains(10), "should contain 10");
395         assertTrue(rb.contains(-10), "should contain -10");
396         assertFalse(rb.contains(21), "should not contain 21");
397         assertFalse(rb.contains(-11), "should not contain -11");
398         rb = Range.of(-10, 20, c);
399         assertFalse(rb.contains(null), "should not contain null");
400         assertTrue(rb.contains(10), "should contain 10");
401         assertTrue(rb.contains(-10), "should contain -10");
402         assertTrue(rb.contains(21), "should contain 21");
403         assertTrue(rb.contains(-11), "should contain -11");
404         Range<String> rbstr = Range.of("house", "i");
405         assertFalse(rbstr.contains(null), "should not contain null");
406         assertTrue(rbstr.contains("house"), "should contain house");
407         assertTrue(rbstr.contains("i"), "should contain i");
408         assertFalse(rbstr.contains("hose"), "should not contain hose");
409         assertFalse(rbstr.contains("ice"), "should not contain ice");
410         rbstr = Range.of("house", "i", lengthComp);
411         assertFalse(rbstr.contains(null), "should not contain null");
412         assertTrue(rbstr.contains("house"), "should contain house");
413         assertTrue(rbstr.contains("i"), "should contain i");
414         assertFalse(rbstr.contains("houses"), "should not contain houses");
415         assertFalse(rbstr.contains(""), "should not contain ''");
416 
417         assertThrows(NullPointerException.class, () -> Range.of(null, null, lengthComp));
418     }
419 
420     @Test
421     public void testRangeOfChars() {
422         final Range<Character> chars = Range.between('a', 'z');
423         assertTrue(chars.contains('b'));
424         assertFalse(chars.contains('B'));
425     }
426 
427     @Test
428     public void testSerializing() {
429         SerializationUtils.clone(intRange);
430     }
431 
432     @Test
433     public void testToString() {
434         assertNotNull(byteRange.toString());
435 
436         final String str = intRange.toString();
437         assertEquals("[10..20]", str);
438         assertEquals("[-20..-10]", Range.between(-20, -10).toString());
439     }
440 
441     @Test
442     public void testToStringFormat() {
443         final String str = intRange.toString("From %1$s to %2$s");
444         assertEquals("From 10 to 20", str);
445     }
446 }