Passed
Push — master ( df1182...461010 )
by Fabio
01:14
created

KeypathDictTestCase.test_pop_default()   A

Complexity

Conditions 1

Size

Total Lines 9
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 8
dl 0
loc 9
rs 10
c 0
b 0
f 0
cc 1
nop 1
1
# -*- coding: utf-8 -*-
2
3
from benedict.dicts.keypath import KeypathDict
4
5
import unittest
6
7
8
class KeypathDictTestCase(unittest.TestCase):
9
10
    def test_init_with_custom_separator(self):
11
        d = {
12
            'a.b': {
13
                'c.d': 1,
14
                'e.f': 2,
15
            },
16
            'g.h': {
17
                'i.j': 3,
18
                'k.l': 4,
19
            },
20
        }
21
        b = KeypathDict(d, keypath_separator='/')
22
        self.assertEqual(b.get('a.b/c.d'), 1)
23
        self.assertEqual(b.get('a.b/e.f'), 2)
24
        self.assertEqual(b.get('g.h/i.j'), 3)
25
        self.assertEqual(b.get('g.h/k.l'), 4)
26
27
    def test_init_without_keypath_separator(self):
28
        d = {
29
            'a': {
30
                'b': 1,
31
                'c': 2,
32
            },
33
            'd': {
34
                'e': 3,
35
                'f': 4,
36
            },
37
        }
38
        b = KeypathDict(d, keypath_separator=None)
39
        self.assertEqual(b.keypaths(), [])
40
        self.assertEqual(b.get('a.b'), None)
41
        self.assertEqual(b.get('a.c'), None)
42
        self.assertEqual(b.get('d.e'), None)
43
        self.assertEqual(b.get('d.f'), None)
44
45
    def test_init_with_dict_with_separator_in_keys(self):
46
        d = {
47
            'a.b.c': 1,
48
            'c.d.e': 2,
49
        }
50
        with self.assertRaises(ValueError):
51
            b = KeypathDict(d)
52
53
    def test_update_with_dict_with_separator_in_keys(self):
54
        d1 = {
55
            'a': 1,
56
            'b': 2,
57
            'c': 3,
58
        }
59
        d2 = {
60
            'a.x': 4,
61
            'a.y': 5,
62
            'a.z': 6,
63
        }
64
        b = KeypathDict(d1)
65
        with self.assertRaises(ValueError):
66
            b.update(d2)
67
68
    def test_update_with_dict_without_separator_in_keys(self):
69
        d1 = {
70
            'a': 1,
71
            'b': 2,
72
            'c': 3,
73
        }
74
        d2 = {
75
            'a.x': 4,
76
            'a.y': 5,
77
            'a.z': 6,
78
        }
79
        b = KeypathDict(d1, keypath_separator='/')
80
        b.update(d2)
81
        self.assertEqual(b.get('a'), 1)
82
        self.assertEqual(b.get('b'), 2)
83
        self.assertEqual(b.get('c'), 3)
84
        self.assertEqual(b.get('a.x'), 4)
85
        self.assertEqual(b.get('a.y'), 5)
86
        self.assertEqual(b.get('a.z'), 6)
87
88
    def test_fromkeys(self):
89
        k = [
90
            'a',
91
            'a.b',
92
            'a.b.c',
93
            'a.b.d',
94
            'a.b.e',
95
            'x',
96
            'x.y',
97
            'x.z',
98
        ]
99
        b = KeypathDict.fromkeys(k)
100
        r = {
101
            'x': {
102
                'y': None,
103
                'z': None,
104
            },
105
            'a': {
106
                'b': {
107
                    'c': None,
108
                    'd': None,
109
                    'e': None,
110
                },
111
            },
112
        }
113
        self.assertEqual(b, r)
114
115
    def test_fromkeys_with_value(self):
116
        k = [
117
            'a',
118
            'a.b',
119
            'a.b.c',
120
            'a.b.d',
121
            'a.b.e',
122
            'x',
123
            'x.y',
124
            'x.z',
125
        ]
126
        b = KeypathDict.fromkeys(k, True)
127
        r = {
128
            'x': {
129
                'y': True,
130
                'z': True,
131
            },
132
            'a': {
133
                'b': {
134
                    'c': True,
135
                    'd': True,
136
                    'e': True,
137
                },
138
            },
139
        }
140
        self.assertEqual(b, r)
141
142
    def test_get_with_1_valid_key(self):
143
        d = {
144
            'a': 1,
145
            1: 1
146
        }
