]> source.dussan.org Git - vaadin-framework.git/commitdiff
Add expansion and limiting for Range (#13334)
authorLeif Åstrand <leif@vaadin.com>
Thu, 17 Apr 2014 13:37:19 +0000 (16:37 +0300)
committerVaadin Code Review <review@vaadin.com>
Fri, 30 May 2014 10:04:04 +0000 (10:04 +0000)
The added functionality is used by the upcoming caching logic.

Change-Id: Ibc4e7103241b2199b85bf7727339d1f6a4b5fc9b

shared/src/com/vaadin/shared/ui/grid/Range.java
shared/tests/src/com/vaadin/shared/ui/grid/RangeTest.java

index 2593f7afd9749302b964904806fd8d6a0956e110..c28502256ca6c89932996ece382cc5233df42f07 100644 (file)
@@ -377,4 +377,55 @@ public final class Range implements Serializable {
         return Range.between(Math.min(getStart(), other.getStart()),
                 Math.max(getEnd(), other.getEnd()));
     }
+
+    /**
+     * Creates a range that is expanded the given amounts in both ends.
+     * 
+     * @param startDelta
+     *            the amount to expand by in the beginning of the range
+     * @param endDelta
+     *            the amount to expand by in the end of the range
+     * 
+     * @return an expanded range
+     * 
+     * @throws IllegalArgumentException
+     *             if the new range would have <code>start &gt; end</code>
+     */
+    public Range expand(int startDelta, int endDelta)
+            throws IllegalArgumentException {
+        return Range.between(getStart() - startDelta, getEnd() + endDelta);
+    }
+
+    /**
+     * Limits this range to be within the bounds of the provided range.
+     * <p>
+     * This is basically an optimized way of calculating
+     * <code>{@link #partitionWith(Range)}[1]</code> without the overhead of
+     * defining the parts that do not overlap.
+     * <p>
+     * If the two ranges do not intersect, an empty range is returned. There are
+     * no guarantees about the position of that range.
+     * 
+     * @param bounds
+     *            the bounds that the returned range should be limited to
+     * @return a bounded range
+     */
+    public Range restrictTo(Range bounds) {
+        boolean startWithin = getStart() >= bounds.getStart();
+        boolean endWithin = getEnd() <= bounds.getEnd();
+
+        if (startWithin) {
+            if (endWithin) {
+                return this;
+            } else {
+                return Range.between(getStart(), bounds.getEnd());
+            }
+        } else {
+            if (endWithin) {
+                return Range.between(bounds.getStart(), getEnd());
+            } else {
+                return bounds;
+            }
+        }
+    }
 }
index b042cee5097ea0a03bc138a5b873164a241194ae..ab67b22d0bc3c71143ca829c38c05e6ba275f466 100644 (file)
@@ -315,4 +315,92 @@ public class RangeTest {
         assertEquals(r1, combined1);
     }
 
+    @Test
+    public void expand_basic() {
+        Range r1 = Range.between(5, 10);
+        Range r2 = r1.expand(2, 3);
+
+        assertEquals(Range.between(3, 13), r2);
+    }
+
+    @Test
+    public void expand_negativeLegal() {
+        Range r1 = Range.between(5, 10);
+
+        Range r2 = r1.expand(-2, -2);
+        assertEquals(Range.between(7, 8), r2);
+
+        Range r3 = r1.expand(-3, -2);
+        assertEquals(Range.between(8, 8), r3);
+
+        Range r4 = r1.expand(3, -8);
+        assertEquals(Range.between(2, 2), r4);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void expand_negativeIllegal1() {
+        Range r1 = Range.between(5, 10);
+
+        // Should throw because the start would contract beyond the end
+        r1.expand(-3, -3);
+
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void expand_negativeIllegal2() {
+        Range r1 = Range.between(5, 10);
+
+        // Should throw because the end would contract beyond the start
+        r1.expand(3, -9);
+    }
+
+    @Test
+    public void restrictTo_fullyInside() {
+        Range r1 = Range.between(5, 10);
+        Range r2 = Range.between(4, 11);
+
+        Range r3 = r1.restrictTo(r2);
+        assertTrue(r1 == r3);
+    }
+
+    @Test
+    public void restrictTo_fullyOutside() {
+        Range r1 = Range.between(4, 11);
+        Range r2 = Range.between(5, 10);
+
+        Range r3 = r1.restrictTo(r2);
+        assertTrue(r2 == r3);
+    }
+
+    public void restrictTo_notInterstecting() {
+        Range r1 = Range.between(5, 10);
+        Range r2 = Range.between(15, 20);
+
+        Range r3 = r1.restrictTo(r2);
+        assertTrue("Non-intersecting ranges should produce an empty result",
+                r3.isEmpty());
+
+        Range r4 = r2.restrictTo(r1);
+        assertTrue("Non-intersecting ranges should produce an empty result",
+                r4.isEmpty());
+    }
+
+    public void restrictTo_startOutside() {
+        Range r1 = Range.between(5, 10);
+        Range r2 = Range.between(7, 15);
+
+        Range r3 = r1.restrictTo(r2);
+
+        assertEquals(Range.between(7, 10), r3);
+    }
+
+    public void restrictTo_endOutside() {
+        Range r1 = Range.between(5, 10);
+        Range r2 = Range.between(4, 7);
+
+        Range r3 = r1.restrictTo(r2);
+
+        assertEquals(Range.between(5, 7), r3);
+    }
+
 }