python-benedict/tests/dicts/test_benedict.py

2246 lines
54 KiB
Python

import re
import unittest
from datetime import datetime
from decimal import Decimal
from benedict import benedict
class benedict_test_case(unittest.TestCase):
"""
This class describes a benedict test case.
"""
def test_clean(self):
d = {
"a": {},
"b": {"x": 1},
"c": [],
"d": [0, 1],
"e": 0.0,
"f": "",
"g": None,
"h": "0",
}
bd = benedict(d.copy())
bd.clean()
r = {
"b": {"x": 1},
"d": [0, 1],
"e": 0.0,
"h": "0",
}
self.assertEqual(bd, r)
bd = benedict(d.copy())
bd.clean(collections=False)
r = {
"a": {},
"b": {"x": 1},
"c": [],
"d": [0, 1],
"e": 0.0,
"h": "0",
}
self.assertEqual(bd, r)
bd = benedict(d.copy())
bd.clean(strings=False)
r = {
"b": {"x": 1},
"d": [0, 1],
"e": 0.0,
"f": "",
"h": "0",
}
self.assertEqual(bd, r)
def test_clone(self):
d = {
"a": {
"b": {
"c": 1,
}
}
}
b = benedict(d)
c = b.clone()
self.assertEqual(type(b), type(c))
self.assertTrue(isinstance(c, benedict))
self.assertEqual(b, c)
self.assertFalse(c is b)
c["a"]["b"]["c"] = 2
self.assertEqual(b["a"]["b"]["c"], 1)
self.assertEqual(c["a"]["b"]["c"], 2)
def test_copy(self):
d = {
"a": {
"b": {
"c": 1,
}
}
}
b = benedict(d)
c = b.copy()
self.assertEqual(type(b), type(c))
self.assertTrue(isinstance(c, benedict))
self.assertEqual(b, c)
self.assertFalse(c is b)
c["a.b.c"] = 2
self.assertEqual(b.get("a.b.c"), 2)
self.assertEqual(c.get("a.b.c"), 2)
def test_copy_with_custom_keypath_separator(self):
d = {
"a": {
"b": {
"c": 1,
}
}
}
b = benedict(d, keypath_separator="/")
c = b.copy()
self.assertEqual(c.keypath_separator, "/")
def test_deepcopy(self):
d = {
"a": {
"b": {
"c": 1,
}
}
}
b = benedict(d)
c = b.deepcopy()
self.assertEqual(type(b), type(c))
self.assertEqual(b, c)
self.assertFalse(c is b)
c["a.b.c"] = 2
self.assertEqual(b.get("a.b.c"), 1)
self.assertEqual(c.get("a.b.c"), 2)
def test_deepcopy_with_custom_keypath_separator(self):
d = {
"a": {
"b": {
"c": 1,
}
}
}
b = benedict(d, keypath_separator="/")
c = b.deepcopy()
self.assertEqual(c.keypath_separator, "/")
def test_deepupdate_with_single_dict(self):
d = {
"a": 1,
"b": 1,
}
a = {
"b": 2,
"c": 3,
}
bd = benedict(d)
bd.deepupdate(a)
r = {
"a": 1,
"b": 2,
"c": 3,
}
self.assertEqual(bd, r)
def test_deepupdate_with_multiple_dicts(self):
d = {
"a": 1,
"b": 1,
}
a = {
"b": 2,
"c": 3,
"d": 3,
}
b = {
"d": 5,
"e": 5,
}
c = {
"d": 4,
"f": 6,
}
bd = benedict(d)
bd.deepupdate(a, b, c)
r = {
"a": 1,
"b": 2,
"c": 3,
"d": 4,
"e": 5,
"f": 6,
}
self.assertEqual(bd, r)
def test_deepupdate(self):
d = {
"a": 1,
"b": {
"c": {
"x": 2,
"y": 3,
},
"d": {
"x": 4,
"y": 5,
},
"e": {
"x": 6,
"y": 7,
},
},
}
a = {
"a": 0,
"b": {
"c": 1,
"d": {
"y": 1,
"z": 2,
},
"e": {
"f": {
"x": 2,
"y": 3,
},
"g": {
"x": 4,
"y": 5,
},
},
},
}
bd = benedict(d)
bd.deepupdate(a)
r = {
"a": 0,
"b": {
"c": 1,
"d": {
"x": 4,
"y": 1,
"z": 2,
},
"e": {
"f": {
"x": 2,
"y": 3,
},
"g": {
"x": 4,
"y": 5,
},
"x": 6,
"y": 7,
},
},
}
self.assertEqual(bd, r)
def test_dump(self):
d = {
"a": {
"b": {
"c": 1,
}
}
}
b = benedict(d)
expected_output = """{
"a": {
"b": {
"c": 1
}
}
}"""
output = benedict.dump(b)
self.assertEqual(output, expected_output)
output = b.dump()
self.assertEqual(output, expected_output)
def test_dump_with_datetime(self):
d = {
"datetime": datetime(2019, 6, 11),
}
b = benedict(d)
expected_output = """{
"datetime": "2019-06-11T00:00:00"
}"""
output = b.dump()
self.assertEqual(output, expected_output)
def test_dump_with_decimal(self):
d = {
"decimal": Decimal("1.75"),
}
b = benedict(d)
expected_output = """{
"decimal": "1.75"
}"""
output = b.dump()
self.assertEqual(output, expected_output)
def test_filter(self):
d = {
"a": 1,
"b": 2,
"c": "4",
"e": "5",
"f": 6,
"g": 7,
}
b = benedict(d)
with self.assertRaises(ValueError):
f = b.filter(True)
f = b.filter(lambda key, val: isinstance(val, int))
r = {
"a": 1,
"b": 2,
"f": 6,
"g": 7,
}
self.assertEqual(type(b), type(f))
self.assertTrue(isinstance(f, benedict))
self.assertEqual(f, r)
self.assertFalse(b is f)
def test_filter_with_custom_keypath_separator(self):
d = {
"a.b": 1,
"b.c": 2,
"c.d": 3,
"e.f": "4",
"f.g": "5",
}
b = benedict(d, keypath_separator="/")
f = b.filter(lambda key, val: isinstance(val, int))
r = {
"a.b": 1,
"b.c": 2,
"c.d": 3,
}
self.assertEqual(type(b), type(f))
self.assertTrue(isinstance(f, benedict))
self.assertEqual(f, r)
self.assertFalse(b is f)
self.assertEqual(b.keypath_separator, f.keypath_separator)
def test_filter_with_parse(self):
d = {
"a": {
"ok": "yes",
},
"b": {
"ok": "no",
},
"c": {
"ok": "yes",
},
"e": {
"ok": "no",
},
"f": {
"ok": "yes",
},
"g": {
"ok": "no",
},
}
b = benedict(d)
f = b.filter(lambda key, val: benedict(val).get_bool("ok"))
r = {
"a": {
"ok": "yes",
},
"c": {
"ok": "yes",
},
"f": {
"ok": "yes",
},
}
self.assertEqual(f, r)
self.assertTrue(isinstance(f, benedict))
def test_filter(self):
d = {
"a": 1,
"b": 2,
"c": {
"d": {
"e": 3,
"f": 4,
}
},
}
b = benedict(d)
r = b.find(["x.y.z", "a.b.c", "c.d.e"])
self.assertEqual(r, 3)
def test_flatten(self):
d = {
"a": 1,
"b": 2,
"c": {
"d": {
"e": 3,
"f": 4,
"g": {
"h": 5,
},
}
},
}
b = benedict(d)
f = b.flatten()
r = {
"a": 1,
"b": 2,
"c_d_e": 3,
"c_d_f": 4,
"c_d_g_h": 5,
}
self.assertEqual(f, r)
self.assertEqual(type(b), type(f))
self.assertTrue(isinstance(f, benedict))
def test_flatten_with_custom_keypath_separator(self):
d = {
"a": 1,
"b": 2,
"c": {
"d": {
"e": 3,
"f": 4,
"g": {
"h": 5,
},
}
},
}
b = benedict(d, keypath_separator="/")
f = b.flatten()
r = {
"a": 1,
"b": 2,
"c_d_e": 3,
"c_d_f": 4,
"c_d_g_h": 5,
}
self.assertEqual(f, r)
self.assertEqual(type(b), type(f))
self.assertTrue(isinstance(f, benedict))
self.assertEqual(b.keypath_separator, f.keypath_separator)
def test_flatten_with_custom_separator(self):
d = {
"a": 1,
"b": 2,
"c": {
"d": {
"e": 3,
"f": 4,
"g": {
"h": 5,
},
}
},
}
b = benedict(d)
f = b.flatten(separator="|")
r = {
"a": 1,
"b": 2,
"c|d|e": 3,
"c|d|f": 4,
"c|d|g|h": 5,
}
self.assertEqual(f, r)
self.assertFalse(b is f)
def test_flatten_with_key_conflict(self):
d = {
"a": 1,
"b": 2,
"c_d": 4,
"c": {
"d": 3,
},
}
b = benedict(d)
with self.assertRaises(KeyError):
f = b.flatten()
# r = {
# 'a': 1,
# 'b': 2,
# 'c_d': 4,
# }
# self.assertEqual(f, r)
# self.assertFalse(b is f)
def test_fromkeys(self):
k = [
"a",
"a.b",
"a.b.c",
"a.b.d",
"a.b.e",
"x",
"x.y",
"x.z",
]
b = benedict.fromkeys(k)
r = {
"x": {
"y": None,
"z": None,
},
"a": {
"b": {
"c": None,
"d": None,
"e": None,
},
},
}
self.assertEqual(b, r)
self.assertEqual(type(b), benedict)
def test_fromkeys_with_value(self):
k = [
"a",
"a.b",
"a.b.c",
"a.b.d",
"a.b.e",
"x",
"x.y",
"x.z",
]
b = benedict.fromkeys(k, True)
r = {
"x": {
"y": True,
"z": True,
},
"a": {
"b": {
"c": True,
"d": True,
"e": True,
},
},
}
self.assertEqual(b, r)
self.assertEqual(type(b), benedict)
def test_from_base64(self):
j = "eyJhIjogMSwgImIiOiAyLCAiYyI6IDN9"
# static method
d = benedict.from_base64(j)
self.assertTrue(isinstance(d, benedict))
self.assertEqual(
d,
{
"a": 1,
"b": 2,
"c": 3,
},
)
# static method with subformat
d = benedict.from_base64(j, subformat="json")
self.assertTrue(isinstance(d, benedict))
self.assertEqual(
d,
{
"a": 1,
"b": 2,
"c": 3,
},
)
# constructor
d = benedict(j, format="base64")
self.assertTrue(isinstance(d, benedict))
self.assertEqual(
d,
{
"a": 1,
"b": 2,
"c": 3,
},
)
# constructor with subformat
d = benedict(j, format="base64", subformat="json")
self.assertTrue(isinstance(d, benedict))
self.assertEqual(
d,
{
"a": 1,
"b": 2,
"c": 3,
},
)
def test_from_csv_with_valid_data(self):
s = """id,name,age,height,weight
1,Alice,20,62,120.6
2,Freddie,21,74,190.6
3,Bob,17,68,120.0
4,François,32,75,110.05
"""
r = {
"values": [
{
"id": "1",
"name": "Alice",
"age": "20",
"height": "62",
"weight": "120.6",
},
{
"id": "2",
"name": "Freddie",
"age": "21",
"height": "74",
"weight": "190.6",
},
{
"id": "3",
"name": "Bob",
"age": "17",
"height": "68",
"weight": "120.0",
},
{
"id": "4",
"name": "François",
"age": "32",
"height": "75",
"weight": "110.05",
},
],
}
# static method
d = benedict.from_csv(s)
self.assertTrue(isinstance(d, dict))
self.assertEqual(d, r)
# constructor
d = benedict(s, format="csv")
self.assertTrue(isinstance(d, dict))
self.assertEqual(d, r)
def test_from_json(self):
j = '{"a": 1, "b": 2, "c": 3}'
# static method
d = benedict.from_json(j)
self.assertTrue(isinstance(d, benedict))
self.assertEqual(
d,
{
"a": 1,
"b": 2,
"c": 3,
},
)
# constructor
d = benedict(j, format="json")
self.assertTrue(isinstance(d, benedict))
self.assertEqual(
d,
{
"a": 1,
"b": 2,
"c": 3,
},
)
def test_from_query_string_with_valid_data(self):
s = "ok=1&test=2&page=3&lib=python%20benedict&author=Fabio+Caccamo&author=Fabio%20Caccamo"
r = {
"ok": "1",
"test": "2",
"page": "3",
"lib": "python benedict",
"author": "Fabio Caccamo",
}
# static method
d = benedict.from_query_string(s)
self.assertTrue(isinstance(d, benedict))
self.assertEqual(d, r)
# constructor
d = benedict(s, format="query-string")
self.assertTrue(isinstance(d, benedict))
self.assertEqual(d, r)
def test_from_toml(self):
j = """
a = 1
[b]
c = 3
d = 4
"""
# static method
d = benedict.from_toml(j)
self.assertTrue(isinstance(d, benedict))
self.assertEqual(
d,
{
"a": 1,
"b": {
"c": 3,
"d": 4,
},
},
)
# constructor
d = benedict(j, format="toml")
self.assertTrue(isinstance(d, benedict))
self.assertEqual(
d,
{
"a": 1,
"b": {
"c": 3,
"d": 4,
},
},
)
def test_from_yaml_with_keypath_separator_in_keys(self):
# fix: https://github.com/fabiocaccamo/python-benedict/issues/12
j = """
192.168.0.1:
test: value
test2: value2
value:
value_with_period: 12.34.45
"""
with self.assertRaises(ValueError):
# static method
d = benedict.from_yaml(j)
self.assertTrue(isinstance(d, dict))
self.assertEqual(
d,
{
"a": 1,
"b": {
"c": 3,
"d": 4,
},
},
)
# constructor
d = benedict(j, format="yaml")
self.assertTrue(isinstance(d, dict))
self.assertEqual(
d,
{
"a": 1,
"b": {
"c": 3,
"d": 4,
},
},
)
r = {
"192.168.0.1": {
"test": "value",
"test2": "value2",
},
"value": {
"value_with_period": "12.34.45",
},
}
# static method
d = benedict.from_yaml(j, keypath_separator=None)
self.assertTrue(isinstance(d, dict))
self.assertEqual(d, r)
# constructor
d = benedict(j, format="yaml", keypath_separator=None)
self.assertTrue(isinstance(d, dict))
self.assertEqual(d, r)
def test_from_xml(self):
j = """
<?xml version="1.0" ?>
<root>
<a>1</a>
<b>
<c>3</c>
<d>4</d>
</b>
</root>
"""
# static method
d = benedict.from_xml(j)
self.assertTrue(isinstance(d, benedict))
self.assertEqual(
d.get("root"),
{
"a": "1",
"b": {
"c": "3",
"d": "4",
},
},
)
# constructor
d = benedict(j, format="xml")
self.assertTrue(isinstance(d, benedict))
self.assertEqual(
d.get("root"),
{
"a": "1",
"b": {
"c": "3",
"d": "4",
},
},
)
def test_from_yaml(self):
j = """
a: 1
b:
c: 3
d: 4
"""
# static method
d = benedict.from_yaml(j)
self.assertTrue(isinstance(d, benedict))
self.assertEqual(
d,
{
"a": 1,
"b": {
"c": 3,
"d": 4,
},
},
)
# constructor
d = benedict(j, format="yaml")
self.assertTrue(isinstance(d, benedict))
self.assertEqual(
d,
{
"a": 1,
"b": {
"c": 3,
"d": 4,
},
},
)
def test_get(self):
d = {
"a": 1,
"b": {
"c": 2,
"d": {
"e": 3,
},
},
}
b = benedict(d)
self.assertEqual(b.get("a"), 1)
self.assertEqual(b.get("b.c"), 2)
# self.assertTrue(isinstance(b.get('b'), benedict))
# self.assertTrue(isinstance(b.get('b.d'), benedict))
# bb = b.get('b')
# self.assertTrue(isinstance(bb.get('d'), benedict))
def test_get_item(self):
d = {
"a": 1,
"b": {
"c": 2,
"d": {
"e": 3,
},
},
}
b = benedict(d)
self.assertEqual(b["a"], 1)
self.assertEqual(b["b.c"], 2)
# self.assertTrue(isinstance(b['b'], benedict))
# self.assertTrue(isinstance(b['b.d'], benedict))
# bb = b['b']
# self.assertTrue(isinstance(bb['d'], benedict))
def test_get_dict(self):
d = {
"a": {
"x": 1,
"y": 2,
},
"b": {},
}
b = benedict(d)
# self.assertTrue(isinstance(b.get_dict('a'), benedict))
self.assertEqual(b.get("a.x"), 1)
def test_get_list(self):
d = {
"a": [
{
"b": {
"c": 1,
}
},
{
"b": {
"c": 2,
}
},
{
"b": {
"c": 3,
}
},
]
}
b = benedict(d)
l = b.get_list("a")
# self.assertTrue(isinstance(l[0], benedict))
# self.assertTrue(isinstance(l[1], benedict))
# self.assertTrue(isinstance(l[2], benedict))
# self.assertEqual(l[0].get('b.c'), 1)
# self.assertEqual(l[1].get('b.c'), 2)
# self.assertEqual(l[2].get('b.c'), 3)
self.assertEqual(benedict(l[0]).get("b.c"), 1)
self.assertEqual(benedict(l[1]).get("b.c"), 2)
self.assertEqual(benedict(l[2]).get("b.c"), 3)
def test_get_list_item(self):
d = {
"a": [
{
"b": {
"c": 1,
}
},
{
"b": {
"c": 2,
}
},
{
"b": {
"c": 3,
}
},
]
}
b = benedict(d)
i = benedict(b.get_list_item("a", index=1))
# self.assertTrue(isinstance(i, benedict))
self.assertEqual(i.get("b.c"), 2)
def test_get_phonenumber(self):
d = {
"a": {
"b": " (0039) 3334445566 ",
"c": "+393334445566 ",
"d": "+39333444556677889900",
}
}
r = {
"e164": "+393334445566",
"international": "+39 333 444 5566",
"national": "333 444 5566",
}
b = benedict(d)
p = b.get_phonenumber("a.b")
self.assertEqual(p, r)
# self.assertTrue(isinstance(p, benedict))
p = b.get_phonenumber("a.c")
self.assertEqual(p, r)
# self.assertTrue(isinstance(p, benedict))
p = b.get_phonenumber("a.d")
self.assertEqual(p, {})
# self.assertTrue(isinstance(p, benedict))
def test_groupby(self):
d = {
"cities": [
{
"country_code": "IT",
"name": "Torino",
},
{
"country_code": "DE",
"name": "Berlin",
},
{
"country_code": "IT",
"name": "Milano",
},
{
"country_code": "FR",
"name": "Paris",
},
{
"country_code": "IT",
"name": "Venezia",
},
{
"country_code": "IT",
"name": "Roma",
},
{
"country_code": "FR",
"name": "Lyon",
},
{
"country_code": "IT",
"name": "Napoli",
},
{
"country_code": "DE",
"name": "Munich",
},
{
"country_code": "IT",
"name": "Palermo",
},
],
}
bd = benedict(d)
bd_cities = bd["cities"]
g = bd.groupby("cities", "country_code")
self.assertEqual(len(g), 3)
self.assertTrue("IT" in g)
self.assertTrue("FR" in g)
self.assertTrue("DE" in g)
self.assertEqual(len(g["IT"]), 6)
self.assertTrue(bd_cities[0] in g["IT"])
self.assertTrue(bd_cities[2] in g["IT"])
self.assertTrue(bd_cities[4] in g["IT"])
self.assertTrue(bd_cities[5] in g["IT"])
self.assertTrue(bd_cities[7] in g["IT"])
self.assertTrue(bd_cities[9] in g["IT"])
self.assertEqual(len(g["FR"]), 2)
self.assertTrue(bd_cities[3] in g["FR"])
self.assertTrue(bd_cities[6] in g["FR"])
self.assertEqual(len(g["DE"]), 2)
self.assertTrue(bd_cities[1] in g["DE"])
self.assertTrue(bd_cities[8] in g["DE"])
def test_invert(self):
d = {
"a": 1,
"b": 2,
"c": 3,
"d": 4,
"e": 5,
}
bd = benedict(d)
i = bd.invert()
r = {
1: ["a"],
2: ["b"],
3: ["c"],
4: ["d"],
5: ["e"],
}
self.assertEqual(i, r)
def test_invert_with_custom_keypath_separator(self):
d = {
"a": "1.0",
"b": "2.0",
"c": "3.0",
"d": "4.0",
"e": "5.0",
}
bd = benedict(d, keypath_separator="/")
i = bd.invert()
r = {
"1.0": ["a"],
"2.0": ["b"],
"3.0": ["c"],
"4.0": ["d"],
"5.0": ["e"],
}
self.assertEqual(i, r)
self.assertEqual(bd.keypath_separator, i.keypath_separator)
def test_invert_multiple_values(self):
d = {
"a": 1,
"b": 2,
"c": 3,
"d": 1,
"e": 2,
"f": 3,
}
bd = benedict(d)
i = bd.invert()
self.assertTrue("a" and "d" in i[1])
self.assertTrue("b" and "e" in i[2])
self.assertTrue("c" and "f" in i[3])
def test_invert_flat(self):
d = {
"a": 1,
"b": 2,
"c": 3,
"d": 4,
"e": 5,
}
bd = benedict(d)
i = bd.invert(flat=True)
r = {
1: "a",
2: "b",
3: "c",
4: "d",
5: "e",
}
self.assertEqual(i, r)
def test_items_sorted_by_keys(self):
d = {
"y": 3,
"a": 6,
"f": 9,
"z": 4,
"x": 1,
}
bd = benedict(d)
items = bd.items_sorted_by_keys()
self.assertEqual(
items,
[
("a", 6),
("f", 9),
("x", 1),
("y", 3),
("z", 4),
],
)
def test_items_sorted_by_keys_reverse(self):
d = {
"y": 3,
"a": 6,
"f": 9,
"z": 4,
"x": 1,
}
bd = benedict(d)
items = bd.items_sorted_by_keys(reverse=True)
self.assertEqual(
items,
[
("z", 4),
("y", 3),
("x", 1),
("f", 9),
("a", 6),
],
)
def test_items_sorted_by_values(self):
d = {
"a": 3,
"b": 6,
"c": 9,
"e": 4,
"d": 1,
}
bd = benedict(d)
items = bd.items_sorted_by_values()
self.assertEqual(
items,
[
("d", 1),
("a", 3),
("e", 4),
("b", 6),
("c", 9),
],
)
def test_items_sorted_by_values_reverse(self):
d = {
"a": 3,
"b": 6,
"c": 9,
"e": 4,
"d": 1,
}
bd = benedict(d)
items = bd.items_sorted_by_values(reverse=True)
self.assertEqual(
items,
[
("c", 9),
("b", 6),
("e", 4),
("a", 3),
("d", 1),
],
)
def test_keypaths(self):
d = {
"x": {
"y": True,
"z": False,
},
"a": {
"b": {
"c": 0,
"d": None,
"e": {},
"f": [1, 2, 3, 4, 5],
},
},
}
b = benedict(d)
r = [
"a",
"a.b",
"a.b.c",
"a.b.d",
"a.b.e",
"a.b.f",
"x",
"x.y",
"x.z",
]
self.assertEqual(b.keypaths(), r)
r = [
"a",
"a.b",
"a.b.c",
"a.b.d",
"a.b.e",
"a.b.f",
"a.b.f[0]",
"a.b.f[1]",
"a.b.f[2]",
"a.b.f[3]",
"a.b.f[4]",
"x",
"x.y",
"x.z",
]
self.assertEqual(b.keypaths(indexes=True), r)
def test_match_with_regex_pattern(self):
d = {
"results": [
{
"name_1": "A",
},
{
"name_2": "B",
},
{
"name_3": "C",
},
{
"name_X": "D",
},
],
}
b = benedict(d)
r = re.compile(r"results\[[\d]+\].name_[\d]+")
m = b.match(r)
self.assertEqual(m, ["A", "B", "C"])
def test_match_with_regex_pattern_and_custom_keypath_separator(self):
d = {
"results": [
{
"name_1": "A",
},
{
"name_2": "B",
},
{
"name_3": "C",
},
{
"name_X": "D",
},
],
}
b = benedict(d, keypath_separator="/")
r = re.compile(r"results\[[\d]+\]/name_[\d]+")
m = b.match(r)
self.assertEqual(m, ["A", "B", "C"])
def test_match_with_string_pattern(self):
d = {
"results": [
{
"name": "A",
"props": [1, 2, 3],
},
{
"name": "B",
"props": [4, 5, 6],
},
{
"name": "C",
"props": [7, 8, 9],
},
],
}
b = benedict(d)
m = b.match("results[*].name")
self.assertEqual(m, ["A", "B", "C"])
m = b.match("results[*].props[0]")
self.assertEqual(m, [1, 4, 7])
m = b.match("results[*].props[1]")
self.assertEqual(m, [2, 5, 8])
m = b.match("results[*].props[2]")
self.assertEqual(m, [3, 6, 9])
def test_match_with_string_pattern_and_custom_keypath_separator(self):
d = {
"results": [
{
"name": "A",
"props": [1, 2, 3],
},
{
"name": "B",
"props": [4, 5, 6],
},
{
"name": "C",
"props": [7, 8, 9],
},
],
}
b = benedict(d, keypath_separator="/")
m = b.match("results[*]/name")
self.assertEqual(m, ["A", "B", "C"])
m = b.match("results[*]/props[2]")
self.assertEqual(m, [3, 6, 9])
def test_merge_with_single_dict(self):
d = {
"a": 1,
"b": 1,
}
a = {
"b": 2,
"c": 3,
}
d = benedict(d)
d.merge(a)
r = {
"a": 1,
"b": 2,
"c": 3,
}
self.assertEqual(d, r)
def test_merge_with_multiple_dicts(self):
d = {
"a": 1,
"b": 1,
}
a = {
"b": 2,
"c": 3,
"d": 3,
}
b = {
"d": 5,
"e": 5,
}
c = {
"d": 4,
"f": 6,
}
d = benedict(d)
d.merge(a, b, c)
r = {
"a": 1,
"b": 2,
"c": 3,
"d": 4,
"e": 5,
"f": 6,
}
self.assertEqual(d, r)
def test_merge(self):
d = {
"a": 1,
"b": {
"c": {
"x": 2,
"y": 3,
},
"d": {
"x": 4,
"y": 5,
},
"e": {
"x": 6,
"y": 7,
},
},
}
a = {
"a": 0,
"b": {
"c": 1,
"d": {
"y": 1,
"z": 2,
},
"e": {
"f": {
"x": 2,
"y": 3,
},
"g": {
"x": 4,
"y": 5,
},
},
},
}
d = benedict(d)
d.merge(a)
r = {
"a": 0,
"b": {
"c": 1,
"d": {
"x": 4,
"y": 1,
"z": 2,
},
"e": {
"f": {
"x": 2,
"y": 3,
},
"g": {
"x": 4,
"y": 5,
},
"x": 6,
"y": 7,
},
},
}
self.assertEqual(d, r)
def test_move(self):
d = {
"a": {
"x": 1,
"y": 1,
},
"b": {
"x": 2,
"y": 2,
},
"c": {
"x": 3,
"y": 3,
},
}
b = benedict(d)
b.move("a", "c.z")
r = {
"b": {
"x": 2,
"y": 2,
},
"c": {
"x": 3,
"y": 3,
"z": {
"x": 1,
"y": 1,
},
},
}
self.assertEqual(b, r)
def test_nest(self):
d = {
"values": [
{"id": 1, "parent_id": None, "name": "John"},
{"id": 2, "parent_id": 1, "name": "Frank"},
{"id": 3, "parent_id": 2, "name": "Tony"},
{"id": 4, "parent_id": 3, "name": "Jimmy"},
{"id": 5, "parent_id": 1, "name": "Sam"},
{"id": 6, "parent_id": 3, "name": "Charles"},
{"id": 7, "parent_id": 2, "name": "Bob"},
{"id": 8, "parent_id": 3, "name": "Paul"},
{"id": 9, "parent_id": None, "name": "Michael"},
],
}
bd = benedict(d)
n = bd.nest("values")
r = [
{
"id": 1,
"parent_id": None,
"name": "John",
"children": [
{
"id": 2,
"parent_id": 1,
"name": "Frank",
"children": [
{
"id": 3,
"parent_id": 2,
"name": "Tony",
"children": [
{
"id": 4,
"parent_id": 3,
"name": "Jimmy",
"children": [],
},
{
"id": 6,
"parent_id": 3,
"name": "Charles",
"children": [],
},
{
"id": 8,
"parent_id": 3,
"name": "Paul",
"children": [],
},
],
},
{
"id": 7,
"parent_id": 2,
"name": "Bob",
"children": [],
},
],
},
{
"id": 5,
"parent_id": 1,
"name": "Sam",
"children": [],
},
],
},
{
"id": 9,
"parent_id": None,
"name": "Michael",
"children": [],
},
]
self.assertEqual(n, r)
def test_nest_with_custom_keys(self):
d = {
"values": [
{"ID": 1, "PARENT": None, "name": "John"},
{"ID": 2, "PARENT": 1, "name": "Frank"},
{"ID": 3, "PARENT": 2, "name": "Tony"},
{"ID": 4, "PARENT": 3, "name": "Jimmy"},
{"ID": 5, "PARENT": 1, "name": "Sam"},
{"ID": 6, "PARENT": 3, "name": "Charles"},
{"ID": 7, "PARENT": 2, "name": "Bob"},
{"ID": 8, "PARENT": 3, "name": "Paul"},
{"ID": 9, "PARENT": None, "name": "Michael"},
],
}
bd = benedict(d)
n = bd.nest("values", "ID", "PARENT", "CHILDREN")
r = [
{
"ID": 1,
"PARENT": None,
"name": "John",
"CHILDREN": [
{
"ID": 2,
"PARENT": 1,
"name": "Frank",
"CHILDREN": [
{
"ID": 3,
"PARENT": 2,
"name": "Tony",
"CHILDREN": [
{
"ID": 4,
"PARENT": 3,
"name": "Jimmy",
"CHILDREN": [],
},
{
"ID": 6,
"PARENT": 3,
"name": "Charles",
"CHILDREN": [],
},
{
"ID": 8,
"PARENT": 3,
"name": "Paul",
"CHILDREN": [],
},
],
},
{
"ID": 7,
"PARENT": 2,
"name": "Bob",
"CHILDREN": [],
},
],
},
{
"ID": 5,
"PARENT": 1,
"name": "Sam",
"CHILDREN": [],
},
],
},
{
"ID": 9,
"PARENT": None,
"name": "Michael",
"CHILDREN": [],
},
]
self.assertEqual(n, r)
def test_pop(self):
d = {
"a": 1,
"b": {
"c": 2,
"d": {
"e": 3,
},
},
}
b = benedict(d)
self.assertEqual(b.pop("a"), 1)
self.assertEqual(b.pop("b.c"), 2)
# self.assertTrue(isinstance(b.pop('b.d'), benedict))
def test_remove_with_key(self):
d = {
"a": 1,
"b": 2,
"c": "4",
}
b = benedict(d)
b.remove("c")
r = {
"a": 1,
"b": 2,
}
self.assertEqual(b, r)
def test_remove_with_keys_list(self):
d = {
"a": 1,
"b": 2,
"c": "4",
"e": "5",
"f": 6,
"g": 7,
}
b = benedict(d)
b.remove(["c", "e", "f", "g", "x", "y", "z"])
r = {
"a": 1,
"b": 2,
}
self.assertEqual(b, r)
def test_remove_with_keys_args(self):
d = {
"a": 1,
"b": 2,
"c": "4",
"e": "5",
"f": 6,
"g": 7,
}
b = benedict(d)
b.remove("c", "e", "f", "g", "x", "y", "z")
r = {
"a": 1,
"b": 2,
}
self.assertEqual(b, r)
def test_remove_with_keypath(self):
d = {
"a": {
"x": 1,
"y": 1,
},
"b": {
"x": 2,
"y": 2,
},
"c": {
"x": 3,
"y": 3,
},
"d": {
"x": 4,
"y": 4,
},
}
b = benedict(d)
b.remove(["a.x", "b.y", "c.x", "c.y", "d"])
r = {
"a": {"y": 1},
"b": {"x": 2},
"c": {},
}
self.assertEqual(b, r)
def test_rename(self):
d = {
"a": {
"x": 1,
"y": 1,
},
"b": {
"x": 2,
"y": 2,
},
}
b = benedict(d)
b.rename("a.x", "a.xx")
b.rename("a.y", "a.yy")
b.rename("a", "aa")
r = {
"aa": {
"xx": 1,
"yy": 1,
},
"b": {
"x": 2,
"y": 2,
},
}
self.assertEqual(b, r)
with self.assertRaises(KeyError):
b.rename("aa", "b")
def test_search(self):
d = {
"a": "Hello world",
"b": "Hello world!",
"c": {
"d": True,
"e": " hello world ",
"f": {
"g": "HELLO",
"h": 12345,
"hello": True,
},
},
"Hello world": "Hello World",
}
b = benedict(d)
results = b.search(
"Hello", in_keys=False, in_values=False, exact=True, case_sensitive=True
)
self.assertEqual(len(results), 0)
self.assertEqual(results, [])
results = b.search(
"Hello", in_keys=False, in_values=True, exact=True, case_sensitive=True
)
self.assertEqual(len(results), 0)
self.assertEqual(results, [])
results = b.search(
"Hello", in_keys=False, in_values=True, exact=True, case_sensitive=False
)
self.assertEqual(len(results), 1)
self.assertTrue(
(
d["c"]["f"],
"g",
d["c"]["f"]["g"],
)
in results
)
results = b.search(
"hello", in_keys=True, in_values=True, exact=False, case_sensitive=False
)
self.assertEqual(len(results), 6)
self.assertTrue(
(
d,
"a",
d["a"],
)
in results
)
self.assertTrue(
(
d,
"b",
d["b"],
)
in results
)
self.assertTrue(
(
d["c"],
"e",
d["c"]["e"],
)
in results
)
self.assertTrue(
(
d["c"]["f"],
"g",
d["c"]["f"]["g"],
)
in results
)
self.assertTrue(
(
d["c"]["f"],
"hello",
d["c"]["f"]["hello"],
)
in results
)
self.assertTrue(
(
d,
"Hello world",
d["Hello world"],
)
in results
)
results = b.search(
"hello", in_keys=True, in_values=False, exact=False, case_sensitive=False
)
self.assertEqual(len(results), 2)
self.assertTrue(
(
d["c"]["f"],
"hello",
d["c"]["f"]["hello"],
)
in results
)
self.assertTrue(
(
d,
"Hello world",
d["Hello world"],
)
in results
)
# def test_setdefault(self):
# d = {
# 'a': 1,
# 'b': {
# 'c': 2,
# 'd': {
# 'e': 3,
# }
# }
# }
# b = benedict(d)
# self.assertTrue(isinstance(b.setdefault('b', 1), benedict))
# self.assertTrue(isinstance(b.setdefault('b.d', 1), benedict))
def test_standardize(self):
d = {
"CamelCase": 1,
"CamelCamelCase": 1,
"Camel2Camel2Case": 1,
"getHTTPResponseCode": 1,
"get2HTTPResponseCode": 1,
"HTTPResponseCode": 1,
"HTTPResponseCodeXYZ": 1,
" LocationCoordinates ": {
"Lat. ": 0.0,
"Lng. ": 0.0,
},
}
b = benedict(d, keypath_separator=None)
b.standardize()
b.keypath_separator = "."
r = {
"camel_case": 1,
"camel_camel_case": 1,
"camel2_camel2_case": 1,
"get_http_response_code": 1,
"get2_http_response_code": 1,
"http_response_code": 1,
"http_response_code_xyz": 1,
"location_coordinates": {
"lat": 0.0,
"lng": 0.0,
},
}
self.assertEqual(b, r)
self.assertEqual(b["location_coordinates.lat"], 0.0)
self.assertEqual(b["location_coordinates.lng"], 0.0)
def test_subset(self):
d = {
"a": 1,
"b": 2,
"c": "4",
"e": "5",
"f": 6,
"g": 7,
}
b = benedict(d)
f = b.subset(["c", "f", "x"])
r = {
"c": "4",
"f": 6,
"x": None,
}
self.assertEqual(f, r)
self.assertFalse(f is b)
self.assertEqual(type(b), type(f))
self.assertTrue(isinstance(f, benedict))
def test_subset_with_custom_keypath_separator(self):
d = {
"a.x": 1,
"b.x": 2,
"c.x": "4",
"e.x": "5",
"f.x": 6,
"g.x": 7,
}
b = benedict(d, keypath_separator="/")
f = b.subset(["c.x", "f.x", "x.x"])
r = {
"c.x": "4",
"f.x": 6,
"x.x": None,
}
self.assertEqual(f, r)
self.assertFalse(f is b)
self.assertEqual(type(b), type(f))
self.assertTrue(isinstance(f, benedict))
self.assertEqual(b.keypath_separator, f.keypath_separator)
def test_subset_with_keys_args(self):
d = {
"a": 1,
"b": 2,
"c": "4",
"e": "5",
"f": 6,
"g": 7,
}
b = benedict(d)
f = b.subset("c", "f", "x")
r = {
"c": "4",
"f": 6,
"x": None,
}
self.assertEqual(f, r)
self.assertFalse(f is b)
def test_subset_with_keypath(self):
d = {
"x": {
"a": 1,
"aa": 1,
},
"y": {
"b": 2,
"bb": 2,
},
"z": {
"c": 3,
"cc": 3,
},
}
b = benedict(d)
f = b.subset(["x", "y"])
r = {
"x": {
"a": 1,
"aa": 1,
},
"y": {
"b": 2,
"bb": 2,
},
}
self.assertEqual(f, r)
self.assertFalse(f is b)
self.assertTrue(isinstance(f, benedict))
self.assertEqual(f.get("x.a"), 1)
self.assertEqual(f.get("x.aa"), 1)
self.assertEqual(f.get("y.b"), 2)
self.assertEqual(f.get("y.bb"), 2)
# test with keypath
f = b.subset(["x.a", "y.b"])
r = {
"x": {
"a": 1,
},
"y": {
"b": 2,
},
}
self.assertEqual(f, r)
self.assertFalse(f is b)
self.assertTrue(isinstance(f, benedict))
self.assertEqual(f.get("x.a"), 1)
self.assertEqual(f.get("y.b"), 2)
def test_swap(self):
d = {
"a": 1,
"b": 2,
"c": 3,
}
b = benedict(d)
b.swap("a", "b")
r = {
"a": 2,
"b": 1,
"c": 3,
}
self.assertEqual(b, r)
def test_swap_with_invalid_key(self):
d = {
"a": 1,
"b": 2,
"c": 3,
}
b = benedict(d)
with self.assertRaises(KeyError):
b.swap("a", "d")
def test_swap_with_keypath(self):
d = {
"a": {
"x": 1,
"y": 1,
},
"b": {
"x": 2,
"y": 2,
},
"c": {
"x": 3,
"y": 3,
},
}
b = benedict(d)
b.swap("a.y", "b.y")
b.swap("b.x", "c.x")
r = {
"a": {
"x": 1,
"y": 2,
},
"b": {
"x": 3,
"y": 1,
},
"c": {
"x": 2,
"y": 3,
},
}
self.assertEqual(b, r)
b.swap("a", "c")
r = {
"a": {
"x": 2,
"y": 3,
},
"b": {
"x": 3,
"y": 1,
},
"c": {
"x": 1,
"y": 2,
},
}
self.assertEqual(b, r)
def test_traverse(self):
d = {
"a": {
"x": 2,
"y": 3,
"z": {
"ok": 5,
},
},
"b": {
"x": 7,
"y": 11,
"z": {
"ok": 13,
},
},
"c": {
"x": 17,
"y": 19,
"z": {
"ok": 23,
},
},
}
b = benedict(d)
def f(parent, key, value):
if not isinstance(value, dict):
parent[key] = value + 1
b.traverse(f)
r = {
"a": {
"x": 3,
"y": 4,
"z": {
"ok": 6,
},
},
"b": {
"x": 8,
"y": 12,
"z": {
"ok": 14,
},
},
"c": {
"x": 18,
"y": 20,
"z": {
"ok": 24,
},
},
}
self.assertEqual(b, r)
def test_unflatten(self):
d = {
"device_os": "Windows",
"device_lang": "en-US",
"device_code": 43,
"browser_name": "Chrome",
"browser_layout": "Webkit",
}
b = benedict(d)
u = b.unflatten()
r = {
"device": {
"os": "Windows",
"lang": "en-US",
"code": 43,
},
"browser": {
"name": "Chrome",
"layout": "Webkit",
},
}
self.assertEqual(u, r)
self.assertEqual(u.flatten(), b)
self.assertEqual(type(b), type(u))
self.assertTrue(isinstance(u, benedict))
def test_unique(self):
d = {
"a": {
"x": 1,
"y": 1,
},
"b": {
"x": 2,
"y": 2,
},
"c": {
"x": 1,
"y": 1,
},
"d": {
"x": 1,
},
"e": {
"x": 1,
"y": 1,
"z": 1,
},
"f": {
"x": 2,
"y": 2,
},
}
b = benedict(d)
b.unique()
rv = [
{
"x": 1,
"y": 1,
},
{
"x": 2,
"y": 2,
},
{
"x": 1,
},
{
"x": 1,
"y": 1,
"z": 1,
},
]
self.assertEqual(len(b.keys()), len(rv))
self.assertTrue(all([value in rv for value in b.values()]))