Completed
Push — master ( 956350...005733 )
by Ramon
01:19
created

TestJsons.test_dump_object_strip_privates()   A

Complexity

Conditions 1

Size

Total Lines 13
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 11
nop 1
dl 0
loc 13
rs 9.85
c 0
b 0
f 0
1
from enum import Enum
2
from typing import List, Tuple
3
from unittest.case import TestCase
4
import datetime
5
import jsons
6
import json
7
from jsons import JsonSerializable, KEY_TRANSFORMER_CAMELCASE
8
from jsons._common_impl import snakecase, camelcase, pascalcase, lispcase
9
from jsons.deserializers import KEY_TRANSFORMER_SNAKECASE
10
11
12
class TestJsons(TestCase):
13
14
    def test_dump_str(self):
15
        self.assertEqual('some string', jsons.dump('some string'))
16
17
    def test_dump_int(self):
18
        self.assertEqual(123, jsons.dump(123))
19
20
    def test_dump_float(self):
21
        self.assertEqual(123.456, jsons.dump(123.456))
22
23
    def test_dump_bool(self):
24
        self.assertEqual(True, jsons.dump(True))
25
26
    def test_dump_dict(self):
27
        d = datetime.datetime(year=2018, month=7, day=8, hour=21, minute=34)
28
        dict_ = {'a': {'b': {'c': {'d': d}}}}
29
        expectation = {'a': {'b': {'c': {'d': '2018-07-08T21:34:00Z'}}}}
30
        self.assertEqual(expectation, jsons.dump(dict_))
31
32
    def test_dump_none(self):
33
        self.assertEqual(None, jsons.dump(None))
34
35
    def test_dump_datetime(self):
36
        d = datetime.datetime(year=2018, month=7, day=8, hour=21, minute=34)
37
        self.assertEqual('2018-07-08T21:34:00Z', jsons.dump(d))
38
39
    def test_dump_datetime_with_microseconds(self):
40
        d = datetime.datetime(year=2018, month=7, day=8, hour=21, minute=34,
41
                              microsecond=123456)
42
        self.assertEqual('2018-07-08T21:34:00.123456Z', jsons.dump(d))
43
44
    def test_dump_enum(self):
45
        class E(Enum):
46
            x = 1
47
            y = 2
48
        self.assertEqual('x', jsons.dump(E.x))
49
        self.assertEqual(2, jsons.dump(E.y, use_enum_name=False))
50
51
    def test_dump_list(self):
52
        d = datetime.datetime(year=2018, month=7, day=8, hour=21, minute=34)
53
        l = [1, 2, 3, [4, 5, [d]]]
54
        self.assertEqual([1, 2, 3, [4, 5, ['2018-07-08T21:34:00Z']]],
55
                         jsons.dump(l))
56
57
    def test_dump_tuple(self):
58
        dat = datetime.datetime(year=2018, month=7, day=8, hour=21, minute=34)
59
        tup = (1, 2, 3, [4, 5, (dat,)])
60
        self.assertEqual([1, 2, 3, [4, 5, ['2018-07-08T21:34:00Z']]],
61
                         jsons.dump(tup))
62
63
    def test_dump_object(self):
64
        class A:
65
            def __init__(self):
66
                self.name = 'A'
67
68
        class B:
69
            def __init__(self, a):
70
                self.a = a
71
                self.name = 'B'
72
73
        b = B(A())
74
        self.assertEqual({'name': 'B', 'a': {'name': 'A'}}, jsons.dump(b))
75
76
    def test_dump_object_properties(self):
77
        class A:
78
            @property
79
            def x(self):
80
                return 123
81
82
            def y(self):
83
                return 456  # Not to be serialized.
84
85
        a = A()
86
        self.assertEqual({'x': 123}, jsons.dump(a))
87
        self.assertEqual({}, jsons.dump(a, strip_properties=True))
88
89
    def test_dump_object_strip_nulls(self):
90
        class A:
91
            def __init__(self):
92
                self.name = None  # This will be stripped.
93
94
        class B:
95
            def __init__(self, a):
96
                self.a = a
97
                self.name = 'B'
