Updated ElementBase.__getitem__ with docs and unit tests.

This commit is contained in:
Lance Stout 2010-08-13 21:33:11 -04:00
parent fe49b8c377
commit 2f6f4fc16d
2 changed files with 83 additions and 17 deletions

View file

@ -183,6 +183,48 @@ class ElementBase(object):
self.plugins[interface].setStanzaValues(value) self.plugins[interface].setStanzaValues(value)
return self return self
def __getitem__(self, attrib):
"""
Return the value of a stanza interface using dictionary-like syntax.
Example:
>>> msg['body']
'Message contents'
Stanza interfaces are typically mapped directly to the underlying XML
object, but can be overridden by the presence of a getAttrib method
(or getFoo where the interface is named foo, etc).
The search order for interface value retrieval for an interface
named 'foo' is:
1. The list of substanzas.
2. The result of calling getFoo.
3. The contents of the foo subelement, if foo is a sub interface.
4. The value of the foo attribute of the XML object.
5. The plugin named 'foo'
6. An empty string.
Arguments:
attrib -- The name of the requested stanza interface.
"""
if attrib == 'substanzas':
return self.iterables
elif attrib in self.interfaces:
get_method = "get%s" % attrib.title()
if hasattr(self, get_method):
return getattr(self, get_method)()
else:
if attrib in self.sub_interfaces:
return self._getSubText(attrib)
else:
return self._getAttr(attrib)
elif attrib in self.plugin_attrib_map:
if attrib not in self.plugins:
self.initPlugin(attrib)
return self.plugins[attrib]
else:
return ''
@property @property
def attrib(self): #backwards compatibility def attrib(self): #backwards compatibility
return self return self
@ -266,23 +308,6 @@ class ElementBase(object):
def findall(self, xpath): def findall(self, xpath):
return self.xml.findall(xpath) return self.xml.findall(xpath)
def __getitem__(self, attrib):
if attrib == 'substanzas':
return self.iterables
elif attrib in self.interfaces:
if hasattr(self, "get%s" % attrib.title()):
return getattr(self, "get%s" % attrib.title())()
else:
if attrib in self.sub_interfaces:
return self._getSubText(attrib)
else:
return self._getAttr(attrib)
elif attrib in self.plugin_attrib_map:
if attrib not in self.plugins: self.initPlugin(attrib)
return self.plugins[attrib]
else:
return ''
def __setitem__(self, attrib, value): def __setitem__(self, attrib, value):
if attrib in self.interfaces: if attrib in self.interfaces:
if value is not None: if value is not None:

View file

@ -109,5 +109,46 @@ class TestElementBase(SleekTest):
</foo> </foo>
""") """)
def testGetItem(self):
"""Test accessing stanza interfaces."""
class TestStanza(ElementBase):
name = "foo"
namespace = "foo"
interfaces = set(('bar', 'baz'))
sub_interfaces = set(('baz',))
class TestStanzaPlugin(ElementBase):
name = "foobar"
namespace = "foo"
plugin_attrib = "foobar"
interfaces = set(('fizz',))
TestStanza.subitem = (TestStanza,)
registerStanzaPlugin(TestStanza, TestStanzaPlugin)
stanza = TestStanza()
substanza = TestStanza()
stanza.append(substanza)
stanza.setStanzaValues({'bar': 'a',
'baz': 'b',
'foobar': {'fizz': 'c'}})
# Test non-plugin interfaces
expected = {'substanzas': [substanza],
'bar': 'a',
'baz': 'b',
'meh': ''}
for interface, value in expected.items():
result = stanza[interface]
self.failUnless(result == value,
"Incorrect stanza interface access result: %s" % result)
# Test plugin interfaces
self.failUnless(isinstance(stanza['foobar'], TestStanzaPlugin),
"Incorrect plugin object result.")
self.failUnless(stanza['foobar']['fizz'] == 'c',
"Incorrect plugin subvalue result.")
suite = unittest.TestLoader().loadTestsFromTestCase(TestElementBase) suite = unittest.TestLoader().loadTestsFromTestCase(TestElementBase)