Skip to content

Commit 443ad61

Browse files
authored
Merge pull request #22 from hackebrot/add-context-to-result
Add context to result
2 parents d64716f + 23699d4 commit 443ad61

File tree

3 files changed

+116
-7
lines changed

3 files changed

+116
-7
lines changed

docs/features.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ hold useful information:
66
* ``exit_code``: is the exit code of cookiecutter, ``0`` means successful termination
77
* ``exception``: is the exception that happened if one did
88
* ``project``: a [py.path.local] object pointing to the rendered project
9+
* ``context``: is the rendered context
910

1011
The returned ``LocalPath`` instance provides you with a powerful interface
1112
to filesystem related information, that comes in handy for validating the generated

pytest_cookies.py

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
import pytest
55

66
from cookiecutter.main import cookiecutter
7+
from cookiecutter.generate import generate_context
8+
from cookiecutter.prompt import prompt_for_config
79

810
USER_CONFIG = u"""
911
cookiecutters_dir: "{cookiecutters_dir}"
@@ -14,9 +16,16 @@
1416
class Result(object):
1517
"""Holds the captured result of the cookiecutter project generation."""
1618

17-
def __init__(self, exception=None, exit_code=0, project_dir=None):
19+
def __init__(
20+
self,
21+
exception=None,
22+
exit_code=0,
23+
project_dir=None,
24+
context=None,
25+
):
1826
self.exception = exception
1927
self.exit_code = exit_code
28+
self.context = context
2029
self._project_dir = project_dir
2130

2231
@property
@@ -28,6 +37,7 @@ def project(self):
2837
def __repr__(self):
2938
if self.exception:
3039
return '<Result {!r}>'.format(self.exception)
40+
3141
return '<Result {}>'.format(self.project)
3242

3343

@@ -50,17 +60,30 @@ def bake(self, extra_context=None, template=None):
5060
exception = None
5161
exit_code = 0
5262
project_dir = None
63+
context = None
5364

5465
if template is None:
5566
template = self._default_template
5667

68+
context_file = py.path.local(template).join('cookiecutter.json')
69+
5770
try:
71+
# Render the context, so that we can store it on the Result
72+
context = prompt_for_config(
73+
generate_context(
74+
context_file=str(context_file),
75+
extra_context=extra_context,
76+
),
77+
no_input=True,
78+
)
79+
80+
# Run cookiecutter to generate a new project
5881
project_dir = cookiecutter(
5982
template,
6083
no_input=True,
6184
extra_context=extra_context,
6285
output_dir=str(self._new_output_dir()),
63-
config_file=str(self._config_file)
86+
config_file=str(self._config_file),
6487
)
6588
except SystemExit as e:
6689
if e.code != 0:
@@ -70,7 +93,12 @@ def bake(self, extra_context=None, template=None):
7093
exception = e
7194
exit_code = -1
7295

73-
return Result(exception, exit_code, project_dir)
96+
return Result(
97+
exception=exception,
98+
exit_code=exit_code,
99+
project_dir=project_dir,
100+
context=context,
101+
)
74102

75103

76104
@pytest.fixture(scope='session')

tests/test_cookies.py

Lines changed: 84 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# -*- coding: utf-8 -*-
22

33
import json
4+
import collections
45

56
import pytest
67

@@ -33,10 +34,10 @@ def test_valid_fixture(cookies):
3334
def cookiecutter_template(tmpdir):
3435
template = tmpdir.ensure('cookiecutter-template', dir=True)
3536

36-
template_config = {
37-
'repo_name': 'foobar',
38-
'short_description': 'Test Project',
39-
}
37+
template_config = collections.OrderedDict([
38+
('repo_name', 'foobar'),
39+
('short_description', 'Test Project'),
40+
])
4041
template.join('cookiecutter.json').write(json.dumps(template_config))
4142

4243
template_readme = '\n'.join([
@@ -138,6 +139,85 @@ def test_bake_project(cookies):
138139
])
139140

140141

142+
def test_cookies_bake_result_context(testdir, cookiecutter_template):
143+
"""Programmatically create a **Cookiecutter** template and use `bake` to
144+
create a project from it.
145+
146+
Check that the result holds the rendered context.
147+
"""
148+
149+
testdir.makepyfile("""
150+
# -*- coding: utf-8 -*-
151+
152+
import collections
153+
154+
def test_bake_project(cookies):
155+
result = cookies.bake(extra_context=collections.OrderedDict([
156+
('repo_name', 'cookies'),
157+
('short_description', '{{cookiecutter.repo_name}} is awesome'),
158+
]))
159+
160+
assert result.exit_code == 0
161+
assert result.exception is None
162+
assert result.project.basename == 'cookies'
163+
assert result.project.isdir()
164+
165+
assert result.context == {
166+
'repo_name': 'cookies',
167+
'short_description': 'cookies is awesome',
168+
}
169+
170+
assert str(result) == '<Result {}>'.format(result.project)
171+
""")
172+
173+
result = testdir.runpytest(
174+
'-v',
175+
'--template={}'.format(cookiecutter_template)
176+
)
177+
178+
result.stdout.fnmatch_lines([
179+
'*::test_bake_project PASSED*',
180+
])
181+
182+
183+
def test_cookies_bake_result_context_exception(testdir, cookiecutter_template):
184+
"""Programmatically create a **Cookiecutter** template and use `bake` to
185+
create a project from it.
186+
187+
Check that exceptions resulting from rendering the context are stored on
188+
result and that the rendered context is not set.
189+
"""
190+
191+
testdir.makepyfile("""
192+
# -*- coding: utf-8 -*-
193+
194+
import collections
195+
196+
def test_bake_project(cookies):
197+
result = cookies.bake(extra_context=collections.OrderedDict([
198+
('repo_name', 'cookies'),
199+
('short_description', '{{cookiecutter.nope}}'),
200+
]))
201+
202+
assert result.exit_code == -1
203+
assert result.exception is not None
204+
assert result.project is None
205+
206+
assert result.context is None
207+
208+
assert str(result) == '<Result {!r}>'.format(result.exception)
209+
""")
210+
211+
result = testdir.runpytest(
212+
'-v',
213+
'--template={}'.format(cookiecutter_template)
214+
)
215+
216+
result.stdout.fnmatch_lines([
217+
'*::test_bake_project PASSED*',
218+
])
219+
220+
141221
def test_cookies_bake_should_create_new_output_directories(
142222
testdir, cookiecutter_template
143223
):

0 commit comments

Comments
 (0)