Passed
Push — master ( 01a50b...c59786 )
by Fabio
01:14
created

tests.test_benedict   B

Complexity

Total Complexity 46

Size/Duplication

Total Lines 1046
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 46
eloc 742
dl 0
loc 1046
rs 8.578
c 0
b 0
f 0

43 Methods

Rating   Name   Duplication   Size   Complexity  
A BenedictTestCase.test_flatten_with_key_conflict() 0 18 1
B BenedictTestCase.test_subset_with_keypath() 0 49 1
A BenedictTestCase.test_clone() 0 15 1
A BenedictTestCase.test_dump() 0 20 1
A BenedictTestCase.test_filter_with_parse() 0 36 2
A BenedictTestCase.test_deepupdate_with_multiple_dicts() 0 29 1
B BenedictTestCase.test_merge() 0 64 1
A BenedictTestCase.test_get_list() 0 31 1
A BenedictTestCase.test_get_phonenumber() 0 25 1
A BenedictTestCase.test_merge_with_multiple_dicts() 0 29 1
A BenedictTestCase.test_dump_with_datetime() 0 10 1
A BenedictTestCase.test_items_sorted_by_values() 0 16 1
A BenedictTestCase.test_fromkeys() 0 27 1
A BenedictTestCase.test_fromkeys_with_value() 0 27 1
A BenedictTestCase.test_from_yaml() 0 15 1
A BenedictTestCase.test_from_json() 0 10 1
A BenedictTestCase.test_pop() 0 13 1
B BenedictTestCase.test_deepupdate() 0 64 1
A BenedictTestCase.test_merge_with_single_dict() 0 17 1
A BenedictTestCase.test_get_dict() 0 8 1
A BenedictTestCase.test_from_base64() 0 10 1
A BenedictTestCase.test_items_sorted_by_values_reverse() 0 16 1
A BenedictTestCase.test_dump_with_decimal() 0 10 1
A BenedictTestCase.test_deepupdate_with_single_dict() 0 17 1
A BenedictTestCase.test_copy() 0 16 1
A BenedictTestCase.test_get_list_item() 0 24 1
A BenedictTestCase.test_items_sorted_by_keys_reverse() 0 16 1
A BenedictTestCase.test_invert_multiple_values() 0 14 1
A BenedictTestCase.test_get_item() 0 13 1
A BenedictTestCase.test_get() 0 13 1
A BenedictTestCase.test_flatten() 0 25 1
A BenedictTestCase.test_remove_with_keypath() 0 32 1
A BenedictTestCase.test_deepcopy() 0 16 1
B BenedictTestCase.test_clean() 0 53 1
A BenedictTestCase.test_from_toml() 0 16 1
A BenedictTestCase.test_invert_flat() 0 18 1
A BenedictTestCase.test_subset() 0 18 1
A BenedictTestCase.test_invert() 0 18 1
A BenedictTestCase.test_flatten_with_custom_separator() 0 25 1
A BenedictTestCase.test_items_sorted_by_keys() 0 16 1
A BenedictTestCase.test_from_xml() 0 18 1
A BenedictTestCase.test_filter() 0 21 3
A BenedictTestCase.test_remove() 0 16 1

How to fix   Complexity   

Complexity

Complex classes like tests.test_benedict often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
# -*- coding: utf-8 -*-
2
3
from benedict import benedict
4
from datetime import datetime
5
from decimal import Decimal
6
7
import unittest
8
9
10
class BenedictTestCase(unittest.TestCase):
11
12
    def test_clean(self):
13
        d = {
14
            'a': {},
15
            'b': { 'x': 1 },
16
            'c': [],
17
            'd': [0, 1],
18
            'e': 0.0,
19
            'f': '',
20
            'g': None,
21
            'h': '0'
22
        }
23
        bd = benedict(d)
24
        bd.clean()
25
        r = {
26
            'b': { 'x': 1 },
27
            'd': [0, 1],
28
            'e': 0.0,
29
            'h': '0',
30
        }
31
        self.assertEqual(bd, r)
