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  package org.apache.commons.functor.range;
18  
19  import static org.junit.Assert.assertEquals;
20  import static org.junit.Assert.assertFalse;
21  import static org.junit.Assert.assertTrue;
22  import static org.junit.Assert.fail;
23  
24  import java.util.ArrayList;
25  import java.util.Arrays;
26  import java.util.Collection;
27  import java.util.Collections;
28  import java.util.List;
29  
30  import org.apache.commons.functor.BaseFunctorTest;
31  import org.apache.commons.functor.Function;
32  import org.apache.commons.functor.generator.Generator;
33  import org.apache.commons.functor.generator.loop.IteratorToGeneratorAdapter;
34  import org.junit.After;
35  import org.junit.Before;
36  import org.junit.Test;
37  
38  /**
39   * @version $Revision: 1515264 $ $Date: 2013-08-18 23:51:41 -0300 (Sun, 18 Aug 2013) $
40   */
41  public class TestIntegerRange extends BaseFunctorTest {
42  
43      // Attributes
44      // ------------------------------------------------------------------------
45      private IntegerRange ascIntRange = null;
46      private IntegerRange descIntRange = null;
47      private Collection<Integer> expectedAsc = null;
48      private Collection<Integer> expectedDesc = null;
49  
50      // Test set up
51      // ------------------------------------------------------------------------
52      @Before
53      public void setUp() {
54          ascIntRange = Ranges.integerRange(0, 10);
55          descIntRange = Ranges.integerRange(10, 0);
56          expectedAsc = Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
57          expectedDesc = Arrays.asList(10, 9, 8, 7, 6, 5, 4, 3, 2, 1);
58      }
59  
60      @After
61      public void tearDown() {
62          ascIntRange = null;
63          descIntRange = null;
64      }
65      
66      @Override
67      protected Object makeFunctor() throws Exception {
68          return Ranges.integerRange(10, 20);
69      }
70  
71      // Generator tests
72      // ------------------------------------------------------------------------
73  
74      @Test
75      public void testGenerateListExample() {
76          // generates a collection of Integers from 0 (inclusive) to 10 (exclusive)
77          {
78              List<? super Integer> list = (List<? super Integer>) (
79                  IteratorToGeneratorAdapter.adapt(Ranges.integerRange(0,10)).to(new ArrayList<Integer>()));
80              for (int i=0;i<10;i++) {
81                  assertEquals(Integer.valueOf(i),list.get(i));
82              }
83          }
84  
85          // generates a collection of Integers from 10 (inclusive) to 0 (exclusive)
86          {
87              List<? super Integer> list = (List<? super Integer>) (
88                  IteratorToGeneratorAdapter.adapt(Ranges.integerRange(10,0)).to(new ArrayList<Integer>()));
89              for (int i=10;i>0;i--) {
90                  assertEquals(Integer.valueOf(i),list.get(10-i));
91              }
92          }
93      }
94  
95      @Test
96      public void testStepChecking() {
97          {
98              Ranges.integerRange(2, 2, 0); // step of 0 is ok when range is empty
99          }
100         {
101             Ranges.integerRange(2, 2, 1); // positive step is ok when range is empty
102         }
103         {
104             Ranges.integerRange(2, 2, -1); // negative step is ok when range is empty
105         }
106         {
107             Ranges.integerRange(0, 1, 10); // big steps are ok
108         }
109         {
110             Ranges.integerRange(1, 0, -10); // big steps are ok
111         }
112         try {
113             Ranges.integerRange(0, 1, 0);
114             fail("Expected IllegalArgumentException");
115         } catch(IllegalArgumentException e) {
116             // expected
117         }
118         try {
119             Ranges.integerRange(0, 1, -1);
120             fail("Expected IllegalArgumentException");
121         } catch(IllegalArgumentException e) {
122             // expected
123         }
124         try {
125             Ranges.integerRange(0, -1, 1);
126             fail("Expected IllegalArgumentException");
127         } catch(IllegalArgumentException e) {
128             // expected
129         }
130     }
131 
132     @Test
133     public void testObjectConstructor() {
134         IntegerRange range = Ranges.integerRange(Integer.valueOf(0), Integer.valueOf(5));
135         assertEquals("[0, 1, 2, 3, 4]", IteratorToGeneratorAdapter.adapt(range).toCollection().toString());
136         range = Ranges.integerRange(Integer.valueOf(0), Integer.valueOf(5), Integer.valueOf(1));
137         assertEquals("[0, 1, 2, 3, 4]", IteratorToGeneratorAdapter.adapt(range).toCollection().toString());
138     }
139 
140 
141     @Test
142     public void testReverseStep() {
143         IntegerRange range = Ranges.integerRange(10, 0, -2);
144         assertEquals("[10, 8, 6, 4, 2]", IteratorToGeneratorAdapter.adapt(range).toCollection().toString());
145     }
146 
147     @Test
148     public void testStep() {
149         IntegerRange range = Ranges.integerRange(0, 10, 2);
150         assertEquals("[0, 2, 4, 6, 8]", IteratorToGeneratorAdapter.adapt(range).toCollection().toString());
151     }
152 
153     @Test
154     public void testForwardRange() {
155         IntegerRange range = Ranges.integerRange(0, 5);
156         assertEquals("[0, 1, 2, 3, 4]", IteratorToGeneratorAdapter.adapt(range).toCollection().toString());
157     }
158 
159     @Test
160     public void testReverseRange() {
161         IntegerRange range = Ranges.integerRange(5, 0);
162         assertEquals("[5, 4, 3, 2, 1]", IteratorToGeneratorAdapter.adapt(range).toCollection().toString());
163     }
164 
165     @Test
166     public void testEdgeCase() {
167         IntegerRange range = Ranges.integerRange(Integer.MAX_VALUE - 3, Integer.MAX_VALUE);
168         assertEquals("[2147483644, 2147483645, 2147483646]", IteratorToGeneratorAdapter.adapt(range).toCollection().toString());
169     }
170 
171     @Test
172     public void testBoundaries() {
173         IntegerRange range = Ranges.integerRange(0, 10);
174         assertEquals(new Endpoint<Comparable<?>>(0, BoundType.CLOSED),
175                      range.getLeftEndpoint());
176         assertEquals(new Endpoint<Comparable<?>>(10, BoundType.OPEN),
177                      range.getRightEndpoint());
178     }
179 
180     @Test
181     public void testClosedClosedAscending() {
182         // [-5, 5], 3 = -5, -2, 1, 4
183         IntegerRange range = Ranges.integerRange(-5, BoundType.CLOSED, 5,
184                                               BoundType.CLOSED, 3);
185         // [-5, 5], 3 = -5, -2, 1, 4
186         List<Integer> expected = Arrays.asList(-5, -2, 1, 4);
187         Collection<Integer> elements = IteratorToGeneratorAdapter.adapt(range).toCollection();
188         assertEquals(expected, elements);
189     }
190 
191     @Test
192     public void testOpenClosedAscending() {
193         // (-5, 5], 3 = -2, 1, 4
194         IntegerRange range = Ranges.integerRange(-5, BoundType.OPEN, 5,
195                                               BoundType.CLOSED, 3);
196         // (-5, 5], 3 = -2, 1, 4
197         List<Integer> expected = Arrays.asList(-2, 1, 4);
198         Collection<Integer> elements = IteratorToGeneratorAdapter.adapt(range).toCollection();
199         assertEquals(expected, elements);
200     }
201 
202     @Test
203     public void testClosedOpenAscending() {
204         // [-5, 5), 3 = -5, -2, 1, 4
205         IntegerRange range = Ranges.integerRange(-5, BoundType.CLOSED, 5,
206                                               BoundType.OPEN, 3);
207         // (-5, 5], 3 = -5, -2, 1, 4
208         List<Integer> expected = Arrays.asList(-5, -2, 1, 4);
209         Collection<Integer> elements = IteratorToGeneratorAdapter.adapt(range).toCollection();
210         assertEquals(expected, elements);
211     }
212 
213     @Test
214     public void testOpenOpenAscending() {
215         // (-5, 5), 3 = -2, 1, 4
216         IntegerRange range = Ranges.integerRange(-5, BoundType.OPEN, 5,
217                                               BoundType.OPEN, 3);
218         // (-5, 5), 3 = -2, 1, 4
219         List<Integer> expected = Arrays.asList(-2, 1, 4);
220         Collection<Integer> elements = IteratorToGeneratorAdapter.adapt(range).toCollection();
221         assertEquals(expected, elements);
222     }
223 
224     @Test
225     public void testSingleStepAscending() {
226         // (-2, 2], 1 = -1, 0, 1, 2
227         IntegerRange range = Ranges.integerRange(-2, BoundType.OPEN, 2,
228                                               BoundType.CLOSED, 1);
229         // (-2, 2], 1 = -1, 0, 1, 2
230         List<Integer> expected = Arrays.asList(-1, 0, 1, 2);
231         Collection<Integer> elements = IteratorToGeneratorAdapter.adapt(range).toCollection();
232         assertEquals(expected, elements);
233     }
234 
235     @Test
236     public void testClosedClosedDescending() {
237         // [5, -5], -3 = 5, 2, -1, -4
238         IntegerRange range = Ranges.integerRange(5, BoundType.CLOSED, -5,
239                                               BoundType.CLOSED, -3);
240         // [5, -5], -3 = 5, 2, -1, -4
241         List<Integer> expected = Arrays.asList(5, 2, -1, -4);
242         Collection<Integer> elements = IteratorToGeneratorAdapter.adapt(range).toCollection();
243         assertEquals(expected, elements);
244     }
245 
246     @Test
247     public void testOpenClosedDescending() {
248         // (5, -5], -3 = 2, -1, -4
249         IntegerRange range = Ranges.integerRange(5, BoundType.OPEN, -5,
250                                               BoundType.CLOSED, -3);
251         // (5, -5], -3 = 2, -1, -4
252         List<Integer> expected = Arrays.asList(2, -1, -4);
253         Collection<Integer> elements = IteratorToGeneratorAdapter.adapt(range).toCollection();
254         assertEquals(expected, elements);
255     }
256 
257     @Test
258     public void testClosedOpenDescending() {
259         // [5, -5), -3 = 5, 2, -1, -4
260         IntegerRange range = Ranges.integerRange(5, BoundType.CLOSED, -5,
261                                               BoundType.OPEN, -3);
262         // [5, -5), -3 = 5, 2, -1, -4
263         List<Integer> expected = Arrays.asList(5, 2, -1, -4);
264         Collection<Integer> elements = IteratorToGeneratorAdapter.adapt(range).toCollection();
265         assertEquals(expected, elements);
266     }
267 
268     @Test
269     public void testOpenOpenDescending() {
270         // (5, -5), -3 = 2, -1, -4
271         IntegerRange range = Ranges.integerRange(5, BoundType.OPEN, -5,
272                                               BoundType.OPEN, -3);
273         // (5, -5), -3 = 2, -1, -4
274         List<Integer> expected = Arrays.asList(2, -1, -4);
275         Collection<Integer> elements = IteratorToGeneratorAdapter.adapt(range).toCollection();
276         assertEquals(expected, elements);
277     }
278 
279     @Test
280     public void testSingleStepDescending() {
281         // [2, -2), -1 = 2, 1, 0, -1
282         IntegerRange range = Ranges.integerRange(2, BoundType.CLOSED, -2,
283                                               BoundType.OPEN, -1);
284         // [2, -2), -1 = 2, 1, 0, -1
285         List<Integer> expected = Arrays.asList(2, 1, 0, -1);
286         Collection<Integer> elements = IteratorToGeneratorAdapter.adapt(range).toCollection();
287         assertEquals(expected, elements);
288     }
289 
290     @Test
291     public void testAscending() {
292         final List<Integer> list = new ArrayList<Integer>();
293         for (int i : ascIntRange) {
294             list.add(i);
295         }
296         assertTrue(expectedAsc.containsAll(list));
297     }
298 
299     @Test
300     public void testDescending() {
301         final List<Integer> list = new ArrayList<Integer>();
302         for (int i : descIntRange) {
303             list.add(i);
304         }
305         assertTrue(expectedDesc.containsAll(list));
306     }
307 
308     @Test
309     public void testToCollection() {
310         Collection<Integer> ascCol = IteratorToGeneratorAdapter.adapt(ascIntRange).toCollection();
311         assertEquals("Different collections", expectedAsc, ascCol);
312         Collection<Integer> descCol = IteratorToGeneratorAdapter.adapt(descIntRange).toCollection();
313         assertEquals("Different collections", expectedDesc, descCol);
314     }
315 
316     @Test
317     public void testTransformedGenerator() {
318         int expected = 45;
319         int total = IteratorToGeneratorAdapter.adapt(ascIntRange)
320             .to(new Function<Generator<? extends Integer>, Integer>() {
321 
322                 public Integer evaluate(Generator<? extends Integer> obj) {
323                     int total = 0;
324                     for (Object element : obj.toCollection()) {
325                         total += (Integer) element;
326                     }
327                     return total;
328                 }
329             });
330         assertEquals(expected, total);
331         expected = 55;
332         total = IteratorToGeneratorAdapter.adapt(descIntRange)
333             .to(new Function<Generator<? extends Integer>, Integer>() {
334 
335                 public Integer evaluate(Generator<? extends Integer> obj) {
336                     int total = 0;
337                     for (Object element : obj.toCollection()) {
338                         total += (Integer) element;
339                     }
340                     return total;
341                 }
342             });
343         assertEquals(expected, total);
344     }
345 
346     // Range tests
347     // ---------------------------------------------------------------
348 
349     // A base range with all integers between -6 and 6
350     private final List<Integer> fullRange = Collections.unmodifiableList(Arrays
351         .asList(-6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6));
352 
353     @Test
354     public void testEmptyRanges() {
355         IntegerRange empty1 = Ranges.integerRange(-2, BoundType.OPEN, -1,
356                                                BoundType.OPEN, 2);
357         assertTrue("The range was expected to be empty.", empty1.isEmpty());
358         IntegerRange empty2 = Ranges.integerRange(2, BoundType.OPEN, 0,
359                                                BoundType.OPEN, -2);
360         assertTrue("The range was expected to be empty.", empty2.isEmpty());
361         IntegerRange empty3 = Ranges.integerRange(0, BoundType.OPEN, 1,
362                                                BoundType.CLOSED, 2);
363         assertTrue("The range was expected to be empty.", empty3.isEmpty());
364         IntegerRange empty4 = Ranges.integerRange(-3, BoundType.OPEN, -3,
365                                                BoundType.OPEN, 1);
366         assertTrue("The range was expected to be empty.", empty4.isEmpty());
367         IntegerRange empty5 = Ranges.integerRange(-3, BoundType.CLOSED, -3,
368                                                BoundType.OPEN, 1);
369         assertTrue("The range was expected to be empty.", empty5.isEmpty());
370         IntegerRange empty6 = Ranges.integerRange(1, BoundType.OPEN, 0,
371                                                BoundType.CLOSED, -2);
372         assertTrue("The range was expected to be empty.", empty6.isEmpty());
373         IntegerRange notEmpty1 = Ranges.integerRange(-3, BoundType.CLOSED, -3,
374                                                   BoundType.CLOSED, 1);
375         assertFalse("The range was not expected to be empty.",
376                     notEmpty1.isEmpty());
377         IntegerRange notEmpty2 = Ranges.integerRange(-3, BoundType.OPEN, -2,
378                                                   BoundType.CLOSED, 1);
379         assertFalse("The range was not expected to be empty.",
380                     notEmpty2.isEmpty());
381         IntegerRange notEmpty3 = Ranges.integerRange(2, BoundType.OPEN, 1,
382                                                   BoundType.CLOSED, -1);
383         assertFalse("The range was not expected to be empty.",
384                     notEmpty3.isEmpty());
385         IntegerRange notEmpty4 = Ranges.integerRange(2, BoundType.CLOSED, 1,
386                                                   BoundType.OPEN, -1);
387         assertFalse("The range was not expected to be empty.",
388                     notEmpty4.isEmpty());
389         IntegerRange notEmpty5 = Ranges.integerRange(1, BoundType.CLOSED, 2,
390                                                   BoundType.OPEN, 1);
391         assertFalse("The range was not expected to be empty.",
392                     notEmpty5.isEmpty());
393     }
394 
395     @Test
396     public void testClosedClosedAscendingContains() {
397         // [-5, 5], 3 = -5, -2, 1, 4
398         IntegerRange range = Ranges.integerRange(-5, BoundType.CLOSED, 5,
399                                               BoundType.CLOSED, 3);
400         // [-5, 5], 3 = -5, -2, 1, 4
401         List<Integer> arr = Arrays.asList(-5, -2, 1, 4);
402         for (Integer element : arr) {
403             assertTrue("Expected element [" + element +
404                                "] is missing in range [" + range + "]",
405                        range.contains(element));
406         }
407         List<Integer> elementsNotPresent = new ArrayList<Integer>(fullRange);
408         elementsNotPresent.removeAll(arr);
409         for (Integer element : elementsNotPresent) {
410             assertFalse("Unexpected element [" + element +
411                                 "] is present in range [" + range + "]",
412                         range.contains(element));
413         }
414     }
415 
416     @Test
417     public void testOpenClosedAscendingContains() {
418         // (-5, 5], 3 = -2, 1, 4
419         IntegerRange range = Ranges.integerRange(-5, BoundType.OPEN, 5,
420                                               BoundType.CLOSED, 3);
421         // (-5, 5], 3 = -2, 1, 4
422         List<Integer> arr = Arrays.asList(-2, 1, 4);
423         for (Integer element : arr) {
424             assertTrue("Expected element [" + element +
425                                "] is missing in range [" + range + "]",
426                        range.contains(element));
427         }
428         List<Integer> elementsNotPresent = new ArrayList<Integer>(fullRange);
429         elementsNotPresent.removeAll(arr);
430         for (Integer element : elementsNotPresent) {
431             assertFalse("Unexpected element [" + element +
432                                 "] is present in range [" + range + "]",
433                         range.contains(element));
434         }
435     }
436 
437     @Test
438     public void testClosedOpenAscendingContains() {
439         // [-5, 5), 3 = -5, -2, 1, 4
440         IntegerRange range = Ranges.integerRange(-5, BoundType.CLOSED, 5,
441                                               BoundType.OPEN, 3);
442         // (-5, 5], 3 = -5, -2, 1, 4
443         List<Integer> arr = Arrays.asList(-5, -2, 1, 4);
444         for (Integer element : arr) {
445             assertTrue("Expected element [" + element +
446                                "] is missing in range [" + range + "]",
447                        range.contains(element));
448         }
449         List<Integer> elementsNotPresent = new ArrayList<Integer>(fullRange);
450         elementsNotPresent.removeAll(arr);
451         for (Integer element : elementsNotPresent) {
452             assertFalse("Unexpected element [" + element +
453                                 "] is present in range [" + range + "]",
454                         range.contains(element));
455         }
456     }
457 
458     @Test
459     public void testOpenOpenAscendingContains() {
460         // (-5, 5), 3 = -2, 1, 4
461         IntegerRange range = Ranges.integerRange(-5, BoundType.OPEN, 5,
462                                               BoundType.OPEN, 3);
463         // (-5, 5), 3 = -2, 1, 4
464         List<Integer> arr = Arrays.asList(-2, 1, 4);
465         for (Integer element : arr) {
466             assertTrue("Expected element [" + element +
467                                "] is missing in range [" + range + "]",
468                        range.contains(element));
469         }
470         List<Integer> elementsNotPresent = new ArrayList<Integer>(fullRange);
471         elementsNotPresent.removeAll(arr);
472         for (Integer element : elementsNotPresent) {
473             assertFalse("Unexpected element [" + element +
474                                 "] is present in range [" + range + "]",
475                         range.contains(element));
476         }
477     }
478 
479     @Test
480     public void testContainsSingleStepAscending() {
481         // (-2, 2], 1 = -1, 0, 1, 2
482         IntegerRange ascendingRange = Ranges.integerRange(-2, BoundType.OPEN, 2,
483                                                        BoundType.CLOSED, 1);
484         // (-2, 2], 1 = -1, 0, 1, 2
485         List<Integer> arr = Arrays.asList(-1, 0, 1, 2);
486         for (Integer element : arr) {
487             assertTrue("Expected element [" + element +
488                                "] is missing in range [" + ascendingRange + "]",
489                        ascendingRange.contains(element));
490         }
491         List<Integer> elementsNotPresent = new ArrayList<Integer>(fullRange);
492         elementsNotPresent.removeAll(arr);
493         for (Integer element : elementsNotPresent) {
494             assertFalse("Unexpected element [" + element +
495                                 "] is present in range [" + ascendingRange +
496                                 "]",
497                         ascendingRange.contains(element));
498         }
499     }
500 
501     @Test
502     public void testClosedClosedDescendingContains() {
503         // [5, -5], -3 = 5, 2, -1, -4
504         IntegerRange range = Ranges.integerRange(5, BoundType.CLOSED, -5,
505                                               BoundType.CLOSED, -3);
506         // [5, -5], -3 = 5, 2, -1, -4
507         List<Integer> arr = Arrays.asList(5, 2, -1, -4);
508         for (Integer element : arr) {
509             assertTrue("Expected element [" + element +
510                                "] is missing in range [" + range + "]",
511                        range.contains(element));
512         }
513         List<Integer> elementsNotPresent = new ArrayList<Integer>(fullRange);
514         elementsNotPresent.removeAll(arr);
515         for (Integer element : elementsNotPresent) {
516             assertFalse("Unexpected element [" + element +
517                                 "] is present in range [" + range + "]",
518                         range.contains(element));
519         }
520     }
521 
522     @Test
523     public void testOpenClosedDescendingContains() {
524         // (5, -5], -3 = 2, -1, -4
525         IntegerRange range = Ranges.integerRange(5, BoundType.OPEN, -5,
526                                               BoundType.CLOSED, -3);
527         // (5, -5], -3 = 2, -1, -4
528         List<Integer> arr = Arrays.asList(2, -1, -4);
529         for (Integer element : arr) {
530             assertTrue("Expected element [" + element +
531                                "] is missing in range [" + range + "]",
532                        range.contains(element));
533         }
534         List<Integer> elementsNotPresent = new ArrayList<Integer>(fullRange);
535         elementsNotPresent.removeAll(arr);
536         for (Integer element : elementsNotPresent) {
537             assertFalse("Unexpected element [" + element +
538                                 "] is present in range [" + range + "]",
539                         range.contains(element));
540         }
541     }
542 
543     @Test
544     public void testClosedOpenDescendingContains() {
545         // [5, -5), -3 = 5, 2, -1, -4
546         IntegerRange range = Ranges.integerRange(5, BoundType.CLOSED, -5,
547                                               BoundType.OPEN, -3);
548         // [5, -5), -3 = 5, 2, -1, -4
549         List<Integer> arr = Arrays.asList(5, 2, -1, -4);
550         for (Integer element : arr) {
551             assertTrue("Expected element [" + element +
552                                "] is missing in range [" + range + "]",
553                        range.contains(element));
554         }
555         List<Integer> elementsNotPresent = new ArrayList<Integer>(fullRange);
556         elementsNotPresent.removeAll(arr);
557         for (Integer element : elementsNotPresent) {
558             assertFalse("Unexpected element [" + element +
559                                 "] is present in range [" + range + "]",
560                         range.contains(element));
561         }
562     }
563 
564     @Test
565     public void testOpenOpenDescendingContains() {
566         // (5, -5), -3 = 2, -1, -4
567         IntegerRange range = Ranges.integerRange(5, BoundType.OPEN, -5,
568                                               BoundType.OPEN, -3);
569         // (5, -5), -3 = 2, -1, -4
570         List<Integer> arr = Arrays.asList(2, -1, -4);
571         for (Integer element : arr) {
572             assertTrue("Expected element [" + element +
573                                "] is missing in range [" + range + "]",
574                        range.contains(element));
575         }
576         List<Integer> elementsNotPresent = new ArrayList<Integer>(fullRange);
577         elementsNotPresent.removeAll(arr);
578         for (Integer element : elementsNotPresent) {
579             assertFalse("Unexpected element [" + element +
580                                 "] is present in range [" + range + "]",
581                         range.contains(element));
582         }
583     }
584 
585     @Test
586     public void testContainsSingleStepDescending() {
587         // [2, -2), -1 = 2, 1, 0, -1
588         IntegerRange descendingRange = Ranges.integerRange(2, BoundType.CLOSED,
589                                                         -2, BoundType.OPEN, -1);
590         // [2, -2), -1 = 2, 1, 0, -1
591         List<Integer> arr = Arrays.asList(2, 1, 0, -1);
592         for (Integer element : arr) {
593             assertTrue("Expected element [" + element +
594                                "] is missing in range [" + descendingRange +
595                                "]",
596                        descendingRange.contains(element));
597         }
598         List<Integer> elementsNotPresent = new ArrayList<Integer>(fullRange);
599         elementsNotPresent.removeAll(arr);
600         for (Integer element : elementsNotPresent) {
601             assertFalse("Unexpected element [" + element +
602                                 "] is present in range [" + descendingRange +
603                                 "]",
604                         descendingRange.contains(element));
605         }
606     }
607 
608     @Test
609     public void testContainsNullOrEmpty() {
610         IntegerRange range = Ranges.integerRange(-2, BoundType.OPEN, 2,
611                                               BoundType.CLOSED, 1);
612         assertFalse(range.contains(null));
613     }
614 
615     @SuppressWarnings("unchecked")
616     @Test
617     public void testContainsAll() {
618         // (-2, 2], 1 = -1, 0, 1, 2
619         IntegerRange range = Ranges.integerRange(-2, BoundType.OPEN, 2,
620                                               BoundType.CLOSED, 1);
621         List<Integer> list = Arrays.asList(-1, 0, 1, 2);
622         assertTrue("Range [" + range +
623                    "] was expected to contain all elements from list [" + list +
624                    "]", range.containsAll(list));
625         List<Integer> listWithExtraElements = Arrays.asList(2, -1, 0, 1, 2, 3);
626         assertFalse("Range [" + range + "] has more elements than expected",
627                     range.containsAll(listWithExtraElements));
628         assertFalse(range.containsAll(null));
629         assertFalse(range.containsAll(Collections.EMPTY_LIST));
630     }
631 
632     @Test
633     public void testEquals()
634         throws Exception {
635         // equals basic properties
636         IntegerRange range = Ranges.integerRange(-2, BoundType.CLOSED, 2,
637                                               BoundType.OPEN, 1);
638         assertEquals("equals must be reflexive", range, range);
639         assertEquals("hashCode must be reflexive", range.hashCode(),
640                      range.hashCode());
641         assertTrue(!range.equals(null)); // should be able to compare to null
642 
643         Object range2 = Ranges.integerRange(-2, BoundType.CLOSED, 2,
644                                          BoundType.OPEN, 1);
645         if (range.equals(range2)) {
646             assertEquals("equals implies hash equals", range.hashCode(),
647                          range2.hashCode());
648             assertEquals("equals must be symmetric", range2, range);
649         } else {
650             assertTrue("equals must be symmetric", !range2.equals(range));
651         }
652 
653         // Changing attributes
654         Object range3 = Ranges.integerRange(-1, BoundType.CLOSED, 2,
655                                          BoundType.OPEN, 1);
656         assertFalse("Invalid equals after changing attributes",
657                     range.equals(range3));
658 
659         Object range4 = Ranges.integerRange(-2, BoundType.OPEN, 2, BoundType.OPEN,
660                                          1);
661         assertFalse("Invalid equals after changing attributes",
662                     range.equals(range4));
663 
664         Object range5 = Ranges.integerRange(-2, BoundType.CLOSED, 1,
665                                          BoundType.OPEN, 1);
666         assertFalse("Invalid equals after changing attributes",
667                     range.equals(range5));
668 
669         Object range6 = Ranges.integerRange(-2, BoundType.CLOSED, 2,
670                                          BoundType.CLOSED, 1);
671         assertFalse("Invalid equals after changing attributes",
672                     range.equals(range6));
673 
674         Object range7 = Ranges.integerRange(-2, BoundType.CLOSED, 2,
675                                          BoundType.OPEN, 2);
676         assertFalse("Invalid equals after changing attributes",
677                     range.equals(range7));
678 
679         // Using different constructors
680         IntegerRange range8 = Ranges.integerRange(Long.valueOf(-2),
681                                                   Long.valueOf(2), Long.valueOf(1));
682         assertEquals("Invalid equals using different constructor", range,
683                      range8);
684 
685         IntegerRange range9 = Ranges.integerRange(Long.valueOf(-2),
686                                                   Long.valueOf(2));
687         assertEquals("Invalid equals using different constructor", range,
688                      range9);
689 
690         Endpoint<Integer> leftEndpoint = new Endpoint<Integer>(-2,
691                                                                BoundType.CLOSED);
692         Endpoint<Integer> rightEndpoint = new Endpoint<Integer>(2,
693                                                                 BoundType.OPEN);
694         IntegerRange range10 = Ranges.integerRange(leftEndpoint, rightEndpoint, 1);
695         assertEquals("Invalid equals using different constructor", range,
696                      range10);
697     }
698 
699     @Test
700     public void testToString() {
701         IntegerRange range = Ranges.integerRange(-2, BoundType.OPEN, 2,
702                                               BoundType.CLOSED, 1);
703         assertEquals("Wrong string value", "IntegerRange<(-2, 2], 1>",
704                      range.toString());
705     }
706 
707     @Test
708     public void testConstructorUsingSameEndpoint() {
709         Endpoint<Integer> uniqueEndpoint = new Endpoint<Integer>(
710                                                                  10,
711                                                                  BoundType.CLOSED);
712         try {
713             Ranges.integerRange(uniqueEndpoint, uniqueEndpoint, 1);
714         } catch (IllegalArgumentException e) {
715             fail("Not expected to get here");
716         }
717     }
718 
719     @Test
720     public void testInvalidRange() {
721         try {
722             Ranges.integerRange(10, BoundType.OPEN, -5, BoundType.CLOSED, 10);
723             fail("Not expected to get here");
724         } catch (IllegalArgumentException e) {
725             // Do nothing
726         }
727         Endpoint<Integer> leftEndpoint = new Endpoint<Integer>(10,
728                                                                BoundType.CLOSED);
729         Endpoint<Integer> rightEndpoint = new Endpoint<Integer>(-5,
730                                                                 BoundType.OPEN);
731         try {
732             Ranges.integerRange(leftEndpoint, rightEndpoint, 1);
733             fail("Not expected to get here");
734         } catch (IllegalArgumentException e) {
735             // Do nothing
736         }
737     }
738 
739     @Test
740     public void testDefaultStep() {
741         assertEquals("Invalid default step", Integer.valueOf(-1),
742                      IntegerRange.DEFAULT_STEP.evaluate(10, 1));
743         assertEquals("Invalid default step", Integer.valueOf(1),
744                      IntegerRange.DEFAULT_STEP.evaluate(1, 10));
745     }
746 
747 }