Skip to content

Commit e0d1465

Browse files
Remove assertion to ensure FiniteDateRange difference
1 parent f49dec0 commit e0d1465

File tree

2 files changed

+154
-2
lines changed

2 files changed

+154
-2
lines changed

tests/test_ranges.py

+113-1
Original file line numberDiff line numberDiff line change
@@ -865,7 +865,7 @@ def test_respects_other_range_boundaries(self, other):
865865

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

887887
assert 3 in subject
888888

889+
class TestDifference:
890+
def test_paco(self):
891+
r1 = ranges.FiniteDateRange(
892+
start=datetime.date(2024, 10, 1),
893+
end=datetime.date(2024, 10, 30),
894+
)
895+
r2 = ranges.FiniteDateRange(
896+
start=datetime.date(2024, 10, 5),
897+
end=datetime.date(2024, 10, 15),
898+
)
899+
r3 = ranges.FiniteDateRange(
900+
start=datetime.date(2024, 12, 1),
901+
end=datetime.date(2024, 12, 30),
902+
)
903+
f1 = ranges.FiniteRangeSet([r1])
904+
f2 = ranges.FiniteRangeSet([r2])
905+
f3 = ranges.FiniteRangeSet([r3])
906+
r1.difference(r2)
907+
r1.difference(r3)
908+
909+
f1-f2
910+
911+
912+
913+
def test_range_sets_overlap(self):
914+
range_set = ranges.FiniteRangeSet(
915+
[
916+
ranges.FiniteDateRange(
917+
start=datetime.date(2024, 10, 1),
918+
end=datetime.date(2024, 10, 31),
919+
)
920+
]
921+
)
922+
other = ranges.FiniteRangeSet(
923+
[
924+
ranges.FiniteDateRange(
925+
start=datetime.date(2024, 10, 1),
926+
end=datetime.date(2024, 10, 15),
927+
)
928+
]
929+
)
930+
difference = range_set.difference(other)
931+
932+
assert difference == ranges.FiniteRangeSet(
933+
[
934+
ranges.FiniteDateRange(
935+
start=datetime.date(2024, 10, 15),
936+
end=datetime.date(2024, 10, 31),
937+
)
938+
]
939+
)
940+
941+
def test_range_sets_overlap_multiple_ranges(self):
942+
range_set = ranges.FiniteRangeSet(
943+
[
944+
ranges.FiniteDateRange(
945+
start=datetime.date(2024, 1, 1),
946+
end=datetime.date(2024, 2, 28),
947+
),
948+
ranges.FiniteDateRange(
949+
start=datetime.date(2024, 5, 1),
950+
end=datetime.date(2024, 6, 30),
951+
),
952+
]
953+
)
954+
other = ranges.FiniteRangeSet(
955+
[
956+
ranges.FiniteDateRange(
957+
start=datetime.date(2024, 1, 1),
958+
end=datetime.date(2024, 2, 15),
959+
),
960+
ranges.FiniteDateRange(
961+
start=datetime.date(2024, 5, 15),
962+
end=datetime.date(2024, 6, 30),
963+
)
964+
]
965+
)
966+
difference = range_set.difference(other)
967+
968+
assert difference == ranges.FiniteRangeSet(
969+
[
970+
ranges.FiniteDateRange(
971+
start=datetime.date(2024, 2, 15),
972+
end=datetime.date(2024, 2, 28),
973+
),
974+
ranges.FiniteDateRange(
975+
start=datetime.date(2024, 5,1),
976+
end=datetime.date(2024, 5, 15),
977+
),
978+
]
979+
)
980+
981+
def test_difference_does_not_overlap(self):
982+
range_set = ranges.FiniteRangeSet(
983+
[
984+
ranges.FiniteDateRange(
985+
start=datetime.date(2024, 1, 1),
986+
end=datetime.date(2024, 1, 31),
987+
)
988+
]
989+
)
990+
other = ranges.FiniteRangeSet(
991+
[
992+
ranges.FiniteDateRange(
993+
start=datetime.date(2024, 3, 1),
994+
end=datetime.date(2024, 3, 31),
995+
)
996+
]
997+
)
998+
difference = range_set.difference(other)
999+
assert difference == range_set
1000+
8891001

8901002
class TestAsFiniteDatetimePeriods:
8911003
def test_converts(self):

xocto/ranges.py

+41-1
Original file line numberDiff line numberDiff line change
@@ -876,9 +876,49 @@ def intersection(self, other: Range[datetime.date]) -> Optional["FiniteDateRange
876876
if base_intersection is None:
877877
return None
878878

879-
assert base_intersection.boundaries == RangeBoundaries.INCLUSIVE_INCLUSIVE
880879
return FiniteDateRange(base_intersection.start, base_intersection.end)
881880

881+
def difference(self, other: Range[datetime.date]) -> Optional["FiniteDateRange"]:
882+
"""
883+
Difference between two FiniteDateRanges should produce a FiniteDateRange.
884+
"""
885+
if self.is_disjoint(other):
886+
return self
887+
888+
boundaries = RangeBoundaries.INCLUSIVE_INCLUSIVE
889+
890+
if (self.start is None and other.start is not None) or (
891+
self.start is not None
892+
and other.start is not None
893+
and not other._is_inside_left_bound(self.start)
894+
and self._is_inside_left_bound(other.start)
895+
):
896+
lower_part: Optional["Range[T]"] = Range(
897+
self.start, other.start, boundaries=boundaries
898+
)
899+
else:
900+
lower_part = None
901+
902+
if (self.end is None and other.end is not None) or (
903+
self.end is not None
904+
and other.end is not None
905+
and not other._is_inside_right_bound(self.end)
906+
and self._is_inside_right_bound(other.end)
907+
):
908+
upper_part: Optional["Range[T]"] = Range(
909+
other.end, self.end, boundaries=boundaries
910+
)
911+
else:
912+
upper_part = None
913+
914+
if lower_part is None and upper_part is None:
915+
return None
916+
elif lower_part is not None and upper_part is not None:
917+
return RangeSet([lower_part, upper_part])
918+
else:
919+
return lower_part or upper_part
920+
921+
882922
def union(self, other: Range[datetime.date]) -> Optional["FiniteDateRange"]:
883923
"""
884924
Unions between two FiniteDateRanges should produce a FiniteDateRange.

0 commit comments

Comments
 (0)