diff --git a/tests/test_bake_django.py b/tests/test_bake_django.py index 27d40994..004ba4d6 100644 --- a/tests/test_bake_django.py +++ b/tests/test_bake_django.py @@ -833,6 +833,20 @@ def test_baked_django_settings_test_file_ok(cookies): assert 'ALLOWED_HOSTS = [""]' in settings_file +def test_baked_django_tox_file_ok(cookies): + """Test Django tox.ini file has been generated correctly.""" + default_django = cookies.bake() + + tox_path = default_django.project_path / "tox.ini" + tox_file = str(tox_path.read_text().splitlines()) + + assert ( + ' find {toxinidir}/django_boilerplate -type f -name "*.pyc" -delete' + in tox_file + ) + assert 'mypy --ignore-missing-imports {toxinidir}/django_boilerplate' in tox_file + + def test_baked_django_urls_file_ok(cookies): """Test Django urls.py file has generated correctly.""" default_django = cookies.bake() diff --git a/{{cookiecutter.git_project_name}}/.gitignore b/{{cookiecutter.git_project_name}}/.gitignore index e9b207cf..aebfbbdb 100644 --- a/{{cookiecutter.git_project_name}}/.gitignore +++ b/{{cookiecutter.git_project_name}}/.gitignore @@ -1,3 +1,6 @@ +# Project Folders +coverage_html_report/ + # vscode *code-workspace .vscode/ diff --git a/{{cookiecutter.git_project_name}}/config/requirements/test.txt b/{{cookiecutter.git_project_name}}/config/requirements/test.txt index 09cfee90..a0158fda 100644 --- a/{{cookiecutter.git_project_name}}/config/requirements/test.txt +++ b/{{cookiecutter.git_project_name}}/config/requirements/test.txt @@ -1,5 +1,7 @@ +coverage==6.2 dj-inmemorystorage==2.1.0 -psycopg2==2.9.3 +psycopg2==2.9.3 # This version should be used in production +#psycopg2-binary # This version is ok for Development and Testing pytest==6.2.5 pytest-django==4.5.2 pytest-reverse==1.3.0 diff --git a/{{cookiecutter.git_project_name}}/setup.cfg b/{{cookiecutter.git_project_name}}/setup.cfg new file mode 100644 index 00000000..c30b61bb --- /dev/null +++ b/{{cookiecutter.git_project_name}}/setup.cfg @@ -0,0 +1,19 @@ +[metadata] +license_file = LICENSE +description-file = README.rst + +[coverage:run] +source= + users +omit = + */migrations/* + +[coverage:report] +fail_under = 100 +exclude_lines = + pragma: no cover + def __str__ + raise NotImplementedError + +[coverage:html] +directory = coverage_html_report diff --git a/{{cookiecutter.git_project_name}}/tox.ini b/{{cookiecutter.git_project_name}}/tox.ini index cf7f361a..5b23c262 100644 --- a/{{cookiecutter.git_project_name}}/tox.ini +++ b/{{cookiecutter.git_project_name}}/tox.ini @@ -2,25 +2,45 @@ skipsdist = true skip_missing_interpreters = true envlist = + py38 pypy + py38-mypy + p39-docs py38 py39 py3.10 - py38 pypy - py39-docs + +; This block of commands finds and removes packaging artifacts at the end of +; every test run +; See https://www.b-list.org/weblog/2020/feb/03/how-im-testing-2020/ +[cleanup] +commands = + find {toxinidir}/tests -type f -name "*.pyc" -delete + find {toxinidir}/tests -type d -name "__pycache__" -delete + find {toxinidir}/{{cookiecutter.project_slug}} -type f -name "*.pyc" -delete + find {toxinidir}/{{cookiecutter.project_slug}} -type d -name "__pycache__" -delete + find {toxinidir}/{{cookiecutter.project_slug}} -type f -path "*.egg-info*" -delete + find {toxinidir}/{{cookiecutter.project_slug}} -type d -path "*.egg-info" -delete + +[pipupgrade] +commands = + {envpython} -m pip install --upgrade pip {% if cookiecutter.include_sphinx_docs == "y" %} [testenv:docs] basepython=python changedir=docs/source -deps= -r{toxinidir}/docs/requirements.txt -commands= - sphinx-build -b html -d {envtmpdir}/doctrees . {envtmpdir}/html +commands = + {[pipupgrade]commands} + sphinx-build -b html -d {envtmpdir}/doctrees . {envtmpdir}/html + {[cleanup]commands} +deps = -r{toxinidir}/docs/requirements.txt {% endif %} [gh-actions] python = pypy-3.8: pypy3 - 3.10: py3.10 - 3.9: py39 + py38-mypy: mypy3 3.8: py38 + 3.9: py39 + 3.10: py3.10 [gh-actions:env] PLATFORM = @@ -28,15 +48,34 @@ PLATFORM = macos-latest: macos windows-latest: windows +[testenv:mypy] +basepython = python +changedir = {toxinidir} +deps = mypy +commands = + {[pipupgrade]commands} + mypy --ignore-missing-imports {toxinidir}/{{cookiecutter.project_slug}} + mypy --ignore-missing-imports {toxinidir}/users + {[cleanup]commands} + [testenv] +whitelist_externals = + find + rm + tests setenv = PYTHONPATH = {toxinidir} + PYTHONWARNINGS=once::DeprecationWarning deps = -r{toxinidir}/requirements_dev.txt commands = # -rP prints stdout to the terminal # -v prints a verbose pytest output to the terminal - pytest -rP -v {posargs:tests} + {[pipupgrade]commands} + coverage run {posargs:-m pytest tests -rP -v} + coverage report -m + coverage html + {[cleanup]commands} [pydocstyle] ignore = D213 diff --git a/{{cookiecutter.git_project_name}}/users/models.py b/{{cookiecutter.git_project_name}}/users/models.py index 37eb3ef4..a792bae0 100644 --- a/{{cookiecutter.git_project_name}}/users/models.py +++ b/{{cookiecutter.git_project_name}}/users/models.py @@ -10,7 +10,10 @@ class CustomUserManager(BaseUserManager): """Custom user manager.""" - def create_user(self, email=None, password=None, **extra_fields): + def create_user( + self, email=None, password=None, **extra_fields + ): # pragma: no cover + """Create and save a User.""" """Create and save a User.""" if not email: raise ValueError(_("An email address must be supplied.")) @@ -22,7 +25,10 @@ def create_user(self, email=None, password=None, **extra_fields): user.save() return user - def create_superuser(self, email=None, password=None, **extra_fields): + def create_superuser( + self, email=None, password=None, **extra_fields + ): # pragma: no cover + """Create and save a User.""" """Create and save a SuperUser.""" extra_fields.setdefault("is_staff", True) extra_fields.setdefault("is_superuser", True)