32
33
        bd = benedict(d)
34
        bd.clean(dicts=False)
35
        r = {
36
            'a': {},
37
            'b': { 'x': 1 },
38
            'd': [0, 1],
39
            'e': 0.0,
40
            'h': '0'
41
        }
42
        self.assertEqual(bd, r)
43
44
        bd = benedict(d)
45
        bd.clean(lists=False)
46
        r = {
47
            'b': { 'x': 1 },
48
            'c': [],
49
            'd': [0, 1],
50
            'e': 0.0,
51
            'h': '0'
52
        }
53
        self.assertEqual(bd, r)
54
55
        bd = benedict(d)
56
        bd.clean(strings=False)
57
        r = {
58
            'b': { 'x': 1 },
59
            'd': [0, 1],
60
            'e': 0.0,
61
            'f': '',
62
            'h': '0',
63
        }
64
        self.assertEqual(bd, r)
65
66
    def test_clone(self):
67
        d = {
68
            'a': {
69
                'b': {
70
                    'c': 1
71
                }
72
            }
73
        }
74
        b = benedict(d)
75
        c = b.clone()
76
        self.assertEqual(b, c)
77
        self.assertFalse(c is b)
78
        c['a']['b']['c'] = 2
79
        self.assertEqual(b['a']['b']['c'], 1)
80
        self.assertEqual(c['a']['b']['c'], 2)
81
82
    def test_copy(self):
83
        d = {
84
            'a': {
85
                'b': {
86
                    'c': 1
87
                }
88
            }
89
        }
90
        b = benedict(d)
91
        c = b.copy()
92
        self.assertEqual(type(b), type(c))
93
        self.assertEqual(b, c)
94
        self.assertFalse(c is b)
95
        c['a.b.c'] = 2
96
        self.assertEqual(b.get('a.b.c'), 2)
97
        self.assertEqual(c.get('a.b.c'), 2)
98
99
    def test_deepcopy(self):
100
        d = {
101
            'a': {
102
                'b': {
103
                    'c': 1
104
                }
105
            }
106
        }
107
        b = benedict(d)
108
        c = b.deepcopy()
109
        self.assertEqual(type(b), type(c))
110
        self.assertEqual(b, c)
111
        self.assertFalse(c is b)
112
        c['a.b.c'] = 2
113
        self.assertEqual(b.get('a.b.c'), 1)
114
        self.assertEqual(c.get('a.b.c'), 2)
115
116
    def test_deepupdate_with_single_dict(self):
117
        d = {
118
            'a': 1,
119
            'b': 1,
120
        }
121
        a = {
122
            'b': 2,
123
            'c': 3,
124
        }
125
        bd = benedict(d)
126
        bd.deepupdate(a)
127
        r = {
128
            'a': 1,
129
            'b': 2,
130
            'c': 3,
131
        }
132
        self.assertEqual(bd, r)
133
134
    def test_deepupdate_with_multiple_dicts(self):
135
        d = {
136
            'a': 1,
137
            'b': 1,
138
        }
139
        a = {
140
            'b': 2,
141
            'c': 3,
142
            'd': 3,
143
        }
144
        b = {
145
            'd': 5,
146
            'e': 5,
147
        }
148
        c = {
149
            'd': 4,
150
            'f': 6,
151
        }
152
        bd = benedict(d)
153
        bd.deepupdate(a, b, c)
154
        r = {
155
            'a': 1,
156
            'b': 2,
157
            'c': 3,
158
            'd': 4,
159
            'e': 5,
160
            'f': 6,
161
        }
162
        self.assertEqual(bd, r)
163
164
    def test_deepupdate(self):
165
        d = {
166
            'a': 1,
167
            'b': {
168
                'c': {
169
                    'x': 2,
170
                    'y': 3,
171
                },
172
                'd': {
173
                    'x': 4,
174
                    'y': 5,
175
                },
176
                'e': {
177
                    'x': 6,
178
                    'y': 7,
179
                },
180
            },
181
        }
