Completed
Push — master ( 454794...2ab37b )
by
unknown
12s
created

test_debug_file_verbose()   B

Complexity

Conditions 6

Size

Total Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 6
c 2
b 0
f 0
dl 0
loc 21
rs 7.8867
1
# -*- coding: utf-8 -*-
2
3
import os
4
import json
5
6
from click.testing import CliRunner
7
import pytest
8
9
from cookiecutter.__main__ import main
10
from cookiecutter.main import cookiecutter
11
from cookiecutter import utils, config
12
13
14
@pytest.fixture(scope='session')
15
def cli_runner():
16
    """Fixture that returns a helper function to run the cookiecutter cli."""
17
    runner = CliRunner()
18
19
    def cli_main(*cli_args):
20
        """Run cookiecutter cli main with the given args."""
21
        return runner.invoke(main, cli_args)
22
23
    return cli_main
24
25
26
@pytest.fixture
27
def remove_fake_project_dir(request):
28
    """
29
    Remove the fake project directory created during the tests.
30
    """
31
    def fin_remove_fake_project_dir():
32
        if os.path.isdir('fake-project'):
33
            utils.rmtree('fake-project')
34
    request.addfinalizer(fin_remove_fake_project_dir)
35
36
37
@pytest.fixture
38
def make_fake_project_dir(request):
39
    """Create a fake project to be overwritten in the according tests."""
40
    os.makedirs('fake-project')
41
42
43
@pytest.fixture(params=['-V', '--version'])
44
def version_cli_flag(request):
45
    return request.param
46
47
48
def test_cli_version(cli_runner, version_cli_flag):
49
    result = cli_runner(version_cli_flag)
50
    assert result.exit_code == 0
51
    assert result.output.startswith('Cookiecutter')
52
53
54
@pytest.mark.usefixtures('make_fake_project_dir', 'remove_fake_project_dir')
55
def test_cli_error_on_existing_output_directory(cli_runner):
56
    result = cli_runner('tests/fake-repo-pre/', '--no-input')
57
    assert result.exit_code != 0
58
    expected_error_msg = 'Error: "fake-project" directory already exists\n'
59
    assert result.output == expected_error_msg
60
61
62
@pytest.mark.usefixtures('remove_fake_project_dir')
63
def test_cli(cli_runner):
64
    result = cli_runner('tests/fake-repo-pre/', '--no-input')
65
    assert result.exit_code == 0
66
    assert os.path.isdir('fake-project')
67
    with open(os.path.join('fake-project', 'README.rst')) as f:
68
        assert 'Project name: **Fake Project**' in f.read()
69
70
71
@pytest.mark.usefixtures('remove_fake_project_dir')
72
def test_cli_verbose(cli_runner):
73
    result = cli_runner('tests/fake-repo-pre/', '--no-input', '-v')
74
    assert result.exit_code == 0
75
    assert os.path.isdir('fake-project')
76
    with open(os.path.join('fake-project', 'README.rst')) as f:
77
        assert 'Project name: **Fake Project**' in f.read()
78
79
80
@pytest.mark.usefixtures('remove_fake_project_dir')
81
def test_cli_replay(mocker, cli_runner):
82
    mock_cookiecutter = mocker.patch(
83
        'cookiecutter.cli.cookiecutter'
84
    )
85
86
    template_path = 'tests/fake-repo-pre/'
87
    result = cli_runner(template_path, '--replay', '-v')
88
89
    assert result.exit_code == 0
90
    mock_cookiecutter.assert_called_once_with(
91
        template_path,
92
        None,
93
        False,
94
        replay=True,
95
        overwrite_if_exists=False,
96
        output_dir='.',
97
        config_file=config.USER_CONFIG_PATH,
98
        extra_context=None
99
    )
100
101
102
@pytest.mark.usefixtures('remove_fake_project_dir')
103
def test_cli_exit_on_noinput_and_replay(mocker, cli_runner):
104
    mock_cookiecutter = mocker.patch(
105
        'cookiecutter.cli.cookiecutter',
106
        side_effect=cookiecutter
107
    )
108
109
    template_path = 'tests/fake-repo-pre/'
110
    result = cli_runner(template_path, '--no-input', '--replay', '-v')
111
112
    assert result.exit_code == 1
113
114
    expected_error_msg = (
115
        "You can not use both replay and no_input or extra_context "
116
        "at the same time."
117
    )
118
119
    assert expected_error_msg in result.output
120
121
    mock_cookiecutter.assert_called_once_with(
122
        template_path,
123
        None,
124
        True,
125
        replay=True,
126
        overwrite_if_exists=False,
127
        output_dir='.',
128
        config_file=config.USER_CONFIG_PATH,
129
        extra_context=None
130
    )
131
132
133
@pytest.fixture(params=['-f', '--overwrite-if-exists'])
134
def overwrite_cli_flag(request):
135
    return request.param
136
137
138
@pytest.mark.usefixtures('remove_fake_project_dir')
139
def test_run_cookiecutter_on_overwrite_if_exists_and_replay(
140
        mocker, cli_runner, overwrite_cli_flag):
141
    mock_cookiecutter = mocker.patch(
142
        'cookiecutter.cli.cookiecutter',
143
        side_effect=cookiecutter
144
    )
145
146
    template_path = 'tests/fake-repo-pre/'
147
    result = cli_runner(template_path, '--replay', '-v', overwrite_cli_flag)
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
        extra_context=None
160
    )
161
162
163
@pytest.mark.usefixtures('remove_fake_project_dir')
164
def test_cli_overwrite_if_exists_when_output_dir_does_not_exist(
165
        cli_runner, overwrite_cli_flag):
166
167
    result = cli_runner(
168
        'tests/fake-repo-pre/',
169
        '--no-input',
170
        overwrite_cli_flag,
171
    )
172
173
    assert result.exit_code == 0
174
    assert os.path.isdir('fake-project')
175
176
177
@pytest.mark.usefixtures('make_fake_project_dir', 'remove_fake_project_dir')
178
def test_cli_overwrite_if_exists_when_output_dir_exists(
179
        cli_runner, overwrite_cli_flag):
180
181
    result = cli_runner(
182
        'tests/fake-repo-pre/',
183
        '--no-input',
184
        overwrite_cli_flag,
185
    )
186
    assert result.exit_code == 0
187
    assert os.path.isdir('fake-project')
188
189
190
@pytest.fixture(params=['-o', '--output-dir'])
191
def output_dir_flag(request):
192
    return request.param
193
194
195
@pytest.fixture
196
def output_dir(tmpdir):
197
    return str(tmpdir.mkdir('output'))
198
199
200
def test_cli_output_dir(mocker, cli_runner, output_dir_flag, output_dir):
201
    mock_cookiecutter = mocker.patch(
202
        'cookiecutter.cli.cookiecutter'
203
    )
204
205
    template_path = 'tests/fake-repo-pre/'
206
    result = cli_runner(template_path, output_dir_flag, output_dir)
207
208
    assert result.exit_code == 0
209
    mock_cookiecutter.assert_called_once_with(
210
        template_path,
211
        None,
212
        False,
213
        replay=False,
214
        overwrite_if_exists=False,
215
        output_dir=output_dir,
216
        config_file=config.USER_CONFIG_PATH,
217
        extra_context=None
218
    )
219
220
221
@pytest.fixture(params=['-h', '--help', 'help'])
222
def help_cli_flag(request):
223
    return request.param
224
225
226
def test_cli_help(cli_runner, help_cli_flag):
227
    result = cli_runner(help_cli_flag)
228
    assert result.exit_code == 0
229
    assert result.output.startswith('Usage')
230
231
232
@pytest.fixture
233
def user_config_path(tmpdir):
234
    return str(tmpdir.join('tests/config.yaml'))
235
236
237
def test_user_config(mocker, cli_runner, user_config_path):
238
    mock_cookiecutter = mocker.patch(
239
        'cookiecutter.cli.cookiecutter'
240
    )
241
242
    template_path = 'tests/fake-repo-pre/'
243
    result = cli_runner(template_path, '--config-file', user_config_path)
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
        extra_context=None
255
    )
256
257
258
def test_default_user_config_overwrite(mocker, cli_runner, user_config_path):
259
    mock_cookiecutter = mocker.patch(
260
        'cookiecutter.cli.cookiecutter'
261
    )
262
263
    template_path = 'tests/fake-repo-pre/'
264
    result = cli_runner(
265
        template_path,
266
        '--config-file',
267
        user_config_path,
268
        '--default-config',
269
    )
