You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by ki...@apache.org on 2012/09/16 20:08:32 UTC

svn commit: r1385335 [2/4] - in /commons/proper/functor/branches/generators-FUNCTOR-14: ./ src/changes/ src/main/java/org/apache/commons/functor/generator/range/ src/site/xdoc/ src/test/java/org/apache/commons/functor/generator/range/

Modified: commons/proper/functor/branches/generators-FUNCTOR-14/src/site/xdoc/examples.xml
URL: http://svn.apache.org/viewvc/commons/proper/functor/branches/generators-FUNCTOR-14/src/site/xdoc/examples.xml?rev=1385335&r1=1385334&r2=1385335&view=diff
==============================================================================
--- commons/proper/functor/branches/generators-FUNCTOR-14/src/site/xdoc/examples.xml (original)
+++ commons/proper/functor/branches/generators-FUNCTOR-14/src/site/xdoc/examples.xml Sun Sep 16 18:08:31 2012
@@ -28,8 +28,10 @@
       <p>
          This page contains basic examples using <a href="apidocs/org/apache/commons/functor/Predicate.html">Predicates</a>, 
          <a href="apidocs/org/apache/commons/functor/Function.html">Functions</a>, 
-         <a href="apidocs/org/apache/commons/functor/Procedure.html">Procedures</a> and 
-         <a href="apidocs/org/apache/commons/functor/generator/Generator.html">Generators</a>. 
+         <a href="apidocs/org/apache/commons/functor/Procedure.html">Procedures</a>, 
+         <a href="apidocs/org/apache/commons/functor/generator/Generator.html">Generators</a>, 
+         <a href="apidocs/org/apache/commons/functor/generator/range/Range.html">Ranges</a> and 
+         <a href="apidocs/org/apache/commons/functor/aggregator/Aggregator.html">Aggregators</a>. 
          There are also examples using composition and more practical examples 
          at the bottom of this page.
       </p>
