Reorganised Python tests to be more pytest-like

This commit is contained in:
Ashley Whetter 2018-12-13 17:52:06 -08:00
parent 9397c0709f
commit 88eea89bb5
20 changed files with 344 additions and 222 deletions

View File

@ -0,0 +1,6 @@
from .subpackage import public_chain
from .subpackage.submodule import public_multiple_imports
def module_level_method(foo, bar):
"""A module level method"""
pass

View File

@ -0,0 +1,10 @@
from .submodule import public_chain
from .submodule import _private_made_public as now_public_function
from .submodule import public_multiple_imports
def module_level_method(foo, bar):
"""A module level method"""
pass
def module_level_method(foo, bar):
"""A module level method"""
pass

View File

@ -0,0 +1,11 @@
def public_chain():
"""Part of a resolution chain."""
return 5
def _private_made_public():
"""A private function made public by import."""
return 5
def public_multiple_imports():
"""A public function imported in multiple places."""
return 5

View File

@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
templates_path = ['_templates']
source_suffix = '.rst'
master_doc = 'index'
project = u'pypackagecomplex'
copyright = u'2015, rtfd'
author = u'rtfd'
version = '0.1'
release = '0.1'
language = None
exclude_patterns = ['_build']
pygments_style = 'sphinx'
todo_include_todos = False
html_theme = 'alabaster'
html_static_path = ['_static']
htmlhelp_basename = 'pypackagecomplexdoc'
extensions = ['autoapi.extension']
autoapi_type = 'python'
autoapi_dirs = ['complex']
autoapi_file_pattern = '*.py'

View File

@ -0,0 +1,6 @@
class PrivateClass(object):
"""A private class with public facing methods."""
def public_method():
"""This is public."""
return 5

View File

@ -0,0 +1,65 @@
"""Example module
This is a description
"""
class Foo(object):
class_var = 42 #: Class var docstring
another_class_var = 42
"""Another class var docstring"""
class Meta(object):
"""A nested class just to test things out"""
@classmethod
def foo():
"""The foo class method"""
return True
def method_okay(self, foo=None, bar=None):
"""This method should parse okay"""
return True
def method_multiline(self, foo=None, bar=None,
baz=None):
"""This is on multiple lines, but should parse okay too
pydocstyle gives us lines of source. Test if this means that multiline
definitions are covered in the way we're anticipating here
"""
return True
def method_tricky(self, foo=None, bar=dict(foo=1, bar=2)):
"""This will likely fail our argument testing
We parse naively on commas, so the nested dictionary will throw this off
"""
return True
def method_sphinx_docs(self, foo, bar=0):
"""This method is documented with sphinx style docstrings.
:param foo: The first argument.
:type foo: int
:param int bar: The second argument.
:returns: The sum of foo and bar.
:rtype: int
"""
return foo + bar
def method_google_docs(self, foo, bar=0):
"""This method is documented with google style docstrings.
Args:
foo (int): The first argument.
bar (int): The second argument.
Returns:
int: The sum of foo and bar.
"""
return foo + bar

View File