147
        b = KeypathDict(d)
148
        self.assertEqual(b.get('a', 2), 1)
149
        self.assertEqual(b.get(1, 2), 1)
150
151
    def test_get_with_1_invalid_key(self):
152
        d = {
153
            'a': 1,
154
        }
155
        b = KeypathDict(d)
156
        self.assertEqual(b.get('b', 2), 2)
157
158
    def test_get_with_1_not_str_key(self):
159
        d = {
160
            None: None,
161
            False: False,
162
            0: 0,
163
        }
164
        b = KeypathDict(d)
165
        self.assertEqual(b.get(None, 1), None)
166
        self.assertEqual(b.get(False, True), False)
167
        self.assertEqual(b.get(True, True), True)
168
        self.assertEqual(b.get(0, 1), 0)
169
170
    def test_getitem_with_1_valid_key(self):
171
        d = {
172
            'a': 1,
173
        }
174
        b = KeypathDict(d)
175
        self.assertEqual(b['a'], 1)
176
177
    def test_getitem_with_1_invalid_key(self):
178
        d = {
179
            'a': 1,
180
        }
181
        b = KeypathDict(d)
182
        with self.assertRaises(KeyError):
183
            val = b['b']
184
            print(val)
185
186
    def test_getitem_with_1_not_str_key(self):
187
        d = {
188
            None: None,
189
            False: False,
190
            # 0: 0,
191
        }
192
        b = KeypathDict(d)
193
        self.assertEqual(b[None], None)
194
        self.assertEqual(b[False], False)
195
        with self.assertRaises(KeyError):
196
            val = b[True]
197
            print(val)
198
199
        self.assertEqual(b[0], 0)
200
201
    def test_get_with_2_valid_keys(self):
202
        d = {
203
            'a': {
204
                'b': 1
205
            }
206
        }
207
        b = KeypathDict(d)
208
        self.assertEqual(b.get('a.b', 2), 1)
209
210
    def test_get_with_2_invalid_keys(self):
211
        d = {
212
            'a': {
213
                'b': 1
214
            }
215
        }
216
        b = KeypathDict(d)
217
        self.assertEqual(b.get('b.a', 2), 2)
218
219
    def test_getitem_with_2_valid_keys(self):
220
        d = {
221
            'a': {
222
                'b': 1
223
            }
224
        }
225
        b = KeypathDict(d)
226
        self.assertEqual(b['a.b'], 1)
227
228
    def test_getitem_with_2_invalid_keys(self):
229
        d = {
230
            'a': {
231
                'b': 1
232
            }
233
        }
234
        b = KeypathDict(d)
235
        with self.assertRaises(KeyError):
236
            val = b['b.a']
237
            print(val)
238
239
    def test_get_with_3_valid_keys(self):
240
        d = {
241
            'a': {
242
                'b': {
243
                    'c': 1
244
                }
245
            }
246
        }
247
        b = KeypathDict(d)
248
        self.assertEqual(b.get('a.b.c', 2), 1)
249
250
    def test_get_with_3_invalid_keys(self):
251
        d = {
252
            'a': {
253
                'b': {
254
                    'c': 1
255
                }
256
            }
257
        }
258
        b = KeypathDict(d)
259
        self.assertEqual(b.get('c.b.a', 2), 2)
260
261
    def test_get_with_keys_list(self):
262
        d = {
263
            'a': {
264
                'b': {
265
                    'c': 1,
266
                    'd': 2,
267
                },
268
            },
269
        }
270
        b = KeypathDict(d)
271
        self.assertEqual(b.get(['a', 'b.c']), 1)
272
        self.assertEqual(b.get(['a', 'b', 'c']), 1)
273
        self.assertEqual(b.get(['a', 'b', 'd']), 2)
274
        self.assertEqual(b.get(['a', 'b', 'e']), None)
275
276
    def test_getitem_with_3_valid_keys(self):
277
        d = {
278
            'a': {
279
                'b': {
280
                    'c': 1
281
                }
282
            }
283
        }
284
        b = KeypathDict(d)
285
        self.assertEqual(b['a.b.c'], 1)
286
287
    def test_getitem_with_3_invalid_keys(self):
288
        d = {
289
            'a': {
290
                'b': {
291
                    'c': 1
292
                }
293
            }
294
        }
295
        b = KeypathDict(d)
296
        with self.assertRaises(KeyError):
297
            val = b['c.b.a']
298
            print(val)
299
300
    def test_get_item_with_keys_list(self):