182
        a = {
183
            'a': 0,
184
            'b': {
185
                'c': 1,
186
                'd': {
187
                    'y': 1,
188
                    'z': 2,
189
                },
190
                'e': {
191
                    'f': {
192
                        'x': 2,
193
                        'y': 3,
194
                    },
195
                    'g': {
196
                        'x': 4,
197
                        'y': 5,
198
                    },
199
                },
200
            },
201
        }
202
        bd = benedict(d)
203
        bd.deepupdate(a)
204
        r = {
205
            'a': 0,
206
            'b': {
207
                'c': 1,
208
                'd': {
209
                    'x': 4,
210
                    'y': 1,
211
                    'z': 2,
212
                },
213
                'e': {
214
                    'f': {
215
                        'x': 2,
216
                        'y': 3,
217
                    },
218
                    'g': {
219
                        'x': 4,
220
                        'y': 5,
221
                    },
222
                    'x': 6,
223
                    'y': 7,
224
                },
225
            },
226
        }
227
        self.assertEqual(bd, r)
228
229
    def test_dump(self):
230
        d = {
231
            'a': {
232
                'b': {
233
                    'c': 1
234
                }
235
            }
236
        }
237
        b = benedict(d)
238
        expected_output = """{
239
    "a": {
240
        "b": {
241
            "c": 1
242
        }
243
    }
244
}"""
245
        output = benedict.dump(b)
246
        self.assertEqual(output, expected_output)
247
        output = b.dump()
248
        self.assertEqual(output, expected_output)
249
250
    def test_dump_with_datetime(self):
251
        d = {
252
            'datetime': datetime(2019, 6, 11),
253
        }
254
        b = benedict(d)
255
        expected_output = """{
256
    "datetime": "2019-06-11 00:00:00"
257
}"""
258
        output = b.dump()
259
        self.assertEqual(output, expected_output)
260
261
    def test_dump_with_decimal(self):
262
        d = {
263
            'decimal': Decimal('1.75'),
264
        }
265
        b = benedict(d)
266
        expected_output = """{
267
    "decimal": "1.75"
268
}"""
269
        output = b.dump()
270
        self.assertEqual(output, expected_output)
271
272
    def test_filter(self):
273
        d = {
274
            'a': 1,
275
            'b': 2,
276
            'c': '4',
277
            'e': '5',
278
            'f': 6,
279
            'g': 7,
280
        }
281
        b = benedict(d)
282
        with self.assertRaises(ValueError):
283
            f = b.filter(True)
284
        f = b.filter(lambda key, val: isinstance(val, int))
285
        r = {
286
            'a': 1,
287
            'b': 2,
288
            'f': 6,
289
            'g': 7,
290
        }
291
        self.assertEqual(f, r)
292
        self.assertFalse(b is f)
293
294
    def test_filter_with_parse(self):
295
        d = {
296
            'a': {
297
                'ok': 'yes',
298
            },
299
            'b': {
300
                'ok': 'no',
301
            },
302
            'c': {
303
                'ok': 'yes',
304
            },
305
            'e': {
306
                'ok': 'no',
307
            },
308
            'f': {
309
                'ok': 'yes',
310
            },
311
            'g': {
312
                'ok': 'no',
313
            },
314
        }
315
        b = benedict(d)
316
        f = b.filter(lambda key, val: benedict(val).get_bool('ok'))
317
        r = {
318
            'a': {
319
                'ok': 'yes',
320
            },
321
            'c': {
322
                'ok': 'yes',
323
            },
324
            'f': {
325
                'ok': 'yes',
326
            },
327
        }
328
        self.assertEqual(f, r)
329
        self.assertTrue(isinstance(f, benedict))
330
331
    def test_flatten(self):
332
        d = {
333
            'a': 1,
334
            'b': 2,
335
            'c': {
336
                'd': {
337
                    'e': 3,
338
                    'f': 4,
339
                    'g': {
340
                        'h': 5,
341
                    }
342
                }
343
            },
344
        }
345
        b = benedict(d)
