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