File: test_read_user_dict.py

package info (click to toggle)
cookiecutter 2.6.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,780 kB
  • sloc: python: 6,097; makefile: 113; sh: 8
file content (130 lines) | stat: -rw-r--r-- 3,901 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
"""Test `process_json`, `read_user_dict` functions in `cookiecutter.prompt`."""

import click
import pytest
from rich.prompt import InvalidResponse

from cookiecutter.prompt import JsonPrompt, process_json, read_user_dict


def test_process_json_invalid_json():
    """Test `process_json` for correct error on malformed input."""
    with pytest.raises(InvalidResponse) as exc_info:
        process_json('nope]')

    assert str(exc_info.value) == 'Unable to decode to JSON.'


def test_process_json_non_dict():
    """Test `process_json` for correct error on non-JSON input."""
    with pytest.raises(InvalidResponse) as exc_info:
        process_json('[1, 2]')

    assert str(exc_info.value) == 'Requires JSON dict.'


def test_process_json_valid_json():
    """Test `process_json` for correct output on JSON input.

    Test for simple dict with list.
    """
    user_value = '{"name": "foobar", "bla": ["a", 1, "b", false]}'

    assert process_json(user_value) == {
        'name': 'foobar',
        'bla': ['a', 1, 'b', False],
    }


def test_process_json_deep_dict():
    """Test `process_json` for correct output on JSON input.

    Test for dict in dict case.
    """
    user_value = '''{
        "key": "value",
        "integer_key": 37,
        "dict_key": {
            "deep_key": "deep_value",
            "deep_integer": 42,
            "deep_list": [
                "deep value 1",
                "deep value 2",
                "deep value 3"
            ]
        },
        "list_key": [
            "value 1",
            "value 2",
            "value 3"
        ]
    }'''

    assert process_json(user_value) == {
        "key": "value",
        "integer_key": 37,
        "dict_key": {
            "deep_key": "deep_value",
            "deep_integer": 42,
            "deep_list": ["deep value 1", "deep value 2", "deep value 3"],
        },
        "list_key": ["value 1", "value 2", "value 3"],
    }


def test_should_raise_type_error(mocker):
    """Test `default_value` arg verification in `read_user_dict` function."""
    prompt = mocker.patch('cookiecutter.prompt.JsonPrompt.ask')

    with pytest.raises(TypeError):
        read_user_dict('name', 'russell')
    assert not prompt.called


def test_should_call_prompt_with_process_json(mocker):
    """Test to make sure that `process_json` is actually being used.

    Verifies generation of a processor for the user input.
    """
    mock_prompt = mocker.patch('cookiecutter.prompt.JsonPrompt.ask', autospec=True)

    read_user_dict('name', {'project_slug': 'pytest-plugin'})
    print(mock_prompt.call_args)
    args, kwargs = mock_prompt.call_args

    assert args == ('name [cyan bold](default)[/]',)
    assert kwargs['default'] == {'project_slug': 'pytest-plugin'}


def test_should_not_load_json_from_sentinel(mocker):
    """Make sure that `json.loads` is not called when using default value."""
    mock_json_loads = mocker.patch(
        'cookiecutter.prompt.json.loads', autospec=True, return_value={}
    )

    runner = click.testing.CliRunner()
    with runner.isolation(input="\n"):
        read_user_dict('name', {'project_slug': 'pytest-plugin'})

    mock_json_loads.assert_not_called()


@pytest.mark.parametrize("input", ["\n", "\ndefault\n"])
def test_read_user_dict_default_value(mocker, input):
    """Make sure that `read_user_dict` returns the default value.

    Verify return of a dict variable rather than the display value.
    """
    runner = click.testing.CliRunner()
    with runner.isolation(input=input):
        val = read_user_dict('name', {'project_slug': 'pytest-plugin'})

    assert val == {'project_slug': 'pytest-plugin'}


def test_json_prompt_process_response():
    """Test `JsonPrompt` process_response to convert str to json."""
    jp = JsonPrompt()
    assert jp.process_response('{"project_slug": "something"}') == {
        'project_slug': 'something'
    }