301
        d = {
302
            'a': {
303
                'b': {
304
                    'c': 1,
305
                    'd': 2,
306
                },
307
            },
308
        }
309
        b = KeypathDict(d)
310
        self.assertEqual(b['a', 'b.c'], 1)
311
        self.assertEqual(b['a', 'b', 'c'], 1)
312
        self.assertEqual(b['a', 'b', 'd'], 2)
313
        with self.assertRaises(KeyError):
314
            val = b['a', 'b', 'e']
315
            print(val)
316
317
    def test_has_with_1_key(self):
318
        d = {
319
            'a': 0,
320
            'b': None,
321
            'c': {},
322
        }
323
        b = KeypathDict(d)
324
        self.assertTrue('a' in b)
325
        self.assertTrue('b' in b)
326
        self.assertTrue('c' in b)
327
        self.assertFalse('d' in b)
328
329
    def test_has_with_2_keys(self):
330
        d = {
331
            'a': {
332
                'a': 0,
333
                'b': None,
334
                'c': {},
335
            },
336
        }
337
        b = KeypathDict(d)
338
        self.assertTrue('a.a' in b)
339
        self.assertTrue('a.b' in b)
340
        self.assertTrue('a.c' in b)
341
        self.assertFalse('a.d' in b)
342
        self.assertFalse('b' in b)
343
        self.assertFalse('b.a' in b)
344
345
    def test_has_with_3_keys(self):
346
        d = {
347
            'a': {
348
                'b': {
349
                    'c': 0,
350
                    'd': None,
351
                    'e': {},
352
                },
353
            },
354
        }
355
        b = KeypathDict(d)
356
        self.assertTrue('a.b.c' in b)
357
        self.assertTrue('a.b.d' in b)
358
        self.assertTrue('a.b.e' in b)
359
        self.assertFalse('a.b.f' in b)
360
        self.assertFalse('b.f' in b)
361
        self.assertFalse('f' in b)
362
363
    def test_has_with_keys_list(self):
364
        d = {
365
            'a': {
366
                'b': {
367
                    'c': 1,
368
                    'd': 2,
369
                },
370
            },
371
        }
372
        b = KeypathDict(d)
373
        self.assertTrue(['a', 'b.c'] in b)
374
        self.assertTrue(['a', 'b', 'c'] in b)
375
        self.assertTrue(['a', 'b', 'd'] in b)
376
        self.assertFalse(['a', 'b', 'e'] in b)
377
378
    def test_keypaths(self):
379
        d = {
380
            'x': {
381
                'y': True,
382
                'z': False,
383
            },
384
            'a': {
385
                'b': {
386
                    'c': 0,
387
                    'd': None,
388
                    'e': {},
389
                },
390
            },
391
        }
392
        b = KeypathDict(d)
393
        r = [
394
            'a',
395
            'a.b',
396
            'a.b.c',
397
            'a.b.d',
398
            'a.b.e',
399
            'x',
400
            'x.y',
401
            'x.z',
402
        ]
403
        self.assertEqual(b.keypaths(), r)
404
405
    def test_set_override_existing_item(self):
406
        d = {}
407
        b = KeypathDict(d)
408
        b.set('a.b.c', 1)
409
        r = {
410
            'a': {
411
                'b': {
412
                    'c': 1
413
                }
414
            }
415
        }
416
        b.set('a.b.c', 2)
417
        r = {
418
            'a': {
419
                'b': {
420
                    'c': 2
421
                }
422
            }
423
        }
424
        self.assertEqual(b, r)
425
        b.set('a.b.c.d', 3)
426
        r = {
427
            'a': {
428
                'b': {
429
                    'c': {
430
                        'd': 3
431
                    }
432
                }
433
            }
434
        }
435
        self.assertEqual(b, r)
436
437
    def test_setitem_override_existing_item(self):
438
        d = {}
439
        b = KeypathDict(d)
440
        b['a.b.c'] = 1
441
        r = {
442
            'a': {
443
                'b': {
444
                    'c': 1
445
                }
446
            }
447
        }
448
        b['a.b.c'] = 2
449
        r = {
450
            'a': {
451
                'b': {
452
                    'c': 2
453
                }
454
            }
455
        }
456
        self.assertEqual(b, r)
457
        b['a.b.c.d'] = 3
458
        r = {
459
            'a': {
460
                'b': {
461
                    'c': {
462
                        'd': 3
463
                    }
464
                }
465
            }
466
        }