98
99
        b = B(A())
100
        dumped = jsons.dump(b, strip_nulls=True)
101
        self.assertEqual({'name': 'B', 'a': {}}, dumped)
102
103
    def test_dump_object_strip_privates(self):
104
        class A:
105
            def __init__(self):
106
                self._name = 'A'  # This will be stripped.
107
108
        class B:
109
            def __init__(self, a):
110
                self.a = a
111
                self._name = 'B'  # This will be stripped.
112
113
        b = B(A())
114
        dumped = jsons.dump(b, strip_privates=True)
115
        self.assertEqual({'a': {}}, dumped)
116
117
    def test_load_str(self):
118
        self.assertEqual('some string', jsons.load('some string'))
119
120
    def test_load_int(self):
121
        self.assertEqual(123, jsons.load(123))
122
123
    def test_load_float(self):
124
        self.assertEqual(123.456, jsons.load(123.456))
125
126
    def test_load_bool(self):
127
        self.assertEqual(True, jsons.load(True))
128
129
    def test_load_dict(self):
130
        dumped = {'a': {'b': {'c': {'d': '2018-07-08T21:34:00Z'}}}}
131
        loaded = jsons.load(dumped)
132
        self.assertEqual(loaded['a']['b']['c']['d'].year, 2018)
133
        self.assertEqual(loaded['a']['b']['c']['d'].month, 7)
134
        self.assertEqual(loaded['a']['b']['c']['d'].day, 8)
135
        self.assertEqual(loaded['a']['b']['c']['d'].hour, 21)
136
        self.assertEqual(loaded['a']['b']['c']['d'].minute, 34)
137
        self.assertEqual(loaded['a']['b']['c']['d'].second, 0)
138
139
    def test_load_none(self):
140
        self.assertEqual(None, jsons.load(None))
141
142
    def test_load_datetime(self):
143
        dat = datetime.datetime(year=2018, month=7, day=8, hour=21, minute=34)
144
        self.assertEqual(dat, jsons.load('2018-07-08T21:34:00Z'))
145
146
    def test_load_enum(self):
147
        class E(Enum):
148
            x = 1
149
            y = 2
150
151
        self.assertEqual(E.x, jsons.load('x', E))
152
        self.assertEqual(E.y, jsons.load(2, E, use_enum_name=False))
153
154
    def test_load_list(self):
155
        dat = datetime.datetime(year=2018, month=7, day=8, hour=21, minute=34)
156
        list_ = [1, 2, 3, [4, 5, [dat]]]
157
        expectation = [1, 2, 3, [4, 5, ['2018-07-08T21:34:00Z']]]
158
        self.assertEqual(list_, jsons.load(expectation))
159
160
    def test_load_tuple(self):
161
        dat = datetime.datetime(year=2018, month=7, day=8, hour=21, minute=34)
162
        tup = (1, ([dat],))
163
        expectation = (1, (['2018-07-08T21:34:00Z'],))
164
        cls = Tuple[int, Tuple[List[datetime.datetime]]]
165
        self.assertEqual(tup, jsons.load(expectation, cls))
166
167
    def test_load_object(self):
168
        class A:
169
            def __init__(self):
170
                self.name = 'A'
171
172
        class B:
173
            def __init__(self, a: A):
174
                self.a = a
175
                self.name = 'B'
176
177
        b = B(A())
178
        loaded_b = jsons.load({'name': 'B', 'a': {'name': 'A'}}, B)
179
        self.assertEqual(b.name, loaded_b.name)
180
        self.assertEqual(b.a.name, loaded_b.a.name)
181
182
    def test_load_object_with_default_value(self):
183
        class A:
184
            def __init__(self, x, y = 2):
185
                self.x = x
186
                self.y = y
187
188
        a = A(1)
189
        loaded_a = jsons.load({'x': 1}, A)
190
        self.assertEqual(a.x, loaded_a.x)
191
        self.assertEqual(a.y, loaded_a.y)
192
193
    def test_dump_load_object_deep(self):
194
        class A:
195
            def __init__(self):
196
                self.name = 'A'
197
198
        class B:
