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