tests.test_read_user_dict   A
last analyzed

Complexity

Total Complexity 13

Size/Duplication

Total Lines 127
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 13
eloc 55
dl 0
loc 127
rs 10
c 0
b 0
f 0

8 Functions

Rating   Name   Duplication   Size   Complexity  
A test_process_json_invalid_json() 0 6 2
A test_should_raise_type_error() 0 8 2
A test_process_json_deep_dict() 0 33 1
A test_process_json_non_dict() 0 6 2
A test_process_json_valid_json() 0 10 1
A test_should_call_prompt_with_process_json() 0 15 1
A test_read_user_dict_default_value() 0 11 2
A test_should_not_load_json_from_sentinel() 0 11 2
1
"""Test `process_json`, `read_user_dict` functions in `cookiecutter.prompt`."""
2
import click
3
import pytest
4
5
from cookiecutter.prompt import (
6
    process_json,
7
    read_user_dict,
8
)
9
10
11
def test_process_json_invalid_json():
12
    """Test `process_json` for correct error on malformed input."""
13
    with pytest.raises(click.UsageError) as exc_info:
14
        process_json('nope]')
15
16
    assert str(exc_info.value) == 'Unable to decode to JSON.'
17
18
19
def test_process_json_non_dict():
20
    """Test `process_json` for correct error on non-JSON input."""
21
    with pytest.raises(click.UsageError) as exc_info:
22
        process_json('[1, 2]')
23
24
    assert str(exc_info.value) == 'Requires JSON dict.'
25
26
27
def test_process_json_valid_json():
28
    """Test `process_json` for correct output on JSON input.
29
30
    Test for simple dict with list.
31
    """
32
    user_value = '{"name": "foobar", "bla": ["a", 1, "b", false]}'
33
34
    assert process_json(user_value) == {
35
        'name': 'foobar',
36
        'bla': ['a', 1, 'b', False],
37
    }
38
39
40
def test_process_json_deep_dict():
41
    """Test `process_json` for correct output on JSON input.
42
43
    Test for dict in dict case.
44
    """
45
    user_value = '''{
46
        "key": "value",
47
        "integer_key": 37,
48
        "dict_key": {
49
            "deep_key": "deep_value",
50
            "deep_integer": 42,
51
            "deep_list": [
52
                "deep value 1",
53
                "deep value 2",
54
                "deep value 3"
55
            ]
56
        },
57
        "list_key": [
58
            "value 1",
59
            "value 2",
60
            "value 3"
61
        ]
62
    }'''
63
64
    assert process_json(user_value) == {
65
        "key": "value",
66
        "integer_key": 37,
67
        "dict_key": {
68
            "deep_key": "deep_value",
69
            "deep_integer": 42,
70
            "deep_list": ["deep value 1", "deep value 2", "deep value 3"],
71
        },
72
        "list_key": ["value 1", "value 2", "value 3"],
73
    }
74
75
76
def test_should_raise_type_error(mocker):
77
    """Test `default_value` arg verification in `read_user_dict` function."""
78
    prompt = mocker.patch('cookiecutter.prompt.click.prompt')
79
80
    with pytest.raises(TypeError):
81
        read_user_dict('name', 'russell')
82
83
    assert not prompt.called
84
85
86
def test_should_call_prompt_with_process_json(mocker):
87
    """Test to make sure that `process_json` is actually being used.
88
89
    Verifies generation of a processor for the user input.
90
    """
91
    mock_prompt = mocker.patch('cookiecutter.prompt.click.prompt', autospec=True)
92
93
    read_user_dict('name', {'project_slug': 'pytest-plugin'})
94
95
    args, kwargs = mock_prompt.call_args
96
97
    assert args == ('name',)
98
    assert kwargs['type'] == click.STRING
99
    assert kwargs['default'] == 'default'
100
    assert kwargs['value_proc'].func == process_json
101
102
103
def test_should_not_load_json_from_sentinel(mocker):
104
    """Make sure that `json.loads` is not called when using default value."""
105
    mock_json_loads = mocker.patch(
106
        'cookiecutter.prompt.json.loads', autospec=True, return_value={}
107
    )
108
109
    runner = click.testing.CliRunner()
110
    with runner.isolation(input="\n"):
111
        read_user_dict('name', {'project_slug': 'pytest-plugin'})
112
113
    mock_json_loads.assert_not_called()
114
115
116
@pytest.mark.parametrize("input", ["\n", "default\n"])
117
def test_read_user_dict_default_value(mocker, input):
118
    """Make sure that `read_user_dict` returns the default value.
119
120
    Verify return of a dict variable rather than the display value.
121
    """
122
    runner = click.testing.CliRunner()
123
    with runner.isolation(input=input):
124
        val = read_user_dict('name', {'project_slug': 'pytest-plugin'})
125
126
    assert val == {'project_slug': 'pytest-plugin'}
127