199
            def __init__(self, list_a: List[A],
200
                         list_dates: List[datetime.datetime]):
201
                self.list_a = list_a
202
                self.list_dates = list_dates
203
                self.name = 'B'
204
205
        class C:
206
            def __init__(self, list_b: List[B]):
207
                self.list_b = list_b
208
209
        c = C([B([A(), A()], []),
210
               B([], [datetime.datetime.now(), datetime.datetime.now()])])
211
        dumped_c = jsons.dump(c)
212
        loaded_c = jsons.load(dumped_c, C)
213
        self.assertEqual(loaded_c.list_b[0].name, 'B')
214
        self.assertEqual(loaded_c.list_b[0].list_a[0].name, 'A')
215
        self.assertEqual(loaded_c.list_b[0].list_a[1].name, 'A')
216
        self.assertEqual(loaded_c.list_b[1].list_dates[0].year,
217
                         c.list_b[1].list_dates[0].year)
218
        self.assertEqual(loaded_c.list_b[1].list_dates[0].month,
219
                         c.list_b[1].list_dates[0].month)
220
        self.assertEqual(loaded_c.list_b[1].list_dates[0].day,
221
                         c.list_b[1].list_dates[0].day)
222
        self.assertEqual(loaded_c.list_b[1].list_dates[0].hour,
223
                         c.list_b[1].list_dates[0].hour)
224
        self.assertEqual(loaded_c.list_b[1].list_dates[0].minute,
225
                         c.list_b[1].list_dates[0].minute)
226
        self.assertEqual(loaded_c.list_b[1].list_dates[0].second,
227
                         c.list_b[1].list_dates[0].second)
228
229
    def test_load_object_properties(self):
230
        class WithoutSetter:
231
            @property
232
            def x(self):
233
                return 123
234
235
        class WithSetter:
236
            def __init__(self):
237
                self.__x = 123
238
            @property
239
            def x(self):
240
                return self.__x
241
242
            @x.setter
243
            def x(self, x):
244
                self.__x = x
245
246
        loaded1 = jsons.load({'x': 123}, WithoutSetter)
247
        self.assertEqual(loaded1.x, 123)
248
249
        loaded2 = jsons.load({'x': 456}, WithSetter)
250
        self.assertEqual(loaded2.x, 456)
251
252
    def test_dumps(self):
253
        class A:
254
            def __init__(self):
255
                self.name = 'A'
256
257
        class B:
258
            def __init__(self, a: A):
259
                self.a = a
260
                self.name = 'B'
261
262
        sdumped = jsons.dumps(B(A()))
263
        s = json.dumps({'a': {'name': 'A'}, 'name': 'B'})
264
        self.assertEqual(s, sdumped)
265
266
    def test_loads(self):
267
        class A:
268
            def __init__(self):
269
                self.name = 'A'
270
271
        class B:
272
            def __init__(self, a: A):
273
                self.a = a
274
                self.name = 'B'
275
276
        s = json.dumps({'a': {'name': 'A'}, 'name': 'B'})
277
        loaded_dict = jsons.loads(s)
278
        self.assertEqual('B', loaded_dict['name'])
279
        self.assertEqual('A', loaded_dict['a']['name'])
280
281
        loaded_obj = jsons.loads(s, B)
282
        self.assertEqual('B', loaded_obj.name)
283
        self.assertEqual('A', loaded_obj.a.name)
284
285
    def test_jsonserializable(self):
286
        class Person(JsonSerializable):
287
            def __init__(self, name, age):
288
                self.name = name
289
                self.age = age
290
291
        person = Person('John', 65)
292
        person_json = person.json
293
        person_loaded = Person.from_json(person_json)
294
295
        self.assertEqual(person_json, {'name': 'John', 'age': 65})
296
        self.assertEqual(person.dump(), {'name': 'John', 'age': 65})
297
        self.assertEqual(person_loaded.name, 'John')
298
        self.assertEqual(person_loaded.age, 65)
299
        self.assertEqual(Person.load(person_json).name, 'John')
300
        self.assertEqual(Person.load(person_json).age, 65)
301
302
    def test_jsonserializable_with_kwargs(self):