@ -0,0 +1,25 @@
.. pypackageexample documentation master file, created by
sphinx-quickstart on Fri May 29 13:34:37 2015.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
Welcome to pypackageexample's documentation!
=====================================
.. toctree::
autoapi/index
Contents:
.. toctree::
:maxdepth: 2
Indices and tables
==================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`

View File

@ -0,0 +1,200 @@
import io
import os
import shutil
import pytest
import sphinx
from sphinx.application import Sphinx
@pytest.fixture(scope='class')
def builder():
cwd = os.getcwd()
def build(test_dir, confoverrides=None):
os.chdir('tests/python/{0}'.format(test_dir))
app = Sphinx(
srcdir='.',
confdir='.',
outdir='_build/text',
doctreedir='_build/.doctrees',
buildername='text',
confoverrides=confoverrides,
)
app.build(force_all=True)
yield build
try:
shutil.rmtree('_build')
finally:
os.chdir(cwd)
class TestSimpleModule(object):
@pytest.fixture(autouse=True, scope='class')
def built(self, builder):
builder('pyexample')
def test_integration(self):
self.check_integration(
'_build/text/autoapi/example/index.txt',
)
def test_manual_directives(self):
# The manual directives should contain the same information
self.check_integration(
'_build/text/manualapi.txt',
)
def check_integration(self, example_path):
with io.open(example_path, encoding='utf8') as example_handle:
example_file = example_handle.read()
assert 'class example.Foo' in example_file
assert 'class Meta' in example_file
assert 'attr2' in example_file
assert 'This is the docstring of an instance attribute.' in example_file
assert 'method_okay(self, foo=None, bar=None)' in example_file
assert 'method_multiline(self, foo=None, bar=None, baz=None)' in example_file
assert 'method_tricky(self, foo=None, bar=dict(foo=1, bar=2))' in example_file
# Are constructor arguments from the class docstring parsed?
assert 'Set an attribute' in example_file
# "self" should not be included in constructor arguments
assert 'Foo(self' not in example_file
assert not os.path.exists('_build/text/autoapi/method_multiline')
index_path = '_build/text/index.txt'
with io.open(index_path, encoding='utf8') as index_handle:
index_file = index_handle.read()
assert 'Sphinx AutoAPI Index' in index_file
assert 'Foo' in index_file
assert 'Meta' in index_file
@pytest.mark.skipif(sphinx.version_info < (1, 4),
reason="Cannot override extensions in Sphinx 1.3")
def test_napoleon_integration_not_loaded(self, builder):
example_path = '_build/text/autoapi/example/index.txt'
with io.open(example_path, encoding='utf8') as example_handle:
example_file = example_handle.read()
# Check that docstrings are not transformed without napoleon loaded
assert 'Args' in example_file
assert 'Returns' in example_file
@pytest.mark.skipif(sphinx.version_info < (1, 4),
reason="Cannot override extensions in Sphinx 1.3")
def test_napoleon_integration_loaded(builder):
confoverrides = {
'extensions': [
'autoapi.extension',
'sphinx.ext.autodoc',
'sphinx.ext.napoleon',
],
}
builder('pyexample', confoverrides=confoverrides)
example_path = '_build/text/autoapi/example/index.txt'
with io.open(example_path, encoding='utf8') as example_handle:
example_file = example_handle.read()
assert 'Parameters' in example_file
assert 'Return type' in example_file
assert 'Args' not in example_file
class TestSimplePackage(object):
@pytest.fixture(autouse=True, scope='class')
def built(self, builder):
builder('pypackageexample')
def test_integration_with_package(self, builder):
example_path = '_build/text/autoapi/example/index.txt'
with io.open(example_path, encoding='utf8') as example_handle:
example_file = example_handle.read()
assert 'example.foo' in example_file
assert 'example.module_level_method(foo, bar)' in example_file
example_foo_path = '_build/text/autoapi/example/foo/index.txt'
with io.open(example_foo_path, encoding='utf8') as example_foo_handle:
example_foo_file = example_foo_handle.read()
assert 'class example.foo.Foo' in example_foo_file
assert 'method_okay(self, foo=None, bar=None)' in example_foo_file
index_path = '_build/text/index.txt'
with io.open(index_path, encoding='utf8') as index_handle:
index_file = index_handle.read()
assert 'Sphinx AutoAPI Index' in index_file
assert 'example.foo' in index_file
assert 'Foo' in index_file
assert 'module_level_method' in index_file
def _test_class_content(builder, class_content):
confoverrides = {
'autoapi_python_class_content': class_content,
}
builder('pyexample', confoverrides=confoverrides)
example_path = '_build/text/autoapi/example/index.txt'
with io.open(example_path, encoding='utf8') as example_handle:
example_file = example_handle.read()
if class_content == 'init':
assert 'Can we parse arguments' not in example_file
else:
assert 'Can we parse arguments' in example_file
if class_content not in ('both', 'init'):
assert 'Constructor docstring' not in example_file
else:
assert 'Constructor docstring' in example_file
def test_class_class_content(builder):
_test_class_content(builder, 'class')
def test_both_class_content(builder):
_test_class_content(builder, 'both')
def test_init_class_content(builder):
_test_class_content(builder, 'init')
def test_hiding_private_members(builder):
confoverrides = {
'autoapi_options': ['members', 'undoc-members', 'special-members'],
}
builder('pypackageexample', confoverrides=confoverrides)
example_path = '_build/text/autoapi/example/index.txt'
with io.open(example_path, encoding='utf8') as example_handle:
example_file = example_handle.read()
assert 'private' not in example_file
private_path = '_build/text/autoapi/example/_private_module/index.txt'
with io.open(private_path, encoding='utf8') as private_handle:
private_file = private_handle.read()
assert 'public_method' in private_file

View File

@ -69,228 +69,6 @@ class GoTests(LanguageIntegrationTests):
) )
class PythonTests(LanguageIntegrationTests):
def test_integration(self):
self.check_integration(
'_build/text/autoapi/example/index.txt'
)
def test_manual_directives(self):
# The manual directives should contain the same information
self.check_integration(
'_build/text/manualapi.txt'
)
def check_integration(self, example_path):
with sphinx_build('pyexample'):
with io.open(example_path, encoding='utf8') as example_handle:
example_file = example_handle.read()
self.assertIn(
'class example.Foo',
example_file
)
self.assertIn(
'class Meta',
example_file
)
self.assertIn(
'attr2',
example_file
)
self.assertIn(
'This is the docstring of an instance attribute.',
example_file
)
self.assertIn(
'method_okay(self, foo=None, bar=None)',
example_file
)
self.assertIn(
'method_multiline(self, foo=None, bar=None, baz=None)',
example_file
)
self.assertIn(
'method_tricky(self, foo=None, bar=dict(foo=1, bar=2))',
example_file
)
# Are constructor arguments from the class docstring parsed?
self.assertIn(
'Set an attribute',
example_file
)
# "self" should not be included in constructor arguments
self.assertNotIn(
'Foo(self',
example_file
)
self.assertFalse(
os.path.exists('_build/text/autoapi/method_multiline')
)
index_path = '_build/text/index.txt'
with io.open(index_path, encoding='utf8') as index_handle:
index_file = index_handle.read()
self.assertIn(
'Sphinx AutoAPI Index',
index_file
)
self.assertIn(
'Foo',
index_file
)
self.assertIn(
'Meta',
index_file
)
def test_integration_with_package(self):
with sphinx_build('pypackageexample'):
example_path = '_build/text/autoapi/example/index.txt'
with io.open(example_path, encoding='utf8') as example_handle:
example_file = example_handle.read()
self.assertIn(
'example.foo',
example_file
)
self.assertIn(
'example.module_level_method(foo, bar)',
example_file
)
example_foo_path = '_build/text/autoapi/example/foo/index.txt'
with io.open(example_foo_path, encoding='utf8') as example_foo_handle:
example_foo_file = example_foo_handle.read()
self.assertIn(
'class example.foo.Foo',
example_foo_file
)
self.assertIn(
'method_okay(self, foo=None, bar=None)',
example_foo_file
)
index_path = '_build/text/index.txt'
with io.open(index_path, encoding='utf8') as index_handle:
index_file = index_handle.read()
self.assertIn(
'Sphinx AutoAPI Index',
index_file
)
self.assertIn(
'example.foo',
index_file
)
self.assertIn(
'Foo',
index_file
)
self.assertIn(
'module_level_method',
index_file
)
@pytest.mark.skipif(sphinx.version_info < (1, 4),
reason="Cannot override extensions in Sphinx 1.3")
def test_napoleon_integration(self):
with sphinx_build('pyexample'):
example_path = '_build/text/autoapi/example/index.txt'
with io.open(example_path, encoding='utf8') as example_handle:
example_file = example_handle.read()
# Check that docstrings are not transformed without napoleon loaded
self.assertIn(
'Args',
example_file
)
self.assertIn(
'Returns',
example_file
)
confoverrides={
'extensions': [
'autoapi.extension',
'sphinx.ext.autodoc',
'sphinx.ext.napoleon',
],
}
with sphinx_build('pyexample', confoverrides=confoverrides):
example_path = '_build/text/autoapi/example/index.txt'
with io.open(example_path, encoding='utf8') as example_handle:
example_file = example_handle.read()
self.assertIn(
'Parameters',
example_file
)
self.assertIn(
'Return type',
example_file
)
self.assertNotIn(
'Args',
example_file
)
def _test_class_content(self, class_content):
confoverrides={
'autoapi_python_class_content': class_content,
}
with sphinx_build('pyexample', confoverrides=confoverrides):
example_path = '_build/text/autoapi/example/index.txt'
with io.open(example_path, encoding='utf8') as example_handle:
example_file = example_handle.read()
assert_class = self.assertIn
if class_content == 'init':
assert_class = self.assertNotIn
assert_class(
'Can we parse arguments',
example_file
)
assert_init = self.assertIn
if class_content not in ('both', 'init'):
assert_init = self.assertNotIn
assert_init(
'Constructor docstring',
example_file
)
def test_class_class_content(self):
self._test_class_content('class')
def test_both_class_content(self):
self._test_class_content('both')
def test_init_class_content(self):
self._test_class_content('init')
def test_hiding_private_members(self):
confoverrides = {
'autoapi_options': ['members', 'undoc-members', 'special-members'],
}
with sphinx_build('pypackageexample', confoverrides=confoverrides):
example_path = '_build/text/autoapi/example/index.txt'
with io.open(example_path, encoding='utf8') as example_handle:
example_file = example_handle.read()
self.assertNotIn('private', example_file)
private_path = '_build/text/autoapi/example/_private_module/index.txt'
with io.open(private_path, encoding='utf8') as private_handle:
private_file = private_handle.read()
self.assertIn('public_method', private_file)
class DotNetTests(LanguageIntegrationTests): class DotNetTests(LanguageIntegrationTests):
def _dotnet_read(self, path): def _dotnet_read(self, path):