mirror of
				https://github.com/cookiecutter/cookiecutter-django.git
				synced 2025-10-31 16:07:49 +03:00 
			
		
		
		
	Merge pull request #402 from hackebrot/use-tox-and-pytest-cookies
Use tox and pytest cookies
This commit is contained in:
		
						commit
						cb8376ce2a
					
				
							
								
								
									
										5
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							|  | @ -33,3 +33,8 @@ my_test_project/* | |||
| 
 | ||||
| # Generated when running py.test for the cookiecutter-django generation tests | ||||
| .cache/ | ||||
| 
 | ||||
| # Unit test / coverage reports | ||||
| .coverage | ||||
| .tox | ||||
| .cache | ||||
|  |  | |||
							
								
								
									
										23
									
								
								.travis.yml
									
									
									
									
									
								
							
							
						
						
									
										23
									
								
								.travis.yml
									
									
									
									
									
								
							|  | @ -1,14 +1,17 @@ | |||
| language: python | ||||
| python: | ||||
|   - 3.5 | ||||
|   - 3.4 | ||||
|   - 2.7 | ||||
| sudo: false | ||||
| install: | ||||
| - pip install -r requirements.txt | ||||
| # Config file for automatic testing at travis-ci.org | ||||
| 
 | ||||
| script: | ||||
|   - py.test | ||||
| sudo: false | ||||
| language: python | ||||
| python: 3.5 | ||||
| env: | ||||
|     - TOX_ENV=py27 | ||||
|     - TOX_ENV=py34 | ||||
|     - TOX_ENV=py35 | ||||
| 
 | ||||
| script: tox -e $TOX_ENV | ||||
| 
 | ||||
| install: | ||||
|     - pip install tox | ||||
| 
 | ||||
| notifications: | ||||
|   email: | ||||
|  |  | |||
|  | @ -9,3 +9,48 @@ Getting your pull request merged in | |||
| #. Keep it small. The smaller the pull request the more likely I'll pull it in. | ||||
| #. Pull requests that fix a current issue get priority for review. | ||||
| #. If you're not already in the `CONTRIBUTORS.rst` file, add yourself! | ||||
| 
 | ||||
| Testing | ||||
| ------- | ||||
| 
 | ||||
| Installation | ||||
| ~~~~~~~~~~~~ | ||||
| 
 | ||||
| Please install `tox`_, which is a generic virtualenv management and test command line tool. | ||||
| 
 | ||||
| `tox`_ is available for download from `PyPI`_ via `pip`_:: | ||||
| 
 | ||||
|     $ pip install tox | ||||
| 
 | ||||
| It will automatically create a fresh virtual environment and install our test dependencies, | ||||
| such as `pytest-cookies`_ and `flake8`_. | ||||
| 
 | ||||
| Run the Tests | ||||
| ~~~~~~~~~~~~~ | ||||
| 
 | ||||
| Tox uses py.test under the hood, hence it supports the same syntax for selecting tests. | ||||
| 
 | ||||
| For further information please consult the `pytest usage docs`_. | ||||
| 
 | ||||
| To run all tests using various versions of python in virtualenvs defined in tox.ini, just run tox.:: | ||||
| 
 | ||||
|     $ tox | ||||
| 
 | ||||
| It is possible to tests with some versions of python, to do this the command | ||||
| is:: | ||||
| 
 | ||||
|     $ tox -e py27,py34 | ||||
| 
 | ||||
| Will run py.test with the python2.7, and python3.4 interpreters, for | ||||
| example. | ||||
| 
 | ||||
| To run a particular test with tox for against your current Python version:: | ||||
| 
 | ||||
|     $ tox -e py -- -k test_default_configuration | ||||
| 
 | ||||
| .. _`pytest usage docs`: https://pytest.org/latest/usage.html#specifying-tests-selecting-tests | ||||
| .. _`tox`: https://tox.readthedocs.org/en/latest/ | ||||
| .. _`pip`: https://pypi.python.org/pypi/pip/ | ||||
| .. _`pytest-cookies`: https://pypi.python.org/pypi/pytest-cookies/ | ||||
| .. _`flake8`: https://pypi.python.org/pypi/flake8/ | ||||
| .. _`PyPI`: https://pypi.python.org/pypi | ||||
|  |  | |||
|  | @ -14,3 +14,4 @@ pytest==2.8.2 | |||
| git+git://github.com/mverteuil/pytest-ipdb.git | ||||
| pep8==1.6.2 | ||||
| pyflakes==1.0.0 | ||||
| tox==2.1.1 | ||||
|  |  | |||
|  | @ -1,71 +0,0 @@ | |||
| import os | ||||
| import re | ||||
| import shutil | ||||
| import unittest | ||||
| from os.path import exists, dirname, join | ||||
| 
 | ||||
| from binaryornot.check import is_binary | ||||
| import sh | ||||
| 
 | ||||
| from cookiecutter.main import cookiecutter | ||||
| 
 | ||||
| 
 | ||||
| class DjangoCookieTestCase(unittest.TestCase): | ||||
| 
 | ||||
|     root_dir = dirname(dirname(__file__)) | ||||
|     ctx = {} | ||||
|     destpath = None | ||||
| 
 | ||||
|     def check_paths(self, paths): | ||||
|         """ | ||||
|         Method to check all paths have correct substitutions, | ||||
|         used by other tests cases | ||||
|         """ | ||||
|         # Construct the cookiecutter search pattern | ||||
|         pattern = "{{(\s?cookiecutter)[.](.*?)}}" | ||||
|         re_obj = re.compile(pattern) | ||||
| 
 | ||||
|         # Assert that no match is found in any of the files | ||||
|         for path in paths: | ||||
|             if not is_binary(path): | ||||
|                 for line in open(path, 'r'): | ||||
|                     match = re_obj.search(line) | ||||
|                     self.assertIsNone( | ||||
|                         match, | ||||
|                         "cookiecutter variable not replaced in {}".format(path)) | ||||
| 
 | ||||
|     def generate_project(self, extra_context=None): | ||||
|         ctx = { | ||||
|             "project_name": "My Test Project", | ||||
|             "repo_name": "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", | ||||
|             "now": "2015/01/13", | ||||
|             "year": "2015" | ||||
|         } | ||||
|         if extra_context: | ||||
|             assert isinstance(extra_context, dict) | ||||
|             ctx.update(extra_context) | ||||
| 
 | ||||
|         self.ctx = ctx | ||||
|         self.destpath = join(self.root_dir, self.ctx['repo_name']) | ||||
| 
 | ||||
|         cookiecutter(template='./', checkout=None, no_input=True, extra_context=ctx) | ||||
| 
 | ||||
|         # Build a list containing absolute paths to the generated files | ||||
|         paths = [os.path.join(dirpath, file_path) | ||||
|                  for dirpath, subdirs, files in os.walk(self.destpath) | ||||
|                  for file_path in files] | ||||
|         return paths | ||||
| 
 | ||||
|     def clean(self): | ||||
|         if exists(self.destpath): | ||||
|             shutil.rmtree(self.destpath) | ||||
|         sh.cd(self.root_dir) | ||||
| 
 | ||||
|     def tearDown(self): | ||||
|         self.clean() | ||||
							
								
								
									
										90
									
								
								tests/test_cookiecutter_generation.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								tests/test_cookiecutter_generation.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,90 @@ | |||
| # -*- coding: utf-8 -*- | ||||
| 
 | ||||
| import os | ||||
| import re | ||||
| import sh | ||||
| 
 | ||||
| import pytest | ||||
| from binaryornot.check import is_binary | ||||
| 
 | ||||
| PATTERN = "{{(\s?cookiecutter)[.](.*?)}}" | ||||
| RE_OBJ = re.compile(PATTERN) | ||||
| 
 | ||||
| 
 | ||||
| @pytest.fixture | ||||
| def context(): | ||||
|     return { | ||||
|         "project_name": "My Test Project", | ||||
|         "repo_name": "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", | ||||
|         "now": "2015/01/13", | ||||
|         "year": "2015" | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
| 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 | ||||
|     ] | ||||
| 
 | ||||
| 
 | ||||
| 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_default_configuration(cookies, context): | ||||
|     result = cookies.bake(extra_context=context) | ||||
|     assert result.exit_code == 0 | ||||
|     assert result.exception is None | ||||
|     assert result.project.basename == context['repo_name'] | ||||
|     assert result.project.isdir() | ||||
| 
 | ||||
|     paths = build_files_list(str(result.project)) | ||||
|     assert paths | ||||
|     check_paths(paths) | ||||
| 
 | ||||
| 
 | ||||
| @pytest.fixture(params=['use_maildump', 'use_celery', 'windows']) | ||||
| def feature_context(request, context): | ||||
|     context.update({request.param: 'y'}) | ||||
|     return context | ||||
| 
 | ||||
| 
 | ||||
| def test_enabled_features(cookies, feature_context): | ||||
|     result = cookies.bake(extra_context=feature_context) | ||||
|     assert result.exit_code == 0 | ||||
|     assert result.exception is None | ||||
|     assert result.project.basename == feature_context['repo_name'] | ||||
|     assert result.project.isdir() | ||||
| 
 | ||||
|     paths = build_files_list(str(result.project)) | ||||
|     assert paths | ||||
|     check_paths(paths) | ||||
| 
 | ||||
| 
 | ||||
| def test_flake8_compliance(cookies): | ||||
|     """generated project should pass flake8""" | ||||
|     result = cookies.bake() | ||||
| 
 | ||||
|     try: | ||||
|         sh.flake8(str(result.project)) | ||||
|     except sh.ErrorReturnCode as e: | ||||
|         pytest.fail(e) | ||||
|  | @ -1,33 +0,0 @@ | |||
| from __future__ import absolute_import | ||||
| import sh | ||||
| 
 | ||||
| from .base import DjangoCookieTestCase | ||||
| 
 | ||||
| 
 | ||||
| class TestCookiecutterSubstitution(DjangoCookieTestCase): | ||||
|     """Test that all cookiecutter instances are substituted""" | ||||
| 
 | ||||
|     def test_default_configuration(self): | ||||
|         # Build a list containing absolute paths to the generated files | ||||
|         paths = self.generate_project() | ||||
|         self.check_paths(paths) | ||||
| 
 | ||||
|     def test_maildump_enabled(self): | ||||
|         paths = self.generate_project(extra_context={'use_maildump': 'y'}) | ||||
|         self.check_paths(paths) | ||||
| 
 | ||||
|     def test_celery_enabled(self): | ||||
|         paths = self.generate_project(extra_context={'use_celery': 'y'}) | ||||
|         self.check_paths(paths) | ||||
| 
 | ||||
|     def test_windows_enabled(self): | ||||
|         paths = self.generate_project(extra_context={'windows': 'y'}) | ||||
|         self.check_paths(paths) | ||||
| 
 | ||||
|     def test_flake8_compliance(self): | ||||
|         """generated project should pass flake8""" | ||||
|         self.generate_project() | ||||
|         try: | ||||
|             sh.flake8(self.destpath) | ||||
|         except sh.ErrorReturnCode as e: | ||||
|             raise AssertionError(e) | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user