346
        f = b.flatten()
347
        r = {
348
            'a': 1,
349
            'b': 2,
350
            'c_d_e': 3,
351
            'c_d_f': 4,
352
            'c_d_g_h': 5,
353
        }
354
        self.assertEqual(f, r)
355
        self.assertTrue(isinstance(f, benedict))
356
357
    def test_flatten_with_custom_separator(self):
358
        d = {
359
            'a': 1,
360
            'b': 2,
361
            'c': {
362
                'd': {
363
                    'e': 3,
364
                    'f': 4,
365
                    'g': {
366
                        'h': 5,
367
                    }
368
                }
369
            },
370
        }
371
        b = benedict(d)
372
        f = b.flatten(separator='|')
373
        r = {
374
            'a': 1,
375
            'b': 2,
376
            'c|d|e': 3,
377
            'c|d|f': 4,
378
            'c|d|g|h': 5,
379
        }
380
        self.assertEqual(f, r)
381
        self.assertFalse(b is f)
382
383
    def test_flatten_with_key_conflict(self):
384
        d = {
385
            'a': 1,
386
            'b': 2,
387
            'c_d': 4,
388
            'c': {
389
                'd': 3,
390
            },
391
        }
392
        b = benedict(d)
393
        f = b.flatten()
394
        r = {
395
            'a': 1,
396
            'b': 2,
397
            'c_d': 4,
398
        }
399
        self.assertEqual(f, r)
400
        self.assertFalse(b is f)
401
402
    def test_fromkeys(self):
403
        k = [
404
            'a',
405
            'a.b',
406
            'a.b.c',
407
            'a.b.d',
408
            'a.b.e',
409
            'x',
410
            'x.y',
411
            'x.z',
412
        ]
413
        b = benedict.fromkeys(k)
414
        r = {
415
            'x': {
416
                'y': None,
417
                'z': None,
418
            },
419
            'a': {
420
                'b': {
421
                    'c': None,
422
                    'd': None,
423
                    'e': None,
424
                },
425
            },
426
        }
427
        self.assertEqual(b, r)
428
        self.assertEqual(type(b), benedict)
429
430
    def test_fromkeys_with_value(self):
431
        k = [
432
            'a',
433
            'a.b',
434
            'a.b.c',
435
            'a.b.d',
436
            'a.b.e',
437
            'x',
438
            'x.y',
439
            'x.z',
440
        ]
441
        b = benedict.fromkeys(k, True)
442
        r = {
443
            'x': {
444
                'y': True,
445
                'z': True,
446
            },
447
            'a': {
448
                'b': {
449
                    'c': True,
450
                    'd': True,
451
                    'e': True,
452
                },
453
            },
454
        }
455
        self.assertEqual(b, r)
456
        self.assertEqual(type(b), benedict)
457
458
    def test_from_base64(self):
459
        j = 'eyJhIjogMSwgImIiOiAyLCAiYyI6IDN9'
460
        # static method
461
        d = benedict.from_base64(j)
462
        self.assertTrue(isinstance(d, benedict))
463
        self.assertEqual(d, { 'a': 1, 'b': 2, 'c': 3, })
464
        # constructor
465
        d = benedict(j)
466
        self.assertTrue(isinstance(d, benedict))
467
        self.assertEqual(d, { 'a': 1, 'b': 2, 'c': 3, })
468
469
    def test_from_json(self):
470
        j = '{"a": 1, "b": 2, "c": 3}'
471
        # static method
472
        d = benedict.from_json(j)
473
        self.assertTrue(isinstance(d, benedict))
474
        self.assertEqual(d, { 'a': 1, 'b': 2, 'c': 3, })
475
        # constructor
476
        d = benedict(j)
477
        self.assertTrue(isinstance(d, benedict))
478
        self.assertEqual(d, { 'a': 1, 'b': 2, 'c': 3, })
479
480
    def test_from_toml(self):
481
        j = """
482
            a = 1
483
484
            [b]
485
            c = 3
486
            d = 4
487
        """
488
        # static method
