Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions hooks/post_gen_project.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,17 @@
"""

import shutil
import os
from pathlib import Path

REMOVE_PATHS = [
"acceptance-scenarios",
"tests/scenarios/steps",
"tests/basic_test.py"
]

for path in REMOVE_PATHS:
p = Path(".") / Path(path)
if p and p.exists() and p.is_dir():
shutil.rmtree(p)
elif p and p.exists() and p.is_file():
os.remove(p)
{% endif %}
Empty file.

This file was deleted.

28 changes: 0 additions & 28 deletions {{cookiecutter.project_slug}}/docs/gen_pages.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,31 +19,3 @@
) as f:
f.write(r.read())


# Injects feature files into the documentation
head_lines = (
"Feature:",
"Scenario:",
"Scenario Outline:",
"Rule:",
"Example:",
"Background:",
)
ignore_lines = ("@", "#")
features_dir = docs_parent_dir / "acceptance-scenarios"
for feature_path in features_dir.glob("**/*.feature"):
with Path.open(feature_path, "r") as f:
relative_dir = feature_path.parent.relative_to(features_dir)
with mkdocs_gen_files.open(
f"scenarios/{relative_dir}/{feature_path.stem}.md", "w"
) as gf:
f_line_list = f.readlines()
for line in f_line_list:
if any(line.strip().startswith(hl) for hl in head_lines):
write_line = f"### {line}\n"
elif any(line.strip().startswith(il) for il in ignore_lines):
continue
else:
write_line = f"> {line}"

gf.write(write_line)
1 change: 0 additions & 1 deletion {{cookiecutter.project_slug}}/docs/mkdocs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,3 @@ nav:
- index.md
- ... | glob=readme.md
- reference.md
- ... | regex=scenarios/.+.md
29 changes: 20 additions & 9 deletions {{cookiecutter.project_slug}}/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,12 @@ dev = [
"mkdocs-material>=9.6.11",
"mkdocstrings[python]>=0.29.1",
"pytest>=8.3.5",
"pytest-bdd>=8.1.0",
"pytest-cov>=6.1.1",
"pytest-html>=4.1.1",
"ruff>=0.11.5",
"taskipy>=1.14.1",
"hypothesis>=6.148.4",
"cosmic-ray>=8.4.3",
]

[tool.setuptools]
Expand Down Expand Up @@ -100,7 +101,6 @@ testpaths = [
python_files = ["*_test.py"]
python_functions = ["test_*"]
render_collapsed = true
bdd_features_base_dir = "acceptance-scenarios"

[tool.coverage.report]
exclude_lines = [
Expand All @@ -118,13 +118,15 @@ exclude_lines = [
run = "python -m {{cookiecutter.package_name}}.{{cookiecutter.module_name}}"
test-report = """\
pytest \
--cov-config=pyproject.toml \
--doctest-modules \
--cov-fail-under=90 \
--cov-report=term-missing \
--cov-report=html:docs/cov-report \
--cov-config=pyproject.toml \
--cov-report html:docs/htmlcov \
--cov-report term:skip-covered \
--cov={{cookiecutter.package_name}} \
--cov-fail-under={{cookiecutter.minimum_coverage}} \
--html=docs/pytest_report.html \
--self-contained-html\
--self-contained-html \
--hypothesis-show-statistics \
"""
test = """\
python -c "import subprocess, sys; print('Running Smoke Tests...'); sys.exit(0 if subprocess.run(['pytest', '-m', 'smoke']).returncode in (0,5) else 1)" && \
Expand All @@ -135,9 +137,18 @@ task test-report\
ruff-check = "ruff check **/*.py --fix"
ruff-format = "ruff format **/*.py"
lint = "task ruff-check && task ruff-format"
doc = "mkdocs serve --use-directory-urls -f docs/mkdocs.yaml"
doc-html = "mkdocs build --no-directory-urls -f docs/mkdocs.yaml"
doc-serve = "mkdocs serve --use-directory-urls -f docs/mkdocs.yaml"
doc-report = "mkdocs build --no-directory-urls -f docs/mkdocs.yaml"
doc-publish = """mkdocs gh-deploy \
--config-file docs/mkdocs.yaml \
--no-directory-urls \
--remote-branch docs"""
mut-report = """
uv run cosmic-ray new-config mut.toml && \
uv run cosmic-ray init mut.toml mut.sqlite && \
uv run cosmic-ray --verbosity=INFO baseline mut.toml && \
uv run cosmic-ray exec mut.toml mut.sqlite && \
uv run cr-html mut.sqlite > docs/mut_report.html && \
rm mut.toml && \
rm mut.sqlite
"""
20 changes: 20 additions & 0 deletions {{cookiecutter.project_slug}}/tests/basic_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{%- if cookiecutter.include_examples == "true" -%}from hypothesis import given, example, strategies as st
import math

from {{cookiecutter.package_name}} import {{cookiecutter.module_name}} as m


@example(a=6, b=3) # result = 2
@example(a=-8, b=2) # result = -4
@example(a=0, b=5) # zero dividend
@example(a=579, b=9105) # the earlier failing example (float rounding)
@given(
a=st.integers(min_value=-10_000, max_value=10_000),
b=st.integers(min_value=-10_000, max_value=10_000).filter(lambda x: x != 0),
)
def test_divide_inverse(a: int, b: int) -> None:
"""Check that multiplication is the inverse of division (within float tolerance)."""
result = m.Calculator.divide(a, b)

assert math.isclose(result * b, a, rel_tol=1e-12, abs_tol=1e-12)
{% endif %}
45 changes: 45 additions & 0 deletions {{cookiecutter.project_slug}}/tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import inspect

from _pytest.config import Config
from _pytest.nodes import Item


def pytest_configure(config: Config) -> None:
"""Initialize per-session state for docstring printing.

Creates a set on the config object used to track which test
node IDs (without parameterization suffixes) have already had
their docstrings printed.
"""
config._printed_docstrings = set() # type: ignore[attr-defined]


def pytest_runtest_setup(item: Item) -> None:
"""Print a test function's docstring the first time it is encountered.

The docstring is printed only once per “base” nodeid. For example,
a parametrized test like ``test_func[param]`` will only have its
docstring printed for the first parameterization. Subsequent cases
skip printing.
"""
tr = item.config.pluginmanager.getplugin("terminalreporter")
if not tr:
return

# strip parameterization suffix:
# "path/to/test.py::test_func[param]" → keep the part before "["
base_nodeid = item.nodeid.split("[", 1)[0]

if base_nodeid in item.config._printed_docstrings: # type: ignore[attr-defined]
return

doc = inspect.getdoc(item.obj) or ""
if not doc.strip():
item.config._printed_docstrings.add(base_nodeid) # type: ignore[attr-defined]
return

for line in doc.splitlines():
tr.write_line(" " + line)
tr.write_line("")

item.config._printed_docstrings.add(base_nodeid) # type: ignore[attr-defined]
74 changes: 0 additions & 74 deletions {{cookiecutter.project_slug}}/tests/scenarios/conftest.py

This file was deleted.

This file was deleted.