Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 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
55 changes: 47 additions & 8 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,51 @@
import pytest


@pytest.fixture
def default_config() -> dict[str, str]:
"""
Get the minimal default configuration for cutting a cookie in tests.

This is used if `generate_package` is called without arguments.
"""
return {
"github_owner": "test-user",
"project_short_description": "description",
"project_name": "Cookiecutter Test",
"project_slug": "cookiecutter-test",
}


@pytest.fixture
def default_config_with(default_config: dict[str, str]) -> typing.Callable:
"""Extend or modify the default configuration with one additional value."""

def _wrapped_with(key: str, value: str) -> dict[str, str]:
default_config[key] = value
return default_config

return _wrapped_with


def _generate_package(
config: dict[str, str], path: pathlib.Path
) -> subprocess.CompletedProcess[str]:
) -> tuple[subprocess.CompletedProcess[str], pathlib.Path]:
"""
Generate a project from the cookiecutter template.

Arguments:
---------
config: dict
Parameters
----------
config
A dictionary with values for the cookiecutter template,
as defined in the cookiecutter.json
path: Path
path
Directory to create package in.

Returns
-------
subprocess.CompletedProcess, pathlib.Path
The result of the cookiecutter command and the path to the generated package.

"""
args = [f"{key}={val}" for key, val in config.items()]
cmd = ["cookiecutter", ".", "--no-input", "--output-dir", f"{path}"]
Expand All @@ -30,10 +61,18 @@ def _generate_package(
shell=False,
capture_output=True,
text=True,
)
), path / config["project_slug"]


@pytest.fixture
def generate_package() -> typing.Callable:
def generate_package(
default_config: dict[str, str], tmp_path: pathlib.Path
) -> typing.Callable:
"""Generate project from cookiecutter template."""
return _generate_package

def _wrapped_with_tmp_path(
config: dict[str, str] = default_config,
) -> tuple[subprocess.CompletedProcess, pathlib.Path]:
return _generate_package(config, tmp_path)

return _wrapped_with_tmp_path
28 changes: 10 additions & 18 deletions tests/test_git_init.py
Original file line number Diff line number Diff line change
@@ -1,29 +1,21 @@
"""Checks that the git repo initialisation works."""

import pathlib
import subprocess
import typing

import pytest


@pytest.mark.parametrize("initialise_git_repository", [True, False])
@pytest.mark.parametrize("init", [True, False])
def test_initialisation_of_git_repo(
initialise_git_repository: bool, # noqa: FBT001
init: bool, # noqa: FBT001
default_config_with: typing.Callable,
generate_package: typing.Callable,
tmp_path: pathlib.Path,
) -> None:
"""Checks to see if git was correctly initialised if desired."""
test_config = {
"github_owner": "test-user",
"project_short_description": "description",
"project_name": "Cookiecutter Test",
"initialise_git_repository": initialise_git_repository,
}
# Run cookiecutter with initialise_git_repository
result = generate_package(config=test_config, path=tmp_path)

test_project_dir = tmp_path / "cookiecutter-test"
config = default_config_with("initialise_git_repository", str(init))
result, test_project_dir = generate_package(config=config)

