Completed
Pull Request — master (#400)
by
unknown
01:02
created

tests.test_cli_extra_context()   B

Complexity

Conditions 5

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %
Metric Value
cc 5
dl 0
loc 7
rs 8.5455
1
import os
2
import json
3
import pytest
4
5
from click.testing import CliRunner
6
7
from cookiecutter.cli import main
8
from cookiecutter.main import cookiecutter
9
from cookiecutter import utils, config
10
11
runner = CliRunner()
12
13
14
@pytest.fixture
15
def remove_fake_project_dir(request):
16
    """
17
    Remove the fake project directory created during the tests.
18
    """
19
    def fin_remove_fake_project_dir():
20
        if os.path.isdir('fake-project'):
21
            utils.rmtree('fake-project')
22
    request.addfinalizer(fin_remove_fake_project_dir)
23
24
25
@pytest.fixture
26
def make_fake_project_dir(request):
27
    """Create a fake project to be overwritten in the according tests."""
28
    os.makedirs('fake-project')
29
30
31
@pytest.fixture(params=['-V', '--version'])
32
def version_cli_flag(request):
33
    return request.param
34
35
36
def test_cli_version(version_cli_flag):
37
    result = runner.invoke(main, [version_cli_flag])
38
    assert result.exit_code == 0
39
    assert result.output.startswith('Cookiecutter')
40
41
42
@pytest.mark.usefixtures('make_fake_project_dir', 'remove_fake_project_dir')
43
def test_cli_error_on_existing_output_directory():
44
    result = runner.invoke(main, ['tests/fake-repo-pre/', '--no-input'])
45
    assert result.exit_code != 0
46
    expected_error_msg = 'Error: "fake-project" directory already exists\n'
47
    assert result.output == expected_error_msg
48
49
50
@pytest.mark.usefixtures('remove_fake_project_dir')
51
def test_cli():
52
    result = runner.invoke(main, ['tests/fake-repo-pre/', '--no-input'])
53
    assert result.exit_code == 0
54
    assert os.path.isdir('fake-project')
55
    with open(os.path.join('fake-project', 'README.rst')) as f:
56
        assert 'Project name: **Fake Project**' in f.read()
57
58
59
@pytest.mark.usefixtures('remove_fake_project_dir')
60
def test_cli_verbose():
61
    result = runner.invoke(main, ['tests/fake-repo-pre/', '--no-input', '-v'])
62
    assert result.exit_code == 0
63
    assert os.path.isdir('fake-project')
64
    with open(os.path.join('fake-project', 'README.rst')) as f:
65
        assert 'Project name: **Fake Project**' in f.read()
66
67
68
@pytest.mark.usefixtures('remove_fake_project_dir')
69
def test_cli_replay(mocker):
70
    mock_cookiecutter = mocker.patch(
71
        'cookiecutter.cli.cookiecutter'
72
    )
73
74
    template_path = 'tests/fake-repo-pre/'
75
    result = runner.invoke(main, [
76
        template_path,
77
        '--replay',
78
        '-v'
79
    ])
80
81
    assert result.exit_code == 0
82
    mock_cookiecutter.assert_called_once_with(
83
        template_path,
84
        None,
85
        False,
86
        replay=True,
87
        overwrite_if_exists=False,
88
        output_dir='.',
89
        config_file=config.USER_CONFIG_PATH
90
    )
91
92
93
@pytest.mark.usefixtures('remove_fake_project_dir')
94
def test_cli_exit_on_noinput_and_replay(mocker):
95
    mock_cookiecutter = mocker.patch(
96
        'cookiecutter.cli.cookiecutter',
97
        side_effect=cookiecutter
98
    )
99
100
    template_path = 'tests/fake-repo-pre/'
101
    result = runner.invoke(main, [
102
        template_path,
103
        '--no-input',
104
        '--replay',
105
        '-v'
106
    ])
107
108
    assert result.exit_code == 1
109
110
    expected_error_msg = (
111
        "You can not use both replay and no_input or extra_context "
112
        "at the same time."
113
    )
114
115
    assert expected_error_msg in result.output
116
117
    mock_cookiecutter.assert_called_once_with(
118
        template_path,
119
        None,
120
        True,
121
        replay=True,
122
        overwrite_if_exists=False,
123
        output_dir='.',
124
        config_file=config.USER_CONFIG_PATH
125
    )
126
127
128
@pytest.fixture(params=['-f', '--overwrite-if-exists'])
129
def overwrite_cli_flag(request):
130
    return request.param
131
132
133
@pytest.mark.usefixtures('remove_fake_project_dir')
134
def test_run_cookiecutter_on_overwrite_if_exists_and_replay(
135
        mocker, overwrite_cli_flag):
136
    mock_cookiecutter = mocker.patch(
137
        'cookiecutter.cli.cookiecutter',
138
        side_effect=cookiecutter
139
    )
140
141
    template_path = 'tests/fake-repo-pre/'
142
    result = runner.invoke(main, [
143
        template_path,
144
        '--replay',
145
        '-v',
146
        overwrite_cli_flag,
147
    ])
148
149
    assert result.exit_code == 0
150
151
    mock_cookiecutter.assert_called_once_with(
152
        template_path,
153
        None,
154
        False,
155
        replay=True,
156
        overwrite_if_exists=True,
157
        output_dir='.',
158
        config_file=config.USER_CONFIG_PATH
159
    )
160
161
162
@pytest.mark.usefixtures('remove_fake_project_dir')
163
def test_cli_overwrite_if_exists_when_output_dir_does_not_exist(
164
        overwrite_cli_flag):
165
    result = runner.invoke(main, [
166
        'tests/fake-repo-pre/', '--no-input', overwrite_cli_flag
167
    ])
168
169
    assert result.exit_code == 0
170
    assert os.path.isdir('fake-project')
171
172
173
@pytest.mark.usefixtures('make_fake_project_dir', 'remove_fake_project_dir')
174
def test_cli_overwrite_if_exists_when_output_dir_exists(overwrite_cli_flag):
175
    result = runner.invoke(main, [
176
        'tests/fake-repo-pre/', '--no-input', overwrite_cli_flag
177
    ])
178
179
    assert result.exit_code == 0
180
    assert os.path.isdir('fake-project')
181
182
183
@pytest.fixture(params=['-o', '--output-dir'])
184
def output_dir_flag(request):
185
    return request.param
186
187
188
@pytest.fixture
189
def output_dir(tmpdir):
190
    return str(tmpdir.mkdir('output'))
191
192
193
def test_cli_output_dir(mocker, output_dir_flag, output_dir):
194
    mock_cookiecutter = mocker.patch(
195
        'cookiecutter.cli.cookiecutter'
196
    )
197
198
    template_path = 'tests/fake-repo-pre/'
199
    result = runner.invoke(main, [
200
        template_path,
201
        output_dir_flag,
202
        output_dir
203
    ])
204
205
    assert result.exit_code == 0
206
    mock_cookiecutter.assert_called_once_with(
207
        template_path,
208
        None,
209
        False,
210
        replay=False,
211
        overwrite_if_exists=False,
212
        output_dir=output_dir,
213
        config_file=config.USER_CONFIG_PATH
214
    )
215
216
217
@pytest.fixture(params=['-h', '--help', 'help'])
218
def help_cli_flag(request):
219
    return request.param
220
221
222
def test_cli_help(help_cli_flag):
223
    result = runner.invoke(main, [help_cli_flag])
224
    assert result.exit_code == 0
225
    assert result.output.startswith('Usage')
226
227
228
@pytest.fixture
229
def user_config_path(tmpdir):
230
    return str(tmpdir.join('tests/config.yaml'))
231
232
233
def test_user_config(mocker, user_config_path):
234
    mock_cookiecutter = mocker.patch(
235
        'cookiecutter.cli.cookiecutter'
236
    )
237
238
    template_path = 'tests/fake-repo-pre/'
239
    result = runner.invoke(main, [
240
        template_path,
241
        '--config-file',
242
        user_config_path
243
    ])
244
245
    assert result.exit_code == 0
246
    mock_cookiecutter.assert_called_once_with(
247
        template_path,
248
        None,
249
        False,
250
        replay=False,
251
        overwrite_if_exists=False,
252
        output_dir='.',
253
        config_file=user_config_path
254
    )
255
256
257
def test_default_user_config_overwrite(mocker, user_config_path):
258
    mock_cookiecutter = mocker.patch(
259
        'cookiecutter.cli.cookiecutter'
260
    )
261
262
    template_path = 'tests/fake-repo-pre/'
263
    result = runner.invoke(main, [
264
        template_path,
265
        '--config-file',
266
        user_config_path,
267
        '--default-config'
268
    ])
269
270
    assert result.exit_code == 0
271
    mock_cookiecutter.assert_called_once_with(
272
        template_path,
273
        None,
274
        False,
275
        replay=False,
276
        overwrite_if_exists=False,
277
        output_dir='.',
278
        config_file=None
279
    )
280
281
282
def test_default_user_config(mocker):
283
    mock_cookiecutter = mocker.patch(
284
        'cookiecutter.cli.cookiecutter'
285
    )
286
287
    template_path = 'tests/fake-repo-pre/'
288
    result = runner.invoke(main, [
289
        template_path,
290
        '--default-config'
291
    ])
292
293
    assert result.exit_code == 0
294
    mock_cookiecutter.assert_called_once_with(
295
        template_path,
296
        None,
297
        False,
298
        replay=False,
299
        overwrite_if_exists=False,
300
        output_dir='.',
301
        config_file=None
302
    )
303
304
305
def test_echo_undefined_variable_error(tmpdir):
306
    output_dir = str(tmpdir.mkdir('output'))
307
    template_path = 'tests/undefined-variable/file-name/'
308
309
    result = runner.invoke(main, [
310
        '--no-input',
311
        '--default-config',
312
        '--output-dir',
313
        output_dir,
314
        template_path,
315
    ])
316
317
    assert result.exit_code == 1
318
319
    error = "Unable to create file '{{cookiecutter.foobar}}'"
320
    assert error in result.output
321
322
    message = "Error message: 'dict object' has no attribute 'foobar'"
323
    assert message in result.output
324
325
    context = {
326
        'cookiecutter': {
327
            'github_username': 'hackebrot',
328
            'project_slug': 'testproject'
329
        }
330
    }
331
    context_str = json.dumps(context, indent=4, sort_keys=True)
332
    assert context_str in result.output
333
334
335
def test_cli_extra_context():
336
    result = runner.invoke(main, ['tests/fake-repo-pre/', '--no-input', '-v',
337
                                  'project_name=Awesomez'])
338
    assert result.exit_code == 0
339
    assert os.path.isdir('fake-project')
340
    with open(os.path.join('fake-project', 'README.rst')) as f:
341
        assert 'Project name: **Awesomez**' in f.read()
342