[#1928] Helper functions and tests
This commit is contained in:
parent
ba9b41ed4b
commit
f9bd07c3ed
2 changed files with 70 additions and 0 deletions
|
|
@ -1603,6 +1603,8 @@ class CmdSetAttribute(ObjManipCommand):
|
||||||
key = "set"
|
key = "set"
|
||||||
locks = "cmd:perm(set) or perm(Builder)"
|
locks = "cmd:perm(set) or perm(Builder)"
|
||||||
help_category = "Building"
|
help_category = "Building"
|
||||||
|
nested_re = re.compile(r'\[.*?\]')
|
||||||
|
not_found = object()
|
||||||
|
|
||||||
def check_obj(self, obj):
|
def check_obj(self, obj):
|
||||||
"""
|
"""
|
||||||
|
|
@ -1627,6 +1629,38 @@ class CmdSetAttribute(ObjManipCommand):
|
||||||
"""
|
"""
|
||||||
return attr_name
|
return attr_name
|
||||||
|
|
||||||
|
def split_nested_attr(self, attr):
|
||||||
|
"""
|
||||||
|
Yields tuples of (possible attr name, nested keys on that attr).
|
||||||
|
For performance, this is biased to the deepest match, but allows compatability
|
||||||
|
with older attrs that might have been named with `[]`'s.
|
||||||
|
|
||||||
|
> list(split_nested_attr("nested['asdf'][0]"))
|
||||||
|
[
|
||||||
|
('nested', ['asdf', 0]),
|
||||||
|
("nested['asdf']", [0]),
|
||||||
|
("nested['asdf'][0]", []),
|
||||||
|
]
|
||||||
|
"""
|
||||||
|
parts = self.nested_re.findall(attr)
|
||||||
|
|
||||||
|
base_attr = ''
|
||||||
|
if parts:
|
||||||
|
base_attr = attr[:attr.find(parts[0])]
|
||||||
|
for index, part in enumerate(parts):
|
||||||
|
yield (base_attr, [p.strip('"\'[]') for p in parts[index:]])
|
||||||
|
base_attr += part
|
||||||
|
yield (attr, [])
|
||||||
|
|
||||||
|
def do_nested_lookup(self, value, *keys):
|
||||||
|
result = value
|
||||||
|
for key in keys:
|
||||||
|
try:
|
||||||
|
result = result.__getitem__(key)
|
||||||
|
except (IndexError, KeyError, TypeError):
|
||||||
|
return self.not_found
|
||||||
|
return result
|
||||||
|
|
||||||
def view_attr(self, obj, attr):
|
def view_attr(self, obj, attr):
|
||||||
"""
|
"""
|
||||||
Look up the value of an attribute and return a string displaying it.
|
Look up the value of an attribute and return a string displaying it.
|
||||||
|
|
|
||||||
|
|
@ -535,6 +535,42 @@ class TestBuilding(CommandTest):
|
||||||
self.call(building.CmdWipe(), "Obj2/test2/test3", "Wiped attributes test2,test3 on Obj2.")
|
self.call(building.CmdWipe(), "Obj2/test2/test3", "Wiped attributes test2,test3 on Obj2.")
|
||||||
self.call(building.CmdWipe(), "Obj2", "Wiped all attributes on Obj2.")
|
self.call(building.CmdWipe(), "Obj2", "Wiped all attributes on Obj2.")
|
||||||
|
|
||||||
|
def test_split_nested_attr(self):
|
||||||
|
split_nested_attr = building.CmdSetAttribute().split_nested_attr
|
||||||
|
test_cases = {
|
||||||
|
'test1': [('test1', [])],
|
||||||
|
'test2["dict"]': [('test2', ['dict']), ('test2["dict"]', [])],
|
||||||
|
# Quotes not actually required
|
||||||
|
'test3[dict]': [('test3', ['dict']), ('test3[dict]', [])],
|
||||||
|
# duplicate keys don't cause issues
|
||||||
|
'test4[0][0]': [('test4', ['0', '0']), ('test4[0]', ['0']), ('test4[0][0]', [])],
|
||||||
|
}
|
||||||
|
|
||||||
|
for attr, result in test_cases.items():
|
||||||
|
self.assertEqual(list(split_nested_attr(attr)), result)
|
||||||
|
|
||||||
|
def test_do_nested_lookup(self):
|
||||||
|
do_nested_lookup = building.CmdSetAttribute().do_nested_lookup
|
||||||
|
not_found = building.CmdSetAttribute.not_found
|
||||||
|
|
||||||
|
def do_test_single(value, key, result):
|
||||||
|
self.assertEqual(do_nested_lookup(value, key), result)
|
||||||
|
|
||||||
|
def do_test_multi(value, keys, result):
|
||||||
|
self.assertEqual(do_nested_lookup(value, *keys), result)
|
||||||
|
|
||||||
|
do_test_single([], 'test1', not_found)
|
||||||
|
do_test_single([1], 'test2', not_found)
|
||||||
|
do_test_single([], 0, not_found)
|
||||||
|
do_test_single([1], 2, not_found)
|
||||||
|
do_test_single([1], 0, 1)
|
||||||
|
do_test_single({}, 'test3', not_found)
|
||||||
|
do_test_single({}, 0, not_found)
|
||||||
|
do_test_single({'foo': 'bar'}, 'foo', 'bar')
|
||||||
|
|
||||||
|
do_test_multi({'one': [1, 2, 3]}, ('one', 0), 1)
|
||||||
|
do_test_multi([{}, {'two': 2}, 3], (1, 'two'), 2)
|
||||||
|
|
||||||
def test_name(self):
|
def test_name(self):
|
||||||
self.call(building.CmdName(), "", "Usage: ")
|
self.call(building.CmdName(), "", "Usage: ")
|
||||||
self.call(building.CmdName(), "Obj2=Obj3", "Object's name changed to 'Obj3'.")
|
self.call(building.CmdName(), "Obj2=Obj3", "Object's name changed to 'Obj3'.")
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue