tests.test_generate_file   A
last analyzed

Complexity

Total Complexity 17

Size/Duplication

Total Lines 170
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 17
eloc 108
dl 0
loc 170
rs 10
c 0
b 0
f 0

11 Functions

Rating   Name   Duplication   Size   Complexity  
A tear_down() 0 14 4
A env() 0 6 1
A test_generate_file_does_not_translate_crlf_newlines_to_lf() 0 16 2
A test_generate_file_does_not_translate_lf_newlines_to_crlf() 0 16 2
A test_generate_file_jsonify_filter() 0 10 1
A test_generate_file() 0 12 1
A test_generate_file_verbose_template_syntax_error() 0 10 2
A test_generate_file_with_false_condition() 0 15 1
A expected_msg_regex() 0 5 1
A test_generate_file_random_ascii_string() 0 11 1
A test_generate_file_with_true_condition() 0 17 1
1
"""Tests for `generate_file` function, part of `generate_files` function workflow."""
2
import json
3
import os
4
import re
5
from pathlib import Path
6
7
import pytest
8
from jinja2 import FileSystemLoader
9
from jinja2.exceptions import TemplateSyntaxError
10
11
from cookiecutter import generate
12
from cookiecutter.environment import StrictEnvironment
13
14
15
@pytest.fixture(scope='function', autouse=True)
16
def tear_down():
17
    """
18
    Fixture. Remove the test text file which is created by the tests.
19
20
    Used for all tests in this file.
21
    """
22
    yield
23
    if os.path.exists('tests/files/cheese.txt'):
24
        os.remove('tests/files/cheese.txt')
25
    if os.path.exists('tests/files/cheese_lf_newlines.txt'):
26
        os.remove('tests/files/cheese_lf_newlines.txt')
27
    if os.path.exists('tests/files/cheese_crlf_newlines.txt'):
28
        os.remove('tests/files/cheese_crlf_newlines.txt')
29
30
31
@pytest.fixture
32
def env():
33
    """Fixture. Set Jinja2 environment settings for other tests."""
34
    environment = StrictEnvironment()
35
    environment.loader = FileSystemLoader('.')
36
    return environment
37
38
39
def test_generate_file(env):
40
    """Verify simple file is generated with rendered context data."""
41
    infile = 'tests/files/{{cookiecutter.generate_file}}.txt'
42
    generate.generate_file(
43
        project_dir=".",
44
        infile=infile,
45
        context={'cookiecutter': {'generate_file': 'cheese'}},
46
        env=env,
47
    )
48
    assert os.path.isfile('tests/files/cheese.txt')
49
    generated_text = Path('tests/files/cheese.txt').read_text()
50
    assert generated_text == 'Testing cheese'
51
52
53
def test_generate_file_jsonify_filter(env):
54
    """Verify jsonify filter works during files generation process."""
55
    infile = 'tests/files/{{cookiecutter.jsonify_file}}.txt'
56
    data = {'jsonify_file': 'cheese', 'type': 'roquefort'}
57
    generate.generate_file(
58
        project_dir=".", infile=infile, context={'cookiecutter': data}, env=env
59
    )
60
    assert os.path.isfile('tests/files/cheese.txt')
61
    generated_text = Path('tests/files/cheese.txt').read_text()
62
    assert json.loads(generated_text) == data
63
64
65
@pytest.mark.parametrize("length", (10, 40))
66
@pytest.mark.parametrize("punctuation", (True, False))
67
def test_generate_file_random_ascii_string(env, length, punctuation):
68
    """Verify correct work of random_ascii_string extension on file generation."""
69
    infile = 'tests/files/{{cookiecutter.random_string_file}}.txt'
70
    data = {'random_string_file': 'cheese'}
71
    context = {"cookiecutter": data, "length": length, "punctuation": punctuation}
72
    generate.generate_file(project_dir=".", infile=infile, context=context, env=env)
73
    assert os.path.isfile('tests/files/cheese.txt')