# check if git is initialised
git_status = subprocess.run( # noqa: S603
Expand All @@ -37,7 +29,7 @@ def test_initialisation_of_git_repo(
text=True,
)

if not initialise_git_repository:
if not init:
# should not have found git
assert "fatal: not a git repository" in git_status.stderr
return # nothing more to test
Expand All @@ -57,9 +49,9 @@ def test_initialisation_of_git_repo(
)
assert (
"GitHub CLI detected, you can create a repo with the following:\n\n"
f"gh repo create {test_config['github_owner']}/"
f"gh repo create {config['github_owner']}/"
f"cookiecutter-test -d "
f'"{test_config["project_short_description"]}" --public -r '
f'"{config["project_short_description"]}" --public -r '
f"origin --source cookiecutter-test" in result.stdout
)
except FileNotFoundError:
Expand All @@ -69,11 +61,11 @@ def test_initialisation_of_git_repo(
assert (
"You now have a local git repository. To sync this to GitHub you "
"need to create an empty GitHub repo with the name "
f"{test_config['github_owner']}/"
f"{config['github_owner']}/"
f"cookiecutter-test - DO NOT SELECT ANY "
"OTHER OPTION.\n\nSee this link for more detail "
"https://docs.github.com/en/get-started/quickstart/create-a-repo"
".\n\nThen run:\n\ngit remote add origin git@github.com:"
f"{test_config['github_owner']}/"
f"{config['github_owner']}/"
f"cookiecutter-test.git" in result.stdout
)
56 changes: 13 additions & 43 deletions tests/test_package_generation.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,26 +36,18 @@ def get_all_files_folders(root_path: pathlib.Path) -> set[pathlib.Path]:


def test_package_generation(
tmp_path: pathlib.Path,
generate_package: typing.Callable,
default_config_with: typing.Callable, generate_package: typing.Callable
) -> None:
"""Test package generation."""
test_config = {
"github_owner": "test-user",
"project_short_description": "description",
"project_name": "Cookiecutter Test",
# Not having a git repo makes it easier to check in/out reference
# data files to the main python-tooling git repository
"initialise_git_repository": False,
}
generate_package(config=test_config, path=tmp_path)
# Not having a git repo makes it easier to check in/out reference
# data files to the main python-tooling git repository
config = default_config_with("initialise_git_repository", "False")
_, test_project_dir = generate_package(config=config)

expected_package_dir = (
pathlib.Path(__file__).parent / "data" / "test_package_generation"
)
# Check project directory exists
test_project_dir = tmp_path / "cookiecutter-test"
assert test_project_dir.exists()
assert test_project_dir.exists(), "Project directory does not exist."

actual_files = get_all_files_folders(test_project_dir)
expected_files = get_all_files_folders(expected_package_dir)
Expand Down Expand Up @@ -94,18 +86,11 @@ def test_package_generation(


def test_pip_installable(
tmp_path: pathlib.Path,
venv: pytest_venv.VirtualEnvironment,
generate_package: typing.Callable,
) -> None:
"""Test generated package is pip installable."""
test_config = {
"github_owner": "test-user",
"project_short_description": "description",
"project_name": "Cookiecutter Test",
}
generate_package(config=test_config, path=tmp_path)
test_project_dir = tmp_path / "cookiecutter-test"
_, test_project_dir = generate_package()
# Try to install package in virtual environment with pip
pipinstall = subprocess.run( # noqa: S603
[
Expand All @@ -124,46 +109,31 @@ def test_pip_installable(
)


@pytest.mark.parametrize("funder", ["", "STFC"])
@pytest.mark.parametrize("funder", ["", "STFC", "UKRI", "Wellcome Trust"])
def test_optional_funder(
tmp_path: pathlib.Path, generate_package: typing.Callable, funder: str
funder: str, default_config_with: typing.Callable, generate_package: typing.Callable
) -> None:
"""Test specifying funder or not in package generation."""
config = {
"github_owner": "test-user",
"project_short_description": "description",
"project_name": "Cookiecutter Test",
"funder": funder,
}

generate_package(config, tmp_path)
config = default_config_with("funder", funder)
_, test_project_dir = generate_package(config)

test_project_dir = tmp_path / "cookiecutter-test"
with (test_project_dir / "README.md").open() as f:
readme_text = "".join(f.readlines())

if funder == "":
assert "## Acknowledgements" not in readme_text
else:
assert (
f"## Acknowledgements\n\nThis work was funded by {config['funder']}."
in readme_text
f"## Acknowledgements\n\nThis work was funded by {funder}." in readme_text
), readme_text


def test_docs_build(
tmp_path: pathlib.Path,
venv: pytest_venv.VirtualEnvironment,
generate_package: typing.Callable,
) -> None:
"""Test documentation build from package created from template."""
config = {
"github_owner": "test-user",
"project_short_description": "description",
"project_name": "Cookiecutter Test",
}
generate_package(config, tmp_path)
test_project_dir = tmp_path / "cookiecutter-test"
_, test_project_dir = generate_package()
venv.install("tox")
tox_docs_process = subprocess.run( # noqa: S603
[
Expand Down
Loading