489
        d = benedict.from_toml(j)
490
        self.assertTrue(isinstance(d, benedict))
491
        self.assertEqual(d, { 'a':1, 'b':{ 'c':3, 'd':4 },})
492
        # constructor
493
        d = benedict(j)
494
        self.assertTrue(isinstance(d, benedict))
495
        self.assertEqual(d, { 'a':1, 'b':{ 'c':3, 'd':4 },})
496
497
    def test_from_xml(self):
498
        j = """<?xml version="1.0" ?>
499
            <root>
500
                <a>1</a>
501
                <b>
502
                    <c>3</c>
503
                    <d>4</d>
504
                </b>
505
            </root>
506
        """
507
        # static method
508
        d = benedict.from_xml(j)
509
        self.assertTrue(isinstance(d, benedict))
510
        self.assertEqual(d.get('root'), { 'a':'1', 'b':{ 'c':'3', 'd':'4' },})
511
        # constructor
512
        d = benedict(j)
513
        self.assertTrue(isinstance(d, benedict))
514
        self.assertEqual(d.get('root'), { 'a':'1', 'b':{ 'c':'3', 'd':'4' },})
515
516
    def test_from_yaml(self):
517
        j = """
518
            a: 1
519
            b:
520
              c: 3
521
              d: 4
522
        """
523
        # static method
524
        d = benedict.from_yaml(j)
525
        self.assertTrue(isinstance(d, benedict))
526
        self.assertEqual(d, { 'a':1, 'b':{ 'c':3, 'd':4 },})
527
        # constructor
528
        d = benedict(j)
529
        self.assertTrue(isinstance(d, benedict))
530
        self.assertEqual(d, { 'a':1, 'b':{ 'c':3, 'd':4 },})
531
532
    def test_get(self):
533
        d = {
534
            'a': 1,
535
            'b': {
536
                'c': 2,
537
                'd': {
538
                    'e': 3,
539
                }
540
            }
541
        }
542
        b = benedict(d)
543
        self.assertEqual(b.get('a'), 1)
544
        self.assertEqual(b.get('b.c'), 2)
545
        # self.assertTrue(isinstance(b.get('b'), benedict))
546
        # self.assertTrue(isinstance(b.get('b.d'), benedict))
547
        # bb = b.get('b')
548
        # self.assertTrue(isinstance(bb.get('d'), benedict))
549
550
    def test_get_item(self):
551
        d = {
552
            'a': 1,
553
            'b': {
554
                'c': 2,
555
                'd': {
556
                    'e': 3,
557
                }
558
            }
559
        }
560
        b = benedict(d)
561
        self.assertEqual(b['a'], 1)
562
        self.assertEqual(b['b.c'], 2)
563
        # self.assertTrue(isinstance(b['b'], benedict))
564
        # self.assertTrue(isinstance(b['b.d'], benedict))
565
        # bb = b['b']
566
        # self.assertTrue(isinstance(bb['d'], benedict))
567
568
    def test_get_dict(self):
569
        d = {
570
            'a': {'x': 1, 'y': 2},
571
            'b': {},
572
        }
573
        b = benedict(d)
574
        # self.assertTrue(isinstance(b.get_dict('a'), benedict))
575
        self.assertEqual(b.get('a.x'), 1)
576
577
    def test_get_list(self):
578
        d = {
579
            'a': [
580
                {
581
                    'b': {
582
                        'c': 1,
583
                    }
584
                },
585
                {
586
                    'b': {
587
                        'c': 2,
588
                    }
589
                },
590
                {
591
                    'b': {
592
                        'c': 3,
593
                    }
594
                },
595
            ]
596
        }
597
        b = benedict(d)
598
        l = b.get_list('a')
599
        # self.assertTrue(isinstance(l[0], benedict))
600
        # self.assertTrue(isinstance(l[1], benedict))
601
        # self.assertTrue(isinstance(l[2], benedict))
602
        # self.assertEqual(l[0].get('b.c'), 1)
603
        # self.assertEqual(l[1].get('b.c'), 2)
