Completed
Pull Request — master (#623)
by
unknown
57s
created

tests.fake_project()   A

Complexity

Conditions 1

Size

Total Lines 4

Duplication

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