Skip to content

Commit

Permalink
Remove assertion to ensure FiniteDateRange difference
Browse files Browse the repository at this point in the history
  • Loading branch information
raulruizgarcia committed Aug 20, 2024
1 parent f49dec0 commit e0d1465
Show file tree
Hide file tree
Showing 2 changed files with 154 additions and 2 deletions.
114 changes: 113 additions & 1 deletion tests/test_ranges.py
Original file line number Diff line number Diff line change
Expand Up @@ -865,7 +865,7 @@ def test_respects_other_range_boundaries(self, other):

def test_doesnt_extend_union(self):
"""
A union of ranges should be longer than the sum of it's parts.
A union of ranges should not be longer than the sum of it's parts.
"""
# This is a weird test to include, it is added because this feels like an
# obvious risk with the implementation I have used.
Expand All @@ -886,6 +886,118 @@ def test_finite_range(self):

assert 3 in subject

class TestDifference:
def test_paco(self):
r1 = ranges.FiniteDateRange(
start=datetime.date(2024, 10, 1),
end=datetime.date(2024, 10, 30),
)
r2 = ranges.FiniteDateRange(
start=datetime.date(2024, 10, 5),
end=datetime.date(2024, 10, 15),
)
r3 = ranges.FiniteDateRange(
start=datetime.date(2024, 12, 1),
end=datetime.date(2024, 12, 30),
)
f1 = ranges.FiniteRangeSet([r1])
f2 = ranges.FiniteRangeSet([r2])
f3 = ranges.FiniteRangeSet([r3])
r1.difference(r2)
r1.difference(r3)

f1-f2



def test_range_sets_overlap(self):
range_set = ranges.FiniteRangeSet(
[
ranges.FiniteDateRange(
start=datetime.date(2024, 10, 1),
end=datetime.date(2024, 10, 31),
)
]
)
other = ranges.FiniteRangeSet(
[
ranges.FiniteDateRange(
start=datetime.date(2024, 10, 1),
end=datetime.date(2024, 10, 15),
)
]
)
difference = range_set.difference(other)

assert difference == ranges.FiniteRangeSet(
[
ranges.FiniteDateRange(
start=datetime.date(2024, 10, 15),
end=datetime.date(2024, 10, 31),
)
]
)

def test_range_sets_overlap_multiple_ranges(self):
range_set = ranges.FiniteRangeSet(
[
ranges.FiniteDateRange(
start=datetime.date(2024, 1, 1),
end=datetime.date(2024, 2, 28),
),
ranges.FiniteDateRange(
start=datetime.date(2024, 5, 1),
end=datetime.date(2024, 6, 30),
),
]
)
other = ranges.FiniteRangeSet(
[
ranges.FiniteDateRange(
start=datetime.date(2024, 1, 1),
end=datetime.date(2024, 2, 15),
),
ranges.FiniteDateRange(
start=datetime.date(2024, 5, 15),
end=datetime.date(2024, 6, 30),
)
]
)
difference = range_set.difference(other)

assert difference == ranges.FiniteRangeSet(
[
ranges.FiniteDateRange(
start=datetime.date(2024, 2, 15),
end=datetime.date(2024, 2, 28),
),
ranges.FiniteDateRange(
start=datetime.date(2024, 5,1),
end=datetime.date(2024, 5, 15),
),
]
)

def test_difference_does_not_overlap(self):
range_set = ranges.FiniteRangeSet(
[
ranges.FiniteDateRange(
start=datetime.date(2024, 1, 1),
end=datetime.date(2024, 1, 31),
)
]
)
other = ranges.FiniteRangeSet(
[
ranges.FiniteDateRange(
start=datetime.date(2024, 3, 1),
end=datetime.date(2024, 3, 31),
)
]
)
difference = range_set.difference(other)
assert difference == range_set


class TestAsFiniteDatetimePeriods:
def test_converts(self):
Expand Down
42 changes: 41 additions & 1 deletion xocto/ranges.py
Original file line number Diff line number Diff line change
Expand Up @@ -876,9 +876,49 @@ def intersection(self, other: Range[datetime.date]) -> Optional["FiniteDateRange
if base_intersection is None:
return None

assert base_intersection.boundaries == RangeBoundaries.INCLUSIVE_INCLUSIVE
return FiniteDateRange(base_intersection.start, base_intersection.end)

def difference(self, other: Range[datetime.date]) -> Optional["FiniteDateRange"]:
"""
Difference between two FiniteDateRanges should produce a FiniteDateRange.
"""
if self.is_disjoint(other):
return self

boundaries = RangeBoundaries.INCLUSIVE_INCLUSIVE

if (self.start is None and other.start is not None) or (
self.start is not None
and other.start is not None
and not other._is_inside_left_bound(self.start)
and self._is_inside_left_bound(other.start)
):
lower_part: Optional["Range[T]"] = Range(
self.start, other.start, boundaries=boundaries
)
else:
lower_part = None

if (self.end is None and other.end is not None) or (
self.end is not None
and other.end is not None
and not other._is_inside_right_bound(self.end)
and self._is_inside_right_bound(other.end)
):
upper_part: Optional["Range[T]"] = Range(
other.end, self.end, boundaries=boundaries
)
else:
upper_part = None

if lower_part is None and upper_part is None:
return None
elif lower_part is not None and upper_part is not None:
return RangeSet([lower_part, upper_part])
else:
return lower_part or upper_part


def union(self, other: Range[datetime.date]) -> Optional["FiniteDateRange"]:
"""
Unions between two FiniteDateRanges should produce a FiniteDateRange.
Expand Down

0 comments on commit e0d1465

Please sign in to comment.