forked from pandas-dev/pandas
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
REF: Add more pytest idiom to test_holiday.py (pandas-dev#25204)
- Loading branch information
Showing
6 changed files
with
399 additions
and
382 deletions.
There are no files selected for viewing
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
from datetime import datetime | ||
|
||
import pytest | ||
|
||
from pandas import DatetimeIndex | ||
import pandas.util.testing as tm | ||
|
||
from pandas.tseries.holiday import ( | ||
AbstractHolidayCalendar, Holiday, Timestamp, USFederalHolidayCalendar, | ||
USThanksgivingDay, get_calendar) | ||
|
||
|
||
@pytest.mark.parametrize("transform", [ | ||
lambda x: x, | ||
lambda x: x.strftime("%Y-%m-%d"), | ||
lambda x: Timestamp(x) | ||
]) | ||
def test_calendar(transform): | ||
start_date = datetime(2012, 1, 1) | ||
end_date = datetime(2012, 12, 31) | ||
|
||
calendar = USFederalHolidayCalendar() | ||
holidays = calendar.holidays(transform(start_date), transform(end_date)) | ||
|
||
expected = [ | ||
datetime(2012, 1, 2), | ||
datetime(2012, 1, 16), | ||
datetime(2012, 2, 20), | ||
datetime(2012, 5, 28), | ||
datetime(2012, 7, 4), | ||
datetime(2012, 9, 3), | ||
datetime(2012, 10, 8), | ||
datetime(2012, 11, 12), | ||
datetime(2012, 11, 22), | ||
datetime(2012, 12, 25) | ||
] | ||
|
||
assert list(holidays.to_pydatetime()) == expected | ||
|
||
|
||
def test_calendar_caching(): | ||
# see gh-9552. | ||
|
||
class TestCalendar(AbstractHolidayCalendar): | ||
def __init__(self, name=None, rules=None): | ||
super(TestCalendar, self).__init__(name=name, rules=rules) | ||
|
||
jan1 = TestCalendar(rules=[Holiday("jan1", year=2015, month=1, day=1)]) | ||
jan2 = TestCalendar(rules=[Holiday("jan2", year=2015, month=1, day=2)]) | ||
|
||
# Getting holidays for Jan 1 should not alter results for Jan 2. | ||
tm.assert_index_equal(jan1.holidays(), DatetimeIndex(["01-Jan-2015"])) | ||
tm.assert_index_equal(jan2.holidays(), DatetimeIndex(["02-Jan-2015"])) | ||
|
||
|
||
def test_calendar_observance_dates(): | ||
# see gh-11477 | ||
us_fed_cal = get_calendar("USFederalHolidayCalendar") | ||
holidays0 = us_fed_cal.holidays(datetime(2015, 7, 3), datetime( | ||
2015, 7, 3)) # <-- same start and end dates | ||
holidays1 = us_fed_cal.holidays(datetime(2015, 7, 3), datetime( | ||
2015, 7, 6)) # <-- different start and end dates | ||
holidays2 = us_fed_cal.holidays(datetime(2015, 7, 3), datetime( | ||
2015, 7, 3)) # <-- same start and end dates | ||
|
||
# These should all produce the same result. | ||
# | ||
# In addition, calling with different start and end | ||
# dates should not alter the output if we call the | ||
# function again with the same start and end date. | ||
tm.assert_index_equal(holidays0, holidays1) | ||
tm.assert_index_equal(holidays0, holidays2) | ||
|
||
|
||
def test_rule_from_name(): | ||
us_fed_cal = get_calendar("USFederalHolidayCalendar") | ||
assert us_fed_cal.rule_from_name("Thanksgiving") == USThanksgivingDay |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
from datetime import datetime | ||
|
||
from pandas.tseries.holiday import ( | ||
AbstractHolidayCalendar, USMartinLutherKingJr, USMemorialDay) | ||
|
||
|
||
def test_no_mlk_before_1986(): | ||
# see gh-10278 | ||
class MLKCalendar(AbstractHolidayCalendar): | ||
rules = [USMartinLutherKingJr] | ||
|
||
holidays = MLKCalendar().holidays(start="1984", | ||
end="1988").to_pydatetime().tolist() | ||
|
||
# Testing to make sure holiday is not incorrectly observed before 1986. | ||
assert holidays == [datetime(1986, 1, 20, 0, 0), | ||
datetime(1987, 1, 19, 0, 0)] | ||
|
||
|
||
def test_memorial_day(): | ||
class MemorialDay(AbstractHolidayCalendar): | ||
rules = [USMemorialDay] | ||
|
||
holidays = MemorialDay().holidays(start="1971", | ||
end="1980").to_pydatetime().tolist() | ||
|
||
# Fixes 5/31 error and checked manually against Wikipedia. | ||
assert holidays == [datetime(1971, 5, 31, 0, 0), | ||
datetime(1972, 5, 29, 0, 0), | ||
datetime(1973, 5, 28, 0, 0), | ||
datetime(1974, 5, 27, 0, 0), | ||
datetime(1975, 5, 26, 0, 0), | ||
datetime(1976, 5, 31, 0, 0), | ||
datetime(1977, 5, 30, 0, 0), | ||
datetime(1978, 5, 29, 0, 0), | ||
datetime(1979, 5, 28, 0, 0)] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,193 @@ | ||
from datetime import datetime | ||
|
||
import pytest | ||
from pytz import utc | ||
|
||
import pandas.util.testing as tm | ||
|
||
from pandas.tseries.holiday import ( | ||
MO, SA, AbstractHolidayCalendar, DateOffset, EasterMonday, GoodFriday, | ||
Holiday, HolidayCalendarFactory, Timestamp, USColumbusDay, USLaborDay, | ||
USMartinLutherKingJr, USMemorialDay, USPresidentsDay, USThanksgivingDay, | ||
get_calendar, next_monday) | ||
|
||
|
||
def _check_holiday_results(holiday, start, end, expected): | ||
""" | ||
Check that the dates for a given holiday match in date and timezone. | ||
Parameters | ||
---------- | ||
holiday : Holiday | ||
The holiday to check. | ||
start : datetime-like | ||
The start date of range in which to collect dates for a given holiday. | ||
end : datetime-like | ||
The end date of range in which to collect dates for a given holiday. | ||
expected : list | ||
The list of dates we expect to get. | ||
""" | ||
assert list(holiday.dates(start, end)) == expected | ||
|
||
# Verify that timezone info is preserved. | ||
assert (list(holiday.dates(utc.localize(Timestamp(start)), | ||
utc.localize(Timestamp(end)))) == | ||
[utc.localize(dt) for dt in expected]) | ||
|
||
|
||
@pytest.mark.parametrize("holiday,start_date,end_date,expected", [ | ||
(USMemorialDay, datetime(2011, 1, 1), datetime(2020, 12, 31), | ||
[datetime(2011, 5, 30), datetime(2012, 5, 28), datetime(2013, 5, 27), | ||
datetime(2014, 5, 26), datetime(2015, 5, 25), datetime(2016, 5, 30), | ||
datetime(2017, 5, 29), datetime(2018, 5, 28), datetime(2019, 5, 27), | ||
datetime(2020, 5, 25)]), | ||
(Holiday("July 4th Eve", month=7, day=3), "2001-01-01", "2003-03-03", | ||
[Timestamp("2001-07-03 00:00:00"), Timestamp("2002-07-03 00:00:00")]), | ||
(Holiday("July 4th Eve", month=7, day=3, days_of_week=(0, 1, 2, 3)), | ||
"2001-01-01", "2008-03-03", [ | ||
Timestamp("2001-07-03 00:00:00"), Timestamp("2002-07-03 00:00:00"), | ||
Timestamp("2003-07-03 00:00:00"), Timestamp("2006-07-03 00:00:00"), | ||
Timestamp("2007-07-03 00:00:00")]), | ||
(EasterMonday, datetime(2011, 1, 1), datetime(2020, 12, 31), | ||
[Timestamp("2011-04-25 00:00:00"), Timestamp("2012-04-09 00:00:00"), | ||
Timestamp("2013-04-01 00:00:00"), Timestamp("2014-04-21 00:00:00"), | ||
Timestamp("2015-04-06 00:00:00"), Timestamp("2016-03-28 00:00:00"), | ||
Timestamp("2017-04-17 00:00:00"), Timestamp("2018-04-02 00:00:00"), | ||
Timestamp("2019-04-22 00:00:00"), Timestamp("2020-04-13 00:00:00")]), | ||
(GoodFriday, datetime(2011, 1, 1), datetime(2020, 12, 31), | ||
[Timestamp("2011-04-22 00:00:00"), Timestamp("2012-04-06 00:00:00"), | ||
Timestamp("2013-03-29 00:00:00"), Timestamp("2014-04-18 00:00:00"), | ||
Timestamp("2015-04-03 00:00:00"), Timestamp("2016-03-25 00:00:00"), | ||
Timestamp("2017-04-14 00:00:00"), Timestamp("2018-03-30 00:00:00"), | ||
Timestamp("2019-04-19 00:00:00"), Timestamp("2020-04-10 00:00:00")]), | ||
(USThanksgivingDay, datetime(2011, 1, 1), datetime(2020, 12, 31), | ||
[datetime(2011, 11, 24), datetime(2012, 11, 22), datetime(2013, 11, 28), | ||
datetime(2014, 11, 27), datetime(2015, 11, 26), datetime(2016, 11, 24), | ||
datetime(2017, 11, 23), datetime(2018, 11, 22), datetime(2019, 11, 28), | ||
datetime(2020, 11, 26)]) | ||
]) | ||
def test_holiday_dates(holiday, start_date, end_date, expected): | ||
_check_holiday_results(holiday, start_date, end_date, expected) | ||
|
||
|
||
@pytest.mark.parametrize("holiday,start,expected", [ | ||
(USMemorialDay, datetime(2015, 7, 1), []), | ||
(USMemorialDay, "2015-05-25", "2015-05-25"), | ||
(USLaborDay, datetime(2015, 7, 1), []), | ||
(USLaborDay, "2015-09-07", "2015-09-07"), | ||
(USColumbusDay, datetime(2015, 7, 1), []), | ||
(USColumbusDay, "2015-10-12", "2015-10-12"), | ||
(USThanksgivingDay, datetime(2015, 7, 1), []), | ||
(USThanksgivingDay, "2015-11-26", "2015-11-26"), | ||
(USMartinLutherKingJr, datetime(2015, 7, 1), []), | ||
(USMartinLutherKingJr, "2015-01-19", "2015-01-19"), | ||
(USPresidentsDay, datetime(2015, 7, 1), []), | ||
(USPresidentsDay, "2015-02-16", "2015-02-16"), | ||
(GoodFriday, datetime(2015, 7, 1), []), | ||
(GoodFriday, "2015-04-03", "2015-04-03"), | ||
(EasterMonday, "2015-04-06", "2015-04-06"), | ||
(EasterMonday, datetime(2015, 7, 1), []), | ||
(EasterMonday, "2015-04-05", []), | ||
("New Years Day", "2015-01-01", "2015-01-01"), | ||
("New Years Day", "2010-12-31", "2010-12-31"), | ||
("New Years Day", datetime(2015, 7, 1), []), | ||
("New Years Day", "2011-01-01", []), | ||
("July 4th", "2015-07-03", "2015-07-03"), | ||
("July 4th", datetime(2015, 7, 1), []), | ||
("July 4th", "2015-07-04", []), | ||
("Veterans Day", "2012-11-12", "2012-11-12"), | ||
("Veterans Day", datetime(2015, 7, 1), []), | ||
("Veterans Day", "2012-11-11", []), | ||
("Christmas", "2011-12-26", "2011-12-26"), | ||
("Christmas", datetime(2015, 7, 1), []), | ||
("Christmas", "2011-12-25", []), | ||
]) | ||
def test_holidays_within_dates(holiday, start, expected): | ||
# see gh-11477 | ||
# | ||
# Fix holiday behavior where holiday.dates returned dates outside | ||
# start/end date, or observed rules could not be applied because the | ||
# holiday was not in the original date range (e.g., 7/4/2015 -> 7/3/2015). | ||
if isinstance(holiday, str): | ||
calendar = get_calendar("USFederalHolidayCalendar") | ||
holiday = calendar.rule_from_name(holiday) | ||
|
||
if isinstance(expected, str): | ||
expected = [Timestamp(expected)] | ||
|
||
_check_holiday_results(holiday, start, start, expected) | ||
|
||
|
||
@pytest.mark.parametrize("transform", [ | ||
lambda x: x.strftime("%Y-%m-%d"), | ||
lambda x: Timestamp(x) | ||
]) | ||
def test_argument_types(transform): | ||
start_date = datetime(2011, 1, 1) | ||
end_date = datetime(2020, 12, 31) | ||
|
||
holidays = USThanksgivingDay.dates(start_date, end_date) | ||
holidays2 = USThanksgivingDay.dates( | ||
transform(start_date), transform(end_date)) | ||
tm.assert_index_equal(holidays, holidays2) | ||
|
||
|
||
@pytest.mark.parametrize("name,kwargs", [ | ||
("One-Time", dict(year=2012, month=5, day=28)), | ||
("Range", dict(month=5, day=28, start_date=datetime(2012, 1, 1), | ||
end_date=datetime(2012, 12, 31), | ||
offset=DateOffset(weekday=MO(1)))) | ||
]) | ||
def test_special_holidays(name, kwargs): | ||
base_date = [datetime(2012, 5, 28)] | ||
holiday = Holiday(name, **kwargs) | ||
|
||
start_date = datetime(2011, 1, 1) | ||
end_date = datetime(2020, 12, 31) | ||
|
||
assert base_date == holiday.dates(start_date, end_date) | ||
|
||
|
||
def test_get_calendar(): | ||
class TestCalendar(AbstractHolidayCalendar): | ||
rules = [] | ||
|
||
calendar = get_calendar("TestCalendar") | ||
assert TestCalendar == calendar.__class__ | ||
|
||
|
||
def test_factory(): | ||
class_1 = HolidayCalendarFactory("MemorialDay", | ||
AbstractHolidayCalendar, | ||
USMemorialDay) | ||
class_2 = HolidayCalendarFactory("Thanksgiving", | ||
AbstractHolidayCalendar, | ||
USThanksgivingDay) | ||
class_3 = HolidayCalendarFactory("Combined", class_1, class_2) | ||
|
||
assert len(class_1.rules) == 1 | ||
assert len(class_2.rules) == 1 | ||
assert len(class_3.rules) == 2 | ||
|
||
|
||
def test_both_offset_observance_raises(): | ||
# see gh-10217 | ||
msg = "Cannot use both offset and observance" | ||
with pytest.raises(NotImplementedError, match=msg): | ||
Holiday("Cyber Monday", month=11, day=1, | ||
offset=[DateOffset(weekday=SA(4))], | ||
observance=next_monday) |
Oops, something went wrong.