Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make validate_docstrings.py ready for the CI #23514

Merged
merged 8 commits into from
Nov 7, 2018
164 changes: 128 additions & 36 deletions scripts/tests/test_validate_docstrings.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import string
import random
import io
import random
import string
import textwrap
import pytest
import numpy as np

from pandas.util.testing import capture_stderr
import validate_docstrings
validate_one = validate_docstrings.validate_one

from pandas.util.testing import capture_stderr


class GoodDocStrings(object):
"""
Expand Down Expand Up @@ -712,9 +711,9 @@ def test_bad_generic_functions(self, func):
('BadSummaries', 'no_capitalization',
('Summary must start with infinitive verb',)),
('BadSummaries', 'multi_line',
('Summary should fit in a single line.',)),
('Summary should fit in a single line',)),
('BadSummaries', 'two_paragraph_multi_line',
('Summary should fit in a single line.',)),
('Summary should fit in a single line',)),
# Parameters tests
('BadParameters', 'missing_params',
('Parameters {**kwargs} not documented',)),
Expand Down Expand Up @@ -753,66 +752,67 @@ def test_bad_generic_functions(self, func):
marks=pytest.mark.xfail),
# Examples tests
('BadGenericDocStrings', 'method',
('numpy does not need to be imported in the examples',)),
('Do not import numpy, as it is imported automatically',)),
('BadGenericDocStrings', 'method',
('pandas does not need to be imported in the examples',)),
('Do not import pandas, as it is imported automatically',)),
# See Also tests
('BadSeeAlso', 'prefix_pandas',
('pandas.Series.rename in `See Also` section '
'does not need `pandas` prefix',)),
# Examples tests
('BadExamples', 'unused_import',
('1 F401 \'pandas as pdf\' imported but unused',)),
("flake8 error: F401 'pandas as pdf' imported but unused",)),
('BadExamples', 'indentation_is_not_a_multiple_of_four',
('1 E111 indentation is not a multiple of four',)),
('flake8 error: E111 indentation is not a multiple of four',)),
('BadExamples', 'missing_whitespace_around_arithmetic_operator',
('1 E226 missing whitespace around arithmetic operator',)),
('flake8 error: '
'E226 missing whitespace around arithmetic operator',)),
('BadExamples', 'missing_whitespace_after_comma',
('3 E231 missing whitespace after \',\'',)),
("flake8 error: E231 missing whitespace after ',' (3 times)",)),
])
def test_bad_examples(self, capsys, klass, func, msgs):
result = validate_one(self._import_path(klass=klass, func=func))
for msg in msgs:
assert msg in ' '.join(result['errors'])
assert msg in ' '.join(err[1] for err in result['errors'])


class ApiItems(object):
@property
def api_doc(self):
return io.StringIO('''
.. currentmodule:: itertools
return textwrap.dedent(io.StringIO('''
.. currentmodule:: itertools

Itertools
---------
Itertools
---------

Infinite
~~~~~~~~
Infinite
~~~~~~~~

.. autosummary::
.. autosummary::

cycle
count
cycle
count

Finite
~~~~~~
Finite
~~~~~~

.. autosummary::
.. autosummary::

chain
chain

.. currentmodule:: random
.. currentmodule:: random

Random
------
Random
------

All
~~~
All
~~~

.. autosummary::
.. autosummary::

seed
randint
''')
seed
randint
'''))

@pytest.mark.parametrize('idx,name', [(0, 'itertools.cycle'),
(1, 'itertools.count'),
Expand Down Expand Up @@ -850,3 +850,95 @@ def test_item_section(self, idx, section):
def test_item_subsection(self, idx, subsection):
result = list(validate_docstrings.get_api_items(self.api_doc))
assert result[idx][3] == subsection


class MainFunction(object):
def test_num_errors_for_validate_one(self, monkeypatch):
monkeypatch.setattr(
validate_docstrings, 'validate_one',
lambda func_name: {'docstring': 'docstring1',
'errors': [('ER01', 'err desc'),
('ER02', 'err desc')
('ER03', 'err desc')],
'warnings': [],
'examples_errors': ''})
num_errors = validate_docstrings.main(func_name='docstring1',
prefix=None,
errors=[],
output_format='default')
assert num_errors == 3

def test_no_num_errors_for_validate_one(self, monkeypatch):
monkeypatch.setattr(
validate_docstrings, 'validate_one',
lambda func_name: {'docstring': 'docstring1',
'errors': [],
'warnings': [('WN01', 'warn desc')],
'examples_errors': ''})
num_errors = validate_docstrings.main(func_name='docstring1',
prefix=None,
errors=[],
output_format='default')
assert num_errors == 0

def test_num_errors_for_validate_all(self, monkeypatch):
monkeypatch.setattr(
validate_docstrings, 'validate_all',
lambda: {'docstring1': {'errors': [('ER01', 'err desc'),
('ER02', 'err desc'),
('ER03', 'err desc')]},
'docstring2': {'errors': [('ER04', 'err desc'),
('ER05', 'err desc')]}})
num_errors = validate_docstrings.main(func_name=None,
prefix=None,
errors=[],
output_format='default')
assert num_errors == 5

def test_no_num_errors_for_validate_all(self, monkeypatch):
monkeypatch.setattr(
validate_docstrings, 'validate_all',
lambda: {'docstring1': {'errors': [],
'warnings': [('WN01', 'warn desc')]},
'docstring2': {'errors': []}})
num_errors = validate_docstrings.main(func_name=None,
prefix=None,
errors=[],
output_format='default')
assert num_errors == 0

def test_prefix_param_filters_docstrings(self, monkeypatch):
monkeypatch.setattr(
validate_docstrings, 'validate_all',
lambda: {'Series.foo': {'errors': [('ER01', 'err desc'),
('ER02', 'err desc'),
('ER03', 'err desc')]},
'DataFrame.bar': {'errors': [('ER04', 'err desc'),
('ER05', 'err desc')]},
'Series.foobar': {'errors': [('ER06', 'err desc')]}})
num_errors = validate_docstrings.main(func_name=None,
prefix='Series.',
errors=[],
output_format='default')
assert num_errors == 4

def test_errors_param_filters_errors(self, monkeypatch):
monkeypatch.setattr(
validate_docstrings, 'validate_all',
lambda: {'Series.foo': {'errors': [('ER01', 'err desc'),
('ER02', 'err desc'),
('ER03', 'err desc')]},
'DataFrame.bar': {'errors': [('ER01', 'err desc'),
('ER02', 'err desc')]},
'Series.foobar': {'errors': [('ER01', 'err desc')]}})
num_errors = validate_docstrings.main(func_name=None,
prefix=None,
errors=['E01'],
output_format='default')
assert num_errors == 3

num_errors = validate_docstrings.main(func_name=None,
prefix=None,
errors=['E03'],
output_format='default')
assert num_errors == 1
Loading