forked from pandas-dev/pandas
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtest_ops.py
123 lines (106 loc) · 4.08 KB
/
test_ops.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
"""Tests for Interval-Interval operations, such as overlaps, contains, etc."""
import pytest
from pandas import (
Interval,
Timedelta,
Timestamp,
)
@pytest.fixture(
params=[
(Timedelta("0 days"), Timedelta("1 day")),
(Timestamp("2018-01-01"), Timedelta("1 day")),
(0, 1),
],
ids=lambda x: type(x[0]).__name__,
)
def start_shift(request):
"""
Fixture for generating intervals of types from a start value and a shift
value that can be added to start to generate an endpoint
"""
return request.param
class TestOverlaps:
def test_overlaps_self(self, start_shift, closed):
start, shift = start_shift
interval = Interval(start, start + shift, closed)
assert interval.overlaps(interval)
def test_overlaps_nested(self, start_shift, closed, other_closed):
start, shift = start_shift
interval1 = Interval(start, start + 3 * shift, other_closed)
interval2 = Interval(start + shift, start + 2 * shift, closed)
# nested intervals should always overlap
assert interval1.overlaps(interval2)
def test_overlaps_disjoint(self, start_shift, closed, other_closed):
start, shift = start_shift
interval1 = Interval(start, start + shift, other_closed)
interval2 = Interval(start + 2 * shift, start + 3 * shift, closed)
# disjoint intervals should never overlap
assert not interval1.overlaps(interval2)
def test_overlaps_endpoint(self, start_shift, closed, other_closed):
start, shift = start_shift
interval1 = Interval(start, start + shift, other_closed)
interval2 = Interval(start + shift, start + 2 * shift, closed)
# overlap if shared endpoint is closed for both (overlap at a point)
result = interval1.overlaps(interval2)
expected = interval1.closed_right and interval2.closed_left
assert result == expected
@pytest.mark.parametrize(
"other",
[10, True, "foo", Timedelta("1 day"), Timestamp("2018-01-01")],
ids=lambda x: type(x).__name__,
)
def test_overlaps_invalid_type(self, other):
interval = Interval(0, 1)
msg = f"`other` must be an Interval, got {type(other).__name__}"
with pytest.raises(TypeError, match=msg):
interval.overlaps(other)
class TestContains:
@pytest.mark.parametrize(
"closed",
["neither", "left", "right"],
)
def test_contains_interval(self, closed):
interval1 = Interval(0, 1, "both")
interval2 = Interval(0, 1, closed)
assert interval1 in interval1
assert interval2 in interval2
assert interval2 in interval1
assert interval1 not in interval2
def test_contains_infinite_length(self):
interval1 = Interval(0, 1, "both")
interval2 = Interval(float("-inf"), float("inf"), "neither")
assert interval1 in interval2
assert interval2 not in interval1
def test_contains_zero_length(self):
interval1 = Interval(0, 1, "both")
interval2 = Interval(-1, -1, "both")
interval3 = Interval(0.5, 0.5, "both")
assert interval2 not in interval1
assert interval3 in interval1
assert interval2 not in interval3 and interval3 not in interval2
assert interval1 not in interval2 and interval1 not in interval3
@pytest.mark.parametrize(
"type1",
[
(0, 1),
(Timestamp(2000, 1, 1, 0), Timestamp(2000, 1, 1, 1)),
(Timedelta("0h"), Timedelta("1h")),
],
)
@pytest.mark.parametrize(
"type2",
[
(0, 1),
(Timestamp(2000, 1, 1, 0), Timestamp(2000, 1, 1, 1)),
(Timedelta("0h"), Timedelta("1h")),
],
)
def test_contains_mixed_types(self, type1, type2):
interval1 = Interval(*type1)
interval2 = Interval(*type2)
if type1 == type2:
assert interval1 in interval2
else:
msg = "^'<=' not supported between instances of"
with pytest.raises(TypeError, match=msg):
interval1 in interval2