@@ -104,6 +106,129 @@ for( Integer number : numbers ) {
     </p>
     </subsection>
 
+    <subsection name="Generators">
+       <p>
+         Apache Functor includes other objects that you can can use to code in
+         a less imperative way, like <em>Generators</em>. In the following
+         example, we create an <em>Integer Generator</em> that generates
+         integers from 1 to 4 (the right argument is non-inclusive). The
+         generator is wrapped within a <em>Filtered Generator</em> that applies
+         the isEven predicate to each integer generated by the former generator.
+         Finally, we execute a <em>Composite Unary Procedure</em> that uses
+         a function to double the value of the integer before printing it.
+       </p>
+<source>
+Generator&lt;Integer&gt; integerGenerator = new IntegerRange(1, 5); // inclusive, exclusive
+    
+UnaryPredicate&lt;Integer&gt; isEven = new UnaryPredicate&lt;Integer&gt;() {
+    public boolean test(Integer obj) {
+        return obj % 2 == 0;
+    }
+};
+
+FilteredGenerator&lt;Integer&gt; filteredGenerator = 
+        new FilteredGenerator&lt;Integer&gt;(integerGenerator, isEven);
+
+UnaryFunction&lt;Integer, Integer&gt; doubler = new UnaryFunction&lt;Integer, Integer&gt;() {
+    public Integer evaluate(Integer obj) {
+        return obj * 2;
+    }
+};
+
+UnaryProcedure&lt;Integer&gt; print = new UnaryProcedure&lt;Integer&gt;() {
+    public void run(Integer obj) {
+        System.out.print(obj + " ");
+    }
+};
+
+CompositeUnaryProcedure&lt;Integer&gt; compositeProcedure =
+        new CompositeUnaryProcedure&lt;Integer&gt;(print);
+
+filteredGenerator.run(compositeProcedure.of(doubler));
+</source>
+       <p>
+         The <a href="http://svn.apache.org/viewvc/commons/proper/functor/trunk/src/test/java/org/apache/commons/functor/example/lines/">lines</a>
+         package demonstrates a functional approach to IO using Generators and the Algorithms class.
+       </p>
+    </subsection>
+
+    <subsection name="Ranges">
+        <p>
+         Using <em>Ranges</em> you are able to create a series of elements of 
+         a certain type. The distance between each element is called 
+         <em>step</em>. And the <em>left</em> and <em>right</em> limits are 
+         <em>endpoints</em>.
+        </p>
+        <p>
+         By default, in numeric ranges the left value is inclusive and the 
+         right is exclusive. The range below creates a series of Integers 
+         between <em>0</em> and <em>10</em>, with a default step of <em>1</em>.
+        </p>
+<source>
+// [0, 10), 1 = 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
+IntegerRange range = new IntegerRange(0, 10);
+</source>
+        <p>
+         The step value can be changed, altering the distance between each 
+         element in the range. As shown below.
+        </p>
+<source>
+// [0, 10), 2 = 0, 2, 4, 6, 8
+IntegerRange range = new IntegerRange(0, 10, 2);
+</source>
+        <p>
+         It is possible, too, to define the <em>bound type</em> of each endpoint. 
+         It is similar to mathematical intervals, where a 
+         <em>closed</em> endpoint means that the value is included in the 
+         series of elements in the range. On the other hand, an <em>open</em> 
+         endpoint means that the value is not included.
+        </p>
+<source>
+// (0, 10], 2 = 2, 4, 6, 8, 10
+IntegerRange range = new IntegerRange(0, BoundType.OPEN, 10, BoundType.CLOSED, 2);
+</source>
+        <p>
+         A Range is also by nature a Generator, so you can use it for executing 
+         procedures for each of its elements.
+        </p>
+<source>
+// [0, 10), 1 = 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
+IntegerRange range = new IntegerRange(0, 10);
+UnaryProcedure&lt;Integer&gt; printProcedure = new UnaryProcedure&lt;Integer&gt;() {
+    
+    public void run(Integer obj) {
+        System.out.print(obj + " ");
+    }
+};
+range.run(printProcedure);
+</source>
+        <p>
+        The code above produces the following output: 0 1 2 3 4 5 6 7 8 9 
+        </p>
+    </subsection>
+
+    <subsection name="Aggregators">
+      <p>
+         There are some code snippets / examples for the <code>org.apache.commons.functor.aggregator</code> package
+         available on <a href="aggregator.html">this page</a>. Also, to exemplify the usage of the <code>Aggregator</code>
+         classes, there are code examples in the test section.
+      </p>
+      <p>
+         First such set of example involves the usage of the <i>nostore</i> <code>Aggregator</code>. Code can be found in
+         <a href="http://svn.apache.org/viewvc/commons/proper/functor/trunk/src/test/java/org/apache/commons/functor/example/aggregator/nostore/">org.apache.commons.functor.example.aggregator.nostore</a>.
+         This shows how can you use an aggregator which doesn't store the data series and processes them on the fly.
+         Also, there are examples provided which show how can you implement your own aggregation function
+         to be used with this <code>Aggregator</code> type.
+      </p>
+      <p>
+         For using an <code>Aggregator</code> which stores the data series in a list, examples are in
+         <a href="http://svn.apache.org/viewvc/commons/proper/functor/trunk/src/test/java/org/apache/commons/functor/example/aggregator/list/">org.apache.commons.functor.example.aggregator.list</a>.
+         This shows how can you use the <code>ArrayList</code>-backed aggregator or provide your own <code>List</code>-based implementation.
+         Also, there are examples provided which show how can you implement your own aggregation function
+         to be used with this <code>Aggregator</code> type.
+      </p>
+    </subsection>
+
     <subsection name="Reuse Through Composition">
        <p>
           The <em>Functor</em> package, and more generally, a functional approach
@@ -178,74 +303,6 @@ for( Integer number : numbers ) {
        </p>
     </subsection>
 
-    <subsection name="Generators">
-       <p>
-         Apache Functor includes other objects that you can can use to code in
-         a less imperative way, like <em>Generators</em>. In the following
-         example, we create an <em>Integer Generator</em> that generates
-         integers from 1 to 4 (the right argument is non-inclusive). The
-         generator is wrapped within a <em>Filtered Generator</em> that applies
-         the isEven predicate to each integer generated by the former generator.
-         Finally, we execute a <em>Composite Unary Procedure</em> that uses
-         a function to double the value of the integer before printing it.
-       </p>
-<source>
-Generator&lt;Integer&gt; integerGenerator = new IntegerRange(1, 5); // inclusive, exclusive
-    
-UnaryPredicate&lt;Integer&gt; isEven = new UnaryPredicate&lt;Integer&gt;() {
-    public boolean test(Integer obj) {
-        return obj % 2 == 0;
-    }
-};
-
-FilteredGenerator&lt;Integer&gt; filteredGenerator = 
-        new FilteredGenerator&lt;Integer&gt;(integerGenerator, isEven);
-
-UnaryFunction&lt;Integer, Integer&gt; doubler = new UnaryFunction&lt;Integer, Integer&gt;() {
-    public Integer evaluate(Integer obj) {
-        return obj * 2;
-    }
-};
-
-UnaryProcedure&lt;Integer&gt; print = new UnaryProcedure&lt;Integer&gt;() {
-    public void run(Integer obj) {
-        System.out.print(obj + " ");
-    }
-};
-
-CompositeUnaryProcedure&lt;Integer&gt; compositeProcedure =
-        new CompositeUnaryProcedure&lt;Integer&gt;(print);
-
-filteredGenerator.run(compositeProcedure.of(doubler));
-</source>
-       <p>
-         The <a href="http://svn.apache.org/viewvc/commons/proper/functor/trunk/src/test/java/org/apache/commons/functor/example/lines/">lines</a>
-         package demonstrates a functional approach to IO using Generators and the Algorithms class.
-       </p>
-    </subsection>
-
-    <subsection name="Aggregators">
-      <p>
-         There are some code snippets / examples for the <code>org.apache.commons.functor.aggregator</code> package
-         available on <a href="aggregator.html">this page</a>. Also, to exemplify the usage of the <code>Aggregator</code>
-         classes, there are code examples in the test section.
-      </p>
-      <p>
-         First such set of example involves the usage of the <i>nostore</i> <code>Aggregator</code>. Code can be found in
-         <a href="http://svn.apache.org/viewvc/commons/proper/functor/trunk/src/test/java/org/apache/commons/functor/example/aggregator/nostore/">org.apache.commons.functor.example.aggregator.nostore</a>.
-         This shows how can you use an aggregator which doesn't store the data series and processes them on the fly.
-         Also, there are examples provided which show how can you implement your own aggregation function
-         to be used with this <code>Aggregator</code> type.
-      </p>
-      <p>
-         For using an <code>Aggregator</code> which stores the data series in a list, examples are in
-         <a href="http://svn.apache.org/viewvc/commons/proper/functor/trunk/src/test/java/org/apache/commons/functor/example/aggregator/list/">org.apache.commons.functor.example.aggregator.list</a>.
-         This shows how can you use the <code>ArrayList</code>-backed aggregator or provide your own <code>List</code>-based implementation.
-         Also, there are examples provided which show how can you implement your own aggregation function
-         to be used with this <code>Aggregator</code> type.
-      </p>
-    </subsection>
-
     <subsection name="Code Katas">
       <p>
         "Pragmatic" Dave Thomas has been

Added: commons/proper/functor/branches/generators-FUNCTOR-14/src/test/java/org/apache/commons/functor/generator/range/TestCharacterRange.java
URL: http://svn.apache.org/viewvc/commons/proper/functor/branches/generators-FUNCTOR-14/src/test/java/org/apache/commons/functor/generator/range/TestCharacterRange.java?rev=1385335&view=auto
==============================================================================
--- commons/proper/functor/branches/generators-FUNCTOR-14/src/test/java/org/apache/commons/functor/generator/range/TestCharacterRange.java (added)
+++ commons/proper/functor/branches/generators-FUNCTOR-14/src/test/java/org/apache/commons/functor/generator/range/TestCharacterRange.java Sun Sep 16 18:08:31 2012
@@ -0,0 +1,740 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.functor.generator.range;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.commons.functor.BaseFunctorTest;
+import org.apache.commons.functor.UnaryFunction;
+import org.apache.commons.functor.UnaryProcedure;
+import org.apache.commons.functor.generator.Generator;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * @version $Revision: $ $Date: $
+ */
+public class TestCharacterRange extends BaseFunctorTest {
+    // A base range with all chars between a and m
+    private final List<Character> fullRange = Collections.unmodifiableList(Arrays.asList('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm'));
+
+    // Attributes
+    // ------------------------------------------------------------------------
+
+    private CharacterRange ascCharRange = null;
+    private CharacterRange descCharRange = null;
+    private Collection<Character> expectedAsc = null;
+    private Collection<Character> expectedDesc = null;
+    
+    // Test set up
+    // ------------------------------------------------------------------------
+    @Before
+    public void setUp() {
+        ascCharRange = Ranges.characterRange('b', 'k');
+        descCharRange = Ranges.characterRange('k', 'b');
+    	expectedAsc = Arrays.asList('b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k');
+    	expectedDesc = Arrays.asList('k', 'j', 'i', 'h', 'g', 'f', 'e', 'd', 'c', 'b');
+    }
+    
+    @After
+    public void tearDown() {
+    	ascCharRange = null;
+    	descCharRange = null;
+    }
+    
+    @Override
+    protected Object makeFunctor()
+        throws Exception {
+        return Ranges.characterRange('b', 'k');
+    }
+
+    // Generator tests
+    // ---------------------------------------------------------------
+
+    @Test
+    public void testStepChecking() {
+        {
+            Ranges.characterRange('b', 'b', 0); // step of 0 is ok when range is
+                                             // empty
+        }
+        {
+            Ranges.characterRange('b', 'b', 1); // positive step is ok when range
+                                             // is empty
+        }
+        {
+            Ranges.characterRange('b', 'b', -1); // negative step is ok when range
+                                              // is empty
+        }
+        {
+            Ranges.characterRange('a', 'b', 10); // big steps are ok
+        }
+        {
+            Ranges.characterRange('b', 'a', -10); // big steps are ok
+        }
+        try {
+            Ranges.characterRange('a', 'b', 0);
+            fail("Expected IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        try {
+            Ranges.characterRange('a', 'b', -1);
+            fail("Expected IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        try {
+            Ranges.characterRange('b', 'a', 1);
+            fail("Expected IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+    }
+
+    @Test
+    public void testObjectConstructor() {
+        CharacterRange range = Ranges.characterRange(new Character('a'),
+                                                     new Character('e'));
+        assertEquals("[a, b, c, d, e]", range.toCollection().toString());
+        range = Ranges.characterRange(new Character('a'), new Character('e'),
+                                      new Integer(1));
+        assertEquals("[a, b, c, d, e]", range.toCollection().toString());
+    }
+
+    @Test
+    public void testReverseStep() {
+        CharacterRange range = Ranges.characterRange('k', 'a', -2);
+        assertEquals("[k, i, g, e, c, a]", range.toCollection().toString());
+        assertEquals("[k, i, g, e, c, a]", range.toCollection().toString());
+    }
+
+    @Test
+    public void testStep() {
+        CharacterRange range = Ranges.characterRange('a', 'k', 2);
+        assertEquals("[a, c, e, g, i, k]", range.toCollection().toString());
+        assertEquals("[a, c, e, g, i, k]", range.toCollection().toString());
+    }
+
+    @Test
+    public void testForwardRange() {
+        CharacterRange range = Ranges.characterRange('a', 'e');
+        assertEquals("[a, b, c, d, e]", range.toCollection().toString());
+        assertEquals("[a, b, c, d, e]", range.toCollection().toString());
+    }
+
+    @Test
+    public void testReverseRange() {
+        CharacterRange range = Ranges.characterRange('e', 'a');
+        assertEquals("[e, d, c, b, a]", range.toCollection().toString());
+        assertEquals("[e, d, c, b, a]", range.toCollection().toString());
+    }
+
+    // @Test
+    // public void testEdgeCase() {
+    // CharacterRange range = Ranges.characterRange(Character.MAX_VALUE-3,
+    // Character.MAX_VALUE);
+    // assertEquals("[2147483644, 2147483645, 2147483646]",
+    // range.toCollection().toString());
+    // assertEquals("[2147483644, 2147483645, 2147483646]",
+    // range.toCollection().toString());
+    // }
+
+    @Test
+    public void testBoundaries() {
+        CharacterRange range = Ranges.characterRange('b', 'l');
+        assertEquals(new Endpoint<Comparable<?>>('b', BoundType.CLOSED),
+                     range.getLeftEndpoint());
+        assertEquals(new Endpoint<Comparable<?>>('l', BoundType.CLOSED),
+                     range.getRightEndpoint());
+    }
+
+    @Test
+    public void testClosedClosedAscending() {
+        // [b, l], 3 = b, e, h, k
+        CharacterRange range =  Ranges.characterRange('b', BoundType.CLOSED, 'l', BoundType.CLOSED, 3);
+        // [b, l], 3 = b, e, h, k
+        List<Character> expected = Arrays.asList('b', 'e', 'h', 'k');
+        Collection<Character> elements = range.toCollection();
+        assertEquals(expected, elements);
+    }
+
+    @Test
+    public void testOpenClosedAscending() {
+        // (b, l], 3 = e, h, k
+        CharacterRange range =  Ranges.characterRange('b', BoundType.OPEN, 'l', BoundType.CLOSED, 3);
+        // (b, l], 3 = e, h, k
+        List<Character> expected = Arrays.asList('e', 'h', 'k');
+        Collection<Character> elements = range.toCollection();
+        assertEquals(expected, elements);
+    }
+
+    @Test
+    public void testClosedOpenAscending() {
+        // [b, l), 3 = b, e, h, k
+        CharacterRange range =  Ranges.characterRange('b', BoundType.CLOSED, 'l', BoundType.OPEN, 3);
+        // [b, l), 3 = b, e, h, k
+        List<Character> expected = Arrays.asList('b', 'e', 'h', 'k');
+        Collection<Character> elements = range.toCollection();
+        assertEquals(expected, elements);
+    }
+
+    @Test
+    public void testOpenOpenAscending() {
+        // (b, l), 3 = e, h, k
+        CharacterRange range =  Ranges.characterRange('b', BoundType.OPEN, 'l', BoundType.OPEN, 3);
+        // (b, l), 3 = e, h, k
+        List<Character> expected = Arrays.asList('e', 'h', 'k');
+        Collection<Character> elements = range.toCollection();
+        assertEquals(expected, elements);
+    }
+
+    @Test
+    public void testSingleStepAscending() {
+        // (d, h], 1 = e, f, g, h
+        CharacterRange range =  Ranges.characterRange('d', BoundType.OPEN, 'h', BoundType.CLOSED, 1);
+        // (d, h], 1 = e, f, g, h
+        List<Character> expected = Arrays.asList('e', 'f', 'g', 'h');
+        Collection<Character> elements = range.toCollection();
+        assertEquals(expected, elements);
+    }
+
+    @Test
+    public void testClosedClosedDescending() {
+        // [l, b], -3 = l, i, f, c
+        CharacterRange range = Ranges.characterRange('l', BoundType.CLOSED, 'b',
+                                                  BoundType.CLOSED, -3);
+        // [l, b], -3 = l, i, f, c
+        List<Character> expected = Arrays.asList('l', 'i', 'f', 'c');
+        Collection<Character> elements = range.toCollection();
+        assertEquals(expected, elements);
+    }
+
+    @Test
+    public void testOpenClosedDescending() {
+        // (l, b], -3 = i, f, c
+        CharacterRange range = Ranges.characterRange('l', BoundType.OPEN, 'b',
+                                                  BoundType.CLOSED, -3);
+        // (l, b], -3 = i, f, c
+        List<Character> expected = Arrays.asList('i', 'f', 'c');
+        Collection<Character> elements = range.toCollection();
+        assertEquals(expected, elements);
+    }
+
+    @Test
+    public void testClosedOpenDescending() {
+        // [l, b), -3 = l, i, f, c
+        CharacterRange range = Ranges.characterRange('l', BoundType.CLOSED, 'b',
+                                                  BoundType.OPEN, -3);
+        // [l, b), -3 = l, i, f, c
+        List<Character> expected = Arrays.asList('l', 'i', 'f', 'c');
+        Collection<Character> elements = range.toCollection();
+        assertEquals(expected, elements);
+    }
+
+    @Test
+    public void testOpenOpenDescending() {
+        // (l, b), -3 = i, f, c
+        CharacterRange range = Ranges.characterRange('l', BoundType.OPEN, 'b',
+                                                  BoundType.OPEN, -3);
+        // (l, b), -3 = i, f, c
+        List<Character> expected = Arrays.asList('i', 'f', 'c');
+        Collection<Character> elements = range.toCollection();
+        assertEquals(expected, elements);
+    }
+
+    @Test
+    public void testSingleStepDescending() {
+        // [h, d), -1 = h, g, f
+        CharacterRange range = Ranges.characterRange('h', BoundType.CLOSED, 'e',
+                                                  BoundType.OPEN, -1);
+        // [h, d), -1 = h, g, f
+        List<Character> expected = Arrays.asList('h', 'g', 'f');
+        Collection<Character> elements = range.toCollection();
+        assertEquals(expected, elements);
+    }
+
+    @Test
+    public void testAscending() {
+        final List<Character> list = new ArrayList<Character>();
+        ascCharRange.run(new UnaryProcedure<Character>() {
+
+            public void run(Character obj) {
+                list.add(obj);
+            }
+        });
+        assertTrue(expectedAsc.containsAll(list));
+    }
+
+    @Test
+    public void testDescending() {
+        final List<Character> list = new ArrayList<Character>();
+        descCharRange.run(new UnaryProcedure<Character>() {
+
+            public void run(Character obj) {
+                list.add(obj);
+            }
+        });
+        assertTrue(expectedDesc.containsAll(list));
+    }
+
+    @Test
+    public void testToCollection() {
+        Collection<Character> ascCol = ascCharRange.toCollection();
+        assertEquals("Different collections", expectedAsc, ascCol);
+        Collection<Character> descCol = descCharRange.toCollection();
+        assertEquals("Different collections", expectedDesc, descCol);
+    }
+
+    @Test
+    public void testTransformedGenerator() {
+        int expected = 10;
+        List<Character> list = ascCharRange
+            .to(new UnaryFunction<Generator<? extends Character>, List<Character>>() {
+
+                public List<Character> evaluate(Generator<? extends Character> obj) {
+                    List<Character> chars = new ArrayList<Character>();
+                    for (Object element : obj.toCollection()) {
+                        chars.add((Character) element);
+                    }
+                    return chars;
+                }
+            });
+        assertEquals(expected, list.size());
+        expected = 10;
+        list = descCharRange
+            .to(new UnaryFunction<Generator<? extends Character>, List<Character>>() {
+
+                public List<Character> evaluate(Generator<? extends Character> obj) {
+                    List<Character> chars = new ArrayList<Character>();
+                    for (Object element : obj.toCollection()) {
+                        chars.add((Character) element);
+                    }
+                    return chars;
+                }
+            });
+        assertEquals(expected, list.size());
+    }
+
+    // Range tests
+    // ---------------------------------------------------------------
+
+    @Test
+    public void testEmptyRanges() {
+        CharacterRange empty1 = Ranges.characterRange('a', BoundType.OPEN, 'b',
+                                                   BoundType.OPEN, 2);
+        assertTrue("The range was expected to be empty.", empty1.isEmpty());
+        CharacterRange empty2 = Ranges.characterRange('c', BoundType.OPEN, 'a',
+                                                   BoundType.OPEN, -2);
+        assertTrue("The range was expected to be empty.", empty2.isEmpty());
+        CharacterRange empty3 = Ranges.characterRange('a', BoundType.OPEN, 'b',
+                                                   BoundType.CLOSED, 2);
+        assertTrue("The range was expected to be empty.", empty3.isEmpty());
+        CharacterRange empty4 = Ranges.characterRange('a', BoundType.OPEN, 'a',
+                                                   BoundType.OPEN, 1);
+        assertTrue("The range was expected to be empty.", empty4.isEmpty());
+        CharacterRange empty5 = Ranges.characterRange('b', BoundType.CLOSED, 'b',
+                                                   BoundType.OPEN, 1);
+        assertTrue("The range was expected to be empty.", empty5.isEmpty());
+        CharacterRange empty6 = Ranges.characterRange('d', BoundType.OPEN, 'c',
+                                                   BoundType.CLOSED, -2);
+        assertTrue("The range was expected to be empty.", empty6.isEmpty());
+        CharacterRange notEmpty1 = Ranges.characterRange('a', BoundType.CLOSED,
+                                                      'a', BoundType.CLOSED, 1);
+        assertFalse("The range was not expected to be empty.",
+                    notEmpty1.isEmpty());
+        CharacterRange notEmpty2 = Ranges.characterRange('a', BoundType.OPEN, 'b',
+                                                      BoundType.CLOSED, 1);
+        assertFalse("The range was not expected to be empty.",
+                    notEmpty2.isEmpty());
+        CharacterRange notEmpty3 = Ranges.characterRange('b', BoundType.OPEN, 'a',
+                                                      BoundType.CLOSED, -1);
+        assertFalse("The range was not expected to be empty.",
+                    notEmpty3.isEmpty());
+        CharacterRange notEmpty4 = Ranges.characterRange('b', BoundType.CLOSED,
+                                                      'a', BoundType.OPEN, -1);
+        assertFalse("The range was not expected to be empty.",
+                    notEmpty4.isEmpty());
+        CharacterRange notEmpty5 = Ranges.characterRange('a', BoundType.CLOSED,
+                                                      'b', BoundType.OPEN, 1);
+        assertFalse("The range was not expected to be empty.",
+                    notEmpty5.isEmpty());
+    }
+
+    @Test
+    public void testClosedClosedAscendingContains() {
+        // [b, l], 3 = 'b', 'e', 'h', 'k'
+        CharacterRange range = Ranges.characterRange('b', BoundType.CLOSED, 'l',
+                                                  BoundType.CLOSED, 3);
+        // [b, l], 3 = 'b', 'e', 'h', 'k'
+        List<Character> arr = Arrays.asList('b', 'e', 'h', 'k');
+        for (Character element : arr) {
+            assertTrue("Expected element [" + element +
+                               "] is missing in range [" + range + "]",
+                       range.contains(element));
+        }
+        List<Character> elementsNotPresent = new ArrayList<Character>(fullRange);
+        elementsNotPresent.removeAll(arr);
+        for (Character element : elementsNotPresent) {
+            assertFalse("Unexpected element [" + element +
+                                "] is present in range [" + range + "]",
+                        range.contains(element));
+        }
+    }
+
+    @Test
+    public void testOpenClosedAscendingContains() {
+        // (b, l], 3 = 'e', 'h', 'k'
+        CharacterRange range = Ranges.characterRange('b', BoundType.OPEN, 'l',
+                                                  BoundType.CLOSED, 3);
+        // (b, l], 3 = 'e', 'h', 'k'
+        List<Character> arr = Arrays.asList('e', 'h', 'k');
+        for (Character element : arr) {
+            assertTrue("Expected element [" + element +
+                               "] is missing in range [" + range + "]",
+                       range.contains(element));
+        }
+        List<Character> elementsNotPresent = new ArrayList<Character>(fullRange);
+        elementsNotPresent.removeAll(arr);
+        for (Character element : elementsNotPresent) {
+            assertFalse("Unexpected element [" + element +
+                                "] is present in range [" + range + "]",
+                        range.contains(element));
+        }
+    }
+
+    @Test
+    public void testClosedOpenAscendingContains() {
+        // [b, l), 3 = 'b', 'e', 'h', 'k'
+        CharacterRange range = Ranges.characterRange('b', BoundType.CLOSED, 'l',
+                                                  BoundType.OPEN, 3);
+        // [b, l), 3 = 'b', 'e', 'h', 'k'
+        List<Character> arr = Arrays.asList('b', 'e', 'h', 'k');
+        for (Character element : arr) {
+            assertTrue("Expected element [" + element +
+                               "] is missing in range [" + range + "]",
+                       range.contains(element));
+        }
+        List<Character> elementsNotPresent = new ArrayList<Character>(fullRange);
+        elementsNotPresent.removeAll(arr);
+        for (Character element : elementsNotPresent) {
+            assertFalse("Unexpected element [" + element +
+                                "] is present in range [" + range + "]",
+                        range.contains(element));
+        }
+    }
+
+    @Test
+    public void testOpenOpenAscendingContains() {
+        // (b, l), 3 = 'e', 'h', 'k'
+        CharacterRange range = Ranges.characterRange('b', BoundType.OPEN, 'l',
+                                                  BoundType.OPEN, 3);
+        // (b, l), 3 = 'e', 'h', 'k'
+        List<Character> arr = Arrays.asList('e', 'h', 'k');
+        for (Character element : arr) {
+            assertTrue("Expected element [" + element +
+                               "] is missing in range [" + range + "]",
+                       range.contains(element));
+        }
+        List<Character> elementsNotPresent = new ArrayList<Character>(fullRange);
+        elementsNotPresent.removeAll(arr);
+        for (Character element : elementsNotPresent) {
+            assertFalse("Unexpected element [" + element +
+                                "] is present in range [" + range + "]",
+                        range.contains(element));
+        }
+    }
+
+    @Test
+    public void testContainsSingleStepAscending() {
+        // (b, l], 1 = 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l'
+        CharacterRange ascendingRange = Ranges.characterRange('b', BoundType.OPEN,
+                                                           'l',
+                                                           BoundType.CLOSED, 1);
+        // (b, l], 1 = 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l'
+        List<Character> arr = Arrays.asList('c', 'd', 'e', 'f', 'g', 'h', 'i',
+                                            'j', 'k', 'l');
+        for (Character element : arr) {
+            assertTrue("Expected element [" + element +
+                               "] is missing in range [" + ascendingRange + "]",
+                       ascendingRange.contains(element));
+        }
+        List<Character> elementsNotPresent = new ArrayList<Character>(fullRange);
+        elementsNotPresent.removeAll(arr);
+        for (Character element : elementsNotPresent) {
+            assertFalse("Unexpected element [" + element +
+                                "] is present in range [" + ascendingRange +
+                                "]",
+                        ascendingRange.contains(element));
+        }
+    }
+
+    @Test
+    public void testClosedClosedDescendingContains() {
+        // [l, b], -3 = 'l', 'i', 'f', 'c'
+        CharacterRange range = Ranges.characterRange('l', BoundType.CLOSED, 'b',
+                                                  BoundType.CLOSED, -3);
+        // [l, b], -3 = 'l', 'i', 'f', 'c'
+        List<Character> arr = Arrays.asList('l', 'i', 'f', 'c');
+        for (Character element : arr) {
+            assertTrue("Expected element [" + element +
+                               "] is missing in range [" + range + "]",
+                       range.contains(element));
+        }
+        List<Character> elementsNotPresent = new ArrayList<Character>(fullRange);
+        elementsNotPresent.removeAll(arr);
+        for (Character element : elementsNotPresent) {
+            assertFalse("Unexpected element [" + element +
+                                "] is present in range [" + range + "]",
+                        range.contains(element));
+        }
+    }
+
+    @Test
+    public void testOpenClosedDescendingContains() {
+        // (l, b], -3 = 'i', 'f', 'c'
+        CharacterRange range = Ranges.characterRange('l', BoundType.OPEN, 'b',
+                                                  BoundType.CLOSED, -3);
+        // (l, b], -3 = 'i', 'f', 'c'
+        List<Character> arr = Arrays.asList('i', 'f', 'c');
+        for (Character element : arr) {
+            assertTrue("Expected element [" + element +
+                               "] is missing in range [" + range + "]",
+                       range.contains(element));
+        }
+        List<Character> elementsNotPresent = new ArrayList<Character>(fullRange);
+        elementsNotPresent.removeAll(arr);
+        for (Character element : elementsNotPresent) {
+            assertFalse("Unexpected element [" + element +
+                                "] is present in range [" + range + "]",
+                        range.contains(element));
+        }
+    }
+
+    @Test
+    public void testClosedOpenDescendingContains() {
+        // [l, b), -3 = 'l', 'i', 'f', 'c'
+        CharacterRange range = Ranges.characterRange('l', BoundType.CLOSED, 'b',
+                                                  BoundType.OPEN, -3);
+        // [l, b), -3 = 'l', 'i', 'f', 'c'
+        List<Character> arr = Arrays.asList('l', 'i', 'f', 'c');
+        for (Character element : arr) {
+            assertTrue("Expected element [" + element +
+                               "] is missing in range [" + range + "]",
+                       range.contains(element));
+        }
+        List<Character> elementsNotPresent = new ArrayList<Character>(fullRange);
+        elementsNotPresent.removeAll(arr);
+        for (Character element : elementsNotPresent) {
+            assertFalse("Unexpected element [" + element +
+                                "] is present in range [" + range + "]",
+                        range.contains(element));
+        }
+    }
+
+    @Test
+    public void testOpenOpenDescendingContains() {
+        // (l, b), -3 = 'i', 'f', 'c'
+        CharacterRange range = Ranges.characterRange('l', BoundType.OPEN, 'b',
+                                                  BoundType.OPEN, -3);
+        // (l, b), -3 = 'i', 'f', 'c'
+        List<Character> arr = Arrays.asList('i', 'f', 'c');
+        for (Character element : arr) {
+            assertTrue("Expected element [" + element +
+                               "] is missing in range [" + range + "]",
+                       range.contains(element));
+        }
+        List<Character> elementsNotPresent = new ArrayList<Character>(fullRange);
+        elementsNotPresent.removeAll(arr);
+        for (Character element : elementsNotPresent) {
+            assertFalse("Unexpected element [" + element +
+                                "] is present in range [" + range + "]",
+                        range.contains(element));
+        }
+    }
+
+    @Test
+    public void testContainsSingleStepDescending() {
+        // [l, b), -1 = 'l', 'k', 'j', 'i', 'h', 'g', 'f', 'e', 'd', 'c'
+        CharacterRange descendingRange = Ranges.characterRange('l',
+                                                            BoundType.CLOSED,
+                                                            'b',
+                                                            BoundType.OPEN, -1);
+        // [l, b), -1 = 'l', 'k', 'j', 'i', 'h', 'g', 'f', 'e', 'd', 'c'
+        List<Character> arr = Arrays.asList('l', 'k', 'j', 'i', 'h', 'g', 'f',
+                                            'e', 'd', 'c');
+        for (Character element : arr) {
+            assertTrue("Expected element [" + element +
+                               "] is missing in range [" + descendingRange +
+                               "]",
+                       descendingRange.contains(element));
+        }
+        List<Character> elementsNotPresent = new ArrayList<Character>(fullRange);
+        elementsNotPresent.removeAll(arr);
+        for (Character element : elementsNotPresent) {
+            assertFalse("Unexpected element [" + element +
+                                "] is present in range [" + descendingRange +
+                                "]",
+                        descendingRange.contains(element));
+        }
+    }
+
+    @Test
+    public void testContainsNullOrEmpty() {
+        CharacterRange range = Ranges.characterRange('a', BoundType.OPEN, 'r',
+                                                  BoundType.CLOSED, 1);
+        assertFalse(range.contains(null));
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testContainsAll() {
+        // (c, g], 1 = d, e, f, g
+        CharacterRange range = Ranges.characterRange('c', BoundType.OPEN, 'g',
+                                                  BoundType.CLOSED, 1);
+        List<Character> list = Arrays.asList('d', 'e', 'f', 'g');
+        assertTrue("Range [" + range +
+                   "] was expected to contain all elements from list [" + list +
+                   "]", range.containsAll(list));
+        List<Character> listWithExtraElements = Arrays.asList('a', 'd', 'e',
+                                                              'f', 'g', 'z');
+        assertFalse("Range [" + range + "] has more elements than expected",
+                    range.containsAll(listWithExtraElements));
+        assertFalse(range.containsAll(null));
+        assertFalse(range.containsAll(Collections.EMPTY_LIST));
+    }
+
+    @Test
+    public void testEquals()
+        throws Exception {
+        // equals basic properties
+        CharacterRange range = Ranges.characterRange('a', BoundType.CLOSED, 'e',
+                                                  BoundType.OPEN, 1);
+        assertEquals("equals must be reflexive", range, range);
+        assertEquals("hashCode must be reflexive", range.hashCode(),
+                     range.hashCode());
+        assertTrue(!range.equals(null)); // should be able to compare to null
+
+        Object range2 = Ranges.characterRange('a', BoundType.CLOSED, 'e',
+                                           BoundType.OPEN, 1);
+        if (range.equals(range2)) {
+            assertEquals("equals implies hash equals", range.hashCode(),
+                         range2.hashCode());
+            assertEquals("equals must be symmetric", range2, range);
+        } else {
+            assertTrue("equals must be symmetric", !range2.equals(range));
+        }
+
+        // Changing attributes
+        Object range3 = Ranges.characterRange('c', BoundType.CLOSED, 'e',
+                                           BoundType.OPEN, 1);
+        assertFalse("Invalid equals after changing attributes",
+                    range.equals(range3));
+
+        Object range4 = Ranges.characterRange('a', BoundType.OPEN, 'e',
+                                           BoundType.OPEN, 1);
+        assertFalse("Invalid equals after changing attributes",
+                    range.equals(range4));
+
+        Object range5 = Ranges.characterRange('a', BoundType.CLOSED, 'r',
+                                           BoundType.OPEN, 1);
+        assertFalse("Invalid equals after changing attributes",
+                    range.equals(range5));
+
+        Object range6 = Ranges.characterRange('a', BoundType.CLOSED, 'e',
+                                           BoundType.CLOSED, 1);
+        assertFalse("Invalid equals after changing attributes",
+                    range.equals(range6));
+
+        Object range7 = Ranges.characterRange('a', BoundType.CLOSED, 'e',
+                                           BoundType.OPEN, 2);
+        assertFalse("Invalid equals after changing attributes",
+                    range.equals(range7));
+
+        // Using different constructors
+        Endpoint<Character> leftEndpoint = new Endpoint<Character>(
+                                                                   'a',
+                                                                   BoundType.CLOSED);
+        Endpoint<Character> rightEndpoint = new Endpoint<Character>(
+                                                                    'e',
+                                                                    BoundType.OPEN);
+        CharacterRange range8 = Ranges.characterRange(leftEndpoint, rightEndpoint,
+                                                   1);
+        assertEquals("Invalid equals using different constructor", range,
+                     range8);
+    }
+
+    @Test
+    public void testToString() {
+        CharacterRange range = Ranges.characterRange('a', BoundType.OPEN, 'b',
+                                                  BoundType.CLOSED, 1);
+        assertEquals("Wrong string value", "CharacterRange<(a, b], 1>",
+                     range.toString());
+    }
+
+    @Test
+    public void testConstructorUsingSameEndpoint() {
+        Endpoint<Character> uniqueEndpoint = new Endpoint<Character>(
+                                                                     'a',
+                                                                     BoundType.CLOSED);
+        try {
+            Ranges.characterRange(uniqueEndpoint, uniqueEndpoint, 1);
+        } catch (IllegalArgumentException e) {
+            fail("Not expected to get here");
+        }
+    }
+
+    @Test
+    public void testInvalidRange() {
+        try {
+            Ranges.characterRange('a', BoundType.OPEN, 'z', BoundType.CLOSED, -100);
+            fail("Not expected to get here");
+        } catch (IllegalArgumentException e) {
+            // Do nothing
+        }
+        Endpoint<Character> leftEndpoint = new Endpoint<Character>(
+                                                                   'a',
+                                                                   BoundType.CLOSED);
+        Endpoint<Character> rightEndpoint = new Endpoint<Character>(
+                                                                    'z',
+                                                                    BoundType.OPEN);
+        try {
+            Ranges.characterRange(leftEndpoint, rightEndpoint, -100);
+            fail("Not expected to get here");
+        } catch (IllegalArgumentException e) {
+            // Do nothing
+        }
+    }
+
+    @Test
+    public void testDefaultStep() {
+        assertEquals("Invalid default step", Integer.valueOf(-1),
+                     CharacterRange.DEFAULT_STEP.evaluate('c', 'a'));
+        assertEquals("Invalid default step", Integer.valueOf(1),
+                     CharacterRange.DEFAULT_STEP.evaluate('a', 'c'));
+    }
+
+}

Propchange: commons/proper/functor/branches/generators-FUNCTOR-14/src/test/java/org/apache/commons/functor/generator/range/TestCharacterRange.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: commons/proper/functor/branches/generators-FUNCTOR-14/src/test/java/org/apache/commons/functor/generator/range/TestDoubleRange.java
URL: http://svn.apache.org/viewvc/commons/proper/functor/branches/generators-FUNCTOR-14/src/test/java/org/apache/commons/functor/generator/range/TestDoubleRange.java?rev=1385335&view=auto
==============================================================================
--- commons/proper/functor/branches/generators-FUNCTOR-14/src/test/java/org/apache/commons/functor/generator/range/TestDoubleRange.java (added)
+++ commons/proper/functor/branches/generators-FUNCTOR-14/src/test/java/org/apache/commons/functor/generator/range/TestDoubleRange.java Sun Sep 16 18:08:31 2012
@@ -0,0 +1,787 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.functor.generator.range;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.commons.functor.BaseFunctorTest;
+import org.apache.commons.functor.UnaryFunction;
+import org.apache.commons.functor.UnaryProcedure;
+import org.apache.commons.functor.generator.Generator;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests for double range.
+ * 
+ * @since 1.0
+ * @version $Revision: $ $Date: $
+ */
+public class TestDoubleRange extends BaseFunctorTest {
+
+    // A base range with all longs between -6 and 6
+    private final List<Double> fullRange = Collections.unmodifiableList(Arrays
+        .asList(-6.0, -5.0, -4.0, -3.0, -2.0, -1.0, 0.0, 1.0, 2.0, 3.0, 4.0,
+                5.0, 6.0));
+
+    // Attributes
+    // ------------------------------------------------------------------------
+    private DoubleRange ascDoubleRange = null;
+    private DoubleRange descDoubleRange = null;
+    private Collection<Double> expectedAsc = null;
+    private Collection<Double> expectedDesc = null;
+
+    // Test set up
+    // ------------------------------------------------------------------------
+    @Before
+    public void setUp() {
+        ascDoubleRange = Ranges.doubleRange(0.0d, 10.0d);
+        descDoubleRange = Ranges.doubleRange(10.0d, 0.0d);
+        expectedAsc = Arrays.asList(0.0d, 1.0d, 2.0d, 3.0d, 4.0d, 5.0d, 6.0d,
+                                    7.0d, 8.0d, 9.0d);
+        expectedDesc = Arrays.asList(10.0d, 9.0d, 8.0d, 7.0d, 6.0d, 5.0d, 4.0d,
+                                     3.0d, 2.0d, 1.0d);
+    }
+
+    @After
+    public void tearDown() {
+        ascDoubleRange = null;
+        descDoubleRange = null;
+    }
+
+    @Override
+    protected Object makeFunctor()
+        throws Exception {
+        return Ranges.doubleRange(10, 20);
+    }
+
+    // Generator tests
+    // ---------------------------------------------------------------
+
+    @Test
+    public void testGenerateListExample() {
+        // generates a collection of Doubles from 0 (inclusive) to 10
+        // (exclusive)
+        {
+            List<? super Double> list = (List<? super Double>) (Ranges.doubleRange(
+                                                                                    0,
+                                                                                    10)
+                .to(new ArrayList<Double>()));
+            for (int i = 0; i < 10; i++) {
+                assertEquals(new Double(i), list.get(i));
+            }
+        }
+
+        // generates a collection of Doubles from 10 (inclusive) to 0
+        // (exclusive)
+        {
+            List<? super Double> list = (List<? super Double>) (Ranges.doubleRange(
+                                                                                    10,
+                                                                                    0)
+                .to(new ArrayList<Double>()));
+            for (int i = 10; i > 0; i--) {
+                assertEquals(new Double(i), list.get(10 - i));
+            }
+        }
+    }
+
+    @Test
+    public void testStepChecking() {
+        {
+            Ranges.doubleRange(2, 2, 0); // step of 0 is ok when range is empty
+        }
+        {
+            Ranges.doubleRange(2, 2, 1); // positive step is ok when range is
+                                          // empty
+        }
+        {
+            Ranges.doubleRange(2, 2, -1); // negative step is ok when range is
+                                           // empty
+        }
+        {
+            Ranges.doubleRange(0, 1, 10); // big steps are ok
+        }
+        {
+            Ranges.doubleRange(1, 0, -10); // big steps are ok
+        }
+        try {
+            Ranges.doubleRange(0, 1, 0);
+            fail("Expected IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        try {
+            Ranges.doubleRange(0, 1, -1);
+            fail("Expected IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        try {
+            Ranges.doubleRange(0, -1, 1);
+            fail("Expected IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+    }
+
+    @Test
+    public void testObjectConstructor() {
+        DoubleRange range = Ranges.doubleRange(new Double(0),
+                                                    new Double(5));
+        assertEquals("[0.0, 1.0, 2.0, 3.0, 4.0]", range.toCollection()
+            .toString());
+        range = Ranges.doubleRange(new Double(0), new Double(5), new Double(1));
+        assertEquals("[0.0, 1.0, 2.0, 3.0, 4.0]", range.toCollection()
+            .toString());
+    }
+
+    @Test
+    public void testReverseStep() {
+        DoubleRange range = Ranges.doubleRange(10, 0, -2);
+        assertEquals("[10.0, 8.0, 6.0, 4.0, 2.0]", range.toCollection()
+            .toString());
+        assertEquals("[10.0, 8.0, 6.0, 4.0, 2.0]", range.toCollection()
+            .toString());
+    }
+
+    @Test
+    public void testStep() {
+        DoubleRange range = Ranges.doubleRange(0, 10, 2);
+        assertEquals("[0.0, 2.0, 4.0, 6.0, 8.0]", range.toCollection()
+            .toString());
+        assertEquals("[0.0, 2.0, 4.0, 6.0, 8.0]", range.toCollection()
+            .toString());
+    }
+
+    @Test
+    public void testForwardRange() {
+        DoubleRange range = Ranges.doubleRange(0, 5);
+        assertEquals("[0.0, 1.0, 2.0, 3.0, 4.0]", range.toCollection()
+            .toString());
+        assertEquals("[0.0, 1.0, 2.0, 3.0, 4.0]", range.toCollection()
+            .toString());
+    }
+
+    @Test
+    public void testReverseRange() {
+        DoubleRange range = Ranges.doubleRange(5, 0);
+        assertEquals("[5.0, 4.0, 3.0, 2.0, 1.0]", range.toCollection()
+            .toString());
+        assertEquals("[5.0, 4.0, 3.0, 2.0, 1.0]", range.toCollection()
+            .toString());
+    }
+
+    // @Test
+    // public void testEdgeCase() {
+    // DoubleRange range = Ranges.doubleRange(Double.MAX_VALUE - 3.0d,
+    // Double.MAX_VALUE);
+    // assertEquals("[9223372036854775804, 9223372036854775805, 9223372036854775806]",
+    // range.toCollection().toString());
+    // assertEquals("[9223372036854775804, 9223372036854775805, 9223372036854775806]",
+    // range.toCollection().toString());
+    // }
+
+    @Test
+    public void testBoundaries() {
+        DoubleRange range = Ranges.doubleRange(0.0d, 10.0d);
+        assertEquals(new Endpoint<Comparable<?>>(0.0d, BoundType.CLOSED),
+                     range.getLeftEndpoint());
+        assertEquals(new Endpoint<Comparable<?>>(10.0d, BoundType.OPEN),
+                     range.getRightEndpoint());
+    }
+
+    @Test
+    public void testClosedClosedAscending() {
+        // [-5.0d, 5.0d], 3.0d = -5.0d, -2.0d, 1.0d, 4.0d
+        DoubleRange range = Ranges.doubleRange(-5.0d, BoundType.CLOSED, 5.0d,
+                                            BoundType.CLOSED, 3.0d);
+        // [-5.0d, 5.0d], 3.0d = -5.0d, -2.0d, 1.0d, 4.0d
+        List<Double> expected = Arrays.asList(-5.0d, -2.0d, 1.0d, 4.0d);
+        Collection<Double> elements = range.toCollection();
+        assertEquals(expected, elements);
+    }
+
+    @Test
+    public void testOpenClosedAscending() {
+        // (-5.0d, 5.0d], 3.0d = -2.0d, 1.0d, 4.0d
+        DoubleRange range = Ranges.doubleRange(-5.0d, BoundType.OPEN, 5.0d,
+                                            BoundType.CLOSED, 3.0d);
+        // (-5.0d, 5.0d], 3.0d = -2.0d, 1.0d, 4.0d
+        List<Double> expected = Arrays.asList(-2.0d, 1.0d, 4.0d);
+        Collection<Double> elements = range.toCollection();
+        assertEquals(expected, elements);
+    }
+
+    @Test
+    public void testClosedOpenAscending() {
+        // [-5.0d, 5.0d), 3.0d = -5.0d, -2.0d, 1.0d, 4.0d
+        DoubleRange range = Ranges.doubleRange(-5.0d, BoundType.CLOSED, 5.0d,
+                                            BoundType.OPEN, 3.0d);
+        // (-5.0d, 5.0d], 3.0d = -5.0d, -2.0d, 1.0d, 4.0d
+        List<Double> expected = Arrays.asList(-5.0d, -2.0d, 1.0d, 4.0d);
+        Collection<Double> elements = range.toCollection();
+        assertEquals(expected, elements);
+    }
+
+    @Test
+    public void testOpenOpenAscending() {
+        // (-5.0d, 5.0d), 3.0d = -2.0d, 1.0d, 4.0d
+        DoubleRange range = Ranges.doubleRange(-5.0d, BoundType.OPEN, 5.0d,
+                                            BoundType.OPEN, 3.0d);
+        // (-5.0d, 5.0d), 3.0d = -2.0d, 1.0d, 4.0d
+        List<Double> expected = Arrays.asList(-2.0d, 1.0d, 4.0d);
+        Collection<Double> elements = range.toCollection();
+        assertEquals(expected, elements);
+    }
+
+    @Test
+    public void testSingleStepAscending() {
+        // (-2.0d, 2.0d], 1.0d = -1.0d, 0.0d, 1.0d, 2.0d
+        DoubleRange range = Ranges.doubleRange(-2.0d, BoundType.OPEN, 2.0d,
+                                            BoundType.CLOSED, 1.0d);
+        // (-2.0d, 2.0d], 1.0d = -1.0d, 0.0d, 1.0d, 2.0d
+        List<Double> expected = Arrays.asList(-1.0d, 0.0d, 1.0d, 2.0d);
+        Collection<Double> elements = range.toCollection();
+        assertEquals(expected, elements);
+    }
+
+    @Test
+    public void testClosedClosedDescending() {
+        // [5.0d, -5.0d], -3.0d = 5.0d, 2.0d, -1.0d, -4.0d
+        DoubleRange range = Ranges.doubleRange(5.0d, BoundType.CLOSED, -5.0d,
+                                            BoundType.CLOSED, -3.0d);
+        // [5.0d, -5.0d], -3.0d = 5.0d, 2.0d, -1.0d, -4.0d
+        List<Double> expected = Arrays.asList(5.0d, 2.0d, -1.0d, -4.0d);
+        Collection<Double> elements = range.toCollection();
+        assertEquals(expected, elements);
+    }
+
+    @Test
+    public void testOpenClosedDescending() {
+        // (5.0d, -5.0d], -3.0d = 2.0d, -1.0d, -4.0d
+        DoubleRange range = Ranges.doubleRange(5.0d, BoundType.OPEN, -5.0d,
+                                            BoundType.CLOSED, -3.0d);
+        // (5.0d, -5.0d], -3.0d = 2.0d, -1.0d, -4.0d
+        List<Double> expected = Arrays.asList(2.0d, -1.0d, -4.0d);
+        Collection<Double> elements = range.toCollection();
+        assertEquals(expected, elements);
+    }
+
+    @Test
+    public void testClosedOpenDescending() {
+        // [5.0d, -5.0d), -3.0d = 5.0d, 2.0d, -1.0d, -4.0d
+        DoubleRange range = Ranges.doubleRange(5.0d, BoundType.CLOSED, -5.0d,
+                                            BoundType.OPEN, -3.0d);
+        // [5.0d, -5.0d), -3.0d = 5.0d, 2.0d, -1.0d, -4.0d
+        List<Double> expected = Arrays.asList(5.0d, 2.0d, -1.0d, -4.0d);
+        Collection<Double> elements = range.toCollection();
+        assertEquals(expected, elements);
+    }
+
+    @Test
+    public void testOpenOpenDescending() {
+        // (5.0d, -5.0d), -3.0d = 2.0d, -1.0d, -4.0d
+        DoubleRange range = Ranges.doubleRange(5.0d, BoundType.OPEN, -5.0d,
+                                            BoundType.OPEN, -3.0d);
+        // (5.0d, -5.0d), -3.0d = 2.0d, -1.0d, -4.0d
+        List<Double> expected = Arrays.asList(2.0d, -1.0d, -4.0d);
+        Collection<Double> elements = range.toCollection();
+        assertEquals(expected, elements);
+    }
+
+    @Test
+    public void testSingleStepDescending() {
+        // [2.0d, -2.0d), -1.0d = 2.0d, 1.0d, 0.0d, -1.0d
+        DoubleRange range = Ranges.doubleRange(2.0d, BoundType.CLOSED, -2.0d,
+                                            BoundType.OPEN, -1.0d);
+        // [2.0d, -2.0d), -1.0d = 2.0d, 1.0d, 0.0d, -1.0d
+        List<Double> expected = Arrays.asList(2.0d, 1.0d, 0.0d, -1.0d);
+        Collection<Double> elements = range.toCollection();
+        assertEquals(expected, elements);
+    }
+
+    @Test
+    public void testAscending() {
+        final List<Double> list = new ArrayList<Double>();
+        ascDoubleRange.run(new UnaryProcedure<Double>() {
+
+            public void run(Double obj) {
+                list.add(obj);
+            }
+        });
+        assertTrue(expectedAsc.containsAll(list));
+    }
+
+    @Test
+    public void testDescending() {
+        final List<Double> list = new ArrayList<Double>();
+        descDoubleRange.run(new UnaryProcedure<Double>() {
+
+            public void run(Double obj) {
+                list.add(obj);
+            }
+        });
+        assertTrue(expectedDesc.containsAll(list));
+    }
+
+    @Test
+    public void testToCollection() {
+        Collection<Double> ascCol = ascDoubleRange.toCollection();
+        assertEquals("Different collections", expectedAsc, ascCol);
+        Collection<Double> descCol = descDoubleRange.toCollection();
+        assertEquals("Different collections", expectedDesc, descCol);
+    }
+
+    @Test
+    public void testTransformedGenerator() {
+        double expected = 45.0d;
+        double total = ascDoubleRange
+            .to(new UnaryFunction<Generator<? extends Double>, Double>() {
+
+                public Double evaluate(Generator<? extends Double> obj) {
+                    double total = 0.0d;
+                    for (Object element : obj.toCollection()) {
+                        total += (Double) element;
+                    }
+                    return total;
+                }
+            });
+        assertTrue(expected == total);
+        expected = 55.0d;
+        total = descDoubleRange
+            .to(new UnaryFunction<Generator<? extends Double>, Double>() {
+
+                public Double evaluate(Generator<? extends Double> obj) {
+                    double total = 0.0d;
+                    for (Object element : obj.toCollection()) {
+                        total += (Double) element;
+                    }
+                    return total;
+                }
+            });
+        assertTrue(expected == total);
+    }
+
+    // Range tests
+    // ---------------------------------------------------------------
+
+    @Test
+    public void testEmptyRanges() {
+        DoubleRange empty1 = Ranges.doubleRange(-2, BoundType.OPEN, -1,
+                                             BoundType.OPEN, 2);
+        assertTrue("The range was expected to be empty.", empty1.isEmpty());
+        DoubleRange empty2 = Ranges.doubleRange(2, BoundType.OPEN, 0,
+                                             BoundType.OPEN, -2);
+        assertTrue("The range was expected to be empty.", empty2.isEmpty());
+        DoubleRange empty3 = Ranges.doubleRange(0, BoundType.OPEN, 1,
+                                             BoundType.CLOSED, 2);
+        assertTrue("The range was expected to be empty.", empty3.isEmpty());
+        DoubleRange empty4 = Ranges.doubleRange(-3, BoundType.OPEN, -3,
+                                             BoundType.OPEN, 1);
+        assertTrue("The range was expected to be empty.", empty4.isEmpty());
+        DoubleRange empty5 = Ranges.doubleRange(-3, BoundType.CLOSED, -3,
+                                             BoundType.OPEN, 1);
+        assertTrue("The range was expected to be empty.", empty5.isEmpty());
+        DoubleRange empty6 = Ranges.doubleRange(1, BoundType.OPEN, 0,
+                                             BoundType.CLOSED, -2);
+        assertTrue("The range was expected to be empty.", empty6.isEmpty());
+        DoubleRange notEmpty1 = Ranges.doubleRange(-3, BoundType.CLOSED, -3,
+                                                BoundType.CLOSED, 1);
+        assertFalse("The range was not expected to be empty.",
+                    notEmpty1.isEmpty());
+        DoubleRange notEmpty2 = Ranges.doubleRange(-3, BoundType.OPEN, -2,
+                                                BoundType.CLOSED, 1);
+        assertFalse("The range was not expected to be empty.",
+                    notEmpty2.isEmpty());
+        DoubleRange notEmpty3 = Ranges.doubleRange(2, BoundType.OPEN, 1,
+                                                BoundType.CLOSED, -1);
+        assertFalse("The range was not expected to be empty.",
+                    notEmpty3.isEmpty());
+        DoubleRange notEmpty4 = Ranges.doubleRange(2, BoundType.CLOSED, 1,
+                                                BoundType.OPEN, -1);
+        assertFalse("The range was not expected to be empty.",
+                    notEmpty4.isEmpty());
+        DoubleRange notEmpty5 = Ranges.doubleRange(1, BoundType.CLOSED, 2,
+                                                BoundType.OPEN, 1);
+        assertFalse("The range was not expected to be empty.",
+                    notEmpty5.isEmpty());
+    }
+
+    @Test
+    public void testClosedClosedAscendingContains() {
+        // [-5, 5], 3 = -5, -2, 1, 4
+        DoubleRange range = Ranges.doubleRange(-5, BoundType.CLOSED, 5,
+                                            BoundType.CLOSED, 3);
+        // [-5, 5], 3 = -5, -2, 1, 4
+        List<Double> arr = Arrays.asList(-5.0, -2.0, 1.0, 4.0);
+        for (Double element : arr) {
+            assertTrue("Expected element [" + element +
+                               "] is missing in range [" + range + "]",
+                       range.contains(element));
+        }
+        List<Double> elementsNotPresent = new ArrayList<Double>(fullRange);
+        elementsNotPresent.removeAll(arr);
+        for (Double element : elementsNotPresent) {
+            assertFalse("Unexpected element [" + element +
+                                "] is present in range [" + range + "]",
+                        range.contains(element));
+        }
+    }
+
+    @Test
+    public void testOpenClosedAscendingContains() {
+        // (-5, 5], 3 = -2, 1, 4
+        DoubleRange range = Ranges.doubleRange(-5, BoundType.OPEN, 5,
+                                            BoundType.CLOSED, 3);
+        // (-5, 5], 3 = -2, 1, 4
+        List<Double> arr = Arrays.asList(-2.0, 1.0, 4.0);
+        for (Double element : arr) {
+            assertTrue("Expected element [" + element +
+                               "] is missing in range [" + range + "]",
+                       range.contains(element));
+        }
+        List<Double> elementsNotPresent = new ArrayList<Double>(fullRange);
+        elementsNotPresent.removeAll(arr);
+        for (Double element : elementsNotPresent) {
+            assertFalse("Unexpected element [" + element +
+                                "] is present in range [" + range + "]",
+                        range.contains(element));
+        }
+    }
+
+    @Test
+    public void testClosedOpenAscendingContains() {
+        // [-5, 5), 3 = -5, -2, 1, 4
+        DoubleRange range = Ranges.doubleRange(-5, BoundType.CLOSED, 5,
+                                            BoundType.OPEN, 3);
+        // (-5, 5], 3 = -5, -2, 1, 4
+        List<Double> arr = Arrays.asList(-5.0, -2.0, 1.0, 4.0);
+        for (Double element : arr) {
+            assertTrue("Expected element [" + element +
+                               "] is missing in range [" + range + "]",
+                       range.contains(element));
+        }
+        List<Double> elementsNotPresent = new ArrayList<Double>(fullRange);
+        elementsNotPresent.removeAll(arr);
+        for (Double element : elementsNotPresent) {
+            assertFalse("Unexpected element [" + element +
+                                "] is present in range [" + range + "]",
+                        range.contains(element));
+        }
+    }
+
+    @Test
+    public void testOpenOpenAscendingContains() {
+        // (-5, 5), 3 = -2, 1, 4
+        DoubleRange range = Ranges.doubleRange(-5, BoundType.OPEN, 5,
+                                            BoundType.OPEN, 3);
+        // (-5, 5), 3 = -2, 1, 4
+        List<Double> arr = Arrays.asList(-2.0, 1.0, 4.0);
+        for (Double element : arr) {
+            assertTrue("Expected element [" + element +
+                               "] is missing in range [" + range + "]",
+                       range.contains(element));
+        }
+        List<Double> elementsNotPresent = new ArrayList<Double>(fullRange);
+        elementsNotPresent.removeAll(arr);
+        for (Double element : elementsNotPresent) {
+            assertFalse("Unexpected element [" + element +
+                                "] is present in range [" + range + "]",
+                        range.contains(element));
+        }
+    }
+
+    @Test
+    public void testContainsSingleStepAscending() {
+        // (-2, 2], 1 = -1, 0, 1, 2
+        DoubleRange ascendingRange = Ranges.doubleRange(-2, BoundType.OPEN, 2,
+                                                     BoundType.CLOSED, 1);
+        // (-2, 2], 1 = -1, 0, 1, 2
+        List<Double> arr = Arrays.asList(-1.0, 0.0, 1.0, 2.0);
+        for (Double element : arr) {
+            assertTrue("Expected element [" + element +
+                               "] is missing in range [" + ascendingRange + "]",
+                       ascendingRange.contains(element));
+        }
+        List<Double> elementsNotPresent = new ArrayList<Double>(fullRange);
+        elementsNotPresent.removeAll(arr);
+        for (Double element : elementsNotPresent) {
+            assertFalse("Unexpected element [" + element +
+                                "] is present in range [" + ascendingRange +
+                                "]",
+                        ascendingRange.contains(element));
+        }
+    }
+
+    @Test
+    public void testClosedClosedDescendingContains() {
+        // [5, -5], -3 = 5, 2, -1, -4
+        DoubleRange range = Ranges.doubleRange(5, BoundType.CLOSED, -5,
+                                            BoundType.CLOSED, -3);
+        // [5, -5], -3 = 5, 2, -1, -4
+        List<Double> arr = Arrays.asList(5.0, 2.0, -1.0, -4.0);
+        for (Double element : arr) {
+            assertTrue("Expected element [" + element +
+                               "] is missing in range [" + range + "]",
+                       range.contains(element));
+        }
+        List<Double> elementsNotPresent = new ArrayList<Double>(fullRange);
+        elementsNotPresent.removeAll(arr);
+        for (Double element : elementsNotPresent) {
+            assertFalse("Unexpected element [" + element +
+                                "] is present in range [" + range + "]",
+                        range.contains(element));
+        }
+    }
+
+    @Test
+    public void testOpenClosedDescendingContains() {
+        // (5, -5], -3 = 2, -1, -4
+        DoubleRange range = Ranges.doubleRange(5, BoundType.OPEN, -5,
+                                            BoundType.CLOSED, -3);
+        // (5, -5], -3 = 2, -1, -4
+        List<Double> arr = Arrays.asList(2.0, -1.0, -4.0);
+        for (Double element : arr) {
+            assertTrue("Expected element [" + element +
+                               "] is missing in range [" + range + "]",
+                       range.contains(element));
+        }
+        List<Double> elementsNotPresent = new ArrayList<Double>(fullRange);
+        elementsNotPresent.removeAll(arr);
+        for (Double element : elementsNotPresent) {
+            assertFalse("Unexpected element [" + element +
+                                "] is present in range [" + range + "]",
+                        range.contains(element));
+        }
+    }
+
+    @Test
+    public void testClosedOpenDescendingContains() {
+        // [5, -5), -3 = 5, 2, -1, -4
+        DoubleRange range = Ranges.doubleRange(5, BoundType.CLOSED, -5,
+                                            BoundType.OPEN, -3);
+        // [5, -5), -3 = 5, 2, -1, -4
+        List<Double> arr = Arrays.asList(5.0, 2.0, -1.0, -4.0);
+        for (Double element : arr) {
+            assertTrue("Expected element [" + element +
+                               "] is missing in range [" + range + "]",
+                       range.contains(element));
+        }
+        List<Double> elementsNotPresent = new ArrayList<Double>(fullRange);
+        elementsNotPresent.removeAll(arr);
+        for (Double element : elementsNotPresent) {
+            assertFalse("Unexpected element [" + element +
+                                "] is present in range [" + range + "]",
+                        range.contains(element));
+        }
+    }
+
+    @Test
+    public void testOpenOpenDescendingContains() {
+        // (5, -5), -3 = 2, -1, -4
+        DoubleRange range = Ranges.doubleRange(5, BoundType.OPEN, -5,
+                                            BoundType.OPEN, -3);
+        // (5, -5), -3 = 2, -1, -4
+        List<Double> arr = Arrays.asList(2.0, -1.0, -4.0);
+        for (Double element : arr) {
+            assertTrue("Expected element [" + element +
+                               "] is missing in range [" + range + "]",
+                       range.contains(element));
+        }
+        List<Double> elementsNotPresent = new ArrayList<Double>(fullRange);
+        elementsNotPresent.removeAll(arr);
+        for (Double element : elementsNotPresent) {
+            assertFalse("Unexpected element [" + element +
+                                "] is present in range [" + range + "]",
+                        range.contains(element));
+        }
+    }
+
+    @Test
+    public void testContainsSingleStepDescending() {
+        // [2, -2), -1 = 2, 1, 0, -1
+        DoubleRange descendingRange = Ranges.doubleRange(2, BoundType.CLOSED, -2,
+                                                      BoundType.OPEN, -1);
+        // [2, -2), -1 = 2, 1, 0, -1
+        List<Double> arr = Arrays.asList(2.0, 1.0, 0.0, -1.0);
+        for (Double element : arr) {
+            assertTrue("Expected element [" + element +
+                               "] is missing in range [" + descendingRange +
+                               "]",
+                       descendingRange.contains(element));
+        }
+        List<Double> elementsNotPresent = new ArrayList<Double>(fullRange);
+        elementsNotPresent.removeAll(arr);
+        for (Double element : elementsNotPresent) {
+            assertFalse("Unexpected element [" + element +
+                                "] is present in range [" + descendingRange +
+                                "]",
+                        descendingRange.contains(element));
+        }
+    }
+
+    @Test
+    public void testContainsNullOrEmpty() {
+        DoubleRange range = Ranges.doubleRange(-2, BoundType.OPEN, 2,
+                                            BoundType.CLOSED, 1);
+        assertFalse(range.contains(null));
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testContainsAll() {
+        // (-2, 2], 1 = -1, 0, 1, 2
+        DoubleRange range = Ranges.doubleRange(-2, BoundType.OPEN, 2,
+                                            BoundType.CLOSED, 1);
+        List<Double> list = Arrays.asList(-1.0, 0.0, 1.0, 2.0);
+        assertTrue("Range [" + range +
+                   "] was expected to contain all elements from list [" + list +
+                   "]", range.containsAll(list));
+        List<Double> listWithExtraElements = Arrays.asList(2.0, -1.0, 0.0, 1.0,
+                                                           2.0, 3.0);
+        assertFalse("Range [" + range + "] has more elements than expected",
+                    range.containsAll(listWithExtraElements));
+        assertFalse(range.containsAll(null));
+        assertFalse(range.containsAll(Collections.EMPTY_LIST));
+    }
+
+    @Test
+    public void testEquals()
+        throws Exception {
+        // equals basic properties
+        DoubleRange range = Ranges.doubleRange(-2, BoundType.CLOSED, 2,
+                                            BoundType.OPEN, 1);
+        assertEquals("equals must be reflexive", range, range);
+        assertEquals("hashCode must be reflexive", range.hashCode(),
+                     range.hashCode());
+        assertTrue(!range.equals(null)); // should be able to compare to null
+
+        Object range2 = Ranges.doubleRange(-2, BoundType.CLOSED, 2,
+                                        BoundType.OPEN, 1);
+        if (range.equals(range2)) {
+            assertEquals("equals implies hash equals", range.hashCode(),
+                         range2.hashCode());
+            assertEquals("equals must be symmetric", range2, range);
+        } else {
+            assertTrue("equals must be symmetric", !range2.equals(range));
+        }
+
+        // Changing attributes
+        Object range3 = Ranges.doubleRange(-1, BoundType.CLOSED, 2,
+                                        BoundType.OPEN, 1);
+        assertFalse("Invalid equals after changing attributes",
+                    range.equals(range3));
+
+        Object range4 = Ranges.doubleRange(-2, BoundType.OPEN, 2, BoundType.OPEN,
+                                        1);
+        assertFalse("Invalid equals after changing attributes",
+                    range.equals(range4));
+
+        Object range5 = Ranges.doubleRange(-2, BoundType.CLOSED, 1,
+                                        BoundType.OPEN, 1);
+        assertFalse("Invalid equals after changing attributes",
+                    range.equals(range5));
+
+        Object range6 = Ranges.doubleRange(-2, BoundType.CLOSED, 2,
+                                        BoundType.CLOSED, 1);
+        assertFalse("Invalid equals after changing attributes",
+                    range.equals(range6));
+
+        Object range7 = Ranges.doubleRange(-2, BoundType.CLOSED, 2,
+                                        BoundType.OPEN, 2);
+        assertFalse("Invalid equals after changing attributes",
+                    range.equals(range7));
+
+        // Using different constructors
+        DoubleRange range8 = Ranges.doubleRange(Long.valueOf(-2), Long.valueOf(2),
+                                             Long.valueOf(1));
+        assertEquals("Invalid equals using different constructor", range,
+                     range8);
+
+        DoubleRange range9 = Ranges.doubleRange(Long.valueOf(-2), Long.valueOf(2));
+        assertEquals("Invalid equals using different constructor", range,
+                     range9);
+
+        Endpoint<Double> leftEndpoint = new Endpoint<Double>(-2.0d,
+                                                             BoundType.CLOSED);
+        Endpoint<Double> rightEndpoint = new Endpoint<Double>(2.0d,
+                                                              BoundType.OPEN);
+        DoubleRange range10 = Ranges.doubleRange(leftEndpoint, rightEndpoint, 1.0d);
+        assertEquals("Invalid equals using different constructor", range,
+                     range10);
+    }
+
+    @Test
+    public void testToString() {
+        DoubleRange range = Ranges.doubleRange(-2, BoundType.OPEN, 2,
+                                            BoundType.CLOSED, 1);
+        assertEquals("Wrong string value", "DoubleRange<(-2.0, 2.0], 1.0>",
+                     range.toString());
+    }
+
+    @Test
+    public void testConstructorUsingSameEndpoint() {
+        Endpoint<Double> uniqueEndpoint = new Endpoint<Double>(10.0d,
+                                                               BoundType.CLOSED);
+        try {
+            Ranges.doubleRange(uniqueEndpoint, uniqueEndpoint, 1.0d);
+        } catch (IllegalArgumentException e) {
+            fail("Not expected to get here");
+        }
+    }
+
+    @Test
+    public void testInvalidRange() {
+        try {
+            Ranges.doubleRange(10.0d, BoundType.OPEN, -5.0d, BoundType.CLOSED,
+                            10.0d);
+            fail("Not expected to get here");
+        } catch (IllegalArgumentException e) {
+            // Do nothing
+        }
+        Endpoint<Double> leftEndpoint = new Endpoint<Double>(10.0d,
+                                                             BoundType.CLOSED);
+        Endpoint<Double> rightEndpoint = new Endpoint<Double>(-5.0d,
+                                                              BoundType.OPEN);
+        try {
+            Ranges.doubleRange(leftEndpoint, rightEndpoint, 1.0f);
+            fail("Not expected to get here");
+        } catch (IllegalArgumentException e) {
+            // Do nothing
+        }
+    }
+
+    @Test
+    public void testDefaultStep() {
+        assertEquals("Invalid default step", Double.valueOf(-1.0d),
+                     DoubleRange.DEFAULT_STEP.evaluate(10.0d, 1.0d));
+        assertEquals("Invalid default step", Double.valueOf(1.0d),
+                     DoubleRange.DEFAULT_STEP.evaluate(1.0d, 10.0d));
+    }
+
+}

Propchange: commons/proper/functor/branches/generators-FUNCTOR-14/src/test/java/org/apache/commons/functor/generator/range/TestDoubleRange.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: commons/proper/functor/branches/generators-FUNCTOR-14/src/test/java/org/apache/commons/functor/generator/range/TestEndpoint.java
URL: http://svn.apache.org/viewvc/commons/proper/functor/branches/generators-FUNCTOR-14/src/test/java/org/apache/commons/functor/generator/range/TestEndpoint.java?rev=1385335&view=auto
==============================================================================
--- commons/proper/functor/branches/generators-FUNCTOR-14/src/test/java/org/apache/commons/functor/generator/range/TestEndpoint.java (added)
+++ commons/proper/functor/branches/generators-FUNCTOR-14/src/test/java/org/apache/commons/functor/generator/range/TestEndpoint.java Sun Sep 16 18:08:31 2012
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.functor.generator.range;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+/**
+ * Tests for endpoint.
+ *
+ * @since 1.0
+ * @version $Revision: $ $Date: $
+ */
+public class TestEndpoint {
+
+    private final Endpoint<Integer> openEndpoint = new Endpoint<Integer>(1, BoundType.OPEN);
+    private final Endpoint<Integer> closedEndpoint = new Endpoint<Integer>(2, BoundType.CLOSED);
+
+    @Test
+    public void testValue() {
+        assertEquals(Integer.valueOf(1), openEndpoint.getValue());
+        assertEquals(Integer.valueOf(2), closedEndpoint.getValue());
+    }
+
+    @Test
+    public void testBoundType() {
+        assertEquals(BoundType.OPEN, openEndpoint.getBoundType());
+        assertEquals(BoundType.CLOSED, closedEndpoint.getBoundType());
+    }
+
+    @Test
+    public void testToString() {
+        assertEquals("Endpoint<1, OPEN>", openEndpoint.toString());
+        assertEquals("Endpoint<2, CLOSED>", closedEndpoint.toString());
+        assertEquals("(1", openEndpoint.toLeftString());
+        assertEquals("[2", closedEndpoint.toLeftString());
+        assertEquals("1)", openEndpoint.toRightString());
+        assertEquals("2]", closedEndpoint.toRightString());
+    }
+
+    @Test
+    public void testEquals()
+        throws Exception {
+        // equals basic properties
+        Endpoint<Integer> endpoint = new Endpoint<Integer>(1, BoundType.OPEN);
+        assertEquals("equals must be reflexive", endpoint, endpoint);
+        assertEquals("hashCode must be reflexive", endpoint.hashCode(),
+                     endpoint.hashCode());
+        assertTrue(!endpoint.equals(null)); // should be able to compare to null
+
+        Object endpoint2 = new Endpoint<Integer>(1, BoundType.OPEN);
+        if (endpoint.equals(endpoint2)) {
+            assertEquals("equals implies hash equals", endpoint.hashCode(),
+                         endpoint2.hashCode());
+            assertEquals("equals must be symmetric", endpoint2, endpoint);
+        } else {
+            assertTrue("equals must be symmetric", !endpoint2.equals(endpoint));
+        }
+
+        Object differentEndpoint = new Endpoint<Integer>(1, BoundType.CLOSED);
+        assertTrue(!differentEndpoint.equals(endpoint));
+        assertTrue(differentEndpoint.hashCode() != endpoint.hashCode());
+    }
+
+}

Propchange: commons/proper/functor/branches/generators-FUNCTOR-14/src/test/java/org/apache/commons/functor/generator/range/TestEndpoint.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain