diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0013481..19c4182 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -67,3 +67,6 @@ jobs: - name: Validate pre-commit hook run: pre-commit try-repo . docstringify + + - name: Run tests + run: pytest diff --git a/pyproject.toml b/pyproject.toml index 710687f..251e464 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -87,6 +87,26 @@ lint.isort.known-first-party = [ [tool.codespell] ignore-regex = 'https://([\w/\.])+' +[tool.pytest.ini_options] +filterwarnings = [ "error" ] +addopts = [ + "-ra", + "-l", + "-v", + "--tb=short", + "--import-mode=importlib", + "--strict-markers", + "--strict-config", + "--cov=docstringify", + "--cov=tests", + "--no-cov-on-fail", + "--cov-report=term-missing", +] +xfail_strict = true +testpaths = [ + "tests", +] + [tool.numpydoc_validation] checks = [ "all", # report on all checks diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..ffd823a --- /dev/null +++ b/tests/__init__.py @@ -0,0 +1 @@ +"""Test suite for Docstringify.""" diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 0000000..996076f --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,39 @@ +"""Shared test fixtures.""" + +from collections import namedtuple +from textwrap import dedent + +import pytest + +EXAMPLE_MODULE_NAME = 'example_module' +EXAMPLE_FUNCTION_NAME = 'function' + +DocstringifyTestCase = namedtuple( + 'DocstringifyTestCase', ('file', 'total_docstrings', 'missing_docstrings') +) + + +@pytest.fixture +def function_without_args(tmp_path): + """ + Fixture for generating an example module with a function without args, type + annotations, or a docstring. + """ + source_code = dedent( + f""" + def {EXAMPLE_FUNCTION_NAME}(): + pass + """ + ) + + tmp_file = tmp_path / f'{EXAMPLE_MODULE_NAME}.py' + tmp_file.write_text(source_code) + + return DocstringifyTestCase( + file=tmp_file, + total_docstrings=2, + missing_docstrings=[ + EXAMPLE_MODULE_NAME, + f'{EXAMPLE_MODULE_NAME}.{EXAMPLE_FUNCTION_NAME}', + ], + ) diff --git a/tests/traversal/__init__.py b/tests/traversal/__init__.py new file mode 100644 index 0000000..c1a7016 --- /dev/null +++ b/tests/traversal/__init__.py @@ -0,0 +1 @@ +"""Tests for the docstringify.traversal subpackage.""" diff --git a/tests/traversal/test_visitor.py b/tests/traversal/test_visitor.py new file mode 100644 index 0000000..710e4a8 --- /dev/null +++ b/tests/traversal/test_visitor.py @@ -0,0 +1,23 @@ +"""Test the docstring.traversal.visitor module.""" + +import pytest + +from docstringify.traversal import DocstringVisitor + + +class TestDocstringVisitor: + """Test the DocstringVisitor.""" + + @pytest.mark.parametrize('file', ['function_without_args']) + def test_process_file(self, capsys, request, file): + """Test that DocstringVisitor.process_file() correctly processes files.""" + test_case = request.getfixturevalue(file) + visitor = DocstringVisitor(test_case.file) + visitor.process_file() + + assert visitor.docstrings_inspected == test_case.total_docstrings + assert len(visitor.missing_docstrings) == len(test_case.missing_docstrings) + + stderr = capsys.readouterr().err.strip().split('\n') + for missing_docstring in test_case.missing_docstrings: + assert f'{missing_docstring} is missing a docstring' in stderr