303
        custom_serializable = JsonSerializable\
304
            .with_dump(key_transformer=KEY_TRANSFORMER_CAMELCASE)\
305
            .with_load(key_transformer=KEY_TRANSFORMER_SNAKECASE)
306
307
        class Person(custom_serializable):
308
            def __init__(self, my_name):
309
                self.my_name = my_name
310
311
        person = Person('John')
312
        person_json = person.json  # should have camelCase
313
        person_loaded = Person.from_json(person_json)  # should have snake_case
314
315
        self.assertEqual(person_json, {'myName': 'John'})
316
        self.assertEqual(person_loaded.my_name, 'John')
317
        self.assertTrue(isinstance(person_loaded, Person))
318
319
    def test_case_transformers(self):
320
        camelcase_str = 'camelCase'
321
        snakecase_str = 'snake_case'
322
        pascalcase_str = 'Pascal_case'
323
        pascalcase_str2 = 'ABcDe'
324
        lispcase_str = 'lisp-case'
325
326
        self.assertEqual(camelcase(camelcase_str), 'camelCase')
327
        self.assertEqual(camelcase(snakecase_str), 'snakeCase')
328
        self.assertEqual(camelcase(pascalcase_str), 'pascalCase')
329
        self.assertEqual(camelcase(pascalcase_str2), 'aBcDe')
330
        self.assertEqual(camelcase(lispcase_str), 'lispCase')
331
332
        self.assertEqual(snakecase(camelcase_str), 'camel_case')
333
        self.assertEqual(snakecase(snakecase_str), 'snake_case')
334
        self.assertEqual(snakecase(pascalcase_str), 'pascal_case')
335
        self.assertEqual(snakecase(pascalcase_str2), 'a_bc_de')
336
        self.assertEqual(snakecase(lispcase_str), 'lisp_case')
337
338
        self.assertEqual(pascalcase(camelcase_str), 'CamelCase')
339
        self.assertEqual(pascalcase(snakecase_str), 'SnakeCase')
340
        self.assertEqual(pascalcase(pascalcase_str), 'PascalCase')
341
        self.assertEqual(pascalcase(pascalcase_str2), 'ABcDe')
342
        self.assertEqual(pascalcase(lispcase_str), 'LispCase')
343
344
        self.assertEqual(lispcase(camelcase_str), 'camel-case')
345
        self.assertEqual(lispcase(snakecase_str), 'snake-case')
346
        self.assertEqual(lispcase(pascalcase_str), 'pascal-case')
347
        self.assertEqual(lispcase(pascalcase_str2), 'a-bc-de')
348
        self.assertEqual(lispcase(lispcase_str), 'lisp-case')
349
350
    def test_serialize_and_deserialize_with_case_transformer(self):
351
        class A:
352
            def __init__(self, snake_case_str, some_dict):
353
                self.snake_case_str = snake_case_str
354
                self.some_dict = some_dict
355
356
        class B:
357
            def __init__(self, a_obj: A, camel_case_str):
358
                self.a_obj = a_obj
359
                self.camel_case_str = camel_case_str
360
361
        b = B(A('one_two', {'some_key': 'some_value'}), 'theeFour')
362
        dumped_pascalcase = \
363
            jsons.dump(b, key_transformer=jsons.KEY_TRANSFORMER_PASCALCASE)
364
        loaded_snakecase = \
365
            jsons.load(dumped_pascalcase, B,
366
                       key_transformer=jsons.KEY_TRANSFORMER_SNAKECASE)
367
        expected_dump = {
368
            'AObj': {
369
                'SnakeCaseStr': 'one_two',
370
                'SomeDict': {
371
                    'SomeKey': 'some_value'
372
                }
373
            },
374
            'CamelCaseStr': 'theeFour'
375
        }
376
        self.assertEqual(expected_dump, dumped_pascalcase)
377
        self.assertEqual(loaded_snakecase.camel_case_str, 'theeFour')
378
        self.assertEqual(loaded_snakecase.a_obj.snake_case_str, 'one_two')
379
        self.assertEqual(loaded_snakecase.a_obj.some_dict['some_key'],
380
                         'some_value')
381