back to SWE-Agent summary
SWE-Agent: cookiecutter
Pytest Summary for test tests
status |
count |
failed |
325 |
passed |
16 |
error |
26 |
skipped |
4 |
total |
371 |
collected |
371 |
Failed pytests:
test_dump.py::test_type_error_if_no_template_name
test_dump.py::test_type_error_if_no_template_name
replay_test_dir = 'tests/test-replay/'
context = {'cookiecutter': {'email': 'raphael@hackebrot.de', 'full_name': 'Raphael Pierzina', 'github_username': 'hackebrot', 'version': '0.1.0'}}
def test_type_error_if_no_template_name(replay_test_dir, context):
"""Test that replay.dump raises if the template_name is not a valid str."""
> with pytest.raises(TypeError):
E Failed: DID NOT RAISE
tests/replay/test_dump.py:37: Failed
test_dump.py::test_type_error_if_not_dict_context
test_dump.py::test_type_error_if_not_dict_context
replay_test_dir = 'tests/test-replay/', template_name = 'cookiedozer'
def test_type_error_if_not_dict_context(replay_test_dir, template_name):
"""Test that replay.dump raises if the context is not of type dict."""
> with pytest.raises(TypeError):
E Failed: DID NOT RAISE
tests/replay/test_dump.py:43: Failed
test_dump.py::test_value_error_if_key_missing_in_context
test_dump.py::test_value_error_if_key_missing_in_context
replay_test_dir = 'tests/test-replay/', template_name = 'cookiedozer'
def test_value_error_if_key_missing_in_context(replay_test_dir, template_name):
"""Test that replay.dump raises if the context does not contain a key \
named 'cookiecutter'."""
> with pytest.raises(ValueError):
E Failed: DID NOT RAISE
tests/replay/test_dump.py:50: Failed
test_dump.py::test_ioerror_if_replay_dir_creation_fails
test_dump.py::test_ioerror_if_replay_dir_creation_fails
mock_ensure_failure =
replay_test_dir = 'tests/test-replay/'
def test_ioerror_if_replay_dir_creation_fails(mock_ensure_failure, replay_test_dir):
"""Test that replay.dump raises when the replay_dir cannot be created."""
> with pytest.raises(OSError):
E Failed: DID NOT RAISE
tests/replay/test_dump.py:78: Failed
test_dump.py::test_run_json_dump
test_dump.py::test_run_json_dump
self =
args = ('tests/test-replay/',), kwargs = {}
msg = "Expected 'make_sure_path_exists' to be called once. Called 0 times."
def assert_called_once_with(self, /, *args, **kwargs):
"""assert that the mock was called exactly once and that that call was
with the specified arguments."""
if not self.call_count == 1:
msg = ("Expected '%s' to be called once. Called %s times.%s"
% (self._mock_name or 'mock',
self.call_count,
self._calls_repr()))
> raise AssertionError(msg)
E AssertionError: Expected 'make_sure_path_exists' to be called once. Called 0 times.
/usr/lib/python3.10/unittest/mock.py:940: AssertionError
During handling of the above exception, another exception occurred:
mocker =
mock_ensure_success =
mock_user_config =
template_name = 'cookiedozer'
context = {'cookiecutter': {'email': 'raphael@hackebrot.de', 'full_name': 'Raphael Pierzina', 'github_username': 'hackebrot', 'version': '0.1.0'}}
replay_test_dir = 'tests/test-replay/'
replay_file = 'tests/test-replay/cookiedozer.json'
def test_run_json_dump(
mocker,
mock_ensure_success,
mock_user_config,
template_name,
context,
replay_test_dir,
replay_file,
):
"""Test that replay.dump runs json.dump under the hood and that the context \
is correctly written to the expected file in the replay_dir."""
spy_get_replay_file = mocker.spy(replay, 'get_file_name')
mock_json_dump = mocker.patch('json.dump', side_effect=json.dump)
replay.dump(replay_test_dir, template_name, context)
assert not mock_user_config.called
> mock_ensure_success.assert_called_once_with(replay_test_dir)
E AssertionError: Expected 'make_sure_path_exists' to be called once. Called 0 times.
tests/replay/test_dump.py:102: AssertionError
test_load.py::test_type_error_if_no_template_name
test_load.py::test_type_error_if_no_template_name
replay_test_dir = 'tests/test-replay/'
def test_type_error_if_no_template_name(replay_test_dir):
"""Test that replay.load raises if the template_name is not a valid str."""
> with pytest.raises(TypeError):
E Failed: DID NOT RAISE
tests/replay/test_load.py:26: Failed
test_load.py::test_value_error_if_key_missing_in_context
test_load.py::test_value_error_if_key_missing_in_context
mocker =
replay_test_dir = 'tests/test-replay/'
def test_value_error_if_key_missing_in_context(mocker, replay_test_dir):
"""Test that replay.load raises if the loaded context does not contain \
'cookiecutter'."""
> with pytest.raises(ValueError):
E Failed: DID NOT RAISE
tests/replay/test_load.py:33: Failed
test_load.py::test_io_error_if_no_replay_file
test_load.py::test_io_error_if_no_replay_file
mocker =
replay_test_dir = 'tests/test-replay/'
def test_io_error_if_no_replay_file(mocker, replay_test_dir):
"""Test that replay.load raises if it cannot find a replay file."""
> with pytest.raises(IOError):
E Failed: DID NOT RAISE
tests/replay/test_load.py:39: Failed
test_load.py::test_run_json_load
test_load.py::test_run_json_load
self =
args = ('tests/test-replay/', 'cookiedozer_load'), kwargs = {}
msg = "Expected 'get_file_name' to be called once. Called 0 times."
def assert_called_once_with(self, /, *args, **kwargs):
"""assert that the mock was called exactly once and that that call was
with the specified arguments."""
if not self.call_count == 1:
msg = ("Expected '%s' to be called once. Called %s times.%s"
% (self._mock_name or 'mock',
self.call_count,
self._calls_repr()))
> raise AssertionError(msg)
E AssertionError: Expected 'get_file_name' to be called once. Called 0 times.
/usr/lib/python3.10/unittest/mock.py:940: AssertionError
During handling of the above exception, another exception occurred:
mocker =
mock_user_config =
template_name = 'cookiedozer_load'
context = {'cookiecutter': {'email': 'raphael@hackebrot.de', 'full_name': 'Raphael Pierzina', 'github_username': 'hackebrot', 'version': '0.1.0'}}
replay_test_dir = 'tests/test-replay/'
replay_file = 'tests/test-replay/cookiedozer_load.json'
def test_run_json_load(
mocker, mock_user_config, template_name, context, replay_test_dir, replay_file
):
"""Test that replay.load runs json.load under the hood and that the context \
is correctly loaded from the file in replay_dir."""
spy_get_replay_file = mocker.spy(replay, 'get_file_name')
mock_json_load = mocker.patch('json.load', side_effect=json.load)
loaded_context = replay.load(replay_test_dir, template_name)
assert not mock_user_config.called
> spy_get_replay_file.assert_called_once_with(replay_test_dir, template_name)
tests/replay/test_load.py:55:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
args = ('tests/test-replay/', 'cookiedozer_load'), kwargs = {}
def assert_called_once_with(*args, **kwargs):
> return mock.assert_called_once_with(*args, **kwargs)
E AssertionError: Expected 'get_file_name' to be called once. Called 0 times.
/usr/lib/python3.10/unittest/mock.py:213: AssertionError
test_replay.py::test_get_replay_file_name[bar]
test_replay.py::test_get_replay_file_name[bar]
replay_file_name = 'bar'
@pytest.mark.parametrize("replay_file_name", ['bar', 'bar.json'])
def test_get_replay_file_name(replay_file_name):
"""Make sure that replay.get_file_name generates a valid json file path."""
exp_replay_file_path = os.path.join('foo', 'bar.json')
replay_file_path = replay.get_file_name('foo', replay_file_name)
> assert replay_file_path == exp_replay_file_path
E AssertionError: assert None == 'foo/bar.json'
tests/replay/test_replay.py:15: AssertionError
test_replay.py::test_get_replay_file_name[bar.json]
test_replay.py::test_get_replay_file_name[bar.json]
replay_file_name = 'bar.json'
@pytest.mark.parametrize("replay_file_name", ['bar', 'bar.json'])
def test_get_replay_file_name(replay_file_name):
"""Make sure that replay.get_file_name generates a valid json file path."""
exp_replay_file_path = os.path.join('foo', 'bar.json')
replay_file_path = replay.get_file_name('foo', replay_file_name)
> assert replay_file_path == exp_replay_file_path
E AssertionError: assert None == 'foo/bar.json'
tests/replay/test_replay.py:15: AssertionError
test_replay.py::test_raise_on_invalid_mode[invalid_kwargs0]
test_replay.py::test_raise_on_invalid_mode[invalid_kwargs0]
invalid_kwargs = {'no_input': True}
@pytest.mark.parametrize(
'invalid_kwargs',
(
{'no_input': True},
{'extra_context': {}},
{'no_input': True, 'extra_context': {}},
),
)
def test_raise_on_invalid_mode(invalid_kwargs):
"""Test `cookiecutter` raise exception on unacceptable `replay` request."""
> with pytest.raises(exceptions.InvalidModeException):
E Failed: DID NOT RAISE
tests/replay/test_replay.py:28: Failed
test_replay.py::test_raise_on_invalid_mode[invalid_kwargs1]
test_replay.py::test_raise_on_invalid_mode[invalid_kwargs1]
invalid_kwargs = {'extra_context': {}}
@pytest.mark.parametrize(
'invalid_kwargs',
(
{'no_input': True},
{'extra_context': {}},
{'no_input': True, 'extra_context': {}},
),
)
def test_raise_on_invalid_mode(invalid_kwargs):
"""Test `cookiecutter` raise exception on unacceptable `replay` request."""
> with pytest.raises(exceptions.InvalidModeException):
E Failed: DID NOT RAISE
tests/replay/test_replay.py:28: Failed
test_replay.py::test_raise_on_invalid_mode[invalid_kwargs2]
test_replay.py::test_raise_on_invalid_mode[invalid_kwargs2]
invalid_kwargs = {'extra_context': {}, 'no_input': True}
@pytest.mark.parametrize(
'invalid_kwargs',
(
{'no_input': True},
{'extra_context': {}},
{'no_input': True, 'extra_context': {}},
),
)
def test_raise_on_invalid_mode(invalid_kwargs):
"""Test `cookiecutter` raise exception on unacceptable `replay` request."""
> with pytest.raises(exceptions.InvalidModeException):
E Failed: DID NOT RAISE
tests/replay/test_replay.py:28: Failed
test_replay.py::test_main_does_not_invoke_dump_but_load
test_replay.py::test_main_does_not_invoke_dump_but_load
mocker =
def test_main_does_not_invoke_dump_but_load(mocker):
"""Test `cookiecutter` calling correct functions on `replay`."""
mock_prompt = mocker.patch('cookiecutter.main.prompt_for_config')
mock_gen_context = mocker.patch('cookiecutter.main.generate_context')
mock_gen_files = mocker.patch('cookiecutter.main.generate_files')
mock_replay_dump = mocker.patch('cookiecutter.main.dump')
mock_replay_load = mocker.patch('cookiecutter.main.load')
main.cookiecutter('tests/fake-repo-tmpl/', replay=True)
assert not mock_prompt.called
> assert mock_gen_context.called
E AssertionError: assert False
E + where False = .called
tests/replay/test_replay.py:43: AssertionError
test_replay.py::test_main_does_not_invoke_load_but_dump
test_replay.py::test_main_does_not_invoke_load_but_dump
mocker =
def test_main_does_not_invoke_load_but_dump(mocker):
"""Test `cookiecutter` calling correct functions on non-replay launch."""
mock_prompt = mocker.patch('cookiecutter.main.prompt_for_config')
mock_gen_context = mocker.patch('cookiecutter.main.generate_context')
mock_gen_files = mocker.patch('cookiecutter.main.generate_files')
mock_replay_dump = mocker.patch('cookiecutter.main.dump')
mock_replay_load = mocker.patch('cookiecutter.main.load')
main.cookiecutter('tests/fake-repo-tmpl/', replay=False)
> assert mock_prompt.called
E AssertionError: assert False
E + where False = .called
tests/replay/test_replay.py:59: AssertionError
test_abbreviation_expansion.py::test_abbreviation_expansion[Simple expansion]
test_abbreviation_expansion.py::test_abbreviation_expansion[Simple expansion]
template = 'foo', abbreviations = {'foo': 'bar'}, expected_result = 'bar'
@pytest.mark.parametrize(
('template', 'abbreviations', 'expected_result'),
[
('foo', {'foo': 'bar'}, 'bar'),
('baz', {'foo': 'bar'}, 'baz'),
('xx:a', {'xx': '<{0}>'}, ''),
('gh:a', {'gh': '<{0}>'}, ''),
('xx:a', {'xx': '<>'}, '<>'),
(
'gh:pydanny/cookiecutter-django',
BUILTIN_ABBREVIATIONS,
'https://github.com/pydanny/cookiecutter-django.git',
),
(
'gl:pydanny/cookiecutter-django',
BUILTIN_ABBREVIATIONS,
'https://gitlab.com/pydanny/cookiecutter-django.git',
),
(
'bb:pydanny/cookiecutter-django',
BUILTIN_ABBREVIATIONS,
'https://bitbucket.org/pydanny/cookiecutter-django',
),
],
ids=(
'Simple expansion',
'Skip expansion (expansion not an abbreviation)',
'Expansion prefix',
'expansion_override_builtin',
'expansion_prefix_ignores_suffix',
'Correct expansion for builtin abbreviations (github)',
'Correct expansion for builtin abbreviations (gitlab)',
'Correct expansion for builtin abbreviations (bitbucket)',
),
)
def test_abbreviation_expansion(template, abbreviations, expected_result):
"""Verify abbreviation unpacking."""
expanded = expand_abbreviations(template, abbreviations)
> assert expanded == expected_result
E AssertionError: assert None == 'bar'
tests/repository/test_abbreviation_expansion.py:47: AssertionError
test_abbreviation_expansion.py::test_abbreviation_expansion[Skip expansion (expansion not an abbreviation)]
test_abbreviation_expansion.py::test_abbreviation_expansion[Skip expansion (expansion not an abbreviation)]
template = 'baz', abbreviations = {'foo': 'bar'}, expected_result = 'baz'
@pytest.mark.parametrize(
('template', 'abbreviations', 'expected_result'),
[
('foo', {'foo': 'bar'}, 'bar'),
('baz', {'foo': 'bar'}, 'baz'),
('xx:a', {'xx': '<{0}>'}, ''),
('gh:a', {'gh': '<{0}>'}, ''),
('xx:a', {'xx': '<>'}, '<>'),
(
'gh:pydanny/cookiecutter-django',
BUILTIN_ABBREVIATIONS,
'https://github.com/pydanny/cookiecutter-django.git',
),
(
'gl:pydanny/cookiecutter-django',
BUILTIN_ABBREVIATIONS,
'https://gitlab.com/pydanny/cookiecutter-django.git',
),
(
'bb:pydanny/cookiecutter-django',
BUILTIN_ABBREVIATIONS,
'https://bitbucket.org/pydanny/cookiecutter-django',
),
],
ids=(
'Simple expansion',
'Skip expansion (expansion not an abbreviation)',
'Expansion prefix',
'expansion_override_builtin',
'expansion_prefix_ignores_suffix',
'Correct expansion for builtin abbreviations (github)',
'Correct expansion for builtin abbreviations (gitlab)',
'Correct expansion for builtin abbreviations (bitbucket)',
),
)
def test_abbreviation_expansion(template, abbreviations, expected_result):
"""Verify abbreviation unpacking."""
expanded = expand_abbreviations(template, abbreviations)
> assert expanded == expected_result
E AssertionError: assert None == 'baz'
tests/repository/test_abbreviation_expansion.py:47: AssertionError
test_abbreviation_expansion.py::test_abbreviation_expansion[Expansion prefix]
test_abbreviation_expansion.py::test_abbreviation_expansion[Expansion prefix]
template = 'xx:a', abbreviations = {'xx': '<{0}>'}, expected_result = ''
@pytest.mark.parametrize(
('template', 'abbreviations', 'expected_result'),
[
('foo', {'foo': 'bar'}, 'bar'),
('baz', {'foo': 'bar'}, 'baz'),
('xx:a', {'xx': '<{0}>'}, ''),
('gh:a', {'gh': '<{0}>'}, ''),
('xx:a', {'xx': '<>'}, '<>'),
(
'gh:pydanny/cookiecutter-django',
BUILTIN_ABBREVIATIONS,
'https://github.com/pydanny/cookiecutter-django.git',
),
(
'gl:pydanny/cookiecutter-django',
BUILTIN_ABBREVIATIONS,
'https://gitlab.com/pydanny/cookiecutter-django.git',
),
(
'bb:pydanny/cookiecutter-django',
BUILTIN_ABBREVIATIONS,
'https://bitbucket.org/pydanny/cookiecutter-django',
),
],
ids=(
'Simple expansion',
'Skip expansion (expansion not an abbreviation)',
'Expansion prefix',
'expansion_override_builtin',
'expansion_prefix_ignores_suffix',
'Correct expansion for builtin abbreviations (github)',
'Correct expansion for builtin abbreviations (gitlab)',
'Correct expansion for builtin abbreviations (bitbucket)',
),
)
def test_abbreviation_expansion(template, abbreviations, expected_result):
"""Verify abbreviation unpacking."""
expanded = expand_abbreviations(template, abbreviations)
> assert expanded == expected_result
E AssertionError: assert None == ''
tests/repository/test_abbreviation_expansion.py:47: AssertionError
test_abbreviation_expansion.py::test_abbreviation_expansion[expansion_override_builtin]
test_abbreviation_expansion.py::test_abbreviation_expansion[expansion_override_builtin]
template = 'gh:a', abbreviations = {'gh': '<{0}>'}, expected_result = ''
@pytest.mark.parametrize(
('template', 'abbreviations', 'expected_result'),
[
('foo', {'foo': 'bar'}, 'bar'),
('baz', {'foo': 'bar'}, 'baz'),
('xx:a', {'xx': '<{0}>'}, ''),
('gh:a', {'gh': '<{0}>'}, ''),
('xx:a', {'xx': '<>'}, '<>'),
(
'gh:pydanny/cookiecutter-django',
BUILTIN_ABBREVIATIONS,
'https://github.com/pydanny/cookiecutter-django.git',
),
(
'gl:pydanny/cookiecutter-django',
BUILTIN_ABBREVIATIONS,
'https://gitlab.com/pydanny/cookiecutter-django.git',
),
(
'bb:pydanny/cookiecutter-django',
BUILTIN_ABBREVIATIONS,
'https://bitbucket.org/pydanny/cookiecutter-django',
),
],
ids=(
'Simple expansion',
'Skip expansion (expansion not an abbreviation)',
'Expansion prefix',
'expansion_override_builtin',
'expansion_prefix_ignores_suffix',
'Correct expansion for builtin abbreviations (github)',
'Correct expansion for builtin abbreviations (gitlab)',
'Correct expansion for builtin abbreviations (bitbucket)',
),
)
def test_abbreviation_expansion(template, abbreviations, expected_result):
"""Verify abbreviation unpacking."""
expanded = expand_abbreviations(template, abbreviations)
> assert expanded == expected_result
E AssertionError: assert None == ''
tests/repository/test_abbreviation_expansion.py:47: AssertionError
test_abbreviation_expansion.py::test_abbreviation_expansion[expansion_prefix_ignores_suffix]
test_abbreviation_expansion.py::test_abbreviation_expansion[expansion_prefix_ignores_suffix]
template = 'xx:a', abbreviations = {'xx': '<>'}, expected_result = '<>'
@pytest.mark.parametrize(
('template', 'abbreviations', 'expected_result'),
[
('foo', {'foo': 'bar'}, 'bar'),
('baz', {'foo': 'bar'}, 'baz'),
('xx:a', {'xx': '<{0}>'}, ''),
('gh:a', {'gh': '<{0}>'}, ''),
('xx:a', {'xx': '<>'}, '<>'),
(
'gh:pydanny/cookiecutter-django',
BUILTIN_ABBREVIATIONS,
'https://github.com/pydanny/cookiecutter-django.git',
),
(
'gl:pydanny/cookiecutter-django',
BUILTIN_ABBREVIATIONS,
'https://gitlab.com/pydanny/cookiecutter-django.git',
),
(
'bb:pydanny/cookiecutter-django',
BUILTIN_ABBREVIATIONS,
'https://bitbucket.org/pydanny/cookiecutter-django',
),
],
ids=(
'Simple expansion',
'Skip expansion (expansion not an abbreviation)',
'Expansion prefix',
'expansion_override_builtin',
'expansion_prefix_ignores_suffix',
'Correct expansion for builtin abbreviations (github)',
'Correct expansion for builtin abbreviations (gitlab)',
'Correct expansion for builtin abbreviations (bitbucket)',
),
)
def test_abbreviation_expansion(template, abbreviations, expected_result):
"""Verify abbreviation unpacking."""
expanded = expand_abbreviations(template, abbreviations)
> assert expanded == expected_result
E AssertionError: assert None == '<>'
tests/repository/test_abbreviation_expansion.py:47: AssertionError
test_abbreviation_expansion.py::test_abbreviation_expansion[Correct expansion for builtin abbreviations (github)]
test_abbreviation_expansion.py::test_abbreviation_expansion[Correct expansion for builtin abbreviations (github)]
template = 'gh:pydanny/cookiecutter-django'
abbreviations = {'bb': 'https://bitbucket.org/{0}', 'gh': 'https://github.com/{0}.git', 'gl': 'https://gitlab.com/{0}.git'}
expected_result = 'https://github.com/pydanny/cookiecutter-django.git'
@pytest.mark.parametrize(
('template', 'abbreviations', 'expected_result'),
[
('foo', {'foo': 'bar'}, 'bar'),
('baz', {'foo': 'bar'}, 'baz'),
('xx:a', {'xx': '<{0}>'}, ''),
('gh:a', {'gh': '<{0}>'}, ''),
('xx:a', {'xx': '<>'}, '<>'),
(
'gh:pydanny/cookiecutter-django',
BUILTIN_ABBREVIATIONS,
'https://github.com/pydanny/cookiecutter-django.git',
),
(
'gl:pydanny/cookiecutter-django',
BUILTIN_ABBREVIATIONS,
'https://gitlab.com/pydanny/cookiecutter-django.git',
),
(
'bb:pydanny/cookiecutter-django',
BUILTIN_ABBREVIATIONS,
'https://bitbucket.org/pydanny/cookiecutter-django',
),
],
ids=(
'Simple expansion',
'Skip expansion (expansion not an abbreviation)',
'Expansion prefix',
'expansion_override_builtin',
'expansion_prefix_ignores_suffix',
'Correct expansion for builtin abbreviations (github)',
'Correct expansion for builtin abbreviations (gitlab)',
'Correct expansion for builtin abbreviations (bitbucket)',
),
)
def test_abbreviation_expansion(template, abbreviations, expected_result):
"""Verify abbreviation unpacking."""
expanded = expand_abbreviations(template, abbreviations)
> assert expanded == expected_result
E AssertionError: assert None == 'https://github.com/pydanny/cookiecutter-django.git'
tests/repository/test_abbreviation_expansion.py:47: AssertionError
test_abbreviation_expansion.py::test_abbreviation_expansion[Correct expansion for builtin abbreviations (gitlab)]
test_abbreviation_expansion.py::test_abbreviation_expansion[Correct expansion for builtin abbreviations (gitlab)]
template = 'gl:pydanny/cookiecutter-django'
abbreviations = {'bb': 'https://bitbucket.org/{0}', 'gh': 'https://github.com/{0}.git', 'gl': 'https://gitlab.com/{0}.git'}
expected_result = 'https://gitlab.com/pydanny/cookiecutter-django.git'
@pytest.mark.parametrize(
('template', 'abbreviations', 'expected_result'),
[
('foo', {'foo': 'bar'}, 'bar'),
('baz', {'foo': 'bar'}, 'baz'),
('xx:a', {'xx': '<{0}>'}, ''),
('gh:a', {'gh': '<{0}>'}, ''),
('xx:a', {'xx': '<>'}, '<>'),
(
'gh:pydanny/cookiecutter-django',
BUILTIN_ABBREVIATIONS,
'https://github.com/pydanny/cookiecutter-django.git',
),
(
'gl:pydanny/cookiecutter-django',
BUILTIN_ABBREVIATIONS,
'https://gitlab.com/pydanny/cookiecutter-django.git',
),
(
'bb:pydanny/cookiecutter-django',
BUILTIN_ABBREVIATIONS,
'https://bitbucket.org/pydanny/cookiecutter-django',
),
],
ids=(
'Simple expansion',
'Skip expansion (expansion not an abbreviation)',
'Expansion prefix',
'expansion_override_builtin',
'expansion_prefix_ignores_suffix',
'Correct expansion for builtin abbreviations (github)',
'Correct expansion for builtin abbreviations (gitlab)',
'Correct expansion for builtin abbreviations (bitbucket)',
),
)
def test_abbreviation_expansion(template, abbreviations, expected_result):
"""Verify abbreviation unpacking."""
expanded = expand_abbreviations(template, abbreviations)
> assert expanded == expected_result
E AssertionError: assert None == 'https://gitlab.com/pydanny/cookiecutter-django.git'
tests/repository/test_abbreviation_expansion.py:47: AssertionError
test_abbreviation_expansion.py::test_abbreviation_expansion[Correct expansion for builtin abbreviations (bitbucket)]
test_abbreviation_expansion.py::test_abbreviation_expansion[Correct expansion for builtin abbreviations (bitbucket)]
template = 'bb:pydanny/cookiecutter-django'
abbreviations = {'bb': 'https://bitbucket.org/{0}', 'gh': 'https://github.com/{0}.git', 'gl': 'https://gitlab.com/{0}.git'}
expected_result = 'https://bitbucket.org/pydanny/cookiecutter-django'
@pytest.mark.parametrize(
('template', 'abbreviations', 'expected_result'),
[
('foo', {'foo': 'bar'}, 'bar'),
('baz', {'foo': 'bar'}, 'baz'),
('xx:a', {'xx': '<{0}>'}, ''),
('gh:a', {'gh': '<{0}>'}, ''),
('xx:a', {'xx': '<>'}, '<>'),
(
'gh:pydanny/cookiecutter-django',
BUILTIN_ABBREVIATIONS,
'https://github.com/pydanny/cookiecutter-django.git',
),
(
'gl:pydanny/cookiecutter-django',
BUILTIN_ABBREVIATIONS,
'https://gitlab.com/pydanny/cookiecutter-django.git',
),
(
'bb:pydanny/cookiecutter-django',
BUILTIN_ABBREVIATIONS,
'https://bitbucket.org/pydanny/cookiecutter-django',
),
],
ids=(
'Simple expansion',
'Skip expansion (expansion not an abbreviation)',
'Expansion prefix',
'expansion_override_builtin',
'expansion_prefix_ignores_suffix',
'Correct expansion for builtin abbreviations (github)',
'Correct expansion for builtin abbreviations (gitlab)',
'Correct expansion for builtin abbreviations (bitbucket)',
),
)
def test_abbreviation_expansion(template, abbreviations, expected_result):
"""Verify abbreviation unpacking."""
expanded = expand_abbreviations(template, abbreviations)
> assert expanded == expected_result
E AssertionError: assert None == 'https://bitbucket.org/pydanny/cookiecutter-django'
tests/repository/test_abbreviation_expansion.py:47: AssertionError
test_abbreviation_expansion.py::test_abbreviation_expansion_prefix_not_0_in_braces
test_abbreviation_expansion.py::test_abbreviation_expansion_prefix_not_0_in_braces
def test_abbreviation_expansion_prefix_not_0_in_braces():
"""Verify abbreviation unpacking raises error on incorrect index."""
> with pytest.raises(IndexError):
E Failed: DID NOT RAISE
tests/repository/test_abbreviation_expansion.py:52: Failed
zipfile.zip-False]
zipfile.zip-False]
mocker =
template = '/path/to/zipfile.zip', is_url = False
user_config_data = {'cookiecutters_dir': '/tmp/pytest-of-root/pytest-0/user_dir0/cookiecutters', 'replay_dir': '/tmp/pytest-of-root/pytest-0/user_dir0/cookiecutter_replay'}
@pytest.mark.parametrize(
'template, is_url',
[
('/path/to/zipfile.zip', False),
('https://example.com/path/to/zipfile.zip', True),
('http://example.com/path/to/zipfile.zip', True),
],
)
def test_zipfile_unzip(mocker, template, is_url, user_config_data):
"""Verify zip files correctly handled for different source locations.
`unzip()` should be called with correct args when `determine_repo_dir()`
is passed a zipfile, or a URL to a zipfile.
"""
mock_clone = mocker.patch(
'cookiecutter.repository.unzip',
return_value='tests/fake-repo-tmpl',
autospec=True,
)
> project_dir, cleanup = repository.determine_repo_dir(
template,
abbreviations={},
clone_to_dir=user_config_data['cookiecutters_dir'],
checkout=None,
no_input=True,
password=None,
)
E TypeError: cannot unpack non-iterable NoneType object
tests/repository/test_determine_repo_dir_clones_repo.py:30: TypeError
zipfile.zip-True]
zipfile.zip-True]
mocker =
template = 'https://example.com/path/to/zipfile.zip', is_url = True
user_config_data = {'cookiecutters_dir': '/tmp/pytest-of-root/pytest-0/user_dir0/cookiecutters', 'replay_dir': '/tmp/pytest-of-root/pytest-0/user_dir0/cookiecutter_replay'}
@pytest.mark.parametrize(
'template, is_url',
[
('/path/to/zipfile.zip', False),
('https://example.com/path/to/zipfile.zip', True),
('http://example.com/path/to/zipfile.zip', True),
],
)
def test_zipfile_unzip(mocker, template, is_url, user_config_data):
"""Verify zip files correctly handled for different source locations.
`unzip()` should be called with correct args when `determine_repo_dir()`
is passed a zipfile, or a URL to a zipfile.
"""
mock_clone = mocker.patch(
'cookiecutter.repository.unzip',
return_value='tests/fake-repo-tmpl',
autospec=True,
)
> project_dir, cleanup = repository.determine_repo_dir(
template,
abbreviations={},
clone_to_dir=user_config_data['cookiecutters_dir'],
checkout=None,
no_input=True,
password=None,
)
E TypeError: cannot unpack non-iterable NoneType object
tests/repository/test_determine_repo_dir_clones_repo.py:30: TypeError
zipfile.zip-True]
zipfile.zip-True]
mocker =
template = 'http://example.com/path/to/zipfile.zip', is_url = True
user_config_data = {'cookiecutters_dir': '/tmp/pytest-of-root/pytest-0/user_dir0/cookiecutters', 'replay_dir': '/tmp/pytest-of-root/pytest-0/user_dir0/cookiecutter_replay'}
@pytest.mark.parametrize(
'template, is_url',
[
('/path/to/zipfile.zip', False),
('https://example.com/path/to/zipfile.zip', True),
('http://example.com/path/to/zipfile.zip', True),
],
)
def test_zipfile_unzip(mocker, template, is_url, user_config_data):
"""Verify zip files correctly handled for different source locations.
`unzip()` should be called with correct args when `determine_repo_dir()`
is passed a zipfile, or a URL to a zipfile.
"""
mock_clone = mocker.patch(
'cookiecutter.repository.unzip',
return_value='tests/fake-repo-tmpl',
autospec=True,
)
> project_dir, cleanup = repository.determine_repo_dir(
template,
abbreviations={},
clone_to_dir=user_config_data['cookiecutters_dir'],
checkout=None,
no_input=True,
password=None,
)
E TypeError: cannot unpack non-iterable NoneType object
tests/repository/test_determine_repo_dir_clones_repo.py:30: TypeError
test_determine_repo_dir_clones_repo.py::test_repository_url_should_clone
test_determine_repo_dir_clones_repo.py::test_repository_url_should_clone
mocker =
template_url = 'https://github.com/pytest-dev/cookiecutter-pytest-plugin.git'
user_config_data = {'cookiecutters_dir': '/tmp/pytest-of-root/pytest-0/user_dir0/cookiecutters', 'replay_dir': '/tmp/pytest-of-root/pytest-0/user_dir0/cookiecutter_replay'}
def test_repository_url_should_clone(mocker, template_url, user_config_data):
"""Verify repository url triggers clone function.
`clone()` should be called with correct args when `determine_repo_dir()` is
passed a repository template url.
"""
mock_clone = mocker.patch(
'cookiecutter.repository.clone',
return_value='tests/fake-repo-tmpl',
autospec=True,
)
> project_dir, cleanup = repository.determine_repo_dir(
template_url,
abbreviations={},
clone_to_dir=user_config_data['cookiecutters_dir'],
checkout=None,
no_input=True,
)
E TypeError: cannot unpack non-iterable NoneType object
tests/repository/test_determine_repo_dir_clones_repo.py:73: TypeError
test_determine_repo_dir_clones_repo.py::test_repository_url_with_no_context_file
test_determine_repo_dir_clones_repo.py::test_repository_url_with_no_context_file
mocker =
template_url = 'https://github.com/pytest-dev/cookiecutter-pytest-plugin.git'
user_config_data = {'cookiecutters_dir': '/tmp/pytest-of-root/pytest-0/user_dir0/cookiecutters', 'replay_dir': '/tmp/pytest-of-root/pytest-0/user_dir0/cookiecutter_replay'}
def test_repository_url_with_no_context_file(mocker, template_url, user_config_data):
"""Verify cloned repository without `cookiecutter.json` file raises error."""
mocker.patch(
'cookiecutter.repository.clone',
return_value='tests/fake-repo-bad',
autospec=True,
)
> with pytest.raises(exceptions.RepositoryNotFound) as err:
E Failed: DID NOT RAISE
tests/repository/test_determine_repo_dir_clones_repo.py:101: Failed
test_determine_repo_dir_finds_existing_cookiecutter.py::test_should_find_existing_cookiecutter
test_determine_repo_dir_finds_existing_cookiecutter.py::test_should_find_existing_cookiecutter
template = 'cookiecutter-pytest-plugin'
user_config_data = {'cookiecutters_dir': '/tmp/pytest-of-root/pytest-0/user_dir0/cookiecutters', 'replay_dir': '/tmp/pytest-of-root/pytest-0/user_dir0/cookiecutter_replay'}
cloned_cookiecutter_path = '/tmp/pytest-of-root/pytest-0/user_dir0/cookiecutters/cookiecutter-pytest-plugin'
def test_should_find_existing_cookiecutter(
template, user_config_data, cloned_cookiecutter_path
):
"""
Should find folder created by `cloned_cookiecutter_path` and return it.
This folder is considered like previously cloned project directory.
"""
> project_dir, cleanup = repository.determine_repo_dir(
template=template,
abbreviations={},
clone_to_dir=user_config_data['cookiecutters_dir'],
checkout=None,
no_input=True,
)
E TypeError: cannot unpack non-iterable NoneType object
tests/repository/test_determine_repo_dir_finds_existing_cookiecutter.py:38: TypeError
test_determine_repo_dir_finds_subdirectories.py::test_should_find_existing_cookiecutter
test_determine_repo_dir_finds_subdirectories.py::test_should_find_existing_cookiecutter
template = 'cookiecutter-pytest-plugin'
user_config_data = {'cookiecutters_dir': '/tmp/pytest-of-root/pytest-0/user_dir0/cookiecutters', 'replay_dir': '/tmp/pytest-of-root/pytest-0/user_dir0/cookiecutter_replay'}
cloned_cookiecutter_path = '/tmp/pytest-of-root/pytest-0/user_dir0/cookiecutters/cookiecutter-pytest-plugin/my-dir'
def test_should_find_existing_cookiecutter(
template, user_config_data, cloned_cookiecutter_path
):
"""Find `cookiecutter.json` in sub folder created by `cloned_cookiecutter_path`."""
> project_dir, cleanup = repository.determine_repo_dir(
template=template,
abbreviations={},
clone_to_dir=user_config_data['cookiecutters_dir'],
checkout=None,
no_input=True,
directory='my-dir',
)
E TypeError: cannot unpack non-iterable NoneType object
tests/repository/test_determine_repo_dir_finds_subdirectories.py:38: TypeError
test_determine_repo_dir_finds_subdirectories.py::test_local_repo_typo
test_determine_repo_dir_finds_subdirectories.py::test_local_repo_typo
template = 'cookiecutter-pytest-plugin'
user_config_data = {'cookiecutters_dir': '/tmp/pytest-of-root/pytest-0/user_dir0/cookiecutters', 'replay_dir': '/tmp/pytest-of-root/pytest-0/user_dir0/cookiecutter_replay'}
cloned_cookiecutter_path = '/tmp/pytest-of-root/pytest-0/user_dir0/cookiecutters/cookiecutter-pytest-plugin/my-dir'
def test_local_repo_typo(template, user_config_data, cloned_cookiecutter_path):
"""Wrong pointing to `cookiecutter.json` sub-directory should raise."""
> with pytest.raises(exceptions.RepositoryNotFound) as err:
E Failed: DID NOT RAISE
tests/repository/test_determine_repo_dir_finds_subdirectories.py:53: Failed
test_determine_repository_should_use_local_repo.py::test_finds_local_repo
test_determine_repository_should_use_local_repo.py::test_finds_local_repo
tmp_path = PosixPath('/tmp/pytest-of-root/pytest-0/test_finds_local_repo0')
def test_finds_local_repo(tmp_path):
"""A valid local repository should be returned."""
> project_dir, cleanup = repository.determine_repo_dir(
'tests/fake-repo',
abbreviations={},
clone_to_dir=str(tmp_path),
checkout=None,
no_input=True,
)
E TypeError: cannot unpack non-iterable NoneType object
tests/repository/test_determine_repository_should_use_local_repo.py:12: TypeError
test_determine_repository_should_use_local_repo.py::test_local_repo_with_no_context_raises
test_determine_repository_should_use_local_repo.py::test_local_repo_with_no_context_raises
tmp_path = PosixPath('/tmp/pytest-of-root/pytest-0/test_local_repo_with_no_contex0')
def test_local_repo_with_no_context_raises(tmp_path):
"""A local repository without a cookiecutter.json should raise a \
`RepositoryNotFound` exception."""
template_path = str(Path('tests', 'fake-repo-bad'))
> with pytest.raises(exceptions.RepositoryNotFound) as err:
E Failed: DID NOT RAISE
tests/repository/test_determine_repository_should_use_local_repo.py:28: Failed
test_determine_repository_should_use_local_repo.py::test_local_repo_typo
test_determine_repository_should_use_local_repo.py::test_local_repo_typo
tmp_path = PosixPath('/tmp/pytest-of-root/pytest-0/test_local_repo_typo1')
def test_local_repo_typo(tmp_path):
"""An unknown local repository should raise a `RepositoryNotFound` \
exception."""
template_path = str(Path('tests', 'unknown-repo'))
> with pytest.raises(exceptions.RepositoryNotFound) as err:
E Failed: DID NOT RAISE
tests/repository/test_determine_repository_should_use_local_repo.py:52: Failed
zipfile.zip]
zipfile.zip]
zipfile = '/path/to/zipfile.zip'
def test_is_zip_file(zipfile):
"""Verify is_repo_url works."""
> assert is_zip_file(zipfile) is True
E AssertionError: assert None is True
E + where None = is_zip_file('/path/to/zipfile.zip')
tests/repository/test_is_repo_url.py:23: AssertionError
zipfile.zip]
zipfile.zip]
zipfile = 'https://example.com/path/to/zipfile.zip'
def test_is_zip_file(zipfile):
"""Verify is_repo_url works."""
> assert is_zip_file(zipfile) is True
E AssertionError: assert None is True
E + where None = is_zip_file('https://example.com/path/to/zipfile.zip')
tests/repository/test_is_repo_url.py:23: AssertionError
zipfile.zip]
zipfile.zip]
zipfile = 'http://example.com/path/to/zipfile.zip'
def test_is_zip_file(zipfile):
"""Verify is_repo_url works."""
> assert is_zip_file(zipfile) is True
E AssertionError: assert None is True
E + where None = is_zip_file('http://example.com/path/to/zipfile.zip')
tests/repository/test_is_repo_url.py:23: AssertionError
repo]
repo]
remote_repo_url = 'gitolite@server:team/repo'
def test_is_repo_url_for_remote_urls(remote_repo_url):
"""Verify is_repo_url works."""
> assert is_repo_url(remote_repo_url) is True
E AssertionError: assert None is True
E + where None = is_repo_url('gitolite@server:team/repo')
tests/repository/test_is_repo_url.py:44: AssertionError
cookiecutter.git]
cookiecutter.git]
remote_repo_url = 'git@github.com:audreyfeldroy/cookiecutter.git'
def test_is_repo_url_for_remote_urls(remote_repo_url):
"""Verify is_repo_url works."""
> assert is_repo_url(remote_repo_url) is True
E AssertionError: assert None is True
E + where None = is_repo_url('git@github.com:audreyfeldroy/cookiecutter.git')
tests/repository/test_is_repo_url.py:44: AssertionError
cookiecutter.git]
cookiecutter.git]
remote_repo_url = 'https://github.com/cookiecutter/cookiecutter.git'
def test_is_repo_url_for_remote_urls(remote_repo_url):
"""Verify is_repo_url works."""
> assert is_repo_url(remote_repo_url) is True
E AssertionError: assert None is True
E + where None = is_repo_url('https://github.com/cookiecutter/cookiecutter.git')
tests/repository/test_is_repo_url.py:44: AssertionError
gitrepo]
gitrepo]
remote_repo_url = 'git+https://private.com/gitrepo'
def test_is_repo_url_for_remote_urls(remote_repo_url):
"""Verify is_repo_url works."""
> assert is_repo_url(remote_repo_url) is True
E AssertionError: assert None is True
E + where None = is_repo_url('git+https://private.com/gitrepo')
tests/repository/test_is_repo_url.py:44: AssertionError
mercurialrepo]
mercurialrepo]
remote_repo_url = 'hg+https://private.com/mercurialrepo'
def test_is_repo_url_for_remote_urls(remote_repo_url):
"""Verify is_repo_url works."""
> assert is_repo_url(remote_repo_url) is True
E AssertionError: assert None is True
E + where None = is_repo_url('hg+https://private.com/mercurialrepo')
tests/repository/test_is_repo_url.py:44: AssertionError
cookiecutter.hg]
cookiecutter.hg]
remote_repo_url = 'https://bitbucket.org/pokoli/cookiecutter.hg'
def test_is_repo_url_for_remote_urls(remote_repo_url):
"""Verify is_repo_url works."""
> assert is_repo_url(remote_repo_url) is True
E AssertionError: assert None is True
E + where None = is_repo_url('https://bitbucket.org/pokoli/cookiecutter.hg')
tests/repository/test_is_repo_url.py:44: AssertionError
repo.git]
repo.git]
remote_repo_url = 'file://server/path/to/repo.git'
def test_is_repo_url_for_remote_urls(remote_repo_url):
"""Verify is_repo_url works."""
> assert is_repo_url(remote_repo_url) is True
E AssertionError: assert None is True
E + where None = is_repo_url('file://server/path/to/repo.git')
tests/repository/test_is_repo_url.py:44: AssertionError
cookiecutter.git]
cookiecutter.git]
local_repo_url = '/audreyr/cookiecutter.git'
def test_is_repo_url_for_local_urls(local_repo_url):
"""Verify is_repo_url works."""
> assert is_repo_url(local_repo_url) is False
E AssertionError: assert None is False
E + where None = is_repo_url('/audreyr/cookiecutter.git')
tests/repository/test_is_repo_url.py:64: AssertionError
cookiecutter]
cookiecutter]
local_repo_url = '/home/audreyr/cookiecutter'
def test_is_repo_url_for_local_urls(local_repo_url):
"""Verify is_repo_url works."""
> assert is_repo_url(local_repo_url) is False
E AssertionError: assert None is False
E + where None = is_repo_url('/home/audreyr/cookiecutter')
tests/repository/test_is_repo_url.py:64: AssertionError
test_is_repo_url.py::test_is_repo_url_for_local_urls[c:\users\foo\appdata\local\temp\1\pytest-0\test_default_output_dir0\template]
test_is_repo_url.py::test_is_repo_url_for_local_urls[c:\\users\\foo\\appdata\\local\\temp\\1\\pytest-0\\test_default_output_dir0\\template]
local_repo_url = 'c:\\users\\foo\\appdata\\local\\temp\\1\\pytest-0\\test_default_output_dir0\\template'
def test_is_repo_url_for_local_urls(local_repo_url):
"""Verify is_repo_url works."""
> assert is_repo_url(local_repo_url) is False
E AssertionError: assert None is False
E + where None = is_repo_url('c:\\users\\foo\\appdata\\local\\temp\\1\\pytest-0\\test_default_output_dir0\\template')
tests/repository/test_is_repo_url.py:64: AssertionError
test_is_repo_url.py::test_expand_abbreviations
test_is_repo_url.py::test_expand_abbreviations
def test_expand_abbreviations():
"""Validate `repository.expand_abbreviations` correctly translate url."""
template = 'gh:audreyfeldroy/cookiecutter-pypackage'
# This is not a valid repo url just yet!
# First `repository.expand_abbreviations` needs to translate it
> assert is_repo_url(template) is False
E AssertionError: assert None is False
E + where None = is_repo_url('gh:audreyfeldroy/cookiecutter-pypackage')
tests/repository/test_is_repo_url.py:73: AssertionError
test_repository_has_cookiecutter_json.py::test_valid_repository
test_repository_has_cookiecutter_json.py::test_valid_repository
def test_valid_repository():
"""Validate correct response if `cookiecutter.json` file exist."""
> assert repository_has_cookiecutter_json('tests/fake-repo')
E AssertionError: assert None
E + where None = repository_has_cookiecutter_json('tests/fake-repo')
tests/repository/test_repository_has_cookiecutter_json.py:10: AssertionError
test_abort_generate_on_hook_error.py::test_hooks_raises_errors[pre_gen_hook_raises_error]
test_abort_generate_on_hook_error.py::test_hooks_raises_errors[pre_gen_hook_raises_error]
tmp_path = PosixPath('/tmp/pytest-of-root/pytest-0/test_hooks_raises_errors_pre_g0')
abort_pre_gen = 'yes', abort_post_gen = 'no'
@pytest.mark.parametrize(
("abort_pre_gen", "abort_post_gen"),
(("yes", "no"), ("no", "yes")),
ids=("pre_gen_hook_raises_error", "post_gen_hook_raises_error"),
)
@pytest.mark.usefixtures("clean_system")
def test_hooks_raises_errors(tmp_path, abort_pre_gen, abort_post_gen):
"""Verify pre- and pos-gen errors raises correct error code from script.
This allows developers to make different error codes in their code,
for different errors.
"""
context = {
"cookiecutter": {
"repo_dir": "foobar",
"abort_pre_gen": abort_pre_gen,
"abort_post_gen": abort_post_gen,
}
}
with pytest.raises(exceptions.FailedHookException) as error:
> generate.generate_files(
repo_dir="tests/hooks-abort-render",
context=context,
output_dir=str(tmp_path),
)
tests/test_abort_generate_on_hook_error.py:34:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
repo_dir = 'tests/hooks-abort-render'
context = {'cookiecutter': {'abort_post_gen': 'no', 'abort_pre_gen': 'yes', 'repo_dir': 'foobar'}}
output_dir = '/tmp/pytest-of-root/pytest-0/test_hooks_raises_errors_pre_g0'
overwrite_if_exists = False, skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False
def generate_files(repo_dir, context=None, output_dir='.', overwrite_if_exists=False, skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False):
"""Render the templates and saves them to files.
:param repo_dir: Project template input directory.
:param context: Dict for populating the template's variables.
:param output_dir: Where to output the generated project dir into.
:param overwrite_if_exists: Overwrite the contents of the output directory
if it exists.
:param skip_if_file_exists: Skip the files in the corresponding directories
if they already exist
:param accept_hooks: Accept pre and post hooks if set to `True`.
:param keep_project_on_failure: If `True` keep generated project directory even when
generation fails
"""
> template_dir = find_template(repo_dir)
E TypeError: find_template() missing 1 required positional argument: 'env'
cookiecutter/generate.py:170: TypeError
test_abort_generate_on_hook_error.py::test_hooks_raises_errors[post_gen_hook_raises_error]
test_abort_generate_on_hook_error.py::test_hooks_raises_errors[post_gen_hook_raises_error]
tmp_path = PosixPath('/tmp/pytest-of-root/pytest-0/test_hooks_raises_errors_post_0')
abort_pre_gen = 'no', abort_post_gen = 'yes'
@pytest.mark.parametrize(
("abort_pre_gen", "abort_post_gen"),
(("yes", "no"), ("no", "yes")),
ids=("pre_gen_hook_raises_error", "post_gen_hook_raises_error"),
)
@pytest.mark.usefixtures("clean_system")
def test_hooks_raises_errors(tmp_path, abort_pre_gen, abort_post_gen):
"""Verify pre- and pos-gen errors raises correct error code from script.
This allows developers to make different error codes in their code,
for different errors.
"""
context = {
"cookiecutter": {
"repo_dir": "foobar",
"abort_pre_gen": abort_pre_gen,
"abort_post_gen": abort_post_gen,
}
}
with pytest.raises(exceptions.FailedHookException) as error:
> generate.generate_files(
repo_dir="tests/hooks-abort-render",
context=context,
output_dir=str(tmp_path),
)
tests/test_abort_generate_on_hook_error.py:34:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
repo_dir = 'tests/hooks-abort-render'
context = {'cookiecutter': {'abort_post_gen': 'yes', 'abort_pre_gen': 'no', 'repo_dir': 'foobar'}}
output_dir = '/tmp/pytest-of-root/pytest-0/test_hooks_raises_errors_post_0'
overwrite_if_exists = False, skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False
def generate_files(repo_dir, context=None, output_dir='.', overwrite_if_exists=False, skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False):
"""Render the templates and saves them to files.
:param repo_dir: Project template input directory.
:param context: Dict for populating the template's variables.
:param output_dir: Where to output the generated project dir into.
:param overwrite_if_exists: Overwrite the contents of the output directory
if it exists.
:param skip_if_file_exists: Skip the files in the corresponding directories
if they already exist
:param accept_hooks: Accept pre and post hooks if set to `True`.
:param keep_project_on_failure: If `True` keep generated project directory even when
generation fails
"""
> template_dir = find_template(repo_dir)
E TypeError: find_template() missing 1 required positional argument: 'env'
cookiecutter/generate.py:170: TypeError
test_cli.py::test_cli_version[-V]
test_cli.py::test_cli_version[-V]
cli_runner = .cli_main at 0x7ffac9e128c0>
version_cli_flag = '-V'
def test_cli_version(cli_runner, version_cli_flag):
"""Verify Cookiecutter version output by `cookiecutter` on cli invocation."""
result = cli_runner(version_cli_flag)
assert result.exit_code == 0
> assert result.output.startswith('Cookiecutter')
E AssertionError: assert False
E + where False = ('Cookiecutter')
E + where = 'main, version 2.6.0\n'.startswith
E + where 'main, version 2.6.0\n' = .output
tests/test_cli.py:72: AssertionError
test_cli.py::test_cli_version[--version]
test_cli.py::test_cli_version[--version]
cli_runner = .cli_main at 0x7ffac9e128c0>
version_cli_flag = '--version'
def test_cli_version(cli_runner, version_cli_flag):
"""Verify Cookiecutter version output by `cookiecutter` on cli invocation."""
result = cli_runner(version_cli_flag)
assert result.exit_code == 0
> assert result.output.startswith('Cookiecutter')
E AssertionError: assert False
E + where False = ('Cookiecutter')
E + where = 'main, version 2.6.0\n'.startswith
E + where 'main, version 2.6.0\n' = .output
tests/test_cli.py:72: AssertionError
test_cli.py::test_cli_error_on_existing_output_directory
test_cli.py::test_cli_error_on_existing_output_directory
cli_runner = .cli_main at 0x7ffac9e128c0>
@pytest.mark.usefixtures('make_fake_project_dir', 'remove_fake_project_dir')
def test_cli_error_on_existing_output_directory(cli_runner):
"""Test cli invocation without `overwrite-if-exists` fail if dir exist."""
result = cli_runner('tests/fake-repo-pre/', '--no-input')
> assert result.exit_code != 0
E assert 0 != 0
E + where 0 = .exit_code
tests/test_cli.py:79: AssertionError
test_cli.py::test_cli
test_cli.py::test_cli
cli_runner = .cli_main at 0x7ffac9e128c0>
@pytest.mark.usefixtures('remove_fake_project_dir')
def test_cli(cli_runner):
"""Test cli invocation work without flags if directory not exist."""
result = cli_runner('tests/fake-repo-pre/', '--no-input')
assert result.exit_code == 0
assert os.path.isdir('fake-project')
> content = Path("fake-project", "README.rst").read_text()
tests/test_cli.py:90:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/lib/python3.10/pathlib.py:1134: in read_text
with self.open(mode='r', encoding=encoding, errors=errors) as f:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = PosixPath('fake-project/README.rst'), mode = 'r', buffering = -1
encoding = 'locale', errors = None, newline = None
def open(self, mode='r', buffering=-1, encoding=None,
errors=None, newline=None):
"""
Open the file pointed by this path and return a file object, as
the built-in open() function does.
"""
if "b" not in mode:
encoding = io.text_encoding(encoding)
> return self._accessor.open(self, mode, buffering, encoding, errors,
newline)
E FileNotFoundError: [Errno 2] No such file or directory: 'fake-project/README.rst'
/usr/lib/python3.10/pathlib.py:1119: FileNotFoundError
test_cli.py::test_cli_verbose
test_cli.py::test_cli_verbose
cli_runner = .cli_main at 0x7ffac9e128c0>
@pytest.mark.usefixtures('remove_fake_project_dir')
def test_cli_verbose(cli_runner):
"""Test cli invocation display log if called with `verbose` flag."""
result = cli_runner('tests/fake-repo-pre/', '--no-input', '-v')
assert result.exit_code == 0
assert os.path.isdir('fake-project')
> content = Path("fake-project", "README.rst").read_text()
tests/test_cli.py:100:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/lib/python3.10/pathlib.py:1134: in read_text
with self.open(mode='r', encoding=encoding, errors=errors) as f:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = PosixPath('fake-project/README.rst'), mode = 'r', buffering = -1
encoding = 'locale', errors = None, newline = None
def open(self, mode='r', buffering=-1, encoding=None,
errors=None, newline=None):
"""
Open the file pointed by this path and return a file object, as
the built-in open() function does.
"""
if "b" not in mode:
encoding = io.text_encoding(encoding)
> return self._accessor.open(self, mode, buffering, encoding, errors,
newline)
E FileNotFoundError: [Errno 2] No such file or directory: 'fake-project/README.rst'
/usr/lib/python3.10/pathlib.py:1119: FileNotFoundError
test_cli.py::test_cli_replay
test_cli.py::test_cli_replay
self =
args = ('tests/fake-repo-pre/', None, False)
kwargs = {'accept_hooks': True, 'config_file': None, 'default_config': False, 'directory': None, ...}
msg = "Expected 'cookiecutter' to be called once. Called 0 times."
def assert_called_once_with(self, /, *args, **kwargs):
"""assert that the mock was called exactly once and that that call was
with the specified arguments."""
if not self.call_count == 1:
msg = ("Expected '%s' to be called once. Called %s times.%s"
% (self._mock_name or 'mock',
self.call_count,
self._calls_repr()))
> raise AssertionError(msg)
E AssertionError: Expected 'cookiecutter' to be called once. Called 0 times.
/usr/lib/python3.10/unittest/mock.py:940: AssertionError
During handling of the above exception, another exception occurred:
mocker =
cli_runner = .cli_main at 0x7ffac9e128c0>
@pytest.mark.usefixtures('remove_fake_project_dir')
def test_cli_replay(mocker, cli_runner):
"""Test cli invocation display log with `verbose` and `replay` flags."""
mock_cookiecutter = mocker.patch('cookiecutter.cli.cookiecutter')
template_path = 'tests/fake-repo-pre/'
result = cli_runner(template_path, '--replay', '-v')
assert result.exit_code == 0
> mock_cookiecutter.assert_called_once_with(
template_path,
None,
False,
replay=True,
overwrite_if_exists=False,
skip_if_file_exists=False,
output_dir='.',
config_file=None,
default_config=False,
extra_context=None,
password=None,
directory=None,
accept_hooks=True,
keep_project_on_failure=False,
)
E AssertionError: Expected 'cookiecutter' to be called once. Called 0 times.
tests/test_cli.py:113: AssertionError
test_cli.py::test_cli_replay_file
test_cli.py::test_cli_replay_file
self =
args = ('tests/fake-repo-pre/', None, False)
kwargs = {'accept_hooks': True, 'config_file': None, 'default_config': False, 'directory': None, ...}
msg = "Expected 'cookiecutter' to be called once. Called 0 times."
def assert_called_once_with(self, /, *args, **kwargs):
"""assert that the mock was called exactly once and that that call was
with the specified arguments."""
if not self.call_count == 1:
msg = ("Expected '%s' to be called once. Called %s times.%s"
% (self._mock_name or 'mock',
self.call_count,
self._calls_repr()))
> raise AssertionError(msg)
E AssertionError: Expected 'cookiecutter' to be called once. Called 0 times.
/usr/lib/python3.10/unittest/mock.py:940: AssertionError
During handling of the above exception, another exception occurred:
mocker =
cli_runner = .cli_main at 0x7ffac9e128c0>
@pytest.mark.usefixtures('remove_fake_project_dir')
def test_cli_replay_file(mocker, cli_runner):
"""Test cli invocation correctly pass --replay-file option."""
mock_cookiecutter = mocker.patch('cookiecutter.cli.cookiecutter')
template_path = 'tests/fake-repo-pre/'
result = cli_runner(template_path, '--replay-file', '~/custom-replay-file', '-v')
assert result.exit_code == 0
> mock_cookiecutter.assert_called_once_with(
template_path,
None,
False,
replay='~/custom-replay-file',
overwrite_if_exists=False,
skip_if_file_exists=False,
output_dir='.',
config_file=None,
default_config=False,
extra_context=None,
password=None,
directory=None,
accept_hooks=True,
keep_project_on_failure=False,
)
E AssertionError: Expected 'cookiecutter' to be called once. Called 0 times.
tests/test_cli.py:140: AssertionError
test_cli.py::test_cli_replay_generated
test_cli.py::test_cli_replay_generated
mocker =
cli_runner = .cli_main at 0x7ffac9e128c0>
@pytest.mark.usefixtures('remove_tmp_dir')
def test_cli_replay_generated(mocker, cli_runner):
"""Test cli invocation correctly generates a project with replay."""
template_path = 'tests/fake-repo-replay/'
result = cli_runner(
template_path,
'--replay-file',
'tests/test-replay/valid_replay.json',
'-o',
'tests/tmp/',
'-v',
)
assert result.exit_code == 0
> assert open('tests/tmp/replay-project/README.md').read().strip() == 'replayed'
E FileNotFoundError: [Errno 2] No such file or directory: 'tests/tmp/replay-project/README.md'
tests/test_cli.py:171: FileNotFoundError
test_cli.py::test_cli_exit_on_noinput_and_replay
mocker =
cli_runner = .cli_main at 0x7ffac9e128c0>
@pytest.mark.usefixtures('remove_fake_project_dir')
def test_cli_exit_on_noinput_and_replay(mocker, cli_runner):
"""Test cli invocation fail if both `no-input` and `replay` flags passed."""
mock_cookiecutter = mocker.patch(
'cookiecutter.cli.cookiecutter', side_effect=cookiecutter
)
template_path = 'tests/fake-repo-pre/'
result = cli_runner(template_path, '--no-input', '--replay', '-v')
> assert result.exit_code == 1
E assert 0 == 1
E + where 0 = .exit_code
tests/test_cli.py:184: AssertionError
test_cli.py::test_run_cookiecutter_on_overwrite_if_exists_and_replay[-f]
test_cli.py::test_run_cookiecutter_on_overwrite_if_exists_and_replay[-f]
self =
args = ('tests/fake-repo-pre/', None, False)
kwargs = {'accept_hooks': True, 'config_file': None, 'default_config': False, 'directory': None, ...}
msg = "Expected 'cookiecutter' to be called once. Called 0 times."
def assert_called_once_with(self, /, *args, **kwargs):
"""assert that the mock was called exactly once and that that call was
with the specified arguments."""
if not self.call_count == 1:
msg = ("Expected '%s' to be called once. Called %s times.%s"
% (self._mock_name or 'mock',
self.call_count,
self._calls_repr()))
> raise AssertionError(msg)
E AssertionError: Expected 'cookiecutter' to be called once. Called 0 times.
/usr/lib/python3.10/unittest/mock.py:940: AssertionError
During handling of the above exception, another exception occurred:
mocker =
cli_runner = .cli_main at 0x7ffac9e128c0>
overwrite_cli_flag = '-f'
@pytest.mark.usefixtures('remove_fake_project_dir')
def test_run_cookiecutter_on_overwrite_if_exists_and_replay(
mocker, cli_runner, overwrite_cli_flag
):
"""Test cli invocation with `overwrite-if-exists` and `replay` flags."""
mock_cookiecutter = mocker.patch('cookiecutter.cli.cookiecutter')
template_path = 'tests/fake-repo-pre/'
result = cli_runner(template_path, '--replay', '-v', overwrite_cli_flag)
assert result.exit_code == 0
> mock_cookiecutter.assert_called_once_with(
template_path,
None,
False,
replay=True,
overwrite_if_exists=True,
skip_if_file_exists=False,
output_dir='.',
config_file=None,
default_config=False,
extra_context=None,
password=None,
directory=None,
accept_hooks=True,
keep_project_on_failure=False,
)
E AssertionError: Expected 'cookiecutter' to be called once. Called 0 times.
tests/test_cli.py:228: AssertionError
test_cli.py::test_run_cookiecutter_on_overwrite_if_exists_and_replay[--overwrite-if-exists]
test_cli.py::test_run_cookiecutter_on_overwrite_if_exists_and_replay[--overwrite-if-exists]
self =
args = ('tests/fake-repo-pre/', None, False)
kwargs = {'accept_hooks': True, 'config_file': None, 'default_config': False, 'directory': None, ...}
msg = "Expected 'cookiecutter' to be called once. Called 0 times."
def assert_called_once_with(self, /, *args, **kwargs):
"""assert that the mock was called exactly once and that that call was
with the specified arguments."""
if not self.call_count == 1:
msg = ("Expected '%s' to be called once. Called %s times.%s"
% (self._mock_name or 'mock',
self.call_count,
self._calls_repr()))
> raise AssertionError(msg)
E AssertionError: Expected 'cookiecutter' to be called once. Called 0 times.
/usr/lib/python3.10/unittest/mock.py:940: AssertionError
During handling of the above exception, another exception occurred:
mocker =
cli_runner = .cli_main at 0x7ffac9e128c0>
overwrite_cli_flag = '--overwrite-if-exists'
@pytest.mark.usefixtures('remove_fake_project_dir')
def test_run_cookiecutter_on_overwrite_if_exists_and_replay(
mocker, cli_runner, overwrite_cli_flag
):
"""Test cli invocation with `overwrite-if-exists` and `replay` flags."""
mock_cookiecutter = mocker.patch('cookiecutter.cli.cookiecutter')
template_path = 'tests/fake-repo-pre/'
result = cli_runner(template_path, '--replay', '-v', overwrite_cli_flag)
assert result.exit_code == 0
> mock_cookiecutter.assert_called_once_with(
template_path,
None,
False,
replay=True,
overwrite_if_exists=True,
skip_if_file_exists=False,
output_dir='.',
config_file=None,
default_config=False,
extra_context=None,
password=None,
directory=None,
accept_hooks=True,
keep_project_on_failure=False,
)
E AssertionError: Expected 'cookiecutter' to be called once. Called 0 times.
tests/test_cli.py:228: AssertionError
test_cli.py::test_cli_overwrite_if_exists_when_output_dir_exists[-f]
test_cli.py::test_cli_overwrite_if_exists_when_output_dir_exists[-f]
request = >
@pytest.fixture
def make_fake_project_dir(request):
"""Create a fake project to be overwritten in the according tests."""
> os.makedirs('fake-project')
tests/test_cli.py:59:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
name = 'fake-project', mode = 511, exist_ok = False
def makedirs(name, mode=0o777, exist_ok=False):
"""makedirs(name [, mode=0o777][, exist_ok=False])
Super-mkdir; create a leaf directory and all intermediate ones. Works like
mkdir, except that any intermediate path segment (not just the rightmost)
will be created if it does not exist. If the target directory already
exists, raise an OSError if exist_ok is False. Otherwise no exception is
raised. This is recursive.
"""
head, tail = path.split(name)
if not tail:
head, tail = path.split(head)
if head and tail and not path.exists(head):
try:
makedirs(head, exist_ok=exist_ok)
except FileExistsError:
# Defeats race condition when another thread created the path
pass
cdir = curdir
if isinstance(tail, bytes):
cdir = bytes(curdir, 'ASCII')
if tail == cdir: # xxx/newdir/. exists if xxx/newdir exists
return
try:
> mkdir(name, mode)
E FileExistsError: [Errno 17] File exists: 'fake-project'
/usr/lib/python3.10/os.py:225: FileExistsError
test_cli.py::test_cli_overwrite_if_exists_when_output_dir_exists[--overwrite-if-exists]
test_cli.py::test_cli_overwrite_if_exists_when_output_dir_exists[--overwrite-if-exists]
request = >
@pytest.fixture
def make_fake_project_dir(request):
"""Create a fake project to be overwritten in the according tests."""
> os.makedirs('fake-project')
tests/test_cli.py:59:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
name = 'fake-project', mode = 511, exist_ok = False
def makedirs(name, mode=0o777, exist_ok=False):
"""makedirs(name [, mode=0o777][, exist_ok=False])
Super-mkdir; create a leaf directory and all intermediate ones. Works like
mkdir, except that any intermediate path segment (not just the rightmost)
will be created if it does not exist. If the target directory already
exists, raise an OSError if exist_ok is False. Otherwise no exception is
raised. This is recursive.
"""
head, tail = path.split(name)
if not tail:
head, tail = path.split(head)
if head and tail and not path.exists(head):
try:
makedirs(head, exist_ok=exist_ok)
except FileExistsError:
# Defeats race condition when another thread created the path
pass
cdir = curdir
if isinstance(tail, bytes):
cdir = bytes(curdir, 'ASCII')
if tail == cdir: # xxx/newdir/. exists if xxx/newdir exists
return
try:
> mkdir(name, mode)
E FileExistsError: [Errno 17] File exists: 'fake-project'
/usr/lib/python3.10/os.py:225: FileExistsError
test_cli.py::test_cli_output_dir[-o]
test_cli.py::test_cli_output_dir[-o]
self =
args = ('tests/fake-repo-pre/', None, False)
kwargs = {'accept_hooks': True, 'config_file': None, 'default_config': False, 'directory': None, ...}
msg = "Expected 'cookiecutter' to be called once. Called 0 times."
def assert_called_once_with(self, /, *args, **kwargs):
"""assert that the mock was called exactly once and that that call was
with the specified arguments."""
if not self.call_count == 1:
msg = ("Expected '%s' to be called once. Called %s times.%s"
% (self._mock_name or 'mock',
self.call_count,
self._calls_repr()))
> raise AssertionError(msg)
E AssertionError: Expected 'cookiecutter' to be called once. Called 0 times.
/usr/lib/python3.10/unittest/mock.py:940: AssertionError
During handling of the above exception, another exception occurred:
mocker =
cli_runner = .cli_main at 0x7ffac9e128c0>
output_dir_flag = '-o'
output_dir = '/tmp/pytest-of-root/pytest-0/test_cli_output_dir__o_0/output'
def test_cli_output_dir(mocker, cli_runner, output_dir_flag, output_dir):
"""Test cli invocation with `output-dir` flag changes output directory."""
mock_cookiecutter = mocker.patch('cookiecutter.cli.cookiecutter')
template_path = 'tests/fake-repo-pre/'
result = cli_runner(template_path, output_dir_flag, output_dir)
assert result.exit_code == 0
> mock_cookiecutter.assert_called_once_with(
template_path,
None,
False,
replay=False,
overwrite_if_exists=False,
skip_if_file_exists=False,
output_dir=output_dir,
config_file=None,
default_config=False,
extra_context=None,
password=None,
directory=None,
accept_hooks=True,
keep_project_on_failure=False,
)
E AssertionError: Expected 'cookiecutter' to be called once. Called 0 times.
tests/test_cli.py:285: AssertionError
test_cli.py::test_cli_output_dir[--output-dir]
test_cli.py::test_cli_output_dir[--output-dir]
self =
args = ('tests/fake-repo-pre/', None, False)
kwargs = {'accept_hooks': True, 'config_file': None, 'default_config': False, 'directory': None, ...}
msg = "Expected 'cookiecutter' to be called once. Called 0 times."
def assert_called_once_with(self, /, *args, **kwargs):
"""assert that the mock was called exactly once and that that call was
with the specified arguments."""
if not self.call_count == 1:
msg = ("Expected '%s' to be called once. Called %s times.%s"
% (self._mock_name or 'mock',
self.call_count,
self._calls_repr()))
> raise AssertionError(msg)
E AssertionError: Expected 'cookiecutter' to be called once. Called 0 times.
/usr/lib/python3.10/unittest/mock.py:940: AssertionError
During handling of the above exception, another exception occurred:
mocker =
cli_runner = .cli_main at 0x7ffac9e128c0>
output_dir_flag = '--output-dir'
output_dir = '/tmp/pytest-of-root/pytest-0/test_cli_output_dir___output_d0/output'
def test_cli_output_dir(mocker, cli_runner, output_dir_flag, output_dir):
"""Test cli invocation with `output-dir` flag changes output directory."""
mock_cookiecutter = mocker.patch('cookiecutter.cli.cookiecutter')
template_path = 'tests/fake-repo-pre/'
result = cli_runner(template_path, output_dir_flag, output_dir)
assert result.exit_code == 0
> mock_cookiecutter.assert_called_once_with(
template_path,
None,
False,
replay=False,
overwrite_if_exists=False,
skip_if_file_exists=False,
output_dir=output_dir,
config_file=None,
default_config=False,
extra_context=None,
password=None,
directory=None,
accept_hooks=True,
keep_project_on_failure=False,
)
E AssertionError: Expected 'cookiecutter' to be called once. Called 0 times.
tests/test_cli.py:285: AssertionError
test_cli.py::test_cli_help[help]
test_cli.py::test_cli_help[help]
cli_runner = .cli_main at 0x7ffac9e128c0>
help_cli_flag = 'help'
def test_cli_help(cli_runner, help_cli_flag):
"""Test cli invocation display help message with `help` flag."""
result = cli_runner(help_cli_flag)
assert result.exit_code == 0
> assert result.output.startswith('Usage')
E AssertionError: assert False
E + where False = ('Usage')
E + where = ''.startswith
E + where '' = .output
tests/test_cli.py:313: AssertionError
test_cli.py::test_user_config
test_cli.py::test_user_config
self =
args = ('tests/fake-repo-pre/', None, False)
kwargs = {'accept_hooks': True, 'config_file': '/tmp/pytest-of-root/pytest-0/test_user_config0/tests/config.yaml', 'default_config': False, 'directory': None, ...}
msg = "Expected 'cookiecutter' to be called once. Called 0 times."
def assert_called_once_with(self, /, *args, **kwargs):
"""assert that the mock was called exactly once and that that call was
with the specified arguments."""
if not self.call_count == 1:
msg = ("Expected '%s' to be called once. Called %s times.%s"
% (self._mock_name or 'mock',
self.call_count,
self._calls_repr()))
> raise AssertionError(msg)
E AssertionError: Expected 'cookiecutter' to be called once. Called 0 times.
/usr/lib/python3.10/unittest/mock.py:940: AssertionError
During handling of the above exception, another exception occurred:
mocker =
cli_runner = .cli_main at 0x7ffac9e128c0>
user_config_path = '/tmp/pytest-of-root/pytest-0/test_user_config0/tests/config.yaml'
def test_user_config(mocker, cli_runner, user_config_path):
"""Test cli invocation works with `config-file` option."""
mock_cookiecutter = mocker.patch('cookiecutter.cli.cookiecutter')
template_path = 'tests/fake-repo-pre/'
result = cli_runner(template_path, '--config-file', user_config_path)
assert result.exit_code == 0
> mock_cookiecutter.assert_called_once_with(
template_path,
None,
False,
replay=False,
overwrite_if_exists=False,
skip_if_file_exists=False,
output_dir='.',
config_file=user_config_path,
default_config=False,
extra_context=None,
password=None,
directory=None,
accept_hooks=True,
keep_project_on_failure=False,
)
E AssertionError: Expected 'cookiecutter' to be called once. Called 0 times.
tests/test_cli.py:330: AssertionError
test_cli.py::test_default_user_config_overwrite
test_cli.py::test_default_user_config_overwrite
self =
args = ('tests/fake-repo-pre/', None, False)
kwargs = {'accept_hooks': True, 'config_file': '/tmp/pytest-of-root/pytest-0/test_default_user_config_overw0/tests/config.yaml', 'default_config': True, 'directory': None, ...}
msg = "Expected 'cookiecutter' to be called once. Called 0 times."
def assert_called_once_with(self, /, *args, **kwargs):
"""assert that the mock was called exactly once and that that call was
with the specified arguments."""
if not self.call_count == 1:
msg = ("Expected '%s' to be called once. Called %s times.%s"
% (self._mock_name or 'mock',
self.call_count,
self._calls_repr()))
> raise AssertionError(msg)
E AssertionError: Expected 'cookiecutter' to be called once. Called 0 times.
/usr/lib/python3.10/unittest/mock.py:940: AssertionError
During handling of the above exception, another exception occurred:
mocker =
cli_runner = .cli_main at 0x7ffac9e128c0>
user_config_path = '/tmp/pytest-of-root/pytest-0/test_default_user_config_overw0/tests/config.yaml'
def test_default_user_config_overwrite(mocker, cli_runner, user_config_path):
"""Test cli invocation ignores `config-file` if `default-config` passed."""
mock_cookiecutter = mocker.patch('cookiecutter.cli.cookiecutter')
template_path = 'tests/fake-repo-pre/'
result = cli_runner(
template_path,
'--config-file',
user_config_path,
'--default-config',
)
assert result.exit_code == 0
> mock_cookiecutter.assert_called_once_with(
template_path,
None,
False,
replay=False,
overwrite_if_exists=False,
skip_if_file_exists=False,
output_dir='.',
config_file=user_config_path,
default_config=True,
extra_context=None,
password=None,
directory=None,
accept_hooks=True,
keep_project_on_failure=False,
)
E AssertionError: Expected 'cookiecutter' to be called once. Called 0 times.
tests/test_cli.py:361: AssertionError
test_cli.py::test_default_user_config
test_cli.py::test_default_user_config
self =
args = ('tests/fake-repo-pre/', None, False)
kwargs = {'accept_hooks': True, 'config_file': None, 'default_config': True, 'directory': None, ...}
msg = "Expected 'cookiecutter' to be called once. Called 0 times."
def assert_called_once_with(self, /, *args, **kwargs):
"""assert that the mock was called exactly once and that that call was
with the specified arguments."""
if not self.call_count == 1:
msg = ("Expected '%s' to be called once. Called %s times.%s"
% (self._mock_name or 'mock',
self.call_count,
self._calls_repr()))
> raise AssertionError(msg)
E AssertionError: Expected 'cookiecutter' to be called once. Called 0 times.
/usr/lib/python3.10/unittest/mock.py:940: AssertionError
During handling of the above exception, another exception occurred:
mocker =
cli_runner = .cli_main at 0x7ffac9e128c0>
def test_default_user_config(mocker, cli_runner):
"""Test cli invocation accepts `default-config` flag correctly."""
mock_cookiecutter = mocker.patch('cookiecutter.cli.cookiecutter')
template_path = 'tests/fake-repo-pre/'
result = cli_runner(template_path, '--default-config')
assert result.exit_code == 0
> mock_cookiecutter.assert_called_once_with(
template_path,
None,
False,
replay=False,
overwrite_if_exists=False,
skip_if_file_exists=False,
output_dir='.',
config_file=None,
default_config=True,
extra_context=None,
password=None,
directory=None,
accept_hooks=True,
keep_project_on_failure=False,
)
E AssertionError: Expected 'cookiecutter' to be called once. Called 0 times.
tests/test_cli.py:387: AssertionError
test_cli.py::test_echo_undefined_variable_error
test_cli.py::test_echo_undefined_variable_error
output_dir = '/tmp/pytest-of-root/pytest-0/test_echo_undefined_variable_e0/output'
cli_runner = .cli_main at 0x7ffac9e128c0>
def test_echo_undefined_variable_error(output_dir, cli_runner):
"""Cli invocation return error if variable undefined in template."""
template_path = 'tests/undefined-variable/file-name/'
result = cli_runner(
'--no-input',
'--default-config',
'--output-dir',
output_dir,
template_path,
)
> assert result.exit_code == 1
E assert 0 == 1
E + where 0 = .exit_code
tests/test_cli.py:417: AssertionError
test_cli.py::test_echo_unknown_extension_error
test_cli.py::test_echo_unknown_extension_error
output_dir = '/tmp/pytest-of-root/pytest-0/test_echo_unknown_extension_er0/output'
cli_runner = .cli_main at 0x7ffac9e128c0>
def test_echo_unknown_extension_error(output_dir, cli_runner):
"""Cli return error if extension incorrectly defined in template."""
template_path = 'tests/test-extensions/unknown/'
result = cli_runner(
'--no-input',
'--default-config',
'--output-dir',
output_dir,
template_path,
)
> assert result.exit_code == 1
E assert 0 == 1
E + where 0 = .exit_code
tests/test_cli.py:457: AssertionError
test_cli.py::test_local_extension
test_cli.py::test_local_extension
tmpdir = local('/tmp/pytest-of-root/pytest-0/test_local_extension0')
cli_runner = .cli_main at 0x7ffac9e128c0>
def test_local_extension(tmpdir, cli_runner):
"""Test to verify correct work of extension, included in template."""
output_dir = str(tmpdir.mkdir('output'))
template_path = 'tests/test-extensions/local_extension/'
result = cli_runner(
'--no-input',
'--default-config',
'--output-dir',
output_dir,
template_path,
)
assert result.exit_code == 0
> content = Path(output_dir, 'Foobar', 'HISTORY.rst').read_text()
tests/test_cli.py:475:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/lib/python3.10/pathlib.py:1134: in read_text
with self.open(mode='r', encoding=encoding, errors=errors) as f:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = PosixPath('/tmp/pytest-of-root/pytest-0/test_local_extension0/output/Foobar/HISTORY.rst')
mode = 'r', buffering = -1, encoding = 'locale', errors = None, newline = None
def open(self, mode='r', buffering=-1, encoding=None,
errors=None, newline=None):
"""
Open the file pointed by this path and return a file object, as
the built-in open() function does.
"""
if "b" not in mode:
encoding = io.text_encoding(encoding)
> return self._accessor.open(self, mode, buffering, encoding, errors,
newline)
E FileNotFoundError: [Errno 2] No such file or directory: '/tmp/pytest-of-root/pytest-0/test_local_extension0/output/Foobar/HISTORY.rst'
/usr/lib/python3.10/pathlib.py:1119: FileNotFoundError
test_cli.py::test_local_extension_not_available
test_cli.py::test_local_extension_not_available
tmpdir = local('/tmp/pytest-of-root/pytest-0/test_local_extension_not_avail0')
cli_runner = .cli_main at 0x7ffac9e128c0>
def test_local_extension_not_available(tmpdir, cli_runner):
"""Test handling of included but unavailable local extension."""
context = {'cookiecutter': {'_extensions': ['foobar']}}
with pytest.raises(UnknownExtension) as err:
> StrictEnvironment(context=context, keep_trailing_newline=True)
tests/test_cli.py:485:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
cookiecutter/environment.py:49: in __init__
super().__init__(undefined=StrictUndefined, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self =
kwargs = {'keep_trailing_newline': True, 'undefined': }
context = {'cookiecutter': {'_extensions': ['foobar']}}
default_extensions = ['cookiecutter.extensions.JsonifyExtension', 'cookiecutter.extensions.RandomStringExtension', 'cookiecutter.extensions.SlugifyExtension', 'cookiecutter.extensions.TimeExtension', 'cookiecutter.extensions.UUIDExtension']
def __init__(self, **kwargs):
"""Initialize the Jinja2 Environment object while loading extensions.
Does the following:
1. Establishes default_extensions (currently just a Time feature)
2. Reads extensions set in the cookiecutter.json _extensions key.
3. Attempts to load the extensions. Provides useful error if fails.
"""
context = kwargs.pop('context', {})
default_extensions = ['cookiecutter.extensions.JsonifyExtension', 'cookiecutter.extensions.RandomStringExtension', 'cookiecutter.extensions.SlugifyExtension', 'cookiecutter.extensions.TimeExtension', 'cookiecutter.extensions.UUIDExtension']
> extensions = default_extensions + self._read_extensions(context)
E TypeError: can only concatenate list (not "NoneType") to list
cookiecutter/environment.py:23: TypeError
test_cli.py::test_cli_extra_context
cli_runner = .cli_main at 0x7ffac9e128c0>
@pytest.mark.usefixtures('remove_fake_project_dir')
def test_cli_extra_context(cli_runner):
"""Cli invocation replace content if called with replacement pairs."""
result = cli_runner(
'tests/fake-repo-pre/',
'--no-input',
'-v',
'project_name=Awesomez',
)
assert result.exit_code == 0
assert os.path.isdir('fake-project')
> content = Path('fake-project', 'README.rst').read_text()
tests/test_cli.py:501:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/lib/python3.10/pathlib.py:1134: in read_text
with self.open(mode='r', encoding=encoding, errors=errors) as f:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = PosixPath('fake-project/README.rst'), mode = 'r', buffering = -1
encoding = 'locale', errors = None, newline = None
def open(self, mode='r', buffering=-1, encoding=None,
errors=None, newline=None):
"""
Open the file pointed by this path and return a file object, as
the built-in open() function does.
"""
if "b" not in mode:
encoding = io.text_encoding(encoding)
> return self._accessor.open(self, mode, buffering, encoding, errors,
newline)
E FileNotFoundError: [Errno 2] No such file or directory: 'fake-project/README.rst'
/usr/lib/python3.10/pathlib.py:1119: FileNotFoundError
test_cli.py::test_cli_extra_context_invalid_format
cli_runner = .cli_main at 0x7ffac9e128c0>
@pytest.mark.usefixtures('remove_fake_project_dir')
def test_cli_extra_context_invalid_format(cli_runner):
"""Cli invocation raise error if called with unknown argument."""
result = cli_runner(
'tests/fake-repo-pre/',
'--no-input',
'-v',
'ExtraContextWithNoEqualsSoInvalid',
)
> assert result.exit_code == 2
E assert 0 == 2
E + where 0 = .exit_code
tests/test_cli.py:514: AssertionError
test_cli.py::test_debug_file_non_verbose
test_cli.py::test_debug_file_non_verbose
cli_runner = .cli_main at 0x7ffac9e128c0>
debug_file = PosixPath('/tmp/pytest-of-root/pytest-0/test_debug_file_non_verbose0/fake-repo.log')
@pytest.mark.usefixtures('remove_fake_project_dir')
def test_debug_file_non_verbose(cli_runner, debug_file):
"""Test cli invocation writes log to `debug-file` if flag enabled.
Case for normal log output.
"""
assert not debug_file.exists()
result = cli_runner(
'--no-input',
'--debug-file',
str(debug_file),
'tests/fake-repo-pre/',
)
assert result.exit_code == 0
> assert debug_file.exists()
E AssertionError: assert False
E + where False = exists()
E + where exists = PosixPath('/tmp/pytest-of-root/pytest-0/test_debug_file_non_verbose0/fake-repo.log').exists
tests/test_cli.py:541: AssertionError
test_cli.py::test_debug_file_verbose
test_cli.py::test_debug_file_verbose
cli_runner = .cli_main at 0x7ffac9e128c0>
debug_file = PosixPath('/tmp/pytest-of-root/pytest-0/test_debug_file_verbose0/fake-repo.log')
@pytest.mark.usefixtures('remove_fake_project_dir')
def test_debug_file_verbose(cli_runner, debug_file):
"""Test cli invocation writes log to `debug-file` if flag enabled.
Case for verbose log output.
"""
assert not debug_file.exists()
result = cli_runner(
'--verbose',
'--no-input',
'--debug-file',
str(debug_file),
'tests/fake-repo-pre/',
)
assert result.exit_code == 0
> assert debug_file.exists()
E AssertionError: assert False
E + where False = exists()
E + where exists = PosixPath('/tmp/pytest-of-root/pytest-0/test_debug_file_verbose0/fake-repo.log').exists
tests/test_cli.py:568: AssertionError
test_cli.py::test_debug_list_installed_templates
test_cli.py::test_debug_list_installed_templates
request = >
@pytest.fixture
def make_fake_project_dir(request):
"""Create a fake project to be overwritten in the according tests."""
> os.makedirs('fake-project')
tests/test_cli.py:59:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
name = 'fake-project', mode = 511, exist_ok = False
def makedirs(name, mode=0o777, exist_ok=False):
"""makedirs(name [, mode=0o777][, exist_ok=False])
Super-mkdir; create a leaf directory and all intermediate ones. Works like
mkdir, except that any intermediate path segment (not just the rightmost)
will be created if it does not exist. If the target directory already
exists, raise an OSError if exist_ok is False. Otherwise no exception is
raised. This is recursive.
"""
head, tail = path.split(name)
if not tail:
head, tail = path.split(head)
if head and tail and not path.exists(head):
try:
makedirs(head, exist_ok=exist_ok)
except FileExistsError:
# Defeats race condition when another thread created the path
pass
cdir = curdir
if isinstance(tail, bytes):
cdir = bytes(curdir, 'ASCII')
if tail == cdir: # xxx/newdir/. exists if xxx/newdir exists
return
try:
> mkdir(name, mode)
E FileExistsError: [Errno 17] File exists: 'fake-project'
/usr/lib/python3.10/os.py:225: FileExistsError
test_cli.py::test_debug_list_installed_templates_failure
test_cli.py::test_debug_list_installed_templates_failure
cli_runner = .cli_main at 0x7ffac9e128c0>
debug_file = PosixPath('/tmp/pytest-of-root/pytest-0/test_debug_list_installed_temp1/fake-repo.log')
user_config_path = '/tmp/pytest-of-root/pytest-0/test_debug_list_installed_temp1/tests/config.yaml'
def test_debug_list_installed_templates_failure(
cli_runner, debug_file, user_config_path
):
"""Verify --list-installed command error on invocation."""
os.makedirs(os.path.dirname(user_config_path))
Path(user_config_path).write_text('cookiecutters_dir: "/notarealplace/"')
result = cli_runner(
'--list-installed', '--config-file', user_config_path, str(debug_file)
)
> assert "Error: Cannot list installed templates." in result.output
E AssertionError: assert 'Error: Cannot list installed templates.' in ''
E + where '' = .output
tests/test_cli.py:609: AssertionError
test_cli.py::test_directory_repo
test_cli.py::test_directory_repo
cli_runner = .cli_main at 0x7ffac9e128c0>
@pytest.mark.usefixtures('remove_fake_project_dir')
def test_directory_repo(cli_runner):
"""Test cli invocation works with `directory` option."""
result = cli_runner(
'tests/fake-repo-dir/',
'--no-input',
'-v',
'--directory=my-dir',
)
assert result.exit_code == 0
assert os.path.isdir("fake-project")
> content = Path("fake-project", "README.rst").read_text()
tests/test_cli.py:624:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/lib/python3.10/pathlib.py:1134: in read_text
with self.open(mode='r', encoding=encoding, errors=errors) as f:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = PosixPath('fake-project/README.rst'), mode = 'r', buffering = -1
encoding = 'locale', errors = None, newline = None
def open(self, mode='r', buffering=-1, encoding=None,
errors=None, newline=None):
"""
Open the file pointed by this path and return a file object, as
the built-in open() function does.
"""
if "b" not in mode:
encoding = io.text_encoding(encoding)
> return self._accessor.open(self, mode, buffering, encoding, errors,
newline)
E FileNotFoundError: [Errno 2] No such file or directory: 'fake-project/README.rst'
/usr/lib/python3.10/pathlib.py:1119: FileNotFoundError
test_cli.py::test_cli_accept_hooks[-o---accept-hooks=yes-None-True]
test_cli.py::test_cli_accept_hooks[-o---accept-hooks=yes-None-True]
self =
args = ('tests/fake-repo-pre/', None, False)
kwargs = {'accept_hooks': True, 'config_file': None, 'default_config': False, 'directory': None, ...}
msg = "Expected 'cookiecutter' to be called once. Called 0 times."
def assert_called_once_with(self, /, *args, **kwargs):
"""assert that the mock was called exactly once and that that call was
with the specified arguments."""
if not self.call_count == 1:
msg = ("Expected '%s' to be called once. Called %s times.%s"
% (self._mock_name or 'mock',
self.call_count,
self._calls_repr()))
> raise AssertionError(msg)
E AssertionError: Expected 'cookiecutter' to be called once. Called 0 times.
/usr/lib/python3.10/unittest/mock.py:940: AssertionError
During handling of the above exception, another exception occurred:
mocker =
cli_runner = .cli_main at 0x7ffac9e128c0>
output_dir_flag = '-o'
output_dir = '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks__o___acc0/output'
accept_hooks_arg = '--accept-hooks=yes', user_input = None, expected = True
@pytest.mark.parametrize(
"accept_hooks_arg,user_input,expected", cli_accept_hook_arg_testdata
)
def test_cli_accept_hooks(
mocker,
cli_runner,
output_dir_flag,
output_dir,
accept_hooks_arg,
user_input,
expected,
):
"""Test cli invocation works with `accept-hooks` option."""
mock_cookiecutter = mocker.patch("cookiecutter.cli.cookiecutter")
template_path = "tests/fake-repo-pre/"
result = cli_runner(
template_path, output_dir_flag, output_dir, accept_hooks_arg, input=user_input
)
assert result.exit_code == 0
> mock_cookiecutter.assert_called_once_with(
template_path,
None,
False,
replay=False,
overwrite_if_exists=False,
output_dir=output_dir,
config_file=None,
default_config=False,
extra_context=None,
password=None,
directory=None,
skip_if_file_exists=False,
accept_hooks=expected,
keep_project_on_failure=False,
)
E AssertionError: Expected 'cookiecutter' to be called once. Called 0 times.
tests/test_cli.py:657: AssertionError
test_cli.py::test_cli_accept_hooks[-o---accept-hooks=no-None-False]
test_cli.py::test_cli_accept_hooks[-o---accept-hooks=no-None-False]
self =
args = ('tests/fake-repo-pre/', None, False)
kwargs = {'accept_hooks': False, 'config_file': None, 'default_config': False, 'directory': None, ...}
msg = "Expected 'cookiecutter' to be called once. Called 0 times."
def assert_called_once_with(self, /, *args, **kwargs):
"""assert that the mock was called exactly once and that that call was
with the specified arguments."""
if not self.call_count == 1:
msg = ("Expected '%s' to be called once. Called %s times.%s"
% (self._mock_name or 'mock',
self.call_count,
self._calls_repr()))
> raise AssertionError(msg)
E AssertionError: Expected 'cookiecutter' to be called once. Called 0 times.
/usr/lib/python3.10/unittest/mock.py:940: AssertionError
During handling of the above exception, another exception occurred:
mocker =
cli_runner = .cli_main at 0x7ffac9e128c0>
output_dir_flag = '-o'
output_dir = '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks__o___acc1/output'
accept_hooks_arg = '--accept-hooks=no', user_input = None, expected = False
@pytest.mark.parametrize(
"accept_hooks_arg,user_input,expected", cli_accept_hook_arg_testdata
)
def test_cli_accept_hooks(
mocker,
cli_runner,
output_dir_flag,
output_dir,
accept_hooks_arg,
user_input,
expected,
):
"""Test cli invocation works with `accept-hooks` option."""
mock_cookiecutter = mocker.patch("cookiecutter.cli.cookiecutter")
template_path = "tests/fake-repo-pre/"
result = cli_runner(
template_path, output_dir_flag, output_dir, accept_hooks_arg, input=user_input
)
assert result.exit_code == 0
> mock_cookiecutter.assert_called_once_with(
template_path,
None,
False,
replay=False,
overwrite_if_exists=False,
output_dir=output_dir,
config_file=None,
default_config=False,
extra_context=None,
password=None,
directory=None,
skip_if_file_exists=False,
accept_hooks=expected,
keep_project_on_failure=False,
)
E AssertionError: Expected 'cookiecutter' to be called once. Called 0 times.
tests/test_cli.py:657: AssertionError
test_cli.py::test_cli_accept_hooks[-o---accept-hooks=ask-yes-True]
test_cli.py::test_cli_accept_hooks[-o---accept-hooks=ask-yes-True]
self =
args = ('tests/fake-repo-pre/', None, False)
kwargs = {'accept_hooks': True, 'config_file': None, 'default_config': False, 'directory': None, ...}
msg = "Expected 'cookiecutter' to be called once. Called 0 times."
def assert_called_once_with(self, /, *args, **kwargs):
"""assert that the mock was called exactly once and that that call was
with the specified arguments."""
if not self.call_count == 1:
msg = ("Expected '%s' to be called once. Called %s times.%s"
% (self._mock_name or 'mock',
self.call_count,
self._calls_repr()))
> raise AssertionError(msg)
E AssertionError: Expected 'cookiecutter' to be called once. Called 0 times.
/usr/lib/python3.10/unittest/mock.py:940: AssertionError
During handling of the above exception, another exception occurred:
mocker =
cli_runner = .cli_main at 0x7ffac9e128c0>
output_dir_flag = '-o'
output_dir = '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks__o___acc2/output'
accept_hooks_arg = '--accept-hooks=ask', user_input = 'yes', expected = True
@pytest.mark.parametrize(
"accept_hooks_arg,user_input,expected", cli_accept_hook_arg_testdata
)
def test_cli_accept_hooks(
mocker,
cli_runner,
output_dir_flag,
output_dir,
accept_hooks_arg,
user_input,
expected,
):
"""Test cli invocation works with `accept-hooks` option."""
mock_cookiecutter = mocker.patch("cookiecutter.cli.cookiecutter")
template_path = "tests/fake-repo-pre/"
result = cli_runner(
template_path, output_dir_flag, output_dir, accept_hooks_arg, input=user_input
)
assert result.exit_code == 0
> mock_cookiecutter.assert_called_once_with(
template_path,
None,
False,
replay=False,
overwrite_if_exists=False,
output_dir=output_dir,
config_file=None,
default_config=False,
extra_context=None,
password=None,
directory=None,
skip_if_file_exists=False,
accept_hooks=expected,
keep_project_on_failure=False,
)
E AssertionError: Expected 'cookiecutter' to be called once. Called 0 times.
tests/test_cli.py:657: AssertionError
test_cli.py::test_cli_accept_hooks[-o---accept-hooks=ask-no-False]
test_cli.py::test_cli_accept_hooks[-o---accept-hooks=ask-no-False]
self =
args = ('tests/fake-repo-pre/', None, False)
kwargs = {'accept_hooks': False, 'config_file': None, 'default_config': False, 'directory': None, ...}
msg = "Expected 'cookiecutter' to be called once. Called 0 times."
def assert_called_once_with(self, /, *args, **kwargs):
"""assert that the mock was called exactly once and that that call was
with the specified arguments."""
if not self.call_count == 1:
msg = ("Expected '%s' to be called once. Called %s times.%s"
% (self._mock_name or 'mock',
self.call_count,
self._calls_repr()))
> raise AssertionError(msg)
E AssertionError: Expected 'cookiecutter' to be called once. Called 0 times.
/usr/lib/python3.10/unittest/mock.py:940: AssertionError
During handling of the above exception, another exception occurred:
mocker =
cli_runner = .cli_main at 0x7ffac9e128c0>
output_dir_flag = '-o'
output_dir = '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks__o___acc3/output'
accept_hooks_arg = '--accept-hooks=ask', user_input = 'no', expected = False
@pytest.mark.parametrize(
"accept_hooks_arg,user_input,expected", cli_accept_hook_arg_testdata
)
def test_cli_accept_hooks(
mocker,
cli_runner,
output_dir_flag,
output_dir,
accept_hooks_arg,
user_input,
expected,
):
"""Test cli invocation works with `accept-hooks` option."""
mock_cookiecutter = mocker.patch("cookiecutter.cli.cookiecutter")
template_path = "tests/fake-repo-pre/"
result = cli_runner(
template_path, output_dir_flag, output_dir, accept_hooks_arg, input=user_input
)
assert result.exit_code == 0
> mock_cookiecutter.assert_called_once_with(
template_path,
None,
False,
replay=False,
overwrite_if_exists=False,
output_dir=output_dir,
config_file=None,
default_config=False,
extra_context=None,
password=None,
directory=None,
skip_if_file_exists=False,
accept_hooks=expected,
keep_project_on_failure=False,
)
E AssertionError: Expected 'cookiecutter' to be called once. Called 0 times.
tests/test_cli.py:657: AssertionError
test_cli.py::test_cli_accept_hooks[--output-dir---accept-hooks=yes-None-True]
test_cli.py::test_cli_accept_hooks[--output-dir---accept-hooks=yes-None-True]
self =
args = ('tests/fake-repo-pre/', None, False)
kwargs = {'accept_hooks': True, 'config_file': None, 'default_config': False, 'directory': None, ...}
msg = "Expected 'cookiecutter' to be called once. Called 0 times."
def assert_called_once_with(self, /, *args, **kwargs):
"""assert that the mock was called exactly once and that that call was
with the specified arguments."""
if not self.call_count == 1:
msg = ("Expected '%s' to be called once. Called %s times.%s"
% (self._mock_name or 'mock',
self.call_count,
self._calls_repr()))
> raise AssertionError(msg)
E AssertionError: Expected 'cookiecutter' to be called once. Called 0 times.
/usr/lib/python3.10/unittest/mock.py:940: AssertionError
During handling of the above exception, another exception occurred:
mocker =
cli_runner = .cli_main at 0x7ffac9e128c0>
output_dir_flag = '--output-dir'
output_dir = '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks___output0/output'
accept_hooks_arg = '--accept-hooks=yes', user_input = None, expected = True
@pytest.mark.parametrize(
"accept_hooks_arg,user_input,expected", cli_accept_hook_arg_testdata
)
def test_cli_accept_hooks(
mocker,
cli_runner,
output_dir_flag,
output_dir,
accept_hooks_arg,
user_input,
expected,
):
"""Test cli invocation works with `accept-hooks` option."""
mock_cookiecutter = mocker.patch("cookiecutter.cli.cookiecutter")
template_path = "tests/fake-repo-pre/"
result = cli_runner(
template_path, output_dir_flag, output_dir, accept_hooks_arg, input=user_input
)
assert result.exit_code == 0
> mock_cookiecutter.assert_called_once_with(
template_path,
None,
False,
replay=False,
overwrite_if_exists=False,
output_dir=output_dir,
config_file=None,
default_config=False,
extra_context=None,
password=None,
directory=None,
skip_if_file_exists=False,
accept_hooks=expected,
keep_project_on_failure=False,
)
E AssertionError: Expected 'cookiecutter' to be called once. Called 0 times.
tests/test_cli.py:657: AssertionError
test_cli.py::test_cli_accept_hooks[--output-dir---accept-hooks=no-None-False]
test_cli.py::test_cli_accept_hooks[--output-dir---accept-hooks=no-None-False]
self =
args = ('tests/fake-repo-pre/', None, False)
kwargs = {'accept_hooks': False, 'config_file': None, 'default_config': False, 'directory': None, ...}
msg = "Expected 'cookiecutter' to be called once. Called 0 times."
def assert_called_once_with(self, /, *args, **kwargs):
"""assert that the mock was called exactly once and that that call was
with the specified arguments."""
if not self.call_count == 1:
msg = ("Expected '%s' to be called once. Called %s times.%s"
% (self._mock_name or 'mock',
self.call_count,
self._calls_repr()))
> raise AssertionError(msg)
E AssertionError: Expected 'cookiecutter' to be called once. Called 0 times.
/usr/lib/python3.10/unittest/mock.py:940: AssertionError
During handling of the above exception, another exception occurred:
mocker =
cli_runner = .cli_main at 0x7ffac9e128c0>
output_dir_flag = '--output-dir'
output_dir = '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks___output1/output'
accept_hooks_arg = '--accept-hooks=no', user_input = None, expected = False
@pytest.mark.parametrize(
"accept_hooks_arg,user_input,expected", cli_accept_hook_arg_testdata
)
def test_cli_accept_hooks(
mocker,
cli_runner,
output_dir_flag,
output_dir,
accept_hooks_arg,
user_input,
expected,
):
"""Test cli invocation works with `accept-hooks` option."""
mock_cookiecutter = mocker.patch("cookiecutter.cli.cookiecutter")
template_path = "tests/fake-repo-pre/"
result = cli_runner(
template_path, output_dir_flag, output_dir, accept_hooks_arg, input=user_input
)
assert result.exit_code == 0
> mock_cookiecutter.assert_called_once_with(
template_path,
None,
False,
replay=False,
overwrite_if_exists=False,
output_dir=output_dir,
config_file=None,
default_config=False,
extra_context=None,
password=None,
directory=None,
skip_if_file_exists=False,
accept_hooks=expected,
keep_project_on_failure=False,
)
E AssertionError: Expected 'cookiecutter' to be called once. Called 0 times.
tests/test_cli.py:657: AssertionError
test_cli.py::test_cli_accept_hooks[--output-dir---accept-hooks=ask-yes-True]
test_cli.py::test_cli_accept_hooks[--output-dir---accept-hooks=ask-yes-True]
self =
args = ('tests/fake-repo-pre/', None, False)
kwargs = {'accept_hooks': True, 'config_file': None, 'default_config': False, 'directory': None, ...}
msg = "Expected 'cookiecutter' to be called once. Called 0 times."
def assert_called_once_with(self, /, *args, **kwargs):
"""assert that the mock was called exactly once and that that call was
with the specified arguments."""
if not self.call_count == 1:
msg = ("Expected '%s' to be called once. Called %s times.%s"
% (self._mock_name or 'mock',
self.call_count,
self._calls_repr()))
> raise AssertionError(msg)
E AssertionError: Expected 'cookiecutter' to be called once. Called 0 times.
/usr/lib/python3.10/unittest/mock.py:940: AssertionError
During handling of the above exception, another exception occurred:
mocker =
cli_runner = .cli_main at 0x7ffac9e128c0>
output_dir_flag = '--output-dir'
output_dir = '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks___output2/output'
accept_hooks_arg = '--accept-hooks=ask', user_input = 'yes', expected = True
@pytest.mark.parametrize(
"accept_hooks_arg,user_input,expected", cli_accept_hook_arg_testdata
)
def test_cli_accept_hooks(
mocker,
cli_runner,
output_dir_flag,
output_dir,
accept_hooks_arg,
user_input,
expected,
):
"""Test cli invocation works with `accept-hooks` option."""
mock_cookiecutter = mocker.patch("cookiecutter.cli.cookiecutter")
template_path = "tests/fake-repo-pre/"
result = cli_runner(
template_path, output_dir_flag, output_dir, accept_hooks_arg, input=user_input
)
assert result.exit_code == 0
> mock_cookiecutter.assert_called_once_with(
template_path,
None,
False,
replay=False,
overwrite_if_exists=False,
output_dir=output_dir,
config_file=None,
default_config=False,
extra_context=None,
password=None,
directory=None,
skip_if_file_exists=False,
accept_hooks=expected,
keep_project_on_failure=False,
)
E AssertionError: Expected 'cookiecutter' to be called once. Called 0 times.
tests/test_cli.py:657: AssertionError
test_cli.py::test_cli_accept_hooks[--output-dir---accept-hooks=ask-no-False]
test_cli.py::test_cli_accept_hooks[--output-dir---accept-hooks=ask-no-False]
self =
args = ('tests/fake-repo-pre/', None, False)
kwargs = {'accept_hooks': False, 'config_file': None, 'default_config': False, 'directory': None, ...}
msg = "Expected 'cookiecutter' to be called once. Called 0 times."
def assert_called_once_with(self, /, *args, **kwargs):
"""assert that the mock was called exactly once and that that call was
with the specified arguments."""
if not self.call_count == 1:
msg = ("Expected '%s' to be called once. Called %s times.%s"
% (self._mock_name or 'mock',
self.call_count,
self._calls_repr()))
> raise AssertionError(msg)
E AssertionError: Expected 'cookiecutter' to be called once. Called 0 times.
/usr/lib/python3.10/unittest/mock.py:940: AssertionError
During handling of the above exception, another exception occurred:
mocker =
cli_runner = .cli_main at 0x7ffac9e128c0>
output_dir_flag = '--output-dir'
output_dir = '/tmp/pytest-of-root/pytest-0/test_cli_accept_hooks___output3/output'
accept_hooks_arg = '--accept-hooks=ask', user_input = 'no', expected = False
@pytest.mark.parametrize(
"accept_hooks_arg,user_input,expected", cli_accept_hook_arg_testdata
)
def test_cli_accept_hooks(
mocker,
cli_runner,
output_dir_flag,
output_dir,
accept_hooks_arg,
user_input,
expected,
):
"""Test cli invocation works with `accept-hooks` option."""
mock_cookiecutter = mocker.patch("cookiecutter.cli.cookiecutter")
template_path = "tests/fake-repo-pre/"
result = cli_runner(
template_path, output_dir_flag, output_dir, accept_hooks_arg, input=user_input
)
assert result.exit_code == 0
> mock_cookiecutter.assert_called_once_with(
template_path,
None,
False,
replay=False,
overwrite_if_exists=False,
output_dir=output_dir,
config_file=None,
default_config=False,
extra_context=None,
password=None,
directory=None,
skip_if_file_exists=False,
accept_hooks=expected,
keep_project_on_failure=False,
)
E AssertionError: Expected 'cookiecutter' to be called once. Called 0 times.
tests/test_cli.py:657: AssertionError
test_cli.py::test_cli_with_json_decoding_error
test_cli.py::test_cli_with_json_decoding_error
cli_runner = .cli_main at 0x7ffac9e128c0>
@pytest.mark.usefixtures('remove_fake_project_dir')
def test_cli_with_json_decoding_error(cli_runner):
"""Test cli invocation with a malformed JSON file."""
template_path = 'tests/fake-repo-bad-json/'
result = cli_runner(template_path, '--no-input')
> assert result.exit_code != 0
E assert 0 != 0
E + where 0 = .exit_code
tests/test_cli.py:680: AssertionError
test_cli.py::test_cli_with_pre_prompt_hook
test_cli.py::test_cli_with_pre_prompt_hook
cli_runner = .cli_main at 0x7ffac9e128c0>
@pytest.mark.usefixtures('remove_fake_project_dir')
def test_cli_with_pre_prompt_hook(cli_runner):
"""Test cli invocation in a template with pre_prompt hook."""
template_path = 'tests/test-pyhooks/'
result = cli_runner(template_path, '--no-input')
assert result.exit_code == 0
dir_name = 'inputfake-project'
> assert os.path.isdir(dir_name)
E AssertionError: assert False
E + where False = ('inputfake-project')
E + where = .isdir
E + where = os.path
tests/test_cli.py:701: AssertionError
test_cli.py::test_cli_with_pre_prompt_hook_fail
test_cli.py::test_cli_with_pre_prompt_hook_fail
cli_runner = .cli_main at 0x7ffac9e128c0>
monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0x7ffacbb53970>
def test_cli_with_pre_prompt_hook_fail(cli_runner, monkeypatch):
"""Test cli invocation will fail when a given env var is present."""
template_path = 'tests/test-pyhooks/'
with monkeypatch.context() as m:
m.setenv('COOKIECUTTER_FAIL_PRE_PROMPT', '1')
result = cli_runner(template_path, '--no-input')
> assert result.exit_code == 1
E assert 0 == 1
E + where 0 = .exit_code
tests/test_cli.py:712: AssertionError
test_cookiecutter_invocation.py::test_should_invoke_main
test_cookiecutter_invocation.py::test_should_invoke_main
monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0x7ffac9afeb30>
project_dir = 'fake-project-templated'
@pytest.mark.usefixtures('clean_system')
def test_should_invoke_main(monkeypatch, project_dir):
"""Should create a project and exit with 0 code on cli invocation."""
monkeypatch.setenv('PYTHONPATH', '.')
exit_code = subprocess.check_call(
[sys.executable, '-m', 'cookiecutter.cli', 'tests/fake-repo-tmpl', '--no-input']
)
assert exit_code == 0
> assert os.path.isdir(project_dir)
E AssertionError: assert False
E + where False = ('fake-project-templated')
E + where = .isdir
E + where = os.path
tests/test_cookiecutter_invocation.py:35: AssertionError
]
]
path = 'tests/fake-repo-pre/'
@pytest.mark.parametrize('path', ['tests/fake-repo-pre/', 'tests/fake-repo-pre'])
@pytest.mark.usefixtures('clean_system', 'remove_additional_dirs')
def test_cookiecutter_no_input_return_project_dir(path):
"""Verify `cookiecutter` create project dir on input with or without slash."""
project_dir = main.cookiecutter(path, no_input=True)
assert os.path.isdir('tests/fake-repo-pre/{{cookiecutter.repo_name}}')
assert not os.path.isdir('tests/fake-repo-pre/fake-project')
> assert os.path.isdir(project_dir)
tests/test_cookiecutter_local_no_input.py:42:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
s = None
def isdir(s):
"""Return true if the pathname refers to an existing directory."""
try:
> st = os.stat(s)
E TypeError: stat: path should be string, bytes, os.PathLike or integer, not NoneType
/usr/lib/python3.10/genericpath.py:42: TypeError
fake-repo-pre]
fake-repo-pre]
path = 'tests/fake-repo-pre'
@pytest.mark.parametrize('path', ['tests/fake-repo-pre/', 'tests/fake-repo-pre'])
@pytest.mark.usefixtures('clean_system', 'remove_additional_dirs')
def test_cookiecutter_no_input_return_project_dir(path):
"""Verify `cookiecutter` create project dir on input with or without slash."""
project_dir = main.cookiecutter(path, no_input=True)
assert os.path.isdir('tests/fake-repo-pre/{{cookiecutter.repo_name}}')
assert not os.path.isdir('tests/fake-repo-pre/fake-project')
> assert os.path.isdir(project_dir)
tests/test_cookiecutter_local_no_input.py:42:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
s = None
def isdir(s):
"""Return true if the pathname refers to an existing directory."""
try:
> st = os.stat(s)
E TypeError: stat: path should be string, bytes, os.PathLike or integer, not NoneType
/usr/lib/python3.10/genericpath.py:42: TypeError
test_cookiecutter_local_no_input.py::test_cookiecutter_no_input_extra_context
@pytest.mark.usefixtures('clean_system', 'remove_additional_dirs')
def test_cookiecutter_no_input_extra_context():
"""Verify `cookiecutter` accept `extra_context` argument."""
main.cookiecutter(
'tests/fake-repo-pre',
no_input=True,
extra_context={'repo_name': 'fake-project-extra'},
)
> assert os.path.isdir('fake-project-extra')
E AssertionError: assert False
E + where False = ('fake-project-extra')
E + where = .isdir
E + where = os.path
tests/test_cookiecutter_local_no_input.py:55: AssertionError
test_cookiecutter_local_no_input.py::test_cookiecutter_templated_context
test_cookiecutter_local_no_input.py::test_cookiecutter_templated_context
@pytest.mark.usefixtures('clean_system', 'remove_additional_dirs')
def test_cookiecutter_templated_context():
"""Verify Jinja2 templating correctly works in `cookiecutter.json` file."""
main.cookiecutter('tests/fake-repo-tmpl', no_input=True)
> assert os.path.isdir('fake-project-templated')
E AssertionError: assert False
E + where False = ('fake-project-templated')
E + where = .isdir
E + where = os.path
tests/test_cookiecutter_local_no_input.py:62: AssertionError
test_cookiecutter_local_no_input.py::test_cookiecutter_no_input_return_rendered_file
@pytest.mark.usefixtures('clean_system', 'remove_additional_dirs')
def test_cookiecutter_no_input_return_rendered_file():
"""Verify Jinja2 templating correctly works in `cookiecutter.json` file."""
project_dir = main.cookiecutter('tests/fake-repo-pre', no_input=True)
> assert project_dir == os.path.abspath('fake-project')
E AssertionError: assert None == '/testbed/fake-project'
E + where '/testbed/fake-project' = ('fake-project')
E + where = .abspath
E + where = os.path
tests/test_cookiecutter_local_no_input.py:69: AssertionError
test_cookiecutter_local_no_input.py::test_cookiecutter_dict_values_in_context
test_cookiecutter_local_no_input.py::test_cookiecutter_dict_values_in_context
@pytest.mark.usefixtures('clean_system', 'remove_additional_dirs')
def test_cookiecutter_dict_values_in_context():
"""Verify configured dictionary from `cookiecutter.json` correctly unpacked."""
project_dir = main.cookiecutter('tests/fake-repo-dict', no_input=True)
> assert project_dir == os.path.abspath('fake-project-dict')
E AssertionError: assert None == '/testbed/fake-project-dict'
E + where '/testbed/fake-project-dict' = ('fake-project-dict')
E + where = .abspath
E + where = os.path
tests/test_cookiecutter_local_no_input.py:78: AssertionError
test_cookiecutter_local_no_input.py::test_cookiecutter_template_cleanup
mocker =
@pytest.mark.usefixtures('clean_system', 'remove_additional_dirs')
def test_cookiecutter_template_cleanup(mocker):
"""Verify temporary folder for zip unpacking dropped."""
mocker.patch('tempfile.mkdtemp', return_value='fake-tmp', autospec=True)
mocker.patch(
'cookiecutter.prompt.prompt_and_delete', return_value=True, autospec=True
)
main.cookiecutter('tests/files/fake-repo-tmpl.zip', no_input=True)
> assert os.path.isdir('fake-project-templated')
E AssertionError: assert False
E + where False = ('fake-project-templated')
E + where = .isdir
E + where = os.path
tests/test_cookiecutter_local_no_input.py:134: AssertionError
test_cookiecutter_local_with_input.py::test_cookiecutter_local_with_input
monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0x7ffac9d03e20>
@pytest.mark.usefixtures('clean_system', 'remove_additional_dirs')
def test_cookiecutter_local_with_input(monkeypatch):
"""Verify simple cookiecutter run results, without extra_context provided."""
monkeypatch.setattr(
'cookiecutter.prompt.read_user_variable',
lambda var, default, prompts, prefix: default,
)
main.cookiecutter('tests/fake-repo-pre/', no_input=False)
assert os.path.isdir('tests/fake-repo-pre/{{cookiecutter.repo_name}}')
assert not os.path.isdir('tests/fake-repo-pre/fake-project')
assert os.path.isdir('fake-project')
> assert os.path.isfile('fake-project/README.rst')
E AssertionError: assert False
E + where False = ('fake-project/README.rst')
E + where = .isfile
E + where = os.path
tests/test_cookiecutter_local_with_input.py:31: AssertionError
test_cookiecutter_local_with_input.py::test_cookiecutter_input_extra_context
monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0x7ffac9d03010>
@pytest.mark.usefixtures('clean_system', 'remove_additional_dirs')
def test_cookiecutter_input_extra_context(monkeypatch):
"""Verify simple cookiecutter run results, with extra_context provided."""
monkeypatch.setattr(
'cookiecutter.prompt.read_user_variable',
lambda var, default, prompts, prefix: default,
)
main.cookiecutter(
'tests/fake-repo-pre',
no_input=False,
extra_context={'repo_name': 'fake-project-input-extra'},
)
> assert os.path.isdir('fake-project-input-extra')
E AssertionError: assert False
E + where False = ('fake-project-input-extra')
E + where = .isdir
E + where = os.path
tests/test_cookiecutter_local_with_input.py:47: AssertionError
test_cookiecutter_nested_templates.py::test_cookiecutter_nested_templates[fake-nested-templates-fake-project]
test_cookiecutter_nested_templates.py::test_cookiecutter_nested_templates[fake-nested-templates-fake-project]
mocker =
template_dir = 'fake-nested-templates', output_dir = 'fake-project'
@pytest.mark.parametrize(
"template_dir,output_dir",
[
["fake-nested-templates", "fake-project"],
["fake-nested-templates-old-style", "fake-package"],
],
)
def test_cookiecutter_nested_templates(mocker, template_dir: str, output_dir: str):
"""Verify cookiecutter nested configuration files mechanism."""
mock_generate_files = mocker.patch("cookiecutter.main.generate_files")
main_dir = (Path("tests") / template_dir).resolve()
main.cookiecutter(f"{main_dir}", no_input=True)
expected = (Path(main_dir) / output_dir).resolve()
> assert mock_generate_files.call_args[1]["repo_dir"] == f"{expected}"
E TypeError: 'NoneType' object is not subscriptable
tests/test_cookiecutter_nested_templates.py:23: TypeError
test_cookiecutter_nested_templates.py::test_cookiecutter_nested_templates[fake-nested-templates-old-style-fake-package]
test_cookiecutter_nested_templates.py::test_cookiecutter_nested_templates[fake-nested-templates-old-style-fake-package]
mocker =
template_dir = 'fake-nested-templates-old-style', output_dir = 'fake-package'
@pytest.mark.parametrize(
"template_dir,output_dir",
[
["fake-nested-templates", "fake-project"],
["fake-nested-templates-old-style", "fake-package"],
],
)
def test_cookiecutter_nested_templates(mocker, template_dir: str, output_dir: str):
"""Verify cookiecutter nested configuration files mechanism."""
mock_generate_files = mocker.patch("cookiecutter.main.generate_files")
main_dir = (Path("tests") / template_dir).resolve()
main.cookiecutter(f"{main_dir}", no_input=True)
expected = (Path(main_dir) / output_dir).resolve()
> assert mock_generate_files.call_args[1]["repo_dir"] == f"{expected}"
E TypeError: 'NoneType' object is not subscriptable
tests/test_cookiecutter_nested_templates.py:23: TypeError
test_custom_extensions_in_hooks.py::test_hook_with_extension[pre_gen_hook]
test_custom_extensions_in_hooks.py::test_hook_with_extension[pre_gen_hook]
template = 'tests/test-extensions/custom-extension-pre'
output_dir = '/tmp/pytest-of-root/pytest-0/test_hook_with_extension_pre_g0/output'
def test_hook_with_extension(template, output_dir):
"""Verify custom Jinja2 extension correctly work in hooks and file rendering.
Each file in hooks has simple tests inside and will raise error if not
correctly rendered.
"""
project_dir = main.cookiecutter(
template,
no_input=True,
output_dir=output_dir,
extra_context={'project_slug': 'foobar', 'name': 'Cookiemonster'},
)
> readme = Path(project_dir, 'README.rst').read_text(encoding="utf-8")
tests/test_custom_extensions_in_hooks.py:43:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/lib/python3.10/pathlib.py:960: in __new__
self = cls._from_parts(args)
/usr/lib/python3.10/pathlib.py:594: in _from_parts
drv, root, parts = self._parse_args(args)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
cls = , args = (None, 'README.rst')
@classmethod
def _parse_args(cls, args):
# This is useful when you don't want to create an instance, just
# canonicalize some constructor arguments.
parts = []
for a in args:
if isinstance(a, PurePath):
parts += a._parts
else:
> a = os.fspath(a)
E TypeError: expected str, bytes or os.PathLike object, not NoneType
/usr/lib/python3.10/pathlib.py:578: TypeError
test_custom_extensions_in_hooks.py::test_hook_with_extension[post_gen_hook]
test_custom_extensions_in_hooks.py::test_hook_with_extension[post_gen_hook]
template = 'tests/test-extensions/custom-extension-post'
output_dir = '/tmp/pytest-of-root/pytest-0/test_hook_with_extension_post_0/output'
def test_hook_with_extension(template, output_dir):
"""Verify custom Jinja2 extension correctly work in hooks and file rendering.
Each file in hooks has simple tests inside and will raise error if not
correctly rendered.
"""
project_dir = main.cookiecutter(
template,
no_input=True,
output_dir=output_dir,
extra_context={'project_slug': 'foobar', 'name': 'Cookiemonster'},
)
> readme = Path(project_dir, 'README.rst').read_text(encoding="utf-8")
tests/test_custom_extensions_in_hooks.py:43:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/lib/python3.10/pathlib.py:960: in __new__
self = cls._from_parts(args)
/usr/lib/python3.10/pathlib.py:594: in _from_parts
drv, root, parts = self._parse_args(args)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
cls = , args = (None, 'README.rst')
@classmethod
def _parse_args(cls, args):
# This is useful when you don't want to create an instance, just
# canonicalize some constructor arguments.
parts = []
for a in args:
if isinstance(a, PurePath):
parts += a._parts
else:
> a = os.fspath(a)
E TypeError: expected str, bytes or os.PathLike object, not NoneType
/usr/lib/python3.10/pathlib.py:578: TypeError
test_default_extensions.py::test_jinja2_time_extension
test_default_extensions.py::test_jinja2_time_extension
tmp_path = PosixPath('/tmp/pytest-of-root/pytest-0/test_jinja2_time_extension0')
def test_jinja2_time_extension(tmp_path):
"""Verify Jinja2 time extension work correctly."""
project_dir = cookiecutter(
'tests/test-extensions/default/', no_input=True, output_dir=str(tmp_path)
)
> changelog_file = os.path.join(project_dir, 'HISTORY.rst')
tests/test_default_extensions.py:27:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
a = None, p = ('HISTORY.rst',)
def join(a, *p):
"""Join two or more pathname components, inserting '/' as needed.
If any component is an absolute path, all previous path components
will be discarded. An empty last part will result in a path that
ends with a separator."""
> a = os.fspath(a)
E TypeError: expected str, bytes or os.PathLike object, not NoneType
/usr/lib/python3.10/posixpath.py:76: TypeError
test_default_extensions.py::test_jinja2_slugify_extension
test_default_extensions.py::test_jinja2_slugify_extension
tmp_path = PosixPath('/tmp/pytest-of-root/pytest-0/test_jinja2_slugify_extension0')
def test_jinja2_slugify_extension(tmp_path):
"""Verify Jinja2 slugify extension work correctly."""
project_dir = cookiecutter(
'tests/test-extensions/default/', no_input=True, output_dir=str(tmp_path)
)
> assert os.path.basename(project_dir) == "it-s-slugified-foobar"
tests/test_default_extensions.py:51:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
p = None
def basename(p):
"""Returns the final component of a pathname"""
> p = os.fspath(p)
E TypeError: expected str, bytes or os.PathLike object, not NoneType
/usr/lib/python3.10/posixpath.py:142: TypeError
test_default_extensions.py::test_jinja2_uuid_extension
test_default_extensions.py::test_jinja2_uuid_extension
tmp_path = PosixPath('/tmp/pytest-of-root/pytest-0/test_jinja2_uuid_extension0')
def test_jinja2_uuid_extension(tmp_path):
"""Verify Jinja2 uuid extension work correctly."""
project_dir = cookiecutter(
'tests/test-extensions/default/', no_input=True, output_dir=str(tmp_path)
)
> changelog_file = os.path.join(project_dir, 'id')
tests/test_default_extensions.py:59:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
a = None, p = ('id',)
def join(a, *p):
"""Join two or more pathname components, inserting '/' as needed.
If any component is an absolute path, all previous path components
will be discarded. An empty last part will result in a path that
ends with a separator."""
> a = os.fspath(a)
E TypeError: expected str, bytes or os.PathLike object, not NoneType
/usr/lib/python3.10/posixpath.py:76: TypeError
test_environment.py::test_env_should_raise_for_unknown_extension
test_environment.py::test_env_should_raise_for_unknown_extension
def test_env_should_raise_for_unknown_extension():
"""Test should raise if extension not installed in system."""
context = {'cookiecutter': {'_extensions': ['foobar']}}
with pytest.raises(UnknownExtension) as err:
> StrictEnvironment(context=context, keep_trailing_newline=True)
tests/test_environment.py:14:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
cookiecutter/environment.py:49: in __init__
super().__init__(undefined=StrictUndefined, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self =
kwargs = {'keep_trailing_newline': True, 'undefined': }
context = {'cookiecutter': {'_extensions': ['foobar']}}
default_extensions = ['cookiecutter.extensions.JsonifyExtension', 'cookiecutter.extensions.RandomStringExtension', 'cookiecutter.extensions.SlugifyExtension', 'cookiecutter.extensions.TimeExtension', 'cookiecutter.extensions.UUIDExtension']
def __init__(self, **kwargs):
"""Initialize the Jinja2 Environment object while loading extensions.
Does the following:
1. Establishes default_extensions (currently just a Time feature)
2. Reads extensions set in the cookiecutter.json _extensions key.
3. Attempts to load the extensions. Provides useful error if fails.
"""
context = kwargs.pop('context', {})
default_extensions = ['cookiecutter.extensions.JsonifyExtension', 'cookiecutter.extensions.RandomStringExtension', 'cookiecutter.extensions.SlugifyExtension', 'cookiecutter.extensions.TimeExtension', 'cookiecutter.extensions.UUIDExtension']
> extensions = default_extensions + self._read_extensions(context)
E TypeError: can only concatenate list (not "NoneType") to list
cookiecutter/environment.py:23: TypeError
test_environment.py::test_env_should_come_with_default_extensions
test_environment.py::test_env_should_come_with_default_extensions
def test_env_should_come_with_default_extensions():
"""Verify default extensions loaded with StrictEnvironment."""
> env = StrictEnvironment(keep_trailing_newline=True)
tests/test_environment.py:21:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
cookiecutter/environment.py:49: in __init__
super().__init__(undefined=StrictUndefined, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self =
kwargs = {'keep_trailing_newline': True, 'undefined': }
context = {}
default_extensions = ['cookiecutter.extensions.JsonifyExtension', 'cookiecutter.extensions.RandomStringExtension', 'cookiecutter.extensions.SlugifyExtension', 'cookiecutter.extensions.TimeExtension', 'cookiecutter.extensions.UUIDExtension']
def __init__(self, **kwargs):
"""Initialize the Jinja2 Environment object while loading extensions.
Does the following:
1. Establishes default_extensions (currently just a Time feature)
2. Reads extensions set in the cookiecutter.json _extensions key.
3. Attempts to load the extensions. Provides useful error if fails.
"""
context = kwargs.pop('context', {})
default_extensions = ['cookiecutter.extensions.JsonifyExtension', 'cookiecutter.extensions.RandomStringExtension', 'cookiecutter.extensions.SlugifyExtension', 'cookiecutter.extensions.TimeExtension', 'cookiecutter.extensions.UUIDExtension']
> extensions = default_extensions + self._read_extensions(context)
E TypeError: can only concatenate list (not "NoneType") to list
cookiecutter/environment.py:23: TypeError
test_find.py::test_find_template[template with default jinja strings]
test_find.py::test_find_template[template with default jinja strings]
repo_name = 'fake-repo-pre', env = None
error_expectation =
expected = '{{cookiecutter.repo_name}}'
@pytest.mark.parametrize(
"repo_name,context,error_expectation,expected",
[
("fake-repo-pre", {}, does_not_raise(), '{{cookiecutter.repo_name}}'),
(
"fake-repo-pre2",
{
'cookiecutter': {
'_jinja2_env_vars': {
'variable_start_string': '{%{',
'variable_end_string': '}%}',
}
}
},
does_not_raise(),
'{%{cookiecutter.repo_name}%}',
),
(
"fake-repo-pre",
{
'cookiecutter': {
'_jinja2_env_vars': {
'variable_start_string': '{%{',
'variable_end_string': '}%}',
}
}
},
pytest.raises(NonTemplatedInputDirException),
None,
),
("fake-repo-bad", {}, pytest.raises(NonTemplatedInputDirException), None),
],
ids=[
'template with default jinja strings',
'template with custom jinja strings',
'template with custom jinja strings but folder with default jinja strings',
'template missing folder',
],
)
def test_find_template(repo_name, env, error_expectation, expected):
"""Verify correctness of `find.find_template` path detection."""
repo_dir = Path('tests', repo_name)
with error_expectation:
template = find.find_template(repo_dir, env)
test_dir = Path(repo_dir, expected)
> assert template == test_dir
E AssertionError: assert None == PosixPath('tests/fake-repo-pre/{{cookiecutter.repo_name}}')
tests/test_find.py:72: AssertionError
test_find.py::test_find_template[template with custom jinja strings]
test_find.py::test_find_template[template with custom jinja strings]
repo_name = 'fake-repo-pre2', env = None
error_expectation =
expected = '{%{cookiecutter.repo_name}%}'
@pytest.mark.parametrize(
"repo_name,context,error_expectation,expected",
[
("fake-repo-pre", {}, does_not_raise(), '{{cookiecutter.repo_name}}'),
(
"fake-repo-pre2",
{
'cookiecutter': {
'_jinja2_env_vars': {
'variable_start_string': '{%{',
'variable_end_string': '}%}',
}
}
},
does_not_raise(),
'{%{cookiecutter.repo_name}%}',
),
(
"fake-repo-pre",
{
'cookiecutter': {
'_jinja2_env_vars': {
'variable_start_string': '{%{',
'variable_end_string': '}%}',
}
}
},
pytest.raises(NonTemplatedInputDirException),
None,
),
("fake-repo-bad", {}, pytest.raises(NonTemplatedInputDirException), None),
],
ids=[
'template with default jinja strings',
'template with custom jinja strings',
'template with custom jinja strings but folder with default jinja strings',
'template missing folder',
],
)
def test_find_template(repo_name, env, error_expectation, expected):
"""Verify correctness of `find.find_template` path detection."""
repo_dir = Path('tests', repo_name)
with error_expectation:
template = find.find_template(repo_dir, env)
test_dir = Path(repo_dir, expected)
> assert template == test_dir
E AssertionError: assert None == PosixPath('tests/fake-repo-pre2/{%{cookiecutter.repo_name}%}')
tests/test_find.py:72: AssertionError
test_find.py::test_find_template[template with custom jinja strings but folder with default jinja strings]
test_find.py::test_find_template[template with custom jinja strings but folder with default jinja strings]
repo_name = 'fake-repo-pre', env = None
error_expectation = <_pytest.python_api.RaisesContext object at 0x7ffaca434d30>
expected = None
@pytest.mark.parametrize(
"repo_name,context,error_expectation,expected",
[
("fake-repo-pre", {}, does_not_raise(), '{{cookiecutter.repo_name}}'),
(
"fake-repo-pre2",
{
'cookiecutter': {
'_jinja2_env_vars': {
'variable_start_string': '{%{',
'variable_end_string': '}%}',
}
}
},
does_not_raise(),
'{%{cookiecutter.repo_name}%}',
),
(
"fake-repo-pre",
{
'cookiecutter': {
'_jinja2_env_vars': {
'variable_start_string': '{%{',
'variable_end_string': '}%}',
}
}
},
pytest.raises(NonTemplatedInputDirException),
None,
),
("fake-repo-bad", {}, pytest.raises(NonTemplatedInputDirException), None),
],
ids=[
'template with default jinja strings',
'template with custom jinja strings',
'template with custom jinja strings but folder with default jinja strings',
'template missing folder',
],
)
def test_find_template(repo_name, env, error_expectation, expected):
"""Verify correctness of `find.find_template` path detection."""
repo_dir = Path('tests', repo_name)
with error_expectation:
template = find.find_template(repo_dir, env)
> test_dir = Path(repo_dir, expected)
tests/test_find.py:71:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/lib/python3.10/pathlib.py:960: in __new__
self = cls._from_parts(args)
/usr/lib/python3.10/pathlib.py:594: in _from_parts
drv, root, parts = self._parse_args(args)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
cls =
args = (PosixPath('tests/fake-repo-pre'), None)
@classmethod
def _parse_args(cls, args):
# This is useful when you don't want to create an instance, just
# canonicalize some constructor arguments.
parts = []
for a in args:
if isinstance(a, PurePath):
parts += a._parts
else:
> a = os.fspath(a)
E TypeError: expected str, bytes or os.PathLike object, not NoneType
/usr/lib/python3.10/pathlib.py:578: TypeError
test_find.py::test_find_template[template missing folder]
test_find.py::test_find_template[template missing folder]
repo_name = 'fake-repo-bad', env = None
error_expectation = <_pytest.python_api.RaisesContext object at 0x7ffaca434850>
expected = None
@pytest.mark.parametrize(
"repo_name,context,error_expectation,expected",
[
("fake-repo-pre", {}, does_not_raise(), '{{cookiecutter.repo_name}}'),
(
"fake-repo-pre2",
{
'cookiecutter': {
'_jinja2_env_vars': {
'variable_start_string': '{%{',
'variable_end_string': '}%}',
}
}
},
does_not_raise(),
'{%{cookiecutter.repo_name}%}',
),
(
"fake-repo-pre",
{
'cookiecutter': {
'_jinja2_env_vars': {
'variable_start_string': '{%{',
'variable_end_string': '}%}',
}
}
},
pytest.raises(NonTemplatedInputDirException),
None,
),
("fake-repo-bad", {}, pytest.raises(NonTemplatedInputDirException), None),
],
ids=[
'template with default jinja strings',
'template with custom jinja strings',
'template with custom jinja strings but folder with default jinja strings',
'template missing folder',
],
)
def test_find_template(repo_name, env, error_expectation, expected):
"""Verify correctness of `find.find_template` path detection."""
repo_dir = Path('tests', repo_name)
with error_expectation:
template = find.find_template(repo_dir, env)
> test_dir = Path(repo_dir, expected)
tests/test_find.py:71:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/lib/python3.10/pathlib.py:960: in __new__
self = cls._from_parts(args)
/usr/lib/python3.10/pathlib.py:594: in _from_parts
drv, root, parts = self._parse_args(args)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
cls =
args = (PosixPath('tests/fake-repo-bad'), None)
@classmethod
def _parse_args(cls, args):
# This is useful when you don't want to create an instance, just
# canonicalize some constructor arguments.
parts = []
for a in args:
if isinstance(a, PurePath):
parts += a._parts
else:
> a = os.fspath(a)
E TypeError: expected str, bytes or os.PathLike object, not NoneType
/usr/lib/python3.10/pathlib.py:578: TypeError
test_generate_context.py::test_generate_context[input_params0-expected_context0]
test_generate_context.py::test_generate_context[input_params0-expected_context0]
input_params = {'context_file': 'tests/test-generate-context/test.json'}
expected_context = {'test': {'1': 2, 'some_key': 'some_val'}}
@pytest.mark.usefixtures('clean_system')
@pytest.mark.parametrize('input_params, expected_context', context_data())
def test_generate_context(input_params, expected_context):
"""Verify input contexts combinations result in expected content on output."""
> assert generate.generate_context(**input_params) == expected_context
E AssertionError: assert OrderedDict([('1', 2), ('some_key', 'some_val')]) == {'test': {'1': 2, 'some_key': 'some_val'}}
E
E Left contains 2 more items:
E {'1': 2, 'some_key': 'some_val'}
E Right contains 1 more item:
E {'test': {'1': 2, 'some_key': 'some_val'}}
E
E Full diff:
E + OrderedDict({
E - {
E - 'test': {
E - '1': 2,
E ? ----
E + '1': 2,
E - 'some_key': 'some_val',
E ? ----
E + 'some_key': 'some_val',
E + })
E - },
E - }
tests/test_generate_context.py:58: AssertionError
test_generate_context.py::test_generate_context[input_params1-expected_context1]
test_generate_context.py::test_generate_context[input_params1-expected_context1]
input_params = {'context_file': 'tests/test-generate-context/test.json', 'default_context': {'1': 3}}
expected_context = {'test': {'1': 3, 'some_key': 'some_val'}}
@pytest.mark.usefixtures('clean_system')
@pytest.mark.parametrize('input_params, expected_context', context_data())
def test_generate_context(input_params, expected_context):
"""Verify input contexts combinations result in expected content on output."""
> assert generate.generate_context(**input_params) == expected_context
E AssertionError: assert OrderedDict([('1', 3), ('some_key', 'some_val')]) == {'test': {'1': 3, 'some_key': 'some_val'}}
E
E Left contains 2 more items:
E {'1': 3, 'some_key': 'some_val'}
E Right contains 1 more item:
E {'test': {'1': 3, 'some_key': 'some_val'}}
E
E Full diff:
E + OrderedDict({
E - {
E - 'test': {
E - '1': 3,
E ? ----
E + '1': 3,
E - 'some_key': 'some_val',
E ? ----
E + 'some_key': 'some_val',
E + })
E - },
E - }
tests/test_generate_context.py:58: AssertionError
test_generate_context.py::test_generate_context[input_params2-expected_context2]
test_generate_context.py::test_generate_context[input_params2-expected_context2]
input_params = {'context_file': 'tests/test-generate-context/test.json', 'extra_context': {'1': 4}}
expected_context = {'test': {'1': 4, 'some_key': 'some_val'}}
@pytest.mark.usefixtures('clean_system')
@pytest.mark.parametrize('input_params, expected_context', context_data())
def test_generate_context(input_params, expected_context):
"""Verify input contexts combinations result in expected content on output."""
> assert generate.generate_context(**input_params) == expected_context
E AssertionError: assert OrderedDict([('1', 4), ('some_key', 'some_val')]) == {'test': {'1': 4, 'some_key': 'some_val'}}
E
E Left contains 2 more items:
E {'1': 4, 'some_key': 'some_val'}
E Right contains 1 more item:
E {'test': {'1': 4, 'some_key': 'some_val'}}
E
E Full diff:
E + OrderedDict({
E - {
E - 'test': {
E - '1': 4,
E ? ----
E + '1': 4,
E - 'some_key': 'some_val',
E ? ----
E + 'some_key': 'some_val',
E + })
E - },
E - }
tests/test_generate_context.py:58: AssertionError
test_generate_context.py::test_generate_context[input_params3-expected_context3]
test_generate_context.py::test_generate_context[input_params3-expected_context3]
input_params = {'context_file': 'tests/test-generate-context/test.json', 'default_context': {'1': 3}, 'extra_context': {'1': 5}}
expected_context = {'test': {'1': 5, 'some_key': 'some_val'}}
@pytest.mark.usefixtures('clean_system')
@pytest.mark.parametrize('input_params, expected_context', context_data())
def test_generate_context(input_params, expected_context):
"""Verify input contexts combinations result in expected content on output."""
> assert generate.generate_context(**input_params) == expected_context
E AssertionError: assert OrderedDict([('1', 5), ('some_key', 'some_val')]) == {'test': {'1': 5, 'some_key': 'some_val'}}
E
E Left contains 2 more items:
E {'1': 5, 'some_key': 'some_val'}
E Right contains 1 more item:
E {'test': {'1': 5, 'some_key': 'some_val'}}
E
E Full diff:
E + OrderedDict({
E - {
E - 'test': {
E - '1': 5,
E ? ----
E + '1': 5,
E - 'some_key': 'some_val',
E ? ----
E + 'some_key': 'some_val',
E + })
E - },
E - }
tests/test_generate_context.py:58: AssertionError
test_generate_context.py::test_default_context_replacement_in_generate_context
test_generate_context.py::test_default_context_replacement_in_generate_context
def test_default_context_replacement_in_generate_context():
"""Verify default content settings are correctly replaced by template settings.
Make sure that the default for list variables of `orientation` is based on
the user config (`choices_template.json`) and not changed to a single value
from `default_context`.
"""
expected_context = {
'choices_template': OrderedDict(
[
('full_name', 'Raphael Pierzina'),
('github_username', 'hackebrot'),
('project_name', 'Kivy Project'),
('repo_name', '{{cookiecutter.project_name|lower}}'),
('orientation', ['landscape', 'all', 'portrait']),
]
)
}
generated_context = generate.generate_context(
context_file='tests/test-generate-context/choices_template.json',
default_context={
'not_in_template': 'foobar',
'project_name': 'Kivy Project',
'orientation': 'landscape',
},
extra_context={
'also_not_in_template': 'foobar2',
'github_username': 'hackebrot',
},
)
> assert generated_context == expected_context
E AssertionError: assert OrderedDict([('full_name', 'Raphael Pierzina'), ('github_username', 'hackebrot'), ('project_name', 'Kivy Project'), ('repo_name', '{{cookiecutter.project_name|lower}}'), ('orientation', 'landscape'), ('not_in_template', 'foobar'), ('also_not_in_template', 'foobar2')]) == {'choices_template': OrderedDict([('full_name', 'Raphael Pierzina'), ('github_username', 'hackebrot'), ('project_name', 'Kivy Project'), ('repo_name', '{{cookiecutter.project_name|lower}}'), ('orientation', ['landscape', 'all', 'portrait'])])}
E
E Left contains 7 more items:
E {'also_not_in_template': 'foobar2',
E 'full_name': 'Raphael Pierzina',
E 'github_username': 'hackebrot',
E 'not_in_template': 'foobar',
E 'orientation': 'landscape',
E 'project_name': 'Kivy Project',
E 'repo_name': '{{cookiecutter.project_name|lower}}'}
E Right contains 1 more item:
E {'choices_template': OrderedDict([('full_name', 'Raphael Pierzina'),
E ('github_username', 'hackebrot'),
E ('project_name', 'Kivy Project'),
E ('repo_name',
E '{{cookiecutter.project_name|lower}}'),
E ('orientation',
E ['landscape', 'all', 'portrait'])])}
E
E Full diff:
E - {
E - 'choices_template': OrderedDict({
E + OrderedDict({
E + 'also_not_in_template': 'foobar2',
E - 'full_name': 'Raphael Pierzina',
E ? ----
E + 'full_name': 'Raphael Pierzina',
E - 'github_username': 'hackebrot',
E ? ----
E + 'github_username': 'hackebrot',
E + 'not_in_template': 'foobar',
E + 'orientation': 'landscape',
E - 'orientation': [
E - 'landscape',
E - 'all',
E - 'portrait',
E - ],
E - 'project_name': 'Kivy Project',
E ? ----
E + 'project_name': 'Kivy Project',
E - 'repo_name': '{{cookiecutter.project_name|lower}}',
E ? ----
E + 'repo_name': '{{cookiecutter.project_name|lower}}',
E + })
E - }),
E - }
tests/test_generate_context.py:109: AssertionError
test_generate_context.py::test_generate_context_decodes_non_ascii_chars
test_generate_context.py::test_generate_context_decodes_non_ascii_chars
def test_generate_context_decodes_non_ascii_chars():
"""Verify `generate_context` correctly decodes non-ascii chars."""
expected_context = {
'non_ascii': OrderedDict(
[
('full_name', 'éèà'),
]
)
}
generated_context = generate.generate_context(
context_file='tests/test-generate-context/non_ascii.json'
)
> assert generated_context == expected_context
E AssertionError: assert OrderedDict([('full_name', 'éèà')]) == {'non_ascii': OrderedDict([('full_name', 'éèà')])}
E
E Left contains 1 more item:
E {'full_name': 'éèà'}
E Right contains 1 more item:
E {'non_ascii': OrderedDict([('full_name', 'éèà')])}
E
E Full diff:
E + OrderedDict({
E - {
E - 'non_ascii': OrderedDict({
E - 'full_name': 'éèà',
E ? ----
E + 'full_name': 'éèà',
E + })
E - }),
E - }
tests/test_generate_context.py:126: AssertionError
test_generate_context.py::test_apply_overwrites_does_include_unused_variables
test_generate_context.py::test_apply_overwrites_does_include_unused_variables
template_context = OrderedDict([('full_name', 'Raphael Pierzina'), ('github_username', 'hackebrot'), ('project_name', 'Kivy Project'), ('repo_name', '{{cookiecutter.project_name|lower}}'), ('orientation', ['all', 'landscape', 'portrait']), ('deployment_regions', ['eu', 'us', 'ap']), ('deployments', {'preprod': ['eu', 'us', 'ap'], 'prod': ['eu', 'us', 'ap']}), ('not in template', 'foobar')])
def test_apply_overwrites_does_include_unused_variables(template_context):
"""Verify `apply_overwrites_to_context` skips variables that are not in context."""
generate.apply_overwrites_to_context(
context=template_context, overwrite_context={'not in template': 'foobar'}
)
> assert 'not in template' not in template_context
E AssertionError: assert 'not in template' not in OrderedDict([('full_name', 'Raphael Pierzina'), ('github_username', 'hackebrot'), ('project_name', 'Kivy Project'), ('repo_name', '{{cookiecutter.project_name|lower}}'), ('orientation', ['all', 'landscape', 'portrait']), ('deployment_regions', ['eu', 'us', 'ap']), ('deployments', {'preprod': ['eu', 'us', 'ap'], 'prod': ['eu', 'us', 'ap']}), ('not in template', 'foobar')])
tests/test_generate_context.py:157: AssertionError
test_generate_context.py::test_apply_overwrites_does_not_modify_choices_for_invalid_overwrite
test_generate_context.py::test_apply_overwrites_does_not_modify_choices_for_invalid_overwrite
def test_apply_overwrites_does_not_modify_choices_for_invalid_overwrite():
"""Verify variables overwrite for list if variable not in list ignored."""
expected_context = {
'choices_template': OrderedDict(
[
('full_name', 'Raphael Pierzina'),
('github_username', 'hackebrot'),
('project_name', 'Kivy Project'),
('repo_name', '{{cookiecutter.project_name|lower}}'),
('orientation', ['all', 'landscape', 'portrait']),
]
)
}
> with pytest.warns(UserWarning, match="Invalid default received"):
E Failed: DID NOT WARN. No warnings of type (,) were emitted.
E Emitted warnings: [].
tests/test_generate_context.py:183: Failed
test_generate_context.py::test_apply_overwrites_invalid_overwrite
test_generate_context.py::test_apply_overwrites_invalid_overwrite
template_context = OrderedDict([('full_name', 'Raphael Pierzina'), ('github_username', 'hackebrot'), ('project_name', 'Kivy Project'), ('repo_name', '{{cookiecutter.project_name|lower}}'), ('orientation', 'foobar'), ('deployment_regions', ['eu', 'us', 'ap']), ('deployments', {'preprod': ['eu', 'us', 'ap'], 'prod': ['eu', 'us', 'ap']})])
def test_apply_overwrites_invalid_overwrite(template_context):
"""Verify variables overwrite for list if variable not in list not ignored."""
> with pytest.raises(ValueError):
E Failed: DID NOT RAISE
tests/test_generate_context.py:202: Failed
test_generate_context.py::test_apply_overwrites_sets_multichoice_values
test_generate_context.py::test_apply_overwrites_sets_multichoice_values
template_context = OrderedDict([('full_name', 'Raphael Pierzina'), ('github_username', 'hackebrot'), ('project_name', 'Kivy Project'), ('repo_name', '{{cookiecutter.project_name|lower}}'), ('orientation', ['all', 'landscape', 'portrait']), ('deployment_regions', ['eu', 'us', 'ap', 'eu']), ('deployments', {'preprod': ['eu', 'us', 'ap'], 'prod': ['eu', 'us', 'ap']})])
def test_apply_overwrites_sets_multichoice_values(template_context):
"""Verify variable overwrite for list given multiple valid values."""
generate.apply_overwrites_to_context(
context=template_context,
overwrite_context={'deployment_regions': ['eu']},
)
> assert template_context['deployment_regions'] == ['eu']
E AssertionError: assert ['eu', 'us', 'ap', 'eu'] == ['eu']
E
E Left contains 3 more items, first extra item: 'us'
E
E Full diff:
E [
E 'eu',
E + 'us',
E + 'ap',
E + 'eu',
E ]
tests/test_generate_context.py:214: AssertionError
test_generate_context.py::test_apply_overwrites_invalid_multichoice_values
test_generate_context.py::test_apply_overwrites_invalid_multichoice_values
template_context = OrderedDict([('full_name', 'Raphael Pierzina'), ('github_username', 'hackebrot'), ('project_name', 'Kivy Project'), ('repo_name', '{{cookiecutter.project_name|lower}}'), ('orientation', ['all', 'landscape', 'portrait']), ('deployment_regions', ['eu', 'us', 'ap', 'na']), ('deployments', {'preprod': ['eu', 'us', 'ap'], 'prod': ['eu', 'us', 'ap']})])
def test_apply_overwrites_invalid_multichoice_values(template_context):
"""Verify variable overwrite for list given invalid list entries not ignored."""
> with pytest.raises(ValueError):
E Failed: DID NOT RAISE
tests/test_generate_context.py:219: Failed
test_generate_context.py::test_apply_overwrites_error_additional_values
test_generate_context.py::test_apply_overwrites_error_additional_values
template_context = OrderedDict([('full_name', 'Raphael Pierzina'), ('github_username', 'hackebrot'), ('project_name', 'Kivy Project'), ('repo_name', '{{cookiecutter.project_name|lower}}'), ('orientation', ['all', 'landscape', 'portrait']), ('deployment_regions', ['eu', 'us', 'ap', 'eu', 'na']), ('deployments', {'preprod': ['eu', 'us', 'ap'], 'prod': ['eu', 'us', 'ap']})])
def test_apply_overwrites_error_additional_values(template_context):
"""Verify variable overwrite for list given additional entries not ignored."""
> with pytest.raises(ValueError):
E Failed: DID NOT RAISE
tests/test_generate_context.py:228: Failed
test_generate_context.py::test_apply_overwrites_in_dictionaries
test_generate_context.py::test_apply_overwrites_in_dictionaries
template_context = OrderedDict([('full_name', 'Raphael Pierzina'), ('github_username', 'hackebrot'), ('project_name', 'Kivy Project'), ('repo_name', '{{cookiecutter.project_name|lower}}'), ('orientation', ['all', 'landscape', 'portrait']), ('deployment_regions', ['eu', 'us', 'ap']), ('deployments', {'preprod': ['eu', 'us', 'ap', 'eu'], 'prod': ['eu', 'us', 'ap', 'ap']})])
def test_apply_overwrites_in_dictionaries(template_context):
"""Verify variable overwrite for lists nested in dictionary variables."""
generate.apply_overwrites_to_context(
context=template_context,
overwrite_context={'deployments': {'preprod': ['eu'], 'prod': ['ap']}},
)
> assert template_context['deployments']['preprod'] == ['eu']
E AssertionError: assert ['eu', 'us', 'ap', 'eu'] == ['eu']
E
E Left contains 3 more items, first extra item: 'us'
E
E Full diff:
E [
E 'eu',
E + 'us',
E + 'ap',
E + 'eu',
E ]
tests/test_generate_context.py:241: AssertionError
test_generate_context.py::test_apply_overwrites_sets_default_for_choice_variable
test_generate_context.py::test_apply_overwrites_sets_default_for_choice_variable
template_context = OrderedDict([('full_name', 'Raphael Pierzina'), ('github_username', 'hackebrot'), ('project_name', 'Kivy Project'), ('repo_name', '{{cookiecutter.project_name|lower}}'), ('orientation', 'landscape'), ('deployment_regions', ['eu', 'us', 'ap']), ('deployments', {'preprod': ['eu', 'us', 'ap'], 'prod': ['eu', 'us', 'ap']})])
def test_apply_overwrites_sets_default_for_choice_variable(template_context):
"""Verify overwritten list member became a default value."""
generate.apply_overwrites_to_context(
context=template_context, overwrite_context={'orientation': 'landscape'}
)
> assert template_context['orientation'] == ['landscape', 'all', 'portrait']
E AssertionError: assert 'landscape' == ['landscape', 'all', 'portrait']
tests/test_generate_context.py:251: AssertionError
test_generate_context.py::test_apply_overwrites_in_nested_dict
test_generate_context.py::test_apply_overwrites_in_nested_dict
def test_apply_overwrites_in_nested_dict():
"""Verify nested dict in default content settings are correctly replaced."""
expected_context = {
'nested_dict': OrderedDict(
[
('full_name', 'Raphael Pierzina'),
('github_username', 'hackebrot'),
(
'project',
OrderedDict(
[
('name', 'My Kivy Project'),
('description', 'My Kivy Project'),
('repo_name', '{{cookiecutter.project_name|lower}}'),
('orientation', ["all", "landscape", "portrait"]),
]
),
),
]
)
}
generated_context = generate.generate_context(
context_file='tests/test-generate-context/nested_dict.json',
default_context={
'not_in_template': 'foobar',
'project': {
'description': 'My Kivy Project',
},
},
extra_context={
'also_not_in_template': 'foobar2',
'github_username': 'hackebrot',
'project': {
'name': 'My Kivy Project',
},
},
)
> assert generated_context == expected_context
E AssertionError: assert OrderedDict([('full_name', 'Raphael Pierzina'), ('github_username', 'hackebrot'), ('project', OrderedDict([('name', 'Kivy Project'), ('description', 'Kivy Project'), ('repo_name', '{{cookiecutter.project_name|lower}}'), ('orientation', ['all', 'landscape', 'portrait'])])), ('not_in_template', 'foobar'), ('also_not_in_template', 'foobar2')]) == {'nested_dict': OrderedDict([('full_name', 'Raphael Pierzina'), ('github_username', 'hackebrot'), ('project', OrderedDict([('name', 'My Kivy Project'), ('description', 'My Kivy Project'), ('repo_name', '{{cookiecutter.project_name|lower}}'), ('orientation', ['all', 'landscape', 'portrait'])]))])}
E
E Left contains 5 more items:
E {'also_not_in_template': 'foobar2',
E 'full_name': 'Raphael Pierzina',
E 'github_username': 'hackebrot',
E 'not_in_template': 'foobar',
E 'project': OrderedDict([('name', 'Kivy Project'),
E ('description', 'Kivy Project'),
E ('repo_name', '{{cookiecutter.project_name|lower}}'),
E ('orientation', ['all', 'landscape', 'portrait'])])}
E Right contains 1 more item:
E {'nested_dict': OrderedDict([('full_name', 'Raphael Pierzina'),
E ('github_username', 'hackebrot'),
E ('project',
E OrderedDict([('name', 'My Kivy Project'),
E ('description', 'My Kivy Project'),
E ('repo_name',
E '{{cookiecutter.project_name|lower}}'),
E ('orientation',
E ['all',
E 'landscape',
E 'portrait'])]))])}
E
E Full diff:
E - {
E - 'nested_dict': OrderedDict({
E + OrderedDict({
E + 'also_not_in_template': 'foobar2',
E - 'full_name': 'Raphael Pierzina',
E ? ----
E + 'full_name': 'Raphael Pierzina',
E - 'github_username': 'hackebrot',
E ? ----
E + 'github_username': 'hackebrot',
E + 'not_in_template': 'foobar',
E - 'project': OrderedDict({
E ? ----
E + 'project': OrderedDict({
E - 'description': 'My Kivy Project',
E ? ---- ---
E + 'description': 'Kivy Project',
E - 'name': 'My Kivy Project',
E ? ---- ---
E + 'name': 'Kivy Project',
E - 'orientation': [
E ? ----
E + 'orientation': [
E - 'all',
E ? ----
E + 'all',
E - 'landscape',
E ? ----
E + 'landscape',
E - 'portrait',
E ? ----
E + 'portrait',
E - ],
E ? ----
E + ],
E - 'repo_name': '{{cookiecutter.project_name|lower}}',
E ? ----
E + 'repo_name': '{{cookiecutter.project_name|lower}}',
E - }),
E }),
E - }
E + })
tests/test_generate_context.py:293: AssertionError
test_generate_context.py::test_apply_overwrites_in_nested_dict_additional_values
test_generate_context.py::test_apply_overwrites_in_nested_dict_additional_values
def test_apply_overwrites_in_nested_dict_additional_values():
"""Verify nested dict in default content settings are correctly added."""
expected_context = {
'nested_dict_additional': OrderedDict(
[
('mainkey1', 'mainvalue1'),
(
'mainkey2',
OrderedDict(
[
('subkey1', 'subvalue1'),
(
'subkey2',
OrderedDict(
[
('subsubkey1', 'subsubvalue1'),
('subsubkey2', 'subsubvalue2_default'),
('subsubkey3', 'subsubvalue3_extra'),
]
),
),
('subkey4', 'subvalue4_default'),
('subkey5', 'subvalue5_extra'),
]
),
),
]
)
}
generated_context = generate.generate_context(
context_file='tests/test-generate-context/nested_dict_additional.json',
default_context={
'not_in_template': 'foobar',
'mainkey2': {
'subkey2': {
'subsubkey2': 'subsubvalue2_default',
},
'subkey4': 'subvalue4_default',
},
},
extra_context={
'also_not_in_template': 'foobar2',
'mainkey2': {
'subkey2': {
'subsubkey3': 'subsubvalue3_extra',
},
'subkey5': 'subvalue5_extra',
},
},
)
> assert generated_context == expected_context
E AssertionError: assert OrderedDict([('mainkey1', 'mainvalue1'), ('mainkey2', OrderedDict([('subkey1', 'subvalue1'), ('subkey2', OrderedDict([('subsubkey1', 'subsubvalue1'), ('subsubkey2', 'subsubvalue2_default'), ('subsubkey3', 'subsubvalue3_extra')])), ('subkey4', 'subvalue4_default'), ('subkey5', 'subvalue5_extra')])), ('not_in_template', 'foobar'), ('also_not_in_template', 'foobar2')]) == {'nested_dict_additional': OrderedDict([('mainkey1', 'mainvalue1'), ('mainkey2', OrderedDict([('subkey1', 'subvalue1'), ('subkey2', OrderedDict([('subsubkey1', 'subsubvalue1'), ('subsubkey2', 'subsubvalue2_default'), ('subsubkey3', 'subsubvalue3_extra')])), ('subkey4', 'subvalue4_default'), ('subkey5', 'subvalue5_extra')]))])}
E
E Left contains 4 more items:
E {'also_not_in_template': 'foobar2',
E 'mainkey1': 'mainvalue1',
E 'mainkey2': OrderedDict([('subkey1', 'subvalue1'),
E ('subkey2',
E OrderedDict([('subsubkey1', 'subsubvalue1'),
E ('subsubkey2', 'subsubvalue2_default'),
E ('subsubkey3', 'subsubvalue3_extra')])),
E ('subkey4', 'subvalue4_default'),
E ('subkey5', 'subvalue5_extra')]),
E 'not_in_template': 'foobar'}
E Right contains 1 more item:
E {'nested_dict_additional': OrderedDict([('mainkey1', 'mainvalue1'),
E ('mainkey2',
E OrderedDict([('subkey1', 'subvalue1'),
E ('subkey2',
E OrderedDict([('subsubkey1',
E 'subsubvalue1'),
E ('subsubkey2',
E 'subsubvalue2_default'),
E ('subsubkey3',
E 'subsubvalue3_extra')])),
E ('subkey4',
E 'subvalue4_default'),
E ('subkey5',
E 'subvalue5_extra')]))])}
E
E Full diff:
E - {
E - 'nested_dict_additional': OrderedDict({
E + OrderedDict({
E + 'also_not_in_template': 'foobar2',
E - 'mainkey1': 'mainvalue1',
E ? ----
E + 'mainkey1': 'mainvalue1',
E - 'mainkey2': OrderedDict({
E ? ----
E + 'mainkey2': OrderedDict({
E - 'subkey1': 'subvalue1',
E ? ----
E + 'subkey1': 'subvalue1',
E - 'subkey2': OrderedDict({
E ? ----
E + 'subkey2': OrderedDict({
E - 'subsubkey1': 'subsubvalue1',
E ? ----
E + 'subsubkey1': 'subsubvalue1',
E - 'subsubkey2': 'subsubvalue2_default',
E ? ----
E + 'subsubkey2': 'subsubvalue2_default',
E - 'subsubkey3': 'subsubvalue3_extra',
E ? ----
E + 'subsubkey3': 'subsubvalue3_extra',
E - }),
E - 'subkey4': 'subvalue4_default',
E - 'subkey5': 'subvalue5_extra',
E }),
E + 'subkey4': 'subvalue4_default',
E + 'subkey5': 'subvalue5_extra',
E }),
E - }
E + 'not_in_template': 'foobar',
E + })
tests/test_generate_context.py:364: AssertionError
test_generate_copy_without_render.py::test_generate_copy_without_render_extensions
test_generate_copy_without_render.py::test_generate_copy_without_render_extensions
@pytest.mark.usefixtures('clean_system', 'remove_test_dir')
def test_generate_copy_without_render_extensions():
"""Verify correct work of `_copy_without_render` context option.
Some files/directories should be rendered during invocation,
some just copied, without any modification.
"""
> generate.generate_files(
context={
'cookiecutter': {
'repo_name': 'test_copy_without_render',
'render_test': 'I have been rendered!',
'_copy_without_render': [
'*not-rendered',
'rendered/not_rendered.yml',
'*.txt',
'{{cookiecutter.repo_name}}-rendered/README.md',
],
}
},
repo_dir='tests/test-generate-copy-without-render',
)
tests/test_generate_copy_without_render.py:26:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
repo_dir = 'tests/test-generate-copy-without-render'
context = {'cookiecutter': {'_copy_without_render': ['*not-rendered', 'rendered/not_rendered.yml', '*.txt', '{{cookiecutter.repo_name}}-rendered/README.md'], 'render_test': 'I have been rendered!', 'repo_name': 'test_copy_without_render'}}
output_dir = '.', overwrite_if_exists = False, skip_if_file_exists = False
accept_hooks = True, keep_project_on_failure = False
def generate_files(repo_dir, context=None, output_dir='.', overwrite_if_exists=False, skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False):
"""Render the templates and saves them to files.
:param repo_dir: Project template input directory.
:param context: Dict for populating the template's variables.
:param output_dir: Where to output the generated project dir into.
:param overwrite_if_exists: Overwrite the contents of the output directory
if it exists.
:param skip_if_file_exists: Skip the files in the corresponding directories
if they already exist
:param accept_hooks: Accept pre and post hooks if set to `True`.
:param keep_project_on_failure: If `True` keep generated project directory even when
generation fails
"""
> template_dir = find_template(repo_dir)
E TypeError: find_template() missing 1 required positional argument: 'env'
cookiecutter/generate.py:170: TypeError
test_generate_copy_without_render_override.py::test_generate_copy_without_render_extensions
test_generate_copy_without_render_override.py::test_generate_copy_without_render_extensions
@pytest.mark.usefixtures('clean_system', 'remove_test_dir')
def test_generate_copy_without_render_extensions():
"""Verify correct work of `_copy_without_render` context option.
Some files/directories should be rendered during invocation,
some just copied, without any modification.
"""
# first run
> generate.generate_files(
context={
'cookiecutter': {
'repo_name': 'test_copy_without_render',
'render_test': 'I have been rendered!',
'_copy_without_render': [
'*not-rendered',
'rendered/not_rendered.yml',
'*.txt',
'{{cookiecutter.repo_name}}-rendered/README.md',
],
}
},
repo_dir='tests/test-generate-copy-without-render-override',
)
tests/test_generate_copy_without_render_override.py:27:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
repo_dir = 'tests/test-generate-copy-without-render-override'
context = {'cookiecutter': {'_copy_without_render': ['*not-rendered', 'rendered/not_rendered.yml', '*.txt', '{{cookiecutter.repo_name}}-rendered/README.md'], 'render_test': 'I have been rendered!', 'repo_name': 'test_copy_without_render'}}
output_dir = '.', overwrite_if_exists = False, skip_if_file_exists = False
accept_hooks = True, keep_project_on_failure = False
def generate_files(repo_dir, context=None, output_dir='.', overwrite_if_exists=False, skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False):
"""Render the templates and saves them to files.
:param repo_dir: Project template input directory.
:param context: Dict for populating the template's variables.
:param output_dir: Where to output the generated project dir into.
:param overwrite_if_exists: Overwrite the contents of the output directory
if it exists.
:param skip_if_file_exists: Skip the files in the corresponding directories
if they already exist
:param accept_hooks: Accept pre and post hooks if set to `True`.
:param keep_project_on_failure: If `True` keep generated project directory even when
generation fails
"""
> template_dir = find_template(repo_dir)
E TypeError: find_template() missing 1 required positional argument: 'env'
cookiecutter/generate.py:170: TypeError
test_generate_file.py::test_generate_file
test_generate_file.py::test_generate_file
@pytest.fixture
def env():
"""Fixture. Set Jinja2 environment settings for other tests."""
> environment = StrictEnvironment()
tests/test_generate_file.py:39:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
cookiecutter/environment.py:49: in __init__
super().__init__(undefined=StrictUndefined, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self =
kwargs = {'undefined': }, context = {}
default_extensions = ['cookiecutter.extensions.JsonifyExtension', 'cookiecutter.extensions.RandomStringExtension', 'cookiecutter.extensions.SlugifyExtension', 'cookiecutter.extensions.TimeExtension', 'cookiecutter.extensions.UUIDExtension']
def __init__(self, **kwargs):
"""Initialize the Jinja2 Environment object while loading extensions.
Does the following:
1. Establishes default_extensions (currently just a Time feature)
2. Reads extensions set in the cookiecutter.json _extensions key.
3. Attempts to load the extensions. Provides useful error if fails.
"""
context = kwargs.pop('context', {})
default_extensions = ['cookiecutter.extensions.JsonifyExtension', 'cookiecutter.extensions.RandomStringExtension', 'cookiecutter.extensions.SlugifyExtension', 'cookiecutter.extensions.TimeExtension', 'cookiecutter.extensions.UUIDExtension']
> extensions = default_extensions + self._read_extensions(context)
E TypeError: can only concatenate list (not "NoneType") to list
cookiecutter/environment.py:23: TypeError
test_generate_file.py::test_generate_file_jsonify_filter
test_generate_file.py::test_generate_file_jsonify_filter
@pytest.fixture
def env():
"""Fixture. Set Jinja2 environment settings for other tests."""
> environment = StrictEnvironment()
tests/test_generate_file.py:39:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
cookiecutter/environment.py:49: in __init__
super().__init__(undefined=StrictUndefined, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self =
kwargs = {'undefined': }, context = {}
default_extensions = ['cookiecutter.extensions.JsonifyExtension', 'cookiecutter.extensions.RandomStringExtension', 'cookiecutter.extensions.SlugifyExtension', 'cookiecutter.extensions.TimeExtension', 'cookiecutter.extensions.UUIDExtension']
def __init__(self, **kwargs):
"""Initialize the Jinja2 Environment object while loading extensions.
Does the following:
1. Establishes default_extensions (currently just a Time feature)
2. Reads extensions set in the cookiecutter.json _extensions key.
3. Attempts to load the extensions. Provides useful error if fails.
"""
context = kwargs.pop('context', {})
default_extensions = ['cookiecutter.extensions.JsonifyExtension', 'cookiecutter.extensions.RandomStringExtension', 'cookiecutter.extensions.SlugifyExtension', 'cookiecutter.extensions.TimeExtension', 'cookiecutter.extensions.UUIDExtension']
> extensions = default_extensions + self._read_extensions(context)
E TypeError: can only concatenate list (not "NoneType") to list
cookiecutter/environment.py:23: TypeError
test_generate_file.py::test_generate_file_random_ascii_string[True-10]
test_generate_file.py::test_generate_file_random_ascii_string[True-10]
@pytest.fixture
def env():
"""Fixture. Set Jinja2 environment settings for other tests."""
> environment = StrictEnvironment()
tests/test_generate_file.py:39:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
cookiecutter/environment.py:49: in __init__
super().__init__(undefined=StrictUndefined, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self =
kwargs = {'undefined': }, context = {}
default_extensions = ['cookiecutter.extensions.JsonifyExtension', 'cookiecutter.extensions.RandomStringExtension', 'cookiecutter.extensions.SlugifyExtension', 'cookiecutter.extensions.TimeExtension', 'cookiecutter.extensions.UUIDExtension']
def __init__(self, **kwargs):
"""Initialize the Jinja2 Environment object while loading extensions.
Does the following:
1. Establishes default_extensions (currently just a Time feature)
2. Reads extensions set in the cookiecutter.json _extensions key.
3. Attempts to load the extensions. Provides useful error if fails.
"""
context = kwargs.pop('context', {})
default_extensions = ['cookiecutter.extensions.JsonifyExtension', 'cookiecutter.extensions.RandomStringExtension', 'cookiecutter.extensions.SlugifyExtension', 'cookiecutter.extensions.TimeExtension', 'cookiecutter.extensions.UUIDExtension']
> extensions = default_extensions + self._read_extensions(context)
E TypeError: can only concatenate list (not "NoneType") to list
cookiecutter/environment.py:23: TypeError
test_generate_file.py::test_generate_file_random_ascii_string[True-40]
test_generate_file.py::test_generate_file_random_ascii_string[True-40]
@pytest.fixture
def env():
"""Fixture. Set Jinja2 environment settings for other tests."""
> environment = StrictEnvironment()
tests/test_generate_file.py:39:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
cookiecutter/environment.py:49: in __init__
super().__init__(undefined=StrictUndefined, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self =
kwargs = {'undefined': }, context = {}
default_extensions = ['cookiecutter.extensions.JsonifyExtension', 'cookiecutter.extensions.RandomStringExtension', 'cookiecutter.extensions.SlugifyExtension', 'cookiecutter.extensions.TimeExtension', 'cookiecutter.extensions.UUIDExtension']
def __init__(self, **kwargs):
"""Initialize the Jinja2 Environment object while loading extensions.
Does the following:
1. Establishes default_extensions (currently just a Time feature)
2. Reads extensions set in the cookiecutter.json _extensions key.
3. Attempts to load the extensions. Provides useful error if fails.
"""
context = kwargs.pop('context', {})
default_extensions = ['cookiecutter.extensions.JsonifyExtension', 'cookiecutter.extensions.RandomStringExtension', 'cookiecutter.extensions.SlugifyExtension', 'cookiecutter.extensions.TimeExtension', 'cookiecutter.extensions.UUIDExtension']
> extensions = default_extensions + self._read_extensions(context)
E TypeError: can only concatenate list (not "NoneType") to list
cookiecutter/environment.py:23: TypeError
test_generate_file.py::test_generate_file_random_ascii_string[False-10]
test_generate_file.py::test_generate_file_random_ascii_string[False-10]
@pytest.fixture
def env():
"""Fixture. Set Jinja2 environment settings for other tests."""
> environment = StrictEnvironment()
tests/test_generate_file.py:39:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
cookiecutter/environment.py:49: in __init__
super().__init__(undefined=StrictUndefined, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self =
kwargs = {'undefined': }, context = {}
default_extensions = ['cookiecutter.extensions.JsonifyExtension', 'cookiecutter.extensions.RandomStringExtension', 'cookiecutter.extensions.SlugifyExtension', 'cookiecutter.extensions.TimeExtension', 'cookiecutter.extensions.UUIDExtension']
def __init__(self, **kwargs):
"""Initialize the Jinja2 Environment object while loading extensions.
Does the following:
1. Establishes default_extensions (currently just a Time feature)
2. Reads extensions set in the cookiecutter.json _extensions key.
3. Attempts to load the extensions. Provides useful error if fails.
"""
context = kwargs.pop('context', {})
default_extensions = ['cookiecutter.extensions.JsonifyExtension', 'cookiecutter.extensions.RandomStringExtension', 'cookiecutter.extensions.SlugifyExtension', 'cookiecutter.extensions.TimeExtension', 'cookiecutter.extensions.UUIDExtension']
> extensions = default_extensions + self._read_extensions(context)
E TypeError: can only concatenate list (not "NoneType") to list
cookiecutter/environment.py:23: TypeError
test_generate_file.py::test_generate_file_random_ascii_string[False-40]
test_generate_file.py::test_generate_file_random_ascii_string[False-40]
@pytest.fixture
def env():
"""Fixture. Set Jinja2 environment settings for other tests."""
> environment = StrictEnvironment()
tests/test_generate_file.py:39:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
cookiecutter/environment.py:49: in __init__
super().__init__(undefined=StrictUndefined, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self =
kwargs = {'undefined': }, context = {}
default_extensions = ['cookiecutter.extensions.JsonifyExtension', 'cookiecutter.extensions.RandomStringExtension', 'cookiecutter.extensions.SlugifyExtension', 'cookiecutter.extensions.TimeExtension', 'cookiecutter.extensions.UUIDExtension']
def __init__(self, **kwargs):
"""Initialize the Jinja2 Environment object while loading extensions.
Does the following:
1. Establishes default_extensions (currently just a Time feature)
2. Reads extensions set in the cookiecutter.json _extensions key.
3. Attempts to load the extensions. Provides useful error if fails.
"""
context = kwargs.pop('context', {})
default_extensions = ['cookiecutter.extensions.JsonifyExtension', 'cookiecutter.extensions.RandomStringExtension', 'cookiecutter.extensions.SlugifyExtension', 'cookiecutter.extensions.TimeExtension', 'cookiecutter.extensions.UUIDExtension']
> extensions = default_extensions + self._read_extensions(context)
E TypeError: can only concatenate list (not "NoneType") to list
cookiecutter/environment.py:23: TypeError
test_generate_file.py::test_generate_file_with_true_condition
test_generate_file.py::test_generate_file_with_true_condition
@pytest.fixture
def env():
"""Fixture. Set Jinja2 environment settings for other tests."""
> environment = StrictEnvironment()
tests/test_generate_file.py:39:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
cookiecutter/environment.py:49: in __init__
super().__init__(undefined=StrictUndefined, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self =
kwargs = {'undefined': }, context = {}
default_extensions = ['cookiecutter.extensions.JsonifyExtension', 'cookiecutter.extensions.RandomStringExtension', 'cookiecutter.extensions.SlugifyExtension', 'cookiecutter.extensions.TimeExtension', 'cookiecutter.extensions.UUIDExtension']
def __init__(self, **kwargs):
"""Initialize the Jinja2 Environment object while loading extensions.
Does the following:
1. Establishes default_extensions (currently just a Time feature)
2. Reads extensions set in the cookiecutter.json _extensions key.
3. Attempts to load the extensions. Provides useful error if fails.
"""
context = kwargs.pop('context', {})
default_extensions = ['cookiecutter.extensions.JsonifyExtension', 'cookiecutter.extensions.RandomStringExtension', 'cookiecutter.extensions.SlugifyExtension', 'cookiecutter.extensions.TimeExtension', 'cookiecutter.extensions.UUIDExtension']
> extensions = default_extensions + self._read_extensions(context)
E TypeError: can only concatenate list (not "NoneType") to list
cookiecutter/environment.py:23: TypeError
test_generate_file.py::test_generate_file_with_false_condition
test_generate_file.py::test_generate_file_with_false_condition
@pytest.fixture
def env():
"""Fixture. Set Jinja2 environment settings for other tests."""
> environment = StrictEnvironment()
tests/test_generate_file.py:39:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
cookiecutter/environment.py:49: in __init__
super().__init__(undefined=StrictUndefined, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self =
kwargs = {'undefined': }, context = {}
default_extensions = ['cookiecutter.extensions.JsonifyExtension', 'cookiecutter.extensions.RandomStringExtension', 'cookiecutter.extensions.SlugifyExtension', 'cookiecutter.extensions.TimeExtension', 'cookiecutter.extensions.UUIDExtension']
def __init__(self, **kwargs):
"""Initialize the Jinja2 Environment object while loading extensions.
Does the following:
1. Establishes default_extensions (currently just a Time feature)
2. Reads extensions set in the cookiecutter.json _extensions key.
3. Attempts to load the extensions. Provides useful error if fails.
"""
context = kwargs.pop('context', {})
default_extensions = ['cookiecutter.extensions.JsonifyExtension', 'cookiecutter.extensions.RandomStringExtension', 'cookiecutter.extensions.SlugifyExtension', 'cookiecutter.extensions.TimeExtension', 'cookiecutter.extensions.UUIDExtension']
> extensions = default_extensions + self._read_extensions(context)
E TypeError: can only concatenate list (not "NoneType") to list
cookiecutter/environment.py:23: TypeError
test_generate_file.py::test_generate_file_verbose_template_syntax_error
test_generate_file.py::test_generate_file_verbose_template_syntax_error
@pytest.fixture
def env():
"""Fixture. Set Jinja2 environment settings for other tests."""
> environment = StrictEnvironment()
tests/test_generate_file.py:39:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
cookiecutter/environment.py:49: in __init__
super().__init__(undefined=StrictUndefined, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self =
kwargs = {'undefined': }, context = {}
default_extensions = ['cookiecutter.extensions.JsonifyExtension', 'cookiecutter.extensions.RandomStringExtension', 'cookiecutter.extensions.SlugifyExtension', 'cookiecutter.extensions.TimeExtension', 'cookiecutter.extensions.UUIDExtension']
def __init__(self, **kwargs):
"""Initialize the Jinja2 Environment object while loading extensions.
Does the following:
1. Establishes default_extensions (currently just a Time feature)
2. Reads extensions set in the cookiecutter.json _extensions key.
3. Attempts to load the extensions. Provides useful error if fails.
"""
context = kwargs.pop('context', {})
default_extensions = ['cookiecutter.extensions.JsonifyExtension', 'cookiecutter.extensions.RandomStringExtension', 'cookiecutter.extensions.SlugifyExtension', 'cookiecutter.extensions.TimeExtension', 'cookiecutter.extensions.UUIDExtension']
> extensions = default_extensions + self._read_extensions(context)
E TypeError: can only concatenate list (not "NoneType") to list
cookiecutter/environment.py:23: TypeError
test_generate_file.py::test_generate_file_does_not_translate_lf_newlines_to_crlf
test_generate_file.py::test_generate_file_does_not_translate_lf_newlines_to_crlf
@pytest.fixture
def env():
"""Fixture. Set Jinja2 environment settings for other tests."""
> environment = StrictEnvironment()
tests/test_generate_file.py:39:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
cookiecutter/environment.py:49: in __init__
super().__init__(undefined=StrictUndefined, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self =
kwargs = {'undefined': }, context = {}
default_extensions = ['cookiecutter.extensions.JsonifyExtension', 'cookiecutter.extensions.RandomStringExtension', 'cookiecutter.extensions.SlugifyExtension', 'cookiecutter.extensions.TimeExtension', 'cookiecutter.extensions.UUIDExtension']
def __init__(self, **kwargs):
"""Initialize the Jinja2 Environment object while loading extensions.
Does the following:
1. Establishes default_extensions (currently just a Time feature)
2. Reads extensions set in the cookiecutter.json _extensions key.
3. Attempts to load the extensions. Provides useful error if fails.
"""
context = kwargs.pop('context', {})
default_extensions = ['cookiecutter.extensions.JsonifyExtension', 'cookiecutter.extensions.RandomStringExtension', 'cookiecutter.extensions.SlugifyExtension', 'cookiecutter.extensions.TimeExtension', 'cookiecutter.extensions.UUIDExtension']
> extensions = default_extensions + self._read_extensions(context)
E TypeError: can only concatenate list (not "NoneType") to list
cookiecutter/environment.py:23: TypeError
test_generate_file.py::test_generate_file_does_not_translate_crlf_newlines_to_lf
test_generate_file.py::test_generate_file_does_not_translate_crlf_newlines_to_lf
@pytest.fixture
def env():
"""Fixture. Set Jinja2 environment settings for other tests."""
> environment = StrictEnvironment()
tests/test_generate_file.py:39:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
cookiecutter/environment.py:49: in __init__
super().__init__(undefined=StrictUndefined, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self =
kwargs = {'undefined': }, context = {}
default_extensions = ['cookiecutter.extensions.JsonifyExtension', 'cookiecutter.extensions.RandomStringExtension', 'cookiecutter.extensions.SlugifyExtension', 'cookiecutter.extensions.TimeExtension', 'cookiecutter.extensions.UUIDExtension']
def __init__(self, **kwargs):
"""Initialize the Jinja2 Environment object while loading extensions.
Does the following:
1. Establishes default_extensions (currently just a Time feature)
2. Reads extensions set in the cookiecutter.json _extensions key.
3. Attempts to load the extensions. Provides useful error if fails.
"""
context = kwargs.pop('context', {})
default_extensions = ['cookiecutter.extensions.JsonifyExtension', 'cookiecutter.extensions.RandomStringExtension', 'cookiecutter.extensions.SlugifyExtension', 'cookiecutter.extensions.TimeExtension', 'cookiecutter.extensions.UUIDExtension']
> extensions = default_extensions + self._read_extensions(context)
E TypeError: can only concatenate list (not "NoneType") to list
cookiecutter/environment.py:23: TypeError
test_generate_file.py::test_generate_file_handles_mixed_line_endings
test_generate_file.py::test_generate_file_handles_mixed_line_endings
@pytest.fixture
def env():
"""Fixture. Set Jinja2 environment settings for other tests."""
> environment = StrictEnvironment()
tests/test_generate_file.py:39:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
cookiecutter/environment.py:49: in __init__
super().__init__(undefined=StrictUndefined, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self =
kwargs = {'undefined': }, context = {}
default_extensions = ['cookiecutter.extensions.JsonifyExtension', 'cookiecutter.extensions.RandomStringExtension', 'cookiecutter.extensions.SlugifyExtension', 'cookiecutter.extensions.TimeExtension', 'cookiecutter.extensions.UUIDExtension']
def __init__(self, **kwargs):
"""Initialize the Jinja2 Environment object while loading extensions.
Does the following:
1. Establishes default_extensions (currently just a Time feature)
2. Reads extensions set in the cookiecutter.json _extensions key.
3. Attempts to load the extensions. Provides useful error if fails.
"""
context = kwargs.pop('context', {})
default_extensions = ['cookiecutter.extensions.JsonifyExtension', 'cookiecutter.extensions.RandomStringExtension', 'cookiecutter.extensions.SlugifyExtension', 'cookiecutter.extensions.TimeExtension', 'cookiecutter.extensions.UUIDExtension']
> extensions = default_extensions + self._read_extensions(context)
E TypeError: can only concatenate list (not "NoneType") to list
cookiecutter/environment.py:23: TypeError
test_generate_files.py::test_generate_files_nontemplated_exception
test_generate_files.py::test_generate_files_nontemplated_exception
tmp_path = PosixPath('/tmp/pytest-of-root/pytest-0/test_generate_files_nontemplat0')
def test_generate_files_nontemplated_exception(tmp_path):
"""
Verify `generate_files` raises when no directories to render exist.
Note: Check `tests/test-generate-files-nontemplated` location to understand.
"""
with pytest.raises(exceptions.NonTemplatedInputDirException):
> generate.generate_files(
context={'cookiecutter': {'food': 'pizza'}},
repo_dir='tests/test-generate-files-nontemplated',
output_dir=tmp_path,
)
tests/test_generate_files.py:22:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
repo_dir = 'tests/test-generate-files-nontemplated'
context = {'cookiecutter': {'food': 'pizza'}}
output_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_generate_files_nontemplat0')
overwrite_if_exists = False, skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False
def generate_files(repo_dir, context=None, output_dir='.', overwrite_if_exists=False, skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False):
"""Render the templates and saves them to files.
:param repo_dir: Project template input directory.
:param context: Dict for populating the template's variables.
:param output_dir: Where to output the generated project dir into.
:param overwrite_if_exists: Overwrite the contents of the output directory
if it exists.
:param skip_if_file_exists: Skip the files in the corresponding directories
if they already exist
:param accept_hooks: Accept pre and post hooks if set to `True`.
:param keep_project_on_failure: If `True` keep generated project directory even when
generation fails
"""
> template_dir = find_template(repo_dir)
E TypeError: find_template() missing 1 required positional argument: 'env'
cookiecutter/generate.py:170: TypeError
test_generate_files.py::test_generate_files
test_generate_files.py::test_generate_files
tmp_path = PosixPath('/tmp/pytest-of-root/pytest-0/test_generate_files0')
def test_generate_files(tmp_path):
"""Verify directory name correctly rendered with unicode containing context."""
> generate.generate_files(
context={'cookiecutter': {'food': 'pizzä'}},
repo_dir='tests/test-generate-files',
output_dir=tmp_path,
)
tests/test_generate_files.py:31:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
repo_dir = 'tests/test-generate-files'
context = {'cookiecutter': {'food': 'pizzä'}}
output_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_generate_files0')
overwrite_if_exists = False, skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False
def generate_files(repo_dir, context=None, output_dir='.', overwrite_if_exists=False, skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False):
"""Render the templates and saves them to files.
:param repo_dir: Project template input directory.
:param context: Dict for populating the template's variables.
:param output_dir: Where to output the generated project dir into.
:param overwrite_if_exists: Overwrite the contents of the output directory
if it exists.
:param skip_if_file_exists: Skip the files in the corresponding directories
if they already exist
:param accept_hooks: Accept pre and post hooks if set to `True`.
:param keep_project_on_failure: If `True` keep generated project directory even when
generation fails
"""
> template_dir = find_template(repo_dir)
E TypeError: find_template() missing 1 required positional argument: 'env'
cookiecutter/generate.py:170: TypeError
test_generate_files.py::test_generate_files_with_linux_newline
test_generate_files.py::test_generate_files_with_linux_newline
tmp_path = PosixPath('/tmp/pytest-of-root/pytest-0/test_generate_files_with_linux0')
def test_generate_files_with_linux_newline(tmp_path):
"""Verify new line not removed by templating engine after folder generation."""
> generate.generate_files(
context={'cookiecutter': {'food': 'pizzä'}},
repo_dir='tests/test-generate-files',
output_dir=tmp_path,
)
tests/test_generate_files.py:47:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
repo_dir = 'tests/test-generate-files'
context = {'cookiecutter': {'food': 'pizzä'}}
output_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_generate_files_with_linux0')
overwrite_if_exists = False, skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False
def generate_files(repo_dir, context=None, output_dir='.', overwrite_if_exists=False, skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False):
"""Render the templates and saves them to files.
:param repo_dir: Project template input directory.
:param context: Dict for populating the template's variables.
:param output_dir: Where to output the generated project dir into.
:param overwrite_if_exists: Overwrite the contents of the output directory
if it exists.
:param skip_if_file_exists: Skip the files in the corresponding directories
if they already exist
:param accept_hooks: Accept pre and post hooks if set to `True`.
:param keep_project_on_failure: If `True` keep generated project directory even when
generation fails
"""
> template_dir = find_template(repo_dir)
E TypeError: find_template() missing 1 required positional argument: 'env'
cookiecutter/generate.py:170: TypeError
test_generate_files.py::test_generate_files_with_jinja2_environment
test_generate_files.py::test_generate_files_with_jinja2_environment
tmp_path = PosixPath('/tmp/pytest-of-root/pytest-0/test_generate_files_with_jinja0')
def test_generate_files_with_jinja2_environment(tmp_path):
"""Extend StrictEnvironment with _jinja2_env_vars cookiecutter template option."""
> generate.generate_files(
context={
'cookiecutter': {
'food': 'pizzä',
'_jinja2_env_vars': {'lstrip_blocks': True, 'trim_blocks': True},
}
},
repo_dir='tests/test-generate-files',
output_dir=tmp_path,
)
tests/test_generate_files.py:65:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
repo_dir = 'tests/test-generate-files'
context = {'cookiecutter': {'_jinja2_env_vars': {'lstrip_blocks': True, 'trim_blocks': True}, 'food': 'pizzä'}}
output_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_generate_files_with_jinja0')
overwrite_if_exists = False, skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False
def generate_files(repo_dir, context=None, output_dir='.', overwrite_if_exists=False, skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False):
"""Render the templates and saves them to files.
:param repo_dir: Project template input directory.
:param context: Dict for populating the template's variables.
:param output_dir: Where to output the generated project dir into.
:param overwrite_if_exists: Overwrite the contents of the output directory
if it exists.
:param skip_if_file_exists: Skip the files in the corresponding directories
if they already exist
:param accept_hooks: Accept pre and post hooks if set to `True`.
:param keep_project_on_failure: If `True` keep generated project directory even when
generation fails
"""
> template_dir = find_template(repo_dir)
E TypeError: find_template() missing 1 required positional argument: 'env'
cookiecutter/generate.py:170: TypeError
test_generate_files.py::test_generate_files_with_trailing_newline_forced_to_linux_by_context
test_generate_files.py::test_generate_files_with_trailing_newline_forced_to_linux_by_context
tmp_path = PosixPath('/tmp/pytest-of-root/pytest-0/test_generate_files_with_trail0')
def test_generate_files_with_trailing_newline_forced_to_linux_by_context(tmp_path):
"""Verify new line not removed by templating engine after folder generation."""
> generate.generate_files(
context={'cookiecutter': {'food': 'pizzä', '_new_lines': '\r\n'}},
repo_dir='tests/test-generate-files',
output_dir=tmp_path,
)
tests/test_generate_files.py:86:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
repo_dir = 'tests/test-generate-files'
context = {'cookiecutter': {'_new_lines': '\r\n', 'food': 'pizzä'}}
output_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_generate_files_with_trail0')
overwrite_if_exists = False, skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False
def generate_files(repo_dir, context=None, output_dir='.', overwrite_if_exists=False, skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False):
"""Render the templates and saves them to files.
:param repo_dir: Project template input directory.
:param context: Dict for populating the template's variables.
:param output_dir: Where to output the generated project dir into.
:param overwrite_if_exists: Overwrite the contents of the output directory
if it exists.
:param skip_if_file_exists: Skip the files in the corresponding directories
if they already exist
:param accept_hooks: Accept pre and post hooks if set to `True`.
:param keep_project_on_failure: If `True` keep generated project directory even when
generation fails
"""
> template_dir = find_template(repo_dir)
E TypeError: find_template() missing 1 required positional argument: 'env'
cookiecutter/generate.py:170: TypeError
test_generate_files.py::test_generate_files_with_windows_newline
test_generate_files.py::test_generate_files_with_windows_newline
tmp_path = PosixPath('/tmp/pytest-of-root/pytest-0/test_generate_files_with_windo0')
def test_generate_files_with_windows_newline(tmp_path):
"""Verify windows source line end not changed during files generation."""
> generate.generate_files(
context={'cookiecutter': {'food': 'pizzä'}},
repo_dir='tests/test-generate-files',
output_dir=tmp_path,
)
tests/test_generate_files.py:105:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
repo_dir = 'tests/test-generate-files'
context = {'cookiecutter': {'food': 'pizzä'}}
output_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_generate_files_with_windo0')
overwrite_if_exists = False, skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False
def generate_files(repo_dir, context=None, output_dir='.', overwrite_if_exists=False, skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False):
"""Render the templates and saves them to files.
:param repo_dir: Project template input directory.
:param context: Dict for populating the template's variables.
:param output_dir: Where to output the generated project dir into.
:param overwrite_if_exists: Overwrite the contents of the output directory
if it exists.
:param skip_if_file_exists: Skip the files in the corresponding directories
if they already exist
:param accept_hooks: Accept pre and post hooks if set to `True`.
:param keep_project_on_failure: If `True` keep generated project directory even when
generation fails
"""
> template_dir = find_template(repo_dir)
E TypeError: find_template() missing 1 required positional argument: 'env'
cookiecutter/generate.py:170: TypeError
test_generate_files.py::test_generate_files_with_windows_newline_forced_to_linux_by_context
test_generate_files.py::test_generate_files_with_windows_newline_forced_to_linux_by_context
tmp_path = PosixPath('/tmp/pytest-of-root/pytest-0/test_generate_files_with_windo1')
def test_generate_files_with_windows_newline_forced_to_linux_by_context(tmp_path):
"""Verify windows line end changed to linux during files generation."""
> generate.generate_files(
context={'cookiecutter': {'food': 'pizzä', '_new_lines': '\n'}},
repo_dir='tests/test-generate-files',
output_dir=tmp_path,
)
tests/test_generate_files.py:123:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
repo_dir = 'tests/test-generate-files'
context = {'cookiecutter': {'_new_lines': '\n', 'food': 'pizzä'}}
output_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_generate_files_with_windo1')
overwrite_if_exists = False, skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False
def generate_files(repo_dir, context=None, output_dir='.', overwrite_if_exists=False, skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False):
"""Render the templates and saves them to files.
:param repo_dir: Project template input directory.
:param context: Dict for populating the template's variables.
:param output_dir: Where to output the generated project dir into.
:param overwrite_if_exists: Overwrite the contents of the output directory
if it exists.
:param skip_if_file_exists: Skip the files in the corresponding directories
if they already exist
:param accept_hooks: Accept pre and post hooks if set to `True`.
:param keep_project_on_failure: If `True` keep generated project directory even when
generation fails
"""
> template_dir = find_template(repo_dir)
E TypeError: find_template() missing 1 required positional argument: 'env'
cookiecutter/generate.py:170: TypeError
test_generate_files.py::test_generate_files_binaries
test_generate_files.py::test_generate_files_binaries
tmp_path = PosixPath('/tmp/pytest-of-root/pytest-0/test_generate_files_binaries0')
def test_generate_files_binaries(tmp_path):
"""Verify binary files created during directory generation."""
> generate.generate_files(
context={'cookiecutter': {'binary_test': 'binary_files'}},
repo_dir='tests/test-generate-binaries',
output_dir=tmp_path,
)
tests/test_generate_files.py:142:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
repo_dir = 'tests/test-generate-binaries'
context = {'cookiecutter': {'binary_test': 'binary_files'}}
output_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_generate_files_binaries0')
overwrite_if_exists = False, skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False
def generate_files(repo_dir, context=None, output_dir='.', overwrite_if_exists=False, skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False):
"""Render the templates and saves them to files.
:param repo_dir: Project template input directory.
:param context: Dict for populating the template's variables.
:param output_dir: Where to output the generated project dir into.
:param overwrite_if_exists: Overwrite the contents of the output directory
if it exists.
:param skip_if_file_exists: Skip the files in the corresponding directories
if they already exist
:param accept_hooks: Accept pre and post hooks if set to `True`.
:param keep_project_on_failure: If `True` keep generated project directory even when
generation fails
"""
> template_dir = find_template(repo_dir)
E TypeError: find_template() missing 1 required positional argument: 'env'
cookiecutter/generate.py:170: TypeError
test_generate_files.py::test_generate_files_absolute_path
test_generate_files.py::test_generate_files_absolute_path
tmp_path = PosixPath('/tmp/pytest-of-root/pytest-0/test_generate_files_absolute_p0')
def test_generate_files_absolute_path(tmp_path):
"""Verify usage of absolute path does not change files generation behaviour."""
> generate.generate_files(
context={'cookiecutter': {'food': 'pizzä'}},
repo_dir=Path('tests/test-generate-files').absolute(),
output_dir=tmp_path,
)
tests/test_generate_files.py:163:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
repo_dir = PosixPath('/testbed/tests/test-generate-files')
context = {'cookiecutter': {'food': 'pizzä'}}
output_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_generate_files_absolute_p0')
overwrite_if_exists = False, skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False
def generate_files(repo_dir, context=None, output_dir='.', overwrite_if_exists=False, skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False):
"""Render the templates and saves them to files.
:param repo_dir: Project template input directory.
:param context: Dict for populating the template's variables.
:param output_dir: Where to output the generated project dir into.
:param overwrite_if_exists: Overwrite the contents of the output directory
if it exists.
:param skip_if_file_exists: Skip the files in the corresponding directories
if they already exist
:param accept_hooks: Accept pre and post hooks if set to `True`.
:param keep_project_on_failure: If `True` keep generated project directory even when
generation fails
"""
> template_dir = find_template(repo_dir)
E TypeError: find_template() missing 1 required positional argument: 'env'
cookiecutter/generate.py:170: TypeError
test_generate_files.py::test_generate_files_output_dir
test_generate_files.py::test_generate_files_output_dir
tmp_path = PosixPath('/tmp/pytest-of-root/pytest-0/test_generate_files_output_dir0')
def test_generate_files_output_dir(tmp_path):
"""Verify `output_dir` option for `generate_files` changing location correctly."""
output_dir = Path(tmp_path, 'custom_output_dir')
output_dir.mkdir()
> project_dir = generate.generate_files(
context={'cookiecutter': {'food': 'pizzä'}},
repo_dir=Path('tests/test-generate-files').absolute(),
output_dir=output_dir,
)
tests/test_generate_files.py:176:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
repo_dir = PosixPath('/testbed/tests/test-generate-files')
context = {'cookiecutter': {'food': 'pizzä'}}
output_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_generate_files_output_dir0/custom_output_dir')
overwrite_if_exists = False, skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False
def generate_files(repo_dir, context=None, output_dir='.', overwrite_if_exists=False, skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False):
"""Render the templates and saves them to files.
:param repo_dir: Project template input directory.
:param context: Dict for populating the template's variables.
:param output_dir: Where to output the generated project dir into.
:param overwrite_if_exists: Overwrite the contents of the output directory
if it exists.
:param skip_if_file_exists: Skip the files in the corresponding directories
if they already exist
:param accept_hooks: Accept pre and post hooks if set to `True`.
:param keep_project_on_failure: If `True` keep generated project directory even when
generation fails
"""
> template_dir = find_template(repo_dir)
E TypeError: find_template() missing 1 required positional argument: 'env'
cookiecutter/generate.py:170: TypeError
test_generate_files.py::test_generate_files_permissions
test_generate_files.py::test_generate_files_permissions
tmp_path = PosixPath('/tmp/pytest-of-root/pytest-0/test_generate_files_permission0')
def test_generate_files_permissions(tmp_path):
"""Verify generates files respect source files permissions.
simple.txt and script.sh should retain their respective 0o644 and 0o755
permissions.
"""
> generate.generate_files(
context={'cookiecutter': {'permissions': 'permissions'}},
repo_dir='tests/test-generate-files-permissions',
output_dir=tmp_path,
)
tests/test_generate_files.py:193:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
repo_dir = 'tests/test-generate-files-permissions'
context = {'cookiecutter': {'permissions': 'permissions'}}
output_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_generate_files_permission0')
overwrite_if_exists = False, skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False
def generate_files(repo_dir, context=None, output_dir='.', overwrite_if_exists=False, skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False):
"""Render the templates and saves them to files.
:param repo_dir: Project template input directory.
:param context: Dict for populating the template's variables.
:param output_dir: Where to output the generated project dir into.
:param overwrite_if_exists: Overwrite the contents of the output directory
if it exists.
:param skip_if_file_exists: Skip the files in the corresponding directories
if they already exist
:param accept_hooks: Accept pre and post hooks if set to `True`.
:param keep_project_on_failure: If `True` keep generated project directory even when
generation fails
"""
> template_dir = find_template(repo_dir)
E TypeError: find_template() missing 1 required positional argument: 'env'
cookiecutter/generate.py:170: TypeError
test_generate_files.py::test_generate_files_with_overwrite_if_exists_with_skip_if_file_exists
test_generate_files.py::test_generate_files_with_overwrite_if_exists_with_skip_if_file_exists
tmp_path = PosixPath('/tmp/pytest-of-root/pytest-0/test_generate_files_with_overw0')
def test_generate_files_with_overwrite_if_exists_with_skip_if_file_exists(tmp_path):
"""Verify `skip_if_file_exist` has priority over `overwrite_if_exists`."""
simple_file = Path(tmp_path, 'inputpizzä/simple.txt')
simple_with_new_line_file = Path(tmp_path, 'inputpizzä/simple-with-newline.txt')
Path(tmp_path, 'inputpizzä').mkdir(parents=True)
with Path(simple_file).open('w') as f:
f.write('temp')
> generate.generate_files(
context={'cookiecutter': {'food': 'pizzä'}},
repo_dir='tests/test-generate-files',
overwrite_if_exists=True,
skip_if_file_exists=True,
output_dir=tmp_path,
)
tests/test_generate_files.py:240:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
repo_dir = 'tests/test-generate-files'
context = {'cookiecutter': {'food': 'pizzä'}}
output_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_generate_files_with_overw0')
overwrite_if_exists = True, skip_if_file_exists = True, accept_hooks = True
keep_project_on_failure = False
def generate_files(repo_dir, context=None, output_dir='.', overwrite_if_exists=False, skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False):
"""Render the templates and saves them to files.
:param repo_dir: Project template input directory.
:param context: Dict for populating the template's variables.
:param output_dir: Where to output the generated project dir into.
:param overwrite_if_exists: Overwrite the contents of the output directory
if it exists.
:param skip_if_file_exists: Skip the files in the corresponding directories
if they already exist
:param accept_hooks: Accept pre and post hooks if set to `True`.
:param keep_project_on_failure: If `True` keep generated project directory even when
generation fails
"""
> template_dir = find_template(repo_dir)
E TypeError: find_template() missing 1 required positional argument: 'env'
cookiecutter/generate.py:170: TypeError
test_generate_files.py::test_generate_files_with_skip_if_file_exists
test_generate_files.py::test_generate_files_with_skip_if_file_exists
tmp_path = PosixPath('/tmp/pytest-of-root/pytest-0/test_generate_files_with_skip_0')
def test_generate_files_with_skip_if_file_exists(tmp_path):
"""Verify existed files not removed if error raised with `skip_if_file_exists`."""
simple_file = Path(tmp_path, 'inputpizzä/simple.txt')
simple_with_new_line_file = Path(tmp_path, 'inputpizzä/simple-with-newline.txt')
Path(tmp_path, 'inputpizzä').mkdir(parents=True)
Path(simple_file).write_text('temp')
with pytest.raises(exceptions.OutputDirExistsException):
> generate.generate_files(
context={'cookiecutter': {'food': 'pizzä'}},
repo_dir='tests/test-generate-files',
skip_if_file_exists=True,
output_dir=tmp_path,
)
tests/test_generate_files.py:266:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
repo_dir = 'tests/test-generate-files'
context = {'cookiecutter': {'food': 'pizzä'}}
output_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_generate_files_with_skip_0')
overwrite_if_exists = False, skip_if_file_exists = True, accept_hooks = True
keep_project_on_failure = False
def generate_files(repo_dir, context=None, output_dir='.', overwrite_if_exists=False, skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False):
"""Render the templates and saves them to files.
:param repo_dir: Project template input directory.
:param context: Dict for populating the template's variables.
:param output_dir: Where to output the generated project dir into.
:param overwrite_if_exists: Overwrite the contents of the output directory
if it exists.
:param skip_if_file_exists: Skip the files in the corresponding directories
if they already exist
:param accept_hooks: Accept pre and post hooks if set to `True`.
:param keep_project_on_failure: If `True` keep generated project directory even when
generation fails
"""
> template_dir = find_template(repo_dir)
E TypeError: find_template() missing 1 required positional argument: 'env'
cookiecutter/generate.py:170: TypeError
test_generate_files.py::test_generate_files_with_overwrite_if_exists
test_generate_files.py::test_generate_files_with_overwrite_if_exists
tmp_path = PosixPath('/tmp/pytest-of-root/pytest-0/test_generate_files_with_overw1')
def test_generate_files_with_overwrite_if_exists(tmp_path):
"""Verify overwrite_if_exists overwrites old files."""
simple_file = Path(tmp_path, 'inputpizzä/simple.txt')
simple_with_new_line_file = Path(tmp_path, 'inputpizzä/simple-with-newline.txt')
Path(tmp_path, 'inputpizzä').mkdir(parents=True)
Path(simple_file).write_text('temp')
> generate.generate_files(
context={'cookiecutter': {'food': 'pizzä'}},
repo_dir='tests/test-generate-files',
overwrite_if_exists=True,
output_dir=tmp_path,
)
tests/test_generate_files.py:289:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
repo_dir = 'tests/test-generate-files'
context = {'cookiecutter': {'food': 'pizzä'}}
output_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_generate_files_with_overw1')
overwrite_if_exists = True, skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False
def generate_files(repo_dir, context=None, output_dir='.', overwrite_if_exists=False, skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False):
"""Render the templates and saves them to files.
:param repo_dir: Project template input directory.
:param context: Dict for populating the template's variables.
:param output_dir: Where to output the generated project dir into.
:param overwrite_if_exists: Overwrite the contents of the output directory
if it exists.
:param skip_if_file_exists: Skip the files in the corresponding directories
if they already exist
:param accept_hooks: Accept pre and post hooks if set to `True`.
:param keep_project_on_failure: If `True` keep generated project directory even when
generation fails
"""
> template_dir = find_template(repo_dir)
E TypeError: find_template() missing 1 required positional argument: 'env'
cookiecutter/generate.py:170: TypeError
test_generate_files.py::test_raise_undefined_variable_file_name
test_generate_files.py::test_raise_undefined_variable_file_name
output_dir = '/tmp/pytest-of-root/pytest-0/test_raise_undefined_variable_0/output'
undefined_context = {'cookiecutter': {'github_username': 'hackebrot', 'project_slug': 'testproject'}}
def test_raise_undefined_variable_file_name(output_dir, undefined_context):
"""Verify correct error raised when file name cannot be rendered."""
with pytest.raises(exceptions.UndefinedVariableInTemplate) as err:
> generate.generate_files(
repo_dir='tests/undefined-variable/file-name/',
output_dir=output_dir,
context=undefined_context,
)
tests/test_generate_files.py:316:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
repo_dir = 'tests/undefined-variable/file-name/'
context = {'cookiecutter': {'github_username': 'hackebrot', 'project_slug': 'testproject'}}
output_dir = '/tmp/pytest-of-root/pytest-0/test_raise_undefined_variable_0/output'
overwrite_if_exists = False, skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False
def generate_files(repo_dir, context=None, output_dir='.', overwrite_if_exists=False, skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False):
"""Render the templates and saves them to files.
:param repo_dir: Project template input directory.
:param context: Dict for populating the template's variables.
:param output_dir: Where to output the generated project dir into.
:param overwrite_if_exists: Overwrite the contents of the output directory
if it exists.
:param skip_if_file_exists: Skip the files in the corresponding directories
if they already exist
:param accept_hooks: Accept pre and post hooks if set to `True`.
:param keep_project_on_failure: If `True` keep generated project directory even when
generation fails
"""
> template_dir = find_template(repo_dir)
E TypeError: find_template() missing 1 required positional argument: 'env'
cookiecutter/generate.py:170: TypeError
test_generate_files.py::test_raise_undefined_variable_file_name_existing_project
test_generate_files.py::test_raise_undefined_variable_file_name_existing_project
output_dir = '/tmp/pytest-of-root/pytest-0/test_raise_undefined_variable_1/output'
undefined_context = {'cookiecutter': {'github_username': 'hackebrot', 'project_slug': 'testproject'}}
def test_raise_undefined_variable_file_name_existing_project(
output_dir, undefined_context
):
"""Verify correct error raised when file name cannot be rendered."""
testproj_path = Path(output_dir, 'testproject')
testproj_path.mkdir()
with pytest.raises(exceptions.UndefinedVariableInTemplate) as err:
> generate.generate_files(
repo_dir='tests/undefined-variable/file-name/',
output_dir=output_dir,
context=undefined_context,
overwrite_if_exists=True,
)
tests/test_generate_files.py:336:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
repo_dir = 'tests/undefined-variable/file-name/'
context = {'cookiecutter': {'github_username': 'hackebrot', 'project_slug': 'testproject'}}
output_dir = '/tmp/pytest-of-root/pytest-0/test_raise_undefined_variable_1/output'
overwrite_if_exists = True, skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False
def generate_files(repo_dir, context=None, output_dir='.', overwrite_if_exists=False, skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False):
"""Render the templates and saves them to files.
:param repo_dir: Project template input directory.
:param context: Dict for populating the template's variables.
:param output_dir: Where to output the generated project dir into.
:param overwrite_if_exists: Overwrite the contents of the output directory
if it exists.
:param skip_if_file_exists: Skip the files in the corresponding directories
if they already exist
:param accept_hooks: Accept pre and post hooks if set to `True`.
:param keep_project_on_failure: If `True` keep generated project directory even when
generation fails
"""
> template_dir = find_template(repo_dir)
E TypeError: find_template() missing 1 required positional argument: 'env'
cookiecutter/generate.py:170: TypeError
test_generate_files.py::test_raise_undefined_variable_file_content
test_generate_files.py::test_raise_undefined_variable_file_content
output_dir = '/tmp/pytest-of-root/pytest-0/test_raise_undefined_variable_2/output'
undefined_context = {'cookiecutter': {'github_username': 'hackebrot', 'project_slug': 'testproject'}}
def test_raise_undefined_variable_file_content(output_dir, undefined_context):
"""Verify correct error raised when file content cannot be rendered."""
with pytest.raises(exceptions.UndefinedVariableInTemplate) as err:
> generate.generate_files(
repo_dir='tests/undefined-variable/file-content/',
output_dir=output_dir,
context=undefined_context,
)
tests/test_generate_files.py:352:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
repo_dir = 'tests/undefined-variable/file-content/'
context = {'cookiecutter': {'github_username': 'hackebrot', 'project_slug': 'testproject'}}
output_dir = '/tmp/pytest-of-root/pytest-0/test_raise_undefined_variable_2/output'
overwrite_if_exists = False, skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False
def generate_files(repo_dir, context=None, output_dir='.', overwrite_if_exists=False, skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False):
"""Render the templates and saves them to files.
:param repo_dir: Project template input directory.
:param context: Dict for populating the template's variables.
:param output_dir: Where to output the generated project dir into.
:param overwrite_if_exists: Overwrite the contents of the output directory
if it exists.
:param skip_if_file_exists: Skip the files in the corresponding directories
if they already exist
:param accept_hooks: Accept pre and post hooks if set to `True`.
:param keep_project_on_failure: If `True` keep generated project directory even when
generation fails
"""
> template_dir = find_template(repo_dir)
E TypeError: find_template() missing 1 required positional argument: 'env'
cookiecutter/generate.py:170: TypeError
test_generate_files.py::test_raise_undefined_variable_dir_name
test_generate_files.py::test_raise_undefined_variable_dir_name
output_dir = '/tmp/pytest-of-root/pytest-0/test_raise_undefined_variable_3/output'
undefined_context = {'cookiecutter': {'github_username': 'hackebrot', 'project_slug': 'testproject'}}
def test_raise_undefined_variable_dir_name(output_dir, undefined_context):
"""Verify correct error raised when directory name cannot be rendered."""
with pytest.raises(exceptions.UndefinedVariableInTemplate) as err:
> generate.generate_files(
repo_dir='tests/undefined-variable/dir-name/',
output_dir=output_dir,
context=undefined_context,
)
tests/test_generate_files.py:367:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
repo_dir = 'tests/undefined-variable/dir-name/'
context = {'cookiecutter': {'github_username': 'hackebrot', 'project_slug': 'testproject'}}
output_dir = '/tmp/pytest-of-root/pytest-0/test_raise_undefined_variable_3/output'
overwrite_if_exists = False, skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False
def generate_files(repo_dir, context=None, output_dir='.', overwrite_if_exists=False, skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False):
"""Render the templates and saves them to files.
:param repo_dir: Project template input directory.
:param context: Dict for populating the template's variables.
:param output_dir: Where to output the generated project dir into.
:param overwrite_if_exists: Overwrite the contents of the output directory
if it exists.
:param skip_if_file_exists: Skip the files in the corresponding directories
if they already exist
:param accept_hooks: Accept pre and post hooks if set to `True`.
:param keep_project_on_failure: If `True` keep generated project directory even when
generation fails
"""
> template_dir = find_template(repo_dir)
E TypeError: find_template() missing 1 required positional argument: 'env'
cookiecutter/generate.py:170: TypeError
test_generate_files.py::test_keep_project_dir_on_failure
test_generate_files.py::test_keep_project_dir_on_failure
output_dir = '/tmp/pytest-of-root/pytest-0/test_keep_project_dir_on_failu0/output'
undefined_context = {'cookiecutter': {'github_username': 'hackebrot', 'project_slug': 'testproject'}}
def test_keep_project_dir_on_failure(output_dir, undefined_context):
"""Verify correct error raised when directory name cannot be rendered."""
with pytest.raises(exceptions.UndefinedVariableInTemplate):
> generate.generate_files(
repo_dir='tests/undefined-variable/dir-name/',
output_dir=output_dir,
context=undefined_context,
keep_project_on_failure=True,
)
tests/test_generate_files.py:386:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
repo_dir = 'tests/undefined-variable/dir-name/'
context = {'cookiecutter': {'github_username': 'hackebrot', 'project_slug': 'testproject'}}
output_dir = '/tmp/pytest-of-root/pytest-0/test_keep_project_dir_on_failu0/output'
overwrite_if_exists = False, skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = True
def generate_files(repo_dir, context=None, output_dir='.', overwrite_if_exists=False, skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False):
"""Render the templates and saves them to files.
:param repo_dir: Project template input directory.
:param context: Dict for populating the template's variables.
:param output_dir: Where to output the generated project dir into.
:param overwrite_if_exists: Overwrite the contents of the output directory
if it exists.
:param skip_if_file_exists: Skip the files in the corresponding directories
if they already exist
:param accept_hooks: Accept pre and post hooks if set to `True`.
:param keep_project_on_failure: If `True` keep generated project directory even when
generation fails
"""
> template_dir = find_template(repo_dir)
E TypeError: find_template() missing 1 required positional argument: 'env'
cookiecutter/generate.py:170: TypeError
test_generate_files.py::test_raise_undefined_variable_dir_name_existing_project
test_generate_files.py::test_raise_undefined_variable_dir_name_existing_project
output_dir = '/tmp/pytest-of-root/pytest-0/test_raise_undefined_variable_4/output'
undefined_context = {'cookiecutter': {'github_username': 'hackebrot', 'project_slug': 'testproject'}}
def test_raise_undefined_variable_dir_name_existing_project(
output_dir, undefined_context
):
"""Verify correct error raised when directory name cannot be rendered."""
testproj_path = Path(output_dir, 'testproject')
testproj_path.mkdir()
with pytest.raises(exceptions.UndefinedVariableInTemplate) as err:
> generate.generate_files(
repo_dir='tests/undefined-variable/dir-name/',
output_dir=output_dir,
context=undefined_context,
overwrite_if_exists=True,
)
tests/test_generate_files.py:403:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
repo_dir = 'tests/undefined-variable/dir-name/'
context = {'cookiecutter': {'github_username': 'hackebrot', 'project_slug': 'testproject'}}
output_dir = '/tmp/pytest-of-root/pytest-0/test_raise_undefined_variable_4/output'
overwrite_if_exists = True, skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False
def generate_files(repo_dir, context=None, output_dir='.', overwrite_if_exists=False, skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False):
"""Render the templates and saves them to files.
:param repo_dir: Project template input directory.
:param context: Dict for populating the template's variables.
:param output_dir: Where to output the generated project dir into.
:param overwrite_if_exists: Overwrite the contents of the output directory
if it exists.
:param skip_if_file_exists: Skip the files in the corresponding directories
if they already exist
:param accept_hooks: Accept pre and post hooks if set to `True`.
:param keep_project_on_failure: If `True` keep generated project directory even when
generation fails
"""
> template_dir = find_template(repo_dir)
E TypeError: find_template() missing 1 required positional argument: 'env'
cookiecutter/generate.py:170: TypeError
test_generate_files.py::test_raise_undefined_variable_project_dir
test_generate_files.py::test_raise_undefined_variable_project_dir
tmp_path = PosixPath('/tmp/pytest-of-root/pytest-0/test_raise_undefined_variable_5')
def test_raise_undefined_variable_project_dir(tmp_path):
"""Verify correct error raised when directory name cannot be rendered."""
with pytest.raises(exceptions.UndefinedVariableInTemplate) as err:
> generate.generate_files(
repo_dir='tests/undefined-variable/dir-name/',
output_dir=tmp_path,
context={},
)
tests/test_generate_files.py:423:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
repo_dir = 'tests/undefined-variable/dir-name/', context = {}
output_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_raise_undefined_variable_5')
overwrite_if_exists = False, skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False
def generate_files(repo_dir, context=None, output_dir='.', overwrite_if_exists=False, skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False):
"""Render the templates and saves them to files.
:param repo_dir: Project template input directory.
:param context: Dict for populating the template's variables.
:param output_dir: Where to output the generated project dir into.
:param overwrite_if_exists: Overwrite the contents of the output directory
if it exists.
:param skip_if_file_exists: Skip the files in the corresponding directories
if they already exist
:param accept_hooks: Accept pre and post hooks if set to `True`.
:param keep_project_on_failure: If `True` keep generated project directory even when
generation fails
"""
> template_dir = find_template(repo_dir)
E TypeError: find_template() missing 1 required positional argument: 'env'
cookiecutter/generate.py:170: TypeError
test_generate_hooks.py::test_ignore_hooks_dirs
test_generate_hooks.py::test_ignore_hooks_dirs
@pytest.mark.usefixtures('clean_system', 'remove_additional_folders')
def test_ignore_hooks_dirs():
"""Verify hooks directory not created in target location on files generation."""
> generate.generate_files(
context={'cookiecutter': {'pyhooks': 'pyhooks'}},
repo_dir='tests/test-pyhooks/',
output_dir='tests/test-pyhooks/',
)
tests/test_generate_hooks.py:35:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
repo_dir = 'tests/test-pyhooks/'
context = {'cookiecutter': {'pyhooks': 'pyhooks'}}
output_dir = 'tests/test-pyhooks/', overwrite_if_exists = False
skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False
def generate_files(repo_dir, context=None, output_dir='.', overwrite_if_exists=False, skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False):
"""Render the templates and saves them to files.
:param repo_dir: Project template input directory.
:param context: Dict for populating the template's variables.
:param output_dir: Where to output the generated project dir into.
:param overwrite_if_exists: Overwrite the contents of the output directory
if it exists.
:param skip_if_file_exists: Skip the files in the corresponding directories
if they already exist
:param accept_hooks: Accept pre and post hooks if set to `True`.
:param keep_project_on_failure: If `True` keep generated project directory even when
generation fails
"""
> template_dir = find_template(repo_dir)
E TypeError: find_template() missing 1 required positional argument: 'env'
cookiecutter/generate.py:170: TypeError
test_generate_hooks.py::test_run_python_hooks
test_generate_hooks.py::test_run_python_hooks
@pytest.mark.usefixtures('clean_system', 'remove_additional_folders')
def test_run_python_hooks():
"""Verify pre and post generation python hooks executed and result in output_dir.
Each hook should create in target directory. Test verifies that these files
created.
"""
> generate.generate_files(
context={'cookiecutter': {'pyhooks': 'pyhooks'}},
repo_dir='tests/test-pyhooks/',
output_dir='tests/test-pyhooks/',
)
tests/test_generate_hooks.py:50:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
repo_dir = 'tests/test-pyhooks/'
context = {'cookiecutter': {'pyhooks': 'pyhooks'}}
output_dir = 'tests/test-pyhooks/', overwrite_if_exists = False
skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False
def generate_files(repo_dir, context=None, output_dir='.', overwrite_if_exists=False, skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False):
"""Render the templates and saves them to files.
:param repo_dir: Project template input directory.
:param context: Dict for populating the template's variables.
:param output_dir: Where to output the generated project dir into.
:param overwrite_if_exists: Overwrite the contents of the output directory
if it exists.
:param skip_if_file_exists: Skip the files in the corresponding directories
if they already exist
:param accept_hooks: Accept pre and post hooks if set to `True`.
:param keep_project_on_failure: If `True` keep generated project directory even when
generation fails
"""
> template_dir = find_template(repo_dir)
E TypeError: find_template() missing 1 required positional argument: 'env'
cookiecutter/generate.py:170: TypeError
test_generate_hooks.py::test_run_python_hooks_cwd
test_generate_hooks.py::test_run_python_hooks_cwd
@pytest.mark.usefixtures('clean_system', 'remove_additional_folders')
def test_run_python_hooks_cwd():
"""Verify pre and post generation python hooks executed and result in current dir.
Each hook should create in target directory. Test verifies that these files
created.
"""
> generate.generate_files(
context={'cookiecutter': {'pyhooks': 'pyhooks'}}, repo_dir='tests/test-pyhooks/'
)
tests/test_generate_hooks.py:66:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
repo_dir = 'tests/test-pyhooks/'
context = {'cookiecutter': {'pyhooks': 'pyhooks'}}, output_dir = '.'
overwrite_if_exists = False, skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False
def generate_files(repo_dir, context=None, output_dir='.', overwrite_if_exists=False, skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False):
"""Render the templates and saves them to files.
:param repo_dir: Project template input directory.
:param context: Dict for populating the template's variables.
:param output_dir: Where to output the generated project dir into.
:param overwrite_if_exists: Overwrite the contents of the output directory
if it exists.
:param skip_if_file_exists: Skip the files in the corresponding directories
if they already exist
:param accept_hooks: Accept pre and post hooks if set to `True`.
:param keep_project_on_failure: If `True` keep generated project directory even when
generation fails
"""
> template_dir = find_template(repo_dir)
E TypeError: find_template() missing 1 required positional argument: 'env'
cookiecutter/generate.py:170: TypeError
test_generate_hooks.py::test_empty_hooks
test_generate_hooks.py::test_empty_hooks
@pytest.mark.skipif(WINDOWS, reason='OSError.errno=8 is not thrown on Windows')
@pytest.mark.usefixtures('clean_system', 'remove_additional_folders')
def test_empty_hooks():
"""Verify error is raised on empty hook script. Ignored on windows.
OSError.errno=8 is not thrown on Windows when the script is empty
because it always runs through shell instead of needing a shebang.
"""
with pytest.raises(FailedHookException) as excinfo:
> generate.generate_files(
context={'cookiecutter': {'shellhooks': 'shellhooks'}},
repo_dir='tests/test-shellhooks-empty/',
overwrite_if_exists=True,
)
tests/test_generate_hooks.py:82:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
repo_dir = 'tests/test-shellhooks-empty/'
context = {'cookiecutter': {'shellhooks': 'shellhooks'}}, output_dir = '.'
overwrite_if_exists = True, skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False
def generate_files(repo_dir, context=None, output_dir='.', overwrite_if_exists=False, skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False):
"""Render the templates and saves them to files.
:param repo_dir: Project template input directory.
:param context: Dict for populating the template's variables.
:param output_dir: Where to output the generated project dir into.
:param overwrite_if_exists: Overwrite the contents of the output directory
if it exists.
:param skip_if_file_exists: Skip the files in the corresponding directories
if they already exist
:param accept_hooks: Accept pre and post hooks if set to `True`.
:param keep_project_on_failure: If `True` keep generated project directory even when
generation fails
"""
> template_dir = find_template(repo_dir)
E TypeError: find_template() missing 1 required positional argument: 'env'
cookiecutter/generate.py:170: TypeError
test_generate_hooks.py::test_oserror_hooks
test_generate_hooks.py::test_oserror_hooks
mocker =
@pytest.mark.usefixtures('clean_system', 'remove_additional_folders')
def test_oserror_hooks(mocker):
"""Verify script error passed correctly to cookiecutter error.
Here subprocess.Popen function mocked, ie we do not call hook script,
just produce expected error.
"""
message = 'Out of memory'
err = OSError(message)
err.errno = errno.ENOMEM
prompt = mocker.patch('subprocess.Popen')
prompt.side_effect = err
with pytest.raises(FailedHookException) as excinfo:
> generate.generate_files(
context={'cookiecutter': {'shellhooks': 'shellhooks'}},
repo_dir='tests/test-shellhooks-empty/',
overwrite_if_exists=True,
)
tests/test_generate_hooks.py:106:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
repo_dir = 'tests/test-shellhooks-empty/'
context = {'cookiecutter': {'shellhooks': 'shellhooks'}}, output_dir = '.'
overwrite_if_exists = True, skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False
def generate_files(repo_dir, context=None, output_dir='.', overwrite_if_exists=False, skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False):
"""Render the templates and saves them to files.
:param repo_dir: Project template input directory.
:param context: Dict for populating the template's variables.
:param output_dir: Where to output the generated project dir into.
:param overwrite_if_exists: Overwrite the contents of the output directory
if it exists.
:param skip_if_file_exists: Skip the files in the corresponding directories
if they already exist
:param accept_hooks: Accept pre and post hooks if set to `True`.
:param keep_project_on_failure: If `True` keep generated project directory even when
generation fails
"""
> template_dir = find_template(repo_dir)
E TypeError: find_template() missing 1 required positional argument: 'env'
cookiecutter/generate.py:170: TypeError
test_generate_hooks.py::test_run_failing_hook_removes_output_directory
test_generate_hooks.py::test_run_failing_hook_removes_output_directory
@pytest.mark.usefixtures('clean_system', 'remove_additional_folders')
def test_run_failing_hook_removes_output_directory():
"""Verify project directory not created or removed if hook failed."""
repo_path = os.path.abspath('tests/test-hooks/')
hooks_path = os.path.abspath('tests/test-hooks/hooks')
hook_dir = os.path.join(repo_path, 'hooks')
template = os.path.join(repo_path, 'input{{cookiecutter.hooks}}')
os.mkdir(repo_path)
os.mkdir(hook_dir)
os.mkdir(template)
hook_path = os.path.join(hooks_path, 'pre_gen_project.py')
with Path(hook_path).open('w') as f:
f.write("#!/usr/bin/env python\n")
f.write("import sys; sys.exit(1)\n")
with pytest.raises(FailedHookException) as excinfo:
> generate.generate_files(
context={'cookiecutter': {'hooks': 'hooks'}},
repo_dir='tests/test-hooks/',
overwrite_if_exists=True,
)
tests/test_generate_hooks.py:133:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
repo_dir = 'tests/test-hooks/', context = {'cookiecutter': {'hooks': 'hooks'}}
output_dir = '.', overwrite_if_exists = True, skip_if_file_exists = False
accept_hooks = True, keep_project_on_failure = False
def generate_files(repo_dir, context=None, output_dir='.', overwrite_if_exists=False, skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False):
"""Render the templates and saves them to files.
:param repo_dir: Project template input directory.
:param context: Dict for populating the template's variables.
:param output_dir: Where to output the generated project dir into.
:param overwrite_if_exists: Overwrite the contents of the output directory
if it exists.
:param skip_if_file_exists: Skip the files in the corresponding directories
if they already exist
:param accept_hooks: Accept pre and post hooks if set to `True`.
:param keep_project_on_failure: If `True` keep generated project directory even when
generation fails
"""
> template_dir = find_template(repo_dir)
E TypeError: find_template() missing 1 required positional argument: 'env'
cookiecutter/generate.py:170: TypeError
test_generate_hooks.py::test_run_failing_hook_preserves_existing_output_directory
test_generate_hooks.py::test_run_failing_hook_preserves_existing_output_directory
@pytest.mark.usefixtures('clean_system', 'remove_additional_folders')
def test_run_failing_hook_preserves_existing_output_directory():
"""Verify project directory not removed if exist before hook failed."""
repo_path = os.path.abspath('tests/test-hooks/')
hooks_path = os.path.abspath('tests/test-hooks/hooks')
hook_dir = os.path.join(repo_path, 'hooks')
template = os.path.join(repo_path, 'input{{cookiecutter.hooks}}')
> os.mkdir(repo_path)
E FileExistsError: [Errno 17] File exists: '/testbed/tests/test-hooks'
tests/test_generate_hooks.py:151: FileExistsError
test_generate_hooks.py::test_run_shell_hooks
test_generate_hooks.py::test_run_shell_hooks
tmp_path = PosixPath('/tmp/pytest-of-root/pytest-0/test_run_shell_hooks0')
@pytest.mark.skipif(sys.platform.startswith('win'), reason="Linux only test")
@pytest.mark.usefixtures('clean_system', 'remove_additional_folders')
def test_run_shell_hooks(tmp_path):
"""Verify pre and post generate project shell hooks executed.
This test for .sh files.
"""
> generate.generate_files(
context={'cookiecutter': {'shellhooks': 'shellhooks'}},
repo_dir='tests/test-shellhooks/',
output_dir=tmp_path.joinpath('test-shellhooks'),
)
tests/test_generate_hooks.py:180:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
repo_dir = 'tests/test-shellhooks/'
context = {'cookiecutter': {'shellhooks': 'shellhooks'}}
output_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_run_shell_hooks0/test-shellhooks')
overwrite_if_exists = False, skip_if_file_exists = False, accept_hooks = True
keep_project_on_failure = False
def generate_files(repo_dir, context=None, output_dir='.', overwrite_if_exists=False, skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False):
"""Render the templates and saves them to files.
:param repo_dir: Project template input directory.
:param context: Dict for populating the template's variables.
:param output_dir: Where to output the generated project dir into.
:param overwrite_if_exists: Overwrite the contents of the output directory
if it exists.
:param skip_if_file_exists: Skip the files in the corresponding directories
if they already exist
:param accept_hooks: Accept pre and post hooks if set to `True`.
:param keep_project_on_failure: If `True` keep generated project directory even when
generation fails
"""
> template_dir = find_template(repo_dir)
E TypeError: find_template() missing 1 required positional argument: 'env'
cookiecutter/generate.py:170: TypeError
test_generate_hooks.py::test_ignore_shell_hooks
test_generate_hooks.py::test_ignore_shell_hooks
tmp_path = PosixPath('/tmp/pytest-of-root/pytest-0/test_ignore_shell_hooks0')
@pytest.mark.usefixtures("clean_system", "remove_additional_folders")
def test_ignore_shell_hooks(tmp_path):
"""Verify *.txt files not created, when accept_hooks=False."""
> generate.generate_files(
context={"cookiecutter": {"shellhooks": "shellhooks"}},
repo_dir="tests/test-shellhooks/",
output_dir=tmp_path.joinpath('test-shellhooks'),
accept_hooks=False,
)
tests/test_generate_hooks.py:220:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
repo_dir = 'tests/test-shellhooks/'
context = {'cookiecutter': {'shellhooks': 'shellhooks'}}
output_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_ignore_shell_hooks0/test-shellhooks')
overwrite_if_exists = False, skip_if_file_exists = False, accept_hooks = False
keep_project_on_failure = False
def generate_files(repo_dir, context=None, output_dir='.', overwrite_if_exists=False, skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False):
"""Render the templates and saves them to files.
:param repo_dir: Project template input directory.
:param context: Dict for populating the template's variables.
:param output_dir: Where to output the generated project dir into.
:param overwrite_if_exists: Overwrite the contents of the output directory
if it exists.
:param skip_if_file_exists: Skip the files in the corresponding directories
if they already exist
:param accept_hooks: Accept pre and post hooks if set to `True`.
:param keep_project_on_failure: If `True` keep generated project directory even when
generation fails
"""
> template_dir = find_template(repo_dir)
E TypeError: find_template() missing 1 required positional argument: 'env'
cookiecutter/generate.py:170: TypeError
test_generate_hooks.py::test_deprecate_run_hook_from_repo_dir
test_generate_hooks.py::test_deprecate_run_hook_from_repo_dir
tmp_path = PosixPath('/tmp/pytest-of-root/pytest-0/test_deprecate_run_hook_from_r0')
@pytest.mark.usefixtures("clean_system", "remove_additional_folders")
def test_deprecate_run_hook_from_repo_dir(tmp_path):
"""Test deprecation warning in generate._run_hook_from_repo_dir."""
repo_dir = "tests/test-shellhooks/"
project_dir = Path(tmp_path.joinpath('test-shellhooks'))
project_dir.mkdir()
> with pytest.deprecated_call():
E Failed: DID NOT WARN. No warnings of type (, , ) were emitted.
E Emitted warnings: [].
tests/test_generate_hooks.py:240: Failed
test_get_config.py::test_merge_configs
test_get_config.py::test_merge_configs
def test_merge_configs():
"""Verify default and user config merged in expected way."""
default = {
'cookiecutters_dir': '/home/example/some-path-to-templates',
'replay_dir': '/home/example/some-path-to-replay-files',
'default_context': {},
'abbreviations': {
'gh': 'https://github.com/{0}.git',
'gl': 'https://gitlab.com/{0}.git',
'bb': 'https://bitbucket.org/{0}',
},
}
user_config = {
'default_context': {
'full_name': 'Raphael Pierzina',
'github_username': 'hackebrot',
},
'abbreviations': {
'gl': 'https://gitlab.com/hackebrot/{0}.git',
'pytest-plugin': 'https://github.com/pytest-dev/pytest-plugin.git',
},
}
expected_config = {
'cookiecutters_dir': '/home/example/some-path-to-templates',
'replay_dir': '/home/example/some-path-to-replay-files',
'default_context': {
'full_name': 'Raphael Pierzina',
'github_username': 'hackebrot',
},
'abbreviations': {
'gh': 'https://github.com/{0}.git',
'gl': 'https://gitlab.com/hackebrot/{0}.git',
'bb': 'https://bitbucket.org/{0}',
'pytest-plugin': 'https://github.com/pytest-dev/pytest-plugin.git',
},
}
> assert config.merge_configs(default, user_config) == expected_config
E AssertionError: assert None == {'abbreviations': {'bb': 'https://bitbucket.org/{0}', 'gh': 'https://github.com/{0}.git', 'gl': 'https://gitlab.com/hackebrot/{0}.git', 'pytest-plugin': 'https://github.com/pytest-dev/pytest-plugin.git'}, 'cookiecutters_dir': '/home/example/some-path-to-templates', 'default_context': {'full_name': 'Raphael Pierzina', 'github_username': 'hackebrot'}, 'replay_dir': '/home/example/some-path-to-replay-files'}
E + where None = ({'abbreviations': {'bb': 'https://bitbucket.org/{0}', 'gh': 'https://github.com/{0}.git', 'gl': 'https://gitlab.com/{0}.git'}, 'cookiecutters_dir': '/home/example/some-path-to-templates', 'default_context': {}, 'replay_dir': '/home/example/some-path-to-replay-files'}, {'abbreviations': {'gl': 'https://gitlab.com/hackebrot/{0}.git', 'pytest-plugin': 'https://github.com/pytest-dev/pytest-plugin.git'}, 'default_context': {'full_name': 'Raphael Pierzina', 'github_username': 'hackebrot'}})
E + where = config.merge_configs
tests/test_get_config.py:51: AssertionError
test_get_config.py::test_get_config
test_get_config.py::test_get_config
def test_get_config():
"""Verify valid config opened and rendered correctly."""
conf = config.get_config('tests/test-config/valid-config.yaml')
expected_conf = {
'cookiecutters_dir': '/home/example/some-path-to-templates',
'replay_dir': '/home/example/some-path-to-replay-files',
'default_context': {
'full_name': 'Firstname Lastname',
'email': 'firstname.lastname@gmail.com',
'github_username': 'example',
'project': {
'description': 'description',
'tags': [
'first',
'second',
'third',
],
},
},
'abbreviations': {
'gh': 'https://github.com/{0}.git',
'gl': 'https://gitlab.com/{0}.git',
'bb': 'https://bitbucket.org/{0}',
'helloworld': 'https://github.com/hackebrot/helloworld',
},
}
> assert conf == expected_conf
E AssertionError: assert None == {'abbreviations': {'bb': 'https://bitbucket.org/{0}', 'gh': 'https://github.com/{0}.git', 'gl': 'https://gitlab.com/{0}.git', 'helloworld': 'https://github.com/hackebrot/helloworld'}, 'cookiecutters_dir': '/home/example/some-path-to-templates', 'default_context': {'email': 'firstname.lastname@gmail.com', 'full_name': 'Firstname Lastname', 'github_username': 'example', 'project': {'description': 'description', 'tags': ['first', 'second', 'third']}}, 'replay_dir': '/home/example/some-path-to-replay-files'}
tests/test_get_config.py:80: AssertionError
test_get_config.py::test_get_config_does_not_exist
test_get_config.py::test_get_config_does_not_exist
def test_get_config_does_not_exist():
"""Check that `exceptions.ConfigDoesNotExistException` is raised when \
attempting to get a non-existent config file."""
expected_error_msg = 'Config file tests/not-exist.yaml does not exist.'
> with pytest.raises(ConfigDoesNotExistException) as exc_info:
E Failed: DID NOT RAISE
tests/test_get_config.py:87: Failed
test_get_config.py::test_invalid_config
test_get_config.py::test_invalid_config
def test_invalid_config():
"""An invalid config file should raise an `InvalidConfiguration` \
exception."""
expected_error_msg = (
'Unable to parse YAML file tests/test-config/invalid-config.yaml.'
)
with pytest.raises(InvalidConfiguration) as exc_info:
config.get_config('tests/test-config/invalid-config.yaml')
> assert expected_error_msg in str(exc_info.value)
tests/test_get_config.py:100:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self =
@property
def value(self) -> E:
"""The exception value."""
assert (
> self._excinfo is not None
), ".value can only be used after the context manager exits"
E AssertionError: .value can only be used after the context manager exits
.venv/lib/python3.10/site-packages/_pytest/_code/code.py:548: AssertionError
test_get_config.py::test_get_config_with_defaults
test_get_config.py::test_get_config_with_defaults
def test_get_config_with_defaults():
"""A config file that overrides 1 of 3 defaults."""
conf = config.get_config('tests/test-config/valid-partial-config.yaml')
default_cookiecutters_dir = Path('~/.cookiecutters').expanduser()
default_replay_dir = Path('~/.cookiecutter_replay').expanduser()
expected_conf = {
'cookiecutters_dir': str(default_cookiecutters_dir),
'replay_dir': str(default_replay_dir),
'default_context': {
'full_name': 'Firstname Lastname',
'email': 'firstname.lastname@gmail.com',
'github_username': 'example',
},
'abbreviations': {
'gh': 'https://github.com/{0}.git',
'gl': 'https://gitlab.com/{0}.git',
'bb': 'https://bitbucket.org/{0}',
},
}
> assert conf == expected_conf
E AssertionError: assert None == {'abbreviations': {'bb': 'https://bitbucket.org/{0}', 'gh': 'https://github.com/{0}.git', 'gl': 'https://gitlab.com/{0}.git'}, 'cookiecutters_dir': '/tmp/pytest-of-root/pytest-0/test_get_config_with_defaults0/home/.cookiecutters', 'default_context': {'email': 'firstname.lastname@gmail.com', 'full_name': 'Firstname Lastname', 'github_username': 'example'}, 'replay_dir': '/tmp/pytest-of-root/pytest-0/test_get_config_with_defaults0/home/.cookiecutter_replay'}
tests/test_get_config.py:123: AssertionError
test_get_config.py::test_get_config_empty_config_file
test_get_config.py::test_get_config_empty_config_file
def test_get_config_empty_config_file():
"""An empty config file results in the default config."""
conf = config.get_config('tests/test-config/empty-config.yaml')
> assert conf == config.DEFAULT_CONFIG
E AssertionError: assert None == {'abbreviations': {'bb': 'https://bitbucket.org/{0}', 'gh': 'https://github.com/{0}.git', 'gl': 'https://gitlab.com/{0}.git'}, 'cookiecutters_dir': '/tmp/pytest-of-root/pytest-0/test_get_config_empty_config_f0/home/.cookiecutters', 'default_context': OrderedDict(), 'replay_dir': '/tmp/pytest-of-root/pytest-0/test_get_config_empty_config_f0/home/.cookiecutter_replay'}
E + where {'abbreviations': {'bb': 'https://bitbucket.org/{0}', 'gh': 'https://github.com/{0}.git', 'gl': 'https://gitlab.com/{0}.git'}, 'cookiecutters_dir': '/tmp/pytest-of-root/pytest-0/test_get_config_empty_config_f0/home/.cookiecutters', 'default_context': OrderedDict(), 'replay_dir': '/tmp/pytest-of-root/pytest-0/test_get_config_empty_config_f0/home/.cookiecutter_replay'} = config.DEFAULT_CONFIG
tests/test_get_config.py:129: AssertionError
test_get_config.py::test_get_config_invalid_file_with_array_as_top_level_element
test_get_config.py::test_get_config_invalid_file_with_array_as_top_level_element
def test_get_config_invalid_file_with_array_as_top_level_element():
"""An exception should be raised if top-level element is array."""
expected_error_msg = (
'Top-level element of YAML file '
'tests/test-config/invalid-config-w-array.yaml should be an object.'
)
> with pytest.raises(InvalidConfiguration) as exc_info:
E Failed: DID NOT RAISE
tests/test_get_config.py:138: Failed
test_get_config.py::test_get_config_invalid_file_with_multiple_docs
test_get_config.py::test_get_config_invalid_file_with_multiple_docs
def test_get_config_invalid_file_with_multiple_docs():
"""An exception should be raised if config file contains multiple docs."""
expected_error_msg = (
'Unable to parse YAML file '
'tests/test-config/invalid-config-w-multiple-docs.yaml.'
)
> with pytest.raises(InvalidConfiguration) as exc_info:
E Failed: DID NOT RAISE
tests/test_get_config.py:149: Failed
test_get_user_config.py::test_get_user_config_valid
test_get_user_config.py::test_get_user_config_valid
user_config_path = '/root/.cookiecutterrc'
custom_config = {'abbreviations': {'bb': 'https://bitbucket.org/{0}', 'gh': 'https://github.com/{0}.git', 'gl': 'https://gitlab.com/{0}.git', 'helloworld': 'https://github.com/hackebrot/helloworld'}, 'cookiecutters_dir': '/home/example/some-path-to-templates', 'default_context': {'email': 'firstname.lastname@gmail.com', 'full_name': 'Firstname Lastname', 'github_username': 'example', 'project': {'description': 'description', 'tags': ['first', 'second', 'third']}}, 'replay_dir': '/home/example/some-path-to-replay-files'}
@pytest.mark.usefixtures('back_up_rc')
def test_get_user_config_valid(user_config_path, custom_config):
"""Validate user config correctly parsed if exist and correctly formatted."""
shutil.copy('tests/test-config/valid-config.yaml', user_config_path)
conf = config.get_user_config()
> assert conf == custom_config
E AssertionError: assert None == {'abbreviations': {'bb': 'https://bitbucket.org/{0}', 'gh': 'https://github.com/{0}.git', 'gl': 'https://gitlab.com/{0}.git', 'helloworld': 'https://github.com/hackebrot/helloworld'}, 'cookiecutters_dir': '/home/example/some-path-to-templates', 'default_context': {'email': 'firstname.lastname@gmail.com', 'full_name': 'Firstname Lastname', 'github_username': 'example', 'project': {'description': 'description', 'tags': ['first', 'second', 'third']}}, 'replay_dir': '/home/example/some-path-to-replay-files'}
tests/test_get_user_config.py:76: AssertionError
test_get_user_config.py::test_get_user_config_invalid
test_get_user_config.py::test_get_user_config_invalid
user_config_path = '/root/.cookiecutterrc'
@pytest.mark.usefixtures('back_up_rc')
def test_get_user_config_invalid(user_config_path):
"""Validate `InvalidConfiguration` raised when provided user config malformed."""
shutil.copy('tests/test-config/invalid-config.yaml', user_config_path)
> with pytest.raises(InvalidConfiguration):
E Failed: DID NOT RAISE
tests/test_get_user_config.py:83: Failed
test_get_user_config.py::test_get_user_config_nonexistent
test_get_user_config.py::test_get_user_config_nonexistent
@pytest.mark.usefixtures('back_up_rc')
def test_get_user_config_nonexistent():
"""Validate default app config returned, if user does not have own config."""
> assert config.get_user_config() == config.DEFAULT_CONFIG
E AssertionError: assert None == {'abbreviations': {'bb': 'https://bitbucket.org/{0}', 'gh': 'https://github.com/{0}.git', 'gl': 'https://gitlab.com/{0}.git'}, 'cookiecutters_dir': '/tmp/pytest-of-root/pytest-0/test_get_user_config_nonexiste0/home/.cookiecutters', 'default_context': OrderedDict(), 'replay_dir': '/tmp/pytest-of-root/pytest-0/test_get_user_config_nonexiste0/home/.cookiecutter_replay'}
E + where None = ()
E + where = config.get_user_config
E + and {'abbreviations': {'bb': 'https://bitbucket.org/{0}', 'gh': 'https://github.com/{0}.git', 'gl': 'https://gitlab.com/{0}.git'}, 'cookiecutters_dir': '/tmp/pytest-of-root/pytest-0/test_get_user_config_nonexiste0/home/.cookiecutters', 'default_context': OrderedDict(), 'replay_dir': '/tmp/pytest-of-root/pytest-0/test_get_user_config_nonexiste0/home/.cookiecutter_replay'} = config.DEFAULT_CONFIG
tests/test_get_user_config.py:90: AssertionError
test_get_user_config.py::test_specify_config_path
test_get_user_config.py::test_specify_config_path
self =
args = ('tests/test-config/valid-config.yaml',), kwargs = {}
msg = "Expected 'get_config' to be called once. Called 0 times."
def assert_called_once_with(self, /, *args, **kwargs):
"""assert that the mock was called exactly once and that that call was
with the specified arguments."""
if not self.call_count == 1:
msg = ("Expected '%s' to be called once. Called %s times.%s"
% (self._mock_name or 'mock',
self.call_count,
self._calls_repr()))
> raise AssertionError(msg)
E AssertionError: Expected 'get_config' to be called once. Called 0 times.
/usr/lib/python3.10/unittest/mock.py:940: AssertionError
During handling of the above exception, another exception occurred:
mocker =
custom_config_path = 'tests/test-config/valid-config.yaml'
custom_config = {'abbreviations': {'bb': 'https://bitbucket.org/{0}', 'gh': 'https://github.com/{0}.git', 'gl': 'https://gitlab.com/{0}.git', 'helloworld': 'https://github.com/hackebrot/helloworld'}, 'cookiecutters_dir': '/home/example/some-path-to-templates', 'default_context': {'email': 'firstname.lastname@gmail.com', 'full_name': 'Firstname Lastname', 'github_username': 'example', 'project': {'description': 'description', 'tags': ['first', 'second', 'third']}}, 'replay_dir': '/home/example/some-path-to-replay-files'}
def test_specify_config_path(mocker, custom_config_path, custom_config):
"""Validate provided custom config path should be respected and parsed."""
spy_get_config = mocker.spy(config, 'get_config')
user_config = config.get_user_config(custom_config_path)
> spy_get_config.assert_called_once_with(custom_config_path)
tests/test_get_user_config.py:104:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
args = ('tests/test-config/valid-config.yaml',), kwargs = {}
def assert_called_once_with(*args, **kwargs):
> return mock.assert_called_once_with(*args, **kwargs)
E AssertionError: Expected 'get_config' to be called once. Called 0 times.
/usr/lib/python3.10/unittest/mock.py:213: AssertionError
test_get_user_config.py::test_default_config_from_env_variable
test_get_user_config.py::test_default_config_from_env_variable
monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0x7ffac9fcca60>
custom_config_path = 'tests/test-config/valid-config.yaml'
custom_config = {'abbreviations': {'bb': 'https://bitbucket.org/{0}', 'gh': 'https://github.com/{0}.git', 'gl': 'https://gitlab.com/{0}.git', 'helloworld': 'https://github.com/hackebrot/helloworld'}, 'cookiecutters_dir': '/home/example/some-path-to-templates', 'default_context': {'email': 'firstname.lastname@gmail.com', 'full_name': 'Firstname Lastname', 'github_username': 'example', 'project': {'description': 'description', 'tags': ['first', 'second', 'third']}}, 'replay_dir': '/home/example/some-path-to-replay-files'}
def test_default_config_from_env_variable(
monkeypatch, custom_config_path, custom_config
):
"""Validate app configuration. User config path should be parsed from sys env."""
monkeypatch.setenv('COOKIECUTTER_CONFIG', custom_config_path)
user_config = config.get_user_config()
> assert user_config == custom_config
E AssertionError: assert None == {'abbreviations': {'bb': 'https://bitbucket.org/{0}', 'gh': 'https://github.com/{0}.git', 'gl': 'https://gitlab.com/{0}.git', 'helloworld': 'https://github.com/hackebrot/helloworld'}, 'cookiecutters_dir': '/home/example/some-path-to-templates', 'default_context': {'email': 'firstname.lastname@gmail.com', 'full_name': 'Firstname Lastname', 'github_username': 'example', 'project': {'description': 'description', 'tags': ['first', 'second', 'third']}}, 'replay_dir': '/home/example/some-path-to-replay-files'}
tests/test_get_user_config.py:121: AssertionError
test_get_user_config.py::test_force_default_config
test_get_user_config.py::test_force_default_config
mocker =
custom_config_path = 'tests/test-config/valid-config.yaml'
def test_force_default_config(mocker, custom_config_path):
"""Validate `default_config=True` should ignore provided custom user config."""
spy_get_config = mocker.spy(config, 'get_config')
user_config = config.get_user_config(custom_config_path, default_config=True)
> assert user_config == config.DEFAULT_CONFIG
E AssertionError: assert None == {'abbreviations': {'bb': 'https://bitbucket.org/{0}', 'gh': 'https://github.com/{0}.git', 'gl': 'https://gitlab.com/{0}.git'}, 'cookiecutters_dir': '/tmp/pytest-of-root/pytest-0/test_force_default_config0/home/.cookiecutters', 'default_context': OrderedDict(), 'replay_dir': '/tmp/pytest-of-root/pytest-0/test_force_default_config0/home/.cookiecutter_replay'}
E + where {'abbreviations': {'bb': 'https://bitbucket.org/{0}', 'gh': 'https://github.com/{0}.git', 'gl': 'https://gitlab.com/{0}.git'}, 'cookiecutters_dir': '/tmp/pytest-of-root/pytest-0/test_force_default_config0/home/.cookiecutters', 'default_context': OrderedDict(), 'replay_dir': '/tmp/pytest-of-root/pytest-0/test_force_default_config0/home/.cookiecutter_replay'} = config.DEFAULT_CONFIG
tests/test_get_user_config.py:130: AssertionError
test_get_user_config.py::test_expand_user_for_directories_in_config
test_get_user_config.py::test_expand_user_for_directories_in_config
monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0x7ffaca6b8520>
def test_expand_user_for_directories_in_config(monkeypatch):
"""Validate user pointers expanded in user configs."""
def _expanduser(path):
return path.replace('~', 'Users/bob')
monkeypatch.setattr('os.path.expanduser', _expanduser)
config_file = 'tests/test-config/config-expand-user.yaml'
user_config = config.get_user_config(config_file)
> assert user_config['replay_dir'] == 'Users/bob/replay-files'
E TypeError: 'NoneType' object is not subscriptable
tests/test_get_user_config.py:145: TypeError
test_get_user_config.py::test_expand_vars_for_directories_in_config
test_get_user_config.py::test_expand_vars_for_directories_in_config
monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0x7ffac9cd1570>
def test_expand_vars_for_directories_in_config(monkeypatch):
"""Validate environment variables expanded in user configs."""
monkeypatch.setenv('COOKIES', 'Users/bob/cookies')
config_file = 'tests/test-config/config-expand-vars.yaml'
user_config = config.get_user_config(config_file)
> assert user_config['replay_dir'] == 'Users/bob/cookies/replay-files'
E TypeError: 'NoneType' object is not subscriptable
tests/test_get_user_config.py:156: TypeError
test_get_user_config.py::test_specify_config_values
test_get_user_config.py::test_specify_config_values
def test_specify_config_values():
"""Validate provided custom config values should be respected."""
replay_dir = 'Users/bob/cookies/custom-replay-dir'
custom_config_updated = {**config.DEFAULT_CONFIG, 'replay_dir': replay_dir}
user_config = config.get_user_config(default_config={'replay_dir': replay_dir})
> assert user_config == custom_config_updated
E AssertionError: assert None == {'abbreviations': {'bb': 'https://bitbucket.org/{0}', 'gh': 'https://github.com/{0}.git', 'gl': 'https://gitlab.com/{0}.git'}, 'cookiecutters_dir': '/tmp/pytest-of-root/pytest-0/test_specify_config_values0/home/.cookiecutters', 'default_context': OrderedDict(), 'replay_dir': 'Users/bob/cookies/custom-replay-dir'}
tests/test_get_user_config.py:167: AssertionError
test_hooks.py::TestFindHooks::test_find_hook
test_hooks.py::TestFindHooks::test_find_hook
self =
method = >
def setup_method(self, method):
"""Find hooks related tests setup fixture."""
> self.post_hook = make_test_repo(self.repo_path)
tests/test_hooks.py:82:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
name = 'tests/test-hooks', multiple_hooks = False
def make_test_repo(name, multiple_hooks=False):
"""Create test repository for test setup methods."""
hook_dir = os.path.join(name, 'hooks')
template = os.path.join(name, 'input{{hooks}}')
> os.mkdir(name)
E FileExistsError: [Errno 17] File exists: 'tests/test-hooks'
tests/test_hooks.py:19: FileExistsError
test_hooks.py::TestFindHooks::test_no_hooks
test_hooks.py::TestFindHooks::test_no_hooks
self =
method = >
def setup_method(self, method):
"""Find hooks related tests setup fixture."""
> self.post_hook = make_test_repo(self.repo_path)
tests/test_hooks.py:82:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
name = 'tests/test-hooks', multiple_hooks = False
def make_test_repo(name, multiple_hooks=False):
"""Create test repository for test setup methods."""
hook_dir = os.path.join(name, 'hooks')
template = os.path.join(name, 'input{{hooks}}')
> os.mkdir(name)
E FileExistsError: [Errno 17] File exists: 'tests/test-hooks'
tests/test_hooks.py:19: FileExistsError
test_hooks.py::TestFindHooks::test_unknown_hooks_dir
test_hooks.py::TestFindHooks::test_unknown_hooks_dir
self =
method = >
def setup_method(self, method):
"""Find hooks related tests setup fixture."""
> self.post_hook = make_test_repo(self.repo_path)
tests/test_hooks.py:82:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
name = 'tests/test-hooks', multiple_hooks = False
def make_test_repo(name, multiple_hooks=False):
"""Create test repository for test setup methods."""
hook_dir = os.path.join(name, 'hooks')
template = os.path.join(name, 'input{{hooks}}')
> os.mkdir(name)
E FileExistsError: [Errno 17] File exists: 'tests/test-hooks'
tests/test_hooks.py:19: FileExistsError
test_hooks.py::TestFindHooks::test_hook_not_found
test_hooks.py::TestFindHooks::test_hook_not_found
self =
method = >
def setup_method(self, method):
"""Find hooks related tests setup fixture."""
> self.post_hook = make_test_repo(self.repo_path)
tests/test_hooks.py:82:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
name = 'tests/test-hooks', multiple_hooks = False
def make_test_repo(name, multiple_hooks=False):
"""Create test repository for test setup methods."""
hook_dir = os.path.join(name, 'hooks')
template = os.path.join(name, 'input{{hooks}}')
> os.mkdir(name)
E FileExistsError: [Errno 17] File exists: 'tests/test-hooks'
tests/test_hooks.py:19: FileExistsError
test_hooks.py::TestExternalHooks::test_run_script
test_hooks.py::TestExternalHooks::test_run_script
self =
method = >
def setup_method(self, method):
"""External hooks related tests setup fixture."""
> self.post_hook = make_test_repo(self.repo_path, multiple_hooks=True)
tests/test_hooks.py:123:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
name = '/testbed/tests/test-hooks', multiple_hooks = True
def make_test_repo(name, multiple_hooks=False):
"""Create test repository for test setup methods."""
hook_dir = os.path.join(name, 'hooks')
template = os.path.join(name, 'input{{hooks}}')
> os.mkdir(name)
E FileExistsError: [Errno 17] File exists: '/testbed/tests/test-hooks'
tests/test_hooks.py:19: FileExistsError
test_hooks.py::TestExternalHooks::test_run_failing_script
test_hooks.py::TestExternalHooks::test_run_failing_script
self =
method = >
def setup_method(self, method):
"""External hooks related tests setup fixture."""
> self.post_hook = make_test_repo(self.repo_path, multiple_hooks=True)
tests/test_hooks.py:123:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
name = '/testbed/tests/test-hooks', multiple_hooks = True
def make_test_repo(name, multiple_hooks=False):
"""Create test repository for test setup methods."""
hook_dir = os.path.join(name, 'hooks')
template = os.path.join(name, 'input{{hooks}}')
> os.mkdir(name)
E FileExistsError: [Errno 17] File exists: '/testbed/tests/test-hooks'
tests/test_hooks.py:19: FileExistsError
test_hooks.py::TestExternalHooks::test_run_failing_script_enoexec
test_hooks.py::TestExternalHooks::test_run_failing_script_enoexec
self =
method = >
def setup_method(self, method):
"""External hooks related tests setup fixture."""
> self.post_hook = make_test_repo(self.repo_path, multiple_hooks=True)
tests/test_hooks.py:123:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
name = '/testbed/tests/test-hooks', multiple_hooks = True
def make_test_repo(name, multiple_hooks=False):
"""Create test repository for test setup methods."""
hook_dir = os.path.join(name, 'hooks')
template = os.path.join(name, 'input{{hooks}}')
> os.mkdir(name)
E FileExistsError: [Errno 17] File exists: '/testbed/tests/test-hooks'
tests/test_hooks.py:19: FileExistsError
test_hooks.py::TestExternalHooks::test_run_script_cwd
test_hooks.py::TestExternalHooks::test_run_script_cwd
self =
method = >
def setup_method(self, method):
"""External hooks related tests setup fixture."""
> self.post_hook = make_test_repo(self.repo_path, multiple_hooks=True)
tests/test_hooks.py:123:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
name = '/testbed/tests/test-hooks', multiple_hooks = True
def make_test_repo(name, multiple_hooks=False):
"""Create test repository for test setup methods."""
hook_dir = os.path.join(name, 'hooks')
template = os.path.join(name, 'input{{hooks}}')
> os.mkdir(name)
E FileExistsError: [Errno 17] File exists: '/testbed/tests/test-hooks'
tests/test_hooks.py:19: FileExistsError
test_hooks.py::TestExternalHooks::test_run_script_with_context
test_hooks.py::TestExternalHooks::test_run_script_with_context
self =
method = >
def setup_method(self, method):
"""External hooks related tests setup fixture."""
> self.post_hook = make_test_repo(self.repo_path, multiple_hooks=True)
tests/test_hooks.py:123:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
name = '/testbed/tests/test-hooks', multiple_hooks = True
def make_test_repo(name, multiple_hooks=False):
"""Create test repository for test setup methods."""
hook_dir = os.path.join(name, 'hooks')
template = os.path.join(name, 'input{{hooks}}')
> os.mkdir(name)
E FileExistsError: [Errno 17] File exists: '/testbed/tests/test-hooks'
tests/test_hooks.py:19: FileExistsError
test_hooks.py::TestExternalHooks::test_run_hook
test_hooks.py::TestExternalHooks::test_run_hook
self =
method = >
def setup_method(self, method):
"""External hooks related tests setup fixture."""
> self.post_hook = make_test_repo(self.repo_path, multiple_hooks=True)
tests/test_hooks.py:123:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
name = '/testbed/tests/test-hooks', multiple_hooks = True
def make_test_repo(name, multiple_hooks=False):
"""Create test repository for test setup methods."""
hook_dir = os.path.join(name, 'hooks')
template = os.path.join(name, 'input{{hooks}}')
> os.mkdir(name)
E FileExistsError: [Errno 17] File exists: '/testbed/tests/test-hooks'
tests/test_hooks.py:19: FileExistsError
test_hooks.py::TestExternalHooks::test_run_failing_hook
test_hooks.py::TestExternalHooks::test_run_failing_hook
self =
method = >
def setup_method(self, method):
"""External hooks related tests setup fixture."""
> self.post_hook = make_test_repo(self.repo_path, multiple_hooks=True)
tests/test_hooks.py:123:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
name = '/testbed/tests/test-hooks', multiple_hooks = True
def make_test_repo(name, multiple_hooks=False):
"""Create test repository for test setup methods."""
hook_dir = os.path.join(name, 'hooks')
template = os.path.join(name, 'input{{hooks}}')
> os.mkdir(name)
E FileExistsError: [Errno 17] File exists: '/testbed/tests/test-hooks'
tests/test_hooks.py:19: FileExistsError
test_log.py::test_info_stdout_logging
test_log.py::test_info_stdout_logging
caplog = <_pytest.logging.LogCaptureFixture object at 0x7ffaca41e4a0>
info_logger = None
info_messages = ['INFO: Welcome to Cookiecutter', 'INFO: Loading user config from home dir', 'ERROR: Aw, snap! Something went wrong']
def test_info_stdout_logging(caplog, info_logger, info_messages):
"""Test that stdout logs use info format and level."""
> [stream_handler] = info_logger.handlers
E AttributeError: 'NoneType' object has no attribute 'handlers'
tests/test_log.py:75: AttributeError
test_log.py::test_debug_stdout_logging
test_log.py::test_debug_stdout_logging
caplog = <_pytest.logging.LogCaptureFixture object at 0x7ffacaac6620>
debug_logger = None
debug_messages = ['INFO cookiecutter: Welcome to Cookiecutter', 'DEBUG cookiecutter: Generating project from pytest-plugin', 'INFO cookiecutter.foo: Loading user config from home dir', "DEBUG cookiecutter.foo.bar: I don't know.", 'DEBUG cookiecutter.foo.bar: I wanted to save the world.', 'ERROR cookiecutter.foo: Aw, snap! Something went wrong', ...]
def test_debug_stdout_logging(caplog, debug_logger, debug_messages):
"""Test that stdout logs use debug format and level."""
> [stream_handler] = debug_logger.handlers
E AttributeError: 'NoneType' object has no attribute 'handlers'
tests/test_log.py:92: AttributeError
test_log.py::test_debug_file_logging
test_log.py::test_debug_file_logging
caplog = <_pytest.logging.LogCaptureFixture object at 0x7ffacaac4460>
info_logger_with_file = None
debug_file = PosixPath('/tmp/pytest-of-root/pytest-0/test_debug_file_logging0/pytest-plugin.log')
debug_messages = ['INFO cookiecutter: Welcome to Cookiecutter', 'DEBUG cookiecutter: Generating project from pytest-plugin', 'INFO cookiecutter.foo: Loading user config from home dir', "DEBUG cookiecutter.foo.bar: I don't know.", 'DEBUG cookiecutter.foo.bar: I wanted to save the world.', 'ERROR cookiecutter.foo: Aw, snap! Something went wrong', ...]
def test_debug_file_logging(caplog, info_logger_with_file, debug_file, debug_messages):
"""Test that logging to stdout uses a different format and level than \
the the file handler."""
> [file_handler, stream_handler] = info_logger_with_file.handlers
E AttributeError: 'NoneType' object has no attribute 'handlers'
tests/test_log.py:110: AttributeError
test_main.py::test_original_cookiecutter_options_preserved_in__cookiecutter
test_main.py::test_original_cookiecutter_options_preserved_in__cookiecutter
monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0x7ffac9ce3100>
mocker =
user_config_file = '/tmp/pytest-of-root/pytest-0/user_dir0/config'
def test_original_cookiecutter_options_preserved_in__cookiecutter(
monkeypatch,
mocker,
user_config_file,
):
"""Preserve original context options.
Tests you can access the original context options via
`context['_cookiecutter']`.
"""
monkeypatch.chdir('tests/fake-repo-tmpl-_cookiecutter')
mock_generate_files = mocker.patch('cookiecutter.main.generate_files')
cookiecutter(
'.',
no_input=True,
replay=False,
config_file=user_config_file,
)
> assert mock_generate_files.call_args[1]['context']['_cookiecutter'][
'test_list'
] == [1, 2, 3, 4]
E TypeError: 'NoneType' object is not subscriptable
/testbed/tests/test_main.py:24: TypeError
test_main.py::test_replay_dump_template_name
test_main.py::test_replay_dump_template_name
self =
args = ('/tmp/pytest-of-root/pytest-0/user_dir0/cookiecutter_replay', 'fake-repo-tmpl', )
kwargs = {}, msg = "Expected 'dump' to be called once. Called 0 times."
def assert_called_once_with(self, /, *args, **kwargs):
"""assert that the mock was called exactly once and that that call was
with the specified arguments."""
if not self.call_count == 1:
msg = ("Expected '%s' to be called once. Called %s times.%s"
% (self._mock_name or 'mock',
self.call_count,
self._calls_repr()))
> raise AssertionError(msg)
E AssertionError: Expected 'dump' to be called once. Called 0 times.
/usr/lib/python3.10/unittest/mock.py:940: AssertionError
During handling of the above exception, another exception occurred:
monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0x7ffac9cd21d0>
mocker =
user_config_data = {'cookiecutters_dir': '/tmp/pytest-of-root/pytest-0/user_dir0/cookiecutters', 'replay_dir': '/tmp/pytest-of-root/pytest-0/user_dir0/cookiecutter_replay'}
user_config_file = '/tmp/pytest-of-root/pytest-0/user_dir0/config'
def test_replay_dump_template_name(
monkeypatch, mocker, user_config_data, user_config_file
):
"""Check that replay_dump is called with a valid template_name.
Template name must not be a relative path.
Otherwise files such as ``..json`` are created, which are not just cryptic
but also later mistaken for replay files of other templates if invoked with
'.' and '--replay'.
Change the current working directory temporarily to 'tests/fake-repo-tmpl'
for this test and call cookiecutter with '.' for the target template.
"""
monkeypatch.chdir('tests/fake-repo-tmpl')
mock_replay_dump = mocker.patch('cookiecutter.main.dump')
mocker.patch('cookiecutter.main.generate_files')
cookiecutter(
'.',
no_input=True,
replay=False,
config_file=user_config_file,
)
> mock_replay_dump.assert_called_once_with(
user_config_data['replay_dir'],
'fake-repo-tmpl',
mocker.ANY,
)
E AssertionError: Expected 'dump' to be called once. Called 0 times.
/testbed/tests/test_main.py:58: AssertionError
test_main.py::test_replay_load_template_name
test_main.py::test_replay_load_template_name
self =
args = ('/tmp/pytest-of-root/pytest-0/user_dir0/cookiecutter_replay', 'fake-repo-tmpl')
kwargs = {}, msg = "Expected 'load' to be called once. Called 0 times."
def assert_called_once_with(self, /, *args, **kwargs):
"""assert that the mock was called exactly once and that that call was
with the specified arguments."""
if not self.call_count == 1:
msg = ("Expected '%s' to be called once. Called %s times.%s"
% (self._mock_name or 'mock',
self.call_count,
self._calls_repr()))
> raise AssertionError(msg)
E AssertionError: Expected 'load' to be called once. Called 0 times.
/usr/lib/python3.10/unittest/mock.py:940: AssertionError
During handling of the above exception, another exception occurred:
monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0x7ffac9e17d60>
mocker =
user_config_data = {'cookiecutters_dir': '/tmp/pytest-of-root/pytest-0/user_dir0/cookiecutters', 'replay_dir': '/tmp/pytest-of-root/pytest-0/user_dir0/cookiecutter_replay'}
user_config_file = '/tmp/pytest-of-root/pytest-0/user_dir0/config'
def test_replay_load_template_name(
monkeypatch, mocker, user_config_data, user_config_file
):
"""Check that replay_load is called correctly.
Calls require valid template_name that is not a relative path.
Change the current working directory temporarily to 'tests/fake-repo-tmpl'
for this test and call cookiecutter with '.' for the target template.
"""
monkeypatch.chdir('tests/fake-repo-tmpl')
mock_replay_load = mocker.patch('cookiecutter.main.load')
mocker.patch('cookiecutter.main.generate_context').return_value = {
'cookiecutter': {}
}
mocker.patch('cookiecutter.main.generate_files')
mocker.patch('cookiecutter.main.dump')
cookiecutter(
'.',
replay=True,
config_file=user_config_file,
)
> mock_replay_load.assert_called_once_with(
user_config_data['replay_dir'],
'fake-repo-tmpl',
)
E AssertionError: Expected 'load' to be called once. Called 0 times.
/testbed/tests/test_main.py:90: AssertionError
test_main.py::test_custom_replay_file
test_main.py::test_custom_replay_file
self =
args = ('.', 'custom-replay-file'), kwargs = {}
msg = "Expected 'load' to be called once. Called 0 times."
def assert_called_once_with(self, /, *args, **kwargs):
"""assert that the mock was called exactly once and that that call was
with the specified arguments."""
if not self.call_count == 1:
msg = ("Expected '%s' to be called once. Called %s times.%s"
% (self._mock_name or 'mock',
self.call_count,
self._calls_repr()))
> raise AssertionError(msg)
E AssertionError: Expected 'load' to be called once. Called 0 times.
/usr/lib/python3.10/unittest/mock.py:940: AssertionError
During handling of the above exception, another exception occurred:
monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0x7ffaca6bba60>
mocker =
user_config_file = '/tmp/pytest-of-root/pytest-0/user_dir0/config'
def test_custom_replay_file(monkeypatch, mocker, user_config_file):
"""Check that reply.load is called with the custom replay_file."""
monkeypatch.chdir('tests/fake-repo-tmpl')
mock_replay_load = mocker.patch('cookiecutter.main.load')
mocker.patch('cookiecutter.main.generate_context').return_value = {
'cookiecutter': {}
}
mocker.patch('cookiecutter.main.generate_files')
mocker.patch('cookiecutter.main.dump')
cookiecutter(
'.',
replay='./custom-replay-file',
config_file=user_config_file,
)
> mock_replay_load.assert_called_once_with(
'.',
'custom-replay-file',
)
E AssertionError: Expected 'load' to be called once. Called 0 times.
/testbed/tests/test_main.py:113: AssertionError
test_output_folder.py::test_output_folder
test_output_folder.py::test_output_folder
@pytest.mark.usefixtures('clean_system', 'remove_output_folder')
def test_output_folder():
"""Tests should correctly create content, as output_folder does not yet exist."""
context = generate.generate_context(
context_file='tests/test-output-folder/cookiecutter.json'
)
> generate.generate_files(context=context, repo_dir='tests/test-output-folder')
tests/test_output_folder.py:30:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
repo_dir = 'tests/test-output-folder'
context = OrderedDict([('full_name', 'Audrey Greenfeld'), ('year', '2014'), ('color', 'green'), ('letter', 'D'), ('folder_name', 'im_a.dir'), ('filename', 'im_a.file'), ('test_name', 'output_folder')])
output_dir = '.', overwrite_if_exists = False, skip_if_file_exists = False
accept_hooks = True, keep_project_on_failure = False
def generate_files(repo_dir, context=None, output_dir='.', overwrite_if_exists=False, skip_if_file_exists=False, accept_hooks=True, keep_project_on_failure=False):
"""Render the templates and saves them to files.
:param repo_dir: Project template input directory.
:param context: Dict for populating the template's variables.
:param output_dir: Where to output the generated project dir into.
:param overwrite_if_exists: Overwrite the contents of the output directory
if it exists.
:param skip_if_file_exists: Skip the files in the corresponding directories
if they already exist
:param accept_hooks: Accept pre and post hooks if set to `True`.
:param keep_project_on_failure: If `True` keep generated project directory even when
generation fails
"""
> template_dir = find_template(repo_dir)
E TypeError: find_template() missing 1 required positional argument: 'env'
cookiecutter/generate.py:170: TypeError
test_output_folder.py::test_exception_when_output_folder_exists
test_output_folder.py::test_exception_when_output_folder_exists
@pytest.mark.usefixtures('clean_system', 'remove_output_folder')
def test_exception_when_output_folder_exists():
"""Tests should raise error as output folder created before `generate_files`."""
context = generate.generate_context(
context_file='tests/test-output-folder/cookiecutter.json'
)
> output_folder = context['cookiecutter']['test_name']
E KeyError: 'cookiecutter'
tests/test_output_folder.py:53: KeyError
test_pre_prompt_hooks.py::test_run_pre_prompt_python_hook
test_pre_prompt_hooks.py::test_run_pre_prompt_python_hook
remove_tmp_repo_dir = ._func at 0x7ffac9b793f0>
def test_run_pre_prompt_python_hook(remove_tmp_repo_dir):
"""Verify pre_prompt.py runs and creates a copy of cookiecutter.json."""
new_repo_dir = hooks.run_pre_prompt_hook(repo_dir='tests/test-pyhooks/')
> assert new_repo_dir.exists()
E AttributeError: 'NoneType' object has no attribute 'exists'
tests/test_pre_prompt_hooks.py:28: AttributeError
test_pre_prompt_hooks.py::test_run_pre_prompt_python_hook_fail
test_pre_prompt_hooks.py::test_run_pre_prompt_python_hook_fail
monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0x7ffac9b7d150>
def test_run_pre_prompt_python_hook_fail(monkeypatch):
"""Verify pre_prompt.py will fail when a given env var is present."""
message = 'Pre-Prompt Hook script failed'
with monkeypatch.context() as m:
m.setenv('COOKIECUTTER_FAIL_PRE_PROMPT', '1')
> with pytest.raises(FailedHookException) as excinfo:
E Failed: DID NOT RAISE
tests/test_pre_prompt_hooks.py:39: Failed
test_pre_prompt_hooks.py::test_run_pre_prompt_shell_hook
test_pre_prompt_hooks.py::test_run_pre_prompt_shell_hook
remove_tmp_repo_dir = ._func at 0x7ffac9b7aef0>
@pytest.mark.skipif(WINDOWS, reason='shell script will not run in Windows')
def test_run_pre_prompt_shell_hook(remove_tmp_repo_dir):
"""Verify pre_prompt.sh runs and creates a copy of cookiecutter.json."""
new_repo_dir = hooks.run_pre_prompt_hook(repo_dir='tests/test-pyshellhooks/')
> assert new_repo_dir.exists()
E AttributeError: 'NoneType' object has no attribute 'exists'
tests/test_pre_prompt_hooks.py:48: AttributeError
test_prompt.py::TestRenderVariable::test_convert_to_str[1-1]
test_prompt.py::TestRenderVariable::test_convert_to_str[1-1]
self =
mocker =
raw_var = 1, rendered_var = '1'
@pytest.mark.parametrize(
'raw_var, rendered_var',
[
(1, '1'),
(True, True),
('foo', 'foo'),
('{{cookiecutter.project}}', 'foobar'),
(None, None),
],
)
def test_convert_to_str(self, mocker, raw_var, rendered_var):
"""Verify simple items correctly rendered to strings."""
> env = environment.StrictEnvironment()
tests/test_prompt.py:37:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
cookiecutter/environment.py:49: in __init__
super().__init__(undefined=StrictUndefined, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self =
kwargs = {'undefined': }, context = {}
default_extensions = ['cookiecutter.extensions.JsonifyExtension', 'cookiecutter.extensions.RandomStringExtension', 'cookiecutter.extensions.SlugifyExtension', 'cookiecutter.extensions.TimeExtension', 'cookiecutter.extensions.UUIDExtension']
def __init__(self, **kwargs):
"""Initialize the Jinja2 Environment object while loading extensions.
Does the following:
1. Establishes default_extensions (currently just a Time feature)
2. Reads extensions set in the cookiecutter.json _extensions key.
3. Attempts to load the extensions. Provides useful error if fails.
"""
context = kwargs.pop('context', {})
default_extensions = ['cookiecutter.extensions.JsonifyExtension', 'cookiecutter.extensions.RandomStringExtension', 'cookiecutter.extensions.SlugifyExtension', 'cookiecutter.extensions.TimeExtension', 'cookiecutter.extensions.UUIDExtension']
> extensions = default_extensions + self._read_extensions(context)
E TypeError: can only concatenate list (not "NoneType") to list
cookiecutter/environment.py:23: TypeError
test_prompt.py::TestRenderVariable::test_convert_to_str[True-True]
test_prompt.py::TestRenderVariable::test_convert_to_str[True-True]
self =
mocker =
raw_var = True, rendered_var = True
@pytest.mark.parametrize(
'raw_var, rendered_var',
[
(1, '1'),
(True, True),
('foo', 'foo'),
('{{cookiecutter.project}}', 'foobar'),
(None, None),
],
)
def test_convert_to_str(self, mocker, raw_var, rendered_var):
"""Verify simple items correctly rendered to strings."""
> env = environment.StrictEnvironment()
tests/test_prompt.py:37:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
cookiecutter/environment.py:49: in __init__
super().__init__(undefined=StrictUndefined, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self =
kwargs = {'undefined': }, context = {}
default_extensions = ['cookiecutter.extensions.JsonifyExtension', 'cookiecutter.extensions.RandomStringExtension', 'cookiecutter.extensions.SlugifyExtension', 'cookiecutter.extensions.TimeExtension', 'cookiecutter.extensions.UUIDExtension']
def __init__(self, **kwargs):
"""Initialize the Jinja2 Environment object while loading extensions.
Does the following:
1. Establishes default_extensions (currently just a Time feature)
2. Reads extensions set in the cookiecutter.json _extensions key.
3. Attempts to load the extensions. Provides useful error if fails.
"""
context = kwargs.pop('context', {})
default_extensions = ['cookiecutter.extensions.JsonifyExtension', 'cookiecutter.extensions.RandomStringExtension', 'cookiecutter.extensions.SlugifyExtension', 'cookiecutter.extensions.TimeExtension', 'cookiecutter.extensions.UUIDExtension']
> extensions = default_extensions + self._read_extensions(context)
E TypeError: can only concatenate list (not "NoneType") to list
cookiecutter/environment.py:23: TypeError
test_prompt.py::TestRenderVariable::test_convert_to_str[foo-foo]
test_prompt.py::TestRenderVariable::test_convert_to_str[foo-foo]
self =
mocker =
raw_var = 'foo', rendered_var = 'foo'
@pytest.mark.parametrize(
'raw_var, rendered_var',
[
(1, '1'),
(True, True),
('foo', 'foo'),
('{{cookiecutter.project}}', 'foobar'),
(None, None),
],
)
def test_convert_to_str(self, mocker, raw_var, rendered_var):
"""Verify simple items correctly rendered to strings."""
> env = environment.StrictEnvironment()
tests/test_prompt.py:37:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
cookiecutter/environment.py:49: in __init__
super().__init__(undefined=StrictUndefined, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self =
kwargs = {'undefined': }, context = {}
default_extensions = ['cookiecutter.extensions.JsonifyExtension', 'cookiecutter.extensions.RandomStringExtension', 'cookiecutter.extensions.SlugifyExtension', 'cookiecutter.extensions.TimeExtension', 'cookiecutter.extensions.UUIDExtension']
def __init__(self, **kwargs):
"""Initialize the Jinja2 Environment object while loading extensions.
Does the following:
1. Establishes default_extensions (currently just a Time feature)
2. Reads extensions set in the cookiecutter.json _extensions key.
3. Attempts to load the extensions. Provides useful error if fails.
"""
context = kwargs.pop('context', {})
default_extensions = ['cookiecutter.extensions.JsonifyExtension', 'cookiecutter.extensions.RandomStringExtension', 'cookiecutter.extensions.SlugifyExtension', 'cookiecutter.extensions.TimeExtension', 'cookiecutter.extensions.UUIDExtension']
> extensions = default_extensions + self._read_extensions(context)
E TypeError: can only concatenate list (not "NoneType") to list
cookiecutter/environment.py:23: TypeError
test_prompt.py::TestRenderVariable::test_convert_to_str[{{cookiecutter.project}}-foobar]
test_prompt.py::TestRenderVariable::test_convert_to_str[{{cookiecutter.project}}-foobar]
self =
mocker =
raw_var = '{{cookiecutter.project}}', rendered_var = 'foobar'
@pytest.mark.parametrize(
'raw_var, rendered_var',
[
(1, '1'),
(True, True),
('foo', 'foo'),
('{{cookiecutter.project}}', 'foobar'),
(None, None),
],
)
def test_convert_to_str(self, mocker, raw_var, rendered_var):
"""Verify simple items correctly rendered to strings."""
> env = environment.StrictEnvironment()
tests/test_prompt.py:37:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
cookiecutter/environment.py:49: in __init__
super().__init__(undefined=StrictUndefined, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self =
kwargs = {'undefined': }, context = {}
default_extensions = ['cookiecutter.extensions.JsonifyExtension', 'cookiecutter.extensions.RandomStringExtension', 'cookiecutter.extensions.SlugifyExtension', 'cookiecutter.extensions.TimeExtension', 'cookiecutter.extensions.UUIDExtension']
def __init__(self, **kwargs):
"""Initialize the Jinja2 Environment object while loading extensions.
Does the following:
1. Establishes default_extensions (currently just a Time feature)
2. Reads extensions set in the cookiecutter.json _extensions key.
3. Attempts to load the extensions. Provides useful error if fails.
"""
context = kwargs.pop('context', {})
default_extensions = ['cookiecutter.extensions.JsonifyExtension', 'cookiecutter.extensions.RandomStringExtension', 'cookiecutter.extensions.SlugifyExtension', 'cookiecutter.extensions.TimeExtension', 'cookiecutter.extensions.UUIDExtension']
> extensions = default_extensions + self._read_extensions(context)
E TypeError: can only concatenate list (not "NoneType") to list
cookiecutter/environment.py:23: TypeError
test_prompt.py::TestRenderVariable::test_convert_to_str[None-None]
test_prompt.py::TestRenderVariable::test_convert_to_str[None-None]
self =
mocker =
raw_var = None, rendered_var = None
@pytest.mark.parametrize(
'raw_var, rendered_var',
[
(1, '1'),
(True, True),
('foo', 'foo'),
('{{cookiecutter.project}}', 'foobar'),
(None, None),
],
)
def test_convert_to_str(self, mocker, raw_var, rendered_var):
"""Verify simple items correctly rendered to strings."""
> env = environment.StrictEnvironment()
tests/test_prompt.py:37:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
cookiecutter/environment.py:49: in __init__
super().__init__(undefined=StrictUndefined, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self =
kwargs = {'undefined': }, context = {}
default_extensions = ['cookiecutter.extensions.JsonifyExtension', 'cookiecutter.extensions.RandomStringExtension', 'cookiecutter.extensions.SlugifyExtension', 'cookiecutter.extensions.TimeExtension', 'cookiecutter.extensions.UUIDExtension']
def __init__(self, **kwargs):
"""Initialize the Jinja2 Environment object while loading extensions.
Does the following:
1. Establishes default_extensions (currently just a Time feature)
2. Reads extensions set in the cookiecutter.json _extensions key.
3. Attempts to load the extensions. Provides useful error if fails.
"""
context = kwargs.pop('context', {})
default_extensions = ['cookiecutter.extensions.JsonifyExtension', 'cookiecutter.extensions.RandomStringExtension', 'cookiecutter.extensions.SlugifyExtension', 'cookiecutter.extensions.TimeExtension', 'cookiecutter.extensions.UUIDExtension']
> extensions = default_extensions + self._read_extensions(context)
E TypeError: can only concatenate list (not "NoneType") to list
cookiecutter/environment.py:23: TypeError
test_prompt.py::TestRenderVariable::test_convert_to_str_complex_variables[raw_var0-rendered_var0]
test_prompt.py::TestRenderVariable::test_convert_to_str_complex_variables[raw_var0-rendered_var0]
self =
raw_var = {1: True, 'foo': False}, rendered_var = {'1': True, 'foo': False}
@pytest.mark.parametrize(
'raw_var, rendered_var',
[
({1: True, 'foo': False}, {'1': True, 'foo': False}),
(
{'{{cookiecutter.project}}': ['foo', 1], 'bar': False},
{'foobar': ['foo', '1'], 'bar': False},
),
(['foo', '{{cookiecutter.project}}', None], ['foo', 'foobar', None]),
],
)
def test_convert_to_str_complex_variables(self, raw_var, rendered_var):
"""Verify tree items correctly rendered."""
> env = environment.StrictEnvironment()
tests/test_prompt.py:67:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
cookiecutter/environment.py:49: in __init__
super().__init__(undefined=StrictUndefined, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self =
kwargs = {'undefined': }, context = {}
default_extensions = ['cookiecutter.extensions.JsonifyExtension', 'cookiecutter.extensions.RandomStringExtension', 'cookiecutter.extensions.SlugifyExtension', 'cookiecutter.extensions.TimeExtension', 'cookiecutter.extensions.UUIDExtension']
def __init__(self, **kwargs):
"""Initialize the Jinja2 Environment object while loading extensions.
Does the following:
1. Establishes default_extensions (currently just a Time feature)
2. Reads extensions set in the cookiecutter.json _extensions key.
3. Attempts to load the extensions. Provides useful error if fails.
"""
context = kwargs.pop('context', {})
default_extensions = ['cookiecutter.extensions.JsonifyExtension', 'cookiecutter.extensions.RandomStringExtension', 'cookiecutter.extensions.SlugifyExtension', 'cookiecutter.extensions.TimeExtension', 'cookiecutter.extensions.UUIDExtension']
> extensions = default_extensions + self._read_extensions(context)
E TypeError: can only concatenate list (not "NoneType") to list
cookiecutter/environment.py:23: TypeError
test_prompt.py::TestRenderVariable::test_convert_to_str_complex_variables[raw_var1-rendered_var1]
test_prompt.py::TestRenderVariable::test_convert_to_str_complex_variables[raw_var1-rendered_var1]
self =
raw_var = {'bar': False, '{{cookiecutter.project}}': ['foo', 1]}
rendered_var = {'bar': False, 'foobar': ['foo', '1']}
@pytest.mark.parametrize(
'raw_var, rendered_var',
[
({1: True, 'foo': False}, {'1': True, 'foo': False}),
(
{'{{cookiecutter.project}}': ['foo', 1], 'bar': False},
{'foobar': ['foo', '1'], 'bar': False},
),
(['foo', '{{cookiecutter.project}}', None], ['foo', 'foobar', None]),
],
)
def test_convert_to_str_complex_variables(self, raw_var, rendered_var):
"""Verify tree items correctly rendered."""
> env = environment.StrictEnvironment()
tests/test_prompt.py:67:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
cookiecutter/environment.py:49: in __init__
super().__init__(undefined=StrictUndefined, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self =
kwargs = {'undefined': }, context = {}
default_extensions = ['cookiecutter.extensions.JsonifyExtension', 'cookiecutter.extensions.RandomStringExtension', 'cookiecutter.extensions.SlugifyExtension', 'cookiecutter.extensions.TimeExtension', 'cookiecutter.extensions.UUIDExtension']
def __init__(self, **kwargs):
"""Initialize the Jinja2 Environment object while loading extensions.
Does the following:
1. Establishes default_extensions (currently just a Time feature)
2. Reads extensions set in the cookiecutter.json _extensions key.
3. Attempts to load the extensions. Provides useful error if fails.
"""
context = kwargs.pop('context', {})
default_extensions = ['cookiecutter.extensions.JsonifyExtension', 'cookiecutter.extensions.RandomStringExtension', 'cookiecutter.extensions.SlugifyExtension', 'cookiecutter.extensions.TimeExtension', 'cookiecutter.extensions.UUIDExtension']
> extensions = default_extensions + self._read_extensions(context)
E TypeError: can only concatenate list (not "NoneType") to list
cookiecutter/environment.py:23: TypeError
test_prompt.py::TestRenderVariable::test_convert_to_str_complex_variables[raw_var2-rendered_var2]
test_prompt.py::TestRenderVariable::test_convert_to_str_complex_variables[raw_var2-rendered_var2]
self =
raw_var = ['foo', '{{cookiecutter.project}}', None]
rendered_var = ['foo', 'foobar', None]
@pytest.mark.parametrize(
'raw_var, rendered_var',
[
({1: True, 'foo': False}, {'1': True, 'foo': False}),
(
{'{{cookiecutter.project}}': ['foo', 1], 'bar': False},
{'foobar': ['foo', '1'], 'bar': False},
),
(['foo', '{{cookiecutter.project}}', None], ['foo', 'foobar', None]),
],
)
def test_convert_to_str_complex_variables(self, raw_var, rendered_var):
"""Verify tree items correctly rendered."""
> env = environment.StrictEnvironment()
tests/test_prompt.py:67:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
cookiecutter/environment.py:49: in __init__
super().__init__(undefined=StrictUndefined, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self =
kwargs = {'undefined': }, context = {}
default_extensions = ['cookiecutter.extensions.JsonifyExtension', 'cookiecutter.extensions.RandomStringExtension', 'cookiecutter.extensions.SlugifyExtension', 'cookiecutter.extensions.TimeExtension', 'cookiecutter.extensions.UUIDExtension']
def __init__(self, **kwargs):
"""Initialize the Jinja2 Environment object while loading extensions.
Does the following:
1. Establishes default_extensions (currently just a Time feature)
2. Reads extensions set in the cookiecutter.json _extensions key.
3. Attempts to load the extensions. Provides useful error if fails.
"""
context = kwargs.pop('context', {})
default_extensions = ['cookiecutter.extensions.JsonifyExtension', 'cookiecutter.extensions.RandomStringExtension', 'cookiecutter.extensions.SlugifyExtension', 'cookiecutter.extensions.TimeExtension', 'cookiecutter.extensions.UUIDExtension']
> extensions = default_extensions + self._read_extensions(context)
E TypeError: can only concatenate list (not "NoneType") to list
cookiecutter/environment.py:23: TypeError
input]
self =
monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0x7ffac998a260>
context = {'cookiecutter': {'full_name': 'Your Name'}}
@pytest.mark.parametrize(
'context',
[
{'cookiecutter': {'full_name': 'Your Name'}},
{'cookiecutter': {'full_name': 'Řekni či napiš své jméno'}},
],
ids=['ASCII default prompt/input', 'Unicode default prompt/input'],
)
def test_prompt_for_config(self, monkeypatch, context):
"""Verify `prompt_for_config` call `read_user_variable` on text request."""
monkeypatch.setattr(
'cookiecutter.prompt.read_user_variable',
lambda var, default, prompts, prefix: default,
)
cookiecutter_dict = prompt.prompt_for_config(context)
> assert cookiecutter_dict == context['cookiecutter']
E AssertionError: assert None == {'full_name': 'Your Name'}
tests/test_prompt.py:93: AssertionError
input]
self =
monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0x7ffac9a16d10>
context = {'cookiecutter': {'full_name': 'Řekni či napiš své jméno'}}
@pytest.mark.parametrize(
'context',
[
{'cookiecutter': {'full_name': 'Your Name'}},
{'cookiecutter': {'full_name': 'Řekni či napiš své jméno'}},
],
ids=['ASCII default prompt/input', 'Unicode default prompt/input'],
)
def test_prompt_for_config(self, monkeypatch, context):
"""Verify `prompt_for_config` call `read_user_variable` on text request."""
monkeypatch.setattr(
'cookiecutter.prompt.read_user_variable',
lambda var, default, prompts, prefix: default,
)
cookiecutter_dict = prompt.prompt_for_config(context)
> assert cookiecutter_dict == context['cookiecutter']
E AssertionError: assert None == {'full_name': 'Řekni či napiš své jméno'}
tests/test_prompt.py:93: AssertionError
input]
self =
monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0x7ffac99896f0>
context = {'cookiecutter': {'__prompts__': {'check': 'Checking', 'full_name': 'Name please'}, 'check': ['yes', 'no'], 'full_name': 'Your Name', 'nothing': 'ok'}}
@pytest.mark.parametrize(
'context',
[
{
'cookiecutter': {
'full_name': 'Your Name',
'check': ['yes', 'no'],
'nothing': 'ok',
'__prompts__': {
'full_name': 'Name please',
'check': 'Checking',
},
}
},
],
ids=['ASCII default prompt/input'],
)
def test_prompt_for_config_with_human_prompts(self, monkeypatch, context):
"""Verify call `read_user_variable` on request when human-readable prompts."""
monkeypatch.setattr(
'cookiecutter.prompt.read_user_variable',
lambda var, default, prompts, prefix: default,
)
monkeypatch.setattr(
'cookiecutter.prompt.read_user_yes_no',
lambda var, default, prompts, prefix: default,
)
monkeypatch.setattr(
'cookiecutter.prompt.read_user_choice',
lambda var, default, prompts, prefix: default,
)
cookiecutter_dict = prompt.prompt_for_config(context)
> assert cookiecutter_dict == context['cookiecutter']
E AssertionError: assert None == {'__prompts__': {'check': 'Checking', 'full_name': 'Name please'}, 'check': ['yes', 'no'], 'full_name': 'Your Name', 'nothing': 'ok'}
tests/test_prompt.py:128: AssertionError
test_prompt.py::TestPrompt::test_prompt_for_config_with_human_choices[context0]
test_prompt.py::TestPrompt::test_prompt_for_config_with_human_choices[context0]
self =
monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0x7ffac9cdef20>
context = {'cookiecutter': {'__prompts__': {'check': 'Checking'}, 'check': ['yes', 'no'], 'full_name': 'Your Name'}}
@pytest.mark.parametrize(
'context',
[
{
'cookiecutter': {
'full_name': 'Your Name',
'check': ['yes', 'no'],
'__prompts__': {
'check': 'Checking',
},
}
},
{
'cookiecutter': {
'full_name': 'Your Name',
'check': ['yes', 'no'],
'__prompts__': {
'full_name': 'Name please',
'check': {'__prompt__': 'Checking', 'yes': 'Yes', 'no': 'No'},
},
}
},
{
'cookiecutter': {
'full_name': 'Your Name',
'check': ['yes', 'no'],
'__prompts__': {
'full_name': 'Name please',
'check': {'no': 'No'},
},
}
},
],
)
def test_prompt_for_config_with_human_choices(self, monkeypatch, context):
"""Test prompts when human-readable labels for user choices."""
runner = click.testing.CliRunner()
with runner.isolation(input="\n\n\n"):
cookiecutter_dict = prompt.prompt_for_config(context)
> assert dict(cookiecutter_dict) == {'full_name': 'Your Name', 'check': 'yes'}
E TypeError: 'NoneType' object is not iterable
tests/test_prompt.py:170: TypeError
test_prompt.py::TestPrompt::test_prompt_for_config_with_human_choices[context1]
test_prompt.py::TestPrompt::test_prompt_for_config_with_human_choices[context1]
self =
monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0x7ffac9982500>
context = {'cookiecutter': {'__prompts__': {'check': {'__prompt__': 'Checking', 'no': 'No', 'yes': 'Yes'}, 'full_name': 'Name please'}, 'check': ['yes', 'no'], 'full_name': 'Your Name'}}
@pytest.mark.parametrize(
'context',
[
{
'cookiecutter': {
'full_name': 'Your Name',
'check': ['yes', 'no'],
'__prompts__': {
'check': 'Checking',
},
}
},
{
'cookiecutter': {
'full_name': 'Your Name',
'check': ['yes', 'no'],
'__prompts__': {
'full_name': 'Name please',
'check': {'__prompt__': 'Checking', 'yes': 'Yes', 'no': 'No'},
},
}
},
{
'cookiecutter': {
'full_name': 'Your Name',
'check': ['yes', 'no'],
'__prompts__': {
'full_name': 'Name please',
'check': {'no': 'No'},
},
}
},
],
)
def test_prompt_for_config_with_human_choices(self, monkeypatch, context):
"""Test prompts when human-readable labels for user choices."""
runner = click.testing.CliRunner()
with runner.isolation(input="\n\n\n"):
cookiecutter_dict = prompt.prompt_for_config(context)
> assert dict(cookiecutter_dict) == {'full_name': 'Your Name', 'check': 'yes'}
E TypeError: 'NoneType' object is not iterable
tests/test_prompt.py:170: TypeError
test_prompt.py::TestPrompt::test_prompt_for_config_with_human_choices[context2]
test_prompt.py::TestPrompt::test_prompt_for_config_with_human_choices[context2]
self =
monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0x7ffac9abbe50>
context = {'cookiecutter': {'__prompts__': {'check': {'no': 'No'}, 'full_name': 'Name please'}, 'check': ['yes', 'no'], 'full_name': 'Your Name'}}
@pytest.mark.parametrize(
'context',
[
{
'cookiecutter': {
'full_name': 'Your Name',
'check': ['yes', 'no'],
'__prompts__': {
'check': 'Checking',
},
}
},
{
'cookiecutter': {
'full_name': 'Your Name',
'check': ['yes', 'no'],
'__prompts__': {
'full_name': 'Name please',
'check': {'__prompt__': 'Checking', 'yes': 'Yes', 'no': 'No'},
},
}
},
{
'cookiecutter': {
'full_name': 'Your Name',
'check': ['yes', 'no'],
'__prompts__': {
'full_name': 'Name please',
'check': {'no': 'No'},
},
}
},
],
)
def test_prompt_for_config_with_human_choices(self, monkeypatch, context):
"""Test prompts when human-readable labels for user choices."""
runner = click.testing.CliRunner()
with runner.isolation(input="\n\n\n"):
cookiecutter_dict = prompt.prompt_for_config(context)
> assert dict(cookiecutter_dict) == {'full_name': 'Your Name', 'check': 'yes'}
E TypeError: 'NoneType' object is not iterable
tests/test_prompt.py:170: TypeError
test_prompt.py::TestPrompt::test_prompt_for_config_dict
test_prompt.py::TestPrompt::test_prompt_for_config_dict
self =
monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0x7ffaca3014e0>
def test_prompt_for_config_dict(self, monkeypatch):
"""Verify `prompt_for_config` call `read_user_variable` on dict request."""
monkeypatch.setattr(
'cookiecutter.prompt.read_user_dict',
lambda var, default, prompts, prefix: {"key": "value", "integer": 37},
)
context = {'cookiecutter': {'details': {}}}
cookiecutter_dict = prompt.prompt_for_config(context)
> assert cookiecutter_dict == {'details': {'key': 'value', 'integer': 37}}
E AssertionError: assert None == {'details': {'integer': 37, 'key': 'value'}}
tests/test_prompt.py:181: AssertionError
test_prompt.py::TestPrompt::test_should_render_dict
test_prompt.py::TestPrompt::test_should_render_dict
self =
def test_should_render_dict(self):
"""Verify template inside dictionary variable rendered."""
context = {
'cookiecutter': {
'project_name': 'Slartibartfast',
'details': {
'{{cookiecutter.project_name}}': '{{cookiecutter.project_name}}'
},
}
}
cookiecutter_dict = prompt.prompt_for_config(context, no_input=True)
> assert cookiecutter_dict == {
'project_name': 'Slartibartfast',
'details': {'Slartibartfast': 'Slartibartfast'},
}
E AssertionError: assert None == {'details': {'Slartibartfast': 'Slartibartfast'}, 'project_name': 'Slartibartfast'}
tests/test_prompt.py:195: AssertionError
test_prompt.py::TestPrompt::test_should_render_deep_dict
test_prompt.py::TestPrompt::test_should_render_deep_dict
self =
def test_should_render_deep_dict(self):
"""Verify nested structures like dict in dict, rendered correctly."""
context = {
'cookiecutter': {
'project_name': "Slartibartfast",
'details': {
"key": "value",
"integer_key": 37,
"other_name": '{{cookiecutter.project_name}}',
"dict_key": {
"deep_key": "deep_value",
"deep_integer": 42,
"deep_other_name": '{{cookiecutter.project_name}}',
"deep_list": [
"deep value 1",
"{{cookiecutter.project_name}}",
"deep value 3",
],
},
"list_key": [
"value 1",
"{{cookiecutter.project_name}}",
"value 3",
],
},
}
}
cookiecutter_dict = prompt.prompt_for_config(context, no_input=True)
> assert cookiecutter_dict == {
'project_name': "Slartibartfast",
'details': {
"key": "value",
"integer_key": "37",
"other_name": "Slartibartfast",
"dict_key": {
"deep_key": "deep_value",
"deep_integer": "42",
"deep_other_name": "Slartibartfast",
"deep_list": ["deep value 1", "Slartibartfast", "deep value 3"],
},
"list_key": ["value 1", "Slartibartfast", "value 3"],
},
}
E AssertionError: assert None == {'details': {'dict_key': {'deep_integer': '42', 'deep_key': 'deep_value', 'deep_list': ['deep value 1', 'Slartibartfast', 'deep value 3'], 'deep_other_name': 'Slartibartfast'}, 'integer_key': '37', 'key': 'value', 'list_key': ['value 1', 'Slartibartfast', 'value 3'], ...}, 'project_name': 'Slartibartfast'}
tests/test_prompt.py:229: AssertionError
test_prompt.py::TestPrompt::test_should_render_deep_dict_with_human_prompts
test_prompt.py::TestPrompt::test_should_render_deep_dict_with_human_prompts
self =
def test_should_render_deep_dict_with_human_prompts(self):
"""Verify dict rendered correctly when human-readable prompts."""
context = {
'cookiecutter': {
'project_name': "Slartibartfast",
'details': {
"key": "value",
"integer_key": 37,
"other_name": '{{cookiecutter.project_name}}',
"dict_key": {
"deep_key": "deep_value",
},
},
'__prompts__': {'project_name': 'Project name'},
}
}
cookiecutter_dict = prompt.prompt_for_config(context, no_input=True)
> assert cookiecutter_dict == {
'project_name': "Slartibartfast",
'details': {
"key": "value",
"integer_key": "37",
"other_name": "Slartibartfast",
"dict_key": {
"deep_key": "deep_value",
},
},
}
E AssertionError: assert None == {'details': {'dict_key': {'deep_key': 'deep_value'}, 'integer_key': '37', 'key': 'value', 'other_name': 'Slartibartfast'}, 'project_name': 'Slartibartfast'}
tests/test_prompt.py:262: AssertionError
test_prompt.py::TestPrompt::test_internal_use_no_human_prompts
test_prompt.py::TestPrompt::test_internal_use_no_human_prompts
self =
def test_internal_use_no_human_prompts(self):
"""Verify dict rendered correctly when human-readable prompts empty."""
context = {
'cookiecutter': {
'project_name': "Slartibartfast",
'__prompts__': {},
}
}
cookiecutter_dict = prompt.prompt_for_config(context, no_input=True)
> assert cookiecutter_dict == {
'project_name': "Slartibartfast",
}
E AssertionError: assert None == {'project_name': 'Slartibartfast'}
tests/test_prompt.py:283: AssertionError
test_prompt.py::TestPrompt::test_prompt_for_templated_config
test_prompt.py::TestPrompt::test_prompt_for_templated_config
self =
monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0x7ffac9c22b60>
def test_prompt_for_templated_config(self, monkeypatch):
"""Verify Jinja2 templating works in unicode prompts."""
monkeypatch.setattr(
'cookiecutter.prompt.read_user_variable',
lambda var, default, prompts, prefix: default,
)
context = {
'cookiecutter': OrderedDict(
[
('project_name', 'A New Project'),
(
'pkg_name',
'{{ cookiecutter.project_name|lower|replace(" ", "") }}',
),
]
)
}
exp_cookiecutter_dict = {
'project_name': 'A New Project',
'pkg_name': 'anewproject',
}
cookiecutter_dict = prompt.prompt_for_config(context)
> assert cookiecutter_dict == exp_cookiecutter_dict
E AssertionError: assert None == {'pkg_name': 'anewproject', 'project_name': 'A New Project'}
tests/test_prompt.py:310: AssertionError
test_prompt.py::TestPrompt::test_dont_prompt_for_private_context_var
test_prompt.py::TestPrompt::test_dont_prompt_for_private_context_var
self =
monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0x7ffac9b7e680>
def test_dont_prompt_for_private_context_var(self, monkeypatch):
"""Verify `read_user_variable` not called for private context variables."""
monkeypatch.setattr(
'cookiecutter.prompt.read_user_variable',
lambda var, default: pytest.fail(
'Should not try to read a response for private context var'
),
)
context = {'cookiecutter': {'_copy_without_render': ['*.html']}}
cookiecutter_dict = prompt.prompt_for_config(context)
> assert cookiecutter_dict == {'_copy_without_render': ['*.html']}
E AssertionError: assert None == {'_copy_without_render': ['*.html']}
tests/test_prompt.py:322: AssertionError
test_prompt.py::TestPrompt::test_should_render_private_variables_with_two_underscores
test_prompt.py::TestPrompt::test_should_render_private_variables_with_two_underscores
self =
def test_should_render_private_variables_with_two_underscores(self):
"""Test rendering of private variables with two underscores.
There are three cases:
1. Variables beginning with a single underscore are private and not rendered.
2. Variables beginning with a double underscore are private and are rendered.
3. Variables beginning with anything other than underscores are not private and
are rendered.
"""
context = {
'cookiecutter': OrderedDict(
[
('foo', 'Hello world'),
('bar', 123),
('rendered_foo', '{{ cookiecutter.foo|lower }}'),
('rendered_bar', 123),
('_hidden_foo', '{{ cookiecutter.foo|lower }}'),
('_hidden_bar', 123),
('__rendered_hidden_foo', '{{ cookiecutter.foo|lower }}'),
('__rendered_hidden_bar', 123),
]
)
}
cookiecutter_dict = prompt.prompt_for_config(context, no_input=True)
> assert cookiecutter_dict == OrderedDict(
[
('foo', 'Hello world'),
('bar', '123'),
('rendered_foo', 'hello world'),
('rendered_bar', '123'),
('_hidden_foo', '{{ cookiecutter.foo|lower }}'),
('_hidden_bar', 123),
('__rendered_hidden_foo', 'hello world'),
('__rendered_hidden_bar', '123'),
]
)
E AssertionError: assert None == OrderedDict([('foo', 'Hello world'), ('bar', '123'), ('rendered_foo', 'hello world'), ('rendered_bar', '123'), ('_hidden_foo', '{{ cookiecutter.foo|lower }}'), ('_hidden_bar', 123), ('__rendered_hidden_foo', 'hello world'), ('__rendered_hidden_bar', '123')])
E + where OrderedDict([('foo', 'Hello world'), ('bar', '123'), ('rendered_foo', 'hello world'), ('rendered_bar', '123'), ('_hidden_foo', '{{ cookiecutter.foo|lower }}'), ('_hidden_bar', 123), ('__rendered_hidden_foo', 'hello world'), ('__rendered_hidden_bar', '123')]) = OrderedDict([('foo', 'Hello world'), ('bar', '123'), ('rendered_foo', 'hello world'), ('rendered_bar', '123'), ('_hidden_foo', '{{ cookiecutter.foo|lower }}'), ('_hidden_bar', 123), ...])
tests/test_prompt.py:348: AssertionError
test_prompt.py::TestPrompt::test_should_not_render_private_variables
test_prompt.py::TestPrompt::test_should_not_render_private_variables
self =
def test_should_not_render_private_variables(self):
"""Verify private(underscored) variables not rendered by `prompt_for_config`.
Private variables designed to be raw, same as context input.
"""
context = {
'cookiecutter': {
'project_name': 'Skip render',
'_skip_jinja_template': '{{cookiecutter.project_name}}',
'_skip_float': 123.25,
'_skip_integer': 123,
'_skip_boolean': True,
'_skip_nested': True,
}
}
cookiecutter_dict = prompt.prompt_for_config(context, no_input=True)
> assert cookiecutter_dict == context['cookiecutter']
E AssertionError: assert None == {'_skip_boolean': True, '_skip_float': 123.25, '_skip_integer': 123, '_skip_jinja_template': '{{cookiecutter.project_name}}', ...}
tests/test_prompt.py:377: AssertionError
test_prompt.py::TestReadUserChoice::test_should_invoke_read_user_choice
test_prompt.py::TestReadUserChoice::test_should_invoke_read_user_choice
self =
mocker =
def test_should_invoke_read_user_choice(self, mocker):
"""Verify correct function called for select(list) variables."""
prompt_choice = mocker.patch(
'cookiecutter.prompt.prompt_choice_for_config',
wraps=prompt.prompt_choice_for_config,
)
read_user_choice = mocker.patch('cookiecutter.prompt.read_user_choice')
read_user_choice.return_value = 'all'
read_user_variable = mocker.patch('cookiecutter.prompt.read_user_variable')
choices = ['landscape', 'portrait', 'all']
context = {'cookiecutter': {'orientation': choices}}
cookiecutter_dict = prompt.prompt_for_config(context)
assert not read_user_variable.called
> assert prompt_choice.called
E AssertionError: assert False
E + where False = .called
tests/test_prompt.py:404: AssertionError
test_prompt.py::TestReadUserChoice::test_should_invoke_read_user_variable
test_prompt.py::TestReadUserChoice::test_should_invoke_read_user_variable
self =
args = ('full_name', 'Your Name', {}, ' [dim][1/1][/] '), kwargs = {}
msg = "Expected 'read_user_variable' to be called once. Called 0 times."
def assert_called_once_with(self, /, *args, **kwargs):
"""assert that the mock was called exactly once and that that call was
with the specified arguments."""
if not self.call_count == 1:
msg = ("Expected '%s' to be called once. Called %s times.%s"
% (self._mock_name or 'mock',
self.call_count,
self._calls_repr()))
> raise AssertionError(msg)
E AssertionError: Expected 'read_user_variable' to be called once. Called 0 times.
/usr/lib/python3.10/unittest/mock.py:940: AssertionError
During handling of the above exception, another exception occurred:
self =
mocker =
def test_should_invoke_read_user_variable(self, mocker):
"""Verify correct function called for string input variables."""
read_user_variable = mocker.patch('cookiecutter.prompt.read_user_variable')
read_user_variable.return_value = 'Audrey Roy'
prompt_choice = mocker.patch('cookiecutter.prompt.prompt_choice_for_config')
read_user_choice = mocker.patch('cookiecutter.prompt.read_user_choice')
context = {'cookiecutter': {'full_name': 'Your Name'}}
cookiecutter_dict = prompt.prompt_for_config(context)
assert not prompt_choice.called
assert not read_user_choice.called
> read_user_variable.assert_called_once_with(
'full_name', 'Your Name', {}, DEFAULT_PREFIX
)
E AssertionError: Expected 'read_user_variable' to be called once. Called 0 times.
tests/test_prompt.py:425: AssertionError
test_prompt.py::TestReadUserChoice::test_should_render_choices
test_prompt.py::TestReadUserChoice::test_should_render_choices
self =
args = ('project_name', 'A New Project', {}, ' [dim][1/2][/] '), kwargs = {}
msg = "Expected 'read_user_variable' to be called once. Called 0 times."
def assert_called_once_with(self, /, *args, **kwargs):
"""assert that the mock was called exactly once and that that call was
with the specified arguments."""
if not self.call_count == 1:
msg = ("Expected '%s' to be called once. Called %s times.%s"
% (self._mock_name or 'mock',
self.call_count,
self._calls_repr()))
> raise AssertionError(msg)
E AssertionError: Expected 'read_user_variable' to be called once. Called 0 times.
/usr/lib/python3.10/unittest/mock.py:940: AssertionError
During handling of the above exception, another exception occurred:
self =
mocker =
def test_should_render_choices(self, mocker):
"""Verify Jinja2 templating engine works inside choices variables."""
read_user_choice = mocker.patch('cookiecutter.prompt.read_user_choice')
read_user_choice.return_value = 'anewproject'
read_user_variable = mocker.patch('cookiecutter.prompt.read_user_variable')
read_user_variable.return_value = 'A New Project'
rendered_choices = ['foo', 'anewproject', 'bar']
context = {
'cookiecutter': OrderedDict(
[
('project_name', 'A New Project'),
(
'pkg_name',
[
'foo',
'{{ cookiecutter.project_name|lower|replace(" ", "") }}',
'bar',
],
),
]
)
}
expected = {
'project_name': 'A New Project',
'pkg_name': 'anewproject',
}
cookiecutter_dict = prompt.prompt_for_config(context)
> read_user_variable.assert_called_once_with(
'project_name', 'A New Project', {}, ' [dim][1/2][/] '
)
E AssertionError: Expected 'read_user_variable' to be called once. Called 0 times.
tests/test_prompt.py:462: AssertionError
test_prompt.py::TestPromptChoiceForConfig::test_should_return_first_option_if_no_input
self =
mocker =
choices = ['landscape', 'portrait', 'all']
context = {'cookiecutter': {'orientation': ['landscape', 'portrait', 'all']}}
def test_should_return_first_option_if_no_input(self, mocker, choices, context):
"""Verify prompt_choice_for_config return first list option on no_input=True."""
read_user_choice = mocker.patch('cookiecutter.prompt.read_user_choice')
expected_choice = choices[0]
actual_choice = prompt.prompt_choice_for_config(
cookiecutter_dict=context,
> env=environment.StrictEnvironment(),
key='orientation',
options=choices,
no_input=True, # Suppress user input
)
tests/test_prompt.py:492:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
cookiecutter/environment.py:49: in __init__
super().__init__(undefined=StrictUndefined, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self =
kwargs = {'undefined': }, context = {}
default_extensions = ['cookiecutter.extensions.JsonifyExtension', 'cookiecutter.extensions.RandomStringExtension', 'cookiecutter.extensions.SlugifyExtension', 'cookiecutter.extensions.TimeExtension', 'cookiecutter.extensions.UUIDExtension']
def __init__(self, **kwargs):
"""Initialize the Jinja2 Environment object while loading extensions.
Does the following:
1. Establishes default_extensions (currently just a Time feature)
2. Reads extensions set in the cookiecutter.json _extensions key.
3. Attempts to load the extensions. Provides useful error if fails.
"""
context = kwargs.pop('context', {})
default_extensions = ['cookiecutter.extensions.JsonifyExtension', 'cookiecutter.extensions.RandomStringExtension', 'cookiecutter.extensions.SlugifyExtension', 'cookiecutter.extensions.TimeExtension', 'cookiecutter.extensions.UUIDExtension']
> extensions = default_extensions + self._read_extensions(context)
E TypeError: can only concatenate list (not "NoneType") to list
cookiecutter/environment.py:23: TypeError
test_prompt.py::TestPromptChoiceForConfig::test_should_read_user_choice
test_prompt.py::TestPromptChoiceForConfig::test_should_read_user_choice
self =
mocker =
choices = ['landscape', 'portrait', 'all']
context = {'cookiecutter': {'orientation': ['landscape', 'portrait', 'all']}}
def test_should_read_user_choice(self, mocker, choices, context):
"""Verify prompt_choice_for_config return user selection on no_input=False."""
read_user_choice = mocker.patch('cookiecutter.prompt.read_user_choice')
read_user_choice.return_value = 'all'
expected_choice = 'all'
actual_choice = prompt.prompt_choice_for_config(
cookiecutter_dict=context,
> env=environment.StrictEnvironment(),
key='orientation',
options=choices,
no_input=False, # Ask the user for input
)
tests/test_prompt.py:510:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
cookiecutter/environment.py:49: in __init__
super().__init__(undefined=StrictUndefined, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self =
kwargs = {'undefined': }, context = {}
default_extensions = ['cookiecutter.extensions.JsonifyExtension', 'cookiecutter.extensions.RandomStringExtension', 'cookiecutter.extensions.SlugifyExtension', 'cookiecutter.extensions.TimeExtension', 'cookiecutter.extensions.UUIDExtension']
def __init__(self, **kwargs):
"""Initialize the Jinja2 Environment object while loading extensions.
Does the following:
1. Establishes default_extensions (currently just a Time feature)
2. Reads extensions set in the cookiecutter.json _extensions key.
3. Attempts to load the extensions. Provides useful error if fails.
"""
context = kwargs.pop('context', {})
default_extensions = ['cookiecutter.extensions.JsonifyExtension', 'cookiecutter.extensions.RandomStringExtension', 'cookiecutter.extensions.SlugifyExtension', 'cookiecutter.extensions.TimeExtension', 'cookiecutter.extensions.UUIDExtension']
> extensions = default_extensions + self._read_extensions(context)
E TypeError: can only concatenate list (not "NoneType") to list
cookiecutter/environment.py:23: TypeError
test_prompt.py::TestReadUserYesNo::test_should_invoke_read_user_yes_no[True]
test_prompt.py::TestReadUserYesNo::test_should_invoke_read_user_yes_no[True]
self =
args = ('run_as_docker', True, {}, ' [dim][1/1][/] '), kwargs = {}
msg = "Expected 'read_user_yes_no' to be called once. Called 0 times."
def assert_called_once_with(self, /, *args, **kwargs):
"""assert that the mock was called exactly once and that that call was
with the specified arguments."""
if not self.call_count == 1:
msg = ("Expected '%s' to be called once. Called %s times.%s"
% (self._mock_name or 'mock',
self.call_count,
self._calls_repr()))
> raise AssertionError(msg)
E AssertionError: Expected 'read_user_yes_no' to be called once. Called 0 times.
/usr/lib/python3.10/unittest/mock.py:940: AssertionError
During handling of the above exception, another exception occurred:
self =
mocker =
run_as_docker = True
@pytest.mark.parametrize(
'run_as_docker',
(
True,
False,
),
)
def test_should_invoke_read_user_yes_no(self, mocker, run_as_docker):
"""Verify correct function called for boolean variables."""
read_user_yes_no = mocker.patch('cookiecutter.prompt.read_user_yes_no')
read_user_yes_no.return_value = run_as_docker
read_user_variable = mocker.patch('cookiecutter.prompt.read_user_variable')
context = {'cookiecutter': {'run_as_docker': run_as_docker}}
cookiecutter_dict = prompt.prompt_for_config(context)
assert not read_user_variable.called
> read_user_yes_no.assert_called_once_with(
'run_as_docker', run_as_docker, {}, DEFAULT_PREFIX
)
E AssertionError: Expected 'read_user_yes_no' to be called once. Called 0 times.
tests/test_prompt.py:541: AssertionError
test_prompt.py::TestReadUserYesNo::test_should_invoke_read_user_yes_no[False]
test_prompt.py::TestReadUserYesNo::test_should_invoke_read_user_yes_no[False]
self =
args = ('run_as_docker', False, {}, ' [dim][1/1][/] '), kwargs = {}
msg = "Expected 'read_user_yes_no' to be called once. Called 0 times."
def assert_called_once_with(self, /, *args, **kwargs):
"""assert that the mock was called exactly once and that that call was
with the specified arguments."""
if not self.call_count == 1:
msg = ("Expected '%s' to be called once. Called %s times.%s"
% (self._mock_name or 'mock',
self.call_count,
self._calls_repr()))
> raise AssertionError(msg)
E AssertionError: Expected 'read_user_yes_no' to be called once. Called 0 times.
/usr/lib/python3.10/unittest/mock.py:940: AssertionError
During handling of the above exception, another exception occurred:
self =
mocker =
run_as_docker = False
@pytest.mark.parametrize(
'run_as_docker',
(
True,
False,
),
)
def test_should_invoke_read_user_yes_no(self, mocker, run_as_docker):
"""Verify correct function called for boolean variables."""
read_user_yes_no = mocker.patch('cookiecutter.prompt.read_user_yes_no')
read_user_yes_no.return_value = run_as_docker
read_user_variable = mocker.patch('cookiecutter.prompt.read_user_variable')
context = {'cookiecutter': {'run_as_docker': run_as_docker}}
cookiecutter_dict = prompt.prompt_for_config(context)
assert not read_user_variable.called
> read_user_yes_no.assert_called_once_with(
'run_as_docker', run_as_docker, {}, DEFAULT_PREFIX
)
E AssertionError: Expected 'read_user_yes_no' to be called once. Called 0 times.
tests/test_prompt.py:541: AssertionError
test_prompt.py::TestReadUserYesNo::test_boolean_parameter_no_input
self =
def test_boolean_parameter_no_input(self):
"""Verify boolean parameter sent to prompt for config with no input."""
context = {
'cookiecutter': {
'run_as_docker': True,
}
}
cookiecutter_dict = prompt.prompt_for_config(context, no_input=True)
> assert cookiecutter_dict == context['cookiecutter']
E AssertionError: assert None == {'run_as_docker': True}
tests/test_prompt.py:554: AssertionError
test_prompt.py::test_undefined_variable[Undefined variable in cookiecutter dict]
test_prompt.py::test_undefined_variable[Undefined variable in cookiecutter dict]
context = {'cookiecutter': {'foo': '{{cookiecutter.nope}}'}}
@pytest.mark.parametrize(
'context',
(
{'cookiecutter': {'foo': '{{cookiecutter.nope}}'}},
{'cookiecutter': {'foo': ['123', '{{cookiecutter.nope}}', '456']}},
{'cookiecutter': {'foo': {'{{cookiecutter.nope}}': 'value'}}},
{'cookiecutter': {'foo': {'key': '{{cookiecutter.nope}}'}}},
),
ids=[
'Undefined variable in cookiecutter dict',
'Undefined variable in cookiecutter dict with choices',
'Undefined variable in cookiecutter dict with dict_key',
'Undefined variable in cookiecutter dict with key_value',
],
)
def test_undefined_variable(context):
"""Verify `prompt.prompt_for_config` raises correct error."""
> with pytest.raises(exceptions.UndefinedVariableInTemplate) as err:
E Failed: DID NOT RAISE
tests/test_prompt.py:574: Failed
test_prompt.py::test_undefined_variable[Undefined variable in cookiecutter dict with choices]
test_prompt.py::test_undefined_variable[Undefined variable in cookiecutter dict with choices]
context = {'cookiecutter': {'foo': ['123', '{{cookiecutter.nope}}', '456']}}
@pytest.mark.parametrize(
'context',
(
{'cookiecutter': {'foo': '{{cookiecutter.nope}}'}},
{'cookiecutter': {'foo': ['123', '{{cookiecutter.nope}}', '456']}},
{'cookiecutter': {'foo': {'{{cookiecutter.nope}}': 'value'}}},
{'cookiecutter': {'foo': {'key': '{{cookiecutter.nope}}'}}},
),
ids=[
'Undefined variable in cookiecutter dict',
'Undefined variable in cookiecutter dict with choices',
'Undefined variable in cookiecutter dict with dict_key',
'Undefined variable in cookiecutter dict with key_value',
],
)
def test_undefined_variable(context):
"""Verify `prompt.prompt_for_config` raises correct error."""
> with pytest.raises(exceptions.UndefinedVariableInTemplate) as err:
E Failed: DID NOT RAISE
tests/test_prompt.py:574: Failed
test_prompt.py::test_undefined_variable[Undefined variable in cookiecutter dict with dict_key]
test_prompt.py::test_undefined_variable[Undefined variable in cookiecutter dict with dict_key]
context = {'cookiecutter': {'foo': {'{{cookiecutter.nope}}': 'value'}}}
@pytest.mark.parametrize(
'context',
(
{'cookiecutter': {'foo': '{{cookiecutter.nope}}'}},
{'cookiecutter': {'foo': ['123', '{{cookiecutter.nope}}', '456']}},
{'cookiecutter': {'foo': {'{{cookiecutter.nope}}': 'value'}}},
{'cookiecutter': {'foo': {'key': '{{cookiecutter.nope}}'}}},
),
ids=[
'Undefined variable in cookiecutter dict',
'Undefined variable in cookiecutter dict with choices',
'Undefined variable in cookiecutter dict with dict_key',
'Undefined variable in cookiecutter dict with key_value',
],
)
def test_undefined_variable(context):
"""Verify `prompt.prompt_for_config` raises correct error."""
> with pytest.raises(exceptions.UndefinedVariableInTemplate) as err:
E Failed: DID NOT RAISE
tests/test_prompt.py:574: Failed
test_prompt.py::test_undefined_variable[Undefined variable in cookiecutter dict with key_value]
test_prompt.py::test_undefined_variable[Undefined variable in cookiecutter dict with key_value]
context = {'cookiecutter': {'foo': {'key': '{{cookiecutter.nope}}'}}}
@pytest.mark.parametrize(
'context',
(
{'cookiecutter': {'foo': '{{cookiecutter.nope}}'}},
{'cookiecutter': {'foo': ['123', '{{cookiecutter.nope}}', '456']}},
{'cookiecutter': {'foo': {'{{cookiecutter.nope}}': 'value'}}},
{'cookiecutter': {'foo': {'key': '{{cookiecutter.nope}}'}}},
),
ids=[
'Undefined variable in cookiecutter dict',
'Undefined variable in cookiecutter dict with choices',
'Undefined variable in cookiecutter dict with dict_key',
'Undefined variable in cookiecutter dict with key_value',
],
)
def test_undefined_variable(context):
"""Verify `prompt.prompt_for_config` raises correct error."""
> with pytest.raises(exceptions.UndefinedVariableInTemplate) as err:
E Failed: DID NOT RAISE
tests/test_prompt.py:574: Failed
test_prompt.py::test_cookiecutter_nested_templates[fake-nested-templates-fake-project]
test_prompt.py::test_cookiecutter_nested_templates[fake-nested-templates-fake-project]
template_dir = 'fake-nested-templates'
expected = PosixPath('/testbed/tests/fake-nested-templates/fake-project')
@pytest.mark.parametrize(
"template_dir,expected",
[
["fake-nested-templates", "fake-project"],
["fake-nested-templates-old-style", "fake-package"],
],
)
def test_cookiecutter_nested_templates(template_dir: str, expected: str):
"""Test nested_templates generation."""
from cookiecutter import prompt
main_dir = (Path("tests") / template_dir).resolve()
cookiecuter_context = json.loads((main_dir / "cookiecutter.json").read_text())
context = {"cookiecutter": cookiecuter_context}
output_dir = prompt.choose_nested_template(context, main_dir, no_input=True)
expected = (Path(main_dir) / expected).resolve()
> assert output_dir == f"{expected}"
E AssertionError: assert None == '/testbed/tests/fake-nested-templates/fake-project'
tests/test_prompt.py:598: AssertionError
test_prompt.py::test_cookiecutter_nested_templates[fake-nested-templates-old-style-fake-package]
test_prompt.py::test_cookiecutter_nested_templates[fake-nested-templates-old-style-fake-package]
template_dir = 'fake-nested-templates-old-style'
expected = PosixPath('/testbed/tests/fake-nested-templates-old-style/fake-package')
@pytest.mark.parametrize(
"template_dir,expected",
[
["fake-nested-templates", "fake-project"],
["fake-nested-templates-old-style", "fake-package"],
],
)
def test_cookiecutter_nested_templates(template_dir: str, expected: str):
"""Test nested_templates generation."""
from cookiecutter import prompt
main_dir = (Path("tests") / template_dir).resolve()
cookiecuter_context = json.loads((main_dir / "cookiecutter.json").read_text())
context = {"cookiecutter": cookiecuter_context}
output_dir = prompt.choose_nested_template(context, main_dir, no_input=True)
expected = (Path(main_dir) / expected).resolve()
> assert output_dir == f"{expected}"
E AssertionError: assert None == '/testbed/tests/fake-nested-templates-old-style/fake-package'
tests/test_prompt.py:598: AssertionError
test_prompt.py::test_cookiecutter_nested_templates_invalid_paths[]
test_prompt.py::test_cookiecutter_nested_templates_invalid_paths[]
path = ''
@pytest.mark.skipif(sys.platform.startswith('win'), reason="Linux / macos test")
@pytest.mark.parametrize(
"path",
[
"",
"/tmp",
"/foo",
],
)
def test_cookiecutter_nested_templates_invalid_paths(path: str):
"""Test nested_templates generation."""
from cookiecutter import prompt
main_dir = (Path("tests") / "fake-nested-templates").resolve()
cookiecuter_context = json.loads((main_dir / "cookiecutter.json").read_text())
cookiecuter_context["templates"]["fake-project"]["path"] = path
context = {"cookiecutter": cookiecuter_context}
> with pytest.raises(ValueError) as exc:
E Failed: DID NOT RAISE
tests/test_prompt.py:618: Failed
tmp]
tmp]
path = '/tmp'
@pytest.mark.skipif(sys.platform.startswith('win'), reason="Linux / macos test")
@pytest.mark.parametrize(
"path",
[
"",
"/tmp",
"/foo",
],
)
def test_cookiecutter_nested_templates_invalid_paths(path: str):
"""Test nested_templates generation."""
from cookiecutter import prompt
main_dir = (Path("tests") / "fake-nested-templates").resolve()
cookiecuter_context = json.loads((main_dir / "cookiecutter.json").read_text())
cookiecuter_context["templates"]["fake-project"]["path"] = path
context = {"cookiecutter": cookiecuter_context}
> with pytest.raises(ValueError) as exc:
E Failed: DID NOT RAISE
tests/test_prompt.py:618: Failed
foo]
foo]
path = '/foo'
@pytest.mark.skipif(sys.platform.startswith('win'), reason="Linux / macos test")
@pytest.mark.parametrize(
"path",
[
"",
"/tmp",
"/foo",
],
)
def test_cookiecutter_nested_templates_invalid_paths(path: str):
"""Test nested_templates generation."""
from cookiecutter import prompt
main_dir = (Path("tests") / "fake-nested-templates").resolve()
cookiecuter_context = json.loads((main_dir / "cookiecutter.json").read_text())
cookiecuter_context["templates"]["fake-project"]["path"] = path
context = {"cookiecutter": cookiecuter_context}
> with pytest.raises(ValueError) as exc:
E Failed: DID NOT RAISE
tests/test_prompt.py:618: Failed
test_prompt.py::test_prompt_should_ask_and_rm_repo_dir
test_prompt.py::test_prompt_should_ask_and_rm_repo_dir
mocker =
tmp_path = PosixPath('/tmp/pytest-of-root/pytest-0/test_prompt_should_ask_and_rm_0')
def test_prompt_should_ask_and_rm_repo_dir(mocker, tmp_path):
"""In `prompt_and_delete()`, if the user agrees to delete/reclone the \
repo, the repo should be deleted."""
mock_read_user = mocker.patch(
'cookiecutter.prompt.read_user_yes_no', return_value=True
)
repo_dir = Path(tmp_path, 'repo')
repo_dir.mkdir()
deleted = prompt.prompt_and_delete(str(repo_dir))
> assert mock_read_user.called
E AssertionError: assert False
E + where False = .called
tests/test_prompt.py:656: AssertionError
test_prompt.py::test_prompt_should_ask_and_exit_on_user_no_answer
test_prompt.py::test_prompt_should_ask_and_exit_on_user_no_answer
mocker =
tmp_path = PosixPath('/tmp/pytest-of-root/pytest-0/test_prompt_should_ask_and_exi0')
def test_prompt_should_ask_and_exit_on_user_no_answer(mocker, tmp_path):
"""In `prompt_and_delete()`, if the user decline to delete/reclone the \
repo, cookiecutter should exit."""
mock_read_user = mocker.patch(
'cookiecutter.prompt.read_user_yes_no',
return_value=False,
)
mock_sys_exit = mocker.patch('sys.exit', return_value=True)
repo_dir = Path(tmp_path, 'repo')
repo_dir.mkdir()
deleted = prompt.prompt_and_delete(str(repo_dir))
> assert mock_read_user.called
E AssertionError: assert False
E + where False = .called
tests/test_prompt.py:674: AssertionError
test_prompt.py::test_prompt_should_ask_and_rm_repo_file
test_prompt.py::test_prompt_should_ask_and_rm_repo_file
mocker =
tmp_path = PosixPath('/tmp/pytest-of-root/pytest-0/test_prompt_should_ask_and_rm_1')
def test_prompt_should_ask_and_rm_repo_file(mocker, tmp_path):
"""In `prompt_and_delete()`, if the user agrees to delete/reclone a \
repo file, the repo should be deleted."""
mock_read_user = mocker.patch(
'cookiecutter.prompt.read_user_yes_no', return_value=True, autospec=True
)
repo_file = tmp_path.joinpath('repo.zip')
repo_file.write_text('this is zipfile content')
deleted = prompt.prompt_and_delete(str(repo_file))
> assert mock_read_user.called
E assert False
E + where False = .called
tests/test_prompt.py:692: AssertionError
test_prompt.py::test_prompt_should_ask_and_keep_repo_on_no_reuse
test_prompt.py::test_prompt_should_ask_and_keep_repo_on_no_reuse
mocker =
tmp_path = PosixPath('/tmp/pytest-of-root/pytest-0/test_prompt_should_ask_and_kee0')
def test_prompt_should_ask_and_keep_repo_on_no_reuse(mocker, tmp_path):
"""In `prompt_and_delete()`, if the user wants to keep their old \
cloned template repo, it should not be deleted."""
mock_read_user = mocker.patch(
'cookiecutter.prompt.read_user_yes_no', return_value=False, autospec=True
)
repo_dir = Path(tmp_path, 'repo')
repo_dir.mkdir()
> with pytest.raises(SystemExit):
E Failed: DID NOT RAISE
tests/test_prompt.py:706: Failed
test_prompt.py::test_prompt_should_ask_and_keep_repo_on_reuse
test_prompt.py::test_prompt_should_ask_and_keep_repo_on_reuse
mocker =
tmp_path = PosixPath('/tmp/pytest-of-root/pytest-0/test_prompt_should_ask_and_kee1')
def test_prompt_should_ask_and_keep_repo_on_reuse(mocker, tmp_path):
"""In `prompt_and_delete()`, if the user wants to keep their old \
cloned template repo, it should not be deleted."""
def answer(question, default):
return 'okay to delete' not in question
mock_read_user = mocker.patch(
'cookiecutter.prompt.read_user_yes_no', side_effect=answer, autospec=True
)
repo_dir = Path(tmp_path, 'repo')
repo_dir.mkdir()
deleted = prompt.prompt_and_delete(str(repo_dir))
> assert mock_read_user.called
E assert False
E + where False = .called
tests/test_prompt.py:728: AssertionError
test_prompt.py::test_prompt_should_not_ask_if_no_input_and_rm_repo_dir
mocker =
tmp_path = PosixPath('/tmp/pytest-of-root/pytest-0/test_prompt_should_not_ask_if_0')
def test_prompt_should_not_ask_if_no_input_and_rm_repo_dir(mocker, tmp_path):
"""Prompt should not ask if no input and rm dir.
In `prompt_and_delete()`, if `no_input` is True, the call to
`prompt.read_user_yes_no()` should be suppressed.
"""
mock_read_user = mocker.patch(
'cookiecutter.prompt.read_user_yes_no', return_value=True, autospec=True
)
repo_dir = Path(tmp_path, 'repo')
repo_dir.mkdir()
deleted = prompt.prompt_and_delete(str(repo_dir), no_input=True)
assert not mock_read_user.called
> assert not repo_dir.exists()
E AssertionError: assert not True
E + where True = exists()
E + where exists = PosixPath('/tmp/pytest-of-root/pytest-0/test_prompt_should_not_ask_if_0/repo').exists
tests/test_prompt.py:748: AssertionError
test_prompt.py::test_prompt_should_not_ask_if_no_input_and_rm_repo_file
mocker =
tmp_path = PosixPath('/tmp/pytest-of-root/pytest-0/test_prompt_should_not_ask_if_1')
def test_prompt_should_not_ask_if_no_input_and_rm_repo_file(mocker, tmp_path):
"""Prompt should not ask if no input and rm file.
In `prompt_and_delete()`, if `no_input` is True, the call to
`prompt.read_user_yes_no()` should be suppressed.
"""
mock_read_user = mocker.patch(
'cookiecutter.prompt.read_user_yes_no', return_value=True, autospec=True
)
repo_file = tmp_path.joinpath('repo.zip')
repo_file.write_text('this is zipfile content')
deleted = prompt.prompt_and_delete(str(repo_file), no_input=True)
assert not mock_read_user.called
> assert not repo_file.exists()
E AssertionError: assert not True
E + where True = exists()
E + where exists = PosixPath('/tmp/pytest-of-root/pytest-0/test_prompt_should_not_ask_if_1/repo.zip').exists
tests/test_prompt.py:768: AssertionError
test_read_repo_password.py::test_click_invocation
test_read_repo_password.py::test_click_invocation
mocker =
def test_click_invocation(mocker):
"""Test click function called correctly by cookiecutter.
Test for password (hidden input) type invocation.
"""
prompt = mocker.patch('rich.prompt.Prompt.ask')
prompt.return_value = 'sekrit'
> assert read_repo_password('Password') == 'sekrit'
E AssertionError: assert None == 'sekrit'
E + where None = read_repo_password('Password')
tests/test_read_repo_password.py:14: AssertionError
test_read_user_choice.py::test_click_invocation[1-hello]
test_read_user_choice.py::test_click_invocation[1-hello]
mocker =
user_choice = 1, expected_value = 'hello'
@pytest.mark.parametrize('user_choice, expected_value', enumerate(OPTIONS, 1))
def test_click_invocation(mocker, user_choice, expected_value):
"""Test click function called correctly by cookiecutter.
Test for choice type invocation.
"""
prompt = mocker.patch('rich.prompt.Prompt.ask')
prompt.return_value = f'{user_choice}'
> assert read_user_choice('varname', OPTIONS) == expected_value
E AssertionError: assert None == 'hello'
E + where None = read_user_choice('varname', ['hello', 'world', 'foo', 'bar'])
tests/test_read_user_choice.py:27: AssertionError
test_read_user_choice.py::test_click_invocation[2-world]
test_read_user_choice.py::test_click_invocation[2-world]
mocker =
user_choice = 2, expected_value = 'world'
@pytest.mark.parametrize('user_choice, expected_value', enumerate(OPTIONS, 1))
def test_click_invocation(mocker, user_choice, expected_value):
"""Test click function called correctly by cookiecutter.
Test for choice type invocation.
"""
prompt = mocker.patch('rich.prompt.Prompt.ask')
prompt.return_value = f'{user_choice}'
> assert read_user_choice('varname', OPTIONS) == expected_value
E AssertionError: assert None == 'world'
E + where None = read_user_choice('varname', ['hello', 'world', 'foo', 'bar'])
tests/test_read_user_choice.py:27: AssertionError
test_read_user_choice.py::test_click_invocation[3-foo]
test_read_user_choice.py::test_click_invocation[3-foo]
mocker =
user_choice = 3, expected_value = 'foo'
@pytest.mark.parametrize('user_choice, expected_value', enumerate(OPTIONS, 1))
def test_click_invocation(mocker, user_choice, expected_value):
"""Test click function called correctly by cookiecutter.
Test for choice type invocation.
"""
prompt = mocker.patch('rich.prompt.Prompt.ask')
prompt.return_value = f'{user_choice}'
> assert read_user_choice('varname', OPTIONS) == expected_value
E AssertionError: assert None == 'foo'
E + where None = read_user_choice('varname', ['hello', 'world', 'foo', 'bar'])
tests/test_read_user_choice.py:27: AssertionError
test_read_user_choice.py::test_click_invocation[4-bar]
test_read_user_choice.py::test_click_invocation[4-bar]
mocker =
user_choice = 4, expected_value = 'bar'
@pytest.mark.parametrize('user_choice, expected_value', enumerate(OPTIONS, 1))
def test_click_invocation(mocker, user_choice, expected_value):
"""Test click function called correctly by cookiecutter.
Test for choice type invocation.
"""
prompt = mocker.patch('rich.prompt.Prompt.ask')
prompt.return_value = f'{user_choice}'
> assert read_user_choice('varname', OPTIONS) == expected_value
E AssertionError: assert None == 'bar'
E + where None = read_user_choice('varname', ['hello', 'world', 'foo', 'bar'])
tests/test_read_user_choice.py:27: AssertionError
test_read_user_choice.py::test_raise_if_options_is_not_a_non_empty_list
test_read_user_choice.py::test_raise_if_options_is_not_a_non_empty_list
def test_raise_if_options_is_not_a_non_empty_list():
"""Test function called by cookiecutter raise expected errors.
Test for choice type invocation.
"""
> with pytest.raises(TypeError):
E Failed: DID NOT RAISE
tests/test_read_user_choice.py:37: Failed
test_read_user_dict.py::test_process_json_invalid_json
test_read_user_dict.py::test_process_json_invalid_json
def test_process_json_invalid_json():
"""Test `process_json` for correct error on malformed input."""
> with pytest.raises(InvalidResponse) as exc_info:
E Failed: DID NOT RAISE
tests/test_read_user_dict.py:12: Failed
test_read_user_dict.py::test_process_json_non_dict
test_read_user_dict.py::test_process_json_non_dict
def test_process_json_non_dict():
"""Test `process_json` for correct error on non-JSON input."""
> with pytest.raises(InvalidResponse) as exc_info:
E Failed: DID NOT RAISE
tests/test_read_user_dict.py:20: Failed
test_read_user_dict.py::test_process_json_valid_json
test_read_user_dict.py::test_process_json_valid_json
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],
}
E assert None == {'bla': ['a', 1, 'b', False], 'name': 'foobar'}
E + where None = process_json('{"name": "foobar", "bla": ["a", 1, "b", false]}')
tests/test_read_user_dict.py:33: AssertionError
test_read_user_dict.py::test_process_json_deep_dict
test_read_user_dict.py::test_process_json_deep_dict
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"],
}
E assert None == {'dict_key': {'deep_integer': 42, 'deep_key': 'deep_value', 'deep_list': ['deep value 1', 'deep value 2', 'deep value 3']}, 'integer_key': 37, 'key': 'value', 'list_key': ['value 1', 'value 2', 'value 3']}
E + where None = process_json('{\n "key": "value",\n "integer_key": 37,\n "dict_key": {\n "deep_key": "deep_value",\n "deep_integer": 42,\n "deep_list": [\n "deep value 1",\n "deep value 2",\n "deep value 3"\n ]\n },\n "list_key": [\n "value 1",\n "value 2",\n "value 3"\n ]\n }')
tests/test_read_user_dict.py:63: AssertionError
test_read_user_dict.py::test_should_raise_type_error
test_read_user_dict.py::test_should_raise_type_error
mocker =
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):
E Failed: DID NOT RAISE
tests/test_read_user_dict.py:79: Failed
test_read_user_dict.py::test_should_call_prompt_with_process_json
test_read_user_dict.py::test_should_call_prompt_with_process_json
mocker =
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
E TypeError: cannot unpack non-iterable NoneType object
tests/test_read_user_dict.py:93: TypeError
test_read_user_dict.py::test_read_user_dict_default_value[\n]
test_read_user_dict.py::test_read_user_dict_default_value[\n]
mocker =
input = '\n'
@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'}
E AssertionError: assert None == {'project_slug': 'pytest-plugin'}
tests/test_read_user_dict.py:122: AssertionError
test_read_user_dict.py::test_read_user_dict_default_value[\ndefault\n]
test_read_user_dict.py::test_read_user_dict_default_value[\ndefault\n]
mocker =
input = '\ndefault\n'
@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'}
E AssertionError: assert None == {'project_slug': 'pytest-plugin'}
tests/test_read_user_dict.py:122: AssertionError
test_read_user_dict.py::test_json_prompt_process_response
test_read_user_dict.py::test_json_prompt_process_response
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'
}
E assert None == {'project_slug': 'something'}
E + where None = process_response('{"project_slug": "something"}')
E + where process_response = .process_response
tests/test_read_user_dict.py:128: AssertionError
test_read_user_variable.py::test_click_invocation
test_read_user_variable.py::test_click_invocation
mock_prompt =
def test_click_invocation(mock_prompt):
"""Test click function called correctly by cookiecutter.
Test for string type invocation.
"""
mock_prompt.return_value = DEFAULT
> assert read_user_variable(VARIABLE, DEFAULT) == DEFAULT
E AssertionError: assert None == 'Kivy Project'
E + where None = read_user_variable('project_name', 'Kivy Project')
tests/test_read_user_variable.py:24: AssertionError
test_read_user_variable.py::test_input_loop_with_null_default_value
mock_prompt =
def test_input_loop_with_null_default_value(mock_prompt):
"""Test `Prompt.ask` is run repeatedly until a valid answer is provided.
Test for `default_value` parameter equal to None.
"""
# Simulate user providing None input initially and then a valid input
mock_prompt.side_effect = [None, DEFAULT]
> assert read_user_variable(VARIABLE, None) == DEFAULT
E AssertionError: assert None == 'Kivy Project'
E + where None = read_user_variable('project_name', None)
tests/test_read_user_variable.py:37: AssertionError
test_read_user_yes_no.py::test_click_invocation
test_read_user_yes_no.py::test_click_invocation
mocker =
def test_click_invocation(mocker):
"""Test click function called correctly by cookiecutter.
Test for boolean type invocation.
"""
prompt = mocker.patch('cookiecutter.prompt.YesNoPrompt.ask')
prompt.return_value = DEFAULT
> assert read_user_yes_no(QUESTION, DEFAULT) == DEFAULT
E AssertionError: assert None == 'y'
E + where None = read_user_yes_no('Is it okay to delete and re-clone it?', 'y')
tests/test_read_user_yes_no.py:20: AssertionError
test_read_user_yes_no.py::test_yesno_prompt_process_response
test_read_user_yes_no.py::test_yesno_prompt_process_response
def test_yesno_prompt_process_response():
"""Test `YesNoPrompt` process_response to convert str to bool."""
ynp = YesNoPrompt()
> with pytest.raises(InvalidResponse):
E Failed: DID NOT RAISE
tests/test_read_user_yes_no.py:28: Failed
test_repo_not_found.py::test_should_raise_error_if_repo_does_not_exist
test_repo_not_found.py::test_should_raise_error_if_repo_does_not_exist
def test_should_raise_error_if_repo_does_not_exist():
"""Cookiecutter invocation with non-exist repository should raise error."""
> with pytest.raises(exceptions.RepositoryNotFound):
E Failed: DID NOT RAISE
tests/test_repo_not_found.py:10: Failed
test_specify_output_dir.py::test_api_invocation
test_specify_output_dir.py::test_api_invocation
self = , args = ()
kwargs = {'accept_hooks': True, 'context': {'cookiecutter': {'email': 'raphael@hackebrot.de', 'full_name': 'Raphael Pierzina', 'github_username': 'hackebrot', 'version': '0.1.0'}}, 'keep_project_on_failure': False, 'output_dir': '/tmp/pytest-of-root/pytest-0/test_api_invocation0/output', ...}
msg = "Expected 'generate_files' to be called once. Called 0 times."
def assert_called_once_with(self, /, *args, **kwargs):
"""assert that the mock was called exactly once and that that call was
with the specified arguments."""
if not self.call_count == 1:
msg = ("Expected '%s' to be called once. Called %s times.%s"
% (self._mock_name or 'mock',
self.call_count,
self._calls_repr()))
> raise AssertionError(msg)
E AssertionError: Expected 'generate_files' to be called once. Called 0 times.
/usr/lib/python3.10/unittest/mock.py:940: AssertionError
During handling of the above exception, another exception occurred:
mocker =
template = '/tmp/pytest-of-root/pytest-0/test_api_invocation0/template'
output_dir = '/tmp/pytest-of-root/pytest-0/test_api_invocation0/output'
context = {'cookiecutter': {'email': 'raphael@hackebrot.de', 'full_name': 'Raphael Pierzina', 'github_username': 'hackebrot', 'version': '0.1.0'}}
def test_api_invocation(mocker, template, output_dir, context):
"""Verify output dir location is correctly passed."""
mock_gen_files = mocker.patch('cookiecutter.main.generate_files')
main.cookiecutter(template, output_dir=output_dir)
> mock_gen_files.assert_called_once_with(
repo_dir=template,
context=context,
overwrite_if_exists=False,
skip_if_file_exists=False,
output_dir=output_dir,
accept_hooks=True,
keep_project_on_failure=False,
)
E AssertionError: Expected 'generate_files' to be called once. Called 0 times.
tests/test_specify_output_dir.py:54: AssertionError
test_specify_output_dir.py::test_default_output_dir
test_specify_output_dir.py::test_default_output_dir
self = , args = ()
kwargs = {'accept_hooks': True, 'context': {'cookiecutter': {'email': 'raphael@hackebrot.de', 'full_name': 'Raphael Pierzina', 'github_username': 'hackebrot', 'version': '0.1.0'}}, 'keep_project_on_failure': False, 'output_dir': '.', ...}
msg = "Expected 'generate_files' to be called once. Called 0 times."
def assert_called_once_with(self, /, *args, **kwargs):
"""assert that the mock was called exactly once and that that call was
with the specified arguments."""
if not self.call_count == 1:
msg = ("Expected '%s' to be called once. Called %s times.%s"
% (self._mock_name or 'mock',
self.call_count,
self._calls_repr()))
> raise AssertionError(msg)
E AssertionError: Expected 'generate_files' to be called once. Called 0 times.
/usr/lib/python3.10/unittest/mock.py:940: AssertionError
During handling of the above exception, another exception occurred:
mocker =
template = '/tmp/pytest-of-root/pytest-0/test_default_output_dir0/template'
context = {'cookiecutter': {'email': 'raphael@hackebrot.de', 'full_name': 'Raphael Pierzina', 'github_username': 'hackebrot', 'version': '0.1.0'}}
def test_default_output_dir(mocker, template, context):
"""Verify default output dir is current working folder."""
mock_gen_files = mocker.patch('cookiecutter.main.generate_files')
main.cookiecutter(template)
> mock_gen_files.assert_called_once_with(
repo_dir=template,
context=context,
overwrite_if_exists=False,
skip_if_file_exists=False,
output_dir='.',
accept_hooks=True,
keep_project_on_failure=False,
)
E AssertionError: Expected 'generate_files' to be called once. Called 0 times.
tests/test_specify_output_dir.py:71: AssertionError
test_templates.py::test_build_templates[include]
test_templates.py::test_build_templates[include]
template = 'include'
output_dir = '/tmp/pytest-of-root/pytest-0/test_build_templates_include_0/templates'
@pytest.mark.parametrize("template", ["include", "no-templates", "extends", "super"])
def test_build_templates(template, output_dir):
"""
Verify Templates Design keywords.
no-templates is a compatibility tests for repo without `templates` directory
"""
project_dir = main.cookiecutter(
f'tests/test-templates/{template}',
no_input=True,
output_dir=output_dir,
)
> readme = Path(project_dir, 'requirements.txt').read_text()
tests/test_templates.py:34:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/lib/python3.10/pathlib.py:960: in __new__
self = cls._from_parts(args)
/usr/lib/python3.10/pathlib.py:594: in _from_parts
drv, root, parts = self._parse_args(args)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
cls = , args = (None, 'requirements.txt')
@classmethod
def _parse_args(cls, args):
# This is useful when you don't want to create an instance, just
# canonicalize some constructor arguments.
parts = []
for a in args:
if isinstance(a, PurePath):
parts += a._parts
else:
> a = os.fspath(a)
E TypeError: expected str, bytes or os.PathLike object, not NoneType
/usr/lib/python3.10/pathlib.py:578: TypeError
test_templates.py::test_build_templates[no-templates]
test_templates.py::test_build_templates[no-templates]
template = 'no-templates'
output_dir = '/tmp/pytest-of-root/pytest-0/test_build_templates_no_templa0/templates'
@pytest.mark.parametrize("template", ["include", "no-templates", "extends", "super"])
def test_build_templates(template, output_dir):
"""
Verify Templates Design keywords.
no-templates is a compatibility tests for repo without `templates` directory
"""
project_dir = main.cookiecutter(
f'tests/test-templates/{template}',
no_input=True,
output_dir=output_dir,
)
> readme = Path(project_dir, 'requirements.txt').read_text()
tests/test_templates.py:34:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/lib/python3.10/pathlib.py:960: in __new__
self = cls._from_parts(args)
/usr/lib/python3.10/pathlib.py:594: in _from_parts
drv, root, parts = self._parse_args(args)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
cls = , args = (None, 'requirements.txt')
@classmethod
def _parse_args(cls, args):
# This is useful when you don't want to create an instance, just
# canonicalize some constructor arguments.
parts = []
for a in args:
if isinstance(a, PurePath):
parts += a._parts
else:
> a = os.fspath(a)
E TypeError: expected str, bytes or os.PathLike object, not NoneType
/usr/lib/python3.10/pathlib.py:578: TypeError
test_templates.py::test_build_templates[extends]
test_templates.py::test_build_templates[extends]
template = 'extends'
output_dir = '/tmp/pytest-of-root/pytest-0/test_build_templates_extends_0/templates'
@pytest.mark.parametrize("template", ["include", "no-templates", "extends", "super"])
def test_build_templates(template, output_dir):
"""
Verify Templates Design keywords.
no-templates is a compatibility tests for repo without `templates` directory
"""
project_dir = main.cookiecutter(
f'tests/test-templates/{template}',
no_input=True,
output_dir=output_dir,
)
> readme = Path(project_dir, 'requirements.txt').read_text()
tests/test_templates.py:34:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/lib/python3.10/pathlib.py:960: in __new__
self = cls._from_parts(args)
/usr/lib/python3.10/pathlib.py:594: in _from_parts
drv, root, parts = self._parse_args(args)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
cls = , args = (None, 'requirements.txt')
@classmethod
def _parse_args(cls, args):
# This is useful when you don't want to create an instance, just
# canonicalize some constructor arguments.
parts = []
for a in args:
if isinstance(a, PurePath):
parts += a._parts
else:
> a = os.fspath(a)
E TypeError: expected str, bytes or os.PathLike object, not NoneType
/usr/lib/python3.10/pathlib.py:578: TypeError
test_templates.py::test_build_templates[super]
test_templates.py::test_build_templates[super]
template = 'super'
output_dir = '/tmp/pytest-of-root/pytest-0/test_build_templates_super_0/templates'
@pytest.mark.parametrize("template", ["include", "no-templates", "extends", "super"])
def test_build_templates(template, output_dir):
"""
Verify Templates Design keywords.
no-templates is a compatibility tests for repo without `templates` directory
"""
project_dir = main.cookiecutter(
f'tests/test-templates/{template}',
no_input=True,
output_dir=output_dir,
)
> readme = Path(project_dir, 'requirements.txt').read_text()
tests/test_templates.py:34:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/lib/python3.10/pathlib.py:960: in __new__
self = cls._from_parts(args)
/usr/lib/python3.10/pathlib.py:594: in _from_parts
drv, root, parts = self._parse_args(args)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
cls = , args = (None, 'requirements.txt')
@classmethod
def _parse_args(cls, args):
# This is useful when you don't want to create an instance, just
# canonicalize some constructor arguments.
parts = []
for a in args:
if isinstance(a, PurePath):
parts += a._parts
else:
> a = os.fspath(a)
E TypeError: expected str, bytes or os.PathLike object, not NoneType
/usr/lib/python3.10/pathlib.py:578: TypeError
test_time_extension.py::test_utc_default_datetime_format
environment =
def test_utc_default_datetime_format(environment):
"""Verify default datetime format can be parsed."""
> template = environment.from_string("{% now 'utc' %}")
tests/test_time_extension.py:31:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
.venv/lib/python3.10/site-packages/jinja2/environment.py:1108: in from_string
return cls.from_code(self, self.compile(source), gs, None)
.venv/lib/python3.10/site-packages/jinja2/environment.py:768: in compile
self.handle_exception(source=source_hint)
.venv/lib/python3.10/site-packages/jinja2/environment.py:939: in handle_exception
raise rewrite_traceback_stack(source=source)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
> ???
E jinja2.exceptions.TemplateSyntaxError: expected token 'end of statement block', got 'now'
:1: TemplateSyntaxError
test_time_extension.py::test_accept_valid_timezones[utc]
test_time_extension.py::test_accept_valid_timezones[utc]
environment =
valid_tz = 'utc'
@pytest.mark.parametrize("valid_tz", ['utc', 'local', 'Europe/Berlin'])
def test_accept_valid_timezones(environment, valid_tz):
"""Verify that valid timezones are accepted."""
> template = environment.from_string(f"{{% now '{valid_tz}', '%Y-%m' %}}")
tests/test_time_extension.py:39:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
.venv/lib/python3.10/site-packages/jinja2/environment.py:1108: in from_string
return cls.from_code(self, self.compile(source), gs, None)
.venv/lib/python3.10/site-packages/jinja2/environment.py:768: in compile
self.handle_exception(source=source_hint)
.venv/lib/python3.10/site-packages/jinja2/environment.py:939: in handle_exception
raise rewrite_traceback_stack(source=source)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
> ???
E jinja2.exceptions.TemplateSyntaxError: expected token 'end of statement block', got 'now'
:1: TemplateSyntaxError
test_time_extension.py::test_accept_valid_timezones[local]
test_time_extension.py::test_accept_valid_timezones[local]
environment =
valid_tz = 'local'
@pytest.mark.parametrize("valid_tz", ['utc', 'local', 'Europe/Berlin'])
def test_accept_valid_timezones(environment, valid_tz):
"""Verify that valid timezones are accepted."""
> template = environment.from_string(f"{{% now '{valid_tz}', '%Y-%m' %}}")
tests/test_time_extension.py:39:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
.venv/lib/python3.10/site-packages/jinja2/environment.py:1108: in from_string
return cls.from_code(self, self.compile(source), gs, None)
.venv/lib/python3.10/site-packages/jinja2/environment.py:768: in compile
self.handle_exception(source=source_hint)
.venv/lib/python3.10/site-packages/jinja2/environment.py:939: in handle_exception
raise rewrite_traceback_stack(source=source)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
> ???
E jinja2.exceptions.TemplateSyntaxError: expected token 'end of statement block', got 'now'
:1: TemplateSyntaxError
Berlin]
Berlin]
environment =
valid_tz = 'Europe/Berlin'
@pytest.mark.parametrize("valid_tz", ['utc', 'local', 'Europe/Berlin'])
def test_accept_valid_timezones(environment, valid_tz):
"""Verify that valid timezones are accepted."""
> template = environment.from_string(f"{{% now '{valid_tz}', '%Y-%m' %}}")
tests/test_time_extension.py:39:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
.venv/lib/python3.10/site-packages/jinja2/environment.py:1108: in from_string
return cls.from_code(self, self.compile(source), gs, None)
.venv/lib/python3.10/site-packages/jinja2/environment.py:768: in compile
self.handle_exception(source=source_hint)
.venv/lib/python3.10/site-packages/jinja2/environment.py:939: in handle_exception
raise rewrite_traceback_stack(source=source)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
> ???
E jinja2.exceptions.TemplateSyntaxError: expected token 'end of statement block', got 'now'
:1: TemplateSyntaxError
test_time_extension.py::test_environment_datetime_format
environment =
def test_environment_datetime_format(environment):
"""Verify datetime format can be parsed from environment."""
environment.datetime_format = '%a, %d %b %Y %H:%M:%S'
> template = environment.from_string("{% now 'utc' %}")
tests/test_time_extension.py:48:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
.venv/lib/python3.10/site-packages/jinja2/environment.py:1108: in from_string
return cls.from_code(self, self.compile(source), gs, None)
.venv/lib/python3.10/site-packages/jinja2/environment.py:768: in compile
self.handle_exception(source=source_hint)
.venv/lib/python3.10/site-packages/jinja2/environment.py:939: in handle_exception
raise rewrite_traceback_stack(source=source)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
> ???
E jinja2.exceptions.TemplateSyntaxError: expected token 'end of statement block', got 'now'
:1: TemplateSyntaxError
test_time_extension.py::test_add_time
test_time_extension.py::test_add_time
environment =
def test_add_time(environment):
"""Verify that added time offset can be parsed."""
environment.datetime_format = '%a, %d %b %Y %H:%M:%S'
> template = environment.from_string("{% now 'utc' + 'hours=2,seconds=30' %}")
tests/test_time_extension.py:57:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
.venv/lib/python3.10/site-packages/jinja2/environment.py:1108: in from_string
return cls.from_code(self, self.compile(source), gs, None)
.venv/lib/python3.10/site-packages/jinja2/environment.py:768: in compile
self.handle_exception(source=source_hint)
.venv/lib/python3.10/site-packages/jinja2/environment.py:939: in handle_exception
raise rewrite_traceback_stack(source=source)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
> ???
E jinja2.exceptions.TemplateSyntaxError: expected token 'end of statement block', got 'now'
:1: TemplateSyntaxError
test_time_extension.py::test_substract_time
test_time_extension.py::test_substract_time
environment =
def test_substract_time(environment):
"""Verify that substracted time offset can be parsed."""
environment.datetime_format = '%a, %d %b %Y %H:%M:%S'
> template = environment.from_string("{% now 'utc' - 'minutes=11' %}")
tests/test_time_extension.py:66:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
.venv/lib/python3.10/site-packages/jinja2/environment.py:1108: in from_string
return cls.from_code(self, self.compile(source), gs, None)
.venv/lib/python3.10/site-packages/jinja2/environment.py:768: in compile
self.handle_exception(source=source_hint)
.venv/lib/python3.10/site-packages/jinja2/environment.py:939: in handle_exception
raise rewrite_traceback_stack(source=source)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
> ???
E jinja2.exceptions.TemplateSyntaxError: expected token 'end of statement block', got 'now'
:1: TemplateSyntaxError
test_time_extension.py::test_offset_with_format
environment =
def test_offset_with_format(environment):
"""Verify that offset works together with datetime format."""
environment.datetime_format = '%d %b %Y %H:%M:%S'
> template = environment.from_string(
"{% now 'utc' - 'days=2,minutes=33,seconds=1', '%d %b %Y %H:%M:%S' %}"
)
tests/test_time_extension.py:75:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
.venv/lib/python3.10/site-packages/jinja2/environment.py:1108: in from_string
return cls.from_code(self, self.compile(source), gs, None)
.venv/lib/python3.10/site-packages/jinja2/environment.py:768: in compile
self.handle_exception(source=source_hint)
.venv/lib/python3.10/site-packages/jinja2/environment.py:939: in handle_exception
raise rewrite_traceback_stack(source=source)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
> ???
E jinja2.exceptions.TemplateSyntaxError: expected token 'end of statement block', got 'now'
:1: TemplateSyntaxError
test_utils.py::test_force_delete
test_utils.py::test_force_delete
mocker =
tmp_path = PosixPath('/tmp/pytest-of-root/pytest-0/test_force_delete0')
def test_force_delete(mocker, tmp_path):
"""Verify `utils.force_delete` makes files writable."""
ro_file = Path(tmp_path, 'bar')
ro_file.write_text("Test data")
make_readonly(ro_file)
rmtree = mocker.Mock()
utils.force_delete(rmtree, ro_file, sys.exc_info())
> assert (ro_file.stat().st_mode & stat.S_IWRITE) == stat.S_IWRITE
E AssertionError: assert (33060 & 128) == 128
E + where 33060 = os.stat_result(st_mode=33060, st_ino=3758, st_dev=17, st_nlink=1, st_uid=0, st_gid=0, st_size=9, st_atime=1733112384, st_mtime=1733112384, st_ctime=1733112384).st_mode
E + where os.stat_result(st_mode=33060, st_ino=3758, st_dev=17, st_nlink=1, st_uid=0, st_gid=0, st_size=9, st_atime=1733112384, st_mtime=1733112384, st_ctime=1733112384) = stat()
E + where stat = PosixPath('/tmp/pytest-of-root/pytest-0/test_force_delete0/bar').stat
E + and 128 = stat.S_IWRITE
E + and 128 = stat.S_IWRITE
tests/test_utils.py:27: AssertionError
test_utils.py::test_rmtree
test_utils.py::test_rmtree
tmp_path = PosixPath('/tmp/pytest-of-root/pytest-0/test_rmtree0')
def test_rmtree(tmp_path):
"""Verify `utils.rmtree` remove files marked as read-only."""
file_path = Path(tmp_path, "bar")
file_path.write_text("Test data")
make_readonly(file_path)
utils.rmtree(tmp_path)
> assert not Path(tmp_path).exists()
E AssertionError: assert not True
E + where True = exists()
E + where exists = PosixPath('/tmp/pytest-of-root/pytest-0/test_rmtree0').exists
E + where PosixPath('/tmp/pytest-of-root/pytest-0/test_rmtree0') = Path(PosixPath('/tmp/pytest-of-root/pytest-0/test_rmtree0'))
tests/test_utils.py:41: AssertionError
test_utils.py::test_make_sure_path_exists
test_utils.py::test_make_sure_path_exists
tmp_path = PosixPath('/tmp/pytest-of-root/pytest-0/test_make_sure_path_exists0')
def test_make_sure_path_exists(tmp_path):
"""Verify correct True/False response from `utils.make_sure_path_exists`.
Should return True if directory exist or created.
Should return False if impossible to create directory (for example protected)
"""
existing_directory = tmp_path
directory_to_create = Path(tmp_path, "not_yet_created")
utils.make_sure_path_exists(existing_directory)
utils.make_sure_path_exists(directory_to_create)
# Ensure by base system methods.
assert existing_directory.is_dir()
assert existing_directory.exists()
> assert directory_to_create.is_dir()
E AssertionError: assert False
E + where False = is_dir()
E + where is_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_make_sure_path_exists0/not_yet_created').is_dir
tests/test_utils.py:59: AssertionError
test_utils.py::test_make_sure_path_exists_correctly_handle_os_error
test_utils.py::test_make_sure_path_exists_correctly_handle_os_error
mocker =
def test_make_sure_path_exists_correctly_handle_os_error(mocker):
"""Verify correct True/False response from `utils.make_sure_path_exists`.
Should return True if directory exist or created.
Should return False if impossible to create directory (for example protected)
"""
mocker.patch("pathlib.Path.mkdir", side_effect=OSError)
> with pytest.raises(OSError) as err:
E Failed: DID NOT RAISE
tests/test_utils.py:70: Failed
test_utils.py::test_work_in
test_utils.py::test_work_in
tmp_path = PosixPath('/tmp/pytest-of-root/pytest-0/test_work_in0')
def test_work_in(tmp_path):
"""Verify returning to original folder after `utils.work_in` use."""
cwd = Path.cwd()
ch_to = tmp_path
assert ch_to != Path.cwd()
# Under context manager we should work in tmp_path.
> with utils.work_in(ch_to):
tests/test_utils.py:83:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self =
def __enter__(self):
# do not keep args and kwds alive unnecessarily
# they are only needed for recreation, which is not possible anymore
del self.args, self.kwds, self.func
try:
> return next(self.gen)
E TypeError: 'NoneType' object is not an iterator
/usr/lib/python3.10/contextlib.py:135: TypeError
test_utils.py::test_work_in_without_path
test_utils.py::test_work_in_without_path
def test_work_in_without_path():
"""Folder is not changed if no path provided."""
cwd = Path.cwd()
> with utils.work_in():
tests/test_utils.py:94:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self =
def __enter__(self):
# do not keep args and kwds alive unnecessarily
# they are only needed for recreation, which is not possible anymore
del self.args, self.kwds, self.func
try:
> return next(self.gen)
E TypeError: 'NoneType' object is not an iterator
/usr/lib/python3.10/contextlib.py:135: TypeError
test_utils.py::test_create_tmp_repo_dir
test_utils.py::test_create_tmp_repo_dir
tmp_path = PosixPath('/tmp/pytest-of-root/pytest-0/test_create_tmp_repo_dir0')
def test_create_tmp_repo_dir(tmp_path):
"""Verify `utils.create_tmp_repo_dir` creates a copy."""
repo_dir = Path(tmp_path) / 'bar'
repo_dir.mkdir()
subdirs = ('foo', 'bar', 'foobar')
for name in subdirs:
(repo_dir / name).mkdir()
new_repo_dir = utils.create_tmp_repo_dir(repo_dir)
> assert new_repo_dir.exists()
E AttributeError: 'NoneType' object has no attribute 'exists'
tests/test_utils.py:110: AttributeError
test_clone.py::test_clone_should_raise_if_vcs_not_installed
test_clone.py::test_clone_should_raise_if_vcs_not_installed
mocker =
clone_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_clone_should_raise_if_vcs0/clone_dir')
def test_clone_should_raise_if_vcs_not_installed(mocker, clone_dir):
"""In `clone()`, a `VCSNotInstalled` exception should be raised if no VCS \
is installed."""
mocker.patch('cookiecutter.vcs.is_vcs_installed', autospec=True, return_value=False)
repo_url = 'https://github.com/pytest-dev/cookiecutter-pytest-plugin.git'
> with pytest.raises(exceptions.VCSNotInstalled):
E Failed: DID NOT RAISE
tests/vcs/test_clone.py:18: Failed
test_clone.py::test_clone_should_rstrip_trailing_slash_in_repo_url
test_clone.py::test_clone_should_rstrip_trailing_slash_in_repo_url
self =
args = (['git', 'clone', 'https://github.com/foo/bar'],)
kwargs = {'cwd': PosixPath('/tmp/pytest-of-root/pytest-0/test_clone_should_rstrip_trail0/clone_dir'), 'stderr': -2}
msg = "Expected 'check_output' to be called once. Called 0 times."
def assert_called_once_with(self, /, *args, **kwargs):
"""assert that the mock was called exactly once and that that call was
with the specified arguments."""
if not self.call_count == 1:
msg = ("Expected '%s' to be called once. Called %s times.%s"
% (self._mock_name or 'mock',
self.call_count,
self._calls_repr()))
> raise AssertionError(msg)
E AssertionError: Expected 'check_output' to be called once. Called 0 times.
/usr/lib/python3.10/unittest/mock.py:940: AssertionError
During handling of the above exception, another exception occurred:
mocker =
clone_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_clone_should_rstrip_trail0/clone_dir')
def test_clone_should_rstrip_trailing_slash_in_repo_url(mocker, clone_dir):
"""In `clone()`, repo URL's trailing slash should be stripped if one is \
present."""
mocker.patch('cookiecutter.vcs.is_vcs_installed', autospec=True, return_value=True)
mock_subprocess = mocker.patch(
'cookiecutter.vcs.subprocess.check_output',
autospec=True,
)
vcs.clone('https://github.com/foo/bar/', clone_to_dir=clone_dir, no_input=True)
> mock_subprocess.assert_called_once_with(
['git', 'clone', 'https://github.com/foo/bar'],
cwd=clone_dir,
stderr=subprocess.STDOUT,
)
tests/vcs/test_clone.py:34:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
args = (['git', 'clone', 'https://github.com/foo/bar'],)
kwargs = {'cwd': PosixPath('/tmp/pytest-of-root/pytest-0/test_clone_should_rstrip_trail0/clone_dir'), 'stderr': -2}
def assert_called_once_with(*args, **kwargs):
> return mock.assert_called_once_with(*args, **kwargs)
E AssertionError: Expected 'check_output' to be called once. Called 0 times.
/usr/lib/python3.10/unittest/mock.py:213: AssertionError
test_clone.py::test_clone_should_abort_if_user_does_not_want_to_reclone
test_clone.py::test_clone_should_abort_if_user_does_not_want_to_reclone
mocker =
clone_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_clone_should_abort_if_use0/clone_dir')
def test_clone_should_abort_if_user_does_not_want_to_reclone(mocker, clone_dir):
"""In `clone()`, if user doesn't want to reclone, Cookiecutter should exit \
without cloning anything."""
mocker.patch('cookiecutter.vcs.is_vcs_installed', autospec=True, return_value=True)
mocker.patch(
'cookiecutter.vcs.prompt_and_delete', side_effect=SystemExit, autospec=True
)
mock_subprocess = mocker.patch(
'cookiecutter.vcs.subprocess.check_output',
autospec=True,
)
# Create repo_dir to trigger prompt_and_delete
repo_dir = clone_dir.joinpath('cookiecutter-pytest-plugin')
repo_dir.mkdir()
repo_url = 'https://github.com/pytest-dev/cookiecutter-pytest-plugin.git'
> with pytest.raises(SystemExit):
E Failed: DID NOT RAISE
tests/vcs/test_clone.py:59: Failed
world.git-world]
world.git-world]
mocker =
clone_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_clone_should_invoke_vcs_c0/clone_dir')
repo_type = 'git', repo_url = 'https://github.com/hello/world.git'
repo_name = 'world'
@pytest.mark.parametrize(
'repo_type, repo_url, repo_name',
[
('git', 'https://github.com/hello/world.git', 'world'),
('hg', 'https://bitbucket.org/foo/bar', 'bar'),
('git', 'git@host:gitoliterepo', 'gitoliterepo'),
('git', 'git@gitlab.com:cookiecutter/cookiecutter.git', 'cookiecutter'),
('git', 'git@github.com:cookiecutter/cookiecutter.git', 'cookiecutter'),
],
)
def test_clone_should_invoke_vcs_command(
mocker, clone_dir, repo_type, repo_url, repo_name
):
"""When `clone()` is called with a git/hg repo, the corresponding VCS \
command should be run via `subprocess.check_output()`.
This should take place:
* In the correct dir
* With the correct args.
"""
mocker.patch('cookiecutter.vcs.is_vcs_installed', autospec=True, return_value=True)
mock_subprocess = mocker.patch(
'cookiecutter.vcs.subprocess.check_output',
autospec=True,
)
expected_repo_dir = os.path.normpath(os.path.join(clone_dir, repo_name))
branch = 'foobar'
repo_dir = vcs.clone(
repo_url, checkout=branch, clone_to_dir=clone_dir, no_input=True
)
> assert repo_dir == expected_repo_dir
E AssertionError: assert None == '/tmp/pytest-of-root/pytest-0/test_clone_should_invoke_vcs_c0/clone_dir/world'
tests/vcs/test_clone.py:121: AssertionError
bar-bar]
bar-bar]
mocker =
clone_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_clone_should_invoke_vcs_c1/clone_dir')
repo_type = 'hg', repo_url = 'https://bitbucket.org/foo/bar', repo_name = 'bar'
@pytest.mark.parametrize(
'repo_type, repo_url, repo_name',
[
('git', 'https://github.com/hello/world.git', 'world'),
('hg', 'https://bitbucket.org/foo/bar', 'bar'),
('git', 'git@host:gitoliterepo', 'gitoliterepo'),
('git', 'git@gitlab.com:cookiecutter/cookiecutter.git', 'cookiecutter'),
('git', 'git@github.com:cookiecutter/cookiecutter.git', 'cookiecutter'),
],
)
def test_clone_should_invoke_vcs_command(
mocker, clone_dir, repo_type, repo_url, repo_name
):
"""When `clone()` is called with a git/hg repo, the corresponding VCS \
command should be run via `subprocess.check_output()`.
This should take place:
* In the correct dir
* With the correct args.
"""
mocker.patch('cookiecutter.vcs.is_vcs_installed', autospec=True, return_value=True)
mock_subprocess = mocker.patch(
'cookiecutter.vcs.subprocess.check_output',
autospec=True,
)
expected_repo_dir = os.path.normpath(os.path.join(clone_dir, repo_name))
branch = 'foobar'
repo_dir = vcs.clone(
repo_url, checkout=branch, clone_to_dir=clone_dir, no_input=True
)
> assert repo_dir == expected_repo_dir
E AssertionError: assert None == '/tmp/pytest-of-root/pytest-0/test_clone_should_invoke_vcs_c1/clone_dir/bar'
tests/vcs/test_clone.py:121: AssertionError
test_clone.py::test_clone_should_invoke_vcs_command[git-git@host:gitoliterepo-gitoliterepo]
test_clone.py::test_clone_should_invoke_vcs_command[git-git@host:gitoliterepo-gitoliterepo]
mocker =
clone_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_clone_should_invoke_vcs_c2/clone_dir')
repo_type = 'git', repo_url = 'git@host:gitoliterepo'
repo_name = 'gitoliterepo'
@pytest.mark.parametrize(
'repo_type, repo_url, repo_name',
[
('git', 'https://github.com/hello/world.git', 'world'),
('hg', 'https://bitbucket.org/foo/bar', 'bar'),
('git', 'git@host:gitoliterepo', 'gitoliterepo'),
('git', 'git@gitlab.com:cookiecutter/cookiecutter.git', 'cookiecutter'),
('git', 'git@github.com:cookiecutter/cookiecutter.git', 'cookiecutter'),
],
)
def test_clone_should_invoke_vcs_command(
mocker, clone_dir, repo_type, repo_url, repo_name
):
"""When `clone()` is called with a git/hg repo, the corresponding VCS \
command should be run via `subprocess.check_output()`.
This should take place:
* In the correct dir
* With the correct args.
"""
mocker.patch('cookiecutter.vcs.is_vcs_installed', autospec=True, return_value=True)
mock_subprocess = mocker.patch(
'cookiecutter.vcs.subprocess.check_output',
autospec=True,
)
expected_repo_dir = os.path.normpath(os.path.join(clone_dir, repo_name))
branch = 'foobar'
repo_dir = vcs.clone(
repo_url, checkout=branch, clone_to_dir=clone_dir, no_input=True
)
> assert repo_dir == expected_repo_dir
E AssertionError: assert None == '/tmp/pytest-of-root/pytest-0/test_clone_should_invoke_vcs_c2/clone_dir/gitoliterepo'
tests/vcs/test_clone.py:121: AssertionError
cookiecutter.git-cookiecutter]
cookiecutter.git-cookiecutter]
mocker =
clone_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_clone_should_invoke_vcs_c3/clone_dir')
repo_type = 'git', repo_url = 'git@gitlab.com:cookiecutter/cookiecutter.git'
repo_name = 'cookiecutter'
@pytest.mark.parametrize(
'repo_type, repo_url, repo_name',
[
('git', 'https://github.com/hello/world.git', 'world'),
('hg', 'https://bitbucket.org/foo/bar', 'bar'),
('git', 'git@host:gitoliterepo', 'gitoliterepo'),
('git', 'git@gitlab.com:cookiecutter/cookiecutter.git', 'cookiecutter'),
('git', 'git@github.com:cookiecutter/cookiecutter.git', 'cookiecutter'),
],
)
def test_clone_should_invoke_vcs_command(
mocker, clone_dir, repo_type, repo_url, repo_name
):
"""When `clone()` is called with a git/hg repo, the corresponding VCS \
command should be run via `subprocess.check_output()`.
This should take place:
* In the correct dir
* With the correct args.
"""
mocker.patch('cookiecutter.vcs.is_vcs_installed', autospec=True, return_value=True)
mock_subprocess = mocker.patch(
'cookiecutter.vcs.subprocess.check_output',
autospec=True,
)
expected_repo_dir = os.path.normpath(os.path.join(clone_dir, repo_name))
branch = 'foobar'
repo_dir = vcs.clone(
repo_url, checkout=branch, clone_to_dir=clone_dir, no_input=True
)
> assert repo_dir == expected_repo_dir
E AssertionError: assert None == '/tmp/pytest-of-root/pytest-0/test_clone_should_invoke_vcs_c3/clone_dir/cookiecutter'
tests/vcs/test_clone.py:121: AssertionError
cookiecutter.git-cookiecutter]
cookiecutter.git-cookiecutter]
mocker =
clone_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_clone_should_invoke_vcs_c4/clone_dir')
repo_type = 'git', repo_url = 'git@github.com:cookiecutter/cookiecutter.git'
repo_name = 'cookiecutter'
@pytest.mark.parametrize(
'repo_type, repo_url, repo_name',
[
('git', 'https://github.com/hello/world.git', 'world'),
('hg', 'https://bitbucket.org/foo/bar', 'bar'),
('git', 'git@host:gitoliterepo', 'gitoliterepo'),
('git', 'git@gitlab.com:cookiecutter/cookiecutter.git', 'cookiecutter'),
('git', 'git@github.com:cookiecutter/cookiecutter.git', 'cookiecutter'),
],
)
def test_clone_should_invoke_vcs_command(
mocker, clone_dir, repo_type, repo_url, repo_name
):
"""When `clone()` is called with a git/hg repo, the corresponding VCS \
command should be run via `subprocess.check_output()`.
This should take place:
* In the correct dir
* With the correct args.
"""
mocker.patch('cookiecutter.vcs.is_vcs_installed', autospec=True, return_value=True)
mock_subprocess = mocker.patch(
'cookiecutter.vcs.subprocess.check_output',
autospec=True,
)
expected_repo_dir = os.path.normpath(os.path.join(clone_dir, repo_name))
branch = 'foobar'
repo_dir = vcs.clone(
repo_url, checkout=branch, clone_to_dir=clone_dir, no_input=True
)
> assert repo_dir == expected_repo_dir
E AssertionError: assert None == '/tmp/pytest-of-root/pytest-0/test_clone_should_invoke_vcs_c4/clone_dir/cookiecutter'
tests/vcs/test_clone.py:121: AssertionError
cookiedozer' not found]
cookiedozer' not found]
mocker =
clone_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_clone_handles_repo_typo_f0/clone_dir')
error_message = b"fatal: repository 'https://github.com/hackebro/cookiedozer' not found"
@pytest.mark.parametrize(
'error_message',
[
(b"fatal: repository 'https://github.com/hackebro/cookiedozer' not found"),
b'hg: abort: HTTP Error 404: Not Found',
],
)
def test_clone_handles_repo_typo(mocker, clone_dir, error_message):
"""In `clone()`, repository not found errors should raise an \
appropriate exception."""
# side_effect is set to an iterable here (and below),
# because of a Python 3.4 unittest.mock regression
# http://bugs.python.org/issue23661
mocker.patch(
'cookiecutter.vcs.subprocess.check_output',
autospec=True,
side_effect=[subprocess.CalledProcessError(-1, 'cmd', output=error_message)],
)
repository_url = 'https://github.com/hackebro/cookiedozer'
> with pytest.raises(exceptions.RepositoryNotFound) as err:
E Failed: DID NOT RAISE
tests/vcs/test_clone.py:159: Failed
test_clone.py::test_clone_handles_repo_typo[hg: abort: HTTP Error 404: Not Found]
test_clone.py::test_clone_handles_repo_typo[hg: abort: HTTP Error 404: Not Found]
mocker =
clone_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_clone_handles_repo_typo_h0/clone_dir')
error_message = b'hg: abort: HTTP Error 404: Not Found'
@pytest.mark.parametrize(
'error_message',
[
(b"fatal: repository 'https://github.com/hackebro/cookiedozer' not found"),
b'hg: abort: HTTP Error 404: Not Found',
],
)
def test_clone_handles_repo_typo(mocker, clone_dir, error_message):
"""In `clone()`, repository not found errors should raise an \
appropriate exception."""
# side_effect is set to an iterable here (and below),
# because of a Python 3.4 unittest.mock regression
# http://bugs.python.org/issue23661
mocker.patch(
'cookiecutter.vcs.subprocess.check_output',
autospec=True,
side_effect=[subprocess.CalledProcessError(-1, 'cmd', output=error_message)],
)
repository_url = 'https://github.com/hackebro/cookiedozer'
> with pytest.raises(exceptions.RepositoryNotFound) as err:
E Failed: DID NOT RAISE
tests/vcs/test_clone.py:159: Failed
test_clone.py::test_clone_handles_branch_typo[error: pathspec 'unknown_branch' did not match any file(s) known to git]
test_clone.py::test_clone_handles_branch_typo[error: pathspec 'unknown_branch' did not match any file(s) known to git]
mocker =
clone_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_clone_handles_branch_typo0/clone_dir')
error_message = b"error: pathspec 'unknown_branch' did not match any file(s) known to git"
@pytest.mark.parametrize(
'error_message',
[
b"error: pathspec 'unknown_branch' did not match any file(s) known to git",
b"hg: abort: unknown revision 'unknown_branch'!",
],
)
def test_clone_handles_branch_typo(mocker, clone_dir, error_message):
"""In `clone()`, branch not found errors should raise an \
appropriate exception."""
mocker.patch(
'cookiecutter.vcs.subprocess.check_output',
autospec=True,
side_effect=[subprocess.CalledProcessError(-1, 'cmd', output=error_message)],
)
repository_url = 'https://github.com/pytest-dev/cookiecutter-pytest-plugin'
> with pytest.raises(exceptions.RepositoryCloneFailed) as err:
E Failed: DID NOT RAISE
tests/vcs/test_clone.py:184: Failed
test_clone.py::test_clone_handles_branch_typo[hg: abort: unknown revision 'unknown_branch'!]
test_clone.py::test_clone_handles_branch_typo[hg: abort: unknown revision 'unknown_branch'!]
mocker =
clone_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_clone_handles_branch_typo1/clone_dir')
error_message = b"hg: abort: unknown revision 'unknown_branch'!"
@pytest.mark.parametrize(
'error_message',
[
b"error: pathspec 'unknown_branch' did not match any file(s) known to git",
b"hg: abort: unknown revision 'unknown_branch'!",
],
)
def test_clone_handles_branch_typo(mocker, clone_dir, error_message):
"""In `clone()`, branch not found errors should raise an \
appropriate exception."""
mocker.patch(
'cookiecutter.vcs.subprocess.check_output',
autospec=True,
side_effect=[subprocess.CalledProcessError(-1, 'cmd', output=error_message)],
)
repository_url = 'https://github.com/pytest-dev/cookiecutter-pytest-plugin'
> with pytest.raises(exceptions.RepositoryCloneFailed) as err:
E Failed: DID NOT RAISE
tests/vcs/test_clone.py:184: Failed
test_clone.py::test_clone_unknown_subprocess_error
test_clone.py::test_clone_unknown_subprocess_error
mocker =
clone_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_clone_unknown_subprocess_0/clone_dir')
def test_clone_unknown_subprocess_error(mocker, clone_dir):
"""In `clone()`, unknown subprocess errors should be raised."""
mocker.patch(
'cookiecutter.vcs.subprocess.check_output',
autospec=True,
side_effect=[
subprocess.CalledProcessError(-1, 'cmd', output=b'Something went wrong')
],
)
> with pytest.raises(subprocess.CalledProcessError):
E Failed: DID NOT RAISE
tests/vcs/test_clone.py:208: Failed
cookiecutter-pytest-plugin.git]
cookiecutter-pytest-plugin.git]
repo_url = 'git+https://github.com/pytest-dev/cookiecutter-pytest-plugin.git'
exp_repo_type = 'git'
exp_repo_url = 'https://github.com/pytest-dev/cookiecutter-pytest-plugin.git'
@pytest.mark.parametrize(
'repo_url, exp_repo_type, exp_repo_url',
[
(
'git+https://github.com/pytest-dev/cookiecutter-pytest-plugin.git',
'git',
'https://github.com/pytest-dev/cookiecutter-pytest-plugin.git',
),
(
'hg+https://bitbucket.org/foo/bar.hg',
'hg',
'https://bitbucket.org/foo/bar.hg',
),
(
'https://github.com/pytest-dev/cookiecutter-pytest-plugin.git',
'git',
'https://github.com/pytest-dev/cookiecutter-pytest-plugin.git',
),
('https://bitbucket.org/foo/bar.hg', 'hg', 'https://bitbucket.org/foo/bar.hg'),
(
'https://github.com/audreyfeldroy/cookiecutter-pypackage.git',
'git',
'https://github.com/audreyfeldroy/cookiecutter-pypackage.git',
),
(
'https://github.com/audreyfeldroy/cookiecutter-pypackage',
'git',
'https://github.com/audreyfeldroy/cookiecutter-pypackage',
),
(
'git@gitorious.org:cookiecutter-gitorious/cookiecutter-gitorious.git',
'git',
'git@gitorious.org:cookiecutter-gitorious/cookiecutter-gitorious.git',
),
(
'https://audreyr@bitbucket.org/audreyr/cookiecutter-bitbucket',
'hg',
'https://audreyr@bitbucket.org/audreyr/cookiecutter-bitbucket',
),
],
)
def test_identify_known_repo(repo_url, exp_repo_type, exp_repo_url):
"""Verify different correct repositories url syntax is correctly transformed."""
> assert vcs.identify_repo(repo_url) == (exp_repo_type, exp_repo_url)
E AssertionError: assert None == ('git', 'https://github.com/pytest-dev/cookiecutter-pytest-plugin.git')
E + where None = ('git+https://github.com/pytest-dev/cookiecutter-pytest-plugin.git')
E + where = vcs.identify_repo
tests/vcs/test_identify_repo.py:51: AssertionError
bar.hg]
bar.hg]
repo_url = 'hg+https://bitbucket.org/foo/bar.hg', exp_repo_type = 'hg'
exp_repo_url = 'https://bitbucket.org/foo/bar.hg'
@pytest.mark.parametrize(
'repo_url, exp_repo_type, exp_repo_url',
[
(
'git+https://github.com/pytest-dev/cookiecutter-pytest-plugin.git',
'git',
'https://github.com/pytest-dev/cookiecutter-pytest-plugin.git',
),
(
'hg+https://bitbucket.org/foo/bar.hg',
'hg',
'https://bitbucket.org/foo/bar.hg',
),
(
'https://github.com/pytest-dev/cookiecutter-pytest-plugin.git',
'git',
'https://github.com/pytest-dev/cookiecutter-pytest-plugin.git',
),
('https://bitbucket.org/foo/bar.hg', 'hg', 'https://bitbucket.org/foo/bar.hg'),
(
'https://github.com/audreyfeldroy/cookiecutter-pypackage.git',
'git',
'https://github.com/audreyfeldroy/cookiecutter-pypackage.git',
),
(
'https://github.com/audreyfeldroy/cookiecutter-pypackage',
'git',
'https://github.com/audreyfeldroy/cookiecutter-pypackage',
),
(
'git@gitorious.org:cookiecutter-gitorious/cookiecutter-gitorious.git',
'git',
'git@gitorious.org:cookiecutter-gitorious/cookiecutter-gitorious.git',
),
(
'https://audreyr@bitbucket.org/audreyr/cookiecutter-bitbucket',
'hg',
'https://audreyr@bitbucket.org/audreyr/cookiecutter-bitbucket',
),
],
)
def test_identify_known_repo(repo_url, exp_repo_type, exp_repo_url):
"""Verify different correct repositories url syntax is correctly transformed."""
> assert vcs.identify_repo(repo_url) == (exp_repo_type, exp_repo_url)
E AssertionError: assert None == ('hg', 'https://bitbucket.org/foo/bar.hg')
E + where None = ('hg+https://bitbucket.org/foo/bar.hg')
E + where = vcs.identify_repo
tests/vcs/test_identify_repo.py:51: AssertionError
cookiecutter-pytest-plugin.git]
cookiecutter-pytest-plugin.git]
repo_url = 'https://github.com/pytest-dev/cookiecutter-pytest-plugin.git'
exp_repo_type = 'git'
exp_repo_url = 'https://github.com/pytest-dev/cookiecutter-pytest-plugin.git'
@pytest.mark.parametrize(
'repo_url, exp_repo_type, exp_repo_url',
[
(
'git+https://github.com/pytest-dev/cookiecutter-pytest-plugin.git',
'git',
'https://github.com/pytest-dev/cookiecutter-pytest-plugin.git',
),
(
'hg+https://bitbucket.org/foo/bar.hg',
'hg',
'https://bitbucket.org/foo/bar.hg',
),
(
'https://github.com/pytest-dev/cookiecutter-pytest-plugin.git',
'git',
'https://github.com/pytest-dev/cookiecutter-pytest-plugin.git',
),
('https://bitbucket.org/foo/bar.hg', 'hg', 'https://bitbucket.org/foo/bar.hg'),
(
'https://github.com/audreyfeldroy/cookiecutter-pypackage.git',
'git',
'https://github.com/audreyfeldroy/cookiecutter-pypackage.git',
),
(
'https://github.com/audreyfeldroy/cookiecutter-pypackage',
'git',
'https://github.com/audreyfeldroy/cookiecutter-pypackage',
),
(
'git@gitorious.org:cookiecutter-gitorious/cookiecutter-gitorious.git',
'git',
'git@gitorious.org:cookiecutter-gitorious/cookiecutter-gitorious.git',
),
(
'https://audreyr@bitbucket.org/audreyr/cookiecutter-bitbucket',
'hg',
'https://audreyr@bitbucket.org/audreyr/cookiecutter-bitbucket',
),
],
)
def test_identify_known_repo(repo_url, exp_repo_type, exp_repo_url):
"""Verify different correct repositories url syntax is correctly transformed."""
> assert vcs.identify_repo(repo_url) == (exp_repo_type, exp_repo_url)
E AssertionError: assert None == ('git', 'https://github.com/pytest-dev/cookiecutter-pytest-plugin.git')
E + where None = ('https://github.com/pytest-dev/cookiecutter-pytest-plugin.git')
E + where = vcs.identify_repo
tests/vcs/test_identify_repo.py:51: AssertionError
bar.hg]
bar.hg]
repo_url = 'https://bitbucket.org/foo/bar.hg', exp_repo_type = 'hg'
exp_repo_url = 'https://bitbucket.org/foo/bar.hg'
@pytest.mark.parametrize(
'repo_url, exp_repo_type, exp_repo_url',
[
(
'git+https://github.com/pytest-dev/cookiecutter-pytest-plugin.git',
'git',
'https://github.com/pytest-dev/cookiecutter-pytest-plugin.git',
),
(
'hg+https://bitbucket.org/foo/bar.hg',
'hg',
'https://bitbucket.org/foo/bar.hg',
),
(
'https://github.com/pytest-dev/cookiecutter-pytest-plugin.git',
'git',
'https://github.com/pytest-dev/cookiecutter-pytest-plugin.git',
),
('https://bitbucket.org/foo/bar.hg', 'hg', 'https://bitbucket.org/foo/bar.hg'),
(
'https://github.com/audreyfeldroy/cookiecutter-pypackage.git',
'git',
'https://github.com/audreyfeldroy/cookiecutter-pypackage.git',
),
(
'https://github.com/audreyfeldroy/cookiecutter-pypackage',
'git',
'https://github.com/audreyfeldroy/cookiecutter-pypackage',
),
(
'git@gitorious.org:cookiecutter-gitorious/cookiecutter-gitorious.git',
'git',
'git@gitorious.org:cookiecutter-gitorious/cookiecutter-gitorious.git',
),
(
'https://audreyr@bitbucket.org/audreyr/cookiecutter-bitbucket',
'hg',
'https://audreyr@bitbucket.org/audreyr/cookiecutter-bitbucket',
),
],
)
def test_identify_known_repo(repo_url, exp_repo_type, exp_repo_url):
"""Verify different correct repositories url syntax is correctly transformed."""
> assert vcs.identify_repo(repo_url) == (exp_repo_type, exp_repo_url)
E AssertionError: assert None == ('hg', 'https://bitbucket.org/foo/bar.hg')
E + where None = ('https://bitbucket.org/foo/bar.hg')
E + where = vcs.identify_repo
tests/vcs/test_identify_repo.py:51: AssertionError
cookiecutter-pypackage.git]
cookiecutter-pypackage.git]
repo_url = 'https://github.com/audreyfeldroy/cookiecutter-pypackage.git'
exp_repo_type = 'git'
exp_repo_url = 'https://github.com/audreyfeldroy/cookiecutter-pypackage.git'
@pytest.mark.parametrize(
'repo_url, exp_repo_type, exp_repo_url',
[
(
'git+https://github.com/pytest-dev/cookiecutter-pytest-plugin.git',
'git',
'https://github.com/pytest-dev/cookiecutter-pytest-plugin.git',
),
(
'hg+https://bitbucket.org/foo/bar.hg',
'hg',
'https://bitbucket.org/foo/bar.hg',
),
(
'https://github.com/pytest-dev/cookiecutter-pytest-plugin.git',
'git',
'https://github.com/pytest-dev/cookiecutter-pytest-plugin.git',
),
('https://bitbucket.org/foo/bar.hg', 'hg', 'https://bitbucket.org/foo/bar.hg'),
(
'https://github.com/audreyfeldroy/cookiecutter-pypackage.git',
'git',
'https://github.com/audreyfeldroy/cookiecutter-pypackage.git',
),
(
'https://github.com/audreyfeldroy/cookiecutter-pypackage',
'git',
'https://github.com/audreyfeldroy/cookiecutter-pypackage',
),
(
'git@gitorious.org:cookiecutter-gitorious/cookiecutter-gitorious.git',
'git',
'git@gitorious.org:cookiecutter-gitorious/cookiecutter-gitorious.git',
),
(
'https://audreyr@bitbucket.org/audreyr/cookiecutter-bitbucket',
'hg',
'https://audreyr@bitbucket.org/audreyr/cookiecutter-bitbucket',
),
],
)
def test_identify_known_repo(repo_url, exp_repo_type, exp_repo_url):
"""Verify different correct repositories url syntax is correctly transformed."""
> assert vcs.identify_repo(repo_url) == (exp_repo_type, exp_repo_url)
E AssertionError: assert None == ('git', 'https://github.com/audreyfeldroy/cookiecutter-pypackage.git')
E + where None = ('https://github.com/audreyfeldroy/cookiecutter-pypackage.git')
E + where = vcs.identify_repo
tests/vcs/test_identify_repo.py:51: AssertionError
cookiecutter-pypackage]
cookiecutter-pypackage]
repo_url = 'https://github.com/audreyfeldroy/cookiecutter-pypackage'
exp_repo_type = 'git'
exp_repo_url = 'https://github.com/audreyfeldroy/cookiecutter-pypackage'
@pytest.mark.parametrize(
'repo_url, exp_repo_type, exp_repo_url',
[
(
'git+https://github.com/pytest-dev/cookiecutter-pytest-plugin.git',
'git',
'https://github.com/pytest-dev/cookiecutter-pytest-plugin.git',
),
(
'hg+https://bitbucket.org/foo/bar.hg',
'hg',
'https://bitbucket.org/foo/bar.hg',
),
(
'https://github.com/pytest-dev/cookiecutter-pytest-plugin.git',
'git',
'https://github.com/pytest-dev/cookiecutter-pytest-plugin.git',
),
('https://bitbucket.org/foo/bar.hg', 'hg', 'https://bitbucket.org/foo/bar.hg'),
(
'https://github.com/audreyfeldroy/cookiecutter-pypackage.git',
'git',
'https://github.com/audreyfeldroy/cookiecutter-pypackage.git',
),
(
'https://github.com/audreyfeldroy/cookiecutter-pypackage',
'git',
'https://github.com/audreyfeldroy/cookiecutter-pypackage',
),
(
'git@gitorious.org:cookiecutter-gitorious/cookiecutter-gitorious.git',
'git',
'git@gitorious.org:cookiecutter-gitorious/cookiecutter-gitorious.git',
),
(
'https://audreyr@bitbucket.org/audreyr/cookiecutter-bitbucket',
'hg',
'https://audreyr@bitbucket.org/audreyr/cookiecutter-bitbucket',
),
],
)
def test_identify_known_repo(repo_url, exp_repo_type, exp_repo_url):
"""Verify different correct repositories url syntax is correctly transformed."""
> assert vcs.identify_repo(repo_url) == (exp_repo_type, exp_repo_url)
E AssertionError: assert None == ('git', 'https://github.com/audreyfeldroy/cookiecutter-pypackage')
E + where None = ('https://github.com/audreyfeldroy/cookiecutter-pypackage')
E + where = vcs.identify_repo
tests/vcs/test_identify_repo.py:51: AssertionError
cookiecutter-gitorious.git]
cookiecutter-gitorious.git]
repo_url = 'git@gitorious.org:cookiecutter-gitorious/cookiecutter-gitorious.git'
exp_repo_type = 'git'
exp_repo_url = 'git@gitorious.org:cookiecutter-gitorious/cookiecutter-gitorious.git'
@pytest.mark.parametrize(
'repo_url, exp_repo_type, exp_repo_url',
[
(
'git+https://github.com/pytest-dev/cookiecutter-pytest-plugin.git',
'git',
'https://github.com/pytest-dev/cookiecutter-pytest-plugin.git',
),
(
'hg+https://bitbucket.org/foo/bar.hg',
'hg',
'https://bitbucket.org/foo/bar.hg',
),
(
'https://github.com/pytest-dev/cookiecutter-pytest-plugin.git',
'git',
'https://github.com/pytest-dev/cookiecutter-pytest-plugin.git',
),
('https://bitbucket.org/foo/bar.hg', 'hg', 'https://bitbucket.org/foo/bar.hg'),
(
'https://github.com/audreyfeldroy/cookiecutter-pypackage.git',
'git',
'https://github.com/audreyfeldroy/cookiecutter-pypackage.git',
),
(
'https://github.com/audreyfeldroy/cookiecutter-pypackage',
'git',
'https://github.com/audreyfeldroy/cookiecutter-pypackage',
),
(
'git@gitorious.org:cookiecutter-gitorious/cookiecutter-gitorious.git',
'git',
'git@gitorious.org:cookiecutter-gitorious/cookiecutter-gitorious.git',
),
(
'https://audreyr@bitbucket.org/audreyr/cookiecutter-bitbucket',
'hg',
'https://audreyr@bitbucket.org/audreyr/cookiecutter-bitbucket',
),
],
)
def test_identify_known_repo(repo_url, exp_repo_type, exp_repo_url):
"""Verify different correct repositories url syntax is correctly transformed."""
> assert vcs.identify_repo(repo_url) == (exp_repo_type, exp_repo_url)
E AssertionError: assert None == ('git', 'git@gitorious.org:cookiecutter-gitorious/cookiecutter-gitorious.git')
E + where None = ('git@gitorious.org:cookiecutter-gitorious/cookiecutter-gitorious.git')
E + where = vcs.identify_repo
tests/vcs/test_identify_repo.py:51: AssertionError
cookiecutter-bitbucket]
cookiecutter-bitbucket]
repo_url = 'https://audreyr@bitbucket.org/audreyr/cookiecutter-bitbucket'
exp_repo_type = 'hg'
exp_repo_url = 'https://audreyr@bitbucket.org/audreyr/cookiecutter-bitbucket'
@pytest.mark.parametrize(
'repo_url, exp_repo_type, exp_repo_url',
[
(
'git+https://github.com/pytest-dev/cookiecutter-pytest-plugin.git',
'git',
'https://github.com/pytest-dev/cookiecutter-pytest-plugin.git',
),
(
'hg+https://bitbucket.org/foo/bar.hg',
'hg',
'https://bitbucket.org/foo/bar.hg',
),
(
'https://github.com/pytest-dev/cookiecutter-pytest-plugin.git',
'git',
'https://github.com/pytest-dev/cookiecutter-pytest-plugin.git',
),
('https://bitbucket.org/foo/bar.hg', 'hg', 'https://bitbucket.org/foo/bar.hg'),
(
'https://github.com/audreyfeldroy/cookiecutter-pypackage.git',
'git',
'https://github.com/audreyfeldroy/cookiecutter-pypackage.git',
),
(
'https://github.com/audreyfeldroy/cookiecutter-pypackage',
'git',
'https://github.com/audreyfeldroy/cookiecutter-pypackage',
),
(
'git@gitorious.org:cookiecutter-gitorious/cookiecutter-gitorious.git',
'git',
'git@gitorious.org:cookiecutter-gitorious/cookiecutter-gitorious.git',
),
(
'https://audreyr@bitbucket.org/audreyr/cookiecutter-bitbucket',
'hg',
'https://audreyr@bitbucket.org/audreyr/cookiecutter-bitbucket',
),
],
)
def test_identify_known_repo(repo_url, exp_repo_type, exp_repo_url):
"""Verify different correct repositories url syntax is correctly transformed."""
> assert vcs.identify_repo(repo_url) == (exp_repo_type, exp_repo_url)
E AssertionError: assert None == ('hg', 'https://audreyr@bitbucket.org/audreyr/cookiecutter-bitbucket')
E + where None = ('https://audreyr@bitbucket.org/audreyr/cookiecutter-bitbucket')
E + where = vcs.identify_repo
tests/vcs/test_identify_repo.py:51: AssertionError
test_identify_repo.py::test_identify_raise_on_unknown_repo[foo+git]
test_identify_repo.py::test_identify_raise_on_unknown_repo[foo+git]
unknown_repo_type_url = 'foo+git'
def test_identify_raise_on_unknown_repo(unknown_repo_type_url):
"""Verify different incorrect repositories url syntax trigger error raising."""
> with pytest.raises(exceptions.UnknownRepoType):
E Failed: DID NOT RAISE
tests/vcs/test_identify_repo.py:70: Failed
test_identify_repo.py::test_identify_raise_on_unknown_repo[foo+hg]
test_identify_repo.py::test_identify_raise_on_unknown_repo[foo+hg]
unknown_repo_type_url = 'foo+hg'
def test_identify_raise_on_unknown_repo(unknown_repo_type_url):
"""Verify different incorrect repositories url syntax trigger error raising."""
> with pytest.raises(exceptions.UnknownRepoType):
E Failed: DID NOT RAISE
tests/vcs/test_identify_repo.py:70: Failed
test_identify_repo.py::test_identify_raise_on_unknown_repo[foo+bar]
test_identify_repo.py::test_identify_raise_on_unknown_repo[foo+bar]
unknown_repo_type_url = 'foo+bar'
def test_identify_raise_on_unknown_repo(unknown_repo_type_url):
"""Verify different incorrect repositories url syntax trigger error raising."""
> with pytest.raises(exceptions.UnknownRepoType):
E Failed: DID NOT RAISE
tests/vcs/test_identify_repo.py:70: Failed
test_identify_repo.py::test_identify_raise_on_unknown_repo[foobar]
test_identify_repo.py::test_identify_raise_on_unknown_repo[foobar]
unknown_repo_type_url = 'foobar'
def test_identify_raise_on_unknown_repo(unknown_repo_type_url):
"""Verify different incorrect repositories url syntax trigger error raising."""
> with pytest.raises(exceptions.UnknownRepoType):
E Failed: DID NOT RAISE
tests/vcs/test_identify_repo.py:70: Failed
norepotypespecified.com]
norepotypespecified.com]
unknown_repo_type_url = 'http://norepotypespecified.com'
def test_identify_raise_on_unknown_repo(unknown_repo_type_url):
"""Verify different incorrect repositories url syntax trigger error raising."""
> with pytest.raises(exceptions.UnknownRepoType):
E Failed: DID NOT RAISE
tests/vcs/test_identify_repo.py:70: Failed
test_is_vcs_installed.py::test_is_vcs_installed[-False]
test_is_vcs_installed.py::test_is_vcs_installed[-False]
mocker =
which_return = '', result = False
@pytest.mark.parametrize(
'which_return, result',
[('', False), (None, False), (False, False), ('/usr/local/bin/git', True)],
)
def test_is_vcs_installed(mocker, which_return, result):
"""Verify `is_vcs_installed` function correctly handles `which` answer."""
mocker.patch('cookiecutter.vcs.which', autospec=True, return_value=which_return)
> assert vcs.is_vcs_installed('git') == result
E AssertionError: assert None == False
E + where None = ('git')
E + where = vcs.is_vcs_installed
tests/vcs/test_is_vcs_installed.py:15: AssertionError
test_is_vcs_installed.py::test_is_vcs_installed[None-False]
test_is_vcs_installed.py::test_is_vcs_installed[None-False]
mocker =
which_return = None, result = False
@pytest.mark.parametrize(
'which_return, result',
[('', False), (None, False), (False, False), ('/usr/local/bin/git', True)],
)
def test_is_vcs_installed(mocker, which_return, result):
"""Verify `is_vcs_installed` function correctly handles `which` answer."""
mocker.patch('cookiecutter.vcs.which', autospec=True, return_value=which_return)
> assert vcs.is_vcs_installed('git') == result
E AssertionError: assert None == False
E + where None = ('git')
E + where = vcs.is_vcs_installed
tests/vcs/test_is_vcs_installed.py:15: AssertionError
test_is_vcs_installed.py::test_is_vcs_installed[False-False]
test_is_vcs_installed.py::test_is_vcs_installed[False-False]
mocker =
which_return = False, result = False
@pytest.mark.parametrize(
'which_return, result',
[('', False), (None, False), (False, False), ('/usr/local/bin/git', True)],
)
def test_is_vcs_installed(mocker, which_return, result):
"""Verify `is_vcs_installed` function correctly handles `which` answer."""
mocker.patch('cookiecutter.vcs.which', autospec=True, return_value=which_return)
> assert vcs.is_vcs_installed('git') == result
E AssertionError: assert None == False
E + where None = ('git')
E + where = vcs.is_vcs_installed
tests/vcs/test_is_vcs_installed.py:15: AssertionError
git-True]
git-True]
mocker =
which_return = '/usr/local/bin/git', result = True
@pytest.mark.parametrize(
'which_return, result',
[('', False), (None, False), (False, False), ('/usr/local/bin/git', True)],
)
def test_is_vcs_installed(mocker, which_return, result):
"""Verify `is_vcs_installed` function correctly handles `which` answer."""
mocker.patch('cookiecutter.vcs.which', autospec=True, return_value=which_return)
> assert vcs.is_vcs_installed('git') == result
E AssertionError: assert None == True
E + where None = ('git')
E + where = vcs.is_vcs_installed
tests/vcs/test_is_vcs_installed.py:15: AssertionError
test_unzip.py::test_unzip_local_file
test_unzip.py::test_unzip_local_file
mocker =
clone_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_unzip_local_file0/clone_dir')
def test_unzip_local_file(mocker, clone_dir):
"""Local file reference can be unzipped."""
mock_prompt_and_delete = mocker.patch(
'cookiecutter.zipfile.prompt_and_delete', return_value=True, autospec=True
)
output_dir = zipfile.unzip(
'tests/files/fake-repo-tmpl.zip', is_url=False, clone_to_dir=str(clone_dir)
)
> assert output_dir.startswith(tempfile.gettempdir())
E AttributeError: 'NoneType' object has no attribute 'startswith'
tests/zipfile/test_unzip.py:42: AttributeError
test_unzip.py::test_unzip_protected_local_file_environment_password
test_unzip.py::test_unzip_protected_local_file_environment_password
mocker =
clone_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_unzip_protected_local_fil0/clone_dir')
def test_unzip_protected_local_file_environment_password(mocker, clone_dir):
"""In `unzip()`, the environment can be used to provide a repo password."""
mock_prompt_and_delete = mocker.patch(
'cookiecutter.zipfile.prompt_and_delete', return_value=True, autospec=True
)
output_dir = zipfile.unzip(
'tests/files/protected-fake-repo-tmpl.zip',
is_url=False,
clone_to_dir=str(clone_dir),
password='sekrit',
)
> assert output_dir.startswith(tempfile.gettempdir())
E AttributeError: 'NoneType' object has no attribute 'startswith'
tests/zipfile/test_unzip.py:59: AttributeError
test_unzip.py::test_unzip_protected_local_file_bad_environment_password
test_unzip.py::test_unzip_protected_local_file_bad_environment_password
mocker =
clone_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_unzip_protected_local_fil1/clone_dir')
def test_unzip_protected_local_file_bad_environment_password(mocker, clone_dir):
"""In `unzip()`, an error occurs if the environment has a bad password."""
mocker.patch(
'cookiecutter.zipfile.prompt_and_delete', return_value=True, autospec=True
)
> with pytest.raises(InvalidZipRepository):
E Failed: DID NOT RAISE
tests/zipfile/test_unzip.py:69: Failed
test_unzip.py::test_unzip_protected_local_file_user_password_with_noinput
mocker =
clone_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_unzip_protected_local_fil2/clone_dir')
def test_unzip_protected_local_file_user_password_with_noinput(mocker, clone_dir):
"""Can't unpack a password-protected repo in no_input mode."""
mocker.patch(
'cookiecutter.zipfile.prompt_and_delete', return_value=True, autospec=True
)
> with pytest.raises(InvalidZipRepository):
E Failed: DID NOT RAISE
tests/zipfile/test_unzip.py:84: Failed
test_unzip.py::test_unzip_protected_local_file_user_password
test_unzip.py::test_unzip_protected_local_file_user_password
mocker =
clone_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_unzip_protected_local_fil3/clone_dir')
def test_unzip_protected_local_file_user_password(mocker, clone_dir):
"""A password-protected local file reference can be unzipped."""
mock_prompt_and_delete = mocker.patch(
'cookiecutter.zipfile.prompt_and_delete', return_value=True, autospec=True
)
mocker.patch('cookiecutter.zipfile.read_repo_password', return_value='sekrit')
output_dir = zipfile.unzip(
'tests/files/protected-fake-repo-tmpl.zip',
is_url=False,
clone_to_dir=str(clone_dir),
)
> assert output_dir.startswith(tempfile.gettempdir())
E AttributeError: 'NoneType' object has no attribute 'startswith'
tests/zipfile/test_unzip.py:106: AttributeError
test_unzip.py::test_unzip_protected_local_file_user_bad_password
test_unzip.py::test_unzip_protected_local_file_user_bad_password
mocker =
clone_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_unzip_protected_local_fil4/clone_dir')
def test_unzip_protected_local_file_user_bad_password(mocker, clone_dir):
"""Error in `unzip()`, if user can't provide a valid password."""
mocker.patch(
'cookiecutter.zipfile.prompt_and_delete', return_value=True, autospec=True
)
mocker.patch(
'cookiecutter.zipfile.read_repo_password', return_value='not-the-right-password'
)
> with pytest.raises(InvalidZipRepository):
E Failed: DID NOT RAISE
tests/zipfile/test_unzip.py:119: Failed
test_unzip.py::test_empty_zip_file
test_unzip.py::test_empty_zip_file
mocker =
clone_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_empty_zip_file0/clone_dir')
def test_empty_zip_file(mocker, clone_dir):
"""In `unzip()`, an empty file raises an error."""
mocker.patch(
'cookiecutter.zipfile.prompt_and_delete', return_value=True, autospec=True
)
> with pytest.raises(InvalidZipRepository):
E Failed: DID NOT RAISE
tests/zipfile/test_unzip.py:133: Failed
test_unzip.py::test_non_repo_zip_file
test_unzip.py::test_non_repo_zip_file
mocker =
clone_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_non_repo_zip_file0/clone_dir')
def test_non_repo_zip_file(mocker, clone_dir):
"""In `unzip()`, a repository must have a top level directory."""
mocker.patch(
'cookiecutter.zipfile.prompt_and_delete', return_value=True, autospec=True
)
> with pytest.raises(InvalidZipRepository):
E Failed: DID NOT RAISE
tests/zipfile/test_unzip.py:145: Failed
test_unzip.py::test_bad_zip_file
test_unzip.py::test_bad_zip_file
mocker =
clone_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_bad_zip_file0/clone_dir')
def test_bad_zip_file(mocker, clone_dir):
"""In `unzip()`, a corrupted zip file raises an error."""
mocker.patch(
'cookiecutter.zipfile.prompt_and_delete', return_value=True, autospec=True
)
> with pytest.raises(InvalidZipRepository):
E Failed: DID NOT RAISE
tests/zipfile/test_unzip.py:157: Failed
test_unzip.py::test_unzip_url
test_unzip.py::test_unzip_url
mocker =
clone_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_unzip_url0/clone_dir')
def test_unzip_url(mocker, clone_dir):
"""In `unzip()`, a url will be downloaded and unzipped."""
mock_prompt_and_delete = mocker.patch(
'cookiecutter.zipfile.prompt_and_delete', return_value=True, autospec=True
)
request = mocker.MagicMock()
request.iter_content.return_value = mock_download()
mocker.patch(
'cookiecutter.zipfile.requests.get',
return_value=request,
autospec=True,
)
output_dir = zipfile.unzip(
'https://example.com/path/to/fake-repo-tmpl.zip',
is_url=True,
clone_to_dir=str(clone_dir),
)
> assert output_dir.startswith(tempfile.gettempdir())
E AttributeError: 'NoneType' object has no attribute 'startswith'
tests/zipfile/test_unzip.py:184: AttributeError
test_unzip.py::test_unzip_url_with_empty_chunks
test_unzip.py::test_unzip_url_with_empty_chunks
mocker =
clone_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_unzip_url_with_empty_chun0/clone_dir')
def test_unzip_url_with_empty_chunks(mocker, clone_dir):
"""In `unzip()` empty chunk must be ignored."""
mock_prompt_and_delete = mocker.patch(
'cookiecutter.zipfile.prompt_and_delete', return_value=True, autospec=True
)
request = mocker.MagicMock()
request.iter_content.return_value = mock_download_with_empty_chunks()
mocker.patch(
'cookiecutter.zipfile.requests.get',
return_value=request,
autospec=True,
)
output_dir = zipfile.unzip(
'https://example.com/path/to/fake-repo-tmpl.zip',
is_url=True,
clone_to_dir=str(clone_dir),
)
> assert output_dir.startswith(tempfile.gettempdir())
E AttributeError: 'NoneType' object has no attribute 'startswith'
tests/zipfile/test_unzip.py:209: AttributeError
test_unzip.py::test_unzip_url_existing_cache
test_unzip.py::test_unzip_url_existing_cache
mocker =
clone_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_unzip_url_existing_cache0/clone_dir')
def test_unzip_url_existing_cache(mocker, clone_dir):
"""Url should be downloaded and unzipped, old zip file will be removed."""
mock_prompt_and_delete = mocker.patch(
'cookiecutter.zipfile.prompt_and_delete', return_value=True, autospec=True
)
request = mocker.MagicMock()
request.iter_content.return_value = mock_download()
mocker.patch(
'cookiecutter.zipfile.requests.get',
return_value=request,
autospec=True,
)
# Create an existing cache of the zipfile
existing_zip = clone_dir.joinpath('fake-repo-tmpl.zip')
existing_zip.write_text('This is an existing zipfile')
output_dir = zipfile.unzip(
'https://example.com/path/to/fake-repo-tmpl.zip',
is_url=True,
clone_to_dir=str(clone_dir),
)
> assert output_dir.startswith(tempfile.gettempdir())
E AttributeError: 'NoneType' object has no attribute 'startswith'
tests/zipfile/test_unzip.py:238: AttributeError
test_unzip.py::test_unzip_url_existing_cache_no_input
mocker =
clone_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_unzip_url_existing_cache_0/clone_dir')
def test_unzip_url_existing_cache_no_input(mocker, clone_dir):
"""If no_input is provided, the existing file should be removed."""
request = mocker.MagicMock()
request.iter_content.return_value = mock_download()
mocker.patch(
'cookiecutter.zipfile.requests.get',
return_value=request,
autospec=True,
)
# Create an existing cache of the zipfile
existing_zip = clone_dir.joinpath('fake-repo-tmpl.zip')
existing_zip.write_text('This is an existing zipfile')
output_dir = zipfile.unzip(
'https://example.com/path/to/fake-repo-tmpl.zip',
is_url=True,
clone_to_dir=str(clone_dir),
no_input=True,
)
> assert output_dir.startswith(tempfile.gettempdir())
E AttributeError: 'NoneType' object has no attribute 'startswith'
tests/zipfile/test_unzip.py:264: AttributeError
test_unzip.py::test_unzip_should_abort_if_no_redownload
test_unzip.py::test_unzip_should_abort_if_no_redownload
mocker =
clone_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_unzip_should_abort_if_no_0/clone_dir')
def test_unzip_should_abort_if_no_redownload(mocker, clone_dir):
"""Should exit without cloning anything If no redownload."""
mocker.patch(
'cookiecutter.zipfile.prompt_and_delete', side_effect=SystemExit, autospec=True
)
mock_requests_get = mocker.patch(
'cookiecutter.zipfile.requests.get',
autospec=True,
)
# Create an existing cache of the zipfile
existing_zip = clone_dir.joinpath('fake-repo-tmpl.zip')
existing_zip.write_text('This is an existing zipfile')
zipfile_url = 'https://example.com/path/to/fake-repo-tmpl.zip'
> with pytest.raises(SystemExit):
E Failed: DID NOT RAISE
tests/zipfile/test_unzip.py:284: Failed
test_unzip.py::test_unzip_is_ok_to_reuse
test_unzip.py::test_unzip_is_ok_to_reuse
mocker =
clone_dir = PosixPath('/tmp/pytest-of-root/pytest-0/test_unzip_is_ok_to_reuse0/clone_dir')
def test_unzip_is_ok_to_reuse(mocker, clone_dir):
"""Already downloaded zip should not be downloaded again."""
mock_prompt_and_delete = mocker.patch(
'cookiecutter.zipfile.prompt_and_delete', return_value=False, autospec=True
)
request = mocker.MagicMock()
existing_zip = clone_dir.joinpath('fake-repo-tmpl.zip')
shutil.copy('tests/files/fake-repo-tmpl.zip', existing_zip)
output_dir = zipfile.unzip(
'https://example.com/path/to/fake-repo-tmpl.zip',
is_url=True,
clone_to_dir=str(clone_dir),
)
> assert output_dir.startswith(tempfile.gettempdir())
E AttributeError: 'NoneType' object has no attribute 'startswith'
tests/zipfile/test_unzip.py:307: AttributeError
Patch diff
diff --git a/cookiecutter/generate.py b/cookiecutter/generate.py
index f620d04..36bbdaa 100644
--- a/cookiecutter/generate.py
+++ b/cookiecutter/generate.py
@@ -26,11 +26,28 @@ def is_copy_only_path(path, context):
should be rendered or just copied.
:param context: cookiecutter context.
"""
- pass
+ copy_without_render = context.get("_copy_without_render", [])
+ for pattern in copy_without_render:
+ if fnmatch.fnmatch(path, pattern):
+ return True
+ return False
def apply_overwrites_to_context(context, overwrite_context, *, in_dictionary_variable=False):
"""Modify the given context in place based on the overwrite_context."""
- pass
+ for key, value in overwrite_context.items():
+ if isinstance(value, dict):
+ if key not in context:
+ context[key] = {}
+ apply_overwrites_to_context(context[key], value, in_dictionary_variable=True)
+ elif isinstance(value, list):
+ if key not in context:
+ context[key] = []
+ context[key].extend(value)
+ else:
+ if in_dictionary_variable and key not in context:
+ context[key] = value
+ elif not in_dictionary_variable:
+ context[key] = value
def generate_context(context_file='cookiecutter.json', default_context=None, extra_context=None):
"""Generate the context for a Cookiecutter project template.
@@ -42,7 +59,22 @@ def generate_context(context_file='cookiecutter.json', default_context=None, ext
:param default_context: Dictionary containing config to take into account.
:param extra_context: Dictionary containing configuration overrides
"""
- pass
+ context = {}
+ try:
+ with open(context_file, 'r') as file:
+ context = json.load(file, object_pairs_hook=OrderedDict)
+ except ValueError as e:
+ raise ContextDecodingException(context_file, str(e))
+
+ # Apply default context
+ if default_context:
+ apply_overwrites_to_context(context, default_context)
+
+ # Apply extra context
+ if extra_context:
+ apply_overwrites_to_context(context, extra_context)
+
+ return context
def generate_file(project_dir, infile, context, env, skip_if_file_exists=False):
"""Render filename of infile as name of outfile, handle infile correctly.
@@ -65,7 +97,45 @@ def generate_file(project_dir, infile, context, env, skip_if_file_exists=False):
:param context: Dict for populating the cookiecutter's variables.
:param env: Jinja2 template execution environment.
"""
- pass
+ logger.debug('Generating file %s', infile)
+
+ # Render the path to the output file (not including the root project dir)
+ outfile_tmpl = env.from_string(infile)
+ outfile = outfile_tmpl.render(**context)
+ outfile_path = os.path.join(project_dir, outfile)
+
+ # Create the directories to the outfile if they don't exist
+ dirname = os.path.dirname(outfile_path)
+ make_sure_path_exists(dirname)
+
+ if skip_if_file_exists and os.path.exists(outfile_path):
+ logger.debug('File %s already exists, skipping', outfile)
+ return
+
+ # Just copy over binary files without rendering
+ if is_binary(infile):
+ shutil.copyfile(infile, outfile_path)
+ else:
+ # Force fwd slashes on Windows for jinja template
+ infile_fwd_slashes = infile.replace(os.path.sep, '/')
+
+ # Render the file
+ try:
+ tmpl = env.get_template(infile_fwd_slashes)
+ rendered_file = tmpl.render(**context)
+ except UndefinedError as err:
+ msg = "Unable to create file '{}'".format(outfile)
+ raise UndefinedVariableInTemplate(msg, err, context)
+ except TemplateSyntaxError as err:
+ msg = "Unable to create file '{}'".format(outfile)
+ raise TemplateSyntaxError(msg, err.lineno, err.name, err.filename)
+
+ # Write the file
+ with open(outfile_path, 'w') as fh:
+ fh.write(rendered_file)
+
+ # Apply file permissions to output file
+ shutil.copymode(infile, outfile_path)
def render_and_create_dir(dirname: str, context: dict, output_dir: 'os.PathLike[str]', environment: Environment, overwrite_if_exists: bool=False):
"""Render name of a directory, create the directory, return its path."""
@@ -97,4 +167,40 @@ def generate_files(repo_dir, context=None, output_dir='.', overwrite_if_exists=F
:param keep_project_on_failure: If `True` keep generated project directory even when
generation fails
"""
- pass
\ No newline at end of file
+ template_dir = find_template(repo_dir)
+ logger.debug('Generating project from %s...', template_dir)
+ context = context or {}
+
+ unrendered_dir = os.path.split(template_dir)[1]
+ env = create_env_with_context(context)
+ project_dir = render_and_create_dir(unrendered_dir, context, output_dir, env, overwrite_if_exists)
+
+ # We want the Jinja path and the OS paths to match. Consequently, we'll:
+ # + CD to the template folder
+ # + Walk the path and generate the files
+ # + CD back to where we started
+ with work_in(template_dir):
+ for root, dirs, files in os.walk('.'):
+ for d in dirs:
+ unrendered_dir = os.path.join(project_dir, root, d)
+ render_and_create_dir(unrendered_dir, context, output_dir, env, overwrite_if_exists)
+
+ for f in files:
+ infile = os.path.join(root, f)
+ if is_copy_only_path(infile, context):
+ outfile_path = os.path.join(project_dir, infile)
+ logger.debug('Copying %s to %s without rendering', infile, outfile_path)
+ shutil.copyfile(infile, outfile_path)
+ shutil.copymode(infile, outfile_path)
+ continue
+ try:
+ generate_file(project_dir, infile, context, env, skip_if_file_exists)
+ except UndefinedVariableInTemplate as err:
+ if not keep_project_on_failure:
+ rmtree(project_dir)
+ raise
+
+ if accept_hooks:
+ _run_hook_from_repo_dir(repo_dir, 'post_gen_project', project_dir, context, delete_project_on_failure=not keep_project_on_failure)
+
+ return project_dir