[#1928] Create and access data structures
This commit is contained in:
parent
f9bd07c3ed
commit
d83e3d471e
2 changed files with 63 additions and 4 deletions
|
|
@ -1642,13 +1642,25 @@ class CmdSetAttribute(ObjManipCommand):
|
||||||
("nested['asdf'][0]", []),
|
("nested['asdf'][0]", []),
|
||||||
]
|
]
|
||||||
"""
|
"""
|
||||||
|
quotes = '"\''
|
||||||
|
|
||||||
|
def clean_key(val):
|
||||||
|
val = val.strip('[]')
|
||||||
|
if val[0] in quotes:
|
||||||
|
return val.strip(quotes)
|
||||||
|
|
||||||
|
try:
|
||||||
|
return int(val)
|
||||||
|
except ValueError:
|
||||||
|
return val
|
||||||
|
|
||||||
parts = self.nested_re.findall(attr)
|
parts = self.nested_re.findall(attr)
|
||||||
|
|
||||||
base_attr = ''
|
base_attr = ''
|
||||||
if parts:
|
if parts:
|
||||||
base_attr = attr[:attr.find(parts[0])]
|
base_attr = attr[:attr.find(parts[0])]
|
||||||
for index, part in enumerate(parts):
|
for index, part in enumerate(parts):
|
||||||
yield (base_attr, [p.strip('"\'[]') for p in parts[index:]])
|
yield (base_attr, [clean_key(p) for p in parts[index:]])
|
||||||
base_attr += part
|
base_attr += part
|
||||||
yield (attr, [])
|
yield (attr, [])
|
||||||
|
|
||||||
|
|
@ -1665,8 +1677,12 @@ class CmdSetAttribute(ObjManipCommand):
|
||||||
"""
|
"""
|
||||||
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.
|
||||||
"""
|
"""
|
||||||
if obj.attributes.has(attr):
|
for key, nested_keys in self.split_nested_attr(attr):
|
||||||
return "\nAttribute %s/%s = %s" % (obj.name, attr, obj.attributes.get(attr))
|
if obj.attributes.has(key):
|
||||||
|
val = obj.attributes.get(key)
|
||||||
|
val = self.do_nested_lookup(val, *nested_keys)
|
||||||
|
if val is not self.not_found:
|
||||||
|
return "\nAttribute %s/%s = %s" % (obj.name, attr, val)
|
||||||
else:
|
else:
|
||||||
return "\n%s has no attribute '%s'." % (obj.name, attr)
|
return "\n%s has no attribute '%s'." % (obj.name, attr)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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_nested_attribute_commands(self):
|
||||||
|
# adding white space proves real parsing
|
||||||
|
self.call(building.CmdSetAttribute(), "Obj/test1=[1,2]", "Created attribute Obj/test1 = [1, 2]")
|
||||||
|
self.call(building.CmdSetAttribute(), "Obj/test1", "Attribute Obj/test1 = [1, 2]")
|
||||||
|
self.call(building.CmdSetAttribute(), "Obj/test1[0]", "Attribute Obj/test1[0] = 1")
|
||||||
|
|
||||||
|
# removing white space proves real parsing
|
||||||
|
self.call(building.CmdSetAttribute(),
|
||||||
|
"Obj/test2={ 'one': 1 }", "Created attribute Obj/test2 = {'one': 1}")
|
||||||
|
self.call(building.CmdSetAttribute(), "Obj/test2", "Attribute Obj/test2 = {'one': 1}")
|
||||||
|
self.call(building.CmdSetAttribute(), "Obj/test2['one']", "Attribute Obj/test2['one'] = 1")
|
||||||
|
self.call(building.CmdSetAttribute(), "Obj/test2['one]", "Attribute Obj/test2['one] = 1")
|
||||||
|
self.call(building.CmdSetAttribute(), "Obj/test2[0]", "Obj has no attribute 'test2[0]'.")
|
||||||
|
|
||||||
|
# Deaper nesting
|
||||||
|
self.call(building.CmdSetAttribute(),
|
||||||
|
"Obj/test3=[{'one': 1}]", "Created attribute Obj/test3 = [{'one': 1}]")
|
||||||
|
self.call(building.CmdSetAttribute(), "Obj/test3[0]['one']", "Attribute Obj/test3[0]['one'] = 1")
|
||||||
|
self.call(building.CmdSetAttribute(), "Obj/test3[0]", "Attribute Obj/test3[0] = {'one': 1}")
|
||||||
|
|
||||||
|
# Naughty keys
|
||||||
|
self.call(building.CmdSetAttribute(),
|
||||||
|
"Obj/test4[0]='foo'", "Created attribute Obj/test4[0] = 'foo'")
|
||||||
|
self.call(building.CmdSetAttribute(), "Obj/test4[0]", "Attribute Obj/test4[0] = foo")
|
||||||
|
self.call(building.CmdSetAttribute(),
|
||||||
|
"Obj/test4=[{'one': 1}]", "Created attribute Obj/test4 = [{'one': 1}]")
|
||||||
|
self.call(building.CmdSetAttribute(), "Obj/test4[0]['one']", "Attribute Obj/test4[0]['one'] = 1")
|
||||||
|
# Prefer nested items
|
||||||
|
self.call(building.CmdSetAttribute(), "Obj/test4[0]", "Attribute Obj/test4[0] = {'one': 1}")
|
||||||
|
self.call(building.CmdSetAttribute(), "Obj/test4[0]['one']", "Attribute Obj/test4[0]['one'] = 1")
|
||||||
|
self.call(building.CmdWipe(), "Obj/test4", "Wiped attributes test4 on Obj.")
|
||||||
|
# Restored access
|
||||||
|
self.call(building.CmdSetAttribute(), "Obj/test4[0]", "Attribute Obj/test4[0] = foo")
|
||||||
|
self.call(building.CmdSetAttribute(),
|
||||||
|
"Obj/test4[0]['one']", "Obj has no attribute 'test4[0]['one']'.")
|
||||||
|
|
||||||
def test_split_nested_attr(self):
|
def test_split_nested_attr(self):
|
||||||
split_nested_attr = building.CmdSetAttribute().split_nested_attr
|
split_nested_attr = building.CmdSetAttribute().split_nested_attr
|
||||||
test_cases = {
|
test_cases = {
|
||||||
|
|
@ -542,8 +578,13 @@ class TestBuilding(CommandTest):
|
||||||
'test2["dict"]': [('test2', ['dict']), ('test2["dict"]', [])],
|
'test2["dict"]': [('test2', ['dict']), ('test2["dict"]', [])],
|
||||||
# Quotes not actually required
|
# Quotes not actually required
|
||||||
'test3[dict]': [('test3', ['dict']), ('test3[dict]', [])],
|
'test3[dict]': [('test3', ['dict']), ('test3[dict]', [])],
|
||||||
|
'test4["dict]': [('test4', ['dict']), ('test4["dict]', [])],
|
||||||
# duplicate keys don't cause issues
|
# duplicate keys don't cause issues
|
||||||
'test4[0][0]': [('test4', ['0', '0']), ('test4[0]', ['0']), ('test4[0][0]', [])],
|
'test5[0][0]': [('test5', [0, 0]), ('test5[0]', [0]), ('test5[0][0]', [])],
|
||||||
|
# String ints preserved
|
||||||
|
'test6["0"][0]': [('test6', ['0', 0]), ('test6["0"]', [0]), ('test6["0"][0]', [])],
|
||||||
|
# Unmatched []
|
||||||
|
'test7[dict': [('test7[dict', [])],
|
||||||
}
|
}
|
||||||
|
|
||||||
for attr, result in test_cases.items():
|
for attr, result in test_cases.items():
|
||||||
|
|
@ -562,8 +603,10 @@ class TestBuilding(CommandTest):
|
||||||
do_test_single([], 'test1', not_found)
|
do_test_single([], 'test1', not_found)
|
||||||
do_test_single([1], 'test2', not_found)
|
do_test_single([1], 'test2', not_found)
|
||||||
do_test_single([], 0, not_found)
|
do_test_single([], 0, not_found)
|
||||||
|
do_test_single([], '0', not_found)
|
||||||
do_test_single([1], 2, not_found)
|
do_test_single([1], 2, not_found)
|
||||||
do_test_single([1], 0, 1)
|
do_test_single([1], 0, 1)
|
||||||
|
do_test_single([1], '0', not_found) # str key is str not int
|
||||||
do_test_single({}, 'test3', not_found)
|
do_test_single({}, 'test3', not_found)
|
||||||
do_test_single({}, 0, not_found)
|
do_test_single({}, 0, not_found)
|
||||||
do_test_single({'foo': 'bar'}, 'foo', 'bar')
|
do_test_single({'foo': 'bar'}, 'foo', 'bar')
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue