Skip to content

Commit 20bf54f

Browse files
committed
is_array_index 支持 string order
补充 expand & restore 的测试
1 parent 610a945 commit 20bf54f

7 files changed

Lines changed: 60 additions & 33 deletions

File tree

fixture/files/raw.2.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
["a", "ab", "b", "a", "ab", "b", "a", "ab", "b", "a", "ab", "b"]
2+
["c", "ab", "b", "a", "ab", "b", "a", "ab", "b", "a", "ab", "c"]

jsoncsv/jsontool.py

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
from __future__ import unicode_literals
66

77
import json
8-
98
from copy import deepcopy
109
from itertools import groupby
1110
from operator import itemgetter
@@ -26,7 +25,6 @@ def gen_leaf(root, path=None):
2625
if path is None:
2726
path = []
2827

29-
# the leaf
3028
if not isinstance(root, (dict, list)) or not root:
3129
leaf = (path, root)
3230
yield leaf
@@ -36,7 +34,6 @@ def gen_leaf(root, path=None):
3634
items = root.iteritems()
3735
else:
3836
items = root.items()
39-
4037
else:
4138
items = enumerate(root)
4239

@@ -47,14 +44,17 @@ def gen_leaf(root, path=None):
4744
yield leaf
4845

4946

50-
def is_array(keys, ensure_str=True):
51-
copy_keys = list(deepcopy(keys))
52-
int_keys = list(range(len(copy_keys)))
53-
if copy_keys == int_keys:
47+
def is_array_index(keys, enable_str=True):
48+
keys = list(deepcopy(keys))
49+
# 不强调有序
50+
key_map = {key: True for key in keys}
51+
int_keys = range(len(keys))
52+
53+
if all(key in key_map for key in int_keys):
5454
return True
55-
if ensure_str:
56-
str_keys = list(map(str, int_keys))
57-
if copy_keys == str_keys:
55+
56+
if enable_str:
57+
if all(str(key) in key_map for key in int_keys):
5858
return True
5959
return False
6060

@@ -84,7 +84,7 @@ def from_leaf(leafs):
8484
child.append((head, _child))
8585

8686
child_keys = map(_get_head, child)
87-
if is_array(child_keys):
87+
if is_array_index(child_keys):
8888
child.sort(key=lambda x: int(x[0]))
8989
return list(map(_get_leaf, child))
9090

@@ -140,6 +140,7 @@ def convert_json(fin, fout, func, separator=".", safe=False, json_array=False):
140140

141141
# default: read json objects from each line
142142
def gen_objs():
143+
print(type(fin))
143144
for line in fin:
144145
obj = json.loads(line)
145146
yield obj
@@ -161,6 +162,7 @@ def gen_objs_from_array():
161162
content = json.dumps(new, ensure_ascii=False)
162163
if PY2:
163164
fout.write(content.encode('utf-8'))
165+
fout.write('\n'.encode('utf-8'))
164166
else:
165167
fout.write(content)
166-
fout.write(str('\n'))
168+
fout.write('\n')

jsoncsv/main.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,15 @@
77
from jsoncsv import dumptool
88
from jsoncsv.dumptool import dump_excel
99
from jsoncsv.jsontool import convert_json
10-
from jsoncsv.utils import separator_type
10+
from jsoncsv.utils import unit_char
11+
12+
13+
def separator_type(sep):
14+
if len(sep) != 1:
15+
raise click.BadOptionUsage('separator can only be a char')
16+
if sep == unit_char:
17+
raise click.BadOptionUsage('separator can not be `\\` ')
18+
return sep
1119

1220

1321
@click.command()

jsoncsv/utils.py

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,9 @@
22
# author@alingse
33
# 2016.11.20
44

5-
import click
6-
7-
__all__ = []
8-
95
unit_char = '\\'
106

117

12-
def separator_type(sep):
13-
if len(sep) > 1:
14-
raise click.BadOptionUsage('separator can only be a char')
15-
if sep == unit_char:
16-
raise click.BadOptionUsage('separator can not be `\\` ')
17-
return sep
18-
19-
208
def encode_safe_key(path, separator):
219
path = [p.replace(unit_char, unit_char * 2) for p in path]
2210
separator = unit_char + separator

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
setup(
1414
name='jsoncsv',
15-
version='2.2.2',
15+
version='2.2.3',
1616
url='https://github.com/alingse/jsoncsv',
1717
description='A command tool easily convert json file to csv or xlsx.',
1818
long_description=readme,

tests/test_jsoncsv.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
# coding=utf-8
22
# author@alingse
33
# 2016.08.09
4-
4+
import io
5+
import json
56
import unittest
67
from click.testing import CliRunner
78

@@ -21,3 +22,18 @@ def test_jsoncsv_expand_with_json_array(self):
2122
args = ['-e', 'fixture/files/raw.1.json', 'fixture/files/tmp.expand.1.json', '-A']
2223
result = runner.invoke(jsoncsv, args=args)
2324
assert result.exit_code == 0
25+
26+
def test_jsoncsv_expand_restore(self):
27+
runner = CliRunner(echo_stdin=True)
28+
result = runner.invoke(jsoncsv, args=['-e', 'fixture/files/raw.2.json', 'fixture/files/tmp.expand.2.json'])
29+
assert result.exit_code == 0
30+
result = runner.invoke(jsoncsv, args=['-r', 'fixture/files/tmp.expand.2.json', 'fixture/files/tmp.restore.2.json'])
31+
assert result.exit_code == 0
32+
33+
with io.open('fixture/files/raw.2.json', 'r') as f:
34+
input_data = [json.loads(line) for line in f]
35+
36+
with io.open('fixture/files/tmp.restore.2.json', 'r') as f:
37+
resotre_data = [json.loads(line) for line in f]
38+
39+
self.assertEqual(input_data, resotre_data)

tests/test_jsontool.py

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
from jsoncsv import PY2
1010
from jsoncsv.jsontool import expand, restore
11-
from jsoncsv.jsontool import is_array
11+
from jsoncsv.jsontool import is_array_index
1212
from jsoncsv.jsontool import convert_json
1313

1414

@@ -63,11 +63,13 @@ def test_complex(self):
6363

6464
self.assertListEqual(s[4], _s[4])
6565

66-
def test_is_array(self):
67-
assert is_array([0, 1, 2, 3])
68-
assert is_array(['0', '1', '2', '3'])
69-
assert not is_array([1, 2, 3])
70-
assert not is_array(['0', 1, 2])
66+
def test_is_array_index(self):
67+
self.assertTrue(is_array_index([0, 1, 2, 3]))
68+
self.assertTrue(is_array_index(['0', '1', '2', '3']))
69+
# string order
70+
self.assertTrue(is_array_index(['0', '1', '10', '2', '3', '4', '5', '6', '7', '8', '9']))
71+
self.assertFalse(is_array_index([1, 2, 3]))
72+
self.assertFalse(is_array_index(['0', 1, 2]))
7173

7274
def test_unicode(self):
7375
data = [
@@ -90,6 +92,15 @@ def test_expand_with_safe(self):
9092
origin = restore(expobj, safe=True)
9193
self.assertEqual(origin, data)
9294

95+
def test_expand_and_restore(self):
96+
data = ["a", "ab", "b"] * 4
97+
expobj = expand(data)
98+
self.assertEqual(expobj["0"], "a")
99+
self.assertEqual(expobj["1"], "ab")
100+
101+
origin = restore(expobj)
102+
self.assertEqual(data, origin)
103+
93104

94105
class TestConvertJSON(unittest.TestCase):
95106

0 commit comments

Comments
 (0)