Skip to content

Commit 9a8642a

Browse files
committed
Make into a package, split code and tests
1 parent 8372a44 commit 9a8642a

4 files changed

Lines changed: 149 additions & 145 deletions

File tree

json_minify.py

Lines changed: 0 additions & 144 deletions
This file was deleted.

json_minify/__init__.py

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
"""A port of the `JSON-minify` utility to the Python language.
2+
3+
Based on JSON.minify.js: https://github.com/getify/JSON.minify
4+
5+
Contributers:
6+
- Gerald Storer
7+
- Contributed original version
8+
- Felipe Machado
9+
- Performance optimization
10+
- Pradyun S. Gedam
11+
- Conditions and variable names changed
12+
- Reformatted tests and moved to separate file
13+
- Made into a PyPI Package
14+
"""
15+
16+
import re
17+
18+
19+
def json_minify(string, strip_space=True):
20+
tokenizer = re.compile('"|(/\*)|(\*/)|(//)|\n|\r')
21+
end_slashes_re = re.compile(r'(\\)*$')
22+
23+
in_string = False
24+
in_multi = False
25+
in_single = False
26+
27+
new_str = []
28+
index = 0
29+
30+
for match in re.finditer(tokenizer, string):
31+
32+
if not (in_multi or in_single):
33+
tmp = string[index:match.start()]
34+
if not in_string and strip_space:
35+
# replace white space as defined in standard
36+
tmp = re.sub('[ \t\n\r]+', '', tmp)
37+
new_str.append(tmp)
38+
39+
index = match.end()
40+
val = match.group()
41+
42+
if val == '"' and not (in_multi or in_single):
43+
escaped = end_slashes_re.search(string, 0, match.start())
44+
45+
# start of string or unescaped quote character to end string
46+
if not in_string or (escaped is None or len(escaped.group()) % 2 == 0): # noqa
47+
in_string = not in_string
48+
index -= 1 # include " character in next catch
49+
elif not (in_string or in_multi or in_single):
50+
if val == '/*':
51+
in_multi = True
52+
elif val == '//':
53+
in_single = True
54+
elif val == '*/' and in_multi and not (in_string or in_single):
55+
in_multi = False
56+
elif val in '\r\n' and not (in_multi or in_string) and in_single:
57+
in_single = False
58+
elif not ((in_multi or in_single) or (val in ' \r\n\t' and strip_space)): # noqa
59+
new_str.append(val)
60+
61+
new_str.append(string[index:])
62+
return ''.join(new_str)

json_minify/test_json_minify.py

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
"""Tests for json_minify
2+
"""
3+
4+
# Python 2.6+ needed to run tests
5+
import json
6+
import textwrap
7+
import unittest
8+
9+
from json_minify import json_minify
10+
11+
12+
class JsonMinifyTestCase(unittest.TestCase):
13+
"""Tests for json_minify"""
14+
15+
tests = [
16+
[
17+
'''
18+
// this is a JSON file with comments
19+
{
20+
"foo": "bar", // this is cool
21+
"bar": [
22+
"baz", "bum"
23+
],
24+
/* the rest of this document is just fluff
25+
in case you are interested. */
26+
"something": 10,
27+
"else": 20
28+
}
29+
30+
/* NOTE: You can easily strip the whitespace and comments
31+
from such a file with the JSON.minify() project hosted
32+
here on github at http://github.com/getify/JSON.minify
33+
*/''',
34+
'{"foo":"bar","bar":["baz","bum"],"something":10,"else":20}'
35+
],
36+
[
37+
'''
38+
{"/*":"*/","//":"",/*"//"*/"/*/"://
39+
"//"}''',
40+
'{"/*":"*/","//":"","/*/":"//"}'
41+
],
42+
[
43+
r'''
44+
/*
45+
this is a
46+
multi line comment */{
47+
48+
"foo"
49+
:
50+
"bar/*"// something
51+
, "b\"az":/*
52+
something else */"blah"
53+
54+
}
55+
''',
56+
r'{"foo":"bar/*","b\"az":"blah"}'
57+
],
58+
[
59+
r'''
60+
{"foo": "ba\"r//", "bar\\": "b\\\"a/*z",
61+
"baz\\\\": /* yay */ "fo\\\\\"*/o"
62+
}
63+
''',
64+
r'{"foo":"ba\"r//","bar\\":"b\\\"a/*z","baz\\\\":"fo\\\\\"*/o"}' # noqa
65+
]
66+
]
67+
68+
def template(self, in_string, expected):
69+
in_dict = json.loads(json_minify(in_string))
70+
expected_dict = json.loads(textwrap.dedent(expected))
71+
self.assertEqual(in_dict, expected_dict)
72+
73+
def test_1(self):
74+
self.template(*self.tests[0])
75+
76+
def test_2(self):
77+
self.template(*self.tests[1])
78+
79+
def test_3(self):
80+
self.template(*self.tests[2])
81+
82+
def test_4(self):
83+
self.template(*self.tests[3])
84+
85+
if __name__ == '__main__':
86+
unittest.main()

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
maintainer="Pradyun S. Gedam",
2121
maintainer_email="pradyunsg@gmail.com",
2222

23-
py_modules=["json_minify"],
23+
packages=["json_minify"],
2424

2525
license="MIT",
2626
classifiers=[

0 commit comments

Comments
 (0)