Skip to content

Commit 10d63ce

Browse files
committed
Rationalise period's offset tests
1 parent dbbb5a3 commit 10d63ce

3 files changed

Lines changed: 74 additions & 30 deletions

File tree

openfisca_core/periods/instant_.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
import calendar
66
import datetime
77

8+
from openfisca_core.types import Period
9+
810
from .. import periods
911
from . import config
1012

@@ -73,7 +75,7 @@ def __str__(self) -> str:
7375
return instant_str
7476

7577
@property
76-
def date(self) -> "datetime.date":
78+
def date(self) -> datetime.date:
7779
"""The date representation of the ``Instant``.
7880
7981
Example:
@@ -139,7 +141,7 @@ def day(self) -> int:
139141

140142
return self[2]
141143

142-
def period(self, unit: str, size: int = 1) -> "periods.Period":
144+
def period(self, unit: str, size: int = 1) -> Period:
143145
"""Creates a new ``Period`` starting at ``self``.
144146
145147
Args:
@@ -166,7 +168,7 @@ def period(self, unit: str, size: int = 1) -> "periods.Period":
166168
assert isinstance(size, int) and size >= 1, 'Invalid size: {} of type {}'.format(size, type(size))
167169
return periods.Period((unit, self, size))
168170

169-
def offset(self, offset: Union[str, int], unit: str) -> "Instant":
171+
def offset(self, offset: Union[str, int], unit: str) -> Instant:
170172
"""Increments/decrements the given instant with offset units.
171173
172174
Args:

openfisca_core/periods/period_.py

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ def __str__(self) -> str:
107107
return '{}:{}-{:02d}:{}'.format(unit, year, month, size)
108108

109109
@property
110-
def date(self) -> "datetime.date":
110+
def date(self) -> datetime.date:
111111
"""The date representation of the ``period``'s' start date.
112112
113113
Returns:
@@ -152,7 +152,7 @@ def days(self) -> int:
152152

153153
return (self.stop.date - self.start.date).days + 1
154154

155-
def intersection(self, start: "Period", stop: "Period") -> Optional["Period"]:
155+
def intersection(self, start: Period, stop: Period) -> Optional[Period]:
156156
"""Intersects a period within ``start`` and ``stop`` boundaries.
157157
158158
Args:
@@ -172,28 +172,37 @@ def intersection(self, start: "Period", stop: "Period") -> Optional["Period"]:
172172
Period(('day', Instant((2023, 1, 1)), 562))
173173
174174
"""
175+
intersection_start: Instant
176+
intersection_stop: Instant
177+
period_start: Instant = self[1]
178+
period_stop: Instant = self.stop
175179

