#!/usr/bin/env python # -*- coding: UTF-8 -*- # Test files gathered from json.org and yaml.org import copy import json import os import pickle import shutil from multiprocessing import Queue from pathlib import Path import pytest import ruamel.yaml as yaml from box import box from box import Box, BoxError, BoxKeyError, BoxList, SBox, ConfigBox from test.common import (test_dict, extended_test_dict, tmp_dir, tmp_json_file, tmp_yaml_file, movie_data, data_json_file, data_yaml_file, test_root) def mp_queue_test(q): bx = q.get() try: assert isinstance(bx, Box) assert bx.a == 4 except AssertionError: q.put(False) else: q.put(True) class TestBox: @pytest.fixture(autouse=True) def temp_dir_cleanup(self): shutil.rmtree(tmp_dir, ignore_errors=True) try: os.mkdir(tmp_dir) except OSError: pass yield shutil.rmtree(tmp_dir, ignore_errors=True) def test_safe_attrs(self): assert Box()._safe_attr("BAD!KEY!1") == "BAD_KEY_1" assert Box(camel_killer_box=True)._safe_attr("BAD!KEY!2") == "bad_key_2" assert Box()._safe_attr((5, 6, 7)) == "x5_6_7" assert Box()._safe_attr(356) == "x356" def test_camel_killer(self): assert box._camel_killer("CamelCase") == "camel_case" assert box._camel_killer("Terrible321KeyA") == "terrible321_key_a" bx = Box(camel_killer_box=True, conversion_box=False) bx.DeadCamel = 3 assert bx['dead_camel'] == 3 assert bx.dead_camel == 3 bx['BigCamel'] = 4 assert bx['big_camel'] == 4 assert bx.big_camel == 4 assert bx.BigCamel == 4 bx1 = Box(camel_killer_box=True, conversion_box=True) bx1['BigCamel'] = 4 bx1.DeadCamel = 3 assert bx1['big_camel'] == 4 assert bx1['dead_camel'] == 3 assert bx1.big_camel == 4 assert bx1.dead_camel == 3 assert bx1.BigCamel == 4 assert bx1['BigCamel'] == 4 del bx1.DeadCamel assert 'dead_camel' not in bx1 del bx1['big_camel'] assert 'big_camel' not in bx1 assert len(bx1.keys()) == 0 def test_recursive_tuples(self): out = box._recursive_tuples(({'test': 'a'}, ({'second': 'b'}, {'third': 'c'}, ('fourth',))), dict, recreate_tuples=True) assert isinstance(out, tuple) assert isinstance(out[0], dict) assert out[0] == {'test': 'a'} assert isinstance(out[1], tuple) assert isinstance(out[1][2], tuple) assert out[1][0] == {'second': 'b'} def test_box(self): bx = Box(**test_dict) assert bx.key1 == test_dict['key1'] assert dict(getattr(bx, 'Key 2')) == test_dict['Key 2'] setattr(bx, 'TEST_KEY', 'VALUE') assert bx.TEST_KEY == 'VALUE' delattr(bx, 'TEST_KEY') assert 'TEST_KEY' not in bx.to_dict(), bx.to_dict() assert isinstance(bx['Key 2'].Key4, Box) assert "'key1': 'value1'" in str(bx) assert repr(bx).startswith("<Box:") bx2 = Box([((3, 4), "A"), ("_box_config", 'test')]) assert bx2[(3, 4)] == "A" assert bx2['_box_config'] == 'test' bx3 = Box(a=4, conversion_box=False) setattr(bx3, 'key', 2) assert bx3.key == 2 bx3.__setattr__("Test", 3) assert bx3.Test == 3 def test_box_modify_at_depth(self): bx = Box(**test_dict) assert 'key1' in bx assert 'key2' not in bx bx['Key 2'].new_thing = "test" assert bx['Key 2'].new_thing == "test" bx['Key 2'].new_thing += "2" assert bx['Key 2'].new_thing == "test2" assert bx['Key 2'].to_dict()['new_thing'] == "test2" assert bx.to_dict()['Key 2']['new_thing'] == "test2" bx.__setattr__('key1', 1) assert bx['key1'] == 1 bx.__delattr__('key1') assert 'key1' not in bx def test_error_box(self): bx = Box(**test_dict) with pytest.raises(AttributeError): getattr(bx, 'hello') def test_box_from_dict(self): ns = Box({"k1": "v1", "k2": {"k3": "v2"}}) assert ns.k2.k3 == "v2" def test_box_from_bad_dict(self): with pytest.raises(ValueError): Box('{"k1": "v1", "k2": {"k3": "v2"}}') def test_basic_box(self): a = Box(one=1, two=2, three=3) b = Box({'one': 1, 'two': 2, 'three': 3}) c = Box((zip(['one', 'two', 'three'], [1, 2, 3]))) d = Box(([('two', 2), ('one', 1), ('three', 3)])) e = Box(({'three': 3, 'one': 1, 'two': 2})) assert a == b == c == d == e def test_protected_box_methods(self): my_box = Box(a=3) with pytest.raises(AttributeError): my_box.to_dict = 'test' with pytest.raises(AttributeError): del my_box.to_json def test_bad_args(self): with pytest.raises(TypeError): Box('123', '432') def test_box_inits(self): a = Box({'data': 2, 'count': 5}) b = Box(data=2, count=5) c = Box({'data': 2, 'count': 1}, count=5) d = Box([('data', 2), ('count', 5)]) e = Box({'a': [{'item': 3}, {'item': []}]}) assert e.a[1].item == [] assert a == b == c == d def test_bad_inits(self): with pytest.raises(ValueError): Box("testing") with pytest.raises(ValueError): Box(22) with pytest.raises(TypeError): Box(22, 33) def test_create_subdicts(self): a = Box({'data': 2, 'count': 5}) a.brand_new = {'subdata': 1} assert a.brand_new.subdata == 1 a.new_list = [{'sub_list_item': 1}] assert a.new_list[0].sub_list_item == 1 assert isinstance(a.new_list, BoxList) a.new_list2 = [[{'sub_list_item': 2}]] assert a.new_list2[0][0].sub_list_item == 2 b = a.to_dict() assert not isinstance(b['new_list'], BoxList) def test_to_json_basic(self): a = Box(test_dict) assert json.loads(a.to_json(indent=0)) == test_dict a.to_json(tmp_json_file) with open(tmp_json_file) as f: data = json.load(f) assert data == test_dict def test_to_yaml_basic(self): a = Box(test_dict) assert yaml.load(a.to_yaml(), Loader=yaml.SafeLoader) == test_dict def test_to_yaml_file(self): a = Box(test_dict) a.to_yaml(tmp_yaml_file) with open(tmp_yaml_file) as f: data = yaml.load(f, Loader=yaml.SafeLoader) assert data == test_dict def test_dir(self): a = Box(test_dict, camel_killer_box=True) assert 'key1' in dir(a) assert 'not$allowed' not in dir(a) assert 'key4' in a['key 2'] for item in ('to_yaml', 'to_dict', 'to_json'): assert item in dir(a) assert a.big_camel == 'hi' assert 'big_camel' in dir(a) def test_update(self): a = Box(test_dict) a.grand = 1000 a.update({'key1': {'new': 5}, 'Key 2': {"add_key": 6}, 'lister': ['a']}) a.update([('asdf', 'fdsa')]) a.update(testkey=66) a.update({'items': {'test': 'pme'}}) a.update({'key1': {'gg': 4}}) b = Box() b.update(item=1) b.update(E=1) b.update(__m=1) with pytest.raises(ValueError): b.update('test') assert a.grand == 1000 assert a['grand'] == 1000 assert isinstance(a['items'], Box) assert a['items'].test == 'pme' assert a['Key 2'].add_key == 6 assert isinstance(a.key1, Box) assert isinstance(a.lister, BoxList) assert a.asdf == 'fdsa' assert a.testkey == 66 assert a.key1.gg == 4 assert 'new' not in a.key1.keys() def test_merge_update(self): a = Box(test_dict) a.grand = 1000 a.merge_update({'key1': {'new': 5}, 'Key 2': {"add_key": 6}, 'lister': ['a']}) a.merge_update([('asdf', 'fdsa')]) a.merge_update(testkey=66) a.merge_update({'items': {'test': 'pme'}}) a.merge_update({'key1': {'gg': 4}}) b = Box() b.merge_update(item=1) b.merge_update(E=4) b.merge_update(__m=1) assert a.grand == 1000 assert a['grand'] == 1000 assert isinstance(a['items'], Box) assert a['items'].test == 'pme' assert a.key1.new == 5 assert a['Key 2'].add_key == 6 assert isinstance(a.key1, Box) assert isinstance(a.lister, BoxList) assert a.asdf == 'fdsa' assert a.testkey == 66 assert a.key1.new == 5 assert a.key1.gg == 4 with pytest.raises(ValueError): b.merge_update('test') def test_auto_attr(self): a = Box(test_dict, default_box=True) assert isinstance(a.a.a.a.a, Box) a.b.b = 4 assert a.b.b == 4 def test_set_default(self): a = Box(test_dict) new = a.setdefault("key3", {'item': 2}) new_list = a.setdefault("lister", [{'gah': 7}]) assert a.setdefault("key1", False) == 'value1' assert new == Box(item=2) assert new_list == BoxList([{'gah': 7}]) assert a.key3.item == 2 assert a.lister[0].gah == 7 def test_from_json_file(self): bx = Box.from_json(filename=data_json_file) assert isinstance(bx, Box) assert bx.widget.window.height == 500 def test_from_yaml_file(self): bx = Box.from_yaml(filename=data_yaml_file) assert isinstance(bx, Box) assert bx.total == 4443.52 def test_from_json(self): bx = Box.from_json(json.dumps(test_dict)) assert isinstance(bx, Box) assert bx.key1 == 'value1' def test_from_yaml(self): bx = Box.from_yaml(yaml.dump(test_dict), conversion_box=False, default_box=True) assert isinstance(bx, Box) assert bx.key1 == 'value1' assert bx.Key_2 == Box() def test_bad_from_json(self): with pytest.raises(BoxError) as err: Box.from_json() with pytest.raises(BoxError) as err2: Box.from_json(json_string="[1]") def test_bad_from_yaml(self): with pytest.raises(BoxError) as err: Box.from_yaml() with pytest.raises(BoxError) as err2: Box.from_yaml('lol') def test_conversion_box(self): bx = Box(extended_test_dict, conversion_box=True) assert bx.Key_2.Key_3 == "Value 3" assert bx.x3 == 'howdy' assert bx.xnot == 'true' assert bx.x3_4 == 'test' with pytest.raises(AttributeError): getattr(bx, "(3, 4)") def test_frozen(self): bx = Box(extended_test_dict, frozen_box=True) assert isinstance(bx.alist, tuple) assert bx.alist[0] == {'a': 1} with pytest.raises(BoxError): bx.new = 3 with pytest.raises(BoxError): bx['new'] = 3 with pytest.raises(BoxError): del bx['not'] with pytest.raises(BoxError): delattr(bx, "key1") with pytest.raises(TypeError): hash(bx) bx2 = Box(test_dict) with pytest.raises(TypeError): hash(bx2) bx3 = Box(test_dict, frozen_box=True) assert hash(bx3) def test_hashing(self): bx1 = Box(t=3, g=4, frozen_box=True) bx2 = Box(g=4, t=3, frozen_box=True) assert hash(bx1) == hash(bx2) bl1 = BoxList([1, 2, 3, 4], frozen_box=True) bl2 = BoxList([1, 2, 3, 4], frozen_box=True) bl3 = BoxList([2, 1, 3, 4], frozen_box=True) assert hash(bl2) == hash(bl1) assert hash(bl3) != hash(bl2) with pytest.raises(TypeError): hash(BoxList([1, 2, 3])) def test_config(self): bx = Box(extended_test_dict) assert bx['_box_config'] is True assert isinstance(bx._box_config, dict) with pytest.raises(BoxError): delattr(bx, '_box_config') bx._box_config def test_default_box(self): bx = Box(test_dict, default_box=True, default_box_attr={'hi': 'there'}) assert bx.key_88 == {'hi': 'there'} assert bx['test'] == {'hi': 'there'} bx2 = Box(test_dict, default_box=True, default_box_attr=Box) assert isinstance(bx2.key_77, Box) bx3 = Box(default_box=True, default_box_attr=3) assert bx3.hello == 3 bx4 = Box(default_box=True, default_box_attr=None) assert bx4.who_is_there is None bx5 = Box(default_box=True, default_box_attr=[]) assert isinstance(bx5.empty_list_please, list) assert len(bx5.empty_list_please) == 0 bx5.empty_list_please.append(1) assert bx5.empty_list_please[0] == 1 bx6 = Box(default_box=True, default_box_attr=[]) my_list = bx6.get('new_list') my_list.append(5) assert bx6.get('new_list')[0] == 5 bx7 = Box(default_box=True, default_box_attr=False) assert bx7.nothing is False bx8 = Box(default_box=True, default_box_attr=0) assert bx8.nothing == 0 # Tests __get_default's `copy` clause s = {1, 2, 3} bx9 = Box(default_box=True, default_box_attr=s) assert isinstance(bx9.test, set) assert bx9.test == s assert id(bx9.test) != id(s) bx10 = Box({'from': 'here'}, default_box=True) assert bx10.xfrom == 'here' bx10.xfrom = 5 assert bx10.xfrom == 5 assert bx10 == {'from': 5} # Issue#59 https://github.com/cdgriffith/Box/issues/59 "Treat None values as non existing keys for default_box" def test_default_box_none_transforms(self): bx4 = Box({"noneValue": None, "inner": {"noneInner": None}}, default_box=True, default_box_attr="issue#59") assert bx4.noneValue == "issue#59" assert bx4.inner.noneInner == "issue#59" bx5 = Box({"noneValue": None, "inner": {"noneInner": None}}, default_box=True, default_box_none_transform=False, default_box_attr="attr") assert bx5.noneValue is None assert bx5.absentKey == "attr" assert bx5.inner.noneInner is None def test_camel_killer_box(self): td = extended_test_dict.copy() td['CamelCase'] = 'Item' td['321CamelCaseFever!'] = 'Safe' kill_box = Box(td, camel_killer_box=True, conversion_box=False) assert kill_box.camel_case == 'Item' assert kill_box['321CamelCaseFever!'] == 'Safe' con_kill_box = Box(td, conversion_box=True, camel_killer_box=True) assert con_kill_box.camel_case == 'Item' assert con_kill_box.x321_camel_case_fever == 'Safe' def test_default_and_camel_killer_box(self): td = extended_test_dict.copy() td['CamelCase'] = 'Item' killer_default_box = Box(td, camel_killer_box=True, default_box=True) assert killer_default_box.camel_case == 'Item' assert killer_default_box.CamelCase == 'Item' assert isinstance(killer_default_box.does_not_exist, Box) assert isinstance(killer_default_box['does_not_exist'], Box) def test_box_modify_tuples(self): bx = Box(extended_test_dict, modify_tuples_box=True) assert bx.tuples_galore[0].item == 3 assert isinstance(bx.tuples_galore[0], Box) assert isinstance(bx.tuples_galore[1], tuple) def test_box_set_attribs(self): bx = Box(extended_test_dict, conversion_box=False, camel_killer_box=True) bx.camel_case = {'new': 'item'} assert bx['CamelCase'] == Box(new='item') bx['CamelCase'] = 4 assert bx.camel_case == 4 bx2 = Box(extended_test_dict) bx2.Key_2 = 4 assert bx2["Key 2"] == 4 def test_functional_data(self): data = Box.from_json(filename=data_json_file, conversion_box=True, camel_killer_box=True, default_box=False) assert data.widget with pytest.raises(AttributeError): data._bad_value with pytest.raises(AttributeError): data.widget._bad_value base_config = data._Box__box_config() widget_config = data.widget._Box__box_config() assert base_config == widget_config, "{} != {}".format(base_config, widget_config) def test_functional_spaceballs(self): my_box = Box(movie_data) my_box.movies.Spaceballs.Stars.append( {"name": "Bill Pullman", "imdb": "nm0000597", "role": "Lone Starr"}) assert my_box.movies.Spaceballs.Stars[-1].role == "Lone Starr" assert my_box.movies.Robin_Hood_Men_in_Tights.length == 104 my_box.movies.Robin_Hood_Men_in_Tights.Stars.pop(0) assert my_box.movies.Robin_Hood_Men_in_Tights.Stars[ 0].name == "Richard Lewis" def test_circular_references(self): circular_dict = {} circular_dict['a'] = circular_dict bx = Box(circular_dict) assert bx.a.a == bx.a circular_dict_2 = bx.a.a.a.to_dict() assert str(circular_dict_2) == "{'a': {...}}" bx2 = Box(circular_dict, k=circular_dict) assert bx2.k == bx2.a with pytest.raises(ValueError): bx.to_json() circular_list = [] circular_list.append(circular_list) bl = BoxList(circular_list) assert bl == bl[0] assert isinstance(bl[0], BoxList) circular_list_2 = bl.to_list() assert circular_list_2 == circular_list_2[0] assert isinstance(circular_list_2, list) def test_to_multiline(self): a = BoxList([Box(a=1), Box(b=2), Box(three=5)]) a.to_json(tmp_json_file, multiline=True) count = 0 with open(tmp_json_file) as f: for line in f: assert isinstance(json.loads(line), dict) count += 1 assert count == 3 def test_from_multiline(self): content = '{"a": 2}\n{"b": 3}\r\n \n' with open(tmp_json_file, 'w') as f: f.write(content) a = BoxList.from_json(filename=tmp_json_file, multiline=True) assert a[1].b == 3 def test_duplicate_errors(self): with pytest.raises(BoxError) as err: Box({"?a": 1, "!a": 3}, box_duplicates="error") Box({"?a": 1, "!a": 3}, box_duplicates="ignore") with pytest.warns(UserWarning) as warning: Box({"?a": 1, "!a": 3}, box_duplicates="warn") assert warning[0].message.args[0].startswith("Duplicate") my_box = Box({"?a": 1}, box_duplicates="error") with pytest.raises(BoxError): my_box['^a'] = 3 def test_copy(self): my_box = Box(movie_data, camel_killer_box=True) bb = my_box.copy() assert my_box == bb assert isinstance(bb, Box) assert bb._box_config['camel_killer_box'] aa = copy.deepcopy(my_box) assert my_box == aa assert isinstance(aa, Box) cc = my_box.__copy__() assert my_box == cc assert isinstance(cc, Box) assert cc._box_config['camel_killer_box'] dd = BoxList([my_box]) assert dd == copy.copy(dd) assert isinstance(copy.copy(dd), BoxList) def test_custom_key_errors(self): my_box = Box() with pytest.raises(BoxKeyError): my_box.g with pytest.raises(AttributeError): my_box.g with pytest.raises(KeyError): my_box['g'] with pytest.raises(BoxKeyError): my_box['g'] with pytest.raises(BoxError): my_box['g'] def test_pickle(self): pic_file = os.path.join(tmp_dir, 'test.p') pic2_file = os.path.join(tmp_dir, 'test.p2') bb = Box(movie_data, conversion_box=False) pickle.dump(bb, open(pic_file, 'wb')) loaded = pickle.load(open(pic_file, 'rb')) assert bb == loaded assert loaded._box_config['conversion_box'] is False ll = [[Box({'a': 'b'})], [[{'c': 'g'}]]] bx = BoxList(ll) pickle.dump(bx, open(pic2_file, 'wb')) loaded2 = pickle.load(open(pic2_file, 'rb')) assert bx == loaded2 loaded2.box_options = bx.box_options def test_pickle_default_box(self): bb = Box(default_box=True) loaded = pickle.loads(pickle.dumps(bb)) assert bb == loaded def test_conversion_dup_only(self): with pytest.raises(BoxError): Box(movie_data, conversion_box=False, box_duplicates='error') def test_values(self): b = Box() b.foo = {} assert isinstance(list(b.values())[0], Box) c = Box() c.foohoo = [] assert isinstance(list(c.values())[0], BoxList) d = Box(movie_data) assert len(movie_data["movies"].values()) == len(d.movies.values()) def test_items(self): b = Box() b.foo = {} assert isinstance(list(b.items())[0][1], Box) c = Box() c.foohoo = [] assert isinstance(list(c.items())[0][1], BoxList) d = Box(movie_data) assert len(movie_data["movies"].items()) == len(d.movies.items()) def test_get(self): bx = Box() bx["c"] = {} assert bx.get("a") is None assert isinstance(bx.get("c"), Box) assert isinstance(bx.get("b", {}), Box) assert "a" in bx.get("a", Box(a=1, conversion_box=False)) assert isinstance(bx.get("a", [1, 2]), BoxList) def test_get_default_box(self): bx = Box(default_box=True) assert bx.get('test', 4) == 4 assert isinstance(bx.get('a'), Box) assert bx.get('test', None) is None def test_inheritance_copy(self): class Box2(Box): pass class SBox2(SBox): pass class ConfigBox2(ConfigBox): pass b = Box2(a=1) c = b.copy() assert c == b assert isinstance(c, Box) c = b.__copy__() assert c == b assert isinstance(c, Box) d = SBox2(a=1) e = d.copy() assert e == d assert isinstance(e, SBox) e = d.__copy__() assert e == d assert isinstance(e, SBox) f = ConfigBox2(a=1) g = f.copy() assert g == f assert isinstance(g, ConfigBox) g = f.__copy__() assert g == f assert isinstance(g, ConfigBox) def test_underscore_removal(self): from box import Box b = Box(_out='preserved', test_='safe') b.update({'out': 'updated', 'test': 'unsafe'}) assert b.out == 'updated' assert b._out == 'preserved' assert b.to_dict() == {'out': 'updated', 'test': 'unsafe', '_out': 'preserved', 'test_': 'safe'} assert b.test == 'unsafe' assert b.test_ == 'safe' def test_is_in(self): bx = Box() dbx = Box(default_box=True) assert "a" not in bx assert "a" not in dbx bx["b"] = 1 dbx["b"] = {} assert "b" in bx assert "b" in dbx def test_through_queue(self): my_box = Box(a=4, c={"d": 3}) queue = Queue() queue.put(my_box) assert queue.get() def test_update_with_integer(self): bx = Box() bx[1] = 4 assert bx[1] == 4 bx.update({1: 2}) assert bx[1] == 2 def test_get_box_config(self): bx = Box() bx_config = bx.__getattr__('_box_config') assert bx_config with pytest.raises(BoxKeyError): bx['_box_config'] def test_pop(self): bx = Box(a=4, c={"d": 3}, sub_box=Box(test=1)) assert bx.pop('a') == 4 with pytest.raises(BoxKeyError): bx.pop('b') assert bx.pop('a', None) is None assert bx.pop('a', True) is True with pytest.raises(BoxError): bx.pop(1, 2, 3) bx.pop('sub_box').pop('test') assert bx == {'c': {"d": 3}} assert bx.pop('c', True) is not True def test_pop_items(self): bx = Box(a=4) assert bx.popitem() == ('a', 4) with pytest.raises(BoxKeyError): assert bx.popitem() def test_iter(self): bx = Box() bx.a = 1 bx.c = 2 assert list(bx.__iter__()) == ['a', 'c'] def test_revered(self): bx = Box() bx.a = 1 bx.c = 2 assert list(reversed(bx)) == ['c', 'a'] def test_clear(self): bx = Box() bx.a = 1 bx.c = 4 bx['g'] = 7 bx.d = 2 assert list(bx.keys()) == ['a', 'c', 'g', 'd'] bx.clear() assert bx == {} assert not bx.keys() def test_bad_recursive(self): b = Box() bl = b.setdefault("l", []) bl.append(["foo"]) assert bl == [['foo']], bl def test_dots(self): b = Box(movie_data.copy(), box_dots=True) assert b['movies.Spaceballs.rating'] == "PG" b['movies.Spaceballs.rating'] = 4 assert b['movies.Spaceballs.rating'] == 4 del b['movies.Spaceballs.rating'] with pytest.raises(BoxKeyError): b['movies.Spaceballs.rating'] assert b['movies.Spaceballs.Stars[1].role'] == 'Barf' b['movies.Spaceballs.Stars[1].role'] = 'Testing' assert b['movies.Spaceballs.Stars[1].role'] == 'Testing' assert b.movies.Spaceballs.Stars[1].role == 'Testing' with pytest.raises(BoxError): b['.'] with pytest.raises(BoxError): from box.box import _parse_box_dots _parse_box_dots('-') def test_unicode(self): bx = Box() bx["\U0001f631"] = 4 bx2 = Box(camel_killer_box=True) bx2["\U0001f631"] = 4 assert bx == bx2 == {'😱': 4} def test_camel_killer_hashables(self): bx = Box(camel_killer_box=True) bx[(1, 2)] = 32 assert bx == {(1, 2): 32} def test_intact_types_dict(self): from collections import OrderedDict bx = Box(a=OrderedDict([('y', 1), ('x', 2)])) assert isinstance(bx.a, Box) assert not isinstance(bx.a, OrderedDict) bx = Box(a=OrderedDict([('y', 1), ('x', 2)]), box_intact_types=[OrderedDict]) assert isinstance(bx.a, OrderedDict) assert not isinstance(bx.a, Box) def test_delete_attributes(self): b = Box(notThief=1, sortaThief=0, reallyAThief=True, camel_killer_box=True) b['$OhNo!'] = 3 c = Box(notThief=1, sortaThief=0, reallyAThief=True, camel_killer_box=True, conversion_box=False) del b.not_thief del b._oh_no_ del b.really_a_thief with pytest.raises(KeyError): del b.really_a_thief with pytest.raises(KeyError): del b._oh_no_ del c.not_thief del c.really_a_thief with pytest.raises(KeyError): del c.really_a_thief def test_add_boxes(self): b = Box(c=1) c = Box(d=2) assert b + c == Box(c=1, d=2) with pytest.raises(BoxError): Box() + BoxList() def test_type_recast(self): b = Box(id='6', box_recast={'id': int}) assert isinstance(b.id, int) with pytest.raises(ValueError): b['sub_box'] = {'id': 'bad_id'} def test_box_dots(self): b = Box({'my_key': {'does stuff': {'to get to': 'where I want'}}}, box_dots=True) assert b['my_key.does stuff.to get to'] == 'where I want' b['my_key.does stuff.to get to'] = 'test' assert b['my_key.does stuff.to get to'] == 'test' del b['my_key.does stuff'] assert b['my_key'] == {} b[4] = 2 assert b[4] == 2 del b[4] def test_toml(self): b = Box.from_toml(filename=Path(test_root, "data", "toml_file.tml"), default_box=True) assert b.database.server == '192.168.1.1' assert b.clients.hosts == ["alpha", "omega"] assert b.database.to_toml().startswith('server = "192.168.1.1"') assert b._box_config['default_box'] is True def test_parameter_pass_through(self): bx = Box.from_yaml('uno: 2', box_dots=True, default_box=True, default_box_attr=None, default_box_none_transform=True, frozen_box=False, camel_killer_box=True, conversion_box=True, modify_tuples_box=True, box_safe_prefix='x', box_duplicates='warn', box_intact_types=(), box_recast=None) assert bx.uno == 2