Index: /Users/edwin/workspace/groovy/src/test/groovy/lang/IntRangeTest.java
===================================================================
--- /Users/edwin/workspace/groovy/src/test/groovy/lang/IntRangeTest.java (revision 4080)
+++ /Users/edwin/workspace/groovy/src/test/groovy/lang/IntRangeTest.java (working copy)
@@ -45,16 +45,552 @@
*/
package groovy.lang;
+import java.util.ArrayList;
+import java.util.Iterator;
import java.util.List;
import junit.framework.TestCase;
/**
+ * Provides unit tests for the IntRange class.
+ *
* @author James Strachan
* @version $Revision$
*/
public class IntRangeTest extends TestCase {
+ /**
+ * Records the values passed to a closure.
+ */
+ private static class RecordingClosure extends Closure {
+ /**
+ * Holds the values passed in
+ */
+ final List callLog;
+
+ /**
+ * Creates a new RecordingClosure
+ *
+ * @param callLog is filled with the values passed to doCall
+ */
+ RecordingClosure(final List callLog) {
+ super(null);
+ this.callLog = callLog;
+ }
+
+ /**
+ * Stores params in the callLog.
+ *
+ * @param params the parameters.
+ *
+ * @return null
+ */
+ public Object doCall(final Object params) {
+ callLog.add(params);
+ return null;
+ }
+ }
+
+ /**
+ * Tests stepping through a range by two with a closure.
+ */
+ public void testStepByTwoWithClosure() {
+ final List callLog = new ArrayList();
+ final Closure closure = new RecordingClosure(callLog);
+
+ final IntRange range = new IntRange(0, 4);
+ range.step(2, closure);
+
+ assertEquals("wrong number of calls to closure", 3, callLog.size());
+ final Iterator iter = callLog.iterator();
+ for (int i = 0; i <= 4; i += 2) {
+ assertEquals("wrong argument passed to closure", new Integer(i), iter.next());
+ }
+ }
+
+ /**
+ * Tests stepping through a reversed range by two with a closure.
+ */
+ public void testReverseStepByTwoWithClosure() {
+ final List callLog = new ArrayList();
+ final Closure closure = new RecordingClosure(callLog);
+
+ final IntRange range = new IntRange(4, 0);
+ range.step(2, closure);
+
+ assertEquals("wrong number of calls to closure", 3, callLog.size());
+ final Iterator iter = callLog.iterator();
+ for (int i = 4; i >= 0; i -= 2) {
+ assertEquals("wrong argument passed to closure", new Integer(i), iter.next());
+ }
+ }
+
+ /**
+ * Tests stepping through a range with a closure.
+ */
+ public void testStepByOneWithClosure() {
+ final List callLog = new ArrayList();
+ final Closure closure = new RecordingClosure(callLog);
+
+ final IntRange range = new IntRange(1, 5);
+ range.step(1, closure);
+
+ assertEquals("wrong number of calls to closure", 5, callLog.size());
+ final Iterator iter = callLog.iterator();
+ for (int i = 1; i <= 5; i++) {
+ assertEquals("wrong argument passed to closure", new Integer(i), iter.next());
+ }
+ }
+
+ /**
+ * Tests stepping through a reversed range by one with a closure.
+ */
+ public void testReverseStepByOneWithClosure() {
+ final List callLog = new ArrayList();
+ final Closure closure = new RecordingClosure(callLog);
+
+ final IntRange range = new IntRange(5, 1);
+ range.step(1, closure);
+
+ assertEquals("wrong number of calls to closure", 5, callLog.size());
+ final Iterator iter = callLog.iterator();
+ for (int i = 5; i >= 1; i--) {
+ assertEquals("wrong argument passed to closure", new Integer(i), iter.next());
+ }
+ }
+
+ /**
+ * Tests stepping backwards through a range with a closure.
+ */
+ public void testNegativeStepByOneWithClosure() {
+ final List callLog = new ArrayList();
+ final Closure closure = new RecordingClosure(callLog);
+
+ final IntRange range = new IntRange(1, 5);
+ range.step(-1, closure);
+
+ assertEquals("wrong number of calls to closure", 5, callLog.size());
+ final Iterator iter = callLog.iterator();
+ for (int i = 5; i >= 1; i--) {
+ assertEquals("wrong argument passed to closure", new Integer(i), iter.next());
+ }
+ }
+
+ /**
+ * Tests stepping backwards through a reversed range with a closure.
+ */
+ public void testNegativeReverseStepByOneWithClosure() {
+ final List callLog = new ArrayList();
+ final Closure closure = new RecordingClosure(callLog);
+
+ final IntRange range = new IntRange(5, 1);
+ range.step(-1, closure);
+
+ assertEquals("wrong number of calls to closure", 5, callLog.size());
+ final Iterator iter = callLog.iterator();
+ for (int i = 1; i <= 5; i++) {
+ assertEquals("wrong argument passed to closure", new Integer(i), iter.next());
+ }
+ }
+
+ /**
+ * Tests stepping backwards through a range with a step size greater than the range size.
+ */
+ public void testStepLargerThanRange() {
+ final List callLog = new ArrayList();
+ final Closure closure = new RecordingClosure(callLog);
+
+ final IntRange range = new IntRange(1, 5);
+
+ range.step(6, closure);
+ assertEquals("wrong number of calls to closure", 1, callLog.size());
+ assertEquals("wrong value", new Integer(1), callLog.get(0));
+
+ final List stepList = range.step(6);
+ assertEquals("wrong number of values in result", 1, stepList.size());
+ assertEquals("wrong value", new Integer(1), callLog.get(0));
+ }
+
+ /**
+ * Tests stepping through a range by one.
+ */
+ public void testStepByOne() {
+ final IntRange range = new IntRange(1, 5);
+ final List result = range.step(1);
+
+ assertEquals("wrong number of calls", 5, result.size());
+ final Iterator iter = result.iterator();
+ for (int i = 1; i <= 5; i++) {
+ assertEquals("incorrect value in result", new Integer(i), iter.next());
+ }
+ }
+
+ /**
+ * Tests stepping through a range by two.
+ */
+ public void testStepByTwo() {
+ final IntRange range = new IntRange(1, 5);
+ final List result = range.step(2);
+
+ assertEquals("wrong number of calls", 3, result.size());
+ final Iterator iter = result.iterator();
+ for (int i = 1; i <= 5; i += 2) {
+ assertEquals("incorrect value in result", new Integer(i), iter.next());
+ }
+ }
+
+ /**
+ * Tests providing invalid arguments to the protected constructor.
+ */
+ public void testInvalidArgumentsToConstructor() {
+ try {
+ new IntRange(2, 1, true);
+ fail("invalid range created");
+ }
+ catch (IllegalArgumentException e) {
+ assertTrue("expected exception thrown", true);
+ }
+ }
+
+ /**
+ * Tests creating a sub list with a negative "from" index.
+ */
+ public void testSubListNegativeFrom() {
+ try {
+ final IntRange range = new IntRange(1, 5);
+ range.subList(-1, 3);
+ fail("accepted sub list with negative index");
+ }
+ catch (IndexOutOfBoundsException e) {
+ assertTrue("expected exception thrown", true);
+ }
+ }
+
+ /**
+ * Tests creating a sub list with an out of range "to" index.
+ */
+ public void testSubListOutOfRangeTo() {
+ try {
+ final IntRange range = new IntRange(1, 5);
+ range.subList(0, 6);
+ fail("accepted sub list with invalid 'to'");
+ }
+ catch (IndexOutOfBoundsException e) {
+ assertTrue("expected exception thrown", true);
+ }
+ }
+
+ /**
+ * Tests creating a sub list with "from" grater than "to."
+ */
+ public void testSubListFromGreaterThanTo() {
+ try {
+ final IntRange range = new IntRange(1, 5);
+ range.subList(3, 2);
+ fail("accepted sub list with 'from' greater than 'to'");
+ }
+ catch (IllegalArgumentException e) {
+ assertTrue("expected exception thrown", true);
+ }
+ }
+
+ /**
+ * Tests creating an empty sub list.
+ */
+ public void testEmptySubList() {
+ final IntRange range = new IntRange(1, 5);
+
+ List subList = range.subList(0, 0);
+ assertEquals("wrong number of elements in sub list", 0, subList.size());
+
+ subList = range.subList(2, 2);
+ assertEquals("wrong number of elements in sub list", 0, subList.size());
+ }
+
+ /**
+ * Tests iterating over a non-reversed range.
+ */
+ public void testIterate() {
+ final IntRange range = new IntRange(1, 5);
+ int next = 1;
+ final Iterator iter = range.iterator();
+ while (iter.hasNext()) {
+ final Integer number = (Integer) iter.next();
+ assertEquals("wrong number", next++, number);
+ }
+ assertEquals("wrong number of elements in iteration", 6, next);
+ assertNull("got element after iterator finished", iter.next());
+ }
+
+ /**
+ * Tests iterating over a one-element range.
+ */
+ public void testOneElementRange() {
+ final IntRange range = new IntRange(1, 1);
+ int next = 1;
+ for (Iterator iter = range.iterator(); iter.hasNext();) {
+ final Integer number = (Integer) iter.next();
+ assertEquals("wrong number", next++, number);
+ }
+ assertEquals("wrong number of elements in iteration", 2, next);
+ }
+
+ /**
+ * Tests removing an element from the range using an iterator (not supported).
+ */
+ public void testRemove() {
+ final IntRange range = new IntRange(1, 5);
+
+ try {
+ final Iterator iter = range.iterator();
+ iter.remove();
+ fail("successfully removed an element from an IntRange");
+ }
+ catch (UnsupportedOperationException e) {
+ assertTrue("expected exception thrown", true);
+ }
+ }
+
+ /**
+ * Tests iterating over a reversed range.
+ */
+ public void testIterateReversed() {
+ final IntRange range = new IntRange(5, 1);
+ int next = 5;
+ for (Iterator iter = range.iterator(); iter.hasNext();) {
+ final Integer number = (Integer) iter.next();
+ assertEquals("wrong number", next--, number);
+ }
+ assertEquals("wrong number of elements in iteration", 0, next);
+ }
+
+ /**
+ * Tests creating an IntRange with from > to.
+ */
+ public void testFromGreaterThanTo() {
+ final int from = 9;
+ final int to = 0;
+ final IntRange range = new IntRange(from, to);
+
+ assertTrue("range not reversed", range.isReverse());
+
+ // make sure to/from are swapped
+ assertEquals("from incorrect", to, range.getFromInt());
+ assertEquals("to incorrect", from, range.getToInt());
+
+ assertEquals("wrong size", 10, range.size());
+
+ assertEquals("wrong first element", 9, range.get(0));
+ assertEquals("wrong last element", 0, range.get(9));
+ }
+
+ /**
+ * Tests creating an IntRange with from == to.
+ */
+ public void testFromEqualsTo() {
+ final IntRange range = new IntRange(5, 5);
+
+ assertFalse("range reversed", range.isReverse());
+ assertEquals("wrong size", 1, range.size());
+ }
+
+ /**
+ * Tests creating an IntRange with from < to.
+ */
+ public void testFromLessThanTo() {
+ final int from = 1;
+ final int to = 4;
+ final IntRange range = new IntRange(from, to);
+
+ assertFalse("range reversed", range.isReverse());
+
+ assertEquals("to incorrect", from, range.getFromInt());
+ assertEquals("from incorrect", to, range.getToInt());
+
+ assertEquals("wrong size", 4, range.size());
+ }
+
+ /**
+ * Making a range equal a list is not actually possible, since list.equals(range) will not evaluate to
+ * true and equals should be symmetric.
+ */
+ public void testEqualsList() {
+ final List list = new ArrayList();
+ list.add(new Integer(1));
+ list.add(new Integer(2));
+
+ final IntRange range = new IntRange(1, 2);
+
+ // cast to Object to test routing through IntRange.equals(Object)
+ assertTrue("range equals list", range.equals((Object) list));
+ assertTrue("list equals range", list.equals(range));
+ assertEquals("hash codes are equal", range.hashCode(), list.hashCode());
+
+ // compare lists that are the same size but contain different elements
+ list.set(0, new Integer(3));
+ assertFalse("range does not equal list", range.equals(list));
+ assertFalse("list doest not equal range", list.equals(range));
+ assertFalse("hash codes are not equal", range.hashCode() == list.hashCode());
+
+ // compare a list longer than the range
+ list.set(0, new Integer(1));
+ list.add(new Integer(3));
+ assertFalse("range does not equal list", range.equals(list));
+ assertFalse("list doest not equal range", list.equals(range));
+ assertFalse("hash codes are not equal", range.hashCode() == list.hashCode());
+
+ // compare a list shorter than the range
+ list.remove(2);
+ list.remove(1);
+ assertFalse("range does not equal list", range.equals(list));
+ assertFalse("list doest not equal range", list.equals(range));
+ assertFalse("hash codes are not equal", range.hashCode() == list.hashCode());
+ }
+
+ /**
+ * Making a range equal a list is not actually possible, since list.equals(range) will not evaluate to
+ * true and equals should be symmetric.
+ */
+ public void testEqualsNullList() {
+ final IntRange range = new IntRange(1, 2);
+ assertFalse("range not equal to null list", range.equals((List) null));
+ }
+
+ /**
+ * Tests comparing an IntRange to an object that is not an IntRange.
+ */
+ public void testEqualsNonIntRange() {
+ final Integer number = new Integer(5);
+ final IntRange range = new IntRange(5, 5);
+ assertFalse("range equal to number", range.equals(number));
+ }
+
+ /**
+ * Tests comparing IntRanges cast to Object.
+ */
+ public void testEqualsIntRangeAsObject() {
+ final IntRange range1 = new IntRange(1, 5);
+ final IntRange range2 = new IntRange(1, 5);
+ assertTrue("ranges not equal", range1.equals((Object) range2));
+ assertTrue("ranges not equal", range2.equals((Object) range1));
+ }
+
+ /**
+ * Tests comparing IntRanges to each other.
+ */
+ public void testEqualsIntRange() {
+ final IntRange range1 = new IntRange(1, 5);
+ IntRange range2 = new IntRange(1, 5);
+ assertTrue("ranges not equal", range1.equals((Object) range2));
+ assertTrue("ranges not equal", range2.equals((Object) range1));
+ assertEquals("hash codes not equal", range1.hashCode(), range2.hashCode());
+
+ range2 = new IntRange(0, 5);
+ assertFalse("ranges equal", range1.equals((Object) range2));
+ assertFalse("ranges equal", range2.equals((Object) range1));
+ assertFalse("hash codes equal", range1.hashCode() == range2.hashCode());
+
+ range2 = new IntRange(1, 6);
+ assertFalse("ranges equal", range1.equals((Object) range2));
+ assertFalse("ranges equal", range2.equals((Object) range1));
+ assertFalse("hash codes equal", range1.hashCode() == range2.hashCode());
+
+ range2 = new IntRange(0, 6);
+ assertFalse("ranges equal", range1.equals((Object) range2));
+ assertFalse("ranges equal", range2.equals((Object) range1));
+ assertFalse("hash codes equal", range1.hashCode() == range2.hashCode());
+
+ range2 = new IntRange(2, 4);
+ assertFalse("ranges equal", range1.equals((Object) range2));
+ assertFalse("ranges equal", range2.equals((Object) range1));
+ assertFalse("hash codes equal", range1.hashCode() == range2.hashCode());
+
+ range2 = new IntRange(5, 1);
+ assertFalse("ranges equal", range1.equals((Object) range2));
+ assertFalse("ranges equal", range2.equals((Object) range1));
+ assertFalse("hash codes equal", range1.hashCode() == range2.hashCode());
+ }
+
+ /**
+ * Tests toString and inspect
+ */
+ public void testToStringAndInspect() {
+ IntRange range = new IntRange(1, 5);
+ assertEquals("wrong string representation", "1..5", range.toString());
+ assertEquals("wrong string representation", "1..5", range.inspect());
+
+ range = new IntRange(5, 1);
+ assertEquals("wrong string representation", "5..1", range.toString());
+ assertEquals("wrong string representation", "5..1", range.inspect());
+ }
+
+ /**
+ * Tests getFrom and getTo.
+ */
+ public void testGetFromAndTo() {
+ final int from = 1, to = 5;
+ final IntRange range = new IntRange(from, to);
+
+ assertEquals("wrong 'from' value", from, range.getFromInt());
+ assertEquals("wrong 'from' value", new Integer(from), range.getFrom());
+
+ assertEquals("wrong 'to' value", to, range.getToInt());
+ assertEquals("wrong 'to' value", new Integer(to), range.getTo());
+ }
+
+ /**
+ * Tests comparing an IntRange to null.
+ *
+ */
+ public void testEqualsNullObject() {
+ final IntRange range = new IntRange(1, 5);
+ assertFalse("range equal to null", range.equals(null));
+ assertFalse("range equal to null object", range.equals((Object) null));
+ assertFalse("range equal to null IntRange", range.equals((IntRange) null));
+ }
+
+ /**
+ * Tests get from a reversed range.
+ */
+ public void testGetFromReversedRange() {
+ final IntRange range = new IntRange(5, 1);
+
+ for (int i = 0; i < 5; i++) {
+ assertEquals("wrong element at position " + i, 5 - i, range.get(i));
+ }
+ }
+
+ private void doTestContains(int from, int to, IntRange range) {
+ // test integers
+ assertTrue("missing 'from' value", range.contains(new Integer(from)));
+ assertTrue("missing 'to' value", range.contains(new Integer(to)));
+ assertTrue("missing mid point", range.contains(new Integer((from + to) / 2)));
+ assertFalse("contains out of range value", range.contains(new Integer(from - 1)));
+ assertFalse("contains out of range value", range.contains(new Integer(to + 1)));
+
+ // test int range
+ assertTrue("missing same range", range.contains(new IntRange(from, to)));
+ assertTrue("missing same range", range.contains(new IntRange(to, from)));
+ assertTrue("missing strict subset", range.contains(new IntRange(from + 1, to - 1)));
+ assertTrue("missing subset", range.contains(new IntRange(from, to - 1)));
+ assertTrue("missing subset", range.contains(new IntRange(from + 1, to)));
+ assertFalse("contains non-subset", range.contains(new IntRange(from - 1, to)));
+ assertFalse("contains non-subset", range.contains(new IntRange(from, to + 1)));
+ assertFalse("contains non-subset", range.contains(new IntRange(from - 2, from - 1)));
+
+ // test non-integer number
+ assertFalse("contains floating point number", range.contains(new Float(from)));
+ }
+
+ /**
+ * Tests whether an IntRange contains another IntRange or a specific integer.
+ */
+ public void testContains() {
+ final int from = 1, to = 5;
+ doTestContains(from, to, new IntRange(from, to));
+ doTestContains(from, to, new IntRange(to, from));
+ }
+
public void testSize() {
IntRange r = createRange(0, 10);
assertEquals("Size of " + r, 11, r.size());
@@ -98,19 +634,6 @@
}
- public void testContains() {
- IntRange r = createRange(10, 20);
-
- assertTrue("contains 11", r.contains(new Integer(11)));
- assertTrue("contains 10", r.contains(new Integer(10)));
- assertTrue("contains 19", r.contains(new Integer(19)));
- assertTrue("contains 20", r.contains(new Integer(20)));
- assertFalse("contains 9", r.contains(new Integer(9)));
- assertFalse("contains 21", r.contains(new Integer(21)));
- assertFalse("contains 100", r.contains(new Integer(100)));
- assertFalse("contains -1", r.contains(new Integer(-1)));
- }
-
public void testSubList() {
IntRange r = createRange(10, 20);