cookiecutter-django/tests/test_cookiecutter_generation.py

176 lines
5.2 KiB
Python
Raw Normal View History

import os
import re
import pytest
from cookiecutter.exceptions import FailedHookException
from pytest_cases import pytest_fixture_plus
import sh
import yaml
from binaryornot.check import is_binary
2019-05-27 18:54:08 +03:00
PATTERN = r"{{(\s?cookiecutter)[.](.*?)}}"
RE_OBJ = re.compile(PATTERN)
@pytest.fixture
def context():
return {
"project_name": "My Test Project",
"project_slug": "my_test_project",
"author_name": "Test Author",
"email": "test@example.com",
"description": "A short description of the project.",
"domain_name": "example.com",
"version": "0.1.0",
"timezone": "UTC",
}
@pytest_fixture_plus
@pytest.mark.parametrize("windows", ["y", "n"], ids=lambda yn: f"win:{yn}")
@pytest.mark.parametrize("use_docker", ["y", "n"], ids=lambda yn: f"docker:{yn}")
@pytest.mark.parametrize("use_celery", ["y", "n"], ids=lambda yn: f"celery:{yn}")
@pytest.mark.parametrize("use_mailhog", ["y", "n"], ids=lambda yn: f"mailhog:{yn}")
@pytest.mark.parametrize("use_sentry", ["y", "n"], ids=lambda yn: f"sentry:{yn}")
@pytest.mark.parametrize("use_compressor", ["y", "n"], ids=lambda yn: f"cmpr:{yn}")
@pytest.mark.parametrize(
"use_whitenoise,cloud_provider",
[
("y", "AWS"),
("y", "GCP"),
("y", "None"),
("n", "AWS"),
("n", "GCP"),
# no whitenoise + co cloud provider is not supported
],
ids=lambda id: f"wnoise:{id[0]}-cloud:{id[1]}",
)
def context_combination(
windows,
use_docker,
use_celery,
use_mailhog,
use_sentry,
use_compressor,
use_whitenoise,
cloud_provider,
):
"""Fixture that parametrize the function where it's used."""
return {
"windows": windows,
"use_docker": use_docker,
"use_compressor": use_compressor,
"use_celery": use_celery,
"use_mailhog": use_mailhog,
"use_sentry": use_sentry,
"use_whitenoise": use_whitenoise,
"cloud_provider": cloud_provider,
}
def build_files_list(root_dir):
"""Build a list containing absolute paths to the generated files."""
return [
os.path.join(dirpath, file_path)
for dirpath, subdirs, files in os.walk(root_dir)
for file_path in files
]
2015-11-09 02:02:07 +03:00
def check_paths(paths):
"""Method to check all paths have correct substitutions,
used by other tests cases
"""
# Assert that no match is found in any of the files
for path in paths:
if is_binary(path):
continue
for line in open(path, "r"):
match = RE_OBJ.search(line)
msg = "cookiecutter variable not replaced in {}"
assert match is None, msg.format(path)
def test_project_generation(cookies, context, context_combination):
"""
Test that project is generated and fully rendered.
This is parametrized for each combination from ``context_combination`` fixture
"""
result = cookies.bake(extra_context={**context, **context_combination})
assert result.exit_code == 0
assert result.exception is None
assert result.project.basename == context["project_slug"]
assert result.project.isdir()
paths = build_files_list(str(result.project))
assert paths
check_paths(paths)
@pytest.mark.flake8
def test_flake8_passes(cookies, context_combination):
"""
Generated project should pass flake8.
2015-11-09 02:02:07 +03:00
This is parametrized for each combination from ``context_combination`` fixture
"""
result = cookies.bake(extra_context=context_combination)
2015-11-09 02:02:07 +03:00
try:
sh.flake8(str(result.project))
except sh.ErrorReturnCode as e:
pytest.fail(e)
Add missing `script` key to Travis CI config (#1950) * Add failing test for travis.yml I see three options to test travis.yml : 1. Testing that the YAML contains relevant value. Least useful and least reliable, but simplest to implement. 2. Testing that the YAML is valid TravisCI YAML. Unfortunately this is difficult / impossible. Doing 'travis lint' would succeed, this command does not check for 'script' key presence and wouldn't be useful for us. We could use 'travis-build' to verify that the YAML can be converted to a worker config, but as of now 'travis-build' doesn't work out of the box. There is a new tool for validating travis YAML files 'travis-yml', but as of now it's a ruby-only library and it's still a work in progress. 3. Running Travis CI task based on the generated YAML. This seems the best approach, however since cookiecutter-django itself uses Travis CI, that would require running Travis CI from within Travis CI. Scheduling Travis CI job without a github push still requires a public github repo, which is something that we can't generate on demand. Given that I'm opting to use approach 1. * Adds missing config to generated .travis.yml The keys added are as follows: 1. 'script' Required by Travis, cookiecutter-django used to provide it until it has been removed together with hitch. I'm assuming hitch has been replaced with pytest, I'm setting pytest as the new value for the 'script' key. 2. 'install' Not required by Travis, but necessary in our case; installs test libraries, mostly pytest. As of now this points to 'local.txt' requirements file. There used to be a separate 'test.txt' requirements file but it has been decided to merge it with 'local.txt', see discussion in https://github.com/pydanny/cookiecutter-django/pull/1557 . * Update CONTRIBUTORS.rst
2019-03-06 04:10:45 +03:00
@pytest.mark.black
def test_black_passes(cookies, context_combination):
"""
Generated project should pass black.
This is parametrized for each combination from ``context_combination`` fixture
"""
result = cookies.bake(extra_context=context_combination)
try:
sh.black("--check", "--diff", "--exclude", "migrations", f"{result.project}/")
except sh.ErrorReturnCode as e:
pytest.fail(e)
Add missing `script` key to Travis CI config (#1950) * Add failing test for travis.yml I see three options to test travis.yml : 1. Testing that the YAML contains relevant value. Least useful and least reliable, but simplest to implement. 2. Testing that the YAML is valid TravisCI YAML. Unfortunately this is difficult / impossible. Doing 'travis lint' would succeed, this command does not check for 'script' key presence and wouldn't be useful for us. We could use 'travis-build' to verify that the YAML can be converted to a worker config, but as of now 'travis-build' doesn't work out of the box. There is a new tool for validating travis YAML files 'travis-yml', but as of now it's a ruby-only library and it's still a work in progress. 3. Running Travis CI task based on the generated YAML. This seems the best approach, however since cookiecutter-django itself uses Travis CI, that would require running Travis CI from within Travis CI. Scheduling Travis CI job without a github push still requires a public github repo, which is something that we can't generate on demand. Given that I'm opting to use approach 1. * Adds missing config to generated .travis.yml The keys added are as follows: 1. 'script' Required by Travis, cookiecutter-django used to provide it until it has been removed together with hitch. I'm assuming hitch has been replaced with pytest, I'm setting pytest as the new value for the 'script' key. 2. 'install' Not required by Travis, but necessary in our case; installs test libraries, mostly pytest. As of now this points to 'local.txt' requirements file. There used to be a separate 'test.txt' requirements file but it has been decided to merge it with 'local.txt', see discussion in https://github.com/pydanny/cookiecutter-django/pull/1557 . * Update CONTRIBUTORS.rst
2019-03-06 04:10:45 +03:00
def test_travis_invokes_pytest(cookies, context):
context.update({"use_travisci": "y"})
result = cookies.bake(extra_context=context)
assert result.exit_code == 0
assert result.exception is None
assert result.project.basename == context["project_slug"]
assert result.project.isdir()
with open(f"{result.project}/.travis.yml", "r") as travis_yml:
Add missing `script` key to Travis CI config (#1950) * Add failing test for travis.yml I see three options to test travis.yml : 1. Testing that the YAML contains relevant value. Least useful and least reliable, but simplest to implement. 2. Testing that the YAML is valid TravisCI YAML. Unfortunately this is difficult / impossible. Doing 'travis lint' would succeed, this command does not check for 'script' key presence and wouldn't be useful for us. We could use 'travis-build' to verify that the YAML can be converted to a worker config, but as of now 'travis-build' doesn't work out of the box. There is a new tool for validating travis YAML files 'travis-yml', but as of now it's a ruby-only library and it's still a work in progress. 3. Running Travis CI task based on the generated YAML. This seems the best approach, however since cookiecutter-django itself uses Travis CI, that would require running Travis CI from within Travis CI. Scheduling Travis CI job without a github push still requires a public github repo, which is something that we can't generate on demand. Given that I'm opting to use approach 1. * Adds missing config to generated .travis.yml The keys added are as follows: 1. 'script' Required by Travis, cookiecutter-django used to provide it until it has been removed together with hitch. I'm assuming hitch has been replaced with pytest, I'm setting pytest as the new value for the 'script' key. 2. 'install' Not required by Travis, but necessary in our case; installs test libraries, mostly pytest. As of now this points to 'local.txt' requirements file. There used to be a separate 'test.txt' requirements file but it has been decided to merge it with 'local.txt', see discussion in https://github.com/pydanny/cookiecutter-django/pull/1557 . * Update CONTRIBUTORS.rst
2019-03-06 04:10:45 +03:00
try:
assert yaml.load(travis_yml)["script"] == ["pytest"]
Add missing `script` key to Travis CI config (#1950) * Add failing test for travis.yml I see three options to test travis.yml : 1. Testing that the YAML contains relevant value. Least useful and least reliable, but simplest to implement. 2. Testing that the YAML is valid TravisCI YAML. Unfortunately this is difficult / impossible. Doing 'travis lint' would succeed, this command does not check for 'script' key presence and wouldn't be useful for us. We could use 'travis-build' to verify that the YAML can be converted to a worker config, but as of now 'travis-build' doesn't work out of the box. There is a new tool for validating travis YAML files 'travis-yml', but as of now it's a ruby-only library and it's still a work in progress. 3. Running Travis CI task based on the generated YAML. This seems the best approach, however since cookiecutter-django itself uses Travis CI, that would require running Travis CI from within Travis CI. Scheduling Travis CI job without a github push still requires a public github repo, which is something that we can't generate on demand. Given that I'm opting to use approach 1. * Adds missing config to generated .travis.yml The keys added are as follows: 1. 'script' Required by Travis, cookiecutter-django used to provide it until it has been removed together with hitch. I'm assuming hitch has been replaced with pytest, I'm setting pytest as the new value for the 'script' key. 2. 'install' Not required by Travis, but necessary in our case; installs test libraries, mostly pytest. As of now this points to 'local.txt' requirements file. There used to be a separate 'test.txt' requirements file but it has been decided to merge it with 'local.txt', see discussion in https://github.com/pydanny/cookiecutter-django/pull/1557 . * Update CONTRIBUTORS.rst
2019-03-06 04:10:45 +03:00
except yaml.YAMLError as e:
pytest.fail(e)
@pytest.mark.parametrize("slug", ["project slug", "Project_Slug"])
def test_invalid_slug(cookies, context, slug):
"""Invalid slug should failed pre-generation hook."""
context.update({"project_slug": slug})
result = cookies.bake(extra_context=context)
assert result.exit_code != 0
assert isinstance(result.exception, FailedHookException)
def test_no_whitenoise_and_no_cloud_provider(cookies, context):
2019-10-02 18:06:53 +03:00
"""It should not generate project if neither whitenoise or cloud provider are set"""
context.update({"use_whitenoise": "n", "cloud_provider": "None"})
result = cookies.bake(extra_context=context)
assert result.exit_code != 0
assert isinstance(result.exception, FailedHookException)