|
1 | 1 | from __future__ import annotations |
2 | 2 |
|
| 3 | +from itertools import islice |
| 4 | + |
| 5 | +import pytest |
| 6 | + |
3 | 7 | import pendulum |
4 | 8 |
|
5 | 9 | from pendulum.interval import Interval |
@@ -117,3 +121,73 @@ def test_range_amount(): |
117 | 121 | assert_datetime(r[1], 2016, 10, 16, 1, 0, 0) |
118 | 122 | assert_datetime(r[2], 2016, 10, 18, 0, 0, 0) |
119 | 123 | assert_datetime(r[3], 2016, 10, 20, 0, 0, 0) |
| 124 | + |
| 125 | + |
| 126 | +@pytest.mark.parametrize("factory", [pendulum.date, pendulum.datetime]) |
| 127 | +@pytest.mark.parametrize("absolute", [False, True]) |
| 128 | +@pytest.mark.parametrize( |
| 129 | + "start, end, unit, amount", |
| 130 | + [ |
| 131 | + ((9999, 12, 30), (9999, 12, 31), "days", 1), |
| 132 | + ((1, 1, 2), (1, 1, 1), "days", 1), |
| 133 | + ((9999, 12, 31), (9999, 12, 31), "days", 1), |
| 134 | + ((1, 1, 1), (1, 1, 1), "days", 1), |
| 135 | + ((9999, 12, 29), (9999, 12, 31), "days", 2), |
| 136 | + ((1, 1, 3), (1, 1, 1), "days", 2), |
| 137 | + ((9999, 12, 24), (9999, 12, 31), "weeks", 1), |
| 138 | + ((1, 1, 8), (1, 1, 1), "weeks", 1), |
| 139 | + ((9999, 11, 30), (9999, 12, 30), "months", 1), |
| 140 | + ((1, 2, 1), (1, 1, 1), "months", 1), |
| 141 | + ((9998, 12, 31), (9999, 12, 31), "years", 1), |
| 142 | + ((2, 1, 1), (1, 1, 1), "years", 1), |
| 143 | + ], |
| 144 | +) |
| 145 | +def test_range_stops_at_final_endpoint(factory, absolute, start, end, unit, amount): |
| 146 | + start, end = factory(*start), factory(*end) |
| 147 | + interval = pendulum.interval(start, end, absolute=absolute) |
| 148 | + expected = [start] if start == end else [start, end] |
| 149 | + if absolute: |
| 150 | + expected.sort() |
| 151 | + |
| 152 | + assert list(interval.range(unit, amount)) == expected |
| 153 | + |
| 154 | + |
| 155 | +@pytest.mark.parametrize("reverse", [False, True]) |
| 156 | +@pytest.mark.parametrize("unit", ["hours", "minutes", "seconds", "microseconds"]) |
| 157 | +def test_range_stops_at_final_datetime_endpoint(reverse, unit): |
| 158 | + if reverse: |
| 159 | + end = pendulum.datetime(1, 1, 1) |
| 160 | + start = end.add(**{unit: 1}) |
| 161 | + else: |
| 162 | + end = pendulum.datetime(9999, 12, 31, 23, 59, 59, 999999) |
| 163 | + start = end.subtract(**{unit: 1}) |
| 164 | + |
| 165 | + assert list(pendulum.interval(start, end).range(unit)) == [start, end] |
| 166 | + |
| 167 | + |
| 168 | +@pytest.mark.parametrize("end_day", [1, 3]) |
| 169 | +def test_range_zero_amount(end_day): |
| 170 | + start = pendulum.date(2000, 1, 1) |
| 171 | + end = pendulum.date(2000, 1, end_day) |
| 172 | + |
| 173 | + assert list(islice(pendulum.interval(start, end).range("days", 0), 3)) == [ |
| 174 | + start, |
| 175 | + start, |
| 176 | + start, |
| 177 | + ] |
| 178 | + |
| 179 | + |
| 180 | +@pytest.mark.parametrize("reverse", [False, True]) |
| 181 | +@pytest.mark.parametrize("absolute", [False, True]) |
| 182 | +def test_range_amount_does_not_reach_endpoint(reverse, absolute): |
| 183 | + start, end = pendulum.date(2000, 1, 1), pendulum.date(2000, 1, 4) |
| 184 | + if reverse: |
| 185 | + start, end = end, start |
| 186 | + expected = [pendulum.date(2000, 1, 1), pendulum.date(2000, 1, 3)] |
| 187 | + if reverse and not absolute: |
| 188 | + expected = [pendulum.date(2000, 1, 4), pendulum.date(2000, 1, 2)] |
| 189 | + |
| 190 | + assert ( |
| 191 | + list(pendulum.interval(start, end, absolute=absolute).range("days", 2)) |
| 192 | + == expected |
| 193 | + ) |
0 commit comments