Skip to content

Commit e47ddc2

Browse files
committed
Updated tests and fixed licenses!
- Fixed license names to match the values in cookiecutter.json. - Added test to mutate cookiecutter.json, build project and check it. - Renamed some tests to reflect their actual purpose. - Moved some testing functions into conftest.py
1 parent 54d6a91 commit e47ddc2

16 files changed

+108
-52
lines changed

tests/conftest.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,61 @@
88

99
_PROJECT = "python-package-cookiecutter"
1010

11+
# EJO This file manifest is super fragile, it should be generated from
12+
# template data rather than duplicated here. It's a start.
13+
14+
MANIFEST = [
15+
("is_dir", ".git"),
16+
("is_dir", ".github"),
17+
("is_dir", ".github/ISSUE_TEMPLATE"),
18+
("is_dir", ".github/workflows"),
19+
("is_dir", ".venv"),
20+
("is_dir", "src"),
21+
("is_dir", "tests"),
22+
("is_file", ".envrc"),
23+
("is_file", ".github/ISSUE_TEMPLATE/1_bug_report.yaml"),
24+
("is_file", ".github/ISSUE_TEMPLATE/2_feature_request.yaml"),
25+
("is_file", ".github/ISSUE_TEMPLATE/3_question.yaml"),
26+
("is_file", ".github/ISSUE_TEMPLATE/config.yaml"),
27+
("is_file", ".github/PULL_REQUEST_TEMPLATE.md"),
28+
("is_file", ".github/dependabot.yaml"),
29+
("is_file", ".github/workflows/README.md"),
30+
("is_file", ".github/workflows/release.yaml"),
31+
("is_file", ".gitignore"),
32+
("is_file", "LICENSE"),
33+
("is_file", "README.md"),
34+
("is_file", "pyproject.toml"),
35+
("is_file", "uv.lock"),
36+
]
37+
38+
SRC = ["__init__.py", "__main__.py", "self_subcommand.py", "settings.py"]
39+
40+
41+
def check_project_contents(
42+
project_path: Path | str,
43+
project_name: str,
44+
) -> bool:
45+
"""Check that the project contents match the expected manifest."""
46+
project_path = Path(project_path)
47+
48+
assert project_path.exists()
49+
assert project_path.is_dir()
50+
51+
for content_test, content_path in MANIFEST:
52+
path = project_path / content_path
53+
54+
assert path.exists(), f"Expected {path} to exist"
55+
assert getattr(path, content_test)(), f"Expected {content_test} for {path}"
56+
57+
if path.is_file():
58+
assert path.stat().st_size > 0, f"File {path} is unexpectedly empty"
59+
60+
src = project_path / "src" / project_name
61+
for path in src.rglob("*.py"):
62+
assert path.name in SRC
63+
64+
return True
65+
1166

1267
@pytest.fixture(scope="session")
1368
def template_root() -> Path:

tests/test_default_project.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
"""tests the contents of the generated package."""
2+
3+
from pathlib import Path
4+
5+
from .conftest import check_project_contents
6+
7+
8+
def test_default_project(
9+
generated_template_path: Path,
10+
cookiecutter_package_name: str,
11+
) -> None:
12+
"""Tests the existence of content in the generated template."""
13+
assert check_project_contents(generated_template_path, cookiecutter_package_name)

tests/test_generate_projects.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
""" """
2+
3+
import pytest
4+
from pathlib import Path
5+
import json
6+
7+
from cookiecutter.main import cookiecutter as bake
8+
9+
from .conftest import check_project_contents
10+
11+
cwd = Path.cwd()
12+
13+
contents = json.loads((cwd / "cookiecutter.json").read_text())
14+
15+
EXTRAS = []
16+
for key, value in contents.items():
17+
if not isinstance(value, list) or key.startswith("_"):
18+
continue
19+
for item in value:
20+
EXTRAS.append({key: item})
21+
22+
23+
@pytest.mark.parametrize("extra", EXTRAS)
24+
def test_generate_project(
25+
extra: dict[str, str],
26+
tmp_path_factory: pytest.TempPathFactory,
27+
template_root: Path,
28+
cookiecutter_extra_context: dict,
29+
cookiecutter_package_name: str,
30+
) -> None:
31+
tmp_path = tmp_path_factory.mktemp("generated_project")
32+
33+
project_path = bake(
34+
template=str(template_root),
35+
no_input=True,
36+
extra_context=extra | cookiecutter_extra_context,
37+
output_dir=tmp_path,
38+
)
39+
40+
assert check_project_contents(project_path, cookiecutter_package_name)

tests/test_generated_project.py

Lines changed: 0 additions & 52 deletions
This file was deleted.

{{ cookiecutter.package_name }}/{% if cookiecutter.license == "agpl-3.0" %}LICENSE{% endif %} renamed to {{ cookiecutter.package_name }}/{% if cookiecutter.license == "AGPL-3.0" %}LICENSE{% endif %}

File renamed without changes.

{{ cookiecutter.package_name }}/{% if cookiecutter.license == "bsd-2-clause" %}LICENSE{% endif %} renamed to {{ cookiecutter.package_name }}/{% if cookiecutter.license == "BSD-2-Clause" %}LICENSE{% endif %}

File renamed without changes.

{{ cookiecutter.package_name }}/{% if cookiecutter.license == "bsd-3-clause" %}LICENSE{% endif %} renamed to {{ cookiecutter.package_name }}/{% if cookiecutter.license == "BSD-3-Clause" %}LICENSE{% endif %}

File renamed without changes.

{{ cookiecutter.package_name }}/{% if cookiecutter.license == "bsl-1.0" %}LICENSE{% endif %} renamed to {{ cookiecutter.package_name }}/{% if cookiecutter.license == "BSL-1.0" %}LICENSE{% endif %}

File renamed without changes.

{{ cookiecutter.package_name }}/{% if cookiecutter.license == "cc0-1.0" %}LICENSE{% endif %} renamed to {{ cookiecutter.package_name }}/{% if cookiecutter.license == "CC0-1.0" %}LICENSE{% endif %}

File renamed without changes.

{{ cookiecutter.package_name }}/{% if cookiecutter.license == "epl-2.0" %}LICENSE{% endif %} renamed to {{ cookiecutter.package_name }}/{% if cookiecutter.license == "EPL-2.0" %}LICENSE{% endif %}

File renamed without changes.

0 commit comments

Comments
 (0)