Passed
Push — master ( 3136b5...f980db )
by Fabio
01:24
created

tests.test_benedict   C

Complexity

Total Complexity 54

Size/Duplication

Total Lines 1189
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 54
eloc 853
dl 0
loc 1189
rs 6.2269
c 0
b 0
f 0

50 Methods

Rating   Name   Duplication   Size   Complexity  
A BenedictTestCase.test_flatten_with_key_conflict() 0 18 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
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_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_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
B BenedictTestCase.test_subset_with_keypath() 0 49 1
A BenedictTestCase.test_remove_with_keys_args() 0 16 1
A BenedictTestCase.test_swap_with_invalid_key() 0 9 2
A BenedictTestCase.test_move() 0 32 1
A BenedictTestCase.test_subset_with_keys_args() 0 18 1
A BenedictTestCase.test_remove_with_keys_list() 0 16 1
A BenedictTestCase.test_pop() 0 13 1
A BenedictTestCase.test_remove_with_key() 0 13 1
A BenedictTestCase.test_remove_with_keypath() 0 32 1
A BenedictTestCase.test_subset() 0 18 1
A BenedictTestCase.test_swap() 0 14 1
A BenedictTestCase.test_swap_with_keypath() 0 34 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_move(self):
900
        d = {
901
            'a': {
902
                'x': 1,
903
                'y': 1,
904
            },
905
            'b': {
906
                'x': 2,
907
                'y': 2,
908
            },
909
            'c': {
910
                'x': 3,
911
                'y': 3,
912
            },
913
        }
914
        b = benedict(d)
915
        b.move('a', 'c.z')
916
        r = {
917
            'b': {
918
                'x': 2,
919
                'y': 2,
920
            },
921
            'c': {
922
                'x': 3,
923
                'y': 3,
924
                'z': {
925
                    'x': 1,
926
                    'y': 1,
927
                },
928
            },
929
        }
930
        self.assertEqual(b, r)
931
932
    def test_pop(self):
933
        d = {
934
            'a': 1,
935
            'b': {
936
                'c': 2,
937
                'd': {
938
                    'e': 3,
939
                }
940
            }
941
        }
942
        b = benedict(d)
943
        self.assertEqual(b.pop('a'), 1)
944
        self.assertEqual(b.pop('b.c'), 2)
945
        # self.assertTrue(isinstance(b.pop('b.d'), benedict))
946
947
    def test_remove_with_key(self):
948
        d = {
949
            'a': 1,
950
            'b': 2,
951
            'c': '4',
952
        }
953
        b = benedict(d)
954
        b.remove('c')
955
        r = {
956
            'a': 1,
957
            'b': 2,
958
        }
959
        self.assertEqual(b, r)
960
961
    def test_remove_with_keys_list(self):
962
        d = {
963
            'a': 1,
964
            'b': 2,
965
            'c': '4',
966
            'e': '5',
967
            'f': 6,
968
            'g': 7,
969
        }
970
        b = benedict(d)
971
        b.remove(['c', 'e', 'f', 'g', 'x', 'y', 'z'])
972
        r = {
973
            'a': 1,
974
            'b': 2,
975
        }
976
        self.assertEqual(b, r)