176180
if start is None and stop is None:
177181
return self
178-
period_start = self[1]
179-
period_stop = self.stop
182+
180183
if start is None:
181184
start = period_start
185+
182186
if stop is None:
183187
stop = period_stop
188+
184189
if stop < period_start or period_stop < start:
185190
return None
186-
intersection_start = max(period_start, start)
187-
intersection_stop = min(period_stop, stop)
191+
192+
intersection_start = Instant(max(period_start, start))
193+
intersection_stop = Instant(min(period_stop, stop))
194+
188195
if intersection_start == period_start and intersection_stop == period_stop:
189196
return self
197+
190198
if intersection_start.day == 1 and intersection_start.month == 1 \
191199
and intersection_stop.day == 31 and intersection_stop.month == 12:
192200
return self.__class__((
193201
'year',
194202
intersection_start,
195203
intersection_stop.year - intersection_start.year + 1,
196204
))
205+
197206
if intersection_start.day == 1 and intersection_stop.day == calendar.monthrange(intersection_stop.year,
198207
intersection_stop.month)[1]:
199208
return self.__class__((
@@ -238,7 +247,7 @@ def get_subperiods(self, unit):
238247
if unit == config.DAY:
239248
return [self.first_day.offset(i, config.DAY) for i in range(self.size_in_days)]
240249

241-
def offset(self, offset: Union[str, int], unit: Optional[str] = None) -> "Period":
250+
def offset(self, offset: Union[str, int], unit: Optional[str] = None) -> Period:
242251
"""Increment (or decrement) the given ``period`` with offset units.
243252
244253
Args:
@@ -265,7 +274,7 @@ def offset(self, offset: Union[str, int], unit: Optional[str] = None) -> "Period
265274

266275
return self.__class__((self[0], self[1].offset(offset, self[0] if unit is None else unit), self[2]))
267276

268-
def contains(self, other: "Period") -> bool:
277+
def contains(self, other: Period) -> bool:
269278
"""Checks if a ``period`` contains another one.
270279
271280
Args:
@@ -432,7 +441,7 @@ def stop(self) -> "Instant":
432441
return Instant((year, month, day))
433442

434443
@property
435-
def unit(self) -> int:
444+
def unit(self) -> str:
436445
"""The ``unit`` of the ``Period``.
437446
438447
Returns:
@@ -452,28 +461,28 @@ def unit(self) -> int:
452461

453462
@property
454463
def last_3_months(self):
455-
return self.first_month.start.period('month', 3).offset(-3)
464+
return self.first_month.start.period("month", 3).offset(-3)
456465

457466
@property
458467
def last_month(self):
459468
return self.first_month.offset(-1)
460469

461470
@property
462471
def last_year(self):
463-
return self.start.offset("first-of", "year").period('year').offset(-1)
472+
return self.start.offset("first-of", "year").period("year").offset(-1)
464473

465474
@property
466475
def n_2(self):
467-
return self.start.offset("first-of", "year").period('year').offset(-2)
476+
return self.start.offset("first-of", "year").period("year").offset(-2)
468477

469478
@property
470479
def this_year(self):
471-
return self.start.offset("first-of", "year").period('year')
480+
return self.start.offset("first-of", "year").period("year")
472481

473482
@property
474483
def first_month(self):
475-
return self.start.offset("first-of", "month").period('month')
484+
return self.start.offset("first-of", "month").period("month")
476485

477486
@property
478487
def first_day(self):
479-
return self.start.period('day')
488+
return self.start.period("day")

openfisca_core/periods/tests/test_period.py

Lines changed: 45 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@
44
from openfisca_core.periods import Instant, Period
55

66

7+
@pytest.fixture
8+
def instant():
9+
return Instant((2022, 12, 31))
10+
11+
712
@pytest.mark.parametrize("date_unit, instant, size, expected", [
813
[periods.YEAR, Instant((2022, 1, 1)), 1, "2022"],
914
[periods.MONTH, Instant((2022, 1, 1)), 12, "2022"],
@@ -34,20 +39,48 @@ def test_str_with_days(date_unit, instant, size, expected):
3439
assert str(Period((date_unit, instant, size))) == expected
3540

3641

37-
@pytest.mark.parametrize("period, unit, length, first, last", [
38-
(periods.period('year:2014:2'), periods.YEAR, 2, periods.period('2014'), periods.period('2015')),
39-
(periods.period(2017), periods.MONTH, 12, periods.period('2017-01'), periods.period('2017-12')),
40-
(periods.period('year:2014:2'), periods.MONTH, 24, periods.period('2014-01'), periods.period('2015-12')),
41-
(periods.period('month:2014-03:3'), periods.MONTH, 3, periods.period('2014-03'), periods.period('2014-05')),
42-
(periods.period(2017), periods.DAY, 365, periods.period('2017-01-01'), periods.period('2017-12-31')),
43-
(periods.period('year:2014:2'), periods.DAY, 730, periods.period('2014-01-01'), periods.period('2015-12-31')),
44-
(periods.period('month:2014-03:3'), periods.DAY, 92, periods.period('2014-03-01'), periods.period('2014-05-31')),
42+
@pytest.mark.parametrize("period_unit, unit, start, cease, count", [
43+
[periods.YEAR, periods.YEAR, Instant((2022, 1, 1)), Instant((2024, 1, 1)), 3],
44+
[periods.YEAR, periods.MONTH, Instant((2022, 12, 1)), Instant((2025, 11, 1)), 36],
45+
[periods.YEAR, periods.DAY, Instant((2022, 12, 31)), Instant((2025, 12, 30)), 1096],
46+
[periods.MONTH, periods.MONTH, Instant((2022, 12, 1)), Instant((2023, 2, 1)), 3],
47+
[periods.MONTH, periods.DAY, Instant((2022, 12, 31)), Instant((2023, 3, 30)), 90],
48+
[periods.DAY, periods.DAY, Instant((2022, 12, 31)), Instant((2023, 1, 2)), 3],
4549
])
46-
def test_subperiods(period, unit, length, first, last):
50+
def test_subperiods(instant, period_unit, unit, start, cease, count):
51+
period = Period((period_unit, instant, 3))
4752
subperiods = period.get_subperiods(unit)
48-
assert len(subperiods) == length
49-
assert subperiods[0] == first
50-
assert subperiods[-1] == last
53+
assert len(subperiods) == count
54+
assert subperiods[0] == Period((unit, start, 1))
55+
assert subperiods[-1] == Period((unit, cease, 1))
56+
57+
58+
@pytest.mark.parametrize("period_unit, offset, unit, expected", [
59+
[periods.YEAR, "first-of", periods.YEAR, Period(('year', Instant((2022, 1, 1)), 3))],
60+
[periods.YEAR, "first-of", periods.MONTH, Period(('year', Instant((2022, 12, 1)), 3))],
61+
[periods.YEAR, "last-of", periods.YEAR, Period(('year', Instant((2022, 12, 31)), 3))],
62+
[periods.YEAR, "last-of", periods.MONTH, Period(('year', Instant((2022, 12, 31)), 3))],
63+
[periods.YEAR, -3, periods.YEAR, Period(('year', Instant((2019, 12, 31)), 3))],
64+
[periods.YEAR, 1, periods.MONTH, Period(('year', Instant((2023, 1, 31)), 3))],
65+
[periods.YEAR, 3, periods.DAY, Period(('year', Instant((2023, 1, 3)), 3))],
66+
[periods.MONTH, "first-of", periods.YEAR, Period(('month', Instant((2022, 1, 1)), 3))],
67+
[periods.MONTH, "first-of", periods.MONTH, Period(('month', Instant((2022, 12, 1)), 3))],
68+
[periods.MONTH, "last-of", periods.YEAR, Period(('month', Instant((2022, 12, 31)), 3))],
69+
[periods.MONTH, "last-of", periods.MONTH, Period(('month', Instant((2022, 12, 31)), 3))],
70+
[periods.MONTH, -3, periods.YEAR, Period(('month', Instant((2019, 12, 31)), 3))],
71+
[periods.MONTH, 1, periods.MONTH, Period(('month', Instant((2023, 1, 31)), 3))],
72+
[periods.MONTH, 3, periods.DAY, Period(('month', Instant((2023, 1, 3)), 3))],
73+
[periods.DAY, "first-of", periods.YEAR, Period(('day', Instant((2022, 1, 1)), 3))],
74+
[periods.DAY, "first-of", periods.MONTH, Period(('day', Instant((2022, 12, 1)), 3))],
75+
[periods.DAY, "last-of", periods.YEAR, Period(('day', Instant((2022, 12, 31)), 3))],
76+
[periods.DAY, "last-of", periods.MONTH, Period(('day', Instant((2022, 12, 31)), 3))],
77+
[periods.DAY, -3, periods.YEAR, Period(('day', Instant((2019, 12, 31)), 3))],
78+
[periods.DAY, 1, periods.MONTH, Period(('day', Instant((2023, 1, 31)), 3))],
79+
[periods.DAY, 3, periods.DAY, Period(('day', Instant((2023, 1, 3)), 3))],
80+
])
81+
def test_offset(instant, period_unit, offset, unit, expected):
82+
period = Period((period_unit, instant, 3))
83+
assert period.offset(offset, unit) == expected
5184

5285

5386
@pytest.mark.parametrize("date_unit, instant, size, expected", [

0 commit comments

Comments
 (0)