467
        self.assertEqual(b, r)
468
469
    def test_setitem_with_keys_list(self):
470
        d = {
471
            'a': {
472
                'b': {
473
                    'c': 1,
474
                    'd': 2,
475
                },
476
            },
477
        }
478
        b = KeypathDict(d)
479
        b['a', 'b.c'] = 2
480
        self.assertEqual(b['a.b.c'], 2)
481
        b['a', 'b', 'c'] = 3
482
        self.assertEqual(b['a.b.c'], 3)
483
        b['a', 'b', 'd'] = 4
484
        self.assertEqual(b['a.b.d'], 4)
485
        b['a', 'b', 'e'] = 5
486
        self.assertEqual(b['a.b.e'], 5)
487
488
    def test_setitem_with_dict_value_with_separator_in_keys(self):
489
        d = {
490
            'a': {
491
                'b': {
492
                    'c': 1,
493
                    'd': 2,
494
                },
495
            },
496
        }
497
        b = KeypathDict(d)
498
        v = {
499
            'i.j.k': 3,
500
            'x.y.z': 4,
501
        }
502
        # print(b['a.b.e.x.y.z'])
503
        # print(b.keypaths())
504
        with self.assertRaises(ValueError):
505
            b['a.b.e'] = v
506
507
    def test_delitem_with_1_valid_key(self):
508
        d = {
509
            'a': 1,
510
        }
511
        b = KeypathDict(d)
512
        del b['a']
513
        with self.assertRaises(KeyError):
514
            del b['a']
515
        self.assertEqual(b.get('a'), None)
516
517
    def test_delitem_with_1_invalid_key(self):
518
        d = {
519
            'a': 1,
520
        }
521
        b = KeypathDict(d)
522
        with self.assertRaises(KeyError):
523
            del b['b']
524
        self.assertEqual(b.get('b'), None)
525
526
    def test_delitem_with_2_valid_keys(self):
527
        d = {
528
            'a': {
529
                'b': 1,
530
            }
531
        }
532
        b = KeypathDict(d)
533
534
        del b['a.b']
535
        with self.assertRaises(KeyError):
536
            del b['a.b']
537
        self.assertEqual(b.get('a'), {})
538
539
        del b['a']
540
        with self.assertRaises(KeyError):
541
            del b['a']
542
        self.assertEqual(b.get('a'), None)
543
544
    def test_delitem_with_2_invalid_keys(self):
545
        d = {
546
            'a': {
547
                'b': 1,
548
            }
549
        }
550
        b = KeypathDict(d)
551
        with self.assertRaises(KeyError):
552
            del b['a.c']
553
        self.assertEqual(b.get('a'), { 'b': 1 })
554
555
    def test_delitem_with_3_valid_keys(self):
556
        d = {
557
            'a': {
558
                'b': {
559
                    'c': 1,
560
                    'd': 2,
561
                },
562
            }
563
        }
564
        b = KeypathDict(d)
565
566
        del b['a.b.c']
567
        with self.assertRaises(KeyError):
568
            del b['a.b.c']
569
        self.assertEqual(b.get('a.b'), { 'd':2 })
570
571
        del b['a.b.d']
572
        with self.assertRaises(KeyError):
573
            del b['a.b.d']
574
        self.assertEqual(b.get('a.b'), {})
575
576
        del b['a.b']
577
        with self.assertRaises(KeyError):
578
            del b['a.b']
579
        self.assertEqual(b.get('a.b'), None)
580
581
    def test_delitem_with_3_invalid_keys(self):
582
        d = {
583
            'a': {
584
                'b': {
585
                    'c': 1,
586
                    'd': 2,
587
                },
588
            }
589
        }
590
        b = KeypathDict(d)
591
        with self.assertRaises(KeyError):
592
            del b['a.b.c.d']
593
        self.assertEqual(b.get('a.b.c'), 1)
594
595
    def test_delitem_with_keys_list(self):
596
        d = {
597
            'a': {
598
                'b': {
599
                    'c': 1,
600
                    'd': 2,
601
                },
602
            }
603
        }
604
        b = KeypathDict(d)
605
        with self.assertRaises(KeyError):
606
            del b['a', 'b', 'c', 'd']
607
        del b['a', 'b', 'c']
608
        self.assertEqual(b.get('a.b.c', 3), 3)
609
610
    def test_pop_default(self):
611
        d = {
612
            'a': 1,
613
        }
614
        b = KeypathDict(d)
615
        val = b.pop('b', 2)
