[go: up one dir, main page]

Skip to content

Commit

Permalink
fix identification of documentation and example-codeblocks as unittests
Browse files Browse the repository at this point in the history
  • Loading branch information
raphaelquast committed Aug 24, 2024
1 parent 616779b commit c06165c
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 70 deletions.
93 changes: 67 additions & 26 deletions tests/test_doc_codeblocks.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def test(*args, **kwargs):
return test


def is_code_block(node):
def is_test_code_block(node):
return (
node.tagname == "literal_block"
and "code" in node.attributes["classes"]
Expand All @@ -29,42 +29,83 @@ def is_code_block(node):
)


class _TestSequenceMeta(type):
def is_any_code_block(node):
return node.tagname == "literal_block" and "code" in node.attributes["classes"]


def _parse_codeblocks_as_test(p, tests, condition=is_test_code_block):
with open(p, "r", encoding="utf8") as file:
data = file.read()

# initialize a "Publisher" to parse the file
doctree = publish_doctree(
data, settings_overrides={"report_level": Reporter.SEVERE_LEVEL}
)

# get a list of all code-blocks in the file
code_blocks = list(doctree.traverse(condition=condition))

# generate unique tests for each code snippet
for i, node in enumerate(code_blocks):
source_code = node.astext()
names = node.attributes.get("names")
if len(names) > 0:
name = names[0]
else:
name = p.name

test_name = f"test_{p.stem}_{i}"
tests[test_name] = gen_test(i, name, source_code)


# the path to the re-structured text file that should be analyzed
docs_path = Path(__file__).parent.parent / "docs" / "source"
examples_path = Path(__file__).parent.parent / "examples"


class _TestDocsSequenceMeta(type):
"""
Metaclass to create tests from each code-block in the documentation
whose ID starts with "test_".
"""

def __new__(mcs, name, bases, tests):
# the path to the re-structured text file that should be analyzed
parent_path = Path(__file__).parent.parent / "docs"
# set cwd to doc parent path to avoid issues with 'include' statements
# remember current working directory
cwd = os.getcwd()
os.chdir(parent_path)

for p in filter(lambda x: x.suffix == ".rst", parent_path.iterdir()):
with open(p, "r", encoding="utf8") as file:
data = file.read()
# set cwd to doc parent path to avoid issues with 'include' statements
for p in docs_path.rglob("*.rst"):
os.chdir(p.parent)
_parse_codeblocks_as_test(p, tests, condition=is_test_code_block)

os.chdir(cwd)

return type.__new__(mcs, name, bases, tests)


# initialize a "Publisher" to parse the file
doctree = publish_doctree(
data, settings_overrides={"report_level": Reporter.SEVERE_LEVEL}
)
class _TestExamplesSequenceMeta(type):
"""
Metaclass to create tests from each code-block found in the examples directory.
"""

# get a list of all code-blocks in the file
# replace .traverse with .findall once docutils > 18.1 is used!
if hasattr(doctree, "findall"):
code_blocks = list(doctree.findall(condition=is_code_block))
else:
code_blocks = list(doctree.traverse(condition=is_code_block))
def __new__(mcs, name, bases, tests):
# remember current working directory
cwd = os.getcwd()

# generate unique tests for each code snippet
for i, node in enumerate(code_blocks):
source_code = node.astext()
name = node.attributes["names"][0]
# set cwd to doc user_guide path to avoid issues with 'include' statements
os.chdir(docs_path / "user_guide")

test_name = f"test_{p.stem}_{i}"
tests[test_name] = gen_test(i, name, source_code)
for p in examples_path.rglob("*.rst"):
_parse_codeblocks_as_test(p, tests, condition=is_any_code_block)

os.chdir(cwd)

return type.__new__(mcs, name, bases, tests)


class TestDocumentationCodeblocks(unittest.TestCase, metaclass=_TestSequenceMeta):
class TestDocumentationCodeblocks(unittest.TestCase, metaclass=_TestDocsSequenceMeta):
pass


class TestExamplesCodeblocks(unittest.TestCase, metaclass=_TestExamplesSequenceMeta):
pass
44 changes: 0 additions & 44 deletions tests/test_examples.py

This file was deleted.

0 comments on commit c06165c

Please sign in to comment.