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