74
    generated_text = Path('tests/files/cheese.txt').read_text()
75
    assert len(generated_text) == length
76
77
78
def test_generate_file_with_true_condition(env):
79
    """Verify correct work of boolean condition in file name on file generation.
80
81
    This test has positive answer, so file should be rendered.
82
    """
83
    infile = (
84
        'tests/files/{% if cookiecutter.generate_file == \'y\' %}cheese.txt{% endif %}'
85
    )
86
    generate.generate_file(
87
        project_dir=".",
88
        infile=infile,
89
        context={'cookiecutter': {'generate_file': 'y'}},
90
        env=env,
91
    )
92
    assert os.path.isfile('tests/files/cheese.txt')
93
    generated_text = Path('tests/files/cheese.txt').read_text()
94
    assert generated_text == 'Testing that generate_file was y'
95
96
97
def test_generate_file_with_false_condition(env):
98
    """Verify correct work of boolean condition in file name on file generation.
99
100
    This test has negative answer, so file should not be rendered.
101
    """
102
    infile = (
103
        'tests/files/{% if cookiecutter.generate_file == \'y\' %}cheese.txt{% endif %}'
104
    )
105
    generate.generate_file(
106
        project_dir=".",
107
        infile=infile,
108
        context={'cookiecutter': {'generate_file': 'n'}},
109
        env=env,
110
    )
111
    assert not os.path.isfile('tests/files/cheese.txt')
112
113
114
@pytest.fixture
115
def expected_msg_regex():
116
    """Fixture. Used to ensure that exception generated text contain full data."""
117
    return re.compile(
118
        'Missing end of comment tag\n'
119
        ' {2}File "(.[/\\\\])*tests[/\\\\]files[/\\\\]syntax_error.txt", line 1\n'
120
        ' {4}I eat {{ syntax_error }} {# this comment is not closed}'
121
    )
122
123
124
def test_generate_file_verbose_template_syntax_error(env, expected_msg_regex):
125
    """Verify correct exception raised on syntax error in file before generation."""
126
    with pytest.raises(TemplateSyntaxError) as exception:
127
        generate.generate_file(
128
            project_dir=".",
129
            infile='tests/files/syntax_error.txt',
130
            context={'syntax_error': 'syntax_error'},
131
            env=env,
132
        )
133
    assert expected_msg_regex.match(str(exception.value))
134
135
136
def test_generate_file_does_not_translate_lf_newlines_to_crlf(env, tmp_path):
137
    """Verify that file generation use same line ending, as in source file."""
138
    infile = 'tests/files/{{cookiecutter.generate_file}}_lf_newlines.txt'
139
    generate.generate_file(
140
        project_dir=".",
141
        infile=infile,
142
        context={'cookiecutter': {'generate_file': 'cheese'}},
143
        env=env,
144
    )
145
146
    # this generated file should have a LF line ending
147
    gf = 'tests/files/cheese_lf_newlines.txt'
148
    with Path(gf).open(encoding='utf-8', newline='') as f:
149
        simple_text = f.readline()
150
    assert simple_text == 'newline is LF\n'
151
    assert f.newlines == '\n'
152
153
154
def test_generate_file_does_not_translate_crlf_newlines_to_lf(env):
155
    """Verify that file generation use same line ending, as in source file."""
156
    infile = 'tests/files/{{cookiecutter.generate_file}}_crlf_newlines.txt'
157
    generate.generate_file(
158
        project_dir=".",
159
        infile=infile,
160
        context={'cookiecutter': {'generate_file': 'cheese'}},
161
        env=env,
162
    )
163
164
    # this generated file should have a CRLF line ending
165
    gf = 'tests/files/cheese_crlf_newlines.txt'
166
    with Path(gf).open(encoding='utf-8', newline='') as f:
167
        simple_text = f.readline()
168
    assert simple_text == 'newline is CRLF\r\n'
169
    assert f.newlines == '\r\n'
170