604
        # self.assertEqual(l[2].get('b.c'), 3)
605
        self.assertEqual(benedict(l[0]).get('b.c'), 1)
606
        self.assertEqual(benedict(l[1]).get('b.c'), 2)
607
        self.assertEqual(benedict(l[2]).get('b.c'), 3)
608
609
    def test_get_list_item(self):
610
        d = {
611
            'a': [
612
                {
613
                    'b': {
614
                        'c': 1,
615
                    }
616
                },
617
                {
618
                    'b': {
619
                        'c': 2,
620
                    }
621
                },
622
                {
623
                    'b': {
624
                        'c': 3,
625
                    }
626
                },
627
            ]
628
        }
629
        b = benedict(d)
630
        i = benedict(b.get_list_item('a', index=1))
631
        # self.assertTrue(isinstance(i, benedict))
632
        self.assertEqual(i.get('b.c'), 2)
633
634
    def test_get_phonenumber(self):
635
        d = {
636
            'a': {
637
                'b': ' (0039) 3334445566 ',
638
                'c': '+393334445566  ',
639
                'd': '+39333444556677889900',
640
            }
641
        }
642
        r = {
643
            'e164': '+393334445566',
644
            'international': '+39 333 444 5566',
645
            'national': '333 444 5566'
646
        }
647
        b = benedict(d)
648
649
        p = b.get_phonenumber('a.b')
650
        self.assertEqual(p, r)
651
        # self.assertTrue(isinstance(p, benedict))
652
653
        p = b.get_phonenumber('a.c')
654
        self.assertEqual(p, r)
655
        # self.assertTrue(isinstance(p, benedict))
656
657
        p = b.get_phonenumber('a.d')
658
        self.assertEqual(p, {})
659
        # self.assertTrue(isinstance(p, benedict))
660
661
    def test_invert(self):
662
        d = {
663
            'a': 1,
664
            'b': 2,
665
            'c': 3,
666
            'd': 4,
667
            'e': 5,
668
        }
669
        bd = benedict(d)
670
        i = bd.invert()
671
        r = {
672
            1: ['a'],
673
            2: ['b'],
674
            3: ['c'],
675
            4: ['d'],
676
            5: ['e'],
677
        }
678
        self.assertEqual(i, r)
679
680
    def test_invert_multiple_values(self):
681
        d = {
682
            'a': 1,
683
            'b': 2,
684
            'c': 3,
685
            'd': 1,
686
            'e': 2,
687
            'f': 3,
688
        }
689
        bd = benedict(d)
690
        i = bd.invert()
691
        self.assertTrue('a' and 'd' in i[1])
692
        self.assertTrue('b' and 'e' in i[2])
693
        self.assertTrue('c' and 'f' in i[3])
694
695
    def test_invert_flat(self):
696
        d = {
697
            'a': 1,
698
            'b': 2,
699
            'c': 3,
700
            'd': 4,
701
            'e': 5,
702
        }
703
        bd = benedict(d)
704
        i = bd.invert(flat=True)
705
        r = {
706
            1: 'a',
707
            2: 'b',
708
            3: 'c',
709
            4: 'd',
710
            5: 'e',
711
        }
712
        self.assertEqual(i, r)
713
714
    def test_items_sorted_by_keys(self):
715
        d = {
716
            'y': 3,
717
            'a': 6,
718
            'f': 9,
719
            'z': 4,
720
            'x': 1,
721
        }
722
        bd = benedict(d)
723
        items = bd.items_sorted_by_keys()
724
        self.assertEqual(items, [
725
            ('a', 6,),
726
            ('f', 9,),
727
            ('x', 1,),
728
            ('y', 3,),
729
            ('z', 4,),
730
        ])
731
732
    def test_items_sorted_by_keys_reverse(self):
733
        d = {
734
            'y': 3,
735
            'a': 6,
736
            'f': 9,
737
            'z': 4,
738
            'x': 1,
739
        }
740
        bd = benedict(d)
