Skip to content

Commit 7e2ed0c

Browse files
committed
TST, fix for issue pandas-dev#17978.
Addition of "hypothesis usage" in test cases of tests/reshape/test_util.py as kind of POC. Incorporate review comments. Resolve flake8 warning.
1 parent 78a5820 commit 7e2ed0c

File tree

1 file changed

+75
-23
lines changed

1 file changed

+75
-23
lines changed

pandas/tests/reshape/test_util.py

+75-23
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,55 @@ def get_elements(elem_type):
2828

2929

3030
@st.composite
31-
def get_seq(draw, types, mixed=False, min_size=None, max_size=None, transform_func=None):
32-
"""helper function to generate strategy for creating lists. parameters define the nature of to be generated list.
33-
:param types: what type of elements constitute the list
34-
:param mixed: if True, list will contains elements from all types listed in arg, oterwise it will have elements only from types[0].
35-
:param min_size: minimum size of the list.
36-
:param max_size: maximum size of the list.
37-
:param transform_func: a callable which can be applied to whole list after it has been generated.
31+
def get_seq(draw, types, mixed=False, min_size=None, max_size=None,
32+
transform_func=None):
33+
"""
34+
Helper function to generate strategy for creating lists.
35+
What constitute in the generated list is driven by the different
36+
parameters.
37+
38+
Parameters
39+
----------
40+
types: iterable sequence like tuple or list
41+
types which can be in the generated list.
42+
mixed: bool
43+
if True, list will contains elements from all types listed in arg,
44+
otherwise it will have elements only from types[0].
45+
min_size: int
46+
minimum size of the list.
47+
max_size: int
48+
maximum size of the list.
49+
transform_func: callable
50+
a callable which can be applied to whole list after it has been
51+
generated. It can think of as providing functionality of filter
52+
and map function.
53+
54+
Returns
55+
-------
56+
hypothesis lists strategy.
57+
58+
Examples
59+
--------
60+
seq_strategy = get_seq((int, str, bool),
61+
mixed=True, min_size=1, max_size=5)
62+
seq_strategy.example()
63+
Out[12]: ['lkYMSn', -2501, 35, 'J']
64+
seq_strategy.example()
65+
Out[13]: [True]
66+
seq_strategy.example()
67+
Out[14]: ['dRWgQYrBrW', True, False, 'gmsujJVDBM', 'Z']
68+
69+
seq_strategy = get_seq((int, bool),
70+
mixed=False,
71+
min_size=1,
72+
max_size=5,
73+
transform_func=lambda seq: [str(x) for x in seq])
74+
seq_strategy.example()
75+
Out[19]: ['-1892']
76+
seq_strategy.example()
77+
Out[20]: ['22', '66', '14785', '-26312', '32']
78+
seq_strategy.example()
79+
Out[21]: ['22890', '-15537', '96']
3880
"""
3981
strategy = st.nothing()
4082
if min_size is None:
@@ -43,7 +85,8 @@ def get_seq(draw, types, mixed=False, min_size=None, max_size=None, transform_fu
4385
if max_size is None:
4486
max_size = draw(st.integers(min_value=min_size, max_value=100))
4587

46-
assert min_size <= max_size, 'max_size must be greater than equal to min_size'
88+
assert min_size <= max_size, \
89+
'max_size must be greater than equal to min_size'
4790

4891
elem_strategies = []
4992
for elem_type in types:
@@ -53,10 +96,12 @@ def get_seq(draw, types, mixed=False, min_size=None, max_size=None, transform_fu
5396

5497
if transform_func:
5598
strategy = draw(st.lists(st.one_of(elem_strategies),
56-
min_size=min_size, max_size=max_size).map(transform_func))
99+
min_size=min_size,
100+
max_size=max_size).map(transform_func))
57101
else:
58102
strategy = draw(st.lists(st.one_of(elem_strategies),
59-
min_size=min_size, max_size=max_size))
103+
min_size=min_size,
104+
max_size=max_size))
60105
return strategy
61106

62107

@@ -67,7 +112,8 @@ class TestCartesianProduct(object):
67112
get_seq((int,), False, 1, 2))
68113
def test_simple(self, x, y):
69114
x = list(x[0])
70-
# non-empty test case is handled in test_empty, therefore ignore it here
115+
# non-empty test case is handled in test_empty,
116+
# therefore ignore it here.
71117
assume(len(x) != 0)
72118
result1, result2 = cartesian_product([x, y])
73119
expected1 = np.array([item1 for item1 in x for item2 in y])
@@ -77,10 +123,10 @@ def test_simple(self, x, y):
77123
tm.assert_numpy_array_equal(result2, expected2)
78124

79125
@settings(max_examples=NO_OF_EXAMPLES_PER_TEST_CASE)
80-
def test_datetimeindex(self):
126+
@given(st.dates(min_value=date(1900, 1, 1), max_value=date(2100, 1, 1)))
127+
def test_datetimeindex(self, d):
81128
# regression test for GitHub issue #6439
82129
# make sure that the ordering on datetimeindex is consistent
83-
d = st.dates(min_value=date(1900, 1, 1), max_value=date(2100, 1, 1)).example()
84130
n = d + relativedelta.relativedelta(days=1)
85131
x = date_range(d, periods=2)
86132
result1, result2 = [Index(y).day for y in cartesian_product([x, x])]
@@ -112,16 +158,22 @@ def test_empty(self, empty_list, list_of_int, list_of_str):
112158
assert result == expected
113159

114160
@settings(max_examples=NO_OF_EXAMPLES_PER_TEST_CASE)
115-
def test_invalid_input(self):
116-
invalid_inputs = [st.integers().example(),
117-
st.tuples(st.integers()).example(),
118-
st.tuples(st.integers(), st.integers()).example(),
119-
st.text(string.ascii_letters, min_size=1, max_size=1).example(),
120-
st.tuples(st.text(string.ascii_letters, min_size=1, max_size=1)).example(),
121-
st.tuples(st.text(string.ascii_letters, min_size=1, max_size=1),
122-
st.text(string.ascii_letters, min_size=1, max_size=1)).example(),
123-
st.tuples(st.tuples(st.text(string.ascii_letters, min_size=1, max_size=1)),
124-
st.text(string.ascii_letters, min_size=1, max_size=1)).example()]
161+
@given(st.integers(),
162+
st.text(string.ascii_letters, min_size=1),
163+
get_seq((int, str), True, min_size=1),
164+
st.lists(st.one_of(st.integers(),
165+
st.text(string.ascii_letters, min_size=1),
166+
get_seq((int,), min_size=1)
167+
),
168+
min_size=1).filter(
169+
lambda x: len(x) == 1 and type(x[0]) != list)
170+
)
171+
def test_invalid_input(self, number, text, seq, mixed_seq):
172+
173+
invalid_inputs = [number,
174+
text,
175+
seq,
176+
mixed_seq]
125177

126178
msg = "Input must be a list-like of list-likes"
127179
for X in invalid_inputs:

0 commit comments

Comments
 (0)