Refactor Range with lots of new methods

git-svn-id: https://svn.apache.org/repos/asf/commons/proper/lang/trunk@1127565 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Stephen Colebourne 2011-05-25 15:43:35 +00:00
parent f5682c4c70
commit 0ad6c30b0e
2 changed files with 349 additions and 265 deletions

View File

@ -18,21 +18,23 @@
import java.io.Serializable;
import java.util.Comparator;
import java.util.Formattable;
/**
* <p>{@code Range} represents an immutable range of comparables of the same type.</p>
* <p>The objects need to either be implementations of {@code java.lang.Comparable}
* or you need to supply a {@code java.util.Comparator}. </p>
* <p>An immutable range of objects from a minimum to maximum point inclusive.</p>
*
* <p>The objects need to either be implementations of {@code Comparable}
* or you need to supply a {@code Comparator}. </p>
*
* <p>#ThreadSafe# if the comparables are thread-safe</p>
* <p>#ThreadSafe# if the objects and comparator are thread-safe</p>
*
* @since 3.0
* @version $Id$
*/
public final class Range<T> implements Serializable {
/**
* Required for serialization support.
*
* Serialization version.
* @see java.io.Serializable
*/
private static final long serialVersionUID = 1L;
@ -41,124 +43,123 @@ public final class Range<T> implements Serializable {
* The ordering scheme used in this range.
*/
private final Comparator<T> comparator;
/**
* The minimum value in this range (inclusive).
*/
private final T minimum;
/**
* The maximum value in this range (inclusive).
*/
private final T maximum;
/**
* Cached output hashCode (class is immutable).
*/
private transient int hashCode = 0;
private transient int hashCode;
/**
* Cached output toString (class is immutable).
*/
private transient String toString = null;
private transient String toString;
/**
* <p>Constructs a new {@code Range} using the specified
* element as both the minimum and maximum in this range.</p>
* <p>The range uses the natural ordering of the elements to
* determine where values lie in the range.</p>
* <p>Obtains a range using the specified element as both the minimum
* and maximum in this range.</p>
*
* <p>The range uses the natural ordering of the elements to determine where
* values lie in the range.</p>
*
* @param <T> the type of this {@code Range}
* @param element the value to use for this range, must not be {@code null}
* @return the new range object
* @throws IllegalArgumentException if the value is {@code null}
* @throws ClassCastException if the value is not Comparable
* @param <T> the type of the elements in this range
* @param element the value to use for this range, not null
* @return the range object, not null
* @throws IllegalArgumentException if the element is null
* @throws ClassCastException if the element is not {@code Comparable}
*/
public static <T extends Comparable<T>> Range<T> is(T element) {
return new Range<T>(element, element, ComparableComparator.<T>getInstance());
return between(element, element, null);
}
/**
* <p>Constructs a new {@code Range} with the specified
* minimum and maximum values (both inclusive).</p>
* <p>The range uses the natural ordering of the elements to
* determine where values lie in the range.</p>
* <p>Obtains a range using the specified element as both the minimum
* and maximum in this range.</p>
*
* <p>The range uses the specified {@code Comparator} to determine where
* values lie in the range.</p>
*
* <p>The arguments may be passed in the order (min,max) or (max,min). The
* getMinimum and getMaximum methods will return the correct values.</p>
*
* @param <T> the type of this {@code Range}
* @param element1 first value that defines the edge of the range, inclusive
* @param element2 second value that defines the edge of the range, inclusive
* @return the new range object
* @throws IllegalArgumentException if either value is {@code null}
* @throws ClassCastException if either value is not Comparable
*/
public static <T extends Comparable<T>> Range<T> between(T element1, T element2) {
return new Range<T>( element1, element2, ComparableComparator.<T>getInstance());
}
/**
* <p>Constructs a new {@code Range} using the specified
* element as both the minimum and maximum in this range.</p>
* <p>The range uses the passed in {@code Comparator} to
* determine where values lie in the range.</p>
*
* @param <T> the type of this {@code Range}
* @param <T> the type of the elements in this range
* @param element the value to use for this range, must not be {@code null}
* @param c comparator to be used
* @return the new range object
* @throws IllegalArgumentException if the value is {@code null}
* @param comparator the comparator to be used, null for natural ordering
* @return the range object, not null
* @throws IllegalArgumentException if the element is null
* @throws ClassCastException if using natural ordering and the elements are not {@code Comparable}
*/
public static <T> Range<T> is(T element, Comparator<T> c) {
return new Range<T>(element, element, c);
public static <T> Range<T> is(T element, Comparator<T> comparator) {
return between(element, element, comparator);
}
/**
* <p>Constructs a new {@code Range} with the specified
* minimum and maximum values (both inclusive).</p>
* <p>The range uses the passed in {@code Comparator} to
* determine where values lie in the range.</p>
* <p>Obtains a range with the specified minimum and maximum values (both inclusive).</p>
*
* <p>The range uses the natural ordering of the elements to determine where
* values lie in the range.</p>
*
* <p>The arguments may be passed in the order (min,max) or (max,min). The
* getMinimum and getMaximum methods will return the correct values.</p>
* <p>The arguments may be passed in the order (min,max) or (max,min).
* The getMinimum and getMaximum methods will return the correct values.</p>
*
* @param <T> the type of this {@code Range}
* @param element1 first value that defines the edge of the range, inclusive
* @param element2 second value that defines the edge of the range, inclusive
* @param c comparator to be used
* @return the new range object
* @throws IllegalArgumentException if either value is {@code null}
* @param <T> the type of the elements in this range
* @param fromInclusive the first value that defines the edge of the range, inclusive
* @param toInclusive the second value that defines the edge of the range, inclusive
* @return the range object, not null
* @throws IllegalArgumentException if either element is null
* @throws ClassCastException if the elements are not {@code Comparable}
*/
public static <T> Range<T> between(T element1, T element2, Comparator<T> c) {
return new Range<T>(element1, element2, c);
public static <T extends Comparable<T>> Range<T> between(T fromInclusive, T toInclusive) {
return between(fromInclusive, toInclusive, null);
}
/**
* Creates a new instance of {@code Range}.
* <p>Obtains a range with the specified minimum and maximum values (both inclusive).</p>
*
* <p>The range uses the specified {@code Comparator} to determine where
* values lie in the range.</p>
*
* @param element1 the first element
* @param element2 the second element
* @param c the comparator to be used
* <p>The arguments may be passed in the order (min,max) or (max,min).
* The getMinimum and getMaximum methods will return the correct values.</p>
*
* @param <T> the type of the elements in this range
* @param fromInclusive the first value that defines the edge of the range, inclusive
* @param toInclusive the second value that defines the edge of the range, inclusive
* @param comparator the comparator to be used, null for natural ordering
* @return the range object, not null
* @throws IllegalArgumentException if either element is null
* @throws ClassCastException if using natural ordering and the elements are not {@code Comparable}
*/
private Range(T element1, T element2, Comparator<T> c) {
if(element1 == null || element2 == null) {
public static <T> Range<T> between(T fromInclusive, T toInclusive, Comparator<T> comparator) {
return new Range<T>(fromInclusive, toInclusive, comparator);
}
/**
* Creates an instance.
*
* @param element1 the first element, not null
* @param element2 the second element, not null
* @param comparator the comparator to be used, null for natural ordering
*/
@SuppressWarnings("unchecked")
private Range(T element1, T element2, Comparator<T> comparator) {
if (element1 == null || element2 == null) {
throw new IllegalArgumentException("Elements in a range must not be null: element1=" +
element1 + ", element2=" + element2);
}
if(c == null) {
throw new IllegalArgumentException("Comparator must not be null");
if (comparator == null) {
comparator = ComparableComparator.INSTANCE;
}
if(c.compare(element1, element2) < 1) {
if (comparator.compare(element1, element2) < 1) {
this.minimum = element1;
this.maximum = element2;
} else {
this.minimum = element2;
this.maximum = element1;
}
this.comparator = c;
this.comparator = comparator;
}
// Accessors
@ -167,108 +168,131 @@ private Range(T element1, T element2, Comparator<T> c) {
/**
* <p>Gets the minimum value in this range.</p>
*
* @return the minimum value in this range
* @return the minimum value in this range, not null
*/
public T getMinimum() {
return this.minimum;
return minimum;
}
/**
* <p>Gets the maximum value in this range.</p>
*
* @return the maximum value in this range
* @return the maximum value in this range, not null
*/
public T getMaximum() {
return this.maximum;
return maximum;
}
/**
* <p>Gets the comparator being used to determine if objects are within the range. </p>
* <p>Gets the comparator being used to determine if objects are within the range.</p>
*
* <p>Natural ordering uses an internal comparator implementation, thus this
* method never returns null. See {@link #isNaturalOrdering()}.</p>
*
* @return the comparator being used
* @return the comparator being used, not null
*/
public Comparator<T> getComparator() {
return this.comparator;
return comparator;
}
/**
* <p>Whether or not the Range is using the default natural comparison method
* to compare elements. </p>
* <p>Whether or not the Range is using the natural ordering of the elements.</p>
*
* <p>Natural ordering uses an internal comparator implementation, thus this
* method is the only way to check if a null comparator was specified.</p>
*
* @return whether or not the default Comparator is in use
* @return true if using natural ordering
*/
public boolean isDefaultNaturalOrdering() {
return this.comparator == ComparableComparator.INSTANCE;
public boolean isNaturalOrdering() {
return comparator == ComparableComparator.INSTANCE;
}
// Include tests
// Element tests
//--------------------------------------------------------------------
/**
* <p>Tests whether the specified element occurs within this range.</p>
* <p>Checks whether the specified element occurs within this range.</p>
*
* <p>{@code null} is handled and returns {@code false}.</p>
*
* @param element the element to test, may be {@code null}
* @return {@code true} if the specified element occurs within this range
* @param element the element to check for, null returns false
* @return true if the specified element occurs within this range
*/
public boolean contains(T element) {
if(element == null) {
return false;
}
return (comparator.compare(element, this.minimum) > -1) && (comparator.compare(element, this.maximum) < 1);
}
/**
* <p>Tests whether the specified element occurs before this range.</p>
*
* <p>{@code null} is handled and returns {@code false}.</p>
*
* @param element the element to test, may be {@code null}
* @return {@code true} if the specified element occurs before this range
*/
public boolean elementBefore(T element) {
if (element == null) {
return false;
}
return this.comparator.compare(element, this.minimum) < 0;
return (comparator.compare(element, minimum) > -1) && (comparator.compare(element, maximum) < 1);
}
/**
* <p>Tests whether the specified element occurs after this range.</p>
* <p>Checks whether this range is after the specified element.</p>
*
* <p>{@code null} is handled and returns {@code false}.</p>
*
* @param element the element to test, may be {@code null}
* @return {@code true} if the specified element occurs after this range
* @param element the element to check for, null returns false
* @return true if this range is entirely after the specified element
*/
public boolean elementAfter(T element) {
public boolean isAfter(T element) {
if (element == null) {
return false;
}
return this.comparator.compare(element, this.maximum) > 0;
return comparator.compare(element, minimum) < 0;
}
/**
* <p>Tests where the specified element occurs relative to this range.</p>
* <p>Checks whether this range starts with the specified element.</p>
*
* @param element the element to check for, null returns false
* @return true if the specified element occurs within this range
*/
public boolean isStartedBy(T element) {
if (element == null) {
return false;
}
return comparator.compare(element, minimum) == 0;
}
/**
* <p>Checks whether this range starts with the specified element.</p>
*
* @param element the element to check for, null returns false
* @return true if the specified element occurs within this range
*/
public boolean isEndedBy(T element) {
if (element == null) {
return false;
}
return comparator.compare(element, maximum) == 0;
}
/**
* <p>Checks whether this range is before the specified element.</p>
*
* @param element the element to check for, null returns false
* @return true if this range is entirely before the specified element
*/
public boolean isBefore(T element) {
if (element == null) {
return false;
}
return comparator.compare(element, maximum) > 0;
}
/**
* <p>Checks where the specified element occurs relative to this range.</p>
*
* <p>The API is reminiscent of the Comparable interface returning {@code -1} if
* the element is before the range, {@code 0} if contained within the range and
* {@code 1} if the element is after the range. </p>
*
* @param element the element to test
* @param element the element to check for, not null
* @return -1, 0 or +1 depending on the element's location relative to the range
*/
public int elementCompareTo(T element) {
if(element == null) {
if (element == null) {
// Comparable API says throw NPE on null
throw new NullPointerException("Element is null");
}
if(elementBefore(element)) {
if (isAfter(element)) {
return -1;
} else
if(elementAfter(element)) {
} else if (isBefore(element)) {
return 1;
} else {
return 0;
@ -279,40 +303,73 @@ public int elementCompareTo(T element) {
//--------------------------------------------------------------------
/**
* <p>Tests whether the specified range occurs entirely within this range.</p>
* <p>Checks whether this range contains all the elements of the specified range.</p>
*
* <p>{@code null} is handled and returns {@code false}.</p>
* <p>This method may fail if the ranges have two different comparators or element types.</p>
*
* @param range the range to test, may be {@code null}
* @return {@code true} if the specified range occurs entirely within
* this range; otherwise, {@code false}
* @throws IllegalArgumentException if the {@code Range} cannot be compared
* @param otherRange the range to check, null returns false
* @return true if this range contains the specified range
* @throws RuntimeException if ranges cannot be compared
*/
public boolean containsAll(Range<T> range) {
if (range == null) {
public boolean containsRange(Range<T> otherRange) {
if (otherRange == null) {
return false;
}
return contains(range.getMinimum())
&& contains(range.getMaximum());
return contains(otherRange.minimum)
&& contains(otherRange.maximum);
}
/**
* <p>Tests whether the specified range overlaps with this range.</p>
* <p>Checks whether this range is completely after the specified range.</p>
*
* <p>{@code null} is handled and returns {@code false}.</p>
* <p>This method may fail if the ranges have two different comparators or element types.</p>
*
* @param range the range to test, may be {@code null}
* @return {@code true} if the specified range overlaps with this
* range; otherwise, {@code false}
* @throws IllegalArgumentException if the {@code Range} cannot be compared
* @param otherRange the range to check, null returns false
* @return true if this range is completely after the specified range
* @throws RuntimeException if ranges cannot be compared
*/
public boolean overlapsWith(Range<T> range) {
if (range == null) {
public boolean isAfterRange(Range<T> otherRange) {
if (otherRange == null) {
return false;
}
return range.contains(this.minimum)
|| range.contains(this.maximum)
|| contains(range.getMinimum());
return isAfter(otherRange.maximum);
}
/**
* <p>Checks whether this range is overlapped by the specified range.</p>
*
* <p>Two ranges overlap if there is at least one element in common.</p>
*
* <p>This method may fail if the ranges have two different comparators or element types.</p>
*
* @param otherRange the range to test, null returns false
* @return true if the specified range overlaps with this
* range; otherwise, {@code false}
* @throws RuntimeException if ranges cannot be compared
*/
public boolean isOverlappedBy(Range<T> otherRange) {
if (otherRange == null) {
return false;
}
return otherRange.contains(minimum)
|| otherRange.contains(maximum)
|| contains(otherRange.minimum);
}
/**
* <p>Checks whether this range is completely before the specified range.</p>
*
* <p>This method may fail if the ranges have two different comparators or element types.</p>
*
* @param otherRange the range to check, null returns false
* @return true if this range is completely before the specified range
* @throws RuntimeException if ranges cannot be compared
*/
public boolean isBeforeRange(Range<T> otherRange) {
if (otherRange == null) {
return false;
}
return isBefore(otherRange.minimum);
}
// Basics
@ -321,10 +378,11 @@ public boolean overlapsWith(Range<T> range) {
/**
* <p>Compares this range to another object to test if they are equal.</p>.
*
* <p>To be equal, the class, minimum and maximum must be equal.</p>
* <p>To be equal, the minimum and maximum values must be equal, which
* ignores any differences in the comparator.</p>
*
* @param obj the reference object with which to compare
* @return {@code true} if this object is equal
* @return true if this object is equal
*/
@Override
public boolean equals(Object obj) {
@ -335,13 +393,13 @@ public boolean equals(Object obj) {
} else {
@SuppressWarnings("unchecked") // OK because we checked the class above
Range<T> range = (Range<T>) obj;
return getMinimum().equals(range.getMinimum()) &&
getMaximum().equals(range.getMaximum());
return minimum.equals(range.minimum) &&
maximum.equals(range.maximum);
}
}
/**
* <p>Gets a hashCode for the range.</p>
* <p>Gets a suitable hash code for the range.</p>
*
* @return a hash code value for this object
*/
@ -351,8 +409,8 @@ public int hashCode() {
if (hashCode == 0) {
result = 17;
result = 37 * result + getClass().hashCode();
result = 37 * result + this.minimum.hashCode();
result = 37 * result + this.maximum.hashCode();
result = 37 * result + minimum.hashCode();
result = 37 * result + maximum.hashCode();
hashCode = result;
}
return result;
@ -361,7 +419,7 @@ public int hashCode() {
/**
* <p>Gets the range as a {@code String}.</p>
*
* <p>The format of the String is 'Range[<i>min</i>,<i>max</i>]'.</p>
* <p>The format of the String is '[<i>min</i>..<i>max</i>]'.</p>
*
* @return the {@code String} representation of this range
*/
@ -370,10 +428,10 @@ public String toString() {
String result = toString;
if (result == null) {
StringBuilder buf = new StringBuilder(32);
buf.append("Range[");
buf.append(this.minimum);
buf.append(',');
buf.append(this.maximum);
buf.append('[');
buf.append(minimum);
buf.append("..");
buf.append(maximum);
buf.append(']');
result = buf.toString();
toString = result;
@ -381,54 +439,29 @@ public String toString() {
return result;
}
// Taken from Commons Collections - documentation removed as not a public class
private static class ComparableComparator<E extends Comparable<? super E>> implements Comparator<E>, Serializable {
/**
* <p>Formats the receiver using the given format.</p>
*
* <p>This uses {@link Formattable} to perform the formatting. Three variables may
* be used to embed the minimum, maximum and comparator.
* Use {@code %1$s} for the minimum element, {@code %2$s} for the maximum element
* and {@code %3$s} for the comparator.
* The default format used by {@code toString()} is {@code [%1$s..%2$s]}.</p>
*
* @param format the format string, optionally containing {@code %1$s}, {@code %2$s} and {@code %3$s}, not null
* @return the formatted string, not null
*/
public String toString(String format) {
return String.format(format, minimum, maximum, comparator);
}
private static final long serialVersionUID = 1L;
@SuppressWarnings("rawtypes") // Comparator works for all types
public static final ComparableComparator<?> INSTANCE = new ComparableComparator();
/**
* Returns a comparator for the specified {@code Comparable} type.
*
* @param <E> the {@code Comparable} type
* @return the comparator for this type
*/
@SuppressWarnings("unchecked") // OK to cast, because comparator works for all types
public static <E extends Comparable<? super E>> ComparableComparator<E> getInstance() {
return (ComparableComparator<E>) INSTANCE;
//-----------------------------------------------------------------------
@SuppressWarnings({"rawtypes", "unchecked"})
private enum ComparableComparator implements Comparator {
INSTANCE;
public int compare(Object obj1, Object obj2) {
return ((Comparable) obj1).compareTo(obj2);
}
/**
* Creates a new instance of {@code ComparableComparator}.
*/
public ComparableComparator() {
super();
}
/**
* Compares two objects.
*
* @param obj1 the first object
* @param obj2 the second object
* @return the result of the comparison
*/
public int compare(E obj1, E obj2) {
return obj1.compareTo(obj2);
}
@Override
public int hashCode() {
return "ComparableComparator".hashCode();
}
@Override
public boolean equals(Object object) {
return (this == object) ||
((null != object) && (object.getClass().equals(this.getClass())));
}
}
}

View File

@ -53,8 +53,8 @@ public void setUp() {
doubleRange = Range.between((double) 10, (double) 20);
}
// --------------------------------------------------------------------------
//-----------------------------------------------------------------------
@SuppressWarnings({ "rawtypes", "unchecked" })
public void testComparableConstructors() {
Comparable c =
new Comparable() {
@ -62,8 +62,10 @@ public int compareTo(Object other) {
return 1;
}
};
Range.is(c);
Range.between(c, c);
Range r1 = Range.is(c);
Range r2 = Range.between(c, c);
assertEquals(true, r1.isNaturalOrdering());
assertEquals(true, r2.isNaturalOrdering());
}
public void testIsWithCompare(){
@ -103,16 +105,14 @@ public int compare(Integer o1, Integer o2) {
assertTrue("should contain -11",rb.contains(-11));
}
// --------------------------------------------------------------------------
//-----------------------------------------------------------------------
public void testRangeOfChars() {
Range<Character> chars = Range.between('a', 'z');
assertTrue(chars.contains('b'));
assertFalse(chars.contains('B'));
}
// --------------------------------------------------------------------------
//-----------------------------------------------------------------------
public void testEqualsObject() {
assertEquals(byteRange, byteRange);
assertEquals(byteRange, byteRange2);
@ -128,29 +128,32 @@ public void testEqualsObject() {
public void testHashCode() {
assertEquals(byteRange.hashCode(), byteRange2.hashCode());
assertFalse(byteRange.hashCode() == byteRange3.hashCode());
assertEquals(intRange.hashCode(), intRange.hashCode());
assertTrue(intRange.hashCode() != 0);
}
public void testToString() {
assertNotNull(byteRange.toString());
String str = intRange.toString();
assertEquals("Range[10,20]", str);
// assertSame(str, intRange.toString()); // no longer passes - does it matter?
assertEquals("Range[-20,-10]", Range.between(-20, -10).toString());
assertEquals("[10..20]", str);
assertEquals("[-20..-10]", Range.between(-20, -10).toString());
}
// --------------------------------------------------------------------------
public void testToStringFormat() {
String str = intRange.toString("From %1$s to %2$s");
assertEquals("From 10 to 20", str);
}
//-----------------------------------------------------------------------
public void testGetMinimum() {
assertEquals(10, (int) intRange.getMinimum());
assertEquals(10L, (long) longRange.getMinimum());
assertEquals(10f, floatRange.getMinimum(), 0.00001f);
assertEquals(10d, doubleRange.getMinimum(), 0.00001d);
}
public void testGetMaximum() {
assertEquals(20, (int) intRange.getMaximum());
assertEquals(20L, (long) longRange.getMaximum());
@ -168,24 +171,44 @@ public void testContains() {
assertFalse(intRange.contains(25));
}
public void testElementBefore() {
assertFalse(intRange.elementBefore(null));
public void testIsAfter() {
assertFalse(intRange.isAfter(null));
assertTrue(intRange.elementBefore(5));
assertFalse(intRange.elementBefore(10));
assertFalse(intRange.elementBefore(15));
assertFalse(intRange.elementBefore(20));
assertFalse(intRange.elementBefore(25));
assertTrue(intRange.isAfter(5));
assertFalse(intRange.isAfter(10));
assertFalse(intRange.isAfter(15));
assertFalse(intRange.isAfter(20));
assertFalse(intRange.isAfter(25));
}
public void testElementAfter() {
assertFalse(intRange.elementAfter(null));
public void testIsStartedBy() {
assertFalse(intRange.isStartedBy(null));
assertFalse(intRange.elementAfter(5));
assertFalse(intRange.elementAfter(10));
assertFalse(intRange.elementAfter(15));
assertFalse(intRange.elementAfter(20));
assertTrue(intRange.elementAfter(25));
assertFalse(intRange.isStartedBy(5));
assertTrue(intRange.isStartedBy(10));
assertFalse(intRange.isStartedBy(15));
assertFalse(intRange.isStartedBy(20));
assertFalse(intRange.isStartedBy(25));
}
public void testIsEndedBy() {
assertFalse(intRange.isEndedBy(null));
assertFalse(intRange.isEndedBy(5));
assertFalse(intRange.isEndedBy(10));
assertFalse(intRange.isEndedBy(15));
assertTrue(intRange.isEndedBy(20));
assertFalse(intRange.isEndedBy(25));
}
public void testIsBefore() {
assertFalse(intRange.isBefore(null));
assertFalse(intRange.isBefore(5));
assertFalse(intRange.isBefore(10));
assertFalse(intRange.isBefore(15));
assertFalse(intRange.isBefore(20));
assertTrue(intRange.isBefore(25));
}
public void testElementCompareTo() {
@ -203,72 +226,100 @@ public void testElementCompareTo() {
assertEquals(1, intRange.elementCompareTo(25));
}
// --------------------------------------------------------------------------
public void testContainsAll() {
//-----------------------------------------------------------------------
public void testContainsRange() {
// null handling
assertFalse(intRange.containsAll(null));
assertFalse(intRange.containsRange(null));
// easy inside range
assertTrue(intRange.containsAll(Range.between(12, 18)));
assertTrue(intRange.containsRange(Range.between(12, 18)));
// outside range on each side
assertFalse(intRange.containsAll(Range.between(32, 45)));
assertFalse(intRange.containsAll(Range.between(2, 8)));
assertFalse(intRange.containsRange(Range.between(32, 45)));
assertFalse(intRange.containsRange(Range.between(2, 8)));
// equals range
assertTrue(intRange.containsAll(Range.between(10, 20)));
assertTrue(intRange.containsRange(Range.between(10, 20)));
// overlaps
assertFalse(intRange.containsAll(Range.between(9, 14)));
assertFalse(intRange.containsAll(Range.between(16, 21)));
assertFalse(intRange.containsRange(Range.between(9, 14)));
assertFalse(intRange.containsRange(Range.between(16, 21)));
// touches lower boundary
assertTrue(intRange.containsAll(Range.between(10, 19)));
assertFalse(intRange.containsAll(Range.between(10, 21)));
assertTrue(intRange.containsRange(Range.between(10, 19)));
assertFalse(intRange.containsRange(Range.between(10, 21)));
// touches upper boundary
assertTrue(intRange.containsAll(Range.between(11, 20)));
assertFalse(intRange.containsAll(Range.between(9, 20)));
assertTrue(intRange.containsRange(Range.between(11, 20)));
assertFalse(intRange.containsRange(Range.between(9, 20)));
// negative
assertFalse(intRange.containsAll(Range.between(-11, -18)));
assertFalse(intRange.containsRange(Range.between(-11, -18)));
}
public void testOverlapsWith() {
public void testIsAfterRange() {
assertFalse(intRange.isAfterRange(null));
assertTrue(intRange.isAfterRange(Range.between(5, 9)));
assertFalse(intRange.isAfterRange(Range.between(5, 10)));
assertFalse(intRange.isAfterRange(Range.between(5, 20)));
assertFalse(intRange.isAfterRange(Range.between(5, 25)));
assertFalse(intRange.isAfterRange(Range.between(15, 25)));
assertFalse(intRange.isAfterRange(Range.between(21, 25)));
assertFalse(intRange.isAfterRange(Range.between(10, 20)));
}
public void testIsOverlappedBy() {
// null handling
assertFalse(intRange.overlapsWith(null));
assertFalse(intRange.isOverlappedBy(null));
// easy inside range
assertTrue(intRange.overlapsWith(Range.between(12, 18)));
assertTrue(intRange.isOverlappedBy(Range.between(12, 18)));
// outside range on each side
assertFalse(intRange.overlapsWith(Range.between(32, 45)));
assertFalse(intRange.overlapsWith(Range.between(2, 8)));
assertFalse(intRange.isOverlappedBy(Range.between(32, 45)));
assertFalse(intRange.isOverlappedBy(Range.between(2, 8)));
// equals range
assertTrue(intRange.overlapsWith(Range.between(10, 20)));
assertTrue(intRange.isOverlappedBy(Range.between(10, 20)));
// overlaps
assertTrue(intRange.overlapsWith(Range.between(9, 14)));
assertTrue(intRange.overlapsWith(Range.between(16, 21)));
assertTrue(intRange.isOverlappedBy(Range.between(9, 14)));
assertTrue(intRange.isOverlappedBy(Range.between(16, 21)));
// touches lower boundary
assertTrue(intRange.overlapsWith(Range.between(10, 19)));
assertTrue(intRange.overlapsWith(Range.between(10, 21)));
assertTrue(intRange.isOverlappedBy(Range.between(10, 19)));
assertTrue(intRange.isOverlappedBy(Range.between(10, 21)));
// touches upper boundary
assertTrue(intRange.overlapsWith(Range.between(11, 20)));
assertTrue(intRange.overlapsWith(Range.between(9, 20)));
assertTrue(intRange.isOverlappedBy(Range.between(11, 20)));
assertTrue(intRange.isOverlappedBy(Range.between(9, 20)));
// negative
assertFalse(intRange.overlapsWith(Range.between(-11, -18)));
assertFalse(intRange.isOverlappedBy(Range.between(-11, -18)));
}
public void testIsBeforeRange() {
assertFalse(intRange.isBeforeRange(null));
assertFalse(intRange.isBeforeRange(Range.between(5, 9)));
assertFalse(intRange.isBeforeRange(Range.between(5, 10)));
assertFalse(intRange.isBeforeRange(Range.between(5, 20)));
assertFalse(intRange.isBeforeRange(Range.between(5, 25)));
assertFalse(intRange.isBeforeRange(Range.between(15, 25)));
assertTrue(intRange.isBeforeRange(Range.between(21, 25)));
assertFalse(intRange.isBeforeRange(Range.between(10, 20)));
}
//-----------------------------------------------------------------------
public void testSerializing() {
SerializationUtils.clone(intRange);
}