Completed
Pull Request — master (#1008)
by
unknown
30s
created

test_variable_str()   F

Complexity

Conditions 17

Size

Total Lines 29

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
cc 17
c 3
b 0
f 0
dl 0
loc 29
rs 2.7204

How to fix   Complexity   

Complexity

Complex classes like test_variable_str() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
# -*- coding: utf-8 -*-
2
# flake8: noqa
3
"""
4
test_context
5
------------
6
7
Tests for `cookiecutter.context` module that handles prompts for v2 context.
8
"""
9
from __future__ import unicode_literals
10
11
import sys
12
import os.path
13
import time
14
import json
15
import logging
16
17
import pytest
18
19
from collections import OrderedDict
20
21
from cookiecutter import context
22
23
from cookiecutter.exceptions import (
24
    ContextDecodingException
25
)
26
27
import click
28
29
from uuid import UUID
30
31
logger = logging.getLogger(__name__)
32
33
34
def load_cookiecutter(cookiecutter_file):
35
36
    context = {}
37
    try:
38
        with open(cookiecutter_file) as file_handle:
39
            obj = json.load(file_handle, object_pairs_hook=OrderedDict)
40
    except ValueError as e:
41
        # JSON decoding error.  Let's throw a new exception that is more
42
        # friendly for the developer or user.
43
        full_fpath = os.path.abspath(cookiecutter_file)
44
        json_exc_message = str(e)
45
        our_exc_message = (
46
            'JSON decoding error while loading "{0}".  Decoding'
47
            ' error details: "{1}"'.format(full_fpath, json_exc_message))
48
        raise ContextDecodingException(our_exc_message)
49
50
    # Add the Python object to the context dictionary
51
    file_name = os.path.split(cookiecutter_file)[1]
52
    file_stem = file_name.split('.')[0]
53
    context[file_stem] = obj
54
55
    return context
56
57
58
def context_data_check():
59
    context_all_reqs = (
60
        {
61
            'cookiecutter_context': OrderedDict([
62
                ("name", "cookiecutter-pytest-plugin"),
63
                ("cookiecutter_version", "2.0.0"),
64
                ("variables", [])
65
            ])
66
        },
67
        True
68
    )
69
70
    context_missing_name = (
71
        {
72
            'cookiecutter_context': OrderedDict([
73
                ("cookiecutter_version", "2.0.0"),
74
                ("variables", [])
75
            ])
76
        },
77
        False
78
    )
79
80
    context_missing_cookiecutter_version = (
81
        {
82
            'cookiecutter_context': OrderedDict([
83
                ("name", "cookiecutter-pytest-plugin"),
84
                ("variables", [])
85
            ])
86
        },
87
        False
88
    )
89
90
    context_missing_variables = (
91
        {
92
            'cookiecutter_context': OrderedDict([
93
                ("name", "cookiecutter-pytest-plugin"),
94
                ("cookiecutter_version", "2.0.0"),
95
            ])
96
        },
97
        False
98
    )
99
100
    yield context_all_reqs
101
    yield context_missing_name
102
    yield context_missing_cookiecutter_version
103
    yield context_missing_variables
104
105
106
@pytest.mark.usefixtures('clean_system')
107
@pytest.mark.parametrize('input_params, expected_result', context_data_check())
108
def test_context_check(input_params, expected_result):
109
    """
110
    Test that a context with the required fields will be detected as a
111
    v2 context.
112
    """
113
    assert context.context_is_version_2(**input_params) == expected_result
114
115
116
@pytest.mark.usefixtures('clean_system')
117
def test_load_context_defaults():
118
119
    cc = load_cookiecutter('tests/test-context/cookiecutter.json')
120
121
    cc_cfg = context.load_context(cc['cookiecutter'], no_input=True)
122
123
    assert cc_cfg['full_name'] == 'Raphael Pierzina'
124
    assert cc_cfg['email'] == '[email protected]'
125
    assert cc_cfg['plugin_name'] == 'emoji'
126
    assert cc_cfg['module_name'] == 'emoji'
127
    assert cc_cfg['license'] == 'MIT'
128
    assert cc_cfg['docs'] is False
129
    assert 'docs_tool' not in cc_cfg.keys()   # skip_if worked
130
    assert cc_cfg['year'] == time.strftime('%Y')
131
    assert cc_cfg['incept_year'] == 2017
132
    assert cc_cfg['released'] is False
133
    assert cc_cfg['temperature'] == 77.3
134
    assert cc_cfg['Release-GUID'] == UUID('04f5eaa9ee7345469dccffc538b27194')
135
    assert cc_cfg['extensions'] == "['jinja2_time.TimeExtension']"
136
    assert cc_cfg['copy_with_out_render'] == "['*.html', '*not_rendered_dir', 'rendered_dir/not_rendered_file.ini']"
137
    assert cc_cfg['fixtures'] == OrderedDict([('foo',
138
                                               OrderedDict([('scope', 'session'),
139
                                                            ('autouse', True)])),
140
                                              ('bar',
141
                                               OrderedDict([('scope', 'function'),
142
                                                            ('autouse',
143
                                                             False)]))])
144
145
146
@pytest.mark.usefixtures('clean_system')
147
def test_load_context_defaults_skips_branch():
148
    """
149
    Test that if_no_skip_to and if_yes_skip_to actually do branch and
150
    skip variables
151
    """
152
    cc = load_cookiecutter('tests/test-context/cookiecutter_skips_1.json')
153
154
    cc_cfg = context.load_context(cc['cookiecutter_skips_1'], no_input=True)
155
156
    assert cc_cfg['project_configuration_enabled'] is False
157
    assert 'project_config_format' not in cc_cfg.keys()  # it was skipped
158
159
    assert cc_cfg['project_uses_existing_logging_facilities'] is True
160
    assert 'project_logging_enabled' not in cc_cfg.keys()  # it was skipped
161
    assert 'project_console_logging_enabled' not in cc_cfg.keys()  # it was skipped
162
    assert 'project_console_logging_level' not in cc_cfg.keys()  # it was skipped
163
    assert 'project_file_logging_enabled' not in cc_cfg.keys()  # it was skipped
164
    assert 'project_file_logging_level' not in cc_cfg.keys()  # it was skipped
165
    assert cc_cfg['github_username'] == 'eruber'
166
167
168
@pytest.mark.usefixtures('clean_system')
169
def test_load_context_defaults_skips_no_branch():
170
    """
171
    Test that if_no_skip_to and if_yes_skip_to do not branch and do not
172
    skip variables.
173
    """
174
    cc = load_cookiecutter('tests/test-context/cookiecutter_skips_2.json')
175
176
    cc_cfg = context.load_context(cc['cookiecutter_skips_2'], no_input=True)
177
178
    assert cc_cfg['project_configuration_enabled'] is True
179
    assert cc_cfg['project_config_format'] == 'toml'  # not skipped
180
181
    assert cc_cfg['project_uses_existing_logging_facilities'] is False
182
    assert cc_cfg['project_logging_enabled'] is True          # not skipped
183
    assert cc_cfg['project_console_logging_enabled'] is True  # not skipped
184
    assert cc_cfg['project_console_logging_level'] == 'WARN'  # not skipped
185
    assert cc_cfg['project_file_logging_enabled'] is True     # not skipped
186
187
    assert 'project_file_logging_level' not in cc_cfg.keys()  # do_if skipped
188
189
    assert cc_cfg['github_username'] == 'eruber'
190
191
192
@pytest.mark.usefixtures('clean_system')
193
def test_load_context_defaults_skips_unknown_variable_name_warning(caplog):
194
    """
195
    Test that a warning is issued if a variable.name specified in a skip_to
196
    directive is not in the variable list.
197
    """
198
    cc = load_cookiecutter('tests/test-context/cookiecutter_skips_3.json')
199
200
    cc_cfg = context.load_context(cc['cookiecutter_skips_3'], no_input=True)
201
202
    assert cc_cfg['project_uses_existing_logging_facilities'] is False
203
    assert 'project_logging_enabled' not in cc_cfg.keys()  # it was skipped
204
    assert 'project_console_logging_enabled' not in cc_cfg.keys()  # it was skipped
205
    assert 'project_console_logging_level' not in cc_cfg.keys()  # it was skipped
206
    assert 'project_file_logging_enabled' not in cc_cfg.keys()  # it was skipped
207
    assert 'project_file_logging_level' not in cc_cfg.keys()  # it was skipped
208
    assert 'github_username' not in cc_cfg.keys()  # it was skipped
209
210
    for record in caplog.records:
211
        assert record.levelname == 'WARNING'
212
213
    assert "Processed all variables, but skip_to_variable_name 'this_variable_name_is_not_in_the_list' was never found." in caplog.text
214
215
216 View Code Duplication
def test_prompt_string(mocker):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
217
218
    EXPECTED_VALUE = 'Input String'
219
220
    mock_prompt = mocker.patch(
221
        'cookiecutter.prompt.click.prompt',
222
        autospec=True,
223
        return_value=EXPECTED_VALUE,
224
    )
225
226
    m = mocker.Mock()
227
    m.side_effect = context.Variable
228
    v = m.side_effect(name='name', default='', prompt='Enter Name', hide_input=False)
229
230
    r = context.prompt_string(v, default='Alpha')
231
232
    assert mock_prompt.call_args == mocker.call(
233
        v.prompt,
234
        default='Alpha',
235
        hide_input=v.hide_input,
236
        type=click.STRING,
237
    )
238
239
    assert r == EXPECTED_VALUE
240
241
242
def test_prompt_bool(mocker):
243
244
    EXPECTED_VALUE = True
245
246
    mock_prompt = mocker.patch(
247
        'cookiecutter.prompt.click.prompt',
248
        autospec=True,
249
        return_value=EXPECTED_VALUE,
250
    )
251
252
    m = mocker.Mock()
253
    m.side_effect = context.Variable
254
    v = m.side_effect(name='flag', default=False, prompt='Enter a Flag', hide_input=False)
255
256
    r = context.prompt_boolean(v, default=False)
257
258
    assert mock_prompt.call_args == mocker.call(
259
        v.prompt,
260
        default=False,
261
        hide_input=v.hide_input,
262
        type=click.BOOL,
263
    )
264
265
    assert r           # EXPECTED_VALUE
266
267
268 View Code Duplication
def test_prompt_int(mocker):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
269
270
    EXPECTED_VALUE = 777
271
272
    mock_prompt = mocker.patch(
273
        'cookiecutter.prompt.click.prompt',
274
        autospec=True,
275
        return_value=EXPECTED_VALUE,
276
    )
277
278
    m = mocker.Mock()
279
    m.side_effect = context.Variable
280
    v = m.side_effect(name='port', default=1000, prompt='Enter Port', hide_input=False)
281
282
    r = context.prompt_int(v, default=1000)
283
284
    assert mock_prompt.call_args == mocker.call(
285
        v.prompt,
286
        default=1000,
287
        hide_input=v.hide_input,
288
        type=click.INT,
289
    )
290
291
    assert r == EXPECTED_VALUE
292
293
294 View Code Duplication
def test_prompt_float(mocker):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
295
296
    EXPECTED_VALUE = 3.14
297
298
    mock_prompt = mocker.patch(
299
        'cookiecutter.prompt.click.prompt',
300
        autospec=True,
301
        return_value=EXPECTED_VALUE,
302
    )
303
304
    m = mocker.Mock()
305
    m.side_effect = context.Variable
306
    v = m.side_effect(name='PI', default=3.0, prompt='Enter PI', hide_input=False)
307
308
    r = context.prompt_float(v, default=3.0)
309
310
    assert mock_prompt.call_args == mocker.call(
311
        v.prompt,
312
        default=3.0,
313
        hide_input=v.hide_input,
314
        type=click.FLOAT,
315
    )
316
317
    assert r == EXPECTED_VALUE
318
319
320 View Code Duplication
def test_prompt_uuid(mocker):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
321
322
    EXPECTED_VALUE = '931ef56c3e7b45eea0427bac386f0a98'
323
324
    mock_prompt = mocker.patch(
325
        'cookiecutter.prompt.click.prompt',
326
        autospec=True,
327
        return_value=EXPECTED_VALUE,
328
    )
329
330
    m = mocker.Mock()
331
    m.side_effect = context.Variable
332
    v = m.side_effect(name='uuid', default=None, prompt='Enter a UUID', hide_input=False)
333
334
    r = context.prompt_uuid(v, default=None)
335
336
    assert mock_prompt.call_args == mocker.call(
337
        v.prompt,
338
        default=None,
339
        hide_input=v.hide_input,
340
        type=click.UUID,
341
    )
342
343
    assert r == EXPECTED_VALUE
344
345
346
def test_prompt_json(monkeypatch, mocker):
347
348
    EXPECTED_VALUE = '{"port": 67888, "colors": ["red", "green", "blue"]}'
349
350
    mocker.patch(
351
        'click.termui.visible_prompt_func',
352
        autospec=True,
353
        return_value=EXPECTED_VALUE,
354
    )
355
    m = mocker.Mock()
356
    m.side_effect = context.Variable
357
    v = m.side_effect(name='json', default=None, prompt='Enter Config', hide_input=False)
358
359
    r = context.prompt_json(v, default=None)
360
361
    assert r == {"port": 67888, "colors": ["red", "green", "blue"]}
362
363
364 View Code Duplication
def test_prompt_json_bad_json_decode_click_asks_again(mocker, capsys):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
365
366
    EXPECTED_BAD_VALUE = '{"port": 67888, "colors": ["red", "green", "blue"}'
367
    EXPECTED_GOOD_VALUE = '{"port": 67888, "colors": ["red", "green", "blue"]}'
368
369
    mocker.patch(
370
        'click.termui.visible_prompt_func',
371
        autospec=True,
372
        side_effect=[EXPECTED_BAD_VALUE, EXPECTED_GOOD_VALUE]
373
    )
374
    m = mocker.Mock()
375
    m.side_effect = context.Variable
376
    v = m.side_effect(name='json', default=None, prompt='Enter Config', hide_input=False)
377
378
    r = context.prompt_json(v, default=None)
379
380
    out, err = capsys.readouterr()
381
    assert 'Error: Unable to decode to JSON.' in out
382
    assert r == {"port": 67888, "colors": ["red", "green", "blue"]}
383
384
385 View Code Duplication
def test_prompt_json_default(mocker):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
386
    EXPECTED_VALUE = 'default'
387
388
    cfg = '{"port": 67888, "colors": ["red", "green", "blue"]}'
389
390
    mock_prompt = mocker.patch(
391
        'cookiecutter.prompt.click.prompt',
392
        autospec=True,
393
        return_value=EXPECTED_VALUE,
394
    )
395
396
    m = mocker.Mock()
397
    m.side_effect = context.Variable
398
    v = m.side_effect(name='json', default=None, prompt='Enter Config', hide_input=False)
399
400
    r = context.prompt_json(v, default=cfg)
401
402
    assert mock_prompt.call_args == mocker.call(
403
        v.prompt,
404
        default='default',
405
        hide_input=v.hide_input,
406
        type=click.STRING,
407
        value_proc=mocker.ANY,
408
    )
409
410
    assert r == cfg
411
412
413
def test_prompt_yes_no_default_no(mocker):
414
415
    EXPECTED_VALUE = 'y'
416
417
    mock_prompt = mocker.patch(
418
        'cookiecutter.prompt.click.prompt',
419
        autospec=True,
420
        return_value=EXPECTED_VALUE,
421
    )
422
423
    m = mocker.Mock()
424
    m.side_effect = context.Variable
425
    v = m.side_effect(name='enable_docs', default='n', prompt='Enable docs', hide_input=False)
426
427
    r = context.prompt_yes_no(v, default=False)
428
429
    assert mock_prompt.call_args == mocker.call(
430
        v.prompt,
431
        default='n',
432
        hide_input=v.hide_input,
433
        type=click.BOOL,
434
    )
435
436
    assert r           # EXPECTED_VALUE
437
438
439
def test_prompt_yes_no_default_yes(mocker):
440
441
    EXPECTED_VALUE = 'y'
442
443
    mock_prompt = mocker.patch(
444
        'cookiecutter.prompt.click.prompt',
445
        autospec=True,
446
        return_value=EXPECTED_VALUE,
447
    )
448
449
    m = mocker.Mock()
450
    m.side_effect = context.Variable
451
    v = m.side_effect(name='enable_docs', default='y', prompt='Enable docs', hide_input=False)
452
453
    r = context.prompt_yes_no(v, default=True)
454
455
    assert mock_prompt.call_args == mocker.call(
456
        v.prompt,
457
        default='y',
458
        hide_input=v.hide_input,
459
        type=click.BOOL,
460
    )
461
462
    assert r           # EXPECTED_VALUE
463
464
465 View Code Duplication
def test_prompt_choice(mocker):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
466
467
    LICENSES = ['ISC', 'MIT', 'BSD3']
468
469
    DEFAULT_LICENSE = 'ISC'
470
471
    EXPECTED_VALUE = '2'
472
    EXPECTED_LICENSE = 'MIT'
473
474
    mocker.patch(
475
        'cookiecutter.prompt.click.prompt',
476
        autospec=True,
477
        return_value=EXPECTED_VALUE,
478
    )
479
480
    m = mocker.Mock()
481
    m.side_effect = context.Variable
482
    v = m.side_effect(name='license', default=DEFAULT_LICENSE, choices=LICENSES,
483
                      prompt='Pick a License', hide_input=False)
484
485
    r = context.prompt_choice(v, default=DEFAULT_LICENSE)
486
487
    assert r == EXPECTED_LICENSE
488
489
490
def test_variable_invalid_type_exception():
491
492
    with pytest.raises(ValueError) as excinfo:
493
        context.Variable(name='badtype', default=None, type='color')
494
495
    assert 'Variable: badtype has an invalid type color' in str(excinfo.value)
496
497
498
def test_variable_invalid_default_choice():
499
500
    CHOICES = ['green', 'red', 'blue', 'yellow']
501
502
    with pytest.raises(ValueError) as excinfo:
503
        context.Variable(name='badchoice', default='purple', type='string',
504
                         choices=CHOICES)
505
506
    assert 'Variable: badchoice has an invalid default value purple for choices: {choices}'.format(choices=CHOICES) in str(excinfo.value)
507
508
509
def test_variable_invalid_validation_control_flag_is_logged_and_removed(caplog):
510
511
    with caplog.at_level(logging.INFO):
512
        v = context.Variable(
513
            'module_name',
514
            "{{cookiecutter.plugin_name|lower|replace('-','_')}}",
515
            prompt="Please enter a name for your base python module",
516
            type='string',
517
            validation='^[a-z_]+$',
518
            validation_flags=['ignorecase', 'forget', ],
519
            hide_input=True)
520
521
        for record in caplog.records:
522
            assert record.levelname == 'WARNING'
523
524
        assert "Variable: module_name - Ignoring unkown RegEx validation Control Flag named 'forget'" in caplog.text
525
526
        assert v.validation_flag_names == ['ignorecase']
527
528
529
def test_variable_validation_compile_exception():
530
531
    VAR_NAME = 'module_name'
532
    BAD_REGEX_STRING = '^[a-z_+$'   # Missing a closing square-bracket (])
533
534
    with pytest.raises(ValueError) as excinfo:
535
        context.Variable(
536
            VAR_NAME,
537
            "{{cookiecutter.plugin_name|lower|replace('-','_')}}",
538
            prompt="Please enter a name for your base python module",
539
            type='string',
540
            validation=BAD_REGEX_STRING,
541
            validation_flags=['ignorecase'],
542
            hide_input=True)
543
544
    assert "Variable: {var_name} - Validation Setup Error: Invalid RegEx '{value}' - does not compile - ".format(var_name=VAR_NAME, value=BAD_REGEX_STRING) in str(excinfo.value)
545
546
547
def test_variable_forces_no_prompt_for_private_variable_names():
548
    v = context.Variable(
549
        '_private_variable_name',
550
        "{{cookiecutter.plugin_name|lower|replace('-','_')}}",
551
        prompt="Please enter a name for your base python module",
552
        prompt_user=True,
553
        type='string',
554
        validation='^[a-z_]+$',
555
        validation_flags=['ignorecase'],
556
        hide_input=True)
557
558
    assert v.prompt_user is False
559
560
561
def test_variable_repr():
562
563
    v = context.Variable(
564
        'module_name',
565
        "{{cookiecutter.plugin_name|lower|replace('-','_')}}",
566
        prompt="Please enter a name for your base python module",
567
        type='string',
568
        validation='^[a-z_]+$',
569
        validation_flags=['ignorecase'],
570
        hide_input=True)
571
572
    assert repr(v) == "<Variable module_name>"
573
574
575
def test_variable_str():
576
577
    v = context.Variable(
578
        'module_name',
579
        "{{cookiecutter.plugin_name|lower|replace('-','_')}}",
580
        prompt="Please enter a name for your base python module",
581
        type='string',
582
        validation='^[a-z_]+$',
583
        validation_flags=['ignorecase'],
584
        hide_input=True)
585
586
    assert '<Variable module_name>:' in str(v)
587
    assert "name='module_name'" in str(v)
588
    assert "default='{{cookiecutter.plugin_name|lower|replace('-','_')}}'" in str(v)
589
    assert "description='None'" in str(v)
590
    assert "prompt='Please enter a name for your base python module'" in str(v)
591
    assert "hide_input='True'" in str(v)
592
    assert "var_type='string'" in str(v)
593
    assert "skip_if=''" in str(v)
594
    assert "prompt_user='True'" in str(v)
595
    assert "choices='[]'" in str(v)
596
    assert "validation='^[a-z_]+$'" in str(v)
597
    assert "validation_flag_names='['ignorecase']'" in str(v)
598
    assert "validation_flags='2'" in str(v)
599
600
    if sys.version_info >= (3, 4):
601
        assert "validate='re.compile('^[a-z_]+$', re.IGNORECASE)'" in str(v)
602
    else:
603
        assert "validate='<_sre.SRE_Pattern object at" in str(v)
604
605
606
def test_variable_option_raise_invalid_type_value_error():
607
608
    VAR_NAME = 'module_name'
609
    OPT_VALUE_OF_INCORRECT_TYPE = 12   # should be a string
610
611
    with pytest.raises(ValueError) as excinfo:
612
        context.Variable(
613
            VAR_NAME,
614
            "{{cookiecutter.plugin_name|lower|replace('-','_')}}",
615
            prompt="Please enter a name for your base python module",
616
            type='string',
617
            validation=OPT_VALUE_OF_INCORRECT_TYPE,
618
            validation_flags=['ignorecase'],
619
            hide_input=True)
620
621
    msg = "Variable: '{var_name}' Option: 'validation' requires a value of type str, but has a value of: {value}"
622
    assert msg.format(var_name=VAR_NAME, value=OPT_VALUE_OF_INCORRECT_TYPE) in str(excinfo.value)
623
624
625
def test_cookiecutter_template_repr():
626
    #  name, cookiecutter_version, variables, **info
627
628
    cct = context.CookiecutterTemplate('cookiecutter_template_repr_test',
629
                                       cookiecutter_version='2.0.0', variables=[])
630
631
    assert repr(cct) == "<CookiecutterTemplate cookiecutter_template_repr_test>"
632
633
634 View Code Duplication
def test_load_context_with_input_chioces(mocker):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
635
    cc = load_cookiecutter('tests/test-context/cookiecutter_choices.json')
636
637
    INPUT_1 = 'E.R. Uber'
638
    INPUT_2 = '[email protected]'
639
    INPUT_3 = '2'  # 'MIT'
640
    mocker.patch(
641
        'click.termui.visible_prompt_func',
642
        autospec=True,
643
        side_effect=[INPUT_1, INPUT_2, INPUT_3]
644
    )
645
646
    cc_cfg = context.load_context(cc['cookiecutter_choices'], no_input=False)
647
648
    assert cc_cfg['full_name'] == INPUT_1
649
    assert cc_cfg['email'] == INPUT_2
650
    assert cc_cfg['license'] == 'MIT'
651
652
653 View Code Duplication
def test_load_context_with_input_with_validation_success(mocker):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
654
    cc = load_cookiecutter('tests/test-context/cookiecutter_val_success.json')
655
656
    INPUT_1 = 'Image Module Maker'
657
    INPUT_2 = ''
658
    mocker.patch(
659
        'click.termui.visible_prompt_func',
660
        autospec=True,
661
        side_effect=[INPUT_1, INPUT_2]
662
    )
663
664
    logger.debug(cc)
665
666
    cc_cfg = context.load_context(cc['cookiecutter_val_success'], no_input=False)
667
668
    assert cc_cfg['project_name'] == INPUT_1
669
    assert cc_cfg['module_name'] == 'image_module_maker'
670
671
672 View Code Duplication
def test_load_context_with_input_with_validation_failure(mocker, capsys):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
673
    cc = load_cookiecutter('tests/test-context/cookiecutter_val_failure.json')
674
675
    INPUT_1 = '6 Debug Shell'
676
    INPUT_2 = ''
677
    INPUT_3 = 'debug_shell'
678
    mocker.patch(
679
        'click.termui.visible_prompt_func',
680
        autospec=True,
681
        side_effect=[INPUT_1, INPUT_2, INPUT_3]
682
    )
683
684
    cc_cfg = context.load_context(cc['cookiecutter_val_failure'], no_input=False)
685
686
    out, err = capsys.readouterr()
687
688
    msg = "Input validation failure against regex: '^[a-z_]+$', try again!"
689
    assert msg in out
690
691
    assert cc_cfg['project_name'] == INPUT_1
692
    assert cc_cfg['module_name'] == INPUT_3
693
694
695 View Code Duplication
def test_load_context_with_input_with_validation_failure_msg(mocker, capsys):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
696
    cc = load_cookiecutter('tests/test-context/cookiecutter_val_failure_msg.json')
697
698
    INPUT_1 = '6 Debug Shell'
699
    INPUT_2 = ''
700
    INPUT_3 = 'debug_shell'
701
    mocker.patch(
702
        'click.termui.visible_prompt_func',
703
        autospec=True,
704
        side_effect=[INPUT_1, INPUT_2, INPUT_3]
705
    )
706
707
    cc_cfg = context.load_context(cc['cookiecutter_val_failure_msg'], no_input=False)
708
709
    out, err = capsys.readouterr()
710
711
    msg = "Input validation failure against regex: '^[a-z_]+$', try again!"
712
    assert msg in out
713
714
    msg2 = "Really, you couldn't get this correct the first time?"
715
    assert msg2 in out
716
717
    assert cc_cfg['project_name'] == INPUT_1
718
    assert cc_cfg['module_name'] == INPUT_3
719
720
721
def test_specify_if_yes_skip_to_without_yes_no_type():
722
    """
723
    Test ValueError is raised when a variable specifies an if_yes_skip_to
724
    field and the variable type is not 'yes+no'
725
    """
726
    with pytest.raises(ValueError) as excinfo:
727
        context.Variable(name='author', default='JKR', type='string',
728
                         if_yes_skip_to='roman')
729
730
    assert "Variable: 'author' specifies 'if_yes_skip_to' field, but variable not of type 'yes_no'" in str(excinfo.value)
731
732
733
def test_specify_if_no_skip_to_without_yes_no_type():
734
    """
735
    Test ValueError is raised when a variable specifies an if_no_skip_to
736
    field and the variable type is not 'yes+no'
737
    """
738
    with pytest.raises(ValueError) as excinfo:
739
        context.Variable(name='author', default='JKR', type='string',
740
                         if_no_skip_to='roman')
741
742
    assert "Variable: 'author' specifies 'if_no_skip_to' field, but variable not of type 'yes_no'" in str(excinfo.value)
743