741
        items = bd.items_sorted_by_keys(reverse=True)
742
        self.assertEqual(items, [
743
            ('z', 4,),
744
            ('y', 3,),
745
            ('x', 1,),
746
            ('f', 9,),
747
            ('a', 6,),
748
        ])
749
750
    def test_items_sorted_by_values(self):
751
        d = {
752
            'a': 3,
753
            'b': 6,
754
            'c': 9,
755
            'e': 4,
756
            'd': 1,
757
        }
758
        bd = benedict(d)
759
        items = bd.items_sorted_by_values()
760
        self.assertEqual(items, [
761
            ('d', 1,),
762
            ('a', 3,),
763
            ('e', 4,),
764
            ('b', 6,),
765
            ('c', 9,),
766
        ])
767
768
    def test_items_sorted_by_values_reverse(self):
769
        d = {
770
            'a': 3,
771
            'b': 6,
772
            'c': 9,
773
            'e': 4,
774
            'd': 1,
775
        }
776
        bd = benedict(d)
777
        items = bd.items_sorted_by_values(reverse=True)
778
        self.assertEqual(items, [
779
            ('c', 9,),
780
            ('b', 6,),
781
            ('e', 4,),
782
            ('a', 3,),
783
            ('d', 1,),
784
        ])
785
786
    def test_merge_with_single_dict(self):
787
        d = {
788
            'a': 1,
789
            'b': 1,
790
        }
791
        a = {
792
            'b': 2,
793
            'c': 3,
794
        }
795
        d = benedict(d)
796
        d.merge(a)
797
        r = {
798
            'a': 1,
799
            'b': 2,
800
            'c': 3,
801
        }
802
        self.assertEqual(d, r)
803
804
    def test_merge_with_multiple_dicts(self):
805
        d = {
806
            'a': 1,
807
            'b': 1,
808
        }
809
        a = {
810
            'b': 2,
811
            'c': 3,
812
            'd': 3,
813
        }
814
        b = {
815
            'd': 5,
816
            'e': 5,
817
        }
818
        c = {
819
            'd': 4,
820
            'f': 6,
821
        }
822
        d = benedict(d)
823
        d.merge(a, b, c)
824
        r = {
825
            'a': 1,
826
            'b': 2,
827
            'c': 3,
828
            'd': 4,
829
            'e': 5,
830
            'f': 6,
831
        }
832
        self.assertEqual(d, r)
833
834
    def test_merge(self):
835
        d = {
836
            'a': 1,
837
            'b': {
838
                'c': {
839
                    'x': 2,
840
                    'y': 3,
841
                },
842
                'd': {
843
                    'x': 4,
844
                    'y': 5,
845
                },
846
                'e': {
847
                    'x': 6,
848
                    'y': 7,
849
                },
850
            },
851
        }
852
        a = {
853
            'a': 0,
854
            'b': {
855
                'c': 1,
856
                'd': {
857
                    'y': 1,
858
                    'z': 2,
859
                },
860
                'e': {
861
                    'f': {
862
                        'x': 2,
863
                        'y': 3,
864
                    },
865
                    'g': {
866
                        'x': 4,
867
                        'y': 5,
868
                    },
869
                },
870
            },
871
        }
872
        d = benedict(d)
873
        d.merge(a)
874
        r = {
875
            'a': 0,
876
            'b': {
877
                'c': 1,
878
                'd': {
879
                    'x': 4,
880
                    'y': 1,
881
                    'z': 2,
882
                },
883
                'e': {
884
                    'f': {
885
                        'x': 2,
886
                        'y': 3,
887
                    },
888
                    'g': {
889
                        'x': 4,
890
                        'y': 5,
891
                    },
892
                    'x': 6,
893
                    'y': 7,
894
                },
895
            },
896
        }
897
        self.assertEqual(d, r)
898
899
    def test_pop(self):
900
        d = {
901
            'a': 1,
902
            'b': {
903
                'c': 2,
904
                'd': {
905
                    'e': 3,
906
                }
907
            }
908
        }
909
        b = benedict(d)
