Skip to content

Commit 2fba016

Browse files
committed
Added much better json encoding and decoding tests, and fixed bugs caught.
1 parent 466d235 commit 2fba016

File tree

3 files changed

+73
-6
lines changed

3 files changed

+73
-6
lines changed

babelapi/generator/target/python/babel_data_types.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,8 @@ def __init__(self, min_value=None, max_value=None):
9494

9595
def validate(self, val):
9696
if not isinstance(val, numbers.Integral):
97-
raise ValidationError('%r is of type %r and is not a valid integer type'
98-
% (val, type(val)))
97+
raise ValidationError('expected integer, got %s'
98+
% generic_type_name(val))
9999
elif not (self.minimum <= val <= self.maximum):
100100
raise ValidationError('%d is not within range [%d, %d]'
101101
% (val, self.minimum, self.maximum))

babelapi/generator/target/python/babel_serializers.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -99,12 +99,9 @@ def _encode_helper(cls, data_type, obj, validate_primitives=True):
9999
if field_data_type:
100100
if isinstance(field_data_type, (dt.Any, dt.Symbol)):
101101
return obj._tag
102-
elif isinstance(field_data_type, dt.PrimitiveType):
103-
val = getattr(obj, obj._tag)
104-
return cls._make_json_friendly(field_data_type, val)
105102
else:
106103
val = getattr(obj, obj._tag)
107-
return {obj._tag: cls._encode_helper(field_data_type, val)}
104+
return {obj._tag: cls._encode_helper(field_data_type, val, False)}
108105
else:
109106
return obj._tag
110107
else:

test/test_python_gen.py

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,43 @@ def test_json_encoder(self):
104104
b = '\xff' * 5
105105
self.assertEqual(JsonEncoder.encode(dt.Binary(), b), json.dumps(base64.b64encode(b)))
106106

107+
def test_json_encoder_union(self):
108+
class S(object):
109+
_field_names_ = {'f'}
110+
_fields_ = [('f', dt.String())]
111+
class U(object):
112+
_fields_ = {'a': dt.Int64(),
113+
'b': dt.Symbol(),
114+
'c': dt.Struct(S),
115+
'd': dt.List(dt.Int64())}
116+
117+
# Test primitive variant
118+
u = U()
119+
u._tag = 'a'
120+
u.a = 64
121+
self.assertEqual(JsonEncoder.encode(dt.Union(U), u), json.dumps({'a': 64}))
122+
123+
# Test symbol variant
124+
u = U()
125+
u._tag = 'b'
126+
self.assertEqual(JsonEncoder.encode(dt.Union(U), u), json.dumps('b'))
127+
128+
# Test struct variant
129+
u = U()
130+
u._tag = 'c'
131+
u.c = S()
132+
u.c.f = 'hello'
133+
self.assertEqual(JsonEncoder.encode(dt.Union(U), u), json.dumps({'c': {'f': 'hello'}}))
134+
135+
# Test list variant
136+
u = U()
137+
u._tag = 'd'
138+
u.d = [1, 2, 3, 'a']
139+
# lists should be re-validated during serialization
140+
self.assertRaises(dt.ValidationError, lambda: JsonEncoder.encode(dt.Union(U), u))
141+
u.d = [1, 2, 3, 4]
142+
self.assertEqual(JsonEncoder.encode(dt.Union(U), u), json.dumps({'d': u.d}))
143+
107144
def test_json_decoder(self):
108145
self.assertEqual(JsonDecoder.decode(dt.String(), json.dumps('abc')), 'abc')
109146
self.assertEqual(JsonDecoder.decode(dt.UInt32(), json.dumps(123)), 123)
@@ -115,3 +152,36 @@ def test_json_decoder(self):
115152
now)
116153
b = '\xff' * 5
117154
self.assertEqual(JsonDecoder.decode(dt.Binary(), json.dumps(base64.b64encode(b))), b)
155+
156+
def test_json_decoder_union(self):
157+
class S(object):
158+
_field_names_ = {'f'}
159+
_fields_ = [('f', dt.String())]
160+
class U(object):
161+
_fields_ = {'a': dt.Int64(),
162+
'b': dt.Symbol(),
163+
'c': dt.Struct(S),
164+
'd': dt.List(dt.Int64())}
165+
_tag = None
166+
def set_b(self):
167+
self._tag = 'b'
168+
169+
# Test primitive variant
170+
u = JsonDecoder.decode(dt.Union(U), json.dumps({'a': 64}))
171+
self.assertEqual(u.a, 64)
172+
173+
# Test symbol variant
174+
u = JsonDecoder.decode(dt.Union(U), json.dumps('b'))
175+
self.assertEqual(u._tag, 'b')
176+
177+
# Test struct variant
178+
u = JsonDecoder.decode(dt.Union(U), json.dumps({'c': {'f': 'hello'}}))
179+
self.assertEqual(u.c.f, 'hello')
180+
181+
# Test list variant
182+
l = [1, 2, 3, 4]
183+
u = JsonDecoder.decode(dt.Union(U), json.dumps({'d': l}))
184+
self.assertEqual(u.d, l)
185+
186+
# Raises if unknown tag
187+
self.assertRaises(dt.ValidationError, lambda: JsonDecoder.decode(dt.Union(U), json.dumps('z')))

0 commit comments

Comments
 (0)