977
978
    def test_remove_with_keys_args(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
        b.remove('c', 'e', 'f', 'g', 'x', 'y', 'z')
989
        r = {
990
            'a': 1,
991
            'b': 2,
992
        }
993
        self.assertEqual(b, r)
994
995
    def test_remove_with_keypath(self):
996
        d = {
997
            'a': {
998
                'x': 1,
999
                'y': 1,
1000
            },
1001
            'b': {
1002
                'x': 2,
1003
                'y': 2,
1004
            },
1005
            'c': {
1006
                'x': 3,
1007
                'y': 3,
1008
            },
1009
            'd': {
1010
                'x': 4,
1011
                'y': 4,
1012
            },
1013
        }
1014
        b = benedict(d)
1015
        b.remove(['a.x', 'b.y', 'c.x', 'c.y', 'd'])
1016
        r = {
1017
            'a': {
1018
                'y': 1
1019
            },
1020
            'b': {
1021
                'x': 2
1022
            },
1023
            'c': {
1024
            },
1025
        }
1026
        self.assertEqual(b, r)
1027
1028
    # def test_setdefault(self):
1029
    #     d = {
1030
    #         'a': 1,
1031
    #         'b': {
1032
    #             'c': 2,
1033
    #             'd': {
1034
    #                 'e': 3,
1035
    #             }
1036
    #         }
1037
    #     }
1038
    #     b = benedict(d)
1039
    #     self.assertTrue(isinstance(b.setdefault('b', 1), benedict))
1040
    #     self.assertTrue(isinstance(b.setdefault('b.d', 1), benedict))
1041
1042
    def test_subset(self):
1043
        d = {
1044
            'a': 1,
1045
            'b': 2,
1046
            'c': '4',
1047
            'e': '5',
1048
            'f': 6,
1049
            'g': 7,
1050
        }
1051
        b = benedict(d)
1052
        f = b.subset(['c', 'f', 'x'])
1053
        r = {
1054
            'c': '4',
1055
            'f': 6,
1056
            'x': None,
1057
        }
1058
        self.assertEqual(f, r)
1059
        self.assertFalse(f is b)
1060
1061
    def test_subset_with_keys_args(self):
1062
        d = {
1063
            'a': 1,
1064
            'b': 2,
1065
            'c': '4',
1066
            'e': '5',
1067
            'f': 6,
1068
            'g': 7,
1069
        }
1070
        b = benedict(d)
1071
        f = b.subset('c', 'f', 'x')
1072
        r = {
1073
            'c': '4',
1074
            'f': 6,
1075
            'x': None,
1076
        }
1077
        self.assertEqual(f, r)
1078
        self.assertFalse(f is b)
1079
1080
    def test_subset_with_keypath(self):
1081
        d = {
1082
            'x': {
1083
                'a': 1,
1084
                'aa': 1,
1085
            },
1086
            'y': {
1087
                'b': 2,
1088
                'bb': 2,
1089
            },
1090
            'z': {
1091
                'c': 3,
1092
                'cc': 3,
1093
            },
1094
        }
1095
        b = benedict(d)
1096
        f = b.subset(['x', 'y'])
1097
        r = {
1098
            'x': {
1099
                'a': 1,
1100
                'aa': 1,
1101
            },
1102
            'y': {
1103
                'b': 2,
1104
                'bb': 2,
1105
            },
1106
        }
1107
        self.assertEqual(f, r)
1108
        self.assertFalse(f is b)
1109
        self.assertTrue(isinstance(f, benedict))
1110
        self.assertEqual(f.get('x.a'), 1)
1111
        self.assertEqual(f.get('x.aa'), 1)
1112
        self.assertEqual(f.get('y.b'), 2)
1113
        self.assertEqual(f.get('y.bb'), 2)
1114
        # test with keypath
1115
        f = b.subset(['x.a', 'y.b'])
1116
        r = {
1117
            'x': {
1118
                'a': 1,
1119
            },
1120
            'y': {
1121
                'b': 2,
1122
            },
1123
        }
1124
        self.assertEqual(f, r)
1125
        self.assertFalse(f is b)
1126
        self.assertTrue(isinstance(f, benedict))
1127
        self.assertEqual(f.get('x.a'), 1)
1128
        self.assertEqual(f.get('y.b'), 2)
1129
1130
    def test_swap(self):
1131
        d = {
1132
            'a': 1,
1133
            'b': 2,
1134
            'c': 3,
1135
        }
1136
        b = benedict(d)
1137
        b.swap('a', 'b')
1138
        r = {
1139
            'a': 2,
1140
            'b': 1,
1141
            'c': 3,
1142
        }
1143
        self.assertEqual(b, r)
1144
1145
    def test_swap_with_invalid_key(self):
1146
        d = {
1147
            'a': 1,
1148
            'b': 2,
1149
            'c': 3,
1150
        }
1151
        b = benedict(d)
1152
        with self.assertRaises(KeyError):
1153
            b.swap('a', 'd')
1154
1155
    def test_swap_with_keypath(self):
1156
        d = {
1157
            'a': {
1158
                'x': 1,
1159
                'y': 1,
1160
            },
1161
            'b': {
1162
                'x': 2,
1163
                'y': 2,
1164
            },
1165
            'c': {
1166
                'x': 3,
1167
                'y': 3,
1168
            },
1169
        }
1170
        b = benedict(d)
1171
        b.swap('a.y', 'b.y')
1172
        b.swap('b.x', 'c.x')
1173
        b.swap('a', 'c')
1174
        r = {
1175
            'a': {
1176
                'x': 2,
1177
                'y': 3,
1178
            },
1179
            'b': {
1180
                'x': 3,
1181
                'y': 1,
1182
            },
1183
            'c': {
1184
                'x': 1,
1185
                'y': 2,
1186
            },
1187
        }
1188
        self.assertEqual(b, r)
1189