def test_len(self): self.assertEqual(0, len(RangeSet.create_mutable())) self.assertEqual( 1, len(RangeSet.create_mutable().add(Range.closed(1, 2)))) self.assertEqual( 2, len(RangeSet.create_mutable().add(Range.closed(1, 2)).add( Range.open(3, 4))), )
def test_ignores_smaller_sharing_lower_bound(self): range_set = RangeSet.create_mutable() range_set.add(Range.closed(1, 6)) range_set.add(Range.closed(1, 4)) self._test_invariants(range_set) self.assertEqual(tuple([Range.closed(1, 6)]), tuple(range_set.as_ranges()))
def test_fill_hole_exactly(self): range_set = RangeSet.create_mutable() range_set.add(Range.closed_open(1, 3)) range_set.add(Range.closed_open(4, 6)) range_set.add(Range.closed_open(3, 4)) self._test_invariants(range_set) self.assertTrue(Range.closed_open(1, 6) in range_set.as_ranges())
def test_range_containing1(self): range_set = RangeSet.create_mutable() range_set.add(Range.closed(3, 10)) self.assertEqual(Range.closed(3, 10), range_set.range_containing(5)) self.assertTrue(5 in range_set) self.assertIsNone(range_set.range_containing(1)) self.assertFalse(1 in range_set)
def test_fill_hole_with_overlap(self): range_set = RangeSet.create_mutable() range_set.add(Range.closed_open(1, 3)) range_set.add(Range.closed_open(4, 6)) range_set.add(Range.closed_open(2, 5)) self._test_invariants(range_set) self.assertEqual(tuple([Range.closed_open(1, 6)]), tuple(range_set.as_ranges()))
def test_range_clear(self) -> None: range_set: MutableRangeSet[int] = RangeSet.create_mutable() range_set.add_all( [Range.at_most(2), Range.open_closed(5, 8), Range.at_least(10)]) range_set.clear() self.assertEqual(0, len(range_set.as_ranges()))
def test_rightmost_containing_or_below(self): range_set = RangeSet.create_mutable().add_all(( Range.closed(-2, -1), Range.closed_open(0, 2), # we don't do [0, 2), [2.1, 3] because they will coalesce # ditto for (4, 5] and (5.1, 7) Range.closed(2.1, 3), Range.open_closed(4, 5), Range.open(5.1, 7), )) # probe value is in the middle of a set # [2.1 ... *2.5* ... 3] self.assertEqual(Range.closed(2.1, 3.0), range_set.rightmost_containing_or_below(2.5)) # probe value is at a closed upper limit # [2.1 .... *3*] self.assertEqual(Range.closed(2.1, 3.0), range_set.rightmost_containing_or_below(3.0)) # probe value is at a closed lower limit # [*2.1* .... 3] self.assertEqual(Range.closed(2.1, 3.0), range_set.rightmost_containing_or_below(2.1)) # probe value is at an open lower limit # [2.1 ... 3], (*4* ... 5] self.assertEqual(Range.closed(2.1, 3.0), range_set.rightmost_containing_or_below(4.0)) # probe value is at an open upper limit # [0 ... *2.1*) self.assertEqual(Range.closed_open(0.0, 2.0), range_set.rightmost_containing_or_below(2.0)) # probe value falls into a gap # [-2, -1] ... *-0.5* ... [0, 2) self.assertEqual(Range.closed(-2.0, -1.0), range_set.rightmost_containing_or_below(-0.5)) # no range below # *-3* .... [-2,-1] self.assertIsNone(range_set.rightmost_containing_or_below(-3.0)) # empty rangeset self.assertIsNone(RangeSet.create_mutable().add(Range.closed( 1.0, 2.0)).rightmost_containing_or_below(0.0)) # lowest range has open lower bound # (*1*,2) self.assertIsNone(RangeSet.create_mutable().add(Range.open( 1.0, 2.0)).rightmost_containing_or_below(1.0))
def test_leftmost_containing_or_above(self): range_set = RangeSet.create_mutable().add_all(( Range.closed(-2, -1), Range.closed_open(0, 2), # we don't do [0, 2), [2.1, 3] because they will coalesce # ditto for (4, 5] and (5.1, 7) Range.closed(2.1, 3), Range.open_closed(4, 5), Range.open(5.1, 7), )) # probe value is in the middle of a set # [2.1 ... *2.5* ... 3] self.assertEqual(Range.closed(2.1, 3.0), range_set.leftmost_containing_or_above(2.5)) # probe value is at a closed upper limit # [2.1 .... *3*] self.assertEqual(Range.closed(2.1, 3.0), range_set.leftmost_containing_or_above(3.0)) # probe value is at a closed lower limit # [*2.1* .... 3] self.assertEqual(Range.closed(2.1, 3.0), range_set.leftmost_containing_or_above(2.1)) # probe value is at an open lower limit # [2 ... 3], (*4* ... 5] self.assertEqual(Range.open_closed(4.0, 5.0), range_set.leftmost_containing_or_above(4.0)) # probe value is at an open upper limit # [0 ... *2*) [2.1, 3.0] self.assertEqual(Range.closed(2.1, 3.0), range_set.leftmost_containing_or_above(2.0)) # probe value falls into a gap # [-2, -1] ... *-0.5* ... [0, 2) self.assertEqual(Range.closed_open(0, 2), range_set.leftmost_containing_or_above(-0.5)) # no range above # (5.1 ... 7) ... *8* self.assertIsNone(range_set.leftmost_containing_or_above(8)) # empty rangeset self.assertIsNone(RangeSet.create_mutable().add(Range.closed( 1.0, 2.0)).leftmost_containing_or_above(3.0)) # higher range has open upper bound # (1,*2*) self.assertIsNone(RangeSet.create_mutable().add(Range.open( 1.0, 2.0)).leftmost_containing_or_above(2.0))
def test_add_all(self): range_set = RangeSet.create_mutable() range_set.add(Range.closed(3, 10)) range_set.add_all( [Range.open(1, 3), Range.closed(5, 8), Range.closed(9, 11)]) self.assertEqual(tuple(range_set.as_ranges()), tuple([Range.open_closed(1, 11)]))
def test_range_enclosing_range(self) -> None: range_set: MutableRangeSet[int] = RangeSet.create_mutable() range_set.add_all( [Range.at_most(2), Range.open_closed(5, 8), Range.at_least(10)]) self.assertEqual(None, range_set.range_enclosing_range(Range.closed(2, 3))) self.assertEqual(Range.at_most(2), range_set.range_enclosing_range(Range.open(-1, 0))) self.assertEqual( Range.open_closed(5, 8), range_set.range_enclosing_range(Range.closed_open(6, 7)), ) self.assertEqual(None, range_set.range_enclosing_range(Range.closed(5, 8)))
def _pair_test(self, a: Range[int], b: Range[int]) -> None: range_set: MutableRangeSet[int] = RangeSet.create_mutable() range_set.add(a) range_set.add(b) if a.is_empty() and b.is_empty(): self.assertTrue(range_set.is_empty()) self.assertFalse(range_set.as_ranges()) elif a.is_empty(): self.assertTrue(b in range_set.as_ranges()) elif b.is_empty(): self.assertTrue(a in range_set.as_ranges()) elif a.is_connected(b): self.assertEqual(tuple(range_set.as_ranges()), tuple([a.span(b)])) else: if a.lower_endpoint < b.lower_endpoint: self.assertEqual(tuple(range_set.as_ranges()), tuple([a, b])) else: self.assertEqual(ImmutableSet.of([a, b]), ImmutableSet.of(range_set.as_ranges()))
def test_intersect_ranges(self): range_set = RangeSet.create_mutable() range_set.add_all([ Range.closed(2, 4), Range.closed(5, 7), Range.closed(10, 12), Range.closed(18, 20), ]) self.assertEqual( range_set.ranges_overlapping(Range.closed(19, 21)), immutableset([Range.closed(18, 20)]), ) self.assertEqual( range_set.ranges_overlapping(Range.closed(11, 19)), immutableset([Range.closed(10, 12), Range.closed(18, 20)]), ) self.assertEqual(range_set.ranges_overlapping(Range.closed(0, 1)), immutableset()) self.assertEqual(range_set.ranges_overlapping(Range.closed(21, 23)), immutableset()) self.assertEqual(range_set.ranges_overlapping(Range.closed(13, 15)), immutableset()) self.assertEqual( range_set.ranges_overlapping(Range.closed(0, 2)), immutableset([Range.closed(2, 4)]), ) self.assertEqual( range_set.ranges_overlapping(Range.closed(12, 15)), immutableset([Range.closed(10, 12)]), ) self.assertEqual( range_set.ranges_overlapping(Range.closed(5, 16)), immutableset([Range.closed(5, 7), Range.closed(10, 12)]), )
def test_all_pair_ranges_enclosing(self): for query_range_1 in TestRangeSet.QUERY_RANGES: for query_range_2 in TestRangeSet.QUERY_RANGES: self._test_encloses(RangeSet.create_mutable().add( query_range_1).add(query_range_2))
def test_all_single_ranges_enclosing(self): for query_range in TestRangeSet.QUERY_RANGES: self._test_encloses(RangeSet.create_mutable().add(query_range))
def test_empty_intersects(self): self._test_intersects(RangeSet.create_mutable())
def test_empty_enclosing(self): self._test_encloses(RangeSet.create_mutable())
def test_merges_connected_disjoint(self): range_set = RangeSet.create_mutable() range_set.add(Range.closed(1, 4)) range_set.add(Range.open(4, 6)) self._test_invariants(range_set) self.assertTrue(Range.closed_open(1, 6) in range_set.as_ranges())
def test_ranges_enclosed_by_out_of_bounds(self) -> None: self.assertEqual( ImmutableSet.empty(), RangeSet.create_mutable() # type: ignore .add(Range.closed(0, 10)).ranges_enclosed_by(Range.at_least(20)), )
def test_all_two_ranges_intersecting(self): for query_1 in TestRangeSet.QUERY_RANGES: for query_2 in TestRangeSet.QUERY_RANGES: self._test_intersects( RangeSet.create_mutable().add(query_1).add(query_2))
def test_ignores_smaller_sharing_upper_bound(self): range_set = RangeSet.create_mutable() range_set.add(Range.closed(1, 6)) range_set.add(Range.closed(3, 6)) self._test_invariants(range_set) self.assertTrue(Range.closed(1, 6) in range_set.as_ranges())
def test_all_single_ranges_intersecting(self): for query in TestRangeSet.QUERY_RANGES: self._test_intersects(RangeSet.create_mutable().add(query))
def test_ignores_equal(self): range_set = RangeSet.create_mutable() range_set.add(Range.closed(1, 6)) range_set.add(Range.closed(1, 6)) self._test_invariants(range_set) self.assertTrue(Range.closed(1, 6) in range_set.as_ranges())
def test_extend_same_upper_bound(self): range_set = RangeSet.create_mutable() range_set.add(Range.closed(3, 6)) range_set.add(Range.closed(1, 6)) self._test_invariants(range_set) self.assertTrue(Range.closed(1, 6) in range_set.as_ranges())
def test_extend_both_directions(self): range_set = RangeSet.create_mutable() range_set.add(Range.closed(3, 4)) range_set.add(Range.closed(1, 6)) self._test_invariants(range_set) self.assertTrue(Range.closed(1, 6) in range_set.as_ranges())
def test_add_empty(self): range_set = RangeSet.create_mutable() range_set.add(Range.closed_open(3, 3)) self._test_invariants(range_set) self.assertTrue(len(range_set.as_ranges()) == 0) self.assertTrue(range_set.is_empty())