diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 868fd07..217862d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -74,3 +74,6 @@ jobs: # this is the only hook that works without an additional arg so we can test it like this - name: Validate the docstringify-check pre-commit hook run: pre-commit try-repo . docstringify-check --all-files + + - name: Run tests + run: pytest diff --git a/pyproject.toml b/pyproject.toml index 3ea9ae8..ea2b291 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -85,6 +85,26 @@ lint.isort.split-on-trailing-comma = false ignore-words-list = "docstringify" ignore-regex = "https://([\\w/\\.])+" +[tool.pytest] +ini_options.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", +] +ini_options.filterwarnings = [ "error" ] +ini_options.xfail_strict = true +ini_options.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