Skip to content

Commit 752c6db

Browse files
committed
Added test for script validator
1 parent 9abc004 commit 752c6db

File tree

2 files changed

+327
-0
lines changed

2 files changed

+327
-0
lines changed

pandas/tests/scripts/__init__.py

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,327 @@
1+
import os
2+
import sys
3+
4+
import numpy
5+
import pytest
6+
7+
8+
class GoodDocStrings(object):
9+
"""
10+
Collection of good docstrings - be sure to update the tests as new
11+
examples are added here
12+
"""
13+
14+
def plot(self, kind, color='blue', **kwargs):
15+
"""
16+
Generate a plot.
17+
18+
Render the data in the Series as a matplotlib plot of the
19+
specified kind.
20+
21+
Parameters
22+
----------
23+
kind : str
24+
Kind of matplotlib plot.
25+
color : str, default 'blue'
26+
Color name or rgb code.
27+
**kwargs
28+
These parameters will be passed to the matplotlib plotting
29+
function.
30+
"""
31+
pass
32+
33+
def sample(self):
34+
"""
35+
Generate and return a random number.
36+
37+
The value is sampled from a continuous uniform distribution between
38+
0 and 1.
39+
40+
Returns
41+
-------
42+
float
43+
Random number generated.
44+
"""
45+
return random.random()
46+
47+
def random_letters(self):
48+
"""
49+
Generate and return a sequence of random letters.
50+
51+
The length of the returned string is also random, and is also
52+
returned.
53+
54+
Returns
55+
-------
56+
length : int
57+
Length of the returned string.
58+
letters : str
59+
String of random letters.
60+
"""
61+
length = random.randint(1, 10)
62+
letters = ''.join(random.choice(string.ascii_lowercase)
63+
for i in range(length))
64+
return length, letters
65+
66+
def sample_values(self):
67+
"""
68+
Generate an infinite sequence of random numbers.
69+
70+
The values are sampled from a continuous uniform distribution between
71+
0 and 1.
72+
73+
Yields
74+
------
75+
float
76+
Random number generated.
77+
"""
78+
while True:
79+
yield random.random()
80+
81+
def head(self):
82+
"""Return the first 5 elements of the Series.
83+
84+
This function is mainly useful to preview the values of the
85+
Series without displaying the whole of it.
86+
87+
Returns
88+
-------
89+
Series
90+
Subset of the original series with the 5 first values.
91+
92+
See Also
93+
--------
94+
Series.tail : Return the last 5 elements of the Series.
95+
Series.iloc : Return a slice of the elements in the Series,
96+
which can also be used to return the first or last n.
97+
"""
98+
return self.iloc[:5]
99+
100+
def head1(self, n=5):
101+
"""Return the first elements of the Series.
102+
103+
This function is mainly useful to preview the values of the
104+
Series without displaying the whole of it.
105+
106+
Parameters
107+
----------
108+
n : int
109+
Number of values to return.
110+
111+
Return
112+
------
113+
pandas.Series
114+
Subset of the original series with the n first values.
115+
116+
See Also
117+
--------
118+
tail : Return the last n elements of the Series.
119+
120+
Examples
121+
--------
122+
>>> s = pd.Series(['Ant', 'Bear', 'Cow', 'Dog', 'Falcon',
123+
... 'Lion', 'Monkey', 'Rabbit', 'Zebra'])
124+
>>> s.head()
125+
0 Ant
126+
1 Bear
127+
2 Cow
128+
3 Dog
129+
4 Falcon
130+
dtype: object
131+
132+
With the `n` parameter, we can change the number of returned rows:
133+
134+
>>> s.head(n=3)
135+
0 Ant
136+
1 Bear
137+
2 Cow
138+
dtype: object
139+
"""
140+
return self.iloc[:n]
141+
142+
def contains(self, pattern, case_sensitive=True, na=numpy.nan):
143+
"""
144+
Return whether each value contains `pattern`.
145+
146+
In this case, we are illustrating how to use sections, even
147+
if the example is simple enough and does not require them.
148+
149+
Examples
150+
--------
151+
>>> s = pd.Series('Antelope', 'Lion', 'Zebra', numpy.nan)
152+
>>> s.contains(pattern='a')
153+
0 False
154+
1 False
155+
2 True
156+
3 NaN
157+
dtype: bool
158+
159+
**Case sensitivity**
160+
161+
With `case_sensitive` set to `False` we can match `a` with both
162+
`a` and `A`:
163+
164+
>>> s.contains(pattern='a', case_sensitive=False)
165+
0 True
166+
1 False
167+
2 True
168+
3 NaN
169+
dtype: bool
170+
171+
**Missing values**
172+
173+
We can fill missing values in the output using the `na` parameter:
174+
175+
>>> s.contains(pattern='a', na=False)
176+
0 False
177+
1 False
178+
2 True
179+
3 False
180+
dtype: bool
181+
"""
182+
pass
183+
184+
def plot2(self):
185+
"""
186+
Generate a plot with the `Series` data.
187+
188+
Examples
189+
--------
190+
191+
.. plot::
192+
:context: close-figs
193+
194+
>>> s = pd.Series([1, 2, 3])
195+
>>> s.plot()
196+
"""
197+
pass
198+
199+
class BadDocStrings(object):
200+
201+
def func(self):
202+
203+
"""Some function.
204+
205+
With several mistakes in the docstring.
206+
207+
It has a blank like after the signature `def func():`.
208+
209+
The text 'Some function' should go in the line after the
210+
opening quotes of the docstring, not in the same line.
211+
212+
There is a blank line between the docstring and the first line
213+
of code `foo = 1`.
214+
215+
The closing quotes should be in the next line, not in this one."""
216+
217+
foo = 1
218+
bar = 2
219+
return foo + bar
220+
221+
def astype(self, dtype):
222+
"""
223+
Casts Series type.
224+
225+
Verb in third-person of the present simple, should be infinitive.
226+
"""
227+
pass
228+
229+
def astype1(self, dtype):
230+
"""
231+
Method to cast Series type.
232+
233+
Does not start with verb.
234+
"""
235+
pass
236+
237+
def astype2(self, dtype):
238+
"""
239+
Cast Series type
240+
241+
Missing dot at the end.
242+
"""
243+
pass
244+
245+
def astype3(self, dtype):
246+
"""
247+
Cast Series type from its current type to the new type defined in
248+
the parameter dtype.
249+
250+
Summary is too verbose and doesn't fit in a single line.
251+
"""
252+
pass
253+
254+
def plot(self, kind, **kwargs):
255+
"""
256+
Generate a plot.
257+
258+
Render the data in the Series as a matplotlib plot of the
259+
specified kind.
260+
261+
Note the blank line between the parameters title and the first
262+
parameter. Also, note that after the name of the parameter `kind`
263+
and before the colon, a space is missing.
264+
265+
Also, note that the parameter descriptions do not start with a
266+
capital letter, and do not finish with a dot.
267+
268+
Finally, the `**kwargs` parameter is missing.
269+
270+
Parameters
271+
----------
272+
273+
kind: str
274+
kind of matplotlib plot
275+
"""
276+
pass
277+
278+
def method(self, foo=None, bar=None):
279+
"""
280+
A sample DataFrame method.
281+
282+
Do not import numpy and pandas.
283+
284+
Try to use meaningful data, when it makes the example easier
285+
to understand.
286+
287+
Try to avoid positional arguments like in `df.method(1)`. They
288+
can be all right if previously defined with a meaningful name,
289+
like in `present_value(interest_rate)`, but avoid them otherwise.
290+
291+
When presenting the behavior with different parameters, do not place
292+
all the calls one next to the other. Instead, add a short sentence
293+
explaining what the example shows.
294+
295+
Examples
296+
--------
297+
>>> import numpy as np
298+
>>> import pandas as pd
299+
>>> df = pd.DataFrame(numpy.random.randn(3, 3),
300+
... columns=('a', 'b', 'c'))
301+
>>> df.method(1)
302+
21
303+
>>> df.method(bar=14)
304+
123
305+
"""
306+
pass
307+
308+
class TestValidator(object):
309+
310+
@pytest.fixture(autouse=True, scope="class")
311+
def import_scripts(self):
312+
up = os.path.dirname
313+
file_dir = up(os.path.abspath(__file__))
314+
script_dir = os.path.join(up(up(up(file_dir))), 'scripts')
315+
sys.path.append(script_dir)
316+
from validate_docstrings import validate_one
317+
globals()['validate_one'] = validate_one
318+
yield
319+
sys.path.pop()
320+
del globals()['validate_one']
321+
322+
@pytest.mark.parametrize("func", [
323+
'plot', 'sample', 'random_letters', 'sample_values', 'head', 'head1',
324+
'contains', 'plot2'])
325+
def test_good_functions(self, func):
326+
assert validate_one('pandas.tests.scripts.test_validate_docstrings'
327+
'.GoodDocStrings.' + func) == 0

0 commit comments

Comments
 (0)