From d6d80a17444c90259c5bfdacb84c61e6bfece655 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Thu, 5 Jan 2023 11:38:41 +0100 Subject: Merging upstream version 3.0.0~a1. Signed-off-by: Daniel Baumann --- tests/interval/__init__.py | 0 tests/interval/test_add_subtract.py | 49 +++++++++++++++ tests/interval/test_arithmetic.py | 53 ++++++++++++++++ tests/interval/test_behavior.py | 54 ++++++++++++++++ tests/interval/test_construct.py | 121 ++++++++++++++++++++++++++++++++++++ tests/interval/test_hashing.py | 23 +++++++ tests/interval/test_in_words.py | 70 +++++++++++++++++++++ tests/interval/test_range.py | 119 +++++++++++++++++++++++++++++++++++ 8 files changed, 489 insertions(+) create mode 100644 tests/interval/__init__.py create mode 100644 tests/interval/test_add_subtract.py create mode 100644 tests/interval/test_arithmetic.py create mode 100644 tests/interval/test_behavior.py create mode 100644 tests/interval/test_construct.py create mode 100644 tests/interval/test_hashing.py create mode 100644 tests/interval/test_in_words.py create mode 100644 tests/interval/test_range.py (limited to 'tests/interval') diff --git a/tests/interval/__init__.py b/tests/interval/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/interval/test_add_subtract.py b/tests/interval/test_add_subtract.py new file mode 100644 index 0000000..88525a3 --- /dev/null +++ b/tests/interval/test_add_subtract.py @@ -0,0 +1,49 @@ +from __future__ import annotations + +import pendulum + + +def test_dst_add(): + start = pendulum.datetime(2017, 3, 7, tz="America/Toronto") + end = start.add(days=6) + period = end - start + new_end = start + period + + assert new_end == end + + +def test_dst_add_non_variable_units(): + start = pendulum.datetime(2013, 3, 31, 1, 30, tz="Europe/Paris") + end = start.add(hours=1) + period = end - start + new_end = start + period + + assert new_end == end + + +def test_dst_subtract(): + start = pendulum.datetime(2017, 3, 7, tz="America/Toronto") + end = start.add(days=6) + period = end - start + new_start = end - period + + assert new_start == start + + +def test_naive_subtract(): + start = pendulum.naive(2013, 3, 31, 1, 30) + end = start.add(hours=1) + period = end - start + new_end = start + period + + assert new_end == end + + +def test_negative_difference_subtract(): + start = pendulum.datetime(2018, 5, 28, 12, 34, 56, 123456) + end = pendulum.datetime(2018, 1, 1) + + period = end - start + new_end = start + period + + assert new_end == end diff --git a/tests/interval/test_arithmetic.py b/tests/interval/test_arithmetic.py new file mode 100644 index 0000000..e5ba01f --- /dev/null +++ b/tests/interval/test_arithmetic.py @@ -0,0 +1,53 @@ +from __future__ import annotations + +import pendulum + +from tests.conftest import assert_duration + + +def test_multiply(): + dt1 = pendulum.DateTime(2016, 8, 7, 12, 34, 56) + dt2 = dt1.add(days=6, seconds=34) + it = pendulum.interval(dt1, dt2) + mul = it * 2 + assert isinstance(mul, pendulum.Duration) + assert_duration(mul, 0, 0, 1, 5, 0, 1, 8) + + dt1 = pendulum.DateTime(2016, 8, 7, 12, 34, 56) + dt2 = dt1.add(days=6, seconds=34) + it = pendulum.interval(dt1, dt2) + mul = it * 2 + assert isinstance(mul, pendulum.Duration) + assert_duration(mul, 0, 0, 1, 5, 0, 1, 8) + + +def test_divide(): + dt1 = pendulum.DateTime(2016, 8, 7, 12, 34, 56) + dt2 = dt1.add(days=2, seconds=34) + it = pendulum.interval(dt1, dt2) + mul = it / 2 + assert isinstance(mul, pendulum.Duration) + assert_duration(mul, 0, 0, 0, 1, 0, 0, 17) + + dt1 = pendulum.DateTime(2016, 8, 7, 12, 34, 56) + dt2 = dt1.add(days=2, seconds=35) + it = pendulum.interval(dt1, dt2) + mul = it / 2 + assert isinstance(mul, pendulum.Duration) + assert_duration(mul, 0, 0, 0, 1, 0, 0, 17) + + +def test_floor_divide(): + dt1 = pendulum.DateTime(2016, 8, 7, 12, 34, 56) + dt2 = dt1.add(days=2, seconds=34) + it = pendulum.interval(dt1, dt2) + mul = it // 2 + assert isinstance(mul, pendulum.Duration) + assert_duration(mul, 0, 0, 0, 1, 0, 0, 17) + + dt1 = pendulum.DateTime(2016, 8, 7, 12, 34, 56) + dt2 = dt1.add(days=2, seconds=35) + it = pendulum.interval(dt1, dt2) + mul = it // 3 + assert isinstance(mul, pendulum.Duration) + assert_duration(mul, 0, 0, 0, 0, 16, 0, 11) diff --git a/tests/interval/test_behavior.py b/tests/interval/test_behavior.py new file mode 100644 index 0000000..b5e057a --- /dev/null +++ b/tests/interval/test_behavior.py @@ -0,0 +1,54 @@ +from __future__ import annotations + +import pickle + +from datetime import timedelta + +import pendulum + + +def test_pickle(): + dt1 = pendulum.datetime(2016, 11, 18) + dt2 = pendulum.datetime(2016, 11, 20) + + p = pendulum.interval(dt1, dt2) + s = pickle.dumps(p) + p2 = pickle.loads(s) + + assert p.start == p2.start + assert p.end == p2.end + assert p.invert == p2.invert + + p = pendulum.interval(dt2, dt1) + s = pickle.dumps(p) + p2 = pickle.loads(s) + + assert p.start == p2.start + assert p.end == p2.end + assert p.invert == p2.invert + + p = pendulum.interval(dt2, dt1, True) + s = pickle.dumps(p) + p2 = pickle.loads(s) + + assert p.start == p2.start + assert p.end == p2.end + assert p.invert == p2.invert + + +def test_comparison_to_timedelta(): + dt1 = pendulum.datetime(2016, 11, 18) + dt2 = pendulum.datetime(2016, 11, 20) + + period = dt2 - dt1 + + assert period < timedelta(days=4) + + +def test_equality_to_timedelta(): + dt1 = pendulum.datetime(2016, 11, 18) + dt2 = pendulum.datetime(2016, 11, 20) + + period = dt2 - dt1 + + assert period == timedelta(days=2) diff --git a/tests/interval/test_construct.py b/tests/interval/test_construct.py new file mode 100644 index 0000000..024e741 --- /dev/null +++ b/tests/interval/test_construct.py @@ -0,0 +1,121 @@ +from __future__ import annotations + +from datetime import datetime + +import pendulum + +from tests.conftest import assert_datetime + + +def test_with_datetimes(): + dt1 = datetime(2000, 1, 1) + dt2 = datetime(2000, 1, 31) + p = pendulum.interval(dt1, dt2) + + assert isinstance(p.start, pendulum.DateTime) + assert isinstance(p.end, pendulum.DateTime) + assert_datetime(p.start, 2000, 1, 1) + assert_datetime(p.end, 2000, 1, 31) + + +def test_with_pendulum(): + dt1 = pendulum.DateTime(2000, 1, 1) + dt2 = pendulum.DateTime(2000, 1, 31) + p = pendulum.interval(dt1, dt2) + + assert_datetime(p.start, 2000, 1, 1) + assert_datetime(p.end, 2000, 1, 31) + + +def test_inverted(): + dt1 = pendulum.DateTime(2000, 1, 1) + dt2 = pendulum.DateTime(2000, 1, 31) + p = pendulum.interval(dt2, dt1) + + assert_datetime(p.start, 2000, 1, 31) + assert_datetime(p.end, 2000, 1, 1) + + +def test_inverted_and_absolute(): + dt1 = pendulum.DateTime(2000, 1, 1) + dt2 = pendulum.DateTime(2000, 1, 31) + p = pendulum.interval(dt2, dt1, True) + + assert_datetime(p.start, 2000, 1, 1) + assert_datetime(p.end, 2000, 1, 31) + + +def test_accuracy(): + dt1 = pendulum.DateTime(2000, 11, 20) + dt2 = pendulum.DateTime(2000, 11, 25) + dt3 = pendulum.DateTime(2016, 11, 5) + p1 = pendulum.interval(dt1, dt3) + p2 = pendulum.interval(dt2, dt3) + + assert p1.years == 15 + assert p1.in_years() == 15 + assert p1.months == 11 + assert p1.in_months() == 191 + assert p1.days == 5829 + assert p1.remaining_days == 2 + assert p1.in_days() == 5829 + + assert p2.years == 15 + assert p2.in_years() == 15 + assert p2.months == 11 + assert p2.in_months() == 191 + assert p2.days == 5824 + assert p2.remaining_days == 4 + assert p2.in_days() == 5824 + + +def test_dst_transition(): + start = pendulum.datetime(2017, 3, 7, tz="America/Toronto") + end = start.add(days=6) + period = end - start + + assert period.days == 5 + assert period.seconds == 82800 + + assert period.remaining_days == 6 + assert period.hours == 0 + assert period.remaining_seconds == 0 + + assert period.in_days() == 6 + assert period.in_hours() == 5 * 24 + 23 + + +def test_timedelta_behavior(): + dt1 = pendulum.DateTime(2000, 11, 20, 1) + dt2 = pendulum.DateTime(2000, 11, 25, 2) + dt3 = pendulum.DateTime(2016, 11, 5, 3) + + p1 = pendulum.interval(dt1, dt3) + p2 = pendulum.interval(dt2, dt3) + it1 = p1.as_timedelta() + it2 = p2.as_timedelta() + + assert it1.total_seconds() == p1.total_seconds() + assert it2.total_seconds() == p2.total_seconds() + assert it1.days == p1.days + assert it2.days == p2.days + assert it1.seconds == p1.seconds + assert it2.seconds == p2.seconds + assert it1.microseconds == p1.microseconds + assert it2.microseconds == p2.microseconds + + +def test_different_timezones_same_time(): + dt1 = pendulum.datetime(2013, 3, 31, 1, 30, tz="Europe/Paris") + dt2 = pendulum.datetime(2013, 4, 1, 1, 30, tz="Europe/Paris") + period = dt2 - dt1 + + assert period.in_words() == "1 day" + assert period.in_hours() == 23 + + dt1 = pendulum.datetime(2013, 3, 31, 1, 30, tz="Europe/Paris") + dt2 = pendulum.datetime(2013, 4, 1, 1, 30, tz="America/Toronto") + period = dt2 - dt1 + + assert period.in_words() == "1 day 5 hours" + assert period.in_hours() == 29 diff --git a/tests/interval/test_hashing.py b/tests/interval/test_hashing.py new file mode 100644 index 0000000..c18502f --- /dev/null +++ b/tests/interval/test_hashing.py @@ -0,0 +1,23 @@ +from __future__ import annotations + +import pendulum + + +def test_periods_with_same_duration_and_different_dates(): + day1 = pendulum.DateTime(2018, 1, 1) + day2 = pendulum.DateTime(2018, 1, 2) + day3 = pendulum.DateTime(2018, 1, 2) + + period1 = day2 - day1 + period2 = day3 - day2 + + assert period1 != period2 + assert len({period1, period2}) == 2 + + +def test_periods_with_same_dates(): + period1 = pendulum.DateTime(2018, 1, 2) - pendulum.DateTime(2018, 1, 1) + period2 = pendulum.DateTime(2018, 1, 2) - pendulum.DateTime(2018, 1, 1) + + assert period1 == period2 + assert len({period1, period2}) == 1 diff --git a/tests/interval/test_in_words.py b/tests/interval/test_in_words.py new file mode 100644 index 0000000..410e11f --- /dev/null +++ b/tests/interval/test_in_words.py @@ -0,0 +1,70 @@ +from __future__ import annotations + +import pendulum + + +def test_week(): + start_date = pendulum.datetime(2012, 1, 1) + period = pendulum.interval(start=start_date, end=start_date.add(weeks=1)) + assert period.in_words() == "1 week" + + +def test_week_and_day(): + start_date = pendulum.datetime(2012, 1, 1) + period = pendulum.interval(start=start_date, end=start_date.add(weeks=1, days=1)) + assert period.in_words() == "1 week 1 day" + + +def test_all(): + start_date = pendulum.datetime(2012, 1, 1) + period = pendulum.interval( + start=start_date, + end=start_date.add(years=1, months=1, days=1, seconds=1, microseconds=1), + ) + assert period.in_words() == "1 year 1 month 1 day 1 second" + + +def test_in_french(): + start_date = pendulum.datetime(2012, 1, 1) + period = pendulum.interval( + start=start_date, + end=start_date.add(years=1, months=1, days=1, seconds=1, microseconds=1), + ) + assert period.in_words(locale="fr") == "1 an 1 mois 1 jour 1 seconde" + + +def test_singular_negative_values(): + start_date = pendulum.datetime(2012, 1, 1) + period = pendulum.interval(start=start_date, end=start_date.subtract(days=1)) + assert period.in_words() == "-1 day" + + +def test_separator(): + start_date = pendulum.datetime(2012, 1, 1) + period = pendulum.interval( + start=start_date, + end=start_date.add(years=1, months=1, days=1, seconds=1, microseconds=1), + ) + assert period.in_words(separator=", ") == "1 year, 1 month, 1 day, 1 second" + + +def test_subseconds(): + start_date = pendulum.datetime(2012, 1, 1) + period = pendulum.interval( + start=start_date, end=start_date.add(microseconds=123456) + ) + assert period.in_words() == "0.12 second" + + +def test_subseconds_with_seconds(): + start_date = pendulum.datetime(2012, 1, 1) + period = pendulum.interval( + start=start_date, end=start_date.add(seconds=12, microseconds=123456) + ) + assert period.in_words() == "12 seconds" + + +def test_zero_period(): + start_date = pendulum.datetime(2012, 1, 1) + period = pendulum.interval(start=start_date, end=start_date) + assert period.in_words() == "0 microseconds" diff --git a/tests/interval/test_range.py b/tests/interval/test_range.py new file mode 100644 index 0000000..28fe1ff --- /dev/null +++ b/tests/interval/test_range.py @@ -0,0 +1,119 @@ +from __future__ import annotations + +import pendulum + +from pendulum.interval import Interval +from tests.conftest import assert_datetime + + +def test_range(): + dt1 = pendulum.datetime(2000, 1, 1, 12, 45, 37) + dt2 = pendulum.datetime(2000, 1, 31, 12, 45, 37) + + p = Interval(dt1, dt2) + r = list(p.range("days")) + + assert len(r) == 31 + assert_datetime(r[0], 2000, 1, 1, 12, 45, 37) + assert_datetime(r[-1], 2000, 1, 31, 12, 45, 37) + + +def test_range_no_overflow(): + dt1 = pendulum.datetime(2000, 1, 1, 12, 45, 37) + dt2 = pendulum.datetime(2000, 1, 31, 11, 45, 37) + + p = Interval(dt1, dt2) + r = list(p.range("days")) + + assert len(r) == 30 + assert_datetime(r[0], 2000, 1, 1, 12, 45, 37) + assert_datetime(r[-1], 2000, 1, 30, 12, 45, 37) + + +def test_range_inverted(): + dt1 = pendulum.datetime(2000, 1, 1, 12, 45, 37) + dt2 = pendulum.datetime(2000, 1, 31, 12, 45, 37) + + p = Interval(dt2, dt1) + r = list(p.range("days")) + + assert len(r) == 31 + assert_datetime(r[-1], 2000, 1, 1, 12, 45, 37) + assert_datetime(r[0], 2000, 1, 31, 12, 45, 37) + + +def test_iter(): + dt1 = pendulum.datetime(2000, 1, 1, 12, 45, 37) + dt2 = pendulum.datetime(2000, 1, 31, 12, 45, 37) + + p = Interval(dt1, dt2) + i = 0 # noqa: SIM113 (suggests use of enumerate) + for dt in p: + assert isinstance(dt, pendulum.DateTime) + i += 1 + + assert i == 31 + + +def test_contains(): + dt1 = pendulum.datetime(2000, 1, 1, 12, 45, 37) + dt2 = pendulum.datetime(2000, 1, 31, 12, 45, 37) + + p = pendulum.interval(dt1, dt2) + dt = pendulum.datetime(2000, 1, 7) + assert dt in p + + +def test_not_contains(): + dt1 = pendulum.datetime(2000, 1, 1, 12, 45, 37) + dt2 = pendulum.datetime(2000, 1, 31, 12, 45, 37) + + p = pendulum.interval(dt1, dt2) + dt = pendulum.datetime(2000, 1, 1, 11, 45, 37) + assert dt not in p + + +def test_contains_with_datetime(): + dt1 = pendulum.datetime(2000, 1, 1, 12, 45, 37) + dt2 = pendulum.datetime(2000, 1, 31, 12, 45, 37) + + p = pendulum.interval(dt1, dt2) + dt = pendulum.datetime(2000, 1, 7) + assert dt in p + + +def test_range_months_overflow(): + dt1 = pendulum.datetime(2016, 1, 30, tz="America/Sao_Paulo") + dt2 = dt1.add(months=4) + + p = pendulum.interval(dt1, dt2) + r = list(p.range("months")) + + assert_datetime(r[0], 2016, 1, 30, 0, 0, 0) + assert_datetime(r[-1], 2016, 5, 30, 0, 0, 0) + + +def test_range_with_dst(): + dt1 = pendulum.datetime(2016, 10, 14, tz="America/Sao_Paulo") + dt2 = dt1.add(weeks=1) + + p = pendulum.interval(dt1, dt2) + r = list(p.range("days")) + + assert_datetime(r[0], 2016, 10, 14, 0, 0, 0) + assert_datetime(r[2], 2016, 10, 16, 1, 0, 0) + assert_datetime(r[-1], 2016, 10, 21, 0, 0, 0) + + +def test_range_amount(): + dt1 = pendulum.datetime(2016, 10, 14, tz="America/Sao_Paulo") + dt2 = dt1.add(weeks=1) + + p = pendulum.interval(dt1, dt2) + r = list(p.range("days", 2)) + + assert len(r) == 4 + assert_datetime(r[0], 2016, 10, 14, 0, 0, 0) + assert_datetime(r[1], 2016, 10, 16, 1, 0, 0) + assert_datetime(r[2], 2016, 10, 18, 0, 0, 0) + assert_datetime(r[3], 2016, 10, 20, 0, 0, 0) -- cgit v1.2.3