pytest-cookies-0.4.0/0000755000175000017500000000000013507427602012605 5ustar hlehlepytest-cookies-0.4.0/tests/0000755000175000017500000000000013507427602013747 5ustar hlehlepytest-cookies-0.4.0/tests/conftest.py0000644000175000017500000000145613507427602016154 0ustar hlehle# -*- coding: utf-8 -*- import collections import json import pytest pytest_plugins = "pytester" @pytest.fixture(name="cookiecutter_template") def fixture_cookiecutter_template(tmpdir): template = tmpdir.ensure("cookiecutter-template", dir=True) template_config = collections.OrderedDict( [("repo_name", "foobar"), ("short_description", "Test Project")] ) template.join("cookiecutter.json").write(json.dumps(template_config)) template_readme = "\n".join( [ "{{cookiecutter.repo_name}}", "{% for _ in cookiecutter.repo_name %}={% endfor %}", "{{cookiecutter.short_description}}", ] ) repo = template.ensure("{{cookiecutter.repo_name}}", dir=True) repo.join("README.rst").write(template_readme) return template pytest-cookies-0.4.0/tests/test_help_message.py0000644000175000017500000000033413507427602020014 0ustar hlehle# -*- coding: utf-8 -*- def test_cookies_group(testdir): result = testdir.runpytest("--help") # fnmatch_lines does an assertion internally result.stdout.fnmatch_lines(["cookies:", "*--template=TEMPLATE*"]) pytest-cookies-0.4.0/tests/test_cookies.py0000644000175000017500000002501113507427602017013 0ustar hlehle# -*- coding: utf-8 -*- import json import pytest def test_cookies_fixture(testdir): """Make sure that pytest accepts the `cookies` fixture.""" # create a temporary pytest test module testdir.makepyfile( """ # -*- coding: utf-8 -*- def test_valid_fixture(cookies): assert hasattr(cookies, 'bake') assert callable(cookies.bake) """ ) # run pytest with the following cmd args result = testdir.runpytest("-v") # fnmatch_lines does an assertion internally result.stdout.fnmatch_lines(["*::test_valid_fixture PASSED*"]) # make sure that that we get a '0' exit code for the testsuite assert result.ret == 0 def test_cookies_bake_with_template_kwarg(testdir, cookiecutter_template): """bake accepts a template kwarg.""" testdir.makepyfile( """ # -*- coding: utf-8 -*- def test_bake_project(cookies): result = cookies.bake( extra_context={'repo_name': 'helloworld'}, template=r'%s', ) assert result.exit_code == 0 assert result.exception is None assert result.project.basename == 'helloworld' assert result.project.isdir() assert str(result) == ''.format(result.project) """ % cookiecutter_template ) # run pytest without the template cli arg result = testdir.runpytest("-v") result.stdout.fnmatch_lines(["*::test_bake_project PASSED*"]) def test_cookies_bake_template_kwarg_overrides_cli_option( testdir, cookiecutter_template ): """bake template kwarg overrides cli option.""" testdir.makepyfile( """ # -*- coding: utf-8 -*- def test_bake_project(cookies): result = cookies.bake( extra_context={'repo_name': 'helloworld'}, template=r'%s', ) assert result.exit_code == 0 assert result.exception is None assert result.project.basename == 'helloworld' assert result.project.isdir() assert str(result) == ''.format(result.project) """ % cookiecutter_template ) # run pytest with a bogus template name # it should use template directory passed to `cookies.bake` result = testdir.runpytest("-v", "--template=foobar") result.stdout.fnmatch_lines(["*::test_bake_project PASSED*"]) def test_cookies_bake(testdir, cookiecutter_template): """Programmatically create a **Cookiecutter** template and use `bake` to create a project from it. """ testdir.makepyfile( """ # -*- coding: utf-8 -*- def test_bake_project(cookies): result = cookies.bake(extra_context={'repo_name': 'helloworld'}) assert result.exit_code == 0 assert result.exception is None assert result.project.basename == 'helloworld' assert result.project.isdir() assert str(result) == ''.format(result.project) """ ) result = testdir.runpytest("-v", "--template={}".format(cookiecutter_template)) result.stdout.fnmatch_lines(["*::test_bake_project PASSED*"]) def test_cookies_bake_result_context(testdir, cookiecutter_template): """Programmatically create a **Cookiecutter** template and use `bake` to create a project from it. Check that the result holds the rendered context. """ testdir.makepyfile( """ # -*- coding: utf-8 -*- import collections def test_bake_project(cookies): result = cookies.bake(extra_context=collections.OrderedDict([ ('repo_name', 'cookies'), ('short_description', '{{cookiecutter.repo_name}} is awesome'), ])) assert result.exit_code == 0 assert result.exception is None assert result.project.basename == 'cookies' assert result.project.isdir() assert result.context == { 'repo_name': 'cookies', 'short_description': 'cookies is awesome', } assert str(result) == ''.format(result.project) """ ) result = testdir.runpytest("-v", "--template={}".format(cookiecutter_template)) result.stdout.fnmatch_lines(["*::test_bake_project PASSED*"]) def test_cookies_bake_result_context_exception(testdir, cookiecutter_template): """Programmatically create a **Cookiecutter** template and use `bake` to create a project from it. Check that exceptions resulting from rendering the context are stored on result and that the rendered context is not set. """ testdir.makepyfile( """ # -*- coding: utf-8 -*- import collections def test_bake_project(cookies): result = cookies.bake(extra_context=collections.OrderedDict([ ('repo_name', 'cookies'), ('short_description', '{{cookiecutter.nope}}'), ])) assert result.exit_code == -1 assert result.exception is not None assert result.project is None assert result.context is None assert str(result) == ''.format(result.exception) """ ) result = testdir.runpytest("-v", "--template={}".format(cookiecutter_template)) result.stdout.fnmatch_lines(["*::test_bake_project PASSED*"]) def test_cookies_bake_should_create_new_output_directories( testdir, cookiecutter_template ): """Programmatically create a **Cookiecutter** template and use `bake` to create a project from it. """ testdir.makepyfile( """ # -*- coding: utf-8 -*- def test_bake_should_create_new_output(cookies): first_result = cookies.bake() assert first_result.exception is None assert first_result.project.dirname.endswith('bake00') second_result = cookies.bake() assert second_result.exception is None assert second_result.project.dirname.endswith('bake01') """ ) result = testdir.runpytest("-v", "--template={}".format(cookiecutter_template)) result.stdout.fnmatch_lines(["*::test_bake_should_create_new_output PASSED*"]) def test_cookies_fixture_removes_output_directories(testdir, cookiecutter_template): """Programmatically create a **Cookiecutter** template and use `bake` to create a project from it. """ testdir.makepyfile( """ # -*- coding: utf-8 -*- import os def test_to_create_result(cookies): global result_dirname result = cookies.bake() result_dirname = result.project.dirname assert result.exception is None def test_previously_generated_directory_is_removed(cookies): exists = os.path.isdir(result_dirname) assert exists is False """ ) result = testdir.runpytest("-v", "--template={}".format(cookiecutter_template)) result.stdout.fnmatch_lines( [ "*::test_to_create_result PASSED*", "*::test_previously_generated_directory_is_removed PASSED*", ] ) def test_cookies_fixture_doesnt_remove_output_directories( testdir, cookiecutter_template ): """Programmatically create a **Cookiecutter** template and use `bake` to create a project from it. """ testdir.makepyfile( """ # -*- coding: utf-8 -*- import os def test_to_create_result(cookies): global result_dirname result = cookies.bake() result_dirname = result.project.dirname assert result.exception is None def test_previously_generated_directory_is_not_removed(cookies): exists = os.path.isdir(result_dirname) assert exists is True """ ) result = testdir.runpytest( "-v", "--template={}".format(cookiecutter_template), "--keep-baked-projects" ) result.stdout.fnmatch_lines( [ "*::test_to_create_result PASSED*", "*::test_previously_generated_directory_is_not_removed PASSED*", ] ) def test_cookies_bake_should_handle_exception(testdir): """Programmatically create a **Cookiecutter** template and make sure that cookies.bake() handles exceptions that happen during project generation. We expect **Cookiecutter** to raise a `NonTemplatedInputDirException`. """ template = testdir.tmpdir.ensure("cookiecutter-fail", dir=True) template_config = {"repo_name": "foobar", "short_description": "Test Project"} template.join("cookiecutter.json").write(json.dumps(template_config)) template.ensure("cookiecutter.repo_name", dir=True) testdir.makepyfile( """ # -*- coding: utf-8 -*- def test_bake_should_fail(cookies): result = cookies.bake() assert result.exit_code == -1 assert result.exception is not None assert result.project is None """ ) result = testdir.runpytest("-v", "--template={}".format(template)) result.stdout.fnmatch_lines(["*::test_bake_should_fail PASSED*"]) @pytest.mark.parametrize("choice", ["mkdocs", "sphinx", "none"]) def test_cookies_bake_choices(testdir, choice): """Programmatically create a **Cookiecutter** template and make sure that cookies.bake() works with choice variables. """ template = testdir.tmpdir.ensure("cookiecutter-choices", dir=True) template_config = {"repo_name": "docs", "docs_tool": ["mkdocs", "sphinx", "none"]} template.join("cookiecutter.json").write(json.dumps(template_config)) repo = template.ensure("{{cookiecutter.repo_name}}", dir=True) repo.join("README.rst").write("docs_tool: {{cookiecutter.docs_tool}}") testdir.makepyfile( """ # -*- coding: utf-8 -*- def test_bake_project(cookies): result = cookies.bake( extra_context={'docs_tool': '%s'}, template=r'%s', ) assert result.exit_code == 0 assert result.exception is None assert result.project.basename == 'docs' assert result.project.isdir() assert result.project.join('README.rst').read() == 'docs_tool: %s' assert str(result) == ''.format(result.project) """ % (choice, template, choice) ) # run pytest without the template cli arg result = testdir.runpytest("-v") result.stdout.fnmatch_lines(["*::test_bake_project PASSED*"]) result = testdir.runpytest("-v", "--template={}".format(template)) pytest-cookies-0.4.0/tests/test_user_config.py0000644000175000017500000000263013507427602017664 0ustar hlehle# -*- coding: utf-8 -*- def test_config(testdir): """Make sure that pytest accepts the `cookies` fixture.""" # create a temporary pytest test module testdir.makepyfile( """ # -*- coding: utf-8 -*- import poyo def test_user_dir(tmpdir_factory, _cookiecutter_config_file): basetemp = tmpdir_factory.getbasetemp() assert _cookiecutter_config_file.basename == 'config' user_dir = _cookiecutter_config_file.dirpath() assert user_dir.fnmatch('user_dir?') assert user_dir.dirpath() == basetemp def test_valid_cookiecutter_config(_cookiecutter_config_file): config_text = _cookiecutter_config_file.read() config = poyo.parse_string(config_text) user_dir = _cookiecutter_config_file.dirpath() expected = { 'cookiecutters_dir': str(user_dir.join('cookiecutters')), 'replay_dir': str(user_dir.join('cookiecutter_replay')), } assert config == expected """ ) # run pytest with the following cmd args result = testdir.runpytest("-v") # fnmatch_lines does an assertion internally result.stdout.fnmatch_lines( ["*::test_user_dir PASSED*", "*::test_valid_cookiecutter_config PASSED*"] ) # make sure that that we get a '0' exit code for the testsuite assert result.ret == 0 pytest-cookies-0.4.0/LICENSE0000644000175000017500000000207213507427602013613 0ustar hlehleThe MIT License (MIT) Copyright (c) 2015 Raphael Pierzina Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.pytest-cookies-0.4.0/COMMUNITY.md0000644000175000017500000000060713507427602014516 0ustar hlehle# Maintainers - [@hackebrot] - [@michaeljoseph] [@hackebrot]: https://github.com/hackebrot [@michaeljoseph]: https://github.com/michaeljoseph # Contributors - [@jakirkham] - [@jsmedmar] - [@obestwalter] - [@pydanny] [@jakirkham]: https://github.com/jakirkham [@jsmedmar]: https://github.com/jsmedmar [@obestwalter]: https://github.com/obestwalter [@pydanny]: https://github.com/pydanny pytest-cookies-0.4.0/README.md0000644000175000017500000001101613507427602014063 0ustar hlehle# pytest-cookies [pytest][pytest] is a mature testing framework for Python that is developed by a thriving and ever-growing community of volunteers. It uses plain assert statements and regular Python comparisons. At the core of the pytest test framework is a powerful hook-based plugin system. **pytest-cookies** is a pytest plugin that comes with a ``cookies`` fixture which is a wrapper for the [cookiecutter][cookiecutter] API for generating projects. It helps you verify that your template is working as expected and takes care of cleaning up after running the tests. 🍪 # Installation **pytest-cookies** is available for download from [PyPI][pypi] via [pip][pip]: ```text pip install pytest-cookies ``` This will automatically install [pytest][pytest] and [cookiecutter][cookiecutter]. # Usage ## Generate a new project The ``cookies.bake()`` method generates a new project from your template based on the default values specified in ``cookiecutter.json``: ```python def test_bake_project(cookies): result = cookies.bake(extra_context={"repo_name": "helloworld"}) assert result.exit_code == 0 assert result.exception is None assert result.project.basename == "helloworld" assert result.project.isdir() ``` The ``cookies.bake()`` method also accepts the ``extra_context`` keyword argument that will be passed to cookiecutter. The given dictionary will override the default values of the template context, effectively allowing you to test arbitrary user input data. For more information on injecting extra context, please check out the [cookiecutter documentation][extra-context]. ## Specify the template directory By default ``cookies.bake()`` looks for a cookiecutter template in the current directory. This can be overridden on the command line by passing a ``--template`` parameter to pytest: ```text pytest --template TEMPLATE ``` You can customize the cookiecutter template directory from a test by passing in the optional ``template`` paramter: ```python @pytest.fixture def custom_template(tmpdir): template = tmpdir.ensure("cookiecutter-template", dir=True) template.join("cookiecutter.json").write('{"repo_name": "example-project"}') repo_dir = template.ensure("{{cookiecutter.repo_name}}", dir=True) repo_dir.join("README.rst").write("{{cookiecutter.repo_name}}") return template def test_bake_custom_project(cookies, custom_template): """Test for 'cookiecutter-template'.""" result = cookies.bake(template=str(custom_template)) assert result.exit_code == 0 assert result.exception is None assert result.project.basename == "example-project" assert result.project.isdir() ``` ## Keep output directories for debugging By default ``cookies`` removes baked projects. However, you can pass the ``keep-baked-projects`` flag if you'd like to keep them ([it won't clutter][temporary-directories] as pytest only keeps the three newest temporary directories): ```text pytest --keep-baked-projects ``` # Community Contributions are very welcome! If you encounter any problems, please [file an issue][new-issue] along with a detailed description. Tests can be run with [tox][tox]. Please make sure all of the tests are green before you submit a pull request. You can also support the development of this project by volunteering to become a maintainer, which means you will be able to triage issues, merge pull-requests, and publish new releases. If you're interested, please submit a pull-request to add yourself to the list of [maintainers][community] and we'll get you started! 🍪 Please note that **pytest-cookies** is released with a [Contributor Code of Conduct][code-of-conduct]. By participating in this project you agree to abide by its terms. # License Distributed under the terms of the [MIT license][license], **pytest-cookies** is free and open source software. [cookiecutter]: https://github.com/audreyr/cookiecutter [pytest]: https://github.com/pytest-dev/pytest [pip]: https://pypi.org/project/pip/ [pypi]: https://pypi.org/project/pytest-cookies/ [extra-context]: https://cookiecutter.readthedocs.io/en/latest/advanced/injecting_context.html [temporary-directories]: https://docs.pytest.org/en/latest/tmpdir.html#the-default-base-temporary-directory [tox]: https://pypi.org/project/tox/ [new-issue]: https://github.com/hackebrot/pytest-cookies/issues [code-of-conduct]: https://github.com/hackebrot/pytest-cookies/blob/master/CODE_OF_CONDUCT.md [community]: https://github.com/hackebrot/pytest-cookies/blob/master/COMMUNITY.md [license]: https://github.com/hackebrot/pytest-cookies/blob/master/LICENSE pytest-cookies-0.4.0/CODE_OF_CONDUCT.md0000644000175000017500000000643013507427602015407 0ustar hlehle# Contributor Covenant Code of Conduct ## Our Pledge In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation. ## Our Standards Examples of behavior that contributes to creating a positive environment include: * Using welcoming and inclusive language * Being respectful of differing viewpoints and experiences * Gracefully accepting constructive criticism * Focusing on what is best for the community * Showing empathy towards other community members Examples of unacceptable behavior by participants include: * The use of sexualized language or imagery and unwelcome sexual attention or advances * Trolling, insulting/derogatory comments, and personal or political attacks * Public or private harassment * Publishing others' private information, such as a physical or electronic address, without explicit permission * Other conduct which could reasonably be considered inappropriate in a professional setting ## Our Responsibilities Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. ## Scope This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. ## Enforcement Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at raphael@hackebrot.de. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. ## Attribution This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html [homepage]: https://www.contributor-covenant.org For answers to common questions about this code of conduct, see https://www.contributor-covenant.org/faq pytest-cookies-0.4.0/.gitignore0000644000175000017500000000230613507427602014576 0ustar hlehle# Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] *$py.class # C extensions *.so # Distribution / packaging .Python build/ develop-eggs/ dist/ downloads/ eggs/ .eggs/ lib/ lib64/ parts/ sdist/ var/ wheels/ *.egg-info/ .installed.cfg *.egg MANIFEST # PyInstaller # Usually these files are written by a python script from a template # before PyInstaller builds the exe, so as to inject date/other infos into it. *.manifest *.spec # Installer logs pip-log.txt pip-delete-this-directory.txt # Unit test / coverage reports htmlcov/ .tox/ .coverage .coverage.* .cache nosetests.xml coverage.xml *.cover .hypothesis/ .pytest_cache/ # Translations *.mo *.pot # Django stuff: *.log local_settings.py db.sqlite3 # Flask stuff: instance/ .webassets-cache # Scrapy stuff: .scrapy # Sphinx documentation docs/_build/ # PyBuilder target/ # Jupyter Notebook .ipynb_checkpoints # pyenv .python-version # celery beat schedule file celerybeat-schedule # SageMath parsed files *.sage.py # Environments .env .venv env/ venv/ ENV/ env.bak/ venv.bak/ # Spyder project settings .spyderproject .spyproject # Rope project settings .ropeproject # mkdocs documentation /site # mypy .mypy_cache/ # VS Code .vscode pytest-cookies-0.4.0/appveyor.yml0000644000175000017500000000024713507427602015200 0ustar hlehleenvironment: matrix: - TOXENV: py27 - TOXENV: py34 - TOXENV: py35 - TOXENV: py36 - TOXENV: py37 build: off install: - pip install tox test_script: - toxpytest-cookies-0.4.0/mkdocs.yml0000644000175000017500000000046513507427602014615 0ustar hlehlesite_name: pytest-cookies site_description: The pytest plugin for your Cookiecutter templates 🍪 site_author: Raphael Pierzina theme: readthedocs repo_url: https://github.com/hackebrot/pytest-cookies pages: - Home: index.md - Getting Started: getting_started.md - Features: features.md - About: about.md pytest-cookies-0.4.0/.travis.yml0000644000175000017500000000071713507427602014723 0ustar hlehledist: xenial language: python cache: directories: - $HOME/.cache/pip matrix: include: - python: 2.7 env: TOXENV=py27 - python: 3.4 env: TOXENV=py34 - python: 3.5 env: TOXENV=py35 - python: 3.6 env: TOXENV=py36 - python: 3.7 env: TOXENV=py37 - python: pypy env: TOXENV=pypy - python: 3.7 env: TOXENV=flake8 install: - pip install tox script: - tox pytest-cookies-0.4.0/docs/0000755000175000017500000000000013507427602013535 5ustar hlehlepytest-cookies-0.4.0/docs/features.md0000644000175000017500000000157013507427602015700 0ustar hlehle# Bake Result ``cookies.bake()`` returns a result instance with a bunch of fields that hold useful information: * ``exit_code``: is the exit code of cookiecutter, ``0`` means successful termination * ``exception``: is the exception that happened if one did * ``project``: a [py.path.local] object pointing to the rendered project * ``context``: is the rendered context The returned ``LocalPath`` instance provides you with a powerful interface to filesystem related information, that comes in handy for validating the generated project layout and even file contents: ```python def test_readme(cookies): result = cookies.bake() readme_file = result.project.join('README.rst') readme_lines = readme_file.readlines(cr=False) assert readme_lines == ['helloworld', '=========='] ``` [py.path.local]: https://py.readthedocs.io/en/latest/path.html#py._path.local.LocalPath pytest-cookies-0.4.0/docs/getting_started.md0000644000175000017500000000232613507427602017251 0ustar hlehle# Installation **pytest-cookies** is available for download from [PyPI] via [pip]: ```no-highlight $ pip install pytest-cookies ``` It will automatically install [pytest] along with [cookiecutter]. [PyPI]: https://pypi.python.org/pypi [cookiecutter]: https://github.com/audreyr/cookiecutter [pip]: https://pypi.python.org/pypi/pip/ [pytest]: https://github.com/pytest-dev/pytest # Usage The ``cookies.bake()`` method generates a new project from your template based on the default values specified in ``cookiecutter.json``: ```python def test_bake_project(cookies): result = cookies.bake(extra_context={'repo_name': 'helloworld'}) assert result.exit_code == 0 assert result.exception is None assert result.project.basename == 'helloworld' assert result.project.isdir() ``` It accepts the ``extra_context`` keyword argument that will be passed to cookiecutter. The given dictionary will override the default values of the template context, allowing you to test arbitrary user input data. Please see the [Injecting Extra Context] section of the official cookiecutter documentation. [Injecting Extra Context]: http://cookiecutter.readthedocs.org/en/latest/advanced_usage.html#injecting-extra-context pytest-cookies-0.4.0/docs/about.md0000644000175000017500000000137313507427602015175 0ustar hlehle# Issues If you encounter any problems, please [file an issue] along with a detailed description. # Community Contributions are very welcome! Tests can be run with [tox], please make sure all of the tests are green before you submit a pull request. Please note that **pytest-cookies** is released with a [Contributor Code of Conduct][coc]. By participating in this project you agree to abide by its terms. # License Distributed under the terms of the [MIT] license, **pytest-cookies** is free and open source software [file an issue]: https://github.com/hackebrot/pytest-cookies/issues [tox]: https://tox.readthedocs.org/en/latest/ [coc]: https://github.com/hackebrot/pytest-cookies/blob/master/CODE_OF_CONDUCT.md [MIT]: http://opensource.org/licenses/MIT pytest-cookies-0.4.0/docs/index.md0000644000175000017500000000303013507427602015162 0ustar hlehle# Welcome to Pytest-Cookies [![Join Chat on Gitter.im][gitter_badge]][gitter] [pytest] is a mature full-featured Python testing tool that provides easy no boilerplate testing. Its hook-based customization system supports integration of external plugins such as **pytest-cookies**. This plugin comes with a ``cookies`` fixture which is a wrapper for the [cookiecutter] API for generating projects. It helps you verify that your template is working as expected and takes care of cleaning up after running the tests. ## GitHub Project [https://github.com/hackebrot/pytest-cookies](https://github.com/hackebrot/pytest-cookies) ![Cookiecutter Logo](https://raw.github.com/audreyr/cookiecutter/aa309b73bdc974788ba265d843a65bb94c2e608e/cookiecutter_medium.png) [gitter_badge]: https://badges.gitter.im/Join%20Chat.svg [gitter]: https://gitter.im/hackebrot/pytest-cookies?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge [travis_badge]: https://travis-ci.org/hackebrot/pytest-cookies.svg?branch=master [travis]: https://travis-ci.org/hackebrot/pytest-cookies [appveyor_badge]: https://ci.appveyor.com/api/projects/status/github/hackebrot/pytest-cookies?branch=master [appveyor]: https://ci.appveyor.com/project/hackebrot/pytest-cookies/branch/master [docs_badge]: https://readthedocs.org/projects/pytest-cookies/badge/?version=latest [documentation]: http://pytest-cookies.readthedocs.org/en/latest/?badge=latest [pytest]: https://github.com/pytest-dev/pytest [cookiecutter]: https://github.com/audreyr/cookiecutter pytest-cookies-0.4.0/MANIFEST.in0000644000175000017500000000021513507427602014341 0ustar hlehleinclude COMMUNITY.md include CONTRIBUTING.md include LICENSE include README.md recursive-exclude * __pycache__ recursive-exclude * *.py[co] pytest-cookies-0.4.0/setup.py0000644000175000017500000000375013507427602014324 0ustar hlehle#!/usr/bin/env python # -*- coding: utf-8 -*- import codecs import os import setuptools def read(fname): file_path = os.path.join(os.path.dirname(__file__), fname) return codecs.open(file_path, encoding="utf-8").read() setuptools.setup( name="pytest-cookies", version="0.4.0", author="Raphael Pierzina", author_email="raphael@hackebrot.de", maintainer="Raphael Pierzina", maintainer_email="raphael@hackebrot.de", license="MIT", url="https://github.com/hackebrot/pytest-cookies", project_urls={ "Repository": "https://github.com/hackebrot/pytest-cookies", "Issues": "https://github.com/hackebrot/pytest-cookies/issues", }, description="The pytest plugin for your Cookiecutter templates 🍪", long_description=read("README.md"), long_description_content_type="text/markdown", packages=setuptools.find_packages("src"), package_dir={"": "src"}, include_package_data=True, zip_safe=False, python_requires=">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*", install_requires=[ "arrow<0.14.0", "cookiecutter>=1.4.0,<=1.6.0", "pytest>=3.3.0,<5.0.0", ], classifiers=[ "Development Status :: 4 - Beta", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python", "Topic :: Software Development :: Testing", "Framework :: Pytest", ], entry_points={"pytest11": ["cookies = pytest_cookies.plugin"]}, keywords=["cookiecutter", "pytest"], ) pytest-cookies-0.4.0/CONTRIBUTING.md0000644000175000017500000001410213507427602015034 0ustar hlehle# Contributing Contributions are welcome, and they are greatly appreciated! Every little bit helps, and credit will always be given. You can contribute in many ways: ## Types of Contributions ### Report Bugs Report bugs at [pytest-cookies/issues][issues]. If you are reporting a bug, please include: * Your operating system name and version. * Any details about your local setup that might be helpful in troubleshooting. * Detailed steps to reproduce the bug. [issues]: https://github.com/hackebrot/pytest-cookies/issues ### Fix Bugs Look through the GitHub issues for bugs. Anything tagged with [bug][bug] and [help wanted][help wanted] is open to whoever wants to implement a fix for it. [help wanted]: https://github.com/hackebrot/pytest-cookies/labels/help%20wanted [bug]: https://github.com/hackebrot/pytest-cookies/labels/bug ### Implement Features Look through the GitHub issues for features. Anything tagged with [enhancement][enhancement] and [help wanted][help wanted] is open to whoever wants to implement it. [enhancement]: https://github.com/hackebrot/pytest-cookies/labels/enhancement [help wanted]: https://github.com/hackebrot/pytest-cookies/labels/help%20wanted ### Write Documentation **pytest-cookies** could always use more documentation, whether as part of the official docs, in docstrings, or even on the web in blog posts, articles, and such. ### Submit Feedback The best way to send feedback is to [file an issue][issues]. If you are proposing a new feature: * Explain in detail how it would work. * Keep the scope as narrow as possible, to make it easier to implement. * Remember that this is a volunteer-driven project, and that contributions are welcome :) [issues]: https://github.com/hackebrot/pytest-cookies/issues ## Get Started! Ready to contribute? Here's how to set up **pytest-cookies** for local development. Please note this documentation assumes you already have [virtualenv][virtualenv] and [git][git] installed and ready to go. 1. [Fork][fork] the **pytest-cookies** repo on GitHub. 2. Clone your fork locally: ```bash $ git clone https://github.com/YOUR-USERNAME/pytest-cookies ``` 3. Assuming you have virtualenv installed (If you have Python3.5 this should already be there), you can create a new environment for your local development by typing: ``` bash $ python -m venv pytest-cookies-env $ source pytest-cookies-env/bin/activate ``` This should change the shell to look something like ``(pytest-cookies-env) $`` 4. Create a branch for local development: ``` bash $ git checkout -b name-of-your-bugfix-or-feature ``` 5. Now you can make your changes locally.When you're done making changes, use [tox][tox] to run checks against your changes. Install it as follows: ``` bash $ pip install tox ``` 6. First you want to make sure that your branch passes [flake8][flake8]. ``` bash $ tox -e flake8 ``` 7. The next step would be to run the tests against your environment (the special tox environment ``py`` refers to the currently active python environment): ``` bash $ tox -e py ``` 8. Before raising any pull request you should run tox. This will run the tests across different versions of Python: ``` bash $ tox ``` 9. If your contribution is a bug fix or new feature, you may want to add a test to the existing test suite. See section *Add a New Test* below for details. 10. Commit your changes and push your branch to GitHub: ``` bash $ git add . $ git commit -m "Your detailed description of your changes." $ git push origin name-of-your-bugfix-or-feature ``` 11. Submit a pull request through the GitHub website. [clone]: https://help.github.com/articles/fork-a-repo/#step-2-create-a-local-clone-of-your-fork [flake8]: https://pypi.python.org/pypi/flake8 [fork]: https://help.github.com/articles/fork-a-repo/ [git]: https://git-scm.com/book/en/v2/Getting-Started-Installing-Git [tox]: https://pypi.python.org/pypi/tox [virtualenv]: https://virtualenv.pypa.io/en/stable/installation Pull Request Guidelines ----------------------- Before you submit a pull request, check that it meets these guidelines: 1. The pull request should include tests. 2. If the pull request adds functionality, the docs should be updated. Put your new functionality into a function with a docstring, and add the feature to the list in README.md. 3. The pull request should work for Python 2.7, 3.4 and 3.5, and for PyPy. Check [travis pull requests][travis] and make sure that the tests pass for all supported Python versions. [travis]: https://travis-ci.org/hackebrot/pytest-cookies/pull_requests Add a New Test --------------- When fixing a bug or adding features, it's good practice to add a test to demonstrate your fix or new feature behaves as expected. These tests should focus on one tiny bit of functionality and prove changes are correct. To write and run your new test, follow these steps: 1. Add the new test to ``tests/test_.py``. Focus your test on the specific bug or a small part of the new feature. 2. If you have already made changes to the code, stash your changes and confirm all your changes were stashed: ``` bash $ git stash $ git stash list ``` 3. Run your test and confirm that your test fails. If your test does not fail, rewrite the test until it fails on the original code: ``` bash $ tox -e py ``` 4. (Optional) Run the tests with tox to ensure that the code changes work with different Python versions: ``` bash $ tox ``` 5. Proceed work on your bug fix or new feature or restore your changes. To restore your stashed changes and confirm their restoration: ``` bash $ git stash pop $ git stash list ``` 6. Rerun your test and confirm that your test passes. If it passes, congratulations! [bug]: https://github.com/hackebrot/pytest-cookies/labels/bug [enhancement]: https://github.com/hackebrot/pytest-cookies/labels/enhancement [help wanted]: https://github.com/hackebrot/pytest-cookies/labels/help%20wanted [issues]: https://github.com/hackebrot/pytest-cookies/issues pytest-cookies-0.4.0/setup.cfg0000644000175000017500000000031113507427602014421 0ustar hlehle[bumpversion] current_version = 0.4.0 commit = True tag = True tag_name = {new_version} files = setup.py [bdist_wheel] universal = 1 [metadata] license_file = LICENSE [flake8] max-line-length = 88 pytest-cookies-0.4.0/Makefile0000644000175000017500000000153013507427602014244 0ustar hlehle.DEFAULT_GOAL := help .PHONY: clean clean: clean-tox clean-build clean-pyc ## Remove all file artifacts .PHONY: clean-tox clean-tox: ## Remove tox testing artifacts @echo "+ $@" @rm -rf .tox/ .PHONY: clean-build clean-build: ## Remove build artifacts @echo "+ $@" @rm -fr build/ @rm -fr dist/ @rm -fr *.egg-info .PHONY: clean-pyc clean-pyc: ## Remove Python file artifacts @echo "+ $@" @find . -type f -name "*.py[co]" -delete @find . -type d -name "__pycache__" -delete @find . -name '*~' -delete .PHONY: test test: ## Run tests quickly with the default Python @echo "+ $@" @tox -e py .PHONY: test-all test-all: ## Run tests on every Python version with tox @echo "+ $@" @tox .PHONY: help help: @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-16s\033[0m %s\n", $$1, $$2}' pytest-cookies-0.4.0/tox.ini0000644000175000017500000000030513507427602014116 0ustar hlehle[tox] envlist = py27,py34,py35,py36,py37,pypy,flake8 [testenv] download = true deps = pytest commands = pytest {posargs:tests} [testenv:flake8] deps = flake8 commands = flake8 setup.py src tests pytest-cookies-0.4.0/src/0000755000175000017500000000000013507427602013374 5ustar hlehlepytest-cookies-0.4.0/src/pytest_cookies/0000755000175000017500000000000013507427602016440 5ustar hlehlepytest-cookies-0.4.0/src/pytest_cookies/plugin.py0000644000175000017500000001044113507427602020310 0ustar hlehle# -*- coding: utf-8 -*- import py import pytest from cookiecutter.main import cookiecutter from cookiecutter.generate import generate_context from cookiecutter.prompt import prompt_for_config USER_CONFIG = u""" cookiecutters_dir: "{cookiecutters_dir}" replay_dir: "{replay_dir}" """ class Result(object): """Holds the captured result of the cookiecutter project generation.""" def __init__(self, exception=None, exit_code=0, project_dir=None, context=None): self.exception = exception self.exit_code = exit_code self.context = context self._project_dir = project_dir @property def project(self): if self.exception is None: return py.path.local(self._project_dir) return None def __repr__(self): if self.exception: return "".format(self.exception) return "".format(self.project) class Cookies(object): """Class to provide convenient access to the cookiecutter API.""" def __init__(self, template, output_factory, config_file): self._default_template = template self._output_factory = output_factory self._config_file = config_file self._counter = 0 def _new_output_dir(self): dirname = "bake{:02d}".format(self._counter) output_dir = self._output_factory(dirname) self._counter += 1 return output_dir def bake(self, extra_context=None, template=None): exception = None exit_code = 0 project_dir = None context = None if template is None: template = self._default_template context_file = py.path.local(template).join("cookiecutter.json") try: # Render the context, so that we can store it on the Result context = prompt_for_config( generate_context( context_file=str(context_file), extra_context=extra_context ), no_input=True, ) # Run cookiecutter to generate a new project project_dir = cookiecutter( template, no_input=True, extra_context=extra_context, output_dir=str(self._new_output_dir()), config_file=str(self._config_file), ) except SystemExit as e: if e.code != 0: exception = e exit_code = e.code except Exception as e: exception = e exit_code = -1 return Result( exception=exception, exit_code=exit_code, project_dir=project_dir, context=context, ) @pytest.fixture(scope="session") def _cookiecutter_config_file(tmpdir_factory): user_dir = tmpdir_factory.mktemp("user_dir") cookiecutters_dir = user_dir.mkdir("cookiecutters") replay_dir = user_dir.mkdir("cookiecutter_replay") config_text = USER_CONFIG.format( cookiecutters_dir=cookiecutters_dir, replay_dir=replay_dir ) config_file = user_dir.join("config") config_file.write_text(config_text, encoding="utf8") return config_file @pytest.yield_fixture def cookies(request, tmpdir, _cookiecutter_config_file): """Yield an instance of the Cookies helper class that can be used to generate a project from a template. Run cookiecutter: result = cookies.bake(extra_context={ 'variable1': 'value1', 'variable2': 'value2', }) """ template_dir = request.config.option.template output_dir = tmpdir.mkdir("cookies") output_factory = output_dir.mkdir yield Cookies(template_dir, output_factory, _cookiecutter_config_file) # Add option to keep generated output directories. if not request.config.option.keep_baked_projects: output_dir.remove() def pytest_addoption(parser): group = parser.getgroup("cookies") group.addoption( "--template", action="store", default=".", dest="template", help="specify the template to be rendered", type="string", ) group.addoption( "--keep-baked-projects", action="store_true", default=False, dest="keep_baked_projects", help="Keep projects directories generated with 'cookies.bake()'.", ) pytest-cookies-0.4.0/src/pytest_cookies/__init__.py0000644000175000017500000000000013507427602020537 0ustar hlehle