Skip to content

Commit b719ffb

Browse files
committed
Make tests for #20, fix #16.
1 parent 66f8a7a commit b719ffb

File tree

3 files changed

+143
-74
lines changed

3 files changed

+143
-74
lines changed

README.md

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@ way, described below:
66
* all lines are indented in uniform manner, with 4 spaces per level
77
* neighbouring empty lines are collapsed to at most two empty lines
88
* curly braces placement follows Java convention
9-
* whitespaces are collapsed, except in comments an quotation marks
10-
* whitespaces in variable designators are removed: `${ my_variable }` is collapsed to `${my_variable}`
9+
* whitespaces are collapsed, except in comments and quotation marks
1110

1211
## Installation
1312

@@ -39,6 +38,16 @@ optional arguments:
3938
backup original config file
4039
```
4140

41+
## Reporting bugs
42+
43+
Please create issue under https://github.com/slomkowski/nginx-config-formatter/issues.
44+
Be sure to add config snippets to reproduce the issue, preferably:
45+
46+
* snippet do be formatted
47+
* actual result with invalid formatting
48+
* desired result
49+
50+
4251
## Credits
4352

4453
Copyright 2016 Michał Słomkowski @ 1CONNECT. License: Apache 2.0.

nginxfmt.py

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -214,25 +214,26 @@ def _clean_lines(self, orig_lines) -> list:
214214
line = self._apply_variable_template_tags(line)
215215
if line == "":
216216
cleaned_lines.append("")
217-
continue
217+
elif line == "};":
218+
cleaned_lines.append("}")
219+
elif line.startswith("#"):
220+
cleaned_lines.append(self._strip_variable_template_tags(line))
218221
else:
219-
if line.startswith("#"):
220-
cleaned_lines.append(self._strip_variable_template_tags(line))
222+
q, c = self._count_multi_semicolon(line)
223+
if q == 1 and c > 1:
224+
ml = self._multi_semicolon(line)
225+
cleaned_lines.extend(self._clean_lines(ml.splitlines()))
226+
elif q != 1 and c > 1:
227+
newlines = line.split(";")
228+
lines_to_add = self._clean_lines(["".join([ln, ";"]) for ln in newlines if ln != ""])
229+
cleaned_lines.extend(lines_to_add)
221230
else:
222-
q, c = self._count_multi_semicolon(line)
223-
if q == 1 and c > 1:
224-
ml = self._multi_semicolon(line)
225-
cleaned_lines.extend(self._clean_lines(ml.splitlines()))
226-
elif q != 1 and c > 1:
227-
newlines = line.split(";")
228-
cleaned_lines.extend(self._clean_lines(["".join([ln, ";"]) for ln in newlines if ln != ""]))
231+
if line.startswith("rewrite"):
232+
cleaned_lines.append(self._strip_variable_template_tags(line))
229233
else:
230-
if line.startswith("rewrite"):
231-
cleaned_lines.append(self._strip_variable_template_tags(line))
232-
else:
233-
cleaned_lines.extend(
234-
[self._strip_variable_template_tags(ln).strip() for ln in re.split(r"([{}])", line) if
235-
ln != ""])
234+
cleaned_lines.extend(
235+
[self._strip_variable_template_tags(ln).strip() for ln in re.split(r"([{}])", line) if
236+
ln != ""])
236237
return cleaned_lines
237238

238239
@staticmethod

test_nginxfmt.py

Lines changed: 115 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,18 @@ def __init__(self, method_name: str = ...) -> None:
1919
super().__init__(method_name)
2020
logging.basicConfig(level=logging.DEBUG) # todo fix logging in debug
2121

22-
def _check_formatting(self, original_text: str, formatted_text: str):
22+
def check_formatting(self, original_text: str, formatted_text: str):
2323
self.assertMultiLineEqual(formatted_text, self.fmt.format_string(original_text))
2424

25+
def check_stays_the_same(self, text: str):
26+
self.assertMultiLineEqual(text, self.fmt.format_string(text))
27+
2528
def _check_variable_tags_symmetry(self, text):
2629
self.assertMultiLineEqual(text,
2730
self.fmt._strip_variable_template_tags(self.fmt._apply_variable_template_tags(text)))
2831

2932
def test_collapse_variable1(self):
30-
self._check_formatting(" lorem ipsum ${ dol } amet", "lorem ipsum ${dol} amet\n")
33+
self.check_formatting(" lorem ipsum ${ dol } amet", "lorem ipsum ${dol} amet\n")
3134

3235
def test_join_opening_parenthesis(self):
3336
self.assertEqual(["foo", "bar {", "johan {", "tee", "ka", "}"],
@@ -125,7 +128,7 @@ def test_variable_template_tags(self):
125128
self._check_variable_tags_symmetry("lorem ipsum ${dolor} $amet\nother $var and ${var_name2}")
126129

127130
def test_umlaut_in_string(self):
128-
self._check_formatting(
131+
self.check_formatting(
129132
"# Statusseite für Monitoring freigeben \n" +
130133
"# line above contains german umlaut causing problems \n" +
131134
"location /nginx_status {\n" +
@@ -145,23 +148,23 @@ def test_umlaut_in_string(self):
145148
)
146149

147150
def test_empty_lines_removal(self):
148-
self._check_formatting(
151+
self.check_formatting(
149152
"\n foo bar {\n" +
150153
" lorem ipsum;\n" +
151154
"}\n\n\n",
152155
"foo bar {\n" +
153156
" lorem ipsum;\n" +
154157
"}\n")
155158

156-
self._check_formatting(
159+
self.check_formatting(
157160
"\n foo bar {\n\n\n\n\n\n" +
158161
" lorem ipsum;\n" +
159162
"}\n\n\n",
160163
"foo bar {\n\n\n" +
161164
" lorem ipsum;\n" +
162165
"}\n")
163166

164-
self._check_formatting(
167+
self.check_formatting(
165168
" foo bar {\n" +
166169
" lorem ipsum;\n" +
167170
" kee {\n" +
@@ -175,46 +178,46 @@ def test_empty_lines_removal(self):
175178
"}\n")
176179

177180
def test_template_variables_with_dollars1(self):
178-
self._check_formatting('server {\n' +
179-
' # commented ${line} should not be touched\n' +
180-
'listen 80 default_server;\n' +
181-
'server_name localhost;\n' +
182-
'location / {\n' +
183-
'proxy_set_header X-User-Auth "In ${cookie_access_token} ${ other}";\n' +
184-
'proxy_set_header X-User-Other "foo ${bar}";\n' +
185-
'}\n' +
186-
'}',
187-
'server {\n' +
188-
' # commented ${line} should not be touched\n' +
189-
' listen 80 default_server;\n' +
190-
' server_name localhost;\n' +
191-
' location / {\n' +
192-
' proxy_set_header X-User-Auth "In ${cookie_access_token} ${ other}";\n' +
193-
' proxy_set_header X-User-Other "foo ${bar}";\n' +
194-
' }\n' +
195-
'}\n')
181+
self.check_formatting('server {\n' +
182+
' # commented ${line} should not be touched\n' +
183+
'listen 80 default_server;\n' +
184+
'server_name localhost;\n' +
185+
'location / {\n' +
186+
'proxy_set_header X-User-Auth "In ${cookie_access_token} ${ other}";\n' +
187+
'proxy_set_header X-User-Other "foo ${bar}";\n' +
188+
'}\n' +
189+
'}',
190+
'server {\n' +
191+
' # commented ${line} should not be touched\n' +
192+
' listen 80 default_server;\n' +
193+
' server_name localhost;\n' +
194+
' location / {\n' +
195+
' proxy_set_header X-User-Auth "In ${cookie_access_token} ${ other}";\n' +
196+
' proxy_set_header X-User-Other "foo ${bar}";\n' +
197+
' }\n' +
198+
'}\n')
196199

197200
def test_template_variables_with_dollars2(self):
198-
self._check_formatting(' some_tag { with_templates "my ${var} and other ${ invalid_variable_use } "; }\n' +
199-
'# in my line\n',
200-
'some_tag {\n' +
201-
' with_templates "my ${var} and other ${ invalid_variable_use } ";\n' +
202-
'}\n' +
203-
'# in my line\n')
201+
self.check_formatting(' some_tag { with_templates "my ${var} and other ${ invalid_variable_use } "; }\n' +
202+
'# in my line\n',
203+
'some_tag {\n' +
204+
' with_templates "my ${var} and other ${ invalid_variable_use } ";\n' +
205+
'}\n' +
206+
'# in my line\n')
204207

205208
def test_backslash3(self):
206-
self._check_formatting('location ~ /\.ht {\n' +
207-
'deny all;\n' +
208-
'}',
209-
'location ~ /\.ht {\n' +
210-
' deny all;\n' +
211-
'}\n')
209+
self.check_formatting('location ~ /\.ht {\n' +
210+
'deny all;\n' +
211+
'}',
212+
'location ~ /\.ht {\n' +
213+
' deny all;\n' +
214+
'}\n')
212215

213216
def test_backslash2(self):
214217
"""If curly braces are withing quotation marks, we treat them as part of the string, not syntax structure.
215218
Writing '${ var }' is not valid in nginx anyway, so we slip collapsing these altogether. May be changed in
216219
the future. """
217-
self._check_formatting(
220+
self.check_formatting(
218221
' tag { wt ~ /\.ht \t "my ${some some} and ~ /\.ht \tother ${comething in curly braces } "; }\n' +
219222
'# in my line\n',
220223

@@ -224,14 +227,14 @@ def test_backslash2(self):
224227
'# in my line\n')
225228

226229
def test_multi_semicolon(self):
227-
self._check_formatting('location /a { \n' +
228-
'allow 127.0.0.1; allow 10.0.0.0/8; deny all; \n' +
229-
'}\n',
230-
'location /a {\n' +
231-
' allow 127.0.0.1;\n' +
232-
' allow 10.0.0.0/8;\n' +
233-
' deny all;\n' +
234-
'}\n')
230+
self.check_formatting('location /a { \n' +
231+
'allow 127.0.0.1; allow 10.0.0.0/8; deny all; \n' +
232+
'}\n',
233+
'location /a {\n' +
234+
' allow 127.0.0.1;\n' +
235+
' allow 10.0.0.0/8;\n' +
236+
' deny all;\n' +
237+
'}\n')
235238

236239
def test_loading_utf8_file(self):
237240
tmp_file = pathlib.Path(tempfile.mkstemp('utf-8')[1])
@@ -248,25 +251,81 @@ def test_loading_latin1_file(self):
248251
tmp_file.unlink()
249252

250253
def test_issue_15(self):
251-
self._check_formatting(
254+
self.check_formatting(
252255
'section { server_name "~^(?<tag>[0-9a-f]{8}\-[0-9a-f]{4}\-[0-9a-f]{4}\-[0-9a-f]{4}\-[0-9a-f]{12})\.a\.b\.com$"; }',
253256
'section {\n server_name "~^(?<tag>[0-9a-f]{8}\-[0-9a-f]{4}\-[0-9a-f]{4}\-[0-9a-f]{4}\-[0-9a-f]{12})\.a\.b\.com$";\n}\n')
254257

255258
def test_issue_11(self):
256-
self._check_formatting(" # 3 spaces\n" +
257-
"# 2 spaces\n" +
258-
" # 1 space",
259-
"# 3 spaces\n" +
260-
"# 2 spaces\n" +
261-
"# 1 space\n")
259+
self.check_formatting(" # 3 spaces\n" +
260+
"# 2 spaces\n" +
261+
" # 1 space",
262+
"# 3 spaces\n" +
263+
"# 2 spaces\n" +
264+
"# 1 space\n")
262265

263266
# everything after # is left as is (except trimming trailing whitespaces)
264-
self._check_formatting(""" #if (!-f $request_filename) {
267+
self.check_formatting(""" #if (!-f $request_filename) {
265268
# rewrite ^/static/?(.*)$ /static.php?resource=$1 last;
266269
#""",
267-
"#if (!-f $request_filename) {\n" +
268-
"# rewrite ^/static/?(.*)$ /static.php?resource=$1 last;\n" +
269-
"#\n")
270+
"#if (!-f $request_filename) {\n" +
271+
"# rewrite ^/static/?(.*)$ /static.php?resource=$1 last;\n" +
272+
"#\n")
273+
274+
def test_issue_20_1(self):
275+
self.check_stays_the_same("# comment 1\n" +
276+
"tag {\n" +
277+
" # comment 2\n" +
278+
" code;\n" +
279+
" # comment 3\n" +
280+
" subtag {\n" +
281+
" code;\n" +
282+
" # comment 4\n" +
283+
" #\n" +
284+
" }\n" +
285+
" # comment 5\n" +
286+
"}\n")
287+
288+
def test_issue_20_2(self):
289+
self.check_formatting(
290+
"location /nginx_status {\n" +
291+
"# Don't break \n" +
292+
" stub_status on;\n" +
293+
" access_log off;\n" +
294+
" allow 127.0.0.1;\n" +
295+
" deny all;\n" +
296+
"}",
297+
"location /nginx_status {\n" +
298+
" # Don't break\n" +
299+
" stub_status on;\n" +
300+
" access_log off;\n" +
301+
" allow 127.0.0.1;\n" +
302+
" deny all;\n" +
303+
"}\n"
304+
)
305+
self.check_formatting(
306+
"location /nginx_status {\n" +
307+
"# Don\"t break \n" +
308+
" stub_status on;\n" +
309+
" access_log off;\n" +
310+
" allow 127.0.0.1;\n" +
311+
" deny all;\n" +
312+
"}",
313+
"location /nginx_status {\n" +
314+
" # Don\"t break\n" +
315+
" stub_status on;\n" +
316+
" access_log off;\n" +
317+
" allow 127.0.0.1;\n" +
318+
" deny all;\n" +
319+
"}\n"
320+
)
321+
322+
def test_issue_16(self):
323+
self.check_formatting(
324+
"location /example { allow 192.168.0.0/16; deny all; }",
325+
"location /example {\n"
326+
" allow 192.168.0.0/16;\n"
327+
" deny all;\n"
328+
"}\n")
270329

271330

272331
if __name__ == '__main__':

0 commit comments

Comments
 (0)