270
271
    assert result.exit_code == 0
272
    mock_cookiecutter.assert_called_once_with(
273
        template_path,
274
        None,
275
        False,
276
        replay=False,
277
        overwrite_if_exists=False,
278
        output_dir='.',
279
        config_file=None,
280
        extra_context=None
281
    )
282
283
284
def test_default_user_config(mocker, cli_runner):
285
    mock_cookiecutter = mocker.patch(
286
        'cookiecutter.cli.cookiecutter'
287
    )
288
289
    template_path = 'tests/fake-repo-pre/'
290
    result = cli_runner(template_path, '--default-config')
291
292
    assert result.exit_code == 0
293
    mock_cookiecutter.assert_called_once_with(
294
        template_path,
295
        None,
296
        False,
297
        replay=False,
298
        overwrite_if_exists=False,
299
        output_dir='.',
300
        config_file=None,
301
        extra_context=None
302
    )
303
304
305
def test_echo_undefined_variable_error(tmpdir, cli_runner):
306
    output_dir = str(tmpdir.mkdir('output'))
307
    template_path = 'tests/undefined-variable/file-name/'
308
309
    result = cli_runner(
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_echo_unknown_extension_error(tmpdir, cli_runner):
336
    output_dir = str(tmpdir.mkdir('output'))
337
    template_path = 'tests/test-extensions/unknown/'
338
339
    result = cli_runner(
340
        '--no-input',
341
        '--default-config',
342
        '--output-dir',
343
        output_dir,
344
        template_path,
345
    )
346
347
    assert result.exit_code == 1
348
349
    assert 'Unable to load extension: ' in result.output
350
351
352
@pytest.mark.usefixtures('remove_fake_project_dir')
353
def test_cli_extra_context(cli_runner):
354
    result = cli_runner(
355
        'tests/fake-repo-pre/',
356
        '--no-input',
357
        '-v',
358
        'project_name=Awesomez',
359
    )
360
    assert result.exit_code == 0
361
    assert os.path.isdir('fake-project')
362
    with open(os.path.join('fake-project', 'README.rst')) as f:
363
        assert 'Project name: **Awesomez**' in f.read()
364
365
366
@pytest.mark.usefixtures('remove_fake_project_dir')
367
def test_cli_extra_context_invalid_format(cli_runner):
368
    result = cli_runner(
369
        'tests/fake-repo-pre/',
370
        '--no-input',
371
        '-v',
372
        'ExtraContextWithNoEqualsSoInvalid',
373
    )
374
    assert result.exit_code == 2
375
    assert 'Error: Invalid value for "extra_context"' in result.output
376
    assert 'should contain items of the form key=value' in result.output
377
378
379
@pytest.fixture
380
def debug_file(tmpdir):
381
    return tmpdir / 'fake-repo.log'
382
383
384
@pytest.mark.usefixtures('remove_fake_project_dir')
385
def test_debug_file_non_verbose(cli_runner, debug_file):
386
    assert not debug_file.exists()
387
388
    result = cli_runner(
389
        '--no-input',
390
        '--debug-file',
391
        str(debug_file),
392
        'tests/fake-repo-pre/',
393
    )
394
    assert result.exit_code == 0
395
396
    assert debug_file.exists()
397
398
    context_log = (
399
        "DEBUG cookiecutter.main: context_file is "
400
        "tests/fake-repo-pre/cookiecutter.json"
401
    )
402
    assert context_log in debug_file.readlines(cr=False)
403
    assert context_log not in result.output
404
405
406
@pytest.mark.usefixtures('remove_fake_project_dir')
407
def test_debug_file_verbose(cli_runner, debug_file):
408
    assert not debug_file.exists()
409
410
    result = cli_runner(
411
        '--verbose',
412
        '--no-input',
413
        '--debug-file',
414
        str(debug_file),
415
        'tests/fake-repo-pre/',
416
    )
417
    assert result.exit_code == 0
418
419
    assert debug_file.exists()
420
421
    context_log = (
422
        "DEBUG cookiecutter.main: context_file is "
423
        "tests/fake-repo-pre/cookiecutter.json"
424
    )
425
    assert context_log in debug_file.readlines(cr=False)
426
    assert context_log in result.output
427