910
        self.assertEqual(b.pop('a'), 1)
911
        self.assertEqual(b.pop('b.c'), 2)
912
        # self.assertTrue(isinstance(b.pop('b.d'), benedict))
913
914
    def test_remove(self):
915
        d = {
916
            'a': 1,
917
            'b': 2,
918
            'c': '4',
919
            'e': '5',
920
            'f': 6,
921
            'g': 7,
922
        }
923
        b = benedict(d)
924
        b.remove(['c', 'e', 'f', 'g', 'x', 'y', 'z'])
925
        r = {
926
            'a': 1,
927
            'b': 2,
928
        }
929
        self.assertEqual(b, r)
930
931
    def test_remove_with_keypath(self):
932
        d = {
933
            'a': {
934
                'x': 1,
935
                'y': 1,
936
            },
937
            'b': {
938
                'x': 2,
939
                'y': 2,
940
            },
941
            'c': {
942
                'x': 3,
943
                'y': 3,
944
            },
945
            'd': {
946
                'x': 4,
947
                'y': 4,
948
            },
949
        }
950
        b = benedict(d)
951
        b.remove(['a.x', 'b.y', 'c.x', 'c.y', 'd'])
952
        r = {
953
            'a': {
954
                'y': 1
955
            },
956
            'b': {
957
                'x': 2
958
            },
959
            'c': {
960
            },
961
        }
962
        self.assertEqual(b, r)
963
964
    # def test_setdefault(self):
965
    #     d = {
966
    #         'a': 1,
967
    #         'b': {
968
    #             'c': 2,
969
    #             'd': {
970
    #                 'e': 3,
971
    #             }
972
    #         }
973
    #     }
974
    #     b = benedict(d)
975
    #     self.assertTrue(isinstance(b.setdefault('b', 1), benedict))
976
    #     self.assertTrue(isinstance(b.setdefault('b.d', 1), benedict))
977
978
    def test_subset(self):
979
        d = {
980
            'a': 1,
981
            'b': 2,
982
            'c': '4',
983
            'e': '5',
984
            'f': 6,
985
            'g': 7,
986
        }
987
        b = benedict(d)
988
        f = b.subset(['c', 'f', 'x'])
989
        r = {
990
            'c': '4',
991
            'f': 6,
992
            'x': None,
993
        }
994
        self.assertEqual(f, r)
995
        self.assertFalse(f is b)
996
997
    def test_subset_with_keypath(self):
998
        d = {
999
            'x': {
1000
                'a': 1,
1001
                'aa': 1,
1002
            },
1003
            'y': {
1004
                'b': 2,
1005
                'bb': 2,
1006
            },
1007
            'z': {
1008
                'c': 3,
1009
                'cc': 3,
1010
            },
1011
        }
1012
        b = benedict(d)
1013
        f = b.subset(['x', 'y'])
1014
        r = {
1015
            'x': {
1016
                'a': 1,
1017
                'aa': 1,
1018
            },
1019
            'y': {
1020
                'b': 2,
1021
                'bb': 2,
1022
            },
1023
        }
1024
        self.assertEqual(f, r)
1025
        self.assertFalse(f is b)
1026
        self.assertTrue(isinstance(f, benedict))
1027
        self.assertEqual(f.get('x.a'), 1)
1028
        self.assertEqual(f.get('x.aa'), 1)
1029
        self.assertEqual(f.get('y.b'), 2)
1030
        self.assertEqual(f.get('y.bb'), 2)
1031
        # test with keypath
1032
        f = b.subset(['x.a', 'y.b'])
1033
        r = {
1034
            'x': {
1035
                'a': 1,
1036
            },
1037
            'y': {
1038
                'b': 2,
1039
            },
1040
        }
1041
        self.assertEqual(f, r)
1042
        self.assertFalse(f is b)
1043
        self.assertTrue(isinstance(f, benedict))
1044
        self.assertEqual(f.get('x.a'), 1)
1045
        self.assertEqual(f.get('y.b'), 2)
1046