616
        self.assertEqual(val, 2)
617
        val = b.pop('c', default=3)
618
        self.assertEqual(val, 3)
619
620
    def test_pop_with_1_valid_key(self):
621
        d = {
622
            'a': 1,
623
        }
624
        b = KeypathDict(d)
625
        val = b.pop('a')
626
        self.assertEqual(val, 1)
627
628
    def test_pop_with_1_invalid_key(self):
629
        d = {
630
            'a': 1,
631
        }
632
        b = KeypathDict(d)
633
        with self.assertRaises(KeyError):
634
            val = b.pop('b')
635
        val = b.pop('b', False)
636
        self.assertFalse(val)
637
        val = b.pop('b', None)
638
        self.assertEqual(val, None)
639
640
    def test_pop_with_2_valid_keys(self):
641
        d = {
642
            'a': {
643
                'b': 1,
644
            }
645
        }
646
        b = KeypathDict(d)
647
648
        val = b.pop('a.b')
649
        with self.assertRaises(KeyError):
650
            val = b.pop('a.b')
651
        self.assertEqual(val, 1)
652
653
        val = b.pop('a')
654
        with self.assertRaises(KeyError):
655
            val = b.pop('a')
656
        self.assertEqual(val, {})
657
658
    def test_pop_with_2_invalid_keys(self):
659
        d = {
660
            'a': {
661
                'b': 1,
662
            }
663
        }
664
        b = KeypathDict(d)
665
666
        val = b.pop('a.c', 2)
667
        self.assertEqual(val, 2)
668
        with self.assertRaises(KeyError):
669
            val = b.pop('a.c')
670
        self.assertEqual(b.get('a'), { 'b': 1 })
671
672
        val = b.pop('x.y', 1)
673
        self.assertEqual(val, 1)
674
        with self.assertRaises(KeyError):
675
            val = b.pop('x.y')
676
677
    def test_pop_with_keys_list(self):
678
        d = {
679
            'a': {
680
                'b': 1,
681
            }
682
        }
683
        b = KeypathDict(d)
684
685
        val = b.pop(['a', 'c'], 2)
686
        self.assertEqual(val, 2)
687
        with self.assertRaises(KeyError):
688
            val = b.pop(['a', 'c'])
689
        self.assertEqual(b.get('a'), { 'b': 1 })
690
691
        val = b.pop(['x', 'y'], 1)
692
        self.assertEqual(val, 1)
693
        with self.assertRaises(KeyError):
694
            val = b.pop(['x', 'y'])
695
696 View Code Duplication
    def test_setdefault_with_1_key(self):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
697
        d = {
698
            'a': None,
699
            'b': 0,
700
            'c': 1,
701
        }
702
        b = KeypathDict(d)
703
        b.setdefault('a', 2)
704
        b.setdefault('b', 2)
705
        b.setdefault('c', 2)
706
        b.setdefault('d', 2)
707
        self.assertEqual(b['a'], None)
708
        self.assertEqual(b['b'], 0)
709
        self.assertEqual(b['c'], 1)
710
        self.assertEqual(b['d'], 2)
711
712 View Code Duplication
    def test_setdefault_with_2_keys(self):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
713
        d = {
714
            'x': {
715
                'a': None,
716
                'b': 0,
717
                'c': 1,
718
            },
719
        }
720
        b = KeypathDict(d)
721
        b.setdefault('x.a', 2)
722
        b.setdefault('x.b', 2)
723
        b.setdefault('x.c', 2)
724
        b.setdefault('x.d', 2)
725
        self.assertEqual(b['x.a'], None)
726
        self.assertEqual(b['x.b'], 0)
727
        self.assertEqual(b['x.c'], 1)
728
        self.assertEqual(b['x.d'], 2)
729
730 View Code Duplication
    def test_setdefault_with_3_keys(self):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
731
        d = {
732
            'y': {
733
                'z': {
734
                    'a': None,
735
                    'b': 0,
736
                    'c': 1,
737
                },
738
            },
739
        }
740
        b = KeypathDict(d)
741
        b.setdefault('y.z.a', 2)
742
        b.setdefault('y.z.b', 2)
743
        b.setdefault('y.z.c', 2)
744
        b.setdefault('y.z.d', 2)
745
        self.assertEqual(b['y.z.a'], None)
746
        self.assertEqual(b['y.z.b'], 0)
747
        self.assertEqual(b['y.z.c'], 1)
748
        self.assertEqual(b['y.z.d'], 2)
749